* syscalls.cc (rename): Fix permission problem with symlinks on NFS.

Rework how NtOpenFile gets called to make it more readable.  Change
	comment.
This commit is contained in:
Corinna Vinschen 2011-01-21 13:13:00 +00:00
parent 2aba945c95
commit a1c35b8b65
2 changed files with 25 additions and 12 deletions

View File

@ -1,3 +1,9 @@
2011-01-21 Corinna Vinschen <corinna@vinschen.de>
* 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 <corinna@vinschen.de>
* exec.cc: Include pinfo.h.

View File

@ -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,
/* 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,
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));
&io, sharing, flags);
}
if (!NT_SUCCESS (status))
{
debug_printf ("status %p", status);