Active Directory访问规则不像数据包那样具体

本文关键字:数据包 Directory 访问 规则 Active | 更新日期: 2023-09-27 18:02:40

所以我试图从特定OU获得ACE列表。我发现了ActiveDirectoryAccess规则类。

输出给出的结果似乎不像dsacls命令(https://technet.microsoft.com/en-us/library/cc771151%28v=ws.11%29.aspx?f=255&MSPPError=-2147217396)的输出那样具体

我如何使我的c#代码得到更多的描述性的结果类似于dsacls?(更好的displayname)

下面是我的测试

的输出结果的一个子集
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

我看得出来00299570-246d-11d0-a768-00aa006e0529对应重置密码但我找不到任何匹配- 28630ebf-41d5-11d1-a9c1-0000f80367c1或bf967aa -0de6-11d0-a285-00aa003049e2

获取特定OU的ACE输出的代码。

[Test]
        public void ForStackOverflow()
        {
            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 ForStackOverflowAllExtendedRights()
{
    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}");
        }
    }
}

Update # 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 ForStackOverflow()
        {
            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();
            }
        }

类获取信息

  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 ControlList 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

Active Directory访问规则不像数据包那样具体

有些条款不匹配(如重置密码为User-Force-Change-Password),有些没有显示

您需要获取扩展权限对象的displayName属性而不是CN属性:

public static string GetNameForRightsGuid(Guid rightsGuid, DirectoryEntry extendedRightsRoot)
{
    string filter = $"(rightsGuid={rightsGuid.ToString("D")})";
    return GetNameForGuid(filter, "displayName", extendedRightsRoot);
}

在您的示例中,这将导致"Reset Password"