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