Добавить локальную группу в CN=Readers,CN=Roles в разделе AD LDS в C#

Я использую AD LDS в Windows 7 и создал локальный экземпляр с новым разделом приложений с помощью утилиты adaminstall.

Как я могу добавить существующую локальную группу Windows к роли Читатели этого раздела?

Я хочу добиться того же результата программно (на С#), который дается следующими ручными шагами:

  1. Запустите редактор ADSI и подключитесь к экземпляру и разделу AD LDS.
  2. Перейдите к CN=Readers под корневым узлом раздела.
  3. Дважды щелкните запись CN=Readers.
  4. Дважды щелкните атрибут «член».
  5. Выберите и добавьте существующую локальную группу Windows.

У меня уже есть следующий код С#:

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

Этот код работает только в том случае, если локальная группа хотя бы один раз была добавлена ​​к роли Читатели с помощью ручных действий, описанных выше. Если я добавлю группу вручную, а затем удалю ее вручную, приведенный выше код можно использовать для повторного добавления группы.

Но когда я пытаюсь добавить новую локальную группу Windows, вызов CommitChanges() в приведенном выше коде выдает DirectoryServicesCOMException с кодом ошибки 0x8007002F и сообщением A constraint violation occurred.

Очевидно, что действия, выполняемые вручную, вносят некоторые изменения в существующую локальную группу Windows, что делает ее пригодной для добавления в роль читателей AD LDS. Но чего мне не хватает?

Я думаю, что должен быть лучший способ, чем мой подход с использованием классов ActiveDirectorySecurity и ActiveDirectoryAccessRule, но я не могу понять, как их использовать.


person candritzky    schedule 15.09.2012    source источник


Ответы (2)


Мое предположение состоит в том, что в вашей конфигурации, пока вы не добавите SID хотя бы к какой-либо роли, FSP для этого принципала не существует, и, следовательно, ссылки на него по SID не будут выполняться.

Пробовали добавить принципала в группу по SID а-ля как делается добавление его в группу читателей? Если вы хотите выяснить, как это делается с помощью внутреннего инструментария, проанализируйте сетевой вызов LDAP между любым инструментом, который вы используете, и экземпляром LDS при добавлении в группу читателей...

person Eric Fleischman    schedule 17.09.2012
comment
Спасибо! В этом есть смысл. Я не знал, что мне нужно заранее добавить FSP. Попробую это. Как я могу взять трассировки LDAP? Пытался использовать Wireshark, но он показывает только зашифрованные данные LDAP (что-то вроде SASL GSS-API Private: payload). Опция Использовать шифрование на основе SSL не отмечена. - person candritzky; 17.09.2012
comment
Вам не нужно добавлять FSP самостоятельно... LDS с удовольствием сделает это за вас. Однако вам нужно ссылаться на принципала по SID, а не по DN FSP (обычно в форме ‹SID=...› Это, вообще говоря, безопаснее. Добавляя вещи по DN, вы рискуете получить зависимость от FSP, который не Пусть LDS сделает всю работу за вас. - person Eric Fleischman; 17.09.2012
comment
Нашел и решил это уже на основе ваших подсказок (см. мой собственный ответ ниже). Еще раз спасибо, что подтолкнули меня в правильном направлении. - person candritzky; 17.09.2012

Благодаря подсказке Эрика относительно FSP (Foreign Security Principal), мы (Google и я) нашли решение здесь: http://www.pcreview.co.uk/forums/add-group-members-trusted-domain-programmatically-t1460084.html (прокрутите вниз на ответ Джо Капланса).

Хитрость заключается в использовании синтаксиса <SID=xxx> для переменной accountNameDN. Мой пример кода из исходных вопросов работает, если переменная accountNameDN изменена следующим образом:

var accountNameDN = string.Format("<SID={0}>", securityIdentifer.Value);

Это неявно добавит требуемый FSP.

person candritzky    schedule 17.09.2012
comment
У меня не работает. System.DirectoryServices.DirectoryServicesCOMException: сервер не желает обрабатывать запрос. - person mshthn; 31.08.2015