Project

General

Profile

« Previous | Next » 

Revision 4629

Added by daigle over 15 years ago

Reformat file

View differences:

src/edu/ucsb/nceas/metacat/AuthLdap.java
62 62
import java.util.Vector;
63 63

  
64 64
/**
65
 * An implementation of the AuthInterface interface that
66
 * allows Metacat to use the LDAP protocol for directory services.
67
 * The LDAP authentication service is used to determine if a user
68
 * is authenticated, and whether they are a member of a particular group.
65
 * An implementation of the AuthInterface interface that allows Metacat to use
66
 * the LDAP protocol for directory services. The LDAP authentication service is
67
 * used to determine if a user is authenticated, and whether they are a member
68
 * of a particular group.
69 69
 */
70 70
public class AuthLdap implements AuthInterface {
71
  private String ldapUrl;
72
  private String ldapsUrl;
73
  private String ldapBase;
74
  private String referral;
75
  private String ldapConnectTimeLimit;
76
  private int ldapSearchTimeLimit;
77
  private int ldapSearchCountLimit;
78
  private String currentReferralInfo;
79
  Hashtable env = new Hashtable(11);
80
  private Context rContext;
81
  private String userName;
82
  private String userPassword;
83
  ReferralException refExc;
71
	private String ldapUrl;
72
	private String ldapsUrl;
73
	private String ldapBase;
74
	private String referral;
75
	private String ldapConnectTimeLimit;
76
	private int ldapSearchTimeLimit;
77
	private int ldapSearchCountLimit;
78
	private String currentReferralInfo;
79
	Hashtable env = new Hashtable(11);
80
	private Context rContext;
81
	private String userName;
82
	private String userPassword;
83
	ReferralException refExc;
84 84

  
85
  private static Logger logMetacat = Logger.getLogger(AuthLdap.class);
86
  
87
    /**
85
	private static Logger logMetacat = Logger.getLogger(AuthLdap.class);
86

  
87
	/**
88 88
	 * Construct an AuthLdap
89 89
	 */
90 90
	public AuthLdap() throws InstantiationException {
......
92 92
		try {
93 93
			this.ldapUrl = PropertyService.getProperty("auth.url");
94 94
			this.ldapsUrl = PropertyService.getProperty("auth.surl");
95
			// use the NCEAS base as a fallback.  Normally, the base will be
95
			// use the NCEAS base as a fallback. Normally, the base will be
96 96
			// parsed from the user during authentication
97 97
			// TODO MCD this may need to remain always at NCEAS value
98 98
			this.ldapBase = PropertyService.getProperty("organization.base.NCEAS");
......
117 117
		this.currentReferralInfo = "";
118 118
	}
119 119

  
120
  /**
120
	/**
121 121
	 * Determine if a user/password are valid according to the authentication
122 122
	 * service.
123 123
	 * 
......
127 127
	 *            the password to use for authentication
128 128
	 * @returns boolean true if authentication successful, false otherwise
129 129
	 */
130
  
131
  public boolean authenticate(String user, String password) throws ConnectException {
132
    String ldapUrl = this.ldapUrl;
133
    String ldapsUrl = this.ldapsUrl;
134
    String ldapBase = this.ldapBase;
135
    boolean authenticated = false;
136
    String identifier = user;
137
    
138
    //get uid here.
139
    if (user.indexOf(",") == -1) {
140
    	throw new ConnectException("Invalid LDAP user credential: " + user + ".  Missing ','");
141
    }
142
    String uid=user.substring(0, user.indexOf(","));
143
    user = user.substring(user.indexOf(","), user.length());
144 130

  
145
    logMetacat.debug("identifier: " + identifier);
146
    logMetacat.debug("uid: " + uid);
147
    logMetacat.debug("user: " + user);
148
    
149
    try {
150
    	// Check the usename as passed in
151
        logMetacat.info("Calling ldapAuthenticate");
152
        logMetacat.info("with user as identifier: " + identifier);
131
	public boolean authenticate(String user, String password) throws ConnectException {
132
		String ldapUrl = this.ldapUrl;
133
		String ldapsUrl = this.ldapsUrl;
134
		String ldapBase = this.ldapBase;
135
		boolean authenticated = false;
136
		String identifier = user;
153 137

  
154
        authenticated = ldapAuthenticate(identifier, password, 
155
        		(new Boolean(PropertyService.getProperty("ldap.onlySecureConnection"))).booleanValue());
156
        // if not found, try looking up a valid DN then auth again
157
        if (!authenticated) {
158
        	logMetacat.info("Not Authenticated");
159
        	logMetacat.info("Looking up DN for: " + identifier);
160
        	identifier = getIdentifyingName(identifier, ldapUrl, ldapBase);
161
        	if(identifier == null){
162
        		logMetacat.info("No DN found from getIdentifyingName");
163
        		return authenticated;
164
        	}
165
        	
166
           	logMetacat.info("DN found from getIdentifyingName: " + identifier);
167
        	String decoded = URLDecoder.decode(identifier);
168
        	logMetacat.info("DN decoded: " + decoded);
169
        	identifier = decoded;
170
        	String refUrl = "";
171
        	String refBase = "";
172
        	if (identifier.startsWith("ldap")) {
173
        		logMetacat.debug("identifier starts with \"ldap\"");
138
		// get uid here.
139
		if (user.indexOf(",") == -1) {
140
			throw new ConnectException("Invalid LDAP user credential: " + user
141
					+ ".  Missing ','");
142
		}
143
		String uid = user.substring(0, user.indexOf(","));
144
		user = user.substring(user.indexOf(","), user.length());
174 145

  
175
        		refUrl = identifier.substring(0, identifier.lastIndexOf("/") + 1);
176
        		int position = identifier.indexOf(",");
177
        		int position2 = identifier.indexOf(",", position + 1);
178
        		
179
        		refBase = identifier.substring(position2 + 1);
180
        		identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
181
        		
182
        		logMetacat.info("Calling ldapAuthenticate:");
183
        		logMetacat.info("with user as identifier: " + identifier);
184
        		logMetacat.info("and refUrl as: " + refUrl);
185
        		logMetacat.info("and refBase as: " + refBase);
146
		logMetacat.debug("identifier: " + identifier);
147
		logMetacat.debug("uid: " + uid);
148
		logMetacat.debug("user: " + user);
186 149

  
187
        		authenticated = ldapAuthenticate(identifier, password, refUrl, refBase,
188
                		(new Boolean(PropertyService.getProperty("ldap.onlySecureReferalsConnection")))
189
                			.booleanValue());
190
        	} else {
191
        		logMetacat.info("identifier doesnt start with ldap");
192
        		identifier = identifier + "," + ldapBase;
193
        		
194
        		logMetacat.info("Calling ldapAuthenticate");
195
        		logMetacat.info("with user as identifier: " + identifier);
196
        		
197
        		authenticated = ldapAuthenticate(identifier, password,
198
            		(new Boolean(PropertyService.getProperty("ldap.onlySecureConnection"))).booleanValue());
199
        	}
200
        }
201
    } catch (NullPointerException e) {
202
    	logMetacat.error("NullPointerException while authenticating in " +
203
                        "AuthLdap.authenticate: " + e);
204
    	e.printStackTrace();
150
		try {
151
			// Check the usename as passed in
152
			logMetacat.info("Calling ldapAuthenticate");
153
			logMetacat.info("with user as identifier: " + identifier);
205 154

  
206
    	throw new ConnectException(
207
          "NullPointerException while authenticating in " +
208
          "AuthLdap.authenticate: " + e);
209
    } catch (NamingException e) {
210
    	logMetacat.error("Naming exception while authenticating in " +
211
                        "AuthLdap.authenticate: " + e);
212
    	e.printStackTrace();
213
    } catch (Exception e) {
214
    	logMetacat.error(e.getMessage());
215
    }
216
    
217
    return authenticated;
218
  }
155
			authenticated = ldapAuthenticate(identifier, password, (new Boolean(
156
					PropertyService.getProperty("ldap.onlySecureConnection")))
157
					.booleanValue());
158
			// if not found, try looking up a valid DN then auth again
159
			if (!authenticated) {
160
				logMetacat.info("Not Authenticated");
161
				logMetacat.info("Looking up DN for: " + identifier);
162
				identifier = getIdentifyingName(identifier, ldapUrl, ldapBase);
163
				if (identifier == null) {
164
					logMetacat.info("No DN found from getIdentifyingName");
165
					return authenticated;
166
				}
219 167

  
220
  /**
221
   * Connect to the LDAP directory and do the authentication using the
222
   * username and password as passed into the routine.
223
   *
224
   * @param identifier the distinguished name to check against LDAP
225
   * @param password the password for authentication
226
   */
227
  private boolean ldapAuthenticate(String identifier, String password, boolean 
228
    secureConnectionOnly) throws ConnectException, NamingException, 
229
    NullPointerException {
230
    return ldapAuthenticate(identifier, password,
231
                            this.ldapsUrl, this.ldapBase, secureConnectionOnly);
232
  }
168
				logMetacat.info("DN found from getIdentifyingName: " + identifier);
169
				String decoded = URLDecoder.decode(identifier);
170
				logMetacat.info("DN decoded: " + decoded);
171
				identifier = decoded;
172
				String refUrl = "";
173
				String refBase = "";
174
				if (identifier.startsWith("ldap")) {
175
					logMetacat.debug("identifier starts with \"ldap\"");
233 176

  
234
  /**
235
   * Connect to the LDAP directory and do the authentication using the
236
   * username and password as passed into the routine.
237
   *
238
   * @param identifier the distinguished name to check against LDAP
239
   * @param password the password for authentication
240
   */
241
  
242
  private boolean ldapAuthenticate(String dn, String password, 
243
    String rootServer, String rootBase, boolean secureConnectionOnly){
244
	  
245
	  boolean authenticated = false;
246
		
247
	  String server = "";
248
	  String userDN = "";
249
	  logMetacat.info("dn is: " + dn);
177
					refUrl = identifier.substring(0, identifier.lastIndexOf("/") + 1);
178
					int position = identifier.indexOf(",");
179
					int position2 = identifier.indexOf(",", position + 1);
250 180

  
251
	  int position = dn.lastIndexOf("/");
252
      logMetacat.debug("position is: " + position);
253
	  if (position == -1) {
254
		  server = rootServer;
255
		  if(dn.indexOf(userDN) < 0){
256
			  userDN = dn + "," + rootBase;
257
		  } else {
258
			  userDN = dn;
259
		  }
260
		  logMetacat.info("userDN is: " + userDN);
181
					refBase = identifier.substring(position2 + 1);
182
					identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
261 183

  
262
       } else {
263
		  server = dn.substring(0, position+1);
264
		  userDN = dn.substring(position+1);
265
		  logMetacat.info("server is: " + server);
266
		  logMetacat.info("userDN is: " + userDN);
267
	   }
268
		          
269
	   logMetacat.warn("Trying to authenticate: " + userDN);
270
	   logMetacat.warn("          Using server: " + server);
271
		          
272
	   LdapContext ctx = null;
273
	   double startTime;
274
	   double stopTime;
275
	   try 
276
     {
277
		   Hashtable env = new Hashtable();
278
		   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
279
		   env.put(Context.PROVIDER_URL, server);
280
		   env.put(Context.REFERRAL, "throw");
281
		   try 
282
       {
283
			   
284
			   startTime = System.currentTimeMillis();
285
			   ctx = new InitialLdapContext(env, null);
286
			   // Start up TLS here so that we don't pass our jewels in cleartext
287
		       StartTlsResponse tls =
288
		              (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
289
		       //tls.setHostnameVerifier(new SampleVerifier());
290
		       SSLSession sess = tls.negotiate();
291
		       ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
292
			   ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
293
			   ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
294
			   ctx.reconnect(null);
295
			   stopTime = System.currentTimeMillis();
296
			   logMetacat.info("Connection time thru " + ldapsUrl + " was: " +
297
                       	(stopTime - startTime) / 1000 + " seconds.");
298
			   authenticated = true;
299
		   } 
300
       catch (Exception ioe) 
301
       {
302
			   logMetacat.info("Caught IOException in login while negotiating TLS: "
303
	                                 + ioe.getMessage());
304
			   
305
			   if(secureConnectionOnly)
306
         {
307
				   return authenticated;
308
			   
309
			   } 
310
         else 
311
         {
312
				   logMetacat.info("Trying to authenticate without TLS");
313
				   env.put(Context.SECURITY_AUTHENTICATION, "simple");
314
				   env.put(Context.SECURITY_PRINCIPAL, userDN);
315
				   env.put(Context.SECURITY_CREDENTIALS, password);
316
				   
317
				   startTime = System.currentTimeMillis();
318
				   ctx = new InitialLdapContext(env, null);				
319
				   stopTime = System.currentTimeMillis();
320
				   logMetacat.info("Connection time thru " + ldapsUrl + " was: " +
321
	                       	(stopTime - startTime) / 1000 + " seconds.");
322
				   authenticated = true;
323
			   }
324
		   }
325
	   } 
326
     catch (AuthenticationException ae) 
327
     {
328
		   authenticated = false;
329
	   } 
330
     catch (javax.naming.InvalidNameException ine) 
331
     {
332
	        logMetacat.error("An invalid DN was provided!");
333
	   } 
334
     catch (NamingException e) 
335
     {
336
		   logMetacat.warn("Caught NamingException in login: " + e.getClass().getName());
337
		   logMetacat.info(e.toString() + "  " + e.getRootCause());
338
     }
184
					logMetacat.info("Calling ldapAuthenticate:");
185
					logMetacat.info("with user as identifier: " + identifier);
186
					logMetacat.info("and refUrl as: " + refUrl);
187
					logMetacat.info("and refBase as: " + refBase);
339 188

  
340
       return authenticated;
341
  }
189
					authenticated = ldapAuthenticate(identifier, password, refUrl,
190
							refBase, (new Boolean(PropertyService
191
									.getProperty("ldap.onlySecureReferalsConnection")))
192
									.booleanValue());
193
				} else {
194
					logMetacat.info("identifier doesnt start with ldap");
195
					identifier = identifier + "," + ldapBase;
342 196

  
197
					logMetacat.info("Calling ldapAuthenticate");
198
					logMetacat.info("with user as identifier: " + identifier);
343 199

  
344
  /**
345
   * Get the identifying name for a given userid or name.  This is the name
346
   * that is used in conjunction withthe LDAP BaseDN to create a
347
   * distinguished name (dn) for the record
348
   *
349
   * @param user the user for which the identifying name is requested
350
   * @returns String the identifying name for the user,
351
   *          or null if not found
352
   */
353
  private String getIdentifyingName(String user, String ldapUrl, 
354
    String ldapBase) throws NamingException {
355
	  
356
      String identifier = null;
357
      Hashtable env = new Hashtable();
358
      env.put(Context.INITIAL_CONTEXT_FACTORY,
359
              "com.sun.jndi.ldap.LdapCtxFactory");
360
      env.put(Context.REFERRAL, "throw");
361
      env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
362
      try {
363
    	  int position = user.indexOf(",");
364
          String uid = user.substring(user.indexOf("=") + 1, position);
365
          logMetacat.info("uid is: " + uid);
366
          String org = user.substring(user.indexOf("=", position + 1) + 1,
367
                                        user.indexOf(",", position + 1));
368
          logMetacat.info("org is: " + org);
369
           
370
          DirContext sctx = new InitialDirContext(env);
371
          SearchControls ctls = new SearchControls();
372
          ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
373
          String filter = "(&(uid=" + uid + ")(o=" + org + "))";
374
          logMetacat.warn("Searching for DNs with following filter: " + filter);
375
          
376
          for (boolean moreReferrals = true; moreReferrals;) {
377
              try {
378
                  // Perform the search
379
                  NamingEnumeration answer = 
380
                      sctx.search("", filter, ctls);
200
					authenticated = ldapAuthenticate(identifier, password, (new Boolean(
201
							PropertyService.getProperty("ldap.onlySecureConnection")))
202
							.booleanValue());
203
				}
204
			}
205
		} catch (NullPointerException e) {
206
			logMetacat.error("NullPointerException while authenticating in "
207
					+ "AuthLdap.authenticate: " + e);
208
			e.printStackTrace();
381 209

  
382
                  // Return the answer
383
                  while (answer.hasMore()) {
384
                      SearchResult sr = (SearchResult)answer.next();
385
                      identifier = sr.getName();
386
                      return identifier;
387
                  }
388
                  // The search completes with no more referrals
389
                  moreReferrals = false;
390
              } catch (ReferralException e) {
391
            	  logMetacat.info("Got referral: " + e.getReferralInfo());
392
            	  // Point to the new context from the referral
393
                  if (moreReferrals) {
394
                      sctx = (DirContext) e.getReferralContext();
395
                  }
396
              }
397
          }
398
      } catch (NamingException e) {
399
    	     logMetacat.error("Naming exception while getting dn: " + e);
400
    	      throw new NamingException(
401
    	          "Naming exception in AuthLdap.getIdentifyingName: " + e);
402
    	      }
403
      return identifier;
404
  }
405
  
406
  /**
407
   * Get all users from the authentication service
408
   *
409
   * @param user the user for authenticating against the service
410
   * @param password the password for authenticating against the service
411
   * @returns string array of all of the user names
412
   */
413
  public String[][] getUsers(String user, String password) throws 
414
    ConnectException {
415
    String[][] users = null;
210
			throw new ConnectException("NullPointerException while authenticating in "
211
					+ "AuthLdap.authenticate: " + e);
212
		} catch (NamingException e) {
213
			logMetacat.error("Naming exception while authenticating in "
214
					+ "AuthLdap.authenticate: " + e);
215
			e.printStackTrace();
216
		} catch (Exception e) {
217
			logMetacat.error(e.getMessage());
218
		}
416 219

  
417
    // Identify service provider to use
418
    Hashtable env = new Hashtable(11);
419
    env.put(Context.INITIAL_CONTEXT_FACTORY,
420
            "com.sun.jndi.ldap.LdapCtxFactory");
421
    env.put(Context.REFERRAL, referral);
422
    env.put(Context.PROVIDER_URL, ldapUrl);
423
    env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
220
		return authenticated;
221
	}
424 222

  
425
    try {
223
	/**
224
	 * Connect to the LDAP directory and do the authentication using the
225
	 * username and password as passed into the routine.
226
	 * 
227
	 * @param identifier
228
	 *            the distinguished name to check against LDAP
229
	 * @param password
230
	 *            the password for authentication
231
	 */
232
	private boolean ldapAuthenticate(String identifier, String password,
233
			boolean secureConnectionOnly) throws ConnectException, NamingException,
234
			NullPointerException {
235
		return ldapAuthenticate(identifier, password, this.ldapsUrl, this.ldapBase,
236
				secureConnectionOnly);
237
	}
426 238

  
427
      // Create the initial directory context
428
      DirContext ctx = new InitialDirContext(env);
239
	/**
240
	 * Connect to the LDAP directory and do the authentication using the
241
	 * username and password as passed into the routine.
242
	 * 
243
	 * @param identifier
244
	 *            the distinguished name to check against LDAP
245
	 * @param password
246
	 *            the password for authentication
247
	 */
429 248

  
430
      // Specify the attributes to match.
431
      // Users are objects that have the attribute objectclass=InetOrgPerson.
432
      SearchControls ctls = new SearchControls();
433
      String[] attrIDs = {
434
          "dn", "cn", "o", "ou", "mail"};
435
      ctls.setReturningAttributes(attrIDs);
436
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
437
      ctls.setTimeLimit(ldapSearchTimeLimit);
438
      //ctls.setCountLimit(1000);
439
      String filter = "(objectClass=inetOrgPerson)";
440
      NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
249
	private boolean ldapAuthenticate(String dn, String password, String rootServer,
250
			String rootBase, boolean secureConnectionOnly) {
441 251

  
442
      // Store the users in a vector
443
      Vector uvec = new Vector();
444
      Vector uname = new Vector();
445
      Vector uorg = new Vector();
446
      Vector uou = new Vector();
447
      Vector umail = new Vector();
448
      Attributes tempAttr = null;
449
      try {
450
        while (namingEnum.hasMore()) {
451
          SearchResult sr = (SearchResult) namingEnum.next();
452
          tempAttr = sr.getAttributes();
252
		boolean authenticated = false;
453 253

  
454
          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
455
            uname.add( (tempAttr.get("cn") + "").substring(4));
456
          }
457
          else {
458
            uname.add(tempAttr.get("cn") + "");
459
          }
254
		String server = "";
255
		String userDN = "";
256
		logMetacat.info("dn is: " + dn);
460 257

  
461
          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
462
            uorg.add( (tempAttr.get("o") + "").substring(3));
463
          }
464
          else {
465
            uorg.add(tempAttr.get("o") + "");
466
          }
258
		int position = dn.lastIndexOf("/");
259
		logMetacat.debug("position is: " + position);
260
		if (position == -1) {
261
			server = rootServer;
262
			if (dn.indexOf(userDN) < 0) {
263
				userDN = dn + "," + rootBase;
264
			} else {
265
				userDN = dn;
266
			}
267
			logMetacat.info("userDN is: " + userDN);
467 268

  
468
          if ( (tempAttr.get("ou") + "").startsWith("ou: ")) {
469
            uou.add( (tempAttr.get("ou") + "").substring(4));
470
          }
471
          else {
472
            uou.add(tempAttr.get("ou") + "");
473
          }
269
		} else {
270
			server = dn.substring(0, position + 1);
271
			userDN = dn.substring(position + 1);
272
			logMetacat.info("server is: " + server);
273
			logMetacat.info("userDN is: " + userDN);
274
		}
474 275

  
475
          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
476
            umail.add( (tempAttr.get("mail") + "").substring(6));
477
          }
478
          else {
479
            umail.add(tempAttr.get("mail") + "");
480
          }
276
		logMetacat.warn("Trying to authenticate: " + userDN);
277
		logMetacat.warn("          Using server: " + server);
481 278

  
482
          uvec.add(sr.getName() + "," + ldapBase);
483
        }
484
      }
485
      catch (SizeLimitExceededException slee) {
486
        logMetacat.error("LDAP Server size limit exceeded. " +
487
                          "Returning incomplete record set.");
488
      }
279
		LdapContext ctx = null;
280
		double startTime;
281
		double stopTime;
282
		try {
283
			Hashtable env = new Hashtable();
284
			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
285
			env.put(Context.PROVIDER_URL, server);
286
			env.put(Context.REFERRAL, "throw");
287
			try {
489 288

  
490
      // initialize users[]; fill users[]
491
      users = new String[uvec.size()][5];
492
      for (int i = 0; i < uvec.size(); i++) {
493
        users[i][0] = (String) uvec.elementAt(i);
494
        users[i][1] = (String) uname.elementAt(i);
495
        users[i][2] = (String) uorg.elementAt(i);
496
        users[i][3] = (String) uorg.elementAt(i);
497
        users[i][4] = (String) umail.elementAt(i);
498
      }
289
				startTime = System.currentTimeMillis();
290
				ctx = new InitialLdapContext(env, null);
291
				// Start up TLS here so that we don't pass our jewels in
292
				// cleartext
293
				StartTlsResponse tls = (StartTlsResponse) ctx
294
						.extendedOperation(new StartTlsRequest());
295
				// tls.setHostnameVerifier(new SampleVerifier());
296
				SSLSession sess = tls.negotiate();
297
				ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
298
				ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
299
				ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
300
				ctx.reconnect(null);
301
				stopTime = System.currentTimeMillis();
302
				logMetacat.info("Connection time thru " + ldapsUrl + " was: "
303
						+ (stopTime - startTime) / 1000 + " seconds.");
304
				authenticated = true;
305
			} catch (Exception ioe) {
306
				logMetacat.info("Caught IOException in login while negotiating TLS: "
307
						+ ioe.getMessage());
499 308

  
500
      // Close the context when we're done
501
      ctx.close();
309
				if (secureConnectionOnly) {
310
					return authenticated;
502 311

  
503
    }
504
    catch (NamingException e) {
505
      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
506
      //e.printStackTrace(System.err);
507
     /* throw new ConnectException(
508
          "Problem getting users in AuthLdap.getUsers:" + e);*/
509
    }
312
				} else {
313
					logMetacat.info("Trying to authenticate without TLS");
314
					env.put(Context.SECURITY_AUTHENTICATION, "simple");
315
					env.put(Context.SECURITY_PRINCIPAL, userDN);
316
					env.put(Context.SECURITY_CREDENTIALS, password);
510 317

  
511
    return users;
512
  }
318
					startTime = System.currentTimeMillis();
319
					ctx = new InitialLdapContext(env, null);
320
					stopTime = System.currentTimeMillis();
321
					logMetacat.info("Connection time thru " + ldapsUrl + " was: "
322
							+ (stopTime - startTime) / 1000 + " seconds.");
323
					authenticated = true;
324
				}
325
			}
326
		} catch (AuthenticationException ae) {
327
			authenticated = false;
328
		} catch (javax.naming.InvalidNameException ine) {
329
			logMetacat.error("An invalid DN was provided!");
330
		} catch (NamingException e) {
331
			logMetacat.warn("Caught NamingException in login: " + e.getClass().getName());
332
			logMetacat.info(e.toString() + "  " + e.getRootCause());
333
		}
513 334

  
514
  
515
  /**
516
   * Get all users from the authentication service
517
   *
518
   * @param user the user for authenticating against the service
519
   * @param password the password for authenticating against the service
520
   * @returns string array of all of the user names
521
   */
522
  public String[] getUserInfo(String user, String password) throws 
523
    ConnectException {
524
    String[] userinfo = new String[3];
335
		return authenticated;
336
	}
525 337

  
526
    // Identify service provider to use
527
    Hashtable env = new Hashtable(11);
528
    env.put(Context.INITIAL_CONTEXT_FACTORY,
529
            "com.sun.jndi.ldap.LdapCtxFactory");
530
    env.put(Context.REFERRAL, referral);
531
    env.put(Context.PROVIDER_URL, ldapUrl);
338
	/**
339
	 * Get the identifying name for a given userid or name. This is the name
340
	 * that is used in conjunction withthe LDAP BaseDN to create a distinguished
341
	 * name (dn) for the record
342
	 * 
343
	 * @param user
344
	 *            the user for which the identifying name is requested
345
	 * @returns String the identifying name for the user, or null if not found
346
	 */
347
	private String getIdentifyingName(String user, String ldapUrl, String ldapBase)
348
			throws NamingException {
532 349

  
533
    try {
534
      
535
      // Create the initial directory context
536
      DirContext ctx = new InitialDirContext(env);
537
      // Specify the attributes to match.
538
      // Users are objects that have the attribute objectclass=InetOrgPerson.
539
      SearchControls ctls = new SearchControls();
540
      String[] attrIDs = {
541
          "cn", "o", "mail"};
542
      ctls.setReturningAttributes(attrIDs);
543
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
544
      //ctls.setCountLimit(1000);
545
      // create the filter based on the uid
546
      
547
      String filter = null;
548
      
549
      if(user.indexOf("o=")>0){
550
    	  String tempStr = user.substring(user.indexOf("o="));
551
    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
552
			+ ")(" + tempStr.substring(0, tempStr.indexOf(",")) 
553
			+ "))";      
554
      } else{
555
    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
556
			+ "))";          		  
557
      }
558
   	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
559
		+ "))";          		  
350
		String identifier = null;
351
		Hashtable env = new Hashtable();
352
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
353
		env.put(Context.REFERRAL, "throw");
354
		env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
355
		try {
356
			int position = user.indexOf(",");
357
			String uid = user.substring(user.indexOf("=") + 1, position);
358
			logMetacat.info("uid is: " + uid);
359
			String org = user.substring(user.indexOf("=", position + 1) + 1, user
360
					.indexOf(",", position + 1));
361
			logMetacat.info("org is: " + org);
560 362

  
561
      NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
562
      
563
      Attributes tempAttr = null;
564
      try {
565
        while (namingEnum.hasMore()) {
566
          SearchResult sr = (SearchResult) namingEnum.next();
567
          tempAttr = sr.getAttributes();
363
			DirContext sctx = new InitialDirContext(env);
364
			SearchControls ctls = new SearchControls();
365
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
366
			String filter = "(&(uid=" + uid + ")(o=" + org + "))";
367
			logMetacat.warn("Searching for DNs with following filter: " + filter);
568 368

  
569
          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
570
        	  userinfo[0] = (tempAttr.get("cn") + "").substring(4);
571
          }
572
          else {
573
        	  userinfo[0] = (tempAttr.get("cn") + "");
574
          }
369
			for (boolean moreReferrals = true; moreReferrals;) {
370
				try {
371
					// Perform the search
372
					NamingEnumeration answer = sctx.search("", filter, ctls);
575 373

  
576
          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
577
        	  userinfo[1] = (tempAttr.get("o") + "").substring(3);
578
          }
579
          else {
580
        	  userinfo[1] = (tempAttr.get("o") + "");
581
          }
374
					// Return the answer
375
					while (answer.hasMore()) {
376
						SearchResult sr = (SearchResult) answer.next();
377
						identifier = sr.getName();
378
						return identifier;
379
					}
380
					// The search completes with no more referrals
381
					moreReferrals = false;
382
				} catch (ReferralException e) {
383
					logMetacat.info("Got referral: " + e.getReferralInfo());
384
					// Point to the new context from the referral
385
					if (moreReferrals) {
386
						sctx = (DirContext) e.getReferralContext();
387
					}
388
				}
389
			}
390
		} catch (NamingException e) {
391
			logMetacat.error("Naming exception while getting dn: " + e);
392
			throw new NamingException("Naming exception in AuthLdap.getIdentifyingName: "
393
					+ e);
394
		}
395
		return identifier;
396
	}
582 397

  
583
          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
584
        	  userinfo[2] =  (tempAttr.get("mail") + "").substring(6);
585
          }
586
          else {
587
        	  userinfo[2] = (tempAttr.get("mail") + "");
588
          }
589
        }
590
      }
591
      catch (SizeLimitExceededException slee) {
592
        logMetacat.error("LDAP Server size limit exceeded. " +
593
                          "Returning incomplete record set.");
594
      }
398
	/**
399
	 * Get all users from the authentication service
400
	 * 
401
	 * @param user
402
	 *            the user for authenticating against the service
403
	 * @param password
404
	 *            the password for authenticating against the service
405
	 * @returns string array of all of the user names
406
	 */
407
	public String[][] getUsers(String user, String password) throws ConnectException {
408
		String[][] users = null;
595 409

  
596
      // Close the context when we're done
597
      ctx.close();
410
		// Identify service provider to use
411
		Hashtable env = new Hashtable(11);
412
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
413
		env.put(Context.REFERRAL, referral);
414
		env.put(Context.PROVIDER_URL, ldapUrl);
415
		env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
598 416

  
599
    }
600
    catch (NamingException e) {
601
      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
602
      //e.printStackTrace(System.err);
603
      throw new ConnectException(
604
          "Problem getting users in AuthLdap.getUsers:" + e);
605
    }
417
		try {
606 418

  
607
    return userinfo;
608
  }
419
			// Create the initial directory context
420
			DirContext ctx = new InitialDirContext(env);
609 421

  
610
  /**
611
   * Get the users for a particular group from the authentication service
612
   *
613
   * @param user the user for authenticating against the service
614
   * @param password the password for authenticating against the service
615
   * @param group the group whose user list should be returned
616
   * @returns string array of the user names belonging to the group
617
   */
618
  public String[] getUsers(String user, String password, String group) throws 
619
    ConnectException {
620
    String[] users = null;
422
			// Specify the attributes to match.
423
			// Users are objects that have the attribute
424
			// objectclass=InetOrgPerson.
425
			SearchControls ctls = new SearchControls();
426
			String[] attrIDs = { "dn", "cn", "o", "ou", "mail" };
427
			ctls.setReturningAttributes(attrIDs);
428
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
429
			ctls.setTimeLimit(ldapSearchTimeLimit);
430
			// ctls.setCountLimit(1000);
431
			String filter = "(objectClass=inetOrgPerson)";
432
			NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
621 433

  
622
    // Identify service provider to use
623
    Hashtable env = new Hashtable(11);
624
    env.put(Context.INITIAL_CONTEXT_FACTORY,
625
            "com.sun.jndi.ldap.LdapCtxFactory");
626
    env.put(Context.REFERRAL, referral);
627
    env.put(Context.PROVIDER_URL, ldapUrl);
434
			// Store the users in a vector
435
			Vector uvec = new Vector();
436
			Vector uname = new Vector();
437
			Vector uorg = new Vector();
438
			Vector uou = new Vector();
439
			Vector umail = new Vector();
440
			Attributes tempAttr = null;
441
			try {
442
				while (namingEnum.hasMore()) {
443
					SearchResult sr = (SearchResult) namingEnum.next();
444
					tempAttr = sr.getAttributes();
628 445

  
629
    try {
446
					if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
447
						uname.add((tempAttr.get("cn") + "").substring(4));
448
					} else {
449
						uname.add(tempAttr.get("cn") + "");
450
					}
630 451

  
631
      // Create the initial directory context
632
      DirContext ctx = new InitialDirContext(env);
452
					if ((tempAttr.get("o") + "").startsWith("o: ")) {
453
						uorg.add((tempAttr.get("o") + "").substring(3));
454
					} else {
455
						uorg.add(tempAttr.get("o") + "");
456
					}
633 457

  
634
      // Specify the ids of the attributes to return
635
      String[] attrIDs = {
636
          "uniqueMember"};
458
					if ((tempAttr.get("ou") + "").startsWith("ou: ")) {
459
						uou.add((tempAttr.get("ou") + "").substring(4));
460
					} else {
461
						uou.add(tempAttr.get("ou") + "");
462
					}
637 463

  
638
      Attributes answer = ctx.getAttributes(group, attrIDs);
464
					if ((tempAttr.get("mail") + "").startsWith("mail: ")) {
465
						umail.add((tempAttr.get("mail") + "").substring(6));
466
					} else {
467
						umail.add(tempAttr.get("mail") + "");
468
					}
639 469

  
640
      Vector uvec = new Vector();
641
      try {
642
        for (NamingEnumeration ae = answer.getAll(); ae.hasMore(); ) {
643
          Attribute attr = (Attribute) ae.next();
644
          for (NamingEnumeration e = attr.getAll();
645
               e.hasMore();
646
               uvec.add(e.next())
647
               ) {
648
            ;
649
          }
650
        }
651
      }
652
      catch (SizeLimitExceededException slee) {
653
        logMetacat.error("LDAP Server size limit exceeded. " +
654
                          "Returning incomplete record set.");
655
      }
470
					uvec.add(sr.getName() + "," + ldapBase);
471
				}
472
			} catch (SizeLimitExceededException slee) {
473
				logMetacat.error("LDAP Server size limit exceeded. "
474
						+ "Returning incomplete record set.");
475
			}
656 476

  
657
      // initialize users[]; fill users[]
658
      users = new String[uvec.size()];
659
      for (int i = 0; i < uvec.size(); i++) {
660
        users[i] = (String) uvec.elementAt(i);
661
      }
477
			// initialize users[]; fill users[]
478
			users = new String[uvec.size()][5];
479
			for (int i = 0; i < uvec.size(); i++) {
480
				users[i][0] = (String) uvec.elementAt(i);
481
				users[i][1] = (String) uname.elementAt(i);
482
				users[i][2] = (String) uorg.elementAt(i);
483
				users[i][3] = (String) uorg.elementAt(i);
484
				users[i][4] = (String) umail.elementAt(i);
485
			}
662 486

  
663
      // Close the context when we're done
664
      ctx.close();
487
			// Close the context when we're done
488
			ctx.close();
665 489

  
666
    }
667
    catch (NamingException e) {
668
      logMetacat.error("Problem getting users for a group in " +
669
                        "AuthLdap.getUsers:" + e);
670
      /*throw new ConnectException(
671
          "Problem getting users for a group in AuthLdap.getUsers:" + e);*/
672
    }
490
		} catch (NamingException e) {
491
			logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
492
			// e.printStackTrace(System.err);
493
			/*
494
			 * throw new ConnectException( "Problem getting users in
495
			 * AuthLdap.getUsers:" + e);
496
			 */
497
		}
673 498

  
674
    return users;
675
  }
499
		return users;
500
	}
676 501

  
677
  /**
678
   * Get all groups from the authentication service
679
   *
680
   * @param user the user for authenticating against the service
681
   * @param password the password for authenticating against the service
682
   * @returns string array of the group names
683
   */
684
  public String[][] getGroups(String user, String password) throws 
685
    ConnectException {
686
    return getGroups(user, password, null);
687
  }
502
	/**
503
	 * Get all users from the authentication service
504
	 * 
505
	 * @param user
506
	 *            the user for authenticating against the service
507
	 * @param password
508
	 *            the password for authenticating against the service
509
	 * @returns string array of all of the user names
510
	 */
511
	public String[] getUserInfo(String user, String password) throws ConnectException {
512
		String[] userinfo = new String[3];
688 513

  
689
  /**
690
   * Get the groups for a particular user from the authentication service
691
   *
692
   * @param user the user for authenticating against the service
693
   * @param password the password for authenticating against the service
694
   * @param foruser the user whose group list should be returned
695
   * @returns string array of the group names
696
   */
697
  public String[][] getGroups(String user, String password, 
698
    String foruser) throws ConnectException {
699
    
700
    logMetacat.debug("getGroups() called.");
701
    
702
    // create vectors to store group and dscription values returned from the
703
    // ldap servers
704
    Vector gvec = new Vector();
705
    Vector desc = new Vector();
706
    Attributes tempAttr = null;
707
    Attributes rsrAttr = null;
708
    
709
    // DURING getGroups(), DO WE NOT BIND USING userName AND userPassword??
710
    // NEED TO FIX THIS ...
711
    userName = user;
712
    userPassword = password;
713
    // Identify service provider to use
714
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
715
    env.put(Context.REFERRAL, "throw");
716
    env.put(Context.PROVIDER_URL, ldapUrl);
717
    env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
718
    
719
        
720
    // Iterate through the referrals, handling NamingExceptions in the 
721
    // outer catch statement, ReferralExceptions in the inner catch statement
722
    try { // outer try
723
       
724
      // Create the initial directory context
725
      DirContext ctx = new InitialDirContext(env);
726
      
727
      // Specify the attributes to match.
728
      // Groups are objects with attribute objectclass=groupofuniquenames.
729
      // and have attribute uniquemember: uid=foruser,ldapbase.
730
      SearchControls ctls = new SearchControls();
731
      // Specify the ids of the attributes to return
732
      String[] attrIDs = {"cn", "o", "description"};
733
      ctls.setReturningAttributes(attrIDs);
734
      // set the ldap search scope
735
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
736
      // set a 10 second time limit on searches to limit non-responding servers
737
      ctls.setTimeLimit(ldapSearchTimeLimit);
738
      // return at most 20000 entries
739
      ctls.setCountLimit(ldapSearchCountLimit);
514
		// Identify service provider to use
515
		Hashtable env = new Hashtable(11);
516
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
517
		env.put(Context.REFERRAL, referral);
518
		env.put(Context.PROVIDER_URL, ldapUrl);
740 519

  
741
      // build the ldap search filter that represents the "group" concept
742
      String filter = null;
743
      String gfilter = "(objectClass=groupOfUniqueNames)";
744
      if (null == foruser) {
745
        filter = gfilter;
746
      } else {
747
        filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
748
      }
749
      logMetacat.info("group filter is: " + filter);
750
      
751
      // now, search and iterate through the referrals
752
      for (boolean moreReferrals = true; moreReferrals;) {  
753
        try { // inner try
754
      
755
          NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
520
		try {
756 521

  
757
          // Print the groups
758
          while (namingEnum.hasMore()) {
759
            SearchResult sr = (SearchResult) namingEnum.next();
760
            
761
            tempAttr = sr.getAttributes();
522
			// Create the initial directory context
523
			DirContext ctx = new InitialDirContext(env);
524
			// Specify the attributes to match.
525
			// Users are objects that have the attribute
526
			// objectclass=InetOrgPerson.
527
			SearchControls ctls = new SearchControls();
528
			String[] attrIDs = { "cn", "o", "mail" };
529
			ctls.setReturningAttributes(attrIDs);
530
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
531
			// ctls.setCountLimit(1000);
532
			// create the filter based on the uid
762 533

  
763
            if ( (tempAttr.get("description") + "").startsWith("description: ")) {
764
              desc.add( (tempAttr.get("description") + "").substring(13));
765
            }
766
            else {
767
              desc.add(tempAttr.get("description") + "");
768
            }
769
            
770
            // check for an absolute URL value or an answer value relative 
771
            // to the target context  
772
            if ( !sr.getName().startsWith("ldap") &&
773
                  sr.isRelative()) {
774
              logMetacat.debug("Search result entry is relative ...");
775
              gvec.add(sr.getName() + "," + ldapBase);
776
              logMetacat.info("group " + sr.getName() + "," +ldapBase + 
777
              " added to the group vector"); 
778
            } else {
779
              logMetacat.debug("Search result entry is absolute ...");
780
              
781
              // search the top level directory for referral objects and match
782
              // that of the search result's absolute URL.  This will let us
783
              // rebuild the group name from the search result, referral point
784
              // in the top directory tree, and ldapBase.
785
              
786
              // configure a new directory search first
787
              Hashtable envHash = new Hashtable(11);
788
              // Identify service provider to use
789
              envHash.put(Context.INITIAL_CONTEXT_FACTORY, 
790
                "com.sun.jndi.ldap.LdapCtxFactory");
791
              envHash.put(Context.REFERRAL, "ignore");
792
              envHash.put(Context.PROVIDER_URL, ldapUrl);
793
              envHash.put("com.sun.jndi.ldap.connect.timeout", 
794
                ldapConnectTimeLimit);
795
              
796
              try {
797
                // Create the initial directory context
798
                DirContext DirCtx = new InitialDirContext(envHash);
534
			String filter = null;
799 535

  
800
                SearchControls searchCtls = new SearchControls();
801
                // Specify the ids of the attributes to return
802
                String[] attrNames = {"o"};
803
                searchCtls.setReturningAttributes(attrNames);
804
                // set the ldap search scope - only look for top level referrals
805
                searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
806
                // set a time limit on searches to limit non-responding servers
807
                searchCtls.setTimeLimit(ldapSearchTimeLimit);
808
                // return the configured number of entries
809
                searchCtls.setCountLimit(ldapSearchCountLimit);
810
                
811
                // Specify the attributes to match.
812
                // build the ldap search filter to match referral entries that 
813
                // match the search result
814
                String rFilter = "(&(objectClass=referral)(ref=" + 
815
                currentReferralInfo.substring(0, 
816
                currentReferralInfo.indexOf("?")) + "))";
817
                logMetacat.debug("rFilter is: " + rFilter);
818
                
819
                NamingEnumeration rNamingEnum = 
820
                  DirCtx.search(ldapBase, rFilter, searchCtls);
821
                  
822
                while (rNamingEnum.hasMore()) {
823
                  SearchResult rsr = (SearchResult) rNamingEnum.next();
824
                  rsrAttr = rsr.getAttributes();
825
                  logMetacat.debug("referral search result is: " +
826
                    rsr.toString());
827
                    
828
                  // add the returned groups to the group vector.  Test the 
829
                  // syntax of the returned attributes - sometimes they are 
830
                  // preceded with the attribute id and a colon
831
                  if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
832
                    gvec.add( "cn=" + (tempAttr.get("cn") + "").substring(4) + 
833
                    "," + "o=" + (rsrAttr.get("o") + "").substring(3 ) + "," + 
834
                    ldapBase);
835
                    logMetacat.info("group " + 
836
                    (tempAttr.get("cn") + "").substring(4) + "," + 
837
                    "o=" + (rsrAttr.get("o") + "").substring(3) + "," + 
838
                    ldapBase + " added to the group vector");
839
                  } else {
840
                    gvec.add( "cn=" + tempAttr.get("cn") + "," + 
841
                    "o=" + rsrAttr.get("o") +
842
                    "," + ldapBase);
843
                    logMetacat.info("group " + 
844
                    "cn=" + tempAttr.get("cn") + "," + 
845
                    "o=" + rsrAttr.get("o") + "," + 
846
                    ldapBase + " added to the group vector");
847
                  }  
848
                }
849
                
850
              } catch (NamingException nameEx){
851
                logMetacat.debug("Caught naming exception: ");
852
                nameEx.printStackTrace(System.err);
853
              }
854
            }
855
          }// end while
856
          
857
          moreReferrals = false;
858
          
859
        } catch (ReferralException re) {
860
          
861
          logMetacat.info(
862
            "In AuthLdap.getGroups(), caught referral exception: " +
863
            re.getReferralInfo()
864
          );
865
          this.currentReferralInfo = (String) re.getReferralInfo();
866
          
867
          // set moreReferrals to true and set the referral context
868
          moreReferrals = true;
869
          ctx = (DirContext) re.getReferralContext();
870
           
871
        }// end inner try
872
      }// end for
873
      
874
      // close the context now that all initial and referral 
875
      // searches are processed
876
      ctx.close();
877
      
878
    } catch (NamingException e) {
879
      
880
      // naming exceptions get logged, groups are returned
881
      logMetacat.info("In AuthLdap.getGroups(), caught naming exception: ");
882
      e.printStackTrace(System.err);
883
      
884
    } finally {
885
      // once all referrals are followed, report and return the groups found
886
      logMetacat.warn("The user is in the following groups: " +
887
                               gvec.toString());
888
      //build and return the groups array
889
      String groups[][] = new String[gvec.size()][2];
890
      for (int i = 0; i < gvec.size(); i++) {
891
        groups[i][0] = (String) gvec.elementAt(i);
892
        groups[i][1] = (String) desc.elementAt(i);
893
      }
894
      return groups;
895
    }// end outer try
896
  }
536
			if (user.indexOf("o=") > 0) {
537
				String tempStr = user.substring(user.indexOf("o="));
538
				filter = "(&(" + user.substring(0, user.indexOf(",")) + ")("
539
						+ tempStr.substring(0, tempStr.indexOf(",")) + "))";
540
			} else {
541
				filter = "(&(" + user.substring(0, user.indexOf(",")) + "))";
542
			}
543
			filter = "(&(" + user.substring(0, user.indexOf(",")) + "))";
897 544

  
898
  /**
899
   * Get attributes describing a user or group
900
   *
901
   * @param foruser the user for which the attribute list is requested
902
   * @returns HashMap a map of attribute name to a Vector of values
903
   */
904
  public HashMap<String, Vector<String>> getAttributes(String foruser) throws ConnectException {
905
    return getAttributes(null, null, foruser);
906
  }
545
			NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
907 546

  
908
  /**
909
   * Get attributes describing a user or group
910
   *
911
   * @param user the user for authenticating against the service
912
   * @param password the password for authenticating against the service
913
   * @param foruser the user whose attributes should be returned
914
   * @returns HashMap a map of attribute name to a Vector of values
915
   */
916
  public HashMap<String,Vector<String>> getAttributes(String user, String password, 
917
    String foruser) throws ConnectException {
918
    HashMap<String,Vector<String>> attributes = new HashMap<String,Vector<String>>();
919
    String ldapUrl = this.ldapUrl;
920
    String ldapBase = this.ldapBase;
921
    String userident = foruser;
547
			Attributes tempAttr = null;
548
			try {
549
				while (namingEnum.hasMore()) {
550
					SearchResult sr = (SearchResult) namingEnum.next();
551
					tempAttr = sr.getAttributes();
922 552

  
923
    // Identify service provider to use
924
    Hashtable env = new Hashtable(11);
925
    env.put(Context.INITIAL_CONTEXT_FACTORY,
926
            "com.sun.jndi.ldap.LdapCtxFactory");
927
    env.put(Context.REFERRAL, referral);
928
    env.put(Context.PROVIDER_URL, ldapUrl);
553
					if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
554
						userinfo[0] = (tempAttr.get("cn") + "").substring(4);
555
					} else {
556
						userinfo[0] = (tempAttr.get("cn") + "");
557
					}
929 558

  
930
    try {
559
					if ((tempAttr.get("o") + "").startsWith("o: ")) {
560
						userinfo[1] = (tempAttr.get("o") + "").substring(3);
561
					} else {
562
						userinfo[1] = (tempAttr.get("o") + "");
563
					}
931 564

  
932
      // Create the initial directory context
933
      DirContext ctx = new InitialDirContext(env);
565
					if ((tempAttr.get("mail") + "").startsWith("mail: ")) {
566
						userinfo[2] = (tempAttr.get("mail") + "").substring(6);
567
					} else {
568
						userinfo[2] = (tempAttr.get("mail") + "");
569
					}
570
				}
571
			} catch (SizeLimitExceededException slee) {
572
				logMetacat.error("LDAP Server size limit exceeded. "
573
						+ "Returning incomplete record set.");
574
			}
934 575

  
935
      // Ask for all attributes of the user
936
      //Attributes attrs = ctx.getAttributes(userident);
937
      Attributes attrs = ctx.getAttributes(foruser);
576
			// Close the context when we're done
577
			ctx.close();
938 578

  
939
      // Print all of the attributes
940
      NamingEnumeration en = attrs.getAll();
941
      while (en.hasMore()) {
942
        Attribute att = (Attribute) en.next();
943
        Vector<String> values = new Vector();
944
        String attName = att.getID();
945
        NamingEnumeration attvalues = att.getAll();
946
        while (attvalues.hasMore()) {
947
          String value = (String) attvalues.next();
948
          values.add(value);
949
        }
950
        attributes.put(attName, values);
951
      }
579
		} catch (NamingException e) {
580
			logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
581
			// e.printStackTrace(System.err);
582
			throw new ConnectException("Problem getting users in AuthLdap.getUsers:" + e);
583
		}
952 584

  
953
      // Close the context when we're done
954
      ctx.close();
955
    }
956
    catch (NamingException e) {
957
      logMetacat.error("Problem getting attributes in " +
958
                        "AuthLdap.getAttributes:" + e);
959
      throw new ConnectException(
960
          "Problem getting attributes in AuthLdap.getAttributes:" + e);
961
    }
585
		return userinfo;
586
	}
962 587

  
963
    return attributes;
964
  }
588
	/**
589
	 * Get the users for a particular group from the authentication service
590
	 * 
591
	 * @param user
592
	 *            the user for authenticating against the service
593
	 * @param password
594
	 *            the password for authenticating against the service
595
	 * @param group
596
	 *            the group whose user list should be returned
597
	 * @returns string array of the user names belonging to the group
598
	 */
599
	public String[] getUsers(String user, String password, String group)
600
			throws ConnectException {
601
		String[] users = null;
965 602

  
966
  /**
967
   * Get list of all subtrees holding Metacat's groups and users
968
   * starting from the Metacat LDAP root,
969
   * i.e. ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
970
   */
971
  private Hashtable getSubtrees(String user, String password, 
972
    String ldapUrl, String ldapBase) throws ConnectException {
973
    Hashtable trees = new Hashtable();
603
		// Identify service provider to use
604
		Hashtable env = new Hashtable(11);
605
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
606
		env.put(Context.REFERRAL, referral);
607
		env.put(Context.PROVIDER_URL, ldapUrl);
974 608

  
975
    // Identify service provider to use
976
    Hashtable env = new Hashtable(11);
977
    env.put(Context.INITIAL_CONTEXT_FACTORY,
978
            "com.sun.jndi.ldap.LdapCtxFactory");
979
    // env.put(Context.REFERRAL, referral);
980
    // Using 'ignore' here instead of 'follow' as 'ignore' seems
981
    // to do the job better. 'follow' was not bringing up the UCNRS
982
    // and PISCO tree whereas 'ignore' brings up the tree.
609
		try {
983 610

  
984
    env.put(Context.REFERRAL, "ignore");
985
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
611
			// Create the initial directory context
612
			DirContext ctx = new InitialDirContext(env);
986 613

  
987
    try {
614
			// Specify the ids of the attributes to return
615
			String[] attrIDs = { "uniqueMember" };
988 616

  
989
      // Create the initial directory context
990
      DirContext ctx = new InitialDirContext(env);
617
			Attributes answer = ctx.getAttributes(group, attrIDs);
991 618

  
992
      // Specify the ids of the attributes to return
993
      String[] attrIDs = {
994
          "o", "ref"};
995
      SearchControls ctls = new SearchControls();
996
      ctls.setReturningAttributes(attrIDs);
997
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
619
			Vector uvec = new Vector();
620
			try {
621
				for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {
622
					Attribute attr = (Attribute) ae.next();
623
					for (NamingEnumeration e = attr.getAll(); e.hasMore(); uvec.add(e
624
							.next())) {
625
						;
626
					}
627
				}
628
			} catch (SizeLimitExceededException slee) {
629
				logMetacat.error("LDAP Server size limit exceeded. "
630
						+ "Returning incomplete record set.");
631
			}
998 632

  
999
      // Specify the attributes to match.
1000
      // Subtrees from the main server are found as objects with attribute
1001
      // objectclass=organization or objectclass=referral to the subtree
1002
      // resided on other server.
1003
      String filter = "(|(objectclass=organization)(objectclass=referral))";
633
			// initialize users[]; fill users[]
634
			users = new String[uvec.size()];
635
			for (int i = 0; i < uvec.size(); i++) {
636
				users[i] = (String) uvec.elementAt(i);
637
			}
1004 638

  
1005
      // Search for objects in the current context
1006
      NamingEnumeration namingEnum = ctx.search("", filter, ctls);
639
			// Close the context when we're done
640
			ctx.close();
1007 641

  
1008
      // Print the subtrees' <ldapURL, baseDN>
1009
      while (namingEnum.hasMore()) {
642
		} catch (NamingException e) {
643
			logMetacat.error("Problem getting users for a group in "
644
					+ "AuthLdap.getUsers:" + e);
645
			/*
646
			 * throw new ConnectException( "Problem getting users for a group in
647
			 * AuthLdap.getUsers:" + e);
648
			 */
649
		}
1010 650

  
1011
        SearchResult sr = (SearchResult) namingEnum.next();
651
		return users;
652
	}
1012 653

  
1013
        Attributes attrs = sr.getAttributes();
1014
        NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref" attrs
654
	/**
655
	 * Get all groups from the authentication service
656
	 * 
657
	 * @param user
658
	 *            the user for authenticating against the service
659
	 * @param password
660
	 *            the password for authenticating against the service
661
	 * @returns string array of the group names
662
	 */
663
	public String[][] getGroups(String user, String password) throws ConnectException {
664
		return getGroups(user, password, null);
665
	}
1015 666

  
1016
        if (enum1.hasMore()) {
1017
          Attribute attr = (Attribute) enum1.next();
1018
          String attrValue = (String) attr.get();
1019
          String attrName = (String) attr.getID();
667
	/**
668
	 * Get the groups for a particular user from the authentication service
669
	 * 
670
	 * @param user
671
	 *            the user for authenticating against the service
672
	 * @param password
673
	 *            the password for authenticating against the service
674
	 * @param foruser
675
	 *            the user whose group list should be returned
676
	 * @returns string array of the group names
677
	 */
678
	public String[][] getGroups(String user, String password, String foruser)
679
			throws ConnectException {
1020 680

  
1021
          if (enum1.hasMore()) {
1022
            attr = (Attribute) enum1.next();
1023
            String refValue = (String) attr.get();
1024
            String refName = (String) attr.getID();
1025
            if (ldapBase.startsWith(refName + "=" + refValue)) {
1026
              trees.put(ldapBase,
1027
                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1028
            }
1029
            else {
1030
              // this is a referral - so organization name is appended in
1031
              // front of the ldapbase.... later it is stripped out
1032
              // in getPrincipals
1033
              trees.put("[" + refName + "=" + refValue + "]" +
1034
                        attrValue.substring(attrValue.lastIndexOf("/") + 1,
1035
                                            attrValue.length()),
1036
                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
681
		logMetacat.debug("getGroups() called.");
1037 682

  
1038
              // trees.put(refName + "=" + refValue + "," + ldapBase,
1039
              //           attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1040
            }
683
		// create vectors to store group and dscription values returned from the
684
		// ldap servers
685
		Vector gvec = new Vector();
686
		Vector desc = new Vector();
687
		Attributes tempAttr = null;
688
		Attributes rsrAttr = null;
1041 689

  
1042
          }
1043
          else if (ldapBase.startsWith(attrName + "=" + attrValue)) {
1044
            trees.put(ldapBase, ldapUrl);
1045
          }
1046
          else {
1047
            if (sr.isRelative()) {
1048
              trees.put(attrName + "=" + attrValue + "," + ldapBase, ldapUrl);
1049
            }
1050
            else {
1051
              String referenceURL = sr.getName();
1052
              referenceURL = referenceURL.substring(0,
1053
                  referenceURL.lastIndexOf("/") + 1);
1054
              trees.put(attrName + "=" + attrValue + "," + ldapBase,
1055
                        referenceURL);
1056
            }
690
		// DURING getGroups(), DO WE NOT BIND USING userName AND userPassword??
691
		// NEED TO FIX THIS ...
692
		userName = user;
693
		userPassword = password;
694
		// Identify service provider to use
695
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
696
		env.put(Context.REFERRAL, "throw");
697
		env.put(Context.PROVIDER_URL, ldapUrl);
698
		env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
1057 699

  
1058
          }
1059
        }
1060
      }
700
		// Iterate through the referrals, handling NamingExceptions in the
701
		// outer catch statement, ReferralExceptions in the inner catch
702
		// statement
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff