import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.event.*;
import javax.naming.ldap.*;
import java.util.Hashtable;
import java.io.*;
public class PSearch
{
static final String PERSISTENT_SEARCH_OID = "2.16.840.1.113730.3.4.3";
static final String QUIT_PROMPT =
"\nMonitoring changes. Enter a 'q' to quit: ";
public static void main(String[] args)
{
LdapContext rootContext;
EventDirContext eventContext;
if (args.length != 4)
{
System.err.println("\n Usage: java PSearch <host name>"
+"<login dn> <password> <search base>");
System.err.println("\n Example: java PSearch ldap://Acme.com:389 "
+" \"cn=Admin,o=Acme\" secret"
+"\n \"ou=Sales,o=Acme\"");
System.exit(0);
}
String hostURL = args[0];
String loginDN = args[1];
String password = args[2];
String searchBase = args[3];
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, hostURL);
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, loginDN);
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.BATCHSIZE, "1");
env.put("java.naming.ldap.derefAliases", "never");
try
{
rootContext = new InitialLdapContext(env, null);
if (!isPersistentSearchSupported(rootContext))
{
System.out.println(
"The LDAP Server does not support persistent search");
System.exit(1);
}
eventContext = (EventDirContext)rootContext.lookup(searchBase);
MyEventListener listener = new MyEventListener("listener_1");
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
eventContext.addNamingListener(
"",
"(objectClass=*)",
constraints,
listener);
BufferedReader in
= new BufferedReader(new InputStreamReader(System.in));
try
{
String input;
while (true)
{
System.out.print(QUIT_PROMPT);
input = in.readLine();
if ( input.startsWith("q") || input.startsWith("Q") )
break;
}
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
eventContext.removeNamingListener(listener);
eventContext.close();
}
catch (AuthenticationException e)
{
System.out.println(e.getMessage());
}
catch (NamingException e)
{
System.out.println(e.getMessage());
}
}
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);
searchControls.setReturningAttributes(attrNames);
searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
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;
}
static class MyEventListener implements NamespaceChangeListener,
ObjectChangeListener
{
private String id;
public MyEventListener(String id)
{
this.id = id;
}
public void objectAdded(NamingEvent evt)
{
System.out.println(
"\n\n" + id + ">>> object added event. Object Name: " +
evt.getNewBinding().getName());
System.out.print(QUIT_PROMPT);
}
public void objectRemoved(NamingEvent evt)
{
System.out.println(
"\n\n" + id + ">>> object removed event. Object Name: " +
evt.getOldBinding().getName());
System.out.print(QUIT_PROMPT);
}
public void objectRenamed(NamingEvent evt)
{
System.out.println(
"\n\n" + id + ">>> object renamed event. New name: " +
evt.getNewBinding().getName() +
" Old name: " + evt.getOldBinding().getName());
System.out.print(QUIT_PROMPT);
}
public void objectChanged(NamingEvent evt)
{
System.out.println(
"\n\n" + id + ">>> object changed event. Object name: " +
evt.getNewBinding().getName());
System.out.print(QUIT_PROMPT);
}
public void namingExceptionThrown(NamingExceptionEvent evt)
{
System.out.println(
"\n\n" + id + ">>> Listener received a naming exception");
evt.getException().printStackTrace();
System.out.print(QUIT_PROMPT);
}
}
}