@@ -5541,148 +5541,6 @@ os__path_normpath_impl(PyObject *module, PyObject *path)
55415541return 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- BYTE sidAdmins [SECURITY_MAX_SID_SIZE ];
5591- BYTE sidSystem [SECURITY_MAX_SID_SIZE ];
5592- BYTE sidCreator [SECURITY_MAX_SID_SIZE ];
5593- };
5594-
5595- static int
5596- _initializeSid (BYTE * sid ,WELL_KNOWN_SID_TYPE sidType )
5597- {
5598- DWORD cbSid = SECURITY_MAX_SID_SIZE ;
5599- return CreateWellKnownSid (sidType ,NULL ,sid ,& cbSid ) ?1 :0 ;
5600- }
5601-
5602- static int
5603- initializeDefaultSecurityAttributes (
5604- PSECURITY_ATTRIBUTES * securityAttributes ,
5605- struct _Py_SECURITY_ATTRIBUTE_DATA * data
5606- ) {
5607- assert (securityAttributes );
5608- assert (data );
5609- * securityAttributes = NULL ;
5610- memset (data ,0 ,sizeof (* data ));
5611- return 0 ;
5612- }
5613-
5614- static int
5615- initializeMkdir700SecurityAttributes (
5616- PSECURITY_ATTRIBUTES * securityAttributes ,
5617- struct _Py_SECURITY_ATTRIBUTE_DATA * data
5618- ) {
5619- assert (securityAttributes );
5620- assert (data );
5621- * securityAttributes = NULL ;
5622- memset (data ,0 ,sizeof (* data ));
5623-
5624- SID_IDENTIFIER_AUTHORITY SidNtAuthority = SECURITY_NT_AUTHORITY ;
5625- if (!InitializeSecurityDescriptor (& data -> sd ,SECURITY_DESCRIPTOR_REVISION )
5626- || !SetSecurityDescriptorGroup (& data -> sd ,NULL , TRUE)
5627- || !_initializeSid (data -> sidAdmins ,WinBuiltinAdministratorsSid )
5628- || !_initializeSid (data -> sidSystem ,WinLocalSystemSid )
5629- || !_initializeSid (data -> sidCreator ,WinCreatorOwnerRightsSid )
5630- ) {
5631- return GetLastError ();
5632- }
5633-
5634- data -> securityAttributes .nLength = sizeof (SECURITY_ATTRIBUTES );
5635- data -> ea [0 ].grfAccessPermissions = GENERIC_ALL ;
5636- data -> ea [0 ].grfAccessMode = SET_ACCESS ;
5637- data -> ea [0 ].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT ;
5638- data -> ea [0 ].Trustee .TrusteeForm = TRUSTEE_IS_SID ;
5639- data -> ea [0 ].Trustee .TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP ;
5640- data -> ea [0 ].Trustee .ptstrName = (LPWCH )data -> sidSystem ;
5641-
5642- data -> ea [1 ].grfAccessPermissions = GENERIC_ALL ;
5643- data -> ea [1 ].grfAccessMode = SET_ACCESS ;
5644- data -> ea [1 ].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT ;
5645- data -> ea [1 ].Trustee .TrusteeForm = TRUSTEE_IS_SID ;
5646- data -> ea [1 ].Trustee .TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP ;
5647- data -> ea [1 ].Trustee .ptstrName = (LPWCH )data -> sidAdmins ;
5648-
5649- data -> ea [2 ].grfAccessPermissions = GENERIC_ALL ;
5650- data -> ea [2 ].grfAccessMode = SET_ACCESS ;
5651- data -> ea [2 ].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT ;
5652- data -> ea [2 ].Trustee .TrusteeForm = TRUSTEE_IS_SID ;
5653- data -> ea [2 ].Trustee .TrusteeType = TRUSTEE_IS_ALIAS ;
5654- data -> ea [2 ].Trustee .ptstrName = (LPWCH )data -> sidCreator ;
5655-
5656- int r = SetEntriesInAclW (3 ,data -> ea ,NULL ,& data -> acl );
5657- if (r ) {
5658- return r ;
5659- }
5660- if (!SetSecurityDescriptorDacl (& data -> sd , TRUE,data -> acl , FALSE)) {
5661- return GetLastError ();
5662- }
5663- data -> securityAttributes .lpSecurityDescriptor = & data -> sd ;
5664- * securityAttributes = & data -> securityAttributes ;
5665- return 0 ;
5666- }
5667-
5668- static int
5669- clearSecurityAttributes (
5670- PSECURITY_ATTRIBUTES * securityAttributes ,
5671- struct _Py_SECURITY_ATTRIBUTE_DATA * data
5672- ) {
5673- assert (securityAttributes );
5674- assert (data );
5675- * securityAttributes = NULL ;
5676- if (data -> acl ) {
5677- if (LocalFree ((void * )data -> acl )) {
5678- return GetLastError ();
5679- }
5680- }
5681- return 0 ;
5682- }
5683-
5684- #endif
5685-
56865544/*[clinic input]
56875545os.mkdir
56885546
@@ -5715,8 +5573,8 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
57155573#ifdef MS_WINDOWS
57165574int error = 0 ;
57175575int pathError = 0 ;
5576+ SECURITY_ATTRIBUTES secAttr = {sizeof (secAttr ) };
57185577SECURITY_ATTRIBUTES * pSecAttr = NULL ;
5719- struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData ;
57205578#endif
57215579#ifdef HAVE_MKDIRAT
57225580int mkdirat_unavailable = 0 ;
@@ -5729,26 +5587,31 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
57295587
57305588#ifdef MS_WINDOWS
57315589Py_BEGIN_ALLOW_THREADS
5732- switch (mode ) {
5733- case 0x1C0 :// 0o700
5734- error = initializeMkdir700SecurityAttributes (& pSecAttr ,& secAttrData );
5735- break ;
5736- default :
5737- error = initializeDefaultSecurityAttributes (& pSecAttr ,& secAttrData );
5738- 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:PAI(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+ }
57395604 }
57405605if (!error ) {
57415606result = CreateDirectoryW (path -> wide ,pSecAttr );
5742- error = clearSecurityAttributes (& pSecAttr ,& secAttrData );
5743- }else {
5744- // Ignore error from "clear" - we have a more interesting one already
5745- clearSecurityAttributes (& pSecAttr ,& secAttrData );
5607+ if (LocalFree (secAttr .lpSecurityDescriptor )) {
5608+ error = GetLastError ();
5609+ }
57465610 }
57475611Py_END_ALLOW_THREADS
57485612
57495613if (error ) {
5750- PyErr_SetFromWindowsErr (error );
5751- return NULL ;
5614+ return PyErr_SetFromWindowsErr (error );
57525615 }
57535616if (!result ) {
57545617return path_error (path );