When connecting to a network share for which the current user (in my case, a network enabled service user) has no rights, name and password have to be provided.
I know how to do this with Win32 functions (the WNet*
family from mpr.dll
), but would like to do it with .Net (2.0) functionality.
What options are available?
Maybe some more information helps:
- The use case is a windows service, not an Asp.Net application.
- The service is running under an account which has no rights on the share.
- The user account needed for the share is not known on the client side.
- Client and server are not members of the same domain.
I liked Mark Brackett's answer so much that I did my own quick implementation. Here it is if anyone else needs it in a hurry:
I searched lots of methods and i did it my own way. You have to open a connection between two machine via command prompt NET USE command and after finishing your work clear the connection with command prompt NET USE "myconnection" /delete.
You must use Command Prompt process from code behind like this:
Usage is simple:
Here is functions:
And also ExecuteCommand function is:
This functions worked very fast and stable for me.
OK... I can resond..
Disclaimer: I just had an 18+ hour day (again).. I'm old and forgetfull.. I can't spell.. I have a short attention span so I better respond fast.. :-)
Question:
Is it possible to change the thread principal to an user with no account on the local machine?
Answer:
Yes, you can change a thread principal even if the credentials you are using are not defined locally or are outside the "forest".
I just ran into this problem when trying to connect to an SQL server with NTLM authentication from a service. This call uses the credentials associated with the process meaning that you need either a local account or a domain account to authenticate before you can impersonate. Blah, blah...
But...
Calling LogonUser(..) with the attribute of ????_NEW_CREDENTIALS will return a security token without trying to authenticate the credentials. Kewl.. Don't have to define the account within the "forest". Once you have the token you might have to call DuplicateToken() with the option to enable impersonation resulting in a new token. Now call SetThreadToken( NULL, token ); (It might be &token?).. A call to ImpersonateLoggedonUser( token ); might be required, but I don't think so. Look it up..
Do what you need to do..
Call RevertToSelf() if you called ImpersonateLoggedonUser() then SetThreadToken( NULL, NULL ); (I think... look it up), and then CloseHandle() on the created handles..
No promises but this worked for me... This is off the top of my head (like my hair) and I can't spell!!!
If you can't create an locally valid security token, it seems like you've ruled all out every option bar Win32 API and WNetAddConnection*.
Tons of information on MSDN about WNet - PInvoke information and sample code that connects to a UNC path here:
MSDN Reference here:
The Luke Quinane solution looks good, but did work only partially in my ASP.NET MVC application. Having two shares on the same server with different credentials I could use the impersonation only for the first one.
The problem with WNetAddConnection2 is also that it behaves differently on different windows versions. That is why I looked for alternatives and found the LogonUser function. Here is my code which also works in ASP.NET:
Usage:
Also ported to F# to use with FAKE