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: daigle $'
11
 *     '$Date: 2009-08-24 14:34:17 -0700 (Mon, 24 Aug 2009) $'
12
 * '$Revision: 5030 $'
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.Attribute;
38
import javax.naming.directory.Attributes;
39
import javax.naming.directory.DirContext;
40
import javax.naming.directory.InitialDirContext;
41
import javax.naming.directory.SearchResult;
42
import javax.naming.directory.SearchControls;
43
import javax.naming.ReferralException;
44
import javax.naming.ldap.InitialLdapContext;
45
import javax.naming.ldap.LdapContext;
46
import javax.naming.ldap.StartTlsRequest;
47
import javax.naming.ldap.StartTlsResponse;
48
import javax.net.ssl.SSLSession;
49

    
50
import org.apache.log4j.Logger;
51

    
52
import edu.ucsb.nceas.metacat.properties.PropertyService;
53
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
54

    
55
import java.lang.InstantiationException;
56
import java.net.URLDecoder;
57
import java.util.Iterator;
58
import java.util.HashMap;
59
import java.util.Hashtable;
60
import java.util.Enumeration;
61
import java.util.Set;
62
import java.util.Vector;
63

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

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

    
87
	/**
88
	 * Construct an AuthLdap
89
	 */
90
	public AuthLdap() throws InstantiationException {
91
		// Read LDAP URI for directory service information
92
		try {
93
			this.ldapUrl = PropertyService.getProperty("auth.url");
94
			this.ldapsUrl = PropertyService.getProperty("auth.surl");
95
			this.ldapBase = PropertyService.getProperty("auth.base");
96
			this.referral = PropertyService.getProperty("ldap.referral");
97
			this.ldapConnectTimeLimit = PropertyService
98
					.getProperty("ldap.connectTimeLimit");
99
			this.ldapSearchTimeLimit = Integer.parseInt(PropertyService
100
					.getProperty("ldap.searchTimeLimit"));
101
			this.ldapSearchCountLimit = Integer.parseInt(PropertyService
102
					.getProperty("ldap.searchCountLimit"));
103
		} catch (PropertyNotFoundException pnfe) {
104
			throw new InstantiationException(
105
					"Could not instantiate AuthLdap.  Property not found: "
106
							+ pnfe.getMessage());
107
		} catch (NumberFormatException nfe) {
108
			throw new InstantiationException(
109
					"Could not instantiate AuthLdap.  Bad number format when converting properties: "
110
							+ nfe.getMessage());
111
		}
112

    
113
		// Store referral info for use in building group DNs in getGroups()
114
		this.currentReferralInfo = "";
115
	}
116

    
117
	/**
118
	 * Determine if a user/password are valid according to the authentication
119
	 * service.
120
	 * 
121
	 * @param user
122
	 *            the name of the principal to authenticate
123
	 * @param password
124
	 *            the password to use for authentication
125
	 * @returns boolean true if authentication successful, false otherwise
126
	 */
127

    
128
	public boolean authenticate(String user, String password) throws ConnectException {
129
		String ldapUrl = this.ldapUrl;
130
		String ldapsUrl = this.ldapsUrl;
131
		String ldapBase = this.ldapBase;
132
		boolean authenticated = false;
133
		String identifier = user;
134

    
135
		// get uid here.
136
		if (user.indexOf(",") == -1) {
137
			throw new ConnectException("Invalid LDAP user credential: " + user
138
					+ ".  Missing ','");
139
		}
140
		String uid = user.substring(0, user.indexOf(","));
141
		user = user.substring(user.indexOf(","), user.length());
142

    
143
		logMetacat.debug("identifier: " + identifier);
144
		logMetacat.debug("uid: " + uid);
145
		logMetacat.debug("user: " + user);
146

    
147
		try {
148
			// Check the usename as passed in
149
			logMetacat.info("Calling ldapAuthenticate");
150
			logMetacat.info("with user as identifier: " + identifier);
151

    
152
			authenticated = ldapAuthenticate(identifier, password, (new Boolean(
153
					PropertyService.getProperty("ldap.onlySecureConnection")))
154
					.booleanValue());
155
			// if not found, try looking up a valid DN then auth again
156
			if (!authenticated) {
157
				logMetacat.info("Not Authenticated");
158
				logMetacat.info("Looking up DN for: " + identifier);
159
				identifier = getIdentifyingName(identifier, ldapUrl, ldapBase);
160
				if (identifier == null) {
161
					logMetacat.info("No DN found from getIdentifyingName");
162
					return authenticated;
163
				}
164

    
165
				logMetacat.info("DN found from getIdentifyingName: " + identifier);
166
				String decoded = URLDecoder.decode(identifier);
167
				logMetacat.info("DN decoded: " + decoded);
168
				identifier = decoded;
169
				String refUrl = "";
170
				String refBase = "";
171
				if (identifier.startsWith("ldap")) {
172
					logMetacat.debug("identifier starts with \"ldap\"");
173

    
174
					refUrl = identifier.substring(0, identifier.lastIndexOf("/") + 1);
175
					int position = identifier.indexOf(",");
176
					int position2 = identifier.indexOf(",", position + 1);
177

    
178
					refBase = identifier.substring(position2 + 1);
179
					identifier = identifier.substring(identifier.lastIndexOf("/") + 1);
180

    
181
					logMetacat.info("Calling ldapAuthenticate:");
182
					logMetacat.info("with user as identifier: " + identifier);
183
					logMetacat.info("and refUrl as: " + refUrl);
184
					logMetacat.info("and refBase as: " + refBase);
185

    
186
					authenticated = ldapAuthenticate(identifier, password, refUrl,
187
							refBase, (new Boolean(PropertyService
188
									.getProperty("ldap.onlySecureReferalsConnection")))
189
									.booleanValue());
190
				} else {
191
					logMetacat.info("identifier doesnt start with ldap");
192
					identifier = identifier + "," + ldapBase;
193

    
194
					logMetacat.info("Calling ldapAuthenticate");
195
					logMetacat.info("with user as identifier: " + identifier);
196

    
197
					authenticated = ldapAuthenticate(identifier, password, (new Boolean(
198
							PropertyService.getProperty("ldap.onlySecureConnection")))
199
							.booleanValue());
200
				}
201
			}
202
		} catch (NullPointerException e) {
203
			logMetacat.error("NullPointerException while authenticating in "
204
					+ "AuthLdap.authenticate: " + e);
205
			e.printStackTrace();
206

    
207
			throw new ConnectException("NullPointerException while authenticating in "
208
					+ "AuthLdap.authenticate: " + e);
209
		} catch (NamingException e) {
210
			logMetacat.error("Naming exception while authenticating in "
211
					+ "AuthLdap.authenticate: " + e);
212
			e.printStackTrace();
213
		} catch (Exception e) {
214
			logMetacat.error(e.getMessage());
215
		}
216

    
217
		return authenticated;
218
	}
219

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

    
236
	/**
237
	 * Connect to the LDAP directory and do the authentication using the
238
	 * username and password as passed into the routine.
239
	 * 
240
	 * @param identifier
241
	 *            the distinguished name to check against LDAP
242
	 * @param password
243
	 *            the password for authentication
244
	 */
245

    
246
	private boolean ldapAuthenticate(String dn, String password, String rootServer,
247
			String rootBase, boolean secureConnectionOnly) {
248

    
249
		boolean authenticated = false;
250

    
251
		String server = "";
252
		String userDN = "";
253
		logMetacat.info("dn is: " + dn);
254

    
255
		int position = dn.lastIndexOf("/");
256
		logMetacat.debug("position is: " + position);
257
		if (position == -1) {
258
			server = rootServer;
259
			if (dn.indexOf(userDN) < 0) {
260
				userDN = dn + "," + rootBase;
261
			} else {
262
				userDN = dn;
263
			}
264
			logMetacat.info("userDN is: " + userDN);
265

    
266
		} else {
267
			server = dn.substring(0, position + 1);
268
			userDN = dn.substring(position + 1);
269
			logMetacat.info("server is: " + server);
270
			logMetacat.info("userDN is: " + userDN);
271
		}
272

    
273
		logMetacat.warn("Trying to authenticate: " + userDN);
274
		logMetacat.warn("          Using server: " + server);
275

    
276
		LdapContext ctx = null;
277
		double startTime;
278
		double stopTime;
279
		try {
280
			Hashtable env = new Hashtable();
281
			env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
282
			env.put(Context.PROVIDER_URL, server);
283
			env.put(Context.REFERRAL, "throw");
284
			try {
285

    
286
				startTime = System.currentTimeMillis();
287
				ctx = new InitialLdapContext(env, null);
288
				// Start up TLS here so that we don't pass our jewels in
289
				// cleartext
290
				StartTlsResponse tls = (StartTlsResponse) ctx
291
						.extendedOperation(new StartTlsRequest());
292
				// tls.setHostnameVerifier(new SampleVerifier());
293
				SSLSession sess = tls.negotiate();
294
				ctx.addToEnvironment(Context.SECURITY_AUTHENTICATION, "simple");
295
				ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, userDN);
296
				ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, password);
297
				ctx.reconnect(null);
298
				stopTime = System.currentTimeMillis();
299
				logMetacat.info("Connection time thru " + ldapsUrl + " was: "
300
						+ (stopTime - startTime) / 1000 + " seconds.");
301
				authenticated = true;
302
			} catch (Exception ioe) {
303
				logMetacat.info("Caught IOException in login while negotiating TLS: "
304
						+ ioe.getMessage());
305

    
306
				if (secureConnectionOnly) {
307
					return authenticated;
308

    
309
				} else {
310
					logMetacat.info("Trying to authenticate without TLS");
311
					env.put(Context.SECURITY_AUTHENTICATION, "simple");
312
					env.put(Context.SECURITY_PRINCIPAL, userDN);
313
					env.put(Context.SECURITY_CREDENTIALS, password);
314

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

    
332
		return authenticated;
333
	}
334

    
335
	/**
336
	 * Get the identifying name for a given userid or name. This is the name
337
	 * that is used in conjunction withthe LDAP BaseDN to create a distinguished
338
	 * name (dn) for the record
339
	 * 
340
	 * @param user
341
	 *            the user for which the identifying name is requested
342
	 * @returns String the identifying name for the user, or null if not found
343
	 */
344
	private String getIdentifyingName(String user, String ldapUrl, String ldapBase)
345
			throws NamingException {
346

    
347
		String identifier = null;
348
		Hashtable env = new Hashtable();
349
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
350
		env.put(Context.REFERRAL, "throw");
351
		env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
352
		try {
353
			int position = user.indexOf(",");
354
			String uid = user.substring(user.indexOf("=") + 1, position);
355
			logMetacat.info("uid is: " + uid);
356
			String org = user.substring(user.indexOf("=", position + 1) + 1, user
357
					.indexOf(",", position + 1));
358
			logMetacat.info("org is: " + org);
359

    
360
			DirContext sctx = new InitialDirContext(env);
361
			SearchControls ctls = new SearchControls();
362
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
363
			String filter = "(&(uid=" + uid + ")(o=" + org + "))";
364
			logMetacat.warn("Searching for DNs with following filter: " + filter);
365

    
366
			for (boolean moreReferrals = true; moreReferrals;) {
367
				try {
368
					// Perform the search
369
					NamingEnumeration answer = sctx.search("", filter, ctls);
370

    
371
					// Return the answer
372
					while (answer.hasMore()) {
373
						SearchResult sr = (SearchResult) answer.next();
374
						identifier = sr.getName();
375
						return identifier;
376
					}
377
					// The search completes with no more referrals
378
					moreReferrals = false;
379
				} catch (ReferralException e) {
380
					logMetacat.info("Got referral: " + e.getReferralInfo());
381
					// Point to the new context from the referral
382
					if (moreReferrals) {
383
						sctx = (DirContext) e.getReferralContext();
384
					}
385
				}
386
			}
387
		} catch (NamingException e) {
388
			logMetacat.error("Naming exception while getting dn: " + e);
389
			throw new NamingException("Naming exception in AuthLdap.getIdentifyingName: "
390
					+ e);
391
		}
392
		return identifier;
393
	}
394

    
395
	/**
396
	 * Get all users from the authentication service
397
	 * 
398
	 * @param user
399
	 *            the user for authenticating against the service
400
	 * @param password
401
	 *            the password for authenticating against the service
402
	 * @returns string array of all of the user names
403
	 */
404
	public String[][] getUsers(String user, String password) throws ConnectException {
405
		String[][] users = null;
406

    
407
		// Identify service provider to use
408
		Hashtable env = new Hashtable(11);
409
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
410
		env.put(Context.REFERRAL, referral);
411
		env.put(Context.PROVIDER_URL, ldapUrl);
412
		env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
413

    
414
		try {
415

    
416
			// Create the initial directory context
417
			DirContext ctx = new InitialDirContext(env);
418

    
419
			// Specify the attributes to match.
420
			// Users are objects that have the attribute
421
			// objectclass=InetOrgPerson.
422
			SearchControls ctls = new SearchControls();
423
			String[] attrIDs = { "dn", "cn", "o", "ou", "mail" };
424
			ctls.setReturningAttributes(attrIDs);
425
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
426
			ctls.setTimeLimit(ldapSearchTimeLimit);
427
			// ctls.setCountLimit(1000);
428
			String filter = "(objectClass=inetOrgPerson)";
429
			NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
430

    
431
			// Store the users in a vector
432
			Vector uvec = new Vector();
433
			Vector uname = new Vector();
434
			Vector uorg = new Vector();
435
			Vector uou = new Vector();
436
			Vector umail = new Vector();
437
			Attributes tempAttr = null;
438
			try {
439
				while (namingEnum.hasMore()) {
440
					SearchResult sr = (SearchResult) namingEnum.next();
441
					tempAttr = sr.getAttributes();
442

    
443
					if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
444
						uname.add((tempAttr.get("cn") + "").substring(4));
445
					} else {
446
						uname.add(tempAttr.get("cn") + "");
447
					}
448

    
449
					if ((tempAttr.get("o") + "").startsWith("o: ")) {
450
						uorg.add((tempAttr.get("o") + "").substring(3));
451
					} else {
452
						uorg.add(tempAttr.get("o") + "");
453
					}
454

    
455
					if ((tempAttr.get("ou") + "").startsWith("ou: ")) {
456
						uou.add((tempAttr.get("ou") + "").substring(4));
457
					} else {
458
						uou.add(tempAttr.get("ou") + "");
459
					}
460

    
461
					if ((tempAttr.get("mail") + "").startsWith("mail: ")) {
462
						umail.add((tempAttr.get("mail") + "").substring(6));
463
					} else {
464
						umail.add(tempAttr.get("mail") + "");
465
					}
466

    
467
					uvec.add(sr.getName() + "," + ldapBase);
468
				}
469
			} catch (SizeLimitExceededException slee) {
470
				logMetacat.error("LDAP Server size limit exceeded. "
471
						+ "Returning incomplete record set.");
472
			}
473

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

    
484
			// Close the context when we're done
485
			ctx.close();
486

    
487
		} catch (NamingException e) {
488
			logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
489
			// e.printStackTrace(System.err);
490
			/*
491
			 * throw new ConnectException( "Problem getting users in
492
			 * AuthLdap.getUsers:" + e);
493
			 */
494
		}
495

    
496
		return users;
497
	}
498

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

    
511
		// Identify service provider to use
512
		Hashtable env = new Hashtable(11);
513
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
514
		env.put(Context.REFERRAL, referral);
515
		env.put(Context.PROVIDER_URL, ldapUrl);
516

    
517
		try {
518

    
519
			// Create the initial directory context
520
			DirContext ctx = new InitialDirContext(env);
521
			// Specify the attributes to match.
522
			// Users are objects that have the attribute
523
			// objectclass=InetOrgPerson.
524
			SearchControls ctls = new SearchControls();
525
			String[] attrIDs = { "cn", "o", "mail" };
526
			ctls.setReturningAttributes(attrIDs);
527
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
528
			// ctls.setCountLimit(1000);
529
			// create the filter based on the uid
530

    
531
			String filter = null;
532

    
533
			if (user.indexOf("o=") > 0) {
534
				String tempStr = user.substring(user.indexOf("o="));
535
				filter = "(&(" + user.substring(0, user.indexOf(",")) + ")("
536
						+ tempStr.substring(0, tempStr.indexOf(",")) + "))";
537
			} else {
538
				filter = "(&(" + user.substring(0, user.indexOf(",")) + "))";
539
			}
540
			filter = "(&(" + user.substring(0, user.indexOf(",")) + "))";
541

    
542
			NamingEnumeration namingEnum = ctx.search(user, filter, ctls);
543

    
544
			Attributes tempAttr = null;
545
			try {
546
				while (namingEnum.hasMore()) {
547
					SearchResult sr = (SearchResult) namingEnum.next();
548
					tempAttr = sr.getAttributes();
549

    
550
					if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
551
						userinfo[0] = (tempAttr.get("cn") + "").substring(4);
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
					} else {
559
						userinfo[1] = (tempAttr.get("o") + "");
560
					}
561

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

    
573
			// Close the context when we're done
574
			ctx.close();
575

    
576
		} catch (NamingException e) {
577
			logMetacat.error("Problem getting users in AuthLdap.getUsers:" + e);
578
			// e.printStackTrace(System.err);
579
			throw new ConnectException("Problem getting users in AuthLdap.getUsers:" + e);
580
		}
581

    
582
		return userinfo;
583
	}
584

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

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

    
606
		try {
607

    
608
			// Create the initial directory context
609
			DirContext ctx = new InitialDirContext(env);
610

    
611
			// Specify the ids of the attributes to return
612
			String[] attrIDs = { "uniqueMember" };
613

    
614
			Attributes answer = ctx.getAttributes(group, attrIDs);
615

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

    
630
			// initialize users[]; fill users[]
631
			users = new String[uvec.size()];
632
			for (int i = 0; i < uvec.size(); i++) {
633
				users[i] = (String) uvec.elementAt(i);
634
			}
635

    
636
			// Close the context when we're done
637
			ctx.close();
638

    
639
		} catch (NamingException e) {
640
			logMetacat.error("Problem getting users for a group in "
641
					+ "AuthLdap.getUsers:" + e);
642
			/*
643
			 * throw new ConnectException( "Problem getting users for a group in
644
			 * AuthLdap.getUsers:" + e);
645
			 */
646
		}
647

    
648
		return users;
649
	}
650

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

    
664
	/**
665
	 * Get the groups for a particular user from the authentication service
666
	 * 
667
	 * @param user
668
	 *            the user for authenticating against the service
669
	 * @param password
670
	 *            the password for authenticating against the service
671
	 * @param foruser
672
	 *            the user whose group list should be returned
673
	 * @returns string array of the group names
674
	 */
675
	public String[][] getGroups(String user, String password, String foruser)
676
			throws ConnectException {
677

    
678
		logMetacat.debug("getGroups() called.");
679

    
680
		// create vectors to store group and dscription values returned from the
681
		// ldap servers
682
		Vector gvec = new Vector();
683
		Vector desc = new Vector();
684
		Attributes tempAttr = null;
685
		Attributes rsrAttr = null;
686

    
687
		// DURING getGroups(), DO WE NOT BIND USING userName AND userPassword??
688
		// NEED TO FIX THIS ...
689
		userName = user;
690
		userPassword = password;
691
		// Identify service provider to use
692
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
693
		env.put(Context.REFERRAL, "throw");
694
		env.put(Context.PROVIDER_URL, ldapUrl);
695
		env.put("com.sun.jndi.ldap.connect.timeout", ldapConnectTimeLimit);
696

    
697
		// Iterate through the referrals, handling NamingExceptions in the
698
		// outer catch statement, ReferralExceptions in the inner catch
699
		// statement
700
		try { // outer try
701

    
702
			// Create the initial directory context
703
			DirContext ctx = new InitialDirContext(env);
704

    
705
			// Specify the attributes to match.
706
			// Groups are objects with attribute objectclass=groupofuniquenames.
707
			// and have attribute uniquemember: uid=foruser,ldapbase.
708
			SearchControls ctls = new SearchControls();
709
			// Specify the ids of the attributes to return
710
			String[] attrIDs = { "cn", "o", "description" };
711
			ctls.setReturningAttributes(attrIDs);
712
			// set the ldap search scope
713
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
714
			// set a 10 second time limit on searches to limit non-responding
715
			// servers
716
			ctls.setTimeLimit(ldapSearchTimeLimit);
717
			// return at most 20000 entries
718
			ctls.setCountLimit(ldapSearchCountLimit);
719

    
720
			// build the ldap search filter that represents the "group" concept
721
			String filter = null;
722
			String gfilter = "(objectClass=groupOfUniqueNames)";
723
			if (null == foruser) {
724
				filter = gfilter;
725
			} else {
726
				filter = "(& " + gfilter + "(uniqueMember=" + foruser + "))";
727
			}
728
			logMetacat.info("group filter is: " + filter);
729

    
730
			// now, search and iterate through the referrals
731
			for (boolean moreReferrals = true; moreReferrals;) {
732
				try { // inner try
733

    
734
					NamingEnumeration namingEnum = ctx.search(ldapBase, filter, ctls);
735

    
736
					// Print the groups
737
					while (namingEnum.hasMore()) {
738
						SearchResult sr = (SearchResult) namingEnum.next();
739

    
740
						tempAttr = sr.getAttributes();
741

    
742
						if ((tempAttr.get("description") + "")
743
								.startsWith("description: ")) {
744
							desc.add((tempAttr.get("description") + "").substring(13));
745
						} else {
746
							desc.add(tempAttr.get("description") + "");
747
						}
748

    
749
						// check for an absolute URL value or an answer value
750
						// relative
751
						// to the target context
752
						if (!sr.getName().startsWith("ldap") && sr.isRelative()) {
753
							logMetacat.debug("Search result entry is relative ...");
754
							gvec.add(sr.getName() + "," + ldapBase);
755
							logMetacat.info("group " + sr.getName() + "," + ldapBase
756
									+ " added to the group vector");
757
						} else {
758
							logMetacat.debug("Search result entry is absolute ...");
759

    
760
							// search the top level directory for referral
761
							// objects and match
762
							// that of the search result's absolute URL. This
763
							// will let us
764
							// rebuild the group name from the search result,
765
							// referral point
766
							// in the top directory tree, and ldapBase.
767

    
768
							// configure a new directory search first
769
							Hashtable envHash = new Hashtable(11);
770
							// Identify service provider to use
771
							envHash.put(Context.INITIAL_CONTEXT_FACTORY,
772
									"com.sun.jndi.ldap.LdapCtxFactory");
773
							envHash.put(Context.REFERRAL, "ignore");
774
							envHash.put(Context.PROVIDER_URL, ldapUrl);
775
							envHash.put("com.sun.jndi.ldap.connect.timeout",
776
									ldapConnectTimeLimit);
777

    
778
							try {
779
								// Create the initial directory context
780
								DirContext DirCtx = new InitialDirContext(envHash);
781

    
782
								SearchControls searchCtls = new SearchControls();
783
								// Specify the ids of the attributes to return
784
								String[] attrNames = { "o" };
785
								searchCtls.setReturningAttributes(attrNames);
786
								// set the ldap search scope - only look for top
787
								// level referrals
788
								searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
789
								// set a time limit on searches to limit
790
								// non-responding servers
791
								searchCtls.setTimeLimit(ldapSearchTimeLimit);
792
								// return the configured number of entries
793
								searchCtls.setCountLimit(ldapSearchCountLimit);
794

    
795
								// Specify the attributes to match.
796
								// build the ldap search filter to match
797
								// referral entries that
798
								// match the search result
799
								String rFilter = "(&(objectClass=referral)(ref="
800
										+ currentReferralInfo.substring(0,
801
												currentReferralInfo.indexOf("?")) + "))";
802
								logMetacat.debug("rFilter is: " + rFilter);
803

    
804
								NamingEnumeration rNamingEnum = DirCtx.search(ldapBase,
805
										rFilter, searchCtls);
806

    
807
								while (rNamingEnum.hasMore()) {
808
									SearchResult rsr = (SearchResult) rNamingEnum.next();
809
									rsrAttr = rsr.getAttributes();
810
									logMetacat.debug("referral search result is: "
811
											+ rsr.toString());
812

    
813
									// add the returned groups to the group
814
									// vector. Test the
815
									// syntax of the returned attributes -
816
									// sometimes they are
817
									// preceded with the attribute id and a
818
									// colon
819
									if ((tempAttr.get("cn") + "").startsWith("cn: ")) {
820
										gvec.add("cn="
821
												+ (tempAttr.get("cn") + "").substring(4)
822
												+ "," + "o="
823
												+ (rsrAttr.get("o") + "").substring(3)
824
												+ "," + ldapBase);
825
										logMetacat.info("group "
826
												+ (tempAttr.get("cn") + "").substring(4)
827
												+ "," + "o="
828
												+ (rsrAttr.get("o") + "").substring(3)
829
												+ "," + ldapBase
830
												+ " added to the group vector");
831
									} else {
832
										gvec.add("cn=" + tempAttr.get("cn") + "," + "o="
833
												+ rsrAttr.get("o") + "," + ldapBase);
834
										logMetacat.info("group " + "cn="
835
												+ tempAttr.get("cn") + "," + "o="
836
												+ rsrAttr.get("o") + "," + ldapBase
837
												+ " added to the group vector");
838
									}
839
								}
840

    
841
							} catch (NamingException nameEx) {
842
								logMetacat.debug("Caught naming exception: ");
843
								nameEx.printStackTrace(System.err);
844
							}
845
						}
846
					}// end while
847

    
848
					moreReferrals = false;
849

    
850
				} catch (ReferralException re) {
851

    
852
					logMetacat
853
							.info("In AuthLdap.getGroups(), caught referral exception: "
854
									+ re.getReferralInfo());
855
					this.currentReferralInfo = (String) re.getReferralInfo();
856

    
857
					// set moreReferrals to true and set the referral context
858
					moreReferrals = true;
859
					ctx = (DirContext) re.getReferralContext();
860

    
861
				}// end inner try
862
			}// end for
863

    
864
			// close the context now that all initial and referral
865
			// searches are processed
866
			ctx.close();
867

    
868
		} catch (NamingException e) {
869

    
870
			// naming exceptions get logged, groups are returned
871
			logMetacat.info("In AuthLdap.getGroups(), caught naming exception: ");
872
			e.printStackTrace(System.err);
873

    
874
		} finally {
875
			// once all referrals are followed, report and return the groups
876
			// found
877
			logMetacat.warn("The user is in the following groups: " + gvec.toString());
878
			// build and return the groups array
879
			String groups[][] = new String[gvec.size()][2];
880
			for (int i = 0; i < gvec.size(); i++) {
881
				groups[i][0] = (String) gvec.elementAt(i);
882
				groups[i][1] = (String) desc.elementAt(i);
883
			}
884
			return groups;
885
		}// end outer try
886
	}
887

    
888
	/**
889
	 * Get attributes describing a user or group
890
	 * 
891
	 * @param foruser
892
	 *            the user for which the attribute list is requested
893
	 * @returns HashMap a map of attribute name to a Vector of values
894
	 */
895
	public HashMap<String, Vector<String>> getAttributes(String foruser)
896
			throws ConnectException {
897
		return getAttributes(null, null, foruser);
898
	}
899

    
900
	/**
901
	 * Get attributes describing a user or group
902
	 * 
903
	 * @param user
904
	 *            the user for authenticating against the service
905
	 * @param password
906
	 *            the password for authenticating against the service
907
	 * @param foruser
908
	 *            the user whose attributes should be returned
909
	 * @returns HashMap a map of attribute name to a Vector of values
910
	 */
911
	public HashMap<String, Vector<String>> getAttributes(String user, String password,
912
			String foruser) throws ConnectException {
913
		HashMap<String, Vector<String>> attributes = new HashMap<String, Vector<String>>();
914
		String ldapUrl = this.ldapUrl;
915
		String ldapBase = this.ldapBase;
916
		String userident = foruser;
917

    
918
		// Identify service provider to use
919
		Hashtable env = new Hashtable(11);
920
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
921
		env.put(Context.REFERRAL, referral);
922
		env.put(Context.PROVIDER_URL, ldapUrl);
923

    
924
		try {
925

    
926
			// Create the initial directory context
927
			DirContext ctx = new InitialDirContext(env);
928

    
929
			// Ask for all attributes of the user
930
			// Attributes attrs = ctx.getAttributes(userident);
931
			Attributes attrs = ctx.getAttributes(foruser);
932

    
933
			// Print all of the attributes
934
			NamingEnumeration en = attrs.getAll();
935
			while (en.hasMore()) {
936
				Attribute att = (Attribute) en.next();
937
				Vector<String> values = new Vector();
938
				String attName = att.getID();
939
				NamingEnumeration attvalues = att.getAll();
940
				while (attvalues.hasMore()) {
941
					String value = (String) attvalues.next();
942
					values.add(value);
943
				}
944
				attributes.put(attName, values);
945
			}
946

    
947
			// Close the context when we're done
948
			ctx.close();
949
		} catch (NamingException e) {
950
			logMetacat.error("Problem getting attributes in " + "AuthLdap.getAttributes:"
951
					+ e);
952
			throw new ConnectException(
953
					"Problem getting attributes in AuthLdap.getAttributes:" + e);
954
		}
955

    
956
		return attributes;
957
	}
958

    
959
	/**
960
	 * Get list of all subtrees holding Metacat's groups and users starting from
961
	 * the Metacat LDAP root, i.e.
962
	 * ldap://dev.nceas.ucsb.edu/dc=ecoinformatics,dc=org
963
	 */
964
	private Hashtable getSubtrees(String user, String password, String ldapUrl,
965
			String ldapBase) throws ConnectException {
966
		Hashtable trees = new Hashtable();
967

    
968
		// Identify service provider to use
969
		Hashtable env = new Hashtable(11);
970
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
971
		// env.put(Context.REFERRAL, referral);
972
		// Using 'ignore' here instead of 'follow' as 'ignore' seems
973
		// to do the job better. 'follow' was not bringing up the UCNRS
974
		// and PISCO tree whereas 'ignore' brings up the tree.
975

    
976
		env.put(Context.REFERRAL, "ignore");
977
		env.put(Context.PROVIDER_URL, ldapUrl + ldapBase);
978

    
979
		try {
980

    
981
			// Create the initial directory context
982
			DirContext ctx = new InitialDirContext(env);
983

    
984
			// Specify the ids of the attributes to return
985
			String[] attrIDs = { "o", "ref" };
986
			SearchControls ctls = new SearchControls();
987
			ctls.setReturningAttributes(attrIDs);
988
			ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
989

    
990
			// Specify the attributes to match.
991
			// Subtrees from the main server are found as objects with attribute
992
			// objectclass=organization or objectclass=referral to the subtree
993
			// resided on other server.
994
			String filter = "(|(objectclass=organization)(objectclass=referral))";
995

    
996
			// Search for objects in the current context
997
			NamingEnumeration namingEnum = ctx.search("", filter, ctls);
998

    
999
			// Print the subtrees' <ldapURL, baseDN>
1000
			while (namingEnum.hasMore()) {
1001

    
1002
				SearchResult sr = (SearchResult) namingEnum.next();
1003

    
1004
				Attributes attrs = sr.getAttributes();
1005
				NamingEnumeration enum1 = attrs.getAll(); // "dc" and "ref"
1006
															// attrs
1007

    
1008
				if (enum1.hasMore()) {
1009
					Attribute attr = (Attribute) enum1.next();
1010
					String attrValue = (String) attr.get();
1011
					String attrName = (String) attr.getID();
1012

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

    
1035
							// trees.put(refName + "=" + refValue + "," +
1036
							// ldapBase,
1037
							// attrValue.substring(0, attrValue.lastIndexOf("/")
1038
							// + 1));
1039
						}
1040

    
1041
					} else if (ldapBase.startsWith(attrName + "=" + attrValue)) {
1042
						trees.put(ldapBase, ldapUrl);
1043
					} else {
1044
						if (sr.isRelative()) {
1045
							trees.put(attrName + "=" + attrValue + "," + ldapBase,
1046
									ldapUrl);
1047
						} else {
1048
							String referenceURL = sr.getName();
1049
							referenceURL = referenceURL.substring(0, referenceURL
1050
									.lastIndexOf("/") + 1);
1051
							trees.put(attrName + "=" + attrValue + "," + ldapBase,
1052
									referenceURL);
1053
						}
1054

    
1055
					}
1056
				}
1057
			}
1058

    
1059
			// Close the context when we're done
1060
			ctx.close();
1061

    
1062
		} catch (NamingException e) {
1063
			logMetacat.error("Problem getting subtrees in AuthLdap.getSubtrees:" + e);
1064
			throw new ConnectException(
1065
					"Problem getting subtrees in AuthLdap.getSubtrees:" + e);
1066
		}
1067

    
1068
		return trees;
1069
	}
1070

    
1071
	/**
1072
	 * Get all groups and users from authentication scheme. The output is
1073
	 * formatted in XML.
1074
	 * 
1075
	 * @param user
1076
	 *            the user which requests the information
1077
	 * @param password
1078
	 *            the user's password
1079
	 */
1080
	public String getPrincipals(String user, String password) throws ConnectException {
1081
		StringBuffer out = new StringBuffer();
1082

    
1083
		out.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
1084
		out.append("<principals>\n");
1085

    
1086
		/*
1087
		 * get all subtrees first in the current dir context and then the
1088
		 * Metacat users under them
1089
		 */
1090
		Hashtable subtrees = getSubtrees(user, password, this.ldapUrl, this.ldapBase);
1091

    
1092
		Enumeration keyEnum = subtrees.keys();
1093
		while (keyEnum.hasMoreElements()) {
1094
			this.ldapBase = (String) keyEnum.nextElement();
1095
			this.ldapUrl = (String) subtrees.get(ldapBase);
1096
			logMetacat.info("ldapBase " + ldapBase);
1097
			logMetacat.info("ldapUrl " + ldapUrl);
1098
			/*
1099
			 * code to get the organization name from ldapBase
1100
			 */
1101
			String orgName = this.ldapBase;
1102
			if (orgName.startsWith("[")) {
1103
				// if orgName starts with [ then it is a referral URL...
1104
				// (see code in getSubtress)
1105
				// hence orgName can be retrieved by getting the string between
1106
				// 'o=' and ']'
1107
				// also the string between [ and ] needs to be striped out from
1108
				// this.ldapBase
1109
				this.ldapBase = orgName.substring(orgName.indexOf("]") + 1);
1110
				if (orgName != null && orgName.indexOf("o=") > -1) {
1111
					orgName = orgName.substring(orgName.indexOf("o=") + 2);
1112
					orgName = orgName.substring(0, orgName.indexOf("]"));
1113
				}
1114
			} else {
1115
				// else it is not referral
1116
				// hence orgName can be retrieved by getting the string between
1117
				// 'o=' and ','
1118
				if (orgName != null && orgName.indexOf("o=") > -1) {
1119
					orgName = orgName.substring(orgName.indexOf("o=") + 2);
1120
					if (orgName.indexOf(",") > -1) {
1121
						orgName = orgName.substring(0, orgName.indexOf(","));
1122
					}
1123
				}
1124
			}
1125
			logMetacat.info("org name is  " + orgName);
1126
			out.append("  <authSystem URI=\"" + this.ldapUrl + this.ldapBase
1127
					+ "\" organization=\"" + orgName + "\">\n");
1128

    
1129
			// get all groups for directory context
1130
			String[][] groups = getGroups(user, password);
1131
			logMetacat.debug("after getting groups " + groups);
1132
			String[][] users = getUsers(user, password);
1133
			logMetacat.debug("after getting users " + users);
1134
			int userIndex = 0;
1135

    
1136
			// for the groups and users that belong to them
1137
			if (groups != null && users != null && groups.length > 0) {
1138
				for (int i = 0; i < groups.length; i++) {
1139
					out.append("    <group>\n");
1140
					out.append("      <groupname>" + groups[i][0] + "</groupname>\n");
1141
					out.append("      <description>" + groups[i][1] + "</description>\n");
1142
					String[] usersForGroup = getUsers(user, password, groups[i][0]);
1143
					for (int j = 0; j < usersForGroup.length; j++) {
1144
						userIndex = searchUser(usersForGroup[j], users);
1145
						out.append("      <user>\n");
1146

    
1147
						if (userIndex < 0) {
1148
							out.append("        <username>" + usersForGroup[j]
1149
									+ "</username>\n");
1150
						} else {
1151
							out.append("        <username>" + users[userIndex][0]
1152
									+ "</username>\n");
1153
							out.append("        <name>" + users[userIndex][1]
1154
									+ "</name>\n");
1155
							out.append("        <organization>" + users[userIndex][2]
1156
									+ "</organization>\n");
1157
							if (users[userIndex][3].compareTo("null") != 0) {
1158
								out.append("      <organizationUnitName>"
1159
										+ users[userIndex][3]
1160
										+ "</organizationUnitName>\n");
1161
							}
1162
							out.append("        <email>" + users[userIndex][4]
1163
									+ "</email>\n");
1164
						}
1165

    
1166
						out.append("      </user>\n");
1167
					}
1168
					out.append("    </group>\n");
1169
				}
1170
			}
1171

    
1172
			if (users != null) {
1173
				// for the users not belonging to any grou8p
1174
				for (int j = 0; j < users.length; j++) {
1175
					out.append("    <user>\n");
1176
					out.append("      <username>" + users[j][0] + "</username>\n");
1177
					out.append("      <name>" + users[j][1] + "</name>\n");
1178
					out
1179
							.append("      <organization>" + users[j][2]
1180
									+ "</organization>\n");
1181
					if (users[j][3].compareTo("null") != 0) {
1182
						out.append("      <organizationUnitName>" + users[j][3]
1183
								+ "</organizationUnitName>\n");
1184
					}
1185
					out.append("      <email>" + users[j][4] + "</email>\n");
1186
					out.append("    </user>\n");
1187
				}
1188
			}
1189

    
1190
			out.append("  </authSystem>\n");
1191
		}
1192
		out.append("</principals>");
1193
		return out.toString();
1194
	}
1195

    
1196
	/**
1197
	 * Method for getting index of user DN in User info array
1198
	 */
1199
	int searchUser(String user, String userGroup[][]) {
1200
		for (int j = 0; j < userGroup.length; j++) {
1201
			if (user.compareTo(userGroup[j][0]) == 0) {
1202
				return j;
1203
			}
1204
		}
1205
		return -1;
1206
	}
1207

    
1208
	public void testCredentials(String dn, String password, String rootServer,
1209
			String rootBase) throws NamingException {
1210

    
1211
		String server = "";
1212
		String userDN = "";
1213
		logMetacat.debug("dn is: " + dn);
1214

    
1215
		int position = dn.lastIndexOf("/");
1216
		logMetacat.debug("position is: " + position);
1217
		if (position == -1) {
1218
			server = rootServer;
1219
			if (dn.indexOf(userDN) < 0) {
1220
				userDN = dn + "," + rootBase;
1221
			} else {
1222
				userDN = dn;
1223
			}
1224
			logMetacat.debug("userDN is: " + userDN);
1225

    
1226
		} else {
1227
			server = dn.substring(0, position + 1);
1228
			userDN = dn.substring(position + 1);
1229
			logMetacat.debug("server is: " + server);
1230
			logMetacat.debug("userDN is: " + userDN);
1231
		}
1232

    
1233
		logMetacat.debug("Trying to authenticate: " + userDN);
1234
		logMetacat.debug("          Using server: " + server);
1235

    
1236
		// /* try {
1237
		LdapContext ctx = null;
1238

    
1239
		env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
1240
		env.put(Context.REFERRAL, "follow");
1241
		env.put(Context.SECURITY_AUTHENTICATION, "simple");
1242
		env.put(Context.SECURITY_PRINCIPAL, userDN);
1243
		env.put(Context.SECURITY_CREDENTIALS, password);
1244
		env.put(Context.PROVIDER_URL, rootServer);
1245

    
1246
		ctx = new InitialLdapContext(env, null);
1247

    
1248
	}
1249

    
1250
	/**
1251
	 * Test method for the class
1252
	 */
1253
	public static void main(String[] args) {
1254

    
1255
		// Provide a user, such as: "Matt Jones", or "jones"
1256
		String user = args[0];
1257
		String password = args[1];
1258
		String org = args[2];
1259

    
1260
		logMetacat.warn("Creating session...");
1261
		AuthLdap authservice = null;
1262
		try {
1263
			authservice = new AuthLdap();
1264
		} catch (Exception e) {
1265
			logMetacat.error("Could not instantiate AuthLdap: " + e.getMessage());
1266
			return;
1267
		}
1268
		logMetacat.warn("Session exists...");
1269

    
1270
		boolean isValid = false;
1271
		try {
1272
			logMetacat.warn("Authenticating...");
1273
			isValid = authservice.authenticate(user, password);
1274
			if (isValid) {
1275
				logMetacat.warn("Authentication successful for: " + user);
1276
			} else {
1277
				logMetacat.warn("Authentication failed for: " + user);
1278
			}
1279

    
1280
			// Get attributes for the user
1281
			if (isValid) {
1282
				logMetacat.info("\nGetting attributes for user....");
1283
				HashMap userInfo = authservice.getAttributes(user, password, user);
1284
				// Print all of the attributes
1285
				Iterator attList = (Iterator) (((Set) userInfo.keySet()).iterator());
1286
				while (attList.hasNext()) {
1287
					String att = (String) attList.next();
1288
					Vector values = (Vector) userInfo.get(att);
1289
					Iterator attvalues = values.iterator();
1290
					while (attvalues.hasNext()) {
1291
						String value = (String) attvalues.next();
1292
						logMetacat.warn(att + ": " + value);
1293
					}
1294
				}
1295
			}
1296

    
1297
			// get the groups
1298
			if (isValid) {
1299
				logMetacat.warn("\nGetting all groups....");
1300
				String[][] groups = authservice.getGroups(user, password);
1301
				logMetacat.info("Groups found: " + groups.length);
1302
				for (int i = 0; i < groups.length; i++) {
1303
					logMetacat.info("Group " + i + ": " + groups[i][0]);
1304
				}
1305
			}
1306

    
1307
			// get the groups for the user
1308
			String savedGroup = null;
1309
			if (isValid) {
1310
				logMetacat.warn("\nGetting groups for user....");
1311
				String[][] groups = authservice.getGroups(user, password, user);
1312
				logMetacat.info("Groups found: " + groups.length);
1313
				for (int i = 0; i < groups.length; i++) {
1314
					logMetacat.info("Group " + i + ": " + groups[i][0]);
1315
					savedGroup = groups[i][0];
1316
				}
1317
			}
1318

    
1319
			// get the users for a group
1320
			if (isValid) {
1321
				logMetacat.warn("\nGetting users for group....");
1322
				logMetacat.info("Group: " + savedGroup);
1323
				String[] users = authservice.getUsers(user, password, savedGroup);
1324
				logMetacat.info("Users found: " + users.length);
1325
				for (int i = 0; i < users.length; i++) {
1326
					logMetacat.warn("User " + i + ": " + users[i]);
1327
				}
1328
			}
1329

    
1330
			// get all users
1331
			if (isValid) {
1332
				logMetacat.warn("\nGetting all users ....");
1333
				String[][] users = authservice.getUsers(user, password);
1334
				logMetacat.info("Users found: " + users.length);
1335

    
1336
			}
1337

    
1338
			// get the whole list groups and users in XML format
1339
			if (isValid) {
1340
				logMetacat.warn("\nTrying principals....");
1341
				authservice = new AuthLdap();
1342
				String out = authservice.getPrincipals(user, password);
1343
				java.io.File f = new java.io.File("principals.xml");
1344
				java.io.FileWriter fw = new java.io.FileWriter(f);
1345
				java.io.BufferedWriter buff = new java.io.BufferedWriter(fw);
1346
				buff.write(out);
1347
				buff.flush();
1348
				buff.close();
1349
				fw.close();
1350
				logMetacat.warn("\nFinished getting principals.");
1351
			}
1352

    
1353
		} catch (ConnectException ce) {
1354
			logMetacat.error(ce.getMessage());
1355
		} catch (java.io.IOException ioe) {
1356
			logMetacat.error("I/O Error writing to file principals.txt: "
1357
					+ ioe.getMessage());
1358
		} catch (InstantiationException ie) {
1359
			logMetacat.error("Instantiation error writing to file principals.txt: "
1360
					+ ie.getMessage());
1361
		}
1362
	}
1363

    
1364
	/**
1365
	 * This method will be called by start a thread. It can handle if a referral
1366
	 * exception happend.
1367
	 */
1368
}
(11-11/63)