Eryk Sun <[email protected]> added the comment:
FYI, here are the access rights applicable to files, including their membership
in generic (R)ead, (W)rite, and e(X)execute access:
0x0100_0000 --- ACCESS_SYSTEM_SECURITY
0x0010_0000 RWX SYNCHRONIZE
0x0008_0000 --- WRITE_OWNER
0x0004_0000 --- WRITE_DAC
0x0002_0000 RWX READ_CONTROL
0x0001_0000 --- DELETE
0x0000_0001 R-- FILE_READ_DATA
0x0000_0002 -W- FILE_WRITE_DATA
0x0000_0004 -W- FILE_APPEND_DATA
0x0000_0008 R-- FILE_READ_EA
0x0000_0010 -W- FILE_WRITE_EA
0x0000_0020 --X FILE_EXECUTE
0x0000_0040 --- FILE_DELETE_CHILD
0x0000_0080 R-X FILE_READ_ATTRIBUTES
0x0000_0100 -W- FILE_WRITE_ATTRIBUTES
> _wopen() uses GENERIC_READ/GENERIC_WRITE access rights, but
> _wopen() doesn't have a contractual obligation to do exactly
> that AFAIU. For example, if it got some extra access rights,
> then my code would "drop" them while switching FILE_WRITE_DATA off.
I overlooked a case that's a complication. For O_TEMPORARY, the open uses
FILE_FLAG_DELETE_ON_CLOSE; adds DELETE to the requested access; and adds
FILE_SHARE_DELETE to the share mode.
With delete-on-close, a file gets marked as deleted as soon as the last handle
for the kernel File is closed. This is the classic Windows 'deleted' state in
which the filename remains linked in the directory but inaccessible for any new
access (as opposed to the immediate POSIX style delete that DeleteFileW
attempts in Windows 10). Existing opens (i.e. kernel File objects from
CreateFileW) are still valid, and, if they have delete access, they can even be
used to undelete the file via SetFileInformationByHandle: FileDispositionInfo.
_Py_wopen_noraise() can easily keep the required DELETE access. The
complication is that you have to be careful not to close the original file
descriptor until after you've successfully created the duplicate file
descriptor. If it fails, you have to return the original file descriptor from
_wopen(). If you close all handles for the kernel File and fail the call, the
side effect of deleting the file is unacceptable.
The C runtime itself isn't careful about using O_TEMPORARY in text mode, given
how it closes the file if truncation fails or has to open the file twice in
O_WRONLY mode in order to read the BOM. But at least it's reliable in binary
mode. The file descriptor is pre-allocated with _alloc_osfhnd(), so it won't
fail after CreateFileW() is called.
> Are you aware of a common scenario when a regular file allows
> appending but not writing?
It's certainly not common for regular files. (It's more common for directories,
for which append access corresponds to the right to create a subdirectory.)
Maybe users are only allowed to append to a given log file. But I think most
scenarios will be accidental.
For example, say an admin wants to deny write access to standard users. Denying
simple or generic write access is wrong, since doing so also denies rights
required for reading, i.e. synchronize and read-control. So the admin runs the
following command to deny only write-data access: `icacls filename /deny
*BU:(WD)`. This forgets about append-data (AD) access. It's still sufficient
for most applications, which request generic-write access.
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue42606>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com