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