data_extract_all: do not chmod symlink. Closes 2053
authorDenys Vlasenko <vda.linux@googlemail.com>
Fri, 18 Jun 2010 00:00:55 +0000 (02:00 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Fri, 18 Jun 2010 00:00:55 +0000 (02:00 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
archival/libunarchive/data_extract_all.c
testsuite/cpio.tests

index 8152610367928f5d4a69ac51c1f687716e212fdc..c4ffe7ef818e31416734df6e552fa856b447f337 100644 (file)
@@ -152,35 +152,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
                bb_error_msg_and_die("unrecognized file type");
        }
 
-       if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) {
-#if ENABLE_FEATURE_TAR_UNAME_GNAME
-               if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) {
+       if (!S_ISLNK(file_header->mode)) {
+               if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) {
                        uid_t uid = file_header->uid;
                        gid_t gid = file_header->gid;
-
-                       if (file_header->tar__uname) {
+#if ENABLE_FEATURE_TAR_UNAME_GNAME
+                       if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) {
+                               if (file_header->tar__uname) {
 //TODO: cache last name/id pair?
-                               struct passwd *pwd = getpwnam(file_header->tar__uname);
-                               if (pwd) uid = pwd->pw_uid;
-                       }
-                       if (file_header->tar__gname) {
-                               struct group *grp = getgrnam(file_header->tar__gname);
-                               if (grp) gid = grp->gr_gid;
+                                       struct passwd *pwd = getpwnam(file_header->tar__uname);
+                                       if (pwd) uid = pwd->pw_uid;
+                               }
+                               if (file_header->tar__gname) {
+                                       struct group *grp = getgrnam(file_header->tar__gname);
+                                       if (grp) gid = grp->gr_gid;
+                               }
                        }
+#endif
                        /* GNU tar 1.15.1 uses chown, not lchown */
                        chown(file_header->name, uid, gid);
-               } else
-#endif
-                       chown(file_header->name, file_header->uid, file_header->gid);
-       }
-       if (!S_ISLNK(file_header->mode)) {
+               }
                /* uclibc has no lchmod, glibc is even stranger -
                 * it has lchmod which seems to do nothing!
                 * so we use chmod... */
                if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
                        chmod(file_header->name, file_header->mode);
                }
-               /* same for utime */
                if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
                        struct timeval t[2];
 
index 725e70eab0f8211a83a587cc8014303aacd9e10c..42e3ff8dc03444dec758e8bc411591d4e59c6cc1 100755 (executable)
@@ -40,8 +40,7 @@ ls -ln cpio.testdir | $FILTER_LS" \
 0
 -rw-r--r-- 2 $user $group 0 x
 -rw-r--r-- 2 $user $group 0 y
-" \
-       "" ""
+" "" ""
 SKIP=
 
 
@@ -56,8 +55,7 @@ cpio.testdir/x
 cpio.testdir/y
 1 blocks
 0
-" \
-       "" ""
+" "" ""
 }
 
 
@@ -83,11 +81,9 @@ ls -ln cpio.testdir2/cpio.testdir | $FILTER_LS" \
 -rw-r--r-- 2 $user $group 2 nonempty
 -rw-r--r-- 2 $user $group 2 nonempty1
 -rw-r--r-- 1 $user $group 0 solo
-" \
-       "" ""
+" "" ""
 SKIP=
 
-
 # Was trying to create "/usr/bin", correct is "usr/bin".
 rm -rf cpio.testdir
 optional FEATURE_CPIO_P
@@ -98,8 +94,24 @@ ls cpio.testdir" \
 1 blocks
 0
 usr
-" \
-       "" ""
+" "" ""
+SKIP=
+
+# chown on a link was affecting file, dropping its sgid bits
+rm -rf cpio.testdir
+optional FEATURE_CPIO_O
+mkdir cpio.testdir
+touch cpio.testdir/file
+chmod 6755 cpio.testdir/file  # set the suid/sgid bit
+ln -sf file cpio.testdir/link
+testing "cpio restores sgid bits" \
+"cd cpio.testdir && { echo file; echo link; } | cpio -ovHnewc >pack.cpio && rm ???? && cpio -idmvu <pack.cpio 2>/dev/null;
+ stat -c '%a %n' file" \
+"\
+file
+link
+6755 file
+" "" ""
 SKIP=