Blame SOURCES/0133-Skip-CHAUTHTOK_PRELIM-when-using-OTPs.patch

905b4d
From fc4862295d512e464feff60cbc5df8c50bf83644 Mon Sep 17 00:00:00 2001
905b4d
From: Jakub Hrozek <jhrozek@redhat.com>
905b4d
Date: Thu, 27 Nov 2014 20:29:03 +0100
905b4d
Subject: [PATCH 133/138] Skip CHAUTHTOK_PRELIM when using OTPs
905b4d
905b4d
https://fedorahosted.org/sssd/ticket/2484
905b4d
905b4d
When OTPs are used, we can only used each authtoken at most once. When
905b4d
it comes to Kerberos password changes, this was only working previously
905b4d
by accident, because the old authtoken was first used to verify the old
905b4d
password is valid and not expired and then also to acquire a chpass
905b4d
principal.
905b4d
905b4d
This patch looks at the user object in LDAP to check if the user has any
905b4d
OTPs enabled. If he does, the CHAUTHTOK_PRELIM step is skipped
905b4d
completely so that the OTP can be used to acquire the chpass ticket
905b4d
later.
905b4d
905b4d
Reviewed-by: Sumit Bose <sbose@redhat.com>
905b4d
---
905b4d
 src/db/sysdb.h                 |  2 ++
905b4d
 src/providers/ad/ad_opts.h     |  1 +
905b4d
 src/providers/ipa/ipa_opts.h   |  1 +
905b4d
 src/providers/krb5/krb5_auth.c | 38 +++++++++++++++++++++++++++++++++++---
905b4d
 src/providers/ldap/ldap_opts.h |  3 +++
905b4d
 src/providers/ldap/sdap.h      |  1 +
905b4d
 6 files changed, 43 insertions(+), 3 deletions(-)
905b4d
905b4d
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
905b4d
index 5bd7f90acb685bbaff5c98f433c7dce8175c33ca..4fbbb16718a2fc3d444e4c6dba5fca4c1bb3096a 100644
905b4d
--- a/src/db/sysdb.h
905b4d
+++ b/src/db/sysdb.h
905b4d
@@ -127,6 +127,8 @@
905b4d
 
905b4d
 #define SYSDB_SSH_PUBKEY "sshPublicKey"
905b4d
 
905b4d
+#define SYSDB_AUTH_TYPE "authType"
905b4d
+
905b4d
 #define SYSDB_SUBDOMAIN_REALM "realmName"
905b4d
 #define SYSDB_SUBDOMAIN_FLAT "flatName"
905b4d
 #define SYSDB_SUBDOMAIN_ID "domainID"
905b4d
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
905b4d
index c3de3d94b1818665a86bba8a2432c699717b6a34..d9405e5020ca724a0f7caa752ac10fb07d8aa397 100644
905b4d
--- a/src/providers/ad/ad_opts.h
905b4d
+++ b/src/providers/ad/ad_opts.h
905b4d
@@ -212,6 +212,7 @@ struct sdap_attr_map ad_2008r2_user_map[] = {
905b4d
     { "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
905b4d
     { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
905b4d
     { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
905b4d
+    { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
905b4d
     SDAP_ATTR_MAP_TERMINATOR
905b4d
 };
905b4d
 
905b4d
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
905b4d
index f77ff1d05b9540155db44d04d4fb3aac9d7b5988..66af648583e552d7edd932f6bb5a2c3bef107e51 100644
905b4d
--- a/src/providers/ipa/ipa_opts.h
905b4d
+++ b/src/providers/ipa/ipa_opts.h
905b4d
@@ -203,6 +203,7 @@ struct sdap_attr_map ipa_user_map[] = {
905b4d
     { "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
905b4d
     { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
905b4d
     { "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL },
905b4d
+    { "ldap_user_auth_type", "ipaUserAuthType", SYSDB_AUTH_TYPE, NULL },
905b4d
     SDAP_ATTR_MAP_TERMINATOR
905b4d
 };
905b4d
 
905b4d
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
905b4d
index e43b3652786678b79499e30ed546712ef080fe2c..25caf7b788a3f373f47e9d8aad38a2ea6fc12621 100644
905b4d
--- a/src/providers/krb5/krb5_auth.c
905b4d
+++ b/src/providers/krb5/krb5_auth.c
905b4d
@@ -311,6 +311,25 @@ static void krb5_auth_store_creds(struct sss_domain_info *domain,
905b4d
     }
905b4d
 }
905b4d
 
905b4d
+static bool is_otp_enabled(struct ldb_message *user_msg)
905b4d
+{
905b4d
+    struct ldb_message_element *el;
905b4d
+    size_t i;
905b4d
+
905b4d
+    el = ldb_msg_find_element(user_msg, SYSDB_AUTH_TYPE);
905b4d
+    if (el == NULL) {
905b4d
+        return false;
905b4d
+    }
905b4d
+
905b4d
+    for (i = 0; i < el->num_values; i++) {
905b4d
+        if (strcmp((const char * )el->values[i].data, "otp") == 0) {
905b4d
+            return true;
905b4d
+        }
905b4d
+    }
905b4d
+
905b4d
+    return false;
905b4d
+}
905b4d
+
905b4d
 /* krb5_auth request */
905b4d
 
905b4d
 struct krb5_auth_state {
905b4d
@@ -344,8 +363,9 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
905b4d
     const char *realm;
905b4d
     struct tevent_req *req;
905b4d
     struct tevent_req *subreq;
905b4d
-    int authtok_type;
905b4d
+    enum sss_authtok_type authtok_type;
905b4d
     int ret;
905b4d
+    bool otp;
905b4d
 
905b4d
     req = tevent_req_create(mem_ctx, &state, struct krb5_auth_state);
905b4d
     if (req == NULL) {
905b4d
@@ -441,7 +461,7 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
905b4d
         goto done;
905b4d
     }
905b4d
 
905b4d
-    attrs = talloc_array(state, const char *, 7);
905b4d
+    attrs = talloc_array(state, const char *, 8);
905b4d
     if (attrs == NULL) {
905b4d
         ret = ENOMEM;
905b4d
         goto done;
905b4d
@@ -453,7 +473,8 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
905b4d
     attrs[3] = SYSDB_UIDNUM;
905b4d
     attrs[4] = SYSDB_GIDNUM;
905b4d
     attrs[5] = SYSDB_CANONICAL_UPN;
905b4d
-    attrs[6] = NULL;
905b4d
+    attrs[6] = SYSDB_AUTH_TYPE;
905b4d
+    attrs[7] = NULL;
905b4d
 
905b4d
     ret = krb5_setup(state, pd, krb5_ctx, &state->kr);
905b4d
     if (ret != EOK) {
905b4d
@@ -547,6 +568,17 @@ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx,
905b4d
         break;
905b4d
     }
905b4d
 
905b4d
+    otp = is_otp_enabled(res->msgs[0]);
905b4d
+    if (pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM && otp == true) {
905b4d
+        /* To avoid consuming the OTP */
905b4d
+        DEBUG(SSSDBG_TRACE_FUNC,
905b4d
+              "Skipping password checks for OTP-enabled user\n");
905b4d
+        state->pam_status = PAM_SUCCESS;
905b4d
+        state->dp_err = DP_ERR_OK;
905b4d
+        ret = EOK;
905b4d
+        goto done;
905b4d
+    }
905b4d
+
905b4d
     kr->srv = NULL;
905b4d
     kr->kpasswd_srv = NULL;
905b4d
 
905b4d
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
905b4d
index f46381e9fac7b93730ce0767154989f2e3b7ebbf..7c9ed3e01f726f2ba6ecb2a7268867abd3baa37d 100644
905b4d
--- a/src/providers/ldap/ldap_opts.h
905b4d
+++ b/src/providers/ldap/ldap_opts.h
905b4d
@@ -179,6 +179,7 @@ struct sdap_attr_map rfc2307_user_map[] = {
905b4d
     { "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
905b4d
     { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
905b4d
     { "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
905b4d
+    { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
905b4d
     SDAP_ATTR_MAP_TERMINATOR
905b4d
 };
905b4d
 
905b4d
@@ -233,6 +234,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
905b4d
     { "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
905b4d
     { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
905b4d
     { "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
905b4d
+    { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
905b4d
     SDAP_ATTR_MAP_TERMINATOR
905b4d
 };
905b4d
 
905b4d
@@ -287,6 +289,7 @@ struct sdap_attr_map gen_ad2008r2_user_map[] = {
905b4d
     { "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
905b4d
     { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
905b4d
     { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
905b4d
+    { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
905b4d
     SDAP_ATTR_MAP_TERMINATOR
905b4d
 };
905b4d
 
905b4d
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
905b4d
index aa10623a58d7d667205b09e744dc2b924ca821ed..921051b41a911a2d1117672a8e9c2697b679f24e 100644
905b4d
--- a/src/providers/ldap/sdap.h
905b4d
+++ b/src/providers/ldap/sdap.h
905b4d
@@ -280,6 +280,7 @@ enum sdap_user_attrs {
905b4d
     SDAP_AT_NDS_LOGIN_EXPIRATION_TIME,
905b4d
     SDAP_AT_NDS_LOGIN_ALLOWED_TIME_MAP,
905b4d
     SDAP_AT_USER_SSH_PUBLIC_KEY,
905b4d
+    SDAP_AT_USER_AUTH_TYPE,
905b4d
 
905b4d
     SDAP_OPTS_USER /* attrs counter */
905b4d
 };
905b4d
-- 
905b4d
1.9.3
905b4d