summaryrefslogtreecommitdiffstats
path: root/src/providers/krb5
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2014-11-27 20:29:03 +0100
committerJakub Hrozek <jhrozek@redhat.com>2014-12-13 22:18:35 +0100
commit2d40bf0ad9f03e345228cba4563091c91eb02f5b (patch)
tree67da4c95485a137a3c43c5c6a126deef8e3be7d6 /src/providers/krb5
parent6fac5e5f0c54a0f92872ce1450606cfcb577a920 (diff)
downloadsssd-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.c38
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;