summaryrefslogtreecommitdiffstats
path: root/server/tools/sss_sync_ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/tools/sss_sync_ops.c')
-rw-r--r--server/tools/sss_sync_ops.c1838
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 25b8ac7a5..000000000
--- 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;
- }
-}
-