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