mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-118486: Support mkdir(mode=0o700) on Windows (GH-118488)
This commit is contained in:
parent
c0d257cc69
commit
eb29e2f590
6 changed files with 106 additions and 2 deletions
|
@ -32,6 +32,8 @@
|
|||
# include <winioctl.h>
|
||||
# include <lmcons.h> // UNLEN
|
||||
# include "osdefs.h" // SEP
|
||||
# include <aclapi.h> // SetEntriesInAcl
|
||||
# include <sddl.h> // SDDL_REVISION_1
|
||||
# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)
|
||||
# define HAVE_SYMLINK
|
||||
# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */
|
||||
|
@ -5342,6 +5344,12 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
|
|||
/*[clinic end generated code: output=a70446903abe821f input=a61722e1576fab03]*/
|
||||
{
|
||||
int result;
|
||||
#ifdef MS_WINDOWS
|
||||
int error = 0;
|
||||
int pathError = 0;
|
||||
SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr) };
|
||||
SECURITY_ATTRIBUTES *pSecAttr = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_MKDIRAT
|
||||
int mkdirat_unavailable = 0;
|
||||
#endif
|
||||
|
@ -5353,11 +5361,38 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
|
|||
|
||||
#ifdef MS_WINDOWS
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result = CreateDirectoryW(path->wide, NULL);
|
||||
if (mode == 0700 /* 0o700 */) {
|
||||
ULONG sdSize;
|
||||
pSecAttr = &secAttr;
|
||||
// Set a discreationary ACL (D) that is protected (P) and includes
|
||||
// inheritable (OICI) entries that allow (A) full control (FA) to
|
||||
// SYSTEM (SY), Administrators (BA), and the owner (OW).
|
||||
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||
L"D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)",
|
||||
SDDL_REVISION_1,
|
||||
&secAttr.lpSecurityDescriptor,
|
||||
&sdSize
|
||||
)) {
|
||||
error = GetLastError();
|
||||
}
|
||||
}
|
||||
if (!error) {
|
||||
result = CreateDirectoryW(path->wide, pSecAttr);
|
||||
if (secAttr.lpSecurityDescriptor &&
|
||||
// uncommonly, LocalFree returns non-zero on error, but still uses
|
||||
// GetLastError() to see what the error code is
|
||||
LocalFree(secAttr.lpSecurityDescriptor)) {
|
||||
error = GetLastError();
|
||||
}
|
||||
}
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (!result)
|
||||
if (error) {
|
||||
return PyErr_SetFromWindowsErr(error);
|
||||
}
|
||||
if (!result) {
|
||||
return path_error(path);
|
||||
}
|
||||
#else
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
#if HAVE_MKDIRAT
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue