summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2012-11-07 12:01:27 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-11-12 00:22:17 +0100
commit35664b044e8c08e9486da90a1cf112ee7e10cf3d (patch)
tree7d9a19321c02574668aa7eaccb5adc08b8c9c672
parentfb1ae36ed841f6db8cdfcc2417db21bd028c819f (diff)
downloadsssd-35664b044e8c08e9486da90a1cf112ee7e10cf3d.tar.gz
sssd-35664b044e8c08e9486da90a1cf112ee7e10cf3d.tar.xz
sssd-35664b044e8c08e9486da90a1cf112ee7e10cf3d.zip
Get lists of GIDs to be added and deleted and use them
Currently the user was just added to all local groups which are given in the PAC. With this patch the user is added only to groups he is currently not a member of and deleted from groups which are not found in the PAC anymore.
-rw-r--r--src/responder/pac/pacsrv_cmd.c92
1 files changed, 89 insertions, 3 deletions
diff --git a/src/responder/pac/pacsrv_cmd.c b/src/responder/pac/pacsrv_cmd.c
index 0e76acf86..d0091dd0c 100644
--- a/src/responder/pac/pacsrv_cmd.c
+++ b/src/responder/pac/pacsrv_cmd.c
@@ -63,6 +63,12 @@ struct pac_req_ctx {
size_t current_grp_count;
struct grp_info *current_grp_list;
+
+ size_t add_gid_count;
+ gid_t *add_gids;
+
+ size_t del_grp_count;
+ struct grp_info **del_grp_list;
};
static errno_t pac_add_user_next(struct pac_req_ctx *pr_ctx);
@@ -223,6 +229,12 @@ static errno_t pac_add_user_next(struct pac_req_ctx *pr_ctx)
goto done;
}
+ ret = diff_gid_lists(pr_ctx,
+ pr_ctx->current_grp_count, pr_ctx->current_grp_list,
+ pr_ctx->gid_count, pr_ctx->gids,
+ &pr_ctx->add_gid_count, &pr_ctx->add_gids,
+ &pr_ctx->del_grp_count, &pr_ctx->del_grp_list);
+
req = pac_save_memberships_send(pr_ctx);
if (req == NULL) {
ret = ENOMEM;
@@ -395,6 +407,9 @@ struct pac_save_memberships_state {
struct sss_domain_info *group_dom;
};
+static errno_t
+pac_save_memberships_delete(struct pac_save_memberships_state *state);
+
struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx)
{
struct pac_save_memberships_state *state;
@@ -422,6 +437,12 @@ struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx)
state->group_dom = pr_ctx->dom;
}
+ ret = pac_save_memberships_delete(state);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("pac_save_memberships_delete failed.\n"));
+ goto done;
+ }
+
ret = pac_save_memberships_next(req);
if (ret == EOK) {
tevent_req_done(req);
@@ -437,6 +458,62 @@ done:
return req;
}
+static errno_t
+pac_save_memberships_delete(struct pac_save_memberships_state *state)
+{
+ int ret;
+ int sret;
+ size_t c;
+ struct pac_req_ctx *pr_ctx;
+ bool in_transaction = false;
+
+ pr_ctx = state->pr_ctx;
+
+ if (pr_ctx->del_grp_count == 0) {
+ return EOK;
+ }
+
+ if (pr_ctx->del_grp_list == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Missing group list.\n"));
+ return EINVAL;
+ }
+
+ ret = sysdb_transaction_start(state->group_dom->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_transaction_start failed.\n"));
+ goto done;
+ }
+ in_transaction = true;
+
+ for (c = 0; c < pr_ctx->del_grp_count; c++) {
+ ret = sysdb_mod_group_member(state->group_dom->sysdb, state->user_dn,
+ pr_ctx->del_grp_list[c]->dn,
+ LDB_FLAG_MOD_DELETE);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_mod_group_member failed.\n"));
+ goto done;
+ }
+ }
+
+ ret = sysdb_transaction_commit(state->group_dom->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_transaction_commit failed.\n"));
+ goto done;
+ }
+ in_transaction = false;
+
+ ret = EOK;
+done:
+ if (in_transaction) {
+ sret = sysdb_transaction_cancel(state->group_dom->sysdb);
+ if (sret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_transaction_cancel failed.\n"));
+ }
+ }
+
+ return ret;
+}
+
static errno_t pac_save_memberships_next(struct tevent_req *req)
{
errno_t ret;
@@ -448,8 +525,17 @@ static errno_t pac_save_memberships_next(struct tevent_req *req)
state = tevent_req_data(req, struct pac_save_memberships_state);
pr_ctx = state->pr_ctx;
- while (state->gid_iter < pr_ctx->gid_count) {
- gid = pr_ctx->gids[state->gid_iter];
+ if (pr_ctx->add_gid_count == 0) {
+ return EOK;
+ }
+
+ if (pr_ctx->add_gids == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Missing group list.\n"));
+ return EINVAL;
+ }
+
+ while (state->gid_iter < pr_ctx->add_gid_count) {
+ gid = pr_ctx->add_gids[state->gid_iter];
ret = pac_store_membership(state->pr_ctx, state->group_dom->sysdb,
state->user_dn, state->gid_iter);
@@ -538,7 +624,7 @@ pac_store_membership(struct pac_req_ctx *pr_ctx,
return ENOMEM;
}
- gid = pr_ctx->gids[gid_iter];
+ gid = pr_ctx->add_gids[gid_iter];
ret = sysdb_search_group_by_gid(tmp_ctx, group_sysdb,
gid, NULL, &group);