The Samba-Bugzilla – Attachment 1415 Details for
Bug 2964
Unable to set "User Cannot Change Password" via User Manager
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
initial patch (inspired by tng)
samba3-acb_pwlock.diff (text/plain), 12.59 KB, created by
Guenther Deschner
on 2005-09-05 08:58:45 UTC
(
hide
)
Description:
initial patch (inspired by tng)
Filename:
MIME Type:
Creator:
Guenther Deschner
Created:
2005-09-05 08:58:45 UTC
Size:
12.59 KB
patch
obsolete
>Index: include/smb.h >=================================================================== >--- include/smb.h (revision 10033) >+++ include/smb.h (working copy) >@@ -228,6 +228,7 @@ > #define ACB_SVRTRUST 0x0100 /* 1 = Server trust account (BDC) */ > #define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */ > #define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */ >+#define ACB_PWLOCK 0x0800 /* 1 = Password is locked and connot be changed remotely */ > > #define MAX_HOURS_LEN 32 > >Index: passdb/passdb.c >=================================================================== >--- passdb/passdb.c (revision 10033) >+++ passdb/passdb.c (working copy) >@@ -479,6 +479,7 @@ > if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L'; > if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X'; > if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I'; >+ if (acct_ctrl & ACB_PWLOCK ) acct_str[i++] = 'P'; > > for ( ; i < length - 2 ; i++ ) > acct_str[i] = ' '; >@@ -520,6 +521,7 @@ > case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ } > case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ } > case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ } >+ case 'P': { acct_ctrl |= ACB_PWLOCK ; break; /* 'P'assword may not change. */ } > case ' ': { break; } > case ':': > case '\n': >Index: smbd/chgpasswd.c >=================================================================== >--- smbd/chgpasswd.c (revision 10033) >+++ smbd/chgpasswd.c (working copy) >@@ -654,6 +654,12 @@ > return False; > } > >+ if (acct_ctrl & ACB_PWLOCK) { >+ DEBUG(0,("change_lanman_password: account %s may not change password.\n", >+ pdb_get_username(sampass))); >+ return False; >+ } >+ > if (pwd == NULL) { > if (acct_ctrl & ACB_PWNOTREQ) { > uchar no_pw[14]; >@@ -778,11 +784,18 @@ > acct_ctrl = pdb_get_acct_ctrl(sampass); > > if (acct_ctrl & ACB_DISABLED) { >- DEBUG(2,("check_lanman_password: account %s disabled.\n", user)); >+ DEBUG(2,("check_oem_password: account %s disabled.\n", user)); > pdb_free_sam(&sampass); > return NT_STATUS_ACCOUNT_DISABLED; > } > >+ if (acct_ctrl & ACB_PWLOCK) { >+ DEBUG(2,("check_oem_password: account %s may not change password.\n", user)); >+ pdb_free_sam(&sampass); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ > if ((acct_ctrl & ACB_PWNOTREQ) && lp_null_passwords()) { > /* construct a null password (in case one is needed */ > no_pw[0] = 0; >Index: rpc_server/srv_samr_nt.c >=================================================================== >--- rpc_server/srv_samr_nt.c (revision 10033) >+++ rpc_server/srv_samr_nt.c (working copy) >@@ -78,18 +78,25 @@ > > static NTSTATUS make_samr_object_sd( TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size, > struct generic_mapping *map, >- DOM_SID *sid, uint32 sid_access ) >+ DOM_SID *sid, uint32 sid_access, BOOL pw_can_change ) > { > DOM_SID domadmin_sid; > SEC_ACE ace[5]; /* at most 5 entries */ > SEC_ACCESS mask; > size_t i = 0; >+ uint32 tmp_mask; > > SEC_ACL *psa = NULL; > > /* basic access for Everyone */ >- >- init_sec_access(&mask, map->generic_execute | map->generic_read ); >+ tmp_mask = map->generic_execute | map->generic_read; >+ >+ if (pw_can_change) >+ tmp_mask |= SA_RIGHT_USER_CHANGE_PASSWORD; >+ else >+ tmp_mask &= ~SA_RIGHT_USER_CHANGE_PASSWORD; >+ >+ init_sec_access(&mask, tmp_mask ); > init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0); > > /* add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */ >@@ -365,7 +372,7 @@ > > /*check if access can be granted as requested by client. */ > >- make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0 ); >+ make_samr_object_sd( p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0, True ); > se_map_generic( &des_access, &dom_generic_mapping ); > > se_priv_copy( &se_rights, &se_machine_account ); >@@ -421,19 +428,7 @@ > return r_u->status; > } > >- > /******************************************************************* >- _samr_set_sec_obj >- ********************************************************************/ >- >-NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u) >-{ >- DEBUG(0,("_samr_set_sec_obj: Not yet implemented!\n")); >- return NT_STATUS_NOT_IMPLEMENTED; >-} >- >- >-/******************************************************************* > ********************************************************************/ > > static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol, >@@ -453,7 +448,118 @@ > return True; > } > >+ > /******************************************************************* >+********************************************************************/ >+ >+static const SEC_ACE *acl_find_ace(const SEC_ACL *acl, const DOM_SID *sid) >+{ >+ uint32 i; >+ const SEC_ACE *ace; >+ if (!acl || !acl->ace || !sid) >+ return NULL; >+ ace = acl->ace; >+ for (i = acl->num_aces; i; i--, ace++) >+ { >+ if (sid_equal(&ace->trustee, sid)) >+ return ace; >+ } >+ return NULL; >+} >+ >+ >+/******************************************************************* >+ _samr_set_sec_obj >+ ********************************************************************/ >+ >+NTSTATUS _samr_set_sec_obj(pipes_struct *p, SAMR_Q_SET_SEC_OBJ *q_u, SAMR_R_SET_SEC_OBJ *r_u) >+{ >+ DOM_SID pol_sid; >+ uint32 acc_granted; >+ fstring sid_str; >+ NTSTATUS status; >+ SAM_USER_INFO_16 id16; >+ SAM_ACCOUNT *smbpass = NULL; >+ BOOL ret; >+ const SEC_ACE *ace; >+ >+ DEBUG(10,("_samr_set_sec_obj:\n")); >+ >+ ZERO_STRUCT(id16); >+ >+ if (!q_u->buf || !q_u->buf->sec) >+ return NT_STATUS_INVALID_PARAMETER; >+ >+ if (q_u->sec_info != 0x00000004) >+ return NT_STATUS_NOT_IMPLEMENTED; >+ >+ ace = acl_find_ace(q_u->buf->sec->dacl, &global_sid_World); >+ if (!ace) { >+ DEBUG(0, ("_samr_set_sec_obj: Didn't find everyone ace\n")); >+ return NT_STATUS_NOT_IMPLEMENTED; >+ } >+ >+ /* find sid from handle */ >+ if (!get_lsa_policy_samr_sid(p, &q_u->pol, &pol_sid, &acc_granted)) >+ return NT_STATUS_INVALID_HANDLE; >+ >+ >+ /* check rights (FIXME) */ >+ status = access_check_samr_function( acc_granted, >+ SA_RIGHT_DOMAIN_OPEN_ACCOUNT, "_samr_open_user" ); >+ >+ if (!NT_STATUS_IS_OK(status)) >+ return status; >+ >+ sid_to_string(sid_str, &pol_sid); >+ >+ DEBUG(10,("_samr_set_sec_obj: will have to look for %s\n", sid_str)); >+ >+ >+ /* query pdb to get the user */ >+ status = pdb_init_sam_talloc(p->mem_ctx, &smbpass); >+ >+ if ( !NT_STATUS_IS_OK(status) ) >+ return status; >+ >+ become_root(); >+ ret = pdb_getsampwsid(smbpass, &pol_sid); >+ unbecome_root(); >+ >+ if (ret==False) { >+ DEBUG(0,("_samr_set_sec_obj: User %s not found\n", sid_str)); >+ pdb_free_sam(&smbpass); >+ return NT_STATUS_NO_SUCH_USER; >+ } >+ >+ DEBUG(10,("_samr_set_sec_obj: User:[%s]\n", pdb_get_username(smbpass) )); >+ >+ >+ /* manipulate the acctflags */ >+ init_sam_user_info16(&id16, pdb_get_acct_ctrl(smbpass) ); >+ >+ DEBUG(10,("_samr_set_sec_obj: acb_info was: 0x%08x\n", id16.acb_info)); >+ >+ if (ace->info.mask & SA_RIGHT_USER_CHANGE_PASSWORD) { >+ DEBUG(10,("_samr_set_sec_obj: user may change his password, clearing bit if necessary\n")); >+ id16.acb_info &= ~ACB_PWLOCK; >+ } else { >+ DEBUG(10,("_samr_set_sec_obj: user may not change his password\n")); >+ id16.acb_info |= ACB_PWLOCK; >+ } >+ >+ DEBUG(10,("_samr_set_sec_obj: acb_info is now: 0x%08x\n", id16.acb_info)); >+ if (!set_user_info_16(&id16, smbpass)) { >+ pdb_free_sam(&smbpass); >+ return NT_STATUS_ACCESS_DENIED; >+ } >+ >+ pdb_free_sam(&smbpass); >+ return NT_STATUS_OK; >+} >+ >+ >+/******************************************************************* > _samr_query_sec_obj > ********************************************************************/ > >@@ -481,27 +587,57 @@ > if (pol_sid.sid_rev_num == 0) > { > DEBUG(5,("_samr_query_sec_obj: querying security on SAM\n")); >- r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); >+ r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0, True); > } > else if (sid_equal(&pol_sid,get_global_sam_sid())) /* check if it is our domain SID */ > > { > DEBUG(5,("_samr_query_sec_obj: querying security on Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); >- r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0); >+ r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0, True); > } > else if (sid_equal(&pol_sid,&global_sid_Builtin)) /* check if it is the Builtin Domain */ > { > /* TODO: Builtin probably needs a different SD with restricted write access*/ > DEBUG(5,("_samr_query_sec_obj: querying security on Builtin Domain with SID: %s\n", sid_to_string(str_sid, &pol_sid))); >- r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0); >+ r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &dom_generic_mapping, NULL, 0, True); > } > else if (sid_check_is_in_our_domain(&pol_sid) || > sid_check_is_in_builtin(&pol_sid)) > { > /* TODO: different SDs have to be generated for aliases groups and users. > Currently all three get a default user SD */ >+ >+ SAM_ACCOUNT *smbpass = NULL; >+ BOOL ret; >+ BOOL may_change = True; >+ >+ /* query pdb to get the user */ >+ r_u->status = pdb_init_sam_talloc(p->mem_ctx, &smbpass); >+ >+ if ( !NT_STATUS_IS_OK(r_u->status) ) >+ return r_u->status; >+ >+ become_root(); >+ ret = pdb_getsampwsid(smbpass, &pol_sid); >+ unbecome_root(); >+ >+ if (ret == False) { >+ DEBUG(0,("_samr_query_sec_obj: User %s not found\n", str_sid)); >+ pdb_free_sam(&smbpass); >+ return NT_STATUS_NO_SUCH_USER; >+ } >+ >+ DEBUG(10,("_samr_query_sec_obj: User:[%s]\n", pdb_get_username(smbpass) )); >+ >+ if (pdb_get_acct_ctrl(smbpass) & ACB_PWLOCK ) >+ may_change = False; >+ >+ pdb_free_sam(&smbpass); >+ >+ > DEBUG(10,("_samr_query_sec_obj: querying security on Object with SID: %s\n", sid_to_string(str_sid, &pol_sid))); >- r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW); >+ r_u->status = make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &pol_sid, SAMR_USR_RIGHTS_WRITE_PW, >+ may_change); > } > else return NT_STATUS_OBJECT_TYPE_MISMATCH; > >@@ -1339,7 +1475,7 @@ > > /* check if access can be granted as requested by client. */ > >- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); >+ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW, True); > se_map_generic(&des_access, &usr_generic_mapping); > > se_priv_copy( &se_rights, &se_machine_account ); >@@ -2059,7 +2195,7 @@ > > sid_copy(&sid, pdb_get_user_sid(sam_pass)); > >- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW); >+ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &usr_generic_mapping, &sid, SAMR_USR_RIGHTS_WRITE_PW, True); > se_map_generic(&des_access, &usr_generic_mapping); > > nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, >@@ -2160,7 +2296,7 @@ > return r_u->status; > } > >- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); >+ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0, True); > se_map_generic(&des_access, &sam_generic_mapping); > > nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, >@@ -2211,7 +2347,7 @@ > return r_u->status; > } > >- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0); >+ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0, True); > se_map_generic(&des_access, &sam_generic_mapping); > > nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, >@@ -2385,7 +2521,7 @@ > > /*check if access can be granted as requested by client. */ > >- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0); >+ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &ali_generic_mapping, NULL, 0, True); > se_map_generic(&des_access,&ali_generic_mapping); > > se_priv_copy( &se_rights, &se_add_users ); >@@ -2420,7 +2556,7 @@ > set_user_info_16 > ********************************************************************/ > >-static BOOL set_user_info_16(const SAM_USER_INFO_16 *id16, SAM_ACCOUNT *pwd) >+BOOL set_user_info_16(const SAM_USER_INFO_16 *id16, SAM_ACCOUNT *pwd) > { > if (id16 == NULL) { > DEBUG(5, ("set_user_info_16: NULL id16\n")); >@@ -4070,7 +4206,7 @@ > return status; > > /*check if access can be granted as requested by client. */ >- make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0); >+ make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &grp_generic_mapping, NULL, 0, True); > se_map_generic(&des_access,&grp_generic_mapping); > > se_priv_copy( &se_rights, &se_add_users );
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 2964
: 1415