Question

I'm trying to run:

    Map<String, String> environmentProperties = new HashMap<String, String>();
    environmentProperties.put("java.naming.security.authentication", "simple");
    environmentProperties.put("java.naming.ldap.attributes.binary", "tokenGroups objectSid");

    LdapContextSource contextSource = new LdapContextSource();
    contextSource.setAnonymousReadOnly(false);
    contextSource.setPooled(false);

    contextSource.setUserDn("CN=Administrator,CN=Users,DC=someDomain,DC=com");
    contextSource.setPassword("password");

    contextSource.setUrls(new String[]{"ldap://url.goes.here"});
    contextSource.setBaseEnvironmentProperties(environmentProperties);
    contextSource.setDirObjectFactory(null);
    contextSource.afterPropertiesSet();

    final SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    ContextExecutor contextExecutor = new ContextExecutor() {
       public Object executeWithContext(DirContext ctx) throws NamingException {
          EventDirContext ectx = (EventDirContext) ctx.lookup("CN=Users,,DC=someDomain,DC=com");
          ectx.addNamingListener("", "(cn=*)", searchControls, new LDAPChangeListener());
          return null;
       }
    };


    LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
    ldapTemplate.setIgnorePartialResultException(true);

    ldapTemplate.executeReadOnly(contextExecutor);

but, the first message my listener gets is:

javax.naming.OperationNotSupportedException: [LDAP: error code 12 - 00000057: LdapErr: DSID-0C090753, comment: Error processing control, data 0, v1db1 ]; remaining name '' at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3127) at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:3013) at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2820) at com.sun.jndi.ldap.LdapNamingEnumeration.getNextBatch(LdapNamingEnumeration.java:129)

I also ran this code I found here that's supposed to verify that my AD supports persistent search, and the result was true.

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("1.2.840.113556.1.4.528"))
                    return true;
            }
        }
    }
    return false;
}

what do I need to do to start getting events from AD?

Was it helpful?

Solution 2

UPDATE: I found this: https://forums.oracle.com/thread/1157474?tstart=0 It basically says that AD does not support this, and that there’s no way I can make the above code work. However, it does give out 2 different ways of getting such notifications from AD:

  1. Using DirSync- I tried the attached code, and it did not work, but did not continue investigating from the reasons that will be listed in the end of this post.
  2. Using LDAP Notifications (https://forums.oracle.com/message/4698114 )- this code worked, however, it only returns results for created / changed events, it will not notify once an object gets deleted, and there’s no way of getting it with this method since the search filter cannot be changed, because any other filter will not work. So it did not fit my purposes, but maybe someone else finds it useful.

I thought DirSync might be the only solution possible for me, if any. However, it should be noted that DirSync has the following limitations:

  • The DirSync control can only be used by a highly privileged account, such as a domain administrator.
  • The DirSync control can only monitor an entire naming context. You cannot limit the scope of a DirSync search to monitor only a specific subtree, container, or object in a naming context.

I hope this information will help someone else in the future.

OTHER TIPS

According to the documentation, the scope can't be Subtree and the search filter must be (objectClass=*) for a persistent search.

I would like to add some additional information on this topic since I have done research on this topic couple years ago.

The NamingListener capability provided by JNDI. If you try to register a NamingListener on any LDAP server, that particularly server must support the 'Persistent Search' extension. The Persistent Search extension has always been in IETF draft stage therefore there's no official RFC# associate with it.

Not a lot of LDAP server support this extension. The last time I researched on this topic was 2008 and the LDAP servers that support persistent search extension were 389 Directory Server, Oracle Internet Directory (OID) and OpenDS (now known as OpenDJ).

http://www-archive.mozilla.org/directory/ietf-docs/draft-smith-psearch-ldap-01.txt

http://www.redhat.com/archives/fedora-directory-users/2008-May/msg00120.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top