Welcome, guest | Sign In | My Account | Store | Cart

Sometimes it is convenient to make thread authenticated as another principle. For example, perhaps something should run temporarily w/administrative rights. This is especially useful if you do not want the issues of making a COM object or service(which are other ways to solve the problem).

Python, 41 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Impersonate:

    def __init__(self,login,password):

	self.domain='bedrock'

	self.login=login

	self.password=password

    def logon(self):

	self.handel=win32security.LogonUser(self.login,self.domain,self.password,\\

	win32con.LOGON32_LOGON_INTERACTIVE,win32con.LOGON32_PROVIDER_DEFAULT)

	win32security.ImpersonateLoggedOnUser(self.handel)

    def logoff(self):

	win32security.RevertToSelf() #terminates impersonation

	self.handel.Close() #guarantees cleanup


a=Impersonate('barney','bambam')


try:

    a.logon() #become the user

    #do whatever here

    print win32api.GetUserName() #show you're someone else

    a.logoff() #return to normal

except:

    print sys.exc_type , sys.exc_value

On windows, processes run with a specific security token. By default, threads use that token. You can however, attach another token to the thread rather easily, thanks to Mark Hammonds modules.

The to do this is with the win32 calls: LogonUser and ImpersonateLoggedOnUser. LogonUser gives you a handel which ImpersonateLoggedOnUser can then use to "become" the user. To do this the thread calling, LogonUser, needs SE_TCB_NAME, SE_CHANGE_NOTIFY_NAME, and SE_ASSIGNPRIMARYTOKEN_NAME privileges.

2 comments

Doug Glenn 21 years, 3 months ago  # | flag

Additional information. The code is problematic as is. It may, or may not work.

To enable this code on locked down NT based systems (Win2k and XP) you will first have to enable "Act as Operating System" and grant rights to the appropriate user groups (run secpol.msc and select Local Policies, then User Rights Assignments). Once this is completed, you have one more step remaining. You will need to grant the rights listed with the code. To do this, you can use the following code snippet.

Begin code: def AdjustPrivilege(priv, enable = 1): # Get the process token. print priv flags = TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY #flags= TOKEN_QUERY htoken = win32security.OpenProcessToken(win32api.GetCurrentProcess(), flags) # Get the ID for the privilege. id = win32security.LookupPrivilegeValue(None, priv) # Now obtain the privilege for this process. # Create a list of the privileges to be added. if enable: newPrivileges = [(id, SE_PRIVILEGE_ENABLED)] else: newPrivileges = [(id, 0)] # and make the adjustment. try: win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges) except: fail.append(priv)

now set the rights

AdjustPrivilege(SE_CHANGE_NOTIFY_NAME) AdjustPrivilege(SE_TCB_NAME) AdjustPrivilege(SE_ASSIGNPRIMARYTOKEN_NAME)

Ian Whiteley 12 years, 4 months ago  # | flag

Great sample, just a question - does not seem to support win32gui functions:

Below code comes up null (win32api.GetUserName() works correctly):

hwnd = win32gui.GetForegroundWindow() print win32gui.GetWindowText (hwnd)

1) why is this and 2) more importantly is there a fix

PS: did not use the AdjustPrivilege function when testing

Created by John Nielsen on Fri, 12 Oct 2001 (PSF)
Python recipes (4591)
John Nielsen's recipes (36)

Required Modules

  • (none specified)

Other Information and Tasks