r2331: check password script code and example from trunk
[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(add_script));
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: