Take the 2-minute tour ×

Are there any alternatives to LogonUser and for impersonating given account in order to access network resources? I'm looking for the method of impersonation which would let me connect to machine in foreign domains (or, workgroup machines for the same matter).

For initial data I have: machine name, username (or domain\username), cleartext password.

I know there's a way to establish connection using WNetAddConnection to a \\machinename\ipc$, then most network functions will run in a context of that account, however win2008 added another twist and some functions still use the account, that thread is running under.

I'm also aware, that there's some way to get an impersonation token using SSPI. Have anyone experimented with those tokens, are they good for accessing shares, SCM, remote registry and stuff? Is is what WNetAddConnection is using?

EDIT: To clarify, the reason I cannot use LogonUser is because I need to impersonate user in a non-trusted domain or workgroup

EDIT2: Another clarification: the item I'm trying to implement is similar to psexec, e.g.:

  • program should not modify host or active directory configuration (e.g.: create temporary local users, etc). Moreover assumption cannot be made that it is running on DC or not
  • there can be no assumptions made about which software is pre-installed on the remote host, only condition given is that windows file sharing is enabled on target
  • Account/password is known to be working on target, but target machine may be in local domain, foreign domain, not in domain at all.

EDIT3: I would really love to hear more about SSPI InitializeSecurityContext / AcquireCredentialsHandle option. Is there anybody who has been working with this API extensively? Is it possible to use the tokens returned with impersonation, so that a thread can access network shares and copy files, etc? Can someone post a working code snippet?

EDIT4: Thanks to Marsh Ray, problem got resolved. If anyone is looking to see the proof-of-concept code, it is here

share|improve this question
add comment

4 Answers

up vote 6 down vote accepted

If you're wanting to "access network resources" outside of your forest, do that with WNetAddConnection2/3 as you mentioned, or use the standard RPC APIs with RPC_ C__ AUTHN__ GSS__ NEGOTIATE and and explicit credentials structure.

Normally, "impersonation" is something that happens on the server side. The server side will be able to impersonate the connection as the account you're connecting as.

But the key is this: impersonation only makes sense for impersonating an account the server can access in his local SAM/domain/forest directory. If the client and server are in different forests, they clearly can't agree on the SID of an account for an impersonation token (except for the case of well-known SIDs like Administrator which serve mainly to confuse this kind of thing), and that seems necessary to check against DACLs etc.

Perhaps what you want is to call LogonUserEx with the LOGON32__ LOGON__ NEW__ CREDENTIALS flag. This should succeed (even in a different forest - it doesn't actually authenticate the credentials you give it) giving you a token with the username/password you specified. You may have to use DuplicateToken to turn this into an impersonation token. Then you can use SetThreadToken to replace the token on your thread.

IMHO this isn't really "impersonation", you're just using the credentials outright, but it allows you to access network resources transparently as the arbitrary username/password you supply.

Edit: Oh yeah, be aware that there is no protection against man-in-the-middle on this type of connection. The client especially cannot strongly authenticate the server (short of heroics like IPSEC), so in theory you can't trust anything the server tells you.

share|improve this answer
wow, sounds like a great approach! I never thought of using this. Let me give it a quick test to see if it works –  galets Jul 29 '09 at 15:47
dude, that did it! Thank you so very much, this was exactly what I've been looking for –  galets Jul 29 '09 at 17:03
great! glad to hear it! –  Marsh Ray Jul 29 '09 at 17:18
Don't forget to restore your thread's old token and clean up all the new ones. You don't want to leak tokens, I suspect they consume a scarce resource in the kernel and/or lsass.exe. –  Marsh Ray Jul 29 '09 at 17:20
Out of curiosity, did you end up needing to call DuplicateToken? –  Marsh Ray Jul 29 '09 at 19:06
show 3 more comments

The theory goes that you pass the credentials as a SEC_WINNT_AUTH_IDENTITY structure to the AcquireCredentialsHandle function that creates the handle used in InitializeSecurityContext. I never tried this on foreign domains though and I don't know if it works.

share|improve this answer
add comment

Doing this directly and reliably via the Windows API seems next to impossible, plus Windows does so much work behind the scenes to make network access "just work". Plus the impersonation side of things only works for the single thread that called the APIs.

But... you can run a whole program under a different user... such as when you run a service.

So you could edit the registry in your main program to run various services under different security tokens and use IPC/Sockets to communicate with those processes from your main application. ie. a whole bunch (or restarting and reconfiguring the same process) of helper processes running under the different user(s) which your main app abuses.

I realize this is a hack but it seems viable ;)

share|improve this answer
nope. not viable. need to be able to obtain impersonation tokens for machines in un-trusted forest. You cannot run a program as a user from untrusted forest –  galets Jul 23 '09 at 17:31
You can create the user locally since you have the cleartext password and delete the user when you are done. Another option is talking DCERPC/MSRPC (en.wikipedia.org/wiki/MSRPC) directly but then you are effectively going down a similar track to samba, but at least you could use Wireshark to compare your implementation against what happens via the normal Window APIs. Can you install helper programs on the remote machine and impersonate on that end (and use whatever protocol you like to connect to the remote helper program?)? –  Rudi Bierach Jul 23 '09 at 22:53
I guess I haven't carefully read your comment about service. My post has been specifically instigated by the fact that when I try to install service to remote Windows 2008 box, and I already have a share mapped, remote SCM will still not use the account used to map a share –  galets Jul 24 '09 at 18:43
Newer versions of Windows stop allowing services from using mapped drives, which leaves only UNC paths to access remote drives. It makes sense since mapped drives are more tied to the desktop than anything else. –  Rudi Bierach Jul 24 '09 at 18:55
Correct. I should have used wording carefully. By "mapping a drive" I meant "establishing WMNet connection". What I found, however, is that even though I established connection and can copy files, under windows 2008 attempts to open SCM will still be using currently logged in account, not the one I used to establish connection and copy files. This is the reason I'm looking what alternatives are –  galets Jul 27 '09 at 15:52
add comment

You could open a command line, map the drive using the plaintext username and password. Then disconnect the drive:

net use m: \\machinename\share password /user:username
... do stuff ...
net use m: /delete


share|improve this answer
I mentioned this solution does not work: "I know there's a way to establish connection using WNetAddConnection to a \\machinename\ipc$, ..." - you essentially suggesting the same thing –  galets Jul 27 '09 at 15:49
Sorry, I thought WNetAddConnection was something different. –  Robert Jul 27 '09 at 22:41
add comment

Your Answer


