/// <summary>Converts the value of a security identifier (SID) to its equivalent string representation according to the provided format specifier.</summary> /// <param name="pSid">A pointer to a valid SID structure.</param> /// <param name="format"> /// A single format specifier that indicates how to format the value of this security identifier (SID). The format parameter can be /// "B" (binary), "D" (sddl), "N" (name), or "P" (upn). If format is null or an empty string (""), "D" is used. /// </param> /// <returns>The value of this security identifier (SID), in the specified format.</returns> /// <exception cref="ArgumentException">SID value is not a valid SID. - pSid</exception> /// <exception cref="FormatException">The value of format is not null, an empty string (""), "B", "D", "N", or "P".</exception> /// <remarks> /// <para>The following table shows the accepted format specifiers for the format parameter.</para> /// <list type="table"> /// <item> /// <description>Specifier</description> /// <description>Format of return value</description> /// </item> /// <item> /// <description>"B"</description> /// <description> /// <para>Binary hex dump representation of the SID.</para> /// </description> /// </item> /// <item> /// <description>"D"</description> /// <description>SDDL representation of the SID.</description> /// </item> /// <item> /// <description>"N"</description> /// <description>The NT4 style name (domain\username) corresponding to the SID.</description> /// </item> /// <item> /// <description>"P"</description> /// <description>The internet style name (UPN) corresponding to the SID.</description> /// </item> /// </list> /// </remarks> public static string ToString(this PSID pSid, string format) { if (!pSid.IsValidSid()) { throw new ArgumentException("SID value is not a valid SID.", nameof(pSid)); } switch (format) { case "B": var len = pSid.Length(); return(pSid.GetBinaryForm().ToHexDumpString(len, len, 0).Trim(' ', '\r', '\n')); case "D": case null: case "": try { return(AdvApi32.ConvertSidToStringSid(pSid)); } catch { goto case "B"; } case "N": case "P": using (var hPol = AdvApi32.LsaOpenPolicy(AdvApi32.LsaPolicyRights.POLICY_ALL_ACCESS)) { var flag = format == "P" ? AdvApi32.LsaLookupSidsFlags.LSA_LOOKUP_PREFER_INTERNET_NAMES : 0; try { AdvApi32.LsaLookupSids2(hPol, flag, 1, new[] { pSid }, out var memDoms, out var memNames).ThrowIfFailed(); memDoms.Dispose(); using (memNames) { return(memNames.ToStructure <AdvApi32.LSA_TRANSLATED_NAME>().Name); } } catch (Exception) { goto case "D"; } } default: throw new FormatException(); } }
public static string GetUserSidFromSessionId(UInt32 sessionId) // Gets the unique Security Identifier (SID) // of the User logged on to 'sessionId' { IntPtr token = (IntPtr)0; IntPtr tokenInf = IntPtr.Zero; uint tokenInfLen = 0; IntPtr szSid = IntPtr.Zero; string sid; try { AcquireSystemPrivilege(AdvApi32.SE_TCB_NAME); Trace.WriteLine("Using session id " + sessionId.ToString()); if (!WtsApi32.WTSQueryUserToken(sessionId, out token)) { Win32Error.Set("WTSQueryUserToken"); throw new Exception(Win32Error.GetFullErrMsg()); } // Get tokenInfLen AdvApi32.GetTokenInformation( token, AdvApi32.TOKEN_INFORMATION_CLASS.TokenUser, tokenInf, tokenInfLen, out tokenInfLen ); Win32Error.Set("GetTokenInformation"); if (Win32Error.GetErrorNo() != WinError.ERROR_INSUFFICIENT_BUFFER) { throw new Exception(Win32Error.GetFullErrMsg()); } tokenInf = Marshal.AllocHGlobal((int)tokenInfLen); if (!AdvApi32.GetTokenInformation( token, AdvApi32.TOKEN_INFORMATION_CLASS.TokenUser, tokenInf, tokenInfLen, out tokenInfLen)) { Win32Error.Set("GetTokenInformation"); throw new Exception(Win32Error.GetFullErrMsg()); } AdvApi32.TOKEN_USER tokenUser = (AdvApi32.TOKEN_USER)Marshal.PtrToStructure( tokenInf, typeof(AdvApi32.TOKEN_USER) ); if (!AdvApi32.ConvertSidToStringSid( tokenUser.User.Sid, out szSid)) { Win32Error.Set("ConvertSidToStringSid"); throw new Exception(Win32Error.GetFullErrMsg()); } sid = Marshal.PtrToStringAuto(szSid); return(sid); } finally { if (szSid != IntPtr.Zero) { Kernel32.LocalFree(szSid); } if (tokenInf != IntPtr.Zero) { Marshal.FreeHGlobal(tokenInf); } if (token != IntPtr.Zero) { Kernel32.CloseHandle(token); } } }