diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2014-11-27 20:29:03 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2014-12-13 22:18:35 +0100 |
commit | 2d40bf0ad9f03e345228cba4563091c91eb02f5b (patch) | |
tree | 67da4c95485a137a3c43c5c6a126deef8e3be7d6 /src/providers/krb5 | |
parent | 6fac5e5f0c54a0f92872ce1450606cfcb577a920 (diff) | |
download | sssd-2d40bf0ad9f03e345228cba4563091c91eb02f5b.tar.gz sssd-2d40bf0ad9f03e345228cba4563091c91eb02f5b.tar.xz sssd-2d40bf0ad9f03e345228cba4563091c91eb02f5b.zip |
Skip CHAUTHTOK_PRELIM when using OTPs
https://fedorahosted.org/sssd/ticket/2484
When OTPs are used, we can only used each authtoken at most once. When
it comes to Kerberos password changes, this was only working previously
by accident, because the old authtoken was first used to verify the old
password is valid and not expired and then also to acquire a chpass
principal.
This patch looks at the user object in LDAP to check if the user has any
OTPs enabled. If he does, the CHAUTHTOK_PRELIM step is skipped
completely so that the OTP can be used to acquire the chpass ticket
later.
Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src/providers/krb5')
-rw-r--r-- | src/providers/krb5/krb5_auth.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index e43b36527..25caf7b78 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -311,6 +311,25 @@ static void krb5_auth_store_creds(struct sss_domain_info *domain, } } +static bool is_otp_enabled(struct ldb_message *user_msg) +{ + struct ldb_message_element *el; + size_t i; + + el = ldb_msg_find_element(user_msg, SYSDB_AUTH_TYPE); + if (el == NULL) { + return false; + } + + for (i = 0; i < el->num_values; i++) { + if (strcmp((const char * )el->values[i].data, "otp") == 0) { + return true; + } + } + + return false; +} + /* krb5_auth request */ struct krb5_auth_state { @@ -344,8 +363,9 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, const char *realm; struct tevent_req *req; struct tevent_req *subreq; - int authtok_type; + enum sss_authtok_type authtok_type; int ret; + bool otp; req = tevent_req_create(mem_ctx, &state, struct krb5_auth_state); if (req == NULL) { @@ -441,7 +461,7 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, goto done; } - attrs = talloc_array(state, const char *, 7); + attrs = talloc_array(state, const char *, 8); if (attrs == NULL) { ret = ENOMEM; goto done; @@ -453,7 +473,8 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, attrs[3] = SYSDB_UIDNUM; attrs[4] = SYSDB_GIDNUM; attrs[5] = SYSDB_CANONICAL_UPN; - attrs[6] = NULL; + attrs[6] = SYSDB_AUTH_TYPE; + attrs[7] = NULL; ret = krb5_setup(state, pd, krb5_ctx, &state->kr); if (ret != EOK) { @@ -547,6 +568,17 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, break; } + otp = is_otp_enabled(res->msgs[0]); + if (pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM && otp == true) { + /* To avoid consuming the OTP */ + DEBUG(SSSDBG_TRACE_FUNC, + "Skipping password checks for OTP-enabled user\n"); + state->pam_status = PAM_SUCCESS; + state->dp_err = DP_ERR_OK; + ret = EOK; + goto done; + } + kr->srv = NULL; kr->kpasswd_srv = NULL; |