summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2024-05-24 17:27:01 (GMT)
committerGitHub <noreply@github.com>2024-05-24 17:27:01 (GMT)
commit5130731c9e779b97d00a24f54cdce73ce9975dfd (patch)
tree9e87cdf79ffcba46651eed0928c66b87b7056084 /Modules
parentb228655c227b2ca298a8ffac44d14ce3d22f6faa (diff)
downloadcpython-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.c44
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