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