From a84b57274796027776828ad952628491846aa86c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Fri, 22 Aug 2014 20:19:36 -0700 Subject: [PATCH] resurrect password change support again --- kuser/kinit.c | 3 +++ lib/krb5/init_creds_pw.c | 32 ++++++++++++++++++++++++++++++++ tests/kdc/check-kdc.in | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/kuser/kinit.c b/kuser/kinit.c index 80dfd3430..76f271b89 100644 --- a/kuser/kinit.c +++ b/kuser/kinit.c @@ -683,6 +683,9 @@ get_new_tickets(krb5_context context, case KRB5KRB_AP_ERR_V4_REPLY: krb5_warnx(context, N_("Looks like a Kerberos 4 reply", "")); goto out; + case KRB5KDC_ERR_KEY_EXPIRED: + krb5_warnx(context, N_("Password expired", "")); + goto out; default: krb5_warn(context, ret, "krb5_get_init_creds"); goto out; diff --git a/lib/krb5/init_creds_pw.c b/lib/krb5/init_creds_pw.c index 7e123f6fc..9072adab5 100644 --- a/lib/krb5/init_creds_pw.c +++ b/lib/krb5/init_creds_pw.c @@ -64,6 +64,10 @@ typedef struct krb5_get_init_creds_ctx { krb5_pk_init_ctx pk_init_ctx; int ic_flags; + struct { + unsigned change_password:1; + } runflags; + int used_pa_types; #define USED_PKINIT 1 #define USED_PKINIT_W2K 2 @@ -2325,6 +2329,34 @@ krb5_init_creds_step(krb5_context context, *ctx->error.crealm); ctx->used_pa_types = 0; + } else if (ret == KRB5KDC_ERR_KEY_EXP && ctx->runflags.change_password == 0 && ctx->prompter) { + char buf2[1024]; + + ctx->runflags.change_password = 1; + + ctx->prompter(context, ctx->prompter_data, NULL, N_("Password has expired", ""), 0, NULL); + + + /* try to avoid recursion */ + if (ctx->in_tkt_service != NULL && strcmp(ctx->in_tkt_service, "kadmin/changepw") == 0) + goto out; + + ret = change_password(context, + ctx->cred.client, + ctx->password, + buf2, + sizeof(buf2), + ctx->prompter, + ctx->prompter_data, + NULL); + if (ret) + goto out; + + krb5_init_creds_set_password(context, ctx, buf2); + + ctx->used_pa_types = 0; + ret = 0; + } else if (ret == KRB5KDC_ERR_PREAUTH_FAILED) { if (ctx->fast_state.flags & KRB5_FAST_DISABLED) diff --git a/tests/kdc/check-kdc.in b/tests/kdc/check-kdc.in index f54e669fe..5e93c0ccc 100644 --- a/tests/kdc/check-kdc.in +++ b/tests/kdc/check-kdc.in @@ -55,10 +55,12 @@ R6=SOME-REALM6.US R7=SOME-REALM7.UK port=@port@ +pwport=@pwport@ kadmin="${kadmin} -l -r $R" kadmin5="${kadmin} -l -r $R5" kdc="${kdc} --addresses=localhost -P $port" +kpasswdd="${kpasswdd} --addresses=localhost -p $pwport" server=host/datan.test.h5l.se server2=host/computer.example.com @@ -204,6 +206,12 @@ ${kadmin} add -p cross2 --use-defaults krbtgt/${R6}@${R7} || exit 1 ${kadmin} add -p foo --use-defaults pw-expire@${R} || exit 1 ${kadmin} modify --pw-expiration-time=+1day pw-expire@${R} || exit 1 +${kadmin} add -p foo --use-defaults pw-expired@${R} || exit 1 +${kadmin} modify --pw-expiration-time=2012-06-12 pw-expired@${R} || exit 1 + +${kadmin} add -p foo --use-defaults account-expired@${R} || exit 1 +${kadmin} modify --expiration-time=2012-06-12 account-expired@${R} || exit 1 + ${kadmin} add -p foo --use-defaults foo@${RH} || exit 1 echo "Check parser" @@ -265,7 +273,12 @@ if [ "$?" != 0 ] ; then exit 1 fi -trap "kill -9 ${kdcpid}; echo signal killing kdc; exit 1;" EXIT +echo Starting kpasswdd; > messages.log +env ${HEIM_MALLOC_DEBUG} ${kpasswdd} & +kpasswddpid=$! + + +trap "kill -9 ${kdcpid} ${kpasswddpid}; echo signal killing kdc kpasswdd; exit 1;" EXIT ec=0 @@ -720,7 +733,7 @@ echo "testing removal of keytab" ${ktutil} -k ${keytab} destroy || { ec=1 ; eval "${testfailed}"; } test -f ${keytabfile} && { ec=1 ; eval "${testfailed}"; } -echo "Getting client pw expire"; > messages.log +echo "Checking client pw expire"; > messages.log ${kinit} --password-file=${objdir}/foopassword \ pw-expire@${R} 2>kinit-log.tmp|| \ { ec=1 ; eval "${testfailed}"; } @@ -733,8 +746,30 @@ ${EGREP} "^e type: 6" kinit-log.tmp > /dev/null || \ echo " test_gic passes" ${kdestroy} -echo "killing kdc (${kdcpid})" +echo "Checking password expiration" ; > messages.log + +kinitpty=${objdir}/foopassword.rkpty +cat > ${kinitpty} < messages.log +${rkpty} ${kinitpty} ${kinit} pw-expired@${R}|| \ + { ec=1 ; eval "${testfailed}"; } + +${kdestroy} + + +echo "killing kdc (${kdcpid}) kpasswdd (${kpasswddpid})" sh ${leaks_kill} kdc $kdcpid || exit 1 +sh ${leaks_kill} kpasswdd $kpasswddpid || exit 1 trap "" EXIT -- 2.11.4.GIT