r6225: get rid of warnings from my compiler about nested externs
[kai/samba.git] / source / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-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_World;
43 extern DOM_SID global_sid_Builtin;
44
45 extern rid_name domain_group_rids[];
46 extern rid_name domain_alias_rids[];
47 extern rid_name builtin_alias_rids[];
48
49
50 typedef struct _disp_info {
51         BOOL user_dbloaded;
52         uint32 num_user_account;
53         SAM_ACCOUNT *disp_user_info;
54         BOOL group_dbloaded;
55         uint32 num_group_account;
56         DOMAIN_GRP *disp_group_info;
57 } DISP_INFO;
58
59 struct samr_info {
60         /* for use by the \PIPE\samr policy */
61         DOM_SID sid;
62         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
63         uint32 acc_granted;
64         uint16 acb_mask;
65         BOOL only_machines;
66         DISP_INFO disp_info;
67
68         TALLOC_CTX *mem_ctx;
69 };
70
71 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
72 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
73 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
74 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
75 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
76
77 /*******************************************************************
78 *******************************************************************/
79
80 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
81                                      struct generic_mapping *map,
82                                      DOM_SID *sid, uint32 sid_access )
83 {
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,
1468                                   const char **names, UNIHDR **pp_hdr_name,
1469                                   UNISTR2 **pp_uni_name)
1470 {
1471         uint32 i;
1472         UNIHDR *hdr_name=NULL;
1473         UNISTR2 *uni_name=NULL;
1474
1475         *pp_uni_name = NULL;
1476         *pp_hdr_name = NULL;
1477
1478         if (num_names != 0) {
1479                 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1480                 if (hdr_name == NULL)
1481                         return False;
1482
1483                 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1484                 if (uni_name == NULL)
1485                         return False;
1486         }
1487
1488         for (i = 0; i < num_names; i++) {
1489                 DEBUG(10, ("names[%d]:%s\n", i, *names[i] ? names[i] : ""));
1490                 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1491                 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1492         }
1493
1494         *pp_uni_name = uni_name;
1495         *pp_hdr_name = hdr_name;
1496
1497         return True;
1498 }
1499
1500 /*******************************************************************
1501  _samr_lookup_rids
1502  ********************************************************************/
1503
1504 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1505 {
1506         const char **names;
1507         uint32 *attrs = NULL;
1508         UNIHDR *hdr_name = NULL;
1509         UNISTR2 *uni_name = NULL;
1510         DOM_SID pol_sid;
1511         int num_rids = q_u->num_rids1;
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 > 1000) {
1523                 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1524                           "to samba4 idl this is not possible\n", num_rids));
1525                 return NT_STATUS_UNSUCCESSFUL;
1526         }
1527
1528         names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
1529         attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
1530
1531         if ((num_rids != 0) && ((names == NULL) || (attrs == NULL)))
1532                 return NT_STATUS_NO_MEMORY;
1533
1534         if (!sid_equal(&pol_sid, get_global_sam_sid())) {
1535                 /* TODO: Sooner or later we need to look up BUILTIN rids as
1536                  * well. -- vl */
1537                 goto done;
1538         }
1539
1540         become_root();  /* lookup_sid can require root privs */
1541         r_u->status = pdb_lookup_rids(p->mem_ctx, &pol_sid, num_rids, q_u->rid,
1542                                       &names, &attrs);
1543         unbecome_root();
1544
1545  done:
1546
1547         if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
1548                                   &hdr_name, &uni_name))
1549                 return NT_STATUS_NO_MEMORY;
1550
1551         init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, attrs);
1552
1553         DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1554
1555         return r_u->status;
1556 }
1557
1558 /*******************************************************************
1559  _samr_open_user. Safe - gives out no passwd info.
1560  ********************************************************************/
1561
1562 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1563 {
1564         SAM_ACCOUNT *sampass=NULL;
1565         DOM_SID sid;
1566         POLICY_HND domain_pol = q_u->domain_pol;
1567         POLICY_HND *user_pol = &r_u->user_pol;
1568         struct samr_info *info = NULL;
1569         SEC_DESC *psd = NULL;
1570         uint32    acc_granted;
1571         uint32    des_access = q_u->access_mask;
1572         size_t    sd_size;
1573         BOOL ret;
1574         NTSTATUS nt_status;
1575         SE_PRIV se_rights;
1576
1577         r_u->status = NT_STATUS_OK;
1578
1579         /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1580         
1581         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
1582                 return NT_STATUS_INVALID_HANDLE;
1583         
1584         nt_status = access_check_samr_function( acc_granted, 
1585                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1586                 
1587         if ( !NT_STATUS_IS_OK(nt_status) )
1588                 return nt_status;
1589
1590         nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1591         
1592         if (!NT_STATUS_IS_OK(nt_status))
1593                 return nt_status;
1594
1595         /* append the user's RID to it */
1596         
1597         if (!sid_append_rid(&sid, q_u->user_rid))
1598                 return NT_STATUS_NO_SUCH_USER;
1599         
1600         /* check if access can be granted as requested by client. */
1601         
1602         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1603         se_map_generic(&des_access, &usr_generic_mapping);
1604         
1605         se_priv_copy( &se_rights, &se_machine_account );
1606         se_priv_add( &se_rights, &se_add_users );
1607         
1608         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
1609                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
1610                 &acc_granted, "_samr_open_user");
1611                 
1612         if ( !NT_STATUS_IS_OK(nt_status) )
1613                 return nt_status;
1614
1615         become_root();
1616         ret=pdb_getsampwsid(sampass, &sid);
1617         unbecome_root();
1618
1619         /* check that the SID exists in our domain. */
1620         if (ret == False) {
1621                 return NT_STATUS_NO_SUCH_USER;
1622         }
1623
1624         pdb_free_sam(&sampass);
1625
1626         /* associate the user's SID and access bits with the new handle. */
1627         if ((info = get_samr_info_by_sid(&sid)) == NULL)
1628                 return NT_STATUS_NO_MEMORY;
1629         info->acc_granted = acc_granted;
1630
1631         /* get a (unique) handle.  open a policy on it. */
1632         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1633                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1634
1635         return r_u->status;
1636 }
1637
1638 /*************************************************************************
1639  get_user_info_7. Safe. Only gives out account_name.
1640  *************************************************************************/
1641
1642 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1643 {
1644         SAM_ACCOUNT *smbpass=NULL;
1645         BOOL ret;
1646         NTSTATUS nt_status;
1647
1648         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1649         
1650         if (!NT_STATUS_IS_OK(nt_status)) {
1651                 return nt_status;
1652         }
1653
1654         become_root();
1655         ret = pdb_getsampwsid(smbpass, user_sid);
1656         unbecome_root();
1657
1658         if (ret==False) {
1659                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1660                 return NT_STATUS_NO_SUCH_USER;
1661         }
1662
1663         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1664
1665         ZERO_STRUCTP(id7);
1666         init_sam_user_info7(id7, pdb_get_username(smbpass) );
1667
1668         pdb_free_sam(&smbpass);
1669
1670         return NT_STATUS_OK;
1671 }
1672 /*************************************************************************
1673  get_user_info_10. Safe. Only gives out acb bits.
1674  *************************************************************************/
1675
1676 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1677 {
1678         SAM_ACCOUNT *smbpass=NULL;
1679         BOOL ret;
1680         NTSTATUS nt_status;
1681
1682         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1683         
1684         if (!NT_STATUS_IS_OK(nt_status)) {
1685                 return nt_status;
1686         }
1687
1688         become_root();
1689         ret = pdb_getsampwsid(smbpass, user_sid);
1690         unbecome_root();
1691
1692         if (ret==False) {
1693                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1694                 return NT_STATUS_NO_SUCH_USER;
1695         }
1696
1697         DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1698
1699         ZERO_STRUCTP(id10);
1700         init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1701
1702         pdb_free_sam(&smbpass);
1703
1704         return NT_STATUS_OK;
1705 }
1706
1707 /*************************************************************************
1708  get_user_info_12. OK - this is the killer as it gives out password info.
1709  Ensure that this is only allowed on an encrypted connection with a root
1710  user. JRA. 
1711  *************************************************************************/
1712
1713 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1714 {
1715         SAM_ACCOUNT *smbpass=NULL;
1716         BOOL ret;
1717         NTSTATUS nt_status;
1718
1719         if (!p->ntlmssp_auth_validated)
1720                 return NT_STATUS_ACCESS_DENIED;
1721
1722         if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1723                 return NT_STATUS_ACCESS_DENIED;
1724
1725         /*
1726          * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1727          */
1728
1729         nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1730         
1731         if (!NT_STATUS_IS_OK(nt_status)) {
1732                 return nt_status;
1733         }
1734
1735         ret = pdb_getsampwsid(smbpass, user_sid);
1736
1737         if (ret == False) {
1738                 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1739                 pdb_free_sam(&smbpass);
1740                 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1741         }
1742
1743         DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1744
1745         if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1746                 pdb_free_sam(&smbpass);
1747                 return NT_STATUS_ACCOUNT_DISABLED;
1748         }
1749
1750         ZERO_STRUCTP(id12);
1751         init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1752         
1753         pdb_free_sam(&smbpass);
1754
1755         return NT_STATUS_OK;
1756 }
1757
1758 /*************************************************************************
1759  get_user_info_20
1760  *************************************************************************/
1761
1762 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1763 {
1764         SAM_ACCOUNT *sampass=NULL;
1765         BOOL ret;
1766
1767         pdb_init_sam_talloc(mem_ctx, &sampass);
1768
1769         become_root();
1770         ret = pdb_getsampwsid(sampass, user_sid);
1771         unbecome_root();
1772
1773         if (ret == False) {
1774                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1775                 return NT_STATUS_NO_SUCH_USER;
1776         }
1777
1778         samr_clear_sam_passwd(sampass);
1779
1780         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1781
1782         ZERO_STRUCTP(id20);
1783         init_sam_user_info20A(id20, sampass);
1784         
1785         pdb_free_sam(&sampass);
1786
1787         return NT_STATUS_OK;
1788 }
1789
1790 /*************************************************************************
1791  get_user_info_21
1792  *************************************************************************/
1793
1794 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21, 
1795                                  DOM_SID *user_sid, DOM_SID *domain_sid)
1796 {
1797         SAM_ACCOUNT *sampass=NULL;
1798         BOOL ret;
1799         NTSTATUS nt_status;
1800
1801         nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1802         if (!NT_STATUS_IS_OK(nt_status)) {
1803                 return nt_status;
1804         }
1805
1806         become_root();
1807         ret = pdb_getsampwsid(sampass, user_sid);
1808         unbecome_root();
1809
1810         if (ret == False) {
1811                 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1812                 return NT_STATUS_NO_SUCH_USER;
1813         }
1814
1815         samr_clear_sam_passwd(sampass);
1816
1817         DEBUG(3,("User:[%s]\n",  pdb_get_username(sampass) ));
1818
1819         ZERO_STRUCTP(id21);
1820         nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1821         
1822         pdb_free_sam(&sampass);
1823
1824         return NT_STATUS_OK;
1825 }
1826
1827 /*******************************************************************
1828  _samr_query_userinfo
1829  ********************************************************************/
1830
1831 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1832 {
1833         SAM_USERINFO_CTR *ctr;
1834         struct samr_info *info = NULL;
1835         DOM_SID domain_sid;
1836         uint32 rid;
1837         
1838         r_u->status=NT_STATUS_OK;
1839
1840         /* search for the handle */
1841         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1842                 return NT_STATUS_INVALID_HANDLE;
1843
1844         domain_sid = info->sid;
1845
1846         sid_split_rid(&domain_sid, &rid);
1847
1848         if (!sid_check_is_in_our_domain(&info->sid))
1849                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1850
1851         DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1852
1853         ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1854         if (!ctr)
1855                 return NT_STATUS_NO_MEMORY;
1856
1857         ZERO_STRUCTP(ctr);
1858
1859         /* ok!  user info levels (lots: see MSDEV help), off we go... */
1860         ctr->switch_value = q_u->switch_value;
1861
1862         switch (q_u->switch_value) {
1863         case 0x07:
1864                 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
1865                 if (ctr->info.id7 == NULL)
1866                         return NT_STATUS_NO_MEMORY;
1867
1868                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
1869                         return r_u->status;
1870                 break;
1871         case 0x10:
1872                 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1873                 if (ctr->info.id10 == NULL)
1874                         return NT_STATUS_NO_MEMORY;
1875
1876                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1877                         return r_u->status;
1878                 break;
1879
1880 #if 0
1881 /* whoops - got this wrong.  i think.  or don't understand what's happening. */
1882         case 0x11:
1883         {
1884             NTTIME expire;
1885             info = (void *)&id11;
1886
1887             expire.low = 0xffffffff;
1888             expire.high = 0x7fffffff;
1889
1890             ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1891             ZERO_STRUCTP(ctr->info.id11);
1892             init_sam_user_info11(ctr->info.id11, &expire,
1893                          "BROOKFIELDS$",    /* name */
1894                          0x03ef,    /* user rid */
1895                          0x201, /* group rid */
1896                          0x0080);   /* acb info */
1897
1898             break;
1899         }
1900 #endif
1901
1902         case 0x12:
1903                 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1904                 if (ctr->info.id12 == NULL)
1905                         return NT_STATUS_NO_MEMORY;
1906
1907                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1908                         return r_u->status;
1909                 break;
1910                 
1911         case 20:
1912                 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1913                 if (ctr->info.id20 == NULL)
1914                         return NT_STATUS_NO_MEMORY;
1915                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1916                         return r_u->status;
1917                 break;
1918
1919         case 21:
1920                 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1921                 if (ctr->info.id21 == NULL)
1922                         return NT_STATUS_NO_MEMORY;
1923                 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21, 
1924                                                                     &info->sid, &domain_sid)))
1925                         return r_u->status;
1926                 break;
1927
1928         default:
1929                 return NT_STATUS_INVALID_INFO_CLASS;
1930         }
1931
1932         init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1933
1934         DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1935         
1936         return r_u->status;
1937 }
1938
1939 /*******************************************************************
1940  samr_reply_query_usergroups
1941  ********************************************************************/
1942
1943 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1944 {
1945         SAM_ACCOUNT *sam_pass=NULL;
1946         struct passwd *passwd;
1947         DOM_SID  sid;
1948         DOM_SID *sids;
1949         DOM_GID *gids = NULL;
1950         int num_groups = 0;
1951         gid_t *unix_gids;
1952         int i, num_gids;
1953         uint32 acc_granted;
1954         BOOL ret;
1955         NTSTATUS result;
1956
1957         /*
1958          * from the SID in the request:
1959          * we should send back the list of DOMAIN GROUPS
1960          * the user is a member of
1961          *
1962          * and only the DOMAIN GROUPS
1963          * no ALIASES !!! neither aliases of the domain
1964          * nor aliases of the builtin SID
1965          *
1966          * JFM, 12/2/2001
1967          */
1968
1969         r_u->status = NT_STATUS_OK;
1970
1971         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1972
1973         /* find the policy handle.  open a policy on it. */
1974         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1975                 return NT_STATUS_INVALID_HANDLE;
1976         
1977         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1978                 return r_u->status;
1979         }
1980
1981         if (!sid_check_is_in_our_domain(&sid))
1982                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1983
1984         pdb_init_sam(&sam_pass);
1985         
1986         become_root();
1987         ret = pdb_getsampwsid(sam_pass, &sid);
1988         unbecome_root();
1989
1990         if (ret == False) {
1991                 pdb_free_sam(&sam_pass);
1992                 return NT_STATUS_NO_SUCH_USER;
1993         }
1994
1995         passwd = getpwnam_alloc(pdb_get_username(sam_pass));
1996         if (passwd == NULL) {
1997                 pdb_free_sam(&sam_pass);
1998                 return NT_STATUS_NO_SUCH_USER;
1999         }
2000
2001         sids = NULL;
2002
2003         become_root();
2004         result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2005                                             passwd->pw_gid,
2006                                             &sids, &unix_gids, &num_groups);
2007         unbecome_root();
2008
2009         pdb_free_sam(&sam_pass);
2010         passwd_free(&passwd);
2011
2012         if (!NT_STATUS_IS_OK(result))
2013                 return result;
2014
2015         SAFE_FREE(unix_gids);
2016
2017         gids = NULL;
2018         num_gids = 0;
2019
2020         for (i=0; i<num_groups; i++) {
2021                 uint32 rid;
2022
2023                 if (!sid_peek_check_rid(get_global_sam_sid(),
2024                                         &(sids[i]), &rid))
2025                         continue;
2026
2027                 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2028                 gids[num_gids].attr=7;
2029                 gids[num_gids].g_rid = rid;
2030                 num_gids += 1;
2031         }
2032         SAFE_FREE(sids);
2033         
2034         /* construct the response.  lkclXXXX: gids are not copied! */
2035         init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2036         
2037         DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2038         
2039         return r_u->status;
2040 }
2041
2042 /*******************************************************************
2043  _samr_query_dom_info
2044  ********************************************************************/
2045
2046 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2047 {
2048         struct samr_info *info = NULL;
2049         SAM_UNK_CTR *ctr;
2050         uint32 min_pass_len,pass_hist,flag;
2051         time_t u_expire, u_min_age;
2052         NTTIME nt_expire, nt_min_age;
2053
2054         time_t u_lock_duration, u_reset_time;
2055         NTTIME nt_lock_duration, nt_reset_time;
2056         uint32 lockout;
2057         
2058         time_t u_logout;
2059         NTTIME nt_logout;
2060
2061         uint32 account_policy_temp;
2062         uint32 server_role;
2063
2064         uint32 num_users=0, num_groups=0, num_aliases=0;
2065
2066         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2067                 return NT_STATUS_NO_MEMORY;
2068
2069         ZERO_STRUCTP(ctr);
2070
2071         r_u->status = NT_STATUS_OK;
2072         
2073         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2074         
2075         /* find the policy handle.  open a policy on it. */
2076         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2077                 return NT_STATUS_INVALID_HANDLE;
2078         
2079         switch (q_u->switch_value) {
2080                 case 0x01:
2081                         
2082                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2083                         min_pass_len = account_policy_temp;
2084
2085                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2086                         pass_hist = account_policy_temp;
2087
2088                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2089                         flag = account_policy_temp;
2090
2091                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2092                         u_expire = account_policy_temp;
2093
2094                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2095                         u_min_age = account_policy_temp;
2096                         
2097                         unix_to_nt_time_abs(&nt_expire, u_expire);
2098                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
2099
2100                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
2101                                        flag, nt_expire, nt_min_age);
2102                         break;
2103                 case 0x02:
2104                         become_root();          
2105                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2106                         unbecome_root();
2107                         if (!NT_STATUS_IS_OK(r_u->status)) {
2108                                 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2109                                 return r_u->status;
2110                         }
2111                         num_users=info->disp_info.num_user_account;
2112                         free_samr_db(info);
2113                         
2114                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2115                         if (!NT_STATUS_IS_OK(r_u->status)) {
2116                                 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2117                                 return r_u->status;
2118                         }
2119                         num_groups=info->disp_info.num_group_account;
2120                         free_samr_db(info);
2121
2122                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2123                         u_logout = account_policy_temp;
2124
2125                         unix_to_nt_time_abs(&nt_logout, u_logout);
2126
2127                         server_role = ROLE_DOMAIN_PDC;
2128                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2129                                 server_role = ROLE_DOMAIN_BDC;
2130
2131                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2132                         init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL), 
2133                                        num_users, num_groups, num_aliases, nt_logout, server_role);
2134                         break;
2135                 case 0x03:
2136                         account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2137                         unix_to_nt_time_abs(&nt_logout, u_logout);
2138                         
2139                         init_unk_info3(&ctr->info.inf3, nt_logout);
2140                         break;
2141                 case 0x05:
2142                         init_unk_info5(&ctr->info.inf5, global_myname());
2143                         break;
2144                 case 0x06:
2145                         init_unk_info6(&ctr->info.inf6);
2146                         break;
2147                 case 0x07:
2148                         server_role = ROLE_DOMAIN_PDC;
2149                         if (lp_server_role() == ROLE_DOMAIN_BDC)
2150                                 server_role = ROLE_DOMAIN_BDC;
2151
2152                         init_unk_info7(&ctr->info.inf7, server_role);
2153                         break;
2154                 case 0x08:
2155                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2156                         break;
2157                 case 0x0c:
2158                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2159                         u_lock_duration = account_policy_temp;
2160                         if (u_lock_duration != -1)
2161                                 u_lock_duration *= 60;
2162
2163                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2164                         u_reset_time = account_policy_temp * 60;
2165
2166                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2167                         lockout = account_policy_temp;
2168
2169                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2170                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2171         
2172                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2173                         break;
2174                 default:
2175                         return NT_STATUS_INVALID_INFO_CLASS;
2176                 }
2177         
2178         init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2179         
2180         DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2181         
2182         return r_u->status;
2183 }
2184
2185 /*******************************************************************
2186  _samr_create_user
2187  Create an account, can be either a normal user or a machine.
2188  This funcion will need to be updated for bdc/domain trusts.
2189  ********************************************************************/
2190
2191 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2192 {
2193         SAM_ACCOUNT *sam_pass=NULL;
2194         fstring account;
2195         DOM_SID sid;
2196         pstring add_script;
2197         POLICY_HND dom_pol = q_u->domain_pol;
2198         UNISTR2 user_account = q_u->uni_name;
2199         uint16 acb_info = q_u->acb_info;
2200         POLICY_HND *user_pol = &r_u->user_pol;
2201         struct samr_info *info = NULL;
2202         BOOL ret;
2203         NTSTATUS nt_status;
2204         struct passwd *pw;
2205         uint32 acc_granted;
2206         SEC_DESC *psd;
2207         size_t    sd_size;
2208         uint32 new_rid = 0;
2209         /* check this, when giving away 'add computer to domain' privs */
2210         uint32    des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2211         BOOL can_add_account = False;
2212         SE_PRIV se_rights;
2213
2214         /* Get the domain SID stored in the domain policy */
2215         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2216                 return NT_STATUS_INVALID_HANDLE;
2217
2218         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2219                 return nt_status;
2220         }
2221
2222         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { 
2223                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if 
2224                    this parameter is not an account type */
2225                 return NT_STATUS_INVALID_PARAMETER;
2226         }
2227
2228         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2229         strlower_m(account);
2230                 
2231         pdb_init_sam(&sam_pass);
2232
2233         become_root();
2234         ret = pdb_getsampwnam(sam_pass, account);
2235         unbecome_root();
2236         if (ret == True) {
2237                 /* this account exists: say so */
2238                 pdb_free_sam(&sam_pass);
2239                 return NT_STATUS_USER_EXISTS;
2240         }
2241
2242         pdb_free_sam(&sam_pass);
2243         
2244         /*********************************************************************
2245          * HEADS UP!  If we have to create a new user account, we have to get 
2246          * a new RID from somewhere.  This used to be done by the passdb 
2247          * backend. It has been moved into idmap now.  Since idmap is now 
2248          * wrapped up behind winbind, this means you have to run winbindd if you
2249          * want new accounts to get a new RID when "enable rid algorithm = no".
2250          * Tough.  We now have a uniform way of allocating RIDs regardless
2251          * of what ever passdb backend people may use.
2252          *                                             --jerry (2003-07-10)
2253          *********************************************************************/
2254         
2255         pw = Get_Pwnam(account);
2256
2257         /* determine which user right we need to check based on the acb_info */
2258         
2259         if ( acb_info & ACB_WSTRUST )
2260         {
2261                 pstrcpy(add_script, lp_addmachine_script());
2262                 se_priv_copy( &se_rights, &se_machine_account );
2263                 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2264         } 
2265         else if ( acb_info & ACB_NORMAL )
2266         {
2267                 pstrcpy(add_script, lp_adduser_script());
2268                 se_priv_copy( &se_rights, &se_add_users );
2269                 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2270         } 
2271         else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) 
2272         {
2273                 pstrcpy(add_script, lp_addmachine_script());
2274                 if ( lp_enable_privileges() ) {
2275                         /* only Domain Admins can add a BDC or domain trust */
2276                         se_priv_copy( &se_rights, &se_priv_none );
2277                         can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2278                 }
2279         }
2280         
2281         DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2282                 p->pipe_user_name, can_add_account ? "True":"False" ));
2283                 
2284         /********** BEGIN Admin BLOCK **********/
2285         
2286         if ( can_add_account )
2287                 become_root();
2288                                 
2289         if ( !pw ) {
2290                 if (*add_script) {
2291                         int add_ret;
2292                         
2293                         all_string_sub(add_script, "%u", account, sizeof(add_script));
2294                         add_ret = smbrun(add_script,NULL);
2295                         DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2296                 }
2297                 else    /* no add user script -- ask winbindd to do it */
2298                 {
2299                         if ( !winbind_create_user( account, &new_rid ) ) {
2300                                 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n", 
2301                                         account));
2302                         }
2303                 }
2304                 
2305         }
2306         
2307         /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
2308
2309         flush_pwnam_cache();
2310         nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2311
2312         /* this code is order such that we have no unnecessary retuns 
2313            out of the admin block of code */    
2314            
2315         if ( NT_STATUS_IS_OK(nt_status) ) {
2316                 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2317         
2318                 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2319                         pdb_free_sam(&sam_pass);
2320                         DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2321                                 account));
2322                         nt_status = NT_STATUS_ACCESS_DENIED;
2323                 }
2324         }
2325                 
2326         if ( can_add_account )
2327                 unbecome_root();
2328
2329         /********** END Admin BLOCK **********/
2330         
2331         /* now check for failure */
2332         
2333         if ( !NT_STATUS_IS_OK(nt_status) )
2334                 return nt_status;
2335                         
2336         /* Get the user's SID */
2337         
2338         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2339         
2340         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2341         se_map_generic(&des_access, &usr_generic_mapping);
2342         
2343         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2344                 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access, 
2345                 &acc_granted, "_samr_create_user");
2346                 
2347         if ( !NT_STATUS_IS_OK(nt_status) ) {
2348                 return nt_status;
2349         }
2350
2351         /* associate the user's SID with the new handle. */
2352         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2353                 pdb_free_sam(&sam_pass);
2354                 return NT_STATUS_NO_MEMORY;
2355         }
2356
2357         ZERO_STRUCTP(info);
2358         info->sid = sid;
2359         info->acc_granted = acc_granted;
2360
2361         /* get a (unique) handle.  open a policy on it. */
2362         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2363                 pdb_free_sam(&sam_pass);
2364                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2365         }
2366
2367         r_u->user_rid=pdb_get_user_rid(sam_pass);
2368
2369         r_u->access_granted = acc_granted;
2370
2371         pdb_free_sam(&sam_pass);
2372
2373         return NT_STATUS_OK;
2374 }
2375
2376 /*******************************************************************
2377  samr_reply_connect_anon
2378  ********************************************************************/
2379
2380 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2381 {
2382         struct samr_info *info = NULL;
2383         uint32    des_access = q_u->access_mask;
2384
2385         /* Access check */
2386
2387         if (!pipe_access_check(p)) {
2388                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2389                 r_u->status = NT_STATUS_ACCESS_DENIED;
2390                 return r_u->status;
2391         }
2392
2393         /* set up the SAMR connect_anon response */
2394
2395         r_u->status = NT_STATUS_OK;
2396
2397         /* associate the user's SID with the new handle. */
2398         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2399                 return NT_STATUS_NO_MEMORY;
2400
2401         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
2402            was observed from a win98 client trying to enumerate users (when configured  
2403            user level access control on shares)   --jerry */
2404            
2405         se_map_generic( &des_access, &sam_generic_mapping );
2406         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2407         
2408         info->status = q_u->unknown_0;
2409
2410         /* get a (unique) handle.  open a policy on it. */
2411         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2412                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2413
2414         return r_u->status;
2415 }
2416
2417 /*******************************************************************
2418  samr_reply_connect
2419  ********************************************************************/
2420
2421 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2422 {
2423         struct samr_info *info = NULL;
2424         SEC_DESC *psd = NULL;
2425         uint32    acc_granted;
2426         uint32    des_access = q_u->access_mask;
2427         NTSTATUS  nt_status;
2428         size_t sd_size;
2429
2430
2431         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2432
2433         /* Access check */
2434
2435         if (!pipe_access_check(p)) {
2436                 DEBUG(3, ("access denied to samr_connect\n"));
2437                 r_u->status = NT_STATUS_ACCESS_DENIED;
2438                 return r_u->status;
2439         }
2440
2441         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2442         se_map_generic(&des_access, &sam_generic_mapping);
2443         
2444         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2445                 NULL, 0, des_access, &acc_granted, "_samr_connect");
2446         
2447         if ( !NT_STATUS_IS_OK(nt_status) ) 
2448                 return nt_status;
2449
2450         r_u->status = NT_STATUS_OK;
2451
2452         /* associate the user's SID and access granted with the new handle. */
2453         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2454                 return NT_STATUS_NO_MEMORY;
2455
2456         info->acc_granted = acc_granted;
2457         info->status = q_u->access_mask;
2458
2459         /* get a (unique) handle.  open a policy on it. */
2460         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2461                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2462
2463         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2464
2465         return r_u->status;
2466 }
2467
2468 /*******************************************************************
2469  samr_connect4
2470  ********************************************************************/
2471
2472 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2473 {
2474         struct samr_info *info = NULL;
2475         SEC_DESC *psd = NULL;
2476         uint32    acc_granted;
2477         uint32    des_access = q_u->access_mask;
2478         NTSTATUS  nt_status;
2479         size_t sd_size;
2480
2481
2482         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2483
2484         /* Access check */
2485
2486         if (!pipe_access_check(p)) {
2487                 DEBUG(3, ("access denied to samr_connect4\n"));
2488                 r_u->status = NT_STATUS_ACCESS_DENIED;
2489                 return r_u->status;
2490         }
2491
2492         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2493         se_map_generic(&des_access, &sam_generic_mapping);
2494         
2495         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2496                 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2497         
2498         if ( !NT_STATUS_IS_OK(nt_status) ) 
2499                 return nt_status;
2500
2501         r_u->status = NT_STATUS_OK;
2502
2503         /* associate the user's SID and access granted with the new handle. */
2504         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2505                 return NT_STATUS_NO_MEMORY;
2506
2507         info->acc_granted = acc_granted;
2508         info->status = q_u->access_mask;
2509
2510         /* get a (unique) handle.  open a policy on it. */
2511         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2512                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2513
2514         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2515
2516         return r_u->status;
2517 }
2518
2519 /**********************************************************************
2520  api_samr_lookup_domain
2521  **********************************************************************/
2522
2523 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2524 {
2525         struct samr_info *info;
2526         fstring domain_name;
2527         DOM_SID sid;
2528
2529         r_u->status = NT_STATUS_OK;
2530
2531         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2532                 return NT_STATUS_INVALID_HANDLE;
2533
2534         /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.  
2535            Reverted that change so we will work with RAS servers again */
2536
2537         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
2538                 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain"))) 
2539         {
2540                 return r_u->status;
2541         }
2542
2543         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2544
2545         ZERO_STRUCT(sid);
2546
2547         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2548                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2549         }
2550
2551         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2552
2553         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2554
2555         return r_u->status;
2556 }
2557
2558 /******************************************************************
2559 makes a SAMR_R_ENUM_DOMAINS structure.
2560 ********************************************************************/
2561
2562 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2563                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2564 {
2565         uint32 i;
2566         SAM_ENTRY *sam;
2567         UNISTR2 *uni_name;
2568
2569         DEBUG(5, ("make_enum_domains\n"));
2570
2571         *pp_sam = NULL;
2572         *pp_uni_name = NULL;
2573
2574         if (num_sam_entries == 0)
2575                 return True;
2576
2577         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2578         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2579
2580         if (sam == NULL || uni_name == NULL)
2581                 return False;
2582
2583         for (i = 0; i < num_sam_entries; i++) {
2584                 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2585                 init_sam_entry(&sam[i], &uni_name[i], 0);
2586         }
2587
2588         *pp_sam = sam;
2589         *pp_uni_name = uni_name;
2590
2591         return True;
2592 }
2593
2594 /**********************************************************************
2595  api_samr_enum_domains
2596  **********************************************************************/
2597
2598 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2599 {
2600         struct samr_info *info;
2601         uint32 num_entries = 2;
2602         fstring dom[2];
2603         const char *name;
2604
2605         r_u->status = NT_STATUS_OK;
2606         
2607         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2608                 return NT_STATUS_INVALID_HANDLE;
2609         
2610         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2611                 return r_u->status;
2612         }
2613
2614         name = get_global_sam_name();
2615
2616         fstrcpy(dom[0],name);
2617         strupper_m(dom[0]);
2618         fstrcpy(dom[1],"Builtin");
2619
2620         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2621                 return NT_STATUS_NO_MEMORY;
2622
2623         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2624
2625         return r_u->status;
2626 }
2627
2628 /*******************************************************************
2629  api_samr_open_alias
2630  ********************************************************************/
2631
2632 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2633 {
2634         DOM_SID sid;
2635         POLICY_HND domain_pol = q_u->dom_pol;
2636         uint32 alias_rid = q_u->rid_alias;
2637         POLICY_HND *alias_pol = &r_u->pol;
2638         struct    samr_info *info = NULL;
2639         SEC_DESC *psd = NULL;
2640         uint32    acc_granted;
2641         uint32    des_access = q_u->access_mask;
2642         size_t    sd_size;
2643         NTSTATUS  status;
2644         SE_PRIV se_rights;
2645
2646         r_u->status = NT_STATUS_OK;
2647
2648         /* find the domain policy and get the SID / access bits stored in the domain policy */
2649         
2650         if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2651                 return NT_STATUS_INVALID_HANDLE;
2652         
2653         status = access_check_samr_function(acc_granted, 
2654                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2655                 
2656         if ( !NT_STATUS_IS_OK(status) ) 
2657                 return status;
2658
2659         /* append the alias' RID to it */
2660         
2661         if (!sid_append_rid(&sid, alias_rid))
2662                 return NT_STATUS_NO_SUCH_USER;
2663                 
2664         /*check if access can be granted as requested by client. */
2665         
2666         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2667         se_map_generic(&des_access,&ali_generic_mapping);
2668         
2669         se_priv_add( &se_rights, &se_add_users );
2670         
2671         
2672         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2673                 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access, 
2674                 &acc_granted, "_samr_open_alias");
2675                 
2676         if ( !NT_STATUS_IS_OK(status) )
2677                 return status;
2678
2679         /*
2680          * we should check if the rid really exist !!!
2681          * JFM.
2682          */
2683
2684         /* associate the user's SID with the new handle. */
2685         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2686                 return NT_STATUS_NO_MEMORY;
2687                 
2688         info->acc_granted = acc_granted;
2689
2690         /* get a (unique) handle.  open a policy on it. */
2691         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2692                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2693
2694         return r_u->status;
2695 }
2696
2697 /*******************************************************************
2698  set_user_info_10
2699  ********************************************************************/
2700
2701 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2702 {
2703         if (id10 == NULL) {
2704                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2705                 pdb_free_sam(&pwd);
2706                 return False;
2707         }
2708         
2709         /* FIX ME: check if the value is really changed --metze */
2710         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2711                 pdb_free_sam(&pwd);
2712                 return False;
2713         }
2714
2715         if(!pdb_update_sam_account(pwd)) {
2716                 pdb_free_sam(&pwd);
2717                 return False;
2718         }
2719
2720         pdb_free_sam(&pwd);
2721
2722         return True;
2723 }
2724
2725 /*******************************************************************
2726  set_user_info_12
2727  ********************************************************************/
2728
2729 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2730 {
2731
2732         if (id12 == NULL) {
2733                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2734                 pdb_free_sam(&pwd);
2735                 return False;
2736         }
2737  
2738         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2739                 pdb_free_sam(&pwd);
2740                 return False;
2741         }
2742         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2743                 pdb_free_sam(&pwd);
2744                 return False;
2745         }
2746         if (!pdb_set_pass_changed_now (pwd)) {
2747                 pdb_free_sam(&pwd);
2748                 return False; 
2749         }
2750  
2751         if(!pdb_update_sam_account(pwd)) {
2752                 pdb_free_sam(&pwd);
2753                 return False;
2754         }
2755
2756         pdb_free_sam(&pwd);
2757         return True;
2758 }
2759
2760 /*******************************************************************
2761  The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2762  ********************************************************************/
2763 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2764 {
2765         struct group *grp;
2766         gid_t gid;
2767
2768         if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2769                                         &gid))) {
2770                 DEBUG(2,("Could not get gid for primary group of "
2771                          "user %s\n", pdb_get_username(sampass)));
2772                 return False;
2773         }
2774
2775         grp = getgrgid(gid);
2776
2777         if (grp == NULL) {
2778                 DEBUG(2,("Could not find primary group %lu for "
2779                          "user %s\n", (unsigned long)gid, 
2780                          pdb_get_username(sampass)));
2781                 return False;
2782         }
2783
2784         if (smb_set_primary_group(grp->gr_name,
2785                                   pdb_get_username(sampass)) != 0) {
2786                 DEBUG(2,("Could not set primary group for user %s to "
2787                          "%s\n",
2788                          pdb_get_username(sampass), grp->gr_name));
2789                 return False;
2790         }
2791
2792         return True;
2793 }
2794         
2795
2796 /*******************************************************************
2797  set_user_info_20
2798  ********************************************************************/
2799
2800 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2801 {
2802         if (id20 == NULL) {
2803                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2804                 return False;
2805         }
2806  
2807         copy_id20_to_sam_passwd(pwd, id20);
2808
2809         /* write the change out */
2810         if(!pdb_update_sam_account(pwd)) {
2811                 pdb_free_sam(&pwd);
2812                 return False;
2813         }
2814
2815         pdb_free_sam(&pwd);
2816
2817         return True;
2818 }
2819 /*******************************************************************
2820  set_user_info_21
2821  ********************************************************************/
2822
2823 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2824 {
2825  
2826         if (id21 == NULL) {
2827                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2828                 return False;
2829         }
2830  
2831         copy_id21_to_sam_passwd(pwd, id21);
2832  
2833         /*
2834          * The funny part about the previous two calls is
2835          * that pwd still has the password hashes from the
2836          * passdb entry.  These have not been updated from
2837          * id21.  I don't know if they need to be set.    --jerry
2838          */
2839  
2840         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2841                 set_unix_primary_group(pwd);
2842
2843         /* write the change out */
2844         if(!pdb_update_sam_account(pwd)) {
2845                 pdb_free_sam(&pwd);
2846                 return False;
2847         }
2848
2849         pdb_free_sam(&pwd);
2850
2851         return True;
2852 }
2853
2854 /*******************************************************************
2855  set_user_info_23
2856  ********************************************************************/
2857
2858 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2859 {
2860         pstring plaintext_buf;
2861         uint32 len;
2862         uint16 acct_ctrl;
2863  
2864         if (id23 == NULL) {
2865                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2866                 return False;
2867         }
2868  
2869         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2870                   pdb_get_username(pwd)));
2871
2872         acct_ctrl = pdb_get_acct_ctrl(pwd);
2873
2874         if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2875                 pdb_free_sam(&pwd);
2876                 return False;
2877         }
2878   
2879         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2880                 pdb_free_sam(&pwd);
2881                 return False;
2882         }
2883  
2884         copy_id23_to_sam_passwd(pwd, id23);
2885  
2886         /* if it's a trust account, don't update /etc/passwd */
2887         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2888                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2889                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2890                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2891         } else  {
2892                 /* update the UNIX password */
2893                 if (lp_unix_password_sync() ) {
2894                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2895                         if (!passwd) {
2896                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2897                         }
2898                         
2899                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2900                                 pdb_free_sam(&pwd);
2901                                 return False;
2902                         }
2903                 }
2904         }
2905  
2906         ZERO_STRUCT(plaintext_buf);
2907  
2908         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2909                 set_unix_primary_group(pwd);
2910
2911         if(!pdb_update_sam_account(pwd)) {
2912                 pdb_free_sam(&pwd);
2913                 return False;
2914         }
2915  
2916         pdb_free_sam(&pwd);
2917
2918         return True;
2919 }
2920
2921 /*******************************************************************
2922  set_user_info_pw
2923  ********************************************************************/
2924
2925 static BOOL set_user_info_pw(uint8 *pass, SAM_ACCOUNT *pwd)
2926 {
2927         uint32 len;
2928         pstring plaintext_buf;
2929         uint16 acct_ctrl;
2930  
2931         DEBUG(5, ("Attempting administrator password change for user %s\n",
2932                   pdb_get_username(pwd)));
2933
2934         acct_ctrl = pdb_get_acct_ctrl(pwd);
2935
2936         ZERO_STRUCT(plaintext_buf);
2937  
2938         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2939                 pdb_free_sam(&pwd);
2940                 return False;
2941         }
2942
2943         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2944                 pdb_free_sam(&pwd);
2945                 return False;
2946         }
2947  
2948         /* if it's a trust account, don't update /etc/passwd */
2949         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2950                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2951                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2952                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2953         } else {
2954                 /* update the UNIX password */
2955                 if (lp_unix_password_sync()) {
2956                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2957                         if (!passwd) {
2958                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2959                         }
2960                         
2961                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2962                                 pdb_free_sam(&pwd);
2963                                 return False;
2964                         }
2965                 }
2966         }
2967  
2968         ZERO_STRUCT(plaintext_buf);
2969  
2970         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2971  
2972         /* update the SAMBA password */
2973         if(!pdb_update_sam_account(pwd)) {
2974                 pdb_free_sam(&pwd);
2975                 return False;
2976         }
2977
2978         pdb_free_sam(&pwd);
2979
2980         return True;
2981 }
2982
2983 /*******************************************************************
2984  samr_reply_set_userinfo
2985  ********************************************************************/
2986
2987 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2988 {
2989         SAM_ACCOUNT *pwd = NULL;
2990         DOM_SID sid;
2991         POLICY_HND *pol = &q_u->pol;
2992         uint16 switch_value = q_u->switch_value;
2993         SAM_USERINFO_CTR *ctr = q_u->ctr;
2994         uint32 acc_granted;
2995         uint32 acc_required;
2996         BOOL ret;
2997         BOOL has_enough_rights = False;
2998         uint32 acb_info;
2999
3000         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3001
3002         r_u->status = NT_STATUS_OK;
3003
3004         /* find the policy handle.  open a policy on it. */
3005         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3006                 return NT_STATUS_INVALID_HANDLE;
3007
3008         /* observed when joining an XP client to a Samba domain */
3009         
3010         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;     
3011
3012         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3013                 return r_u->status;
3014         }
3015                 
3016         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3017
3018         if (ctr == NULL) {
3019                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3020                 return NT_STATUS_INVALID_INFO_CLASS;
3021         }
3022         
3023         pdb_init_sam(&pwd);     
3024         
3025         become_root();
3026         ret = pdb_getsampwsid(pwd, &sid);
3027         unbecome_root();
3028         
3029         if ( !ret ) {
3030                 pdb_free_sam(&pwd);
3031                 return NT_STATUS_NO_SUCH_USER;
3032         }
3033         
3034         /* deal with machine password changes differently from userinfo changes */
3035         /* check to see if we have the sufficient rights */
3036         
3037         acb_info = pdb_get_acct_ctrl(pwd);
3038         if ( acb_info & ACB_WSTRUST ) 
3039                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3040         else if ( acb_info & ACB_NORMAL )
3041                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3042         else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3043                 if ( lp_enable_privileges() )
3044                         has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3045         }
3046                 
3047         DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3048                 p->pipe_user_name, has_enough_rights ? "" : " not"));
3049
3050         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3051         
3052         if ( has_enough_rights )                                
3053                 become_root(); 
3054         
3055         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3056
3057         switch (switch_value) {
3058                 case 18:
3059                         if (!set_user_info_12(ctr->info.id12, pwd))
3060                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3061                         break;
3062
3063                 case 24:
3064                         if (!p->session_key.length) {
3065                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3066                         }
3067                         SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3068
3069                         dump_data(100, (char *)ctr->info.id24->pass, 516);
3070
3071                         if (!set_user_info_pw(ctr->info.id24->pass, pwd))
3072                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3073                         break;
3074
3075                 case 25:
3076 #if 0
3077                         /*
3078                          * Currently we don't really know how to unmarshall
3079                          * the level 25 struct, and the password encryption
3080                          * is different. This is a placeholder for when we
3081                          * do understand it. In the meantime just return INVALID
3082                          * info level and W2K SP2 drops down to level 23... JRA.
3083                          */
3084
3085                         if (!p->session_key.length) {
3086                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3087                         }
3088                         SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3089
3090                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3091
3092                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3093                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3094                         break;
3095 #endif
3096                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3097                         break;
3098
3099                 case 23:
3100                         if (!p->session_key.length) {
3101                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3102                         }
3103                         SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3104
3105                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3106
3107                         if (!set_user_info_23(ctr->info.id23, pwd))
3108                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3109                         break;
3110
3111                 default:
3112                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3113         }
3114
3115         
3116         if ( has_enough_rights )                                
3117                 unbecome_root();
3118                 
3119         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3120
3121         return r_u->status;
3122 }
3123
3124 /*******************************************************************
3125  samr_reply_set_userinfo2
3126  ********************************************************************/
3127
3128 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3129 {
3130         SAM_ACCOUNT *pwd = NULL;
3131         DOM_SID sid;
3132         SAM_USERINFO_CTR *ctr = q_u->ctr;
3133         POLICY_HND *pol = &q_u->pol;
3134         uint16 switch_value = q_u->switch_value;
3135         uint32 acc_granted;
3136         uint32 acc_required;
3137         BOOL ret;
3138         BOOL has_enough_rights = False;
3139         uint32 acb_info;
3140
3141         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3142
3143         r_u->status = NT_STATUS_OK;
3144
3145         /* find the policy handle.  open a policy on it. */
3146         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3147                 return NT_STATUS_INVALID_HANDLE;
3148
3149         /* observed when joining XP client to Samba domain */
3150                 
3151         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3152         
3153         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3154                 return r_u->status;
3155         }
3156
3157         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3158
3159         if (ctr == NULL) {
3160                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3161                 return NT_STATUS_INVALID_INFO_CLASS;
3162         }
3163
3164         switch_value=ctr->switch_value;
3165
3166         pdb_init_sam(&pwd);     
3167         
3168         become_root();
3169         ret = pdb_getsampwsid(pwd, &sid);
3170         unbecome_root();
3171         
3172         if ( !ret ) {
3173                 pdb_free_sam(&pwd);
3174                 return NT_STATUS_NO_SUCH_USER;
3175         }
3176         
3177         acb_info = pdb_get_acct_ctrl(pwd);
3178         if ( acb_info & ACB_WSTRUST ) 
3179                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3180         else if ( acb_info & ACB_NORMAL )
3181                 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3182         else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3183                 if ( lp_enable_privileges() )
3184                         has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3185         }
3186                 
3187         DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3188                 p->pipe_user_name, has_enough_rights ? "" : " not"));
3189
3190         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3191         
3192         if ( has_enough_rights )                                
3193                 become_root(); 
3194         
3195         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3196         
3197         switch (switch_value) {
3198                 case 16:
3199                         if (!set_user_info_10(ctr->info.id10, pwd))
3200                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3201                         break;
3202                 case 18:
3203                         /* Used by AS/U JRA. */
3204                         if (!set_user_info_12(ctr->info.id12, pwd))
3205                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3206                         break;
3207                 case 20:
3208                         if (!set_user_info_20(ctr->info.id20, pwd))
3209                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3210                         break;
3211                 case 21:
3212                         if (!set_user_info_21(ctr->info.id21, pwd))
3213                                 return NT_STATUS_ACCESS_DENIED;
3214                         break;
3215                 default:
3216                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3217         }
3218
3219         if ( has_enough_rights )                                
3220                 unbecome_root();
3221                 
3222         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3223
3224         return r_u->status;
3225 }
3226
3227 /*********************************************************************
3228  _samr_query_aliasmem
3229 *********************************************************************/
3230
3231 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3232 {
3233         int num_alias_rids;
3234         uint32 *alias_rids;
3235         struct samr_info *info = NULL;
3236         int i;
3237                 
3238         NTSTATUS ntstatus1;
3239         NTSTATUS ntstatus2;
3240
3241         DOM_SID *members;
3242         BOOL res;
3243
3244         r_u->status = NT_STATUS_OK;
3245
3246         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3247
3248         /* find the policy handle.  open a policy on it. */
3249         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3250                 return NT_STATUS_INVALID_HANDLE;
3251                 
3252         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3253         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3254         
3255         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3256                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3257                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3258                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3259                 }
3260         }               
3261
3262         if (!sid_check_is_domain(&info->sid) &&
3263             !sid_check_is_builtin(&info->sid))
3264                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3265
3266         members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3267
3268         if (members == NULL)
3269                 return NT_STATUS_NO_MEMORY;
3270
3271         for (i=0; i<q_u->num_sids1; i++)
3272                 sid_copy(&members[i], &q_u->sid[i].sid);
3273
3274         alias_rids = NULL;
3275         num_alias_rids = 0;
3276
3277         become_root();
3278         res = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
3279                                          q_u->num_sids1,
3280                                          &alias_rids, &num_alias_rids);
3281         unbecome_root();
3282
3283         if (!res)
3284                 return NT_STATUS_UNSUCCESSFUL;
3285
3286         init_samr_r_query_useraliases(r_u, num_alias_rids, alias_rids,
3287                                       NT_STATUS_OK);
3288         return NT_STATUS_OK;
3289 }
3290
3291 /*********************************************************************
3292  _samr_query_aliasmem
3293 *********************************************************************/
3294
3295 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3296 {
3297         int i;
3298
3299         int num_sids = 0;
3300         DOM_SID2 *sid;
3301         DOM_SID *sids=NULL;
3302
3303         DOM_SID alias_sid;
3304
3305         uint32 acc_granted;
3306
3307         /* find the policy handle.  open a policy on it. */
3308         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3309                 return NT_STATUS_INVALID_HANDLE;
3310         
3311         if (!NT_STATUS_IS_OK(r_u->status = 
3312                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3313                 return r_u->status;
3314         }
3315
3316         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3317
3318         if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3319                 return NT_STATUS_NO_SUCH_ALIAS;
3320
3321         sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);        
3322         if (num_sids!=0 && sid == NULL) {
3323                 SAFE_FREE(sids);
3324                 return NT_STATUS_NO_MEMORY;
3325         }
3326
3327         for (i = 0; i < num_sids; i++) {
3328                 init_dom_sid2(&sid[i], &sids[i]);
3329         }
3330
3331         init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3332
3333         SAFE_FREE(sids);
3334
3335         return NT_STATUS_OK;
3336 }
3337
3338 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3339 {
3340         int i;
3341
3342         for (i=0; i<*num; i++) {
3343                 if ((*uids)[i] == uid)
3344                         return;
3345         }
3346         
3347         *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3348
3349         if (*uids == NULL)
3350                 return;
3351
3352         (*uids)[*num] = uid;
3353         *num += 1;
3354 }
3355
3356
3357 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3358 {
3359         struct group *grp;
3360         char **gr;
3361         struct sys_pwent *userlist, *user;
3362  
3363         *uids = NULL;
3364         *num = 0;
3365
3366         /* We only look at our own sam, so don't care about imported stuff */
3367
3368         winbind_off();
3369
3370         if ((grp = getgrgid(gid)) == NULL) {
3371                 winbind_on();
3372                 return False;
3373         }
3374
3375         /* Primary group members */
3376
3377         userlist = getpwent_list();
3378
3379         for (user = userlist; user != NULL; user = user->next) {
3380                 if (user->pw_gid != gid)
3381                         continue;
3382                 add_uid_to_array_unique(user->pw_uid, uids, num);
3383         }
3384
3385         pwent_free(userlist);
3386
3387         /* Secondary group members */
3388
3389         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3390                 struct passwd *pw = getpwnam(*gr);
3391
3392                 if (pw == NULL)
3393                         continue;
3394                 add_uid_to_array_unique(pw->pw_uid, uids, num);
3395         }
3396
3397         winbind_on();
3398
3399         return True;
3400 }       
3401
3402 /*********************************************************************
3403  _samr_query_groupmem
3404 *********************************************************************/
3405
3406 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3407 {
3408         DOM_SID group_sid;
3409         fstring group_sid_str;
3410         int i, num_members;
3411
3412         uint32 *rid=NULL;
3413         uint32 *attr=NULL;
3414
3415         uint32 acc_granted;
3416
3417         NTSTATUS result;
3418
3419         /* find the policy handle.  open a policy on it. */
3420         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3421                 return NT_STATUS_INVALID_HANDLE;
3422                 
3423         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3424                 return r_u->status;
3425         }
3426                 
3427         sid_to_string(group_sid_str, &group_sid);
3428         DEBUG(10, ("sid is %s\n", group_sid_str));
3429
3430         if (!sid_check_is_in_our_domain(&group_sid)) {
3431                 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3432                 return NT_STATUS_NO_SUCH_GROUP;
3433         }
3434
3435         DEBUG(10, ("lookup on Domain SID\n"));
3436
3437         become_root();
3438         result = pdb_enum_group_members(p->mem_ctx, &group_sid,
3439                                         &rid, &num_members);
3440         unbecome_root();
3441
3442         if (!NT_STATUS_IS_OK(result))
3443                 return result;
3444
3445         attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
3446         
3447         if ((num_members!=0) && (rid==NULL))
3448                 return NT_STATUS_NO_MEMORY;
3449         
3450         for (i=0; i<num_members; i++)
3451                 attr[i] = SID_NAME_USER;
3452
3453         init_samr_r_query_groupmem(r_u, num_members, rid, attr, NT_STATUS_OK);
3454
3455         return NT_STATUS_OK;
3456 }
3457
3458 /*********************************************************************
3459  _samr_add_aliasmem
3460 *********************************************************************/
3461
3462 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3463 {
3464         DOM_SID alias_sid;
3465         uint32 acc_granted;
3466         SE_PRIV se_rights;
3467         BOOL can_add_accounts;
3468         BOOL ret;
3469
3470
3471         /* Find the policy handle. Open a policy on it. */
3472         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3473                 return NT_STATUS_INVALID_HANDLE;
3474         
3475         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3476                 return r_u->status;
3477         }
3478                 
3479         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3480         
3481         se_priv_copy( &se_rights, &se_add_users );
3482         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3483
3484         /******** BEGIN SeAddUsers BLOCK *********/
3485         
3486         if ( can_add_accounts )
3487                 become_root();
3488         
3489         ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3490         
3491         if ( can_add_accounts )
3492                 unbecome_root();
3493                 
3494         /******** END SeAddUsers BLOCK *********/
3495         
3496         return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3497 }
3498
3499 /*********************************************************************
3500  _samr_del_aliasmem
3501 *********************************************************************/
3502
3503 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3504 {
3505         DOM_SID alias_sid;
3506         uint32 acc_granted;
3507         SE_PRIV se_rights;
3508         BOOL can_add_accounts;
3509         BOOL ret;
3510
3511         /* Find the policy handle. Open a policy on it. */
3512         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3513                 return NT_STATUS_INVALID_HANDLE;
3514         
3515         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3516                 return r_u->status;
3517         }
3518         
3519         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3520                    sid_string_static(&alias_sid)));
3521
3522         se_priv_copy( &se_rights, &se_add_users );
3523         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3524
3525         /******** BEGIN SeAddUsers BLOCK *********/
3526         
3527         if ( can_add_accounts )
3528                 become_root();
3529
3530         ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3531         
3532         if ( can_add_accounts )
3533                 unbecome_root();
3534                 
3535         /******** END SeAddUsers BLOCK *********/
3536         
3537         return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3538 }
3539
3540 /*********************************************************************
3541  _samr_add_groupmem
3542 *********************************************************************/
3543
3544 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3545 {
3546         DOM_SID group_sid;
3547         DOM_SID user_sid;
3548         fstring group_sid_str;
3549         uid_t uid;
3550         struct passwd *pwd;
3551         struct group *grp;
3552         fstring grp_name;
3553         GROUP_MAP map;
3554         NTSTATUS ret;
3555         SAM_ACCOUNT *sam_user=NULL;
3556         BOOL check;
3557         uint32 acc_granted;
3558         SE_PRIV se_rights;
3559         BOOL can_add_accounts;
3560
3561         /* Find the policy handle. Open a policy on it. */
3562         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3563                 return NT_STATUS_INVALID_HANDLE;
3564         
3565         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3566                 return r_u->status;
3567         }
3568
3569         sid_to_string(group_sid_str, &group_sid);
3570         DEBUG(10, ("sid is %s\n", group_sid_str));
3571
3572         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3573                 return NT_STATUS_NO_SUCH_GROUP;
3574
3575         DEBUG(10, ("lookup on Domain SID\n"));
3576
3577         if(!get_domain_group_from_sid(group_sid, &map))
3578                 return NT_STATUS_NO_SUCH_GROUP;
3579
3580         sid_copy(&user_sid, get_global_sam_sid());
3581         sid_append_rid(&user_sid, q_u->rid);
3582
3583         ret = pdb_init_sam(&sam_user);
3584         if (!NT_STATUS_IS_OK(ret))
3585                 return ret;
3586         
3587         check = pdb_getsampwsid(sam_user, &user_sid);
3588         
3589         if (check != True) {
3590                 pdb_free_sam(&sam_user);
3591                 return NT_STATUS_NO_SUCH_USER;
3592         }
3593
3594         /* check a real user exist before we run the script to add a user to a group */
3595         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3596                 pdb_free_sam(&sam_user);
3597                 return NT_STATUS_NO_SUCH_USER;
3598         }
3599
3600         pdb_free_sam(&sam_user);
3601
3602         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3603                 return NT_STATUS_NO_SUCH_USER;
3604         }
3605
3606         if ((grp=getgrgid(map.gid)) == NULL) {
3607                 passwd_free(&pwd);
3608                 return NT_STATUS_NO_SUCH_GROUP;
3609         }
3610
3611         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3612         fstrcpy(grp_name, grp->gr_name);
3613
3614         /* if the user is already in the group */
3615         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3616                 passwd_free(&pwd);
3617                 return NT_STATUS_MEMBER_IN_GROUP;
3618         }
3619
3620         se_priv_copy( &se_rights, &se_add_users );
3621         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3622
3623         /******** BEGIN SeAddUsers BLOCK *********/
3624         
3625         if ( can_add_accounts )
3626                 become_root();
3627                 
3628         /* 
3629          * ok, the group exist, the user exist, the user is not in the group,
3630          *
3631          * we can (finally) add it to the group !
3632          */
3633
3634         smb_add_user_group(grp_name, pwd->pw_name);
3635
3636         if ( can_add_accounts )
3637                 unbecome_root();
3638                 
3639         /******** END SeAddUsers BLOCK *********/
3640         
3641         /* check if the user has been added then ... */
3642         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3643                 passwd_free(&pwd);
3644                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3645         }
3646
3647         passwd_free(&pwd);
3648         return NT_STATUS_OK;
3649 }
3650
3651 /*********************************************************************
3652  _samr_del_groupmem
3653 *********************************************************************/
3654
3655 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3656 {
3657         DOM_SID group_sid;
3658         DOM_SID user_sid;
3659         SAM_ACCOUNT *sam_pass=NULL;
3660         GROUP_MAP map;
3661         fstring grp_name;
3662         struct group *grp;
3663         uint32 acc_granted;
3664         SE_PRIV se_rights;
3665         BOOL can_add_accounts;
3666
3667         /*
3668          * delete the group member named q_u->rid
3669          * who is a member of the sid associated with the handle
3670          * the rid is a user's rid as the group is a domain group.
3671          */
3672
3673         /* Find the policy handle. Open a policy on it. */
3674         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3675                 return NT_STATUS_INVALID_HANDLE;
3676         
3677         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3678                 return r_u->status;
3679         }
3680                 
3681         if (!sid_check_is_in_our_domain(&group_sid))
3682                 return NT_STATUS_NO_SUCH_GROUP;
3683
3684         sid_copy(&user_sid, get_global_sam_sid());
3685         sid_append_rid(&user_sid, q_u->rid);
3686
3687         if (!get_domain_group_from_sid(group_sid, &map))
3688                 return NT_STATUS_NO_SUCH_GROUP;
3689
3690         if ((grp=getgrgid(map.gid)) == NULL)
3691                 return NT_STATUS_NO_SUCH_GROUP;
3692
3693         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3694         fstrcpy(grp_name, grp->gr_name);
3695
3696         /* check if the user exists before trying to remove it from the group */
3697         pdb_init_sam(&sam_pass);
3698         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3699                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3700                 pdb_free_sam(&sam_pass);
3701                 return NT_STATUS_NO_SUCH_USER;
3702         }
3703
3704         /* if the user is not in the group */
3705         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3706                 pdb_free_sam(&sam_pass);
3707                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3708         }
3709         
3710
3711         se_priv_copy( &se_rights, &se_add_users );
3712         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3713
3714         /******** BEGIN SeAddUsers BLOCK *********/
3715         
3716         if ( can_add_accounts )
3717                 become_root();
3718                 
3719         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3720
3721         if ( can_add_accounts )
3722                 unbecome_root();
3723                 
3724         /******** END SeAddUsers BLOCK *********/
3725         
3726         /* check if the user has been removed then ... */
3727         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3728                 pdb_free_sam(&sam_pass);
3729                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3730         }
3731         
3732         pdb_free_sam(&sam_pass);
3733         return NT_STATUS_OK;
3734
3735 }
3736
3737 /****************************************************************************
3738  Delete a UNIX user on demand.
3739 ****************************************************************************/
3740
3741 static int smb_delete_user(const char *unix_user)
3742 {
3743         pstring del_script;
3744         int ret;
3745
3746         /* try winbindd first since it is impossible to determine where 
3747            a user came from via NSS.  Try the delete user script if this fails
3748            meaning the user did not exist in winbindd's list of accounts */
3749
3750         if ( winbind_delete_user( unix_user ) ) {
3751                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3752                 return 0;
3753         }
3754
3755
3756         /* fall back to 'delete user script' */
3757
3758         pstrcpy(del_script, lp_deluser_script());
3759         if (! *del_script)
3760                 return -1;
3761         all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3762         ret = smbrun(del_script,NULL);
3763         flush_pwnam_cache();
3764         DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3765
3766         return ret;
3767 }
3768
3769 /*********************************************************************
3770  _samr_delete_dom_user
3771 *********************************************************************/
3772
3773 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3774 {
3775         DOM_SID user_sid;
3776         SAM_ACCOUNT *sam_pass=NULL;
3777         uint32 acc_granted;
3778         BOOL can_add_accounts;
3779         BOOL ret;
3780
3781         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3782
3783         /* Find the policy handle. Open a policy on it. */
3784         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3785                 return NT_STATUS_INVALID_HANDLE;
3786                 
3787         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3788                 return r_u->status;
3789         }
3790                 
3791         if (!sid_check_is_in_our_domain(&user_sid))
3792                 return NT_STATUS_CANNOT_DELETE;
3793
3794         /* check if the user exists before trying to delete */
3795         pdb_init_sam(&sam_pass);
3796         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3797                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3798                         sid_string_static(&user_sid)));
3799                 pdb_free_sam(&sam_pass);
3800                 return NT_STATUS_NO_SUCH_USER;
3801         }
3802         
3803         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3804
3805         /******** BEGIN SeAddUsers BLOCK *********/
3806         
3807         if ( can_add_accounts )
3808                 become_root();
3809
3810         /* First delete the samba side....
3811            code is order to prevent unnecessary returns out of the admin 
3812            block of code */
3813            
3814         if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3815                 /*
3816                  * Now delete the unix side ....
3817                  * note: we don't check if the delete really happened
3818                  * as the script is not necessary present
3819                  * and maybe the sysadmin doesn't want to delete the unix side
3820                  */
3821                 smb_delete_user( pdb_get_username(sam_pass) );
3822         }
3823         
3824         if ( can_add_accounts )
3825                 unbecome_root();
3826                 
3827         /******** END SeAddUsers BLOCK *********/
3828                 
3829         if ( !ret ) {
3830                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3831                 pdb_free_sam(&sam_pass);
3832                 return NT_STATUS_CANNOT_DELETE;
3833         }
3834
3835
3836         pdb_free_sam(&sam_pass);
3837
3838         if (!close_policy_hnd(p, &q_u->user_pol))
3839                 return NT_STATUS_OBJECT_NAME_INVALID;
3840
3841         return NT_STATUS_OK;
3842 }
3843
3844 /*********************************************************************
3845  _samr_delete_dom_group
3846 *********************************************************************/
3847
3848 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3849 {
3850         DOM_SID group_sid;
3851         DOM_SID dom_sid;
3852         uint32 group_rid;
3853         fstring group_sid_str;
3854         gid_t gid;
3855         struct group *grp;
3856         GROUP_MAP map;
3857         uint32 acc_granted;
3858         SE_PRIV se_rights;
3859         BOOL can_add_accounts;
3860         BOOL ret;
3861
3862         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3863
3864         /* Find the policy handle. Open a policy on it. */
3865         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3866                 return NT_STATUS_INVALID_HANDLE;
3867                 
3868         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3869                 return r_u->status;
3870         }
3871                 
3872         sid_copy(&dom_sid, &group_sid);
3873         sid_to_string(group_sid_str, &dom_sid);
3874         sid_split_rid(&dom_sid, &group_rid);
3875
3876         DEBUG(10, ("sid is %s\n", group_sid_str));
3877
3878         /* we check if it's our SID before deleting */
3879         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3880                 return NT_STATUS_NO_SUCH_GROUP;
3881
3882         DEBUG(10, ("lookup on Domain SID\n"));
3883
3884         if(!get_domain_group_from_sid(group_sid, &map))
3885                 return NT_STATUS_NO_SUCH_GROUP;
3886
3887         gid=map.gid;
3888
3889         /* check if group really exists */
3890         if ( (grp=getgrgid(gid)) == NULL)
3891                 return NT_STATUS_NO_SUCH_GROUP;
3892
3893         se_priv_copy( &se_rights, &se_add_users );
3894         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3895
3896         /******** BEGIN SeAddUsers BLOCK *********/
3897         
3898         if ( can_add_accounts )
3899                 become_root();
3900
3901         /* delete mapping first */
3902         
3903         if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3904                 smb_delete_group( grp->gr_name );
3905         }
3906
3907         if ( can_add_accounts )
3908                 unbecome_root();
3909                 
3910         /******** END SeAddUsers BLOCK *********/
3911         
3912         if ( !ret ) {
3913                 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n", 
3914                         group_sid_str));
3915                 return NT_STATUS_ACCESS_DENIED;
3916         }
3917         
3918         /* don't check that the unix group has been deleted.  Work like 
3919            _samr_delet_dom_user() */
3920
3921         if (!close_policy_hnd(p, &q_u->group_pol))
3922                 return NT_STATUS_OBJECT_NAME_INVALID;
3923
3924         return NT_STATUS_OK;
3925 }
3926
3927 /*********************************************************************
3928  _samr_delete_dom_alias
3929 *********************************************************************/
3930
3931 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3932 {
3933         DOM_SID alias_sid;
3934         uint32 acc_granted;
3935         SE_PRIV se_rights;
3936         BOOL can_add_accounts;
3937         BOOL ret;
3938
3939         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3940
3941         /* Find the policy handle. Open a policy on it. */
3942         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3943                 return NT_STATUS_INVALID_HANDLE;
3944         
3945         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3946                 return r_u->status;
3947         }
3948
3949         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3950
3951         if (!sid_check_is_in_our_domain(&alias_sid))
3952                 return NT_STATUS_NO_SUCH_ALIAS;
3953                 
3954         DEBUG(10, ("lookup on Local SID\n"));
3955
3956         se_priv_copy( &se_rights, &se_add_users );
3957         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3958
3959         /******** BEGIN SeAddUsers BLOCK *********/
3960         
3961         if ( can_add_accounts )
3962                 become_root();
3963
3964         /* Have passdb delete the alias */
3965         ret = pdb_delete_alias(&alias_sid);
3966         
3967         if ( can_add_accounts )
3968                 unbecome_root();
3969                 
3970         /******** END SeAddUsers BLOCK *********/
3971
3972         if ( !ret )
3973                 return NT_STATUS_ACCESS_DENIED;
3974
3975         if (!close_policy_hnd(p, &q_u->alias_pol))
3976                 return NT_STATUS_OBJECT_NAME_INVALID;
3977
3978         return NT_STATUS_OK;
3979 }
3980
3981 /*********************************************************************
3982  _samr_create_dom_group
3983 *********************************************************************/
3984
3985 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3986 {
3987         DOM_SID dom_sid;
3988         DOM_SID info_sid;
3989         fstring name;
3990         fstring sid_string;
3991         struct group *grp;
3992         struct samr_info *info;
3993         uint32 acc_granted;
3994         gid_t gid;
3995         SE_PRIV se_rights;
3996         BOOL can_add_accounts;
3997         NTSTATUS result;
3998
3999         /* Find the policy handle. Open a policy on it. */
4000         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
4001                 return NT_STATUS_INVALID_HANDLE;
4002         
4003         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4004                 return r_u->status;
4005         }
4006                 
4007         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4008                 return NT_STATUS_ACCESS_DENIED;
4009
4010         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4011
4012         /* check if group already exist */
4013         if ((grp=getgrnam(name)) != NULL)
4014                 return NT_STATUS_GROUP_EXISTS;
4015
4016         se_priv_copy( &se_rights, &se_add_users );
4017         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4018
4019         /******** BEGIN SeAddUsers BLOCK *********/
4020         
4021         if ( can_add_accounts )
4022                 become_root();
4023         
4024         /* check that we successfully create the UNIX group */
4025         
4026         result = NT_STATUS_ACCESS_DENIED;
4027         if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4028         
4029                 /* so far, so good */
4030                 
4031                 result = NT_STATUS_OK;
4032                 
4033                 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4034
4035                 /* add the group to the mapping table */
4036                 
4037                 sid_copy( &info_sid, get_global_sam_sid() );
4038                 sid_append_rid( &info_sid, r_u->rid );
4039                 sid_to_string( sid_string, &info_sid );
4040                 
4041                 /* reset the error code if we fail to add the mapping entry */
4042                 
4043                 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4044                         result = NT_STATUS_ACCESS_DENIED;
4045         }
4046
4047         if ( can_add_accounts )
4048                 unbecome_root();
4049                 
4050         /******** END SeAddUsers BLOCK *********/
4051         
4052         /* check if we should bail out here */
4053         
4054         if ( !NT_STATUS_IS_OK(result) )
4055                 return result;
4056         
4057         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4058                 return NT_STATUS_NO_MEMORY;
4059
4060         /* get a (unique) handle.  open a policy on it. */
4061         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4062                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4063
4064         return NT_STATUS_OK;
4065 }
4066
4067 /*********************************************************************
4068  _samr_create_dom_alias
4069 *********************************************************************/
4070
4071 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4072 {
4073         DOM_SID dom_sid;
4074         DOM_SID info_sid;
4075         fstring name;
4076         struct samr_info *info;
4077         uint32 acc_granted;
4078         gid_t gid;
4079         NTSTATUS result;
4080         SE_PRIV se_rights;
4081         BOOL can_add_accounts;
4082
4083         /* Find the policy handle. Open a policy on it. */
4084         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
4085                 return NT_STATUS_INVALID_HANDLE;
4086                 
4087         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4088                 return r_u->status;
4089         }
4090                 
4091         if (!sid_equal(&dom_sid, get_global_sam_sid()))
4092                 return NT_STATUS_ACCESS_DENIED;
4093
4094         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4095
4096         se_priv_copy( &se_rights, &se_add_users );
4097         can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4098
4099         /******** BEGIN SeAddUsers BLOCK *********/
4100         
4101         if ( can_add_accounts )
4102                 become_root();
4103
4104         /* Have passdb create the alias */
4105         result = pdb_create_alias(name, &r_u->rid);
4106
4107         if ( can_add_accounts )
4108                 unbecome_root();
4109                 
4110         /******** END SeAddUsers BLOCK *********/
4111
4112         if (!NT_STATUS_IS_OK(result))
4113                 return result;
4114
4115         sid_copy(&info_sid, get_global_sam_sid());
4116         sid_append_rid(&info_sid, r_u->rid);
4117
4118         if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4119                 return NT_STATUS_ACCESS_DENIED;
4120
4121         /* check if the group has been successfully created */
4122         if ( getgrgid(gid) == NULL )
4123                 return NT_STATUS_ACCESS_DENIED;
4124
4125         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4126                 return NT_STATUS_NO_MEMORY;
4127
4128         /* get a (unique) handle.  open a policy on it. */
4129         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4130                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4131
4132         return NT_STATUS_OK;
4133 }
4134
4135 /*********************************************************************
4136  _samr_query_groupinfo
4137
4138 sends the name/comment pair of a domain group
4139 level 1 send also the number of users of that group
4140 *********************************************************************/
4141
4142 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4143 {
4144         DOM_SID group_sid;
4145         GROUP_MAP map;
4146         DOM_SID *sids=NULL;
4147         uid_t *uids;
4148         int num=0;
4149         GROUP_INFO_CTR *ctr;
4150         uint32 acc_granted;
4151         BOOL ret;
4152
4153         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4154                 return NT_STATUS_INVALID_HANDLE;
4155         
4156         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4157                 return r_u->status;
4158         }
4159                 
4160         become_root();
4161         ret = get_domain_group_from_sid(group_sid, &map);
4162         unbecome_root();
4163         if (!ret)
4164                 return NT_STATUS_INVALID_HANDLE;
4165
4166         ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4167         if (ctr==NULL)
4168                 return NT_STATUS_NO_MEMORY;
4169
4170         switch (q_u->switch_level) {
4171                 case 1:
4172                         ctr->switch_value1 = 1;
4173                         if(!get_memberuids(map.gid, &uids, &num))
4174                                 return NT_STATUS_NO_SUCH_GROUP;
4175                         SAFE_FREE(uids);
4176                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4177                         SAFE_FREE(sids);
4178                         break;
4179                 case 3:
4180                         ctr->switch_value1 = 3;
4181                         init_samr_group_info3(&ctr->group.info3);
4182                         break;
4183                 case 4:
4184                         ctr->switch_value1 = 4;
4185                         init_samr_group_info4(&ctr->group.info4, map.comment);
4186                         break;
4187                 default:
4188                         return NT_STATUS_INVALID_INFO_CLASS;
4189         }
4190
4191         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4192
4193         return NT_STATUS_OK;
4194 }
4195
4196 /*********************************************************************
4197  _samr_set_groupinfo
4198  
4199  update a domain group's comment.
4200 *********************************************************************/
4201
4202 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4203 {
4204         DOM_SID group_sid;
4205         GROUP_MAP map;
4206         GROUP_INFO_CTR *ctr;
4207         uint32 acc_granted;
4208
4209         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4210                 return NT_STATUS_INVALID_HANDLE;
4211         
4212         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4213                 return r_u->status;
4214         }
4215                 
4216         if (!get_domain_group_from_sid(group_sid, &map))
4217                 return NT_STATUS_NO_SUCH_GROUP;
4218         
4219         ctr=q_u->ctr;
4220
4221         switch (ctr->switch_value1) {
4222                 case 1:
4223                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4224                         break;
4225                 case 4:
4226                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4227                         break;
4228                 default:
4229                         return NT_STATUS_INVALID_INFO_CLASS;
4230         }
4231
4232         if(!pdb_update_group_mapping_entry(&map)) {
4233                 return NT_STATUS_NO_SUCH_GROUP;
4234         }
4235
4236         return NT_STATUS_OK;
4237 }
4238
4239 /*********************************************************************
4240  _samr_set_aliasinfo
4241  
4242  update an alias's comment.
4243 *********************************************************************/
4244
4245 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4246 {
4247         DOM_SID group_sid;
4248         struct acct_info info;
4249         ALIAS_INFO_CTR *ctr;
4250         uint32 acc_granted;
4251
4252         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4253                 return NT_STATUS_INVALID_HANDLE;
4254         
4255         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4256                 return r_u->status;
4257         }
4258                 
4259         ctr=&q_u->ctr;
4260
4261         switch (ctr->switch_value1) {
4262                 case 3:
4263                         unistr2_to_ascii(info.acct_desc,
4264                                          &(ctr->alias.info3.uni_acct_desc),
4265                                          sizeof(info.acct_desc)-1);
4266                         break;
4267                 default:
4268                         return NT_STATUS_INVALID_INFO_CLASS;
4269         }
4270
4271         if(!pdb_set_aliasinfo(&group_sid, &info)) {
4272                 return NT_STATUS_ACCESS_DENIED;
4273         }
4274
4275         return NT_STATUS_OK;
4276 }
4277
4278 /*********************************************************************
4279  _samr_get_dom_pwinfo
4280 *********************************************************************/
4281
4282 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4283 {
4284         /* Perform access check.  Since this rpc does not require a
4285            policy handle it will not be caught by the access checks on
4286            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4287
4288         if (!pipe_access_check(p)) {
4289                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4290                 r_u->status = NT_STATUS_ACCESS_DENIED;
4291                 return r_u->status;
4292         }
4293
4294         /* Actually, returning zeros here works quite well :-). */
4295
4296         return NT_STATUS_OK;
4297 }
4298
4299 /*********************************************************************
4300  _samr_open_group
4301 *********************************************************************/
4302
4303 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4304 {
4305         DOM_SID sid;
4306         DOM_SID info_sid;
4307         GROUP_MAP map;
4308         struct samr_info *info;
4309         SEC_DESC         *psd = NULL;
4310         uint32            acc_granted;
4311         uint32            des_access = q_u->access_mask;
4312         size_t            sd_size;
4313         NTSTATUS          status;
4314         fstring sid_string;
4315         BOOL ret;
4316         SE_PRIV se_rights;
4317
4318         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4319                 return NT_STATUS_INVALID_HANDLE;
4320         
4321         status = access_check_samr_function(acc_granted, 
4322                 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4323                 
4324         if ( !NT_STATUS_IS_OK(status) )
4325                 return status;
4326                 
4327         /*check if access can be granted as requested by client. */
4328         make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4329         se_map_generic(&des_access,&grp_generic_mapping);
4330
4331         se_priv_copy( &se_rights, &se_add_users );
4332
4333         status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4334                 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access, 
4335                 &acc_granted, "_samr_open_group");
4336                 
4337         if ( !NT_STATUS_IS_OK(status) ) 
4338                 return status;
4339
4340         /* this should not be hard-coded like this */
4341         
4342         if (!sid_equal(&sid, get_global_sam_sid()))
4343                 return NT_STATUS_ACCESS_DENIED;
4344
4345         sid_copy(&info_sid, get_global_sam_sid());
4346         sid_append_rid(&info_sid, q_u->rid_group);
4347         sid_to_string(sid_string, &info_sid);
4348
4349         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4350                 return NT_STATUS_NO_MEMORY;
4351                 
4352         info->acc_granted = acc_granted;
4353
4354         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4355
4356         /* check if that group really exists */
4357         become_root();
4358         ret = get_domain_group_from_sid(info->sid, &map);
4359         unbecome_root();
4360         if (!ret)
4361                 return NT_STATUS_NO_SUCH_GROUP;
4362
4363         /* get a (unique) handle.  open a policy on it. */
4364         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4365                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4366
4367         return NT_STATUS_OK;
4368 }
4369
4370 /*********************************************************************
4371  _samr_remove_sid_foreign_domain
4372 *********************************************************************/
4373
4374 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4375                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4376                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4377 {
4378         DOM_SID                 delete_sid, alias_sid;
4379         SAM_ACCOUNT             *sam_pass=NULL;
4380         uint32                  acc_granted;
4381         GROUP_MAP               map;
4382         BOOL                    is_user = False;
4383         NTSTATUS                result;
4384         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4385         
4386         sid_copy( &delete_sid, &q_u->sid.sid );
4387         
4388         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4389                 sid_string_static(&delete_sid)));
4390                 
4391         /* Find the policy handle. Open a policy on it. */
4392         
4393         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4394                 return NT_STATUS_INVALID_HANDLE;
4395         
4396         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4397                 "_samr_remove_sid_foreign_domain");
4398                 
4399         if (!NT_STATUS_IS_OK(result)) 
4400                 return result;
4401                         
4402         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4403                 sid_string_static(&alias_sid)));
4404                 
4405         /* make sure we can handle this */
4406         
4407         if ( sid_check_is_domain(&alias_sid) )
4408                 type = SID_NAME_DOM_GRP;
4409         else if ( sid_check_is_builtin(&alias_sid) )
4410                 type = SID_NAME_ALIAS;
4411         
4412         if ( type == SID_NAME_UNKNOWN ) {
4413                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4414                 return NT_STATUS_OK;
4415         }
4416
4417         /* check if the user exists before trying to delete */
4418         
4419         pdb_init_sam(&sam_pass);
4420         
4421         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4422                 is_user = True;
4423         } else {
4424                 /* maybe it is a group */
4425                 if( !pdb_getgrsid(&map, delete_sid) ) {
4426                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4427                                 sid_string_static(&delete_sid)));
4428                         result = NT_STATUS_INVALID_SID;
4429                         goto done;
4430                 }
4431         }
4432         
4433         /* we can only delete a user from a group since we don't have 
4434            nested groups anyways.  So in the latter case, just say OK */
4435            
4436         if ( is_user ) {
4437                 GROUP_MAP       *mappings = NULL;
4438                 int             num_groups, i;
4439                 struct group    *grp2;
4440                 
4441                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4442                 
4443                         /* interate over the groups */
4444                         for ( i=0; i<num_groups; i++ ) {
4445
4446                                 grp2 = getgrgid(mappings[i].gid);
4447
4448                                 if ( !grp2 ) {
4449                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4450                                         continue;
4451                                 }
4452                         
4453                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4454                                         continue;
4455                                 
4456                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4457                                 
4458                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4459                                         /* should we fail here ? */
4460                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4461                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4462                                         continue;
4463                                 }
4464                                         
4465                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4466                                         pdb_get_username(sam_pass), grp2->gr_name ));
4467                         }
4468                         
4469                         SAFE_FREE(mappings);
4470                 }
4471         }
4472         
4473         result = NT_STATUS_OK;
4474 done:
4475
4476         pdb_free_sam(&sam_pass);
4477
4478         return result;
4479 }
4480
4481 /*******************************************************************
4482  _samr_unknown_2e
4483  ********************************************************************/
4484
4485 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4486 {
4487         struct samr_info *info = NULL;
4488         SAM_UNK_CTR *ctr;
4489         uint32 min_pass_len,pass_hist,flag;
4490         time_t u_expire, u_min_age;
4491         NTTIME nt_expire, nt_min_age;
4492
4493         time_t u_lock_duration, u_reset_time;
4494         NTTIME nt_lock_duration, nt_reset_time;
4495         uint32 lockout;
4496         
4497         time_t u_logout;
4498         NTTIME nt_logout;
4499
4500         uint32 num_users=0, num_groups=0, num_aliases=0;
4501
4502         uint32 account_policy_temp;
4503         uint32 server_role;
4504
4505         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4506                 return NT_STATUS_NO_MEMORY;
4507
4508         ZERO_STRUCTP(ctr);
4509
4510         r_u->status = NT_STATUS_OK;
4511
4512         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4513
4514         /* find the policy handle.  open a policy on it. */
4515         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4516                 return NT_STATUS_INVALID_HANDLE;
4517
4518         switch (q_u->switch_value) {
4519                 case 0x01:
4520                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4521                         min_pass_len = account_policy_temp;
4522
4523                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4524                         pass_hist = account_policy_temp;
4525
4526                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4527                         flag = account_policy_temp;
4528
4529                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4530                         u_expire = account_policy_temp;
4531
4532                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4533                         u_min_age = account_policy_temp;
4534
4535                         unix_to_nt_time_abs(&nt_expire, u_expire);
4536                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4537
4538                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4539                                        flag, nt_expire, nt_min_age);
4540                         break;
4541                 case 0x02:
4542                         become_root();          
4543                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4544                         unbecome_root();
4545                         if (!NT_STATUS_IS_OK(r_u->status)) {
4546                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4547                                 return r_u->status;
4548                         }
4549                         num_users=info->disp_info.num_user_account;
4550                         free_samr_db(info);
4551                         
4552                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4553                         if (NT_STATUS_IS_ERR(r_u->status)) {
4554                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4555                                 return r_u->status;
4556                         }
4557                         num_groups=info->disp_info.num_group_account;
4558                         free_samr_db(info);
4559
4560                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4561                         u_logout = account_policy_temp;
4562
4563                         unix_to_nt_time_abs(&nt_logout, u_logout);
4564
4565                         server_role = ROLE_DOMAIN_PDC;
4566                         if (lp_server_role() == ROLE_DOMAIN_BDC)
4567                                 server_role = ROLE_DOMAIN_BDC;
4568
4569                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4570                         init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL), 
4571                                        num_users, num_groups, num_aliases, nt_logout, server_role);
4572                         break;
4573                 case 0x03:
4574                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4575                         u_logout = account_policy_temp;
4576
4577                         unix_to_nt_time_abs(&nt_logout, u_logout);
4578                         
4579                         init_unk_info3(&ctr->info.inf3, nt_logout);
4580                         break;
4581                 case 0x05:
4582                         init_unk_info5(&ctr->info.inf5, global_myname());
4583                         break;
4584                 case 0x06:
4585                         init_unk_info6(&ctr->info.inf6);
4586                         break;
4587                 case 0x07:
4588                         server_role = ROLE_DOMAIN_PDC;
4589                         if (lp_server_role() == ROLE_DOMAIN_BDC)
4590                                 server_role = ROLE_DOMAIN_BDC;
4591                         init_unk_info7(&ctr->info.inf7, server_role);
4592                         break;
4593                 case 0x08:
4594                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4595                         break;
4596                 case 0x0c:
4597                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4598                         u_lock_duration = account_policy_temp;
4599                         if (u_lock_duration != -1)
4600                                 u_lock_duration *= 60;
4601
4602                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4603                         u_reset_time = account_policy_temp * 60;
4604
4605                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4606                         lockout = account_policy_temp;
4607         
4608                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4609                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4610         
4611                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4612                         break;
4613                 default:
4614                         return NT_STATUS_INVALID_INFO_CLASS;
4615         }
4616
4617         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4618
4619         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4620
4621         return r_u->status;
4622 }
4623
4624 /*******************************************************************
4625  _samr_
4626  ********************************************************************/
4627
4628 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4629 {
4630         time_t u_expire, u_min_age;
4631         time_t u_logout;
4632         time_t u_lock_duration, u_reset_time;
4633
4634         r_u->status = NT_STATUS_OK;
4635
4636         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4637
4638         /* find the policy handle.  open a policy on it. */
4639         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4640                 return NT_STATUS_INVALID_HANDLE;
4641
4642         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4643
4644         switch (q_u->switch_value) {
4645                 case 0x01:
4646                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4647                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4648                         
4649                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4650                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4651                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4652                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4653                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4654                         break;
4655                 case 0x02:
4656                         break;
4657                 case 0x03:
4658                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4659                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4660                         break;
4661                 case 0x05:
4662                         break;
4663                 case 0x06:
4664                         break;
4665                 case 0x07:
4666                         break;
4667                 case 0x0c:
4668                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4669                         if (u_lock_duration != -1)
4670                                 u_lock_duration /= 60;
4671
4672                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4673                         
4674                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4675                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4676                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4677                         break;
4678                 default:
4679                         return NT_STATUS_INVALID_INFO_CLASS;
4680         }
4681
4682         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4683
4684         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4685
4686         return r_u->status;
4687 }