diff options
-rw-r--r-- | src/tools/sss_groupshow.c | 415 |
1 files changed, 105 insertions, 310 deletions
diff --git a/src/tools/sss_groupshow.c b/src/tools/sss_groupshow.c index 3f72fcef..be28f165 100644 --- a/src/tools/sss_groupshow.c +++ b/src/tools/sss_groupshow.c @@ -264,24 +264,15 @@ done: } /*========Find info about a group and recursively about subgroups====== */ -struct group_show_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sss_domain_info *domain; - struct group_info *root; - bool recursive; -}; - -static void group_show_recurse_done(struct tevent_req *subreq); - -struct tevent_req *group_show_recurse_send(TALLOC_CTX *, - struct group_show_state *, - struct group_info *, - const char **, - const int ); -static int group_show_recurse_recv(TALLOC_CTX *, struct tevent_req *, - struct group_info ***); +int group_show_recurse(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + struct group_info *root, + struct group_info *parent, + const char **group_members, + const int nmembers, + struct group_info ***up_members); static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, @@ -290,16 +281,14 @@ static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, const char **memberofs, const char ***_direct); -struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sss_domain_info *domain, - bool recursive, - const char *name) +int group_show(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + bool recursive, + const char *name, + struct group_info **res) { - struct group_show_state *state = NULL; - struct tevent_req *subreq = NULL; - struct tevent_req *req = NULL; + struct group_info *root; static const char *attrs[] = GROUP_SHOW_ATTRS; struct ldb_message *msg = NULL; const char **group_members = NULL; @@ -307,26 +296,16 @@ struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx, int ret; int i; - req = tevent_req_create(mem_ctx, &state, struct group_show_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->domain = domain; - state->recursive = recursive; - /* First, search for the root group */ - ret = sysdb_search_group_by_name(state, state->sysdb, - state->domain, name, attrs, &msg); + ret = sysdb_search_group_by_name(mem_ctx, sysdb, + domain, name, attrs, &msg); if (ret) { DEBUG(2, ("Search failed: %s (%d)\n", strerror(ret), ret)); goto done; } - ret = process_group(state, - sysdb_ctx_get_ldb(state->sysdb), - msg, state->domain, NULL, &state->root, + ret = process_group(mem_ctx, sysdb_ctx_get_ldb(sysdb), + msg, domain, NULL, &root, &group_members, &nmembers); if (ret != EOK) { DEBUG(2, ("Group processing failed: %s (%d)\n", @@ -334,38 +313,39 @@ struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx, goto done; } - if (state->recursive == false) { + if (!recursive) { if (group_members) { - state->root->group_members = talloc_array(state->root, - struct group_info *, - nmembers+1); - for (i=0; group_members[i]; i++) { - state->root->group_members[i] = talloc_zero(state->root, - struct group_info); - if (!state->root->group_members) { + root->group_members = talloc_array(root, + struct group_info *, + nmembers+1); + if (!root->group_members) { + ret = ENOMEM; + goto done; + } + for (i = 0; i < nmembers; i++) { + root->group_members[i] = talloc_zero(root, struct group_info); + if (!root->group_members[i]) { ret = ENOMEM; goto done; } - state->root->group_members[i]->name = talloc_strdup(state->root, - group_members[i]); - if (!state->root->group_members[i]->name) { + root->group_members[i]->name = talloc_strdup(root, + group_members[i]); + if (!root->group_members[i]->name) { ret = ENOMEM; goto done; } } - state->root->group_members[nmembers] = NULL; + root->group_members[nmembers] = NULL; } - if (state->root->memberofs == NULL) { + if (root->memberofs == NULL) { ret = EOK; goto done; } /* if not recursive, only show the direct parent */ - ret = group_show_trim_memberof(state, state->sysdb, - state->domain, state->root->name, - state->root->memberofs, - &state->root->memberofs); + ret = group_show_trim_memberof(mem_ctx, sysdb, domain, root->name, + root->memberofs, &root->memberofs); goto done; } @@ -374,60 +354,20 @@ struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx, goto done; } - subreq = group_show_recurse_send(state->root, state, - state->root, - group_members, - nmembers); - if (!subreq) { - ret = ENOMEM; + ret = group_show_recurse(root, sysdb, domain, root, root, + group_members, nmembers, + &root->group_members); + if (ret) { + DEBUG(2, ("Recursive search failed: %s (%d)\n", strerror(ret), ret)); goto done; } - tevent_req_set_callback(subreq, group_show_recurse_done, req); - - return req; + ret = EOK; done: - if (ret) { - tevent_req_error(req, ret); - } else { - tevent_req_done(req); + if (ret == EOK) { + *res = root; } - tevent_req_post(req, ev); - return req; -} - -static void group_show_recurse_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_recurse_recv(state->root, - subreq, - &state->root->group_members); - talloc_zfree(subreq); - if (ret) { - DEBUG(2, ("Recursive search failed: %s (%d)\n", strerror(ret), ret)); - tevent_req_error(req, EIO); - return; - } - - tevent_req_done(req); -} - -static int group_show_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct group_info **res) -{ - struct group_show_state *state = tevent_req_data(req, - struct group_show_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - *res = talloc_move(mem_ctx, &state->root); - - return EOK; + return ret; } /*=========Nonrecursive search should only show direct parent========== */ @@ -500,177 +440,71 @@ static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, } /*==================Recursive search for nested groups================= */ -struct group_show_recurse { - const char **names; - int current; - - struct group_info *parent; - struct group_show_state *state; - - struct group_info **groups; -}; - -static int group_show_recurse_search(struct tevent_req *, - struct group_show_recurse *); -static void group_show_recurse_level_done(struct tevent_req *); -static int group_show_recurse_cont(struct tevent_req *); -struct tevent_req *group_show_recurse_send(TALLOC_CTX *mem_ctx, - struct group_show_state *state, - struct group_info *parent, - const char **group_members, - const int nmembers) +int group_show_recurse(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + struct group_info *root, + struct group_info *parent, + const char **group_members, + const int nmembers, + struct group_info ***up_members) { - struct tevent_req *req = NULL; - struct group_show_recurse *recurse_state = NULL; - int ret; - - req = tevent_req_create(mem_ctx, &recurse_state, struct group_show_recurse); - if (req == NULL) { - return NULL; - } - recurse_state->current = 0; - recurse_state->parent = parent; - recurse_state->names = group_members; - recurse_state->state = state; - recurse_state->groups = talloc_array(state->root, - struct group_info *, - nmembers+1); /* trailing NULL */ - - if (!recurse_state->names || - !recurse_state->names[recurse_state->current]) { - talloc_zfree(req); - return NULL; - } - - ret = group_show_recurse_search(req, recurse_state); - if (ret == ENOENT) { - tevent_req_done(req); - tevent_req_post(req, state->ev); - } - if (ret) { - tevent_req_error(req, ret); - tevent_req_post(req, state->ev); - } - - return req; -} - -static int group_show_recurse_search(struct tevent_req *req, - struct group_show_recurse *recurse_state) -{ - struct tevent_req *subreq; + struct group_info **groups; static const char *attrs[] = GROUP_SHOW_ATTRS; struct ldb_message *msg; - const char **group_members = NULL; - int nmembers = 0; + const char **new_group_members = NULL; + int new_nmembers = 0; int ret; + int i; + groups = talloc_zero_array(root, + struct group_info *, + nmembers+1); /* trailing NULL */ - /* Skip circular groups */ - if (strcmp(recurse_state->names[recurse_state->current], - recurse_state->parent->name) == 0) { - group_show_recurse_cont(req); - return EOK; - } - - ret = sysdb_search_group_by_name(recurse_state->state, - recurse_state->state->sysdb, - recurse_state->state->domain, - recurse_state->names[recurse_state->current], - attrs, &msg); - if (ret) { - DEBUG(2, ("Search failed: %s (%d)\n", strerror(ret), ret)); - return EIO; - } - - ret = process_group(recurse_state->state->root, - sysdb_ctx_get_ldb(recurse_state->state->sysdb), - msg, - recurse_state->state->domain, - recurse_state->parent->name, - &recurse_state->groups[recurse_state->current], - &group_members, - &nmembers); - if (ret != EOK) { - DEBUG(2, ("Group processing failed: %s (%d)\n", - strerror(ret), ret)); - return ret; + if (!group_members || !group_members[0]) { + return ENOENT; } - /* descend to another level */ - if (nmembers > 0) { - subreq = group_show_recurse_send(recurse_state, - recurse_state->state, - recurse_state->groups[recurse_state->current], - group_members, nmembers); - if (!subreq) { - return ENOMEM; + for (i = 0; i < nmembers; i++) { + /* Skip circular groups */ + if (strcmp(group_members[i], parent->name) == 0) { + continue; } - /* to free group_members in the callback */ - group_members = talloc_move(subreq, &group_members); - tevent_req_set_callback(subreq, group_show_recurse_level_done, req); - return EOK; - } - - /* Move to next group in the same level */ - return group_show_recurse_cont(req); -} -static void group_show_recurse_level_done(struct tevent_req *subreq) -{ - int ret; - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct group_show_recurse *recurse_state = tevent_req_data(subreq, - struct group_show_recurse); - - ret = group_show_recurse_recv(recurse_state->state->root, subreq, - &recurse_state->parent->group_members); - talloc_zfree(subreq); - if (ret) { - DEBUG(2, ("Recursive search failed: %s (%d)\n", strerror(ret), ret)); - tevent_req_error(req, EIO); - return; - } - - /* Move to next group on the upper level */ - ret = group_show_recurse_cont(req); - if (ret == ENOENT) { - tevent_req_done(req); - return; - } - if (ret) { - tevent_req_error(req, ret); - return; - } -} + ret = sysdb_search_group_by_name(mem_ctx, sysdb, + domain, group_members[i], + attrs, &msg); + if (ret) { + DEBUG(2, ("Search failed: %s (%d)\n", strerror(ret), ret)); + return EIO; + } -static int group_show_recurse_cont(struct tevent_req *req) -{ - struct group_show_recurse *state = tevent_req_data(req, - struct group_show_recurse); + ret = process_group(root, sysdb_ctx_get_ldb(sysdb), + msg, domain, parent->name, + &groups[i], &new_group_members, &new_nmembers); + if (ret != EOK) { + DEBUG(2, ("Group processing failed: %s (%d)\n", + strerror(ret), ret)); + return ret; + } - state->current++; - if (state->names[state->current] == NULL) { - state->groups[state->current] = NULL; /* Sentinel */ - return ENOENT; + /* descend to another level */ + if (new_nmembers > 0) { + ret = group_show_recurse(mem_ctx, sysdb, domain, + root, groups[i], + new_group_members, new_nmembers, + &parent->group_members); + if (ret != EOK) { + DEBUG(2, ("Recursive search failed: %s (%d)\n", + strerror(ret), ret)); + return ret; + } + talloc_zfree(new_group_members); + } } - /* examine next group on the same level */ - return group_show_recurse_search(req, state); -} - -static int group_show_recurse_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct group_info ***out) -{ - struct group_show_recurse *recurse_state = tevent_req_data(req, - struct group_show_recurse); - - TEVENT_REQ_RETURN_ON_ERROR(req); - *out = talloc_move(mem_ctx, &recurse_state->groups); - + *up_members = groups; return EOK; } @@ -720,25 +554,6 @@ fail: } /*==================The main program=================================== */ -struct sss_groupshow_state { - struct group_info *root; - - int ret; - bool done; -}; - -static void sss_group_show_done(struct tevent_req *req) -{ - int ret; - struct sss_groupshow_state *sss_state = tevent_req_callback_data(req, - struct sss_groupshow_state); - - ret = group_show_recv(sss_state, req, &sss_state->root); - talloc_zfree(req); - - sss_state->ret = ret; - sss_state->done = true; -} static void print_group_info(struct group_info *g, int level) { @@ -795,8 +610,7 @@ int main(int argc, const char **argv) bool pc_recursive = false; const char *pc_groupname = NULL; struct tools_ctx *tctx = NULL; - struct tevent_req *req = NULL; - struct sss_groupshow_state *state = NULL; + struct group_info *root = NULL; int i; poptContext pc = NULL; @@ -868,31 +682,12 @@ int main(int argc, const char **argv) } /* The search itself */ - state = talloc_zero(tctx, struct sss_groupshow_state); - if (!state) { - goto fini; - } - - req = group_show_send(tctx, tctx->ev, tctx->sysdb, - tctx->local, pc_recursive, tctx->octx->name); - if (!req) { - ERROR("Cannot initiate search\n"); - ret = EXIT_FAILURE; - goto fini; - } - tevent_req_set_callback(req, sss_group_show_done, state); - while (!state->done) { - tevent_loop_once(tctx->ev); - } - ret = state->ret; - + ret = group_show(tctx, tctx->sysdb, + tctx->local, pc_recursive, tctx->octx->name, &root); /* Also show MPGs */ if (ret == ENOENT) { - state->done = false; - state->ret = EOK; - ret = group_show_mpg(tctx, tctx->sysdb, tctx->local, - tctx->octx->name, &state->root); + tctx->octx->name, &root); } /* Process result */ @@ -913,15 +708,15 @@ int main(int argc, const char **argv) } /* print the results */ - print_group_info(state->root, 0); + print_group_info(root, 0); if (pc_recursive) { printf("\n"); - print_recursive(state->root->group_members, 0); + print_recursive(root->group_members, 0); } else { - if (state->root->group_members) { - for (i=0; state->root->group_members[i]; ++i) { + if (root->group_members) { + for (i=0; root->group_members[i]; ++i) { printf("%s%s", i>0 ? "," : "", - state->root->group_members[i]->name); + root->group_members[i]->name); } } printf("\n"); |