Merge pull request #50290 from twangboy/fix_test_state

Fix `test_state` for Windows
This commit is contained in:
Mike Place 2018-10-31 20:28:33 +01:00 committed by GitHub
commit af1075b26d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 171 additions and 3 deletions

View File

@ -122,11 +122,11 @@ class _AtomicWFile(object):
return return
self._fh.close() self._fh.close()
if os.path.isfile(self._filename): if os.path.isfile(self._filename):
shutil.copymode(self._filename, self._tmp_filename)
if salt.utils.win_dacl.HAS_WIN32: if salt.utils.win_dacl.HAS_WIN32:
owner = salt.utils.win_dacl.get_owner(self._filename) salt.utils.win_dacl.copy_security(
salt.utils.win_dacl.set_owner(self._tmp_filename, owner) source=self._filename, target=self._tmp_filename)
else: else:
shutil.copymode(self._filename, self._tmp_filename)
st = os.stat(self._filename) st = os.stat(self._filename)
os.chown(self._tmp_filename, st.st_uid, st.st_gid) os.chown(self._tmp_filename, st.st_uid, st.st_gid)
atomic_rename(self._tmp_filename, self._filename) atomic_rename(self._tmp_filename, self._filename)

View File

@ -1689,3 +1689,171 @@ def get_inheritance(obj_name, obj_type='file'):
return True return True
return False return False
def copy_security(source,
target,
obj_type='file',
copy_owner=True,
copy_group=True,
copy_dacl=True,
copy_sacl=True):
r'''
Copy the security descriptor of the Source to the Target. You can specify a
specific portion of the security descriptor to copy using one of the
`copy_*` parameters.
.. note::
At least one `copy_*` parameter must be ``True``
.. note::
The user account running this command must have the following
privileges:
- SeTakeOwnershipPrivilege
- SeRestorePrivilege
- SeSecurityPrivilege
Args:
source (str):
The full path to the source. This is where the security info will be
copied from
target (str):
The full path to the target. This is where the security info will be
applied
obj_type (str): file
The type of object to query. This value changes the format of the
``obj_name`` parameter as follows:
- file: indicates a file or directory
- a relative path, such as ``FileName.txt`` or ``..\FileName``
- an absolute path, such as ``C:\DirName\FileName.txt``
- A UNC name, such as ``\\ServerName\ShareName\FileName.txt``
- service: indicates the name of a Windows service
- printer: indicates the name of a printer
- registry: indicates a registry key
- Uses the following literal strings to denote the hive:
- HKEY_LOCAL_MACHINE
- MACHINE
- HKLM
- HKEY_USERS
- USERS
- HKU
- HKEY_CURRENT_USER
- CURRENT_USER
- HKCU
- HKEY_CLASSES_ROOT
- CLASSES_ROOT
- HKCR
- Should be in the format of ``HIVE\Path\To\Key``. For example,
``HKLM\SOFTWARE\Windows``
- registry32: indicates a registry key under WOW64. Formatting is
the same as it is for ``registry``
- share: indicates a network share
copy_owner (bool): True
``True`` copies owner information. Default is ``True``
copy_group (bool): True
``True`` copies group information. Default is ``True``
copy_dacl (bool): True
``True`` copies the DACL. Default is ``True``
copy_sacl (bool): True
``True`` copies the SACL. Default is ``True``
Returns:
bool: ``True`` if successful
Raises:
SaltInvocationError: When parameters are invalid
CommandExecutionError: On failure to set security
Usage:
.. code-block:: python
salt.utils.win_dacl.copy_security(
source='C:\\temp\\source_file.txt',
target='C:\\temp\\target_file.txt',
obj_type='file')
salt.utils.win_dacl.copy_security(
source='HKLM\\SOFTWARE\\salt\\test_source',
target='HKLM\\SOFTWARE\\salt\\test_target',
obj_type='registry',
copy_owner=False)
'''
obj_dacl = dacl(obj_type=obj_type)
if 'registry' in obj_type.lower():
source = obj_dacl.get_reg_name(source)
log.info('Source converted to: %s', source)
target = obj_dacl.get_reg_name(target)
log.info('Target converted to: %s', target)
# Set flags
try:
obj_type_flag = flags().obj_type[obj_type.lower()]
except KeyError:
raise SaltInvocationError(
'Invalid "obj_type" passed: {0}'.format(obj_type))
security_flags = 0
if copy_owner:
security_flags |= win32security.OWNER_SECURITY_INFORMATION
if copy_group:
security_flags |= win32security.GROUP_SECURITY_INFORMATION
if copy_dacl:
security_flags |= win32security.DACL_SECURITY_INFORMATION
if copy_sacl:
security_flags |= win32security.SACL_SECURITY_INFORMATION
if not security_flags:
raise SaltInvocationError(
'One of copy_owner, copy_group, copy_dacl, or copy_sacl must be '
'True')
# To set the owner to something other than the logged in user requires
# SE_TAKE_OWNERSHIP_NAME and SE_RESTORE_NAME privileges
# Enable them for the logged in user
# Setup the privilege set
new_privs = set()
luid = win32security.LookupPrivilegeValue('', 'SeTakeOwnershipPrivilege')
new_privs.add((luid, win32con.SE_PRIVILEGE_ENABLED))
luid = win32security.LookupPrivilegeValue('', 'SeRestorePrivilege')
new_privs.add((luid, win32con.SE_PRIVILEGE_ENABLED))
luid = win32security.LookupPrivilegeValue('', 'SeSecurityPrivilege')
new_privs.add((luid, win32con.SE_PRIVILEGE_ENABLED))
# Get the current token
p_handle = win32api.GetCurrentProcess()
t_handle = win32security.OpenProcessToken(
p_handle,
win32security.TOKEN_ALL_ACCESS | win32con.TOKEN_ADJUST_PRIVILEGES)
# Enable the privileges
win32security.AdjustTokenPrivileges(t_handle, 0, new_privs)
# Load object Security Info from the Source
sec = win32security.GetNamedSecurityInfo(
source, obj_type_flag, security_flags)
# The following return None if the corresponding flag is not set
sd_sid = sec.GetSecurityDescriptorOwner()
sd_gid = sec.GetSecurityDescriptorGroup()
sd_dacl = sec.GetSecurityDescriptorDacl()
sd_sacl = sec.GetSecurityDescriptorSacl()
# Set Security info on the target
try:
win32security.SetNamedSecurityInfo(
target, obj_type_flag, security_flags, sd_sid, sd_gid, sd_dacl,
sd_sacl)
except pywintypes.error as exc:
raise CommandExecutionError(
'Failed to set security info: {0}'.format(exc.strerror))
return True