summaryrefslogtreecommitdiff
path: root/server/providers/krb5/krb5_child.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/providers/krb5/krb5_child.c')
-rw-r--r--server/providers/krb5/krb5_child.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/server/providers/krb5/krb5_child.c b/server/providers/krb5/krb5_child.c
index 6f698400..7649406f 100644
--- a/server/providers/krb5/krb5_child.c
+++ b/server/providers/krb5/krb5_child.c
@@ -359,14 +359,37 @@ static errno_t tgt_req_child(int fd, struct krb5_req *kr)
}
kerr = get_and_save_tgt(kr, pass_str);
+
+ /* If the password is expired the KDC will always return
+ KRB5KDC_ERR_KEY_EXP regardless if the supplied password is correct or
+ not. In general the password can still be used to get a changepw ticket.
+ So we validate the password by trying to get a changepw ticket. */
+ if (kerr == KRB5KDC_ERR_KEY_EXP) {
+ kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ,
+ pass_str, NULL, NULL, 0,
+ kr->krb5_ctx->changepw_principle,
+ kr->options);
+ krb5_free_cred_contents(kr->ctx, kr->creds);
+ if (kerr == 0) {
+ kerr = KRB5KDC_ERR_KEY_EXP;
+ }
+ }
+
memset(pass_str, 0, kr->pd->authtok_size);
talloc_zfree(pass_str);
memset(kr->pd->authtok, 0, kr->pd->authtok_size);
if (kerr != 0) {
KRB5_DEBUG(1, kerr);
- if (kerr == KRB5_KDC_UNREACH) {
- pam_status = PAM_AUTHINFO_UNAVAIL;
+ switch (kerr) {
+ case KRB5_KDC_UNREACH:
+ pam_status = PAM_AUTHINFO_UNAVAIL;
+ break;
+ case KRB5KDC_ERR_KEY_EXP:
+ pam_status = PAM_AUTHTOK_EXPIRED;
+ break;
+ default:
+ pam_status = PAM_SYSTEM_ERR;
}
}