Czy zapytanie LDAP w AD może dostarczyć nazwę domeny Netbios dla jednego konta podczas korzystania z Katalogu globalnego?

11

Korzystam z ADSI Edit, aby sprawdzić właściwości LDAP pojedynczego konta użytkownika w AD. Widzę właściwości takie jak userPrincipalName, ale nie widzę żadnej dla w pełni kwalifikowanej nazwy domeny (FQDN) lub nazwy domeny netbios.

Będziemy konfigurować wykaz globalny (GC), aby zapewnić nam dostęp LDAP do wielu domen, a poprzez konfigurację w aplikacji mapujemy właściwości LDAP na właściwości profilu użytkownika w aplikacji. W typowym AD nazwy FQDN i nazwa domeny Netbios są takie same dla wszystkich użytkowników, ale w przypadku GC potrzebujemy tych dodatkowych informacji. Naprawdę potrzebujemy tylko nazwy domeny Netbios (nazwa FQDN nie jest wystarczająco dobra).

Może istnieje zapytanie LDAP, które można wykonać, aby zażądać tych informacji od obiektu najwyższego poziomu w AD?

Kirk Liemohn
źródło

Odpowiedzi:

5

Myślę, że to rozgryzłem. Za pomocą Edycji ADSI możesz przeglądać właściwości obiektu (np. Użytkownika), ale domyślnie filtrował atrybuty „zbudowane”. Za pomocą przycisku Filtr w prawym dolnym rogu ekranu właściwości mogłem wyświetlić te dodatkowe atrybuty.

Wydaje się, że „msDS-PrincipalName” ma „[nazwa domeny Netbios] \ [sAMAccountName]” jako swoją wartość.

Jeśli przejdę do AD Użytkownicy i komputery i zmienię „Nazwę logowania użytkownika” z „[email protected]” na „[email protected]”, wpływa to na atrybut „userPrincipalName”, ale nie na „msDS- Atrybut PrincipalName ”. Jest to dobre w moim przypadku, ponieważ mój inny system (SharePoint) również nie rozpoznaje tej zmiany.

Jeśli przejdę do AD Użytkownicy i komputery i zmienię „Nazwę logowania użytkownika (wcześniejszą niż Windows 2000)” z „KIRKDEV \ gwashington” na „KIRKDEV \ g2washington” (zauważ, że nie mogę zmienić pierwszej części), nie wpływa to na „userPrincipalName” atrybut, ale nie wpływa na atrybut „msDS-PrincipalName”. Właśnie tego chcę, ponieważ mój inny system (SharePoint) rozpoznaje tę zmianę.

Uwaga dodatkowa: Powiedziałem, że SharePoint rozpoznaje zmianę, ale dzieje się tak tylko wtedy, gdy użytkownik nigdy wcześniej nie logował się do tego zbioru witryn SharePoint. Gdy użytkownik zaloguje się do zbioru witryn SharePoint, pole tp_Login w tabeli UserInfo jest ustawiane wartością „msDS-PrincipalName” i wydaje się, że to się nie zmienia. Być może będę musiał znaleźć sposób na wymuszenie zmiany lub po prostu powiedzieć, że ten scenariusz nie jest obsługiwany.

Kirk Liemohn
źródło
Nie sprawdziłem, czy rzeczywiście możemy wyszukać „msDS-PrincipalName” z katalogu globalnego. To będzie następny krok.
Kirk Liemohn
Cóż, miałem zaznaczyć swoją odpowiedź jako prawidłową, ale teraz widzę, że Katalog globalny nie może zapytać msDS-PrincipalName. Ugh, wciąż nie jestem pewien, jak stamtąd wymyślimy nazwę domeny Netbios bez pewnych założeń (jakby to była pierwsza część FQDN).
Kirk Liemohn
Jeśli chodzi o moją notatkę dodatkową, zobacz serverfault.com/questions/234526/..., aby pomóc w uzyskaniu przez SharePoint rozpoznania zmiany logowania.
Kirk Liemohn
Jest to tak zwany skonstruowany atrybut - to jest obliczany na żądanie, gdy żądane jest zapytanie o obiekt. Z tego powodu nie można go filtrować w zapytaniu.
Brian Desmond
Dzięki za te informacje - przydały mi się bardzo przy zapytaniach za pośrednictwem LDAP z SQL Server.
Ian Yates
3

Aby odpowiedzieć na ostatnie pytanie, powinieneś być w stanie ręcznie zweryfikować nazwę NetBios, sprawdzając sekcję Konfiguracja, a następnie Partycje katalogu w ADSIEdit:

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

Ma to namei netBIOSNamewłaściwości. W przeciwnym razie myślę, że będziesz musiał pobrać go z fqdn / DN, jak sugeruje squillman.

BoyMars
źródło
Dzięki @BoyMars. Miałem problem ze znalezieniem „CN = Konfiguracja” na najwyższym poziomie w mojej domenie. Rozejrzałem się trochę i nie mogłem znaleźć „Konfiguracja” lub „Partycji katalogu”. Myślę jednak, że mogłem to rozgryźć (zamierzam opublikować odpowiedź).
Kirk Liemohn
OK, właśnie wymyśliłem, jak dostać się do CN = Konfiguracja (przepraszam, minęło około 6 lat, odkąd bawiłem się LDAP i ADSI Edit). @BoyMars, rozumiem o czym mówisz. Niestety, jest zapytanie o nazwę domeny Netbios, wydaje się, że muszę zapętlić wszystkie obiekty w CN = partycje, CN = konfiguracja i dla każdego sprawdzić, czy ma atrybut „nETBIOSName”. Być może zapytanie, które mówi, że daj mi wszystkie obiekty crossRef, w których atrybut netBIOSName nie ma wartości null, załatwi sprawę. Wydaje się to względnie łatwe do zrobienia w kodzie, ale muszę to zrobić przez konfigurację. :-(
Kirk Liemohn
Oto strona omawiająca sposób zapytania o nazwę netbiosname. Jednak używają kodu. Podejrzewam, że to nie zadziała dla mnie. geekswithblogs.net/Tariq/archive/2009/07/30/133813.aspx
Kirk Liemohn
ale wyjaśnia lokalizację „AD przechowuje nazwę netbios w kontenerze nazewnictwa Partitions, który jest przechowywany wewnątrz kontenera nazewnictwa konfiguracji”.
BoyMars,
Jest to jedyne wiarygodne źródło informacji. W szczególności wspomniany obiekt crossRef.
Brian Desmond
3

Do wniosku? Microsoft sprawia, że ​​jest to dość proste w .NET. Powinno to zapewnić Ci listę nazw Netbios domeny, których możesz użyć do utworzenia listy niestandardowych obiektów z nazwami DN / DNS / Netbios domeny lub słowników odsyłaczy.

To, co określa, czy atrybut jest dostępny w wykazie globalnym, to (jeszcze inny) atrybut o nazwie isMemberOfPartialAttributeSet. Za pomocą Microsoft SysInternals AD Explorer możesz przeszukiwać kontener Schematu w domenie i wyszukiwać dowolny obiekt, który ma isMemberOfPartialAttributeSet = true, aby zobaczyć wszystkie atrybuty dostępne dla zapytania 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;
}
Greg Askew
źródło
Dzięki za odpowiedź, ale muszę uruchomić to z komputera innego niż Windows. Jednak w razie potrzeby wydaje mi się, że mógłbym utworzyć własną usługę sieci Web w .NET i przekazać informacje na drugim komputerze. To może być podejście awaryjne.
Kirk Liemohn
2
To również powinno być proste. Ustaw podstawową nazwę wyróżniającą na „CN = partycje, CN = konfiguracja” + podstawowa nazwa wyróżniająca atrybutu nazwa wyróżniająca domeny, a filtr wyszukiwania na (& (nETBIOSName = *) (dnsRoot = <nazwa dns domeny AD>)). Możesz także wyszukać atrybut ncName zamiast dnsRoot, jeśli chcesz dopasować sufiks dn domeny zamiast nazwy dns.
Greg Askew
1

Będziesz musiał przeanalizować go z dn(nazwa wyróżniająca) lub AdsDSPathatrybutów. Jednostki nazw domen są poprzedzone "DC="tymi atrybutami. Najbardziej z lewej strony DC=będzie zawierać nazwę domeny Netbios.

Na przykład: cn=myuser,ou=users,dc=mydomain,dc=mycompany,dc=com

mydomain to nazwa domeny Netbios.

EDYCJA:
Jak zauważa Brian Desmond, niekoniecznie jest to autorytatywny sposób na znalezienie rzeczywistej nazwy netbios, jest to tylko zbieg okoliczności, że zwykle są one skorelowane. Zobacz odpowiedź BoyMars na autorytatywny sposób.

squillman
źródło
uważaj na limit netbios 15 znaków przy użyciu wartości z łańcucha fqdn lub DN, nie widziałem wielu domen, które używają łańcucha tak długo :)
BoyMars
Dzięki @squillman, ale kiedy utworzyłem tę domenę, celowo sprawiłem, że nazwa domeny Netbios nie była pierwszą częścią nazwy FQDN tylko dlatego, że było to możliwe i muszę sprawdzić granice, ponieważ mój kod musi działać w wielu środowiskach. W moim przypadku nazwa FQDN to test.kirkdev.local (przykładowy użytkownik dn to „CN = George Washington, CN = Użytkownicy, DC = test, DC = kirkdev, DC = lokalny”), ale nazwa domeny Netbios to kirkdev.
Kirk Liemohn
Jeśli używasz systemu Windows, dsquery computer OU=OU,OU=You,OU=Need,DC=local.domain -o rdndaje ci to, czego chcesz, z nazwą NetBIOS w cudzysłowie. Ponieważ jest względny, nie będziesz musiał uzyskać pełnej ścieżki. Nie jestem jednak pewien, czy to pomoże PO; zapytał o LDAP, więc nie jest to czysta odpowiedź LDAP.
songei2f
@alharaka dziękuję za komentarz, ale my odpytujemy AD z komputera innego niż MS. Potencjalnie moglibyśmy sobie z tym poradzić, ale naprawdę chcemy, aby było to częścią zapytania LDAP. Wygląda na to, że dsquery to narzędzie wiersza polecenia systemu Windows Server.
Kirk Liemohn
1
Przepraszam, ale to jest niepoprawne. Nie ma absolutnie ŻADNEGO związku między najwyższym komponentem domeny (np. Dc = mojadomena) a nazwą NetBIOS domeny. To tylko wspólny zbieg okoliczności, że się zgadzają.
Brian Desmond
0

Jeśli masz główną nazwę użytkownika lub nazwę wyróżniającą, możesz użyć biblioteki COM ActiveDS do przetłumaczenia wartości. Poniżej znajduje się przykład tłumaczenia nazwy użytkownika UserPrincipalName na nazwę 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);
        }
    }
}
Jeff
źródło
Dzięki za odpowiedź, ale muszę to zrobić z komputera innego niż Windows i najlepiej za pomocą zapytania LDAP.
Kirk Liemohn