代码之家  ›  专栏  ›  技术社区  ›  deostroll

LDAP:如何获取所有域名的列表

  •  3
  • deostroll  · 技术社区  · 14 年前

    我是LDAP的新手。我正在列出所有的NT域名。我说的NT域名是指你在局域网上可以找到的域名。当您尝试登录到该计算机时,可以在Windows XP计算机上观察到这一点(即,在按下ctrl+alt+del后,您将看到登录对话框)。通常,我们在最后一个下拉列表中输入凭据后选择域名。

    我看了一下 this post 也做不到什么。我不知道什么 rootDSE 是。文章中给出的代码使用rootdse执行此操作。但是,我有一个特定的服务器要访问和查询,我认为它是一个域控制器。(我可能错了)。我们写的东西

    LDAP://<domain_name>/dc=<domain>,dc=org
    

    正如我在文章中提到的,我试图寻找一个名为 rootDomainNamingContext . 但我找不到。然后我尝试了下面的代码:

    Sub Main()
            Dim oRoot As DirectoryEntry = Nothing
            'Dim oSearcher As DirectorySearcher
            'Dim oResults As SearchResultCollection
    
            Try
    
                oRoot = New DirectoryEntry("LDAP://<domain_name>/dc=<domain>,dc=org")
                For Each obj As String In oRoot.Properties.PropertyNames
                    Console.Write(obj + ", ")
                Next
            Catch ex As Exception
                Console.Write(ex.Message)
            Finally
                oRoot.Dispose()
            End Try
    
            Console.Read()
        End Sub
    

    我不知道在我得到的输出中要特别寻找什么。我得到的结果是:

    objectClass, description, distinguishedName, instanceType, whenCreated, whenChan
    ged, subRefs, uSNCreated, dSASignature, repsTo, repsFrom, uSNChanged, name, obje
    ctGUID, replUpToDateVector, creationTime, forceLogoff, lockoutDuration, lockOutO
    bservationWindow, lockoutThreshold, maxPwdAge, minPwdAge, minPwdLength, modified
    CountAtLastProm, nextRid, pwdProperties, pwdHistoryLength, objectSid, uASCompat,
     modifiedCount, auditingPolicy, nTMixedDomain, rIDManagerReference, fSMORoleOwne
    r, systemFlags, wellKnownObjects, objectCategory, isCriticalSystemObject, gPLink
    , gPOptions, masteredBy, ms-DS-MachineAccountQuota, msDS-Behavior-Version, msDS-
    PerUserTrustQuota, msDS-AllUsersTrustQuota, msDS-PerUserTrustTombstonesQuota, ms
    Ds-masteredBy, dc, nTSecurityDescriptor,
    

    我真的需要指导。

    更新

    我使用下面的代码获取域:

        Dim dc As New DirectoryContext(DirectoryContextType.DirectoryServer, DcIpAddr)
        Dim domc As DomainController = DomainController.GetDomainController(dc)
        For Each dmn As Domain In domc.Forest.Domains
            Console.WriteLine(dmn.Name)
        Next
    

    现在问题是双重的。首先,域名的不一致性。假设我的DC的DNS名称是 prod.domain.com 以及预期的域名名称,例如 dev, domain, etc . 取而代之的是我得到 dev.domain.org, domain.org, etc . 在查询时,显示在“Windows登录”对话框中的某些名称会显示为后缀 domain.org ;有些有后缀 .org .

    第二个问题不是所有域名(出现在Windows登录对话框的第三个下拉列表中)都会出现。不知道为什么会这样?

    更新

    图中的其他域(未显示)可能是另一个域控制器服务器的一部分,或者我需要使用适当的凭据访问DC。

    3 回复  |  直到 12 年前
        1
  •  1
  •   abatishchev Marc Gravell    14 年前

    看来我找到了解决办法! 我尝试导入interop.active ds.dll(活动DS类型库)的COM引用,然后我们可以将这些名称转换为您喜欢的名称。

    这是我的密码。

    using System.DirectoryServices.ActiveDirectory;
    using ActiveDs;
    
    private void ListDomains()
    {
        string sUserName = "xxxx";
        string sPassword = "xxxx";
    
        DirectoryContext oDirectoryContext = new DirectoryContext(DirectoryContextType.Domain, sUserName, sPassword);
    
        Domain oCurrentDomain = Domain.GetDomain(oDirectoryContext);
        Forest oForest = oCurrentDomain.Forest;
        DomainCollection oAddDomainsInForest = oForest.Domains;
    
        foreach (Domain oDomain in oAddDomainsInForest)
        {
            Console.WriteLine(GetFriendlyName(oDomain.ToString()));
        }           
    }
    
    private string GetFriendlyName(string sDomainName)
    {
        try
        {
            IADsADSystemInfo oSysInfo = new ADSystemInfoClass();
            IADsNameTranslate oNameTranslate = new NameTranslateClass();
            oNameTranslate.Init((int)ADS_NAME_INITTYPE_ENUM.ADS_NAME_INITTYPE_DOMAIN, sDomainName);
    
            string[] aSplitDN = sDomainName.Split(new Char[] { '.' });
            string sDistinguishedName = "";
    
            //Convert Domain Name to Distinguished Name
            foreach (string sDomainPart in aSplitDN)
            {
                sDistinguishedName = sDistinguishedName + "DC=" + sDomainPart + ",";
            }
    
            oNameTranslate.Set((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_UNKNOWN, sDistinguishedName.Remove(sDistinguishedName.Length - 1));//Remove the last comma
            string sFriendlyName = oNameTranslate.Get((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_NT4);
            return sFriendlyName(@"\", "");
        }
        catch
        {
            return "Access Denied";
        }
    }
    

    你可以在这里查看我的文章来获得更多的解释 http://anyrest.wordpress.com/2010/08/06/how-to-get-domain-name-pre-windows-2000-from-fqdn-fully-qualified-domain-name-using-c/

        2
  •  2
  •   jmz    14 年前

    rootdse在中定义 LDAP clossary . 根DSE可能是,在您的情况下, LDAP://<domain_name>/dc=<domain>,dc=org .

    如果您的广告服务器定义了rootDomainNamingContext,则应该能够使用其他堆栈溢出问题上的代码获取域。由于您似乎没有该属性,因此需要对记录进行迭代,以找到正确的属性。我建议您通过物理或远程桌面访问域控制器,打开a d目录并查找条目及其属性,以便从vb中获得需要查询的内容的良好视图。如果无法访问,请询问系统管理员。

        3
  •  0
  •   abatishchev Marc Gravell    14 年前

    @Raymund的代码使用了一点LINQ:

        private static string GetFriendlyName(string names)
        {
            try
            {
                string[] arr = names.Split('.');
                //Convert Domain Name to Distinguished Name
                string distinguishedName = String.Join(",", arr.Select(d => "DC=" + d));
    
                IADsADSystemInfo info = new ADSystemInfo();
                IADsNameTranslate nameTranslate = new NameTranslate();
                nameTranslate.Init((int)ADS_NAME_INITTYPE_ENUM.ADS_NAME_INITTYPE_DOMAIN, names);
                nameTranslate.Set((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_UNKNOWN, distinguishedName);
    
                string friendlyName = nameTranslate.Get((int)ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_DOMAIN_SIMPLE);
                return friendlyName.Replace("\\", String.Empty);
            }
            catch
            {
                return "Access Denied";
            }
        }