Wednesday, February 22, 2012

set and remove impersonation programmatically / runtime

/// <summary>
    /// <Description> This code is from http://support.microsoft.com/kb/306158 </Description>
    /// </summary>
    public class CallImpersonation
    {
        public const int LOGON32_LOGON_INTERACTIVE = 2;
        public const int LOGON32_PROVIDER_DEFAULT = 0;
        WindowsImpersonationContext impersonationContext;
        [DllImport("advapi32.dll")]
        public static extern int LogonUserA(String lpszUserName, String lpszDomain,
            String lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int DuplicateToken(IntPtr hToken, int impersonationLevel,
            ref IntPtr hNewToken);
        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool RevertToSelf();
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern bool CloseHandle(IntPtr handle);
        /// <summary>
        /// Turn on the impersonation
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="domain"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool ImpersonateValidUser(String userName, String domain, String password)
        {
            WindowsIdentity ident = WindowsIdentity.GetCurrent();
            WindowsPrincipal user = new WindowsPrincipal(ident);
            WindowsIdentity tempWindowsIdentity;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;
            if (RevertToSelf())
            {
                if (LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
                    LOGON32_PROVIDER_DEFAULT, ref token) != 0)
                {
                    if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
                    {
                        tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
                        impersonationContext = tempWindowsIdentity.Impersonate();
                        if (impersonationContext != null)
                        {
                            CloseHandle(token);
                            CloseHandle(tokenDuplicate);
                            return true;
                        }
                    }
                }
            }
            if (token != IntPtr.Zero)
                CloseHandle(token);
            if (tokenDuplicate != IntPtr.Zero)
                CloseHandle(tokenDuplicate);
            return false;
        }
        /// <summary>
        /// Trunoff the impersonation.
        /// </summary>
        public void UndoImpersonation()
        {
            impersonationContext.Undo();
        }
        /// <summary>
        /// <Description>Get the credential for impersonation</Description>
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="domain"></param>
        /// <param name="password"></param>
        /// <param name="client"></param>
        /// <param name="key"></param>
        /// <param name="eBase"></param>
        /// <returns></returns>
        public bool GetImpersonateCredentials(out string userName, out string domain, out string password, string client, int key, ErgoBase eBase)
        {
            ErgoBase ebase = eBase;
            try
            {
                string fetchForExistingSql = "SELECT egemimp_guid,domainName,username,password_ue FROM egem_impersonation " +
                  "WHERE client = @client " +
                  "AND valid=   @valid " +
                  "AND status = @status ";
                ebase.Db.AddParameter("@client", client);
                ebase.Db.AddParameter("@valid", 1);
                ebase.Db.AddParameter("@status", "N");
                System.Data.DataTable dtforRegisteredusers = ebase.Db.GetDataTable(fetchForExistingSql);
                if (dtforRegisteredusers.Rows.Count > 0)
                {
                    domain = dtforRegisteredusers.Rows[0]["domainName"].ToString();
                    userName = dtforRegisteredusers.Rows[0]["username"].ToString();
                    password = EmploymentSettings.Decrypt(dtforRegisteredusers.Rows[0]["password_ue"].ToString(), key);
                    return true;
                }
                else
                {
                    domain = string.Empty;
                    userName = string.Empty;
                    password = string.Empty;
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
   

No comments: