memset(&no_server, 0, sizeof(no_server));
+ /* Ignore password expiration and needchange attributes (as Windows
+ * does), since S4U2Self is not password authentication. */
+ princ->pw_expiration = 0;
+ clear(princ->attributes, KRB5_KDB_REQUIRES_PWCHANGE);
+
code = validate_as_request(kdc_active_realm, request, *princ,
no_server, kdc_time, status, &e_data);
if (code) {
code = k5_get_init_creds(context, &creds, &client, NULL, NULL, 0, NULL,
opts, krb5_get_as_key_noop, &userid, &use_master,
NULL);
- if (code == 0 || code == KRB5_PREAUTH_FAILED) {
+ if (!code || code == KRB5_PREAUTH_FAILED || code == KRB5KDC_ERR_KEY_EXP) {
*canon_user = userid.user;
userid.user = NULL;
code = 0;
# Get forwardable creds for service1 in the default cache.
realm.kinit(service1, None, ['-f', '-k'])
+# Try S4U2Self for user with a restricted password.
+realm.run([kadminl, 'modprinc', '+needchange', realm.user_princ])
+realm.run(['./t_s4u', 'e:user', '-'])
+realm.run([kadminl, 'modprinc', '-needchange',
+ '-pwexpire', '1/1/2000', realm.user_princ])
+realm.run(['./t_s4u', 'e:user', '-'])
+realm.run([kadminl, 'modprinc', '-pwexpire', 'never', realm.user_princ])
+
# Try krb5 -> S4U2Proxy with forwardable user creds. This should fail
# at the S4U2Proxy step since the DB2 back end currently has no
# support for allowing it.