summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/Makefile.am1
-rw-r--r--server/confdb/confdb.c52
-rw-r--r--server/confdb/confdb.h2
-rw-r--r--server/confdb/confdb_private.h2
-rw-r--r--server/db/sysdb.c793
-rw-r--r--server/db/sysdb.h18
-rw-r--r--server/db/sysdb_private.h28
-rw-r--r--server/monitor/monitor.c17
-rw-r--r--server/providers/data_provider_be.c4
-rw-r--r--server/responder/common/responder.h2
-rw-r--r--server/responder/common/responder_common.c4
-rw-r--r--server/responder/nss/nsssrv_cmd.c205
-rw-r--r--server/responder/pam/pam_LOCAL_domain.c8
-rw-r--r--server/responder/pam/pamsrv_cache.c9
-rw-r--r--server/responder/pam/pamsrv_cmd.c29
-rw-r--r--server/tests/sysdb-tests.c127
-rw-r--r--server/tools/sss_groupadd.c10
-rw-r--r--server/tools/sss_groupdel.c12
-rw-r--r--server/tools/sss_groupmod.c18
-rw-r--r--server/tools/sss_useradd.c16
-rw-r--r--server/tools/sss_userdel.c12
-rw-r--r--server/tools/sss_usermod.c18
-rw-r--r--server/tools/tools_util.c4
-rw-r--r--server/tools/tools_util.h3
-rw-r--r--server/util/backup_file.c122
-rw-r--r--server/util/util.h3
26 files changed, 1184 insertions, 335 deletions
diff --git a/server/Makefile.am b/server/Makefile.am
index e1f7f3bc..e7885b37 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -159,6 +159,7 @@ SSSD_UTIL_OBJ = \
util/server.c \
util/signal.c \
util/usertools.c \
+ util/backup_file.c \
$(SSSD_DEBUG_OBJ)
SSSD_RESPONDER_OBJ = \
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index 72e5eeb4..7d89f75f 100644
--- a/server/confdb/confdb.c
+++ b/server/confdb/confdb.c
@@ -673,10 +673,10 @@ int confdb_init(TALLOC_CTX *mem_ctx,
return EOK;
}
-int confdb_get_domain(struct confdb_ctx *cdb,
- TALLOC_CTX *mem_ctx,
- const char *name,
- struct sss_domain_info **_domain)
+static int confdb_get_domain_internal(struct confdb_ctx *cdb,
+ TALLOC_CTX *mem_ctx,
+ const char *name,
+ struct sss_domain_info **_domain)
{
struct sss_domain_info *domain;
struct ldb_result *res;
@@ -803,16 +803,19 @@ done:
}
int confdb_get_domains(struct confdb_ctx *cdb,
- TALLOC_CTX *mem_ctx,
struct sss_domain_info **domains)
{
TALLOC_CTX *tmp_ctx;
struct sss_domain_info *domain, *prevdom = NULL;
- struct sss_domain_info *first = NULL;
char **domlist;
int ret, i;
- tmp_ctx = talloc_new(mem_ctx);
+ if (cdb->doms) {
+ *domains = cdb->doms;
+ return EOK;
+ }
+
+ tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
ret = confdb_get_string_as_list(cdb, tmp_ctx,
@@ -827,7 +830,7 @@ int confdb_get_domains(struct confdb_ctx *cdb,
}
for (i = 0; domlist[i]; i++) {
- ret = confdb_get_domain(cdb, mem_ctx, domlist[i], &domain);
+ ret = confdb_get_domain_internal(cdb, cdb, domlist[i], &domain);
if (ret) {
DEBUG(0, ("Error (%d [%s]) retrieving domain [%s], skipping!\n",
ret, strerror(ret), domlist[i]));
@@ -835,23 +838,46 @@ int confdb_get_domains(struct confdb_ctx *cdb,
continue;
}
- if (first == NULL) {
- first = domain;
- prevdom = first;
+ if (cdb->doms == NULL) {
+ cdb->doms = domain;
+ prevdom = cdb->doms;
} else {
prevdom->next = domain;
prevdom = domain;
}
}
- if (first == NULL) {
+ if (cdb->doms == NULL) {
DEBUG(0, ("No domains configured, fatal error!\n"));
ret = ENOENT;
}
- *domains = first;
+ *domains = cdb->doms;
+ ret = EOK;
done:
talloc_free(tmp_ctx);
return ret;
}
+
+int confdb_get_domain(struct confdb_ctx *cdb,
+ const char *name,
+ struct sss_domain_info **_domain)
+{
+ struct sss_domain_info *dom, *doms;
+ int ret;
+
+ ret = confdb_get_domains(cdb, &doms);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ for (dom = doms; dom; dom = dom->next) {
+ if (strcasecmp(dom->name, name) == 0) {
+ *_domain = dom;
+ return EOK;
+ }
+ }
+
+ return ENOENT;
+}
diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index f5650887..d325ac8f 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -91,12 +91,10 @@ int confdb_init(TALLOC_CTX *mem_ctx,
char *confdb_location);
int confdb_get_domain(struct confdb_ctx *cdb,
- TALLOC_CTX *mem_ctx,
const char *name,
struct sss_domain_info **domain);
int confdb_get_domains(struct confdb_ctx *cdb,
- TALLOC_CTX *mem_ctx,
struct sss_domain_info **domains);
#endif
diff --git a/server/confdb/confdb_private.h b/server/confdb/confdb_private.h
index 41fcd269..1bab99ca 100644
--- a/server/confdb/confdb_private.h
+++ b/server/confdb/confdb_private.h
@@ -25,6 +25,8 @@
struct confdb_ctx {
struct tevent_context *pev;
struct ldb_context *ldb;
+
+ struct sss_domain_info *doms;
};
int parse_section(TALLOC_CTX *mem_ctx, const char *section,
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
index 90482b52..d4f25797 100644
--- a/server/db/sysdb.c
+++ b/server/db/sysdb.c
@@ -3,7 +3,7 @@
System Database
- Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
+ Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -565,145 +565,26 @@ void sysdb_operation_done(struct sysdb_handle *handle)
/* =Initialization======================================================== */
-static int sysdb_read_var(TALLOC_CTX *mem_ctx,
- struct confdb_ctx *cdb,
- const char *name,
- const char *def_value,
- char **target)
+static int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *base_path, char **_ldb_file)
{
- int ret;
- char **values;
-
- ret = confdb_get_param(cdb, mem_ctx,
- SYSDB_CONF_SECTION,
- name, &values);
- if (ret != EOK)
- return ret;
-
- if (values[0])
- *target = values[0];
- else
- *target = talloc_strdup(mem_ctx, def_value);
+ char *ldb_file;
- return EOK;
-}
-
-static int sysdb_get_db_path(TALLOC_CTX *mem_ctx,
- struct confdb_ctx *cdb,
- char **db_path)
-{
- TALLOC_CTX *tmp_ctx;
- char *default_ldb_path;
- char *path;
- int ret;
-
- tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx)
- return ENOMEM;
-
- default_ldb_path = talloc_asprintf(tmp_ctx, "%s/%s", DB_PATH, SYSDB_FILE);
- if (default_ldb_path == NULL) {
- ret = ENOMEM;
- goto done;
+ /* special case for the local domain */
+ if (strcasecmp(domain->provider, "local") == 0) {
+ ldb_file = talloc_asprintf(mem_ctx, "%s/"LOCAL_SYSDB_FILE,
+ base_path);
+ } else {
+ ldb_file = talloc_asprintf(mem_ctx, "%s/"CACHE_SYSDB_FILE,
+ base_path, domain->name);
}
-
- sysdb_read_var(tmp_ctx, cdb, "ldbFile",
- default_ldb_path, &path);
-
- *db_path = talloc_steal(mem_ctx, path);
- ret = EOK;
-
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver);
-
-static int sysdb_check_init(struct sysdb_ctx *ctx)
-{
- TALLOC_CTX *tmp_ctx;
- const char *base_ldif;
- struct ldb_ldif *ldif;
- struct ldb_message_element *el;
- struct ldb_result *res;
- struct ldb_dn *verdn;
- const char *version = NULL;
- int ret;
-
- tmp_ctx = talloc_new(ctx);
- if (!tmp_ctx)
+ if (!ldb_file) {
return ENOMEM;
-
- verdn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");
- if (!verdn) {
- ret = EIO;
- goto done;
- }
-
- ret = ldb_search(ctx->ldb, tmp_ctx, &res,
- verdn, LDB_SCOPE_BASE,
- NULL, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
- if (res->count > 1) {
- ret = EIO;
- goto done;
- }
-
- if (res->count == 1) {
- el = ldb_msg_find_element(res->msgs[0], "version");
- if (el) {
- if (el->num_values != 1) {
- ret = EINVAL;
- goto done;
- }
- version = talloc_strndup(tmp_ctx,
- (char *)(el->values[0].data),
- el->values[0].length);
- if (!version) {
- ret = ENOMEM;
- goto done;
- }
-
- if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
- /* convert database */
- ret = sysdb_upgrade_01(ctx, &version);
- if (ret != EOK) goto done;
- }
-
- if (strcmp(version, SYSDB_VERSION) == 0) {
- /* all fine, return */
- ret = EOK;
- goto done;
- }
- }
-
- DEBUG(0,("Unknown DB version [%s], expected [%s], aborting!\n",
- version?version:"not found", SYSDB_VERSION));
- ret = EINVAL;
- goto done;
- }
-
- /* cn=sysdb does not exists, means db is empty, populate */
- base_ldif = SYSDB_BASE_LDIF;
- while ((ldif = ldb_ldif_read_string(ctx->ldb, &base_ldif))) {
- ret = ldb_add(ctx->ldb, ldif->msg);
- if (ret != LDB_SUCCESS) {
- DEBUG(0, ("Failed to inizialiaze DB (%d,[%s]), aborting!\n",
- ret, ldb_errstring(ctx->ldb)));
- ret = EIO;
- goto done;
- }
- ldb_ldif_read_free(ctx->ldb, ldif);
}
- ret = EOK;
-done:
- talloc_free(tmp_ctx);
- return ret;
+ *_ldb_file = ldb_file;
+ return EOK;
}
/* serach all groups that have a memberUid attribute.
@@ -837,7 +718,7 @@ static int sysdb_upgrade_01(struct sysdb_ctx *ctx, const char **ver)
ret = ENOMEM;
goto done;
}
- ret = ldb_msg_add_string(msg, "version", "0.2");
+ ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_2);
if (ret != LDB_SUCCESS) {
ret = ENOMEM;
goto done;
@@ -866,62 +747,654 @@ done:
return ret;
}
-int sysdb_init(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct confdb_ctx *cdb,
- const char *alt_db_path,
- struct sysdb_ctx **_ctx)
+static int sysdb_upgrade_02(struct confdb_ctx *cdb,
+ struct tevent_context *ev,
+ struct sysdb_ctx *local,
+ struct sysdb_ctx_list *list)
{
+ TALLOC_CTX *tmp_ctx;
struct sysdb_ctx *ctx;
- int ret;
-
- if (!ev) return EINVAL;
+ struct ldb_message_element *el;
+ struct ldb_message *msg;
+ struct ldb_result *res;
+ struct ldb_dn *basedn;
+ const char *version;
+ bool loc_trans = false;
+ bool ctx_trans = false;
+ int ret, i, j;
- ctx = talloc_zero(mem_ctx, struct sysdb_ctx);
- if (!ctx) {
+ tmp_ctx = talloc_new(list);
+ if (!tmp_ctx) {
return ENOMEM;
}
- ctx->ev = ev;
- if (!alt_db_path) {
- ret = sysdb_get_db_path(ctx, cdb, &ctx->ldb_file);
- if (ret != EOK) {
- return ret;
+ /* first check local has the expected version for an upgrade */
+
+ basedn = ldb_dn_new(tmp_ctx, local->ldb, "cn=sysdb");
+ if (!basedn) {
+ ret = EIO;
+ goto done;
+ }
+
+ ret = ldb_search(local->ldb, tmp_ctx, &res,
+ basedn, LDB_SCOPE_BASE,
+ NULL, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+ if (res->count != 1) {
+ ret = EIO;
+ goto done;
+ }
+
+ el = ldb_msg_find_element(res->msgs[0], "version");
+ if (el) {
+ if (el->num_values != 1) {
+ ret = EINVAL;
+ goto done;
+ }
+ version = talloc_strndup(tmp_ctx,
+ (char *)(el->values[0].data),
+ el->values[0].length);
+ if (!version) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (strcmp(version, SYSDB_VERSION_0_2) != 0) {
+ DEBUG(0,("Wrong DB version [%s],"
+ " expected [%s] for this upgrade!\n",
+ version, SYSDB_VERSION));
+ ret = EINVAL;
+ goto done;
+ }
+ }
+ talloc_zfree(res);
+
+ DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3));
+
+ /* ldb uses posix locks,
+ * posix is stupid and kills all locks when you close *any* file
+ * descriptor associated to the same file.
+ * Therefore we must close and reopen the ldb file here */
+
+ /* == Backup and reopen ldb == */
+
+ /* close */
+ talloc_zfree(local->ldb);
+
+ /* backup*/
+ ret = backup_file(local->ldb_file, 0);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ /* reopen */
+ local->ldb = ldb_init(local, ev);
+ if (!local->ldb) {
+ return EIO;
+ }
+
+ ret = ldb_set_debug(local->ldb, ldb_debug_messages, NULL);
+ if (ret != LDB_SUCCESS) {
+ return EIO;
+ }
+
+ ret = ldb_connect(local->ldb, local->ldb_file, 0, NULL);
+ if (ret != LDB_SUCCESS) {
+ return EIO;
+ }
+
+ /* open a transaction */
+ ret = ldb_transaction_start(local->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
+ return EIO;
+ }
+ loc_trans = true;
+
+ /* == Upgrade contents == */
+
+ for (i = 0; i < list->num_dbs; i++) {
+ struct ldb_dn *domain_dn;
+ struct ldb_dn *users_dn;
+ struct ldb_dn *groups_dn;
+
+ ctx = list->dbs[i];
+
+ /* skip local */
+ if (list->dbs[i] == local) continue;
+
+ ret = ldb_transaction_start(ctx->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
+ ret = EIO;
+ goto done;
+ }
+ ctx_trans = true;
+
+ /* search all entries for this domain in local,
+ * copy them all in the new database,
+ * then remove them from local */
+
+ domain_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
+ SYSDB_DOM_BASE, ctx->domain->name);
+ if (!domain_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_search(local->ldb, tmp_ctx, &res,
+ domain_dn, LDB_SCOPE_SUBTREE,
+ NULL, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+
+ users_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
+ SYSDB_TMPL_USER_BASE, ctx->domain->name);
+ if (!users_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+ groups_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
+ SYSDB_TMPL_GROUP_BASE, ctx->domain->name);
+ if (!groups_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (j = 0; j < res->count; j++) {
+
+ msg = res->msgs[j];
+
+ /* skip pre-created congtainers */
+ if ((ldb_dn_compare(msg->dn, domain_dn) == 0) ||
+ (ldb_dn_compare(msg->dn, users_dn) == 0) ||
+ (ldb_dn_compare(msg->dn, groups_dn) == 0)) {
+ continue;
+ }
+
+ ret = ldb_add(ctx->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("WARNING: Could not add entry %s,"
+ " to new ldb file! (%d [%s])\n",
+ ldb_dn_get_linearized(msg->dn),
+ ret, ldb_errstring(ctx->ldb)));
+ }
+
+ ret = ldb_delete(local->ldb, msg->dn);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("WARNING: Could not remove entry %s,"
+ " from old ldb file! (%d [%s])\n",
+ ldb_dn_get_linearized(msg->dn),
+ ret, ldb_errstring(local->ldb)));
+ }
+ }
+
+ /* now remove the basic containers from local */
+ /* these were optional so debug at level 9 in case
+ * of failure just for tracing */
+ ret = ldb_delete(local->ldb, groups_dn);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(9, ("WARNING: Could not remove entry %s,"
+ " from old ldb file! (%d [%s])\n",
+ ldb_dn_get_linearized(msg->dn),
+ ret, ldb_errstring(local->ldb)));
+ }
+ ret = ldb_delete(local->ldb, users_dn);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(9, ("WARNING: Could not remove entry %s,"
+ " from old ldb file! (%d [%s])\n",
+ ldb_dn_get_linearized(msg->dn),
+ ret, ldb_errstring(local->ldb)));
+ }
+ ret = ldb_delete(local->ldb, domain_dn);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(9, ("WARNING: Could not remove entry %s,"
+ " from old ldb file! (%d [%s])\n",
+ ldb_dn_get_linearized(msg->dn),
+ ret, ldb_errstring(local->ldb)));
+ }
+
+ ret = ldb_transaction_commit(ctx->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
+ ret = EIO;
+ goto done;
+ }
+ ctx_trans = false;
+
+ talloc_zfree(domain_dn);
+ talloc_zfree(groups_dn);
+ talloc_zfree(users_dn);
+ talloc_zfree(res);
+ }
+
+ /* conversion done, upgrade version number */
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = ldb_dn_new(tmp_ctx, local->ldb, "cn=sysdb");
+ if (!msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3);
+ if (ret != LDB_SUCCESS) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ldb_modify(local->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ ret = ldb_transaction_commit(local->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
+ ret = EIO;
+ goto done;
+ }
+ loc_trans = false;
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ if (ctx_trans) {
+ ret = ldb_transaction_cancel(ctx->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
+ }
+ }
+ if (loc_trans) {
+ ret = ldb_transaction_cancel(local->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
+ }
}
- } else {
- ctx->ldb_file = talloc_strdup(ctx, alt_db_path);
}
- if (ctx->ldb_file == NULL) {
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+
+static int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *domain,
+ const char *db_path,
+ bool allow_upgrade,
+ struct sysdb_ctx **_ctx,
+ bool *need_02_upgrade)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct sysdb_ctx *ctx;
+ const char *base_ldif;
+ struct ldb_ldif *ldif;
+ struct ldb_message *msg;
+ struct ldb_message_element *el;
+ struct ldb_result *res;
+ struct ldb_dn *verdn;
+ const char *version = NULL;
+ int ret;
+
+ ctx = talloc_zero(mem_ctx, struct sysdb_ctx);
+ if (!ctx) {
return ENOMEM;
}
+ ctx->ev = ev;
+ ctx->domain = domain;
- DEBUG(3, ("DB Path is: %s\n", ctx->ldb_file));
+ ret = sysdb_get_db_file(ctx, domain, db_path, &ctx->ldb_file);
+ if (ret != EOK) {
+ return ret;
+ }
+ DEBUG(5, ("DB File for %s: %s\n", domain->name, ctx->ldb_file));
ctx->ldb = ldb_init(ctx, ev);
if (!ctx->ldb) {
- talloc_free(ctx);
return EIO;
}
ret = ldb_set_debug(ctx->ldb, ldb_debug_messages, NULL);
if (ret != LDB_SUCCESS) {
- talloc_free(ctx);
return EIO;
}
ret = ldb_connect(ctx->ldb, ctx->ldb_file, 0, NULL);
if (ret != LDB_SUCCESS) {
- talloc_free(ctx);
return EIO;
}
- ret = sysdb_check_init(ctx);
+ tmp_ctx = talloc_new(ctx);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ verdn = ldb_dn_new(tmp_ctx, ctx->ldb, "cn=sysdb");
+ if (!verdn) {
+ ret = EIO;
+ goto done;
+ }
+
+ ret = ldb_search(ctx->ldb, tmp_ctx, &res,
+ verdn, LDB_SCOPE_BASE,
+ NULL, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+ if (res->count > 1) {
+ ret = EIO;
+ goto done;
+ }
+
+ if (res->count == 1) {
+ el = ldb_msg_find_element(res->msgs[0], "version");
+ if (el) {
+ if (el->num_values != 1) {
+ ret = EINVAL;
+ goto done;
+ }
+ version = talloc_strndup(tmp_ctx,
+ (char *)(el->values[0].data),
+ el->values[0].length);
+ if (!version) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ if (strcmp(version, SYSDB_VERSION) == 0) {
+ /* all fine, return */
+ ret = EOK;
+ goto done;
+ }
+
+ if (!allow_upgrade) {
+ DEBUG(0, ("Wrong DB version (got %s expected %s)\n",
+ version, SYSDB_VERSION));
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
+ /* convert database */
+ ret = sysdb_upgrade_01(ctx, &version);
+ if (ret != EOK) goto done;
+ }
+
+ if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
+ /* if this is not local we have a big problem */
+ if (strcasecmp(domain->provider, "local") != 0) {
+ DEBUG(0, ("Fatal: providers other than 'local'"
+ " shouldn't present v0.2, db corrupted?\n"));
+ ret = EFAULT;
+ goto done;
+ }
+
+ /* need to convert database to split files */
+ /* this need to be done later when all domains are set up */
+ if (need_02_upgrade) {
+ *need_02_upgrade = true;
+ } else {
+ DEBUG(0, ("DB file seem to need an upgrade,"
+ " but upgrade flag is not provided,"
+ " db corrupted?\n"));
+ ret = EFAULT;
+ goto done;
+ }
+
+ ret = EOK;
+ goto done;
+ }
+
+ }
+
+ DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",
+ version?version:"not found", SYSDB_VERSION, domain->name));
+ ret = EINVAL;
+ goto done;
+ }
+
+ /* cn=sysdb does not exists, means db is empty, populate */
+
+ base_ldif = SYSDB_BASE_LDIF;
+ while ((ldif = ldb_ldif_read_string(ctx->ldb, &base_ldif))) {
+ ret = ldb_add(ctx->ldb, ldif->msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!",
+ ret, ldb_errstring(ctx->ldb), domain->name));
+ ret = EIO;
+ goto done;
+ }
+ ldb_ldif_read_free(ctx->ldb, ldif);
+ }
+
+ /* == create base domain object == */
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = ldb_dn_new_fmt(msg, ctx->ldb, SYSDB_DOM_BASE, domain->name);
+ if (!msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_fmt(msg, "cn", "%s", domain->name);
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+ /* do a synchronous add */
+ ret = ldb_add(ctx->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!",
+ ret, ldb_errstring(ctx->ldb), domain->name));
+ ret = EIO;
+ goto done;
+ }
+ talloc_free(msg);
+
+ /* == create Users tree == */
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = ldb_dn_new_fmt(msg, ctx->ldb,
+ SYSDB_TMPL_USER_BASE, domain->name);
+ if (!msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_fmt(msg, "cn", "Users");
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+ /* do a synchronous add */
+ ret = ldb_add(ctx->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!",
+ ret, ldb_errstring(ctx->ldb), domain->name));
+ ret = EIO;
+ goto done;
+ }
+ talloc_free(msg);
+
+ /* == create Groups tree == */
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = ldb_dn_new_fmt(msg, ctx->ldb,
+ SYSDB_TMPL_GROUP_BASE, domain->name);
+ if (!msg->dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = ldb_msg_add_fmt(msg, "cn", "Groups");
+ if (ret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+ /* do a synchronous add */
+ ret = ldb_add(ctx->ldb, msg);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!",
+ ret, ldb_errstring(ctx->ldb), domain->name));
+ ret = EIO;
+ goto done;
+ }
+ talloc_free(msg);
+
+ ret = EOK;
+
+done:
+ if (ret == EOK) {
+ *_ctx = ctx;
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+int sysdb_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct confdb_ctx *cdb,
+ const char *alt_db_path,
+ bool allow_upgrade,
+ struct sysdb_ctx_list **_ctx_list)
+{
+ struct sysdb_ctx_list *ctx_list;
+ struct sss_domain_info *domains, *dom;
+ struct sysdb_ctx *ctx;
+ bool upgrade_02 = false;
+ int ret;
+
+ if (!ev) return EINVAL;
+
+ ctx_list = talloc_zero(mem_ctx, struct sysdb_ctx_list);
+ if (!ctx_list) {
+ return ENOMEM;
+ }
+
+ if (alt_db_path) {
+ ctx_list->db_path = talloc_strdup(ctx_list, alt_db_path);
+ } else {
+ ctx_list->db_path = talloc_strdup(ctx_list, DB_PATH);
+ }
+ if (!ctx_list->db_path) {
+ talloc_zfree(ctx_list);
+ return ENOMEM;
+ }
+
+ /* open a db for each backend */
+ ret = confdb_get_domains(cdb, &domains);
if (ret != EOK) {
- talloc_free(ctx);
+ talloc_zfree(ctx_list);
return ret;
}
- *_ctx = ctx;
+ for (dom = domains; dom; dom = dom->next) {
+
+ ctx_list->dbs = talloc_realloc(ctx_list, ctx_list->dbs,
+ struct sysdb_ctx *,
+ ctx_list->num_dbs + 1);
+ if (!ctx_list->dbs) {
+ talloc_zfree(ctx_list);
+ return ENOMEM;
+ }
+
+ ret = sysdb_domain_init_internal(ctx_list, ev, dom,
+ ctx_list->db_path,
+ allow_upgrade,
+ &ctx, &upgrade_02);
+ if (ret != EOK) {
+ talloc_zfree(ctx_list);
+ return ret;
+ }
+
+ ctx_list->dbs[ctx_list->num_dbs] = ctx;
+ ctx_list->num_dbs++;
+ }
+ if (ctx_list->num_dbs == 0) {
+ /* what? .. */
+ talloc_zfree(ctx_list);
+ return ENOENT;
+ }
+
+ if (upgrade_02) {
+ ret = confdb_get_domain(cdb, "local", &dom);
+ if (ret != EOK) {
+ talloc_zfree(ctx_list);
+ return ret;
+ }
+ ret = sysdb_get_ctx_from_list(ctx_list, dom, &ctx);
+ if (ret != EOK) {
+ talloc_zfree(ctx_list);
+ return ret;
+ }
+
+ ret = sysdb_upgrade_02(cdb, ev, ctx, ctx_list);
+ if (ret != EOK) {
+ DEBUG(0, ("FATAL: Upgrade form db version %d failed!\n",
+ SYSDB_VERSION_0_2));
+ DEBUG(0, ("You can find a backup of the database here: %s\n",
+ backup_file));
+ talloc_zfree(ctx_list);
+ return ret;
+ }
+ }
+
+ *_ctx_list = ctx_list;
return EOK;
}
+
+int sysdb_domain_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *domain,
+ const char *db_path,
+ struct sysdb_ctx **_ctx)
+{
+ return sysdb_domain_init_internal(mem_ctx, ev, domain,
+ db_path, false, _ctx, NULL);
+}
+
+int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list,
+ struct sss_domain_info *domain,
+ struct sysdb_ctx **ctx)
+{
+ int i;
+
+ for (i = 0; i < ctx_list->num_dbs; i++) {
+ if (ctx_list->dbs[i]->domain == domain) {
+ *ctx = ctx_list->dbs[i];
+ return EOK;
+ }
+ if (strcasecmp(ctx_list->dbs[i]->domain->name, domain->name) == 0) {
+ *ctx = ctx_list->dbs[i];
+ return EOK;
+ }
+ }
+ /* definitely not found */
+ return ENOENT;
+}
diff --git a/server/db/sysdb.h b/server/db/sysdb.h
index 3d75f507..2d8b3eae 100644
--- a/server/db/sysdb.h
+++ b/server/db/sysdb.h
@@ -26,7 +26,8 @@
#include <tevent.h>
#define SYSDB_CONF_SECTION "config/sysdb"
-#define SYSDB_FILE "sssd.ldb"
+#define CACHE_SYSDB_FILE "cache_%s.ldb"
+#define LOCAL_SYSDB_FILE "sssd.ldb"
#define SYSDB_BASE "cn=sysdb"
#define SYSDB_DOM_BASE "cn=%s,cn=sysdb"
@@ -137,6 +138,7 @@
#define SYSDB_MOD_REP LDB_FLAG_MOD_REPLACE
struct confdb_ctx;
+struct sysdb_ctx_list;
struct sysdb_ctx;
struct sysdb_handle;
@@ -215,7 +217,19 @@ int sysdb_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct confdb_ctx *cdb,
const char *alt_db_path,
- struct sysdb_ctx **dbctx);
+ bool allow_upgrade,
+ struct sysdb_ctx_list **_ctx_list);
+/* used to initialize only one domain database.
+ * Do NOT use if sysdb_init has already been called */
+int sysdb_domain_init(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *domain,
+ const char *db_path,
+ struct sysdb_ctx **_ctx);
+
+int sysdb_get_ctx_from_list(struct sysdb_ctx_list *ctx_list,
+ struct sss_domain_info *domain,
+ struct sysdb_ctx **_ctx);
/* FIXME: REMOVE */
typedef void (*sysdb_callback_t)(void *, int, struct ldb_result *);
diff --git a/server/db/sysdb_private.h b/server/db/sysdb_private.h
index d8b66cd7..e380c827 100644
--- a/server/db/sysdb_private.h
+++ b/server/db/sysdb_private.h
@@ -23,7 +23,9 @@
#ifndef __INT_SYS_DB_H__
#define __INT_SYS_DB_H__
-#define SYSDB_VERSION "0.2"
+#define SYSDB_VERSION "0.3"
+#define SYSDB_VERSION_0_3 "0.3"
+#define SYSDB_VERSION_0_2 "0.2"
#define SYSDB_VERSION_0_1 "0.1"
#define SYSDB_BASE_LDIF \
@@ -50,20 +52,8 @@
"\n" \
"dn: cn=sysdb\n" \
"cn: sysdb\n" \
- "version: 0.2\n" \
+ "version: " SYSDB_VERSION "\n" \
"description: base object\n" \
- "\n" \
- "dn: cn=LOCAL,cn=sysdb\n" \
- "cn: local\n" \
- "description: Local system data\n" \
- "\n" \
- "dn: cn=Users,cn=LOCAL,cn=sysdb\n" \
- "cn: users\n" \
- "description: Local POSIX users\n" \
- "\n" \
- "dn: cn=Groups,cn=LOCAL,cn=sysdb\n" \
- "cn: groups\n" \
- "description: Local POSIX groups\n" \
"\n"
#include "db/sysdb.h"
@@ -80,12 +70,22 @@ struct sysdb_handle {
struct sysdb_ctx {
struct tevent_context *ev;
+
+ struct sss_domain_info *domain;
+
struct ldb_context *ldb;
char *ldb_file;
struct sysdb_handle *queue;
};
+struct sysdb_ctx_list {
+ struct sysdb_ctx **dbs;
+ size_t num_dbs;
+
+ char *db_path;
+};
+
/* An operation blocks the transaction queue as well, but does not
* start a transaction, normally useful only for search type calls.
* do *NOT* call within a transaction you'll deadlock sysdb.
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index 893de9b1..86b2364c 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -866,7 +866,7 @@ int get_monitor_config(struct mt_ctx *ctx)
if(!ctx->domain_ctx) {
return ENOMEM;
}
- ret = confdb_get_domains(ctx->cdb, ctx->domain_ctx, &ctx->domains);
+ ret = confdb_get_domains(ctx->cdb, &ctx->domains);
if (ret != EOK) {
DEBUG(0, ("No domains configured.\n"));
return ret;
@@ -1780,7 +1780,7 @@ int monitor_process_init(TALLOC_CTX *mem_ctx,
const char *config_file)
{
struct mt_ctx *ctx;
- struct sysdb_ctx *sysdb;
+ struct sysdb_ctx_list *db_list;
struct tevent_signal *tes;
int ret, i;
char *cdb_file;
@@ -1860,19 +1860,16 @@ int monitor_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
- /* Avoid a startup race condition between InfoPipe
- * and NSS. If the sysdb doesn't exist yet, both
- * will try to create it at the same time. So
- * we'll have the monitor create it before either of
- * those processes start.
+ /* Avoid a startup race condition between process.
+ * We need to handle DB upgrades or DB creation only
+ * in one process before all other start.
*/
- ret = sysdb_init(mem_ctx, ctx->ev, ctx->cdb,
- NULL, &sysdb);
+ ret = sysdb_init(mem_ctx, ctx->ev, ctx->cdb, NULL, true, &db_list);
if (ret != EOK) {
talloc_free(ctx);
return ret;
}
- talloc_free(sysdb);
+ talloc_free(db_list);
/* Initialize D-BUS Server
* The monitor will act as a D-BUS server for all
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index 8428954a..55fc2787 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -944,13 +944,13 @@ int be_process_init(TALLOC_CTX *mem_ctx,
return ENOMEM;
}
- ret = confdb_get_domain(cdb, ctx, be_domain, &ctx->domain);
+ ret = confdb_get_domain(cdb, be_domain, &ctx->domain);
if (ret != EOK) {
DEBUG(0, ("fatal error retrieving domain configuration\n"));
return ret;
}
- ret = sysdb_init(ctx, ev, cdb, NULL, &ctx->sysdb);
+ ret = sysdb_domain_init(ctx, ev, ctx->domain, DB_PATH, &ctx->sysdb);
if (ret != EOK) {
DEBUG(0, ("fatal error opening cache database\n"));
return ret;
diff --git a/server/responder/common/responder.h b/server/responder/common/responder.h
index 59a58a5c..ddf8b893 100644
--- a/server/responder/common/responder.h
+++ b/server/responder/common/responder.h
@@ -62,7 +62,6 @@ struct resp_ctx {
int lfd;
struct tevent_fd *priv_lfde;
int priv_lfd;
- struct sysdb_ctx *sysdb;
struct confdb_ctx *cdb;
const char *sock_name;
const char *priv_sock_name;
@@ -71,6 +70,7 @@ struct resp_ctx {
struct sbus_connection *dp_conn;
struct sss_domain_info *domains;
+ struct sysdb_ctx_list *db_list;
struct sss_cmd_table *sss_cmds;
const char *sss_pipe_name;
diff --git a/server/responder/common/responder_common.c b/server/responder/common/responder_common.c
index f1030c04..57c8678b 100644
--- a/server/responder/common/responder_common.c
+++ b/server/responder/common/responder_common.c
@@ -510,7 +510,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
rctx->priv_sock_name = sss_priv_pipe_name;
rctx->confdb_service_path = confdb_service_path;
- ret = confdb_get_domains(rctx->cdb, rctx, &rctx->domains);
+ ret = confdb_get_domains(rctx->cdb, &rctx->domains);
if (ret != EOK) {
DEBUG(0, ("fatal error setting up domain map\n"));
return ret;
@@ -534,7 +534,7 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
return EIO;
}
- ret = sysdb_init(rctx, ev, cdb, NULL, &rctx->sysdb);
+ ret = sysdb_init(rctx, ev, cdb, NULL, false, &rctx->db_list);
if (ret != EOK) {
DEBUG(0, ("fatal error initializing resp_ctx\n"));
return ret;
diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c
index abd20a1b..405dae81 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -271,6 +271,7 @@ static void nss_cmd_getpwnam_callback(void *ptr, int status,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
struct sss_domain_info *dom;
struct nss_ctx *nctx;
int timeout;
@@ -388,7 +389,13 @@ static void nss_cmd_getpwnam_callback(void *ptr, int status,
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getpwnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getpwnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getpwnam_callback, dctx);
if (ret != EOK) {
@@ -458,6 +465,7 @@ static void nss_cmd_getpwnam_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -479,7 +487,13 @@ static void nss_cmd_getpwnam_dp_callback(uint16_t err_maj, uint32_t err_min,
return;
}
- ret = sysdb_getpwnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getpwnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getpwnam_callback, dctx);
@@ -501,6 +515,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
const char *rawname;
char *domname;
@@ -602,7 +617,14 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getpwnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_getpwnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getpwnam_callback, dctx);
if (ret != EOK) {
@@ -644,6 +666,7 @@ static void nss_cmd_getpwuid_callback(void *ptr, int status,
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int timeout;
uint64_t lastUpdate;
@@ -748,7 +771,13 @@ static void nss_cmd_getpwuid_callback(void *ptr, int status,
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getpwuid(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getpwuid(cmdctx, sysdb,
dctx->domain, cmdctx->id,
nss_cmd_getpwuid_callback, dctx);
if (ret != EOK) {
@@ -818,6 +847,7 @@ static void nss_cmd_getpwuid_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -839,7 +869,13 @@ static void nss_cmd_getpwuid_dp_callback(uint16_t err_maj, uint32_t err_min,
return;
}
- ret = sysdb_getpwuid(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getpwuid(cmdctx, sysdb,
dctx->domain, cmdctx->id,
nss_cmd_getpwuid_callback, dctx);
@@ -860,6 +896,7 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
uint8_t *body;
size_t blen;
@@ -920,7 +957,14 @@ static int nss_cmd_getpwuid(struct cli_ctx *cctx)
DEBUG(4, ("Requesting info for [%lu@%s]\n",
cmdctx->id, dctx->domain->name));
- ret = sysdb_getpwuid(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_getpwuid(cmdctx, sysdb,
dctx->domain, cmdctx->id,
nss_cmd_getpwuid_callback, dctx);
if (ret != EOK) {
@@ -978,6 +1022,7 @@ static void nss_cmd_setpwent_callback(void *ptr, int status,
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct getent_ctx *pctx;
struct nss_ctx *nctx;
int timeout;
@@ -1040,7 +1085,13 @@ static void nss_cmd_setpwent_callback(void *ptr, int status,
timeout, dom->name, SSS_DP_USER,
NULL, 0);
} else {
- ret = sysdb_enumpwent(dctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_enumpwent(dctx, sysdb,
dctx->domain, NULL,
nss_cmd_setpwent_callback, dctx);
}
@@ -1085,6 +1136,7 @@ static void nss_cmd_setpw_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -1094,7 +1146,13 @@ static void nss_cmd_setpw_dp_callback(uint16_t err_maj, uint32_t err_min,
(unsigned int)err_maj, (unsigned int)err_min, err_msg));
}
- ret = sysdb_enumpwent(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_enumpwent(cmdctx, sysdb,
dctx->domain, NULL,
nss_cmd_setpwent_callback, dctx);
if (ret != EOK) {
@@ -1111,6 +1169,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 sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct nss_ctx *nctx;
@@ -1173,7 +1232,14 @@ static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, bool immediate)
timeout, dom->name, SSS_DP_USER,
NULL, 0);
} else {
- ret = sysdb_enumpwent(dctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_enumpwent(dctx, sysdb,
dctx->domain, NULL,
nss_cmd_setpwent_callback, dctx);
}
@@ -1634,6 +1700,7 @@ static void nss_cmd_getgrnam_callback(void *ptr, int status,
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int timeout;
uint64_t lastUpdate;
@@ -1740,7 +1807,13 @@ static void nss_cmd_getgrnam_callback(void *ptr, int status,
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getgrnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getgrnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getgrnam_callback, dctx);
if (ret != EOK) {
@@ -1806,6 +1879,7 @@ static void nss_cmd_getgrnam_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -1827,7 +1901,13 @@ static void nss_cmd_getgrnam_dp_callback(uint16_t err_maj, uint32_t err_min,
return;
}
- ret = sysdb_getgrnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getgrnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getgrnam_callback, dctx);
@@ -1849,6 +1929,7 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
const char *rawname;
char *domname;
@@ -1950,7 +2031,14 @@ static int nss_cmd_getgrnam(struct cli_ctx *cctx)
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getgrnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_getgrnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getgrnam_callback, dctx);
if (ret != EOK) {
@@ -1992,6 +2080,7 @@ static void nss_cmd_getgrgid_callback(void *ptr, int status,
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int timeout;
uint64_t lastUpdate;
@@ -2087,7 +2176,13 @@ static void nss_cmd_getgrgid_callback(void *ptr, int status,
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getgrgid(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getgrgid(cmdctx, sysdb,
dctx->domain, cmdctx->id,
nss_cmd_getgrgid_callback, dctx);
if (ret != EOK) {
@@ -2151,6 +2246,7 @@ static void nss_cmd_getgrgid_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -2172,7 +2268,13 @@ static void nss_cmd_getgrgid_dp_callback(uint16_t err_maj, uint32_t err_min,
return;
}
- ret = sysdb_getgrgid(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getgrgid(cmdctx, sysdb,
dctx->domain, cmdctx->id,
nss_cmd_getgrgid_callback, dctx);
@@ -2193,6 +2295,7 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
uint8_t *body;
size_t blen;
@@ -2253,7 +2356,14 @@ static int nss_cmd_getgrgid(struct cli_ctx *cctx)
DEBUG(4, ("Requesting info for [%lu@%s]\n",
cmdctx->id, dctx->domain->name));
- ret = sysdb_getgrgid(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_getgrgid(cmdctx, sysdb,
dctx->domain, cmdctx->id,
nss_cmd_getgrgid_callback, dctx);
if (ret != EOK) {
@@ -2311,6 +2421,7 @@ static void nss_cmd_setgrent_callback(void *ptr, int status,
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct getent_ctx *gctx;
struct nss_ctx *nctx;
int timeout;
@@ -2369,7 +2480,13 @@ static void nss_cmd_setgrent_callback(void *ptr, int status,
timeout, dom->name, SSS_DP_GROUP,
NULL, 0);
} else {
- ret = sysdb_enumgrent(dctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_enumgrent(dctx, sysdb,
dctx->domain,
nss_cmd_setgrent_callback, dctx);
}
@@ -2414,6 +2531,7 @@ static void nss_cmd_setgr_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -2423,7 +2541,13 @@ static void nss_cmd_setgr_dp_callback(uint16_t err_maj, uint32_t err_min,
(unsigned int)err_maj, (unsigned int)err_min, err_msg));
}
- ret = sysdb_enumgrent(dctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_enumgrent(dctx, sysdb,
dctx->domain,
nss_cmd_setgrent_callback, dctx);
if (ret != EOK) {
@@ -2440,6 +2564,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 sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct nss_ctx *nctx;
@@ -2502,7 +2627,14 @@ static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, bool immediate)
timeout, dom->name, SSS_DP_GROUP,
NULL, 0);
} else {
- ret = sysdb_enumgrent(dctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_enumgrent(dctx, sysdb,
dctx->domain,
nss_cmd_setgrent_callback, dctx);
}
@@ -2728,6 +2860,7 @@ static void nss_cmd_getinitgr_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -2737,7 +2870,13 @@ static void nss_cmd_getinitgr_callback(uint16_t err_maj, uint32_t err_min,
(unsigned int)err_maj, (unsigned int)err_min, err_msg));
}
- ret = sysdb_initgroups(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_initgroups(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_initgr_callback, cmdctx);
if (ret != EOK) {
@@ -2760,6 +2899,7 @@ static void nss_cmd_getinitnam_dp_callback(uint16_t err_maj, uint32_t err_min,
struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx);
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
+ struct sysdb_ctx *sysdb;
int ret;
if (err_maj) {
@@ -2781,7 +2921,13 @@ static void nss_cmd_getinitnam_dp_callback(uint16_t err_maj, uint32_t err_min,
return;
}
- ret = sysdb_getpwnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getpwnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getinit_callback, dctx);
@@ -2804,6 +2950,7 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
struct nss_cmd_ctx *cmdctx = dctx->cmdctx;
struct cli_ctx *cctx = cmdctx->cctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
int timeout;
uint64_t lastUpdate;
@@ -2920,7 +3067,13 @@ static void nss_cmd_getinit_callback(void *ptr, int status,
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getpwnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ ret = sysdb_getpwnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getinit_callback, dctx);
if (ret != EOK) {
@@ -2991,6 +3144,7 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
struct nss_cmd_ctx *cmdctx;
struct nss_dom_ctx *dctx;
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct nss_ctx *nctx;
const char *rawname;
char *domname;
@@ -3092,7 +3246,14 @@ static int nss_cmd_initgroups(struct cli_ctx *cctx)
DEBUG(4, ("Requesting info for [%s@%s]\n",
cmdctx->name, dctx->domain->name));
- ret = sysdb_getpwnam(cmdctx, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ dctx->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ ret = EFAULT;
+ goto done;
+ }
+ ret = sysdb_getpwnam(cmdctx, sysdb,
dctx->domain, cmdctx->name,
nss_cmd_getinit_callback, dctx);
if (ret != EOK) {
diff --git a/server/responder/pam/pam_LOCAL_domain.c b/server/responder/pam/pam_LOCAL_domain.c
index 5d76891f..41d64b3e 100644
--- a/server/responder/pam/pam_LOCAL_domain.c
+++ b/server/responder/pam/pam_LOCAL_domain.c
@@ -459,7 +459,13 @@ int LOCAL_pam_handler(struct pam_auth_req *preq)
return ENOMEM;
}
- lreq->dbctx = preq->cctx->rctx->sysdb;
+ ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list,
+ preq->domain, &lreq->dbctx);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ talloc_free(lreq);
+ return ret;
+ }
lreq->ev = preq->cctx->ev;
lreq->preq = preq;
diff --git a/server/responder/pam/pamsrv_cache.c b/server/responder/pam/pamsrv_cache.c
index 7cfd97b1..9c5c209f 100644
--- a/server/responder/pam/pamsrv_cache.c
+++ b/server/responder/pam/pamsrv_cache.c
@@ -132,6 +132,7 @@ done:
int pam_cache_auth(struct pam_auth_req *preq)
{
+ struct sysdb_ctx *sysdb;
int ret;
static const char *attrs[] = {SYSDB_NAME,
@@ -144,7 +145,13 @@ int pam_cache_auth(struct pam_auth_req *preq)
"lastFailedLogin",
NULL};
- ret = sysdb_get_user_attr(preq, preq->cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list,
+ preq->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ return ret;
+ }
+ ret = sysdb_get_user_attr(preq, sysdb,
preq->domain, preq->pd->user, attrs,
pam_cache_auth_callback, preq);
diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c
index 12625509..1204e325 100644
--- a/server/responder/pam/pamsrv_cmd.c
+++ b/server/responder/pam/pamsrv_cmd.c
@@ -382,6 +382,7 @@ static void pam_dom_forwarder(struct pam_auth_req *preq);
static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
{
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
struct pam_auth_req *preq;
struct pam_data *pd;
uint8_t *body;
@@ -486,7 +487,13 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
else {
preq->check_provider = NEED_CHECK_PROVIDER(preq->domain->provider);
- ret = sysdb_getpwnam(preq, cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(cctx->rctx->db_list,
+ preq->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ goto done;
+ }
+ ret = sysdb_getpwnam(preq, sysdb,
preq->domain, preq->pd->user,
pam_check_user_callback, preq);
}
@@ -509,6 +516,7 @@ static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min,
{
struct pam_auth_req *preq = talloc_get_type(ptr, struct pam_auth_req);
struct ldb_result *res = NULL;
+ struct sysdb_ctx *sysdb;
int ret;
if ((err_maj != DP_ERR_OK) && (err_maj != DP_ERR_OFFLINE)) {
@@ -531,7 +539,13 @@ static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min,
return;
}
- ret = sysdb_getpwnam(preq, preq->cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list,
+ preq->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ goto done;
+ }
+ ret = sysdb_getpwnam(preq, sysdb,
preq->domain, preq->pd->user,
pam_check_user_callback, preq);
@@ -547,6 +561,7 @@ static void pam_check_user_callback(void *ptr, int status,
{
struct pam_auth_req *preq = talloc_get_type(ptr, struct pam_auth_req);
struct sss_domain_info *dom;
+ struct sysdb_ctx *sysdb;
uint64_t lastUpdate;
bool call_provider = false;
time_t timeout;
@@ -673,7 +688,15 @@ static void pam_check_user_callback(void *ptr, int status,
else {
preq->check_provider = NEED_CHECK_PROVIDER(preq->domain->provider);
- ret = sysdb_getpwnam(preq, preq->cctx->rctx->sysdb,
+ ret = sysdb_get_ctx_from_list(preq->cctx->rctx->db_list,
+ preq->domain, &sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n"));
+ preq->pd->pam_status = PAM_SYSTEM_ERR;
+ pam_reply(preq);
+ return;
+ }
+ ret = sysdb_getpwnam(preq, sysdb,
preq->domain, preq->pd->user,
pam_check_user_callback, preq);
}
diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c
index 72514e3b..38bfcb10 100644
--- a/server/tests/sysdb-tests.c
+++ b/server/tests/sysdb-tests.c
@@ -24,15 +24,19 @@
#include <talloc.h>
#include <tevent.h>
#include <popt.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include "util/util.h"
#include "confdb/confdb_setup.h"
#include "db/sysdb_private.h"
+#define TESTS_PATH "tests_sysdb"
+
struct sysdb_test_ctx {
struct sysdb_ctx *sysdb;
struct confdb_ctx *confdb;
struct tevent_context *ev;
- struct sss_domain_info *domains;
+ struct sss_domain_info *domain;
};
static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
@@ -44,6 +48,14 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
const char *val[2];
val[1] = NULL;
+ /* Create tests directory if it doesn't exist */
+ /* (relative to current dir) */
+ ret = mkdir(TESTS_PATH, 0775);
+ if (ret == -1 && errno != EEXIST) {
+ fail("Could not create %s directory", TESTS_PATH);
+ return EFAULT;
+ }
+
test_ctx = talloc_zero(NULL, struct sysdb_test_ctx);
if (test_ctx == NULL) {
fail("Could not allocate memory for test context");
@@ -60,7 +72,7 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
return EIO;
}
- conf_db = talloc_asprintf(test_ctx, "tests_conf.ldb");
+ conf_db = talloc_asprintf(test_ctx, "%s/tests_conf.ldb", TESTS_PATH);
if (conf_db == NULL) {
fail("Out of memory, aborting!");
talloc_free(test_ctx);
@@ -77,58 +89,52 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
}
val[0] = "LOCAL";
- ret = confdb_add_param(test_ctx->confdb, true, "config/domains", "domains", val);
+ ret = confdb_add_param(test_ctx->confdb, true,
+ "config/domains", "domains", val);
if (ret != EOK) {
fail("Could not initialize domains placeholder");
talloc_free(test_ctx);
return ret;
}
- val[0] = "foo";
- ret = confdb_add_param(test_ctx->confdb, true, "config/domains/LOCAL", "provider", val);
+ val[0] = "local";
+ ret = confdb_add_param(test_ctx->confdb, true,
+ "config/domains/LOCAL", "provider", val);
if (ret != EOK) {
- fail("Could not initialize domains placeholder");
+ fail("Could not initialize provider");
talloc_free(test_ctx);
return ret;
}
/*
val[0] = "TRUE";
- ret = confdb_add_param(test_ctx->confdb, true, "config/domains/LOCAL", "legacy", val);
+ ret = confdb_add_param(test_ctx->confdb, true,
+ "config/domains/LOCAL", "magicPrivateGroups", val);
if (ret != EOK) {
fail("Could not initialize LOCAL domain");
talloc_free(test_ctx);
return ret;
}
*/
-/*
val[0] = "TRUE";
- ret = confdb_add_param(test_ctx->confdb, true, "config/domains/LOCAL", "magicPrivateGroups", val);
- if (ret != EOK) {
- fail("Could not initialize LOCAL domain");
- talloc_free(test_ctx);
- return ret;
- }
-*/
- val[0] = "3";
- ret = confdb_add_param(test_ctx->confdb, true, "config/domains/LOCAL", "enumerate", val);
+ ret = confdb_add_param(test_ctx->confdb, true,
+ "config/domains/LOCAL", "enumerate", val);
if (ret != EOK) {
fail("Could not initialize LOCAL domain");
talloc_free(test_ctx);
return ret;
}
- ret = sysdb_init(test_ctx, test_ctx->ev, test_ctx->confdb, "tests.ldb",
- &test_ctx->sysdb);
+ ret = confdb_get_domain(test_ctx->confdb, "local", &test_ctx->domain);
if (ret != EOK) {
- fail("Could not initialize connection to the sysdb");
+ fail("Could not retrieve LOCAL domain");
talloc_free(test_ctx);
return ret;
}
- ret = confdb_get_domains(test_ctx->confdb, test_ctx,
- &test_ctx->domains);
+ ret = sysdb_domain_init(test_ctx, test_ctx->ev,
+ test_ctx->domain, TESTS_PATH, &test_ctx->sysdb);
if (ret != EOK) {
- fail("Could not initialize domains");
+ fail("Could not initialize connection to the sysdb (%d)", ret);
talloc_free(test_ctx);
return ret;
}
@@ -140,7 +146,6 @@ static int setup_sysdb_tests(struct sysdb_test_ctx **ctx)
struct test_data {
struct tevent_context *ev;
struct sysdb_handle *handle;
- struct sss_domain_info *domain;
struct sysdb_test_ctx *ctx;
const char *username;
@@ -156,25 +161,6 @@ struct test_data {
const char *attrval; /* testing sysdb_get_user_attr */
};
-static struct sss_domain_info *get_local_domain(struct sss_domain_info *domlist)
-{
- struct sss_domain_info *local = domlist;
-
- while (local) {
- if (strcmp(local->name, "LOCAL") == 0)
- break;
-
- local = local->next;
- }
-
- if (local == NULL) {
- fail("Could not set up the test (missing LOCAL domain)");
- return NULL;
- }
-
- return local;
-}
-
static int test_loop(struct test_data *data)
{
while (!data->finished)
@@ -236,7 +222,7 @@ static void test_add_user(struct tevent_req *subreq)
gecos = talloc_asprintf(data, "Test User %d", data->uid);
subreq = sysdb_add_user_send(data, data->ev, data->handle,
- data->domain, data->username,
+ data->ctx->domain, data->username,
data->uid, 0,
gecos, homedir, "/bin/bash",
NULL);
@@ -276,7 +262,7 @@ static void test_store_user(struct tevent_req *req)
gecos = talloc_asprintf(data, "Test User %d", data->uid);
subreq = sysdb_store_user_send(data, data->ev, data->handle,
- data->domain, data->username, "x",
+ data->ctx->domain, data->username, "x",
data->uid, 0,
gecos, homedir,
data->shell ? data->shell : "/bin/bash",
@@ -349,7 +335,7 @@ static void test_remove_user_by_uid(struct tevent_req *req)
subreq = sysdb_delete_user_by_uid_send(data,
data->ev, data->handle,
- data->domain, data->uid,
+ data->ctx->domain, data->uid,
true);
if (!subreq) return test_return(data, ENOMEM);
@@ -383,7 +369,7 @@ static void test_remove_nonexistent_group(struct tevent_req *req)
subreq = sysdb_delete_group_by_gid_send(data,
data->ev, data->handle,
- data->domain, data->uid,
+ data->ctx->domain, data->uid,
false);
if (!subreq) return test_return(data, ENOMEM);
@@ -417,7 +403,7 @@ static void test_remove_nonexistent_user(struct tevent_req *req)
subreq = sysdb_delete_user_by_uid_send(data,
data->ev, data->handle,
- data->domain, data->uid,
+ data->ctx->domain, data->uid,
false);
if (!subreq) return test_return(data, ENOMEM);
@@ -451,7 +437,7 @@ static void test_add_group(struct tevent_req *req)
}
subreq = sysdb_add_group_send(data, data->ev, data->handle,
- data->domain, data->groupname,
+ data->ctx->domain, data->groupname,
data->gid, NULL);
if (!subreq) {
test_return(data, ret);
@@ -484,7 +470,7 @@ static void test_store_group(struct tevent_req *req)
}
subreq = sysdb_store_group_send(data, data->ev, data->handle,
- data->domain, data->groupname,
+ data->ctx->domain, data->groupname,
data->gid, NULL, NULL);
if (!subreq) {
test_return(data, ret);
@@ -551,7 +537,7 @@ static void test_remove_group_by_gid(struct tevent_req *req)
}
subreq = sysdb_delete_group_by_gid_send(data, data->ev, data->handle,
- data->domain, data->gid,
+ data->ctx->domain, data->gid,
true);
if (!subreq) return test_return(data, ENOMEM);
@@ -723,7 +709,7 @@ static void test_set_user_attr(struct tevent_req *req)
}
subreq = sysdb_set_user_attr_send(data, data->ev, data->handle,
- data->domain, data->username,
+ data->ctx->domain, data->username,
data->attrs, SYSDB_MOD_REP);
if (!subreq) return test_return(data, ENOMEM);
@@ -787,7 +773,7 @@ static void test_add_group_member(struct tevent_req *req)
}
subreq = sysdb_add_group_member_send(data, data->ev,
- data->handle, data->domain,
+ data->handle, data->ctx->domain,
data->groupname, username);
if (!subreq) {
test_return(data, ENOMEM);
@@ -825,7 +811,7 @@ static void test_remove_group_member(struct tevent_req *req)
}
subreq = sysdb_remove_group_member_send(data, data->ev,
- data->handle, data->domain,
+ data->handle, data->ctx->domain,
data->groupname, username);
if (!subreq) {
test_return(data, ENOMEM);
@@ -863,7 +849,6 @@ START_TEST (test_sysdb_store_user)
data->uid = _i;
data->gid = _i;
data->username = talloc_asprintf(data, "testuser%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -901,7 +886,6 @@ START_TEST (test_sysdb_store_user_existing)
data->uid = _i;
data->gid = _i;
data->username = talloc_asprintf(data, "testuser%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
data->shell = talloc_asprintf(data, "/bin/ksh");
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
@@ -939,7 +923,6 @@ START_TEST (test_sysdb_store_group)
data->ev = test_ctx->ev;
data->gid = _i;
data->groupname = talloc_asprintf(data, "testgroup%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -1010,7 +993,6 @@ START_TEST (test_sysdb_remove_local_user_by_uid)
data->ctx = test_ctx;
data->ev = test_ctx->ev;
data->uid = _i;
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -1081,7 +1063,6 @@ START_TEST (test_sysdb_remove_local_group_by_gid)
data->ctx = test_ctx;
data->ev = test_ctx->ev;
data->gid = _i;
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -1119,7 +1100,6 @@ START_TEST (test_sysdb_add_user)
data->uid = _i;
data->gid = _i;
data->username = talloc_asprintf(data, "testuser%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
subreq = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!subreq) {
@@ -1157,7 +1137,6 @@ START_TEST (test_sysdb_add_group)
data->uid = _i;
data->gid = _i;
data->groupname = talloc_asprintf(data, "testgroup%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
subreq = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!subreq) {
@@ -1191,11 +1170,10 @@ START_TEST (test_sysdb_getpwnam)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
data->username = talloc_asprintf(data, "testuser%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_getpwnam(test_ctx,
test_ctx->sysdb,
- data->domain,
+ data->ctx->domain,
data->username,
test_getpwent,
data);
@@ -1231,11 +1209,10 @@ START_TEST (test_sysdb_getgrnam)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
data->groupname = talloc_asprintf(data, "testgroup%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_getgrnam(test_ctx,
test_ctx->sysdb,
- data->domain,
+ data->ctx->domain,
data->groupname,
test_getgrent,
data);
@@ -1279,11 +1256,10 @@ START_TEST (test_sysdb_getgrgid)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
data->gid = _i;
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_getgrgid(test_ctx,
test_ctx->sysdb,
- data->domain,
+ data->ctx->domain,
data->gid,
test_getgrgid,
data);
@@ -1327,11 +1303,10 @@ START_TEST (test_sysdb_getpwuid)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
data->uid = _i;
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_getpwuid(test_ctx,
test_ctx->sysdb,
- data->domain,
+ data->ctx->domain,
data->uid,
test_getpwuid,
data);
@@ -1368,11 +1343,10 @@ START_TEST (test_sysdb_enumgrent)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_enumgrent(test_ctx,
test_ctx->sysdb,
- data->domain,
+ data->ctx->domain,
test_enumgrent,
data);
if (ret == EOK) {
@@ -1402,11 +1376,10 @@ START_TEST (test_sysdb_enumpwent)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_enumpwent(test_ctx,
test_ctx->sysdb,
- data->domain,
+ data->ctx->domain,
NULL,
test_enumpwent,
data);
@@ -1441,7 +1414,6 @@ START_TEST (test_sysdb_set_user_attr)
data->ctx = test_ctx;
data->ev = test_ctx->ev;
data->username = talloc_asprintf(data, "testuser%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
data->attrs = sysdb_new_attrs(test_ctx);
if (ret != EOK) {
@@ -1491,11 +1463,10 @@ START_TEST (test_sysdb_get_user_attr)
data = talloc_zero(test_ctx, struct test_data);
data->ctx = test_ctx;
data->username = talloc_asprintf(data, "testuser%d", _i);
- data->domain = get_local_domain(test_ctx->domains);
ret = sysdb_get_user_attr(data,
data->ctx->sysdb,
- data->domain,
+ data->ctx->domain,
data->username,
attrs,
test_get_user_attr,
@@ -1535,7 +1506,6 @@ START_TEST (test_sysdb_add_group_member)
data->ev = test_ctx->ev;
data->groupname = talloc_asprintf(data, "testgroup%d", _i);
data->uid = _i - 1000; /* the UID of user to add */
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -1572,7 +1542,6 @@ START_TEST (test_sysdb_remove_group_member)
data->ev = test_ctx->ev;
data->groupname = talloc_asprintf(data, "testgroup%d", _i);
data->uid = _i - 1000; /* the UID of user to add */
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -1607,7 +1576,6 @@ START_TEST (test_sysdb_remove_nonexistent_user)
data->ctx = test_ctx;
data->ev = test_ctx->ev;
data->uid = 12345;
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
@@ -1643,7 +1611,6 @@ START_TEST (test_sysdb_remove_nonexistent_group)
data->ctx = test_ctx;
data->ev = test_ctx->ev;
data->uid = 12345;
- data->domain = get_local_domain(test_ctx->domains);
req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb);
if (!req) {
diff --git a/server/tools/sss_groupadd.c b/server/tools/sss_groupadd.c
index 5c4733d7..10bb9649 100644
--- a/server/tools/sss_groupadd.c
+++ b/server/tools/sss_groupadd.c
@@ -261,8 +261,16 @@ int main(int argc, const char **argv)
goto fini;
}
+ ret = sysdb_get_ctx_from_list(ctx->db_list, data->domain, &data->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Cannot get domain database!\n"));
+ ERROR("Internal error accesing database\n");
+ ret = EXIT_FAILURE;
+ goto fini;
+ }
+
/* add_group */
- req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ req = sysdb_transaction_send(ctx, ctx->ev, data->sysdb);
if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not add group.\n");
diff --git a/server/tools/sss_groupdel.c b/server/tools/sss_groupdel.c
index 1cf9ed0c..8f02cf3d 100644
--- a/server/tools/sss_groupdel.c
+++ b/server/tools/sss_groupdel.c
@@ -90,7 +90,7 @@ static void group_del(struct tevent_req *req)
return groupdel_done(data, ret, NULL);
}
- group_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ group_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name, data->name);
if (group_dn == NULL) {
DEBUG(1, ("Could not construct a group DN\n"));
@@ -265,8 +265,16 @@ int main(int argc, const char **argv)
goto fini;
}
+ ret = sysdb_get_ctx_from_list(ctx->db_list, data->domain, &data->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Cannot get domain database!\n"));
+ ERROR("Internal error accesing database\n");
+ ret = EXIT_FAILURE;
+ goto fini;
+ }
+
/* groupdel */
- req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ req = sysdb_transaction_send(ctx, ctx->ev, data->sysdb);
if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not remove group.\n");
diff --git a/server/tools/sss_groupmod.c b/server/tools/sss_groupmod.c
index cca9abc6..6f60b6eb 100644
--- a/server/tools/sss_groupmod.c
+++ b/server/tools/sss_groupmod.c
@@ -156,13 +156,13 @@ static void remove_from_groups(struct ops_ctx *data)
struct ldb_dn *member_dn;
struct tevent_req *req;
- parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ parent_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name, data->name);
if (!parent_dn) {
return mod_group_done(data, ENOMEM);
}
- member_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ member_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name,
data->rmgroups[data->cur]);
if (!member_dn) {
@@ -213,13 +213,13 @@ static void add_to_groups(struct ops_ctx *data)
struct ldb_dn *member_dn;
struct tevent_req *req;
- parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ parent_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name, data->name);
if (!parent_dn) {
return mod_group_done(data, ENOMEM);
}
- member_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ member_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name,
data->addgroups[data->cur]);
if (!member_dn) {
@@ -463,7 +463,15 @@ int main(int argc, const char **argv)
goto fini;
}
- req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ ret = sysdb_get_ctx_from_list(ctx->db_list, data->domain, &data->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Cannot get domain database!\n"));
+ ERROR("Internal error accesing database\n");
+ ret = EXIT_FAILURE;
+ goto fini;
+ }
+
+ req = sysdb_transaction_send(ctx, ctx->ev, data->sysdb);
if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not modify group.\n");
diff --git a/server/tools/sss_useradd.c b/server/tools/sss_useradd.c
index 51f0eed8..928212d4 100644
--- a/server/tools/sss_useradd.c
+++ b/server/tools/sss_useradd.c
@@ -126,7 +126,7 @@ static int get_gid(struct ops_ctx *data, const char *groupname)
errno != 0 || data->gid == 0) {
/* Does not look like a gid - find the group name */
- ret = sysdb_getgrnam(data, data->ctx->sysdb,
+ ret = sysdb_getgrnam(data, data->sysdb,
data->domain, groupname,
get_gid_callback, data);
if (ret != EOK) {
@@ -233,13 +233,13 @@ static void add_to_groups(struct ops_ctx *data)
struct ldb_dn *member_dn;
struct tevent_req *subreq;
- member_dn = sysdb_user_dn(data->ctx->sysdb, data,
+ member_dn = sysdb_user_dn(data->sysdb, data,
data->domain->name, data->name);
if (!member_dn) {
return add_user_terminate(data, ENOMEM);
}
- parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ parent_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name,
data->groups[data->cur]);
if (!parent_dn) {
@@ -526,8 +526,16 @@ int main(int argc, const char **argv)
goto fini;
}
+ ret = sysdb_get_ctx_from_list(ctx->db_list, data->domain, &data->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Cannot get domain database!\n"));
+ ERROR("Internal error accesing database\n");
+ ret = EXIT_FAILURE;
+ goto fini;
+ }
+
/* useradd */
- req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ req = sysdb_transaction_send(ctx, ctx->ev, data->sysdb);
if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not modify user.\n");
diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c
index 7c796bb6..2e595f55 100644
--- a/server/tools/sss_userdel.c
+++ b/server/tools/sss_userdel.c
@@ -91,7 +91,7 @@ static void user_del(struct tevent_req *req)
return userdel_done(data, ret, NULL);
}
- user_dn = sysdb_user_dn(data->ctx->sysdb, data,
+ user_dn = sysdb_user_dn(data->sysdb, data,
data->domain->name, data->name);
if (!user_dn) {
DEBUG(1, ("Could not construct a user DN\n"));
@@ -265,8 +265,16 @@ int main(int argc, const char **argv)
goto fini;
}
+ ret = sysdb_get_ctx_from_list(ctx->db_list, data->domain, &data->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Cannot get domain database!\n"));
+ ERROR("Internal error accesing database\n");
+ ret = EXIT_FAILURE;
+ goto fini;
+ }
+
/* userdel */
- req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ req = sysdb_transaction_send(ctx, ctx->ev, data->sysdb);
if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not remove user.\n");
diff --git a/server/tools/sss_usermod.c b/server/tools/sss_usermod.c
index 1dfd2a72..b53c8706 100644
--- a/server/tools/sss_usermod.c
+++ b/server/tools/sss_usermod.c
@@ -182,13 +182,13 @@ static void remove_from_groups(struct ops_ctx *data)
struct ldb_dn *member_dn;
struct tevent_req *req;
- member_dn = sysdb_user_dn(data->ctx->sysdb, data,
+ member_dn = sysdb_user_dn(data->sysdb, data,
data->domain->name, data->name);
if (!member_dn) {
return mod_user_done(data, ENOMEM);
}
- parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ parent_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name,
data->rmgroups[data->cur]);
if (!parent_dn) {
@@ -239,13 +239,13 @@ static void add_to_groups(struct ops_ctx *data)
struct ldb_dn *member_dn;
struct tevent_req *req;
- member_dn = sysdb_user_dn(data->ctx->sysdb, data,
+ member_dn = sysdb_user_dn(data->sysdb, data,
data->domain->name, data->name);
if (!member_dn) {
return mod_user_done(data, ENOMEM);
}
- parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ parent_dn = sysdb_group_dn(data->sysdb, data,
data->domain->name,
data->addgroups[data->cur]);
if (!parent_dn) {
@@ -589,7 +589,15 @@ int main(int argc, const char **argv)
"Could not add attribute to changeset\n");
}
- req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ ret = sysdb_get_ctx_from_list(ctx->db_list, data->domain, &data->sysdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Cannot get domain database!\n"));
+ ERROR("Internal error accesing database\n");
+ ret = EXIT_FAILURE;
+ goto fini;
+ }
+
+ req = sysdb_transaction_send(ctx, ctx->ev, data->sysdb);
if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not modify user.\n");
diff --git a/server/tools/tools_util.c b/server/tools/tools_util.c
index 62013994..3b16f593 100644
--- a/server/tools/tools_util.c
+++ b/server/tools/tools_util.c
@@ -167,7 +167,7 @@ int setup_db(struct tools_ctx **tools_ctx)
return ret;
}
- ret = confdb_get_domains(ctx->confdb, ctx, &ctx->domains);
+ ret = confdb_get_domains(ctx->confdb, &ctx->domains);
if (ret != EOK) {
DEBUG(1, ("Could not get domains"));
talloc_free(ctx);
@@ -175,7 +175,7 @@ int setup_db(struct tools_ctx **tools_ctx)
}
/* open sysdb at default path */
- ret = sysdb_init(ctx, ctx->ev, ctx->confdb, NULL, &ctx->sysdb);
+ ret = sysdb_init(ctx, ctx->ev, ctx->confdb, NULL, false, &ctx->db_list);
if (ret != EOK) {
DEBUG(1, ("Could not initialize connection to the sysdb"));
talloc_free(ctx);
diff --git a/server/tools/tools_util.h b/server/tools/tools_util.h
index 772ba36b..5e2dd95c 100644
--- a/server/tools/tools_util.h
+++ b/server/tools/tools_util.h
@@ -43,7 +43,7 @@ enum id_domain {
struct tools_ctx {
struct tevent_context *ev;
struct confdb_ctx *confdb;
- struct sysdb_ctx *sysdb;
+ struct sysdb_ctx_list *db_list;
struct sss_names_ctx *snctx;
struct sss_domain_info *domains;
@@ -53,6 +53,7 @@ struct ops_ctx {
struct tools_ctx *ctx;
struct tevent_context *ev;
struct sss_domain_info *domain;
+ struct sysdb_ctx *sysdb;
char *name;
uid_t uid;
diff --git a/server/util/backup_file.c b/server/util/backup_file.c
new file mode 100644
index 00000000..cf9ddf30
--- /dev/null
+++ b/server/util/backup_file.c
@@ -0,0 +1,122 @@
+/*
+ SSSD
+
+ Backup files
+
+ Copyright (C) Simo Sorce 2009
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#define BUFFER_SIZE 65536
+
+int backup_file(const char *src_file, int dbglvl)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ char buf[BUFFER_SIZE];
+ int src_fd = -1;
+ int dst_fd = -1;
+ char *dst_file;
+ ssize_t count;
+ ssize_t num;
+ ssize_t pos;
+ int ret, i;
+
+ src_fd = open(src_file, O_RDONLY);
+ if (src_fd < 0) {
+ ret = errno;
+ DEBUG(dbglvl, ("Error (%d [%s]) opening source file %s\n",
+ ret, strerror(ret), src_file));
+ goto done;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* try a few times to come up with a new backup file, then give up */
+ for (i = 0; i < 10; i++) {
+ if (i == 0) {
+ dst_file = talloc_asprintf(tmp_ctx, "%s.bak", src_file);
+ } else {
+ dst_file = talloc_asprintf(tmp_ctx, "%s.bak%d", src_file, i);
+ }
+ if (!dst_file) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ errno = 0;
+ dst_fd = open(dst_file, O_CREAT|O_EXCL|O_WRONLY, 0600);
+ ret = errno;
+
+ if (dst_fd > 0) break;
+
+ if (ret != EEXIST) {
+ DEBUG(dbglvl, ("Error (%d [%s]) opening destination file %s\n",
+ ret, strerror(ret), dst_file));
+ goto done;
+ }
+ }
+ if (ret != 0) {
+ DEBUG(dbglvl, ("Error (%d [%s]) opening destination file %s\n",
+ ret, strerror(ret), dst_file));
+ goto done;
+ }
+
+ /* copy file contents */
+ while (1) {
+ num = read(src_fd, buf, BUFFER_SIZE);
+ if (num < 0) {
+ if (errno == EINTR) continue;
+ ret = errno;
+ DEBUG(dbglvl, ("Error (%d [%s]) reading from source %s\n",
+ ret, strerror(ret), src_file));
+ goto done;
+ }
+ if (num == 0) break;
+
+ count = num;
+
+ while (count > 0) {
+ pos = 0;
+ errno = 0;
+ num = write(dst_fd, &buf[pos], count);
+ if (num < 0) {
+ if (errno == EINTR) continue;
+ ret = errno;
+ DEBUG(dbglvl, ("Error (%d [%s]) writing to destination %s\n",
+ ret, strerror(ret), dst_file));
+ goto done;
+ }
+ pos += num;
+ count -= num;
+ }
+ }
+
+ ret = EOK;
+
+done:
+ if (src_fd != -1) close(src_fd);
+ if (dst_fd != -1) close(dst_fd);
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/server/util/util.h b/server/util/util.h
index f289f9c5..93e5dc97 100644
--- a/server/util/util.h
+++ b/server/util/util.h
@@ -157,4 +157,7 @@ int sss_parse_name(TALLOC_CTX *memctx,
struct sss_names_ctx *snctx,
const char *orig, char **domain, char **name);
+/* from backup-file.c */
+int backup_file(const char *src, int dbglvl);
+
#endif /* __SSSD_UTIL_H__ */