]> err.no Git - dpkg/commitdiff
correct permission and owner/group handling when extracting
authorFrank Lichtenheld <djpig@debian.org>
Sat, 30 Jun 2007 23:35:58 +0000 (23:35 +0000)
committerFrank Lichtenheld <djpig@debian.org>
Sat, 30 Jun 2007 23:35:58 +0000 (23:35 +0000)
tar balls to match more the user's preferences instead of
ours or the ones from the originator of the tar ball. Patch
by Ian Jackson. Closes: #390915, #207289

ChangeLog
debian/changelog
scripts/dpkg-source.pl

index b42a8378f3c17a8c0ccfb3eaedbd4d8a9141a2b4..4ad24a8597832f5341f5301d5c5baf62869338a7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2007-07-01  Ian Jackson  <ian@davenant.greenend.org.uk>
+
+       * scripts/dpkg-source.pl: Don't remove setgid bits
+       on directories when extracting the .orig tarball
+       since the user might prefer to have them. Also don't
+       manually override user and group for extracted
+       directories. Instead we will take tar take of most
+       of that.
+       (extracttar): Explicetly specify --no-same-owner
+       and --no-same-permissions. They are default anyway
+       for non-root users, but no need to handle the source
+       differently (i.e. more carelessly) if working as root.
+       Since tar still insists on honoring the file permissions in the
+       tar ball, fix them up so that they match what the user would
+       expect according to his umask.
+
 2007-06-12  Jiří Paleček  <jpalecek@web.de>
 
        * dpkg-shlibdeps.pl: Support colon separated list of paths in the
index 50a9b56786bab764564114c196d023858e54b834..4982aaae823b8cdf25ea201be4fb13d244ce2f30 100644 (file)
@@ -25,6 +25,10 @@ dpkg (1.14.5) UNRELEASED; urgency=low
   [ Frank Lichtenheld ]
   * Fix typo in German translation of start-stop-daemon(8).
     Noted by Joachim Breitner. Closes: #430008
+  * Correct permission and owner/group handling when extracting
+    tar balls to match more the user's preferences instead of
+    ours or the ones from the originator of the tar ball. Patch
+    by Ian Jackson. Closes: #390915, #207289
   
   [ Updated dselect translations ]
   * French (Christian Perrier)
index bcd3e40059ee80d6ddcc8fd6d55f2b2f50b43922..6b40d086d624f7af802b6e821bdc98e273a4f0e7 100755 (executable)
@@ -817,10 +817,8 @@ if ($opmode eq 'build') {
        (my $t = $target) =~ s!.*/!!;
 
        mkdir($tmp,0700) || &syserr(sprintf(_g("unable to create `%s'"), $tmp));
-       system "chmod", "g-s", $tmp;
        printf(_g("%s: unpacking %s")."\n", $progname, $tarfile);
        extracttar("$dscdir/$tarfile",$tmp,$t);
-       system "chown", '-R', '-f', join(':', getfowner()), "$tmp/$t";
        rename("$tmp/$t",$target)
            || &syserr(sprintf(_g("unable to rename `%s' to `%s'"), "$tmp/$t", $target));
        rmdir($tmp)
@@ -1298,19 +1296,49 @@ sub checkdiff
 
 sub extracttar {
     my ($tarfileread,$dirchdir,$newtopdir) = @_;
+    my ($mode, $modes_set, $i, $j);
     &forkgzipread("$tarfileread");
     defined(my $c2 = fork) || syserr(_g("fork for tar -xkf -"));
     if (!$c2) {
         open(STDIN,"<&GZIP") || &syserr(_g("reopen gzip for tar -xkf -"));
         &cpiostderr;
         chdir($dirchdir) || &syserr(sprintf(_g("cannot chdir to `%s' for tar extract"), $dirchdir));
-        exec('tar','-xkf','-') or &syserr(_g("exec tar -xkf -"));
+       exec('tar','--no-same-owner','--no-same-permissions',
+            '-xkf','-') or &syserr(_g("exec tar -xkf -"));
     }
     close(GZIP);
     $c2 == waitpid($c2,0) || &syserr(_g("wait for tar -xkf -"));
     $? && subprocerr("tar -xkf -");
     &reapgzip;
 
+    # Unfortunately tar insists on applying our umask _to the original
+    # permissions_ rather than mostly-ignoring the original
+    # permissions.  We fix it up with chmod -R (which saves us some
+    # work) but we have to construct a u+/- string which is a bit
+    # of a palaver.  (Numeric doesn't work because we need [ugo]+X
+    # and [ugo]=<stuff> doesn't work because that unsets sgid on dirs.)
+    #
+    # We still need --no-same-permissions because otherwise tar might
+    # extract directory setgid (which we want inherited, not
+    # extracted); we need --no-same-owner because putting the owner
+    # back is tedious - in particular, correct group ownership would
+    # have to be calculated using mount options and other madness.
+    #
+    # It would be nice if tar could do it right, or if pax could cope
+    # with GNU format tarfiles with long filenames.
+    #
+    $mode= 0777 & ~umask;
+    for ($i=0; $i<9; $i+=3) {
+       $modes_set.= ',' if $i;
+       $modes_set.= qw(u g o)[$i/3];
+       for ($j=0; $j<3; $j++) {
+           $modes_set.= $mode & (0400 >> ($i+$j)) ? '+' : '-';
+           $modes_set.= qw(r w X)[$j];
+       }
+    }
+    system 'chmod','-R',$modes_set,'--',$dirchdir;
+    $? && subprocerr("chmod -R $modes_set $dirchdir");
+
     opendir(D,"$dirchdir") || &syserr(sprintf(_g("Unable to open dir %s"), $dirchdir));
     my @dirchdirfiles = grep($_ ne "." && $_ ne "..", readdir(D));
     closedir(D) || &syserr(sprintf(_g("Unable to close dir %s"), $dirchdir));