diff options
author | Simo Sorce <ssorce@redhat.com> | 2009-09-29 10:14:36 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2009-10-01 08:42:36 -0400 |
commit | f24c2dd7cc8414ea0a5c8c4ae7766ca71554480f (patch) | |
tree | cceff211fe8fc0c78c59b959af5367c0c4ce49f3 | |
parent | bc58f5892d3a8f6b28e2148c5a0cca34b63ef354 (diff) | |
download | sssd-f24c2dd7cc8414ea0a5c8c4ae7766ca71554480f.tar.gz sssd-f24c2dd7cc8414ea0a5c8c4ae7766ca71554480f.tar.bz2 sssd-f24c2dd7cc8414ea0a5c8c4ae7766ca71554480f.zip |
Fix tools sync operations and mem hierarchy
Tools were using nested loops that are illegal.
(and enforced in latest tevent with a nice abort())
Fix them by creating appropriate synchronous transaction calls.
Also fix tools_ctx mem hierarchy setup.
-rw-r--r-- | server/tools/sss_groupadd.c | 62 | ||||
-rw-r--r-- | server/tools/sss_groupdel.c | 62 | ||||
-rw-r--r-- | server/tools/sss_groupmod.c | 61 | ||||
-rw-r--r-- | server/tools/sss_sync_ops.c | 80 | ||||
-rw-r--r-- | server/tools/sss_sync_ops.h | 4 | ||||
-rw-r--r-- | server/tools/sss_useradd.c | 67 | ||||
-rw-r--r-- | server/tools/sss_userdel.c | 62 | ||||
-rw-r--r-- | server/tools/sss_usermod.c | 61 | ||||
-rw-r--r-- | server/tools/tools_util.c | 48 | ||||
-rw-r--r-- | server/tools/tools_util.h | 5 |
10 files changed, 193 insertions, 319 deletions
diff --git a/server/tools/sss_groupadd.c b/server/tools/sss_groupadd.c index 72bd0fdf..1f6a2f11 100644 --- a/server/tools/sss_groupadd.c +++ b/server/tools/sss_groupadd.c @@ -29,42 +29,7 @@ #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" - -static void add_group_transaction(struct tevent_req *req) -{ - int ret; - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - struct tevent_req *subreq; - - ret = sysdb_transaction_recv(req, tctx, &tctx->handle); - if (ret) { - tevent_req_error(req, ret); - return; - } - talloc_zfree(req); - - /* groupadd */ - ret = groupadd(tctx, tctx->ev, - tctx->sysdb, tctx->handle, tctx->octx); - if (ret != EOK) { - goto fail; - } - - subreq = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, tools_transaction_done, tctx); - return; - -fail: - /* free transaction and signal error */ - talloc_zfree(tctx->handle); - tctx->transaction_done = true; - tctx->error = ret; -} +#include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { @@ -82,7 +47,6 @@ int main(int argc, const char **argv) struct tools_ctx *tctx = NULL; int ret = EXIT_SUCCESS; const char *pc_groupname = NULL; - struct tevent_req *req; debug_prg_name = argv[0]; @@ -140,20 +104,24 @@ int main(int argc, const char **argv) goto fini; } - /* add_group */ - req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->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; + start_transaction(tctx); + if (tctx->error != EOK) { + goto done; } - tevent_req_set_callback(req, add_group_transaction, tctx); - while (!tctx->transaction_done) { - tevent_loop_once(tctx->ev); + /* groupadd */ + ret = groupadd(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx); + if (ret != EOK) { + tctx->error = ret; + + /* cancel transaction */ + talloc_zfree(tctx->handle); + goto done; } + end_transaction(tctx); + +done: if (tctx->error) { ret = tctx->error; switch (ret) { diff --git a/server/tools/sss_groupdel.c b/server/tools/sss_groupdel.c index 3134279d..a4451c43 100644 --- a/server/tools/sss_groupdel.c +++ b/server/tools/sss_groupdel.c @@ -29,42 +29,7 @@ #include "db/sysdb.h" #include "util/util.h" #include "tools/tools_util.h" - -static void del_group_transaction(struct tevent_req *req) -{ - int ret; - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - struct tevent_req *subreq; - - ret = sysdb_transaction_recv(req, tctx, &tctx->handle); - if (ret) { - tevent_req_error(req, ret); - return; - } - talloc_zfree(req); - - /* groupdel */ - ret = groupdel(tctx, tctx->ev, - tctx->sysdb, tctx->handle, tctx->octx); - if (ret != EOK) { - goto fail; - } - - subreq = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, tools_transaction_done, tctx); - return; - -fail: - /* free transaction and signal error */ - talloc_zfree(tctx->handle); - tctx->transaction_done = true; - tctx->error = ret; -} +#include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { @@ -73,7 +38,6 @@ int main(int argc, const char **argv) struct group *grp_info; const char *pc_groupname = NULL; struct tools_ctx *tctx = NULL; - struct tevent_req *req; poptContext pc = NULL; struct poptOption long_options[] = { @@ -142,20 +106,24 @@ int main(int argc, const char **argv) goto fini; } - /* groupdel */ - req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->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; + start_transaction(tctx); + if (tctx->error != EOK) { + goto done; } - tevent_req_set_callback(req, del_group_transaction, tctx); - while (!tctx->transaction_done) { - tevent_loop_once(tctx->ev); + /* groupdel */ + ret = groupdel(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx); + if (ret != EOK) { + tctx->error = ret; + + /* cancel transaction */ + talloc_zfree(tctx->handle); + goto done; } + end_transaction(tctx); + +done: if (tctx->error) { ret = tctx->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); diff --git a/server/tools/sss_groupmod.c b/server/tools/sss_groupmod.c index 1ecf076c..e821fdc3 100644 --- a/server/tools/sss_groupmod.c +++ b/server/tools/sss_groupmod.c @@ -30,42 +30,7 @@ #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" - -static void mod_group_transaction(struct tevent_req *req) -{ - int ret; - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - struct tevent_req *subreq; - - ret = sysdb_transaction_recv(req, tctx, &tctx->handle); - if (ret) { - tevent_req_error(req, ret); - return; - } - talloc_zfree(req); - - /* groupmod */ - ret = groupmod(tctx, tctx->ev, - tctx->sysdb, tctx->handle, tctx->octx); - if (ret != EOK) { - goto fail; - } - - subreq = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, tools_transaction_done, tctx); - return; - -fail: - /* free transaction and signal error */ - talloc_zfree(tctx->handle); - tctx->transaction_done = true; - tctx->error = ret; -} +#include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { @@ -88,7 +53,6 @@ int main(int argc, const char **argv) char *addgroups = NULL, *rmgroups = NULL; int ret; const char *pc_groupname = NULL; - struct tevent_req *req; debug_prg_name = argv[0]; @@ -194,19 +158,24 @@ int main(int argc, const char **argv) goto fini; } - req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->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; + start_transaction(tctx); + if (tctx->error != EOK) { + goto done; } - tevent_req_set_callback(req, mod_group_transaction, tctx); - while (!tctx->transaction_done) { - tevent_loop_once(tctx->ev); + /* groupmod */ + ret = groupmod(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx); + if (ret != EOK) { + tctx->error = ret; + + /* cancel transaction */ + talloc_zfree(tctx->handle); + goto done; } + end_transaction(tctx); + +done: if (tctx->error) { ret = tctx->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); diff --git a/server/tools/sss_sync_ops.c b/server/tools/sss_sync_ops.c index 50eb197e..68fe73e5 100644 --- a/server/tools/sss_sync_ops.c +++ b/server/tools/sss_sync_ops.c @@ -23,7 +23,6 @@ #include "util/util.h" #include "db/sysdb.h" - #include "tools/sss_sync_ops.h" /* Default settings for user attributes */ @@ -1468,3 +1467,82 @@ static void groupmod_done(struct tevent_req *req) res->error = ret; } +/* + * Synchronous transaction functions + */ +static void start_transaction_done(struct tevent_req *req); + +void start_transaction(struct tools_ctx *tctx) +{ + struct tevent_req *req; + + /* make sure handle is NULL, as it is the spy to check if the transaction + * has been started */ + tctx->handle = NULL; + tctx->error = 0; + + req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->sysdb); + if (!req) { + DEBUG(1, ("Could not start transaction\n")); + tctx->error = ENOMEM; + return; + } + tevent_req_set_callback(req, start_transaction_done, tctx); + + /* loop to obtain a transaction */ + while (!tctx->handle && !tctx->error) { + tevent_loop_once(tctx->ev); + } +} + +static void start_transaction_done(struct tevent_req *req) +{ + struct tools_ctx *tctx = tevent_req_callback_data(req, + struct tools_ctx); + int ret; + + ret = sysdb_transaction_recv(req, tctx, &tctx->handle); + if (ret) { + tctx->error = ret; + } + if (!tctx->handle) { + tctx->error = EIO; + } + talloc_zfree(req); +} + +static void end_transaction_done(struct tevent_req *req); + +void end_transaction(struct tools_ctx *tctx) +{ + struct tevent_req *req; + + tctx->error = 0; + + req = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); + if (!req) { + /* free transaction and signal error */ + tctx->error = ENOMEM; + return; + } + tevent_req_set_callback(req, end_transaction_done, tctx); + + /* loop to obtain a transaction */ + while (!tctx->transaction_done && !tctx->error) { + tevent_loop_once(tctx->ev); + } +} + +static void end_transaction_done(struct tevent_req *req) +{ + struct tools_ctx *tctx = tevent_req_callback_data(req, + struct tools_ctx); + int ret; + + ret = sysdb_transaction_commit_recv(req); + + tctx->transaction_done = true; + tctx->error = ret; + talloc_zfree(req); +} + diff --git a/server/tools/sss_sync_ops.h b/server/tools/sss_sync_ops.h index 525f2ff1..c99b9b91 100644 --- a/server/tools/sss_sync_ops.h +++ b/server/tools/sss_sync_ops.h @@ -21,6 +21,7 @@ #ifndef __SSS_OPS_H__ #define __SSS_OPS_H__ +#include "tools/tools_util.h" #include <stdbool.h> #define DO_LOCK 1 @@ -82,5 +83,8 @@ int groupmod(TALLOC_CTX *mem_ctx, struct sysdb_handle *handle, struct ops_ctx *data); +void start_transaction(struct tools_ctx *tctx); +void end_transaction(struct tools_ctx *tctx); + #endif /* __SSS_OPS_H__ */ diff --git a/server/tools/sss_useradd.c b/server/tools/sss_useradd.c index 61034bef..07e741e4 100644 --- a/server/tools/sss_useradd.c +++ b/server/tools/sss_useradd.c @@ -30,6 +30,7 @@ #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" +#include "tools/sss_sync_ops.h" #include "util/sssd-i18n.h" /* Default settings for user attributes */ @@ -107,42 +108,6 @@ done: return ret; } -static void add_user_transaction(struct tevent_req *req) -{ - int ret; - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - struct tevent_req *subreq; - - ret = sysdb_transaction_recv(req, tctx, &tctx->handle); - if (ret) { - tevent_req_error(req, ret); - return; - } - talloc_zfree(req); - - /* useradd */ - ret = useradd(tctx, tctx->ev, - tctx->sysdb, tctx->handle, tctx->octx); - if (ret != EOK) { - goto fail; - } - - subreq = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, tools_transaction_done, tctx); - return; - -fail: - /* free transaction and signal error */ - talloc_zfree(tctx->handle); - tctx->transaction_done = true; - tctx->error = ret; -} - int main(int argc, const char **argv) { uid_t pc_uid = 0; @@ -164,7 +129,6 @@ int main(int argc, const char **argv) POPT_TABLEEND }; poptContext pc = NULL; - struct tevent_req *req; struct tools_ctx *tctx = NULL; char *groups = NULL; int ret; @@ -272,30 +236,33 @@ int main(int argc, const char **argv) goto fini; } - /* useradd */ - req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->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; + start_transaction(tctx); + if (tctx->error != EOK) { + goto done; } - tevent_req_set_callback(req, add_user_transaction, tctx); - while (!tctx->transaction_done) { - tevent_loop_once(tctx->ev); + /* useradd */ + ret = useradd(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx); + if (ret != EOK) { + tctx->error = ret; + + /* cancel transaction */ + talloc_zfree(tctx->handle); + goto done; } + end_transaction(tctx); + +done: if (tctx->error) { - ret = tctx->error; - switch (ret) { + switch (tctx->error) { case EEXIST: ERROR("A user with the same name or UID already exists\n"); break; default: DEBUG(1, ("sysdb operation failed (%d)[%s]\n", - ret, strerror(ret))); + tctx->error, strerror(tctx->error))); ERROR("Transaction error. Could not add user.\n"); break; } diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c index 83db3cd5..8c7c7bd7 100644 --- a/server/tools/sss_userdel.c +++ b/server/tools/sss_userdel.c @@ -29,47 +29,11 @@ #include "db/sysdb.h" #include "util/util.h" #include "tools/tools_util.h" - -static void del_user_transaction(struct tevent_req *req) -{ - int ret; - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - struct tevent_req *subreq; - - ret = sysdb_transaction_recv(req, tctx, &tctx->handle); - if (ret) { - tevent_req_error(req, ret); - return; - } - talloc_zfree(req); - - /* userdel */ - ret = userdel(tctx, tctx->ev, - tctx->sysdb, tctx->handle, tctx->octx); - if (ret != EOK) { - goto fail; - } - - subreq = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, tools_transaction_done, tctx); - return; - -fail: - /* free transaction and signal error */ - talloc_zfree(tctx->handle); - tctx->transaction_done = true; - tctx->error = ret; -} +#include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { int ret = EXIT_SUCCESS; - struct tevent_req *req; struct tools_ctx *tctx = NULL; struct passwd *pwd_info; const char *pc_username = NULL; @@ -141,20 +105,24 @@ int main(int argc, const char **argv) goto fini; } - /* userdel */ - req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->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; + start_transaction(tctx); + if (tctx->error != EOK) { + goto done; } - tevent_req_set_callback(req, del_user_transaction, tctx); - while (!tctx->transaction_done) { - tevent_loop_once(tctx->ev); + /* userdel */ + ret = userdel(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx); + if (ret != EOK) { + tctx->error = ret; + + /* cancel transaction */ + talloc_zfree(tctx->handle); + goto done; } + end_transaction(tctx); + +done: if (tctx->error) { ret = tctx->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); diff --git a/server/tools/sss_usermod.c b/server/tools/sss_usermod.c index 5be1dfb6..2c2b80ec 100644 --- a/server/tools/sss_usermod.c +++ b/server/tools/sss_usermod.c @@ -30,42 +30,7 @@ #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" - -static void mod_user_transaction(struct tevent_req *req) -{ - int ret; - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - struct tevent_req *subreq; - - ret = sysdb_transaction_recv(req, tctx, &tctx->handle); - if (ret) { - tevent_req_error(req, ret); - return; - } - talloc_zfree(req); - - /* usermod */ - ret = usermod(tctx, tctx->ev, - tctx->sysdb, tctx->handle, tctx->octx); - if (ret != EOK) { - goto fail; - } - - subreq = sysdb_transaction_commit_send(tctx, tctx->ev, tctx->handle); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, tools_transaction_done, tctx); - return; - -fail: - /* free transaction and signal error */ - talloc_zfree(tctx->handle); - tctx->transaction_done = true; - tctx->error = ret; -} +#include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { @@ -95,7 +60,6 @@ int main(int argc, const char **argv) int ret; const char *pc_username = NULL; struct tools_ctx *tctx = NULL; - struct tevent_req *req; debug_prg_name = argv[0]; @@ -215,19 +179,24 @@ int main(int argc, const char **argv) tctx->octx->gid = pc_gid; tctx->octx->lock = pc_lock; - req = sysdb_transaction_send(tctx->octx, tctx->ev, tctx->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; + start_transaction(tctx); + if (tctx->error != EOK) { + goto done; } - tevent_req_set_callback(req, mod_user_transaction, tctx); - while (!tctx->transaction_done) { - tevent_loop_once(tctx->ev); + /* usermod */ + ret = usermod(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx); + if (ret != EOK) { + tctx->error = ret; + + /* cancel transaction */ + talloc_zfree(tctx->handle); + goto done; } + end_transaction(tctx); + +done: if (tctx->error) { ret = tctx->error; switch (ret) { diff --git a/server/tools/tools_util.c b/server/tools/tools_util.c index a6ccbc94..77721721 100644 --- a/server/tools/tools_util.c +++ b/server/tools/tools_util.c @@ -28,19 +28,13 @@ #include "confdb/confdb.h" #include "db/sysdb.h" #include "tools/tools_util.h" +#include "tools/sss_sync_ops.h" -static int setup_db(TALLOC_CTX *mem_ctx, struct tools_ctx **tools_ctx) +static int setup_db(struct tools_ctx *ctx) { char *confdb_path; - struct tools_ctx *ctx; int ret; - ctx = talloc_zero(mem_ctx, struct tools_ctx); - if (ctx == NULL) { - DEBUG(1, ("Could not allocate memory for tools context\n")); - return ENOMEM; - } - /* Create the event context */ ctx->ev = tevent_context_init(ctx); if (ctx->ev == NULL) { @@ -79,7 +73,6 @@ static int setup_db(TALLOC_CTX *mem_ctx, struct tools_ctx **tools_ctx) } talloc_free(confdb_path); - *tools_ctx = ctx; return EOK; } @@ -238,18 +231,15 @@ int init_sss_tools(struct tools_ctx **_tctx) { int ret; struct tools_ctx *tctx; - struct ops_ctx *octx; - octx = talloc_zero(NULL, struct ops_ctx); - if (octx == NULL) { - DEBUG(1, ("Could not allocate memory for data context\n")); - ERROR("Out of memory\n"); - ret = ENOMEM; - goto fini; + tctx = talloc_zero(NULL, struct tools_ctx); + if (tctx == NULL) { + DEBUG(1, ("Could not allocate memory for tools context\n")); + return ENOMEM; } /* Connect to the database */ - ret = setup_db(octx, &tctx); + ret = setup_db(tctx); if (ret != EOK) { DEBUG(1, ("Could not set up database\n")); goto fini; @@ -261,24 +251,20 @@ int init_sss_tools(struct tools_ctx **_tctx) goto fini; } - octx->domain = tctx->local; - tctx->octx = octx; + tctx->octx = talloc_zero(tctx, struct ops_ctx); + if (!tctx->octx) { + DEBUG(1, ("Could not allocate memory for data context\n")); + ERROR("Out of memory\n"); + ret = ENOMEM; + goto fini; + } + tctx->octx->domain = tctx->local; *_tctx = tctx; ret = EOK; + fini: + if (ret != EOK) talloc_free(tctx); return ret; } -/* - * Common transaction finish - */ -void tools_transaction_done(struct tevent_req *req) -{ - struct tools_ctx *tctx = tevent_req_callback_data(req, - struct tools_ctx); - - tctx->error = sysdb_transaction_commit_recv(req); - tctx->transaction_done = true; -} - diff --git a/server/tools/tools_util.h b/server/tools/tools_util.h index f17e68da..c062dece 100644 --- a/server/tools/tools_util.h +++ b/server/tools/tools_util.h @@ -26,7 +26,6 @@ #include <popt.h> #include "util/sssd-i18n.h" -#include "tools/sss_sync_ops.h" #define CHECK_ROOT(val, prg_name) do { \ val = getuid(); \ @@ -49,7 +48,7 @@ struct tools_ctx { struct ops_ctx *octx; struct sysdb_handle *handle; - int transaction_done; + bool transaction_done; int error; }; @@ -73,6 +72,4 @@ int parse_groups(TALLOC_CTX *mem_ctx, int parse_group_name_domain(struct tools_ctx *tctx, char **groups); -void tools_transaction_done(struct tevent_req *req); - #endif /* __TOOLS_UTIL_H__ */ |