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, fstring names[],
1468 UNIHDR **pp_hdr_name, UNISTR2 **pp_uni_name)
1471 UNIHDR *hdr_name=NULL;
1472 UNISTR2 *uni_name=NULL;
1474 *pp_uni_name = NULL;
1475 *pp_hdr_name = NULL;
1477 if (num_names != 0) {
1478 hdr_name = TALLOC_ZERO_ARRAY(ctx, UNIHDR, num_names);
1479 if (hdr_name == NULL)
1482 uni_name = TALLOC_ZERO_ARRAY(ctx,UNISTR2, num_names);
1483 if (uni_name == NULL)
1487 for (i = 0; i < num_names; i++) {
1488 DEBUG(10, ("names[%d]:%s\n", i, names[i] ? names[i] : ""));
1489 init_unistr2(&uni_name[i], names[i], UNI_FLAGS_NONE);
1490 init_uni_hdr(&hdr_name[i], &uni_name[i]);
1493 *pp_uni_name = uni_name;
1494 *pp_hdr_name = hdr_name;
1499 /*******************************************************************
1501 ********************************************************************/
1503 NTSTATUS _samr_lookup_rids(pipes_struct *p, SAMR_Q_LOOKUP_RIDS *q_u, SAMR_R_LOOKUP_RIDS *r_u)
1505 fstring group_names[MAX_SAM_ENTRIES];
1506 uint32 *group_attrs = NULL;
1507 UNIHDR *hdr_name = NULL;
1508 UNISTR2 *uni_name = NULL;
1510 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 > MAX_SAM_ENTRIES) {
1523 num_rids = MAX_SAM_ENTRIES;
1524 DEBUG(5,("_samr_lookup_rids: truncating entries to %d\n", num_rids));
1528 if ((group_attrs = TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num_rids )) == NULL)
1529 return NT_STATUS_NO_MEMORY;
1532 r_u->status = NT_STATUS_NONE_MAPPED;
1534 become_root(); /* lookup_sid can require root privs */
1536 for (i = 0; i < num_rids; i++) {
1540 enum SID_NAME_USE type;
1542 group_attrs[i] = SID_NAME_UNKNOWN;
1543 *group_names[i] = '\0';
1545 if (sid_equal(&pol_sid, get_global_sam_sid())) {
1546 sid_copy(&sid, &pol_sid);
1547 sid_append_rid(&sid, q_u->rid[i]);
1549 if (lookup_sid(&sid, domname, tmpname, &type)) {
1550 r_u->status = NT_STATUS_OK;
1551 group_attrs[i] = (uint32)type;
1552 fstrcpy(group_names[i],tmpname);
1553 DEBUG(5,("_samr_lookup_rids: %s:%d\n", group_names[i], group_attrs[i]));
1560 if(!make_samr_lookup_rids(p->mem_ctx, num_rids, group_names, &hdr_name, &uni_name))
1561 return NT_STATUS_NO_MEMORY;
1563 init_samr_r_lookup_rids(r_u, num_rids, hdr_name, uni_name, group_attrs);
1565 DEBUG(5,("_samr_lookup_rids: %d\n", __LINE__));
1570 /*******************************************************************
1571 _samr_open_user. Safe - gives out no passwd info.
1572 ********************************************************************/
1574 NTSTATUS _samr_open_user(pipes_struct *p, SAMR_Q_OPEN_USER *q_u, SAMR_R_OPEN_USER *r_u)
1576 SAM_ACCOUNT *sampass=NULL;
1578 POLICY_HND domain_pol = q_u->domain_pol;
1579 POLICY_HND *user_pol = &r_u->user_pol;
1580 struct samr_info *info = NULL;
1581 SEC_DESC *psd = NULL;
1583 uint32 des_access = q_u->access_mask;
1589 r_u->status = NT_STATUS_OK;
1591 /* find the domain policy handle and get domain SID / access bits in the domain policy. */
1593 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
1594 return NT_STATUS_INVALID_HANDLE;
1596 nt_status = access_check_samr_function( acc_granted,
1597 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" );
1599 if ( !NT_STATUS_IS_OK(nt_status) )
1602 nt_status = pdb_init_sam_talloc(p->mem_ctx, &sampass);
1604 if (!NT_STATUS_IS_OK(nt_status))
1607 /* append the user's RID to it */
1609 if (!sid_append_rid(&sid, q_u->user_rid))
1610 return NT_STATUS_NO_SUCH_USER;
1612 /* check if access can be granted as requested by client. */
1614 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
1615 se_map_generic(&des_access, &usr_generic_mapping);
1617 se_priv_copy( &se_rights, &se_machine_account );
1618 se_priv_add( &se_rights, &se_add_users );
1620 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
1621 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
1622 &acc_granted, "_samr_open_user");
1624 if ( !NT_STATUS_IS_OK(nt_status) )
1628 ret=pdb_getsampwsid(sampass, &sid);
1631 /* check that the SID exists in our domain. */
1633 return NT_STATUS_NO_SUCH_USER;
1636 pdb_free_sam(&sampass);
1638 /* associate the user's SID and access bits with the new handle. */
1639 if ((info = get_samr_info_by_sid(&sid)) == NULL)
1640 return NT_STATUS_NO_MEMORY;
1641 info->acc_granted = acc_granted;
1643 /* get a (unique) handle. open a policy on it. */
1644 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info))
1645 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1650 /*************************************************************************
1651 get_user_info_7. Safe. Only gives out account_name.
1652 *************************************************************************/
1654 static NTSTATUS get_user_info_7(TALLOC_CTX *mem_ctx, SAM_USER_INFO_7 *id7, DOM_SID *user_sid)
1656 SAM_ACCOUNT *smbpass=NULL;
1660 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1662 if (!NT_STATUS_IS_OK(nt_status)) {
1667 ret = pdb_getsampwsid(smbpass, user_sid);
1671 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1672 return NT_STATUS_NO_SUCH_USER;
1675 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1678 init_sam_user_info7(id7, pdb_get_username(smbpass) );
1680 pdb_free_sam(&smbpass);
1682 return NT_STATUS_OK;
1684 /*************************************************************************
1685 get_user_info_10. Safe. Only gives out acb bits.
1686 *************************************************************************/
1688 static NTSTATUS get_user_info_10(TALLOC_CTX *mem_ctx, SAM_USER_INFO_10 *id10, DOM_SID *user_sid)
1690 SAM_ACCOUNT *smbpass=NULL;
1694 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1696 if (!NT_STATUS_IS_OK(nt_status)) {
1701 ret = pdb_getsampwsid(smbpass, user_sid);
1705 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1706 return NT_STATUS_NO_SUCH_USER;
1709 DEBUG(3,("User:[%s]\n", pdb_get_username(smbpass) ));
1712 init_sam_user_info10(id10, pdb_get_acct_ctrl(smbpass) );
1714 pdb_free_sam(&smbpass);
1716 return NT_STATUS_OK;
1719 /*************************************************************************
1720 get_user_info_12. OK - this is the killer as it gives out password info.
1721 Ensure that this is only allowed on an encrypted connection with a root
1723 *************************************************************************/
1725 static NTSTATUS get_user_info_12(pipes_struct *p, TALLOC_CTX *mem_ctx, SAM_USER_INFO_12 * id12, DOM_SID *user_sid)
1727 SAM_ACCOUNT *smbpass=NULL;
1731 if (!p->ntlmssp_auth_validated)
1732 return NT_STATUS_ACCESS_DENIED;
1734 if (!(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) || !(p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL))
1735 return NT_STATUS_ACCESS_DENIED;
1738 * Do *NOT* do become_root()/unbecome_root() here ! JRA.
1741 nt_status = pdb_init_sam_talloc(mem_ctx, &smbpass);
1743 if (!NT_STATUS_IS_OK(nt_status)) {
1747 ret = pdb_getsampwsid(smbpass, user_sid);
1750 DEBUG(4, ("User %s not found\n", sid_string_static(user_sid)));
1751 pdb_free_sam(&smbpass);
1752 return (geteuid() == (uid_t)0) ? NT_STATUS_NO_SUCH_USER : NT_STATUS_ACCESS_DENIED;
1755 DEBUG(3,("User:[%s] 0x%x\n", pdb_get_username(smbpass), pdb_get_acct_ctrl(smbpass) ));
1757 if ( pdb_get_acct_ctrl(smbpass) & ACB_DISABLED) {
1758 pdb_free_sam(&smbpass);
1759 return NT_STATUS_ACCOUNT_DISABLED;
1763 init_sam_user_info12(id12, pdb_get_lanman_passwd(smbpass), pdb_get_nt_passwd(smbpass));
1765 pdb_free_sam(&smbpass);
1767 return NT_STATUS_OK;
1770 /*************************************************************************
1772 *************************************************************************/
1774 static NTSTATUS get_user_info_20(TALLOC_CTX *mem_ctx, SAM_USER_INFO_20 *id20, DOM_SID *user_sid)
1776 SAM_ACCOUNT *sampass=NULL;
1779 pdb_init_sam_talloc(mem_ctx, &sampass);
1782 ret = pdb_getsampwsid(sampass, user_sid);
1786 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1787 return NT_STATUS_NO_SUCH_USER;
1790 samr_clear_sam_passwd(sampass);
1792 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1795 init_sam_user_info20A(id20, sampass);
1797 pdb_free_sam(&sampass);
1799 return NT_STATUS_OK;
1802 /*************************************************************************
1804 *************************************************************************/
1806 static NTSTATUS get_user_info_21(TALLOC_CTX *mem_ctx, SAM_USER_INFO_21 *id21,
1807 DOM_SID *user_sid, DOM_SID *domain_sid)
1809 SAM_ACCOUNT *sampass=NULL;
1813 nt_status = pdb_init_sam_talloc(mem_ctx, &sampass);
1814 if (!NT_STATUS_IS_OK(nt_status)) {
1819 ret = pdb_getsampwsid(sampass, user_sid);
1823 DEBUG(4,("User %s not found\n", sid_string_static(user_sid)));
1824 return NT_STATUS_NO_SUCH_USER;
1827 samr_clear_sam_passwd(sampass);
1829 DEBUG(3,("User:[%s]\n", pdb_get_username(sampass) ));
1832 nt_status = init_sam_user_info21A(id21, sampass, domain_sid);
1834 pdb_free_sam(&sampass);
1836 return NT_STATUS_OK;
1839 /*******************************************************************
1840 _samr_query_userinfo
1841 ********************************************************************/
1843 NTSTATUS _samr_query_userinfo(pipes_struct *p, SAMR_Q_QUERY_USERINFO *q_u, SAMR_R_QUERY_USERINFO *r_u)
1845 SAM_USERINFO_CTR *ctr;
1846 struct samr_info *info = NULL;
1850 r_u->status=NT_STATUS_OK;
1852 /* search for the handle */
1853 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
1854 return NT_STATUS_INVALID_HANDLE;
1856 domain_sid = info->sid;
1858 sid_split_rid(&domain_sid, &rid);
1860 if (!sid_check_is_in_our_domain(&info->sid))
1861 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1863 DEBUG(5,("_samr_query_userinfo: sid:%s\n", sid_string_static(&info->sid)));
1865 ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_USERINFO_CTR);
1867 return NT_STATUS_NO_MEMORY;
1871 /* ok! user info levels (lots: see MSDEV help), off we go... */
1872 ctr->switch_value = q_u->switch_value;
1874 switch (q_u->switch_value) {
1876 ctr->info.id7 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_7);
1877 if (ctr->info.id7 == NULL)
1878 return NT_STATUS_NO_MEMORY;
1880 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_7(p->mem_ctx, ctr->info.id7, &info->sid)))
1884 ctr->info.id10 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_10);
1885 if (ctr->info.id10 == NULL)
1886 return NT_STATUS_NO_MEMORY;
1888 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_10(p->mem_ctx, ctr->info.id10, &info->sid)))
1893 /* whoops - got this wrong. i think. or don't understand what's happening. */
1897 info = (void *)&id11;
1899 expire.low = 0xffffffff;
1900 expire.high = 0x7fffffff;
1902 ctr->info.id = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_11));
1903 ZERO_STRUCTP(ctr->info.id11);
1904 init_sam_user_info11(ctr->info.id11, &expire,
1905 "BROOKFIELDS$", /* name */
1906 0x03ef, /* user rid */
1907 0x201, /* group rid */
1908 0x0080); /* acb info */
1915 ctr->info.id12 = TALLOC_ZERO_P(p->mem_ctx, SAM_USER_INFO_12);
1916 if (ctr->info.id12 == NULL)
1917 return NT_STATUS_NO_MEMORY;
1919 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_12(p, p->mem_ctx, ctr->info.id12, &info->sid)))
1924 ctr->info.id20 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_20);
1925 if (ctr->info.id20 == NULL)
1926 return NT_STATUS_NO_MEMORY;
1927 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_20(p->mem_ctx, ctr->info.id20, &info->sid)))
1932 ctr->info.id21 = TALLOC_ZERO_P(p->mem_ctx,SAM_USER_INFO_21);
1933 if (ctr->info.id21 == NULL)
1934 return NT_STATUS_NO_MEMORY;
1935 if (!NT_STATUS_IS_OK(r_u->status = get_user_info_21(p->mem_ctx, ctr->info.id21,
1936 &info->sid, &domain_sid)))
1941 return NT_STATUS_INVALID_INFO_CLASS;
1944 init_samr_r_query_userinfo(r_u, ctr, r_u->status);
1946 DEBUG(5,("_samr_query_userinfo: %d\n", __LINE__));
1951 /*******************************************************************
1952 samr_reply_query_usergroups
1953 ********************************************************************/
1955 NTSTATUS _samr_query_usergroups(pipes_struct *p, SAMR_Q_QUERY_USERGROUPS *q_u, SAMR_R_QUERY_USERGROUPS *r_u)
1957 SAM_ACCOUNT *sam_pass=NULL;
1958 struct passwd *passwd;
1961 DOM_GID *gids = NULL;
1964 int i, num_gids, num_sids;
1970 * from the SID in the request:
1971 * we should send back the list of DOMAIN GROUPS
1972 * the user is a member of
1974 * and only the DOMAIN GROUPS
1975 * no ALIASES !!! neither aliases of the domain
1976 * nor aliases of the builtin SID
1981 r_u->status = NT_STATUS_OK;
1983 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
1985 /* find the policy handle. open a policy on it. */
1986 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &sid, &acc_granted))
1987 return NT_STATUS_INVALID_HANDLE;
1989 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_USER_GET_GROUPS, "_samr_query_usergroups"))) {
1993 if (!sid_check_is_in_our_domain(&sid))
1994 return NT_STATUS_OBJECT_TYPE_MISMATCH;
1996 pdb_init_sam(&sam_pass);
1999 ret = pdb_getsampwsid(sam_pass, &sid);
2003 pdb_free_sam(&sam_pass);
2004 return NT_STATUS_NO_SUCH_USER;
2007 passwd = getpwnam_alloc(pdb_get_username(sam_pass));
2008 if (passwd == NULL) {
2009 pdb_free_sam(&sam_pass);
2010 return NT_STATUS_NO_SUCH_USER;
2017 result = pdb_enum_group_memberships(pdb_get_username(sam_pass),
2019 &sids, &unix_gids, &num_groups);
2022 pdb_free_sam(&sam_pass);
2023 passwd_free(&passwd);
2025 if (!NT_STATUS_IS_OK(result))
2028 SAFE_FREE(unix_gids);
2033 for (i=0; i<num_groups; i++) {
2036 if (!sid_peek_check_rid(get_global_sam_sid(),
2040 gids = TALLOC_REALLOC_ARRAY(p->mem_ctx, gids, DOM_GID, num_gids+1);
2041 gids[num_gids].attr=7;
2042 gids[num_gids].g_rid = rid;
2047 /* construct the response. lkclXXXX: gids are not copied! */
2048 init_samr_r_query_usergroups(r_u, num_groups, gids, r_u->status);
2050 DEBUG(5,("_samr_query_usergroups: %d\n", __LINE__));
2055 /*******************************************************************
2056 _samr_query_dom_info
2057 ********************************************************************/
2059 NTSTATUS _samr_query_dom_info(pipes_struct *p, SAMR_Q_QUERY_DOMAIN_INFO *q_u, SAMR_R_QUERY_DOMAIN_INFO *r_u)
2061 struct samr_info *info = NULL;
2063 uint32 min_pass_len,pass_hist,flag;
2064 time_t u_expire, u_min_age;
2065 NTTIME nt_expire, nt_min_age;
2067 time_t u_lock_duration, u_reset_time;
2068 NTTIME nt_lock_duration, nt_reset_time;
2074 uint32 account_policy_temp;
2077 uint32 num_users=0, num_groups=0, num_aliases=0;
2079 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2080 return NT_STATUS_NO_MEMORY;
2084 r_u->status = NT_STATUS_OK;
2086 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2088 /* find the policy handle. open a policy on it. */
2089 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2090 return NT_STATUS_INVALID_HANDLE;
2092 switch (q_u->switch_value) {
2095 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2096 min_pass_len = account_policy_temp;
2098 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
2099 pass_hist = account_policy_temp;
2101 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2102 flag = account_policy_temp;
2104 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2105 u_expire = account_policy_temp;
2107 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2108 u_min_age = account_policy_temp;
2110 unix_to_nt_time_abs(&nt_expire, u_expire);
2111 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2113 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2114 flag, nt_expire, nt_min_age);
2118 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2120 if (!NT_STATUS_IS_OK(r_u->status)) {
2121 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2124 num_users=info->disp_info.num_user_account;
2127 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2128 if (!NT_STATUS_IS_OK(r_u->status)) {
2129 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2132 num_groups=info->disp_info.num_group_account;
2135 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
2136 u_logout = account_policy_temp;
2138 unix_to_nt_time_abs(&nt_logout, u_logout);
2140 server_role = ROLE_DOMAIN_PDC;
2141 if (lp_server_role() == ROLE_DOMAIN_BDC)
2142 server_role = ROLE_DOMAIN_BDC;
2144 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2145 init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
2146 num_users, num_groups, num_aliases, nt_logout, server_role);
2149 account_policy_get(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2150 unix_to_nt_time_abs(&nt_logout, u_logout);
2152 init_unk_info3(&ctr->info.inf3, nt_logout);
2155 init_unk_info5(&ctr->info.inf5, global_myname());
2158 init_unk_info6(&ctr->info.inf6);
2161 server_role = ROLE_DOMAIN_PDC;
2162 if (lp_server_role() == ROLE_DOMAIN_BDC)
2163 server_role = ROLE_DOMAIN_BDC;
2165 init_unk_info7(&ctr->info.inf7, server_role);
2168 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2171 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2172 u_lock_duration = account_policy_temp;
2173 if (u_lock_duration != -1)
2174 u_lock_duration *= 60;
2176 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
2177 u_reset_time = account_policy_temp * 60;
2179 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2180 lockout = account_policy_temp;
2182 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2183 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2185 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2188 return NT_STATUS_INVALID_INFO_CLASS;
2191 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2193 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2198 /*******************************************************************
2200 Create an account, can be either a normal user or a machine.
2201 This funcion will need to be updated for bdc/domain trusts.
2202 ********************************************************************/
2204 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2206 SAM_ACCOUNT *sam_pass=NULL;
2210 POLICY_HND dom_pol = q_u->domain_pol;
2211 UNISTR2 user_account = q_u->uni_name;
2212 uint16 acb_info = q_u->acb_info;
2213 POLICY_HND *user_pol = &r_u->user_pol;
2214 struct samr_info *info = NULL;
2222 /* check this, when giving away 'add computer to domain' privs */
2223 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2224 BOOL can_add_account;
2227 /* Get the domain SID stored in the domain policy */
2228 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2229 return NT_STATUS_INVALID_HANDLE;
2231 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2235 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2236 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2237 this parameter is not an account type */
2238 return NT_STATUS_INVALID_PARAMETER;
2241 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2242 strlower_m(account);
2244 pdb_init_sam(&sam_pass);
2247 ret = pdb_getsampwnam(sam_pass, account);
2250 /* this account exists: say so */
2251 pdb_free_sam(&sam_pass);
2252 return NT_STATUS_USER_EXISTS;
2255 pdb_free_sam(&sam_pass);
2257 /*********************************************************************
2258 * HEADS UP! If we have to create a new user account, we have to get
2259 * a new RID from somewhere. This used to be done by the passdb
2260 * backend. It has been moved into idmap now. Since idmap is now
2261 * wrapped up behind winbind, this means you have to run winbindd if you
2262 * want new accounts to get a new RID when "enable rid algorithm = no".
2263 * Tough. We now have a uniform way of allocating RIDs regardless
2264 * of what ever passdb backend people may use.
2265 * --jerry (2003-07-10)
2266 *********************************************************************/
2268 pw = Get_Pwnam(account);
2270 /* determine which user right we need to check based on the acb_info */
2272 if ( acb_info & ACB_WSTRUST )
2274 pstrcpy(add_script, lp_addmachine_script());
2275 se_priv_copy( &se_rights, &se_machine_account );
2276 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2278 else if ( acb_info & ACB_NORMAL )
2280 pstrcpy(add_script, lp_adduser_script());
2281 se_priv_copy( &se_rights, &se_add_users );
2282 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2284 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) )
2286 pstrcpy(add_script, lp_addmachine_script());
2287 if ( lp_enable_privileges() ) {
2288 /* only Domain Admins can add a BDC or domain trust */
2289 se_priv_copy( &se_rights, &se_priv_none );
2290 can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2294 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2295 p->pipe_user_name, can_add_account ? "True":"False" ));
2297 /********** BEGIN Admin BLOCK **********/
2299 if ( can_add_account )
2306 all_string_sub(add_script, "%u", account, sizeof(add_script));
2307 add_ret = smbrun(add_script,NULL);
2308 DEBUG(add_ret ? 0 : 3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2310 else /* no add user script -- ask winbindd to do it */
2312 if ( !winbind_create_user( account, &new_rid ) ) {
2313 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2320 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2322 nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2324 /* this code is order such that we have no unnecessary retuns
2325 out of the admin block of code */
2327 if ( NT_STATUS_IS_OK(nt_status) ) {
2328 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2330 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2331 pdb_free_sam(&sam_pass);
2332 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2334 nt_status = NT_STATUS_ACCESS_DENIED;
2338 if ( can_add_account )
2341 /********** END Admin BLOCK **********/
2343 /* now check for failure */
2345 if ( !NT_STATUS_IS_OK(nt_status) )
2348 /* Get the user's SID */
2350 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2352 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2353 se_map_generic(&des_access, &usr_generic_mapping);
2355 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2356 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2357 &acc_granted, "_samr_create_user");
2359 if ( !NT_STATUS_IS_OK(nt_status) ) {
2363 /* associate the user's SID with the new handle. */
2364 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2365 pdb_free_sam(&sam_pass);
2366 return NT_STATUS_NO_MEMORY;
2371 info->acc_granted = acc_granted;
2373 /* get a (unique) handle. open a policy on it. */
2374 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2375 pdb_free_sam(&sam_pass);
2376 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2379 r_u->user_rid=pdb_get_user_rid(sam_pass);
2381 r_u->access_granted = acc_granted;
2383 pdb_free_sam(&sam_pass);
2385 return NT_STATUS_OK;
2388 /*******************************************************************
2389 samr_reply_connect_anon
2390 ********************************************************************/
2392 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2394 struct samr_info *info = NULL;
2395 uint32 des_access = q_u->access_mask;
2399 if (!pipe_access_check(p)) {
2400 DEBUG(3, ("access denied to samr_connect_anon\n"));
2401 r_u->status = NT_STATUS_ACCESS_DENIED;
2405 /* set up the SAMR connect_anon response */
2407 r_u->status = NT_STATUS_OK;
2409 /* associate the user's SID with the new handle. */
2410 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2411 return NT_STATUS_NO_MEMORY;
2413 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2414 was observed from a win98 client trying to enumerate users (when configured
2415 user level access control on shares) --jerry */
2417 se_map_generic( &des_access, &sam_generic_mapping );
2418 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2420 info->status = q_u->unknown_0;
2422 /* get a (unique) handle. open a policy on it. */
2423 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2424 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2429 /*******************************************************************
2431 ********************************************************************/
2433 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2435 struct samr_info *info = NULL;
2436 SEC_DESC *psd = NULL;
2438 uint32 des_access = q_u->access_mask;
2443 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2447 if (!pipe_access_check(p)) {
2448 DEBUG(3, ("access denied to samr_connect\n"));
2449 r_u->status = NT_STATUS_ACCESS_DENIED;
2453 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2454 se_map_generic(&des_access, &sam_generic_mapping);
2456 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2457 NULL, 0, des_access, &acc_granted, "_samr_connect");
2459 if ( !NT_STATUS_IS_OK(nt_status) )
2462 r_u->status = NT_STATUS_OK;
2464 /* associate the user's SID and access granted with the new handle. */
2465 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2466 return NT_STATUS_NO_MEMORY;
2468 info->acc_granted = acc_granted;
2469 info->status = q_u->access_mask;
2471 /* get a (unique) handle. open a policy on it. */
2472 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2473 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2475 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2480 /*******************************************************************
2482 ********************************************************************/
2484 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2486 struct samr_info *info = NULL;
2487 SEC_DESC *psd = NULL;
2489 uint32 des_access = q_u->access_mask;
2494 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2498 if (!pipe_access_check(p)) {
2499 DEBUG(3, ("access denied to samr_connect4\n"));
2500 r_u->status = NT_STATUS_ACCESS_DENIED;
2504 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2505 se_map_generic(&des_access, &sam_generic_mapping);
2507 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2508 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2510 if ( !NT_STATUS_IS_OK(nt_status) )
2513 r_u->status = NT_STATUS_OK;
2515 /* associate the user's SID and access granted with the new handle. */
2516 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2517 return NT_STATUS_NO_MEMORY;
2519 info->acc_granted = acc_granted;
2520 info->status = q_u->access_mask;
2522 /* get a (unique) handle. open a policy on it. */
2523 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2524 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2526 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2531 /**********************************************************************
2532 api_samr_lookup_domain
2533 **********************************************************************/
2535 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2537 struct samr_info *info;
2538 fstring domain_name;
2541 r_u->status = NT_STATUS_OK;
2543 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2544 return NT_STATUS_INVALID_HANDLE;
2546 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2547 Reverted that change so we will work with RAS servers again */
2549 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2550 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
2555 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2559 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2560 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2563 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2565 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2570 /******************************************************************
2571 makes a SAMR_R_ENUM_DOMAINS structure.
2572 ********************************************************************/
2574 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2575 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2581 DEBUG(5, ("make_enum_domains\n"));
2584 *pp_uni_name = NULL;
2586 if (num_sam_entries == 0)
2589 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2590 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2592 if (sam == NULL || uni_name == NULL)
2595 for (i = 0; i < num_sam_entries; i++) {
2596 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2597 init_sam_entry(&sam[i], &uni_name[i], 0);
2601 *pp_uni_name = uni_name;
2606 /**********************************************************************
2607 api_samr_enum_domains
2608 **********************************************************************/
2610 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2612 struct samr_info *info;
2613 uint32 num_entries = 2;
2617 r_u->status = NT_STATUS_OK;
2619 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2620 return NT_STATUS_INVALID_HANDLE;
2622 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2626 name = get_global_sam_name();
2628 fstrcpy(dom[0],name);
2630 fstrcpy(dom[1],"Builtin");
2632 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2633 return NT_STATUS_NO_MEMORY;
2635 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2640 /*******************************************************************
2642 ********************************************************************/
2644 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2647 POLICY_HND domain_pol = q_u->dom_pol;
2648 uint32 alias_rid = q_u->rid_alias;
2649 POLICY_HND *alias_pol = &r_u->pol;
2650 struct samr_info *info = NULL;
2651 SEC_DESC *psd = NULL;
2653 uint32 des_access = q_u->access_mask;
2658 r_u->status = NT_STATUS_OK;
2660 /* find the domain policy and get the SID / access bits stored in the domain policy */
2662 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2663 return NT_STATUS_INVALID_HANDLE;
2665 status = access_check_samr_function(acc_granted,
2666 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2668 if ( !NT_STATUS_IS_OK(status) )
2671 /* append the alias' RID to it */
2673 if (!sid_append_rid(&sid, alias_rid))
2674 return NT_STATUS_NO_SUCH_USER;
2676 /*check if access can be granted as requested by client. */
2678 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2679 se_map_generic(&des_access,&ali_generic_mapping);
2681 se_priv_add( &se_rights, &se_add_users );
2684 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2685 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
2686 &acc_granted, "_samr_open_alias");
2688 if ( !NT_STATUS_IS_OK(status) )
2692 * we should check if the rid really exist !!!
2696 /* associate the user's SID with the new handle. */
2697 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2698 return NT_STATUS_NO_MEMORY;
2700 info->acc_granted = acc_granted;
2702 /* get a (unique) handle. open a policy on it. */
2703 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2704 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2709 /*******************************************************************
2711 ********************************************************************/
2713 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2716 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2721 /* FIX ME: check if the value is really changed --metze */
2722 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2727 if(!pdb_update_sam_account(pwd)) {
2737 /*******************************************************************
2739 ********************************************************************/
2741 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2745 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2750 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2754 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2758 if (!pdb_set_pass_changed_now (pwd)) {
2763 if(!pdb_update_sam_account(pwd)) {
2772 /*******************************************************************
2773 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2774 ********************************************************************/
2775 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2780 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2782 DEBUG(2,("Could not get gid for primary group of "
2783 "user %s\n", pdb_get_username(sampass)));
2787 grp = getgrgid(gid);
2790 DEBUG(2,("Could not find primary group %lu for "
2791 "user %s\n", (unsigned long)gid,
2792 pdb_get_username(sampass)));
2796 if (smb_set_primary_group(grp->gr_name,
2797 pdb_get_username(sampass)) != 0) {
2798 DEBUG(2,("Could not set primary group for user %s to "
2800 pdb_get_username(sampass), grp->gr_name));
2808 /*******************************************************************
2810 ********************************************************************/
2812 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2815 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2819 copy_id20_to_sam_passwd(pwd, id20);
2821 /* write the change out */
2822 if(!pdb_update_sam_account(pwd)) {
2831 /*******************************************************************
2833 ********************************************************************/
2835 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2839 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2843 copy_id21_to_sam_passwd(pwd, id21);
2846 * The funny part about the previous two calls is
2847 * that pwd still has the password hashes from the
2848 * passdb entry. These have not been updated from
2849 * id21. I don't know if they need to be set. --jerry
2852 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2853 set_unix_primary_group(pwd);
2855 /* write the change out */
2856 if(!pdb_update_sam_account(pwd)) {
2866 /*******************************************************************
2868 ********************************************************************/
2870 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2872 pstring plaintext_buf;
2877 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2881 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2882 pdb_get_username(pwd)));
2884 acct_ctrl = pdb_get_acct_ctrl(pwd);
2886 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2891 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2896 copy_id23_to_sam_passwd(pwd, id23);
2898 /* if it's a trust account, don't update /etc/passwd */
2899 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2900 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2901 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2902 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2904 /* update the UNIX password */
2905 if (lp_unix_password_sync() ) {
2906 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2908 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2911 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2918 ZERO_STRUCT(plaintext_buf);
2920 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2921 set_unix_primary_group(pwd);
2923 if(!pdb_update_sam_account(pwd)) {
2933 /*******************************************************************
2935 ********************************************************************/
2937 static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
2940 pstring plaintext_buf;
2943 DEBUG(5, ("Attempting administrator password change for user %s\n",
2944 pdb_get_username(pwd)));
2946 acct_ctrl = pdb_get_acct_ctrl(pwd);
2948 ZERO_STRUCT(plaintext_buf);
2950 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2955 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2960 /* if it's a trust account, don't update /etc/passwd */
2961 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2962 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2963 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2964 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2966 /* update the UNIX password */
2967 if (lp_unix_password_sync()) {
2968 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2970 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2973 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2980 ZERO_STRUCT(plaintext_buf);
2982 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2984 /* update the SAMBA password */
2985 if(!pdb_update_sam_account(pwd)) {
2995 /*******************************************************************
2996 samr_reply_set_userinfo
2997 ********************************************************************/
2999 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
3001 SAM_ACCOUNT *pwd = NULL;
3003 POLICY_HND *pol = &q_u->pol;
3004 uint16 switch_value = q_u->switch_value;
3005 SAM_USERINFO_CTR *ctr = q_u->ctr;
3007 uint32 acc_required;
3009 BOOL has_enough_rights;
3012 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3014 r_u->status = NT_STATUS_OK;
3016 /* find the policy handle. open a policy on it. */
3017 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3018 return NT_STATUS_INVALID_HANDLE;
3020 /* observed when joining an XP client to a Samba domain */
3022 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3024 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3028 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3031 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3032 return NT_STATUS_INVALID_INFO_CLASS;
3038 ret = pdb_getsampwsid(pwd, &sid);
3043 return NT_STATUS_NO_SUCH_USER;
3046 /* deal with machine password changes differently from userinfo changes */
3047 /* check to see if we have the sufficient rights */
3049 acb_info = pdb_get_acct_ctrl(pwd);
3050 if ( acb_info & ACB_WSTRUST )
3051 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3052 else if ( acb_info & ACB_NORMAL )
3053 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3054 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3055 if ( lp_enable_privileges() )
3056 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3059 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3060 p->pipe_user_name, has_enough_rights ? "" : " not"));
3062 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3064 if ( has_enough_rights )
3067 /* ok! user info levels (lots: see MSDEV help), off we go... */
3069 switch (switch_value) {
3071 if (!set_user_info_12(ctr->info.id12, pwd))
3072 r_u->status = NT_STATUS_ACCESS_DENIED;
3076 if (!p->session_key.length) {
3077 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3079 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3081 dump_data(100, (char *)ctr->info.id24->pass, 516);
3083 if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
3084 r_u->status = NT_STATUS_ACCESS_DENIED;
3090 * Currently we don't really know how to unmarshall
3091 * the level 25 struct, and the password encryption
3092 * is different. This is a placeholder for when we
3093 * do understand it. In the meantime just return INVALID
3094 * info level and W2K SP2 drops down to level 23... JRA.
3097 if (!p->session_key.length) {
3098 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3100 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3102 dump_data(100, (char *)ctr->info.id25->pass, 532);
3104 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3105 r_u->status = NT_STATUS_ACCESS_DENIED;
3108 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3112 if (!p->session_key.length) {
3113 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3115 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3117 dump_data(100, (char *)ctr->info.id23->pass, 516);
3119 if (!set_user_info_23(ctr->info.id23, pwd))
3120 r_u->status = NT_STATUS_ACCESS_DENIED;
3124 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3128 if ( has_enough_rights )
3131 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3136 /*******************************************************************
3137 samr_reply_set_userinfo2
3138 ********************************************************************/
3140 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3142 SAM_ACCOUNT *pwd = NULL;
3144 SAM_USERINFO_CTR *ctr = q_u->ctr;
3145 POLICY_HND *pol = &q_u->pol;
3146 uint16 switch_value = q_u->switch_value;
3148 uint32 acc_required;
3150 BOOL has_enough_rights;
3153 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3155 r_u->status = NT_STATUS_OK;
3157 /* find the policy handle. open a policy on it. */
3158 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3159 return NT_STATUS_INVALID_HANDLE;
3161 /* observed when joining XP client to Samba domain */
3163 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3165 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3169 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3172 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3173 return NT_STATUS_INVALID_INFO_CLASS;
3176 switch_value=ctr->switch_value;
3181 ret = pdb_getsampwsid(pwd, &sid);
3186 return NT_STATUS_NO_SUCH_USER;
3189 acb_info = pdb_get_acct_ctrl(pwd);
3190 if ( acb_info & ACB_WSTRUST )
3191 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_machine_account);
3192 else if ( acb_info & ACB_NORMAL )
3193 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_add_users );
3194 else if ( acb_info & (ACB_SVRTRUST|ACB_DOMTRUST) ) {
3195 if ( lp_enable_privileges() )
3196 has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
3199 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3200 p->pipe_user_name, has_enough_rights ? "" : " not"));
3202 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3204 if ( has_enough_rights )
3207 /* ok! user info levels (lots: see MSDEV help), off we go... */
3209 switch (switch_value) {
3211 if (!set_user_info_10(ctr->info.id10, pwd))
3212 r_u->status = NT_STATUS_ACCESS_DENIED;
3215 /* Used by AS/U JRA. */
3216 if (!set_user_info_12(ctr->info.id12, pwd))
3217 r_u->status = NT_STATUS_ACCESS_DENIED;
3220 if (!set_user_info_20(ctr->info.id20, pwd))
3221 r_u->status = NT_STATUS_ACCESS_DENIED;
3224 if (!set_user_info_21(ctr->info.id21, pwd))
3225 return NT_STATUS_ACCESS_DENIED;
3228 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3231 if ( has_enough_rights )
3234 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3239 /*********************************************************************
3240 _samr_query_aliasmem
3241 *********************************************************************/
3243 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3247 struct samr_info *info = NULL;
3258 r_u->status = NT_STATUS_OK;
3260 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3262 /* find the policy handle. open a policy on it. */
3263 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3264 return NT_STATUS_INVALID_HANDLE;
3266 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3267 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3269 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3270 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3271 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3272 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3276 if (!sid_check_is_domain(&info->sid) &&
3277 !sid_check_is_builtin(&info->sid))
3278 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3280 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3282 if (members == NULL)
3283 return NT_STATUS_NO_MEMORY;
3285 for (i=0; i<q_u->num_sids1; i++)
3286 sid_copy(&members[i], &q_u->sid[i].sid);
3289 res = pdb_enum_alias_memberships(members,
3290 q_u->num_sids1, &aliases,
3295 return NT_STATUS_UNSUCCESSFUL;
3300 for (i=0; i<num_aliases; i++) {
3303 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3306 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3309 return NT_STATUS_NO_MEMORY;
3311 rids[num_groups] = rid;
3316 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3317 return NT_STATUS_OK;
3320 /*********************************************************************
3321 _samr_query_aliasmem
3322 *********************************************************************/
3324 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3336 /* find the policy handle. open a policy on it. */
3337 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3338 return NT_STATUS_INVALID_HANDLE;
3340 if (!NT_STATUS_IS_OK(r_u->status =
3341 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3345 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3347 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3348 return NT_STATUS_NO_SUCH_ALIAS;
3350 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3351 if (num_sids!=0 && sid == NULL) {
3353 return NT_STATUS_NO_MEMORY;
3356 for (i = 0; i < num_sids; i++) {
3357 init_dom_sid2(&sid[i], &sids[i]);
3360 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3364 return NT_STATUS_OK;
3367 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3371 for (i=0; i<*num; i++) {
3372 if ((*uids)[i] == uid)
3376 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3381 (*uids)[*num] = uid;
3386 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3390 struct sys_pwent *userlist, *user;
3395 /* We only look at our own sam, so don't care about imported stuff */
3399 if ((grp = getgrgid(gid)) == NULL) {
3404 /* Primary group members */
3406 userlist = getpwent_list();
3408 for (user = userlist; user != NULL; user = user->next) {
3409 if (user->pw_gid != gid)
3411 add_uid_to_array_unique(user->pw_uid, uids, num);
3414 pwent_free(userlist);
3416 /* Secondary group members */
3418 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3419 struct passwd *pw = getpwnam(*gr);
3423 add_uid_to_array_unique(pw->pw_uid, uids, num);
3431 /*********************************************************************
3432 _samr_query_groupmem
3433 *********************************************************************/
3435 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3437 int final_num_rids, i;
3439 fstring group_sid_str;
3449 /* find the policy handle. open a policy on it. */
3450 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3451 return NT_STATUS_INVALID_HANDLE;
3453 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3457 sid_to_string(group_sid_str, &group_sid);
3458 DEBUG(10, ("sid is %s\n", group_sid_str));
3460 if (!sid_check_is_in_our_domain(&group_sid)) {
3461 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3462 return NT_STATUS_NO_SUCH_GROUP;
3465 DEBUG(10, ("lookup on Domain SID\n"));
3467 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3468 return NT_STATUS_NO_SUCH_GROUP;
3470 if(!get_memberuids(gid, &uids, &num))
3471 return NT_STATUS_NO_SUCH_GROUP;
3473 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3474 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3476 if (num!=0 && (rid==NULL || attr==NULL))
3477 return NT_STATUS_NO_MEMORY;
3481 for (i=0; i<num; i++) {
3484 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3485 DEBUG(1, ("Could not map member uid to SID\n"));
3489 if (!sid_check_is_in_our_domain(&sid)) {
3490 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3491 "in our domain\n"));
3495 sid_peek_rid(&sid, &rid[final_num_rids]);
3497 /* Hmm. In a trace I got the constant 7 here from NT. */
3498 attr[final_num_rids] = SID_NAME_USER;
3500 final_num_rids += 1;
3505 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3508 return NT_STATUS_OK;
3511 /*********************************************************************
3513 *********************************************************************/
3515 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3520 BOOL can_add_accounts;
3524 /* Find the policy handle. Open a policy on it. */
3525 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3526 return NT_STATUS_INVALID_HANDLE;
3528 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3532 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3534 se_priv_copy( &se_rights, &se_add_users );
3535 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3537 /******** BEGIN SeAddUsers BLOCK *********/
3539 if ( can_add_accounts )
3542 ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3544 if ( can_add_accounts )
3547 /******** END SeAddUsers BLOCK *********/
3549 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3552 /*********************************************************************
3554 *********************************************************************/
3556 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3561 BOOL can_add_accounts;
3564 /* Find the policy handle. Open a policy on it. */
3565 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3566 return NT_STATUS_INVALID_HANDLE;
3568 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3572 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3573 sid_string_static(&alias_sid)));
3575 se_priv_copy( &se_rights, &se_add_users );
3576 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3578 /******** BEGIN SeAddUsers BLOCK *********/
3580 if ( can_add_accounts )
3583 ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3585 if ( can_add_accounts )
3588 /******** END SeAddUsers BLOCK *********/
3590 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3593 /*********************************************************************
3595 *********************************************************************/
3597 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3601 fstring group_sid_str;
3608 SAM_ACCOUNT *sam_user=NULL;
3612 BOOL can_add_accounts;
3614 /* Find the policy handle. Open a policy on it. */
3615 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3616 return NT_STATUS_INVALID_HANDLE;
3618 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3622 sid_to_string(group_sid_str, &group_sid);
3623 DEBUG(10, ("sid is %s\n", group_sid_str));
3625 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3626 return NT_STATUS_NO_SUCH_GROUP;
3628 DEBUG(10, ("lookup on Domain SID\n"));
3630 if(!get_domain_group_from_sid(group_sid, &map))
3631 return NT_STATUS_NO_SUCH_GROUP;
3633 sid_copy(&user_sid, get_global_sam_sid());
3634 sid_append_rid(&user_sid, q_u->rid);
3636 ret = pdb_init_sam(&sam_user);
3637 if (!NT_STATUS_IS_OK(ret))
3640 check = pdb_getsampwsid(sam_user, &user_sid);
3642 if (check != True) {
3643 pdb_free_sam(&sam_user);
3644 return NT_STATUS_NO_SUCH_USER;
3647 /* check a real user exist before we run the script to add a user to a group */
3648 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3649 pdb_free_sam(&sam_user);
3650 return NT_STATUS_NO_SUCH_USER;
3653 pdb_free_sam(&sam_user);
3655 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3656 return NT_STATUS_NO_SUCH_USER;
3659 if ((grp=getgrgid(map.gid)) == NULL) {
3661 return NT_STATUS_NO_SUCH_GROUP;
3664 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3665 fstrcpy(grp_name, grp->gr_name);
3667 /* if the user is already in the group */
3668 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3670 return NT_STATUS_MEMBER_IN_GROUP;
3673 se_priv_copy( &se_rights, &se_add_users );
3674 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3676 /******** BEGIN SeAddUsers BLOCK *********/
3678 if ( can_add_accounts )
3682 * ok, the group exist, the user exist, the user is not in the group,
3684 * we can (finally) add it to the group !
3687 smb_add_user_group(grp_name, pwd->pw_name);
3689 if ( can_add_accounts )
3692 /******** END SeAddUsers BLOCK *********/
3694 /* check if the user has been added then ... */
3695 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3697 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3701 return NT_STATUS_OK;
3704 /*********************************************************************
3706 *********************************************************************/
3708 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3712 SAM_ACCOUNT *sam_pass=NULL;
3718 BOOL can_add_accounts;
3721 * delete the group member named q_u->rid
3722 * who is a member of the sid associated with the handle
3723 * the rid is a user's rid as the group is a domain group.
3726 /* Find the policy handle. Open a policy on it. */
3727 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3728 return NT_STATUS_INVALID_HANDLE;
3730 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3734 if (!sid_check_is_in_our_domain(&group_sid))
3735 return NT_STATUS_NO_SUCH_GROUP;
3737 sid_copy(&user_sid, get_global_sam_sid());
3738 sid_append_rid(&user_sid, q_u->rid);
3740 if (!get_domain_group_from_sid(group_sid, &map))
3741 return NT_STATUS_NO_SUCH_GROUP;
3743 if ((grp=getgrgid(map.gid)) == NULL)
3744 return NT_STATUS_NO_SUCH_GROUP;
3746 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3747 fstrcpy(grp_name, grp->gr_name);
3749 /* check if the user exists before trying to remove it from the group */
3750 pdb_init_sam(&sam_pass);
3751 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3752 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3753 pdb_free_sam(&sam_pass);
3754 return NT_STATUS_NO_SUCH_USER;
3757 /* if the user is not in the group */
3758 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3759 pdb_free_sam(&sam_pass);
3760 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3764 se_priv_copy( &se_rights, &se_add_users );
3765 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3767 /******** BEGIN SeAddUsers BLOCK *********/
3769 if ( can_add_accounts )
3772 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3774 if ( can_add_accounts )
3777 /******** END SeAddUsers BLOCK *********/
3779 /* check if the user has been removed then ... */
3780 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3781 pdb_free_sam(&sam_pass);
3782 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3785 pdb_free_sam(&sam_pass);
3786 return NT_STATUS_OK;
3790 /****************************************************************************
3791 Delete a UNIX user on demand.
3792 ****************************************************************************/
3794 static int smb_delete_user(const char *unix_user)
3799 /* try winbindd first since it is impossible to determine where
3800 a user came from via NSS. Try the delete user script if this fails
3801 meaning the user did not exist in winbindd's list of accounts */
3803 if ( winbind_delete_user( unix_user ) ) {
3804 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3809 /* fall back to 'delete user script' */
3811 pstrcpy(del_script, lp_deluser_script());
3814 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3815 ret = smbrun(del_script,NULL);
3816 DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3821 /*********************************************************************
3822 _samr_delete_dom_user
3823 *********************************************************************/
3825 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3828 SAM_ACCOUNT *sam_pass=NULL;
3831 BOOL can_add_accounts;
3834 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3836 /* Find the policy handle. Open a policy on it. */
3837 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3838 return NT_STATUS_INVALID_HANDLE;
3840 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3844 if (!sid_check_is_in_our_domain(&user_sid))
3845 return NT_STATUS_CANNOT_DELETE;
3847 /* check if the user exists before trying to delete */
3848 pdb_init_sam(&sam_pass);
3849 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3850 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3851 sid_string_static(&user_sid)));
3852 pdb_free_sam(&sam_pass);
3853 return NT_STATUS_NO_SUCH_USER;
3856 se_priv_copy( &se_rights, &se_add_users );
3857 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3859 /******** BEGIN SeAddUsers BLOCK *********/
3861 if ( can_add_accounts )
3864 /* First delete the samba side....
3865 code is order to prevent unnecessary returns out of the admin
3868 if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3870 * Now delete the unix side ....
3871 * note: we don't check if the delete really happened
3872 * as the script is not necessary present
3873 * and maybe the sysadmin doesn't want to delete the unix side
3875 smb_delete_user( pdb_get_username(sam_pass) );
3878 if ( can_add_accounts )
3881 /******** END SeAddUsers BLOCK *********/
3884 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3885 pdb_free_sam(&sam_pass);
3886 return NT_STATUS_CANNOT_DELETE;
3890 pdb_free_sam(&sam_pass);
3892 if (!close_policy_hnd(p, &q_u->user_pol))
3893 return NT_STATUS_OBJECT_NAME_INVALID;
3895 return NT_STATUS_OK;
3898 /*********************************************************************
3899 _samr_delete_dom_group
3900 *********************************************************************/
3902 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3907 fstring group_sid_str;
3913 BOOL can_add_accounts;
3916 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3918 /* Find the policy handle. Open a policy on it. */
3919 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3920 return NT_STATUS_INVALID_HANDLE;
3922 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3926 sid_copy(&dom_sid, &group_sid);
3927 sid_to_string(group_sid_str, &dom_sid);
3928 sid_split_rid(&dom_sid, &group_rid);
3930 DEBUG(10, ("sid is %s\n", group_sid_str));
3932 /* we check if it's our SID before deleting */
3933 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3934 return NT_STATUS_NO_SUCH_GROUP;
3936 DEBUG(10, ("lookup on Domain SID\n"));
3938 if(!get_domain_group_from_sid(group_sid, &map))
3939 return NT_STATUS_NO_SUCH_GROUP;
3943 /* check if group really exists */
3944 if ( (grp=getgrgid(gid)) == NULL)
3945 return NT_STATUS_NO_SUCH_GROUP;
3947 se_priv_copy( &se_rights, &se_add_users );
3948 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3950 /******** BEGIN SeAddUsers BLOCK *********/
3952 if ( can_add_accounts )
3955 /* delete mapping first */
3957 if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3958 smb_delete_group( grp->gr_name );
3961 if ( can_add_accounts )
3964 /******** END SeAddUsers BLOCK *********/
3967 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
3969 return NT_STATUS_ACCESS_DENIED;
3972 /* don't check that the unix group has been deleted. Work like
3973 _samr_delet_dom_user() */
3975 if (!close_policy_hnd(p, &q_u->group_pol))
3976 return NT_STATUS_OBJECT_NAME_INVALID;
3978 return NT_STATUS_OK;
3981 /*********************************************************************
3982 _samr_delete_dom_alias
3983 *********************************************************************/
3985 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3990 BOOL can_add_accounts;
3993 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3995 /* Find the policy handle. Open a policy on it. */
3996 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3997 return NT_STATUS_INVALID_HANDLE;
3999 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
4003 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
4005 if (!sid_check_is_in_our_domain(&alias_sid))
4006 return NT_STATUS_NO_SUCH_ALIAS;
4008 DEBUG(10, ("lookup on Local SID\n"));
4010 se_priv_copy( &se_rights, &se_add_users );
4011 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4013 /******** BEGIN SeAddUsers BLOCK *********/
4015 if ( can_add_accounts )
4018 /* Have passdb delete the alias */
4019 ret = pdb_delete_alias(&alias_sid);
4021 if ( can_add_accounts )
4024 /******** END SeAddUsers BLOCK *********/
4027 return NT_STATUS_ACCESS_DENIED;
4029 if (!close_policy_hnd(p, &q_u->alias_pol))
4030 return NT_STATUS_OBJECT_NAME_INVALID;
4032 return NT_STATUS_OK;
4035 /*********************************************************************
4036 _samr_create_dom_group
4037 *********************************************************************/
4039 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4046 struct samr_info *info;
4050 BOOL can_add_accounts;
4053 /* Find the policy handle. Open a policy on it. */
4054 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
4055 return NT_STATUS_INVALID_HANDLE;
4057 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4061 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4062 return NT_STATUS_ACCESS_DENIED;
4064 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4066 /* check if group already exist */
4067 if ((grp=getgrnam(name)) != NULL)
4068 return NT_STATUS_GROUP_EXISTS;
4070 se_priv_copy( &se_rights, &se_add_users );
4071 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4073 /******** BEGIN SeAddUsers BLOCK *********/
4075 if ( can_add_accounts )
4078 /* check that we successfully create the UNIX group */
4080 result = NT_STATUS_ACCESS_DENIED;
4081 if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4083 /* so far, so good */
4085 result = NT_STATUS_OK;
4087 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4089 /* add the group to the mapping table */
4091 sid_copy( &info_sid, get_global_sam_sid() );
4092 sid_append_rid( &info_sid, r_u->rid );
4093 sid_to_string( sid_string, &info_sid );
4095 /* reset the error code if we fail to add the mapping entry */
4097 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4098 result = NT_STATUS_ACCESS_DENIED;
4101 if ( can_add_accounts )
4104 /******** END SeAddUsers BLOCK *********/
4106 /* check if we should bail out here */
4108 if ( !NT_STATUS_IS_OK(result) )
4111 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4112 return NT_STATUS_NO_MEMORY;
4114 /* get a (unique) handle. open a policy on it. */
4115 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4116 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4118 return NT_STATUS_OK;
4121 /*********************************************************************
4122 _samr_create_dom_alias
4123 *********************************************************************/
4125 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4131 struct samr_info *info;
4136 BOOL can_add_accounts;
4138 /* Find the policy handle. Open a policy on it. */
4139 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4140 return NT_STATUS_INVALID_HANDLE;
4142 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4146 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4147 return NT_STATUS_ACCESS_DENIED;
4149 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4151 se_priv_copy( &se_rights, &se_add_users );
4152 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4154 /******** BEGIN SeAddUsers BLOCK *********/
4156 if ( can_add_accounts )
4159 /* Have passdb create the alias */
4160 result = pdb_create_alias(name, &r_u->rid);
4162 if ( can_add_accounts )
4165 /******** END SeAddUsers BLOCK *********/
4167 if (!NT_STATUS_IS_OK(result))
4170 sid_copy(&info_sid, get_global_sam_sid());
4171 sid_append_rid(&info_sid, r_u->rid);
4173 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4174 return NT_STATUS_ACCESS_DENIED;
4176 /* check if the group has been successfully created */
4177 if ((grp=getgrgid(gid)) == NULL)
4178 return NT_STATUS_ACCESS_DENIED;
4180 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4181 return NT_STATUS_NO_MEMORY;
4183 /* get a (unique) handle. open a policy on it. */
4184 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4185 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4187 return NT_STATUS_OK;
4190 /*********************************************************************
4191 _samr_query_groupinfo
4193 sends the name/comment pair of a domain group
4194 level 1 send also the number of users of that group
4195 *********************************************************************/
4197 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4204 GROUP_INFO_CTR *ctr;
4208 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4209 return NT_STATUS_INVALID_HANDLE;
4211 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4216 ret = get_domain_group_from_sid(group_sid, &map);
4219 return NT_STATUS_INVALID_HANDLE;
4221 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4223 return NT_STATUS_NO_MEMORY;
4225 switch (q_u->switch_level) {
4227 ctr->switch_value1 = 1;
4228 if(!get_memberuids(map.gid, &uids, &num))
4229 return NT_STATUS_NO_SUCH_GROUP;
4231 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4235 ctr->switch_value1 = 3;
4236 init_samr_group_info3(&ctr->group.info3);
4239 ctr->switch_value1 = 4;
4240 init_samr_group_info4(&ctr->group.info4, map.comment);
4243 return NT_STATUS_INVALID_INFO_CLASS;
4246 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4248 return NT_STATUS_OK;
4251 /*********************************************************************
4254 update a domain group's comment.
4255 *********************************************************************/
4257 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4261 GROUP_INFO_CTR *ctr;
4264 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4265 return NT_STATUS_INVALID_HANDLE;
4267 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4271 if (!get_domain_group_from_sid(group_sid, &map))
4272 return NT_STATUS_NO_SUCH_GROUP;
4276 switch (ctr->switch_value1) {
4278 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4281 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4284 return NT_STATUS_INVALID_INFO_CLASS;
4287 if(!pdb_update_group_mapping_entry(&map)) {
4288 return NT_STATUS_NO_SUCH_GROUP;
4291 return NT_STATUS_OK;
4294 /*********************************************************************
4297 update an alias's comment.
4298 *********************************************************************/
4300 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4303 struct acct_info info;
4304 ALIAS_INFO_CTR *ctr;
4307 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4308 return NT_STATUS_INVALID_HANDLE;
4310 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4316 switch (ctr->switch_value1) {
4318 unistr2_to_ascii(info.acct_desc,
4319 &(ctr->alias.info3.uni_acct_desc),
4320 sizeof(info.acct_desc)-1);
4323 return NT_STATUS_INVALID_INFO_CLASS;
4326 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4327 return NT_STATUS_ACCESS_DENIED;
4330 return NT_STATUS_OK;
4333 /*********************************************************************
4334 _samr_get_dom_pwinfo
4335 *********************************************************************/
4337 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4339 /* Perform access check. Since this rpc does not require a
4340 policy handle it will not be caught by the access checks on
4341 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4343 if (!pipe_access_check(p)) {
4344 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4345 r_u->status = NT_STATUS_ACCESS_DENIED;
4349 /* Actually, returning zeros here works quite well :-). */
4351 return NT_STATUS_OK;
4354 /*********************************************************************
4356 *********************************************************************/
4358 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4363 struct samr_info *info;
4364 SEC_DESC *psd = NULL;
4366 uint32 des_access = q_u->access_mask;
4373 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4374 return NT_STATUS_INVALID_HANDLE;
4376 status = access_check_samr_function(acc_granted,
4377 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4379 if ( !NT_STATUS_IS_OK(status) )
4382 /*check if access can be granted as requested by client. */
4383 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4384 se_map_generic(&des_access,&grp_generic_mapping);
4386 se_priv_copy( &se_rights, &se_add_users );
4388 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
4389 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
4390 &acc_granted, "_samr_open_group");
4392 if ( !NT_STATUS_IS_OK(status) )
4395 /* this should not be hard-coded like this */
4397 if (!sid_equal(&sid, get_global_sam_sid()))
4398 return NT_STATUS_ACCESS_DENIED;
4400 sid_copy(&info_sid, get_global_sam_sid());
4401 sid_append_rid(&info_sid, q_u->rid_group);
4402 sid_to_string(sid_string, &info_sid);
4404 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4405 return NT_STATUS_NO_MEMORY;
4407 info->acc_granted = acc_granted;
4409 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4411 /* check if that group really exists */
4413 ret = get_domain_group_from_sid(info->sid, &map);
4416 return NT_STATUS_NO_SUCH_GROUP;
4418 /* get a (unique) handle. open a policy on it. */
4419 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4420 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4422 return NT_STATUS_OK;
4425 /*********************************************************************
4426 _samr_remove_sid_foreign_domain
4427 *********************************************************************/
4429 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4430 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4431 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4433 DOM_SID delete_sid, alias_sid;
4434 SAM_ACCOUNT *sam_pass=NULL;
4437 BOOL is_user = False;
4439 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4441 sid_copy( &delete_sid, &q_u->sid.sid );
4443 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4444 sid_string_static(&delete_sid)));
4446 /* Find the policy handle. Open a policy on it. */
4448 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4449 return NT_STATUS_INVALID_HANDLE;
4451 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4452 "_samr_remove_sid_foreign_domain");
4454 if (!NT_STATUS_IS_OK(result))
4457 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4458 sid_string_static(&alias_sid)));
4460 /* make sure we can handle this */
4462 if ( sid_check_is_domain(&alias_sid) )
4463 type = SID_NAME_DOM_GRP;
4464 else if ( sid_check_is_builtin(&alias_sid) )
4465 type = SID_NAME_ALIAS;
4467 if ( type == SID_NAME_UNKNOWN ) {
4468 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4469 return NT_STATUS_OK;
4472 /* check if the user exists before trying to delete */
4474 pdb_init_sam(&sam_pass);
4476 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4479 /* maybe it is a group */
4480 if( !pdb_getgrsid(&map, delete_sid) ) {
4481 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4482 sid_string_static(&delete_sid)));
4483 result = NT_STATUS_INVALID_SID;
4488 /* we can only delete a user from a group since we don't have
4489 nested groups anyways. So in the latter case, just say OK */
4492 GROUP_MAP *mappings = NULL;
4496 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4498 /* interate over the groups */
4499 for ( i=0; i<num_groups; i++ ) {
4501 grp2 = getgrgid(mappings[i].gid);
4504 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4508 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4511 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4513 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4514 /* should we fail here ? */
4515 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4516 pdb_get_username(sam_pass), grp2->gr_name ));
4520 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4521 pdb_get_username(sam_pass), grp2->gr_name ));
4524 SAFE_FREE(mappings);
4528 result = NT_STATUS_OK;
4531 pdb_free_sam(&sam_pass);
4536 /*******************************************************************
4538 ********************************************************************/
4540 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4542 struct samr_info *info = NULL;
4544 uint32 min_pass_len,pass_hist,flag;
4545 time_t u_expire, u_min_age;
4546 NTTIME nt_expire, nt_min_age;
4548 time_t u_lock_duration, u_reset_time;
4549 NTTIME nt_lock_duration, nt_reset_time;
4555 uint32 num_users=0, num_groups=0, num_aliases=0;
4557 uint32 account_policy_temp;
4560 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4561 return NT_STATUS_NO_MEMORY;
4565 r_u->status = NT_STATUS_OK;
4567 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4569 /* find the policy handle. open a policy on it. */
4570 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4571 return NT_STATUS_INVALID_HANDLE;
4573 switch (q_u->switch_value) {
4575 account_policy_get(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4576 min_pass_len = account_policy_temp;
4578 account_policy_get(AP_PASSWORD_HISTORY, &account_policy_temp);
4579 pass_hist = account_policy_temp;
4581 account_policy_get(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4582 flag = account_policy_temp;
4584 account_policy_get(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4585 u_expire = account_policy_temp;
4587 account_policy_get(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4588 u_min_age = account_policy_temp;
4590 unix_to_nt_time_abs(&nt_expire, u_expire);
4591 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4593 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4594 flag, nt_expire, nt_min_age);
4598 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4600 if (!NT_STATUS_IS_OK(r_u->status)) {
4601 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4604 num_users=info->disp_info.num_user_account;
4607 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4608 if (NT_STATUS_IS_ERR(r_u->status)) {
4609 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4612 num_groups=info->disp_info.num_group_account;
4615 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4616 u_logout = account_policy_temp;
4618 unix_to_nt_time_abs(&nt_logout, u_logout);
4620 server_role = ROLE_DOMAIN_PDC;
4621 if (lp_server_role() == ROLE_DOMAIN_BDC)
4622 server_role = ROLE_DOMAIN_BDC;
4624 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4625 init_unk_info2(&ctr->info.inf2, lp_serverstring(), lp_workgroup(), global_myname(), time(NULL),
4626 num_users, num_groups, num_aliases, nt_logout, server_role);
4629 account_policy_get(AP_TIME_TO_LOGOUT, &account_policy_temp);
4630 u_logout = account_policy_temp;
4632 unix_to_nt_time_abs(&nt_logout, u_logout);
4634 init_unk_info3(&ctr->info.inf3, nt_logout);
4637 init_unk_info5(&ctr->info.inf5, global_myname());
4640 init_unk_info6(&ctr->info.inf6);
4643 server_role = ROLE_DOMAIN_PDC;
4644 if (lp_server_role() == ROLE_DOMAIN_BDC)
4645 server_role = ROLE_DOMAIN_BDC;
4646 init_unk_info7(&ctr->info.inf7, server_role);
4649 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4652 account_policy_get(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4653 u_lock_duration = account_policy_temp;
4654 if (u_lock_duration != -1)
4655 u_lock_duration *= 60;
4657 account_policy_get(AP_RESET_COUNT_TIME, &account_policy_temp);
4658 u_reset_time = account_policy_temp * 60;
4660 account_policy_get(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4661 lockout = account_policy_temp;
4663 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4664 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4666 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4669 return NT_STATUS_INVALID_INFO_CLASS;
4672 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4674 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4679 /*******************************************************************
4681 ********************************************************************/
4683 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4685 time_t u_expire, u_min_age;
4687 time_t u_lock_duration, u_reset_time;
4689 r_u->status = NT_STATUS_OK;
4691 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4693 /* find the policy handle. open a policy on it. */
4694 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4695 return NT_STATUS_INVALID_HANDLE;
4697 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4699 switch (q_u->switch_value) {
4701 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4702 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4704 account_policy_set(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4705 account_policy_set(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4706 account_policy_set(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4707 account_policy_set(AP_MAX_PASSWORD_AGE, (int)u_expire);
4708 account_policy_set(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4713 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4714 account_policy_set(AP_TIME_TO_LOGOUT, (int)u_logout);
4723 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4724 if (u_lock_duration != -1)
4725 u_lock_duration /= 60;
4727 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4729 account_policy_set(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4730 account_policy_set(AP_RESET_COUNT_TIME, (int)u_reset_time);
4731 account_policy_set(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4734 return NT_STATUS_INVALID_INFO_CLASS;
4737 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4739 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));