sysdb.c revision 35480afaefafb77b28d35b29039989ab888aafe9
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder System Database
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder This program is free software; you can redistribute it and/or modify
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder it under the terms of the GNU General Public License as published by
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder the Free Software Foundation; either version 3 of the License, or
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder (at your option) any later version.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder This program is distributed in the hope that it will be useful,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder GNU General Public License for more details.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder You should have received a copy of the GNU General Public License
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder along with this program. If not, see <http://www.gnu.org/licenses/>.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct ldb_dn *sysdb_custom_subtree_dn(struct sysdb_ctx *ctx, void *memctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
38c817b94e0a5b1ae94178b1075c187e07bcc5e1Christian Maederstruct ldb_dn *sysdb_custom_dn(struct sysdb_ctx *ctx, void *memctx,
38c817b94e0a5b1ae94178b1075c187e07bcc5e1Christian Maeder const char *domain, const char *object_name,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_CUSTOM, object_name,
d81905a5b924415c524d702df26204683c82c12eChristian Maederstruct ldb_dn *sysdb_user_dn(struct sysdb_ctx *ctx, void *memctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_USER, name, domain);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct ldb_dn *sysdb_group_dn(struct sysdb_ctx *ctx, void *memctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_TMPL_GROUP, name, domain);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct ldb_dn *sysdb_domain_dn(struct sysdb_ctx *ctx, void *memctx,
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder return ldb_dn_new_fmt(memctx, ctx->ldb, SYSDB_DOM_BASE, domain);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *ctx)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *memctx)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return talloc_zero(memctx, struct sysdb_attrs);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic int sysdb_attrs_get_el_int(struct sysdb_attrs *attrs, const char *name,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder bool alloc, struct ldb_message_element **el)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (strcasecmp(name, attrs->a[i].name) == 0)
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke if (!e) return ENOMEM;
2353f65833a3da763392f771223250cd50b8d873Christian Maederint sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name,
2353f65833a3da763392f771223250cd50b8d873Christian Maeder return sysdb_attrs_get_el_int(attrs, name, true, el);
2353f65833a3da763392f771223250cd50b8d873Christian Maederint sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_attrs_get_el_int(attrs, name, false, &el);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder *string = (const char *)el->values[0].data;
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maederint sysdb_attrs_add_val(struct sysdb_attrs *attrs,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *name, const struct ldb_val *val)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_attrs_get_el(attrs, name, &el);
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder vals = talloc_realloc(attrs->a, el->values,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder vals[el->num_values] = ldb_val_dup(vals, val);
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maederint sysdb_attrs_add_string(struct sysdb_attrs *attrs,
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder return sysdb_attrs_add_val(attrs, name, &v);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederint sysdb_attrs_add_bool(struct sysdb_attrs *attrs,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return sysdb_attrs_add_string(attrs, name, "TRUE");
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder return sysdb_attrs_add_string(attrs, name, "FALSE");
d81905a5b924415c524d702df26204683c82c12eChristian Maederint sysdb_attrs_steal_string(struct sysdb_attrs *attrs,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_attrs_get_el(attrs, name, &el);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder /* now steal and assign the string */
2353f65833a3da763392f771223250cd50b8d873Christian Maeder el->values[el->num_values].data = (uint8_t *)str;
083bc1972a66d73749760eab3a90bf4eb9ca7951Christian Maeder el->values[el->num_values].length = strlen(str);
2353f65833a3da763392f771223250cd50b8d873Christian Maederint sysdb_attrs_add_long(struct sysdb_attrs *attrs,
2353f65833a3da763392f771223250cd50b8d873Christian Maeder str = talloc_asprintf(attrs, "%ld", value);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_attrs_add_val(attrs, name, &v);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederint sysdb_attrs_add_uint32(struct sysdb_attrs *attrs,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_attrs_add_val(attrs, name, &v);
a9e804dbec424ec36e34bab955cbe90edac5baa6Christian Maederint sysdb_attrs_add_time_t(struct sysdb_attrs *attrs,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_attrs_add_val(attrs, name, &v);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederint sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char **list)
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder ret = sysdb_attrs_get_el(attrs, attr_name, &el);
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich for (num = 0; list[num]; num++) /* count */ ;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder vals = talloc_realloc(attrs->a, el->values,
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder DEBUG(9, ("Adding %d members to existing %d ones\n",
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder for (i = 0, j = el->num_values; i < num; i++) {
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder member = sysdb_user_strdn(el->values, domain, list[i]);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(4, ("Failed to get user dn for [%s]\n", list[i]));
fdac680252d7347858bd67b4c2a2aaa52e623815Christian Maeder DEBUG(7, (" member #%d: [%s]\n", i, member));
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maederint sysdb_attrs_users_from_ldb_vals(struct sysdb_attrs *attrs,
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke ret = sysdb_attrs_get_el(attrs, attr_name, &el);
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder vals = talloc_realloc(attrs->a, el->values, struct ldb_val,
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder DEBUG(9, ("Adding %d members to existing %d ones\n",
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder for (i = 0, j = el->num_values; i < num_values; i++) {
2353f65833a3da763392f771223250cd50b8d873Christian Maeder member = sysdb_user_strdn(el->values, domain,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(4, ("Failed to get user dn for [%s]\n",
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(7, (" member #%d: [%s]\n", i, member));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic char *build_dom_dn_str_escape(TALLOC_CTX *memctx, const char *template,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = talloc_asprintf(memctx, template, tmp, domain);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = talloc_asprintf(memctx, template, name, domain);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return build_dom_dn_str_escape(memctx, SYSDB_TMPL_USER, domain, name);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return build_dom_dn_str_escape(memctx, SYSDB_TMPL_GROUP, domain, name);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder/* TODO: make a more complete and precise mapping */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder/* =Transactions========================================================== */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederint sysdb_transaction_start(struct sysdb_ctx *ctx)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maederint sysdb_transaction_commit(struct sysdb_ctx *ctx)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maederint sysdb_transaction_cancel(struct sysdb_ctx *ctx)
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
083bc1972a66d73749760eab3a90bf4eb9ca7951Christian Maeder/* =Initialization======================================================== */
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maederstatic int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
2353f65833a3da763392f771223250cd50b8d873Christian Maederstatic int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* special case for the local domain */
3a9d784341454573b50b32fa1b494e7418df3086Christian Maeder ldb_file = talloc_asprintf(mem_ctx, "%s/"LOCAL_SYSDB_FILE,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ldb_file = talloc_asprintf(mem_ctx, "%s/"CACHE_SYSDB_FILE,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder/* serach all groups that have a memberUid attribute.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * change it into a member attribute for a user of same domain.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * remove the memberUid attribute
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * add the new member attribute
9dd71ac51c9a6e72bcb126224f9c64131698b636Christian Maeder * finally stop indexing memberUid
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder * upgrade version to 0.2
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maederstatic int sysdb_upgrade_01(TALLOC_CTX *mem_ctx,
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maeder const char **ver)
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder const char *filter = "(&(memberUid=*)(objectclass=group))";
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder const char *attrs[] = { "memberUid", NULL };
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder basedn = ldb_dn_new(mem_ctx, ldb, "cn=sysdb");
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder el = ldb_msg_find_element(res->msgs[i], "memberUid");
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder DEBUG(1, ("memberUid is missing from message [%s], skipping\n",
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder /* create modification message */
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* get domain name component value */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder val = ldb_dn_get_component_val(res->msgs[i]->dn, 2);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder domain = talloc_strndup(mem_ctx, (const char *)val->data, val->length);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder mem_dn = ldb_dn_new_fmt(mem_ctx, ldb, SYSDB_TMPL_USER,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn));
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* ok now we are ready to modify the entry */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* conversion done, upgrade version number */
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder msg->dn = ldb_dn_new(mem_ctx, ldb, "cn=sysdb");
2353f65833a3da763392f771223250cd50b8d873Christian Maeder ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_2);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic int sysdb_check_upgrade_02(TALLOC_CTX *mem_ctx,
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder ldb_set_modules_dir(ctx->ldb, ABS_BUILD_DIR"/.libs");
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder verdn = ldb_dn_new(tmp_ctx, ldb, "cn=sysdb");
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder el = ldb_msg_find_element(res->msgs[0], "version");
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* all fine, return */
2353f65833a3da763392f771223250cd50b8d873Christian Maeder DEBUG(4, ("Upgrading DB from version: %s\n", version));
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder /* convert database */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sysdb_upgrade_01(tmp_ctx, ldb, &version);
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder /* need to convert database to split files */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* not a v2 upgrade, return and let the normal code take over any
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * further upgrade */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* == V2->V3 UPGRADE == */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(0, ("UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* ldb uses posix locks,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * posix is stupid and kills all locks when you close *any* file
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * descriptor associated to the same file.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * Therefore we must close and reopen the ldb file here */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* == Backup and reopen ldb == */
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* open a transaction */
2353f65833a3da763392f771223250cd50b8d873Christian Maeder DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* == Upgrade contents == */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder for (dom = domains; dom; dom = dom->next) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* skip local */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (strcasecmp(dom->provider, "local") == 0) {
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder /* create new dom db */
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder ret = sysdb_domain_init_internal(tmp_ctx, dom,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder /* search all entries for this domain in local,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * copy them all in the new database,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * then remove them from local */
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder domain_dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
goto done;
if (!users_dn) {
goto done;
if (!groups_dn) {
goto done;
goto done;
goto done;
ctx_trans = false;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
goto done;
goto exit;
done:
if (ctx_trans) {
exit:
return ret;
int ret;
if (!tmp_ctx) {
return ENOMEM;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
int ret;
if (!tmp_ctx) {
return ENOMEM;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
const char *db_path,
bool allow_upgrade,
const char *base_ldif;
int ret;
if (!ctx) {
return ENOMEM;
return ret;
return EIO;
return EIO;
#ifdef SYSDB_TEST
return EIO;
if (!tmp_ctx) {
return ENOMEM;
if (!verdn) {
goto done;
goto done;
goto done;
if (el) {
goto done;
if (!version) {
goto done;
goto done;
if (!allow_upgrade) {
goto done;
goto done;
goto done;
goto done;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
if (!msg) {
goto done;
goto done;
goto done;
goto done;
done:
return ret;
const char *alt_db_path,
bool allow_upgrade,
int ret;
if (!ctx_list) {
return ENOMEM;
if (alt_db_path) {
return ENOMEM;
return ret;
if (allow_upgrade) {
return ret;
struct sysdb_ctx *,
return ENOMEM;
return ret;
return ENOENT;
return EOK;
const char *db_path,
return EOK;
return EOK;
return ENOENT;
struct ldb_message);
struct ldb_message);
const char *newname)
const char *dummy;
e = &(attrs->a[i]);
return EEXIST;
if (e != NULL) {
return ENOMEM;
return EOK;