Eryk Sun <eryk...@gmail.com> added the comment:

> It might be that Python is the first/only MSI that the user 
> has tried though?

It's likely the first per-user MSI install attempted since the security of the 
"Installer" directory was modified. There's no problem with a per-machine 
install.

> did your change reproduce the "Error: 0"? 

It's the same "Could not set file security for file... Error: 0" dialog, which 
is created by the python-3.9.0.exe child process that executes from a copy in 
%TEMP%. 

In Process Monitor, I see the actual access-denied error due to the installer 
service trying to open the directory with WRITE_DAC and WRITE_OWNER access.

If I also remove the Everyone group that grants read and execute access, the 
installer service fails at an earlier step, which results in an 0x80070643 
fatal installation error.

> It sounds like just resetting the owner isn't enough on its own, 
> but the inherited ACLs should include SYSTEM and not prevent it 
> from working. 

The security descriptor that the installer service sets prevents inheritance of 
discretionary access control entries (i.e. the DACL is protected):

    >>> sd = GetFileSecurity('Installer', DACL_SECURITY_INFORMATION)
    >>> sd.GetSecurityDescriptorControl()[0] & SE_DACL_PROTECTED
    4096

Thus the entries in the ACL for SYSTEM and Administrators groups are set 
explicitly instead of inherited from the parent directory. If something else 
rewrites the security on the directory, it can just as easily protect the DACL 
from inheritance.

In my first experiment, I had left the entry for Everyone (WD) in the DACL, 
but, as mentioned above, it turns out that it's required at an earlier step. So 
a fix has to also add it back:

    >icacls "%APPDATA%\Microsoft\Installer" /grant:r *WD:(OI)(CI)(RX)

Also, in my first message, I manually re-added the SYSTEM and Administrators 
entries unnecessarily -- though it doesn't hurt to do so. It turns out that all 
the service needs is for the directory's owner to be set back to the 
Administrators group. Then it implicitly has WRITE_DAC access. It gets 
WRITE_OWNER access as well, even though the file security at the time doesn't 
grant it (the owner of an object does not implicitly have WRITE_OWNER access to 
it), so presumably the service is temporarily enabling SeTakeOwnershipPrivilege 
for the process or thread.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41961>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to