diff options
author | Darren Tucker <dtucker@zip.com.au> | 2016-07-18 09:33:25 +1000 |
---|---|---|
committer | Darren Tucker <dtucker@zip.com.au> | 2016-07-18 09:33:25 +1000 |
commit | 01558b7b07af43da774d3a11a5c51fa9c310849d (patch) | |
tree | 97052332089b01018034206d1dcd683c4177f787 /auth-pam.c | |
parent | 65c6c6b567ab5ab12945a5ad8e0ab3a8c26119cc (diff) |
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.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/auth-pam.c b/auth-pam.c index 465b5a702..1f13c181c 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -229,6 +229,7 @@ static int sshpam_authenticated = 0; | |||
229 | static int sshpam_session_open = 0; | 229 | static int sshpam_session_open = 0; |
230 | static int sshpam_cred_established = 0; | 230 | static int sshpam_cred_established = 0; |
231 | static int sshpam_account_status = -1; | 231 | static int sshpam_account_status = -1; |
232 | static int sshpam_maxtries_reached = 0; | ||
232 | static char **sshpam_env = NULL; | 233 | static char **sshpam_env = NULL; |
233 | static Authctxt *sshpam_authctxt = NULL; | 234 | static Authctxt *sshpam_authctxt = NULL; |
234 | static const char *sshpam_password = NULL; | 235 | static const char *sshpam_password = NULL; |
@@ -450,6 +451,8 @@ sshpam_thread(void *ctxtp) | |||
450 | if (sshpam_err != PAM_SUCCESS) | 451 | if (sshpam_err != PAM_SUCCESS) |
451 | goto auth_fail; | 452 | goto auth_fail; |
452 | sshpam_err = pam_authenticate(sshpam_handle, flags); | 453 | sshpam_err = pam_authenticate(sshpam_handle, flags); |
454 | if (sshpam_err == PAM_MAXTRIES) | ||
455 | sshpam_set_maxtries_reached(1); | ||
453 | if (sshpam_err != PAM_SUCCESS) | 456 | if (sshpam_err != PAM_SUCCESS) |
454 | goto auth_fail; | 457 | goto auth_fail; |
455 | 458 | ||
@@ -501,6 +504,8 @@ sshpam_thread(void *ctxtp) | |||
501 | /* XXX - can't do much about an error here */ | 504 | /* XXX - can't do much about an error here */ |
502 | if (sshpam_err == PAM_ACCT_EXPIRED) | 505 | if (sshpam_err == PAM_ACCT_EXPIRED) |
503 | ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); | 506 | ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer); |
507 | else if (sshpam_maxtries_reached) | ||
508 | ssh_msg_send(ctxt->pam_csock, PAM_MAXTRIES, &buffer); | ||
504 | else | 509 | else |
505 | ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); | 510 | ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer); |
506 | buffer_free(&buffer); | 511 | buffer_free(&buffer); |
@@ -741,7 +746,11 @@ sshpam_query(void *ctx, char **name, char **info, | |||
741 | free(msg); | 746 | free(msg); |
742 | break; | 747 | break; |
743 | case PAM_ACCT_EXPIRED: | 748 | case PAM_ACCT_EXPIRED: |
744 | sshpam_account_status = 0; | 749 | case PAM_MAXTRIES: |
750 | if (type == PAM_ACCT_EXPIRED) | ||
751 | sshpam_account_status = 0; | ||
752 | if (type == PAM_MAXTRIES) | ||
753 | sshpam_set_maxtries_reached(1); | ||
745 | /* FALLTHROUGH */ | 754 | /* FALLTHROUGH */ |
746 | case PAM_AUTH_ERR: | 755 | case PAM_AUTH_ERR: |
747 | debug3("PAM: %s", pam_strerror(sshpam_handle, type)); | 756 | debug3("PAM: %s", pam_strerror(sshpam_handle, type)); |
@@ -1218,6 +1227,8 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) | |||
1218 | sshpam_err = pam_authenticate(sshpam_handle, flags); | 1227 | sshpam_err = pam_authenticate(sshpam_handle, flags); |
1219 | sshpam_password = NULL; | 1228 | sshpam_password = NULL; |
1220 | free(fake); | 1229 | free(fake); |
1230 | if (sshpam_err == PAM_MAXTRIES) | ||
1231 | sshpam_set_maxtries_reached(1); | ||
1221 | if (sshpam_err == PAM_SUCCESS && authctxt->valid) { | 1232 | if (sshpam_err == PAM_SUCCESS && authctxt->valid) { |
1222 | debug("PAM: password authentication accepted for %.100s", | 1233 | debug("PAM: password authentication accepted for %.100s", |
1223 | authctxt->user); | 1234 | authctxt->user); |
@@ -1229,4 +1240,21 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password) | |||
1229 | return 0; | 1240 | return 0; |
1230 | } | 1241 | } |
1231 | } | 1242 | } |
1243 | |||
1244 | int | ||
1245 | sshpam_get_maxtries_reached(void) | ||
1246 | { | ||
1247 | return sshpam_maxtries_reached; | ||
1248 | } | ||
1249 | |||
1250 | void | ||
1251 | sshpam_set_maxtries_reached(int reached) | ||
1252 | { | ||
1253 | if (reached == 0 || sshpam_maxtries_reached) | ||
1254 | return; | ||
1255 | sshpam_maxtries_reached = 1; | ||
1256 | options.password_authentication = 0; | ||
1257 | options.kbd_interactive_authentication = 0; | ||
1258 | options.challenge_response_authentication = 0; | ||
1259 | } | ||
1232 | #endif /* USE_PAM */ | 1260 | #endif /* USE_PAM */ |