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