Active Directory 访问规则不像 dsacls 那样具体
Active Directory Access Rules aren't as specific as dsacls
所以我正在尝试从特定的 OU 获取 ACE 列表。我发现了 ActiveDirectoryAccess 规则 class.
输出给出的结果似乎不像 dsacls 命令的输出那样具体 (https://technet.microsoft.com/en-us/library/cc771151%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396)
如何使我的 C# 代码获得更多类似于 dsacls 的描述性结果? (更好的显示名称)
这是我的测试输出结果的一个子集
Domain\myGroup
Inherits - Descendents
ObjectType - 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectType - bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags - ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType - Allow
ActiveDirectoryRights - ExtendedRight
IsInherited - True
PropagationFlags - InheritOnly
-------
Domain\myGroup
Inherits - Descendents
ObjectType - bf967a0a-0de6-11d0-a285-00aa003049e2
InheritedObjectType - bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags - ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType - Allow
ActiveDirectoryRights - ReadProperty, WriteProperty
IsInherited - True
PropagationFlags - InheritOnly
-------
Domain\myGroup
Inherits - Descendents
ObjectType - 28630ebf-41d5-11d1-a9c1-0000f80367c1
InheritedObjectType - bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags - ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType - Allow
ActiveDirectoryRights - ReadProperty, WriteProperty
IsInherited - True
PropagationFlags - InheritOnly
这是 dsacls 的输出
Allow Domain\myGroup Reset Password <Inherited from parent>
Allow Domain\myGroup SPECIAL ACCESS for lockoutTime <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Allow Domain\myGroup SPECIAL ACCESS for pwdLastSet <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
通过查看LDAP://cn=Extended-rights,CN=Configuration,Dc=Mydomain下的一些objecttype代码
我可以说
00299570-246d-11d0-a768-00aa006e0529 映射到重置密码
但我找不到任何匹配 - 28630ebf-41d5-11d1-a9c1-0000f80367c1 或 bf967a0a-0de6-11d0-a285-00aa003049e2
获取特定 OU 的 ACE 输出的代码。
[Test]
public void ForWhosebug()
{
var cfg = new DirectoryEntry("LDAP://PathToMyOU");
var cfgsearch = new DirectorySearcher(cfg);
cfgsearch.Filter = "(name=*)";
cfgsearch.PropertiesToLoad.Add("distinguishedName");
cfgsearch.SearchScope = SearchScope.Subtree;
var res = cfgsearch.FindAll();
var ouDE = res[0].GetDirectoryEntry();
var accessRules = ouDE.ObjectSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (ActiveDirectoryAccessRule ar in accessRules)
{
Console.WriteLine($"{ar.IdentityReference.ToString()}");
Console.WriteLine($"Inherits - {ar.InheritanceType.ToString()}");
Console.WriteLine($"ObjectType - {ar.ObjectType.ToString()}");
Console.WriteLine($"InheritedObjectType - {ar.InheritedObjectType.ToString()}");
Console.WriteLine($"ObjectFlags - {ar.ObjectFlags.ToString()}");
Console.WriteLine($"AccessControlType - {ar.AccessControlType.ToString()}");
Console.WriteLine($"ActiveDirectoryRights - {ar.ActiveDirectoryRights.ToString()}");
Console.WriteLine($"IsInherited - {ar.IsInherited.ToString()}");
Console.WriteLine($"PropagationFlags - {ar.PropagationFlags.ToString()}");
Console.WriteLine("-------");
}
}
我用来获取一些对象 guid displayname 的代码
[Test]
public void ForWhosebugAllExtendedRights()
{
DirectoryEntry rootdse = new DirectoryEntry("LDAP://RootDSE");
DirectoryEntry cfg = new DirectoryEntry("LDAP://" + rootdse.Properties["configurationnamingcontext"].Value);
DirectoryEntry exRights = new DirectoryEntry("LDAP://cn=Extended-rights," + rootdse.Properties["configurationnamingcontext"].Value);
Hashtable exRighthash = new Hashtable();
foreach (DirectoryEntry chent in exRights.Children)
{
if (chent.Properties["rightsGuid"].Value != null && !exRighthash.ContainsKey(chent.Properties["rightsGuid"].Value))
{
exRighthash.Add(chent.Properties["rightsGuid"].Value, chent.Properties["DisplayName"].Value);
Console.WriteLine($"{chent.Properties["rightsGuid"].Value}, {chent.Properties["DisplayName"].Value}");
}
}
}
更新 #1
我设法找到了一段代码(来自本书https://www.amazon.com/s/?url=search-alias=stripbooks&field-keywords=0321350170&tag=technicalibra-20&link_code=wql&camp=212361&creative=380601&_encoding=UTF-8)
检查受影响的帐户类型。
我现在更接近了。有些条款不匹配(例如将密码重置为 User-Force-Change-Password),有些条款未显示
这是我之前示例的结果。
Identity: Domain\Mygroup
AccessControlType: Allow
ActiveDirectoryRights: ExtendedRight
InheritanceType: Descendents
ObjectType: 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: ObjectAceTypePresent, InheritedObjectAceTypePresent
{00299570-246d-11d0-a768-00aa006e0529}=
{00299570-246d-11d0-a768-00aa006e0529}=User-Force-Change-Password
Identity: Domain\Mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: Descendents
ObjectType: bf967a0a-0de6-11d0-a285-00aa003049e2
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: ObjectAceTypePresent, InheritedObjectAceTypePresent
{bf967a0a-0de6-11d0-a285-00aa003049e2}=pwdLastSet
{bf967a0a-0de6-11d0-a285-00aa003049e2}=
Identity: Domain\Mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: Descendents
ObjectType: 28630ebf-41d5-11d1-a9c1-0000f80367c1
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: ObjectAceTypePresent, InheritedObjectAceTypePresent
{28630ebf-41d5-11d1-a9c1-0000f80367c1}=lockoutTime
{28630ebf-41d5-11d1-a9c1-0000f80367c1}=
新测试
[Test]
public void ForWhosebug()
{
var cfg = new DirectoryEntry("LDAP://OU=CountryTestSync,OU=EDS,DC=d,DC=r,DC=dfait-maeci,DC=gc,DC=ca");
var cfgsearch = new DirectorySearcher(cfg);
cfgsearch.Filter = "(name=*)";
cfgsearch.PropertiesToLoad.Add("distinguishedName");
cfgsearch.SearchScope = SearchScope.Subtree;
var res = cfgsearch.FindAll();
var ouDE = res[0].GetDirectoryEntry();
var accessRules = ouDE.ObjectSecurity.GetAccessRules(true, true, typeof(NTAccount));
SchemaGuidConversion.PrintSD(ouDE.ObjectSecurity);
string extendedRightsDN = "CN=Extended-Rights,";
string schemaAtt = "schemaNamingContext";
string configAtt = "configurationNamingContext";
Guid samGuid = new Guid("3e0abfd0-126a-11d0-a060-00aa006c33ed");
var rootDse = new DirectoryEntry("LDAP://rootDSE");
var schemaDN = rootDse.Properties[schemaAtt].Value.ToString();
extendedRightsDN += rootDse.Properties[configAtt].Value.ToString();
var schemaRoot = new DirectoryEntry("LDAP://" + schemaDN);
var extendedRightsRoot = new DirectoryEntry("LDAP://" + extendedRightsDN);
foreach (ActiveDirectoryAccessRule ar in accessRules)
{
SchemaGuidConversion.PrintAce(ar);
Console.WriteLine("{0}={1}", ar.ObjectType.ToString("B"), SchemaGuidConversion.GetNameForSchemaGuid(ar.ObjectType, schemaRoot));
Console.WriteLine("{0}={1}", ar.ObjectType.ToString("B"), SchemaGuidConversion.GetNameForRightsGuid(ar.ObjectType, extendedRightsRoot));
}
if (rootDse != null)
{
rootDse.Dispose();
}
if (schemaRoot != null)
{
schemaRoot.Dispose();
}
}
Class获取信息
public class SchemaGuidConversion
{
public static void PrintAce(ActiveDirectoryAccessRule rule)
{
Console.WriteLine("=====ACE=====");
Console.Write(" Identity: ");
Console.WriteLine(rule.IdentityReference.ToString());
Console.Write(" AccessControlType: ");
Console.WriteLine(rule.AccessControlType.ToString());
Console.Write(" ActiveDirectoryRights: ");
Console.WriteLine( rule.ActiveDirectoryRights.ToString());
Console.Write(" InheritanceType: ");
Console.WriteLine(rule.InheritanceType.ToString());
Console.Write(" ObjectType: ");
if (rule.ObjectType == Guid.Empty)
{
Console.WriteLine("<null>");
}
else
{
Console.WriteLine(rule.ObjectType.ToString());
}
Console.Write(" InheritedObjectType: ");
if (rule.InheritedObjectType == Guid.Empty)
{
Console.WriteLine("<null>");
}
else
{
Console.WriteLine( rule.InheritedObjectType.ToString());
}
Console.Write(" ObjectFlags: ");
Console.WriteLine(rule.ObjectFlags.ToString());
}
public static void PrintSD(ActiveDirectorySecurity sd)
{
Console.WriteLine("=====Security Descriptor=====");
Console.Write(" Owner: ");
Console.WriteLine(sd.GetOwner(typeof(NTAccount)));
Console.Write(" Group: ");
Console.WriteLine(sd.GetGroup(typeof(NTAccount)));
}
public static string GetNameForRightsGuid(Guid rightsGuid, DirectoryEntry extendedRightsRoot)
{
string filter = $"(rightsGuid={rightsGuid.ToString("D")})";
return GetNameForGuid(filter, "cn", extendedRightsRoot);
}
public static string GetNameForSchemaGuid(Guid schemaIDGuid, DirectoryEntry schemaRoot)
{
string filter = $"(schemaIDGUID={BuildFilterOctetString(schemaIDGuid.ToByteArray())})";
return GetNameForGuid(filter, "ldapDisplayName", schemaRoot);
}
public static string GetNameForGuid(string filter, string targetAttribute, DirectoryEntry searchRoot)
{
string attributeName = null;
var searcher = new DirectorySearcher(searchRoot);
searcher.SearchScope = SearchScope.OneLevel;
searcher.PropertiesToLoad.Add(targetAttribute);
searcher.Filter = filter;
using (searcher)
{
var result = searcher.FindOne();
if (result != null)
{
attributeName = result.Properties[targetAttribute][0].ToString();
}
}
return attributeName;
}
public static Guid GetRightsGuid(string rightsName, DirectoryEntry extendedRightsRoot)
{
return GetGuidForName("cn", rightsName, "rightsGuid", extendedRightsRoot);
}
public static Guid GetSchemaIDGuid(string ldapDisplayName, DirectoryEntry schemaRoot)
{
return GetGuidForName("ldapDisplayName", ldapDisplayName, "schemaIDGUID", schemaRoot);
}
private static Guid GetGuidForName(string attributeName, string attributeValue, string targetAttribute, DirectoryEntry root)
{
Guid targetGuid = Guid.Empty;
SearchResult result;
object guidValue;
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.SearchScope = SearchScope.OneLevel;
searcher.PropertiesToLoad.Add(targetAttribute);
searcher.Filter = $"({attributeName}={attributeValue})";
using (searcher)
{
result = searcher.FindOne();
if (result != null)
{
guidValue = result.Properties[targetAttribute][0];
if (guidValue is string)
{
targetGuid = new Guid((string)guidValue);
}
else
{
targetGuid = new Guid((byte[])guidValue);
}
}
}
return targetGuid;
}
public static string BuildFilterOctetString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
sb.AppendFormat("\{0}", bytes[i].ToString("X2"));
}
return sb.ToString();
}
}
更新 2
这是另一个不同条目的示例
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: CreateChild, DeleteChild
InheritanceType: All
ObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
InheritedObjectType: <null>
ObjectFlags: ObjectAceTypePresent
{bf967aba-0de6-11d0-a285-00aa003049e2}=user
{bf967aba-0de6-11d0-a285-00aa003049e2}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: All
ObjectType: f30e3bbe-9ff0-11d1-b603-0000f80367c1
InheritedObjectType: <null>
ObjectFlags: ObjectAceTypePresent
{f30e3bbe-9ff0-11d1-b603-0000f80367c1}=gPLink
{f30e3bbe-9ff0-11d1-b603-0000f80367c1}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: All
ObjectType: f30e3bbf-9ff0-11d1-b603-0000f80367c1
InheritedObjectType: <null>
ObjectFlags: ObjectAceTypePresent
{f30e3bbf-9ff0-11d1-b603-0000f80367c1}=gPOptions
{f30e3bbf-9ff0-11d1-b603-0000f80367c1}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: GenericAll
InheritanceType: Descendents
ObjectType: <null>
InheritedObjectType: bf967a9c-0de6-11d0-a285-00aa003049e2
ObjectFlags: InheritedObjectAceTypePresent
{00000000-0000-0000-0000-000000000000}=
{00000000-0000-0000-0000-000000000000}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: GenericAll
InheritanceType: Descendents
ObjectType: <null>
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: InheritedObjectAceTypePresent
{00000000-0000-0000-0000-000000000000}=
{00000000-0000-0000-0000-000000000000}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, GenericExecute
InheritanceType: All
ObjectType: <null>
InheritedObjectType: <null>
ObjectFlags: None
{00000000-0000-0000-0000-000000000000}=
{00000000-0000-0000-0000-000000000000}=
这是 dsacls 条目。我可以从上面获得相应的条目,但我不确定下面的 FULL Control 或 List Contents 条目。
Allow Domain\mygroup SPECIAL ACCESS <Inherited from parent>
READ PERMISSONS
LIST CONTENTS
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for group <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for user <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for gPLink <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for gPOptions <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Inherited to all subobjects
Allow Domain\mygroup SPECIAL ACCESS <Inherited from parent>
READ PERMISSONS
LIST CONTENTS
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for group <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for user <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for gPLink <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for gPOptions <Inherited from parent>
WRITE PROPERTY
Allow Domain\mygroup FULL CONTROL <Inherited from parent>
Inherited to group
Allow Domain\mygroup FULL CONTROL <Inherited from parent>
Inherited to user
READ PROPERTY
Some of the terms don't match (like reset password to User-Force-Change-Password) and some don't show up
对于扩展权限对象,您需要获取 displayName
属性而不是 CN
:
public static string GetNameForRightsGuid(Guid rightsGuid, DirectoryEntry extendedRightsRoot)
{
string filter = $"(rightsGuid={rightsGuid.ToString("D")})";
return GetNameForGuid(filter, "displayName", extendedRightsRoot);
}
在您的示例中,结果为 "Reset Password"
所以我正在尝试从特定的 OU 获取 ACE 列表。我发现了 ActiveDirectoryAccess 规则 class.
输出给出的结果似乎不像 dsacls 命令的输出那样具体 (https://technet.microsoft.com/en-us/library/cc771151%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396)
如何使我的 C# 代码获得更多类似于 dsacls 的描述性结果? (更好的显示名称)
这是我的测试输出结果的一个子集
Domain\myGroup
Inherits - Descendents
ObjectType - 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectType - bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags - ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType - Allow
ActiveDirectoryRights - ExtendedRight
IsInherited - True
PropagationFlags - InheritOnly
-------
Domain\myGroup
Inherits - Descendents
ObjectType - bf967a0a-0de6-11d0-a285-00aa003049e2
InheritedObjectType - bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags - ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType - Allow
ActiveDirectoryRights - ReadProperty, WriteProperty
IsInherited - True
PropagationFlags - InheritOnly
-------
Domain\myGroup
Inherits - Descendents
ObjectType - 28630ebf-41d5-11d1-a9c1-0000f80367c1
InheritedObjectType - bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags - ObjectAceTypePresent, InheritedObjectAceTypePresent
AccessControlType - Allow
ActiveDirectoryRights - ReadProperty, WriteProperty
IsInherited - True
PropagationFlags - InheritOnly
这是 dsacls 的输出
Allow Domain\myGroup Reset Password <Inherited from parent>
Allow Domain\myGroup SPECIAL ACCESS for lockoutTime <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Allow Domain\myGroup SPECIAL ACCESS for pwdLastSet <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
通过查看LDAP://cn=Extended-rights,CN=Configuration,Dc=Mydomain下的一些objecttype代码
我可以说 00299570-246d-11d0-a768-00aa006e0529 映射到重置密码 但我找不到任何匹配 - 28630ebf-41d5-11d1-a9c1-0000f80367c1 或 bf967a0a-0de6-11d0-a285-00aa003049e2
获取特定 OU 的 ACE 输出的代码。
[Test]
public void ForWhosebug()
{
var cfg = new DirectoryEntry("LDAP://PathToMyOU");
var cfgsearch = new DirectorySearcher(cfg);
cfgsearch.Filter = "(name=*)";
cfgsearch.PropertiesToLoad.Add("distinguishedName");
cfgsearch.SearchScope = SearchScope.Subtree;
var res = cfgsearch.FindAll();
var ouDE = res[0].GetDirectoryEntry();
var accessRules = ouDE.ObjectSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (ActiveDirectoryAccessRule ar in accessRules)
{
Console.WriteLine($"{ar.IdentityReference.ToString()}");
Console.WriteLine($"Inherits - {ar.InheritanceType.ToString()}");
Console.WriteLine($"ObjectType - {ar.ObjectType.ToString()}");
Console.WriteLine($"InheritedObjectType - {ar.InheritedObjectType.ToString()}");
Console.WriteLine($"ObjectFlags - {ar.ObjectFlags.ToString()}");
Console.WriteLine($"AccessControlType - {ar.AccessControlType.ToString()}");
Console.WriteLine($"ActiveDirectoryRights - {ar.ActiveDirectoryRights.ToString()}");
Console.WriteLine($"IsInherited - {ar.IsInherited.ToString()}");
Console.WriteLine($"PropagationFlags - {ar.PropagationFlags.ToString()}");
Console.WriteLine("-------");
}
}
我用来获取一些对象 guid displayname 的代码
[Test]
public void ForWhosebugAllExtendedRights()
{
DirectoryEntry rootdse = new DirectoryEntry("LDAP://RootDSE");
DirectoryEntry cfg = new DirectoryEntry("LDAP://" + rootdse.Properties["configurationnamingcontext"].Value);
DirectoryEntry exRights = new DirectoryEntry("LDAP://cn=Extended-rights," + rootdse.Properties["configurationnamingcontext"].Value);
Hashtable exRighthash = new Hashtable();
foreach (DirectoryEntry chent in exRights.Children)
{
if (chent.Properties["rightsGuid"].Value != null && !exRighthash.ContainsKey(chent.Properties["rightsGuid"].Value))
{
exRighthash.Add(chent.Properties["rightsGuid"].Value, chent.Properties["DisplayName"].Value);
Console.WriteLine($"{chent.Properties["rightsGuid"].Value}, {chent.Properties["DisplayName"].Value}");
}
}
}
更新 #1 我设法找到了一段代码(来自本书https://www.amazon.com/s/?url=search-alias=stripbooks&field-keywords=0321350170&tag=technicalibra-20&link_code=wql&camp=212361&creative=380601&_encoding=UTF-8) 检查受影响的帐户类型。
我现在更接近了。有些条款不匹配(例如将密码重置为 User-Force-Change-Password),有些条款未显示
这是我之前示例的结果。
Identity: Domain\Mygroup
AccessControlType: Allow
ActiveDirectoryRights: ExtendedRight
InheritanceType: Descendents
ObjectType: 00299570-246d-11d0-a768-00aa006e0529
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: ObjectAceTypePresent, InheritedObjectAceTypePresent
{00299570-246d-11d0-a768-00aa006e0529}=
{00299570-246d-11d0-a768-00aa006e0529}=User-Force-Change-Password
Identity: Domain\Mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: Descendents
ObjectType: bf967a0a-0de6-11d0-a285-00aa003049e2
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: ObjectAceTypePresent, InheritedObjectAceTypePresent
{bf967a0a-0de6-11d0-a285-00aa003049e2}=pwdLastSet
{bf967a0a-0de6-11d0-a285-00aa003049e2}=
Identity: Domain\Mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: Descendents
ObjectType: 28630ebf-41d5-11d1-a9c1-0000f80367c1
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: ObjectAceTypePresent, InheritedObjectAceTypePresent
{28630ebf-41d5-11d1-a9c1-0000f80367c1}=lockoutTime
{28630ebf-41d5-11d1-a9c1-0000f80367c1}=
新测试
[Test]
public void ForWhosebug()
{
var cfg = new DirectoryEntry("LDAP://OU=CountryTestSync,OU=EDS,DC=d,DC=r,DC=dfait-maeci,DC=gc,DC=ca");
var cfgsearch = new DirectorySearcher(cfg);
cfgsearch.Filter = "(name=*)";
cfgsearch.PropertiesToLoad.Add("distinguishedName");
cfgsearch.SearchScope = SearchScope.Subtree;
var res = cfgsearch.FindAll();
var ouDE = res[0].GetDirectoryEntry();
var accessRules = ouDE.ObjectSecurity.GetAccessRules(true, true, typeof(NTAccount));
SchemaGuidConversion.PrintSD(ouDE.ObjectSecurity);
string extendedRightsDN = "CN=Extended-Rights,";
string schemaAtt = "schemaNamingContext";
string configAtt = "configurationNamingContext";
Guid samGuid = new Guid("3e0abfd0-126a-11d0-a060-00aa006c33ed");
var rootDse = new DirectoryEntry("LDAP://rootDSE");
var schemaDN = rootDse.Properties[schemaAtt].Value.ToString();
extendedRightsDN += rootDse.Properties[configAtt].Value.ToString();
var schemaRoot = new DirectoryEntry("LDAP://" + schemaDN);
var extendedRightsRoot = new DirectoryEntry("LDAP://" + extendedRightsDN);
foreach (ActiveDirectoryAccessRule ar in accessRules)
{
SchemaGuidConversion.PrintAce(ar);
Console.WriteLine("{0}={1}", ar.ObjectType.ToString("B"), SchemaGuidConversion.GetNameForSchemaGuid(ar.ObjectType, schemaRoot));
Console.WriteLine("{0}={1}", ar.ObjectType.ToString("B"), SchemaGuidConversion.GetNameForRightsGuid(ar.ObjectType, extendedRightsRoot));
}
if (rootDse != null)
{
rootDse.Dispose();
}
if (schemaRoot != null)
{
schemaRoot.Dispose();
}
}
Class获取信息
public class SchemaGuidConversion
{
public static void PrintAce(ActiveDirectoryAccessRule rule)
{
Console.WriteLine("=====ACE=====");
Console.Write(" Identity: ");
Console.WriteLine(rule.IdentityReference.ToString());
Console.Write(" AccessControlType: ");
Console.WriteLine(rule.AccessControlType.ToString());
Console.Write(" ActiveDirectoryRights: ");
Console.WriteLine( rule.ActiveDirectoryRights.ToString());
Console.Write(" InheritanceType: ");
Console.WriteLine(rule.InheritanceType.ToString());
Console.Write(" ObjectType: ");
if (rule.ObjectType == Guid.Empty)
{
Console.WriteLine("<null>");
}
else
{
Console.WriteLine(rule.ObjectType.ToString());
}
Console.Write(" InheritedObjectType: ");
if (rule.InheritedObjectType == Guid.Empty)
{
Console.WriteLine("<null>");
}
else
{
Console.WriteLine( rule.InheritedObjectType.ToString());
}
Console.Write(" ObjectFlags: ");
Console.WriteLine(rule.ObjectFlags.ToString());
}
public static void PrintSD(ActiveDirectorySecurity sd)
{
Console.WriteLine("=====Security Descriptor=====");
Console.Write(" Owner: ");
Console.WriteLine(sd.GetOwner(typeof(NTAccount)));
Console.Write(" Group: ");
Console.WriteLine(sd.GetGroup(typeof(NTAccount)));
}
public static string GetNameForRightsGuid(Guid rightsGuid, DirectoryEntry extendedRightsRoot)
{
string filter = $"(rightsGuid={rightsGuid.ToString("D")})";
return GetNameForGuid(filter, "cn", extendedRightsRoot);
}
public static string GetNameForSchemaGuid(Guid schemaIDGuid, DirectoryEntry schemaRoot)
{
string filter = $"(schemaIDGUID={BuildFilterOctetString(schemaIDGuid.ToByteArray())})";
return GetNameForGuid(filter, "ldapDisplayName", schemaRoot);
}
public static string GetNameForGuid(string filter, string targetAttribute, DirectoryEntry searchRoot)
{
string attributeName = null;
var searcher = new DirectorySearcher(searchRoot);
searcher.SearchScope = SearchScope.OneLevel;
searcher.PropertiesToLoad.Add(targetAttribute);
searcher.Filter = filter;
using (searcher)
{
var result = searcher.FindOne();
if (result != null)
{
attributeName = result.Properties[targetAttribute][0].ToString();
}
}
return attributeName;
}
public static Guid GetRightsGuid(string rightsName, DirectoryEntry extendedRightsRoot)
{
return GetGuidForName("cn", rightsName, "rightsGuid", extendedRightsRoot);
}
public static Guid GetSchemaIDGuid(string ldapDisplayName, DirectoryEntry schemaRoot)
{
return GetGuidForName("ldapDisplayName", ldapDisplayName, "schemaIDGUID", schemaRoot);
}
private static Guid GetGuidForName(string attributeName, string attributeValue, string targetAttribute, DirectoryEntry root)
{
Guid targetGuid = Guid.Empty;
SearchResult result;
object guidValue;
DirectorySearcher searcher = new DirectorySearcher(root);
searcher.SearchScope = SearchScope.OneLevel;
searcher.PropertiesToLoad.Add(targetAttribute);
searcher.Filter = $"({attributeName}={attributeValue})";
using (searcher)
{
result = searcher.FindOne();
if (result != null)
{
guidValue = result.Properties[targetAttribute][0];
if (guidValue is string)
{
targetGuid = new Guid((string)guidValue);
}
else
{
targetGuid = new Guid((byte[])guidValue);
}
}
}
return targetGuid;
}
public static string BuildFilterOctetString(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
sb.AppendFormat("\{0}", bytes[i].ToString("X2"));
}
return sb.ToString();
}
}
更新 2
这是另一个不同条目的示例
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: CreateChild, DeleteChild
InheritanceType: All
ObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
InheritedObjectType: <null>
ObjectFlags: ObjectAceTypePresent
{bf967aba-0de6-11d0-a285-00aa003049e2}=user
{bf967aba-0de6-11d0-a285-00aa003049e2}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: All
ObjectType: f30e3bbe-9ff0-11d1-b603-0000f80367c1
InheritedObjectType: <null>
ObjectFlags: ObjectAceTypePresent
{f30e3bbe-9ff0-11d1-b603-0000f80367c1}=gPLink
{f30e3bbe-9ff0-11d1-b603-0000f80367c1}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, WriteProperty
InheritanceType: All
ObjectType: f30e3bbf-9ff0-11d1-b603-0000f80367c1
InheritedObjectType: <null>
ObjectFlags: ObjectAceTypePresent
{f30e3bbf-9ff0-11d1-b603-0000f80367c1}=gPOptions
{f30e3bbf-9ff0-11d1-b603-0000f80367c1}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: GenericAll
InheritanceType: Descendents
ObjectType: <null>
InheritedObjectType: bf967a9c-0de6-11d0-a285-00aa003049e2
ObjectFlags: InheritedObjectAceTypePresent
{00000000-0000-0000-0000-000000000000}=
{00000000-0000-0000-0000-000000000000}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: GenericAll
InheritanceType: Descendents
ObjectType: <null>
InheritedObjectType: bf967aba-0de6-11d0-a285-00aa003049e2
ObjectFlags: InheritedObjectAceTypePresent
{00000000-0000-0000-0000-000000000000}=
{00000000-0000-0000-0000-000000000000}=
=====ACE=====
Identity: domain/mygroup
AccessControlType: Allow
ActiveDirectoryRights: ReadProperty, GenericExecute
InheritanceType: All
ObjectType: <null>
InheritedObjectType: <null>
ObjectFlags: None
{00000000-0000-0000-0000-000000000000}=
{00000000-0000-0000-0000-000000000000}=
这是 dsacls 条目。我可以从上面获得相应的条目,但我不确定下面的 FULL Control 或 List Contents 条目。
Allow Domain\mygroup SPECIAL ACCESS <Inherited from parent>
READ PERMISSONS
LIST CONTENTS
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for group <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for user <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for gPLink <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for gPOptions <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Inherited to all subobjects
Allow Domain\mygroup SPECIAL ACCESS <Inherited from parent>
READ PERMISSONS
LIST CONTENTS
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for group <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for user <Inherited from parent>
CREATE CHILD
DELETE CHILD
Allow Domain\mygroup SPECIAL ACCESS for gPLink <Inherited from parent>
WRITE PROPERTY
READ PROPERTY
Allow Domain\mygroup SPECIAL ACCESS for gPOptions <Inherited from parent>
WRITE PROPERTY
Allow Domain\mygroup FULL CONTROL <Inherited from parent>
Inherited to group
Allow Domain\mygroup FULL CONTROL <Inherited from parent>
Inherited to user
READ PROPERTY
Some of the terms don't match (like reset password to User-Force-Change-Password) and some don't show up
对于扩展权限对象,您需要获取 displayName
属性而不是 CN
:
public static string GetNameForRightsGuid(Guid rightsGuid, DirectoryEntry extendedRightsRoot)
{
string filter = $"(rightsGuid={rightsGuid.ToString("D")})";
return GetNameForGuid(filter, "displayName", extendedRightsRoot);
}
在您的示例中,结果为 "Reset Password"