def chown(path, user, group): ''' Chown a file, pass the file the desired user and group CLI Example:: salt '*' file.chown c:\\temp\\test.txt myusername administrators ''' # I think this function isn't working correctly yet sd = win32security.GetFileSecurity (path, win32security.DACL_SECURITY_INFORMATION) uid = user_to_uid(user) gid = group_to_gid(group) err = '' if uid == '': err += 'User does not exist\n' if gid == '': err += 'Group does not exist\n' if not os.path.exists(path): err += 'File not found' if err: return err dacl = win32security.ACL () dacl.AddAccessAllowedAce (win32security.ACL_REVISION, con.FILE_ALL_ACCESS, win32security.GetBinarySid(uid)) dacl.AddAccessAllowedAce (win32security.ACL_REVISION, con.FILE_ALL_ACCESS, win32security.GetBinarySid(gid)) sd.SetSecurityDescriptorDacl (1, dacl, 0) return win32security.SetFileSecurity (path, win32security.DACL_SECURITY_INFORMATION, sd)
def _getUserSid(user): ''' return a state error dictionary, with 'sid' as a field if it could be returned if user is None, sid will also be None ''' ret = {} sid_pattern = r'^S-1(-\d+){1,}$' if user and re.match(sid_pattern, user, re.I): try: sid = win32security.GetBinarySid(user) except Exception as e: ret['result'] = False ret['comment'] = 'Unable to obtain the binary security identifier for {0}. The exception was {1}.'.format( user, e) else: try: win32security.LookupAccountSid('', sid) ret['result'] = True ret['sid'] = sid except Exception as e: ret['result'] = False ret['comment'] = 'Unable to lookup the account for the security identifier {0}. The exception was {1}.'.format( user, e) else: try: sid = win32security.LookupAccountName('', user)[0] if user else None ret['result'] = True ret['sid'] = sid except Exception as e: ret['result'] = False ret['comment'] = 'Unable to obtain the security identifier for {0}. The exception was {1}.'.format( user, e) return ret
def preConnect(self, userName: str, protocol: str, ip: str, hostname: str) -> str: logger.debug('Pre connect invoked') if protocol == 'rdp': # If connection is not using rdp, skip adding user # Well known SSID for Remote Desktop Users groupName = win32security.LookupAccountSid(None, win32security.GetBinarySid(REMOTE_USERS_SID))[0] useraAlreadyInGroup = False resumeHandle = 0 while True: users, _, resumeHandle = win32net.NetLocalGroupGetMembers(None, groupName, 1, resumeHandle, 32768) if userName.lower() in [u['name'].lower() for u in users]: useraAlreadyInGroup = True break if resumeHandle == 0: break if not useraAlreadyInGroup: logger.debug('User not in group, adding it') self._user = userName try: userSSID = win32security.LookupAccountName(None, userName)[0] win32net.NetLocalGroupAddMembers(None, groupName, 0, [{'sid': userSSID}]) except Exception as e: logger.error('Exception adding user to Remote Desktop Users: {}'.format(e)) else: self._user = None logger.debug('User {} already in group'.format(userName)) return super().preConnect(userName, protocol, ip, hostname)
def uid_to_user(uid): ''' Convert a uid to a user name CLI Example: .. code-block:: bash salt '*' file.uid_to_user S-1-5-21-626487655-2533044672-482107328-1010 ''' if uid is None or uid == '': return '' sid = win32security.GetBinarySid(uid) try: name, domain, account_type = win32security.LookupAccountSid(None, sid) return name except pywinerror as exc: # if user does not exist... # 1332 = No mapping between account names and security IDs was carried # out. if exc.winerror == 1332: return '' else: raise
def parse_win32sid(sid): try: pysid = win32security.GetBinarySid(sid) name, dom, typ = win32security.LookupAccountSid(None, pysid) logger.debug('parse_win32sid') return name except: logger.debug('parse_win32sid error')
def preConnect(self, user, protocol): logger.debug('Pre connect invoked') if protocol != 'rdp': # If connection is not using rdp, skip adding user return 'ok' # Well known SSID for Remote Desktop Users REMOTE_USERS_SID = 'S-1-5-32-555' p = win32security.GetBinarySid(REMOTE_USERS_SID) groupName = win32security.LookupAccountSid(None, p)[0] useraAlreadyInGroup = False resumeHandle = 0 while True: users, _, resumeHandle = win32net.NetLocalGroupGetMembers( None, groupName, 1, resumeHandle, 32768) if user.lower() in [u['name'].lower() for u in users]: useraAlreadyInGroup = True break if resumeHandle == 0: break if useraAlreadyInGroup is False: logger.debug('User not in group, adding it') self._user = user try: userSSID = win32security.LookupAccountName(None, user)[0] win32net.NetLocalGroupAddMembers(None, groupName, 0, [{ 'sid': userSSID }]) except Exception as e: logger.error( 'Exception adding user to Remote Desktop Users: {}'.format( e)) else: self._user = None logger.debug('User {} already in group'.format(user)) # Now try to run pre connect command try: pre_cmd = store.preApplication() if os.path.isfile(pre_cmd): if (os.stat(pre_cmd).st_mode & stat.S_IXUSR) != 0: subprocess.call([pre_cmd, user, protocol]) else: logger.info( 'PRECONNECT file exists but it it is not executable (needs execution permission by root)' ) else: logger.info('PRECONNECT file not found & not executed') except Exception as e: # Ignore output of execution command logger.error('Executing preconnect command give') return 'ok'
def gid_to_group(gid): ''' Convert the group id to the group name on this system CLI Example:: salt '*' file.gid_to_group S-1-5-21-626487655-2533044672-482107328-1010 ''' sid = win32security.GetBinarySid(gid) name, domain, type = win32security.LookupAccountSid (None, sid) return name
def uid_to_user(uid): ''' Convert a uid to a user name CLI Example:: salt '*' file.uid_to_user S-1-5-21-626487655-2533044672-482107328-1010 ''' sid = win32security.GetBinarySid(uid) name, domain, type = win32security.LookupAccountSid (None, sid) return name
def onLogout(self, userName) -> None: logger.debug('Windows onLogout invoked: {}, {}'.format(userName, self._user)) try: p = win32security.GetBinarySid(REMOTE_USERS_SID) groupName = win32security.LookupAccountSid(None, p)[0] except Exception: logger.error('Exception getting Windows Group') return if self._user: try: win32net.NetLocalGroupDelMembers(None, groupName, [self._user]) except Exception as e: logger.error('Exception removing user from Remote Desktop Users: {}'.format(e))
def gid_to_group(gid): ''' Convert the group id to the group name on this system CLI Example: .. code-block:: bash salt '*' file.gid_to_group S-1-5-21-626487655-2533044672-482107328-1010 ''' if not gid: return False sid = win32security.GetBinarySid(gid) name, domain, account_type = win32security.LookupAccountSid(None, sid) return name
def get_username_from_sid( sid: Union[str, object] = None) -> Tuple[str, str, int]: """ Convert a SID / PySID to userinfo :param sid: str/PySID object :return: Tuple (str username, str domain, int type) """ try: if isinstance(sid, str): sid = win32security.GetBinarySid(sid) return win32security.LookupAccountSid('', sid) except pywintypes.error as exc: raise OSError('Cannot map security ID "{0}" with name: {1}'.format( sid, exc))
def get_user_name(sid) -> str: """ Translate from User SID to User Name. Args: PySID (object): contains a user's SID (See http://timgolden.me.uk/pywin32-docs/win32security.html). Returns: username (str): Windows user name with argument's SID. Raises: none. """ if sid is None: return "None" else: py_sid = win32security.GetBinarySid(sid) return win32security.LookupAccountSid(None, py_sid)[0]
def get_pysid(identifier: str = None) -> object: """ Wrapper function that returns PySID object from SID identifier or username If none given, we'll get current user :param identifier: (str) SID identifier or username :return: (PySID) object """ if identifier is None: # If no identifier given, take current user identifier = whoami() if identifier.startswith('S-1-'): # Consider we deal with a sid string return win32security.GetBinarySid(identifier) # Try to resolve username user, _, _ = get_pysid_from_username(identifier) return user
def preConnect(self, user, protocol): logger.debug('Pre connect invoked') if protocol != 'rdp': # If connection is not using rdp, skip adding user return 'ok' # Well known SSID for Remote Desktop Users REMOTE_USERS_SID = 'S-1-5-32-555' p = win32security.GetBinarySid(REMOTE_USERS_SID) groupName = win32security.LookupAccountSid(None, p)[0] useraAlreadyInGroup = False resumeHandle = 0 while True: users, _, resumeHandle = win32net.NetLocalGroupGetMembers( None, groupName, 1, resumeHandle, 32768) if user in [u['name'] for u in users]: useraAlreadyInGroup = True break if resumeHandle == 0: break if useraAlreadyInGroup is False: logger.debug('User not in group, adding it') self._user = user try: userSSID = win32security.LookupAccountName(None, user)[0] win32net.NetLocalGroupAddMembers(None, groupName, 0, [{ 'sid': userSSID }]) except Exception as e: logger.error( 'Exception adding user to Remote Desktop Users: {}'.format( e)) else: self._user = None logger.debug('User {} already in group'.format(user)) return 'ok'
def _getUserSid(user): """ return a state error dictionary, with 'sid' as a field if it could be returned if user is None, sid will also be None """ ret = {} sid_pattern = r"^S-1(-\d+){1,}$" if user and re.match(sid_pattern, user, re.I): try: sid = win32security.GetBinarySid(user) except Exception as e: # pylint: disable=broad-except ret["result"] = False ret["comment"] = ( "Unable to obtain the binary security identifier for {}. The exception" " was {}.".format(user, e)) else: try: win32security.LookupAccountSid("", sid) ret["result"] = True ret["sid"] = sid except Exception as e: # pylint: disable=broad-except ret["result"] = False ret["comment"] = ( "Unable to lookup the account for the security identifier {}. The" " exception was {}.".format(user, e)) else: try: sid = win32security.LookupAccountName("", user)[0] if user else None ret["result"] = True ret["sid"] = sid except Exception as e: # pylint: disable=broad-except ret["result"] = False ret["comment"] = ( "Unable to obtain the security identifier for {}. The exception" " was {}.".format(user, e)) return ret
def GetIdObjFromStr(id_str): return win32security.GetBinarySid(id_str)
def __sddl_dacl_parse(self, sddl_string): try: # We already know we have obtained the DACL SDDL string via win32security. Therefore # we do not have to enumerate the SDDL type even though we prove such data in the # windows_objects.SDDL() class. all_permissions = {} sddl_permissions = re.findall(self.re_perms, sddl_string) for dacl in sddl_permissions: # There are some odd dacl windows-isms here that I need to account for: if "WIN://" not in dacl: raw_ace_type = dacl.split(";")[0] raw_ace_flags = dacl.split(";")[1] raw_perms = dacl.split(";")[2] raw_trustee = dacl.split(";")[5] # Obtain the Plaintext ACE Type: access_type = self.ACCESS[raw_ace_type] # Obtain the plaintext ACE Flags: Don't Need These """ flags = "" flags_index = 0 if (len(raw_ace_flags) > 2): flag_split = [raw_ace_flags[i:i+2] for i in range(0, len(raw_ace_flags), 2)] for flag in flag_split: if (flags_index == 0): flags += f"{self.ACCESS[flag]}" flags_index += 1 else: flags += f", {self.ACCESS[flag]}" else: flags += f"{self.ACCESS[raw_ace_flags]}" """ # Obtain the plaintext permissions: acls = "" acl_index = 0 # Check if we have HEX permissions first: if "0x" in raw_perms: raw_perms = self.__access_from_hex(raw_perms) # Plaintext Permission Set: if len(raw_perms) > 2: perm_split = [ raw_perms[i:i + 2] for i in range(0, len(raw_perms), 2) ] for acl in perm_split: if acl_index == 0: acls += f"{self.ACCESS[acl]}" acl_index += 1 else: acls += f", {self.ACCESS[acl]}" else: acls += f"{self.ACCESS[raw_perms]}" # Obtain the Account/User (Trustee) try: # sometimes fails due to undocumented trustees such as services. if len(raw_trustee) <= 2: trustee = self.TRUSTEE[ raw_trustee] # Get the trustee from the windows_objects class else: try: # if the object is a SID, attempt to translate it and obtain the ASCII name trustee = win32security.LookupAccountSid( None, win32security.GetBinarySid(raw_trustee)) trustee = f"{trustee[1]}/{trustee[0]}" except: trustee = None except: trustee = None # Add all the content to the dict object if trustee not in all_permissions.keys( ) and trustee != None: all_permissions[trustee] = acls elif trustee != None: current = f"{str(all_permissions[trustee])} {acls}" all_permissions[trustee] = current current = "" return all_permissions except Exception as e: self.__write_error(sddl_string + "\n" + dacl) self.__print_exception() pass