Skip to content

Commit 7e01002

Browse files
committed
Use language-invariant ACL
1 parent ffed50e commit 7e01002

File tree

1 file changed

+22
-154
lines changed

1 file changed

+22
-154
lines changed

Modules/posixmodule.c

Lines changed: 22 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -4587,146 +4587,6 @@ os__path_normpath_impl(PyObject *module, PyObject *path)
45874587
return result;
45884588
}
45894589

4590-
#ifdef MS_WINDOWS
4591-
4592-
/* We centralise SECURITY_ATTRIBUTE initialization based around
4593-
templates that will probably mostly match common POSIX mode settings.
4594-
The _Py_SECURITY_ATTRIBUTE_DATA structure contains temporary data, as
4595-
a constructed SECURITY_ATTRIBUTE structure typically refers to memory
4596-
that has to be alive while it's being used.
4597-
4598-
Typical use will look like:
4599-
SECURITY_ATTRIBUTES *pSecAttr = NULL;
4600-
struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData;
4601-
int error, error2;
4602-
4603-
Py_BEGIN_ALLOW_THREADS
4604-
switch (mode) {
4605-
case 0x1C0: // 0o700
4606-
error = initializeMkdir700SecurityAttributes(&pSecAttr, &secAttrData);
4607-
break;
4608-
...
4609-
default:
4610-
error = initializeDefaultSecurityAttributes(&pSecAttr, &secAttrData);
4611-
break;
4612-
}
4613-
4614-
if (!error) {
4615-
// do operation, passing pSecAttr
4616-
}
4617-
4618-
// Unconditionally clear secAttrData.
4619-
error2 = clearSecurityAttributes(&pSecAttr, &secAttrData);
4620-
if (!error) {
4621-
error = error2;
4622-
}
4623-
Py_END_ALLOW_THREADS
4624-
4625-
if (error) {
4626-
PyErr_SetFromWindowsErr(error);
4627-
return NULL;
4628-
}
4629-
*/
4630-
4631-
struct _Py_SECURITY_ATTRIBUTE_DATA {
4632-
SECURITY_ATTRIBUTES securityAttributes;
4633-
PACL acl;
4634-
SECURITY_DESCRIPTOR sd;
4635-
EXPLICIT_ACCESS_W ea[4];
4636-
char sid[64];
4637-
};
4638-
4639-
static int
4640-
initializeDefaultSecurityAttributes(
4641-
PSECURITY_ATTRIBUTES *securityAttributes,
4642-
struct _Py_SECURITY_ATTRIBUTE_DATA *data
4643-
) {
4644-
assert(securityAttributes);
4645-
assert(data);
4646-
*securityAttributes = NULL;
4647-
memset(data, 0, sizeof(*data));
4648-
return 0;
4649-
}
4650-
4651-
static int
4652-
initializeMkdir700SecurityAttributes(
4653-
PSECURITY_ATTRIBUTES *securityAttributes,
4654-
struct _Py_SECURITY_ATTRIBUTE_DATA *data
4655-
) {
4656-
assert(securityAttributes);
4657-
assert(data);
4658-
*securityAttributes = NULL;
4659-
memset(data, 0, sizeof(*data));
4660-
4661-
if (!InitializeSecurityDescriptor(&data->sd, SECURITY_DESCRIPTOR_REVISION)
4662-
|| !SetSecurityDescriptorGroup(&data->sd, NULL, TRUE)) {
4663-
return GetLastError();
4664-
}
4665-
4666-
int use_alias = 0;
4667-
DWORD cbSid = sizeof(data->sid);
4668-
if (!CreateWellKnownSid(WinCreatorOwnerRightsSid, NULL, (PSID)data->sid, &cbSid)) {
4669-
use_alias = 1;
4670-
}
4671-
4672-
data->securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
4673-
data->ea[0].grfAccessPermissions = GENERIC_ALL;
4674-
data->ea[0].grfAccessMode = SET_ACCESS;
4675-
data->ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
4676-
if (use_alias) {
4677-
data->ea[0].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
4678-
data->ea[0].Trustee.TrusteeType = TRUSTEE_IS_ALIAS;
4679-
data->ea[0].Trustee.ptstrName = L"CURRENT_USER";
4680-
} else {
4681-
data->ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
4682-
data->ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
4683-
data->ea[0].Trustee.ptstrName = (LPWCH)(SID*)data->sid;
4684-
}
4685-
4686-
data->ea[1].grfAccessPermissions = GENERIC_ALL;
4687-
data->ea[1].grfAccessMode = SET_ACCESS;
4688-
data->ea[1].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
4689-
data->ea[1].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
4690-
data->ea[1].Trustee.TrusteeType = TRUSTEE_IS_ALIAS;
4691-
data->ea[1].Trustee.ptstrName = L"SYSTEM";
4692-
4693-
data->ea[2].grfAccessPermissions = GENERIC_ALL;
4694-
data->ea[2].grfAccessMode = SET_ACCESS;
4695-
data->ea[2].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
4696-
data->ea[2].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
4697-
data->ea[2].Trustee.TrusteeType = TRUSTEE_IS_ALIAS;
4698-
data->ea[2].Trustee.ptstrName = L"ADMINISTRATORS";
4699-
4700-
int r = SetEntriesInAclW(3, data->ea, NULL, &data->acl);
4701-
if (r) {
4702-
return r;
4703-
}
4704-
if (!SetSecurityDescriptorDacl(&data->sd, TRUE, data->acl, FALSE)) {
4705-
return GetLastError();
4706-
}
4707-
data->securityAttributes.lpSecurityDescriptor = &data->sd;
4708-
*securityAttributes = &data->securityAttributes;
4709-
return 0;
4710-
}
4711-
4712-
static int
4713-
clearSecurityAttributes(
4714-
PSECURITY_ATTRIBUTES *securityAttributes,
4715-
struct _Py_SECURITY_ATTRIBUTE_DATA *data
4716-
) {
4717-
assert(securityAttributes);
4718-
assert(data);
4719-
*securityAttributes = NULL;
4720-
if (data->acl) {
4721-
if (LocalFree((void *)data->acl)) {
4722-
return GetLastError();
4723-
}
4724-
}
4725-
return 0;
4726-
}
4727-
4728-
#endif
4729-
47304590
/*[clinic input]
47314591
os.mkdir
47324592
@@ -4759,8 +4619,8 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
47594619
#ifdef MS_WINDOWS
47604620
int error = 0;
47614621
int pathError = 0;
4622+
SECURITY_ATTRIBUTES secAttr = { sizeof(secAttr) };
47624623
SECURITY_ATTRIBUTES *pSecAttr = NULL;
4763-
struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData;
47644624
#endif
47654625
#ifdef HAVE_MKDIRAT
47664626
int mkdirat_unavailable = 0;
@@ -4773,26 +4633,34 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
47734633

47744634
#ifdef MS_WINDOWS
47754635
Py_BEGIN_ALLOW_THREADS
4776-
switch (mode) {
4777-
case 0x1C0: // 0o700
4778-
error = initializeMkdir700SecurityAttributes(&pSecAttr, &secAttrData);
4779-
break;
4780-
default:
4781-
error = initializeDefaultSecurityAttributes(&pSecAttr, &secAttrData);
4782-
break;
4636+
if (mode == 0700 /* 0o700 */) {
4637+
ULONG sdSize;
4638+
pSecAttr = &secAttr;
4639+
// Set a discreationary ACL (D) that is protected (P) and includes
4640+
// inheritable (OICI) entries that allow (A) full control (FA) to
4641+
// SYSTEM (SY), Administrators (BA), and the owner (OW).
4642+
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(
4643+
L"D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)",
4644+
SDDL_REVISION_1,
4645+
&secAttr.lpSecurityDescriptor,
4646+
&sdSize
4647+
)) {
4648+
error = GetLastError();
4649+
}
47834650
}
47844651
if (!error) {
47854652
result = CreateDirectoryW(path->wide, pSecAttr);
4786-
error = clearSecurityAttributes(&pSecAttr, &secAttrData);
4787-
} else {
4788-
// Ignore error from "clear" - we have a more interesting one already
4789-
clearSecurityAttributes(&pSecAttr, &secAttrData);
4653+
if (secAttr.lpSecurityDescriptor &&
4654+
// uncommonly, LocalFree returns non-zero on error, but still uses
4655+
// GetLastError() to see what the error code is
4656+
LocalFree(secAttr.lpSecurityDescriptor)) {
4657+
error = GetLastError();
4658+
}
47904659
}
47914660
Py_END_ALLOW_THREADS
47924661

47934662
if (error) {
4794-
PyErr_SetFromWindowsErr(error);
4795-
return NULL;
4663+
return PyErr_SetFromWindowsErr(error);
47964664
}
47974665
if (!result) {
47984666
return path_error(path);

0 commit comments

Comments
 (0)