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;
2076 uint32 num_users=0, num_groups=0, num_aliases=0;
2078 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
2079 return NT_STATUS_NO_MEMORY;
2083 r_u->status = NT_STATUS_OK;
2085 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2087 /* find the policy handle. open a policy on it. */
2088 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
2089 return NT_STATUS_INVALID_HANDLE;
2091 switch (q_u->switch_value) {
2094 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
2095 min_pass_len = account_policy_temp;
2097 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
2098 pass_hist = account_policy_temp;
2100 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
2101 flag = account_policy_temp;
2103 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
2104 u_expire = account_policy_temp;
2106 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
2107 u_min_age = account_policy_temp;
2109 unix_to_nt_time_abs(&nt_expire, u_expire);
2110 unix_to_nt_time_abs(&nt_min_age, u_min_age);
2112 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
2113 flag, nt_expire, nt_min_age);
2117 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
2119 if (!NT_STATUS_IS_OK(r_u->status)) {
2120 DEBUG(5, ("_samr_query_dispinfo: load_sampwd_entries failed\n"));
2123 num_users=info->disp_info.num_user_account;
2126 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
2127 if (!NT_STATUS_IS_OK(r_u->status)) {
2128 DEBUG(5, ("_samr_query_dispinfo: load_group_domain_entries failed\n"));
2131 num_groups=info->disp_info.num_group_account;
2134 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
2135 u_logout = account_policy_temp;
2137 unix_to_nt_time_abs(&nt_logout, u_logout);
2139 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
2140 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
2141 num_users, num_groups, num_aliases, nt_logout);
2144 pdb_get_account_policy(AP_TIME_TO_LOGOUT, (unsigned int *)&u_logout);
2145 unix_to_nt_time_abs(&nt_logout, u_logout);
2147 init_unk_info3(&ctr->info.inf3, nt_logout);
2150 init_unk_info5(&ctr->info.inf5, global_myname());
2153 init_unk_info6(&ctr->info.inf6);
2156 init_unk_info7(&ctr->info.inf7);
2159 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
2162 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
2163 u_lock_duration = account_policy_temp;
2164 if (u_lock_duration != -1)
2165 u_lock_duration *= 60;
2167 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
2168 u_reset_time = account_policy_temp * 60;
2170 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
2171 lockout = account_policy_temp;
2173 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
2174 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
2176 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
2179 return NT_STATUS_INVALID_INFO_CLASS;
2182 init_samr_r_query_dom_info(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
2184 DEBUG(5,("_samr_query_dom_info: %d\n", __LINE__));
2189 /*******************************************************************
2191 Create an account, can be either a normal user or a machine.
2192 This funcion will need to be updated for bdc/domain trusts.
2193 ********************************************************************/
2195 NTSTATUS _samr_create_user(pipes_struct *p, SAMR_Q_CREATE_USER *q_u, SAMR_R_CREATE_USER *r_u)
2197 SAM_ACCOUNT *sam_pass=NULL;
2201 POLICY_HND dom_pol = q_u->domain_pol;
2202 UNISTR2 user_account = q_u->uni_name;
2203 uint16 acb_info = q_u->acb_info;
2204 POLICY_HND *user_pol = &r_u->user_pol;
2205 struct samr_info *info = NULL;
2213 /* check this, when giving away 'add computer to domain' privs */
2214 uint32 des_access = GENERIC_RIGHTS_USER_ALL_ACCESS;
2215 BOOL can_add_account;
2218 /* Get the domain SID stored in the domain policy */
2219 if (!get_lsa_policy_samr_sid(p, &dom_pol, &sid, &acc_granted))
2220 return NT_STATUS_INVALID_HANDLE;
2222 if (!NT_STATUS_IS_OK(nt_status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_USER, "_samr_create_user"))) {
2226 if (!(acb_info == ACB_NORMAL || acb_info == ACB_DOMTRUST || acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)) {
2227 /* Match Win2k, and return NT_STATUS_INVALID_PARAMETER if
2228 this parameter is not an account type */
2229 return NT_STATUS_INVALID_PARAMETER;
2232 rpcstr_pull(account, user_account.buffer, sizeof(account), user_account.uni_str_len*2, 0);
2233 strlower_m(account);
2235 pdb_init_sam(&sam_pass);
2238 ret = pdb_getsampwnam(sam_pass, account);
2241 /* this account exists: say so */
2242 pdb_free_sam(&sam_pass);
2243 return NT_STATUS_USER_EXISTS;
2246 pdb_free_sam(&sam_pass);
2248 /*********************************************************************
2249 * HEADS UP! If we have to create a new user account, we have to get
2250 * a new RID from somewhere. This used to be done by the passdb
2251 * backend. It has been moved into idmap now. Since idmap is now
2252 * wrapped up behind winbind, this means you have to run winbindd if you
2253 * want new accounts to get a new RID when "enable rid algorithm = no".
2254 * Tough. We now have a uniform way of allocating RIDs regardless
2255 * of what ever passdb backend people may use.
2256 * --jerry (2003-07-10)
2257 *********************************************************************/
2259 pw = Get_Pwnam(account);
2261 /* determine which user right we need to check based on the acb_info */
2263 if ( (acb_info & ACB_WSTRUST) == ACB_WSTRUST )
2265 pstrcpy(add_script, lp_addmachine_script());
2266 se_priv_copy( &se_rights, &se_machine_account );
2267 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2269 else if ( (acb_info & ACB_WSTRUST) == ACB_NORMAL )
2271 pstrcpy(add_script, lp_adduser_script());
2272 se_priv_copy( &se_rights, &se_add_users );
2273 can_add_account = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
2275 else if ( ((acb_info & ACB_SVRTRUST) == ACB_SVRTRUST) || ((acb_info & ACB_DOMTRUST) == ACB_DOMTRUST) )
2277 pstrcpy(add_script, lp_addmachine_script());
2278 /* only Domain Admins can add a BDC or domain trust */
2279 se_priv_copy( &se_rights, &se_priv_none );
2280 can_add_account = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
2283 DEBUG(5, ("_samr_create_user: %s can add this account : %s\n",
2284 p->pipe_user_name, can_add_account ? "True":"False" ));
2286 /********** BEGIN Admin BLOCK **********/
2288 if ( can_add_account )
2295 all_string_sub(add_script, "%u", account, sizeof(add_script));
2296 add_ret = smbrun(add_script,NULL);
2297 DEBUG(3,("_samr_create_user: Running the command `%s' gave %d\n", add_script, add_ret));
2299 else /* no add user script -- ask winbindd to do it */
2301 if ( !winbind_create_user( account, &new_rid ) ) {
2302 DEBUG(3,("_samr_create_user: winbind_create_user(%s) failed\n",
2309 /* implicit call to getpwnam() next. we have a valid SID coming out of this call */
2311 nt_status = pdb_init_sam_new(&sam_pass, account, new_rid);
2313 /* this code is order such that we have no unnecessary retuns
2314 out of the admin block of code */
2316 if ( NT_STATUS_IS_OK(nt_status) ) {
2317 pdb_set_acct_ctrl(sam_pass, acb_info, PDB_CHANGED);
2319 if ( !(ret = pdb_add_sam_account(sam_pass)) ) {
2320 pdb_free_sam(&sam_pass);
2321 DEBUG(0, ("could not add user/computer %s to passdb. Check permissions?\n",
2323 nt_status = NT_STATUS_ACCESS_DENIED;
2327 if ( can_add_account )
2330 /********** END Admin BLOCK **********/
2332 /* now check for failure */
2334 if ( !NT_STATUS_IS_OK(nt_status) )
2337 /* Get the user's SID */
2339 sid_copy(&sid, pdb_get_user_sid(sam_pass));
2341 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW);
2342 se_map_generic(&des_access, &usr_generic_mapping);
2344 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2345 &se_rights, GENERIC_RIGHTS_USER_WRITE, des_access,
2346 &acc_granted, "_samr_create_user");
2348 if ( !NT_STATUS_IS_OK(nt_status) ) {
2352 /* associate the user's SID with the new handle. */
2353 if ((info = get_samr_info_by_sid(&sid)) == NULL) {
2354 pdb_free_sam(&sam_pass);
2355 return NT_STATUS_NO_MEMORY;
2360 info->acc_granted = acc_granted;
2362 /* get a (unique) handle. open a policy on it. */
2363 if (!create_policy_hnd(p, user_pol, free_samr_info, (void *)info)) {
2364 pdb_free_sam(&sam_pass);
2365 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2368 r_u->user_rid=pdb_get_user_rid(sam_pass);
2370 r_u->access_granted = acc_granted;
2372 pdb_free_sam(&sam_pass);
2374 return NT_STATUS_OK;
2377 /*******************************************************************
2378 samr_reply_connect_anon
2379 ********************************************************************/
2381 NTSTATUS _samr_connect_anon(pipes_struct *p, SAMR_Q_CONNECT_ANON *q_u, SAMR_R_CONNECT_ANON *r_u)
2383 struct samr_info *info = NULL;
2384 uint32 des_access = q_u->access_mask;
2388 if (!pipe_access_check(p)) {
2389 DEBUG(3, ("access denied to samr_connect_anon\n"));
2390 r_u->status = NT_STATUS_ACCESS_DENIED;
2394 /* set up the SAMR connect_anon response */
2396 r_u->status = NT_STATUS_OK;
2398 /* associate the user's SID with the new handle. */
2399 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2400 return NT_STATUS_NO_MEMORY;
2402 /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS
2403 was observed from a win98 client trying to enumerate users (when configured
2404 user level access control on shares) --jerry */
2406 se_map_generic( &des_access, &sam_generic_mapping );
2407 info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN);
2409 info->status = q_u->unknown_0;
2411 /* get a (unique) handle. open a policy on it. */
2412 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2413 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2418 /*******************************************************************
2420 ********************************************************************/
2422 NTSTATUS _samr_connect(pipes_struct *p, SAMR_Q_CONNECT *q_u, SAMR_R_CONNECT *r_u)
2424 struct samr_info *info = NULL;
2425 SEC_DESC *psd = NULL;
2427 uint32 des_access = q_u->access_mask;
2432 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2436 if (!pipe_access_check(p)) {
2437 DEBUG(3, ("access denied to samr_connect\n"));
2438 r_u->status = NT_STATUS_ACCESS_DENIED;
2442 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2443 se_map_generic(&des_access, &sam_generic_mapping);
2445 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2446 NULL, 0, des_access, &acc_granted, "_samr_connect");
2448 if ( !NT_STATUS_IS_OK(nt_status) )
2451 r_u->status = NT_STATUS_OK;
2453 /* associate the user's SID and access granted with the new handle. */
2454 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2455 return NT_STATUS_NO_MEMORY;
2457 info->acc_granted = acc_granted;
2458 info->status = q_u->access_mask;
2460 /* get a (unique) handle. open a policy on it. */
2461 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2462 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2464 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2469 /*******************************************************************
2471 ********************************************************************/
2473 NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *r_u)
2475 struct samr_info *info = NULL;
2476 SEC_DESC *psd = NULL;
2478 uint32 des_access = q_u->access_mask;
2483 DEBUG(5,("_samr_connect4: %d\n", __LINE__));
2487 if (!pipe_access_check(p)) {
2488 DEBUG(3, ("access denied to samr_connect4\n"));
2489 r_u->status = NT_STATUS_ACCESS_DENIED;
2493 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
2494 se_map_generic(&des_access, &sam_generic_mapping);
2496 nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2497 NULL, 0, des_access, &acc_granted, "_samr_connect4");
2499 if ( !NT_STATUS_IS_OK(nt_status) )
2502 r_u->status = NT_STATUS_OK;
2504 /* associate the user's SID and access granted with the new handle. */
2505 if ((info = get_samr_info_by_sid(NULL)) == NULL)
2506 return NT_STATUS_NO_MEMORY;
2508 info->acc_granted = acc_granted;
2509 info->status = q_u->access_mask;
2511 /* get a (unique) handle. open a policy on it. */
2512 if (!create_policy_hnd(p, &r_u->connect_pol, free_samr_info, (void *)info))
2513 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2515 DEBUG(5,("_samr_connect: %d\n", __LINE__));
2520 /**********************************************************************
2521 api_samr_lookup_domain
2522 **********************************************************************/
2524 NTSTATUS _samr_lookup_domain(pipes_struct *p, SAMR_Q_LOOKUP_DOMAIN *q_u, SAMR_R_LOOKUP_DOMAIN *r_u)
2526 struct samr_info *info;
2527 fstring domain_name;
2530 r_u->status = NT_STATUS_OK;
2532 if (!find_policy_by_hnd(p, &q_u->connect_pol, (void**)&info))
2533 return NT_STATUS_INVALID_HANDLE;
2535 /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here.
2536 Reverted that change so we will work with RAS servers again */
2538 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
2539 SA_RIGHT_SAM_OPEN_DOMAIN, "_samr_lookup_domain")))
2544 rpcstr_pull(domain_name, q_u->uni_domain.buffer, sizeof(domain_name), q_u->uni_domain.uni_str_len*2, 0);
2548 if (!secrets_fetch_domain_sid(domain_name, &sid)) {
2549 r_u->status = NT_STATUS_NO_SUCH_DOMAIN;
2552 DEBUG(2,("Returning domain sid for domain %s -> %s\n", domain_name, sid_string_static(&sid)));
2554 init_samr_r_lookup_domain(r_u, &sid, r_u->status);
2559 /******************************************************************
2560 makes a SAMR_R_ENUM_DOMAINS structure.
2561 ********************************************************************/
2563 static BOOL make_enum_domains(TALLOC_CTX *ctx, SAM_ENTRY **pp_sam,
2564 UNISTR2 **pp_uni_name, uint32 num_sam_entries, fstring doms[])
2570 DEBUG(5, ("make_enum_domains\n"));
2573 *pp_uni_name = NULL;
2575 if (num_sam_entries == 0)
2578 sam = TALLOC_ZERO_ARRAY(ctx, SAM_ENTRY, num_sam_entries);
2579 uni_name = TALLOC_ZERO_ARRAY(ctx, UNISTR2, num_sam_entries);
2581 if (sam == NULL || uni_name == NULL)
2584 for (i = 0; i < num_sam_entries; i++) {
2585 init_unistr2(&uni_name[i], doms[i], UNI_FLAGS_NONE);
2586 init_sam_entry(&sam[i], &uni_name[i], 0);
2590 *pp_uni_name = uni_name;
2595 /**********************************************************************
2596 api_samr_enum_domains
2597 **********************************************************************/
2599 NTSTATUS _samr_enum_domains(pipes_struct *p, SAMR_Q_ENUM_DOMAINS *q_u, SAMR_R_ENUM_DOMAINS *r_u)
2601 struct samr_info *info;
2602 uint32 num_entries = 2;
2606 r_u->status = NT_STATUS_OK;
2608 if (!find_policy_by_hnd(p, &q_u->pol, (void**)&info))
2609 return NT_STATUS_INVALID_HANDLE;
2611 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted, SA_RIGHT_SAM_ENUM_DOMAINS, "_samr_enum_domains"))) {
2615 name = get_global_sam_name();
2617 fstrcpy(dom[0],name);
2619 fstrcpy(dom[1],"Builtin");
2621 if (!make_enum_domains(p->mem_ctx, &r_u->sam, &r_u->uni_dom_name, num_entries, dom))
2622 return NT_STATUS_NO_MEMORY;
2624 init_samr_r_enum_domains(r_u, q_u->start_idx + num_entries, num_entries);
2629 /*******************************************************************
2631 ********************************************************************/
2633 NTSTATUS _samr_open_alias(pipes_struct *p, SAMR_Q_OPEN_ALIAS *q_u, SAMR_R_OPEN_ALIAS *r_u)
2636 POLICY_HND domain_pol = q_u->dom_pol;
2637 uint32 alias_rid = q_u->rid_alias;
2638 POLICY_HND *alias_pol = &r_u->pol;
2639 struct samr_info *info = NULL;
2640 SEC_DESC *psd = NULL;
2642 uint32 des_access = q_u->access_mask;
2647 r_u->status = NT_STATUS_OK;
2649 /* find the domain policy and get the SID / access bits stored in the domain policy */
2651 if ( !get_lsa_policy_samr_sid(p, &domain_pol, &sid, &acc_granted) )
2652 return NT_STATUS_INVALID_HANDLE;
2654 status = access_check_samr_function(acc_granted,
2655 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_alias");
2657 if ( !NT_STATUS_IS_OK(status) )
2660 /* append the alias' RID to it */
2662 if (!sid_append_rid(&sid, alias_rid))
2663 return NT_STATUS_NO_SUCH_USER;
2665 /*check if access can be granted as requested by client. */
2667 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0);
2668 se_map_generic(&des_access,&ali_generic_mapping);
2670 se_priv_add( &se_rights, &se_add_users );
2673 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
2674 &se_rights, GENERIC_RIGHTS_ALIAS_WRITE, des_access,
2675 &acc_granted, "_samr_open_alias");
2677 if ( !NT_STATUS_IS_OK(status) )
2681 * we should check if the rid really exist !!!
2685 /* associate the user's SID with the new handle. */
2686 if ((info = get_samr_info_by_sid(&sid)) == NULL)
2687 return NT_STATUS_NO_MEMORY;
2689 info->acc_granted = acc_granted;
2691 /* get a (unique) handle. open a policy on it. */
2692 if (!create_policy_hnd(p, alias_pol, free_samr_info, (void *)info))
2693 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2698 /*******************************************************************
2700 ********************************************************************/
2702 static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, SAM_ACCOUNT *pwd)
2705 DEBUG(5, ("set_user_info_10: NULL id10\n"));
2710 /* FIX ME: check if the value is really changed --metze */
2711 if (!pdb_set_acct_ctrl(pwd, id10->acb_info, PDB_CHANGED)) {
2716 if(!pdb_update_sam_account(pwd)) {
2726 /*******************************************************************
2728 ********************************************************************/
2730 static BOOL set_user_info_12(SAM_USER_INFO_12 *id12, SAM_ACCOUNT *pwd)
2734 DEBUG(2, ("set_user_info_12: id12 is NULL\n"));
2739 if (!pdb_set_lanman_passwd (pwd, id12->lm_pwd, PDB_CHANGED)) {
2743 if (!pdb_set_nt_passwd (pwd, id12->nt_pwd, PDB_CHANGED)) {
2747 if (!pdb_set_pass_changed_now (pwd)) {
2752 if(!pdb_update_sam_account(pwd)) {
2761 /*******************************************************************
2762 The GROUPSID field in the SAM_ACCOUNT changed. Try to tell unix.
2763 ********************************************************************/
2764 static BOOL set_unix_primary_group(SAM_ACCOUNT *sampass)
2769 if (!NT_STATUS_IS_OK(sid_to_gid(pdb_get_group_sid(sampass),
2771 DEBUG(2,("Could not get gid for primary group of "
2772 "user %s\n", pdb_get_username(sampass)));
2776 grp = getgrgid(gid);
2779 DEBUG(2,("Could not find primary group %lu for "
2780 "user %s\n", (unsigned long)gid,
2781 pdb_get_username(sampass)));
2785 if (smb_set_primary_group(grp->gr_name,
2786 pdb_get_username(sampass)) != 0) {
2787 DEBUG(2,("Could not set primary group for user %s to "
2789 pdb_get_username(sampass), grp->gr_name));
2797 /*******************************************************************
2799 ********************************************************************/
2801 static BOOL set_user_info_20(SAM_USER_INFO_20 *id20, SAM_ACCOUNT *pwd)
2804 DEBUG(5, ("set_user_info_20: NULL id20\n"));
2808 copy_id20_to_sam_passwd(pwd, id20);
2810 /* write the change out */
2811 if(!pdb_update_sam_account(pwd)) {
2820 /*******************************************************************
2822 ********************************************************************/
2824 static BOOL set_user_info_21(SAM_USER_INFO_21 *id21, SAM_ACCOUNT *pwd)
2828 DEBUG(5, ("set_user_info_21: NULL id21\n"));
2832 copy_id21_to_sam_passwd(pwd, id21);
2835 * The funny part about the previous two calls is
2836 * that pwd still has the password hashes from the
2837 * passdb entry. These have not been updated from
2838 * id21. I don't know if they need to be set. --jerry
2841 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2842 set_unix_primary_group(pwd);
2844 /* write the change out */
2845 if(!pdb_update_sam_account(pwd)) {
2855 /*******************************************************************
2857 ********************************************************************/
2859 static BOOL set_user_info_23(SAM_USER_INFO_23 *id23, SAM_ACCOUNT *pwd)
2861 pstring plaintext_buf;
2866 DEBUG(5, ("set_user_info_23: NULL id23\n"));
2870 DEBUG(5, ("Attempting administrator password change (level 23) for user %s\n",
2871 pdb_get_username(pwd)));
2873 acct_ctrl = pdb_get_acct_ctrl(pwd);
2875 if (!decode_pw_buffer((char*)id23->pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2880 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2885 copy_id23_to_sam_passwd(pwd, id23);
2887 /* if it's a trust account, don't update /etc/passwd */
2888 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2889 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2890 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2891 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2893 /* update the UNIX password */
2894 if (lp_unix_password_sync() ) {
2895 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2897 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2900 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2907 ZERO_STRUCT(plaintext_buf);
2909 if (IS_SAM_CHANGED(pwd, PDB_GROUPSID))
2910 set_unix_primary_group(pwd);
2912 if(!pdb_update_sam_account(pwd)) {
2922 /*******************************************************************
2924 ********************************************************************/
2926 static BOOL set_user_info_pw(char *pass, SAM_ACCOUNT *pwd)
2929 pstring plaintext_buf;
2932 DEBUG(5, ("Attempting administrator password change for user %s\n",
2933 pdb_get_username(pwd)));
2935 acct_ctrl = pdb_get_acct_ctrl(pwd);
2937 ZERO_STRUCT(plaintext_buf);
2939 if (!decode_pw_buffer(pass, plaintext_buf, 256, &len, STR_UNICODE)) {
2944 if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
2949 /* if it's a trust account, don't update /etc/passwd */
2950 if ( ( (acct_ctrl & ACB_DOMTRUST) == ACB_DOMTRUST ) ||
2951 ( (acct_ctrl & ACB_WSTRUST) == ACB_WSTRUST) ||
2952 ( (acct_ctrl & ACB_SVRTRUST) == ACB_SVRTRUST) ) {
2953 DEBUG(5, ("Changing trust account or non-unix-user password, not updating /etc/passwd\n"));
2955 /* update the UNIX password */
2956 if (lp_unix_password_sync()) {
2957 struct passwd *passwd = Get_Pwnam(pdb_get_username(pwd));
2959 DEBUG(1, ("chgpasswd: Username does not exist in system !?!\n"));
2962 if(!chgpasswd(pdb_get_username(pwd), passwd, "", plaintext_buf, True)) {
2969 ZERO_STRUCT(plaintext_buf);
2971 DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n"));
2973 /* update the SAMBA password */
2974 if(!pdb_update_sam_account(pwd)) {
2984 /*******************************************************************
2985 samr_reply_set_userinfo
2986 ********************************************************************/
2988 NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SET_USERINFO *r_u)
2990 SAM_ACCOUNT *pwd = NULL;
2992 POLICY_HND *pol = &q_u->pol;
2993 uint16 switch_value = q_u->switch_value;
2994 SAM_USERINFO_CTR *ctr = q_u->ctr;
2996 uint32 acc_required;
2998 BOOL has_enough_rights;
3001 DEBUG(5, ("_samr_set_userinfo: %d\n", __LINE__));
3003 r_u->status = NT_STATUS_OK;
3005 /* find the policy handle. open a policy on it. */
3006 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3007 return NT_STATUS_INVALID_HANDLE;
3009 /* observed when joining an XP client to a Samba domain */
3011 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3013 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo"))) {
3017 DEBUG(5, ("_samr_set_userinfo: sid:%s, level:%d\n", sid_string_static(&sid), switch_value));
3020 DEBUG(5, ("_samr_set_userinfo: NULL info level\n"));
3021 return NT_STATUS_INVALID_INFO_CLASS;
3027 ret = pdb_getsampwsid(pwd, &sid);
3032 return NT_STATUS_NO_SUCH_USER;
3035 /* deal with machine password changes differently from userinfo changes */
3037 if ( pdb_get_acct_ctrl(pwd) & ACB_WSTRUST )
3038 se_priv_copy( &se_rights, &se_machine_account );
3040 se_priv_copy( &se_rights, &se_add_users );
3042 /* check to see if we have the sufficient rights */
3044 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3046 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3047 p->pipe_user_name, has_enough_rights ? "" : " not"));
3049 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3051 if ( has_enough_rights )
3054 /* ok! user info levels (lots: see MSDEV help), off we go... */
3056 switch (switch_value) {
3058 if (!set_user_info_12(ctr->info.id12, pwd))
3059 r_u->status = NT_STATUS_ACCESS_DENIED;
3063 if (!p->session_key.length) {
3064 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3066 SamOEMhashBlob(ctr->info.id24->pass, 516, &p->session_key);
3068 dump_data(100, (char *)ctr->info.id24->pass, 516);
3070 if (!set_user_info_pw((char *)ctr->info.id24->pass, pwd))
3071 r_u->status = NT_STATUS_ACCESS_DENIED;
3077 * Currently we don't really know how to unmarshall
3078 * the level 25 struct, and the password encryption
3079 * is different. This is a placeholder for when we
3080 * do understand it. In the meantime just return INVALID
3081 * info level and W2K SP2 drops down to level 23... JRA.
3084 if (!p->session_key.length) {
3085 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3087 SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
3089 dump_data(100, (char *)ctr->info.id25->pass, 532);
3091 if (!set_user_info_pw(ctr->info.id25->pass, &sid))
3092 r_u->status = NT_STATUS_ACCESS_DENIED;
3095 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3099 if (!p->session_key.length) {
3100 r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
3102 SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
3104 dump_data(100, (char *)ctr->info.id23->pass, 516);
3106 if (!set_user_info_23(ctr->info.id23, pwd))
3107 r_u->status = NT_STATUS_ACCESS_DENIED;
3111 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3115 if ( has_enough_rights )
3118 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3123 /*******************************************************************
3124 samr_reply_set_userinfo2
3125 ********************************************************************/
3127 NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_SET_USERINFO2 *r_u)
3129 SAM_ACCOUNT *pwd = NULL;
3131 SAM_USERINFO_CTR *ctr = q_u->ctr;
3132 POLICY_HND *pol = &q_u->pol;
3133 uint16 switch_value = q_u->switch_value;
3135 uint32 acc_required;
3137 BOOL has_enough_rights;
3140 DEBUG(5, ("samr_reply_set_userinfo2: %d\n", __LINE__));
3142 r_u->status = NT_STATUS_OK;
3144 /* find the policy handle. open a policy on it. */
3145 if (!get_lsa_policy_samr_sid(p, pol, &sid, &acc_granted))
3146 return NT_STATUS_INVALID_HANDLE;
3148 /* observed when joining XP client to Samba domain */
3150 acc_required = SA_RIGHT_USER_SET_PASSWORD | SA_RIGHT_USER_SET_ATTRIBUTES | SA_RIGHT_USER_ACCT_FLAGS_EXPIRY;
3152 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, acc_required, "_samr_set_userinfo2"))) {
3156 DEBUG(5, ("samr_reply_set_userinfo2: sid:%s\n", sid_string_static(&sid)));
3159 DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
3160 return NT_STATUS_INVALID_INFO_CLASS;
3163 switch_value=ctr->switch_value;
3168 ret = pdb_getsampwsid(pwd, &sid);
3173 return NT_STATUS_NO_SUCH_USER;
3176 /* deal with machine password changes differently from userinfo changes */
3178 if ( pdb_get_acct_ctrl(pwd) & ACB_WSTRUST )
3179 se_priv_copy( &se_rights, &se_machine_account );
3181 se_priv_copy( &se_rights, &se_add_users );
3183 /* check to see if we have the sufficient rights */
3185 has_enough_rights = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3187 DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
3188 p->pipe_user_name, has_enough_rights ? "" : " not"));
3190 /* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
3192 if ( has_enough_rights )
3195 /* ok! user info levels (lots: see MSDEV help), off we go... */
3197 switch (switch_value) {
3199 if (!set_user_info_10(ctr->info.id10, pwd))
3200 r_u->status = NT_STATUS_ACCESS_DENIED;
3203 /* Used by AS/U JRA. */
3204 if (!set_user_info_12(ctr->info.id12, pwd))
3205 r_u->status = NT_STATUS_ACCESS_DENIED;
3208 if (!set_user_info_20(ctr->info.id20, pwd))
3209 r_u->status = NT_STATUS_ACCESS_DENIED;
3212 if (!set_user_info_21(ctr->info.id21, pwd))
3213 return NT_STATUS_ACCESS_DENIED;
3216 r_u->status = NT_STATUS_INVALID_INFO_CLASS;
3219 if ( has_enough_rights )
3222 /* ================ END SeMachineAccountPrivilege BLOCK ================ */
3227 /*********************************************************************
3228 _samr_query_aliasmem
3229 *********************************************************************/
3231 NTSTATUS _samr_query_useraliases(pipes_struct *p, SAMR_Q_QUERY_USERALIASES *q_u, SAMR_R_QUERY_USERALIASES *r_u)
3235 struct samr_info *info = NULL;
3246 r_u->status = NT_STATUS_OK;
3248 DEBUG(5,("_samr_query_useraliases: %d\n", __LINE__));
3250 /* find the policy handle. open a policy on it. */
3251 if (!find_policy_by_hnd(p, &q_u->pol, (void **)&info))
3252 return NT_STATUS_INVALID_HANDLE;
3254 ntstatus1 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, "_samr_query_useraliases");
3255 ntstatus2 = access_check_samr_function(info->acc_granted, SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_query_useraliases");
3257 if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) {
3258 if (!(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus2)) &&
3259 !(NT_STATUS_EQUAL(ntstatus1,NT_STATUS_ACCESS_DENIED) && NT_STATUS_IS_OK(ntstatus1))) {
3260 return (NT_STATUS_IS_OK(ntstatus1)) ? ntstatus2 : ntstatus1;
3264 if (!sid_check_is_domain(&info->sid) &&
3265 !sid_check_is_builtin(&info->sid))
3266 return NT_STATUS_OBJECT_TYPE_MISMATCH;
3268 members = TALLOC_ARRAY(p->mem_ctx, DOM_SID, q_u->num_sids1);
3270 if (members == NULL)
3271 return NT_STATUS_NO_MEMORY;
3273 for (i=0; i<q_u->num_sids1; i++)
3274 sid_copy(&members[i], &q_u->sid[i].sid);
3277 res = pdb_enum_alias_memberships(members,
3278 q_u->num_sids1, &aliases,
3283 return NT_STATUS_UNSUCCESSFUL;
3288 for (i=0; i<num_aliases; i++) {
3291 if (!sid_peek_check_rid(&info->sid, &aliases[i], &rid))
3294 rids = TALLOC_REALLOC_ARRAY(p->mem_ctx, rids, uint32, num_groups+1);
3297 return NT_STATUS_NO_MEMORY;
3299 rids[num_groups] = rid;
3304 init_samr_r_query_useraliases(r_u, num_groups, rids, NT_STATUS_OK);
3305 return NT_STATUS_OK;
3308 /*********************************************************************
3309 _samr_query_aliasmem
3310 *********************************************************************/
3312 NTSTATUS _samr_query_aliasmem(pipes_struct *p, SAMR_Q_QUERY_ALIASMEM *q_u, SAMR_R_QUERY_ALIASMEM *r_u)
3324 /* find the policy handle. open a policy on it. */
3325 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3326 return NT_STATUS_INVALID_HANDLE;
3328 if (!NT_STATUS_IS_OK(r_u->status =
3329 access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_GET_MEMBERS, "_samr_query_aliasmem"))) {
3333 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3335 if (!pdb_enum_aliasmem(&alias_sid, &sids, &num_sids))
3336 return NT_STATUS_NO_SUCH_ALIAS;
3338 sid = TALLOC_ZERO_ARRAY(p->mem_ctx, DOM_SID2, num_sids);
3339 if (num_sids!=0 && sid == NULL) {
3341 return NT_STATUS_NO_MEMORY;
3344 for (i = 0; i < num_sids; i++) {
3345 init_dom_sid2(&sid[i], &sids[i]);
3348 init_samr_r_query_aliasmem(r_u, num_sids, sid, NT_STATUS_OK);
3352 return NT_STATUS_OK;
3355 static void add_uid_to_array_unique(uid_t uid, uid_t **uids, int *num)
3359 for (i=0; i<*num; i++) {
3360 if ((*uids)[i] == uid)
3364 *uids = SMB_REALLOC_ARRAY(*uids, uid_t, *num+1);
3369 (*uids)[*num] = uid;
3374 static BOOL get_memberuids(gid_t gid, uid_t **uids, int *num)
3378 struct sys_pwent *userlist, *user;
3383 /* We only look at our own sam, so don't care about imported stuff */
3387 if ((grp = getgrgid(gid)) == NULL) {
3392 /* Primary group members */
3394 userlist = getpwent_list();
3396 for (user = userlist; user != NULL; user = user->next) {
3397 if (user->pw_gid != gid)
3399 add_uid_to_array_unique(user->pw_uid, uids, num);
3402 pwent_free(userlist);
3404 /* Secondary group members */
3406 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
3407 struct passwd *pw = getpwnam(*gr);
3411 add_uid_to_array_unique(pw->pw_uid, uids, num);
3419 /*********************************************************************
3420 _samr_query_groupmem
3421 *********************************************************************/
3423 NTSTATUS _samr_query_groupmem(pipes_struct *p, SAMR_Q_QUERY_GROUPMEM *q_u, SAMR_R_QUERY_GROUPMEM *r_u)
3425 int final_num_rids, i;
3427 fstring group_sid_str;
3437 /* find the policy handle. open a policy on it. */
3438 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3439 return NT_STATUS_INVALID_HANDLE;
3441 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_GET_MEMBERS, "_samr_query_groupmem"))) {
3445 sid_to_string(group_sid_str, &group_sid);
3446 DEBUG(10, ("sid is %s\n", group_sid_str));
3448 if (!sid_check_is_in_our_domain(&group_sid)) {
3449 DEBUG(3, ("sid %s is not in our domain\n", group_sid_str));
3450 return NT_STATUS_NO_SUCH_GROUP;
3453 DEBUG(10, ("lookup on Domain SID\n"));
3455 if (!NT_STATUS_IS_OK(sid_to_gid(&group_sid, &gid)))
3456 return NT_STATUS_NO_SUCH_GROUP;
3458 if(!get_memberuids(gid, &uids, &num))
3459 return NT_STATUS_NO_SUCH_GROUP;
3461 rid=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3462 attr=TALLOC_ZERO_ARRAY(p->mem_ctx, uint32, num);
3464 if (num!=0 && (rid==NULL || attr==NULL))
3465 return NT_STATUS_NO_MEMORY;
3469 for (i=0; i<num; i++) {
3472 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) {
3473 DEBUG(1, ("Could not map member uid to SID\n"));
3477 if (!sid_check_is_in_our_domain(&sid)) {
3478 DEBUG(1, ("Inconsistent SAM -- group member uid not "
3479 "in our domain\n"));
3483 sid_peek_rid(&sid, &rid[final_num_rids]);
3485 /* Hmm. In a trace I got the constant 7 here from NT. */
3486 attr[final_num_rids] = SID_NAME_USER;
3488 final_num_rids += 1;
3493 init_samr_r_query_groupmem(r_u, final_num_rids, rid, attr,
3496 return NT_STATUS_OK;
3499 /*********************************************************************
3501 *********************************************************************/
3503 NTSTATUS _samr_add_aliasmem(pipes_struct *p, SAMR_Q_ADD_ALIASMEM *q_u, SAMR_R_ADD_ALIASMEM *r_u)
3508 BOOL can_add_accounts;
3512 /* Find the policy handle. Open a policy on it. */
3513 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3514 return NT_STATUS_INVALID_HANDLE;
3516 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_ADD_MEMBER, "_samr_add_aliasmem"))) {
3520 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3522 se_priv_copy( &se_rights, &se_add_users );
3523 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3525 /******** BEGIN SeAddUsers BLOCK *********/
3527 if ( can_add_accounts )
3530 ret = pdb_add_aliasmem(&alias_sid, &q_u->sid.sid);
3532 if ( can_add_accounts )
3535 /******** END SeAddUsers BLOCK *********/
3537 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3540 /*********************************************************************
3542 *********************************************************************/
3544 NTSTATUS _samr_del_aliasmem(pipes_struct *p, SAMR_Q_DEL_ALIASMEM *q_u, SAMR_R_DEL_ALIASMEM *r_u)
3549 BOOL can_add_accounts;
3552 /* Find the policy handle. Open a policy on it. */
3553 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3554 return NT_STATUS_INVALID_HANDLE;
3556 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_REMOVE_MEMBER, "_samr_del_aliasmem"))) {
3560 DEBUG(10, ("_samr_del_aliasmem:sid is %s\n",
3561 sid_string_static(&alias_sid)));
3563 se_priv_copy( &se_rights, &se_add_users );
3564 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3566 /******** BEGIN SeAddUsers BLOCK *********/
3568 if ( can_add_accounts )
3571 ret = pdb_del_aliasmem(&alias_sid, &q_u->sid.sid);
3573 if ( can_add_accounts )
3576 /******** END SeAddUsers BLOCK *********/
3578 return ret ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED;
3581 /*********************************************************************
3583 *********************************************************************/
3585 NTSTATUS _samr_add_groupmem(pipes_struct *p, SAMR_Q_ADD_GROUPMEM *q_u, SAMR_R_ADD_GROUPMEM *r_u)
3589 fstring group_sid_str;
3596 SAM_ACCOUNT *sam_user=NULL;
3600 BOOL can_add_accounts;
3602 /* Find the policy handle. Open a policy on it. */
3603 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3604 return NT_STATUS_INVALID_HANDLE;
3606 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_ADD_MEMBER, "_samr_add_groupmem"))) {
3610 sid_to_string(group_sid_str, &group_sid);
3611 DEBUG(10, ("sid is %s\n", group_sid_str));
3613 if (sid_compare(&group_sid, get_global_sam_sid())<=0)
3614 return NT_STATUS_NO_SUCH_GROUP;
3616 DEBUG(10, ("lookup on Domain SID\n"));
3618 if(!get_domain_group_from_sid(group_sid, &map))
3619 return NT_STATUS_NO_SUCH_GROUP;
3621 sid_copy(&user_sid, get_global_sam_sid());
3622 sid_append_rid(&user_sid, q_u->rid);
3624 ret = pdb_init_sam(&sam_user);
3625 if (!NT_STATUS_IS_OK(ret))
3628 check = pdb_getsampwsid(sam_user, &user_sid);
3630 if (check != True) {
3631 pdb_free_sam(&sam_user);
3632 return NT_STATUS_NO_SUCH_USER;
3635 /* check a real user exist before we run the script to add a user to a group */
3636 if (!NT_STATUS_IS_OK(sid_to_uid(pdb_get_user_sid(sam_user), &uid))) {
3637 pdb_free_sam(&sam_user);
3638 return NT_STATUS_NO_SUCH_USER;
3641 pdb_free_sam(&sam_user);
3643 if ((pwd=getpwuid_alloc(uid)) == NULL) {
3644 return NT_STATUS_NO_SUCH_USER;
3647 if ((grp=getgrgid(map.gid)) == NULL) {
3649 return NT_STATUS_NO_SUCH_GROUP;
3652 /* we need to copy the name otherwise it's overloaded in user_in_unix_group_list */
3653 fstrcpy(grp_name, grp->gr_name);
3655 /* if the user is already in the group */
3656 if(user_in_unix_group_list(pwd->pw_name, grp_name)) {
3658 return NT_STATUS_MEMBER_IN_GROUP;
3661 se_priv_copy( &se_rights, &se_add_users );
3662 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3664 /******** BEGIN SeAddUsers BLOCK *********/
3666 if ( can_add_accounts )
3670 * ok, the group exist, the user exist, the user is not in the group,
3672 * we can (finally) add it to the group !
3675 smb_add_user_group(grp_name, pwd->pw_name);
3677 if ( can_add_accounts )
3680 /******** END SeAddUsers BLOCK *********/
3682 /* check if the user has been added then ... */
3683 if(!user_in_unix_group_list(pwd->pw_name, grp_name)) {
3685 return NT_STATUS_MEMBER_NOT_IN_GROUP; /* don't know what to reply else */
3689 return NT_STATUS_OK;
3692 /*********************************************************************
3694 *********************************************************************/
3696 NTSTATUS _samr_del_groupmem(pipes_struct *p, SAMR_Q_DEL_GROUPMEM *q_u, SAMR_R_DEL_GROUPMEM *r_u)
3700 SAM_ACCOUNT *sam_pass=NULL;
3706 BOOL can_add_accounts;
3709 * delete the group member named q_u->rid
3710 * who is a member of the sid associated with the handle
3711 * the rid is a user's rid as the group is a domain group.
3714 /* Find the policy handle. Open a policy on it. */
3715 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
3716 return NT_STATUS_INVALID_HANDLE;
3718 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_REMOVE_MEMBER, "_samr_del_groupmem"))) {
3722 if (!sid_check_is_in_our_domain(&group_sid))
3723 return NT_STATUS_NO_SUCH_GROUP;
3725 sid_copy(&user_sid, get_global_sam_sid());
3726 sid_append_rid(&user_sid, q_u->rid);
3728 if (!get_domain_group_from_sid(group_sid, &map))
3729 return NT_STATUS_NO_SUCH_GROUP;
3731 if ((grp=getgrgid(map.gid)) == NULL)
3732 return NT_STATUS_NO_SUCH_GROUP;
3734 /* we need to copy the name otherwise it's overloaded in user_in_group_list */
3735 fstrcpy(grp_name, grp->gr_name);
3737 /* check if the user exists before trying to remove it from the group */
3738 pdb_init_sam(&sam_pass);
3739 if (!pdb_getsampwsid(sam_pass, &user_sid)) {
3740 DEBUG(5,("User %s doesn't exist.\n", pdb_get_username(sam_pass)));
3741 pdb_free_sam(&sam_pass);
3742 return NT_STATUS_NO_SUCH_USER;
3745 /* if the user is not in the group */
3746 if (!user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3747 pdb_free_sam(&sam_pass);
3748 return NT_STATUS_MEMBER_NOT_IN_GROUP;
3752 se_priv_copy( &se_rights, &se_add_users );
3753 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3755 /******** BEGIN SeAddUsers BLOCK *********/
3757 if ( can_add_accounts )
3760 smb_delete_user_group(grp_name, pdb_get_username(sam_pass));
3762 if ( can_add_accounts )
3765 /******** END SeAddUsers BLOCK *********/
3767 /* check if the user has been removed then ... */
3768 if (user_in_unix_group_list(pdb_get_username(sam_pass), grp_name)) {
3769 pdb_free_sam(&sam_pass);
3770 return NT_STATUS_ACCESS_DENIED; /* don't know what to reply else */
3773 pdb_free_sam(&sam_pass);
3774 return NT_STATUS_OK;
3778 /****************************************************************************
3779 Delete a UNIX user on demand.
3780 ****************************************************************************/
3782 static int smb_delete_user(const char *unix_user)
3787 /* try winbindd first since it is impossible to determine where
3788 a user came from via NSS. Try the delete user script if this fails
3789 meaning the user did not exist in winbindd's list of accounts */
3791 if ( winbind_delete_user( unix_user ) ) {
3792 DEBUG(3,("winbind_delete_user: removed user (%s)\n", unix_user));
3797 /* fall back to 'delete user script' */
3799 pstrcpy(del_script, lp_deluser_script());
3802 all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
3803 ret = smbrun(del_script,NULL);
3804 DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
3809 /*********************************************************************
3810 _samr_delete_dom_user
3811 *********************************************************************/
3813 NTSTATUS _samr_delete_dom_user(pipes_struct *p, SAMR_Q_DELETE_DOM_USER *q_u, SAMR_R_DELETE_DOM_USER *r_u )
3816 SAM_ACCOUNT *sam_pass=NULL;
3819 BOOL can_add_accounts;
3822 DEBUG(5, ("_samr_delete_dom_user: %d\n", __LINE__));
3824 /* Find the policy handle. Open a policy on it. */
3825 if (!get_lsa_policy_samr_sid(p, &q_u->user_pol, &user_sid, &acc_granted))
3826 return NT_STATUS_INVALID_HANDLE;
3828 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_user"))) {
3832 if (!sid_check_is_in_our_domain(&user_sid))
3833 return NT_STATUS_CANNOT_DELETE;
3835 /* check if the user exists before trying to delete */
3836 pdb_init_sam(&sam_pass);
3837 if(!pdb_getsampwsid(sam_pass, &user_sid)) {
3838 DEBUG(5,("_samr_delete_dom_user:User %s doesn't exist.\n",
3839 sid_string_static(&user_sid)));
3840 pdb_free_sam(&sam_pass);
3841 return NT_STATUS_NO_SUCH_USER;
3844 se_priv_copy( &se_rights, &se_add_users );
3845 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3847 /******** BEGIN SeAddUsers BLOCK *********/
3849 if ( can_add_accounts )
3852 /* First delete the samba side....
3853 code is order to prevent unnecessary returns out of the admin
3856 if ( (ret = pdb_delete_sam_account(sam_pass)) == True ) {
3858 * Now delete the unix side ....
3859 * note: we don't check if the delete really happened
3860 * as the script is not necessary present
3861 * and maybe the sysadmin doesn't want to delete the unix side
3863 smb_delete_user( pdb_get_username(sam_pass) );
3866 if ( can_add_accounts )
3869 /******** END SeAddUsers BLOCK *********/
3872 DEBUG(5,("_samr_delete_dom_user:Failed to delete entry for user %s.\n", pdb_get_username(sam_pass)));
3873 pdb_free_sam(&sam_pass);
3874 return NT_STATUS_CANNOT_DELETE;
3878 pdb_free_sam(&sam_pass);
3880 if (!close_policy_hnd(p, &q_u->user_pol))
3881 return NT_STATUS_OBJECT_NAME_INVALID;
3883 return NT_STATUS_OK;
3886 /*********************************************************************
3887 _samr_delete_dom_group
3888 *********************************************************************/
3890 NTSTATUS _samr_delete_dom_group(pipes_struct *p, SAMR_Q_DELETE_DOM_GROUP *q_u, SAMR_R_DELETE_DOM_GROUP *r_u)
3895 fstring group_sid_str;
3901 BOOL can_add_accounts;
3904 DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
3906 /* Find the policy handle. Open a policy on it. */
3907 if (!get_lsa_policy_samr_sid(p, &q_u->group_pol, &group_sid, &acc_granted))
3908 return NT_STATUS_INVALID_HANDLE;
3910 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_group"))) {
3914 sid_copy(&dom_sid, &group_sid);
3915 sid_to_string(group_sid_str, &dom_sid);
3916 sid_split_rid(&dom_sid, &group_rid);
3918 DEBUG(10, ("sid is %s\n", group_sid_str));
3920 /* we check if it's our SID before deleting */
3921 if (!sid_equal(&dom_sid, get_global_sam_sid()))
3922 return NT_STATUS_NO_SUCH_GROUP;
3924 DEBUG(10, ("lookup on Domain SID\n"));
3926 if(!get_domain_group_from_sid(group_sid, &map))
3927 return NT_STATUS_NO_SUCH_GROUP;
3931 /* check if group really exists */
3932 if ( (grp=getgrgid(gid)) == NULL)
3933 return NT_STATUS_NO_SUCH_GROUP;
3935 se_priv_copy( &se_rights, &se_add_users );
3936 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
3938 /******** BEGIN SeAddUsers BLOCK *********/
3940 if ( can_add_accounts )
3943 /* delete mapping first */
3945 if ( (ret = pdb_delete_group_mapping_entry(group_sid)) == True ) {
3946 smb_delete_group( grp->gr_name );
3949 if ( can_add_accounts )
3952 /******** END SeAddUsers BLOCK *********/
3955 DEBUG(5,("_samr_delete_dom_group: Failed to delete mapping entry for group %s.\n",
3957 return NT_STATUS_ACCESS_DENIED;
3960 /* don't check that the unix group has been deleted. Work like
3961 _samr_delet_dom_user() */
3963 if (!close_policy_hnd(p, &q_u->group_pol))
3964 return NT_STATUS_OBJECT_NAME_INVALID;
3966 return NT_STATUS_OK;
3969 /*********************************************************************
3970 _samr_delete_dom_alias
3971 *********************************************************************/
3973 NTSTATUS _samr_delete_dom_alias(pipes_struct *p, SAMR_Q_DELETE_DOM_ALIAS *q_u, SAMR_R_DELETE_DOM_ALIAS *r_u)
3978 BOOL can_add_accounts;
3981 DEBUG(5, ("_samr_delete_dom_alias: %d\n", __LINE__));
3983 /* Find the policy handle. Open a policy on it. */
3984 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &alias_sid, &acc_granted))
3985 return NT_STATUS_INVALID_HANDLE;
3987 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS, "_samr_delete_dom_alias"))) {
3991 DEBUG(10, ("sid is %s\n", sid_string_static(&alias_sid)));
3993 if (!sid_check_is_in_our_domain(&alias_sid))
3994 return NT_STATUS_NO_SUCH_ALIAS;
3996 DEBUG(10, ("lookup on Local SID\n"));
3998 se_priv_copy( &se_rights, &se_add_users );
3999 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4001 /******** BEGIN SeAddUsers BLOCK *********/
4003 if ( can_add_accounts )
4006 /* Have passdb delete the alias */
4007 ret = pdb_delete_alias(&alias_sid);
4009 if ( can_add_accounts )
4012 /******** END SeAddUsers BLOCK *********/
4015 return NT_STATUS_ACCESS_DENIED;
4017 if (!close_policy_hnd(p, &q_u->alias_pol))
4018 return NT_STATUS_OBJECT_NAME_INVALID;
4020 return NT_STATUS_OK;
4023 /*********************************************************************
4024 _samr_create_dom_group
4025 *********************************************************************/
4027 NTSTATUS _samr_create_dom_group(pipes_struct *p, SAMR_Q_CREATE_DOM_GROUP *q_u, SAMR_R_CREATE_DOM_GROUP *r_u)
4034 struct samr_info *info;
4038 BOOL can_add_accounts;
4041 /* Find the policy handle. Open a policy on it. */
4042 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &dom_sid, &acc_granted))
4043 return NT_STATUS_INVALID_HANDLE;
4045 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_GROUP, "_samr_create_dom_group"))) {
4049 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4050 return NT_STATUS_ACCESS_DENIED;
4052 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4054 /* check if group already exist */
4055 if ((grp=getgrnam(name)) != NULL)
4056 return NT_STATUS_GROUP_EXISTS;
4058 se_priv_copy( &se_rights, &se_add_users );
4059 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4061 /******** BEGIN SeAddUsers BLOCK *********/
4063 if ( can_add_accounts )
4066 /* check that we successfully create the UNIX group */
4068 result = NT_STATUS_ACCESS_DENIED;
4069 if ( (smb_create_group(name, &gid) == 0) && ((grp=getgrgid(gid)) != NULL) ) {
4071 /* so far, so good */
4073 result = NT_STATUS_OK;
4075 r_u->rid = pdb_gid_to_group_rid( grp->gr_gid );
4077 /* add the group to the mapping table */
4079 sid_copy( &info_sid, get_global_sam_sid() );
4080 sid_append_rid( &info_sid, r_u->rid );
4081 sid_to_string( sid_string, &info_sid );
4083 /* reset the error code if we fail to add the mapping entry */
4085 if ( !add_initial_entry(grp->gr_gid, sid_string, SID_NAME_DOM_GRP, name, NULL) )
4086 result = NT_STATUS_ACCESS_DENIED;
4089 if ( can_add_accounts )
4092 /******** END SeAddUsers BLOCK *********/
4094 /* check if we should bail out here */
4096 if ( !NT_STATUS_IS_OK(result) )
4099 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4100 return NT_STATUS_NO_MEMORY;
4102 /* get a (unique) handle. open a policy on it. */
4103 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4104 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4106 return NT_STATUS_OK;
4109 /*********************************************************************
4110 _samr_create_dom_alias
4111 *********************************************************************/
4113 NTSTATUS _samr_create_dom_alias(pipes_struct *p, SAMR_Q_CREATE_DOM_ALIAS *q_u, SAMR_R_CREATE_DOM_ALIAS *r_u)
4119 struct samr_info *info;
4124 BOOL can_add_accounts;
4126 /* Find the policy handle. Open a policy on it. */
4127 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &dom_sid, &acc_granted))
4128 return NT_STATUS_INVALID_HANDLE;
4130 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_DOMAIN_CREATE_ALIAS, "_samr_create_alias"))) {
4134 if (!sid_equal(&dom_sid, get_global_sam_sid()))
4135 return NT_STATUS_ACCESS_DENIED;
4137 unistr2_to_ascii(name, &q_u->uni_acct_desc, sizeof(name)-1);
4139 se_priv_copy( &se_rights, &se_add_users );
4140 can_add_accounts = user_has_privileges( p->pipe_user.nt_user_token, &se_rights );
4142 /******** BEGIN SeAddUsers BLOCK *********/
4144 if ( can_add_accounts )
4147 /* Have passdb create the alias */
4148 result = pdb_create_alias(name, &r_u->rid);
4150 if ( can_add_accounts )
4153 /******** END SeAddUsers BLOCK *********/
4155 if (!NT_STATUS_IS_OK(result))
4158 sid_copy(&info_sid, get_global_sam_sid());
4159 sid_append_rid(&info_sid, r_u->rid);
4161 if (!NT_STATUS_IS_OK(sid_to_gid(&info_sid, &gid)))
4162 return NT_STATUS_ACCESS_DENIED;
4164 /* check if the group has been successfully created */
4165 if ((grp=getgrgid(gid)) == NULL)
4166 return NT_STATUS_ACCESS_DENIED;
4168 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4169 return NT_STATUS_NO_MEMORY;
4171 /* get a (unique) handle. open a policy on it. */
4172 if (!create_policy_hnd(p, &r_u->alias_pol, free_samr_info, (void *)info))
4173 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4175 return NT_STATUS_OK;
4178 /*********************************************************************
4179 _samr_query_groupinfo
4181 sends the name/comment pair of a domain group
4182 level 1 send also the number of users of that group
4183 *********************************************************************/
4185 NTSTATUS _samr_query_groupinfo(pipes_struct *p, SAMR_Q_QUERY_GROUPINFO *q_u, SAMR_R_QUERY_GROUPINFO *r_u)
4192 GROUP_INFO_CTR *ctr;
4196 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4197 return NT_STATUS_INVALID_HANDLE;
4199 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_LOOKUP_INFO, "_samr_query_groupinfo"))) {
4204 ret = get_domain_group_from_sid(group_sid, &map);
4207 return NT_STATUS_INVALID_HANDLE;
4209 ctr=TALLOC_ZERO_P(p->mem_ctx, GROUP_INFO_CTR);
4211 return NT_STATUS_NO_MEMORY;
4213 switch (q_u->switch_level) {
4215 ctr->switch_value1 = 1;
4216 if(!get_memberuids(map.gid, &uids, &num))
4217 return NT_STATUS_NO_SUCH_GROUP;
4219 init_samr_group_info1(&ctr->group.info1, map.nt_name, map.comment, num);
4223 ctr->switch_value1 = 3;
4224 init_samr_group_info3(&ctr->group.info3);
4227 ctr->switch_value1 = 4;
4228 init_samr_group_info4(&ctr->group.info4, map.comment);
4231 return NT_STATUS_INVALID_INFO_CLASS;
4234 init_samr_r_query_groupinfo(r_u, ctr, NT_STATUS_OK);
4236 return NT_STATUS_OK;
4239 /*********************************************************************
4242 update a domain group's comment.
4243 *********************************************************************/
4245 NTSTATUS _samr_set_groupinfo(pipes_struct *p, SAMR_Q_SET_GROUPINFO *q_u, SAMR_R_SET_GROUPINFO *r_u)
4249 GROUP_INFO_CTR *ctr;
4252 if (!get_lsa_policy_samr_sid(p, &q_u->pol, &group_sid, &acc_granted))
4253 return NT_STATUS_INVALID_HANDLE;
4255 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_GROUP_SET_INFO, "_samr_set_groupinfo"))) {
4259 if (!get_domain_group_from_sid(group_sid, &map))
4260 return NT_STATUS_NO_SUCH_GROUP;
4264 switch (ctr->switch_value1) {
4266 unistr2_to_ascii(map.comment, &(ctr->group.info1.uni_acct_desc), sizeof(map.comment)-1);
4269 unistr2_to_ascii(map.comment, &(ctr->group.info4.uni_acct_desc), sizeof(map.comment)-1);
4272 return NT_STATUS_INVALID_INFO_CLASS;
4275 if(!pdb_update_group_mapping_entry(&map)) {
4276 return NT_STATUS_NO_SUCH_GROUP;
4279 return NT_STATUS_OK;
4282 /*********************************************************************
4285 update an alias's comment.
4286 *********************************************************************/
4288 NTSTATUS _samr_set_aliasinfo(pipes_struct *p, SAMR_Q_SET_ALIASINFO *q_u, SAMR_R_SET_ALIASINFO *r_u)
4291 struct acct_info info;
4292 ALIAS_INFO_CTR *ctr;
4295 if (!get_lsa_policy_samr_sid(p, &q_u->alias_pol, &group_sid, &acc_granted))
4296 return NT_STATUS_INVALID_HANDLE;
4298 if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(acc_granted, SA_RIGHT_ALIAS_SET_INFO, "_samr_set_aliasinfo"))) {
4304 switch (ctr->switch_value1) {
4306 unistr2_to_ascii(info.acct_desc,
4307 &(ctr->alias.info3.uni_acct_desc),
4308 sizeof(info.acct_desc)-1);
4311 return NT_STATUS_INVALID_INFO_CLASS;
4314 if(!pdb_set_aliasinfo(&group_sid, &info)) {
4315 return NT_STATUS_ACCESS_DENIED;
4318 return NT_STATUS_OK;
4321 /*********************************************************************
4322 _samr_get_dom_pwinfo
4323 *********************************************************************/
4325 NTSTATUS _samr_get_dom_pwinfo(pipes_struct *p, SAMR_Q_GET_DOM_PWINFO *q_u, SAMR_R_GET_DOM_PWINFO *r_u)
4327 /* Perform access check. Since this rpc does not require a
4328 policy handle it will not be caught by the access checks on
4329 SAMR_CONNECT or SAMR_CONNECT_ANON. */
4331 if (!pipe_access_check(p)) {
4332 DEBUG(3, ("access denied to samr_get_dom_pwinfo\n"));
4333 r_u->status = NT_STATUS_ACCESS_DENIED;
4337 /* Actually, returning zeros here works quite well :-). */
4339 return NT_STATUS_OK;
4342 /*********************************************************************
4344 *********************************************************************/
4346 NTSTATUS _samr_open_group(pipes_struct *p, SAMR_Q_OPEN_GROUP *q_u, SAMR_R_OPEN_GROUP *r_u)
4351 struct samr_info *info;
4352 SEC_DESC *psd = NULL;
4354 uint32 des_access = q_u->access_mask;
4361 if (!get_lsa_policy_samr_sid(p, &q_u->domain_pol, &sid, &acc_granted))
4362 return NT_STATUS_INVALID_HANDLE;
4364 status = access_check_samr_function(acc_granted,
4365 SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_group");
4367 if ( !NT_STATUS_IS_OK(status) )
4370 /*check if access can be granted as requested by client. */
4371 make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0);
4372 se_map_generic(&des_access,&grp_generic_mapping);
4374 se_priv_copy( &se_rights, &se_add_users );
4376 status = access_check_samr_object(psd, p->pipe_user.nt_user_token,
4377 &se_rights, GENERIC_RIGHTS_GROUP_WRITE, des_access,
4378 &acc_granted, "_samr_open_group");
4380 if ( !NT_STATUS_IS_OK(status) )
4383 /* this should not be hard-coded like this */
4385 if (!sid_equal(&sid, get_global_sam_sid()))
4386 return NT_STATUS_ACCESS_DENIED;
4388 sid_copy(&info_sid, get_global_sam_sid());
4389 sid_append_rid(&info_sid, q_u->rid_group);
4390 sid_to_string(sid_string, &info_sid);
4392 if ((info = get_samr_info_by_sid(&info_sid)) == NULL)
4393 return NT_STATUS_NO_MEMORY;
4395 info->acc_granted = acc_granted;
4397 DEBUG(10, ("_samr_open_group:Opening SID: %s\n", sid_string));
4399 /* check if that group really exists */
4401 ret = get_domain_group_from_sid(info->sid, &map);
4404 return NT_STATUS_NO_SUCH_GROUP;
4406 /* get a (unique) handle. open a policy on it. */
4407 if (!create_policy_hnd(p, &r_u->pol, free_samr_info, (void *)info))
4408 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4410 return NT_STATUS_OK;
4413 /*********************************************************************
4414 _samr_remove_sid_foreign_domain
4415 *********************************************************************/
4417 NTSTATUS _samr_remove_sid_foreign_domain(pipes_struct *p,
4418 SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN *q_u,
4419 SAMR_R_REMOVE_SID_FOREIGN_DOMAIN *r_u)
4421 DOM_SID delete_sid, alias_sid;
4422 SAM_ACCOUNT *sam_pass=NULL;
4425 BOOL is_user = False;
4427 enum SID_NAME_USE type = SID_NAME_UNKNOWN;
4429 sid_copy( &delete_sid, &q_u->sid.sid );
4431 DEBUG(5,("_samr_remove_sid_foreign_domain: removing SID [%s]\n",
4432 sid_string_static(&delete_sid)));
4434 /* Find the policy handle. Open a policy on it. */
4436 if (!get_lsa_policy_samr_sid(p, &q_u->dom_pol, &alias_sid, &acc_granted))
4437 return NT_STATUS_INVALID_HANDLE;
4439 result = access_check_samr_function(acc_granted, STD_RIGHT_DELETE_ACCESS,
4440 "_samr_remove_sid_foreign_domain");
4442 if (!NT_STATUS_IS_OK(result))
4445 DEBUG(8, ("_samr_remove_sid_foreign_domain:sid is %s\n",
4446 sid_string_static(&alias_sid)));
4448 /* make sure we can handle this */
4450 if ( sid_check_is_domain(&alias_sid) )
4451 type = SID_NAME_DOM_GRP;
4452 else if ( sid_check_is_builtin(&alias_sid) )
4453 type = SID_NAME_ALIAS;
4455 if ( type == SID_NAME_UNKNOWN ) {
4456 DEBUG(10, ("_samr_remove_sid_foreign_domain: can't operate on what we don't own!\n"));
4457 return NT_STATUS_OK;
4460 /* check if the user exists before trying to delete */
4462 pdb_init_sam(&sam_pass);
4464 if ( pdb_getsampwsid(sam_pass, &delete_sid) ) {
4467 /* maybe it is a group */
4468 if( !pdb_getgrsid(&map, delete_sid) ) {
4469 DEBUG(3,("_samr_remove_sid_foreign_domain: %s is not a user or a group!\n",
4470 sid_string_static(&delete_sid)));
4471 result = NT_STATUS_INVALID_SID;
4476 /* we can only delete a user from a group since we don't have
4477 nested groups anyways. So in the latter case, just say OK */
4480 GROUP_MAP *mappings = NULL;
4484 if ( pdb_enum_group_mapping(type, &mappings, &num_groups, False) && num_groups>0 ) {
4486 /* interate over the groups */
4487 for ( i=0; i<num_groups; i++ ) {
4489 grp2 = getgrgid(mappings[i].gid);
4492 DEBUG(0,("_samr_remove_sid_foreign_domain: group mapping without UNIX group!\n"));
4496 if ( !user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) )
4499 smb_delete_user_group(grp2->gr_name, pdb_get_username(sam_pass));
4501 if ( user_in_unix_group_list(pdb_get_username(sam_pass), grp2->gr_name) ) {
4502 /* should we fail here ? */
4503 DEBUG(0,("_samr_remove_sid_foreign_domain: Delete user [%s] from group [%s] failed!\n",
4504 pdb_get_username(sam_pass), grp2->gr_name ));
4508 DEBUG(10,("_samr_remove_sid_foreign_domain: Removed user [%s] from group [%s]!\n",
4509 pdb_get_username(sam_pass), grp2->gr_name ));
4512 SAFE_FREE(mappings);
4516 result = NT_STATUS_OK;
4519 pdb_free_sam(&sam_pass);
4524 /*******************************************************************
4526 ********************************************************************/
4528 NTSTATUS _samr_unknown_2e(pipes_struct *p, SAMR_Q_UNKNOWN_2E *q_u, SAMR_R_UNKNOWN_2E *r_u)
4530 struct samr_info *info = NULL;
4532 uint32 min_pass_len,pass_hist,flag;
4533 time_t u_expire, u_min_age;
4534 NTTIME nt_expire, nt_min_age;
4536 time_t u_lock_duration, u_reset_time;
4537 NTTIME nt_lock_duration, nt_reset_time;
4543 uint32 num_users=0, num_groups=0, num_aliases=0;
4545 uint32 account_policy_temp;
4547 if ((ctr = TALLOC_ZERO_P(p->mem_ctx, SAM_UNK_CTR)) == NULL)
4548 return NT_STATUS_NO_MEMORY;
4552 r_u->status = NT_STATUS_OK;
4554 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4556 /* find the policy handle. open a policy on it. */
4557 if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)&info))
4558 return NT_STATUS_INVALID_HANDLE;
4560 switch (q_u->switch_value) {
4562 pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &account_policy_temp);
4563 min_pass_len = account_policy_temp;
4565 pdb_get_account_policy(AP_PASSWORD_HISTORY, &account_policy_temp);
4566 pass_hist = account_policy_temp;
4568 pdb_get_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, &account_policy_temp);
4569 flag = account_policy_temp;
4571 pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &account_policy_temp);
4572 u_expire = account_policy_temp;
4574 pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &account_policy_temp);
4575 u_min_age = account_policy_temp;
4577 unix_to_nt_time_abs(&nt_expire, u_expire);
4578 unix_to_nt_time_abs(&nt_min_age, u_min_age);
4580 init_unk_info1(&ctr->info.inf1, (uint16)min_pass_len, (uint16)pass_hist,
4581 flag, nt_expire, nt_min_age);
4585 r_u->status=load_sampwd_entries(info, ACB_NORMAL, False);
4587 if (!NT_STATUS_IS_OK(r_u->status)) {
4588 DEBUG(5, ("_samr_unknown_2e: load_sampwd_entries failed\n"));
4591 num_users=info->disp_info.num_user_account;
4594 r_u->status=load_group_domain_entries(info, get_global_sam_sid());
4595 if (NT_STATUS_IS_ERR(r_u->status)) {
4596 DEBUG(5, ("_samr_unknown_2e: load_group_domain_entries failed\n"));
4599 num_groups=info->disp_info.num_group_account;
4602 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
4603 u_logout = account_policy_temp;
4605 unix_to_nt_time_abs(&nt_logout, u_logout);
4607 /* The time call below is to get a sequence number for the sam. FIXME !!! JRA. */
4608 init_unk_info2(&ctr->info.inf2, "", lp_workgroup(), global_myname(), (uint32) time(NULL),
4609 num_users, num_groups, num_aliases, nt_logout);
4612 pdb_get_account_policy(AP_TIME_TO_LOGOUT, &account_policy_temp);
4613 u_logout = account_policy_temp;
4615 unix_to_nt_time_abs(&nt_logout, u_logout);
4617 init_unk_info3(&ctr->info.inf3, nt_logout);
4620 init_unk_info5(&ctr->info.inf5, global_myname());
4623 init_unk_info6(&ctr->info.inf6);
4626 init_unk_info7(&ctr->info.inf7);
4629 init_unk_info8(&ctr->info.inf8, (uint32) time(NULL));
4632 pdb_get_account_policy(AP_LOCK_ACCOUNT_DURATION, &account_policy_temp);
4633 u_lock_duration = account_policy_temp;
4634 if (u_lock_duration != -1)
4635 u_lock_duration *= 60;
4637 pdb_get_account_policy(AP_RESET_COUNT_TIME, &account_policy_temp);
4638 u_reset_time = account_policy_temp * 60;
4640 pdb_get_account_policy(AP_BAD_ATTEMPT_LOCKOUT, &account_policy_temp);
4641 lockout = account_policy_temp;
4643 unix_to_nt_time_abs(&nt_lock_duration, u_lock_duration);
4644 unix_to_nt_time_abs(&nt_reset_time, u_reset_time);
4646 init_unk_info12(&ctr->info.inf12, nt_lock_duration, nt_reset_time, (uint16)lockout);
4649 return NT_STATUS_INVALID_INFO_CLASS;
4652 init_samr_r_samr_unknown_2e(r_u, q_u->switch_value, ctr, NT_STATUS_OK);
4654 DEBUG(5,("_samr_unknown_2e: %d\n", __LINE__));
4659 /*******************************************************************
4661 ********************************************************************/
4663 NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R_SET_DOMAIN_INFO *r_u)
4665 time_t u_expire, u_min_age;
4667 time_t u_lock_duration, u_reset_time;
4669 r_u->status = NT_STATUS_OK;
4671 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));
4673 /* find the policy handle. open a policy on it. */
4674 if (!find_policy_by_hnd(p, &q_u->domain_pol, NULL))
4675 return NT_STATUS_INVALID_HANDLE;
4677 DEBUG(5,("_samr_set_dom_info: switch_value: %d\n", q_u->switch_value));
4679 switch (q_u->switch_value) {
4681 u_expire=nt_time_to_unix_abs(&q_u->ctr->info.inf1.expire);
4682 u_min_age=nt_time_to_unix_abs(&q_u->ctr->info.inf1.min_passwordage);
4684 pdb_set_account_policy(AP_MIN_PASSWORD_LEN, (uint32)q_u->ctr->info.inf1.min_length_password);
4685 pdb_set_account_policy(AP_PASSWORD_HISTORY, (uint32)q_u->ctr->info.inf1.password_history);
4686 pdb_set_account_policy(AP_USER_MUST_LOGON_TO_CHG_PASS, (uint32)q_u->ctr->info.inf1.flag);
4687 pdb_set_account_policy(AP_MAX_PASSWORD_AGE, (int)u_expire);
4688 pdb_set_account_policy(AP_MIN_PASSWORD_AGE, (int)u_min_age);
4693 u_logout=nt_time_to_unix_abs(&q_u->ctr->info.inf3.logout);
4694 pdb_set_account_policy(AP_TIME_TO_LOGOUT, (int)u_logout);
4703 u_lock_duration=nt_time_to_unix_abs(&q_u->ctr->info.inf12.duration);
4704 if (u_lock_duration != -1)
4705 u_lock_duration /= 60;
4707 u_reset_time=nt_time_to_unix_abs(&q_u->ctr->info.inf12.reset_count)/60;
4709 pdb_set_account_policy(AP_LOCK_ACCOUNT_DURATION, (int)u_lock_duration);
4710 pdb_set_account_policy(AP_RESET_COUNT_TIME, (int)u_reset_time);
4711 pdb_set_account_policy(AP_BAD_ATTEMPT_LOCKOUT, (uint32)q_u->ctr->info.inf12.bad_attempt_lockout);
4714 return NT_STATUS_INVALID_INFO_CLASS;
4717 init_samr_r_set_domain_info(r_u, NT_STATUS_OK);
4719 DEBUG(5,("_samr_set_dom_info: %d\n", __LINE__));