summaryrefslogtreecommitdiffstats
path: root/server/tests
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/tests
parentf2119734c75b71577eba4a17ea3a84a5d89493e8 (diff)
downloadsssd-f3bc40136878ab91cb98f1b206ff9517000112f7.tar.gz
sssd-f3bc40136878ab91cb98f1b206ff9517000112f7.tar.xz
sssd-f3bc40136878ab91cb98f1b206ff9517000112f7.zip
User home directories management
Create and populate user directories on useradd, delete them on userdel Fixes: #212
Diffstat (limited to 'server/tests')
-rw-r--r--server/tests/files-tests.c321
-rw-r--r--server/tests/python-test.py66
2 files changed, 381 insertions, 6 deletions
diff --git a/server/tests/files-tests.c b/server/tests/files-tests.c
new file mode 100644
index 000000000..206879f27
--- /dev/null
+++ b/server/tests/files-tests.c
@@ -0,0 +1,321 @@
+/*
+ * Authors:
+ * Jakub Hrozek <jhrozek@redhat.com>
+ *
+ * Copyright (C) 2008 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * 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; version 3 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdlib.h>
+#include <check.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <talloc.h>
+#include <popt.h>
+
+#include "config.h"
+#include "util/util.h"
+
+static char tpl_dir[] = "file-tests-dir-XXXXXX";
+static char *dir_path;
+static char *dst_path;
+static uid_t uid;
+static gid_t gid;
+static TALLOC_CTX *test_ctx = NULL;
+
+static void setup_files_test(void)
+{
+ /* create a temporary directory that we fill with stuff later on */
+ test_ctx = talloc_new(NULL);
+ dir_path = mkdtemp(talloc_strdup(test_ctx, tpl_dir));
+ dst_path = mkdtemp(talloc_strdup(test_ctx, tpl_dir));
+
+ uid = getuid();
+ gid = getgid();
+}
+
+static void teardown_files_test(void)
+{
+ char *cmd = NULL;
+
+ /* OK this is crude but since the functions to remove tree are under test.. */
+ if (dir_path && test_ctx) {
+ cmd = talloc_asprintf(test_ctx, "/bin/rm -rf %s\n", dir_path);
+ system(cmd);
+ }
+ if (dst_path && test_ctx) {
+ cmd = talloc_asprintf(test_ctx, "/bin/rm -rf %s\n", dst_path);
+ system(cmd);
+ }
+
+ /* clean up */
+ talloc_zfree(test_ctx);
+}
+
+static int create_simple_file(const char *name, const char *content)
+{
+ int fd;
+ ssize_t size;
+ int ret;
+
+ fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0700);
+ fail_if(fd == -1, "Cannot create simple file\n");
+
+ size = write(fd, "abc", 3);
+ fail_if(size == -1, "Cannot write to file\n");
+
+ ret = fsync(fd);
+ fail_if(ret == -1, "Cannot sync file\n");
+
+ ret = close(fd);
+ fail_if(ret == -1, "Cannot close file\n");
+
+ return ret;
+}
+
+START_TEST(test_remove_tree)
+{
+ int ret;
+ char origpath[PATH_MAX+1];
+
+ errno = 0;
+ getcwd(origpath, PATH_MAX);
+ fail_unless(errno == 0, "Cannot getcwd\n");
+
+ DEBUG(5, ("About to delete %s\n", dir_path));
+
+ /* create a file */
+ ret = chdir(dir_path);
+ fail_if(ret == -1, "Cannot chdir1\n");
+
+ ret = create_simple_file("bar", "bar");
+ fail_if(ret == -1, "Cannot create file1\n");
+
+ /* create a subdir and file inside it */
+ ret = mkdir("subdir", 0700);
+ fail_if(ret == -1, "Cannot create subdir\n");
+
+ ret = chdir("subdir");
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ ret = create_simple_file("foo", "foo");
+ fail_if(ret == -1, "Cannot create file\n");
+
+ /* create another subdir, empty this time */
+ ret = mkdir("subdir2", 0700);
+ fail_if(ret == -1, "Cannot create subdir\n");
+
+ ret = chdir(origpath);
+ fail_if(ret == -1, "Cannot chdir2\n");
+
+ /* go back */
+ ret = chdir(origpath);
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ /* and finally wipe it out.. */
+ ret = remove_tree(dir_path);
+ fail_unless(ret == EOK, "remove_tree failed\n");
+
+ /* check if really gone */
+ ret = access(dir_path, F_OK);
+ fail_unless(ret == -1, "directory still there after remove_tree\n");
+}
+END_TEST
+
+START_TEST(test_simple_copy)
+{
+ int ret;
+ char origpath[PATH_MAX+1];
+ char *tmp;
+ int fd = -1;
+
+ errno = 0;
+ getcwd(origpath, PATH_MAX);
+ fail_unless(errno == 0, "Cannot getcwd\n");
+
+ /* create a file */
+ ret = chdir(dir_path);
+ fail_if(ret == -1, "Cannot chdir1\n");
+
+ ret = create_simple_file("bar", "bar");
+ fail_if(ret == -1, "Cannot create file1\n");
+
+ /* create a subdir and file inside it */
+ ret = mkdir("subdir", 0700);
+ fail_if(ret == -1, "Cannot create subdir\n");
+
+ ret = chdir("subdir");
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ ret = create_simple_file("foo", "foo");
+ fail_if(ret == -1, "Cannot create file\n");
+
+ /* go back */
+ ret = chdir(origpath);
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ /* and finally copy.. */
+ DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));
+ ret = copy_tree(dir_path, dst_path, uid, gid);
+ fail_unless(ret == EOK, "copy_tree failed\n");
+
+ /* check if really copied */
+ ret = access(dst_path, F_OK);
+ fail_unless(ret == 0, "destination directory not there\n");
+
+ tmp = talloc_asprintf(test_ctx, "%s/bar", dst_path);
+ ret = check_and_open_readonly(tmp, &fd, uid, gid, 0700);
+ fail_unless(ret == EOK, "Cannot open %s\n");
+ close(fd);
+ talloc_free(tmp);
+}
+END_TEST
+
+START_TEST(test_copy_symlink)
+{
+ int ret;
+ char origpath[PATH_MAX+1];
+ char *tmp;
+ struct stat statbuf;
+
+ errno = 0;
+ getcwd(origpath, PATH_MAX);
+ fail_unless(errno == 0, "Cannot getcwd\n");
+
+ /* create a subdir */
+ ret = chdir(dir_path);
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ ret = create_simple_file("footarget", "foo");
+ fail_if(ret == -1, "Cannot create file\n");
+
+ ret = symlink("footarget", "foolink");
+ fail_if(ret == -1, "Cannot create symlink\n");
+
+ /* go back */
+ ret = chdir(origpath);
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ /* and finally copy.. */
+ DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));
+ ret = copy_tree(dir_path, dst_path, uid, gid);
+ fail_unless(ret == EOK, "copy_tree failed\n");
+
+ /* check if really copied */
+ ret = access(dst_path, F_OK);
+ fail_unless(ret == 0, "destination directory not there\n");
+
+ tmp = talloc_asprintf(test_ctx, "%s/foolink", dst_path);
+ ret = lstat(tmp, &statbuf);
+ fail_unless(ret == 0, "cannot stat the symlink %s\n", tmp);
+ fail_unless(S_ISLNK(statbuf.st_mode), "%s not a symlink?\n", tmp);
+ talloc_free(tmp);
+}
+END_TEST
+
+START_TEST(test_copy_node)
+{
+ int ret;
+ char origpath[PATH_MAX+1];
+ char *tmp;
+ struct stat statbuf;
+
+ errno = 0;
+ getcwd(origpath, PATH_MAX);
+ fail_unless(errno == 0, "Cannot getcwd\n");
+
+ /* create a node */
+ ret = chdir(dir_path);
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ ret = mknod("testnode", S_IFIFO | S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, 0);
+ fail_unless(ret == 0, "cannot stat /dev/null: %s", strerror(errno));
+
+ /* go back */
+ ret = chdir(origpath);
+ fail_if(ret == -1, "Cannot chdir\n");
+
+ /* and finally copy.. */
+ DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));
+ ret = copy_tree(dir_path, dst_path, uid, gid);
+ fail_unless(ret == EOK, "copy_tree failed\n");
+
+ /* check if really copied */
+ ret = access(dst_path, F_OK);
+ fail_unless(ret == 0, "destination directory not there\n");
+
+ tmp = talloc_asprintf(test_ctx, "%s/testnode", dst_path);
+ ret = lstat(tmp, &statbuf);
+ fail_unless(ret == 0, "cannot stat the node %s\n", tmp);
+ fail_unless(S_ISFIFO(statbuf.st_mode), "%s not a char device??\n", tmp);
+ talloc_free(tmp);
+}
+END_TEST
+
+static Suite *files_suite(void)
+{
+ Suite *s = suite_create("files_suite");
+
+ TCase *tc_files = tcase_create("files");
+ tcase_add_checked_fixture(tc_files,
+ setup_files_test,
+ teardown_files_test);
+
+ tcase_add_test(tc_files, test_remove_tree);
+ tcase_add_test(tc_files, test_simple_copy);
+ tcase_add_test(tc_files, test_copy_symlink);
+ tcase_add_test(tc_files, test_copy_node);
+ suite_add_tcase(s, tc_files);
+
+ return s;
+}
+
+int main(int argc, char *argv[])
+{
+ int number_failed;
+ int opt;
+ poptContext pc;
+ int debug = 0;
+
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL },
+ POPT_TABLEEND
+ };
+
+ pc = poptGetContext(argv[0], argc, (const char **) argv, long_options, 0);
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+ poptFreeContext(pc);
+ debug_level = debug;
+
+ Suite *s = files_suite();
+ SRunner *sr = srunner_create(s);
+ srunner_run_all(sr, CK_NORMAL);
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
diff --git a/server/tests/python-test.py b/server/tests/python-test.py
index fddf9c311..e1eaab2d1 100644
--- a/server/tests/python-test.py
+++ b/server/tests/python-test.py
@@ -20,6 +20,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+import os
+import tempfile
+import shutil
import unittest
import commands
import errno
@@ -120,9 +123,15 @@ class LocalTest(unittest.TestCase):
def add_user(self, username):
self._run_and_check("sss_useradd %s" % (username))
+ def add_user_not_home(self, username):
+ self._run_and_check("sss_useradd -M %s" % (username))
+
def remove_user(self, username):
self._run_and_check("sss_userdel %s" % (username))
+ def remove_user_not_home(self, username):
+ self._run_and_check("sss_userdel -R %s" % (username))
+
class SanityTest(unittest.TestCase):
def testInstantiate(self):
"Test that the local backed binding can be instantiated"
@@ -139,18 +148,51 @@ class UseraddTest(LocalTest):
self.username = "testUseradd"
self.local.useradd(self.username)
self.validate_user(self.username)
+ # check home directory was created with default name
+ self.assertEquals(os.access("/home/%s" % self.username, os.F_OK), True)
def testUseraddWithParams(self):
"Test adding a local user with modified parameters"
self.username = "testUseraddWithParams"
self.local.useradd(self.username,
gecos="foo bar",
- homedir="/people/foobar",
+ homedir="/home/foobar",
shell="/bin/zsh")
self.validate_user(self.username,
gecos="foo bar",
- homeDirectory="/people/foobar",
+ homeDirectory="/home/foobar",
loginShell="/bin/zsh")
+ # check home directory was created with nondefault name
+ self.assertEquals(os.access("/home/foobar", os.F_OK), True)
+
+ def testUseraddNoHomedir(self):
+ "Test adding a local user without creating his home dir"
+ self.username = "testUseraddNoHomedir"
+ self.local.useradd(self.username, create_home = False)
+ self.validate_user(self.username)
+ # check home directory was not created
+ self.assertEquals(os.access("/home/%s" % self.username, os.F_OK), False)
+ self.local.userdel(self.username, remove = False)
+ self.username = None # fool tearDown into not removing the user
+
+ def testUseraddAlternateSkeldir(self):
+ "Test adding a local user and init his homedir from a custom location"
+ self.username = "testUseraddAlternateSkeldir"
+
+ skeldir = tempfile.mkdtemp()
+ fd, path = tempfile.mkstemp(dir=skeldir)
+ fdo = os.fdopen(fd)
+ fdo.flush()
+ fdo.close
+ self.assertEquals(os.access(path, os.F_OK), True)
+ filename = os.path.basename(path)
+
+ try:
+ self.local.useradd(self.username, skel = skeldir)
+ self.validate_user(self.username)
+ self.assertEquals(os.access("/home/%s/%s"%(self.username,filename), os.F_OK), True)
+ finally:
+ shutil.rmtree(skeldir)
def testUseraddToGroups(self):
"Test adding a local user with group membership"
@@ -208,9 +250,21 @@ class UseraddTestNegative(LocalTest):
class UserdelTest(LocalTest):
def testUserdel(self):
self.add_user("testUserdel")
+ self.assertEquals(os.access("/home/testUserdel", os.F_OK), True)
self.validate_user("testUserdel")
self.local.userdel("testUserdel")
self.validate_no_user("testUserdel")
+ self.assertEquals(os.access("/home/testUserdel", os.F_OK), False)
+
+ def testUserdelNotHomedir(self):
+ self.add_user("testUserdel")
+ self.assertEquals(os.access("/home/testUserdel", os.F_OK), True)
+ self.validate_user("testUserdel")
+ self.local.userdel("testUserdel", remove=False)
+ self.validate_no_user("testUserdel")
+ self.assertEquals(os.access("/home/testUserdel", os.F_OK), True)
+ shutil.rmtree("/home/testUserdel")
+ os.remove("/var/mail/testUserdel")
def testUserdelNegative(self):
self.validate_no_user("testUserdelNegative")
@@ -225,20 +279,20 @@ class UsermodTest(LocalTest):
def setUp(self):
self.local = pysss.local()
self.username = "UsermodTest"
- self.add_user(self.username)
+ self.add_user_not_home(self.username)
def tearDown(self):
- self.remove_user(self.username)
+ self.remove_user_not_home(self.username)
def testUsermod(self):
"Test modifying user attributes"
self.local.usermod(self.username,
gecos="foo bar",
- homedir="/people/foobar",
+ homedir="/home/foobar",
shell="/bin/zsh")
self.validate_user(self.username,
gecos="foo bar",
- homeDirectory="/people/foobar",
+ homeDirectory="/home/foobar",
loginShell="/bin/zsh")
def testUsermodUID(self):