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();
}
}
}
}
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;