summaryrefslogtreecommitdiffstats
path: root/server/tools
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2010-02-18 07:49:04 -0500
committerStephen Gallagher <sgallagh@redhat.com>2010-02-18 13:48:45 -0500
commit1c48b5a62f73234ed26bb20f0ab345ab61cda0ab (patch)
tree0b6cddd567a862e1a7b5df23764869782a62ca78 /server/tools
parent8c56df3176f528fe0260974b3bf934173c4651ea (diff)
downloadsssd-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.tar.gz
sssd-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.tar.xz
sssd-1c48b5a62f73234ed26bb20f0ab345ab61cda0ab.zip
Rename server/ directory to src/
Also update BUILD.txt
Diffstat (limited to 'server/tools')
-rw-r--r--server/tools/files.c736
-rw-r--r--server/tools/sss_groupadd.c155
-rw-r--r--server/tools/sss_groupdel.c155
-rw-r--r--server/tools/sss_groupmod.c246
-rw-r--r--server/tools/sss_groupshow.c944
-rw-r--r--server/tools/sss_sync_ops.c1838
-rw-r--r--server/tools/sss_sync_ops.h125
-rw-r--r--server/tools/sss_useradd.c349
-rw-r--r--server/tools/sss_userdel.c205
-rw-r--r--server/tools/sss_usermod.c265
-rw-r--r--server/tools/tools_util.c520
-rw-r--r--server/tools/tools_util.h108
12 files changed, 0 insertions, 5646 deletions
diff --git a/server/tools/files.c b/server/tools/files.c
deleted file mode 100644
index 6c6447059..000000000
--- a/server/tools/files.c
+++ /dev/null
@@ -1,736 +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/>.
-*/
-
-/*
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (c) 1991 - 1994, Julianne Frances Haugh
- * Copyright (c) 1996 - 2001, Marek Michałkiewicz
- * Copyright (c) 2003 - 2006, Tomasz Kłoczko
- * Copyright (c) 2007 - 2008, Nicolas François
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the copyright holders or contributors may not be used to
- * endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <talloc.h>
-
-#include "config.h"
-#include "util/util.h"
-#include "tools/tools_util.h"
-
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
-
-int copy_tree(const char *src_root, const char *dst_root,
- uid_t uid, gid_t gid);
-
-struct copy_ctx {
- const char *src_orig;
- const char *dst_orig;
- dev_t src_dev;
-};
-
-#ifdef HAVE_SELINUX
-/*
- * selinux_file_context - Set the security context before any file or
- * directory creation.
- *
- * selinux_file_context () should be called before any creation of file,
- * symlink, directory, ...
- *
- * Callers may have to Reset SELinux to create files with default
- * contexts:
- * reset_selinux_file_context();
- */
-int selinux_file_context(const char *dst_name)
-{
- security_context_t scontext = NULL;
-
- if (is_selinux_enabled() == 1) {
- /* Get the default security context for this file */
- if (matchpathcon(dst_name, 0, &scontext) < 0) {
- if (security_getenforce () != 0) {
- return 1;
- }
- }
- /* Set the security context for the next created file */
- if (setfscreatecon(scontext) < 0) {
- if (security_getenforce() != 0) {
- return 1;
- }
- }
- freecon(scontext);
- }
-
- return 0;
-}
-
-int reset_selinux_file_context(void)
-{
- setfscreatecon(NULL);
- return EOK;
-}
-
-#else /* HAVE_SELINUX */
-int selinux_file_context(const char *dst_name)
-{
- return EOK;
-}
-
-int reset_selinux_file_context(void)
-{
- return EOK;
-}
-#endif /* HAVE_SELINUX */
-
-/* wrapper in order not to create a temporary context in
- * every iteration */
-static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
- dev_t parent_dev,
- const char *root);
-
-int remove_tree(const char *root)
-{
- TALLOC_CTX *tmp_ctx = NULL;
- int ret;
-
- tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- ret = remove_tree_with_ctx(tmp_ctx, 0, root);
- talloc_free(tmp_ctx);
- return ret;
-}
-
-/*
- * The context is not freed in case of error
- * because this is a recursive function, will be freed when we
- * reach the top level remove_tree() again
- */
-static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
- dev_t parent_dev,
- const char *root)
-{
- char *fullpath = NULL;
- struct dirent *result;
- struct dirent direntp;
- struct stat statres;
- DIR *rootdir = NULL;
- int ret;
-
- rootdir = opendir(root);
- if (rootdir == NULL) {
- ret = errno;
- DEBUG(1, ("Cannot open directory %s [%d][%s]",
- root, ret, strerror(ret)));
- goto fail;
- }
-
- while (readdir_r(rootdir, &direntp, &result) == 0) {
- if (result == NULL) {
- /* End of directory */
- break;
- }
-
- if (strcmp (direntp.d_name, ".") == 0 ||
- strcmp (direntp.d_name, "..") == 0) {
- continue;
- }
-
- fullpath = talloc_asprintf(mem_ctx, "%s/%s", root, direntp.d_name);
- if (fullpath == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- ret = lstat(fullpath, &statres);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot stat %s: [%d][%s]\n",
- fullpath, ret, strerror(ret)));
- goto fail;
- }
-
- if (S_ISDIR(statres.st_mode)) {
- /* if directory, recursively descend, but check if on the same FS */
- if (parent_dev && parent_dev != statres.st_dev) {
- DEBUG(1, ("Directory %s is on different filesystem, "
- "will not follow\n", fullpath));
- ret = EFAULT;
- goto fail;
- }
-
- ret = remove_tree_with_ctx(mem_ctx, statres.st_dev, fullpath);
- if (ret != EOK) {
- DEBUG(1, ("Removing subdirectory %s failed: [%d][%s]\n",
- fullpath, ret, strerror(ret)));
- goto fail;
- }
- } else {
- ret = unlink(fullpath);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Removing file %s failed: [%d][%s]\n",
- fullpath, ret, strerror(ret)));
- goto fail;
- }
- }
-
- talloc_free(fullpath);
- }
-
- ret = closedir(rootdir);
- if (ret != 0) {
- ret = errno;
- goto fail;
- }
-
- ret = rmdir(root);
- if (ret != 0) {
- ret = errno;
- goto fail;
- }
-
-fail:
- return ret;
-}
-
-static int copy_dir(const char *src, const char *dst,
- const struct stat *statp, const struct timeval mt[2],
- uid_t uid, gid_t gid)
-{
- int ret = 0;
-
- /*
- * Create a new target directory, make it owned by
- * the user and then recursively copy that directory.
- */
- selinux_file_context(dst);
-
- ret = mkdir(dst, statp->st_mode);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot mkdir directory '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = chown(dst, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot chown directory '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = chmod(dst, statp->st_mode);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot chmod directory '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = copy_tree(src, dst, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot copy directory from '%s' to '%s': [%d][%s].\n",
- src, dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = utimes(dst, mt);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot set utimes on a directory '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- return EOK;
-}
-
-static char *talloc_readlink(TALLOC_CTX *mem_ctx, const char *filename)
-{
- size_t size = 1024;
- ssize_t nchars;
- char *buffer;
-
- buffer = talloc_array(mem_ctx, char, size);
- if (!buffer) {
- return NULL;
- }
-
- while (1) {
- nchars = readlink(filename, buffer, size);
- if (nchars < 0) {
- return NULL;
- }
-
- if ((size_t) nchars < size) {
- /* The buffer was large enough */
- break;
- }
-
- /* Try again with a bigger buffer */
- size *= 2;
- buffer = talloc_realloc(mem_ctx, buffer, char, size);
- if (!buffer) {
- return NULL;
- }
- }
-
- /* readlink does not nul-terminate */
- buffer[nchars] = '\0';
- return buffer;
-}
-
-static int copy_symlink(struct copy_ctx *cctx,
- const char *src,
- const char *dst,
- const struct stat *statp,
- const struct timeval mt[],
- uid_t uid, gid_t gid)
-{
- int ret;
- char *oldlink;
- char *tmp;
- TALLOC_CTX *tmp_ctx = NULL;
-
- tmp_ctx = talloc_new(cctx);
- if (!tmp_ctx) {
- return ENOMEM;
- }
-
- /*
- * Get the name of the file which the link points
- * to. If that name begins with the original
- * source directory name, that part of the link
- * name will be replaced with the original
- * destination directory name.
- */
- oldlink = talloc_readlink(tmp_ctx, src);
- if (oldlink == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- /* If src was a link to an entry of the src_orig directory itself,
- * create a link to the corresponding entry in the dst_orig
- * directory.
- * FIXME: This may change a relative link to an absolute link
- */
- if (strncmp(oldlink, cctx->src_orig, strlen(cctx->src_orig)) == 0) {
- tmp = talloc_asprintf(tmp_ctx, "%s%s", cctx->dst_orig, oldlink + strlen(cctx->src_orig));
- if (tmp == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- talloc_free(oldlink);
- oldlink = tmp;
- }
-
- selinux_file_context(dst);
-
- ret = symlink(oldlink, dst);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("symlink() failed on file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto done;
- }
-
- ret = lchown(dst, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("lchown() failed on file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto done;
- }
-
-done:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-static int copy_special(const char *dst,
- const struct stat *statp,
- const struct timeval mt[],
- uid_t uid, gid_t gid)
-{
- int ret = 0;
-
- selinux_file_context(dst);
-
- ret = mknod(dst, statp->st_mode & ~07777, statp->st_rdev);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot mknod special file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = chown(dst, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot chown special file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = chmod(dst, statp->st_mode & 07777);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot chmod special file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- ret = utimes(dst, mt);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot call utimes on special file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- return ret;
- }
-
- return EOK;
-}
-
-static int copy_file(const char *src,
- const char *dst,
- const struct stat *statp,
- const struct timeval mt[],
- uid_t uid, gid_t gid)
-{
- int ret;
- int ifd = -1;
- int ofd = -1;
- char buf[1024];
- ssize_t cnt, written, offset;
- struct stat fstatbuf;
-
- ifd = open(src, O_RDONLY);
- if (ifd < 0) {
- ret = errno;
- DEBUG(1, ("Cannot open() source file '%s': [%d][%s].\n",
- src, ret, strerror(ret)));
- goto fail;
- }
-
- ret = fstat(ifd, &fstatbuf);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot fstat() source file '%s': [%d][%s].\n",
- src, ret, strerror(ret)));
- goto fail;
- }
-
- if (statp->st_dev != fstatbuf.st_dev ||
- statp->st_ino != fstatbuf.st_ino) {
- DEBUG(1, ("File %s was modified between lstat and open.\n", src));
- ret = EIO;
- goto fail;
- }
-
- selinux_file_context(dst);
-
- ofd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, statp->st_mode & 07777);
- if (ofd < 0) {
- ret = errno;
- DEBUG(1, ("Cannot open() destination file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
- ret = fchown(ofd, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot fchown() destination file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
- ret = fchmod(ofd, statp->st_mode & 07777);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot fchmod() destination file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
- while ((cnt = read(ifd, buf, sizeof(buf))) > 0) {
- offset = 0;
- while (cnt > 0) {
- written = write(ofd, buf+offset, (size_t)cnt);
- if (written == -1) {
- ret = errno;
- DEBUG(1, ("Cannot write() to source file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
- offset += written;
- cnt -= written;
- }
- }
- if (cnt == -1) {
- ret = errno;
- DEBUG(1, ("Cannot read() from source file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
-
- ret = close(ifd);
- ifd = -1;
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot close() source file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
- ret = close(ofd);
- ifd = -1;
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot close() destination file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
- ret = utimes(dst, mt);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot call utimes() on destination file '%s': [%d][%s].\n",
- dst, ret, strerror(ret)));
- goto fail;
- }
-
- return EOK;
-
- /* Reachable by jump only */
-fail:
- if (ifd != -1) close(ifd);
- if (ofd != -1) close(ofd);
- return ret;
-}
-
-/*
- * The context is not freed in case of error
- * because this is a recursive function, will be freed when we
- * reach the top level copy_tree() again
- */
-static int copy_entry(struct copy_ctx *cctx,
- const char *src,
- const char *dst,
- uid_t uid,
- gid_t gid)
-{
- int ret = EOK;
- struct stat sb;
- struct timeval mt[2];
-
- ret = lstat(src, &sb);
- if (ret == -1) {
- ret = errno;
- DEBUG(1, ("Cannot lstat() the source file '%s': [%d][%s].\n",
- src, ret, strerror(ret)));
- return ret;
- }
-
- mt[0].tv_sec = sb.st_atime;
- mt[0].tv_usec = 0;
-
- mt[1].tv_sec = sb.st_mtime;
- mt[1].tv_usec = 0;
-
- if (S_ISLNK (sb.st_mode)) {
- ret = copy_symlink(cctx, src, dst, &sb, mt, uid, gid);
- if (ret != EOK) {
- DEBUG(1, ("Cannot copy symlink '%s' to '%s': [%d][%s]\n",
- src, dst, ret, strerror(ret)));
- }
- return ret;
- }
-
- if (S_ISDIR(sb.st_mode)) {
- /* Check if we're still on the same FS */
- if (sb.st_dev != cctx->src_dev) {
- DEBUG(2, ("Will not descend to other FS\n"));
- /* Skip this without error */
- return EOK;
- }
- return copy_dir(src, dst, &sb, mt, uid, gid);
- } else if (!S_ISREG(sb.st_mode)) {
- /*
- * Deal with FIFOs and special files. The user really
- * shouldn't have any of these, but it seems like it
- * would be nice to copy everything ...
- */
- return copy_special(dst, &sb, mt, uid, gid);
- } else {
- /*
- * Create the new file and copy the contents. The new
- * file will be owned by the provided UID and GID values.
- */
- return copy_file(src, dst, &sb, mt, uid, gid);
- }
-
- return ret;
-}
-
-/*
- * The context is not freed in case of error
- * because this is a recursive function, will be freed when we
- * reach the top level copy_tree() again
- */
-static int copy_tree_ctx(struct copy_ctx *cctx,
- const char *src_root,
- const char *dst_root,
- uid_t uid,
- gid_t gid)
-{
- DIR *src_dir;
- int ret;
- struct dirent *result;
- struct dirent direntp;
- char *src_name, *dst_name;
- TALLOC_CTX *tmp_ctx;
-
- tmp_ctx = talloc_new(cctx);
-
- src_dir = opendir(src_root);
- if (src_dir == NULL) {
- ret = errno;
- DEBUG(1, ("Cannot open the source directory %s: [%d][%s].\n",
- src_root, ret, strerror(ret)));
- goto fail;
- }
-
- while (readdir_r(src_dir, &direntp, &result) == 0) {
- if (result == NULL) {
- /* End of directory */
- break;
- }
-
- if (strcmp (direntp.d_name, ".") == 0 ||
- strcmp (direntp.d_name, "..") == 0) {
- continue;
- }
-
- /* build src and dst paths */
- src_name = talloc_asprintf(tmp_ctx, "%s/%s", src_root, direntp.d_name);
- dst_name = talloc_asprintf(tmp_ctx, "%s/%s", dst_root, direntp.d_name);
- if (dst_name == NULL || src_name == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- /* copy */
- ret = copy_entry(cctx, src_name, dst_name, uid, gid);
- if (ret != EOK) {
- DEBUG(1, ("Cannot copy '%s' to '%s', error %d\n",
- src_name, dst_name, ret));
- goto fail;
- }
- talloc_free(src_name);
- talloc_free(dst_name);
- }
-
- ret = closedir(src_dir);
- if (ret != 0) {
- ret = errno;
- goto fail;
- }
-
-fail:
- talloc_free(tmp_ctx);
- return ret;
-}
-
-int copy_tree(const char *src_root, const char *dst_root,
- uid_t uid, gid_t gid)
-{
- int ret = EOK;
- struct copy_ctx *cctx = NULL;
- struct stat s_src;
-
- cctx = talloc_zero(NULL, struct copy_ctx);
-
- ret = lstat(src_root, &s_src);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot lstat the source directory '%s': [%d][%s]\n",
- src_root, ret, strerror(ret)));
- goto fail;
- }
-
- cctx->src_orig = src_root;
- cctx->dst_orig = dst_root;
- cctx->src_dev = s_src.st_dev;
-
- ret = copy_tree_ctx(cctx, src_root, dst_root, uid, gid);
- if (ret != EOK) {
- DEBUG(1, ("copy_tree_ctx failed: [%d][%s]\n", ret, strerror(ret)));
- goto fail;
- }
-
-fail:
- reset_selinux_file_context();
- talloc_free(cctx);
- return ret;
-}
-
diff --git a/server/tools/sss_groupadd.c b/server/tools/sss_groupadd.c
deleted file mode 100644
index 15eed100e..000000000
--- a/server/tools/sss_groupadd.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- SSSD
-
- sss_groupadd
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-int main(int argc, const char **argv)
-{
- gid_t pc_gid = 0;
- 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 },
- POPT_TABLEEND
- };
- poptContext pc = NULL;
- struct tools_ctx *tctx = NULL;
- int ret = EXIT_SUCCESS;
- const char *pc_groupname = NULL;
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse params */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "GROUPNAME");
- if ((ret = poptGetNextOpt(pc)) < -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- debug_level = pc_debug;
-
- /* groupname is an argument, not option */
- pc_groupname = poptGetArg(pc);
- if (pc_groupname == NULL) {
- usage(pc, _("Specify group to add\n"));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* if the domain was not given as part of FQDN, default to local domain */
- ret = parse_name_domain(tctx, pc_groupname);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- tctx->octx->gid = pc_gid;
-
- /* arguments processed, go on to actual work */
- if (id_in_range(tctx->octx->gid, tctx->octx->domain) != EOK) {
- ERROR("The selected GID is outside the allowed range\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- start_transaction(tctx);
- if (tctx->error != EOK) {
- goto done;
- }
-
- /* groupadd */
- ret = groupadd(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx);
- if (ret != EOK) {
- tctx->error = ret;
-
- /* cancel transaction */
- talloc_zfree(tctx->handle);
- goto done;
- }
-
- end_transaction(tctx);
-
-done:
- if (tctx->error) {
- ret = tctx->error;
- switch (ret) {
- case ERANGE:
- ERROR("Could not allocate ID for the group - domain full?\n");
- break;
-
- case EEXIST:
- ERROR("A group with the same name or GID already exists\n");
- break;
-
- default:
- DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
- ERROR("Transaction error. Could not add group.\n");
- break;
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = EXIT_SUCCESS;
-fini:
- talloc_free(tctx);
- poptFreeContext(pc);
- exit(ret);
-}
-
diff --git a/server/tools/sss_groupdel.c b/server/tools/sss_groupdel.c
deleted file mode 100644
index e5b043e27..000000000
--- a/server/tools/sss_groupdel.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- SSSD
-
- sss_groupdel
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-
-#include "db/sysdb.h"
-#include "util/util.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-int main(int argc, const char **argv)
-{
- int ret = EXIT_SUCCESS;
- int pc_debug = 0;
- const char *pc_groupname = NULL;
- struct tools_ctx *tctx = NULL;
-
- 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 },
- POPT_TABLEEND
- };
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse ops_ctx */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "GROUPNAME");
- if ((ret = poptGetNextOpt(pc)) < -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- debug_level = pc_debug;
-
- pc_groupname = poptGetArg(pc);
- if (pc_groupname == NULL) {
- usage(pc, _("Specify group to delete\n"));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* if the domain was not given as part of FQDN, default to local domain */
- ret = parse_name_domain(tctx, pc_groupname);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = sysdb_getgrnam_sync(tctx, tctx->ev, tctx->sysdb,
- tctx->octx->name, tctx->local,
- &tctx->octx);
- if (ret != EOK) {
- /* Error message will be printed in the switch */
- goto done;
- }
-
- if ((tctx->octx->gid < tctx->local->id_min) ||
- (tctx->local->id_max && tctx->octx->gid > tctx->local->id_max)) {
- ERROR("Group %s is outside the defined ID range for domain\n",
- tctx->octx->name);
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- start_transaction(tctx);
- if (tctx->error != EOK) {
- goto done;
- }
-
- /* groupdel */
- ret = groupdel(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx);
- if (ret != EOK) {
- tctx->error = ret;
-
- /* cancel transaction */
- talloc_zfree(tctx->handle);
- goto done;
- }
-
- end_transaction(tctx);
-
- ret = tctx->error;
-done:
- if (ret) {
- DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
- switch (ret) {
- case ENOENT:
- ERROR("No such group in local domain. "
- "Removing groups only allowed in local domain.\n");
- break;
-
- default:
- ERROR("Internal error. Could not remove group.\n");
- break;
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = EXIT_SUCCESS;
-
-fini:
- talloc_free(tctx);
- poptFreeContext(pc);
- exit(ret);
-}
-
diff --git a/server/tools/sss_groupmod.c b/server/tools/sss_groupmod.c
deleted file mode 100644
index b25a018d3..000000000
--- a/server/tools/sss_groupmod.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- SSSD
-
- sss_groupmod
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-#include <errno.h>
-#include <grp.h>
-#include <unistd.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-int main(int argc, const char **argv)
-{
- gid_t pc_gid = 0;
- 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 },
- POPT_TABLEEND
- };
- poptContext pc = NULL;
- struct tools_ctx *tctx = NULL;
- char *addgroups = NULL, *rmgroups = NULL;
- int ret;
- const char *pc_groupname = NULL;
- char *badgroup = NULL;
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse parameters */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "GROUPNAME");
- while ((ret = poptGetNextOpt(pc)) > 0) {
- switch (ret) {
- case 'a':
- addgroups = poptGetOptArg(pc);
- if (addgroups == NULL) {
- ret = -1;
- }
- break;
-
- case 'r':
- rmgroups = poptGetOptArg(pc);
- if (rmgroups == NULL) {
- ret = -1;
- }
- break;
- }
- }
-
- if (ret != -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* groupname is an argument without --option */
- pc_groupname = poptGetArg(pc);
- if (pc_groupname == NULL) {
- usage(pc, _("Specify group to modify\n"));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- debug_level = pc_debug;
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = parse_name_domain(tctx, pc_groupname);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
- /* check the username to be able to give sensible error message */
- ret = sysdb_getgrnam_sync(tctx, tctx->ev, tctx->sysdb,
- tctx->octx->name, tctx->local,
- &tctx->octx);
- if (ret != EOK) {
- ERROR("Cannot find group in local domain, "
- "modifying groups is allowed only in local domain\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
-
- tctx->octx->gid = pc_gid;
-
- if (addgroups) {
- ret = parse_groups(tctx, addgroups, &tctx->octx->addgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse groups to add the group to\n"));
- ERROR("Internal error while parsing parameters\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = parse_group_name_domain(tctx, tctx->octx->addgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse FQDN groups to add the group to\n"));
- ERROR("Member groups must be in the same domain as parent group\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* Check group names in the LOCAL domain */
- ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup);
- if (ret != EOK) {
- ERROR("Cannot find group %s in local domain, "
- "only groups in local domain are allowed\n", badgroup);
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- if (rmgroups) {
- ret = parse_groups(tctx, rmgroups, &tctx->octx->rmgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse groups to remove the group from\n"));
- ERROR("Internal error while parsing parameters\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = parse_group_name_domain(tctx, tctx->octx->rmgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse FQDN groups to remove the group from\n"));
- ERROR("Member groups must be in the same domain as parent group\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* Check group names in the LOCAL domain */
- ret = check_group_names(tctx, tctx->octx->rmgroups, &badgroup);
- if (ret != EOK) {
- ERROR("Cannot find group %s in local domain, "
- "only groups in local domain are allowed\n", badgroup);
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- if (id_in_range(tctx->octx->gid, tctx->octx->domain) != EOK) {
- ERROR("The selected GID is outside the allowed range\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- start_transaction(tctx);
- if (tctx->error != EOK) {
- goto done;
- }
-
- /* groupmod */
- ret = groupmod(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx);
- if (ret != EOK) {
- tctx->error = ret;
-
- /* cancel transaction */
- talloc_zfree(tctx->handle);
- goto done;
- }
-
- end_transaction(tctx);
-
-done:
- if (tctx->error) {
- ret = tctx->error;
- DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
- switch (ret) {
- case ENOENT:
- ERROR("Could not modify group - check if member group names are correct\n");
- break;
-
- case EFAULT:
- ERROR("Could not modify group - check if groupname is correct\n");
- break;
-
- default:
- ERROR("Transaction error. Could not modify group.\n");
- break;
- }
-
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = EXIT_SUCCESS;
-
-fini:
- free(addgroups);
- free(rmgroups);
- poptFreeContext(pc);
- talloc_free(tctx);
- exit(ret);
-}
diff --git a/server/tools/sss_groupshow.c b/server/tools/sss_groupshow.c
deleted file mode 100644
index 2f848b7d8..000000000
--- a/server/tools/sss_groupshow.c
+++ /dev/null
@@ -1,944 +0,0 @@
-/*
- SSSD
-
- sss_groupshow
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2010
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-
-#include "db/sysdb.h"
-#include "util/util.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-#define PADDING_SPACES 4
-#define GROUP_SHOW_ATTRS { SYSDB_MEMBEROF, SYSDB_GIDNUM, \
- SYSDB_MEMBER, SYSDB_NAME, \
- NULL }
-#define GROUP_SHOW_MPG_ATTRS { SYSDB_MEMBEROF, SYSDB_UIDNUM, \
- SYSDB_NAME, NULL }
-
-struct group_info {
- const char *name;
- gid_t gid;
- bool mpg;
-
- const char **user_members;
- const char **memberofs;
-
- struct group_info **group_members;
-};
-
-/*==================Helper routines to process results================= */
-const char *rdn_as_string(TALLOC_CTX *mem_ctx,
- struct ldb_dn *dn)
-{
- const struct ldb_val *val;
-
- val = ldb_dn_get_rdn_val(dn);
- if (val == NULL) {
- return NULL;
- }
-
- return ldb_dn_escape_value(mem_ctx, *val);;
-}
-
-static int parse_memberofs(struct ldb_context *ldb,
- struct ldb_message_element *el,
- struct group_info *gi)
-{
- int i;
- struct ldb_dn *dn = NULL;
-
- gi->memberofs = talloc_array(gi, const char *, el->num_values+1);
- if (gi->memberofs == NULL) {
- return ENOMEM;
- }
-
- for (i = 0; i< el->num_values; ++i) {
- dn = ldb_dn_from_ldb_val(gi, ldb, &(el->values[i]));
- gi->memberofs[i] = talloc_strdup(gi, rdn_as_string(gi, dn));
- talloc_zfree(dn);
- if (gi->memberofs[i] == NULL) {
- return ENOMEM;
- }
- DEBUG(6, ("memberof value: %s\n", gi->memberofs[i]));
- }
- gi->memberofs[el->num_values] = NULL;
-
- return EOK;
-}
-
-static int parse_members(TALLOC_CTX *mem_ctx,
- struct ldb_context *ldb,
- struct sss_domain_info *domain,
- struct ldb_message_element *el,
- const char *parent_name,
- const char ***user_members,
- const char ***group_members,
- int *num_group_members)
-{
- struct ldb_dn *user_basedn = NULL, *group_basedn = NULL;
- struct ldb_dn *parent_dn = NULL;
- struct ldb_dn *dn = NULL;
- const char **um = NULL, **gm = NULL;
- unsigned int um_index = 0, gm_index = 0;
- TALLOC_CTX *tmp_ctx = NULL;
- int ret;
- int i;
-
- tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx) {
- ret = ENOMEM;
- goto fail;
- }
-
- user_basedn = ldb_dn_new_fmt(tmp_ctx, ldb,
- SYSDB_TMPL_USER_BASE,
- domain->name);
- group_basedn = ldb_dn_new_fmt(tmp_ctx, ldb,
- SYSDB_TMPL_GROUP_BASE,
- domain->name);
- if (!user_basedn || !group_basedn) {
- ret = ENOMEM;
- goto fail;
- }
-
- um = talloc_array(mem_ctx, const char *, el->num_values+1);
- gm = talloc_array(mem_ctx, const char *, el->num_values+1);
- if (!um || !gm) {
- ret = ENOMEM;
- goto fail;
- }
-
- for (i = 0; i< el->num_values; ++i) {
- dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &(el->values[i]));
-
- /* user member or group member? */
- parent_dn = ldb_dn_get_parent(tmp_ctx, dn);
- if (ldb_dn_compare_base(parent_dn, user_basedn) == 0) {
- um[um_index] = rdn_as_string(mem_ctx, dn);
- if (um[um_index] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- DEBUG(6, ("User member %s\n", um[um_index]));
- um_index++;
- } else if (ldb_dn_compare_base(parent_dn, group_basedn) == 0) {
- gm[gm_index] = rdn_as_string(mem_ctx, dn);
- if (gm[gm_index] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
- if (parent_name && strcmp(gm[gm_index], parent_name) == 0) {
- DEBUG(6, ("Skipping circular nesting for group %s\n",
- gm[gm_index]));
- continue;
- }
- DEBUG(6, ("Group member %s\n", gm[gm_index]));
- gm_index++;
- } else {
- DEBUG(2, ("Group member not a user nor group: %s\n",
- ldb_dn_get_linearized(dn)));
- ret = EIO;
- goto fail;
- }
-
- talloc_zfree(dn);
- talloc_zfree(parent_dn);
- }
- um[um_index] = NULL;
- gm[gm_index] = NULL;
-
- if (um_index > 0) {
- um = talloc_realloc(mem_ctx, um, const char *, um_index+1);
- if (!um) {
- ret = ENOMEM;
- goto fail;
- }
- } else {
- talloc_zfree(um);
- }
-
- if (gm_index > 0) {
- gm = talloc_realloc(mem_ctx, gm, const char *, gm_index+1);
- if (!gm) {
- ret = ENOMEM;
- goto fail;
- }
- } else {
- talloc_zfree(gm);
- }
-
- *user_members = um;
- *group_members = gm;
- *num_group_members = gm_index;
- talloc_zfree(tmp_ctx);
- return EOK;
-
-fail:
- talloc_zfree(um);
- talloc_zfree(gm);
- talloc_zfree(tmp_ctx);
- return ret;
-}
-
-static int process_group(TALLOC_CTX *mem_ctx,
- struct ldb_context *ldb,
- struct ldb_message *msg,
- struct sss_domain_info *domain,
- const char *parent_name,
- struct group_info **info,
- const char ***group_members,
- int *num_group_members)
-{
- struct ldb_message_element *el;
- int ret;
- struct group_info *gi = NULL;
-
- DEBUG(6, ("Found entry %s\n", ldb_dn_get_linearized(msg->dn)));
-
- gi = talloc_zero(mem_ctx, struct group_info);
- if (!gi) {
- ret = ENOMEM;
- goto done;
- }
-
- /* mandatory data - name and gid */
- gi->name = talloc_strdup(gi,
- ldb_msg_find_attr_as_string(msg,
- SYSDB_NAME,
- NULL));
- gi->gid = ldb_msg_find_attr_as_uint64(msg,
- SYSDB_GIDNUM, 0);
- if (gi->gid == 0 || gi->name == NULL) {
- DEBUG(3, ("No name or no GID?\n"));
- ret = EIO;
- goto done;
- }
-
- /* list members */
- el = ldb_msg_find_element(msg, SYSDB_MEMBER);
- if (el) {
- ret = parse_members(gi, ldb, domain, el,
- parent_name,
- &gi->user_members,
- group_members, num_group_members);
- if (ret != EOK) {
- goto done;
- }
- }
-
- /* list memberofs */
- el = ldb_msg_find_element(msg, SYSDB_MEMBEROF);
- if (el) {
- ret = parse_memberofs(ldb, el, gi);
- if (ret != EOK) {
- goto done;
- }
- }
-
- *info = gi;
- return EOK;
-done:
- talloc_zfree(gi);
- return ret;
-}
-
-/*========Find info about a group and recursively about subgroups====== */
-struct group_show_state {
- struct tevent_context *ev;
- struct sysdb_ctx *sysdb;
- struct sysdb_handle *handle;
- struct sss_domain_info *domain;
-
- struct group_info *root;
- bool recursive;
-};
-
-static void group_show_root_done(struct tevent_req *subreq);
-static void group_show_recurse_done(struct tevent_req *subreq);
-
-struct tevent_req *group_show_recurse_send(TALLOC_CTX *,
- struct group_show_state *,
- struct group_info *,
- const char **,
- const int );
-static int group_show_recurse_recv(TALLOC_CTX *, struct tevent_req *,
- struct group_info ***);
-
-struct tevent_req *group_show_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- bool recursive,
- const char *name)
-{
- struct group_show_state *search_state = NULL;
- struct tevent_req *subreq = NULL;
- struct tevent_req *req = NULL;
- static const char *attrs[] = GROUP_SHOW_ATTRS;
-
- req = tevent_req_create(mem_ctx, &search_state, struct group_show_state);
- if (req == NULL) {
- return NULL;
- }
- search_state->ev = ev;
- search_state->sysdb = sysdb;
- search_state->handle = handle;
- search_state->domain = domain;
- search_state->recursive = recursive;
-
- /* First, search for the root group */
- subreq = sysdb_search_group_by_name_send(search_state,
- search_state->ev,
- search_state->sysdb,
- search_state->handle,
- search_state->domain,
- name, attrs);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, group_show_root_done, req);
-
- return req;
-}
-
-static void group_show_root_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct group_show_state *state = tevent_req_data(req,
- struct group_show_state);
- int ret;
- int i;
- struct ldb_message *msg = NULL;
- const char **group_members = NULL;
- int nmembers = 0;
-
- ret = sysdb_search_group_recv(subreq, state, &msg);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Search failed: %s (%d)\n", strerror(ret), ret));
- tevent_req_error(req, ret);
- return;
- }
-
- ret = process_group(state,
- sysdb_ctx_get_ldb(state->sysdb),
- msg, state->domain, NULL, &state->root,
- &group_members, &nmembers);
- if (ret != EOK) {
- DEBUG(2, ("Group processing failed: %s (%d)\n",
- strerror(ret), ret));
- tevent_req_error(req, ret);
- return;
- }
-
- if (group_members == NULL) {
- tevent_req_done(req);
- return;
- }
-
- if (state->recursive == false) {
- /* if not recursive, just fill in names */
- state->root->group_members = talloc_array(state->root,
- struct group_info *,
- nmembers+1);
- for (i=0; group_members[i]; i++) {
- state->root->group_members[i] = talloc_zero(state->root,
- struct group_info);
- if (!state->root->group_members) {
- tevent_req_error(req, ENOMEM);
- }
- state->root->group_members[i]->name = talloc_strdup(state->root,
- group_members[i]);
- if (!state->root->group_members[i]->name) {
- tevent_req_error(req, ENOMEM);
- }
- }
- state->root->group_members[nmembers] = NULL;
-
- tevent_req_done(req);
- return;
- }
-
- subreq = group_show_recurse_send(state->root, state,
- state->root,
- group_members,
- nmembers);
- if (!subreq) {
- tevent_req_error(req, ret);
- return;
- }
- tevent_req_set_callback(subreq, group_show_recurse_done, req);
-}
-
-static void group_show_recurse_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct group_show_state *state = tevent_req_data(req,
- struct group_show_state);
- int ret;
-
- ret = group_show_recurse_recv(state->root,
- subreq,
- &state->root->group_members);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Recursive search failed: %s (%d)\n", strerror(ret), ret));
- tevent_req_error(req, EIO);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static int group_show_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- struct group_info **res)
-{
- struct group_show_state *state = tevent_req_data(req,
- struct group_show_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
- *res = talloc_move(mem_ctx, &state->root);
-
- return EOK;
-}
-
-/*==================Recursive search for nested groups================= */
-struct group_show_recurse {
- const char **names;
- int current;
-
- struct group_info *parent;
- struct group_show_state *state;
-
- struct group_info **groups;
-};
-
-static int group_show_recurse_search(struct tevent_req *,
- struct group_show_recurse *);
-static void group_show_recurse_next(struct tevent_req *);
-static void group_show_recurse_level_done(struct tevent_req *);
-static void group_show_recurse_cont(struct tevent_req *);
-
-struct tevent_req *group_show_recurse_send(TALLOC_CTX *mem_ctx,
- struct group_show_state *state,
- struct group_info *parent,
- const char **group_members,
- const int nmembers)
-{
- struct tevent_req *req = NULL;
- struct group_show_recurse *recurse_state = NULL;
-
- req = tevent_req_create(mem_ctx, &recurse_state, struct group_show_recurse);
- if (req == NULL) {
- return NULL;
- }
- recurse_state->current = 0;
- recurse_state->parent = parent;
- recurse_state->names = group_members;
- recurse_state->state = state;
- recurse_state->groups = talloc_array(state->root,
- struct group_info *,
- nmembers+1); /* trailing NULL */
-
- if (!recurse_state->names ||
- !recurse_state->names[recurse_state->current]) {
- talloc_zfree(req);
- return NULL;
- }
-
- if (group_show_recurse_search(req, recurse_state) != EOK) {
- talloc_zfree(req);
- return NULL;
- }
-
- return req;
-}
-
-static int group_show_recurse_search(struct tevent_req *req,
- struct group_show_recurse *recurse_state)
-{
- static const char *attrs[] = GROUP_SHOW_ATTRS;
- struct tevent_req *subreq = NULL;
-
- /* Skip circular groups */
- if (strcmp(recurse_state->names[recurse_state->current],
- recurse_state->parent->name) == 0) {
- DEBUG(0, ("CIRCULAR DEP DETECTED\n"));
- group_show_recurse_cont(req);
- return EOK;
- }
-
- subreq = sysdb_search_group_by_name_send(recurse_state->state,
- recurse_state->state->ev,
- recurse_state->state->sysdb,
- recurse_state->state->handle,
- recurse_state->state->domain,
- recurse_state->names[recurse_state->current],
- attrs);
- if (!subreq) {
- return ENOMEM;
- }
- tevent_req_set_callback(subreq, group_show_recurse_next, req);
-
- return EOK;
-}
-
-static void group_show_recurse_next(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct group_show_recurse *recurse_state = tevent_req_data(req,
- struct group_show_recurse);
- const char **group_members = NULL;
- int nmembers = 0;
- struct ldb_message *msg = NULL;
- int ret;
- struct tevent_req *recurse_req = NULL;
-
- ret = sysdb_search_group_recv(subreq, recurse_state, &msg);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Search failed: %s (%d)\n", strerror(ret), ret));
- tevent_req_error(req, EIO);
- return;
- }
-
- ret = process_group(recurse_state->state->root,
- sysdb_ctx_get_ldb(recurse_state->state->sysdb),
- msg,
- recurse_state->state->domain,
- recurse_state->parent->name,
- &recurse_state->groups[recurse_state->current],
- &group_members,
- &nmembers);
- if (ret != EOK) {
- DEBUG(2, ("Group processing failed: %s (%d)\n",
- strerror(ret), ret));
- tevent_req_error(req, ret);
- return;
- }
-
- /* descend to another level */
- if (nmembers > 0) {
- recurse_req = group_show_recurse_send(recurse_state,
- recurse_state->state,
- recurse_state->groups[recurse_state->current],
- group_members, nmembers);
- if (!recurse_req) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- /* to free group_members in the callback */
- group_members = talloc_move(recurse_req, &group_members);
- tevent_req_set_callback(recurse_req, group_show_recurse_level_done, req);
- return;
- }
-
- /* Move to next group in the same level */
- group_show_recurse_cont(req);
-}
-
-static void group_show_recurse_level_done(struct tevent_req *recurse_req)
-{
- int ret;
- struct tevent_req *req = tevent_req_callback_data(recurse_req,
- struct tevent_req);
- struct group_show_recurse *recurse_state = tevent_req_data(recurse_req,
- struct group_show_recurse);
-
- ret = group_show_recurse_recv(recurse_state->state->root, recurse_req,
- &recurse_state->parent->group_members);
- talloc_zfree(recurse_req);
- if (ret) {
- DEBUG(2, ("Recursive search failed: %s (%d)\n", strerror(ret), ret));
- tevent_req_error(req, EIO);
- return;
- }
-
- /* Move to next group on the upper level */
- group_show_recurse_cont(req);
-}
-
-static void group_show_recurse_cont(struct tevent_req *req)
-{
- struct group_show_recurse *recurse_state = tevent_req_data(req,
- struct group_show_recurse);
- int ret;
-
- recurse_state->current++;
- if (recurse_state->names[recurse_state->current] == NULL) {
- recurse_state->groups[recurse_state->current] = NULL; /* Sentinel */
- tevent_req_done(req);
- return;
- }
-
- /* examine next group on the same level */
- ret = group_show_recurse_search(req, recurse_state);
- if (ret != EOK) {
- tevent_req_error(req, ret);
- return;
- }
-}
-
-static int group_show_recurse_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- struct group_info ***out)
-{
- struct group_show_recurse *recurse_state = tevent_req_data(req,
- struct group_show_recurse);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
- *out = talloc_move(mem_ctx, &recurse_state->groups);
-
- return EOK;
-}
-
-/*==================Get info about MPG================================= */
-struct group_show_mpg_state {
- struct ldb_context *ldb;
- struct group_info *info;
-};
-
-static void group_show_mpg_done(struct tevent_req *);
-
-struct tevent_req *group_show_mpg_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct sss_domain_info *domain,
- const char *name)
-{
- struct tevent_req *req = NULL;
- struct tevent_req *subreq = NULL;
- struct group_show_mpg_state *state;
- static const char *mpg_attrs[] = GROUP_SHOW_MPG_ATTRS;
-
- req = tevent_req_create(mem_ctx, &state, struct group_show_mpg_state);
- if (req == NULL) {
- return NULL;
- }
- state->ldb = sysdb_ctx_get_ldb(sysdb);
-
- subreq = sysdb_search_user_by_name_send(mem_ctx, ev, sysdb, handle,
- domain, name, mpg_attrs);
- if (!subreq) {
- talloc_zfree(req);
- return NULL;
- }
- tevent_req_set_callback(subreq, group_show_mpg_done, req);
-
- return req;
-}
-
-static void group_show_mpg_done(struct tevent_req *subreq)
-{
- int ret;
- struct ldb_message *msg = NULL;
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct group_show_mpg_state *state = tevent_req_data(req,
- struct group_show_mpg_state);
-
- ret = sysdb_search_user_recv(subreq, req, &msg);
- talloc_zfree(subreq);
- if (ret) {
- DEBUG(2, ("Search failed: %s (%d)\n", strerror(ret), ret));
- tevent_req_error(req, ret);
- return;
- }
-
- state->info = talloc_zero(state, struct group_info);
- if (!state->info) {
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- state->info->name = talloc_strdup(state->info,
- ldb_msg_find_attr_as_string(msg,
- SYSDB_NAME,
- NULL));
- state->info->gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0);
- if (state->info->gid == 0 || state->info->name == NULL) {
- DEBUG(3, ("No name or no GID?\n"));
- tevent_req_error(req, EIO);
- return;
- }
- state->info->mpg = true;
-
- tevent_req_done(req);
-}
-
-static int group_show_mpg_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- struct group_info **res)
-{
- struct group_show_mpg_state *state = tevent_req_data(req,
- struct group_show_mpg_state);
- TEVENT_REQ_RETURN_ON_ERROR(req);
- *res = talloc_move(mem_ctx, &state->info);
-
- return EOK;
-}
-
-/*==================The main program=================================== */
-struct sss_groupshow_state {
- struct group_info *root;
-
- int ret;
- bool done;
-};
-
-static void sss_group_show_done(struct tevent_req *req)
-{
- int ret;
- struct sss_groupshow_state *sss_state = tevent_req_callback_data(req,
- struct sss_groupshow_state);
-
- ret = group_show_recv(sss_state, req, &sss_state->root);
- talloc_zfree(req);
-
- sss_state->ret = ret;
- sss_state->done = true;
-}
-
-static void sss_group_show_mpg_done(struct tevent_req *req)
-{
- int ret;
- struct sss_groupshow_state *sss_state = tevent_req_callback_data(req,
- struct sss_groupshow_state);
-
- ret = group_show_mpg_recv(sss_state, req, &sss_state->root);
- talloc_zfree(req);
-
- sss_state->ret = ret;
- sss_state->done = true;
-}
-
-static void print_group_info(struct group_info *g, int level)
-{
- int i;
- char padding[512];
- char fmt[8];
-
- snprintf(fmt, 8, "%%%ds", level*PADDING_SPACES);
- snprintf(padding, 512, fmt, "");
-
- printf(_("%s%sGroup: %s\n"), padding,
- g->mpg ? _("Magic Private ") : "",
- g->name);
- printf(_("%sGID number: %d\n"), padding, g->gid);
-
- printf(_("%sMember users: "), padding);
- if (g->user_members) {
- for (i=0; g->user_members[i]; ++i) {
- printf("%s%s", i>0 ? "," : "",
- g->user_members[i]);
- }
- }
- printf(_("\n%sIs a member of: "), padding);
- if (g->memberofs) {
- for (i=0; g->memberofs[i]; ++i) {
- printf("%s%s", i>0 ? "," : "",
- g->memberofs[i]);
- }
- }
- printf(_("\n%sMember groups: "), padding);
-}
-
-static void print_recursive(struct group_info **group_members, int level)
-{
- int i;
-
- if (group_members == NULL) {
- return;
- }
-
- level++;
- for (i=0; group_members[i]; ++i) {
- printf("\n");
- print_group_info(group_members[i], level);
- printf("\n");
- print_recursive(group_members[i]->group_members, level);
- }
-}
-
-int main(int argc, const char **argv)
-{
- int ret = EXIT_SUCCESS;
- int pc_debug = 0;
- bool pc_recursive = false;
- const char *pc_groupname = NULL;
- struct tools_ctx *tctx = NULL;
- struct tevent_req *req = NULL;
- struct sss_groupshow_state *state = NULL;
- int i;
-
- 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 },
- { "recursive", 'R', POPT_ARG_NONE, NULL, 'r',
- _("Print indirect group members recursively"), NULL },
- POPT_TABLEEND
- };
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse ops_ctx */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "GROUPNAME");
- while ((ret = poptGetNextOpt(pc)) > 0) {
- switch (ret) {
- case 'r':
- pc_recursive = true;
- break;
- }
- }
-
- debug_level = pc_debug;
-
- if (ret != -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- pc_groupname = poptGetArg(pc);
- if (pc_groupname == NULL) {
- usage(pc, _("Specify group to show\n"));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* if the domain was not given as part of FQDN, default to local domain */
- ret = parse_name_domain(tctx, pc_groupname);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* The search itself */
- state = talloc_zero(tctx, struct sss_groupshow_state);
- if (!state) {
- goto fini;
- }
-
- req = group_show_send(tctx, tctx->ev, tctx->sysdb, tctx->handle,
- tctx->local, pc_recursive, tctx->octx->name);
- if (!req) {
- ERROR("Cannot initiate search\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
- tevent_req_set_callback(req, sss_group_show_done, state);
- while (!state->done) {
- tevent_loop_once(tctx->ev);
- }
- ret = state->ret;
-
- /* Also show MPGs */
- if (ret == ENOENT) {
- state->done = false;
- state->ret = EOK;
-
- req = group_show_mpg_send(tctx, tctx->ev, tctx->sysdb, tctx->handle,
- tctx->local, tctx->octx->name);
- if (!req) {
- ERROR("Cannot initiate search\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
- tevent_req_set_callback(req, sss_group_show_mpg_done, state);
- while (!state->done) {
- tevent_loop_once(tctx->ev);
- }
- ret = state->ret;
- }
-
- /* Process result */
- if (ret) {
- DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
- switch (ret) {
- case ENOENT:
- ERROR("No such group in local domain. "
- "Printing groups only allowed in local domain.\n");
- break;
-
- default:
- ERROR("Internal error. Could not print group.\n");
- break;
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* print the results */
- print_group_info(state->root, 0);
- if (pc_recursive) {
- printf("\n");
- print_recursive(state->root->group_members, 0);
- } else {
- if (state->root->group_members) {
- for (i=0; state->root->group_members[i]; ++i) {
- printf("%s%s", i>0 ? "," : "",
- state->root->group_members[i]->name);
- }
- }
- printf("\n");
- }
-
-fini:
- talloc_free(tctx);
- poptFreeContext(pc);
- exit(ret);
-}
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;
- }
-}
-
diff --git a/server/tools/sss_sync_ops.h b/server/tools/sss_sync_ops.h
deleted file mode 100644
index 383319a8f..000000000
--- a/server/tools/sss_sync_ops.h
+++ /dev/null
@@ -1,125 +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/>.
-*/
-
-#ifndef __SSS_OPS_H__
-#define __SSS_OPS_H__
-
-#include "tools/tools_util.h"
-#include <stdbool.h>
-
-#define DO_LOCK 1
-#define DO_UNLOCK 2
-
-/* 0 = not set, pick default */
-#define DO_CREATE_HOME 1
-#define DO_NOT_CREATE_HOME 2
-#define DO_REMOVE_HOME 1
-#define DO_NOT_REMOVE_HOME 2
-#define DO_FORCE_REMOVAL 1
-
-struct ops_ctx {
- struct sss_domain_info *domain;
-
- char *name;
- uid_t uid;
- gid_t gid;
- char *gecos;
- char *home;
- char *shell;
- int lock;
-
- bool create_homedir;
- bool remove_homedir;
- mode_t umask;
- char *skeldir;
- char *maildir;
-
- char **addgroups;
- char **rmgroups;
-};
-
-/* 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);
-
-/* default values for remove operations */
-int userdel_defaults(TALLOC_CTX *mem_ctx,
- struct confdb_ctx *confdb,
- struct ops_ctx *data,
- int remove_home);
-
-/* synchronous operations */
-int useradd(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data);
-int userdel(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data);
-int usermod(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data);
-
-int groupadd(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data);
-int groupdel(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data);
-int groupmod(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sysdb_ctx *sysdb,
- struct sysdb_handle *handle,
- struct ops_ctx *data);
-
-void start_transaction(struct tools_ctx *tctx);
-void end_transaction(struct tools_ctx *tctx);
-
-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 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);
-
-#endif /* __SSS_OPS_H__ */
-
diff --git a/server/tools/sss_useradd.c b/server/tools/sss_useradd.c
deleted file mode 100644
index 077ac99f7..000000000
--- a/server/tools/sss_useradd.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- SSSD
-
- sss_useradd
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
- Copyright (C) Simo Sorce <ssorce@redhat.com> 2009
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-#include <errno.h>
-#include <unistd.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-static void get_gid_callback(void *ptr, int error, struct ldb_result *res)
-{
- struct tools_ctx *tctx = talloc_get_type(ptr, struct tools_ctx);
-
- if (error) {
- tctx->error = error;
- return;
- }
-
- switch (res->count) {
- case 0:
- tctx->error = ENOENT;
- break;
-
- case 1:
- tctx->octx->gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 0);
- if (tctx->octx->gid == 0) {
- tctx->error = ERANGE;
- }
- break;
-
- default:
- tctx->error = EFAULT;
- break;
- }
-}
-
-/* Returns a gid for a given groupname. If a numerical gid
- * is given, returns that as integer (rationale: shadow-utils)
- * On error, returns -EINVAL
- */
-static int get_gid(struct tools_ctx *tctx, const char *groupname)
-{
- char *end_ptr;
- int ret;
-
- errno = 0;
- tctx->octx->gid = strtoul(groupname, &end_ptr, 10);
- if (groupname == '\0' || *end_ptr != '\0' ||
- errno != 0 || tctx->octx->gid == 0) {
- /* Does not look like a gid - find the group name */
-
- ret = sysdb_getgrnam(tctx->octx, tctx->sysdb,
- tctx->octx->domain, groupname,
- get_gid_callback, tctx);
- if (ret != EOK) {
- DEBUG(1, ("sysdb_getgrnam failed: %d\n", ret));
- goto done;
- }
-
- tctx->error = EOK;
- tctx->octx->gid = 0;
- while ((tctx->error == EOK) && (tctx->octx->gid == 0)) {
- tevent_loop_once(tctx->ev);
- }
-
- if (tctx->error) {
- DEBUG(1, ("sysdb_getgrnam failed: %d\n", ret));
- goto done;
- }
- }
-
-done:
- return ret;
-}
-
-int main(int argc, const char **argv)
-{
- uid_t pc_uid = 0;
- const char *pc_group = NULL;
- const char *pc_gecos = NULL;
- const char *pc_home = NULL;
- char *pc_shell = NULL;
- int pc_debug = 0;
- int pc_create_home = 0;
- const char *pc_username = NULL;
- const char *pc_skeldir = 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 },
- { "uid", 'u', POPT_ARG_INT, &pc_uid, 0, _("The UID of the user"), NULL },
- { "gid", 'g', POPT_ARG_STRING, &pc_group, 0, _("The GID or group name of the user"), NULL },
- { "gecos", 'c', POPT_ARG_STRING, &pc_gecos, 0, _("The comment string"), NULL },
- { "home", 'h', POPT_ARG_STRING, &pc_home, 0, _("Home directory"), NULL },
- { "shell", 's', POPT_ARG_STRING, &pc_shell, 0, _("Login shell"), NULL },
- { "groups", 'G', POPT_ARG_STRING, NULL, 'G', _("Groups"), NULL },
- { "create-home", 'm', POPT_ARG_NONE, NULL, 'm', _("Create user's directory if it does not exist"), NULL },
- { "no-create-home", 'M', POPT_ARG_NONE, NULL, 'M', _("Never create user's directory, overrides config"), NULL },
- { "skel", 'k', POPT_ARG_STRING, &pc_skeldir, 0, _("Specify an alternative skeleton directory") },
- POPT_TABLEEND
- };
- poptContext pc = NULL;
- struct tools_ctx *tctx = NULL;
- char *groups = NULL;
- char *badgroup = NULL;
- int ret;
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse parameters */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "USERNAME");
- while ((ret = poptGetNextOpt(pc)) > 0) {
- switch (ret) {
- case 'G':
- groups = poptGetOptArg(pc);
- if (!groups) goto fini;
-
- case 'm':
- pc_create_home = DO_CREATE_HOME;
- break;
-
- case 'M':
- pc_create_home = DO_NOT_CREATE_HOME;
- break;
- }
- }
-
- debug_level = pc_debug;
-
- if (ret != -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* username is an argument without --option */
- pc_username = poptGetArg(pc);
- if (pc_username == NULL) {
- usage(pc, (_("Specify user to add\n")));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* if the domain was not given as part of FQDN, default to local domain */
- ret = parse_name_domain(tctx, pc_username);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- if (groups) {
- ret = parse_groups(tctx, groups, &tctx->octx->addgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse groups to add the user to\n"));
- ERROR("Internal error while parsing parameters\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = parse_group_name_domain(tctx, tctx->octx->addgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse FQDN groups to add the user to\n"));
- ERROR("Groups must be in the same domain as user\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* Check group names in the LOCAL domain */
- ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup);
- if (ret != EOK) {
- ERROR("Cannot find group %s in local domain\n", badgroup);
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- /* Same as shadow-utils useradd, -g can specify gid or group name */
- if (pc_group != NULL) {
- ret = get_gid(tctx, pc_group);
- if (ret != EOK) {
- ERROR("Cannot get group information for the user\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- tctx->octx->uid = pc_uid;
-
- /*
- * Fills in defaults for ops_ctx user did not specify.
- */
- ret = useradd_defaults(tctx, tctx->confdb, tctx->octx,
- pc_gecos, pc_home, pc_shell,
- pc_create_home, pc_skeldir);
- if (ret != EOK) {
- ERROR("Cannot set default values\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* arguments processed, go on to actual work */
- if (id_in_range(tctx->octx->uid, tctx->octx->domain) != EOK) {
- ERROR("The selected UID is outside the allowed range\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- start_transaction(tctx);
- if (tctx->error != EOK) {
- goto done;
- }
-
- /* useradd */
- ret = useradd(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx);
- if (ret != EOK) {
- tctx->error = ret;
-
- /* cancel transaction */
- talloc_zfree(tctx->handle);
- goto done;
- }
-
- end_transaction(tctx);
-
- /* Create user's home directory and/or mail spool */
- if (tctx->octx->create_homedir) {
- /* We need to know the UID and GID of the user, if
- * sysdb did assign it automatically, do a lookup */
- if (tctx->octx->uid == 0 || tctx->octx->gid == 0) {
- ret = sysdb_getpwnam_sync(tctx,
- tctx->ev,
- tctx->sysdb,
- tctx->octx->name,
- tctx->local,
- &tctx->octx);
- if (ret != EOK) {
- ERROR("Cannot get info about the user\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- ret = create_homedir(tctx,
- tctx->octx->skeldir,
- tctx->octx->home,
- tctx->octx->name,
- tctx->octx->uid,
- tctx->octx->gid,
- tctx->octx->umask);
- if (ret == EEXIST) {
- ERROR("User's home directory already exists, not copying "
- "data from skeldir\n");
- } else if (ret != EOK) {
- ERROR("Cannot create user's home directory: %s\n", strerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = create_mail_spool(tctx,
- tctx->octx->name,
- tctx->octx->maildir,
- tctx->octx->uid,
- tctx->octx->gid);
- if (ret != EOK) {
- ERROR("Cannot create user's mail spool: %s\n", strerror(ret));
- DEBUG(1, ("Cannot create user's mail spool: [%d][%s].\n",
- ret, strerror(ret)));
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
-done:
- if (tctx->error) {
- switch (tctx->error) {
- case ERANGE:
- ERROR("Could not allocate ID for the user - domain full?\n");
- break;
-
- case EEXIST:
- ERROR("A user or group with the same name or ID already exists\n");
- break;
-
- default:
- DEBUG(1, ("sysdb operation failed (%d)[%s]\n",
- tctx->error, strerror(tctx->error)));
- ERROR("Transaction error. Could not add user.\n");
- break;
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = EXIT_SUCCESS;
-
-fini:
- poptFreeContext(pc);
- talloc_free(tctx);
- free(groups);
- exit(ret);
-}
diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c
deleted file mode 100644
index e84d78b17..000000000
--- a/server/tools/sss_userdel.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- SSSD
-
- sss_userdel
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-
-#include "db/sysdb.h"
-#include "util/util.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-int main(int argc, const char **argv)
-{
- int ret = EXIT_SUCCESS;
- struct tools_ctx *tctx = NULL;
- const char *pc_username = NULL;
-
- int pc_debug = 0;
- int pc_remove = 0;
- int pc_force = 0;
- 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 },
- { "remove", 'r', POPT_ARG_NONE, NULL, 'r', _("Remove home directory and mail spool"), NULL },
- { "no-remove", 'R', POPT_ARG_NONE, NULL, 'R', _("Do not remove home directory and mail spool"), NULL },
- { "force", 'f', POPT_ARG_NONE, NULL, 'f', _("Force removal of files not owned by the user"), NULL },
- POPT_TABLEEND
- };
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse parameters */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "USERNAME");
- while ((ret = poptGetNextOpt(pc)) > 0) {
- switch (ret) {
- case 'r':
- pc_remove = DO_REMOVE_HOME;
- break;
-
- case 'R':
- pc_remove = DO_NOT_REMOVE_HOME;
- break;
-
- case 'f':
- pc_force = DO_FORCE_REMOVAL;
- break;
- }
- }
-
- debug_level = pc_debug;
-
- if (ret != -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- pc_username = poptGetArg(pc);
- if (pc_username == NULL) {
- usage(pc, _("Specify user to delete\n"));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* if the domain was not given as part of FQDN, default to local domain */
- ret = parse_name_domain(tctx, pc_username);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /*
- * Fills in defaults for ops_ctx user did not specify.
- */
- ret = userdel_defaults(tctx, tctx->confdb, tctx->octx, pc_remove);
- if (ret != EOK) {
- ERROR("Cannot set default values\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = sysdb_getpwnam_sync(tctx,
- tctx->ev,
- tctx->sysdb,
- tctx->octx->name,
- tctx->local,
- &tctx->octx);
- if (ret != EOK) {
- /* Error message will be printed in the switch */
- goto done;
- }
-
- if ((tctx->octx->uid < tctx->local->id_min) ||
- (tctx->local->id_max && tctx->octx->uid > tctx->local->id_max)) {
- ERROR("User %s is outside the defined ID range for domain\n",
- tctx->octx->name);
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- start_transaction(tctx);
- if (tctx->error != EOK) {
- goto done;
- }
-
- /* userdel */
- ret = userdel(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx);
- if (ret != EOK) {
- tctx->error = ret;
-
- /* cancel transaction */
- talloc_zfree(tctx->handle);
- goto done;
- }
-
- end_transaction(tctx);
-
- if (tctx->octx->remove_homedir) {
- ret = remove_homedir(tctx,
- tctx->octx->home,
- tctx->octx->maildir,
- tctx->octx->name,
- tctx->octx->uid,
- pc_force);
- if (ret == EPERM) {
- ERROR("Not removing home dir - not owned by user\n");
- } else if (ret != EOK) {
- ERROR("Cannot remove homedir: %s\n", strerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- ret = tctx->error;
-done:
- if (ret) {
- DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
- switch (ret) {
- case ENOENT:
- ERROR("No such user in local domain. "
- "Removing users only allowed in local domain.\n");
- break;
-
- default:
- ERROR("Internal error. Could not remove user.\n");
- break;
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = EXIT_SUCCESS;
-
-fini:
- talloc_free(tctx);
- poptFreeContext(pc);
- exit(ret);
-}
-
diff --git a/server/tools/sss_usermod.c b/server/tools/sss_usermod.c
deleted file mode 100644
index a272bc55e..000000000
--- a/server/tools/sss_usermod.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- SSSD
-
- sss_usermod
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
-
- 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 <stdio.h>
-#include <stdlib.h>
-#include <talloc.h>
-#include <popt.h>
-#include <errno.h>
-#include <pwd.h>
-#include <unistd.h>
-
-#include "util/util.h"
-#include "db/sysdb.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-int main(int argc, const char **argv)
-{
- int pc_lock = 0;
- uid_t pc_uid = 0;
- gid_t pc_gid = 0;
- char *pc_gecos = NULL;
- char *pc_home = NULL;
- char *pc_shell = NULL;
- 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 },
- { "uid", 'u', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_uid, 0, _("The UID of the user"), NULL },
- { "gid", 'g', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_gid, 0, _("The GID of the user"), NULL },
- { "gecos", 'c', POPT_ARG_STRING, &pc_gecos, 0, _("The comment string"), NULL },
- { "home", 'h', POPT_ARG_STRING, &pc_home, 0, _("Home directory"), NULL },
- { "shell", 's', POPT_ARG_STRING, &pc_shell, 0, _("Login shell"), NULL },
- { "append-group", 'a', POPT_ARG_STRING, NULL, 'a', _("Groups to add this user to"), NULL },
- { "remove-group", 'r', POPT_ARG_STRING, NULL, 'r', _("Groups to remove this user from"), NULL },
- { "lock", 'L', POPT_ARG_NONE, NULL, 'L', _("Lock the account"), NULL },
- { "unlock", 'U', POPT_ARG_NONE, NULL, 'U', _("Unlock the account"), NULL },
- POPT_TABLEEND
- };
- poptContext pc = NULL;
- char *addgroups = NULL, *rmgroups = NULL;
- int ret;
- const char *pc_username = NULL;
- struct tools_ctx *tctx = NULL;
- char *badgroup = NULL;
-
- debug_prg_name = argv[0];
-
- ret = set_locale();
- if (ret != EOK) {
- DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
- ERROR("Error setting the locale\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* parse parameters */
- pc = poptGetContext(NULL, argc, argv, long_options, 0);
- poptSetOtherOptionHelp(pc, "USERNAME");
- while ((ret = poptGetNextOpt(pc)) > 0) {
- switch (ret) {
- case 'a':
- addgroups = poptGetOptArg(pc);
- if (addgroups == NULL) {
- ret = -1;
- }
- break;
-
- case 'r':
- rmgroups = poptGetOptArg(pc);
- if (rmgroups == NULL) {
- ret = -1;
- }
- break;
-
- case 'L':
- pc_lock = DO_LOCK;
- break;
-
- case 'U':
- pc_lock = DO_UNLOCK;
- break;
- }
- }
-
- if (ret != -1) {
- usage(pc, poptStrerror(ret));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- debug_level = pc_debug;
-
- /* username is an argument without --option */
- pc_username = poptGetArg(pc);
- if (pc_username == NULL) {
- usage(pc, _("Specify user to modify\n"));
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- CHECK_ROOT(ret, debug_prg_name);
-
- ret = init_sss_tools(&tctx);
- if (ret != EOK) {
- DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
- if (ret == ENOENT) {
- ERROR("Error initializing the tools - no local domain\n");
- } else {
- ERROR("Error initializing the tools\n");
- }
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* if the domain was not given as part of FQDN, default to local domain */
- ret = parse_name_domain(tctx, pc_username);
- if (ret != EOK) {
- ERROR("Invalid domain specified in FQDN\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
- /* check the username to be able to give sensible error message */
- ret = sysdb_getpwnam_sync(tctx, tctx->ev, tctx->sysdb,
- tctx->octx->name, tctx->local,
- &tctx->octx);
- if (ret != EOK) {
- ERROR("Cannot find user in local domain, "
- "modifying users is allowed only in local domain\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- if (id_in_range(tctx->octx->uid, tctx->octx->domain) != EOK) {
- ERROR("The selected UID is outside the allowed range\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- if (addgroups) {
- ret = parse_groups(tctx, addgroups, &tctx->octx->addgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse groups to add the user to\n"));
- ERROR("Internal error while parsing parameters\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = parse_group_name_domain(tctx, tctx->octx->addgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse FQDN groups to add the user to\n"));
- ERROR("Groups must be in the same domain as user\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* Check group names in the LOCAL domain */
- ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup);
- if (ret != EOK) {
- ERROR("Cannot find group %s in local domain, "
- "only groups in local domain are allowed\n", badgroup);
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- if (rmgroups) {
- ret = parse_groups(tctx, rmgroups, &tctx->octx->rmgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse groups to remove the user from\n"));
- ERROR("Internal error while parsing parameters\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = parse_group_name_domain(tctx, tctx->octx->rmgroups);
- if (ret != EOK) {
- DEBUG(1, ("Cannot parse FQDN groups to remove the user from\n"));
- ERROR("Groups must be in the same domain as user\n");
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- /* Check group names in the LOCAL domain */
- ret = check_group_names(tctx, tctx->octx->rmgroups, &badgroup);
- if (ret != EOK) {
- ERROR("Cannot find group %s in local domain, "
- "only groups in local domain are allowed\n", badgroup);
- ret = EXIT_FAILURE;
- goto fini;
- }
- }
-
- tctx->octx->gecos = pc_gecos;
- tctx->octx->home = pc_home;
- tctx->octx->shell = pc_shell;
- tctx->octx->uid = pc_uid;
- tctx->octx->gid = pc_gid;
- tctx->octx->lock = pc_lock;
-
- start_transaction(tctx);
- if (tctx->error != EOK) {
- goto done;
- }
-
- /* usermod */
- ret = usermod(tctx, tctx->ev, tctx->sysdb, tctx->handle, tctx->octx);
- if (ret != EOK) {
- tctx->error = ret;
-
- /* cancel transaction */
- talloc_zfree(tctx->handle);
- goto done;
- }
-
- end_transaction(tctx);
-
-done:
- if (tctx->error) {
- ret = tctx->error;
- switch (ret) {
- case ENOENT:
- ERROR("Could not modify user - check if group names are correct\n");
- break;
-
- case EFAULT:
- ERROR("Could not modify user - user already member of groups?\n");
- break;
-
- default:
- ERROR("Transaction error. Could not modify user.\n");
- break;
- }
-
- ret = EXIT_FAILURE;
- goto fini;
- }
-
- ret = EXIT_SUCCESS;
-
-fini:
- free(addgroups);
- free(rmgroups);
- poptFreeContext(pc);
- talloc_free(tctx);
- exit(ret);
-}
diff --git a/server/tools/tools_util.c b/server/tools/tools_util.c
deleted file mode 100644
index 97945238e..000000000
--- a/server/tools/tools_util.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- SSSD
-
- tools_utils.c
-
- Copyright (C) Jakub Hrozek <jhrozek@redhat.com> 2009
-
- 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 <talloc.h>
-#include <tevent.h>
-#include <popt.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-
-#include "config.h"
-#ifdef HAVE_SELINUX
-#include <selinux/selinux.h>
-#endif
-
-#include "util/util.h"
-#include "confdb/confdb.h"
-#include "db/sysdb.h"
-#include "tools/tools_util.h"
-#include "tools/sss_sync_ops.h"
-
-static int setup_db(struct tools_ctx *ctx)
-{
- char *confdb_path;
- int ret;
-
- /* Create the event context */
- ctx->ev = tevent_context_init(ctx);
- if (ctx->ev == NULL) {
- DEBUG(1, ("Could not create event context\n"));
- return EIO;
- }
-
- confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
- if (confdb_path == NULL) {
- return ENOMEM;
- }
-
- /* Connect to the conf db */
- ret = confdb_init(ctx, &ctx->confdb, confdb_path);
- if (ret != EOK) {
- DEBUG(1, ("Could not initialize connection to the confdb\n"));
- return ret;
- }
-
- ret = confdb_get_domain(ctx->confdb, "local", &ctx->local);
- if (ret != EOK) {
- DEBUG(1, ("Could not get 'local' domain: [%d] [%s]\n", ret, strerror(ret)));
- return ret;
- }
-
- /* open 'local' sysdb at default path */
- ret = sysdb_domain_init(ctx, ctx->ev, ctx->local, DB_PATH, &ctx->sysdb);
- if (ret != EOK) {
- DEBUG(1, ("Could not initialize connection to the sysdb\n"));
- return ret;
- }
-
- talloc_free(confdb_path);
- return EOK;
-}
-
-/*
- * Print poptUsage as well as our error message
- */
-void usage(poptContext pc, const char *error)
-{
- poptPrintUsage(pc, stderr, 0);
- if (error) fprintf(stderr, "%s", error);
-}
-
-int parse_groups(TALLOC_CTX *mem_ctx, const char *optstr, char ***_out)
-{
- char **out;
- char *orig, *n, *o;
- char delim = ',';
- unsigned int tokens = 1;
- int i;
-
- orig = talloc_strdup(mem_ctx, optstr);
- if (!orig) return ENOMEM;
-
- n = orig;
- tokens = 1;
- while ((n = strchr(n, delim))) {
- n++;
- tokens++;
- }
-
- out = talloc_array(mem_ctx, char *, tokens+1);
- if (!out) {
- talloc_free(orig);
- return ENOMEM;
- }
-
- n = o = orig;
- for (i = 0; i < tokens; i++) {
- o = n;
- n = strchr(n, delim);
- if (!n) {
- break;
- }
- *n = '\0';
- n++;
- out[i] = talloc_strdup(out, o);
- }
- out[tokens-1] = talloc_strdup(out, o);
- out[tokens] = NULL;
-
- talloc_free(orig);
- *_out = out;
- return EOK;
-}
-
-int parse_group_name_domain(struct tools_ctx *tctx,
- char **groups)
-{
- int i;
- int ret;
- char *name = NULL;
- char *domain = NULL;
-
- if (!groups) {
- return EOK;
- }
-
- for (i = 0; groups[i]; ++i) {
- ret = sss_parse_name(tctx, tctx->snctx, groups[i], &domain, &name);
-
- /* If FQDN is specified, it must be within the same domain as user */
- if (domain) {
- if (strcmp(domain, tctx->octx->domain->name) != 0) {
- return EINVAL;
- }
-
- /* Use only groupname */
- talloc_zfree(groups[i]);
- groups[i] = talloc_strdup(tctx, name);
- if (groups[i] == NULL) {
- return ENOMEM;
- }
- }
-
- talloc_zfree(name);
- talloc_zfree(domain);
- }
-
- talloc_zfree(name);
- talloc_zfree(domain);
- return EOK;
-}
-
-int parse_name_domain(struct tools_ctx *tctx,
- const char *fullname)
-{
- int ret;
- char *domain = NULL;
-
- ret = sss_parse_name(tctx, tctx->snctx, fullname, &domain, &tctx->octx->name);
- if (ret != EOK) {
- DEBUG(0, ("Cannot parse full name\n"));
- return ret;
- }
- DEBUG(5, ("Parsed username: %s\n", tctx->octx->name));
-
- if (domain) {
- DEBUG(5, ("Parsed domain: %s\n", domain));
- /* only the local domain, whatever named is allowed in tools */
- if (strcasecmp(domain, tctx->local->name) != 0) {
- DEBUG(1, ("Invalid domain %s specified in FQDN\n", domain));
- return EINVAL;
- }
- }
-
- return EOK;
-}
-
-int check_group_names(struct tools_ctx *tctx,
- char **grouplist,
- char **badgroup)
-{
- int ret;
- int i;
- struct ops_ctx *groupinfo;
-
- groupinfo = talloc_zero(tctx, struct ops_ctx);
- if (!groupinfo) {
- return ENOMEM;
- }
-
- ret = EOK;
- for (i=0; grouplist[i]; ++i) {
- ret = sysdb_getgrnam_sync(tctx,
- tctx->ev,
- tctx->sysdb,
- grouplist[i],
- tctx->local,
- &groupinfo);
- if (ret) {
- DEBUG(6, ("Cannot find group %s, ret: %d\n", grouplist[i], ret));
- break;
- }
- }
-
- talloc_zfree(groupinfo);
- *badgroup = grouplist[i];
- return ret;
-}
-
-int id_in_range(uint32_t id,
- struct sss_domain_info *dom)
-{
- if (id &&
- ((id < dom->id_min) ||
- (dom->id_max && id > dom->id_max))) {
- return ERANGE;
- }
-
- return EOK;
-}
-
-int set_locale(void)
-{
- char *c;
-
- c = setlocale(LC_ALL, "");
- if (c == NULL) {
- return EIO;
- }
-
- errno = 0;
- c = bindtextdomain(PACKAGE, LOCALEDIR);
- if (c == NULL) {
- return errno;
- }
-
- errno = 0;
- c = textdomain(PACKAGE);
- if (c == NULL) {
- return errno;
- }
-
- return EOK;
-}
-
-int init_sss_tools(struct tools_ctx **_tctx)
-{
- int ret;
- struct tools_ctx *tctx;
-
- tctx = talloc_zero(NULL, struct tools_ctx);
- if (tctx == NULL) {
- DEBUG(1, ("Could not allocate memory for tools context\n"));
- return ENOMEM;
- }
-
- /* Connect to the database */
- ret = setup_db(tctx);
- if (ret != EOK) {
- DEBUG(1, ("Could not set up database\n"));
- goto fini;
- }
-
- ret = sss_names_init(tctx, tctx->confdb, &tctx->snctx);
- if (ret != EOK) {
- DEBUG(1, ("Could not set up parsing\n"));
- goto fini;
- }
-
- tctx->octx = talloc_zero(tctx, struct ops_ctx);
- if (!tctx->octx) {
- DEBUG(1, ("Could not allocate memory for data context\n"));
- ERROR("Out of memory\n");
- ret = ENOMEM;
- goto fini;
- }
- tctx->octx->domain = tctx->local;
-
- *_tctx = tctx;
- ret = EOK;
-
-fini:
- if (ret != EOK) talloc_free(tctx);
- return ret;
-}
-
-/*
- * Check is path is owned by uid
- * returns 0 - owns
- * -1 - does not own
- * >0 - an error occured, error code
- */
-static int is_owner(uid_t uid, const char *path)
-{
- struct stat statres;
- int ret;
-
- ret = stat(path, &statres);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot stat %s: [%d][%s]\n", path, ret, strerror(ret)));
- return ret;
- }
-
- if (statres.st_uid == uid) {
- return EOK;
- }
- return -1;
-}
-
-static int remove_mail_spool(TALLOC_CTX *mem_ctx,
- const char *maildir,
- const char *username,
- uid_t uid,
- bool force)
-{
- int ret;
- char *spool_file;
-
- spool_file = talloc_asprintf(mem_ctx, "%s/%s", maildir, username);
- if (spool_file == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- if (force == false) {
- /* Check the owner of the mail spool */
- ret = is_owner(uid, spool_file);
- switch (ret) {
- case 0:
- break;
- case -1:
- DEBUG(3, ("%s not owned by %d, not removing\n",
- spool_file, uid));
- ret = EACCES;
- /* FALLTHROUGH */
- default:
- goto fail;
- }
- }
-
- ret = unlink(spool_file);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot remove() the spool file %s: [%d][%s]\n",
- spool_file, ret, strerror(ret)));
- goto fail;
- }
-
-fail:
- talloc_free(spool_file);
- return ret;
-}
-
-int remove_homedir(TALLOC_CTX *mem_ctx,
- const char *homedir,
- const char *maildir,
- const char *username,
- uid_t uid, bool force)
-{
- int ret;
-
- ret = remove_mail_spool(mem_ctx, maildir, username, uid, force);
- if (ret != EOK) {
- DEBUG(1, ("Cannot remove user's mail spool\n"));
- /* Should this be fatal? I don't think so. Maybe convert to ERROR? */
- }
-
- if (force == false && is_owner(uid, homedir) == -1) {
- DEBUG(1, ("Not removing home dir - not owned by user\n"));
- return EPERM;
- }
-
- /* Remove the tree */
- ret = remove_tree(homedir);
- if (ret != EOK) {
- DEBUG(1, ("Cannot remove homedir %s: %d\n",
- homedir, ret));
- return ret;
- }
-
- return EOK;
-}
-
-/* The reason for not putting this into create_homedir
- * is better granularity when it comes to reporting error
- * messages and tracebacks in pysss
- */
-int create_mail_spool(TALLOC_CTX *mem_ctx,
- const char *username,
- const char *maildir,
- uid_t uid, gid_t gid)
-{
- char *spool_file = NULL;
- int fd;
- int ret;
-
- spool_file = talloc_asprintf(mem_ctx, "%s/%s", maildir, username);
- if (spool_file == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- selinux_file_context(spool_file);
-
- fd = open(spool_file, O_CREAT | O_WRONLY | O_EXCL, 0);
- if (fd < 0) {
- ret = errno;
- DEBUG(1, ("Cannot open() the spool file: [%d][%s]\n",
- ret, strerror(ret)));
- goto fail;
- }
-
- ret = fchmod(fd, 0600);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot fchmod() the spool file: [%d][%s]\n",
- ret, strerror(ret)));
- goto fail;
- }
-
- ret = fchown(fd, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot fchown() the spool file: [%d][%s]\n",
- ret, strerror(ret)));
- goto fail;
- }
-
- ret = fsync(fd);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot fsync() the spool file: [%d][%s]\n",
- ret, strerror(ret)));
- goto fail;
- }
-
- ret = close(fd);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot close() the spool file: [%d][%s]\n",
- ret, strerror(ret)));
- goto fail;
- }
-
-fail:
- reset_selinux_file_context();
- talloc_free(spool_file);
- return ret;
-}
-
-int create_homedir(TALLOC_CTX *mem_ctx,
- const char *skeldir,
- const char *homedir,
- const char *username,
- uid_t uid,
- gid_t gid,
- mode_t default_umask)
-{
- int ret;
-
- selinux_file_context(homedir);
-
- ret = mkdir(homedir, 0);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot create user's home directory: [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- ret = chown(homedir, uid, gid);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot chown user's home directory: [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- ret = chmod(homedir, 0777 & ~default_umask);
- if (ret != 0) {
- ret = errno;
- DEBUG(1, ("Cannot chmod user's home directory: [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
- reset_selinux_file_context();
-
- ret = copy_tree(skeldir, homedir, uid, gid);
- if (ret != EOK) {
- DEBUG(1, ("Cannot populate user's home directory: [%d][%s].\n",
- ret, strerror(ret)));
- goto done;
- }
-
-done:
- reset_selinux_file_context();
- return ret;
-}
-
diff --git a/server/tools/tools_util.h b/server/tools/tools_util.h
deleted file mode 100644
index a643e739f..000000000
--- a/server/tools/tools_util.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
- Simo Sorce <ssorce@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/>.
-*/
-
-
-#ifndef __TOOLS_UTIL_H__
-#define __TOOLS_UTIL_H__
-
-#include <popt.h>
-
-#include "util/util.h"
-
-#define CHECK_ROOT(val, prg_name) do { \
- val = getuid(); \
- if (val != 0) { \
- DEBUG(1, ("Running under %d, must be root\n", val)); \
- ERROR("%s must be run as root\n", prg_name); \
- val = EXIT_FAILURE; \
- goto fini; \
- } \
-} while(0)
-
-struct tools_ctx {
- struct tevent_context *ev;
- struct confdb_ctx *confdb;
- struct sysdb_ctx *sysdb;
-
- struct sss_names_ctx *snctx;
- struct sss_domain_info *local;
-
- struct ops_ctx *octx;
-
- struct sysdb_handle *handle;
- bool transaction_done;
- int error;
-};
-
-int init_sss_tools(struct tools_ctx **_tctx);
-
-void usage(poptContext pc, const char *error);
-
-int set_locale(void);
-
-
-int parse_name_domain(struct tools_ctx *tctx,
- const char *fullname);
-
-int id_in_range(uint32_t id,
- struct sss_domain_info *dom);
-
-int parse_groups(TALLOC_CTX *mem_ctx,
- const char *optstr,
- char ***_out);
-
-int parse_group_name_domain(struct tools_ctx *tctx,
- char **groups);
-
-int check_group_names(struct tools_ctx *tctx,
- char **grouplist,
- char **badgroup);
-
-int create_homedir(TALLOC_CTX *mem_ctx,
- const char *skeldir,
- const char *homedir,
- const char *username,
- uid_t uid,
- gid_t gid,
- mode_t default_umask);
-
-int create_mail_spool(TALLOC_CTX *mem_ctx,
- const char *username,
- const char *maildir,
- uid_t uid, gid_t gid);
-
-int remove_homedir(TALLOC_CTX *mem_ctx,
- const char *homedir,
- const char *maildir,
- const char *username,
- uid_t uid, bool force);
-
-/* from files.c */
-int remove_tree(const char *root);
-
-int copy_tree(const char *src_root,
- const char *dst_root,
- uid_t uid, gid_t gid);
-
-int selinux_file_context(const char *dst_name);
-int reset_selinux_file_context(void);
-
-#endif /* __TOOLS_UTIL_H__ */