Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2006

Tip: Looking for answers? Try searching our database.

Create remote object with specified credentials.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Heliotic - 28 Oct 2005 04:37 GMT
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.   
Nicholas Paldino [.NET/C# MVP] - 28 Oct 2005 20:32 GMT
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.

Signature

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

> Hi everyone,
>
[quoted text clipped - 16 lines]
> 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.
Heliotic - 31 Oct 2005 06:26 GMT
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?

> Heliotic,
>
[quoted text clipped - 33 lines]
> > 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.
Willy Denoyette [MVP] - 31 Oct 2005 16:51 GMT
> Thanks Nicholas,
>
[quoted text clipped - 7 lines]
> with
> some code to copy a file, and it worked fine.

> Here is the code I am currently using (apologies for the spam):
>
[quoted text clipped - 75 lines]
> 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.
Tommy was - 16 Mar 2006 22:26 GMT
> > Thanks Nicholas,
> >
[quoted text clipped - 101 lines]
>
> Willy.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.