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