0

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:

  1. Start ADSI Edit and connect to the AD LDS instance and partition.
  2. Navigate to CN=Readers below the partition root node.
  3. Double-click the CN=Readers entry.
  4. Double-Click the "member" attribute.
  5. Select and add an existing local Windows group.

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.

candritzky
  • 351
  • 4
  • 11

2 Answers2

1

My speculation would be that in your configuration, until you have added the SID to at least some role there is no FSP for that principal and, hence, references to it by SID will fail.

Have you tried adding the principal to the group by SID a la how adding it to the readers group is being done? If you want to figure out how this is being done by the internal tooling, take a network sniff of the LDAP call between whatever tool you are using and the LDS instance when doing that add to the readers group...

Eric Fleischman
  • 1,168
  • 6
  • 8
  • Thanks! That makes sense. I was not aware I have to add an FSP in advance. Will try that. How can I take LDAP traces? Tried to use Wireshark, but it only shows encrypted LDAP data (something like "SASL GSS-API Private: payload"). Option "Use SSL-based encryption" is not checked. – candritzky Sep 17 '12 at 07:22
  • 1
    You don't have to add an FSP yourself...LDS is happy to do it for you. However, you need to reference the principal by SID instead of by FSP DN (typically of the form This is, generally speaking, safer. By adding things by DN you risk taking a dependency on an FSP that isn't there. Let LDS do the work for you. – Eric Fleischman Sep 17 '12 at 14:58
  • Found and solved that already based on your hints (see my own answer below). Thanks again for pushing me into the right direction. – candritzky Sep 17 '12 at 18:08
0

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.

candritzky
  • 351
  • 4
  • 11
  • Does not work for me. System.DirectoryServices.DirectoryServicesCOMException: The server is unwilling to process the request. – Laszlo T Aug 31 '15 at 14:55