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