From 94ec51d8b53f636d41a879ed1d0d39127168cb21 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 24 Jun 2009 16:40:56 -0400 Subject: 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. --- server/tools/sss_groupadd.c | 82 ++++++++++---- server/tools/sss_groupdel.c | 79 ++++++++++--- server/tools/sss_groupmod.c | 266 ++++++++++++++++++++++++++++++-------------- server/tools/sss_useradd.c | 166 ++++++++++++++++++--------- server/tools/sss_userdel.c | 82 +++++++++++--- server/tools/sss_usermod.c | 256 ++++++++++++++++++++++++++++-------------- 6 files changed, 651 insertions(+), 280 deletions(-) (limited to 'server/tools') diff --git a/server/tools/sss_groupadd.c b/server/tools/sss_groupadd.c index acb26f3aa..ea7320161 100644 --- a/server/tools/sss_groupadd.c +++ b/server/tools/sss_groupadd.c @@ -44,6 +44,7 @@ #endif struct group_add_ctx { + struct tevent_context *ev; struct sysdb_handle *handle; struct sss_domain_info *domain; @@ -56,36 +57,75 @@ struct group_add_ctx { bool done; }; -/* sysdb callback */ -static void add_group_done(void *pvt, int error, struct ldb_result *ignore) +static void add_group_req_done(struct tevent_req *req) { - struct group_add_ctx *data = talloc_get_type(pvt, struct group_add_ctx); + struct group_add_ctx *data = tevent_req_callback_data(req, + struct group_add_ctx); + data->error = sysdb_transaction_commit_recv(req); data->done = true; - sysdb_transaction_done(data->handle, error); + talloc_zfree(data->handle); +} + +static void add_group_terminate(struct group_add_ctx *data, int error) +{ + struct tevent_req *req; + + if (error != EOK) { + goto fail; + } - if (error) - data->error = error; + req = sysdb_transaction_commit_send(data, data->ev, data->handle); + if (!req) { + error = ENOMEM; + goto fail; + } + tevent_req_set_callback(req, add_group_req_done, data); + + return; + +fail: + /* free transaction */ + talloc_zfree(data->handle); + + data->error = error; + data->done = true; } -/* sysdb_fn_t */ -static void add_group(struct sysdb_handle *handle, void *pvt) +static void add_group_done(struct tevent_req *subreq); + +static void add_group(struct tevent_req *req) { - struct group_add_ctx *group_ctx; + struct group_add_ctx *data = tevent_req_callback_data(req, + struct group_add_ctx); + struct tevent_req *subreq; int ret; - group_ctx = talloc_get_type(pvt, struct group_add_ctx); - group_ctx->handle = handle; + ret = sysdb_transaction_recv(req, data, &data->handle); + if (ret != EOK) { + return add_group_terminate(data, ret); + } - ret = sysdb_add_group(handle, group_ctx->domain, - group_ctx->groupname, - group_ctx->gid, - add_group_done, - group_ctx); + subreq = sysdb_add_group_send(data, data->ev, data->handle, + data->domain, data->groupname, + data->gid, NULL); + if (!subreq) { + add_group_terminate(data, ENOMEM); + } + tevent_req_set_callback(subreq, add_group_done, data); +} - if(ret != EOK) - add_group_done(group_ctx, ret, NULL); +static void add_group_done(struct tevent_req *subreq) +{ + struct group_add_ctx *data = tevent_req_callback_data(subreq, + struct group_add_ctx); + int ret; + + ret = sysdb_add_group_recv(subreq); + talloc_zfree(subreq); + + return add_group_terminate(data, ret); } static int groupadd_legacy(struct group_add_ctx *ctx) @@ -130,6 +170,7 @@ int main(int argc, const char **argv) struct sss_domain_info *dom; poptContext pc = NULL; struct tools_ctx *ctx = NULL; + struct tevent_req *req; struct group_add_ctx *group_ctx = NULL; int ret = EXIT_SUCCESS; @@ -202,13 +243,14 @@ int main(int argc, const char **argv) } /* add_group */ - ret = sysdb_transaction(ctx, ctx->sysdb, add_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 add group.\n"); ret = EXIT_FAILURE; goto fini; } + tevent_req_set_callback(req, add_group, group_ctx); while (!group_ctx->done) { tevent_loop_once(ctx->ev); diff --git a/server/tools/sss_groupdel.c b/server/tools/sss_groupdel.c index 820cf2520..194285c97 100644 --- a/server/tools/sss_groupdel.c +++ b/server/tools/sss_groupdel.c @@ -41,6 +41,7 @@ struct group_del_ctx { + struct tevent_context *ev; struct sysdb_handle *handle; sysdb_callback_t next_fn; @@ -55,35 +56,77 @@ struct group_del_ctx { bool done; }; +static void groupdel_req_done(struct tevent_req *req) +{ + struct group_del_ctx *data = tevent_req_callback_data(req, + struct group_del_ctx); + + data->error = sysdb_transaction_commit_recv(req); + data->done = true; + + talloc_zfree(data->handle); +} + /* sysdb callback */ static void groupdel_done(void *pvt, int error, struct ldb_result *ignore) { struct group_del_ctx *data = talloc_get_type(pvt, struct group_del_ctx); + struct tevent_req *req; - data->done = true; + 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, groupdel_req_done, data); + + return; - sysdb_transaction_done(data->handle, error); +fail: + /* free transaction */ + talloc_zfree(data->handle); - if (error) - data->error = error; + data->error = error; + data->done = true; } -/* sysdb_fn_t */ -static void group_del(struct sysdb_handle *handle, void *pvt) +static void group_del_done(struct tevent_req *subreq); + +static void group_del(struct tevent_req *req) { - struct group_del_ctx *group_ctx; + struct group_del_ctx *data = tevent_req_callback_data(req, + struct group_del_ctx); + struct tevent_req *subreq; int ret; - group_ctx = talloc_get_type(pvt, struct group_del_ctx); - group_ctx->handle = handle; + ret = sysdb_transaction_recv(req, data, &data->handle); + if (ret != EOK) { + return groupdel_done(data, ret, NULL); + } + + subreq = sysdb_delete_entry_send(data, + data->ev, + data->handle, + data->group_dn); + if (!subreq) + return groupdel_done(data, ret, NULL); + + tevent_req_set_callback(subreq, group_del_done, data); +} - ret = sysdb_delete_entry(handle, - group_ctx->group_dn, - groupdel_done, - group_ctx); +static void group_del_done(struct tevent_req *subreq) +{ + struct group_del_ctx *data = tevent_req_callback_data(subreq, + struct group_del_ctx); + int ret; - if(ret != EOK) - groupdel_done(group_ctx, ret, NULL); + ret = sysdb_delete_entry_recv(subreq); + + return groupdel_done(data, ret, NULL); } static int groupdel_legacy(struct group_del_ctx *ctx) @@ -115,6 +158,7 @@ int main(int argc, const char **argv) int pc_debug = 0; struct group_del_ctx *group_ctx = NULL; struct tools_ctx *ctx = NULL; + struct tevent_req *req; struct sss_domain_info *dom; struct group *grp_info; @@ -208,13 +252,14 @@ int main(int argc, const char **argv) } /* groupdel */ - ret = sysdb_transaction(ctx, ctx->sysdb, group_del, 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 remove group.\n"); ret = EXIT_FAILURE; goto fini; } + tevent_req_set_callback(req, group_del, group_ctx); while (!group_ctx->done) { tevent_loop_once(ctx->ev); 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); diff --git a/server/tools/sss_useradd.c b/server/tools/sss_useradd.c index d1d83cf1d..ed9974fe8 100644 --- a/server/tools/sss_useradd.c +++ b/server/tools/sss_useradd.c @@ -84,6 +84,7 @@ #define DFL_BASEDIR_VAL "/home" struct user_add_ctx { + struct tevent_context *ev; struct sysdb_handle *handle; struct sss_domain_info *domain; @@ -187,85 +188,137 @@ done: return ret; } -static void add_to_groups(void *, int, struct ldb_result *); - -/* sysdb callback */ -static void add_user_done(void *pvt, int error, struct ldb_result *ignore) +static void add_user_req_done(struct tevent_req *req) { - struct user_add_ctx *data = talloc_get_type(pvt, struct user_add_ctx); + struct user_add_ctx *data = tevent_req_callback_data(req, + struct user_add_ctx); + data->error = sysdb_transaction_commit_recv(req); data->done = true; - sysdb_transaction_done(data->handle, error); + talloc_zfree(data->handle); +} - if (error) - data->error = error; +static void add_user_terminate(struct user_add_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, add_user_req_done, data); + + return; + +fail: + /* free transaction */ + talloc_zfree(data->handle); + + data->error = error; + data->done = true; } -/* sysdb_fn_t */ -static void add_user(struct sysdb_handle *handle, void *pvt) +static void add_user_done(struct tevent_req *subreq); +static void add_to_groups(struct user_add_ctx *data); +static void add_to_groups_done(struct tevent_req *req); + +static void add_user(struct tevent_req *req) { - struct user_add_ctx *user_ctx; + struct user_add_ctx *data = tevent_req_callback_data(req, + struct user_add_ctx); + struct tevent_req *subreq; int ret; - user_ctx = talloc_get_type(pvt, struct user_add_ctx); - user_ctx->handle = handle; - - ret = sysdb_add_user(handle, user_ctx->domain, - user_ctx->username, - user_ctx->uid, - user_ctx->gid, - user_ctx->gecos, - user_ctx->home, - user_ctx->shell, - add_to_groups, user_ctx); + ret = sysdb_transaction_recv(req, data, &data->handle); + if (ret != EOK) { + return add_user_terminate(data, ret); + } - if (ret != EOK) - add_user_done(user_ctx, ret, NULL); + subreq = sysdb_add_user_send(data, data->ev, data->handle, + data->domain, data->username, + data->uid, data->gid, + data->gecos, data->home, + data->shell, NULL); + if (!subreq) { + add_user_terminate(data, ENOMEM); + } + tevent_req_set_callback(subreq, add_user_done, data); } -static void add_to_groups(void *pvt, int error, struct ldb_result *ignore) +static void add_user_done(struct tevent_req *subreq) { - struct user_add_ctx *user_ctx = talloc_get_type(pvt, struct user_add_ctx); - struct ldb_dn *group_dn; - struct ldb_dn *user_dn; + struct user_add_ctx *data = tevent_req_callback_data(subreq, + struct user_add_ctx); int ret; - if (error) { - add_user_done(pvt, error, NULL); - return; + ret = sysdb_add_user_recv(subreq); + talloc_zfree(subreq); + if (ret) { + return add_user_terminate(data, ret); } - /* check if we added all of them */ - if (user_ctx->groups == NULL || - user_ctx->groups[user_ctx->cur] == NULL) { - add_user_done(user_ctx, EOK, NULL); - return; + if (data->groups) { + return add_to_groups(data); } - user_dn = sysdb_user_dn(user_ctx->ctx->sysdb, user_ctx, - user_ctx->domain->name, user_ctx->username); - if (!user_dn) { - add_user_done(pvt, ENOMEM, NULL); - return; + return add_user_terminate(data, ret); +} + +static void add_to_groups(struct user_add_ctx *data) +{ + struct ldb_dn *parent_dn; + struct ldb_dn *member_dn; + struct tevent_req *subreq; + + member_dn = sysdb_group_dn(data->ctx->sysdb, data, + data->domain->name, data->username); + if (!member_dn) { + return add_user_terminate(data, ENOMEM); } - group_dn = sysdb_group_dn(user_ctx->ctx->sysdb, user_ctx, - user_ctx->domain->name, - user_ctx->groups[user_ctx->cur]); - if (!group_dn) { - add_user_done(pvt, ENOMEM, NULL); - return; + parent_dn = sysdb_group_dn(data->ctx->sysdb, data, + data->domain->name, + data->groups[data->cur]); + if (!parent_dn) { + return add_user_terminate(data, ENOMEM); } - ret = sysdb_add_group_member(user_ctx->handle, - user_dn, group_dn, - add_to_groups, user_ctx); - if (ret != EOK) - add_user_done(user_ctx, ret, NULL); + subreq = sysdb_mod_group_member_send(data, data->ev, data->handle, + member_dn, parent_dn, + LDB_FLAG_MOD_ADD); + if (!subreq) { + return add_user_terminate(data, ENOMEM); + } + tevent_req_set_callback(subreq, add_to_groups_done, data); +} + +static void add_to_groups_done(struct tevent_req *subreq) +{ + struct user_add_ctx *data = tevent_req_callback_data(subreq, + struct user_add_ctx); + int ret; + + ret = sysdb_mod_group_member_recv(subreq); + talloc_zfree(subreq); + if (ret) { + return add_user_terminate(data, ret); + } /* go on to next group */ - user_ctx->cur++; + data->cur++; + + /* check if we added all of them */ + if (data->groups[data->cur] == NULL) { + return add_user_terminate(data, EOK); + } + + return add_to_groups(data); } static int useradd_legacy(struct user_add_ctx *ctx, char *grouplist) @@ -332,6 +385,7 @@ int main(int argc, const char **argv) struct sss_domain_info *dom = NULL; struct user_add_ctx *user_ctx = NULL; struct tools_ctx *ctx = NULL; + struct tevent_req *req; char *groups = NULL; int ret; @@ -352,6 +406,7 @@ int main(int argc, const char **argv) return ENOMEM; } user_ctx->ctx = ctx; + user_ctx->ev = ctx->ev; /* parse user_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); @@ -478,13 +533,14 @@ int main(int argc, const char **argv) } /* useradd */ - ret = sysdb_transaction(ctx, ctx->sysdb, add_user, user_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 user.\n"); ret = EXIT_FAILURE; goto fini; } + tevent_req_set_callback(req, add_user, user_ctx); while (!user_ctx->done) { tevent_loop_once(ctx->ev); diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c index 0222d00cc..bb0673b0a 100644 --- a/server/tools/sss_userdel.c +++ b/server/tools/sss_userdel.c @@ -40,6 +40,7 @@ #endif struct user_del_ctx { + struct tevent_context *ev; struct sysdb_handle *handle; sysdb_callback_t next_fn; @@ -54,37 +55,81 @@ struct user_del_ctx { bool done; }; +static void userdel_req_done(struct tevent_req *req) +{ + struct user_del_ctx *data = tevent_req_callback_data(req, + struct user_del_ctx); + + data->error = sysdb_transaction_commit_recv(req); + data->done = true; + + talloc_zfree(data->handle); +} + /* sysdb callback */ static void userdel_done(void *pvt, int error, struct ldb_result *ignore) { struct user_del_ctx *data = talloc_get_type(pvt, struct user_del_ctx); + struct tevent_req *req; - data->done = true; + 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, userdel_req_done, data); + + return; - sysdb_transaction_done(data->handle, error); +fail: + /* free transaction */ + talloc_zfree(data->handle); - if (error) - data->error = error; + data->error = error; + data->done = true; } -/* sysdb_fn_t */ -static void user_del(struct sysdb_handle *handle, void *pvt) +static void user_del_done(struct tevent_req *subreq); + +static void user_del(struct tevent_req *req) { - struct user_del_ctx *user_ctx; + struct user_del_ctx *data; + struct tevent_req *subreq; int ret; - user_ctx = talloc_get_type(pvt, struct user_del_ctx); - user_ctx->handle = handle; + data = tevent_req_callback_data(req, struct user_del_ctx); + + ret = sysdb_transaction_recv(req, data, &data->handle); + if (ret != EOK) { + return userdel_done(data, ret, NULL); + } - ret = sysdb_delete_entry(handle, - user_ctx->user_dn, - userdel_done, - user_ctx); + subreq = sysdb_delete_entry_send(data, + data->ev, + data->handle, + data->user_dn); + if (!subreq) + return userdel_done(data, ret, NULL); - if(ret != EOK) - userdel_done(user_ctx, ret, NULL); + tevent_req_set_callback(subreq, user_del_done, data); } +static void user_del_done(struct tevent_req *subreq) +{ + struct user_del_ctx *data = tevent_req_callback_data(subreq, + struct user_del_ctx); + int ret; + + ret = sysdb_delete_entry_recv(subreq); + + return userdel_done(data, ret, NULL); +} + + static int userdel_legacy(struct user_del_ctx *ctx) { int ret = EOK; @@ -113,6 +158,7 @@ int main(int argc, const char **argv) int ret = EXIT_SUCCESS; struct user_del_ctx *user_ctx = NULL; struct tools_ctx *ctx = NULL; + struct tevent_req *req; struct sss_domain_info *dom; struct passwd *pwd_info; @@ -141,6 +187,7 @@ int main(int argc, const char **argv) return ENOMEM; } user_ctx->ctx = ctx; + user_ctx->ev = ctx->ev; /* parse user_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); @@ -208,13 +255,14 @@ int main(int argc, const char **argv) /* userdel */ - ret = sysdb_transaction(ctx, ctx->sysdb, user_del, user_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 remove user.\n"); ret = EXIT_FAILURE; goto fini; } + tevent_req_set_callback(req, user_del, user_ctx); while (!user_ctx->done) { tevent_loop_once(ctx->ev); diff --git a/server/tools/sss_usermod.c b/server/tools/sss_usermod.c index 7bb8d663a..521c52645 100644 --- a/server/tools/sss_usermod.c +++ b/server/tools/sss_usermod.c @@ -82,6 +82,7 @@ #endif struct user_mod_ctx { + struct tevent_context *ev; struct sysdb_handle *handle; struct sss_domain_info *domain; @@ -98,133 +99,214 @@ struct user_mod_ctx { bool done; }; -/* sysdb callback */ -static void mod_user_done(void *pvt, int error, struct ldb_result *ignore) +static void mod_user_req_done(struct tevent_req *req) { - struct user_mod_ctx *data = talloc_get_type(pvt, struct user_mod_ctx); + struct user_mod_ctx *data = tevent_req_callback_data(req, + struct user_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_user_done(struct user_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_user_req_done, data); - if (error) - data->error = error; + return; + +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_user_attr_done(struct tevent_req *req); +static void mod_user_cont(struct user_mod_ctx *data); +static void remove_from_groups(struct user_mod_ctx *data); +static void remove_from_groups_done(struct tevent_req *req); +static void add_to_groups(struct user_mod_ctx *data); +static void add_to_groups_done(struct tevent_req *req); -/* sysdb_fn_t */ -static void mod_user(struct sysdb_handle *handle, void *pvt) +static void mod_user(struct tevent_req *req) { - struct user_mod_ctx *user_ctx; + struct user_mod_ctx *data; + struct tevent_req *subreq; int ret; - user_ctx = talloc_get_type(pvt, struct user_mod_ctx); - user_ctx->handle = handle; - - if(user_ctx->attrs->num == 0) { - add_to_groups(user_ctx, EOK, NULL); - } else { - ret = sysdb_set_user_attr(handle, - user_ctx->domain, - user_ctx->username, - user_ctx->attrs, - add_to_groups, - user_ctx); - - if (ret != EOK) { - mod_user_done(user_ctx, ret, NULL); + data = tevent_req_callback_data(req, struct user_mod_ctx); + + ret = sysdb_transaction_recv(req, data, &data->handle); + if (ret != EOK) { + return mod_user_done(data, ret); + } + + if (data->attrs->num != 0) { + subreq = sysdb_set_user_attr_send(data, data->ev, data->handle, + data->domain, data->username, + data->attrs, SYSDB_MOD_REP); + if (!subreq) { + return mod_user_done(data, ret); } + tevent_req_set_callback(subreq, mod_user_attr_done, data); + return; } + + return mod_user_cont(data); } -static void remove_from_groups(void *pvt, int error, struct ldb_result *ignore) +static void mod_user_attr_done(struct tevent_req *subreq) { - struct user_mod_ctx *user_ctx = talloc_get_type(pvt, struct user_mod_ctx); - struct ldb_dn *group_dn; - struct ldb_dn *user_dn; + struct user_mod_ctx *data = tevent_req_callback_data(subreq, + struct user_mod_ctx); int ret; - if (error) { - mod_user_done(pvt, error, NULL); - return; + ret = sysdb_set_user_attr_recv(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + return mod_user_done(data, ret); } - /* check if we removed all of them */ - if (user_ctx->rmgroups == NULL || - user_ctx->rmgroups[user_ctx->cur] == NULL) { - mod_user_done(user_ctx, EOK, NULL); - return; + mod_user_cont(data); +} + +static void mod_user_cont(struct user_mod_ctx *data) +{ + if (data->rmgroups != NULL) { + return remove_from_groups(data); } - user_dn = sysdb_user_dn(user_ctx->ctx->sysdb, user_ctx, - user_ctx->domain->name, user_ctx->username); - if (!user_dn) { - mod_user_done(pvt, ENOMEM, NULL); - return; + if (data->addgroups != NULL) { + return add_to_groups(data); } - group_dn = sysdb_group_dn(user_ctx->ctx->sysdb, user_ctx, - user_ctx->domain->name, - user_ctx->rmgroups[user_ctx->cur]); - if (!group_dn) { - mod_user_done(pvt, ENOMEM, NULL); - return; + return mod_user_done(data, EOK); +} + +static void remove_from_groups(struct user_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->username); + if (!member_dn) { + return mod_user_done(data, ENOMEM); } - ret = sysdb_remove_group_member(user_ctx->handle, - user_dn, group_dn, - remove_from_groups, user_ctx); - if (ret != EOK) - mod_user_done(user_ctx, ret, NULL); + parent_dn = sysdb_group_dn(data->ctx->sysdb, data, + data->domain->name, + data->rmgroups[data->cur]); + if (!parent_dn) { + return mod_user_done(data, ENOMEM); + } - /* go on to next group */ - user_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_user_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 user_mod_ctx *user_ctx = talloc_get_type(pvt, struct user_mod_ctx); - struct ldb_dn *group_dn; - struct ldb_dn *user_dn; + struct user_mod_ctx *data = tevent_req_callback_data(req, + struct user_mod_ctx); int ret; - if (error) { - mod_user_done(pvt, error, NULL); - return; + ret = sysdb_mod_group_member_recv(req); + if (ret) { + return mod_user_done(data, ret); } + talloc_zfree(req); + + /* go on to next group */ + data->cur++; /* check if we added all of them */ - if (user_ctx->addgroups == NULL || - user_ctx->addgroups[user_ctx->cur] == NULL) { - user_ctx->cur = 0; - remove_from_groups(user_ctx, EOK, NULL); - return; + if (data->rmgroups[data->cur] == NULL) { + data->cur = 0; + if (data->addgroups != NULL) { + return remove_from_groups(data); + } + return mod_user_done(data, EOK); } - user_dn = sysdb_user_dn(user_ctx->ctx->sysdb, user_ctx, - user_ctx->domain->name, user_ctx->username); - if (!user_dn) { - mod_user_done(pvt, ENOMEM, NULL); - return; + return remove_from_groups(data); +} + +static void add_to_groups(struct user_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->username); + if (!member_dn) { + return mod_user_done(data, ENOMEM); } - group_dn = sysdb_group_dn(user_ctx->ctx->sysdb, user_ctx, - user_ctx->domain->name, - user_ctx->addgroups[user_ctx->cur]); - if (!group_dn) { - mod_user_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_user_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_user_done(data, ENOMEM); } + tevent_req_set_callback(req, add_to_groups_done, data); +} + +static void add_to_groups_done(struct tevent_req *req) +{ + struct user_mod_ctx *data = tevent_req_callback_data(req, + struct user_mod_ctx); + int ret; - ret = sysdb_add_group_member(user_ctx->handle, - user_dn, group_dn, - add_to_groups, user_ctx); - if (ret != EOK) - mod_user_done(user_ctx, ret, NULL); + ret = sysdb_mod_group_member_recv(req); + if (ret) { + return mod_user_done(data, ret); + } + talloc_zfree(req); /* go on to next group */ - user_ctx->cur++; + data->cur++; + + /* check if we added all of them */ + if (data->addgroups[data->cur] == NULL) { + return mod_user_done(data, EOK); + } + + return add_to_groups(data); } static int usermod_legacy(struct tools_ctx *tools_ctx, struct user_mod_ctx *ctx, @@ -316,6 +398,7 @@ int main(int argc, const char **argv) struct sss_domain_info *dom; struct user_mod_ctx *user_ctx = NULL; struct tools_ctx *ctx = NULL; + struct tevent_req *req; char *groups; int ret; struct passwd *pwd_info; @@ -494,13 +577,14 @@ int main(int argc, const char **argv) } user_ctx->domain = dom; - ret = sysdb_transaction(ctx, ctx->sysdb, mod_user, user_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 user.\n"); ret = EXIT_FAILURE; goto fini; } + tevent_req_set_callback(req, mod_user, user_ctx); while (!user_ctx->done) { tevent_loop_once(ctx->ev); -- cgit