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