KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > activedirectory > ActiveDirectoryUserDatabaseConfiguration


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.activedirectory;
21
22 import java.net.URI JavaDoc;
23 import java.net.URISyntaxException JavaDoc;
24 import java.security.PrivilegedAction JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Collections JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Properties JavaDoc;
34 import java.util.StringTokenizer JavaDoc;
35
36 import javax.naming.Context JavaDoc;
37 import javax.naming.NamingException JavaDoc;
38 import javax.naming.ldap.InitialLdapContext JavaDoc;
39 import javax.security.auth.Subject JavaDoc;
40 import javax.security.auth.login.LoginContext JavaDoc;
41 import javax.security.auth.login.LoginException JavaDoc;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45
46 import com.sslexplorer.boot.PropertyList;
47 import com.sslexplorer.properties.Property;
48 import com.sslexplorer.properties.impl.realms.RealmKey;
49 import com.sslexplorer.realms.Realm;
50 import com.sslexplorer.security.UserDatabaseException;
51
52 public final class ActiveDirectoryUserDatabaseConfiguration {
53     private static final Log logger = LogFactory.getLog(ActiveDirectoryUserDatabaseConfiguration.class);
54     private static final String JavaDoc COMMON_NAME = "CN=";
55     private static final String JavaDoc CN_USERS = COMMON_NAME + "Users";
56     private static final String JavaDoc CN_BUILTIN = COMMON_NAME + "Builtin";
57     private static final String JavaDoc LDAP_PROTOCOL = "ldap://";
58     private static final String JavaDoc PORT_SEPARATOR = ":";
59     private static final String JavaDoc ESCAPE_BACKSLASH = "\\\\";
60     private static final String JavaDoc ESCAPE_QUOTE = "\"";
61     private static final String JavaDoc[] ESCAPED_CHARACTERS = {ESCAPE_BACKSLASH, "/", "#", ",,", "\\+", ESCAPE_QUOTE, "<", ">", ";"};
62     private static final int SSL_SECURED_PORT = 636;
63     private static final int CLEAR_TEXT_PORT = 389;
64     
65     /** The Kerberos GSSAPI authentication type. */
66     public static final String JavaDoc GSSAPI_AUTHENTICATION_METHOD = "GSSAPI";
67     /** The JNDI simple bind authentication type. */
68     public static final String JavaDoc SIMPLE_AUTHENTICATION_METHOD = "simple";
69     
70     /** The plain text protocol. */
71     public static final String JavaDoc PLAIN_PROTOCOL = "plain";
72     /** The SSL protocol. */
73     public static final String JavaDoc SSL_PROTOCOL = "ssl";
74
75     private final Realm realm;
76     private final ActiveDirectoryPropertyManager propertyManager;
77     private String JavaDoc domain;
78     private String JavaDoc controllerHost;
79     private Collection JavaDoc<String JavaDoc> backupControllerHosts;
80     private String JavaDoc serviceAuthenticationType;
81     private String JavaDoc userAuthenticationType;
82     private String JavaDoc serviceAccountName;
83     private String JavaDoc serviceAccountPassword;
84     private String JavaDoc baseDn;
85     private String JavaDoc protocolType;
86     private boolean followReferrals;
87     private int userCacheSize;
88     private int groupCacheSize;
89     private boolean inMemoryCache;
90     private int timeToLive;
91     private final List JavaDoc<String JavaDoc> includedOuBasesList = new ArrayList JavaDoc<String JavaDoc>();
92     private final List JavaDoc<String JavaDoc> excludedOuBasesList = new ArrayList JavaDoc<String JavaDoc>();
93     private boolean hasFilteredOus;
94     private boolean usernamesAreCaseSensitive;
95     private final Collection JavaDoc<URI JavaDoc> activeDirectoryUrls = new ArrayList JavaDoc<URI JavaDoc>();
96     private URI JavaDoc lastContactedActiveDirectoryUrl;
97     private int pageSize;
98     private int timeOut;
99     private PagedResultTemplate template;
100
101     public ActiveDirectoryUserDatabaseConfiguration(Realm realm, Properties JavaDoc propertyNames) throws IllegalArgumentException JavaDoc, Exception JavaDoc {
102         this.realm = realm;
103         propertyManager = new ActiveDirectoryPropertyManager(realm);
104         initialize(propertyNames);
105     }
106
107     private void initialize(Properties JavaDoc propertyNames) throws Exception JavaDoc {
108         // Get the domain and active directory root
109
setControllerHost(getProperty("activeDirectory.controllerHost", propertyNames));
110         setBackupControllerHosts(getPropertyList("activeDirectory.backupControllerHosts", propertyNames));
111         setDomain(getProperty("activeDirectory.domain", propertyNames));
112         setUserAuthenticationType(getProperty("activeDirectory.userAuthenticationType", propertyNames));
113         setServiceAccountName(getProperty("activeDirectory.serviceAccountUsername", propertyNames));
114         setServiceAccountPassword(getProperty("activeDirectory.serviceAccountPassword", propertyNames));
115         
116         setFollowReferrals(Boolean.valueOf(System.getProperty("sslexplorer.followADReferrals", "false")));
117         setUserCacheSize(getPropertyInt("activeDirectory.cacheUserMaxObjects", propertyNames));
118         setGroupCacheSize(getPropertyInt("activeDirectory.cacheGroupMaxObjects", propertyNames));
119         setInMemoryCache(getPropertyBoolean("activeDirectory.cacheInMemory", propertyNames));
120         setTimeToLive(getPropertyInt("activeDirectory.userCacheTTL", propertyNames));
121
122         Collection JavaDoc<String JavaDoc> includedOuFilterList = getPropertyList("activeDirectory.organizationalUnitFilter", propertyNames);
123         Collection JavaDoc<String JavaDoc> excludedOuFilterList = getPropertyList("activeDirectory.excludedOrganizationalUnitFilter", propertyNames);
124         setValidOus(baseDn, includedOuFilterList, excludedOuFilterList);
125         setIncludeStandardUsers(getPropertyBoolean("activeDirectory.includeStandardUsers", propertyNames));
126         setIncludeBuiltInGroups(getPropertyBoolean("activeDirectory.includeBuiltInGroups", propertyNames));
127
128         setUsernamesAreCaseSensitive(getPropertyBoolean("activeDirectory.usernamesAreCaseSensitive", propertyNames));
129         setPageSize(getPropertyInt("activeDirectory.pageSize", propertyNames));
130         setTimeOut(getPropertyInt("activeDirectory.connection.timeout", propertyNames));
131     }
132
133     private String JavaDoc getProperty(String JavaDoc key, Properties JavaDoc propertyNames) {
134         return Property.getProperty(getRealmKey(key, propertyNames));
135     }
136
137     private boolean getPropertyBoolean(String JavaDoc key, Properties JavaDoc propertyNames) {
138         return Property.getPropertyBoolean(getRealmKey(key, propertyNames));
139     }
140     
141     private int getPropertyInt(String JavaDoc key, Properties JavaDoc propertyNames) {
142         return Property.getPropertyInt(getRealmKey(key, propertyNames));
143     }
144     
145     private Collection JavaDoc<String JavaDoc> getPropertyList(String JavaDoc key, Properties JavaDoc propertyNames) {
146         return Property.getPropertyList(getRealmKey(key, propertyNames));
147     }
148     
149     private RealmKey getRealmKey(String JavaDoc key, Properties JavaDoc propertyNames) {
150         String JavaDoc propertyOrDefault = propertyNames.getProperty(key, key);
151         return new RealmKey(propertyOrDefault, realm);
152     }
153     
154     void postInitialize() throws URISyntaxException JavaDoc {
155         setActiveDirectoryUrls();
156         if(!isServiceAuthenticationGssApi() && !serviceAccountName.toLowerCase().endsWith(baseDn)) {
157             serviceAccountName = appendBaseDn(formatUsername(serviceAccountName));
158         }
159         includedOuBasesList.removeAll(excludedOuBasesList); // just to make sure
160

161         Collection JavaDoc<String JavaDoc> escapedIncludedOuBasesList = getEscapedDns(includedOuBasesList, false);
162         Collection JavaDoc<String JavaDoc> escapedExcludedOuBasesList = getEscapedDns(excludedOuBasesList, false);
163         Collection JavaDoc<String JavaDoc> escapedOuSearchBase = getEscapedDns(includedOuBasesList, true);
164         template = new PagedResultTemplate(escapedIncludedOuBasesList, escapedExcludedOuBasesList, escapedOuSearchBase, pageSize);
165         refresh();
166     }
167
168     private static Collection JavaDoc<String JavaDoc> getEscapedDns(Collection JavaDoc<String JavaDoc> toEscapeDns, boolean requiresSecondEscape) {
169         Collection JavaDoc<String JavaDoc> escapedDns = new HashSet JavaDoc<String JavaDoc>(toEscapeDns.size());
170         for (String JavaDoc toEscapeDn : toEscapeDns) {
171             String JavaDoc escapedDn = getEscapedDn(toEscapeDn, requiresSecondEscape);
172             escapedDns.add(escapedDn);
173         }
174         return Collections.unmodifiableCollection(escapedDns);
175     }
176        
177     static String JavaDoc getEscapedDn(String JavaDoc toEscape, boolean requiresSecondEscape) {
178         for (int index = 0; index < ESCAPED_CHARACTERS.length; index++) {
179             String JavaDoc character = ESCAPED_CHARACTERS[index];
180             if (requiresSecondEscape) {
181                 if(character.equals(ESCAPE_BACKSLASH)) {
182                     toEscape = toEscape.replaceAll(character, ESCAPE_BACKSLASH + ESCAPE_BACKSLASH + ESCAPE_BACKSLASH + ESCAPE_BACKSLASH);
183                 } else if(character.equals(ESCAPE_QUOTE)) {
184                     toEscape = toEscape.replaceAll(character, ESCAPE_BACKSLASH + ESCAPE_BACKSLASH + ESCAPE_QUOTE);
185                 } else {
186                     toEscape = toEscape.replaceAll(character, ESCAPE_BACKSLASH + character);
187                 }
188             } else {
189                 toEscape = toEscape.replaceAll(character, ESCAPE_BACKSLASH + character);
190             }
191         }
192         return toEscape;
193     }
194     
195     private static String JavaDoc formatUsername(String JavaDoc username) {
196         return username.toUpperCase().startsWith(COMMON_NAME) ? username : COMMON_NAME + username;
197     }
198     
199     public String JavaDoc appendBaseDn(String JavaDoc commonName) {
200         if (commonName.toLowerCase().endsWith(baseDn.toLowerCase())) {
201             return commonName;
202         } else {
203             return commonName.endsWith(",") ? commonName : commonName + "," + baseDn;
204         }
205     }
206     
207     void refresh() {
208         propertyManager.refresh();
209     }
210
211     public String JavaDoc getDomain() {
212         return domain;
213     }
214     
215     private void setDomain(String JavaDoc domain) throws Exception JavaDoc {
216         this.domain = domain.toUpperCase().trim();
217         if (this.domain.equals("")) {
218             throw new IllegalArgumentException JavaDoc("No active directory domain configured.");
219         }
220         setBaseDn(splitDomain(domain));
221     }
222
223     private void setControllerHost(String JavaDoc controllerHost) {
224         if (controllerHost.equals("")) {
225             throw new IllegalArgumentException JavaDoc("No active directory controller host configured.");
226         }
227         this.controllerHost = controllerHost;
228     }
229
230     private Collection JavaDoc<String JavaDoc> getBackupControllerHosts() {
231         return backupControllerHosts;
232     }
233     
234     private void setBackupControllerHosts(Collection JavaDoc<String JavaDoc> backupControllerHosts) {
235         this.backupControllerHosts = backupControllerHosts;
236     }
237
238     String JavaDoc getServiceAuthenticationType() {
239         return serviceAuthenticationType;
240     }
241
242     public void setServiceAuthenticationType(String JavaDoc serviceAuthenticationType) {
243         this.serviceAuthenticationType = serviceAuthenticationType;
244     }
245
246     boolean isServiceAuthenticationGssApi() {
247         return GSSAPI_AUTHENTICATION_METHOD.equals(getServiceAuthenticationType());
248     }
249
250     boolean isUserAuthenticationGssApi() {
251         return GSSAPI_AUTHENTICATION_METHOD.equals(getUserAuthenticationType());
252     }
253     
254     String JavaDoc getUserAuthenticationType() {
255         return userAuthenticationType;
256     }
257
258     public void setUserAuthenticationType(String JavaDoc userAuthenticationType) {
259         this.userAuthenticationType = userAuthenticationType;
260     }
261
262     String JavaDoc getServiceAccountName() {
263         return serviceAccountName;
264     }
265
266     void setServiceAccountName(String JavaDoc serviceAccountName) {
267         this.serviceAccountName = serviceAccountName == null ? null : serviceAccountName.trim();
268     }
269
270     private String JavaDoc getServiceAccountPassword() {
271         return serviceAccountPassword;
272     }
273
274     void setServiceAccountPassword(String JavaDoc serviceAccountPassword) {
275         this.serviceAccountPassword = serviceAccountPassword;
276     }
277
278     private String JavaDoc getProtocolType() {
279         return protocolType;
280     }
281
282     public boolean isSslProtcolType() {
283         return "ssl".equals(getProtocolType());
284     }
285     
286     public void setProtocolType(String JavaDoc protocolType) {
287         this.protocolType = protocolType;
288     }
289     
290     private boolean isFollowReferrals() {
291         return followReferrals;
292     }
293
294     void setFollowReferrals(boolean followReferrals) {
295         this.followReferrals = followReferrals;
296     }
297
298     public String JavaDoc getBaseDn() {
299         return baseDn;
300     }
301
302     void setBaseDn(String JavaDoc baseDn) {
303         this.baseDn = baseDn == null ? null : baseDn.toLowerCase().trim();
304     }
305
306     void setUserCacheSize(int userCacheSize) {
307         this.userCacheSize = userCacheSize;
308     }
309     
310     void setGroupCacheSize(int groupCacheSize) {
311         this.groupCacheSize = groupCacheSize;
312     }
313
314     void setInMemoryCache(boolean inMemoryCache) {
315         this.inMemoryCache = inMemoryCache;
316     }
317
318     int getTimeToLive() {
319         return timeToLive;
320     }
321
322     void setTimeToLive(int timeToLive) {
323         if (timeToLive < 1) {
324             logger.warn("Cache TTL is less than 1 minute. This would cause serious performance problems. The minimum value of 1 minute will now be used");
325             timeToLive = 1;
326         }
327         this.timeToLive = minutesToMillis(timeToLive);
328     }
329     
330     private static int minutesToMillis(int minutes) {
331         return minutes * 60 * 1000;
332     }
333
334     UserContainer createUserContainer() {
335         return new UserContainer(userCacheSize, inMemoryCache, isUsernamesAreCaseSensitive());
336     }
337
338     GroupContainer createRoleContainer() {
339         return new GroupContainer(groupCacheSize, inMemoryCache);
340     }
341     
342     void setValidOus(String JavaDoc baseDn, Collection JavaDoc<String JavaDoc> includedOuFilterList, Collection JavaDoc<String JavaDoc> excludedOuFilterList) {
343         includedOuBasesList.clear();
344         includedOuBasesList.addAll(getFormattedOuFilterList(baseDn, includedOuFilterList));
345         excludedOuBasesList.clear();
346         excludedOuBasesList.addAll(getFormattedOuFilterList(baseDn, excludedOuFilterList));
347         includedOuBasesList.removeAll(excludedOuBasesList);
348
349         hasFilteredOus = !includedOuBasesList.isEmpty();
350         if (!hasFilteredOus) {
351             includedOuBasesList.add(baseDn);
352         }
353
354         if (logger.isDebugEnabled()) {
355             logger.debug("Included OU Bases:");
356             for (String JavaDoc dn : includedOuBasesList) {
357                 logger.debug(" " + dn);
358             }
359
360             logger.debug("Excluded OU Bases:");
361             for (String JavaDoc dn : excludedOuBasesList) {
362                 logger.debug(" " + dn);
363             }
364         }
365     }
366
367     private static Collection JavaDoc<String JavaDoc> getFormattedOuFilterList(String JavaDoc baseDn, Collection JavaDoc<String JavaDoc> ouFilterList) {
368         Collection JavaDoc<String JavaDoc> formattedOuFilterList = new HashSet JavaDoc<String JavaDoc>();
369         for (String JavaDoc dn : ouFilterList) {
370             if (!dn.trim().toLowerCase().endsWith(baseDn.trim().toLowerCase())) {
371                 dn = dn + "," + baseDn;
372             }
373             formattedOuFilterList.add(dn);
374         }
375         return formattedOuFilterList;
376     }
377
378     private void setIncludeStandardUsers(boolean includeStandardUsers) {
379         if (includeStandardUsers) {
380             if (hasFilteredOus) {
381                 includedOuBasesList.add(0, appendBaseDn(CN_USERS));
382             }
383         } else {
384             excludedOuBasesList.add(0, appendBaseDn(CN_USERS));
385         }
386     }
387
388     private void setIncludeBuiltInGroups(boolean includeBuiltInGroups) {
389         if (includeBuiltInGroups) {
390             if (hasFilteredOus) {
391                 includedOuBasesList.add(0, appendBaseDn(CN_BUILTIN));
392             }
393         } else {
394             excludedOuBasesList.add(0, appendBaseDn(CN_BUILTIN));
395         }
396     }
397
398     boolean isUsernamesAreCaseSensitive() {
399         return usernamesAreCaseSensitive;
400     }
401
402     private void setUsernamesAreCaseSensitive(boolean usernamesAreCaseSensitive) {
403         this.usernamesAreCaseSensitive = usernamesAreCaseSensitive;
404     }
405
406     boolean isDnValid(String JavaDoc dn) {
407         return template.isDnValid(dn);
408     }
409     
410     private void setActiveDirectoryUrls() throws URISyntaxException JavaDoc {
411         activeDirectoryUrls.clear();
412         lastContactedActiveDirectoryUrl = null;
413
414         int controllerPort = getControllerPort();
415         URI JavaDoc primaryUri = controllerHost.contains(PORT_SEPARATOR) ? buildURI(controllerHost) : buildURI(controllerHost, controllerPort);
416         activeDirectoryUrls.add(primaryUri);
417
418         for (String JavaDoc uri : getBackupControllerHosts()) {
419             if (uri.contains(PORT_SEPARATOR)) {
420                 activeDirectoryUrls.add(buildURI(uri));
421             } else {
422                 activeDirectoryUrls.add(buildURI(uri, controllerPort));
423             }
424         }
425
426         setLastContactedActiveDirectoryUrl(primaryUri);
427     }
428     
429     private int getControllerPort() {
430         int indexOf = controllerHost.indexOf(PORT_SEPARATOR);
431         if(indexOf == -1 || indexOf == controllerHost.length() - 1) {
432             if(isServiceAuthenticationGssApi()) {
433                 return CLEAR_TEXT_PORT;
434             }
435             return isSslProtcolType() ? SSL_SECURED_PORT : CLEAR_TEXT_PORT;
436         } else {
437             String JavaDoc port = controllerHost.substring(indexOf + 1);
438             Integer JavaDoc valueOf = Integer.valueOf(port);
439             return valueOf;
440         }
441     }
442
443     private static URI JavaDoc buildURI(String JavaDoc host, int port) throws URISyntaxException JavaDoc {
444         return buildURI(host + PORT_SEPARATOR + port);
445     }
446
447     private static URI JavaDoc buildURI(String JavaDoc url) throws URISyntaxException JavaDoc {
448         return new URI JavaDoc(LDAP_PROTOCOL + url);
449     }
450
451     String JavaDoc getContactableActiveDirectories() {
452         URI JavaDoc lastContactedUrl = getLastContactedActiveDirectoryUrl();
453         URI JavaDoc firstUrl = activeDirectoryUrls.isEmpty() ? null : activeDirectoryUrls.iterator().next();
454         boolean isDifferent = !lastContactedUrl.equals(firstUrl);
455
456         Collection JavaDoc<URI JavaDoc> hosts = new ArrayList JavaDoc<URI JavaDoc>(activeDirectoryUrls.size() + 1);
457         if (isDifferent) {
458             hosts.add(lastContactedUrl);
459         }
460         hosts.addAll(activeDirectoryUrls);
461         return getHosts(hosts);
462     }
463
464     private static String JavaDoc getHosts(Collection JavaDoc<URI JavaDoc> urls) {
465         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
466         for (Iterator JavaDoc itr = urls.iterator(); itr.hasNext();) {
467             URI JavaDoc url = (URI JavaDoc) itr.next();
468             buffer.append(url.toString());
469             if(itr.hasNext()) {
470                 buffer.append(" ");
471             }
472         }
473         return buffer.toString();
474     }
475     
476     synchronized URI JavaDoc getLastContactedActiveDirectoryUrl() {
477         return lastContactedActiveDirectoryUrl;
478     }
479
480     synchronized void setLastContactedActiveDirectoryUrl(String JavaDoc url) {
481         try {
482             setLastContactedActiveDirectoryUrl(new URI JavaDoc(url));
483         } catch (URISyntaxException JavaDoc e) {
484             // ignore
485
}
486     }
487
488     private synchronized void setLastContactedActiveDirectoryUrl(URI JavaDoc url) {
489         if (lastContactedActiveDirectoryUrl == null || !lastContactedActiveDirectoryUrl.equals(url)) {
490             PropertyList kerbrosControllerSettings = getKerbrosControllerSettings(url);
491             propertyManager.refresh(Collections.singletonMap("activeDirectory.backupControllerHosts", kerbrosControllerSettings.getAsPropertyText()));
492         }
493         lastContactedActiveDirectoryUrl = url;
494     }
495
496     private PropertyList getKerbrosControllerSettings(URI JavaDoc contactedUrl) {
497         PropertyList values = new PropertyList();
498         values.add(getKerbrosController(contactedUrl));
499
500         for (URI JavaDoc url : activeDirectoryUrls) {
501             String JavaDoc kerbrosController = getKerbrosController(url);
502             if (!values.contains(kerbrosController)) {
503                 values.add(kerbrosController);
504             }
505         }
506         return values;
507     }
508
509     private static String JavaDoc getKerbrosController(URI JavaDoc url) {
510         String JavaDoc toParse = url.toString();
511         return toParse.substring(LDAP_PROTOCOL.length(), toParse.lastIndexOf(PORT_SEPARATOR));
512     }
513
514     void search(InitialLdapContext JavaDoc context, String JavaDoc filter, String JavaDoc[] attributes, PagedResultMapper mapper) throws Exception JavaDoc {
515         template.search(context, filter, attributes, mapper);
516     }
517
518     void setPageSize(int pageSize) {
519         this.pageSize = pageSize;
520     }
521     
522     private int getTimeout() {
523         return timeOut;
524     }
525
526     private void setTimeOut(int timeOut) {
527         this.timeOut = timeOut * 1000;
528     }
529     
530     public Object JavaDoc doAs(PrivilegedAction JavaDoc action) throws UserDatabaseException {
531         Object JavaDoc result = null;
532         if (isServiceAuthenticationGssApi()) {
533             try {
534                 LoginContext JavaDoc context = getServiceAccountLoginContext();
535                 result = Subject.doAs(context.getSubject(), action);
536                 logoutContext(context);
537             } catch (Exception JavaDoc e) {
538                 logger.error("Failure to create Login Context", e);
539                 throw new UserDatabaseException("", e);
540             }
541         } else {
542             result = action.run();
543         }
544         
545         if (result instanceof Throwable JavaDoc) {
546             Throwable JavaDoc e = (Throwable JavaDoc) result;
547             logger.error("Failure to doAs", e);
548             throw new UserDatabaseException("", e);
549         }
550         return result;
551     }
552     
553     private LoginContext JavaDoc getServiceAccountLoginContext() throws Exception JavaDoc {
554         /*
555          * Only attempt to load the service account context if it has not been
556          * loaded, if the username has changed or if the password has changed
557          */

558         try {
559             return createLoginContext(getServiceAccountName(), getServiceAccountPassword());
560         } catch (LoginException JavaDoc e) {
561             Throwable JavaDoc cause = e.getCause();
562             // Check the class by name to allow non Sun Javas to compile
563
if (cause != null && cause.getClass().getName().equals("sun.security.krb5.KrbException")) {
564                 throw new Exception JavaDoc("Failed to logon. Please check your Active Directory configuration.", e);
565             }
566             throw e;
567         }
568     }
569     
570     LoginContext JavaDoc createLoginContext(String JavaDoc username, String JavaDoc password) throws LoginException JavaDoc {
571         if (logger.isDebugEnabled()) {
572             logger.debug("Creating login context for " + username);
573         }
574
575         UserPasswordCallbackHandler callbackHandler = new UserPasswordCallbackHandler();
576         callbackHandler.setUserId(username);
577         callbackHandler.setPassword(password);
578
579         LoginContext JavaDoc context = new LoginContext JavaDoc(ActiveDirectoryUserDatabase.class.getName(), callbackHandler);
580         context.login();
581         return context;
582     }
583
584     static void logoutContext(LoginContext JavaDoc context) {
585         try {
586             if (context != null) {
587                 context.logout();
588             }
589         } catch (LoginException JavaDoc e) {
590             // ignore
591
}
592     }
593
594     InitialLdapContext JavaDoc getAuthenticatedContext(String JavaDoc url, Map JavaDoc<String JavaDoc, String JavaDoc> properties) throws NamingException JavaDoc {
595         Hashtable JavaDoc<String JavaDoc, String JavaDoc> variables = new Hashtable JavaDoc<String JavaDoc, String JavaDoc>(properties);
596         variables.put(Context.SECURITY_AUTHENTICATION, getServiceAuthenticationType());
597         if (!isServiceAuthenticationGssApi()) {
598             variables.put(Context.SECURITY_PRINCIPAL, getServiceAccountName());
599             variables.put(Context.SECURITY_CREDENTIALS, getServiceAccountPassword());
600         }
601         return getInitialContext(url, variables);
602     }
603
604     InitialLdapContext JavaDoc getAuthenticatedContext(String JavaDoc url) throws NamingException JavaDoc {
605         return getAuthenticatedContext(url, Collections.<String JavaDoc, String JavaDoc> emptyMap());
606     }
607
608     public InitialLdapContext JavaDoc getInitialContext(String JavaDoc url, Map JavaDoc<String JavaDoc, String JavaDoc> properties) throws NamingException JavaDoc {
609         Hashtable JavaDoc<String JavaDoc, String JavaDoc> variables = new Hashtable JavaDoc<String JavaDoc, String JavaDoc>(properties);
610         variables.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
611         variables.put(Context.PROVIDER_URL, url); // Must use fully qualified hostname
612

613         if (isSslProtcolType()) {
614             variables.put("java.naming.ldap.factory.socket", "com.sslexplorer.boot.CustomSSLSocketFactory");
615             // Add the custom socket factory
616
}
617
618         if (isFollowReferrals()) {
619             variables.put(Context.REFERRAL, "follow");
620         }
621
622         variables.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(getTimeout()));
623         variables.put("java.naming.ldap.version", "3");
624         variables.put("com.sun.jndi.ldap.connect.pool", "true");
625         variables.put("javax.security.sasl.qop", "auth-conf,auth-int,auth");
626         variables.put(Context.SECURITY_PROTOCOL, getProtocolType());
627
628         InitialLdapContext JavaDoc context = new InitialLdapContext JavaDoc(variables, null);
629         String JavaDoc usedUrl = (String JavaDoc) context.getEnvironment().get(Context.PROVIDER_URL);
630         setLastContactedActiveDirectoryUrl(usedUrl);
631         return context;
632     }
633
634     private static String JavaDoc splitDomain(String JavaDoc domain) {
635         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
636         for (StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(domain, "."); tokenizer.hasMoreTokens();) {
637             if (buffer.length() > 0) {
638                 buffer.append(",");
639             }
640             buffer.append("DC=" + tokenizer.nextToken());
641         }
642         return buffer.toString();
643     }
644 }
Popular Tags