random walk through fields of musings

Monday, December 15, 2008

searching UMOD with JNDI

For some of the support tools I've been writing for CTools (in JSP with JSTL) I need to authorize against a group in the LDAP interface to UMOD. JNDI is very complete, so it should have been an easy task, but searching to see if a given logged-in (via Cosign) user was in the requisite group wasn't working. I had some example code in Perl that a colleague had once sent out, and a 1-to-1 transcription into Java using JNDI didn't work. It turns out that the scope for searches in JNDI does not default to "SUB" AND if you try to bind (even anonymously) the query tries to ADD the attribute instead of searching for it, and so had to be explicitly set. To help you (and remind me) avoid this pain, here is the requisite code:


private boolean isMember(String grp, String un) throws Exception {
   boolean isMem = false;
   Hashtable env = new Hashtable();
   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
   env.put(Context.PROVIDER_URL, "ldap://ldap.itd.umich.edu:389/dc=umich,dc=edu");

   try {
     javax.naming.directory.DirContext ctx = new javax.naming.directory.InitialDirContext(env);
     String[] attrIDs = {"member"};

     javax.naming.directory.SearchControls ctls = new javax.naming.directory.SearchControls();
     String filter = "(&(cn=" + grp + ") (objectclass=rfc822MailGroup))";
     ctls.setReturningAttributes(attrIDs);
     ctls.setReturningObjFlag(true);
     ctls.setSearchScope(javax.naming.directory.SearchControls.SUBTREE_SCOPE);
     String searchBase = "ou=Groups";
     javax.naming.NamingEnumeration s = ctx.search(searchBase, filter, ctls);
     String positiveMatch = "uid=" + un + ",";
     while (s.hasMore()) {
     javax.naming.directory.SearchResult sr = (javax.naming.directory.SearchResult)s.next();
     javax.naming.NamingEnumeration e = (sr.getAttributes()).getAll();
     while (e.hasMoreElements()){
       javax.naming.directory.Attribute attr = (javax.naming.directory.Attribute) e.nextElement();
       javax.naming.NamingEnumeration a = attr.getAll();
       while (a.hasMoreElements()){
         String val = (String) a.nextElement();
         if(val.indexOf(positiveMatch) != -1){
           isMem = true;
         }
       }
       a.close();
     }
     e.close();
   }
   s.close();
   ctx.close();
   return isMem;
  } catch (javax.naming.NamingException e) {
    System.err.println("Problem getting attribute:" + e);
    return false;
  }
}


There must be a better way of formatting code in HTML without JS.