summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2001-09-26 12:28:46 +0000
committerAndrew Bartlett <abartlet@samba.org>2001-09-26 12:28:46 +0000
commit71850be47edf5e1c3d36eec45c006a9f94c7f6ce (patch)
tree3464ecd6e5b37ff7bff9d885b6099fe09999617d
parent83db39d2b5624217422b4c10509d589018f7a329 (diff)
downloadsamba-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.c184
-rw-r--r--source3/smbd/auth_smbpasswd.c184
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;
}
+