r5203: additional changes for BUG 2291 to restrict who can join a BDC and add domain...
[kai/samba-autobuild/.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-2002,
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  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 /*
29  * This is the implementation of the SAMR code.
30  */
31
32 #include "includes.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 #define SAMR_USR_RIGHTS_WRITE_PW \
38                 ( READ_CONTROL_ACCESS           | \
39                   SA_RIGHT_USER_CHANGE_PASSWORD | \
40                   SA_RIGHT_USER_SET_LOC_COM )
41
42 extern DOM_SID global_sid_Builtin;
43
44 extern rid_name domain_group_rids[];
45 extern rid_name domain_alias_rids[];
46 extern rid_name builtin_alias_rids[];
47
48
49 typedef struct _disp_info {
50         BOOL user_dbloaded;
51         uint32 num_user_account;
52         SAM_ACCOUNT *disp_user_info;
53         BOOL group_dbloaded;
54         uint32 num_group_account;
55         DOMAIN_GRP *disp_group_info;
56 } DISP_INFO;
57
58 struct samr_info {
59         /* for use by the \PIPE\samr policy */
60         DOM_SID sid;
61         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
62         uint32 acc_granted;
63         uint16 acb_mask;
64         BOOL only_machines;
65         DISP_INFO disp_info;
66
67         TALLOC_CTX *mem_ctx;
68 };
69
70 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
71 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
72 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
73 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
74 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
75
76 /*******************************************************************
77 *******************************************************************/
78
79 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
80                                      struct generic_mapping *map,
81                                      DOM_SID *sid, uint32 sid_access )
82 {
83         extern DOM_SID global_sid_World;
84         DOM_SID adm_sid, act_sid, domadmin_sid;
85         SEC_ACE ace[5];         /* at most 5 entries */
86         SEC_ACCESS mask;
87         size_t i = 0;
88
89         SEC_ACL *psa = NULL;
90
91         /* basic access for Everyone */
92         
93         init_sec_access(&mask, map->generic_execute | map->generic_read );
94         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
95         
96         /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
97         
98         sid_copy(&adm_sid, &global_sid_Builtin);
99         sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
100
101         sid_copy(&act_sid, &global_sid_Builtin);
102         sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
103         
104         init_sec_access(&mask, map->generic_all);
105         
106         init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
107         init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
108         
109         /* Add Full Access for Domain Admins if we are a DC */
110         
111         if ( IS_DC ) {
112                 sid_copy( &domadmin_sid, get_global_sam_sid() );
113                 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
114                 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
115         }
116
117         /* if we have a sid, give it some special access */
118         
119         if ( sid ) {
120                 init_sec_access( &mask, sid_access );
121                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
122         }
123         
124         /* create the security descriptor */
125         
126         if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
127                 return NT_STATUS_NO_MEMORY;
128
129         if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
130                 return NT_STATUS_NO_MEMORY;
131
132         return NT_STATUS_OK;
133 }
134
135 /*******************************************************************
136  Checks if access to an object should be granted, and returns that
137  level of access for further checks.
138 ********************************************************************/
139
140 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token, 
141                                           SE_PRIV *rights, uint32 rights_mask,
142                                           uint32 des_access, uint32 *acc_granted, 
143                                           const char *debug )
144 {
145         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
146         uint32 saved_mask = 0;
147
148         /* check privileges; certain SAM access bits should be overridden 
149            by privileges (mostly having to do with creating/modifying/deleting 
150            users and groups) */
151         
152         if ( rights && user_has_any_privilege( token, rights ) ) {
153         
154                 saved_mask = (des_access & rights_mask);
155                 des_access &= ~saved_mask;
156                 
157                 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
158                         rights_mask));
159         }
160                 
161         
162         /* check the security descriptor first */
163         
164         if ( se_access_check(psd, token, des_access, acc_granted, &status) )
165                 goto done;
166         
167         /* give root a free pass */
168         
169         if ( geteuid() == sec_initial_uid() ) {
170         
171                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
172                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
173                 
174                 *acc_granted = des_access;
175                 
176                 status = NT_STATUS_OK;
177                 goto done;
178         }
179         
180         
181 done:
182         /* add in any bits saved during the privilege check (only 
183            matters is status is ok) */
184         
185         *acc_granted |= rights_mask;
186
187         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n", 
188                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED", 
189                 des_access, *acc_granted));
190         
191         return status;
192 }
193
194 /*******************************************************************
195  Checks if access to a function can be granted
196 ********************************************************************/
197
198 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
199 {
200         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",  
201                 debug, acc_granted, acc_required));
202
203         /* check the security descriptor first */
204         
205         if ( (acc_granted&acc_required) == acc_required )
206                 return NT_STATUS_OK;
207                 
208         /* give root a free pass */
209
210         if (geteuid() == sec_initial_uid()) {
211         
212                 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
213                         debug, acc_granted, acc_required));
214                 DEBUGADD(4,("but overwritten by euid == 0\n"));
215                 
216                 return NT_STATUS_OK;
217         }
218         
219         DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n", 
220                 debug, acc_granted, acc_required));
221                 
222         return NT_STATUS_ACCESS_DENIED;
223 }
224
225
226 /*******************************************************************
227  Create a samr_info struct.
228 ********************************************************************/
229
230 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
231 {
232         struct samr_info *info;
233         fstring sid_str;
234         TALLOC_CTX *mem_ctx;
235         
236         if (psid) {
237                 sid_to_string(sid_str, psid);
238         } else {
239                 fstrcpy(sid_str,"(NULL)");
240         }
241
242         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
243
244         if ((info = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
245                 return NULL;
246
247         ZERO_STRUCTP(info);
248         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
249         if (psid) {
250                 sid_copy( &info->sid, psid);
251         } else {
252                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
253         }
254         info->mem_ctx = mem_ctx;
255         return info;
256 }
257
258 /*******************************************************************
259  Function to free the per handle data.
260  ********************************************************************/
261
262 static void free_samr_users(struct samr_info *info) 
263 {
264         int i;
265
266         if (info->disp_info.user_dbloaded){
267                 for (i=0; i<info->disp_info.num_user_account; i++) {
268                         SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
269                         /* Not really a free, actually a 'clear' */
270                         pdb_free_sam(&sam);
271                 }
272         }
273         info->disp_info.user_dbloaded=False;
274         info->disp_info.num_user_account=0;
275 }
276
277 /*******************************************************************
278  Function to free the per handle data.
279  ********************************************************************/
280
281 static void free_samr_db(struct samr_info *info)
282 {
283         /* Groups are talloced */
284
285         free_samr_users(info);
286
287         info->disp_info.group_dbloaded=False;
288         info->disp_info.num_group_account=0;
289 }
290
291 static void free_samr_info(void *ptr)
292 {
293         struct samr_info *info=(struct samr_info *) ptr;
294
295         free_samr_db(info);
296         talloc_destroy(info->mem_ctx);
297 }
298
299 /*******************************************************************
300  Ensure password info is never given out. Paranioa... JRA.
301  ********************************************************************/
302
303 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
304 {
305         
306         if (!sam_pass)
307                 return;
308
309         /* These now zero out the old password */
310
311         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
312         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
313 }
314
315
316 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
317 {
318         SAM_ACCOUNT *pwd = NULL;
319         SAM_ACCOUNT *pwd_array = NULL;
320         NTSTATUS nt_status = NT_STATUS_OK;
321         TALLOC_CTX *mem_ctx = info->mem_ctx;
322         uint16 query_acb_mask = acb_mask;
323
324         DEBUG(10,("load_sampwd_entries\n"));
325
326         /* if the snapshoot is already loaded, return */
327         if ((info->disp_info.user_dbloaded==True) 
328             && (info->acb_mask == acb_mask) 
329             && (info->only_machines == only_machines)) {
330                 DEBUG(10,("load_sampwd_entries: already in memory\n"));
331                 return NT_STATUS_OK;
332         }
333
334         free_samr_users(info);
335         
336         if (only_machines) {
337                 query_acb_mask |= ACB_WSTRUST;
338                 query_acb_mask |= ACB_SVRTRUST;
339         }
340
341         if (!pdb_setsampwent(False, query_acb_mask)) {
342                 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
343                 return NT_STATUS_ACCESS_DENIED;
344         }
345
346         for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
347                      && pdb_getsampwent(pwd) == True; pwd=NULL) {
348         
349                 if (only_machines) {
350                         if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
351                               || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
352                                 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
353                                 pdb_free_sam(&pwd);
354                                 continue;
355                         }
356                 } else {
357                         if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
358                                 pdb_free_sam(&pwd);
359                                 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
360                                 continue;
361                         }
362                 }
363
364                 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
365                 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
366                 
367                         DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
368                         pwd_array=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
369                                           info->disp_info.num_user_account+MAX_SAM_ENTRIES);
370
371                         if (pwd_array==NULL)
372                                 return NT_STATUS_NO_MEMORY;
373
374                         info->disp_info.disp_user_info=pwd_array;
375                 }
376         
377                 /* Copy the SAM_ACCOUNT into the array */
378                 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
379
380                 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
381
382                 info->disp_info.num_user_account++;     
383         }
384
385         pdb_endsampwent();
386
387         /* the snapshoot is in memory, we're ready to enumerate fast */
388
389         info->acb_mask = acb_mask;
390         info->only_machines = only_machines;
391         info->disp_info.user_dbloaded=True;
392
393         DEBUG(10,("load_sampwd_entries: done\n"));
394
395         return nt_status;
396 }
397
398 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
399 {
400         GROUP_MAP *map=NULL;
401         DOMAIN_GRP *grp_array = NULL;
402         uint32 group_entries = 0;
403         uint32 i;
404         TALLOC_CTX *mem_ctx = info->mem_ctx;
405         BOOL ret;
406
407         DEBUG(10,("load_group_domain_entries\n"));
408
409         /* if the snapshoot is already loaded, return */
410         if (info->disp_info.group_dbloaded==True) {
411                 DEBUG(10,("load_group_domain_entries: already in memory\n"));
412                 return NT_STATUS_OK;
413         }
414         
415         if (sid_equal(sid, &global_sid_Builtin)) {
416                 /* No domain groups for now in the BUILTIN domain */
417                 info->disp_info.num_group_account=0;
418                 info->disp_info.disp_group_info=NULL;
419                 info->disp_info.group_dbloaded=True;
420                 return NT_STATUS_OK;
421         }
422
423         become_root();
424         ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED); 
425         unbecome_root();
426         
427         if ( !ret ) {
428                 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
429                 return NT_STATUS_NO_MEMORY;
430         }
431         
432
433         info->disp_info.num_group_account=group_entries;
434
435         grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
436         if (group_entries!=0 && grp_array==NULL) {
437                 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
438                 SAFE_FREE(map);
439                 return NT_STATUS_NO_MEMORY;
440         }
441
442         info->disp_info.disp_group_info=grp_array;
443
444         for (i=0; i<group_entries; i++) {
445                 fstrcpy(grp_array[i].name, map[i].nt_name);
446                 fstrcpy(grp_array[i].comment, map[i].comment);
447                 sid_split_rid(&map[i].sid, &grp_array[i].rid);
448                 grp_array[i].attr=SID_NAME_DOM_GRP;
449         }
450
451         SAFE_FREE(map);
452
453         /* the snapshoot is in memory, we're ready to enumerate fast */
454
455         info->disp_info.group_dbloaded=True;
456
457         DEBUG(10,("load_group_domain_entries: done\n"));
458
459         return NT_STATUS_OK;
460 }
461
462
463 /*******************************************************************
464  _samr_close_hnd
465  ********************************************************************/
466
467 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
468 {
469         r_u->status = NT_STATUS_OK;
470
471         /* close the policy handle */
472         if (!close_policy_hnd(p, &q_u->pol))
473                 return NT_STATUS_OBJECT_NAME_INVALID;
474
475         DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
476
477         return r_u->status;
478 }
479
480 /*******************************************************************
481  samr_reply_open_domain
482  ********************************************************************/
483
484 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
485 {
486         struct    samr_info *info;
487         SEC_DESC *psd = NULL;
488         uint32    acc_granted;
489         uint32    des_access = q_u->flags;
490         NTSTATUS  status;
491         size_t sd_size;
492         SE_PRIV se_rights;
493
494         r_u->status = NT_STATUS_OK;
495
496         /* find the connection policy handle. */
497         
498         if ( !find_policy_by_hnd(p, &q_u->pol, (void**)&info) )
499                 return NT_STATUS_INVALID_HANDLE;
500
501         status = access_check_samr_function( info->acc_granted, 
502                 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" );
503                 
504         if ( !NT_STATUS_IS_OK(status) )
505                 return status;
506
507         /*check if access can be granted as requested by client. */
508         
509         make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
510         se_map_generic( &des_access, &dom_generic_mapping );
511         
512         se_priv_copy( &se_rights, &se_machine_account );
513         se_priv_add( &se_rights, &se_add_users );
514
515         status = access_check_samr_object( psd, p->pipe_user.nt_user_token, 
516                 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access, 
517                 &acc_granted, "_samr_open_domain" );
518                 
519         if ( !NT_STATUS_IS_OK(status) )
520                 return status;
521
522         /* associate the domain SID with the (unique) handle. */
523         if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
524                 return NT_STATUS_NO_MEMORY;
525         info->acc_granted = acc_granted;
526
527         /* get a (unique) handle.  open a policy on it. */
528         if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
529                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
530
531         DEBUG(5,("samr_open_domain: %d\n", __LINE__));
532
533         return r_u->status;
534 }
535
536 /*******************************************************************
537  _samr_get_usrdom_pwinfo
538  ********************************************************************/
539
540 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
541 {
542         struct samr_info *info = NULL;
543
544         r_u->status = NT_STATUS_OK;
545
546         /* find the policy handle.  open a policy on it. */
547         if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
548                 return NT_STATUS_INVALID_HANDLE;
549
550         if (!sid_check_is_in_our_domain(&info->sid))
551                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
552
553         init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
554
555         DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
556
557         /* 
558          * NT sometimes return NT_STATUS_ACCESS_DENIED
559          * I don't know yet why.
560          */
561
562         return r_u->status;
563 }
564
565
566 /*******************************************************************
567  _samr_set_sec_obj
568  ********************************************************************/
569
570 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
571 {
572         DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
573         return NT_STATUS_NOT_IMPLEMENTED;
574 }
575
576
577 /*******************************************************************
578 ********************************************************************/
579
580 static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, 
581                                      DOM_SID *sid, uint32 *acc_granted)
582 {
583         struct samr_info *info = NULL;
584
585         /* find the policy handle.  open a policy on it. */
586         if (!find_policy_by_hnd(p, pol, (void **)&info))
587                 return False;
588
589         if (!info)
590                 return False;
591
592         *sid = info->sid;
593         *acc_granted = info->acc_granted;
594         return True;
595 }
596
597 /*******************************************************************
598  _samr_query_sec_obj
599  ********************************************************************/
600
601 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
602 {
603         DOM_SID pol_sid;
604         fstring str_sid;
605         SEC_DESC * psd = NULL;
606         uint32 acc_granted;
607         size_t sd_size;
608
609         r_u->status = NT_STATUS_OK;
610
611         /* Get the SID. */
612         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
613                 return NT_STATUS_INVALID_HANDLE;
614
615
616
617         DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
618
619         /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
620
621         /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
622         if (pol_sid.sid_rev_num == 0)
623         {
624                 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
625                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
626         }
627         else if (sid_equal(&pol_sid,get_global_sam_sid()))  /* check if it is our domain SID */
628
629         {
630                 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
631                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
632         }
633         else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin  Domain */
634         {
635                 /* TODO: Builtin probably needs a different SD with restricted write access*/
636                 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
637                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
638         }
639         else if (sid_check_is_in_our_domain(&pol_sid) ||
640                  sid_check_is_in_builtin(&pol_sid))
641         {
642                 /* TODO: different SDs have to be generated for aliases groups and users.
643                          Currently all three get a default user SD  */
644                 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
645                 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
646         }
647         else return NT_STATUS_OBJECT_TYPE_MISMATCH;
648
649         if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
650                 return NT_STATUS_NO_MEMORY;
651
652         if (NT_STATUS_IS_OK(r_u->status))
653                 r_u->ptr = 1;
654
655         return r_u->status;
656 }
657
658 /*******************************************************************
659 makes a SAM_ENTRY / UNISTR2* structure from a user list.
660 ********************************************************************/
661
662 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
663                                          uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
664                                          DOM_SID *domain_sid)
665 {
666         uint32 i;
667         SAM_ENTRY *sam;
668         UNISTR2 *uni_name;
669         SAM_ACCOUNT *pwd = NULL;
670         UNISTR2 uni_temp_name;
671         const char *temp_name;
672         const DOM_SID *user_sid;
673         uint32 user_rid;
674         fstring user_sid_string;
675         fstring domain_sid_string;
676         
677         *sam_pp = NULL;
678         *uni_name_pp = NULL;
679
680         if (num_entries == 0)
681                 return NT_STATUS_OK;
682
683         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
684
685         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
686
687         if (sam == NULL || uni_name == NULL) {
688                 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
689                 return NT_STATUS_NO_MEMORY;
690         }
691
692         for (i = 0; i < num_entries; i++) {
693                 pwd = &disp_user_info[i+start_idx];
694                 temp_name = pdb_get_username(pwd);
695
696                 /*
697                  * usrmgr expects a non-NULL terminated string with
698                  * trust relationships
699                  */
700                 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
701                         init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
702                 } else {
703                         init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
704                 }
705
706                 user_sid = pdb_get_user_sid(pwd);
707
708                 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
709                         DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
710                                   "the domain sid %s.  Failing operation.\n", 
711                                   temp_name, 
712                                   sid_to_string(user_sid_string, user_sid),
713                                   sid_to_string(domain_sid_string, domain_sid)));
714                         return NT_STATUS_UNSUCCESSFUL;
715                 }
716
717                 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
718                 copy_unistr2(&uni_name[i], &uni_temp_name);
719         }
720
721         *sam_pp = sam;
722         *uni_name_pp = uni_name;
723         return NT_STATUS_OK;
724 }
725
726 /*******************************************************************
727  samr_reply_enum_dom_users
728  ********************************************************************/
729
730 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, 
731                               SAMR_R_ENUM_DOM_USERS *r_u)
732 {
733         struct samr_info *info = NULL;
734         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
735         int num_account;
736         uint32 enum_context=q_u->start_idx;
737         uint32 max_size=q_u->max_size;
738         uint32 temp_size;
739         enum remote_arch_types ra_type = get_remote_arch();
740         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
741         uint32 max_entries = max_sam_entries;
742         DOM_SID domain_sid;
743         
744         r_u->status = NT_STATUS_OK;
745
746         /* find the policy handle.  open a policy on it. */
747         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
748                 return NT_STATUS_INVALID_HANDLE;
749
750         domain_sid = info->sid;
751
752         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
753                                         SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, 
754                                         "_samr_enum_dom_users"))) {
755                 return r_u->status;
756         }
757         
758         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
759
760         become_root();
761         r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
762         unbecome_root();
763         
764         if (!NT_STATUS_IS_OK(r_u->status))
765                 return r_u->status;
766
767         num_account = info->disp_info.num_user_account;
768
769         if (enum_context > num_account) {
770                 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
771                 return NT_STATUS_OK;
772         }
773
774         /* verify we won't overflow */
775         if (max_entries > num_account-enum_context) {
776                 max_entries = num_account-enum_context;
777                 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
778         }
779
780         /* calculate the size and limit on the number of entries we will return */
781         temp_size=max_entries*struct_size;
782         
783         if (temp_size>max_size) {
784                 max_entries=MIN((max_size/struct_size),max_entries);;
785                 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
786         }
787
788         /* 
789          * Note from JRA. total_entries is not being used here. Currently if there is a
790          * large user base then it looks like NT will enumerate until get_sampwd_entries
791          * returns False due to num_entries being zero. This will cause an access denied
792          * return. I don't think this is right and needs further investigation. Note that
793          * this is also the same in the TNG code (I don't think that has been tested with
794          * a very large user list as MAX_SAM_ENTRIES is set to 600).
795          * 
796          * I also think that one of the 'num_entries' return parameters is probably
797          * the "max entries" parameter - but in the TNG code they're all currently set to the same
798          * value (again I think this is wrong).
799          */
800
801         r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name, 
802                                                max_entries, enum_context, 
803                                                info->disp_info.disp_user_info,
804                                                &domain_sid);
805
806         if (!NT_STATUS_IS_OK(r_u->status))
807                 return r_u->status;
808
809         if (enum_context+max_entries < num_account)
810                 r_u->status = STATUS_MORE_ENTRIES;
811
812         DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
813
814         init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
815
816         DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
817
818         return r_u->status;
819 }
820
821 /*******************************************************************
822 makes a SAM_ENTRY / UNISTR2* structure from a group list.
823 ********************************************************************/
824
825 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
826                 uint32 num_sam_entries, DOMAIN_GRP *grp)
827 {
828         uint32 i;
829         SAM_ENTRY *sam;
830         UNISTR2 *uni_name;
831
832         *sam_pp = NULL;
833         *uni_name_pp = NULL;
834
835         if (num_sam_entries == 0)
836                 return;
837
838         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
839         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
840
841         if (sam == NULL || uni_name == NULL) {
842                 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
843                 return;
844         }
845
846         for (i = 0; i < num_sam_entries; i++) {
847                 /*
848                  * JRA. I think this should include the null. TNG does not.
849                  */
850                 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
851                 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
852         }
853
854         *sam_pp = sam;
855         *uni_name_pp = uni_name;
856 }
857
858 /*******************************************************************
859  Get the group entries - similar to get_sampwd_entries().
860  ******************************************************************/
861
862 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, 
863                                    DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
864                                    uint32 *p_num_entries, uint32 max_entries )
865 {
866         GROUP_MAP *map=NULL;
867         int i;
868         uint32 group_entries = 0;
869         uint32 num_entries = 0;
870
871         *p_num_entries = 0;
872
873         /* access checks for the users were performed higher up.  become/unbecome_root()
874            needed for some passdb backends to enumerate groups */
875            
876         become_root();
877         pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
878                                ENUM_ONLY_MAPPED);
879         unbecome_root();
880         
881         num_entries=group_entries-start_idx;
882
883         /* limit the number of entries */
884         if (num_entries>max_entries) {
885                 DEBUG(5,("Limiting to %d entries\n", max_entries));
886                 num_entries=max_entries;
887         }
888
889         *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
890         if (num_entries!=0 && *d_grp==NULL){
891                 SAFE_FREE(map);
892                 return NT_STATUS_NO_MEMORY;
893         }
894         
895         for (i=0; i<num_entries; i++) {
896                 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
897                 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
898                 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
899                 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
900         }
901
902         SAFE_FREE(map);
903
904         *p_num_entries = num_entries;
905
906         DEBUG(10,("get_group_domain_entries: returning %d entries\n",
907                   *p_num_entries));
908
909         return NT_STATUS_OK;
910 }
911
912 /*******************************************************************
913  Wrapper for enumerating local groups
914  ******************************************************************/
915
916 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
917                                    const DOM_SID *sid, uint32 start_idx,
918                                    uint32 *p_num_entries, uint32 max_entries )
919 {
920         struct acct_info *info;
921         int i;
922         BOOL res;
923
924         become_root();
925         res = pdb_enum_aliases(sid, start_idx, max_entries,
926                                p_num_entries, &info);
927         unbecome_root();
928
929         if (!res)
930                 return NT_STATUS_ACCESS_DENIED;
931
932         if (*p_num_entries == 0)
933                 return NT_STATUS_OK;
934
935         *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
936
937         if (*d_grp == NULL) {
938                 SAFE_FREE(info);
939                 return NT_STATUS_NO_MEMORY;
940         }
941
942         for (i=0; i<*p_num_entries; i++) {
943                 fstrcpy((*d_grp)[i].name, info[i].acct_name);
944                 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
945                 (*d_grp)[i].rid = info[i].rid;
946                 (*d_grp)[i].attr = SID_NAME_ALIAS;
947         }
948
949         SAFE_FREE(info);
950         return NT_STATUS_OK;
951 }
952
953 /*******************************************************************
954  samr_reply_enum_dom_groups
955  ********************************************************************/
956
957 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
958 {
959         DOMAIN_GRP *grp=NULL;
960         uint32 num_entries;
961         DOM_SID sid;
962         uint32 acc_granted;
963
964         r_u->status = NT_STATUS_OK;
965
966         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
967                 return NT_STATUS_INVALID_HANDLE;
968                 
969         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
970                 return r_u->status;
971         }
972
973         DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
974
975         /* the domain group array is being allocated in the function below */
976         if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
977                 return r_u->status;
978         }
979
980         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
981
982         init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
983
984         DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
985
986         return r_u->status;
987 }
988
989
990 /*******************************************************************
991  samr_reply_enum_dom_aliases
992  ********************************************************************/
993
994 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
995 {
996         DOMAIN_GRP *grp=NULL;
997         uint32 num_entries = 0;
998         fstring sid_str;
999         DOM_SID sid;
1000         NTSTATUS status;
1001         uint32  acc_granted;
1002         
1003         r_u->status = NT_STATUS_OK;
1004
1005         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1006                 return NT_STATUS_INVALID_HANDLE;
1007
1008         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1009                 return r_u->status;
1010         }
1011         
1012         sid_to_string(sid_str, &sid);
1013         DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1014
1015         status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, 
1016                                    &num_entries, MAX_SAM_ENTRIES);
1017         if (!NT_STATUS_IS_OK(status)) return status;
1018
1019         make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1020
1021         /*safe_free(grp);*/
1022
1023         init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1024
1025         DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1026
1027         return r_u->status;
1028 }
1029
1030 /*******************************************************************
1031  samr_reply_query_dispinfo
1032  ********************************************************************/
1033
1034 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, 
1035                               SAMR_R_QUERY_DISPINFO *r_u)
1036 {
1037         struct samr_info *info = NULL;
1038         uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1039         
1040         uint32 max_entries=q_u->max_entries;
1041         uint32 enum_context=q_u->start_idx;
1042         uint32 max_size=q_u->max_size;
1043
1044         SAM_DISPINFO_CTR *ctr;
1045         uint32 temp_size=0, total_data_size=0;
1046         NTSTATUS disp_ret;
1047         uint32 num_account = 0;
1048         enum remote_arch_types ra_type = get_remote_arch();
1049         int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1050         DOM_SID domain_sid;
1051
1052         DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1053         r_u->status = NT_STATUS_OK;
1054
1055         /* find the policy handle.  open a policy on it. */
1056         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1057                 return NT_STATUS_INVALID_HANDLE;
1058
1059         domain_sid = info->sid;
1060
1061         /*
1062          * calculate how many entries we will return.
1063          * based on 
1064          * - the number of entries the client asked
1065          * - our limit on that
1066          * - the starting point (enumeration context)
1067          * - the buffer size the client will accept
1068          */
1069
1070         /*
1071          * We are a lot more like W2K. Instead of reading the SAM
1072          * each time to find the records we need to send back,
1073          * we read it once and link that copy to the sam handle.
1074          * For large user list (over the MAX_SAM_ENTRIES)
1075          * it's a definitive win.
1076          * second point to notice: between enumerations
1077          * our sam is now the same as it's a snapshoot.
1078          * third point: got rid of the static SAM_USER_21 struct
1079          * no more intermediate.
1080          * con: it uses much more memory, as a full copy is stored
1081          * in memory.
1082          *
1083          * If you want to change it, think twice and think
1084          * of the second point , that's really important.
1085          *
1086          * JFM, 12/20/2001
1087          */
1088
1089         /* Get what we need from the password database */
1090         switch (q_u->switch_level) {
1091                 case 0x1:
1092                         /* When playing with usrmgr, this is necessary
1093                            if you want immediate refresh after editing
1094                            a user. I would like to do this after the
1095                            setuserinfo2, but we do not have access to
1096                            the domain handle in that call, only to the
1097                            user handle. Where else does this hurt?
1098                            -- Volker
1099                         */
1100 #if 0
1101                         /* We cannot do this here - it kills performace. JRA. */
1102                         free_samr_users(info);
1103 #endif
1104                 case 0x2:
1105                 case 0x4:
1106                         become_root();          
1107                         /* Level 2 is for all machines, otherwise only 'normal' users */
1108                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1109                         unbecome_root();
1110                         if (!NT_STATUS_IS_OK(r_u->status)) {
1111                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1112                                 return r_u->status;
1113                         }
1114                         num_account = info->disp_info.num_user_account;
1115                         break;
1116                 case 0x3:
1117                 case 0x5:
1118                         r_u->status = load_group_domain_entries(info, &info->sid);
1119                         if (!NT_STATUS_IS_OK(r_u->status))
1120                                 return r_u->status;
1121                         num_account = info->disp_info.num_group_account;
1122                         break;
1123                 default:
1124                         DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1125                         return NT_STATUS_INVALID_INFO_CLASS;
1126         }
1127
1128         /* first limit the number of entries we will return */
1129         if(max_entries > max_sam_entries) {
1130                 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1131                 max_entries = max_sam_entries;
1132         }
1133
1134         if (enum_context > num_account) {
1135                 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1136                 return NT_STATUS_NO_MORE_ENTRIES;
1137         }
1138
1139         /* verify we won't overflow */
1140         if (max_entries > num_account-enum_context) {
1141                 max_entries = num_account-enum_context;
1142                 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1143         }
1144
1145         /* calculate the size and limit on the number of entries we will return */
1146         temp_size=max_entries*struct_size;
1147         
1148         if (temp_size>max_size) {
1149                 max_entries=MIN((max_size/struct_size),max_entries);;
1150                 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1151         }
1152
1153         if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1154                 return NT_STATUS_NO_MEMORY;
1155
1156         ZERO_STRUCTP(ctr);
1157
1158         /* Now create reply structure */
1159         switch (q_u->switch_level) {
1160         case 0x1:
1161                 if (max_entries) {
1162                         if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1163                                 return NT_STATUS_NO_MEMORY;
1164                 }
1165                 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context, 
1166                                                info->disp_info.disp_user_info, &domain_sid);
1167                 if (!NT_STATUS_IS_OK(disp_ret))
1168                         return disp_ret;
1169                 break;
1170         case 0x2:
1171                 if (max_entries) {
1172                         if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1173                                 return NT_STATUS_NO_MEMORY;
1174                 }
1175                 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context, 
1176                                                info->disp_info.disp_user_info, &domain_sid);
1177                 if (!NT_STATUS_IS_OK(disp_ret))
1178                         return disp_ret;
1179                 break;
1180         case 0x3:
1181                 if (max_entries) {
1182                         if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1183                                 return NT_STATUS_NO_MEMORY;
1184                 }
1185                 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1186                 if (!NT_STATUS_IS_OK(disp_ret))
1187                         return disp_ret;
1188                 break;
1189         case 0x4:
1190                 if (max_entries) {
1191                         if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1192                                 return NT_STATUS_NO_MEMORY;
1193                 }
1194                 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1195                 if (!NT_STATUS_IS_OK(disp_ret))
1196                         return disp_ret;
1197                 break;
1198         case 0x5:
1199                 if (max_entries) {
1200                         if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1201                                 return NT_STATUS_NO_MEMORY;
1202                 }
1203                 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1204                 if (!NT_STATUS_IS_OK(disp_ret))
1205                         return disp_ret;
1206                 break;
1207
1208         default:
1209                 ctr->sam.info = NULL;
1210                 return NT_STATUS_INVALID_INFO_CLASS;
1211         }
1212
1213         /* calculate the total size */
1214         total_data_size=num_account*struct_size;
1215
1216         if (enum_context+max_entries < num_account)
1217                 r_u->status = STATUS_MORE_ENTRIES;
1218
1219         DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1220
1221         init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1222
1223         return r_u->status;
1224
1225 }
1226
1227 /*******************************************************************
1228  samr_reply_query_aliasinfo
1229  ********************************************************************/
1230
1231 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1232 {
1233         DOM_SID   sid;
1234         struct acct_info info;
1235         uint32    acc_granted;
1236         BOOL ret;
1237
1238         r_u->status = NT_STATUS_OK;
1239
1240         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1241
1242         /* find the policy handle.  open a policy on it. */
1243         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1244                 return NT_STATUS_INVALID_HANDLE;
1245         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1246                 return r_u->status;
1247         }
1248
1249         become_root();
1250         ret = pdb_get_aliasinfo(&sid, &info);
1251         unbecome_root();
1252         
1253         if ( !ret )
1254                 return NT_STATUS_NO_SUCH_ALIAS;
1255
1256         switch (q_u->switch_level) {
1257         case 1:
1258                 r_u->ptr = 1;
1259                 r_u->ctr.switch_value1 = 1;
1260                 init_samr_alias_info1(&r_u->ctr.alias.info1,
1261                                       info.acct_name, 1, info.acct_desc);
1262                 break;
1263         case 3:
1264                 r_u->ptr = 1;
1265                 r_u->ctr.switch_value1 = 3;
1266                 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1267                 break;
1268         default:
1269                 return NT_STATUS_INVALID_INFO_CLASS;
1270         }
1271
1272         DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1273
1274         return r_u->status;
1275 }
1276
1277 #if 0
1278 /*******************************************************************
1279  samr_reply_lookup_ids
1280  ********************************************************************/
1281
1282  uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1283 {
1284     uint32 rid[MAX_SAM_ENTRIES];
1285     int num_rids = q_u->num_sids1;
1286
1287     r_u->status = NT_STATUS_OK;
1288
1289     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1290
1291     if (num_rids > MAX_SAM_ENTRIES) {
1292         num_rids = MAX_SAM_ENTRIES;
1293         DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1294     }
1295
1296 #if 0
1297     int i;
1298     SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1299
1300     for (i = 0; i < num_rids && status == 0; i++)
1301     {
1302         struct sam_passwd *sam_pass;
1303         fstring user_name;
1304
1305
1306         fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1307                                     q_u->uni_user_name[i].uni_str_len));
1308
1309         /* find the user account */
1310         become_root();
1311         sam_pass = get_smb21pwd_entry(user_name, 0);
1312         unbecome_root();
1313
1314         if (sam_pass == NULL)
1315         {
1316             status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1317             rid[i] = 0;
1318         }
1319         else
1320         {
1321             rid[i] = sam_pass->user_rid;
1322         }
1323     }
1324 #endif
1325
1326     num_rids = 1;
1327     rid[0] = BUILTIN_ALIAS_RID_USERS;
1328
1329     init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1330
1331     DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1332
1333     return r_u->status;
1334 }
1335 #endif
1336
1337 /*******************************************************************
1338  _samr_lookup_names
1339  ********************************************************************/
1340
1341 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1342 {
1343         uint32 rid[MAX_SAM_ENTRIES];
1344         uint32 local_rid;
1345         enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1346         enum SID_NAME_USE local_type;
1347         int i;
1348         int num_rids = q_u->num_names2;
1349         DOM_SID pol_sid;
1350         fstring sid_str;
1351         uint32  acc_granted;
1352
1353         r_u->status = NT_STATUS_OK;
1354
1355         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1356
1357         ZERO_ARRAY(rid);
1358         ZERO_ARRAY(type);
1359
1360         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1361                 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1362                 return r_u->status;
1363         }
1364         
1365         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 */
1366                 return r_u->status;
1367         }
1368
1369         if (num_rids > MAX_SAM_ENTRIES) {
1370                 num_rids = MAX_SAM_ENTRIES;
1371                 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1372         }
1373
1374         DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1375         
1376         for (i = 0; i < num_rids; i++) {
1377                 fstring name;
1378                 DOM_SID sid;
1379                 int ret;
1380
1381                 r_u->status = NT_STATUS_NONE_MAPPED;
1382
1383                 rid [i] = 0xffffffff;
1384                 type[i] = SID_NAME_UNKNOWN;
1385
1386                 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1387
1388                 /*
1389                  * we are only looking for a name
1390                  * the SID we get back can be outside
1391                  * the scope of the pol_sid
1392                  * 
1393                  * in clear: it prevents to reply to domain\group: yes
1394                  * when only builtin\group exists.
1395                  *
1396                  * a cleaner code is to add the sid of the domain we're looking in
1397                  * to the local_lookup_name function.
1398                  */
1399                  
1400                 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1401                         sid_split_rid(&sid, &local_rid);
1402                                 
1403                         if (sid_equal(&sid, &pol_sid)) {
1404                                 rid[i]=local_rid;
1405
1406                                 /* Windows does not return WKN_GRP here, even
1407                                  * on lookups in builtin */
1408                                 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1409                                         SID_NAME_ALIAS : local_type;
1410
1411                                 r_u->status = NT_STATUS_OK;
1412                         }
1413                 }
1414         }
1415
1416         init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1417
1418         DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1419
1420         return r_u->status;
1421 }
1422
1423 /*******************************************************************
1424  _samr_chgpasswd_user
1425  ********************************************************************/
1426
1427 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1428 {
1429         fstring user_name;
1430         fstring wks;
1431
1432         DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1433
1434         r_u->status = NT_STATUS_OK;
1435
1436         rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1437         rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1438
1439         DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1440
1441         /*
1442          * Pass the user through the NT -> unix user mapping
1443          * function.
1444          */
1445  
1446         (void)map_username(user_name);
1447  
1448         /*
1449          * UNIX username case mangling not required, pass_oem_change 
1450          * is case insensitive.
1451          */
1452
1453         r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1454                                 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1455
1456         init_samr_r_chgpasswd_user(r_u, r_u->status);
1457
1458         DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1459
1460         return r_u->status;
1461 }
1462
1463 /*******************************************************************
1464 makes a SAMR_R_LOOKUP_RIDS structure.
1465 ********************************************************************/
1466
1467 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1468             UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1469 {
1470         uint32 i;
1471         UNIHDR *hdr_name=NULL;
1472         UNISTR2 *uni_name=NULL;
1473
1474         *pp_uni_name = NULL;
1475         *pp_hdr_name = NULL;
1476
1477         if (num_names != 0) {
1478                 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1479                 if (hdr_name == NULL)
1480                         return False;
1481
1482                 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1483                 if (uni_name == NULL)
1484                         return False;
1485         }
1486
1487         for (i = 0; i < num_names; i++) {
1488                 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1489                 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1490                 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1491         }
1492
1493         *pp_uni_name = uni_name;
1494         *pp_hdr_name = hdr_name;
1495
1496         return True;
1497 }
1498
1499 /*******************************************************************
1500  _samr_lookup_rids
1501  ********************************************************************/
1502
1503 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1504 {
1505         fstring group_names[MAX_SAM_ENTRIES];
1506         uint32 *group_attrs = NULL;
1507         UNIHDR *hdr_name = NULL;
1508         UNISTR2 *uni_name = NULL;
1509         DOM_SID pol_sid;
1510         int num_rids = q_u->num_rids1;
1511         int i;
1512         uint32 acc_granted;
1513
1514         r_u->status = NT_STATUS_OK;
1515
1516         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1517
1518         /* find the policy handle.  open a policy on it. */
1519         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1520                 return NT_STATUS_INVALID_HANDLE;
1521
1522         if (num_rids > MAX_SAM_ENTRIES) {
1523                 num_rids = MAX_SAM_ENTRIES;
1524                 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1525         }
1526
1527         if (num_rids) {
1528                 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1529                         return NT_STATUS_NO_MEMORY;
1530         }
1531  
1532         r_u->status = NT_STATUS_NONE_MAPPED;
1533
1534         become_root();  /* lookup_sid can require root privs */
1535
1536         for (i = 0; i < num_rids; i++) {
1537                 fstring tmpname;
1538                 fstring domname;
1539                 DOM_SID sid;
1540                 enum SID_NAME_USE type;
1541
1542                 group_attrs[i] = SID_NAME_UNKNOWN;
1543                 *group_names[i] = '\0';
1544
1545                 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1546                         sid_copy(&sid, &pol_sid);
1547                         sid_append_rid(&sid, q_u->rid[i]);
1548
1549                         if (lookup_sid(&sid, domname, tmpname, &type)) {
1550                                 r_u->status = NT_STATUS_OK;
1551                                 group_attrs[i] = (uint32)type;
1552                                 fstrcpy(group_names[i],tmpname);
1553                                 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1554                         }
1555                 }
1556         }
1557
1558         unbecome_root();
1559
1560         if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1561                 return NT_STATUS_NO_MEMORY;
1562
1563         init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1564
1565         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1566
1567         return r_u->status;
1568 }
1569
1570 /*******************************************************************
1571  _samr_open_user. Safe - gives out no passwd info.
1572  ********************************************************************/
1573
1574 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1575 {
1576         SAM_ACCOUNT *sampass=NULL;
1577         DOM_SID sid;
1578         POLICY_HND domain_pol = q_u->domain_pol;
1579         POLICY_HND *user_pol = &r_u->user_pol;
1580         struct samr_info *info = NULL;
1581         SEC_DESC *psd = NULL;
1582         uint32    acc_granted;
1583         uint32    des_access = q_u->access_mask;
1584         size_t    sd_size;
1585         BOOL ret;
1586         NTSTATUS nt_status;
1587         SE_PRIV se_rights;
1588
1589         r_u->status = NT_STATUS_OK;
1590
1591         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1592         
1593         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
1594                 return NT_STATUS_INVALID_HANDLE;
1595         
1596         nt_status = access_check_samr_function( acc_granted, 
1597                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1598                 
1599         if ( !NT_STATUS_IS_OK(nt_status) )
1600                 return nt_status;
1601
1602         nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1603         
1604         if (!NT_STATUS_IS_OK(nt_status))
1605                 return nt_status;
1606
1607         /* append the user's RID to it */
1608         
1609         if (!sid_append_rid(&sid, q_u->user_rid))
1610                 return NT_STATUS_NO_SUCH_USER;
1611         
1612         /* check if access can be granted as requested by client. */
1613         
1614         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1615         se_map_generic(&des_access, &usr_generic_mapping);
1616         
1617         se_priv_copy( &se_rights, &se_machine_account );
1618         se_priv_add( &se_rights, &se_add_users );
1619         
1620         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
1621                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
1622                 &acc_granted, "_samr_open_user");
1623                 
1624         if ( !NT_STATUS_IS_OK(nt_status) )
1625                 return nt_status;
1626
1627         become_root();
1628         ret=pdb_getsampwsid(sampass, &sid);
1629         unbecome_root();
1630
1631         /* check that the SID exists in our domain. */
1632         if (ret == False) {
1633                 return NT_STATUS_NO_SUCH_USER;
1634         }
1635
1636         pdb_free_sam(&sampass);
1637
1638         /* associate the user's SID and access bits with the new handle. */
1639         if ((info = get_samr_info_by_sid(&sid)) == NULL)
1640                 return NT_STATUS_NO_MEMORY;
1641         info->acc_granted = acc_granted;
1642
1643         /* get a (unique) handle.  open a policy on it. */
1644         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1645                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1646
1647         return r_u->status;
1648 }
1649
1650 /*************************************************************************
1651  get_user_info_7. Safe. Only gives out account_name.
1652  *************************************************************************/
1653
1654 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1655 {
1656         SAM_ACCOUNT *smbpass=NULL;
1657         BOOL ret;
1658         NTSTATUS nt_status;
1659
1660         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1661         
1662         if (!NT_STATUS_IS_OK(nt_status)) {
1663                 return nt_status;
1664         }
1665
1666         become_root();
1667         ret = pdb_getsampwsid(smbpass, user_sid);
1668         unbecome_root();
1669
1670         if (ret==False) {
1671                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1672                 return NT_STATUS_NO_SUCH_USER;
1673         }
1674
1675         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1676
1677         ZERO_STRUCTP(id7);
1678         init_sam_user_info7(id7, pdb_get_username(smbpass) );
1679
1680         pdb_free_sam(&smbpass);
1681
1682         return NT_STATUS_OK;
1683 }
1684 /*************************************************************************
1685  get_user_info_10. Safe. Only gives out acb bits.
1686  *************************************************************************/
1687
1688 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1689 {
1690         SAM_ACCOUNT *smbpass=NULL;
1691         BOOL ret;
1692         NTSTATUS nt_status;
1693
1694         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1695         
1696         if (!NT_STATUS_IS_OK(nt_status)) {
1697                 return nt_status;
1698         }
1699
1700         become_root();
1701         ret = pdb_getsampwsid(smbpass, user_sid);
1702         unbecome_root();
1703
1704         if (ret==False) {
1705                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1706                 return NT_STATUS_NO_SUCH_USER;
1707         }
1708
1709         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1710
1711         ZERO_STRUCTP(id10);
1712         init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1713
1714         pdb_free_sam(&smbpass);
1715
1716         return NT_STATUS_OK;
1717 }
1718
1719 /*************************************************************************
1720  get_user_info_12. OK - this is the killer as it gives out password info.
1721  Ensure that this is only allowed on an encrypted connection with a root
1722  user. JRA. 
1723  *************************************************************************/
1724
1725 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1726 {
1727         SAM_ACCOUNT *smbpass=NULL;
1728         BOOL ret;
1729         NTSTATUS nt_status;
1730
1731         if (!p->ntlmssp_auth_validated)
1732                 return NT_STATUS_ACCESS_DENIED;
1733
1734         if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1735                 return NT_STATUS_ACCESS_DENIED;
1736
1737         /*
1738          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1739          */
1740
1741         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1742         
1743         if (!NT_STATUS_IS_OK(nt_status)) {
1744                 return nt_status;
1745         }
1746
1747         ret = pdb_getsampwsid(smbpass, user_sid);
1748
1749         if (ret == False) {
1750                 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1751                 pdb_free_sam(&smbpass);
1752                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1753         }
1754
1755         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1756
1757         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1758                 pdb_free_sam(&smbpass);
1759                 return NT_STATUS_ACCOUNT_DISABLED;
1760         }
1761
1762         ZERO_STRUCTP(id12);
1763         init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1764         
1765         pdb_free_sam(&smbpass);
1766
1767         return NT_STATUS_OK;
1768 }
1769
1770 /*************************************************************************
1771  get_user_info_20
1772  *************************************************************************/
1773
1774 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1775 {
1776         SAM_ACCOUNT *sampass=NULL;
1777         BOOL ret;
1778
1779         pdb_init_sam_talloc(mem_ctx, &sampass);
1780
1781         become_root();
1782         ret = pdb_getsampwsid(sampass, user_sid);
1783         unbecome_root();
1784
1785         if (ret == False) {
1786                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1787                 return NT_STATUS_NO_SUCH_USER;
1788         }
1789
1790         samr_clear_sam_passwd(sampass);
1791
1792         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1793
1794         ZERO_STRUCTP(id20);
1795         init_sam_user_info20A(id20, sampass);
1796         
1797         pdb_free_sam(&sampass);
1798
1799         return NT_STATUS_OK;
1800 }
1801
1802 /*************************************************************************
1803  get_user_info_21
1804  *************************************************************************/
1805
1806 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, 
1807                                  DOM_SID *user_sid, DOM_SID *domain_sid)
1808 {
1809         SAM_ACCOUNT *sampass=NULL;
1810         BOOL ret;
1811         NTSTATUS nt_status;
1812
1813         nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1814         if (!NT_STATUS_IS_OK(nt_status)) {
1815                 return nt_status;
1816         }
1817
1818         become_root();
1819         ret = pdb_getsampwsid(sampass, user_sid);
1820         unbecome_root();
1821
1822         if (ret == False) {
1823                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1824                 return NT_STATUS_NO_SUCH_USER;
1825         }
1826
1827         samr_clear_sam_passwd(sampass);
1828
1829         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1830
1831         ZERO_STRUCTP(id21);
1832         nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1833         
1834         pdb_free_sam(&sampass);
1835
1836         return NT_STATUS_OK;
1837 }
1838
1839 /*******************************************************************
1840  _samr_query_userinfo
1841  ********************************************************************/
1842
1843 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1844 {
1845         SAM_USERINFO_CTR *ctr;
1846         struct samr_info *info = NULL;
1847         DOM_SID domain_sid;
1848         uint32 rid;
1849         
1850         r_u->status=NT_STATUS_OK;
1851
1852         /* search for the handle */
1853         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1854                 return NT_STATUS_INVALID_HANDLE;
1855
1856         domain_sid = info->sid;
1857
1858         sid_split_rid(&domain_sid, &rid);
1859
1860         if (!sid_check_is_in_our_domain(&info->sid))
1861                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1862
1863         DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1864
1865         ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1866         if (!ctr)
1867                 return NT_STATUS_NO_MEMORY;
1868
1869         ZERO_STRUCTP(ctr);
1870
1871         /* ok!  user info levels (lots: see MSDEV help), off we go... */
1872         ctr->switch_value = q_u->switch_value;
1873
1874         switch (q_u->switch_value) {
1875         case 0x07:
1876                 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
1877                 if (ctr->info.id7 == NULL)
1878                         return NT_STATUS_NO_MEMORY;
1879
1880                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
1881                         return r_u->status;
1882                 break;
1883         case 0x10:
1884                 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1885                 if (ctr->info.id10 == NULL)
1886                         return NT_STATUS_NO_MEMORY;
1887
1888                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1889                         return r_u->status;
1890                 break;
1891
1892 #if 0
1893 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1894         case 0x11:
1895         {
1896             NTTIME expire;
1897             info = (void *)&id11;
1898
1899             expire.low = 0xffffffff;
1900             expire.high = 0x7fffffff;
1901
1902             ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1903             ZERO_STRUCTP(ctr->info.id11);
1904             init_sam_user_info11(ctr->info.id11, &expire,
1905                          "BROOKFIELDS$",    /* name */
1906                          0x03ef,    /* user rid */
1907                          0x201, /* group rid */
1908                          0x0080);   /* acb info */
1909
1910             break;
1911         }
1912 #endif
1913
1914         case 0x12:
1915                 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1916                 if (ctr->info.id12 == NULL)
1917                         return NT_STATUS_NO_MEMORY;
1918
1919                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1920                         return r_u->status;
1921                 break;
1922                 
1923         case 20:
1924                 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1925                 if (ctr->info.id20 == NULL)
1926                         return NT_STATUS_NO_MEMORY;
1927                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1928                         return r_u->status;
1929                 break;
1930
1931         case 21:
1932                 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1933                 if (ctr->info.id21 == NULL)
1934                         return NT_STATUS_NO_MEMORY;
1935                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, 
1936                                                                     &info->sid, &domain_sid)))
1937                         return r_u->status;
1938                 break;
1939
1940         default:
1941                 return NT_STATUS_INVALID_INFO_CLASS;
1942         }
1943
1944         init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1945
1946         DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1947         
1948         return r_u->status;
1949 }
1950
1951 /*******************************************************************
1952  samr_reply_query_usergroups
1953  ********************************************************************/
1954
1955 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1956 {
1957         SAM_ACCOUNT *sam_pass=NULL;
1958         struct passwd *passwd;
1959         DOM_SID  sid;
1960         DOM_SID *sids;
1961         DOM_GID *gids = NULL;
1962         int num_groups = 0;
1963         gid_t *unix_gids;
1964         int i, num_gids, num_sids;
1965         uint32 acc_granted;
1966         BOOL ret;
1967         NTSTATUS result;
1968
1969         /*
1970          * from the SID in the request:
1971          * we should send back the list of DOMAIN GROUPS
1972          * the user is a member of
1973          *
1974          * and only the DOMAIN GROUPS
1975          * no ALIASES !!! neither aliases of the domain
1976          * nor aliases of the builtin SID
1977          *
1978          * JFM, 12/2/2001
1979          */
1980
1981         r_u->status = NT_STATUS_OK;
1982
1983         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1984
1985         /* find the policy handle.  open a policy on it. */
1986         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1987                 return NT_STATUS_INVALID_HANDLE;
1988         
1989         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1990                 return r_u->status;
1991         }
1992
1993         if (!sid_check_is_in_our_domain(&sid))
1994                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1995
1996         pdb_init_sam(&sam_pass);
1997         
1998         become_root();
1999         ret = pdb_getsampwsid(sam_pass, &sid);
2000         unbecome_root();
2001
2002         if (ret == False) {
2003                 pdb_free_sam(&sam_pass);
2004                 return NT_STATUS_NO_SUCH_USER;
2005         }
2006
2007         passwd = getpwnam_alloc(pdb_get_username(sam_pass));
2008         if (passwd == NULL) {
2009                 pdb_free_sam(&sam_pass);
2010                 return NT_STATUS_NO_SUCH_USER;
2011         }
2012
2013         sids = NULL;
2014         num_sids = 0;
2015
2016         become_root();
2017         result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2018                                             passwd->pw_gid,
2019                                             &sids, &unix_gids, &num_groups);
2020         unbecome_root();
2021
2022         pdb_free_sam(&sam_pass);
2023         passwd_free(&passwd);
2024
2025         if (!NT_STATUS_IS_OK(result))
2026                 return result;
2027
2028         SAFE_FREE(unix_gids);
2029
2030         gids = NULL;
2031         num_gids = 0;
2032
2033         for (i=0; i<num_groups; i++) {
2034                 uint32 rid;
2035
2036                 if (!sid_peek_check_rid(get_global_sam_sid(),
2037                                         &(sids[i]), &rid))
2038                         continue;
2039
2040                 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2041                 gids[num_gids].attr=7;
2042                 gids[num_gids].g_rid = rid;
2043                 num_gids += 1;
2044         }
2045         SAFE_FREE(sids);
2046         
2047         /* construct the response.  lkclXXXX: gids are not copied! */
2048         init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2049         
2050         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2051         
2052         return r_u->status;
2053 }
2054
2055 /*******************************************************************
2056  _samr_query_dom_info
2057  ********************************************************************/
2058
2059 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2060 {
2061         struct samr_info *info = NULL;
2062         SAM_UNK_CTR *ctr;
2063         uint32 min_pass_len,pass_hist,flag;
2064         time_t u_expire, u_min_age;
2065         NTTIME nt_expire, nt_min_age;
2066
2067         time_t u_lock_duration, u_reset_time;
2068         NTTIME nt_lock_duration, nt_reset_time;
2069         uint32 lockout;
2070         
2071         time_t u_logout;
2072         NTTIME nt_logout;
2073
2074         uint32 account_policy_temp;
2075
2076         uint32 num_users=0, num_groups=0, num_aliases=0;
2077
2078         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2079                 return NT_STATUS_NO_MEMORY;
2080
2081         ZERO_STRUCTP(ctr);
2082
2083         r_u->status = NT_STATUS_OK;
2084         
2085         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2086         
2087         /* find the policy handle.  open a policy on it. */
2088         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2089                 return NT_STATUS_INVALID_HANDLE;
2090         
2091         switch (q_u->switch_value) {
2092                 case 0x01:
2093                         
2094                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2095                         min_pass_len = account_policy_temp;
2096
2097                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2098                         pass_hist = account_policy_temp;
2099
2100                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2101                         flag = account_policy_temp;
2102
2103                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2104                         u_expire = account_policy_temp;
2105
2106                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2107                         u_min_age = account_policy_temp;
2108                         
2109                         unix_to_nt_time_abs(&nt_expire, u_expire);
2110                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2111
2112                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
2113                                        flag, nt_expire, nt_min_age);
2114                         break;
2115                 case 0x02:
2116                         become_root();          
2117                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2118                         unbecome_root();
2119                         if (!NT_STATUS_IS_OK(r_u->status)) {
2120                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2121                                 return r_u->status;
2122                         }
2123                         num_users=info->disp_info.num_user_account;
2124                         free_samr_db(info);
2125                         
2126                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2127                         if (!NT_STATUS_IS_OK(r_u->status)) {
2128                                 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2129                                 return r_u->status;
2130                         }
2131                         num_groups=info->disp_info.num_group_account;
2132                         free_samr_db(info);
2133
2134                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2135                         u_logout = account_policy_temp;
2136
2137                         unix_to_nt_time_abs(&nt_logout, u_logout);
2138
2139                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2140                         init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL), 
2141                                        num_users, num_groups, num_aliases, nt_logout);
2142                         break;
2143                 case 0x03:
2144                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2145                         unix_to_nt_time_abs(&nt_logout, u_logout);
2146                         
2147                         init_unk_info3(&ctr->info.inf3, nt_logout);
2148                         break;
2149                 case 0x05:
2150                         init_unk_info5(&ctr->info.inf5, global_myname());
2151                         break;
2152                 case 0x06:
2153                         init_unk_info6(&ctr->info.inf6);
2154                         break;
2155                 case 0x07:
2156                         init_unk_info7(&ctr->info.inf7);
2157                         break;
2158                 case 0x08:
2159                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2160                         break;
2161                 case 0x0c:
2162                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2163                         u_lock_duration = account_policy_temp;
2164                         if (u_lock_duration != -1)
2165                                 u_lock_duration *= 60;
2166
2167                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2168                         u_reset_time = account_policy_temp * 60;
2169
2170                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2171                         lockout = account_policy_temp;
2172
2173                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2174                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2175         
2176                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2177                         break;
2178                 default:
2179                         return NT_STATUS_INVALID_INFO_CLASS;
2180                 }
2181         
2182         init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2183         
2184         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2185         
2186         return r_u->status;
2187 }
2188
2189 /*******************************************************************
2190  _samr_create_user
2191  Create an account, can be either a normal user or a machine.
2192  This funcion will need to be updated for bdc/domain trusts.
2193  ********************************************************************/
2194
2195 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2196 {
2197         SAM_ACCOUNT *sam_pass=NULL;
2198         fstring account;
2199         DOM_SID sid;
2200         pstring add_script;
2201         POLICY_HND dom_pol = q_u->domain_pol;
2202         UNISTR2 user_account = q_u->uni_name;
2203         uint16 acb_info = q_u->acb_info;
2204         POLICY_HND *user_pol = &r_u->user_pol;
2205         struct samr_info *info = NULL;
2206         BOOL ret;
2207         NTSTATUS nt_status;
2208         struct passwd *pw;
2209         uint32 acc_granted;
2210         SEC_DESC *psd;
2211         size_t    sd_size;
2212         uint32 new_rid = 0;
2213         /* check this, when giving away 'add computer to domain' privs */
2214         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2215         BOOL can_add_account;
2216         SE_PRIV se_rights;
2217
2218         /* Get the domain SID stored in the domain policy */
2219         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2220                 return NT_STATUS_INVALID_HANDLE;
2221
2222         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2223                 return nt_status;
2224         }
2225
2226         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { 
2227                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if 
2228                    this parameter is not an account type */
2229                 return NT_STATUS_INVALID_PARAMETER;
2230         }
2231
2232         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2233         strlower_m(account);
2234                 
2235         pdb_init_sam(&sam_pass);
2236
2237         become_root();
2238         ret = pdb_getsampwnam(sam_pass, account);
2239         unbecome_root();
2240         if (ret == True) {
2241                 /* this account exists: say so */
2242                 pdb_free_sam(&sam_pass);
2243                 return NT_STATUS_USER_EXISTS;
2244         }
2245
2246         pdb_free_sam(&sam_pass);
2247         
2248         /*********************************************************************
2249          * HEADS UP!  If we have to create a new user account, we have to get 
2250          * a new RID from somewhere.  This used to be done by the passdb 
2251          * backend. It has been moved into idmap now.  Since idmap is now 
2252          * wrapped up behind winbind, this means you have to run winbindd if you
2253          * want new accounts to get a new RID when "enable rid algorithm = no".
2254          * Tough.  We now have a uniform way of allocating RIDs regardless
2255          * of what ever passdb backend people may use.
2256          *                                             --jerry (2003-07-10)
2257          *********************************************************************/
2258         
2259         pw = Get_Pwnam(account);
2260
2261         /* determine which user right we need to check based on the acb_info */
2262         
2263         if ( (acb_info & ACB_WSTRUST) == ACB_WSTRUST ) 
2264         {
2265                 pstrcpy(add_script, lp_addmachine_script());
2266                 se_priv_copy( &se_rights, &se_machine_account );
2267                 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2268         } 
2269         else if ( (acb_info & ACB_WSTRUST) == ACB_NORMAL ) 
2270         {
2271                 pstrcpy(add_script, lp_adduser_script());
2272                 se_priv_copy( &se_rights, &se_add_users );
2273                 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2274         } 
2275         else if ( ((acb_info & ACB_SVRTRUST) == ACB_SVRTRUST) ||  ((acb_info & ACB_DOMTRUST) == ACB_DOMTRUST) ) 
2276         {
2277                 pstrcpy(add_script, lp_addmachine_script());
2278                 /* only Domain Admins can add a BDC or domain trust */
2279                 se_priv_copy( &se_rights, &se_priv_none );
2280                 can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2281         }
2282         
2283         DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2284                 p->pipe_user_name, can_add_account ? "True":"False" ));
2285                 
2286         /********** BEGIN Admin BLOCK **********/
2287         
2288         if ( can_add_account )
2289                 become_root();
2290                                 
2291         if ( !pw ) {
2292                 if (*add_script) {
2293                         int add_ret;
2294                         
2295                         all_string_sub(add_script, "%u", account, sizeof(add_script));
2296                         add_ret = smbrun(add_script,NULL);
2297                         DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2298                 }
2299                 else    /* no add user script -- ask winbindd to do it */
2300                 {
2301                         if ( !winbind_create_user( account, &new_rid ) ) {
2302                                 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n", 
2303                                         account));
2304                         }
2305                 }
2306                 
2307         }
2308         
2309         /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
2310
2311         nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2312
2313         /* this code is order such that we have no unnecessary retuns 
2314            out of the admin block of code */    
2315            
2316         if ( NT_STATUS_IS_OK(nt_status) ) {
2317                 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2318         
2319                 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2320                         pdb_free_sam(&sam_pass);
2321                         DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2322                                 account));
2323                         nt_status = NT_STATUS_ACCESS_DENIED;
2324                 }
2325         }
2326                 
2327         if ( can_add_account )
2328                 unbecome_root();
2329
2330         /********** END Admin BLOCK **********/
2331         
2332         /* now check for failure */
2333         
2334         if ( !NT_STATUS_IS_OK(nt_status) )
2335                 return nt_status;
2336                         
2337         /* Get the user's SID */
2338         
2339         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2340         
2341         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2342         se_map_generic(&des_access, &usr_generic_mapping);
2343         
2344         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2345                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
2346                 &acc_granted, "_samr_create_user");
2347                 
2348         if ( !NT_STATUS_IS_OK(nt_status) ) {
2349                 return nt_status;
2350         }
2351
2352         /* associate the user's SID with the new handle. */
2353         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2354                 pdb_free_sam(&sam_pass);
2355                 return NT_STATUS_NO_MEMORY;
2356         }
2357
2358         ZERO_STRUCTP(info);
2359         info->sid = sid;
2360         info->acc_granted = acc_granted;
2361
2362         /* get a (unique) handle.  open a policy on it. */
2363         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2364                 pdb_free_sam(&sam_pass);
2365                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2366         }
2367
2368         r_u->user_rid=pdb_get_user_rid(sam_pass);
2369
2370         r_u->access_granted = acc_granted;
2371
2372         pdb_free_sam(&sam_pass);
2373
2374         return NT_STATUS_OK;
2375 }
2376
2377 /*******************************************************************
2378  samr_reply_connect_anon
2379  ********************************************************************/
2380
2381 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2382 {
2383         struct samr_info *info = NULL;
2384         uint32    des_access = q_u->access_mask;
2385
2386         /* Access check */
2387
2388         if (!pipe_access_check(p)) {
2389                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2390                 r_u->status = NT_STATUS_ACCESS_DENIED;
2391                 return r_u->status;
2392         }
2393
2394         /* set up the SAMR connect_anon response */
2395
2396         r_u->status = NT_STATUS_OK;
2397
2398         /* associate the user's SID with the new handle. */
2399         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2400                 return NT_STATUS_NO_MEMORY;
2401
2402         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
2403            was observed from a win98 client trying to enumerate users (when configured  
2404            user level access control on shares)   --jerry */
2405            
2406         se_map_generic( &des_access, &sam_generic_mapping );
2407         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2408         
2409         info->status = q_u->unknown_0;
2410
2411         /* get a (unique) handle.  open a policy on it. */
2412         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2413                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2414
2415         return r_u->status;
2416 }
2417
2418 /*******************************************************************
2419  samr_reply_connect
2420  ********************************************************************/
2421
2422 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2423 {
2424         struct samr_info *info = NULL;
2425         SEC_DESC *psd = NULL;
2426         uint32    acc_granted;
2427         uint32    des_access = q_u->access_mask;
2428         NTSTATUS  nt_status;
2429         size_t sd_size;
2430
2431
2432         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2433
2434         /* Access check */
2435
2436         if (!pipe_access_check(p)) {
2437                 DEBUG(3, ("access denied to samr_connect\n"));
2438                 r_u->status = NT_STATUS_ACCESS_DENIED;
2439                 return r_u->status;
2440         }
2441
2442         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2443         se_map_generic(&des_access, &sam_generic_mapping);
2444         
2445         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2446                 NULL, 0, des_access, &acc_granted, "_samr_connect");
2447         
2448         if ( !NT_STATUS_IS_OK(nt_status) ) 
2449                 return nt_status;
2450
2451         r_u->status = NT_STATUS_OK;
2452
2453         /* associate the user's SID and access granted with the new handle. */
2454         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2455                 return NT_STATUS_NO_MEMORY;
2456
2457         info->acc_granted = acc_granted;
2458         info->status = q_u->access_mask;
2459
2460         /* get a (unique) handle.  open a policy on it. */
2461         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2462                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2463
2464         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2465
2466         return r_u->status;
2467 }
2468
2469 /*******************************************************************
2470  samr_connect4
2471  ********************************************************************/
2472
2473 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2474 {
2475         struct samr_info *info = NULL;
2476         SEC_DESC *psd = NULL;
2477         uint32    acc_granted;
2478         uint32    des_access = q_u->access_mask;
2479         NTSTATUS  nt_status;
2480         size_t sd_size;
2481
2482
2483         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2484
2485         /* Access check */
2486
2487         if (!pipe_access_check(p)) {
2488                 DEBUG(3, ("access denied to samr_connect4\n"));
2489                 r_u->status = NT_STATUS_ACCESS_DENIED;
2490                 return r_u->status;
2491         }
2492
2493         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2494         se_map_generic(&des_access, &sam_generic_mapping);
2495         
2496         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2497                 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2498         
2499         if ( !NT_STATUS_IS_OK(nt_status) ) 
2500                 return nt_status;
2501
2502         r_u->status = NT_STATUS_OK;
2503
2504         /* associate the user's SID and access granted with the new handle. */
2505         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2506                 return NT_STATUS_NO_MEMORY;
2507
2508         info->acc_granted = acc_granted;
2509         info->status = q_u->access_mask;
2510
2511         /* get a (unique) handle.  open a policy on it. */
2512         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2513                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2514
2515         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2516
2517         return r_u->status;
2518 }
2519
2520 /**********************************************************************
2521  api_samr_lookup_domain
2522  **********************************************************************/
2523
2524 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2525 {
2526         struct samr_info *info;
2527         fstring domain_name;
2528         DOM_SID sid;
2529
2530         r_u->status = NT_STATUS_OK;
2531
2532         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2533                 return NT_STATUS_INVALID_HANDLE;
2534
2535         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.  
2536            Reverted that change so we will work with RAS servers again */
2537
2538         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
2539                 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) 
2540         {
2541                 return r_u->status;
2542         }
2543
2544         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2545
2546         ZERO_STRUCT(sid);
2547
2548         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2549                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2550         }
2551
2552         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2553
2554         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2555
2556         return r_u->status;
2557 }
2558
2559 /******************************************************************
2560 makes a SAMR_R_ENUM_DOMAINS structure.
2561 ********************************************************************/
2562
2563 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2564                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2565 {
2566         uint32 i;
2567         SAM_ENTRY *sam;
2568         UNISTR2 *uni_name;
2569
2570         DEBUG(5, ("make_enum_domains\n"));
2571
2572         *pp_sam = NULL;
2573         *pp_uni_name = NULL;
2574
2575         if (num_sam_entries == 0)
2576                 return True;
2577
2578         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2579         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2580
2581         if (sam == NULL || uni_name == NULL)
2582                 return False;
2583
2584         for (i = 0; i < num_sam_entries; i++) {
2585                 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2586                 init_sam_entry(&sam[i], &uni_name[i], 0);
2587         }
2588
2589         *pp_sam = sam;
2590         *pp_uni_name = uni_name;
2591
2592         return True;
2593 }
2594
2595 /**********************************************************************
2596  api_samr_enum_domains
2597  **********************************************************************/
2598
2599 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2600 {
2601         struct samr_info *info;
2602         uint32 num_entries = 2;
2603         fstring dom[2];
2604         const char *name;
2605
2606         r_u->status = NT_STATUS_OK;
2607         
2608         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2609                 return NT_STATUS_INVALID_HANDLE;
2610         
2611         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2612                 return r_u->status;
2613         }
2614
2615         name = get_global_sam_name();
2616
2617         fstrcpy(dom[0],name);
2618         strupper_m(dom[0]);
2619         fstrcpy(dom[1],"Builtin");
2620
2621         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2622                 return NT_STATUS_NO_MEMORY;
2623
2624         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2625
2626         return r_u->status;
2627 }
2628
2629 /*******************************************************************
2630  api_samr_open_alias
2631  ********************************************************************/
2632
2633 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2634 {
2635         DOM_SID sid;
2636         POLICY_HND domain_pol = q_u->dom_pol;
2637         uint32 alias_rid = q_u->rid_alias;
2638         POLICY_HND *alias_pol = &r_u->pol;
2639         struct    samr_info *info = NULL;
2640         SEC_DESC *psd = NULL;
2641         uint32    acc_granted;
2642         uint32    des_access = q_u->access_mask;
2643         size_t    sd_size;
2644         NTSTATUS  status;
2645         SE_PRIV se_rights;
2646
2647         r_u->status = NT_STATUS_OK;
2648
2649         /* find the domain policy and get the SID / access bits stored in the domain policy */
2650         
2651         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2652                 return NT_STATUS_INVALID_HANDLE;
2653         
2654         status = access_check_samr_function(acc_granted, 
2655                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2656                 
2657         if ( !NT_STATUS_IS_OK(status) ) 
2658                 return status;
2659
2660         /* append the alias' RID to it */
2661         
2662         if (!sid_append_rid(&sid, alias_rid))
2663                 return NT_STATUS_NO_SUCH_USER;
2664                 
2665         /*check if access can be granted as requested by client. */
2666         
2667         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2668         se_map_generic(&des_access,&ali_generic_mapping);
2669         
2670         se_priv_add( &se_rights, &se_add_users );
2671         
2672         
2673         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2674                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access, 
2675                 &acc_granted, "_samr_open_alias");
2676                 
2677         if ( !NT_STATUS_IS_OK(status) )
2678                 return status;
2679
2680         /*
2681          * we should check if the rid really exist !!!
2682          * JFM.
2683          */
2684
2685         /* associate the user's SID with the new handle. */
2686         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2687                 return NT_STATUS_NO_MEMORY;
2688                 
2689         info->acc_granted = acc_granted;
2690
2691         /* get a (unique) handle.  open a policy on it. */
2692         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2693                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2694
2695         return r_u->status;
2696 }
2697
2698 /*******************************************************************
2699  set_user_info_10
2700  ********************************************************************/
2701
2702 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2703 {
2704         if (id10 == NULL) {
2705                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2706                 pdb_free_sam(&pwd);
2707                 return False;
2708         }
2709         
2710         /* FIX ME: check if the value is really changed --metze */
2711         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2712                 pdb_free_sam(&pwd);
2713                 return False;
2714         }
2715
2716         if(!pdb_update_sam_account(pwd)) {
2717                 pdb_free_sam(&pwd);
2718                 return False;
2719         }
2720
2721         pdb_free_sam(&pwd);
2722
2723         return True;
2724 }
2725
2726 /*******************************************************************
2727  set_user_info_12
2728  ********************************************************************/
2729
2730 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2731 {
2732
2733         if (id12 == NULL) {
2734                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2735                 pdb_free_sam(&pwd);
2736                 return False;
2737         }
2738  
2739         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2740                 pdb_free_sam(&pwd);
2741                 return False;
2742         }
2743         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2744                 pdb_free_sam(&pwd);
2745                 return False;
2746         }
2747         if (!pdb_set_pass_changed_now (pwd)) {
2748                 pdb_free_sam(&pwd);
2749                 return False; 
2750         }
2751  
2752         if(!pdb_update_sam_account(pwd)) {
2753                 pdb_free_sam(&pwd);
2754                 return False;
2755         }
2756
2757         pdb_free_sam(&pwd);
2758         return True;
2759 }
2760
2761 /*******************************************************************
2762  The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2763  ********************************************************************/
2764 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2765 {
2766         struct group *grp;
2767         gid_t gid;
2768
2769         if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2770                                         &gid))) {
2771                 DEBUG(2,("Could not get gid for primary group of "
2772                          "user %s\n", pdb_get_username(sampass)));
2773                 return False;
2774         }
2775
2776         grp = getgrgid(gid);
2777
2778         if (grp == NULL) {
2779                 DEBUG(2,("Could not find primary group %lu for "
2780                          "user %s\n", (unsigned long)gid, 
2781                          pdb_get_username(sampass)));
2782                 return False;
2783         }
2784
2785         if (smb_set_primary_group(grp->gr_name,
2786                                   pdb_get_username(sampass)) != 0) {
2787                 DEBUG(2,("Could not set primary group for user %s to "
2788                          "%s\n",
2789                          pdb_get_username(sampass), grp->gr_name));
2790                 return False;
2791         }
2792
2793         return True;
2794 }
2795         
2796
2797 /*******************************************************************
2798  set_user_info_20
2799  ********************************************************************/
2800
2801 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2802 {
2803         if (id20 == NULL) {
2804                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2805                 return False;
2806         }
2807  
2808         copy_id20_to_sam_passwd(pwd, id20);
2809
2810         /* write the change out */
2811         if(!pdb_update_sam_account(pwd)) {
2812                 pdb_free_sam(&pwd);
2813                 return False;
2814         }
2815
2816         pdb_free_sam(&pwd);
2817
2818         return True;
2819 }
2820 /*******************************************************************
2821  set_user_info_21
2822  ********************************************************************/
2823
2824 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2825 {
2826  
2827         if (id21 == NULL) {
2828                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2829                 return False;
2830         }
2831  
2832         copy_id21_to_sam_passwd(pwd, id21);
2833  
2834         /*
2835          * The funny part about the previous two calls is
2836          * that pwd still has the password hashes from the
2837          * passdb entry.  These have not been updated from
2838          * id21.  I don't know if they need to be set.    --jerry
2839          */
2840  
2841         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2842                 set_unix_primary_group(pwd);
2843
2844         /* write the change out */
2845         if(!pdb_update_sam_account(pwd)) {
2846                 pdb_free_sam(&pwd);
2847                 return False;
2848         }
2849
2850         pdb_free_sam(&pwd);
2851
2852         return True;
2853 }
2854
2855 /*******************************************************************
2856  set_user_info_23
2857  ********************************************************************/
2858
2859 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2860 {
2861         pstring plaintext_buf;
2862         uint32 len;
2863         uint16 acct_ctrl;
2864  
2865         if (id23 == NULL) {
2866                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2867                 return False;
2868         }
2869  
2870         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2871                   pdb_get_username(pwd)));
2872
2873         acct_ctrl = pdb_get_acct_ctrl(pwd);
2874
2875         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2876                 pdb_free_sam(&pwd);
2877                 return False;
2878         }
2879   
2880         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2881                 pdb_free_sam(&pwd);
2882                 return False;
2883         }
2884  
2885         copy_id23_to_sam_passwd(pwd, id23);
2886  
2887         /* if it's a trust account, don't update /etc/passwd */
2888         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2889                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2890                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2891                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2892         } else  {
2893                 /* update the UNIX password */
2894                 if (lp_unix_password_sync() ) {
2895                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2896                         if (!passwd) {
2897                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2898                         }
2899                         
2900                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2901                                 pdb_free_sam(&pwd);
2902                                 return False;
2903                         }
2904                 }
2905         }
2906  
2907         ZERO_STRUCT(plaintext_buf);
2908  
2909         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2910                 set_unix_primary_group(pwd);
2911
2912         if(!pdb_update_sam_account(pwd)) {
2913                 pdb_free_sam(&pwd);
2914                 return False;
2915         }
2916  
2917         pdb_free_sam(&pwd);
2918
2919         return True;
2920 }
2921
2922 /*******************************************************************
2923  set_user_info_pw
2924  ********************************************************************/
2925
2926 static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
2927 {
2928         uint32 len;
2929         pstring plaintext_buf;
2930         uint16 acct_ctrl;
2931  
2932         DEBUG(5, ("Attempting administrator password change for user %s\n",
2933                   pdb_get_username(pwd)));
2934
2935         acct_ctrl = pdb_get_acct_ctrl(pwd);
2936
2937         ZERO_STRUCT(plaintext_buf);
2938  
2939         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2940                 pdb_free_sam(&pwd);
2941                 return False;
2942         }
2943
2944         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2945                 pdb_free_sam(&pwd);
2946                 return False;
2947         }
2948  
2949         /* if it's a trust account, don't update /etc/passwd */
2950         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2951                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2952                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2953                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2954         } else {
2955                 /* update the UNIX password */
2956                 if (lp_unix_password_sync()) {
2957                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2958                         if (!passwd) {
2959                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2960                         }
2961                         
2962                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2963                                 pdb_free_sam(&pwd);
2964                                 return False;
2965                         }
2966                 }
2967         }
2968  
2969         ZERO_STRUCT(plaintext_buf);
2970  
2971         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2972  
2973         /* update the SAMBA password */
2974         if(!pdb_update_sam_account(pwd)) {
2975                 pdb_free_sam(&pwd);
2976                 return False;
2977         }
2978
2979         pdb_free_sam(&pwd);
2980
2981         return True;
2982 }
2983
2984 /*******************************************************************
2985  samr_reply_set_userinfo
2986  ********************************************************************/
2987
2988 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2989 {
2990         SAM_ACCOUNT *pwd = NULL;
2991         DOM_SID sid;
2992         POLICY_HND *pol = &q_u->pol;
2993         uint16 switch_value = q_u->switch_value;
2994         SAM_USERINFO_CTR *ctr = q_u->ctr;
2995         uint32 acc_granted;
2996         uint32 acc_required;
2997         BOOL ret;
2998         BOOL has_enough_rights;
2999         SE_PRIV se_rights;
3000
3001         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3002
3003         r_u->status = NT_STATUS_OK;
3004
3005         /* find the policy handle.  open a policy on it. */
3006         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3007                 return NT_STATUS_INVALID_HANDLE;
3008
3009         /* observed when joining an XP client to a Samba domain */
3010         
3011         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;     
3012
3013         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3014                 return r_u->status;
3015         }
3016                 
3017         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3018
3019         if (ctr == NULL) {
3020                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3021                 return NT_STATUS_INVALID_INFO_CLASS;
3022         }
3023         
3024         pdb_init_sam(&pwd);     
3025         
3026         become_root();
3027         ret = pdb_getsampwsid(pwd, &sid);
3028         unbecome_root();
3029         
3030         if ( !ret ) {
3031                 pdb_free_sam(&pwd);
3032                 return NT_STATUS_NO_SUCH_USER;
3033         }
3034         
3035         /* deal with machine password changes differently from userinfo changes */
3036         
3037         if ( pdb_get_acct_ctrl(pwd) & ACB_WSTRUST )
3038                 se_priv_copy( &se_rights, &se_machine_account );
3039         else
3040                 se_priv_copy( &se_rights, &se_add_users );
3041
3042         /* check to see if we have the sufficient rights */
3043         
3044         has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3045         
3046         DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3047                 p->pipe_user_name, has_enough_rights ? "" : " not"));
3048
3049         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3050         
3051         if ( has_enough_rights )                                
3052                 become_root(); 
3053         
3054         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3055
3056         switch (switch_value) {
3057                 case 18:
3058                         if (!set_user_info_12(ctr->info.id12, pwd))
3059                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3060                         break;
3061
3062                 case 24:
3063                         if (!p->session_key.length) {
3064                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3065                         }
3066                         SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3067
3068                         dump_data(100, (char *)ctr->info.id24->pass, 516);
3069
3070                         if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
3071                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3072                         break;
3073
3074                 case 25:
3075 #if 0
3076                         /*
3077                          * Currently we don't really know how to unmarshall
3078                          * the level 25 struct, and the password encryption
3079                          * is different. This is a placeholder for when we
3080                          * do understand it. In the meantime just return INVALID
3081                          * info level and W2K SP2 drops down to level 23... JRA.
3082                          */
3083
3084                         if (!p->session_key.length) {
3085                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3086                         }
3087                         SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3088
3089                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3090
3091                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3092                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3093                         break;
3094 #endif
3095                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3096                         break;
3097
3098                 case 23:
3099                         if (!p->session_key.length) {
3100                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3101                         }
3102                         SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3103
3104                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3105
3106                         if (!set_user_info_23(ctr->info.id23, pwd))
3107                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3108                         break;
3109
3110                 default:
3111                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3112         }
3113
3114         
3115         if ( has_enough_rights )                                
3116                 unbecome_root();
3117                 
3118         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3119
3120         return r_u->status;
3121 }
3122
3123 /*******************************************************************
3124  samr_reply_set_userinfo2
3125  ********************************************************************/
3126
3127 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3128 {
3129         SAM_ACCOUNT *pwd = NULL;
3130         DOM_SID sid;
3131         SAM_USERINFO_CTR *ctr = q_u->ctr;
3132         POLICY_HND *pol = &q_u->pol;
3133         uint16 switch_value = q_u->switch_value;
3134         uint32 acc_granted;
3135         uint32 acc_required;
3136         BOOL ret;
3137         BOOL has_enough_rights;
3138         SE_PRIV se_rights;
3139
3140         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3141
3142         r_u->status = NT_STATUS_OK;
3143
3144         /* find the policy handle.  open a policy on it. */
3145         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3146                 return NT_STATUS_INVALID_HANDLE;
3147
3148         /* observed when joining XP client to Samba domain */
3149                 
3150         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3151         
3152         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3153                 return r_u->status;
3154         }
3155
3156         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3157
3158         if (ctr == NULL) {
3159                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3160                 return NT_STATUS_INVALID_INFO_CLASS;
3161         }
3162
3163         switch_value=ctr->switch_value;
3164
3165         pdb_init_sam(&pwd);     
3166         
3167         become_root();
3168         ret = pdb_getsampwsid(pwd, &sid);
3169         unbecome_root();
3170         
3171         if ( !ret ) {
3172                 pdb_free_sam(&pwd);
3173                 return NT_STATUS_NO_SUCH_USER;
3174         }
3175         
3176         /* deal with machine password changes differently from userinfo changes */
3177         
3178         if ( pdb_get_acct_ctrl(pwd) & ACB_WSTRUST )
3179                 se_priv_copy( &se_rights, &se_machine_account );
3180         else
3181                 se_priv_copy( &se_rights, &se_add_users );
3182
3183         /* check to see if we have the sufficient rights */
3184         
3185         has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3186         
3187         DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3188                 p->pipe_user_name, has_enough_rights ? "" : " not"));
3189
3190         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3191         
3192         if ( has_enough_rights )                                
3193                 become_root(); 
3194         
3195         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3196         
3197         switch (switch_value) {
3198                 case 16:
3199                         if (!set_user_info_10(ctr->info.id10, pwd))
3200                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3201                         break;
3202                 case 18:
3203                         /* Used by AS/U JRA. */
3204                         if (!set_user_info_12(ctr->info.id12, pwd))
3205                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3206                         break;
3207                 case 20:
3208                         if (!set_user_info_20(ctr->info.id20, pwd))
3209                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3210                         break;
3211                 case 21:
3212                         if (!set_user_info_21(ctr->info.id21, pwd))
3213                                 return NT_STATUS_ACCESS_DENIED;
3214                         break;
3215                 default:
3216                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3217         }
3218
3219         if ( has_enough_rights )                                
3220                 unbecome_root();
3221                 
3222         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3223
3224         return r_u->status;
3225 }
3226
3227 /*********************************************************************
3228  _samr_query_aliasmem
3229 *********************************************************************/
3230
3231 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3232 {
3233         int num_groups = 0;
3234         uint32 *rids=NULL;
3235         struct samr_info *info = NULL;
3236         int i;
3237                 
3238         NTSTATUS ntstatus1;
3239         NTSTATUS ntstatus2;
3240
3241         DOM_SID *members;
3242         DOM_SID *aliases;
3243         int num_aliases;
3244         BOOL res;
3245
3246         r_u->status = NT_STATUS_OK;
3247
3248         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3249
3250         /* find the policy handle.  open a policy on it. */
3251         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3252                 return NT_STATUS_INVALID_HANDLE;
3253                 
3254         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3255         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3256         
3257         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3258                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3259                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3260                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3261                 }
3262         }               
3263
3264         if (!sid_check_is_domain(&info->sid) &&
3265             !sid_check_is_builtin(&info->sid))
3266                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3267
3268         members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3269
3270         if (members == NULL)
3271                 return NT_STATUS_NO_MEMORY;
3272
3273         for (i=0; i<q_u->num_sids1; i++)
3274                 sid_copy(&members[i], &q_u->sid[i].sid);
3275
3276         become_root();
3277         res = pdb_enum_alias_memberships(members,
3278                                          q_u->num_sids1, &aliases,
3279                                          &num_aliases);
3280         unbecome_root();
3281
3282         if (!res)
3283                 return NT_STATUS_UNSUCCESSFUL;
3284
3285         rids = NULL;
3286         num_groups = 0;
3287
3288         for (i=0; i<num_aliases; i++) {
3289                 uint32 rid;
3290
3291                 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3292                         continue;
3293
3294                 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3295
3296                 if (rids == NULL)
3297                         return NT_STATUS_NO_MEMORY;
3298
3299                 rids[num_groups] = rid;
3300                 num_groups += 1;
3301         }
3302         SAFE_FREE(aliases);
3303
3304         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3305         return NT_STATUS_OK;
3306 }
3307
3308 /*********************************************************************
3309  _samr_query_aliasmem
3310 *********************************************************************/
3311
3312 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3313 {
3314         int i;
3315
3316         int num_sids = 0;
3317         DOM_SID2 *sid;
3318         DOM_SID *sids=NULL;
3319
3320         DOM_SID alias_sid;
3321
3322         uint32 acc_granted;
3323
3324         /* find the policy handle.  open a policy on it. */
3325         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3326                 return NT_STATUS_INVALID_HANDLE;
3327         
3328         if (!NT_STATUS_IS_OK(r_u->status = 
3329                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3330                 return r_u->status;
3331         }
3332
3333         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3334
3335         if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3336                 return NT_STATUS_NO_SUCH_ALIAS;
3337
3338         sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);        
3339         if (num_sids!=0 && sid == NULL) {
3340                 SAFE_FREE(sids);
3341                 return NT_STATUS_NO_MEMORY;
3342         }
3343
3344         for (i = 0; i < num_sids; i++) {
3345                 init_dom_sid2(&sid[i], &sids[i]);
3346         }
3347
3348         init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3349
3350         SAFE_FREE(sids);
3351
3352         return NT_STATUS_OK;
3353 }
3354
3355 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3356 {
3357         int i;
3358
3359         for (i=0; i<*num; i++) {
3360                 if ((*uids)[i] == uid)
3361                         return;
3362         }
3363         
3364         *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3365
3366         if (*uids == NULL)
3367                 return;
3368
3369         (*uids)[*num] = uid;
3370         *num += 1;
3371 }
3372
3373
3374 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3375 {
3376         struct group *grp;
3377         char **gr;
3378         struct sys_pwent *userlist, *user;
3379  
3380         *uids = NULL;
3381         *num = 0;
3382
3383         /* We only look at our own sam, so don't care about imported stuff */
3384
3385         winbind_off();
3386
3387         if ((grp = getgrgid(gid)) == NULL) {
3388                 winbind_on();
3389                 return False;
3390         }
3391
3392         /* Primary group members */
3393
3394         userlist = getpwent_list();
3395
3396         for (user = userlist; user != NULL; user = user->next) {
3397                 if (user->pw_gid != gid)
3398                         continue;
3399                 add_uid_to_array_unique(user->pw_uid, uids, num);
3400         }
3401
3402         pwent_free(userlist);
3403
3404         /* Secondary group members */
3405
3406         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3407                 struct passwd *pw = getpwnam(*gr);
3408
3409                 if (pw == NULL)
3410                         continue;
3411                 add_uid_to_array_unique(pw->pw_uid, uids, num);
3412         }
3413
3414         winbind_on();
3415
3416         return True;
3417 }       
3418
3419 /*********************************************************************
3420  _samr_query_groupmem
3421 *********************************************************************/
3422
3423 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3424 {
3425         int final_num_rids, i;
3426         DOM_SID group_sid;
3427         fstring group_sid_str;
3428         uid_t *uids;
3429         int num;
3430         gid_t gid;
3431
3432         uint32 *rid=NULL;
3433         uint32 *attr=NULL;
3434
3435         uint32 acc_granted;
3436
3437         /* find the policy handle.  open a policy on it. */
3438         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3439                 return NT_STATUS_INVALID_HANDLE;
3440                 
3441         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3442                 return r_u->status;
3443         }
3444                 
3445         sid_to_string(group_sid_str, &group_sid);
3446         DEBUG(10, ("sid is %s\n", group_sid_str));
3447
3448         if (!sid_check_is_in_our_domain(&group_sid)) {
3449                 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3450                 return NT_STATUS_NO_SUCH_GROUP;
3451         }
3452
3453         DEBUG(10, ("lookup on Domain SID\n"));
3454
3455         if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3456                 return NT_STATUS_NO_SUCH_GROUP;
3457
3458         if(!get_memberuids(gid, &uids, &num))
3459                 return NT_STATUS_NO_SUCH_GROUP;
3460
3461         rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3462         attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3463         
3464         if (num!=0 && (rid==NULL || attr==NULL))
3465                 return NT_STATUS_NO_MEMORY;
3466         
3467         final_num_rids = 0;
3468                 
3469         for (i=0; i<num; i++) {
3470                 DOM_SID sid;
3471
3472                 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3473                         DEBUG(1, ("Could not map member uid to SID\n"));
3474                         continue;
3475                 }
3476
3477                 if (!sid_check_is_in_our_domain(&sid)) {
3478                         DEBUG(1, ("Inconsistent SAM -- group member uid not "
3479                                   "in our domain\n"));
3480                         continue;
3481                 }
3482
3483                 sid_peek_rid(&sid, &rid[final_num_rids]);
3484
3485                 /* Hmm. In a trace I got the constant 7 here from NT. */
3486                 attr[final_num_rids] = SID_NAME_USER;
3487
3488                 final_num_rids += 1;
3489         }
3490
3491         SAFE_FREE(uids);
3492
3493         init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3494                                    NT_STATUS_OK);
3495
3496         return NT_STATUS_OK;
3497 }
3498
3499 /*********************************************************************
3500  _samr_add_aliasmem
3501 *********************************************************************/
3502
3503 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3504 {
3505         DOM_SID alias_sid;
3506         uint32 acc_granted;
3507         SE_PRIV se_rights;
3508         BOOL can_add_accounts;
3509         BOOL ret;
3510
3511
3512         /* Find the policy handle. Open a policy on it. */
3513         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3514                 return NT_STATUS_INVALID_HANDLE;
3515         
3516         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3517                 return r_u->status;
3518         }
3519                 
3520         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3521         
3522         se_priv_copy( &se_rights, &se_add_users );
3523         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3524
3525         /******** BEGIN SeAddUsers BLOCK *********/
3526         
3527         if ( can_add_accounts )
3528                 become_root();
3529         
3530         ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3531         
3532         if ( can_add_accounts )
3533                 unbecome_root();
3534                 
3535         /******** END SeAddUsers BLOCK *********/
3536         
3537         return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3538 }
3539
3540 /*********************************************************************
3541  _samr_del_aliasmem
3542 *********************************************************************/
3543
3544 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3545 {
3546         DOM_SID alias_sid;
3547         uint32 acc_granted;
3548         SE_PRIV se_rights;
3549         BOOL can_add_accounts;
3550         BOOL ret;
3551
3552         /* Find the policy handle. Open a policy on it. */
3553         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3554                 return NT_STATUS_INVALID_HANDLE;
3555         
3556         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3557                 return r_u->status;
3558         }
3559         
3560         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3561                    sid_string_static(&alias_sid)));
3562
3563         se_priv_copy( &se_rights, &se_add_users );
3564         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3565
3566         /******** BEGIN SeAddUsers BLOCK *********/
3567         
3568         if ( can_add_accounts )
3569                 become_root();
3570
3571         ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3572         
3573         if ( can_add_accounts )
3574                 unbecome_root();
3575                 
3576         /******** END SeAddUsers BLOCK *********/
3577         
3578         return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3579 }
3580
3581 /*********************************************************************
3582  _samr_add_groupmem
3583 *********************************************************************/
3584
3585 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3586 {
3587         DOM_SID group_sid;
3588         DOM_SID user_sid;
3589         fstring group_sid_str;
3590         uid_t uid;
3591         struct passwd *pwd;
3592         struct group *grp;
3593         fstring grp_name;
3594         GROUP_MAP map;
3595         NTSTATUS ret;
3596         SAM_ACCOUNT *sam_user=NULL;
3597         BOOL check;
3598         uint32 acc_granted;
3599         SE_PRIV se_rights;
3600         BOOL can_add_accounts;
3601
3602         /* Find the policy handle. Open a policy on it. */
3603         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3604                 return NT_STATUS_INVALID_HANDLE;
3605         
3606         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3607                 return r_u->status;
3608         }
3609
3610         sid_to_string(group_sid_str, &group_sid);
3611         DEBUG(10, ("sid is %s\n", group_sid_str));
3612
3613         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3614                 return NT_STATUS_NO_SUCH_GROUP;
3615
3616         DEBUG(10, ("lookup on Domain SID\n"));
3617
3618         if(!get_domain_group_from_sid(group_sid, &map))
3619                 return NT_STATUS_NO_SUCH_GROUP;
3620
3621         sid_copy(&user_sid, get_global_sam_sid());
3622         sid_append_rid(&user_sid, q_u->rid);
3623
3624         ret = pdb_init_sam(&sam_user);
3625         if (!NT_STATUS_IS_OK(ret))
3626                 return ret;
3627         
3628         check = pdb_getsampwsid(sam_user, &user_sid);
3629         
3630         if (check != True) {
3631                 pdb_free_sam(&sam_user);
3632                 return NT_STATUS_NO_SUCH_USER;
3633         }
3634
3635         /* check a real user exist before we run the script to add a user to a group */
3636         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3637                 pdb_free_sam(&sam_user);
3638                 return NT_STATUS_NO_SUCH_USER;
3639         }
3640
3641         pdb_free_sam(&sam_user);
3642
3643         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3644                 return NT_STATUS_NO_SUCH_USER;
3645         }
3646
3647         if ((grp=getgrgid(map.gid)) == NULL) {
3648                 passwd_free(&pwd);
3649                 return NT_STATUS_NO_SUCH_GROUP;
3650         }
3651
3652         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3653         fstrcpy(grp_name, grp->gr_name);
3654
3655         /* if the user is already in the group */
3656         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3657                 passwd_free(&pwd);
3658                 return NT_STATUS_MEMBER_IN_GROUP;
3659         }
3660
3661         se_priv_copy( &se_rights, &se_add_users );
3662         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3663
3664         /******** BEGIN SeAddUsers BLOCK *********/
3665         
3666         if ( can_add_accounts )
3667                 become_root();
3668                 
3669         /* 
3670          * ok, the group exist, the user exist, the user is not in the group,
3671          *
3672          * we can (finally) add it to the group !
3673          */
3674
3675         smb_add_user_group(grp_name, pwd->pw_name);
3676
3677         if ( can_add_accounts )
3678                 unbecome_root();
3679                 
3680         /******** END SeAddUsers BLOCK *********/
3681         
3682         /* check if the user has been added then ... */
3683         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3684                 passwd_free(&pwd);
3685                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3686         }
3687
3688         passwd_free(&pwd);
3689         return NT_STATUS_OK;
3690 }
3691
3692 /*********************************************************************
3693  _samr_del_groupmem
3694 *********************************************************************/
3695
3696 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3697 {
3698         DOM_SID group_sid;
3699         DOM_SID user_sid;
3700         SAM_ACCOUNT *sam_pass=NULL;
3701         GROUP_MAP map;
3702         fstring grp_name;
3703         struct group *grp;
3704         uint32 acc_granted;
3705         SE_PRIV se_rights;
3706         BOOL can_add_accounts;
3707
3708         /*
3709          * delete the group member named q_u->rid
3710          * who is a member of the sid associated with the handle
3711          * the rid is a user's rid as the group is a domain group.
3712          */
3713
3714         /* Find the policy handle. Open a policy on it. */
3715         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3716                 return NT_STATUS_INVALID_HANDLE;
3717         
3718         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3719                 return r_u->status;
3720         }
3721                 
3722         if (!sid_check_is_in_our_domain(&group_sid))
3723                 return NT_STATUS_NO_SUCH_GROUP;
3724
3725         sid_copy(&user_sid, get_global_sam_sid());
3726         sid_append_rid(&user_sid, q_u->rid);
3727
3728         if (!get_domain_group_from_sid(group_sid, &map))
3729                 return NT_STATUS_NO_SUCH_GROUP;
3730
3731         if ((grp=getgrgid(map.gid)) == NULL)
3732                 return NT_STATUS_NO_SUCH_GROUP;
3733
3734         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3735         fstrcpy(grp_name, grp->gr_name);
3736
3737         /* check if the user exists before trying to remove it from the group */
3738         pdb_init_sam(&sam_pass);
3739         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3740                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3741                 pdb_free_sam(&sam_pass);
3742                 return NT_STATUS_NO_SUCH_USER;
3743         }
3744
3745         /* if the user is not in the group */
3746         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3747                 pdb_free_sam(&sam_pass);
3748                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3749         }
3750         
3751
3752         se_priv_copy( &se_rights, &se_add_users );
3753         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3754
3755         /******** BEGIN SeAddUsers BLOCK *********/
3756         
3757         if ( can_add_accounts )
3758                 become_root();
3759                 
3760         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3761
3762         if ( can_add_accounts )
3763                 unbecome_root();
3764                 
3765         /******** END SeAddUsers BLOCK *********/
3766         
3767         /* check if the user has been removed then ... */
3768         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3769                 pdb_free_sam(&sam_pass);
3770                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3771         }
3772         
3773         pdb_free_sam(&sam_pass);
3774         return NT_STATUS_OK;
3775
3776 }
3777
3778 /****************************************************************************
3779  Delete a UNIX user on demand.
3780 ****************************************************************************/
3781
3782 static int smb_delete_user(const char *unix_user)
3783 {
3784         pstring del_script;
3785         int ret;
3786
3787         /* try winbindd first since it is impossible to determine where 
3788            a user came from via NSS.  Try the delete user script if this fails
3789            meaning the user did not exist in winbindd's list of accounts */
3790
3791         if ( winbind_delete_user( unix_user ) ) {
3792                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3793                 return 0;
3794         }
3795
3796
3797         /* fall back to 'delete user script' */
3798
3799         pstrcpy(del_script, lp_deluser_script());
3800         if (! *del_script)
3801                 return -1;
3802         all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3803         ret = smbrun(del_script,NULL);
3804         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3805
3806         return ret;
3807 }
3808
3809 /*********************************************************************
3810  _samr_delete_dom_user
3811 *********************************************************************/
3812
3813 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3814 {
3815         DOM_SID user_sid;
3816         SAM_ACCOUNT *sam_pass=NULL;
3817         uint32 acc_granted;
3818         SE_PRIV se_rights;
3819         BOOL can_add_accounts;
3820         BOOL ret;
3821
3822         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3823
3824         /* Find the policy handle. Open a policy on it. */
3825         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3826                 return NT_STATUS_INVALID_HANDLE;
3827                 
3828         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3829                 return r_u->status;
3830         }
3831                 
3832         if (!sid_check_is_in_our_domain(&user_sid))
3833                 return NT_STATUS_CANNOT_DELETE;
3834
3835         /* check if the user exists before trying to delete */
3836         pdb_init_sam(&sam_pass);
3837         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3838                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3839                         sid_string_static(&user_sid)));
3840                 pdb_free_sam(&sam_pass);
3841                 return NT_STATUS_NO_SUCH_USER;
3842         }
3843         
3844         se_priv_copy( &se_rights, &se_add_users );
3845         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3846
3847         /******** BEGIN SeAddUsers BLOCK *********/
3848         
3849         if ( can_add_accounts )
3850                 become_root();
3851
3852         /* First delete the samba side....
3853            code is order to prevent unnecessary returns out of the admin 
3854            block of code */
3855            
3856         if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3857                 /*
3858                  * Now delete the unix side ....
3859                  * note: we don't check if the delete really happened
3860                  * as the script is not necessary present
3861                  * and maybe the sysadmin doesn't want to delete the unix side
3862                  */
3863                 smb_delete_user( pdb_get_username(sam_pass) );
3864         }
3865         
3866         if ( can_add_accounts )
3867                 unbecome_root();
3868                 
3869         /******** END SeAddUsers BLOCK *********/
3870                 
3871         if ( !ret ) {
3872                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3873                 pdb_free_sam(&sam_pass);
3874                 return NT_STATUS_CANNOT_DELETE;
3875         }
3876
3877
3878         pdb_free_sam(&sam_pass);
3879
3880         if (!close_policy_hnd(p, &q_u->user_pol))
3881                 return NT_STATUS_OBJECT_NAME_INVALID;
3882
3883         return NT_STATUS_OK;
3884 }
3885
3886 /*********************************************************************
3887  _samr_delete_dom_group
3888 *********************************************************************/
3889
3890 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3891 {
3892         DOM_SID group_sid;
3893         DOM_SID dom_sid;
3894         uint32 group_rid;
3895         fstring group_sid_str;
3896         gid_t gid;
3897         struct group *grp;
3898         GROUP_MAP map;
3899         uint32 acc_granted;
3900         SE_PRIV se_rights;
3901         BOOL can_add_accounts;
3902         BOOL ret;
3903
3904         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3905
3906         /* Find the policy handle. Open a policy on it. */
3907         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3908                 return NT_STATUS_INVALID_HANDLE;
3909                 
3910         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3911                 return r_u->status;
3912         }
3913                 
3914         sid_copy(&dom_sid, &group_sid);
3915         sid_to_string(group_sid_str, &dom_sid);
3916         sid_split_rid(&dom_sid, &group_rid);
3917
3918         DEBUG(10, ("sid is %s\n", group_sid_str));
3919
3920         /* we check if it's our SID before deleting */
3921         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3922                 return NT_STATUS_NO_SUCH_GROUP;
3923
3924         DEBUG(10, ("lookup on Domain SID\n"));
3925
3926         if(!get_domain_group_from_sid(group_sid, &map))
3927                 return NT_STATUS_NO_SUCH_GROUP;
3928
3929         gid=map.gid;
3930
3931         /* check if group really exists */
3932         if ( (grp=getgrgid(gid)) == NULL)
3933                 return NT_STATUS_NO_SUCH_GROUP;
3934
3935         se_priv_copy( &se_rights, &se_add_users );
3936         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3937
3938         /******** BEGIN SeAddUsers BLOCK *********/
3939         
3940         if ( can_add_accounts )
3941                 become_root();
3942
3943         /* delete mapping first */
3944         
3945         if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3946                 smb_delete_group( grp->gr_name );
3947         }
3948
3949         if ( can_add_accounts )
3950                 unbecome_root();
3951                 
3952         /******** END SeAddUsers BLOCK *********/
3953         
3954         if ( !ret ) {
3955                 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n", 
3956                         group_sid_str));
3957                 return NT_STATUS_ACCESS_DENIED;
3958         }
3959         
3960         /* don't check that the unix group has been deleted.  Work like 
3961            _samr_delet_dom_user() */
3962
3963         if (!close_policy_hnd(p, &q_u->group_pol))
3964                 return NT_STATUS_OBJECT_NAME_INVALID;
3965
3966         return NT_STATUS_OK;
3967 }
3968
3969 /*********************************************************************
3970  _samr_delete_dom_alias
3971 *********************************************************************/
3972
3973 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3974 {
3975         DOM_SID alias_sid;
3976         uint32 acc_granted;
3977         SE_PRIV se_rights;
3978         BOOL can_add_accounts;
3979         BOOL ret;
3980
3981         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3982
3983         /* Find the policy handle. Open a policy on it. */
3984         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3985                 return NT_STATUS_INVALID_HANDLE;
3986         
3987         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3988                 return r_u->status;
3989         }
3990
3991         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3992
3993         if (!sid_check_is_in_our_domain(&alias_sid))
3994                 return NT_STATUS_NO_SUCH_ALIAS;
3995                 
3996         DEBUG(10, ("lookup on Local SID\n"));
3997
3998         se_priv_copy( &se_rights, &se_add_users );
3999         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4000
4001         /******** BEGIN SeAddUsers BLOCK *********/
4002         
4003         if ( can_add_accounts )
4004                 become_root();
4005
4006         /* Have passdb delete the alias */
4007         ret = pdb_delete_alias(&alias_sid);
4008         
4009         if ( can_add_accounts )
4010                 unbecome_root();
4011                 
4012         /******** END SeAddUsers BLOCK *********/
4013
4014         if ( !ret )
4015                 return NT_STATUS_ACCESS_DENIED;
4016
4017         if (!close_policy_hnd(p, &q_u->alias_pol))
4018                 return NT_STATUS_OBJECT_NAME_INVALID;
4019
4020         return NT_STATUS_OK;
4021 }
4022
4023 /*********************************************************************
4024  _samr_create_dom_group
4025 *********************************************************************/
4026
4027 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4028 {
4029         DOM_SID dom_sid;
4030         DOM_SID info_sid;
4031         fstring name;
4032         fstring sid_string;
4033         struct group *grp;
4034         struct samr_info *info;
4035         uint32 acc_granted;
4036         gid_t gid;
4037         SE_PRIV se_rights;
4038         BOOL can_add_accounts;
4039         NTSTATUS result;
4040
4041         /* Find the policy handle. Open a policy on it. */
4042         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
4043                 return NT_STATUS_INVALID_HANDLE;
4044         
4045         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4046                 return r_u->status;
4047         }
4048                 
4049         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4050                 return NT_STATUS_ACCESS_DENIED;
4051
4052         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4053
4054         /* check if group already exist */
4055         if ((grp=getgrnam(name)) != NULL)
4056                 return NT_STATUS_GROUP_EXISTS;
4057
4058         se_priv_copy( &se_rights, &se_add_users );
4059         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4060
4061         /******** BEGIN SeAddUsers BLOCK *********/
4062         
4063         if ( can_add_accounts )
4064                 become_root();
4065         
4066         /* check that we successfully create the UNIX group */
4067         
4068         result = NT_STATUS_ACCESS_DENIED;
4069         if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4070         
4071                 /* so far, so good */
4072                 
4073                 result = NT_STATUS_OK;
4074                 
4075                 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4076
4077                 /* add the group to the mapping table */
4078                 
4079                 sid_copy( &info_sid, get_global_sam_sid() );
4080                 sid_append_rid( &info_sid, r_u->rid );
4081                 sid_to_string( sid_string, &info_sid );
4082                 
4083                 /* reset the error code if we fail to add the mapping entry */
4084                 
4085                 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4086                         result = NT_STATUS_ACCESS_DENIED;
4087         }
4088
4089         if ( can_add_accounts )
4090                 unbecome_root();
4091                 
4092         /******** END SeAddUsers BLOCK *********/
4093         
4094         /* check if we should bail out here */
4095         
4096         if ( !NT_STATUS_IS_OK(result) )
4097                 return result;
4098         
4099         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4100                 return NT_STATUS_NO_MEMORY;
4101
4102         /* get a (unique) handle.  open a policy on it. */
4103         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4104                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4105
4106         return NT_STATUS_OK;
4107 }
4108
4109 /*********************************************************************
4110  _samr_create_dom_alias
4111 *********************************************************************/
4112
4113 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4114 {
4115         DOM_SID dom_sid;
4116         DOM_SID info_sid;
4117         fstring name;
4118         struct group *grp;
4119         struct samr_info *info;
4120         uint32 acc_granted;
4121         gid_t gid;
4122         NTSTATUS result;
4123         SE_PRIV se_rights;
4124         BOOL can_add_accounts;
4125
4126         /* Find the policy handle. Open a policy on it. */
4127         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
4128                 return NT_STATUS_INVALID_HANDLE;
4129                 
4130         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4131                 return r_u->status;
4132         }
4133                 
4134         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4135                 return NT_STATUS_ACCESS_DENIED;
4136
4137         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4138
4139         se_priv_copy( &se_rights, &se_add_users );
4140         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4141
4142         /******** BEGIN SeAddUsers BLOCK *********/
4143         
4144         if ( can_add_accounts )
4145                 become_root();
4146
4147         /* Have passdb create the alias */
4148         result = pdb_create_alias(name, &r_u->rid);
4149
4150         if ( can_add_accounts )
4151                 unbecome_root();
4152                 
4153         /******** END SeAddUsers BLOCK *********/
4154
4155         if (!NT_STATUS_IS_OK(result))
4156                 return result;
4157
4158         sid_copy(&info_sid, get_global_sam_sid());
4159         sid_append_rid(&info_sid, r_u->rid);
4160
4161         if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4162                 return NT_STATUS_ACCESS_DENIED;
4163
4164         /* check if the group has been successfully created */
4165         if ((grp=getgrgid(gid)) == NULL)
4166                 return NT_STATUS_ACCESS_DENIED;
4167
4168         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4169                 return NT_STATUS_NO_MEMORY;
4170
4171         /* get a (unique) handle.  open a policy on it. */
4172         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4173                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4174
4175         return NT_STATUS_OK;
4176 }
4177
4178 /*********************************************************************
4179  _samr_query_groupinfo
4180
4181 sends the name/comment pair of a domain group
4182 level 1 send also the number of users of that group
4183 *********************************************************************/
4184
4185 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4186 {
4187         DOM_SID group_sid;
4188         GROUP_MAP map;
4189         DOM_SID *sids=NULL;
4190         uid_t *uids;
4191         int num=0;
4192         GROUP_INFO_CTR *ctr;
4193         uint32 acc_granted;
4194         BOOL ret;
4195
4196         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4197                 return NT_STATUS_INVALID_HANDLE;
4198         
4199         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4200                 return r_u->status;
4201         }
4202                 
4203         become_root();
4204         ret = get_domain_group_from_sid(group_sid, &map);
4205         unbecome_root();
4206         if (!ret)
4207                 return NT_STATUS_INVALID_HANDLE;
4208
4209         ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4210         if (ctr==NULL)
4211                 return NT_STATUS_NO_MEMORY;
4212
4213         switch (q_u->switch_level) {
4214                 case 1:
4215                         ctr->switch_value1 = 1;
4216                         if(!get_memberuids(map.gid, &uids, &num))
4217                                 return NT_STATUS_NO_SUCH_GROUP;
4218                         SAFE_FREE(uids);
4219                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4220                         SAFE_FREE(sids);
4221                         break;
4222                 case 3:
4223                         ctr->switch_value1 = 3;
4224                         init_samr_group_info3(&ctr->group.info3);
4225                         break;
4226                 case 4:
4227                         ctr->switch_value1 = 4;
4228                         init_samr_group_info4(&ctr->group.info4, map.comment);
4229                         break;
4230                 default:
4231                         return NT_STATUS_INVALID_INFO_CLASS;
4232         }
4233
4234         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4235
4236         return NT_STATUS_OK;
4237 }
4238
4239 /*********************************************************************
4240  _samr_set_groupinfo
4241  
4242  update a domain group's comment.
4243 *********************************************************************/
4244
4245 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4246 {
4247         DOM_SID group_sid;
4248         GROUP_MAP map;
4249         GROUP_INFO_CTR *ctr;
4250         uint32 acc_granted;
4251
4252         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4253                 return NT_STATUS_INVALID_HANDLE;
4254         
4255         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4256                 return r_u->status;
4257         }
4258                 
4259         if (!get_domain_group_from_sid(group_sid, &map))
4260                 return NT_STATUS_NO_SUCH_GROUP;
4261         
4262         ctr=q_u->ctr;
4263
4264         switch (ctr->switch_value1) {
4265                 case 1:
4266                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4267                         break;
4268                 case 4:
4269                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4270                         break;
4271                 default:
4272                         return NT_STATUS_INVALID_INFO_CLASS;
4273         }
4274
4275         if(!pdb_update_group_mapping_entry(&map)) {
4276                 return NT_STATUS_NO_SUCH_GROUP;
4277         }
4278
4279         return NT_STATUS_OK;
4280 }
4281
4282 /*********************************************************************
4283  _samr_set_aliasinfo
4284  
4285  update an alias's comment.
4286 *********************************************************************/
4287
4288 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4289 {
4290         DOM_SID group_sid;
4291         struct acct_info info;
4292         ALIAS_INFO_CTR *ctr;
4293         uint32 acc_granted;
4294
4295         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4296                 return NT_STATUS_INVALID_HANDLE;
4297         
4298         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4299                 return r_u->status;
4300         }
4301                 
4302         ctr=&q_u->ctr;
4303
4304         switch (ctr->switch_value1) {
4305                 case 3:
4306                         unistr2_to_ascii(info.acct_desc,
4307                                          &(ctr->alias.info3.uni_acct_desc),
4308                                          sizeof(info.acct_desc)-1);
4309                         break;
4310                 default:
4311                         return NT_STATUS_INVALID_INFO_CLASS;
4312         }
4313
4314         if(!pdb_set_aliasinfo(&group_sid, &info)) {
4315                 return NT_STATUS_ACCESS_DENIED;
4316         }
4317
4318         return NT_STATUS_OK;
4319 }
4320
4321 /*********************************************************************
4322  _samr_get_dom_pwinfo
4323 *********************************************************************/
4324
4325 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4326 {
4327         /* Perform access check.  Since this rpc does not require a
4328            policy handle it will not be caught by the access checks on
4329            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4330
4331         if (!pipe_access_check(p)) {
4332                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4333                 r_u->status = NT_STATUS_ACCESS_DENIED;
4334                 return r_u->status;
4335         }
4336
4337         /* Actually, returning zeros here works quite well :-). */
4338
4339         return NT_STATUS_OK;
4340 }
4341
4342 /*********************************************************************
4343  _samr_open_group
4344 *********************************************************************/
4345
4346 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4347 {
4348         DOM_SID sid;
4349         DOM_SID info_sid;
4350         GROUP_MAP map;
4351         struct samr_info *info;
4352         SEC_DESC         *psd = NULL;
4353         uint32            acc_granted;
4354         uint32            des_access = q_u->access_mask;
4355         size_t            sd_size;
4356         NTSTATUS          status;
4357         fstring sid_string;
4358         BOOL ret;
4359         SE_PRIV se_rights;
4360
4361         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4362                 return NT_STATUS_INVALID_HANDLE;
4363         
4364         status = access_check_samr_function(acc_granted, 
4365                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4366                 
4367         if ( !NT_STATUS_IS_OK(status) )
4368                 return status;
4369                 
4370         /*check if access can be granted as requested by client. */
4371         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4372         se_map_generic(&des_access,&grp_generic_mapping);
4373
4374         se_priv_copy( &se_rights, &se_add_users );
4375
4376         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4377                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access, 
4378                 &acc_granted, "_samr_open_group");
4379                 
4380         if ( !NT_STATUS_IS_OK(status) ) 
4381                 return status;
4382
4383         /* this should not be hard-coded like this */
4384         
4385         if (!sid_equal(&sid, get_global_sam_sid()))
4386                 return NT_STATUS_ACCESS_DENIED;
4387
4388         sid_copy(&info_sid, get_global_sam_sid());
4389         sid_append_rid(&info_sid, q_u->rid_group);
4390         sid_to_string(sid_string, &info_sid);
4391
4392         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4393                 return NT_STATUS_NO_MEMORY;
4394                 
4395         info->acc_granted = acc_granted;
4396
4397         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4398
4399         /* check if that group really exists */
4400         become_root();
4401         ret = get_domain_group_from_sid(info->sid, &map);
4402         unbecome_root();
4403         if (!ret)
4404                 return NT_STATUS_NO_SUCH_GROUP;
4405
4406         /* get a (unique) handle.  open a policy on it. */
4407         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4408                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4409
4410         return NT_STATUS_OK;
4411 }
4412
4413 /*********************************************************************
4414  _samr_remove_sid_foreign_domain
4415 *********************************************************************/
4416
4417 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4418                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4419                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4420 {
4421         DOM_SID                 delete_sid, alias_sid;
4422         SAM_ACCOUNT             *sam_pass=NULL;
4423         uint32                  acc_granted;
4424         GROUP_MAP               map;
4425         BOOL                    is_user = False;
4426         NTSTATUS                result;
4427         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4428         
4429         sid_copy( &delete_sid, &q_u->sid.sid );
4430         
4431         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4432                 sid_string_static(&delete_sid)));
4433                 
4434         /* Find the policy handle. Open a policy on it. */
4435         
4436         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4437                 return NT_STATUS_INVALID_HANDLE;
4438         
4439         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4440                 "_samr_remove_sid_foreign_domain");
4441                 
4442         if (!NT_STATUS_IS_OK(result)) 
4443                 return result;
4444                         
4445         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4446                 sid_string_static(&alias_sid)));
4447                 
4448         /* make sure we can handle this */
4449         
4450         if ( sid_check_is_domain(&alias_sid) )
4451                 type = SID_NAME_DOM_GRP;
4452         else if ( sid_check_is_builtin(&alias_sid) )
4453                 type = SID_NAME_ALIAS;
4454         
4455         if ( type == SID_NAME_UNKNOWN ) {
4456                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4457                 return NT_STATUS_OK;
4458         }
4459
4460         /* check if the user exists before trying to delete */
4461         
4462         pdb_init_sam(&sam_pass);
4463         
4464         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4465                 is_user = True;
4466         } else {
4467                 /* maybe it is a group */
4468                 if( !pdb_getgrsid(&map, delete_sid) ) {
4469                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4470                                 sid_string_static(&delete_sid)));
4471                         result = NT_STATUS_INVALID_SID;
4472                         goto done;
4473                 }
4474         }
4475         
4476         /* we can only delete a user from a group since we don't have 
4477            nested groups anyways.  So in the latter case, just say OK */
4478            
4479         if ( is_user ) {
4480                 GROUP_MAP       *mappings = NULL;
4481                 int             num_groups, i;
4482                 struct group    *grp2;
4483                 
4484                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4485                 
4486                         /* interate over the groups */
4487                         for ( i=0; i<num_groups; i++ ) {
4488
4489                                 grp2 = getgrgid(mappings[i].gid);
4490
4491                                 if ( !grp2 ) {
4492                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4493                                         continue;
4494                                 }
4495                         
4496                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4497                                         continue;
4498                                 
4499                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4500                                 
4501                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4502                                         /* should we fail here ? */
4503                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4504                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4505                                         continue;
4506                                 }
4507                                         
4508                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4509                                         pdb_get_username(sam_pass), grp2->gr_name ));
4510                         }
4511                         
4512                         SAFE_FREE(mappings);
4513                 }
4514         }
4515         
4516         result = NT_STATUS_OK;
4517 done:
4518
4519         pdb_free_sam(&sam_pass);
4520
4521         return result;
4522 }
4523
4524 /*******************************************************************
4525  _samr_unknown_2e
4526  ********************************************************************/
4527
4528 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4529 {
4530         struct samr_info *info = NULL;
4531         SAM_UNK_CTR *ctr;
4532         uint32 min_pass_len,pass_hist,flag;
4533         time_t u_expire, u_min_age;
4534         NTTIME nt_expire, nt_min_age;
4535
4536         time_t u_lock_duration, u_reset_time;
4537         NTTIME nt_lock_duration, nt_reset_time;
4538         uint32 lockout;
4539         
4540         time_t u_logout;
4541         NTTIME nt_logout;
4542
4543         uint32 num_users=0, num_groups=0, num_aliases=0;
4544
4545         uint32 account_policy_temp;
4546
4547         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4548                 return NT_STATUS_NO_MEMORY;
4549
4550         ZERO_STRUCTP(ctr);
4551
4552         r_u->status = NT_STATUS_OK;
4553
4554         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4555
4556         /* find the policy handle.  open a policy on it. */
4557         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4558                 return NT_STATUS_INVALID_HANDLE;
4559
4560         switch (q_u->switch_value) {
4561                 case 0x01:
4562                         pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4563                         min_pass_len = account_policy_temp;
4564
4565                         pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
4566                         pass_hist = account_policy_temp;
4567
4568                         pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4569                         flag = account_policy_temp;
4570
4571                         pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4572                         u_expire = account_policy_temp;
4573
4574                         pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4575                         u_min_age = account_policy_temp;
4576
4577                         unix_to_nt_time_abs(&nt_expire, u_expire);
4578                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4579
4580                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4581                                        flag, nt_expire, nt_min_age);
4582                         break;
4583                 case 0x02:
4584                         become_root();          
4585                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4586                         unbecome_root();
4587                         if (!NT_STATUS_IS_OK(r_u->status)) {
4588                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4589                                 return r_u->status;
4590                         }
4591                         num_users=info->disp_info.num_user_account;
4592                         free_samr_db(info);
4593                         
4594                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4595                         if (NT_STATUS_IS_ERR(r_u->status)) {
4596                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4597                                 return r_u->status;
4598                         }
4599                         num_groups=info->disp_info.num_group_account;
4600                         free_samr_db(info);
4601
4602                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
4603                         u_logout = account_policy_temp;
4604
4605                         unix_to_nt_time_abs(&nt_logout, u_logout);
4606
4607                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4608                         init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL), 
4609                                        num_users, num_groups, num_aliases, nt_logout);
4610                         break;
4611                 case 0x03:
4612                         pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
4613                         u_logout = account_policy_temp;
4614
4615                         unix_to_nt_time_abs(&nt_logout, u_logout);
4616                         
4617                         init_unk_info3(&ctr->info.inf3, nt_logout);
4618                         break;
4619                 case 0x05:
4620                         init_unk_info5(&ctr->info.inf5, global_myname());
4621                         break;
4622                 case 0x06:
4623                         init_unk_info6(&ctr->info.inf6);
4624                         break;
4625                 case 0x07:
4626                         init_unk_info7(&ctr->info.inf7);
4627                         break;
4628                 case 0x08:
4629                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4630                         break;
4631                 case 0x0c:
4632                         pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4633                         u_lock_duration = account_policy_temp;
4634                         if (u_lock_duration != -1)
4635                                 u_lock_duration *= 60;
4636
4637                         pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
4638                         u_reset_time = account_policy_temp * 60;
4639
4640                         pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4641                         lockout = account_policy_temp;
4642         
4643                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4644                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4645         
4646                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4647                         break;
4648                 default:
4649                         return NT_STATUS_INVALID_INFO_CLASS;
4650         }
4651
4652         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4653
4654         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4655
4656         return r_u->status;
4657 }
4658
4659 /*******************************************************************
4660  _samr_
4661  ********************************************************************/
4662
4663 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4664 {
4665         time_t u_expire, u_min_age;
4666         time_t u_logout;
4667         time_t u_lock_duration, u_reset_time;
4668
4669         r_u->status = NT_STATUS_OK;
4670
4671         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4672
4673         /* find the policy handle.  open a policy on it. */
4674         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4675                 return NT_STATUS_INVALID_HANDLE;
4676
4677         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4678
4679         switch (q_u->switch_value) {
4680                 case 0x01:
4681                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4682                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4683                         
4684                         pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4685                         pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4686                         pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4687                         pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
4688                         pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4689                         break;
4690                 case 0x02:
4691                         break;
4692                 case 0x03:
4693                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4694                         pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
4695                         break;
4696                 case 0x05:
4697                         break;
4698                 case 0x06:
4699                         break;
4700                 case 0x07:
4701                         break;
4702                 case 0x0c:
4703                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4704                         if (u_lock_duration != -1)
4705                                 u_lock_duration /= 60;
4706
4707                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4708                         
4709                         pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4710                         pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
4711                         pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4712                         break;
4713                 default:
4714                         return NT_STATUS_INVALID_INFO_CLASS;
4715         }
4716
4717         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4718
4719         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4720
4721         return r_u->status;
4722 }