From a1c35b8b65fadc52c8654a74ae60422ad15f4002 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 21 Jan 2011 13:13:00 +0000 Subject: [PATCH] * syscalls.cc (rename): Fix permission problem with symlinks on NFS. Rework how NtOpenFile gets called to make it more readable. Change comment. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/syscalls.cc | 31 +++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c6ebe1d89..50b443158 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2011-01-21 Corinna Vinschen + + * syscalls.cc (rename): Fix permission problem with symlinks on NFS. + Rework how NtOpenFile gets called to make it more readable. Change + comment. + 2011-01-20 Corinna Vinschen * exec.cc: Include pinfo.h. diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index c38671f39..6ea3c2803 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -2053,18 +2053,25 @@ rename (const char *oldpath, const char *newpath) int retry_count; retry_count = 0; retry: - /* DELETE is required to rename a file. At least one cifs FS (Tru64) needs - FILE_READ_ATTRIBUTE, otherwise the FileRenameInformation call fails with - STATUS_ACCESS_DENIED. Samba (only some versions?) doesn't like the - FILE_SHARE_DELETE mode if the file has the R/O attribute set and returns - STATUS_ACCESS_DENIED in that case. */ - status = NtOpenFile (&fh, DELETE | FILE_READ_ATTRIBUTES, - oldpc.get_object_attr (attr, sec_none_nih), - &io, - oldpc.fs_is_samba () ? FILE_SHARE_READ | FILE_SHARE_WRITE - : FILE_SHARE_VALID_FLAGS, - FILE_OPEN_FOR_BACKUP_INTENT - | (oldpc.is_rep_symlink () ? FILE_OPEN_REPARSE_POINT : 0)); + /* Talking about inconsistent behaviour... + - DELETE is required to rename a file. So far, so good. + - At least one cifs FS (Tru64) needs FILE_READ_ATTRIBUTE, otherwise the + FileRenameInformation call fails with STATUS_ACCESS_DENIED. However, + on NFS we get a STATUS_ACCESS_DENIED if FILE_READ_ATTRIBUTE is used + and the file we try to rename is a symlink. Urgh. + - Samba (only some versions?) doesn't like the FILE_SHARE_DELETE mode if + the file has the R/O attribute set and returns STATUS_ACCESS_DENIED in + that case. */ + { + ULONG access = DELETE | (oldpc.fs_is_cifs () ? FILE_READ_ATTRIBUTES : 0); + ULONG sharing = FILE_SHARE_READ | FILE_SHARE_WRITE + | (oldpc.fs_is_samba () ? 0 : FILE_SHARE_DELETE); + ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT + | (oldpc.is_rep_symlink () ? FILE_OPEN_REPARSE_POINT : 0); + status = NtOpenFile (&fh, access, + oldpc.get_object_attr (attr, sec_none_nih), + &io, sharing, flags); + } if (!NT_SUCCESS (status)) { debug_printf ("status %p", status);