Project

General

Profile

1 503 bojilova
/**
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
 *    Release: @release@
10
 *
11
 *   '$Author$'
12
 *     '$Date$'
13
 * '$Revision$'
14 669 jones
 *
15
 * This program is free software; you can redistribute it and/or modify
16
 * it under the terms of the GNU General Public License as published by
17
 * the Free Software Foundation; either version 2 of the License, or
18
 * (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU General Public License
26
 * along with this program; if not, write to the Free Software
27
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 503 bojilova
 */
29
30
package edu.ucsb.nceas.metacat;
31
32
import java.net.ConnectException;
33
import javax.naming.AuthenticationException;
34
import javax.naming.Context;
35 787 bojilova
import javax.naming.NamingEnumeration;
36
import javax.naming.NamingException;
37 873 jones
import javax.naming.SizeLimitExceededException;
38 730 bojilova
import javax.naming.InitialContext;
39 802 bojilova
import javax.naming.directory.InvalidSearchFilterException;
40 503 bojilova
import javax.naming.directory.Attribute;
41
import javax.naming.directory.Attributes;
42 504 jones
import javax.naming.directory.BasicAttribute;
43
import javax.naming.directory.BasicAttributes;
44
import javax.naming.directory.DirContext;
45
import javax.naming.directory.InitialDirContext;
46
import javax.naming.directory.SearchResult;
47 723 bojilova
import javax.naming.directory.SearchControls;
48 868 berkley
import javax.naming.ReferralException;
49 787 bojilova
import javax.naming.ldap.*;
50 1988 jones
import java.net.URLDecoder;
51 503 bojilova
import java.util.Iterator;
52
import java.util.HashMap;
53
import java.util.Hashtable;
54 730 bojilova
import java.util.Enumeration;
55 503 bojilova
import java.util.Set;
56
import java.util.Vector;
57
58
/**
59
 * An implementation of the AuthInterface interface that
60
 * allows Metacat to use the LDAP protocol for directory services.
61 2058 sgarg
 * The LDAP authentication service is used to determine if a user
62 503 bojilova
 * is authenticated, and whether they are a member of a particular group.
63
 */
64 893 berkley
public class AuthLdap implements AuthInterface, Runnable {
65 787 bojilova
  private MetaCatUtil util = new MetaCatUtil();
66 728 bojilova
  private String ldapUrl;
67 787 bojilova
  private String ldapsUrl;
68 728 bojilova
  private String ldapBase;
69 865 jones
  private String referral;
70 991 tao
  private Context referralContext;
71 893 berkley
  Hashtable env = new Hashtable(11);
72
  private Context rContext;
73 934 tao
  private String userName;
74
  private String userPassword;
75 893 berkley
  ReferralException refExc;
76 1988 jones
  //String uid=null;
77 503 bojilova
78 2058 sgarg
  /**
79 728 bojilova
   * Construct an AuthLdap
80
   */
81
  public AuthLdap() {
82
    // Read LDAP URI for directory service information
83 787 bojilova
    this.ldapUrl = MetaCatUtil.getOption("ldapurl");
84
    this.ldapsUrl = MetaCatUtil.getOption("ldapsurl");
85
    this.ldapBase = MetaCatUtil.getOption("ldapbase");
86 865 jones
    this.referral = MetaCatUtil.getOption("referral");
87 728 bojilova
  }
88
89 503 bojilova
  /**
90
   * Determine if a user/password are valid according to the authentication
91
   * service.
92
   *
93
   * @param user the name of the principal to authenticate
94
   * @param password the password to use for authentication
95
   * @returns boolean true if authentication successful, false otherwise
96
   */
97
  public boolean authenticate(String user, String password)
98
                    throws ConnectException
99
  {
100 730 bojilova
    String ldapUrl = this.ldapUrl;
101 787 bojilova
    String ldapsUrl = this.ldapsUrl;
102 730 bojilova
    String ldapBase = this.ldapBase;
103 503 bojilova
    boolean authenticated = false;
104 802 bojilova
    String identifier = user;
105 1004 tao
    //get uid here.
106 1988 jones
    //uid=user.substring(0, user.indexOf(","));
107 2058 sgarg
108 503 bojilova
    try {
109 852 jones
        // Check the usename as passed in
110
        authenticated = ldapAuthenticate(identifier, password);
111 1004 tao
        // if not found, try looking up a valid DN then auth again
112
        if (!authenticated) {
113 1477 tao
            MetaCatUtil.debugMessage("Looking up DN for: " + identifier, 35);
114 1004 tao
            identifier = getIdentifyingName(identifier,ldapUrl,ldapBase);
115 1988 jones
            MetaCatUtil.debugMessage("DN found: " + identifier, 35);
116
            String decoded = URLDecoder.decode(identifier);
117
            MetaCatUtil.debugMessage("DN decoded: " + decoded, 35);
118
            identifier = decoded;
119 1005 jones
            String refUrl = "";
120
            String refBase = "";
121
            if (identifier.startsWith("ldap")) {
122
                refUrl = identifier.substring(0,
123
                               identifier.lastIndexOf("/")+1);
124 1494 tao
                MetaCatUtil.debugMessage("Ref ldapUrl: " + refUrl, 35);
125 1005 jones
                int position = identifier.indexOf(",");
126
                int position2 = identifier.indexOf(",", position+1);
127
                refBase = identifier.substring(position2+1);
128 1494 tao
                MetaCatUtil.debugMessage("Ref ldapBase: " + refBase, 35);
129 1005 jones
                identifier = identifier.substring(
130
                             identifier.lastIndexOf("/")+1);
131 1477 tao
                MetaCatUtil.debugMessage("Trying: " + identifier, 35);
132 1005 jones
                authenticated = ldapAuthenticate(identifier, password,
133
                                                 refUrl, refBase);
134
            } else {
135
                identifier = identifier+","+ldapBase;
136 1494 tao
                MetaCatUtil.debugMessage("Trying: " + identifier, 35);
137 1005 jones
                authenticated = ldapAuthenticate(identifier, password);
138
            }
139
            //authenticated = ldapAuthenticate(identifier, password);
140 1004 tao
        }
141 2058 sgarg
142 740 bojilova
    } catch (NullPointerException e) {
143 1477 tao
      util.debugMessage("NullPointerException b' password is null", 30);
144 2058 sgarg
      util.debugMessage("NullPointerException while authenticating in " +
145 1477 tao
                        "AuthLdap.authenticate: " + e, 30);
146 740 bojilova
      throw new ConnectException(
147 2058 sgarg
      "NullPointerException while authenticating in " +
148 740 bojilova
                        "AuthLdap.authenticate: " + e);
149 503 bojilova
    } catch (NamingException e) {
150 2058 sgarg
      util.debugMessage("Naming exception while authenticating in " +
151 1477 tao
                        "AuthLdap.authenticate: " + e, 30);
152 852 jones
      e.printStackTrace();
153 730 bojilova
    } catch (Exception e) {
154 1477 tao
      util.debugMessage(e.getMessage(), 30);
155 503 bojilova
    }
156
    return authenticated;
157
  }
158
159
  /**
160 852 jones
   * Connect to the LDAP directory and do the authentication using the
161
   * username and password as passed into the routine.
162
   *
163
   * @param identifier the distinguished name to check against LDAP
164
   * @param password the password for authentication
165
   */
166
  private boolean ldapAuthenticate(String identifier, String password)
167
            throws ConnectException, NamingException, NullPointerException
168
  {
169 2058 sgarg
      return ldapAuthenticate(identifier, password,
170 1005 jones
                              this.ldapsUrl, this.ldapBase);
171
  }
172
173
  /**
174
   * Connect to the LDAP directory and do the authentication using the
175
   * username and password as passed into the routine.
176
   *
177
   * @param identifier the distinguished name to check against LDAP
178
   * @param password the password for authentication
179
   */
180
  private boolean ldapAuthenticate(String identifier, String password,
181
            String directoryUrl, String searchBase)
182
            throws ConnectException, NamingException, NullPointerException
183
  {
184 867 berkley
    double totStartTime = System.currentTimeMillis();
185 852 jones
    boolean authenticated = false;
186 1988 jones
    if (identifier != null && !password.equals("")) {
187 2058 sgarg
188 934 tao
        //Pass the username and password to run() method
189
        userName=identifier;
190
        userPassword=password;
191
        // Identify service provider to use
192 852 jones
        Hashtable env = new Hashtable(11);
193 2058 sgarg
        env.put(Context.INITIAL_CONTEXT_FACTORY,
194 934 tao
              "com.sun.jndi.ldap.LdapCtxFactory");
195 866 berkley
        env.put(Context.REFERRAL, "throw");
196 1005 jones
        env.put(Context.PROVIDER_URL, directoryUrl + searchBase);
197 1988 jones
        util.debugMessage("PROVIDER_URL set to: " + directoryUrl + searchBase, 35);
198
        if ( !ldapsUrl.equals(ldapUrl) ) {
199 852 jones
          // ldap is set on default port 389
200
          // ldaps is set on second port - 636 by default
201 1005 jones
          //env.put(Context.SECURITY_PROTOCOL, "ssl");
202 852 jones
        }
203
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
204
        env.put(Context.SECURITY_PRINCIPAL, identifier);
205
        env.put(Context.SECURITY_CREDENTIALS, password);
206
        // If our auth credentials are invalid, an exception will be thrown
207
        DirContext ctx = null;
208 1988 jones
        try {
209 852 jones
          double startTime = System.currentTimeMillis();
210 1988 jones
          //Here to check the authorization
211 852 jones
          ctx = new InitialDirContext(env);
212
          double stopTime = System.currentTimeMillis();
213 934 tao
          util.debugMessage("Connection time thru " + ldapsUrl + " was: " +
214 1494 tao
                             (stopTime-startTime)/1000 + " seconds.", 35);
215 852 jones
          authenticated = true;
216
          //tls.close();
217
          ctx.close();
218
          this.ldapUrl = ldapUrl;
219
          this.ldapBase = ldapBase;
220
          //break;
221 1988 jones
        } catch (AuthenticationException ae) {
222 852 jones
          authenticated = false;
223 1988 jones
          if ( ctx != null ) {
224 852 jones
            ctx.close();
225
          }
226 1988 jones
        } catch (javax.naming.InvalidNameException ine) {
227 1477 tao
            util.debugMessage("An invalid DN was provided!", 30);
228 1988 jones
        } catch (javax.naming.ReferralException re) {
229 1477 tao
          util.debugMessage("referral during authentication", 30);
230
          util.debugMessage("Referral information: "+re.getReferralInfo(), 30);
231 1988 jones
          try {
232 893 berkley
            refExc = re;
233 934 tao
234 893 berkley
            Thread t = new Thread(this);
235
            t.start();
236 2058 sgarg
            Thread.sleep(5000); //this is a manual override of ldap's
237 915 berkley
                                //hideously long time out period.
238 1494 tao
            util.debugMessage("Awake after 5 seconds.", 35);
239 1988 jones
            if (referralContext == null) {
240 893 berkley
              t.interrupt();
241
              authenticated = false;
242 1988 jones
            } else {
243 893 berkley
              authenticated = true;
244
            }
245 1988 jones
          } catch (Exception e) {
246 868 berkley
            authenticated = false;
247
          }
248
        }
249 2058 sgarg
    } else {
250 1477 tao
        util.debugMessage("User not found", 30);
251 852 jones
    }
252 867 berkley
    double totStopTime = System.currentTimeMillis();
253 2058 sgarg
    util.debugMessage("total ldap authentication time: " +
254 1477 tao
                      (totStopTime - totStartTime)/1000 + " seconds", 35);
255 852 jones
    return authenticated;
256
  }
257
258 2058 sgarg
259
260 852 jones
  /**
261 730 bojilova
   * Get the identifying name for a given userid or name.  This is the name
262
   * that is used in conjunction withthe LDAP BaseDN to create a
263
   * distinguished name (dn) for the record
264
   *
265
   * @param user the user for which the identifying name is requested
266 2058 sgarg
   * @returns String the identifying name for the user,
267 730 bojilova
   *          or null if not found
268
   */
269 934 tao
  private String getIdentifyingName(String user, String ldapUrl,
270
                                    String ldapBase) throws NamingException
271 730 bojilova
  {
272
    String identifier = null;
273
    // Identify service provider to use
274
    Hashtable env = new Hashtable(11);
275
    env.put(Context.INITIAL_CONTEXT_FACTORY,
276
            "com.sun.jndi.ldap.LdapCtxFactory");
277 1477 tao
    util.debugMessage("setting referrals to: " + referral, 35);
278 865 jones
    env.put(Context.REFERRAL, referral);
279 730 bojilova
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
280 867 berkley
    //    non-secure LDAP context; dn are publicly readable
281 730 bojilova
    try {
282 2058 sgarg
283 730 bojilova
      // Bind to the LDAP server, in order to search for the right
284
      // distinguished name (dn) based on userid (uid) or common name (cn)
285
      DirContext ctx = new InitialDirContext(env);
286
      SearchControls ctls = new SearchControls();
287
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
288 2058 sgarg
      // Search for the user id or name using the uid, then cn and sn
289 934 tao
      //attributes
290 730 bojilova
      // If we find a record, determine the dn for the record
291 1005 jones
      // The following blocks need to be refactored into a subroutine
292
      // they have a ridiculous amount of redundancy
293 730 bojilova
294 1005 jones
      // Parse out the uid and org components and look up the real DN
295
      // This assumes a dn like "uid=x,o=y,dc=someinst,dc=org"
296
      int position = user.indexOf(",");
297
      String comp1 = user.substring(0, position);
298 1477 tao
      MetaCatUtil.debugMessage("First comp is: " + comp1, 35);
299 2058 sgarg
      String comp2 = user.substring(position+1,
300 1005 jones
                                    user.indexOf(",", position+1));
301 1477 tao
      MetaCatUtil.debugMessage("Second comp is: " + comp2, 35);
302 1005 jones
303 1998 jones
      //String filter = "(&(" + comp1 + "))";
304
      String filter = "(&(" + comp1 + ")(" + comp2 + "))";
305 1477 tao
      MetaCatUtil.debugMessage("Filter is: " + filter, 35);
306
      MetaCatUtil.debugMessage("Provider URL is: " + ldapUrl + ldapBase, 35);
307 802 bojilova
      NamingEnumeration answer;
308
      try {
309 1988 jones
        util.debugMessage("Trying search 1: " + filter, 35);
310 802 bojilova
        answer = ctx.search("", filter, ctls);
311 1988 jones
        util.debugMessage("Search 1 complete", 35);
312
        if (answer == null) {
313
            util.debugMessage("Search 1 answer is null.", 35);
314
        }
315 802 bojilova
        if (answer.hasMore()) {
316 1988 jones
          util.debugMessage("Search 1 has answers.", 35);
317 802 bojilova
          SearchResult sr = (SearchResult)answer.next();
318
          identifier = sr.getName();
319 1477 tao
          util.debugMessage("Originally Found: " + identifier, 35);
320 1005 jones
          return identifier;
321
        }
322 1988 jones
      } catch (InvalidSearchFilterException e) {
323
          util.debugMessage("Invalid Filter exception thrown (if1)", 35);
324
      }
325 1005 jones
326
      // That failed, so check if it is just a username
327
      filter = "(" + user + ")";
328
      try {
329 1988 jones
        MetaCatUtil.debugMessage("Trying again: " + filter, 35);
330 1005 jones
        answer = ctx.search("", filter, ctls);
331
        if (answer.hasMore()) {
332
          SearchResult sr = (SearchResult)answer.next();
333
          identifier = sr.getName();
334 2058 sgarg
          if ( !sr.isRelative() ) {
335 934 tao
            this.ldapUrl = identifier.substring(0,
336
                                                identifier.lastIndexOf("/")+1);
337 802 bojilova
            this.ldapBase = identifier.substring(identifier.indexOf(",")+1);
338
            identifier = identifier.substring(identifier.lastIndexOf("/")+1,
339
                                              identifier.indexOf(","));
340
          }
341 1477 tao
          util.debugMessage("Found: " + identifier, 35);
342 802 bojilova
          return identifier;
343
        }
344
      } catch (InvalidSearchFilterException e) {}
345 1005 jones
346
      // Maybe its a user id (uid)
347 802 bojilova
      filter = "(uid=" + user + ")";
348 1988 jones
      MetaCatUtil.debugMessage("Trying again: " + filter, 35);
349 802 bojilova
      answer = ctx.search("", filter, ctls);
350 730 bojilova
      if (answer.hasMore()) {
351
        SearchResult sr = (SearchResult)answer.next();
352
        identifier = sr.getName();
353 2058 sgarg
        if ( !sr.isRelative() ) {
354 730 bojilova
          this.ldapUrl = identifier.substring(0,identifier.lastIndexOf("/")+1);
355
          this.ldapBase = identifier.substring(identifier.indexOf(",")+1);
356
          identifier = identifier.substring(identifier.lastIndexOf("/")+1,
357
                                            identifier.indexOf(","));
358
        }
359 1477 tao
        util.debugMessage("Found: " + identifier, 35);
360 730 bojilova
      } else {
361 1005 jones
362
        // maybe its just a common name
363 730 bojilova
        filter = "(cn=" + user + ")";
364 1988 jones
        MetaCatUtil.debugMessage("Trying again: " + filter, 35);
365 730 bojilova
        NamingEnumeration answer2 = ctx.search("", filter, ctls);
366
        if (answer2.hasMore()) {
367
          SearchResult sr = (SearchResult)answer2.next();
368
          identifier = sr.getName();
369 2058 sgarg
          if ( !sr.isRelative() ) {
370 934 tao
            this.ldapUrl = identifier.substring(0,
371
                                                identifier.lastIndexOf("/")+1);
372 730 bojilova
            this.ldapBase = identifier.substring(identifier.indexOf(",")+1);
373
            identifier = identifier.substring(identifier.lastIndexOf("/")+1,
374
                                              identifier.indexOf(","));
375
          }
376 1477 tao
          util.debugMessage("Found: " + identifier, 35);
377 730 bojilova
        } else {
378 1005 jones
379
          // ok, last resort, is it a surname?
380 730 bojilova
          filter = "(sn=" + user + ")";
381 1988 jones
          MetaCatUtil.debugMessage("Trying again: " + filter, 35);
382 730 bojilova
          NamingEnumeration answer3 = ctx.search("", filter, ctls);
383
          if (answer3.hasMore()) {
384
            SearchResult sr = (SearchResult)answer3.next();
385
            identifier = sr.getName();
386 2058 sgarg
            if ( !sr.isRelative() ) {
387 934 tao
              this.ldapUrl = identifier.substring(0,
388
                                                identifier.lastIndexOf("/")+1);
389 730 bojilova
              this.ldapBase = identifier.substring(identifier.indexOf(",")+1);
390
              identifier = identifier.substring(identifier.lastIndexOf("/")+1,
391
                                                identifier.indexOf(","));
392
            }
393 1477 tao
            util.debugMessage("Found: " + identifier, 35);
394 730 bojilova
          }
395
        }
396
      }
397
      // Close the context when we're done the initial search
398
      ctx.close();
399
    } catch (NamingException e) {
400 1477 tao
      util.debugMessage("Naming exception while getting dn: " + e, 35);
401 730 bojilova
      throw new NamingException(
402
      "Naming exception in AuthLdap.getIdentifyingName: " + e);
403
    }
404 1988 jones
    MetaCatUtil.debugMessage("Returning found identifier as: " + identifier, 35);
405 730 bojilova
    return identifier;
406
  }
407
408
  /**
409 503 bojilova
   * Get all users from the authentication service
410 871 jones
   *
411
   * @param user the user for authenticating against the service
412
   * @param password the password for authenticating against the service
413
   * @returns string array of all of the user names
414 503 bojilova
   */
415 2058 sgarg
  public String[][] getUsers(String user, String password)
416 514 jones
         throws ConnectException
417 503 bojilova
  {
418 2058 sgarg
    String[][] users = null;
419 723 bojilova
420
    // Identify service provider to use
421
    Hashtable env = new Hashtable(11);
422 2058 sgarg
    env.put(Context.INITIAL_CONTEXT_FACTORY,
423 723 bojilova
            "com.sun.jndi.ldap.LdapCtxFactory");
424 865 jones
    env.put(Context.REFERRAL, referral);
425 871 jones
    env.put(Context.PROVIDER_URL, ldapUrl);
426 2058 sgarg
427 723 bojilova
    try {
428
429
        // Create the initial directory context
430
        DirContext ctx = new InitialDirContext(env);
431
432 726 bojilova
        // Specify the attributes to match.
433
        // Users are objects that have the attribute objectclass=InetOrgPerson.
434 871 jones
        SearchControls ctls = new SearchControls();
435 2058 sgarg
        String[] attrIDs = {"dn", "cn", "mail"};
436 871 jones
        ctls.setReturningAttributes(attrIDs);
437
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
438 873 jones
        //ctls.setCountLimit(1000);
439 871 jones
        String filter = "(objectClass=inetOrgPerson)";
440
        NamingEnumeration enum = ctx.search(ldapBase, filter, ctls);
441 2058 sgarg
442 873 jones
        // Store the users in a vector
443 723 bojilova
        Vector uvec = new Vector();
444 2058 sgarg
        Vector uname = new Vector();
445
        Vector umail = new Vector();
446
        Attributes tempAttr = null;
447 873 jones
        try {
448
            while (enum.hasMore()) {
449
                SearchResult sr = (SearchResult)enum.next();
450 2058 sgarg
                tempAttr = sr.getAttributes();
451
452
                if((tempAttr.get("cn")+"").startsWith("cn: ")){
453
                  uname.add( (tempAttr.get("cn") + "").substring(4));
454
                } else {
455
                  uname.add( tempAttr.get("cn") + "");
456
                }
457
458
                if((tempAttr.get("mail")+"").startsWith("mail: ")){
459
                  umail.add((tempAttr.get("mail") + "").substring(6));
460
                } else {
461
                  umail.add(tempAttr.get("mail") + "");
462
                }
463
464 873 jones
                uvec.add(sr.getName()+","+ldapBase);
465
            }
466
        } catch (SizeLimitExceededException slee) {
467
            util.debugMessage("LDAP Server size limit exceeded. " +
468 1477 tao
                    "Returning incomplete record set.", 35);
469 723 bojilova
        }
470
471
        // initialize users[]; fill users[]
472 2058 sgarg
        users = new String[uvec.size()][3];
473 723 bojilova
        for (int i=0; i < uvec.size(); i++) {
474 2058 sgarg
          users[i][0] = (String)uvec.elementAt(i);
475
          users[i][1] = (String)uname.elementAt(i);
476
          users[i][2] = (String)umail.elementAt(i);
477 723 bojilova
        }
478
479
        // Close the context when we're done
480
        ctx.close();
481
482
    } catch (NamingException e) {
483 1477 tao
      util.debugMessage("Problem getting users in AuthLdap.getUsers:" + e, 35);
484
      //e.printStackTrace(System.err);
485 723 bojilova
      throw new ConnectException(
486 728 bojilova
      "Problem getting users in AuthLdap.getUsers:" + e);
487 723 bojilova
    }
488
489
    return users;
490 503 bojilova
  }
491
492
  /**
493
   * Get the users for a particular group from the authentication service
494 871 jones
   *
495
   * @param user the user for authenticating against the service
496
   * @param password the password for authenticating against the service
497
   * @param group the group whose user list should be returned
498
   * @returns string array of the user names belonging to the group
499 503 bojilova
   */
500 2058 sgarg
  public String[] getUsers(String user, String password, String group)
501 514 jones
         throws ConnectException
502 503 bojilova
  {
503 723 bojilova
    String[] users = null;
504
505
    // Identify service provider to use
506
    Hashtable env = new Hashtable(11);
507 2058 sgarg
    env.put(Context.INITIAL_CONTEXT_FACTORY,
508 723 bojilova
            "com.sun.jndi.ldap.LdapCtxFactory");
509 865 jones
    env.put(Context.REFERRAL, referral);
510 871 jones
    env.put(Context.PROVIDER_URL, ldapUrl);
511 723 bojilova
512
    try {
513
514
        // Create the initial directory context
515
        DirContext ctx = new InitialDirContext(env);
516
517
        // Specify the ids of the attributes to return
518 871 jones
        String[] attrIDs = {"uniqueMember"};
519 723 bojilova
520 871 jones
        Attributes answer = ctx.getAttributes(group, attrIDs);
521 723 bojilova
522
        Vector uvec = new Vector();
523 873 jones
        try {
524
            for (NamingEnumeration ae = answer.getAll(); ae.hasMore();) {
525
                Attribute attr = (Attribute)ae.next();
526 2058 sgarg
                for (NamingEnumeration e = attr.getAll();
527 873 jones
                     e.hasMore();
528 2058 sgarg
                     uvec.add(e.next())
529 873 jones
                    );
530
            }
531
        } catch (SizeLimitExceededException slee) {
532
            util.debugMessage("LDAP Server size limit exceeded. " +
533 1477 tao
                    "Returning incomplete record set.", 35);
534 723 bojilova
        }
535
536
        // initialize users[]; fill users[]
537
        users = new String[uvec.size()];
538
        for (int i=0; i < uvec.size(); i++) {
539 2058 sgarg
          users[i] = (String)uvec.elementAt(i);
540 723 bojilova
        }
541
542
        // Close the context when we're done
543
        ctx.close();
544
545
    } catch (NamingException e) {
546 934 tao
      util.debugMessage("Problem getting users for a group in " +
547 1477 tao
              "AuthLdap.getUsers:" + e, 30);
548 723 bojilova
      throw new ConnectException(
549 728 bojilova
      "Problem getting users for a group in AuthLdap.getUsers:" + e);
550 723 bojilova
    }
551
552
    return users;
553 503 bojilova
  }
554
555
  /**
556
   * Get all groups from the authentication service
557 871 jones
   *
558
   * @param user the user for authenticating against the service
559
   * @param password the password for authenticating against the service
560
   * @returns string array of the group names
561 503 bojilova
   */
562 2058 sgarg
  public String[][] getGroups(String user, String password)
563 514 jones
         throws ConnectException
564 503 bojilova
  {
565 991 tao
      return getGroups(user, password, null);
566 503 bojilova
  }
567
568
  /**
569
   * Get the groups for a particular user from the authentication service
570 871 jones
   *
571
   * @param user the user for authenticating against the service
572
   * @param password the password for authenticating against the service
573
   * @param foruser the user whose group list should be returned
574
   * @returns string array of the group names
575 503 bojilova
   */
576 2058 sgarg
  public String[][] getGroups(String user, String password, String foruser)
577 514 jones
         throws ConnectException
578 503 bojilova
  {
579 1000 berkley
    Vector uvec = new Vector();
580 2058 sgarg
    Vector desc = new Vector();
581
    Attributes tempAttr = null;
582
583 976 tao
    //Pass the username and password to run() method
584
    userName=user;
585
    userPassword=password;
586 723 bojilova
    // Identify service provider to use
587 2058 sgarg
    env.put(Context.INITIAL_CONTEXT_FACTORY,
588 723 bojilova
            "com.sun.jndi.ldap.LdapCtxFactory");
589 888 berkley
    env.put(Context.REFERRAL, "throw");
590 871 jones
    env.put(Context.PROVIDER_URL, ldapUrl);
591 723 bojilova
    try {
592
        // Create the initial directory context
593
        DirContext ctx = new InitialDirContext(env);
594
        // Specify the ids of the attributes to return
595 2058 sgarg
        String[] attrIDs = {"cn", "description"};
596 723 bojilova
        // Specify the attributes to match.
597 726 bojilova
        // Groups are objects with attribute objectclass=groupofuniquenames.
598 842 bojilova
        // and have attribute uniquemember: uid=foruser,ldapbase.
599 871 jones
        SearchControls ctls = new SearchControls();
600
        ctls.setReturningAttributes(attrIDs);
601
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
602 2058 sgarg
603 871 jones
        String filter = null;
604
        String gfilter = "(objectClass=groupOfUniqueNames)";
605
        if (null == foruser) {
606
            filter = gfilter;
607
        } else {
608
            filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
609
        }
610 1477 tao
        MetaCatUtil.debugMessage("searching for groups: " + filter, 35);
611 991 tao
        NamingEnumeration enum = ctx.search(ldapBase, filter, ctls);
612
613
        // Print the groups
614 1494 tao
        MetaCatUtil.debugMessage("getting group results.", 50);
615 991 tao
        while (enum.hasMore()) {
616 2058 sgarg
          SearchResult sr = (SearchResult)enum.next();
617
          tempAttr = sr.getAttributes();
618
619
          if((tempAttr.get("description")+"").startsWith("description: ")){
620
            desc.add( (tempAttr.get("description") + "").substring(13));
621
          } else {
622
            desc.add( tempAttr.get("description") + "");
623
          }
624
625 991 tao
          uvec.add(sr.getName()+","+ldapBase);
626 2058 sgarg
          MetaCatUtil.debugMessage("group " + sr.getName() +
627 1477 tao
                                  " added to Group vector", 35);
628 723 bojilova
        }
629
        // Close the context when we're done
630
        ctx.close();
631 991 tao
632 2058 sgarg
    }
633
    catch (ReferralException re)
634 1000 berkley
    {
635
      refExc = re;
636
      Thread t = new Thread(new GetGroup());
637 1494 tao
      util.debugMessage("Starting thread...", 50);
638 1000 berkley
      t.start();
639 1494 tao
      util.debugMessage("sleeping for 5 seconds.", 50);
640 991 tao
      try
641
      {
642 1000 berkley
        Thread.sleep(5000);
643
      }
644
      catch(InterruptedException ie)
645
      {
646 1477 tao
        MetaCatUtil.debugMessage("main thread interrupted: " + ie.getMessage(), 30);
647 1000 berkley
      }
648
      //this is a manual override of jndi's hideously long time
649
      //out period.
650 1494 tao
      util.debugMessage("Awake after 5 seconds.", 40);
651 1000 berkley
      if (referralContext == null)
652
      {
653 1477 tao
        util.debugMessage("thread timed out...returning groups: " + uvec.toString(), 35);
654 2058 sgarg
        String groups[][] = new String[uvec.size()][2];
655 1000 berkley
        for(int i=0; i<uvec.size(); i++)
656 991 tao
        {
657 2058 sgarg
          groups[i][0] = (String)uvec.elementAt(i);
658
          groups[i][1] = (String)desc.elementAt(i);
659 991 tao
        }
660 1000 berkley
        t.interrupt();
661
        return groups;
662
      }
663
      DirContext dc = (DirContext)referralContext;
664 2058 sgarg
      String[] attrIDs = {"cn", "description"};
665 1000 berkley
      // Specify the attributes to match.
666
      // Groups are objects with attribute objectclass=groupofuniquenames.
667
      // and have attribute uniquemember: uid=foruser,ldapbase.
668
      SearchControls ctls = new SearchControls();
669
      ctls.setReturningAttributes(attrIDs);
670
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
671 2058 sgarg
672 1000 berkley
      String filter = null;
673
      String gfilter = "(objectClass=groupOfUniqueNames)";
674
      if (null == foruser) {
675
          filter = gfilter;
676
      } else {
677
          filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
678
      }
679 2058 sgarg
680 1000 berkley
      try
681
      {
682 991 tao
        NamingEnumeration enum = dc.search(ldapBase, filter, ctls);
683
        // Print the groups
684
        while (enum.hasMore()) {
685
          SearchResult sr = (SearchResult)enum.next();
686 2058 sgarg
          tempAttr = sr.getAttributes();
687
688
          if((tempAttr.get("description")+"").startsWith("description: ")){
689
            desc.add( (tempAttr.get("description") + "").substring(13));
690
          } else {
691
            desc.add( tempAttr.get("description") + "");
692
          }
693
694 991 tao
          uvec.add(sr.getName()+","+ldapBase);
695
        }
696 2058 sgarg
697 991 tao
        referralContext.close();
698
        dc.close();
699
      }
700 1000 berkley
      catch(NamingException ne)
701 991 tao
      {
702 2058 sgarg
        MetaCatUtil.debugMessage("Naming Exception in AuthLdap.getGroups" + ne.getExplanation() + ne.getMessage(), 30);
703 991 tao
      }
704
    } catch (NamingException e) {
705 868 berkley
      e.printStackTrace(System.err);
706 2058 sgarg
      String groups[][] = new String[uvec.size()][2];
707 1006 tao
      for(int i=0; i<uvec.size(); i++)
708
      {
709 2058 sgarg
        groups[i][0] = (String)uvec.elementAt(i);
710
        groups[i][1] = (String)desc.elementAt(i);
711 1006 tao
      }
712
      return groups;
713
       /*throw new ConnectException(
714
      "Problem getting groups for a user in AuthLdap.getGroups:" + e);*/
715 2058 sgarg
    }
716
717
    MetaCatUtil.debugMessage("The user is in the following groups: " +
718 1477 tao
                              uvec.toString(), 35);
719 2058 sgarg
    String groups[][] = new String[uvec.size()][2];
720 1000 berkley
    for(int i=0; i<uvec.size(); i++)
721
    {
722 2058 sgarg
      groups[i][0] = (String)uvec.elementAt(i);
723
      groups[i][1] = (String)desc.elementAt(i);
724 1000 berkley
    }
725 723 bojilova
    return groups;
726 503 bojilova
  }
727
728
  /**
729
   * Get attributes describing a user or group
730
   *
731 871 jones
   * @param foruser the user for which the attribute list is requested
732 503 bojilova
   * @returns HashMap a map of attribute name to a Vector of values
733
   */
734 2058 sgarg
  public HashMap getAttributes(String foruser)
735 503 bojilova
         throws ConnectException
736
  {
737 514 jones
    return getAttributes(null, null, foruser);
738 503 bojilova
  }
739
740
  /**
741
   * Get attributes describing a user or group
742
   *
743 871 jones
   * @param user the user for authenticating against the service
744 503 bojilova
   * @param password the password for authenticating against the service
745 871 jones
   * @param foruser the user whose attributes should be returned
746 503 bojilova
   * @returns HashMap a map of attribute name to a Vector of values
747
   */
748 2058 sgarg
  public HashMap getAttributes(String user, String password, String foruser)
749 503 bojilova
         throws ConnectException
750
  {
751
    HashMap attributes = new HashMap();
752 802 bojilova
    String ldapUrl = this.ldapUrl;
753
    String ldapBase = this.ldapBase;
754
    String userident = foruser;
755 2058 sgarg
756 503 bojilova
    // Identify service provider to use
757
    Hashtable env = new Hashtable(11);
758 2058 sgarg
    env.put(Context.INITIAL_CONTEXT_FACTORY,
759 503 bojilova
        "com.sun.jndi.ldap.LdapCtxFactory");
760 865 jones
    env.put(Context.REFERRAL, referral);
761 871 jones
    env.put(Context.PROVIDER_URL, ldapUrl);
762 503 bojilova
763
    try {
764 2058 sgarg
765 503 bojilova
      // Create the initial directory context
766
      DirContext ctx = new InitialDirContext(env);
767 2058 sgarg
768
      // Ask for all attributes of the user
769 871 jones
      //Attributes attrs = ctx.getAttributes(userident);
770
      Attributes attrs = ctx.getAttributes(foruser);
771 2058 sgarg
772 503 bojilova
      // Print all of the attributes
773
      NamingEnumeration en = attrs.getAll();
774
      while (en.hasMore()) {
775
        Attribute att = (Attribute)en.next();
776
        Vector values = new Vector();
777
        String attName = att.getID();
778
        NamingEnumeration attvalues = att.getAll();
779
        while (attvalues.hasMore()) {
780
          String value = (String)attvalues.next();
781
          values.add(value);
782
        }
783
        attributes.put(attName, values);
784
      }
785 2058 sgarg
786 503 bojilova
      // Close the context when we're done
787
      ctx.close();
788
    } catch (NamingException e) {
789 2058 sgarg
      util.debugMessage("Problem getting attributes in " +
790 1477 tao
              "AuthLdap.getAttributes:" + e, 35);
791 723 bojilova
      throw new ConnectException(
792
      "Problem getting attributes in AuthLdap.getAttributes:" + e);
793 503 bojilova
    }
794
795
    return attributes;
796
  }
797
798
  /**
799 730 bojilova
   * Get list of all subtrees holding Metacat's groups and users
800 2058 sgarg
   * starting from the Metacat LDAP root,
801 730 bojilova
   * i.e. ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
802 504 jones
   */
803 730 bojilova
  private Hashtable getSubtrees(String user, String password,
804
                                String ldapUrl, String ldapBase)
805
                throws ConnectException
806 504 jones
  {
807 730 bojilova
    Hashtable trees = new Hashtable();
808 504 jones
809
    // Identify service provider to use
810
    Hashtable env = new Hashtable(11);
811 2058 sgarg
    env.put(Context.INITIAL_CONTEXT_FACTORY,
812 504 jones
            "com.sun.jndi.ldap.LdapCtxFactory");
813 865 jones
    env.put(Context.REFERRAL, referral);
814 504 jones
    env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
815
816
    try {
817
818 730 bojilova
        // Create the initial directory context
819
        DirContext ctx = new InitialDirContext(env);
820
821
        // Specify the ids of the attributes to return
822
        String[] attrIDs = {"o","ref"};
823
        SearchControls ctls = new SearchControls();
824
        ctls.setReturningAttributes(attrIDs);
825
        ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
826 2058 sgarg
827 730 bojilova
        // Specify the attributes to match.
828
        // Subtrees from the main server are found as objects with attribute
829
        // objectclass=organization or objectclass=referral to the subtree
830
        // resided on other server.
831
        String filter = "(|(objectclass=organization)(objectclass=referral))";
832
833
        // Search for objects in the current context
834
        NamingEnumeration enum = ctx.search("", filter, ctls);
835
836
        // Print the subtrees' <ldapURL, baseDN>
837
        while (enum.hasMore()) {
838
          SearchResult sr = (SearchResult)enum.next();
839
          Attributes attrs = sr.getAttributes();
840
          NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref" attrs
841
          if (enum1.hasMore()) {
842
            Attribute attr = (Attribute)enum1.next();
843
            String attrValue = (String)attr.get();
844
            String attrName = (String)attr.getID();
845 2058 sgarg
846 730 bojilova
            if ( enum1.hasMore() ) {
847
              attr = (Attribute)enum1.next();
848
              String refValue = (String)attr.get();
849
              String refName = (String)attr.getID();
850 934 tao
               if ( ldapBase.startsWith(refName + "=" + refValue) ) {
851 730 bojilova
                trees.put(ldapBase,
852 934 tao
                         attrValue.substring(0,attrValue.lastIndexOf("/")+1) );
853 730 bojilova
              } else {
854
                trees.put(refName + "=" + refValue + "," + ldapBase,
855 934 tao
                         attrValue.substring(0,attrValue.lastIndexOf("/")+1) );
856 730 bojilova
              }
857 2058 sgarg
858 730 bojilova
            } else if ( ldapBase.startsWith(attrName + "=" + attrValue) ) {
859
                trees.put(ldapBase, ldapUrl);
860 2058 sgarg
            } else {
861
                trees.put(attrName + "=" + attrValue + "," + ldapBase, ldapUrl);
862 730 bojilova
            }
863 504 jones
          }
864
        }
865 730 bojilova
866
        // Close the context when we're done
867
        ctx.close();
868
869 504 jones
    } catch (NamingException e) {
870 2058 sgarg
      util.debugMessage("Problem getting subtrees in AuthLdap.getSubtrees:"
871 1477 tao
                        + e, 30);
872 730 bojilova
      throw new ConnectException(
873
      "Problem getting subtrees in AuthLdap.getSubtrees:" + e);
874 504 jones
    }
875
876 730 bojilova
    return trees;
877 504 jones
  }
878
879
  /**
880 730 bojilova
   * Get all groups and users from authentication scheme.
881 725 bojilova
   * The output is formatted in XML.
882 730 bojilova
   * @param user the user which requests the information
883
   * @param password the user's password
884 725 bojilova
   */
885 730 bojilova
  public String getPrincipals(String user, String password)
886 725 bojilova
                throws ConnectException
887
  {
888
    StringBuffer out = new StringBuffer();
889 726 bojilova
    Vector usersIn = new Vector();
890 2058 sgarg
891
    out.append("<?xml version=\"1.0\" encoding=\"US-ASCII\"?>\n");
892 730 bojilova
    out.append("<principals>\n");
893 2058 sgarg
894 730 bojilova
    /*
895 2058 sgarg
     * get all subtrees first in the current dir context
896 730 bojilova
     * and then the Metacat users under them
897
     */
898
    Hashtable subtrees = getSubtrees(user,password,this.ldapUrl,this.ldapBase);
899 2058 sgarg
900 730 bojilova
    Enumeration enum = subtrees.keys();
901
    while ( enum.hasMoreElements() ) {
902
      this.ldapBase = (String)enum.nextElement();
903
      this.ldapUrl = (String)subtrees.get(ldapBase);
904 2058 sgarg
905
      out.append("  <authSystem URI=\"" +
906 730 bojilova
                 this.ldapUrl + this.ldapBase + "\">\n");
907
908
      // get all groups for directory context
909 2058 sgarg
      String[][] groups = getGroups(user, password);
910
      String[][] users = getUsers(user, password);
911
      int userIndex = 0;
912 730 bojilova
913
      // for the groups and users that belong to them
914 976 tao
      if ( groups!=null && groups.length > 0 ) {
915 730 bojilova
        for (int i=0; i < groups.length; i++ ) {
916
          out.append("    <group>\n");
917 2058 sgarg
          out.append("      <groupname>" + groups[i][0] + "</groupname>\n");
918
          out.append("      <description>" + groups[i][1] + "</description>\n");
919
          String[] usersForGroup = getUsers(user,password,groups[i][0]);
920 730 bojilova
          for (int j=0; j < usersForGroup.length; j++ ) {
921
            usersIn.addElement(usersForGroup[j]);
922 2058 sgarg
923
            userIndex = searchUser(usersForGroup[j], users);
924 730 bojilova
            out.append("      <user>\n");
925 2058 sgarg
926
            if(userIndex < 0){
927 2095 sgarg
              out.append("        <username>" + usersForGroup[j] +
928
                         "</username>\n");
929 2058 sgarg
            } else {
930
              out.append("      <username>" + users[userIndex][0] + "</username>\n");
931
              out.append("      <name>" + users[userIndex][1] + "</name>\n");
932
              out.append("      <email>" + users[userIndex][2] + "</email>\n");
933
            }
934
935 730 bojilova
            out.append("      </user>\n");
936
          }
937
          out.append("    </group>\n");
938
        }
939
      }
940 2058 sgarg
941 730 bojilova
      // for the users not belonging to any group
942
      for (int j=0; j < users.length; j++ ) {
943 2058 sgarg
        if ( !usersIn.contains(users[j][0]) ) {
944 725 bojilova
          out.append("    <user>\n");
945 2058 sgarg
          out.append("      <username>" + users[j][0] + "</username>\n");
946
          out.append("      <name>" + users[j][1] + "</name>\n");
947
          out.append("      <email>" + users[j][2] + "</email>\n");
948 725 bojilova
          out.append("    </user>\n");
949
        }
950
      }
951 2058 sgarg
952 730 bojilova
      out.append("  </authSystem>\n");
953
      if ( !usersIn.isEmpty() ) {
954
        usersIn.removeAllElements();
955
        usersIn.trimToSize();
956 725 bojilova
      }
957 2058 sgarg
958 725 bojilova
    }
959
    out.append("</principals>");
960
    return out.toString();
961
  }
962
963 2058 sgarg
964 725 bojilova
  /**
965 2058 sgarg
   * Method for getting index of user DN in User info array
966
   */
967
  int searchUser(String user, String userGroup[][]){
968
    for (int j=0; j < userGroup.length; j++ ) {
969
      if (user.compareTo(userGroup[j][0]) == 0){
970
        return j;
971
      }
972
    }
973
    return -1;
974
  }
975
976
  /**
977 503 bojilova
   * Test method for the class
978
   */
979
  public static void main(String[] args) {
980
981 504 jones
    // Provide a user, such as: "Matt Jones", or "jones"
982 503 bojilova
    String user = args[0];
983
    String password = args[1];
984
985 1477 tao
    MetaCatUtil.debugMessage("Creating session...", 20);
986 503 bojilova
    AuthLdap authservice = new AuthLdap();
987 1477 tao
    MetaCatUtil.debugMessage("Session exists...", 20);
988 2058 sgarg
989 503 bojilova
    boolean isValid = false;
990
    try {
991 1477 tao
      MetaCatUtil.debugMessage("Authenticating...", 20);
992 503 bojilova
      isValid = authservice.authenticate(user, password);
993
      if (isValid) {
994 1477 tao
        MetaCatUtil.debugMessage("Authentication successful for: " + user, 20 );
995 503 bojilova
      } else {
996 1477 tao
        MetaCatUtil.debugMessage("Authentication failed for: " + user, 20);
997 503 bojilova
      }
998 725 bojilova
999 871 jones
      // Get attributes for the user
1000 503 bojilova
      if (isValid) {
1001 1477 tao
        MetaCatUtil.debugMessage("\nGetting attributes for user....", 20);
1002 991 tao
        HashMap userInfo = authservice.getAttributes(user, password, user);
1003 503 bojilova
        // Print all of the attributes
1004
        Iterator attList = (Iterator)(((Set)userInfo.keySet()).iterator());
1005
        while (attList.hasNext()) {
1006
          String att = (String)attList.next();
1007
          Vector values = (Vector)userInfo.get(att);
1008
          Iterator attvalues = values.iterator();
1009
          while (attvalues.hasNext()) {
1010
            String value = (String)attvalues.next();
1011 1477 tao
            MetaCatUtil.debugMessage(att + ": " + value, 20);
1012 503 bojilova
          }
1013
        }
1014 871 jones
      }
1015 723 bojilova
1016 871 jones
      // get the groups
1017
      if (isValid) {
1018 1477 tao
        MetaCatUtil.debugMessage("\nGetting all groups....", 20);
1019 2058 sgarg
        String[][] groups = authservice.getGroups(user, password);
1020 1477 tao
        MetaCatUtil.debugMessage("Groups found: " + groups.length, 20);
1021 871 jones
        for (int i=0; i < groups.length; i++) {
1022 2058 sgarg
            MetaCatUtil.debugMessage("Group " + i + ": " + groups[i][0], 20);
1023 871 jones
        }
1024 503 bojilova
      }
1025 725 bojilova
1026 871 jones
      // get the groups for the user
1027
      String savedGroup = null;
1028
      if (isValid) {
1029 1477 tao
        MetaCatUtil.debugMessage("\nGetting groups for user....", 20);
1030 2058 sgarg
        String[][] groups = authservice.getGroups(user, password, user);
1031 1477 tao
        MetaCatUtil.debugMessage("Groups found: " + groups.length, 20);
1032 871 jones
        for (int i=0; i < groups.length; i++) {
1033 2058 sgarg
            MetaCatUtil.debugMessage("Group " + i + ": " + groups[i][0], 20);
1034
            savedGroup = groups[i][0];
1035 871 jones
        }
1036
      }
1037
1038
      // get the users for a group
1039
      if (isValid) {
1040 1477 tao
        MetaCatUtil.debugMessage("\nGetting users for group....", 20);
1041
        MetaCatUtil.debugMessage("Group: " + savedGroup, 20);
1042 871 jones
        String[] users = authservice.getUsers(user, password, savedGroup);
1043 1477 tao
        MetaCatUtil.debugMessage("Users found: " + users.length, 20);
1044 871 jones
        for (int i=0; i < users.length; i++) {
1045 1477 tao
            MetaCatUtil.debugMessage("User " + i + ": " + users[i], 20);
1046 871 jones
        }
1047
      }
1048
1049
      // get all users
1050
      if (isValid) {
1051 1494 tao
        MetaCatUtil.debugMessage("\nGetting all users ....", 20);
1052 2058 sgarg
        String[][] users = authservice.getUsers(user, password);
1053 1494 tao
        MetaCatUtil.debugMessage("Users found: " + users.length, 20);
1054 2058 sgarg
1055 871 jones
      }
1056 873 jones
1057 726 bojilova
      // get the whole list groups and users in XML format
1058 725 bojilova
      if (isValid) {
1059 1494 tao
        MetaCatUtil.debugMessage("\nTrying principals....", 20);
1060 730 bojilova
        authservice = new AuthLdap();
1061 725 bojilova
        String out = authservice.getPrincipals(user, password);
1062 802 bojilova
        java.io.File f = new java.io.File("principals.xml");
1063 725 bojilova
        java.io.FileWriter fw = new java.io.FileWriter(f);
1064
        java.io.BufferedWriter buff = new java.io.BufferedWriter(fw);
1065
        buff.write(out);
1066
        buff.flush();
1067
        buff.close();
1068
        fw.close();
1069 1494 tao
        MetaCatUtil.debugMessage("\nFinished getting principals.", 20);
1070 725 bojilova
      }
1071 873 jones
1072 503 bojilova
    } catch (ConnectException ce) {
1073 1494 tao
      MetaCatUtil.debugMessage(ce.getMessage(), 30);
1074 725 bojilova
    } catch (java.io.IOException ioe) {
1075 1494 tao
      MetaCatUtil.debugMessage("I/O Error writing to file principals.txt", 20);
1076 503 bojilova
    }
1077
  }
1078 2058 sgarg
1079 934 tao
  /**
1080
   * This method will be called by start a thread.
1081
   * It can handle if a referral exception happend.
1082 2058 sgarg
   */
1083 893 berkley
  public void run()
1084
  {
1085
    referralContext = null;
1086 934 tao
    DirContext refDirContext=null;
1087
    boolean moreReferrals=true;
1088 1004 tao
    String referralInfo=null;
1089 934 tao
    //set a while loop is because we don't know if a referral excption contains
1090
    //another referral exception
1091 935 tao
    while (moreReferrals)
1092 934 tao
    {
1093
      try
1094 2058 sgarg
      {
1095 934 tao
        //revise environment variable
1096 1004 tao
        referralInfo=(String)refExc.getReferralInfo();
1097 1988 jones
        util.debugMessage("Processing referral (pr0): ", 35);
1098
        util.debugMessage("PROVIDER_URL set to (pr1): " + referralInfo, 35);
1099
        //env.put(Context.PROVIDER_URL,referralInfo);
1100
        //env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
1101
        //env.put(Context.SECURITY_PRINCIPAL, userName);
1102
        //env.put(Context.SECURITY_CREDENTIALS, userPassword);
1103
        //env.put(Context.REFERRAL, "throw");
1104
        //util.debugMessage("Processing referral (pr1.info): " + userName,35);
1105
        //util.debugMessage("Processing referral (pr2)",35);
1106
        //rContext = refExc.getReferralContext(env);
1107
        rContext = refExc.getReferralContext();
1108
        util.debugMessage("Processing referral (pr3)",35);
1109 934 tao
        //casting the context to dircontext and it will create a
1110
        //autherntication or naming exception if DN and password is incorrect
1111 991 tao
        referralContext=rContext;
1112
        refDirContext=(DirContext)rContext;
1113
        refDirContext.close();
1114 934 tao
        //get context and jump out the while loop
1115
        moreReferrals=false;
1116 1988 jones
        util.debugMessage("Processing referral (pr4)",35);
1117 934 tao
      }//try
1118 991 tao
      //if referral have another referral excption
1119 935 tao
      catch (ReferralException re)
1120 934 tao
      {
1121 1988 jones
        util.debugMessage("GOT referral exception (re1): " + re.getMessage(),35);
1122
        util.debugMessage("RE details (re2): " + re.toString(true),35);
1123 934 tao
        //keep running in while loop
1124
        moreReferrals=true;
1125
        //assign refExc to new referral exception re
1126
        refExc=re;
1127
      }
1128 991 tao
      //catch a authentication exception
1129 935 tao
      catch (AuthenticationException ae)
1130 934 tao
      {
1131 2058 sgarg
        util.debugMessage("Error running referral handler thread (ae1): " +
1132 1494 tao
                          ae.getMessage(), 20);
1133 934 tao
        //check if has another referral
1134
        moreReferrals=refExc.skipReferral();
1135
        //don't get the context
1136
        referralContext = null;
1137
      }
1138 991 tao
      //catch a naming exception
1139 935 tao
      catch (NamingException ne)
1140 934 tao
      {
1141 2058 sgarg
        util.debugMessage("Error running referral handler thread (ne1): " +
1142 1494 tao
                          ne.getMessage(), 20);
1143 934 tao
        //check if has another referral
1144
        moreReferrals=refExc.skipReferral();
1145
        //don't get context
1146 2058 sgarg
        referralContext = null;
1147 934 tao
      }
1148
    }//while
1149 930 tao
  }//run()
1150 2058 sgarg
1151 991 tao
  private class GetGroup implements Runnable
1152
  {
1153
    public void run()
1154
    {
1155
      referralContext = null;
1156 1494 tao
      MetaCatUtil.debugMessage("getting groups context", 50);
1157 991 tao
      DirContext refDirContext=null;
1158
      boolean moreReferrals=true;
1159 2058 sgarg
      //set a while loop is because we don't know if a referral excption
1160 991 tao
      //contains another referral exception
1161
      while (moreReferrals)
1162
      {
1163
        try
1164
        {
1165
          //revise environment variable
1166
          String refInfo = null;
1167
          refInfo = (String)refExc.getReferralInfo();
1168
          if(refInfo != null)
1169
          {
1170 2058 sgarg
            MetaCatUtil.debugMessage("Referral in thread to: " +
1171 1494 tao
                              refInfo.toString(), 40);
1172 991 tao
          }
1173
          else
1174
          {
1175 1494 tao
            MetaCatUtil.debugMessage("getting refInfo Manually", 50);
1176 991 tao
            refInfo = (String)refExc.getReferralContext().getEnvironment().
1177
                                                  get(Context.PROVIDER_URL);
1178
          }
1179 1494 tao
          MetaCatUtil.debugMessage("refInfo: " + refInfo, 40);
1180 2058 sgarg
1181
          env.put(Context.INITIAL_CONTEXT_FACTORY,
1182 991 tao
              "com.sun.jndi.ldap.LdapCtxFactory");
1183
          env.put(Context.REFERRAL, "throw");
1184
          env.put(Context.PROVIDER_URL, refInfo);
1185 2058 sgarg
1186 1494 tao
          MetaCatUtil.debugMessage("creating referralContext", 40);
1187 991 tao
          referralContext = new InitialDirContext(env);
1188 1494 tao
          MetaCatUtil.debugMessage("referralContext created", 40);
1189 991 tao
          //get context and jump out the while loop
1190
          moreReferrals=false;
1191
        }//try
1192
        catch (ReferralException re)
1193
        {
1194
          //keep running in while loop
1195
          moreReferrals=true;
1196
          //assign refExc to new referral exception re
1197
          refExc=re;
1198
        }
1199
        catch (AuthenticationException ae)
1200
        {
1201 2058 sgarg
          util.debugMessage("Error running referral handler thread (ae2): " +
1202 1494 tao
                          ae.getMessage(), 50);
1203 991 tao
          //check if has another referral
1204
          moreReferrals=refExc.skipReferral();
1205
          //don't get the context
1206
          referralContext = null;
1207
        }
1208
        catch (NamingException ne)
1209
        {
1210 2058 sgarg
          util.debugMessage("Error running referral handler thread (ne2): " +
1211 1494 tao
                          ne.getMessage(), 50);
1212 991 tao
          //check if has another referral
1213
          moreReferrals=refExc.skipReferral();
1214
          //don't get context
1215 2058 sgarg
          referralContext = null;
1216 991 tao
        }
1217
      }//while
1218
    }//run()
1219
 }
1220 503 bojilova
}