def _set_dacl_inheritance(path, objectType, inheritance=True, copy=True, clear=False): ''' helper function to set the inheritance ''' ret = {'result': False, 'comment': '', 'changes': {}} if path: try: sd = win32security.GetNamedSecurityInfo(path, objectType, win32security.DACL_SECURITY_INFORMATION) tdacl = sd.GetSecurityDescriptorDacl() if inheritance: if clear: counter = 0 removedAces = [] while counter < tdacl.GetAceCount(): tAce = tdacl.GetAce(counter) if (tAce[0][1] & win32security.INHERITED_ACE) != win32security.INHERITED_ACE: tdacl.DeleteAce(counter) removedAces.append(_ace_to_text(tAce, objectType)) else: counter = counter + 1 if removedAces: ret['changes']['Removed ACEs'] = removedAces else: ret['changes']['Non-Inherited ACEs'] = 'Left in the DACL' win32security.SetNamedSecurityInfo( path, objectType, win32security.DACL_SECURITY_INFORMATION | win32security.UNPROTECTED_DACL_SECURITY_INFORMATION, None, None, tdacl, None) ret['changes']['Inheritance'] = 'Enabled' else: if not copy: counter = 0 inheritedAcesRemoved = [] while counter < tdacl.GetAceCount(): tAce = tdacl.GetAce(counter) if (tAce[0][1] & win32security.INHERITED_ACE) == win32security.INHERITED_ACE: tdacl.DeleteAce(counter) inheritedAcesRemoved.append(_ace_to_text(tAce, objectType)) else: counter = counter + 1 if inheritedAcesRemoved: ret['changes']['Removed ACEs'] = inheritedAcesRemoved else: ret['changes']['Previously Inherited ACEs'] = 'Copied to the DACL' win32security.SetNamedSecurityInfo( path, objectType, win32security.DACL_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION, None, None, tdacl, None) ret['changes']['Inheritance'] = 'Disabled' ret['result'] = True except Exception as e: ret['result'] = False ret['comment'] = ( 'Error attempting to set the inheritance. The error was {0}' ).format(e) return ret
def delete_dir_dacl(path): try: dc = daclConstants() objectTypeBit = dc.getObjectTypeBit("DIRECTORY") sd = win32security.GetFileSecurity( path, win32security.DACL_SECURITY_INFORMATION) dacl = sd.GetSecurityDescriptorDacl() counter = 0 while counter < dacl.GetAceCount(): try: rev, access, usersid = dacl.GetAce(counter) user, group, type = win32security.LookupAccountSid('', usersid) except Exception as e: dacl.DeleteAce(counter) counter = counter - 1 counter = counter + 1 try: win32security.SetNamedSecurityInfo( path, objectTypeBit, win32security.DACL_SECURITY_INFORMATION, None, None, dacl, None) return True except Exception as e: return False except: return False
def chown(path, user, group): ''' Chown a file, pass the file the desired user and group CLI Example: .. code-block:: bash salt '*' file.chown c:\\temp\\test.txt myusername administrators ''' err = '' # get SID object for user try: userSID, domainName, objectType = win32security.LookupAccountName(None, user) except pywinerror: err += 'User does not exist\n' # get SID object for group try: groupSID, domainName, objectType = win32security.LookupAccountName(None, group) except pywinerror: err += 'Group does not exist\n' if not os.path.exists(path): err += 'File not found\n' if err: return err # set owner and group securityInfo = win32security.OWNER_SECURITY_INFORMATION + win32security.GROUP_SECURITY_INFORMATION win32security.SetNamedSecurityInfo(path, win32security.SE_FILE_OBJECT, securityInfo, userSID, groupSID, None, None) return None
def removeReadOnlyAccess(path=None): try: if os.path.exists(path): everyone = win32security.CreateWellKnownSid( win32security.WinWorldSid) #Delete ace sd = win32security.GetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION) dacl = sd.GetSecurityDescriptorDacl( ) # instead of dacl = win32security.ACL() #print("Ace count=",dacl.GetAceCount()) num_delete = 0 for index in range(0, dacl.GetAceCount()): ace = dacl.GetAce(index) for index in range(0, dacl.GetAceCount()): ace = dacl.GetAce(index - num_delete) if ace[2] == everyone: dacl.DeleteAce(index - num_delete) num_delete += 1 sd.SetSecurityDescriptorDacl(1, dacl, 0) win32security.SetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl, None) except Exception as err: print("exeption {}".format(str(err)))
def chgrp(path, group): ''' Change the group of a file CLI Example: .. code-block:: bash salt '*' file.chgrp c:\\temp\\test.txt administrators ''' err = '' # get SID object for group try: groupSID, domainName, objectType = win32security.LookupAccountName(None, group) except pywinerror: err += 'Group does not exist\n' if not os.path.exists(path): err += 'File not found\n' if err: return err # set group securityInfo = win32security.GROUP_SECURITY_INFORMATION win32security.SetNamedSecurityInfo(path, win32security.SE_FILE_OBJECT, securityInfo, None, groupSID, None, None) return None
def set_path_owner(path): ''' Sets the owner of a file or directory to be Administrator Args: path (str): The path to the file or directory Returns: bool: True if successful, Otherwise CommandExecutionError ''' # Must use the SID here to be locale agnostic admins = win32security.ConvertStringSidToSid('S-1-5-32-544') try: win32security.SetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION, admins, None, None, None) except pywintypes.error as exc: raise CommandExecutionError( 'Failed to set owner: {0}'.format(exc[2])) return True
def _detect_win_acls(self, dir_rp, write): """ Test if windows access control lists are supported """ assert dir_rp.conn is Globals.local_connection, ( "Action only foreseen locally and not over {conn}.".format( conn=dir_rp.conn)) assert dir_rp.lstat(), "Path '{rp}' must exist to test ACLs.".format( rp=dir_rp) if not Globals.win_acls_active: log.Log( "Windows ACLs test skipped as rdiff-backup was started " "with --no-acls option", log.INFO) self.win_acls = None return try: import win32security import pywintypes except ImportError: log.Log( "Unable to import win32security module. Windows ACLs not " "supported by filesystem at path {pa}".format(pa=dir_rp), log.INFO) self.win_acls = False return try: sd = win32security.GetNamedSecurityInfo( os.fsdecode(dir_rp.path), win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) acl = sd.GetSecurityDescriptorDacl() acl.GetAceCount() # to verify that it works if write: win32security.SetNamedSecurityInfo( os.fsdecode(dir_rp.path), win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION, sd.GetSecurityDescriptorOwner(), sd.GetSecurityDescriptorGroup(), sd.GetSecurityDescriptorDacl(), None) except (OSError, AttributeError, pywintypes.error): log.Log( "Unable to load a Windows ACL. Windows ACLs not supported " "by filesystem at path {pa}".format(pa=dir_rp), log.INFO) self.win_acls = False return try: acl_win.init_acls() # FIXME there should be no cross-dependency except (OSError, AttributeError, pywintypes.error): log.Log( "Unable to init win_acls. Windows ACLs not supported by " "filesystem at path {pa}".format(pa=dir_rp), log.INFO) self.win_acls = False return self.win_acls = True
def restore_access(filepath): win32security.SetNamedSecurityInfo( filepath, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.UNPROTECTED_DACL_SECURITY_INFORMATION | win32security.SACL_SECURITY_INFORMATION | win32security.UNPROTECTED_SACL_SECURITY_INFORMATION, None, None, win32security.ACL(), win32security.ACL())
def SetSecurity(self, requestedinfo, sd): """Applies permissions to the object""" owner=sd.GetSecurityDescriptorOwner() group=sd.GetSecurityDescriptorGroup() dacl=sd.GetSecurityDescriptorDacl() sacl=sd.GetSecurityDescriptorSacl() win32security.SetNamedSecurityInfo(self.ServiceName, win32security.SE_SERVICE, requestedinfo, owner, group, dacl, sacl)
def chpgrp(path, group): ''' Change the group of a file Under Windows, this will set the rarely used primary group of a file. This generally has no bearing on permissions unless intentionally configured and is most commonly used to provide Unix compatibility (e.g. Services For Unix, NFS services). Ensure you know what you are doing before using this function. To set the primary group to 'None', it must be specified in quotes. Otherwise Salt will interpret it as the Python value of None and no primary group changes will occur. See the example below. CLI Example: .. code-block:: bash salt '*' file.chpgrp c:\\temp\\test.txt Administrators salt '*' file.chpgrp c:\\temp\\test.txt "'None'" ''' if group is None: raise SaltInvocationError("The group value was specified as None and " "is invalid. If you mean the built-in None " "group, specify the group in lowercase, e.g. " "'none'.") err = '' # get SID object for group try: groupSID, domainName, objectType = win32security.LookupAccountName(None, group) except pywinerror: err += 'Group does not exist\n' if not os.path.exists(path): err += 'File not found\n' if err: return err # set group privilege_enabled = False try: privilege_enabled = _enable_privilege(win32security.SE_RESTORE_NAME) win32security.SetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.GROUP_SECURITY_INFORMATION, None, groupSID, None, None ) finally: if privilege_enabled: _disable_privilege(win32security.SE_RESTORE_NAME) return None
def _detect_win_acls(self, dir_rp, write): """Test if windows access control lists are supported""" assert dir_rp.conn is Globals.local_connection, ( "Action only foreseen locally and not over {conn}.".format( conn=dir_rp.conn)) assert dir_rp.lstat(), "Path '{rp!s}' must exist to test ACLs.".format( rp=dir_rp) if Globals.win_acls_active == 0: log.Log( "Windows ACLs test skipped. rdiff-backup run " "with --no-acls option.", 4) self.win_acls = 0 return try: import win32security import pywintypes except ImportError: log.Log( "Unable to import win32security module. Windows ACLs\n" "not supported by filesystem at %s" % dir_rp.get_safepath(), 4) self.win_acls = 0 return try: sd = win32security.GetNamedSecurityInfo( os.fsdecode(dir_rp.path), win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) acl = sd.GetSecurityDescriptorDacl() acl.GetAceCount() # to verify that it works if write: win32security.SetNamedSecurityInfo( os.fsdecode(dir_rp.path), win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION, sd.GetSecurityDescriptorOwner(), sd.GetSecurityDescriptorGroup(), sd.GetSecurityDescriptorDacl(), None) except (OSError, AttributeError, pywintypes.error): log.Log( "Unable to load a Windows ACL.\nWindows ACLs not supported " "by filesystem at %s" % dir_rp.get_safepath(), 4) self.win_acls = 0 return try: win_acls.init_acls() except (OSError, AttributeError, pywintypes.error): log.Log( "Unable to init win_acls.\nWindows ACLs not supported by " "filesystem at %s" % dir_rp.get_safepath(), 4) self.win_acls = 0 return self.win_acls = 1
def createDir(subpath, temp_tpath): dacl = win32security.GetNamedSecurityInfo( subpath, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION).GetSecurityDescriptorDacl() if not os.path.exists(temp_tpath): os.makedirs(temp_tpath) win32security.SetNamedSecurityInfo( temp_tpath, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl, None) return dacl
def setUpSACL(self): sacl = win32security.ACL() sid, _, _ = win32security.LookupAccountName(None, win32api.GetUserName()) sacl.AddAuditAccessAceEx( win32security.ACL_REVISION_DS, win32security.OBJECT_INHERIT_ACE | win32security.CONTAINER_INHERIT_ACE, ntsecuritycon.FILE_ALL_ACCESS, sid, 1, 1) win32security.SetNamedSecurityInfo( self.TEST_ROOT, win32security.SE_FILE_OBJECT, win32security.SACL_SECURITY_INFORMATION, None, None, None, sacl)
def set_win_acls(self, dir_rp, write): """Test if windows access control lists are supported""" assert Globals.local_connection is dir_rp.conn assert dir_rp.lstat() if Globals.win_acls_active == 0: log.Log( "Windows ACLs test skipped. rdiff-backup run " "with --no-acls option.", 4) self.win_acls = 0 return try: import win32security, pywintypes except ImportError: log.Log( "Unable to import win32security module. Windows ACLs\n" "not supported by filesystem at %s" % dir_rp.path, 4) self.win_acls = 0 return try: sd = win32security.GetNamedSecurityInfo( dir_rp.path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) acl = sd.GetSecurityDescriptorDacl() n = acl.GetAceCount() if write: win32security.SetNamedSecurityInfo( dir_rp.path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION, sd.GetSecurityDescriptorOwner(), sd.GetSecurityDescriptorGroup(), sd.GetSecurityDescriptorDacl(), None) except (OSError, AttributeError, pywintypes.error): log.Log( "Unable to load a Windows ACL.\nWindows ACLs not supported " "by filesystem at %s" % dir_rp.path, 4) self.win_acls = 0 return try: win_acls.init_acls() except (OSError, AttributeError, pywintypes.error): log.Log( "Unable to init win_acls.\nWindows ACLs not supported by " "filesystem at %s" % dir_rp.path, 4) self.win_acls = 0 return self.win_acls = 1
def setUp(self): testutils.change_priv(win32security.SE_SECURITY_NAME, True) self.filehandle, self.filename = tempfile.mkstemp() dacl = win32security.ACL() dacl.AddAccessAllowedAceEx(win32security.ACL_REVISION_DS, 0, ntsecuritycon.FILE_READ_DATA, everyone) sacl = win32security.ACL() sacl.AddAuditAccessAce(win32security.ACL_REVISION_DS, ntsecuritycon.FILE_READ_DATA, everyone, 1, 1) win32security.SetNamedSecurityInfo( self.filename, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.SACL_SECURITY_INFORMATION, None, None, dacl, sacl)
def save(self, obj_name, protected=None): ''' Save the DACL obj_name (str): The object for which to set permissions. This can be the path to a file or folder, a registry key, printer, etc. For more information about how to format the name see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx protected (Optional[bool]): True will disable inheritance for the object. False will enable inheritance. None will make no change. Default is None. Returns: bool: True if successful, Otherwise raises an exception Usage: .. code-block:: python dacl = Dacl(obj_type='file') dacl.save('C:\\Temp', True) ''' sec_info = self.element['dacl'] if protected is not None: if protected: sec_info = sec_info | self.inheritance['protected'] else: sec_info = sec_info | self.inheritance['unprotected'] if self.dacl_type in ['registry', 'registry32']: obj_name = self.get_reg_name(obj_name) try: win32security.SetNamedSecurityInfo( obj_name, self.obj_type[self.dacl_type], sec_info, None, None, self.dacl, None) except pywintypes.error as exc: raise CommandExecutionError( 'Failed to set permissions: {0}'.format(exc[2])) return True
def run(self, entries): try: sd = win32security.GetNamedSecurityInfo( self.file, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION) dacl = sd.GetSecurityDescriptorDacl() dacl.SetEntriesInAcl(entries) win32security.SetNamedSecurityInfo( self.file, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.UNPROTECTED_DACL_SECURITY_INFORMATION, None, None, dacl, None) except Exception as err: exc_type, exc_obj, exc_tb = sys.exc_info() self.log.error( "perms.run failed\n%s, %s, %s, %s" % (err, exc_type, exc_obj, traceback.print_tb(exc_tb)))
def _SetFileSecurity(username, fname, rights, inherit_flags=None): import win32security import pywintypes import ntsecuritycon # Returns None if no user, True if changed, False if already had # rights. if inherit_flags is None: inherit_flags = ( ntsecuritycon.CONTAINER_INHERIT_ACE | ntsecuritycon.OBJECT_INHERIT_ACE # child objects inherit? ) # Overload the 'username' param - allow it to already be a SID. if isinstance(username, pywintypes.SIDType): user_sid = username else: try: user_sid = win32security.LookupAccountName(None, username)[0] except win32security.error: return None sd = win32security.GetNamedSecurityInfo( fname, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION) # Walk the dacl, looking for this entry. Could maybe use # GetEffectiveRightsFromACL but that doesn't seem to give inherit # info. dacl = sd.GetSecurityDescriptorDacl() for i in range(dacl.GetAceCount()): ace = dacl.GetAce(i) ace_type, flags = ace[0] sid = ace[-1] if (ace_type == win32security.ACCESS_ALLOWED_ACE_TYPE and flags & inherit_flags == inherit_flags and ace[1] == rights and sid == user_sid): return False dacl.AddAccessAllowedAceEx(dacl.GetAclRevision(), inherit_flags, rights, user_sid) sd = win32security.SetNamedSecurityInfo( fname, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl, None) return True
def RemoveWriteDAC(fname): try: win32file.DeleteFile(fname) except: pass my_dacl = "D:(D;;WD;;;SY)(A;;GA;;;WD)" se_obj = MakeDaclStringToSeObj(my_dacl) fdacl = se_obj.GetSecurityDescriptorDacl() in_se_attr = win32security.SECURITY_ATTRIBUTES() in_se_attr.SECURITY_DESCRIPTOR = se_obj ret = win32security.SetNamedSecurityInfo(fname, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION, my_sid, my_sid, fdacl, None) if ret == None: print '[*] Removed WriteDAC for System.' else: print '[!] Error while removing WriteDAC for System.'
def set_path_permissions(path): ''' Gives Administrators, System, and Owner full control over the specified directory Args: path (str): The path to the file or directory Returns: bool: True if successful, Otherwise CommandExecutionError ''' # TODO: Need to make this more generic, maybe a win_dacl utility admins = win32security.ConvertStringSidToSid('S-1-5-32-544') user = win32security.ConvertStringSidToSid('S-1-5-32-545') system = win32security.ConvertStringSidToSid('S-1-5-18') owner = win32security.ConvertStringSidToSid('S-1-3-4') dacl = win32security.ACL() revision = win32security.ACL_REVISION_DS inheritance = win32security.CONTAINER_INHERIT_ACE |\ win32security.OBJECT_INHERIT_ACE full_access = ntsecuritycon.GENERIC_ALL user_access = ntsecuritycon.GENERIC_READ | \ ntsecuritycon.GENERIC_EXECUTE dacl.AddAccessAllowedAceEx(revision, inheritance, full_access, admins) dacl.AddAccessAllowedAceEx(revision, inheritance, full_access, system) dacl.AddAccessAllowedAceEx(revision, inheritance, full_access, owner) if 'pki' not in path: dacl.AddAccessAllowedAceEx(revision, inheritance, user_access, user) try: win32security.SetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.DACL_SECURITY_INFORMATION | win32security.PROTECTED_DACL_SECURITY_INFORMATION, None, None, dacl, None) except pywintypes.error as exc: raise CommandExecutionError('Failed to set permissions: {0}'.format( exc[2])) return True
def _AllowNamedObjectAccess(sid, name: str, object_type: int, access_permissions: int) -> None: """Allows access to a named object. Args: sid: A `PySID` representing the SID to grant access to. name: Name of the object. object_type: A `SE_OBJECT_TYPE` enum value. access_permissions: The permissions as a set of biflags using the `ACCESS_MASK` format. """ info = win32security.GetNamedSecurityInfo( name, object_type, win32security.DACL_SECURITY_INFORMATION) dacl = info.GetSecurityDescriptorDacl() _AddPermissionToDacl(dacl, sid, access_permissions) win32security.SetNamedSecurityInfo( name, object_type, win32security.DACL_SECURITY_INFORMATION | win32security.UNPROTECTED_DACL_SECURITY_INFORMATION, None, None, dacl, None)
def add_level1_authority(path, Basic_authority, manager): ''' :param path: 文件路径 :param Basic_authority: 初始权限;(建议 Authenticated Users) :param manager: 管理权限账号 :return: ''' try: disable_inheritances = disable_inheritance(path, "DIRECTORY") # 禁用继承 add_ace_man = add_ace(path, 'DIRECTORY', manager, 'FULLCONTROL', 'ALLOW', 'FOLDER&SUBFOLDERS&FILES') dc = daclConstants() objectTypeBit = dc.getObjectTypeBit("DIRECTORY") sd = win32security.GetFileSecurity( path, win32security.DACL_SECURITY_INFORMATION) dacl = sd.GetSecurityDescriptorDacl() counter = 0 while counter < dacl.GetAceCount(): try: rev, access, usersid = dacl.GetAce(counter) user, group, type = win32security.LookupAccountSid('', usersid) if not (('administrator' in user) or ("SYSTEM" in user) or (manager in user) or ('Administrator' in user)): dacl.DeleteAce(counter) counter = counter - 1 except Exception as e: dacl.DeleteAce(counter) counter = counter - 1 counter = counter + 1 try: win32security.SetNamedSecurityInfo( path, objectTypeBit, win32security.DACL_SECURITY_INFORMATION, None, None, dacl, None) except Exception as e: print(e) add_ace_user = add_ace(path, 'DIRECTORY', Basic_authority, 'READ', 'ALLOW', 'THIS FOLDER ONLY') print(add_ace_user) return add_ace_user['result'] except Exception as e: print(e) return False
def setUp(self): # # If you don't enable SeSecurity, you won't be able to # read SACL in this process. # utils.change_priv(win32security.SE_SECURITY_NAME, True) self.GUID = str(uuid.uuid1()) self.TEST_ROOT = tempfile.mkdtemp(prefix="winsys-") assert os.path.isdir(self.TEST_ROOT) sacl = win32security.ACL() sid, _, _ = win32security.LookupAccountName(None, win32api.GetUserName()) sacl.AddAuditAccessAceEx( win32security.ACL_REVISION_DS, win32security.OBJECT_INHERIT_ACE | win32security.CONTAINER_INHERIT_ACE, ntsecuritycon.FILE_ALL_ACCESS, sid, 1, 1) win32security.SetNamedSecurityInfo( self.TEST_ROOT, win32security.SE_FILE_OBJECT, win32security.SACL_SECURITY_INFORMATION, None, None, None, sacl)
def setup(): # # If you don't enable SeSecurity, you won't be able to # read SACL in this process. # utils.change_priv(win32security.SE_SECURITY_NAME, True) assert os.path.isdir(TEST_ROOT) sacl = win32security.ACL() sid, _, _ = win32security.LookupAccountName(None, win32api.GetUserName()) sacl.AddAuditAccessAceEx( win32security.ACL_REVISION_DS, win32security.OBJECT_INHERIT_ACE | win32security.CONTAINER_INHERIT_ACE, ntsecuritycon.FILE_ALL_ACCESS, sid, 1, 1) win32security.SetNamedSecurityInfo(TEST_ROOT, win32security.SE_FILE_OBJECT, win32security.SACL_SECURITY_INFORMATION, None, None, None, sacl) open(TEST_FILE, "w").close() os.mkdir(TEST1_DIR) open(TEST1_FILE, "w").close() os.mkdir(TEST2_DIR) open(TEST2_FILE, "w").close()
def set_owner(obj_name, principal, obj_type='file'): ''' Set the owner of an object. This can be a file, folder, registry key, printer, service, etc... Args: obj_name (str): The object for which to set owner. This can be the path to a file or folder, a registry key, printer, etc. For more information about how to format the name see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx principal (str): The name of the user or group to make owner of the object. Can also pass a SID. obj_type (Optional[str]): The type of object for which to set the owner. Returns: bool: True if successful, raises an error otherwise Usage: .. code-block:: python salt.utils.win_dacl.set_owner('C:\\MyDirectory', 'jsnuffy', 'file') ''' sid = get_sid(principal) flags = Flags() # Set the user try: win32security.SetNamedSecurityInfo(obj_name, flags.obj_type[obj_type], flags.element['owner'], sid, None, None, None) except pywintypes.error as exc: raise CommandExecutionError('Failed to set owner: {0}'.format(exc[2])) return True
def chown(path, user, group=None, pgroup=None, follow_symlinks=True): ''' Chown a file, pass the file the desired user and group Under Windows, the group parameter will be ignored. This is because while files in Windows do have a 'primary group' property, this is rarely used. It generally has no bearing on permissions unless intentionally configured and is most commonly used to provide Unix compatibility (e.g. Services For Unix, NFS services). If you do want to change the 'primary group' property and understand the implications, pass the Windows only parameter, pgroup, instead. To set the primary group to 'None', it must be specified in quotes. Otherwise Salt will interpret it as the Python value of None and no primary group changes will occur. See the example below. CLI Example: .. code-block:: bash salt '*' file.chown c:\\temp\\test.txt myusername salt '*' file.chown c:\\temp\\test.txt myusername pgroup=Administrators salt '*' file.chown c:\\temp\\test.txt myusername "pgroup='None'" ''' # the group parameter is not used; only provided for API compatibility if group: func_name = '{0}.chown'.format(__virtualname__) if __opts__.get('fun', '') == func_name: log.info('The group parameter has no effect when using {0} on Windows ' 'systems; see function docs for details.'.format(func_name)) log.debug( 'win_file.py {0} Ignoring the group parameter for {1}'.format( func_name, path ) ) group = None err = '' # get SID object for user try: userSID, domainName, objectType = win32security.LookupAccountName(None, user) except pywinerror: err += 'User does not exist\n' if pgroup: # get SID object for group try: groupSID, domainName, objectType = win32security.LookupAccountName(None, pgroup) except pywinerror: err += 'Group does not exist\n' else: groupSID = None if not os.path.exists(path): err += 'File not found' if err: return err if follow_symlinks and sys.getwindowsversion().major >= 6: path = _resolve_symlink(path) privilege_enabled = False try: privilege_enabled = _enable_privilege(win32security.SE_RESTORE_NAME) if pgroup: # set owner and group win32security.SetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION + win32security.GROUP_SECURITY_INFORMATION, userSID, groupSID, None, None ) else: # set owner only win32security.SetNamedSecurityInfo( path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION, userSID, None, None, None ) finally: if privilege_enabled: _disable_privilege(win32security.SE_RESTORE_NAME) return None
sd=win32security.GetNamedSecurityInfo(fname,win32security.SE_FILE_OBJECT,all_info) dacl=sd.GetSecurityDescriptorDacl() if dacl is None: dacl=win32security.ACL() sacl=sd.GetSecurityDescriptorSacl() if sacl is None: sacl=win32security.ACL() dacl_ace_cnt=dacl.GetAceCount() sacl_ace_cnt=sacl.GetAceCount() dacl.AddAccessAllowedAce(dacl.GetAclRevision(),win32con.ACCESS_SYSTEM_SECURITY|win32con.WRITE_DAC,my_sid) sacl.AddAuditAccessAce(sacl.GetAclRevision(),win32con.GENERIC_ALL,my_sid,1,1) win32security.SetNamedSecurityInfo(fname,win32security.SE_FILE_OBJECT,all_info,pwr_sid, pwr_sid, dacl, sacl) new_sd=win32security.GetNamedSecurityInfo(fname,win32security.SE_FILE_OBJECT,all_info) ## could do additional checking to make sure added ACE contains expected info if new_sd.GetSecurityDescriptorDacl().GetAceCount()!=dacl_ace_cnt+1: print('New dacl doesn''t contain extra ace ????') if new_sd.GetSecurityDescriptorSacl().GetAceCount()!=sacl_ace_cnt+1: print('New Sacl doesn''t contain extra ace ????') if win32security.LookupAccountSid('',new_sd.GetSecurityDescriptorOwner())[0]!='Power Users': print('Owner not successfully set to Power Users !!!!!') if win32security.LookupAccountSid('',new_sd.GetSecurityDescriptorGroup())[0]!='Power Users': print('Group not successfully set to Power Users !!!!!') win32security.SetNamedSecurityInfo(fname,win32security.SE_FILE_OBJECT,win32security.SACL_SECURITY_INFORMATION, None, None, None, None) new_sd_1=win32security.GetNamedSecurityInfo(fname,win32security.SE_FILE_OBJECT,win32security.SACL_SECURITY_INFORMATION) if new_sd_1.GetSecurityDescriptorSacl() is not None:
everyone_sid, ) ## make sure current user has permissions on dir dir_dacl.AddAccessAllowedAceEx( ACL_REVISION_DS, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, win32con.GENERIC_ALL, my_sid, ) ## keep dir from inheriting any permissions so it only has ACEs explicitely set here win32security.SetNamedSecurityInfo( dir_name, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION, pwr_sid, pwr_sid, dir_dacl, None, ) ## Create a file in the dir and add some specific permissions to it fname = win32api.GetTempFileName(dir_name, "sfa")[0] print(fname) file_sd = win32security.GetNamedSecurityInfo( fname, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ) file_dacl = file_sd.GetSecurityDescriptorDacl() file_sacl = file_sd.GetSecurityDescriptorSacl()
def set_owner(obj_name, principal, obj_type='file'): ''' Set the owner of an object. This can be a file, folder, registry key, printer, service, etc... Args: obj_name (str): The object for which to set owner. This can be the path to a file or folder, a registry key, printer, etc. For more information about how to format the name see: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379593(v=vs.85).aspx principal (str): The name of the user or group to make owner of the object. Can also pass a SID. obj_type (Optional[str]): The type of object for which to set the owner. Returns: bool: True if successful, raises an error otherwise Usage: .. code-block:: python salt.utils.win_dacl.set_owner('C:\\MyDirectory', 'jsnuffy', 'file') ''' sid = get_sid(principal) flags = Flags() # 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)) # 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) # Set the user try: win32security.SetNamedSecurityInfo( obj_name, flags.obj_type[obj_type], flags.element['owner'], sid, None, None, None) except pywintypes.error as exc: log.debug('Failed to make {0} the owner: {1}'.format(principal, exc[2])) raise CommandExecutionError( 'Failed to set owner: {0}'.format(exc[2])) return True
def rm_ace(path, objectType, user, permission, acetype, propagation): r''' remove an ace to an object path: path to the object (i.e. c:\\temp\\file, HKEY_LOCAL_MACHINE\\SOFTWARE\\KEY, etc) user: user to remove permission: permissions for the user acetypes: either allow/deny for each user/permission (ALLOW, DENY) propagation: how the ACE applies to children for Registry Keys and Directories(KEY, KEY&SUBKEYS, SUBKEYS) ***The entire ACE must match to be removed*** CLI Example: .. code-block:: bash remove allow domain\fakeuser full control on HKLM\\SOFTWARE\\somekey propagated to this key and subkeys salt 'myminion' win_dacl.rm_ace 'Registry' 'HKEY_LOCAL_MACHINE\\SOFTWARE\\somekey' 'domain\fakeuser' 'FULLCONTROL' 'ALLOW' 'KEY&SUBKEYS' ''' ret = {'result': None, 'changes': {}, 'comment': []} if (path and user and permission and acetype and propagation): dc = daclConstants() if objectType.upper() == "FILE": propagation = "FILE" objectTypeBit = dc.getObjectTypeBit(objectType) path = dc.processPath(path, objectTypeBit) u = User() user = user.strip() permission = permission.strip().upper() acetype = acetype.strip().upper() propagation = propagation.strip().upper() if check_ace(path, objectType, user, permission, acetype, propagation, True)['Exists']: thisSid = getattr(u, user) permissionbit = dc.getPermissionBit(objectTypeBit, permission) acetypebit = dc.getAceTypeBit(acetype) propagationbit = dc.getPropagationBit(objectTypeBit, propagation) dacl = _get_dacl(path, objectTypeBit) counter = 0 acesRemoved = [] if objectTypeBit == win32security.SE_FILE_OBJECT: if check_inheritance(path, objectType)['Inheritance']: if permission == 'FULLCONTROL': # if inhertiance is enabled on an SE_FILE_OBJECT, then the SI_NO_ACL_PROTECT # gets unset on FullControl which greys out the include inheritable permission # checkbox on the advanced security settings gui page permissionbit = permissionbit ^ ntsecuritycon.SI_NO_ACL_PROTECT while counter < dacl.GetAceCount(): tAce = dacl.GetAce(counter) if (tAce[0][1] & win32security.INHERITED_ACE ) != win32security.INHERITED_ACE: if tAce[2] == thisSid: if tAce[0][0] == acetypebit: if (tAce[0][1] & propagationbit) == propagationbit: if tAce[1] == permissionbit: dacl.DeleteAce(counter) counter = counter - 1 acesRemoved.append( ('{0} {1} {2} on {3}').format( user, dc.getAceTypeText(acetype), dc.getPermissionText( objectTypeBit, permission), dc.getPropagationText( objectTypeBit, propagation))) counter = counter + 1 if acesRemoved: try: win32security.SetNamedSecurityInfo( path, objectTypeBit, win32security.DACL_SECURITY_INFORMATION, None, None, dacl, None) ret['changes']['Removed ACEs'] = acesRemoved ret['result'] = True except Exception as e: ret['result'] = False ret['comment'].append( ('Error removing ACE. The error was {0}').format(e)) return ret else: ret['comment'].append( ('The specified ACE was not found on the path')) return ret