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