Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the NETBIOS Domain Name using the FQDN in a Complex Environment

Getting the NETBIOS domain name from a fully qualified Active Directory domain name is sometimes a tedious task. I found a good answer here.

In an environment with multiple forests this approach will however not work if the PC is not in the forest you are querying. This is because LDAP://RootDSE will query information for the computer’s domain.

Some might ask: why so complicated? Just use the name before the first dot retrieved by:

ActiveDirectory.Domain.GetComputerDomain().Name;

Or just get the user's domain name:

Environment.GetEnvironmentVariable("USERDOMAIN");

or

Environment.UserDomainName;

BUT the NETBIOS domain name can be something completely different, and you or your computer might be in a different domain or forest! So this approach is usable only in a simple environment.

DJ KRAZE’s solution needs only one small modification to allow cross domain queries. This assumes a trust relationship!

private string GetNetbiosDomainName(string dnsDomainName)
{
      string netbiosDomainName = string.Empty;

      DirectoryEntry rootDSE = new DirectoryEntry(string.Format("LDAP://{0}/RootDSE",dnsDomainName));

      string configurationNamingContext = rootDSE.Properties["configurationNamingContext"][0].ToString();

      DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=Partitions," + configurationNamingContext);

      DirectorySearcher searcher = new DirectorySearcher(searchRoot);
      searcher.SearchScope = SearchScope.OneLevel;
      searcher.PropertiesToLoad.Add("netbiosname");
      searcher.Filter = string.Format("(&(objectcategory=Crossref)(dnsRoot={0})(netBIOSName=*))", dnsDomainName);

      SearchResult result = searcher.FindOne();

      if (result != null)
      {
        netbiosDomainName = result.Properties["netbiosname"][0].ToString();
      }

      return netbiosDomainName;
    }
like image 274
Daro Avatar asked Jan 02 '13 09:01

Daro


People also ask

What is the FQDN and NetBIOS domain?

DNS computer names consist of two parts: a host name and a domain name, which combined form the fully qualified domain name (FQDN). Fortunately, NetBIOS computer names are compatible with DNS host names, making interoperability possible between the two types of components.

What is the NetBIOS name of this computer?

NetBIOS name In a Windows-based computer, the name you see listed on the Computer Name tab of the My Computer properties is the NetBIOS name. This name can be up to 15 characters long (in Microsoft operating systems) and is used to identify the computer on the network.

Which of the following NetBIOS names Cannot be used?

The "NetBIOS domain name\username" format cannot be used for user accounts in a child domain when the Kerberos referral mechanism is working in a cross-forest environment in which trusts are established among the forests.


1 Answers

You can also use the DsGetDcName API, which will do all the monkeying around for you. It will also cache calls and not even hit the network if the domain you are querying is the local computer.

If you have additional requirements on the capabilities of the

Use:

internal static string GetNetbiosNameForDomain(string dns)
{
    IntPtr pDomainInfo;
    int result = DsGetDcName(null, dns, IntPtr.Zero, null,
        DSGETDCNAME_FLAGS.DS_IS_DNS_NAME | DSGETDCNAME_FLAGS.DS_RETURN_FLAT_NAME,
        out pDomainInfo);
    try
    {
        if (result != ERROR_SUCCESS)
            throw new Win32Exception(result);

        var dcinfo = new DomainControllerInfo();
        Marshal.PtrToStructure(pDomainInfo, dcinfo);

        return dcinfo.DomainName;
    }
    finally
    {
        if (pDomainInfo != IntPtr.Zero)
            NetApiBufferFree(pDomainInfo);
    }
}

P/Invoke:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private class DomainControllerInfo
{
    public string DomainControllerName;
    public string DomainControllerAddress;
    public int DomainControllerAddressType;
    public Guid DomainGuid;
    public string DomainName;
    public string DnsForestName;
    public int Flags;
    public string DcSiteName;
    public string ClientSiteName;
}

[Flags]
private enum DSGETDCNAME_FLAGS : uint
{
    DS_FORCE_REDISCOVERY = 0x00000001,
    DS_DIRECTORY_SERVICE_REQUIRED = 0x00000010,
    DS_DIRECTORY_SERVICE_PREFERRED = 0x00000020,
    DS_GC_SERVER_REQUIRED = 0x00000040,
    DS_PDC_REQUIRED = 0x00000080,
    DS_BACKGROUND_ONLY = 0x00000100,
    DS_IP_REQUIRED = 0x00000200,
    DS_KDC_REQUIRED = 0x00000400,
    DS_TIMESERV_REQUIRED = 0x00000800,
    DS_WRITABLE_REQUIRED = 0x00001000,
    DS_GOOD_TIMESERV_PREFERRED = 0x00002000,
    DS_AVOID_SELF = 0x00004000,
    DS_ONLY_LDAP_NEEDED = 0x00008000,
    DS_IS_FLAT_NAME = 0x00010000,
    DS_IS_DNS_NAME = 0x00020000,
    DS_RETURN_DNS_NAME = 0x40000000,
    DS_RETURN_FLAT_NAME = 0x80000000
}

[DllImport("Netapi32.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "DsGetDcNameW", CharSet = CharSet.Unicode)]
private static extern int DsGetDcName(
    [In] string computerName,
    [In] string domainName,
    [In] IntPtr domainGuid,
    [In] string siteName,
    [In] DSGETDCNAME_FLAGS flags,
    [Out] out IntPtr domainControllerInfo);

[DllImport("Netapi32.dll")]
private static extern int NetApiBufferFree(
    [In] IntPtr buffer);

private const int ERROR_SUCCESS = 0;
like image 119
Mitch Avatar answered Sep 24 '22 17:09

Mitch