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