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