In a C# .Net web page I'm displaying some information from our AD.
Furthermore I have a method allowing replacing a SID in an ACL of a user,
group or computer object.
I use the managedBy attribute a lot, but when this manager resigns, I must
set a new user, and I prefer to give whatever rights the previous manager
had to the newly designated one.
I have my code working, but only when the calling user is an administrator.
Having the right to change permissions (write DACL) is not sufficient.
Here's what I do (simplified):
objAccount is a DirectoryEntry object representing ex. a group or computer.
string strSDDL =
objAccount.ObjectSecurity.GetSecurityDescriptorSdd lForm(System.Security.AccessControl.AccessControlS ections.Access);
// Search for old SID, replace with new one
....
objAccount.ObjectSecurity.SetSecurityDescriptorSdd lForm(strSDDL,
System.Security.AccessControl.AccessControlSection s.Access)
objAccount.InvokeSet("managedBy",
objNewResp.Properties["distinguishedName"].Value.ToString());
objAccount.CommitChanges();
This succeeds if called by an admin, but throws an exception saying "A
constraint violation occurred. (Exception from HRESULT: 0x8007202F)", if the
calling user is not an admin, even if account operator.
I've found KB323749, and it sounds reasonable the problem is the function
trying to set the owner in the SD as well, even though I specify the second
argument on the SetSecurityDescriptorSddlForm method. To me this seems like
an error in the .Net framework, or am I mistaken???
The AccessControlSections.Access value ought to specify DACL only, according
to the documentation.
To verify this is really the problem, I tried to implement the method
suggested in the mentioned article.
The following two lines somewhat solves the problem:
ActiveDs.IADsObjectOptions options =
(ActiveDs.IADsObjectOptions)objAccount.NativeObjec t;
options.SetOption((int)ActiveDs.ADS_OPTION_ENUM.AD S_OPTION_SECURITY_MASK,
ActiveDs.ADS_SECURITY_INFO_ENUM.ADS_SECURITY_INFO_ DACL);
And as such proves the owner to be the problem. However, apparently this is
a global setting. As another part of my web page reads a SD and among others
passes it to the API function AccessCheckByTypeResultList. This suddently
starts to fail, and it reports the SD is not valid (error code: 1338). I can
set the option back to include all aspects of the SD, but it would just be a
matter of time until two users clicks at the same time, and one of the calls
fail. I'd rather not want to implement a semaphore in a web page.
I'm wondering why the second argument on
ObjectSecurity.SetSecurityDescriptorSddlForm doesn't have an effect.
Do I need a patch to fix this???
Thanks in advance,
Jan