Package: fai-client
Version: 5.3.3
Severity: normal
Tags: upstream patch

When using the -H option (treat symlinks in the config space to mean to create 
symlinks on the target), fcopy uses stat(), chown(), utime() and chmod(), where 
it should be using lstat(), lchown(), lutimes() and nothing.

You need an additional dependeny on libfile-lchown-perl with the attached patch.
-- System Information:
Debian Release: 9.0
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 4.9.6.wap (SMP w/2 CPU cores)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages fai-client depends on:
ii  debconf-utils    1.5.60
ii  file             1:5.29-2
ii  iproute2         4.9.0-1
ii  libapt-pkg-perl  0.1.30
ii  perl             5.24.1-1

Versions of packages fai-client recommends:
pn  libgraph-perl  <none>

Versions of packages fai-client suggests:
ii  logtail  1.3.17

-- Configuration Files:
/etc/fai/fai.conf changed [not included]

-- no debconf information
--- fcopy.1     2017-01-11 16:14:10.000000000 +0100
+++ fcopy.2     2017-01-12 11:54:29.000000000 +0100
@@ -36,6 +36,7 @@
 use File::Basename;
 use File::Spec;
 use File::Temp qw/tempfile/;
+use File::lchown qw/lchown lutimes/;
 use Getopt::Std;
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -298,11 +299,20 @@
     $stime = (stat("$sourcefile/$class"))[9];
   } else {
     # get mtime,uid,gid,mode from source file
-    ($stime,@defmodes) = (stat("$sourcefile/$class"))[9,4,5,2];
+    if ($opt_H) {
+      ($stime,@defmodes) = (lstat("$sourcefile/$class"))[9,4,5,2];
+    } else {
+      ($stime,@defmodes) = (stat("$sourcefile/$class"))[9,4,5,2];
+    }
   }
 
   # get mtime,uid,gid,mode from destination file
-  my ($dtime,@ddefmodes) = (stat("$destfile"))[9,4,5,2];
+  my ($dtime,@ddefmodes);
+  if ($opt_H) {
+    ($dtime,@ddefmodes) = (lstat("$destfile"))[9,4,5,2];
+  } else {
+    ($dtime,@ddefmodes) = (stat("$destfile"))[9,4,5,2];
+  }
   # compare time,uid,gid and mode of source file and target file
 
   if ($modeset) { # use -m values
@@ -314,15 +324,22 @@
   }
 
   # if different: change the values
+  # setting modes on a symlink is not portable, so ignore it
+  my $issymlink = $opt_H && -l $destfile;
   return if ($stime == $dtime && (($ddefmodes[0] == $owner) &&
-      ($ddefmodes[1] == $group) && ($ddefmodes[2] == $mode)));
+      ($ddefmodes[1] == $group) && ($issymlink || ($ddefmodes[2] == $mode))));
 
   ($uid,$gid) = name2num($owner,$group);
   warn "chown/chmod u:$uid g:$gid m:$mode $destfile\n" if $debug;
   return if $dryrun; # do not execute if -n or FCOPY_DRYRUN was given
-  chown ($uid,$gid,     $destfile) || ewarn("chown $owner $group $destfile 
failed. $!");
-  chmod ($mode,         $destfile) || ewarn("chmod $mode $destfile failed. 
$!");
-  utime ($stime,$stime, $destfile) || ewarn("utime for $destfile failed. $!");
+  if ($issymlink) {
+    lchown  ($uid,$gid,     $destfile) || ewarn("lchown $owner $group 
$destfile failed. $!");
+    lutimes ($stime,$stime, $destfile) || ewarn("lutime for $destfile failed. 
$!");
+  } else {
+    chown ($uid,$gid,     $destfile) || ewarn("chown $owner $group $destfile 
failed. $!");
+    chmod ($mode,         $destfile) || ewarn("chmod $mode $destfile failed. 
$!");
+    utime ($stime,$stime, $destfile) || ewarn("utime for $destfile failed. 
$!");
+  }
 }
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 sub check_mopt {

Reply via email to