"BLiTZWiNG" <(E-Mail Removed)> wrote in message
news

0624DC8-1E2D-468D-8480-(E-Mail Removed)...
> Having a few strage behaviours with this function, mainly in that when I
> try
> to logon to another computer with a different name/pass to the current
> user
> of the local machine, it tries to impersonate me, not the credentials I
> gave
> it.
>
> LogonUser succeeds only when using LOGON32_LOGON_NEW_CREDENTIALS (9). Any
> other LogonType causes error 126: Specified module could not be found -
> whatever that means...
>
> The initial WindowsIdentity.GetCurrent() reveals "DELLWING\Trent" as the
> user, which is my local account. Upon success of LogonUser I create a new
> WindowsIdentity with the received token. Printing out the details reveals
> "DELLWING\Trent" as the user, even though I supplied "Administrator" and
> the
> password of the remote box. I then get "Unable to Impersonate User" when
> trying Impersonate().
>
> Why would the token come back represent me when I specified a whole nother
> user and computer?
>
> My code looks like this currently (thanks to Willy Denoyette).
> -----------------------
> using System;
> using System.Runtime.InteropServices;
> using System.Security.Principal;
> using System.Security.Permissions;
>
> namespace SecurityTest
> {
> /// <summary>
> /// Summary description for Class1.
> /// </summary>
> class SecurityTest
> {
> [DllImport("advapi32.DLL")]
> public static extern int LogonUser(string lpszUsername, string lpszDomain,
> string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr
> phToken);
>
> /// <summary>
> /// The main entry point for the application.
> /// </summary>
> [STAThread]
> static void Main(string[] args)
> {
> IntPtr admin_token;
>
> // This works fine
> WindowsIdentity wid_current = WindowsIdentity.GetCurrent();
> Console.WriteLine("Current Name: " + wid_current.Name);
> Console.WriteLine("Current Token: " + wid_current.Token);
>
> if (LogonUser("Administrator", "192.168.0.5", "password", 9, 0, out
> admin_token) != 0)
> {
> WindowsIdentity wid_admin = new WindowsIdentity(admin_token);
> Console.WriteLine("Remote Name: " + wid_admin.Name);
> Console.WriteLine("Remote Token: " + wid_admin.Token);
>
>
> WindowsImpersonationContext wic = null;
> try
> {
> wic = wid_admin.Impersonate();
> // Always get an exception here after Impersonate
>
> System.IO.File.Copy("C:\\test_read\\test.txt",
> "\\\\192.168.0.5\\trent\\test.txt", true);
>
> }
> catch (System.Exception se)
> {
> Console.WriteLine(se.Message);
> }
> finally
> {
> if (wic != null) wic.Undo();
> }
> }
> else
> {
> int ret = Marshal.GetLastWin32Error();
> Console.WriteLine(ret.ToString(), "Error");
> }
> }
> }
A few remarks:
LogonUser returns or a "direct" token or an "impersonation" token. A direct
token kan be used to impersonate, an impersonation token cannot and will
return an error.
Both LOGON32_LOGON_NEW_CREDENTIALS (9) and LOGON32_LOGON_NETWORK_CLEARTEXT
Logontypes returns a direct token, but LOGON32_LOGON_NETWORK does not.
Why the error 126? The reason is that the original error code is lost in the
call chain. To prevent this you should add SetLastError=true in the
DllImport.
[DllImport("advapi32.DLL"), SetLastError=true]
Why is the local identity still the same, simply because logontype 9 returns
a clone of the current token but also creates a hidden secondary token.
The clone will be used to access local resources while the secondary token
will ONLY be used when accessing remote resources.
Logontype 9 requires a "negotiate" logon provider (W2K or higher), when
running on W2K the default however is NTLM, so it's better to specify
LOGON32_PROVIDER_WINNT50 (5) a logon provider to make sure negotiate is used
in all cases.
if (LogonUser("Administrator", "192.168.0.5", "password", 9, 5, out
admin_token) != 0)
Willy.