diff options
Diffstat (limited to 'server/db')
-rw-r--r-- | server/db/sysdb.c | 1084 | ||||
-rw-r--r-- | server/db/sysdb.h | 87 | ||||
-rw-r--r-- | server/db/sysdb_internal.h | 2 | ||||
-rw-r--r-- | server/db/sysdb_sync.c | 880 |
4 files changed, 1087 insertions, 966 deletions
diff --git a/server/db/sysdb.c b/server/db/sysdb.c index 5a9d8f25..c4b040b6 100644 --- a/server/db/sysdb.c +++ b/server/db/sysdb.c @@ -27,7 +27,8 @@ struct sysdb_search_ctx { struct sysdb_ctx *dbctx; - const char *base_dn; + const char *domain; + bool legacy; sysdb_callback_t callback; void *ptr; struct ldb_result *res; @@ -114,7 +115,8 @@ static int get_gen_callback(struct ldb_request *req, } static struct sysdb_search_ctx *init_src_ctx(TALLOC_CTX *mem_ctx, - const char *base_dn, + const char *domain, + bool legacy, struct sysdb_ctx *ctx, sysdb_callback_t fn, void *ptr) @@ -126,7 +128,6 @@ static struct sysdb_search_ctx *init_src_ctx(TALLOC_CTX *mem_ctx, return NULL; } sctx->dbctx = ctx; - sctx->base_dn = base_dn; sctx->callback = fn; sctx->ptr = ptr; sctx->res = talloc_zero(sctx, struct ldb_result); @@ -134,6 +135,12 @@ static struct sysdb_search_ctx *init_src_ctx(TALLOC_CTX *mem_ctx, talloc_free(sctx); return NULL; } + sctx->domain = talloc_strdup(sctx, domain); + if (!sctx->domain) { + talloc_free(sctx); + return NULL; + } + sctx->legacy = legacy; return sctx; } @@ -146,11 +153,17 @@ static int pwd_search(struct sysdb_search_ctx *sctx, { static const char *attrs[] = SYSDB_PW_ATTRS; struct ldb_request *req; + struct ldb_dn *base_dn; int ret; + base_dn = ldb_dn_new_fmt(sctx, ctx->ldb, + SYSDB_TMPL_USER_BASE, sctx->domain); + if (!base_dn) { + return ENOMEM; + } + ret = ldb_build_search_req(&req, ctx->ldb, sctx, - ldb_dn_new(sctx, ctx->ldb, sctx->base_dn), - LDB_SCOPE_SUBTREE, + base_dn, LDB_SCOPE_SUBTREE, expression, attrs, NULL, sctx, get_gen_callback, NULL); @@ -171,22 +184,17 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, const char *name, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; - const char *base_dn; char *expression; - if (domain) { - base_dn = talloc_asprintf(mem_ctx, SYSDB_TMPL_USER_BASE, domain); - } else { - base_dn = SYSDB_BASE; - } - if (!base_dn) { - return ENOMEM; + if (!domain) { + return EINVAL; } - sctx = init_src_ctx(mem_ctx, base_dn, ctx, fn, ptr); + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } @@ -205,23 +213,18 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, uid_t uid, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; unsigned long int filter_uid = uid; - const char *base_dn; char *expression; - if (domain) { - base_dn = talloc_asprintf(mem_ctx, SYSDB_TMPL_USER_BASE, domain); - } else { - base_dn = SYSDB_BASE; - } - if (!base_dn) { - return ENOMEM; + if (!domain) { + return EINVAL; } - sctx = init_src_ctx(mem_ctx, base_dn, ctx, fn, ptr); + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } @@ -238,11 +241,17 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, int sysdb_enumpwent(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, + const char *domain, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; - sctx = init_src_ctx(mem_ctx, SYSDB_BASE, ctx, fn, ptr); + if (!domain) { + return EINVAL; + } + + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } @@ -267,6 +276,7 @@ static void get_members(void *ptr, int status, struct ldb_result *res) struct ldb_request *req; struct ldb_message *msg; struct ldb_result *ret_res; + struct ldb_dn *dn; static const char *attrs[] = SYSDB_GRPW_ATTRS; const char *expression; int ret, i; @@ -297,7 +307,8 @@ static void get_members(void *ptr, int status, struct ldb_result *res) return request_done(gmctx->ret_sctx); } - mem_sctx = init_src_ctx(gmctx, SYSDB_BASE, ctx, get_members, sctx); + mem_sctx = init_src_ctx(gmctx, sctx->domain, sctx->legacy, + ctx, get_members, sctx); if (!mem_sctx) { return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR); } @@ -325,9 +336,14 @@ static void get_members(void *ptr, int status, struct ldb_result *res) return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR); } + dn = ldb_dn_new_fmt(mem_sctx, ctx->ldb, + SYSDB_TMPL_USER_BASE, sctx->domain); + if (!dn) { + return request_error(gmctx->ret_sctx, LDB_ERR_OPERATIONS_ERROR); + } + ret = ldb_build_search_req(&req, ctx->ldb, mem_sctx, - ldb_dn_new(mem_sctx, ctx->ldb, sctx->base_dn), - LDB_SCOPE_SUBTREE, + dn, LDB_SCOPE_SUBTREE, expression, attrs, NULL, mem_sctx, get_gen_callback, NULL); @@ -419,7 +435,9 @@ static int get_grp_callback(struct ldb_request *req, /* re-use sctx to create a fake handler for the first call to * get_members() */ - sctx = init_src_ctx(gmctx, SYSDB_BASE, ctx, get_members, gmctx); + sctx = init_src_ctx(gmctx, + sctx->domain, sctx->legacy, + ctx, get_members, gmctx); get_members(sctx, LDB_SUCCESS, NULL); return LDB_SUCCESS; @@ -438,15 +456,28 @@ static int grp_search(struct sysdb_search_ctx *sctx, struct sysdb_ctx *ctx, const char *expression) { + ldb_request_callback_t callback; static const char *attrs[] = SYSDB_GRNAM_ATTRS; struct ldb_request *req; + struct ldb_dn *base_dn; int ret; + if (sctx->legacy) { + callback = get_gen_callback; + } else { + callback = get_grp_callback; + } + + base_dn = ldb_dn_new_fmt(sctx, ctx->ldb, + SYSDB_TMPL_GROUP_BASE, sctx->domain); + if (!base_dn) { + return ENOMEM; + } + ret = ldb_build_search_req(&req, ctx->ldb, sctx, - ldb_dn_new(sctx, ctx->ldb, sctx->base_dn), - LDB_SCOPE_SUBTREE, + base_dn, LDB_SCOPE_SUBTREE, expression, attrs, NULL, - sctx, get_grp_callback, + sctx, callback, NULL); if (ret != LDB_SUCCESS) { return sysdb_error_to_errno(ret); @@ -465,22 +496,17 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, const char *name, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; - const char *base_dn; char *expression; - if (domain) { - base_dn = talloc_asprintf(mem_ctx, SYSDB_TMPL_GROUP_BASE, domain); - } else { - base_dn = SYSDB_BASE; - } - if (!base_dn) { - return ENOMEM; + if (!domain) { + return EINVAL; } - sctx = init_src_ctx(mem_ctx, base_dn, ctx, fn, ptr); + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } @@ -499,23 +525,18 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, gid_t gid, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; unsigned long int filter_gid = gid; - const char *base_dn; char *expression; - if (domain) { - base_dn = talloc_asprintf(mem_ctx, SYSDB_TMPL_GROUP_BASE, domain); - } else { - base_dn = SYSDB_BASE; - } - if (!base_dn) { - return ENOMEM; + if (!domain) { + return EINVAL; } - sctx = init_src_ctx(mem_ctx, base_dn, ctx, fn, ptr); + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } @@ -532,11 +553,17 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx, int sysdb_enumgrent(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, + const char *domain, + bool legacy, sysdb_callback_t fn, void *ptr) { struct sysdb_search_ctx *sctx; - sctx = init_src_ctx(mem_ctx, SYSDB_BASE, ctx, fn, ptr); + if (!domain) { + return EINVAL; + } + + sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!sctx) { return ENOMEM; } @@ -544,6 +571,59 @@ int sysdb_enumgrent(TALLOC_CTX *mem_ctx, return grp_search(sctx, ctx, SYSDB_GRENT_FILTER); } +static void sysdb_initgr_legacy(void *ptr, int status, + struct ldb_result *res) +{ + struct sysdb_ctx *ctx; + struct sysdb_search_ctx *sctx; + char *expression; + struct ldb_request *req; + struct ldb_dn *base_dn; + static const char *attrs[] = SYSDB_INITGR_ATTRS; + const char *userid; + int ret; + + sctx = talloc_get_type(ptr, struct sysdb_search_ctx); + ctx = sctx->dbctx; + + if (res->count == 0) { + return request_done(sctx); + } + if (res->count > 1) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + userid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_PW_NAME, NULL); + if (!userid) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + expression = talloc_asprintf(sctx, SYSDB_INITGR_LEGACY_FILTER, userid); + if (!expression) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + base_dn = ldb_dn_new_fmt(sctx, ctx->ldb, + SYSDB_TMPL_GROUP_BASE, sctx->domain); + if (!base_dn) { + return request_error(sctx, LDB_ERR_OPERATIONS_ERROR); + } + + ret = ldb_build_search_req(&req, ctx->ldb, sctx, + base_dn, LDB_SCOPE_SUBTREE, + expression, attrs, NULL, + sctx, get_gen_callback, + NULL); + if (ret != LDB_SUCCESS) { + return request_error(sctx, ret); + } + + ret = ldb_request(ctx->ldb, req); + if (ret != LDB_SUCCESS) { + return request_error(sctx, ret); + } +} + static void sysdb_initgr_search(void *ptr, int status, struct ldb_result *res) { @@ -615,44 +695,54 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, const char *name, + bool legacy, sysdb_callback_t fn, void *ptr) { + sysdb_callback_t second_callback; static const char *attrs[] = SYSDB_PW_ATTRS; struct sysdb_search_ctx *ret_sctx; struct sysdb_search_ctx *sctx; - const char *base_dn; char *expression; struct ldb_request *req; + struct ldb_dn *base_dn; int ret; - if (domain) { - base_dn = talloc_asprintf(mem_ctx, SYSDB_TMPL_USER_BASE, domain); - } else { - base_dn = SYSDB_BASE; - } - if (!base_dn) { - return ENOMEM; + if (!domain) { + return EINVAL; } - ret_sctx = init_src_ctx(mem_ctx, SYSDB_BASE, ctx, fn, ptr); + ret_sctx = init_src_ctx(mem_ctx, domain, legacy, ctx, fn, ptr); if (!ret_sctx) { return ENOMEM; } - sctx = init_src_ctx(ret_sctx, base_dn, ctx, sysdb_initgr_search, ret_sctx); + + if (legacy) { + second_callback = sysdb_initgr_legacy; + } else { + second_callback = sysdb_initgr_search; + } + + sctx = init_src_ctx(ret_sctx, domain, legacy, + ctx, second_callback, ret_sctx); if (!sctx) { - talloc_free(sctx); + talloc_free(ret_sctx); return ENOMEM; } expression = talloc_asprintf(sctx, SYSDB_PWNAM_FILTER, name); if (!expression) { - talloc_free(sctx); + talloc_free(ret_sctx); + return ENOMEM; + } + + base_dn = ldb_dn_new_fmt(sctx, ctx->ldb, SYSDB_TMPL_USER_BASE, domain); + if (!base_dn) { + talloc_free(ret_sctx); return ENOMEM; } ret = ldb_build_search_req(&req, ctx->ldb, sctx, - ldb_dn_new(sctx, ctx->ldb, sctx->base_dn), - LDB_SCOPE_SUBTREE, + base_dn, LDB_SCOPE_SUBTREE, expression, attrs, NULL, sctx, get_gen_callback, NULL); @@ -721,872 +811,6 @@ done: return ret; } -/* the following are all SYNCHRONOUS calls - * TODO: make these asynchronous */ - -int sysdb_add_group_member(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - struct ldb_dn *member_dn, - struct ldb_dn *group_dn) -{ - TALLOC_CTX *tmp_ctx; - int ret, lret; - struct ldb_message *msg; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) return ENOMEM; - - /* Add the member_dn as a member of the group */ - msg = ldb_msg_new(tmp_ctx); - if(msg == NULL) { - ret = ENOMEM; - goto done; - } - msg->dn = group_dn; - lret = ldb_msg_add_empty(msg, SYSDB_GR_MEMBER, - LDB_FLAG_MOD_ADD, NULL); - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, "%s", - ldb_dn_get_linearized(member_dn)); - if (lret != LDB_SUCCESS) { - ret = EINVAL; - goto done; - } - - lret = ldb_modify(sysdb->ldb, msg); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_remove_group_member(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - struct ldb_dn *member_dn, - struct ldb_dn *group_dn) -{ - TALLOC_CTX *tmp_ctx; - int ret, lret; - struct ldb_message *msg; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) return ENOMEM; - - /* Add the member_dn as a member of the group */ - msg = ldb_msg_new(tmp_ctx); - if(msg == NULL) { - ret = ENOMEM; - goto done; - } - msg->dn = group_dn; - lret = ldb_msg_add_empty(msg, SYSDB_GR_MEMBER, - LDB_FLAG_MOD_DELETE, NULL); - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, "%s", - ldb_dn_get_linearized(member_dn)); - if (lret != LDB_SUCCESS) { - ret = EINVAL; - goto done; - } - - lret = ldb_modify(sysdb->ldb, msg); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - talloc_free(tmp_ctx); - return ret; -} - -/* "sysdb_posix_" functions - * the set of functions named sysdb_posix_* are used by modules - * that only have access to strictly posix like databases where - * user and groups names are retrieved as strings, groups can't - * be nested and can't reference foreign sources */ - -int sysdb_posix_store_user(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *name, const char *pwd, - uid_t uid, gid_t gid, const char *gecos, - const char *homedir, const char *shell) -{ - TALLOC_CTX *tmp_ctx; - const char *attrs[] = { SYSDB_PW_NAME, NULL }; - struct ldb_dn *user_dn; - struct ldb_message *msg; - struct ldb_request *req; - struct ldb_result *res; - int lret, ret; - int flags; - - tmp_ctx = talloc_new(memctx); - if (!tmp_ctx) { - return ENOMEM; - } - - user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, - name, domain); - if (!user_dn) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - lret = ldb_transaction_start(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); - ret = EIO; - goto done; - } - - lret = ldb_search(sysdb->ldb, tmp_ctx, &res, user_dn, - LDB_SCOPE_BASE, attrs, SYSDB_PWENT_FILTER); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - req = NULL; - - msg = ldb_msg_new(tmp_ctx); - if (!msg) { - ret = ENOMEM; - goto done; - } - msg->dn = user_dn; - - switch (res->count) { - case 0: - flags = LDB_FLAG_MOD_ADD; - break; - case 1: - flags = LDB_FLAG_MOD_REPLACE; - break; - default: - DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", - res->count)); - ret = EIO; - goto done; - } - - talloc_free(res); - res = NULL; - - if (flags == LDB_FLAG_MOD_ADD) { - /* TODO: retrieve user objectclass list from configuration */ - lret = ldb_msg_add_empty(msg, "objectClass", flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, "objectClass", "user"); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* TODO: retrieve user name attribute from configuration */ - lret = ldb_msg_add_empty(msg, SYSDB_PW_NAME, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, SYSDB_PW_NAME, name); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - } - - /* TODO: retrieve attribute name mappings from configuration */ - - /* pwd */ - if (pwd && *pwd) { - lret = ldb_msg_add_empty(msg, SYSDB_PW_PWD, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, SYSDB_PW_PWD, pwd); - } - } else { - lret = ldb_msg_add_empty(msg, SYSDB_PW_PWD, - LDB_FLAG_MOD_DELETE, NULL); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* uid */ - if (uid) { - lret = ldb_msg_add_empty(msg, SYSDB_PW_UIDNUM, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_fmt(msg, SYSDB_PW_UIDNUM, - "%lu", (unsigned long)uid); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - } else { - DEBUG(0, ("Cached users can't have UID == 0\n")); - ret = EINVAL; - goto done; - } - - /* gid */ - if (gid) { - lret = ldb_msg_add_empty(msg, SYSDB_PW_GIDNUM, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_fmt(msg, SYSDB_PW_GIDNUM, - "%lu", (unsigned long)gid); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - } else { - DEBUG(0, ("Cached users can't have GID == 0\n")); - ret = EINVAL; - goto done; - } - - /* gecos */ - if (gecos && *gecos) { - lret = ldb_msg_add_empty(msg, SYSDB_PW_FULLNAME, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, SYSDB_PW_FULLNAME, gecos); - } - } else { - lret = ldb_msg_add_empty(msg, SYSDB_PW_FULLNAME, - LDB_FLAG_MOD_DELETE, NULL); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* homedir */ - if (homedir && *homedir) { - lret = ldb_msg_add_empty(msg, SYSDB_PW_HOMEDIR, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, SYSDB_PW_HOMEDIR, homedir); - } - } else { - lret = ldb_msg_add_empty(msg, SYSDB_PW_HOMEDIR, - LDB_FLAG_MOD_DELETE, NULL); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* shell */ - if (shell && *shell) { - lret = ldb_msg_add_empty(msg, SYSDB_PW_SHELL, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, SYSDB_PW_SHELL, shell); - } - } else { - lret = ldb_msg_add_empty(msg, SYSDB_PW_SHELL, - LDB_FLAG_MOD_DELETE, NULL); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* modification time */ - lret = ldb_msg_add_empty(msg, SYSDB_LAST_UPDATE, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_fmt(msg, SYSDB_LAST_UPDATE, - "%ld", (long int)time(NULL)); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - if (flags == LDB_FLAG_MOD_ADD) { - lret = ldb_build_add_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, - NULL, ldb_op_default_callback, NULL); - } else { - lret = ldb_build_mod_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, - NULL, ldb_op_default_callback, NULL); - } - if (lret == LDB_SUCCESS) { - lret = ldb_request(sysdb->ldb, req); - if (lret == LDB_SUCCESS) { - lret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - } - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - if (ret == EOK) { - lret = ldb_transaction_commit(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); - ret = EIO; - } - } else { - lret = ldb_transaction_cancel(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); - ret = EIO; - } - } - - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_posix_remove_user(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, const char *name) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_dn *user_dn; - int lret, ret = EOK; - - tmp_ctx = talloc_new(memctx); - if (!tmp_ctx) { - return ENOMEM; - } - - user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, - name, domain); - if (!user_dn) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - lret = ldb_delete(sysdb->ldb, user_dn); - - if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { - DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); - ret = EIO; - } - - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_posix_remove_user_by_uid(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, uid_t uid) -{ - TALLOC_CTX *tmp_ctx; - const char *attrs[] = { SYSDB_PW_NAME, SYSDB_PW_UIDNUM, NULL }; - struct ldb_dn *base_dn; - struct ldb_dn *user_dn; - struct ldb_result *res; - int lret, ret; - - tmp_ctx = talloc_new(memctx); - if (!tmp_ctx) { - return ENOMEM; - } - - base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_TMPL_USER_BASE, domain); - if (!base_dn) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - lret = ldb_transaction_start(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); - ret = EIO; - goto done; - } - - lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, - LDB_SCOPE_ONELEVEL, attrs, - SYSDB_PWUID_FILTER, - (unsigned long)uid); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - if (res->count == 0) { - DEBUG(0, ("Base search returned no results\n")); - ret = EOK; - goto done; - } - if (res->count > 1) { - DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", - res->count)); - ret = EIO; - goto done; - } - - user_dn = ldb_dn_copy(tmp_ctx, res->msgs[0]->dn); - if (!user_dn) { - ret = ENOMEM; - goto done; - } - - talloc_free(res); - res = NULL; - - lret = ldb_delete(sysdb->ldb, user_dn); - - if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { - DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - if (ret == EOK) { - lret = ldb_transaction_commit(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction commit !! (%d)\n", lret)); - ret = EIO; - } - } else { - lret = ldb_transaction_cancel(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); - ret = EIO; - } - } - - talloc_free(tmp_ctx); - return ret; -} - -/* this function does not check that all user members are actually present, - * the caller must verify the members list is valid and exists in the - * database before calling this function */ - -int sysdb_posix_store_group(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *name, gid_t gid, - char **members) -{ - TALLOC_CTX *tmp_ctx; - const char *attrs[] = { SYSDB_GR_NAME, NULL }; - struct ldb_dn *group_dn; - struct ldb_result *res; - struct ldb_request *req; - struct ldb_message *msg; - int i, ret, lret; - int flags; - - tmp_ctx = talloc_new(memctx); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, - name, domain); - if (group_dn == NULL) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - /* Start a transaction to ensure that nothing changes - * underneath us while we're working - */ - lret = ldb_transaction_start(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); - talloc_free(tmp_ctx); - return EIO; - } - - /* Determine if the group already exists */ - lret = ldb_search(sysdb->ldb, tmp_ctx, &res, group_dn, - LDB_SCOPE_BASE, attrs, SYSDB_GRENT_FILTER); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make search request: %s(%d)[%s]\b", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - req = NULL; - - switch(res->count) { - case 0: - flags = LDB_FLAG_MOD_ADD; - DEBUG(7, ("Adding new entry\n")); - break; - case 1: - flags = LDB_FLAG_MOD_REPLACE; - DEBUG(7, ("Replacing existing entry\n")); - break; - default: - DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", - res->count)); - ret = EIO; - goto done; - } - talloc_free(res); - res = NULL; - - /* Set up the add/replace request */ - msg = ldb_msg_new(tmp_ctx); - if (msg == NULL) { - ret = ENOMEM; - goto done; - } - msg->dn = group_dn; - - if (flags == LDB_FLAG_MOD_ADD) { - lret = ldb_msg_add_empty(msg, "objectClass", flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, "objectClass", "group"); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - lret = ldb_msg_add_empty(msg, SYSDB_GR_NAME, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_string(msg, SYSDB_GR_NAME, name); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - } - - /* gid */ - if (gid) { - lret = ldb_msg_add_empty(msg, SYSDB_GR_GIDNUM, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_fmt(msg, SYSDB_GR_GIDNUM, - "%lu", (unsigned long)gid); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - } else { - DEBUG(0, ("Cached groups can't have GID == 0\n")); - ret = EINVAL; - goto done; - } - - /* modification time */ - lret = ldb_msg_add_empty(msg, SYSDB_LAST_UPDATE, flags, NULL); - if (lret == LDB_SUCCESS) { - lret = ldb_msg_add_fmt(msg, SYSDB_LAST_UPDATE, - "%ld", (long int)time(NULL)); - } - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - - /* members */ - if (members && members[0]) { - lret = ldb_msg_add_empty(msg, SYSDB_GR_MEMBER, flags, NULL); - if (lret != LDB_SUCCESS) { - ret = ENOMEM; - goto done; - } - for (i = 0; members[i]; i++) { - lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, - "uid=%s,"SYSDB_TMPL_USER_BASE, - members[i], domain); - } - } - - if (flags == LDB_FLAG_MOD_ADD) { - lret = ldb_build_add_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, - NULL, ldb_op_default_callback, NULL); - } else { - lret = ldb_build_mod_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, - NULL, ldb_op_default_callback, NULL); - } - if (lret == LDB_SUCCESS) { - lret = ldb_request(sysdb->ldb, req); - if (lret == LDB_SUCCESS) { - lret = ldb_wait(req->handle, LDB_WAIT_ALL); - } - } - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - if (ret == EOK) { - lret = ldb_transaction_commit(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); - ret = EIO; - } - } else { - lret = ldb_transaction_cancel(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); - ret = EIO; - } - } - talloc_free(tmp_ctx); - return ret; -} - -/* Wrapper around adding a user to a POSIX group */ -int sysdb_posix_add_user_to_group(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *group, - const char *username) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_dn *user_dn; - struct ldb_dn *group_dn; - - - if (!sysdb || !domain || !group || !username) { - return EINVAL; - } - - tmp_ctx = talloc_new(mem_ctx); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, - username, domain); - if (!user_dn) { - ret = ENOMEM; - goto done; - } - - group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, - group, domain); - if (group_dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_add_group_member(tmp_ctx, sysdb, user_dn, group_dn); - -done: - talloc_free(tmp_ctx); - return ret; -} - -/* Wrapper around adding a user to a POSIX group */ -int sysdb_posix_remove_user_from_group(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *group, - const char *username) -{ - TALLOC_CTX *tmp_ctx; - int ret; - struct ldb_dn *user_dn; - struct ldb_dn *group_dn; - - - if (!sysdb || !domain || !group || !username) { - return EINVAL; - } - - tmp_ctx = talloc_new(mem_ctx); - if (tmp_ctx == NULL) { - return ENOMEM; - } - - user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, - username, domain); - if (!user_dn) { - ret = ENOMEM; - goto done; - } - - group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, - group, domain); - if (group_dn == NULL) { - ret = ENOMEM; - goto done; - } - - ret = sysdb_remove_group_member(tmp_ctx, sysdb, user_dn, group_dn); - -done: - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_posix_remove_group(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, const char *name) -{ - TALLOC_CTX *tmp_ctx; - struct ldb_dn *group_dn; - int lret, ret = EOK; - - tmp_ctx = talloc_new(memctx); - if (!tmp_ctx) { - return ENOMEM; - } - - group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, - name, domain); - if (!group_dn) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - lret = ldb_delete(sysdb->ldb, group_dn); - - if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { - DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); - ret = EIO; - } - - talloc_free(tmp_ctx); - return ret; -} - -int sysdb_posix_remove_group_by_gid(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, gid_t gid) -{ - TALLOC_CTX *tmp_ctx; - const char *attrs[] = { SYSDB_GR_NAME, SYSDB_GR_GIDNUM, NULL }; - struct ldb_dn *base_dn; - struct ldb_dn *group_dn; - struct ldb_result *res; - int lret, ret; - - tmp_ctx = talloc_new(memctx); - if (!tmp_ctx) { - return ENOMEM; - } - - base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, - SYSDB_TMPL_GROUP_BASE, domain); - if (!base_dn) { - talloc_free(tmp_ctx); - return ENOMEM; - } - - lret = ldb_transaction_start(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); - ret = EIO; - goto done; - } - - lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, - LDB_SCOPE_ONELEVEL, attrs, - SYSDB_GRGID_FILTER, - (unsigned long)gid); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n", - ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - if (res->count == 0) { - DEBUG(0, ("Base search returned no results\n")); - ret = EOK; - goto done; - } - if (res->count > 1) { - DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", - res->count)); - ret = EIO; - goto done; - } - - group_dn = ldb_dn_copy(tmp_ctx, res->msgs[0]->dn); - if (!group_dn) { - ret = ENOMEM; - goto done; - } - - talloc_free(res); - res = NULL; - - lret = ldb_delete(sysdb->ldb, group_dn); - - if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { - DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", - ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); - ret = EIO; - goto done; - } - - ret = EOK; - -done: - if (ret == EOK) { - lret = ldb_transaction_commit(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed ldb transaction commit !! (%d)\n", lret)); - ret = EIO; - } - } else { - lret = ldb_transaction_cancel(sysdb->ldb); - if (lret != LDB_SUCCESS) { - DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); - ret = EIO; - } - } - - talloc_free(tmp_ctx); - return ret; -} - static int sysdb_check_init(struct sysdb_ctx *ctx) { TALLOC_CTX *tmp_ctx; diff --git a/server/db/sysdb.h b/server/db/sysdb.h index 7b285721..e0dd3349 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -29,6 +29,7 @@ #define SYSDB_FILE "sssd.ldb" #define SYSDB_BASE "cn=sysdb" +#define SYSDB_DOM_BASE "cn=%s,cn=sysdb" #define SYSDB_TMPL_USER_BASE "cn=users,cn=%s,"SYSDB_BASE #define SYSDB_TMPL_GROUP_BASE "cn=groups,cn=%s,"SYSDB_BASE @@ -36,13 +37,15 @@ #define SYSDB_PWUID_FILTER "(&(objectclass=user)(uidNumber=%lu))" #define SYSDB_PWENT_FILTER "(objectclass=user)" -#define SYSDB_GRNAM_FILTER "(&(objectclass=group)(cn=%s))" +#define SYSDB_GRNAM_FILTER "(&(objectclass=group)(gid=%s))" #define SYSDB_GRNA2_FILTER "(&(objectclass=user)(memberof=%s))" #define SYSDB_GRGID_FILTER "(&(objectclass=group)(gidNumber=%lu))" #define SYSDB_GRENT_FILTER "(objectclass=group)" #define SYSDB_INITGR_FILTER "(&(objectclass=group)(gidNumber=*))" +#define SYSDB_INITGR_LEGACY_FILTER "(&(objectclass=group)(memberUid=%s))" + #define SYSDB_PW_NAME "uid" #define SYSDB_PW_PWD "userPassword" #define SYSDB_PW_UIDNUM "uidNumber" @@ -52,9 +55,10 @@ #define SYSDB_PW_SHELL "loginShell" #define SYSDB_PW_MEMBEROF "memberOf" -#define SYSDB_GR_NAME "cn" +#define SYSDB_GR_NAME "gid" #define SYSDB_GR_GIDNUM "gidNumber" #define SYSDB_GR_MEMBER "member" +#define SYSDB_LEGACY_MEMBER "memberUid" #define SYSDB_LAST_UPDATE "lastUpdate" @@ -64,7 +68,7 @@ SYSDB_LAST_UPDATE, \ NULL} #define SYSDB_GRNAM_ATTRS {SYSDB_GR_NAME, SYSDB_GR_GIDNUM, \ - SYSDB_LAST_UPDATE, \ + SYSDB_LAST_UPDATE, SYSDB_LEGACY_MEMBER, \ NULL} #define SYSDB_GRPW_ATTRS {SYSDB_PW_NAME, SYSDB_LAST_UPDATE, \ NULL} @@ -93,6 +97,7 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, const char *name, + bool legacy, sysdb_callback_t fn, void *ptr); int sysdb_getpwuid(TALLOC_CTX *mem_ctx, @@ -100,11 +105,14 @@ int sysdb_getpwuid(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, uid_t uid, + bool legacy, sysdb_callback_t fn, void *ptr); int sysdb_enumpwent(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, + const char *domain, + bool legacy, sysdb_callback_t fn, void *ptr); int sysdb_getgrnam(TALLOC_CTX *mem_ctx, @@ -112,6 +120,7 @@ int sysdb_getgrnam(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, const char *name, + bool legacy, sysdb_callback_t fn, void *ptr); int sysdb_getgrgid(TALLOC_CTX *mem_ctx, @@ -119,11 +128,14 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, gid_t gid, + bool legacy, sysdb_callback_t fn, void *ptr); int sysdb_enumgrent(TALLOC_CTX *mem_ctx, struct event_context *ev, struct sysdb_ctx *ctx, + const char *domain, + bool legacy, sysdb_callback_t fn, void *ptr); int sysdb_initgroups(TALLOC_CTX *mem_ctx, @@ -131,6 +143,7 @@ int sysdb_initgroups(TALLOC_CTX *mem_ctx, struct sysdb_ctx *ctx, const char *domain, const char *name, + bool legacy, sysdb_callback_t fn, void *ptr); @@ -147,45 +160,47 @@ int sysdb_remove_group_member(TALLOC_CTX *mem_ctx, struct ldb_dn *member_dn, struct ldb_dn *group_dn); -int sysdb_posix_store_user(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *name, const char *pwd, - uid_t uid, gid_t gid, const char *gecos, - const char *homedir, const char *shell); +int sysdb_delete_user(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, const char *name); + +int sysdb_delete_user_by_uid(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, uid_t uid); -int sysdb_posix_remove_user(TALLOC_CTX *memctx, +int sysdb_add_user_to_group(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - const char *domain, const char *name); + const char *domain, + const char *group, + const char *username); + +int sysdb_remove_user_from_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *group, + const char *username); -int sysdb_posix_remove_user_by_uid(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, uid_t uid); +int sysdb_delete_group(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, const char *name); -int sysdb_posix_store_group(TALLOC_CTX *memctx, +int sysdb_delete_group_by_gid(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, gid_t gid); + +/* legacy synchronous functions for proxy providers */ + +int sysdb_legacy_store_user(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, const char *domain, - const char *name, gid_t gid, - char **members); - -int sysdb_posix_add_user_to_group(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *group, - const char *username); - -int sysdb_posix_remove_user_from_group(TALLOC_CTX *mem_ctx, - struct sysdb_ctx *sysdb, - const char *domain, - const char *group, - const char *username); - -int sysdb_posix_remove_group(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, const char *name); + const char *name, const char *pwd, + uid_t uid, gid_t gid, const char *gecos, + const char *homedir, const char *shell); -int sysdb_posix_remove_group_by_gid(TALLOC_CTX *memctx, - struct sysdb_ctx *sysdb, - const char *domain, gid_t gid); +int sysdb_legacy_store_group(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *name, gid_t gid, + char **members); #endif /* __SYS_DB_H__ */ diff --git a/server/db/sysdb_internal.h b/server/db/sysdb_internal.h index 5757e847..719f6606 100644 --- a/server/db/sysdb_internal.h +++ b/server/db/sysdb_internal.h @@ -39,7 +39,9 @@ "@IDXATTR: objectclass\n" \ "@IDXATTR: member\n" \ "@IDXATTR: memberof\n" \ + "@IDXATTR: memberuid\n" \ "@IDXATTR: uid\n" \ + "@IDXATTR: gid\n" \ "@IDXATTR: uidNumber\n" \ "@IDXATTR: gidNumber\n" \ "@IDXATTR: lastUpdate\n" \ diff --git a/server/db/sysdb_sync.c b/server/db/sysdb_sync.c new file mode 100644 index 00000000..f2c992fc --- /dev/null +++ b/server/db/sysdb_sync.c @@ -0,0 +1,880 @@ +/* + 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.h" +#include <time.h> + +/* the following are all SYNCHRONOUS calls + * TODO: make these asynchronous */ + +int sysdb_add_group_member(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct ldb_dn *member_dn, + struct ldb_dn *group_dn) +{ + TALLOC_CTX *tmp_ctx; + int ret, lret; + struct ldb_message *msg; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) return ENOMEM; + + /* Add the member_dn as a member of the group */ + msg = ldb_msg_new(tmp_ctx); + if(msg == NULL) { + ret = ENOMEM; + goto done; + } + msg->dn = group_dn; + lret = ldb_msg_add_empty(msg, SYSDB_GR_MEMBER, + LDB_FLAG_MOD_ADD, NULL); + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, "%s", + ldb_dn_get_linearized(member_dn)); + if (lret != LDB_SUCCESS) { + ret = EINVAL; + goto done; + } + + lret = ldb_modify(sysdb->ldb, msg); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_remove_group_member(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct ldb_dn *member_dn, + struct ldb_dn *group_dn) +{ + TALLOC_CTX *tmp_ctx; + int ret, lret; + struct ldb_message *msg; + + tmp_ctx = talloc_new(mem_ctx); + if (!tmp_ctx) return ENOMEM; + + /* Add the member_dn as a member of the group */ + msg = ldb_msg_new(tmp_ctx); + if(msg == NULL) { + ret = ENOMEM; + goto done; + } + msg->dn = group_dn; + lret = ldb_msg_add_empty(msg, SYSDB_GR_MEMBER, + LDB_FLAG_MOD_DELETE, NULL); + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + lret = ldb_msg_add_fmt(msg, SYSDB_GR_MEMBER, "%s", + ldb_dn_get_linearized(member_dn)); + if (lret != LDB_SUCCESS) { + ret = EINVAL; + goto done; + } + + lret = ldb_modify(sysdb->ldb, msg); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +/* "sysdb_legacy_" functions + * the set of functions named sysdb_legacy_* are used by modules + * that only have access to strictly posix like databases where + * user and groups names are retrieved as strings, groups can't + * be nested and can't reference foreign sources */ + +int sysdb_legacy_store_user(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *name, const char *pwd, + uid_t uid, gid_t gid, const char *gecos, + const char *homedir, const char *shell) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { SYSDB_PW_NAME, NULL }; + struct ldb_dn *user_dn; + struct ldb_message *msg; + struct ldb_request *req; + struct ldb_result *res; + int lret, ret; + int flags; + + tmp_ctx = talloc_new(memctx); + if (!tmp_ctx) { + return ENOMEM; + } + + user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, + name, domain); + if (!user_dn) { + talloc_free(tmp_ctx); + return ENOMEM; + } + + lret = ldb_transaction_start(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + ret = EIO; + goto done; + } + + lret = ldb_search(sysdb->ldb, tmp_ctx, &res, user_dn, + LDB_SCOPE_BASE, attrs, SYSDB_PWENT_FILTER); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + req = NULL; + + msg = ldb_msg_new(tmp_ctx); + if (!msg) { + ret = ENOMEM; + goto done; + } + msg->dn = user_dn; + + switch (res->count) { + case 0: + flags = LDB_FLAG_MOD_ADD; + break; + case 1: + flags = LDB_FLAG_MOD_REPLACE; + break; + default: + DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", + res->count)); + ret = EIO; + goto done; + } + + talloc_free(res); + res = NULL; + + if (flags == LDB_FLAG_MOD_ADD) { + /* TODO: retrieve user objectclass list from configuration */ + lret = ldb_msg_add_empty(msg, "objectClass", flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, "objectClass", "user"); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* TODO: retrieve user name attribute from configuration */ + lret = ldb_msg_add_empty(msg, SYSDB_PW_NAME, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_PW_NAME, name); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + } + + /* TODO: retrieve attribute name mappings from configuration */ + + /* pwd */ + if (pwd && *pwd) { + lret = ldb_msg_add_empty(msg, SYSDB_PW_PWD, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_PW_PWD, pwd); + } + } else { + lret = ldb_msg_add_empty(msg, SYSDB_PW_PWD, + LDB_FLAG_MOD_DELETE, NULL); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* uid */ + if (uid) { + lret = ldb_msg_add_empty(msg, SYSDB_PW_UIDNUM, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_PW_UIDNUM, + "%lu", (unsigned long)uid); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + } else { + DEBUG(0, ("Cached users can't have UID == 0\n")); + ret = EINVAL; + goto done; + } + + /* gid */ + if (gid) { + lret = ldb_msg_add_empty(msg, SYSDB_PW_GIDNUM, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_PW_GIDNUM, + "%lu", (unsigned long)gid); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + } else { + DEBUG(0, ("Cached users can't have GID == 0\n")); + ret = EINVAL; + goto done; + } + + /* gecos */ + if (gecos && *gecos) { + lret = ldb_msg_add_empty(msg, SYSDB_PW_FULLNAME, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_PW_FULLNAME, gecos); + } + } else { + lret = ldb_msg_add_empty(msg, SYSDB_PW_FULLNAME, + LDB_FLAG_MOD_DELETE, NULL); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* homedir */ + if (homedir && *homedir) { + lret = ldb_msg_add_empty(msg, SYSDB_PW_HOMEDIR, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_PW_HOMEDIR, homedir); + } + } else { + lret = ldb_msg_add_empty(msg, SYSDB_PW_HOMEDIR, + LDB_FLAG_MOD_DELETE, NULL); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* shell */ + if (shell && *shell) { + lret = ldb_msg_add_empty(msg, SYSDB_PW_SHELL, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_PW_SHELL, shell); + } + } else { + lret = ldb_msg_add_empty(msg, SYSDB_PW_SHELL, + LDB_FLAG_MOD_DELETE, NULL); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* modification time */ + lret = ldb_msg_add_empty(msg, SYSDB_LAST_UPDATE, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_LAST_UPDATE, + "%ld", (long int)time(NULL)); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + if (flags == LDB_FLAG_MOD_ADD) { + lret = ldb_build_add_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, + NULL, ldb_op_default_callback, NULL); + } else { + lret = ldb_build_mod_req(&req, sysdb->ldb, tmp_ctx, msg, NULL, + NULL, ldb_op_default_callback, NULL); + } + if (lret == LDB_SUCCESS) { + lret = ldb_request(sysdb->ldb, req); + if (lret == LDB_SUCCESS) { + lret = ldb_wait(req->handle, LDB_WAIT_ALL); + } + } + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + if (ret == EOK) { + lret = ldb_transaction_commit(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + ret = EIO; + } + } else { + lret = ldb_transaction_cancel(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); + ret = EIO; + } + } + + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_delete_user(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, const char *name) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *user_dn; + int lret, ret = EOK; + + tmp_ctx = talloc_new(memctx); + if (!tmp_ctx) { + return ENOMEM; + } + + user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, + name, domain); + if (!user_dn) { + talloc_free(tmp_ctx); + return ENOMEM; + } + + lret = ldb_delete(sysdb->ldb, user_dn); + + if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { + DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); + ret = EIO; + } + + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_delete_user_by_uid(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, uid_t uid) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { SYSDB_PW_NAME, SYSDB_PW_UIDNUM, NULL }; + struct ldb_dn *base_dn; + struct ldb_dn *user_dn; + struct ldb_result *res; + int lret, ret; + + tmp_ctx = talloc_new(memctx); + if (!tmp_ctx) { + return ENOMEM; + } + + base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_TMPL_USER_BASE, domain); + if (!base_dn) { + talloc_free(tmp_ctx); + return ENOMEM; + } + + lret = ldb_transaction_start(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + ret = EIO; + goto done; + } + + lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, + LDB_SCOPE_ONELEVEL, attrs, + SYSDB_PWUID_FILTER, + (unsigned long)uid); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + if (res->count == 0) { + DEBUG(7, ("Base search returned no results\n")); + ret = EOK; + goto done; + } + if (res->count > 1) { + DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", + res->count)); + ret = EIO; + goto done; + } + + user_dn = ldb_dn_copy(tmp_ctx, res->msgs[0]->dn); + if (!user_dn) { + ret = ENOMEM; + goto done; + } + + talloc_free(res); + res = NULL; + + lret = ldb_delete(sysdb->ldb, user_dn); + + if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { + DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + if (ret == EOK) { + lret = ldb_transaction_commit(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction commit !! (%d)\n", lret)); + ret = EIO; + } + } else { + lret = ldb_transaction_cancel(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); + ret = EIO; + } + } + + talloc_free(tmp_ctx); + return ret; +} + +/* this function does not check that all user members are actually present */ + +int sysdb_legacy_store_group(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *name, gid_t gid, + char **members) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { SYSDB_GR_NAME, NULL }; + struct ldb_dn *group_dn; + struct ldb_result *res; + struct ldb_message *msg; + int i, ret, lret; + int flags; + + tmp_ctx = talloc_new(memctx); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + name, domain); + if (group_dn == NULL) { + talloc_free(tmp_ctx); + return ENOMEM; + } + + /* Start a transaction to ensure that nothing changes + * underneath us while we're working + */ + lret = ldb_transaction_start(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + talloc_free(tmp_ctx); + return EIO; + } + + /* Determine if the group already exists */ + lret = ldb_search(sysdb->ldb, tmp_ctx, &res, group_dn, + LDB_SCOPE_BASE, attrs, SYSDB_GRENT_FILTER); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make search request: %s(%d)[%s]\b", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + switch(res->count) { + case 0: + flags = LDB_FLAG_MOD_ADD; + DEBUG(7, ("Adding new entry\n")); + break; + case 1: + flags = LDB_FLAG_MOD_REPLACE; + DEBUG(7, ("Replacing existing entry\n")); + break; + default: + DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", + res->count)); + ret = EIO; + goto done; + } + talloc_free(res); + res = NULL; + + /* Set up the add/replace request */ + msg = ldb_msg_new(tmp_ctx); + if (msg == NULL) { + ret = ENOMEM; + goto done; + } + msg->dn = group_dn; + + if (flags == LDB_FLAG_MOD_ADD) { + lret = ldb_msg_add_empty(msg, "objectClass", flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, "objectClass", "group"); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + lret = ldb_msg_add_empty(msg, SYSDB_GR_NAME, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_string(msg, SYSDB_GR_NAME, name); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + } + + /* gid */ + if (gid) { + lret = ldb_msg_add_empty(msg, SYSDB_GR_GIDNUM, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_GR_GIDNUM, + "%lu", (unsigned long)gid); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + } else { + DEBUG(0, ("Cached groups can't have GID == 0\n")); + ret = EINVAL; + goto done; + } + + /* modification time */ + lret = ldb_msg_add_empty(msg, SYSDB_LAST_UPDATE, flags, NULL); + if (lret == LDB_SUCCESS) { + lret = ldb_msg_add_fmt(msg, SYSDB_LAST_UPDATE, + "%ld", (long int)time(NULL)); + } + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + + /* members */ + if (members && members[0]) { + lret = ldb_msg_add_empty(msg, SYSDB_LEGACY_MEMBER, flags, NULL); + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + for (i = 0; members[i]; i++) { + lret = ldb_msg_add_string(msg, SYSDB_LEGACY_MEMBER, members[i]); + if (lret != LDB_SUCCESS) { + ret = ENOMEM; + goto done; + } + } + } + + if (flags == LDB_FLAG_MOD_ADD) { + lret = ldb_add(sysdb->ldb, msg); + } else { + lret = ldb_modify(sysdb->ldb, msg); + } + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make modify request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + if (ret == EOK) { + lret = ldb_transaction_commit(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + ret = EIO; + } + } else { + lret = ldb_transaction_cancel(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); + ret = EIO; + } + } + talloc_free(tmp_ctx); + return ret; +} + +/* Wrapper around adding a user to a POSIX group */ +int sysdb_add_user_to_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *group, + const char *username) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_dn *user_dn; + struct ldb_dn *group_dn; + + + if (!sysdb || !domain || !group || !username) { + return EINVAL; + } + + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, + username, domain); + if (!user_dn) { + ret = ENOMEM; + goto done; + } + + group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + group, domain); + if (group_dn == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_add_group_member(tmp_ctx, sysdb, user_dn, group_dn); + +done: + talloc_free(tmp_ctx); + return ret; +} + +/* Wrapper around adding a user to a POSIX group */ +int sysdb_remove_user_from_group(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + const char *domain, + const char *group, + const char *username) +{ + TALLOC_CTX *tmp_ctx; + int ret; + struct ldb_dn *user_dn; + struct ldb_dn *group_dn; + + + if (!sysdb || !domain || !group || !username) { + return EINVAL; + } + + tmp_ctx = talloc_new(mem_ctx); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + user_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_PW_NAME"=%s,"SYSDB_TMPL_USER_BASE, + username, domain); + if (!user_dn) { + ret = ENOMEM; + goto done; + } + + group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + group, domain); + if (group_dn == NULL) { + ret = ENOMEM; + goto done; + } + + ret = sysdb_remove_group_member(tmp_ctx, sysdb, user_dn, group_dn); + +done: + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_delete_group(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, const char *name) +{ + TALLOC_CTX *tmp_ctx; + struct ldb_dn *group_dn; + int lret, ret = EOK; + + tmp_ctx = talloc_new(memctx); + if (!tmp_ctx) { + return ENOMEM; + } + + group_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_GR_NAME"=%s,"SYSDB_TMPL_GROUP_BASE, + name, domain); + if (!group_dn) { + talloc_free(tmp_ctx); + return ENOMEM; + } + + lret = ldb_delete(sysdb->ldb, group_dn); + + if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { + DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); + ret = EIO; + } + + talloc_free(tmp_ctx); + return ret; +} + +int sysdb_delete_group_by_gid(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + const char *domain, gid_t gid) +{ + TALLOC_CTX *tmp_ctx; + const char *attrs[] = { SYSDB_GR_NAME, SYSDB_GR_GIDNUM, NULL }; + struct ldb_dn *base_dn; + struct ldb_dn *group_dn; + struct ldb_result *res; + int lret, ret; + + tmp_ctx = talloc_new(memctx); + if (!tmp_ctx) { + return ENOMEM; + } + + base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, + SYSDB_TMPL_GROUP_BASE, domain); + if (!base_dn) { + talloc_free(tmp_ctx); + return ENOMEM; + } + + lret = ldb_transaction_start(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction start !? (%d)\n", lret)); + ret = EIO; + goto done; + } + + lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, + LDB_SCOPE_ONELEVEL, attrs, + SYSDB_GRGID_FILTER, + (unsigned long)gid); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to make search request: %s(%d)[%s]\n", + ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + if (res->count == 0) { + DEBUG(7, ("Base search returned no results\n")); + ret = EOK; + goto done; + } + if (res->count > 1) { + DEBUG(0, ("Cache DB corrupted, base search returned %d results\n", + res->count)); + ret = EIO; + goto done; + } + + group_dn = ldb_dn_copy(tmp_ctx, res->msgs[0]->dn); + if (!group_dn) { + ret = ENOMEM; + goto done; + } + + talloc_free(res); + res = NULL; + + lret = ldb_delete(sysdb->ldb, group_dn); + + if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_OBJECT) { + DEBUG(2, ("LDB Error: %s(%d)\nError Message: [%s]\n", + ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb))); + ret = EIO; + goto done; + } + + ret = EOK; + +done: + if (ret == EOK) { + lret = ldb_transaction_commit(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed ldb transaction commit !! (%d)\n", lret)); + ret = EIO; + } + } else { + lret = ldb_transaction_cancel(sysdb->ldb); + if (lret != LDB_SUCCESS) { + DEBUG(1, ("Failed to cancel ldb transaction (%d)\n", lret)); + ret = EIO; + } + } + + talloc_free(tmp_ctx); + return ret; +} + |