This .NET API works OK if I'm trying to open the Registry in a machine that's in the same domain as I am (and my logged-on user has admin rights on the target machine).
It gets tricky if it's an out-of-domain machine with a different, local administrative user (of whom I do have the password).
I tried to use WNetUseConnection() (which has served me well in the past in situations where what I wanted was to read a remote disk file) prior to calling OpenRemoteBaseKey(), but no dice -- I get an access denied exception.
Clearly, I must pass credentials some other way, but how?
What I've used successfully to access files on a computer is the following code:
#region imports
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string
lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, ref
IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle
);
[DllImport("advapi32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
public extern static bool DuplicateToken(IntPtr
existingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr
duplicateTokenHandle);
#endregion
#region logon consts
// logon types
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// logon providers
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
#endregion
And then for signing in part, just use:
IntPtr token = IntPtr.Zero;
bool isSuccess = LogonUser("username", "domain", "password",
LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
using (WindowsImpersonationContext person = new WindowsIdentity(token).Impersonate())
{
//do your thing
person.Undo();
}
As you might see, "Undo()" will make that you are no longer signed in as that user. So don't use it before you're done. But don't forget to use it!