From 1c48b5a62f73234ed26bb20f0ab345ab61cda0ab Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Thu, 18 Feb 2010 07:49:04 -0500 Subject: Rename server/ directory to src/ Also update BUILD.txt --- server/db/sysdb.c | 1883 ----------------------------------------------------- 1 file changed, 1883 deletions(-) delete mode 100644 server/db/sysdb.c (limited to 'server/db/sysdb.c') 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 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 . -*/ - -#include "util/util.h" -#include "db/sysdb_private.h" -#include "confdb/confdb.h" -#include - - -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; -} -- cgit