4c3f95fe6b8480e1fa2ea90d145645fa5d17a1e6
[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
2220         /* Get the domain SID stored in the domain policy */
2221         if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2222                 return NT_STATUS_INVALID_HANDLE;
2223
2224         if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2225                 return nt_status;
2226         }
2227
2228         if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) { 
2229                 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if 
2230                    this parameter is not an account type */
2231                 return NT_STATUS_INVALID_PARAMETER;
2232         }
2233
2234         /* find the account: tell the caller if it exists.
2235           lkclXXXX i have *no* idea if this is a problem or not
2236           or even if you are supposed to construct a different
2237           reply if the account already exists...
2238          */
2239
2240         rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2241         strlower_m(account);
2242         
2243         /* check to see if we are a domain admin */
2244         
2245         can_add_machines = user_has_privilege( p->pipe_user.nt_user_token, SE_MACHINE_ACCOUNT );
2246         
2247         DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
2248                 p->pipe_user_name, can_add_machines ? "" : " not"));
2249
2250         pdb_init_sam(&sam_pass);
2251
2252         become_root();
2253         ret = pdb_getsampwnam(sam_pass, account);
2254         unbecome_root();
2255         if (ret == True) {
2256                 /* this account exists: say so */
2257                 pdb_free_sam(&sam_pass);
2258                 return NT_STATUS_USER_EXISTS;
2259         }
2260
2261         pdb_free_sam(&sam_pass);
2262
2263         /*
2264          * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2265          * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2266          * that only people with write access to the smbpasswd file will be able
2267          * to create a user. JRA.
2268          */   
2269         
2270         /*********************************************************************
2271          * HEADS UP!  If we have to create a new user account, we have to get 
2272          * a new RID from somewhere.  This used to be done by the passdb 
2273          * backend. It has been moved into idmap now.  Since idmap is now 
2274          * wrapped up behind winbind, this means you have to run winbindd if you
2275          * want new accounts to get a new RID when "enable rid algorithm = no".
2276          * Tough.  We now have a uniform way of allocating RIDs regardless
2277          * of what ever passdb backend people may use.
2278          *                                             --jerry (2003-07-10)
2279          *********************************************************************/
2280         
2281         pw = Get_Pwnam(account);
2282         
2283         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
2284         
2285         if ( can_add_machines )                         
2286                 become_root();
2287         
2288         if ( !pw ) {
2289                 /* 
2290                  * we can't check both the ending $ and the acb_info.
2291                  * 
2292                  * UserManager creates trust accounts (ending in $,
2293                  * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2294                  * JFM, 11/29/2001
2295                  */
2296                 if (account[strlen(account)-1] == '$')
2297                         pstrcpy(add_script, lp_addmachine_script());            
2298                 else 
2299                         pstrcpy(add_script, lp_adduser_script());
2300
2301                 if (*add_script) {
2302                         int add_ret;
2303                         all_string_sub(add_script, "%u", account, sizeof(add_script));
2304                         add_ret = smbrun(add_script,NULL);
2305                         DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2306                 }
2307                 else    /* no add user script -- ask winbindd to do it */
2308                 {
2309                         if ( !winbind_create_user( account, &new_rid ) ) {
2310                                 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n", 
2311                                         account));
2312                         }
2313                 }
2314                 
2315         }
2316         
2317         /* implicit call to getpwnam() next.  we have a valid SID coming out of this call */
2318
2319         if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) ) {
2320                 if ( can_add_machines )
2321                         unbecome_root();
2322                 return nt_status;
2323         }
2324                 
2325         pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2326         
2327         ret = pdb_add_sam_account(sam_pass);
2328         
2329         if ( can_add_machines )                         
2330                 unbecome_root();
2331                 
2332         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
2333
2334         if ( !ret ) {
2335                 pdb_free_sam(&sam_pass);
2336                 DEBUG(0, ("could not add user/computer %s to passdb.  Check permissions?\n", 
2337                           account));
2338                 return NT_STATUS_ACCESS_DENIED;         
2339         }
2340         
2341         /* Get the user's SID */
2342         
2343         sid_copy(&sid, pdb_get_user_sid(sam_pass));
2344         
2345         samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2346         se_map_generic(&des_access, &usr_generic_mapping);
2347         
2348         nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2349                 des_access, &acc_granted, "_samr_create_user");
2350                 
2351         if ( !NT_STATUS_IS_OK(nt_status) ) {
2352                 return nt_status;
2353         }
2354
2355         /* associate the user's SID with the new handle. */
2356         if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2357                 pdb_free_sam(&sam_pass);
2358                 return NT_STATUS_NO_MEMORY;
2359         }
2360
2361         ZERO_STRUCTP(info);
2362         info->sid = sid;
2363         info->acc_granted = acc_granted;
2364
2365         /* get a (unique) handle.  open a policy on it. */
2366         if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2367                 pdb_free_sam(&sam_pass);
2368                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2369         }
2370
2371         r_u->user_rid=pdb_get_user_rid(sam_pass);
2372
2373         r_u->access_granted = acc_granted;
2374
2375         pdb_free_sam(&sam_pass);
2376
2377         return NT_STATUS_OK;
2378 }
2379
2380 /*******************************************************************
2381  samr_reply_connect_anon
2382  ********************************************************************/
2383
2384 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2385 {
2386         struct samr_info *info = NULL;
2387         uint32    des_access = q_u->access_mask;
2388
2389         /* Access check */
2390
2391         if (!pipe_access_check(p)) {
2392                 DEBUG(3, ("access denied to samr_connect_anon\n"));
2393                 r_u->status = NT_STATUS_ACCESS_DENIED;
2394                 return r_u->status;
2395         }
2396
2397         /* set up the SAMR connect_anon response */
2398
2399         r_u->status = NT_STATUS_OK;
2400
2401         /* associate the user's SID with the new handle. */
2402         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2403                 return NT_STATUS_NO_MEMORY;
2404
2405         /* don't give away the farm but this is probably ok.  The SA_RIGHT_SAM_ENUM_DOMAINS
2406            was observed from a win98 client trying to enumerate users (when configured  
2407            user level access control on shares)   --jerry */
2408            
2409         se_map_generic( &des_access, &sam_generic_mapping );
2410         info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2411         
2412         info->status = q_u->unknown_0;
2413
2414         /* get a (unique) handle.  open a policy on it. */
2415         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2416                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2417
2418         return r_u->status;
2419 }
2420
2421 /*******************************************************************
2422  samr_reply_connect
2423  ********************************************************************/
2424
2425 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2426 {
2427         struct samr_info *info = NULL;
2428         SEC_DESC *psd = NULL;
2429         uint32    acc_granted;
2430         uint32    des_access = q_u->access_mask;
2431         size_t    sd_size;
2432         NTSTATUS  nt_status;
2433
2434
2435         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2436
2437         /* Access check */
2438
2439         if (!pipe_access_check(p)) {
2440                 DEBUG(3, ("access denied to samr_connect\n"));
2441                 r_u->status = NT_STATUS_ACCESS_DENIED;
2442                 return r_u->status;
2443         }
2444
2445         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2446         se_map_generic(&des_access, &sam_generic_mapping);
2447         if (!NT_STATUS_IS_OK(nt_status = 
2448                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2449                                                       des_access, &acc_granted, "_samr_connect"))) {
2450                 return nt_status;
2451         }
2452
2453         r_u->status = NT_STATUS_OK;
2454
2455         /* associate the user's SID and access granted with the new handle. */
2456         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2457                 return NT_STATUS_NO_MEMORY;
2458
2459         info->acc_granted = acc_granted;
2460         info->status = q_u->access_mask;
2461
2462         /* get a (unique) handle.  open a policy on it. */
2463         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2464                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2465
2466         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2467
2468         return r_u->status;
2469 }
2470
2471 /*******************************************************************
2472  samr_connect4
2473  ********************************************************************/
2474
2475 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2476 {
2477         struct samr_info *info = NULL;
2478         SEC_DESC *psd = NULL;
2479         uint32    acc_granted;
2480         uint32    des_access = q_u->access_mask;
2481         size_t    sd_size;
2482         NTSTATUS  nt_status;
2483
2484
2485         DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2486
2487         /* Access check */
2488
2489         if (!pipe_access_check(p)) {
2490                 DEBUG(3, ("access denied to samr_connect4\n"));
2491                 r_u->status = NT_STATUS_ACCESS_DENIED;
2492                 return r_u->status;
2493         }
2494
2495         samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2496         se_map_generic(&des_access, &sam_generic_mapping);
2497         if (!NT_STATUS_IS_OK(nt_status = 
2498                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2499                                                       des_access, &acc_granted, "_samr_connect"))) {
2500                 return nt_status;
2501         }
2502
2503         r_u->status = NT_STATUS_OK;
2504
2505         /* associate the user's SID and access granted with the new handle. */
2506         if ((info = get_samr_info_by_sid(NULL)) == NULL)
2507                 return NT_STATUS_NO_MEMORY;
2508
2509         info->acc_granted = acc_granted;
2510         info->status = q_u->access_mask;
2511
2512         /* get a (unique) handle.  open a policy on it. */
2513         if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2514                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2515
2516         DEBUG(5,("_samr_connect: %d\n", __LINE__));
2517
2518         return r_u->status;
2519 }
2520
2521 /**********************************************************************
2522  api_samr_lookup_domain
2523  **********************************************************************/
2524
2525 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2526 {
2527         struct samr_info *info;
2528         fstring domain_name;
2529         DOM_SID sid;
2530
2531         r_u->status = NT_STATUS_OK;
2532
2533         if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2534                 return NT_STATUS_INVALID_HANDLE;
2535
2536         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, 
2537                 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain"))) 
2538         {
2539                 return r_u->status;
2540         }
2541
2542         rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2543
2544         ZERO_STRUCT(sid);
2545
2546         if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2547                 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2548         }
2549
2550         DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2551
2552         init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2553
2554         return r_u->status;
2555 }
2556
2557 /******************************************************************
2558 makes a SAMR_R_ENUM_DOMAINS structure.
2559 ********************************************************************/
2560
2561 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2562                         UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2563 {
2564         uint32 i;
2565         SAM_ENTRY *sam;
2566         UNISTR2 *uni_name;
2567
2568         DEBUG(5, ("make_enum_domains\n"));
2569
2570         *pp_sam = NULL;
2571         *pp_uni_name = NULL;
2572
2573         if (num_sam_entries == 0)
2574                 return True;
2575
2576         sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2577         uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2578
2579         if (sam == NULL || uni_name == NULL)
2580                 return False;
2581
2582         for (i = 0; i < num_sam_entries; i++) {
2583                 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2584                 init_sam_entry(&sam[i], &uni_name[i], 0);
2585         }
2586
2587         *pp_sam = sam;
2588         *pp_uni_name = uni_name;
2589
2590         return True;
2591 }
2592
2593 /**********************************************************************
2594  api_samr_enum_domains
2595  **********************************************************************/
2596
2597 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2598 {
2599         struct samr_info *info;
2600         uint32 num_entries = 2;
2601         fstring dom[2];
2602         const char *name;
2603
2604         r_u->status = NT_STATUS_OK;
2605         
2606         if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2607                 return NT_STATUS_INVALID_HANDLE;
2608         
2609         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2610                 return r_u->status;
2611         }
2612
2613         name = get_global_sam_name();
2614
2615         fstrcpy(dom[0],name);
2616         strupper_m(dom[0]);
2617         fstrcpy(dom[1],"Builtin");
2618
2619         if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2620                 return NT_STATUS_NO_MEMORY;
2621
2622         init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2623
2624         return r_u->status;
2625 }
2626
2627 /*******************************************************************
2628  api_samr_open_alias
2629  ********************************************************************/
2630
2631 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2632 {
2633         DOM_SID sid;
2634         POLICY_HND domain_pol = q_u->dom_pol;
2635         uint32 alias_rid = q_u->rid_alias;
2636         POLICY_HND *alias_pol = &r_u->pol;
2637         struct    samr_info *info = NULL;
2638         SEC_DESC *psd = NULL;
2639         uint32    acc_granted;
2640         uint32    des_access = q_u->access_mask;
2641         size_t    sd_size;
2642         NTSTATUS  status;
2643
2644         r_u->status = NT_STATUS_OK;
2645
2646         /* find the domain policy and get the SID / access bits stored in the domain policy */
2647         if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2648                 return NT_STATUS_INVALID_HANDLE;
2649                 
2650         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2651                 return status;
2652         }
2653
2654         /* append the alias' RID to it */
2655         if (!sid_append_rid(&sid, alias_rid))
2656                 return NT_STATUS_NO_SUCH_USER;
2657                 
2658         /*check if access can be granted as requested by client. */
2659         samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2660         se_map_generic(&des_access,&ali_generic_mapping);
2661         if (!NT_STATUS_IS_OK(status = 
2662                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
2663                                                       des_access, &acc_granted, "_samr_open_alias"))) {
2664                 return status;
2665         }
2666
2667         /*
2668          * we should check if the rid really exist !!!
2669          * JFM.
2670          */
2671
2672         /* associate the user's SID with the new handle. */
2673         if ((info = get_samr_info_by_sid(&sid)) == NULL)
2674                 return NT_STATUS_NO_MEMORY;
2675                 
2676         info->acc_granted = acc_granted;
2677
2678         /* get a (unique) handle.  open a policy on it. */
2679         if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2680                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2681
2682         return r_u->status;
2683 }
2684
2685 /*******************************************************************
2686  set_user_info_10
2687  ********************************************************************/
2688
2689 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2690 {
2691         SAM_ACCOUNT *pwd =NULL;
2692         BOOL ret;
2693         
2694         pdb_init_sam(&pwd);
2695         
2696         ret = pdb_getsampwsid(pwd, sid);
2697         
2698         if(ret==False) {
2699                 pdb_free_sam(&pwd);
2700                 return False;
2701         }
2702
2703         if (id10 == NULL) {
2704                 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2705                 pdb_free_sam(&pwd);
2706                 return False;
2707         }
2708         
2709         /* FIX ME: check if the value is really changed --metze */
2710         if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2711                 pdb_free_sam(&pwd);
2712                 return False;
2713         }
2714
2715         if(!pdb_update_sam_account(pwd)) {
2716                 pdb_free_sam(&pwd);
2717                 return False;
2718         }
2719
2720         pdb_free_sam(&pwd);
2721
2722         return True;
2723 }
2724
2725 /*******************************************************************
2726  set_user_info_12
2727  ********************************************************************/
2728
2729 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2730 {
2731         SAM_ACCOUNT *pwd = NULL;
2732
2733         pdb_init_sam(&pwd);
2734
2735         if(!pdb_getsampwsid(pwd, sid)) {
2736                 pdb_free_sam(&pwd);
2737                 return False;
2738         }
2739
2740         if (id12 == NULL) {
2741                 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2742                 pdb_free_sam(&pwd);
2743                 return False;
2744         }
2745  
2746         if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2747                 pdb_free_sam(&pwd);
2748                 return False;
2749         }
2750         if (!pdb_set_nt_passwd     (pwd, id12->nt_pwd, PDB_CHANGED)) {
2751                 pdb_free_sam(&pwd);
2752                 return False;
2753         }
2754         if (!pdb_set_pass_changed_now (pwd)) {
2755                 pdb_free_sam(&pwd);
2756                 return False; 
2757         }
2758  
2759         if(!pdb_update_sam_account(pwd)) {
2760                 pdb_free_sam(&pwd);
2761                 return False;
2762         }
2763
2764         pdb_free_sam(&pwd);
2765         return True;
2766 }
2767
2768 /*******************************************************************
2769  The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2770  ********************************************************************/
2771 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2772 {
2773         struct group *grp;
2774         gid_t gid;
2775
2776         if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2777                                         &gid))) {
2778                 DEBUG(2,("Could not get gid for primary group of "
2779                          "user %s\n", pdb_get_username(sampass)));
2780                 return False;
2781         }
2782
2783         grp = getgrgid(gid);
2784
2785         if (grp == NULL) {
2786                 DEBUG(2,("Could not find primary group %lu for "
2787                          "user %s\n", (unsigned long)gid, 
2788                          pdb_get_username(sampass)));
2789                 return False;
2790         }
2791
2792         if (smb_set_primary_group(grp->gr_name,
2793                                   pdb_get_username(sampass)) != 0) {
2794                 DEBUG(2,("Could not set primary group for user %s to "
2795                          "%s\n",
2796                          pdb_get_username(sampass), grp->gr_name));
2797                 return False;
2798         }
2799
2800         return True;
2801 }
2802         
2803
2804 /*******************************************************************
2805  set_user_info_20
2806  ********************************************************************/
2807
2808 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2809 {
2810         SAM_ACCOUNT *pwd = NULL;
2811  
2812         if (id20 == NULL) {
2813                 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2814                 return False;
2815         }
2816  
2817         pdb_init_sam(&pwd);
2818  
2819         if (!pdb_getsampwsid(pwd, sid)) {
2820                 pdb_free_sam(&pwd);
2821                 return False;
2822         }
2823  
2824         copy_id20_to_sam_passwd(pwd, id20);
2825
2826         /* write the change out */
2827         if(!pdb_update_sam_account(pwd)) {
2828                 pdb_free_sam(&pwd);
2829                 return False;
2830         }
2831
2832         pdb_free_sam(&pwd);
2833
2834         return True;
2835 }
2836 /*******************************************************************
2837  set_user_info_21
2838  ********************************************************************/
2839
2840 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2841 {
2842         SAM_ACCOUNT *pwd = NULL;
2843  
2844         if (id21 == NULL) {
2845                 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2846                 return False;
2847         }
2848  
2849         pdb_init_sam(&pwd);
2850  
2851         if (!pdb_getsampwsid(pwd, sid)) {
2852                 pdb_free_sam(&pwd);
2853                 return False;
2854         }
2855  
2856         copy_id21_to_sam_passwd(pwd, id21);
2857  
2858         /*
2859          * The funny part about the previous two calls is
2860          * that pwd still has the password hashes from the
2861          * passdb entry.  These have not been updated from
2862          * id21.  I don't know if they need to be set.    --jerry
2863          */
2864  
2865         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2866                 set_unix_primary_group(pwd);
2867
2868         /* write the change out */
2869         if(!pdb_update_sam_account(pwd)) {
2870                 pdb_free_sam(&pwd);
2871                 return False;
2872         }
2873
2874         pdb_free_sam(&pwd);
2875
2876         return True;
2877 }
2878
2879 /*******************************************************************
2880  set_user_info_23
2881  ********************************************************************/
2882
2883 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2884 {
2885         SAM_ACCOUNT *pwd = NULL;
2886         pstring plaintext_buf;
2887         uint32 len;
2888         uint16 acct_ctrl;
2889  
2890         if (id23 == NULL) {
2891                 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2892                 return False;
2893         }
2894  
2895         pdb_init_sam(&pwd);
2896  
2897         if (!pdb_getsampwsid(pwd, sid)) {
2898                 pdb_free_sam(&pwd);
2899                 return False;
2900         }
2901
2902         DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2903                   pdb_get_username(pwd)));
2904
2905         acct_ctrl = pdb_get_acct_ctrl(pwd);
2906
2907         if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2908                 pdb_free_sam(&pwd);
2909                 return False;
2910         }
2911   
2912         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2913                 pdb_free_sam(&pwd);
2914                 return False;
2915         }
2916  
2917         copy_id23_to_sam_passwd(pwd, id23);
2918  
2919         /* if it's a trust account, don't update /etc/passwd */
2920         if (    ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2921                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2922                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2923                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2924         } else  {
2925                 /* update the UNIX password */
2926                 if (lp_unix_password_sync() ) {
2927                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2928                         if (!passwd) {
2929                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2930                         }
2931                         
2932                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2933                                 pdb_free_sam(&pwd);
2934                                 return False;
2935                         }
2936                 }
2937         }
2938  
2939         ZERO_STRUCT(plaintext_buf);
2940  
2941         if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2942                 set_unix_primary_group(pwd);
2943
2944         if(!pdb_update_sam_account(pwd)) {
2945                 pdb_free_sam(&pwd);
2946                 return False;
2947         }
2948  
2949         pdb_free_sam(&pwd);
2950
2951         return True;
2952 }
2953
2954 /*******************************************************************
2955  set_user_info_pw
2956  ********************************************************************/
2957
2958 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2959 {
2960         SAM_ACCOUNT *pwd = NULL;
2961         uint32 len;
2962         pstring plaintext_buf;
2963         uint16 acct_ctrl;
2964  
2965         pdb_init_sam(&pwd);
2966  
2967         if (!pdb_getsampwsid(pwd, sid)) {
2968                 pdb_free_sam(&pwd);
2969                 return False;
2970         }
2971         
2972         DEBUG(5, ("Attempting administrator password change for user %s\n",
2973                   pdb_get_username(pwd)));
2974
2975         acct_ctrl = pdb_get_acct_ctrl(pwd);
2976
2977         ZERO_STRUCT(plaintext_buf);
2978  
2979         if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2980                 pdb_free_sam(&pwd);
2981                 return False;
2982         }
2983
2984         if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2985                 pdb_free_sam(&pwd);
2986                 return False;
2987         }
2988  
2989         /* if it's a trust account, don't update /etc/passwd */
2990         if ( ( (acct_ctrl &  ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2991                 ( (acct_ctrl &  ACB_WSTRUST) ==  ACB_WSTRUST) ||
2992                 ( (acct_ctrl &  ACB_SVRTRUST) ==  ACB_SVRTRUST) ) {
2993                 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2994         } else {
2995                 /* update the UNIX password */
2996                 if (lp_unix_password_sync()) {
2997                         struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2998                         if (!passwd) {
2999                                 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
3000                         }
3001                         
3002                         if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
3003                                 pdb_free_sam(&pwd);
3004                                 return False;
3005                         }
3006                 }
3007         }
3008  
3009         ZERO_STRUCT(plaintext_buf);
3010  
3011         DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
3012  
3013         /* update the SAMBA password */
3014         if(!pdb_update_sam_account(pwd)) {
3015                 pdb_free_sam(&pwd);
3016                 return False;
3017         }
3018
3019         pdb_free_sam(&pwd);
3020
3021         return True;
3022 }
3023
3024 /*******************************************************************
3025  samr_reply_set_userinfo
3026  ********************************************************************/
3027
3028 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3029 {
3030         DOM_SID sid;
3031         POLICY_HND *pol = &q_u->pol;
3032         uint16 switch_value = q_u->switch_value;
3033         SAM_USERINFO_CTR *ctr = q_u->ctr;
3034         uint32 acc_granted;
3035         uint32 acc_required;
3036         BOOL can_add_machines;
3037
3038         DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3039
3040         r_u->status = NT_STATUS_OK;
3041
3042         /* find the policy handle.  open a policy on it. */
3043         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3044                 return NT_STATUS_INVALID_HANDLE;
3045         
3046         /* the access mask depends on what the caller wants to do */
3047
3048         switch (switch_value) {
3049                 case 24:
3050                         acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3051                         break;
3052                 default:
3053                         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3054                         break;
3055         }
3056
3057         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3058                 return r_u->status;
3059         }
3060                 
3061         DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3062
3063         if (ctr == NULL) {
3064                 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3065                 return NT_STATUS_INVALID_INFO_CLASS;
3066         }
3067
3068         /* check to see if we are a domain admin */
3069         
3070         can_add_machines = user_has_privilege( p->pipe_user.nt_user_token, SE_MACHINE_ACCOUNT );
3071         
3072         DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
3073                 p->pipe_user_name, can_add_machines ? "" : " not"));
3074
3075         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3076         
3077         if ( can_add_machines )                         
3078                 become_root();
3079
3080         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3081
3082         switch (switch_value) {
3083                 case 0x12:
3084                         if (!set_user_info_12(ctr->info.id12, &sid))
3085                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3086                         break;
3087
3088                 case 24:
3089                         if (!p->session_key.length) {
3090                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3091                         }
3092                         SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3093
3094                         dump_data(100, (char *)ctr->info.id24->pass, 516);
3095
3096                         if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
3097                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3098                         break;
3099
3100                 case 25:
3101 #if 0
3102                         /*
3103                          * Currently we don't really know how to unmarshall
3104                          * the level 25 struct, and the password encryption
3105                          * is different. This is a placeholder for when we
3106                          * do understand it. In the meantime just return INVALID
3107                          * info level and W2K SP2 drops down to level 23... JRA.
3108                          */
3109
3110                         if (!p->session_key.length) {
3111                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3112                         }
3113                         SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3114
3115                         dump_data(100, (char *)ctr->info.id25->pass, 532);
3116
3117                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3118                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3119                         break;
3120 #endif
3121                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3122                         break;
3123
3124                 case 23:
3125                         if (!p->session_key.length) {
3126                                 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3127                         }
3128                         SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3129
3130                         dump_data(100, (char *)ctr->info.id23->pass, 516);
3131
3132                         if (!set_user_info_23(ctr->info.id23, &sid))
3133                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3134                         break;
3135
3136                 default:
3137                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3138         }
3139
3140         
3141         if ( can_add_machines )                         
3142                 unbecome_root();
3143                 
3144         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3145
3146         return r_u->status;
3147 }
3148
3149 /*******************************************************************
3150  samr_reply_set_userinfo2
3151  ********************************************************************/
3152
3153 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3154 {
3155         DOM_SID sid;
3156         SAM_USERINFO_CTR *ctr = q_u->ctr;
3157         POLICY_HND *pol = &q_u->pol;
3158         uint16 switch_value = q_u->switch_value;
3159         uint32 acc_granted;
3160         uint32 acc_required;
3161         BOOL can_add_machines;
3162
3163         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3164
3165         r_u->status = NT_STATUS_OK;
3166
3167         /* find the policy handle.  open a policy on it. */
3168         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3169                 return NT_STATUS_INVALID_HANDLE;
3170         
3171         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3172         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3173                 return r_u->status;
3174         }
3175
3176         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3177
3178         if (ctr == NULL) {
3179                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3180                 return NT_STATUS_INVALID_INFO_CLASS;
3181         }
3182
3183         switch_value=ctr->switch_value;
3184
3185         /* check to see if we are a domain admin */
3186         
3187         can_add_machines = user_has_privilege( p->pipe_user.nt_user_token, SE_MACHINE_ACCOUNT );
3188         
3189         DEBUG(5, ("_samr_create_user: %s is%s a member of the Domain Admins group\n",
3190                 p->pipe_user_name, can_add_machines ? "" : " not"));
3191
3192         /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3193         
3194         if ( can_add_machines )                         
3195                 become_root();
3196                 
3197         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3198         
3199         switch (switch_value) {
3200                 case 21:
3201                         if (!set_user_info_21(ctr->info.id21, &sid))
3202                                 return NT_STATUS_ACCESS_DENIED;
3203                         break;
3204                 case 20:
3205                         if (!set_user_info_20(ctr->info.id20, &sid))
3206                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3207                         break;
3208                 case 16:
3209                         if (!set_user_info_10(ctr->info.id10, &sid))
3210                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3211                         break;
3212                 case 18:
3213                         /* Used by AS/U JRA. */
3214                         if (!set_user_info_12(ctr->info.id12, &sid))
3215                                 r_u->status = NT_STATUS_ACCESS_DENIED;
3216                         break;
3217                 default:
3218                         r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3219         }
3220
3221         if ( can_add_machines )                         
3222                 unbecome_root();
3223                 
3224         /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3225
3226         return r_u->status;
3227 }
3228
3229 /*********************************************************************
3230  _samr_query_aliasmem
3231 *********************************************************************/
3232
3233 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3234 {
3235         int num_groups = 0;
3236         uint32 *rids=NULL;
3237         struct samr_info *info = NULL;
3238         int i;
3239                 
3240         NTSTATUS ntstatus1;
3241         NTSTATUS ntstatus2;
3242
3243         DOM_SID *members;
3244         DOM_SID *aliases;
3245         int num_aliases;
3246         BOOL res;
3247
3248         r_u->status = NT_STATUS_OK;
3249
3250         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3251
3252         /* find the policy handle.  open a policy on it. */
3253         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3254                 return NT_STATUS_INVALID_HANDLE;
3255                 
3256         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3257         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3258         
3259         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3260                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3261                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3262                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3263                 }
3264         }               
3265
3266         if (!sid_check_is_domain(&info->sid) &&
3267             !sid_check_is_builtin(&info->sid))
3268                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3269
3270         members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3271
3272         if (members == NULL)
3273                 return NT_STATUS_NO_MEMORY;
3274
3275         for (i=0; i<q_u->num_sids1; i++)
3276                 sid_copy(&members[i], &q_u->sid[i].sid);
3277
3278         become_root();
3279         res = pdb_enum_alias_memberships(members,
3280                                          q_u->num_sids1, &aliases,
3281                                          &num_aliases);
3282         unbecome_root();
3283
3284         if (!res)
3285                 return NT_STATUS_UNSUCCESSFUL;
3286
3287         rids = NULL;
3288         num_groups = 0;
3289
3290         for (i=0; i<num_aliases; i++) {
3291                 uint32 rid;
3292
3293                 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3294                         continue;
3295
3296                 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3297
3298                 if (rids == NULL)
3299                         return NT_STATUS_NO_MEMORY;
3300
3301                 rids[num_groups] = rid;
3302                 num_groups += 1;
3303         }
3304         SAFE_FREE(aliases);
3305
3306         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3307         return NT_STATUS_OK;
3308 }
3309
3310 /*********************************************************************
3311  _samr_query_aliasmem
3312 *********************************************************************/
3313
3314 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3315 {
3316         int i;
3317
3318         int num_sids = 0;
3319         DOM_SID2 *sid;
3320         DOM_SID *sids=NULL;
3321
3322         DOM_SID alias_sid;
3323
3324         uint32 acc_granted;
3325
3326         /* find the policy handle.  open a policy on it. */
3327         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3328                 return NT_STATUS_INVALID_HANDLE;
3329         
3330         if (!NT_STATUS_IS_OK(r_u->status = 
3331                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3332                 return r_u->status;
3333         }
3334
3335         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3336
3337         if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3338                 return NT_STATUS_NO_SUCH_ALIAS;
3339
3340         sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);        
3341         if (num_sids!=0 && sid == NULL) {
3342                 SAFE_FREE(sids);
3343                 return NT_STATUS_NO_MEMORY;
3344         }
3345
3346         for (i = 0; i < num_sids; i++) {
3347                 init_dom_sid2(&sid[i], &sids[i]);
3348         }
3349
3350         init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3351
3352         SAFE_FREE(sids);
3353
3354         return NT_STATUS_OK;
3355 }
3356
3357 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3358 {
3359         int i;
3360
3361         for (i=0; i<*num; i++) {
3362                 if ((*uids)[i] == uid)
3363                         return;
3364         }
3365         
3366         *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3367
3368         if (*uids == NULL)
3369                 return;
3370
3371         (*uids)[*num] = uid;
3372         *num += 1;
3373 }
3374
3375
3376 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3377 {
3378         struct group *grp;
3379         char **gr;
3380         struct sys_pwent *userlist, *user;
3381  
3382         *uids = NULL;
3383         *num = 0;
3384
3385         /* We only look at our own sam, so don't care about imported stuff */
3386
3387         winbind_off();
3388
3389         if ((grp = getgrgid(gid)) == NULL) {
3390                 winbind_on();
3391                 return False;
3392         }
3393
3394         /* Primary group members */
3395
3396         userlist = getpwent_list();
3397
3398         for (user = userlist; user != NULL; user = user->next) {
3399                 if (user->pw_gid != gid)
3400                         continue;
3401                 add_uid_to_array_unique(user->pw_uid, uids, num);
3402         }
3403
3404         pwent_free(userlist);
3405
3406         /* Secondary group members */
3407
3408         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3409                 struct passwd *pw = getpwnam(*gr);
3410
3411                 if (pw == NULL)
3412                         continue;
3413                 add_uid_to_array_unique(pw->pw_uid, uids, num);
3414         }
3415
3416         winbind_on();
3417
3418         return True;
3419 }       
3420
3421 /*********************************************************************
3422  _samr_query_groupmem
3423 *********************************************************************/
3424
3425 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3426 {
3427         int final_num_rids, i;
3428         DOM_SID group_sid;
3429         fstring group_sid_str;
3430         uid_t *uids;
3431         int num;
3432         gid_t gid;
3433
3434         uint32 *rid=NULL;
3435         uint32 *attr=NULL;
3436
3437         uint32 acc_granted;
3438
3439         /* find the policy handle.  open a policy on it. */
3440         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3441                 return NT_STATUS_INVALID_HANDLE;
3442                 
3443         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3444                 return r_u->status;
3445         }
3446                 
3447         sid_to_string(group_sid_str, &group_sid);
3448         DEBUG(10, ("sid is %s\n", group_sid_str));
3449
3450         if (!sid_check_is_in_our_domain(&group_sid)) {
3451                 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3452                 return NT_STATUS_NO_SUCH_GROUP;
3453         }
3454
3455         DEBUG(10, ("lookup on Domain SID\n"));
3456
3457         if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3458                 return NT_STATUS_NO_SUCH_GROUP;
3459
3460         if(!get_memberuids(gid, &uids, &num))
3461                 return NT_STATUS_NO_SUCH_GROUP;
3462
3463         rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3464         attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3465         
3466         if (num!=0 && (rid==NULL || attr==NULL))
3467                 return NT_STATUS_NO_MEMORY;
3468         
3469         final_num_rids = 0;
3470                 
3471         for (i=0; i<num; i++) {
3472                 DOM_SID sid;
3473
3474                 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3475                         DEBUG(1, ("Could not map member uid to SID\n"));
3476                         continue;
3477                 }
3478
3479                 if (!sid_check_is_in_our_domain(&sid)) {
3480                         DEBUG(1, ("Inconsistent SAM -- group member uid not "
3481                                   "in our domain\n"));
3482                         continue;
3483                 }
3484
3485                 sid_peek_rid(&sid, &rid[final_num_rids]);
3486
3487                 /* Hmm. In a trace I got the constant 7 here from NT. */
3488                 attr[final_num_rids] = SID_NAME_USER;
3489
3490                 final_num_rids += 1;
3491         }
3492
3493         SAFE_FREE(uids);
3494
3495         init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3496                                    NT_STATUS_OK);
3497
3498         return NT_STATUS_OK;
3499 }
3500
3501 /*********************************************************************
3502  _samr_add_aliasmem
3503 *********************************************************************/
3504
3505 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3506 {
3507         DOM_SID alias_sid;
3508         uint32 acc_granted;
3509
3510         /* Find the policy handle. Open a policy on it. */
3511         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3512                 return NT_STATUS_INVALID_HANDLE;
3513         
3514         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3515                 return r_u->status;
3516         }
3517                 
3518         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3519
3520         if (!pdb_add_aliasmem(&alias_sid, &q_u->sid.sid))
3521                 return NT_STATUS_ACCESS_DENIED;
3522
3523         return NT_STATUS_OK;
3524 }
3525
3526 /*********************************************************************
3527  _samr_del_aliasmem
3528 *********************************************************************/
3529
3530 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3531 {
3532         DOM_SID alias_sid;
3533         uint32 acc_granted;
3534
3535         /* Find the policy handle. Open a policy on it. */
3536         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3537                 return NT_STATUS_INVALID_HANDLE;
3538         
3539         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3540                 return r_u->status;
3541         }
3542         
3543         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3544                    sid_string_static(&alias_sid)));
3545
3546         if (!pdb_del_aliasmem(&alias_sid, &q_u->sid.sid))
3547                 return NT_STATUS_ACCESS_DENIED;
3548         
3549         return NT_STATUS_OK;
3550 }
3551
3552 /*********************************************************************
3553  _samr_add_groupmem
3554 *********************************************************************/
3555
3556 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3557 {
3558         DOM_SID group_sid;
3559         DOM_SID user_sid;
3560         fstring group_sid_str;
3561         uid_t uid;
3562         struct passwd *pwd;
3563         struct group *grp;
3564         fstring grp_name;
3565         GROUP_MAP map;
3566         NTSTATUS ret;
3567         SAM_ACCOUNT *sam_user=NULL;
3568         BOOL check;
3569         uint32 acc_granted;
3570
3571         /* Find the policy handle. Open a policy on it. */
3572         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3573                 return NT_STATUS_INVALID_HANDLE;
3574         
3575         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3576                 return r_u->status;
3577         }
3578
3579         sid_to_string(group_sid_str, &group_sid);
3580         DEBUG(10, ("sid is %s\n", group_sid_str));
3581
3582         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3583                 return NT_STATUS_NO_SUCH_GROUP;
3584
3585         DEBUG(10, ("lookup on Domain SID\n"));
3586
3587         if(!get_domain_group_from_sid(group_sid, &map))
3588                 return NT_STATUS_NO_SUCH_GROUP;
3589
3590         sid_copy(&user_sid, get_global_sam_sid());
3591         sid_append_rid(&user_sid, q_u->rid);
3592
3593         ret = pdb_init_sam(&sam_user);
3594         if (!NT_STATUS_IS_OK(ret))
3595                 return ret;
3596         
3597         check = pdb_getsampwsid(sam_user, &user_sid);
3598         
3599         if (check != True) {
3600                 pdb_free_sam(&sam_user);
3601                 return NT_STATUS_NO_SUCH_USER;
3602         }
3603
3604         /* check a real user exist before we run the script to add a user to a group */
3605         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3606                 pdb_free_sam(&sam_user);
3607                 return NT_STATUS_NO_SUCH_USER;
3608         }
3609
3610         pdb_free_sam(&sam_user);
3611
3612         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3613                 return NT_STATUS_NO_SUCH_USER;
3614         }
3615
3616         if ((grp=getgrgid(map.gid)) == NULL) {
3617                 passwd_free(&pwd);
3618                 return NT_STATUS_NO_SUCH_GROUP;
3619         }
3620
3621         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3622         fstrcpy(grp_name, grp->gr_name);
3623
3624         /* if the user is already in the group */
3625         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3626                 passwd_free(&pwd);
3627                 return NT_STATUS_MEMBER_IN_GROUP;
3628         }
3629
3630         /* 
3631          * ok, the group exist, the user exist, the user is not in the group,
3632          *
3633          * we can (finally) add it to the group !
3634          */
3635
3636         smb_add_user_group(grp_name, pwd->pw_name);
3637
3638         /* check if the user has been added then ... */
3639         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3640                 passwd_free(&pwd);
3641                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3642         }
3643
3644         passwd_free(&pwd);
3645         return NT_STATUS_OK;
3646 }
3647
3648 /*********************************************************************
3649  _samr_del_groupmem
3650 *********************************************************************/
3651
3652 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3653 {
3654         DOM_SID group_sid;
3655         DOM_SID user_sid;
3656         SAM_ACCOUNT *sam_pass=NULL;
3657         GROUP_MAP map;
3658         fstring grp_name;
3659         struct group *grp;
3660         uint32 acc_granted;
3661
3662         /*
3663          * delete the group member named q_u->rid
3664          * who is a member of the sid associated with the handle
3665          * the rid is a user's rid as the group is a domain group.
3666          */
3667
3668         /* Find the policy handle. Open a policy on it. */
3669         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3670                 return NT_STATUS_INVALID_HANDLE;
3671         
3672         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3673                 return r_u->status;
3674         }
3675                 
3676         if (!sid_check_is_in_our_domain(&group_sid))
3677                 return NT_STATUS_NO_SUCH_GROUP;
3678
3679         sid_copy(&user_sid, get_global_sam_sid());
3680         sid_append_rid(&user_sid, q_u->rid);
3681
3682         if (!get_domain_group_from_sid(group_sid, &map))
3683                 return NT_STATUS_NO_SUCH_GROUP;
3684
3685         if ((grp=getgrgid(map.gid)) == NULL)
3686                 return NT_STATUS_NO_SUCH_GROUP;
3687
3688         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3689         fstrcpy(grp_name, grp->gr_name);
3690
3691         /* check if the user exists before trying to remove it from the group */
3692         pdb_init_sam(&sam_pass);
3693         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3694                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3695                 pdb_free_sam(&sam_pass);
3696                 return NT_STATUS_NO_SUCH_USER;
3697         }
3698
3699         /* if the user is not in the group */
3700         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3701                 pdb_free_sam(&sam_pass);
3702                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3703         }
3704
3705         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3706
3707         /* check if the user has been removed then ... */
3708         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3709                 pdb_free_sam(&sam_pass);
3710                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3711         }
3712         
3713         pdb_free_sam(&sam_pass);
3714         return NT_STATUS_OK;
3715
3716 }
3717
3718 /****************************************************************************
3719  Delete a UNIX user on demand.
3720 ****************************************************************************/
3721
3722 static int smb_delete_user(const char *unix_user)
3723 {
3724         pstring del_script;
3725         int ret;
3726
3727         /* try winbindd first since it is impossible to determine where 
3728            a user came from via NSS.  Try the delete user script if this fails
3729            meaning the user did not exist in winbindd's list of accounts */
3730
3731         if ( winbind_delete_user( unix_user ) ) {
3732                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3733                 return 0;
3734         }
3735
3736
3737         /* fall back to 'delete user script' */
3738
3739         pstrcpy(del_script, lp_deluser_script());
3740         if (! *del_script)
3741                 return -1;
3742         all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3743         ret = smbrun(del_script,NULL);
3744         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3745
3746         return ret;
3747 }
3748
3749 /*********************************************************************
3750  _samr_delete_dom_user
3751 *********************************************************************/
3752
3753 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3754 {
3755         DOM_SID user_sid;
3756         SAM_ACCOUNT *sam_pass=NULL;
3757         uint32 acc_granted;
3758
3759         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3760
3761         /* Find the policy handle. Open a policy on it. */
3762         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3763                 return NT_STATUS_INVALID_HANDLE;
3764                 
3765         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3766                 return r_u->status;
3767         }
3768                 
3769         if (!sid_check_is_in_our_domain(&user_sid))
3770                 return NT_STATUS_CANNOT_DELETE;
3771
3772         /* check if the user exists before trying to delete */
3773         pdb_init_sam(&sam_pass);
3774         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3775                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3776                         sid_string_static(&user_sid)));
3777                 pdb_free_sam(&sam_pass);
3778                 return NT_STATUS_NO_SUCH_USER;
3779         }
3780
3781         /* First delete the samba side */
3782         if (!pdb_delete_sam_account(sam_pass)) {
3783                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3784                 pdb_free_sam(&sam_pass);
3785                 return NT_STATUS_CANNOT_DELETE;
3786         }
3787
3788         /* Now delete the unix side */
3789         /*
3790          * note: we don't check if the delete really happened
3791          * as the script is not necessary present
3792          * and maybe the sysadmin doesn't want to delete the unix side
3793          */
3794         smb_delete_user(pdb_get_username(sam_pass));
3795
3796
3797         pdb_free_sam(&sam_pass);
3798
3799         if (!close_policy_hnd(p, &q_u->user_pol))
3800                 return NT_STATUS_OBJECT_NAME_INVALID;
3801
3802         return NT_STATUS_OK;
3803 }
3804
3805 /*********************************************************************
3806  _samr_delete_dom_group
3807 *********************************************************************/
3808
3809 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3810 {
3811         DOM_SID group_sid;
3812         DOM_SID dom_sid;
3813         uint32 group_rid;
3814         fstring group_sid_str;
3815         gid_t gid;
3816         struct group *grp;
3817         GROUP_MAP map;
3818         uint32 acc_granted;
3819
3820         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3821
3822         /* Find the policy handle. Open a policy on it. */
3823         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3824                 return NT_STATUS_INVALID_HANDLE;
3825                 
3826         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3827                 return r_u->status;
3828         }
3829                 
3830         sid_copy(&dom_sid, &group_sid);
3831         sid_to_string(group_sid_str, &dom_sid);
3832         sid_split_rid(&dom_sid, &group_rid);
3833
3834         DEBUG(10, ("sid is %s\n", group_sid_str));
3835
3836         /* we check if it's our SID before deleting */
3837         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3838                 return NT_STATUS_NO_SUCH_GROUP;
3839
3840         DEBUG(10, ("lookup on Domain SID\n"));
3841
3842         if(!get_domain_group_from_sid(group_sid, &map))
3843                 return NT_STATUS_NO_SUCH_GROUP;
3844
3845         gid=map.gid;
3846
3847         /* check if group really exists */
3848         if ( (grp=getgrgid(gid)) == NULL)
3849                 return NT_STATUS_NO_SUCH_GROUP;
3850
3851         /* delete mapping first */
3852         if(!pdb_delete_group_mapping_entry(group_sid))
3853                 return NT_STATUS_ACCESS_DENIED;
3854                 
3855         /* we can delete the UNIX group */
3856         smb_delete_group(grp->gr_name);
3857
3858         /* check if the group has been successfully deleted */
3859         if ( (grp=getgrgid(gid)) != NULL)
3860                 return NT_STATUS_ACCESS_DENIED;
3861
3862
3863         if (!close_policy_hnd(p, &q_u->group_pol))
3864                 return NT_STATUS_OBJECT_NAME_INVALID;
3865
3866         return NT_STATUS_OK;
3867 }
3868
3869 /*********************************************************************
3870  _samr_delete_dom_alias
3871 *********************************************************************/
3872
3873 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3874 {
3875         DOM_SID alias_sid;
3876         uint32 acc_granted;
3877
3878         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3879
3880         /* Find the policy handle. Open a policy on it. */
3881         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3882                 return NT_STATUS_INVALID_HANDLE;
3883         
3884         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3885                 return r_u->status;
3886         }
3887
3888         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3889
3890         if (!sid_check_is_in_our_domain(&alias_sid))
3891                 return NT_STATUS_NO_SUCH_ALIAS;
3892                 
3893         DEBUG(10, ("lookup on Local SID\n"));
3894
3895         /* Have passdb delete the alias */
3896         if (!pdb_delete_alias(&alias_sid))
3897                 return NT_STATUS_ACCESS_DENIED;
3898
3899         if (!close_policy_hnd(p, &q_u->alias_pol))
3900                 return NT_STATUS_OBJECT_NAME_INVALID;
3901
3902         return NT_STATUS_OK;
3903 }
3904
3905 /*********************************************************************
3906  _samr_create_dom_group
3907 *********************************************************************/
3908
3909 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3910 {
3911         DOM_SID dom_sid;
3912         DOM_SID info_sid;
3913         fstring name;
3914         fstring sid_string;
3915         struct group *grp;
3916         struct samr_info *info;
3917         uint32 acc_granted;
3918         gid_t gid;
3919
3920         /* Find the policy handle. Open a policy on it. */
3921         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3922                 return NT_STATUS_INVALID_HANDLE;
3923         
3924         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3925                 return r_u->status;
3926         }
3927                 
3928         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3929                 return NT_STATUS_ACCESS_DENIED;
3930
3931         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3932
3933         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3934
3935         /* check if group already exist */
3936         if ((grp=getgrnam(name)) != NULL)
3937                 return NT_STATUS_GROUP_EXISTS;
3938
3939         /* we can create the UNIX group */
3940         if (smb_create_group(name, &gid) != 0)
3941                 return NT_STATUS_ACCESS_DENIED;
3942
3943         /* check if the group has been successfully created */
3944         if ((grp=getgrgid(gid)) == NULL)
3945                 return NT_STATUS_ACCESS_DENIED;
3946
3947         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3948
3949         /* add the group to the mapping table */
3950         sid_copy(&info_sid, get_global_sam_sid());
3951         sid_append_rid(&info_sid, r_u->rid);
3952         sid_to_string(sid_string, &info_sid);
3953
3954         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3955                 return NT_STATUS_ACCESS_DENIED;
3956
3957         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3958                 return NT_STATUS_NO_MEMORY;
3959
3960         /* get a (unique) handle.  open a policy on it. */
3961         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3962                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3963
3964         return NT_STATUS_OK;
3965 }
3966
3967 /*********************************************************************
3968  _samr_create_dom_alias
3969 *********************************************************************/
3970
3971 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3972 {
3973         DOM_SID dom_sid;
3974         DOM_SID info_sid;
3975         fstring name;
3976         struct group *grp;
3977         struct samr_info *info;
3978         uint32 acc_granted;
3979         gid_t gid;
3980         NTSTATUS result;
3981
3982         /* Find the policy handle. Open a policy on it. */
3983         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3984                 return NT_STATUS_INVALID_HANDLE;
3985                 
3986         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3987                 return r_u->status;
3988         }
3989                 
3990         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3991                 return NT_STATUS_ACCESS_DENIED;
3992
3993         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3994
3995         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3996
3997         /* Have passdb create the alias */
3998         result = pdb_create_alias(name, &r_u->rid);
3999
4000         if (!NT_STATUS_IS_OK(result))
4001                 return result;
4002
4003         sid_copy(&info_sid, get_global_sam_sid());
4004         sid_append_rid(&info_sid, r_u->rid);
4005
4006         if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4007                 return NT_STATUS_ACCESS_DENIED;
4008
4009         /* check if the group has been successfully created */
4010         if ((grp=getgrgid(gid)) == NULL)
4011                 return NT_STATUS_ACCESS_DENIED;
4012
4013         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4014                 return NT_STATUS_NO_MEMORY;
4015
4016         /* get a (unique) handle.  open a policy on it. */
4017         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4018                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4019
4020         return NT_STATUS_OK;
4021 }
4022
4023 /*********************************************************************
4024  _samr_query_groupinfo
4025
4026 sends the name/comment pair of a domain group
4027 level 1 send also the number of users of that group
4028 *********************************************************************/
4029
4030 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4031 {
4032         DOM_SID group_sid;
4033         GROUP_MAP map;
4034         DOM_SID *sids=NULL;
4035         uid_t *uids;
4036         int num=0;
4037         GROUP_INFO_CTR *ctr;
4038         uint32 acc_granted;
4039         BOOL ret;
4040
4041         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4042                 return NT_STATUS_INVALID_HANDLE;
4043         
4044         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4045                 return r_u->status;
4046         }
4047                 
4048         become_root();
4049         ret = get_domain_group_from_sid(group_sid, &map);
4050         unbecome_root();
4051         if (!ret)
4052                 return NT_STATUS_INVALID_HANDLE;
4053
4054         ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4055         if (ctr==NULL)
4056                 return NT_STATUS_NO_MEMORY;
4057
4058         switch (q_u->switch_level) {
4059                 case 1:
4060                         ctr->switch_value1 = 1;
4061                         if(!get_memberuids(map.gid, &uids, &num))
4062                                 return NT_STATUS_NO_SUCH_GROUP;
4063                         SAFE_FREE(uids);
4064                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4065                         SAFE_FREE(sids);
4066                         break;
4067                 case 3:
4068                         ctr->switch_value1 = 3;
4069                         init_samr_group_info3(&ctr->group.info3);
4070                         break;
4071                 case 4:
4072                         ctr->switch_value1 = 4;
4073                         init_samr_group_info4(&ctr->group.info4, map.comment);
4074                         break;
4075                 default:
4076                         return NT_STATUS_INVALID_INFO_CLASS;
4077         }
4078
4079         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4080
4081         return NT_STATUS_OK;
4082 }
4083
4084 /*********************************************************************
4085  _samr_set_groupinfo
4086  
4087  update a domain group's comment.
4088 *********************************************************************/
4089
4090 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4091 {
4092         DOM_SID group_sid;
4093         GROUP_MAP map;
4094         GROUP_INFO_CTR *ctr;
4095         uint32 acc_granted;
4096
4097         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4098                 return NT_STATUS_INVALID_HANDLE;
4099         
4100         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4101                 return r_u->status;
4102         }
4103                 
4104         if (!get_domain_group_from_sid(group_sid, &map))
4105                 return NT_STATUS_NO_SUCH_GROUP;
4106         
4107         ctr=q_u->ctr;
4108
4109         switch (ctr->switch_value1) {
4110                 case 1:
4111                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4112                         break;
4113                 case 4:
4114                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4115                         break;
4116                 default:
4117                         return NT_STATUS_INVALID_INFO_CLASS;
4118         }
4119
4120         if(!pdb_update_group_mapping_entry(&map)) {
4121                 return NT_STATUS_NO_SUCH_GROUP;
4122         }
4123
4124         return NT_STATUS_OK;
4125 }
4126
4127 /*********************************************************************
4128  _samr_set_aliasinfo
4129  
4130  update an alias's comment.
4131 *********************************************************************/
4132
4133 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4134 {
4135         DOM_SID group_sid;
4136         struct acct_info info;
4137         ALIAS_INFO_CTR *ctr;
4138         uint32 acc_granted;
4139
4140         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4141                 return NT_STATUS_INVALID_HANDLE;
4142         
4143         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4144                 return r_u->status;
4145         }
4146                 
4147         ctr=&q_u->ctr;
4148
4149         switch (ctr->switch_value1) {
4150                 case 3:
4151                         unistr2_to_ascii(info.acct_desc,
4152                                          &(ctr->alias.info3.uni_acct_desc),
4153                                          sizeof(info.acct_desc)-1);
4154                         break;
4155                 default:
4156                         return NT_STATUS_INVALID_INFO_CLASS;
4157         }
4158
4159         if(!pdb_set_aliasinfo(&group_sid, &info)) {
4160                 return NT_STATUS_ACCESS_DENIED;
4161         }
4162
4163         return NT_STATUS_OK;
4164 }
4165
4166 /*********************************************************************
4167  _samr_get_dom_pwinfo
4168 *********************************************************************/
4169
4170 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4171 {
4172         /* Perform access check.  Since this rpc does not require a
4173            policy handle it will not be caught by the access checks on
4174            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4175
4176         if (!pipe_access_check(p)) {
4177                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4178                 r_u->status = NT_STATUS_ACCESS_DENIED;
4179                 return r_u->status;
4180         }
4181
4182         /* Actually, returning zeros here works quite well :-). */
4183
4184         return NT_STATUS_OK;
4185 }
4186
4187 /*********************************************************************
4188  _samr_open_group
4189 *********************************************************************/
4190
4191 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4192 {
4193         DOM_SID sid;
4194         DOM_SID info_sid;
4195         GROUP_MAP map;
4196         struct samr_info *info;
4197         SEC_DESC         *psd = NULL;
4198         uint32            acc_granted;
4199         uint32            des_access = q_u->access_mask;
4200         size_t            sd_size;
4201         NTSTATUS          status;
4202         fstring sid_string;
4203         BOOL ret;
4204
4205         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4206                 return NT_STATUS_INVALID_HANDLE;
4207         
4208         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4209                 return status;
4210         }
4211                 
4212         /*check if access can be granted as requested by client. */
4213         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4214         se_map_generic(&des_access,&grp_generic_mapping);
4215         if (!NT_STATUS_IS_OK(status = 
4216                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4217                                                       des_access, &acc_granted, "_samr_open_group"))) {
4218                 return status;
4219         }
4220
4221
4222         /* this should not be hard-coded like this */
4223         if (!sid_equal(&sid, get_global_sam_sid()))
4224                 return NT_STATUS_ACCESS_DENIED;
4225
4226         sid_copy(&info_sid, get_global_sam_sid());
4227         sid_append_rid(&info_sid, q_u->rid_group);
4228         sid_to_string(sid_string, &info_sid);
4229
4230         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4231                 return NT_STATUS_NO_MEMORY;
4232                 
4233         info->acc_granted = acc_granted;
4234
4235         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4236
4237         /* check if that group really exists */
4238         become_root();
4239         ret = get_domain_group_from_sid(info->sid, &map);
4240         unbecome_root();
4241         if (!ret)
4242                 return NT_STATUS_NO_SUCH_GROUP;
4243
4244         /* get a (unique) handle.  open a policy on it. */
4245         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4246                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4247
4248         return NT_STATUS_OK;
4249 }
4250
4251 /*********************************************************************
4252  _samr_remove_sid_foreign_domain
4253 *********************************************************************/
4254
4255 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4256                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4257                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4258 {
4259         DOM_SID                 delete_sid, alias_sid;
4260         SAM_ACCOUNT             *sam_pass=NULL;
4261         uint32                  acc_granted;
4262         GROUP_MAP               map;
4263         BOOL                    is_user = False;
4264         NTSTATUS                result;
4265         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4266         
4267         sid_copy( &delete_sid, &q_u->sid.sid );
4268         
4269         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4270                 sid_string_static(&delete_sid)));
4271                 
4272         /* Find the policy handle. Open a policy on it. */
4273         
4274         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4275                 return NT_STATUS_INVALID_HANDLE;
4276         
4277         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4278                 "_samr_remove_sid_foreign_domain");
4279                 
4280         if (!NT_STATUS_IS_OK(result)) 
4281                 return result;
4282                         
4283         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4284                 sid_string_static(&alias_sid)));
4285                 
4286         /* make sure we can handle this */
4287         
4288         if ( sid_check_is_domain(&alias_sid) )
4289                 type = SID_NAME_DOM_GRP;
4290         else if ( sid_check_is_builtin(&alias_sid) )
4291                 type = SID_NAME_ALIAS;
4292         
4293         if ( type == SID_NAME_UNKNOWN ) {
4294                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4295                 return NT_STATUS_OK;
4296         }
4297
4298         /* check if the user exists before trying to delete */
4299         
4300         pdb_init_sam(&sam_pass);
4301         
4302         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4303                 is_user = True;
4304         } else {
4305                 /* maybe it is a group */
4306                 if( !pdb_getgrsid(&map, delete_sid) ) {
4307                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4308                                 sid_string_static(&delete_sid)));
4309                         result = NT_STATUS_INVALID_SID;
4310                         goto done;
4311                 }
4312         }
4313         
4314         /* we can only delete a user from a group since we don't have 
4315            nested groups anyways.  So in the latter case, just say OK */
4316            
4317         if ( is_user ) {
4318                 GROUP_MAP       *mappings = NULL;
4319                 int             num_groups, i;
4320                 struct group    *grp2;
4321                 
4322                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4323                 
4324                         /* interate over the groups */
4325                         for ( i=0; i<num_groups; i++ ) {
4326
4327                                 grp2 = getgrgid(mappings[i].gid);
4328
4329                                 if ( !grp2 ) {
4330                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4331                                         continue;
4332                                 }
4333                         
4334                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4335                                         continue;
4336                                 
4337                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4338                                 
4339                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4340                                         /* should we fail here ? */
4341                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4342                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4343                                         continue;
4344                                 }
4345                                         
4346                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4347                                         pdb_get_username(sam_pass), grp2->gr_name ));
4348                         }
4349                         
4350                         SAFE_FREE(mappings);
4351                 }
4352         }
4353         
4354         result = NT_STATUS_OK;
4355 done:
4356
4357         pdb_free_sam(&sam_pass);
4358
4359         return result;
4360 }
4361
4362 /*******************************************************************
4363  _samr_unknown_2e
4364  ********************************************************************/
4365
4366 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4367 {
4368         struct samr_info *info = NULL;
4369         SAM_UNK_CTR *ctr;
4370         uint32 min_pass_len,pass_hist,flag;
4371         time_t u_expire, u_min_age;
4372         NTTIME nt_expire, nt_min_age;
4373
4374         time_t u_lock_duration, u_reset_time;
4375         NTTIME nt_lock_duration, nt_reset_time;
4376         uint32 lockout;
4377         
4378         time_t u_logout;
4379         NTTIME nt_logout;
4380
4381         uint32 num_users=0, num_groups=0, num_aliases=0;
4382
4383         uint32 account_policy_temp;
4384
4385         if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4386                 return NT_STATUS_NO_MEMORY;
4387
4388         ZERO_STRUCTP(ctr);
4389
4390         r_u->status = NT_STATUS_OK;
4391
4392         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4393
4394         /* find the policy handle.  open a policy on it. */
4395         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4396                 return NT_STATUS_INVALID_HANDLE;
4397
4398         switch (q_u->switch_value) {
4399                 case 0x01:
4400                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4401                         min_pass_len = account_policy_temp;
4402
4403                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4404                         pass_hist = account_policy_temp;
4405
4406                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4407                         flag = account_policy_temp;
4408
4409                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4410                         u_expire = account_policy_temp;
4411
4412                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4413                         u_min_age = account_policy_temp;
4414
4415                         unix_to_nt_time_abs(&nt_expire, u_expire);
4416                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4417
4418                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4419                                        flag, nt_expire, nt_min_age);
4420                         break;
4421                 case 0x02:
4422                         become_root();          
4423                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4424                         unbecome_root();
4425                         if (!NT_STATUS_IS_OK(r_u->status)) {
4426                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4427                                 return r_u->status;
4428                         }
4429                         num_users=info->disp_info.num_user_account;
4430                         free_samr_db(info);
4431                         
4432                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4433                         if (NT_STATUS_IS_ERR(r_u->status)) {
4434                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4435                                 return r_u->status;
4436                         }
4437                         num_groups=info->disp_info.num_group_account;
4438                         free_samr_db(info);
4439
4440                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4441                         u_logout = account_policy_temp;
4442
4443                         unix_to_nt_time_abs(&nt_logout, u_logout);
4444
4445                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4446                         init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL), 
4447                                        num_users, num_groups, num_aliases, nt_logout);
4448                         break;
4449                 case 0x03:
4450                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4451                         u_logout = account_policy_temp;
4452
4453                         unix_to_nt_time_abs(&nt_logout, u_logout);
4454                         
4455                         init_unk_info3(&ctr->info.inf3, nt_logout);
4456                         break;
4457                 case 0x05:
4458                         init_unk_info5(&ctr->info.inf5, global_myname());
4459                         break;
4460                 case 0x06:
4461                         init_unk_info6(&ctr->info.inf6);
4462                         break;
4463                 case 0x07:
4464                         init_unk_info7(&ctr->info.inf7);
4465                         break;
4466                 case 0x08:
4467                         init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4468                         break;
4469                 case 0x0c:
4470                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4471                         u_lock_duration = account_policy_temp;
4472                         if (u_lock_duration != -1)
4473                                 u_lock_duration *= 60;
4474
4475                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4476                         u_reset_time = account_policy_temp * 60;
4477
4478                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4479                         lockout = account_policy_temp;
4480         
4481                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4482                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4483         
4484                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4485                         break;
4486                 default:
4487                         return NT_STATUS_INVALID_INFO_CLASS;
4488         }
4489
4490         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4491
4492         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4493
4494         return r_u->status;
4495 }
4496
4497 /*******************************************************************
4498  _samr_
4499  ********************************************************************/
4500
4501 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4502 {
4503         time_t u_expire, u_min_age;
4504         time_t u_logout;
4505         time_t u_lock_duration, u_reset_time;
4506
4507         r_u->status = NT_STATUS_OK;
4508
4509         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4510
4511         /* find the policy handle.  open a policy on it. */
4512         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4513                 return NT_STATUS_INVALID_HANDLE;
4514
4515         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4516
4517         switch (q_u->switch_value) {
4518                 case 0x01:
4519                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4520                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4521                         
4522                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4523                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4524                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4525                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4526                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4527                         break;
4528                 case 0x02:
4529                         break;
4530                 case 0x03:
4531                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4532                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4533                         break;
4534                 case 0x05:
4535                         break;
4536                 case 0x06:
4537                         break;
4538                 case 0x07:
4539                         break;
4540                 case 0x0c:
4541                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4542                         if (u_lock_duration != -1)
4543                                 u_lock_duration /= 60;
4544                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4545                         
4546                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4547                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4548                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4549                         break;
4550                 default:
4551                         return NT_STATUS_INVALID_INFO_CLASS;
4552         }
4553
4554         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4555
4556         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4557
4558         return r_u->status;
4559 }