r2369: Fix from Richard Renard <rrenard@idealx.com> to fix usermgr and trust relation...
[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         /* delete the unix side */
3679         /*
3680          * note: we don't check if the delete really happened
3681          * as the script is not necessary present
3682          * and maybe the sysadmin doesn't want to delete the unix side
3683          */
3684         smb_delete_user(pdb_get_username(sam_pass));
3685
3686         /* and delete the samba side */
3687         if (!pdb_delete_sam_account(sam_pass)) {
3688                 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3689                 pdb_free_sam(&sam_pass);
3690                 return NT_STATUS_CANNOT_DELETE;
3691         }
3692         
3693         pdb_free_sam(&sam_pass);
3694
3695         if (!close_policy_hnd(p, &q_u->user_pol))
3696                 return NT_STATUS_OBJECT_NAME_INVALID;
3697
3698         return NT_STATUS_OK;
3699 }
3700
3701 /*********************************************************************
3702  _samr_delete_dom_group
3703 *********************************************************************/
3704
3705 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3706 {
3707         DOM_SID group_sid;
3708         DOM_SID dom_sid;
3709         uint32 group_rid;
3710         fstring group_sid_str;
3711         gid_t gid;
3712         struct group *grp;
3713         GROUP_MAP map;
3714         uint32 acc_granted;
3715
3716         DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3717
3718         /* Find the policy handle. Open a policy on it. */
3719         if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted)) 
3720                 return NT_STATUS_INVALID_HANDLE;
3721                 
3722         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3723                 return r_u->status;
3724         }
3725                 
3726         sid_copy(&dom_sid, &group_sid);
3727         sid_to_string(group_sid_str, &dom_sid);
3728         sid_split_rid(&dom_sid, &group_rid);
3729
3730         DEBUG(10, ("sid is %s\n", group_sid_str));
3731
3732         /* we check if it's our SID before deleting */
3733         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3734                 return NT_STATUS_NO_SUCH_GROUP;
3735
3736         DEBUG(10, ("lookup on Domain SID\n"));
3737
3738         if(!get_domain_group_from_sid(group_sid, &map))
3739                 return NT_STATUS_NO_SUCH_GROUP;
3740
3741         gid=map.gid;
3742
3743         /* check if group really exists */
3744         if ( (grp=getgrgid(gid)) == NULL)
3745                 return NT_STATUS_NO_SUCH_GROUP;
3746
3747         /* delete mapping first */
3748         if(!pdb_delete_group_mapping_entry(group_sid))
3749                 return NT_STATUS_ACCESS_DENIED;
3750                 
3751         /* we can delete the UNIX group */
3752         smb_delete_group(grp->gr_name);
3753
3754         /* check if the group has been successfully deleted */
3755         if ( (grp=getgrgid(gid)) != NULL)
3756                 return NT_STATUS_ACCESS_DENIED;
3757
3758
3759         if (!close_policy_hnd(p, &q_u->group_pol))
3760                 return NT_STATUS_OBJECT_NAME_INVALID;
3761
3762         return NT_STATUS_OK;
3763 }
3764
3765 /*********************************************************************
3766  _samr_delete_dom_alias
3767 *********************************************************************/
3768
3769 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3770 {
3771         DOM_SID alias_sid;
3772         uint32 acc_granted;
3773
3774         DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3775
3776         /* Find the policy handle. Open a policy on it. */
3777         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted)) 
3778                 return NT_STATUS_INVALID_HANDLE;
3779         
3780         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3781                 return r_u->status;
3782         }
3783
3784         DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3785
3786         if (!sid_check_is_in_our_domain(&alias_sid))
3787                 return NT_STATUS_NO_SUCH_ALIAS;
3788                 
3789         DEBUG(10, ("lookup on Local SID\n"));
3790
3791         /* Have passdb delete the alias */
3792         if (!pdb_delete_alias(&alias_sid))
3793                 return NT_STATUS_ACCESS_DENIED;
3794
3795         if (!close_policy_hnd(p, &q_u->alias_pol))
3796                 return NT_STATUS_OBJECT_NAME_INVALID;
3797
3798         return NT_STATUS_OK;
3799 }
3800
3801 /*********************************************************************
3802  _samr_create_dom_group
3803 *********************************************************************/
3804
3805 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3806 {
3807         DOM_SID dom_sid;
3808         DOM_SID info_sid;
3809         fstring name;
3810         fstring sid_string;
3811         struct group *grp;
3812         struct samr_info *info;
3813         uint32 acc_granted;
3814         gid_t gid;
3815
3816         /* Find the policy handle. Open a policy on it. */
3817         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted)) 
3818                 return NT_STATUS_INVALID_HANDLE;
3819         
3820         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3821                 return r_u->status;
3822         }
3823                 
3824         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3825                 return NT_STATUS_ACCESS_DENIED;
3826
3827         /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3828
3829         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3830
3831         /* check if group already exist */
3832         if ((grp=getgrnam(name)) != NULL)
3833                 return NT_STATUS_GROUP_EXISTS;
3834
3835         /* we can create the UNIX group */
3836         if (smb_create_group(name, &gid) != 0)
3837                 return NT_STATUS_ACCESS_DENIED;
3838
3839         /* check if the group has been successfully created */
3840         if ((grp=getgrgid(gid)) == NULL)
3841                 return NT_STATUS_ACCESS_DENIED;
3842
3843         r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3844
3845         /* add the group to the mapping table */
3846         sid_copy(&info_sid, get_global_sam_sid());
3847         sid_append_rid(&info_sid, r_u->rid);
3848         sid_to_string(sid_string, &info_sid);
3849
3850         if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3851                 return NT_STATUS_ACCESS_DENIED;
3852
3853         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3854                 return NT_STATUS_NO_MEMORY;
3855
3856         /* get a (unique) handle.  open a policy on it. */
3857         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3858                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3859
3860         return NT_STATUS_OK;
3861 }
3862
3863 /*********************************************************************
3864  _samr_create_dom_alias
3865 *********************************************************************/
3866
3867 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3868 {
3869         DOM_SID dom_sid;
3870         DOM_SID info_sid;
3871         fstring name;
3872         struct group *grp;
3873         struct samr_info *info;
3874         uint32 acc_granted;
3875         gid_t gid;
3876         NTSTATUS result;
3877
3878         /* Find the policy handle. Open a policy on it. */
3879         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted)) 
3880                 return NT_STATUS_INVALID_HANDLE;
3881                 
3882         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3883                 return r_u->status;
3884         }
3885                 
3886         if (!sid_equal(&dom_sid, get_global_sam_sid()))
3887                 return NT_STATUS_ACCESS_DENIED;
3888
3889         /* TODO: check if allowed to create group  and add a become_root/unbecome_root pair.*/
3890
3891         unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3892
3893         /* Have passdb create the alias */
3894         result = pdb_create_alias(name, &r_u->rid);
3895
3896         if (!NT_STATUS_IS_OK(result))
3897                 return result;
3898
3899         sid_copy(&info_sid, get_global_sam_sid());
3900         sid_append_rid(&info_sid, r_u->rid);
3901
3902         if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
3903                 return NT_STATUS_ACCESS_DENIED;
3904
3905         /* check if the group has been successfully created */
3906         if ((grp=getgrgid(gid)) == NULL)
3907                 return NT_STATUS_ACCESS_DENIED;
3908
3909         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3910                 return NT_STATUS_NO_MEMORY;
3911
3912         /* get a (unique) handle.  open a policy on it. */
3913         if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3914                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3915
3916         return NT_STATUS_OK;
3917 }
3918
3919 /*********************************************************************
3920  _samr_query_groupinfo
3921
3922 sends the name/comment pair of a domain group
3923 level 1 send also the number of users of that group
3924 *********************************************************************/
3925
3926 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
3927 {
3928         DOM_SID group_sid;
3929         GROUP_MAP map;
3930         DOM_SID *sids=NULL;
3931         uid_t *uids;
3932         int num=0;
3933         GROUP_INFO_CTR *ctr;
3934         uint32 acc_granted;
3935         BOOL ret;
3936
3937         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted)) 
3938                 return NT_STATUS_INVALID_HANDLE;
3939         
3940         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
3941                 return r_u->status;
3942         }
3943                 
3944         become_root();
3945         ret = get_domain_group_from_sid(group_sid, &map);
3946         unbecome_root();
3947         if (!ret)
3948                 return NT_STATUS_INVALID_HANDLE;
3949
3950         ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
3951         if (ctr==NULL)
3952                 return NT_STATUS_NO_MEMORY;
3953
3954         switch (q_u->switch_level) {
3955                 case 1:
3956                         ctr->switch_value1 = 1;
3957                         if(!get_memberuids(map.gid, &uids, &num))
3958                                 return NT_STATUS_NO_SUCH_GROUP;
3959                         SAFE_FREE(uids);
3960                         init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
3961                         SAFE_FREE(sids);
3962                         break;
3963                 case 3:
3964                         ctr->switch_value1 = 3;
3965                         init_samr_group_info3(&ctr->group.info3);
3966                         break;
3967                 case 4:
3968                         ctr->switch_value1 = 4;
3969                         init_samr_group_info4(&ctr->group.info4, map.comment);
3970                         break;
3971                 default:
3972                         return NT_STATUS_INVALID_INFO_CLASS;
3973         }
3974
3975         init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
3976
3977         return NT_STATUS_OK;
3978 }
3979
3980 /*********************************************************************
3981  _samr_set_groupinfo
3982  
3983  update a domain group's comment.
3984 *********************************************************************/
3985
3986 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
3987 {
3988         DOM_SID group_sid;
3989         GROUP_MAP map;
3990         GROUP_INFO_CTR *ctr;
3991         uint32 acc_granted;
3992
3993         if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3994                 return NT_STATUS_INVALID_HANDLE;
3995         
3996         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
3997                 return r_u->status;
3998         }
3999                 
4000         if (!get_domain_group_from_sid(group_sid, &map))
4001                 return NT_STATUS_NO_SUCH_GROUP;
4002         
4003         ctr=q_u->ctr;
4004
4005         switch (ctr->switch_value1) {
4006                 case 1:
4007                         unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4008                         break;
4009                 case 4:
4010                         unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4011                         break;
4012                 default:
4013                         return NT_STATUS_INVALID_INFO_CLASS;
4014         }
4015
4016         if(!pdb_update_group_mapping_entry(&map)) {
4017                 return NT_STATUS_NO_SUCH_GROUP;
4018         }
4019
4020         return NT_STATUS_OK;
4021 }
4022
4023 /*********************************************************************
4024  _samr_set_aliasinfo
4025  
4026  update an alias's comment.
4027 *********************************************************************/
4028
4029 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4030 {
4031         DOM_SID group_sid;
4032         struct acct_info info;
4033         ALIAS_INFO_CTR *ctr;
4034         uint32 acc_granted;
4035
4036         if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4037                 return NT_STATUS_INVALID_HANDLE;
4038         
4039         if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4040                 return r_u->status;
4041         }
4042                 
4043         ctr=&q_u->ctr;
4044
4045         switch (ctr->switch_value1) {
4046                 case 3:
4047                         unistr2_to_ascii(info.acct_desc,
4048                                          &(ctr->alias.info3.uni_acct_desc),
4049                                          sizeof(info.acct_desc)-1);
4050                         break;
4051                 default:
4052                         return NT_STATUS_INVALID_INFO_CLASS;
4053         }
4054
4055         if(!pdb_set_aliasinfo(&group_sid, &info)) {
4056                 return NT_STATUS_ACCESS_DENIED;
4057         }
4058
4059         return NT_STATUS_OK;
4060 }
4061
4062 /*********************************************************************
4063  _samr_get_dom_pwinfo
4064 *********************************************************************/
4065
4066 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4067 {
4068         /* Perform access check.  Since this rpc does not require a
4069            policy handle it will not be caught by the access checks on
4070            SAMR_CONNECT or SAMR_CONNECT_ANON. */
4071
4072         if (!pipe_access_check(p)) {
4073                 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4074                 r_u->status = NT_STATUS_ACCESS_DENIED;
4075                 return r_u->status;
4076         }
4077
4078         /* Actually, returning zeros here works quite well :-). */
4079
4080         return NT_STATUS_OK;
4081 }
4082
4083 /*********************************************************************
4084  _samr_open_group
4085 *********************************************************************/
4086
4087 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4088 {
4089         DOM_SID sid;
4090         DOM_SID info_sid;
4091         GROUP_MAP map;
4092         struct samr_info *info;
4093         SEC_DESC         *psd = NULL;
4094         uint32            acc_granted;
4095         uint32            des_access = q_u->access_mask;
4096         size_t            sd_size;
4097         NTSTATUS          status;
4098         fstring sid_string;
4099         BOOL ret;
4100
4101         if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted)) 
4102                 return NT_STATUS_INVALID_HANDLE;
4103         
4104         if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4105                 return status;
4106         }
4107                 
4108         /*check if access can be granted as requested by client. */
4109         samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4110         se_map_generic(&des_access,&grp_generic_mapping);
4111         if (!NT_STATUS_IS_OK(status = 
4112                              access_check_samr_object(psd, p->pipe_user.nt_user_token, 
4113                                                       des_access, &acc_granted, "_samr_open_group"))) {
4114                 return status;
4115         }
4116
4117
4118         /* this should not be hard-coded like this */
4119         if (!sid_equal(&sid, get_global_sam_sid()))
4120                 return NT_STATUS_ACCESS_DENIED;
4121
4122         sid_copy(&info_sid, get_global_sam_sid());
4123         sid_append_rid(&info_sid, q_u->rid_group);
4124         sid_to_string(sid_string, &info_sid);
4125
4126         if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4127                 return NT_STATUS_NO_MEMORY;
4128                 
4129         info->acc_granted = acc_granted;
4130
4131         DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4132
4133         /* check if that group really exists */
4134         become_root();
4135         ret = get_domain_group_from_sid(info->sid, &map);
4136         unbecome_root();
4137         if (!ret)
4138                 return NT_STATUS_NO_SUCH_GROUP;
4139
4140         /* get a (unique) handle.  open a policy on it. */
4141         if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4142                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4143
4144         return NT_STATUS_OK;
4145 }
4146
4147 /*********************************************************************
4148  _samr_remove_sid_foreign_domain
4149 *********************************************************************/
4150
4151 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p, 
4152                                           SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u, 
4153                                           SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4154 {
4155         DOM_SID                 delete_sid, alias_sid;
4156         SAM_ACCOUNT             *sam_pass=NULL;
4157         uint32                  acc_granted;
4158         GROUP_MAP               map;
4159         BOOL                    is_user = False;
4160         NTSTATUS                result;
4161         enum SID_NAME_USE       type = SID_NAME_UNKNOWN;
4162         
4163         sid_copy( &delete_sid, &q_u->sid.sid );
4164         
4165         DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4166                 sid_string_static(&delete_sid)));
4167                 
4168         /* Find the policy handle. Open a policy on it. */
4169         
4170         if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted)) 
4171                 return NT_STATUS_INVALID_HANDLE;
4172         
4173         result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, 
4174                 "_samr_remove_sid_foreign_domain");
4175                 
4176         if (!NT_STATUS_IS_OK(result)) 
4177                 return result;
4178                         
4179         DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n", 
4180                 sid_string_static(&alias_sid)));
4181                 
4182         /* make sure we can handle this */
4183         
4184         if ( sid_check_is_domain(&alias_sid) )
4185                 type = SID_NAME_DOM_GRP;
4186         else if ( sid_check_is_builtin(&alias_sid) )
4187                 type = SID_NAME_ALIAS;
4188         
4189         if ( type == SID_NAME_UNKNOWN ) {
4190                 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4191                 return NT_STATUS_OK;
4192         }
4193
4194         /* check if the user exists before trying to delete */
4195         
4196         pdb_init_sam(&sam_pass);
4197         
4198         if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4199                 is_user = True;
4200         } else {
4201                 /* maybe it is a group */
4202                 if( !pdb_getgrsid(&map, delete_sid) ) {
4203                         DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4204                                 sid_string_static(&delete_sid)));
4205                         result = NT_STATUS_INVALID_SID;
4206                         goto done;
4207                 }
4208         }
4209         
4210         /* we can only delete a user from a group since we don't have 
4211            nested groups anyways.  So in the latter case, just say OK */
4212            
4213         if ( is_user ) {
4214                 GROUP_MAP       *mappings = NULL;
4215                 int             num_groups, i;
4216                 struct group    *grp2;
4217                 
4218                 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4219                 
4220                         /* interate over the groups */
4221                         for ( i=0; i<num_groups; i++ ) {
4222
4223                                 grp2 = getgrgid(mappings[i].gid);
4224
4225                                 if ( !grp2 ) {
4226                                         DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4227                                         continue;
4228                                 }
4229                         
4230                                 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4231                                         continue;
4232                                 
4233                                 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4234                                 
4235                                 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4236                                         /* should we fail here ? */
4237                                         DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4238                                                 pdb_get_username(sam_pass), grp2->gr_name ));
4239                                         continue;
4240                                 }
4241                                         
4242                                 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4243                                         pdb_get_username(sam_pass), grp2->gr_name ));
4244                         }
4245                         
4246                         SAFE_FREE(mappings);
4247                 }
4248         }
4249         
4250         result = NT_STATUS_OK;
4251 done:
4252
4253         pdb_free_sam(&sam_pass);
4254
4255         return result;
4256 }
4257
4258 /*******************************************************************
4259  _samr_unknown_2e
4260  ********************************************************************/
4261
4262 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4263 {
4264         struct samr_info *info = NULL;
4265         SAM_UNK_CTR *ctr;
4266         uint32 min_pass_len,pass_hist,flag;
4267         time_t u_expire, u_min_age;
4268         NTTIME nt_expire, nt_min_age;
4269
4270         time_t u_lock_duration, u_reset_time;
4271         NTTIME nt_lock_duration, nt_reset_time;
4272         uint32 lockout;
4273         
4274         time_t u_logout;
4275         NTTIME nt_logout;
4276
4277         uint32 num_users=0, num_groups=0, num_aliases=0;
4278
4279         uint32 account_policy_temp;
4280
4281         if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4282                 return NT_STATUS_NO_MEMORY;
4283
4284         ZERO_STRUCTP(ctr);
4285
4286         r_u->status = NT_STATUS_OK;
4287
4288         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4289
4290         /* find the policy handle.  open a policy on it. */
4291         if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4292                 return NT_STATUS_INVALID_HANDLE;
4293
4294         switch (q_u->switch_value) {
4295                 case 0x01:
4296                         account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4297                         min_pass_len = account_policy_temp;
4298
4299                         account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4300                         pass_hist = account_policy_temp;
4301
4302                         account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4303                         flag = account_policy_temp;
4304
4305                         account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4306                         u_expire = account_policy_temp;
4307
4308                         account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4309                         u_min_age = account_policy_temp;
4310
4311                         unix_to_nt_time_abs(&nt_expire, u_expire);
4312                         unix_to_nt_time_abs(&nt_min_age, u_min_age);
4313
4314                         init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist, 
4315                                        flag, nt_expire, nt_min_age);
4316                         break;
4317                 case 0x02:
4318                         become_root();          
4319                         r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4320                         unbecome_root();
4321                         if (!NT_STATUS_IS_OK(r_u->status)) {
4322                                 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4323                                 return r_u->status;
4324                         }
4325                         num_users=info->disp_info.num_user_account;
4326                         free_samr_db(info);
4327                         
4328                         r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4329                         if (NT_STATUS_IS_ERR(r_u->status)) {
4330                                 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4331                                 return r_u->status;
4332                         }
4333                         num_groups=info->disp_info.num_group_account;
4334                         free_samr_db(info);
4335
4336                         /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4337                         init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL), 
4338                                        num_users, num_groups, num_aliases);
4339                         break;
4340                 case 0x03:
4341                         account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4342                         u_logout = account_policy_temp;
4343
4344                         unix_to_nt_time_abs(&nt_logout, u_logout);
4345                         
4346                         init_unk_info3(&ctr->info.inf3, nt_logout);
4347                         break;
4348                 case 0x05:
4349                         init_unk_info5(&ctr->info.inf5, global_myname());
4350                         break;
4351                 case 0x06:
4352                         init_unk_info6(&ctr->info.inf6);
4353                         break;
4354                 case 0x07:
4355                         init_unk_info7(&ctr->info.inf7);
4356                         break;
4357                 case 0x0c:
4358                         account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4359                         u_lock_duration = account_policy_temp * 60;
4360
4361                         account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4362                         u_reset_time = account_policy_temp * 60;
4363
4364                         account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4365                         lockout = account_policy_temp;
4366         
4367                         unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4368                         unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4369         
4370                         init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4371                         break;
4372                 default:
4373                         return NT_STATUS_INVALID_INFO_CLASS;
4374         }
4375
4376         init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4377
4378         DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4379
4380         return r_u->status;
4381 }
4382
4383 /*******************************************************************
4384  _samr_
4385  ********************************************************************/
4386
4387 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4388 {
4389         time_t u_expire, u_min_age;
4390         time_t u_logout;
4391         time_t u_lock_duration, u_reset_time;
4392
4393         r_u->status = NT_STATUS_OK;
4394
4395         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4396
4397         /* find the policy handle.  open a policy on it. */
4398         if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4399                 return NT_STATUS_INVALID_HANDLE;
4400
4401         DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4402
4403         switch (q_u->switch_value) {
4404                 case 0x01:
4405                         u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4406                         u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4407                         
4408                         account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4409                         account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4410                         account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4411                         account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4412                         account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4413                         break;
4414                 case 0x02:
4415                         break;
4416                 case 0x03:
4417                         u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4418                         account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4419                         break;
4420                 case 0x05:
4421                         break;
4422                 case 0x06:
4423                         break;
4424                 case 0x07:
4425                         break;
4426                 case 0x0c:
4427                         u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration)/60;
4428                         u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4429                         
4430                         account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4431                         account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4432                         account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4433                         break;
4434                 default:
4435                         return NT_STATUS_INVALID_INFO_CLASS;
4436         }
4437
4438         init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4439
4440         DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4441
4442         return r_u->status;
4443 }