Link to home
Start Free TrialLog in
Avatar of sol400
sol400Flag for United States of America

asked on

Find Active Directory Server URL/IP

I have an application that runs on client machines. The application validates the user credentials using  LDAP against Active Directory.  Some of my clients have no idea what the URL or IP address is of their Active Directory server.

What is the proper procedure to locate the Active Directory (LDAP) credential server?

Thanks,
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image


If AD is properly configured it should be the DNS Domain Name.

There are a number of ways to get that, you might use the environmental variable %USERDNSDOMAIN%.

If you wanted to be clever you could build site-awareness into your application and have it locate a local DC using the Service Records registered in DNS, but that's a bit more involved than just looking up the domain name in DNS.

Chris
Avatar of sol400

ASKER

Hi,
The users I am working also would not have access to the DNS. They generally know their internal domain name. These are generally large companies where the network is maintained by a different group. I know that they can ping %USERDNSDOMAIN% to get the domain BUT have no idea about how to find the Active Directory server URL/IP

Thanks,
Spencer

If AD is properly configured, and you have to make that assumption somewhere then the IP Addresses you get back from %UserDNSDomain% are the Domain Controllers / AD Servers / IP.

At the very least they will be able to query DNS, I didn't expect them to have any level of access beyond that. That's all you need though, Domain Controllers publish information in DNS, if you know the domain name you can find Domain Controllers, Global Catalogs, whatever you want.

If you needed specifics about LDAP itself you could connect to RootDSE (e.g. LDAP://IPAddress/RootDSE) on the IP returned from a query of the DNS Domain to get basic configuration information.

Chris
Avatar of sol400

ASKER

Hi, Maybe I do not understand the PING %USERDNSDOMAIN% I just ran it on my system and received the following:
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\>ping %UserDNSDomain%
Pinging INTRA.S4ISYSTEMS.COM [10.47.55.117] with 32 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
Ping statistics for 10.47.55.117:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

I then ran the ldap command and received the following:
C:\>ldap://10.47.55.117/RootDSE
'ldap:' is not recognized as an internal or external command,
operable program or batch file.

I checked my Active Directory server and DNS and found that ip:10.47.55.117 is NOT assigned ot any machine in my shop BUT I found the following A records in my internal domain zone
Name      Type      Data
(same as parent folder)      Host (A)      10.47.55.30
(same as parent folder)      Host (A)      10.47.55.100
(same as parent folder)      Host (A)      10.47.55.102
(same as parent folder)      Host (A)      10.47.55.110
(same as parent folder)      Host (A)      10.47.55.112
(same as parent folder)      Host (A)      10.47.55.113
(same as parent folder)      Host (A)      10.47.55.114
(same as parent folder)      Host (A)      10.47.55.117
(same as parent folder)      Host (A)      10.47.55.118
(same as parent folder)      Name Server (NS)      s4isvr03.intra.s4isystems.com.
(same as parent folder)      Start of Authority (SOA)      [4678], s4isvr03.intra.s4isystems.com., hostmaster.

My Active Directory server has the following IP addresses assigned only. I do not have Active Directory on any other server.  It appears to me that I need to remove some A records for the internal domain zone. What do you think?
10.47.55.30
10.47.55.110
10.47.55.113
10.47.55.112

Now back to my customers problem.  Are you saying that the PING should return the IP address of the Active Directory server because I was under the impression that the DNS and Active Directory could reside on different servers?

Yeah, it looks like it. That goes back to assumptions of correct configuration, clearly not a good assumption :)

Can you run this command:

nslookup -q=srv _ldap._tcp.intra.s4isystems.com

In theory that should return all your domain controllers (it's one of the service records I mentioned above). Does it?

Chris
Avatar of sol400

ASKER

C:\>nslookup -q=srv _ldap._tcp.intra.s4isystems.com
*** Can't find server name for address 10.47.55.112: Non-existent domain
*** Default servers are not available
Server:  UnKnown
Address:  10.47.55.112
_ldap._tcp.intra.s4isystems.com SRV service location:
          priority       = 0
          weight         = 100
          port           = 389
          svr hostname   = s4isvr03.intra.s4isystems.com
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.112
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.110
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.113
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.30

So what does this mean report mean?

Thanks,

It means DNS thinks you have 4 Domain Controllers on each of the IP Addresses listed there. Is it accurate?

Just in case... the error message, it's because it cannot find a PTR record in the Reverse Lookup zone for your server. If you expand Reverse Lookup Zones in the DNS Console I would expect to have a zone called "10.47.55.x Subnet" or "55.47.10.in-addr.arpa" (the two names being equivalent). The name is a bit dependant on your IP range.

Chris
Avatar of sol400

ASKER

S4iSVR03 is the only domain controller BUT it has these 4-IP addresses assigned.
Here are the records from 55.47.10.in-addr.arpa.  BTW We changed both our interal and external IPs within the last 6-months.

I know I have gotton off us off target here but I am still hoping I can find a cook book aproach to finding the Active Directory.

Name      Type      Data
30      Pointer (PTR)      s4isvr03.intra.s4isystems.com.
71      Pointer (PTR)      etiws070.intra.s4isystems.com.
80      Pointer (PTR)      s4iws06.intra.s4isystems.com.
82      Pointer (PTR)      s4iws07.intra.s4isystems.com.
83      Pointer (PTR)      s4iws05.intra.s4isystems.com.
88      Pointer (PTR)      s4iws08.intra.s4isystems.com.
120      Pointer (PTR)      technical.intra.s4isystems.com.
128      Pointer (PTR)      s4i_mobile_g41.intra.s4isystems.com.
129      Pointer (PTR)      s4isvr03.intra.s4isystems.com.
131      Pointer (PTR)      s4iws01.intra.s4isystems.com.
134      Pointer (PTR)      s4i_mobile_g41.intra.s4isystems.com.
135      Pointer (PTR)      s4i_mobile_g41.intra.s4isystems.com.
140      Pointer (PTR)      s4iws01.intra.s4isystems.com.
172      Pointer (PTR)      s4i_mobile_g41.intra.s4isystems.com.
198      Pointer (PTR)      s4iws02.intra.s4isystems.com.
201      Pointer (PTR)      s4i_mobile_g41.intra.s4isystems.com.
(same as parent folder)      Name Server (NS)      s4isvr03.intra.s4isystems.com.
(same as parent folder)      Start of Authority (SOA)      [66], s4isvr03.intra.s4isystems.com., hostmaster.intra.s4isystems.com.

Lets take a step back from that a moment and look back at finding AD.

Every member of the domain knows about AD. It has to because it belongs to the domain and authenticates against it.

That means that in an application you can make use of Serverless Binding. By that I mean instead of using:

LDAP://SomeServer/DC=domain,DC=com

You would use:

LDAP://DC=domain,DC=com

Whether that works for you or not depends on how the application works. If that's not appropriate there are quite a few different ways to end up at the server. Are you looking to modify the application to find this dynamically? Or do you just need a quick way of determining it when a user needs it?

If you're modifying the code, are you able to show us what it's doing to connect to AD at the moment?

Back on the AD / DNS side...

> BUT it has these 4-IP addresses assigned

Does it have 4 network interfaces? Or just one?

Multi-homed DCs are always more problematic than DCs with just one interface. They register too much in DNS which can get very confusing for clients. We can stop it registering lots of extra IP addresses, provided they're separate network interfaces.

Chris
Avatar of sol400

ASKER

The 4-ips are multi-homed (one network card).  My LDAP validation JSP is attached in the next section.  I pick up the ExpAppProperties come from a configuration properties file. I did not know that it was possible to validate without the host IP address/name but it makes sense.

My current values in the properties file are:
serverValidationExit=http://localhost:8080/wv31/Login/ldapNetworkUserValidator.jsp
ldapProviderUrl=ldap://s4isvr03.intra.s4isystems.com:389/dc=intra,dc=s4isystems,dc=com
ldapProviderUrl=ldap://dc=intra,dc=s4isystems,dc=com
ldapProviderDomain=intra.s4isystems.com
serverValidationSuccess=<networkuser>valid</networkuser>



<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="1.2">
<jsp:directive.page	import="java.util.*"/>
<jsp:directive.page import="javax.naming.*" />
<jsp:directive.page import="javax.naming.directory.*" />
<jsp:directive.page import="com.s4i.express.service.ExpAppProperties" />
<jsp:scriptlet> 
<![CDATA[
	/**
	*	ldapNetworkUserValidator.jsp
	*	Validate WebView user against an ldap server (Active Directory )
	*	See: Microsoft Article ID: 240078 
	*	Exchange Server and Active Directory Utilize the Same LDAP Ports
	*/
	//---( Change the following values to match your ldap server )---
//	String providerUrl = "ldap://intra.s4isystems.com:389/o=intra.s4isystems.com";
//	String providerUrl = "ldap://intra.s4isystems.com:389/dc=intra,dc=s4isystems,dc=com";
//	String domain = "intra.s4isystems.com";
	String providerUrl = ExpAppProperties.getLdapProviderUrl();
	String domain = ExpAppProperties.getLdapProviderDomain();
	
	String userName = request.getParameter("username");
	String credentials = request.getParameter("password");
	String valid = ExpAppProperties.getServerValidationSuccess();
	Hashtable env = new Hashtable();
	try {
		//---(set the name of domain with the user name)---
		String fullName = userName + "@" + domain;
		env.put(Context.INITIAL_CONTEXT_FACTORY,
			"com.sun.jndi.ldap.LdapCtxFactory");
		env.put(Context.PROVIDER_URL, providerUrl);
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
		//---(set user related information)---
		env.put(Context.SECURITY_PRINCIPAL, fullName);
		//---(set user password)---
		env.put(Context.SECURITY_CREDENTIALS, credentials);
		//---(validate user)---
		Context ctx = new InitialDirContext(env);
		out.print(valid);
		out.flush();
	} catch (AuthenticationException ex) {
		String errorMsg = "(ldapNetworkUserValidator.jsp) " + 
			"LDAP Authentication Exception is: ";
		String tempString;
		boolean found = false;
		StringTokenizer tokenizerTemp = new StringTokenizer(ex.toString());
		while (tokenizerTemp.hasMoreElements()) {
			tempString = tokenizerTemp.nextToken();
			if (tempString.equalsIgnoreCase("AcceptSecurityContext")) {
				while (tokenizerTemp.hasMoreElements()) {
					tempString = tokenizerTemp.nextToken();
					if (tempString.startsWith("525")) {
						errorMsg += "525 - user not found ";
						found = true;
					} else if (tempString.startsWith("52e")) {
						errorMsg += "52e - invalid password ";
						found = true;
					} else if (tempString.startsWith("530")) {
						errorMsg += "530 - not permitted to logon at this time ";
						found = true;
					} else if (tempString.startsWith("531")) {
						errorMsg += "531 - not permitted to logon at this workstation"; 
						found = true;
					} else if (tempString.startsWith("532")) {
						errorMsg += "532 - password expired";
						found = true;
					} else if (tempString.startsWith("533")) {
						errorMsg += "533 - account disabled";
						found = true;
					} else if (tempString.startsWith("701")) {
						errorMsg += "701 - account expired";
						found = true;
					} else if (tempString.startsWith("773")) {
						errorMsg += "773 - user must reset password";
						found = true;
					} else if (tempString.startsWith("775")) {
						errorMsg += "775 - user account locked";
						found = true;
					}
				}
			}
		}
		if (found) { //---( Error is one of the above )---
			out.print(errorMsg);
		} else {	//---( Error is NOT in the list )---
			out.print(errorMsg + ex );
		}
		out.flush();
	} catch (NamingException ex) {
		out.print("(ldapNetworkUserValidator.jsp) " + 
			"LDAP Naming Exception is: " + ex);
		out.flush();
	}
 
]]>
</jsp:scriptlet>
</jsp:root>

Open in new window


Hmm we won't be able to limit registration of those addresses if they're bound to single interface. It shouldn't cause a significant problem with the operation of the domain, and you should find you can bind with each of them.

If there are concerns about it you might run DCDiag and see if it has any problems.

If server-less binding works you might consider creating a connection to RootDSE and dynamically getting directory information. Unfortunately Java really isn't my forte, in essence you would connect with a URL like this:

String rootDSEURL = "ldap://RootDSE"

From there the following properties may be useful:

defaultNamingContext - Gets you "dc=intra,dc=s4isystems,dc=com" dynamically
rootDomainNamingContext - Gets you the forest root domain, useful for Global Catalog based searches

In addition to that, there's a COMObject called ADSystemInfo on each PC that's able to tell you a number of things about AD from the PC without having to know anything about the domain. See the following for a reference:

http://msdn.microsoft.com/en-us/library/aa705962(VS.85).aspx

I tend to make a lot of use of that for client-side scripting. I assume it can be used from Java, somehow... but I wouldn't be able to say how unfortunately.

Chris
Avatar of sol400

ASKER

Hi,
It didn't work out of the box.  I received the following message when I attempted to validate:
javax.naming.CommunicationException: dc=intra,dc=s4isystems,dc=com:389 [Root exception is java.net.UnknownHostException: dc=intra,dc=s4isystems,dc=com]

I made the folloowing changes:
1. Removed the following entries from the intra.s4isystems.com zone in the DNS:
Name      Type      Data
(same as parent folder)      Host (A)      10.47.55.30
(same as parent folder)      Host (A)      10.47.55.110
(same as parent folder)      Host (A)      10.47.55.112
(same as parent folder)      Host (A)      10.47.55.113

2. Added the following PTR records to the 55.47.10.in-addr.arpa zone:
110      Pointer (PTR)      s4isvr03.intra.s4issystems.com
112      Pointer (PTR)      s4isvr03.intra.s4isystems.com
113      Pointer (PTR)      s4isvr03.intra.s4isystems.com

3. Ran the nslookup again:
C:\>nslookup -q=srv _ldap._tcp.intra.s4isystems.com
Server:  s4isvr03.intra.s4isystems.com
Address:  10.47.55.112
_ldap._tcp.intra.s4isystems.com SRV service location:
          priority       = 0
          weight         = 100
          port           = 389
          svr hostname   = s4isvr03.intra.s4isystems.com
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.112
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.110
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.113
s4isvr03.intra.s4isystems.com   internet address = 10.47.55.30

4. Tried to login to my application again using the following parameters:
serverValidationExit=http://localhost:8080/wv31/Login/ldapNetworkUserValidator.jsp
ldapProviderUrl=ldap://dc=intra,dc=s4isystems,dc=com
ldapProviderDomain=intra.s4isystems.com
serverValidationSuccess=<networkuser>valid</networkuser>

5. I still received the following message:
javax.naming.CommunicationException: dc=intra,dc=s4isystems,dc=com:389 [Root exception is java.net.UnknownHostException: dc=intra,dc=s4isystems,dc=com]

6. I think I still need some way to get the host IP or name.


ASKER CERTIFIED SOLUTION
Avatar of Chris Dent
Chris Dent
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of sol400

ASKER

Your last suggestion worked... Great for us.  I am still having a problem with a customer BUT will close this request Thanks,

Spencer