13

I am using ADSI Edit to look at LDAP properties of a single user account in AD. I see properties such as userPrincipalName, but I do not see one for the fully qualified domain name (FQDN) or the netbios domain name.

We will be setting up the Global Catalog (GC) to give us LDAP access to multiple domains and through configuration in an application we map LDAP properties to user profile properties within the application. With typical AD the FQDN and netbios domain name are the same for all users, but with the GC involved we need this additional information. We really only need the netbios domain name (the FQDN is not good enough).

Maybe there is a LDAP query that can be done to request this information from a more top-level object in AD?

Kirk Liemohn
  • 593
  • 3
  • 8
  • 18

5 Answers5

7

I think I figured it out. Using ADSI Edit you can look at properties on an object (e.g., a user), but by default it was filtering out "constructed" attributes. Using the Filter button at the bottom right of the properties screen I was able to show these additional attributes.

The "msDS-PrincipalName" appears to have "[netbios domain name]\[sAMAccountName]" as its value.

If I go into AD Users and Computers and change the "User logon name" from "gwasington@test.kirkdev.local" to "gwash2ington@test.kirk2dev.local" this affects the "userPrincipalName" attribute, but not the "msDS-PrincipalName" attribute. This is good in my case, because my other system (SharePoint) does not recognize this change either.

If I go into AD Users and Computers and change the "User logon name (pre-Windows 2000)" from "KIRKDEV\gwashington" to "KIRKDEV\g2washington" (note, that I cannot change the first part) this does not affect the "userPrincipalName" attribute, but does affect the "msDS-PrincipalName" attribute. This is exactly what I want because my other system (SharePoint) does recognize this change.

Side Note: I said SharePoint does recognize the change, but that is only if the user has never logged into that SharePoint site collection before. Once the user has logged into the SharePoint site collection, the tp_Login field in the UserInfo table is set with the "msDS-PrincipalName" value and that does not seem to change. So, I may have to find a way to force that to be changed or just say that this scenario is not supported.

Kirk Liemohn
  • 593
  • 3
  • 8
  • 18
  • I haven't verified that we can actually query "msDS-PrincipalName" from the Global Catalog. That will be the next step. – Kirk Liemohn Feb 11 '11 at 15:52
  • Well, I was about to mark my answer as the correct one, but now I see that the Global Catalog cannot query msDS-PrincipalName. Ugh, still not sure how we'll figure out the netbios domain name from there without making some assumptions (like it is the first part of FQDN). – Kirk Liemohn Feb 14 '11 at 18:01
  • Regarding my side note, see http://serverfault.com/questions/234526/how-do-you-get-sharepoint-back-in-sync-when-you-change-a-users-samaccountname to help with getting SharePoint to recognize the login change. – Kirk Liemohn Feb 15 '11 at 18:31
  • This is what's called a constructed attribute - that is it's calculated on demand when a request is made for an object. You can't filter on it in a query because of this. – Brian Desmond Feb 21 '11 at 01:44
  • Thanks for this info - came in very handy for me when querying via LDAP from SQL Server. – Ian Yates Jun 11 '15 at 07:19
3

To answer your last question you should be able to verify the NetBios name manually by checking the Configuration section and then Directory Partitions in ADSIEdit:

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

This has both name and netBIOSName properties. Otherwise I think you'd have to get it from a fqdn/DN as squillman suggests.

BoyMars
  • 1,012
  • 1
  • 6
  • 15
  • Thanks @BoyMars. I had some trouble finding "CN=Configuration" at the top level in my domain. I poked around a bit and couldn't find "Configuration" or "Directory Partitions". However, I think I may have figure this out (about to post answer). – Kirk Liemohn Feb 11 '11 at 15:23
  • OK, I just figured out how to get to CN=Configuration (sorry, it's been about 6 years since I played around with LDAP and ADSI Edit). @BoyMars, I do see what you are talking about. Unfortunately, is to query the netbios domain name, it appears that I need to loop through all objects under CN=Partitions,CN=Configuration and for each one see if it has a "nETBIOSName" attribute. Maybe a query that says give me all crossRef objects where the netBIOSName attribute is not null would do the trick. This seems relatively easy to do in code, but I have to do this through configuration. :-( – Kirk Liemohn Feb 11 '11 at 19:49
  • Here is a page that discusses how to query the netbiosname. They are using code, though. I suspect that this won't work for me. http://geekswithblogs.net/Tariq/archive/2009/07/30/133813.aspx – Kirk Liemohn Feb 11 '11 at 20:45
  • but it does explain the location "AD stores the the netbios name in the Partitions naming container which is stored inside the configuration naming container." – BoyMars Feb 12 '11 at 07:35
  • This is the only authoritative source of information. Specifically, the crossRef object mentioned. – Brian Desmond Feb 21 '11 at 01:47
3

For an application? Microsoft makes this fairly straightforward in .NET. This should provide you with a list of domain Netbios names that you can use to create a list of custom objects with the domain DN/DNS/Netbios names, or cross-referencing dictionaries.

Also, what determines if an attribute is available in the Global Catalog is (yet another) attribute called isMemberOfPartialAttributeSet. Using Microsoft SysInternals AD Explorer, you can search the Schema container in a domain, and search for any object that has the isMemberOfPartialAttributeSet = true to see all the attributes that are available for a GC query.

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
  • 35,880
  • 5
  • 54
  • 82
  • Thanks for the answer, but I need to run this from a non-Windows machine. However, if needed I guess I could create my own web service in .NET and provide the other machine with this information. That can be a fallback approach. – Kirk Liemohn Jun 06 '11 at 11:25
  • 2
    That should also be straightforward. Set your base DN to "CN=Partitions,CN=Configuration"+ the base DN of the domain distinguishedName attribute, and the search filter to (&(nETBIOSName=*)(dnsRoot=)). You can also search for the ncName attribute instead of dnsRoot, if you want to match the dn suffix of the domain instead of the dns name. – Greg Askew Jun 06 '11 at 16:16
1

You'll have to parse it out of either the dn (distinguishedName) or the AdsDSPath attributes. Domain name entities are prefixed with "DC=" in these attributes. The leftmost DC= will contain your netbios domain name.

For example: cn=myuser,ou=users,dc=mydomain,dc=mycompany,dc=com

mydomain is the netbios domain name.

EDIT:
As Brian Desmond points out, this is not necessarily the authoritative way to find the actual netbios name, it is merely coincidence that they usually correlate. See BoyMars' answer for the authoritative way.

squillman
  • 37,883
  • 12
  • 92
  • 146
  • watch for netbios limit of 15 chars when using the values from a fqdn or DN string, i haven't seen many domains that use a string that long though :) – BoyMars Feb 10 '11 at 20:19
  • Thanks @squillman, but when I created this domain I purposely made the netbios domain name *not* be the first part of the FQDN just because it was possible and I need to check the boundaries as my code has to work in multiple environments. So in my case the FQDN is test.kirkdev.local (example user dn is "CN=George Washington,CN=Users,DC=test,DC=kirkdev,DC=local") but the netbios domain name is kirkdev. – Kirk Liemohn Feb 11 '11 at 15:07
  • If you are using Windows, `dsquery computer OU=OU,OU=You,OU=Need,DC=local.domain -o rdn` gives you what you want, with the NetBIOS name in quotation marks. Since it is relative, you will not need get the full path. Not sure if this will help the OP though; he asked about LDAP, so this is not a pure LDAP answer. – songei2f Feb 11 '11 at 16:02
  • @alharaka thanks for the comment, but we are querying AD from a non-MS computer. We could potentially deal with it, but we really do want this to be part of an LDAP query. It appears that dsquery is a Windows Server command line tool. – Kirk Liemohn Feb 11 '11 at 17:52
  • @Kirk It is and I am sorry for you, haha. Too many times I want Linux to solve my problems for me, and I am forced to use Windows to interact with AD because it is the easier solution if you want something easy to parse. – songei2f Feb 11 '11 at 21:07
  • 1
    Sorry but this is incorrect. There is absolutely NO relationship between the top domain component (e.g. dc=mydomain) and the NetBIOS name of the domain. It's just a common coincidence that they agre. – Brian Desmond Feb 21 '11 at 01:43
  • @Brian Thanks for the clarification. I've edited my answer to note that. – squillman Feb 21 '11 at 14:41
0

If you have the User Principal Name or the DN you can use the ActiveDS COM library to translate the values. Below is an example to translate UserPrincipalName to NT4 (NetBios) name.

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
  • 1,018
  • 1
  • 10
  • 14