Fix for possible crash bug from Sebastian Krahmer (SuSE).
[Samba/gebeck_regimport.git] / source3 / rpc_server / srv_samr_nt.c
blobb8de24cf39b952b3cf87c37129796efcba8c17d7
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.
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.
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.
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.
29 * This is the implementation of the SAMR code.
32 #include "includes.h"
34 #undef DBGC_CLASS
35 #define DBGC_CLASS DBGC_RPC_SRV
37 extern DOM_SID global_sid_Builtin;
39 extern rid_name domain_group_rids[];
40 extern rid_name domain_alias_rids[];
41 extern rid_name builtin_alias_rids[];
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;
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;
62 TALLOC_CTX *mem_ctx;
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};
71 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size);
73 /*******************************************************************
74 Checks if access to an object should be granted, and returns that
75 level of access for further checks.
76 ********************************************************************/
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)
81 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
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;
91 else {
92 DEBUG(2,("%s: ACCESS DENIED (requested: %#010x)\n",
93 debug, des_access));
96 return status;
99 /*******************************************************************
100 Checks if access to a function can be granted
101 ********************************************************************/
103 NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
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;
114 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
115 debug, acc_granted, acc_required));
116 return NT_STATUS_ACCESS_DENIED;
118 return NT_STATUS_OK;
122 /*******************************************************************
123 Create a samr_info struct.
124 ********************************************************************/
126 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
128 struct samr_info *info;
129 fstring sid_str;
130 TALLOC_CTX *mem_ctx;
132 if (psid) {
133 sid_to_string(sid_str, psid);
134 } else {
135 fstrcpy(sid_str,"(NULL)");
138 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
140 if ((info = (struct samr_info *)talloc(mem_ctx, sizeof(struct samr_info))) == NULL)
141 return NULL;
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"));
150 info->mem_ctx = mem_ctx;
151 return info;
154 /*******************************************************************
155 Function to free the per handle data.
156 ********************************************************************/
158 static void free_samr_users(struct samr_info *info)
160 int i;
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);
169 info->disp_info.user_dbloaded=False;
170 info->disp_info.num_user_account=0;
173 /*******************************************************************
174 Function to free the per handle data.
175 ********************************************************************/
177 static void free_samr_db(struct samr_info *info)
179 /* Groups are talloced */
181 free_samr_users(info);
183 info->disp_info.group_dbloaded=False;
184 info->disp_info.num_group_account=0;
187 static void free_samr_info(void *ptr)
189 struct samr_info *info=(struct samr_info *) ptr;
191 free_samr_db(info);
192 talloc_destroy(info->mem_ctx);
195 /*******************************************************************
196 Ensure password info is never given out. Paranioa... JRA.
197 ********************************************************************/
199 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
202 if (!sam_pass)
203 return;
205 /* These now zero out the old password */
207 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
208 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
212 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
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;
219 DEBUG(10,("load_sampwd_entries\n"));
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;
229 free_samr_users(info);
231 if (!pdb_setsampwent(False)) {
232 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
233 return NT_STATUS_ACCESS_DENIED;
236 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
237 && pdb_getsampwent(pwd) == True; pwd=NULL) {
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;
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;
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) {
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));
261 if (pwd_array==NULL)
262 return NT_STATUS_NO_MEMORY;
264 info->disp_info.disp_user_info=pwd_array;
267 /* Copy the SAM_ACCOUNT into the array */
268 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
270 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
272 info->disp_info.num_user_account++;
275 pdb_endsampwent();
277 /* the snapshoot is in memory, we're ready to enumerate fast */
279 info->acb_mask = acb_mask;
280 info->all_machines = all_machines;
281 info->disp_info.user_dbloaded=True;
283 DEBUG(10,("load_sampwd_entries: done\n"));
285 return nt_status;
288 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
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;
297 DEBUG(10,("load_group_domain_entries\n"));
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;
306 become_root();
307 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
308 unbecome_root();
310 if ( !ret ) {
311 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
312 return NT_STATUS_NO_MEMORY;
316 info->disp_info.num_group_account=group_entries;
318 grp_array=(DOMAIN_GRP *)talloc(mem_ctx, info->disp_info.num_group_account*sizeof(DOMAIN_GRP));
319 if (group_entries!=0 && grp_array==NULL) {
320 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
321 SAFE_FREE(map);
322 return NT_STATUS_NO_MEMORY;
325 info->disp_info.disp_group_info=grp_array;
327 for (i=0; i<group_entries; i++) {
328 fstrcpy(grp_array[i].name, map[i].nt_name);
329 fstrcpy(grp_array[i].comment, map[i].comment);
330 sid_split_rid(&map[i].sid, &grp_array[i].rid);
331 grp_array[i].attr=SID_NAME_DOM_GRP;
334 SAFE_FREE(map);
336 /* the snapshoot is in memory, we're ready to enumerate fast */
338 info->disp_info.group_dbloaded=True;
340 DEBUG(10,("load_group_domain_entries: done\n"));
342 return NT_STATUS_OK;
346 /*******************************************************************
347 _samr_close_hnd
348 ********************************************************************/
350 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
352 r_u->status = NT_STATUS_OK;
354 /* close the policy handle */
355 if (!close_policy_hnd(p, &q_u->pol))
356 return NT_STATUS_OBJECT_NAME_INVALID;
358 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
360 return r_u->status;
363 /*******************************************************************
364 samr_reply_open_domain
365 ********************************************************************/
367 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
369 struct samr_info *info;
370 SEC_DESC *psd = NULL;
371 uint32 acc_granted;
372 uint32 des_access = q_u->flags;
373 size_t sd_size;
374 NTSTATUS status;
376 r_u->status = NT_STATUS_OK;
378 /* find the connection policy handle. */
379 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
380 return NT_STATUS_INVALID_HANDLE;
382 if (!NT_STATUS_IS_OK(status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_OPEN_DOMAIN,"_samr_open_domain"))) {
383 return status;
386 /*check if access can be granted as requested by client. */
387 samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
388 se_map_generic(&des_access,&dom_generic_mapping);
390 if (!NT_STATUS_IS_OK(status =
391 access_check_samr_object(psd, p->pipe_user.nt_user_token,
392 des_access, &acc_granted, "_samr_open_domain"))) {
393 return status;
396 /* associate the domain SID with the (unique) handle. */
397 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
398 return NT_STATUS_NO_MEMORY;
399 info->acc_granted = acc_granted;
401 /* get a (unique) handle. open a policy on it. */
402 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
403 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
405 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
407 return r_u->status;
410 /*******************************************************************
411 _samr_get_usrdom_pwinfo
412 ********************************************************************/
414 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
416 struct samr_info *info = NULL;
418 r_u->status = NT_STATUS_OK;
420 /* find the policy handle. open a policy on it. */
421 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
422 return NT_STATUS_INVALID_HANDLE;
424 if (!sid_check_is_in_our_domain(&info->sid))
425 return NT_STATUS_OBJECT_TYPE_MISMATCH;
427 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
429 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
432 * NT sometimes return NT_STATUS_ACCESS_DENIED
433 * I don't know yet why.
436 return r_u->status;
439 /*******************************************************************
440 samr_make_dom_obj_sd
441 ********************************************************************/
443 static NTSTATUS samr_make_dom_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
445 extern DOM_SID global_sid_World;
446 DOM_SID adm_sid;
447 DOM_SID act_sid;
449 SEC_ACE ace[3];
450 SEC_ACCESS mask;
452 SEC_ACL *psa = NULL;
454 sid_copy(&adm_sid, &global_sid_Builtin);
455 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
457 sid_copy(&act_sid, &global_sid_Builtin);
458 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
460 /*basic access for every one*/
461 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_EXECUTE | GENERIC_RIGHTS_DOMAIN_READ);
462 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
464 /*full access for builtin aliases Administrators and Account Operators*/
465 init_sec_access(&mask, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS);
466 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
467 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
469 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
470 return NT_STATUS_NO_MEMORY;
472 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
473 return NT_STATUS_NO_MEMORY;
475 return NT_STATUS_OK;
478 /*******************************************************************
479 samr_make_usr_obj_sd
480 ********************************************************************/
482 static NTSTATUS samr_make_usr_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, DOM_SID *usr_sid)
484 extern DOM_SID global_sid_World;
485 DOM_SID adm_sid;
486 DOM_SID act_sid;
488 SEC_ACE ace[4];
489 SEC_ACCESS mask;
491 SEC_ACL *psa = NULL;
493 sid_copy(&adm_sid, &global_sid_Builtin);
494 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
496 sid_copy(&act_sid, &global_sid_Builtin);
497 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
499 /*basic access for every one*/
500 init_sec_access(&mask, GENERIC_RIGHTS_USER_EXECUTE | GENERIC_RIGHTS_USER_READ);
501 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
503 /*full access for builtin aliases Administrators and Account Operators*/
504 init_sec_access(&mask, GENERIC_RIGHTS_USER_ALL_ACCESS);
505 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
506 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
508 /*extended access for the user*/
509 init_sec_access(&mask,READ_CONTROL_ACCESS | SA_RIGHT_USER_CHANGE_PASSWORD | SA_RIGHT_USER_SET_LOC_COM);
510 init_sec_ace(&ace[3], usr_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
512 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 4, ace)) == NULL)
513 return NT_STATUS_NO_MEMORY;
515 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
516 return NT_STATUS_NO_MEMORY;
518 return NT_STATUS_OK;
521 /*******************************************************************
522 samr_make_grp_obj_sd
523 ********************************************************************/
525 static NTSTATUS samr_make_grp_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
527 extern DOM_SID global_sid_World;
528 DOM_SID adm_sid;
529 DOM_SID act_sid;
531 SEC_ACE ace[3];
532 SEC_ACCESS mask;
534 SEC_ACL *psa = NULL;
536 sid_copy(&adm_sid, &global_sid_Builtin);
537 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
539 sid_copy(&act_sid, &global_sid_Builtin);
540 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
542 /*basic access for every one*/
543 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_EXECUTE | GENERIC_RIGHTS_GROUP_READ);
544 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
546 /*full access for builtin aliases Administrators and Account Operators*/
547 init_sec_access(&mask, GENERIC_RIGHTS_GROUP_ALL_ACCESS);
548 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
549 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
551 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
552 return NT_STATUS_NO_MEMORY;
554 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
555 return NT_STATUS_NO_MEMORY;
557 return NT_STATUS_OK;
560 /*******************************************************************
561 samr_make_ali_obj_sd
562 ********************************************************************/
564 static NTSTATUS samr_make_ali_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
566 extern DOM_SID global_sid_World;
567 DOM_SID adm_sid;
568 DOM_SID act_sid;
570 SEC_ACE ace[3];
571 SEC_ACCESS mask;
573 SEC_ACL *psa = NULL;
575 sid_copy(&adm_sid, &global_sid_Builtin);
576 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
578 sid_copy(&act_sid, &global_sid_Builtin);
579 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
581 /*basic access for every one*/
582 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_EXECUTE | GENERIC_RIGHTS_ALIAS_READ);
583 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
585 /*full access for builtin aliases Administrators and Account Operators*/
586 init_sec_access(&mask, GENERIC_RIGHTS_ALIAS_ALL_ACCESS);
587 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
588 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
590 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
591 return NT_STATUS_NO_MEMORY;
593 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
594 return NT_STATUS_NO_MEMORY;
596 return NT_STATUS_OK;
599 static BOOL get_lsa_policy_samr_sid(pipes_struct *p, POLICY_HND *pol, DOM_SID *sid, uint32 *acc_granted)
601 struct samr_info *info = NULL;
603 /* find the policy handle. open a policy on it. */
604 if (!find_policy_by_hnd(p, pol, (void **)&info))
605 return False;
607 if (!info)
608 return False;
610 *sid = info->sid;
611 *acc_granted = info->acc_granted;
612 return True;
615 /*******************************************************************
616 _samr_set_sec_obj
617 ********************************************************************/
619 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
621 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
622 return NT_STATUS_NOT_IMPLEMENTED;
626 /*******************************************************************
627 _samr_query_sec_obj
628 ********************************************************************/
630 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
632 DOM_SID pol_sid;
633 fstring str_sid;
634 SEC_DESC * psd = NULL;
635 size_t sd_size;
636 uint32 acc_granted;
638 r_u->status = NT_STATUS_OK;
640 /* Get the SID. */
641 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
642 return NT_STATUS_INVALID_HANDLE;
646 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
648 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
650 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
651 if (pol_sid.sid_rev_num == 0)
653 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
654 r_u->status = samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
656 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
659 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
660 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
662 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
664 /* TODO: Builtin probably needs a different SD with restricted write access*/
665 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
666 r_u->status = samr_make_dom_obj_sd(p->mem_ctx, &psd, &sd_size);
668 else if (sid_check_is_in_our_domain(&pol_sid) ||
669 sid_check_is_in_builtin(&pol_sid))
671 /* TODO: different SDs have to be generated for aliases groups and users.
672 Currently all three get a default user SD */
673 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
674 r_u->status = samr_make_usr_obj_sd(p->mem_ctx, &psd,&sd_size, &pol_sid);
676 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
678 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
679 return NT_STATUS_NO_MEMORY;
681 if (NT_STATUS_IS_OK(r_u->status))
682 r_u->ptr = 1;
684 return r_u->status;
687 /*******************************************************************
688 makes a SAM_ENTRY / UNISTR2* structure from a user list.
689 ********************************************************************/
691 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
692 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
693 DOM_SID *domain_sid)
695 uint32 i;
696 SAM_ENTRY *sam;
697 UNISTR2 *uni_name;
698 SAM_ACCOUNT *pwd = NULL;
699 UNISTR2 uni_temp_name;
700 const char *temp_name;
701 const DOM_SID *user_sid;
702 uint32 user_rid;
703 fstring user_sid_string;
704 fstring domain_sid_string;
706 *sam_pp = NULL;
707 *uni_name_pp = NULL;
709 if (num_entries == 0)
710 return NT_STATUS_OK;
712 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_entries);
714 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_entries);
716 if (sam == NULL || uni_name == NULL) {
717 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
718 return NT_STATUS_NO_MEMORY;
721 for (i = 0; i < num_entries; i++) {
722 pwd = &disp_user_info[i+start_idx];
723 temp_name = pdb_get_username(pwd);
724 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
725 user_sid = pdb_get_user_sid(pwd);
727 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
728 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
729 "the domain sid %s. Failing operation.\n",
730 temp_name,
731 sid_to_string(user_sid_string, user_sid),
732 sid_to_string(domain_sid_string, domain_sid)));
733 return NT_STATUS_UNSUCCESSFUL;
736 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
737 copy_unistr2(&uni_name[i], &uni_temp_name);
740 *sam_pp = sam;
741 *uni_name_pp = uni_name;
742 return NT_STATUS_OK;
745 /*******************************************************************
746 samr_reply_enum_dom_users
747 ********************************************************************/
749 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
750 SAMR_R_ENUM_DOM_USERS *r_u)
752 struct samr_info *info = NULL;
753 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
754 int num_account;
755 uint32 enum_context=q_u->start_idx;
756 uint32 max_size=q_u->max_size;
757 uint32 temp_size;
758 enum remote_arch_types ra_type = get_remote_arch();
759 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
760 uint32 max_entries = max_sam_entries;
761 DOM_SID domain_sid;
763 r_u->status = NT_STATUS_OK;
765 /* find the policy handle. open a policy on it. */
766 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
767 return NT_STATUS_INVALID_HANDLE;
769 domain_sid = info->sid;
771 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
772 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
773 "_samr_enum_dom_users"))) {
774 return r_u->status;
777 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
779 become_root();
780 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
781 unbecome_root();
783 if (!NT_STATUS_IS_OK(r_u->status))
784 return r_u->status;
786 num_account = info->disp_info.num_user_account;
788 if (enum_context > num_account) {
789 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
790 return NT_STATUS_OK;
793 /* verify we won't overflow */
794 if (max_entries > num_account-enum_context) {
795 max_entries = num_account-enum_context;
796 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
799 /* calculate the size and limit on the number of entries we will return */
800 temp_size=max_entries*struct_size;
802 if (temp_size>max_size) {
803 max_entries=MIN((max_size/struct_size),max_entries);;
804 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
808 * Note from JRA. total_entries is not being used here. Currently if there is a
809 * large user base then it looks like NT will enumerate until get_sampwd_entries
810 * returns False due to num_entries being zero. This will cause an access denied
811 * return. I don't think this is right and needs further investigation. Note that
812 * this is also the same in the TNG code (I don't think that has been tested with
813 * a very large user list as MAX_SAM_ENTRIES is set to 600).
815 * I also think that one of the 'num_entries' return parameters is probably
816 * the "max entries" parameter - but in the TNG code they're all currently set to the same
817 * value (again I think this is wrong).
820 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
821 max_entries, enum_context,
822 info->disp_info.disp_user_info,
823 &domain_sid);
825 if (!NT_STATUS_IS_OK(r_u->status))
826 return r_u->status;
828 if (enum_context+max_entries < num_account)
829 r_u->status = STATUS_MORE_ENTRIES;
831 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
833 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
835 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
837 return r_u->status;
840 /*******************************************************************
841 makes a SAM_ENTRY / UNISTR2* structure from a group list.
842 ********************************************************************/
844 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
845 uint32 num_sam_entries, DOMAIN_GRP *grp)
847 uint32 i;
848 SAM_ENTRY *sam;
849 UNISTR2 *uni_name;
851 *sam_pp = NULL;
852 *uni_name_pp = NULL;
854 if (num_sam_entries == 0)
855 return;
857 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
859 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
861 if (sam == NULL || uni_name == NULL) {
862 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
863 return;
866 for (i = 0; i < num_sam_entries; i++) {
868 * JRA. I think this should include the null. TNG does not.
870 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
871 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
874 *sam_pp = sam;
875 *uni_name_pp = uni_name;
878 /*******************************************************************
879 Get the group entries - similar to get_sampwd_entries().
880 ******************************************************************/
882 static NTSTATUS get_group_entries( enum SID_NAME_USE type, TALLOC_CTX *ctx,
883 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
884 uint32 *p_num_entries, uint32 max_entries )
886 GROUP_MAP *map=NULL;
887 int i;
888 uint32 group_entries = 0;
889 uint32 num_entries = 0;
891 *p_num_entries = 0;
893 /* access checks for the users were performed higher up. become/unbecome_root()
894 needed for some passdb backends to enumerate groups */
896 become_root();
897 pdb_enum_group_mapping(type, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
898 unbecome_root();
900 num_entries=group_entries-start_idx;
902 /* limit the number of entries */
903 if (num_entries>max_entries) {
904 DEBUG(5,("Limiting to %d entries\n", max_entries));
905 num_entries=max_entries;
908 *d_grp=(DOMAIN_GRP *)talloc_zero(ctx, num_entries*sizeof(DOMAIN_GRP));
909 if (num_entries!=0 && *d_grp==NULL){
910 SAFE_FREE(map);
911 return NT_STATUS_NO_MEMORY;
914 for (i=0; i<num_entries; i++) {
915 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
916 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
917 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
918 (*d_grp)[i].attr=type;
921 SAFE_FREE(map);
923 *p_num_entries = num_entries;
925 DEBUG(10,("get_group_entries: returning %d entries\n", *p_num_entries));
927 return NT_STATUS_OK;
930 /*******************************************************************
931 Wrapper for enuemrating domain groups
932 ******************************************************************/
934 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
935 DOM_SID *sid, uint32 start_idx,
936 uint32 *p_num_entries, uint32 max_entries )
938 return get_group_entries( SID_NAME_DOM_GRP, ctx, d_grp, sid, start_idx,
939 p_num_entries, max_entries );
942 /*******************************************************************
943 Wrapper for enumerating local groups
944 ******************************************************************/
946 static NTSTATUS get_group_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
947 DOM_SID *sid, uint32 start_idx,
948 uint32 *p_num_entries, uint32 max_entries)
950 if ( sid_equal(sid, &global_sid_Builtin) ) {
951 return get_group_entries( SID_NAME_WKN_GRP, ctx, d_grp,
952 sid, start_idx, p_num_entries, max_entries );
954 else if ( sid_equal(sid, get_global_sam_sid()) ) {
955 return get_group_entries( SID_NAME_ALIAS, ctx, d_grp,
956 sid, start_idx, p_num_entries, max_entries );
959 /* can't do anything with this SID */
961 *p_num_entries = 0;
963 return NT_STATUS_OK;
966 /*******************************************************************
967 samr_reply_enum_dom_groups
968 ********************************************************************/
970 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
972 DOMAIN_GRP *grp=NULL;
973 uint32 num_entries;
974 DOM_SID sid;
975 uint32 acc_granted;
977 r_u->status = NT_STATUS_OK;
979 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
980 return NT_STATUS_INVALID_HANDLE;
982 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
983 return r_u->status;
986 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
988 /* the domain group array is being allocated in the function below */
989 if (!NT_STATUS_IS_OK(r_u->status = get_group_domain_entries(p->mem_ctx, &grp, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES))) {
990 return r_u->status;
993 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
995 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
997 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
999 return r_u->status;
1003 /*******************************************************************
1004 samr_reply_enum_dom_aliases
1005 ********************************************************************/
1007 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
1009 DOMAIN_GRP *grp=NULL;
1010 uint32 num_entries = 0;
1011 fstring sid_str;
1012 DOM_SID sid;
1013 NTSTATUS status;
1014 uint32 acc_granted;
1016 r_u->status = NT_STATUS_OK;
1018 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1019 return NT_STATUS_INVALID_HANDLE;
1021 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1022 return r_u->status;
1025 sid_to_string(sid_str, &sid);
1026 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1028 status = get_group_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1029 &num_entries, MAX_SAM_ENTRIES);
1030 if (NT_STATUS_IS_ERR(status)) return status;
1032 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1034 /*safe_free(grp);*/
1036 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1038 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1040 return r_u->status;
1043 /*******************************************************************
1044 samr_reply_query_dispinfo
1045 ********************************************************************/
1047 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1048 SAMR_R_QUERY_DISPINFO *r_u)
1050 struct samr_info *info = NULL;
1051 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1053 uint32 max_entries=q_u->max_entries;
1054 uint32 enum_context=q_u->start_idx;
1055 uint32 max_size=q_u->max_size;
1057 SAM_DISPINFO_CTR *ctr;
1058 uint32 temp_size=0, total_data_size=0;
1059 NTSTATUS disp_ret;
1060 uint32 num_account = 0;
1061 enum remote_arch_types ra_type = get_remote_arch();
1062 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1063 DOM_SID domain_sid;
1065 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1066 r_u->status = NT_STATUS_OK;
1068 /* find the policy handle. open a policy on it. */
1069 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1070 return NT_STATUS_INVALID_HANDLE;
1072 domain_sid = info->sid;
1075 * calculate how many entries we will return.
1076 * based on
1077 * - the number of entries the client asked
1078 * - our limit on that
1079 * - the starting point (enumeration context)
1080 * - the buffer size the client will accept
1084 * We are a lot more like W2K. Instead of reading the SAM
1085 * each time to find the records we need to send back,
1086 * we read it once and link that copy to the sam handle.
1087 * For large user list (over the MAX_SAM_ENTRIES)
1088 * it's a definitive win.
1089 * second point to notice: between enumerations
1090 * our sam is now the same as it's a snapshoot.
1091 * third point: got rid of the static SAM_USER_21 struct
1092 * no more intermediate.
1093 * con: it uses much more memory, as a full copy is stored
1094 * in memory.
1096 * If you want to change it, think twice and think
1097 * of the second point , that's really important.
1099 * JFM, 12/20/2001
1102 /* Get what we need from the password database */
1103 switch (q_u->switch_level) {
1104 case 0x1:
1105 /* When playing with usrmgr, this is necessary
1106 if you want immediate refresh after editing
1107 a user. I would like to do this after the
1108 setuserinfo2, but we do not have access to
1109 the domain handle in that call, only to the
1110 user handle. Where else does this hurt?
1111 -- Volker
1113 #if 0
1114 /* We cannot do this here - it kills performace. JRA. */
1115 free_samr_users(info);
1116 #endif
1117 case 0x2:
1118 case 0x4:
1119 become_root();
1120 /* Level 2 is for all machines, otherwise only 'normal' users */
1121 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1122 unbecome_root();
1123 if (!NT_STATUS_IS_OK(r_u->status)) {
1124 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1125 return r_u->status;
1127 num_account = info->disp_info.num_user_account;
1128 break;
1129 case 0x3:
1130 case 0x5:
1131 r_u->status = load_group_domain_entries(info, &info->sid);
1132 if (!NT_STATUS_IS_OK(r_u->status))
1133 return r_u->status;
1134 num_account = info->disp_info.num_group_account;
1135 break;
1136 default:
1137 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1138 return NT_STATUS_INVALID_INFO_CLASS;
1141 /* first limit the number of entries we will return */
1142 if(max_entries > max_sam_entries) {
1143 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1144 max_entries = max_sam_entries;
1147 if (enum_context > num_account) {
1148 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1149 return NT_STATUS_NO_MORE_ENTRIES;
1152 /* verify we won't overflow */
1153 if (max_entries > num_account-enum_context) {
1154 max_entries = num_account-enum_context;
1155 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1158 /* calculate the size and limit on the number of entries we will return */
1159 temp_size=max_entries*struct_size;
1161 if (temp_size>max_size) {
1162 max_entries=MIN((max_size/struct_size),max_entries);;
1163 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1166 if (!(ctr = (SAM_DISPINFO_CTR *)talloc_zero(p->mem_ctx,sizeof(SAM_DISPINFO_CTR))))
1167 return NT_STATUS_NO_MEMORY;
1169 ZERO_STRUCTP(ctr);
1171 /* Now create reply structure */
1172 switch (q_u->switch_level) {
1173 case 0x1:
1174 if (max_entries) {
1175 if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_1))))
1176 return NT_STATUS_NO_MEMORY;
1178 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1179 info->disp_info.disp_user_info, &domain_sid);
1180 if (!NT_STATUS_IS_OK(disp_ret))
1181 return disp_ret;
1182 break;
1183 case 0x2:
1184 if (max_entries) {
1185 if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_2))))
1186 return NT_STATUS_NO_MEMORY;
1188 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1189 info->disp_info.disp_user_info, &domain_sid);
1190 if (!NT_STATUS_IS_OK(disp_ret))
1191 return disp_ret;
1192 break;
1193 case 0x3:
1194 if (max_entries) {
1195 if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_3))))
1196 return NT_STATUS_NO_MEMORY;
1198 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1199 if (!NT_STATUS_IS_OK(disp_ret))
1200 return disp_ret;
1201 break;
1202 case 0x4:
1203 if (max_entries) {
1204 if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_4))))
1205 return NT_STATUS_NO_MEMORY;
1207 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1208 if (!NT_STATUS_IS_OK(disp_ret))
1209 return disp_ret;
1210 break;
1211 case 0x5:
1212 if (max_entries) {
1213 if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc_zero(p->mem_ctx,max_entries*sizeof(SAM_DISPINFO_5))))
1214 return NT_STATUS_NO_MEMORY;
1216 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1217 if (!NT_STATUS_IS_OK(disp_ret))
1218 return disp_ret;
1219 break;
1221 default:
1222 ctr->sam.info = NULL;
1223 return NT_STATUS_INVALID_INFO_CLASS;
1226 /* calculate the total size */
1227 total_data_size=num_account*struct_size;
1229 if (enum_context+max_entries < num_account)
1230 r_u->status = STATUS_MORE_ENTRIES;
1232 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1234 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1236 return r_u->status;
1240 /*******************************************************************
1241 samr_reply_query_aliasinfo
1242 ********************************************************************/
1244 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1246 DOM_SID sid;
1247 GROUP_MAP map;
1248 uint32 acc_granted;
1249 BOOL ret;
1251 r_u->status = NT_STATUS_OK;
1253 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1255 /* find the policy handle. open a policy on it. */
1256 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1257 return NT_STATUS_INVALID_HANDLE;
1258 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1259 return r_u->status;
1262 if (!sid_check_is_in_our_domain(&sid) &&
1263 !sid_check_is_in_builtin(&sid))
1264 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1266 become_root();
1267 ret = pdb_getgrsid(&map, sid);
1268 unbecome_root();
1270 if ( !ret )
1271 return NT_STATUS_NO_SUCH_ALIAS;
1273 switch (q_u->switch_level) {
1274 case 1:
1275 r_u->ptr = 1;
1276 r_u->ctr.switch_value1 = 1;
1277 init_samr_alias_info1(&r_u->ctr.alias.info1, map.nt_name, 1, map.comment);
1278 break;
1279 case 3:
1280 r_u->ptr = 1;
1281 r_u->ctr.switch_value1 = 3;
1282 init_samr_alias_info3(&r_u->ctr.alias.info3, map.comment);
1283 break;
1284 default:
1285 return NT_STATUS_INVALID_INFO_CLASS;
1288 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1290 return r_u->status;
1293 #if 0
1294 /*******************************************************************
1295 samr_reply_lookup_ids
1296 ********************************************************************/
1298 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1300 uint32 rid[MAX_SAM_ENTRIES];
1301 int num_rids = q_u->num_sids1;
1303 r_u->status = NT_STATUS_OK;
1305 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1307 if (num_rids > MAX_SAM_ENTRIES) {
1308 num_rids = MAX_SAM_ENTRIES;
1309 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1312 #if 0
1313 int i;
1314 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1316 for (i = 0; i < num_rids && status == 0; i++)
1318 struct sam_passwd *sam_pass;
1319 fstring user_name;
1322 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1323 q_u->uni_user_name[i].uni_str_len));
1325 /* find the user account */
1326 become_root();
1327 sam_pass = get_smb21pwd_entry(user_name, 0);
1328 unbecome_root();
1330 if (sam_pass == NULL)
1332 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1333 rid[i] = 0;
1335 else
1337 rid[i] = sam_pass->user_rid;
1340 #endif
1342 num_rids = 1;
1343 rid[0] = BUILTIN_ALIAS_RID_USERS;
1345 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1347 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1349 return r_u->status;
1351 #endif
1353 /*******************************************************************
1354 _samr_lookup_names
1355 ********************************************************************/
1357 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1359 uint32 rid[MAX_SAM_ENTRIES];
1360 uint32 local_rid;
1361 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1362 enum SID_NAME_USE local_type;
1363 int i;
1364 int num_rids = q_u->num_names2;
1365 DOM_SID pol_sid;
1366 fstring sid_str;
1367 uint32 acc_granted;
1369 r_u->status = NT_STATUS_OK;
1371 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1373 ZERO_ARRAY(rid);
1374 ZERO_ARRAY(type);
1376 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1377 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1378 return r_u->status;
1381 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, 0, "_samr_lookup_names"))) { /* Don't know the acc_bits yet */
1382 return r_u->status;
1385 if (num_rids > MAX_SAM_ENTRIES) {
1386 num_rids = MAX_SAM_ENTRIES;
1387 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1390 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1392 for (i = 0; i < num_rids; i++) {
1393 fstring name;
1394 DOM_SID sid;
1395 int ret;
1397 r_u->status = NT_STATUS_NONE_MAPPED;
1399 rid [i] = 0xffffffff;
1400 type[i] = SID_NAME_UNKNOWN;
1402 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1405 * we are only looking for a name
1406 * the SID we get back can be outside
1407 * the scope of the pol_sid
1409 * in clear: it prevents to reply to domain\group: yes
1410 * when only builtin\group exists.
1412 * a cleaner code is to add the sid of the domain we're looking in
1413 * to the local_lookup_name function.
1416 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1417 sid_split_rid(&sid, &local_rid);
1419 if (sid_equal(&sid, &pol_sid)) {
1420 rid[i]=local_rid;
1421 type[i]=local_type;
1422 r_u->status = NT_STATUS_OK;
1427 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1429 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1431 return r_u->status;
1434 /*******************************************************************
1435 _samr_chgpasswd_user
1436 ********************************************************************/
1438 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1440 fstring user_name;
1441 fstring wks;
1443 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1445 r_u->status = NT_STATUS_OK;
1447 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1448 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1450 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1453 * Pass the user through the NT -> unix user mapping
1454 * function.
1457 (void)map_username(user_name);
1460 * UNIX username case mangling not required, pass_oem_change
1461 * is case insensitive.
1464 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1465 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1467 init_samr_r_chgpasswd_user(r_u, r_u->status);
1469 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1471 return r_u->status;
1474 /*******************************************************************
1475 makes a SAMR_R_LOOKUP_RIDS structure.
1476 ********************************************************************/
1478 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names, fstring names[],
1479 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1481 uint32 i;
1482 UNIHDR *hdr_name=NULL;
1483 UNISTR2 *uni_name=NULL;
1485 *pp_uni_name = NULL;
1486 *pp_hdr_name = NULL;
1488 if (num_names != 0) {
1489 hdr_name = (UNIHDR *)talloc_zero(ctx, sizeof(UNIHDR)*num_names);
1490 if (hdr_name == NULL)
1491 return False;
1493 uni_name = (UNISTR2 *)talloc_zero(ctx,sizeof(UNISTR2)*num_names);
1494 if (uni_name == NULL)
1495 return False;
1498 for (i = 0; i < num_names; i++) {
1499 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1500 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1501 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1504 *pp_uni_name = uni_name;
1505 *pp_hdr_name = hdr_name;
1507 return True;
1510 /*******************************************************************
1511 _samr_lookup_rids
1512 ********************************************************************/
1514 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1516 fstring group_names[MAX_SAM_ENTRIES];
1517 uint32 *group_attrs = NULL;
1518 UNIHDR *hdr_name = NULL;
1519 UNISTR2 *uni_name = NULL;
1520 DOM_SID pol_sid;
1521 int num_rids = q_u->num_rids1;
1522 int i;
1523 uint32 acc_granted;
1525 r_u->status = NT_STATUS_OK;
1527 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1529 /* find the policy handle. open a policy on it. */
1530 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1531 return NT_STATUS_INVALID_HANDLE;
1533 if (num_rids > MAX_SAM_ENTRIES) {
1534 num_rids = MAX_SAM_ENTRIES;
1535 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1538 if (num_rids) {
1539 if ((group_attrs = (uint32 *)talloc_zero(p->mem_ctx, num_rids * sizeof(uint32))) == NULL)
1540 return NT_STATUS_NO_MEMORY;
1543 r_u->status = NT_STATUS_NONE_MAPPED;
1545 become_root(); /* lookup_sid can require root privs */
1547 for (i = 0; i < num_rids; i++) {
1548 fstring tmpname;
1549 fstring domname;
1550 DOM_SID sid;
1551 enum SID_NAME_USE type;
1553 group_attrs[i] = SID_NAME_UNKNOWN;
1554 *group_names[i] = '\0';
1556 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1557 sid_copy(&sid, &pol_sid);
1558 sid_append_rid(&sid, q_u->rid[i]);
1560 if (lookup_sid(&sid, domname, tmpname, &type)) {
1561 r_u->status = NT_STATUS_OK;
1562 group_attrs[i] = (uint32)type;
1563 fstrcpy(group_names[i],tmpname);
1564 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1569 unbecome_root();
1571 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1572 return NT_STATUS_NO_MEMORY;
1574 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1576 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1578 return r_u->status;
1581 /*******************************************************************
1582 _samr_open_user. Safe - gives out no passwd info.
1583 ********************************************************************/
1585 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1587 SAM_ACCOUNT *sampass=NULL;
1588 DOM_SID sid;
1589 POLICY_HND domain_pol = q_u->domain_pol;
1590 POLICY_HND *user_pol = &r_u->user_pol;
1591 struct samr_info *info = NULL;
1592 SEC_DESC *psd = NULL;
1593 uint32 acc_granted;
1594 uint32 des_access = q_u->access_mask;
1595 size_t sd_size;
1596 BOOL ret;
1597 NTSTATUS nt_status;
1599 r_u->status = NT_STATUS_OK;
1601 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1602 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
1603 return NT_STATUS_INVALID_HANDLE;
1605 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user"))) {
1606 return nt_status;
1609 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1610 if (!NT_STATUS_IS_OK(nt_status)) {
1611 return nt_status;
1614 /* append the user's RID to it */
1615 if (!sid_append_rid(&sid, q_u->user_rid))
1616 return NT_STATUS_NO_SUCH_USER;
1618 /* check if access can be granted as requested by client. */
1619 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
1620 se_map_generic(&des_access, &usr_generic_mapping);
1621 if (!NT_STATUS_IS_OK(nt_status =
1622 access_check_samr_object(psd, p->pipe_user.nt_user_token,
1623 des_access, &acc_granted, "_samr_open_user"))) {
1624 return nt_status;
1627 become_root();
1628 ret=pdb_getsampwsid(sampass, &sid);
1629 unbecome_root();
1631 /* check that the SID exists in our domain. */
1632 if (ret == False) {
1633 return NT_STATUS_NO_SUCH_USER;
1636 pdb_free_sam(&sampass);
1638 /* associate the user's SID and access bits with the new handle. */
1639 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1640 return NT_STATUS_NO_MEMORY;
1641 info->acc_granted = acc_granted;
1643 /* get a (unique) handle. open a policy on it. */
1644 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1645 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1647 return r_u->status;
1650 /*************************************************************************
1651 get_user_info_10. Safe. Only gives out acb bits.
1652 *************************************************************************/
1654 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1656 SAM_ACCOUNT *smbpass=NULL;
1657 BOOL ret;
1658 NTSTATUS nt_status;
1660 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1662 if (!NT_STATUS_IS_OK(nt_status)) {
1663 return nt_status;
1666 become_root();
1667 ret = pdb_getsampwsid(smbpass, user_sid);
1668 unbecome_root();
1670 if (ret==False) {
1671 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1672 return NT_STATUS_NO_SUCH_USER;
1675 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1677 ZERO_STRUCTP(id10);
1678 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1680 pdb_free_sam(&smbpass);
1682 return NT_STATUS_OK;
1685 /*************************************************************************
1686 get_user_info_12. OK - this is the killer as it gives out password info.
1687 Ensure that this is only allowed on an encrypted connection with a root
1688 user. JRA.
1689 *************************************************************************/
1691 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1693 SAM_ACCOUNT *smbpass=NULL;
1694 BOOL ret;
1695 NTSTATUS nt_status;
1697 if (!p->ntlmssp_auth_validated)
1698 return NT_STATUS_ACCESS_DENIED;
1700 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1701 return NT_STATUS_ACCESS_DENIED;
1704 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1707 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1709 if (!NT_STATUS_IS_OK(nt_status)) {
1710 return nt_status;
1713 ret = pdb_getsampwsid(smbpass, user_sid);
1715 if (ret == False) {
1716 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1717 pdb_free_sam(&smbpass);
1718 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1721 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1723 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1724 pdb_free_sam(&smbpass);
1725 return NT_STATUS_ACCOUNT_DISABLED;
1728 ZERO_STRUCTP(id12);
1729 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1731 pdb_free_sam(&smbpass);
1733 return NT_STATUS_OK;
1736 /*************************************************************************
1737 get_user_info_20
1738 *************************************************************************/
1740 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1742 SAM_ACCOUNT *sampass=NULL;
1743 BOOL ret;
1745 pdb_init_sam_talloc(mem_ctx, &sampass);
1747 become_root();
1748 ret = pdb_getsampwsid(sampass, user_sid);
1749 unbecome_root();
1751 if (ret == False) {
1752 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1753 return NT_STATUS_NO_SUCH_USER;
1756 samr_clear_sam_passwd(sampass);
1758 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1760 ZERO_STRUCTP(id20);
1761 init_sam_user_info20A(id20, sampass);
1763 pdb_free_sam(&sampass);
1765 return NT_STATUS_OK;
1768 /*************************************************************************
1769 get_user_info_21
1770 *************************************************************************/
1772 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1773 DOM_SID *user_sid, DOM_SID *domain_sid)
1775 SAM_ACCOUNT *sampass=NULL;
1776 BOOL ret;
1777 NTSTATUS nt_status;
1779 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1780 if (!NT_STATUS_IS_OK(nt_status)) {
1781 return nt_status;
1784 become_root();
1785 ret = pdb_getsampwsid(sampass, user_sid);
1786 unbecome_root();
1788 if (ret == False) {
1789 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1790 return NT_STATUS_NO_SUCH_USER;
1793 samr_clear_sam_passwd(sampass);
1795 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1797 ZERO_STRUCTP(id21);
1798 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1800 pdb_free_sam(&sampass);
1802 return NT_STATUS_OK;
1805 /*******************************************************************
1806 _samr_query_userinfo
1807 ********************************************************************/
1809 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1811 SAM_USERINFO_CTR *ctr;
1812 struct samr_info *info = NULL;
1813 DOM_SID domain_sid;
1814 uint32 rid;
1816 r_u->status=NT_STATUS_OK;
1818 /* search for the handle */
1819 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1820 return NT_STATUS_INVALID_HANDLE;
1822 domain_sid = info->sid;
1824 sid_split_rid(&domain_sid, &rid);
1826 if (!sid_check_is_in_our_domain(&info->sid))
1827 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1829 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1831 ctr = (SAM_USERINFO_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_USERINFO_CTR));
1832 if (!ctr)
1833 return NT_STATUS_NO_MEMORY;
1835 ZERO_STRUCTP(ctr);
1837 /* ok! user info levels (lots: see MSDEV help), off we go... */
1838 ctr->switch_value = q_u->switch_value;
1840 switch (q_u->switch_value) {
1841 case 0x10:
1842 ctr->info.id10 = (SAM_USER_INFO_10 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_10));
1843 if (ctr->info.id10 == NULL)
1844 return NT_STATUS_NO_MEMORY;
1846 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1847 return r_u->status;
1848 break;
1850 #if 0
1851 /* whoops - got this wrong. i think. or don't understand what's happening. */
1852 case 0x11:
1854 NTTIME expire;
1855 info = (void *)&id11;
1857 expire.low = 0xffffffff;
1858 expire.high = 0x7fffffff;
1860 ctr->info.id = (SAM_USER_INFO_11 *)talloc_zero(p->mem_ctx,
1861 sizeof
1862 (*ctr->
1863 info.
1864 id11));
1865 ZERO_STRUCTP(ctr->info.id11);
1866 init_sam_user_info11(ctr->info.id11, &expire,
1867 "BROOKFIELDS$", /* name */
1868 0x03ef, /* user rid */
1869 0x201, /* group rid */
1870 0x0080); /* acb info */
1872 break;
1874 #endif
1876 case 0x12:
1877 ctr->info.id12 = (SAM_USER_INFO_12 *)talloc_zero(p->mem_ctx, sizeof(SAM_USER_INFO_12));
1878 if (ctr->info.id12 == NULL)
1879 return NT_STATUS_NO_MEMORY;
1881 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1882 return r_u->status;
1883 break;
1885 case 20:
1886 ctr->info.id20 = (SAM_USER_INFO_20 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_20));
1887 if (ctr->info.id20 == NULL)
1888 return NT_STATUS_NO_MEMORY;
1889 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1890 return r_u->status;
1891 break;
1893 case 21:
1894 ctr->info.id21 = (SAM_USER_INFO_21 *)talloc_zero(p->mem_ctx,sizeof(SAM_USER_INFO_21));
1895 if (ctr->info.id21 == NULL)
1896 return NT_STATUS_NO_MEMORY;
1897 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1898 &info->sid, &domain_sid)))
1899 return r_u->status;
1900 break;
1902 default:
1903 return NT_STATUS_INVALID_INFO_CLASS;
1906 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1908 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1910 return r_u->status;
1913 /*******************************************************************
1914 samr_reply_query_usergroups
1915 ********************************************************************/
1917 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1919 SAM_ACCOUNT *sam_pass=NULL;
1920 DOM_SID sid;
1921 DOM_GID *gids = NULL;
1922 int num_groups = 0;
1923 uint32 acc_granted;
1924 BOOL ret;
1927 * from the SID in the request:
1928 * we should send back the list of DOMAIN GROUPS
1929 * the user is a member of
1931 * and only the DOMAIN GROUPS
1932 * no ALIASES !!! neither aliases of the domain
1933 * nor aliases of the builtin SID
1935 * JFM, 12/2/2001
1938 r_u->status = NT_STATUS_OK;
1940 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1942 /* find the policy handle. open a policy on it. */
1943 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1944 return NT_STATUS_INVALID_HANDLE;
1946 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1947 return r_u->status;
1950 if (!sid_check_is_in_our_domain(&sid))
1951 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1953 pdb_init_sam(&sam_pass);
1955 become_root();
1956 ret = pdb_getsampwsid(sam_pass, &sid);
1957 unbecome_root();
1959 if (ret == False) {
1960 pdb_free_sam(&sam_pass);
1961 return NT_STATUS_NO_SUCH_USER;
1964 if(!get_domain_user_groups(p->mem_ctx, &num_groups, &gids, sam_pass)) {
1965 pdb_free_sam(&sam_pass);
1966 return NT_STATUS_NO_SUCH_GROUP;
1969 /* construct the response. lkclXXXX: gids are not copied! */
1970 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
1972 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1974 pdb_free_sam(&sam_pass);
1976 return r_u->status;
1979 /*******************************************************************
1980 _samr_query_dom_info
1981 ********************************************************************/
1983 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
1985 struct samr_info *info = NULL;
1986 SAM_UNK_CTR *ctr;
1987 uint32 min_pass_len,pass_hist,flag;
1988 time_t u_expire, u_min_age;
1989 NTTIME nt_expire, nt_min_age;
1991 time_t u_lock_duration, u_reset_time;
1992 NTTIME nt_lock_duration, nt_reset_time;
1993 uint32 lockout;
1995 time_t u_logout;
1996 NTTIME nt_logout;
1998 uint32 account_policy_temp;
2000 uint32 num_users=0, num_groups=0, num_aliases=0;
2002 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
2003 return NT_STATUS_NO_MEMORY;
2005 ZERO_STRUCTP(ctr);
2007 r_u->status = NT_STATUS_OK;
2009 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2011 /* find the policy handle. open a policy on it. */
2012 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2013 return NT_STATUS_INVALID_HANDLE;
2015 switch (q_u->switch_value) {
2016 case 0x01:
2018 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2019 min_pass_len = account_policy_temp;
2021 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2022 pass_hist = account_policy_temp;
2024 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2025 flag = account_policy_temp;
2027 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2028 u_expire = account_policy_temp;
2030 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2031 u_min_age = account_policy_temp;
2033 unix_to_nt_time_abs(&nt_expire, u_expire);
2034 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2036 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2037 flag, nt_expire, nt_min_age);
2038 break;
2039 case 0x02:
2040 become_root();
2041 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2042 unbecome_root();
2043 if (!NT_STATUS_IS_OK(r_u->status)) {
2044 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2045 return r_u->status;
2047 num_users=info->disp_info.num_user_account;
2048 free_samr_db(info);
2050 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2051 if (!NT_STATUS_IS_OK(r_u->status)) {
2052 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2053 return r_u->status;
2055 num_groups=info->disp_info.num_group_account;
2056 free_samr_db(info);
2058 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2059 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
2060 num_users, num_groups, num_aliases);
2061 break;
2062 case 0x03:
2063 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2064 unix_to_nt_time_abs(&nt_logout, u_logout);
2066 init_unk_info3(&ctr->info.inf3, nt_logout);
2067 break;
2068 case 0x05:
2069 init_unk_info5(&ctr->info.inf5, global_myname());
2070 break;
2071 case 0x06:
2072 init_unk_info6(&ctr->info.inf6);
2073 break;
2074 case 0x07:
2075 init_unk_info7(&ctr->info.inf7);
2076 break;
2077 case 0x0c:
2078 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2079 u_lock_duration = account_policy_temp;
2081 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2082 u_reset_time = account_policy_temp;
2084 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2085 lockout = account_policy_temp;
2087 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2088 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2090 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2091 break;
2092 default:
2093 return NT_STATUS_INVALID_INFO_CLASS;
2096 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2098 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2100 return r_u->status;
2103 /*******************************************************************
2104 _samr_create_user
2105 Create an account, can be either a normal user or a machine.
2106 This funcion will need to be updated for bdc/domain trusts.
2107 ********************************************************************/
2109 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2111 SAM_ACCOUNT *sam_pass=NULL;
2112 fstring account;
2113 DOM_SID sid;
2114 pstring add_script;
2115 POLICY_HND dom_pol = q_u->domain_pol;
2116 UNISTR2 user_account = q_u->uni_name;
2117 uint16 acb_info = q_u->acb_info;
2118 POLICY_HND *user_pol = &r_u->user_pol;
2119 struct samr_info *info = NULL;
2120 BOOL ret;
2121 NTSTATUS nt_status;
2122 struct passwd *pw;
2123 uint32 acc_granted;
2124 SEC_DESC *psd;
2125 size_t sd_size;
2126 uint32 new_rid = 0;
2127 /* check this, when giving away 'add computer to domain' privs */
2128 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2130 /* Get the domain SID stored in the domain policy */
2131 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2132 return NT_STATUS_INVALID_HANDLE;
2134 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2135 return nt_status;
2138 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2139 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2140 this parameter is not an account type */
2141 return NT_STATUS_INVALID_PARAMETER;
2144 /* find the account: tell the caller if it exists.
2145 lkclXXXX i have *no* idea if this is a problem or not
2146 or even if you are supposed to construct a different
2147 reply if the account already exists...
2150 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2151 strlower_m(account);
2153 pdb_init_sam(&sam_pass);
2155 become_root();
2156 ret = pdb_getsampwnam(sam_pass, account);
2157 unbecome_root();
2158 if (ret == True) {
2159 /* this account exists: say so */
2160 pdb_free_sam(&sam_pass);
2161 return NT_STATUS_USER_EXISTS;
2164 pdb_free_sam(&sam_pass);
2167 * NB. VERY IMPORTANT ! This call must be done as the current pipe user,
2168 * *NOT* surrounded by a become_root()/unbecome_root() call. This ensures
2169 * that only people with write access to the smbpasswd file will be able
2170 * to create a user. JRA.
2174 * add the user in the /etc/passwd file or the unix authority system.
2175 * We don't check if the smb_create_user() function succed or not for 2 reasons:
2176 * a) local_password_change() checks for us if the /etc/passwd account really exists
2177 * b) smb_create_user() would return an error if the account already exists
2178 * and as it could return an error also if it can't create the account, it would be tricky.
2180 * So we go the easy way, only check after if the account exists.
2181 * JFM (2/3/2001), to clear any possible bad understanding (-:
2183 * We now have seperate script paramaters for adding users/machines so we
2184 * now have some sainity-checking to match.
2187 DEBUG(10,("checking account %s at pos %lu for $ termination\n",account, (unsigned long)strlen(account)-1));
2190 * we used to have code here that made sure the acb_info flags
2191 * matched with the users named (e.g. an account flags as a machine
2192 * trust account ended in '$'). It has been ifdef'd out for a long
2193 * time, so I replaced it with this comment. --jerry
2196 /* the passdb lookup has failed; check to see if we need to run the
2197 add user/machine script */
2199 pw = Get_Pwnam(account);
2201 /*********************************************************************
2202 * HEADS UP! If we have to create a new user account, we have to get
2203 * a new RID from somewhere. This used to be done by the passdb
2204 * backend. It has been moved into idmap now. Since idmap is now
2205 * wrapped up behind winbind, this means you have to run winbindd if you
2206 * want new accounts to get a new RID when "enable rid algorithm = no".
2207 * Tough. We now have a uniform way of allocating RIDs regardless
2208 * of what ever passdb backend people may use.
2209 * --jerry (2003-07-10)
2210 *********************************************************************/
2212 if ( !pw ) {
2214 * we can't check both the ending $ and the acb_info.
2216 * UserManager creates trust accounts (ending in $,
2217 * normal that hidden accounts) with the acb_info equals to ACB_NORMAL.
2218 * JFM, 11/29/2001
2220 if (account[strlen(account)-1] == '$')
2221 pstrcpy(add_script, lp_addmachine_script());
2222 else
2223 pstrcpy(add_script, lp_adduser_script());
2225 if (*add_script) {
2226 int add_ret;
2227 all_string_sub(add_script, "%u", account, sizeof(account));
2228 add_ret = smbrun(add_script,NULL);
2229 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2231 else /* no add user script -- ask winbindd to do it */
2233 if ( !winbind_create_user( account, &new_rid ) ) {
2234 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2235 account));
2241 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2243 if ( !NT_STATUS_IS_OK(nt_status = pdb_init_sam_new(&sam_pass, account, new_rid)) )
2244 return nt_status;
2246 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2248 if (!pdb_add_sam_account(sam_pass)) {
2249 pdb_free_sam(&sam_pass);
2250 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2251 account));
2252 return NT_STATUS_ACCESS_DENIED;
2255 /* Get the user's SID */
2256 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2258 samr_make_usr_obj_sd(p->mem_ctx, &psd, &sd_size, &sid);
2259 se_map_generic(&des_access, &usr_generic_mapping);
2260 if (!NT_STATUS_IS_OK(nt_status =
2261 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2262 des_access, &acc_granted, "_samr_create_user"))) {
2263 return nt_status;
2266 /* associate the user's SID with the new handle. */
2267 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2268 pdb_free_sam(&sam_pass);
2269 return NT_STATUS_NO_MEMORY;
2272 ZERO_STRUCTP(info);
2273 info->sid = sid;
2274 info->acc_granted = acc_granted;
2276 /* get a (unique) handle. open a policy on it. */
2277 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2278 pdb_free_sam(&sam_pass);
2279 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2282 r_u->user_rid=pdb_get_user_rid(sam_pass);
2284 r_u->access_granted = acc_granted;
2286 pdb_free_sam(&sam_pass);
2288 return NT_STATUS_OK;
2291 /*******************************************************************
2292 samr_reply_connect_anon
2293 ********************************************************************/
2295 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2297 struct samr_info *info = NULL;
2298 uint32 des_access = q_u->access_mask;
2300 /* Access check */
2302 if (!pipe_access_check(p)) {
2303 DEBUG(3, ("access denied to samr_connect_anon\n"));
2304 r_u->status = NT_STATUS_ACCESS_DENIED;
2305 return r_u->status;
2308 /* set up the SAMR connect_anon response */
2310 r_u->status = NT_STATUS_OK;
2312 /* associate the user's SID with the new handle. */
2313 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2314 return NT_STATUS_NO_MEMORY;
2316 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2317 was observed from a win98 client trying to enumerate users (when configured
2318 user level access control on shares) --jerry */
2320 se_map_generic( &des_access, &sam_generic_mapping );
2321 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2323 info->status = q_u->unknown_0;
2325 /* get a (unique) handle. open a policy on it. */
2326 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2327 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2329 return r_u->status;
2332 /*******************************************************************
2333 samr_reply_connect
2334 ********************************************************************/
2336 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2338 struct samr_info *info = NULL;
2339 SEC_DESC *psd = NULL;
2340 uint32 acc_granted;
2341 uint32 des_access = q_u->access_mask;
2342 size_t sd_size;
2343 NTSTATUS nt_status;
2346 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2348 /* Access check */
2350 if (!pipe_access_check(p)) {
2351 DEBUG(3, ("access denied to samr_connect\n"));
2352 r_u->status = NT_STATUS_ACCESS_DENIED;
2353 return r_u->status;
2356 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2357 se_map_generic(&des_access, &sam_generic_mapping);
2358 if (!NT_STATUS_IS_OK(nt_status =
2359 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2360 des_access, &acc_granted, "_samr_connect"))) {
2361 return nt_status;
2364 r_u->status = NT_STATUS_OK;
2366 /* associate the user's SID and access granted with the new handle. */
2367 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2368 return NT_STATUS_NO_MEMORY;
2370 info->acc_granted = acc_granted;
2371 info->status = q_u->access_mask;
2373 /* get a (unique) handle. open a policy on it. */
2374 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2375 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2377 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2379 return r_u->status;
2382 /*******************************************************************
2383 samr_connect4
2384 ********************************************************************/
2386 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2388 struct samr_info *info = NULL;
2389 SEC_DESC *psd = NULL;
2390 uint32 acc_granted;
2391 uint32 des_access = q_u->access_mask;
2392 size_t sd_size;
2393 NTSTATUS nt_status;
2396 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2398 /* Access check */
2400 if (!pipe_access_check(p)) {
2401 DEBUG(3, ("access denied to samr_connect4\n"));
2402 r_u->status = NT_STATUS_ACCESS_DENIED;
2403 return r_u->status;
2406 samr_make_sam_obj_sd(p->mem_ctx, &psd, &sd_size);
2407 se_map_generic(&des_access, &sam_generic_mapping);
2408 if (!NT_STATUS_IS_OK(nt_status =
2409 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2410 des_access, &acc_granted, "_samr_connect"))) {
2411 return nt_status;
2414 r_u->status = NT_STATUS_OK;
2416 /* associate the user's SID and access granted with the new handle. */
2417 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2418 return NT_STATUS_NO_MEMORY;
2420 info->acc_granted = acc_granted;
2421 info->status = q_u->access_mask;
2423 /* get a (unique) handle. open a policy on it. */
2424 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2425 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2427 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2429 return r_u->status;
2432 /**********************************************************************
2433 api_samr_lookup_domain
2434 **********************************************************************/
2436 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2438 struct samr_info *info;
2439 fstring domain_name;
2440 DOM_SID sid;
2442 r_u->status = NT_STATUS_OK;
2444 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2445 return NT_STATUS_INVALID_HANDLE;
2447 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2448 SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_lookup_domain")))
2450 return r_u->status;
2453 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2455 ZERO_STRUCT(sid);
2457 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2458 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2461 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2463 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2465 return r_u->status;
2468 /******************************************************************
2469 makes a SAMR_R_ENUM_DOMAINS structure.
2470 ********************************************************************/
2472 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2473 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2475 uint32 i;
2476 SAM_ENTRY *sam;
2477 UNISTR2 *uni_name;
2479 DEBUG(5, ("make_enum_domains\n"));
2481 *pp_sam = NULL;
2482 *pp_uni_name = NULL;
2484 if (num_sam_entries == 0)
2485 return True;
2487 sam = (SAM_ENTRY *)talloc_zero(ctx, sizeof(SAM_ENTRY)*num_sam_entries);
2488 uni_name = (UNISTR2 *)talloc_zero(ctx, sizeof(UNISTR2)*num_sam_entries);
2490 if (sam == NULL || uni_name == NULL)
2491 return False;
2493 for (i = 0; i < num_sam_entries; i++) {
2494 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2495 init_sam_entry(&sam[i], &uni_name[i], 0);
2498 *pp_sam = sam;
2499 *pp_uni_name = uni_name;
2501 return True;
2504 /**********************************************************************
2505 api_samr_enum_domains
2506 **********************************************************************/
2508 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2510 struct samr_info *info;
2511 uint32 num_entries = 2;
2512 fstring dom[2];
2513 const char *name;
2515 r_u->status = NT_STATUS_OK;
2517 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2518 return NT_STATUS_INVALID_HANDLE;
2520 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2521 return r_u->status;
2524 name = get_global_sam_name();
2526 fstrcpy(dom[0],name);
2527 strupper_m(dom[0]);
2528 fstrcpy(dom[1],"Builtin");
2530 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2531 return NT_STATUS_NO_MEMORY;
2533 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2535 return r_u->status;
2538 /*******************************************************************
2539 api_samr_open_alias
2540 ********************************************************************/
2542 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2544 DOM_SID sid;
2545 POLICY_HND domain_pol = q_u->dom_pol;
2546 uint32 alias_rid = q_u->rid_alias;
2547 POLICY_HND *alias_pol = &r_u->pol;
2548 struct samr_info *info = NULL;
2549 SEC_DESC *psd = NULL;
2550 uint32 acc_granted;
2551 uint32 des_access = q_u->access_mask;
2552 size_t sd_size;
2553 NTSTATUS status;
2555 r_u->status = NT_STATUS_OK;
2557 /* find the domain policy and get the SID / access bits stored in the domain policy */
2558 if (!get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted))
2559 return NT_STATUS_INVALID_HANDLE;
2561 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias"))) {
2562 return status;
2565 /* append the alias' RID to it */
2566 if (!sid_append_rid(&sid, alias_rid))
2567 return NT_STATUS_NO_SUCH_USER;
2569 /*check if access can be granted as requested by client. */
2570 samr_make_ali_obj_sd(p->mem_ctx, &psd, &sd_size);
2571 se_map_generic(&des_access,&ali_generic_mapping);
2572 if (!NT_STATUS_IS_OK(status =
2573 access_check_samr_object(psd, p->pipe_user.nt_user_token,
2574 des_access, &acc_granted, "_samr_open_alias"))) {
2575 return status;
2579 * we should check if the rid really exist !!!
2580 * JFM.
2583 /* associate the user's SID with the new handle. */
2584 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2585 return NT_STATUS_NO_MEMORY;
2587 info->acc_granted = acc_granted;
2589 /* get a (unique) handle. open a policy on it. */
2590 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2591 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2593 return r_u->status;
2596 /*******************************************************************
2597 set_user_info_10
2598 ********************************************************************/
2600 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, DOM_SID *sid)
2602 SAM_ACCOUNT *pwd =NULL;
2603 BOOL ret;
2605 pdb_init_sam(&pwd);
2607 ret = pdb_getsampwsid(pwd, sid);
2609 if(ret==False) {
2610 pdb_free_sam(&pwd);
2611 return False;
2614 if (id10 == NULL) {
2615 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2616 pdb_free_sam(&pwd);
2617 return False;
2620 /* FIX ME: check if the value is really changed --metze */
2621 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2622 pdb_free_sam(&pwd);
2623 return False;
2626 if(!pdb_update_sam_account(pwd)) {
2627 pdb_free_sam(&pwd);
2628 return False;
2631 pdb_free_sam(&pwd);
2633 return True;
2636 /*******************************************************************
2637 set_user_info_12
2638 ********************************************************************/
2640 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, DOM_SID *sid)
2642 SAM_ACCOUNT *pwd = NULL;
2644 pdb_init_sam(&pwd);
2646 if(!pdb_getsampwsid(pwd, sid)) {
2647 pdb_free_sam(&pwd);
2648 return False;
2651 if (id12 == NULL) {
2652 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2653 pdb_free_sam(&pwd);
2654 return False;
2657 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2658 pdb_free_sam(&pwd);
2659 return False;
2661 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2662 pdb_free_sam(&pwd);
2663 return False;
2665 if (!pdb_set_pass_changed_now (pwd)) {
2666 pdb_free_sam(&pwd);
2667 return False;
2670 if(!pdb_update_sam_account(pwd)) {
2671 pdb_free_sam(&pwd);
2672 return False;
2675 pdb_free_sam(&pwd);
2676 return True;
2679 /*******************************************************************
2680 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2681 ********************************************************************/
2682 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2684 struct group *grp;
2685 gid_t gid;
2687 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2688 &gid))) {
2689 DEBUG(2,("Could not get gid for primary group of "
2690 "user %s\n", pdb_get_username(sampass)));
2691 return False;
2694 grp = getgrgid(gid);
2696 if (grp == NULL) {
2697 DEBUG(2,("Could not find primary group %lu for "
2698 "user %s\n", (unsigned long)gid,
2699 pdb_get_username(sampass)));
2700 return False;
2703 if (smb_set_primary_group(grp->gr_name,
2704 pdb_get_username(sampass)) != 0) {
2705 DEBUG(2,("Could not set primary group for user %s to "
2706 "%s\n",
2707 pdb_get_username(sampass), grp->gr_name));
2708 return False;
2711 return True;
2715 /*******************************************************************
2716 set_user_info_20
2717 ********************************************************************/
2719 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, DOM_SID *sid)
2721 SAM_ACCOUNT *pwd = NULL;
2723 if (id20 == NULL) {
2724 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2725 return False;
2728 pdb_init_sam(&pwd);
2730 if (!pdb_getsampwsid(pwd, sid)) {
2731 pdb_free_sam(&pwd);
2732 return False;
2735 copy_id20_to_sam_passwd(pwd, id20);
2737 /* write the change out */
2738 if(!pdb_update_sam_account(pwd)) {
2739 pdb_free_sam(&pwd);
2740 return False;
2743 pdb_free_sam(&pwd);
2745 return True;
2747 /*******************************************************************
2748 set_user_info_21
2749 ********************************************************************/
2751 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, DOM_SID *sid)
2753 SAM_ACCOUNT *pwd = NULL;
2755 if (id21 == NULL) {
2756 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2757 return False;
2760 pdb_init_sam(&pwd);
2762 if (!pdb_getsampwsid(pwd, sid)) {
2763 pdb_free_sam(&pwd);
2764 return False;
2767 copy_id21_to_sam_passwd(pwd, id21);
2770 * The funny part about the previous two calls is
2771 * that pwd still has the password hashes from the
2772 * passdb entry. These have not been updated from
2773 * id21. I don't know if they need to be set. --jerry
2776 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2777 set_unix_primary_group(pwd);
2779 /* write the change out */
2780 if(!pdb_update_sam_account(pwd)) {
2781 pdb_free_sam(&pwd);
2782 return False;
2785 pdb_free_sam(&pwd);
2787 return True;
2790 /*******************************************************************
2791 set_user_info_23
2792 ********************************************************************/
2794 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, DOM_SID *sid)
2796 SAM_ACCOUNT *pwd = NULL;
2797 pstring plaintext_buf;
2798 uint32 len;
2799 uint16 acct_ctrl;
2801 if (id23 == NULL) {
2802 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2803 return False;
2806 pdb_init_sam(&pwd);
2808 if (!pdb_getsampwsid(pwd, sid)) {
2809 pdb_free_sam(&pwd);
2810 return False;
2813 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2814 pdb_get_username(pwd)));
2816 acct_ctrl = pdb_get_acct_ctrl(pwd);
2818 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2819 pdb_free_sam(&pwd);
2820 return False;
2823 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2824 pdb_free_sam(&pwd);
2825 return False;
2828 copy_id23_to_sam_passwd(pwd, id23);
2830 /* if it's a trust account, don't update /etc/passwd */
2831 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2832 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2833 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2834 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2835 } else {
2836 /* update the UNIX password */
2837 if (lp_unix_password_sync() ) {
2838 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2839 if (!passwd) {
2840 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2843 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2844 pdb_free_sam(&pwd);
2845 return False;
2850 ZERO_STRUCT(plaintext_buf);
2852 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2853 set_unix_primary_group(pwd);
2855 if(!pdb_update_sam_account(pwd)) {
2856 pdb_free_sam(&pwd);
2857 return False;
2860 pdb_free_sam(&pwd);
2862 return True;
2865 /*******************************************************************
2866 set_user_info_pw
2867 ********************************************************************/
2869 static BOOL set_user_info_pw(char *pass, DOM_SID *sid)
2871 SAM_ACCOUNT *pwd = NULL;
2872 uint32 len;
2873 pstring plaintext_buf;
2874 uint16 acct_ctrl;
2876 pdb_init_sam(&pwd);
2878 if (!pdb_getsampwsid(pwd, sid)) {
2879 pdb_free_sam(&pwd);
2880 return False;
2883 DEBUG(5, ("Attempting administrator password change for user %s\n",
2884 pdb_get_username(pwd)));
2886 acct_ctrl = pdb_get_acct_ctrl(pwd);
2888 ZERO_STRUCT(plaintext_buf);
2890 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2891 pdb_free_sam(&pwd);
2892 return False;
2895 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2896 pdb_free_sam(&pwd);
2897 return False;
2900 /* if it's a trust account, don't update /etc/passwd */
2901 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2902 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2903 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2904 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2905 } else {
2906 /* update the UNIX password */
2907 if (lp_unix_password_sync()) {
2908 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2909 if (!passwd) {
2910 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2913 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2914 pdb_free_sam(&pwd);
2915 return False;
2920 ZERO_STRUCT(plaintext_buf);
2922 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2924 /* update the SAMBA password */
2925 if(!pdb_update_sam_account(pwd)) {
2926 pdb_free_sam(&pwd);
2927 return False;
2930 pdb_free_sam(&pwd);
2932 return True;
2935 /*******************************************************************
2936 samr_reply_set_userinfo
2937 ********************************************************************/
2939 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2941 DOM_SID sid;
2942 POLICY_HND *pol = &q_u->pol;
2943 uint16 switch_value = q_u->switch_value;
2944 SAM_USERINFO_CTR *ctr = q_u->ctr;
2945 uint32 acc_granted;
2946 uint32 acc_required;
2948 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
2950 r_u->status = NT_STATUS_OK;
2952 /* find the policy handle. open a policy on it. */
2953 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
2954 return NT_STATUS_INVALID_HANDLE;
2956 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
2957 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
2958 return r_u->status;
2961 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
2963 if (ctr == NULL) {
2964 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
2965 return NT_STATUS_INVALID_INFO_CLASS;
2968 /* ok! user info levels (lots: see MSDEV help), off we go... */
2969 switch (switch_value) {
2970 case 0x12:
2971 if (!set_user_info_12(ctr->info.id12, &sid))
2972 return NT_STATUS_ACCESS_DENIED;
2973 break;
2975 case 24:
2976 if (!p->session_key.length) {
2977 return NT_STATUS_NO_USER_SESSION_KEY;
2979 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
2981 dump_data(100, (char *)ctr->info.id24->pass, 516);
2983 if (!set_user_info_pw((char *)ctr->info.id24->pass, &sid))
2984 return NT_STATUS_ACCESS_DENIED;
2985 break;
2987 case 25:
2988 #if 0
2990 * Currently we don't really know how to unmarshall
2991 * the level 25 struct, and the password encryption
2992 * is different. This is a placeholder for when we
2993 * do understand it. In the meantime just return INVALID
2994 * info level and W2K SP2 drops down to level 23... JRA.
2997 if (!p->session_key.length) {
2998 return NT_STATUS_NO_USER_SESSION_KEY;
3000 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3002 dump_data(100, (char *)ctr->info.id25->pass, 532);
3004 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3005 return NT_STATUS_ACCESS_DENIED;
3006 break;
3007 #endif
3008 return NT_STATUS_INVALID_INFO_CLASS;
3010 case 23:
3011 if (!p->session_key.length) {
3012 return NT_STATUS_NO_USER_SESSION_KEY;
3014 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3016 dump_data(100, (char *)ctr->info.id23->pass, 516);
3018 if (!set_user_info_23(ctr->info.id23, &sid))
3019 return NT_STATUS_ACCESS_DENIED;
3020 break;
3022 default:
3023 return NT_STATUS_INVALID_INFO_CLASS;
3026 return r_u->status;
3029 /*******************************************************************
3030 samr_reply_set_userinfo2
3031 ********************************************************************/
3033 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3035 DOM_SID sid;
3036 SAM_USERINFO_CTR *ctr = q_u->ctr;
3037 POLICY_HND *pol = &q_u->pol;
3038 uint16 switch_value = q_u->switch_value;
3039 uint32 acc_granted;
3040 uint32 acc_required;
3042 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3044 r_u->status = NT_STATUS_OK;
3046 /* find the policy handle. open a policy on it. */
3047 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3048 return NT_STATUS_INVALID_HANDLE;
3050 acc_required = SA_RIGHT_USER_SET_LOC_COM | SA_RIGHT_USER_SET_ATTRIBUTES; /* This is probably wrong */
3051 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3052 return r_u->status;
3055 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3057 if (ctr == NULL) {
3058 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3059 return NT_STATUS_INVALID_INFO_CLASS;
3062 switch_value=ctr->switch_value;
3064 /* ok! user info levels (lots: see MSDEV help), off we go... */
3065 switch (switch_value) {
3066 case 21:
3067 if (!set_user_info_21(ctr->info.id21, &sid))
3068 return NT_STATUS_ACCESS_DENIED;
3069 break;
3070 case 20:
3071 if (!set_user_info_20(ctr->info.id20, &sid))
3072 return NT_STATUS_ACCESS_DENIED;
3073 break;
3074 case 16:
3075 if (!set_user_info_10(ctr->info.id10, &sid))
3076 return NT_STATUS_ACCESS_DENIED;
3077 break;
3078 case 18:
3079 /* Used by AS/U JRA. */
3080 if (!set_user_info_12(ctr->info.id12, &sid))
3081 return NT_STATUS_ACCESS_DENIED;
3082 break;
3083 default:
3084 return NT_STATUS_INVALID_INFO_CLASS;
3087 return r_u->status;
3090 /*********************************************************************
3091 _samr_query_aliasmem
3092 *********************************************************************/
3094 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3096 int num_groups = 0, tmp_num_groups=0;
3097 uint32 *rids=NULL, *new_rids=NULL, *tmp_rids=NULL;
3098 struct samr_info *info = NULL;
3099 int i,j;
3101 NTSTATUS ntstatus1;
3102 NTSTATUS ntstatus2;
3104 /* until i see a real useraliases query, we fack one up */
3106 /* I have seen one, JFM 2/12/2001 */
3108 * Explanation of what this call does:
3109 * for all the SID given in the request:
3110 * return a list of alias (local groups)
3111 * that have those SID as members.
3113 * and that's the alias in the domain specified
3114 * in the policy_handle
3116 * if the policy handle is on an incorrect sid
3117 * for example a user's sid
3118 * we should reply NT_STATUS_OBJECT_TYPE_MISMATCH
3121 r_u->status = NT_STATUS_OK;
3123 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3125 /* find the policy handle. open a policy on it. */
3126 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3127 return NT_STATUS_INVALID_HANDLE;
3129 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3130 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3132 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3133 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3134 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3135 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3139 if (!sid_check_is_domain(&info->sid) &&
3140 !sid_check_is_builtin(&info->sid))
3141 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3144 for (i=0; i<q_u->num_sids1; i++) {
3146 r_u->status=get_alias_user_groups(p->mem_ctx, &info->sid, &tmp_num_groups, &tmp_rids, &(q_u->sid[i].sid));
3149 * if there is an error, we just continue as
3150 * it can be an unfound user or group
3152 if (!NT_STATUS_IS_OK(r_u->status)) {
3153 DEBUG(10,("_samr_query_useraliases: an error occured while getting groups\n"));
3154 continue;
3157 if (tmp_num_groups==0) {
3158 DEBUG(10,("_samr_query_useraliases: no groups found\n"));
3159 continue;
3162 new_rids=(uint32 *)talloc_realloc(p->mem_ctx, rids, (num_groups+tmp_num_groups)*sizeof(uint32));
3163 if (new_rids==NULL) {
3164 DEBUG(0,("_samr_query_useraliases: could not realloc memory\n"));
3165 return NT_STATUS_NO_MEMORY;
3167 rids=new_rids;
3169 for (j=0; j<tmp_num_groups; j++)
3170 rids[j+num_groups]=tmp_rids[j];
3172 safe_free(tmp_rids);
3174 num_groups+=tmp_num_groups;
3177 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3178 return NT_STATUS_OK;
3181 /*********************************************************************
3182 _samr_query_aliasmem
3183 *********************************************************************/
3185 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3187 int i;
3189 GROUP_MAP map;
3190 int num_sids = 0;
3191 DOM_SID2 *sid;
3192 DOM_SID *sids=NULL;
3194 DOM_SID alias_sid;
3195 DOM_SID als_sid;
3196 uint32 alias_rid;
3197 fstring alias_sid_str;
3199 uint32 acc_granted;
3201 /* find the policy handle. open a policy on it. */
3202 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3203 return NT_STATUS_INVALID_HANDLE;
3205 if (!NT_STATUS_IS_OK(r_u->status =
3206 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3207 return r_u->status;
3210 sid_copy(&als_sid, &alias_sid);
3211 sid_to_string(alias_sid_str, &alias_sid);
3212 sid_split_rid(&alias_sid, &alias_rid);
3214 DEBUG(10, ("sid is %s\n", alias_sid_str));
3216 if (sid_equal(&alias_sid, &global_sid_Builtin)) {
3217 DEBUG(10, ("lookup on Builtin SID (S-1-5-32)\n"));
3218 if(!get_builtin_group_from_sid(&als_sid, &map))
3219 return NT_STATUS_NO_SUCH_ALIAS;
3220 } else {
3221 if (sid_equal(&alias_sid, get_global_sam_sid())) {
3222 DEBUG(10, ("lookup on Server SID\n"));
3223 if(!get_local_group_from_sid(&als_sid, &map)) {
3224 fstring alias_sid_string;
3225 DEBUG(10, ("Alias %s not found\n", sid_to_string(alias_sid_string, &als_sid)));
3226 return NT_STATUS_NO_SUCH_ALIAS;
3231 if (!get_sid_list_of_group(map.gid, &sids, &num_sids)) {
3232 fstring alias_sid_string;
3233 DEBUG(10, ("Alias %s found, but member list unavailable\n", sid_to_string(alias_sid_string, &als_sid)));
3234 return NT_STATUS_NO_SUCH_ALIAS;
3237 DEBUG(10, ("sid is %s\n", alias_sid_str));
3238 sid = (DOM_SID2 *)talloc_zero(p->mem_ctx, sizeof(DOM_SID2) * num_sids);
3239 if (num_sids!=0 && sid == NULL) {
3240 SAFE_FREE(sids);
3241 return NT_STATUS_NO_MEMORY;
3244 for (i = 0; i < num_sids; i++) {
3245 init_dom_sid2(&sid[i], &sids[i]);
3248 DEBUG(10, ("sid is %s\n", alias_sid_str));
3249 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3251 SAFE_FREE(sids);
3253 return NT_STATUS_OK;
3256 /*********************************************************************
3257 _samr_query_groupmem
3258 *********************************************************************/
3260 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3262 int num_sids = 0;
3263 int final_num_sids = 0;
3264 int i;
3265 DOM_SID group_sid;
3266 uint32 group_rid;
3267 fstring group_sid_str;
3268 DOM_SID *sids=NULL;
3270 GROUP_MAP map;
3272 uint32 *rid=NULL;
3273 uint32 *attr=NULL;
3275 uint32 acc_granted;
3277 /* find the policy handle. open a policy on it. */
3278 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3279 return NT_STATUS_INVALID_HANDLE;
3281 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3282 return r_u->status;
3285 /* todo: change to use sid_compare_front */
3287 sid_split_rid(&group_sid, &group_rid);
3288 sid_to_string(group_sid_str, &group_sid);
3289 DEBUG(10, ("sid is %s\n", group_sid_str));
3291 /* can we get a query for an SID outside our domain ? */
3292 if (!sid_equal(&group_sid, get_global_sam_sid()))
3293 return NT_STATUS_NO_SUCH_GROUP;
3295 sid_append_rid(&group_sid, group_rid);
3296 DEBUG(10, ("lookup on Domain SID\n"));
3298 if(!get_domain_group_from_sid(group_sid, &map))
3299 return NT_STATUS_NO_SUCH_GROUP;
3301 if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
3302 return NT_STATUS_NO_SUCH_GROUP;
3304 rid=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids);
3305 attr=talloc_zero(p->mem_ctx, sizeof(uint32)*num_sids);
3307 if (num_sids!=0 && (rid==NULL || attr==NULL))
3308 return NT_STATUS_NO_MEMORY;
3310 for (i=0; i<num_sids; i++) {
3311 uint32 urid;
3313 if (sid_peek_check_rid(get_global_sam_sid(), &sids[i], &urid)) {
3314 rid[final_num_sids] = urid;
3315 attr[final_num_sids] = SID_NAME_USER;
3316 final_num_sids++;
3317 } else {
3318 fstring user_sid_str, domain_sid_str;
3319 DEBUG(1, ("_samr_query_groupmem: SID %s in group %s is not in our domain %s\n",
3320 sid_to_string(user_sid_str, &sids[i]),
3321 sid_to_string(group_sid_str, &group_sid),
3322 sid_to_string(domain_sid_str, get_global_sam_sid())));
3326 init_samr_r_query_groupmem(r_u, final_num_sids, rid, attr, NT_STATUS_OK);
3328 return NT_STATUS_OK;
3331 /*********************************************************************
3332 _samr_add_aliasmem
3333 *********************************************************************/
3335 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3337 DOM_SID alias_sid;
3338 fstring alias_sid_str;
3339 uid_t uid;
3340 struct passwd *pwd;
3341 struct group *grp;
3342 fstring grp_name;
3343 GROUP_MAP map;
3344 NTSTATUS ret;
3345 SAM_ACCOUNT *sam_user = NULL;
3346 BOOL check;
3347 uint32 acc_granted;
3349 /* Find the policy handle. Open a policy on it. */
3350 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3351 return NT_STATUS_INVALID_HANDLE;
3353 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3354 return r_u->status;
3357 sid_to_string(alias_sid_str, &alias_sid);
3358 DEBUG(10, ("sid is %s\n", alias_sid_str));
3360 if (sid_compare(&alias_sid, get_global_sam_sid())>0) {
3361 DEBUG(10, ("adding member on Server SID\n"));
3362 if(!get_local_group_from_sid(&alias_sid, &map))
3363 return NT_STATUS_NO_SUCH_ALIAS;
3365 } else {
3366 if (sid_compare(&alias_sid, &global_sid_Builtin)>0) {
3367 DEBUG(10, ("adding member on BUILTIN SID\n"));
3368 if( !get_builtin_group_from_sid(&alias_sid, &map))
3369 return NT_STATUS_NO_SUCH_ALIAS;
3371 } else
3372 return NT_STATUS_NO_SUCH_ALIAS;
3375 ret = pdb_init_sam(&sam_user);
3376 if (!NT_STATUS_IS_OK(ret))
3377 return ret;
3379 check = pdb_getsampwsid(sam_user, &q_u->sid.sid);
3381 if (check != True) {
3382 pdb_free_sam(&sam_user);
3383 return NT_STATUS_NO_SUCH_USER;
3386 /* check a real user exist before we run the script to add a user to a group */
3387 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3388 pdb_free_sam(&sam_user);
3389 return NT_STATUS_NO_SUCH_USER;
3392 pdb_free_sam(&sam_user);
3394 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3395 return NT_STATUS_NO_SUCH_USER;
3398 if ((grp=getgrgid(map.gid)) == NULL) {
3399 passwd_free(&pwd);
3400 return NT_STATUS_NO_SUCH_ALIAS;
3403 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3404 fstrcpy(grp_name, grp->gr_name);
3406 /* if the user is already in the group */
3407 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3408 passwd_free(&pwd);
3409 return NT_STATUS_MEMBER_IN_ALIAS;
3413 * ok, the group exist, the user exist, the user is not in the group,
3414 * we can (finally) add it to the group !
3416 smb_add_user_group(grp_name, pwd->pw_name);
3418 /* check if the user has been added then ... */
3419 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3420 passwd_free(&pwd);
3421 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3424 passwd_free(&pwd);
3425 return NT_STATUS_OK;
3428 /*********************************************************************
3429 _samr_del_aliasmem
3430 *********************************************************************/
3432 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3434 DOM_SID alias_sid;
3435 fstring alias_sid_str;
3436 struct group *grp;
3437 fstring grp_name;
3438 GROUP_MAP map;
3439 SAM_ACCOUNT *sam_pass=NULL;
3440 uint32 acc_granted;
3442 /* Find the policy handle. Open a policy on it. */
3443 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3444 return NT_STATUS_INVALID_HANDLE;
3446 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3447 return r_u->status;
3450 sid_to_string(alias_sid_str, &alias_sid);
3451 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n", alias_sid_str));
3453 if (!sid_check_is_in_our_domain(&alias_sid) &&
3454 !sid_check_is_in_builtin(&alias_sid)) {
3455 DEBUG(10, ("_samr_del_aliasmem:invalid alias group\n"));
3456 return NT_STATUS_NO_SUCH_ALIAS;
3459 if( !get_local_group_from_sid(&alias_sid, &map))
3460 return NT_STATUS_NO_SUCH_ALIAS;
3462 if ((grp=getgrgid(map.gid)) == NULL)
3463 return NT_STATUS_NO_SUCH_ALIAS;
3465 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3466 fstrcpy(grp_name, grp->gr_name);
3468 /* check if the user exists before trying to remove it from the group */
3469 pdb_init_sam(&sam_pass);
3470 if(!pdb_getsampwsid(sam_pass, &q_u->sid.sid)) {
3471 DEBUG(5,("_samr_del_aliasmem:User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3472 pdb_free_sam(&sam_pass);
3473 return NT_STATUS_NO_SUCH_USER;
3476 /* if the user is not in the group */
3477 if(!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3478 pdb_free_sam(&sam_pass);
3479 return NT_STATUS_MEMBER_IN_ALIAS;
3482 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3484 /* check if the user has been removed then ... */
3485 if(user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3486 pdb_free_sam(&sam_pass);
3487 return NT_STATUS_MEMBER_NOT_IN_ALIAS; /* don't know what to reply else */
3490 pdb_free_sam(&sam_pass);
3491 return NT_STATUS_OK;
3494 /*********************************************************************
3495 _samr_add_groupmem
3496 *********************************************************************/
3498 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3500 DOM_SID group_sid;
3501 DOM_SID user_sid;
3502 fstring group_sid_str;
3503 uid_t uid;
3504 struct passwd *pwd;
3505 struct group *grp;
3506 fstring grp_name;
3507 GROUP_MAP map;
3508 NTSTATUS ret;
3509 SAM_ACCOUNT *sam_user=NULL;
3510 BOOL check;
3511 uint32 acc_granted;
3513 /* Find the policy handle. Open a policy on it. */
3514 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3515 return NT_STATUS_INVALID_HANDLE;
3517 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3518 return r_u->status;
3521 sid_to_string(group_sid_str, &group_sid);
3522 DEBUG(10, ("sid is %s\n", group_sid_str));
3524 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3525 return NT_STATUS_NO_SUCH_GROUP;
3527 DEBUG(10, ("lookup on Domain SID\n"));
3529 if(!get_domain_group_from_sid(group_sid, &map))
3530 return NT_STATUS_NO_SUCH_GROUP;
3532 sid_copy(&user_sid, get_global_sam_sid());
3533 sid_append_rid(&user_sid, q_u->rid);
3535 ret = pdb_init_sam(&sam_user);
3536 if (!NT_STATUS_IS_OK(ret))
3537 return ret;
3539 check = pdb_getsampwsid(sam_user, &user_sid);
3541 if (check != True) {
3542 pdb_free_sam(&sam_user);
3543 return NT_STATUS_NO_SUCH_USER;
3546 /* check a real user exist before we run the script to add a user to a group */
3547 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3548 pdb_free_sam(&sam_user);
3549 return NT_STATUS_NO_SUCH_USER;
3552 pdb_free_sam(&sam_user);
3554 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3555 return NT_STATUS_NO_SUCH_USER;
3558 if ((grp=getgrgid(map.gid)) == NULL) {
3559 passwd_free(&pwd);
3560 return NT_STATUS_NO_SUCH_GROUP;
3563 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3564 fstrcpy(grp_name, grp->gr_name);
3566 /* if the user is already in the group */
3567 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3568 passwd_free(&pwd);
3569 return NT_STATUS_MEMBER_IN_GROUP;
3573 * ok, the group exist, the user exist, the user is not in the group,
3575 * we can (finally) add it to the group !
3578 smb_add_user_group(grp_name, pwd->pw_name);
3580 /* check if the user has been added then ... */
3581 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3582 passwd_free(&pwd);
3583 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3586 passwd_free(&pwd);
3587 return NT_STATUS_OK;
3590 /*********************************************************************
3591 _samr_del_groupmem
3592 *********************************************************************/
3594 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3596 DOM_SID group_sid;
3597 DOM_SID user_sid;
3598 SAM_ACCOUNT *sam_pass=NULL;
3599 GROUP_MAP map;
3600 fstring grp_name;
3601 struct group *grp;
3602 uint32 acc_granted;
3605 * delete the group member named q_u->rid
3606 * who is a member of the sid associated with the handle
3607 * the rid is a user's rid as the group is a domain group.
3610 /* Find the policy handle. Open a policy on it. */
3611 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3612 return NT_STATUS_INVALID_HANDLE;
3614 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3615 return r_u->status;
3618 if (!sid_check_is_in_our_domain(&group_sid))
3619 return NT_STATUS_NO_SUCH_GROUP;
3621 sid_copy(&user_sid, get_global_sam_sid());
3622 sid_append_rid(&user_sid, q_u->rid);
3624 if (!get_domain_group_from_sid(group_sid, &map))
3625 return NT_STATUS_NO_SUCH_GROUP;
3627 if ((grp=getgrgid(map.gid)) == NULL)
3628 return NT_STATUS_NO_SUCH_GROUP;
3630 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3631 fstrcpy(grp_name, grp->gr_name);
3633 /* check if the user exists before trying to remove it from the group */
3634 pdb_init_sam(&sam_pass);
3635 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3636 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3637 pdb_free_sam(&sam_pass);
3638 return NT_STATUS_NO_SUCH_USER;
3641 /* if the user is not in the group */
3642 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3643 pdb_free_sam(&sam_pass);
3644 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3647 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3649 /* check if the user has been removed then ... */
3650 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3651 pdb_free_sam(&sam_pass);
3652 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3655 pdb_free_sam(&sam_pass);
3656 return NT_STATUS_OK;
3660 /****************************************************************************
3661 Delete a UNIX user on demand.
3662 ****************************************************************************/
3664 static int smb_delete_user(const char *unix_user)
3666 pstring del_script;
3667 int ret;
3669 /* try winbindd first since it is impossible to determine where
3670 a user came from via NSS. Try the delete user script if this fails
3671 meaning the user did not exist in winbindd's list of accounts */
3673 if ( winbind_delete_user( unix_user ) ) {
3674 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3675 return 0;
3679 /* fall back to 'delete user script' */
3681 pstrcpy(del_script, lp_deluser_script());
3682 if (! *del_script)
3683 return -1;
3684 all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
3685 ret = smbrun(del_script,NULL);
3686 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3688 return ret;
3691 /*********************************************************************
3692 _samr_delete_dom_user
3693 *********************************************************************/
3695 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3697 DOM_SID user_sid;
3698 SAM_ACCOUNT *sam_pass=NULL;
3699 uint32 acc_granted;
3701 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3703 /* Find the policy handle. Open a policy on it. */
3704 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3705 return NT_STATUS_INVALID_HANDLE;
3707 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3708 return r_u->status;
3711 if (!sid_check_is_in_our_domain(&user_sid))
3712 return NT_STATUS_CANNOT_DELETE;
3714 /* check if the user exists before trying to delete */
3715 pdb_init_sam(&sam_pass);
3716 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3717 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3718 sid_string_static(&user_sid)));
3719 pdb_free_sam(&sam_pass);
3720 return NT_STATUS_NO_SUCH_USER;
3723 /* delete the unix side */
3725 * note: we don't check if the delete really happened
3726 * as the script is not necessary present
3727 * and maybe the sysadmin doesn't want to delete the unix side
3729 smb_delete_user(pdb_get_username(sam_pass));
3731 /* and delete the samba side */
3732 if (!pdb_delete_sam_account(sam_pass)) {
3733 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3734 pdb_free_sam(&sam_pass);
3735 return NT_STATUS_CANNOT_DELETE;
3738 pdb_free_sam(&sam_pass);
3740 if (!close_policy_hnd(p, &q_u->user_pol))
3741 return NT_STATUS_OBJECT_NAME_INVALID;
3743 return NT_STATUS_OK;
3746 /*********************************************************************
3747 _samr_delete_dom_group
3748 *********************************************************************/
3750 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3752 DOM_SID group_sid;
3753 DOM_SID dom_sid;
3754 uint32 group_rid;
3755 fstring group_sid_str;
3756 gid_t gid;
3757 struct group *grp;
3758 GROUP_MAP map;
3759 uint32 acc_granted;
3761 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3763 /* Find the policy handle. Open a policy on it. */
3764 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3765 return NT_STATUS_INVALID_HANDLE;
3767 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3768 return r_u->status;
3771 sid_copy(&dom_sid, &group_sid);
3772 sid_to_string(group_sid_str, &dom_sid);
3773 sid_split_rid(&dom_sid, &group_rid);
3775 DEBUG(10, ("sid is %s\n", group_sid_str));
3777 /* we check if it's our SID before deleting */
3778 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3779 return NT_STATUS_NO_SUCH_GROUP;
3781 DEBUG(10, ("lookup on Domain SID\n"));
3783 if(!get_domain_group_from_sid(group_sid, &map))
3784 return NT_STATUS_NO_SUCH_GROUP;
3786 gid=map.gid;
3788 /* check if group really exists */
3789 if ( (grp=getgrgid(gid)) == NULL)
3790 return NT_STATUS_NO_SUCH_GROUP;
3792 /* delete mapping first */
3793 if(!pdb_delete_group_mapping_entry(group_sid))
3794 return NT_STATUS_ACCESS_DENIED;
3796 /* we can delete the UNIX group */
3797 smb_delete_group(grp->gr_name);
3799 /* check if the group has been successfully deleted */
3800 if ( (grp=getgrgid(gid)) != NULL)
3801 return NT_STATUS_ACCESS_DENIED;
3804 if (!close_policy_hnd(p, &q_u->group_pol))
3805 return NT_STATUS_OBJECT_NAME_INVALID;
3807 return NT_STATUS_OK;
3810 /*********************************************************************
3811 _samr_delete_dom_alias
3812 *********************************************************************/
3814 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3816 DOM_SID alias_sid;
3817 DOM_SID dom_sid;
3818 uint32 alias_rid;
3819 fstring alias_sid_str;
3820 gid_t gid;
3821 struct group *grp;
3822 GROUP_MAP map;
3823 uint32 acc_granted;
3825 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3827 /* Find the policy handle. Open a policy on it. */
3828 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3829 return NT_STATUS_INVALID_HANDLE;
3831 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3832 return r_u->status;
3835 sid_copy(&dom_sid, &alias_sid);
3836 sid_to_string(alias_sid_str, &dom_sid);
3837 sid_split_rid(&dom_sid, &alias_rid);
3839 DEBUG(10, ("sid is %s\n", alias_sid_str));
3841 /* we check if it's our SID before deleting */
3842 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3843 return NT_STATUS_NO_SUCH_ALIAS;
3845 DEBUG(10, ("lookup on Local SID\n"));
3847 if(!get_local_group_from_sid(&alias_sid, &map))
3848 return NT_STATUS_NO_SUCH_ALIAS;
3850 gid=map.gid;
3852 /* check if group really exists */
3853 if ( (grp=getgrgid(gid)) == NULL)
3854 return NT_STATUS_NO_SUCH_ALIAS;
3856 /* we can delete the UNIX group */
3857 smb_delete_group(grp->gr_name);
3859 /* check if the group has been successfully deleted */
3860 if ( (grp=getgrgid(gid)) != NULL)
3861 return NT_STATUS_ACCESS_DENIED;
3863 /* don't check if we removed it as it could be an un-mapped group */
3864 pdb_delete_group_mapping_entry(alias_sid);
3866 if (!close_policy_hnd(p, &q_u->alias_pol))
3867 return NT_STATUS_OBJECT_NAME_INVALID;
3869 return NT_STATUS_OK;
3872 /*********************************************************************
3873 _samr_create_dom_group
3874 *********************************************************************/
3876 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3878 DOM_SID dom_sid;
3879 DOM_SID info_sid;
3880 fstring name;
3881 fstring sid_string;
3882 struct group *grp;
3883 struct samr_info *info;
3884 uint32 acc_granted;
3885 gid_t gid;
3887 /* Find the policy handle. Open a policy on it. */
3888 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
3889 return NT_STATUS_INVALID_HANDLE;
3891 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
3892 return r_u->status;
3895 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3896 return NT_STATUS_ACCESS_DENIED;
3898 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3900 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3902 /* check if group already exist */
3903 if ((grp=getgrnam(name)) != NULL)
3904 return NT_STATUS_GROUP_EXISTS;
3906 /* we can create the UNIX group */
3907 if (smb_create_group(name, &gid) != 0)
3908 return NT_STATUS_ACCESS_DENIED;
3910 /* check if the group has been successfully created */
3911 if ((grp=getgrgid(gid)) == NULL)
3912 return NT_STATUS_ACCESS_DENIED;
3914 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3916 /* add the group to the mapping table */
3917 sid_copy(&info_sid, get_global_sam_sid());
3918 sid_append_rid(&info_sid, r_u->rid);
3919 sid_to_string(sid_string, &info_sid);
3921 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL))
3922 return NT_STATUS_ACCESS_DENIED;
3924 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3925 return NT_STATUS_NO_MEMORY;
3927 /* get a (unique) handle. open a policy on it. */
3928 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
3929 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3931 return NT_STATUS_OK;
3934 /*********************************************************************
3935 _samr_create_dom_alias
3936 *********************************************************************/
3938 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
3940 DOM_SID dom_sid;
3941 DOM_SID info_sid;
3942 fstring name;
3943 fstring sid_string;
3944 struct group *grp;
3945 struct samr_info *info;
3946 uint32 acc_granted;
3947 gid_t gid;
3949 /* Find the policy handle. Open a policy on it. */
3950 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
3951 return NT_STATUS_INVALID_HANDLE;
3953 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
3954 return r_u->status;
3957 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3958 return NT_STATUS_ACCESS_DENIED;
3960 /* TODO: check if allowed to create group and add a become_root/unbecome_root pair.*/
3962 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
3964 /* check if group already exists */
3965 if ( (grp=getgrnam(name)) != NULL)
3966 return NT_STATUS_GROUP_EXISTS;
3968 /* we can create the UNIX group */
3969 if (smb_create_group(name, &gid) != 0)
3970 return NT_STATUS_ACCESS_DENIED;
3972 /* check if the group has been successfully created */
3973 if ((grp=getgrgid(gid)) == NULL)
3974 return NT_STATUS_ACCESS_DENIED;
3976 r_u->rid=pdb_gid_to_group_rid(grp->gr_gid);
3978 sid_copy(&info_sid, get_global_sam_sid());
3979 sid_append_rid(&info_sid, r_u->rid);
3980 sid_to_string(sid_string, &info_sid);
3982 /* add the group to the mapping table */
3983 if(!add_initial_entry(grp->gr_gid, sid_string, SID_NAME_ALIAS, name, NULL))
3984 return NT_STATUS_ACCESS_DENIED;
3986 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
3987 return NT_STATUS_NO_MEMORY;
3989 /* get a (unique) handle. open a policy on it. */
3990 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
3991 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3993 return NT_STATUS_OK;
3996 /*********************************************************************
3997 _samr_query_groupinfo
3999 sends the name/comment pair of a domain group
4000 level 1 send also the number of users of that group
4001 *********************************************************************/
4003 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4005 DOM_SID group_sid;
4006 GROUP_MAP map;
4007 DOM_SID *sids=NULL;
4008 int num_sids=0;
4009 GROUP_INFO_CTR *ctr;
4010 uint32 acc_granted;
4011 BOOL ret;
4013 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4014 return NT_STATUS_INVALID_HANDLE;
4016 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4017 return r_u->status;
4020 become_root();
4021 ret = get_domain_group_from_sid(group_sid, &map);
4022 unbecome_root();
4023 if (!ret)
4024 return NT_STATUS_INVALID_HANDLE;
4026 ctr=(GROUP_INFO_CTR *)talloc_zero(p->mem_ctx, sizeof(GROUP_INFO_CTR));
4027 if (ctr==NULL)
4028 return NT_STATUS_NO_MEMORY;
4030 switch (q_u->switch_level) {
4031 case 1:
4032 ctr->switch_value1 = 1;
4033 if(!get_sid_list_of_group(map.gid, &sids, &num_sids))
4034 return NT_STATUS_NO_SUCH_GROUP;
4035 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num_sids);
4036 SAFE_FREE(sids);
4037 break;
4038 case 3:
4039 ctr->switch_value1 = 3;
4040 init_samr_group_info3(&ctr->group.info3);
4041 break;
4042 case 4:
4043 ctr->switch_value1 = 4;
4044 init_samr_group_info4(&ctr->group.info4, map.comment);
4045 break;
4046 default:
4047 return NT_STATUS_INVALID_INFO_CLASS;
4050 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4052 return NT_STATUS_OK;
4055 /*********************************************************************
4056 _samr_set_groupinfo
4058 update a domain group's comment.
4059 *********************************************************************/
4061 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4063 DOM_SID group_sid;
4064 GROUP_MAP map;
4065 GROUP_INFO_CTR *ctr;
4066 uint32 acc_granted;
4068 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4069 return NT_STATUS_INVALID_HANDLE;
4071 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4072 return r_u->status;
4075 if (!get_domain_group_from_sid(group_sid, &map))
4076 return NT_STATUS_NO_SUCH_GROUP;
4078 ctr=q_u->ctr;
4080 switch (ctr->switch_value1) {
4081 case 1:
4082 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4083 break;
4084 case 4:
4085 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4086 break;
4087 default:
4088 return NT_STATUS_INVALID_INFO_CLASS;
4091 if(!pdb_update_group_mapping_entry(&map)) {
4092 return NT_STATUS_NO_SUCH_GROUP;
4095 return NT_STATUS_OK;
4098 /*********************************************************************
4099 _samr_set_aliasinfo
4101 update an alias's comment.
4102 *********************************************************************/
4104 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4106 DOM_SID group_sid;
4107 GROUP_MAP map;
4108 ALIAS_INFO_CTR *ctr;
4109 uint32 acc_granted;
4111 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4112 return NT_STATUS_INVALID_HANDLE;
4114 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4115 return r_u->status;
4118 if (!get_local_group_from_sid(&group_sid, &map))
4119 return NT_STATUS_NO_SUCH_GROUP;
4121 ctr=&q_u->ctr;
4123 switch (ctr->switch_value1) {
4124 case 3:
4125 unistr2_to_ascii(map.comment, &(ctr->alias.info3.uni_acct_desc), sizeof(map.comment)-1);
4126 break;
4127 default:
4128 return NT_STATUS_INVALID_INFO_CLASS;
4131 if(!pdb_update_group_mapping_entry(&map)) {
4132 return NT_STATUS_NO_SUCH_GROUP;
4135 return NT_STATUS_OK;
4138 /*********************************************************************
4139 _samr_get_dom_pwinfo
4140 *********************************************************************/
4142 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4144 /* Perform access check. Since this rpc does not require a
4145 policy handle it will not be caught by the access checks on
4146 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4148 if (!pipe_access_check(p)) {
4149 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4150 r_u->status = NT_STATUS_ACCESS_DENIED;
4151 return r_u->status;
4154 /* Actually, returning zeros here works quite well :-). */
4156 return NT_STATUS_OK;
4159 /*********************************************************************
4160 _samr_open_group
4161 *********************************************************************/
4163 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4165 DOM_SID sid;
4166 DOM_SID info_sid;
4167 GROUP_MAP map;
4168 struct samr_info *info;
4169 SEC_DESC *psd = NULL;
4170 uint32 acc_granted;
4171 uint32 des_access = q_u->access_mask;
4172 size_t sd_size;
4173 NTSTATUS status;
4174 fstring sid_string;
4175 BOOL ret;
4177 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4178 return NT_STATUS_INVALID_HANDLE;
4180 if (!NT_STATUS_IS_OK(status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group"))) {
4181 return status;
4184 /*check if access can be granted as requested by client. */
4185 samr_make_grp_obj_sd(p->mem_ctx, &psd, &sd_size);
4186 se_map_generic(&des_access,&grp_generic_mapping);
4187 if (!NT_STATUS_IS_OK(status =
4188 access_check_samr_object(psd, p->pipe_user.nt_user_token,
4189 des_access, &acc_granted, "_samr_open_group"))) {
4190 return status;
4194 /* this should not be hard-coded like this */
4195 if (!sid_equal(&sid, get_global_sam_sid()))
4196 return NT_STATUS_ACCESS_DENIED;
4198 sid_copy(&info_sid, get_global_sam_sid());
4199 sid_append_rid(&info_sid, q_u->rid_group);
4200 sid_to_string(sid_string, &info_sid);
4202 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4203 return NT_STATUS_NO_MEMORY;
4205 info->acc_granted = acc_granted;
4207 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4209 /* check if that group really exists */
4210 become_root();
4211 ret = get_domain_group_from_sid(info->sid, &map);
4212 unbecome_root();
4213 if (!ret)
4214 return NT_STATUS_NO_SUCH_GROUP;
4216 /* get a (unique) handle. open a policy on it. */
4217 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4218 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4220 return NT_STATUS_OK;
4223 /*********************************************************************
4224 _samr_remove_sid_foreign_domain
4225 *********************************************************************/
4227 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4228 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4229 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4231 DOM_SID delete_sid, alias_sid;
4232 SAM_ACCOUNT *sam_pass=NULL;
4233 uint32 acc_granted;
4234 GROUP_MAP map;
4235 BOOL is_user = False;
4236 NTSTATUS result;
4237 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4239 sid_copy( &delete_sid, &q_u->sid.sid );
4241 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4242 sid_string_static(&delete_sid)));
4244 /* Find the policy handle. Open a policy on it. */
4246 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4247 return NT_STATUS_INVALID_HANDLE;
4249 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4250 "_samr_remove_sid_foreign_domain");
4252 if (!NT_STATUS_IS_OK(result))
4253 return result;
4255 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4256 sid_string_static(&alias_sid)));
4258 /* make sure we can handle this */
4260 if ( sid_check_is_domain(&alias_sid) )
4261 type = SID_NAME_DOM_GRP;
4262 else if ( sid_check_is_builtin(&alias_sid) )
4263 type = SID_NAME_ALIAS;
4265 if ( type == SID_NAME_UNKNOWN ) {
4266 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4267 return NT_STATUS_OK;
4270 /* check if the user exists before trying to delete */
4272 pdb_init_sam(&sam_pass);
4274 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4275 is_user = True;
4276 } else {
4277 /* maybe it is a group */
4278 if( !pdb_getgrsid(&map, delete_sid) ) {
4279 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4280 sid_string_static(&delete_sid)));
4281 result = NT_STATUS_INVALID_SID;
4282 goto done;
4286 /* we can only delete a user from a group since we don't have
4287 nested groups anyways. So in the latter case, just say OK */
4289 if ( is_user ) {
4290 GROUP_MAP *mappings = NULL;
4291 int num_groups, i;
4292 struct group *grp2;
4294 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4296 /* interate over the groups */
4297 for ( i=0; i<num_groups; i++ ) {
4299 grp2 = getgrgid(mappings[i].gid);
4301 if ( !grp2 ) {
4302 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4303 continue;
4306 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4307 continue;
4309 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4311 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4312 /* should we fail here ? */
4313 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4314 pdb_get_username(sam_pass), grp2->gr_name ));
4315 continue;
4318 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4319 pdb_get_username(sam_pass), grp2->gr_name ));
4322 SAFE_FREE(mappings);
4326 result = NT_STATUS_OK;
4327 done:
4329 pdb_free_sam(&sam_pass);
4331 return result;
4334 /*******************************************************************
4335 _samr_unknown_2e
4336 ********************************************************************/
4338 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4340 struct samr_info *info = NULL;
4341 SAM_UNK_CTR *ctr;
4342 uint32 min_pass_len,pass_hist,flag;
4343 time_t u_expire, u_min_age;
4344 NTTIME nt_expire, nt_min_age;
4346 time_t u_lock_duration, u_reset_time;
4347 NTTIME nt_lock_duration, nt_reset_time;
4348 uint32 lockout;
4350 time_t u_logout;
4351 NTTIME nt_logout;
4353 uint32 num_users=0, num_groups=0, num_aliases=0;
4355 uint32 account_policy_temp;
4357 if ((ctr = (SAM_UNK_CTR *)talloc_zero(p->mem_ctx, sizeof(SAM_UNK_CTR))) == NULL)
4358 return NT_STATUS_NO_MEMORY;
4360 ZERO_STRUCTP(ctr);
4362 r_u->status = NT_STATUS_OK;
4364 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4366 /* find the policy handle. open a policy on it. */
4367 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4368 return NT_STATUS_INVALID_HANDLE;
4370 switch (q_u->switch_value) {
4371 case 0x01:
4372 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4373 min_pass_len = account_policy_temp;
4375 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4376 pass_hist = account_policy_temp;
4378 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4379 flag = account_policy_temp;
4381 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4382 u_expire = account_policy_temp;
4384 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4385 u_min_age = account_policy_temp;
4387 unix_to_nt_time_abs(&nt_expire, u_expire);
4388 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4390 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4391 flag, nt_expire, nt_min_age);
4392 break;
4393 case 0x02:
4394 become_root();
4395 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4396 unbecome_root();
4397 if (!NT_STATUS_IS_OK(r_u->status)) {
4398 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4399 return r_u->status;
4401 num_users=info->disp_info.num_user_account;
4402 free_samr_db(info);
4404 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4405 if (NT_STATUS_IS_ERR(r_u->status)) {
4406 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4407 return r_u->status;
4409 num_groups=info->disp_info.num_group_account;
4410 free_samr_db(info);
4412 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4413 init_unk_info2(&ctr->info.inf2, lp_workgroup(), global_myname(), (uint32) time(NULL),
4414 num_users, num_groups, num_aliases);
4415 break;
4416 case 0x03:
4417 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4418 u_logout = account_policy_temp;
4420 unix_to_nt_time_abs(&nt_logout, u_logout);
4422 init_unk_info3(&ctr->info.inf3, nt_logout);
4423 break;
4424 case 0x05:
4425 init_unk_info5(&ctr->info.inf5, global_myname());
4426 break;
4427 case 0x06:
4428 init_unk_info6(&ctr->info.inf6);
4429 break;
4430 case 0x07:
4431 init_unk_info7(&ctr->info.inf7);
4432 break;
4433 case 0x0c:
4434 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4435 u_lock_duration = account_policy_temp;
4437 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4438 u_reset_time = account_policy_temp;
4440 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4441 lockout = account_policy_temp;
4443 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4444 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4446 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4447 break;
4448 default:
4449 return NT_STATUS_INVALID_INFO_CLASS;
4452 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4454 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4456 return r_u->status;
4459 /*******************************************************************
4460 _samr_
4461 ********************************************************************/
4463 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4465 time_t u_expire, u_min_age;
4466 time_t u_logout;
4467 time_t u_lock_duration, u_reset_time;
4469 r_u->status = NT_STATUS_OK;
4471 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4473 /* find the policy handle. open a policy on it. */
4474 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4475 return NT_STATUS_INVALID_HANDLE;
4477 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4479 switch (q_u->switch_value) {
4480 case 0x01:
4481 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4482 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4484 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4485 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4486 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4487 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4488 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4489 break;
4490 case 0x02:
4491 break;
4492 case 0x03:
4493 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4494 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4495 break;
4496 case 0x05:
4497 break;
4498 case 0x06:
4499 break;
4500 case 0x07:
4501 break;
4502 case 0x0c:
4503 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4504 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count);
4506 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4507 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4508 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4509 break;
4510 default:
4511 return NT_STATUS_INVALID_INFO_CLASS;
4514 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4516 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4518 return r_u->status;