Mail Archives: cygwin/2002/05/08/16:30:33
'cp -p src dest' doesn't work properly under the following conditions:
1) running as an unprivileged user
2) 'source' is a symlink to 'target'
3) 'target' is owned by root (Administrator)
Test case:
(assuming /usr/bin/mount.exe is owned by Administrator, and current user
!= Administrator)
$ ls -l /usr/bin/mount.exe
-rwxrwxrwx 1 Administ None 10240 Feb 25 11:16 /usr/bin/mount
$ ln -s /usr/bin/mount.exe foo
$ cp -p foo bar
cp: preserving ownership for `bob': Permission denied
$ ls -l foo bar
-rwxrwxrwx 1 cwilson None 10240 Feb 25 11:16 bar
lrwxrwxrwx 1 cwilson None 121 May 8 15:46 foo ->
/usr/bin/mount.exe
Note that bar has the same timestamp and permissions as
/usr/bin/mount.exe; but the UID/GID differs.
What it should do (e.g. linux operation):
'dest' should be an actual copy of 'target' itself -- not a copy of the
symlink. Cygwin does this.
'dest' should have the same permissions as the 'target' -- since
permissions of a symlink are meaningless. Cygwin does this.
'dest' should have its UID and GID set to the UID/GID of the current
user; cp.exe should not attempt to set the UID/GID of 'dest' to match
that of 'target' -- or, if it does attempt to do so, it should not
return an error when it fails.
On linux, no error is reported, and 'dest' is created as an actual file,
with UID/GID === current user, and file perms of dest == file perms of
target.
On cygwin, an error IS reported, and 'dest' is created as an actual
file, with UID/GID == current user, and file perms of dest == file perms
of target.
So, the only difference seems to be that an error is reported on cygwin.
Can we silence that error (probably a bad idea) or convince cygwin's
cp.exe not to attempt to set the UID/GID when current user !=
root/Administrator, even when the -p argument is used?
I think the problem is here (in fileutils-4.1-1: src/copy.c line 40)
#define DO_CHOWN(Chown, File, New_uid, New_gid) \
(Chown (File, New_uid, New_gid) \
/* If non-root uses -p, it's ok if we can't preserve ownership. \
But root probably wants to know, e.g. if NFS disallows it, \
or if the target system doesn't support file ownership. */ \
&& ((errno != EPERM && errno != EINVAL) || x->myeuid == 0))
chown() returns 0 on success. So, this #define is supposed to:
report all errors is x->myeuid == 0
if x->myeuid != 0, don't report EPERM or EINVAL errors
So, two questions:
1) on cygwin, should the 'test' value for "root/Administrator" be 0?
or 500?
2) chown is actually reporting EACCES -- so should this test also
mask EACCES in addition to EPERM and EINVAL, when user != root?
--Chuck
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Bug reporting: http://cygwin.com/bugs.html
Documentation: http://cygwin.com/docs.html
FAQ: http://cygwin.com/faq/
- Raw text -