Skip to content

Commit

Permalink
Merge pull request #7521 from chackoj/assert-privileges-to-retrieve-o…
Browse files Browse the repository at this point in the history
…bject-factory-class

Call Class.forName() within doPrivileged block from WASURLObjectFactoryFinder
  • Loading branch information
joe-chacko committed May 17, 2019
2 parents 4c109dd + d66e01e commit d80f5df
Showing 1 changed file with 53 additions and 30 deletions.
Expand Up @@ -10,35 +10,34 @@
*******************************************************************************/
package com.ibm.ws.jndi.internal;

import static org.osgi.service.component.annotations.ConfigurationPolicy.IGNORE;
import com.ibm.websphere.ras.Tr;
import com.ibm.websphere.ras.TraceComponent;
import com.ibm.ws.ffdc.annotation.FFDCIgnore;
import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
import org.osgi.service.component.annotations.Component;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.ObjectFactory;
import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.StringTokenizer;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.ObjectFactory;

import org.apache.aries.jndi.urls.URLObjectFactoryFinder;
import org.osgi.service.component.annotations.Component;

import com.ibm.websphere.ras.Tr;
import com.ibm.websphere.ras.TraceComponent;
import com.ibm.ws.ffdc.FFDCFilter;
import com.ibm.ws.ffdc.annotation.FFDCIgnore;
import static org.osgi.service.component.annotations.ConfigurationPolicy.IGNORE;

@Component(configurationPolicy = IGNORE, property = "service.vendor=IBM")
public class WASURLObjectFactoryFinder implements URLObjectFactoryFinder {
private static final TraceComponent tc = Tr.register(WASURLObjectFactoryFinder.class);

@Override
@FFDCIgnore(ClassNotFoundException.class)
public ObjectFactory findFactory(String urlSchema, Hashtable<?, ?> env) throws NamingException {
List<String> pkgPrefixes = new ArrayList<String>();
final List<String> pkgPrefixes = new ArrayList<String>();

// Collect any package prefixes specified by the environment
if (env != null) {
Expand All @@ -54,16 +53,27 @@ public ObjectFactory findFactory(String urlSchema, Hashtable<?, ?> env) throws N
// Always add default prefix
pkgPrefixes.add("com.sun.jndi.url");

try {
return findFactory(urlSchema, pkgPrefixes);
} catch (ClassNotFoundException e) {
// auto-ffdc
return null;
}
}

@FFDCIgnore(ClassNotFoundException.class)
private ObjectFactory findFactory(String urlSchema, List<String> pkgPrefixes) throws ClassNotFoundException {
ClassNotFoundException cnfe = null;
final ClassLoader tccl = Privileged.getThreadContextClassLoader();

for (String pkgPrefix : pkgPrefixes) {
String className = pkgPrefix + "." + urlSchema + "." + urlSchema + "URLContextFactory";

try {
Class<?> clazz = Class.forName(className, true, getClassLoader());
return (ObjectFactory) clazz.newInstance();
return Privileged.getConstructor(tccl, className).newInstance();
} catch (ClassNotFoundException e) {
// Can occur quite often, so we want to minimize the noise
// trace every occurrence, but only report FFDC for one occurrence
// Can occur quite often, so minimize the noise.
// Trace every occurrence, but only report FFDC for the final occurrence
if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
Tr.debug(tc, "Could not find class " + className, e);
}
Expand All @@ -73,24 +83,37 @@ public ObjectFactory findFactory(String urlSchema, Hashtable<?, ?> env) throws N
}
}

if (cnfe != null) {
// If we get here it should be not-null unless some other exception were thrown -
// in that case, the auto ffdc should have caught it
FFDCFilter.processException(cnfe, WASURLObjectFactoryFinder.class.getName() + ".findFactory",
"74", new Object[] { pkgPrefixes, urlSchema, env });
}

if (cnfe != null) throw cnfe;
return null;
}

private ClassLoader getClassLoader() {
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
private enum Privileged implements PrivilegedAction<ClassLoader> {
GET_TCCL {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
};

});
}
static ClassLoader getThreadContextClassLoader() {
return AccessController.doPrivileged(GET_TCCL);
}

@FFDCIgnore(PrivilegedActionException.class)
static Constructor<? extends ObjectFactory> getConstructor(final ClassLoader tccl, final String className) throws Exception {
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<? extends ObjectFactory>>() {
public Constructor<? extends ObjectFactory> run() throws ClassNotFoundException, NoSuchMethodException {
Class<?> clazz = Class.forName(className, true, tccl);
if (!ObjectFactory.class.isAssignableFrom(clazz)) {
throw new ClassCastException(ObjectFactory.class.getName() + " is not assignable from " + clazz.getName());
}
Class<? extends ObjectFactory> ofc = (Class<? extends ObjectFactory>) clazz;
return ofc.getConstructor();
}
});
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}
}

0 comments on commit d80f5df

Please sign in to comment.