diff options
Diffstat (limited to 'daemons/ipa-kdb')
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb.c | 38 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb.h | 13 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_principals.c | 28 |
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; |