@@ -4431,147 +4431,6 @@ os__path_splitroot_impl(PyObject *module, path_t *path)
4431
4431
4432
4432
#endif /* MS_WINDOWS */
4433
4433
4434
-
4435
- #ifdef MS_WINDOWS
4436
-
4437
- /* We centralise SECURITY_ATTRIBUTE initialization based around
4438
- templates that will probably mostly match common POSIX mode settings.
4439
- The _Py_SECURITY_ATTRIBUTE_DATA structure contains temporary data, as
4440
- a constructed SECURITY_ATTRIBUTE structure typically refers to memory
4441
- that has to be alive while it's being used.
4442
-
4443
- Typical use will look like:
4444
- SECURITY_ATTRIBUTES *pSecAttr = NULL;
4445
- struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData;
4446
- int error, error2;
4447
-
4448
- Py_BEGIN_ALLOW_THREADS
4449
- switch (mode) {
4450
- case 0x1C0: // 0o700
4451
- error = initializeMkdir700SecurityAttributes(&pSecAttr, &secAttrData);
4452
- break;
4453
- ...
4454
- default:
4455
- error = initializeDefaultSecurityAttributes(&pSecAttr, &secAttrData);
4456
- break;
4457
- }
4458
-
4459
- if (!error) {
4460
- // do operation, passing pSecAttr
4461
- }
4462
-
4463
- // Unconditionally clear secAttrData.
4464
- error2 = clearSecurityAttributes(&pSecAttr, &secAttrData);
4465
- if (!error) {
4466
- error = error2;
4467
- }
4468
- Py_END_ALLOW_THREADS
4469
-
4470
- if (error) {
4471
- PyErr_SetFromWindowsErr(error);
4472
- return NULL;
4473
- }
4474
- */
4475
-
4476
- struct _Py_SECURITY_ATTRIBUTE_DATA {
4477
- SECURITY_ATTRIBUTES securityAttributes ;
4478
- PACL acl ;
4479
- SECURITY_DESCRIPTOR sd ;
4480
- EXPLICIT_ACCESS_W ea [4 ];
4481
- char sid [64 ];
4482
- };
4483
-
4484
- static int
4485
- initializeDefaultSecurityAttributes (
4486
- PSECURITY_ATTRIBUTES * securityAttributes ,
4487
- struct _Py_SECURITY_ATTRIBUTE_DATA * data
4488
- ) {
4489
- assert (securityAttributes );
4490
- assert (data );
4491
- * securityAttributes = NULL ;
4492
- memset (data , 0 , sizeof (* data ));
4493
- return 0 ;
4494
- }
4495
-
4496
- static int
4497
- initializeMkdir700SecurityAttributes (
4498
- PSECURITY_ATTRIBUTES * securityAttributes ,
4499
- struct _Py_SECURITY_ATTRIBUTE_DATA * data
4500
- ) {
4501
- assert (securityAttributes );
4502
- assert (data );
4503
- * securityAttributes = NULL ;
4504
- memset (data , 0 , sizeof (* data ));
4505
-
4506
- if (!InitializeSecurityDescriptor (& data -> sd , SECURITY_DESCRIPTOR_REVISION )
4507
- || !SetSecurityDescriptorGroup (& data -> sd , NULL , TRUE)) {
4508
- return GetLastError ();
4509
- }
4510
-
4511
- int use_alias = 0 ;
4512
- DWORD cbSid = sizeof (data -> sid );
4513
- if (!CreateWellKnownSid (WinCreatorOwnerRightsSid , NULL , (PSID )data -> sid , & cbSid )) {
4514
- use_alias = 1 ;
4515
- }
4516
-
4517
- data -> securityAttributes .nLength = sizeof (SECURITY_ATTRIBUTES );
4518
- data -> ea [0 ].grfAccessPermissions = GENERIC_ALL ;
4519
- data -> ea [0 ].grfAccessMode = SET_ACCESS ;
4520
- data -> ea [0 ].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT ;
4521
- if (use_alias ) {
4522
- data -> ea [0 ].Trustee .TrusteeForm = TRUSTEE_IS_NAME ;
4523
- data -> ea [0 ].Trustee .TrusteeType = TRUSTEE_IS_ALIAS ;
4524
- data -> ea [0 ].Trustee .ptstrName = L"CURRENT_USER" ;
4525
- } else {
4526
- data -> ea [0 ].Trustee .TrusteeForm = TRUSTEE_IS_SID ;
4527
- data -> ea [0 ].Trustee .TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP ;
4528
- data -> ea [0 ].Trustee .ptstrName = (LPWCH )(SID * )data -> sid ;
4529
- }
4530
-
4531
- data -> ea [1 ].grfAccessPermissions = GENERIC_ALL ;
4532
- data -> ea [1 ].grfAccessMode = SET_ACCESS ;
4533
- data -> ea [1 ].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT ;
4534
- data -> ea [1 ].Trustee .TrusteeForm = TRUSTEE_IS_NAME ;
4535
- data -> ea [1 ].Trustee .TrusteeType = TRUSTEE_IS_ALIAS ;
4536
- data -> ea [1 ].Trustee .ptstrName = L"SYSTEM" ;
4537
-
4538
- data -> ea [2 ].grfAccessPermissions = GENERIC_ALL ;
4539
- data -> ea [2 ].grfAccessMode = SET_ACCESS ;
4540
- data -> ea [2 ].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT ;
4541
- data -> ea [2 ].Trustee .TrusteeForm = TRUSTEE_IS_NAME ;
4542
- data -> ea [2 ].Trustee .TrusteeType = TRUSTEE_IS_ALIAS ;
4543
- data -> ea [2 ].Trustee .ptstrName = L"ADMINISTRATORS" ;
4544
-
4545
- int r = SetEntriesInAclW (3 , data -> ea , NULL , & data -> acl );
4546
- if (r ) {
4547
- return r ;
4548
- }
4549
- if (!SetSecurityDescriptorDacl (& data -> sd , TRUE, data -> acl , FALSE)) {
4550
- return GetLastError ();
4551
- }
4552
- data -> securityAttributes .lpSecurityDescriptor = & data -> sd ;
4553
- * securityAttributes = & data -> securityAttributes ;
4554
- return 0 ;
4555
- }
4556
-
4557
- static int
4558
- clearSecurityAttributes (
4559
- PSECURITY_ATTRIBUTES * securityAttributes ,
4560
- struct _Py_SECURITY_ATTRIBUTE_DATA * data
4561
- ) {
4562
- assert (securityAttributes );
4563
- assert (data );
4564
- * securityAttributes = NULL ;
4565
- if (data -> acl ) {
4566
- if (LocalFree ((void * )data -> acl )) {
4567
- return GetLastError ();
4568
- }
4569
- }
4570
- return 0 ;
4571
- }
4572
-
4573
- #endif
4574
-
4575
4434
/*[clinic input]
4576
4435
os.mkdir
4577
4436
@@ -4603,8 +4462,8 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4603
4462
#ifdef MS_WINDOWS
4604
4463
int error = 0 ;
4605
4464
int pathError = 0 ;
4465
+ SECURITY_ATTRIBUTES secAttr = { sizeof (secAttr ) };
4606
4466
SECURITY_ATTRIBUTES * pSecAttr = NULL ;
4607
- struct _Py_SECURITY_ATTRIBUTE_DATA secAttrData ;
4608
4467
#endif
4609
4468
#ifdef HAVE_MKDIRAT
4610
4469
int mkdirat_unavailable = 0 ;
@@ -4617,26 +4476,34 @@ os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4617
4476
4618
4477
#ifdef MS_WINDOWS
4619
4478
Py_BEGIN_ALLOW_THREADS
4620
- switch (mode ) {
4621
- case 0x1C0 : // 0o700
4622
- error = initializeMkdir700SecurityAttributes (& pSecAttr , & secAttrData );
4623
- break ;
4624
- default :
4625
- error = initializeDefaultSecurityAttributes (& pSecAttr , & secAttrData );
4626
- break ;
4479
+ if (mode == 0700 /* 0o700 */ ) {
4480
+ ULONG sdSize ;
4481
+ pSecAttr = & secAttr ;
4482
+ // Set a discreationary ACL (D) that is protected (P) and includes
4483
+ // inheritable (OICI) entries that allow (A) full control (FA) to
4484
+ // SYSTEM (SY), Administrators (BA), and the owner (OW).
4485
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptorW (
4486
+ L"D:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;OW)" ,
4487
+ SDDL_REVISION_1 ,
4488
+ & secAttr .lpSecurityDescriptor ,
4489
+ & sdSize
4490
+ )) {
4491
+ error = GetLastError ();
4492
+ }
4627
4493
}
4628
4494
if (!error ) {
4629
4495
result = CreateDirectoryW (path -> wide , pSecAttr );
4630
- error = clearSecurityAttributes (& pSecAttr , & secAttrData );
4631
- } else {
4632
- // Ignore error from "clear" - we have a more interesting one already
4633
- clearSecurityAttributes (& pSecAttr , & secAttrData );
4496
+ if (secAttr .lpSecurityDescriptor &&
4497
+ // uncommonly, LocalFree returns non-zero on error, but still uses
4498
+ // GetLastError() to see what the error code is
4499
+ LocalFree (secAttr .lpSecurityDescriptor )) {
4500
+ error = GetLastError ();
4501
+ }
4634
4502
}
4635
4503
Py_END_ALLOW_THREADS
4636
4504
4637
4505
if (error ) {
4638
- PyErr_SetFromWindowsErr (error );
4639
- return NULL ;
4506
+ return PyErr_SetFromWindowsErr (error );
4640
4507
}
4641
4508
if (!result ) {
4642
4509
return path_error (path );
0 commit comments