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