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