I am using AD LDS on Windows 7 and created a local instance with a new application partition using the adaminstall utility.
How can I add an existing local Windows group to the Readers role of this partition?
I want to achieve the same result programmatically (in C#) that are given by the following manual steps:
I already have the following C# code:
public void AddReader(string partitionName, string accountName)
{
var ntAccount = new NTAccount(accountName);
var securityIdentifer = ntAccount.Translate(typeof(SecurityIdentifier));
var accountNameDN = string.Format("CN={0},CN=ForeignSecurityPrincipals,{1}", securityIdentifer.Value, partitionName);
var rootPath = string.Format("LDAP://localhost:389/CN=Readers,CN=Roles,{0}", partitionName)
var directoryEntry = new DirectoryEntry(RootPath);
directoryEntry.Properties["member"].Add(accountNameDN);
directoryEntry.CommitChanges();
}
This code works only if the local group has at least been added once to the Readers role using the manual steps described above. If I add the group manually and then remove it manually, the code shown above can be used to re-add the group again.
But when I try to add a new local Windows group, the CommitChanges()
call in the code above throws a DirectoryServicesCOMException
with error code 0x8007002F
and message A constraint violation occurred
.
Obviously the manual steps perform some modification on the existing local Windows group that make it suitable for being added to the AD LDS Readers role. But what am I missing?
I think there must be a better way than my approach using the ActiveDirectorySecurity
and ActiveDirectoryAccessRule
classes, but I cannot figure out how to use them.
Thanks to Eric's hint regarding FSP (Foreign Security Principal), we (Google and me) found a solution here: http://www.pcreview.co.uk/forums/add-group-members-trusted-domain-programmatically-t1460084.html (scroll down to Joe Kaplans answer).
The trick is to use the <SID=xxx>
syntax for the accountNameDN variable. My code sample from the original questions works if the the accountNameDN variable is modified as follows:
var accountNameDN = string.Format("<SID={0}>", securityIdentifer.Value);
This will implicitly add the required FSP.