Может ли запрос LDAP в AD предоставить имя домена netbios для одной учетной записи при использовании глобального каталога?

11

Я использую ADSI Edit для просмотра свойств LDAP одной учетной записи пользователя в AD. Я вижу такие свойства, как userPrincipalName, но не вижу ни одного для полного доменного имени (FQDN) или доменного имени netbios.

Мы будем настраивать Глобальный каталог (GC), чтобы предоставить нам доступ LDAP к нескольким доменам, и через конфигурацию в приложении мы сопоставляем свойства LDAP со свойствами профиля пользователя в приложении. При использовании типичного AD полное доменное имя и доменное имя netbios одинаковы для всех пользователей, но с помощью GC нам нужна эта дополнительная информация. Нам действительно нужно только доменное имя netbios (полное доменное имя недостаточно хорошее).

Может быть, существует запрос LDAP, который можно сделать, чтобы запросить эту информацию у объекта более высокого уровня в AD?

Кирк Лимон
источник

Ответы:

5

Я думаю, что я понял это. Используя ADSI Edit, вы можете просматривать свойства объекта (например, пользователя), но по умолчанию он отфильтровывал «построенные» атрибуты. Используя кнопку «Фильтр» в правом нижнем углу экрана свойств, я смог показать эти дополнительные атрибуты.

«MsDS-PrincipalName» имеет значение «[имя домена netbios] \ [sAMAccountName]» в качестве значения.

Если я захожу в AD Users and Computers и изменяю «Имя входа пользователя» с «gwasington@test.kirkdev.local» на «gwash2ington@test.kirk2dev.local», это влияет на атрибут «userPrincipalName», но не на «msDS- PrincipalName "атрибут. Это хорошо в моем случае, потому что моя другая система (SharePoint) также не распознает это изменение.

Если я захожу в AD Users and Computers и меняю «Имя входа пользователя (до Windows 2000)» с «KIRKDEV \ gwashington» на «KIRKDEV \ g2washington» (обратите внимание, что я не могу изменить первую часть), это не влияет на «UserPrincipalName» атрибут, но это влияет на атрибут «MSDS-PrincipalName». Это именно то, чего я хочу, потому что моя другая система (SharePoint) распознает это изменение.

Примечание: я сказал, что SharePoint распознает это изменение, но это только в том случае, если пользователь никогда ранее не входил в это семейство сайтов SharePoint. После того как пользователь вошел в семейство сайтов SharePoint, поле tp_Login в таблице UserInfo устанавливается со значением «msDS-PrincipalName», и это, похоже, не меняется. Поэтому мне, возможно, придется найти способ заставить это измениться или просто сказать, что этот сценарий не поддерживается.

Кирк Лимон
источник
Я не проверял, что мы действительно можем запросить «msDS-PrincipalName» из Глобального каталога. Это будет следующим шагом.
Кирк Лимон
Ну, я собирался пометить свой ответ как правильный, но теперь я вижу, что Глобальный каталог не может запрашивать msDS-PrincipalName. Тьфу, все еще не уверен, как мы выясним имя домена netbios оттуда, не делая некоторых предположений (как будто это первая часть FQDN).
Кирк Лимон
Что касается моего примечания, см. Serverfault.com/questions/234526/… чтобы помочь SharePoint распознать изменение входа в систему.
Кирк Лимон
Это то, что называется составным атрибутом, то есть он рассчитывается по требованию, когда делается запрос для объекта. Вы не можете отфильтровать его в запросе из-за этого.
Брайан Десмонд
Спасибо за эту информацию - она ​​мне очень пригодилась при запросах через LDAP от SQL Server.
Ян Йейтс
3

Чтобы ответить на последний вопрос, вы сможете проверить имя NetBios вручную, проверив раздел «Конфигурация», а затем разделы каталога в ADSIEdit:

CN=MYNETBIOSNAME,CN=Partitions,CN=Configuration,DC=mydomain,DC=internal

Это имеет nameи netBIOSNameсвойства. В противном случае, я думаю, вам придется получить его из fqdn / DN, как предполагает squillman.

BoyMars
источник
Спасибо @BoyMars. У меня возникли проблемы с поиском "CN = Configuration" на верхнем уровне в моем домене. Я немного поковырялся и не смог найти «Конфигурация» или «Разделы каталога». Тем не менее, я думаю, что, возможно, придется выяснить это (собирается опубликовать ответ).
Кирк Лимон
Хорошо, я только что понял, как перейти к CN = Configuration (извините, прошло около 6 лет с тех пор, как я поиграл с LDAP и ADSI Edit). @BoyMars, я понимаю, о чем ты говоришь. К сожалению, это запрос доменного имени netbios. Похоже, мне нужно перебрать все объекты в разделе CN = Разделы, CN = Конфигурация, и для каждого посмотреть, есть ли у него атрибут «nETBIOSName». Возможно, запрос, который даст мне все объекты crossRef, где атрибут netBIOSName не равен NULL, поможет. Это кажется относительно легко сделать в коде, но я должен сделать это с помощью конфигурации. :-(
Кирк Лимон
Вот страница, которая обсуждает, как запросить имя netbios. Они используют код, хотя. Я подозреваю, что это не сработает для меня. geekswithblogs.net/Tariq/archive/2009/07/30/133813.aspx
Кирк Лимон
но он объясняет местоположение: «AD хранит имя netbios в контейнере именования разделов, который хранится в контейнере именования конфигурации».
BoyMars
Это единственный авторитетный источник информации. В частности, упоминается объект crossRef.
Брайан Десмонд
3

Для приложения? Microsoft делает это довольно просто в .NET. Это должно предоставить вам список доменных имен Netbios, которые вы можете использовать для создания списка пользовательских объектов с именами DN / DNS / Netbios домена или перекрестных ссылок на словари.

Кроме того, то, что определяет, доступен ли атрибут в Глобальном каталоге, является (еще одним) атрибутом, называемым isMemberOfPartialAttributeSet. Используя Microsoft SysInternals AD Explorer, вы можете искать контейнер схемы в домене и искать любой объект, имеющий isMemberOfPartialAttributeSet = true, чтобы увидеть все атрибуты, доступные для запроса GC.

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;

private void GetNetbiosNamesTest()
{
    DomainCollection domains = Forest.GetCurrentForest().Domains;
    foreach (Domain domain in domains)
    {
        Console.WriteLine("Domain Netbios name: {0}", this.GetDomainNetBiosName(domain));
    }
}

private string GetDomainNetBiosName(Domain domain)
{
    ForestRootDirectoryEntry = Forest.GetCurrentForest().RootDomain.GetDirectoryEntry();
    string forestConfigurationBindPath = String.Format("LDAP://CN=Partitions,CN=Configuration,{0}", ForestRootDirectoryEntry.Properties["distinguishedName"].Value);
    ForestRootConfigurationDirectoryEntry = new DirectoryEntry(forestConfigurationBindPath);

    string netBiosName = String.Empty;

    using (DirectorySearcher directorySearcher = new DirectorySearcher(ForestRootConfigurationDirectoryEntry))
    {
        directorySearcher.Filter = String.Format("(&(nETBIOSName=*)(dnsRoot={0}))", domain.Name);
        directorySearcher.PropertiesToLoad.AddRange(new String[] { "dnsRoot", "nETBIOSName" });
        var result = directorySearcher.FindOne();

        if ((result != null) && (result.Properties.Contains("nETBIOSName"))) netBiosName = result.Properties["nETBIOSName"][0].ToString();
    }
    return netBiosName;
}
Грег Аскью
источник
Спасибо за ответ, но мне нужно запустить его с компьютера, отличного от Windows. Однако, при необходимости, я думаю, я мог бы создать свой собственный веб-сервис в .NET и предоставить другой машине эту информацию. Это может быть запасной подход.
Кирк Лимон
2
Это также должно быть простым. Задайте для базового DN значение «CN = Разделы, CN = Конфигурация» + базовое DN для атрибута Домена manifishedName, а для фильтра поиска - (& (nETBIOSName = *) (dnsRoot = <имя DNS домена AD>)). Вы также можете искать атрибут ncName вместо dnsRoot, если вы хотите сопоставить суффикс dn домена вместо имени dns.
Грег Аскью
1

Вам придется анализировать его dnпо AdsDSPathатрибуту (detachedName) или по атрибутам. Объекты доменных имен имеют префикс "DC="в этих атрибутах. Самый левый DC=будет содержать ваше доменное имя netbios.

Например: cn=myuser,ou=users,dc=mydomain,dc=mycompany,dc=com

mydomain доменное имя netbios

РЕДАКТИРОВАТЬ:
Как указывает Брайан Десмонд, это не обязательно авторитетный способ найти фактическое имя netbios, это просто совпадение, что они обычно коррелируют. См. Ответ BoyMars для авторитетного пути.

squillman
источник
следите за пределом netbios в 15 символов при использовании значений из строки fqdn или DN, хотя я не видел много доменов, которые используют такую ​​длинную строку :)
BoyMars
Спасибо @squillman, но когда я создал этот домен, я намеренно сделал доменное имя netbios не первой частью полного доменного имени только потому, что это было возможно, и мне нужно проверить границы, так как мой код должен работать в нескольких средах. Таким образом, в моем случае полное доменное имя - test.kirkdev.local (пример пользователя dn - «CN = Джордж Вашингтон, CN = пользователи, DC = test, DC = kirkdev, DC = local»), но имя домена netbios - kirkdev.
Кирк Лимон
Если вы используете Windows, dsquery computer OU=OU,OU=You,OU=Need,DC=local.domain -o rdnвыдает то, что вы хотите, с именем NetBIOS в кавычках. Поскольку это относительно, вам не нужно будет получать полный путь. Не уверен, если это поможет ОП, хотя; он спросил о LDAP, так что это не чистый ответ LDAP.
songei2f
@alharaka спасибо за комментарий, но мы запрашиваем AD с компьютера не от MS. Мы могли бы потенциально иметь дело с этим, но мы действительно хотим, чтобы это было частью запроса LDAP. Похоже, что dsquery - это инструмент командной строки Windows Server.
Кирк Лимон
1
Извините, но это неверно. Абсолютно НЕТ отношений между верхним компонентом домена (например, dc = mydomain) и NetBIOS-именем домена. Это просто общее совпадение, что они согласны.
Брайан Десмонд
0

Если у вас есть имя участника-пользователя или DN, вы можете использовать COM-библиотеку ActiveDS для перевода значений. Ниже приведен пример для перевода UserPrincipalName в NT4 (NetBios) имя.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ActiveDs;

namespace Foo.Repository.AdUserProfile
{
    public class ADUserProfileValueTranslate
    {
        public static string ConvertUserPrincipalNameToNetBiosName(string userPrincipleName)
        {
            NameTranslate nameTranslate = new NameTranslate();
            nameTranslate.Set((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_USER_PRINCIPAL_NAME, userPrincipleName);
            return nameTranslate.Get((int) ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_NT4);
        }
    }
}
Джефф
источник
Спасибо за ответ, но мне нужно сделать это с компьютера, отличного от Windows, и в идеале через запрос LDAP.
Кирк Лимон