r21562: Regenerate gen_ndr after pidl changes.
[kai/samba.git] / source / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2005,
9  *  Copyright (C) Jean Fran├žois Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *
15  *  This program is free software; you can redistribute it and/or modify
16  *  it under the terms of the GNU General Public License as published by
17  *  the Free Software Foundation; either version 2 of the License, or
18  *  (at your option) any later version.
19  *
20  *  This program is distributed in the hope that it will be useful,
21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *  GNU General Public License for more details.
24  *
25  *  You should have received a copy of the GNU General Public License
26  *  along with this program; if not, write to the Free Software
27  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28  */
29
30 /*
31  * This is the implementation of the SAMR code.
32  */
33
34 #include "includes.h"
35
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_RPC_SRV
38
39 #define SAMR_USR_RIGHTS_WRITE_PW \
40                 ( READ_CONTROL_ACCESS           | \
41                   SA_RIGHT_USER_CHANGE_PASSWORD | \
42                   SA_RIGHT_USER_SET_LOC_COM )
43 #define SAMR_USR_RIGHTS_CANT_WRITE_PW \
44                 ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM )
45
46 #define DISP_INFO_CACHE_TIMEOUT 10
47
48 typedef struct disp_info {
49         struct disp_info *next, *prev;
50         TALLOC_CTX *mem_ctx;
51         DOM_SID sid; /* identify which domain this is. */
52         BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
53         struct pdb_search *users; /* querydispinfo 1 and 4 */
54         struct pdb_search *machines; /* querydispinfo 2 */
55         struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
56         struct pdb_search *aliases; /* enumaliases */
57
58         uint16 enum_acb_mask;
59         struct pdb_search *enum_users; /* enumusers with a mask */
60
61
62         smb_event_id_t di_cache_timeout_event; /* cache idle timeout handler. */
63 } DISP_INFO;
64
65 /* We keep a static list of these by SID as modern clients close down
66    all resources between each request in a complete enumeration. */
67
68 static DISP_INFO *disp_info_list;
69
70 struct samr_info {
71         /* for use by the \PIPE\samr policy */
72         DOM_SID sid;
73         BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
74         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
75         uint32 acc_granted;
76         DISP_INFO *disp_info;
77         TALLOC_CTX *mem_ctx;
78 };
79
80 static struct generic_mapping sam_generic_mapping = {
81         GENERIC_RIGHTS_SAM_READ,
82         GENERIC_RIGHTS_SAM_WRITE,
83         GENERIC_RIGHTS_SAM_EXECUTE,
84         GENERIC_RIGHTS_SAM_ALL_ACCESS};
85 static struct generic_mapping dom_generic_mapping = {
86         GENERIC_RIGHTS_DOMAIN_READ,
87         GENERIC_RIGHTS_DOMAIN_WRITE,
88         GENERIC_RIGHTS_DOMAIN_EXECUTE,
89         GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
90 static struct generic_mapping usr_generic_mapping = {
91         GENERIC_RIGHTS_USER_READ,
92         GENERIC_RIGHTS_USER_WRITE,
93         GENERIC_RIGHTS_USER_EXECUTE,
94         GENERIC_RIGHTS_USER_ALL_ACCESS};
95 static struct generic_mapping usr_nopwchange_generic_mapping = {
96         GENERIC_RIGHTS_USER_READ,
97         GENERIC_RIGHTS_USER_WRITE,
98         GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD,
99         GENERIC_RIGHTS_USER_ALL_ACCESS};
100 static struct generic_mapping grp_generic_mapping = {
101         GENERIC_RIGHTS_GROUP_READ,
102         GENERIC_RIGHTS_GROUP_WRITE,
103         GENERIC_RIGHTS_GROUP_EXECUTE,
104         GENERIC_RIGHTS_GROUP_ALL_ACCESS};
105 static struct generic_mapping ali_generic_mapping = {
106         GENERIC_RIGHTS_ALIAS_READ,
107         GENERIC_RIGHTS_ALIAS_WRITE,
108         GENERIC_RIGHTS_ALIAS_EXECUTE,
109         GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
110
111 /*******************************************************************
112 *******************************************************************/
113
114 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
115                                      struct generic_mapping *map,
116                                      DOM_SID *sid, uint32 sid_access )
117 {
118         DOM_SID domadmin_sid;
119         SEC_ACE ace[5];         /* at most 5 entries */
120         SEC_ACCESS mask;
121         size_t i = 0;
122
123         SEC_ACL *psa = NULL;
124
125         /* basic access for Everyone */
126
127         init_sec_access(&mask, map->generic_execute | map->generic_read );
128         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
129
130         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
131
132         init_sec_access(&mask, map->generic_all);
133         
134         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
135         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
136
137         /* Add Full Access for Domain Admins if we are a DC */
138         
139         if ( IS_DC ) {
140                 sid_copy( &domadmin_sid, get_global_sam_sid() );
141                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
142                 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
143         }
144
145         /* if we have a sid, give it some special access */
146
147         if ( sid ) {
148                 init_sec_access( &mask, sid_access );
149                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
150         }
151
152         /* create the security descriptor */
153
154         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
155                 return NT_STATUS_NO_MEMORY;
156
157         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
158                 return NT_STATUS_NO_MEMORY;
159
160         return NT_STATUS_OK;
161 }
162
163 /*******************************************************************
164  Checks if access to an object should be granted, and returns that
165  level of access for further checks.
166 ********************************************************************/
167
168 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token, 
169                                           SE_PRIV *rights, uint32 rights_mask,
170                                           uint32 des_access, uint32 *acc_granted, 
171                                           const char *debug )
172 {
173         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
174         uint32 saved_mask = 0;
175
176         /* check privileges; certain SAM access bits should be overridden 
177            by privileges (mostly having to do with creating/modifying/deleting 
178            users and groups) */
179         
180         if ( rights && user_has_any_privilege( token, rights ) ) {
181         
182                 saved_mask = (des_access & rights_mask);
183                 des_access &= ~saved_mask;
184                 
185                 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
186                         rights_mask));
187         }
188                 
189         
190         /* check the security descriptor first */
191         
192         if ( se_access_check(psd, token, des_access, acc_granted, &status) )
193                 goto done;
194         
195         /* give root a free pass */
196         
197         if ( geteuid() == sec_initial_uid() ) {
198         
199                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
200                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
201                 
202                 *acc_granted = des_access;
203                 
204                 status = NT_STATUS_OK;
205                 goto done;
206         }
207         
208         
209 done:
210         /* add in any bits saved during the privilege check (only 
211            matters is status is ok) */
212         
213         *acc_granted |= rights_mask;
214
215         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n", 
216                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED", 
217                 des_access, *acc_granted));
218         
219         return status;
220 }
221
222 /*******************************************************************
223  Checks if access to a function can be granted
224 ********************************************************************/
225
226 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
227 {
228         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",  
229                 debug, acc_granted, acc_required));
230
231         /* check the security descriptor first */
232         
233         if ( (acc_granted&acc_required) == acc_required )
234                 return NT_STATUS_OK;
235                 
236         /* give root a free pass */
237
238         if (geteuid() == sec_initial_uid()) {
239         
240                 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
241                         debug, acc_granted, acc_required));
242                 DEBUGADD(4,("but overwritten by euid == 0\n"));
243                 
244                 return NT_STATUS_OK;
245         }
246         
247         DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n", 
248                 debug, acc_granted, acc_required));
249                 
250         return NT_STATUS_ACCESS_DENIED;
251 }
252
253 /*******************************************************************
254  Fetch or create a dispinfo struct.
255 ********************************************************************/
256
257 static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid, const char *sid_str)
258 {
259         TALLOC_CTX *mem_ctx;
260         DISP_INFO *dpi;
261
262         /* There are two cases to consider here:
263            1) The SID is a domain SID and we look for an equality match, or
264            2) This is an account SID and so we return the DISP_INFO* for our 
265               domain */
266
267         if ( psid && sid_check_is_in_our_domain( psid ) ) {
268                 DEBUG(10,("get_samr_dispinfo_by_sid: Replacing %s with our domain SID\n",
269                         sid_str));
270                 psid = get_global_sam_sid();
271         }
272
273         for (dpi = disp_info_list; dpi; dpi = dpi->next) {
274                 if (sid_equal(psid, &dpi->sid)) {
275                         return dpi;
276                 }
277         }
278
279         /* This struct is never free'd - I'm using talloc so we
280            can get a list out of smbd using smbcontrol. There will
281            be one of these per SID we're authorative for. JRA. */
282
283         mem_ctx = talloc_init("DISP_INFO for domain sid %s", sid_str);
284
285         if ((dpi = TALLOC_ZERO_P(mem_ctx, DISP_INFO)) == NULL)
286                 return NULL;
287
288         dpi->mem_ctx = mem_ctx;
289
290         if (psid) {
291                 sid_copy( &dpi->sid, psid);
292                 dpi->builtin_domain = sid_check_is_builtin(psid);
293         } else {
294                 dpi->builtin_domain = False;
295         }
296
297         DLIST_ADD(disp_info_list, dpi);
298
299         return dpi;
300 }
301
302 /*******************************************************************
303  Create a samr_info struct.
304 ********************************************************************/
305
306 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
307 {
308         struct samr_info *info;
309         fstring sid_str;
310         TALLOC_CTX *mem_ctx;
311         
312         if (psid) {
313                 sid_to_string(sid_str, psid);
314         } else {
315                 fstrcpy(sid_str,"(NULL)");
316         }
317
318         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
319
320         if ((info = TALLOC_ZERO_P(mem_ctx, struct samr_info)) == NULL)
321                 return NULL;
322
323         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
324         if (psid) {
325                 sid_copy( &info->sid, psid);
326                 info->builtin_domain = sid_check_is_builtin(psid);
327         } else {
328                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
329                 info->builtin_domain = False;
330         }
331         info->mem_ctx = mem_ctx;
332
333         info->disp_info = get_samr_dispinfo_by_sid(psid, sid_str);
334
335         if (!info->disp_info) {
336                 talloc_destroy(mem_ctx);
337                 return NULL;
338         }
339
340         return info;
341 }
342
343 /*******************************************************************
344  Function to free the per SID data.
345  ********************************************************************/
346
347 static void free_samr_cache(DISP_INFO *disp_info, const char *sid_str)
348 {
349         DEBUG(10,("free_samr_cache: deleting cache for SID %s\n", sid_str));
350
351         /* We need to become root here because the paged search might have to
352          * tell the LDAP server we're not interested in the rest anymore. */
353
354         become_root();
355
356         if (disp_info->users) {
357                 DEBUG(10,("free_samr_cache: deleting users cache\n"));
358                 pdb_search_destroy(disp_info->users);
359                 disp_info->users = NULL;
360         }
361         if (disp_info->machines) {
362                 DEBUG(10,("free_samr_cache: deleting machines cache\n"));
363                 pdb_search_destroy(disp_info->machines);
364                 disp_info->machines = NULL;
365         }
366         if (disp_info->groups) {
367                 DEBUG(10,("free_samr_cache: deleting groups cache\n"));
368                 pdb_search_destroy(disp_info->groups);
369                 disp_info->groups = NULL;
370         }
371         if (disp_info->aliases) {
372                 DEBUG(10,("free_samr_cache: deleting aliases cache\n"));
373                 pdb_search_destroy(disp_info->aliases);
374                 disp_info->aliases = NULL;
375         }
376         if (disp_info->enum_users) {
377                 DEBUG(10,("free_samr_cache: deleting enum_users cache\n"));
378                 pdb_search_destroy(disp_info->enum_users);
379                 disp_info->enum_users = NULL;
380         }
381         disp_info->enum_acb_mask = 0;
382
383         unbecome_root();
384 }
385
386 /*******************************************************************
387  Function to free the per handle data.
388  ********************************************************************/
389
390 static void free_samr_info(void *ptr)
391 {
392         struct samr_info *info=(struct samr_info *) ptr;
393
394         /* Only free the dispinfo cache if no one bothered to set up
395            a timeout. */
396
397         if (info->disp_info && info->disp_info->di_cache_timeout_event == (smb_event_id_t)0) {
398                 fstring sid_str;
399                 sid_to_string(sid_str, &info->disp_info->sid);
400                 free_samr_cache(info->disp_info, sid_str);
401         }
402
403         talloc_destroy(info->mem_ctx);
404 }
405
406 /*******************************************************************
407  Idle event handler. Throw away the disp info cache.
408  ********************************************************************/
409
410 static void disp_info_cache_idle_timeout_handler(void **private_data,
411                                         time_t *ev_interval,
412                                         time_t ev_now)
413 {
414         fstring sid_str;
415         DISP_INFO *disp_info = (DISP_INFO *)(*private_data);
416
417         sid_to_string(sid_str, &disp_info->sid);
418
419         free_samr_cache(disp_info, sid_str);
420
421         /* Remove the event. */
422         smb_unregister_idle_event(disp_info->di_cache_timeout_event);
423         disp_info->di_cache_timeout_event = (smb_event_id_t)0;
424
425         DEBUG(10,("disp_info_cache_idle_timeout_handler: caching timed out for SID %s at %u\n",
426                 sid_str, (unsigned int)ev_now));
427 }
428
429 /*******************************************************************
430  Setup cache removal idle event handler.
431  ********************************************************************/
432
433 static void set_disp_info_cache_timeout(DISP_INFO *disp_info, time_t secs_fromnow)
434 {
435         fstring sid_str;
436
437         sid_to_string(sid_str, &disp_info->sid);
438
439         /* Remove any pending timeout and update. */
440
441         if (disp_info->di_cache_timeout_event) {
442                 smb_unregister_idle_event(disp_info->di_cache_timeout_event);
443                 disp_info->di_cache_timeout_event = (smb_event_id_t)0;
444         }
445
446         DEBUG(10,("set_disp_info_cache_timeout: caching enumeration for SID %s for %u seconds\n",
447                 sid_str, (unsigned int)secs_fromnow ));
448
449         disp_info->di_cache_timeout_event =
450                 smb_register_idle_event(disp_info_cache_idle_timeout_handler,
451                                         disp_info,
452                                         secs_fromnow);
453 }
454
455 /*******************************************************************
456  Force flush any cache. We do this on any samr_set_xxx call.
457  We must also remove the timeout handler.
458  ********************************************************************/
459
460 static void force_flush_samr_cache(DISP_INFO *disp_info)
461 {
462         if (disp_info) {
463                 fstring sid_str;
464
465                 sid_to_string(sid_str, &disp_info->sid);
466                 if (disp_info->di_cache_timeout_event) {
467                         smb_unregister_idle_event(disp_info->di_cache_timeout_event);
468                         disp_info->di_cache_timeout_event = (smb_event_id_t)0;
469                         DEBUG(10,("force_flush_samr_cache: clearing idle event for SID %s\n",
470                                 sid_str));
471                 }
472                 free_samr_cache(disp_info, sid_str);
473         }
474 }
475
476 /*******************************************************************
477  Ensure password info is never given out. Paranioa... JRA.
478  ********************************************************************/
479
480 static void samr_clear_sam_passwd(struct samu *sam_pass)
481 {
482         
483         if (!sam_pass)
484                 return;
485
486         /* These now zero out the old password */
487
488         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
489         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
490 }
491
492 static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
493 {
494         struct samr_displayentry *entry;
495
496         if (info->builtin_domain) {
497                 /* No users in builtin. */
498                 return 0;
499         }
500
501         if (info->users == NULL) {
502                 info->users = pdb_search_users(acct_flags);
503                 if (info->users == NULL) {
504                         return 0;
505                 }
506         }
507         /* Fetch the last possible entry, thus trigger an enumeration */
508         pdb_search_entries(info->users, 0xffffffff, 1, &entry);
509
510         /* Ensure we cache this enumeration. */
511         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
512
513         return info->users->num_entries;
514 }
515
516 static uint32 count_sam_groups(struct disp_info *info)
517 {
518         struct samr_displayentry *entry;
519
520         if (info->builtin_domain) {
521                 /* No groups in builtin. */
522                 return 0;
523         }
524
525         if (info->groups == NULL) {
526                 info->groups = pdb_search_groups();
527                 if (info->groups == NULL) {
528                         return 0;
529                 }
530         }
531         /* Fetch the last possible entry, thus trigger an enumeration */
532         pdb_search_entries(info->groups, 0xffffffff, 1, &entry);
533
534         /* Ensure we cache this enumeration. */
535         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
536
537         return info->groups->num_entries;
538 }
539
540 static uint32 count_sam_aliases(struct disp_info *info)
541 {
542         struct samr_displayentry *entry;
543
544         if (info->aliases == NULL) {
545                 info->aliases = pdb_search_aliases(&info->sid);
546                 if (info->aliases == NULL) {
547                         return 0;
548                 }
549         }
550         /* Fetch the last possible entry, thus trigger an enumeration */
551         pdb_search_entries(info->aliases, 0xffffffff, 1, &entry);
552
553         /* Ensure we cache this enumeration. */
554         set_disp_info_cache_timeout(info, DISP_INFO_CACHE_TIMEOUT);
555
556         return info->aliases->num_entries;
557 }
558
559 /*******************************************************************
560  _samr_close_hnd
561  ********************************************************************/
562
563 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
564 {
565         r_u->status = NT_STATUS_OK;
566
567         /* close the policy handle */
568         if (!close_policy_hnd(p, &q_u->pol))
569                 return NT_STATUS_OBJECT_NAME_INVALID;
570
571         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
572
573         return r_u->status;
574 }
575
576 /*******************************************************************
577  samr_reply_open_domain
578  ********************************************************************/
579
580 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
581 {
582         struct    samr_info *info;
583         SEC_DESC *psd = NULL;
584         uint32    acc_granted;
585         uint32    des_access = q_u->flags;
586         NTSTATUS  status;
587         size_t    sd_size;
588         SE_PRIV se_rights;
589
590         r_u->status = NT_STATUS_OK;
591
592         /* find the connection policy handle. */
593         
594         if ( !find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info) )
595                 return NT_STATUS_INVALID_HANDLE;
596
597         status = access_check_samr_function( info->acc_granted, 
598                 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" );
599                 
600         if ( !NT_STATUS_IS_OK(status) )
601                 return status;
602
603         /*check if access can be granted as requested by client. */
604         
605         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
606         se_map_generic( &des_access, &dom_generic_mapping );
607         
608         se_priv_copy( &se_rights, &se_machine_account );
609         se_priv_add( &se_rights, &se_add_users );
610
611         status = access_check_samr_object( psd, p->pipe_user.nt_user_token, 
612                 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access, 
613                 &acc_granted, "_samr_open_domain" );
614                 
615         if ( !NT_STATUS_IS_OK(status) )
616                 return status;
617
618         if (!sid_check_is_domain(&q_u->dom_sid.sid) &&
619             !sid_check_is_builtin(&q_u->dom_sid.sid)) {
620                 return NT_STATUS_NO_SUCH_DOMAIN;
621         }
622
623         /* associate the domain SID with the (unique) handle. */
624         if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
625                 return NT_STATUS_NO_MEMORY;
626         info->acc_granted = acc_granted;
627
628         /* get a (unique) handle.  open a policy on it. */
629         if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
630                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
631
632         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
633
634         return r_u->status;
635 }
636
637 /*******************************************************************
638  _samr_get_usrdom_pwinfo
639  ********************************************************************/
640
641 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
642 {
643         struct samr_info *info = NULL;
644
645         r_u->status = NT_STATUS_OK;
646
647         /* find the policy handle.  open a policy on it. */
648         if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)(void *)&info))
649                 return NT_STATUS_INVALID_HANDLE;
650
651         if (!sid_check_is_in_our_domain(&info->sid))
652                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
653
654         init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
655
656         DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
657
658         /* 
659          * NT sometimes return NT_STATUS_ACCESS_DENIED
660          * I don't know yet why.
661          */
662
663         return r_u->status;
664 }
665
666 /*******************************************************************
667 ********************************************************************/
668
669 static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, 
670                                         DOM_SID *sid, uint32 *acc_granted,
671                                         DISP_INFO **ppdisp_info)
672 {
673         struct samr_info *info = NULL;
674
675         /* find the policy handle.  open a policy on it. */
676         if (!find_policy_by_hnd(p, pol, (void **)(void *)&info))
677                 return False;
678
679         if (!info)
680                 return False;
681
682         *sid = info->sid;
683         *acc_granted = info->acc_granted;
684         if (ppdisp_info) {
685                 *ppdisp_info = info->disp_info;
686         }
687
688         return True;
689 }
690
691 /*******************************************************************
692  _samr_set_sec_obj
693  ********************************************************************/
694
695 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
696 {
697         DOM_SID pol_sid;
698         uint32 acc_granted, i;
699         SEC_ACL *dacl;
700         BOOL ret;
701         struct samu *sampass=NULL;
702         NTSTATUS status;
703
704         r_u->status = NT_STATUS_OK;
705
706         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL))
707                 return NT_STATUS_INVALID_HANDLE;
708
709         if (!(sampass = samu_new( p->mem_ctx))) {
710                 DEBUG(0,("No memory!\n"));
711                 return NT_STATUS_NO_MEMORY;
712         }
713
714         /* get the user record */
715         become_root();
716         ret = pdb_getsampwsid(sampass, &pol_sid);
717         unbecome_root();
718
719         if (!ret) {
720                 DEBUG(4, ("User %s not found\n", sid_string_static(&pol_sid)));
721                 TALLOC_FREE(sampass);
722                 return NT_STATUS_INVALID_HANDLE;
723         }
724
725         dacl = q_u->buf->sd->dacl;
726         for (i=0; i < dacl->num_aces; i++) {
727                 if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) {
728                         ret = pdb_set_pass_can_change(sampass, 
729                                 (dacl->aces[i].access_mask & 
730                                  SA_RIGHT_USER_CHANGE_PASSWORD) ? 
731                                                       True: False);
732                         break;
733                 }
734         }
735
736         if (!ret) {
737                 TALLOC_FREE(sampass);
738                 return NT_STATUS_ACCESS_DENIED;
739         }
740
741         status = pdb_update_sam_account(sampass);
742
743         TALLOC_FREE(sampass);
744
745         return status;
746 }
747
748 /*******************************************************************
749   build correct perms based on policies and password times for _samr_query_sec_obj
750 *******************************************************************/
751 static BOOL check_change_pw_access(TALLOC_CTX *mem_ctx, DOM_SID *user_sid)
752 {
753         struct samu *sampass=NULL;
754         BOOL ret;
755
756         if ( !(sampass = samu_new( mem_ctx )) ) {
757                 DEBUG(0,("No memory!\n"));
758                 return False;
759         }
760
761         become_root();
762         ret = pdb_getsampwsid(sampass, user_sid);
763         unbecome_root();
764
765         if (ret == False) {
766                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
767                 TALLOC_FREE(sampass);
768                 return False;
769         }
770
771         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
772
773         if (pdb_get_pass_can_change(sampass)) {
774                 TALLOC_FREE(sampass);
775                 return True;
776         }
777         TALLOC_FREE(sampass);
778         return False;
779 }
780
781
782 /*******************************************************************
783  _samr_query_sec_obj
784  ********************************************************************/
785
786 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
787 {
788         DOM_SID pol_sid;
789         fstring str_sid;
790         SEC_DESC * psd = NULL;
791         uint32 acc_granted;
792         size_t sd_size;
793
794         r_u->status = NT_STATUS_OK;
795
796         /* Get the SID. */
797         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted, NULL))
798                 return NT_STATUS_INVALID_HANDLE;
799
800         DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
801
802         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
803
804         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
805         if (pol_sid.sid_rev_num == 0) {
806                 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
807                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
808         } else if (sid_equal(&pol_sid,get_global_sam_sid())) { 
809                 /* check if it is our domain SID */
810                 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
811                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
812         } else if (sid_equal(&pol_sid,&global_sid_Builtin)) {
813                 /* check if it is the Builtin  Domain */
814                 /* TODO: Builtin probably needs a different SD with restricted write access*/
815                 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
816                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
817         } else if (sid_check_is_in_our_domain(&pol_sid) ||
818                  sid_check_is_in_builtin(&pol_sid)) {
819                 /* TODO: different SDs have to be generated for aliases groups and users.
820                          Currently all three get a default user SD  */
821                 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
822                 if (check_change_pw_access(p->mem_ctx, &pol_sid)) {
823                         r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, 
824                                                           &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
825                 } else {
826                         r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_nopwchange_generic_mapping, 
827                                                           &pol_sid, SAMR_USR_RIGHTS_CANT_WRITE_PW);
828                 }
829         } else {
830                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
831         }
832
833         if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
834                 return NT_STATUS_NO_MEMORY;
835
836         if (NT_STATUS_IS_OK(r_u->status))
837                 r_u->ptr = 1;
838
839         return r_u->status;
840 }
841
842 /*******************************************************************
843 makes a SAM_ENTRY / UNISTR2* structure from a user list.
844 ********************************************************************/
845
846 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
847                                          UNISTR2 **uni_name_pp,
848                                          uint32 num_entries, uint32 start_idx,
849                                          struct samr_displayentry *entries)
850 {
851         uint32 i;
852         SAM_ENTRY *sam;
853         UNISTR2 *uni_name;
854         
855         *sam_pp = NULL;
856         *uni_name_pp = NULL;
857
858         if (num_entries == 0)
859                 return NT_STATUS_OK;
860
861         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
862
863         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
864
865         if (sam == NULL || uni_name == NULL) {
866                 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
867                 return NT_STATUS_NO_MEMORY;
868         }
869
870         for (i = 0; i < num_entries; i++) {
871                 UNISTR2 uni_temp_name;
872                 /*
873                  * usrmgr expects a non-NULL terminated string with
874                  * trust relationships
875                  */
876                 if (entries[i].acct_flags & ACB_DOMTRUST) {
877                         init_unistr2(&uni_temp_name, entries[i].account_name,
878                                      UNI_FLAGS_NONE);
879                 } else {
880                         init_unistr2(&uni_temp_name, entries[i].account_name,
881                                      UNI_STR_TERMINATE);
882                 }
883
884                 init_sam_entry(&sam[i], &uni_temp_name, entries[i].rid);
885                 copy_unistr2(&uni_name[i], &uni_temp_name);
886         }
887
888         *sam_pp = sam;
889         *uni_name_pp = uni_name;
890         return NT_STATUS_OK;
891 }
892
893 /*******************************************************************
894  samr_reply_enum_dom_users
895  ********************************************************************/
896
897 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, 
898                               SAMR_R_ENUM_DOM_USERS *r_u)
899 {
900         struct samr_info *info = NULL;
901         int num_account;
902         uint32 enum_context=q_u->start_idx;
903         enum remote_arch_types ra_type = get_remote_arch();
904         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
905         uint32 max_entries = max_sam_entries;
906         struct samr_displayentry *entries = NULL;
907         
908         r_u->status = NT_STATUS_OK;
909
910         /* find the policy handle.  open a policy on it. */
911         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
912                 return NT_STATUS_INVALID_HANDLE;
913
914         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
915                                         SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 
916                                         "_samr_enum_dom_users"))) {
917                 return r_u->status;
918         }
919         
920         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
921
922         if (info->builtin_domain) {
923                 /* No users in builtin. */
924                 init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0);
925                 DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n"));
926                 return r_u->status;
927         }
928
929         become_root();
930
931         /* AS ROOT !!!! */
932
933         if ((info->disp_info->enum_users != NULL) &&
934             (info->disp_info->enum_acb_mask != q_u->acb_mask)) {
935                 pdb_search_destroy(info->disp_info->enum_users);
936                 info->disp_info->enum_users = NULL;
937         }
938
939         if (info->disp_info->enum_users == NULL) {
940                 info->disp_info->enum_users = pdb_search_users(q_u->acb_mask);
941                 info->disp_info->enum_acb_mask = q_u->acb_mask;
942         }
943
944         if (info->disp_info->enum_users == NULL) {
945                 /* END AS ROOT !!!! */
946                 unbecome_root();
947                 return NT_STATUS_ACCESS_DENIED;
948         }
949
950         num_account = pdb_search_entries(info->disp_info->enum_users,
951                                          enum_context, max_entries,
952                                          &entries);
953
954         /* END AS ROOT !!!! */
955
956         unbecome_root();
957
958         if (num_account == 0) {
959                 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over "
960                           "total entries\n"));
961                 return NT_STATUS_OK;
962         }
963
964         r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam,
965                                                &r_u->uni_acct_name, 
966                                                num_account, enum_context,
967                                                entries);
968
969         if (!NT_STATUS_IS_OK(r_u->status))
970                 return r_u->status;
971
972         if (max_entries <= num_account) {
973                 r_u->status = STATUS_MORE_ENTRIES;
974         } else {
975                 r_u->status = NT_STATUS_OK;
976         }
977
978         /* Ensure we cache this enumeration. */
979         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
980
981         DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
982
983         init_samr_r_enum_dom_users(r_u, q_u->start_idx + num_account,
984                                    num_account);
985
986         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
987
988         return r_u->status;
989 }
990
991 /*******************************************************************
992 makes a SAM_ENTRY / UNISTR2* structure from a group list.
993 ********************************************************************/
994
995 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp,
996                                       UNISTR2 **uni_name_pp,
997                                       uint32 num_sam_entries,
998                                       struct samr_displayentry *entries)
999 {
1000         uint32 i;
1001         SAM_ENTRY *sam;
1002         UNISTR2 *uni_name;
1003
1004         *sam_pp = NULL;
1005         *uni_name_pp = NULL;
1006
1007         if (num_sam_entries == 0)
1008                 return;
1009
1010         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
1011         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
1012
1013         if (sam == NULL || uni_name == NULL) {
1014                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
1015                 return;
1016         }
1017
1018         for (i = 0; i < num_sam_entries; i++) {
1019                 /*
1020                  * JRA. I think this should include the null. TNG does not.
1021                  */
1022                 init_unistr2(&uni_name[i], entries[i].account_name,
1023                              UNI_STR_TERMINATE);
1024                 init_sam_entry(&sam[i], &uni_name[i], entries[i].rid);
1025         }
1026
1027         *sam_pp = sam;
1028         *uni_name_pp = uni_name;
1029 }
1030
1031 /*******************************************************************
1032  samr_reply_enum_dom_groups
1033  ********************************************************************/
1034
1035 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
1036 {
1037         struct samr_info *info = NULL;
1038         struct samr_displayentry *groups;
1039         uint32 num_groups;
1040
1041         r_u->status = NT_STATUS_OK;
1042
1043         /* find the policy handle.  open a policy on it. */
1044         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1045                 return NT_STATUS_INVALID_HANDLE;
1046
1047         r_u->status = access_check_samr_function(info->acc_granted,
1048                                                  SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1049                                                  "_samr_enum_dom_groups");
1050         if (!NT_STATUS_IS_OK(r_u->status))
1051                 return r_u->status;
1052
1053         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
1054
1055         if (info->builtin_domain) {
1056                 /* No groups in builtin. */
1057                 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, 0);
1058                 DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n"));
1059                 return r_u->status;
1060         }
1061
1062         /* the domain group array is being allocated in the function below */
1063
1064         become_root();
1065
1066         if (info->disp_info->groups == NULL) {
1067                 info->disp_info->groups = pdb_search_groups();
1068
1069                 if (info->disp_info->groups == NULL) {
1070                         unbecome_root();
1071                         return NT_STATUS_ACCESS_DENIED;
1072                 }
1073         }
1074
1075         num_groups = pdb_search_entries(info->disp_info->groups, q_u->start_idx,
1076                                         MAX_SAM_ENTRIES, &groups);
1077         unbecome_root();
1078         
1079         /* Ensure we cache this enumeration. */
1080         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1081
1082         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
1083                                   num_groups, groups);
1084
1085         init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_groups);
1086
1087         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
1088
1089         return r_u->status;
1090 }
1091
1092 /*******************************************************************
1093  samr_reply_enum_dom_aliases
1094  ********************************************************************/
1095
1096 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1097 {
1098         struct samr_info *info;
1099         struct samr_displayentry *aliases;
1100         uint32 num_aliases = 0;
1101
1102         /* find the policy handle.  open a policy on it. */
1103         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
1104                 return NT_STATUS_INVALID_HANDLE;
1105
1106         r_u->status = access_check_samr_function(info->acc_granted,
1107                                                  SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
1108                                                  "_samr_enum_dom_aliases");
1109         if (!NT_STATUS_IS_OK(r_u->status))
1110                 return r_u->status;
1111
1112         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n",
1113                  sid_string_static(&info->sid)));
1114
1115         become_root();
1116
1117         if (info->disp_info->aliases == NULL) {
1118                 info->disp_info->aliases = pdb_search_aliases(&info->sid);
1119                 if (info->disp_info->aliases == NULL) {
1120                         unbecome_root();
1121                         return NT_STATUS_ACCESS_DENIED;
1122                 }
1123         }
1124
1125         num_aliases = pdb_search_entries(info->disp_info->aliases, q_u->start_idx,
1126                                          MAX_SAM_ENTRIES, &aliases);
1127         unbecome_root();
1128         
1129         /* Ensure we cache this enumeration. */
1130         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1131
1132         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name,
1133                                   num_aliases, aliases);
1134
1135         init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_aliases,
1136                                      num_aliases);
1137
1138         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1139
1140         return r_u->status;
1141 }
1142
1143 /*******************************************************************
1144  samr_reply_query_dispinfo
1145  ********************************************************************/
1146
1147 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, 
1148                               SAMR_R_QUERY_DISPINFO *r_u)
1149 {
1150         struct samr_info *info = NULL;
1151         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1152         
1153         uint32 max_entries=q_u->max_entries;
1154         uint32 enum_context=q_u->start_idx;
1155         uint32 max_size=q_u->max_size;
1156
1157         SAM_DISPINFO_CTR *ctr;
1158         uint32 temp_size=0, total_data_size=0;
1159         NTSTATUS disp_ret = NT_STATUS_UNSUCCESSFUL;
1160         uint32 num_account = 0;
1161         enum remote_arch_types ra_type = get_remote_arch();
1162         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1163         struct samr_displayentry *entries = NULL;
1164
1165         DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1166         r_u->status = NT_STATUS_UNSUCCESSFUL;
1167
1168         /* find the policy handle.  open a policy on it. */
1169         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
1170                 return NT_STATUS_INVALID_HANDLE;
1171
1172         /*
1173          * calculate how many entries we will return.
1174          * based on 
1175          * - the number of entries the client asked
1176          * - our limit on that
1177          * - the starting point (enumeration context)
1178          * - the buffer size the client will accept
1179          */
1180
1181         /*
1182          * We are a lot more like W2K. Instead of reading the SAM
1183          * each time to find the records we need to send back,
1184          * we read it once and link that copy to the sam handle.
1185          * For large user list (over the MAX_SAM_ENTRIES)
1186          * it's a definitive win.
1187          * second point to notice: between enumerations
1188          * our sam is now the same as it's a snapshoot.
1189          * third point: got rid of the static SAM_USER_21 struct
1190          * no more intermediate.
1191          * con: it uses much more memory, as a full copy is stored
1192          * in memory.
1193          *
1194          * If you want to change it, think twice and think
1195          * of the second point , that's really important.
1196          *
1197          * JFM, 12/20/2001
1198          */
1199
1200         if ((q_u->switch_level < 1) || (q_u->switch_level > 5)) {
1201                 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n",
1202                          (unsigned int)q_u->switch_level ));
1203                 return NT_STATUS_INVALID_INFO_CLASS;
1204         }
1205
1206         /* first limit the number of entries we will return */
1207         if(max_entries > max_sam_entries) {
1208                 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d "
1209                           "entries, limiting to %d\n", max_entries,
1210                           max_sam_entries));
1211                 max_entries = max_sam_entries;
1212         }
1213
1214         /* calculate the size and limit on the number of entries we will
1215          * return */
1216
1217         temp_size=max_entries*struct_size;
1218         
1219         if (temp_size>max_size) {
1220                 max_entries=MIN((max_size/struct_size),max_entries);;
1221                 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to "
1222                           "only %d entries\n", max_entries));
1223         }
1224
1225         if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1226                 return NT_STATUS_NO_MEMORY;
1227
1228         ZERO_STRUCTP(ctr);
1229
1230         become_root();
1231
1232         /* THe following done as ROOT. Don't return without unbecome_root(). */
1233
1234         switch (q_u->switch_level) {
1235         case 0x1:
1236         case 0x4:
1237                 if (info->disp_info->users == NULL) {
1238                         info->disp_info->users = pdb_search_users(ACB_NORMAL);
1239                         if (info->disp_info->users == NULL) {
1240                                 unbecome_root();
1241                                 return NT_STATUS_ACCESS_DENIED;
1242                         }
1243                         DEBUG(10,("samr_reply_query_dispinfo: starting user enumeration at index %u\n",
1244                                 (unsigned  int)enum_context ));
1245                 } else {
1246                         DEBUG(10,("samr_reply_query_dispinfo: using cached user enumeration at index %u\n",
1247                                 (unsigned  int)enum_context ));
1248                 }
1249
1250                 num_account = pdb_search_entries(info->disp_info->users,
1251                                                  enum_context, max_entries,
1252                                                  &entries);
1253                 break;
1254         case 0x2:
1255                 if (info->disp_info->machines == NULL) {
1256                         info->disp_info->machines =
1257                                 pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
1258                         if (info->disp_info->machines == NULL) {
1259                                 unbecome_root();
1260                                 return NT_STATUS_ACCESS_DENIED;
1261                         }
1262                         DEBUG(10,("samr_reply_query_dispinfo: starting machine enumeration at index %u\n",
1263                                 (unsigned  int)enum_context ));
1264                 } else {
1265                         DEBUG(10,("samr_reply_query_dispinfo: using cached machine enumeration at index %u\n",
1266                                 (unsigned  int)enum_context ));
1267                 }
1268
1269                 num_account = pdb_search_entries(info->disp_info->machines,
1270                                                  enum_context, max_entries,
1271                                                  &entries);
1272                 break;
1273         case 0x3:
1274         case 0x5:
1275                 if (info->disp_info->groups == NULL) {
1276                         info->disp_info->groups = pdb_search_groups();
1277                         if (info->disp_info->groups == NULL) {
1278                                 unbecome_root();
1279                                 return NT_STATUS_ACCESS_DENIED;
1280                         }
1281                         DEBUG(10,("samr_reply_query_dispinfo: starting group enumeration at index %u\n",
1282                                 (unsigned  int)enum_context ));
1283                 } else {
1284                         DEBUG(10,("samr_reply_query_dispinfo: using cached group enumeration at index %u\n",
1285                                 (unsigned  int)enum_context ));
1286                 }
1287
1288                 num_account = pdb_search_entries(info->disp_info->groups,
1289                                                  enum_context, max_entries,
1290                                                  &entries);
1291                 break;
1292         default:
1293                 unbecome_root();
1294                 smb_panic("info class changed");
1295                 break;
1296         }
1297         unbecome_root();
1298
1299         /* Now create reply structure */
1300         switch (q_u->switch_level) {
1301         case 0x1:
1302                 disp_ret = init_sam_dispinfo_1(p->mem_ctx, &ctr->sam.info1,
1303                                                num_account, enum_context,
1304                                                entries);
1305                 break;
1306         case 0x2:
1307                 disp_ret = init_sam_dispinfo_2(p->mem_ctx, &ctr->sam.info2,
1308                                                num_account, enum_context,
1309                                                entries);
1310                 break;
1311         case 0x3:
1312                 disp_ret = init_sam_dispinfo_3(p->mem_ctx, &ctr->sam.info3,
1313                                                num_account, enum_context,
1314                                                entries);
1315                 break;
1316         case 0x4:
1317                 disp_ret = init_sam_dispinfo_4(p->mem_ctx, &ctr->sam.info4,
1318                                                num_account, enum_context,
1319                                                entries);
1320                 break;
1321         case 0x5:
1322                 disp_ret = init_sam_dispinfo_5(p->mem_ctx, &ctr->sam.info5,
1323                                                num_account, enum_context,
1324                                                entries);
1325                 break;
1326         default:
1327                 smb_panic("info class changed");
1328                 break;
1329         }
1330
1331         if (!NT_STATUS_IS_OK(disp_ret))
1332                 return disp_ret;
1333
1334         /* calculate the total size */
1335         total_data_size=num_account*struct_size;
1336
1337         if (num_account) {
1338                 r_u->status = STATUS_MORE_ENTRIES;
1339         } else {
1340                 r_u->status = NT_STATUS_OK;
1341         }
1342
1343         /* Ensure we cache this enumeration. */
1344         set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
1345
1346         DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1347
1348         init_samr_r_query_dispinfo(r_u, num_account, total_data_size,
1349                                    temp_size, q_u->switch_level, ctr,
1350                                    r_u->status);
1351
1352         return r_u->status;
1353
1354 }
1355
1356 /*******************************************************************
1357  samr_reply_query_aliasinfo
1358  ********************************************************************/
1359
1360 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1361 {
1362         DOM_SID   sid;
1363         struct acct_info info;
1364         uint32    acc_granted;
1365         BOOL ret;
1366
1367         r_u->status = NT_STATUS_OK;
1368
1369         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1370
1371         /* find the policy handle.  open a policy on it. */
1372         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL))
1373                 return NT_STATUS_INVALID_HANDLE;
1374         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1375                 return r_u->status;
1376         }
1377
1378         become_root();
1379         ret = pdb_get_aliasinfo(&sid, &info);
1380         unbecome_root();
1381         
1382         if ( !ret )
1383                 return NT_STATUS_NO_SUCH_ALIAS;
1384
1385         if ( !(r_u->ctr = TALLOC_ZERO_P( p->mem_ctx, ALIAS_INFO_CTR )) ) 
1386                 return NT_STATUS_NO_MEMORY;
1387
1388
1389         switch (q_u->level ) {
1390         case 1:
1391                 r_u->ctr->level = 1;
1392                 init_samr_alias_info1(&r_u->ctr->alias.info1, info.acct_name, 1, info.acct_desc);
1393                 break;
1394         case 3:
1395                 r_u->ctr->level = 3;
1396                 init_samr_alias_info3(&r_u->ctr->alias.info3, info.acct_desc);
1397                 break;
1398         default:
1399                 return NT_STATUS_INVALID_INFO_CLASS;
1400         }
1401
1402         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1403
1404         return r_u->status;
1405 }
1406
1407 #if 0
1408 /*******************************************************************
1409  samr_reply_lookup_ids
1410  ********************************************************************/
1411
1412  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1413 {
1414     uint32 rid[MAX_SAM_ENTRIES];
1415     int num_rids = q_u->num_sids1;
1416
1417     r_u->status = NT_STATUS_OK;
1418
1419     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1420
1421     if (num_rids > MAX_SAM_ENTRIES) {
1422         num_rids = MAX_SAM_ENTRIES;
1423         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1424     }
1425
1426 #if 0
1427     int i;
1428     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1429
1430     for (i = 0; i < num_rids && status == 0; i++)
1431     {
1432         struct sam_passwd *sam_pass;
1433         fstring user_name;
1434
1435
1436         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1437                                     q_u->uni_user_name[i].uni_str_len));
1438
1439         /* find the user account */
1440         become_root();
1441         sam_pass = get_smb21pwd_entry(user_name, 0);
1442         unbecome_root();
1443
1444         if (sam_pass == NULL)
1445         {
1446             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1447             rid[i] = 0;
1448         }
1449         else
1450         {
1451             rid[i] = sam_pass->user_rid;
1452         }
1453     }
1454 #endif
1455
1456     num_rids = 1;
1457     rid[0] = BUILTIN_ALIAS_RID_USERS;
1458
1459     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1460
1461     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1462
1463     return r_u->status;
1464 }
1465 #endif
1466
1467 /*******************************************************************
1468  _samr_lookup_names
1469  ********************************************************************/
1470
1471 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1472 {
1473         uint32 rid[MAX_SAM_ENTRIES];
1474         enum lsa_SidType type[MAX_SAM_ENTRIES];
1475         int i;
1476         int num_rids = q_u->num_names2;
1477         DOM_SID pol_sid;
1478         fstring sid_str;
1479         uint32  acc_granted;
1480
1481         r_u->status = NT_STATUS_OK;
1482
1483         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1484
1485         ZERO_ARRAY(rid);
1486         ZERO_ARRAY(type);
1487
1488         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL)) {
1489                 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1490                 return r_u->status;
1491         }
1492         
1493         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1494                 return r_u->status;
1495         }
1496
1497         if (num_rids > MAX_SAM_ENTRIES) {
1498                 num_rids = MAX_SAM_ENTRIES;
1499                 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1500         }
1501
1502         DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1503         
1504         for (i = 0; i < num_rids; i++) {
1505                 fstring name;
1506                 int ret;
1507
1508                 r_u->status = NT_STATUS_NONE_MAPPED;
1509                 type[i] = SID_NAME_UNKNOWN;
1510
1511                 rid [i] = 0xffffffff;
1512
1513                 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1514
1515                 if (ret <= 0) {
1516                         continue;
1517                 }
1518
1519                 if (sid_check_is_builtin(&pol_sid)) {
1520                         if (lookup_builtin_name(name, &rid[i])) {
1521                                 type[i] = SID_NAME_ALIAS;
1522                         }
1523                 } else {
1524                         lookup_global_sam_name(name, 0, &rid[i], &type[i]);
1525                 }
1526
1527                 if (type[i] != SID_NAME_UNKNOWN) {
1528                         r_u->status = NT_STATUS_OK;
1529                 }
1530         }
1531
1532         init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, type, r_u->status);
1533
1534         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1535
1536         return r_u->status;
1537 }
1538
1539 /*******************************************************************
1540  _samr_chgpasswd_user
1541  ********************************************************************/
1542
1543 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1544 {
1545         fstring user_name;
1546         fstring wks;
1547
1548         DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1549
1550         r_u->status = NT_STATUS_OK;
1551
1552         rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1553         rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1554
1555         DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1556
1557         /*
1558          * Pass the user through the NT -> unix user mapping
1559          * function.
1560          */
1561  
1562         (void)map_username(user_name);
1563  
1564         /*
1565          * UNIX username case mangling not required, pass_oem_change 
1566          * is case insensitive.
1567          */
1568
1569         r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1570                                 q_u->nt_newpass.pass, q_u->nt_oldhash.hash, NULL);
1571
1572         init_samr_r_chgpasswd_user(r_u, r_u->status);
1573
1574         DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1575
1576         return r_u->status;
1577 }
1578
1579 /*******************************************************************
1580  _samr_chgpasswd_user3
1581  ********************************************************************/
1582
1583 NTSTATUS _samr_chgpasswd_user3(pipes_struct *p, SAMR_Q_CHGPASSWD_USER3 *q_u, SAMR_R_CHGPASSWD_USER3 *r_u)
1584 {
1585         fstring user_name;
1586         fstring wks;
1587         uint32 reject_reason;
1588         SAM_UNK_INFO_1 *info = NULL;
1589         SAMR_CHANGE_REJECT *reject = NULL;
1590
1591         DEBUG(5,("_samr_chgpasswd_user3: %d\n", __LINE__));
1592
1593         rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1594         rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1595
1596         DEBUG(5,("_samr_chgpasswd_user3: user: %s wks: %s\n", user_name, wks));
1597
1598         /*
1599          * Pass the user through the NT -> unix user mapping
1600          * function.
1601          */
1602  
1603         (void)map_username(user_name);
1604  
1605         /*
1606          * UNIX username case mangling not required, pass_oem_change 
1607          * is case insensitive.
1608          */
1609
1610         r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1611                                       q_u->nt_newpass.pass, q_u->nt_oldhash.hash, &reject_reason);
1612
1613         if (NT_STATUS_EQUAL(r_u->status, NT_STATUS_PASSWORD_RESTRICTION) || 
1614             NT_STATUS_EQUAL(r_u->status, NT_STATUS_ACCOUNT_RESTRICTION)) {
1615
1616                 uint32 min_pass_len,pass_hist,password_properties;
1617                 time_t u_expire, u_min_age;
1618                 NTTIME nt_expire, nt_min_age;
1619                 uint32 account_policy_temp;
1620
1621                 if ((info = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_INFO_1)) == NULL) {
1622                         return NT_STATUS_NO_MEMORY;
1623                 }
1624
1625                 if ((reject = TALLOC_ZERO_P(p->mem_ctx, SAMR_CHANGE_REJECT)) == NULL) {
1626                         return NT_STATUS_NO_MEMORY;
1627                 }
1628
1629                 ZERO_STRUCTP(info);
1630                 ZERO_STRUCTP(reject);
1631
1632                 become_root();
1633
1634                 /* AS ROOT !!! */
1635
1636                 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
1637                 min_pass_len = account_policy_temp;
1638
1639                 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
1640                 pass_hist = account_policy_temp;
1641
1642                 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
1643                 password_properties = account_policy_temp;
1644
1645                 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
1646                 u_expire = account_policy_temp;
1647
1648                 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
1649                 u_min_age = account_policy_temp;
1650
1651                 /* !AS ROOT */
1652                 
1653                 unbecome_root();
1654
1655                 unix_to_nt_time_abs(&nt_expire, u_expire);
1656                 unix_to_nt_time_abs(&nt_min_age, u_min_age);
1657
1658                 init_unk_info1(info, (uint16)min_pass_len, (uint16)pass_hist, 
1659                                password_properties, nt_expire, nt_min_age);
1660
1661                 reject->reject_reason = reject_reason;
1662         }
1663         
1664         init_samr_r_chgpasswd_user3(r_u, r_u->status, reject, info);
1665
1666         DEBUG(5,("_samr_chgpasswd_user3: %d\n", __LINE__));
1667
1668         return r_u->status;
1669 }
1670
1671 /*******************************************************************
1672 makes a SAMR_R_LOOKUP_RIDS structure.
1673 ********************************************************************/
1674
1675 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1676                                   const char **names, UNIHDR **pp_hdr_name,
1677                                   UNISTR2 **pp_uni_name)
1678 {
1679         uint32 i;
1680         UNIHDR *hdr_name=NULL;
1681         UNISTR2 *uni_name=NULL;
1682
1683         *pp_uni_name = NULL;
1684         *pp_hdr_name = NULL;
1685
1686         if (num_names != 0) {
1687                 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1688                 if (hdr_name == NULL)
1689                         return False;
1690
1691                 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1692                 if (uni_name == NULL)
1693                         return False;
1694         }
1695
1696         for (i = 0; i < num_names; i++) {
1697                 DEBUG(10, ("names[%d]:%s\n", i, names[i] && *names[i] ? names[i] : ""));
1698                 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1699                 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1700         }
1701
1702         *pp_uni_name = uni_name;
1703         *pp_hdr_name = hdr_name;
1704
1705         return True;
1706 }
1707
1708 /*******************************************************************
1709  _samr_lookup_rids
1710  ********************************************************************/
1711
1712 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1713 {
1714         const char **names;
1715         enum lsa_SidType *attrs = NULL;
1716         uint32 *wire_attrs = NULL;
1717         UNIHDR *hdr_name = NULL;
1718         UNISTR2 *uni_name = NULL;
1719         DOM_SID pol_sid;
1720         int num_rids = q_u->num_rids1;
1721         uint32 acc_granted;
1722         int i;
1723
1724         r_u->status = NT_STATUS_OK;
1725
1726         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1727
1728         /* find the policy handle.  open a policy on it. */
1729         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted, NULL))
1730                 return NT_STATUS_INVALID_HANDLE;
1731
1732         if (num_rids > 1000) {
1733                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1734                           "to samba4 idl this is not possible\n", num_rids));
1735                 return NT_STATUS_UNSUCCESSFUL;
1736         }
1737
1738         names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
1739         attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, enum lsa_SidType, num_rids);
1740         wire_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
1741
1742         if ((num_rids != 0) && ((names == NULL) || (attrs == NULL) || (wire_attrs==NULL)))
1743                 return NT_STATUS_NO_MEMORY;
1744
1745         become_root();  /* lookup_sid can require root privs */
1746         r_u->status = pdb_lookup_rids(&pol_sid, num_rids, q_u->rid,
1747                                       names, attrs);
1748         unbecome_root();
1749
1750         if ( NT_STATUS_EQUAL(r_u->status, NT_STATUS_NONE_MAPPED) && (num_rids == 0) ) {
1751                 r_u->status = NT_STATUS_OK;
1752         }
1753
1754         if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
1755                                   &hdr_name, &uni_name))
1756                 return NT_STATUS_NO_MEMORY;
1757
1758         /* Convert from enum lsa_SidType to uint32 for wire format. */
1759         for (i = 0; i < num_rids; i++) {
1760                 wire_attrs[i] = (uint32)attrs[i];
1761         }
1762
1763         init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, wire_attrs);
1764
1765         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1766
1767         return r_u->status;
1768 }
1769
1770 /*******************************************************************
1771  _samr_open_user. Safe - gives out no passwd info.
1772  ********************************************************************/
1773
1774 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1775 {
1776         struct samu *sampass=NULL;
1777         DOM_SID sid;
1778         POLICY_HND domain_pol = q_u->domain_pol;
1779         POLICY_HND *user_pol = &r_u->user_pol;
1780         struct samr_info *info = NULL;
1781         SEC_DESC *psd = NULL;
1782         uint32    acc_granted;
1783         uint32    des_access = q_u->access_mask;
1784         size_t    sd_size;
1785         BOOL ret;
1786         NTSTATUS nt_status;
1787         SE_PRIV se_rights;
1788
1789         r_u->status = NT_STATUS_OK;
1790
1791         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1792         
1793         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
1794                 return NT_STATUS_INVALID_HANDLE;
1795         
1796         nt_status = access_check_samr_function( acc_granted, 
1797                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1798                 
1799         if ( !NT_STATUS_IS_OK(nt_status) )
1800                 return nt_status;
1801
1802         if ( !(sampass = samu_new( p->mem_ctx )) ) {
1803                 return NT_STATUS_NO_MEMORY;
1804         }
1805
1806         /* append the user's RID to it */
1807         
1808         if (!sid_append_rid(&sid, q_u->user_rid))
1809                 return NT_STATUS_NO_SUCH_USER;
1810         
1811         /* check if access can be granted as requested by client. */
1812         
1813         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1814         se_map_generic(&des_access, &usr_generic_mapping);
1815         
1816         se_priv_copy( &se_rights, &se_machine_account );
1817         se_priv_add( &se_rights, &se_add_users );
1818         
1819         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
1820                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
1821                 &acc_granted, "_samr_open_user");
1822                 
1823         if ( !NT_STATUS_IS_OK(nt_status) )
1824                 return nt_status;
1825
1826         become_root();
1827         ret=pdb_getsampwsid(sampass, &sid);
1828         unbecome_root();
1829
1830         /* check that the SID exists in our domain. */
1831         if (ret == False) {
1832                 return NT_STATUS_NO_SUCH_USER;
1833         }
1834
1835         TALLOC_FREE(sampass);
1836
1837         /* associate the user's SID and access bits with the new handle. */
1838         if ((info = get_samr_info_by_sid(&sid)) == NULL)
1839                 return NT_STATUS_NO_MEMORY;
1840         info->acc_granted = acc_granted;
1841
1842         /* get a (unique) handle.  open a policy on it. */
1843         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1844                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1845
1846         return r_u->status;
1847 }
1848
1849 /*************************************************************************
1850  get_user_info_7. Safe. Only gives out account_name.
1851  *************************************************************************/
1852
1853 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1854 {
1855         struct samu *smbpass=NULL;
1856         BOOL ret;
1857
1858         if ( !(smbpass = samu_new( mem_ctx )) ) {
1859                 return NT_STATUS_NO_MEMORY;
1860         }
1861         
1862         become_root();
1863         ret = pdb_getsampwsid(smbpass, user_sid);
1864         unbecome_root();
1865
1866         if ( !ret ) {
1867                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1868                 return NT_STATUS_NO_SUCH_USER;
1869         }
1870
1871         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1872
1873         ZERO_STRUCTP(id7);
1874         init_sam_user_info7(id7, pdb_get_username(smbpass) );
1875
1876         TALLOC_FREE(smbpass);
1877
1878         return NT_STATUS_OK;
1879 }
1880
1881 /*************************************************************************
1882  get_user_info_9. Only gives out primary group SID.
1883  *************************************************************************/
1884 static NTSTATUS get_user_info_9(TALLOC_CTX *mem_ctx, SAM_USER_INFO_9 * id9, DOM_SID *user_sid)
1885 {
1886         struct samu *smbpass=NULL;
1887         BOOL ret;
1888
1889         if ( !(smbpass = samu_new( mem_ctx )) ) {
1890                 return NT_STATUS_NO_MEMORY;
1891         }
1892
1893         become_root();
1894         ret = pdb_getsampwsid(smbpass, user_sid);
1895         unbecome_root();
1896
1897         if (ret==False) {
1898                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1899                 return NT_STATUS_NO_SUCH_USER;
1900         }
1901
1902         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1903
1904         ZERO_STRUCTP(id9);
1905         init_sam_user_info9(id9, pdb_get_group_rid(smbpass) );
1906
1907         TALLOC_FREE(smbpass);
1908
1909         return NT_STATUS_OK;
1910 }
1911
1912 /*************************************************************************
1913  get_user_info_16. Safe. Only gives out acb bits.
1914  *************************************************************************/
1915
1916 static NTSTATUS get_user_info_16(TALLOC_CTX *mem_ctx, SAM_USER_INFO_16 *id16, DOM_SID *user_sid)
1917 {
1918         struct samu *smbpass=NULL;
1919         BOOL ret;
1920
1921         if ( !(smbpass = samu_new( mem_ctx )) ) {
1922                 return NT_STATUS_NO_MEMORY;
1923         }
1924
1925         become_root();
1926         ret = pdb_getsampwsid(smbpass, user_sid);
1927         unbecome_root();
1928
1929         if (ret==False) {
1930                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1931                 return NT_STATUS_NO_SUCH_USER;
1932         }
1933
1934         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1935
1936         ZERO_STRUCTP(id16);
1937         init_sam_user_info16(id16, pdb_get_acct_ctrl(smbpass) );
1938
1939         TALLOC_FREE(smbpass);
1940
1941         return NT_STATUS_OK;
1942 }
1943
1944 /*************************************************************************
1945  get_user_info_18. OK - this is the killer as it gives out password info.
1946  Ensure that this is only allowed on an encrypted connection with a root
1947  user. JRA. 
1948  *************************************************************************/
1949
1950 static NTSTATUS get_user_info_18(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_18 * id18, DOM_SID *user_sid)
1951 {
1952         struct samu *smbpass=NULL;
1953         BOOL ret;
1954
1955         if (p->auth.auth_type != PIPE_AUTH_TYPE_NTLMSSP || p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP) {
1956                 return NT_STATUS_ACCESS_DENIED;
1957         }
1958
1959         if (p->auth.auth_level != PIPE_AUTH_LEVEL_PRIVACY) {
1960                 return NT_STATUS_ACCESS_DENIED;
1961         }
1962
1963         /*
1964          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1965          */
1966
1967         if ( !(smbpass = samu_new( mem_ctx )) ) {
1968                 return NT_STATUS_NO_MEMORY;
1969         }
1970
1971         ret = pdb_getsampwsid(smbpass, user_sid);
1972
1973         if (ret == False) {
1974                 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1975                 TALLOC_FREE(smbpass);
1976                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1977         }
1978
1979         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1980
1981         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1982                 TALLOC_FREE(smbpass);
1983                 return NT_STATUS_ACCOUNT_DISABLED;
1984         }
1985
1986         ZERO_STRUCTP(id18);
1987         init_sam_user_info18(id18, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1988         
1989         TALLOC_FREE(smbpass);
1990
1991         return NT_STATUS_OK;
1992 }
1993
1994 /*************************************************************************
1995  get_user_info_20
1996  *************************************************************************/
1997
1998 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1999 {
2000         struct samu *sampass=NULL;
2001         BOOL ret;
2002
2003         if ( !(sampass = samu_new( mem_ctx )) ) {
2004                 return NT_STATUS_NO_MEMORY;
2005         }
2006
2007         become_root();
2008         ret = pdb_getsampwsid(sampass, user_sid);
2009         unbecome_root();
2010
2011         if (ret == False) {
2012                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
2013                 return NT_STATUS_NO_SUCH_USER;
2014         }
2015
2016         samr_clear_sam_passwd(sampass);
2017
2018         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
2019
2020         ZERO_STRUCTP(id20);
2021         init_sam_user_info20A(id20, sampass);
2022         
2023         TALLOC_FREE(sampass);
2024
2025         return NT_STATUS_OK;
2026 }
2027
2028 /*************************************************************************
2029  get_user_info_21
2030  *************************************************************************/
2031
2032 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, 
2033                                  DOM_SID *user_sid, DOM_SID *domain_sid)
2034 {
2035         struct samu *sampass=NULL;
2036         BOOL ret;
2037         NTSTATUS nt_status;
2038
2039         if ( !(sampass = samu_new( mem_ctx )) ) {
2040                 return NT_STATUS_NO_MEMORY;
2041         }
2042
2043         become_root();
2044         ret = pdb_getsampwsid(sampass, user_sid);
2045         unbecome_root();
2046
2047         if (ret == False) {
2048                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
2049                 return NT_STATUS_NO_SUCH_USER;
2050         }
2051
2052         samr_clear_sam_passwd(sampass);
2053
2054         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
2055
2056         ZERO_STRUCTP(id21);
2057         nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
2058         
2059         TALLOC_FREE(sampass);
2060
2061         return nt_status;
2062 }
2063
2064 /*******************************************************************
2065  _samr_query_userinfo
2066  ********************************************************************/
2067
2068 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
2069 {
2070         SAM_USERINFO_CTR *ctr;
2071         struct samr_info *info = NULL;
2072         DOM_SID domain_sid;
2073         uint32 rid;
2074         
2075         r_u->status=NT_STATUS_OK;
2076
2077         /* search for the handle */
2078         if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
2079                 return NT_STATUS_INVALID_HANDLE;
2080
2081         domain_sid = info->sid;
2082
2083         sid_split_rid(&domain_sid, &rid);
2084
2085         if (!sid_check_is_in_our_domain(&info->sid))
2086                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2087
2088         DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
2089
2090         ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
2091         if (!ctr)
2092                 return NT_STATUS_NO_MEMORY;
2093
2094         ZERO_STRUCTP(ctr);
2095
2096         /* ok!  user info levels (lots: see MSDEV help), off we go... */
2097         ctr->switch_value = q_u->switch_value;
2098
2099         DEBUG(5,("_samr_query_userinfo: user info level: %d\n", q_u->switch_value));
2100
2101         switch (q_u->switch_value) {
2102         case 7:
2103                 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
2104                 if (ctr->info.id7 == NULL)
2105                         return NT_STATUS_NO_MEMORY;
2106
2107                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
2108                         return r_u->status;
2109                 break;
2110         case 9:
2111                 ctr->info.id9 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_9);
2112                 if (ctr->info.id9 == NULL)
2113                         return NT_STATUS_NO_MEMORY;
2114
2115                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_9(p->mem_ctx, ctr->info.id9, &info->sid)))
2116                         return r_u->status;
2117                 break;
2118         case 16:
2119                 ctr->info.id16 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_16);
2120                 if (ctr->info.id16 == NULL)
2121                         return NT_STATUS_NO_MEMORY;
2122
2123                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_16(p->mem_ctx, ctr->info.id16, &info->sid)))
2124                         return r_u->status;
2125                 break;
2126
2127         case 18:
2128                 ctr->info.id18 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_18);
2129                 if (ctr->info.id18 == NULL)
2130                         return NT_STATUS_NO_MEMORY;
2131
2132                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_18(p, p->mem_ctx, ctr->info.id18, &info->sid)))
2133                         return r_u->status;
2134                 break;
2135                 
2136         case 20:
2137                 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
2138                 if (ctr->info.id20 == NULL)
2139                         return NT_STATUS_NO_MEMORY;
2140                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
2141                         return r_u->status;
2142                 break;
2143
2144         case 21:
2145                 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
2146                 if (ctr->info.id21 == NULL)
2147                         return NT_STATUS_NO_MEMORY;
2148                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, 
2149                                                                     &info->sid, &domain_sid)))
2150                         return r_u->status;
2151                 break;
2152
2153         default:
2154                 return NT_STATUS_INVALID_INFO_CLASS;
2155         }
2156
2157         init_samr_r_query_userinfo(r_u, ctr, r_u->status);
2158
2159         DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
2160         
2161         return r_u->status;
2162 }
2163
2164 /*******************************************************************
2165  samr_reply_query_usergroups
2166  ********************************************************************/
2167
2168 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
2169 {
2170         struct samu *sam_pass=NULL;
2171         DOM_SID  sid;
2172         DOM_SID *sids;
2173         DOM_GID dom_gid;
2174         DOM_GID *gids = NULL;
2175         uint32 primary_group_rid;
2176         size_t num_groups = 0;
2177         gid_t *unix_gids;
2178         size_t i, num_gids;
2179         uint32 acc_granted;
2180         BOOL ret;
2181         NTSTATUS result;
2182         BOOL success = False;
2183
2184         /*
2185          * from the SID in the request:
2186          * we should send back the list of DOMAIN GROUPS
2187          * the user is a member of
2188          *
2189          * and only the DOMAIN GROUPS
2190          * no ALIASES !!! neither aliases of the domain
2191          * nor aliases of the builtin SID
2192          *
2193          * JFM, 12/2/2001
2194          */
2195
2196         r_u->status = NT_STATUS_OK;
2197
2198         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2199
2200         /* find the policy handle.  open a policy on it. */
2201         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted, NULL))
2202                 return NT_STATUS_INVALID_HANDLE;
2203         
2204         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
2205                 return r_u->status;
2206         }
2207
2208         if (!sid_check_is_in_our_domain(&sid))
2209                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
2210
2211         if ( !(sam_pass = samu_new( p->mem_ctx )) ) {
2212                 return NT_STATUS_NO_MEMORY;
2213         }
2214
2215         become_root();
2216         ret = pdb_getsampwsid(sam_pass, &sid);
2217         unbecome_root();
2218
2219         if (!ret) {
2220                 DEBUG(10, ("pdb_getsampwsid failed for %s\n",
2221                            sid_string_static(&sid)));
2222                 return NT_STATUS_NO_SUCH_USER;
2223         }
2224
2225         sids = NULL;
2226
2227         /* make both calls inside the root block */
2228         become_root();
2229         result = pdb_enum_group_memberships(p->mem_ctx, sam_pass,
2230                                             &sids, &unix_gids, &num_groups);
2231         if ( NT_STATUS_IS_OK(result) ) {
2232                 success = sid_peek_check_rid(get_global_sam_sid(), 
2233                                              pdb_get_group_sid(sam_pass),
2234                                              &primary_group_rid);
2235         }
2236         unbecome_root();
2237
2238         if (!NT_STATUS_IS_OK(result)) {
2239                 DEBUG(10, ("pdb_enum_group_memberships failed for %s\n",
2240                            sid_string_static(&sid)));
2241                 return result;
2242         }
2243
2244         if ( !success ) {
2245                 DEBUG(5, ("Group sid %s for user %s not in our domain\n",
2246                           sid_string_static(pdb_get_group_sid(sam_pass)),
2247                           pdb_get_username(sam_pass)));
2248                 TALLOC_FREE(sam_pass);
2249                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
2250         }
2251
2252         gids = NULL;
2253         num_gids = 0;
2254
2255         dom_gid.attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
2256                         SE_GROUP_ENABLED);
2257         dom_gid.g_rid = primary_group_rid;
2258         ADD_TO_ARRAY(p->mem_ctx, DOM_GID, dom_gid, &gids, &num_gids);
2259
2260         for (i=0; i<num_groups; i++) {
2261
2262                 if (!sid_peek_check_rid(get_global_sam_sid(),
2263                                         &(sids[i]), &dom_gid.g_rid)) {
2264                         DEBUG(10, ("Found sid %s not in our domain\n",
2265                                    sid_string_static(&sids[i])));
2266                         continue;
2267                 }
2268
2269                 if (dom_gid.g_rid == primary_group_rid) {
2270                         /* We added the primary group directly from the
2271                          * sam_account. The other SIDs are unique from
2272                          * enum_group_memberships */
2273                         continue;
2274                 }
2275
2276                 ADD_TO_ARRAY(p->mem_ctx, DOM_GID, dom_gid, &gids, &num_gids);
2277         }
2278         
2279         /* construct the response.  lkclXXXX: gids are not copied! */
2280         init_samr_r_query_usergroups(r_u, num_gids, gids, r_u->status);
2281         
2282         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2283         
2284         return r_u->status;
2285 }
2286
2287 /*******************************************************************
2288  _samr_query_domain_info
2289  ********************************************************************/
2290
2291 NTSTATUS _samr_query_domain_info(pipes_struct *p, 
2292                                  SAMR_Q_QUERY_DOMAIN_INFO *q_u, 
2293                                  SAMR_R_QUERY_DOMAIN_INFO *r_u)
2294 {
2295         struct samr_info *info = NULL;
2296         SAM_UNK_CTR *ctr;
2297         uint32 min_pass_len,pass_hist,password_properties;
2298         time_t u_expire, u_min_age;
2299         NTTIME nt_expire, nt_min_age;
2300
2301         time_t u_lock_duration, u_reset_time;
2302         NTTIME nt_lock_duration, nt_reset_time;
2303         uint32 lockout;
2304         time_t u_logout;
2305         NTTIME nt_logout;
2306
2307         uint32 account_policy_temp;
2308
2309         time_t seq_num;
2310         uint32 server_role;
2311
2312         uint32 num_users=0, num_groups=0, num_aliases=0;
2313
2314         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL) {
2315                 return NT_STATUS_NO_MEMORY;
2316         }
2317
2318         ZERO_STRUCTP(ctr);
2319
2320         r_u->status = NT_STATUS_OK;
2321         
2322         DEBUG(5,("_samr_query_domain_info: %d\n", __LINE__));
2323         
2324         /* find the policy handle.  open a policy on it. */
2325         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info)) {
2326                 return NT_STATUS_INVALID_HANDLE;
2327         }
2328         
2329         switch (q_u->switch_value) {
2330                 case 0x01:
2331                         
2332                         become_root();
2333
2334                         /* AS ROOT !!! */
2335
2336                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2337                         min_pass_len = account_policy_temp;
2338
2339                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2340                         pass_hist = account_policy_temp;
2341
2342                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2343                         password_properties = account_policy_temp;
2344
2345                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2346                         u_expire = account_policy_temp;
2347
2348                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2349                         u_min_age = account_policy_temp;
2350
2351                         /* !AS ROOT */
2352                         
2353                         unbecome_root();
2354
2355                         unix_to_nt_time_abs(&nt_expire, u_expire);
2356                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2357
2358                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
2359                                        password_properties, nt_expire, nt_min_age);
2360                         break;
2361                 case 0x02:
2362
2363                         become_root();
2364
2365                         /* AS ROOT !!! */
2366
2367                         num_users = count_sam_users(info->disp_info, ACB_NORMAL);
2368                         num_groups = count_sam_groups(info->disp_info);
2369                         num_aliases = count_sam_aliases(info->disp_info);
2370
2371                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2372                         u_logout = account_policy_temp;
2373
2374                         unix_to_nt_time_abs(&nt_logout, u_logout);
2375
2376                         if (!pdb_get_seq_num(&seq_num))
2377                                 seq_num = time(NULL);
2378
2379                         /* !AS ROOT */
2380                         
2381                         unbecome_root();
2382
2383                         server_role = ROLE_DOMAIN_PDC;
2384                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2385                                 server_role = ROLE_DOMAIN_BDC;
2386
2387                         init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), seq_num, 
2388                                        num_users, num_groups, num_aliases, nt_logout, server_role);
2389                         break;
2390                 case 0x03:
2391
2392                         become_root();
2393
2394                         /* AS ROOT !!! */
2395
2396                         {
2397                                 uint32 ul;
2398                                 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &ul);
2399                                 u_logout = (time_t)ul;
2400                         }
2401
2402                         /* !AS ROOT */
2403                         
2404                         unbecome_root();
2405
2406                         unix_to_nt_time_abs(&nt_logout, u_logout);
2407                         
2408                         init_unk_info3(&ctr->info.inf3, nt_logout);
2409                         break;
2410                 case 0x04:
2411                         init_unk_info4(&ctr->info.inf4, lp_serverstring());
2412                         break;
2413                 case 0x05:
2414                         init_unk_info5(&ctr->info.inf5, get_global_sam_name());
2415                         break;
2416                 case 0x06:
2417                         /* NT returns its own name when a PDC. win2k and later
2418                          * only the name of the PDC if itself is a BDC (samba4
2419                          * idl) */
2420                         init_unk_info6(&ctr->info.inf6, global_myname());
2421                         break;
2422                 case 0x07:
2423                         server_role = ROLE_DOMAIN_PDC;
2424                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2425                                 server_role = ROLE_DOMAIN_BDC;
2426
2427                         init_unk_info7(&ctr->info.inf7, server_role);
2428                         break;
2429                 case 0x08:
2430
2431                         become_root();
2432
2433                         /* AS ROOT !!! */
2434
2435                         if (!pdb_get_seq_num(&seq_num)) {
2436                                 seq_num = time(NULL);
2437                         }
2438
2439                         /* !AS ROOT */
2440                         
2441                         unbecome_root();
2442
2443                         init_unk_info8(&ctr->info.inf8, (uint32) seq_num);
2444                         break;
2445                 case 0x0c:
2446
2447                         become_root();
2448
2449                         /* AS ROOT !!! */
2450
2451                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2452                         u_lock_duration = account_policy_temp;
2453                         if (u_lock_duration != -1) {
2454                                 u_lock_duration *= 60;
2455                         }
2456
2457                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2458                         u_reset_time = account_policy_temp * 60;
2459
2460                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2461                         lockout = account_policy_temp;
2462
2463                         /* !AS ROOT */
2464                         
2465                         unbecome_root();
2466
2467                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2468                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2469         
2470                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2471                         break;
2472                 default:
2473                         return NT_STATUS_INVALID_INFO_CLASS;
2474                 }
2475         
2476
2477         init_samr_r_query_domain_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2478         
2479         DEBUG(5,("_samr_query_domain_info: %d\n", __LINE__));
2480         
2481         return r_u->status;
2482 }
2483
2484 /* W2k3 seems to use the same check for all 3 objects that can be created via
2485  * SAMR, if you try to create for example "Dialup" as an alias it says
2486  * "NT_STATUS_USER_EXISTS". This is racy, but we can't really lock the user
2487  * database. */
2488
2489 static NTSTATUS can_create(TALLOC_CTX *mem_ctx, const char *new_name)
2490 {
2491         enum lsa_SidType type;
2492         BOOL result;
2493
2494         DEBUG(10, ("Checking whether [%s] can be created\n", new_name));
2495
2496         become_root();
2497         /* Lookup in our local databases (only LOOKUP_NAME_ISOLATED set)
2498          * whether the name already exists */
2499         result = lookup_name(mem_ctx, new_name, LOOKUP_NAME_ISOLATED,
2500                              NULL, NULL, NULL, &type);
2501         unbecome_root();
2502
2503         if (!result) {
2504                 DEBUG(10, ("%s does not exist, can create it\n", new_name));
2505                 return NT_STATUS_OK;
2506         }
2507
2508         DEBUG(5, ("trying to create %s, exists as %s\n",
2509                   new_name, sid_type_lookup(type)));
2510
2511         if (type == SID_NAME_DOM_GRP) {
2512                 return NT_STATUS_GROUP_EXISTS;
2513         }
2514         if (type == SID_NAME_ALIAS) {
2515                 return NT_STATUS_ALIAS_EXISTS;
2516         }
2517
2518         /* Yes, the default is NT_STATUS_USER_EXISTS */
2519         return NT_STATUS_USER_EXISTS;
2520 }
2521
2522 /*******************************************************************
2523  _samr_create_user
2524  Create an account, can be either a normal user or a machine.
2525  This funcion will need to be updated for bdc/domain trusts.
2526  ********************************************************************/
2527
2528 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u,
2529                            SAMR_R_CREATE_USER *r_u)
2530 {
2531         char *account;
2532         DOM_SID sid;
2533         POLICY_HND dom_pol = q_u->domain_pol;
2534         uint16 acb_info = q_u->acb_info;
2535         POLICY_HND *user_pol = &r_u->user_pol;
2536         struct samr_info *info = NULL;
2537         NTSTATUS nt_status;
2538         uint32 acc_granted;
2539         SEC_DESC *psd;
2540         size_t    sd_size;
2541         /* check this, when giving away 'add computer to domain' privs */
2542         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2543         BOOL can_add_account = False;
2544         SE_PRIV se_rights;
2545         DISP_INFO *disp_info = NULL;
2546
2547         /* Get the domain SID stored in the domain policy */
2548         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted,
2549                                      &disp_info))
2550                 return NT_STATUS_INVALID_HANDLE;
2551
2552         nt_status = access_check_samr_function(acc_granted,
2553                                                SA_RIGHT_DOMAIN_CREATE_USER,
2554                                                "_samr_create_user");
2555         if (!NT_STATUS_IS_OK(nt_status)) {
2556                 return nt_status;
2557         }
2558
2559         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST ||
2560               acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { 
2561                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if 
2562                    this parameter is not an account type */
2563                 return NT_STATUS_INVALID_PARAMETER;
2564         }
2565
2566         account = rpcstr_pull_unistr2_talloc(p->mem_ctx, &q_u->uni_name);
2567         if (account == NULL) {
2568                 return NT_STATUS_NO_MEMORY;
2569         }
2570
2571         nt_status = can_create(p->mem_ctx, account);
2572         if (!NT_STATUS_IS_OK(nt_status)) {
2573                 return nt_status;
2574         }
2575
2576         /* determine which user right we need to check based on the acb_info */
2577         
2578         if ( acb_info & ACB_WSTRUST )
2579         {
2580                 se_priv_copy( &se_rights, &se_machine_account );
2581                 can_add_account = user_has_privileges(
2582                         p->pipe_user.nt_user_token, &se_rights );
2583         } 
2584         /* usrmgr.exe (and net rpc trustdom grant) creates a normal user 
2585            account for domain trusts and changes the ACB flags later */
2586         else if ( acb_info & ACB_NORMAL &&
2587                   (account[strlen(account)-1] != '$') )
2588         {
2589                 se_priv_copy( &se_rights, &se_add_users );
2590                 can_add_account = user_has_privileges(
2591                         p->pipe_user.nt_user_token, &se_rights );
2592         } 
2593         else    /* implicit assumption of a BDC or domain trust account here
2594                  * (we already check the flags earlier) */
2595         {
2596                 if ( lp_enable_privileges() ) {
2597                         /* only Domain Admins can add a BDC or domain trust */
2598                         se_priv_copy( &se_rights, &se_priv_none );
2599                         can_add_account = nt_token_check_domain_rid(
2600                                 p->pipe_user.nt_user_token,
2601                                 DOMAIN_GROUP_RID_ADMINS );
2602                 }
2603         }
2604                 
2605         DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2606                   uidtoname(p->pipe_user.ut.uid),
2607                   can_add_account ? "True":"False" ));
2608                 
2609         /********** BEGIN Admin BLOCK **********/
2610
2611         if ( can_add_account )
2612                 become_root();
2613
2614         nt_status = pdb_create_user(p->mem_ctx, account, acb_info,
2615                                     &r_u->user_rid);
2616
2617         if ( can_add_account )
2618                 unbecome_root();
2619
2620         /********** END Admin BLOCK **********/
2621         
2622         /* now check for failure */
2623         
2624         if ( !NT_STATUS_IS_OK(nt_status) )
2625                 return nt_status;
2626                         
2627         /* Get the user's SID */
2628
2629         sid_compose(&sid, get_global_sam_sid(), r_u->user_rid);
2630         
2631         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping,
2632                             &sid, SAMR_USR_RIGHTS_WRITE_PW);
2633         se_map_generic(&des_access, &usr_generic_mapping);
2634         
2635         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2636                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
2637                 &acc_granted, "_samr_create_user");
2638                 
2639         if ( !NT_STATUS_IS_OK(nt_status) ) {
2640                 return nt_status;
2641         }
2642
2643         /* associate the user's SID with the new handle. */
2644         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2645                 return NT_STATUS_NO_MEMORY;
2646         }
2647
2648         ZERO_STRUCTP(info);
2649         info->sid = sid;
2650         info->acc_granted = acc_granted;
2651
2652         /* get a (unique) handle.  open a policy on it. */
2653         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2654                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2655         }
2656
2657         /* After a "set" ensure we have no cached display info. */
2658         force_flush_samr_cache(info->disp_info);
2659
2660         r_u->access_granted = acc_granted;
2661
2662         return NT_STATUS_OK;
2663 }
2664
2665 /*******************************************************************
2666  samr_reply_connect_anon
2667  ********************************************************************/
2668
2669 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2670 {
2671         struct samr_info *info = NULL;
2672         uint32    des_access = q_u->access_mask;
2673
2674         /* Access check */
2675
2676         if (!pipe_access_check(p)) {
2677                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2678                 r_u->status = NT_STATUS_ACCESS_DENIED;
2679                 return r_u->status;
2680         }
2681
2682         /* set up the SAMR connect_anon response */
2683
2684         r_u->status = NT_STATUS_OK;
2685
2686         /* associate the user's SID with the new handle. */
2687         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2688                 return NT_STATUS_NO_MEMORY;
2689
2690         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
2691            was observed from a win98 client trying to enumerate users (when configured  
2692            user level access control on shares)   --jerry */
2693            
2694         if (des_access == MAXIMUM_ALLOWED_ACCESS) {
2695                 /* Map to max possible knowing we're filtered below. */
2696                 des_access = GENERIC_ALL_ACCESS;
2697         }
2698
2699         se_map_generic( &des_access, &sam_generic_mapping );
2700         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2701         
2702         info->status = q_u->unknown_0;
2703
2704         /* get a (unique) handle.  open a policy on it. */
2705         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2706                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2707
2708         return r_u->status;
2709 }
2710
2711 /*******************************************************************
2712  samr_reply_connect
2713  ********************************************************************/
2714
2715 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2716 {
2717         struct samr_info *info = NULL;
2718         SEC_DESC *psd = NULL;
2719         uint32    acc_granted;
2720         uint32    des_access = q_u->access_mask;
2721         NTSTATUS  nt_status;
2722         size_t    sd_size;
2723
2724
2725         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2726
2727         /* Access check */
2728
2729         if (!pipe_access_check(p)) {
2730                 DEBUG(3, ("access denied to samr_connect\n"));
2731                 r_u->status = NT_STATUS_ACCESS_DENIED;
2732                 return r_u->status;
2733         }
2734
2735         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2736         se_map_generic(&des_access, &sam_generic_mapping);
2737         
2738         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2739                 NULL, 0, des_access, &acc_granted, "_samr_connect");
2740         
2741         if ( !NT_STATUS_IS_OK(nt_status) ) 
2742                 return nt_status;
2743
2744         r_u->status = NT_STATUS_OK;
2745
2746         /* associate the user's SID and access granted with the new handle. */
2747         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2748                 return NT_STATUS_NO_MEMORY;
2749
2750         info->acc_granted = acc_granted;
2751         info->status = q_u->access_mask;
2752
2753         /* get a (unique) handle.  open a policy on it. */
2754         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2755                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2756
2757         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2758
2759         return r_u->status;
2760 }
2761
2762 /*******************************************************************
2763  samr_connect4
2764  ********************************************************************/
2765
2766 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2767 {
2768         struct samr_info *info = NULL;
2769         SEC_DESC *psd = NULL;
2770         uint32    acc_granted;
2771         uint32    des_access = q_u->access_mask;
2772         NTSTATUS  nt_status;
2773         size_t    sd_size;
2774
2775
2776         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2777
2778         /* Access check */
2779
2780         if (!pipe_access_check(p)) {
2781                 DEBUG(3, ("access denied to samr_connect4\n"));
2782                 r_u->status = NT_STATUS_ACCESS_DENIED;
2783                 return r_u->status;
2784         }
2785
2786         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2787         se_map_generic(&des_access, &sam_generic_mapping);
2788         
2789         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2790                 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2791         
2792         if ( !NT_STATUS_IS_OK(nt_status) ) 
2793                 return nt_status;
2794
2795         r_u->status = NT_STATUS_OK;
2796
2797         /* associate the user's SID and access granted with the new handle. */
2798         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2799                 return NT_STATUS_NO_MEMORY;
2800
2801         info->acc_granted = acc_granted;
2802         info->status = q_u->access_mask;
2803
2804         /* get a (unique) handle.  open a policy on it. */
2805         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2806                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2807
2808         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2809
2810         return r_u->status;
2811 }
2812
2813 /*******************************************************************
2814  samr_connect5
2815  ********************************************************************/
2816
2817 NTSTATUS _samr_connect5(pipes_struct *p, SAMR_Q_CONNECT5 *q_u, SAMR_R_CONNECT5 *r_u)
2818 {
2819         struct samr_info *info = NULL;
2820         SEC_DESC *psd = NULL;
2821         uint32    acc_granted;
2822         uint32    des_access = q_u->access_mask;
2823         NTSTATUS  nt_status;
2824         POLICY_HND pol;
2825         size_t    sd_size;
2826
2827
2828         DEBUG(5,("_samr_connect5: %d\n", __LINE__));
2829
2830         ZERO_STRUCTP(r_u);
2831
2832         /* Access check */
2833
2834         if (!pipe_access_check(p)) {
2835                 DEBUG(3, ("access denied to samr_connect5\n"));
2836                 r_u->status = NT_STATUS_ACCESS_DENIED;
2837                 return r_u->status;
2838         }
2839
2840         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2841         se_map_generic(&des_access, &sam_generic_mapping);
2842         
2843         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2844                 NULL, 0, des_access, &acc_granted, "_samr_connect5");
2845         
2846         if ( !NT_STATUS_IS_OK(nt_status) ) 
2847                 return nt_status;
2848
2849         /* associate the user's SID and access granted with the new handle. */
2850         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2851                 return NT_STATUS_NO_MEMORY;
2852
2853         info->acc_granted = acc_granted;
2854         info->status = q_u->access_mask;
2855
2856         /* get a (unique) handle.  open a policy on it. */
2857         if (!create_policy_hnd(p, &pol, free_samr_info, (void *)info))
2858                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2859
2860         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2861
2862         init_samr_r_connect5(r_u, &pol, NT_STATUS_OK);
2863
2864         return r_u->status;
2865 }
2866
2867 /**********************************************************************
2868  api_samr_lookup_domain
2869  **********************************************************************/
2870
2871 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2872 {
2873         struct samr_info *info;
2874         fstring domain_name;
2875         DOM_SID sid;
2876
2877         r_u->status = NT_STATUS_OK;
2878
2879         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)(void *)&info))
2880                 return NT_STATUS_INVALID_HANDLE;
2881
2882         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.  
2883            Reverted that change so we will work with RAS servers again */
2884
2885         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
2886                 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) 
2887         {
2888                 return r_u->status;
2889         }
2890
2891         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2892
2893         ZERO_STRUCT(sid);
2894
2895         if (strequal(domain_name, builtin_domain_name())) {
2896                 sid_copy(&sid, &global_sid_Builtin);
2897         } else {
2898                 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2899                         r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2900                 }
2901         }
2902
2903         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2904
2905         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2906
2907         return r_u->status;
2908 }
2909
2910 /******************************************************************
2911 makes a SAMR_R_ENUM_DOMAINS structure.
2912 ********************************************************************/
2913
2914 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2915                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2916 {
2917         uint32 i;
2918         SAM_ENTRY *sam;
2919         UNISTR2 *uni_name;
2920
2921         DEBUG(5, ("make_enum_domains\n"));
2922
2923         *pp_sam = NULL;
2924         *pp_uni_name = NULL;
2925
2926         if (num_sam_entries == 0)
2927                 return True;
2928
2929         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2930         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2931
2932         if (sam == NULL || uni_name == NULL)
2933                 return False;
2934
2935         for (i = 0; i < num_sam_entries; i++) {
2936                 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2937                 init_sam_entry(&sam[i], &uni_name[i], 0);
2938         }
2939
2940         *pp_sam = sam;
2941         *pp_uni_name = uni_name;
2942
2943         return True;
2944 }
2945
2946 /**********************************************************************
2947  api_samr_enum_domains
2948  **********************************************************************/
2949
2950 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2951 {
2952         struct samr_info *info;
2953         uint32 num_entries = 2;
2954         fstring dom[2];
2955         const char *name;
2956
2957         r_u->status = NT_STATUS_OK;
2958         
2959         if (!find_policy_by_hnd(p, &q_u->pol, (void**)(void *)&info))
2960                 return NT_STATUS_INVALID_HANDLE;
2961         
2962         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2963                 return r_u->status;
2964         }
2965
2966         name = get_global_sam_name();
2967
2968         fstrcpy(dom[0],name);
2969         strupper_m(dom[0]);
2970         fstrcpy(dom[1],"Builtin");
2971
2972         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2973                 return NT_STATUS_NO_MEMORY;
2974
2975         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2976
2977         return r_u->status;
2978 }
2979
2980 /*******************************************************************
2981  api_samr_open_alias
2982  ********************************************************************/
2983
2984 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2985 {
2986         DOM_SID sid;
2987         POLICY_HND domain_pol = q_u->dom_pol;
2988         uint32 alias_rid = q_u->rid_alias;
2989         POLICY_HND *alias_pol = &r_u->pol;
2990         struct    samr_info *info = NULL;
2991         SEC_DESC *psd = NULL;
2992         uint32    acc_granted;
2993         uint32    des_access = q_u->access_mask;
2994         size_t    sd_size;
2995         NTSTATUS  status;
2996         SE_PRIV se_rights;
2997
2998         r_u->status = NT_STATUS_OK;
2999
3000         /* find the domain policy and get the SID / access bits stored in the domain policy */
3001         
3002         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted, NULL) )
3003                 return NT_STATUS_INVALID_HANDLE;
3004         
3005         status = access_check_samr_function(acc_granted, 
3006                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
3007                 
3008         if ( !NT_STATUS_IS_OK(status) ) 
3009                 return status;
3010
3011         /* append the alias' RID to it */
3012         
3013         if (!sid_append_rid(&sid, alias_rid))
3014                 return NT_STATUS_NO_SUCH_ALIAS;
3015                 
3016         /*check if access can be granted as requested by client. */
3017         
3018         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
3019         se_map_generic(&des_access,&ali_generic_mapping);
3020         
3021         se_priv_copy( &se_rights, &se_add_users );
3022         
3023         
3024         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
3025                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access, 
3026                 &acc_granted, "_samr_open_alias");
3027                 
3028         if ( !NT_STATUS_IS_OK(status) )
3029                 return status;
3030
3031         {
3032                 /* Check we actually have the requested alias */
3033                 enum lsa_SidType type;
3034                 BOOL result;
3035                 gid_t gid;
3036
3037                 become_root();
3038                 result = lookup_sid(NULL, &sid, NULL, NULL, &type);
3039                 unbecome_root();
3040
3041                 if (!result || (type != SID_NAME_ALIAS)) {
3042                         return NT_STATUS_NO_SUCH_ALIAS;
3043                 }
3044
3045                 /* make sure there is a mapping */
3046                 
3047                 if ( !sid_to_gid( &sid, &gid ) ) {
3048                         return NT_STATUS_NO_SUCH_ALIAS;
3049                 }
3050
3051         }
3052
3053         /* associate the alias SID with the new handle. */
3054         if ((info = get_samr_info_by_sid(&sid)) == NULL)
3055                 return NT_STATUS_NO_MEMORY;
3056                 
3057         info->acc_granted = acc_granted;
3058
3059         /* get a (unique) handle.  open a policy on it. */
3060         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
3061                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3062
3063         return r_u->status;
3064 }
3065
3066 /*******************************************************************
3067  set_user_info_7
3068  ********************************************************************/
3069 static NTSTATUS set_user_info_7(TALLOC_CTX *mem_ctx,
3070                                 const SAM_USER_INFO_7 *id7, struct samu *pwd)
3071 {
3072         fstring new_name;
3073         NTSTATUS rc;
3074
3075         if (id7 == NULL) {
3076                 DEBUG(5, ("set_user_info_7: NULL id7\n"));
3077                 TALLOC_FREE(pwd);
3078                 return NT_STATUS_ACCESS_DENIED;
3079         }
3080
3081         if(!rpcstr_pull(new_name, id7->uni_name.buffer, sizeof(new_name), id7->uni_name.uni_str_len*2, 0)) {
3082                 DEBUG(5, ("set_user_info_7: failed to get new username\n"));
3083                 TALLOC_FREE(pwd);
3084                 return NT_STATUS_ACCESS_DENIED;
3085         }
3086
3087         /* check to see if the new username already exists.  Note: we can't
3088            reliably lock all backends, so there is potentially the 
3089            possibility that a user can be created in between this check and
3090            the rename.  The rename should fail, but may not get the
3091            exact same failure status code.  I think this is small enough
3092            of a window for this type of operation and the results are
3093            simply that the rename fails with a slightly different status
3094            code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3095
3096         rc = can_create(mem_ctx, new_name);
3097         if (!NT_STATUS_IS_OK(rc)) {
3098                 return rc;
3099         }
3100
3101         rc = pdb_rename_sam_account(pwd, new_name);
3102
3103         TALLOC_FREE(pwd);
3104         return rc;
3105 }
3106
3107 /*******************************************************************
3108  set_user_info_16
3109  ********************************************************************/
3110
3111 static BOOL set_user_info_16(const SAM_USER_INFO_16 *id16, struct samu *pwd)
3112 {
3113         if (id16 == NULL) {
3114                 DEBUG(5, ("set_user_info_16: NULL id16\n"));
3115                 TALLOC_FREE(pwd);
3116                 return False;
3117         }
3118         
3119         /* FIX ME: check if the value is really changed --metze */
3120         if (!pdb_set_acct_ctrl(pwd, id16->acb_info, PDB_CHANGED)) {
3121                 TALLOC_FREE(pwd);
3122                 return False;
3123         }
3124
3125         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3126                 TALLOC_FREE(pwd);
3127                 return False;
3128         }
3129
3130         TALLOC_FREE(pwd);
3131
3132         return True;
3133 }
3134
3135 /*******************************************************************
3136  set_user_info_18
3137  ********************************************************************/
3138
3139 static BOOL set_user_info_18(SAM_USER_INFO_18 *id18, struct samu *pwd)
3140 {
3141
3142         if (id18 == NULL) {
3143                 DEBUG(2, ("set_user_info_18: id18 is NULL\n"));
3144                 TALLOC_FREE(pwd);
3145                 return False;
3146         }
3147  
3148         if (!pdb_set_lanman_passwd (pwd, id18->lm_pwd, PDB_CHANGED)) {
3149                 TALLOC_FREE(pwd);
3150                 return False;
3151         }
3152         if (!pdb_set_nt_passwd     (pwd, id18->nt_pwd, PDB_CHANGED)) {
3153                 TALLOC_FREE(pwd);
3154                 return False;
3155         }
3156         if (!pdb_set_pass_last_set_time (pwd, time(NULL), PDB_CHANGED)) {
3157                 TALLOC_FREE(pwd);
3158                 return False; 
3159         }
3160  
3161         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3162                 TALLOC_FREE(pwd);
3163                 return False;
3164         }
3165
3166         TALLOC_FREE(pwd);
3167         return True;
3168 }
3169
3170 /*******************************************************************
3171  set_user_info_20
3172  ********************************************************************/
3173
3174 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, struct samu *pwd)
3175 {
3176         if (id20 == NULL) {
3177                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
3178                 return False;
3179         }
3180  
3181         copy_id20_to_sam_passwd(pwd, id20);
3182
3183         /* write the change out */
3184         if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) {
3185                 TALLOC_FREE(pwd);
3186                 return False;
3187         }
3188
3189         TALLOC_FREE(pwd);
3190
3191         return True;
3192 }
3193 /*******************************************************************
3194  set_user_info_21
3195  ********************************************************************/
3196
3197 static NTSTATUS set_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
3198                                  struct samu *pwd)
3199 {
3200         fstring new_name;
3201         NTSTATUS status;
3202         
3203         if (id21 == NULL) {
3204                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
3205                 return NT_STATUS_INVALID_PARAMETER;
3206         }
3207
3208         /* we need to separately check for an account rename first */
3209         
3210         if (rpcstr_pull(new_name, id21->uni_user_name.buffer, 
3211                 sizeof(new_name), id21->uni_user_name.uni_str_len*2, 0) 
3212                 && (!strequal(new_name, pdb_get_username(pwd)))) 
3213         {
3214
3215                 /* check to see if the new username already exists.  Note: we can't
3216                    reliably lock all backends, so there is potentially the 
3217                    possibility that a user can be created in between this check and
3218                    the rename.  The rename should fail, but may not get the
3219                    exact same failure status code.  I think this is small enough
3220                    of a window for this type of operation and the results are
3221                    simply that the rename fails with a slightly different status
3222                    code (like UNSUCCESSFUL instead of ALREADY_EXISTS). */
3223
3224                 status = can_create(mem_ctx, new_name);
3225                 if (!NT_STATUS_IS_OK(status)) {
3226                         return status;
3227                 }
3228
3229                 status = pdb_rename_sam_account(pwd, new_name);
3230
3231                 if (!NT_STATUS_IS_OK(status)) {
3232                         DEBUG(0,("set_user_info_21: failed to rename account: %s\n", 
3233                                 nt_errstr(status)));
3234                         TALLOC_FREE(pwd);
3235                         return status;
3236                 }
3237
3238                 /* set the new username so that later 
3239                    functions can work on the new account */
3240                 pdb_set_username(pwd, new_name, PDB_SET);
3241         }
3242
3243         copy_id21_to_sam_passwd(pwd, id21);
3244  
3245         /*
3246          * The funny part about the previous two calls is
3247          * that pwd still has the password hashes from the
3248          * passdb entry.  These have not been updated from
3249          * id21.  I don't know if they need to be set.    --jerry
3250          */
3251  
3252         if ( IS_SAM_CHANGED(pwd, PDB_GROUPSID) ) {
3253                 status = pdb_set_unix_primary_group(mem_ctx, pwd);
3254                 if ( !NT_STATUS_IS_OK(status) ) {
3255                         return status;
3256                 }
3257         }