diff options
-rw-r--r-- | server/confdb/confdb.c | 137 | ||||
-rw-r--r-- | server/confdb/confdb.h | 22 | ||||
-rw-r--r-- | server/monitor/monitor.c | 5 | ||||
-rw-r--r-- | server/responder/common/responder_common.c | 71 | ||||
-rw-r--r-- | server/responder/nss/nsssrv.c | 83 | ||||
-rw-r--r-- | server/responder/nss/nsssrv.h | 9 | ||||
-rw-r--r-- | server/responder/nss/nsssrv_cmd.c | 36 | ||||
-rw-r--r-- | server/util/btreemap.c | 46 | ||||
-rw-r--r-- | server/util/btreemap.h | 2 |
9 files changed, 211 insertions, 200 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c index 0435191b..ca335c58 100644 --- a/server/confdb/confdb.c +++ b/server/confdb/confdb.c @@ -24,6 +24,8 @@ #include "ldb_errors.h" #include "util/util.h" #include "confdb/confdb.h" +#include "util/btreemap.h" +#include "db/sysdb.h" #define CONFDB_VERSION "0.1" #define CONFDB_DOMAIN_BASEDN "cn=domains,cn=config" #define CONFDB_DOMAIN_ATTR "cn" @@ -600,9 +602,25 @@ int confdb_init(TALLOC_CTX *mem_ctx, return EOK; } +/* domain names are case insensitive for now + * NOTE: this function is not utf-8 safe, + * only ASCII names for now */ +static int _domain_comparator(const void *key1, const void *key2) +{ + int ret; + + ret = strcasecmp((const char *)key1, (const char *)key2); + if (ret) { + /* special case LOCAL to be always the first domain */ + if (strcmp(key1, "LOCAL") == 0) return 1; + if (strcmp(key2, "LOCAL") == 0) return -1; + } + return ret; +} + int confdb_get_domains(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, - char ***values) + struct btreemap **domains) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; @@ -610,8 +628,9 @@ int confdb_get_domains(struct confdb_ctx *cdb, struct ldb_message_element *el; int ret, i; const char *attrs[] = {CONFDB_DOMAIN_ATTR, NULL}; - char **vals; - int val_count; + char *path; + struct btreemap *domain_map; + struct sss_domain_info *domain; tmp_ctx = talloc_new(mem_ctx); @@ -628,15 +647,13 @@ int confdb_get_domains(struct confdb_ctx *cdb, goto done; } - val_count = 1; - vals = talloc(mem_ctx, char *); - if (!vals) { - ret = ENOMEM; - goto done; - } - + domain_map = NULL; i = 0; while (i < res->count) { + /* allocate the domain on the tmp_ctx. It will be stolen + * by btreemap_set_value + */ + domain = talloc_zero(tmp_ctx, struct sss_domain_info); el = ldb_msg_find_element(res->msgs[i], CONFDB_DOMAIN_ATTR); if (el && el->num_values > 0) { if (el->num_values > 1) { @@ -644,26 +661,106 @@ int confdb_get_domains(struct confdb_ctx *cdb, ret = EINVAL; goto done; } - val_count++; - vals = talloc_realloc(mem_ctx, vals, char *, val_count); - if (!vals) { - DEBUG(0, ("realloc failed\n")); + + /* should always be strings so this should be safe */ + struct ldb_val v = el->values[0]; + domain->name = talloc_strndup(domain, (char *)v.data, v.length); + if (!domain->name) { ret = ENOMEM; + talloc_free(domain_map); goto done; } - /* should always be strings so this should be safe */ - struct ldb_val v = el->values[0]; - vals[i] = talloc_strndup(vals, (char *)v.data, v.length); - if (!vals[i]) { + + /* Create the confdb path for this domain */ + path = talloc_asprintf(tmp_ctx, "config/domains/%s", domain->name); + if (!path) { + ret = ENOMEM; + goto done; + } + + /* Build the BaseDN for this domain */ + domain->basedn = talloc_asprintf(domain, SYSDB_DOM_BASE, domain->name); + if (domain->basedn == NULL) { ret = ENOMEM; goto done; } + DEBUG(3, ("BaseDN: %s\n", domain->basedn)); + + /* Determine if this domain can be enumerated */ + ret = confdb_get_int(cdb, domain, path, + "enumerate", false, &(domain->enumerate)); + if (ret != EOK) { + DEBUG(0, ("Failed to fetch enumerate for [%s]!\n", domain->name)); + goto done; + } + + /* Determine if this is a legacy domain */ + ret = confdb_get_bool(cdb, domain, path, + "legacy", false, &(domain->legacy)); + if (ret != EOK) { + DEBUG(0, ("Failed to fetch legacy for [%s]!\n", domain->name)); + goto done; + } + + /* Determine if this domain is managed by a backend provider */ + ret = confdb_get_string(cdb, domain, path, "provider", + NULL, &domain->provider); + if (ret != EOK) { + DEBUG(0, ("Failed to fetch provider for [%s]!\n", domain->name)); + goto done; + } + if (domain->provider) domain->has_provider = true; + + ret = btreemap_set_value(mem_ctx, &domain_map, + domain->name, domain, + _domain_comparator); + if (ret != EOK) { + DEBUG(1, ("Failed to store domain info for [%s]!\n", domain->name)); + goto done; + } + + talloc_free(path); } i++; } - vals[i] = NULL; - *values = vals; + *domains = domain_map; + +done: + talloc_free(tmp_ctx); + if (ret != EOK) { + talloc_free(domain_map); + *domains = NULL; + } + return ret; +} + +int confdb_get_domains_list(struct confdb_ctx *cdb, + TALLOC_CTX *mem_ctx, + const char ***domain_names, + int *count) +{ + int ret; + struct btreemap *domain_map; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(mem_ctx); + if(tmp_ctx == NULL) { + return ENOMEM; + } + + ret = confdb_get_domains(cdb, tmp_ctx, &domain_map); + if (ret != EOK || domain_map == NULL) { + DEBUG(0, ("Error, no domains were configured\n")); + *domain_names = NULL; + count = 0; + goto done; + } + + ret = btreemap_get_keys(mem_ctx, domain_map, (const void ***)domain_names, count); + if (ret != EOK) { + DEBUG(0, ("Couldn't get domain list\n")); + } done: talloc_free(tmp_ctx); diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h index a1d80855..3bd0d038 100644 --- a/server/confdb/confdb.h +++ b/server/confdb/confdb.h @@ -19,12 +19,25 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _CONF_DB_H +#define _CONF_DB_H + #include <stdbool.h> #include "talloc.h" #include "tevent.h" +#include "util/btreemap.h" #define CONFDB_FILE "config.ldb" +struct sss_domain_info { + char *name; + char *basedn; + int enumerate; + bool has_provider; + char *provider; + bool legacy; +}; + struct confdb_ctx; int confdb_add_param(struct confdb_ctx *cdb, @@ -59,4 +72,11 @@ int confdb_init(TALLOC_CTX *mem_ctx, int confdb_get_domains(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, - char ***values); + struct btreemap **domains); + +int confdb_get_domains_list(struct confdb_ctx *cdb, + TALLOC_CTX *mem_ctx, + const char ***domain_names, + int *count); + +#endif diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c index ff88b293..a07178f8 100644 --- a/server/monitor/monitor.c +++ b/server/monitor/monitor.c @@ -365,6 +365,7 @@ int monitor_process_init(TALLOC_CTX *mem_ctx, struct mt_ctx *ctx; struct mt_svc *svc; char **doms; + int dom_count; char *path; int ret, i; @@ -434,13 +435,13 @@ int monitor_process_init(TALLOC_CTX *mem_ctx, } /* now start the data providers */ - ret = confdb_get_domains(cdb, ctx, &doms); + ret = confdb_get_domains_list(cdb, ctx, (const char ***)&doms, &dom_count); if (ret != EOK) { DEBUG(2, ("No domains configured. LOCAL should always exist!\n")); return ret; } - for (i = 0; doms[i]; i++) { + for (i = 0; i < dom_count; i++) { svc = talloc_zero(ctx, struct mt_svc); if (!svc) { talloc_free(ctx); diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c index 74e03215..f532102f 100644 --- a/server/responder/common/responder_common.c +++ b/server/responder/common/responder_common.c @@ -319,85 +319,20 @@ failed: return EIO; } -/* domain names are case insensitive for now - * NOTE: this function is not utf-8 safe, - * only ASCII names for now */ -static int _domain_comparator(const void *key1, const void *key2) -{ - return strcasecmp((const char *)key1, (const char *)key2); -} - static int sss_init_domains(struct nss_ctx *nctx) { - char *path; - char **domains; - char *provider; TALLOC_CTX *tmp_ctx; - struct nss_domain_info *info; - int ret, i, c; + int ret; int retval; tmp_ctx = talloc_new(nctx); - ret = confdb_get_domains(nctx->cdb, tmp_ctx, &domains); + ret = confdb_get_domains(nctx->cdb, nctx, &nctx->domain_map); if (ret != EOK) { retval = ret; goto done; } - i = 0; - c = 0; - while (domains[i] != NULL) { - DEBUG(3, ("Adding domain %s to the map\n", domains[i])); - - path = talloc_asprintf(tmp_ctx, "config/domains/%s", domains[i]); - if (!path) { - retval = ENOMEM; - goto done; - } - - /* alloc on tmp_ctx, it will be stolen by btreemap_set_value */ - info = talloc_zero(tmp_ctx, struct nss_domain_info); - if (!info) { - retval = ENOMEM; - goto done; - } - - /* Build the basedn for this domain */ - info->basedn = talloc_asprintf(info, SYSDB_DOM_BASE, domains[i]); - DEBUG(3, ("BaseDN: %s\n", info->basedn)); - - ret = confdb_get_int(nctx->cdb, tmp_ctx, path, - "enumerate", false, &(info->enumerate)); - if (ret != EOK) { - DEBUG(0, ("Failed to fetch enumerate for [%s]!\n", domains[i])); - } - - ret = confdb_get_bool(nctx->cdb, tmp_ctx, path, - "legacy", false, &(info->legacy)); - if (ret != EOK) { - DEBUG(0, ("Failed to fetch legacy for [%s]!\n", domains[i])); - } - - ret = confdb_get_string(nctx->cdb, tmp_ctx, path, "provider", - NULL, &provider); - if (ret != EOK) { - DEBUG(0, ("Failed to fetch provider for [%s]!\n", domains[i])); - } - if (provider) info->has_provider = true; - - ret = btreemap_set_value(nctx, &nctx->domain_map, - domains[i], info, - _domain_comparator); - if (ret != EOK) { - DEBUG(1, ("Failed to store domain info, aborting!\n")); - retval = ret; - goto done; - } - - i++; - c++; - } - if (c == 0) { + if (nctx->domain_map == NULL) { /* No domains configured! * Note: this should never happen, since LOCAL should * always be configured */ diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c index 2fbe3970..7c68ba19 100644 --- a/server/responder/nss/nsssrv.c +++ b/server/responder/nss/nsssrv.c @@ -49,7 +49,6 @@ static int service_identity(DBusMessage *message, struct sbus_conn_ctx *sconn); static int service_pong(DBusMessage *message, struct sbus_conn_ctx *sconn); static int service_reload(DBusMessage *message, struct sbus_conn_ctx *sconn); static int nss_init_domains(struct nss_ctx *nctx); -static int _domain_comparator(const void *key1, const void *key2); struct sbus_method nss_sbus_methods[] = { {SERVICE_METHOD_IDENTITY, service_identity}, @@ -392,93 +391,18 @@ failed: return EIO; } -/* domain names are case insensitive for now - * NOTE: this function is not utf-8 safe, - * only ASCII names for now */ -static int _domain_comparator(const void *key1, const void *key2) -{ - int ret; - - ret = strcasecmp((const char *)key1, (const char *)key2); - if (ret) { - /* special case LOCAL to be always the first domain */ - if (strcmp(key1, "LOCAL") == 0) return 1; - if (strcmp(key2, "LOCAL") == 0) return -1; - } - return ret; -} - static int nss_init_domains(struct nss_ctx *nctx) { - char *path; - char **domains; - char *provider; - TALLOC_CTX *tmp_ctx; - struct nss_domain_info *info; - int ret, i, c; + int ret; int retval; - tmp_ctx = talloc_new(nctx); - ret = confdb_get_domains(nctx->cdb, tmp_ctx, &domains); + ret = confdb_get_domains(nctx->cdb, nctx, &nctx->domain_map); if (ret != EOK) { retval = ret; goto done; } - i = 0; - c = 0; - while (domains[i] != NULL) { - DEBUG(3, ("Adding domain %s to the map\n", domains[i])); - - path = talloc_asprintf(tmp_ctx, "config/domains/%s", domains[i]); - if (!path) { - retval = ENOMEM; - goto done; - } - - /* alloc on tmp_ctx, it will be stolen by btreemap_set_value */ - info = talloc_zero(tmp_ctx, struct nss_domain_info); - if (!info) { - retval = ENOMEM; - goto done; - } - - /* Build the basedn for this domain */ - info->basedn = talloc_asprintf(info, SYSDB_DOM_BASE, domains[i]); - DEBUG(3, ("BaseDN: %s\n", info->basedn)); - - ret = confdb_get_int(nctx->cdb, tmp_ctx, path, - "enumerate", false, &(info->enumerate)); - if (ret != EOK) { - DEBUG(0, ("Failed to fetch enumerate for [%s]!\n", domains[i])); - } - - ret = confdb_get_bool(nctx->cdb, tmp_ctx, path, - "legacy", false, &(info->legacy)); - if (ret != EOK) { - DEBUG(0, ("Failed to fetch legacy for [%s]!\n", domains[i])); - } - - ret = confdb_get_string(nctx->cdb, tmp_ctx, path, "provider", - NULL, &provider); - if (ret != EOK) { - DEBUG(0, ("Failed to fetch provider for [%s]!\n", domains[i])); - } - if (provider) info->has_provider = true; - - ret = btreemap_set_value(nctx, &nctx->domain_map, - domains[i], info, - _domain_comparator); - if (ret != EOK) { - DEBUG(1, ("Failed to store domain info, aborting!\n")); - retval = ret; - goto done; - } - - i++; - c++; - } - if (c == 0) { + if (nctx->domain_map == NULL) { /* No domains configured! * Note: this should never happen, since LOCAL should * always be configured */ @@ -498,7 +422,6 @@ static int nss_init_domains(struct nss_ctx *nctx) retval = EOK; done: - talloc_free(tmp_ctx); return retval; } diff --git a/server/responder/nss/nsssrv.h b/server/responder/nss/nsssrv.h index 333e4281..1431dded 100644 --- a/server/responder/nss/nsssrv.h +++ b/server/responder/nss/nsssrv.h @@ -65,7 +65,7 @@ struct nss_ctx { int cache_timeout; struct sbus_method *sss_sbus_methods; - struct sss_cmd_table *sss_cmds; + struct sss_cmd_table *sss_cmds; const char *sss_pipe_name; const char *confdb_socket_path; struct sbus_method *dp_methods; @@ -81,13 +81,6 @@ struct cli_ctx { struct getent_ctx *gctx; }; -struct nss_domain_info { - char *basedn; - int enumerate; - bool has_provider; - bool legacy; -}; - struct nss_packet; struct cli_request { diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c index 16146585..76da6e06 100644 --- a/server/responder/nss/nsssrv_cmd.c +++ b/server/responder/nss/nsssrv_cmd.c @@ -25,6 +25,7 @@ #include "responder/nss/nsssrv.h" #include "db/sysdb.h" #include <time.h> +#include "confdb/confdb.h" struct nss_cmd_ctx { struct cli_ctx *cctx; @@ -92,7 +93,7 @@ static int nss_parse_name(struct nss_dom_ctx *dctx, const char *fullname) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct nss_ctx *nctx = cmdctx->cctx->nctx; - struct nss_domain_info *info; + struct sss_domain_info *info; struct btreemap *domain_map; char *delim; char *domain; @@ -617,7 +618,7 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx) { struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; - struct nss_domain_info *info; + struct sss_domain_info *info; const char **domains; uint8_t *body; size_t blen; @@ -643,8 +644,10 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx) domains = NULL; num = 0; /* get domains list */ - btreemap_get_keys(cmdctx, cctx->nctx->domain_map, - (const void ***)&domains, &num); + ret = btreemap_get_keys(cmdctx, cctx->nctx->domain_map, + (const void ***)&domains, &num); + if (ret != EOK) + return ret; cmdctx->nr = num; @@ -797,7 +800,7 @@ static void nss_cmd_setpw_dp_callback(uint16_t err_maj, uint32_t err_min, static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, bool immediate) { - struct nss_domain_info *info; + struct sss_domain_info *info; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; struct getent_ctx *gctx; @@ -832,8 +835,11 @@ static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, bool immediate) domains = NULL; num = 0; /* get domains list */ - btreemap_get_keys(cmdctx, cctx->nctx->domain_map, + ret = btreemap_get_keys(cmdctx, cctx->nctx->domain_map, (const void ***)&domains, &num); + if (ret != EOK) { + return ret; + } /* check if enumeration is enabled in any domain */ for (i = 0; i < num; i++) { @@ -1515,7 +1521,7 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx) { struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; - struct nss_domain_info *info; + struct sss_domain_info *info; const char **domains; uint8_t *body; size_t blen; @@ -1541,8 +1547,11 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx) domains = NULL; num = 0; /* get domains list */ - btreemap_get_keys(cmdctx, cctx->nctx->domain_map, - (const void ***)&domains, &num); + ret = btreemap_get_keys(cmdctx, cctx->nctx->domain_map, + (const void ***)&domains, &num); + if (ret != EOK) { + return ret; + } cmdctx->nr = num; @@ -1693,7 +1702,7 @@ static void nss_cmd_setgr_dp_callback(uint16_t err_maj, uint32_t err_min, static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, bool immediate) { - struct nss_domain_info *info; + struct sss_domain_info *info; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; struct getent_ctx *gctx; @@ -1728,8 +1737,11 @@ static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, bool immediate) domains = NULL; num = 0; /* get domains list */ - btreemap_get_keys(cmdctx, cctx->nctx->domain_map, - (const void ***)&domains, &num); + ret = btreemap_get_keys(cmdctx, cctx->nctx->domain_map, + (const void ***)&domains, &num); + if(ret != EOK) { + return ret; + } /* check if enumeration is enabled in any domain */ for (i = 0; i < num; i++) { diff --git a/server/util/btreemap.c b/server/util/btreemap.c index c9289f52..7bda0570 100644 --- a/server/util/btreemap.c +++ b/server/util/btreemap.c @@ -166,21 +166,51 @@ int btreemap_set_value(TALLOC_CTX *mem_ctx, return EOK; } -/* Return an array of keys in sort order - * count should be initialized to zero before calling this function. - */ -void btreemap_get_keys(TALLOC_CTX *mem_ctx, struct btreemap *map, const void ***array, int *count) +static int _btreemap_get_keys(TALLOC_CTX *mem_ctx, struct btreemap *map, const void ***array, int *count, int depth) { - if (map == NULL) return; + int ret; + const void **tmp_array; + + if (map == NULL) { + if (depth == 0) { + /* This is the top-level */ + count = 0; + *array = NULL; + } + return EOK; + } /* Left Node */ - btreemap_get_keys(mem_ctx, map->left, array, count); + ret = _btreemap_get_keys(mem_ctx, map->left, array, count, depth+1); + if (ret != EOK) { + return ret; + } /* Current Node */ (*count)++; - *array = talloc_realloc(mem_ctx, *array, const void *, *count); + tmp_array = talloc_realloc(mem_ctx, *array, const void *, *count); + if (tmp_array == NULL) { + /* Out of memory */ + *count = 0; + talloc_free(*array); + *array = NULL; + return ENOMEM; + } + *array = tmp_array; (*array)[(*count)-1] = map->key; /* Right Node */ - btreemap_get_keys(mem_ctx, map->right, array, count); + ret = _btreemap_get_keys(mem_ctx, map->right, array, count, depth+1); + if (ret != EOK) { + return ret; + } + + return EOK; +} +/* Return an array of keys in sort order + */ +int btreemap_get_keys(TALLOC_CTX *mem_ctx, struct btreemap *map, const void ***array, int *count) +{ + *array = NULL; + return _btreemap_get_keys(mem_ctx, map, array, count, 0); } diff --git a/server/util/btreemap.h b/server/util/btreemap.h index c5c41507..8d7fb159 100644 --- a/server/util/btreemap.h +++ b/server/util/btreemap.h @@ -35,7 +35,7 @@ void *btreemap_get_value(struct btreemap *map, const void *key); int btreemap_set_value(TALLOC_CTX *mem_ctx, struct btreemap **map, const void *key, void *value, btreemap_comparison_fn comparator); -void btreemap_get_keys(TALLOC_CTX *mem_ctx, struct btreemap *map, const void ***array, int *count); +int btreemap_get_keys(TALLOC_CTX *mem_ctx, struct btreemap *map, const void ***array, int *count); #endif /*BTREEMAP_H_*/ |