summaryrefslogtreecommitdiff
path: root/auth-pam.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2016-07-18 09:33:25 +1000
committerDarren Tucker <dtucker@zip.com.au>2016-07-18 09:33:25 +1000
commit01558b7b07af43da774d3a11a5c51fa9c310849d (patch)
tree97052332089b01018034206d1dcd683c4177f787 /auth-pam.c
parent65c6c6b567ab5ab12945a5ad8e0ab3a8c26119cc (diff)
downloadopenssh-git-01558b7b07af43da774d3a11a5c51fa9c310849d.tar.gz
Handle PAM_MAXTRIES from modules.
bz#2249: handle the case where PAM returns PAM_MAXTRIES by ceasing to offer password and keyboard-interative authentication methods. Should prevent "sshd ignoring max retries" warnings in the log. ok djm@ It probably won't trigger with keyboard-interactive in the default configuration because the retry counter is stored in module-private storage which goes away with the sshd PAM process (see bz#688). On the other hand, those cases probably won't log a warning either.
Diffstat (limited to 'auth-pam.c')
-rw-r--r--auth-pam.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/auth-pam.c b/auth-pam.c
index 465b5a70..1f13c181 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -229,6 +229,7 @@ static int sshpam_authenticated = 0;
static int sshpam_session_open = 0;
static int sshpam_cred_established = 0;
static int sshpam_account_status = -1;
+static int sshpam_maxtries_reached = 0;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL;
@@ -450,6 +451,8 @@ sshpam_thread(void *ctxtp)
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
sshpam_err = pam_authenticate(sshpam_handle, flags);
+ if (sshpam_err == PAM_MAXTRIES)
+ sshpam_set_maxtries_reached(1);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
@@ -501,6 +504,8 @@ sshpam_thread(void *ctxtp)
/* XXX - can't do much about an error here */
if (sshpam_err == PAM_ACCT_EXPIRED)
ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
+ else if (sshpam_maxtries_reached)
+ ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &buffer);
else
ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
buffer_free(&buffer);
@@ -741,7 +746,11 @@ sshpam_query(void *ctx, char **name, char **info,
free(msg);
break;
case PAM_ACCT_EXPIRED:
- sshpam_account_status = 0;
+ case PAM_MAXTRIES:
+ if (type == PAM_ACCT_EXPIRED)
+ sshpam_account_status = 0;
+ if (type == PAM_MAXTRIES)
+ sshpam_set_maxtries_reached(1);
/* FALLTHROUGH */
case PAM_AUTH_ERR:
debug3("PAM: %s", pam_strerror(sshpam_handle, type));
@@ -1218,6 +1227,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
sshpam_err = pam_authenticate(sshpam_handle, flags);
sshpam_password = NULL;
free(fake);
+ if (sshpam_err == PAM_MAXTRIES)
+ sshpam_set_maxtries_reached(1);
if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
debug("PAM: password authentication accepted for %.100s",
authctxt->user);
@@ -1229,4 +1240,21 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
return 0;
}
}
+
+int
+sshpam_get_maxtries_reached(void)
+{
+ return sshpam_maxtries_reached;
+}
+
+void
+sshpam_set_maxtries_reached(int reached)
+{
+ if (reached == 0 || sshpam_maxtries_reached)
+ return;
+ sshpam_maxtries_reached = 1;
+ options.password_authentication = 0;
+ options.kbd_interactive_authentication = 0;
+ options.challenge_response_authentication = 0;
+}
#endif /* USE_PAM */