private static string GetTextualSid(PSID pSid) { const int SID_REVISION = 1; // // test if parameters passed in are valid, IsValidSid can not take // a NULL parameter // if (pSid.IsNull || !pSid.IsValidSid()) { throw new ArgumentException(nameof(pSid)); } // obtain SidIdentifierAuthority var psia = GetSidIdentifierAuthority(pSid); // obtain sidsubauthority count var dwSubAuthorities = GetSidSubAuthorityCount(pSid); // // compute approximate buffer length // S-SID_REVISION- + identifierauthority + -subauthorities + NULL // var cchMaxLen = 6 + 14 + 11 * dwSubAuthorities + 1; var TextualSid = new StringBuilder(cchMaxLen); // // prepare S-SID_REVISION- // TextualSid.AppendFormat("S-{0}-", SID_REVISION); // // prepare SidIdentifierAuthority // if (psia.Value[0] != 0 || psia.Value[1] != 0) { TextualSid.AppendFormat("0x{0:X2}{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}", psia.Value[0], psia.Value[1], psia.Value[2], psia.Value[3], psia.Value[4], psia.Value[5]); } else { TextualSid.Append(psia.Value[5] + (uint)(psia.Value[4] << 8) + (uint)(psia.Value[3] << 16) + (uint)(psia.Value[2] << 24)); } // // loop through SidSubAuthorities // for (var dwCounter = 0U; dwCounter < dwSubAuthorities; dwCounter++) { TextualSid.AppendFormat("-{0}", GetSidSubAuthority(pSid, dwCounter)); } return(TextualSid.ToString()); }
/// <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(); } }
/// <summary>Gets the binary form of the SID structure.</summary> /// <param name="pSid">The SID structure pointer.</param> /// <returns>The binary form (byte array) of the SID structure.</returns> public static byte[] GetBinaryForm(this PSID pSid) => pSid.IsValidSid() ? ((IntPtr)pSid).ToArray <byte>(pSid.Length()) : (new byte[0]);