From 3a946e38a911fdfb1575135c41128f41ab44324c Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 26 May 2017 18:19:48 +0200 Subject: [PATCH] ipa-kdb: reload certificate mapping rules periodically With this patch the certificate mapping rules are reloaded every 5 minutes. Resolves https://pagure.io/freeipa/issue/6963 Reviewed-By: David Kupka --- daemons/ipa-kdb/ipa_kdb_certauth.c | 153 ++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 72 deletions(-) diff --git a/daemons/ipa-kdb/ipa_kdb_certauth.c b/daemons/ipa-kdb/ipa_kdb_certauth.c index a53a2ce4e7ceb06ec8de117cdbca2666fdb5a97a..dbe7a0443700784d2b8dbb1fb9196d6249e5522a 100644 --- a/daemons/ipa-kdb/ipa_kdb_certauth.c +++ b/daemons/ipa-kdb/ipa_kdb_certauth.c @@ -58,6 +58,8 @@ #define CERTMAP_FILTER "(&("OBJECTCLASS"="IPA_OC_CERTMAP_RULE")" \ "("IPA_ENABLED_FLAG"="IPA_TRUE_VALUE"))" +#define DEFAULT_CERTMAP_LIFETIME 300 + #ifndef discard_const #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) #endif @@ -67,6 +69,7 @@ struct krb5_certauth_moddata_st { char *local_domain; struct sss_certmap_ctx *sss_certmap_ctx; struct ipadb_context *ipactx; + time_t valid_until; }; void ipa_certmap_debug(void *private, @@ -133,95 +136,101 @@ static krb5_error_code ipa_get_init_data(krb5_context kcontext, } if (ipactx->certauth_moddata == NULL) { - ret = asprintf(&basedn, "cn=certmap,%s", ipactx->base); - if (ret == -1) { - return ENOMEM; - } + ipactx->certauth_moddata = moddata_out; - kerr = ipadb_simple_search(ipactx,basedn, LDAP_SCOPE_SUBTREE, - CERTMAP_FILTER, discard_const(certmap_attrs), - &result); - if (kerr != 0 && kerr != KRB5_KDB_NOENTRY) { - goto done; + if (ipactx->realm != NULL) { + ipactx->certauth_moddata->local_domain = strdup(ipactx->realm); + if (ipactx->certauth_moddata->local_domain == NULL) { + free(ipactx->certauth_moddata); + ipactx->certauth_moddata = NULL; + ret = ENOMEM; + goto done; + } } - ret = sss_certmap_init(NULL, ipa_certmap_debug, NULL, &ctx); + ipactx->certauth_moddata->ipactx = ipactx; + + } + + ret = asprintf(&basedn, "cn=certmap,%s", ipactx->base); + if (ret == -1) { + return ENOMEM; + } + + kerr = ipadb_simple_search(ipactx,basedn, LDAP_SCOPE_SUBTREE, + CERTMAP_FILTER, discard_const(certmap_attrs), + &result); + if (kerr != 0 && kerr != KRB5_KDB_NOENTRY) { + goto done; + } + + ret = sss_certmap_init(NULL, ipa_certmap_debug, NULL, &ctx); + if (ret != 0) { + return ret; + } + + if (kerr == KRB5_KDB_NOENTRY) { + ret = sss_certmap_add_rule(ctx, SSS_CERTMAP_MIN_PRIO, + NULL, NULL, NULL); if (ret != 0) { - return ret; + goto done; } - - if (kerr == KRB5_KDB_NOENTRY) { - ret = sss_certmap_add_rule(ctx, SSS_CERTMAP_MIN_PRIO, - NULL, NULL, NULL); - if (ret != 0) { + } else { + lc = ipactx->lcontext; + + for (le = ldap_first_entry(lc, result); le; + le = ldap_next_entry(lc, le)) { + prio = SSS_CERTMAP_MIN_PRIO; + ret = ipadb_ldap_attr_to_uint32(lc, le, IPA_CERTMAP_PRIORITY, + &prio); + if (ret != 0 && ret != ENOENT) { goto done; } - } else { - lc = ipactx->lcontext; - - for (le = ldap_first_entry(lc, result); le; - le = ldap_next_entry(lc, le)) { - prio = SSS_CERTMAP_MIN_PRIO; - ret = ipadb_ldap_attr_to_uint32(lc, le, IPA_CERTMAP_PRIORITY, - &prio); - if (ret != 0 && ret != ENOENT) { - goto done; - } - - free(map_rule); - map_rule = NULL; - ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MAPRULE, - &map_rule); - if (ret != 0 && ret != ENOENT) { - goto done; - } - free(match_rule); - match_rule = NULL; - ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MATCHRULE, - &match_rule); - if (ret != 0 && ret != ENOENT) { - goto done; - } + free(map_rule); + map_rule = NULL; + ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MAPRULE, + &map_rule); + if (ret != 0 && ret != ENOENT) { + goto done; + } - if (domains != NULL) { - for (c = 0; domains[c] != NULL; c++) { - free(domains[c]); - } - free(domains); - domains = NULL; - } - ret = ipadb_ldap_attr_to_strlist(lc, le, IPA_ASSOCIATED_DOMAIN, - &domains); - if (ret != 0 && ret != ENOENT) { - goto done; - } + free(match_rule); + match_rule = NULL; + ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MATCHRULE, + &match_rule); + if (ret != 0 && ret != ENOENT) { + goto done; + } - ret = sss_certmap_add_rule(ctx, prio, match_rule, map_rule, - (const char **) domains); - if (ret != 0) { - goto done; + if (domains != NULL) { + for (c = 0; domains[c] != NULL; c++) { + free(domains[c]); } + free(domains); + domains = NULL; + } + ret = ipadb_ldap_attr_to_strlist(lc, le, IPA_ASSOCIATED_DOMAIN, + &domains); + if (ret != 0 && ret != ENOENT) { + goto done; } - } - - ipactx->certauth_moddata = moddata_out; - if (ipactx->realm != NULL) { - ipactx->certauth_moddata->local_domain = strdup(ipactx->realm); - if (ipactx->certauth_moddata->local_domain == NULL) { - free(ipactx->certauth_moddata); - ipactx->certauth_moddata = NULL; - ret = ENOMEM; + ret = sss_certmap_add_rule(ctx, prio, match_rule, map_rule, + (const char **) domains); + if (ret != 0) { goto done; } } - - ipactx->certauth_moddata->sss_certmap_ctx = ctx; - ipactx->certauth_moddata->ipactx = ipactx; - } + sss_certmap_free_ctx(ipactx->certauth_moddata->sss_certmap_ctx); + ipactx->certauth_moddata->sss_certmap_ctx = ctx; + ipactx->certauth_moddata->valid_until = time(NULL) + + DEFAULT_CERTMAP_LIFETIME; + krb5_klog_syslog(LOG_DEBUG, + "Successfully updates certificate mapping rules."); + ret = 0; done: @@ -266,7 +275,7 @@ static krb5_error_code ipa_certauth_authorize(krb5_context context, return KRB5_PLUGIN_NO_HANDLE; } - if (moddata->sss_certmap_ctx == NULL) { + if (moddata->sss_certmap_ctx == NULL || time(NULL) > moddata->valid_until) { kerr = ipa_get_init_data(context, moddata); if (kerr != 0) { krb5_klog_syslog(LOG_ERR, "Failed to init certmapping data"); -- 2.9.4