diff options
author | Stephen Gallagher <sgallagh@redhat.com> | 2010-02-18 07:49:04 -0500 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-02-18 13:48:45 -0500 |
commit | 1c48b5a62f73234ed26bb20f0ab345ab61cda0ab (patch) | |
tree | 0b6cddd567a862e1a7b5df23764869782a62ca78 /server/tools/sss_sync_ops.c | |
parent | 8c56df3176f528fe0260974b3bf934173c4651ea (diff) | |
download | sssd_unused-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.tar.gz sssd_unused-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.tar.xz sssd_unused-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.zip |
Rename server/ directory to src/
Also update BUILD.txt
Diffstat (limited to 'server/tools/sss_sync_ops.c')
-rw-r--r-- | server/tools/sss_sync_ops.c | 1838 |
1 files changed, 0 insertions, 1838 deletions
diff --git a/server/tools/sss_sync_ops.c b/server/tools/sss_sync_ops.c deleted file mode 100644 index 25b8ac7a..00000000 --- a/server/tools/sss_sync_ops.c +++ /dev/null @@ -1,1838 +0,0 @@ -/* - Authors: - Jakub Hrozek <jhrozek@redhat.com> - - Copyright (C) 2009 Red Hat - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <tevent.h> -#include <talloc.h> -#include <sys/types.h> - -#include "util/util.h" -#include "db/sysdb.h" -#include "tools/sss_sync_ops.h" - -/* Default settings for user attributes */ -#define DFL_SHELL_VAL "/bin/bash" -#define DFL_BASEDIR_VAL "/home" -#define DFL_CREATE_HOMEDIR "TRUE" -#define DFL_REMOVE_HOMEDIR "TRUE" -#define DFL_UMASK 077 -#define DFL_SKEL_DIR "/etc/skel" -#define DFL_MAIL_DIR "/var/spool/mail" - - -#define VAR_CHECK(var, val, attr, msg) do { \ - if (var != (val)) { \ - DEBUG(1, (msg" attribute: %s", attr)); \ - return val; \ - } \ -} while(0) - -#define SYNC_LOOP(ops, retval) do { \ - while (!ops->done) { \ - tevent_loop_once(ev); \ - } \ - retval = ops->error; \ -} while(0) - -struct sync_op_res { - struct ops_ctx *data; - int error; - bool done; -}; - -/* - * Generic recv function - */ -static int sync_ops_recv(struct tevent_req *req) -{ - TEVENT_REQ_RETURN_ON_ERROR(req); - - return EOK; -} - -/* - * Generic add member to group - */ -struct add_to_groups_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - - int cur; - struct ops_ctx *data; - struct ldb_dn *member_dn; -}; - -static void add_to_groups_done(struct tevent_req *subreq); - -static struct tevent_req *add_to_groups_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data, - struct ldb_dn *member_dn) -{ - struct add_to_groups_state *state; - struct tevent_req *req; - struct tevent_req *subreq; - struct ldb_dn *parent_dn; - - req = tevent_req_create(mem_ctx, &state, struct add_to_groups_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - state->member_dn = member_dn; - state->cur = 0; - - parent_dn = sysdb_group_dn(state->sysdb, state, - state->data->domain->name, - state->data->addgroups[state->cur]); - if (!parent_dn) { - return NULL; - } - - subreq = sysdb_mod_group_member_send(state, - state->ev, - state->handle, - member_dn, - parent_dn, - LDB_FLAG_MOD_ADD); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, add_to_groups_done, req); - return req; -} - -static void add_to_groups_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct add_to_groups_state *state = tevent_req_data(req, - struct add_to_groups_state); - int ret; - struct ldb_dn *parent_dn; - struct tevent_req *next_group_req; - - ret = sysdb_mod_group_member_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - /* go on to next group */ - state->cur++; - - /* check if we added all of them */ - if (state->data->addgroups[state->cur] == NULL) { - tevent_req_done(req); - return; - } - - /* if not, schedule a new addition */ - parent_dn = sysdb_group_dn(state->sysdb, state, - state->data->domain->name, - state->data->addgroups[state->cur]); - if (!parent_dn) { - tevent_req_error(req, ENOMEM); - return; - } - - next_group_req = sysdb_mod_group_member_send(state, - state->ev, - state->handle, - state->member_dn, - parent_dn, - LDB_FLAG_MOD_ADD); - if (!next_group_req) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(next_group_req, add_to_groups_done, req); -} - -static int add_to_groups_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Generic remove member from group - */ -struct remove_from_groups_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - - int cur; - struct ops_ctx *data; - struct ldb_dn *member_dn; -}; - -static void remove_from_groups_done(struct tevent_req *subreq); - -static struct tevent_req *remove_from_groups_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data, - struct ldb_dn *member_dn) -{ - struct tevent_req *req; - struct tevent_req *subreq; - struct ldb_dn *parent_dn; - struct remove_from_groups_state *state; - - req = tevent_req_create(mem_ctx, &state, struct remove_from_groups_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - state->member_dn = member_dn; - state->cur = 0; - - parent_dn = sysdb_group_dn(state->sysdb, state, - state->data->domain->name, - state->data->rmgroups[state->cur]); - if (!parent_dn) { - return NULL; - } - - subreq = sysdb_mod_group_member_send(state, - state->ev, - state->handle, - state->member_dn, - parent_dn, - LDB_FLAG_MOD_DELETE); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, remove_from_groups_done, req); - return req; -} - -static void remove_from_groups_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct remove_from_groups_state *state = tevent_req_data(req, - struct remove_from_groups_state); - int ret; - struct ldb_dn *parent_dn; - struct tevent_req *next_group_req; - - ret = sysdb_mod_group_member_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - /* go on to next group */ - state->cur++; - - /* check if we removed all of them */ - if (state->data->rmgroups[state->cur] == NULL) { - tevent_req_done(req); - return; - } - - /* if not, schedule a new removal */ - parent_dn = sysdb_group_dn(state->sysdb, state, - state->data->domain->name, - state->data->rmgroups[state->cur]); - if (!parent_dn) { - tevent_req_error(req, ENOMEM); - return; - } - - next_group_req = sysdb_mod_group_member_send(state, - state->ev, - state->handle, - state->member_dn, - parent_dn, - LDB_FLAG_MOD_DELETE); - if (!next_group_req) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(next_group_req, remove_from_groups_done, req); -} - -static int remove_from_groups_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Add a user - */ -struct user_add_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - - struct ops_ctx *data; -}; - -static void user_add_to_group_done(struct tevent_req *groupreq); -static void user_add_done(struct tevent_req *subreq); - -static struct tevent_req *user_add_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - struct user_add_state *state = NULL; - struct tevent_req *req; - struct tevent_req *subreq; - - req = tevent_req_create(mem_ctx, &state, struct user_add_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - - subreq = sysdb_add_user_send(state, state->ev, state->handle, - state->data->domain, state->data->name, - state->data->uid, state->data->gid, - state->data->gecos, state->data->home, - state->data->shell, NULL, 0); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, user_add_done, req); - return req; -} - -static void user_add_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct user_add_state *state = tevent_req_data(req, - struct user_add_state); - int ret; - struct ldb_dn *member_dn; - struct tevent_req *groupreq; - - ret = sysdb_add_user_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - if (state->data->addgroups) { - member_dn = sysdb_user_dn(state->sysdb, state, - state->data->domain->name, - state->data->name); - if (!member_dn) { - tevent_req_error(req, ENOMEM); - return; - } - - groupreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, member_dn); - tevent_req_set_callback(groupreq, user_add_to_group_done, req); - return; - } - - return tevent_req_done(req); -} - -static void user_add_to_group_done(struct tevent_req *groupreq) -{ - struct tevent_req *req = tevent_req_callback_data(groupreq, - struct tevent_req); - int ret; - - ret = add_to_groups_recv(groupreq); - talloc_zfree(groupreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); - return; -} - -static int user_add_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Remove a user - */ -struct user_del_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - - struct ops_ctx *data; -}; - -static void user_del_done(struct tevent_req *subreq); - -static struct tevent_req *user_del_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - struct user_del_state *state = NULL; - struct tevent_req *req; - struct tevent_req *subreq; - struct ldb_dn *user_dn; - - req = tevent_req_create(mem_ctx, &state, struct user_del_state); - if (req == NULL) { - talloc_zfree(req); - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - - user_dn = sysdb_user_dn(state->sysdb, state, - state->data->domain->name, state->data->name); - if (!user_dn) { - DEBUG(1, ("Could not construct a user DN\n")); - return NULL; - } - - subreq = sysdb_delete_entry_send(state, - state->ev, state->handle, - user_dn, false); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, user_del_done, req); - return req; -} - -static void user_del_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_delete_entry_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - return tevent_req_done(req); -} - -static int user_del_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Modify a user - */ -struct user_mod_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - - struct sysdb_attrs *attrs; - struct ldb_dn *member_dn; - - struct ops_ctx *data; -}; - -static int usermod_build_attrs(TALLOC_CTX *mem_ctx, - const char *gecos, - const char *home, - const char *shell, - uid_t uid, - gid_t gid, - int lock, - struct sysdb_attrs **_attrs) -{ - int ret; - struct sysdb_attrs *attrs; - - attrs = sysdb_new_attrs(mem_ctx); - if (attrs == NULL) { - return ENOMEM; - } - - if (shell) { - ret = sysdb_attrs_add_string(attrs, - SYSDB_SHELL, - shell); - VAR_CHECK(ret, EOK, SYSDB_SHELL, - "Could not add attribute to changeset\n"); - } - - if (home) { - ret = sysdb_attrs_add_string(attrs, - SYSDB_HOMEDIR, - home); - VAR_CHECK(ret, EOK, SYSDB_HOMEDIR, - "Could not add attribute to changeset\n"); - } - - if (gecos) { - ret = sysdb_attrs_add_string(attrs, - SYSDB_GECOS, - gecos); - VAR_CHECK(ret, EOK, SYSDB_GECOS, - "Could not add attribute to changeset\n"); - } - - if (uid) { - ret = sysdb_attrs_add_long(attrs, - SYSDB_UIDNUM, - uid); - VAR_CHECK(ret, EOK, SYSDB_UIDNUM, - "Could not add attribute to changeset\n"); - } - - if (gid) { - ret = sysdb_attrs_add_long(attrs, - SYSDB_GIDNUM, - gid); - VAR_CHECK(ret, EOK, SYSDB_GIDNUM, - "Could not add attribute to changeset\n"); - } - - if (lock == DO_LOCK) { - ret = sysdb_attrs_add_string(attrs, - SYSDB_DISABLED, - "true"); - VAR_CHECK(ret, EOK, SYSDB_DISABLED, - "Could not add attribute to changeset\n"); - } - - if (lock == DO_UNLOCK) { - /* PAM code checks for 'false' value in SYSDB_DISABLED attribute */ - ret = sysdb_attrs_add_string(attrs, - SYSDB_DISABLED, - "false"); - VAR_CHECK(ret, EOK, SYSDB_DISABLED, - "Could not add attribute to changeset\n"); - } - - *_attrs = attrs; - return EOK; -} - -static void user_mod_attr_done(struct tevent_req *attrreq); -static void user_mod_attr_wakeup(struct tevent_req *subreq); -static void user_mod_rm_group_done(struct tevent_req *groupreq); -static void user_mod_add_group_done(struct tevent_req *groupreq); - -static struct tevent_req *user_mod_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - struct user_mod_state *state = NULL; - struct tevent_req *req; - struct tevent_req *subreq; - int ret; - struct timeval tv = { 0, 0 }; - - req = tevent_req_create(mem_ctx, &state, struct user_mod_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - - if (data->addgroups || data->rmgroups) { - state->member_dn = sysdb_user_dn(state->sysdb, state, - state->data->domain->name, - state->data->name); - if (!state->member_dn) { - talloc_zfree(req); - return NULL; - } - } - - ret = usermod_build_attrs(state, - state->data->gecos, - state->data->home, - state->data->shell, - state->data->uid, - state->data->gid, - state->data->lock, - &state->attrs); - if (ret != EOK) { - talloc_zfree(req); - return NULL; - } - - subreq = tevent_wakeup_send(req, ev, tv); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, user_mod_attr_wakeup, req); - return req; -} - -static void user_mod_attr_wakeup(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct user_mod_state *state = tevent_req_data(req, - struct user_mod_state); - struct tevent_req *attrreq, *groupreq; - - if (state->attrs->num != 0) { - attrreq = sysdb_set_user_attr_send(state, state->ev, state->handle, - state->data->domain, state->data->name, - state->attrs, SYSDB_MOD_REP); - if (!attrreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(attrreq, user_mod_attr_done, req); - return; - } - - if (state->data->rmgroups != NULL) { - groupreq = remove_from_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, user_mod_rm_group_done, req); - return; - } - - if (state->data->addgroups != NULL) { - groupreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, user_mod_add_group_done, req); - return; - } - - /* No changes to be made, mark request as done */ - tevent_req_done(req); -} - -static void user_mod_attr_done(struct tevent_req *attrreq) -{ - struct tevent_req *req = tevent_req_callback_data(attrreq, - struct tevent_req); - struct user_mod_state *state = tevent_req_data(req, - struct user_mod_state); - int ret; - struct tevent_req *groupreq; - - ret = sysdb_set_user_attr_recv(attrreq); - talloc_zfree(attrreq); - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - - if (state->data->rmgroups != NULL) { - groupreq = remove_from_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, user_mod_rm_group_done, req); - return; - } - - if (state->data->addgroups != NULL) { - groupreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, user_mod_add_group_done, req); - return; - } - - return tevent_req_done(req); -} - -static void user_mod_rm_group_done(struct tevent_req *groupreq) -{ - struct tevent_req *req = tevent_req_callback_data(groupreq, - struct tevent_req); - struct user_mod_state *state = tevent_req_data(req, - struct user_mod_state); - int ret; - struct tevent_req *addreq; - - ret = remove_from_groups_recv(groupreq); - talloc_zfree(groupreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - if (state->data->addgroups != NULL) { - addreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!addreq) { - tevent_req_error(req, ENOMEM); - } - tevent_req_set_callback(addreq, user_mod_add_group_done, req); - return; - } - - tevent_req_done(req); - return; -} - -static void user_mod_add_group_done(struct tevent_req *groupreq) -{ - struct tevent_req *req = tevent_req_callback_data(groupreq, - struct tevent_req); - int ret; - - ret = add_to_groups_recv(groupreq); - talloc_zfree(groupreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); - return; -} - -static int user_mod_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Add a group - */ -struct group_add_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - struct sysdb_attrs *attrs; - - struct ops_ctx *data; -}; - -static void group_add_done(struct tevent_req *subreq); - -static struct tevent_req *group_add_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - struct group_add_state *state = NULL; - struct tevent_req *req; - struct tevent_req *subreq; - - req = tevent_req_create(mem_ctx, &state, struct group_add_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - - subreq = sysdb_add_group_send(state, state->ev, state->handle, - state->data->domain, state->data->name, - state->data->gid, NULL, 0); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, group_add_done, req); - return req; -} - -static void group_add_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_add_group_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - return tevent_req_done(req); -} - -static int group_add_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Delete a group - */ -struct group_del_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - struct sysdb_attrs *attrs; - - struct ops_ctx *data; -}; - -static void group_del_done(struct tevent_req *subreq); - -static struct tevent_req *group_del_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - struct group_del_state *state = NULL; - struct tevent_req *req; - struct tevent_req *subreq; - struct ldb_dn *group_dn; - - req = tevent_req_create(mem_ctx, &state, struct group_del_state); - if (req == NULL) { - talloc_zfree(req); - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - - group_dn = sysdb_group_dn(state->sysdb, state, - state->data->domain->name, state->data->name); - if (group_dn == NULL) { - DEBUG(1, ("Could not construct a group DN\n")); - return NULL; - } - - subreq = sysdb_delete_entry_send(state, - state->ev, state->handle, - group_dn, false); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, group_del_done, req); - return req; -} - -static void group_del_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - int ret; - - ret = sysdb_delete_entry_recv(subreq); - talloc_zfree(subreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - return tevent_req_done(req); -} - -static int group_del_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -/* - * Modify a group - */ -struct group_mod_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - - struct sysdb_attrs *attrs; - struct ldb_dn *member_dn; - - struct ops_ctx *data; -}; - -static void group_mod_attr_done(struct tevent_req *); -static void group_mod_attr_wakeup(struct tevent_req *); -static void group_mod_add_group_done(struct tevent_req *groupreq); -static void group_mod_rm_group_done(struct tevent_req *groupreq); - -static struct tevent_req *group_mod_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - struct group_mod_state *state; - struct tevent_req *req; - struct tevent_req *subreq; - struct timeval tv = { 0, 0 }; - - req = tevent_req_create(mem_ctx, &state, struct group_mod_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->sysdb = sysdb; - state->handle = handle; - state->data = data; - - if (data->addgroups || data->rmgroups) { - state->member_dn = sysdb_group_dn(state->sysdb, state, - state->data->domain->name, - state->data->name); - if (!state->member_dn) { - return NULL; - } - } - - subreq = tevent_wakeup_send(req, ev, tv); - if (!subreq) { - talloc_zfree(req); - return NULL; - } - - tevent_req_set_callback(subreq, group_mod_attr_wakeup, req); - return req; -} - -static void group_mod_attr_wakeup(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct group_mod_state *state = tevent_req_data(req, - struct group_mod_state); - struct sysdb_attrs *attrs; - struct tevent_req *attrreq; - struct tevent_req *groupreq; - int ret; - - if (state->data->gid != 0) { - attrs = sysdb_new_attrs(NULL); - if (!attrs) { - tevent_req_error(req, ENOMEM); - return; - } - ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, state->data->gid); - if (ret) { - tevent_req_error(req, ret); - return; - } - - attrreq = sysdb_set_group_attr_send(state, state->ev, state->handle, - state->data->domain, state->data->name, - attrs, SYSDB_MOD_REP); - if (!attrreq) { - tevent_req_error(req, ENOMEM); - return; - } - - tevent_req_set_callback(attrreq, group_mod_attr_done, req); - return; - } - - if (state->data->rmgroups != NULL) { - groupreq = remove_from_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, group_mod_rm_group_done, req); - return; - } - - if (state->data->addgroups != NULL) { - groupreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, group_mod_add_group_done, req); - return; - } - - /* No changes to be made, mark request as done */ - tevent_req_done(req); -} - -static void group_mod_attr_done(struct tevent_req *attrreq) -{ - struct tevent_req *req = tevent_req_callback_data(attrreq, - struct tevent_req); - struct group_mod_state *state = tevent_req_data(req, - struct group_mod_state); - int ret; - struct tevent_req *groupreq; - - ret = sysdb_set_group_attr_recv(attrreq); - talloc_zfree(attrreq); - if (ret != EOK) { - tevent_req_error(req, ret); - return; - } - - if (state->data->rmgroups != NULL) { - groupreq = remove_from_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, group_mod_rm_group_done, req); - return; - } - - if (state->data->addgroups != NULL) { - groupreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!groupreq) { - tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(groupreq, group_mod_add_group_done, req); - return; - } - - return tevent_req_done(req); -} - -static void group_mod_rm_group_done(struct tevent_req *groupreq) -{ - struct tevent_req *req = tevent_req_callback_data(groupreq, - struct tevent_req); - struct group_mod_state *state = tevent_req_data(req, - struct group_mod_state); - int ret; - struct tevent_req *addreq; - - ret = remove_from_groups_recv(groupreq); - talloc_zfree(groupreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - if (state->data->addgroups != NULL) { - addreq = add_to_groups_send(state, state->ev, state->sysdb, - state->handle, state->data, state->member_dn); - if (!addreq) { - tevent_req_error(req, ENOMEM); - } - tevent_req_set_callback(addreq, group_mod_add_group_done, req); - return; - } - - tevent_req_done(req); - return; -} - -static void group_mod_add_group_done(struct tevent_req *groupreq) -{ - struct tevent_req *req = tevent_req_callback_data(groupreq, - struct tevent_req); - int ret; - - ret = add_to_groups_recv(groupreq); - talloc_zfree(groupreq); - if (ret) { - tevent_req_error(req, ret); - return; - } - - tevent_req_done(req); - return; -} - -static int group_mod_recv(struct tevent_req *req) -{ - return sync_ops_recv(req); -} - -int userdel_defaults(TALLOC_CTX *mem_ctx, - struct confdb_ctx *confdb, - struct ops_ctx *data, - int remove_home) -{ - int ret; - char *conf_path; - bool dfl_remove_home; - - conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name); - if (!conf_path) { - return ENOMEM; - } - - /* remove homedir on user creation? */ - if (!remove_home) { - ret = confdb_get_bool(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_REMOVE_HOMEDIR, - DFL_REMOVE_HOMEDIR, &dfl_remove_home); - if (ret != EOK) { - goto done; - } - data->remove_homedir = dfl_remove_home; - } else { - data->remove_homedir = (remove_home == DO_REMOVE_HOME); - } - - /* a directory to remove mail spools from */ - ret = confdb_get_string(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_MAIL_DIR, - DFL_MAIL_DIR, &data->maildir); - if (ret != EOK) { - goto done; - } - - ret = EOK; -done: - talloc_free(conf_path); - return ret; -} - -/* - * Default values for add operations - */ -int useradd_defaults(TALLOC_CTX *mem_ctx, - struct confdb_ctx *confdb, - struct ops_ctx *data, - const char *gecos, - const char *homedir, - const char *shell, - int create_home, - const char *skeldir) -{ - int ret; - char *basedir = NULL; - char *conf_path = NULL; - - conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name); - if (!conf_path) { - return ENOMEM; - } - - /* gecos */ - data->gecos = talloc_strdup(mem_ctx, gecos ? gecos : data->name); - if (!data->gecos) { - ret = ENOMEM; - goto done; - } - DEBUG(7, ("Gecos: %s\n", data->gecos)); - - /* homedir */ - if (homedir) { - data->home = talloc_strdup(data, homedir); - } else { - ret = confdb_get_string(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_DEFAULT_BASEDIR, - DFL_BASEDIR_VAL, &basedir); - if (ret != EOK) { - goto done; - } - data->home = talloc_asprintf(mem_ctx, "%s/%s", basedir, data->name); - } - if (!data->home) { - ret = ENOMEM; - goto done; - } - DEBUG(7, ("Homedir: %s\n", data->home)); - - /* default shell */ - if (!shell) { - ret = confdb_get_string(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_DEFAULT_SHELL, - DFL_SHELL_VAL, &data->shell); - if (ret != EOK) { - goto done; - } - } else { - data->shell = talloc_strdup(mem_ctx, shell); - if (!data->shell) { - ret = ENOMEM; - goto done; - } - } - DEBUG(7, ("Shell: %s\n", data->shell)); - - /* create homedir on user creation? */ - if (!create_home) { - ret = confdb_get_bool(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_CREATE_HOMEDIR, - DFL_CREATE_HOMEDIR, &data->create_homedir); - if (ret != EOK) { - goto done; - } - } else { - data->create_homedir = (create_home == DO_CREATE_HOME); - } - DEBUG(7, ("Auto create homedir: %s\n", data->create_homedir?"True":"False")); - - /* umask to create homedirs */ - ret = confdb_get_int(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_UMASK, - DFL_UMASK, (int *) &data->umask); - if (ret != EOK) { - goto done; - } - DEBUG(7, ("Umask: %o\n", data->umask)); - - /* a directory to create mail spools in */ - ret = confdb_get_string(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_MAIL_DIR, - DFL_MAIL_DIR, &data->maildir); - if (ret != EOK) { - goto done; - } - DEBUG(7, ("Mail dir: %s\n", data->maildir)); - - /* skeleton dir */ - if (!skeldir) { - ret = confdb_get_string(confdb, mem_ctx, - conf_path, CONFDB_LOCAL_SKEL_DIR, - DFL_SKEL_DIR, &data->skeldir); - if (ret != EOK) { - goto done; - } - } else { - data->skeldir = talloc_strdup(mem_ctx, skeldir); - if (!data->skeldir) { - ret = ENOMEM; - goto done; - } - } - DEBUG(7, ("Skeleton dir: %s\n", data->skeldir)); - - ret = EOK; -done: - talloc_free(basedir); - talloc_free(conf_path); - return ret; -} - -/* - * Public interface for adding users - */ -static void useradd_done(struct tevent_req *); - -int useradd(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - int ret; - struct tevent_req *req; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - req = user_add_send(res, ev, sysdb, handle, data); - if (!req) { - return ENOMEM; - } - tevent_req_set_callback(req, useradd_done, res); - - SYNC_LOOP(res, ret); - - talloc_free(res); - return ret; -} - -static void useradd_done(struct tevent_req *req) -{ - int ret; - struct sync_op_res *res = tevent_req_callback_data(req, - struct sync_op_res); - - ret = user_add_recv(req); - talloc_free(req); - if (ret) { - DEBUG(2, ("Adding user failed: %s (%d)\n", strerror(ret), ret)); - } - - res->done = true; - res->error = ret; -} - -/* - * Public interface for deleting users - */ -static void userdel_done(struct tevent_req *req); - -int userdel(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - int ret; - struct tevent_req *req; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - req = user_del_send(res, ev, sysdb, handle, data); - if (!req) { - return ENOMEM; - } - tevent_req_set_callback(req, userdel_done, res); - - SYNC_LOOP(res, ret); - - talloc_free(res); - return ret; -} - -static void userdel_done(struct tevent_req *req) -{ - int ret; - struct sync_op_res *res = tevent_req_callback_data(req, - struct sync_op_res); - - ret = user_del_recv(req); - talloc_free(req); - if (ret) { - DEBUG(2, ("Removing user failed: %s (%d)\n", strerror(ret), ret)); - } - - res->done = true; - res->error = ret; -} - -/* - * Public interface for modifying users - */ -static void usermod_done(struct tevent_req *req); - -int usermod(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - int ret; - struct tevent_req *req; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - req = user_mod_send(res, ev, sysdb, handle, data); - if (!req) { - return ENOMEM; - } - tevent_req_set_callback(req, usermod_done, res); - - SYNC_LOOP(res, ret); - - talloc_free(res); - return ret; -} - -static void usermod_done(struct tevent_req *req) -{ - int ret; - struct sync_op_res *res = tevent_req_callback_data(req, - struct sync_op_res); - - ret = user_mod_recv(req); - talloc_free(req); - if (ret) { - DEBUG(2, ("Modifying user failed: %s (%d)\n", strerror(ret), ret)); - } - - res->done = true; - res->error = ret; -} - -/* - * Public interface for adding groups - */ -static void groupadd_done(struct tevent_req *); - -int groupadd(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - int ret; - struct tevent_req *req; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - req = group_add_send(res, ev, sysdb, handle, data); - if (!req) { - return ENOMEM; - } - tevent_req_set_callback(req, groupadd_done, res); - - SYNC_LOOP(res, ret); - - talloc_free(res); - return ret; -} - -static void groupadd_done(struct tevent_req *req) -{ - int ret; - struct sync_op_res *res = tevent_req_callback_data(req, - struct sync_op_res); - - ret = group_add_recv(req); - talloc_free(req); - if (ret) { - DEBUG(2, ("Adding group failed: %s (%d)\n", strerror(ret), ret)); - } - - res->done = true; - res->error = ret; -} - -/* - * Public interface for deleting groups - */ -static void groupdel_done(struct tevent_req *req); - -int groupdel(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - int ret; - struct tevent_req *req; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - req = group_del_send(res, ev, sysdb, handle, data); - if (!req) { - return ENOMEM; - } - tevent_req_set_callback(req, groupdel_done, res); - - SYNC_LOOP(res, ret); - - talloc_free(res); - return ret; -} - -static void groupdel_done(struct tevent_req *req) -{ - int ret; - struct sync_op_res *res = tevent_req_callback_data(req, - struct sync_op_res); - - ret = group_del_recv(req); - talloc_free(req); - if (ret) { - DEBUG(2, ("Removing group failed: %s (%d)\n", strerror(ret), ret)); - } - - res->done = true; - res->error = ret; -} - -/* - * Public interface for modifying groups - */ -static void groupmod_done(struct tevent_req *req); - -int groupmod(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct ops_ctx *data) -{ - int ret; - struct tevent_req *req; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - req = group_mod_send(res, ev, sysdb, handle, data); - if (!req) { - return ENOMEM; - } - tevent_req_set_callback(req, groupmod_done, res); - - SYNC_LOOP(res, ret); - - talloc_free(res); - return ret; -} - -static void groupmod_done(struct tevent_req *req) -{ - int ret; - struct sync_op_res *res = tevent_req_callback_data(req, - struct sync_op_res); - - ret = group_mod_recv(req); - talloc_free(req); - if (ret) { - DEBUG(2, ("Modifying group failed: %s (%d)\n", strerror(ret), ret)); - } - - res->done = true; - 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); -} - -/* - * getpwnam, getgrnam and friends - */ -static void sss_getpwnam_done(void *ptr, int status, - struct ldb_result *lrs); - -int sysdb_getpwnam_sync(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - const char *name, - struct sss_domain_info *domain, - struct ops_ctx **out) -{ - int ret; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - if (out == NULL) { - DEBUG(1, ("NULL passed for storage pointer\n")); - return EINVAL; - } - res->data = *out; - - ret = sysdb_getpwnam(mem_ctx, - sysdb, - domain, - name, - sss_getpwnam_done, - res); - - SYNC_LOOP(res, ret); - - return ret; -} - -static void sss_getpwnam_done(void *ptr, int status, - struct ldb_result *lrs) -{ - struct sync_op_res *res = talloc_get_type(ptr, struct sync_op_res ); - const char *str; - - res->done = true; - - if (status != LDB_SUCCESS) { - res->error = status; - return; - } - - switch (lrs->count) { - case 0: - DEBUG(1, ("No result for sysdb_getpwnam call\n")); - res->error = ENOENT; - break; - - case 1: - res->error = EOK; - /* fill ops_ctx */ - res->data->uid = ldb_msg_find_attr_as_uint64(lrs->msgs[0], - SYSDB_UIDNUM, 0); - - res->data->gid = ldb_msg_find_attr_as_uint64(lrs->msgs[0], - SYSDB_GIDNUM, 0); - - str = ldb_msg_find_attr_as_string(lrs->msgs[0], - SYSDB_NAME, NULL); - res->data->name = talloc_strdup(res, str); - if (res->data->name == NULL) { - res->error = ENOMEM; - return; - } - - str = ldb_msg_find_attr_as_string(lrs->msgs[0], - SYSDB_GECOS, NULL); - res->data->gecos = talloc_strdup(res, str); - if (res->data->gecos == NULL) { - res->error = ENOMEM; - return; - } - - str = ldb_msg_find_attr_as_string(lrs->msgs[0], - SYSDB_HOMEDIR, NULL); - res->data->home = talloc_strdup(res, str); - if (res->data->home == NULL) { - res->error = ENOMEM; - return; - } - - str = ldb_msg_find_attr_as_string(lrs->msgs[0], - SYSDB_SHELL, NULL); - res->data->shell = talloc_strdup(res, str); - if (res->data->shell == NULL) { - res->error = ENOMEM; - return; - } - - str = ldb_msg_find_attr_as_string(lrs->msgs[0], - SYSDB_DISABLED, NULL); - if (str == NULL) { - res->data->lock = DO_UNLOCK; - } else { - if (strcasecmp(str, "true") == 0) { - res->data->lock = DO_LOCK; - } else if (strcasecmp(str, "false") == 0) { - res->data->lock = DO_UNLOCK; - } else { /* Invalid value */ - DEBUG(2, ("Invalid value for %s attribute: %s\n", - SYSDB_DISABLED, str ? str : "NULL")); - res->error = EIO; - return; - } - } - break; - - default: - DEBUG(1, ("More than one result for sysdb_getpwnam call\n")); - res->error = EIO; - break; - } -} - -static void sss_getgrnam_done(void *ptr, int status, - struct ldb_result *lrs); - -int sysdb_getgrnam_sync(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - const char *name, - struct sss_domain_info *domain, - struct ops_ctx **out) -{ - int ret; - struct sync_op_res *res = NULL; - - res = talloc_zero(mem_ctx, struct sync_op_res); - if (!res) { - return ENOMEM; - } - - if (out == NULL) { - DEBUG(1, ("NULL passed for storage pointer\n")); - return EINVAL; - } - res->data = *out; - - ret = sysdb_getgrnam(mem_ctx, - sysdb, - domain, - name, - sss_getgrnam_done, - res); - - SYNC_LOOP(res, ret); - - return ret; -} - -static void sss_getgrnam_done(void *ptr, int status, - struct ldb_result *lrs) -{ - struct sync_op_res *res = talloc_get_type(ptr, struct sync_op_res ); - const char *str; - - res->done = true; - - if (status != LDB_SUCCESS) { - res->error = status; - return; - } - - switch (lrs->count) { - case 0: - DEBUG(1, ("No result for sysdb_getgrnam call\n")); - res->error = ENOENT; - break; - - /* sysdb_getgrnam also returns members */ - default: - res->error = EOK; - /* fill ops_ctx */ - res->data->gid = ldb_msg_find_attr_as_uint64(lrs->msgs[0], - SYSDB_GIDNUM, 0); - str = ldb_msg_find_attr_as_string(lrs->msgs[0], - SYSDB_NAME, NULL); - res->data->name = talloc_strdup(res, str); - if (res->data->name == NULL) { - res->error = ENOMEM; - return; - } - break; - } -} - |