001: /**
002: * Copyright 2002 Sun Microsystems, Inc. All
003: * rights reserved. Use of this product is subject
004: * to license terms. Federal Acquisitions:
005: * Commercial Software -- Government Users
006: * Subject to Standard License Terms and
007: * Conditions.
008: *
009: * Sun, Sun Microsystems, the Sun logo, and iPlanet
010: * are trademarks or registered trademarks of Sun Microsystems,
011: * Inc. in the United States and other countries.
012: */package com.sun.addressbook.ldap;
013:
014: import java.util.ArrayList;
015: import java.util.Properties;
016: import java.util.Enumeration;
017: import java.util.Hashtable;
018: import java.util.logging.Logger;
019: import java.util.logging.Level;
020: import java.util.logging.LogRecord;
021:
022: import com.sun.addressbook.ABFilter;
023: import com.sun.addressbook.ABSearchTerm;
024: import com.sun.addressbook.ABStoreException;
025: import com.sun.addressbook.Entry;
026: import com.sun.addressbook.ABSession;
027: import com.sun.addressbook.Group;
028: import com.sun.addressbook.ABStore;
029: import com.sun.addressbook.AddressBook;
030: import com.sun.addressbook.MissingPropertiesException;
031: import com.sun.addressbook.OperationNotSupportedException;
032: import com.sun.addressbook.ABLogger;
033:
034: import netscape.ldap.LDAPConnection;
035: import netscape.ldap.LDAPSearchResults;
036: import netscape.ldap.LDAPException;
037: import netscape.ldap.LDAPEntry;
038: import netscape.ldap.LDAPRebind;
039: import netscape.ldap.LDAPModification;
040: import netscape.ldap.LDAPModificationSet;
041: import netscape.ldap.LDAPAttribute;
042: import netscape.ldap.LDAPAttributeSet;
043: import netscape.ldap.LDAPv2;
044: import netscape.ldap.LDAPRebindAuth;
045: import netscape.ldap.LDAPCompareAttrNames;
046: import java.lang.reflect.Field;
047: import netscape.ldap.util.ConnectionPool;
048:
049: /**
050: * Ldap Adapter Address Book Store implementation: encapsulates the
051: * commands to be carried out on the address book.
052: *
053: * Required properties are:
054: * ab.host - Ldap server host name.
055: * ab.port - Ldap server port name.
056: * ab.ldap.authId - Authentication dn for the administrator of Address book.
057: * ab.ldap.authPw - Password of the admin of the address book.
058: * ab.ldap.dirSearchBase - Searchbase of the iMS directory. e.g. o=iplanet.com .
059: * ab.ldap.pabSearchBase - SearchBase of the address book tree. e.g. o=pab .
060: * ab.userName - User id of the address book user.
061: *
062: * Optional properties
063: * ab.ldap.lang - locale of the user. Defaults to LdapABConstants.LANG.
064: * ab.ldap.connPoolMin - Initial number of connections in the ldap
065: * connection pool. This defaults to
066: * LdapABConstants.CONNPOOL_MIN.
067: * ab.ldap.connPoolMax - Maximum size of the connection pool. Above this
068: * value, new requests block till a connection is
069: * freed up. Defaults to LdapABConstants.CONNPOOL_MAX.
070: * ab.ldap.timeout - Specifies the maximum number of milliseconds to
071: * wait for the reults before timing out. Defaults to
072: * LdapABConstants.CONN_TIMEOUT.
073: *
074: * iMS Ldap has stores only a single set of address fields. It is assumed that
075: * the address maps to home address. If it has to map to business address, the
076: * business address will have to be stored into the home address fields. The attributes
077: * stored in the iMS address book are: ln, cn, fn, description, homeStreet, homeCity,
078: * homeState, homeZip, homeCountry, bp, fp, hp, mp, pp, dob, uri, memberofpab,
079: * memberofpabgroup, em.
080: */
081: public class LdapABStore extends ABStore {
082:
083: private static Hashtable connPoolTable = new Hashtable();
084:
085: private static long lastPabTimeStamp = 0L;
086: private String ldapServer = null;
087: private int ldapPort = -1;
088: private String ldapPortStr = null;
089: private String authId = null;
090: private String authPw = null;
091: private String dirSearchBase = null;
092: private String fullPabSearchBase = null;
093: private String pabSearchBase = null;
094: private String user = null;
095: private String domain = null;
096: private int min = LdapABConstants.CONNPOOL_MIN;
097: private int max = LdapABConstants.CONNPOOL_MAX;
098: private int ldapTimeout = LdapABConstants.CONN_TIMEOUT;
099: private String pabLang = LdapABConstants.LANG;
100:
101: // Create a Logger for this class
102: private static Logger debugLogger = ABLogger
103: .getLogger("com.sun.portal.addressbook.ldap");
104:
105: // Accessor methods for variables needed in LdapAddressBook
106: protected String getFullPabSearchBase() {
107: return fullPabSearchBase;
108: }
109:
110: protected String getPabLang() {
111: return pabLang;
112: }
113:
114: /**
115: * Initializes and verifies the properties passed, required by the ldap
116: * store. Also establishes a connection pool if one hasnt been instantiated
117: * earlier. For the list of properties refer to the properties listed in the
118: * class description.
119: *
120: */
121: public void init(ABSession session)
122: throws MissingPropertiesException, ABStoreException {
123: this .session = session;
124: ldapServer = session.getProperty("ab.host");
125: if (ldapServer == null) {
126: throw new MissingPropertiesException(
127: "Failed to setup the LdapABStore: Property ab.host missing");
128: }
129: ldapPortStr = session.getProperty("ab.port");
130: if (ldapPortStr == null) {
131: throw new MissingPropertiesException(
132: "Failed to setup the LdapABStore: Property ab.port missing");
133: }
134: try {
135: ldapPort = Integer.parseInt(ldapPortStr);
136: } catch (Exception e) {
137: throw new MissingPropertiesException(
138: "Failed to setup the LdapABStore: Property ab.port should be an integer");
139: }
140: authId = session.getProperty("ab.ldap.authId");
141: if (authId == null) {
142: throw new MissingPropertiesException(
143: "Failed to setup the LdapABStore: Property ab.ldap.authId missing");
144: }
145: authPw = session.getProperty("ab.ldap.authPw");
146: if (authPw == null) {
147: throw new MissingPropertiesException(
148: "Failed to setup the LdapABStore: Property ab.ldap.authPw missing");
149: }
150: dirSearchBase = session.getProperty("ab.ldap.dirSearchBase");
151: if (dirSearchBase == null) {
152: throw new MissingPropertiesException(
153: "Failed to setup the LdapABStore: Property ab.ldap.dirSearchBase missing");
154: }
155: pabSearchBase = session.getProperty("ab.ldap.pabSearchBase");
156: if (pabSearchBase == null) {
157: throw new MissingPropertiesException(
158: "Failed to setup the LdapABStore: Property ab.ldap.pabSearchBase missing");
159: }
160: user = session.getProperty("ab.userName");
161: if (user == null) {
162: throw new MissingPropertiesException(
163: "Failed to setup the LdapABStore: Property ab.userName missing");
164: }
165:
166: // Optional Properties
167:
168: pabLang = session.getProperty("ab.ldap.lang");
169: if (pabLang == null) {
170: debugLogger
171: .log(Level.FINE, "PSJA_CSAL0006", "ab.ldap.lang");
172: pabLang = LdapABConstants.LANG;
173: }
174:
175: domain = session.getProperty("ab.domain");
176: if (domain == null) {
177: debugLogger.log(Level.FINE, "PSJA_CSAL0007", "ab.domain");
178: domain = "";
179: }
180:
181: try {
182: min = Integer.parseInt(session
183: .getProperty("ab.ldap.connPoolMin"));
184: } catch (Exception e) {
185: debugLogger.log(Level.FINE, "PSJA_CSAL0006",
186: "ab.ldap.connPoolMin");
187: min = LdapABConstants.CONNPOOL_MIN;
188: }
189: try {
190: max = Integer.parseInt(session
191: .getProperty("ab.ldap.connPoolMax"));
192:
193: } catch (Exception e) {
194: debugLogger.log(Level.FINE, "PSJA_CSAL0006",
195: "ab.ldap.connPoolMax");
196: max = LdapABConstants.CONNPOOL_MAX;
197:
198: }
199: try {
200: ldapTimeout = Integer.parseInt(session
201: .getProperty("ab.ldap.timeout"));
202: } catch (Exception e) {
203: debugLogger.log(Level.FINE, "PSJA_CSAL0006",
204: "ab.ldap.timeout");
205: ldapTimeout = LdapABConstants.CONN_TIMEOUT;
206: }
207:
208: }
209:
210: /**
211: *
212: * Connect to the address book server and create a connection pool for the
213: * server if not already present.
214: *
215: * As the iMS Address Book needs admin authentication instead of user
216: * auth, the connect doesnt need to authenticate the credentials
217: * of the user.
218: *
219: * @exception ABStoreException if unable to connect to back end service.
220: */
221: public void connect() throws ABStoreException {
222:
223: LDAPConnection ld = null;
224:
225: // A connection pool exists per backend server. If connection pool hasnt
226: // already been established, then create one
227: if (connPoolTable.get(ldapServer) == null) {
228: ConnectionPool cp = null;
229: try {
230: ld = makeConnection(ldapServer, ldapPort, authId,
231: authPw, ldapTimeout);
232: cp = new ConnectionPool(min, max, ld);
233: connPoolTable.put(ldapServer, cp);
234: } catch (LDAPException ldapE) {
235: debugLogger.info("PSJA_CSAL0008");
236: throw new ABStoreException(ldapE.getMessage());
237: }
238:
239: } // if connPool == null
240: }
241:
242: /**
243: * Close the connection pool to the address book store and remove it from
244: * the connection pool table.
245: *
246: * @exception ABStoreException if unable to connect to back end service.
247: */
248: public void closePool() throws ABStoreException {
249: ConnectionPool cp = (ConnectionPool) connPoolTable
250: .get(ldapServer);
251: cp.destroy();
252: connPoolTable.remove(ldapServer);
253: }
254:
255: /**
256: * No connection specific stuff happens in ldap adapter, so no need
257: * to do anything here
258: *
259: * @exception ABStoreException if unable to connect to back end service.
260: */
261: public void disconnect() throws ABStoreException {
262: }
263:
264: /**
265: * Checks if we are able to get a valid non-null connection from the
266: * connection pool table.
267: *
268: * @return boolean indicating whether the address book is connected.
269: * @exception ABStoreException if unable to connect to back end service.
270: */
271: public boolean isConnected() throws ABStoreException {
272: LDAPConnection ld = LDAPConnect();
273: if (ld != null) {
274: LDAPClose(ld);
275: return true;
276: } else {
277: return false;
278: }
279: }
280:
281: /*
282: * First the main dirSearchBase e.g. o=iplanet.com is searched for the
283: * user's paburi attribute. If paburi is found the dirSearchBase is changed
284: * to 'ou=user' + searchBase from paburi.
285: * If the paburi field is not found, then it is assumed that address book
286: * doesnt exist and one is created for the user calling createAB.
287: */
288: private String getPabSearchBase() throws ABStoreException{
289: // Get a connection to the Database from the connection pool
290: LDAPConnection ld = LDAPConnect();
291: if(ld == null){
292: String msg = "LdapABStore.getPabSearchBase():failed to get ldap" +
293: "connection from pool";
294: debugLogger.info("PSJA_CSAL0009");
295: throw new ABStoreException(msg);
296: }
297:
298: String searchFilter = "";
299: debugLogger.log(Level.FINER, "PSJA_CSAL0010", domain);
300: if (domain.equals(""))
301: searchFilter = "uid=" + user;
302: else {
303: searchFilter = "(&(uid=" + user + ")(pabURI=*" + domain + "*))";
304: }
305:
306: LDAPSearchResults paburiSearchResults = null;
307: String searchAttrPaburi[] = { "paburi" };
308: String newSearchBase = null;
309: //
310: // Search the database
311: //
312: /*
313: if (ABDebug.messageEnabled()){
314: StringBuffer searchAttribs = new StringBuffer();
315: for (int i=0; i<searchAttrPaburi.length; i++){
316: searchAttribs.append("\"" + searchAttrPaburi[i] + "\" ");
317: }
318: }
319: */
320:
321: try {
322: paburiSearchResults = ld.search(dirSearchBase,
323: ld.SCOPE_SUB,
324: searchFilter,searchAttrPaburi,
325: false);
326:
327: }
328: catch(LDAPException ldapE) {
329: debugLogger.log(Level.FINE, "PSJA_CSAL0011", user);
330: }
331:
332: if(paburiSearchResults != null) {
333: if (paburiSearchResults.getCount() == 1) {
334: debugLogger.finer("PSJA_CSAL0055");
335:
336: try{
337: LDAPEntry tmp = null;
338: if (paburiSearchResults.hasMoreElements()){
339: tmp = paburiSearchResults.next();
340: Enumeration enum = tmp.getAttribute("paburi").getStringValues();
341: String pabUri = (String)enum.nextElement();
342: debugLogger.log(Level.FINER, "PSJA_CSAL0012", new String[] { tmp.getDN(), pabUri });
343: int idx = pabUri.indexOf("/ou=");
344: newSearchBase = pabUri.substring(idx+1);
345: } else {
346: debugLogger.log(Level.FINER, "PSJA_CSAL0013", user);
347: }
348: } catch(Exception e) {
349: //e.printStackTrace();
350: debugLogger.log(Level.INFO, "PSJA_CSAL0013", user);
351: newSearchBase = null;
352: }
353: } else {
354: debugLogger.finer("PSJA_CSAL0014");
355:
356: try {
357: while (paburiSearchResults.hasMoreElements()) {
358: LDAPEntry tmp = paburiSearchResults.next();
359: Enumeration enum = tmp.getAttribute("paburi").getStringValues();
360:
361: String pabUri = (String)enum.nextElement();
362:
363: int idx = pabUri.indexOf("/ou=");
364: String tmpnewSearchBase = pabUri.substring(idx+1);
365: if ( (tmpnewSearchBase.indexOf(domain)) != -1) {
366: newSearchBase=tmpnewSearchBase;
367: debugLogger.log(Level.FINER, "PSJA_CSAL0053", newSearchBase);
368: break;
369: }
370:
371: debugLogger.log(Level.FINER, "PSJA_CSAL0054", tmpnewSearchBase);
372: }
373: } catch(Exception e) {
374: e.printStackTrace();
375: debugLogger.log(Level.INFO, "PSJA_CSAL0013", user);
376: newSearchBase = null;
377: }
378: }
379: } // end outer if
380: LDAPClose(ld);
381: return newSearchBase;
382: }
383:
384: /**
385: * Get the list of address books id's of the user.
386: *
387: * @return array of user's address book ids
388: */
389: public String[] getAddressBooks() throws ABStoreException,
390: OperationNotSupportedException {
391: LDAPSearchResults abIdSearchResults = null;
392: LDAPConnection ld = LDAPConnect();
393: String searchFilter = null;
394: ArrayList abIDs = new ArrayList();
395: String newSearchBase = getPabSearchBase();
396: if (newSearchBase != null) {
397: fullPabSearchBase = newSearchBase;
398: debugLogger.log(Level.FINER, "PSJA_CSAL0015",
399: fullPabSearchBase);
400:
401: searchFilter = LdapABConstants.ATTR_objectclass + "=pab";
402: String searchAttr[] = { "un" };
403:
404: // Search the database
405: try {
406: abIdSearchResults = ld.search(fullPabSearchBase,
407: ld.SCOPE_SUB, searchFilter, searchAttr, false);
408:
409: } catch (LDAPException ldapE) {
410: debugLogger.log(Level.INFO, "PSJA_CSAL0016", user);
411: abIdSearchResults = null;
412: }
413:
414: if (abIdSearchResults != null) {
415: try {
416:
417: while (abIdSearchResults.hasMoreElements()) {
418: LDAPEntry tmp = abIdSearchResults.next();
419: Enumeration enumeration = tmp
420: .getAttribute("un").getStringValues();
421: abIDs.add((String) enumeration.nextElement());
422: }
423:
424: } catch (Exception e) {
425: String msg = "LdapABStore.getAddressBooks(): ERROR: Cannot "
426: + "find user address book at the location specified in paburi."
427: + e;
428: debugLogger.log(Level.INFO, "PSJA_CSAL0017", e);
429: throw new ABStoreException(msg);
430: }
431:
432: } // end if abIdSearchResults != null
433: } else {
434: // create an address book and return the address book id
435: abIDs.add(createAB());
436: }
437: LDAPClose(ld);
438: return (String[]) abIDs.toArray(new String[abIDs.size()]);
439: }
440:
441: /**
442: * Method to get the user's default address book id. This returns the
443: * first address book id encountered in the search.
444: *
445: * @return The address book id corresponding to the authenticated user.
446: */
447: protected String getDefaultAbID() throws ABStoreException {
448: try {
449: return getAddressBooks()[0];
450: } catch (Exception e) {
451: throw new ABStoreException(e.getMessage());
452: }
453: }
454:
455: /**
456: * Method to retrieve a address book from the backend service.
457: *
458: * @param abID A specific address book ID
459: * @return The specified address book
460: *
461: * @exception ABStoreException if unable to load the specified calendar
462: */
463: public AddressBook openAddressBook(String abID)
464: throws ABStoreException {
465: debugLogger.log(Level.FINER, "PSJA_CSAL0018", abID);
466: return new LdapAddressBook(this , abID);
467: }
468:
469: /**
470: * Method to close a currently opened address book. In this case,
471: * there is nothing to do to close the address book.
472: *
473: * @param ab A specific address book.
474: *
475: * @exception ABStoreException if unable to close the specified calendar
476: */
477: public void closeAddressBook(AddressBook ab)
478: throws ABStoreException {
479: ab = null;
480: }
481:
482: /**
483: * Create an address book if one doesnt exist beforehand.
484: * Create this user's paburi, ou and pab entries.
485: * @return addressBookId - the id of the address book that got created.
486: * @exception ABStoreException if unable to connect to back end service.
487: */
488: public String createAB() throws ABStoreException {
489:
490: String abID = null;
491: // Get connection to the Database
492:
493: LDAPConnection ld = LDAPConnect();
494:
495: LDAPSearchResults userDNSearchResults = null;
496: String userDN = null;
497: String searchAttrDN[] = { "dn" };
498: String searchFilter = "uid=" + user;
499:
500: // Search the database .. assuming since we have come here, dirSearchBase
501: // has not been altered from the actual directory o = iplanet.com
502: try {
503: userDNSearchResults = ld.search(dirSearchBase,
504: ld.SCOPE_SUB, searchFilter, searchAttrDN, false);
505:
506: } catch (LDAPException ldapE) {
507: debugLogger.log(Level.FINE, "PSJA_CSAL0019", new String[] {
508: user, dirSearchBase });
509: throw new ABStoreException(
510: "LdapABStore.createAB: Creation of address book failed: User doesnt exist in the directory");
511: }
512:
513: String searchBaseFromUserDN = null;
514: debugLogger.log(Level.FINER, "PSJA_CSAL0020", Integer
515: .toString(userDNSearchResults.getCount()));
516: if (userDNSearchResults != null) {
517: try {
518: LDAPEntry tmp = userDNSearchResults.next();
519: debugLogger.log(Level.FINER, "PSJA_CSAL0021", tmp);
520: //Enumeration enum = tmp.getAttribute("dn").getStringValues();
521: //userDN = (String)enum.nextElement();
522: userDN = tmp.getDN();
523: int idx = userDN.indexOf("ou=");
524: searchBaseFromUserDN = userDN.substring(idx);
525: } catch (Exception e) {
526: //e.printStackTrace();
527: debugLogger.log(Level.INFO, "PSJA_CSAL0022", user);
528: String msg = "LdapABStore.createAB(): Cannot locate user = "
529: + user + " in directory";
530: throw new ABStoreException(msg);
531: }
532: }
533: if (searchBaseFromUserDN == null) {
534: throw new ABStoreException(
535: "LdapABStore.createAB(): Error in user's " + user
536: + " entry in directory = ");
537: }
538:
539: String searchBase = searchBaseFromUserDN + ", " + pabSearchBase;
540: fullPabSearchBase = "ou=" + user + "," + searchBase;
541:
542: debugLogger
543: .log(Level.FINER, "PSJA_CSAL0023", fullPabSearchBase);
544: if (ld == null) {
545: debugLogger.fine("PSJA_CSAL0024");
546: return null;
547: }
548: String dn = null;
549: try {
550: String objClass[] = { "top", "organizationalunit" };
551:
552: LDAPAttributeSet attrs = new LDAPAttributeSet();
553:
554: attrs.add(new LDAPAttribute(
555: LdapABConstants.ATTR_objectclass, objClass));
556: attrs.add(new LDAPAttribute("ou", user));
557: // dn = "ou=" + user + "," + fullPabSearchBase;
558: dn = fullPabSearchBase;
559: LDAPEntry pabEntry = new LDAPEntry(dn, attrs);
560:
561: ld.add(pabEntry);
562: } catch (Exception e) {
563: if (debugLogger.isLoggable(Level.FINE)) {
564: LogRecord logRecord = new LogRecord(Level.FINE,
565: "PSJA_CSAL0025");
566: logRecord.setParameters(new String[] { dn });
567: logRecord.setThrown(e);
568: logRecord.setLoggerName(debugLogger.getName());
569: debugLogger.log(logRecord);
570: }
571: }
572:
573: try {
574: String objClass[] = { "top", "pab" };
575: LDAPAttributeSet attrs = new LDAPAttributeSet();
576: abID = "AddressBook" + pabTimeStamp();
577: attrs.add(new LDAPAttribute(
578: LdapABConstants.ATTR_objectclass, objClass));
579: attrs.add(new LDAPAttribute(LdapABConstants.ATTR_cn,
580: "Address Book"));
581: attrs.add(new LDAPAttribute("un", abID));
582: dn = "un=" + abID + "," + fullPabSearchBase;
583: LDAPEntry pabEntry = new LDAPEntry(dn, attrs);
584:
585: ld.add(pabEntry);
586: } catch (Exception e) {
587: if (debugLogger.isLoggable(Level.FINE)) {
588: LogRecord logRecord = new LogRecord(Level.FINE,
589: "PSJA_CSAL0025");
590: logRecord.setParameters(new String[] { dn });
591: logRecord.setThrown(e);
592: logRecord.setLoggerName(debugLogger.getName());
593: debugLogger.log(logRecord);
594: }
595: abID = null;
596: }
597:
598: // Add paburi field to the user's ldap entry
599: try {
600: dn = "uid=" + user + ", " + searchBaseFromUserDN;
601: String pabURL = "ldap://" + ldapServer + ":" + ldapPortStr;
602:
603: String newpabUri = pabURL + "/" + fullPabSearchBase;
604: LDAPModificationSet mods = new LDAPModificationSet();
605:
606: mods.add(LDAPModification.REPLACE, new LDAPAttribute(
607: "paburi", newpabUri));
608:
609: ld.modify(dn, mods);
610: } catch (Exception e) {
611: debugLogger.log(Level.FINE, "PSJA_CSAL0027", user);
612: abID = null;
613: }
614:
615: LDAPClose(ld);
616: return abID;
617: }
618:
619: /**
620: * Method returning an inner class implementing LDAPRebind interface
621: * to handle authentication of LDAP referrals.
622: *
623: * @param authId The DN of the AB admin on the LDAP server.
624: * @param authPw The password of the AB admin on the LDAP server.
625: *
626: * @return an instance of LDAPRebind with given credentials.
627: */
628:
629: private LDAPRebind getRebind(final String authId,
630: final String authPw) {
631: return new LDAPRebind() {
632: // Anonymous inner class implementing LDAPRebind
633:
634: private String authDN = "";
635: private String authPwd = "";
636: {
637: this .authDN = authId;
638: this .authPwd = authPw;
639: }
640:
641: public LDAPRebindAuth getRebindAuthentication(String host,
642: int port) {
643: return new LDAPRebindAuth(authDN, authPwd);
644: }
645: }; // End inner class
646: }
647:
648: /**
649: * Connect to the LDAP database and authenticate the connection.
650: *
651: * @param host The LDAP host to connect .
652: * @param port The port of the LDAP host to connect .
653: * @param authId The DN of the AB admin on the given LDAP server.
654: * @param authPw The password of the AB admin on the given LDAP server.
655: * @param timeout The timeout to be set for the ldap connection.
656: * @return ld Authenticated LDAPConnection.
657: */
658: private LDAPConnection makeConnection(String host, int port,
659: String authId, String authPw, int timeout)
660: throws LDAPException {
661:
662: LDAPConnection ld = new LDAPConnection();
663:
664: if (debugLogger.isLoggable(Level.FINER)) {
665: StringBuffer authHiddenPw = new StringBuffer();
666: for (int i = 0; i < authPw.length(); i++) {
667: authHiddenPw.append("*");
668: }
669: debugLogger.log(Level.FINER, "PSJA_CSAL0028",
670: new String[] { host, Integer.toString(port),
671: authId, authHiddenPw.toString(),
672: Integer.toString(timeout) });
673: }
674: try {
675: ld.setOption(LDAPv2.TIMELIMIT, new Integer(timeout));
676: ld.connect(host, port, authId, authPw);
677:
678: // Support for referrals in LDAP database
679:
680: // Set the referral credentials to be the same as the standard
681: // LDAP server credentials
682: LDAPRebind x_rebind = getRebind(authId, authPw);
683: ld.setOption(ld.REFERRALS, new Boolean(true));
684: ld.setOption(ld.REFERRALS_REBIND_PROC, x_rebind);
685:
686: debugLogger.finer("PSJA_CSAL0029");
687: } catch (Exception e) {
688: String msg = "LdapABStore.makeConnection(): Error "
689: + "while creating connection: Invalid ldap host/port or admin credentials";
690: debugLogger.info("PSJA_CSAL0030");
691: throw new LDAPException(msg);
692: }
693: return ld;
694: }
695:
696: /**
697: * Get a LDAP connection to LDAP Database.
698: *
699: * @return LDAPConnection object obtained from the connection pool.
700: */
701: LDAPConnection LDAPConnect() {
702: ConnectionPool cp = (ConnectionPool) connPoolTable
703: .get(ldapServer);
704: if (cp == null) {
705: return null;
706: }
707: LDAPConnection ld = cp.getConnection();
708: return ld;
709: }
710:
711: /**
712: * Close LDAP Connection.
713: *
714: * @param LDAPConnection object to return to the connection pool.
715: */
716: void LDAPClose(LDAPConnection ld) {
717: // mark the connection in the pool as free
718: ConnectionPool cp = (ConnectionPool) connPoolTable
719: .get(ldapServer);
720: if (cp != null) {
721: cp.close(ld);
722: }
723: return;
724: }
725:
726: /*
727: * pabTimeStamp emulates the behaviour of WebMail in generating the unique id.
728: *
729: * @return timeStamp String - returns the current time to
730: * achieve uniqueness while adding entries.
731: */
732:
733: private synchronized String pabTimeStamp() {
734: long current = System.currentTimeMillis() / 1000 - 915170400;
735: if (current > lastPabTimeStamp) {
736: lastPabTimeStamp = current;
737: } else {
738: lastPabTimeStamp++;
739: }
740: return Long.toString(lastPabTimeStamp);
741: }
742:
743: }
|