From mkamm@sbox.tu-graz.ac.at  Sun Feb 11 14:43:50 2001
Return-Path: <mkamm@sbox.tu-graz.ac.at>
Received: from ns1.tu-graz.ac.at (ns1.tu-graz.ac.at [129.27.2.3])
	by hub.freebsd.org (Postfix) with ESMTP id 9000E37B4EC
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 11 Feb 2001 14:43:49 -0800 (PST)
Received: from homebox.kammerhofer.org (isdn091.tu-graz.ac.at [129.27.240.91])
	by ns1.tu-graz.ac.at (8.9.3/8.9.3) with ESMTP id XAA07821
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 11 Feb 2001 23:43:44 +0100 (MET)
Received: (from mkamm@localhost)
	by homebox.kammerhofer.org (8.11.2/8.11.2) id f1B16SU01894;
	Sun, 11 Feb 2001 02:06:28 +0100 (CET)
	(envelope-from mkamm)
Message-Id: <200102110106.f1B16SU01894@homebox.kammerhofer.org>
Date: Sun, 11 Feb 2001 02:06:28 +0100 (CET)
From: mkamm@gmx.net
Reply-To: mkamm@gmx.net
To: FreeBSD-gnats-submit@freebsd.org
Subject: cp -pRP does not preserve symlink ownership
X-Send-Pr-Version: 3.2

>Number:         25017
>Category:       bin
>Synopsis:       cp -pRP does not preserve symlink ownership
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Feb 11 14:50:02 PST 2001
>Closed-Date:    Sun Jun 22 00:03:09 PDT 2003
>Last-Modified:  Sun Jun 22 00:03:09 PDT 2003
>Originator:     Martin Kammerhofer
>Release:        FreeBSD 4.2-STABLE i386
>Organization:
Universitt Graz
>Environment:
>Description:

I quote "man cp":

     -p    Cause cp to preserve in the copy as many of the modification time,
           access time, file flags, file mode, user ID, and group ID as al-
           lowed by permissions.

However no attempt is made by cp(1) to preserve ownership of copied symlinks.

>How-To-Repeat:

as root try:

# ln -s /COPYRIGHT copyright
# chown -h uucp:bin copyright
# ls -l copyright
lrwxr-xr-x  1 uucp  bin  10 11 Feb 01:57 copyright -> /COPYRIGHT
# cp -pR copyright copyright2
# ls -l copyright2
lrwxr-xr-x  1 root  mkamm  10 11 Feb 01:57 copyright2 -> /COPYRIGHT

>Fix:

Index: utils.c
===================================================================
RCS file: /home/ncvs/src/bin/cp/utils.c,v
retrieving revision 1.28
diff -u -r1.28 utils.c
--- utils.c	2000/10/10 01:48:18	1.28
+++ utils.c	2001/02/11 00:52:13
@@ -224,7 +224,7 @@
 		warn("symlink: %s", link);
 		return (1);
 	}
-	return (0);
+	return (pflag ? setlink(p->fts_statp) : 0);
 }
 
 int
@@ -305,7 +305,7 @@
 
 	if (!gotstat || fs->st_mode != ts.st_mode)
 		if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
-			warn("chown: %s", to.p_path);
+			warn("chmod: %s", to.p_path);
 			rval = 1;
 		}
 
@@ -318,6 +318,31 @@
 
 	return (rval);
 }
+
+
+int
+setlink(fs)
+	struct stat *fs;
+{
+	struct stat ts;
+
+	if (lstat(to.p_path, &ts)) {
+	    warn("symlink %s disappeared", to.p_path);
+	    return (1);
+	}
+	/*
+	 * Changing the ownership probably won't succeed, unless we are root.
+	 */
+	if (fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid)
+	    if (lchown(to.p_path, fs->st_uid, fs->st_gid)) {
+		if (errno != EPERM) {
+		    warn("lchown: %s", to.p_path);
+		    return (1);
+		}
+	    }
+	return (0);
+}
+
 
 void
 usage()

>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: mkamm@gmx.net
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/25017: cp -pRP does not preserve symlink ownership
Date: Mon, 12 Feb 2001 17:00:13 +1100 (EST)

 On Sun, 11 Feb 2001 mkamm@gmx.net wrote:
 
 > >Description:
 > 
 > I quote "man cp":
 > 
 >      -p    Cause cp to preserve in the copy as many of the modification time,
 >            access time, file flags, file mode, user ID, and group ID as al-
 >            lowed by permissions.
 > 
 > However no attempt is made by cp(1) to preserve ownership of copied symlinks.
 
 > >Fix:
 > 
 > Index: utils.c
 > ===================================================================
 > RCS file: /home/ncvs/src/bin/cp/utils.c,v
 > retrieving revision 1.28
 > diff -u -r1.28 utils.c
 > --- utils.c	2000/10/10 01:48:18	1.28
 > +++ utils.c	2001/02/11 00:52:13
 > @@ -224,7 +224,7 @@
 >  		warn("symlink: %s", link);
 >  		return (1);
 >  	}
 > -	return (0);
 > +	return (pflag ? setlink(p->fts_statp) : 0);
 >  }
 
 This should use a slightly modified version of setfile() (replace
 `chown(...)' by `(S_ISLINK(...) ? chown : lchown)(...)', etc.  This
 will also fix the non-preservation of modes and times for symlinks.
 
 Bruce
 
 

From: Martin Kammerhofer <mkamm@sbox.tu-graz.ac.at>
To: Bruce Evans <bde@zeta.org.au>
Cc: mkamm@gmx.net, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: bin/25017: cp -pRP does not preserve symlink ownership
Date: Thu, 15 Feb 2001 14:25:04 +0100 (CET)

 Am 12.02.01 hat Bruce Evans folgendes geschrieben:
 
 : 
 : This should use a slightly modified version of setfile() (replace
 : `chown(...)' by `(S_ISLINK(...) ? chown : lchown)(...)', etc.  This
 : will also fix the non-preservation of modes and times for symlinks.
 : 
 : Bruce
 : 
 
 Below is a revised patch following this proposition:
 
 Index: utils.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/cp/utils.c,v
 retrieving revision 1.28
 diff -u -r1.28 utils.c
 --- utils.c	2000/10/10 01:48:18	1.28
 +++ utils.c	2001/02/15 14:15:03
 @@ -224,7 +224,7 @@
  		warn("symlink: %s", link);
  		return (1);
  	}
 -	return (0);
 +	return (pflag ? setfile(p->fts_statp, 0) : 0);
  }
  
  int
 @@ -267,20 +267,21 @@
  {
  	static struct timeval tv[2];
  	struct stat ts;
 -	int rval;
 -	int gotstat;
 +	int rval, gotstat, islink;
  
  	rval = 0;
 +	islink = !fd && S_ISLNK(fs->st_mode);
  	fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX |
  		       S_IRWXU | S_IRWXG | S_IRWXO;
  
  	TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec);
  	TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec);
 -	if (utimes(to.p_path, tv)) {
 +	if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) {
  		warn("utimes: %s", to.p_path);
  		rval = 1;
  	}
 -	if (fd ? fstat(fd, &ts) : stat(to.p_path, &ts))
 +	if (fd ? fstat(fd, &ts) :
 +	    (islink ? lstat(to.p_path, &ts) : stat(to.p_path, &ts)))
  		gotstat = 0;
  	else {
  		gotstat = 1;
 @@ -295,7 +296,8 @@
  	 */
  	if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid)
  		if (fd ? fchown(fd, fs->st_uid, fs->st_gid) :
 -		    chown(to.p_path, fs->st_uid, fs->st_gid)) {
 +		    (islink ? lchown(to.p_path, fs->st_uid, fs->st_gid) :
 +			      chown(to.p_path, fs->st_uid, fs->st_gid))) {
  			if (errno != EPERM) {
  				warn("chown: %s", to.p_path);
  				rval = 1;
 @@ -304,14 +306,17 @@
  		}
  
  	if (!gotstat || fs->st_mode != ts.st_mode)
 -		if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) {
 -			warn("chown: %s", to.p_path);
 +		if (fd ? fchmod(fd, fs->st_mode) :
 +			(islink ? lchmod(to.p_path, fs->st_mode)
 +				: chmod(to.p_path, fs->st_mode))) {
 +			warn("chmod: %s", to.p_path);
  			rval = 1;
  		}
  
  	if (!gotstat || fs->st_flags != ts.st_flags)
 -		if (fd ?
 -		    fchflags(fd, fs->st_flags) : chflags(to.p_path, fs->st_flags)) {
 +		if (fd ? fchflags(fd, fs->st_flags) :
 +		    (islink ? (errno = ENOSYS)
 +		            : chflags(to.p_path, fs->st_flags))) {
  			warn("chflags: %s", to.p_path);
  			rval = 1;
  		}
 
 
State-Changed-From-To: open->closed 
State-Changed-By: jmg 
State-Changed-When: Sun Jun 22 00:02:39 PDT 2003 
State-Changed-Why:  
fixed in rev1.41 of src/bin/cp/utils.c 

http://www.freebsd.org/cgi/query-pr.cgi?pr=25017 
>Unformatted:
