r4629 - trunk/src/edu/ucsb/nceas/metacat

daigle at ecoinformatics.org daigle at ecoinformatics.org
Tue Nov 25 10:50:46 PST 2008


Author: daigle
Date: 2008-11-25 10:50:45 -0800 (Tue, 25 Nov 2008)
New Revision: 4629

Modified:
   trunk/src/edu/ucsb/nceas/metacat/AuthLdap.java
Log:
Reformat file

Modified: trunk/src/edu/ucsb/nceas/metacat/AuthLdap.java
===================================================================
--- trunk/src/edu/ucsb/nceas/metacat/AuthLdap.java	2008-11-25 17:54:32 UTC (rev 4628)
+++ trunk/src/edu/ucsb/nceas/metacat/AuthLdap.java	2008-11-25 18:50:45 UTC (rev 4629)
@@ -62,29 +62,29 @@
 import java.util.Vector;
 
 /**
- * An implementation of the AuthInterface interface that
- * allows Metacat to use the LDAP protocol for directory services.
- * The LDAP authentication service is used to determine if a user
- * is authenticated, and whether they are a member of a particular group.
+ * An implementation of the AuthInterface interface that allows Metacat to use
+ * the LDAP protocol for directory services. The LDAP authentication service is
+ * used to determine if a user is authenticated, and whether they are a member
+ * of a particular group.
  */
 public class AuthLdap implements AuthInterface {
-  private String ldapUrl;
-  private String ldapsUrl;
-  private String ldapBase;
-  private String referral;
-  private String ldapConnectTimeLimit;
-  private int ldapSearchTimeLimit;
-  private int ldapSearchCountLimit;
-  private String currentReferralInfo;
-  Hashtable env = new Hashtable(11);
-  private Context rContext;
-  private String userName;
-  private String userPassword;
-  ReferralException refExc;
+	private String ldapUrl;
+	private String ldapsUrl;
+	private String ldapBase;
+	private String referral;
+	private String ldapConnectTimeLimit;
+	private int ldapSearchTimeLimit;
+	private int ldapSearchCountLimit;
+	private String currentReferralInfo;
+	Hashtable env = new Hashtable(11);
+	private Context rContext;
+	private String userName;
+	private String userPassword;
+	ReferralException refExc;
 
-  private static Logger logMetacat = Logger.getLogger(AuthLdap.class);
-  
-    /**
+	private static Logger logMetacat = Logger.getLogger(AuthLdap.class);
+
+	/**
 	 * Construct an AuthLdap
 	 */
 	public AuthLdap() throws InstantiationException {
@@ -92,7 +92,7 @@
 		try {
 			this.ldapUrl = PropertyService.getProperty("auth.url");
 			this.ldapsUrl = PropertyService.getProperty("auth.surl");
-			// use the NCEAS base as a fallback.  Normally, the base will be
+			// use the NCEAS base as a fallback. Normally, the base will be
 			// parsed from the user during authentication
 			// TODO MCD this may need to remain always at NCEAS value
 			this.ldapBase = PropertyService.getProperty("organization.base.NCEAS");
@@ -117,7 +117,7 @@
 		this.currentReferralInfo = "";
 	}
 
-  /**
+	/**
 	 * Determine if a user/password are valid according to the authentication
 	 * service.
 	 * 
@@ -127,1133 +127,1130 @@
 	 *            the password to use for authentication
 	 * @returns boolean true if authentication successful, false otherwise
 	 */
-  
-  public boolean authenticate(String user, String password) throws ConnectException {
-    String ldapUrl = this.ldapUrl;
-    String ldapsUrl = this.ldapsUrl;
-    String ldapBase = this.ldapBase;
-    boolean authenticated = false;
-    String identifier = user;
-    
-    //get uid here.
-    if (user.indexOf(",") == -1) {
-    	throw new ConnectException("Invalid LDAP user credential: " + user + ".  Missing ','");
-    }
-    String uid=user.substring(0, user.indexOf(","));
-    user = user.substring(user.indexOf(","), user.length());
 
-    logMetacat.debug("identifier: " + identifier);
-    logMetacat.debug("uid: " + uid);
-    logMetacat.debug("user: " + user);
-    
-    try {
-    	// Check the usename as passed in
-        logMetacat.info("Calling ldapAuthenticate");
-        logMetacat.info("with user as identifier: " + identifier);
+	public boolean authenticate(String user, String password) throws ConnectException {
+		String ldapUrl = this.ldapUrl;
+		String ldapsUrl = this.ldapsUrl;
+		String ldapBase = this.ldapBase;
+		boolean authenticated = false;
+		String identifier = user;
 
-        authenticated = ldapAuthenticate(identifier, password, 
-        		(new Boolean(PropertyService.getProperty("ldap.onlySecureConnection"))).booleanValue());
-        // if not found, try looking up a valid DN then auth again
-        if (!authenticated) {
-        	logMetacat.info("Not Authenticated");
-        	logMetacat.info("Looking up DN for: " + identifier);
-        	identifier = getIdentifyingName(identifier, ldapUrl, ldapBase);
-        	if(identifier == null){
-        		logMetacat.info("No DN found from getIdentifyingName");
-        		return authenticated;
-        	}
-        	
-           	logMetacat.info("DN found from getIdentifyingName: " + identifier);
-        	String decoded = URLDecoder.decode(identifier);
-        	logMetacat.info("DN decoded: " + decoded);
-        	identifier = decoded;
-        	String refUrl = "";
-        	String refBase = "";
-        	if (identifier.startsWith("ldap")) {
-        		logMetacat.debug("identifier starts with \"ldap\"");
+		// get uid here.
+		if (user.indexOf(",") == -1) {
+			throw new ConnectException("Invalid LDAP user credential: " + user
+					+ ".  Missing ','");
+		}
+		String uid = user.substring(0, user.indexOf(","));
+		user = user.substring(user.indexOf(","), user.length());
 
-        		refUrl = identifier.substring(0, identifier.lastIndexOf("/") + 1);
-        		int position = identifier.indexOf(",");
-        		int position2 = identifier.indexOf(",", position + 1);
-        		
-        		refBase = identifier.substring(position2 + 1);
-        		identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
-        		
-        		logMetacat.info("Calling ldapAuthenticate:");
-        		logMetacat.info("with user as identifier: " + identifier);
-        		logMetacat.info("and refUrl as: " + refUrl);
-        		logMetacat.info("and refBase as: " + refBase);
+		logMetacat.debug("identifier: " + identifier);
+		logMetacat.debug("uid: " + uid);
+		logMetacat.debug("user: " + user);
 
-        		authenticated = ldapAuthenticate(identifier, password, refUrl, refBase,
-                		(new Boolean(PropertyService.getProperty("ldap.onlySecureReferalsConnection")))
-                			.booleanValue());
-        	} else {
-        		logMetacat.info("identifier doesnt start with ldap");
-        		identifier = identifier + "," + ldapBase;
-        		
-        		logMetacat.info("Calling ldapAuthenticate");
-        		logMetacat.info("with user as identifier: " + identifier);
-        		
-        		authenticated = ldapAuthenticate(identifier, password,
-            		(new Boolean(PropertyService.getProperty("ldap.onlySecureConnection"))).booleanValue());
-        	}
-        }
-    } catch (NullPointerException e) {
-    	logMetacat.error("NullPointerException while authenticating in " +
-                        "AuthLdap.authenticate: " + e);
-    	e.printStackTrace();
+		try {
+			// Check the usename as passed in
+			logMetacat.info("Calling ldapAuthenticate");
+			logMetacat.info("with user as identifier: " + identifier);
 
-    	throw new ConnectException(
-          "NullPointerException while authenticating in " +
-          "AuthLdap.authenticate: " + e);
-    } catch (NamingException e) {
-    	logMetacat.error("Naming exception while authenticating in " +
-                        "AuthLdap.authenticate: " + e);
-    	e.printStackTrace();
-    } catch (Exception e) {
-    	logMetacat.error(e.getMessage());
-    }
-    
-    return authenticated;
-  }
+			authenticated = ldapAuthenticate(identifier, password, (new Boolean(
+					PropertyService.getProperty("ldap.onlySecureConnection")))
+					.booleanValue());
+			// if not found, try looking up a valid DN then auth again
+			if (!authenticated) {
+				logMetacat.info("Not Authenticated");
+				logMetacat.info("Looking up DN for: " + identifier);
+				identifier = getIdentifyingName(identifier, ldapUrl, ldapBase);
+				if (identifier == null) {
+					logMetacat.info("No DN found from getIdentifyingName");
+					return authenticated;
+				}
 
-  /**
-   * Connect to the LDAP directory and do the authentication using the
-   * username and password as passed into the routine.
-   *
-   * @param identifier the distinguished name to check against LDAP
-   * @param password the password for authentication
-   */
-  private boolean ldapAuthenticate(String identifier, String password, boolean 
-    secureConnectionOnly) throws ConnectException, NamingException, 
-    NullPointerException {
-    return ldapAuthenticate(identifier, password,
-                            this.ldapsUrl, this.ldapBase, secureConnectionOnly);
-  }
+				logMetacat.info("DN found from getIdentifyingName: " + identifier);
+				String decoded = URLDecoder.decode(identifier);
+				logMetacat.info("DN decoded: " + decoded);
+				identifier = decoded;
+				String refUrl = "";
+				String refBase = "";
+				if (identifier.startsWith("ldap")) {
+					logMetacat.debug("identifier starts with \"ldap\"");
 
-  /**
-   * Connect to the LDAP directory and do the authentication using the
-   * username and password as passed into the routine.
-   *
-   * @param identifier the distinguished name to check against LDAP
-   * @param password the password for authentication
-   */
-  
-  private boolean ldapAuthenticate(String dn, String password, 
-    String rootServer, String rootBase, boolean secureConnectionOnly){
-	  
-	  boolean authenticated = false;
-		
-	  String server = "";
-	  String userDN = "";
-	  logMetacat.info("dn is: " + dn);
+					refUrl = identifier.substring(0, identifier.lastIndexOf("/") + 1);
+					int position = identifier.indexOf(",");
+					int position2 = identifier.indexOf(",", position + 1);
 
-	  int position = dn.lastIndexOf("/");
-      logMetacat.debug("position is: " + position);
-	  if (position == -1) {
-		  server = rootServer;
-		  if(dn.indexOf(userDN) < 0){
-			  userDN = dn + "," + rootBase;
-		  } else {
-			  userDN = dn;
-		  }
-		  logMetacat.info("userDN is: " + userDN);
+					refBase = identifier.substring(position2 + 1);
+					identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
 
-       } else {
-		  server = dn.substring(0, position+1);
-		  userDN = dn.substring(position+1);
-		  logMetacat.info("server is: " + server);
-		  logMetacat.info("userDN is: " + userDN);
-	   }
-		          
-	   logMetacat.warn("Trying to authenticate: " + userDN);
-	   logMetacat.warn("          Using server: " + server);
-		          
-	   LdapContext ctx = null;
-	   double startTime;
-	   double stopTime;
-	   try 
-     {
-		   Hashtable env = new Hashtable();
-		   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
-		   env.put(Context.PROVIDER_URL, server);
-		   env.put(Context.REFERRAL, "throw");
-		   try 
-       {
-			   
-			   startTime = System.currentTimeMillis();
-			   ctx = new InitialLdapContext(env, null);
-			   // Start up TLS here so that we don't pass our jewels in cleartext
-		       StartTlsResponse tls =
-		              (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
-		       //tls.setHostnameVerifier(new SampleVerifier());
-		       SSLSession sess = tls.negotiate();
-		       ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
-			   ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
-			   ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
-			   ctx.reconnect(null);
-			   stopTime = System.currentTimeMillis();
-			   logMetacat.info("Connection time thru " + ldapsUrl + " was: " +
-                       	(stopTime - startTime) / 1000 + " seconds.");
-			   authenticated = true;
-		   } 
-       catch (Exception ioe) 
-       {
-			   logMetacat.info("Caught IOException in login while negotiating TLS: "
-	                                 + ioe.getMessage());
-			   
-			   if(secureConnectionOnly)
-         {
-				   return authenticated;
-			   
-			   } 
-         else 
-         {
-				   logMetacat.info("Trying to authenticate without TLS");
-				   env.put(Context.SECURITY_AUTHENTICATION, "simple");
-				   env.put(Context.SECURITY_PRINCIPAL, userDN);
-				   env.put(Context.SECURITY_CREDENTIALS, password);
-				   
-				   startTime = System.currentTimeMillis();
-				   ctx = new InitialLdapContext(env, null);				
-				   stopTime = System.currentTimeMillis();
-				   logMetacat.info("Connection time thru " + ldapsUrl + " was: " +
-	                       	(stopTime - startTime) / 1000 + " seconds.");
-				   authenticated = true;
-			   }
-		   }
-	   } 
-     catch (AuthenticationException ae) 
-     {
-		   authenticated = false;
-	   } 
-     catch (javax.naming.InvalidNameException ine) 
-     {
-	        logMetacat.error("An invalid DN was provided!");
-	   } 
-     catch (NamingException e) 
-     {
-		   logMetacat.warn("Caught NamingException in login: " + e.getClass().getName());
-		   logMetacat.info(e.toString() + "  " + e.getRootCause());
-     }
+					logMetacat.info("Calling ldapAuthenticate:");
+					logMetacat.info("with user as identifier: " + identifier);
+					logMetacat.info("and refUrl as: " + refUrl);
+					logMetacat.info("and refBase as: " + refBase);
 
-       return authenticated;
-  }
+					authenticated = ldapAuthenticate(identifier, password, refUrl,
+							refBase, (new Boolean(PropertyService
+									.getProperty("ldap.onlySecureReferalsConnection")))
+									.booleanValue());
+				} else {
+					logMetacat.info("identifier doesnt start with ldap");
+					identifier = identifier + "," + ldapBase;
 
+					logMetacat.info("Calling ldapAuthenticate");
+					logMetacat.info("with user as identifier: " + identifier);
 
-  /**
-   * Get the identifying name for a given userid or name.  This is the name
-   * that is used in conjunction withthe LDAP BaseDN to create a
-   * distinguished name (dn) for the record
-   *
-   * @param user the user for which the identifying name is requested
-   * @returns String the identifying name for the user,
-   *          or null if not found
-   */
-  private String getIdentifyingName(String user, String ldapUrl, 
-    String ldapBase) throws NamingException {
-	  
-      String identifier = null;
-      Hashtable env = new Hashtable();
-      env.put(Context.INITIAL_CONTEXT_FACTORY,
-              "com.sun.jndi.ldap.LdapCtxFactory");
-      env.put(Context.REFERRAL, "throw");
-      env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
-      try {
-    	  int position = user.indexOf(",");
-          String uid = user.substring(user.indexOf("=") + 1, position);
-          logMetacat.info("uid is: " + uid);
-          String org = user.substring(user.indexOf("=", position + 1) + 1,
-                                        user.indexOf(",", position + 1));
-          logMetacat.info("org is: " + org);
-           
-          DirContext sctx = new InitialDirContext(env);
-          SearchControls ctls = new SearchControls();
-          ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
-          String filter = "(&(uid=" + uid + ")(o=" + org + "))";
-          logMetacat.warn("Searching for DNs with following filter: " + filter);
-          
-          for (boolean moreReferrals = true; moreReferrals;) {
-              try {
-                  // Perform the search
-                  NamingEnumeration answer = 
-                      sctx.search("", filter, ctls);
+					authenticated = ldapAuthenticate(identifier, password, (new Boolean(
+							PropertyService.getProperty("ldap.onlySecureConnection")))
+							.booleanValue());
+				}
+			}
+		} catch (NullPointerException e) {
+			logMetacat.error("NullPointerException while authenticating in "
+					+ "AuthLdap.authenticate: " + e);
+			e.printStackTrace();
 
-                  // Return the answer
-                  while (answer.hasMore()) {
-                      SearchResult sr = (SearchResult)answer.next();
-                      identifier = sr.getName();
-                      return identifier;
-                  }
-                  // The search completes with no more referrals
-                  moreReferrals = false;
-              } catch (ReferralException e) {
-            	  logMetacat.info("Got referral: " + e.getReferralInfo());
-            	  // Point to the new context from the referral
-                  if (moreReferrals) {
-                      sctx = (DirContext) e.getReferralContext();
-                  }
-              }
-          }
-      } catch (NamingException e) {
-    	     logMetacat.error("Naming exception while getting dn: " + e);
-    	      throw new NamingException(
-    	          "Naming exception in AuthLdap.getIdentifyingName: " + e);
-    	      }
-      return identifier;
-  }
-  
-  /**
-   * Get all users from the authentication service
-   *
-   * @param user the user for authenticating against the service
-   * @param password the password for authenticating against the service
-   * @returns string array of all of the user names
-   */
-  public String[][] getUsers(String user, String password) throws 
-    ConnectException {
-    String[][] users = null;
+			throw new ConnectException("NullPointerException while authenticating in "
+					+ "AuthLdap.authenticate: " + e);
+		} catch (NamingException e) {
+			logMetacat.error("Naming exception while authenticating in "
+					+ "AuthLdap.authenticate: " + e);
+			e.printStackTrace();
+		} catch (Exception e) {
+			logMetacat.error(e.getMessage());
+		}
 
-    // Identify service provider to use
-    Hashtable env = new Hashtable(11);
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    env.put(Context.REFERRAL, referral);
-    env.put(Context.PROVIDER_URL, ldapUrl);
-    env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
+		return authenticated;
+	}
 
-    try {
+	/**
+	 * Connect to the LDAP directory and do the authentication using the
+	 * username and password as passed into the routine.
+	 * 
+	 * @param identifier
+	 *            the distinguished name to check against LDAP
+	 * @param password
+	 *            the password for authentication
+	 */
+	private boolean ldapAuthenticate(String identifier, String password,
+			boolean secureConnectionOnly) throws ConnectException, NamingException,
+			NullPointerException {
+		return ldapAuthenticate(identifier, password, this.ldapsUrl, this.ldapBase,
+				secureConnectionOnly);
+	}
 
-      // Create the initial directory context
-      DirContext ctx = new InitialDirContext(env);
+	/**
+	 * Connect to the LDAP directory and do the authentication using the
+	 * username and password as passed into the routine.
+	 * 
+	 * @param identifier
+	 *            the distinguished name to check against LDAP
+	 * @param password
+	 *            the password for authentication
+	 */
 
-      // Specify the attributes to match.
-      // Users are objects that have the attribute objectclass=InetOrgPerson.
-      SearchControls ctls = new SearchControls();
-      String[] attrIDs = {
-          "dn", "cn", "o", "ou", "mail"};
-      ctls.setReturningAttributes(attrIDs);
-      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
-      ctls.setTimeLimit(ldapSearchTimeLimit);
-      //ctls.setCountLimit(1000);
-      String filter = "(objectClass=inetOrgPerson)";
-      NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
+	private boolean ldapAuthenticate(String dn, String password, String rootServer,
+			String rootBase, boolean secureConnectionOnly) {
 
-      // Store the users in a vector
-      Vector uvec = new Vector();
-      Vector uname = new Vector();
-      Vector uorg = new Vector();
-      Vector uou = new Vector();
-      Vector umail = new Vector();
-      Attributes tempAttr = null;
-      try {
-        while (namingEnum.hasMore()) {
-          SearchResult sr = (SearchResult) namingEnum.next();
-          tempAttr = sr.getAttributes();
+		boolean authenticated = false;
 
-          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
-            uname.add( (tempAttr.get("cn") + "").substring(4));
-          }
-          else {
-            uname.add(tempAttr.get("cn") + "");
-          }
+		String server = "";
+		String userDN = "";
+		logMetacat.info("dn is: " + dn);
 
-          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
-            uorg.add( (tempAttr.get("o") + "").substring(3));
-          }
-          else {
-            uorg.add(tempAttr.get("o") + "");
-          }
+		int position = dn.lastIndexOf("/");
+		logMetacat.debug("position is: " + position);
+		if (position == -1) {
+			server = rootServer;
+			if (dn.indexOf(userDN) < 0) {
+				userDN = dn + "," + rootBase;
+			} else {
+				userDN = dn;
+			}
+			logMetacat.info("userDN is: " + userDN);
 
-          if ( (tempAttr.get("ou") + "").startsWith("ou: ")) {
-            uou.add( (tempAttr.get("ou") + "").substring(4));
-          }
-          else {
-            uou.add(tempAttr.get("ou") + "");
-          }
+		} else {
+			server = dn.substring(0, position + 1);
+			userDN = dn.substring(position + 1);
+			logMetacat.info("server is: " + server);
+			logMetacat.info("userDN is: " + userDN);
+		}
 
-          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
-            umail.add( (tempAttr.get("mail") + "").substring(6));
-          }
-          else {
-            umail.add(tempAttr.get("mail") + "");
-          }
+		logMetacat.warn("Trying to authenticate: " + userDN);
+		logMetacat.warn("          Using server: " + server);
 
-          uvec.add(sr.getName() + "," + ldapBase);
-        }
-      }
-      catch (SizeLimitExceededException slee) {
-        logMetacat.error("LDAP Server size limit exceeded. " +
-                          "Returning incomplete record set.");
-      }
+		LdapContext ctx = null;
+		double startTime;
+		double stopTime;
+		try {
+			Hashtable env = new Hashtable();
+			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+			env.put(Context.PROVIDER_URL, server);
+			env.put(Context.REFERRAL, "throw");
+			try {
 
-      // initialize users[]; fill users[]
-      users = new String[uvec.size()][5];
-      for (int i = 0; i < uvec.size(); i++) {
-        users[i][0] = (String) uvec.elementAt(i);
-        users[i][1] = (String) uname.elementAt(i);
-        users[i][2] = (String) uorg.elementAt(i);
-        users[i][3] = (String) uorg.elementAt(i);
-        users[i][4] = (String) umail.elementAt(i);
-      }
+				startTime = System.currentTimeMillis();
+				ctx = new InitialLdapContext(env, null);
+				// Start up TLS here so that we don't pass our jewels in
+				// cleartext
+				StartTlsResponse tls = (StartTlsResponse) ctx
+						.extendedOperation(new StartTlsRequest());
+				// tls.setHostnameVerifier(new SampleVerifier());
+				SSLSession sess = tls.negotiate();
+				ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
+				ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
+				ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
+				ctx.reconnect(null);
+				stopTime = System.currentTimeMillis();
+				logMetacat.info("Connection time thru " + ldapsUrl + " was: "
+						+ (stopTime - startTime) / 1000 + " seconds.");
+				authenticated = true;
+			} catch (Exception ioe) {
+				logMetacat.info("Caught IOException in login while negotiating TLS: "
+						+ ioe.getMessage());
 
-      // Close the context when we're done
-      ctx.close();
+				if (secureConnectionOnly) {
+					return authenticated;
 
-    }
-    catch (NamingException e) {
-      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
-      //e.printStackTrace(System.err);
-     /* throw new ConnectException(
-          "Problem getting users in AuthLdap.getUsers:" + e);*/
-    }
+				} else {
+					logMetacat.info("Trying to authenticate without TLS");
+					env.put(Context.SECURITY_AUTHENTICATION, "simple");
+					env.put(Context.SECURITY_PRINCIPAL, userDN);
+					env.put(Context.SECURITY_CREDENTIALS, password);
 
-    return users;
-  }
+					startTime = System.currentTimeMillis();
+					ctx = new InitialLdapContext(env, null);
+					stopTime = System.currentTimeMillis();
+					logMetacat.info("Connection time thru " + ldapsUrl + " was: "
+							+ (stopTime - startTime) / 1000 + " seconds.");
+					authenticated = true;
+				}
+			}
+		} catch (AuthenticationException ae) {
+			authenticated = false;
+		} catch (javax.naming.InvalidNameException ine) {
+			logMetacat.error("An invalid DN was provided!");
+		} catch (NamingException e) {
+			logMetacat.warn("Caught NamingException in login: " + e.getClass().getName());
+			logMetacat.info(e.toString() + "  " + e.getRootCause());
+		}
 
-  
-  /**
-   * Get all users from the authentication service
-   *
-   * @param user the user for authenticating against the service
-   * @param password the password for authenticating against the service
-   * @returns string array of all of the user names
-   */
-  public String[] getUserInfo(String user, String password) throws 
-    ConnectException {
-    String[] userinfo = new String[3];
+		return authenticated;
+	}
 
-    // Identify service provider to use
-    Hashtable env = new Hashtable(11);
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    env.put(Context.REFERRAL, referral);
-    env.put(Context.PROVIDER_URL, ldapUrl);
+	/**
+	 * Get the identifying name for a given userid or name. This is the name
+	 * that is used in conjunction withthe LDAP BaseDN to create a distinguished
+	 * name (dn) for the record
+	 * 
+	 * @param user
+	 *            the user for which the identifying name is requested
+	 * @returns String the identifying name for the user, or null if not found
+	 */
+	private String getIdentifyingName(String user, String ldapUrl, String ldapBase)
+			throws NamingException {
 
-    try {
-      
-      // Create the initial directory context
-      DirContext ctx = new InitialDirContext(env);
-      // Specify the attributes to match.
-      // Users are objects that have the attribute objectclass=InetOrgPerson.
-      SearchControls ctls = new SearchControls();
-      String[] attrIDs = {
-          "cn", "o", "mail"};
-      ctls.setReturningAttributes(attrIDs);
-      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
-      //ctls.setCountLimit(1000);
-      // create the filter based on the uid
-      
-      String filter = null;
-      
-      if(user.indexOf("o=")>0){
-    	  String tempStr = user.substring(user.indexOf("o="));
-    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
-			+ ")(" + tempStr.substring(0, tempStr.indexOf(",")) 
-			+ "))";      
-      } else{
-    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
-			+ "))";          		  
-      }
-   	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
-		+ "))";          		  
+		String identifier = null;
+		Hashtable env = new Hashtable();
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, "throw");
+		env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
+		try {
+			int position = user.indexOf(",");
+			String uid = user.substring(user.indexOf("=") + 1, position);
+			logMetacat.info("uid is: " + uid);
+			String org = user.substring(user.indexOf("=", position + 1) + 1, user
+					.indexOf(",", position + 1));
+			logMetacat.info("org is: " + org);
 
-      NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
-      
-      Attributes tempAttr = null;
-      try {
-        while (namingEnum.hasMore()) {
-          SearchResult sr = (SearchResult) namingEnum.next();
-          tempAttr = sr.getAttributes();
+			DirContext sctx = new InitialDirContext(env);
+			SearchControls ctls = new SearchControls();
+			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+			String filter = "(&(uid=" + uid + ")(o=" + org + "))";
+			logMetacat.warn("Searching for DNs with following filter: " + filter);
 
-          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
-        	  userinfo[0] = (tempAttr.get("cn") + "").substring(4);
-          }
-          else {
-        	  userinfo[0] = (tempAttr.get("cn") + "");
-          }
+			for (boolean moreReferrals = true; moreReferrals;) {
+				try {
+					// Perform the search
+					NamingEnumeration answer = sctx.search("", filter, ctls);
 
-          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
-        	  userinfo[1] = (tempAttr.get("o") + "").substring(3);
-          }
-          else {
-        	  userinfo[1] = (tempAttr.get("o") + "");
-          }
+					// Return the answer
+					while (answer.hasMore()) {
+						SearchResult sr = (SearchResult) answer.next();
+						identifier = sr.getName();
+						return identifier;
+					}
+					// The search completes with no more referrals
+					moreReferrals = false;
+				} catch (ReferralException e) {
+					logMetacat.info("Got referral: " + e.getReferralInfo());
+					// Point to the new context from the referral
+					if (moreReferrals) {
+						sctx = (DirContext) e.getReferralContext();
+					}
+				}
+			}
+		} catch (NamingException e) {
+			logMetacat.error("Naming exception while getting dn: " + e);
+			throw new NamingException("Naming exception in AuthLdap.getIdentifyingName: "
+					+ e);
+		}
+		return identifier;
+	}
 
-          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
-        	  userinfo[2] =  (tempAttr.get("mail") + "").substring(6);
-          }
-          else {
-        	  userinfo[2] = (tempAttr.get("mail") + "");
-          }
-        }
-      }
-      catch (SizeLimitExceededException slee) {
-        logMetacat.error("LDAP Server size limit exceeded. " +
-                          "Returning incomplete record set.");
-      }
+	/**
+	 * Get all users from the authentication service
+	 * 
+	 * @param user
+	 *            the user for authenticating against the service
+	 * @param password
+	 *            the password for authenticating against the service
+	 * @returns string array of all of the user names
+	 */
+	public String[][] getUsers(String user, String password) throws ConnectException {
+		String[][] users = null;
 
-      // Close the context when we're done
-      ctx.close();
+		// Identify service provider to use
+		Hashtable env = new Hashtable(11);
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, referral);
+		env.put(Context.PROVIDER_URL, ldapUrl);
+		env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
 
-    }
-    catch (NamingException e) {
-      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
-      //e.printStackTrace(System.err);
-      throw new ConnectException(
-          "Problem getting users in AuthLdap.getUsers:" + e);
-    }
+		try {
 
-    return userinfo;
-  }
+			// Create the initial directory context
+			DirContext ctx = new InitialDirContext(env);
 
-  /**
-   * Get the users for a particular group from the authentication service
-   *
-   * @param user the user for authenticating against the service
-   * @param password the password for authenticating against the service
-   * @param group the group whose user list should be returned
-   * @returns string array of the user names belonging to the group
-   */
-  public String[] getUsers(String user, String password, String group) throws 
-    ConnectException {
-    String[] users = null;
+			// Specify the attributes to match.
+			// Users are objects that have the attribute
+			// objectclass=InetOrgPerson.
+			SearchControls ctls = new SearchControls();
+			String[] attrIDs = { "dn", "cn", "o", "ou", "mail" };
+			ctls.setReturningAttributes(attrIDs);
+			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+			ctls.setTimeLimit(ldapSearchTimeLimit);
+			// ctls.setCountLimit(1000);
+			String filter = "(objectClass=inetOrgPerson)";
+			NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
 
-    // Identify service provider to use
-    Hashtable env = new Hashtable(11);
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    env.put(Context.REFERRAL, referral);
-    env.put(Context.PROVIDER_URL, ldapUrl);
+			// Store the users in a vector
+			Vector uvec = new Vector();
+			Vector uname = new Vector();
+			Vector uorg = new Vector();
+			Vector uou = new Vector();
+			Vector umail = new Vector();
+			Attributes tempAttr = null;
+			try {
+				while (namingEnum.hasMore()) {
+					SearchResult sr = (SearchResult) namingEnum.next();
+					tempAttr = sr.getAttributes();
 
-    try {
+					if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
+						uname.add((tempAttr.get("cn") + "").substring(4));
+					} else {
+						uname.add(tempAttr.get("cn") + "");
+					}
 
-      // Create the initial directory context
-      DirContext ctx = new InitialDirContext(env);
+					if ((tempAttr.get("o") + "").startsWith("o: ")) {
+						uorg.add((tempAttr.get("o") + "").substring(3));
+					} else {
+						uorg.add(tempAttr.get("o") + "");
+					}
 
-      // Specify the ids of the attributes to return
-      String[] attrIDs = {
-          "uniqueMember"};
+					if ((tempAttr.get("ou") + "").startsWith("ou: ")) {
+						uou.add((tempAttr.get("ou") + "").substring(4));
+					} else {
+						uou.add(tempAttr.get("ou") + "");
+					}
 
-      Attributes answer = ctx.getAttributes(group, attrIDs);
+					if ((tempAttr.get("mail") + "").startsWith("mail: ")) {
+						umail.add((tempAttr.get("mail") + "").substring(6));
+					} else {
+						umail.add(tempAttr.get("mail") + "");
+					}
 
-      Vector uvec = new Vector();
-      try {
-        for (NamingEnumeration ae = answer.getAll(); ae.hasMore(); ) {
-          Attribute attr = (Attribute) ae.next();
-          for (NamingEnumeration e = attr.getAll();
-               e.hasMore();
-               uvec.add(e.next())
-               ) {
-            ;
-          }
-        }
-      }
-      catch (SizeLimitExceededException slee) {
-        logMetacat.error("LDAP Server size limit exceeded. " +
-                          "Returning incomplete record set.");
-      }
+					uvec.add(sr.getName() + "," + ldapBase);
+				}
+			} catch (SizeLimitExceededException slee) {
+				logMetacat.error("LDAP Server size limit exceeded. "
+						+ "Returning incomplete record set.");
+			}
 
-      // initialize users[]; fill users[]
-      users = new String[uvec.size()];
-      for (int i = 0; i < uvec.size(); i++) {
-        users[i] = (String) uvec.elementAt(i);
-      }
+			// initialize users[]; fill users[]
+			users = new String[uvec.size()][5];
+			for (int i = 0; i < uvec.size(); i++) {
+				users[i][0] = (String) uvec.elementAt(i);
+				users[i][1] = (String) uname.elementAt(i);
+				users[i][2] = (String) uorg.elementAt(i);
+				users[i][3] = (String) uorg.elementAt(i);
+				users[i][4] = (String) umail.elementAt(i);
+			}
 
-      // Close the context when we're done
-      ctx.close();
+			// Close the context when we're done
+			ctx.close();
 
-    }
-    catch (NamingException e) {
-      logMetacat.error("Problem getting users for a group in " +
-                        "AuthLdap.getUsers:" + e);
-      /*throw new ConnectException(
-          "Problem getting users for a group in AuthLdap.getUsers:" + e);*/
-    }
+		} catch (NamingException e) {
+			logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
+			// e.printStackTrace(System.err);
+			/*
+			 * throw new ConnectException( "Problem getting users in
+			 * AuthLdap.getUsers:" + e);
+			 */
+		}
 
-    return users;
-  }
+		return users;
+	}
 
-  /**
-   * Get all groups from the authentication service
-   *
-   * @param user the user for authenticating against the service
-   * @param password the password for authenticating against the service
-   * @returns string array of the group names
-   */
-  public String[][] getGroups(String user, String password) throws 
-    ConnectException {
-    return getGroups(user, password, null);
-  }
+	/**
+	 * Get all users from the authentication service
+	 * 
+	 * @param user
+	 *            the user for authenticating against the service
+	 * @param password
+	 *            the password for authenticating against the service
+	 * @returns string array of all of the user names
+	 */
+	public String[] getUserInfo(String user, String password) throws ConnectException {
+		String[] userinfo = new String[3];
 
-  /**
-   * Get the groups for a particular user from the authentication service
-   *
-   * @param user the user for authenticating against the service
-   * @param password the password for authenticating against the service
-   * @param foruser the user whose group list should be returned
-   * @returns string array of the group names
-   */
-  public String[][] getGroups(String user, String password, 
-    String foruser) throws ConnectException {
-    
-    logMetacat.debug("getGroups() called.");
-    
-    // create vectors to store group and dscription values returned from the
-    // ldap servers
-    Vector gvec = new Vector();
-    Vector desc = new Vector();
-    Attributes tempAttr = null;
-    Attributes rsrAttr = null;
-    
-    // DURING getGroups(), DO WE NOT BIND USING userName AND userPassword??
-    // NEED TO FIX THIS ...
-    userName = user;
-    userPassword = password;
-    // Identify service provider to use
-    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
-    env.put(Context.REFERRAL, "throw");
-    env.put(Context.PROVIDER_URL, ldapUrl);
-    env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
-    
-        
-    // Iterate through the referrals, handling NamingExceptions in the 
-    // outer catch statement, ReferralExceptions in the inner catch statement
-    try { // outer try
-       
-      // Create the initial directory context
-      DirContext ctx = new InitialDirContext(env);
-      
-      // Specify the attributes to match.
-      // Groups are objects with attribute objectclass=groupofuniquenames.
-      // and have attribute uniquemember: uid=foruser,ldapbase.
-      SearchControls ctls = new SearchControls();
-      // Specify the ids of the attributes to return
-      String[] attrIDs = {"cn", "o", "description"};
-      ctls.setReturningAttributes(attrIDs);
-      // set the ldap search scope
-      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
-      // set a 10 second time limit on searches to limit non-responding servers
-      ctls.setTimeLimit(ldapSearchTimeLimit);
-      // return at most 20000 entries
-      ctls.setCountLimit(ldapSearchCountLimit);
+		// Identify service provider to use
+		Hashtable env = new Hashtable(11);
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, referral);
+		env.put(Context.PROVIDER_URL, ldapUrl);
 
-      // build the ldap search filter that represents the "group" concept
-      String filter = null;
-      String gfilter = "(objectClass=groupOfUniqueNames)";
-      if (null == foruser) {
-        filter = gfilter;
-      } else {
-        filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
-      }
-      logMetacat.info("group filter is: " + filter);
-      
-      // now, search and iterate through the referrals
-      for (boolean moreReferrals = true; moreReferrals;) {  
-        try { // inner try
-      
-          NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
+		try {
 
-          // Print the groups
-          while (namingEnum.hasMore()) {
-            SearchResult sr = (SearchResult) namingEnum.next();
-            
-            tempAttr = sr.getAttributes();
+			// Create the initial directory context
+			DirContext ctx = new InitialDirContext(env);
+			// Specify the attributes to match.
+			// Users are objects that have the attribute
+			// objectclass=InetOrgPerson.
+			SearchControls ctls = new SearchControls();
+			String[] attrIDs = { "cn", "o", "mail" };
+			ctls.setReturningAttributes(attrIDs);
+			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+			// ctls.setCountLimit(1000);
+			// create the filter based on the uid
 
-            if ( (tempAttr.get("description") + "").startsWith("description: ")) {
-              desc.add( (tempAttr.get("description") + "").substring(13));
-            }
-            else {
-              desc.add(tempAttr.get("description") + "");
-            }
-            
-            // check for an absolute URL value or an answer value relative 
-            // to the target context  
-            if ( !sr.getName().startsWith("ldap") &&
-                  sr.isRelative()) {
-              logMetacat.debug("Search result entry is relative ...");
-              gvec.add(sr.getName() + "," + ldapBase);
-              logMetacat.info("group " + sr.getName() + "," +ldapBase + 
-              " added to the group vector"); 
-            } else {
-              logMetacat.debug("Search result entry is absolute ...");
-              
-              // search the top level directory for referral objects and match
-              // that of the search result's absolute URL.  This will let us
-              // rebuild the group name from the search result, referral point
-              // in the top directory tree, and ldapBase.
-              
-              // configure a new directory search first
-              Hashtable envHash = new Hashtable(11);
-              // Identify service provider to use
-              envHash.put(Context.INITIAL_CONTEXT_FACTORY, 
-                "com.sun.jndi.ldap.LdapCtxFactory");
-              envHash.put(Context.REFERRAL, "ignore");
-              envHash.put(Context.PROVIDER_URL, ldapUrl);
-              envHash.put("com.sun.jndi.ldap.connect.timeout", 
-                ldapConnectTimeLimit);
-              
-              try {
-                // Create the initial directory context
-                DirContext DirCtx = new InitialDirContext(envHash);
+			String filter = null;
 
-                SearchControls searchCtls = new SearchControls();
-                // Specify the ids of the attributes to return
-                String[] attrNames = {"o"};
-                searchCtls.setReturningAttributes(attrNames);
-                // set the ldap search scope - only look for top level referrals
-                searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
-                // set a time limit on searches to limit non-responding servers
-                searchCtls.setTimeLimit(ldapSearchTimeLimit);
-                // return the configured number of entries
-                searchCtls.setCountLimit(ldapSearchCountLimit);
-                
-                // Specify the attributes to match.
-                // build the ldap search filter to match referral entries that 
-                // match the search result
-                String rFilter = "(&(objectClass=referral)(ref=" + 
-                currentReferralInfo.substring(0, 
-                currentReferralInfo.indexOf("?")) + "))";
-                logMetacat.debug("rFilter is: " + rFilter);
-                
-                NamingEnumeration rNamingEnum = 
-                  DirCtx.search(ldapBase, rFilter, searchCtls);
-                  
-                while (rNamingEnum.hasMore()) {
-                  SearchResult rsr = (SearchResult) rNamingEnum.next();
-                  rsrAttr = rsr.getAttributes();
-                  logMetacat.debug("referral search result is: " +
-                    rsr.toString());
-                    
-                  // add the returned groups to the group vector.  Test the 
-                  // syntax of the returned attributes - sometimes they are 
-                  // preceded with the attribute id and a colon
-                  if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
-                    gvec.add( "cn=" + (tempAttr.get("cn") + "").substring(4) + 
-                    "," + "o=" + (rsrAttr.get("o") + "").substring(3 ) + "," + 
-                    ldapBase);
-                    logMetacat.info("group " + 
-                    (tempAttr.get("cn") + "").substring(4) + "," + 
-                    "o=" + (rsrAttr.get("o") + "").substring(3) + "," + 
-                    ldapBase + " added to the group vector");
-                  } else {
-                    gvec.add( "cn=" + tempAttr.get("cn") + "," + 
-                    "o=" + rsrAttr.get("o") +
-                    "," + ldapBase);
-                    logMetacat.info("group " + 
-                    "cn=" + tempAttr.get("cn") + "," + 
-                    "o=" + rsrAttr.get("o") + "," + 
-                    ldapBase + " added to the group vector");
-                  }  
-                }
-                
-              } catch (NamingException nameEx){
-                logMetacat.debug("Caught naming exception: ");
-                nameEx.printStackTrace(System.err);
-              }
-            }
-          }// end while
-          
-          moreReferrals = false;
-          
-        } catch (ReferralException re) {
-          
-          logMetacat.info(
-            "In AuthLdap.getGroups(), caught referral exception: " +
-            re.getReferralInfo()
-          );
-          this.currentReferralInfo = (String) re.getReferralInfo();
-          
-          // set moreReferrals to true and set the referral context
-          moreReferrals = true;
-          ctx = (DirContext) re.getReferralContext();
-           
-        }// end inner try
-      }// end for
-      
-      // close the context now that all initial and referral 
-      // searches are processed
-      ctx.close();
-      
-    } catch (NamingException e) {
-      
-      // naming exceptions get logged, groups are returned
-      logMetacat.info("In AuthLdap.getGroups(), caught naming exception: ");
-      e.printStackTrace(System.err);
-      
-    } finally {
-      // once all referrals are followed, report and return the groups found
-      logMetacat.warn("The user is in the following groups: " +
-                               gvec.toString());
-      //build and return the groups array
-      String groups[][] = new String[gvec.size()][2];
-      for (int i = 0; i < gvec.size(); i++) {
-        groups[i][0] = (String) gvec.elementAt(i);
-        groups[i][1] = (String) desc.elementAt(i);
-      }
-      return groups;
-    }// end outer try
-  }
+			if (user.indexOf("o=") > 0) {
+				String tempStr = user.substring(user.indexOf("o="));
+				filter = "(&(" + user.substring(0, user.indexOf(",")) + ")("
+						+ tempStr.substring(0, tempStr.indexOf(",")) + "))";
+			} else {
+				filter = "(&(" + user.substring(0, user.indexOf(",")) + "))";
+			}
+			filter = "(&(" + user.substring(0, user.indexOf(",")) + "))";
 
-  /**
-   * Get attributes describing a user or group
-   *
-   * @param foruser the user for which the attribute list is requested
-   * @returns HashMap a map of attribute name to a Vector of values
-   */
-  public HashMap<String, Vector<String>> getAttributes(String foruser) throws ConnectException {
-    return getAttributes(null, null, foruser);
-  }
+			NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
 
-  /**
-   * Get attributes describing a user or group
-   *
-   * @param user the user for authenticating against the service
-   * @param password the password for authenticating against the service
-   * @param foruser the user whose attributes should be returned
-   * @returns HashMap a map of attribute name to a Vector of values
-   */
-  public HashMap<String,Vector<String>> getAttributes(String user, String password, 
-    String foruser) throws ConnectException {
-    HashMap<String,Vector<String>> attributes = new HashMap<String,Vector<String>>();
-    String ldapUrl = this.ldapUrl;
-    String ldapBase = this.ldapBase;
-    String userident = foruser;
+			Attributes tempAttr = null;
+			try {
+				while (namingEnum.hasMore()) {
+					SearchResult sr = (SearchResult) namingEnum.next();
+					tempAttr = sr.getAttributes();
 
-    // Identify service provider to use
-    Hashtable env = new Hashtable(11);
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    env.put(Context.REFERRAL, referral);
-    env.put(Context.PROVIDER_URL, ldapUrl);
+					if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
+						userinfo[0] = (tempAttr.get("cn") + "").substring(4);
+					} else {
+						userinfo[0] = (tempAttr.get("cn") + "");
+					}
 
-    try {
+					if ((tempAttr.get("o") + "").startsWith("o: ")) {
+						userinfo[1] = (tempAttr.get("o") + "").substring(3);
+					} else {
+						userinfo[1] = (tempAttr.get("o") + "");
+					}
 
-      // Create the initial directory context
-      DirContext ctx = new InitialDirContext(env);
+					if ((tempAttr.get("mail") + "").startsWith("mail: ")) {
+						userinfo[2] = (tempAttr.get("mail") + "").substring(6);
+					} else {
+						userinfo[2] = (tempAttr.get("mail") + "");
+					}
+				}
+			} catch (SizeLimitExceededException slee) {
+				logMetacat.error("LDAP Server size limit exceeded. "
+						+ "Returning incomplete record set.");
+			}
 
-      // Ask for all attributes of the user
-      //Attributes attrs = ctx.getAttributes(userident);
-      Attributes attrs = ctx.getAttributes(foruser);
+			// Close the context when we're done
+			ctx.close();
 
-      // Print all of the attributes
-      NamingEnumeration en = attrs.getAll();
-      while (en.hasMore()) {
-        Attribute att = (Attribute) en.next();
-        Vector<String> values = new Vector();
-        String attName = att.getID();
-        NamingEnumeration attvalues = att.getAll();
-        while (attvalues.hasMore()) {
-          String value = (String) attvalues.next();
-          values.add(value);
-        }
-        attributes.put(attName, values);
-      }
+		} catch (NamingException e) {
+			logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
+			// e.printStackTrace(System.err);
+			throw new ConnectException("Problem getting users in AuthLdap.getUsers:" + e);
+		}
 
-      // Close the context when we're done
-      ctx.close();
-    }
-    catch (NamingException e) {
-      logMetacat.error("Problem getting attributes in " +
-                        "AuthLdap.getAttributes:" + e);
-      throw new ConnectException(
-          "Problem getting attributes in AuthLdap.getAttributes:" + e);
-    }
+		return userinfo;
+	}
 
-    return attributes;
-  }
+	/**
+	 * Get the users for a particular group from the authentication service
+	 * 
+	 * @param user
+	 *            the user for authenticating against the service
+	 * @param password
+	 *            the password for authenticating against the service
+	 * @param group
+	 *            the group whose user list should be returned
+	 * @returns string array of the user names belonging to the group
+	 */
+	public String[] getUsers(String user, String password, String group)
+			throws ConnectException {
+		String[] users = null;
 
-  /**
-   * Get list of all subtrees holding Metacat's groups and users
-   * starting from the Metacat LDAP root,
-   * i.e. ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
-   */
-  private Hashtable getSubtrees(String user, String password, 
-    String ldapUrl, String ldapBase) throws ConnectException {
-    Hashtable trees = new Hashtable();
+		// Identify service provider to use
+		Hashtable env = new Hashtable(11);
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, referral);
+		env.put(Context.PROVIDER_URL, ldapUrl);
 
-    // Identify service provider to use
-    Hashtable env = new Hashtable(11);
-    env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-    // env.put(Context.REFERRAL, referral);
-    // Using 'ignore' here instead of 'follow' as 'ignore' seems
-    // to do the job better. 'follow' was not bringing up the UCNRS
-    // and PISCO tree whereas 'ignore' brings up the tree.
+		try {
 
-    env.put(Context.REFERRAL, "ignore");
-    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
+			// Create the initial directory context
+			DirContext ctx = new InitialDirContext(env);
 
-    try {
+			// Specify the ids of the attributes to return
+			String[] attrIDs = { "uniqueMember" };
 
-      // Create the initial directory context
-      DirContext ctx = new InitialDirContext(env);
+			Attributes answer = ctx.getAttributes(group, attrIDs);
 
-      // Specify the ids of the attributes to return
-      String[] attrIDs = {
-          "o", "ref"};
-      SearchControls ctls = new SearchControls();
-      ctls.setReturningAttributes(attrIDs);
-      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+			Vector uvec = new Vector();
+			try {
+				for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {
+					Attribute attr = (Attribute) ae.next();
+					for (NamingEnumeration e = attr.getAll(); e.hasMore(); uvec.add(e
+							.next())) {
+						;
+					}
+				}
+			} catch (SizeLimitExceededException slee) {
+				logMetacat.error("LDAP Server size limit exceeded. "
+						+ "Returning incomplete record set.");
+			}
 
-      // Specify the attributes to match.
-      // Subtrees from the main server are found as objects with attribute
-      // objectclass=organization or objectclass=referral to the subtree
-      // resided on other server.
-      String filter = "(|(objectclass=organization)(objectclass=referral))";
+			// initialize users[]; fill users[]
+			users = new String[uvec.size()];
+			for (int i = 0; i < uvec.size(); i++) {
+				users[i] = (String) uvec.elementAt(i);
+			}
 
-      // Search for objects in the current context
-      NamingEnumeration namingEnum = ctx.search("", filter, ctls);
+			// Close the context when we're done
+			ctx.close();
 
-      // Print the subtrees' <ldapURL, baseDN>
-      while (namingEnum.hasMore()) {
+		} catch (NamingException e) {
+			logMetacat.error("Problem getting users for a group in "
+					+ "AuthLdap.getUsers:" + e);
+			/*
+			 * throw new ConnectException( "Problem getting users for a group in
+			 * AuthLdap.getUsers:" + e);
+			 */
+		}
 
-        SearchResult sr = (SearchResult) namingEnum.next();
+		return users;
+	}
 
-        Attributes attrs = sr.getAttributes();
-        NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref" attrs
+	/**
+	 * Get all groups from the authentication service
+	 * 
+	 * @param user
+	 *            the user for authenticating against the service
+	 * @param password
+	 *            the password for authenticating against the service
+	 * @returns string array of the group names
+	 */
+	public String[][] getGroups(String user, String password) throws ConnectException {
+		return getGroups(user, password, null);
+	}
 
-        if (enum1.hasMore()) {
-          Attribute attr = (Attribute) enum1.next();
-          String attrValue = (String) attr.get();
-          String attrName = (String) attr.getID();
+	/**
+	 * Get the groups for a particular user from the authentication service
+	 * 
+	 * @param user
+	 *            the user for authenticating against the service
+	 * @param password
+	 *            the password for authenticating against the service
+	 * @param foruser
+	 *            the user whose group list should be returned
+	 * @returns string array of the group names
+	 */
+	public String[][] getGroups(String user, String password, String foruser)
+			throws ConnectException {
 
-          if (enum1.hasMore()) {
-            attr = (Attribute) enum1.next();
-            String refValue = (String) attr.get();
-            String refName = (String) attr.getID();
-            if (ldapBase.startsWith(refName + "=" + refValue)) {
-              trees.put(ldapBase,
-                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
-            }
-            else {
-              // this is a referral - so organization name is appended in
-              // front of the ldapbase.... later it is stripped out
-              // in getPrincipals
-              trees.put("[" + refName + "=" + refValue + "]" +
-                        attrValue.substring(attrValue.lastIndexOf("/") + 1,
-                                            attrValue.length()),
-                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
+		logMetacat.debug("getGroups() called.");
 
-              // trees.put(refName + "=" + refValue + "," + ldapBase,
-              //           attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
-            }
+		// create vectors to store group and dscription values returned from the
+		// ldap servers
+		Vector gvec = new Vector();
+		Vector desc = new Vector();
+		Attributes tempAttr = null;
+		Attributes rsrAttr = null;
 
-          }
-          else if (ldapBase.startsWith(attrName + "=" + attrValue)) {
-            trees.put(ldapBase, ldapUrl);
-          }
-          else {
-            if (sr.isRelative()) {
-              trees.put(attrName + "=" + attrValue + "," + ldapBase, ldapUrl);
-            }
-            else {
-              String referenceURL = sr.getName();
-              referenceURL = referenceURL.substring(0,
-                  referenceURL.lastIndexOf("/") + 1);
-              trees.put(attrName + "=" + attrValue + "," + ldapBase,
-                        referenceURL);
-            }
+		// DURING getGroups(), DO WE NOT BIND USING userName AND userPassword??
+		// NEED TO FIX THIS ...
+		userName = user;
+		userPassword = password;
+		// Identify service provider to use
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, "throw");
+		env.put(Context.PROVIDER_URL, ldapUrl);
+		env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
 
-          }
-        }
-      }
+		// Iterate through the referrals, handling NamingExceptions in the
+		// outer catch statement, ReferralExceptions in the inner catch
+		// statement
+		try { // outer try
 
-      // Close the context when we're done
-      ctx.close();
+			// Create the initial directory context
+			DirContext ctx = new InitialDirContext(env);
 
-    }
-    catch (NamingException e) {
-      logMetacat.error("Problem getting subtrees in AuthLdap.getSubtrees:"
-                        + e);
-      throw new ConnectException(
-          "Problem getting subtrees in AuthLdap.getSubtrees:" + e);
-    }
+			// Specify the attributes to match.
+			// Groups are objects with attribute objectclass=groupofuniquenames.
+			// and have attribute uniquemember: uid=foruser,ldapbase.
+			SearchControls ctls = new SearchControls();
+			// Specify the ids of the attributes to return
+			String[] attrIDs = { "cn", "o", "description" };
+			ctls.setReturningAttributes(attrIDs);
+			// set the ldap search scope
+			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+			// set a 10 second time limit on searches to limit non-responding
+			// servers
+			ctls.setTimeLimit(ldapSearchTimeLimit);
+			// return at most 20000 entries
+			ctls.setCountLimit(ldapSearchCountLimit);
 
-    return trees;
-  }
+			// build the ldap search filter that represents the "group" concept
+			String filter = null;
+			String gfilter = "(objectClass=groupOfUniqueNames)";
+			if (null == foruser) {
+				filter = gfilter;
+			} else {
+				filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
+			}
+			logMetacat.info("group filter is: " + filter);
 
-  /**
-   * Get all groups and users from authentication scheme.
-   * The output is formatted in XML.
-   * @param user the user which requests the information
-   * @param password the user's password
-   */
-  public String getPrincipals(String user, String password) throws 
-    ConnectException {
-    StringBuffer out = new StringBuffer();
-   
-    out.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
-    out.append("<principals>\n");
+			// now, search and iterate through the referrals
+			for (boolean moreReferrals = true; moreReferrals;) {
+				try { // inner try
 
-    /*
-     * get all subtrees first in the current dir context
-     * and then the Metacat users under them
-     */
-    Hashtable subtrees = getSubtrees(user, password, this.ldapUrl,
-                                     this.ldapBase);
+					NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
 
-    Enumeration keyEnum = subtrees.keys();
-    while (keyEnum.hasMoreElements()) {
-      this.ldapBase = (String) keyEnum.nextElement();
-      this.ldapUrl = (String) subtrees.get(ldapBase);
-      logMetacat.info("ldapBase "+ldapBase);
-      logMetacat.info("ldapUrl "+ldapUrl);
-      /*
-       * code to get the organization name from ldapBase
-       */
-      String orgName = this.ldapBase;
-      if (orgName.startsWith("[")) {
-        // if orgName starts with [ then it is a referral URL...
-        // (see code in getSubtress)
-        // hence orgName can be retrieved  by getting the string between
-        // 'o=' and ']'
-        // also the string between [ and ] needs to be striped out from
-        // this.ldapBase
-        this.ldapBase = orgName.substring(orgName.indexOf("]") + 1);
-        if (orgName != null && orgName.indexOf("o=") > -1) {
-          orgName = orgName.substring(orgName.indexOf("o=") + 2);
-          orgName = orgName.substring(0, orgName.indexOf("]"));
-        }
-      }
-      else {
-        // else it is not referral
-        // hence orgName can be retrieved  by getting the string between
-        // 'o=' and ','
-        if (orgName != null && orgName.indexOf("o=") > -1) {
-          orgName = orgName.substring(orgName.indexOf("o=") + 2);
-          if (orgName.indexOf(",") > -1) {
-            orgName = orgName.substring(0, orgName.indexOf(","));
-          }
-        }
-      }
-      logMetacat.info("org name is  "+orgName);
-      out.append("  <authSystem URI=\"" +
-                 this.ldapUrl + this.ldapBase + "\" organization=\"" + orgName +
-                 "\">\n");
+					// Print the groups
+					while (namingEnum.hasMore()) {
+						SearchResult sr = (SearchResult) namingEnum.next();
 
-      // get all groups for directory context
-      String[][] groups = getGroups(user, password);
-      logMetacat.debug("after getting groups "+groups);
-      String[][] users = getUsers(user, password);
-      logMetacat.debug("after getting users "+users);
-      int userIndex = 0;
+						tempAttr = sr.getAttributes();
 
-      // for the groups and users that belong to them
-      if (groups != null && users != null && groups.length > 0) {
-    	 for (int i = 0; i < groups.length; i++) {
-          out.append("    <group>\n");
-          out.append("      <groupname>" + groups[i][0] + "</groupname>\n");
-          out.append("      <description>" + groups[i][1] + "</description>\n");
-          String[] usersForGroup = getUsers(user, password, groups[i][0]);
-          for (int j = 0; j < usersForGroup.length; j++) {
-            userIndex = searchUser(usersForGroup[j], users);
-            out.append("      <user>\n");
+						if ((tempAttr.get("description") + "")
+								.startsWith("description: ")) {
+							desc.add((tempAttr.get("description") + "").substring(13));
+						} else {
+							desc.add(tempAttr.get("description") + "");
+						}
 
-            if (userIndex < 0) {
-              out.append("        <username>" + usersForGroup[j] +
-                         "</username>\n");
-            }
-            else {
-              out.append("        <username>" + users[userIndex][0] +
-                         "</username>\n");
-              out.append("        <name>" + users[userIndex][1] + "</name>\n");
-              out.append("        <organization>" + users[userIndex][2] +
-                         "</organization>\n");
-              if (users[userIndex][3].compareTo("null") != 0) {
-                out.append("      <organizationUnitName>" + users[userIndex][3] +
-                           "</organizationUnitName>\n");
-              }
-              out.append("        <email>" + users[userIndex][4] + "</email>\n");
-            }
+						// check for an absolute URL value or an answer value
+						// relative
+						// to the target context
+						if (!sr.getName().startsWith("ldap") && sr.isRelative()) {
+							logMetacat.debug("Search result entry is relative ...");
+							gvec.add(sr.getName() + "," + ldapBase);
+							logMetacat.info("group " + sr.getName() + "," + ldapBase
+									+ " added to the group vector");
+						} else {
+							logMetacat.debug("Search result entry is absolute ...");
 
-            out.append("      </user>\n");
-          }
-          out.append("    </group>\n");
-        }
-      }
-     
-      if (users != null)
-      {
-	      // for the users not belonging to any grou8p
-	      for (int j = 0; j < users.length; j++) {
-	          out.append("    <user>\n");
-	          out.append("      <username>" + users[j][0] + "</username>\n");
-	          out.append("      <name>" + users[j][1] + "</name>\n");
-	          out.append("      <organization>" + users[j][2] +
-	                     "</organization>\n");
-	          if (users[j][3].compareTo("null") != 0) {
-	            out.append("      <organizationUnitName>" + users[j][3] +
-	                       "</organizationUnitName>\n");
-	          }
-	          out.append("      <email>" + users[j][4] + "</email>\n");
-	          out.append("    </user>\n");
-	      }
-      }
+							// search the top level directory for referral
+							// objects and match
+							// that of the search result's absolute URL. This
+							// will let us
+							// rebuild the group name from the search result,
+							// referral point
+							// in the top directory tree, and ldapBase.
 
-      out.append("  </authSystem>\n");
-    }
-    out.append("</principals>");
-    return out.toString();
-  }
+							// configure a new directory search first
+							Hashtable envHash = new Hashtable(11);
+							// Identify service provider to use
+							envHash.put(Context.INITIAL_CONTEXT_FACTORY,
+									"com.sun.jndi.ldap.LdapCtxFactory");
+							envHash.put(Context.REFERRAL, "ignore");
+							envHash.put(Context.PROVIDER_URL, ldapUrl);
+							envHash.put("com.sun.jndi.ldap.connect.timeout",
+									ldapConnectTimeLimit);
 
-  /**
-   * Method for getting index of user DN in User info array
-   */
-  int searchUser(String user, String userGroup[][]) {
-    for (int j = 0; j < userGroup.length; j++) {
-      if (user.compareTo(userGroup[j][0]) == 0) {
-        return j;
-      }
-    }
-    return -1;
-  }
+							try {
+								// Create the initial directory context
+								DirContext DirCtx = new InitialDirContext(envHash);
 
-  public void testCredentials(String dn, String password, 
-		    String rootServer, String rootBase ) throws NamingException {
-	  
-	  String server = "";
-	  String userDN = "";
-	  logMetacat.debug("dn is: " + dn);
+								SearchControls searchCtls = new SearchControls();
+								// Specify the ids of the attributes to return
+								String[] attrNames = { "o" };
+								searchCtls.setReturningAttributes(attrNames);
+								// set the ldap search scope - only look for top
+								// level referrals
+								searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+								// set a time limit on searches to limit
+								// non-responding servers
+								searchCtls.setTimeLimit(ldapSearchTimeLimit);
+								// return the configured number of entries
+								searchCtls.setCountLimit(ldapSearchCountLimit);
 
-	  int position = dn.lastIndexOf("/");
-      logMetacat.debug("position is: " + position);
-	  if (position == -1) {
-		  server = rootServer;
-		  if(dn.indexOf(userDN) < 0){
-			  userDN = dn + "," + rootBase;
-		  } else {
-			  userDN = dn;
-		  }
-		  logMetacat.debug("userDN is: " + userDN);
+								// Specify the attributes to match.
+								// build the ldap search filter to match
+								// referral entries that
+								// match the search result
+								String rFilter = "(&(objectClass=referral)(ref="
+										+ currentReferralInfo.substring(0,
+												currentReferralInfo.indexOf("?")) + "))";
+								logMetacat.debug("rFilter is: " + rFilter);
 
-       } else {
-		  server = dn.substring(0, position+1);
-		  userDN = dn.substring(position+1);
-		  logMetacat.debug("server is: " + server);
-		  logMetacat.debug("userDN is: " + userDN);
-	   }
-		          
-	   logMetacat.debug("Trying to authenticate: " + userDN);
-	   logMetacat.debug("          Using server: " + server);
+								NamingEnumeration rNamingEnum = DirCtx.search(ldapBase,
+										rFilter, searchCtls);
 
-///*	   try { 
-			LdapContext ctx = null;
-			   
-			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
-	        env.put(Context.REFERRAL, "follow");
-			env.put(Context.SECURITY_AUTHENTICATION, "simple");
-			env.put(Context.SECURITY_PRINCIPAL, userDN);
-			env.put(Context.SECURITY_CREDENTIALS, password);
-			env.put(Context.PROVIDER_URL, rootServer);
+								while (rNamingEnum.hasMore()) {
+									SearchResult rsr = (SearchResult) rNamingEnum.next();
+									rsrAttr = rsr.getAttributes();
+									logMetacat.debug("referral search result is: "
+											+ rsr.toString());
 
-			ctx = new InitialLdapContext(env, null);
+									// add the returned groups to the group
+									// vector. Test the
+									// syntax of the returned attributes -
+									// sometimes they are
+									// preceded with the attribute id and a
+									// colon
+									if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
+										gvec.add("cn="
+												+ (tempAttr.get("cn") + "").substring(4)
+												+ "," + "o="
+												+ (rsrAttr.get("o") + "").substring(3)
+												+ "," + ldapBase);
+										logMetacat.info("group "
+												+ (tempAttr.get("cn") + "").substring(4)
+												+ "," + "o="
+												+ (rsrAttr.get("o") + "").substring(3)
+												+ "," + ldapBase
+												+ " added to the group vector");
+									} else {
+										gvec.add("cn=" + tempAttr.get("cn") + "," + "o="
+												+ rsrAttr.get("o") + "," + ldapBase);
+										logMetacat.info("group " + "cn="
+												+ tempAttr.get("cn") + "," + "o="
+												+ rsrAttr.get("o") + "," + ldapBase
+												+ " added to the group vector");
+									}
+								}
 
+							} catch (NamingException nameEx) {
+								logMetacat.debug("Caught naming exception: ");
+								nameEx.printStackTrace(System.err);
+							}
+						}
+					}// end while
 
-		
-  }
-   
-    /**
+					moreReferrals = false;
+
+				} catch (ReferralException re) {
+
+					logMetacat
+							.info("In AuthLdap.getGroups(), caught referral exception: "
+									+ re.getReferralInfo());
+					this.currentReferralInfo = (String) re.getReferralInfo();
+
+					// set moreReferrals to true and set the referral context
+					moreReferrals = true;
+					ctx = (DirContext) re.getReferralContext();
+
+				}// end inner try
+			}// end for
+
+			// close the context now that all initial and referral
+			// searches are processed
+			ctx.close();
+
+		} catch (NamingException e) {
+
+			// naming exceptions get logged, groups are returned
+			logMetacat.info("In AuthLdap.getGroups(), caught naming exception: ");
+			e.printStackTrace(System.err);
+
+		} finally {
+			// once all referrals are followed, report and return the groups
+			// found
+			logMetacat.warn("The user is in the following groups: " + gvec.toString());
+			// build and return the groups array
+			String groups[][] = new String[gvec.size()][2];
+			for (int i = 0; i < gvec.size(); i++) {
+				groups[i][0] = (String) gvec.elementAt(i);
+				groups[i][1] = (String) desc.elementAt(i);
+			}
+			return groups;
+		}// end outer try
+	}
+
+	/**
+	 * Get attributes describing a user or group
+	 * 
+	 * @param foruser
+	 *            the user for which the attribute list is requested
+	 * @returns HashMap a map of attribute name to a Vector of values
+	 */
+	public HashMap<String, Vector<String>> getAttributes(String foruser)
+			throws ConnectException {
+		return getAttributes(null, null, foruser);
+	}
+
+	/**
+	 * Get attributes describing a user or group
+	 * 
+	 * @param user
+	 *            the user for authenticating against the service
+	 * @param password
+	 *            the password for authenticating against the service
+	 * @param foruser
+	 *            the user whose attributes should be returned
+	 * @returns HashMap a map of attribute name to a Vector of values
+	 */
+	public HashMap<String, Vector<String>> getAttributes(String user, String password,
+			String foruser) throws ConnectException {
+		HashMap<String, Vector<String>> attributes = new HashMap<String, Vector<String>>();
+		String ldapUrl = this.ldapUrl;
+		String ldapBase = this.ldapBase;
+		String userident = foruser;
+
+		// Identify service provider to use
+		Hashtable env = new Hashtable(11);
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, referral);
+		env.put(Context.PROVIDER_URL, ldapUrl);
+
+		try {
+
+			// Create the initial directory context
+			DirContext ctx = new InitialDirContext(env);
+
+			// Ask for all attributes of the user
+			// Attributes attrs = ctx.getAttributes(userident);
+			Attributes attrs = ctx.getAttributes(foruser);
+
+			// Print all of the attributes
+			NamingEnumeration en = attrs.getAll();
+			while (en.hasMore()) {
+				Attribute att = (Attribute) en.next();
+				Vector<String> values = new Vector();
+				String attName = att.getID();
+				NamingEnumeration attvalues = att.getAll();
+				while (attvalues.hasMore()) {
+					String value = (String) attvalues.next();
+					values.add(value);
+				}
+				attributes.put(attName, values);
+			}
+
+			// Close the context when we're done
+			ctx.close();
+		} catch (NamingException e) {
+			logMetacat.error("Problem getting attributes in " + "AuthLdap.getAttributes:"
+					+ e);
+			throw new ConnectException(
+					"Problem getting attributes in AuthLdap.getAttributes:" + e);
+		}
+
+		return attributes;
+	}
+
+	/**
+	 * Get list of all subtrees holding Metacat's groups and users starting from
+	 * the Metacat LDAP root, i.e.
+	 * ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
+	 */
+	private Hashtable getSubtrees(String user, String password, String ldapUrl,
+			String ldapBase) throws ConnectException {
+		Hashtable trees = new Hashtable();
+
+		// Identify service provider to use
+		Hashtable env = new Hashtable(11);
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		// env.put(Context.REFERRAL, referral);
+		// Using 'ignore' here instead of 'follow' as 'ignore' seems
+		// to do the job better. 'follow' was not bringing up the UCNRS
+		// and PISCO tree whereas 'ignore' brings up the tree.
+
+		env.put(Context.REFERRAL, "ignore");
+		env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
+
+		try {
+
+			// Create the initial directory context
+			DirContext ctx = new InitialDirContext(env);
+
+			// Specify the ids of the attributes to return
+			String[] attrIDs = { "o", "ref" };
+			SearchControls ctls = new SearchControls();
+			ctls.setReturningAttributes(attrIDs);
+			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
+
+			// Specify the attributes to match.
+			// Subtrees from the main server are found as objects with attribute
+			// objectclass=organization or objectclass=referral to the subtree
+			// resided on other server.
+			String filter = "(|(objectclass=organization)(objectclass=referral))";
+
+			// Search for objects in the current context
+			NamingEnumeration namingEnum = ctx.search("", filter, ctls);
+
+			// Print the subtrees' <ldapURL, baseDN>
+			while (namingEnum.hasMore()) {
+
+				SearchResult sr = (SearchResult) namingEnum.next();
+
+				Attributes attrs = sr.getAttributes();
+				NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref"
+															// attrs
+
+				if (enum1.hasMore()) {
+					Attribute attr = (Attribute) enum1.next();
+					String attrValue = (String) attr.get();
+					String attrName = (String) attr.getID();
+
+					if (enum1.hasMore()) {
+						attr = (Attribute) enum1.next();
+						String refValue = (String) attr.get();
+						String refName = (String) attr.getID();
+						if (ldapBase.startsWith(refName + "=" + refValue)) {
+							trees.put(ldapBase, attrValue.substring(0, attrValue
+									.lastIndexOf("/") + 1));
+						} else {
+							// this is a referral - so organization name is
+							// appended in
+							// front of the ldapbase.... later it is stripped
+							// out
+							// in getPrincipals
+							trees.put("["
+									+ refName
+									+ "="
+									+ refValue
+									+ "]"
+									+ attrValue.substring(attrValue.lastIndexOf("/") + 1,
+											attrValue.length()), attrValue.substring(0,
+									attrValue.lastIndexOf("/") + 1));
+
+							// trees.put(refName + "=" + refValue + "," +
+							// ldapBase,
+							// attrValue.substring(0, attrValue.lastIndexOf("/")
+							// + 1));
+						}
+
+					} else if (ldapBase.startsWith(attrName + "=" + attrValue)) {
+						trees.put(ldapBase, ldapUrl);
+					} else {
+						if (sr.isRelative()) {
+							trees.put(attrName + "=" + attrValue + "," + ldapBase,
+									ldapUrl);
+						} else {
+							String referenceURL = sr.getName();
+							referenceURL = referenceURL.substring(0, referenceURL
+									.lastIndexOf("/") + 1);
+							trees.put(attrName + "=" + attrValue + "," + ldapBase,
+									referenceURL);
+						}
+
+					}
+				}
+			}
+
+			// Close the context when we're done
+			ctx.close();
+
+		} catch (NamingException e) {
+			logMetacat.error("Problem getting subtrees in AuthLdap.getSubtrees:" + e);
+			throw new ConnectException(
+					"Problem getting subtrees in AuthLdap.getSubtrees:" + e);
+		}
+
+		return trees;
+	}
+
+	/**
+	 * Get all groups and users from authentication scheme. The output is
+	 * formatted in XML.
+	 * 
+	 * @param user
+	 *            the user which requests the information
+	 * @param password
+	 *            the user's password
+	 */
+	public String getPrincipals(String user, String password) throws ConnectException {
+		StringBuffer out = new StringBuffer();
+
+		out.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
+		out.append("<principals>\n");
+
+		/*
+		 * get all subtrees first in the current dir context and then the
+		 * Metacat users under them
+		 */
+		Hashtable subtrees = getSubtrees(user, password, this.ldapUrl, this.ldapBase);
+
+		Enumeration keyEnum = subtrees.keys();
+		while (keyEnum.hasMoreElements()) {
+			this.ldapBase = (String) keyEnum.nextElement();
+			this.ldapUrl = (String) subtrees.get(ldapBase);
+			logMetacat.info("ldapBase " + ldapBase);
+			logMetacat.info("ldapUrl " + ldapUrl);
+			/*
+			 * code to get the organization name from ldapBase
+			 */
+			String orgName = this.ldapBase;
+			if (orgName.startsWith("[")) {
+				// if orgName starts with [ then it is a referral URL...
+				// (see code in getSubtress)
+				// hence orgName can be retrieved by getting the string between
+				// 'o=' and ']'
+				// also the string between [ and ] needs to be striped out from
+				// this.ldapBase
+				this.ldapBase = orgName.substring(orgName.indexOf("]") + 1);
+				if (orgName != null && orgName.indexOf("o=") > -1) {
+					orgName = orgName.substring(orgName.indexOf("o=") + 2);
+					orgName = orgName.substring(0, orgName.indexOf("]"));
+				}
+			} else {
+				// else it is not referral
+				// hence orgName can be retrieved by getting the string between
+				// 'o=' and ','
+				if (orgName != null && orgName.indexOf("o=") > -1) {
+					orgName = orgName.substring(orgName.indexOf("o=") + 2);
+					if (orgName.indexOf(",") > -1) {
+						orgName = orgName.substring(0, orgName.indexOf(","));
+					}
+				}
+			}
+			logMetacat.info("org name is  " + orgName);
+			out.append("  <authSystem URI=\"" + this.ldapUrl + this.ldapBase
+					+ "\" organization=\"" + orgName + "\">\n");
+
+			// get all groups for directory context
+			String[][] groups = getGroups(user, password);
+			logMetacat.debug("after getting groups " + groups);
+			String[][] users = getUsers(user, password);
+			logMetacat.debug("after getting users " + users);
+			int userIndex = 0;
+
+			// for the groups and users that belong to them
+			if (groups != null && users != null && groups.length > 0) {
+				for (int i = 0; i < groups.length; i++) {
+					out.append("    <group>\n");
+					out.append("      <groupname>" + groups[i][0] + "</groupname>\n");
+					out.append("      <description>" + groups[i][1] + "</description>\n");
+					String[] usersForGroup = getUsers(user, password, groups[i][0]);
+					for (int j = 0; j < usersForGroup.length; j++) {
+						userIndex = searchUser(usersForGroup[j], users);
+						out.append("      <user>\n");
+
+						if (userIndex < 0) {
+							out.append("        <username>" + usersForGroup[j]
+									+ "</username>\n");
+						} else {
+							out.append("        <username>" + users[userIndex][0]
+									+ "</username>\n");
+							out.append("        <name>" + users[userIndex][1]
+									+ "</name>\n");
+							out.append("        <organization>" + users[userIndex][2]
+									+ "</organization>\n");
+							if (users[userIndex][3].compareTo("null") != 0) {
+								out.append("      <organizationUnitName>"
+										+ users[userIndex][3]
+										+ "</organizationUnitName>\n");
+							}
+							out.append("        <email>" + users[userIndex][4]
+									+ "</email>\n");
+						}
+
+						out.append("      </user>\n");
+					}
+					out.append("    </group>\n");
+				}
+			}
+
+			if (users != null) {
+				// for the users not belonging to any grou8p
+				for (int j = 0; j < users.length; j++) {
+					out.append("    <user>\n");
+					out.append("      <username>" + users[j][0] + "</username>\n");
+					out.append("      <name>" + users[j][1] + "</name>\n");
+					out
+							.append("      <organization>" + users[j][2]
+									+ "</organization>\n");
+					if (users[j][3].compareTo("null") != 0) {
+						out.append("      <organizationUnitName>" + users[j][3]
+								+ "</organizationUnitName>\n");
+					}
+					out.append("      <email>" + users[j][4] + "</email>\n");
+					out.append("    </user>\n");
+				}
+			}
+
+			out.append("  </authSystem>\n");
+		}
+		out.append("</principals>");
+		return out.toString();
+	}
+
+	/**
+	 * Method for getting index of user DN in User info array
+	 */
+	int searchUser(String user, String userGroup[][]) {
+		for (int j = 0; j < userGroup.length; j++) {
+			if (user.compareTo(userGroup[j][0]) == 0) {
+				return j;
+			}
+		}
+		return -1;
+	}
+
+	public void testCredentials(String dn, String password, String rootServer,
+			String rootBase) throws NamingException {
+
+		String server = "";
+		String userDN = "";
+		logMetacat.debug("dn is: " + dn);
+
+		int position = dn.lastIndexOf("/");
+		logMetacat.debug("position is: " + position);
+		if (position == -1) {
+			server = rootServer;
+			if (dn.indexOf(userDN) < 0) {
+				userDN = dn + "," + rootBase;
+			} else {
+				userDN = dn;
+			}
+			logMetacat.debug("userDN is: " + userDN);
+
+		} else {
+			server = dn.substring(0, position + 1);
+			userDN = dn.substring(position + 1);
+			logMetacat.debug("server is: " + server);
+			logMetacat.debug("userDN is: " + userDN);
+		}
+
+		logMetacat.debug("Trying to authenticate: " + userDN);
+		logMetacat.debug("          Using server: " + server);
+
+		// /* try {
+		LdapContext ctx = null;
+
+		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+		env.put(Context.REFERRAL, "follow");
+		env.put(Context.SECURITY_AUTHENTICATION, "simple");
+		env.put(Context.SECURITY_PRINCIPAL, userDN);
+		env.put(Context.SECURITY_CREDENTIALS, password);
+		env.put(Context.PROVIDER_URL, rootServer);
+
+		ctx = new InitialLdapContext(env, null);
+
+	}
+
+	/**
 	 * Test method for the class
 	 */
 	public static void main(String[] args) {
@@ -1268,8 +1265,7 @@
 		try {
 			authservice = new AuthLdap();
 		} catch (Exception e) {
-			logMetacat.error("Could not instantiate AuthLdap: "
-					+ e.getMessage());
+			logMetacat.error("Could not instantiate AuthLdap: " + e.getMessage());
 			return;
 		}
 		logMetacat.warn("Session exists...");
@@ -1287,11 +1283,9 @@
 			// Get attributes for the user
 			if (isValid) {
 				logMetacat.info("\nGetting attributes for user....");
-				HashMap userInfo = authservice.getAttributes(user, password,
-						user);
+				HashMap userInfo = authservice.getAttributes(user, password, user);
 				// Print all of the attributes
-				Iterator attList = (Iterator) (((Set) userInfo.keySet())
-						.iterator());
+				Iterator attList = (Iterator) (((Set) userInfo.keySet()).iterator());
 				while (attList.hasNext()) {
 					String att = (String) attList.next();
 					Vector values = (Vector) userInfo.get(att);
@@ -1329,8 +1323,7 @@
 			if (isValid) {
 				logMetacat.warn("\nGetting users for group....");
 				logMetacat.info("Group: " + savedGroup);
-				String[] users = authservice.getUsers(user, password,
-						savedGroup);
+				String[] users = authservice.getUsers(user, password, savedGroup);
 				logMetacat.info("Users found: " + users.length);
 				for (int i = 0; i < users.length; i++) {
 					logMetacat.warn("User " + i + ": " + users[i]);
@@ -1367,12 +1360,12 @@
 					+ ioe.getMessage());
 		} catch (InstantiationException ie) {
 			logMetacat.error("Instantiation error writing to file principals.txt: "
-							+ ie.getMessage());
+					+ ie.getMessage());
 		}
 	}
 
-  /**
-   * This method will be called by start a thread.
-   * It can handle if a referral exception happend.
-   */
+	/**
+	 * This method will be called by start a thread. It can handle if a referral
+	 * exception happend.
+	 */
 }



More information about the Metacat-cvs mailing list