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