PC Review


Reply
Thread Tools Rate Thread

LogonUser issues

 
 
=?Utf-8?B?QkxpVFpXaU5H?=
Guest
Posts: n/a
 
      27th Jan 2005
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");
}
}
}
 
Reply With Quote
 
 
 
 
Willy Denoyette [MVP]
Guest
Posts: n/a
 
      27th Jan 2005

"BLiTZWiNG" <(E-Mail Removed)> wrote in message
news(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.




 
Reply With Quote
 
 
 
 
=?Utf-8?B?QkxpVFpXaU5H?=
Guest
Posts: n/a
 
      28th Jan 2005
Thanks again Willy. I will try what you have suggested here.

However note that I used unmanaged function ImpersonateLoggedOnUser and
succeeded with the copy, so I at least have a solution. I'm not sure if there
are downsides to that way though. I am still going to persist with the
managed way.

Also note that the 2k3 server I'm trying to copy to is now suffering UserEnv
errors 1058 (unable to save group policy object) :/ I can see there is a fix
for it but I have to discuss it with my boss.

"Willy Denoyette [MVP]" wrote:

>
> "BLiTZWiNG" <(E-Mail Removed)> wrote in message
> news(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.
>
>
>
>
>

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
LogonUser failed error Nimi Microsoft ASP .NET 1 14th Oct 2004 02:40 PM
impersonating and LogonUser Jason Microsoft ASP .NET 7 5th Jan 2004 04:35 PM
LogonUser API call... paul Microsoft Excel Programming 4 14th Oct 2003 10:41 AM
Re: Impersonation in ASPNET and LogonUser Mary Chipman Microsoft Dot NET Framework 0 3rd Sep 2003 04:48 PM
Re: Impersonation in ASPNET and LogonUser Mary Chipman Microsoft ASP .NET 0 3rd Sep 2003 04:48 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:35 PM.