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