@@ -5541,146 +5541,6 @@ os__path_normpath_impl(PyObject *module, PyObject *path)
5541
5541
return result ;
5542
5542
}
5543
5543
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
-
5684
5544
/*[clinic input]
5685
5545
os.mkdir
5686
5546
@@ -5713,8 +5573,8 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
5713
5573
#ifdef MS_WINDOWS
5714
5574
int error = 0 ;
5715
5575
int pathError = 0 ;
5576
+ SECURITY_ATTRIBUTES secAttr = { sizeof (secAttr ) };
5716
5577
SECURITY_ATTRIBUTES * pSecAttr = NULL ;
5717
- struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData ;
5718
5578
#endif
5719
5579
#ifdef HAVE_MKDIRAT
5720
5580
int mkdirat_unavailable = 0 ;
@@ -5727,26 +5587,34 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
5727
5587
5728
5588
#ifdef MS_WINDOWS
5729
5589
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
+ }
5737
5604
}
5738
5605
if (!error ) {
5739
5606
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
+ }
5744
5613
}
5745
5614
Py_END_ALLOW_THREADS
5746
5615
5747
5616
if (error ) {
5748
- PyErr_SetFromWindowsErr (error );
5749
- return NULL ;
5617
+ return PyErr_SetFromWindowsErr (error );
5750
5618
}
5751
5619
if (!result ) {
5752
5620
return path_error (path );
0 commit comments