views:

212

answers:

3

I am a newbie with LDAP. I am trying to list all the NT Domain names. By NT Domain names I mean, the names of domains you would find on the LAN Network. You can observe this on windows xp machines when you try to log-on to that machine (i.e. the log-on dialog you get after hitting ctrl+alt+del). Usually we select the domain name in the last drop down, after typing credentials.

I've taken a look at this post, and couldn't make anything off it. I don't know what rootDSE is. The code given in the post does it with rootdse. However, I have a specific server to hit and query, and I think its a domain controller. (I may be wrong on this). We write something like

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

As given in the post i tried to look for a property named rootDomainNamingContext. But I couldn't find it. Then I tried the below code:

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

I don't know what to specifically look for in the output I got. The output I got was:

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,

I really need guidance here.

UPDATE

I have used the code below to get the domains:

    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

Now the issue is two fold. Firstly, the inconsistency in the domain names. Suppose my DC's DNS name is prod.domain.com, and expected domain nams are for e.g. dev, domain, etc. Instead I get dev.domain.org, domain.org, etc. Some of the names which appear windows log-in dialog, when queried, appear with the suffix domain.org; some have the suffix .org.

The 2nd issue is not all the domain names (which appear in the windows log-in dialog, 3rd drop down) appear. Wonder why this is so?

UPDATE

Figure that the other domains (which are not appearing) may be part of another domain controller server or I need access the dc with appropriate credentials.

+2  A: 

RootDSE is defined in LDAP clossary. the root DSE could be, in your case, LDAP://<domain_name>/dc=<domain>,dc=org.

You should be able to get domains using the code on the other Stack Overflow question, if your AD server has rootDomainNamingContext defined. Since it seems you don't have that property, you'll need to iterate over the records to find the proper property. I'd suggest you go the the domain controller, either physically or via remote desktop, and open the AD directory and look for the entries and their properties to get a good view of what you need to query from VB. If you can't get access, ask your sysadmin.

jmz
updated the question
deostroll
+1 asking the admin is a lot easier, but reaching him/her isn't :)
deostroll
+1  A: 

It looks like I found a solution for you dude! I tried importing the COM reference for Interop.ActiveDs.dll (Active DS Type Library) then we can translate those names to what you had preferred.

Here goes my codes.

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";
    }
}

For more explanation you can view my article here http://anyrest.wordpress.com/2010/08/06/how-to-get-domain-name-pre-windows-2000-from-fqdn-fully-qualified-domain-name-using-c/

Raymund
thanx for the answer, but you may need to correct your code
deostroll
Very nice code except that `GetFriendlyName()` makes no sense
abatishchev
A: 

@Raymund's code using little bit of 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";
        }
    }
abatishchev