summaryrefslogtreecommitdiffstats
path: root/server/tools/sss_groupmod.c
diff options
context:
space:
mode:
authorSimo Sorce <ssorce@redhat.com>2009-06-24 16:40:56 -0400
committerSimo Sorce <ssorce@redhat.com>2009-07-03 11:07:36 -0400
commit94ec51d8b53f636d41a879ed1d0d39127168cb21 (patch)
treee6984ad304bf81781de2b118dac189db4bb0a582 /server/tools/sss_groupmod.c
parent6aca93fb4d5d39a100b900a8c297d08629407960 (diff)
downloadsssd-94ec51d8b53f636d41a879ed1d0d39127168cb21.tar.gz
sssd-94ec51d8b53f636d41a879ed1d0d39127168cb21.tar.xz
sssd-94ec51d8b53f636d41a879ed1d0d39127168cb21.zip
Rework transaction code to use tevent_req
This is part of a set of patches to rewrite sysdb to a hopefully better API, that will also let use use tevent_req async style calls to manipulate our cache.
Diffstat (limited to 'server/tools/sss_groupmod.c')
-rw-r--r--server/tools/sss_groupmod.c266
1 files changed, 181 insertions, 85 deletions
diff --git a/server/tools/sss_groupmod.c b/server/tools/sss_groupmod.c
index 0c2abda8f..cc7665d9d 100644
--- a/server/tools/sss_groupmod.c
+++ b/server/tools/sss_groupmod.c
@@ -45,6 +45,7 @@
#endif
struct group_mod_ctx {
+ struct tevent_context *ev;
struct sysdb_handle *handle;
struct sss_domain_info *domain;
@@ -61,132 +62,225 @@ struct group_mod_ctx {
bool done;
};
-/* sysdb callback */
-static void mod_group_done(void *pvt, int error, struct ldb_result *ignore)
+static void mod_group_req_done(struct tevent_req *req)
{
- struct group_mod_ctx *data = talloc_get_type(pvt, struct group_mod_ctx);
+ struct group_mod_ctx *data = tevent_req_callback_data(req,
+ struct group_mod_ctx);
+ data->error = sysdb_transaction_commit_recv(req);
data->done = true;
- sysdb_transaction_done(data->handle, error);
+ talloc_zfree(data->handle);
+}
+
+static void mod_group_done(struct group_mod_ctx *data, int error)
+{
+ struct tevent_req *req;
+
+ if (error != EOK) {
+ goto fail;
+ }
+
+ req = sysdb_transaction_commit_send(data, data->ev, data->handle);
+ if (!req) {
+ error = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(req, mod_group_req_done, data);
+
+ return;
- if (error)
- data->error = error;
+fail:
+ /* free transaction */
+ talloc_zfree(data->handle);
+
+ data->error = error;
+ data->done = true;
}
-static void add_to_groups(void *, int, struct ldb_result *);
+static void mod_group_attr_done(struct tevent_req *req);
+static void mod_group_cont(struct group_mod_ctx *data);
+static void remove_from_groups(struct group_mod_ctx *data);
+static void remove_from_groups_done(struct tevent_req *req);
+static void add_to_groups(struct group_mod_ctx *data);
+static void add_to_groups_done(struct tevent_req *req);
-/* sysdb_fn_t */
-static void mod_group(struct sysdb_handle *handle, void *pvt)
+static void mod_group(struct tevent_req *req)
{
- struct group_mod_ctx *group_ctx;
+ struct group_mod_ctx *data;
+ struct tevent_req *subreq;
+ struct sysdb_attrs *attrs;
int ret;
- group_ctx = talloc_get_type(pvt, struct group_mod_ctx);
- group_ctx->handle = handle;
-
- if(group_ctx->gid == 0) {
- add_to_groups(group_ctx, EOK, NULL);
- } else {
- ret = sysdb_set_group_gid(handle,
- group_ctx->domain,
- group_ctx->groupname,
- group_ctx->gid,
- mod_group_done,
- group_ctx);
- if (ret != EOK) {
- mod_group_done(group_ctx, ret, NULL);
+ data = tevent_req_callback_data(req, struct group_mod_ctx);
+
+ ret = sysdb_transaction_recv(req, data, &data->handle);
+ if (ret != EOK) {
+ return mod_group_done(data, ret);
+ }
+ talloc_zfree(req);
+
+ if (data->gid != 0) {
+ attrs = sysdb_new_attrs(data);
+ if (!attrs) {
+ mod_group_done(data, ENOMEM);
+ }
+ ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, data->gid);
+ if (ret) {
+ mod_group_done(data, ret);
}
+
+ subreq = sysdb_set_group_attr_send(data, data->ev, data->handle,
+ data->domain, data->groupname,
+ attrs, SYSDB_MOD_REP);
+ if (!subreq) {
+ return mod_group_done(data, ret);
+ }
+ tevent_req_set_callback(subreq, mod_group_attr_done, data);
+ return;
}
+
+ return mod_group_cont(data);
}
-static void remove_from_groups(void *pvt, int error, struct ldb_result *ignore)
+static void mod_group_attr_done(struct tevent_req *subreq)
{
- struct group_mod_ctx *group_ctx = talloc_get_type(pvt, struct group_mod_ctx);
- struct ldb_dn *group_dn;
- struct ldb_dn *parent_group_dn;
+ struct group_mod_ctx *data = tevent_req_callback_data(subreq,
+ struct group_mod_ctx);
int ret;
- if (error) {
- mod_group_done(pvt, error, NULL);
- return;
+ ret = sysdb_set_group_attr_recv(subreq);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ return mod_group_done(data, ret);
}
- /* check if we removed all of them */
- if (group_ctx->rmgroups == NULL ||
- group_ctx->rmgroups[group_ctx->cur] == NULL) {
- mod_group_done(group_ctx, EOK, NULL);
- return;
+ mod_group_cont(data);
+}
+
+static void mod_group_cont(struct group_mod_ctx *data)
+{
+ if (data->rmgroups != NULL) {
+ return remove_from_groups(data);
}
- group_dn = sysdb_group_dn(group_ctx->ctx->sysdb, group_ctx,
- group_ctx->domain->name, group_ctx->groupname);
- if (!group_dn) {
- mod_group_done(pvt, ENOMEM, NULL);
- return;
+ if (data->addgroups != NULL) {
+ return add_to_groups(data);
}
- parent_group_dn = sysdb_group_dn(group_ctx->ctx->sysdb, group_ctx,
- group_ctx->domain->name,
- group_ctx->rmgroups[group_ctx->cur]);
- if (!parent_group_dn) {
- mod_group_done(pvt, ENOMEM, NULL);
- return;
+ return mod_group_done(data, EOK);
+}
+
+static void remove_from_groups(struct group_mod_ctx *data)
+{
+ struct ldb_dn *parent_dn;
+ struct ldb_dn *member_dn;
+ struct tevent_req *req;
+
+ member_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ data->domain->name, data->groupname);
+ if (!member_dn) {
+ return mod_group_done(data, ENOMEM);
}
- ret = sysdb_remove_group_member(group_ctx->handle,
- group_dn, parent_group_dn,
- remove_from_groups, group_ctx);
- if (ret != EOK)
- mod_group_done(group_ctx, ret, NULL);
+ parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ data->domain->name,
+ data->rmgroups[data->cur]);
+ if (!parent_dn) {
+ return mod_group_done(data, ENOMEM);
+ }
- /* go on to next group */
- group_ctx->cur++;
+ req = sysdb_mod_group_member_send(data,
+ data->ev,
+ data->handle,
+ member_dn,
+ parent_dn,
+ LDB_FLAG_MOD_DELETE);
+ if (!req) {
+ return mod_group_done(data, ENOMEM);
+ }
+ tevent_req_set_callback(req, remove_from_groups_done, data);
}
-static void add_to_groups(void *pvt, int error, struct ldb_result *ignore)
+static void remove_from_groups_done(struct tevent_req *req)
{
- struct group_mod_ctx *group_ctx = talloc_get_type(pvt, struct group_mod_ctx);
- struct ldb_dn *group_dn;
- struct ldb_dn *parent_group_dn;
+ struct group_mod_ctx *data = tevent_req_callback_data(req,
+ struct group_mod_ctx);
int ret;
- if (error) {
- mod_group_done(pvt, error, NULL);
- return;
+ ret = sysdb_mod_group_member_recv(req);
+ if (ret) {
+ return mod_group_done(data, ret);
}
+ talloc_zfree(req);
+
+ /* go on to next group */
+ data->cur++;
/* check if we added all of them */
- if (group_ctx->addgroups == NULL ||
- group_ctx->addgroups[group_ctx->cur] == NULL) {
- group_ctx->cur = 0;
- remove_from_groups(group_ctx, EOK, NULL);
- return;
+ if (data->rmgroups[data->cur] == NULL) {
+ data->cur = 0;
+ if (data->addgroups != NULL) {
+ return remove_from_groups(data);
+ }
+ return mod_group_done(data, EOK);
}
- group_dn = sysdb_group_dn(group_ctx->ctx->sysdb, group_ctx,
- group_ctx->domain->name, group_ctx->groupname);
- if (!group_dn) {
- mod_group_done(pvt, ENOMEM, NULL);
- return;
+ return remove_from_groups(data);
+}
+
+static void add_to_groups(struct group_mod_ctx *data)
+{
+ struct ldb_dn *parent_dn;
+ struct ldb_dn *member_dn;
+ struct tevent_req *req;
+
+ member_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ data->domain->name, data->groupname);
+ if (!member_dn) {
+ return mod_group_done(data, ENOMEM);
}
- parent_group_dn = sysdb_group_dn(group_ctx->ctx->sysdb, group_ctx,
- group_ctx->domain->name,
- group_ctx->addgroups[group_ctx->cur]);
- if (!parent_group_dn) {
- mod_group_done(pvt, ENOMEM, NULL);
- return;
+ parent_dn = sysdb_group_dn(data->ctx->sysdb, data,
+ data->domain->name,
+ data->addgroups[data->cur]);
+ if (!parent_dn) {
+ return mod_group_done(data, ENOMEM);
+ }
+
+ req = sysdb_mod_group_member_send(data,
+ data->ev,
+ data->handle,
+ member_dn,
+ parent_dn,
+ LDB_FLAG_MOD_ADD);
+ if (!req) {
+ return mod_group_done(data, ENOMEM);
}
+ tevent_req_set_callback(req, add_to_groups_done, data);
+}
+
+static void add_to_groups_done(struct tevent_req *req)
+{
+ struct group_mod_ctx *data = tevent_req_callback_data(req,
+ struct group_mod_ctx);
+ int ret;
- ret = sysdb_add_group_member(group_ctx->handle,
- group_dn, parent_group_dn,
- add_to_groups, group_ctx);
- if (ret != EOK)
- mod_group_done(group_ctx, ret, NULL);
+ ret = sysdb_mod_group_member_recv(req);
+ if (ret) {
+ return mod_group_done(data, ret);
+ }
+ talloc_zfree(req);
/* go on to next group */
- group_ctx->cur++;
+ data->cur++;
+
+ /* check if we added all of them */
+ if (data->addgroups[data->cur] == NULL) {
+ return mod_group_done(data, EOK);
+ }
+
+ return add_to_groups(data);
}
static int groupmod_legacy(struct tools_ctx *tools_ctx, struct group_mod_ctx *ctx, int old_domain)
@@ -247,6 +341,7 @@ int main(int argc, const char **argv)
struct sss_domain_info *dom;
struct group_mod_ctx *group_ctx = NULL;
struct tools_ctx *ctx = NULL;
+ struct tevent_req *req;
char *groups;
int ret;
struct group *grp_info;
@@ -344,13 +439,14 @@ int main(int argc, const char **argv)
goto fini;
}
- ret = sysdb_transaction(ctx, ctx->sysdb, mod_group, group_ctx);
- if (ret != EOK) {
+ req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb);
+ if (!req) {
DEBUG(1, ("Could not start transaction (%d)[%s]\n", ret, strerror(ret)));
ERROR("Transaction error. Could not modify group.\n");
ret = EXIT_FAILURE;
goto fini;
}
+ tevent_req_set_callback(req, mod_group, group_ctx);
while (!group_ctx->done) {
tevent_loop_once(ctx->ev);