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