go to  ForumEasy.com   
LdapPro  
 
 
   Home  |  MyForum  |  FAQ  |  Archive    You are not logged in. [Login] or [Register]  
Forum Home » LDAP Operations & Controls » LDAP Persistent Search Control -- JNDI Client for AD
Email To Friend  |   Set Alert To This Topic Rewarding Points Availabe: 0 (What's this) New Topic  |   Post Reply
Author Topic: LDAP Persistent Search Control -- JNDI Client for AD
SteveHB
member
offline   
 
posts: 113
joined: 05/31/2006
from: Mountain View, CA
  posted on: 03/13/2007 02:07:35 PM    Edit  |   Quote  |   Report 
LDAP Persistent Search Control -- JNDI Client for AD
The smart guys in Microsoft support Persistent Search Control in a clever way using OID "1.2.840.113556.1.4.528" instead of the standard OID "2.16.840.1.113730.3.4.3". Definitely, they have a name for it: NotifyControl.

/**
 *  A code example of Persistent Search Control JNDI Client for AD
 *  Note: This example has been tested to work with Active Directory 2003
 */
import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.event.*;
import javax.naming.ldap.*;

import java.util.Hashtable;
import java.io.*;

public class PersistentSearchControlJndiClientAD 
{
     
  // no longer "2.16.840.1.113730.3.4.3"
  static final String PERSISTENT_SEARCH_OID = "1.2.840.113556.1.4.528";
  
  public static void main(String[] args)
  {
    LdapContext   rootContext;

    //create initial context
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://myserevr.mycompany.com:389");
    env.put(Context.SECURITY_AUTHENTICATION, "simple");
    env.put(Context.SECURITY_PRINCIPAL, "mytest@mydomain.com");
    env.put(Context.SECURITY_CREDENTIALS, "mypassword");
    env.put(Context.BATCHSIZE, "1");  //return each change as it occurs
    env.put("java.naming.ldap.derefAliases", "never");
    
    try {
      // Create the initial directory context
      rootContext = new InitialLdapContext(env, null);
    
      // verify that persistent search is supported, exit if not supported
      if (!isPersistentSearchSupported(rootContext)){
        System.out.println(
            "The LDAP Server does not support persistent search");
        System.exit(1);
      }

      // Set up the search constraints
      SearchControls constraints = new SearchControls();
      constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
      constraints.setTimeLimit(0);
  
      //Request the LDAP Persistent Search control
      Control[] rqstCtls = new Control[]{new NotifyControl()};
      rootContext.setRequestControls(rqstCtls);

      //Specify the base for the search
      String searchBase = "dc=mydomain,dc=com";
      
      //For persistent search can only use objectClass=*
      String searchFilter = "(objectClass=*)";
 
      //Now perform the search
      NamingEnumeration answer = 
            rootContext.search(searchBase,searchFilter,constraints);
      SearchResult sr;
      Attributes attrs;
      
      //Continue waiting for changes....forever
      while(true) {
        System.out.println("Waiting for changes..., press Ctrl C to exit");
 
         sr = (SearchResult)answer.next();
            System.out.println(">>>" + sr.getName());
 
        //Print out the modified attributes
        //instanceType and objectGUID are always returned
        attrs = sr.getAttributes();
        if (attrs != null) {
          try {
            for (NamingEnumeration ae = attrs.getAll();ae.hasMore();) 
            {
              Attribute attr = (Attribute)ae.next();
              System.out.println("Attribute: " + attr.getID());
              for (NamingEnumeration e = attr.getAll();e.hasMore();
                System.out.println("   " + e.next().toString()));
            }
          } 
          catch (NullPointerException e)  {
            System.err.println("Problem listing attributes: " + e);
          }
        }
      }
    }
    catch (NamingException e) 
    {
      System.err.println("Problem searching directory: " + e);
    } 
    catch (Exception e) 
    {
      System.err.println("Problem searching directory: " + e);
    }
  }

  /**
   * isPersistentSearchSupported
   *
   * Query the rootDSE to find out if the persistent search control
   * is supported.
   */
  static boolean isPersistentSearchSupported(
    LdapContext   rootContext) throws NamingException
  {
    SearchResult     rootDSE;
    NamingEnumeration  searchResults;
    Attributes       attrs;
    NamingEnumeration  attrEnum;
    Attribute      attr;
    NamingEnumeration  values;
    String         value;
    String[]       attrNames = {"supportedControl"};
    SearchControls     searchControls = new SearchControls();

    searchControls.setCountLimit(0);  //0 means no limit
    searchControls.setReturningAttributes(attrNames);
    searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);

    // search for the rootDSE object
    searchResults =
      rootContext.search("", "(objectClass=*)", searchControls);

    while (searchResults.hasMore())
    {
      rootDSE = (SearchResult)searchResults.next();

      attrs = rootDSE.getAttributes();
      attrEnum = attrs.getAll();
      while (attrEnum.hasMore())
      {
        attr = (Attribute)attrEnum.next();
        values = attr.getAll();
        while (values.hasMore())
        {
          value = (String) values.next();
          if (value.equals(PERSISTENT_SEARCH_OID))
            return true;
        }
      }
    }
    return false;
  }
} 

class DeletedControl implements Control {

  public byte[] getEncodedValue() {
    return new byte[] {};
  }

  public String getID() {
    return "1.2.840.113556.1.4.417";
  }

  public boolean isCritical() {
    return true;
  }

}

class NotifyControl implements Control {

  public byte[] getEncodedValue() {
          return new byte[] {};
  }

  public String getID() {
    return "1.2.840.113556.1.4.528";
  }

  public boolean isCritical() {
    return true;
  }
}

 Profile | Reply Points Earned: 0
mhmldappro
member
offline   
 
posts: 2
joined: 10/15/2007
from: SAO PAULO, SAO PAULO
Brazil
  posted on: 10/18/2007 10:04:19 AM    Edit  |   Quote  |   Report 
LDAP Persistent Search Control -- JNDI Client for AD
How can I know what change was made in each object ?

MHM
 Profile | Reply Points Earned: 0
SteveHB
member
offline   
 
posts: 113
joined: 05/31/2006
from: Mountain View, CA
  posted on: 10/19/2007 07:43:43 PM    Edit  |   Quote  |   Report 
Hi MHM,

From each response you received from server, you should have inside a changed entry and an Entry Change Notification control:
	entryChangeNotificationControlValue::= SEQUENCE {
              changeType ENUMERATED {
                      add             (1),
                      delete          (2),
                      modify          (4),
                      modDN           (8)
              },
              previousDN   LDAPDN OPTIONAL,     -- modifyDN ops. only
              changeNumber INTEGER OPTIONAL     -- if supported
	}


which tells what had happened as to the changed entry.

For add, delete or modDN, it's quite straight forward to know what change was made.

For modify, however, you have to compare the changed entry with the old one to figure out the difference.

Regards,
Steve

 Profile | Reply Points Earned: 0
mhmldappro
member
offline   
 
posts: 2
joined: 10/15/2007
from: SAO PAULO, SAO PAULO
Brazil
  posted on: 10/23/2007 08:48:59 AM    Edit  |   Quote  |   Report 
Hi Steve

When I call the getResponseControls() (after the research) no one control its returned.

Do you know why ?

Thanks

MHM
 Profile | Reply Points Earned: 0

 
Powered by ForumEasy © 2003-2005, All Rights Reserved. | Privacy Policy | Terms of Use
 
Get your own forum today. It's easy and free.