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