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

Need help with impersonation, please.

P: n/a
I have a .net DLL that I've created (based on someone's post in this
group, sorry I've forgotten who) and I need a little help with making it
work.

I want to provide the same functionality as "runas /netonly" and I'm
using LOGON32_LOGON_NEW_CREDENTIALS as I've read here many times.

I'm trying to launch a MOM operator console that will connect to a
management server in a different domain. I've verified that this works
with runas /netonly.

I can't use the p.StartInfo.UserName, .Domain, and .Password properties
in my app (I'm using .net 2.0) because the domain that I wish to connect
to does not have a trust relationship with my own. (i get a
win32exception that says bad username or password when i *know* they're
correct and that i'm entering them properly in my code.)

Can anyone tell me what I'm doing wrong?

Here is the relevant code in my app:

//////////////

string user = username.Text;
string pass = password.Text;
string domain = "UNTOPR";

if (!ImpersonationUtil.Impersonate(user, pass, domain)) {
MessageBox.Show("Impersonation failed.");
return;
}
else {
Process p = new Process();
p.StartInfo.FileName = @"MOM.UI.OpsConsoleExe.exe";
p.Start();
p.WaitForExit();

ImpersonationUtil.UnImpersonate();
}

///////////////

and here is the ImpersonationUtil DLL code in its entirety. From the
app above I simply reference the DLL this creates.

///////////////////////////////
///////////////////////////////

using System;
using System.Security.Principal;
using System.Runtime.InteropServices;

public class ImpersonationUtil {

//private const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
//private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 4;
//private const int LOGON32_PROVIDER_DEFAULT = 0;
private static WindowsImpersonationContext impersonationContext;

public static bool Impersonate(
string user,
string password,
string domain) {

WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;

// put ints here rather than consts to keep this line readable //
if (LogonUser(user, domain, password, 9, 0, ref token) != 0) {

if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) {
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();

if (null != impersonationContext) {
return true;
}

}
}

return false;
}

public static void UnImpersonate() {
impersonationContext.Undo();
}

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int LogonUser(
string lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);

[DllImport("advapi32.dll",
CharSet = System.Runtime.InteropServices.CharSet.Auto,
SetLastError = true)]
public extern static int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);

}

////////////////////////////
////////////////////////////

Any help at all appreciated.

Many thanks.
Mar 28 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a
This won't work, impersonation works at the thread level, not at the process
level. That means that your "new" process will run with the same access
token as it's parent process, not the impersonated token. More, when using
LOGON32_LOGON_NEW_CREDENTIALS you are not creating a new thread token, you
simply say which token (credentials) the current thread should use when
accessing the network.
If you need to mimic the "runas /netonly" behavior, you will need to call
CreateProcessWithLogonW using PInvoke specifying LOGON_NETCREDENTIALS_ONLY
for dwLogonFlags.

Willy.

"jeremiah johnson" <na*******@gmail.com> wrote in message
news:%2***************@TK2MSFTNGP10.phx.gbl...
|I have a .net DLL that I've created (based on someone's post in this
| group, sorry I've forgotten who) and I need a little help with making it
| work.
|
| I want to provide the same functionality as "runas /netonly" and I'm
| using LOGON32_LOGON_NEW_CREDENTIALS as I've read here many times.
|
| I'm trying to launch a MOM operator console that will connect to a
| management server in a different domain. I've verified that this works
| with runas /netonly.
|
| I can't use the p.StartInfo.UserName, .Domain, and .Password properties
| in my app (I'm using .net 2.0) because the domain that I wish to connect
| to does not have a trust relationship with my own. (i get a
| win32exception that says bad username or password when i *know* they're
| correct and that i'm entering them properly in my code.)
|
| Can anyone tell me what I'm doing wrong?
|
| Here is the relevant code in my app:
|
| //////////////
|
| string user = username.Text;
| string pass = password.Text;
| string domain = "UNTOPR";
|
| if (!ImpersonationUtil.Impersonate(user, pass, domain)) {
| MessageBox.Show("Impersonation failed.");
| return;
| }
| else {
| Process p = new Process();
| p.StartInfo.FileName = @"MOM.UI.OpsConsoleExe.exe";
| p.Start();
| p.WaitForExit();
|
| ImpersonationUtil.UnImpersonate();
| }
|
| ///////////////
|
| and here is the ImpersonationUtil DLL code in its entirety. From the
| app above I simply reference the DLL this creates.
|
| ///////////////////////////////
| ///////////////////////////////
|
| using System;
| using System.Security.Principal;
| using System.Runtime.InteropServices;
|
| public class ImpersonationUtil {
|
| //private const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
| //private const int LOGON32_LOGON_NETWORK_CLEARTEXT = 4;
| //private const int LOGON32_PROVIDER_DEFAULT = 0;
| private static WindowsImpersonationContext impersonationContext;
|
| public static bool Impersonate(
| string user,
| string password,
| string domain) {
|
| WindowsIdentity tempWindowsIdentity;
| IntPtr token = IntPtr.Zero;
| IntPtr tokenDuplicate = IntPtr.Zero;
|
| // put ints here rather than consts to keep this line readable //
| if (LogonUser(user, domain, password, 9, 0, ref token) != 0) {
|
| if (DuplicateToken(token, 2, ref tokenDuplicate) != 0) {
| tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
| impersonationContext = tempWindowsIdentity.Impersonate();
|
| if (null != impersonationContext) {
| return true;
| }
|
| }
| }
|
| return false;
| }
|
| public static void UnImpersonate() {
| impersonationContext.Undo();
| }
|
| [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
| public static extern int LogonUser(
| string lpszUserName,
| String lpszDomain,
| String lpszPassword,
| int dwLogonType,
| int dwLogonProvider,
| ref IntPtr phToken);
|
| [DllImport("advapi32.dll",
| CharSet = System.Runtime.InteropServices.CharSet.Auto,
| SetLastError = true)]
| public extern static int DuplicateToken(
| IntPtr hToken,
| int impersonationLevel,
| ref IntPtr hNewToken);
|
| }
|
| ////////////////////////////
| ////////////////////////////
|
| Any help at all appreciated.
|
| Many thanks.
Mar 28 '06 #2

P: n/a
Thank you. Based on your response I was able to Google around a bit and
find what I needed.

Willy Denoyette [MVP] wrote:
This won't work, impersonation works at the thread level, not at the process
level. That means that your "new" process will run with the same access
token as it's parent process, not the impersonated token. More, when using
LOGON32_LOGON_NEW_CREDENTIALS you are not creating a new thread token, you
simply say which token (credentials) the current thread should use when
accessing the network.
If you need to mimic the "runas /netonly" behavior, you will need to call
CreateProcessWithLogonW using PInvoke specifying LOGON_NETCREDENTIALS_ONLY
for dwLogonFlags.

Willy.

Mar 28 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.