This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cp.ese bug report -- possible fix?


'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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]