This lesson answers the frequently asked questions
users often have when using the JNDI to access LDAP services.
Some of the common problems are answered in the
Trouble Shooting Tips of the Naming and Directory Operations lesson.
Contexts:
- Is the context safe for multithreaded access?
- Why does the LDAP provider ignore my security environment properties?
- Why do I keep getting a CommunicationException?
- How can I get a trace of LDAP messages?
- How do I use a different authentication mechanism such as Kerberos?
- Should I enable ssl when changing the password?
Attributes:
- When I ask for one attribute, I get back another. Why?
- How do I know the type of an attribute's value?
- How do I get back an attribute's value in a form other than a String
or byte array?
- Why does putting an "*" as an attribute value not work as expected
in my search?
Searches:
- Why don't wildcards in search filters always work?
- Why do I get back only n number of entries when I know
there are more in the directory?
- How do I pass controls with my search?
- How do I find out how many search results I got back?
Names:
- Why do I get an empty string as a name in my SearchResult?
- Why do I get a URL string as a name in my SearchResult?
- What type is the Name argument passed to the context methods?
- Can I pass the name I got back from NameParser to the Context methods?
- What's the relationship between the name I use for the
Context.SECURITY_PRINCIPAL property and the directory?
- Why are there strange quotation marks and escapes in the names
that I read from the directory?
- How do I get an LDAP entry's full DN?
1. Is the context safe for multithreaded access,
or do I need to lock/synchronize access to a context?
The answer depends on the implementation.
This is because the
Context and
DirContext interfaces do not specify synchronization requirements.
Sun's LDAP implementation is optimized for single-threaded access.
If you have multiple threads accessing the same
Context instance, then each thread needs to
lock the Context instance when using it.
This also applies to any NamingEnumeration that is derived from the
same Context instance.
However, multiple threads can access different
Context instances
(even those derived from the same initial context) concurrently
without locks.
2. Why does the LDAP provider ignore my security environment properties
if I do not set the
Context.SECURITY_CREDENTIALS ("java.naming.security.credentials") property or set it to the empty string?
If you supply an empty string, an empty byte/char array, or null to the
Context.SECURITY_CREDENTIALS environment property,
then an anonymous bind will occur even if the
Context.SECURITY_AUTHENTICATION property
was set to "simple".
This is because for simple authentication,
the LDAP requires the password to be nonempty.
If a password is not supplied,
then the protocol automatically converts the authentication to "none".
3. Why do I keep getting a
CommunicationException when I try to create an initial context?
You might be talking to a server that supports only the LDAP v2.
See the Miscellaneous lesson of the
JNDI Tutorial for an example of how to set the version number.
4. How can I trace the LDAP message?
Try using the "com.sun.jndi.ldap.trace.ber" environment
property. If the value of this property is an instance of
java.io.OutputStream, then trace information about BER buffers
sent and received by the LDAP provider is written to that stream. If
the property's value is null, then no trace output is written.
For example, the following code will send the trace output to System.err.
env.put("com.sun.jndi.ldap.trace.ber", System.err);
5. How do I use a different authentication mechanism such as
Kerberos?
Follow the instructions in the GSS-API/Kerberos v5 Authentication
of the
JNDI Tutorial for information on how to use Kerberos authentication.
To use other authentication mechanisms, see the
Using Arbitrary SASL Mechanisms section of the
JNDI tutorial .
6. Should I enable SSL when changing the password?
/
It really depends on the directory server you are using. Some directory
servers won't allow you to change the password if SSL is not enabled but
some do allow it.
It's good to have SSL enabled to have your password secured in the
communication channel.
7. When I ask for one attribute, I get back another. Why?
The attribute name that you are using might be a synonym for another attribute.
In this case, the LDAP server might return the canonical attribute name instead
of the one that you supplied.
When you look in the Attributes returned by
the server, you need to use the canonical name instead
of the synonym.
For example, "fax" might be a synonym for the canonical
attribute name "facsimiletelephonenumber".
If you ask for "fax", the server will return the attribute
named "facsimiletelephonenumber".
See the
Naming and Directory Operations lesson for details on synonyms and other issues regarding
attribute names.
8. How do I know the type of an attribute's value?
An attribute's value can be either java.lang.String or byte[].
See the Miscellaneous section of the
JNDI Tutorial for information on which attributes' values are returned
as byte[].
To do this programmatically,
you can use the instanceof operator to examine
the attribute value that you get back from the LDAP provider.
9. How do I get back an attribute's value in a form
other than a String or byte array?
Currently you can't. The LDAP provider returns only attribute values
that are either java.lang.String or byte[].
See the Miscellaneous section of the
JNDI Tutorial .
10. Why does putting an "*" as an attribute value not work as expected
in my search?
When you use the following
form of search(), the attribute values are treated as literals; that is, the
attribute in the directory entry is expected to contain exactly that value:
search(Name name, Attributes matchingAttrs)
To use wildcards, you should use the string filter forms of
search(), as follows.
search(Name name, String filter, SearchControls ctls)
search(Name name, String filterExpr, Object[]filterArgs, SearchControls ctls)
For the last form, the wildcard characters must appear in the filterExpr
argument, and not in filterArgs.
The values in filterArgs are also treated as literals.
11. Why don't wildcards in search filters always work?
A wildcard that appears before or after the attribute value (such as
in "attr=*I*") indicates that the server is to search for matching
attribute values by using the attribute's substring matching rule. If
the attribute's definition does not have a substring matching rule,
then the server cannot find the attribute. You'll have to search
by using an equality or "present" filter instead.
12. Why do I get back only n number of entries when I know
there are more in the directory?
Some servers are configured to limit the number
of entries that can be returned. Others also limit the number
of entries that can be examined during a search.
Check your server configuration.
13. How do I pass controls with my search?
Controls are not explained in this tutorial.
Check out the
JNDI Tutorial .
14. How do I find out how many search results I got back?
You must keep count as you enumerate
through the results. The LDAP does not provide this information.
15. Why do I get an empty string as a name in my
SearchResult?
getName() always returns a name relative to the target context
of the search.
So, if the target context satisfies the search filter,
then the name returned will be "" (the empty name) because that is
the name relative to the target context.
See the
Search Results section for details.
16. Why do I get a URL string as a name in my
SearchResult?
The LDAP entry was retrieved by following either an alias or
a referral, so its name is a URL.
See the
Search Results lesson for details.
17. What type is the
Name argument passed to the
Context and
DirContext methods? - a
CompoundName or a
CompositeName?
The string forms accept the string representation of a composite name.
That is, using a string name is equivalent to calling
new CompositeName(stringName) and passing the results
to the Context/DirContext method.
The Name argument can be any object that implements the
Name interface.
If it is an instance of CompositeName,
then the name is treated as a composite name; otherwise, it is treated
as a compound name.
18. Can I pass the name I got back from
NameParser to
Context methods?
This is related to the previous question.
Yes, you can.
NameParser.parse() returns a compound name that implements the Name interface.
This name can be passed to the Context methods, which will
interpret it as a compound name.
19. What's the relationship between the name I use for the
Context.SECURITY_PRINCIPAL property and the directory?
You can think of the principal name
as coming from a different namespace than the directory.
See
RFC 2829
and the
Security section for details on LDAP authentication mechanisms.
Sun's LDAP service provider accepts a string principal name, which
it passes directly to the LDAP server.
Some LDAP servers accept DNs, whereas
others support the schemes proposed by
RFC 2829.
20. Why are there strange quotation marks and escapes in the names
that I read from the directory?
Sun's LDAP name parser is conservative with respect to quoting
rules,
but it nevertheless produces "correct" names.
Also, remember that the names of entries returned by
NamingEnumerations are
composite names
that can be passed back to the Context and DirContext
methods. So, if the name contains a character that conflicts with
the composite name syntax (such as the forward slash character "/"),
then the LDAP provider will provide an encoding to ensure that the
slash character will be treated as part of the LDAP name rather than as a composite
name separator.
Start using the
LdapName and
Rdn classes that enable easy name manipulation.
21. How do I get an LDAP entry's full DN?
You can use
NameClassPair.getNameInNamespace().