Before this patch, ipa-kdb would load global configuration on startup and never update it. This means that if global configuration is changed, the KDC never receives the new configuration until it is restarted.
This patch enables caching of the global configuration with a timeout of 60 seconds. https://fedorahosted.org/freeipa/ticket/4153
>From 7daeae56671d7b3049b0341aad66c96877431bbe Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum <[email protected]> Date: Mon, 24 Feb 2014 14:19:13 -0500 Subject: [PATCH] Periodically refresh global ipa-kdb configuration Before this patch, ipa-kdb would load global configuration on startup and never update it. This means that if global configuration is changed, the KDC never receives the new configuration until it is restarted. This patch enables caching of the global configuration with a timeout of 60 seconds. https://fedorahosted.org/freeipa/ticket/4153 --- daemons/ipa-kdb/ipa_kdb.c | 65 +++++++++++++++++++++--------------- daemons/ipa-kdb/ipa_kdb.h | 17 +++++++--- daemons/ipa-kdb/ipa_kdb_audit_as.c | 4 +-- daemons/ipa-kdb/ipa_kdb_mspac.c | 7 ++-- daemons/ipa-kdb/ipa_kdb_principals.c | 6 ++-- 5 files changed, 62 insertions(+), 37 deletions(-) diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c index 0f3996cdfa35374c005bc1ed174dea0816a27747..1b55735f1118ccbba2fc5d810c0171724634f9ad 100644 --- a/daemons/ipa-kdb/ipa_kdb.c +++ b/daemons/ipa-kdb/ipa_kdb.c @@ -25,6 +25,8 @@ #include "ipa_kdb.h" +#define IPADB_GLOBAL_CONFIG_CACHE_TIME 60 + struct ipadb_context *ipadb_get_context(krb5_context kcontext) { void *db_ctx; @@ -41,6 +43,7 @@ struct ipadb_context *ipadb_get_context(krb5_context kcontext) static void ipadb_context_free(krb5_context kcontext, struct ipadb_context **ctx) { + struct ipadb_global_config *cfg; size_t c; if (*ctx != NULL) { @@ -56,10 +59,11 @@ static void ipadb_context_free(krb5_context kcontext, ipadb_mspac_struct_free(&(*ctx)->mspac); krb5_free_default_realm(kcontext, (*ctx)->realm); - for (c = 0; (*ctx)->authz_data && (*ctx)->authz_data[c]; c++) { - free((*ctx)->authz_data[c]); + cfg = &(*ctx)->config; + for (c = 0; cfg->authz_data && cfg->authz_data[c]; c++) { + free(cfg->authz_data[c]); } - free((*ctx)->authz_data); + free(cfg->authz_data); free(*ctx); *ctx = NULL; @@ -209,7 +213,7 @@ void ipadb_parse_user_auth(LDAP *lcontext, LDAPMessage *le, ldap_value_free_len(vals); } -int ipadb_get_global_configs(struct ipadb_context *ipactx) +static int ipadb_load_global_config(struct ipadb_context *ipactx) { char *attrs[] = { "ipaConfigString", IPA_KRB_AUTHZ_DATA_ATTR, IPA_USER_AUTH_TYPE, NULL }; @@ -241,45 +245,40 @@ int ipadb_get_global_configs(struct ipadb_context *ipactx) } /* Check for permitted authentication types. */ - ipadb_parse_user_auth(ipactx->lcontext, res, &ipactx->user_auth); + ipadb_parse_user_auth(ipactx->lcontext, res, &ipactx->config.user_auth); - vals = ldap_get_values_len(ipactx->lcontext, first, - "ipaConfigString"); - if (!vals || !vals[0]) { - /* no config, set nothing */ - ret = 0; - goto done; - } - - for (i = 0; vals[i]; i++) { + /* Load config strings. */ + vals = ldap_get_values_len(ipactx->lcontext, first, "ipaConfigString"); + for (i = 0; vals && vals[i]; i++) { if (strncasecmp("KDC:Disable Last Success", vals[i]->bv_val, vals[i]->bv_len) == 0) { - ipactx->disable_last_success = true; + ipactx->config.disable_last_success = true; continue; } + if (strncasecmp("KDC:Disable Lockout", vals[i]->bv_val, vals[i]->bv_len) == 0) { - ipactx->disable_lockout = true; + ipactx->config.disable_lockout = true; continue; } } + /* Load authz data. */ ret = ipadb_ldap_attr_to_strlist(ipactx->lcontext, first, IPA_KRB_AUTHZ_DATA_ATTR, &authz_data_list); - if (ret != 0 && ret != ENOENT) { - goto done; - } if (ret == 0) { - if (ipactx->authz_data != NULL) { - for (i = 0; ipactx->authz_data[i]; i++) { - free(ipactx->authz_data[i]); - } - free(ipactx->authz_data); + if (ipactx->config.authz_data != NULL) { + for (i = 0; ipactx->config.authz_data[i]; i++) + free(ipactx->config.authz_data[i]); + free(ipactx->config.authz_data); } - ipactx->authz_data = authz_data_list; - } + ipactx->config.authz_data = authz_data_list; + } else if (ret != ENOENT) + goto done; + /* Success! */ + ipactx->config.last_update = time(NULL); ret = 0; done: @@ -289,6 +288,18 @@ done: return ret; } +const struct ipadb_global_config * +ipadb_get_global_config(struct ipadb_context *ipactx) +{ + time_t now = 0; + + if (time(&now) != (time_t)-1 + && now - ipactx->config.last_update > IPADB_GLOBAL_CONFIG_CACHE_TIME) + ipadb_load_global_config(ipactx); + + return &ipactx->config; +} + int ipadb_get_connection(struct ipadb_context *ipactx) { struct berval **vals = NULL; @@ -390,7 +401,7 @@ int ipadb_get_connection(struct ipadb_context *ipactx) ipactx->n_supp_encs = n_kst; /* get additional options */ - ret = ipadb_get_global_configs(ipactx); + ret = ipadb_load_global_config(ipactx); if (ret) { goto done; } diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h index 6c036e3b6403a3b5fde544dc49c9d7efbaa6ca9b..b92107bab5a259601160a402c54fa8ed440925b3 100644 --- a/daemons/ipa-kdb/ipa_kdb.h +++ b/daemons/ipa-kdb/ipa_kdb.h @@ -87,6 +87,14 @@ enum ipadb_user_auth { IPADB_USER_AUTH_OTP = 1 << 3, }; +struct ipadb_global_config { + time_t last_update; + bool disable_last_success; + bool disable_lockout; + char **authz_data; + enum ipadb_user_auth user_auth; +}; + struct ipadb_context { char *uri; char *base; @@ -99,10 +107,9 @@ struct ipadb_context { krb5_key_salt_tuple *supp_encs; int n_supp_encs; struct ipadb_mspac *mspac; - bool disable_last_success; - bool disable_lockout; - char **authz_data; - enum ipadb_user_auth user_auth; + + /* Don't access this directly, use ipadb_get_global_config(). */ + struct ipadb_global_config config; }; #define IPA_E_DATA_MAGIC 0x0eda7a @@ -277,3 +284,5 @@ void ipadb_audit_as_req(krb5_context kcontext, /* AUTH METHODS */ void ipadb_parse_user_auth(LDAP *lcontext, LDAPMessage *le, enum ipadb_user_auth *user_auth); +const struct ipadb_global_config * +ipadb_get_global_config(struct ipadb_context *ipactx); diff --git a/daemons/ipa-kdb/ipa_kdb_audit_as.c b/daemons/ipa-kdb/ipa_kdb_audit_as.c index 7596db0fae165efd21e7c24f9af97a200e99e624..ef69f85ded88c743e22a0939f5c5a7b823f09cf6 100644 --- a/daemons/ipa-kdb/ipa_kdb_audit_as.c +++ b/daemons/ipa-kdb/ipa_kdb_audit_as.c @@ -72,7 +72,7 @@ void ipadb_audit_as_req(krb5_context kcontext, client->fail_auth_count = 0; client->mask |= KMASK_FAIL_AUTH_COUNT; } - if (ipactx->disable_last_success) { + if (ipadb_get_global_config(ipactx)->disable_last_success) { break; } client->last_success = authtime; @@ -83,7 +83,7 @@ void ipadb_audit_as_req(krb5_context kcontext, case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5KRB_AP_ERR_BAD_INTEGRITY: - if (ipactx->disable_lockout) { + if (ipadb_get_global_config(ipactx)->disable_lockout) { break; } diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index ff67391538234e2272ea1ec886ec96fa88ea579b..e8130ffd9b79f74d7432b228867220f38e7322fb 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -1859,6 +1859,8 @@ void get_authz_data_types(krb5_context context, krb5_db_entry *entry, } if (ied == NULL || ied->authz_data == NULL) { + char **tmp; + if (context == NULL) { krb5_klog_syslog(LOG_ERR, "Missing Kerberos context, no " \ "authorization data will be added."); @@ -1866,14 +1868,15 @@ void get_authz_data_types(krb5_context context, krb5_db_entry *entry, } ipactx = ipadb_get_context(context); - if (ipactx == NULL || ipactx->authz_data == NULL) { + tmp = ipadb_get_global_config(ipactx)->authz_data; + if (ipactx == NULL || tmp == NULL) { krb5_klog_syslog(LOG_ERR, "No default authorization data types " \ "available, no authorization data will " \ "be added."); goto done; } - authz_data_list = ipactx->authz_data; + authz_data_list = tmp; } else { authz_data_list = ied->authz_data; } diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index f0be76ea7b36efe3540429f7e31ffbc582edd060..9e74b0861a09df11c37c338be21131206322cc92 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -320,18 +320,20 @@ static void ipadb_validate_password(struct ipadb_context *ipactx, static enum ipadb_user_auth ipadb_get_user_auth(struct ipadb_context *ipactx, LDAPMessage *lentry) { + enum ipadb_user_auth gua = IPADB_USER_AUTH_NONE; enum ipadb_user_auth ua = IPADB_USER_AUTH_NONE; /* Get the user's user_auth settings. */ ipadb_parse_user_auth(ipactx->lcontext, lentry, &ua); /* If the disabled flag is set, ignore everything else. */ - if ((ua | ipactx->user_auth) & IPADB_USER_AUTH_DISABLED) + gua = ipadb_get_global_config(ipactx)->user_auth; + if ((ua | gua) & IPADB_USER_AUTH_DISABLED) return IPADB_USER_AUTH_DISABLED; /* Determine which user_auth policy is active: user or global. */ if (ua == IPADB_USER_AUTH_NONE) - ua = ipactx->user_auth; + ua = gua; /* Perform flag validation. */ ipadb_validate_otp(ipactx, lentry, &ua); -- 1.8.5.3
_______________________________________________ Freeipa-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/freeipa-devel
