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-2004,
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.
35 #define DBGC_CLASS DBGC_RPC_SRV
37 #define SAMR_USR_RIGHTS_WRITE_PW \
38 ( READ_CONTROL_ACCESS | \
39 SA_RIGHT_USER_CHANGE_PASSWORD | \
40 SA_RIGHT_USER_SET_LOC_COM )
42 extern DOM_SID global_sid_Builtin;
44 extern rid_name domain_group_rids[];
45 extern rid_name domain_alias_rids[];
46 extern rid_name builtin_alias_rids[];
49 typedef struct _disp_info {
51 uint32 num_user_account;
52 SAM_ACCOUNT *disp_user_info;
54 uint32 num_group_account;
55 DOMAIN_GRP *disp_group_info;
59 /* for use by the \PIPE\samr policy */
61 uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
70 struct generic_mapping sam_generic_mapping = {GENERIC_RIGHTS_SAM_READ, GENERIC_RIGHTS_SAM_WRITE, GENERIC_RIGHTS_SAM_EXECUTE, GENERIC_RIGHTS_SAM_ALL_ACCESS};
71 struct generic_mapping dom_generic_mapping = {GENERIC_RIGHTS_DOMAIN_READ, GENERIC_RIGHTS_DOMAIN_WRITE, GENERIC_RIGHTS_DOMAIN_EXECUTE, GENERIC_RIGHTS_DOMAIN_ALL_ACCESS};
72 struct generic_mapping usr_generic_mapping = {GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, GENERIC_RIGHTS_USER_EXECUTE, GENERIC_RIGHTS_USER_ALL_ACCESS};
73 struct generic_mapping grp_generic_mapping = {GENERIC_RIGHTS_GROUP_READ, GENERIC_RIGHTS_GROUP_WRITE, GENERIC_RIGHTS_GROUP_EXECUTE, GENERIC_RIGHTS_GROUP_ALL_ACCESS};
74 struct generic_mapping ali_generic_mapping = {GENERIC_RIGHTS_ALIAS_READ, GENERIC_RIGHTS_ALIAS_WRITE, GENERIC_RIGHTS_ALIAS_EXECUTE, GENERIC_RIGHTS_ALIAS_ALL_ACCESS};
76 /*******************************************************************
77 *******************************************************************/
79 static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size,
80 struct generic_mapping *map,
81 DOM_SID *sid, uint32 sid_access )
83 extern DOM_SID global_sid_World;
84 DOM_SID adm_sid, act_sid, domadmin_sid;
85 SEC_ACE ace[5]; /* at most 5 entries */
91 /* basic access for Everyone */
93 init_sec_access(&mask, map->generic_execute | map->generic_read );
94 init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
96 /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
98 sid_copy(&adm_sid, &global_sid_Builtin);
99 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
101 sid_copy(&act_sid, &global_sid_Builtin);
102 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
104 init_sec_access(&mask, map->generic_all);
106 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
107 init_sec_ace(&ace[i++], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
109 /* Add Full Access for Domain Admins if we are a DC */
112 sid_copy( &domadmin_sid, get_global_sam_sid() );
113 sid_append_rid( &domadmin_sid, DOMAIN_GROUP_RID_ADMINS );
114 init_sec_ace(&ace[i++], &domadmin_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
117 /* if we have a sid, give it some special access */
120 init_sec_access( &mask, sid_access );
121 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
124 /* create the security descriptor */
126 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) == NULL)
127 return NT_STATUS_NO_MEMORY;
129 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
130 return NT_STATUS_NO_MEMORY;
135 /*******************************************************************
136 Checks if access to an object should be granted, and returns that
137 level of access for further checks.
138 ********************************************************************/
140 static NTSTATUS access_check_samr_object( SEC_DESC *psd, NT_USER_TOKEN *token,
141 SE_PRIV *rights, uint32 rights_mask,
142 uint32 des_access, uint32 *acc_granted,
145 NTSTATUS status = NT_STATUS_ACCESS_DENIED;
146 uint32 saved_mask = 0;
148 /* check privileges; certain SAM access bits should be overridden
149 by privileges (mostly having to do with creating/modifying/deleting
152 if ( rights && user_has_any_privilege( token, rights ) ) {
154 saved_mask = (des_access & rights_mask);
155 des_access &= ~saved_mask;
157 DEBUG(4,("access_check_samr_object: user rights access mask [0x%x]\n",
162 /* check the security descriptor first */
164 if ( se_access_check(psd, token, des_access, acc_granted, &status) )
167 /* give root a free pass */
169 if ( geteuid() == sec_initial_uid() ) {
171 DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access));
172 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
174 *acc_granted = des_access;
176 status = NT_STATUS_OK;
182 /* add in any bits saved during the privilege check (only
183 matters is status is ok) */
185 *acc_granted |= rights_mask;
187 DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
188 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
189 des_access, *acc_granted));
194 /*******************************************************************
195 Checks if access to a function can be granted
196 ********************************************************************/
198 static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_required, const char *debug)
200 DEBUG(5,("%s: access check ((granted: %#010x; required: %#010x)\n",
201 debug, acc_granted, acc_required));
203 /* check the security descriptor first */
205 if ( (acc_granted&acc_required) == acc_required )
208 /* give root a free pass */
210 if (geteuid() == sec_initial_uid()) {
212 DEBUG(4,("%s: ACCESS should be DENIED (granted: %#010x; required: %#010x)\n",
213 debug, acc_granted, acc_required));
214 DEBUGADD(4,("but overwritten by euid == 0\n"));
219 DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: %#010x)\n",
220 debug, acc_granted, acc_required));
222 return NT_STATUS_ACCESS_DENIED;
226 /*******************************************************************
227 Create a samr_info struct.
228 ********************************************************************/
230 static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
232 struct samr_info *info;
237 sid_to_string(sid_str, psid);
239 fstrcpy(sid_str,"(NULL)");
242 mem_ctx = talloc_init("samr_info for domain sid %s", sid_str);
244 if ((info = TALLOC_P(mem_ctx, struct samr_info)) == NULL)
248 DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
250 sid_copy( &info->sid, psid);
252 DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
254 info->mem_ctx = mem_ctx;
258 /*******************************************************************
259 Function to free the per handle data.
260 ********************************************************************/
262 static void free_samr_users(struct samr_info *info)
266 if (info->disp_info.user_dbloaded){
267 for (i=0; i<info->disp_info.num_user_account; i++) {
268 SAM_ACCOUNT *sam = &info->disp_info.disp_user_info[i];
269 /* Not really a free, actually a 'clear' */
273 info->disp_info.user_dbloaded=False;
274 info->disp_info.num_user_account=0;
277 /*******************************************************************
278 Function to free the per handle data.
279 ********************************************************************/
281 static void free_samr_db(struct samr_info *info)
283 /* Groups are talloced */
285 free_samr_users(info);
287 info->disp_info.group_dbloaded=False;
288 info->disp_info.num_group_account=0;
291 static void free_samr_info(void *ptr)
293 struct samr_info *info=(struct samr_info *) ptr;
296 talloc_destroy(info->mem_ctx);
299 /*******************************************************************
300 Ensure password info is never given out. Paranioa... JRA.
301 ********************************************************************/
303 static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
309 /* These now zero out the old password */
311 pdb_set_lanman_passwd(sam_pass, NULL, PDB_DEFAULT);
312 pdb_set_nt_passwd(sam_pass, NULL, PDB_DEFAULT);
316 static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
318 SAM_ACCOUNT *pwd = NULL;
319 SAM_ACCOUNT *pwd_array = NULL;
320 NTSTATUS nt_status = NT_STATUS_OK;
321 TALLOC_CTX *mem_ctx = info->mem_ctx;
322 uint16 query_acb_mask = acb_mask;
324 DEBUG(10,("load_sampwd_entries\n"));
326 /* if the snapshoot is already loaded, return */
327 if ((info->disp_info.user_dbloaded==True)
328 && (info->acb_mask == acb_mask)
329 && (info->only_machines == only_machines)) {
330 DEBUG(10,("load_sampwd_entries: already in memory\n"));
334 free_samr_users(info);
337 query_acb_mask |= ACB_WSTRUST;
338 query_acb_mask |= ACB_SVRTRUST;
341 if (!pdb_setsampwent(False, query_acb_mask)) {
342 DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
343 return NT_STATUS_ACCESS_DENIED;
346 for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd)))
347 && pdb_getsampwent(pwd) == True; pwd=NULL) {
350 if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST)
351 || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
352 DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
357 if (acb_mask != 0 && !(pdb_get_acct_ctrl(pwd) & acb_mask)) {
359 DEBUG(5,(" acb_mask %x reject\n", acb_mask));
364 /* Realloc some memory for the array of ptr to the SAM_ACCOUNT structs */
365 if (info->disp_info.num_user_account % MAX_SAM_ENTRIES == 0) {
367 DEBUG(10,("load_sampwd_entries: allocating more memory\n"));
368 pwd_array=TALLOC_REALLOC_ARRAY(mem_ctx, info->disp_info.disp_user_info, SAM_ACCOUNT,
369 info->disp_info.num_user_account+MAX_SAM_ENTRIES);
372 return NT_STATUS_NO_MEMORY;
374 info->disp_info.disp_user_info=pwd_array;
377 /* Copy the SAM_ACCOUNT into the array */
378 info->disp_info.disp_user_info[info->disp_info.num_user_account]=*pwd;
380 DEBUG(10,("load_sampwd_entries: entry: %d\n", info->disp_info.num_user_account));
382 info->disp_info.num_user_account++;
387 /* the snapshoot is in memory, we're ready to enumerate fast */
389 info->acb_mask = acb_mask;
390 info->only_machines = only_machines;
391 info->disp_info.user_dbloaded=True;
393 DEBUG(10,("load_sampwd_entries: done\n"));
398 static NTSTATUS load_group_domain_entries(struct samr_info *info, DOM_SID *sid)
401 DOMAIN_GRP *grp_array = NULL;
402 uint32 group_entries = 0;
404 TALLOC_CTX *mem_ctx = info->mem_ctx;
407 DEBUG(10,("load_group_domain_entries\n"));
409 /* if the snapshoot is already loaded, return */
410 if (info->disp_info.group_dbloaded==True) {
411 DEBUG(10,("load_group_domain_entries: already in memory\n"));
415 if (sid_equal(sid, &global_sid_Builtin)) {
416 /* No domain groups for now in the BUILTIN domain */
417 info->disp_info.num_group_account=0;
418 info->disp_info.disp_group_info=NULL;
419 info->disp_info.group_dbloaded=True;
424 ret = pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries, ENUM_ONLY_MAPPED);
428 DEBUG(1, ("load_group_domain_entries: pdb_enum_group_mapping() failed!\n"));
429 return NT_STATUS_NO_MEMORY;
433 info->disp_info.num_group_account=group_entries;
435 grp_array=TALLOC_ARRAY(mem_ctx, DOMAIN_GRP, info->disp_info.num_group_account);
436 if (group_entries!=0 && grp_array==NULL) {
437 DEBUG(1, ("load_group_domain_entries: talloc() failed for grp_array!\n"));
439 return NT_STATUS_NO_MEMORY;
442 info->disp_info.disp_group_info=grp_array;
444 for (i=0; i<group_entries; i++) {
445 fstrcpy(grp_array[i].name, map[i].nt_name);
446 fstrcpy(grp_array[i].comment, map[i].comment);
447 sid_split_rid(&map[i].sid, &grp_array[i].rid);
448 grp_array[i].attr=SID_NAME_DOM_GRP;
453 /* the snapshoot is in memory, we're ready to enumerate fast */
455 info->disp_info.group_dbloaded=True;
457 DEBUG(10,("load_group_domain_entries: done\n"));
463 /*******************************************************************
465 ********************************************************************/
467 NTSTATUS _samr_close_hnd(pipes_struct *p, SAMR_Q_CLOSE_HND *q_u, SAMR_R_CLOSE_HND *r_u)
469 r_u->status = NT_STATUS_OK;
471 /* close the policy handle */
472 if (!close_policy_hnd(p, &q_u->pol))
473 return NT_STATUS_OBJECT_NAME_INVALID;
475 DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
480 /*******************************************************************
481 samr_reply_open_domain
482 ********************************************************************/
484 NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN_DOMAIN *r_u)
486 struct samr_info *info;
487 SEC_DESC *psd = NULL;
489 uint32 des_access = q_u->flags;
494 r_u->status = NT_STATUS_OK;
496 /* find the connection policy handle. */
498 if ( !find_policy_by_hnd(p, &q_u->pol, (void**)&info) )
499 return NT_STATUS_INVALID_HANDLE;
501 status = access_check_samr_function( info->acc_granted,
502 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_open_domain" );
504 if ( !NT_STATUS_IS_OK(status) )
507 /*check if access can be granted as requested by client. */
509 make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 );
510 se_map_generic( &des_access, &dom_generic_mapping );
512 se_priv_copy( &se_rights, &se_machine_account );
513 se_priv_add( &se_rights, &se_add_users );
515 status = access_check_samr_object( psd, p->pipe_user.nt_user_token,
516 &se_rights, GENERIC_RIGHTS_DOMAIN_WRITE, des_access,
517 &acc_granted, "_samr_open_domain" );
519 if ( !NT_STATUS_IS_OK(status) )
522 /* associate the domain SID with the (unique) handle. */
523 if ((info = get_samr_info_by_sid(&q_u->dom_sid.sid))==NULL)
524 return NT_STATUS_NO_MEMORY;
525 info->acc_granted = acc_granted;
527 /* get a (unique) handle. open a policy on it. */
528 if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
529 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
531 DEBUG(5,("samr_open_domain: %d\n", __LINE__));
536 /*******************************************************************
537 _samr_get_usrdom_pwinfo
538 ********************************************************************/
540 NTSTATUS _samr_get_usrdom_pwinfo(pipes_struct *p, SAMR_Q_GET_USRDOM_PWINFO *q_u, SAMR_R_GET_USRDOM_PWINFO *r_u)
542 struct samr_info *info = NULL;
544 r_u->status = NT_STATUS_OK;
546 /* find the policy handle. open a policy on it. */
547 if (!find_policy_by_hnd(p, &q_u->user_pol, (void **)&info))
548 return NT_STATUS_INVALID_HANDLE;
550 if (!sid_check_is_in_our_domain(&info->sid))
551 return NT_STATUS_OBJECT_TYPE_MISMATCH;
553 init_samr_r_get_usrdom_pwinfo(r_u, NT_STATUS_OK);
555 DEBUG(5,("_samr_get_usrdom_pwinfo: %d\n", __LINE__));
558 * NT sometimes return NT_STATUS_ACCESS_DENIED
559 * I don't know yet why.
566 /*******************************************************************
568 ********************************************************************/
570 NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u)
572 DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n"));
573 return NT_STATUS_NOT_IMPLEMENTED;
577 /*******************************************************************
578 ********************************************************************/
580 static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
581 DOM_SID *sid, uint32 *acc_granted)
583 struct samr_info *info = NULL;
585 /* find the policy handle. open a policy on it. */
586 if (!find_policy_by_hnd(p, pol, (void **)&info))
593 *acc_granted = info->acc_granted;
597 /*******************************************************************
599 ********************************************************************/
601 NTSTATUS _samr_query_sec_obj(pipes_struct *p, SAMR_Q_QUERY_SEC_OBJ *q_u, SAMR_R_QUERY_SEC_OBJ *r_u)
605 SEC_DESC * psd = NULL;
609 r_u->status = NT_STATUS_OK;
612 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &pol_sid, &acc_granted))
613 return NT_STATUS_INVALID_HANDLE;
617 DEBUG(10,("_samr_query_sec_obj: querying security on SID: %s\n", sid_to_string(str_sid, &pol_sid)));
619 /* Check what typ of SID is beeing queried (e.g Domain SID, User SID, Group SID) */
621 /* To query the security of the SAM it self an invalid SID with S-0-0 is passed to this function */
622 if (pol_sid.sid_rev_num == 0)
624 DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n"));
625 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
627 else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */
630 DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
631 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
633 else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */
635 /* TODO: Builtin probably needs a different SD with restricted write access*/
636 DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
637 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0);
639 else if (sid_check_is_in_our_domain(&pol_sid) ||
640 sid_check_is_in_builtin(&pol_sid))
642 /* TODO: different SDs have to be generated for aliases groups and users.
643 Currently all three get a default user SD */
644 DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid)));
645 r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW);
647 else return NT_STATUS_OBJECT_TYPE_MISMATCH;
649 if ((r_u->buf = make_sec_desc_buf(p->mem_ctx, sd_size, psd)) == NULL)
650 return NT_STATUS_NO_MEMORY;
652 if (NT_STATUS_IS_OK(r_u->status))
658 /*******************************************************************
659 makes a SAM_ENTRY / UNISTR2* structure from a user list.
660 ********************************************************************/
662 static NTSTATUS make_user_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
663 uint32 num_entries, uint32 start_idx, SAM_ACCOUNT *disp_user_info,
669 SAM_ACCOUNT *pwd = NULL;
670 UNISTR2 uni_temp_name;
671 const char *temp_name;
672 const DOM_SID *user_sid;
674 fstring user_sid_string;
675 fstring domain_sid_string;
680 if (num_entries == 0)
683 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_entries);
685 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_entries);
687 if (sam == NULL || uni_name == NULL) {
688 DEBUG(0, ("make_user_sam_entry_list: talloc_zero failed!\n"));
689 return NT_STATUS_NO_MEMORY;
692 for (i = 0; i < num_entries; i++) {
693 pwd = &disp_user_info[i+start_idx];
694 temp_name = pdb_get_username(pwd);
697 * usrmgr expects a non-NULL terminated string with
698 * trust relationships
700 if (pdb_get_acct_ctrl(pwd) & ACB_DOMTRUST) {
701 init_unistr2(&uni_temp_name, temp_name, UNI_FLAGS_NONE);
703 init_unistr2(&uni_temp_name, temp_name, UNI_STR_TERMINATE);
706 user_sid = pdb_get_user_sid(pwd);
708 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) {
709 DEBUG(0, ("make_user_sam_entry_list: User %s has SID %s, which conflicts with "
710 "the domain sid %s. Failing operation.\n",
712 sid_to_string(user_sid_string, user_sid),
713 sid_to_string(domain_sid_string, domain_sid)));
714 return NT_STATUS_UNSUCCESSFUL;
717 init_sam_entry(&sam[i], &uni_temp_name, user_rid);
718 copy_unistr2(&uni_name[i], &uni_temp_name);
722 *uni_name_pp = uni_name;
726 /*******************************************************************
727 samr_reply_enum_dom_users
728 ********************************************************************/
730 NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
731 SAMR_R_ENUM_DOM_USERS *r_u)
733 struct samr_info *info = NULL;
734 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
736 uint32 enum_context=q_u->start_idx;
737 uint32 max_size=q_u->max_size;
739 enum remote_arch_types ra_type = get_remote_arch();
740 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
741 uint32 max_entries = max_sam_entries;
744 r_u->status = NT_STATUS_OK;
746 /* find the policy handle. open a policy on it. */
747 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
748 return NT_STATUS_INVALID_HANDLE;
750 domain_sid = info->sid;
752 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
753 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
754 "_samr_enum_dom_users"))) {
758 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
761 r_u->status=load_sampwd_entries(info, q_u->acb_mask, False);
764 if (!NT_STATUS_IS_OK(r_u->status))
767 num_account = info->disp_info.num_user_account;
769 if (enum_context > num_account) {
770 DEBUG(5, ("_samr_enum_dom_users: enumeration handle over total entries\n"));
774 /* verify we won't overflow */
775 if (max_entries > num_account-enum_context) {
776 max_entries = num_account-enum_context;
777 DEBUG(5, ("_samr_enum_dom_users: only %d entries to return\n", max_entries));
780 /* calculate the size and limit on the number of entries we will return */
781 temp_size=max_entries*struct_size;
783 if (temp_size>max_size) {
784 max_entries=MIN((max_size/struct_size),max_entries);;
785 DEBUG(5, ("_samr_enum_dom_users: buffer size limits to only %d entries\n", max_entries));
789 * Note from JRA. total_entries is not being used here. Currently if there is a
790 * large user base then it looks like NT will enumerate until get_sampwd_entries
791 * returns False due to num_entries being zero. This will cause an access denied
792 * return. I don't think this is right and needs further investigation. Note that
793 * this is also the same in the TNG code (I don't think that has been tested with
794 * a very large user list as MAX_SAM_ENTRIES is set to 600).
796 * I also think that one of the 'num_entries' return parameters is probably
797 * the "max entries" parameter - but in the TNG code they're all currently set to the same
798 * value (again I think this is wrong).
801 r_u->status = make_user_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_acct_name,
802 max_entries, enum_context,
803 info->disp_info.disp_user_info,
806 if (!NT_STATUS_IS_OK(r_u->status))
809 if (enum_context+max_entries < num_account)
810 r_u->status = STATUS_MORE_ENTRIES;
812 DEBUG(5, ("_samr_enum_dom_users: %d\n", __LINE__));
814 init_samr_r_enum_dom_users(r_u, q_u->start_idx + max_entries, max_entries);
816 DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
821 /*******************************************************************
822 makes a SAM_ENTRY / UNISTR2* structure from a group list.
823 ********************************************************************/
825 static void make_group_sam_entry_list(TALLOC_CTX *ctx, SAM_ENTRY **sam_pp, UNISTR2 **uni_name_pp,
826 uint32 num_sam_entries, DOMAIN_GRP *grp)
835 if (num_sam_entries == 0)
838 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
839 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
841 if (sam == NULL || uni_name == NULL) {
842 DEBUG(0, ("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
846 for (i = 0; i < num_sam_entries; i++) {
848 * JRA. I think this should include the null. TNG does not.
850 init_unistr2(&uni_name[i], grp[i].name, UNI_STR_TERMINATE);
851 init_sam_entry(&sam[i], &uni_name[i], grp[i].rid);
855 *uni_name_pp = uni_name;
858 /*******************************************************************
859 Get the group entries - similar to get_sampwd_entries().
860 ******************************************************************/
862 static NTSTATUS get_group_domain_entries( TALLOC_CTX *ctx,
863 DOMAIN_GRP **d_grp, DOM_SID *sid, uint32 start_idx,
864 uint32 *p_num_entries, uint32 max_entries )
868 uint32 group_entries = 0;
869 uint32 num_entries = 0;
873 /* access checks for the users were performed higher up. become/unbecome_root()
874 needed for some passdb backends to enumerate groups */
877 pdb_enum_group_mapping(SID_NAME_DOM_GRP, &map, (int *)&group_entries,
881 num_entries=group_entries-start_idx;
883 /* limit the number of entries */
884 if (num_entries>max_entries) {
885 DEBUG(5,("Limiting to %d entries\n", max_entries));
886 num_entries=max_entries;
889 *d_grp=TALLOC_ZERO_ARRAY(ctx, DOMAIN_GRP, num_entries);
890 if (num_entries!=0 && *d_grp==NULL){
892 return NT_STATUS_NO_MEMORY;
895 for (i=0; i<num_entries; i++) {
896 fstrcpy((*d_grp)[i].name, map[i+start_idx].nt_name);
897 fstrcpy((*d_grp)[i].comment, map[i+start_idx].comment);
898 sid_split_rid(&map[i+start_idx].sid, &(*d_grp)[i].rid);
899 (*d_grp)[i].attr=SID_NAME_DOM_GRP;
904 *p_num_entries = num_entries;
906 DEBUG(10,("get_group_domain_entries: returning %d entries\n",
912 /*******************************************************************
913 Wrapper for enumerating local groups
914 ******************************************************************/
916 static NTSTATUS get_alias_entries( TALLOC_CTX *ctx, DOMAIN_GRP **d_grp,
917 const DOM_SID *sid, uint32 start_idx,
918 uint32 *p_num_entries, uint32 max_entries )
920 struct acct_info *info;
925 res = pdb_enum_aliases(sid, start_idx, max_entries,
926 p_num_entries, &info);
930 return NT_STATUS_ACCESS_DENIED;
932 if (*p_num_entries == 0)
935 *d_grp = TALLOC_ARRAY(ctx, DOMAIN_GRP, *p_num_entries);
937 if (*d_grp == NULL) {
939 return NT_STATUS_NO_MEMORY;
942 for (i=0; i<*p_num_entries; i++) {
943 fstrcpy((*d_grp)[i].name, info[i].acct_name);
944 fstrcpy((*d_grp)[i].comment, info[i].acct_desc);
945 (*d_grp)[i].rid = info[i].rid;
946 (*d_grp)[i].attr = SID_NAME_ALIAS;
953 /*******************************************************************
954 samr_reply_enum_dom_groups
955 ********************************************************************/
957 NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAMR_R_ENUM_DOM_GROUPS *r_u)
959 DOMAIN_GRP *grp=NULL;
964 r_u->status = NT_STATUS_OK;
966 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
967 return NT_STATUS_INVALID_HANDLE;
969 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_groups"))) {
973 DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
975 /* the domain group array is being allocated in the function below */
976 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))) {
980 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
982 init_samr_r_enum_dom_groups(r_u, q_u->start_idx, num_entries);
984 DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
990 /*******************************************************************
991 samr_reply_enum_dom_aliases
992 ********************************************************************/
994 NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, SAMR_R_ENUM_DOM_ALIASES *r_u)
996 DOMAIN_GRP *grp=NULL;
997 uint32 num_entries = 0;
1003 r_u->status = NT_STATUS_OK;
1005 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1006 return NT_STATUS_INVALID_HANDLE;
1008 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, "_samr_enum_dom_aliases"))) {
1012 sid_to_string(sid_str, &sid);
1013 DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
1015 status = get_alias_entries(p->mem_ctx, &grp, &sid, q_u->start_idx,
1016 &num_entries, MAX_SAM_ENTRIES);
1017 if (!NT_STATUS_IS_OK(status)) return status;
1019 make_group_sam_entry_list(p->mem_ctx, &r_u->sam, &r_u->uni_grp_name, num_entries, grp);
1023 init_samr_r_enum_dom_aliases(r_u, q_u->start_idx + num_entries, num_entries);
1025 DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
1030 /*******************************************************************
1031 samr_reply_query_dispinfo
1032 ********************************************************************/
1034 NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
1035 SAMR_R_QUERY_DISPINFO *r_u)
1037 struct samr_info *info = NULL;
1038 uint32 struct_size=0x20; /* W2K always reply that, client doesn't care */
1040 uint32 max_entries=q_u->max_entries;
1041 uint32 enum_context=q_u->start_idx;
1042 uint32 max_size=q_u->max_size;
1044 SAM_DISPINFO_CTR *ctr;
1045 uint32 temp_size=0, total_data_size=0;
1047 uint32 num_account = 0;
1048 enum remote_arch_types ra_type = get_remote_arch();
1049 int max_sam_entries = (ra_type == RA_WIN95) ? MAX_SAM_ENTRIES_W95 : MAX_SAM_ENTRIES_W2K;
1052 DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
1053 r_u->status = NT_STATUS_OK;
1055 /* find the policy handle. open a policy on it. */
1056 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
1057 return NT_STATUS_INVALID_HANDLE;
1059 domain_sid = info->sid;
1062 * calculate how many entries we will return.
1064 * - the number of entries the client asked
1065 * - our limit on that
1066 * - the starting point (enumeration context)
1067 * - the buffer size the client will accept
1071 * We are a lot more like W2K. Instead of reading the SAM
1072 * each time to find the records we need to send back,
1073 * we read it once and link that copy to the sam handle.
1074 * For large user list (over the MAX_SAM_ENTRIES)
1075 * it's a definitive win.
1076 * second point to notice: between enumerations
1077 * our sam is now the same as it's a snapshoot.
1078 * third point: got rid of the static SAM_USER_21 struct
1079 * no more intermediate.
1080 * con: it uses much more memory, as a full copy is stored
1083 * If you want to change it, think twice and think
1084 * of the second point , that's really important.
1089 /* Get what we need from the password database */
1090 switch (q_u->switch_level) {
1092 /* When playing with usrmgr, this is necessary
1093 if you want immediate refresh after editing
1094 a user. I would like to do this after the
1095 setuserinfo2, but we do not have access to
1096 the domain handle in that call, only to the
1097 user handle. Where else does this hurt?
1101 /* We cannot do this here - it kills performace. JRA. */
1102 free_samr_users(info);
1107 /* Level 2 is for all machines, otherwise only 'normal' users */
1108 r_u->status=load_sampwd_entries(info, ACB_NORMAL, q_u->switch_level==2);
1110 if (!NT_STATUS_IS_OK(r_u->status)) {
1111 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
1114 num_account = info->disp_info.num_user_account;
1118 r_u->status = load_group_domain_entries(info, &info->sid);
1119 if (!NT_STATUS_IS_OK(r_u->status))
1121 num_account = info->disp_info.num_group_account;
1124 DEBUG(0,("_samr_query_dispinfo: Unknown info level (%u)\n", (unsigned int)q_u->switch_level ));
1125 return NT_STATUS_INVALID_INFO_CLASS;
1128 /* first limit the number of entries we will return */
1129 if(max_entries > max_sam_entries) {
1130 DEBUG(5, ("samr_reply_query_dispinfo: client requested %d entries, limiting to %d\n", max_entries, max_sam_entries));
1131 max_entries = max_sam_entries;
1134 if (enum_context > num_account) {
1135 DEBUG(5, ("samr_reply_query_dispinfo: enumeration handle over total entries\n"));
1136 return NT_STATUS_NO_MORE_ENTRIES;
1139 /* verify we won't overflow */
1140 if (max_entries > num_account-enum_context) {
1141 max_entries = num_account-enum_context;
1142 DEBUG(5, ("samr_reply_query_dispinfo: only %d entries to return\n", max_entries));
1145 /* calculate the size and limit on the number of entries we will return */
1146 temp_size=max_entries*struct_size;
1148 if (temp_size>max_size) {
1149 max_entries=MIN((max_size/struct_size),max_entries);;
1150 DEBUG(5, ("samr_reply_query_dispinfo: buffer size limits to only %d entries\n", max_entries));
1153 if (!(ctr = TALLOC_ZERO_P(p->mem_ctx,SAM_DISPINFO_CTR)))
1154 return NT_STATUS_NO_MEMORY;
1158 /* Now create reply structure */
1159 switch (q_u->switch_level) {
1162 if (!(ctr->sam.info1 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_1,max_entries)))
1163 return NT_STATUS_NO_MEMORY;
1165 disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, max_entries, enum_context,
1166 info->disp_info.disp_user_info, &domain_sid);
1167 if (!NT_STATUS_IS_OK(disp_ret))
1172 if (!(ctr->sam.info2 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_2,max_entries)))
1173 return NT_STATUS_NO_MEMORY;
1175 disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, max_entries, enum_context,
1176 info->disp_info.disp_user_info, &domain_sid);
1177 if (!NT_STATUS_IS_OK(disp_ret))
1182 if (!(ctr->sam.info3 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_3,max_entries)))
1183 return NT_STATUS_NO_MEMORY;
1185 disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, max_entries, enum_context, info->disp_info.disp_group_info);
1186 if (!NT_STATUS_IS_OK(disp_ret))
1191 if (!(ctr->sam.info4 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_4,max_entries)))
1192 return NT_STATUS_NO_MEMORY;
1194 disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, max_entries, enum_context, info->disp_info.disp_user_info);
1195 if (!NT_STATUS_IS_OK(disp_ret))
1200 if (!(ctr->sam.info5 = TALLOC_ZERO_ARRAY(p->mem_ctx,SAM_DISPINFO_5,max_entries)))
1201 return NT_STATUS_NO_MEMORY;
1203 disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, max_entries, enum_context, info->disp_info.disp_group_info);
1204 if (!NT_STATUS_IS_OK(disp_ret))
1209 ctr->sam.info = NULL;
1210 return NT_STATUS_INVALID_INFO_CLASS;
1213 /* calculate the total size */
1214 total_data_size=num_account*struct_size;
1216 if (enum_context+max_entries < num_account)
1217 r_u->status = STATUS_MORE_ENTRIES;
1219 DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__));
1221 init_samr_r_query_dispinfo(r_u, max_entries, total_data_size, temp_size, q_u->switch_level, ctr, r_u->status);
1227 /*******************************************************************
1228 samr_reply_query_aliasinfo
1229 ********************************************************************/
1231 NTSTATUS _samr_query_aliasinfo(pipes_struct *p, SAMR_Q_QUERY_ALIASINFO *q_u, SAMR_R_QUERY_ALIASINFO *r_u)
1234 struct acct_info info;
1238 r_u->status = NT_STATUS_OK;
1240 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1242 /* find the policy handle. open a policy on it. */
1243 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1244 return NT_STATUS_INVALID_HANDLE;
1245 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_LOOKUP_INFO, "_samr_query_aliasinfo"))) {
1250 ret = pdb_get_aliasinfo(&sid, &info);
1254 return NT_STATUS_NO_SUCH_ALIAS;
1256 switch (q_u->switch_level) {
1259 r_u->ctr.switch_value1 = 1;
1260 init_samr_alias_info1(&r_u->ctr.alias.info1,
1261 info.acct_name, 1, info.acct_desc);
1265 r_u->ctr.switch_value1 = 3;
1266 init_samr_alias_info3(&r_u->ctr.alias.info3, info.acct_desc);
1269 return NT_STATUS_INVALID_INFO_CLASS;
1272 DEBUG(5,("_samr_query_aliasinfo: %d\n", __LINE__));
1278 /*******************************************************************
1279 samr_reply_lookup_ids
1280 ********************************************************************/
1282 uint32 _samr_lookup_ids(pipes_struct *p, SAMR_Q_LOOKUP_IDS *q_u, SAMR_R_LOOKUP_IDS *r_u)
1284 uint32 rid[MAX_SAM_ENTRIES];
1285 int num_rids = q_u->num_sids1;
1287 r_u->status = NT_STATUS_OK;
1289 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1291 if (num_rids > MAX_SAM_ENTRIES) {
1292 num_rids = MAX_SAM_ENTRIES;
1293 DEBUG(5,("_samr_lookup_ids: truncating entries to %d\n", num_rids));
1298 SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
1300 for (i = 0; i < num_rids && status == 0; i++)
1302 struct sam_passwd *sam_pass;
1306 fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
1307 q_u->uni_user_name[i].uni_str_len));
1309 /* find the user account */
1311 sam_pass = get_smb21pwd_entry(user_name, 0);
1314 if (sam_pass == NULL)
1316 status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
1321 rid[i] = sam_pass->user_rid;
1327 rid[0] = BUILTIN_ALIAS_RID_USERS;
1329 init_samr_r_lookup_ids(&r_u, num_rids, rid, NT_STATUS_OK);
1331 DEBUG(5,("_samr_lookup_ids: %d\n", __LINE__));
1337 /*******************************************************************
1339 ********************************************************************/
1341 NTSTATUS _samr_lookup_names(pipes_struct *p, SAMR_Q_LOOKUP_NAMES *q_u, SAMR_R_LOOKUP_NAMES *r_u)
1343 uint32 rid[MAX_SAM_ENTRIES];
1345 enum SID_NAME_USE type[MAX_SAM_ENTRIES];
1346 enum SID_NAME_USE local_type;
1348 int num_rids = q_u->num_names2;
1353 r_u->status = NT_STATUS_OK;
1355 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1360 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) {
1361 init_samr_r_lookup_names(p->mem_ctx, r_u, 0, NULL, NULL, NT_STATUS_OBJECT_TYPE_MISMATCH);
1365 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 */
1369 if (num_rids > MAX_SAM_ENTRIES) {
1370 num_rids = MAX_SAM_ENTRIES;
1371 DEBUG(5,("_samr_lookup_names: truncating entries to %d\n", num_rids));
1374 DEBUG(5,("_samr_lookup_names: looking name on SID %s\n", sid_to_string(sid_str, &pol_sid)));
1376 for (i = 0; i < num_rids; i++) {
1381 r_u->status = NT_STATUS_NONE_MAPPED;
1383 rid [i] = 0xffffffff;
1384 type[i] = SID_NAME_UNKNOWN;
1386 ret = rpcstr_pull(name, q_u->uni_name[i].buffer, sizeof(name), q_u->uni_name[i].uni_str_len*2, 0);
1389 * we are only looking for a name
1390 * the SID we get back can be outside
1391 * the scope of the pol_sid
1393 * in clear: it prevents to reply to domain\group: yes
1394 * when only builtin\group exists.
1396 * a cleaner code is to add the sid of the domain we're looking in
1397 * to the local_lookup_name function.
1400 if ((ret > 0) && local_lookup_name(name, &sid, &local_type)) {
1401 sid_split_rid(&sid, &local_rid);
1403 if (sid_equal(&sid, &pol_sid)) {
1406 /* Windows does not return WKN_GRP here, even
1407 * on lookups in builtin */
1408 type[i] = (local_type == SID_NAME_WKN_GRP) ?
1409 SID_NAME_ALIAS : local_type;
1411 r_u->status = NT_STATUS_OK;
1416 init_samr_r_lookup_names(p->mem_ctx, r_u, num_rids, rid, (uint32 *)type, r_u->status);
1418 DEBUG(5,("_samr_lookup_names: %d\n", __LINE__));
1423 /*******************************************************************
1424 _samr_chgpasswd_user
1425 ********************************************************************/
1427 NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_R_CHGPASSWD_USER *r_u)
1432 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1434 r_u->status = NT_STATUS_OK;
1436 rpcstr_pull(user_name, q_u->uni_user_name.buffer, sizeof(user_name), q_u->uni_user_name.uni_str_len*2, 0);
1437 rpcstr_pull(wks, q_u->uni_dest_host.buffer, sizeof(wks), q_u->uni_dest_host.uni_str_len*2,0);
1439 DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
1442 * Pass the user through the NT -> unix user mapping
1446 (void)map_username(user_name);
1449 * UNIX username case mangling not required, pass_oem_change
1450 * is case insensitive.
1453 r_u->status = pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
1454 q_u->nt_newpass.pass, q_u->nt_oldhash.hash);
1456 init_samr_r_chgpasswd_user(r_u, r_u->status);
1458 DEBUG(5,("_samr_chgpasswd_user: %d\n", __LINE__));
1463 /*******************************************************************
1464 makes a SAMR_R_LOOKUP_RIDS structure.
1465 ********************************************************************/
1467 static BOOL make_samr_lookup_rids(TALLOC_CTX *ctx, uint32 num_names,
1468 const char **names, UNIHDR **pp_hdr_name,
1469 UNISTR2 **pp_uni_name)
1472 UNIHDR *hdr_name=NULL;
1473 UNISTR2 *uni_name=NULL;
1475 *pp_uni_name = NULL;
1476 *pp_hdr_name = NULL;
1478 if (num_names != 0) {
1479 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1480 if (hdr_name == NULL)
1483 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1484 if (uni_name == NULL)
1488 for (i = 0; i < num_names; i++) {
1489 DEBUG(10, ("names[%d]:%s\n", i, *names[i] ? names[i] : ""));
1490 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1491 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1494 *pp_uni_name = uni_name;
1495 *pp_hdr_name = hdr_name;
1500 /*******************************************************************
1502 ********************************************************************/
1504 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1507 uint32 *attrs = NULL;
1508 UNIHDR *hdr_name = NULL;
1509 UNISTR2 *uni_name = NULL;
1511 int num_rids = q_u->num_rids1;
1514 r_u->status = NT_STATUS_OK;
1516 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1518 /* find the policy handle. open a policy on it. */
1519 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted))
1520 return NT_STATUS_INVALID_HANDLE;
1522 if (num_rids > 1000) {
1523 DEBUG(0, ("Got asked for %d rids (more than 1000) -- according "
1524 "to samba4 idl this is not possible\n", num_rids));
1525 return NT_STATUS_UNSUCCESSFUL;
1528 names = TALLOC_ZERO_ARRAY(p->mem_ctx, const char *, num_rids);
1529 attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids);
1531 if ((num_rids != 0) && ((names == NULL) || (attrs == NULL)))
1532 return NT_STATUS_NO_MEMORY;
1534 if (!sid_equal(&pol_sid, get_global_sam_sid())) {
1535 /* TODO: Sooner or later we need to look up BUILTIN rids as
1540 become_root(); /* lookup_sid can require root privs */
1541 r_u->status = pdb_lookup_rids(p->mem_ctx, &pol_sid, num_rids, q_u->rid,
1547 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, names,
1548 &hdr_name, &uni_name))
1549 return NT_STATUS_NO_MEMORY;
1551 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, attrs);
1553 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1558 /*******************************************************************
1559 _samr_open_user. Safe - gives out no passwd info.
1560 ********************************************************************/
1562 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1564 SAM_ACCOUNT *sampass=NULL;
1566 POLICY_HND domain_pol = q_u->domain_pol;
1567 POLICY_HND *user_pol = &r_u->user_pol;
1568 struct samr_info *info = NULL;
1569 SEC_DESC *psd = NULL;
1571 uint32 des_access = q_u->access_mask;
1577 r_u->status = NT_STATUS_OK;
1579 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1581 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
1582 return NT_STATUS_INVALID_HANDLE;
1584 nt_status = access_check_samr_function( acc_granted,
1585 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1587 if ( !NT_STATUS_IS_OK(nt_status) )
1590 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1592 if (!NT_STATUS_IS_OK(nt_status))
1595 /* append the user's RID to it */
1597 if (!sid_append_rid(&sid, q_u->user_rid))
1598 return NT_STATUS_NO_SUCH_USER;
1600 /* check if access can be granted as requested by client. */
1602 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1603 se_map_generic(&des_access, &usr_generic_mapping);
1605 se_priv_copy( &se_rights, &se_machine_account );
1606 se_priv_add( &se_rights, &se_add_users );
1608 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
1609 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
1610 &acc_granted, "_samr_open_user");
1612 if ( !NT_STATUS_IS_OK(nt_status) )
1616 ret=pdb_getsampwsid(sampass, &sid);
1619 /* check that the SID exists in our domain. */
1621 return NT_STATUS_NO_SUCH_USER;
1624 pdb_free_sam(&sampass);
1626 /* associate the user's SID and access bits with the new handle. */
1627 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1628 return NT_STATUS_NO_MEMORY;
1629 info->acc_granted = acc_granted;
1631 /* get a (unique) handle. open a policy on it. */
1632 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1633 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1638 /*************************************************************************
1639 get_user_info_7. Safe. Only gives out account_name.
1640 *************************************************************************/
1642 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1644 SAM_ACCOUNT *smbpass=NULL;
1648 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1650 if (!NT_STATUS_IS_OK(nt_status)) {
1655 ret = pdb_getsampwsid(smbpass, user_sid);
1659 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1660 return NT_STATUS_NO_SUCH_USER;
1663 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1666 init_sam_user_info7(id7, pdb_get_username(smbpass) );
1668 pdb_free_sam(&smbpass);
1670 return NT_STATUS_OK;
1672 /*************************************************************************
1673 get_user_info_10. Safe. Only gives out acb bits.
1674 *************************************************************************/
1676 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1678 SAM_ACCOUNT *smbpass=NULL;
1682 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1684 if (!NT_STATUS_IS_OK(nt_status)) {
1689 ret = pdb_getsampwsid(smbpass, user_sid);
1693 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1694 return NT_STATUS_NO_SUCH_USER;
1697 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1700 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1702 pdb_free_sam(&smbpass);
1704 return NT_STATUS_OK;
1707 /*************************************************************************
1708 get_user_info_12. OK - this is the killer as it gives out password info.
1709 Ensure that this is only allowed on an encrypted connection with a root
1711 *************************************************************************/
1713 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1715 SAM_ACCOUNT *smbpass=NULL;
1719 if (!p->ntlmssp_auth_validated)
1720 return NT_STATUS_ACCESS_DENIED;
1722 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1723 return NT_STATUS_ACCESS_DENIED;
1726 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1729 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1731 if (!NT_STATUS_IS_OK(nt_status)) {
1735 ret = pdb_getsampwsid(smbpass, user_sid);
1738 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1739 pdb_free_sam(&smbpass);
1740 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1743 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1745 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1746 pdb_free_sam(&smbpass);
1747 return NT_STATUS_ACCOUNT_DISABLED;
1751 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1753 pdb_free_sam(&smbpass);
1755 return NT_STATUS_OK;
1758 /*************************************************************************
1760 *************************************************************************/
1762 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1764 SAM_ACCOUNT *sampass=NULL;
1767 pdb_init_sam_talloc(mem_ctx, &sampass);
1770 ret = pdb_getsampwsid(sampass, user_sid);
1774 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1775 return NT_STATUS_NO_SUCH_USER;
1778 samr_clear_sam_passwd(sampass);
1780 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1783 init_sam_user_info20A(id20, sampass);
1785 pdb_free_sam(&sampass);
1787 return NT_STATUS_OK;
1790 /*************************************************************************
1792 *************************************************************************/
1794 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1795 DOM_SID *user_sid, DOM_SID *domain_sid)
1797 SAM_ACCOUNT *sampass=NULL;
1801 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1802 if (!NT_STATUS_IS_OK(nt_status)) {
1807 ret = pdb_getsampwsid(sampass, user_sid);
1811 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1812 return NT_STATUS_NO_SUCH_USER;
1815 samr_clear_sam_passwd(sampass);
1817 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1820 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1822 pdb_free_sam(&sampass);
1824 return NT_STATUS_OK;
1827 /*******************************************************************
1828 _samr_query_userinfo
1829 ********************************************************************/
1831 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1833 SAM_USERINFO_CTR *ctr;
1834 struct samr_info *info = NULL;
1838 r_u->status=NT_STATUS_OK;
1840 /* search for the handle */
1841 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1842 return NT_STATUS_INVALID_HANDLE;
1844 domain_sid = info->sid;
1846 sid_split_rid(&domain_sid, &rid);
1848 if (!sid_check_is_in_our_domain(&info->sid))
1849 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1851 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1853 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1855 return NT_STATUS_NO_MEMORY;
1859 /* ok! user info levels (lots: see MSDEV help), off we go... */
1860 ctr->switch_value = q_u->switch_value;
1862 switch (q_u->switch_value) {
1864 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
1865 if (ctr->info.id7 == NULL)
1866 return NT_STATUS_NO_MEMORY;
1868 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
1872 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1873 if (ctr->info.id10 == NULL)
1874 return NT_STATUS_NO_MEMORY;
1876 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1881 /* whoops - got this wrong. i think. or don't understand what's happening. */
1885 info = (void *)&id11;
1887 expire.low = 0xffffffff;
1888 expire.high = 0x7fffffff;
1890 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1891 ZERO_STRUCTP(ctr->info.id11);
1892 init_sam_user_info11(ctr->info.id11, &expire,
1893 "BROOKFIELDS$", /* name */
1894 0x03ef, /* user rid */
1895 0x201, /* group rid */
1896 0x0080); /* acb info */
1903 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1904 if (ctr->info.id12 == NULL)
1905 return NT_STATUS_NO_MEMORY;
1907 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1912 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1913 if (ctr->info.id20 == NULL)
1914 return NT_STATUS_NO_MEMORY;
1915 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1920 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1921 if (ctr->info.id21 == NULL)
1922 return NT_STATUS_NO_MEMORY;
1923 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1924 &info->sid, &domain_sid)))
1929 return NT_STATUS_INVALID_INFO_CLASS;
1932 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1934 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1939 /*******************************************************************
1940 samr_reply_query_usergroups
1941 ********************************************************************/
1943 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1945 SAM_ACCOUNT *sam_pass=NULL;
1946 struct passwd *passwd;
1949 DOM_GID *gids = NULL;
1958 * from the SID in the request:
1959 * we should send back the list of DOMAIN GROUPS
1960 * the user is a member of
1962 * and only the DOMAIN GROUPS
1963 * no ALIASES !!! neither aliases of the domain
1964 * nor aliases of the builtin SID
1969 r_u->status = NT_STATUS_OK;
1971 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1973 /* find the policy handle. open a policy on it. */
1974 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1975 return NT_STATUS_INVALID_HANDLE;
1977 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1981 if (!sid_check_is_in_our_domain(&sid))
1982 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1984 pdb_init_sam(&sam_pass);
1987 ret = pdb_getsampwsid(sam_pass, &sid);
1991 pdb_free_sam(&sam_pass);
1992 return NT_STATUS_NO_SUCH_USER;
1995 passwd = getpwnam_alloc(pdb_get_username(sam_pass));
1996 if (passwd == NULL) {
1997 pdb_free_sam(&sam_pass);
1998 return NT_STATUS_NO_SUCH_USER;
2004 result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2006 &sids, &unix_gids, &num_groups);
2009 pdb_free_sam(&sam_pass);
2010 passwd_free(&passwd);
2012 if (!NT_STATUS_IS_OK(result))
2015 SAFE_FREE(unix_gids);
2020 for (i=0; i<num_groups; i++) {
2023 if (!sid_peek_check_rid(get_global_sam_sid(),
2027 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2028 gids[num_gids].attr=7;
2029 gids[num_gids].g_rid = rid;
2034 /* construct the response. lkclXXXX: gids are not copied! */
2035 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2037 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2042 /*******************************************************************
2043 _samr_query_dom_info
2044 ********************************************************************/
2046 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2048 struct samr_info *info = NULL;
2050 uint32 min_pass_len,pass_hist,flag;
2051 time_t u_expire, u_min_age;
2052 NTTIME nt_expire, nt_min_age;
2054 time_t u_lock_duration, u_reset_time;
2055 NTTIME nt_lock_duration, nt_reset_time;
2061 uint32 account_policy_temp;
2064 uint32 num_users=0, num_groups=0, num_aliases=0;
2066 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2067 return NT_STATUS_NO_MEMORY;
2071 r_u->status = NT_STATUS_OK;
2073 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2075 /* find the policy handle. open a policy on it. */
2076 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2077 return NT_STATUS_INVALID_HANDLE;
2079 switch (q_u->switch_value) {
2082 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2083 min_pass_len = account_policy_temp;
2085 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2086 pass_hist = account_policy_temp;
2088 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2089 flag = account_policy_temp;
2091 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2092 u_expire = account_policy_temp;
2094 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2095 u_min_age = account_policy_temp;
2097 unix_to_nt_time_abs(&nt_expire, u_expire);
2098 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2100 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2101 flag, nt_expire, nt_min_age);
2105 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2107 if (!NT_STATUS_IS_OK(r_u->status)) {
2108 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2111 num_users=info->disp_info.num_user_account;
2114 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2115 if (!NT_STATUS_IS_OK(r_u->status)) {
2116 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2119 num_groups=info->disp_info.num_group_account;
2122 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2123 u_logout = account_policy_temp;
2125 unix_to_nt_time_abs(&nt_logout, u_logout);
2127 server_role = ROLE_DOMAIN_PDC;
2128 if (lp_server_role() == ROLE_DOMAIN_BDC)
2129 server_role = ROLE_DOMAIN_BDC;
2131 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2132 init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
2133 num_users, num_groups, num_aliases, nt_logout, server_role);
2136 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2137 unix_to_nt_time_abs(&nt_logout, u_logout);
2139 init_unk_info3(&ctr->info.inf3, nt_logout);
2142 init_unk_info5(&ctr->info.inf5, global_myname());
2145 init_unk_info6(&ctr->info.inf6);
2148 server_role = ROLE_DOMAIN_PDC;
2149 if (lp_server_role() == ROLE_DOMAIN_BDC)
2150 server_role = ROLE_DOMAIN_BDC;
2152 init_unk_info7(&ctr->info.inf7, server_role);
2155 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2158 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2159 u_lock_duration = account_policy_temp;
2160 if (u_lock_duration != -1)
2161 u_lock_duration *= 60;
2163 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2164 u_reset_time = account_policy_temp * 60;
2166 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2167 lockout = account_policy_temp;
2169 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2170 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2172 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2175 return NT_STATUS_INVALID_INFO_CLASS;
2178 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2180 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2185 /*******************************************************************
2187 Create an account, can be either a normal user or a machine.
2188 This funcion will need to be updated for bdc/domain trusts.
2189 ********************************************************************/
2191 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2193 SAM_ACCOUNT *sam_pass=NULL;
2197 POLICY_HND dom_pol = q_u->domain_pol;
2198 UNISTR2 user_account = q_u->uni_name;
2199 uint16 acb_info = q_u->acb_info;
2200 POLICY_HND *user_pol = &r_u->user_pol;
2201 struct samr_info *info = NULL;
2209 /* check this, when giving away 'add computer to domain' privs */
2210 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2211 BOOL can_add_account = False;
2214 /* Get the domain SID stored in the domain policy */
2215 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2216 return NT_STATUS_INVALID_HANDLE;
2218 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2222 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2223 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2224 this parameter is not an account type */
2225 return NT_STATUS_INVALID_PARAMETER;
2228 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2229 strlower_m(account);
2231 pdb_init_sam(&sam_pass);
2234 ret = pdb_getsampwnam(sam_pass, account);
2237 /* this account exists: say so */
2238 pdb_free_sam(&sam_pass);
2239 return NT_STATUS_USER_EXISTS;
2242 pdb_free_sam(&sam_pass);
2244 /*********************************************************************
2245 * HEADS UP! If we have to create a new user account, we have to get
2246 * a new RID from somewhere. This used to be done by the passdb
2247 * backend. It has been moved into idmap now. Since idmap is now
2248 * wrapped up behind winbind, this means you have to run winbindd if you
2249 * want new accounts to get a new RID when "enable rid algorithm = no".
2250 * Tough. We now have a uniform way of allocating RIDs regardless
2251 * of what ever passdb backend people may use.
2252 * --jerry (2003-07-10)
2253 *********************************************************************/
2255 pw = Get_Pwnam(account);
2257 /* determine which user right we need to check based on the acb_info */
2259 if ( acb_info & ACB_WSTRUST )
2261 pstrcpy(add_script, lp_addmachine_script());
2262 se_priv_copy( &se_rights, &se_machine_account );
2263 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2265 else if ( acb_info & ACB_NORMAL )
2267 pstrcpy(add_script, lp_adduser_script());
2268 se_priv_copy( &se_rights, &se_add_users );
2269 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2271 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) )
2273 pstrcpy(add_script, lp_addmachine_script());
2274 if ( lp_enable_privileges() ) {
2275 /* only Domain Admins can add a BDC or domain trust */
2276 se_priv_copy( &se_rights, &se_priv_none );
2277 can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2281 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2282 p->pipe_user_name, can_add_account ? "True":"False" ));
2284 /********** BEGIN Admin BLOCK **********/
2286 if ( can_add_account )
2293 all_string_sub(add_script, "%u", account, sizeof(add_script));
2294 add_ret = smbrun(add_script,NULL);
2295 DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2297 else /* no add user script -- ask winbindd to do it */
2299 if ( !winbind_create_user( account, &new_rid ) ) {
2300 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2307 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2309 flush_pwnam_cache();
2310 nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2312 /* this code is order such that we have no unnecessary retuns
2313 out of the admin block of code */
2315 if ( NT_STATUS_IS_OK(nt_status) ) {
2316 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2318 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2319 pdb_free_sam(&sam_pass);
2320 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2322 nt_status = NT_STATUS_ACCESS_DENIED;
2326 if ( can_add_account )
2329 /********** END Admin BLOCK **********/
2331 /* now check for failure */
2333 if ( !NT_STATUS_IS_OK(nt_status) )
2336 /* Get the user's SID */
2338 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2340 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2341 se_map_generic(&des_access, &usr_generic_mapping);
2343 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2344 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2345 &acc_granted, "_samr_create_user");
2347 if ( !NT_STATUS_IS_OK(nt_status) ) {
2351 /* associate the user's SID with the new handle. */
2352 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2353 pdb_free_sam(&sam_pass);
2354 return NT_STATUS_NO_MEMORY;
2359 info->acc_granted = acc_granted;
2361 /* get a (unique) handle. open a policy on it. */
2362 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2363 pdb_free_sam(&sam_pass);
2364 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2367 r_u->user_rid=pdb_get_user_rid(sam_pass);
2369 r_u->access_granted = acc_granted;
2371 pdb_free_sam(&sam_pass);
2373 return NT_STATUS_OK;
2376 /*******************************************************************
2377 samr_reply_connect_anon
2378 ********************************************************************/
2380 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2382 struct samr_info *info = NULL;
2383 uint32 des_access = q_u->access_mask;
2387 if (!pipe_access_check(p)) {
2388 DEBUG(3, ("access denied to samr_connect_anon\n"));
2389 r_u->status = NT_STATUS_ACCESS_DENIED;
2393 /* set up the SAMR connect_anon response */
2395 r_u->status = NT_STATUS_OK;
2397 /* associate the user's SID with the new handle. */
2398 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2399 return NT_STATUS_NO_MEMORY;
2401 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2402 was observed from a win98 client trying to enumerate users (when configured
2403 user level access control on shares) --jerry */
2405 se_map_generic( &des_access, &sam_generic_mapping );
2406 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2408 info->status = q_u->unknown_0;
2410 /* get a (unique) handle. open a policy on it. */
2411 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2412 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2417 /*******************************************************************
2419 ********************************************************************/
2421 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2423 struct samr_info *info = NULL;
2424 SEC_DESC *psd = NULL;
2426 uint32 des_access = q_u->access_mask;
2431 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2435 if (!pipe_access_check(p)) {
2436 DEBUG(3, ("access denied to samr_connect\n"));
2437 r_u->status = NT_STATUS_ACCESS_DENIED;
2441 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2442 se_map_generic(&des_access, &sam_generic_mapping);
2444 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2445 NULL, 0, des_access, &acc_granted, "_samr_connect");
2447 if ( !NT_STATUS_IS_OK(nt_status) )
2450 r_u->status = NT_STATUS_OK;
2452 /* associate the user's SID and access granted with the new handle. */
2453 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2454 return NT_STATUS_NO_MEMORY;
2456 info->acc_granted = acc_granted;
2457 info->status = q_u->access_mask;
2459 /* get a (unique) handle. open a policy on it. */
2460 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2461 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2463 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2468 /*******************************************************************
2470 ********************************************************************/
2472 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2474 struct samr_info *info = NULL;
2475 SEC_DESC *psd = NULL;
2477 uint32 des_access = q_u->access_mask;
2482 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2486 if (!pipe_access_check(p)) {
2487 DEBUG(3, ("access denied to samr_connect4\n"));
2488 r_u->status = NT_STATUS_ACCESS_DENIED;
2492 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2493 se_map_generic(&des_access, &sam_generic_mapping);
2495 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2496 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2498 if ( !NT_STATUS_IS_OK(nt_status) )
2501 r_u->status = NT_STATUS_OK;
2503 /* associate the user's SID and access granted with the new handle. */
2504 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2505 return NT_STATUS_NO_MEMORY;
2507 info->acc_granted = acc_granted;
2508 info->status = q_u->access_mask;
2510 /* get a (unique) handle. open a policy on it. */
2511 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2512 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2514 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2519 /**********************************************************************
2520 api_samr_lookup_domain
2521 **********************************************************************/
2523 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2525 struct samr_info *info;
2526 fstring domain_name;
2529 r_u->status = NT_STATUS_OK;
2531 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2532 return NT_STATUS_INVALID_HANDLE;
2534 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2535 Reverted that change so we will work with RAS servers again */
2537 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2538 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
2543 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2547 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2548 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2551 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2553 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2558 /******************************************************************
2559 makes a SAMR_R_ENUM_DOMAINS structure.
2560 ********************************************************************/
2562 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2563 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2569 DEBUG(5, ("make_enum_domains\n"));
2572 *pp_uni_name = NULL;
2574 if (num_sam_entries == 0)
2577 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2578 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2580 if (sam == NULL || uni_name == NULL)
2583 for (i = 0; i < num_sam_entries; i++) {
2584 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2585 init_sam_entry(&sam[i], &uni_name[i], 0);
2589 *pp_uni_name = uni_name;
2594 /**********************************************************************
2595 api_samr_enum_domains
2596 **********************************************************************/
2598 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2600 struct samr_info *info;
2601 uint32 num_entries = 2;
2605 r_u->status = NT_STATUS_OK;
2607 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2608 return NT_STATUS_INVALID_HANDLE;
2610 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2614 name = get_global_sam_name();
2616 fstrcpy(dom[0],name);
2618 fstrcpy(dom[1],"Builtin");
2620 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2621 return NT_STATUS_NO_MEMORY;
2623 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2628 /*******************************************************************
2630 ********************************************************************/
2632 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2635 POLICY_HND domain_pol = q_u->dom_pol;
2636 uint32 alias_rid = q_u->rid_alias;
2637 POLICY_HND *alias_pol = &r_u->pol;
2638 struct samr_info *info = NULL;
2639 SEC_DESC *psd = NULL;
2641 uint32 des_access = q_u->access_mask;
2646 r_u->status = NT_STATUS_OK;
2648 /* find the domain policy and get the SID / access bits stored in the domain policy */
2650 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2651 return NT_STATUS_INVALID_HANDLE;
2653 status = access_check_samr_function(acc_granted,
2654 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2656 if ( !NT_STATUS_IS_OK(status) )
2659 /* append the alias' RID to it */
2661 if (!sid_append_rid(&sid, alias_rid))
2662 return NT_STATUS_NO_SUCH_USER;
2664 /*check if access can be granted as requested by client. */
2666 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2667 se_map_generic(&des_access,&ali_generic_mapping);
2669 se_priv_add( &se_rights, &se_add_users );
2672 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2673 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
2674 &acc_granted, "_samr_open_alias");
2676 if ( !NT_STATUS_IS_OK(status) )
2680 * we should check if the rid really exist !!!
2684 /* associate the user's SID with the new handle. */
2685 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2686 return NT_STATUS_NO_MEMORY;
2688 info->acc_granted = acc_granted;
2690 /* get a (unique) handle. open a policy on it. */
2691 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2692 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2697 /*******************************************************************
2699 ********************************************************************/
2701 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2704 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2709 /* FIX ME: check if the value is really changed --metze */
2710 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2715 if(!pdb_update_sam_account(pwd)) {
2725 /*******************************************************************
2727 ********************************************************************/
2729 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2733 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2738 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2742 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2746 if (!pdb_set_pass_changed_now (pwd)) {
2751 if(!pdb_update_sam_account(pwd)) {
2760 /*******************************************************************
2761 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2762 ********************************************************************/
2763 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2768 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2770 DEBUG(2,("Could not get gid for primary group of "
2771 "user %s\n", pdb_get_username(sampass)));
2775 grp = getgrgid(gid);
2778 DEBUG(2,("Could not find primary group %lu for "
2779 "user %s\n", (unsigned long)gid,
2780 pdb_get_username(sampass)));
2784 if (smb_set_primary_group(grp->gr_name,
2785 pdb_get_username(sampass)) != 0) {
2786 DEBUG(2,("Could not set primary group for user %s to "
2788 pdb_get_username(sampass), grp->gr_name));
2796 /*******************************************************************
2798 ********************************************************************/
2800 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2803 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2807 copy_id20_to_sam_passwd(pwd, id20);
2809 /* write the change out */
2810 if(!pdb_update_sam_account(pwd)) {
2819 /*******************************************************************
2821 ********************************************************************/
2823 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2827 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2831 copy_id21_to_sam_passwd(pwd, id21);
2834 * The funny part about the previous two calls is
2835 * that pwd still has the password hashes from the
2836 * passdb entry. These have not been updated from
2837 * id21. I don't know if they need to be set. --jerry
2840 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2841 set_unix_primary_group(pwd);
2843 /* write the change out */
2844 if(!pdb_update_sam_account(pwd)) {
2854 /*******************************************************************
2856 ********************************************************************/
2858 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2860 pstring plaintext_buf;
2865 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2869 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2870 pdb_get_username(pwd)));
2872 acct_ctrl = pdb_get_acct_ctrl(pwd);
2874 if (!decode_pw_buffer(id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2879 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2884 copy_id23_to_sam_passwd(pwd, id23);
2886 /* if it's a trust account, don't update /etc/passwd */
2887 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2888 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2889 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2890 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2892 /* update the UNIX password */
2893 if (lp_unix_password_sync() ) {
2894 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2896 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2899 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2906 ZERO_STRUCT(plaintext_buf);
2908 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2909 set_unix_primary_group(pwd);
2911 if(!pdb_update_sam_account(pwd)) {
2921 /*******************************************************************
2923 ********************************************************************/
2925 static BOOL set_user_info_pw(uint8 *pass, SAM_ACCOUNT *pwd)
2928 pstring plaintext_buf;
2931 DEBUG(5, ("Attempting administrator password change for user %s\n",
2932 pdb_get_username(pwd)));
2934 acct_ctrl = pdb_get_acct_ctrl(pwd);
2936 ZERO_STRUCT(plaintext_buf);
2938 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2943 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2948 /* if it's a trust account, don't update /etc/passwd */
2949 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2950 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2951 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2952 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2954 /* update the UNIX password */
2955 if (lp_unix_password_sync()) {
2956 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2958 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2961 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2968 ZERO_STRUCT(plaintext_buf);
2970 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2972 /* update the SAMBA password */
2973 if(!pdb_update_sam_account(pwd)) {
2983 /*******************************************************************
2984 samr_reply_set_userinfo
2985 ********************************************************************/
2987 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2989 SAM_ACCOUNT *pwd = NULL;
2991 POLICY_HND *pol = &q_u->pol;
2992 uint16 switch_value = q_u->switch_value;
2993 SAM_USERINFO_CTR *ctr = q_u->ctr;
2995 uint32 acc_required;
2997 BOOL has_enough_rights = False;
3000 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3002 r_u->status = NT_STATUS_OK;
3004 /* find the policy handle. open a policy on it. */
3005 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3006 return NT_STATUS_INVALID_HANDLE;
3008 /* observed when joining an XP client to a Samba domain */
3010 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3012 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3016 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3019 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3020 return NT_STATUS_INVALID_INFO_CLASS;
3026 ret = pdb_getsampwsid(pwd, &sid);
3031 return NT_STATUS_NO_SUCH_USER;
3034 /* deal with machine password changes differently from userinfo changes */
3035 /* check to see if we have the sufficient rights */
3037 acb_info = pdb_get_acct_ctrl(pwd);
3038 if ( acb_info & ACB_WSTRUST )
3039 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3040 else if ( acb_info & ACB_NORMAL )
3041 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3042 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3043 if ( lp_enable_privileges() )
3044 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3047 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3048 p->pipe_user_name, has_enough_rights ? "" : " not"));
3050 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3052 if ( has_enough_rights )
3055 /* ok! user info levels (lots: see MSDEV help), off we go... */
3057 switch (switch_value) {
3059 if (!set_user_info_12(ctr->info.id12, pwd))
3060 r_u->status = NT_STATUS_ACCESS_DENIED;
3064 if (!p->session_key.length) {
3065 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3067 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3069 dump_data(100, (char *)ctr->info.id24->pass, 516);
3071 if (!set_user_info_pw(ctr->info.id24->pass, pwd))
3072 r_u->status = NT_STATUS_ACCESS_DENIED;
3078 * Currently we don't really know how to unmarshall
3079 * the level 25 struct, and the password encryption
3080 * is different. This is a placeholder for when we
3081 * do understand it. In the meantime just return INVALID
3082 * info level and W2K SP2 drops down to level 23... JRA.
3085 if (!p->session_key.length) {
3086 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3088 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3090 dump_data(100, (char *)ctr->info.id25->pass, 532);
3092 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3093 r_u->status = NT_STATUS_ACCESS_DENIED;
3096 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3100 if (!p->session_key.length) {
3101 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3103 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3105 dump_data(100, (char *)ctr->info.id23->pass, 516);
3107 if (!set_user_info_23(ctr->info.id23, pwd))
3108 r_u->status = NT_STATUS_ACCESS_DENIED;
3112 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3116 if ( has_enough_rights )
3119 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3124 /*******************************************************************
3125 samr_reply_set_userinfo2
3126 ********************************************************************/
3128 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3130 SAM_ACCOUNT *pwd = NULL;
3132 SAM_USERINFO_CTR *ctr = q_u->ctr;
3133 POLICY_HND *pol = &q_u->pol;
3134 uint16 switch_value = q_u->switch_value;
3136 uint32 acc_required;
3138 BOOL has_enough_rights = False;
3141 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3143 r_u->status = NT_STATUS_OK;
3145 /* find the policy handle. open a policy on it. */
3146 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3147 return NT_STATUS_INVALID_HANDLE;
3149 /* observed when joining XP client to Samba domain */
3151 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3153 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3157 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3160 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3161 return NT_STATUS_INVALID_INFO_CLASS;
3164 switch_value=ctr->switch_value;
3169 ret = pdb_getsampwsid(pwd, &sid);
3174 return NT_STATUS_NO_SUCH_USER;
3177 acb_info = pdb_get_acct_ctrl(pwd);
3178 if ( acb_info & ACB_WSTRUST )
3179 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3180 else if ( acb_info & ACB_NORMAL )
3181 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3182 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3183 if ( lp_enable_privileges() )
3184 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3187 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3188 p->pipe_user_name, has_enough_rights ? "" : " not"));
3190 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3192 if ( has_enough_rights )
3195 /* ok! user info levels (lots: see MSDEV help), off we go... */
3197 switch (switch_value) {
3199 if (!set_user_info_10(ctr->info.id10, pwd))
3200 r_u->status = NT_STATUS_ACCESS_DENIED;
3203 /* Used by AS/U JRA. */
3204 if (!set_user_info_12(ctr->info.id12, pwd))
3205 r_u->status = NT_STATUS_ACCESS_DENIED;
3208 if (!set_user_info_20(ctr->info.id20, pwd))
3209 r_u->status = NT_STATUS_ACCESS_DENIED;
3212 if (!set_user_info_21(ctr->info.id21, pwd))
3213 return NT_STATUS_ACCESS_DENIED;
3216 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3219 if ( has_enough_rights )
3222 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3227 /*********************************************************************
3228 _samr_query_aliasmem
3229 *********************************************************************/
3231 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3235 struct samr_info *info = NULL;
3244 r_u->status = NT_STATUS_OK;
3246 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3248 /* find the policy handle. open a policy on it. */
3249 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3250 return NT_STATUS_INVALID_HANDLE;
3252 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3253 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3255 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3256 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3257 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3258 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3262 if (!sid_check_is_domain(&info->sid) &&
3263 !sid_check_is_builtin(&info->sid))
3264 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3266 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3268 if (members == NULL)
3269 return NT_STATUS_NO_MEMORY;
3271 for (i=0; i<q_u->num_sids1; i++)
3272 sid_copy(&members[i], &q_u->sid[i].sid);
3278 res = pdb_enum_alias_memberships(p->mem_ctx, &info->sid, members,
3280 &alias_rids, &num_alias_rids);
3284 return NT_STATUS_UNSUCCESSFUL;
3286 init_samr_r_query_useraliases(r_u, num_alias_rids, alias_rids,
3288 return NT_STATUS_OK;
3291 /*********************************************************************
3292 _samr_query_aliasmem
3293 *********************************************************************/
3295 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3307 /* find the policy handle. open a policy on it. */
3308 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3309 return NT_STATUS_INVALID_HANDLE;
3311 if (!NT_STATUS_IS_OK(r_u->status =
3312 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3316 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3318 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3319 return NT_STATUS_NO_SUCH_ALIAS;
3321 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3322 if (num_sids!=0 && sid == NULL) {
3324 return NT_STATUS_NO_MEMORY;
3327 for (i = 0; i < num_sids; i++) {
3328 init_dom_sid2(&sid[i], &sids[i]);
3331 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3335 return NT_STATUS_OK;
3338 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3342 for (i=0; i<*num; i++) {
3343 if ((*uids)[i] == uid)
3347 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3352 (*uids)[*num] = uid;
3357 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3361 struct sys_pwent *userlist, *user;
3366 /* We only look at our own sam, so don't care about imported stuff */
3370 if ((grp = getgrgid(gid)) == NULL) {
3375 /* Primary group members */
3377 userlist = getpwent_list();
3379 for (user = userlist; user != NULL; user = user->next) {
3380 if (user->pw_gid != gid)
3382 add_uid_to_array_unique(user->pw_uid, uids, num);
3385 pwent_free(userlist);
3387 /* Secondary group members */
3389 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3390 struct passwd *pw = getpwnam(*gr);
3394 add_uid_to_array_unique(pw->pw_uid, uids, num);
3402 /*********************************************************************
3403 _samr_query_groupmem
3404 *********************************************************************/
3406 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3409 fstring group_sid_str;
3419 /* find the policy handle. open a policy on it. */
3420 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3421 return NT_STATUS_INVALID_HANDLE;
3423 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3427 sid_to_string(group_sid_str, &group_sid);
3428 DEBUG(10, ("sid is %s\n", group_sid_str));
3430 if (!sid_check_is_in_our_domain(&group_sid)) {
3431 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3432 return NT_STATUS_NO_SUCH_GROUP;
3435 DEBUG(10, ("lookup on Domain SID\n"));
3438 result = pdb_enum_group_members(p->mem_ctx, &group_sid,
3439 &rid, &num_members);
3442 if (!NT_STATUS_IS_OK(result))
3445 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_members);
3447 if ((num_members!=0) && (rid==NULL))
3448 return NT_STATUS_NO_MEMORY;
3450 for (i=0; i<num_members; i++)
3451 attr[i] = SID_NAME_USER;
3453 init_samr_r_query_groupmem(r_u, num_members, rid, attr, NT_STATUS_OK);
3455 return NT_STATUS_OK;
3458 /*********************************************************************
3460 *********************************************************************/
3462 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3467 BOOL can_add_accounts;
3471 /* Find the policy handle. Open a policy on it. */
3472 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3473 return NT_STATUS_INVALID_HANDLE;
3475 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3479 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3481 se_priv_copy( &se_rights, &se_add_users );
3482 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3484 /******** BEGIN SeAddUsers BLOCK *********/
3486 if ( can_add_accounts )
3489 ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3491 if ( can_add_accounts )
3494 /******** END SeAddUsers BLOCK *********/
3496 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3499 /*********************************************************************
3501 *********************************************************************/
3503 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3508 BOOL can_add_accounts;
3511 /* Find the policy handle. Open a policy on it. */
3512 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3513 return NT_STATUS_INVALID_HANDLE;
3515 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3519 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3520 sid_string_static(&alias_sid)));
3522 se_priv_copy( &se_rights, &se_add_users );
3523 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3525 /******** BEGIN SeAddUsers BLOCK *********/
3527 if ( can_add_accounts )
3530 ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3532 if ( can_add_accounts )
3535 /******** END SeAddUsers BLOCK *********/
3537 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3540 /*********************************************************************
3542 *********************************************************************/
3544 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3548 fstring group_sid_str;
3555 SAM_ACCOUNT *sam_user=NULL;
3559 BOOL can_add_accounts;
3561 /* Find the policy handle. Open a policy on it. */
3562 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3563 return NT_STATUS_INVALID_HANDLE;
3565 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3569 sid_to_string(group_sid_str, &group_sid);
3570 DEBUG(10, ("sid is %s\n", group_sid_str));
3572 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3573 return NT_STATUS_NO_SUCH_GROUP;
3575 DEBUG(10, ("lookup on Domain SID\n"));
3577 if(!get_domain_group_from_sid(group_sid, &map))
3578 return NT_STATUS_NO_SUCH_GROUP;
3580 sid_copy(&user_sid, get_global_sam_sid());
3581 sid_append_rid(&user_sid, q_u->rid);
3583 ret = pdb_init_sam(&sam_user);
3584 if (!NT_STATUS_IS_OK(ret))
3587 check = pdb_getsampwsid(sam_user, &user_sid);
3589 if (check != True) {
3590 pdb_free_sam(&sam_user);
3591 return NT_STATUS_NO_SUCH_USER;
3594 /* check a real user exist before we run the script to add a user to a group */
3595 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3596 pdb_free_sam(&sam_user);
3597 return NT_STATUS_NO_SUCH_USER;
3600 pdb_free_sam(&sam_user);
3602 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3603 return NT_STATUS_NO_SUCH_USER;
3606 if ((grp=getgrgid(map.gid)) == NULL) {
3608 return NT_STATUS_NO_SUCH_GROUP;
3611 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3612 fstrcpy(grp_name, grp->gr_name);
3614 /* if the user is already in the group */
3615 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3617 return NT_STATUS_MEMBER_IN_GROUP;
3620 se_priv_copy( &se_rights, &se_add_users );
3621 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3623 /******** BEGIN SeAddUsers BLOCK *********/
3625 if ( can_add_accounts )
3629 * ok, the group exist, the user exist, the user is not in the group,
3631 * we can (finally) add it to the group !
3634 smb_add_user_group(grp_name, pwd->pw_name);
3636 if ( can_add_accounts )
3639 /******** END SeAddUsers BLOCK *********/
3641 /* check if the user has been added then ... */
3642 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3644 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3648 return NT_STATUS_OK;
3651 /*********************************************************************
3653 *********************************************************************/
3655 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3659 SAM_ACCOUNT *sam_pass=NULL;
3665 BOOL can_add_accounts;
3668 * delete the group member named q_u->rid
3669 * who is a member of the sid associated with the handle
3670 * the rid is a user's rid as the group is a domain group.
3673 /* Find the policy handle. Open a policy on it. */
3674 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3675 return NT_STATUS_INVALID_HANDLE;
3677 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3681 if (!sid_check_is_in_our_domain(&group_sid))
3682 return NT_STATUS_NO_SUCH_GROUP;
3684 sid_copy(&user_sid, get_global_sam_sid());
3685 sid_append_rid(&user_sid, q_u->rid);
3687 if (!get_domain_group_from_sid(group_sid, &map))
3688 return NT_STATUS_NO_SUCH_GROUP;
3690 if ((grp=getgrgid(map.gid)) == NULL)
3691 return NT_STATUS_NO_SUCH_GROUP;
3693 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3694 fstrcpy(grp_name, grp->gr_name);
3696 /* check if the user exists before trying to remove it from the group */
3697 pdb_init_sam(&sam_pass);
3698 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3699 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3700 pdb_free_sam(&sam_pass);
3701 return NT_STATUS_NO_SUCH_USER;
3704 /* if the user is not in the group */
3705 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3706 pdb_free_sam(&sam_pass);
3707 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3711 se_priv_copy( &se_rights, &se_add_users );
3712 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3714 /******** BEGIN SeAddUsers BLOCK *********/
3716 if ( can_add_accounts )
3719 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3721 if ( can_add_accounts )
3724 /******** END SeAddUsers BLOCK *********/
3726 /* check if the user has been removed then ... */
3727 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3728 pdb_free_sam(&sam_pass);
3729 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3732 pdb_free_sam(&sam_pass);
3733 return NT_STATUS_OK;
3737 /****************************************************************************
3738 Delete a UNIX user on demand.
3739 ****************************************************************************/
3741 static int smb_delete_user(const char *unix_user)
3746 /* try winbindd first since it is impossible to determine where
3747 a user came from via NSS. Try the delete user script if this fails
3748 meaning the user did not exist in winbindd's list of accounts */
3750 if ( winbind_delete_user( unix_user ) ) {
3751 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3756 /* fall back to 'delete user script' */
3758 pstrcpy(del_script, lp_deluser_script());
3761 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3762 ret = smbrun(del_script,NULL);
3763 flush_pwnam_cache();
3764 DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3769 /*********************************************************************
3770 _samr_delete_dom_user
3771 *********************************************************************/
3773 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3776 SAM_ACCOUNT *sam_pass=NULL;
3778 BOOL can_add_accounts;
3781 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3783 /* Find the policy handle. Open a policy on it. */
3784 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3785 return NT_STATUS_INVALID_HANDLE;
3787 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3791 if (!sid_check_is_in_our_domain(&user_sid))
3792 return NT_STATUS_CANNOT_DELETE;
3794 /* check if the user exists before trying to delete */
3795 pdb_init_sam(&sam_pass);
3796 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3797 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3798 sid_string_static(&user_sid)));
3799 pdb_free_sam(&sam_pass);
3800 return NT_STATUS_NO_SUCH_USER;
3803 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3805 /******** BEGIN SeAddUsers BLOCK *********/
3807 if ( can_add_accounts )
3810 /* First delete the samba side....
3811 code is order to prevent unnecessary returns out of the admin
3814 if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3816 * Now delete the unix side ....
3817 * note: we don't check if the delete really happened
3818 * as the script is not necessary present
3819 * and maybe the sysadmin doesn't want to delete the unix side
3821 smb_delete_user( pdb_get_username(sam_pass) );
3824 if ( can_add_accounts )
3827 /******** END SeAddUsers BLOCK *********/
3830 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3831 pdb_free_sam(&sam_pass);
3832 return NT_STATUS_CANNOT_DELETE;
3836 pdb_free_sam(&sam_pass);
3838 if (!close_policy_hnd(p, &q_u->user_pol))
3839 return NT_STATUS_OBJECT_NAME_INVALID;
3841 return NT_STATUS_OK;
3844 /*********************************************************************
3845 _samr_delete_dom_group
3846 *********************************************************************/
3848 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3853 fstring group_sid_str;
3859 BOOL can_add_accounts;
3862 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3864 /* Find the policy handle. Open a policy on it. */
3865 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3866 return NT_STATUS_INVALID_HANDLE;
3868 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3872 sid_copy(&dom_sid, &group_sid);
3873 sid_to_string(group_sid_str, &dom_sid);
3874 sid_split_rid(&dom_sid, &group_rid);
3876 DEBUG(10, ("sid is %s\n", group_sid_str));
3878 /* we check if it's our SID before deleting */
3879 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3880 return NT_STATUS_NO_SUCH_GROUP;
3882 DEBUG(10, ("lookup on Domain SID\n"));
3884 if(!get_domain_group_from_sid(group_sid, &map))
3885 return NT_STATUS_NO_SUCH_GROUP;
3889 /* check if group really exists */
3890 if ( (grp=getgrgid(gid)) == NULL)
3891 return NT_STATUS_NO_SUCH_GROUP;
3893 se_priv_copy( &se_rights, &se_add_users );
3894 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3896 /******** BEGIN SeAddUsers BLOCK *********/
3898 if ( can_add_accounts )
3901 /* delete mapping first */
3903 if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3904 smb_delete_group( grp->gr_name );
3907 if ( can_add_accounts )
3910 /******** END SeAddUsers BLOCK *********/
3913 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
3915 return NT_STATUS_ACCESS_DENIED;
3918 /* don't check that the unix group has been deleted. Work like
3919 _samr_delet_dom_user() */
3921 if (!close_policy_hnd(p, &q_u->group_pol))
3922 return NT_STATUS_OBJECT_NAME_INVALID;
3924 return NT_STATUS_OK;
3927 /*********************************************************************
3928 _samr_delete_dom_alias
3929 *********************************************************************/
3931 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3936 BOOL can_add_accounts;
3939 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3941 /* Find the policy handle. Open a policy on it. */
3942 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3943 return NT_STATUS_INVALID_HANDLE;
3945 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3949 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3951 if (!sid_check_is_in_our_domain(&alias_sid))
3952 return NT_STATUS_NO_SUCH_ALIAS;
3954 DEBUG(10, ("lookup on Local SID\n"));
3956 se_priv_copy( &se_rights, &se_add_users );
3957 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3959 /******** BEGIN SeAddUsers BLOCK *********/
3961 if ( can_add_accounts )
3964 /* Have passdb delete the alias */
3965 ret = pdb_delete_alias(&alias_sid);
3967 if ( can_add_accounts )
3970 /******** END SeAddUsers BLOCK *********/
3973 return NT_STATUS_ACCESS_DENIED;
3975 if (!close_policy_hnd(p, &q_u->alias_pol))
3976 return NT_STATUS_OBJECT_NAME_INVALID;
3978 return NT_STATUS_OK;
3981 /*********************************************************************
3982 _samr_create_dom_group
3983 *********************************************************************/
3985 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
3992 struct samr_info *info;
3996 BOOL can_add_accounts;
3999 /* Find the policy handle. Open a policy on it. */
4000 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
4001 return NT_STATUS_INVALID_HANDLE;
4003 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4007 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4008 return NT_STATUS_ACCESS_DENIED;
4010 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4012 /* check if group already exist */
4013 if ((grp=getgrnam(name)) != NULL)
4014 return NT_STATUS_GROUP_EXISTS;
4016 se_priv_copy( &se_rights, &se_add_users );
4017 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4019 /******** BEGIN SeAddUsers BLOCK *********/
4021 if ( can_add_accounts )
4024 /* check that we successfully create the UNIX group */
4026 result = NT_STATUS_ACCESS_DENIED;
4027 if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4029 /* so far, so good */
4031 result = NT_STATUS_OK;
4033 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4035 /* add the group to the mapping table */
4037 sid_copy( &info_sid, get_global_sam_sid() );
4038 sid_append_rid( &info_sid, r_u->rid );
4039 sid_to_string( sid_string, &info_sid );
4041 /* reset the error code if we fail to add the mapping entry */
4043 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4044 result = NT_STATUS_ACCESS_DENIED;
4047 if ( can_add_accounts )
4050 /******** END SeAddUsers BLOCK *********/
4052 /* check if we should bail out here */
4054 if ( !NT_STATUS_IS_OK(result) )
4057 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4058 return NT_STATUS_NO_MEMORY;
4060 /* get a (unique) handle. open a policy on it. */
4061 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4062 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4064 return NT_STATUS_OK;
4067 /*********************************************************************
4068 _samr_create_dom_alias
4069 *********************************************************************/
4071 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4076 struct samr_info *info;
4081 BOOL can_add_accounts;
4083 /* Find the policy handle. Open a policy on it. */
4084 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4085 return NT_STATUS_INVALID_HANDLE;
4087 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4091 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4092 return NT_STATUS_ACCESS_DENIED;
4094 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4096 se_priv_copy( &se_rights, &se_add_users );
4097 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4099 /******** BEGIN SeAddUsers BLOCK *********/
4101 if ( can_add_accounts )
4104 /* Have passdb create the alias */
4105 result = pdb_create_alias(name, &r_u->rid);
4107 if ( can_add_accounts )
4110 /******** END SeAddUsers BLOCK *********/
4112 if (!NT_STATUS_IS_OK(result))
4115 sid_copy(&info_sid, get_global_sam_sid());
4116 sid_append_rid(&info_sid, r_u->rid);
4118 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4119 return NT_STATUS_ACCESS_DENIED;
4121 /* check if the group has been successfully created */
4122 if ( getgrgid(gid) == NULL )
4123 return NT_STATUS_ACCESS_DENIED;
4125 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4126 return NT_STATUS_NO_MEMORY;
4128 /* get a (unique) handle. open a policy on it. */
4129 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4130 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4132 return NT_STATUS_OK;
4135 /*********************************************************************
4136 _samr_query_groupinfo
4138 sends the name/comment pair of a domain group
4139 level 1 send also the number of users of that group
4140 *********************************************************************/
4142 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4149 GROUP_INFO_CTR *ctr;
4153 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4154 return NT_STATUS_INVALID_HANDLE;
4156 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4161 ret = get_domain_group_from_sid(group_sid, &map);
4164 return NT_STATUS_INVALID_HANDLE;
4166 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4168 return NT_STATUS_NO_MEMORY;
4170 switch (q_u->switch_level) {
4172 ctr->switch_value1 = 1;
4173 if(!get_memberuids(map.gid, &uids, &num))
4174 return NT_STATUS_NO_SUCH_GROUP;
4176 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4180 ctr->switch_value1 = 3;
4181 init_samr_group_info3(&ctr->group.info3);
4184 ctr->switch_value1 = 4;
4185 init_samr_group_info4(&ctr->group.info4, map.comment);
4188 return NT_STATUS_INVALID_INFO_CLASS;
4191 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4193 return NT_STATUS_OK;
4196 /*********************************************************************
4199 update a domain group's comment.
4200 *********************************************************************/
4202 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4206 GROUP_INFO_CTR *ctr;
4209 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4210 return NT_STATUS_INVALID_HANDLE;
4212 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4216 if (!get_domain_group_from_sid(group_sid, &map))
4217 return NT_STATUS_NO_SUCH_GROUP;
4221 switch (ctr->switch_value1) {
4223 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4226 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4229 return NT_STATUS_INVALID_INFO_CLASS;
4232 if(!pdb_update_group_mapping_entry(&map)) {
4233 return NT_STATUS_NO_SUCH_GROUP;
4236 return NT_STATUS_OK;
4239 /*********************************************************************
4242 update an alias's comment.
4243 *********************************************************************/
4245 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4248 struct acct_info info;
4249 ALIAS_INFO_CTR *ctr;
4252 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4253 return NT_STATUS_INVALID_HANDLE;
4255 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4261 switch (ctr->switch_value1) {
4263 unistr2_to_ascii(info.acct_desc,
4264 &(ctr->alias.info3.uni_acct_desc),
4265 sizeof(info.acct_desc)-1);
4268 return NT_STATUS_INVALID_INFO_CLASS;
4271 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4272 return NT_STATUS_ACCESS_DENIED;
4275 return NT_STATUS_OK;
4278 /*********************************************************************
4279 _samr_get_dom_pwinfo
4280 *********************************************************************/
4282 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4284 /* Perform access check. Since this rpc does not require a
4285 policy handle it will not be caught by the access checks on
4286 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4288 if (!pipe_access_check(p)) {
4289 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4290 r_u->status = NT_STATUS_ACCESS_DENIED;
4294 /* Actually, returning zeros here works quite well :-). */
4296 return NT_STATUS_OK;
4299 /*********************************************************************
4301 *********************************************************************/
4303 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4308 struct samr_info *info;
4309 SEC_DESC *psd = NULL;
4311 uint32 des_access = q_u->access_mask;
4318 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4319 return NT_STATUS_INVALID_HANDLE;
4321 status = access_check_samr_function(acc_granted,
4322 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4324 if ( !NT_STATUS_IS_OK(status) )
4327 /*check if access can be granted as requested by client. */
4328 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4329 se_map_generic(&des_access,&grp_generic_mapping);
4331 se_priv_copy( &se_rights, &se_add_users );
4333 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
4334 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
4335 &acc_granted, "_samr_open_group");
4337 if ( !NT_STATUS_IS_OK(status) )
4340 /* this should not be hard-coded like this */
4342 if (!sid_equal(&sid, get_global_sam_sid()))
4343 return NT_STATUS_ACCESS_DENIED;
4345 sid_copy(&info_sid, get_global_sam_sid());
4346 sid_append_rid(&info_sid, q_u->rid_group);
4347 sid_to_string(sid_string, &info_sid);
4349 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4350 return NT_STATUS_NO_MEMORY;
4352 info->acc_granted = acc_granted;
4354 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4356 /* check if that group really exists */
4358 ret = get_domain_group_from_sid(info->sid, &map);
4361 return NT_STATUS_NO_SUCH_GROUP;
4363 /* get a (unique) handle. open a policy on it. */
4364 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4367 return NT_STATUS_OK;
4370 /*********************************************************************
4371 _samr_remove_sid_foreign_domain
4372 *********************************************************************/
4374 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4375 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4376 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4378 DOM_SID delete_sid, alias_sid;
4379 SAM_ACCOUNT *sam_pass=NULL;
4382 BOOL is_user = False;
4384 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4386 sid_copy( &delete_sid, &q_u->sid.sid );
4388 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4389 sid_string_static(&delete_sid)));
4391 /* Find the policy handle. Open a policy on it. */
4393 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4394 return NT_STATUS_INVALID_HANDLE;
4396 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4397 "_samr_remove_sid_foreign_domain");
4399 if (!NT_STATUS_IS_OK(result))
4402 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4403 sid_string_static(&alias_sid)));
4405 /* make sure we can handle this */
4407 if ( sid_check_is_domain(&alias_sid) )
4408 type = SID_NAME_DOM_GRP;
4409 else if ( sid_check_is_builtin(&alias_sid) )
4410 type = SID_NAME_ALIAS;
4412 if ( type == SID_NAME_UNKNOWN ) {
4413 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4414 return NT_STATUS_OK;
4417 /* check if the user exists before trying to delete */
4419 pdb_init_sam(&sam_pass);
4421 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4424 /* maybe it is a group */
4425 if( !pdb_getgrsid(&map, delete_sid) ) {
4426 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4427 sid_string_static(&delete_sid)));
4428 result = NT_STATUS_INVALID_SID;
4433 /* we can only delete a user from a group since we don't have
4434 nested groups anyways. So in the latter case, just say OK */
4437 GROUP_MAP *mappings = NULL;
4441 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4443 /* interate over the groups */
4444 for ( i=0; i<num_groups; i++ ) {
4446 grp2 = getgrgid(mappings[i].gid);
4449 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4453 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4456 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4458 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4459 /* should we fail here ? */
4460 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4461 pdb_get_username(sam_pass), grp2->gr_name ));
4465 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4466 pdb_get_username(sam_pass), grp2->gr_name ));
4469 SAFE_FREE(mappings);
4473 result = NT_STATUS_OK;
4476 pdb_free_sam(&sam_pass);
4481 /*******************************************************************
4483 ********************************************************************/
4485 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4487 struct samr_info *info = NULL;
4489 uint32 min_pass_len,pass_hist,flag;
4490 time_t u_expire, u_min_age;
4491 NTTIME nt_expire, nt_min_age;
4493 time_t u_lock_duration, u_reset_time;
4494 NTTIME nt_lock_duration, nt_reset_time;
4500 uint32 num_users=0, num_groups=0, num_aliases=0;
4502 uint32 account_policy_temp;
4505 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4506 return NT_STATUS_NO_MEMORY;
4510 r_u->status = NT_STATUS_OK;
4512 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4514 /* find the policy handle. open a policy on it. */
4515 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4516 return NT_STATUS_INVALID_HANDLE;
4518 switch (q_u->switch_value) {
4520 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4521 min_pass_len = account_policy_temp;
4523 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4524 pass_hist = account_policy_temp;
4526 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4527 flag = account_policy_temp;
4529 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4530 u_expire = account_policy_temp;
4532 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4533 u_min_age = account_policy_temp;
4535 unix_to_nt_time_abs(&nt_expire, u_expire);
4536 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4538 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4539 flag, nt_expire, nt_min_age);
4543 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4545 if (!NT_STATUS_IS_OK(r_u->status)) {
4546 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4549 num_users=info->disp_info.num_user_account;
4552 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4553 if (NT_STATUS_IS_ERR(r_u->status)) {
4554 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4557 num_groups=info->disp_info.num_group_account;
4560 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4561 u_logout = account_policy_temp;
4563 unix_to_nt_time_abs(&nt_logout, u_logout);
4565 server_role = ROLE_DOMAIN_PDC;
4566 if (lp_server_role() == ROLE_DOMAIN_BDC)
4567 server_role = ROLE_DOMAIN_BDC;
4569 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4570 init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
4571 num_users, num_groups, num_aliases, nt_logout, server_role);
4574 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4575 u_logout = account_policy_temp;
4577 unix_to_nt_time_abs(&nt_logout, u_logout);
4579 init_unk_info3(&ctr->info.inf3, nt_logout);
4582 init_unk_info5(&ctr->info.inf5, global_myname());
4585 init_unk_info6(&ctr->info.inf6);
4588 server_role = ROLE_DOMAIN_PDC;
4589 if (lp_server_role() == ROLE_DOMAIN_BDC)
4590 server_role = ROLE_DOMAIN_BDC;
4591 init_unk_info7(&ctr->info.inf7, server_role);
4594 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4597 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4598 u_lock_duration = account_policy_temp;
4599 if (u_lock_duration != -1)
4600 u_lock_duration *= 60;
4602 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4603 u_reset_time = account_policy_temp * 60;
4605 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4606 lockout = account_policy_temp;
4608 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4609 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4611 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4614 return NT_STATUS_INVALID_INFO_CLASS;
4617 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4619 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4624 /*******************************************************************
4626 ********************************************************************/
4628 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4630 time_t u_expire, u_min_age;
4632 time_t u_lock_duration, u_reset_time;
4634 r_u->status = NT_STATUS_OK;
4636 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4638 /* find the policy handle. open a policy on it. */
4639 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4640 return NT_STATUS_INVALID_HANDLE;
4642 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4644 switch (q_u->switch_value) {
4646 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4647 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4649 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4650 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4651 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4652 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4653 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4658 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4659 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4668 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4669 if (u_lock_duration != -1)
4670 u_lock_duration /= 60;
4672 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4674 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4675 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4676 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4679 return NT_STATUS_INVALID_INFO_CLASS;
4682 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4684 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));