summaryrefslogtreecommitdiffstats
path: root/server/db/sysdb.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/db/sysdb.c')
-rw-r--r--server/db/sysdb.c1883
1 files changed, 0 insertions, 1883 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c
deleted file mode 100644
index b3f81a083..000000000
--- a/server/db/sysdb.c
+++ /dev/null
@@ -1,1883 +0,0 @@
-/*
- SSSD
-
- System Database
-
- 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
- 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 "db/sysdb_private.h"
-#include "confdb/confdb.h"
-#include <time.h>
-
-
-struct ldb_dn *sysdb_custom_subtree_dn(struct sysdb_ctx *ctx, void *memctx,
- const char *domain,
- const char *subtree_name)
-{
- return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
- subtree_name, domain);
-}
-struct ldb_dn *sysdb_custom_dn(struct sysdb_ctx *ctx, void *memctx,
- const char *domain, const char *object_name,
- const char *subtree_name)
-{
- return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_CUSTOM, object_name,
- subtree_name, domain);
-}
-
-struct ldb_dn *sysdb_user_dn(struct sysdb_ctx *ctx, void *memctx,
- const char *domain, const char *name)
-{
- return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_USER, name, domain);
-}
-
-struct ldb_dn *sysdb_group_dn(struct sysdb_ctx *ctx, void *memctx,
- const char *domain, const char *name)
-{
- return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_GROUP, name, domain);
-}
-
-struct ldb_dn *sysdb_domain_dn(struct sysdb_ctx *ctx, void *memctx,
- const char *domain)
-{
- return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_DOM_BASE, domain);
-}
-
-struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx)
-{
- return ctx->ldb;
-}
-
-struct ldb_context *sysdb_handle_get_ldb(struct sysdb_handle *handle)
-{
- return handle->ctx->ldb;
-}
-
-struct sysdb_ctx *sysdb_handle_get_ctx(struct sysdb_handle *handle)
-{
- return handle->ctx;
-}
-
-struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *memctx)
-{
- return talloc_zero(memctx, struct sysdb_attrs);
-}
-
-static int sysdb_attrs_get_el_int(struct sysdb_attrs *attrs, const char *name,
- bool alloc, struct ldb_message_element **el)
-{
- struct ldb_message_element *e = NULL;
- int i;
-
- for (i = 0; i < attrs->num; i++) {
- if (strcasecmp(name, attrs->a[i].name) == 0)
- e = &(attrs->a[i]);
- }
-
- if (!e && alloc) {
- e = talloc_realloc(attrs, attrs->a,
- struct ldb_message_element, attrs->num+1);
- if (!e) return ENOMEM;
- attrs->a = e;
-
- e[attrs->num].name = talloc_strdup(e, name);
- if (!e[attrs->num].name) return ENOMEM;
-
- e[attrs->num].num_values = 0;
- e[attrs->num].values = NULL;
- e[attrs->num].flags = 0;
-
- e = &(attrs->a[attrs->num]);
- attrs->num++;
- }
-
- if (!e) {
- return ENOENT;
- }
-
- *el = e;
-
- return EOK;
-}
-
-int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name,
- struct ldb_message_element **el)
-{
- return sysdb_attrs_get_el_int(attrs, name, true, el);
-}
-
-int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
- const char **string)
-{
- struct ldb_message_element *el;
- int ret;
-
- ret = sysdb_attrs_get_el_int(attrs, name, false, &el);
- if (ret) {
- return ret;
- }
-
- if (el->num_values != 1) {
- return ERANGE;
- }
-
- *string = (const char *)el->values[0].data;
- return EOK;
-}
-
-int sysdb_attrs_add_val(struct sysdb_attrs *attrs,
- const char *name, const struct ldb_val *val)
-{
- struct ldb_message_element *el = NULL;
- struct ldb_val *vals;
- int ret;
-
- ret = sysdb_attrs_get_el(attrs, name, &el);
-
- vals = talloc_realloc(attrs->a, el->values,
- struct ldb_val, el->num_values+1);
- if (!vals) return ENOMEM;
-
- vals[el->num_values] = ldb_val_dup(vals, val);
- if (vals[el->num_values].data == NULL &&
- vals[el->num_values].length != 0) {
- return ENOMEM;
- }
-
- el->values = vals;
- el->num_values++;
-
- return EOK;
-}
-
-int sysdb_attrs_add_string(struct sysdb_attrs *attrs,
- const char *name, const char *str)
-{
- struct ldb_val v;
-
- v.data = (uint8_t *)discard_const(str);
- v.length = strlen(str);
-
- return sysdb_attrs_add_val(attrs, name, &v);
-}
-
-int sysdb_attrs_steal_string(struct sysdb_attrs *attrs,
- const char *name, char *str)
-{
- struct ldb_message_element *el = NULL;
- struct ldb_val *vals;
- int ret;
-
- ret = sysdb_attrs_get_el(attrs, name, &el);
-
- vals = talloc_realloc(attrs->a, el->values,
- struct ldb_val, el->num_values+1);
- if (!vals) return ENOMEM;
- el->values = vals;
-
- /* now steal and assign the string */
- talloc_steal(el->values, str);
-
- el->values[el->num_values].data = (uint8_t *)str;
- el->values[el->num_values].length = strlen(str);
- el->num_values++;
-
- return EOK;
-}
-
-int sysdb_attrs_add_long(struct sysdb_attrs *attrs,
- const char *name, long value)
-{
- struct ldb_val v;
- char *str;
- int ret;
-
- str = talloc_asprintf(attrs, "%ld", value);
- if (!str) return ENOMEM;
-
- v.data = (uint8_t *)str;
- v.length = strlen(str);
-
- ret = sysdb_attrs_add_val(attrs, name, &v);
- talloc_free(str);
-
- return ret;
-}
-
-int sysdb_attrs_add_uint32(struct sysdb_attrs *attrs,
- const char *name, uint32_t value)
-{
- unsigned long val = value;
- struct ldb_val v;
- char *str;
- int ret;
-
- str = talloc_asprintf(attrs, "%lu", val);
- if (!str) return ENOMEM;
-
- v.data = (uint8_t *)str;
- v.length = strlen(str);
-
- ret = sysdb_attrs_add_val(attrs, name, &v);
- talloc_free(str);
-
- return ret;
-}
-
-int sysdb_attrs_add_time_t(struct sysdb_attrs *attrs,
- const char *name, time_t value)
-{
- long long val = value;
- struct ldb_val v;
- char *str;
- int ret;
-
- str = talloc_asprintf(attrs, "%lld", val);
- if (!str) return ENOMEM;
-
- v.data = (uint8_t *)str;
- v.length = strlen(str);
-
- ret = sysdb_attrs_add_val(attrs, name, &v);
- talloc_free(str);
-
- return ret;
-}
-
-int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs,
- const char *attr_name,
- const char *domain,
- const char **list)
-{
- struct ldb_message_element *el = NULL;
- struct ldb_val *vals;
- int i, j, num;
- char *member;
- int ret;
-
- ret = sysdb_attrs_get_el(attrs, attr_name, &el);
- if (ret) {
- return ret;
- }
-
- for (num = 0; list[num]; num++) /* count */ ;
-
- vals = talloc_realloc(attrs->a, el->values,
- struct ldb_val, el->num_values + num);
- if (!vals) {
- return ENOMEM;
- }
- el->values = vals;
-
- DEBUG(9, ("Adding %d members to existing %d ones\n",
- num, el->num_values));
-
- for (i = 0, j = el->num_values; i < num; i++) {
-
- member = sysdb_user_strdn(el->values, domain, list[i]);
- if (!member) {
- DEBUG(4, ("Failed to get user dn for [%s]\n", list[i]));
- continue;
- }
- el->values[j].data = (uint8_t *)member;
- el->values[j].length = strlen(member);
- j++;
-
- DEBUG(7, (" member #%d: [%s]\n", i, member));
- }
- el->num_values = j;
-
- return EOK;
-}
-
-int sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs,
- const char *attr_name,
- const char *domain,
- struct ldb_val *values,
- int num_values)
-{
- struct ldb_message_element *el = NULL;
- struct ldb_val *vals;
- int i, j;
- char *member;
- int ret;
-
- ret = sysdb_attrs_get_el(attrs, attr_name, &el);
- if (ret) {
- return ret;
- }
-
- vals = talloc_realloc(attrs->a, el->values, struct ldb_val,
- el->num_values + num_values);
- if (!vals) {
- return ENOMEM;
- }
- el->values = vals;
-
- DEBUG(9, ("Adding %d members to existing %d ones\n",
- num_values, el->num_values));
-
- for (i = 0, j = el->num_values; i < num_values; i++) {
- member = sysdb_user_strdn(el->values, domain,
- (char *)values[i].data);
- if (!member) {
- DEBUG(4, ("Failed to get user dn for [%s]\n",
- (char *)values[i].data));
- return ENOMEM;
- }
- el->values[j].data = (uint8_t *)member;
- el->values[j].length = strlen(member);
- j++;
-
- DEBUG(7, (" member #%d: [%s]\n", i, member));
- }
- el->num_values = j;
-
- return EOK;
-}
-
-static char *build_dom_dn_str_escape(TALLOC_CTX *memctx, const char *template,
- const char *domain, const char *name)
-{
- char *ret;
- int l;
-
- l = strcspn(name, ",=\n+<>#;\\\"");
- if (name[l] != '\0') {
- struct ldb_val v;
- char *tmp;
-
- v.data = discard_const_p(uint8_t, name);
- v.length = strlen(name);
-
- tmp = ldb_dn_escape_value(memctx, v);
- if (!tmp) {
- return NULL;
- }
-
- ret = talloc_asprintf(memctx, template, tmp, domain);
- talloc_zfree(tmp);
- if (!ret) {
- return NULL;
- }
-
- return ret;
- }
-
- ret = talloc_asprintf(memctx, template, name, domain);
- if (!ret) {
- return NULL;
- }
-
- return ret;
-}
-
-char *sysdb_user_strdn(TALLOC_CTX *memctx,
- const char *domain, const char *name)
-{
- return build_dom_dn_str_escape(memctx, SYSDB_TMPL_USER, domain, name);
-}
-
-char *sysdb_group_strdn(TALLOC_CTX *memctx,
- const char *domain, const char *name)
-{
- return build_dom_dn_str_escape(memctx, SYSDB_TMPL_GROUP, domain, name);
-}
-
-/* TODO: make a more complete and precise mapping */
-int sysdb_error_to_errno(int ldberr)
-{
- switch (ldberr) {
- case LDB_SUCCESS:
- return EOK;
- case LDB_ERR_OPERATIONS_ERROR:
- return EIO;
- case LDB_ERR_NO_SUCH_OBJECT:
- return ENOENT;
- case LDB_ERR_BUSY:
- return EBUSY;
- case LDB_ERR_ENTRY_ALREADY_EXISTS:
- return EEXIST;
- default:
- return EFAULT;
- }
-}
-
-/* =Internal-Operations-Queue============================================= */
-
-static void sysdb_run_operation(struct tevent_context *ev,
- struct tevent_timer *te,
- struct timeval tv, void *pvt)
-{
- struct sysdb_handle *handle = talloc_get_type(pvt, struct sysdb_handle);
-
- tevent_req_done(handle->subreq);
-}
-
-static void sysdb_schedule_operation(struct sysdb_handle *handle)
-{
- struct timeval tv = { 0, 0 };
- struct tevent_timer *te;
-
- te = tevent_add_timer(handle->ctx->ev, handle, tv,
- sysdb_run_operation, handle);
- if (!te) {
- DEBUG(1, ("Failed to add critical timer to run next handle!\n"));
- }
-}
-
-static int sysdb_handle_destructor(void *mem)
-{
- struct sysdb_handle *handle = talloc_get_type(mem, struct sysdb_handle);
- bool start_next = false;
- int ret;
-
- /* if this was the current op start next */
- if (handle->ctx->queue == handle) {
- start_next = true;
- }
-
- DLIST_REMOVE(handle->ctx->queue, handle);
-
- if (start_next && handle->ctx->queue) {
- /* run next */
- sysdb_schedule_operation(handle->ctx->queue);
- }
-
- if (handle->transaction_active) {
- ret = ldb_transaction_cancel(handle->ctx->ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
- }
- /* FIXME: abort() ? */
- handle->transaction_active = false;
- }
-
- return 0;
-}
-
-struct sysdb_get_handle_state {
- struct tevent_context *ev;
- struct sysdb_ctx *ctx;
-
- struct sysdb_handle *handle;
-};
-
-struct tevent_req *sysdb_get_handle_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx)
-{
- struct tevent_req *req;
- struct sysdb_get_handle_state *state;
- struct sysdb_handle *handle;
-
- req = tevent_req_create(mem_ctx, &state, struct sysdb_get_handle_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- handle = talloc_zero(state, struct sysdb_handle);
- if (!handle) {
- talloc_zfree(req);
- return NULL;
- }
-
- handle->ctx = ctx;
- handle->subreq = req;
-
- talloc_set_destructor((TALLOC_CTX *)handle, sysdb_handle_destructor);
-
- DLIST_ADD_END(ctx->queue, handle, struct sysdb_handle *);
-
- if (ctx->queue == handle) {
- /* this is the first in the queue, schedule an immediate run */
- sysdb_schedule_operation(handle);
- }
-
- state->handle = handle;
-
- return req;
-}
-
-static int sysdb_get_handle_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct sysdb_handle **handle)
-{
- struct sysdb_get_handle_state *state = tevent_req_data(req,
- struct sysdb_get_handle_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *handle = talloc_steal(memctx, state->handle);
- if (!*handle) return ENOMEM;
-
- return EOK;
-}
-
-/* =Transactions========================================================== */
-
-struct sysdb_transaction_state {
- struct tevent_context *ev;
- struct sysdb_ctx *ctx;
-
- struct sysdb_handle *handle;
-};
-
-static void sysdb_transaction_done(struct tevent_req *subreq);
-
-struct tevent_req *sysdb_transaction_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct sysdb_transaction_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct sysdb_transaction_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- subreq = sysdb_get_handle_send(state, ev, ctx);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
-
- tevent_req_set_callback(subreq, sysdb_transaction_done, req);
-
- return req;
-}
-
-static void sysdb_transaction_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sysdb_transaction_state *state = tevent_req_data(req,
- struct sysdb_transaction_state);
- int ret;
-
- ret = sysdb_get_handle_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- ret = ldb_transaction_start(state->ctx->ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
- tevent_req_error(req, sysdb_error_to_errno(ret));
- return;
- }
- state->handle->transaction_active = true;
-
- tevent_req_done(req);
-}
-
-int sysdb_transaction_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct sysdb_handle **handle)
-{
- struct sysdb_transaction_state *state = tevent_req_data(req,
- struct sysdb_transaction_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *handle = talloc_steal(memctx, state->handle);
- if (!*handle) return ENOMEM;
-
- return EOK;
-}
-
-struct tevent_req *sysdb_transaction_commit_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_handle *handle)
-{
- struct tevent_req *req;
- struct sysdb_transaction_state *state;
- int ret;
-
- req = tevent_req_create(mem_ctx, &state, struct sysdb_transaction_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = handle->ctx;
- state->handle = handle;
-
- ret = ldb_transaction_commit(handle->ctx->ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
- tevent_req_error(req, sysdb_error_to_errno(ret));
- }
- handle->transaction_active = false;
-
- /* the following may seem weird but it is actually fine.
- * _done() will not actually call the callback as it will not be set
- * until we return. But it will mark the request as done.
- * _post() will trigger the callback as it schedules after we returned
- * and actually set the callback */
- tevent_req_done(req);
- tevent_req_post(req, ev);
- return req;
-}
-
-int sysdb_transaction_commit_recv(struct tevent_req *req)
-{
- struct sysdb_transaction_state *state = tevent_req_data(req,
- struct sysdb_transaction_state);
-
- /* finally free handle
- * this will also trigger the next transaction in the queue if any */
- talloc_zfree(state->handle);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-/* default transaction commit receive function.
- * This function does not use the request state so it is safe to use
- * from any caller */
-void sysdb_transaction_complete(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- int ret;
-
- ret = sysdb_transaction_commit_recv(subreq);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-
-/* =Operations============================================================ */
-
-struct sysdb_operation_state {
- struct tevent_context *ev;
- struct sysdb_ctx *ctx;
-
- struct sysdb_handle *handle;
-};
-
-static void sysdb_operation_process(struct tevent_req *subreq);
-
-struct tevent_req *sysdb_operation_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *ctx)
-{
- struct tevent_req *req, *subreq;
- struct sysdb_operation_state *state;
-
- req = tevent_req_create(mem_ctx, &state, struct sysdb_operation_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = ctx;
-
- subreq = sysdb_get_handle_send(state, ev, ctx);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
-
- tevent_req_set_callback(subreq, sysdb_operation_process, req);
-
- return req;
-}
-
-static void sysdb_operation_process(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct sysdb_operation_state *state = tevent_req_data(req,
- struct sysdb_operation_state);
- int ret;
-
- ret = sysdb_get_handle_recv(subreq, state, &state->handle);
- talloc_zfree(subreq);
- if (ret) {
- tevent_req_error(req, ret);
- return;
- }
-
- tevent_req_done(req);
-}
-
-int sysdb_operation_recv(struct tevent_req *req, TALLOC_CTX *memctx,
- struct sysdb_handle **handle)
-{
- struct sysdb_operation_state *state = tevent_req_data(req,
- struct sysdb_operation_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *handle = talloc_steal(memctx, state->handle);
- if (!*handle) return ENOMEM;
-
- return EOK;
-}
-
-void sysdb_operation_done(struct sysdb_handle *handle)
-{
- talloc_free(handle);
-}
-
-/* =Initialization======================================================== */
-
-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);
-
-static int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
- const char *provider, const char *name,
- const char *base_path, char **_ldb_file)
-{
- char *ldb_file;
-
- /* special case for the local domain */
- if (strcasecmp(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, name);
- }
- if (!ldb_file) {
- return ENOMEM;
- }
-
- *_ldb_file = ldb_file;
- return EOK;
-}
-
-/* serach all groups that have a memberUid attribute.
- * change it into a member attribute for a user of same domain.
- * remove the memberUid attribute
- * add the new member attribute
- * finally stop indexing memberUid
- * upgrade version to 0.2
- */
-static int sysdb_upgrade_01(TALLOC_CTX *mem_ctx,
- struct ldb_context *ldb,
- const char **ver)
-{
- struct ldb_message_element *el;
- struct ldb_result *res;
- struct ldb_dn *basedn;
- struct ldb_dn *mem_dn;
- struct ldb_message *msg;
- const struct ldb_val *val;
- const char *filter = "(&(memberUid=*)(objectclass=group))";
- const char *attrs[] = { "memberUid", NULL };
- const char *mdn;
- char *domain;
- int ret, i, j;
-
- basedn = ldb_dn_new(mem_ctx, ldb, "cn=sysdb");
- if (!basedn) {
- ret = EIO;
- goto done;
- }
-
- ret = ldb_search(ldb, mem_ctx, &res,
- basedn, LDB_SCOPE_SUBTREE,
- attrs, filter);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
-
- ret = ldb_transaction_start(ldb);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
-
- for (i = 0; i < res->count; i++) {
- el = ldb_msg_find_element(res->msgs[i], "memberUid");
- if (!el) {
- DEBUG(1, ("memberUid is missing from message [%s], skipping\n",
- ldb_dn_get_linearized(res->msgs[i]->dn)));
- continue;
- }
-
- /* create modification message */
- msg = ldb_msg_new(mem_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = res->msgs[i]->dn;
-
- ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- /* get domain name component value */
- val = ldb_dn_get_component_val(res->msgs[i]->dn, 2);
- domain = talloc_strndup(mem_ctx, (const char *)val->data, val->length);
- if (!domain) {
- ret = ENOMEM;
- goto done;
- }
-
- for (j = 0; j < el->num_values; j++) {
- mem_dn = ldb_dn_new_fmt(mem_ctx, ldb, SYSDB_TMPL_USER,
- (const char *)el->values[j].data, domain);
- if (!mem_dn) {
- ret = ENOMEM;
- goto done;
- }
-
- mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn));
- if (!mdn) {
- ret = ENOMEM;
- goto done;
- }
- ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- talloc_zfree(mem_dn);
- }
-
- /* ok now we are ready to modify the entry */
- ret = ldb_modify(ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- talloc_zfree(msg);
- }
-
- /* conversion done, upgrade version number */
- msg = ldb_msg_new(mem_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = ldb_dn_new(mem_ctx, 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_2);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_modify(ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- ret = EOK;
-
-done:
- if (ret != EOK) {
- ldb_transaction_cancel(ldb);
- } else {
- ret = ldb_transaction_commit(ldb);
- if (ret != LDB_SUCCESS) {
- return EIO;
- }
-
- *ver = SYSDB_VERSION_0_2;
- }
-
- return ret;
-}
-
-static int sysdb_check_upgrade_02(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sss_domain_info *domains,
- const char *db_path)
-{
- TALLOC_CTX *tmp_ctx = NULL;
- struct ldb_context *ldb;
- char *ldb_file;
- struct sysdb_ctx *ctx;
- struct sss_domain_info *dom;
- struct ldb_message_element *el;
- struct ldb_message *msg;
- struct ldb_result *res;
- struct ldb_dn *verdn;
- const char *version = NULL;
- bool do_02_upgrade = false;
- bool ctx_trans = false;
- int ret;
-
- tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- ret = sysdb_get_db_file(mem_ctx,
- "local", "UPGRADE",
- db_path, &ldb_file);
- if (ret != EOK) {
- goto exit;
- }
-
- ldb = ldb_init(tmp_ctx, ev);
- if (!ldb) {
- ret = EIO;
- goto exit;
- }
-
- ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto exit;
- }
-
-#ifdef SYSDB_TEST
- ldb_set_modules_dir(ldb, "./.libs");
-#endif
-
- ret = ldb_connect(ldb, ldb_file, 0, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto exit;
- }
-
- verdn = ldb_dn_new(tmp_ctx, ldb, "cn=sysdb");
- if (!verdn) {
- ret = EIO;
- goto exit;
- }
-
- ret = ldb_search(ldb, tmp_ctx, &res,
- verdn, LDB_SCOPE_BASE,
- NULL, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto exit;
- }
- if (res->count > 1) {
- ret = EIO;
- goto exit;
- }
-
- if (res->count == 1) {
- el = ldb_msg_find_element(res->msgs[0], "version");
- if (el) {
- if (el->num_values != 1) {
- ret = EINVAL;
- goto exit;
- }
- version = talloc_strndup(tmp_ctx,
- (char *)(el->values[0].data),
- el->values[0].length);
- if (!version) {
- ret = ENOMEM;
- goto exit;
- }
-
- if (strcmp(version, SYSDB_VERSION) == 0) {
- /* all fine, return */
- ret = EOK;
- goto exit;
- }
-
- DEBUG(4, ("Upgrading DB from version: %s\n", version));
-
- if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
- /* convert database */
- ret = sysdb_upgrade_01(tmp_ctx, ldb, &version);
- if (ret != EOK) goto exit;
- }
-
- if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
- /* need to convert database to split files */
- do_02_upgrade = true;
- }
-
- }
- }
-
- if (!do_02_upgrade) {
- /* not a v2 upgrade, return and let the normal code take over any
- * further upgrade */
- ret = EOK;
- goto exit;
- }
-
- /* == V2->V3 UPGRADE == */
-
- 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(ldb);
-
- /* backup*/
- ret = backup_file(ldb_file, 0);
- if (ret != EOK) {
- goto exit;
- }
-
- /* reopen */
- ldb = ldb_init(tmp_ctx, ev);
- if (!ldb) {
- ret = EIO;
- goto exit;
- }
-
- ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto exit;
- }
-
- ret = ldb_connect(ldb, ldb_file, 0, NULL);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto exit;
- }
-
- /* open a transaction */
- ret = ldb_transaction_start(ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
- ret = EIO;
- goto exit;
- }
-
- /* == Upgrade contents == */
-
- for (dom = domains; dom; dom = dom->next) {
- struct ldb_dn *domain_dn;
- struct ldb_dn *users_dn;
- struct ldb_dn *groups_dn;
- int i;
-
- /* skip local */
- if (strcasecmp(dom->provider, "local") == 0) {
- continue;
- }
-
- /* create new dom db */
- ret = sysdb_domain_init_internal(tmp_ctx, ev, dom,
- db_path, false, &ctx);
- if (ret != EOK) {
- goto done;
- }
-
- 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(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 (i = 0; i < res->count; i++) {
-
- struct ldb_dn *orig_dn;
-
- msg = res->msgs[i];
-
- /* 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;
- }
-
- /* regenerate the DN against the new ldb as it may have different
- * casefolding rules (example: name changing from case insensitive
- * to case sensitive) */
- orig_dn = msg->dn;
- msg->dn = ldb_dn_new(msg, ctx->ldb,
- ldb_dn_get_linearized(orig_dn));
- if (!msg->dn) {
- ret = ENOMEM;
- goto done;
- }
-
- 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(ldb, orig_dn);
- if (ret != LDB_SUCCESS) {
- DEBUG(0, ("WARNING: Could not remove entry %s,"
- " from old ldb file! (%d [%s])\n",
- ldb_dn_get_linearized(orig_dn),
- ret, ldb_errstring(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(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(groups_dn),
- ret, ldb_errstring(ldb)));
- }
- ret = ldb_delete(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(users_dn),
- ret, ldb_errstring(ldb)));
- }
- ret = ldb_delete(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(domain_dn),
- ret, ldb_errstring(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, 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(ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- ret = ldb_transaction_commit(ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
- ret = EIO;
- goto exit;
- }
-
- 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));
- }
- }
- ret = ldb_transaction_cancel(ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
- }
- }
-
-exit:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-static int sysdb_upgrade_03(struct sysdb_ctx *ctx, const char **ver)
-{
- TALLOC_CTX *tmp_ctx;
- int ret;
- struct ldb_message *msg;
-
- tmp_ctx = talloc_new(ctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_4));
-
- ret = ldb_transaction_start(ctx->ldb);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
-
- /* Make this database case-sensitive */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "@ATTRIBUTES");
- if (!msg->dn) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_modify(ctx->ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- /* conversion done, upgrade version number */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = ldb_dn_new(tmp_ctx, ctx->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_4);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_modify(ctx->ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- ret = EOK;
-
-done:
- talloc_zfree(tmp_ctx);
-
- if (ret != EOK) {
- ret = ldb_transaction_cancel(ctx->ldb);
- } else {
- ret = ldb_transaction_commit(ctx->ldb);
- *ver = SYSDB_VERSION_0_4;
- }
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- }
-
- return ret;
-}
-
-static int sysdb_upgrade_04(struct sysdb_ctx *ctx, const char **ver)
-{
- TALLOC_CTX *tmp_ctx;
- int ret;
- struct ldb_message *msg;
-
- tmp_ctx = talloc_new(ctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_5));
-
- ret = ldb_transaction_start(ctx->ldb);
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- goto done;
- }
-
- /* Add new index */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "@INDEXLIST");
- if (!msg->dn) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
- ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN");
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_modify(ctx->ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- /* Rebuild memberuid and memberoif attributes */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = ldb_dn_new(tmp_ctx, ctx->ldb, "@MEMBEROF-REBUILD");
- if (!msg->dn) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_add(ctx->ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- /* conversion done, upgrade version number */
- msg = ldb_msg_new(tmp_ctx);
- if (!msg) {
- ret = ENOMEM;
- goto done;
- }
- msg->dn = ldb_dn_new(tmp_ctx, ctx->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_5);
- if (ret != LDB_SUCCESS) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = ldb_modify(ctx->ldb, msg);
- if (ret != LDB_SUCCESS) {
- ret = sysdb_error_to_errno(ret);
- goto done;
- }
-
- ret = EOK;
-
-done:
- talloc_zfree(tmp_ctx);
-
- if (ret != EOK) {
- ret = ldb_transaction_cancel(ctx->ldb);
- } else {
- ret = ldb_transaction_commit(ctx->ldb);
- *ver = SYSDB_VERSION_0_5;
- }
- if (ret != LDB_SUCCESS) {
- ret = EIO;
- }
-
- 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)
-{
- 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;
-
- /* The local provider s the only true MPG,
- * for the other domains, the provider actually unrolls MPGs */
- if (strcasecmp(domain->provider, "local") == 0) {
- ctx->mpg = true;
- }
-
- ret = sysdb_get_db_file(ctx, domain->provider,
- domain->name, 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) {
- return EIO;
- }
-
- ret = ldb_set_debug(ctx->ldb, ldb_debug_messages, NULL);
- if (ret != LDB_SUCCESS) {
- return EIO;
- }
-
-#ifdef SYSDB_TEST
- ldb_set_modules_dir(ctx->ldb, "./.libs");
-#endif
-
- ret = ldb_connect(ctx->ldb, ctx->ldb_file, 0, NULL);
- if (ret != LDB_SUCCESS) {
- return EIO;
- }
-
- 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;
- }
-
- DEBUG(4, ("Upgrading DB [%s] from version: %s\n",
- domain->name, version));
-
- if (strcmp(version, SYSDB_VERSION_0_3) == 0) {
- ret = sysdb_upgrade_03(ctx, &version);
- if (ret != EOK) {
- goto done;
- }
- }
-
- if (strcmp(version, SYSDB_VERSION_0_4) == 0) {
- ret = sysdb_upgrade_04(ctx, &version);
- 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_zfree(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_zfree(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_zfree(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;
- 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_zfree(ctx_list);
- return ret;
- }
-
- if (allow_upgrade) {
- /* check if we have an old sssd.ldb to upgrade */
- ret = sysdb_check_upgrade_02(ctx_list, ev, domains,
- ctx_list->db_path);
- if (ret != EOK) {
- talloc_zfree(ctx_list);
- return ret;
- }
- }
-
- 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);
- 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;
- }
-
- *_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);
-}
-
-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;
-}
-
-
-int compare_ldb_dn_comp_num(const void *m1, const void *m2)
-{
- struct ldb_message *msg1 = talloc_get_type(*(void **) discard_const(m1),
- struct ldb_message);
- struct ldb_message *msg2 = talloc_get_type(*(void **) discard_const(m2),
- struct ldb_message);
-
- return ldb_dn_get_comp_num(msg2->dn) - ldb_dn_get_comp_num(msg1->dn);
-}
-
-int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname,
- const char *newname)
-{
- struct ldb_message_element *e = NULL;
- int i;
- const char *dummy;
-
- if (attrs == NULL || oldname == NULL || newname == NULL) return EINVAL;
-
- for (i = 0; i < attrs->num; i++) {
- if (strcasecmp(oldname, attrs->a[i].name) == 0) {
- e = &(attrs->a[i]);
- }
- if (strcasecmp(newname, attrs->a[i].name) == 0) {
- DEBUG(3, ("New attribute name [%s] already exists.\n", newname));
- return EEXIST;
- }
- }
-
- if (e != NULL) {
- dummy = talloc_strdup(attrs, newname);
- if (dummy == NULL) {
- DEBUG(1, ("talloc_strdup failed.\n"));
- return ENOMEM;
- }
-
- talloc_free(discard_const(e->name));
- e->name = dummy;
- }
-
- return EOK;
-}