/// <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); }
/// <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); } }
/// <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); } }
/// <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 ".". /// </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); }
/// <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 ".". /// </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); }
/// <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; })); }
/// <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); }); }
/// <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); } }
/// <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); } }
/// <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); }
/// <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(); } } }
/// <summary> /// Closes a logon token. /// </summary> /// <param name="token"> The logon token. </param> public static void CloseLogonToken(IntPtr token) { WindowsUser.CloseHandle(token); }
/// <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); }
/// <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)); }