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