Feed
Google+
Contact
XING
LinkedIn
Twitter
ICQ
meebo.com

Impersonate an application

by Roland Schumacher alias GENiALi 6. Oktober 2005 -- 450 words  -- 1 mal gelesen

You can use it over and over again. You have a program that under a
running user other than the logged-on.
This I found a link in MS which shows how to do it, however,
in a console application.

WindowsIdentity.Impersonate method
 
In principle this works too. I have now made me a class, the
me it slightly easier provides.
It has two public static methods. A to the change of identity, the
others return to the old.
Here the code.

/*
Original habe ich bei MS gefunden.
http://msdn.microsoft.com/library/deu/default.asp?url=/library/DEU/cpref/html/frlrfSystemSecurityPrincipalWindowsIdentityClassImpersonateTopic.asp
*/


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

namespace Test
{
    /// <summary>
    /// Zusammenfassung für ChangeIdentity.
    /// </summary>
    publicclass ChangeIdentity
    {
        #region Variabeln

        /****************************************************************************/
        /***** Variablen                                                        *****/
        /****************************************************************************/
        privatestatic IntPtr tokenHandle =new IntPtr(0);
        privatestatic IntPtr dupeTokenHandle =new IntPtr(0);
        //Deklaration benötigter API-Funktionen und Konstanten
        privateconstint LOGON32_PROVIDER_DEFAULT = 0;
        privateconstint LOGON32_LOGON_INTERACTIVE = 2;
        privateconstint SecurityImpersonation = 2;

        [DllImport("advapi32.dll", SetLastError=true)]
        privatestaticexternbool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        [DllImport("kernel32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)]
        privatestaticexternunsafeint FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);

        [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
        privatestaticexternbool CloseHandle(IntPtr handle);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        privatestaticexternbool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

        //Das wird benötigt um die Personifizierung wieder rückgängig zu machen.
        privatestatic WindowsImpersonationContext impersonatedUser =null;
        /****************************************************************************/
        /***** Ende Variablen                                                    *****/
        /****************************************************************************/

        #endregion

        #region Methoden

        /****************************************************************************/
        /***** Methoden                                                            *****/
        /****************************************************************************/

        /// <summary>
        /// Wechselt den Benutzer, unter dem das Programm ausgeführt werden soll.
        /// </summary>
        /// <param name="Domain">Name der Domäne</param>
        /// <param name="UserName">User Name, unter dem das Programm laufen soll</param>
        /// <param name="Passwort">Das passende Passwort</param>
        publicstaticvoid ImpersonateUser(string Domain, string UserName, string Passwort)
        {
            tokenHandle = IntPtr.Zero;
            dupeTokenHandle = IntPtr.Zero;
            
            //Mit dem gewünschten User anmelden.
            bool returnValue = LogonUser(UserName, Domain, Passwort, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
            
            //Bei einem Fehler, z.b. falschen Namen, falsches Passwort, soll eine Exception geworfen werden.
            if(false == returnValue)
            {
                int ret = Marshal.GetLastWin32Error();
                string fehler = GetErrorMessage(ret);
                string f ="Errorcode: "+ ret.ToString() + Environment.NewLine;
                f += fehler;
                thrownew Exception(f);
            }

            //Für was??? Weiss ich nicht so genau. :-)s
            bool retVal = DuplicateToken(tokenHandle, SecurityImpersonation, ref dupeTokenHandle);
            
            if(false == retVal)
            {
                CloseHandle(tokenHandle);
                thrownew Exception("Fehler beim Dublizieren des Token.");
            }
            
            //Die Intentität wechseln.
            WindowsIdentity newId =new WindowsIdentity(dupeTokenHandle);
            impersonatedUser = newId.Impersonate();
            
            //Die Token wieder freigeben.
            if(tokenHandle != IntPtr.Zero)
                CloseHandle(tokenHandle);
            if(dupeTokenHandle != IntPtr.Zero)
                CloseHandle(dupeTokenHandle);
        }

        /*----------------------------------------------------------------------------------------------*/
        /// <summary>
        /// Die Identität wieder zurücksetzen.
        /// </summary>
        publicstaticvoid UndoImpersonateUser()
        {
            if(impersonatedUser !=null)
            {
                impersonatedUser.Undo();
            }
        }
        /*----------------------------------------------------------------------------------------------*/
        /// <summary>
        /// Gibt den letzten Win32Error zurück.
        /// Habe ich 1:1 aus dem Beispiel übernommen.
        /// </summary>
        privatestaticunsafestring GetErrorMessage(int errorCode)
        {
            int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
            int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
            int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
            //int errorCode = 0x5; //ERROR_ACCESS_DENIED
            //throw new System.ComponentModel.Win32Exception(errorCode);
            int messageSize = 255;
            String lpMsgBuf ="";
            int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
            IntPtr ptrlpSource = IntPtr.Zero;
            IntPtr prtArguments = IntPtr.Zero;
            int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
            if(0 == retVal)
            {
                thrownew Exception("Failed to format message for error code "+ errorCode +". ");
            }
            return lpMsgBuf;
        }

        /****************************************************************************/
        /***** Ende Methoden                                                    *****/
        /****************************************************************************/

        #endregion
    }
}

You can apply them as follows. Made I have it in a WinForm application.

/ / / < summary >

/ / / The main entry point for the application.
/ / / < / summary >
[STAThread]
staticvoid Main()
{
'S application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);

    try
{
ChangeIdentity.ImpersonateUser ("DOMAIN", "username", "Password");
}
    catch(Exception ex)
{
MessageBox.Show (ex.message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
}

Application.run (new FrmMain());)

ChangeIdentity.UndoImpersonateUser();
}
 
Keep in mind is that it so much I was sleeping, so simply works only with Windows XP and Windows Server 2003.
On Windows 2000 and NT4, the user running the program must have the privilege SE_TCP_NAME.

Tags:

Kommentare sind geschlossen

Statistik

Gesamte Posts: 1025
Dieses Jahr: 7
Diesen Monat: 1
Diese Woche: 0
Kommentare: 929
Total Bewertungen: 91
Ø Bewertung: 4,42
Meisten Kommentare
Google+ ... (28)
Beste Ø Bewertung
Tastaturlayout von Visual Stud ... (5)
Meiste Bewertungen
Windows 7 und die ersten Erfah ... (5)

Buttons

Stop Spam Harvesters, Join Project Honey Pot Benutzerprofil von GENiALi connection speed test network connection Bloggeramt.de Slug.ch Blog Verzeichnis und Blog Webkatalog Schumacher Roland Seitwert Valid XHTML 1.0 Transitional

writing