Package: dpkg
Version: 1.13.22
Tags: patch

An ubuntu user reported here
 https://launchpad.net/distros/ubuntu/+source/dpkg/+bug/51468
that dpkg-source can get the permissions wrong when extracting an
archive.  I believe the patch below corrects the behaviour.

Here is the changelog bullet point:

  * dpkg-source: respect g+s and umask when extracting.  (LP 51468.)
    The new behaviour is that the only thing which matters about the
    permissions specified in the archive is whether an object has execute
    permission for anyone, as for chmod =X.  Set-id (of files and
    directories) and read/write permissions from the archive are ignored.
    Permissions are determined by the umask; group ownership and
    directory-setgid according the usual filesystem policies.

Regards,
Ian.

diff -Nru /tmp/InoaTvHgRd/dpkg-1.13.22ubuntu6/scripts/dpkg-source.pl 
/tmp/PIGkcmiEoT/dpkg-1.13.22ubuntu7/scripts/dpkg-source.pl
--- /tmp/InoaTvHgRd/dpkg-1.13.22ubuntu6/scripts/dpkg-source.pl  2006-08-14 
16:40:52.000000000 +0100
+++ /tmp/PIGkcmiEoT/dpkg-1.13.22ubuntu7/scripts/dpkg-source.pl  2006-10-03 
17:55:58.000000000 +0100
@@ -746,10 +746,8 @@
        (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(':',@fowner), "$tmp/$t";
        rename("$tmp/$t",$target)
            || &syserr(sprintf(_g("unable to rename `%s' to `%s'"), "$tmp/$t", 
$target));
        rmdir($tmp)
@@ -1217,19 +1215,49 @@
 
 sub extracttar {
     my ($tarfileread,$dirchdir,$newtopdir) = @_;
+    my ($mode, $modes_set);
     &forkgzipread("$tarfileread");
     defined($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));
     @dirchdirfiles = grep($_ ne "." && $_ ne "..",readdir(D));
     closedir(D) || &syserr(sprintf(_g("Unable to close dir %s"), $dirchdir));


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to