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