From 4ad7fe5e6acc87140fc29b635605af8445d2d32f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 14 Apr 2009 11:20:30 -0400 Subject: [PATCH] Add common function to retrieve comma sep. lists Also convert all places where we were using custom code to parse config arguments. And fix a copy&paste error in nss_get_config --- server/confdb/confdb.c | 203 ++++++++++++++++++++++++++++++++--------- server/confdb/confdb.h | 4 + server/monitor/monitor.c | 54 +---------- server/responder/nss/nsssrv.c | 24 +++-- 4 files changed, 179 insertions(+), 106 deletions(-) diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c index d3a2a08..1f642ca 100644 --- a/server/confdb/confdb.c +++ b/server/confdb/confdb.c @@ -36,8 +36,8 @@ #include "ini_config.h" #define CONFDB_VERSION "1" -#define CONFDB_BASEDN "cn=config" -#define CONFDB_DOMAIN_BASEDN "cn=domains,"CONFDB_BASEDN +#define CONFDB_DOMAINS_PATH "config/domains" +#define CONFDB_DOMAIN_BASEDN "cn=domains,cn=config" #define CONFDB_DOMAIN_ATTR "cn" #define CONFDB_MPG "magicPrivateGroups" #define CONFDB_FQ "useFullyQualifiedNames" @@ -121,6 +121,110 @@ done: return ret; } +/* split a string into an allocated array of strings. + * the separator is a string, and is case-sensitive. + * optionally single values can be trimmed of of spaces and tabs */ +static int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, + char *sep, bool trim, char ***_list, int *size) +{ + const char *t, *p, *n; + size_t l, s, len; + char **list, **r; + + if (!str || !*str || !sep || !*sep || !_list) return EINVAL; + + s = strlen(sep); + t = str; + + list = NULL; + l = 0; + + if (trim) + while (*t == ' ' || *t == '\t') t++; + + while (t && (p = strstr(t, sep))) { + len = p - t; + n = p + s; /* save next string starting point */ + if (trim) { + while (*t == ' ' || *t == '\t') { + t++; + len--; + if (len == 0) break; + } + p--; + while (len > 0 && (*p == ' ' || *p == '\t')) { + len--; + p--; + } + } + + r = talloc_realloc(mem_ctx, list, char *, l + 2); + if (!r) { + talloc_free(list); + return ENOMEM; + } else { + list = r; + } + + if (len == 0) { + list[l] = talloc_strdup(list, ""); + } else { + list[l] = talloc_strndup(list, t, len); + } + if (!list[l]) { + talloc_free(list); + return ENOMEM; + } + l++; + + t = n; /* move to next string */ + } + + if (t) { + r = talloc_realloc(mem_ctx, list, char *, l + 2); + if (!r) { + talloc_free(list); + return ENOMEM; + } else { + list = r; + } + + if (trim) { + len = strlen(t); + while (*t == ' ' || *t == '\t') { + t++; + len--; + if (len == 0) break; + } + p = t + len - 1; + while (len > 0 && (*p == ' ' || *p == '\t')) { + len--; + p--; + } + + if (len == 0) { + list[l] = talloc_strdup(list, ""); + } else { + list[l] = talloc_strndup(list, t, len); + } + } else { + list[l] = talloc_strdup(list, t); + } + if (!list[l]) { + talloc_free(list); + return ENOMEM; + } + l++; + } + + list[l] = NULL; /* terminate list */ + + if (size) *size = l + 1; + *_list = list; + + return EOK; +} + int confdb_add_param(struct confdb_ctx *cdb, bool replace, const char *section, @@ -496,6 +600,43 @@ failed: return ret; } +/* WARNING: Unlike other similar functions, this one does NOT take a default, + * and returns ENOENT if the attribute was not found ! */ +int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx, + const char *section, const char *attribute, + char ***result) +{ + char **values = NULL; + int ret; + + ret = confdb_get_param(cdb, ctx, section, attribute, &values); + if (ret != EOK) { + goto done; + } + + if (values && values[0]) { + if (values[1] != NULL) { + /* too many values */ + ret = EINVAL; + goto done; + } + } else { + /* Did not return a value */ + ret = ENOENT; + goto done; + } + + ret = split_on_separator(ctx, values[0], ",", true, result, NULL); + +done: + talloc_free(values); + if (ret != EOK && ret != ENOENT) { + DEBUG(2, ("Failed to get [%s] from [%s], error [%d] (%s)", + attribute, section, ret, strerror(ret))); + } + return ret; +} + int confdb_test(struct confdb_ctx *cdb) { char **values; @@ -948,61 +1089,33 @@ int confdb_get_domains(struct confdb_ctx *cdb, struct sss_domain_info **domains) { TALLOC_CTX *tmp_ctx; - struct ldb_dn *dn; - struct ldb_result *res; struct sss_domain_info *domain, *prevdom; struct sss_domain_info *first = NULL; - const char *attrs[] = { "domains", NULL }; - const char *tmp; - char *cur, *p, *t; - int ret; + char **domlist; + int ret, i; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; - dn = ldb_dn_new(tmp_ctx, cdb->ldb, CONFDB_DOMAIN_BASEDN); - if (!dn) { - ret = EIO; - goto done; - } - - ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, - LDB_SCOPE_BASE, attrs, NULL); - if (ret != LDB_SUCCESS) { - ret = EIO; - goto done; - } - - if (res->count != 1) { - ret = EFAULT; + ret = confdb_get_string_as_list(cdb, tmp_ctx, + CONFDB_DOMAINS_PATH, "domains", &domlist); + if (ret == ENOENT) { + DEBUG(0, ("No domains configured, fatal error!\n")); goto done; } - - tmp = ldb_msg_find_attr_as_string(res->msgs[0], "domains", NULL); - if (!tmp) { - DEBUG(0, ("No domains configured, fatal error!\n")); - ret = EINVAL; + if (ret != EOK ) { + DEBUG(0, ("Fatal error retrieving domains list!\n")); goto done; } - cur = p = talloc_strdup(tmp_ctx, tmp); - while (p && *p) { - - for (cur = p; (*cur == ' ' || *cur == '\t'); cur++) /* trim */ ; - if (!*cur) break; - - p = strchr(cur, ','); - if (p) { - /* terminate element */ - *p = '\0'; - /* trim spaces */ - for (t = p-1; (*t == ' ' || *t == '\t'); t--) *t = '\0'; - p++; + for (i = 0; domlist[i]; i++) { + ret = confdb_get_domain(cdb, mem_ctx, domlist[i], &domain); + if (ret) { + DEBUG(0, ("Error (%d [%s]) retrieving domain %s, skipping!\n", + ret, strerror(ret), domains[i])); + continue; } - ret = confdb_get_domain(cdb, mem_ctx, cur, &domain); - if (ret) goto done; - if (first == NULL) { first = domain; prevdom = first; @@ -1014,7 +1127,7 @@ int confdb_get_domains(struct confdb_ctx *cdb, if (first == NULL) { DEBUG(0, ("No domains configured, fatal error!\n")); - ret = EINVAL; + ret = ENOENT; } *domains = first; diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h index 19614fc..76e4482 100644 --- a/server/confdb/confdb.h +++ b/server/confdb/confdb.h @@ -80,6 +80,10 @@ int confdb_get_bool(struct confdb_ctx *cdb, TALLOC_CTX *ctx, const char *section, const char *attribute, bool defval, bool *result); +int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx, + const char *section, const char *attribute, + char ***result); + int confdb_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx **cdb_ctx, diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c index dd80830..20734d1 100644 --- a/server/monitor/monitor.c +++ b/server/monitor/monitor.c @@ -544,11 +544,6 @@ static int service_signal_reload(struct mt_svc *svc) int get_monitor_config(struct mt_ctx *ctx) { int ret; - size_t svc_count = 0; - char *svcs; - char *cur, *p, *t; - char **svc_list = NULL; - char **tmp_list = NULL; ret = confdb_get_int(ctx->cdb, ctx, MONITOR_CONF_ENTRY, "sbusTimeout", @@ -557,61 +552,20 @@ int get_monitor_config(struct mt_ctx *ctx) return ret; } - ret = confdb_get_string(ctx->cdb, ctx, - SERVICE_CONF_ENTRY, "activeServices", - NULL, &svcs); - - if (ret != EOK || svcs == NULL) { + ret = confdb_get_string_as_list(ctx->cdb, ctx, SERVICE_CONF_ENTRY, + "activeServices", &ctx->services); + if (ret != EOK) { DEBUG(0, ("No services configured!\n")); return EINVAL; } - cur = p = talloc_strdup(svcs, svcs); - while (p && *p) { - for (cur = p; (*cur == ' ' || *cur == '\t'); cur++) /* trim */ ; - if (!*cur) break; - - p = strchr(cur, ','); - if (p) { - /* terminate element */ - *p = '\0'; - /* trim spaces */ - for (t = p-1; (*t == ' ' || *t == '\t'); t--) *t = '\0'; - p++; - } - - svc_count++; - tmp_list = talloc_realloc(svcs, svc_list, char *, svc_count); - if (!tmp_list) { - ret = ENOMEM; - goto done; - } - svc_list = tmp_list; - svc_list[svc_count-1] = talloc_strdup(svc_list, cur); - } - - svc_count++; - tmp_list = talloc_realloc(svcs, svc_list, char *, svc_count); - if (!tmp_list) { - ret = ENOMEM; - goto done; - } - svc_list = tmp_list; - svc_list[svc_count-1] = NULL; - - ctx->services = talloc_steal(ctx, svc_list); - ret = confdb_get_domains(ctx->cdb, ctx, &ctx->domains); if (ret != EOK) { DEBUG(2, ("No domains configured. LOCAL should always exist!\n")); return ret; } - ret = EOK; - -done: - talloc_free(svcs); - return ret; + return EOK; } static int get_service_config(struct mt_ctx *ctx, const char *name, diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c index e85e56b..e04a8c8 100644 --- a/server/responder/nss/nsssrv.c +++ b/server/responder/nss/nsssrv.c @@ -138,18 +138,20 @@ static int nss_get_config(struct nss_ctx *nctx, ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG, "EntryCacheTimeout", 600, - &nctx->enum_cache_timeout); + &nctx->cache_timeout); if (ret != EOK) goto done; ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG, "EntryNegativeTimeout", 15, - &nctx->enum_cache_timeout); + &nctx->neg_timeout); if (ret != EOK) goto done; - ret = confdb_get_param(cdb, nctx, NSS_SRV_CONFIG, - "filterUsers", &filter_list); - if (ret != EOK) goto done; - for (i = 0; filter_list[i]; i++) { + ret = confdb_get_string_as_list(cdb, tmpctx, NSS_SRV_CONFIG, + "filterUsers", &filter_list); + if (ret == ENOENT) filter_list = NULL; + else if (ret != EOK) goto done; + + for (i = 0; (filter_list && filter_list[i]); i++) { ret = sss_parse_name(tmpctx, nctx->rctx->names, filter_list[i], &domain, &name); if (ret != EOK) { @@ -178,11 +180,12 @@ static int nss_get_config(struct nss_ctx *nctx, } } } - talloc_free(filter_list); - ret = confdb_get_param(cdb, nctx, NSS_SRV_CONFIG, - "filterGroups", &filter_list); - if (ret != EOK) goto done; + ret = confdb_get_string_as_list(cdb, tmpctx, NSS_SRV_CONFIG, + "filterGroups", &filter_list); + if (ret == ENOENT) filter_list = NULL; + else if (ret != EOK) goto done; + for (i = 0; filter_list[i]; i++) { ret = sss_parse_name(tmpctx, nctx->rctx->names, filter_list[i], &domain, &name); @@ -212,7 +215,6 @@ static int nss_get_config(struct nss_ctx *nctx, } } } - talloc_free(filter_list); done: talloc_free(tmpctx); -- 1.6.0.6