diff options
| author | Steve Dower <steve.dower@python.org> | 2024-05-24 17:27:01 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-24 17:27:01 (GMT) |
| commit | 5130731c9e779b97d00a24f54cdce73ce9975dfd (patch) | |
| tree | 9e87cdf79ffcba46651eed0928c66b87b7056084 /Modules | |
| parent | b228655c227b2ca298a8ffac44d14ce3d22f6faa (diff) | |
| download | cpython-5130731c9e779b97d00a24f54cdce73ce9975dfd.zip cpython-5130731c9e779b97d00a24f54cdce73ce9975dfd.tar.gz cpython-5130731c9e779b97d00a24f54cdce73ce9975dfd.tar.bz2 | |
[3.9] gh-118486: Support mkdir(mode=0o700) on Windows (GH-118488) (GH-118741)
Co-authored-by: Ćukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Modules')
| -rw-r--r-- | Modules/posixmodule.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index bf4e648..7645bcf 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -24,6 +24,12 @@ #include "pycore_ceval.h" // _PyEval_ReInitThreads() #include "pycore_import.h" // _PyImport_ReInitLock() #include "pycore_pystate.h" // _PyInterpreterState_GET() + +#ifdef MS_WINDOWS +# include <aclapi.h> // SetEntriesInAcl +# include <sddl.h> // SDDL_REVISION_1 +#endif + #include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS # include "posixmodule.h" @@ -4425,7 +4431,6 @@ os__path_splitroot_impl(PyObject *module, path_t *path) #endif /* MS_WINDOWS */ - /*[clinic input] os.mkdir @@ -4454,6 +4459,12 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd) /*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/ { 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 @@ -4465,11 +4476,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 discretionary 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 |
