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