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