def setup_sacl(user_group_sid): """ Without this setup, the single user server will likely fail with either Error 0x0000142 or ExitCode -1073741502. This sets up access for the given user to the WinSta (Window Station) and Desktop objects. """ # Set access rights to window station h_win_sta = win32service.OpenWindowStation( "winsta0", False, win32con.READ_CONTROL | win32con.WRITE_DAC) # Get security descriptor by winsta0-handle sec_desc_win_sta = win32security.GetUserObjectSecurity( h_win_sta, win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION | win32con.GROUP_SECURITY_INFORMATION) # Get DACL from security descriptor dacl_win_sta = sec_desc_win_sta.GetSecurityDescriptorDacl() if dacl_win_sta is None: # Create DACL if not exisiting dacl_win_sta = win32security.ACL() # Add ACEs to DACL for specific user group dacl_win_sta.AddAccessAllowedAce(win32security.ACL_REVISION_DS, GENERIC_ACCESS, user_group_sid) dacl_win_sta.AddAccessAllowedAce(win32security.ACL_REVISION_DS, WINSTA_ALL, user_group_sid) # Set modified DACL for winsta0 win32security.SetSecurityInfo(h_win_sta, win32security.SE_WINDOW_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl_win_sta, None) # Set access rights to desktop h_desktop = win32service.OpenDesktop( "default", 0, False, win32con.READ_CONTROL | win32con.WRITE_DAC | win32con.DESKTOP_WRITEOBJECTS | win32con.DESKTOP_READOBJECTS) # Get security descriptor by desktop-handle sec_desc_desktop = win32security.GetUserObjectSecurity( h_desktop, win32security.OWNER_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION | win32con.GROUP_SECURITY_INFORMATION) # Get DACL from security descriptor dacl_desktop = sec_desc_desktop.GetSecurityDescriptorDacl() if dacl_desktop is None: #create DACL if not exisiting dacl_desktop = win32security.ACL() # Add ACEs to DACL for specific user group dacl_desktop.AddAccessAllowedAce(win32security.ACL_REVISION_DS, GENERIC_ACCESS, user_group_sid) dacl_desktop.AddAccessAllowedAce(win32security.ACL_REVISION_DS, DESKTOP_ALL, user_group_sid) # Set modified DACL for desktop win32security.SetSecurityInfo(h_desktop, win32security.SE_WINDOW_OBJECT, win32security.DACL_SECURITY_INFORMATION, None, None, dacl_desktop, None)
def addUserToWindowStation(winsta, userSid): ''' Adds the given PySID representing a user to the given window station's discretionary access-control list. The old security descriptor for winsta is returned. ''' winsta_all = win32con.WINSTA_ACCESSCLIPBOARD | \ win32con.WINSTA_ACCESSGLOBALATOMS | \ win32con.WINSTA_CREATEDESKTOP | \ win32con.WINSTA_ENUMDESKTOPS | \ win32con.WINSTA_ENUMERATE | \ win32con.WINSTA_EXITWINDOWS | \ win32con.WINSTA_READATTRIBUTES | \ win32con.WINSTA_READSCREEN | \ win32con.WINSTA_WRITEATTRIBUTES | \ win32con.DELETE | \ win32con.READ_CONTROL | \ win32con.WRITE_DAC | \ win32con.WRITE_OWNER generic_access = win32con.GENERIC_READ | \ win32con.GENERIC_WRITE | \ win32con.GENERIC_EXECUTE | \ win32con.GENERIC_ALL # Get the security description for winsta. security_desc = \ win32security.GetUserObjectSecurity(winsta, win32con.DACL_SECURITY_INFORMATION) # Get discretionary access-control list (DACL) for winsta. acl = security_desc.GetSecurityDescriptorDacl() # Add the first ACE for userSid to the window station. ace0_index = acl.GetAceCount() ace_flags = win32con.CONTAINER_INHERIT_ACE | \ win32con.INHERIT_ONLY_ACE | \ win32con.OBJECT_INHERIT_ACE acl.AddAccessAllowedAceEx(win32con.ACL_REVISION, ace_flags, generic_access, userSid) # Add the second ACE for userSid to the window station. ace1_index = acl.GetAceCount() ace_flags = win32con.NO_PROPAGATE_INHERIT_ACE acl.AddAccessAllowedAceEx(win32con.ACL_REVISION, ace_flags, winsta_all, userSid) # Update the DACL for winsta. This is the crux of all this. Just adding # ACEs to acl does not propagate back automatically. # NOTE: Simply creating a new security descriptor and assigning it as # the security descriptor for winsta (without setting the DACL) is # sufficient to allow windows to be opened, but that is probably not # providing any kind of security on winsta. updateACL(winsta, acl) return [ace0_index, ace1_index]
def handleHasSID(handle, sid): ''' Determines whether the given SID is known to the ACEs of the given handle. ''' security_desc = \ win32security.GetUserObjectSecurity(handle, win32con.DACL_SECURITY_INFORMATION) acl = security_desc.GetSecurityDescriptorDacl() for i in range(acl.GetAceCount()): ace = acl.GetAce(i) if len(ace) == 3: sid_index = 2 else: sid_index = 5 if ace[sid_index] == sid: return True return False
def set_user_perm(obj, perm, sid): ''' Set an object permission for the given user sid ''' info = (win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION) sd = win32security.GetUserObjectSecurity(obj, info) dacl = sd.GetSecurityDescriptorDacl() ace_cnt = dacl.GetAceCount() found = False for idx in range(0, ace_cnt): (aceType, aceFlags), ace_mask, ace_sid = dacl.GetAce(idx) ace_exists = (aceType == ntsecuritycon.ACCESS_ALLOWED_ACE_TYPE and ace_mask == perm and ace_sid == sid) if ace_exists: # If the ace already exists, do nothing break else: dacl.AddAccessAllowedAce(dacl.GetAclRevision(), perm, sid) sd.SetSecurityDescriptorDacl(1, dacl, 0) win32security.SetUserObjectSecurity(obj, info, sd)
def removeACEs(handle, aceIndices): security_desc = \ win32security.GetUserObjectSecurity(handle, win32con.DACL_SECURITY_INFORMATION) acl = security_desc.GetSecurityDescriptorDacl() # Make a copy of aceIndices that is sorted in decreasing order of ACE # index. This allows us to iterate over the indices and remove them from # acl without worrying about indices being invalidated. old_count = acl.GetAceCount() ace_list = [i for i in aceIndices] ace_list.sort() ace_list.reverse() for i in ace_list: logging.debug("Removing ACE %d from %s's ACL" % (i, handle)) acl.DeleteAce(i) assert acl.GetAceCount() == old_count - len(ace_list) logging.debug("ACE count before %d" % old_count) logging.debug("ACE count after %d" % acl.GetAceCount()) updateACL(handle, acl)
def addUserToDesktop(desktop, userSid): ''' Adds the given PySID representing a user to the given desktop's discretionary access-control list. The old security descriptor for desktop is returned. ''' desktop_all = win32con.DESKTOP_CREATEMENU | \ win32con.DESKTOP_CREATEWINDOW | \ win32con.DESKTOP_ENUMERATE | \ win32con.DESKTOP_HOOKCONTROL | \ win32con.DESKTOP_JOURNALPLAYBACK | \ win32con.DESKTOP_JOURNALRECORD | \ win32con.DESKTOP_READOBJECTS | \ win32con.DESKTOP_SWITCHDESKTOP | \ win32con.DESKTOP_WRITEOBJECTS | \ win32con.DELETE | \ win32con.READ_CONTROL | \ win32con.WRITE_DAC | \ win32con.WRITE_OWNER security_desc = \ win32security.GetUserObjectSecurity(desktop, win32con.DACL_SECURITY_INFORMATION) # Get discretionary access-control list (DACL) for desktop. acl = security_desc.GetSecurityDescriptorDacl() # Add the ACE for user_sid to the desktop. ace0_index = acl.GetAceCount() acl.AddAccessAllowedAce(win32con.ACL_REVISION, desktop_all, userSid) # Update the DACL for desktop. This is the crux of all this. Just adding # ACEs to acl does not propagate back automatically. updateACL(desktop, acl) return [ace0_index]
def removeACEs(handle, aceIndices): security_desc = \ win32security.GetUserObjectSecurity(handle, win32con.DACL_SECURITY_INFORMATION) acl = security_desc.GetSecurityDescriptorDacl() # Make a copy of aceIndices that is sorted in decreasing order of ACE # index. This allows us to iterate over the indices and remove them from # acl without worrying about indices being invalidated. old_count = acl.GetAceCount() ace_list = [i for i in aceIndices] ace_list.sort() ace_list.reverse() gLogger.debug("Old ACE count = %d" % old_count) gLogger.debug("Will remove %d ACEs" % len(ace_list)) for i in ace_list: gLogger.debug("\tRemoving ACE %d from ACL for handle %s" % (i, handle)) acl.DeleteAce(i) gLogger.debug("New ACE count = %d" % acl.GetAceCount()) updateACL(handle, acl)
def removeUserSID(handle, sid): if handle is None or sid is None: return security_desc = \ win32security.GetUserObjectSecurity(handle, win32con.DACL_SECURITY_INFORMATION) acl = security_desc.GetSecurityDescriptorDacl() indices = [] for i in range(acl.GetAceCount()): ace = acl.GetAce(i) if len(ace) == 3: sid_index = 2 else: sid_index = 5 if ace[sid_index] == sid: indices.append(i) indices.sort() indices.reverse() removeACEs(handle, indices)
'', win32security.SE_LOCK_MEMORY_NAME), win32con.SE_PRIVILEGE_ENABLED)) all_info=win32security.OWNER_SECURITY_INFORMATION|win32security.GROUP_SECURITY_INFORMATION| \ win32security.DACL_SECURITY_INFORMATION|win32security.SACL_SECURITY_INFORMATION info = win32security.OWNER_SECURITY_INFORMATION | win32security.GROUP_SECURITY_INFORMATION | win32security.DACL_SECURITY_INFORMATION ph = win32process.GetCurrentProcess() th = win32security.OpenProcessToken( ph, win32security.TOKEN_ALL_ACCESS) ##win32con.TOKEN_ADJUST_PRIVILEGES) win32security.AdjustTokenPrivileges(th, 0, new_privs) my_sid = win32security.GetTokenInformation(th, win32security.TokenUser)[0] pwr_sid = win32security.LookupAccountName('', 'Power Users')[0] h = win32process.GetProcessWindowStation() sd = win32security.GetUserObjectSecurity(h, info) dacl = sd.GetSecurityDescriptorDacl() ace_cnt = dacl.GetAceCount() dacl.AddAccessAllowedAce(dacl.GetAclRevision(), win32con.ACCESS_SYSTEM_SECURITY | win32con.WRITE_DAC, my_sid) sd.SetSecurityDescriptorDacl(1, dacl, 0) sd.SetSecurityDescriptorGroup(pwr_sid, 0) sd.SetSecurityDescriptorOwner(pwr_sid, 0) win32security.SetUserObjectSecurity(h, info, sd) new_sd = win32security.GetUserObjectSecurity(h, info) assert new_sd.GetSecurityDescriptorDacl().GetAceCount( ) == ace_cnt + 1, 'Did not add an ace to the Dacl !!!!!!' assert win32security.LookupAccountSid('', new_sd.GetSecurityDescriptorOwner(