From 8a6449480e4be898248c1d35bbf5c24d91503e4e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 3 Mar 2010 16:22:46 -0500 Subject: sysdb: convert sysdb_search_groups --- src/db/sysdb.h | 16 ++- src/db/sysdb_ops.c | 121 +++++------------- src/providers/ldap/ldap_id_cleanup.c | 190 +++++++++------------------- src/tools/sss_groupshow.c | 234 +++++++++-------------------------- 4 files changed, 151 insertions(+), 410 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index a0714b86..b39d26c9 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -570,15 +570,13 @@ int sysdb_delete_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, uid_t uid); -struct tevent_req *sysdb_search_groups_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - const char *sub_filter, - const char **attrs); -int sysdb_search_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - size_t *msgs_count, struct ldb_message ***msgs); +int sysdb_search_groups(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *sub_filter, + const char **attrs, + size_t *msgs_count, + struct ldb_message ***msgs); int sysdb_delete_group(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 1a816dca..19427d44 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -1857,120 +1857,55 @@ fail: /* =Search-Groups-with-Custom-Filter===================================== */ -struct sysdb_search_groups_state { - struct tevent_context *ev; - struct sysdb_handle *handle; - struct sss_domain_info *domain; - const char *sub_filter; - const char **attrs; - - struct ldb_message **msgs; - size_t msgs_count; -}; - -static void sysdb_search_groups_check_handle(struct tevent_req *subreq); - -struct tevent_req *sysdb_search_groups_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - const char *sub_filter, - const char **attrs) -{ - struct tevent_req *req, *subreq; - struct sysdb_search_groups_state *state; - int ret; - - req = tevent_req_create(mem_ctx, &state, struct sysdb_search_groups_state); - if (req == NULL) { - DEBUG(1, ("tevent_req_create failed.\n")); - return NULL; - } - - state->ev = ev; - state->handle = handle; - state->domain = domain; - state->sub_filter = sub_filter; - state->attrs = attrs; - - state->msgs_count = 0; - state->msgs = NULL; - - subreq = sysdb_check_handle_send(state, ev, sysdb, handle); - if (!subreq) { - DEBUG(1, ("sysdb_check_handle_send failed.\n")); - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, sysdb_search_groups_check_handle, req); - - return req; - -fail: - tevent_req_error(req, ret); - tevent_req_post(req, ev); - return req; -} - -static void sysdb_search_groups_check_handle(struct tevent_req *subreq) +int sysdb_search_groups(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *sub_filter, + const char **attrs, + size_t *msgs_count, + struct ldb_message ***msgs) { - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct sysdb_search_groups_state *state = tevent_req_data(req, - struct sysdb_search_groups_state); + TALLOC_CTX *tmpctx; struct ldb_dn *basedn; char *filter; int ret; - ret = sysdb_check_handle_recv(subreq, state, &state->handle); - talloc_zfree(subreq); - if (ret != EOK) { - tevent_req_error(req, ret); - return; + tmpctx = talloc_new(mem_ctx); + if (!tmpctx) { + return ENOMEM; } - basedn = ldb_dn_new_fmt(state, state->handle->ctx->ldb, - SYSDB_TMPL_GROUP_BASE, state->domain->name); + basedn = ldb_dn_new_fmt(tmpctx, sysdb->ldb, + SYSDB_TMPL_GROUP_BASE, domain->name); if (!basedn) { DEBUG(2, ("Failed to build base dn\n")); - tevent_req_error(req, ENOMEM); - return; + ret = ENOMEM; + goto fail; } - filter = talloc_asprintf(state, "(&(%s)%s)", - SYSDB_GC, state->sub_filter); + filter = talloc_asprintf(tmpctx, "(&(%s)%s)", SYSDB_GC, sub_filter); if (!filter) { DEBUG(2, ("Failed to build filter\n")); - tevent_req_error(req, ENOMEM); - return; + ret = ENOMEM; + goto fail; } DEBUG(6, ("Search groups with filter: %s\n", filter)); - ret = sysdb_search_entry(state, state->handle->ctx, basedn, - LDB_SCOPE_SUBTREE, filter, state->attrs, - &state->msgs_count, &state->msgs); + ret = sysdb_search_entry(mem_ctx, sysdb, basedn, + LDB_SCOPE_SUBTREE, filter, attrs, + msgs_count, msgs); if (ret) { - tevent_req_error(req, ret); - return; + goto fail; } - tevent_req_done(req); -} - -int sysdb_search_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - size_t *msgs_count, struct ldb_message ***msgs) -{ - struct sysdb_search_groups_state *state = tevent_req_data(req, - struct sysdb_search_groups_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - *msgs_count = state->msgs_count; - *msgs = talloc_move(mem_ctx, &state->msgs); - + talloc_zfree(tmpctx); return EOK; + +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + talloc_zfree(tmpctx); + return ret; } /* =Delete-Group-by-Name-OR-gid=========================================== */ diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c index e92545d9..230e36fb 100644 --- a/src/providers/ldap/ldap_id_cleanup.c +++ b/src/providers/ldap/ldap_id_cleanup.c @@ -148,18 +148,16 @@ struct global_cleanup_state { }; static int cleanup_users(TALLOC_CTX *memctx, struct sdap_id_ctx *ctx); -static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sss_domain_info *domain); -static void ldap_id_cleanup_groups_done(struct tevent_req *subreq); +static int cleanup_groups(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain); struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx) { struct global_cleanup_state *state; - struct tevent_req *req, *subreq; + struct tevent_req *req; int ret; req = tevent_req_create(memctx, &state, struct global_cleanup_state); @@ -175,51 +173,25 @@ struct tevent_req *ldap_id_cleanup_send(TALLOC_CTX *memctx, goto fail; } - subreq = cleanup_groups_send(state, state->ev, - state->ctx->be->sysdb, - state->ctx->be->domain); - if (!subreq) { - ret = ENOMEM; + ret = cleanup_groups(state, + state->ctx->be->sysdb, + state->ctx->be->domain); + if (ret) { goto fail; } - tevent_req_set_callback(subreq, ldap_id_cleanup_groups_done, req); + tevent_req_done(req); + tevent_req_post(req, ev); return req; fail: - DEBUG(1, ("Failed to cleanup users (%d [%s]), retrying later!\n", + DEBUG(1, ("Failed to cleanup caches (%d [%s]), retrying later!\n", (int)ret, strerror(ret))); tevent_req_done(req); tevent_req_post(req, ev); return req; } -static void ldap_id_cleanup_groups_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - enum tevent_req_state tstate; - uint64_t err; - - if (tevent_req_is_error(subreq, &tstate, &err)) { - if (tstate != TEVENT_REQ_USER_ERROR) { - err = EIO; - } - if (err != ENOENT) { - goto fail; - } - } - talloc_zfree(subreq); - - tevent_req_done(req); - return; - -fail: - DEBUG(1, ("Failed to cleanup groups (%d [%s]), retrying later!\n", - (int)err, strerror(err))); - tevent_req_done(req); -} - /* ==User-Cleanup-Process================================================= */ @@ -363,142 +335,94 @@ static int cleanup_users_logged_in(hash_table_t *table, /* ==Group-Cleanup-Process================================================ */ -struct cleanup_groups_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sss_domain_info *domain; - - struct sysdb_handle *handle; - - struct ldb_message **msgs; - size_t count; - int cur; -}; - -static void cleanup_groups_process(struct tevent_req *subreq); - -static struct tevent_req *cleanup_groups_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sss_domain_info *domain) +static int cleanup_groups(TALLOC_CTX *memctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain) { - struct tevent_req *req, *subreq; - struct cleanup_groups_state *state; - static const char *attrs[] = { SYSDB_NAME, NULL }; + TALLOC_CTX *tmpctx; + const char *attrs[] = { SYSDB_NAME, NULL }; time_t now = time(NULL); char *subfilter; + const char *dn; + struct ldb_message **msgs; + size_t count; + struct ldb_message **u_msgs; + size_t u_count; + int ret; + int i; - req = tevent_req_create(memctx, &state, struct cleanup_groups_state); - if (!req) { - return NULL; + tmpctx = talloc_new(memctx); + if (!tmpctx) { + return ENOMEM; } - state->ev = ev; - state->sysdb = sysdb; - state->domain = domain; - state->msgs = NULL; - state->count = 0; - state->cur = 0; - - subfilter = talloc_asprintf(state, "(&(!(%s=0))(%s<=%ld))", + subfilter = talloc_asprintf(tmpctx, "(&(!(%s=0))(%s<=%ld))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, (long)now); if (!subfilter) { DEBUG(2, ("Failed to build filter\n")); - talloc_zfree(req); - return NULL; - } - - subreq = sysdb_search_groups_send(state, state->ev, - state->sysdb, NULL, - state->domain, subfilter, attrs); - if (!subreq) { - DEBUG(2, ("Failed to send entry search\n")); - talloc_zfree(req); - return NULL; + ret = ENOMEM; + goto done; } - tevent_req_set_callback(subreq, cleanup_groups_process, req); - - return req; -} - -static void cleanup_groups_process(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct cleanup_groups_state *state = tevent_req_data(req, - struct cleanup_groups_state); - const char *subfilter; - const char *dn; - struct ldb_message **msgs; - size_t count; - int ret; - int i; - ret = sysdb_search_groups_recv(subreq, state, &state->count, &state->msgs); - talloc_zfree(subreq); + ret = sysdb_search_groups(tmpctx, sysdb, + domain, subfilter, attrs, &count, &msgs); if (ret) { if (ret == ENOENT) { - tevent_req_done(req); - return; + ret = EOK; } - tevent_req_error(req, ret); - return; + goto done; } - DEBUG(4, ("Found %d expired group entries!\n", state->count)); + DEBUG(4, ("Found %d expired group entries!\n", count)); - if (state->count == 0) { - tevent_req_done(req); - return; + if (count == 0) { + ret = EOK; + goto done; } - for (i = 0; i < state->count; i++) { - dn = ldb_dn_get_linearized(state->msgs[i]->dn); + for (i = 0; i < count; i++) { + dn = ldb_dn_get_linearized(msgs[i]->dn); if (!dn) { - tevent_req_error(req, EINVAL); - return; + ret = EFAULT; + goto done; } - subfilter = talloc_asprintf(state, "(%s=%s)", - SYSDB_MEMBEROF, dn); + subfilter = talloc_asprintf(tmpctx, "(%s=%s)", SYSDB_MEMBEROF, dn); if (!subfilter) { DEBUG(2, ("Failed to build filter\n")); - tevent_req_error(req, ENOMEM); - return; + ret = ENOMEM; + goto done; } - ret = sysdb_search_users(state, state->sysdb, - state->domain, subfilter, NULL, - &count, &msgs); + ret = sysdb_search_users(tmpctx, sysdb, + domain, subfilter, NULL, &u_count, &u_msgs); if (ret == ENOENT) { const char *name; - name = ldb_msg_find_attr_as_string(state->msgs[i], - SYSDB_NAME, NULL); + name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (!name) { DEBUG(2, ("Entry %s has no Name Attribute ?!?\n", - ldb_dn_get_linearized(state->msgs[i]->dn))); - tevent_req_error(req, EFAULT); - return; + ldb_dn_get_linearized(msgs[i]->dn))); + ret = EFAULT; + goto done; } DEBUG(8, ("About to delete group %s\n", name)); - ret = sysdb_delete_group(state, state->sysdb, - state->domain, name, 0); + ret = sysdb_delete_group(tmpctx, sysdb, domain, name, 0); if (ret) { DEBUG(2, ("Group delete returned %d (%s)\n", ret, strerror(ret))); - tevent_req_error(req, ret); - return; + goto done; } } if (ret != EOK) { - tevent_req_error(req, ret); - return; + goto done; } - talloc_zfree(msgs); + talloc_zfree(u_msgs); } - tevent_req_done(req); +done: + talloc_zfree(tmpctx); + return ret; } diff --git a/src/tools/sss_groupshow.c b/src/tools/sss_groupshow.c index 20f1a765..b6fb1a15 100644 --- a/src/tools/sss_groupshow.c +++ b/src/tools/sss_groupshow.c @@ -275,7 +275,6 @@ struct group_show_state { }; static void group_show_recurse_done(struct tevent_req *subreq); -static void group_show_trim_done(struct tevent_req *subreq); struct tevent_req *group_show_recurse_send(TALLOC_CTX *, struct group_show_state *, @@ -285,16 +284,12 @@ struct tevent_req *group_show_recurse_send(TALLOC_CTX *, static int group_show_recurse_recv(TALLOC_CTX *, struct tevent_req *, struct group_info ***); -static struct tevent_req *group_show_trim_memberof_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - const char *name, - const char **memberofs); -static int group_show_trim_memberof_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - const char ***direct); +static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *name, + const char **memberofs, + const char ***_direct); struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -370,17 +365,11 @@ struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx, } /* if not recursive, only show the direct parent */ - subreq = group_show_trim_memberof_send(state, state->ev, - state->sysdb, state->handle, - state->domain, state->root->name, - state->root->memberofs); - if (!subreq) { - ret = ENOMEM; - goto done; - } - tevent_req_set_callback(subreq, group_show_trim_done, req); - - return req; + ret = group_show_trim_memberof(state, state->sysdb, + state->domain, state->root->name, + state->root->memberofs, + &state->root->memberofs); + goto done; } if (group_members == NULL) { @@ -410,26 +399,6 @@ done: return req; } -static void group_show_trim_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct group_show_state *state = tevent_req_data(req, - struct group_show_state); - int ret; - - ret = group_show_trim_memberof_recv(state->root, subreq, - &state->root->memberofs); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); - return; -} - static void group_show_recurse_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, @@ -465,156 +434,71 @@ static int group_show_recv(TALLOC_CTX *mem_ctx, } /*=========Nonrecursive search should only show direct parent========== */ -struct group_show_trim_state { - const char *name; - struct ldb_dn *dn; - const char **all; - int current; - - const char **direct; - int ndirect; - - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - struct sss_domain_info *domain; -}; - -static int group_show_trim_memberof_next(struct tevent_req *req); -static void group_show_trim_memberof_done(struct tevent_req *subreq); - -static struct tevent_req *group_show_trim_memberof_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - const char *name, - const char **memberofs) +static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + const char *name, + const char **memberofs, + const char ***_direct) { - struct tevent_req *req = NULL; - struct group_show_trim_state *state; + struct ldb_dn *dn; + char *filter; + struct ldb_message **msgs; + size_t count; + const char **direct = NULL; + int ndirect = 0; int ret; + int i; - req = tevent_req_create(mem_ctx, &state, struct group_show_trim_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->domain = domain; - state->name = name; - state->all = memberofs; - - state->dn = sysdb_group_dn(state->sysdb, state, - state->domain->name, - state->name); - if (!state->dn) { - talloc_zfree(req); - return NULL; - } - - ret = group_show_trim_memberof_next(req); - if (ret) { - talloc_zfree(req); - return NULL; - } - - return req; -} - -static int group_show_trim_memberof_next(struct tevent_req *req) -{ - const char *filter; - struct tevent_req *subreq = NULL; - struct group_show_trim_state *state = tevent_req_data(req, - struct group_show_trim_state); - - filter = talloc_asprintf(req, "(&(%s=%s)(%s=%s))", - SYSDB_NAME, state->all[state->current], - SYSDB_MEMBER, ldb_dn_get_linearized(state->dn)); - if (!filter) { - return ENOMEM; - } - - subreq = sysdb_search_groups_send(state, state->ev, state->sysdb, - state->handle, state->domain, - filter, NULL); - if (!subreq) { + dn = sysdb_group_dn(sysdb, mem_ctx, domain->name, name); + if (!dn) { return ENOMEM; } - tevent_req_set_callback(subreq, group_show_trim_memberof_done, req); - return EOK; -} + for (i = 0; memberofs[i]; i++) { -static void group_show_trim_memberof_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct group_show_trim_state *state = tevent_req_data(req, - struct group_show_trim_state); - int ret; - struct ldb_message **msgs; - size_t count = 0; - const char *name; - - ret = sysdb_search_groups_recv(subreq, state, &count, &msgs); - talloc_zfree(subreq); - /* ENOENT is OK, the group is just not a direct parent */ - if (ret != EOK && ret != ENOENT) { - tevent_req_error(req, ret); - return; - } - - if (count > 0) { - name = ldb_msg_find_attr_as_string(msgs[0], - SYSDB_NAME, NULL); - if (!name) { - DEBUG(2, ("Entry %s has no Name Attribute ?!?\n", - ldb_dn_get_linearized(msgs[0]->dn))); - tevent_req_error(req, EFAULT); - return; + filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(%s=%s))", + SYSDB_NAME, memberofs[i], + SYSDB_MEMBER, ldb_dn_get_linearized(dn)); + if (!filter) { + return ENOMEM; } - state->direct = talloc_realloc(state, state->direct, - const char *, state->ndirect+2); - if (!state->direct) { - tevent_req_error(req, ENOMEM); + ret = sysdb_search_groups(mem_ctx, sysdb, + domain, filter, NULL, + &count, &msgs); + /* ENOENT is OK, the group is just not a direct parent */ + if (ret != EOK && ret != ENOENT) { + return ret; } - state->direct[state->ndirect] = talloc_strdup(state->direct, name); - if (!state->direct[state->ndirect]) { - tevent_req_error(req, ENOMEM); - } + if (count > 0) { + name = ldb_msg_find_attr_as_string(msgs[0], + SYSDB_NAME, NULL); + if (!name) { + DEBUG(2, ("Entry %s has no Name Attribute ?!?\n", + ldb_dn_get_linearized(msgs[0]->dn))); + return EFAULT; + } - state->direct[state->ndirect+1] = NULL; - state->ndirect++; - } + direct = talloc_realloc(mem_ctx, direct, + const char *, ndirect + 2); + if (!direct) { + return ENOMEM; + } - state->current++; - if (state->all[state->current] != NULL) { - ret = group_show_trim_memberof_next(req); - if (ret != EOK) { - tevent_req_error(req, ret); + direct[ndirect] = talloc_strdup(direct, name); + if (!direct[ndirect]) { + return ENOMEM; + } + + direct[ndirect + 1] = NULL; + ndirect++; } - return; } - tevent_req_done(req); -} - -static int group_show_trim_memberof_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - const char ***direct) -{ - struct group_show_trim_state *state = tevent_req_data(req, - struct group_show_trim_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - *direct = talloc_move(mem_ctx, &state->direct); - + *_direct = direct; return EOK; } -- cgit