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 22:18:35 +0100
commit2d40bf0ad9f03e345228cba4563091c91eb02f5b (patch)
tree67da4c95485a137a3c43c5c6a126deef8e3be7d6
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>
-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 cdcdfd51d..01900425a 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 */
};