views:

6665

answers:

4

How can a C# program running as LocalSystem impersonate the login identity of another user temporarily? Roughly speaking I have a Windows Service that I'd like to run as LocalSystem but at times impersonate user XYZ (when connecting to a db using windows integrated security).

Most important of all: Is there a way to do this without knowing the other user's password?

Note: if a password is mandatory is there a recommended strategy for storing a password securely (c# and/or vbscript).

+2  A: 

For the password storing part, you may want to have a look at this question asked recently.

This was my answer:

You could/should use the DPAPI, the Data Protection API that provides storage encryption.
It's there just for this type of problem.

Encryption of the storage is based on either:

  • the user account, so only the logged-in user can access the data. This makes the data transferable to another PC with the exact same user credentials.
  • the machine, making the data only accessible on that particular machine setup and not transferable to another PC.

There is a dnrTV show with Karl Franklin showing exactly what's needed to implement this, and other encryption functions.
The source code from the show is also available on the page.

There are, of course, lots of other articles on that subject.

Renaud Bompuis
+11  A: 

For the Impersonation code see the following two Code Project articles:

http://www.codeproject.com/KB/cs/cpimpersonation1.aspx

http://www.codeproject.com/KB/cs/zetaimpersonator.aspx

and the Microsoft KB article they are based upon:

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158

mundeep
I've used these examples in real code, and they work. Good call.
dviljoen
+2  A: 

Short answer: you can't without the user password or the user calling your service through COM.

To impersonate another user in your process, you have to call ImpersonateLoggedOnUser. ImpersonateLoggedOnUser requires a token handle. There are several ways you can obtain token handle:

Franci Penov
+1  A: 

It's possible, although it requires you to do a lot of code. See NtCreateToken and CreateToken. You need SeCreateTokenPrivilege, although that won't be a problem since you're running under NT AUTHORITY\SYSTEM. You can then use the created token to impersonate inside a thread.

wj32
Thanks. Not much in the way of code samples out there for it though :)
Note that it's not recommended to run services under LocalSystem, and sysadmins rightly frown on this practice.
Anton Tykhyy
On stackoverflow, I prefer to do/answer what is asked.
wj32