diff options
author | Andrew Bartlett <abartlet@samba.org> | 2001-09-26 12:28:46 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2001-09-26 12:28:46 +0000 |
commit | 71850be47edf5e1c3d36eec45c006a9f94c7f6ce (patch) | |
tree | 3464ecd6e5b37ff7bff9d885b6099fe09999617d | |
parent | 83db39d2b5624217422b4c10509d589018f7a329 (diff) | |
download | samba-71850be47edf5e1c3d36eec45c006a9f94c7f6ce.tar.gz samba-71850be47edf5e1c3d36eec45c006a9f94c7f6ce.tar.bz2 samba-71850be47edf5e1c3d36eec45c006a9f94c7f6ce.zip |
Rearrange the order of the checks in auth_smbpasswd.c, always check passwords
first.
Add password expiry and 'must change before first logon' support.
- This requires that the passdb be up to the job to supply the info.
(This used to be commit 53c1c5091ea4e3ccc294f8b6f132be78c11c431f)
-rw-r--r-- | source3/auth/auth_sam.c | 184 | ||||
-rw-r--r-- | source3/smbd/auth_smbpasswd.c | 184 |
2 files changed, 222 insertions, 146 deletions
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index cb8d711770..7a21c3111b 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -31,7 +31,7 @@ core of smb password checking routine. static BOOL smb_pwd_check_ntlmv1(const uchar *password, const uchar *part_passwd, const uchar *c8, - uchar user_sess_key[16]) + char user_sess_key[16]) { /* Finish the encryption of part_passwd. */ uchar p24[24]; @@ -45,7 +45,7 @@ static BOOL smb_pwd_check_ntlmv1(const uchar *password, SMBOWFencrypt(part_passwd, c8, p24); if (user_sess_key != NULL) { - SMBsesskeygen_ntv1(part_passwd, NULL, (char *)user_sess_key); + SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key); } @@ -70,7 +70,7 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len, uchar *part_passwd, uchar const *c8, const char *user, const char *domain, - char *user_sess_key) + char user_sess_key[16]) { /* Finish the encryption of part_passwd. */ uchar kr[16]; @@ -109,17 +109,104 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len, Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ -NTSTATUS smb_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info) +NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, char user_sess_key[16]) { uint8 *nt_pw, *lm_pw; uint16 acct_ctrl = pdb_get_acct_ctrl(sampass); + + if (!user_info || !sampass) + return NT_STATUS_LOGON_FAILURE; + + if (acct_ctrl & ACB_PWNOTREQ) + { + if (lp_null_passwords()) + { + DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", sampass->username)); + return(NT_STATUS_OK); + } + else + { + DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", sampass->username)); + return(NT_STATUS_LOGON_FAILURE); + } + } else { + nt_pw = pdb_get_nt_passwd(sampass); + lm_pw = pdb_get_lanman_passwd(sampass); + + if (nt_pw != NULL && user_info->nt_resp.len > 0) { + if ((user_info->nt_resp.len > 24 )) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n")); + if (smb_pwd_check_ntlmv2( user_info->nt_resp.buffer, + user_info->nt_resp.len, + nt_pw, + user_info->chal, user_info->smb_username.str, + user_info->requested_domain.str, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(4,("smb_password_ok: NTLMv2 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (lp_ntlm_auth() && (user_info->nt_resp.len == 24)) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); + if (smb_pwd_check_ntlmv1(user_info->nt_resp.buffer, + nt_pw, user_info->chal, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + return NT_STATUS_LOGON_FAILURE; + } + } else if (lm_pw != NULL && user_info->lm_resp.len == 24) { + if (lp_lanman_auth()) { + DEBUG(4,("smb_password_ok: Checking LM password\n")); + if (smb_pwd_check_ntlmv1(user_info->lm_resp.buffer, + lm_pw, user_info->chal, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(4,("smb_password_ok: LM password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } + } + } + /* Should not be reached */ + return NT_STATUS_LOGON_FAILURE; +} + +/**************************************************************************** + Do a specific test for a SAM_ACCOUNT being vaild for this connection + (ie not disabled, expired and the like). +****************************************************************************/ +NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info) +{ + uint16 acct_ctrl = pdb_get_acct_ctrl(sampass); char *workstation_list; time_t kickoff_time; + if (!user_info || !sampass) + return NT_STATUS_LOGON_FAILURE; + + DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",sampass->username)); + /* Quit if the account was disabled. */ if(acct_ctrl & ACB_DISABLED) { DEBUG(1,("Account for user '%s' was disabled.\n", sampass->username)); - return(NT_STATUS_ACCOUNT_DISABLED); + return NT_STATUS_ACCOUNT_DISABLED; } /* Test account expire time */ @@ -127,6 +214,8 @@ NTSTATUS smb_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use kickoff_time = pdb_get_kickoff_time(sampass); if (kickoff_time != (time_t)-1) { if (time(NULL) > kickoff_time) { + DEBUG(1,("Account for user '%s' has expried.\n", sampass->username)); + DEBUG(3,("Account expired at '%d' unix time.\n", kickoff_time)); return NT_STATUS_ACCOUNT_EXPIRED; } } @@ -161,77 +250,21 @@ NTSTATUS smb_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use return NT_STATUS_NO_MEMORY; } - if (acct_ctrl & ACB_PWNOTREQ) { - if (lp_null_passwords()) - { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", sampass->username)); - return(NT_STATUS_OK); - } - else - { - DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", sampass->username)); - return(NT_STATUS_LOGON_FAILURE); - } - } - - if (!user_info || !sampass) - return(NT_STATUS_LOGON_FAILURE); - - DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",sampass->username)); - - nt_pw = pdb_get_nt_passwd(sampass); - - if (nt_pw != NULL) { - if ((user_info->nt_resp.len > 24 )) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n")); - if (smb_pwd_check_ntlmv2( user_info->nt_resp.buffer, - user_info->nt_resp.len, - nt_pw, - user_info->chal, user_info->smb_username.str, - user_info->requested_domain.str, - (char *)server_info->session_key)) - { - return NT_STATUS_OK; - } - DEBUG(4,("smb_password_ok: NTLMv2 password check failed\n")); - - } else if (lp_ntlm_auth() && (user_info->nt_resp.len == 24 )) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(user_info->nt_resp.buffer, - nt_pw, user_info->chal, - server_info->session_key)) { - DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); - return NT_STATUS_OK; - } else { - DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } + time_t must_change_time = pdb_get_pass_must_change_time(sampass); + if (must_change_time == 0) { + DEBUG(1,("Account for user '%s' must change password at next logon! (ie now).\n", sampass->username)); + return NT_STATUS_PASSWORD_MUST_CHANGE; } - } - - lm_pw = pdb_get_lanman_passwd(sampass); - - if(lp_lanman_auth() && (lm_pw != NULL) && (user_info->lm_resp.len == 24 )) { - DEBUG(4,("smb_password_ok: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(user_info->lm_resp.buffer, - lm_pw, user_info->chal, - server_info->session_key)) { - DEBUG(4,("smb_password_ok: LM password check succeeded\n")); - return NT_STATUS_OK; - } else { - DEBUG(4,("smb_password_ok: LM password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; + + if (must_change_time != (time_t)-1 && must_change_time < time(NULL)) { + DEBUG(1,("Account for user '%s' password expired!.\n", sampass->username)); + DEBUG(1,("Password expired at '%d' unix time.\n", must_change_time)); + return NT_STATUS_PASSWORD_EXPIRED; } } - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_OK; } @@ -262,10 +295,15 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_ return NT_STATUS_NO_SUCH_USER; } - nt_status = smb_password_ok(sampass, user_info, server_info); - + nt_status = sam_password_ok(sampass, user_info, server_info->session_key); + + if NT_STATUS_IS_OK(nt_status) { + nt_status = sam_account_ok(sampass, user_info); + } + pdb_free_sam(sampass); return nt_status; } + diff --git a/source3/smbd/auth_smbpasswd.c b/source3/smbd/auth_smbpasswd.c index cb8d711770..7a21c3111b 100644 --- a/source3/smbd/auth_smbpasswd.c +++ b/source3/smbd/auth_smbpasswd.c @@ -31,7 +31,7 @@ core of smb password checking routine. static BOOL smb_pwd_check_ntlmv1(const uchar *password, const uchar *part_passwd, const uchar *c8, - uchar user_sess_key[16]) + char user_sess_key[16]) { /* Finish the encryption of part_passwd. */ uchar p24[24]; @@ -45,7 +45,7 @@ static BOOL smb_pwd_check_ntlmv1(const uchar *password, SMBOWFencrypt(part_passwd, c8, p24); if (user_sess_key != NULL) { - SMBsesskeygen_ntv1(part_passwd, NULL, (char *)user_sess_key); + SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key); } @@ -70,7 +70,7 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len, uchar *part_passwd, uchar const *c8, const char *user, const char *domain, - char *user_sess_key) + char user_sess_key[16]) { /* Finish the encryption of part_passwd. */ uchar kr[16]; @@ -109,17 +109,104 @@ static BOOL smb_pwd_check_ntlmv2(const uchar *password, size_t pwd_len, Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ -NTSTATUS smb_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info) +NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, char user_sess_key[16]) { uint8 *nt_pw, *lm_pw; uint16 acct_ctrl = pdb_get_acct_ctrl(sampass); + + if (!user_info || !sampass) + return NT_STATUS_LOGON_FAILURE; + + if (acct_ctrl & ACB_PWNOTREQ) + { + if (lp_null_passwords()) + { + DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", sampass->username)); + return(NT_STATUS_OK); + } + else + { + DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", sampass->username)); + return(NT_STATUS_LOGON_FAILURE); + } + } else { + nt_pw = pdb_get_nt_passwd(sampass); + lm_pw = pdb_get_lanman_passwd(sampass); + + if (nt_pw != NULL && user_info->nt_resp.len > 0) { + if ((user_info->nt_resp.len > 24 )) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n")); + if (smb_pwd_check_ntlmv2( user_info->nt_resp.buffer, + user_info->nt_resp.len, + nt_pw, + user_info->chal, user_info->smb_username.str, + user_info->requested_domain.str, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(4,("smb_password_ok: NTLMv2 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (lp_ntlm_auth() && (user_info->nt_resp.len == 24)) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); + if (smb_pwd_check_ntlmv1(user_info->nt_resp.buffer, + nt_pw, user_info->chal, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + return NT_STATUS_LOGON_FAILURE; + } + } else if (lm_pw != NULL && user_info->lm_resp.len == 24) { + if (lp_lanman_auth()) { + DEBUG(4,("smb_password_ok: Checking LM password\n")); + if (smb_pwd_check_ntlmv1(user_info->lm_resp.buffer, + lm_pw, user_info->chal, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(4,("smb_password_ok: LM password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } + } + } + /* Should not be reached */ + return NT_STATUS_LOGON_FAILURE; +} + +/**************************************************************************** + Do a specific test for a SAM_ACCOUNT being vaild for this connection + (ie not disabled, expired and the like). +****************************************************************************/ +NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info) +{ + uint16 acct_ctrl = pdb_get_acct_ctrl(sampass); char *workstation_list; time_t kickoff_time; + if (!user_info || !sampass) + return NT_STATUS_LOGON_FAILURE; + + DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",sampass->username)); + /* Quit if the account was disabled. */ if(acct_ctrl & ACB_DISABLED) { DEBUG(1,("Account for user '%s' was disabled.\n", sampass->username)); - return(NT_STATUS_ACCOUNT_DISABLED); + return NT_STATUS_ACCOUNT_DISABLED; } /* Test account expire time */ @@ -127,6 +214,8 @@ NTSTATUS smb_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use kickoff_time = pdb_get_kickoff_time(sampass); if (kickoff_time != (time_t)-1) { if (time(NULL) > kickoff_time) { + DEBUG(1,("Account for user '%s' has expried.\n", sampass->username)); + DEBUG(3,("Account expired at '%d' unix time.\n", kickoff_time)); return NT_STATUS_ACCOUNT_EXPIRED; } } @@ -161,77 +250,21 @@ NTSTATUS smb_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use return NT_STATUS_NO_MEMORY; } - if (acct_ctrl & ACB_PWNOTREQ) { - if (lp_null_passwords()) - { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", sampass->username)); - return(NT_STATUS_OK); - } - else - { - DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", sampass->username)); - return(NT_STATUS_LOGON_FAILURE); - } - } - - if (!user_info || !sampass) - return(NT_STATUS_LOGON_FAILURE); - - DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",sampass->username)); - - nt_pw = pdb_get_nt_passwd(sampass); - - if (nt_pw != NULL) { - if ((user_info->nt_resp.len > 24 )) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n")); - if (smb_pwd_check_ntlmv2( user_info->nt_resp.buffer, - user_info->nt_resp.len, - nt_pw, - user_info->chal, user_info->smb_username.str, - user_info->requested_domain.str, - (char *)server_info->session_key)) - { - return NT_STATUS_OK; - } - DEBUG(4,("smb_password_ok: NTLMv2 password check failed\n")); - - } else if (lp_ntlm_auth() && (user_info->nt_resp.len == 24 )) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(user_info->nt_resp.buffer, - nt_pw, user_info->chal, - server_info->session_key)) { - DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); - return NT_STATUS_OK; - } else { - DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } + time_t must_change_time = pdb_get_pass_must_change_time(sampass); + if (must_change_time == 0) { + DEBUG(1,("Account for user '%s' must change password at next logon! (ie now).\n", sampass->username)); + return NT_STATUS_PASSWORD_MUST_CHANGE; } - } - - lm_pw = pdb_get_lanman_passwd(sampass); - - if(lp_lanman_auth() && (lm_pw != NULL) && (user_info->lm_resp.len == 24 )) { - DEBUG(4,("smb_password_ok: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(user_info->lm_resp.buffer, - lm_pw, user_info->chal, - server_info->session_key)) { - DEBUG(4,("smb_password_ok: LM password check succeeded\n")); - return NT_STATUS_OK; - } else { - DEBUG(4,("smb_password_ok: LM password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; + + if (must_change_time != (time_t)-1 && must_change_time < time(NULL)) { + DEBUG(1,("Account for user '%s' password expired!.\n", sampass->username)); + DEBUG(1,("Password expired at '%d' unix time.\n", must_change_time)); + return NT_STATUS_PASSWORD_EXPIRED; } } - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_OK; } @@ -262,10 +295,15 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_ return NT_STATUS_NO_SUCH_USER; } - nt_status = smb_password_ok(sampass, user_info, server_info); - + nt_status = sam_password_ok(sampass, user_info, server_info->session_key); + + if NT_STATUS_IS_OK(nt_status) { + nt_status = sam_account_ok(sampass, user_info); + } + pdb_free_sam(sampass); return nt_status; } + |