7.14 Impersonating Principals on Windows


Credit: John Nielsen

7.14.1 Problem

You need to authenticate a thread temporarily as another principal on a Windows machine for example, to make something run with the appropriate administrative rights.

7.14.2 Solution

On Unix, you can call setuid. On Windows, the impersonation task is slightly more involved, but not terribly so:

import win32security, win32con class Impersonate:     def _ _init_ _(self, login, password):         self.domain = 'bedrock'         self.login = login         self.password = password     def logon(self):         self.handle = win32security.LogonUser(self.login, self.domain,             self.password, win32con.LOGON32_LOGON_INTERACTIVE,             win32con.LOGON32_PROVIDER_DEFAULT)         win32security.ImpersonateLoggedOnUser(self.handle)     def logoff(self):         win32security.RevertToSelf(  ) # terminates impersonation         self.handle.Close(  ) # guarantees cleanup if __name__=='__main__':     a = Impersonate('barney', 'bambam')     try:         a.logon() # become the user         try:             # Do whatever you need to do, e.g.,:             print win32api.GetUserName() # show you're someone else         finally:             a.logoff() # Ensure return-to-normal no matter what     except:         print 'Exception:', sys.exc_type, sys.exc_value

7.14.3 Discussion

Sometimes it is convenient to authenticate a thread as another principal. For example, perhaps something should run temporarily with administrative rights. This is especially useful if you do not want the hassle of making a COM object or a service (which are other ways to solve the problem or, rather, work around it). On Windows, processes run with a specific security token. By default, all threads use that token. You can, however, easily attach another token to the thread, thanks to Mark Hammond's win32all package.

The way to do this is with the Win32 calls LogonUser and ImpersonateLoggedOnUser. LogonUser gives you a handle that ImpersonateLoggedOnUser can then use to become the user. To do this, the thread calling LogonUser needs the SE_TCB_NAME, SE_CHANGE_NOTIFY_NAME, and SE_ASSIGNPRIMARYTOKEN_NAME privileges.

7.14.4 See Also

Documentation for the win32security and win32con in win32all (http://starship.python.net/crew/mhammond/win32/Downloads.html) or ActivePython (http://www.activestate.com/ActivePython/); Windows API documentation available from Microsoft (http://msdn.microsoft.com); Python Programming on Win32, by Mark Hammond and Andy Robinson (O'Reilly).



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2005
Pages: 346

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net