2

私はOUと協力していて、ただ見つけようとしていました

OU が誤って削除されないように保護されているかどうかを確認する方法はありますか?

私はそれをグーグルで検索しましたが、解決策が見つかりませんでした。

スクリプトではなく C# での解決策を探しています。

前もって感謝します

4

5 に答える 5

2

オブジェクト (属性) の ACL を開き、ntSecurityDescriptorDeny Everyone Delete を探す必要があります。このActiveDirectorySecurityクラスは、これに関するマネージ ラッパーを提供します - http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectorysecurity.aspx

于 2012-08-08T19:41:09.540 に答える
1

AD オブジェクトを保護するには、2 つの ACE が必要です。1 つは、保護するオブジェクトに設定する必要がある「deny Delete + DeleteTree」であり、2 つ目は、親オブジェクトに設定する必要がある「deny DeleteChild」です。保護を削除する必要がある場合は、オブジェクトの ACE のみを削除する必要があります。親オブジェクトの ACE はそのままにしておく必要があります。そうしないと、同じ OU 内の他のオブジェクトが保護されなくなります。

完全に機能している私のコードは次のとおりです。

    //using System.Security.Principal
    //using System.DirectoryServices;


    public static void SetProtectADObject(DirectoryEntry ent, bool Protect = true)
    {
        //get parent object
        var parentEnt = new DirectoryEntry(ent.Parent.Path);

        //refresh objects
        ent.RefreshCache();
        parentEnt.RefreshCache();

        if (Protect)
        {
            #region Protect
            try
            {
                IdentityReference everyOneAccount = new NTAccount("Everyone").Translate(typeof(SecurityIdentifier)); //S-1-1-0
                var objAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.Delete | ActiveDirectoryRights.DeleteTree, AccessControlType.Deny);
                var parentAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.DeleteChild, AccessControlType.Deny);

                //check if ace present on object
                var objACL = ent.ObjectSecurity;
                bool acePresent = false;
                foreach (ActiveDirectoryAccessRule ace in objACL.GetAccessRules(true, false, typeof(NTAccount)))
                {
                    if (ace.IdentityReference.Value == "Everyone")
                    {
                        if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
                        else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
                    }
                }

                if (!acePresent)
                {
                    //set ace to object
                    objACL.AddAccessRule(objAce);

                    //commit changes
                    ent.CommitChanges();
                }

                //check if ace present on parent object
                var parentACL = parentEnt.ObjectSecurity;
                bool parentAcePresent = false;
                foreach (ActiveDirectoryAccessRule ace in parentACL.GetAccessRules(true, false, typeof(NTAccount)))
                {
                    if (ace.IdentityReference.Value == "Everyone")
                    {
                        if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild)) { parentAcePresent = true; break; }
                        else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { parentAcePresent = true; break; }
                    }
                }

                if (!parentAcePresent)
                {
                    //set ace to parent object
                    parentACL.AddAccessRule(parentAce);

                    //commit changes
                    parentEnt.CommitChanges();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error protecting object {0}", ent.Path), ex);
            }
            #endregion
        }
        else
        {
            #region Unprotect
            //to remove the protection we remove only the ACE from the object, not from the parent. 
            //The ACE on the parent must be in place because otherwise other objects on the same level will not protected anymore!

            try
            {
                IdentityReference everyOneAccount = new NTAccount("Everyone").Translate(typeof(SecurityIdentifier)); //S - 1 - 1 - 0
                var objAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.Delete | ActiveDirectoryRights.DeleteTree, AccessControlType.Deny);

                //check if ace present on object
                var objACL = ent.ObjectSecurity;
                bool acePresent = false;
                foreach (ActiveDirectoryAccessRule ace in objACL.GetAccessRules(true, false, typeof(NTAccount)))
                {
                    if (ace.IdentityReference.Value == "Everyone")
                    {
                        if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
                        else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
                    }
                }

                //set ace to object
                if (acePresent)
                {
                    ent.ObjectSecurity.RemoveAccessRule(objAce);
                    ent.CommitChanges();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error unprotecting object {0}", ent.Path), ex);
            }
            #endregion 
        }
    }

    public static bool IsADObjectProtected(DirectoryEntry ent)
    {
        //get parent object
        var parentEnt = new DirectoryEntry(ent.Parent.Path);

        //refresh objects
        ent.RefreshCache();
        parentEnt.RefreshCache();

        //get current ACLs
        ActiveDirectorySecurity acl = ent.ObjectSecurity;
        ActiveDirectorySecurity parentAcl = ent.Parent.ObjectSecurity;
        AuthorizationRuleCollection rules = acl.GetAccessRules(true, true, typeof(NTAccount));
        AuthorizationRuleCollection parentRules = parentAcl.GetAccessRules(true, false, typeof(NTAccount));

        //check object acl
        bool acePresent = false;
        foreach (ActiveDirectoryAccessRule ace in rules)
        {
            Console.WriteLine(ace.AccessControlType.ToString());
            if (ace.AccessControlType == AccessControlType.Deny)
            {
                if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
                else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { acePresent = true; break; }
            }
        }

        //check parent acl
        bool parentAcePresent = false;
        foreach (ActiveDirectoryAccessRule ace in parentRules)
        {
            if (ace.AccessControlType == AccessControlType.Deny)
            {
                if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild)) { parentAcePresent = true; break; }
                else if (ace.ActiveDirectoryRights == (ActiveDirectoryRights.DeleteChild | ActiveDirectoryRights.DeleteTree | ActiveDirectoryRights.Delete)) { parentAcePresent = true; break; }
            }
        }

        return parentAcePresent && acePresent;
    }
于 2016-06-09T18:37:27.137 に答える
0

systemFlags 属性を確認してください。ADS_SYSTEMFLAG_ENUMの MS ページには C++ の例があり、C# に簡単に適用できるはずです。

于 2012-08-08T09:35:11.003 に答える