Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8af84b5

Browse filesBrowse files
authored
pythongh-118773: Use language-invariant SDDL string instead of aliases for ACLs. (pythonGH-118800)
1 parent c30d8e5 commit 8af84b5
Copy full SHA for 8af84b5

File tree

2 files changed

+24
-154
lines changed
Filter options

2 files changed

+24
-154
lines changed
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixes creation of ACLs in :func:`os.mkdir` on Windows to work correctly on
2+
non-English machines.

‎Modules/posixmodule.c

Copy file name to clipboardExpand all lines: Modules/posixmodule.c
+22-154Lines changed: 22 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -5541,146 +5541,6 @@ os__path_normpath_impl(PyObject *module, PyObject *path)
55415541
return result;
55425542
}
55435543

5544-
#ifdef MS_WINDOWS
5545-
5546-
/* We centralise SECURITY_ATTRIBUTE initialization based around
5547-
templates that will probably mostly match common POSIX mode settings.
5548-
The _Py_SECURITY_ATTRIBUTE_DATA structure contains temporary data, as
5549-
a constructed SECURITY_ATTRIBUTE structure typically refers to memory
5550-
that has to be alive while it's being used.
5551-
5552-
Typical use will look like:
5553-
SECURITY_ATTRIBUTES *pSecAttr = NULL;
5554-
struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData;
5555-
int error, error2;
5556-
5557-
Py_BEGIN_ALLOW_THREADS
5558-
switch (mode) {
5559-
case 0x1C0: // 0o700
5560-
error = initializeMkdir700SecurityAttributes(&pSecAttr, &secAttrData);
5561-
break;
5562-
...
5563-
default:
5564-
error = initializeDefaultSecurityAttributes(&pSecAttr, &secAttrData);
5565-
break;
5566-
}
5567-
5568-
if (!error) {
5569-
// do operation, passing pSecAttr
5570-
}
5571-
5572-
// Unconditionally clear secAttrData.
5573-
error2 = clearSecurityAttributes(&pSecAttr, &secAttrData);
5574-
if (!error) {
5575-
error = error2;
5576-
}
5577-
Py_END_ALLOW_THREADS
5578-
5579-
if (error) {
5580-
PyErr_SetFromWindowsErr(error);
5581-
return NULL;
5582-
}
5583-
*/
5584-
5585-
struct _Py_SECURITY_ATTRIBUTE_DATA {
5586-
SECURITY_ATTRIBUTES securityAttributes;
5587-
PACL acl;
5588-
SECURITY_DESCRIPTOR sd;
5589-
EXPLICIT_ACCESS_W ea[4];
5590-
char sid[64];
5591-
};
5592-
5593-
static int
5594-
initializeDefaultSecurityAttributes(
5595-
PSECURITY_ATTRIBUTES *securityAttributes,
5596-
struct _Py_SECURITY_ATTRIBUTE_DATA *data
5597-
) {
5598-
assert(securityAttributes);
5599-
assert(data);
5600-
*securityAttributes = NULL;
5601-
memset(data, 0, sizeof(*data));
5602-
return 0;
5603-
}
5604-
5605-
static int
5606-
initializeMkdir700SecurityAttributes(
5607-
PSECURITY_ATTRIBUTES *securityAttributes,
5608-
struct _Py_SECURITY_ATTRIBUTE_DATA *data
5609-
) {
5610-
assert(securityAttributes);
5611-
assert(data);
5612-
*securityAttributes = NULL;
5613-
memset(data, 0, sizeof(*data));
5614-
5615-
if (!InitializeSecurityDescriptor(&data->sd, SECURITY_DESCRIPTOR_REVISION)
5616-
|| !SetSecurityDescriptorGroup(&data->sd, NULL, TRUE)) {
5617-
return GetLastError();
5618-
}
5619-
5620-
int use_alias = 0;
5621-
DWORD cbSid = sizeof(data->sid);
5622-
if (!CreateWellKnownSid(WinCreatorOwnerRightsSid, NULL, (PSID)data->sid, &cbSid)) {
5623-
use_alias = 1;
5624-
}
5625-
5626-
data->securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
5627-
data->ea[0].grfAccessPermissions = GENERIC_ALL;
5628-
data->ea[0].grfAccessMode = SET_ACCESS;
5629-
data->ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
5630-
if (use_alias) {
5631-
data->ea[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
5632-
data->ea[0].Trustee.TrusteeType = TRUSTEE_IS_ALIAS;
5633-
data->ea[0].Trustee.ptstrName = L"CURRENT_USER";
5634-
} else {
5635-
data->ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
5636-
data->ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
5637-
data->ea[0].Trustee.ptstrName = (LPWCH)(SID*)data->sid;
5638-
}
5639-
5640-
data->ea[1].grfAccessPermissions = GENERIC_ALL;
5641-
data->ea[1].grfAccessMode = SET_ACCESS;
5642-
data->ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
5643-
data->ea[1].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
5644-
data->ea[1].Trustee.TrusteeType = TRUSTEE_IS_ALIAS;
5645-
data->ea[1].Trustee.ptstrName = L"SYSTEM";
5646-
5647-
data->ea[2].grfAccessPermissions = GENERIC_ALL;
5648-
data->ea[2].grfAccessMode = SET_ACCESS;
5649-
data->ea[2].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
5650-
data->ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
5651-
data->ea[2].Trustee.TrusteeType = TRUSTEE_IS_ALIAS;
5652-
data->ea[2].Trustee.ptstrName = L"ADMINISTRATORS";
5653-
5654-
int r = SetEntriesInAclW(3, data->ea, NULL, &data->acl);
5655-
if (r) {
5656-
return r;
5657-
}
5658-
if (!SetSecurityDescriptorDacl(&data->sd, TRUE, data->acl, FALSE)) {
5659-
return GetLastError();
5660-
}
5661-
data->securityAttributes.lpSecurityDescriptor = &data->sd;
5662-
*securityAttributes = &data->securityAttributes;
5663-
return 0;
5664-
}
5665-
5666-
static int
5667-
clearSecurityAttributes(
5668-
PSECURITY_ATTRIBUTES *securityAttributes,
5669-
struct _Py_SECURITY_ATTRIBUTE_DATA *data
5670-
) {
5671-
assert(securityAttributes);
5672-
assert(data);
5673-
*securityAttributes = NULL;
5674-
if (data->acl) {
5675-
if (LocalFree((void *)data->acl)) {
5676-
return GetLastError();
5677-
}
5678-
}
5679-
return 0;
5680-
}
5681-
5682-
#endif
5683-
56845544
/*[clinic input]
56855545
os.mkdir
56865546
@@ -5713,8 +5573,8 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
57135573
#ifdef MS_WINDOWS
57145574
int error = 0;
57155575
int pathError = 0;
5576+
SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr) };
57165577
SECURITY_ATTRIBUTES *pSecAttr = NULL;
5717-
struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData;
57185578
#endif
57195579
#ifdef HAVE_MKDIRAT
57205580
int mkdirat_unavailable = 0;
@@ -5727,26 +5587,34 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
57275587

57285588
#ifdef MS_WINDOWS
57295589
Py_BEGIN_ALLOW_THREADS
5730-
switch (mode) {
5731-
case 0x1C0: // 0o700
5732-
error = initializeMkdir700SecurityAttributes(&pSecAttr, &secAttrData);
5733-
break;
5734-
default:
5735-
error = initializeDefaultSecurityAttributes(&pSecAttr, &secAttrData);
5736-
break;
5590+
if (mode == 0700 /* 0o700 */) {
5591+
ULONG sdSize;
5592+
pSecAttr = &secAttr;
5593+
// Set a discreationary ACL (D) that is protected (P) and includes
5594+
// inheritable (OICI) entries that allow (A) full control (FA) to
5595+
// SYSTEM (SY), Administrators (BA), and the owner (OW).
5596+
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
5597+
L"D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)",
5598+
SDDL_REVISION_1,
5599+
&secAttr.lpSecurityDescriptor,
5600+
&sdSize
5601+
)) {
5602+
error = GetLastError();
5603+
}
57375604
}
57385605
if (!error) {
57395606
result = CreateDirectoryW(path->wide, pSecAttr);
5740-
error = clearSecurityAttributes(&pSecAttr, &secAttrData);
5741-
} else {
5742-
// Ignore error from "clear" - we have a more interesting one already
5743-
clearSecurityAttributes(&pSecAttr, &secAttrData);
5607+
if (secAttr.lpSecurityDescriptor &&
5608+
// uncommonly, LocalFree returns non-zero on error, but still uses
5609+
// GetLastError() to see what the error code is
5610+
LocalFree(secAttr.lpSecurityDescriptor)) {
5611+
error = GetLastError();
5612+
}
57445613
}
57455614
Py_END_ALLOW_THREADS
57465615

57475616
if (error) {
5748-
PyErr_SetFromWindowsErr(error);
5749-
return NULL;
5617+
return PyErr_SetFromWindowsErr(error);
57505618
}
57515619
if (!result) {
57525620
return path_error(path);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.