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: berkley $'
11
 *     '$Date: 2007-08-07 13:40:13 -0700 (Tue, 07 Aug 2007) $'
12
 * '$Revision: 3344 $'
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
                  NamingEnumeration answer = 
362
                      sctx.search("", filter, ctls);
363

    
364
                  // Return the answer
365
                  while (answer.hasMore()) {
366
                      SearchResult sr = (SearchResult)answer.next();
367
                      identifier = sr.getName();
368
                      return identifier;
369
                  }
370
                  // The search completes with no more referrals
371
                  moreReferrals = false;
372
              } catch (ReferralException e) {
373
            	  logMetacat.info("Got referral: " + e.getReferralInfo());
374
            	  // Point to the new context from the referral
375
                  if (moreReferrals) {
376
                      sctx = (DirContext) e.getReferralContext();
377
                  }
378
              }
379
          }
380
      } catch (NamingException e) {
381
    	     logMetacat.error("Naming exception while getting dn: " + e);
382
    	      throw new NamingException(
383
    	          "Naming exception in AuthLdap.getIdentifyingName: " + e);
384
    	      }
385
      return identifier;
386
  }
387
  
388
  /**
389
   * Get all users from the authentication service
390
   *
391
   * @param user the user for authenticating against the service
392
   * @param password the password for authenticating against the service
393
   * @returns string array of all of the user names
394
   */
395
  public String[][] getUsers(String user, String password) throws 
396
    ConnectException {
397
    String[][] users = null;
398

    
399
    // Identify service provider to use
400
    Hashtable env = new Hashtable(11);
401
    env.put(Context.INITIAL_CONTEXT_FACTORY,
402
            "com.sun.jndi.ldap.LdapCtxFactory");
403
    env.put(Context.REFERRAL, referral);
404
    env.put(Context.PROVIDER_URL, ldapUrl);
405

    
406
    try {
407

    
408
      // Create the initial directory context
409
      DirContext ctx = new InitialDirContext(env);
410

    
411
      // Specify the attributes to match.
412
      // Users are objects that have the attribute objectclass=InetOrgPerson.
413
      SearchControls ctls = new SearchControls();
414
      String[] attrIDs = {
415
          "dn", "cn", "o", "ou", "mail"};
416
      ctls.setReturningAttributes(attrIDs);
417
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
418
      //ctls.setCountLimit(1000);
419
      String filter = "(objectClass=inetOrgPerson)";
420
      NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
421

    
422
      // Store the users in a vector
423
      Vector uvec = new Vector();
424
      Vector uname = new Vector();
425
      Vector uorg = new Vector();
426
      Vector uou = new Vector();
427
      Vector umail = new Vector();
428
      Attributes tempAttr = null;
429
      try {
430
        while (namingEnum.hasMore()) {
431
          SearchResult sr = (SearchResult) namingEnum.next();
432
          tempAttr = sr.getAttributes();
433

    
434
          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
435
            uname.add( (tempAttr.get("cn") + "").substring(4));
436
          }
437
          else {
438
            uname.add(tempAttr.get("cn") + "");
439
          }
440

    
441
          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
442
            uorg.add( (tempAttr.get("o") + "").substring(3));
443
          }
444
          else {
445
            uorg.add(tempAttr.get("o") + "");
446
          }
447

    
448
          if ( (tempAttr.get("ou") + "").startsWith("ou: ")) {
449
            uou.add( (tempAttr.get("ou") + "").substring(4));
450
          }
451
          else {
452
            uou.add(tempAttr.get("ou") + "");
453
          }
454

    
455
          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
456
            umail.add( (tempAttr.get("mail") + "").substring(6));
457
          }
458
          else {
459
            umail.add(tempAttr.get("mail") + "");
460
          }
461

    
462
          uvec.add(sr.getName() + "," + ldapBase);
463
        }
464
      }
465
      catch (SizeLimitExceededException slee) {
466
        logMetacat.error("LDAP Server size limit exceeded. " +
467
                          "Returning incomplete record set.");
468
      }
469

    
470
      // initialize users[]; fill users[]
471
      users = new String[uvec.size()][5];
472
      for (int i = 0; i < uvec.size(); i++) {
473
        users[i][0] = (String) uvec.elementAt(i);
474
        users[i][1] = (String) uname.elementAt(i);
475
        users[i][2] = (String) uorg.elementAt(i);
476
        users[i][3] = (String) uorg.elementAt(i);
477
        users[i][4] = (String) umail.elementAt(i);
478
      }
479

    
480
      // Close the context when we're done
481
      ctx.close();
482

    
483
    }
484
    catch (NamingException e) {
485
      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
486
      //e.printStackTrace(System.err);
487
      throw new ConnectException(
488
          "Problem getting users in AuthLdap.getUsers:" + e);
489
    }
490

    
491
    return users;
492
  }
493

    
494
  
495
  /**
496
   * Get all users from the authentication service
497
   *
498
   * @param user the user for authenticating against the service
499
   * @param password the password for authenticating against the service
500
   * @returns string array of all of the user names
501
   */
502
  public String[] getUserInfo(String user, String password) throws 
503
    ConnectException {
504
    String[] userinfo = new String[3];
505

    
506
    // Identify service provider to use
507
    Hashtable env = new Hashtable(11);
508
    env.put(Context.INITIAL_CONTEXT_FACTORY,
509
            "com.sun.jndi.ldap.LdapCtxFactory");
510
    env.put(Context.REFERRAL, referral);
511
    env.put(Context.PROVIDER_URL, ldapUrl);
512

    
513
    try {
514
      
515
      // Create the initial directory context
516
      DirContext ctx = new InitialDirContext(env);
517
      // Specify the attributes to match.
518
      // Users are objects that have the attribute objectclass=InetOrgPerson.
519
      SearchControls ctls = new SearchControls();
520
      String[] attrIDs = {
521
          "cn", "o", "mail"};
522
      ctls.setReturningAttributes(attrIDs);
523
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
524
      //ctls.setCountLimit(1000);
525
      // create the filter based on the uid
526
      
527
      String filter = null;
528
      
529
      if(user.indexOf("o=")>0){
530
    	  String tempStr = user.substring(user.indexOf("o="));
531
    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
532
			+ ")(" + tempStr.substring(0, tempStr.indexOf(",")) 
533
			+ "))";      
534
      } else{
535
    	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
536
			+ "))";          		  
537
      }
538
   	  filter = "(&(" + user.substring(0, user.indexOf(",")) 
539
		+ "))";          		  
540

    
541
      NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
542
      
543
      Attributes tempAttr = null;
544
      try {
545
        while (namingEnum.hasMore()) {
546
          SearchResult sr = (SearchResult) namingEnum.next();
547
          tempAttr = sr.getAttributes();
548

    
549
          if ( (tempAttr.get("cn") + "").startsWith("cn: ")) {
550
        	  userinfo[0] = (tempAttr.get("cn") + "").substring(4);
551
          }
552
          else {
553
        	  userinfo[0] = (tempAttr.get("cn") + "");
554
          }
555

    
556
          if ( (tempAttr.get("o") + "").startsWith("o: ")) {
557
        	  userinfo[1] = (tempAttr.get("o") + "").substring(3);
558
          }
559
          else {
560
        	  userinfo[1] = (tempAttr.get("o") + "");
561
          }
562

    
563
          if ( (tempAttr.get("mail") + "").startsWith("mail: ")) {
564
        	  userinfo[2] =  (tempAttr.get("mail") + "").substring(6);
565
          }
566
          else {
567
        	  userinfo[2] = (tempAttr.get("mail") + "");
568
          }
569
        }
570
      }
571
      catch (SizeLimitExceededException slee) {
572
        logMetacat.error("LDAP Server size limit exceeded. " +
573
                          "Returning incomplete record set.");
574
      }
575

    
576
      // Close the context when we're done
577
      ctx.close();
578

    
579
    }
580
    catch (NamingException e) {
581
      logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
582
      //e.printStackTrace(System.err);
583
      throw new ConnectException(
584
          "Problem getting users in AuthLdap.getUsers:" + e);
585
    }
586

    
587
    return userinfo;
588
  }
589

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

    
602
    // Identify service provider to use
603
    Hashtable env = new Hashtable(11);
604
    env.put(Context.INITIAL_CONTEXT_FACTORY,
605
            "com.sun.jndi.ldap.LdapCtxFactory");
606
    env.put(Context.REFERRAL, referral);
607
    env.put(Context.PROVIDER_URL, ldapUrl);
608

    
609
    try {
610

    
611
      // Create the initial directory context
612
      DirContext ctx = new InitialDirContext(env);
613

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

    
618
      Attributes answer = ctx.getAttributes(group, attrIDs);
619

    
620
      Vector uvec = new Vector();
621
      try {
622
        for (NamingEnumeration ae = answer.getAll(); ae.hasMore(); ) {
623
          Attribute attr = (Attribute) ae.next();
624
          for (NamingEnumeration e = attr.getAll();
625
               e.hasMore();
626
               uvec.add(e.next())
627
               ) {
628
            ;
629
          }
630
        }
631
      }
632
      catch (SizeLimitExceededException slee) {
633
        logMetacat.error("LDAP Server size limit exceeded. " +
634
                          "Returning incomplete record set.");
635
      }
636

    
637
      // initialize users[]; fill users[]
638
      users = new String[uvec.size()];
639
      for (int i = 0; i < uvec.size(); i++) {
640
        users[i] = (String) uvec.elementAt(i);
641
      }
642

    
643
      // Close the context when we're done
644
      ctx.close();
645

    
646
    }
647
    catch (NamingException e) {
648
      logMetacat.error("Problem getting users for a group in " +
649
                        "AuthLdap.getUsers:" + e);
650
      throw new ConnectException(
651
          "Problem getting users for a group in AuthLdap.getUsers:" + e);
652
    }
653

    
654
    return users;
655
  }
656

    
657
  /**
658
   * Get all groups from the authentication service
659
   *
660
   * @param user the user for authenticating against the service
661
   * @param password the password for authenticating against the service
662
   * @returns string array of the group names
663
   */
664
  public String[][] getGroups(String user, String password) throws 
665
    ConnectException {
666
    return getGroups(user, password, null);
667
  }
668

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

    
721
      // build the ldap search filter that represents the "group" concept
722
      String filter = null;
723
      String gfilter = "(objectClass=groupOfUniqueNames)";
724
      if (null == foruser) {
725
        filter = gfilter;
726
      } else {
727
        filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
728
      }
729
      logMetacat.info("group filter is: " + filter);
730
      
731
      // now, search and iterate through the referrals
732
      for (boolean moreReferrals = true; moreReferrals;) {  
733
        try { // inner try
734
      
735
          NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
736

    
737
          // Print the groups
738
          while (namingEnum.hasMore()) {
739
            SearchResult sr = (SearchResult) namingEnum.next();
740
            
741
            tempAttr = sr.getAttributes();
742

    
743
            if ( (tempAttr.get("description") + "").startsWith("description: ")) {
744
              desc.add( (tempAttr.get("description") + "").substring(13));
745
            }
746
            else {
747
              desc.add(tempAttr.get("description") + "");
748
            }
749
            
750
            // check for an absolute URL value or an answer value relative 
751
            // to the target context  
752
            if ( !sr.getName().startsWith("ldap") &&
753
                  sr.isRelative()) {
754
              logMetacat.debug("Search result entry is relative ...");
755
              gvec.add(sr.getName() + "," + ldapBase);
756
              logMetacat.info("group " + sr.getName() + "," +ldapBase + 
757
              " added to the group vector"); 
758
            } else {
759
              logMetacat.debug("Search result entry is absolute ...");
760
              
761
              // search the top level directory for referral objects and match
762
              // that of the search result's absolute URL.  This will let us
763
              // rebuild the group name from the search result, referral point
764
              // in the top directory tree, and ldapBase.
765
              
766
              // configure a new directory search first
767
              Hashtable envHash = new Hashtable(11);
768
              // Identify service provider to use
769
              envHash.put(Context.INITIAL_CONTEXT_FACTORY, 
770
                "com.sun.jndi.ldap.LdapCtxFactory");
771
              envHash.put(Context.REFERRAL, "ignore");
772
              envHash.put(Context.PROVIDER_URL, ldapUrl);
773
              envHash.put("com.sun.jndi.ldap.connect.timeout", 
774
                ldapConnectTimeLimit);
775
              
776
              try {
777
                // Create the initial directory context
778
                DirContext DirCtx = new InitialDirContext(envHash);
779

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

    
878
  /**
879
   * Get attributes describing a user or group
880
   *
881
   * @param foruser the user for which the attribute list is requested
882
   * @returns HashMap a map of attribute name to a Vector of values
883
   */
884
  public HashMap getAttributes(String foruser) throws ConnectException {
885
    return getAttributes(null, null, foruser);
886
  }
887

    
888
  /**
889
   * Get attributes describing a user or group
890
   *
891
   * @param user the user for authenticating against the service
892
   * @param password the password for authenticating against the service
893
   * @param foruser the user whose attributes should be returned
894
   * @returns HashMap a map of attribute name to a Vector of values
895
   */
896
  public HashMap getAttributes(String user, String password, 
897
    String foruser) throws ConnectException {
898
    HashMap attributes = new HashMap();
899
    String ldapUrl = this.ldapUrl;
900
    String ldapBase = this.ldapBase;
901
    String userident = foruser;
902

    
903
    // Identify service provider to use
904
    Hashtable env = new Hashtable(11);
905
    env.put(Context.INITIAL_CONTEXT_FACTORY,
906
            "com.sun.jndi.ldap.LdapCtxFactory");
907
    env.put(Context.REFERRAL, referral);
908
    env.put(Context.PROVIDER_URL, ldapUrl);
909

    
910
    try {
911

    
912
      // Create the initial directory context
913
      DirContext ctx = new InitialDirContext(env);
914

    
915
      // Ask for all attributes of the user
916
      //Attributes attrs = ctx.getAttributes(userident);
917
      Attributes attrs = ctx.getAttributes(foruser);
918

    
919
      // Print all of the attributes
920
      NamingEnumeration en = attrs.getAll();
921
      while (en.hasMore()) {
922
        Attribute att = (Attribute) en.next();
923
        Vector values = new Vector();
924
        String attName = att.getID();
925
        NamingEnumeration attvalues = att.getAll();
926
        while (attvalues.hasMore()) {
927
          String value = (String) attvalues.next();
928
          values.add(value);
929
        }
930
        attributes.put(attName, values);
931
      }
932

    
933
      // Close the context when we're done
934
      ctx.close();
935
    }
936
    catch (NamingException e) {
937
      logMetacat.error("Problem getting attributes in " +
938
                        "AuthLdap.getAttributes:" + e);
939
      throw new ConnectException(
940
          "Problem getting attributes in AuthLdap.getAttributes:" + e);
941
    }
942

    
943
    return attributes;
944
  }
945

    
946
  /**
947
   * Get list of all subtrees holding Metacat's groups and users
948
   * starting from the Metacat LDAP root,
949
   * i.e. ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
950
   */
951
  private Hashtable getSubtrees(String user, String password, 
952
    String ldapUrl, String ldapBase) throws ConnectException {
953
    Hashtable trees = new Hashtable();
954

    
955
    // Identify service provider to use
956
    Hashtable env = new Hashtable(11);
957
    env.put(Context.INITIAL_CONTEXT_FACTORY,
958
            "com.sun.jndi.ldap.LdapCtxFactory");
959
    // env.put(Context.REFERRAL, referral);
960
    // Using 'ignore' here instead of 'follow' as 'ignore' seems
961
    // to do the job better. 'follow' was not bringing up the UCNRS
962
    // and PISCO tree whereas 'ignore' brings up the tree.
963

    
964
    env.put(Context.REFERRAL, "ignore");
965
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
966

    
967
    try {
968

    
969
      // Create the initial directory context
970
      DirContext ctx = new InitialDirContext(env);
971

    
972
      // Specify the ids of the attributes to return
973
      String[] attrIDs = {
974
          "o", "ref"};
975
      SearchControls ctls = new SearchControls();
976
      ctls.setReturningAttributes(attrIDs);
977
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
978

    
979
      // Specify the attributes to match.
980
      // Subtrees from the main server are found as objects with attribute
981
      // objectclass=organization or objectclass=referral to the subtree
982
      // resided on other server.
983
      String filter = "(|(objectclass=organization)(objectclass=referral))";
984

    
985
      // Search for objects in the current context
986
      NamingEnumeration namingEnum = ctx.search("", filter, ctls);
987

    
988
      // Print the subtrees' <ldapURL, baseDN>
989
      while (namingEnum.hasMore()) {
990

    
991
        SearchResult sr = (SearchResult) namingEnum.next();
992

    
993
        Attributes attrs = sr.getAttributes();
994
        NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref" attrs
995

    
996
        if (enum1.hasMore()) {
997
          Attribute attr = (Attribute) enum1.next();
998
          String attrValue = (String) attr.get();
999
          String attrName = (String) attr.getID();
1000

    
1001
          if (enum1.hasMore()) {
1002
            attr = (Attribute) enum1.next();
1003
            String refValue = (String) attr.get();
1004
            String refName = (String) attr.getID();
1005
            if (ldapBase.startsWith(refName + "=" + refValue)) {
1006
              trees.put(ldapBase,
1007
                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1008
            }
1009
            else {
1010
              // this is a referral - so organization name is appended in
1011
              // front of the ldapbase.... later it is stripped out
1012
              // in getPrincipals
1013
              trees.put("[" + refName + "=" + refValue + "]" +
1014
                        attrValue.substring(attrValue.lastIndexOf("/") + 1,
1015
                                            attrValue.length()),
1016
                        attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1017

    
1018
              // trees.put(refName + "=" + refValue + "," + ldapBase,
1019
              //           attrValue.substring(0, attrValue.lastIndexOf("/") + 1));
1020
            }
1021

    
1022
          }
1023
          else if (ldapBase.startsWith(attrName + "=" + attrValue)) {
1024
            trees.put(ldapBase, ldapUrl);
1025
          }
1026
          else {
1027
            if (sr.isRelative()) {
1028
              trees.put(attrName + "=" + attrValue + "," + ldapBase, ldapUrl);
1029
            }
1030
            else {
1031
              String referenceURL = sr.getName();
1032
              referenceURL = referenceURL.substring(0,
1033
                  referenceURL.lastIndexOf("/") + 1);
1034
              trees.put(attrName + "=" + attrValue + "," + ldapBase,
1035
                        referenceURL);
1036
            }
1037

    
1038
          }
1039
        }
1040
      }
1041

    
1042
      // Close the context when we're done
1043
      ctx.close();
1044

    
1045
    }
1046
    catch (NamingException e) {
1047
      logMetacat.error("Problem getting subtrees in AuthLdap.getSubtrees:"
1048
                        + e);
1049
      throw new ConnectException(
1050
          "Problem getting subtrees in AuthLdap.getSubtrees:" + e);
1051
    }
1052

    
1053
    return trees;
1054
  }
1055

    
1056
  /**
1057
   * Get all groups and users from authentication scheme.
1058
   * The output is formatted in XML.
1059
   * @param user the user which requests the information
1060
   * @param password the user's password
1061
   */
1062
  public String getPrincipals(String user, String password) throws 
1063
    ConnectException {
1064
    StringBuffer out = new StringBuffer();
1065
   
1066
    out.append("<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n");
1067
    out.append("<principals>\n");
1068

    
1069
    /*
1070
     * get all subtrees first in the current dir context
1071
     * and then the Metacat users under them
1072
     */
1073
    Hashtable subtrees = getSubtrees(user, password, this.ldapUrl,
1074
                                     this.ldapBase);
1075

    
1076
    Enumeration keyEnum = subtrees.keys();
1077
    while (keyEnum.hasMoreElements()) {
1078
      this.ldapBase = (String) keyEnum.nextElement();
1079
      this.ldapUrl = (String) subtrees.get(ldapBase);
1080

    
1081
      /*
1082
       * code to get the organization name from ldapBase
1083
       */
1084
      String orgName = this.ldapBase;
1085
      if (orgName.startsWith("[")) {
1086
        // if orgName starts with [ then it is a referral URL...
1087
        // (see code in getSubtress)
1088
        // hence orgName can be retrieved  by getting the string between
1089
        // 'o=' and ']'
1090
        // also the string between [ and ] needs to be striped out from
1091
        // this.ldapBase
1092
        this.ldapBase = orgName.substring(orgName.indexOf("]") + 1);
1093
        if (orgName != null && orgName.indexOf("o=") > -1) {
1094
          orgName = orgName.substring(orgName.indexOf("o=") + 2);
1095
          orgName = orgName.substring(0, orgName.indexOf("]"));
1096
        }
1097
      }
1098
      else {
1099
        // else it is not referral
1100
        // hence orgName can be retrieved  by getting the string between
1101
        // 'o=' and ','
1102
        if (orgName != null && orgName.indexOf("o=") > -1) {
1103
          orgName = orgName.substring(orgName.indexOf("o=") + 2);
1104
          if (orgName.indexOf(",") > -1) {
1105
            orgName = orgName.substring(0, orgName.indexOf(","));
1106
          }
1107
        }
1108
      }
1109

    
1110
      out.append("  <authSystem URI=\"" +
1111
                 this.ldapUrl + this.ldapBase + "\" organization=\"" + orgName +
1112
                 "\">\n");
1113

    
1114
      // get all groups for directory context
1115
      String[][] groups = getGroups(user, password);
1116
      String[][] users = getUsers(user, password);
1117
      int userIndex = 0;
1118

    
1119
      // for the groups and users that belong to them
1120
      if (groups != null && groups.length > 0) {
1121
        for (int i = 0; i < groups.length; i++) {
1122
          out.append("    <group>\n");
1123
          out.append("      <groupname>" + groups[i][0] + "</groupname>\n");
1124
          out.append("      <description>" + groups[i][1] + "</description>\n");
1125
          String[] usersForGroup = getUsers(user, password, groups[i][0]);
1126
          for (int j = 0; j < usersForGroup.length; j++) {
1127
            
1128
            userIndex = searchUser(usersForGroup[j], users);
1129
            out.append("      <user>\n");
1130

    
1131
            if (userIndex < 0) {
1132
              out.append("        <username>" + usersForGroup[j] +
1133
                         "</username>\n");
1134
            }
1135
            else {
1136
              out.append("        <username>" + users[userIndex][0] +
1137
                         "</username>\n");
1138
              out.append("        <name>" + users[userIndex][1] + "</name>\n");
1139
              out.append("        <organization>" + users[userIndex][2] +
1140
                         "</organization>\n");
1141
              if (users[userIndex][3].compareTo("null") != 0) {
1142
                out.append("      <organizationUnitName>" + users[userIndex][3] +
1143
                           "</organizationUnitName>\n");
1144
              }
1145
              out.append("        <email>" + users[userIndex][4] + "</email>\n");
1146
            }
1147

    
1148
            out.append("      </user>\n");
1149
          }
1150
          out.append("    </group>\n");
1151
        }
1152
      }
1153

    
1154
      // for the users not belonging to any grou8p
1155
      for (int j = 0; j < users.length; j++) {
1156
          out.append("    <user>\n");
1157
          out.append("      <username>" + users[j][0] + "</username>\n");
1158
          out.append("      <name>" + users[j][1] + "</name>\n");
1159
          out.append("      <organization>" + users[j][2] +
1160
                     "</organization>\n");
1161
          if (users[j][3].compareTo("null") != 0) {
1162
            out.append("      <organizationUnitName>" + users[j][3] +
1163
                       "</organizationUnitName>\n");
1164
          }
1165
          out.append("      <email>" + users[j][4] + "</email>\n");
1166
          out.append("    </user>\n");
1167
      }
1168

    
1169
      out.append("  </authSystem>\n");
1170
    }
1171
    out.append("</principals>");
1172
    return out.toString();
1173
  }
1174

    
1175
  /**
1176
   * Method for getting index of user DN in User info array
1177
   */
1178
  int searchUser(String user, String userGroup[][]) {
1179
    for (int j = 0; j < userGroup.length; j++) {
1180
      if (user.compareTo(userGroup[j][0]) == 0) {
1181
        return j;
1182
      }
1183
    }
1184
    return -1;
1185
  }
1186

    
1187
  /**
1188
   * Test method for the class
1189
   */
1190
  public static void main(String[] args) {
1191

    
1192
    // Provide a user, such as: "Matt Jones", or "jones"
1193
    String user = args[0];
1194
    String password = args[1];
1195

    
1196
    logMetacat.warn("Creating session...");
1197
    AuthLdap authservice = new AuthLdap();
1198
    logMetacat.warn("Session exists...");
1199

    
1200
    boolean isValid = false;
1201
    try {
1202
      logMetacat.warn("Authenticating...");
1203
      isValid = authservice.authenticate(user, password);
1204
      if (isValid) {
1205
    	  logMetacat.warn("Authentication successful for: " + user);
1206
      }
1207
      else {
1208
        logMetacat.warn("Authentication failed for: " + user);
1209
      }
1210

    
1211
      // Get attributes for the user
1212
      if (isValid) {
1213
        logMetacat.info("\nGetting attributes for user....");
1214
        HashMap userInfo = authservice.getAttributes(user, password, user);
1215
        // Print all of the attributes
1216
        Iterator attList = (Iterator) ( ( (Set) userInfo.keySet()).iterator());
1217
        while (attList.hasNext()) {
1218
          String att = (String) attList.next();
1219
          Vector values = (Vector) userInfo.get(att);
1220
          Iterator attvalues = values.iterator();
1221
          while (attvalues.hasNext()) {
1222
            String value = (String) attvalues.next();
1223
            logMetacat.warn(att + ": " + value);
1224
          }
1225
        }
1226
      }
1227

    
1228
      // get the groups
1229
      if (isValid) {
1230
        logMetacat.warn("\nGetting all groups....");
1231
        String[][] groups = authservice.getGroups(user, password);
1232
        logMetacat.info("Groups found: " + groups.length);
1233
        for (int i = 0; i < groups.length; i++) {
1234
          logMetacat.info("Group " + i + ": " + groups[i][0]);
1235
        }
1236
      }
1237

    
1238
      // get the groups for the user
1239
      String savedGroup = null;
1240
      if (isValid) {
1241
        logMetacat.warn("\nGetting groups for user....");
1242
        String[][] groups = authservice.getGroups(user, password, user);
1243
        logMetacat.info("Groups found: " + groups.length);
1244
        for (int i = 0; i < groups.length; i++) {
1245
          logMetacat.info("Group " + i + ": " + groups[i][0]);
1246
          savedGroup = groups[i][0];
1247
        }
1248
      }
1249

    
1250
      // get the users for a group
1251
      if (isValid) {
1252
        logMetacat.warn("\nGetting users for group....");
1253
        logMetacat.info("Group: " + savedGroup);
1254
        String[] users = authservice.getUsers(user, password, savedGroup);
1255
        logMetacat.info("Users found: " + users.length);
1256
        for (int i = 0; i < users.length; i++) {
1257
          logMetacat.warn("User " + i + ": " + users[i]);
1258
        }
1259
      }
1260

    
1261
      // get all users
1262
      if (isValid) {
1263
        logMetacat.warn("\nGetting all users ....");
1264
        String[][] users = authservice.getUsers(user, password);
1265
        logMetacat.info("Users found: " + users.length);
1266

    
1267
      }
1268

    
1269
      // get the whole list groups and users in XML format
1270
      if (isValid) {
1271
        logMetacat.warn("\nTrying principals....");
1272
        authservice = new AuthLdap();
1273
        String out = authservice.getPrincipals(user, password);
1274
        java.io.File f = new java.io.File("principals.xml");
1275
        java.io.FileWriter fw = new java.io.FileWriter(f);
1276
        java.io.BufferedWriter buff = new java.io.BufferedWriter(fw);
1277
        buff.write(out);
1278
        buff.flush();
1279
        buff.close();
1280
        fw.close();
1281
        logMetacat.warn("\nFinished getting principals.");
1282
      }
1283

    
1284
    }
1285
    catch (ConnectException ce) {
1286
      logMetacat.error(ce.getMessage());
1287
    }
1288
    catch (java.io.IOException ioe) {
1289
      logMetacat.error("I/O Error writing to file principals.txt");
1290
    }
1291
  }
1292

    
1293
  /**
1294
   * This method will be called by start a thread.
1295
   * It can handle if a referral exception happend.
1296
   */
1297
}
(11-11/66)