summaryrefslogtreecommitdiff
path: root/server/tools
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2009-10-05 19:45:03 +0200
committerStephen Gallagher <sgallagh@redhat.com>2009-10-22 14:04:28 -0400
commitf3bc40136878ab91cb98f1b206ff9517000112f7 (patch)
tree2cae1ff9ad9b537c93e6ffaef51b3f69f16862ca /server/tools
parentf2119734c75b71577eba4a17ea3a84a5d89493e8 (diff)
downloadsssd-f3bc40136878ab91cb98f1b206ff9517000112f7.tar.gz
sssd-f3bc40136878ab91cb98f1b206ff9517000112f7.tar.bz2
sssd-f3bc40136878ab91cb98f1b206ff9517000112f7.zip
User home directories management
Create and populate user directories on useradd, delete them on userdel Fixes: #212
Diffstat (limited to 'server/tools')
-rw-r--r--server/tools/sss_sync_ops.c126
-rw-r--r--server/tools/sss_sync_ops.h23
-rw-r--r--server/tools/sss_useradd.c81
-rw-r--r--server/tools/sss_userdel.c70
-rw-r--r--server/tools/tools_util.c223
-rw-r--r--server/tools/tools_util.h19
6 files changed, 505 insertions, 37 deletions
diff --git a/server/tools/sss_sync_ops.c b/server/tools/sss_sync_ops.c
index 932a7122..2bea4f07 100644
--- a/server/tools/sss_sync_ops.c
+++ b/server/tools/sss_sync_ops.c
@@ -20,6 +20,7 @@
#include <tevent.h>
#include <talloc.h>
+#include <sys/types.h>
#include "util/util.h"
#include "db/sysdb.h"
@@ -28,6 +29,12 @@
/* 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)) { \
@@ -1111,6 +1118,47 @@ 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
*/
@@ -1119,11 +1167,12 @@ int useradd_defaults(TALLOC_CTX *mem_ctx,
struct ops_ctx *data,
const char *gecos,
const char *homedir,
- const char *shell)
+ const char *shell,
+ int create_home,
+ const char *skeldir)
{
int ret;
char *basedir = NULL;
- char *dfl_shell = NULL;
char *conf_path = NULL;
conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name);
@@ -1131,18 +1180,17 @@ int useradd_defaults(TALLOC_CTX *mem_ctx,
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);
- if (data->home == NULL) {
- ret = ENOMEM;
- goto done;
- }
} else {
ret = confdb_get_string(confdb, mem_ctx,
conf_path, CONFDB_LOCAL_DEFAULT_BASEDIR,
@@ -1151,34 +1199,80 @@ int useradd_defaults(TALLOC_CTX *mem_ctx,
goto done;
}
data->home = talloc_asprintf(mem_ctx, "%s/%s", basedir, data->name);
- if (!data->home) {
- ret = ENOMEM;
- goto done;
- }
}
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, &dfl_shell);
+ DFL_SHELL_VAL, &data->shell);
if (ret != EOK) {
goto done;
}
- shell = dfl_shell;
+ } else {
+ data->shell = talloc_strdup(mem_ctx, shell);
+ if (!data->shell) {
+ ret = ENOMEM;
+ goto done;
+ }
}
- data->shell = talloc_strdup(mem_ctx, shell);
- if (!data->shell) {
- ret = ENOMEM;
+ 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(dfl_shell);
talloc_free(basedir);
talloc_free(conf_path);
return ret;
diff --git a/server/tools/sss_sync_ops.h b/server/tools/sss_sync_ops.h
index 3988992e..383319a8 100644
--- a/server/tools/sss_sync_ops.h
+++ b/server/tools/sss_sync_ops.h
@@ -27,6 +27,13 @@
#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;
@@ -38,6 +45,12 @@ struct ops_ctx {
char *shell;
int lock;
+ bool create_homedir;
+ bool remove_homedir;
+ mode_t umask;
+ char *skeldir;
+ char *maildir;
+
char **addgroups;
char **rmgroups;
};
@@ -48,7 +61,15 @@ int useradd_defaults(TALLOC_CTX *mem_ctx,
struct ops_ctx *data,
const char *gecos,
const char *homedir,
- const char *shell);
+ 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,
diff --git a/server/tools/sss_useradd.c b/server/tools/sss_useradd.c
index d05f5ae9..94de68fd 100644
--- a/server/tools/sss_useradd.c
+++ b/server/tools/sss_useradd.c
@@ -32,15 +32,6 @@
#include "tools/tools_util.h"
#include "tools/sss_sync_ops.h"
-/* Default settings for user attributes */
-#define CONFDB_DFL_SECTION "config/user_defaults"
-
-#define DFL_SHELL_ATTR "defaultShell"
-#define DFL_BASEDIR_ATTR "baseDirectory"
-
-#define DFL_SHELL_VAL "/bin/bash"
-#define DFL_BASEDIR_VAL "/home"
-
static void get_gid_callback(void *ptr, int error, struct ldb_result *res)
{
struct tools_ctx *tctx = talloc_get_type(ptr, struct tools_ctx);
@@ -115,7 +106,9 @@ int main(int argc, const char **argv)
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 },
@@ -125,6 +118,9 @@ int main(int argc, const char **argv)
{ "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;
@@ -147,12 +143,18 @@ int main(int argc, const char **argv)
pc = poptGetContext(NULL, argc, argv, long_options, 0);
poptSetOtherOptionHelp(pc, "USERNAME");
while ((ret = poptGetNextOpt(pc)) > 0) {
- if (ret == 'G') {
- groups = poptGetOptArg(pc);
- if (!groups) {
- ret = -1;
+ 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;
- }
}
}
@@ -232,7 +234,8 @@ int main(int argc, const char **argv)
* 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_gecos, pc_home, pc_shell,
+ pc_create_home, pc_skeldir);
if (ret != EOK) {
ERROR("Cannot set default values\n");
ret = EXIT_FAILURE;
@@ -263,6 +266,54 @@ int main(int argc, const char **argv)
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) {
diff --git a/server/tools/sss_userdel.c b/server/tools/sss_userdel.c
index d14ef3da..d4088cb5 100644
--- a/server/tools/sss_userdel.c
+++ b/server/tools/sss_userdel.c
@@ -36,11 +36,16 @@ int main(int argc, const char **argv)
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
};
@@ -57,14 +62,30 @@ int main(int argc, const char **argv)
/* parse parameters */
pc = poptGetContext(NULL, argc, argv, long_options, 0);
poptSetOtherOptionHelp(pc, "USERNAME");
- if ((ret = poptGetNextOpt(pc)) < -1) {
+ 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;
}
- debug_level = pc_debug;
-
pc_username = poptGetArg(pc);
if (pc_username == NULL) {
usage(pc, _("Specify user to delete\n"));
@@ -90,6 +111,29 @@ int main(int argc, const char **argv)
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;
+ }
+
+ if (tctx->octx->remove_homedir) {
+ 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;
+ }
+ }
+
start_transaction(tctx);
if (tctx->error != EOK) {
goto done;
@@ -107,9 +151,25 @@ int main(int argc, const char **argv)
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 (tctx->error) {
- ret = tctx->error;
+ if (ret) {
DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
switch (ret) {
case ENOENT:
diff --git a/server/tools/tools_util.c b/server/tools/tools_util.c
index 17cc3aa7..bcb8d5c1 100644
--- a/server/tools/tools_util.c
+++ b/server/tools/tools_util.c
@@ -23,6 +23,14 @@
#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"
@@ -294,3 +302,218 @@ fini:
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
index 92fba20d..2a1ee25e 100644
--- a/server/tools/tools_util.h
+++ b/server/tools/tools_util.h
@@ -76,4 +76,23 @@ 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);
+
#endif /* __TOOLS_UTIL_H__ */