我有一个问题无法将所有Sid添加到我当前的循环中。其他一切都按照我的预期运作。我只需要帮助添加我的代码,为我的代码显示的每个用户添加SID。 SID现在将显示。
这是我目前的代码:
namespace ActiveDirectoryDisplayNamesApp
{
class Program
{
static void Main(string[] args)
{
using (var context = new PrincipalContext(ContextType.Domain, "nor-amcoldcorp.local"))
{
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
var sidByte = ObjectToByteArray(de.Properties["objectSId"].Value);
Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
Console.WriteLine("Last Name : " + de.Properties["sn"].Value);
Console.WriteLine("SAM account name : " + de.Properties["samAccountName"].Value);
Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value);
Console.WriteLine("Object Sid: " + System.Text.Encoding.UTF8.GetString(sidByte)); //Here is the changement
Console.WriteLine();
}
}
}
Console.ReadLine();
}
static public byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
}
答案 0 :(得分:0)
编辑:
声明此功能:
private byte[] ObjectToByteArray(Object obj)
{
if(obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
要做到这一点:
byte[] bytes = Encoding.Default.GetBytes(de.Properties["objectSid"].value);
sidByte= Encoding.UTF8.GetString(bytes);
Console.WriteLine("Object Sid: " + sidByte ); //Here is the changement
或者你尝试这个approcah(如果第一个没有用)但保留第一个将你的字节对象转换为byte的函数:
声明一个函数
static string BytesToStringConverted(byte[] bytes)
{
using (var stream = new MemoryStream(bytes))
{
using (var streamReader = new StreamReader(stream))
{
return streamReader.ReadToEnd();
}
}
}
比如那样称呼:
Console.WriteLine("Object Sid: " +BytesToStringConverted (sidByte)
答案 1 :(得分:0)
de.Properties["objectSid"].value
返回一个Byte []数组,以查看您需要将其解析为字符串以获取您正在寻找的功能的SID。可以找到关于如何做到这一点的好帖子here。
以下是将数组转换为可用字符串所需的函数:
public static string ConvertByteToStringSid(Byte[] sidBytes)
{
StringBuilder strSid = new StringBuilder();
strSid.Append("S-");
try
{
// Add SID revision.
strSid.Append(sidBytes[0].ToString());
// Next six bytes are SID authority value.
if (sidBytes[6] != 0 || sidBytes[5] != 0)
{
string strAuth = String.Format
("0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}",
(Int16)sidBytes[1],
(Int16)sidBytes[2],
(Int16)sidBytes[3],
(Int16)sidBytes[4],
(Int16)sidBytes[5],
(Int16)sidBytes[6]);
strSid.Append("-");
strSid.Append(strAuth);
}
else
{
Int64 iVal = (Int32)(sidBytes[1]) +
(Int32)(sidBytes[2] << 8) +
(Int32)(sidBytes[3] << 16) +
(Int32)(sidBytes[4] << 24);
strSid.Append("-");
strSid.Append(iVal.ToString());
// Get sub authority count...
int iSubCount = Convert.ToInt32(sidBytes[7]);
int idxAuth = 0;
for (int i = 0; i < iSubCount; i++)
{
idxAuth = 8 + i * 4;
UInt32 iSubAuth = BitConverter.ToUInt32(sidBytes, idxAuth);
strSid.Append("-");
strSid.Append(iSubAuth.ToString());
}
}
catch (Exception ex)
{
}
return strSid.ToString();
}
以下是调用该函数所需的内容:
System.DirectoryServices.PropertyCollection coll = de.Properties;
object obVal = coll["objectSid"].Value;
string yourSID;
if (null != obVal)
{
yourSID = ConvertByteToStringSid((Byte[])obVal);
}
答案 2 :(得分:0)
已经有一个专用的Sid类,可用于解码Sid数据。
var sidBytes = (byte[])de.Properties["objectSId"].Value;
var sid = new SecurityIdentifier(sidBytes ,0);
string strSid = sid.Value;//Something like S-1-5-21..
。
答案 3 :(得分:0)
对于十六进制形式,应该是:string strAuth = String.Format("0x{0:x2}{1:x2}{2:x2}{3:x2}{4:x2}{5:x2}",
对于 .NET 5,SecurityIdentifier
仅适用于 Windows。
https://github.com/dotnet/runtime/blob/6bc6560e51d1cf58b54561f7be44801864479b8d/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs#L403-L478
发现原版的一些错误
https://www.codeproject.com/articles/3688/how-to-get-user-sid-using-directoryservices-classe
公共静态字符串 ConvertByteToStringSid(Byte[] sidBytes)
"0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}"
,正确:"0x{0:x2}{1:x2}{2:x2}{3:x2}{4:x2}{5:x2}"
)Convert.ToInt32(sidBytes[7])
,正确:Convert.ToInt32(sidBytes[1])
)我遵循了原始实现并与类 SecurityIdentifier
的结果进行了比较,还考虑了注释:
SID 解码错误 Pin
你好, 我认为您的 SID 解码是错误的。子权限的数量是 SID 字节数组中的第 2 个字节,而不是第 8 个,并且主权限的字节存储顺序与您正在读取的顺序不同。
我想分享一个更好的版本,可以在以下位置找到: https://gist.github.com/thohng/8820153f7d1e107b6619b34fd765f887:
public static string ConvertByteToStringSid(byte[] sidBytes)
{
if (sidBytes == null || sidBytes.Length < 8 ||
sidBytes.Length > 68) // maximum 15 sub authorities
return string.Empty;
var span = new ReadOnlySpan<byte>(sidBytes);
var strSid = new StringBuilder("S-");
// Add SID revision.
strSid.Append(span[0]);
// Get sub authority count...
var subAuthoritiesLength = Convert.ToInt32(span[1]);
if (sidBytes.Length != 8 + subAuthoritiesLength * 4)
return string.Empty;
long identifierAuthority =
(((long)span[2]) << 40) +
(((long)span[3]) << 32) +
(((long)span[4]) << 24) +
(((long)span[5]) << 16) +
(((long)span[6]) << 8) +
span[7];
strSid.Append('-');
strSid.Append(identifierAuthority);
span = span[8..];
for (int i = 0; i < subAuthoritiesLength; i++, span = span[4..])
{
strSid.Append('-');
strSid.Append(BitConverter.ToUInt32(span.Slice(0, 4)));
}
return strSid.ToString();
}
和单元测试:
private static Func<byte[], string> GetConvertByteToStringSidService() => LdapHelper.ConvertByteToStringSid;
[Fact]
public void ConvertByteToStringSid_Builtin()
{
var service = GetConvertByteToStringSidService();
var sid = new byte[] { 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 39, 2, 0, 0 };
var result = service(sid);
Assert.Equal("S-1-5-32-551", result);
}
[Fact]
[SupportedOSPlatform("windows")]
public void ConvertByteToStringSid_Builtin_Windows()
{
var sid = new byte[] { 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 39, 2, 0, 0 };
var s2 = new SecurityIdentifier(sid, 0);
Assert.Equal("S-1-5-32-551", s2.ToString());
}
[Fact]
public void ConvertByteToStringSid_Malformed()
{
var service = GetConvertByteToStringSidService();
var sid1 = new byte[] { 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0, 0, 1 };
var result1 = service(sid1);
Assert.Equal("", result1);
var sid2 = new byte[] { 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0 };
var result2 = service(sid2);
Assert.Equal("", result2);
var sid3 = new byte[] { 1, 4, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0, 0 };
var result3 = service(sid3);
Assert.Equal("", result3);
}
[Fact]
public void ConvertByteToStringSid_Max()
{
var service = GetConvertByteToStringSidService();
var sid = new byte[] { 1, 1, 255, 254, 253, 252, 0, 0, 251, 250, 249, 248 };
var result = service(sid);
Assert.Equal("S-1-281470647926784-4177132283", result);
var sid2 = new byte[] { 1, 5, 136, 0, 44, 89, 0xFE, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0, 0 };
var result2 = service(sid2);
Assert.Equal("S-1-149534325472773-21-71093982-54227939-39018152-1025", result2);
}
[Fact]
[SupportedOSPlatform("windows")]
public void ConvertByteToStringSid_Max_Windows()
{
var sid = new byte[] { 1, 1, 255, 254, 253, 252, 0, 0, 251, 250, 249, 248 };
var s1 = new SecurityIdentifier(sid, 0);
Assert.Equal("S-1-281470647926784-4177132283", s1.ToString());
var sid2 = new byte[] { 1, 5, 136, 0, 44, 89, 0xFE, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0, 0 };
var s2 = new SecurityIdentifier(sid2, 0);
Assert.Equal("S-1-149534325472773-21-71093982-54227939-39018152-1025", s2.ToString());
}
[Fact]
public void ConvertByteToStringSid_NullEmpty()
{
var service = GetConvertByteToStringSidService();
var sid1 = Array.Empty<byte>();
var result1 = service(sid1);
Assert.Equal("", result1);
var result2 = service(null);
Assert.Equal("", result2);
}
[Fact]
public void ConvertByteToStringSid_Success()
{
var service = GetConvertByteToStringSidService();
var sid = new byte[] { 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0, 0 };
var result = service(sid);
Assert.Equal("S-1-5-21-71093982-54227939-39018152-1025", result);
}
[Fact]
[SupportedOSPlatform("windows")]
public void ConvertByteToStringSid_Windows()
{
var sid = new byte[] { 1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 222, 206, 60, 4, 227, 115, 59, 3, 168, 94, 83, 2, 1, 4, 0, 0 };
var s1 = new SecurityIdentifier(sid, 0);
Assert.Equal("S-1-5-21-71093982-54227939-39018152-1025", s1.ToString());
}