This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to...
[samba.git] / source3 / rpc_server / srv_samr_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison               2001-2002,
9  *  Copyright (C) Jean François Micouleau      1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002.
11  *  Copyright (C) Gerald (Jerry) Carter             2003.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 /*
29  * This is the implementation of the SAMR code.
30  */
31
32 #include "includes.h"
33
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
36
37 extern DOM_SID global_sid_Builtin;
38
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
42
43
44 typedef struct _disp_info {
45         BOOL user_dbloaded;
46         uint32 num_user_account;
47         SAM_ACCOUNT *disp_user_info;
48         BOOL group_dbloaded;
49         uint32 num_group_account;
50         DOMAIN_GRP *disp_group_info;
51 } DISP_INFO;
52
53 struct samr_info {
54         /* for use by the \PIPE\samr policy */
55         DOM_SID sid;
56         uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
57         uint32 acc_granted;
58         uint16 acb_mask;
59         BOOL all_machines;
60         DISP_INFO disp_info;
61
62         TALLOC_CTX *mem_ctx;
63 };
64
65 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
66 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
67 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
68 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
69 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
70
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
72
73 /*******************************************************************
74  Checks if access to an object should be granted, and returns that
75  level of access for further checks.
76 ********************************************************************/
77
78 NTSTATUS access_check_samr_object(SEC_DESC *psd, NT_USER_TOKEN *nt_user_token, uint32 des_access, 
79                                   uint32 *acc_granted, const char *debug) 
80 {
81         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
82
83         if (!se_access_check(psd, nt_user_token, des_access, acc_granted, &status)) {
84                 *acc_granted = des_access;
85                 if (geteuid() == sec_initial_uid()) {
86                         DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n",
87                                 debug, des_access));
88                         DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
89                         status = NT_STATUS_OK;
90                 }
91                 else {
92                         DEBUG(2,("%s: ACCESS DENIED  (requested: %#010x)\n",
93                                 debug, des_access));
94                 }
95         }
96         return status;
97 }
98
99 /*******************************************************************
100  Checks if access to a function can be granted
101 ********************************************************************/
102
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
104 {
105         DEBUG(5,("%s: access check ((granted: %#010x;  required: %#010x)\n",
106                         debug, acc_granted, acc_required));
107         if ((acc_granted & acc_required) != acc_required) {
108                 if (geteuid() == sec_initial_uid()) {
109                         DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x;  required: %#010x)\n",
110                                 debug, acc_granted, acc_required));
111                         DEBUGADD(4,("but overwritten by euid == 0\n"));
112                         return NT_STATUS_OK;
113                 }
114                 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x;  required: %#010x)\n",
115                         debug, acc_granted, acc_required));
116                 return NT_STATUS_ACCESS_DENIED;
117         }
118         return NT_STATUS_OK;
119 }
120
121
122 /*******************************************************************
123  Create a samr_info struct.
124 ********************************************************************/
125
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
127 {
128         struct samr_info *info;
129         fstring sid_str;
130         TALLOC_CTX *mem_ctx;
131         
132         if (psid) {
133                 sid_to_string(sid_str, psid);
134         } else {
135                 fstrcpy(sid_str,"(NULL)");
136         }
137
138         mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
139
140         if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141                 return NULL;
142
143         ZERO_STRUCTP(info);
144         DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
145         if (psid) {
146                 sid_copy( &info->sid, psid);
147         } else {
148                 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
149         }
150         info->mem_ctx = mem_ctx;
151         return info;
152 }
153
154 /*******************************************************************
155  Function to free the per handle data.
156  ********************************************************************/
157
158 static void free_samr_users(struct samr_info *info) 
159 {
160         int i;
161
162         if (info->disp_info.user_dbloaded){
163                 for (i=0; i<info->disp_info.num_user_account; i++) {
164                         SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
165                         /* Not really a free, actually a 'clear' */
166                         pdb_free_sam(&sam);
167                 }
168         }
169         info->disp_info.user_dbloaded=False;
170         info->disp_info.num_user_account=0;
171 }
172
173 /*******************************************************************
174  Function to free the per handle data.
175  ********************************************************************/
176
177 static void free_samr_db(struct samr_info *info)
178 {
179         /* Groups are talloced */
180
181         free_samr_users(info);
182
183         info->disp_info.group_dbloaded=False;
184         info->disp_info.num_group_account=0;
185 }
186
187 static void free_samr_info(void *ptr)
188 {
189         struct samr_info *info=(struct samr_info *) ptr;
190
191         free_samr_db(info);
192         talloc_destroy(info->mem_ctx);
193 }
194
195 /*******************************************************************
196  Ensure password info is never given out. Paranioa... JRA.
197  ********************************************************************/
198
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
200 {
201         
202         if (!sam_pass)
203                 return;
204
205         /* These now zero out the old password */
206
207         pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208         pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
209 }
210
211
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
213 {
214         SAM_ACCOUNT *pwd = NULL;
215         SAM_ACCOUNT *pwd_array = NULL;
216         NTSTATUS nt_status = NT_STATUS_OK;
217         TALLOC_CTX *mem_ctx = info->mem_ctx;
218
219         DEBUG(10,("load_sampwd_entries\n"));
220
221         /* if the snapshoot is already loaded, return */
222         if ((info->disp_info.user_dbloaded==True) 
223             && (info->acb_mask == acb_mask) 
224             && (info->all_machines == all_machines)) {
225                 DEBUG(10,("load_sampwd_entries: already in memory\n"));
226                 return NT_STATUS_OK;
227         }
228
229         free_samr_users(info);
230
231         if (!pdb_setsampwent(False)) {
232                 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233                 return NT_STATUS_ACCESS_DENIED;
234         }
235
236         for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
237                      && pdb_getsampwent(pwd) == True; pwd=NULL) {
238                 
239                 if (all_machines) {
240                         if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
241                               || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
242                                 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
243                                 pdb_free_sam(&pwd);
244                                 continue;
245                         }
246                 } else {
247                         if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
248                                 pdb_free_sam(&pwd);
249                                 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
250                                 continue;
251                         }
252                 }
253
254                 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
255                 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
256                 
257                         DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
258                         pwd_array=(SAM_ACCOUNT *)talloc_realloc(mem_ctx, info->disp_info.disp_user_info, 
259                                           (info->disp_info.num_user_account+MAX_SAM_ENTRIES)*sizeof(SAM_ACCOUNT));
260
261                         if (pwd_array==NULL)
262                                 return NT_STATUS_NO_MEMORY;
263
264                         info->disp_info.disp_user_info=pwd_array;
265                 }
266         
267                 /* Copy the SAM_ACCOUNT into the array */
268                 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
269
270                 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
271
272                 info->disp_info.num_user_account++;     
273         }
274
275         pdb_endsampwent();
276
277         /* the snapshoot is in memory, we're ready to enumerate fast */
278
279         info->acb_mask = acb_mask;
280         info->all_machines = all_machines;
281         info->disp_info.user_dbloaded=True;
282
283         DEBUG(10,("load_sampwd_entries: done\n"));
284
285         return nt_status;
286 }
287
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
289 {
290         GROUP_MAP *map=NULL;
291         DOMAIN_GRP *grp_array = NULL;
292         uint32 group_entries = 0;
293         uint32 i;
294         TALLOC_CTX *mem_ctx = info->mem_ctx;
295         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 NT_STATUS_NO_SUCH_USER;
3385         }
3386
3387         /* check a real user exist before we run the script to add a user to a group */
3388         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3389                 pdb_free_sam(&sam_user);
3390                 return NT_STATUS_NO_SUCH_USER;
3391         }
3392
3393         pdb_free_sam(&sam_user);
3394
3395         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3396                 return NT_STATUS_NO_SUCH_USER;
3397         }
3398         
3399         if ((grp=getgrgid(map.gid)) == NULL) {
3400                 passwd_free(&pwd);
3401                 return NT_STATUS_NO_SUCH_ALIAS;
3402         }
3403
3404         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3405         fstrcpy(grp_name, grp->gr_name);
3406
3407         /* if the user is already in the group */
3408         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3409                 passwd_free(&pwd);
3410                 return NT_STATUS_MEMBER_IN_ALIAS;
3411         }
3412
3413         /* 
3414          * ok, the group exist, the user exist, the user is not in the group,
3415          * we can (finally) add it to the group !
3416          */
3417         smb_add_user_group(grp_name, pwd->pw_name);
3418
3419         /* check if the user has been added then ... */
3420         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3421                 passwd_free(&pwd);
3422                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3423         }
3424
3425         passwd_free(&pwd);
3426         return NT_STATUS_OK;
3427 }
3428
3429 /*********************************************************************
3430  _samr_del_aliasmem
3431 *********************************************************************/
3432
3433 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3434 {
3435         DOM_SID alias_sid;
3436         fstring alias_sid_str;
3437         struct group *grp;
3438         fstring grp_name;
3439         GROUP_MAP map;
3440         SAM_ACCOUNT *sam_pass=NULL;
3441         uint32 acc_granted;
3442
3443         /* Find the policy handle. Open a policy on it. */
3444         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3445                 return NT_STATUS_INVALID_HANDLE;
3446         
3447         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3448                 return r_u->status;
3449         }
3450         
3451         sid_to_string(alias_sid_str, &alias_sid);
3452         DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3453
3454         if (!sid_check_is_in_our_domain(&alias_sid) &&
3455             !sid_check_is_in_builtin(&alias_sid)) {
3456                 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3457                 return NT_STATUS_NO_SUCH_ALIAS;
3458         }
3459
3460         if( !get_local_group_from_sid(&alias_sid, &map))
3461                 return NT_STATUS_NO_SUCH_ALIAS;
3462
3463         if ((grp=getgrgid(map.gid)) == NULL)
3464                 return NT_STATUS_NO_SUCH_ALIAS;
3465
3466         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3467         fstrcpy(grp_name, grp->gr_name);
3468
3469         /* check if the user exists before trying to remove it from the group */
3470         pdb_init_sam(&sam_pass);
3471         if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3472                 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3473                 pdb_free_sam(&sam_pass);
3474                 return NT_STATUS_NO_SUCH_USER;
3475         }
3476
3477         /* if the user is not in the group */
3478         if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3479                 pdb_free_sam(&sam_pass);
3480                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;
3481         }
3482
3483         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3484
3485         /* check if the user has been removed then ... */
3486         if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3487                 pdb_free_sam(&sam_pass);
3488                 return NT_STATUS_MEMBER_NOT_IN_ALIAS;   /* don't know what to reply else */
3489         }
3490
3491         pdb_free_sam(&sam_pass);
3492         return NT_STATUS_OK;
3493 }
3494
3495 /*********************************************************************
3496  _samr_add_groupmem
3497 *********************************************************************/
3498
3499 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3500 {
3501         DOM_SID group_sid;
3502         DOM_SID user_sid;
3503         fstring group_sid_str;
3504         uid_t uid;
3505         struct passwd *pwd;
3506         struct group *grp;
3507         fstring grp_name;
3508         GROUP_MAP map;
3509         NTSTATUS ret;
3510         SAM_ACCOUNT *sam_user=NULL;
3511         BOOL check;
3512         uint32 acc_granted;
3513
3514         /* Find the policy handle. Open a policy on it. */
3515         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3516                 return NT_STATUS_INVALID_HANDLE;
3517         
3518         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3519                 return r_u->status;
3520         }
3521
3522         sid_to_string(group_sid_str, &group_sid);
3523         DEBUG(10, ("sid is %s\n", group_sid_str));
3524
3525         if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3526                 return NT_STATUS_NO_SUCH_GROUP;
3527
3528         DEBUG(10, ("lookup on Domain SID\n"));
3529
3530         if(!get_domain_group_from_sid(group_sid, &map))
3531                 return NT_STATUS_NO_SUCH_GROUP;
3532
3533         sid_copy(&user_sid, get_global_sam_sid());
3534         sid_append_rid(&user_sid, q_u->rid);
3535
3536         ret = pdb_init_sam(&sam_user);
3537         if (!NT_STATUS_IS_OK(ret))
3538                 return ret;
3539         
3540         check = pdb_getsampwsid(sam_user, &user_sid);
3541         
3542         if (check != True) {
3543                 pdb_free_sam(&sam_user);
3544                 return NT_STATUS_NO_SUCH_USER;
3545         }
3546
3547         /* check a real user exist before we run the script to add a user to a group */
3548         if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3549                 pdb_free_sam(&sam_user);
3550                 return NT_STATUS_NO_SUCH_USER;
3551         }
3552
3553         pdb_free_sam(&sam_user);
3554
3555         if ((pwd=getpwuid_alloc(uid)) == NULL) {
3556                 return NT_STATUS_NO_SUCH_USER;
3557         }
3558
3559         if ((grp=getgrgid(map.gid)) == NULL) {
3560                 passwd_free(&pwd);
3561                 return NT_STATUS_NO_SUCH_GROUP;
3562         }
3563
3564         /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3565         fstrcpy(grp_name, grp->gr_name);
3566
3567         /* if the user is already in the group */
3568         if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3569                 passwd_free(&pwd);
3570                 return NT_STATUS_MEMBER_IN_GROUP;
3571         }
3572
3573         /* 
3574          * ok, the group exist, the user exist, the user is not in the group,
3575          *
3576          * we can (finally) add it to the group !
3577          */
3578
3579         smb_add_user_group(grp_name, pwd->pw_name);
3580
3581         /* check if the user has been added then ... */
3582         if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3583                 passwd_free(&pwd);
3584                 return NT_STATUS_MEMBER_NOT_IN_GROUP;           /* don't know what to reply else */
3585         }
3586
3587         passwd_free(&pwd);
3588         return NT_STATUS_OK;
3589 }
3590
3591 /*********************************************************************
3592  _samr_del_groupmem
3593 *********************************************************************/
3594
3595 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3596 {
3597         DOM_SID group_sid;
3598         DOM_SID user_sid;
3599         SAM_ACCOUNT *sam_pass=NULL;
3600         GROUP_MAP map;
3601         fstring grp_name;
3602         struct group *grp;
3603         uint32 acc_granted;
3604
3605         /*
3606          * delete the group member named q_u->rid
3607          * who is a member of the sid associated with the handle
3608          * the rid is a user's rid as the group is a domain group.
3609          */
3610
3611         /* Find the policy handle. Open a policy on it. */
3612         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3613                 return NT_STATUS_INVALID_HANDLE;
3614         
3615         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3616                 return r_u->status;
3617         }
3618                 
3619         if (!sid_check_is_in_our_domain(&group_sid))
3620                 return NT_STATUS_NO_SUCH_GROUP;
3621
3622         sid_copy(&user_sid, get_global_sam_sid());
3623         sid_append_rid(&user_sid, q_u->rid);
3624
3625         if (!get_domain_group_from_sid(group_sid, &map))
3626                 return NT_STATUS_NO_SUCH_GROUP;
3627
3628         if ((grp=getgrgid(map.gid)) == NULL)
3629                 return NT_STATUS_NO_SUCH_GROUP;
3630
3631         /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3632         fstrcpy(grp_name, grp->gr_name);
3633
3634         /* check if the user exists before trying to remove it from the group */
3635         pdb_init_sam(&sam_pass);
3636         if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3637                 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3638                 pdb_free_sam(&sam_pass);
3639                 return NT_STATUS_NO_SUCH_USER;
3640         }
3641
3642         /* if the user is not in the group */
3643         if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3644                 pdb_free_sam(&sam_pass);
3645                 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3646         }
3647
3648         smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3649
3650         /* check if the user has been removed then ... */
3651         if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3652                 pdb_free_sam(&sam_pass);
3653                 return NT_STATUS_ACCESS_DENIED;         /* don't know what to reply else */
3654         }
3655         
3656         pdb_free_sam(&sam_pass);
3657         return NT_STATUS_OK;
3658
3659 }
3660
3661 /****************************************************************************
3662  Delete a UNIX user on demand.
3663 ****************************************************************************/
3664
3665 static int smb_delete_user(const char *unix_user)
3666 {
3667         pstring del_script;
3668         int ret;
3669
3670         /* try winbindd first since it is impossible to determine where 
3671            a user came from via NSS.  Try the delete user script if this fails
3672            meaning the user did not exist in winbindd's list of accounts */
3673
3674         if ( winbind_delete_user( unix_user ) ) {
3675                 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3676                 return 0;
3677         }
3678
3679
3680         /* fall back to 'delete user script' */
3681
3682         pstrcpy(del_script, lp_deluser_script());
3683         if (! *del_script)
3684                 return -1;
3685         all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3686         ret = smbrun(del_script,NULL);
3687         DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3688
3689         return ret;
3690 }
3691
3692 /*********************************************************************
3693  _samr_delete_dom_user
3694 *********************************************************************/
3695
3696 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3697 {
3698         DOM_SID user_sid;
3699         SAM_ACCOUNT *sam_pass=NULL;
3700         uint32 acc_granted;
3701
3702         DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3703
3704         /* Find the policy handle. Open a policy on it. */
3705         if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted)) 
3706                 return NT_STATUS_INVALID_HANDLE;
3707                 
3708         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3709                 return r_u->status;
3710         }
3711                 
3712         if (!sid_check_is_in_our_domain(&user_sid))
3713                 return NT_STATUS_CANNOT_DELETE;
3714
3715         /* check if the user exists before trying to delete */
3716         pdb_init_sam(&sam_pass);
3717         if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3718                 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n", 
3719                         sid_string_static(&user_sid)));
3720                 pdb_free_sam(&sam_pass);
3721                 return NT_STATUS_NO_SUCH_USER;
3722         }
3723
3724         /* delete the unix side */
3725         /*
3726          * note: we don't check if the delete really happened
3727          * as the script is not necessary present
3728          * and maybe the sysadmin doesn't want to delete the unix side
3729          */
3730         smb_delete_user(pdb_get_username(sam_pass));
3731
3732         /* and delete the samba side */
3733         if (!pdb_delete_sam_account(sam_pass)) {
3734                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3735                 pdb_free_sam(&sam_pass);
3736                 return NT_STATUS_CANNOT_DELETE;
3737         }
3738         
3739         pdb_free_sam(&sam_pass);
3740
3741         if (!close_policy_hnd(p, &q_u->user_pol))
3742                 return NT_STATUS_OBJECT_NAME_INVALID;
3743
3744         return NT_STATUS_OK;
3745 }
3746
3747 /*********************************************************************
3748  _samr_delete_dom_group
3749 *********************************************************************/
3750
3751 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3752 {
3753         DOM_SID group_sid;
3754         DOM_SID dom_sid;
3755         uint32 group_rid;
3756         fstring group_sid_str;
3757         gid_t gid;
3758         struct group *grp;
3759         GROUP_MAP map;
3760         uint32 acc_granted;
3761
3762         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3763
3764         /* Find the policy handle. Open a policy on it. */
3765         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3766                 return NT_STATUS_INVALID_HANDLE;
3767                 
3768         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3769                 return r_u->status;
3770         }
3771                 
3772         sid_copy(&dom_sid, &group_sid);
3773         sid_to_string(group_sid_str, &dom_sid);
3774         sid_split_rid(&dom_sid, &group_rid);
3775
3776         DEBUG(10, ("sid is %s\n", group_sid_str));
3777
3778         /* we check if it's our SID before deleting */
3779         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3780                 return NT_STATUS_NO_SUCH_GROUP;
3781
3782         DEBUG(10, ("lookup on Domain SID\n"));
3783
3784         if(!get_domain_group_from_sid(group_sid, &map))
3785                 return NT_STATUS_NO_SUCH_GROUP;
3786
3787         gid=map.gid;
3788
3789         /* check if group really exists */
3790         if ( (grp=getgrgid(gid)) == NULL)
3791                 return NT_STATUS_NO_SUCH_GROUP;
3792
3793         /* delete mapping first */
3794         if(!pdb_delete_group_mapping_entry(group_sid))
3795                 return NT_STATUS_ACCESS_DENIED;
3796                 
3797         /* we can delete the UNIX group */
3798         smb_delete_group(grp->gr_name);
3799
3800         /* check if the group has been successfully deleted */
3801         if ( (grp=getgrgid(gid)) != NULL)
3802                 return NT_STATUS_ACCESS_DENIED;
3803
3804
3805         if (!close_policy_hnd(p, &q_u->group_pol))
3806                 return NT_STATUS_OBJECT_NAME_INVALID;
3807
3808         return NT_STATUS_OK;
3809 }
3810
3811 /*********************************************************************
3812  _samr_delete_dom_alias
3813 *********************************************************************/
3814
3815 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3816 {
3817         DOM_SID alias_sid;
3818         DOM_SID dom_sid;
3819         uint32 alias_rid;
3820         fstring alias_sid_str;
3821         gid_t gid;
3822         struct group *grp;
3823         GROUP_MAP map;
3824         uint32 acc_granted;
3825
3826         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3827
3828         /* Find the policy handle. Open a policy on it. */
3829         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3830                 return NT_STATUS_INVALID_HANDLE;
3831         
3832         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3833                 return r_u->status;
3834         }
3835                 
3836         sid_copy(&dom_sid, &alias_sid);
3837         sid_to_string(alias_sid_str, &dom_sid);
3838         sid_split_rid(&dom_sid, &alias_rid);
3839
3840         DEBUG(10, ("sid is %s\n", alias_sid_str));
3841
3842         /* we check if it's our SID before deleting */
3843         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3844                 return NT_STATUS_NO_SUCH_ALIAS;
3845
3846         DEBUG(10, ("lookup on Local SID\n"));
3847
3848         if(!get_local_group_from_sid(&alias_sid, &map))
3849                 return NT_STATUS_NO_SUCH_ALIAS;
3850
3851         gid=map.gid;
3852
3853         /* check if group really exists */
3854         if ( (grp=getgrgid(gid)) == NULL)
3855                 return NT_STATUS_NO_SUCH_ALIAS;
3856
3857         /* we can delete the UNIX group */
3858         smb_delete_group(grp->gr_name);
3859
3860         /* check if the group has been successfully deleted */
3861         if ( (grp=getgrgid(gid)) != NULL)
3862                 return NT_STATUS_ACCESS_DENIED;
3863
3864         /* don't check if we removed it as it could be an un-mapped group */
3865         pdb_delete_group_mapping_entry(alias_sid);
3866
3867         if (!close_policy_hnd(p, &q_u->alias_pol))
3868                 return NT_STATUS_OBJECT_NAME_INVALID;
3869
3870         return NT_STATUS_OK;
3871 }
3872
3873 /*********************************************************************
3874  _samr_create_dom_group
3875 *********************************************************************/
3876
3877 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3878 {
3879         DOM_SID dom_sid;
3880         DOM_SID info_sid;
3881         fstring name;
3882         fstring sid_string;
3883         struct group *grp;
3884         struct samr_info *info;
3885         uint32 acc_granted;
3886         gid_t gid;
3887
3888         /* Find the policy handle. Open a policy on it. */
3889         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3890                 return NT_STATUS_INVALID_HANDLE;
3891         
3892         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3893                 return r_u->status;
3894         }
3895                 
3896         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3897                 return NT_STATUS_ACCESS_DENIED;
3898
3899         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3900
3901         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3902
3903         /* check if group already exist */
3904         if ((grp=getgrnam(name)) != NULL)
3905                 return NT_STATUS_GROUP_EXISTS;
3906
3907         /* we can create the UNIX group */
3908         if (smb_create_group(name, &gid) != 0)
3909                 return NT_STATUS_ACCESS_DENIED;
3910
3911         /* check if the group has been successfully created */
3912         if ((grp=getgrgid(gid)) == NULL)
3913                 return NT_STATUS_ACCESS_DENIED;
3914
3915         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3916
3917         /* add the group to the mapping table */
3918         sid_copy(&info_sid, get_global_sam_sid());
3919         sid_append_rid(&info_sid, r_u->rid);
3920         sid_to_string(sid_string, &info_sid);
3921
3922         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3923                 return NT_STATUS_ACCESS_DENIED;
3924
3925         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3926                 return NT_STATUS_NO_MEMORY;
3927
3928         /* get a (unique) handle.  open a policy on it. */
3929         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3930                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3931
3932         return NT_STATUS_OK;
3933 }
3934
3935 /*********************************************************************
3936  _samr_create_dom_alias
3937 *********************************************************************/
3938
3939 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3940 {
3941         DOM_SID dom_sid;
3942         DOM_SID info_sid;
3943         fstring name;
3944         fstring sid_string;
3945         struct group *grp;
3946         struct samr_info *info;
3947         uint32 acc_granted;
3948         gid_t gid;
3949
3950         /* Find the policy handle. Open a policy on it. */
3951         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3952                 return NT_STATUS_INVALID_HANDLE;
3953                 
3954         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3955                 return r_u->status;
3956         }
3957                 
3958         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3959                 return NT_STATUS_ACCESS_DENIED;
3960
3961         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3962
3963         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3964
3965         /* check if group already exists */
3966         if ( (grp=getgrnam(name)) != NULL)
3967                 return NT_STATUS_ALIAS_EXISTS;
3968
3969         /* we can create the UNIX group */
3970         if (smb_create_group(name, &gid) != 0)
3971                 return NT_STATUS_ACCESS_DENIED;
3972
3973         /* check if the group has been successfully created */
3974         if ((grp=getgrgid(gid)) == NULL)
3975                 return NT_STATUS_ACCESS_DENIED;
3976
3977         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3978
3979         sid_copy(&info_sid, get_global_sam_sid());
3980         sid_append_rid(&info_sid, r_u->rid);
3981         sid_to_string(sid_string, &info_sid);
3982
3983         /* add the group to the mapping table */
3984         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
3985                 return NT_STATUS_ACCESS_DENIED;
3986
3987         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3988                 return NT_STATUS_NO_MEMORY;
3989
3990         /* get a (unique) handle.  open a policy on it. */
3991         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3992                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3993
3994         return NT_STATUS_OK;
3995 }
3996
3997 /*********************************************************************
3998  _samr_query_groupinfo
3999
4000 sends the name/comment pair of a domain group
4001 level 1 send also the number of users of that group
4002 *********************************************************************/
4003
4004 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4005 {
4006         DOM_SID group_sid;
4007         GROUP_MAP map;
4008         DOM_SID *sids=NULL;
4009         int num_sids=0;
4010         GROUP_INFO_CTR *ctr;
4011         uint32 acc_granted;
4012         BOOL ret;
4013
4014         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
4015                 return NT_STATUS_INVALID_HANDLE;
4016         
4017         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4018                 return r_u->status;
4019         }
4020                 
4021         become_root();
4022         ret = get_domain_group_from_sid(group_sid, &map);
4023         unbecome_root();
4024         if (!ret)
4025                 return NT_STATUS_INVALID_HANDLE;
4026
4027         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4028         if (ctr==NULL)
4029                 return NT_STATUS_NO_MEMORY;
4030
4031         switch (q_u->switch_level) {
4032                 case 1:
4033                         ctr->switch_value1 = 1;
4034                         if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
4035                                 return NT_STATUS_NO_SUCH_GROUP;
4036                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_sids);
4037                         SAFE_FREE(sids);
4038                         break;
4039                 case 3:
4040                         ctr->switch_value1 = 3;
4041                         init_samr_group_info3(&ctr->group.info3);
4042                         break;
4043                 case 4:
4044                         ctr->switch_value1 = 4;
4045                         init_samr_group_info4(&ctr->group.info4, map.comment);
4046                         break;
4047                 default:
4048                         return NT_STATUS_INVALID_INFO_CLASS;
4049         }
4050
4051         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4052
4053         return NT_STATUS_OK;
4054 }
4055
4056 /*********************************************************************
4057  _samr_set_groupinfo
4058  
4059  update a domain group's comment.
4060 *********************************************************************/
4061
4062 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4063 {
4064         DOM_SID group_sid;
4065         GROUP_MAP map;
4066         GROUP_INFO_CTR *ctr;
4067         uint32 acc_granted;
4068
4069         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4070                 return NT_STATUS_INVALID_HANDLE;
4071         
4072         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4073                 return r_u->status;
4074         }
4075                 
4076         if (!get_domain_group_from_sid(group_sid, &map))
4077                 return NT_STATUS_NO_SUCH_GROUP;
4078         
4079         ctr=q_u->ctr;
4080
4081         switch (ctr->switch_value1) {
4082                 case 1:
4083                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4084                         break;
4085                 case 4:
4086                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4087                         break;
4088                 default:
4089                         return NT_STATUS_INVALID_INFO_CLASS;
4090         }
4091
4092         if(!pdb_update_group_mapping_entry(&map)) {
4093                 return NT_STATUS_NO_SUCH_GROUP;
4094         }
4095
4096         return NT_STATUS_OK;
4097 }
4098
4099 /*********************************************************************
4100  _samr_set_aliasinfo
4101  
4102  update an alias's comment.
4103 *********************************************************************/
4104
4105 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4106 {
4107         DOM_SID group_sid;
4108         GROUP_MAP map;
4109         ALIAS_INFO_CTR *ctr;
4110         uint32 acc_granted;
4111
4112         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4113                 return NT_STATUS_INVALID_HANDLE;
4114         
4115         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4116                 return r_u->status;
4117         }
4118                 
4119         if (!get_local_group_from_sid(&group_sid, &map) &&
4120             !get_builtin_group_from_sid(&group_sid, &map))
4121                 return NT_STATUS_NO_SUCH_GROUP;
4122         
4123         ctr=&q_u->ctr;
4124
4125         switch (ctr->switch_value1) {
4126                 case 3:
4127                         unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4128                         break;
4129                 default:
4130                         return NT_STATUS_INVALID_INFO_CLASS;
4131         }
4132
4133         if(!pdb_update_group_mapping_entry(&map)) {
4134                 return NT_STATUS_NO_SUCH_GROUP;
4135         }
4136
4137         return NT_STATUS_OK;
4138 }
4139
4140 /*********************************************************************
4141  _samr_get_dom_pwinfo
4142 *********************************************************************/
4143
4144 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4145 {
4146         /* Perform access check.  Since this rpc does not require a
4147            policy handle it will not be caught by the access checks on
4148            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4149
4150         if (!pipe_access_check(p)) {
4151                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4152                 r_u->status = NT_STATUS_ACCESS_DENIED;
4153                 return r_u->status;
4154         }
4155
4156         /* Actually, returning zeros here works quite well :-). */
4157
4158         return NT_STATUS_OK;
4159 }
4160
4161 /*********************************************************************
4162  _samr_open_group
4163 *********************************************************************/
4164
4165 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4166 {
4167         DOM_SID sid;
4168         DOM_SID info_sid;
4169         GROUP_MAP map;
4170         struct samr_info *info;
4171         SEC_DESC         *psd = NULL;
4172         uint32            acc_granted;
4173         uint32            des_access = q_u->access_mask;
4174         size_t            sd_size;
4175         NTSTATUS          status;
4176         fstring sid_string;
4177         BOOL ret;
4178
4179         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4180                 return NT_STATUS_INVALID_HANDLE;
4181         
4182         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4183                 return status;
4184         }
4185                 
4186         /*check if access can be granted as requested by client. */
4187         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4188         se_map_generic(&des_access,&grp_generic_mapping);
4189         if (!NT_STATUS_IS_OK(status = 
4190                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4191                                                       des_access, &acc_granted, "_samr_open_group"))) {
4192                 return status;
4193         }
4194
4195
4196         /* this should not be hard-coded like this */
4197         if (!sid_equal(&sid, get_global_sam_sid()))
4198                 return NT_STATUS_ACCESS_DENIED;
4199
4200         sid_copy(&info_sid, get_global_sam_sid());
4201         sid_append_rid(&info_sid, q_u->rid_group);
4202         sid_to_string(sid_string, &info_sid);
4203
4204         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4205                 return NT_STATUS_NO_MEMORY;
4206                 
4207         info->acc_granted = acc_granted;
4208
4209         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4210
4211         /* check if that group really exists */
4212         become_root();
4213         ret = get_domain_group_from_sid(info->sid, &map);
4214         unbecome_root();
4215         if (!ret)
4216                 return NT_STATUS_NO_SUCH_GROUP;
4217
4218         /* get a (unique) handle.  open a policy on it. */
4219         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4220                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4221
4222         return NT_STATUS_OK;
4223 }
4224
4225 /*********************************************************************
4226  _samr_remove_sid_foreign_domain
4227 *********************************************************************/
4228
4229 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4230                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4231                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4232 {
4233         DOM_SID                 delete_sid, alias_sid;
4234         SAM_ACCOUNT             *sam_pass=NULL;
4235         uint32                  acc_granted;
4236         GROUP_MAP               map;
4237         BOOL                    is_user = False;
4238         NTSTATUS                result;
4239         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4240         
4241         sid_copy( &delete_sid, &q_u->sid.sid );
4242         
4243         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4244                 sid_string_static(&delete_sid)));
4245                 
4246         /* Find the policy handle. Open a policy on it. */
4247         
4248         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4249                 return NT_STATUS_INVALID_HANDLE;
4250         
4251         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4252                 "_samr_remove_sid_foreign_domain");
4253                 
4254         if (!NT_STATUS_IS_OK(result)) 
4255                 return result;
4256                         
4257         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4258                 sid_string_static(&alias_sid)));
4259                 
4260         /* make sure we can handle this */
4261         
4262         if ( sid_check_is_domain(&alias_sid) )
4263                 type = SID_NAME_DOM_GRP;
4264         else if ( sid_check_is_builtin(&alias_sid) )
4265                 type = SID_NAME_ALIAS;
4266         
4267         if ( type == SID_NAME_UNKNOWN ) {
4268                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4269                 return NT_STATUS_OK;
4270         }
4271
4272         /* check if the user exists before trying to delete */
4273         
4274         pdb_init_sam(&sam_pass);
4275         
4276         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4277                 is_user = True;
4278         } else {
4279                 /* maybe it is a group */
4280                 if( !pdb_getgrsid(&map, delete_sid) ) {
4281                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4282                                 sid_string_static(&delete_sid)));
4283                         result = NT_STATUS_INVALID_SID;
4284                         goto done;
4285                 }
4286         }
4287         
4288         /* we can only delete a user from a group since we don't have 
4289            nested groups anyways.  So in the latter case, just say OK */
4290            
4291         if ( is_user ) {
4292                 GROUP_MAP       *mappings = NULL;
4293                 int             num_groups, i;
4294                 struct group    *grp2;
4295                 
4296                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4297                 
4298                         /* interate over the groups */
4299                         for ( i=0; i<num_groups; i++ ) {
4300
4301                                 grp2 = getgrgid(mappings[i].gid);
4302
4303                                 if ( !grp2 ) {
4304                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4305                                         continue;
4306                                 }
4307                         
4308                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4309                                         continue;
4310                                 
4311                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4312                                 
4313                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4314                                         /* should we fail here ? */
4315                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4316                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4317                                         continue;
4318                                 }
4319                                         
4320                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4321                                         pdb_get_username(sam_pass), grp2->gr_name ));
4322                         }
4323                         
4324                         SAFE_FREE(mappings);
4325                 }
4326         }
4327         
4328         result = NT_STATUS_OK;
4329 done:
4330
4331         pdb_free_sam(&sam_pass);
4332
4333         return result;
4334 }
4335
4336 /*******************************************************************
4337  _samr_unknown_2e
4338  ********************************************************************/
4339
4340 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4341 {
4342         struct samr_info *info = NULL;
4343         SAM_UNK_CTR *ctr;
4344         uint32 min_pass_len,pass_hist,flag;
4345         time_t u_expire, u_min_age;
4346         NTTIME nt_expire, nt_min_age;
4347
4348         time_t u_lock_duration, u_reset_time;
4349         NTTIME nt_lock_duration, nt_reset_time;
4350         uint32 lockout;
4351         
4352         time_t u_logout;
4353         NTTIME nt_logout;
4354
4355         uint32 num_users=0, num_groups=0, num_aliases=0;
4356
4357         uint32 account_policy_temp;
4358
4359         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4360                 return NT_STATUS_NO_MEMORY;
4361
4362         ZERO_STRUCTP(ctr);
4363
4364         r_u->status = NT_STATUS_OK;
4365
4366         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4367
4368         /* find the policy handle.  open a policy on it. */
4369         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4370                 return NT_STATUS_INVALID_HANDLE;
4371
4372         switch (q_u->switch_value) {
4373                 case 0x01:
4374                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4375                         min_pass_len = account_policy_temp;
4376
4377                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4378                         pass_hist = account_policy_temp;
4379
4380                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4381                         flag = account_policy_temp;
4382
4383                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4384                         u_expire = account_policy_temp;
4385
4386                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4387                         u_min_age = account_policy_temp;
4388
4389                         unix_to_nt_time_abs(&nt_expire, u_expire);
4390                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4391
4392                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4393                                        flag, nt_expire, nt_min_age);
4394                         break;
4395                 case 0x02:
4396                         become_root();          
4397                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4398                         unbecome_root();
4399                         if (!NT_STATUS_IS_OK(r_u->status)) {
4400                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4401                                 return r_u->status;
4402                         }
4403                         num_users=info->disp_info.num_user_account;
4404                         free_samr_db(info);
4405                         
4406                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4407                         if (NT_STATUS_IS_ERR(r_u->status)) {
4408                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4409                                 return r_u->status;
4410                         }
4411                         num_groups=info->disp_info.num_group_account;
4412                         free_samr_db(info);
4413
4414                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4415                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4416                                        num_users, num_groups, num_aliases);
4417                         break;
4418                 case 0x03:
4419                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4420                         u_logout = account_policy_temp;
4421
4422                         unix_to_nt_time_abs(&nt_logout, u_logout);
4423                         
4424                         init_unk_info3(&ctr->info.inf3, nt_logout);
4425                         break;
4426                 case 0x05:
4427                         init_unk_info5(&ctr->info.inf5, global_myname());
4428                         break;
4429                 case 0x06:
4430                         init_unk_info6(&ctr->info.inf6);
4431                         break;
4432                 case 0x07:
4433                         init_unk_info7(&ctr->info.inf7);
4434                         break;
4435                 case 0x0c:
4436                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4437                         u_lock_duration = account_policy_temp * 60;
4438
4439                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4440                         u_reset_time = account_policy_temp * 60;
4441
4442                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4443                         lockout = account_policy_temp;
4444         
4445                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4446                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4447         
4448                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4449                         break;
4450                 default:
4451                         return NT_STATUS_INVALID_INFO_CLASS;
4452         }
4453
4454         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4455
4456         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4457
4458         return r_u->status;
4459 }
4460
4461 /*******************************************************************
4462  _samr_
4463  ********************************************************************/
4464
4465 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4466 {
4467         time_t u_expire, u_min_age;
4468         time_t u_logout;
4469         time_t u_lock_duration, u_reset_time;
4470
4471         r_u->status = NT_STATUS_OK;
4472
4473         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4474
4475         /* find the policy handle.  open a policy on it. */
4476         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4477                 return NT_STATUS_INVALID_HANDLE;
4478
4479         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4480
4481         switch (q_u->switch_value) {
4482                 case 0x01:
4483                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4484                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4485                         
4486                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4487                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4488                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4489                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4490                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4491                         break;
4492                 case 0x02:
4493                         break;
4494                 case 0x03:
4495                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4496                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4497                         break;
4498                 case 0x05:
4499                         break;
4500                 case 0x06:
4501                         break;
4502                 case 0x07:
4503                         break;
4504                 case 0x0c:
4505                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4506                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4507                         
4508                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4509                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4510                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4511                         break;
4512                 default:
4513                         return NT_STATUS_INVALID_INFO_CLASS;
4514         }
4515
4516         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4517
4518         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4519
4520         return r_u->status;
4521 }