ce6d9dd37ec4f323d0dcbc15c8c5870f56844a60
[sfrench/samba-autobuild/.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison               2001-2002,
9  *  Copyright (C) Jean François Micouleau      1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003,
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 /*
29  * This is the implementation of the SAMR code.
30  */
31
32 #include "includes.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 extern DOM_SID global_sid_Builtin;
38
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
42
43
44 typedef struct _disp_info {
45         BOOL user_dbloaded;
46         uint32 num_user_account;
47         SAM_ACCOUNT *disp_user_info;
48         BOOL group_dbloaded;
49         uint32 num_group_account;
50         DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
52
53 struct samr_info {
54         /* for use by the \PIPE\samr policy */
55         DOM_SID sid;
56         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
57         uint32 acc_granted;
58         uint16 acb_mask;
59         BOOL all_machines;
60         DISP_INFO disp_info;
61
62         TALLOC_CTX *mem_ctx;
63 };
64
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
70
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
72
73 /*******************************************************************
74  Checks if access to an object should be granted, and returns that
75  level of access for further checks.
76 ********************************************************************/
77
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access, 
79                                   uint32 *acc_granted, const char *debug) 
80 {
81         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
82
83         if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84                 *acc_granted = des_access;
85                 if (geteuid() == sec_initial_uid()) {
86                         DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n",
87                                 debug, des_access));
88                         DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89                         status = NT_STATUS_OK;
90                 }
91                 else {
92                         DEBUG(2,("%s: ACCESS DENIED  (requested: %#010x)\n",
93                                 debug, des_access));
94                 }
95         }
96         return status;
97 }
98
99 /*******************************************************************
100  Checks if access to a function can be granted
101 ********************************************************************/
102
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 {
105         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
106                         debug, acc_granted, acc_required));
107         if ((acc_granted & acc_required) != acc_required) {
108                 if (geteuid() == sec_initial_uid()) {
109                         DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
110                                 debug, acc_granted, acc_required));
111                         DEBUGADD(4,("but overwritten by euid == 0\n"));
112                         return NT_STATUS_OK;
113                 }
114                 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
115                         debug, acc_granted, acc_required));
116                 return NT_STATUS_ACCESS_DENIED;
117         }
118         return NT_STATUS_OK;
119 }
120
121
122 /*******************************************************************
123  Create a samr_info struct.
124 ********************************************************************/
125
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 {
128         struct samr_info *info;
129         fstring sid_str;
130         TALLOC_CTX *mem_ctx;
131         
132         if (psid) {
133                 sid_to_string(sid_str, psid);
134         } else {
135                 fstrcpy(sid_str,"(NULL)");
136         }
137
138         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
139
140         if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141                 return NULL;
142
143         ZERO_STRUCTP(info);
144         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145         if (psid) {
146                 sid_copy( &info->sid, psid);
147         } else {
148                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149         }
150         info->mem_ctx = mem_ctx;
151         return info;
152 }
153
154 /*******************************************************************
155  Function to free the per handle data.
156  ********************************************************************/
157
158 static void free_samr_users(struct samr_info *info) 
159 {
160         int i;
161
162         if (info->disp_info.user_dbloaded){
163                 for (i=0; i<info->disp_info.num_user_account; i++) {
164                         SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165                         /* Not really a free, actually a 'clear' */
166                         pdb_free_sam(&sam);
167                 }
168         }
169         info->disp_info.user_dbloaded=False;
170         info->disp_info.num_user_account=0;
171 }
172
173 /*******************************************************************
174  Function to free the per handle data.
175  ********************************************************************/
176
177 static void free_samr_db(struct samr_info *info)
178 {
179         /* Groups are talloced */
180
181         free_samr_users(info);
182
183         info->disp_info.group_dbloaded=False;
184         info->disp_info.num_group_account=0;
185 }
186
187 static void free_samr_info(void *ptr)
188 {
189         struct samr_info *info=(struct samr_info *) ptr;
190
191         free_samr_db(info);
192         talloc_destroy(info->mem_ctx);
193 }
194
195 /*******************************************************************
196  Ensure password info is never given out. Paranioa... JRA.
197  ********************************************************************/
198
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
200 {
201         
202         if (!sam_pass)
203                 return;
204
205         /* These now zero out the old password */
206
207         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
209 }
210
211
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
213 {
214         SAM_ACCOUNT *pwd = NULL;
215         SAM_ACCOUNT *pwd_array = NULL;
216         NTSTATUS nt_status = NT_STATUS_OK;
217         TALLOC_CTX *mem_ctx = info->mem_ctx;
218
219         DEBUG(10,("load_sampwd_entries\n"));
220
221         /* if the snapshoot is already loaded, return */
222         if ((info->disp_info.user_dbloaded==True) 
223             && (info->acb_mask == acb_mask) 
224             && (info->all_machines == all_machines)) {
225                 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226                 return NT_STATUS_OK;
227         }
228
229         free_samr_users(info);
230
231         if (!pdb_setsampwent(False)) {
232                 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233                 return NT_STATUS_ACCESS_DENIED;
234         }
235
236         for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
237                      && pdb_getsampwent(pwd) == True; pwd=NULL) {
238                 
239                 if (all_machines) {
240                         if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
241                               || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242                                 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243                                 pdb_free_sam(&pwd);
244                                 continue;
245                         }
246                 } else {
247                         if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248                                 pdb_free_sam(&pwd);
249                                 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250                                 continue;
251                         }
252                 }
253
254                 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255                 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
256                 
257                         DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258                         pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info, 
259                                           (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
260
261                         if (pwd_array==NULL)
262                                 return NT_STATUS_NO_MEMORY;
263
264                         info->disp_info.disp_user_info=pwd_array;
265                 }
266         
267                 /* Copy the SAM_ACCOUNT into the array */
268                 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
269
270                 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
271
272                 info->disp_info.num_user_account++;     
273         }
274
275         pdb_endsampwent();
276
277         /* the snapshoot is in memory, we're ready to enumerate fast */
278
279         info->acb_mask = acb_mask;
280         info->all_machines = all_machines;
281         info->disp_info.user_dbloaded=True;
282
283         DEBUG(10,("load_sampwd_entries: done\n"));
284
285         return nt_status;
286 }
287
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
289 {
290         GROUP_MAP *map=NULL;
291         DOMAIN_GRP *grp_array = NULL;
292         uint32 group_entries = 0;
293         uint32 i;
294         TALLOC_CTX *mem_ctx = info->mem_ctx;
295         BOOL ret;
296
297         DEBUG(10,("load_group_domain_entries\n"));
298
299         /* if the snapshoot is already loaded, return */
300         if (info->disp_info.group_dbloaded==True) {
301                 DEBUG(10,("load_group_domain_entries: already in memory\n"));
302                 return NT_STATUS_OK;
303         }
304         
305         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         for (i=0; i<*num; i++) {
3249                 if ((*uids)[i] == uid)
3250                         return;
3251         }
3252         
3253         *uids = Realloc(*uids, (*num+1) * sizeof(uid_t));
3254
3255         if (*uids == NULL)
3256                 return;
3257
3258         (*uids)[*num] = uid;
3259         *num += 1;
3260 }
3261
3262
3263 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3264 {
3265         struct group *grp;
3266         char **gr;
3267         struct sys_pwent *userlist, *user;
3268  
3269         *uids = NULL;
3270         *num = 0;
3271
3272         /* We only look at our own sam, so don't care about imported stuff */
3273
3274         winbind_off();
3275
3276         if ((grp = getgrgid(gid)) == NULL) {
3277                 winbind_on();
3278                 return False;
3279         }
3280
3281         /* Primary group members */
3282
3283         userlist = getpwent_list();
3284
3285         for (user = userlist; user != NULL; user = user->next) {
3286                 if (user->pw_gid != gid)
3287                         continue;
3288                 add_uid_to_array_unique(user->pw_uid, uids, num);
3289         }
3290
3291         pwent_free(userlist);
3292
3293         /* Secondary group members */
3294
3295         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3296                 struct passwd *pw = getpwnam(*gr);
3297
3298                 if (pw == NULL)
3299                         continue;
3300                 add_uid_to_array_unique(pw->pw_uid, uids, num);
3301         }
3302
3303         winbind_on();
3304
3305         return True;
3306 }       
3307
3308 /*********************************************************************
3309  _samr_query_groupmem
3310 *********************************************************************/
3311
3312 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3313 {
3314         int final_num_rids, i;
3315         DOM_SID group_sid;
3316         fstring group_sid_str;
3317         uid_t *uids;
3318         int num;
3319         gid_t gid;
3320
3321         uint32 *rid=NULL;
3322         uint32 *attr=NULL;
3323
3324         uint32 acc_granted;
3325
3326         /* find the policy handle.  open a policy on it. */
3327         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3328                 return NT_STATUS_INVALID_HANDLE;
3329                 
3330         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3331                 return r_u->status;
3332         }
3333                 
3334         sid_to_string(group_sid_str, &group_sid);
3335         DEBUG(10, ("sid is %s\n", group_sid_str));
3336
3337         if (!sid_check_is_in_our_domain(&group_sid)) {
3338                 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3339                 return NT_STATUS_NO_SUCH_GROUP;
3340         }
3341
3342         DEBUG(10, ("lookup on Domain SID\n"));
3343
3344         if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3345                 return NT_STATUS_NO_SUCH_GROUP;
3346
3347         if(!get_memberuids(gid, &uids, &num))
3348                 return NT_STATUS_NO_SUCH_GROUP;
3349
3350         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3351         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num);
3352         
3353         if (num!=0 && (rid==NULL || attr==NULL))
3354                 return NT_STATUS_NO_MEMORY;
3355         
3356         final_num_rids = 0;
3357                 
3358         for (i=0; i<num; i++) {
3359                 DOM_SID sid;
3360
3361                 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3362                         DEBUG(1, ("Could not map member uid to SID\n"));
3363                         continue;
3364                 }
3365
3366                 if (!sid_check_is_in_our_domain(&sid)) {
3367                         DEBUG(1, ("Inconsistent SAM -- group member uid not "
3368                                   "in our domain\n"));
3369                         continue;
3370                 }
3371
3372                 sid_peek_rid(&sid, &rid[final_num_rids]);
3373
3374                 /* Hmm. In a trace I got the constant 7 here from NT. */
3375                 attr[final_num_rids] = SID_NAME_USER;
3376
3377                 final_num_rids += 1;
3378         }
3379
3380         SAFE_FREE(uids);
3381
3382         init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3383                                    NT_STATUS_OK);
3384
3385         return NT_STATUS_OK;
3386 }
3387
3388 /*********************************************************************
3389  _samr_add_aliasmem
3390 *********************************************************************/
3391
3392 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3393 {
3394         DOM_SID alias_sid;
3395         uint32 acc_granted;
3396
3397         /* Find the policy handle. Open a policy on it. */
3398         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3399                 return NT_STATUS_INVALID_HANDLE;
3400         
3401         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3402                 return r_u->status;
3403         }
3404                 
3405         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3406
3407         if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3408                 return NT_STATUS_ACCESS_DENIED;
3409
3410         return NT_STATUS_OK;
3411 }
3412
3413 /*********************************************************************
3414  _samr_del_aliasmem
3415 *********************************************************************/
3416
3417 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3418 {
3419         DOM_SID alias_sid;
3420         uint32 acc_granted;
3421
3422         /* Find the policy handle. Open a policy on it. */
3423         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3424                 return NT_STATUS_INVALID_HANDLE;
3425         
3426         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3427                 return r_u->status;
3428         }
3429         
3430         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3431                    sid_string_static(&alias_sid)));
3432
3433         if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3434                 return NT_STATUS_ACCESS_DENIED;
3435         
3436         return NT_STATUS_OK;
3437 }
3438
3439 /*********************************************************************
3440  _samr_add_groupmem
3441 *********************************************************************/
3442
3443 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3444 {
3445         DOM_SID group_sid;
3446         DOM_SID user_sid;
3447         fstring group_sid_str;
3448         uid_t uid;
3449         struct passwd *pwd;
3450         struct group *grp;
3451         fstring grp_name;
3452         GROUP_MAP map;
3453         NTSTATUS ret;
3454         SAM_ACCOUNT *sam_user=NULL;
3455         BOOL check;
3456         uint32 acc_granted;
3457
3458         /* Find the policy handle. Open a policy on it. */
3459         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3460                 return NT_STATUS_INVALID_HANDLE;
3461         
3462         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3463                 return r_u->status;
3464         }
3465
3466         sid_to_string(group_sid_str, &group_sid);
3467         DEBUG(10, ("sid is %s\n", group_sid_str));
3468
3469         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3470                 return NT_STATUS_NO_SUCH_GROUP;
3471
3472         DEBUG(10, ("lookup on Domain SID\n"));
3473
3474         if(!get_domain_group_from_sid(group_sid, &map))
3475                 return NT_STATUS_NO_SUCH_GROUP;
3476
3477         sid_copy(&user_sid, get_global_sam_sid());
3478         sid_append_rid(&user_sid, q_u->rid);
3479
3480         ret = pdb_init_sam(&sam_user);
3481         if (!NT_STATUS_IS_OK(ret))
3482                 return ret;
3483         
3484         check = pdb_getsampwsid(sam_user, &user_sid);
3485         
3486         if (check != True) {
3487                 pdb_free_sam(&sam_user);
3488                 return NT_STATUS_NO_SUCH_USER;
3489         }
3490
3491         /* check a real user exist before we run the script to add a user to a group */
3492         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3493                 pdb_free_sam(&sam_user);
3494                 return NT_STATUS_NO_SUCH_USER;
3495         }
3496
3497         pdb_free_sam(&sam_user);
3498
3499         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3500                 return NT_STATUS_NO_SUCH_USER;
3501         }
3502
3503         if ((grp=getgrgid(map.gid)) == NULL) {
3504                 passwd_free(&pwd);
3505                 return NT_STATUS_NO_SUCH_GROUP;
3506         }
3507
3508         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3509         fstrcpy(grp_name, grp->gr_name);
3510
3511         /* if the user is already in the group */
3512         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3513                 passwd_free(&pwd);
3514                 return NT_STATUS_MEMBER_IN_GROUP;
3515         }
3516
3517         /* 
3518          * ok, the group exist, the user exist, the user is not in the group,
3519          *
3520          * we can (finally) add it to the group !
3521          */
3522
3523         smb_add_user_group(grp_name, pwd->pw_name);
3524
3525         /* check if the user has been added then ... */
3526         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3527                 passwd_free(&pwd);
3528                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3529         }
3530
3531         passwd_free(&pwd);
3532         return NT_STATUS_OK;
3533 }
3534
3535 /*********************************************************************
3536  _samr_del_groupmem
3537 *********************************************************************/
3538
3539 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3540 {
3541         DOM_SID group_sid;
3542         DOM_SID user_sid;
3543         SAM_ACCOUNT *sam_pass=NULL;
3544         GROUP_MAP map;
3545         fstring grp_name;
3546         struct group *grp;
3547         uint32 acc_granted;
3548
3549         /*
3550          * delete the group member named q_u->rid
3551          * who is a member of the sid associated with the handle
3552          * the rid is a user's rid as the group is a domain group.
3553          */
3554
3555         /* Find the policy handle. Open a policy on it. */
3556         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3557                 return NT_STATUS_INVALID_HANDLE;
3558         
3559         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3560                 return r_u->status;
3561         }
3562                 
3563         if (!sid_check_is_in_our_domain(&group_sid))
3564                 return NT_STATUS_NO_SUCH_GROUP;
3565
3566         sid_copy(&user_sid, get_global_sam_sid());
3567         sid_append_rid(&user_sid, q_u->rid);
3568
3569         if (!get_domain_group_from_sid(group_sid, &map))
3570                 return NT_STATUS_NO_SUCH_GROUP;
3571
3572         if ((grp=getgrgid(map.gid)) == NULL)
3573                 return NT_STATUS_NO_SUCH_GROUP;
3574
3575         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3576         fstrcpy(grp_name, grp->gr_name);
3577
3578         /* check if the user exists before trying to remove it from the group */
3579         pdb_init_sam(&sam_pass);
3580         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3581                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3582                 pdb_free_sam(&sam_pass);
3583                 return NT_STATUS_NO_SUCH_USER;
3584         }
3585
3586         /* if the user is not in the group */
3587         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3588                 pdb_free_sam(&sam_pass);
3589                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3590         }
3591
3592         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3593
3594         /* check if the user has been removed then ... */
3595         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3596                 pdb_free_sam(&sam_pass);
3597                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3598         }
3599         
3600         pdb_free_sam(&sam_pass);
3601         return NT_STATUS_OK;
3602
3603 }
3604
3605 /****************************************************************************
3606  Delete a UNIX user on demand.
3607 ****************************************************************************/
3608
3609 static int smb_delete_user(const char *unix_user)
3610 {
3611         pstring del_script;
3612         int ret;
3613
3614         /* try winbindd first since it is impossible to determine where 
3615            a user came from via NSS.  Try the delete user script if this fails
3616            meaning the user did not exist in winbindd's list of accounts */
3617
3618         if ( winbind_delete_user( unix_user ) ) {
3619                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3620                 return 0;
3621         }
3622
3623
3624         /* fall back to 'delete user script' */
3625
3626         pstrcpy(del_script, lp_deluser_script());
3627         if (! *del_script)
3628                 return -1;
3629         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3630         ret = smbrun(del_script,NULL);
3631         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3632
3633         return ret;
3634 }
3635
3636 /*********************************************************************
3637  _samr_delete_dom_user
3638 *********************************************************************/
3639
3640 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3641 {
3642         DOM_SID user_sid;
3643         SAM_ACCOUNT *sam_pass=NULL;
3644         uint32 acc_granted;
3645
3646         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3647
3648         /* Find the policy handle. Open a policy on it. */
3649         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3650                 return NT_STATUS_INVALID_HANDLE;
3651                 
3652         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3653                 return r_u->status;
3654         }
3655                 
3656         if (!sid_check_is_in_our_domain(&user_sid))
3657                 return NT_STATUS_CANNOT_DELETE;
3658
3659         /* check if the user exists before trying to delete */
3660         pdb_init_sam(&sam_pass);
3661         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3662                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3663                         sid_string_static(&user_sid)));
3664                 pdb_free_sam(&sam_pass);
3665                 return NT_STATUS_NO_SUCH_USER;
3666         }
3667
3668         /* delete the unix side */
3669         /*
3670          * note: we don't check if the delete really happened
3671          * as the script is not necessary present
3672          * and maybe the sysadmin doesn't want to delete the unix side
3673          */
3674         smb_delete_user(pdb_get_username(sam_pass));
3675
3676         /* and delete the samba side */
3677         if (!pdb_delete_sam_account(sam_pass)) {
3678                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3679                 pdb_free_sam(&sam_pass);
3680                 return NT_STATUS_CANNOT_DELETE;
3681         }
3682         
3683         pdb_free_sam(&sam_pass);
3684
3685         if (!close_policy_hnd(p, &q_u->user_pol))
3686                 return NT_STATUS_OBJECT_NAME_INVALID;
3687
3688         return NT_STATUS_OK;
3689 }
3690
3691 /*********************************************************************
3692  _samr_delete_dom_group
3693 *********************************************************************/
3694
3695 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3696 {
3697         DOM_SID group_sid;
3698         DOM_SID dom_sid;
3699         uint32 group_rid;
3700         fstring group_sid_str;
3701         gid_t gid;
3702         struct group *grp;
3703         GROUP_MAP map;
3704         uint32 acc_granted;
3705
3706         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3707
3708         /* Find the policy handle. Open a policy on it. */
3709         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3710                 return NT_STATUS_INVALID_HANDLE;
3711                 
3712         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3713                 return r_u->status;
3714         }
3715                 
3716         sid_copy(&dom_sid, &group_sid);
3717         sid_to_string(group_sid_str, &dom_sid);
3718         sid_split_rid(&dom_sid, &group_rid);
3719
3720         DEBUG(10, ("sid is %s\n", group_sid_str));
3721
3722         /* we check if it's our SID before deleting */
3723         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3724                 return NT_STATUS_NO_SUCH_GROUP;
3725
3726         DEBUG(10, ("lookup on Domain SID\n"));
3727
3728         if(!get_domain_group_from_sid(group_sid, &map))
3729                 return NT_STATUS_NO_SUCH_GROUP;
3730
3731         gid=map.gid;
3732
3733         /* check if group really exists */
3734         if ( (grp=getgrgid(gid)) == NULL)
3735                 return NT_STATUS_NO_SUCH_GROUP;
3736
3737         /* delete mapping first */
3738         if(!pdb_delete_group_mapping_entry(group_sid))
3739                 return NT_STATUS_ACCESS_DENIED;
3740                 
3741         /* we can delete the UNIX group */
3742         smb_delete_group(grp->gr_name);
3743
3744         /* check if the group has been successfully deleted */
3745         if ( (grp=getgrgid(gid)) != NULL)
3746                 return NT_STATUS_ACCESS_DENIED;
3747
3748
3749         if (!close_policy_hnd(p, &q_u->group_pol))
3750                 return NT_STATUS_OBJECT_NAME_INVALID;
3751
3752         return NT_STATUS_OK;
3753 }
3754
3755 /*********************************************************************
3756  _samr_delete_dom_alias
3757 *********************************************************************/
3758
3759 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3760 {
3761         DOM_SID alias_sid;
3762         uint32 acc_granted;
3763
3764         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3765
3766         /* Find the policy handle. Open a policy on it. */
3767         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3768                 return NT_STATUS_INVALID_HANDLE;
3769         
3770         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3771                 return r_u->status;
3772         }
3773
3774         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3775
3776         if (!sid_check_is_in_our_domain(&alias_sid))
3777                 return NT_STATUS_NO_SUCH_ALIAS;
3778                 
3779         DEBUG(10, ("lookup on Local SID\n"));
3780
3781         /* Have passdb delete the alias */
3782         if (!pdb_delete_alias(&alias_sid))
3783                 return NT_STATUS_ACCESS_DENIED;
3784
3785         if (!close_policy_hnd(p, &q_u->alias_pol))
3786                 return NT_STATUS_OBJECT_NAME_INVALID;
3787
3788         return NT_STATUS_OK;
3789 }
3790
3791 /*********************************************************************
3792  _samr_create_dom_group
3793 *********************************************************************/
3794
3795 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3796 {
3797         DOM_SID dom_sid;
3798         DOM_SID info_sid;
3799         fstring name;
3800         fstring sid_string;
3801         struct group *grp;
3802         struct samr_info *info;
3803         uint32 acc_granted;
3804         gid_t gid;
3805
3806         /* Find the policy handle. Open a policy on it. */
3807         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3808                 return NT_STATUS_INVALID_HANDLE;
3809         
3810         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3811                 return r_u->status;
3812         }
3813                 
3814         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3815                 return NT_STATUS_ACCESS_DENIED;
3816
3817         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3818
3819         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3820
3821         /* check if group already exist */
3822         if ((grp=getgrnam(name)) != NULL)
3823                 return NT_STATUS_GROUP_EXISTS;
3824
3825         /* we can create the UNIX group */
3826         if (smb_create_group(name, &gid) != 0)
3827                 return NT_STATUS_ACCESS_DENIED;
3828
3829         /* check if the group has been successfully created */
3830         if ((grp=getgrgid(gid)) == NULL)
3831                 return NT_STATUS_ACCESS_DENIED;
3832
3833         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3834
3835         /* add the group to the mapping table */
3836         sid_copy(&info_sid, get_global_sam_sid());
3837         sid_append_rid(&info_sid, r_u->rid);
3838         sid_to_string(sid_string, &info_sid);
3839
3840         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3841                 return NT_STATUS_ACCESS_DENIED;
3842
3843         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3844                 return NT_STATUS_NO_MEMORY;
3845
3846         /* get a (unique) handle.  open a policy on it. */
3847         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3848                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3849
3850         return NT_STATUS_OK;
3851 }
3852
3853 /*********************************************************************
3854  _samr_create_dom_alias
3855 *********************************************************************/
3856
3857 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3858 {
3859         DOM_SID dom_sid;
3860         DOM_SID info_sid;
3861         fstring name;
3862         struct group *grp;
3863         struct samr_info *info;
3864         uint32 acc_granted;
3865         gid_t gid;
3866         NTSTATUS result;
3867
3868         /* Find the policy handle. Open a policy on it. */
3869         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3870                 return NT_STATUS_INVALID_HANDLE;
3871                 
3872         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3873                 return r_u->status;
3874         }
3875                 
3876         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3877                 return NT_STATUS_ACCESS_DENIED;
3878
3879         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3880
3881         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3882
3883         /* Have passdb create the alias */
3884         result = pdb_create_alias(name, &r_u->rid);
3885
3886         if (!NT_STATUS_IS_OK(result))
3887                 return result;
3888
3889         sid_copy(&info_sid, get_global_sam_sid());
3890         sid_append_rid(&info_sid, r_u->rid);
3891
3892         if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3893                 return NT_STATUS_ACCESS_DENIED;
3894
3895         /* check if the group has been successfully created */
3896         if ((grp=getgrgid(gid)) == NULL)
3897                 return NT_STATUS_ACCESS_DENIED;
3898
3899         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3900                 return NT_STATUS_NO_MEMORY;
3901
3902         /* get a (unique) handle.  open a policy on it. */
3903         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3904                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3905
3906         return NT_STATUS_OK;
3907 }
3908
3909 /*********************************************************************
3910  _samr_query_groupinfo
3911
3912 sends the name/comment pair of a domain group
3913 level 1 send also the number of users of that group
3914 *********************************************************************/
3915
3916 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3917 {
3918         DOM_SID group_sid;
3919         GROUP_MAP map;
3920         DOM_SID *sids=NULL;
3921         uid_t *uids;
3922         int num=0;
3923         GROUP_INFO_CTR *ctr;
3924         uint32 acc_granted;
3925         BOOL ret;
3926
3927         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3928                 return NT_STATUS_INVALID_HANDLE;
3929         
3930         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3931                 return r_u->status;
3932         }
3933                 
3934         become_root();
3935         ret = get_domain_group_from_sid(group_sid, &map);
3936         unbecome_root();
3937         if (!ret)
3938                 return NT_STATUS_INVALID_HANDLE;
3939
3940         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3941         if (ctr==NULL)
3942                 return NT_STATUS_NO_MEMORY;
3943
3944         switch (q_u->switch_level) {
3945                 case 1:
3946                         ctr->switch_value1 = 1;
3947                         if(!get_memberuids(map.gid, &uids, &num))
3948                                 return NT_STATUS_NO_SUCH_GROUP;
3949                         SAFE_FREE(uids);
3950                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3951                         SAFE_FREE(sids);
3952                         break;
3953                 case 3:
3954                         ctr->switch_value1 = 3;
3955                         init_samr_group_info3(&ctr->group.info3);
3956                         break;
3957                 case 4:
3958                         ctr->switch_value1 = 4;
3959                         init_samr_group_info4(&ctr->group.info4, map.comment);
3960                         break;
3961                 default:
3962                         return NT_STATUS_INVALID_INFO_CLASS;
3963         }
3964
3965         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3966
3967         return NT_STATUS_OK;
3968 }
3969
3970 /*********************************************************************
3971  _samr_set_groupinfo
3972  
3973  update a domain group's comment.
3974 *********************************************************************/
3975
3976 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3977 {
3978         DOM_SID group_sid;
3979         GROUP_MAP map;
3980         GROUP_INFO_CTR *ctr;
3981         uint32 acc_granted;
3982
3983         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3984                 return NT_STATUS_INVALID_HANDLE;
3985         
3986         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
3987                 return r_u->status;
3988         }
3989                 
3990         if (!get_domain_group_from_sid(group_sid, &map))
3991                 return NT_STATUS_NO_SUCH_GROUP;
3992         
3993         ctr=q_u->ctr;
3994
3995         switch (ctr->switch_value1) {
3996                 case 1:
3997                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
3998                         break;
3999                 case 4:
4000                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4001                         break;
4002                 default:
4003                         return NT_STATUS_INVALID_INFO_CLASS;
4004         }
4005
4006         if(!pdb_update_group_mapping_entry(&map)) {
4007                 return NT_STATUS_NO_SUCH_GROUP;
4008         }
4009
4010         return NT_STATUS_OK;
4011 }
4012
4013 /*********************************************************************
4014  _samr_set_aliasinfo
4015  
4016  update an alias's comment.
4017 *********************************************************************/
4018
4019 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4020 {
4021         DOM_SID group_sid;
4022         struct acct_info info;
4023         ALIAS_INFO_CTR *ctr;
4024         uint32 acc_granted;
4025
4026         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4027                 return NT_STATUS_INVALID_HANDLE;
4028         
4029         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4030                 return r_u->status;
4031         }
4032                 
4033         ctr=&q_u->ctr;
4034
4035         switch (ctr->switch_value1) {
4036                 case 3:
4037                         unistr2_to_ascii(info.acct_desc,
4038                                          &(ctr->alias.info3.uni_acct_desc),
4039                                          sizeof(info.acct_desc)-1);
4040                         break;
4041                 default:
4042                         return NT_STATUS_INVALID_INFO_CLASS;
4043         }
4044
4045         if(!pdb_set_aliasinfo(&group_sid, &info)) {
4046                 return NT_STATUS_ACCESS_DENIED;
4047         }
4048
4049         return NT_STATUS_OK;
4050 }
4051
4052 /*********************************************************************
4053  _samr_get_dom_pwinfo
4054 *********************************************************************/
4055
4056 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4057 {
4058         /* Perform access check.  Since this rpc does not require a
4059            policy handle it will not be caught by the access checks on
4060            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4061
4062         if (!pipe_access_check(p)) {
4063                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4064                 r_u->status = NT_STATUS_ACCESS_DENIED;
4065                 return r_u->status;
4066         }
4067
4068         /* Actually, returning zeros here works quite well :-). */
4069
4070         return NT_STATUS_OK;
4071 }
4072
4073 /*********************************************************************
4074  _samr_open_group
4075 *********************************************************************/
4076
4077 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4078 {
4079         DOM_SID sid;
4080         DOM_SID info_sid;
4081         GROUP_MAP map;
4082         struct samr_info *info;
4083         SEC_DESC         *psd = NULL;
4084         uint32            acc_granted;
4085         uint32            des_access = q_u->access_mask;
4086         size_t            sd_size;
4087         NTSTATUS          status;
4088         fstring sid_string;
4089         BOOL ret;
4090
4091         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4092                 return NT_STATUS_INVALID_HANDLE;
4093         
4094         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4095                 return status;
4096         }
4097                 
4098         /*check if access can be granted as requested by client. */
4099         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4100         se_map_generic(&des_access,&grp_generic_mapping);
4101         if (!NT_STATUS_IS_OK(status = 
4102                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4103                                                       des_access, &acc_granted, "_samr_open_group"))) {
4104                 return status;
4105         }
4106
4107
4108         /* this should not be hard-coded like this */
4109         if (!sid_equal(&sid, get_global_sam_sid()))
4110                 return NT_STATUS_ACCESS_DENIED;
4111
4112         sid_copy(&info_sid, get_global_sam_sid());
4113         sid_append_rid(&info_sid, q_u->rid_group);
4114         sid_to_string(sid_string, &info_sid);
4115
4116         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4117                 return NT_STATUS_NO_MEMORY;
4118                 
4119         info->acc_granted = acc_granted;
4120
4121         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4122
4123         /* check if that group really exists */
4124         become_root();
4125         ret = get_domain_group_from_sid(info->sid, &map);
4126         unbecome_root();
4127         if (!ret)
4128                 return NT_STATUS_NO_SUCH_GROUP;
4129
4130         /* get a (unique) handle.  open a policy on it. */
4131         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4132                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4133
4134         return NT_STATUS_OK;
4135 }
4136
4137 /*********************************************************************
4138  _samr_remove_sid_foreign_domain
4139 *********************************************************************/
4140
4141 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4142                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4143                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4144 {
4145         DOM_SID                 delete_sid, alias_sid;
4146         SAM_ACCOUNT             *sam_pass=NULL;
4147         uint32                  acc_granted;
4148         GROUP_MAP               map;
4149         BOOL                    is_user = False;
4150         NTSTATUS                result;
4151         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4152         
4153         sid_copy( &delete_sid, &q_u->sid.sid );
4154         
4155         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4156                 sid_string_static(&delete_sid)));
4157                 
4158         /* Find the policy handle. Open a policy on it. */
4159         
4160         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4161                 return NT_STATUS_INVALID_HANDLE;
4162         
4163         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4164                 "_samr_remove_sid_foreign_domain");
4165                 
4166         if (!NT_STATUS_IS_OK(result)) 
4167                 return result;
4168                         
4169         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4170                 sid_string_static(&alias_sid)));
4171                 
4172         /* make sure we can handle this */
4173         
4174         if ( sid_check_is_domain(&alias_sid) )
4175                 type = SID_NAME_DOM_GRP;
4176         else if ( sid_check_is_builtin(&alias_sid) )
4177                 type = SID_NAME_ALIAS;
4178         
4179         if ( type == SID_NAME_UNKNOWN ) {
4180                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4181                 return NT_STATUS_OK;
4182         }
4183
4184         /* check if the user exists before trying to delete */
4185         
4186         pdb_init_sam(&sam_pass);
4187         
4188         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4189                 is_user = True;
4190         } else {
4191                 /* maybe it is a group */
4192                 if( !pdb_getgrsid(&map, delete_sid) ) {
4193                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4194                                 sid_string_static(&delete_sid)));
4195                         result = NT_STATUS_INVALID_SID;
4196                         goto done;
4197                 }
4198         }
4199         
4200         /* we can only delete a user from a group since we don't have 
4201            nested groups anyways.  So in the latter case, just say OK */
4202            
4203         if ( is_user ) {
4204                 GROUP_MAP       *mappings = NULL;
4205                 int             num_groups, i;
4206                 struct group    *grp2;
4207                 
4208                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4209                 
4210                         /* interate over the groups */
4211                         for ( i=0; i<num_groups; i++ ) {
4212
4213                                 grp2 = getgrgid(mappings[i].gid);
4214
4215                                 if ( !grp2 ) {
4216                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4217                                         continue;
4218                                 }
4219                         
4220                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4221                                         continue;
4222                                 
4223                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4224                                 
4225                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4226                                         /* should we fail here ? */
4227                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4228                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4229                                         continue;
4230                                 }
4231                                         
4232                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4233                                         pdb_get_username(sam_pass), grp2->gr_name ));
4234                         }
4235                         
4236                         SAFE_FREE(mappings);
4237                 }
4238         }
4239         
4240         result = NT_STATUS_OK;
4241 done:
4242
4243         pdb_free_sam(&sam_pass);
4244
4245         return result;
4246 }
4247
4248 /*******************************************************************
4249  _samr_unknown_2e
4250  ********************************************************************/
4251
4252 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4253 {
4254         struct samr_info *info = NULL;
4255         SAM_UNK_CTR *ctr;
4256         uint32 min_pass_len,pass_hist,flag;
4257         time_t u_expire, u_min_age;
4258         NTTIME nt_expire, nt_min_age;
4259
4260         time_t u_lock_duration, u_reset_time;
4261         NTTIME nt_lock_duration, nt_reset_time;
4262         uint32 lockout;
4263         
4264         time_t u_logout;
4265         NTTIME nt_logout;
4266
4267         uint32 num_users=0, num_groups=0, num_aliases=0;
4268
4269         uint32 account_policy_temp;
4270
4271         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4272                 return NT_STATUS_NO_MEMORY;
4273
4274         ZERO_STRUCTP(ctr);
4275
4276         r_u->status = NT_STATUS_OK;
4277
4278         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4279
4280         /* find the policy handle.  open a policy on it. */
4281         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4282                 return NT_STATUS_INVALID_HANDLE;
4283
4284         switch (q_u->switch_value) {
4285                 case 0x01:
4286                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4287                         min_pass_len = account_policy_temp;
4288
4289                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4290                         pass_hist = account_policy_temp;
4291
4292                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4293                         flag = account_policy_temp;
4294
4295                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4296                         u_expire = account_policy_temp;
4297
4298                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4299                         u_min_age = account_policy_temp;
4300
4301                         unix_to_nt_time_abs(&nt_expire, u_expire);
4302                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4303
4304                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4305                                        flag, nt_expire, nt_min_age);
4306                         break;
4307                 case 0x02:
4308                         become_root();          
4309                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4310                         unbecome_root();
4311                         if (!NT_STATUS_IS_OK(r_u->status)) {
4312                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4313                                 return r_u->status;
4314                         }
4315                         num_users=info->disp_info.num_user_account;
4316                         free_samr_db(info);
4317                         
4318                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4319                         if (NT_STATUS_IS_ERR(r_u->status)) {
4320                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4321                                 return r_u->status;
4322                         }
4323                         num_groups=info->disp_info.num_group_account;
4324                         free_samr_db(info);
4325
4326                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4327                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4328                                        num_users, num_groups, num_aliases);
4329                         break;
4330                 case 0x03:
4331                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4332                         u_logout = account_policy_temp;
4333
4334                         unix_to_nt_time_abs(&nt_logout, u_logout);
4335                         
4336                         init_unk_info3(&ctr->info.inf3, nt_logout);
4337                         break;
4338                 case 0x05:
4339                         init_unk_info5(&ctr->info.inf5, global_myname());
4340                         break;
4341                 case 0x06:
4342                         init_unk_info6(&ctr->info.inf6);
4343                         break;
4344                 case 0x07:
4345                         init_unk_info7(&ctr->info.inf7);
4346                         break;
4347                 case 0x0c:
4348                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4349                         u_lock_duration = account_policy_temp * 60;
4350
4351                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4352                         u_reset_time = account_policy_temp * 60;
4353
4354                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4355                         lockout = account_policy_temp;
4356         
4357                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4358                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4359         
4360                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4361                         break;
4362                 default:
4363                         return NT_STATUS_INVALID_INFO_CLASS;
4364         }
4365
4366         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4367
4368         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4369
4370         return r_u->status;
4371 }
4372
4373 /*******************************************************************
4374  _samr_
4375  ********************************************************************/
4376
4377 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4378 {
4379         time_t u_expire, u_min_age;
4380         time_t u_logout;
4381         time_t u_lock_duration, u_reset_time;
4382
4383         r_u->status = NT_STATUS_OK;
4384
4385         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4386
4387         /* find the policy handle.  open a policy on it. */
4388         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4389                 return NT_STATUS_INVALID_HANDLE;
4390
4391         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4392
4393         switch (q_u->switch_value) {
4394                 case 0x01:
4395                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4396                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4397                         
4398                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4399                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4400                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4401                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4402                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4403                         break;
4404                 case 0x02:
4405                         break;
4406                 case 0x03:
4407                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4408                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4409                         break;
4410                 case 0x05:
4411                         break;
4412                 case 0x06:
4413                         break;
4414                 case 0x07:
4415                         break;
4416                 case 0x0c:
4417                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4418                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4419                         
4420                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4421                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4422                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4423                         break;
4424                 default:
4425                         return NT_STATUS_INVALID_INFO_CLASS;
4426         }
4427
4428         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4429
4430         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4431
4432         return r_u->status;
4433 }