blogger templates blogger widgets
This is part of a list of blog posts.
To browse the contents go to

LDAP Operation: Searching directory

The search functionality is like reverse lookup meaning, you can compose a query consisting of attributes of entries that you are seeking and submit that query to the directory. The directory then returns a list of entries that satisfy the query.

Basic Search

The simplest form of search requires that you specify the set of attributes that an entry must have and the name of the target context in which to perform the search.

try {
 //In the main() method of the program, create an initial directory context. 
 //This is similar to creating an initial context in the previous naming example, 
 //except that you use the constructor for InitialDirContext
 Hashtable env = new Hashtable();
 env.put(Context.INITIAL_CONTEXT_FACTORY,
  "com.sun.jndi.ldap.LdapCtxFactory");
 env.put(Context.PROVIDER_URL, "ldap://localhost:10389/o=csRepository");

 DirContext ctx = new InitialDirContext(env);
 
 // Specify the attributes to match
 // Ask for objects that has a surname ("sn") attribute with 
 // the value "Jacky" and the "mail" attribute
 Attributes matchAttrs = new BasicAttributes(true); // ignore attribute name case
 matchAttrs.put(new BasicAttribute("sn", "Jacky"));
 matchAttrs.put(new BasicAttribute("mail"));

 // Search for objects that have those matching attributes
 NamingEnumeration answer = ctx.search("ou=employees", matchAttrs);
 
 while (answer.hasMore()) {
  SearchResult sr = (SearchResult)answer.next();
  System.out.println("Name: " + sr.getName());
  System.out.println("Email: "+ sr.getAttributes().get("mail"));
  
 }
}catch(NamingException e){
 e.printStackTrace();
}

Output:
Name: cn=Jack Sparrow
Email: mail: jacksparrow@gmail.com


Search Filters

In addition to specifying a search using a set of attributes, you can specify a search in the form of a search filter. A search filter is a search query expressed in the form of a logical expression. The syntax of search filters accepted by DirContext.search() is described in RFC 2254.

try {
 //In the main() method of the program, create an initial directory context. 
 //This is similar to creating an initial context in the previous naming example, 
 //except that you use the constructor for InitialDirContext
 Hashtable env = new Hashtable();
 env.put(Context.INITIAL_CONTEXT_FACTORY,
  "com.sun.jndi.ldap.LdapCtxFactory");
 env.put(Context.PROVIDER_URL, "ldap://localhost:10389/o=csRepository");

 DirContext ctx = new InitialDirContext(env);
 
 // Create the default search controls
 SearchControls ctls = new SearchControls();

 // Specify the search filter to match
 // Ask for objects that have the attribute "sn" == "Jacky"
 // and the "mail" attribute
 String filter = "(&(sn=Jacky)(mail=*))";

 // Search for objects using the filter
 NamingEnumeration answer = ctx.search("ou=employees", filter, ctls);
 
 
 while (answer.hasMore()) {
  SearchResult sr = (SearchResult)answer.next();
  System.out.println("Name: " + sr.getName());
  System.out.println("Email: "+ sr.getAttributes().get("mail"));
  
 }
}catch(NamingException e){
 e.printStackTrace();
}

I get the same output as above.

Quick Overview of Search Filter Syntax

The search filter syntax is basically a logical expression in prefix notation (that is, the logical operator appears before its arguments). The following table lists the symbols used for creating filters.

Symbol
Description
&
conjunction (i.e., and -- all in list must be true)
|
disjunction (i.e., or -- one or more alternatives must be true)
!
negation (i.e., not -- the item being negated must not be true)
=
equality (according to the matching rule of the attribute)
~=
approximate equality (according to the matching rule of the attribute)
>=
greater than (according to the matching rule of the attribute)
<=
less than (according to the matching rule of the attribute)
=*
presence (i.e., the entry must have the attribute but its value is irrelevant)
*
wildcard (indicates zero or more characters can occur in that position); used when specifying attribute values to match
\
escape (for escaping '*', '(', or ')' when they occur inside an attribute value)

Returning Selected Attributes

The previous example returned all attributes associated with the entries that satisfy the specified filter. You can select the attributes to return by setting the search controls argument. You create an array of attribute identifiers that you want to include in the result and pass it to SearchControls.setReturningAttributes()
// Specify the ids of the attributes to return
String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
//The entry does not have a "golfhandicap" attribute, so it is not returned when you perform search but this does //not cause any exception


More about SearchControls

You can use SearchControl to control other aspects of the search too.
Following are the available controls:


  1. The attributes to return
  2. The scope in which the search is to occur
  3. The maximum number of entries to return
  4. The maximum number of milliseconds to wait
  5. Whether to return the Java object associated with the entry
  6. Whether JNDI links are dereferenced during the search

1. Specify attributes to return
// Specify the ids of the attributes to return
String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attrIDs);
//The entry does not have a "golfhandicap" attribute, so it is not returned when you perform search but this does //not cause any exception

2. Specify the scope

The default SearchControls specifies that the search is to be performed in the named context SearchControls.ONELEVEL_SCOPE. It searches only one level of the named context.

Symbol Description
& conjunction (i.e., and -- all in list must be true)
| disjunction (i.e., or -- one or more alternatives must be true)
! negation (i.e., not -- the item being negated must not be true)
= equality (according to the matching rule of the attribute)
~= approximate equality (according to the matching rule of the attribute)
>= greater than (according to the matching rule of the attribute)
<= less than (according to the matching rule of the attribute)
=* presence (i.e., the entry must have the attribute but its value is irrelevant)
* wildcard (indicates zero or more characters can occur in that position); used when specifying attribute values to match
\ escape (for escaping '*', '(', or ')' when they occur inside an attribute value)


o=myserver.com; Scope= SUBTREE_SCOPE

ou=people, o=myserver.com; Scope= ONELEVEL_SCOPE

uid=styagi,ou=people,o=myserver.com; Scope=OBJECT_SCOPE

try {
 //In the main() method of the program, create an initial directory context. 
 //This is similar to creating an initial context in the previous naming example, 
 //except that you use the constructor for InitialDirContext
 Hashtable env = new Hashtable();
 env.put(Context.INITIAL_CONTEXT_FACTORY,
   "com.sun.jndi.ldap.LdapCtxFactory");
  env.put(Context.PROVIDER_URL, "ldap://localhost:10389/o=csRepository");

 DirContext ctx = new InitialDirContext(env);
  
 // Specify the ids of the attributes to return
 String[] attrIDs = {"sn", "telephonenumber", "golfhandicap", "mail"};
 SearchControls ctls = new SearchControls();
 ctls.setReturningAttributes(attrIDs);
 ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

 // Specify the search filter to match
 // Ask for objects that have the attribute "sn" == "Jacky"
 // and the "mail" attribute
 String filter = "(&(sn=Jacky)(mail=*))";

 // Search the subtree for objects by using the filter
 NamingEnumeration answer = ctx.search("", filter, ctls);
  
  
 while (answer.hasMore()) {
     SearchResult sr = (SearchResult)answer.next();
   System.out.println("Name: " + sr.getName());
   System.out.println("Email: "+ sr.getAttributes().get("mail"));
   
  }
}catch(NamingException e){
 e.printStackTrace();
}


3. Count Limit

Sometimes, a query might produce too many answers and you want to limit the number of answers returned. You can do this by using the count limit search control.
// Set the search controls to limit the count to 1
SearchControls ctls = new SearchControls();
ctls.setCountLimit(1);

4. Time Limit
A time limit on a search places an upper bound on the amount of time that the search operation will block waiting for the answers. This is useful when you don't want to wait too long for an answer.
// Set the search controls to limit the time to 1 second (1000 ms)
SearchControls ctls = new SearchControls();
ctls.setTimeLimit(1000);

Continue reading: LDAP Operations

No comments:

Post a Comment