From 49d051dcce7fbc01111cf0eae7c1f45600cff516 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 9 Jul 2009 18:43:45 -0400 Subject: Start rationalizing user tools a bit There is a lot of duplication in user tools. First steps to remove as much duplication as possible. --- server/tools/sss_groupadd.c | 77 +++++++++------------ server/tools/sss_groupdel.c | 99 +++++++++++--------------- server/tools/sss_groupmod.c | 113 +++++++++++++----------------- server/tools/sss_useradd.c | 165 +++++++++++++++++--------------------------- server/tools/sss_userdel.c | 106 +++++++++++----------------- server/tools/sss_usermod.c | 124 ++++++++++++++------------------- server/tools/tools_util.h | 23 ++++++ 7 files changed, 299 insertions(+), 408 deletions(-) diff --git a/server/tools/sss_groupadd.c b/server/tools/sss_groupadd.c index 40df8c92b..e9c81b8f3 100644 --- a/server/tools/sss_groupadd.c +++ b/server/tools/sss_groupadd.c @@ -44,30 +44,15 @@ #define GROUPADD_GROUPNAME "%s " #endif -struct group_add_ctx { - struct tevent_context *ev; - struct sysdb_handle *handle; - - struct sss_domain_info *domain; - struct tools_ctx *ctx; - - const char *groupname; - gid_t gid; - - int error; - bool done; -}; - static void add_group_req_done(struct tevent_req *req) { - struct group_add_ctx *data = tevent_req_callback_data(req, - struct group_add_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); data->error = sysdb_transaction_commit_recv(req); data->done = true; } -static void add_group_terminate(struct group_add_ctx *data, int error) +static void add_group_terminate(struct ops_ctx *data, int error) { struct tevent_req *req; @@ -96,8 +81,7 @@ static void add_group_done(struct tevent_req *subreq); static void add_group(struct tevent_req *req) { - struct group_add_ctx *data = tevent_req_callback_data(req, - struct group_add_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); struct tevent_req *subreq; int ret; @@ -107,7 +91,7 @@ static void add_group(struct tevent_req *req) } subreq = sysdb_add_group_send(data, data->ev, data->handle, - data->domain, data->groupname, + data->domain, data->name, data->gid, NULL); if (!subreq) { add_group_terminate(data, ENOMEM); @@ -117,8 +101,7 @@ static void add_group(struct tevent_req *req) static void add_group_done(struct tevent_req *subreq) { - struct group_add_ctx *data = tevent_req_callback_data(subreq, - struct group_add_ctx); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_add_group_recv(subreq); @@ -127,7 +110,7 @@ static void add_group_done(struct tevent_req *subreq) return add_group_terminate(data, ret); } -static int groupadd_legacy(struct group_add_ctx *ctx) +static int groupadd_legacy(struct ops_ctx *ctx) { int ret = EOK; char *command = NULL; @@ -139,14 +122,15 @@ static int groupadd_legacy(struct group_add_ctx *ctx) } APPEND_PARAM(command, GROUPADD_GID, ctx->gid); - APPEND_STRING(command, ctx->groupname); + APPEND_STRING(command, ctx->name); ret = system(command); if (ret) { if (ret == -1) { DEBUG(1, ("system(3) failed\n")); } else { - DEBUG(1, ("Could not exec '%s', return code: %d\n", command, WEXITSTATUS(ret))); + DEBUG(1, ("Could not exec '%s', return code: %d\n", + command, WEXITSTATUS(ret))); } talloc_free(command); return EFAULT; @@ -162,15 +146,17 @@ int main(int argc, const char **argv) int pc_debug = 0; struct poptOption long_options[] = { POPT_AUTOHELP - { "debug",'\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, - { "gid", 'g', POPT_ARG_INT, &pc_gid, 0, _("The GID of the group"), NULL }, + { "debug",'\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, + 0, _("The debug level to run with"), NULL }, + { "gid", 'g', POPT_ARG_INT, &pc_gid, + 0, _("The GID of the group"), NULL }, POPT_TABLEEND }; struct sss_domain_info *dom; poptContext pc = NULL; struct tools_ctx *ctx = NULL; struct tevent_req *req; - struct group_add_ctx *group_ctx = NULL; + struct ops_ctx *data = NULL; int ret = EXIT_SUCCESS; debug_prg_name = argv[0]; @@ -192,13 +178,14 @@ int main(int argc, const char **argv) goto fini; } - group_ctx = talloc_zero(NULL, struct group_add_ctx); - if (group_ctx == NULL) { - DEBUG(1, ("Could not allocate memory for group_ctx context\n")); + data = talloc_zero(NULL, struct ops_ctx); + if (data == NULL) { + DEBUG(1, ("Could not allocate memory for data context\n")); ERROR("Out of memory.\n"); return ENOMEM; } - group_ctx->ctx = ctx; + data->ctx = ctx; + data->ev = ctx->ev; /* parse params */ pc = poptGetContext(NULL, argc, argv, long_options, 0); @@ -212,26 +199,26 @@ int main(int argc, const char **argv) debug_level = pc_debug; /* groupname is an argument, not option */ - group_ctx->groupname = poptGetArg(pc); - if(group_ctx->groupname == NULL) { + data->name = poptGetArg(pc); + if (data->name == NULL) { usage(pc, _("Specify group to add\n")); ret = EXIT_FAILURE; goto fini; } - group_ctx->gid = pc_gid; + data->gid = pc_gid; /* arguments processed, go on to actual work */ - ret = find_domain_for_id(ctx, group_ctx->gid, &dom); + ret = find_domain_for_id(ctx, data->gid, &dom); switch (ret) { case ID_IN_LOCAL: - group_ctx->domain = dom; + data->domain = dom; break; case ID_IN_LEGACY_LOCAL: - group_ctx->domain = dom; + data->domain = dom; case ID_OUTSIDE: - ret = groupadd_legacy(group_ctx); + ret = groupadd_legacy(data); if(ret != EOK) { ERROR("Cannot add group to domain using the legacy tools\n"); } @@ -258,17 +245,17 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - tevent_req_set_callback(req, add_group, group_ctx); + tevent_req_set_callback(req, add_group, data); - while (!group_ctx->done) { + while (!data->done) { tevent_loop_once(ctx->ev); } - if (group_ctx->error) { - ret = group_ctx->error; + if (data->error) { + ret = data->error; switch (ret) { case EEXIST: - ERROR("The group %s already exists\n", group_ctx->groupname); + ERROR("The group %s already exists\n", data->name); break; default: @@ -282,7 +269,7 @@ int main(int argc, const char **argv) ret = EXIT_SUCCESS; fini: - talloc_free(group_ctx); + talloc_free(data); talloc_free(ctx); poptFreeContext(pc); exit(ret); diff --git a/server/tools/sss_groupdel.c b/server/tools/sss_groupdel.c index 7b65b7d47..98d73c397 100644 --- a/server/tools/sss_groupdel.c +++ b/server/tools/sss_groupdel.c @@ -41,26 +41,9 @@ #endif -struct group_del_ctx { - struct tevent_context *ev; - struct sysdb_handle *handle; - sysdb_callback_t next_fn; - - gid_t gid; - const char *groupname; - struct ldb_dn *group_dn; - - struct sss_domain_info *domain; - struct tools_ctx *ctx; - - int error; - 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); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); data->error = sysdb_transaction_commit_recv(req); data->done = true; @@ -69,7 +52,7 @@ static void groupdel_req_done(struct tevent_req *req) /* 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 ops_ctx *data = talloc_get_type(pvt, struct ops_ctx); struct tevent_req *req; if (error != EOK) { @@ -97,9 +80,9 @@ static void group_del_done(struct tevent_req *subreq); static void group_del(struct tevent_req *req) { - struct group_del_ctx *data = tevent_req_callback_data(req, - struct group_del_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); struct tevent_req *subreq; + struct ldb_dn *group_dn; int ret; ret = sysdb_transaction_recv(req, data, &data->handle); @@ -107,10 +90,14 @@ static void group_del(struct tevent_req *req) return groupdel_done(data, ret, NULL); } - subreq = sysdb_delete_entry_send(data, - data->ev, - data->handle, - data->group_dn); + group_dn = sysdb_group_dn(data->ctx->sysdb, data, + data->domain->name, data->name); + if (group_dn == NULL) { + DEBUG(1, ("Could not construct a group DN\n")); + return groupdel_done(data, ENOMEM, NULL); + } + + subreq = sysdb_delete_entry_send(data, data->ev, data->handle, group_dn); if (!subreq) return groupdel_done(data, ret, NULL); @@ -119,8 +106,7 @@ static void group_del(struct tevent_req *req) static void group_del_done(struct tevent_req *subreq) { - struct group_del_ctx *data = tevent_req_callback_data(subreq, - struct group_del_ctx); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_delete_entry_recv(subreq); @@ -128,20 +114,21 @@ static void group_del_done(struct tevent_req *subreq) return groupdel_done(data, ret, NULL); } -static int groupdel_legacy(struct group_del_ctx *ctx) +static int groupdel_legacy(struct ops_ctx *ctx) { int ret = EOK; char *command = NULL; APPEND_STRING(command, GROUPDEL); - APPEND_PARAM(command, GROUPDEL_GROUPNAME, ctx->groupname); + APPEND_PARAM(command, GROUPDEL_GROUPNAME, ctx->name); ret = system(command); if (ret) { if (ret == -1) { DEBUG(1, ("system(3) failed\n")); } else { - DEBUG(1, ("Could not exec '%s', return code: %d\n", command, WEXITSTATUS(ret))); + DEBUG(1, ("Could not exec '%s', return code: %d\n", + command, WEXITSTATUS(ret))); } talloc_free(command); return EFAULT; @@ -155,7 +142,7 @@ int main(int argc, const char **argv) { int ret = EXIT_SUCCESS; int pc_debug = 0; - struct group_del_ctx *group_ctx = NULL; + struct ops_ctx *data = NULL; struct tools_ctx *ctx = NULL; struct tevent_req *req; struct sss_domain_info *dom; @@ -164,7 +151,8 @@ int main(int argc, const char **argv) poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP - { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, + { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, + 0, _("The debug level to run with"), NULL }, POPT_TABLEEND }; @@ -187,15 +175,16 @@ int main(int argc, const char **argv) goto fini; } - group_ctx = talloc_zero(NULL, struct group_del_ctx); - if (group_ctx == NULL) { - DEBUG(1, ("Could not allocate memory for group_ctx context\n")); + data = talloc_zero(NULL, struct ops_ctx); + if (data == NULL) { + DEBUG(1, ("Could not allocate memory for data context\n")); ERROR("Out of memory\n"); return ENOMEM; } - group_ctx->ctx = ctx; + data->ctx = ctx; + data->ev = ctx->ev; - /* parse group_ctx */ + /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); if((ret = poptGetNextOpt(pc)) < -1) { @@ -206,29 +195,29 @@ int main(int argc, const char **argv) debug_level = pc_debug; - group_ctx->groupname = poptGetArg(pc); - if(group_ctx->groupname == NULL) { + data->name = poptGetArg(pc); + if(data->name == NULL) { usage(pc, _("Specify group to delete\n")); ret = EXIT_FAILURE; goto fini; } /* arguments processed, go on to actual work */ - grp_info = getgrnam(group_ctx->groupname); + grp_info = getgrnam(data->name); if (grp_info) { - group_ctx->gid = grp_info->gr_gid; + data->gid = grp_info->gr_gid; } - ret = find_domain_for_id(ctx, group_ctx->gid, &dom); + ret = find_domain_for_id(ctx, data->gid, &dom); switch (ret) { case ID_IN_LOCAL: - group_ctx->domain = dom; + data->domain = dom; break; case ID_IN_LEGACY_LOCAL: - group_ctx->domain = dom; + data->domain = dom; case ID_OUTSIDE: - ret = groupdel_legacy(group_ctx); + ret = groupdel_legacy(data); if(ret != EOK) { ERROR("Cannot delete group from domain using the legacy tools\n"); ret = EXIT_FAILURE; @@ -249,16 +238,6 @@ int main(int argc, const char **argv) goto fini; } - group_ctx->group_dn = sysdb_group_dn(ctx->sysdb, ctx, - group_ctx->domain->name, - group_ctx->groupname); - if(group_ctx->group_dn == NULL) { - DEBUG(1, ("Could not construct a group DN\n")); - ERROR("Internal database error. Could not remove group.\n"); - ret = EXIT_FAILURE; - goto fini; - } - /* groupdel */ req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb); if (!req) { @@ -267,14 +246,14 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - tevent_req_set_callback(req, group_del, group_ctx); + tevent_req_set_callback(req, group_del, data); - while (!group_ctx->done) { + while (!data->done) { tevent_loop_once(ctx->ev); } - if (group_ctx->error) { - ret = group_ctx->error; + if (data->error) { + ret = data->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); ERROR("Transaction error. Could not remove group.\n"); ret = EXIT_FAILURE; @@ -285,7 +264,7 @@ int main(int argc, const char **argv) fini: talloc_free(ctx); - talloc_free(group_ctx); + talloc_free(data); poptFreeContext(pc); exit(ret); } diff --git a/server/tools/sss_groupmod.c b/server/tools/sss_groupmod.c index 9f6a9740b..2fc6f9de5 100644 --- a/server/tools/sss_groupmod.c +++ b/server/tools/sss_groupmod.c @@ -45,34 +45,15 @@ #define GROUPMOD_GROUPNAME "%s " #endif -struct group_mod_ctx { - struct tevent_context *ev; - struct sysdb_handle *handle; - struct sss_domain_info *domain; - - struct tools_ctx *ctx; - - gid_t gid; - const char *groupname; - - char **addgroups; - char **rmgroups; - int cur; - - int error; - bool done; -}; - static void mod_group_req_done(struct tevent_req *req) { - struct group_mod_ctx *data = tevent_req_callback_data(req, - struct group_mod_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); data->error = sysdb_transaction_commit_recv(req); data->done = true; } -static void mod_group_done(struct group_mod_ctx *data, int error) +static void mod_group_done(struct ops_ctx *data, int error) { struct tevent_req *req; @@ -98,20 +79,20 @@ fail: } 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 mod_group_cont(struct ops_ctx *data); +static void remove_from_groups(struct ops_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(struct ops_ctx *data); static void add_to_groups_done(struct tevent_req *req); static void mod_group(struct tevent_req *req) { - struct group_mod_ctx *data; + struct ops_ctx *data; struct tevent_req *subreq; struct sysdb_attrs *attrs; int ret; - data = tevent_req_callback_data(req, struct group_mod_ctx); + data = tevent_req_callback_data(req, struct ops_ctx); ret = sysdb_transaction_recv(req, data, &data->handle); if (ret != EOK) { @@ -130,7 +111,7 @@ static void mod_group(struct tevent_req *req) } subreq = sysdb_set_group_attr_send(data, data->ev, data->handle, - data->domain, data->groupname, + data->domain, data->name, attrs, SYSDB_MOD_REP); if (!subreq) { return mod_group_done(data, ret); @@ -144,8 +125,7 @@ static void mod_group(struct tevent_req *req) static void mod_group_attr_done(struct tevent_req *subreq) { - struct group_mod_ctx *data = tevent_req_callback_data(subreq, - struct group_mod_ctx); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_set_group_attr_recv(subreq); @@ -157,7 +137,7 @@ static void mod_group_attr_done(struct tevent_req *subreq) mod_group_cont(data); } -static void mod_group_cont(struct group_mod_ctx *data) +static void mod_group_cont(struct ops_ctx *data) { if (data->rmgroups != NULL) { return remove_from_groups(data); @@ -170,14 +150,14 @@ static void mod_group_cont(struct group_mod_ctx *data) return mod_group_done(data, EOK); } -static void remove_from_groups(struct group_mod_ctx *data) +static void remove_from_groups(struct ops_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); + data->domain->name, data->name); if (!member_dn) { return mod_group_done(data, ENOMEM); } @@ -203,8 +183,7 @@ static void remove_from_groups(struct group_mod_ctx *data) static void remove_from_groups_done(struct tevent_req *req) { - struct group_mod_ctx *data = tevent_req_callback_data(req, - struct group_mod_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); int ret; ret = sysdb_mod_group_member_recv(req); @@ -228,14 +207,14 @@ static void remove_from_groups_done(struct tevent_req *req) return remove_from_groups(data); } -static void add_to_groups(struct group_mod_ctx *data) +static void add_to_groups(struct ops_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); + data->domain->name, data->name); if (!member_dn) { return mod_group_done(data, ENOMEM); } @@ -261,8 +240,7 @@ static void add_to_groups(struct group_mod_ctx *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); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); int ret; ret = sysdb_mod_group_member_recv(req); @@ -282,7 +260,8 @@ static void add_to_groups_done(struct tevent_req *req) return add_to_groups(data); } -static int groupmod_legacy(struct tools_ctx *tools_ctx, struct group_mod_ctx *ctx, int old_domain) +static int groupmod_legacy(struct tools_ctx *tools_ctx, + struct ops_ctx *ctx, int old_domain) { int ret = EOK; char *command = NULL; @@ -307,14 +286,15 @@ static int groupmod_legacy(struct tools_ctx *tools_ctx, struct group_mod_ctx *ct } } - APPEND_PARAM(command, GROUPMOD_GROUPNAME, ctx->groupname); + APPEND_PARAM(command, GROUPMOD_GROUPNAME, ctx->name); ret = system(command); if (ret) { if (ret == -1) { DEBUG(1, ("system(3) failed\n")); } else { - DEBUG(1, ("Could not exec '%s', return code: %d\n", command, WEXITSTATUS(ret))); + DEBUG(1, ("Could not exec '%s', return code: %d\n", + command, WEXITSTATUS(ret))); } talloc_free(command); return EFAULT; @@ -330,15 +310,19 @@ int main(int argc, const char **argv) int pc_debug = 0; struct poptOption long_options[] = { POPT_AUTOHELP - { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, - { "append-group", 'a', POPT_ARG_STRING, NULL, 'a', _("Groups to add this group to"), NULL }, - { "remove-group", 'r', POPT_ARG_STRING, NULL, 'r', _("Groups to remove this group from"), NULL }, - { "gid", 'g', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_gid, 0, _("The GID of the group"), NULL }, + { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, + 0, _("The debug level to run with"), NULL }, + { "append-group", 'a', POPT_ARG_STRING, NULL, + 'a', _("Groups to add this group to"), NULL }, + { "remove-group", 'r', POPT_ARG_STRING, NULL, + 'r', _("Groups to remove this group from"), NULL }, + { "gid", 'g', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_gid, + 0, _("The GID of the group"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; struct sss_domain_info *dom; - struct group_mod_ctx *group_ctx = NULL; + struct ops_ctx *data = NULL; struct tools_ctx *ctx = NULL; struct tevent_req *req; char *groups; @@ -365,15 +349,16 @@ int main(int argc, const char **argv) goto fini; } - group_ctx = talloc_zero(ctx, struct group_mod_ctx); - if (group_ctx == NULL) { - DEBUG(1, ("Could not allocate memory for group_ctx context\n")); + data = talloc_zero(ctx, struct ops_ctx); + if (data == NULL) { + DEBUG(1, ("Could not allocate memory for data context\n")); ERROR("Out of memory\n"); return ENOMEM; } - group_ctx->ctx = ctx; + data->ctx = ctx; + data->ev = ctx->ev; - /* parse group_ctx */ + /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { @@ -386,7 +371,7 @@ int main(int argc, const char **argv) ret = parse_groups(ctx, groups, - (ret == 'a') ? (&group_ctx->addgroups) : (&group_ctx->rmgroups)); + (ret == 'a') ? (&data->addgroups) : (&data->rmgroups)); free(groups); if (ret != EOK) { @@ -397,24 +382,24 @@ int main(int argc, const char **argv) debug_level = pc_debug; - if(ret != -1) { + if (ret != -1) { usage(pc, poptStrerror(ret)); ret = EXIT_FAILURE; goto fini; } /* groupname is an argument without --option */ - group_ctx->groupname = poptGetArg(pc); - if (group_ctx->groupname == NULL) { + data->name = poptGetArg(pc); + if (data->name == NULL) { usage(pc, _("Specify group to modify\n")); ret = EXIT_FAILURE; goto fini; } - group_ctx->gid = pc_gid; + data->gid = pc_gid; /* arguments processed, go on to actual work */ - grp_info = getgrnam(group_ctx->groupname); + grp_info = getgrnam(data->name); if (grp_info) { old_gid = grp_info->gr_gid; } @@ -422,13 +407,13 @@ int main(int argc, const char **argv) ret = find_domain_for_id(ctx, old_gid, &dom); switch (ret) { case ID_IN_LOCAL: - group_ctx->domain = dom; + data->domain = dom; break; case ID_IN_LEGACY_LOCAL: - group_ctx->domain = dom; + data->domain = dom; case ID_OUTSIDE: - ret = groupmod_legacy(ctx, group_ctx, ret); + ret = groupmod_legacy(ctx, data, ret); if(ret != EOK) { ERROR("Cannot delete group from domain using the legacy tools\n"); } @@ -454,14 +439,14 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - tevent_req_set_callback(req, mod_group, group_ctx); + tevent_req_set_callback(req, mod_group, data); - while (!group_ctx->done) { + while (!data->done) { tevent_loop_once(ctx->ev); } - if (group_ctx->error) { - ret = group_ctx->error; + if (data->error) { + ret = data->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); ERROR("Transaction error. Could not modify group.\n"); ret = EXIT_FAILURE; diff --git a/server/tools/sss_useradd.c b/server/tools/sss_useradd.c index f9482aa7b..2880182c0 100644 --- a/server/tools/sss_useradd.c +++ b/server/tools/sss_useradd.c @@ -84,38 +84,9 @@ #define DFL_SHELL_VAL "/bin/bash" #define DFL_BASEDIR_VAL "/home" -struct user_add_ctx { - struct tevent_context *ev; - struct sysdb_handle *handle; - - struct sss_domain_info *domain; - struct tools_ctx *ctx; - - const char *username; - uid_t uid; - gid_t gid; - char *gecos; - char *home; - char *shell; - - char **groups; - int cur; - - int error; - bool done; -}; - -struct fetch_group { - gid_t gid; - int error; - bool done; -}; - static void get_gid_callback(void *ptr, int error, struct ldb_result *res) { - struct fetch_group *data = talloc_get_type(ptr, struct fetch_group); - - data->done = true; + struct ops_ctx *data = talloc_get_type(ptr, struct ops_ctx); if (error) { data->error = error; @@ -129,6 +100,9 @@ static void get_gid_callback(void *ptr, int error, struct ldb_result *res) case 1: data->gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 0); + if (data->gid == 0) { + data->error = ERANGE; + } break; default: @@ -141,64 +115,50 @@ static void get_gid_callback(void *ptr, int error, struct ldb_result *res) * is given, returns that as integer (rationale: shadow-utils) * On error, returns -EINVAL */ -static int get_gid(struct user_add_ctx *user_ctx, const char *groupname) +static int get_gid(struct ops_ctx *data, const char *groupname) { - struct tools_ctx *ctx = user_ctx->ctx; - struct fetch_group *data = NULL; char *end_ptr; - gid_t gid; int ret; errno = 0; - gid = strtoul(groupname, &end_ptr, 10); - if (groupname == '\0' || *end_ptr != '\0' || errno != 0) { + data->gid = strtoul(groupname, &end_ptr, 10); + if (groupname == '\0' || *end_ptr != '\0' || + errno != 0 || data->gid == 0) { /* Does not look like a gid - find the group name */ - data = talloc_zero(ctx, struct fetch_group); - if (!data) return ENOMEM; - - ret = sysdb_getgrnam(data, ctx->sysdb, - user_ctx->domain, groupname, + ret = sysdb_getgrnam(data, data->ctx->sysdb, + data->domain, groupname, get_gid_callback, data); if (ret != EOK) { DEBUG(1, ("sysdb_getgrnam failed: %d\n", ret)); goto done; } - while (!data->done) { - tevent_loop_once(ctx->ev); + data->error = EOK; + data->gid = 0; + while ((data->error == EOK) && (data->gid == 0)) { + tevent_loop_once(data->ctx->ev); } if (data->error) { DEBUG(1, ("sysdb_getgrnam failed: %d\n", ret)); - ret = data->error; goto done; } - - gid = data->gid; - } - - if (gid == 0) { - ret = ERANGE; - } else { - user_ctx->gid = gid; } done: - talloc_free(data); return ret; } static void add_user_req_done(struct tevent_req *req) { - struct user_add_ctx *data = tevent_req_callback_data(req, - struct user_add_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); data->error = sysdb_transaction_commit_recv(req); data->done = true; } -static void add_user_terminate(struct user_add_ctx *data, int error) +static void add_user_terminate(struct ops_ctx *data, int error) { struct tevent_req *req; @@ -224,13 +184,12 @@ fail: } static void add_user_done(struct tevent_req *subreq); -static void add_to_groups(struct user_add_ctx *data); +static void add_to_groups(struct ops_ctx *data); static void add_to_groups_done(struct tevent_req *req); static void add_user(struct tevent_req *req) { - struct user_add_ctx *data = tevent_req_callback_data(req, - struct user_add_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); struct tevent_req *subreq; int ret; @@ -240,7 +199,7 @@ static void add_user(struct tevent_req *req) } subreq = sysdb_add_user_send(data, data->ev, data->handle, - data->domain, data->username, + data->domain, data->name, data->uid, data->gid, data->gecos, data->home, data->shell, NULL); @@ -252,8 +211,7 @@ static void add_user(struct tevent_req *req) static void add_user_done(struct tevent_req *subreq) { - struct user_add_ctx *data = tevent_req_callback_data(subreq, - struct user_add_ctx); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_add_user_recv(subreq); @@ -269,14 +227,14 @@ static void add_user_done(struct tevent_req *subreq) return add_user_terminate(data, ret); } -static void add_to_groups(struct user_add_ctx *data) +static void add_to_groups(struct ops_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); + data->domain->name, data->name); if (!member_dn) { return add_user_terminate(data, ENOMEM); } @@ -299,8 +257,7 @@ static void add_to_groups(struct user_add_ctx *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); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_mod_group_member_recv(subreq); @@ -320,7 +277,7 @@ static void add_to_groups_done(struct tevent_req *subreq) return add_to_groups(data); } -static int useradd_legacy(struct user_add_ctx *ctx, char *grouplist) +static int useradd_legacy(struct ops_ctx *ctx, char *grouplist) { int ret = EOK; char *command = NULL; @@ -343,14 +300,15 @@ static int useradd_legacy(struct user_add_ctx *ctx, char *grouplist) APPEND_PARAM(command, USERADD_GROUPS, grouplist); - APPEND_PARAM(command, USERADD_USERNAME, ctx->username); + APPEND_PARAM(command, USERADD_USERNAME, ctx->name); ret = system(command); if (ret) { if (ret == -1) { DEBUG(1, ("system(3) failed\n")); } else { - DEBUG(1, ("Could not exec '%s', return code: %d\n", command, WEXITSTATUS(ret))); + DEBUG(1, ("Could not exec '%s', return code: %d\n", + command, WEXITSTATUS(ret))); } talloc_free(command); return EFAULT; @@ -382,7 +340,7 @@ int main(int argc, const char **argv) }; poptContext pc = NULL; struct sss_domain_info *dom = NULL; - struct user_add_ctx *user_ctx = NULL; + struct ops_ctx *data = NULL; struct tools_ctx *ctx = NULL; struct tevent_req *req; char *groups = NULL; @@ -407,16 +365,16 @@ int main(int argc, const char **argv) goto fini; } - user_ctx = talloc_zero(ctx, struct user_add_ctx); - if (user_ctx == NULL) { - DEBUG(1, ("Could not allocate memory for user_ctx context\n")); + data = talloc_zero(ctx, struct ops_ctx); + if (data == NULL) { + DEBUG(1, ("Could not allocate memory for ops_ctx context\n")); ERROR("Out of memory\n"); return ENOMEM; } - user_ctx->ctx = ctx; - user_ctx->ev = ctx->ev; + data->ctx = ctx; + data->ev = ctx->ev; - /* parse user_ctx */ + /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { @@ -427,7 +385,7 @@ int main(int argc, const char **argv) break; } - ret = parse_groups(ctx, groups, &user_ctx->groups); + ret = parse_groups(ctx, groups, &data->groups); if (ret != EOK) { break; } @@ -443,8 +401,8 @@ int main(int argc, const char **argv) } /* username is an argument without --option */ - user_ctx->username = poptGetArg(pc); - if (user_ctx->username == NULL) { + data->name = poptGetArg(pc); + if (data->name == NULL) { usage(pc, (_("Specify user to add\n"))); ret = EXIT_FAILURE; goto fini; @@ -452,7 +410,7 @@ int main(int argc, const char **argv) /* Same as shadow-utils useradd, -g can specify gid or group name */ if (pc_group != NULL) { - ret = get_gid(user_ctx, pc_group); + ret = get_gid(data, pc_group); if (ret != EOK) { ERROR("Cannot get group information for the user\n"); ret = EXIT_FAILURE; @@ -460,44 +418,44 @@ int main(int argc, const char **argv) } } - user_ctx->uid = pc_uid; + data->uid = pc_uid; /* - * Fills in defaults for user_ctx user did not specify. + * Fills in defaults for ops_ctx user did not specify. * FIXME - Should this originate from the confdb or another config? */ if (!pc_gecos) { - pc_gecos = user_ctx->username; + pc_gecos = data->name; } - user_ctx->gecos = talloc_strdup(user_ctx, pc_gecos); - if (!user_ctx->gecos) { + data->gecos = talloc_strdup(data, pc_gecos); + if (!data->gecos) { ret = EXIT_FAILURE; goto fini; } if (pc_home) { - user_ctx->home = talloc_strdup(user_ctx, pc_home); + data->home = talloc_strdup(data, pc_home); } else { - ret = confdb_get_string(user_ctx->ctx->confdb, user_ctx, + ret = confdb_get_string(data->ctx->confdb, data, CONFDB_DFL_SECTION, DFL_BASEDIR_ATTR, DFL_BASEDIR_VAL, &basedir); if (ret != EOK) { ret = EXIT_FAILURE; goto fini; } - user_ctx->home = talloc_asprintf(user_ctx, "%s/%s", basedir, user_ctx->username); - if (!user_ctx->home) { + data->home = talloc_asprintf(data, "%s/%s", basedir, data->name); + if (!data->home) { ret = EXIT_FAILURE; goto fini; } } - if (!user_ctx->home) { + if (!data->home) { ret = EXIT_FAILURE; goto fini; } if (!pc_shell) { - ret = confdb_get_string(user_ctx->ctx->confdb, user_ctx, + ret = confdb_get_string(data->ctx->confdb, data, CONFDB_DFL_SECTION, DFL_SHELL_ATTR, DFL_SHELL_VAL, &pc_shell); if (ret != EOK) { @@ -505,23 +463,23 @@ int main(int argc, const char **argv) goto fini; } } - user_ctx->shell = talloc_strdup(user_ctx, pc_shell); - if (!user_ctx->shell) { + data->shell = talloc_strdup(data, pc_shell); + if (!data->shell) { ret = EXIT_FAILURE; goto fini; } /* arguments processed, go on to actual work */ - ret = find_domain_for_id(ctx, user_ctx->uid, &dom); + ret = find_domain_for_id(ctx, data->uid, &dom); switch (ret) { case ID_IN_LOCAL: - user_ctx->domain = dom; + data->domain = dom; break; case ID_IN_LEGACY_LOCAL: - user_ctx->domain = dom; + data->domain = dom; case ID_OUTSIDE: - ret = useradd_legacy(user_ctx, groups); + ret = useradd_legacy(data, groups); if(ret != EOK) { ERROR("Cannot add user to domain using the legacy tools\n"); } @@ -548,21 +506,22 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - tevent_req_set_callback(req, add_user, user_ctx); + tevent_req_set_callback(req, add_user, data); - while (!user_ctx->done) { + while (!data->done) { tevent_loop_once(ctx->ev); } - if (user_ctx->error) { - ret = user_ctx->error; + if (data->error) { + ret = data->error; switch (ret) { case EEXIST: - ERROR("The user %s already exists\n", user_ctx->username); + ERROR("The user %s already exists\n", data->name); break; default: - DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); + DEBUG(1, ("sysdb operation failed (%d)[%s]\n", + ret, strerror(ret))); ERROR("Transaction error. Could not modify user.\n"); break; } diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c index 5e400fcb6..f70482ce7 100644 --- a/server/tools/sss_userdel.c +++ b/server/tools/sss_userdel.c @@ -40,26 +40,9 @@ #define USERDEL_USERNAME "%s " #endif -struct user_del_ctx { - struct tevent_context *ev; - struct sysdb_handle *handle; - sysdb_callback_t next_fn; - - uid_t uid; - const char *username; - struct ldb_dn *user_dn; - - struct sss_domain_info *domain; - struct tools_ctx *ctx; - - int error; - 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); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); data->error = sysdb_transaction_commit_recv(req); data->done = true; @@ -68,7 +51,7 @@ static void userdel_req_done(struct tevent_req *req) /* 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 ops_ctx *data = talloc_get_type(pvt, struct ops_ctx); struct tevent_req *req; if (error != EOK) { @@ -96,21 +79,26 @@ static void user_del_done(struct tevent_req *subreq); static void user_del(struct tevent_req *req) { - struct user_del_ctx *data; + struct ops_ctx *data; struct tevent_req *subreq; + struct ldb_dn *user_dn; int ret; - data = tevent_req_callback_data(req, struct user_del_ctx); + data = tevent_req_callback_data(req, struct ops_ctx); ret = sysdb_transaction_recv(req, data, &data->handle); if (ret != EOK) { return userdel_done(data, ret, NULL); } - subreq = sysdb_delete_entry_send(data, - data->ev, - data->handle, - data->user_dn); + user_dn = sysdb_user_dn(data->ctx->sysdb, data, + data->domain->name, data->name); + if (!user_dn) { + DEBUG(1, ("Could not construct a user DN\n")); + return userdel_done(data, ENOMEM, NULL); + } + + subreq = sysdb_delete_entry_send(data, data->ev, data->handle, user_dn); if (!subreq) return userdel_done(data, ret, NULL); @@ -119,8 +107,7 @@ static void user_del(struct tevent_req *req) static void user_del_done(struct tevent_req *subreq) { - struct user_del_ctx *data = tevent_req_callback_data(subreq, - struct user_del_ctx); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_delete_entry_recv(subreq); @@ -129,20 +116,21 @@ static void user_del_done(struct tevent_req *subreq) } -static int userdel_legacy(struct user_del_ctx *ctx) +static int userdel_legacy(struct ops_ctx *ctx) { int ret = EOK; char *command = NULL; APPEND_STRING(command, USERDEL); - APPEND_PARAM(command, USERDEL_USERNAME, ctx->username); + APPEND_PARAM(command, USERDEL_USERNAME, ctx->name); ret = system(command); if (ret) { if (ret == -1) { DEBUG(1, ("system(3) failed\n")); } else { - DEBUG(1, ("Could not exec '%s', return code: %d\n", command, WEXITSTATUS(ret))); + DEBUG(1, ("Could not exec '%s', return code: %d\n", + command, WEXITSTATUS(ret))); } talloc_free(command); return EFAULT; @@ -155,7 +143,7 @@ static int userdel_legacy(struct user_del_ctx *ctx) int main(int argc, const char **argv) { int ret = EXIT_SUCCESS; - struct user_del_ctx *user_ctx = NULL; + struct ops_ctx *data = NULL; struct tools_ctx *ctx = NULL; struct tevent_req *req; struct sss_domain_info *dom; @@ -165,7 +153,8 @@ int main(int argc, const char **argv) poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP - { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, + { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, + 0, _("The debug level to run with"), NULL }, POPT_TABLEEND }; @@ -188,19 +177,19 @@ int main(int argc, const char **argv) goto fini; } - user_ctx = talloc_zero(NULL, struct user_del_ctx); - if (user_ctx == NULL) { - DEBUG(1, ("Could not allocate memory for user_ctx context\n")); + data = talloc_zero(NULL, struct ops_ctx); + if (data == NULL) { + DEBUG(1, ("Could not allocate memory for data context\n")); ERROR("Out of memory\n"); return ENOMEM; } - user_ctx->ctx = ctx; - user_ctx->ev = ctx->ev; + data->ctx = ctx; + data->ev = ctx->ev; - /* parse user_ctx */ + /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); - if((ret = poptGetNextOpt(pc)) < -1) { + if ((ret = poptGetNextOpt(pc)) < -1) { usage(pc, poptStrerror(ret)); ret = EXIT_FAILURE; goto fini; @@ -208,29 +197,29 @@ int main(int argc, const char **argv) debug_level = pc_debug; - user_ctx->username = poptGetArg(pc); - if(user_ctx->username == NULL) { + data->name = poptGetArg(pc); + if (data->name == NULL) { usage(pc, _("Specify user to delete\n")); ret = EXIT_FAILURE; goto fini; } /* arguments processed, go on to actual work */ - pwd_info = getpwnam(user_ctx->username); + pwd_info = getpwnam(data->name); if (pwd_info) { - user_ctx->uid = pwd_info->pw_uid; + data->uid = pwd_info->pw_uid; } - ret = find_domain_for_id(ctx, user_ctx->uid, &dom); + ret = find_domain_for_id(ctx, data->uid, &dom); switch (ret) { case ID_IN_LOCAL: - user_ctx->domain = dom; + data->domain = dom; break; case ID_IN_LEGACY_LOCAL: - user_ctx->domain = dom; + data->domain = dom; case ID_OUTSIDE: - ret = userdel_legacy(user_ctx); + ret = userdel_legacy(data); if(ret != EOK) { ERROR("Cannot delete user from domain using the legacy tools\n"); ret = EXIT_FAILURE; @@ -251,17 +240,6 @@ int main(int argc, const char **argv) goto fini; } - user_ctx->user_dn = sysdb_user_dn(ctx->sysdb, ctx, - user_ctx->domain->name, - user_ctx->username); - if(user_ctx->user_dn == NULL) { - DEBUG(1, ("Could not construct a user DN\n")); - ERROR("Internal database error. Could not remove user.\n"); - ret = EXIT_FAILURE; - goto fini; - } - - /* userdel */ req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb); if (!req) { @@ -270,16 +248,16 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - tevent_req_set_callback(req, user_del, user_ctx); + tevent_req_set_callback(req, user_del, data); - while (!user_ctx->done) { + while (!data->done) { tevent_loop_once(ctx->ev); } - if (user_ctx->error) { - ret = user_ctx->error; + if (data->error) { + ret = data->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); - ERROR("Transaction error. Could not remove user.\n"); + ERROR("Internal error. Could not remove user.\n"); ret = EXIT_FAILURE; goto fini; } @@ -288,7 +266,7 @@ int main(int argc, const char **argv) fini: talloc_free(ctx); - talloc_free(user_ctx); + talloc_free(data); poptFreeContext(pc); exit(ret); } diff --git a/server/tools/sss_usermod.c b/server/tools/sss_usermod.c index 05df1336c..6ef873b60 100644 --- a/server/tools/sss_usermod.c +++ b/server/tools/sss_usermod.c @@ -82,34 +82,15 @@ #define USERMOD_USERNAME "%s" #endif -struct user_mod_ctx { - struct tevent_context *ev; - struct sysdb_handle *handle; - - struct sss_domain_info *domain; - struct tools_ctx *ctx; - - const char *username; - struct sysdb_attrs *attrs; - - char **addgroups; - char **rmgroups; - int cur; - - int error; - bool done; -}; - static void mod_user_req_done(struct tevent_req *req) { - struct user_mod_ctx *data = tevent_req_callback_data(req, - struct user_mod_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); data->error = sysdb_transaction_commit_recv(req); data->done = true; } -static void mod_user_done(struct user_mod_ctx *data, int error) +static void mod_user_done(struct ops_ctx *data, int error) { struct tevent_req *req; @@ -135,19 +116,19 @@ fail: } 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 mod_user_cont(struct ops_ctx *data); +static void remove_from_groups(struct ops_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(struct ops_ctx *data); static void add_to_groups_done(struct tevent_req *req); static void mod_user(struct tevent_req *req) { - struct user_mod_ctx *data; + struct ops_ctx *data; struct tevent_req *subreq; int ret; - data = tevent_req_callback_data(req, struct user_mod_ctx); + data = tevent_req_callback_data(req, struct ops_ctx); ret = sysdb_transaction_recv(req, data, &data->handle); if (ret != EOK) { @@ -156,7 +137,7 @@ static void mod_user(struct tevent_req *req) if (data->attrs->num != 0) { subreq = sysdb_set_user_attr_send(data, data->ev, data->handle, - data->domain, data->username, + data->domain, data->name, data->attrs, SYSDB_MOD_REP); if (!subreq) { return mod_user_done(data, ret); @@ -170,8 +151,7 @@ static void mod_user(struct tevent_req *req) static void mod_user_attr_done(struct tevent_req *subreq) { - struct user_mod_ctx *data = tevent_req_callback_data(subreq, - struct user_mod_ctx); + struct ops_ctx *data = tevent_req_callback_data(subreq, struct ops_ctx); int ret; ret = sysdb_set_user_attr_recv(subreq); @@ -183,7 +163,7 @@ static void mod_user_attr_done(struct tevent_req *subreq) mod_user_cont(data); } -static void mod_user_cont(struct user_mod_ctx *data) +static void mod_user_cont(struct ops_ctx *data) { if (data->rmgroups != NULL) { return remove_from_groups(data); @@ -196,14 +176,14 @@ static void mod_user_cont(struct user_mod_ctx *data) return mod_user_done(data, EOK); } -static void remove_from_groups(struct user_mod_ctx *data) +static void remove_from_groups(struct ops_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); + member_dn = sysdb_user_dn(data->ctx->sysdb, data, + data->domain->name, data->name); if (!member_dn) { return mod_user_done(data, ENOMEM); } @@ -229,8 +209,7 @@ static void remove_from_groups(struct user_mod_ctx *data) static void remove_from_groups_done(struct tevent_req *req) { - struct user_mod_ctx *data = tevent_req_callback_data(req, - struct user_mod_ctx); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); int ret; ret = sysdb_mod_group_member_recv(req); @@ -254,21 +233,21 @@ static void remove_from_groups_done(struct tevent_req *req) return remove_from_groups(data); } -static void add_to_groups(struct user_mod_ctx *data) +static void add_to_groups(struct ops_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); + member_dn = sysdb_user_dn(data->ctx->sysdb, data, + data->domain->name, data->name); if (!member_dn) { return mod_user_done(data, ENOMEM); } parent_dn = sysdb_group_dn(data->ctx->sysdb, data, - data->domain->name, - data->addgroups[data->cur]); + data->domain->name, + data->addgroups[data->cur]); if (!parent_dn) { return mod_user_done(data, ENOMEM); } @@ -287,8 +266,7 @@ static void add_to_groups(struct user_mod_ctx *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); + struct ops_ctx *data = tevent_req_callback_data(req, struct ops_ctx); int ret; ret = sysdb_mod_group_member_recv(req); @@ -308,7 +286,7 @@ static void add_to_groups_done(struct tevent_req *req) return add_to_groups(data); } -static int usermod_legacy(struct tools_ctx *tools_ctx, struct user_mod_ctx *ctx, +static int usermod_legacy(struct tools_ctx *tools_ctx, struct ops_ctx *ctx, uid_t uid, gid_t gid, const char *gecos, const char *home, const char *shell, int lock, int old_domain) @@ -353,14 +331,15 @@ static int usermod_legacy(struct tools_ctx *tools_ctx, struct user_mod_ctx *ctx, APPEND_STRING(command, USERMOD_UNLOCK); } - APPEND_PARAM(command, USERMOD_USERNAME, ctx->username); + APPEND_PARAM(command, USERMOD_USERNAME, ctx->name); ret = system(command); if (ret) { if (ret == -1) { DEBUG(1, ("system(3) failed\n")); } else { - DEBUG(1, ("Could not exec '%s', return code: %d\n", command, WEXITSTATUS(ret))); + DEBUG(1, ("Could not exec '%s', return code: %d\n", + command, WEXITSTATUS(ret))); } talloc_free(command); return EFAULT; @@ -395,7 +374,7 @@ int main(int argc, const char **argv) }; poptContext pc = NULL; struct sss_domain_info *dom; - struct user_mod_ctx *user_ctx = NULL; + struct ops_ctx *data = NULL; struct tools_ctx *ctx = NULL; struct tevent_req *req; char *groups; @@ -422,22 +401,23 @@ int main(int argc, const char **argv) goto fini; } - user_ctx = talloc_zero(ctx, struct user_mod_ctx); - if (user_ctx == NULL) { - DEBUG(1, ("Could not allocate memory for user_ctx context\n")); + data = talloc_zero(ctx, struct ops_ctx); + if (data == NULL) { + DEBUG(1, ("Could not allocate memory for data context\n")); ERROR("Out of memory\n"); return ENOMEM; } - user_ctx->ctx = ctx; + data->ctx = ctx; + data->ev = ctx->ev; - user_ctx->attrs = sysdb_new_attrs(ctx); - if (user_ctx->attrs == NULL) { + data->attrs = sysdb_new_attrs(ctx); + if (data->attrs == NULL) { DEBUG(1, ("Could not allocate memory for sysdb_attrs context\n")); ERROR("Out of memory\n"); return ENOMEM; } - /* parse user_ctx */ + /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { @@ -450,7 +430,7 @@ int main(int argc, const char **argv) ret = parse_groups(ctx, groups, - (ret == 'a') ? (&user_ctx->addgroups) : (&user_ctx->rmgroups)); + (ret == 'a') ? (&data->addgroups) : (&data->rmgroups)); free(groups); if (ret != EOK) { @@ -472,14 +452,14 @@ int main(int argc, const char **argv) } /* username is an argument without --option */ - user_ctx->username = poptGetArg(pc); - if (user_ctx->username == NULL) { + data->name = poptGetArg(pc); + if (data->name == NULL) { usage(pc, _("Specify user to modify\n")); ret = EXIT_FAILURE; goto fini; } - pwd_info = getpwnam(user_ctx->username); + pwd_info = getpwnam(data->name); if (pwd_info) { old_uid = pwd_info->pw_uid; } @@ -487,13 +467,13 @@ int main(int argc, const char **argv) ret = find_domain_for_id(ctx, old_uid, &dom); switch (ret) { case ID_IN_LOCAL: - user_ctx->domain = dom; + data->domain = dom; break; case ID_IN_LEGACY_LOCAL: - user_ctx->domain = dom; + data->domain = dom; case ID_OUTSIDE: - ret = usermod_legacy(ctx, user_ctx, pc_uid, pc_gid, pc_gecos, + ret = usermod_legacy(ctx, data, pc_uid, pc_gid, pc_gecos, pc_home, pc_shell, pc_lock, ret); if(ret != EOK) { ERROR("Cannot delete user from domain using the legacy tools\n"); @@ -517,7 +497,7 @@ int main(int argc, const char **argv) /* FIXME - might want to do this via attr:pc_var mapping in a loop */ if(pc_shell) { - ret = sysdb_attrs_add_string(user_ctx->attrs, + ret = sysdb_attrs_add_string(data->attrs, SYSDB_SHELL, pc_shell); VAR_CHECK(ret, EOK, SYSDB_SHELL, @@ -525,7 +505,7 @@ int main(int argc, const char **argv) } if(pc_home) { - ret = sysdb_attrs_add_string(user_ctx->attrs, + ret = sysdb_attrs_add_string(data->attrs, SYSDB_HOMEDIR, pc_home); VAR_CHECK(ret, EOK, SYSDB_HOMEDIR, @@ -533,7 +513,7 @@ int main(int argc, const char **argv) } if(pc_gecos) { - ret = sysdb_attrs_add_string(user_ctx->attrs, + ret = sysdb_attrs_add_string(data->attrs, SYSDB_GECOS, pc_gecos); VAR_CHECK(ret, EOK, SYSDB_GECOS, @@ -541,7 +521,7 @@ int main(int argc, const char **argv) } if(pc_uid) { - ret = sysdb_attrs_add_long(user_ctx->attrs, + ret = sysdb_attrs_add_long(data->attrs, SYSDB_UIDNUM, pc_uid); VAR_CHECK(ret, EOK, SYSDB_UIDNUM, @@ -549,7 +529,7 @@ int main(int argc, const char **argv) } if(pc_gid) { - ret = sysdb_attrs_add_long(user_ctx->attrs, + ret = sysdb_attrs_add_long(data->attrs, SYSDB_GIDNUM, pc_gid); VAR_CHECK(ret, EOK, SYSDB_GIDNUM, @@ -557,7 +537,7 @@ int main(int argc, const char **argv) } if(pc_lock == DO_LOCK) { - ret = sysdb_attrs_add_string(user_ctx->attrs, + ret = sysdb_attrs_add_string(data->attrs, SYSDB_DISABLED, "true"); VAR_CHECK(ret, EOK, SYSDB_DISABLED, @@ -566,7 +546,7 @@ int main(int argc, const char **argv) if(pc_lock == DO_UNLOCK) { /* PAM code checks for 'false' value in SYSDB_DISABLED attribute */ - ret = sysdb_attrs_add_string(user_ctx->attrs, + ret = sysdb_attrs_add_string(data->attrs, SYSDB_DISABLED, "false"); VAR_CHECK(ret, EOK, SYSDB_DISABLED, @@ -583,7 +563,7 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - user_ctx->domain = dom; + data->domain = dom; req = sysdb_transaction_send(ctx, ctx->ev, ctx->sysdb); if (!req) { @@ -592,14 +572,14 @@ int main(int argc, const char **argv) ret = EXIT_FAILURE; goto fini; } - tevent_req_set_callback(req, mod_user, user_ctx); + tevent_req_set_callback(req, mod_user, data); - while (!user_ctx->done) { + while (!data->done) { tevent_loop_once(ctx->ev); } - if (user_ctx->error) { - ret = user_ctx->error; + if (data->error) { + ret = data->error; DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret))); ERROR("Transaction error. Could not modify user.\n"); ret = EXIT_FAILURE; diff --git a/server/tools/tools_util.h b/server/tools/tools_util.h index 0520731ad..5bf3b3840 100644 --- a/server/tools/tools_util.h +++ b/server/tools/tools_util.h @@ -48,6 +48,29 @@ struct tools_ctx { struct sss_domain_info *domains; }; +struct ops_ctx { + struct tools_ctx *ctx; + struct tevent_context *ev; + struct sss_domain_info *domain; + + const char *name; + uid_t uid; + gid_t gid; + char *gecos; + char *home; + char *shell; + struct sysdb_attrs *attrs; + + char **addgroups; + char **rmgroups; + char **groups; + int cur; + + struct sysdb_handle *handle; + int error; + bool done; +}; + int init_sss_tools(struct tools_ctx **ctx); int setup_db(struct tools_ctx **ctx); -- cgit