473,383 Members | 1,789 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Create remote object with specified credentials.

Hi everyone,

Currently I am working on an application that will perform a remote scan of
a specified server using the following code:

Type t = Type.GetTypeFromProgID( "Microsoft.Update.Session", "proact" );
UpdateSession UpdSess = (UpdateSession) Activator.CreateInstance(t);

This code works quite well, as long as the user you are currently
authenticated to also has administrative access on the target device. This
won't always be the case, so I need to be able to prompt the user for a name
and password on the target server to use instead.

What is the best way to do this?

John.
PS: I'm fairly new to this whole remote object game, so if there is a
'better' way to hook into the Windows Update Agent, please let me know.
Nov 17 '05 #1
4 14418
Heliotic,

You can make a call to LogonUser through the P/Invoke layer to get a
user token for a user (given a username and password). When you have that
token, you can pass it to the constructor or Impersonate method on the
WindowsIdentity class to impersonate that user. It will return to you a
WindowsImpersonationContext instance which you then must call Undo upon to
revert back to the the original user identity.

You would then place your call to Activator.CreateInstance in between
the call to Impersonate and Undo.

Check the "about" documentation for the WindowsImpersonationContext
class for an example of the calls you need to make.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Heliotic" <He******@discussions.microsoft.com> wrote in message
news:73**********************************@microsof t.com...
Hi everyone,

Currently I am working on an application that will perform a remote scan
of
a specified server using the following code:

Type t = Type.GetTypeFromProgID( "Microsoft.Update.Session", "proact" );
UpdateSession UpdSess = (UpdateSession) Activator.CreateInstance(t);

This code works quite well, as long as the user you are currently
authenticated to also has administrative access on the target device. This
won't always be the case, so I need to be able to prompt the user for a
name
and password on the target server to use instead.

What is the best way to do this?

John.
PS: I'm fairly new to this whole remote object game, so if there is a
'better' way to hook into the Windows Update Agent, please let me know.

Nov 17 '05 #2
Thanks Nicholas,

I finally have it authenticating to the remote server (which is a great
relief, since the helpfile explicitly states that LogonUser can't provide
this functionality)

However I continue to get access denied when I try to instance the object. I
know the authentication code is working, because I replaced the COM code with
some code to copy a file, and it worked fine.

Here is the code I am currently using (apologies for the spam):

IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);

string userName = txtUserName.Text, domainName = txtDomain.Text, password
= txtPassword.Text;

const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int SecurityDelegation = 3;

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, password,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref tokenHandle);

if (returnValue == false)
{
int ret = Marshal.GetLastWin32Error();
MessageBox.Show("LogonUser failed with error code : "+ ret.ToString() );
MessageBox.Show("\nError: "+ ret.ToString() +" ,"+ GetErrorMessage(ret));
int errorCode = 0x5; //ERROR_ACCESS_DENIED
throw new System.ComponentModel.Win32Exception(errorCode);
return;
}

MessageBox.Show("Did LogonUser Succeed? " + returnValue.ToString() );
MessageBox.Show("Value of Windows NT token: " + tokenHandle.ToString() );

bool retVal = DuplicateToken(tokenHandle, SecurityDelegation, ref
dupeTokenHandle);

if (false == retVal)
{
CloseHandle(tokenHandle);
Console.WriteLine("Exception thrown in trying to duplicate token.");

return;
}

//Impersonation.
MessageBox.Show("Before impersonation: " +
WindowsIdentity.GetCurrent().Name);

WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

MessageBox.Show("After impersonation: " +
WindowsIdentity.GetCurrent().Name);
Type t = Type.GetTypeFromProgID( "Microsoft.Update.Session",
txtDomain.Text );

UpdateSession UpdSess = (UpdateSession) Activator.CreateInstance(t);

IUpdateSearcher UpdSrch = UpdSess.CreateUpdateSearcher();
ISearchResult sr = UpdSrch.Search("IsInstalled=0 and Type='Software'");
MessageBox.Show( "Found "+ sr.Updates.Count.ToString() + " updates" );

foreach( IUpdate temp in sr.Updates )
MessageBox.Show( temp.Description.ToString() );

impersonatedUser.Undo();

// Free the tokens.
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);

if (dupeTokenHandle != IntPtr.Zero)
CloseHandle(dupeTokenHandle);
return;
The other strange thing I've noticed is that the 'after impersonation'
message still displays my local userid instead of the remote one. (Even when
the copy worked successfully).

In my searching, I've come across some references to a feature within COM
where it will ignore impersonated access. Does that apply here? If so, is
there a way to bypass it?

"Nicholas Paldino [.NET/C# MVP]" wrote:
Heliotic,

You can make a call to LogonUser through the P/Invoke layer to get a
user token for a user (given a username and password). When you have that
token, you can pass it to the constructor or Impersonate method on the
WindowsIdentity class to impersonate that user. It will return to you a
WindowsImpersonationContext instance which you then must call Undo upon to
revert back to the the original user identity.

You would then place your call to Activator.CreateInstance in between
the call to Impersonate and Undo.

Check the "about" documentation for the WindowsImpersonationContext
class for an example of the calls you need to make.

Hope this helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Heliotic" <He******@discussions.microsoft.com> wrote in message
news:73**********************************@microsof t.com...
Hi everyone,

Currently I am working on an application that will perform a remote scan
of
a specified server using the following code:

Type t = Type.GetTypeFromProgID( "Microsoft.Update.Session", "proact" );
UpdateSession UpdSess = (UpdateSession) Activator.CreateInstance(t);

This code works quite well, as long as the user you are currently
authenticated to also has administrative access on the target device. This
won't always be the case, so I need to be able to prompt the user for a
name
and password on the target server to use instead.

What is the best way to do this?

John.
PS: I'm fairly new to this whole remote object game, so if there is a
'better' way to hook into the Windows Update Agent, please let me know.


Nov 17 '05 #3

"Heliotic" <He******@discussions.microsoft.com> wrote in message
news:BE**********************************@microsof t.com...
Thanks Nicholas,

I finally have it authenticating to the remote server (which is a great
relief, since the helpfile explicitly states that LogonUser can't provide
this functionality)

However I continue to get access denied when I try to instance the object.
I
know the authentication code is working, because I replaced the COM code
with
some code to copy a file, and it worked fine.
Here is the code I am currently using (apologies for the spam):

IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);

string userName = txtUserName.Text, domainName = txtDomain.Text, password
= txtPassword.Text;

const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int SecurityDelegation = 3;

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, password,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref tokenHandle);

if (returnValue == false)
{
int ret = Marshal.GetLastWin32Error();
MessageBox.Show("LogonUser failed with error code : "+ ret.ToString() );
MessageBox.Show("\nError: "+ ret.ToString() +" ,"+ GetErrorMessage(ret));
int errorCode = 0x5; //ERROR_ACCESS_DENIED
throw new System.ComponentModel.Win32Exception(errorCode);
return;
}

MessageBox.Show("Did LogonUser Succeed? " + returnValue.ToString() );
MessageBox.Show("Value of Windows NT token: " + tokenHandle.ToString() );

bool retVal = DuplicateToken(tokenHandle, SecurityDelegation, ref
dupeTokenHandle);

if (false == retVal)
{
CloseHandle(tokenHandle);
Console.WriteLine("Exception thrown in trying to duplicate token.");

return;
}

//Impersonation.
MessageBox.Show("Before impersonation: " +
WindowsIdentity.GetCurrent().Name);

WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

MessageBox.Show("After impersonation: " +
WindowsIdentity.GetCurrent().Name);
Type t = Type.GetTypeFromProgID( "Microsoft.Update.Session",
txtDomain.Text );

UpdateSession UpdSess = (UpdateSession) Activator.CreateInstance(t);

IUpdateSearcher UpdSrch = UpdSess.CreateUpdateSearcher();
ISearchResult sr = UpdSrch.Search("IsInstalled=0 and Type='Software'");
MessageBox.Show( "Found "+ sr.Updates.Count.ToString() + " updates" );

foreach( IUpdate temp in sr.Updates )
MessageBox.Show( temp.Description.ToString() );

impersonatedUser.Undo();

// Free the tokens.
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);

if (dupeTokenHandle != IntPtr.Zero)
CloseHandle(dupeTokenHandle);
return;
The other strange thing I've noticed is that the 'after impersonation'
message still displays my local userid instead of the remote one. (Even
when
the copy worked successfully).

1. That's normal, LOGON32_LOGON_NEW_CREDENTIALS returns a token that uses
the credentials specified to access the network only, the current thread
token remains the same. Please read the docs. on LogonUser carefully.
2. Initializing DCOM security and impersonating when accessing remote
network shares are diferent beasts, the reason for this is that DCOM
security is initialized by the CLR (by calling CoInitializeSecurity) to use
the process credentials by default. So the reason why it fails is because
the default process security blanket is used when calling into COM/DCOM, If
you wan't to apply different security setings for the process you'll have to
call CoInitializeSecurity very early in the process (at least before your
first call into COM/DCOM).
Willy.

Nov 17 '05 #4


"Willy Denoyette [MVP]" wrote:

"Heliotic" <He******@discussions.microsoft.com> wrote in message
news:BE**********************************@microsof t.com...
Thanks Nicholas,

I finally have it authenticating to the remote server (which is a great
relief, since the helpfile explicitly states that LogonUser can't provide
this functionality)

However I continue to get access denied when I try to instance the object.
I
know the authentication code is working, because I replaced the COM code
with
some code to copy a file, and it worked fine.

Here is the code I am currently using (apologies for the spam):

IntPtr tokenHandle = new IntPtr(0);
IntPtr dupeTokenHandle = new IntPtr(0);

string userName = txtUserName.Text, domainName = txtDomain.Text, password
= txtPassword.Text;

const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int SecurityDelegation = 3;

tokenHandle = IntPtr.Zero;
dupeTokenHandle = IntPtr.Zero;

// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, password,
LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref tokenHandle);

if (returnValue == false)
{
int ret = Marshal.GetLastWin32Error();
MessageBox.Show("LogonUser failed with error code : "+ ret.ToString() );
MessageBox.Show("\nError: "+ ret.ToString() +" ,"+ GetErrorMessage(ret));
int errorCode = 0x5; //ERROR_ACCESS_DENIED
throw new System.ComponentModel.Win32Exception(errorCode);
return;
}

MessageBox.Show("Did LogonUser Succeed? " + returnValue.ToString() );
MessageBox.Show("Value of Windows NT token: " + tokenHandle.ToString() );

bool retVal = DuplicateToken(tokenHandle, SecurityDelegation, ref
dupeTokenHandle);

if (false == retVal)
{
CloseHandle(tokenHandle);
Console.WriteLine("Exception thrown in trying to duplicate token.");

return;
}

//Impersonation.
MessageBox.Show("Before impersonation: " +
WindowsIdentity.GetCurrent().Name);

WindowsIdentity newId = new WindowsIdentity(dupeTokenHandle);
WindowsImpersonationContext impersonatedUser = newId.Impersonate();

MessageBox.Show("After impersonation: " +
WindowsIdentity.GetCurrent().Name);
Type t = Type.GetTypeFromProgID( "Microsoft.Update.Session",
txtDomain.Text );

UpdateSession UpdSess = (UpdateSession) Activator.CreateInstance(t);

IUpdateSearcher UpdSrch = UpdSess.CreateUpdateSearcher();
ISearchResult sr = UpdSrch.Search("IsInstalled=0 and Type='Software'");
MessageBox.Show( "Found "+ sr.Updates.Count.ToString() + " updates" );

foreach( IUpdate temp in sr.Updates )
MessageBox.Show( temp.Description.ToString() );

impersonatedUser.Undo();

// Free the tokens.
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);

if (dupeTokenHandle != IntPtr.Zero)
CloseHandle(dupeTokenHandle);
return;
The other strange thing I've noticed is that the 'after impersonation'
message still displays my local userid instead of the remote one. (Even
when
the copy worked successfully).

1. That's normal, LOGON32_LOGON_NEW_CREDENTIALS returns a token that uses
the credentials specified to access the network only, the current thread
token remains the same. Please read the docs. on LogonUser carefully.
2. Initializing DCOM security and impersonating when accessing remote
network shares are diferent beasts, the reason for this is that DCOM
security is initialized by the CLR (by calling CoInitializeSecurity) to use
the process credentials by default. So the reason why it fails is because
the default process security blanket is used when calling into COM/DCOM, If
you wan't to apply different security setings for the process you'll have to
call CoInitializeSecurity very early in the process (at least before your
first call into COM/DCOM).
Willy.


Mar 16 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: PRM | last post by:
Hi I have an ASp.net application using C#. I need to copy a file present on the web server machine to a remote machine on the network. Although this seems to be a trivial matter I am having...
1
by: POnfri | last post by:
Hi, I have a problem in a peace of code were i'm doing a file copy using File.Copy. The Source is local and the target is a remote machine. Example: File.Copy(C:\temp\hi.txt,...
1
by: sajithm | last post by:
Hi all, I have a problem while trying to create folder and files in a remot storage server using asp.net. Actually I was trying with filesystem object and this says bad usernam and passeord,....
11
by: Andre | last post by:
Hi, I have ASP.NET application running on standalone (not part of the domain) Windows 2003. I use forms authentication for my application. The problem I have is that I need to create and read...
2
by: Glen Conway | last post by:
Hi, I am trying to get the contents of a file in a hidden share on a remote server, something like '\\server.domain.com\c$\program files\application\document.xml'. When I try any of the...
1
by: screenbert | last post by:
I have a need to create a web-portal that allows certain users to create DNS A records in a specific domain. I've looked into using WMI to do this in my C# code, but the DNS server is on a...
7
by: Ctal | last post by:
What is the best way to have my windows app run a .bat file on a remote server? The .bat will need to run as an admin on the remote machine. Additonally I need for my windows app to wait for the...
11
by: JCav | last post by:
I need to call a COM object from a remote machine using C#. I also need to pass on a different userID and password to the call. Has anyone done this? I've used Java to do this using JIntegra, but...
4
by: John Straumann | last post by:
Hello all: Most of my development for websites has been on test VPC images where VS is installed on the server image. I now have a setup where I have a test server joined to my domain, and a...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.