6cd5da4892f802f29de34cbba75035159ac569a8
[jra/samba/.git] / source / 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                         if (!p->session_key.length) {
2957                                 return NT_STATUS_NO_USER_SESSION_KEY;
2958                         }
2959                         SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
2960
2961                         dump_data(100, (char *)ctr->info.id24->pass, 516);
2962
2963                         if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2964                                 return NT_STATUS_ACCESS_DENIED;
2965                         break;
2966
2967                 case 25:
2968 #if 0
2969                         /*
2970                          * Currently we don't really know how to unmarshall
2971                          * the level 25 struct, and the password encryption
2972                          * is different. This is a placeholder for when we
2973                          * do understand it. In the meantime just return INVALID
2974                          * info level and W2K SP2 drops down to level 23... JRA.
2975                          */
2976
2977                         if (!p->session_key.length) {
2978                                 return NT_STATUS_NO_USER_SESSION_KEY;
2979                         }
2980                         SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
2981
2982                         dump_data(100, (char *)ctr->info.id25->pass, 532);
2983
2984                         if (!set_user_info_pw(ctr->info.id25->pass, &sid))
2985                                 return NT_STATUS_ACCESS_DENIED;
2986                         break;
2987 #endif
2988                         return NT_STATUS_INVALID_INFO_CLASS;
2989
2990                 case 23:
2991                         if (!p->session_key.length) {
2992                                 return NT_STATUS_NO_USER_SESSION_KEY;
2993                         }
2994                         SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
2995
2996                         dump_data(100, (char *)ctr->info.id23->pass, 516);
2997
2998                         if (!set_user_info_23(ctr->info.id23, &sid))
2999                                 return NT_STATUS_ACCESS_DENIED;
3000                         break;
3001
3002                 default:
3003                         return NT_STATUS_INVALID_INFO_CLASS;
3004         }
3005
3006         return r_u->status;
3007 }
3008
3009 /*******************************************************************
3010  samr_reply_set_userinfo2
3011  ********************************************************************/
3012
3013 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3014 {
3015         DOM_SID sid;
3016         SAM_USERINFO_CTR *ctr = q_u->ctr;
3017         POLICY_HND *pol = &q_u->pol;
3018         uint16 switch_value = q_u->switch_value;
3019         uint32 acc_granted;
3020         uint32 acc_required;
3021
3022         DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3023
3024         r_u->status = NT_STATUS_OK;
3025
3026         /* find the policy handle.  open a policy on it. */
3027         if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3028                 return NT_STATUS_INVALID_HANDLE;
3029         
3030         acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */   
3031         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3032                 return r_u->status;
3033         }
3034
3035         DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3036
3037         if (ctr == NULL) {
3038                 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3039                 return NT_STATUS_INVALID_INFO_CLASS;
3040         }
3041
3042         switch_value=ctr->switch_value;
3043
3044         /* ok!  user info levels (lots: see MSDEV help), off we go... */
3045         switch (switch_value) {
3046                 case 21:
3047                         if (!set_user_info_21(ctr->info.id21, &sid))
3048                                 return NT_STATUS_ACCESS_DENIED;
3049                         break;
3050                 case 20:
3051                         if (!set_user_info_20(ctr->info.id20, &sid))
3052                                 return NT_STATUS_ACCESS_DENIED;
3053                         break;
3054                 case 16:
3055                         if (!set_user_info_10(ctr->info.id10, &sid))
3056                                 return NT_STATUS_ACCESS_DENIED;
3057                         break;
3058                 case 18:
3059                         /* Used by AS/U JRA. */
3060                         if (!set_user_info_12(ctr->info.id12, &sid))
3061                                 return NT_STATUS_ACCESS_DENIED;
3062                         break;
3063                 default:
3064                         return NT_STATUS_INVALID_INFO_CLASS;
3065         }
3066
3067         return r_u->status;
3068 }
3069
3070 /*********************************************************************
3071  _samr_query_aliasmem
3072 *********************************************************************/
3073
3074 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3075 {
3076         int num_groups = 0, tmp_num_groups=0;
3077         uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3078         struct samr_info *info = NULL;
3079         int i,j;
3080                 
3081         NTSTATUS ntstatus1;
3082         NTSTATUS ntstatus2;
3083
3084         /* until i see a real useraliases query, we fack one up */
3085
3086         /* I have seen one, JFM 2/12/2001 */
3087         /*
3088          * Explanation of what this call does:
3089          * for all the SID given in the request:
3090          * return a list of alias (local groups)
3091          * that have those SID as members.
3092          *
3093          * and that's the alias in the domain specified
3094          * in the policy_handle
3095          *
3096          * if the policy handle is on an incorrect sid
3097          * for example a user's sid
3098          * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3099          */
3100         
3101         r_u->status = NT_STATUS_OK;
3102
3103         DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3104
3105         /* find the policy handle.  open a policy on it. */
3106         if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3107                 return NT_STATUS_INVALID_HANDLE;
3108                 
3109         ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3110         ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3111         
3112         if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3113                 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3114                     !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3115                         return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3116                 }
3117         }               
3118
3119         if (!sid_check_is_domain(&info->sid) &&
3120             !sid_check_is_builtin(&info->sid))
3121                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3122
3123
3124         for (i=0; i<q_u->num_sids1; i++) {
3125
3126                 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3127
3128                 /*
3129                  * if there is an error, we just continue as
3130                  * it can be an unfound user or group
3131                  */
3132                 if (!NT_STATUS_IS_OK(r_u->status)) {
3133                         DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3134                         continue;
3135                 }
3136
3137                 if (tmp_num_groups==0) {
3138                         DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3139                         continue;
3140                 }
3141
3142                 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3143                 if (new_rids==NULL) {
3144                         DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3145                         return NT_STATUS_NO_MEMORY;
3146                 }
3147                 rids=new_rids;
3148
3149                 for (j=0; j<tmp_num_groups; j++)
3150                         rids[j+num_groups]=tmp_rids[j];
3151                 
3152                 safe_free(tmp_rids);
3153                 
3154                 num_groups+=tmp_num_groups;
3155         }
3156         
3157         init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3158         return NT_STATUS_OK;
3159 }
3160
3161 /*********************************************************************
3162  _samr_query_aliasmem
3163 *********************************************************************/
3164
3165 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3166 {
3167         int i;
3168
3169         GROUP_MAP map;
3170         int num_uids = 0;
3171         DOM_SID2 *sid;
3172         uid_t *uid=NULL;
3173
3174         DOM_SID alias_sid;
3175         DOM_SID als_sid;
3176         uint32 alias_rid;
3177         fstring alias_sid_str;
3178         DOM_SID temp_sid;
3179
3180         SAM_ACCOUNT *sam_user = NULL;
3181         BOOL check;
3182         uint32 acc_granted;
3183
3184         /* find the policy handle.  open a policy on it. */
3185         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3186                 return NT_STATUS_INVALID_HANDLE;
3187         
3188         if (!NT_STATUS_IS_OK(r_u->status = 
3189                 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3190                 return r_u->status;
3191         }
3192                 
3193         sid_copy(&als_sid, &alias_sid);
3194         sid_to_string(alias_sid_str, &alias_sid);
3195         sid_split_rid(&alias_sid, &alias_rid);
3196
3197         DEBUG(10, ("sid is %s\n", alias_sid_str));
3198
3199         if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3200                 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3201                 if(!get_builtin_group_from_sid(als_sid, &map))
3202                         return NT_STATUS_NO_SUCH_ALIAS;
3203         } else {
3204                 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3205                         DEBUG(10, ("lookup on Server SID\n"));
3206                         if(!get_local_group_from_sid(als_sid, &map))
3207                                 return NT_STATUS_NO_SUCH_ALIAS;
3208                 }
3209         }
3210
3211         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3212                 return NT_STATUS_NO_SUCH_ALIAS;
3213
3214         DEBUG(10, ("sid is %s\n", alias_sid_str));
3215         sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_uids); 
3216         if (num_uids!=0 && sid == NULL) 
3217                 return NT_STATUS_NO_MEMORY;
3218
3219         for (i = 0; i < num_uids; i++) {
3220                 struct passwd *pass;
3221                 uint32 rid;
3222
3223                 sid_copy(&temp_sid, get_global_sam_sid());
3224
3225                 pass = getpwuid_alloc(uid[i]);
3226                 if (!pass) continue;
3227
3228                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3229                         passwd_free(&pass);
3230                         continue;
3231                 }
3232
3233                 become_root();
3234                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3235                 unbecome_root();
3236         
3237                 if (check != True) {
3238                         pdb_free_sam(&sam_user);
3239                         passwd_free(&pass);
3240                         continue;
3241                 }
3242         
3243                 rid = pdb_get_user_rid(sam_user);
3244                 if (rid == 0) {
3245                         pdb_free_sam(&sam_user);
3246                         passwd_free(&pass);
3247                         continue;
3248                 }
3249
3250                 pdb_free_sam(&sam_user);
3251                 passwd_free(&pass);
3252
3253                 sid_append_rid(&temp_sid, rid);
3254                 
3255                 init_dom_sid2(&sid[i], &temp_sid);
3256         }
3257
3258         DEBUG(10, ("sid is %s\n", alias_sid_str));
3259         init_samr_r_query_aliasmem(r_u, num_uids, sid, NT_STATUS_OK);
3260
3261         return NT_STATUS_OK;
3262 }
3263
3264 /*********************************************************************
3265  _samr_query_groupmem
3266 *********************************************************************/
3267
3268 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3269 {
3270         int num_uids = 0;
3271         int i;
3272         DOM_SID group_sid;
3273         uint32 group_rid;
3274         fstring group_sid_str;
3275         uid_t *uid=NULL;
3276         
3277         GROUP_MAP map;
3278
3279         uint32 *rid=NULL;
3280         uint32 *attr=NULL;
3281
3282         SAM_ACCOUNT *sam_user = NULL;
3283         BOOL check;
3284         uint32 acc_granted;
3285
3286         /* find the policy handle.  open a policy on it. */
3287         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3288                 return NT_STATUS_INVALID_HANDLE;
3289                 
3290         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3291                 return r_u->status;
3292         }
3293                 
3294         /* todo: change to use sid_compare_front */
3295
3296         sid_split_rid(&group_sid, &group_rid);
3297         sid_to_string(group_sid_str, &group_sid);
3298         DEBUG(10, ("sid is %s\n", group_sid_str));
3299
3300         /* can we get a query for an SID outside our domain ? */
3301         if (!sid_equal(&group_sid, get_global_sam_sid()))
3302                 return NT_STATUS_NO_SUCH_GROUP;
3303
3304         sid_append_rid(&group_sid, group_rid);
3305         DEBUG(10, ("lookup on Domain SID\n"));
3306
3307         if(!get_domain_group_from_sid(group_sid, &map))
3308                 return NT_STATUS_NO_SUCH_GROUP;
3309
3310         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
3311                 return NT_STATUS_NO_SUCH_GROUP;
3312
3313         rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3314         attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_uids);
3315         
3316         if (num_uids!=0 && (rid==NULL || attr==NULL))
3317                 return NT_STATUS_NO_MEMORY;
3318         
3319         for (i=0; i<num_uids; i++) {
3320                 struct passwd *pass;
3321                 uint32 urid;
3322
3323                 pass = getpwuid_alloc(uid[i]);
3324                 if (!pass) continue;
3325
3326                 if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_user))) {
3327                         passwd_free(&pass);
3328                         continue;
3329                 }
3330
3331                 become_root();
3332                 check = pdb_getsampwnam(sam_user, pass->pw_name);
3333                 unbecome_root();
3334         
3335                 if (check != True) {
3336                         pdb_free_sam(&sam_user);
3337                         passwd_free(&pass);
3338                         continue;
3339                 }
3340         
3341                 urid = pdb_get_user_rid(sam_user);
3342                 if (urid == 0) {
3343                         pdb_free_sam(&sam_user);
3344                         passwd_free(&pass);
3345                         continue;
3346                 }
3347
3348                 pdb_free_sam(&sam_user);
3349                 passwd_free(&pass);
3350
3351                 rid[i] = urid;
3352                 attr[i] = SID_NAME_USER;                
3353         }
3354
3355         init_samr_r_query_groupmem(r_u, num_uids, rid, attr, NT_STATUS_OK);
3356
3357         return NT_STATUS_OK;
3358 }
3359
3360 /*********************************************************************
3361  _samr_add_aliasmem
3362 *********************************************************************/
3363
3364 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3365 {
3366         DOM_SID alias_sid;
3367         fstring alias_sid_str;
3368         uid_t uid;
3369         struct passwd *pwd;
3370         struct group *grp;
3371         fstring grp_name;
3372         GROUP_MAP map;
3373         NTSTATUS ret;
3374         SAM_ACCOUNT *sam_user = NULL;
3375         BOOL check;
3376         uint32 acc_granted;
3377
3378         /* Find the policy handle. Open a policy on it. */
3379         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3380                 return NT_STATUS_INVALID_HANDLE;
3381         
3382         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3383                 return r_u->status;
3384         }
3385                 
3386         sid_to_string(alias_sid_str, &alias_sid);
3387         DEBUG(10, ("sid is %s\n", alias_sid_str));
3388
3389         if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3390                 DEBUG(10, ("adding member on Server SID\n"));
3391                 if(!get_local_group_from_sid(alias_sid, &map))
3392                         return NT_STATUS_NO_SUCH_ALIAS;
3393         
3394         } else {
3395                 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3396                         DEBUG(10, ("adding member on BUILTIN SID\n"));
3397                         if( !get_local_group_from_sid(alias_sid, &map))
3398                                 return NT_STATUS_NO_SUCH_ALIAS;
3399
3400                 } else
3401                         return NT_STATUS_NO_SUCH_ALIAS;
3402         }
3403
3404         ret = pdb_init_sam(&sam_user);
3405         if (!NT_STATUS_IS_OK(ret))
3406                 return ret;
3407         
3408         check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3409         
3410         if (check != True) {
3411                 pdb_free_sam(&sam_user);
3412                 return NT_STATUS_NO_SUCH_USER;
3413         }
3414
3415         /* check a real user exist before we run the script to add a user to a group */
3416         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3417                 pdb_free_sam(&sam_user);
3418                 return NT_STATUS_NO_SUCH_USER;
3419         }
3420
3421         pdb_free_sam(&sam_user);
3422
3423         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3424                 return NT_STATUS_NO_SUCH_USER;
3425         }
3426         
3427         if ((grp=getgrgid(map.gid)) == NULL) {
3428                 passwd_free(&pwd);
3429                 return NT_STATUS_NO_SUCH_ALIAS;
3430         }
3431
3432         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3433         fstrcpy(grp_name, grp->gr_name);
3434
3435         /* if the user is already in the group */
3436         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3437                 passwd_free(&pwd);
3438                 return NT_STATUS_MEMBER_IN_ALIAS;
3439         }
3440
3441         /* 
3442          * ok, the group exist, the user exist, the user is not in the group,
3443          * we can (finally) add it to the group !
3444          */
3445         smb_add_user_group(grp_name, pwd->pw_name);
3446
3447         /* check if the user has been added then ... */
3448         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3449                 passwd_free(&pwd);
3450                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3451         }
3452
3453         passwd_free(&pwd);
3454         return NT_STATUS_OK;
3455 }
3456
3457 /*********************************************************************
3458  _samr_del_aliasmem
3459 *********************************************************************/
3460
3461 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3462 {
3463         DOM_SID alias_sid;
3464         fstring alias_sid_str;
3465         struct group *grp;
3466         fstring grp_name;
3467         GROUP_MAP map;
3468         SAM_ACCOUNT *sam_pass=NULL;
3469         uint32 acc_granted;
3470
3471         /* Find the policy handle. Open a policy on it. */
3472         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3473                 return NT_STATUS_INVALID_HANDLE;
3474         
3475         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3476                 return r_u->status;
3477         }
3478         
3479         sid_to_string(alias_sid_str, &alias_sid);
3480         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3481
3482         if (!sid_check_is_in_our_domain(&alias_sid) &&
3483             !sid_check_is_in_builtin(&alias_sid)) {
3484                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3485                 return NT_STATUS_NO_SUCH_ALIAS;
3486         }
3487
3488         if( !get_local_group_from_sid(alias_sid, &map))
3489                 return NT_STATUS_NO_SUCH_ALIAS;
3490
3491         if ((grp=getgrgid(map.gid)) == NULL)
3492                 return NT_STATUS_NO_SUCH_ALIAS;
3493
3494         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3495         fstrcpy(grp_name, grp->gr_name);
3496
3497         /* check if the user exists before trying to remove it from the group */
3498         pdb_init_sam(&sam_pass);
3499         if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3500                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3501                 pdb_free_sam(&sam_pass);
3502                 return NT_STATUS_NO_SUCH_USER;
3503         }
3504
3505         /* if the user is not in the group */
3506         if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3507                 pdb_free_sam(&sam_pass);
3508                 return NT_STATUS_MEMBER_IN_ALIAS;
3509         }
3510
3511         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3512
3513         /* check if the user has been removed then ... */
3514         if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3515                 pdb_free_sam(&sam_pass);
3516                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3517         }
3518
3519         pdb_free_sam(&sam_pass);
3520         return NT_STATUS_OK;
3521 }
3522
3523 /*********************************************************************
3524  _samr_add_groupmem
3525 *********************************************************************/
3526
3527 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3528 {
3529         DOM_SID group_sid;
3530         DOM_SID user_sid;
3531         fstring group_sid_str;
3532         uid_t uid;
3533         struct passwd *pwd;
3534         struct group *grp;
3535         fstring grp_name;
3536         GROUP_MAP map;
3537         NTSTATUS ret;
3538         SAM_ACCOUNT *sam_user=NULL;
3539         BOOL check;
3540         uint32 acc_granted;
3541
3542         /* Find the policy handle. Open a policy on it. */
3543         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3544                 return NT_STATUS_INVALID_HANDLE;
3545         
3546         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3547                 return r_u->status;
3548         }
3549
3550         sid_to_string(group_sid_str, &group_sid);
3551         DEBUG(10, ("sid is %s\n", group_sid_str));
3552
3553         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3554                 return NT_STATUS_NO_SUCH_GROUP;
3555
3556         DEBUG(10, ("lookup on Domain SID\n"));
3557
3558         if(!get_domain_group_from_sid(group_sid, &map))
3559                 return NT_STATUS_NO_SUCH_GROUP;
3560
3561         sid_copy(&user_sid, get_global_sam_sid());
3562         sid_append_rid(&user_sid, q_u->rid);
3563
3564         ret = pdb_init_sam(&sam_user);
3565         if (!NT_STATUS_IS_OK(ret))
3566                 return ret;
3567         
3568         check = pdb_getsampwsid(sam_user, &user_sid);
3569         
3570         if (check != True) {
3571                 pdb_free_sam(&sam_user);
3572                 return NT_STATUS_NO_SUCH_USER;
3573         }
3574
3575         /* check a real user exist before we run the script to add a user to a group */
3576         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3577                 pdb_free_sam(&sam_user);
3578                 return NT_STATUS_NO_SUCH_USER;
3579         }
3580
3581         pdb_free_sam(&sam_user);
3582
3583         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3584                 return NT_STATUS_NO_SUCH_USER;
3585         }
3586
3587         if ((grp=getgrgid(map.gid)) == NULL) {
3588                 passwd_free(&pwd);
3589                 return NT_STATUS_NO_SUCH_GROUP;
3590         }
3591
3592         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3593         fstrcpy(grp_name, grp->gr_name);
3594
3595         /* if the user is already in the group */
3596         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3597                 passwd_free(&pwd);
3598                 return NT_STATUS_MEMBER_IN_GROUP;
3599         }
3600
3601         /* 
3602          * ok, the group exist, the user exist, the user is not in the group,
3603          *
3604          * we can (finally) add it to the group !
3605          */
3606
3607         smb_add_user_group(grp_name, pwd->pw_name);
3608
3609         /* check if the user has been added then ... */
3610         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3611                 passwd_free(&pwd);
3612                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3613         }
3614
3615         passwd_free(&pwd);
3616         return NT_STATUS_OK;
3617 }
3618
3619 /*********************************************************************
3620  _samr_del_groupmem
3621 *********************************************************************/
3622
3623 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3624 {
3625         DOM_SID group_sid;
3626         DOM_SID user_sid;
3627         SAM_ACCOUNT *sam_pass=NULL;
3628         GROUP_MAP map;
3629         fstring grp_name;
3630         struct group *grp;
3631         uint32 acc_granted;
3632
3633         /*
3634          * delete the group member named q_u->rid
3635          * who is a member of the sid associated with the handle
3636          * the rid is a user's rid as the group is a domain group.
3637          */
3638
3639         /* Find the policy handle. Open a policy on it. */
3640         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3641                 return NT_STATUS_INVALID_HANDLE;
3642         
3643         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3644                 return r_u->status;
3645         }
3646                 
3647         if (!sid_check_is_in_our_domain(&group_sid))
3648                 return NT_STATUS_NO_SUCH_GROUP;
3649
3650         sid_copy(&user_sid, get_global_sam_sid());
3651         sid_append_rid(&user_sid, q_u->rid);
3652
3653         if (!get_domain_group_from_sid(group_sid, &map))
3654                 return NT_STATUS_NO_SUCH_GROUP;
3655
3656         if ((grp=getgrgid(map.gid)) == NULL)
3657                 return NT_STATUS_NO_SUCH_GROUP;
3658
3659         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3660         fstrcpy(grp_name, grp->gr_name);
3661
3662         /* check if the user exists before trying to remove it from the group */
3663         pdb_init_sam(&sam_pass);
3664         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3665                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3666                 pdb_free_sam(&sam_pass);
3667                 return NT_STATUS_NO_SUCH_USER;
3668         }
3669
3670         /* if the user is not in the group */
3671         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3672                 pdb_free_sam(&sam_pass);
3673                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3674         }
3675
3676         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3677
3678         /* check if the user has been removed then ... */
3679         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3680                 pdb_free_sam(&sam_pass);
3681                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3682         }
3683         
3684         pdb_free_sam(&sam_pass);
3685         return NT_STATUS_OK;
3686
3687 }
3688
3689 /****************************************************************************
3690  Delete a UNIX user on demand.
3691 ****************************************************************************/
3692
3693 static int smb_delete_user(const char *unix_user)
3694 {
3695         pstring del_script;
3696         int ret;
3697
3698         /* try winbindd first since it is impossible to determine where 
3699            a user came from via NSS.  Try the delete user script if this fails
3700            meaning the user did not exist in winbindd's list of accounts */
3701
3702         if ( winbind_delete_user( unix_user ) ) {
3703                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3704                 return 0;
3705         }
3706
3707
3708         /* fall back to 'delete user script' */
3709
3710         pstrcpy(del_script, lp_deluser_script());
3711         if (! *del_script)
3712                 return -1;
3713         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3714         ret = smbrun(del_script,NULL);
3715         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3716
3717         return ret;
3718 }
3719
3720 /*********************************************************************
3721  _samr_delete_dom_user
3722 *********************************************************************/
3723
3724 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3725 {
3726         DOM_SID user_sid;
3727         SAM_ACCOUNT *sam_pass=NULL;
3728         uint32 acc_granted;
3729
3730         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3731
3732         /* Find the policy handle. Open a policy on it. */
3733         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3734                 return NT_STATUS_INVALID_HANDLE;
3735                 
3736         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3737                 return r_u->status;
3738         }
3739                 
3740         if (!sid_check_is_in_our_domain(&user_sid))
3741                 return NT_STATUS_CANNOT_DELETE;
3742
3743         /* check if the user exists before trying to delete */
3744         pdb_init_sam(&sam_pass);
3745         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3746                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3747                         sid_string_static(&user_sid)));
3748                 pdb_free_sam(&sam_pass);
3749                 return NT_STATUS_NO_SUCH_USER;
3750         }
3751
3752         /* delete the unix side */
3753         /*
3754          * note: we don't check if the delete really happened
3755          * as the script is not necessary present
3756          * and maybe the sysadmin doesn't want to delete the unix side
3757          */
3758         smb_delete_user(pdb_get_username(sam_pass));
3759
3760         /* and delete the samba side */
3761         if (!pdb_delete_sam_account(sam_pass)) {
3762                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3763                 pdb_free_sam(&sam_pass);
3764                 return NT_STATUS_CANNOT_DELETE;
3765         }
3766         
3767         pdb_free_sam(&sam_pass);
3768
3769         if (!close_policy_hnd(p, &q_u->user_pol))
3770                 return NT_STATUS_OBJECT_NAME_INVALID;
3771
3772         return NT_STATUS_OK;
3773 }
3774
3775 /*********************************************************************
3776  _samr_delete_dom_group
3777 *********************************************************************/
3778
3779 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3780 {
3781         DOM_SID group_sid;
3782         DOM_SID dom_sid;
3783         uint32 group_rid;
3784         fstring group_sid_str;
3785         gid_t gid;
3786         struct group *grp;
3787         GROUP_MAP map;
3788         uint32 acc_granted;
3789
3790         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3791
3792         /* Find the policy handle. Open a policy on it. */
3793         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3794                 return NT_STATUS_INVALID_HANDLE;
3795                 
3796         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3797                 return r_u->status;
3798         }
3799                 
3800         sid_copy(&dom_sid, &group_sid);
3801         sid_to_string(group_sid_str, &dom_sid);
3802         sid_split_rid(&dom_sid, &group_rid);
3803
3804         DEBUG(10, ("sid is %s\n", group_sid_str));
3805
3806         /* we check if it's our SID before deleting */
3807         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3808                 return NT_STATUS_NO_SUCH_GROUP;
3809
3810         DEBUG(10, ("lookup on Domain SID\n"));
3811
3812         if(!get_domain_group_from_sid(group_sid, &map))
3813                 return NT_STATUS_NO_SUCH_GROUP;
3814
3815         gid=map.gid;
3816
3817         /* check if group really exists */
3818         if ( (grp=getgrgid(gid)) == NULL)
3819                 return NT_STATUS_NO_SUCH_GROUP;
3820
3821         /* we can delete the UNIX group */
3822         smb_delete_group(grp->gr_name);
3823
3824         /* check if the group has been successfully deleted */
3825         if ( (grp=getgrgid(gid)) != NULL)
3826                 return NT_STATUS_ACCESS_DENIED;
3827
3828         if(!pdb_delete_group_mapping_entry(group_sid))
3829                 return NT_STATUS_ACCESS_DENIED;
3830
3831         if (!close_policy_hnd(p, &q_u->group_pol))
3832                 return NT_STATUS_OBJECT_NAME_INVALID;
3833
3834         return NT_STATUS_OK;
3835 }
3836
3837 /*********************************************************************
3838  _samr_delete_dom_alias
3839 *********************************************************************/
3840
3841 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3842 {
3843         DOM_SID alias_sid;
3844         DOM_SID dom_sid;
3845         uint32 alias_rid;
3846         fstring alias_sid_str;
3847         gid_t gid;
3848         struct group *grp;
3849         GROUP_MAP map;
3850         uint32 acc_granted;
3851
3852         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3853
3854         /* Find the policy handle. Open a policy on it. */
3855         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3856                 return NT_STATUS_INVALID_HANDLE;
3857         
3858         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3859                 return r_u->status;
3860         }
3861                 
3862         sid_copy(&dom_sid, &alias_sid);
3863         sid_to_string(alias_sid_str, &dom_sid);
3864         sid_split_rid(&dom_sid, &alias_rid);
3865
3866         DEBUG(10, ("sid is %s\n", alias_sid_str));
3867
3868         /* we check if it's our SID before deleting */
3869         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3870                 return NT_STATUS_NO_SUCH_ALIAS;
3871
3872         DEBUG(10, ("lookup on Local SID\n"));
3873
3874         if(!get_local_group_from_sid(alias_sid, &map))
3875                 return NT_STATUS_NO_SUCH_ALIAS;
3876
3877         gid=map.gid;
3878
3879         /* check if group really exists */
3880         if ( (grp=getgrgid(gid)) == NULL)
3881                 return NT_STATUS_NO_SUCH_ALIAS;
3882
3883         /* we can delete the UNIX group */
3884         smb_delete_group(grp->gr_name);
3885
3886         /* check if the group has been successfully deleted */
3887         if ( (grp=getgrgid(gid)) != NULL)
3888                 return NT_STATUS_ACCESS_DENIED;
3889
3890         /* don't check if we removed it as it could be an un-mapped group */
3891         pdb_delete_group_mapping_entry(alias_sid);
3892
3893         if (!close_policy_hnd(p, &q_u->alias_pol))
3894                 return NT_STATUS_OBJECT_NAME_INVALID;
3895
3896         return NT_STATUS_OK;
3897 }
3898
3899 /*********************************************************************
3900  _samr_create_dom_group
3901 *********************************************************************/
3902
3903 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3904 {
3905         DOM_SID dom_sid;
3906         DOM_SID info_sid;
3907         fstring name;
3908         fstring sid_string;
3909         struct group *grp;
3910         struct samr_info *info;
3911         uint32 acc_granted;
3912         gid_t gid;
3913
3914         /* Find the policy handle. Open a policy on it. */
3915         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3916                 return NT_STATUS_INVALID_HANDLE;
3917         
3918         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3919                 return r_u->status;
3920         }
3921                 
3922         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3923                 return NT_STATUS_ACCESS_DENIED;
3924
3925         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3926
3927         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3928
3929         /* check if group already exist */
3930         if ((grp=getgrnam(name)) != NULL)
3931                 return NT_STATUS_GROUP_EXISTS;
3932
3933         /* we can create the UNIX group */
3934         if (smb_create_group(name, &gid) != 0)
3935                 return NT_STATUS_ACCESS_DENIED;
3936
3937         /* check if the group has been successfully created */
3938         if ((grp=getgrgid(gid)) == NULL)
3939                 return NT_STATUS_ACCESS_DENIED;
3940
3941         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3942
3943         /* add the group to the mapping table */
3944         sid_copy(&info_sid, get_global_sam_sid());
3945         sid_append_rid(&info_sid, r_u->rid);
3946         sid_to_string(sid_string, &info_sid);
3947
3948         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3949                 return NT_STATUS_ACCESS_DENIED;
3950
3951         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3952                 return NT_STATUS_NO_MEMORY;
3953
3954         /* get a (unique) handle.  open a policy on it. */
3955         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3956                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3957
3958         return NT_STATUS_OK;
3959 }
3960
3961 /*********************************************************************
3962  _samr_create_dom_alias
3963 *********************************************************************/
3964
3965 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3966 {
3967         DOM_SID dom_sid;
3968         DOM_SID info_sid;
3969         fstring name;
3970         fstring sid_string;
3971         struct group *grp;
3972         struct samr_info *info;
3973         uint32 acc_granted;
3974         gid_t gid;
3975
3976         /* Find the policy handle. Open a policy on it. */
3977         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3978                 return NT_STATUS_INVALID_HANDLE;
3979                 
3980         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3981                 return r_u->status;
3982         }
3983                 
3984         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3985                 return NT_STATUS_ACCESS_DENIED;
3986
3987         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3988
3989         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3990
3991         /* check if group already exists */
3992         if ( (grp=getgrnam(name)) != NULL)
3993                 return NT_STATUS_GROUP_EXISTS;
3994
3995         /* we can create the UNIX group */
3996         if (smb_create_group(name, &gid) != 0)
3997                 return NT_STATUS_ACCESS_DENIED;
3998
3999         /* check if the group has been successfully created */
4000         if ((grp=getgrgid(gid)) == NULL)
4001                 return NT_STATUS_ACCESS_DENIED;
4002
4003         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
4004
4005         sid_copy(&info_sid, get_global_sam_sid());
4006         sid_append_rid(&info_sid, r_u->rid);
4007         sid_to_string(sid_string, &info_sid);
4008
4009         /* add the group to the mapping table */
4010         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
4011                 return NT_STATUS_ACCESS_DENIED;
4012
4013         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4014                 return NT_STATUS_NO_MEMORY;
4015
4016         /* get a (unique) handle.  open a policy on it. */
4017         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4018                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4019
4020         return NT_STATUS_OK;
4021 }
4022
4023 /*********************************************************************
4024  _samr_query_groupinfo
4025
4026 sends the name/comment pair of a domain group
4027 level 1 send also the number of users of that group
4028 *********************************************************************/
4029
4030 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4031 {
4032         DOM_SID group_sid;
4033         GROUP_MAP map;
4034         uid_t *uid=NULL;
4035         int num_uids=0;
4036         GROUP_INFO_CTR *ctr;
4037         uint32 acc_granted;
4038         BOOL ret;
4039
4040         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4041                 return NT_STATUS_INVALID_HANDLE;
4042         
4043         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4044                 return r_u->status;
4045         }
4046                 
4047         become_root();
4048         ret = get_domain_group_from_sid(group_sid, &map);
4049         unbecome_root();
4050         if (!ret)
4051                 return NT_STATUS_INVALID_HANDLE;
4052
4053         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4054         if (ctr==NULL)
4055                 return NT_STATUS_NO_MEMORY;
4056
4057         switch (q_u->switch_level) {
4058                 case 1:
4059                         ctr->switch_value1 = 1;
4060                         if(!get_uid_list_of_group(map.gid, &uid, &num_uids))
4061                                 return NT_STATUS_NO_SUCH_GROUP;
4062                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_uids);
4063                         SAFE_FREE(uid);
4064                         break;
4065                 case 3:
4066                         ctr->switch_value1 = 3;
4067                         init_samr_group_info3(&ctr->group.info3);
4068                         break;
4069                 case 4:
4070                         ctr->switch_value1 = 4;
4071                         init_samr_group_info4(&ctr->group.info4, map.comment);
4072                         break;
4073                 default:
4074                         return NT_STATUS_INVALID_INFO_CLASS;
4075         }
4076
4077         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4078
4079         return NT_STATUS_OK;
4080 }
4081
4082 /*********************************************************************
4083  _samr_set_groupinfo
4084  
4085  update a domain group's comment.
4086 *********************************************************************/
4087
4088 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4089 {
4090         DOM_SID group_sid;
4091         GROUP_MAP map;
4092         GROUP_INFO_CTR *ctr;
4093         uint32 acc_granted;
4094
4095         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4096                 return NT_STATUS_INVALID_HANDLE;
4097         
4098         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4099                 return r_u->status;
4100         }
4101                 
4102         if (!get_domain_group_from_sid(group_sid, &map))
4103                 return NT_STATUS_NO_SUCH_GROUP;
4104         
4105         ctr=q_u->ctr;
4106
4107         switch (ctr->switch_value1) {
4108                 case 1:
4109                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4110                         break;
4111                 case 4:
4112                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4113                         break;
4114                 default:
4115                         return NT_STATUS_INVALID_INFO_CLASS;
4116         }
4117
4118         if(!pdb_update_group_mapping_entry(&map)) {
4119                 return NT_STATUS_NO_SUCH_GROUP;
4120         }
4121
4122         return NT_STATUS_OK;
4123 }
4124
4125 /*********************************************************************
4126  _samr_set_aliasinfo
4127  
4128  update an alias's comment.
4129 *********************************************************************/
4130
4131 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4132 {
4133         DOM_SID group_sid;
4134         GROUP_MAP map;
4135         ALIAS_INFO_CTR *ctr;
4136         uint32 acc_granted;
4137
4138         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4139                 return NT_STATUS_INVALID_HANDLE;
4140         
4141         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4142                 return r_u->status;
4143         }
4144                 
4145         if (!get_local_group_from_sid(group_sid, &map))
4146                 return NT_STATUS_NO_SUCH_GROUP;
4147         
4148         ctr=&q_u->ctr;
4149
4150         switch (ctr->switch_value1) {
4151                 case 3:
4152                         unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4153                         break;
4154                 default:
4155                         return NT_STATUS_INVALID_INFO_CLASS;
4156         }
4157
4158         if(!pdb_update_group_mapping_entry(&map)) {
4159                 return NT_STATUS_NO_SUCH_GROUP;
4160         }
4161
4162         return NT_STATUS_OK;
4163 }
4164
4165 /*********************************************************************
4166  _samr_get_dom_pwinfo
4167 *********************************************************************/
4168
4169 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4170 {
4171         /* Perform access check.  Since this rpc does not require a
4172            policy handle it will not be caught by the access checks on
4173            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4174
4175         if (!pipe_access_check(p)) {
4176                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4177                 r_u->status = NT_STATUS_ACCESS_DENIED;
4178                 return r_u->status;
4179         }
4180
4181         /* Actually, returning zeros here works quite well :-). */
4182
4183         return NT_STATUS_OK;
4184 }
4185
4186 /*********************************************************************
4187  _samr_open_group
4188 *********************************************************************/
4189
4190 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4191 {
4192         DOM_SID sid;
4193         DOM_SID info_sid;
4194         GROUP_MAP map;
4195         struct samr_info *info;
4196         SEC_DESC         *psd = NULL;
4197         uint32            acc_granted;
4198         uint32            des_access = q_u->access_mask;
4199         size_t            sd_size;
4200         NTSTATUS          status;
4201         fstring sid_string;
4202         BOOL ret;
4203
4204         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4205                 return NT_STATUS_INVALID_HANDLE;
4206         
4207         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4208                 return status;
4209         }
4210                 
4211         /*check if access can be granted as requested by client. */
4212         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4213         se_map_generic(&des_access,&grp_generic_mapping);
4214         if (!NT_STATUS_IS_OK(status = 
4215                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4216                                                       des_access, &acc_granted, "_samr_open_group"))) {
4217                 return status;
4218         }
4219
4220
4221         /* this should not be hard-coded like this */
4222         if (!sid_equal(&sid, get_global_sam_sid()))
4223                 return NT_STATUS_ACCESS_DENIED;
4224
4225         sid_copy(&info_sid, get_global_sam_sid());
4226         sid_append_rid(&info_sid, q_u->rid_group);
4227         sid_to_string(sid_string, &info_sid);
4228
4229         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4230                 return NT_STATUS_NO_MEMORY;
4231                 
4232         info->acc_granted = acc_granted;
4233
4234         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4235
4236         /* check if that group really exists */
4237         become_root();
4238         ret = get_domain_group_from_sid(info->sid, &map);
4239         unbecome_root();
4240         if (!ret)
4241                 return NT_STATUS_NO_SUCH_GROUP;
4242
4243         /* get a (unique) handle.  open a policy on it. */
4244         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4245                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4246
4247         return NT_STATUS_OK;
4248 }
4249
4250 /*********************************************************************
4251  _samr_remove_user_foreign_domain
4252 *********************************************************************/
4253
4254 NTSTATUS _samr_remove_user_foreign_domain(pipes_struct *p, 
4255                                           SAMR_Q_REMOVE_USER_FOREIGN_DOMAIN *q_u, 
4256                                           SAMR_R_REMOVE_USER_FOREIGN_DOMAIN *r_u)
4257 {
4258         DOM_SID                 user_sid, dom_sid;
4259         SAM_ACCOUNT             *sam_pass=NULL;
4260         uint32                  acc_granted;
4261         
4262         sid_copy( &user_sid, &q_u->sid.sid );
4263         
4264         DEBUG(5,("_samr_remove_user_foreign_domain: removing user [%s]\n",
4265                 sid_string_static(&user_sid)));
4266                 
4267         /* Find the policy handle. Open a policy on it. */
4268         
4269         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
4270                 return NT_STATUS_INVALID_HANDLE;
4271                 
4272         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 
4273                 STD_RIGHT_DELETE_ACCESS, "_samr_remove_user_foreign_domain"))) 
4274         {
4275                 return r_u->status;
4276         }
4277                 
4278         if ( !sid_check_is_in_our_domain(&user_sid) ) {
4279                 DEBUG(5,("_samr_remove_user_foreign_domain: user not is our domain!\n"));
4280                 return NT_STATUS_NO_SUCH_USER;
4281         }
4282
4283         /* check if the user exists before trying to delete */
4284         
4285         pdb_init_sam(&sam_pass);
4286         
4287         if ( !pdb_getsampwsid(sam_pass, &user_sid) ) {
4288         
4289                 DEBUG(5,("_samr_remove_user_foreign_domain:User %s doesn't exist.\n", 
4290                         sid_string_static(&user_sid)));
4291                         
4292                 pdb_free_sam(&sam_pass);
4293                 
4294                 return NT_STATUS_NO_SUCH_USER;
4295         }
4296
4297         /*
4298          * delete the unix side
4299          * 
4300          * note: we don't check if the delete really happened
4301          * as the script is not necessary present
4302          * and maybe the sysadmin doesn't want to delete the unix side
4303          */
4304          
4305         smb_delete_user(pdb_get_username(sam_pass));
4306
4307         /* and delete the samba side */
4308         
4309         if ( !pdb_delete_sam_account(sam_pass) ) {
4310         
4311                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
4312                 pdb_free_sam(&sam_pass);
4313                 
4314                 return NT_STATUS_CANNOT_DELETE;
4315         }
4316         
4317         pdb_free_sam(&sam_pass);
4318
4319         return NT_STATUS_OK;
4320 }
4321
4322 /*******************************************************************
4323  _samr_unknown_2e
4324  ********************************************************************/
4325
4326 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4327 {
4328         struct samr_info *info = NULL;
4329         SAM_UNK_CTR *ctr;
4330         uint32 min_pass_len,pass_hist,flag;
4331         time_t u_expire, u_min_age;
4332         NTTIME nt_expire, nt_min_age;
4333
4334         time_t u_lock_duration, u_reset_time;
4335         NTTIME nt_lock_duration, nt_reset_time;
4336         uint32 lockout;
4337         
4338         time_t u_logout;
4339         NTTIME nt_logout;
4340
4341         uint32 num_users=0, num_groups=0, num_aliases=0;
4342
4343         uint32 account_policy_temp;
4344
4345         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4346                 return NT_STATUS_NO_MEMORY;
4347
4348         ZERO_STRUCTP(ctr);
4349
4350         r_u->status = NT_STATUS_OK;
4351
4352         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4353
4354         /* find the policy handle.  open a policy on it. */
4355         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4356                 return NT_STATUS_INVALID_HANDLE;
4357
4358         switch (q_u->switch_value) {
4359                 case 0x01:
4360                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4361                         min_pass_len = account_policy_temp;
4362
4363                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4364                         pass_hist = account_policy_temp;
4365
4366                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4367                         flag = account_policy_temp;
4368
4369                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4370                         u_expire = account_policy_temp;
4371
4372                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4373                         u_min_age = account_policy_temp;
4374
4375                         unix_to_nt_time_abs(&nt_expire, u_expire);
4376                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4377
4378                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4379                                        flag, nt_expire, nt_min_age);
4380                         break;
4381                 case 0x02:
4382                         become_root();          
4383                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4384                         unbecome_root();
4385                         if (!NT_STATUS_IS_OK(r_u->status)) {
4386                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4387                                 return r_u->status;
4388                         }
4389                         num_users=info->disp_info.num_user_account;
4390                         free_samr_db(info);
4391                         
4392                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4393                         if (NT_STATUS_IS_ERR(r_u->status)) {
4394                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4395                                 return r_u->status;
4396                         }
4397                         num_groups=info->disp_info.num_group_account;
4398                         free_samr_db(info);
4399
4400                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4401                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4402                                        num_users, num_groups, num_aliases);
4403                         break;
4404                 case 0x03:
4405                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4406                         u_logout = account_policy_temp;
4407
4408                         unix_to_nt_time_abs(&nt_logout, u_logout);
4409                         
4410                         init_unk_info3(&ctr->info.inf3, nt_logout);
4411                         break;
4412                 case 0x05:
4413                         init_unk_info5(&ctr->info.inf5, global_myname());
4414                         break;
4415                 case 0x06:
4416                         init_unk_info6(&ctr->info.inf6);
4417                         break;
4418                 case 0x07:
4419                         init_unk_info7(&ctr->info.inf7);
4420                         break;
4421                 case 0x0c:
4422                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4423                         u_lock_duration = account_policy_temp;
4424
4425                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4426                         u_reset_time = account_policy_temp;
4427
4428                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4429                         lockout = account_policy_temp;
4430         
4431                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4432                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4433         
4434                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4435                         break;
4436                 default:
4437                         return NT_STATUS_INVALID_INFO_CLASS;
4438         }
4439
4440         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4441
4442         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4443
4444         return r_u->status;
4445 }
4446
4447 /*******************************************************************
4448  _samr_
4449  ********************************************************************/
4450
4451 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4452 {
4453         time_t u_expire, u_min_age;
4454         time_t u_logout;
4455         time_t u_lock_duration, u_reset_time;
4456
4457         r_u->status = NT_STATUS_OK;
4458
4459         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4460
4461         /* find the policy handle.  open a policy on it. */
4462         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4463                 return NT_STATUS_INVALID_HANDLE;
4464
4465         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4466
4467         switch (q_u->switch_value) {
4468                 case 0x01:
4469                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4470                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4471                         
4472                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4473                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4474                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4475                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4476                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4477                         break;
4478                 case 0x02:
4479                         break;
4480                 case 0x03:
4481                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4482                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4483                         break;
4484                 case 0x05:
4485                         break;
4486                 case 0x06:
4487                         break;
4488                 case 0x07:
4489                         break;
4490                 case 0x0c:
4491                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4492                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4493                         
4494                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4495                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4496                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4497                         break;
4498                 default:
4499                         return NT_STATUS_INVALID_INFO_CLASS;
4500         }
4501
4502         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4503
4504         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4505
4506         return r_u->status;
4507 }