summaryrefslogtreecommitdiffstats
path: root/daemons/ipa-kdb
diff options
context:
space:
mode:
Diffstat (limited to 'daemons/ipa-kdb')
-rw-r--r--daemons/ipa-kdb/ipa_kdb.c38
-rw-r--r--daemons/ipa-kdb/ipa_kdb.h13
-rw-r--r--daemons/ipa-kdb/ipa_kdb_principals.c28
3 files changed, 78 insertions, 1 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
index e5c718ea9..8464264cf 100644
--- a/daemons/ipa-kdb/ipa_kdb.c
+++ b/daemons/ipa-kdb/ipa_kdb.c
@@ -173,9 +173,42 @@ done:
return base;
}
+static const struct {
+ const char *name;
+ enum ipadb_user_auth flag;
+} userauth_table[] = {
+ { "disabled", IPADB_USER_AUTH_DISABLED },
+ { "password", IPADB_USER_AUTH_PASSWORD },
+ { "radius", IPADB_USER_AUTH_RADIUS },
+ { "otp", IPADB_USER_AUTH_OTP },
+ { }
+};
+
+void ipadb_get_user_auth(LDAP *lcontext, LDAPMessage *le,
+ enum ipadb_user_auth *userauth)
+{
+ struct berval **vals;
+ int i, j;
+
+ *userauth = IPADB_USER_AUTH_EMPTY;
+ vals = ldap_get_values_len(lcontext, le, IPA_USER_AUTH_TYPE);
+ if (!vals)
+ return;
+
+ for (i = 0; vals[i]; i++) {
+ for (j = 0; userauth_table[j].name; j++) {
+ if (strcasecmp(vals[i]->bv_val, userauth_table[j].name) == 0) {
+ *userauth |= userauth_table[j].flag;
+ break;
+ }
+ }
+ }
+}
+
int ipadb_get_global_configs(struct ipadb_context *ipactx)
{
- char *attrs[] = { "ipaConfigString", IPA_KRB_AUTHZ_DATA_ATTR, NULL };
+ char *attrs[] = { "ipaConfigString", IPA_KRB_AUTHZ_DATA_ATTR,
+ IPA_USER_AUTH_TYPE, NULL };
struct berval **vals = NULL;
LDAPMessage *res = NULL;
LDAPMessage *first;
@@ -203,6 +236,9 @@ int ipadb_get_global_configs(struct ipadb_context *ipactx)
goto done;
}
+ /* Check for permitted authentication types. */
+ ipadb_get_user_auth(ipactx->lcontext, res, &ipactx->user_auth);
+
vals = ldap_get_values_len(ipactx->lcontext, first,
"ipaConfigString");
if (!vals || !vals[0]) {
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 9daaab80d..54869d8f9 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -75,9 +75,18 @@
#define IPA_SETUP "ipa-setup-override-restrictions"
#define IPA_KRB_AUTHZ_DATA_ATTR "ipaKrbAuthzData"
+#define IPA_USER_AUTH_TYPE "ipaUserAuthType"
struct ipadb_mspac;
+enum ipadb_user_auth {
+ IPADB_USER_AUTH_EMPTY = 0,
+ IPADB_USER_AUTH_DISABLED = 1 << 0,
+ IPADB_USER_AUTH_PASSWORD = 1 << 1,
+ IPADB_USER_AUTH_RADIUS = 1 << 2,
+ IPADB_USER_AUTH_OTP = 1 << 3,
+};
+
struct ipadb_context {
char *uri;
char *base;
@@ -92,6 +101,7 @@ struct ipadb_context {
bool disable_last_success;
bool disable_lockout;
char **authz_data;
+ enum ipadb_user_auth user_auth;
};
#define IPA_E_DATA_MAGIC 0x0eda7a
@@ -259,3 +269,6 @@ void ipadb_audit_as_req(krb5_context kcontext,
krb5_timestamp authtime,
krb5_error_code error_code);
+/* AUTH METHODS */
+void ipadb_get_user_auth(LDAP *lcontext, LDAPMessage *le,
+ enum ipadb_user_auth *user_auth);
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
index 11c155e64..3566e1ece 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -64,6 +64,7 @@ static char *std_principal_attrs[] = {
"nsaccountlock",
"passwordHistory",
IPA_KRB_AUTHZ_DATA_ATTR,
+ IPA_USER_AUTH_TYPE,
"objectClass",
NULL
@@ -228,6 +229,9 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
krb5_db_entry **kentry,
uint32_t *polmask)
{
+ krb5_octet otp_string[] = {'o', 't', 'p', 0, '[', ']', 0 };
+ enum ipadb_user_auth user_ua = IPADB_USER_AUTH_EMPTY;
+ enum ipadb_user_auth *active_ua = &user_ua;
struct ipadb_context *ipactx;
LDAP *lcontext;
krb5_db_entry *entry;
@@ -262,6 +266,17 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
entry->magic = KRB5_KDB_MAGIC_NUMBER;
entry->len = KRB5_KDB_V1_BASE_LENGTH;
+ /* Get the user's user_auth settings. */
+ ipadb_get_user_auth(ipactx->lcontext, lentry, &user_ua);
+
+ /* TODO: Should we confirm the existence of ipatokenRadiusConfigLink in
+ * the case of RADIUS? Existence of a token for OTP? */
+
+ /* Determine which user_auth policy is active: user or global. */
+ if ((ipactx->user_auth & IPADB_USER_AUTH_DISABLED)
+ || user_ua == IPADB_USER_AUTH_EMPTY)
+ active_ua = &ipactx->user_auth;
+
/* ignore mask for now */
ret = ipadb_ldap_attr_to_int(lcontext, lentry,
@@ -393,6 +408,13 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
&res_key_data, &result, &mkvno);
switch (ret) {
case 0:
+ /* Only set a principal's key if password auth should be used. */
+ if ((*active_ua & ~IPADB_USER_AUTH_DISABLED) != IPADB_USER_AUTH_EMPTY
+ && !(*active_ua & IPADB_USER_AUTH_PASSWORD)) {
+ /* This is the same behavior as ENOENT below. */
+ break;
+ }
+
entry->key_data = res_key_data;
entry->n_key_data = result;
if (mkvno) {
@@ -515,6 +537,12 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
ied->authz_data = authz_data_list;
}
+ /* If enabled, set the otp user string, enabling otp. */
+ if ((*active_ua & (IPADB_USER_AUTH_RADIUS | IPADB_USER_AUTH_OTP)) &&
+ !(*active_ua & IPADB_USER_AUTH_DISABLED)) {
+ ret = ipadb_set_tl_data(entry, KRB5_TL_STRING_ATTRS,
+ sizeof(otp_string), otp_string);
+ }
kerr = 0;