[Pkg-sssd-devel] sssd: Changes to 'ubuntu'
Timo Aaltonen
tjaalton-guest at alioth.debian.org
Tue Feb 5 23:35:46 UTC 2013
Makefile.am | 32
configure.ac | 4
debian/changelog | 106
debian/patches/fix-cve-2013-0219-1.diff | 170
debian/patches/fix-cve-2013-0219-2.diff | 967 ---
debian/patches/fix-cve-2013-0220.diff | 63
debian/patches/series | 4
debian/rules | 3
po/LINGUAS | 2
po/bg.po | 138
po/de.po | 138
po/es.po | 138
po/eu.po | 138
po/fr.po | 138
po/hu.po | 138
po/id.po | 138
po/it.po | 138
po/ja.po | 138
po/nb.po | 138
po/nl.po | 138
po/pl.po | 138
po/pt.po | 138
po/ru.po | 138
po/sssd.pot | 138
po/sv.po | 138
po/tg.po | 138
po/tr.po | 138
po/uk.po | 138
po/zh_CN.po | 1673 +++++
po/zh_TW.po | 138
src/confdb/confdb.c | 11
src/db/sysdb.c | 1
src/db/sysdb.h | 9
src/db/sysdb_autofs.c | 118
src/db/sysdb_autofs.h | 14
src/db/sysdb_ops.c | 42
src/db/sysdb_selinux.c | 66
src/db/sysdb_selinux.h | 7
src/db/sysdb_sudo.c | 100
src/db/sysdb_sudo.h | 6
src/db/sysdb_upgrade.c | 47
src/ldb_modules/memberof.c | 41
src/lib/idmap/sss_idmap.c | 22
src/lib/idmap/sss_idmap.h | 17
src/man/include/failover.xml | 2
src/man/po/br.po | 356 -
src/man/po/ca.po | 370 -
src/man/po/cs.po | 356 -
src/man/po/es.po | 2779 +++++++--
src/man/po/eu.po | 356 -
src/man/po/fr.po | 655 +-
src/man/po/ja.po | 368 -
src/man/po/lv.po | 356 -
src/man/po/nl.po | 356 -
src/man/po/po4a.cfg | 2
src/man/po/pt.po | 356 -
src/man/po/ru.po | 356 -
src/man/po/sssd-docs.pot | 350 -
src/man/po/tg.po | 356 -
src/man/po/uk.po | 392 -
src/man/po/zh_CN.po | 8288 +++++++++++++++++++++++++++
src/man/sssd-ldap.5.xml | 2
src/man/sssd-sudo.5.xml | 4
src/man/sssd.conf.5.xml | 10
src/monitor/monitor.c | 10
src/monitor/monitor_interfaces.h | 1
src/providers/data_provider_be.c | 19
src/providers/data_provider_callbacks.c | 24
src/providers/data_provider_fo.c | 3
src/providers/dp_backend.h | 1
src/providers/fail_over.c | 9
src/providers/fail_over.h | 2
src/providers/ipa/ipa_config.c | 2
src/providers/ipa/ipa_config.h | 2
src/providers/ipa/ipa_opts.h | 1
src/providers/ipa/ipa_selinux.c | 659 +-
src/providers/krb5/krb5_auth.c | 7
src/providers/krb5/krb5_init.c | 4
src/providers/krb5/krb5_renew_tgt.c | 8
src/providers/ldap/ldap_auth.c | 15
src/providers/ldap/ldap_init.c | 6
src/providers/ldap/sdap.c | 31
src/providers/ldap/sdap.h | 2
src/providers/ldap/sdap_async_autofs.c | 274
src/providers/ldap/sdap_async_groups.c | 149
src/providers/ldap/sdap_async_initgroups.c | 17
src/providers/ldap/sdap_async_users.c | 7
src/providers/ldap/sdap_autofs.c | 8
src/providers/ldap/sdap_sudo.c | 259
src/providers/ldap/sdap_sudo.h | 10
src/providers/proxy/proxy_id.c | 50
src/resolv/async_resolv.c | 5
src/responder/autofs/autofs_private.h | 8
src/responder/autofs/autofssrv.c | 25
src/responder/autofs/autofssrv_cmd.c | 93
src/responder/common/responder_dp.c | 26
src/responder/common/responder_get_domains.c | 16
src/responder/common/responder_sbus.h | 43
src/responder/nss/nsssrv.c | 1
src/responder/nss/nsssrv.h | 3
src/responder/nss/nsssrv_cmd.c | 93
src/responder/nss/nsssrv_mmap_cache.c | 240
src/responder/nss/nsssrv_mmap_cache.h | 4
src/responder/pac/pacsrv.h | 22
src/responder/pac/pacsrv_cmd.c | 193
src/responder/pac/pacsrv_utils.c | 398 +
src/responder/pam/pamsrv.c | 9
src/responder/ssh/sshsrv.c | 1
src/responder/ssh/sshsrv_cmd.c | 13
src/responder/ssh/sshsrv_private.h | 3
src/responder/sudo/sudosrv.c | 1
src/responder/sudo/sudosrv_cmd.c | 2
src/responder/sudo/sudosrv_dp.c | 10
src/responder/sudo/sudosrv_get_sudorules.c | 14
src/responder/sudo/sudosrv_private.h | 10
src/responder/sudo/sudosrv_query.c | 6
src/sss_client/autofs/sss_autofs.c | 15
src/sss_client/nss_mc_common.c | 53
src/tests/files-tests.c | 6
src/tests/pac_responder-tests.c | 341 +
src/tests/sysdb_ssh-tests.c | 1
src/tools/files.c | 871 +-
src/tools/sss_cache.c | 163
src/tools/sss_groupdel.c | 14
src/tools/sss_groupmod.c | 21
src/tools/sss_userdel.c | 11
src/tools/sss_usermod.c | 21
src/tools/tools_mc_util.c | 325 +
src/tools/tools_util.c | 189
src/tools/tools_util.h | 11
src/util/debug.c | 13
src/util/mmap_cache.h | 15
src/util/sss_krb5.c | 44
version.m4 | 2
134 files changed, 20454 insertions(+), 6836 deletions(-)
New commits:
commit 2d085444ee5619154a81e8d7b89af4141e372fc5
Author: Timo Aaltonen <tjaalton at ubuntu.com>
Date: Wed Feb 6 00:55:49 2013 +0200
release to raring
diff --git a/debian/changelog b/debian/changelog
index 03c9126..909ac9c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-sssd (1.9.4-0ubuntu1) UNRELEASED; urgency=low
+sssd (1.9.4-0ubuntu1) raring; urgency=low
* Merge from unreleased debian git
- New upstream release
commit 7ad23fde406fe607b2d63c18feec4189a7042950
Author: Timo Aaltonen <tjaalton at ubuntu.com>
Date: Wed Feb 6 00:49:29 2013 +0200
patches: Remove CVE-fixes, included upstream.
diff --git a/debian/changelog b/debian/changelog
index 1855331..03c9126 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,7 @@ sssd (1.9.4-0ubuntu1) UNRELEASED; urgency=low
changes. (LP: #1086272)
- rules: Pass --datadir, so the path in autogenerated python files is
correctly substituted. (LP: #1079938)
+ * patches: Remove CVE-fixes, included upstream.
-- Timo Aaltonen <tjaalton at ubuntu.com> Wed, 06 Feb 2013 00:44:31 +0200
diff --git a/debian/patches/fix-cve-2013-0219-1.diff b/debian/patches/fix-cve-2013-0219-1.diff
deleted file mode 100644
index d45d033..0000000
--- a/debian/patches/fix-cve-2013-0219-1.diff
+++ /dev/null
@@ -1,170 +0,0 @@
-commit 020bf88fd1c5bdac8fc671b37c7118f5378c7047
-Author: Jakub Hrozek <jhrozek at redhat.com>
-Date: Wed Dec 12 19:02:33 2012 +0100
-
- TOOLS: Use openat/unlinkat when removing the homedir
-
- The removal of a home directory is sensitive to concurrent modification
- of the directory tree being removed and can unlink files outside the
- directory tree.
-
- This security issue was assigned CVE-2013-0219
-
- https://fedorahosted.org/sssd/ticket/1782
-
---- a/src/tools/files.c
-+++ b/src/tools/files.c
-@@ -78,8 +78,9 @@ struct copy_ctx {
- /* 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 parent_fd,
-+ const char *dir_name,
-+ dev_t parent_dev);
-
- int remove_tree(const char *root)
- {
-@@ -91,7 +92,7 @@ int remove_tree(const char *root)
- return ENOMEM;
- }
-
-- ret = remove_tree_with_ctx(tmp_ctx, 0, root);
-+ ret = remove_tree_with_ctx(tmp_ctx, AT_FDCWD, root, 0);
- talloc_free(tmp_ctx);
- return ret;
- }
-@@ -102,75 +103,75 @@ int remove_tree(const char *root)
- * reach the top level remove_tree() again
- */
- static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx,
-- dev_t parent_dev,
-- const char *root)
-+ int parent_fd,
-+ const char *dir_name,
-+ dev_t parent_dev)
- {
-- char *fullpath = NULL;
- struct dirent *result;
-- struct dirent direntp;
- struct stat statres;
- DIR *rootdir = NULL;
- int ret, err;
-+ int dir_fd;
-
-- rootdir = opendir(root);
-+ dir_fd = openat(parent_fd, dir_name,
-+ O_RDONLY | O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW);
-+ if (dir_fd == -1) {
-+ ret = errno;
-+ DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot open %s: [%d]: %s\n",
-+ dir_name, ret, strerror(ret)));
-+ return ret;
-+ }
-+
-+ rootdir = fdopendir(dir_fd);
- if (rootdir == NULL) {
- ret = errno;
-- DEBUG(1, ("Cannot open directory %s [%d][%s]\n",
-- root, ret, strerror(ret)));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("Cannot open directory: [%d][%s]\n", ret, strerror(ret)));
-+ close(dir_fd);
- 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) {
-+ while ((result = readdir(rootdir)) != NULL) {
-+ if (strcmp(result->d_name, ".") == 0 ||
-+ strcmp(result->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);
-+ ret = fstatat(dir_fd, result->d_name,
-+ &statres, AT_SYMLINK_NOFOLLOW);
- if (ret != 0) {
- ret = errno;
-- DEBUG(1, ("Cannot stat %s: [%d][%s]\n",
-- fullpath, ret, strerror(ret)));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("stat failed: [%d][%s]\n", 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));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("Directory %s is on different filesystem, "
-+ "will not follow\n"));
- ret = EFAULT;
- goto fail;
- }
-
-- ret = remove_tree_with_ctx(mem_ctx, statres.st_dev, fullpath);
-+ ret = remove_tree_with_ctx(mem_ctx, dir_fd, result->d_name, statres.st_dev);
- if (ret != EOK) {
-- DEBUG(1, ("Removing subdirectory %s failed: [%d][%s]\n",
-- fullpath, ret, strerror(ret)));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("Removing subdirectory failed: [%d][%s]\n",
-+ ret, strerror(ret)));
- goto fail;
- }
- } else {
-- ret = unlink(fullpath);
-+ ret = unlinkat(dir_fd, result->d_name, 0);
- if (ret != 0) {
- ret = errno;
-- DEBUG(1, ("Removing file %s failed: [%d][%s]\n",
-- fullpath, ret, strerror(ret)));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("Removing file failed: [%d][%s]\n", ret, strerror(ret)));
- goto fail;
- }
- }
--
-- talloc_free(fullpath);
- }
-
- ret = closedir(rootdir);
-@@ -180,19 +181,17 @@ static int remove_tree_with_ctx(TALLOC_C
- goto fail;
- }
-
-- ret = rmdir(root);
-- if (ret != 0) {
-+ ret = unlinkat(parent_fd, dir_name, AT_REMOVEDIR);
-+ if (ret == -1) {
- ret = errno;
-- goto fail;
- }
-
- ret = EOK;
--
- fail:
- if (rootdir) { /* clean up on abnormal exit but retain return code */
- err = closedir(rootdir);
- if (err) {
-- DEBUG(1, ("closedir failed, bad dirp?\n"));
-+ DEBUG(SSSDBG_CRIT_FAILURE, ("closedir failed, bad dirp?\n"));
- }
- }
- return ret;
diff --git a/debian/patches/fix-cve-2013-0219-2.diff b/debian/patches/fix-cve-2013-0219-2.diff
deleted file mode 100644
index 9e7cae1..0000000
--- a/debian/patches/fix-cve-2013-0219-2.diff
+++ /dev/null
@@ -1,967 +0,0 @@
-commit 94cbf1cfb0f88c967f1fb0a4cf23723148868e4a
-Author: Jakub Hrozek <jhrozek at redhat.com>
-Date: Sun Jan 20 20:27:05 2013 +0100
-
- TOOLS: Use file descriptor to avoid races when creating a home directory
-
- When creating a home directory, the destination tree can be modified in
- various ways while it is being constructed because directory permissions
- are set before populating the directory. This can lead to file creation
- and permission changes outside the target directory tree, using hard links.
-
- This security problem was assigned CVE-2013-0219
-
- https://fedorahosted.org/sssd/ticket/1782
-
---- a/src/tests/files-tests.c
-+++ b/src/tests/files-tests.c
-@@ -183,7 +183,7 @@ START_TEST(test_simple_copy)
-
- /* 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);
-+ ret = copy_tree(dir_path, dst_path, 0700, uid, gid);
- fail_unless(ret == EOK, "copy_tree failed\n");
-
- /* check if really copied */
-@@ -225,7 +225,7 @@ START_TEST(test_copy_symlink)
-
- /* 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);
-+ ret = copy_tree(dir_path, dst_path, 0700, uid, gid);
- fail_unless(ret == EOK, "copy_tree failed\n");
-
- /* check if really copied */
-@@ -264,7 +264,7 @@ START_TEST(test_copy_node)
-
- /* 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);
-+ ret = copy_tree(dir_path, dst_path, 0700, uid, gid);
- fail_unless(ret == EOK, "copy_tree failed\n");
-
- /* check if really copied */
---- a/src/tools/files.c
-+++ b/src/tools/files.c
-@@ -66,13 +66,12 @@
- #include "util/util.h"
- #include "tools/tools_util.h"
-
--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;
-+ uid_t uid;
-+ gid_t gid;
- };
-
- /* wrapper in order not to create a temporary context in
-@@ -197,66 +196,13 @@ 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)
-+static char *talloc_readlinkat(TALLOC_CTX *mem_ctx, int dir_fd,
-+ const char *filename)
- {
- size_t size = 1024;
- ssize_t nchars;
- char *buffer;
-+ char *new_buffer;
-
- buffer = talloc_array(mem_ctx, char, size);
- if (!buffer) {
-@@ -264,8 +210,9 @@ static char *talloc_readlink(TALLOC_CTX
- }
-
- while (1) {
-- nchars = readlink(filename, buffer, size);
-+ nchars = readlinkat(dir_fd, filename, buffer, size);
- if (nchars < 0) {
-+ talloc_free(buffer);
- return NULL;
- }
-
-@@ -276,10 +223,12 @@ static char *talloc_readlink(TALLOC_CTX
-
- /* Try again with a bigger buffer */
- size *= 2;
-- buffer = talloc_realloc(mem_ctx, buffer, char, size);
-- if (!buffer) {
-+ new_buffer = talloc_realloc(mem_ctx, buffer, char, size);
-+ if (!new_buffer) {
-+ talloc_free(buffer);
- return NULL;
- }
-+ buffer = new_buffer;
- }
-
- /* readlink does not nul-terminate */
-@@ -287,188 +236,174 @@ static char *talloc_readlink(TALLOC_CTX
- 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)
-+static int
-+copy_symlink(int src_dir_fd,
-+ int dst_dir_fd,
-+ const char *file_name,
-+ const char *full_path,
-+ const struct stat *statp,
-+ uid_t uid, gid_t gid)
- {
-- int ret;
-- char *oldlink;
-- char *tmp;
-- TALLOC_CTX *tmp_ctx = NULL;
-+ char *buf;
-+ errno_t ret;
-+ struct timespec timebuf[2];
-
-- tmp_ctx = talloc_new(cctx);
-- if (!tmp_ctx) {
-+ buf = talloc_readlinkat(NULL, src_dir_fd, file_name);
-+ if (!buf) {
- 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;
-+ ret = selinux_file_context(full_path);
-+ if (ret != 0) {
-+ DEBUG(SSSDBG_MINOR_FAILURE,
-+ ("Failed to set SELinux context for [%s]\n", full_path));
-+ /* Not fatal */
- }
-
-- /* 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;
-+ ret = symlinkat(buf, dst_dir_fd, file_name);
-+ talloc_free(buf);
-+ if (ret == -1) {
-+ ret = errno;
-+ if (ret == EEXIST) {
-+ DEBUG(SSSDBG_MINOR_FAILURE,
-+ ("symlink pointing to already exists at '%s'\n", full_path));
-+ return EOK;
- }
-
-- talloc_free(oldlink);
-- oldlink = tmp;
-+ DEBUG(SSSDBG_CRIT_FAILURE, ("symlinkat failed: %s\n", strerror(ret)));
-+ return ret;
- }
-
-- selinux_file_context(dst);
--
-- ret = symlink(oldlink, dst);
-- if (ret != 0) {
-+ ret = fchownat(dst_dir_fd, file_name,
-+ uid, gid, AT_SYMLINK_NOFOLLOW);
-+ if (ret == -1) {
- ret = errno;
-- DEBUG(1, ("symlink() failed on file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto done;
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("fchownat failed: %s\n", strerror(ret)));
-+ return ret;
- }
-
-- ret = lchown(dst, uid, gid);
-- if (ret != 0) {
-+ timebuf[0] = statp->st_atim;
-+ timebuf[1] = statp->st_mtim;
-+ ret = utimensat(dst_dir_fd, file_name, timebuf,
-+ AT_SYMLINK_NOFOLLOW);
-+ if (ret == -1) {
- ret = errno;
-- DEBUG(1, ("lchown() failed on file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto done;
-+ DEBUG(SSSDBG_MINOR_FAILURE, ("utimensat failed [%d]: %s\n",
-+ ret, strerror(ret)));
-+ /* Do not fail */
- }
-
--done:
-- talloc_free(tmp_ctx);
-- return ret;
-+ return EOK;
- }
-
--static int copy_special(const char *dst,
-+/* Create a special file named file_name under a directory with file
-+ * descriptor dst_dir_fd. full_path is used for both setting SELinux
-+ * context and logging. The node is owned by uid/gid and its mode
-+ * and device number is read from statp.
-+ */
-+static int copy_special(int dst_dir_fd,
-+ const char *file_name,
-+ const char *full_path,
- const struct stat *statp,
-- const struct timeval mt[],
- uid_t uid, gid_t gid)
- {
-- int ret = 0;
-+ int ret;
-+ struct timespec timebuf[2];
-
-- selinux_file_context(dst);
-+ ret = selinux_file_context(full_path);
-+ if (ret != 0) {
-+ DEBUG(SSSDBG_MINOR_FAILURE,
-+ ("Failed to set SELinux context for [%s]\n", full_path));
-+ /* Not fatal */
-+ }
-
-- ret = mknod(dst, statp->st_mode & ~07777, statp->st_rdev);
-+ ret = mknodat(dst_dir_fd, file_name, 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)));
-+ DEBUG(SSSDBG_OP_FAILURE,
-+ ("Cannot mknod special file '%s': [%d][%s].\n",
-+ full_path, ret, strerror(ret)));
- return ret;
- }
-
-- ret = chown(dst, uid, gid);
-+ ret = fchownat(dst_dir_fd, file_name, uid, gid, 0);
- if (ret != 0) {
- ret = errno;
-- DEBUG(1, ("Cannot chown special file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("fchownat failed for '%s': [%d][%s]\n",
-+ full_path, ret, strerror(ret)));
- return ret;
- }
-
-- ret = chmod(dst, statp->st_mode & 07777);
-+ ret = fchmodat(dst_dir_fd, file_name, statp->st_mode & 07777, 0);
- if (ret != 0) {
- ret = errno;
-- DEBUG(1, ("Cannot chmod special file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("fchmodat failed for '%s': [%d][%s]\n",
-+ full_path, ret, strerror(ret)));
- return ret;
- }
-
-- ret = utimes(dst, mt);
-- if (ret != 0) {
-+ timebuf[0] = statp->st_atim;
-+ timebuf[1] = statp->st_mtim;
-+ ret = utimensat(dst_dir_fd, file_name, timebuf, 0);
-+ if (ret == -1) {
- ret = errno;
-- DEBUG(1, ("Cannot call utimes on special file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- return ret;
-+ DEBUG(SSSDBG_MINOR_FAILURE,
-+ ("utimensat failed for '%s': [%d][%s]\n",
-+ full_path, ret, strerror(ret)));
-+ /* Do not fail, this shouldn't be fatal */
- }
-
- 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)
-+/* Copy bytes from input file descriptor ifd into file named
-+ * dst_named under directory with dest_dir_fd. Own the new file
-+ * by uid/gid
-+ */
-+static int
-+copy_file(int ifd,
-+ int dest_dir_fd,
-+ const char *file_name,
-+ const char *full_path,
-+ const struct stat *statp,
-+ uid_t uid, gid_t gid)
- {
-- int ret;
-- int ifd = -1;
- int ofd = -1;
-+ errno_t ret;
- char buf[1024];
- ssize_t cnt, written;
-- 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);
-+ struct timespec timebuf[2];
-
-- 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);
-+ ret = selinux_file_context(full_path);
- if (ret != 0) {
-- ret = errno;
-- DEBUG(1, ("Cannot fchown() destination file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto fail;
-+ DEBUG(SSSDBG_MINOR_FAILURE,
-+ ("Failed to set SELinux context for [%s]\n", full_path));
-+ /* Not fatal */
- }
-
-- ret = fchmod(ofd, statp->st_mode & 07777);
-- if (ret != 0) {
-+ /* Start with absolutely restrictive permissions */
-+ ofd = openat(dest_dir_fd, file_name,
-+ O_EXCL | O_CREAT | O_WRONLY | O_NOFOLLOW,
-+ 0);
-+ if (ofd < 0 && errno != EEXIST) {
- ret = errno;
-- DEBUG(1, ("Cannot fchmod() destination file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto fail;
-+ DEBUG(SSSDBG_OP_FAILURE,
-+ ("Cannot open() destination file '%s': [%d][%s].\n",
-+ full_path, ret, strerror(ret)));
-+ goto done;
- }
-
- while ((cnt = sss_atomic_read_s(ifd, buf, sizeof(buf))) != 0) {
- if (cnt == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
-- ("Cannot read() from source file '%s': [%d][%s].\n",
-- src, ret, strerror(ret)));
-- goto fail;
-+ ("Cannot read() from source file: [%d][%s].\n",
-+ ret, strerror(ret)));
-+ goto done;
- }
-
- errno = 0;
-@@ -476,222 +411,324 @@ static int copy_file(const char *src,
- if (written == -1) {
- ret = errno;
- DEBUG(SSSDBG_CRIT_FAILURE,
-- ("Cannot write() to destination file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto fail;
-+ ("Cannot write() to destination file: [%d][%s].\n",
-+ ret, strerror(ret)));
-+ goto done;
- }
-
- if (written != cnt) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- ("Wrote %d bytes, expected %d\n", written, cnt));
-- goto fail;
-+ goto done;
- }
- }
-
-- ret = close(ifd);
-- ifd = -1;
-- if (ret != 0) {
-+ /* Set the ownership; permissions are still
-+ * restrictive. */
-+ ret = fchown(ofd, uid, gid);
-+ if (ret == -1 && errno != EPERM) {
- ret = errno;
-- DEBUG(1, ("Cannot close() source file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto fail;
-+ DEBUG(SSSDBG_OP_FAILURE,
-+ ("Error changing owner of '%s': %s\n",
-+ full_path, strerror(ret)));
-+ goto done;
- }
-
-- ret = close(ofd);
-- ifd = -1;
-- if (ret != 0) {
-+ /* Set the desired mode. */
-+ ret = fchmod(ofd, statp->st_mode);
-+ if (ret == -1) {
- ret = errno;
-- DEBUG(1, ("Cannot close() destination file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto fail;
-+ DEBUG(SSSDBG_OP_FAILURE, ("Error changing owner of '%s': %s\n",
-+ full_path, strerror(ret)));
-+ goto done;
- }
-
-- ret = utimes(dst, mt);
-- if (ret != 0) {
-+ timebuf[0] = statp->st_atim;
-+ timebuf[1] = statp->st_mtim;
-+ ret = futimens(ofd, timebuf);
-+ if (ret == -1) {
- ret = errno;
-- DEBUG(1, ("Cannot call utimes() on destination file '%s': [%d][%s].\n",
-- dst, ret, strerror(ret)));
-- goto fail;
-+ DEBUG(SSSDBG_MINOR_FAILURE, ("futimens failed [%d]: %s\n",
-+ ret, strerror(ret)));
-+ /* Do not fail */
- }
-
-- return EOK;
-+ close(ofd);
-+ ofd = -1;
-+ ret = EOK;
-
-- /* Reachable by jump only */
--fail:
-- if (ifd != -1) close(ifd);
-+done:
- 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)
-+static errno_t
-+copy_dir(struct copy_ctx *cctx,
-+ int src_dir_fd, const char *src_dir_path,
-+ int dest_parent_fd, const char *dest_dir_name,
-+ const char *dest_dir_path,
-+ mode_t mode,
-+ const struct stat *src_dir_stat);
-+
-+static errno_t
-+copy_entry(struct copy_ctx *cctx,
-+ int src_dir_fd,
-+ const char *src_dir_path,
-+ int dest_dir_fd,
-+ const char *dest_dir_path,
-+ const char *ent_name)
- {
-- int ret = EOK;
-- struct stat sb;
-- struct timeval mt[2];
-+ char *src_ent_path = NULL;
-+ char *dest_ent_path = NULL;
-+ int ifd = -1;
-+ errno_t ret;
-+ struct stat st;
-
-- 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;
-+ /* Build the path of the source file or directory and its
-+ * corresponding member in the new tree. */
-+ src_ent_path = talloc_asprintf(cctx, "%s/%s", src_dir_path, ent_name);
-+ dest_ent_path = talloc_asprintf(cctx, "%s/%s", dest_dir_path, ent_name);
-+ if (!src_ent_path || !dest_ent_path) {
-+ ret = ENOMEM;
-+ goto done;
- }
-
-- mt[0].tv_sec = sb.st_atime;
-- mt[0].tv_usec = 0;
--
-- mt[1].tv_sec = sb.st_mtime;
-- mt[1].tv_usec = 0;
-+ /* Open the input entry first, then we can fstat() it and be
-+ * certain that it is still the same file. O_NONBLOCK protects
-+ * us against FIFOs and perhaps side-effects of the open() of a
-+ * device file if there ever was one here, and doesn't matter
-+ * for regular files or directories. */
-+ ifd = openat(src_dir_fd, ent_name,
-+ O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK);
-+ if (ifd == -1 && errno != ELOOP) {
-+ /* openat error */
-+ ret = errno;
-+ DEBUG(SSSDBG_CRIT_FAILURE, ("openat failed on '%s': %s\n",
-+ src_ent_path, strerror(ret)));
-+ goto done;
-+ } else if (ifd == -1 && errno == ELOOP) {
-+ /* Should be a symlink.. */
-+ ret = fstatat(src_dir_fd, ent_name, &st, AT_SYMLINK_NOFOLLOW);
-+ if (ret == -1) {
-+ ret = errno;
-+ DEBUG(SSSDBG_CRIT_FAILURE, ("fstatat failed on '%s': %s\n",
-+ src_ent_path, strerror(ret)));
-+ goto done;
-+ }
-
-- if (S_ISLNK (sb.st_mode)) {
-- ret = copy_symlink(cctx, src, dst, &sb, mt, uid, gid);
-+ /* Handle symlinks */
-+ ret = copy_symlink(src_dir_fd, dest_dir_fd, ent_name,
-+ dest_ent_path, &st, cctx->uid, cctx->gid);
- if (ret != EOK) {
-- DEBUG(1, ("Cannot copy symlink '%s' to '%s': [%d][%s]\n",
-- src, dst, ret, strerror(ret)));
-+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot copy '%s' to '%s'\n",
-+ src_ent_path, dest_ent_path));
- }
-- return ret;
-+ goto done;
- }
-
-- 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;
-+ ret = fstat(ifd, &st);
-+ if (ret != 0) {
-+ ret = errno;
-+ DEBUG(SSSDBG_CRIT_FAILURE,
-+ ("couldn't stat '%s': %s", src_ent_path, strerror(ret)));
-+ goto done;
-+ }
-+
-+ if (S_ISDIR(st.st_mode)) {
-+ /* If it's a directory, descend into it. */
-+ ret = copy_dir(cctx, ifd, src_ent_path,
-+ dest_dir_fd, ent_name,
More information about the Pkg-sssd-devel
mailing list