diff options
author | Andrew Bartlett <abartlet@samba.org> | 2013-11-07 16:23:12 +1300 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2014-03-13 10:26:03 +0100 |
commit | 9f53b61f0674f7855a42b8e0de66f343f4592589 (patch) | |
tree | d5f0cf798bcc5927d3aa1e8077bc19f73c939c34 /source3/smbd/lanman.c | |
parent | 76e5ea3a2c5f49cfc1026bd7c6b8baddb1e7dc16 (diff) | |
download | samba-9f53b61f0674f7855a42b8e0de66f343f4592589.tar.gz |
CVE-2013-4496:samr: Remove ChangePasswordUser
This old password change mechanism does not provide the plaintext to
validate against password complexity, and it is not used by modern
clients. It also has quite difficult semantics to handle regarding
password lockout.
The missing features in both implementations (by design) were:
- the password complexity checks (no plaintext)
- the minimum password length (no plaintext)
Additionally, the source3 version did not check:
- the minimum password age
- pdb_get_pass_can_change() which checks the security
descriptor for the 'user cannot change password' setting.
- the password history
- the output of the 'passwd program' if 'unix passwd sync = yes'.
Finally, the mechanism was almost useless, as it was incorrectly
only made available to administrative users with permission
to reset the password. It is removed here so that it is not
mistakenly reinstated in the future.
Andrew Bartlett
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10245
Change-Id: If2edd3183c177e5ff37c9511b0d0ad0dd9038c66
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-on: https://gerrit.samba.org/37
Diffstat (limited to 'source3/smbd/lanman.c')
-rw-r--r-- | source3/smbd/lanman.c | 254 |
1 files changed, 0 insertions, 254 deletions
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index f7f77534ee4..63c2ad7cae2 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -2948,259 +2948,6 @@ static bool api_NetRemoteTOD(struct smbd_server_connection *sconn, } /**************************************************************************** - Set the user password. -*****************************************************************************/ - -static bool api_SetUserPassword(struct smbd_server_connection *sconn, - connection_struct *conn,uint64_t vuid, - char *param, int tpscnt, - char *data, int tdscnt, - int mdrcnt,int mprcnt, - char **rdata,char **rparam, - int *rdata_len,int *rparam_len) -{ - char *np = get_safe_str_ptr(param,tpscnt,param,2); - char *p = NULL; - fstring user; - fstring pass1,pass2; - TALLOC_CTX *mem_ctx = talloc_tos(); - NTSTATUS status, result; - struct rpc_pipe_client *cli = NULL; - struct policy_handle connect_handle, domain_handle, user_handle; - struct lsa_String domain_name; - struct dom_sid2 *domain_sid; - struct lsa_String names; - struct samr_Ids rids; - struct samr_Ids types; - struct samr_Password old_lm_hash; - struct samr_Password new_lm_hash; - int errcode = NERR_badpass; - uint32_t rid; - int encrypted; - int min_pwd_length; - struct dcerpc_binding_handle *b = NULL; - - /* Skip 2 strings. */ - p = skip_string(param,tpscnt,np); - p = skip_string(param,tpscnt,p); - - if (!np || !p) { - return False; - } - - /* Do we have a string ? */ - if (skip_string(param,tpscnt,p) == NULL) { - return False; - } - pull_ascii_fstring(user,p); - - p = skip_string(param,tpscnt,p); - if (!p) { - return False; - } - - memset(pass1,'\0',sizeof(pass1)); - memset(pass2,'\0',sizeof(pass2)); - /* - * We use 31 here not 32 as we're checking - * the last byte we want to access is safe. - */ - if (!is_offset_safe(param,tpscnt,p,31)) { - return False; - } - memcpy(pass1,p,16); - memcpy(pass2,p+16,16); - - encrypted = get_safe_SVAL(param,tpscnt,p+32,0,-1); - if (encrypted == -1) { - errcode = W_ERROR_V(WERR_INVALID_PARAM); - goto out; - } - - min_pwd_length = get_safe_SVAL(param,tpscnt,p+34,0,-1); - if (min_pwd_length == -1) { - errcode = W_ERROR_V(WERR_INVALID_PARAM); - goto out; - } - - *rparam_len = 4; - *rparam = smb_realloc_limit(*rparam,*rparam_len); - if (!*rparam) { - return False; - } - - *rdata_len = 0; - - DEBUG(3,("Set password for <%s> (encrypted: %d, min_pwd_length: %d)\n", - user, encrypted, min_pwd_length)); - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - ZERO_STRUCT(user_handle); - - status = rpc_pipe_open_interface(mem_ctx, &ndr_table_samr, - conn->session_info, - conn->sconn->remote_address, - conn->sconn->msg_ctx, - &cli); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("api_SetUserPassword: could not connect to samr: %s\n", - nt_errstr(status))); - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - - b = cli->binding_handle; - - status = dcerpc_samr_Connect2(b, mem_ctx, - lp_netbios_name(), - SAMR_ACCESS_CONNECT_TO_SERVER | - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_LOOKUP_DOMAIN, - &connect_handle, - &result); - if (!NT_STATUS_IS_OK(status)) { - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - if (!NT_STATUS_IS_OK(result)) { - errcode = W_ERROR_V(ntstatus_to_werror(result)); - goto out; - } - - init_lsa_String(&domain_name, get_global_sam_name()); - - status = dcerpc_samr_LookupDomain(b, mem_ctx, - &connect_handle, - &domain_name, - &domain_sid, - &result); - if (!NT_STATUS_IS_OK(status)) { - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - if (!NT_STATUS_IS_OK(result)) { - errcode = W_ERROR_V(ntstatus_to_werror(result)); - goto out; - } - - status = dcerpc_samr_OpenDomain(b, mem_ctx, - &connect_handle, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, - domain_sid, - &domain_handle, - &result); - if (!NT_STATUS_IS_OK(status)) { - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - if (!NT_STATUS_IS_OK(result)) { - errcode = W_ERROR_V(ntstatus_to_werror(result)); - goto out; - } - - init_lsa_String(&names, user); - - status = dcerpc_samr_LookupNames(b, mem_ctx, - &domain_handle, - 1, - &names, - &rids, - &types, - &result); - if (!NT_STATUS_IS_OK(status)) { - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - if (!NT_STATUS_IS_OK(result)) { - errcode = W_ERROR_V(ntstatus_to_werror(result)); - goto out; - } - - if (rids.count != 1) { - errcode = W_ERROR_V(WERR_NO_SUCH_USER); - goto out; - } - if (rids.count != types.count) { - errcode = W_ERROR_V(WERR_INVALID_PARAM); - goto out; - } - if (types.ids[0] != SID_NAME_USER) { - errcode = W_ERROR_V(WERR_INVALID_PARAM); - goto out; - } - - rid = rids.ids[0]; - - status = dcerpc_samr_OpenUser(b, mem_ctx, - &domain_handle, - SAMR_USER_ACCESS_CHANGE_PASSWORD, - rid, - &user_handle, - &result); - if (!NT_STATUS_IS_OK(status)) { - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - if (!NT_STATUS_IS_OK(result)) { - errcode = W_ERROR_V(ntstatus_to_werror(result)); - goto out; - } - - if (encrypted == 0) { - E_deshash(pass1, old_lm_hash.hash); - E_deshash(pass2, new_lm_hash.hash); - } else { - ZERO_STRUCT(old_lm_hash); - ZERO_STRUCT(new_lm_hash); - memcpy(old_lm_hash.hash, pass1, MIN(strlen(pass1), 16)); - memcpy(new_lm_hash.hash, pass2, MIN(strlen(pass2), 16)); - } - - status = dcerpc_samr_ChangePasswordUser(b, mem_ctx, - &user_handle, - true, /* lm_present */ - &old_lm_hash, - &new_lm_hash, - false, /* nt_present */ - NULL, /* old_nt_crypted */ - NULL, /* new_nt_crypted */ - false, /* cross1_present */ - NULL, /* nt_cross */ - false, /* cross2_present */ - NULL, /* lm_cross */ - &result); - if (!NT_STATUS_IS_OK(status)) { - errcode = W_ERROR_V(ntstatus_to_werror(status)); - goto out; - } - if (!NT_STATUS_IS_OK(result)) { - errcode = W_ERROR_V(ntstatus_to_werror(result)); - goto out; - } - - errcode = NERR_Success; - out: - - if (b && is_valid_policy_hnd(&user_handle)) { - dcerpc_samr_Close(b, mem_ctx, &user_handle, &result); - } - if (b && is_valid_policy_hnd(&domain_handle)) { - dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result); - } - if (b && is_valid_policy_hnd(&connect_handle)) { - dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result); - } - - memset((char *)pass1,'\0',sizeof(fstring)); - memset((char *)pass2,'\0',sizeof(fstring)); - - SSVAL(*rparam,0,errcode); - SSVAL(*rparam,2,0); /* converter word */ - return(True); -} - -/**************************************************************************** Set the user password (SamOEM version - gets plaintext). ****************************************************************************/ @@ -5797,7 +5544,6 @@ static const struct { {"NetServerEnum2", RAP_NetServerEnum2, api_RNetServerEnum2}, /* anon OK */ {"NetServerEnum3", RAP_NetServerEnum3, api_RNetServerEnum3}, /* anon OK */ {"WAccessGetUserPerms",RAP_WAccessGetUserPerms,api_WAccessGetUserPerms}, - {"SetUserPassword", RAP_WUserPasswordSet2, api_SetUserPassword}, {"WWkstaUserLogon", RAP_WWkstaUserLogon, api_WWkstaUserLogon}, {"PrintJobInfo", RAP_WPrintJobSetInfo, api_PrintJobInfo}, {"WPrintDriverEnum", RAP_WPrintDriverEnum, api_WPrintDriverEnum}, |