summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2012-11-07 11:53:13 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-11-12 00:22:13 +0100
commitfb1ae36ed841f6db8cdfcc2417db21bd028c819f (patch)
tree56ae51c68590e9be5a85f45b7e3e87c72dbeef06
parentbb34baa8c4d61d8dfad621e6c2d1f9764da82baa (diff)
downloadsssd-fb1ae36ed841f6db8cdfcc2417db21bd028c819f.tar.gz
sssd-fb1ae36ed841f6db8cdfcc2417db21bd028c819f.tar.xz
sssd-fb1ae36ed841f6db8cdfcc2417db21bd028c819f.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
-rw-r--r--src/db/sysdb.h1
-rw-r--r--src/responder/pac/pacsrv_cmd.c106
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;