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