197 *
198 * Non-configurable rejections:
199 * - nonstandard socketFactory has been specified: the pool manager
200 * cannot track input or parameters used by the socket factory and
201 * thus has no way of determining whether two connection requests
202 * are equivalent. Maybe in the future it might add a list of allowed
203 * socket factories to be configured
204 * - trace enabled (except when debugging)
205 * - for Digest authentication, if a callback handler has been specified:
206 * the pool manager cannot track input collected by the handler
207 * and thus has no way of determining whether two connection requests are
208 * equivalent. Maybe in the future it might add a list of allowed
209 * callback handlers.
210 *
211 * Configurable tests:
212 * - Pooling for the requested protocol (plain or ssl) is supported
213 * - Pooling for the requested authentication mechanism is supported
214 *
215 */
216 static boolean isPoolingAllowed(String socketFactory, OutputStream trace,
217 String authMech, String protocol, Hashtable env)
218 throws NamingException {
219
220 if (trace != null && !debug
221
222 // Requesting plain protocol but it is not supported
223 || (protocol == null && !supportPlainProtocol)
224
225 // Requesting ssl protocol but it is not supported
226 || ("ssl".equalsIgnoreCase(protocol) && !supportSslProtocol)) {
227
228 d("Pooling disallowed due to tracing or unsupported pooling of protocol");
229 return false;
230 }
231 // pooling of custom socket factory is possible only if the
232 // socket factory interface implements java.util.comparator
233 String COMPARATOR = "java.util.Comparator";
234 boolean foundSockCmp = false;
235 if ((socketFactory != null) &&
236 !socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) {
237 try {
238 Class socketFactoryClass = Obj.helper.loadClass(socketFactory);
239 Class[] interfaces = socketFactoryClass.getInterfaces();
240 for (int i = 0; i < interfaces.length; i++) {
241 if (interfaces[i].getCanonicalName().equals(COMPARATOR)) {
242 foundSockCmp = true;
243 }
244 }
245 } catch (Exception e) {
246 CommunicationException ce =
247 new CommunicationException("Loading the socket factory");
248 ce.setRootCause(e);
249 throw ce;
250 }
251 if (!foundSockCmp) {
252 return false;
253 }
254 }
255 // Cannot use pooling if authMech is not a supported mechs
256 // Cannot use pooling if authMech contains multiple mechs
257 int p = findPool(authMech);
258 if (p < 0 || pools[p] == null) {
277 }
278
279 /**
280 * Obtains a pooled connection that either already exists or is
281 * newly created using the parameters supplied. If it is newly
282 * created, it needs to go through the authentication checks to
283 * determine whether an LDAP bind is necessary.
284 *
285 * Caller needs to invoke ldapClient.authenticateCalled() to
286 * determine whether ldapClient.authenticate() needs to be invoked.
287 * Caller has that responsibility because caller needs to deal
288 * with the LDAP bind response, which might involve referrals,
289 * response controls, errors, etc. This method is responsible only
290 * for establishing the connection.
291 *
292 * @return an LdapClient that is pooled.
293 */
294 static LdapClient getLdapClient(String host, int port, String socketFactory,
295 int connTimeout, int readTimeout, OutputStream trace, int version,
296 String authMech, Control[] ctls, String protocol, String user,
297 Object passwd, Hashtable env) throws NamingException {
298
299 // Create base identity for LdapClient
300 ClientId id = null;
301 Pool pool;
302
303 int p = findPool(authMech);
304 if (p < 0 || (pool=pools[p]) == null) {
305 throw new IllegalArgumentException(
306 "Attempting to use pooling for an unsupported mechanism: " +
307 authMech);
308 }
309 switch (p) {
310 case NONE:
311 id = new ClientId(version, host, port, protocol,
312 ctls, trace, socketFactory);
313 break;
314
315 case SIMPLE:
316 // Add identity information used in simple authentication
317 id = new SimpleClientId(version, host, port, protocol,
368 if (pools[i] != null) {
369 pools[i].expire(threshold);
370 }
371 }
372 }
373
374 private static void d(String msg) {
375 if (debug) {
376 System.err.println("LdapPoolManager: " + msg);
377 }
378 }
379
380 private static void d(String msg, String o) {
381 if (debug) {
382 System.err.println("LdapPoolManager: " + msg + o);
383 }
384 }
385
386 private static final String getProperty(final String propName,
387 final String defVal) {
388 return (String) AccessController.doPrivileged(
389 new PrivilegedAction() {
390 public Object run() {
391 try {
392 return System.getProperty(propName, defVal);
393 } catch (SecurityException e) {
394 return defVal;
395 }
396 }
397 });
398 }
399
400 private static final int getInteger(final String propName,
401 final int defVal) {
402 Integer val = (Integer) AccessController.doPrivileged(
403 new PrivilegedAction() {
404 public Object run() {
405 try {
406 return Integer.getInteger(propName, defVal);
407 } catch (SecurityException e) {
408 return new Integer(defVal);
409 }
410 }
411 });
412 return val.intValue();
413 }
414
415 private static final long getLong(final String propName,
416 final long defVal) {
417 Long val = (Long) AccessController.doPrivileged(
418 new PrivilegedAction() {
419 public Object run() {
420 try {
421 return Long.getLong(propName, defVal);
422 } catch (SecurityException e) {
423 return new Long(defVal);
424 }
425 }
426 });
427 return val.longValue();
428 }
429 }
|
197 *
198 * Non-configurable rejections:
199 * - nonstandard socketFactory has been specified: the pool manager
200 * cannot track input or parameters used by the socket factory and
201 * thus has no way of determining whether two connection requests
202 * are equivalent. Maybe in the future it might add a list of allowed
203 * socket factories to be configured
204 * - trace enabled (except when debugging)
205 * - for Digest authentication, if a callback handler has been specified:
206 * the pool manager cannot track input collected by the handler
207 * and thus has no way of determining whether two connection requests are
208 * equivalent. Maybe in the future it might add a list of allowed
209 * callback handlers.
210 *
211 * Configurable tests:
212 * - Pooling for the requested protocol (plain or ssl) is supported
213 * - Pooling for the requested authentication mechanism is supported
214 *
215 */
216 static boolean isPoolingAllowed(String socketFactory, OutputStream trace,
217 String authMech, String protocol, Hashtable<?,?> env)
218 throws NamingException {
219
220 if (trace != null && !debug
221
222 // Requesting plain protocol but it is not supported
223 || (protocol == null && !supportPlainProtocol)
224
225 // Requesting ssl protocol but it is not supported
226 || ("ssl".equalsIgnoreCase(protocol) && !supportSslProtocol)) {
227
228 d("Pooling disallowed due to tracing or unsupported pooling of protocol");
229 return false;
230 }
231 // pooling of custom socket factory is possible only if the
232 // socket factory interface implements java.util.comparator
233 String COMPARATOR = "java.util.Comparator";
234 boolean foundSockCmp = false;
235 if ((socketFactory != null) &&
236 !socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) {
237 try {
238 Class<?> socketFactoryClass = Obj.helper.loadClass(socketFactory);
239 Class[] interfaces = socketFactoryClass.getInterfaces();
240 for (int i = 0; i < interfaces.length; i++) {
241 if (interfaces[i].getCanonicalName().equals(COMPARATOR)) {
242 foundSockCmp = true;
243 }
244 }
245 } catch (Exception e) {
246 CommunicationException ce =
247 new CommunicationException("Loading the socket factory");
248 ce.setRootCause(e);
249 throw ce;
250 }
251 if (!foundSockCmp) {
252 return false;
253 }
254 }
255 // Cannot use pooling if authMech is not a supported mechs
256 // Cannot use pooling if authMech contains multiple mechs
257 int p = findPool(authMech);
258 if (p < 0 || pools[p] == null) {
277 }
278
279 /**
280 * Obtains a pooled connection that either already exists or is
281 * newly created using the parameters supplied. If it is newly
282 * created, it needs to go through the authentication checks to
283 * determine whether an LDAP bind is necessary.
284 *
285 * Caller needs to invoke ldapClient.authenticateCalled() to
286 * determine whether ldapClient.authenticate() needs to be invoked.
287 * Caller has that responsibility because caller needs to deal
288 * with the LDAP bind response, which might involve referrals,
289 * response controls, errors, etc. This method is responsible only
290 * for establishing the connection.
291 *
292 * @return an LdapClient that is pooled.
293 */
294 static LdapClient getLdapClient(String host, int port, String socketFactory,
295 int connTimeout, int readTimeout, OutputStream trace, int version,
296 String authMech, Control[] ctls, String protocol, String user,
297 Object passwd, Hashtable<?,?> env) throws NamingException {
298
299 // Create base identity for LdapClient
300 ClientId id = null;
301 Pool pool;
302
303 int p = findPool(authMech);
304 if (p < 0 || (pool=pools[p]) == null) {
305 throw new IllegalArgumentException(
306 "Attempting to use pooling for an unsupported mechanism: " +
307 authMech);
308 }
309 switch (p) {
310 case NONE:
311 id = new ClientId(version, host, port, protocol,
312 ctls, trace, socketFactory);
313 break;
314
315 case SIMPLE:
316 // Add identity information used in simple authentication
317 id = new SimpleClientId(version, host, port, protocol,
368 if (pools[i] != null) {
369 pools[i].expire(threshold);
370 }
371 }
372 }
373
374 private static void d(String msg) {
375 if (debug) {
376 System.err.println("LdapPoolManager: " + msg);
377 }
378 }
379
380 private static void d(String msg, String o) {
381 if (debug) {
382 System.err.println("LdapPoolManager: " + msg + o);
383 }
384 }
385
386 private static final String getProperty(final String propName,
387 final String defVal) {
388 return AccessController.doPrivileged(
389 new PrivilegedAction<String>() {
390 public String run() {
391 try {
392 return System.getProperty(propName, defVal);
393 } catch (SecurityException e) {
394 return defVal;
395 }
396 }
397 });
398 }
399
400 private static final int getInteger(final String propName,
401 final int defVal) {
402 Integer val = AccessController.doPrivileged(
403 new PrivilegedAction<Integer>() {
404 public Integer run() {
405 try {
406 return Integer.getInteger(propName, defVal);
407 } catch (SecurityException e) {
408 return new Integer(defVal);
409 }
410 }
411 });
412 return val.intValue();
413 }
414
415 private static final long getLong(final String propName,
416 final long defVal) {
417 Long val = AccessController.doPrivileged(
418 new PrivilegedAction<Long>() {
419 public Long run() {
420 try {
421 return Long.getLong(propName, defVal);
422 } catch (SecurityException e) {
423 return new Long(defVal);
424 }
425 }
426 });
427 return val.longValue();
428 }
429 }
|