/* * RHQ Management Platform * Copyright 2012, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.server.naming; import java.lang.reflect.Field; import java.util.Hashtable; import javax.naming.spi.InitialContextFactory; import javax.naming.spi.InitialContextFactoryBuilder; import javax.naming.spi.NamingManager; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * @author Lukas Krejci */ public class NamingHack { private static final Log LOG = LogFactory.getLog(NamingHack.class); //in case this method is called multiple times, which can happen during the tests, //remember the builder encountered the first time... private static InitialContextFactoryBuilder originalBuilder; public static void bruteForceInitialContextFactoryBuilder() { LOG.info("Modifying the naming subsystem to enable secure execution of scripts inside the server..."); //it is important to synchronize on the NamingManager class because the get/setInitialContextFactoryBuilder //methods in that class are static synchronized. By holding the lock on the NamingManager class we prevent //any other thread to check for the initial context factory builder (and therefore de-facto do any JNDI lookup). synchronized (NamingManager.class) { if (NamingManager.hasInitialContextFactoryBuilder()) { //if anyone ever changes the implementation of the NamingManager, we will break here... //but as of now, we have no other option but to do this and wait for //https://issues.jboss.org/browse/AS7-6109 to be resolved and incorporated into our underlying container try { Field f = NamingManager.class.getDeclaredField("initctx_factory_builder"); f.setAccessible(true); if (originalBuilder == null) { originalBuilder = (InitialContextFactoryBuilder) f.get(null); } f.set(null, null); } catch (Exception e) { LOG.error( "Failed to install a custom initial context factory builder. RHQ installation is unsecure!", e); return; } } try { InitialContextFactory defaultFactory = null; if (originalBuilder != null) { defaultFactory = originalBuilder .createInitialContextFactory(new Hashtable<String, String>()); } NamingManager.setInitialContextFactoryBuilder(new AccessCheckingInitialContextFactoryBuilder( defaultFactory, originalBuilder == null)); } catch (Exception e) { LOG.error("Failed to install a custom initial context factory builder. RHQ installation is unsecure!", e); if (originalBuilder != null) { if (LOG.isDebugEnabled()) { LOG.debug("Trying to restore the original initial context factory builder: " + originalBuilder); } try { NamingManager.setInitialContextFactoryBuilder(originalBuilder); } catch (Exception e2) { LOG.error("Failed to restore the original initial context factory builder. The JNDI lookup may" + " not function properly from this point on...", e2); } } } } } }