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