diff options
author | Sumit Bose <sbose@redhat.com> | 2012-11-07 11:53:13 +0100 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2012-11-10 21:44:34 -0500 |
commit | 6722c85cb59c2d6fc223966c2b83cc3ea0d9aceb (patch) | |
tree | 4ae78d421151560000d80579d69b76614830664b /src | |
parent | 1a456e464803c6d1e82081e9b4d618fa0b07b3d7 (diff) | |
download | sssd-6722c85cb59c2d6fc223966c2b83cc3ea0d9aceb.tar.gz sssd-6722c85cb59c2d6fc223966c2b83cc3ea0d9aceb.tar.xz sssd-6722c85cb59c2d6fc223966c2b83cc3ea0d9aceb.zip |
Add pac_user_get_grp_info() to read current group memberships
To be able to efficiently store group memberships we need to know the
current memberships of a user. sysdb_initgroups() is used to read the
user entry together with all groups the user is a member of. Some of the
group attributes are kept to avoid additional lookups and speed up
further processing.
Currently sysdb_initgroups() does not return the original DN of the
group. Since it is needed to remove memberships later on it is added to
the list of requested attributes
Diffstat (limited to 'src')
-rw-r--r-- | src/db/sysdb.h | 1 | ||||
-rw-r--r-- | src/responder/pac/pacsrv_cmd.c | 106 |
2 files changed, 107 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 8fe0e81c1..39e0f9f52 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -200,6 +200,7 @@ #define SYSDB_INITGR_ATTR SYSDB_MEMBEROF #define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, SYSDB_POSIX, \ SYSDB_DEFAULT_ATTRS, \ + SYSDB_ORIG_DN, \ NULL} #define SYSDB_TMPL_USER SYSDB_NAME"=%s,"SYSDB_TMPL_USER_BASE diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c index 777798387..0e76acf86 100644 --- a/src/responder/pac/pacsrv_cmd.c +++ b/src/responder/pac/pacsrv_cmd.c @@ -60,10 +60,17 @@ struct pac_req_ctx { size_t gid_count; gid_t *gids; + + size_t current_grp_count; + struct grp_info *current_grp_list; }; static errno_t pac_add_user_next(struct pac_req_ctx *pr_ctx); static void pac_get_domains_done(struct tevent_req *req); +static errno_t pac_user_get_grp_info(TALLOC_CTX *mem_ctx, + struct pac_req_ctx *pr_ctx, + size_t *_current_grp_count, + struct grp_info **_current_grp_list); static errno_t save_pac_user(struct pac_req_ctx *pr_ctx); static void pac_get_group_done(struct tevent_req *subreq); static errno_t pac_save_memberships_next(struct tevent_req *req); @@ -194,6 +201,13 @@ static errno_t pac_add_user_next(struct pac_req_ctx *pr_ctx) goto done; } + ret = pac_user_get_grp_info(pr_ctx, pr_ctx, &pr_ctx->current_grp_count, + &pr_ctx->current_grp_list); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("pac_user_get_grp_info failed.\n")); + goto done; + } + ret = get_my_domain_data(pr_ctx->pac_ctx, pr_ctx->dom, &my_dom_sid, &my_range_map); if (ret != EOK) { @@ -223,6 +237,98 @@ done: return ret; } +static errno_t pac_user_get_grp_info(TALLOC_CTX *mem_ctx, + struct pac_req_ctx *pr_ctx, + size_t *_current_grp_count, + struct grp_info **_current_grp_list) +{ + struct sysdb_ctx *sysdb; + int ret; + TALLOC_CTX *tmp_ctx = NULL; + struct ldb_result *res = NULL; + struct grp_info *current_grp_list = NULL; + size_t current_grp_count = 0; + size_t c; + const char *tmp_str; + + sysdb = pr_ctx->dom->sysdb; + if (sysdb == NULL) { + ret = EINVAL; + DEBUG(SSSDBG_FATAL_FAILURE, ("Fatal: Sysdb CTX not found for this domain!\n")); + goto done; + } + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + ret = ENOMEM; + DEBUG(SSSDBG_OP_FAILURE, ("talloc_new failed.\n")); + goto done; + } + + ret = sysdb_initgroups(tmp_ctx, sysdb, pr_ctx->user_name, &res); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("sysdb_initgroups failed.\n")); + goto done; + } + + /* First result is the user entry then the groups follow */ + if (res->count > 1) { + current_grp_count = res->count - 1; + current_grp_list = talloc_array(tmp_ctx, struct grp_info, + current_grp_count); + if (current_grp_list == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("talloc_array failed.\n")); + ret = ENOMEM; + goto done; + } + + for (c = 0; c < current_grp_count; c++) { + current_grp_list[c].gid = + ldb_msg_find_attr_as_uint64(res->msgs[c + 1], + SYSDB_GIDNUM, 0); + if (current_grp_list[c].gid == 0) { + DEBUG(SSSDBG_OP_FAILURE, ("Missing GID.\n")); + ret = EINVAL; + goto done; + } + + tmp_str = ldb_msg_find_attr_as_string(res->msgs[c + 1], + SYSDB_ORIG_DN, NULL); + if (tmp_str == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("Missing original DN.\n")); + ret = EINVAL; + goto done; + } + + current_grp_list[c].orig_dn = talloc_strdup(current_grp_list, + tmp_str); + if (current_grp_list[c].orig_dn == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n")); + ret = ENOMEM; + goto done; + } + + current_grp_list[c].dn = ldb_dn_copy(current_grp_list, + res->msgs[c + 1]->dn); + if (current_grp_list[c].dn == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("ldb_dn_copy failed.\n")); + ret = ENOMEM; + goto done; + } + } + } + + *_current_grp_count = current_grp_count; + *_current_grp_list = talloc_steal(mem_ctx, current_grp_list); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} + static errno_t save_pac_user(struct pac_req_ctx *pr_ctx) { struct sysdb_ctx *sysdb; |