Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *    Purpose: An implementation of the AuthInterface interface that
4
 *             allows Metacat to use the LDAP protocol for
5
 *             directory services
6
 *  Copyright: 2000 Regents of the University of California and the
7
 *             National Center for Ecological Analysis and Synthesis
8
 *    Authors: Matt Jones
9
 *
10
 *   '$Author: tao $'
11
 *     '$Date: 2008-06-05 19:08:03 -0700 (Thu, 05 Jun 2008) $'
12
 * '$Revision: 3938 $'
13
 *
14
 * This program is free software; you can redistribute it and/or modify
15
 * it under the terms of the GNU General Public License as published by
16
 * the Free Software Foundation; either version 2 of the License, or
17
 * (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU General Public License
25
 * along with this program; if not, write to the Free Software
26
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
 */
28

    
29
package edu.ucsb.nceas.metacat;
30

    
31
import java.net.ConnectException;
32
import javax.naming.AuthenticationException;
33
import javax.naming.Context;
34
import javax.naming.NamingEnumeration;
35
import javax.naming.NamingException;
36
import javax.naming.SizeLimitExceededException;
37
import javax.naming.directory.InvalidSearchFilterException;
38
import javax.naming.directory.Attribute;
39
import javax.naming.directory.Attributes;
40
import javax.naming.directory.DirContext;
41
import javax.naming.directory.InitialDirContext;
42
import javax.naming.directory.SearchResult;
43
import javax.naming.directory.SearchControls;
44
import javax.naming.ReferralException;
45
import javax.naming.ldap.InitialLdapContext;
46
import javax.naming.ldap.LdapContext;
47
import javax.naming.ldap.StartTlsRequest;
48
import javax.naming.ldap.StartTlsResponse;
49
import javax.net.ssl.SSLSession;
50

    
51
import org.apache.log4j.Logger;
52

    
53
import java.net.URLDecoder;
54
import java.util.Iterator;
55
import java.util.HashMap;
56
import java.util.Hashtable;
57
import java.util.Enumeration;
58
import java.util.Set;
59
import java.util.Vector;
60

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

    
84
  private static Logger logMetacat = Logger.getLogger(AuthLdap.class);
85
  
86
  /**
87
   * Construct an AuthLdap
88
   */
89
  public AuthLdap() {
90
    // Read LDAP URI for directory service information
91
    this.ldapUrl = MetaCatUtil.getOption("ldapurl");
92
    this.ldapsUrl = MetaCatUtil.getOption("ldapsurl");
93
    this.ldapBase = MetaCatUtil.getOption("ldapbase");
94
    this.referral = MetaCatUtil.getOption("referral");
95
    this.ldapConnectTimeLimit = 
96
      MetaCatUtil.getOption("ldapconnecttimelimit");
97
    this.ldapSearchTimeLimit = Integer.parseInt(
98
      MetaCatUtil.getOption("ldapsearchtimelimit"));
99
    this.ldapSearchCountLimit = Integer.parseInt(
100
      MetaCatUtil.getOption("ldapsearchcountlimit"));
101
    
102
    // Store referral info for use in building group DNs in getGroups() 
103
    this.currentReferralInfo = "";
104
  }
105

    
106
  /**
107
   * Determine if a user/password are valid according to the authentication
108
   * service.
109
   *
110
   * @param user the name of the principal to authenticate
111
   * @param password the password to use for authentication
112
   * @returns boolean true if authentication successful, false otherwise
113
   */
114
  
115
  public boolean authenticate(String user, String password) throws 
116
    ConnectException {
117
    String ldapUrl = this.ldapUrl;
118
    String ldapsUrl = this.ldapsUrl;
119
    String ldapBase = this.ldapBase;
120
    boolean authenticated = false;
121
    String identifier = user;
122
    
123
    //get uid here.
124
    String uid=user.substring(0, user.indexOf(","));
125
    user = user.substring(user.indexOf(","), user.length());
126

    
127
    logMetacat.debug("identifier: " + identifier);
128
    logMetacat.debug("uid: " + uid);
129
    logMetacat.debug("user: " + user);
130
    
131
    try {
132
    	// Check the usename as passed in
133
        logMetacat.info("Calling ldapAuthenticate");
134
        logMetacat.info("with user as identifier: " + identifier);
135

    
136
        authenticated = ldapAuthenticate(identifier, password, 
137
        		(new Boolean(MetaCatUtil.getOption("onlySecureLDAPConnection"))).booleanValue());
138
        // if not found, try looking up a valid DN then auth again
139
        if (!authenticated) {
140
        	logMetacat.info("Not Authenticated");
141
        	logMetacat.info("Looking up DN for: " + identifier);
142
        	identifier = getIdentifyingName(identifier, ldapUrl, ldapBase);
143
        	if(identifier == null){
144
        		logMetacat.info("No DN found from getIdentifyingName");
145
        		return authenticated;
146
        	}
147
        	
148
           	logMetacat.info("DN found from getIdentifyingName: " + identifier);
149
        	String decoded = URLDecoder.decode(identifier);
150
        	logMetacat.info("DN decoded: " + decoded);
151
        	identifier = decoded;
152
        	String refUrl = "";
153
        	String refBase = "";
154
        	if (identifier.startsWith("ldap")) {
155
        		logMetacat.debug("identifier starts with \"ldap\"");
156

    
157
        		refUrl = identifier.substring(0, identifier.lastIndexOf("/") + 1);
158
        		int position = identifier.indexOf(",");
159
        		int position2 = identifier.indexOf(",", position + 1);
160
        		
161
        		refBase = identifier.substring(position2 + 1);
162
        		identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
163
        		
164
        		logMetacat.info("Calling ldapAuthenticate:");
165
        		logMetacat.info("with user as identifier: " + identifier);
166
        		logMetacat.info("and refUrl as: " + refUrl);
167
        		logMetacat.info("and refBase as: " + refBase);
168

    
169
        		authenticated = ldapAuthenticate(identifier, password, refUrl, refBase,
170
                		(new Boolean(MetaCatUtil.getOption("onlySecureLDAPReferalsConnection")))
171
                			.booleanValue());
172
        	} else {
173
        		logMetacat.info("identifier doesnt start with ldap");
174
        		identifier = identifier + "," + ldapBase;
175
        		
176
        		logMetacat.info("Calling ldapAuthenticate");
177
        		logMetacat.info("with user as identifier: " + identifier);
178
        		
179
        		authenticated = ldapAuthenticate(identifier, password,
180
            		(new Boolean(MetaCatUtil.getOption("onlySecureLDAPConnection"))).booleanValue());
181
        	}
182
        }
183
    } catch (NullPointerException e) {
184
    	logMetacat.error("NullPointerException while authenticating in " +
185
                        "AuthLdap.authenticate: " + e);
186
    	e.printStackTrace();
187

    
188
    	throw new ConnectException(
189
          "NullPointerException while authenticating in " +
190
          "AuthLdap.authenticate: " + e);
191
    } catch (NamingException e) {
192
    	logMetacat.error("Naming exception while authenticating in " +
193
                        "AuthLdap.authenticate: " + e);
194
    	e.printStackTrace();
195
    } catch (Exception e) {
196
    	logMetacat.error(e.getMessage());
197
    }
198
    
199
    return authenticated;
200
  }
201

    
202
  /**
203
   * Connect to the LDAP directory and do the authentication using the
204
   * username and password as passed into the routine.
205
   *
206
   * @param identifier the distinguished name to check against LDAP
207
   * @param password the password for authentication
208
   */
209
  private boolean ldapAuthenticate(String identifier, String password, boolean 
210
    secureConnectionOnly) throws ConnectException, NamingException, 
211
    NullPointerException {
212
    return ldapAuthenticate(identifier, password,
213
                            this.ldapsUrl, this.ldapBase, secureConnectionOnly);
214
  }
215

    
216
  /**
217
   * Connect to the LDAP directory and do the authentication using the
218
   * username and password as passed into the routine.
219
   *
220
   * @param identifier the distinguished name to check against LDAP
221
   * @param password the password for authentication
222
   */
223
  
224
  private boolean ldapAuthenticate(String dn, String password, 
225
    String rootServer, String rootBase, boolean secureConnectionOnly){
226
	  
227
	  boolean authenticated = false;
228
		
229
	  String server = "";
230
	  String userDN = "";
231
	  logMetacat.info("dn is: " + dn);
232

    
233
	  int position = dn.lastIndexOf("/");
234
      logMetacat.debug("position is: " + position);
235
	  if (position == -1) {
236
		  server = rootServer;
237
		  if(dn.indexOf(userDN) < 0){
238
			  userDN = dn + "," + rootBase;
239
		  } else {
240
			  userDN = dn;
241
		  }
242
		  logMetacat.info("userDN is: " + userDN);
243

    
244
       } else {
245
		  server = dn.substring(0, position+1);
246
		  userDN = dn.substring(position+1);
247
		  logMetacat.info("server is: " + server);
248
		  logMetacat.info("userDN is: " + userDN);
249
	   }
250
		          
251
	   logMetacat.warn("Trying to authenticate: " + userDN);
252
	   logMetacat.warn("          Using server: " + server);
253
		          
254
	   LdapContext ctx = null;
255
	   double startTime;
256
	   double stopTime;
257
	   try 
258
     {
259
		   Hashtable env = new Hashtable();
260
		   env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
261
		   env.put(Context.PROVIDER_URL, server);
262
		   env.put(Context.REFERRAL, "throw");
263
		   try 
264
       {
265
			   
266
			   startTime = System.currentTimeMillis();
267
			   ctx = new InitialLdapContext(env, null);
268
			   // Start up TLS here so that we don't pass our jewels in cleartext
269
		       StartTlsResponse tls =
270
		              (StartTlsResponse)ctx.extendedOperation(new StartTlsRequest());
271
		       //tls.setHostnameVerifier(new SampleVerifier());
272
		       SSLSession sess = tls.negotiate();
273
		       ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
274
			   ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
275
			   ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
276
			   ctx.reconnect(null);
277
			   stopTime = System.currentTimeMillis();
278
			   logMetacat.info("Connection time thru " + ldapsUrl + " was: " +
279
                       	(stopTime - startTime) / 1000 + " seconds.");
280
			   authenticated = true;
281
		   } 
282
       catch (Exception ioe) 
283
       {
284
			   logMetacat.info("Caught IOException in login while negotiating TLS: "
285
	                                 + ioe.getMessage());
286
			   
287
			   if(secureConnectionOnly)
288
         {
289
				   return authenticated;
290
			   
291
			   } 
292
         else 
293
         {
294
				   logMetacat.info("Trying to authenticate without TLS");
295
				   env.put(Context.SECURITY_AUTHENTICATION, "simple");
296
				   env.put(Context.SECURITY_PRINCIPAL, userDN);
297
				   env.put(Context.SECURITY_CREDENTIALS, password);
298
				   
299
				   startTime = System.currentTimeMillis();
300
				   ctx = new InitialLdapContext(env, null);				
301
				   stopTime = System.currentTimeMillis();
302
				   logMetacat.info("Connection time thru " + ldapsUrl + " was: " +
303
	                       	(stopTime - startTime) / 1000 + " seconds.");
304
				   authenticated = true;
305
			   }
306
		   }
307
	   } 
308
     catch (AuthenticationException ae) 
309
     {
310
		   authenticated = false;
311
	   } 
312
     catch (javax.naming.InvalidNameException ine) 
313
     {
314
	        logMetacat.error("An invalid DN was provided!");
315
	   } 
316
     catch (NamingException e) 
317
     {
318
		   logMetacat.warn("Caught NamingException in login: " + e.getClass().getName());
319
		   logMetacat.info(e.toString() + "  " + e.getRootCause());
320
     }
321

    
322
       return authenticated;
323
  }
324

    
325

    
326
  /**
327
   * Get the identifying name for a given userid or name.  This is the name
328
   * that is used in conjunction withthe LDAP BaseDN to create a
329
   * distinguished name (dn) for the record
330
   *
331
   * @param user the user for which the identifying name is requested
332
   * @returns String the identifying name for the user,
333
   *          or null if not found
334
   */
335
  private String getIdentifyingName(String user, String ldapUrl, 
336
    String ldapBase) throws NamingException {
337
	  
338
      String identifier = null;
339
      Hashtable env = new Hashtable();
340
      env.put(Context.INITIAL_CONTEXT_FACTORY,
341
              "com.sun.jndi.ldap.LdapCtxFactory");
342
      env.put(Context.REFERRAL, "throw");
343
      env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
344
      try {
345
    	  int position = user.indexOf(",");
346
          String uid = user.substring(user.indexOf("=") + 1, position);
347
          logMetacat.info("uid is: " + uid);
348
          String org = user.substring(user.indexOf("=", position + 1) + 1,
349
                                        user.indexOf(",", position + 1));
350
          logMetacat.info("org is: " + org);
351
           
352
          DirContext sctx = new InitialDirContext(env);
353
          SearchControls ctls = new SearchControls();
354
          ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
355
          String filter = "(&(uid=" + uid + ")(o=" + org + "))";
356
          logMetacat.warn("Searching for DNs with following filter: " + filter);
357
          
358
          for (boolean moreReferrals = true; moreReferrals;) {
359
              try {
360
                  // Perform the search
361
            	  logMetacat.debug("before searching for DNs with following filter: " + filter);
362
            	  //logMetacat.debug("the context name space is ====== "+sctx.getNameInNamespace());
363
                  NamingEnumeration answer = 
364
                      sctx.search("", filter, ctls);
365
                  logMetacat.debug("after searching for DNs with following filter: " + filter);
366
                  // Return the answer
367
                  while (answer.hasMore()) {
368
                	  logMetacat.debug("In anwer.hasMore() while loop");
369
                      SearchResult sr = (SearchResult)answer.next();
370
                      identifier = sr.getName();
371
                      logMetacat.debug("after anwer.hasMore() while loop "+identifier);
372
                      return identifier;
373
                  }
374
                  // The search completes with no more referrals
375
                  moreReferrals = false;
376
              } catch (ReferralException e) {
377
            	  logMetacat.warn("Got referral: " + e.getReferralInfo());
378
            	  // Point to the new context from the referral
379
            	  DirContext storedConext = sctx;
380
            	  try
381
            	  {
382
	                  if (moreReferrals) {
383
	                      sctx = (DirContext) e.getReferralContext();
384
	                  }
385
            	  }
386
            	  catch(Exception ee)
387
            	  {
388
            		   e.skipReferral();
389
            		   if (moreReferrals) {
390
 	                      sctx = (DirContext) e.getReferralContext();
391
 	                   }
392
            		   logMetacat.warn("Naming exception while setting context to referral: " + ee);
393
            	  }
394
                  logMetacat.debug("after reset new context " + e.getReferralInfo());
395
              }
396
          }
397
      } catch (NamingException e) {
398
    	     logMetacat.error("Naming exception while getting dn: " + e);
399
    	      throw new NamingException(
400
    	          "Naming exception in AuthLdap.getIdentifyingName: " + e);
401
    	      }
402
      return identifier;
403
  }
404
  
405
  /**
406
   * Get all users from the authentication service
407
   *
408
   * @param user the user for authenticating against the service
409
   * @param password the password for authenticating against the service
410
   * @returns string array of all of the user names
411
   */
412
  public String[][] getUsers(String user, String password) throws 
413
    ConnectException {
414
    String[][] users = null;
415

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

    
424
    try {
425

    
426
      // Create the initial directory context
427
      DirContext ctx = new InitialDirContext(env);
428

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

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

    
453
          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
454
            uname.add( (tempAttr.get("cn") + "").substring(4));
455
          }
456
          else {
457
            uname.add(tempAttr.get("cn") + "");
458
          }
459

    
460
          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
461
            uorg.add( (tempAttr.get("o") + "").substring(3));
462
          }
463
          else {
464
            uorg.add(tempAttr.get("o") + "");
465
          }
466

    
467
          if ( (tempAttr.get("ou") + "").startsWith("ou: ")) {
468
            uou.add( (tempAttr.get("ou") + "").substring(4));
469
          }
470
          else {
471
            uou.add(tempAttr.get("ou") + "");
472
          }
473

    
474
          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
475
            umail.add( (tempAttr.get("mail") + "").substring(6));
476
          }
477
          else {
478
            umail.add(tempAttr.get("mail") + "");
479
          }
480

    
481
          uvec.add(sr.getName() + "," + ldapBase);
482
        }
483
      }
484
      catch (SizeLimitExceededException slee) {
485
        logMetacat.error("LDAP Server size limit exceeded. " +
486
                          "Returning incomplete record set.");
487
      }
488

    
489
      // initialize users[]; fill users[]
490
      users = new String[uvec.size()][5];
491
      for (int i = 0; i < uvec.size(); i++) {
492
        users[i][0] = (String) uvec.elementAt(i);
493
        users[i][1] = (String) uname.elementAt(i);
494
        users[i][2] = (String) uorg.elementAt(i);
495
        users[i][3] = (String) uorg.elementAt(i);
496
        users[i][4] = (String) umail.elementAt(i);
497
      }
498

    
499
      // Close the context when we're done
500
      ctx.close();
501

    
502
    }
503
    catch (NamingException e) {
504
      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
505
      //e.printStackTrace(System.err);
506
     /* throw new ConnectException(
507
          "Problem getting users in AuthLdap.getUsers:" + e);*/
508
    }
509

    
510
    return users;
511
  }
512

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

    
525
    // Identify service provider to use
526
    Hashtable env = new Hashtable(11);
527
    env.put(Context.INITIAL_CONTEXT_FACTORY,
528
            "com.sun.jndi.ldap.LdapCtxFactory");
529
    env.put(Context.REFERRAL, referral);
530
    env.put(Context.PROVIDER_URL, ldapUrl);
531

    
532
    try {
533
      
534
      // Create the initial directory context
535
      DirContext ctx = new InitialDirContext(env);
536
      // Specify the attributes to match.
537
      // Users are objects that have the attribute objectclass=InetOrgPerson.
538
      SearchControls ctls = new SearchControls();
539
      String[] attrIDs = {
540
          "cn", "o", "mail"};
541
      ctls.setReturningAttributes(attrIDs);
542
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
543
      //ctls.setCountLimit(1000);
544
      // create the filter based on the uid
545
      
546
      String filter = null;
547
      
548
      if(user.indexOf("o=")>0){
549
    	  String tempStr = user.substring(user.indexOf("o="));
550
    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
551
			+ ")(" + tempStr.substring(0, tempStr.indexOf(",")) 
552
			+ "))";      
553
      } else{
554
    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
555
			+ "))";          		  
556
      }
557
   	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
558
		+ "))";          		  
559

    
560
      NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
561
      
562
      Attributes tempAttr = null;
563
      try {
564
        while (namingEnum.hasMore()) {
565
          SearchResult sr = (SearchResult) namingEnum.next();
566
          tempAttr = sr.getAttributes();
567

    
568
          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
569
        	  userinfo[0] = (tempAttr.get("cn") + "").substring(4);
570
          }
571
          else {
572
        	  userinfo[0] = (tempAttr.get("cn") + "");
573
          }
574

    
575
          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
576
        	  userinfo[1] = (tempAttr.get("o") + "").substring(3);
577
          }
578
          else {
579
        	  userinfo[1] = (tempAttr.get("o") + "");
580
          }
581

    
582
          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
583
        	  userinfo[2] =  (tempAttr.get("mail") + "").substring(6);
584
          }
585
          else {
586
        	  userinfo[2] = (tempAttr.get("mail") + "");
587
          }
588
        }
589
      }
590
      catch (SizeLimitExceededException slee) {
591
        logMetacat.error("LDAP Server size limit exceeded. " +
592
                          "Returning incomplete record set.");
593
      }
594

    
595
      // Close the context when we're done
596
      ctx.close();
597

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

    
606
    return userinfo;
607
  }
608

    
609
  /**
610
   * Get the users for a particular group from the authentication service
611
   *
612
   * @param user the user for authenticating against the service
613
   * @param password the password for authenticating against the service
614
   * @param group the group whose user list should be returned
615
   * @returns string array of the user names belonging to the group
616
   */
617
  public String[] getUsers(String user, String password, String group) throws 
618
    ConnectException {
619
    String[] users = null;
620

    
621
    // Identify service provider to use
622
    Hashtable env = new Hashtable(11);
623
    env.put(Context.INITIAL_CONTEXT_FACTORY,
624
            "com.sun.jndi.ldap.LdapCtxFactory");
625
    env.put(Context.REFERRAL, referral);
626
    env.put(Context.PROVIDER_URL, ldapUrl);
627

    
628
    try {
629

    
630
      // Create the initial directory context
631
      DirContext ctx = new InitialDirContext(env);
632

    
633
      // Specify the ids of the attributes to return
634
      String[] attrIDs = {
635
          "uniqueMember"};
636

    
637
      Attributes answer = ctx.getAttributes(group, attrIDs);
638

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

    
656
      // initialize users[]; fill users[]
657
      users = new String[uvec.size()];
658
      for (int i = 0; i < uvec.size(); i++) {
659
        users[i] = (String) uvec.elementAt(i);
660
      }
661

    
662
      // Close the context when we're done
663
      ctx.close();
664

    
665
    }
666
    catch (NamingException e) {
667
      logMetacat.error("Problem getting users for a group in " +
668
                        "AuthLdap.getUsers:" + e);
669
      /*throw new ConnectException(
670
          "Problem getting users for a group in AuthLdap.getUsers:" + e);*/
671
    }
672

    
673
    return users;
674
  }
675

    
676
  /**
677
   * Get all groups from the authentication service
678
   *
679
   * @param user the user for authenticating against the service
680
   * @param password the password for authenticating against the service
681
   * @returns string array of the group names
682
   */
683
  public String[][] getGroups(String user, String password) throws 
684
    ConnectException {
685
    return getGroups(user, password, null);
686
  }
687

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

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

    
756
          // Print the groups
757
          while (namingEnum.hasMore()) {
758
            SearchResult sr = (SearchResult) namingEnum.next();
759
            
760
            tempAttr = sr.getAttributes();
761

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

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

    
909
  /**
910
   * Get attributes describing a user or group
911
   *
912
   * @param foruser the user for which the attribute list is requested
913
   * @returns HashMap a map of attribute name to a Vector of values
914
   */
915
  public HashMap getAttributes(String foruser) throws ConnectException {
916
    return getAttributes(null, null, foruser);
917
  }
918

    
919
  /**
920
   * Get attributes describing a user or group
921
   *
922
   * @param user the user for authenticating against the service
923
   * @param password the password for authenticating against the service
924
   * @param foruser the user whose attributes should be returned
925
   * @returns HashMap a map of attribute name to a Vector of values
926
   */
927
  public HashMap getAttributes(String user, String password, 
928
    String foruser) throws ConnectException {
929
    HashMap attributes = new HashMap();
930
    String ldapUrl = this.ldapUrl;
931
    String ldapBase = this.ldapBase;
932
    String userident = foruser;
933

    
934
    // Identify service provider to use
935
    Hashtable env = new Hashtable(11);
936
    env.put(Context.INITIAL_CONTEXT_FACTORY,
937
            "com.sun.jndi.ldap.LdapCtxFactory");
938
    env.put(Context.REFERRAL, referral);
939
    env.put(Context.PROVIDER_URL, ldapUrl);
940

    
941
    try {
942

    
943
      // Create the initial directory context
944
      DirContext ctx = new InitialDirContext(env);
945

    
946
      // Ask for all attributes of the user
947
      //Attributes attrs = ctx.getAttributes(userident);
948
      Attributes attrs = ctx.getAttributes(foruser);
949

    
950
      // Print all of the attributes
951
      NamingEnumeration en = attrs.getAll();
952
      while (en.hasMore()) {
953
        Attribute att = (Attribute) en.next();
954
        Vector values = new Vector();
955
        String attName = att.getID();
956
        NamingEnumeration attvalues = att.getAll();
957
        while (attvalues.hasMore()) {
958
          String value = (String) attvalues.next();
959
          values.add(value);
960
        }
961
        attributes.put(attName, values);
962
      }
963

    
964
      // Close the context when we're done
965
      ctx.close();
966
    }
967
    catch (NamingException e) {
968
      logMetacat.error("Problem getting attributes in " +
969
                        "AuthLdap.getAttributes:" + e);
970
      throw new ConnectException(
971
          "Problem getting attributes in AuthLdap.getAttributes:" + e);
972
    }
973

    
974
    return attributes;
975
  }
976

    
977
  /**
978
   * Get list of all subtrees holding Metacat's groups and users
979
   * starting from the Metacat LDAP root,
980
   * i.e. ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
981
   */
982
  private Hashtable getSubtrees(String user, String password, 
983
    String ldapUrl, String ldapBase) throws ConnectException {
984
    Hashtable trees = new Hashtable();
985

    
986
    // Identify service provider to use
987
    Hashtable env = new Hashtable(11);
988
    env.put(Context.INITIAL_CONTEXT_FACTORY,
989
            "com.sun.jndi.ldap.LdapCtxFactory");
990
    // env.put(Context.REFERRAL, referral);
991
    // Using 'ignore' here instead of 'follow' as 'ignore' seems
992
    // to do the job better. 'follow' was not bringing up the UCNRS
993
    // and PISCO tree whereas 'ignore' brings up the tree.
994

    
995
    env.put(Context.REFERRAL, "ignore");
996
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
997

    
998
    try {
999

    
1000
      // Create the initial directory context
1001
      DirContext ctx = new InitialDirContext(env);
1002

    
1003
      // Specify the ids of the attributes to return
1004
      String[] attrIDs = {
1005
          "o", "ref"};
1006
      SearchControls ctls = new SearchControls();
1007
      ctls.setReturningAttributes(attrIDs);
1008
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
1009

    
1010
      // Specify the attributes to match.
1011
      // Subtrees from the main server are found as objects with attribute
1012
      // objectclass=organization or objectclass=referral to the subtree
1013
      // resided on other server.
1014
      String filter = "(|(objectclass=organization)(objectclass=referral))";
1015

    
1016
      // Search for objects in the current context
1017
      NamingEnumeration namingEnum = ctx.search("", filter, ctls);
1018

    
1019
      // Print the subtrees' <ldapURL, baseDN>
1020
      while (namingEnum.hasMore()) {
1021

    
1022
        SearchResult sr = (SearchResult) namingEnum.next();
1023

    
1024
        Attributes attrs = sr.getAttributes();
1025
        NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref" attrs
1026

    
1027
        if (enum1.hasMore()) {
1028
          Attribute attr = (Attribute) enum1.next();
1029
          String attrValue = (String) attr.get();
1030
          String attrName = (String) attr.getID();
1031

    
1032
          if (enum1.hasMore()) {
1033
            attr = (Attribute) enum1.next();
1034
            String refValue = (String) attr.get();
1035
            String refName = (String) attr.getID();
1036
            if (ldapBase.startsWith(refName + "=" + refValue)) {
1037
              trees.put(ldapBase,
1038
                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1039
            }
1040
            else {
1041
              // this is a referral - so organization name is appended in
1042
              // front of the ldapbase.... later it is stripped out
1043
              // in getPrincipals
1044
              trees.put("[" + refName + "=" + refValue + "]" +
1045
                        attrValue.substring(attrValue.lastIndexOf("/") + 1,
1046
                                            attrValue.length()),
1047
                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1048

    
1049
              // trees.put(refName + "=" + refValue + "," + ldapBase,
1050
              //           attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1051
            }
1052

    
1053
          }
1054
          else if (ldapBase.startsWith(attrName + "=" + attrValue)) {
1055
            trees.put(ldapBase, ldapUrl);
1056
          }
1057
          else {
1058
            if (sr.isRelative()) {
1059
              trees.put(attrName + "=" + attrValue + "," + ldapBase, ldapUrl);
1060
            }
1061
            else {
1062
              String referenceURL = sr.getName();
1063
              referenceURL = referenceURL.substring(0,
1064
                  referenceURL.lastIndexOf("/") + 1);
1065
              trees.put(attrName + "=" + attrValue + "," + ldapBase,
1066
                        referenceURL);
1067
            }
1068

    
1069
          }
1070
        }
1071
      }
1072

    
1073
      // Close the context when we're done
1074
      ctx.close();
1075

    
1076
    }
1077
    catch (NamingException e) {
1078
      logMetacat.error("Problem getting subtrees in AuthLdap.getSubtrees:"
1079
                        + e);
1080
      throw new ConnectException(
1081
          "Problem getting subtrees in AuthLdap.getSubtrees:" + e);
1082
    }
1083

    
1084
    return trees;
1085
  }
1086

    
1087
  /**
1088
   * Get all groups and users from authentication scheme.
1089
   * The output is formatted in XML.
1090
   * @param user the user which requests the information
1091
   * @param password the user's password
1092
   */
1093
  public String getPrincipals(String user, String password) throws 
1094
    ConnectException {
1095
    StringBuffer out = new StringBuffer();
1096
   
1097
    out.append("<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n");
1098
    out.append("<principals>\n");
1099

    
1100
    /*
1101
     * get all subtrees first in the current dir context
1102
     * and then the Metacat users under them
1103
     */
1104
    Hashtable subtrees = getSubtrees(user, password, this.ldapUrl,
1105
                                     this.ldapBase);
1106

    
1107
    Enumeration keyEnum = subtrees.keys();
1108
    while (keyEnum.hasMoreElements()) {
1109
      this.ldapBase = (String) keyEnum.nextElement();
1110
      this.ldapUrl = (String) subtrees.get(ldapBase);
1111
      logMetacat.info("ldapBase "+ldapBase);
1112
      logMetacat.info("ldapUrl "+ldapUrl);
1113
      /*
1114
       * code to get the organization name from ldapBase
1115
       */
1116
      String orgName = this.ldapBase;
1117
      if (orgName.startsWith("[")) {
1118
        // if orgName starts with [ then it is a referral URL...
1119
        // (see code in getSubtress)
1120
        // hence orgName can be retrieved  by getting the string between
1121
        // 'o=' and ']'
1122
        // also the string between [ and ] needs to be striped out from
1123
        // this.ldapBase
1124
        this.ldapBase = orgName.substring(orgName.indexOf("]") + 1);
1125
        if (orgName != null && orgName.indexOf("o=") > -1) {
1126
          orgName = orgName.substring(orgName.indexOf("o=") + 2);
1127
          orgName = orgName.substring(0, orgName.indexOf("]"));
1128
        }
1129
      }
1130
      else {
1131
        // else it is not referral
1132
        // hence orgName can be retrieved  by getting the string between
1133
        // 'o=' and ','
1134
        if (orgName != null && orgName.indexOf("o=") > -1) {
1135
          orgName = orgName.substring(orgName.indexOf("o=") + 2);
1136
          if (orgName.indexOf(",") > -1) {
1137
            orgName = orgName.substring(0, orgName.indexOf(","));
1138
          }
1139
        }
1140
      }
1141
      logMetacat.info("org name is  "+orgName);
1142
      out.append("  <authSystem URI=\"" +
1143
                 this.ldapUrl + this.ldapBase + "\" organization=\"" + orgName +
1144
                 "\">\n");
1145

    
1146
      // get all groups for directory context
1147
      String[][] groups = getGroups(user, password);
1148
      logMetacat.debug("after getting groups "+groups);
1149
      String[][] users = getUsers(user, password);
1150
      logMetacat.debug("after getting users "+users);
1151
      int userIndex = 0;
1152

    
1153
      // for the groups and users that belong to them
1154
      if (groups != null && users != null && groups.length > 0) {
1155
    	 for (int i = 0; i < groups.length; i++) {
1156
          out.append("    <group>\n");
1157
          out.append("      <groupname>" + groups[i][0] + "</groupname>\n");
1158
          out.append("      <description>" + groups[i][1] + "</description>\n");
1159
          String[] usersForGroup = getUsers(user, password, groups[i][0]);
1160
          for (int j = 0; j < usersForGroup.length; j++) {
1161
            userIndex = searchUser(usersForGroup[j], users);
1162
            out.append("      <user>\n");
1163

    
1164
            if (userIndex < 0) {
1165
              out.append("        <username>" + usersForGroup[j] +
1166
                         "</username>\n");
1167
            }
1168
            else {
1169
              out.append("        <username>" + users[userIndex][0] +
1170
                         "</username>\n");
1171
              out.append("        <name>" + users[userIndex][1] + "</name>\n");
1172
              out.append("        <organization>" + users[userIndex][2] +
1173
                         "</organization>\n");
1174
              if (users[userIndex][3].compareTo("null") != 0) {
1175
                out.append("      <organizationUnitName>" + users[userIndex][3] +
1176
                           "</organizationUnitName>\n");
1177
              }
1178
              out.append("        <email>" + users[userIndex][4] + "</email>\n");
1179
            }
1180

    
1181
            out.append("      </user>\n");
1182
          }
1183
          out.append("    </group>\n");
1184
        }
1185
      }
1186
     
1187
      if (users != null)
1188
      {
1189
	      // for the users not belonging to any grou8p
1190
	      for (int j = 0; j < users.length; j++) {
1191
	          out.append("    <user>\n");
1192
	          out.append("      <username>" + users[j][0] + "</username>\n");
1193
	          out.append("      <name>" + users[j][1] + "</name>\n");
1194
	          out.append("      <organization>" + users[j][2] +
1195
	                     "</organization>\n");
1196
	          if (users[j][3].compareTo("null") != 0) {
1197
	            out.append("      <organizationUnitName>" + users[j][3] +
1198
	                       "</organizationUnitName>\n");
1199
	          }
1200
	          out.append("      <email>" + users[j][4] + "</email>\n");
1201
	          out.append("    </user>\n");
1202
	      }
1203
      }
1204

    
1205
      out.append("  </authSystem>\n");
1206
    }
1207
    out.append("</principals>");
1208
    return out.toString();
1209
  }
1210

    
1211
  /**
1212
   * Method for getting index of user DN in User info array
1213
   */
1214
  int searchUser(String user, String userGroup[][]) {
1215
    for (int j = 0; j < userGroup.length; j++) {
1216
      if (user.compareTo(userGroup[j][0]) == 0) {
1217
        return j;
1218
      }
1219
    }
1220
    return -1;
1221
  }
1222

    
1223
  /**
1224
   * Test method for the class
1225
   */
1226
  public static void main(String[] args) {
1227

    
1228
    // Provide a user, such as: "Matt Jones", or "jones"
1229
    String user = args[0];
1230
    String password = args[1];
1231

    
1232
    logMetacat.warn("Creating session...");
1233
    AuthLdap authservice = new AuthLdap();
1234
    logMetacat.warn("Session exists...");
1235

    
1236
    boolean isValid = false;
1237
    try {
1238
      logMetacat.warn("Authenticating...");
1239
      isValid = authservice.authenticate(user, password);
1240
      if (isValid) {
1241
    	  logMetacat.warn("Authentication successful for: " + user);
1242
      }
1243
      else {
1244
        logMetacat.warn("Authentication failed for: " + user);
1245
      }
1246

    
1247
      // Get attributes for the user
1248
      if (isValid) {
1249
        logMetacat.info("\nGetting attributes for user....");
1250
        HashMap userInfo = authservice.getAttributes(user, password, user);
1251
        // Print all of the attributes
1252
        Iterator attList = (Iterator) ( ( (Set) userInfo.keySet()).iterator());
1253
        while (attList.hasNext()) {
1254
          String att = (String) attList.next();
1255
          Vector values = (Vector) userInfo.get(att);
1256
          Iterator attvalues = values.iterator();
1257
          while (attvalues.hasNext()) {
1258
            String value = (String) attvalues.next();
1259
            logMetacat.warn(att + ": " + value);
1260
          }
1261
        }
1262
      }
1263

    
1264
      // get the groups
1265
      if (isValid) {
1266
        logMetacat.warn("\nGetting all groups....");
1267
        String[][] groups = authservice.getGroups(user, password);
1268
        logMetacat.info("Groups found: " + groups.length);
1269
        for (int i = 0; i < groups.length; i++) {
1270
          logMetacat.info("Group " + i + ": " + groups[i][0]);
1271
        }
1272
      }
1273

    
1274
      // get the groups for the user
1275
      String savedGroup = null;
1276
      if (isValid) {
1277
        logMetacat.warn("\nGetting groups for user....");
1278
        String[][] groups = authservice.getGroups(user, password, user);
1279
        logMetacat.info("Groups found: " + groups.length);
1280
        for (int i = 0; i < groups.length; i++) {
1281
          logMetacat.info("Group " + i + ": " + groups[i][0]);
1282
          savedGroup = groups[i][0];
1283
        }
1284
      }
1285

    
1286
      // get the users for a group
1287
      if (isValid) {
1288
        logMetacat.warn("\nGetting users for group....");
1289
        logMetacat.info("Group: " + savedGroup);
1290
        String[] users = authservice.getUsers(user, password, savedGroup);
1291
        logMetacat.info("Users found: " + users.length);
1292
        for (int i = 0; i < users.length; i++) {
1293
          logMetacat.warn("User " + i + ": " + users[i]);
1294
        }
1295
      }
1296

    
1297
      // get all users
1298
      if (isValid) {
1299
        logMetacat.warn("\nGetting all users ....");
1300
        String[][] users = authservice.getUsers(user, password);
1301
        logMetacat.info("Users found: " + users.length);
1302

    
1303
      }
1304

    
1305
      // get the whole list groups and users in XML format
1306
      if (isValid) {
1307
        logMetacat.warn("\nTrying principals....");
1308
        authservice = new AuthLdap();
1309
        String out = authservice.getPrincipals(user, password);
1310
        java.io.File f = new java.io.File("principals.xml");
1311
        java.io.FileWriter fw = new java.io.FileWriter(f);
1312
        java.io.BufferedWriter buff = new java.io.BufferedWriter(fw);
1313
        buff.write(out);
1314
        buff.flush();
1315
        buff.close();
1316
        fw.close();
1317
        logMetacat.warn("\nFinished getting principals.");
1318
      }
1319

    
1320
    }
1321
    catch (ConnectException ce) {
1322
      logMetacat.error(ce.getMessage());
1323
    }
1324
    catch (java.io.IOException ioe) {
1325
      logMetacat.error("I/O Error writing to file principals.txt");
1326
    }
1327
  }
1328

    
1329
  /**
1330
   * This method will be called by start a thread.
1331
   * It can handle if a referral exception happend.
1332
   */
1333
}
(10-10/66)