diff options
| author | Matt Rogers <mrogers@redhat.com> | 2016-03-25 17:01:40 -0400 |
|---|---|---|
| committer | Martin Basti <mbasti@redhat.com> | 2016-05-02 19:15:45 +0200 |
| commit | 8a2afcafee977675fc289acab50cc808b469a2b3 (patch) | |
| tree | 80019cbabed6616da54a7a8d46e8e8169d86e4e2 /daemons/ipa-kdb | |
| parent | 829ba69e027351e056b3bbc159722e2cf5e3f1e9 (diff) | |
| download | freeipa-8a2afcafee977675fc289acab50cc808b469a2b3.tar.gz freeipa-8a2afcafee977675fc289acab50cc808b469a2b3.tar.xz freeipa-8a2afcafee977675fc289acab50cc808b469a2b3.zip | |
ipa_kdb: add krbPrincipalAuthInd handling
Store and retrieve the authentication indicator "require_auth" string in
the krbPrincipalAuthInd attribute. Skip storing auth indicators to
krbExtraData.
https://fedorahosted.org/freeipa/ticket/5782
Reviewed-By: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'daemons/ipa-kdb')
| -rw-r--r-- | daemons/ipa-kdb/ipa_kdb_principals.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index e32be856a..502781087 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -54,6 +54,7 @@ static char *std_principal_attrs[] = { "krbLastSuccessfulAuth", "krbLastFailedAuth", "krbLoginFailedCount", + "krbPrincipalAuthInd", "krbExtraData", "krbLastAdminUnlock", "krbObjectReferences", @@ -428,6 +429,85 @@ done: return kerr; } +static void strv_free(char **strv) +{ + int i; + + if (strv == NULL) { + return; + } + + for (i = 0; strv[i] != NULL; i++) { + free(strv[i]); + } + + free(strv); +} + +static krb5_error_code ipadb_get_ldap_auth_ind(krb5_context kcontext, + LDAP *lcontext, + LDAPMessage *lentry, + krb5_db_entry *entry) +{ + krb5_error_code ret = 0; + char **authinds = NULL; + char *aistr = NULL; + char *ap = NULL; + size_t len = 0; + size_t l = 0; + int count = 0; + int i = 0; + + ret = ipadb_ldap_attr_to_strlist(lcontext, lentry, "krbPrincipalAuthInd", + &authinds); + switch (ret) { + case 0: + break; + case ENOENT: + return 0; + default: + return ret; + } + + for (count = 0; authinds != NULL && authinds[count] != NULL; count++) { + len += strlen(authinds[count]) + 1; + } + + if (len == 0) { + strv_free(authinds); + return 0; + } + + aistr = malloc(len); + if (aistr == NULL) { + ret = errno; + goto cleanup; + } + + /* Create a space-separated string of authinds. */ + ap = aistr; + l = len; + for (i = 0; i < count; i++) { + ret = snprintf(ap, l, "%s ", authinds[i]); + if (ret <= 0 || ret > l) { + ret = ENOMEM; + goto cleanup; + } + ap += ret; + l -= ret; + } + aistr[len - 1] = '\0'; + + ret = krb5_dbe_set_string(kcontext, entry, "require_auth", + aistr); + +cleanup: + strv_free(authinds); + free(aistr); + + return ret; +} + static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, char *principal, LDAPMessage *lentry, @@ -611,6 +691,10 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, goto done; } + ret = ipadb_get_ldap_auth_ind(kcontext, lcontext, lentry, entry); + if (ret) + goto done; + ret = ipadb_ldap_attr_to_key_data(lcontext, lentry, "krbPrincipalKey", &res_key_data, &result, &mkvno); @@ -1668,6 +1752,62 @@ done: return kerr; } +static krb5_error_code ipadb_get_ldap_mod_auth_ind(krb5_context kcontext, + struct ipadb_mods *imods, + krb5_db_entry *entry, + int mod_op) +{ + krb5_error_code ret = 0; + char **strlist = NULL; + char *ais = NULL; + char *ai = NULL; + char *s = NULL; + size_t ai_size = 0; + int cnt = 0; + int i = 0; + + ret = krb5_dbe_get_string(kcontext, entry, "require_auth", &ais); + if (ret) { + return ret; + } + if (ais == NULL) { + return 0; + } + + ai_size = strlen(ais) + 1; + + for (i = 0; i < ai_size; i++) { + if (ais[i] != ' ') { + continue; + } + if (i > 0 && ais[i - 1] != ' ') { + cnt++; + } + } + + strlist = calloc(cnt + 2, sizeof(*strlist)); + if (strlist == NULL) { + free(ais); + return errno; + } + + cnt = 0; + ai = strtok_r(ais, " ", &s); + while (ai != NULL) { + if (ai[0] != '\0') { + strlist[cnt++] = ai; + } + ai = strtok_r(NULL, " ", &s); + } + + ret = ipadb_get_ldap_mod_str_list(imods, "krbPrincipalAuthInd", + strlist, cnt, mod_op); + + free(ais); + free(strlist); + return ret; +} + static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, struct ipadb_mods *imods, krb5_db_entry *entry, @@ -1676,6 +1816,7 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, krb5_error_code kerr; krb5_int32 time32le; int mkvno; + char *req_auth_str = NULL; /* check each mask flag in order */ @@ -1854,6 +1995,10 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, } } + kerr = ipadb_get_ldap_mod_auth_ind(kcontext, imods, entry, mod_op); + if (kerr) + goto done; + /* KADM5_TL_DATA */ if (entry->mask & KMASK_TL_DATA) { kerr = ipadb_get_tl_data(entry, @@ -1873,12 +2018,36 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, } } + kerr = krb5_dbe_get_string(kcontext, entry, "require_auth", + &req_auth_str); + if (kerr) { + goto done; + } + + /* Do not store auth indicators from the string attribute in + * krbExtraData. Remove require_auth value from the entry temporarily. */ + if (req_auth_str != NULL) { + kerr = krb5_dbe_set_string(kcontext, entry, "require_auth", NULL); + if (kerr) { + goto done; + } + } + kerr = ipadb_get_ldap_mod_extra_data(imods, entry->tl_data, mod_op); if (kerr && kerr != ENOENT) { goto done; } + + /* Restore require_auth value */ + if (req_auth_str != NULL) { + kerr = krb5_dbe_set_string(kcontext, entry, "require_auth", + req_auth_str); + if (kerr) { + goto done; + } + } } /* KADM5_LOAD */ @@ -1956,6 +2125,7 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, kerr = 0; done: + free(req_auth_str); return kerr; } |
