r5349: After talking with Jerry, reverted the addition of account policies to
[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         uint32 server_role;
2076
2077         uint32 num_users=0, num_groups=0, num_aliases=0;
2078
2079         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2080                 return NT_STATUS_NO_MEMORY;
2081
2082         ZERO_STRUCTP(ctr);
2083
2084         r_u->status = NT_STATUS_OK;
2085         
2086         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2087         
2088         /* find the policy handle.  open a policy on it. */
2089         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2090                 return NT_STATUS_INVALID_HANDLE;
2091         
2092         switch (q_u->switch_value) {
2093                 case 0x01:
2094                         
2095                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2096                         min_pass_len = account_policy_temp;
2097
2098                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2099                         pass_hist = account_policy_temp;
2100
2101                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2102                         flag = account_policy_temp;
2103
2104                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2105                         u_expire = account_policy_temp;
2106
2107                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2108                         u_min_age = account_policy_temp;
2109                         
2110                         unix_to_nt_time_abs(&nt_expire, u_expire);
2111                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2112
2113                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
2114                                        flag, nt_expire, nt_min_age);
2115                         break;
2116                 case 0x02:
2117                         become_root();          
2118                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2119                         unbecome_root();
2120                         if (!NT_STATUS_IS_OK(r_u->status)) {
2121                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2122                                 return r_u->status;
2123                         }
2124                         num_users=info->disp_info.num_user_account;
2125                         free_samr_db(info);
2126                         
2127                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2128                         if (!NT_STATUS_IS_OK(r_u->status)) {
2129                                 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2130                                 return r_u->status;
2131                         }
2132                         num_groups=info->disp_info.num_group_account;
2133                         free_samr_db(info);
2134
2135                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2136                         u_logout = account_policy_temp;
2137
2138                         unix_to_nt_time_abs(&nt_logout, u_logout);
2139
2140                         server_role = ROLE_DOMAIN_PDC;
2141                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2142                                 server_role = ROLE_DOMAIN_BDC;
2143
2144                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2145                         init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL), 
2146                                        num_users, num_groups, num_aliases, nt_logout, server_role);
2147                         break;
2148                 case 0x03:
2149                         account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2150                         unix_to_nt_time_abs(&nt_logout, u_logout);
2151                         
2152                         init_unk_info3(&ctr->info.inf3, nt_logout);
2153                         break;
2154                 case 0x05:
2155                         init_unk_info5(&ctr->info.inf5, global_myname());
2156                         break;
2157                 case 0x06:
2158                         init_unk_info6(&ctr->info.inf6);
2159                         break;
2160                 case 0x07:
2161                         server_role = ROLE_DOMAIN_PDC;
2162                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2163                                 server_role = ROLE_DOMAIN_BDC;
2164
2165                         init_unk_info7(&ctr->info.inf7, server_role);
2166                         break;
2167                 case 0x08:
2168                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2169                         break;
2170                 case 0x0c:
2171                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2172                         u_lock_duration = account_policy_temp;
2173                         if (u_lock_duration != -1)
2174                                 u_lock_duration *= 60;
2175
2176                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2177                         u_reset_time = account_policy_temp * 60;
2178
2179                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2180                         lockout = account_policy_temp;
2181
2182                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2183                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2184         
2185                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2186                         break;
2187                 default:
2188                         return NT_STATUS_INVALID_INFO_CLASS;
2189                 }
2190         
2191         init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2192         
2193         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2194         
2195         return r_u->status;
2196 }
2197
2198 /*******************************************************************
2199  _samr_create_user
2200  Create an account, can be either a normal user or a machine.
2201  This funcion will need to be updated for bdc/domain trusts.
2202  ********************************************************************/
2203
2204 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2205 {
2206         SAM_ACCOUNT *sam_pass=NULL;
2207         fstring account;
2208         DOM_SID sid;
2209         pstring add_script;
2210         POLICY_HND dom_pol = q_u->domain_pol;
2211         UNISTR2 user_account = q_u->uni_name;
2212         uint16 acb_info = q_u->acb_info;
2213         POLICY_HND *user_pol = &r_u->user_pol;
2214         struct samr_info *info = NULL;
2215         BOOL ret;
2216         NTSTATUS nt_status;
2217         struct passwd *pw;
2218         uint32 acc_granted;
2219         SEC_DESC *psd;
2220         size_t    sd_size;
2221         uint32 new_rid = 0;
2222         /* check this, when giving away 'add computer to domain' privs */
2223         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2224         BOOL can_add_account;
2225         SE_PRIV se_rights;
2226
2227         /* Get the domain SID stored in the domain policy */
2228         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2229                 return NT_STATUS_INVALID_HANDLE;
2230
2231         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2232                 return nt_status;
2233         }
2234
2235         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { 
2236                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if 
2237                    this parameter is not an account type */
2238                 return NT_STATUS_INVALID_PARAMETER;
2239         }
2240
2241         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2242         strlower_m(account);
2243                 
2244         pdb_init_sam(&sam_pass);
2245
2246         become_root();
2247         ret = pdb_getsampwnam(sam_pass, account);
2248         unbecome_root();
2249         if (ret == True) {
2250                 /* this account exists: say so */
2251                 pdb_free_sam(&sam_pass);
2252                 return NT_STATUS_USER_EXISTS;
2253         }
2254
2255         pdb_free_sam(&sam_pass);
2256         
2257         /*********************************************************************
2258          * HEADS UP!  If we have to create a new user account, we have to get 
2259          * a new RID from somewhere.  This used to be done by the passdb 
2260          * backend. It has been moved into idmap now.  Since idmap is now 
2261          * wrapped up behind winbind, this means you have to run winbindd if you
2262          * want new accounts to get a new RID when "enable rid algorithm = no".
2263          * Tough.  We now have a uniform way of allocating RIDs regardless
2264          * of what ever passdb backend people may use.
2265          *                                             --jerry (2003-07-10)
2266          *********************************************************************/
2267         
2268         pw = Get_Pwnam(account);
2269
2270         /* determine which user right we need to check based on the acb_info */
2271         
2272         if ( acb_info & ACB_WSTRUST )
2273         {
2274                 pstrcpy(add_script, lp_addmachine_script());
2275                 se_priv_copy( &se_rights, &se_machine_account );
2276                 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2277         } 
2278         else if ( acb_info & ACB_NORMAL )
2279         {
2280                 pstrcpy(add_script, lp_adduser_script());
2281                 se_priv_copy( &se_rights, &se_add_users );
2282                 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2283         } 
2284         else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) 
2285         {
2286                 pstrcpy(add_script, lp_addmachine_script());
2287                 if ( lp_enable_privileges() ) {
2288                         /* only Domain Admins can add a BDC or domain trust */
2289                         se_priv_copy( &se_rights, &se_priv_none );
2290                         can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2291                 }
2292         }
2293         
2294         DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2295                 p->pipe_user_name, can_add_account ? "True":"False" ));
2296                 
2297         /********** BEGIN Admin BLOCK **********/
2298         
2299         if ( can_add_account )
2300                 become_root();
2301                                 
2302         if ( !pw ) {
2303                 if (*add_script) {
2304                         int add_ret;
2305                         
2306                         all_string_sub(add_script, "%u", account, sizeof(add_script));
2307                         add_ret = smbrun(add_script,NULL);
2308                         DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2309                 }
2310                 else    /* no add user script -- ask winbindd to do it */
2311                 {
2312                         if ( !winbind_create_user( account, &new_rid ) ) {
2313                                 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n", 
2314                                         account));
2315                         }
2316                 }
2317                 
2318         }
2319         
2320         /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
2321
2322         nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2323
2324         /* this code is order such that we have no unnecessary retuns 
2325            out of the admin block of code */    
2326            
2327         if ( NT_STATUS_IS_OK(nt_status) ) {
2328                 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2329         
2330                 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2331                         pdb_free_sam(&sam_pass);
2332                         DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2333                                 account));
2334                         nt_status = NT_STATUS_ACCESS_DENIED;
2335                 }
2336         }
2337                 
2338         if ( can_add_account )
2339                 unbecome_root();
2340
2341         /********** END Admin BLOCK **********/
2342         
2343         /* now check for failure */
2344         
2345         if ( !NT_STATUS_IS_OK(nt_status) )
2346                 return nt_status;
2347                         
2348         /* Get the user's SID */
2349         
2350         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2351         
2352         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2353         se_map_generic(&des_access, &usr_generic_mapping);
2354         
2355         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2356                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
2357                 &acc_granted, "_samr_create_user");
2358                 
2359         if ( !NT_STATUS_IS_OK(nt_status) ) {
2360                 return nt_status;
2361         }
2362
2363         /* associate the user's SID with the new handle. */
2364         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2365                 pdb_free_sam(&sam_pass);
2366                 return NT_STATUS_NO_MEMORY;
2367         }
2368
2369         ZERO_STRUCTP(info);
2370         info->sid = sid;
2371         info->acc_granted = acc_granted;
2372
2373         /* get a (unique) handle.  open a policy on it. */
2374         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2375                 pdb_free_sam(&sam_pass);
2376                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2377         }
2378
2379         r_u->user_rid=pdb_get_user_rid(sam_pass);
2380
2381         r_u->access_granted = acc_granted;
2382
2383         pdb_free_sam(&sam_pass);
2384
2385         return NT_STATUS_OK;
2386 }
2387
2388 /*******************************************************************
2389  samr_reply_connect_anon
2390  ********************************************************************/
2391
2392 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2393 {
2394         struct samr_info *info = NULL;
2395         uint32    des_access = q_u->access_mask;
2396
2397         /* Access check */
2398
2399         if (!pipe_access_check(p)) {
2400                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2401                 r_u->status = NT_STATUS_ACCESS_DENIED;
2402                 return r_u->status;
2403         }
2404
2405         /* set up the SAMR connect_anon response */
2406
2407         r_u->status = NT_STATUS_OK;
2408
2409         /* associate the user's SID with the new handle. */
2410         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2411                 return NT_STATUS_NO_MEMORY;
2412
2413         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
2414            was observed from a win98 client trying to enumerate users (when configured  
2415            user level access control on shares)   --jerry */
2416            
2417         se_map_generic( &des_access, &sam_generic_mapping );
2418         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2419         
2420         info->status = q_u->unknown_0;
2421
2422         /* get a (unique) handle.  open a policy on it. */
2423         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2424                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2425
2426         return r_u->status;
2427 }
2428
2429 /*******************************************************************
2430  samr_reply_connect
2431  ********************************************************************/
2432
2433 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2434 {
2435         struct samr_info *info = NULL;
2436         SEC_DESC *psd = NULL;
2437         uint32    acc_granted;
2438         uint32    des_access = q_u->access_mask;
2439         NTSTATUS  nt_status;
2440         size_t sd_size;
2441
2442
2443         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2444
2445         /* Access check */
2446
2447         if (!pipe_access_check(p)) {
2448                 DEBUG(3, ("access denied to samr_connect\n"));
2449                 r_u->status = NT_STATUS_ACCESS_DENIED;
2450                 return r_u->status;
2451         }
2452
2453         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2454         se_map_generic(&des_access, &sam_generic_mapping);
2455         
2456         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2457                 NULL, 0, des_access, &acc_granted, "_samr_connect");
2458         
2459         if ( !NT_STATUS_IS_OK(nt_status) ) 
2460                 return nt_status;
2461
2462         r_u->status = NT_STATUS_OK;
2463
2464         /* associate the user's SID and access granted with the new handle. */
2465         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2466                 return NT_STATUS_NO_MEMORY;
2467
2468         info->acc_granted = acc_granted;
2469         info->status = q_u->access_mask;
2470
2471         /* get a (unique) handle.  open a policy on it. */
2472         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2473                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2474
2475         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2476
2477         return r_u->status;
2478 }
2479
2480 /*******************************************************************
2481  samr_connect4
2482  ********************************************************************/
2483
2484 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2485 {
2486         struct samr_info *info = NULL;
2487         SEC_DESC *psd = NULL;
2488         uint32    acc_granted;
2489         uint32    des_access = q_u->access_mask;
2490         NTSTATUS  nt_status;
2491         size_t sd_size;
2492
2493
2494         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2495
2496         /* Access check */
2497
2498         if (!pipe_access_check(p)) {
2499                 DEBUG(3, ("access denied to samr_connect4\n"));
2500                 r_u->status = NT_STATUS_ACCESS_DENIED;
2501                 return r_u->status;
2502         }
2503
2504         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2505         se_map_generic(&des_access, &sam_generic_mapping);
2506         
2507         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2508                 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2509         
2510         if ( !NT_STATUS_IS_OK(nt_status) ) 
2511                 return nt_status;
2512
2513         r_u->status = NT_STATUS_OK;
2514
2515         /* associate the user's SID and access granted with the new handle. */
2516         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2517                 return NT_STATUS_NO_MEMORY;
2518
2519         info->acc_granted = acc_granted;
2520         info->status = q_u->access_mask;
2521
2522         /* get a (unique) handle.  open a policy on it. */
2523         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2524                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2525
2526         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2527
2528         return r_u->status;
2529 }
2530
2531 /**********************************************************************
2532  api_samr_lookup_domain
2533  **********************************************************************/
2534
2535 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2536 {
2537         struct samr_info *info;
2538         fstring domain_name;
2539         DOM_SID sid;
2540
2541         r_u->status = NT_STATUS_OK;
2542
2543         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2544                 return NT_STATUS_INVALID_HANDLE;
2545
2546         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.  
2547            Reverted that change so we will work with RAS servers again */
2548
2549         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
2550                 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) 
2551         {
2552                 return r_u->status;
2553         }
2554
2555         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2556
2557         ZERO_STRUCT(sid);
2558
2559         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2560                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2561         }
2562
2563         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2564
2565         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2566
2567         return r_u->status;
2568 }
2569
2570 /******************************************************************
2571 makes a SAMR_R_ENUM_DOMAINS structure.
2572 ********************************************************************/
2573
2574 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2575                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2576 {
2577         uint32 i;
2578         SAM_ENTRY *sam;
2579         UNISTR2 *uni_name;
2580
2581         DEBUG(5, ("make_enum_domains\n"));
2582
2583         *pp_sam = NULL;
2584         *pp_uni_name = NULL;
2585
2586         if (num_sam_entries == 0)
2587                 return True;
2588
2589         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2590         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2591
2592         if (sam == NULL || uni_name == NULL)
2593                 return False;
2594
2595         for (i = 0; i < num_sam_entries; i++) {
2596                 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2597                 init_sam_entry(&sam[i], &uni_name[i], 0);
2598         }
2599
2600         *pp_sam = sam;
2601         *pp_uni_name = uni_name;
2602
2603         return True;
2604 }
2605
2606 /**********************************************************************
2607  api_samr_enum_domains
2608  **********************************************************************/
2609
2610 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2611 {
2612         struct samr_info *info;
2613         uint32 num_entries = 2;
2614         fstring dom[2];
2615         const char *name;
2616
2617         r_u->status = NT_STATUS_OK;
2618         
2619         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2620                 return NT_STATUS_INVALID_HANDLE;
2621         
2622         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2623                 return r_u->status;
2624         }
2625
2626         name = get_global_sam_name();
2627
2628         fstrcpy(dom[0],name);
2629         strupper_m(dom[0]);
2630         fstrcpy(dom[1],"Builtin");
2631
2632         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2633                 return NT_STATUS_NO_MEMORY;
2634
2635         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2636
2637         return r_u->status;
2638 }
2639
2640 /*******************************************************************
2641  api_samr_open_alias
2642  ********************************************************************/
2643
2644 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2645 {
2646         DOM_SID sid;
2647         POLICY_HND domain_pol = q_u->dom_pol;
2648         uint32 alias_rid = q_u->rid_alias;
2649         POLICY_HND *alias_pol = &r_u->pol;
2650         struct    samr_info *info = NULL;
2651         SEC_DESC *psd = NULL;
2652         uint32    acc_granted;
2653         uint32    des_access = q_u->access_mask;
2654         size_t    sd_size;
2655         NTSTATUS  status;
2656         SE_PRIV se_rights;
2657
2658         r_u->status = NT_STATUS_OK;
2659
2660         /* find the domain policy and get the SID / access bits stored in the domain policy */
2661         
2662         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2663                 return NT_STATUS_INVALID_HANDLE;
2664         
2665         status = access_check_samr_function(acc_granted, 
2666                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2667                 
2668         if ( !NT_STATUS_IS_OK(status) ) 
2669                 return status;
2670
2671         /* append the alias' RID to it */
2672         
2673         if (!sid_append_rid(&sid, alias_rid))
2674                 return NT_STATUS_NO_SUCH_USER;
2675                 
2676         /*check if access can be granted as requested by client. */
2677         
2678         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2679         se_map_generic(&des_access,&ali_generic_mapping);
2680         
2681         se_priv_add( &se_rights, &se_add_users );
2682         
2683         
2684         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2685                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access, 
2686                 &acc_granted, "_samr_open_alias");
2687                 
2688         if ( !NT_STATUS_IS_OK(status) )
2689                 return status;
2690
2691         /*
2692          * we should check if the rid really exist !!!
2693          * JFM.
2694          */
2695
2696         /* associate the user's SID with the new handle. */
2697         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2698                 return NT_STATUS_NO_MEMORY;
2699                 
2700         info->acc_granted = acc_granted;
2701
2702         /* get a (unique) handle.  open a policy on it. */
2703         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2704                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2705
2706         return r_u->status;
2707 }
2708
2709 /*******************************************************************
2710  set_user_info_10
2711  ********************************************************************/
2712
2713 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2714 {
2715         if (id10 == NULL) {
2716                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2717                 pdb_free_sam(&pwd);
2718                 return False;
2719         }
2720         
2721         /* FIX ME: check if the value is really changed --metze */
2722         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2723                 pdb_free_sam(&pwd);
2724                 return False;
2725         }
2726
2727         if(!pdb_update_sam_account(pwd)) {
2728                 pdb_free_sam(&pwd);
2729                 return False;
2730         }
2731
2732         pdb_free_sam(&pwd);
2733
2734         return True;
2735 }
2736
2737 /*******************************************************************
2738  set_user_info_12
2739  ********************************************************************/
2740
2741 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2742 {
2743
2744         if (id12 == NULL) {
2745                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2746                 pdb_free_sam(&pwd);
2747                 return False;
2748         }
2749  
2750         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2751                 pdb_free_sam(&pwd);
2752                 return False;
2753         }
2754         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2755                 pdb_free_sam(&pwd);
2756                 return False;
2757         }
2758         if (!pdb_set_pass_changed_now (pwd)) {
2759                 pdb_free_sam(&pwd);
2760                 return False; 
2761         }
2762  
2763         if(!pdb_update_sam_account(pwd)) {
2764                 pdb_free_sam(&pwd);
2765                 return False;
2766         }
2767
2768         pdb_free_sam(&pwd);
2769         return True;
2770 }
2771
2772 /*******************************************************************
2773  The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2774  ********************************************************************/
2775 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2776 {
2777         struct group *grp;
2778         gid_t gid;
2779
2780         if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2781                                         &gid))) {
2782                 DEBUG(2,("Could not get gid for primary group of "
2783                          "user %s\n", pdb_get_username(sampass)));
2784                 return False;
2785         }
2786
2787         grp = getgrgid(gid);
2788
2789         if (grp == NULL) {
2790                 DEBUG(2,("Could not find primary group %lu for "
2791                          "user %s\n", (unsigned long)gid, 
2792                          pdb_get_username(sampass)));
2793                 return False;
2794         }
2795
2796         if (smb_set_primary_group(grp->gr_name,
2797                                   pdb_get_username(sampass)) != 0) {
2798                 DEBUG(2,("Could not set primary group for user %s to "
2799                          "%s\n",
2800                          pdb_get_username(sampass), grp->gr_name));
2801                 return False;
2802         }
2803
2804         return True;
2805 }
2806         
2807
2808 /*******************************************************************
2809  set_user_info_20
2810  ********************************************************************/
2811
2812 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2813 {
2814         if (id20 == NULL) {
2815                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2816                 return False;
2817         }
2818  
2819         copy_id20_to_sam_passwd(pwd, id20);
2820
2821         /* write the change out */
2822         if(!pdb_update_sam_account(pwd)) {
2823                 pdb_free_sam(&pwd);
2824                 return False;
2825         }
2826
2827         pdb_free_sam(&pwd);
2828
2829         return True;
2830 }
2831 /*******************************************************************
2832  set_user_info_21
2833  ********************************************************************/
2834
2835 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2836 {
2837  
2838         if (id21 == NULL) {
2839                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2840                 return False;
2841         }
2842  
2843         copy_id21_to_sam_passwd(pwd, id21);
2844  
2845         /*
2846          * The funny part about the previous two calls is
2847          * that pwd still has the password hashes from the
2848          * passdb entry.  These have not been updated from
2849          * id21.  I don't know if they need to be set.    --jerry
2850          */
2851  
2852         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2853                 set_unix_primary_group(pwd);
2854
2855         /* write the change out */
2856         if(!pdb_update_sam_account(pwd)) {
2857                 pdb_free_sam(&pwd);
2858                 return False;
2859         }
2860
2861         pdb_free_sam(&pwd);
2862
2863         return True;
2864 }
2865
2866 /*******************************************************************
2867  set_user_info_23
2868  ********************************************************************/
2869
2870 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2871 {
2872         pstring plaintext_buf;
2873         uint32 len;
2874         uint16 acct_ctrl;
2875  
2876         if (id23 == NULL) {
2877                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2878                 return False;
2879         }
2880  
2881         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2882                   pdb_get_username(pwd)));
2883
2884         acct_ctrl = pdb_get_acct_ctrl(pwd);
2885
2886         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2887                 pdb_free_sam(&pwd);
2888                 return False;
2889         }
2890   
2891         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2892                 pdb_free_sam(&pwd);
2893                 return False;
2894         }
2895  
2896         copy_id23_to_sam_passwd(pwd, id23);
2897  
2898         /* if it's a trust account, don't update /etc/passwd */
2899         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2900                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2901                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2902                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2903         } else  {
2904                 /* update the UNIX password */
2905                 if (lp_unix_password_sync() ) {
2906                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2907                         if (!passwd) {
2908                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2909                         }
2910                         
2911                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2912                                 pdb_free_sam(&pwd);
2913                                 return False;
2914                         }
2915                 }
2916         }
2917  
2918         ZERO_STRUCT(plaintext_buf);
2919  
2920         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2921                 set_unix_primary_group(pwd);
2922
2923         if(!pdb_update_sam_account(pwd)) {
2924                 pdb_free_sam(&pwd);
2925                 return False;
2926         }
2927  
2928         pdb_free_sam(&pwd);
2929
2930         return True;
2931 }
2932
2933 /*******************************************************************
2934  set_user_info_pw
2935  ********************************************************************/
2936
2937 static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
2938 {
2939         uint32 len;
2940         pstring plaintext_buf;
2941         uint16 acct_ctrl;
2942  
2943         DEBUG(5, ("Attempting administrator password change for user %s\n",
2944                   pdb_get_username(pwd)));
2945
2946         acct_ctrl = pdb_get_acct_ctrl(pwd);
2947
2948         ZERO_STRUCT(plaintext_buf);
2949  
2950         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2951                 pdb_free_sam(&pwd);
2952                 return False;
2953         }
2954
2955         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2956                 pdb_free_sam(&pwd);
2957                 return False;
2958         }
2959  
2960         /* if it's a trust account, don't update /etc/passwd */
2961         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2962                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2963                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2964                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2965         } else {
2966                 /* update the UNIX password */
2967                 if (lp_unix_password_sync()) {
2968                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2969                         if (!passwd) {
2970                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2971                         }
2972                         
2973                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2974                                 pdb_free_sam(&pwd);
2975                                 return False;
2976                         }
2977                 }
2978         }
2979  
2980         ZERO_STRUCT(plaintext_buf);
2981  
2982         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2983  
2984         /* update the SAMBA password */
2985         if(!pdb_update_sam_account(pwd)) {
2986                 pdb_free_sam(&pwd);
2987                 return False;
2988         }
2989
2990         pdb_free_sam(&pwd);
2991
2992         return True;
2993 }
2994
2995 /*******************************************************************
2996  samr_reply_set_userinfo
2997  ********************************************************************/
2998
2999 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3000 {
3001         SAM_ACCOUNT *pwd = NULL;
3002         DOM_SID sid;
3003         POLICY_HND *pol = &q_u->pol;
3004         uint16 switch_value = q_u->switch_value;
3005         SAM_USERINFO_CTR *ctr = q_u->ctr;
3006         uint32 acc_granted;
3007         uint32 acc_required;
3008         BOOL ret;
3009         BOOL has_enough_rights;
3010         uint32 acb_info;
3011
3012         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3013
3014         r_u->status = NT_STATUS_OK;
3015
3016         /* find the policy handle.  open a policy on it. */
3017         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3018                 return NT_STATUS_INVALID_HANDLE;
3019
3020         /* observed when joining an XP client to a Samba domain */
3021         
3022         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;     
3023
3024         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3025                 return r_u->status;
3026         }
3027                 
3028         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3029
3030         if (ctr == NULL) {
3031                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3032                 return NT_STATUS_INVALID_INFO_CLASS;
3033         }
3034         
3035         pdb_init_sam(&pwd);     
3036         
3037         become_root();
3038         ret = pdb_getsampwsid(pwd, &sid);
3039         unbecome_root();
3040         
3041         if ( !ret ) {
3042                 pdb_free_sam(&pwd);
3043                 return NT_STATUS_NO_SUCH_USER;
3044         }
3045         
3046         /* deal with machine password changes differently from userinfo changes */
3047         /* check to see if we have the sufficient rights */
3048         
3049         acb_info = pdb_get_acct_ctrl(pwd);
3050         if ( acb_info & ACB_WSTRUST ) 
3051                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3052         else if ( acb_info & ACB_NORMAL )
3053                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3054         else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3055                 if ( lp_enable_privileges() )
3056                         has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3057         }
3058                 
3059         DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3060                 p->pipe_user_name, has_enough_rights ? "" : " not"));
3061
3062         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3063         
3064         if ( has_enough_rights )                                
3065                 become_root(); 
3066         
3067         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3068
3069         switch (switch_value) {
3070                 case 18:
3071                         if (!set_user_info_12(ctr->info.id12, pwd))
3072                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3073                         break;
3074
3075                 case 24:
3076                         if (!p->session_key.length) {
3077                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3078                         }
3079                         SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3080
3081                         dump_data(100, (char *)ctr->info.id24->pass, 516);
3082
3083                         if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
3084                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3085                         break;
3086
3087                 case 25:
3088 #if 0
3089                         /*
3090                          * Currently we don't really know how to unmarshall
3091                          * the level 25 struct, and the password encryption
3092                          * is different. This is a placeholder for when we
3093                          * do understand it. In the meantime just return INVALID
3094                          * info level and W2K SP2 drops down to level 23... JRA.
3095                          */
3096
3097                         if (!p->session_key.length) {
3098                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3099                         }
3100                         SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3101
3102                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3103
3104                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3105                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3106                         break;
3107 #endif
3108                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3109                         break;
3110
3111                 case 23:
3112                         if (!p->session_key.length) {
3113                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3114                         }
3115                         SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3116
3117                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3118
3119                         if (!set_user_info_23(ctr->info.id23, pwd))
3120                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3121                         break;
3122
3123                 default:
3124                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3125         }
3126
3127         
3128         if ( has_enough_rights )                                
3129                 unbecome_root();
3130                 
3131         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3132
3133         return r_u->status;
3134 }
3135
3136 /*******************************************************************
3137  samr_reply_set_userinfo2
3138  ********************************************************************/
3139
3140 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3141 {
3142         SAM_ACCOUNT *pwd = NULL;
3143         DOM_SID sid;
3144         SAM_USERINFO_CTR *ctr = q_u->ctr;
3145         POLICY_HND *pol = &q_u->pol;
3146         uint16 switch_value = q_u->switch_value;
3147         uint32 acc_granted;
3148         uint32 acc_required;
3149         BOOL ret;
3150         BOOL has_enough_rights;
3151         uint32 acb_info;
3152
3153         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3154
3155         r_u->status = NT_STATUS_OK;
3156
3157         /* find the policy handle.  open a policy on it. */
3158         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3159                 return NT_STATUS_INVALID_HANDLE;
3160
3161         /* observed when joining XP client to Samba domain */
3162                 
3163         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3164         
3165         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3166                 return r_u->status;
3167         }
3168
3169         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3170
3171         if (ctr == NULL) {
3172                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3173                 return NT_STATUS_INVALID_INFO_CLASS;
3174         }
3175
3176         switch_value=ctr->switch_value;
3177
3178         pdb_init_sam(&pwd);     
3179         
3180         become_root();
3181         ret = pdb_getsampwsid(pwd, &sid);
3182         unbecome_root();
3183         
3184         if ( !ret ) {
3185                 pdb_free_sam(&pwd);
3186                 return NT_STATUS_NO_SUCH_USER;
3187         }
3188         
3189         acb_info = pdb_get_acct_ctrl(pwd);
3190         if ( acb_info & ACB_WSTRUST ) 
3191                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3192         else if ( acb_info & ACB_NORMAL )
3193                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3194         else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3195                 if ( lp_enable_privileges() )
3196                         has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3197         }
3198                 
3199         DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3200                 p->pipe_user_name, has_enough_rights ? "" : " not"));
3201
3202         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3203         
3204         if ( has_enough_rights )                                
3205                 become_root(); 
3206         
3207         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3208         
3209         switch (switch_value) {
3210                 case 16:
3211                         if (!set_user_info_10(ctr->info.id10, pwd))
3212                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3213                         break;
3214                 case 18:
3215                         /* Used by AS/U JRA. */
3216                         if (!set_user_info_12(ctr->info.id12, pwd))
3217                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3218                         break;
3219                 case 20:
3220                         if (!set_user_info_20(ctr->info.id20, pwd))
3221                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3222                         break;
3223                 case 21:
3224                         if (!set_user_info_21(ctr->info.id21, pwd))
3225                                 return NT_STATUS_ACCESS_DENIED;
3226                         break;
3227                 default:
3228                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3229         }
3230
3231         if ( has_enough_rights )                                
3232                 unbecome_root();
3233                 
3234         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3235
3236         return r_u->status;
3237 }
3238
3239 /*********************************************************************
3240  _samr_query_aliasmem
3241 *********************************************************************/
3242
3243 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3244 {
3245         int num_groups = 0;
3246         uint32 *rids=NULL;
3247         struct samr_info *info = NULL;
3248         int i;
3249                 
3250         NTSTATUS ntstatus1;
3251         NTSTATUS ntstatus2;
3252
3253         DOM_SID *members;
3254         DOM_SID *aliases;
3255         int num_aliases;
3256         BOOL res;
3257
3258         r_u->status = NT_STATUS_OK;
3259
3260         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3261
3262         /* find the policy handle.  open a policy on it. */
3263         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3264                 return NT_STATUS_INVALID_HANDLE;
3265                 
3266         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3267         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3268         
3269         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3270                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3271                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3272                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3273                 }
3274         }               
3275
3276         if (!sid_check_is_domain(&info->sid) &&
3277             !sid_check_is_builtin(&info->sid))
3278                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3279
3280         members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3281
3282         if (members == NULL)
3283                 return NT_STATUS_NO_MEMORY;
3284
3285         for (i=0; i<q_u->num_sids1; i++)
3286                 sid_copy(&members[i], &q_u->sid[i].sid);
3287
3288         become_root();
3289         res = pdb_enum_alias_memberships(members,
3290                                          q_u->num_sids1, &aliases,
3291                                          &num_aliases);
3292         unbecome_root();
3293
3294         if (!res)
3295                 return NT_STATUS_UNSUCCESSFUL;
3296
3297         rids = NULL;
3298         num_groups = 0;
3299
3300         for (i=0; i<num_aliases; i++) {
3301                 uint32 rid;
3302
3303                 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3304                         continue;
3305
3306                 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3307
3308                 if (rids == NULL)
3309                         return NT_STATUS_NO_MEMORY;
3310
3311                 rids[num_groups] = rid;
3312                 num_groups += 1;
3313         }
3314         SAFE_FREE(aliases);
3315
3316         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3317         return NT_STATUS_OK;
3318 }
3319
3320 /*********************************************************************
3321  _samr_query_aliasmem
3322 *********************************************************************/
3323
3324 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3325 {
3326         int i;
3327
3328         int num_sids = 0;
3329         DOM_SID2 *sid;
3330         DOM_SID *sids=NULL;
3331
3332         DOM_SID alias_sid;
3333
3334         uint32 acc_granted;
3335
3336         /* find the policy handle.  open a policy on it. */
3337         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3338                 return NT_STATUS_INVALID_HANDLE;
3339         
3340         if (!NT_STATUS_IS_OK(r_u->status = 
3341                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3342                 return r_u->status;
3343         }
3344
3345         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3346
3347         if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3348                 return NT_STATUS_NO_SUCH_ALIAS;
3349
3350         sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);        
3351         if (num_sids!=0 && sid == NULL) {
3352                 SAFE_FREE(sids);
3353                 return NT_STATUS_NO_MEMORY;
3354         }
3355
3356         for (i = 0; i < num_sids; i++) {
3357                 init_dom_sid2(&sid[i], &sids[i]);
3358         }
3359
3360         init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3361
3362         SAFE_FREE(sids);
3363
3364         return NT_STATUS_OK;
3365 }
3366
3367 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3368 {
3369         int i;
3370
3371         for (i=0; i<*num; i++) {
3372                 if ((*uids)[i] == uid)
3373                         return;
3374         }
3375         
3376         *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3377
3378         if (*uids == NULL)
3379                 return;
3380
3381         (*uids)[*num] = uid;
3382         *num += 1;
3383 }
3384
3385
3386 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3387 {
3388         struct group *grp;
3389         char **gr;
3390         struct sys_pwent *userlist, *user;
3391  
3392         *uids = NULL;
3393         *num = 0;
3394
3395         /* We only look at our own sam, so don't care about imported stuff */
3396
3397         winbind_off();
3398
3399         if ((grp = getgrgid(gid)) == NULL) {
3400                 winbind_on();
3401                 return False;
3402         }
3403
3404         /* Primary group members */
3405
3406         userlist = getpwent_list();
3407
3408         for (user = userlist; user != NULL; user = user->next) {
3409                 if (user->pw_gid != gid)
3410                         continue;
3411                 add_uid_to_array_unique(user->pw_uid, uids, num);
3412         }
3413
3414         pwent_free(userlist);
3415
3416         /* Secondary group members */
3417
3418         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3419                 struct passwd *pw = getpwnam(*gr);
3420
3421                 if (pw == NULL)
3422                         continue;
3423                 add_uid_to_array_unique(pw->pw_uid, uids, num);
3424         }
3425
3426         winbind_on();
3427
3428         return True;
3429 }       
3430
3431 /*********************************************************************
3432  _samr_query_groupmem
3433 *********************************************************************/
3434
3435 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3436 {
3437         int final_num_rids, i;
3438         DOM_SID group_sid;
3439         fstring group_sid_str;
3440         uid_t *uids;
3441         int num;
3442         gid_t gid;
3443
3444         uint32 *rid=NULL;
3445         uint32 *attr=NULL;
3446
3447         uint32 acc_granted;
3448
3449         /* find the policy handle.  open a policy on it. */
3450         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3451                 return NT_STATUS_INVALID_HANDLE;
3452                 
3453         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3454                 return r_u->status;
3455         }
3456                 
3457         sid_to_string(group_sid_str, &group_sid);
3458         DEBUG(10, ("sid is %s\n", group_sid_str));
3459
3460         if (!sid_check_is_in_our_domain(&group_sid)) {
3461                 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3462                 return NT_STATUS_NO_SUCH_GROUP;
3463         }
3464
3465         DEBUG(10, ("lookup on Domain SID\n"));
3466
3467         if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3468                 return NT_STATUS_NO_SUCH_GROUP;
3469
3470         if(!get_memberuids(gid, &uids, &num))
3471                 return NT_STATUS_NO_SUCH_GROUP;
3472
3473         rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3474         attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3475         
3476         if (num!=0 && (rid==NULL || attr==NULL))
3477                 return NT_STATUS_NO_MEMORY;
3478         
3479         final_num_rids = 0;
3480                 
3481         for (i=0; i<num; i++) {
3482                 DOM_SID sid;
3483
3484                 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3485                         DEBUG(1, ("Could not map member uid to SID\n"));
3486                         continue;
3487                 }
3488
3489                 if (!sid_check_is_in_our_domain(&sid)) {
3490                         DEBUG(1, ("Inconsistent SAM -- group member uid not "
3491                                   "in our domain\n"));
3492                         continue;
3493                 }
3494
3495                 sid_peek_rid(&sid, &rid[final_num_rids]);
3496
3497                 /* Hmm. In a trace I got the constant 7 here from NT. */
3498                 attr[final_num_rids] = SID_NAME_USER;
3499
3500                 final_num_rids += 1;
3501         }
3502
3503         SAFE_FREE(uids);
3504
3505         init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3506                                    NT_STATUS_OK);
3507
3508         return NT_STATUS_OK;
3509 }
3510
3511 /*********************************************************************
3512  _samr_add_aliasmem
3513 *********************************************************************/
3514
3515 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3516 {
3517         DOM_SID alias_sid;
3518         uint32 acc_granted;
3519         SE_PRIV se_rights;
3520         BOOL can_add_accounts;
3521         BOOL ret;
3522
3523
3524         /* Find the policy handle. Open a policy on it. */
3525         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3526                 return NT_STATUS_INVALID_HANDLE;
3527         
3528         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3529                 return r_u->status;
3530         }
3531                 
3532         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3533         
3534         se_priv_copy( &se_rights, &se_add_users );
3535         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3536
3537         /******** BEGIN SeAddUsers BLOCK *********/
3538         
3539         if ( can_add_accounts )
3540                 become_root();
3541         
3542         ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3543         
3544         if ( can_add_accounts )
3545                 unbecome_root();
3546                 
3547         /******** END SeAddUsers BLOCK *********/
3548         
3549         return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3550 }
3551
3552 /*********************************************************************
3553  _samr_del_aliasmem
3554 *********************************************************************/
3555
3556 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3557 {
3558         DOM_SID alias_sid;
3559         uint32 acc_granted;
3560         SE_PRIV se_rights;
3561         BOOL can_add_accounts;
3562         BOOL ret;
3563
3564         /* Find the policy handle. Open a policy on it. */
3565         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3566                 return NT_STATUS_INVALID_HANDLE;
3567         
3568         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3569                 return r_u->status;
3570         }
3571         
3572         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3573                    sid_string_static(&alias_sid)));
3574
3575         se_priv_copy( &se_rights, &se_add_users );
3576         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3577
3578         /******** BEGIN SeAddUsers BLOCK *********/
3579         
3580         if ( can_add_accounts )
3581                 become_root();
3582
3583         ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3584         
3585         if ( can_add_accounts )
3586                 unbecome_root();
3587                 
3588         /******** END SeAddUsers BLOCK *********/
3589         
3590         return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3591 }
3592
3593 /*********************************************************************
3594  _samr_add_groupmem
3595 *********************************************************************/
3596
3597 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3598 {
3599         DOM_SID group_sid;
3600         DOM_SID user_sid;
3601         fstring group_sid_str;
3602         uid_t uid;
3603         struct passwd *pwd;
3604         struct group *grp;
3605         fstring grp_name;
3606         GROUP_MAP map;
3607         NTSTATUS ret;
3608         SAM_ACCOUNT *sam_user=NULL;
3609         BOOL check;
3610         uint32 acc_granted;
3611         SE_PRIV se_rights;
3612         BOOL can_add_accounts;
3613
3614         /* Find the policy handle. Open a policy on it. */
3615         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3616                 return NT_STATUS_INVALID_HANDLE;
3617         
3618         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3619                 return r_u->status;
3620         }
3621
3622         sid_to_string(group_sid_str, &group_sid);
3623         DEBUG(10, ("sid is %s\n", group_sid_str));
3624
3625         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3626                 return NT_STATUS_NO_SUCH_GROUP;
3627
3628         DEBUG(10, ("lookup on Domain SID\n"));
3629
3630         if(!get_domain_group_from_sid(group_sid, &map))
3631                 return NT_STATUS_NO_SUCH_GROUP;
3632
3633         sid_copy(&user_sid, get_global_sam_sid());
3634         sid_append_rid(&user_sid, q_u->rid);
3635
3636         ret = pdb_init_sam(&sam_user);
3637         if (!NT_STATUS_IS_OK(ret))
3638                 return ret;
3639         
3640         check = pdb_getsampwsid(sam_user, &user_sid);
3641         
3642         if (check != True) {
3643                 pdb_free_sam(&sam_user);
3644                 return NT_STATUS_NO_SUCH_USER;
3645         }
3646
3647         /* check a real user exist before we run the script to add a user to a group */
3648         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3649                 pdb_free_sam(&sam_user);
3650                 return NT_STATUS_NO_SUCH_USER;
3651         }
3652
3653         pdb_free_sam(&sam_user);
3654
3655         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3656                 return NT_STATUS_NO_SUCH_USER;
3657         }
3658
3659         if ((grp=getgrgid(map.gid)) == NULL) {
3660                 passwd_free(&pwd);
3661                 return NT_STATUS_NO_SUCH_GROUP;
3662         }
3663
3664         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3665         fstrcpy(grp_name, grp->gr_name);
3666
3667         /* if the user is already in the group */
3668         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3669                 passwd_free(&pwd);
3670                 return NT_STATUS_MEMBER_IN_GROUP;
3671         }
3672
3673         se_priv_copy( &se_rights, &se_add_users );
3674         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3675
3676         /******** BEGIN SeAddUsers BLOCK *********/
3677         
3678         if ( can_add_accounts )
3679                 become_root();
3680                 
3681         /* 
3682          * ok, the group exist, the user exist, the user is not in the group,
3683          *
3684          * we can (finally) add it to the group !
3685          */
3686
3687         smb_add_user_group(grp_name, pwd->pw_name);
3688
3689         if ( can_add_accounts )
3690                 unbecome_root();
3691                 
3692         /******** END SeAddUsers BLOCK *********/
3693         
3694         /* check if the user has been added then ... */
3695         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3696                 passwd_free(&pwd);
3697                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3698         }
3699
3700         passwd_free(&pwd);
3701         return NT_STATUS_OK;
3702 }
3703
3704 /*********************************************************************
3705  _samr_del_groupmem
3706 *********************************************************************/
3707
3708 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3709 {
3710         DOM_SID group_sid;
3711         DOM_SID user_sid;
3712         SAM_ACCOUNT *sam_pass=NULL;
3713         GROUP_MAP map;
3714         fstring grp_name;
3715         struct group *grp;
3716         uint32 acc_granted;
3717         SE_PRIV se_rights;
3718         BOOL can_add_accounts;
3719
3720         /*
3721          * delete the group member named q_u->rid
3722          * who is a member of the sid associated with the handle
3723          * the rid is a user's rid as the group is a domain group.
3724          */
3725
3726         /* Find the policy handle. Open a policy on it. */
3727         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3728                 return NT_STATUS_INVALID_HANDLE;
3729         
3730         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3731                 return r_u->status;
3732         }
3733                 
3734         if (!sid_check_is_in_our_domain(&group_sid))
3735                 return NT_STATUS_NO_SUCH_GROUP;
3736
3737         sid_copy(&user_sid, get_global_sam_sid());
3738         sid_append_rid(&user_sid, q_u->rid);
3739
3740         if (!get_domain_group_from_sid(group_sid, &map))
3741                 return NT_STATUS_NO_SUCH_GROUP;
3742
3743         if ((grp=getgrgid(map.gid)) == NULL)
3744                 return NT_STATUS_NO_SUCH_GROUP;
3745
3746         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3747         fstrcpy(grp_name, grp->gr_name);
3748
3749         /* check if the user exists before trying to remove it from the group */
3750         pdb_init_sam(&sam_pass);
3751         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3752                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3753                 pdb_free_sam(&sam_pass);
3754                 return NT_STATUS_NO_SUCH_USER;
3755         }
3756
3757         /* if the user is not in the group */
3758         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3759                 pdb_free_sam(&sam_pass);
3760                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3761         }
3762         
3763
3764         se_priv_copy( &se_rights, &se_add_users );
3765         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3766
3767         /******** BEGIN SeAddUsers BLOCK *********/
3768         
3769         if ( can_add_accounts )
3770                 become_root();
3771                 
3772         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3773
3774         if ( can_add_accounts )
3775                 unbecome_root();
3776                 
3777         /******** END SeAddUsers BLOCK *********/
3778         
3779         /* check if the user has been removed then ... */
3780         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3781                 pdb_free_sam(&sam_pass);
3782                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3783         }
3784         
3785         pdb_free_sam(&sam_pass);
3786         return NT_STATUS_OK;
3787
3788 }
3789
3790 /****************************************************************************
3791  Delete a UNIX user on demand.
3792 ****************************************************************************/
3793
3794 static int smb_delete_user(const char *unix_user)
3795 {
3796         pstring del_script;
3797         int ret;
3798
3799         /* try winbindd first since it is impossible to determine where 
3800            a user came from via NSS.  Try the delete user script if this fails
3801            meaning the user did not exist in winbindd's list of accounts */
3802
3803         if ( winbind_delete_user( unix_user ) ) {
3804                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3805                 return 0;
3806         }
3807
3808
3809         /* fall back to 'delete user script' */
3810
3811         pstrcpy(del_script, lp_deluser_script());
3812         if (! *del_script)
3813                 return -1;
3814         all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3815         ret = smbrun(del_script,NULL);
3816         DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3817
3818         return ret;
3819 }
3820
3821 /*********************************************************************
3822  _samr_delete_dom_user
3823 *********************************************************************/
3824
3825 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3826 {
3827         DOM_SID user_sid;
3828         SAM_ACCOUNT *sam_pass=NULL;
3829         uint32 acc_granted;
3830         SE_PRIV se_rights;
3831         BOOL can_add_accounts;
3832         BOOL ret;
3833
3834         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3835
3836         /* Find the policy handle. Open a policy on it. */
3837         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3838                 return NT_STATUS_INVALID_HANDLE;
3839                 
3840         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3841                 return r_u->status;
3842         }
3843                 
3844         if (!sid_check_is_in_our_domain(&user_sid))
3845                 return NT_STATUS_CANNOT_DELETE;
3846
3847         /* check if the user exists before trying to delete */
3848         pdb_init_sam(&sam_pass);
3849         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3850                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3851                         sid_string_static(&user_sid)));
3852                 pdb_free_sam(&sam_pass);
3853                 return NT_STATUS_NO_SUCH_USER;
3854         }
3855         
3856         se_priv_copy( &se_rights, &se_add_users );
3857         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3858
3859         /******** BEGIN SeAddUsers BLOCK *********/
3860         
3861         if ( can_add_accounts )
3862                 become_root();
3863
3864         /* First delete the samba side....
3865            code is order to prevent unnecessary returns out of the admin 
3866            block of code */
3867            
3868         if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3869                 /*
3870                  * Now delete the unix side ....
3871                  * note: we don't check if the delete really happened
3872                  * as the script is not necessary present
3873                  * and maybe the sysadmin doesn't want to delete the unix side
3874                  */
3875                 smb_delete_user( pdb_get_username(sam_pass) );
3876         }
3877         
3878         if ( can_add_accounts )
3879                 unbecome_root();
3880                 
3881         /******** END SeAddUsers BLOCK *********/
3882                 
3883         if ( !ret ) {
3884                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3885                 pdb_free_sam(&sam_pass);
3886                 return NT_STATUS_CANNOT_DELETE;
3887         }
3888
3889
3890         pdb_free_sam(&sam_pass);
3891
3892         if (!close_policy_hnd(p, &q_u->user_pol))
3893                 return NT_STATUS_OBJECT_NAME_INVALID;
3894
3895         return NT_STATUS_OK;
3896 }
3897
3898 /*********************************************************************
3899  _samr_delete_dom_group
3900 *********************************************************************/
3901
3902 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3903 {
3904         DOM_SID group_sid;
3905         DOM_SID dom_sid;
3906         uint32 group_rid;
3907         fstring group_sid_str;
3908         gid_t gid;
3909         struct group *grp;
3910         GROUP_MAP map;
3911         uint32 acc_granted;
3912         SE_PRIV se_rights;
3913         BOOL can_add_accounts;
3914         BOOL ret;
3915
3916         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3917
3918         /* Find the policy handle. Open a policy on it. */
3919         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3920                 return NT_STATUS_INVALID_HANDLE;
3921                 
3922         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3923                 return r_u->status;
3924         }
3925                 
3926         sid_copy(&dom_sid, &group_sid);
3927         sid_to_string(group_sid_str, &dom_sid);
3928         sid_split_rid(&dom_sid, &group_rid);
3929
3930         DEBUG(10, ("sid is %s\n", group_sid_str));
3931
3932         /* we check if it's our SID before deleting */
3933         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3934                 return NT_STATUS_NO_SUCH_GROUP;
3935
3936         DEBUG(10, ("lookup on Domain SID\n"));
3937
3938         if(!get_domain_group_from_sid(group_sid, &map))
3939                 return NT_STATUS_NO_SUCH_GROUP;
3940
3941         gid=map.gid;
3942
3943         /* check if group really exists */
3944         if ( (grp=getgrgid(gid)) == NULL)
3945                 return NT_STATUS_NO_SUCH_GROUP;
3946
3947         se_priv_copy( &se_rights, &se_add_users );
3948         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3949
3950         /******** BEGIN SeAddUsers BLOCK *********/
3951         
3952         if ( can_add_accounts )
3953                 become_root();
3954
3955         /* delete mapping first */
3956         
3957         if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3958                 smb_delete_group( grp->gr_name );
3959         }
3960
3961         if ( can_add_accounts )
3962                 unbecome_root();
3963                 
3964         /******** END SeAddUsers BLOCK *********/
3965         
3966         if ( !ret ) {
3967                 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n", 
3968                         group_sid_str));
3969                 return NT_STATUS_ACCESS_DENIED;
3970         }
3971         
3972         /* don't check that the unix group has been deleted.  Work like 
3973            _samr_delet_dom_user() */
3974
3975         if (!close_policy_hnd(p, &q_u->group_pol))
3976                 return NT_STATUS_OBJECT_NAME_INVALID;
3977
3978         return NT_STATUS_OK;
3979 }
3980
3981 /*********************************************************************
3982  _samr_delete_dom_alias
3983 *********************************************************************/
3984
3985 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3986 {
3987         DOM_SID alias_sid;
3988         uint32 acc_granted;
3989         SE_PRIV se_rights;
3990         BOOL can_add_accounts;
3991         BOOL ret;
3992
3993         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3994
3995         /* Find the policy handle. Open a policy on it. */
3996         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3997                 return NT_STATUS_INVALID_HANDLE;
3998         
3999         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
4000                 return r_u->status;
4001         }
4002
4003         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
4004
4005         if (!sid_check_is_in_our_domain(&alias_sid))
4006                 return NT_STATUS_NO_SUCH_ALIAS;
4007                 
4008         DEBUG(10, ("lookup on Local SID\n"));
4009
4010         se_priv_copy( &se_rights, &se_add_users );
4011         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4012
4013         /******** BEGIN SeAddUsers BLOCK *********/
4014         
4015         if ( can_add_accounts )
4016                 become_root();
4017
4018         /* Have passdb delete the alias */
4019         ret = pdb_delete_alias(&alias_sid);
4020         
4021         if ( can_add_accounts )
4022                 unbecome_root();
4023                 
4024         /******** END SeAddUsers BLOCK *********/
4025
4026         if ( !ret )
4027                 return NT_STATUS_ACCESS_DENIED;
4028
4029         if (!close_policy_hnd(p, &q_u->alias_pol))
4030                 return NT_STATUS_OBJECT_NAME_INVALID;
4031
4032         return NT_STATUS_OK;
4033 }
4034
4035 /*********************************************************************
4036  _samr_create_dom_group
4037 *********************************************************************/
4038
4039 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4040 {
4041         DOM_SID dom_sid;
4042         DOM_SID info_sid;
4043         fstring name;
4044         fstring sid_string;
4045         struct group *grp;
4046         struct samr_info *info;
4047         uint32 acc_granted;
4048         gid_t gid;
4049         SE_PRIV se_rights;
4050         BOOL can_add_accounts;
4051         NTSTATUS result;
4052
4053         /* Find the policy handle. Open a policy on it. */
4054         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
4055                 return NT_STATUS_INVALID_HANDLE;
4056         
4057         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4058                 return r_u->status;
4059         }
4060                 
4061         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4062                 return NT_STATUS_ACCESS_DENIED;
4063
4064         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4065
4066         /* check if group already exist */
4067         if ((grp=getgrnam(name)) != NULL)
4068                 return NT_STATUS_GROUP_EXISTS;
4069
4070         se_priv_copy( &se_rights, &se_add_users );
4071         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4072
4073         /******** BEGIN SeAddUsers BLOCK *********/
4074         
4075         if ( can_add_accounts )
4076                 become_root();
4077         
4078         /* check that we successfully create the UNIX group */
4079         
4080         result = NT_STATUS_ACCESS_DENIED;
4081         if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4082         
4083                 /* so far, so good */
4084                 
4085                 result = NT_STATUS_OK;
4086                 
4087                 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4088
4089                 /* add the group to the mapping table */
4090                 
4091                 sid_copy( &info_sid, get_global_sam_sid() );
4092                 sid_append_rid( &info_sid, r_u->rid );
4093                 sid_to_string( sid_string, &info_sid );
4094                 
4095                 /* reset the error code if we fail to add the mapping entry */
4096                 
4097                 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4098                         result = NT_STATUS_ACCESS_DENIED;
4099         }
4100
4101         if ( can_add_accounts )
4102                 unbecome_root();
4103                 
4104         /******** END SeAddUsers BLOCK *********/
4105         
4106         /* check if we should bail out here */
4107         
4108         if ( !NT_STATUS_IS_OK(result) )
4109                 return result;
4110         
4111         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4112                 return NT_STATUS_NO_MEMORY;
4113
4114         /* get a (unique) handle.  open a policy on it. */
4115         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4116                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4117
4118         return NT_STATUS_OK;
4119 }
4120
4121 /*********************************************************************
4122  _samr_create_dom_alias
4123 *********************************************************************/
4124
4125 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4126 {
4127         DOM_SID dom_sid;
4128         DOM_SID info_sid;
4129         fstring name;
4130         struct group *grp;
4131         struct samr_info *info;
4132         uint32 acc_granted;
4133         gid_t gid;
4134         NTSTATUS result;
4135         SE_PRIV se_rights;
4136         BOOL can_add_accounts;
4137
4138         /* Find the policy handle. Open a policy on it. */
4139         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
4140                 return NT_STATUS_INVALID_HANDLE;
4141                 
4142         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4143                 return r_u->status;
4144         }
4145                 
4146         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4147                 return NT_STATUS_ACCESS_DENIED;
4148
4149         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4150
4151         se_priv_copy( &se_rights, &se_add_users );
4152         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4153
4154         /******** BEGIN SeAddUsers BLOCK *********/
4155         
4156         if ( can_add_accounts )
4157                 become_root();
4158
4159         /* Have passdb create the alias */
4160         result = pdb_create_alias(name, &r_u->rid);
4161
4162         if ( can_add_accounts )
4163                 unbecome_root();
4164                 
4165         /******** END SeAddUsers BLOCK *********/
4166
4167         if (!NT_STATUS_IS_OK(result))
4168                 return result;
4169
4170         sid_copy(&info_sid, get_global_sam_sid());
4171         sid_append_rid(&info_sid, r_u->rid);
4172
4173         if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4174                 return NT_STATUS_ACCESS_DENIED;
4175
4176         /* check if the group has been successfully created */
4177         if ((grp=getgrgid(gid)) == NULL)
4178                 return NT_STATUS_ACCESS_DENIED;
4179
4180         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4181                 return NT_STATUS_NO_MEMORY;
4182
4183         /* get a (unique) handle.  open a policy on it. */
4184         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4185                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4186
4187         return NT_STATUS_OK;
4188 }
4189
4190 /*********************************************************************
4191  _samr_query_groupinfo
4192
4193 sends the name/comment pair of a domain group
4194 level 1 send also the number of users of that group
4195 *********************************************************************/
4196
4197 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4198 {
4199         DOM_SID group_sid;
4200         GROUP_MAP map;
4201         DOM_SID *sids=NULL;
4202         uid_t *uids;
4203         int num=0;
4204         GROUP_INFO_CTR *ctr;
4205         uint32 acc_granted;
4206         BOOL ret;
4207
4208         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4209                 return NT_STATUS_INVALID_HANDLE;
4210         
4211         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4212                 return r_u->status;
4213         }
4214                 
4215         become_root();
4216         ret = get_domain_group_from_sid(group_sid, &map);
4217         unbecome_root();
4218         if (!ret)
4219                 return NT_STATUS_INVALID_HANDLE;
4220
4221         ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4222         if (ctr==NULL)
4223                 return NT_STATUS_NO_MEMORY;
4224
4225         switch (q_u->switch_level) {
4226                 case 1:
4227                         ctr->switch_value1 = 1;
4228                         if(!get_memberuids(map.gid, &uids, &num))
4229                                 return NT_STATUS_NO_SUCH_GROUP;
4230                         SAFE_FREE(uids);
4231                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4232                         SAFE_FREE(sids);
4233                         break;
4234                 case 3:
4235                         ctr->switch_value1 = 3;
4236                         init_samr_group_info3(&ctr->group.info3);
4237                         break;
4238                 case 4:
4239                         ctr->switch_value1 = 4;
4240                         init_samr_group_info4(&ctr->group.info4, map.comment);
4241                         break;
4242                 default:
4243                         return NT_STATUS_INVALID_INFO_CLASS;
4244         }
4245
4246         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4247
4248         return NT_STATUS_OK;
4249 }
4250
4251 /*********************************************************************
4252  _samr_set_groupinfo
4253  
4254  update a domain group's comment.
4255 *********************************************************************/
4256
4257 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4258 {
4259         DOM_SID group_sid;
4260         GROUP_MAP map;
4261         GROUP_INFO_CTR *ctr;
4262         uint32 acc_granted;
4263
4264         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4265                 return NT_STATUS_INVALID_HANDLE;
4266         
4267         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4268                 return r_u->status;
4269         }
4270                 
4271         if (!get_domain_group_from_sid(group_sid, &map))
4272                 return NT_STATUS_NO_SUCH_GROUP;
4273         
4274         ctr=q_u->ctr;
4275
4276         switch (ctr->switch_value1) {
4277                 case 1:
4278                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4279                         break;
4280                 case 4:
4281                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4282                         break;
4283                 default:
4284                         return NT_STATUS_INVALID_INFO_CLASS;
4285         }
4286
4287         if(!pdb_update_group_mapping_entry(&map)) {
4288                 return NT_STATUS_NO_SUCH_GROUP;
4289         }
4290
4291         return NT_STATUS_OK;
4292 }
4293
4294 /*********************************************************************
4295  _samr_set_aliasinfo
4296  
4297  update an alias's comment.
4298 *********************************************************************/
4299
4300 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4301 {
4302         DOM_SID group_sid;
4303         struct acct_info info;
4304         ALIAS_INFO_CTR *ctr;
4305         uint32 acc_granted;
4306
4307         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4308                 return NT_STATUS_INVALID_HANDLE;
4309         
4310         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4311                 return r_u->status;
4312         }
4313                 
4314         ctr=&q_u->ctr;
4315
4316         switch (ctr->switch_value1) {
4317                 case 3:
4318                         unistr2_to_ascii(info.acct_desc,
4319                                          &(ctr->alias.info3.uni_acct_desc),
4320                                          sizeof(info.acct_desc)-1);
4321                         break;
4322                 default:
4323                         return NT_STATUS_INVALID_INFO_CLASS;
4324         }
4325
4326         if(!pdb_set_aliasinfo(&group_sid, &info)) {
4327                 return NT_STATUS_ACCESS_DENIED;
4328         }
4329
4330         return NT_STATUS_OK;
4331 }
4332
4333 /*********************************************************************
4334  _samr_get_dom_pwinfo
4335 *********************************************************************/
4336
4337 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4338 {
4339         /* Perform access check.  Since this rpc does not require a
4340            policy handle it will not be caught by the access checks on
4341            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4342
4343         if (!pipe_access_check(p)) {
4344                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4345                 r_u->status = NT_STATUS_ACCESS_DENIED;
4346                 return r_u->status;
4347         }
4348
4349         /* Actually, returning zeros here works quite well :-). */
4350
4351         return NT_STATUS_OK;
4352 }
4353
4354 /*********************************************************************
4355  _samr_open_group
4356 *********************************************************************/
4357
4358 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4359 {
4360         DOM_SID sid;
4361         DOM_SID info_sid;
4362         GROUP_MAP map;
4363         struct samr_info *info;
4364         SEC_DESC         *psd = NULL;
4365         uint32            acc_granted;
4366         uint32            des_access = q_u->access_mask;
4367         size_t            sd_size;
4368         NTSTATUS          status;
4369         fstring sid_string;
4370         BOOL ret;
4371         SE_PRIV se_rights;
4372
4373         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4374                 return NT_STATUS_INVALID_HANDLE;
4375         
4376         status = access_check_samr_function(acc_granted, 
4377                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4378                 
4379         if ( !NT_STATUS_IS_OK(status) )
4380                 return status;
4381                 
4382         /*check if access can be granted as requested by client. */
4383         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4384         se_map_generic(&des_access,&grp_generic_mapping);
4385
4386         se_priv_copy( &se_rights, &se_add_users );
4387
4388         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4389                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access, 
4390                 &acc_granted, "_samr_open_group");
4391                 
4392         if ( !NT_STATUS_IS_OK(status) ) 
4393                 return status;
4394
4395         /* this should not be hard-coded like this */
4396         
4397         if (!sid_equal(&sid, get_global_sam_sid()))
4398                 return NT_STATUS_ACCESS_DENIED;
4399
4400         sid_copy(&info_sid, get_global_sam_sid());
4401         sid_append_rid(&info_sid, q_u->rid_group);
4402         sid_to_string(sid_string, &info_sid);
4403
4404         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4405                 return NT_STATUS_NO_MEMORY;
4406                 
4407         info->acc_granted = acc_granted;
4408
4409         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4410
4411         /* check if that group really exists */
4412         become_root();
4413         ret = get_domain_group_from_sid(info->sid, &map);
4414         unbecome_root();
4415         if (!ret)
4416                 return NT_STATUS_NO_SUCH_GROUP;
4417
4418         /* get a (unique) handle.  open a policy on it. */
4419         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4420                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4421
4422         return NT_STATUS_OK;
4423 }
4424
4425 /*********************************************************************
4426  _samr_remove_sid_foreign_domain
4427 *********************************************************************/
4428
4429 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4430                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4431                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4432 {
4433         DOM_SID                 delete_sid, alias_sid;
4434         SAM_ACCOUNT             *sam_pass=NULL;
4435         uint32                  acc_granted;
4436         GROUP_MAP               map;
4437         BOOL                    is_user = False;
4438         NTSTATUS                result;
4439         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4440         
4441         sid_copy( &delete_sid, &q_u->sid.sid );
4442         
4443         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4444                 sid_string_static(&delete_sid)));
4445                 
4446         /* Find the policy handle. Open a policy on it. */
4447         
4448         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4449                 return NT_STATUS_INVALID_HANDLE;
4450         
4451         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4452                 "_samr_remove_sid_foreign_domain");
4453                 
4454         if (!NT_STATUS_IS_OK(result)) 
4455                 return result;
4456                         
4457         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4458                 sid_string_static(&alias_sid)));
4459                 
4460         /* make sure we can handle this */
4461         
4462         if ( sid_check_is_domain(&alias_sid) )
4463                 type = SID_NAME_DOM_GRP;
4464         else if ( sid_check_is_builtin(&alias_sid) )
4465                 type = SID_NAME_ALIAS;
4466         
4467         if ( type == SID_NAME_UNKNOWN ) {
4468                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4469                 return NT_STATUS_OK;
4470         }
4471
4472         /* check if the user exists before trying to delete */
4473         
4474         pdb_init_sam(&sam_pass);
4475         
4476         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4477                 is_user = True;
4478         } else {
4479                 /* maybe it is a group */
4480                 if( !pdb_getgrsid(&map, delete_sid) ) {
4481                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4482                                 sid_string_static(&delete_sid)));
4483                         result = NT_STATUS_INVALID_SID;
4484                         goto done;
4485                 }
4486         }
4487         
4488         /* we can only delete a user from a group since we don't have 
4489            nested groups anyways.  So in the latter case, just say OK */
4490            
4491         if ( is_user ) {
4492                 GROUP_MAP       *mappings = NULL;
4493                 int             num_groups, i;
4494                 struct group    *grp2;
4495                 
4496                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4497                 
4498                         /* interate over the groups */
4499                         for ( i=0; i<num_groups; i++ ) {
4500
4501                                 grp2 = getgrgid(mappings[i].gid);
4502
4503                                 if ( !grp2 ) {
4504                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4505                                         continue;
4506                                 }
4507                         
4508                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4509                                         continue;
4510                                 
4511                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4512                                 
4513                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4514                                         /* should we fail here ? */
4515                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4516                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4517                                         continue;
4518                                 }
4519                                         
4520                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4521                                         pdb_get_username(sam_pass), grp2->gr_name ));
4522                         }
4523                         
4524                         SAFE_FREE(mappings);
4525                 }
4526         }
4527         
4528         result = NT_STATUS_OK;
4529 done:
4530
4531         pdb_free_sam(&sam_pass);
4532
4533         return result;
4534 }
4535
4536 /*******************************************************************
4537  _samr_unknown_2e
4538  ********************************************************************/
4539
4540 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4541 {
4542         struct samr_info *info = NULL;
4543         SAM_UNK_CTR *ctr;
4544         uint32 min_pass_len,pass_hist,flag;
4545         time_t u_expire, u_min_age;
4546         NTTIME nt_expire, nt_min_age;
4547
4548         time_t u_lock_duration, u_reset_time;
4549         NTTIME nt_lock_duration, nt_reset_time;
4550         uint32 lockout;
4551         
4552         time_t u_logout;
4553         NTTIME nt_logout;
4554
4555         uint32 num_users=0, num_groups=0, num_aliases=0;
4556
4557         uint32 account_policy_temp;
4558         uint32 server_role;
4559
4560         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4561                 return NT_STATUS_NO_MEMORY;
4562
4563         ZERO_STRUCTP(ctr);
4564
4565         r_u->status = NT_STATUS_OK;
4566
4567         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4568
4569         /* find the policy handle.  open a policy on it. */
4570         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4571                 return NT_STATUS_INVALID_HANDLE;
4572
4573         switch (q_u->switch_value) {
4574                 case 0x01:
4575                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4576                         min_pass_len = account_policy_temp;
4577
4578                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4579                         pass_hist = account_policy_temp;
4580
4581                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4582                         flag = account_policy_temp;
4583
4584                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4585                         u_expire = account_policy_temp;
4586
4587                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4588                         u_min_age = account_policy_temp;
4589
4590                         unix_to_nt_time_abs(&nt_expire, u_expire);
4591                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4592
4593                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4594                                        flag, nt_expire, nt_min_age);
4595                         break;
4596                 case 0x02:
4597                         become_root();          
4598                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4599                         unbecome_root();
4600                         if (!NT_STATUS_IS_OK(r_u->status)) {
4601                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4602                                 return r_u->status;
4603                         }
4604                         num_users=info->disp_info.num_user_account;
4605                         free_samr_db(info);
4606                         
4607                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4608                         if (NT_STATUS_IS_ERR(r_u->status)) {
4609                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4610                                 return r_u->status;
4611                         }
4612                         num_groups=info->disp_info.num_group_account;
4613                         free_samr_db(info);
4614
4615                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4616                         u_logout = account_policy_temp;
4617
4618                         unix_to_nt_time_abs(&nt_logout, u_logout);
4619
4620                         server_role = ROLE_DOMAIN_PDC;
4621                         if (lp_server_role() == ROLE_DOMAIN_BDC)
4622                                 server_role = ROLE_DOMAIN_BDC;
4623
4624                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4625                         init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL), 
4626                                        num_users, num_groups, num_aliases, nt_logout, server_role);
4627                         break;
4628                 case 0x03:
4629                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4630                         u_logout = account_policy_temp;
4631
4632                         unix_to_nt_time_abs(&nt_logout, u_logout);
4633                         
4634                         init_unk_info3(&ctr->info.inf3, nt_logout);
4635                         break;
4636                 case 0x05:
4637                         init_unk_info5(&ctr->info.inf5, global_myname());
4638                         break;
4639                 case 0x06:
4640                         init_unk_info6(&ctr->info.inf6);
4641                         break;
4642                 case 0x07:
4643                         server_role = ROLE_DOMAIN_PDC;
4644                         if (lp_server_role() == ROLE_DOMAIN_BDC)
4645                                 server_role = ROLE_DOMAIN_BDC;
4646                         init_unk_info7(&ctr->info.inf7, server_role);
4647                         break;
4648                 case 0x08:
4649                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4650                         break;
4651                 case 0x0c:
4652                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4653                         u_lock_duration = account_policy_temp;
4654                         if (u_lock_duration != -1)
4655                                 u_lock_duration *= 60;
4656
4657                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4658                         u_reset_time = account_policy_temp * 60;
4659
4660                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4661                         lockout = account_policy_temp;
4662         
4663                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4664                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4665         
4666                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4667                         break;
4668                 default:
4669                         return NT_STATUS_INVALID_INFO_CLASS;
4670         }
4671
4672         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4673
4674         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4675
4676         return r_u->status;
4677 }
4678
4679 /*******************************************************************
4680  _samr_
4681  ********************************************************************/
4682
4683 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4684 {
4685         time_t u_expire, u_min_age;
4686         time_t u_logout;
4687         time_t u_lock_duration, u_reset_time;
4688
4689         r_u->status = NT_STATUS_OK;
4690
4691         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4692
4693         /* find the policy handle.  open a policy on it. */
4694         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4695                 return NT_STATUS_INVALID_HANDLE;
4696
4697         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4698
4699         switch (q_u->switch_value) {
4700                 case 0x01:
4701                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4702                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4703                         
4704                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4705                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4706                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4707                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4708                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4709                         break;
4710                 case 0x02:
4711                         break;
4712                 case 0x03:
4713                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4714                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4715                         break;
4716                 case 0x05:
4717                         break;
4718                 case 0x06:
4719                         break;
4720                 case 0x07:
4721                         break;
4722                 case 0x0c:
4723                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4724                         if (u_lock_duration != -1)
4725                                 u_lock_duration /= 60;
4726
4727                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4728                         
4729                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4730                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4731                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4732                         break;
4733                 default:
4734                         return NT_STATUS_INVALID_INFO_CLASS;
4735         }
4736
4737         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4738
4739         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4740
4741         return r_u->status;
4742 }