2010-03-29 8 views
13

This .NET API funktioniert OK, wenn ich versuche, die Registrierung auf einem Computer zu öffnen, der sich in derselben Domäne befindet wie ich (und mein angemeldeter Benutzer verfügt über Administratorrechte auf dem Zielcomputer).Wie übermittle ich Anmeldeinformationen an einen Computer, damit ich Microsoft.Win32.RegistryKey.OpenRemoteBaseKey() darauf verwenden kann?

Es wird schwierig, wenn es sich um eine Out-of-Domain-Maschine mit einem anderen lokalen administrativen Benutzer handelt (von dem ich das Passwort habe).

Ich habe versucht, WNetUseConnection() (das hat mir gut in der Vergangenheit in Situationen, in denen ich wollte, war eine Remote-Datei zu lesen) vor dem Aufruf von OpenRemoteBaseKey(), aber keine Würfel - ich bekomme eine Ausnahme Zugriff verweigert .

Natürlich muss ich Anmeldeinformationen auf andere Weise übergeben, aber wie?

Antwort

32

Was ich erfolgreich Zugriff auf Dateien auf einem Computer verwendet wird, ist der folgende 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 

Und dann teil Unterzeichnung, benutzen Sie einfach:

 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(); 
     } 

Wie Sie vielleicht sehen, "Undo()" bewirkt, dass Sie nicht länger als dieser Benutzer angemeldet sind. Also benutze es nicht, bevor du fertig bist. Aber vergiss nicht, es zu benutzen!

+2

+1 Dies ist wirklich die einzige Möglichkeit, es zu tun. – Nate

+0

Kann ich die Variable "Token" lange Zeit behalten und dann den Block "using/Undo()" an verschiedenen Stellen mit demselben Token verwenden? " – JCCyC

+0

Ich denke schon. Es ist die Impersonate, die sich tatsächlich anmeldet. Was ich verwendet habe, ist ein "GetImpersonation()", das einen WindowsImpersonationContext wie oben –