Search code examples
c#active-directorydirectoryentry

Authorization problem with DirectoryEntry and ActiveDirectorySecurity


I am writing a class to set or remove access rules to protect or unprotect objects from accidental removal, using ActiveDirectorySecurity.AddAccessRule and ActiveDirectorySecurity.RemoveAccessRule.

My class works fine if I provide the username and password of an admin account to the DirectoryEntry (which I don't want to do), but if I don't provide username and password it throws an error

System.DirectoryServices.DirectoryServicesCOMException: A constraint violation occurred

My default account however can change the protect object flag using the Active Directory Users and Computers app without any problems.

Any ideas on why this could be happening?

using System;
using System.DirectoryServices;
using System.Security.AccessControl;
using System.Security.Principal;

namespace test123
{
    internal class Test124
    {
        internal static void RemoveAccidentialProtection()
        {
            string dn = "CN=XXX,OU=XXX,OU=XXX,OU=XXX,OU=XXX,DC=XXX,DC=XXX";

            using (DirectoryEntry ent = new DirectoryEntry("LDAP://XXX:nnn/" + dn))
            {
                IdentityReference everyOneAccount = new NTAccount("Everyone").Translate(typeof(SecurityIdentifier)); //S - 1 - 1 - 0
                ActiveDirectoryAccessRule objAce = new ActiveDirectoryAccessRule(everyOneAccount, ActiveDirectoryRights.Delete | ActiveDirectoryRights.DeleteTree, AccessControlType.Deny);
                ent.ObjectSecurity.RemoveAccessRule(objAce);
                ent.CommitChanges();
            }
        }
    }
}

Solution

  • I found a post that says DirectoryEntry.CommitChanges defaults to setting ownership information which isn't allowed for regular users, so you need to set DirectoryEntry to only write the ACL changes. Put the following line just before the call to CommitChanges:

    ent.Options.SecurityMasks = SecurityMasks.Dacl;