Beispiel #1
0
        /// <summary>
        ///     Performs a user impersonation based on a logon token.
        /// </summary>
        /// <param name="token"> The logon token. </param>
        /// <param name="loadUserProfile"> Specifies whether the users profile is to be loaded. </param>
        /// <param name="func"> The code to run under the impersonated user. </param>
        /// <returns>
        ///     The return value from <paramref name="func" />.
        /// </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="func" /> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="token" /> is zero. </exception>
        /// <exception cref="SecurityException"> The current user does not have sufficient permissions. </exception>
        /// <exception cref="Win32Exception">
        ///     The current user does not have sufficient permissions or the impersonation could not
        ///     be completed.
        /// </exception>
        public static Task <TResult> RunImpersonatedAsync <TResult> (IntPtr token, bool loadUserProfile,
                                                                     ImpersonatedFuncAsync <TResult> func)
        {
            if (func == null)
            {
                throw new ArgumentNullException(nameof(func));
            }

            if (token == IntPtr.Zero)
            {
                throw new ArgumentException("The token is zero.", nameof(token));
            }

            Task <TResult> result = WindowsIdentity.RunImpersonatedAsync(new SafeAccessTokenHandle(token), async() =>
            {
                WindowsIdentity identity   = null;
                WindowsUserProfile profile = null;

                try
                {
                    identity = new WindowsIdentity(token);

                    if (loadUserProfile)
                    {
                        USERPROFILE profileInfo = new USERPROFILE();
                        profileInfo.dwSize      = Marshal.SizeOf(profileInfo);
                        profileInfo.lpUserName  = identity.Name;
                        profileInfo.dwFlags     = 1;

                        bool loadSuccess = WindowsUser.LoadUserProfile(token, ref profileInfo);

                        if (!loadSuccess)
                        {
                            int errorCode       = WindowsApi.GetLastErrorCode();
                            string errorMessage = WindowsApi.GetErrorMessage(errorCode);
                            throw new Win32Exception(errorCode, errorMessage);
                        }

                        profile = new WindowsUserProfile(profileInfo);
                    }

                    return(await func(token, identity, profile));
                }
                finally
                {
                    if (profile != null)
                    {
                        WindowsUser.UnloadUserProfile(token, profile.NativeUserProfile.hProfile);
                    }

                    if (identity != null)
                    {
                        identity.Dispose();
                    }
                }
            });

            return(result);
        }
Beispiel #2
0
 /// <summary>
 ///     Gets the user name of the current user.
 /// </summary>
 /// <returns>
 ///     The user name of the current user.
 /// </returns>
 public static string GetCurrentUser()
 {
     using (WindowsIdentity identity = WindowsIdentity.GetCurrent(false))
     {
         WindowsUser.ExtractDomainAndUser(identity.Name, false, false, out _, out string username);
         return(username);
     }
 }
Beispiel #3
0
 /// <summary>
 ///     Gets the domain of the current user.
 /// </summary>
 /// <returns>
 ///     The domain of the current user.
 /// </returns>
 public static string GetCurrentDomain()
 {
     using (WindowsIdentity identity = WindowsIdentity.GetCurrent(false))
     {
         WindowsUser.ExtractDomainAndUser(identity.Name, false, false, out string domain, out _);
         return(domain);
     }
 }
Beispiel #4
0
        /// <summary>
        ///     Resolves a user.
        /// </summary>
        /// <param name="user"> The user to resolve. </param>
        /// <returns>
        ///     Either the user name specified by <paramref name="user" /> or the current user (<see cref="GetCurrentUser" />) if
        ///     <paramref name="user" /> is an empty string or a &quot;.&quot;.
        /// </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="user" /> is null. </exception>
        public static string ResolveUser(string user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (string.IsNullOrWhiteSpace(user) ||
                string.Equals(user.Trim(), ".", StringComparison.InvariantCultureIgnoreCase))
            {
                return(WindowsUser.GetCurrentUser());
            }

            return(user);
        }
Beispiel #5
0
        /// <summary>
        ///     Resolves a domain.
        /// </summary>
        /// <param name="domain"> The domain to resolve. </param>
        /// <returns>
        ///     Either the domain name specified by <paramref name="domain" /> or the local domain (<see cref="GetLocalDomain" />)
        ///     if <paramref name="domain" /> is an empty string or a &quot;.&quot;.
        /// </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="domain" /> is null. </exception>
        public static string ResolveDomain(string domain)
        {
            if (domain == null)
            {
                throw new ArgumentNullException(nameof(domain));
            }

            if (string.IsNullOrWhiteSpace(domain) ||
                string.Equals(domain.Trim(), ".", StringComparison.InvariantCultureIgnoreCase))
            {
                return(WindowsUser.GetLocalDomain());
            }

            return(domain);
        }
Beispiel #6
0
        /// <summary>
        ///     Performs a user impersonation based on a logon token.
        /// </summary>
        /// <param name="token"> The logon token. </param>
        /// <param name="loadUserProfile"> Specifies whether the users profile is to be loaded. </param>
        /// <param name="action"> The code to run under the impersonated user. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="action" /> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="token" /> is zero. </exception>
        /// <exception cref="SecurityException"> The current user does not have sufficient permissions. </exception>
        /// <exception cref="Win32Exception">
        ///     The current user does not have sufficient permissions or the impersonation could not
        ///     be completed.
        /// </exception>
        public static Task RunImpersonatedAsync(IntPtr token, bool loadUserProfile,
                                                ImpersonatedActionAsync action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (token == IntPtr.Zero)
            {
                throw new ArgumentException("The token is zero.", nameof(token));
            }

            return(WindowsUser.RunImpersonatedAsync <object>(token, loadUserProfile, async(ptr, identity, profile) =>
            {
                await action(ptr, identity, profile);
                return null;
            }));
        }
Beispiel #7
0
        /// <summary>
        ///     Performs a user impersonation based on a logon token.
        /// </summary>
        /// <param name="token"> The logon token. </param>
        /// <param name="loadUserProfile"> Specifies whether the users profile is to be loaded. </param>
        /// <param name="action"> The code to run under the impersonated user. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="action" /> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="token" /> is zero. </exception>
        /// <exception cref="SecurityException"> The current user does not have sufficient permissions. </exception>
        /// <exception cref="Win32Exception">
        ///     The current user does not have sufficient permissions or the impersonation could not
        ///     be completed.
        /// </exception>
        public static void RunImpersonated(IntPtr token, bool loadUserProfile,
                                           ImpersonatedAction action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            if (token == IntPtr.Zero)
            {
                throw new ArgumentException("The token is zero.", nameof(token));
            }

            WindowsUser.RunImpersonated <object>(token, loadUserProfile, (ptr, identity, profile) =>
            {
                action(ptr, identity, profile);
                return(null);
            });
        }
Beispiel #8
0
        /// <summary>
        ///     Gets the logon domain, or the domain the local computer has joined respectively.
        /// </summary>
        /// <returns>
        ///     The domain the local computer has joined.
        /// </returns>
        public static string GetNetworkDomain()
        {
            using (ManagementObject mgmtObj =
                       new ManagementObject("Win32_ComputerSystem.Name='" + WindowsUser.GetLocalDomain() + "'"))
            {
                mgmtObj.Get();

                string networkDomain = mgmtObj["domain"]
                                       .ToString();

                if (string.IsNullOrWhiteSpace(networkDomain) ||
                    string.Equals(networkDomain.Trim(), ".", StringComparison.InvariantCultureIgnoreCase))
                {
                    networkDomain = WindowsUser.GetLocalDomain();
                }

                return(networkDomain);
            }
        }
Beispiel #9
0
        /// <summary>
        ///     Performs a user logon and creates a logon token for that user.
        /// </summary>
        /// <param name="domain"> The domain (null or an empty string to use the local machine). </param>
        /// <param name="user"> The user name (null or an empty string to use the current user name). </param>
        /// <param name="password"> The optional password (null or empty string if not used). </param>
        /// <param name="token"> The created logon token. </param>
        /// <remarks>
        ///     <para>
        ///         Before being used for the logon, <paramref name="domain" /> and <paramref name="user" /> are processed by
        ///         <see cref="ResolveDomain" /> and <see cref="ResolveUser" /> respectively.
        ///     </para>
        /// </remarks>
        /// <exception cref="Win32Exception"> The current user does not have sufficient permissions or the logon failed. </exception>
        public static void CreateLogonToken(string domain, string user, string password, out IntPtr token)
        {
            domain ??= string.Empty;
            user ??= string.Empty;
            password = string.IsNullOrEmpty(password) ? null : password;

            domain = WindowsUser.ResolveDomain(domain);
            user   = WindowsUser.ResolveUser(user);

            token = IntPtr.Zero;

            bool returnValue = WindowsUser.LogonUser(user, domain, password, WindowsUser.Logon32LogonInteractive,
                                                     WindowsUser.Logon32ProviderDefault, ref token);

            if ((!returnValue) || (token == IntPtr.Zero))
            {
                int    errorCode    = WindowsApi.GetLastErrorCode();
                string errorMessage = WindowsApi.GetErrorMessage(errorCode);
                throw new Win32Exception(errorCode, errorMessage);
            }
        }
Beispiel #10
0
        /// <summary>
        ///     Resolves the domain and username of a user as specified by a SID.
        /// </summary>
        /// <param name="sid"> The SID to resolve. </param>
        /// <param name="domain"> The domain the resolved user belongs to. </param>
        /// <param name="user"> The username of the resolved user. </param>
        /// <returns>
        ///     true if the SID was successfully resolved, false otherwise.
        /// </returns>
        /// <remarks>
        ///     <value>
        ///         For well-known-users/SIDs, the resolved username depends on the system language.
        ///     </value>
        /// </remarks>
        /// <exception cref="ArgumentNullException"> <paramref name="sid" /> is null. </exception>
        /// <exception cref="Win32Exception"> The resolve failed. </exception>
        public static bool GetUserFromSid(SecurityIdentifier sid, out string domain, out string user)
        {
            if (sid == null)
            {
                throw new ArgumentNullException(nameof(sid));
            }

            domain = null;
            user   = null;

            byte[] sidBytes = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidBytes, 0);

            uint capacity = 1024;

            StringBuilder domainBuilder = new StringBuilder((int)capacity);
            StringBuilder nameBuilder   = new StringBuilder((int)capacity);

            bool success =
                WindowsUser.LookupAccountSid(null, sidBytes, nameBuilder, ref capacity, domainBuilder, ref capacity,
                                             out _);

            if (!success)
            {
                int errorCode = WindowsApi.GetLastErrorCode();

                if (errorCode != (int)WindowsError.ErrorNoneMapped)
                {
                    string errorMessage = WindowsApi.GetErrorMessage(errorCode);
                    throw new Win32Exception(errorCode, errorMessage);
                }

                return(false);
            }

            domain = domainBuilder.ToString();
            user   = nameBuilder.ToString();

            return(true);
        }
Beispiel #11
0
        /// <summary>
        ///     Extracts domain and user name from logon information.
        /// </summary>
        /// <param name="logon"> The logon information (either user or domain\user). </param>
        /// <param name="resolveDomain"> Specifies whether the extracted domain should be resolved. </param>
        /// <param name="resolveUser"> Specifies whether the extracted user should be resolved. </param>
        /// <param name="domain"> The extracted domain. Null if no domain information is available. </param>
        /// <param name="user"> The extracted user name. Null if no user information is available. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="logon" /> is null. </exception>
        /// <exception cref="ArgumentException"> <paramref name="logon" /> is an empty string. </exception>
        public static void ExtractDomainAndUser(string logon, bool resolveDomain, bool resolveUser, out string domain, out string user)
        {
            if (logon == null)
            {
                throw new ArgumentNullException(nameof(logon));
            }

            if (string.IsNullOrWhiteSpace(logon))
            {
                throw new ArgumentException("The string is empty.", nameof(logon));
            }

            int index = logon.IndexOf('\\');

            if (index == -1)
            {
                domain = null;
                user   = logon;
            }
            else
            {
                if (index == 0)
                {
                    domain = null;
                }
                else
                {
                    domain = logon.Substring(0, index);
                }

                if (index >= (logon.Length - 1))
                {
                    user = null;
                }
                else
                {
                    user = logon.Substring(index + 1);
                }
            }

            user ??= string.Empty;
            domain ??= string.Empty;

            if (resolveUser)
            {
                if (string.IsNullOrWhiteSpace(user) ||
                    string.Equals(user.Trim(), ".", StringComparison.InvariantCultureIgnoreCase))
                {
                    user = WindowsUser.GetCurrentUser();
                }
            }

            if (resolveDomain)
            {
                if (string.IsNullOrWhiteSpace(domain) ||
                    string.Equals(domain.Trim(), ".", StringComparison.InvariantCultureIgnoreCase))
                {
                    domain = WindowsUser.GetLocalDomain();
                }
            }
        }
Beispiel #12
0
 /// <summary>
 ///     Closes a logon token.
 /// </summary>
 /// <param name="token"> The logon token. </param>
 public static void CloseLogonToken(IntPtr token)
 {
     WindowsUser.CloseHandle(token);
 }
Beispiel #13
0
 /// <summary>
 ///     Gets the localized username for the "Everyone" user.
 /// </summary>
 /// <returns>
 ///     The localized username for the "Everyone" user.
 /// </returns>
 public static string GetEveryoneUserName()
 {
     WindowsUser.GetUserFromSid(new SecurityIdentifier(WellKnownSidType.WorldSid, null), out _, out string user);
     return(user);
 }
Beispiel #14
0
 /// <summary>
 ///     Gets the current users default culture.
 /// </summary>
 /// <returns>
 ///     The culture of the current user.
 /// </returns>
 /// <remarks>
 ///     <para>
 ///         The returned <see cref="CultureInfo" /> specifies the formatting culture of the current user.
 ///         It is not necessarily the same as for example <see cref="CultureInfo.CurrentCulture" /> as this might have been
 ///         modified by your or some other code.
 ///         <see cref="GetCurrentDefaultCulture" /> retrieves the default culture of the current user.
 ///     </para>
 /// </remarks>
 public static CultureInfo GetCurrentDefaultCulture()
 {
     return(new CultureInfo(WindowsUser.GetUserDefaultUILanguage(), true));
 }