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