使用全局编录时,AD上的LDAP查询可以提供单个帐户的netbios域名吗?


11

我正在使用ADSI Edit查看AD中单个用户帐户的LDAP属性。我看到了诸如userPrincipalName之类的属性,但没有看到用于完全限定域名(FQDN)或netbios域名的属性。

我们将设置全局目录(GC),以使LDAP对多个域具有访问权限,并通过在应用程序中进行配置,我们将LDAP属性映射到应用程序中的用户配置文件属性。对于典型的AD,所有用户的FQDN和netbios域名都是相同的,但是在涉及GC的情况下,我们需要此附加信息。我们实际上只需要netbios域名(FQDN不够好)。

也许可以执行LDAP查询以从AD中更顶层的对象请求此信息?

Answers:


5

我想我知道了。使用ADSI Edit,您可以查看对象(例如,用户)的属性,但是默认情况下,它会过滤掉“构造的”属性。使用属性屏幕右下方的“过滤器”按钮,我可以显示这些附加属性。

“ msDS-PrincipalName”似乎具有“ [netbios域名] \ [sAMAccountName]”作为其值。

如果我进入“ AD用户和计算机”并将“用户登录名”从“ gwasington@test.kirkdev.local”更改为“ gwash2ington@test.kirk2dev.local”,则会影响“ userPrincipalName”属性,但不会影响“ msDS- PrincipalName”属性。就我而言,这很好,因为我的其他系统(SharePoint)也无法识别此更改。

如果我进入“ AD用户和计算机”,并将“用户登录名(Windows 2000之前的版本)”从“ KIRKDEV \ gwashington”更改为“ KIRKDEV \ g2washington”(请注意,我无法更改第一部分),这不会影响“ userPrincipalName”属性,但影响“ msDS-PrincipalName”属性。这正是我想要的,因为我的其他系统(SharePoint)确实可以识别此更改。

旁注:我说过SharePoint可以识别更改,但是前提是用户以前从未登录过该SharePoint网站集。用户登录到SharePoint网站集后,将使用“ msDS-PrincipalName”值设置UserInfo表中的tp_Login字段,并且该值似乎没有改变。因此,我可能必须找到一种方法来强制进行更改,或者只是说不支持这种情况。


我尚未验证我们是否可以实际从全局目录中查询“ msDS-PrincipalName”。这将是下一步。
Kirk Liemohn

好了,我打算将答案标记为正确的答案,但是现在我看到全局目录无法查询msDS-PrincipalName。gh,仍然不确定我们如何在不做任何假设的情况下从那里算出netbios域名(例如,它是FQDN的第一部分)。
Kirk Liemohn

关于我的旁注,请参阅serverfault.com/questions/234526/…以帮助SharePoint识别登录更改。
柯克·利摩恩

这就是所谓的构造属性-即在请求对象时按需计算的属性。因此,您无法在查询中对其进行过滤。
布莱恩·戴斯蒙德

感谢您提供此信息-从SQL Server通过LDAP查询时,对我来说非常方便。
伊恩·耶茨

3

要回答您的最后一个问题,您应该能够通过检查“配置”部分,然后检查ADSIEdit中的“目录分区”来手动验证NetBios名称:

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

这具有namenetBIOSName属性。否则,我认为您必须按照squillman的建议从fqdn / DN中获取它。


谢谢@BoyMars。我在域的顶级位置找到“ CN = Configuration”时遇到了一些麻烦。我戳了一下,找不到“配置”或“目录分区”。但是,我想我可能已经弄清楚了(即将发布答案)。
Kirk Liemohn

好的,我只是想出了如何使用CN = Configuration(对不起,距离我使用LDAP和ADSI Edit已有6年了)。@BoyMars,我确实知道您在说什么。不幸的是,要查询netbios域名,看来我需要遍历CN = Partitions,CN = Configuration下的所有对象,并为每个对象查看它是否具有“ nETBIOSName”属性。也许有一个查询告诉我netBIOSName属性不为null的所有crossRef对象都会解决这个问题。这似乎在代码中相对容易实现,但是我必须通过配置来实现。:-(
Kirk Liemohn 2011年

这是讨论如何查询netbiosname的页面。他们正在使用代码。我怀疑这对我不起作用。 geekswithblogs.net/Tariq/archive/2009/07/30/133813.aspx
Kirk Liemohn 2011年

但它确实说明了位置“ AD将netbios名称存储在分区命名容器中,该名称存储在配置命名容器中”。
BoyMars 2011年

这是唯一的权威信息来源。具体而言,提到了crossRef对象。
布莱恩·戴斯蒙德

3

要申请吗?Microsoft在.NET中使其变得相当简单。这应该为您提供域Netbios名称的列表,可用于创建具有域DN / DNS / Netbios名称或交叉引用字典的自定义对象的列表。

同样,确定属性在全局编录中是否可用的是另一个属性isMemberOfPartialAttributeSet。使用Microsoft SysInternals AD Explorer,可以搜索域中的Schema容器,并搜索具有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中创建自己的Web服务,并向另一台计算机提供此信息。那可能是一个后备方法。
Kirk Liemohn 2011年

2
那也应该很简单。将您的基本DN设置为“ CN =分区,CN =配置” +域distinguishedName属性的基本DN,并将搜索过滤器设置为(&(nETBIOSName = *)(dnsRoot = <AD域的dns名称>))。如果要匹配域的dn后缀而不是dns名称,也可以搜索ncName属性而不是dnsRoot。
Greg Askew

1

您必须从dn(distinguishedName)或AdsDSPath属性中解析它。域名实体"DC="在这些属性中带有前缀。最左侧DC=将包含您的netbios域名。

例如: cn=myuser,ou=users,dc=mydomain,dc=mycompany,dc=com

mydomain 是netbios域名。

编辑:
正如布赖恩·戴斯蒙德(Brian Desmond)所指出的那样,这不一定是查找实际netbios名称的权威方法,这只是它们通常相关的巧合。有关权威性方法,请参见BoyMars的答案。


当使用来自fqdn或DN字符串的值时,注意netbios限制为15个字符,但是我没有看到很多使用字符串的域这么长时间:)
BoyMars 2011年

感谢@squillman,但是当我创建此域时,我故意使netbios域名不是 FQDN的第一部分,因为这是可能的,并且我需要检查边界,因为我的代码必须在多个环境中工作。因此,在我的情况下,FQDN是test.kirkdev.local(示例用户dn是“ CN = George Washington,CN = Users,DC = test,DC = kirkdev,DC = local”),但是netbios域名是kirkdev。
Kirk Liemohn 2011年

如果使用Windows,则使用dsquery computer OU=OU,OU=You,OU=Need,DC=local.domain -o rdnNetBIOS名称(用引号引起来)为您提供所需的内容。由于它是相对的,因此您无需获取完整路径。不确定这是否对OP有帮助;他询问了LDAP,所以这不是一个纯粹的LDAP答案。
songei2f 2011年

@alharaka感谢您的评论,但我们正在从非MS计算机查询AD。我们可能会处理它,但我们确实希望它成为LDAP查询的一部分。看来dsquery是Windows Server命令行工具。
Kirk Liemohn

1
抱歉,这是不正确的。顶级域组件(例如dc = mydomain)与域的NetBIOS名称之间绝对没有关系。他们同意只是一个普遍的巧合。
布莱恩·戴斯蒙德

0

如果您具有用户主体名称或DN,则可以使用ActiveDS COM库来转换值。下面是将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查询来执行此操作。
Kirk Liemohn 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.