summaryrefslogtreecommitdiffstats
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 23:41:33 +0100
commitfc4862295d512e464feff60cbc5df8c50bf83644 (patch)
tree428eda11c3a67924d4ee4f8f7af3a0108a67c1ec
parent2e84796d8e23ee6e406c0625288655e056b0d90d (diff)
downloadsssd-fc4862295d512e464feff60cbc5df8c50bf83644.tar.gz
sssd-fc4862295d512e464feff60cbc5df8c50bf83644.tar.xz
sssd-fc4862295d512e464feff60cbc5df8c50bf83644.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>
-rw-r--r--src/db/sysdb.h2
-rw-r--r--src/providers/ad/ad_opts.h1
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/krb5/krb5_auth.c38
-rw-r--r--src/providers/ldap/ldap_opts.h3
-rw-r--r--src/providers/ldap/sdap.h1
6 files changed, 43 insertions, 3 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 5bd7f90ac..4fbbb1671 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -127,6 +127,8 @@
#define SYSDB_SSH_PUBKEY "sshPublicKey"
+#define SYSDB_AUTH_TYPE "authType"
+
#define SYSDB_SUBDOMAIN_REALM "realmName"
#define SYSDB_SUBDOMAIN_FLAT "flatName"
#define SYSDB_SUBDOMAIN_ID "domainID"
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index c3de3d94b..d9405e502 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -212,6 +212,7 @@ struct sdap_attr_map ad_2008r2_user_map[] = {
{ "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
+ { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index f77ff1d05..66af64858 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -203,6 +203,7 @@ struct sdap_attr_map ipa_user_map[] = {
{ "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL },
+ { "ldap_user_auth_type", "ipaUserAuthType", SYSDB_AUTH_TYPE, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
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;
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index f46381e9f..7c9ed3e01 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -179,6 +179,7 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
+ { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -233,6 +234,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
+ { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -287,6 +289,7 @@ struct sdap_attr_map gen_ad2008r2_user_map[] = {
{ "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
{ "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
+ { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index aa10623a5..921051b41 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -280,6 +280,7 @@ enum sdap_user_attrs {
SDAP_AT_NDS_LOGIN_EXPIRATION_TIME,
SDAP_AT_NDS_LOGIN_ALLOWED_TIME_MAP,
SDAP_AT_USER_SSH_PUBLIC_KEY,
+ SDAP_AT_USER_AUTH_TYPE,
SDAP_OPTS_USER /* attrs counter */
};