[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