By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 2,134 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

WindowsIdentity.Impersonate() vs ImpersonateLoggedOnUser()

P: n/a
After playing with the code shown and utilising Willy Denyottes' help, I have
come to the conclusion that there is some form of difference between the
managed WindowsIdentity.Impersonate() over the unmanaged
ImpersonateLoggedOnUser().

Below is my code showing a file copy to a remote computer's shared folder
using both WindowsImpersonationContext and
ImpersonateLoggedOnUser/RevertToSelf, with the latter currently commented out.

The issue I have is that the code executes and copies the file when using
ImpersonateLoggedOnUser, but not when using a WindowsImpersonationContext.
This wouldn't be an issue except that the ImpersonateLoggedOnUser does not
work when called on Windows 2000/2003 Pro/Server, only Windows XP.

The question would be why is this so and what can I do to get it working
with managed code. Note that the logon type and provider listed here are only
test values that I'm using, but no combination yields any better result other
than error 1326 "Logon failure: unknown user name or bad password".

Thanks.
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", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr
phToken);
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //
handle to token for logged-on user
[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
IntPtr admin_token;

//WindowsIdentity wid_current = WindowsIdentity.GetCurrent();

WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;

try
{
Console.WriteLine("Copying file...");
if (LogonUser("Administrator", "192.168.0.1", "password", 9, 0, out
admin_token) != 0)
{
//ImpersonateLoggedOnUser(admin_token);
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
System.IO.File.Copy("C:\\rpmtest.txt",
"\\\\192.168.0.1\\bb.uploads\\test.txt", true);
Console.WriteLine("Copy succeeded");
}
else Console.WriteLine("Copy Failed");
}
catch (System.Exception se)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine(ret.ToString(), "Error code: " + ret.ToString());
Console.WriteLine(se.Message);
}
finally
{
//RevertToSelf();
if (wic != null) wic.Undo();
}

//Console.ReadLine();
}
}
}
Nov 16 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
Windows 2000 uses NTLM as authentication protocol provider, but Logontype 9
needs Kerberos authentication, so you must explicitely specify
LOGON32_PROVIDER_WINNT50 for this to work on W2K.

// 9 = LOGON32_LOGON_NEW_CREDENTIALS
// 5 = LOGON32_PROVIDER_WINNT50
if(LogonUser(userName, domain, password, 9, 3, ref token) != 0)
{
....
Note that your code leaks a handle, whenener you call LogonUser you have to
close the handle when done with it!

[DllImport("kernel32.dll")]
public extern static bool CloseHandle(IntPtr hToken);
impersonationContext = tempWindowsIdentity.Impersonate();
// close impersonation token, no longer needed
CloseHandle(token);

Willy.
"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:77**********************************@microsof t.com...
After playing with the code shown and utilising Willy Denyottes' help, I
have
come to the conclusion that there is some form of difference between the
managed WindowsIdentity.Impersonate() over the unmanaged
ImpersonateLoggedOnUser().

Below is my code showing a file copy to a remote computer's shared folder
using both WindowsImpersonationContext and
ImpersonateLoggedOnUser/RevertToSelf, with the latter currently commented
out.

The issue I have is that the code executes and copies the file when using
ImpersonateLoggedOnUser, but not when using a WindowsImpersonationContext.
This wouldn't be an issue except that the ImpersonateLoggedOnUser does not
work when called on Windows 2000/2003 Pro/Server, only Windows XP.

The question would be why is this so and what can I do to get it working
with managed code. Note that the logon type and provider listed here are
only
test values that I'm using, but no combination yields any better result
other
than error 1326 "Logon failure: unknown user name or bad password".

Thanks.
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", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr
phToken);
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //
handle to token for logged-on user
[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
IntPtr admin_token;

//WindowsIdentity wid_current = WindowsIdentity.GetCurrent();

WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;

try
{
Console.WriteLine("Copying file...");
if (LogonUser("Administrator", "192.168.0.1", "password", 9, 0, out
admin_token) != 0)
{
//ImpersonateLoggedOnUser(admin_token);
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
System.IO.File.Copy("C:\\rpmtest.txt",
"\\\\192.168.0.1\\bb.uploads\\test.txt", true);
Console.WriteLine("Copy succeeded");
}
else Console.WriteLine("Copy Failed");
}
catch (System.Exception se)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine(ret.ToString(), "Error code: " + ret.ToString());
Console.WriteLine(se.Message);
}
finally
{
//RevertToSelf();
if (wic != null) wic.Undo();
}

//Console.ReadLine();
}
}
}

Nov 16 '05 #2

P: n/a
Ok, I remember you said this from your last post, and I've been trying to get
it to work from there. Winbase.h defines LOGON32_PROVIDER_WINNT50 as 3. If I
put 5 in I get error 87 (invalid parameter). 3 gives me the same error as 0
(error 1326) when using managed code, and no error (and successful copy) when
using unmanaged code (but only on XP). I get the same errors using 8 and 3 in
managed code also (LOGON32_LOGON_NETWORK_CLEARTEXT and LOGON32_LOGON_NETWORK).

This is the bit that has me confused. For all intents and purposes it
appears to work in XP but only with unmanaged code.

"Willy Denoyette [MVP]" wrote:
Windows 2000 uses NTLM as authentication protocol provider, but Logontype 9
needs Kerberos authentication, so you must explicitely specify
LOGON32_PROVIDER_WINNT50 for this to work on W2K.

// 9 = LOGON32_LOGON_NEW_CREDENTIALS
// 5 = LOGON32_PROVIDER_WINNT50
if(LogonUser(userName, domain, password, 9, 3, ref token) != 0)
{
....
Note that your code leaks a handle, whenener you call LogonUser you have to
close the handle when done with it!

[DllImport("kernel32.dll")]
public extern static bool CloseHandle(IntPtr hToken);
impersonationContext = tempWindowsIdentity.Impersonate();
// close impersonation token, no longer needed
CloseHandle(token);

Willy.
"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:77**********************************@microsof t.com...
After playing with the code shown and utilising Willy Denyottes' help, I
have
come to the conclusion that there is some form of difference between the
managed WindowsIdentity.Impersonate() over the unmanaged
ImpersonateLoggedOnUser().

Below is my code showing a file copy to a remote computer's shared folder
using both WindowsImpersonationContext and
ImpersonateLoggedOnUser/RevertToSelf, with the latter currently commented
out.

The issue I have is that the code executes and copies the file when using
ImpersonateLoggedOnUser, but not when using a WindowsImpersonationContext.
This wouldn't be an issue except that the ImpersonateLoggedOnUser does not
work when called on Windows 2000/2003 Pro/Server, only Windows XP.

The question would be why is this so and what can I do to get it working
with managed code. Note that the logon type and provider listed here are
only
test values that I'm using, but no combination yields any better result
other
than error 1326 "Logon failure: unknown user name or bad password".

Thanks.
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", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain,
string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr
phToken);
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken); //
handle to token for logged-on user
[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
IntPtr admin_token;

//WindowsIdentity wid_current = WindowsIdentity.GetCurrent();

WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;

try
{
Console.WriteLine("Copying file...");
if (LogonUser("Administrator", "192.168.0.1", "password", 9, 0, out
admin_token) != 0)
{
//ImpersonateLoggedOnUser(admin_token);
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
System.IO.File.Copy("C:\\rpmtest.txt",
"\\\\192.168.0.1\\bb.uploads\\test.txt", true);
Console.WriteLine("Copy succeeded");
}
else Console.WriteLine("Copy Failed");
}
catch (System.Exception se)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine(ret.ToString(), "Error code: " + ret.ToString());
Console.WriteLine(se.Message);
}
finally
{
//RevertToSelf();
if (wic != null) wic.Undo();
}

//Console.ReadLine();
}
}
}


Nov 16 '05 #3

P: n/a


"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:98**********************************@microsof t.com...
Ok, I remember you said this from your last post, and I've been trying to
get
it to work from there. Winbase.h defines LOGON32_PROVIDER_WINNT50 as 3. If
I
put 5 in I get error 87 (invalid parameter). 3 gives me the same error as
0
(error 1326) when using managed code, and no error (and successful copy)
when
using unmanaged code (but only on XP). I get the same errors using 8 and 3
in
managed code also (LOGON32_LOGON_NETWORK_CLEARTEXT and
LOGON32_LOGON_NETWORK).

This is the bit that has me confused. For all intents and purposes it
appears to work in XP but only with unmanaged code.

Sorry, 5 was a typo,
if(LogonUser(userName, domain, password, 9, 3, ref token) != 0)
was correct ;-).
Some questions:
error 1326 is returned after what call, LogonUser or ? (I don't see why
LogonUser would fail depending the Impersonation method used later on).
What exactly do you mean with managed/unmanaged code in this context?
Is it:
ImpersonateLoggedOnUser = unmanaged?
Impersonate = managed?
What system (OS) are you connceting to, is it the same in all cases?
Note : you should add SetLastError = true)] to your ImpersonateLoggedOnUser
declaration too.
9 is the only logon option you can use here, the logon access token
should only be used to access the remote resource, the local file must still
be read with the original user's access token.

Willy.
Nov 16 '05 #4

P: n/a
To answer your questions:

I refer to the DLL import functions as unmanaged, though this is probably
incorrect to do so. So LogonUser, ImpersonateLoggedOnUser and RevertToSelf I
refer to as unmanaged, and the .NET classes as managed.

The OS I am connecting to is Windows 2003 Server in all cases. I assume the
server is setup in a valid manner as I can copy files to it from my machine
but only if I use unmanaged (I should start referring to it as imported) code.

Note that I have since modified my code in the posted example to better
handle the errors returned.

Ok, structured test results:

When calling LogonUser with LOGON32_LOGON_NETWORK (3) or
LOGON32_LOGON_NETWORK_CLEARTEXT (8) and either 0 or 3 as the provider, the
code fails at LogonUser with GetLastWin32Error being 1326 (Logon failure).

When using a WindowsIdentity class and calling LogonUser with
LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider, the code
fails on WindowsIdentity.Impersonate(). The error code from GetLastWin32Error
is 0, and the exception message is "Unable to impersonate user" on Windows
XP. On Windows 2000 Professional the code fails at LogonUser with error code
1314 "A required privilege is not held by the client."

When using DLL imported code ImpersonateLoggedOnUser and calling LogonUser
with LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider, the
code succeeds at copying the file on Windows XP. On Windows 2000 Professional
the code fails at LogonUser with error code 1314 "A required privilege is not
held by the client."

This is the latest set of results, which now seem to be consistent as this
whole testing process has had to suffer my learning curve. I was previously
getting different errors on the 2k pro box, but it seems now that I know I
need to use (9) that I can consistently get 1314 at LogonUser, which if I
could fix would solve my immediate issue of needing to get the code working.
However I still don't understand why WindowsIdentity.Impersonate() always
fails.

Thanks.

"Willy Denoyette [MVP]" wrote:


"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:98**********************************@microsof t.com...
Ok, I remember you said this from your last post, and I've been trying to
get
it to work from there. Winbase.h defines LOGON32_PROVIDER_WINNT50 as 3. If
I
put 5 in I get error 87 (invalid parameter). 3 gives me the same error as
0
(error 1326) when using managed code, and no error (and successful copy)
when
using unmanaged code (but only on XP). I get the same errors using 8 and 3
in
managed code also (LOGON32_LOGON_NETWORK_CLEARTEXT and
LOGON32_LOGON_NETWORK).

This is the bit that has me confused. For all intents and purposes it
appears to work in XP but only with unmanaged code.

Sorry, 5 was a typo,
if(LogonUser(userName, domain, password, 9, 3, ref token) != 0)
was correct ;-).
Some questions:
error 1326 is returned after what call, LogonUser or ? (I don't see why
LogonUser would fail depending the Impersonation method used later on).
What exactly do you mean with managed/unmanaged code in this context?
Is it:
ImpersonateLoggedOnUser = unmanaged?
Impersonate = managed?
What system (OS) are you connceting to, is it the same in all cases?
Note : you should add SetLastError = true)] to your ImpersonateLoggedOnUser
declaration too.
9 is the only logon option you can use here, the logon access token
should only be used to access the remote resource, the local file must still
be read with the original user's access token.

Willy.

Nov 16 '05 #5

P: n/a
Hi All,

and sorry, that I break in here ......

I have also to connect to remote files and process them, but I do not
understand the InterOp code completely. What I do, from a thread from the
threadpool is just simply:

comp = new DirectoryEntry
(
String.Format("{0}://{1},computer", adsDefaultProvider,
args.computerName),
args.userName,
args.password,
AuthenticationTypes.Secure
);
comp.UsePropertyCache = false;
string os = comp.Properties["OperatingSystemVersion"][0].ToString();
[I do not really need the "os", but the trsuted channel]

After I - so I call it - "establish a secure channel" this way, I can access
the files also, no interop/win32 code neccessary.

I verified this to work from w2l to w2k and to xp. I needed a long time to
trust this snippet of code [ok, I do it not for 100%, but it works].

Any thoughts and objections are really very welcome. I came to this idea,
because I do not really understand impersonation. How can I impersonate a
thread on the local machine with credentials, which are not valid on the
local machine, but on the remote one!??

Thanks so far and best regards,

Best regards,
Manfred Braun

(Private)
Mannheim
Germany

mailto:_m*************@manfbraun.de
(Remove the anti-spam-underscore to mail me!)

"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:FB**********************************@microsof t.com...
To answer your questions:

I refer to the DLL import functions as unmanaged, though this is probably
incorrect to do so. So LogonUser, ImpersonateLoggedOnUser and RevertToSelf I refer to as unmanaged, and the .NET classes as managed.

The OS I am connecting to is Windows 2003 Server in all cases. I assume the server is setup in a valid manner as I can copy files to it from my machine but only if I use unmanaged (I should start referring to it as imported) code.
Note that I have since modified my code in the posted example to better
handle the errors returned.

Ok, structured test results:

When calling LogonUser with LOGON32_LOGON_NETWORK (3) or
LOGON32_LOGON_NETWORK_CLEARTEXT (8) and either 0 or 3 as the provider, the
code fails at LogonUser with GetLastWin32Error being 1326 (Logon failure).

When using a WindowsIdentity class and calling LogonUser with
LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider, the code fails on WindowsIdentity.Impersonate(). The error code from GetLastWin32Error is 0, and the exception message is "Unable to impersonate user" on Windows
XP. On Windows 2000 Professional the code fails at LogonUser with error code 1314 "A required privilege is not held by the client."

When using DLL imported code ImpersonateLoggedOnUser and calling LogonUser
with LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider, the code succeeds at copying the file on Windows XP. On Windows 2000 Professional the code fails at LogonUser with error code 1314 "A required privilege is not held by the client."

This is the latest set of results, which now seem to be consistent as this
whole testing process has had to suffer my learning curve. I was previously getting different errors on the 2k pro box, but it seems now that I know I
need to use (9) that I can consistently get 1314 at LogonUser, which if I
could fix would solve my immediate issue of needing to get the code working. However I still don't understand why WindowsIdentity.Impersonate() always
fails.

Thanks.

"Willy Denoyette [MVP]" wrote:


"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:98**********************************@microsof t.com...
Ok, I remember you said this from your last post, and I've been trying to get
it to work from there. Winbase.h defines LOGON32_PROVIDER_WINNT50 as 3. If I
put 5 in I get error 87 (invalid parameter). 3 gives me the same error as 0
(error 1326) when using managed code, and no error (and successful copy) when
using unmanaged code (but only on XP). I get the same errors using 8 and 3 in
managed code also (LOGON32_LOGON_NETWORK_CLEARTEXT and
LOGON32_LOGON_NETWORK).

This is the bit that has me confused. For all intents and purposes it
appears to work in XP but only with unmanaged code.

Sorry, 5 was a typo,
if(LogonUser(userName, domain, password, 9, 3, ref token) != 0)
was correct ;-).
Some questions:
error 1326 is returned after what call, LogonUser or ? (I don't see why
LogonUser would fail depending the Impersonation method used later on).
What exactly do you mean with managed/unmanaged code in this context?
Is it:
ImpersonateLoggedOnUser = unmanaged?
Impersonate = managed?
What system (OS) are you connceting to, is it the same in all cases?
Note : you should add SetLastError = true)] to your ImpersonateLoggedOnUser declaration too.
9 is the only logon option you can use here, the logon access token
should only be used to access the remote resource, the local file must still be read with the original user's access token.

Willy.

Nov 16 '05 #6

P: n/a
See inline ***

Willy.

"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:FB**********************************@microsof t.com...
To answer your questions:

I refer to the DLL import functions as unmanaged, though this is probably
incorrect to do so. So LogonUser, ImpersonateLoggedOnUser and RevertToSelf
I
refer to as unmanaged, and the .NET classes as managed.
*** No problem, just to be sure we are talking about the same thing.
The OS I am connecting to is Windows 2003 Server in all cases. I assume
the
server is setup in a valid manner as I can copy files to it from my
machine
but only if I use unmanaged (I should start referring to it as imported)
code.

Note that I have since modified my code in the posted example to better
handle the errors returned.

Ok, structured test results:

When calling LogonUser with LOGON32_LOGON_NETWORK (3) or
LOGON32_LOGON_NETWORK_CLEARTEXT (8) and either 0 or 3 as the provider, the
code fails at LogonUser with GetLastWin32Error being 1326 (Logon failure).
When using a WindowsIdentity class and calling LogonUser with
LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider, the
code
fails on WindowsIdentity.Impersonate(). The error code from
GetLastWin32Error
is 0, and the exception message is "Unable to impersonate user" on Windows
XP. On Windows 2000 Professional the code fails at LogonUser with error
code
1314 "A required privilege is not held by the client."
***
1. Not sure why WindowsIdentity.Impersonate(). works for me on XP SP2
running .NET v1.1 SP1, will try to investigate why it throws on you. Note
that LogonUser didn't fail, but aparantly Impersonate doesn't like the token
returned.
2. Windows 2000 needs the "Act as part of the operating system" privilege
(also called TCB privilege) in order to call LogonUser, this super privilege
is no longer required on XP and W2K3. This is very unfortunate, but unless
you are willing to spend some hard time to interop with the SSP API's there
is no other way to call LogonUser than enabling the TCB privilege for the
calling user account..


When using DLL imported code ImpersonateLoggedOnUser and calling LogonUser
with LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider,
the
code succeeds at copying the file on Windows XP. On Windows 2000
Professional
the code fails at LogonUser with error code 1314 "A required privilege is
not
held by the client."
*** See above for privilege error on W2K.
This is the latest set of results, which now seem to be consistent as this
whole testing process has had to suffer my learning curve. I was
previously
getting different errors on the 2k pro box, but it seems now that I know I
need to use (9) that I can consistently get 1314 at LogonUser, which if I
could fix would solve my immediate issue of needing to get the code
working.
However I still don't understand why WindowsIdentity.Impersonate() always
fails.
*** To resume:
- Call LogonUser with Logontype 9 and preferaby specifying the Kerberos
authentication provider (3).
- Add user account to the TCB when running your code on W2K :-(

Thanks.

"Willy Denoyette [MVP]" wrote:

Nov 16 '05 #7

P: n/a
Manfred,

See inline.

Willy.

"Manfred Braun" <aa@bb.cc> wrote in message
news:uh**************@TK2MSFTNGP09.phx.gbl...
Hi All,

and sorry, that I break in here ......

I have also to connect to remote files and process them, but I do not
understand the InterOp code completely. What I do, from a thread from the
threadpool is just simply:

comp = new DirectoryEntry
(
String.Format("{0}://{1},computer", adsDefaultProvider,
args.computerName),
args.userName,
args.password,
AuthenticationTypes.Secure
);
comp.UsePropertyCache = false;
string os = comp.Properties["OperatingSystemVersion"][0].ToString();
[I do not really need the "os", but the trsuted channel]

After I - so I call it - "establish a secure channel" this way, I can
access
the files also, no interop/win32 code neccessary.

*** {0} contains WinNT, right? and {1} is the remote system name.
By doing this you are currently establishing a "network logon session" for
the current user (local logon session) , using the credentials arg.userName
and arg.password to access the remote resource. The network session is
shared by all applications running in the same user session.
The result of this is the same as you would create a remote session using
the "net use ..." command.
I verified this to work from w2l to w2k and to xp. I needed a long time to
trust this snippet of code [ok, I do it not for 100%, but it works].
*** While this might work for you it is an indication that your network
resources are not secured, you are establishing a network logon to access
"Directory services", but you can use the same session credentials to access
file server resources and guess what else :-).

Any thoughts and objections are really very welcome. I came to this idea,
because I do not really understand impersonation. How can I impersonate a
thread on the local machine with credentials, which are not valid on the
local machine, but on the remote one!??

Thanks so far and best regards,

Best regards,
Manfred Braun

Nov 16 '05 #8

P: n/a
Thanks Willy, you saved the day =) It took some fiddling but I got it to work
with the TCB priv. Thanks so much for your help here.

I'm also using XP SP2 with .NET v1.1.. but I'm not sure about SP1 ... That
might be my problem, I'll have to check and see if I have SP1 installed.

"Willy Denoyette [MVP]" wrote:
See inline ***

Willy.

"BLiTZWiNG" <BL*******@discussions.microsoft.com> wrote in message
news:FB**********************************@microsof t.com...
To answer your questions:

I refer to the DLL import functions as unmanaged, though this is probably
incorrect to do so. So LogonUser, ImpersonateLoggedOnUser and RevertToSelf
I
refer to as unmanaged, and the .NET classes as managed.

*** No problem, just to be sure we are talking about the same thing.
The OS I am connecting to is Windows 2003 Server in all cases. I assume
the
server is setup in a valid manner as I can copy files to it from my
machine
but only if I use unmanaged (I should start referring to it as imported)
code.

Note that I have since modified my code in the posted example to better
handle the errors returned.

Ok, structured test results:

When calling LogonUser with LOGON32_LOGON_NETWORK (3) or
LOGON32_LOGON_NETWORK_CLEARTEXT (8) and either 0 or 3 as the provider, the
code fails at LogonUser with GetLastWin32Error being 1326 (Logon failure).

When using a WindowsIdentity class and calling LogonUser with
LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider, the
code
fails on WindowsIdentity.Impersonate(). The error code from
GetLastWin32Error
is 0, and the exception message is "Unable to impersonate user" on Windows
XP. On Windows 2000 Professional the code fails at LogonUser with error
code
1314 "A required privilege is not held by the client."


***
1. Not sure why WindowsIdentity.Impersonate(). works for me on XP SP2
running .NET v1.1 SP1, will try to investigate why it throws on you. Note
that LogonUser didn't fail, but aparantly Impersonate doesn't like the token
returned.
2. Windows 2000 needs the "Act as part of the operating system" privilege
(also called TCB privilege) in order to call LogonUser, this super privilege
is no longer required on XP and W2K3. This is very unfortunate, but unless
you are willing to spend some hard time to interop with the SSP API's there
is no other way to call LogonUser than enabling the TCB privilege for the
calling user account..


When using DLL imported code ImpersonateLoggedOnUser and calling LogonUser
with LOGON32_LOGON_NEW_CREDENTIALS (9) and either 0 or 3 as the provider,
the
code succeeds at copying the file on Windows XP. On Windows 2000
Professional
the code fails at LogonUser with error code 1314 "A required privilege is
not
held by the client."


*** See above for privilege error on W2K.

This is the latest set of results, which now seem to be consistent as this
whole testing process has had to suffer my learning curve. I was
previously
getting different errors on the 2k pro box, but it seems now that I know I
need to use (9) that I can consistently get 1314 at LogonUser, which if I
could fix would solve my immediate issue of needing to get the code
working.
However I still don't understand why WindowsIdentity.Impersonate() always
fails.


*** To resume:
- Call LogonUser with Logontype 9 and preferaby specifying the Kerberos
authentication provider (3).
- Add user account to the TCB when running your code on W2K :-(

Thanks.

"Willy Denoyette [MVP]" wrote:


Nov 16 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.