summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/confdb/confdb.c137
-rw-r--r--server/confdb/confdb.h22
-rw-r--r--server/monitor/monitor.c5
-rw-r--r--server/responder/common/responder_common.c71
-rw-r--r--server/responder/nss/nsssrv.c83
-rw-r--r--server/responder/nss/nsssrv.h9
-rw-r--r--server/responder/nss/nsssrv_cmd.c36
-rw-r--r--server/util/btreemap.c46
-rw-r--r--server/util/btreemap.h2
9 files changed, 211 insertions, 200 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index 0435191be..ca335c587 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 a1d808559..3bd0d0387 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 ff88b293c..a07178f87 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 74e03215c..f532102f1 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 2fbe39706..7c68ba190 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 333e42815..1431ddedd 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 16146585f..76da6e063 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 c9289f521..7bda0570a 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 c5c415075..8d7fb1595 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_*/