|
@@ -18,6 +18,7 @@
|
|
|
|
|
|
package org.apache.hadoop.conf;
|
|
package org.apache.hadoop.conf;
|
|
|
|
|
|
|
|
+import com.ctc.wstx.api.ReaderConfig;
|
|
import com.ctc.wstx.io.StreamBootstrapper;
|
|
import com.ctc.wstx.io.StreamBootstrapper;
|
|
import com.ctc.wstx.io.SystemId;
|
|
import com.ctc.wstx.io.SystemId;
|
|
import com.ctc.wstx.stax.WstxInputFactory;
|
|
import com.ctc.wstx.stax.WstxInputFactory;
|
|
@@ -70,6 +71,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
import javax.xml.parsers.ParserConfigurationException;
|
|
|
|
+import javax.xml.stream.XMLInputFactory;
|
|
import javax.xml.stream.XMLStreamConstants;
|
|
import javax.xml.stream.XMLStreamConstants;
|
|
import javax.xml.stream.XMLStreamException;
|
|
import javax.xml.stream.XMLStreamException;
|
|
import javax.xml.stream.XMLStreamReader;
|
|
import javax.xml.stream.XMLStreamReader;
|
|
@@ -91,6 +93,7 @@ import org.apache.hadoop.fs.CommonConfigurationKeys;
|
|
import org.apache.hadoop.io.Writable;
|
|
import org.apache.hadoop.io.Writable;
|
|
import org.apache.hadoop.io.WritableUtils;
|
|
import org.apache.hadoop.io.WritableUtils;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
|
|
+import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.security.alias.CredentialProvider;
|
|
import org.apache.hadoop.security.alias.CredentialProvider;
|
|
import org.apache.hadoop.security.alias.CredentialProvider.CredentialEntry;
|
|
import org.apache.hadoop.security.alias.CredentialProvider.CredentialEntry;
|
|
import org.apache.hadoop.security.alias.CredentialProviderFactory;
|
|
import org.apache.hadoop.security.alias.CredentialProviderFactory;
|
|
@@ -206,19 +209,31 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
private static final String DEFAULT_STRING_CHECK =
|
|
private static final String DEFAULT_STRING_CHECK =
|
|
"testingforemptydefaultvalue";
|
|
"testingforemptydefaultvalue";
|
|
|
|
|
|
|
|
+ private static boolean restrictSystemPropsDefault = false;
|
|
|
|
+ private boolean restrictSystemProps = restrictSystemPropsDefault;
|
|
private boolean allowNullValueProperties = false;
|
|
private boolean allowNullValueProperties = false;
|
|
|
|
|
|
private static class Resource {
|
|
private static class Resource {
|
|
private final Object resource;
|
|
private final Object resource;
|
|
private final String name;
|
|
private final String name;
|
|
|
|
+ private final boolean restrictParser;
|
|
|
|
|
|
public Resource(Object resource) {
|
|
public Resource(Object resource) {
|
|
this(resource, resource.toString());
|
|
this(resource, resource.toString());
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ public Resource(Object resource, boolean useRestrictedParser) {
|
|
|
|
+ this(resource, resource.toString(), useRestrictedParser);
|
|
|
|
+ }
|
|
|
|
+
|
|
public Resource(Object resource, String name) {
|
|
public Resource(Object resource, String name) {
|
|
|
|
+ this(resource, name, getRestrictParserDefault(resource));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public Resource(Object resource, String name, boolean restrictParser) {
|
|
this.resource = resource;
|
|
this.resource = resource;
|
|
this.name = name;
|
|
this.name = name;
|
|
|
|
+ this.restrictParser = restrictParser;
|
|
}
|
|
}
|
|
|
|
|
|
public String getName(){
|
|
public String getName(){
|
|
@@ -228,11 +243,28 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
public Object getResource() {
|
|
public Object getResource() {
|
|
return resource;
|
|
return resource;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ public boolean isParserRestricted() {
|
|
|
|
+ return restrictParser;
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public String toString() {
|
|
public String toString() {
|
|
return name;
|
|
return name;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ private static boolean getRestrictParserDefault(Object resource) {
|
|
|
|
+ if (resource instanceof String) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ UserGroupInformation user;
|
|
|
|
+ try {
|
|
|
|
+ user = UserGroupInformation.getCurrentUser();
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new RuntimeException("Unable to determine current user", e);
|
|
|
|
+ }
|
|
|
|
+ return user.getRealUser() != null;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -254,7 +286,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
new ConcurrentHashMap<String, Boolean>());
|
|
new ConcurrentHashMap<String, Boolean>());
|
|
|
|
|
|
private boolean loadDefaults = true;
|
|
private boolean loadDefaults = true;
|
|
-
|
|
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Configuration objects
|
|
* Configuration objects
|
|
*/
|
|
*/
|
|
@@ -777,6 +809,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
this.overlay = (Properties)other.overlay.clone();
|
|
this.overlay = (Properties)other.overlay.clone();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this.restrictSystemProps = other.restrictSystemProps;
|
|
if (other.updatingResource != null) {
|
|
if (other.updatingResource != null) {
|
|
this.updatingResource = new ConcurrentHashMap<String, String[]>(
|
|
this.updatingResource = new ConcurrentHashMap<String, String[]>(
|
|
other.updatingResource);
|
|
other.updatingResource);
|
|
@@ -825,6 +858,14 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public static void setRestrictSystemPropertiesDefault(boolean val) {
|
|
|
|
+ restrictSystemPropsDefault = val;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void setRestrictSystemProperties(boolean val) {
|
|
|
|
+ this.restrictSystemProps = val;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Add a configuration resource.
|
|
* Add a configuration resource.
|
|
*
|
|
*
|
|
@@ -838,6 +879,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
addResourceObject(new Resource(name));
|
|
addResourceObject(new Resource(name));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void addResource(String name, boolean restrictedParser) {
|
|
|
|
+ addResourceObject(new Resource(name, restrictedParser));
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Add a configuration resource.
|
|
* Add a configuration resource.
|
|
*
|
|
*
|
|
@@ -852,6 +897,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
addResourceObject(new Resource(url));
|
|
addResourceObject(new Resource(url));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void addResource(URL url, boolean restrictedParser) {
|
|
|
|
+ addResourceObject(new Resource(url, restrictedParser));
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Add a configuration resource.
|
|
* Add a configuration resource.
|
|
*
|
|
*
|
|
@@ -866,6 +915,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
addResourceObject(new Resource(file));
|
|
addResourceObject(new Resource(file));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void addResource(Path file, boolean restrictedParser) {
|
|
|
|
+ addResourceObject(new Resource(file, restrictedParser));
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Add a configuration resource.
|
|
* Add a configuration resource.
|
|
*
|
|
*
|
|
@@ -883,6 +936,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
addResourceObject(new Resource(in));
|
|
addResourceObject(new Resource(in));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void addResource(InputStream in, boolean restrictedParser) {
|
|
|
|
+ addResourceObject(new Resource(in, restrictedParser));
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Add a configuration resource.
|
|
* Add a configuration resource.
|
|
*
|
|
*
|
|
@@ -896,7 +953,12 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
public void addResource(InputStream in, String name) {
|
|
public void addResource(InputStream in, String name) {
|
|
addResourceObject(new Resource(in, name));
|
|
addResourceObject(new Resource(in, name));
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ public void addResource(InputStream in, String name,
|
|
|
|
+ boolean restrictedParser) {
|
|
|
|
+ addResourceObject(new Resource(in, name, restrictedParser));
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Add a configuration resource.
|
|
* Add a configuration resource.
|
|
*
|
|
*
|
|
@@ -906,7 +968,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
* @param conf Configuration object from which to load properties
|
|
* @param conf Configuration object from which to load properties
|
|
*/
|
|
*/
|
|
public void addResource(Configuration conf) {
|
|
public void addResource(Configuration conf) {
|
|
- addResourceObject(new Resource(conf.getProps()));
|
|
|
|
|
|
+ addResourceObject(new Resource(conf.getProps(), conf.restrictSystemProps));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -926,6 +988,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
|
|
|
|
private synchronized void addResourceObject(Resource resource) {
|
|
private synchronized void addResourceObject(Resource resource) {
|
|
resources.add(resource); // add to resources
|
|
resources.add(resource); // add to resources
|
|
|
|
+ restrictSystemProps |= resource.isParserRestricted();
|
|
reloadConfiguration();
|
|
reloadConfiguration();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1034,34 +1097,36 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
final String var = eval.substring(varBounds[SUB_START_IDX],
|
|
final String var = eval.substring(varBounds[SUB_START_IDX],
|
|
varBounds[SUB_END_IDX]);
|
|
varBounds[SUB_END_IDX]);
|
|
String val = null;
|
|
String val = null;
|
|
- try {
|
|
|
|
- if (var.startsWith("env.") && 4 < var.length()) {
|
|
|
|
- String v = var.substring(4);
|
|
|
|
- int i = 0;
|
|
|
|
- for (; i < v.length(); i++) {
|
|
|
|
- char c = v.charAt(i);
|
|
|
|
- if (c == ':' && i < v.length() - 1 && v.charAt(i + 1) == '-') {
|
|
|
|
- val = getenv(v.substring(0, i));
|
|
|
|
- if (val == null || val.length() == 0) {
|
|
|
|
- val = v.substring(i + 2);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- } else if (c == '-') {
|
|
|
|
- val = getenv(v.substring(0, i));
|
|
|
|
- if (val == null) {
|
|
|
|
- val = v.substring(i + 1);
|
|
|
|
|
|
+ if (!restrictSystemProps) {
|
|
|
|
+ try {
|
|
|
|
+ if (var.startsWith("env.") && 4 < var.length()) {
|
|
|
|
+ String v = var.substring(4);
|
|
|
|
+ int i = 0;
|
|
|
|
+ for (; i < v.length(); i++) {
|
|
|
|
+ char c = v.charAt(i);
|
|
|
|
+ if (c == ':' && i < v.length() - 1 && v.charAt(i + 1) == '-') {
|
|
|
|
+ val = getenv(v.substring(0, i));
|
|
|
|
+ if (val == null || val.length() == 0) {
|
|
|
|
+ val = v.substring(i + 2);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ } else if (c == '-') {
|
|
|
|
+ val = getenv(v.substring(0, i));
|
|
|
|
+ if (val == null) {
|
|
|
|
+ val = v.substring(i + 1);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- break;
|
|
|
|
}
|
|
}
|
|
|
|
+ if (i == v.length()) {
|
|
|
|
+ val = getenv(v);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ val = getProperty(var);
|
|
}
|
|
}
|
|
- if (i == v.length()) {
|
|
|
|
- val = getenv(v);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- val = getProperty(var);
|
|
|
|
|
|
+ } catch (SecurityException se) {
|
|
|
|
+ LOG.warn("Unexpected SecurityException in Configuration", se);
|
|
}
|
|
}
|
|
- } catch(SecurityException se) {
|
|
|
|
- LOG.warn("Unexpected SecurityException in Configuration", se);
|
|
|
|
}
|
|
}
|
|
if (val == null) {
|
|
if (val == null) {
|
|
val = getRaw(var);
|
|
val = getRaw(var);
|
|
@@ -1128,6 +1193,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
this.allowNullValueProperties = val;
|
|
this.allowNullValueProperties = val;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ public void setRestrictSystemProps(boolean val) {
|
|
|
|
+ this.restrictSystemProps = val;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Return existence of the <code>name</code> property, but only for
|
|
* Return existence of the <code>name</code> property, but only for
|
|
* names which have no valid value, usually non-existent or commented
|
|
* names which have no valid value, usually non-existent or commented
|
|
@@ -2718,7 +2787,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
return configMap;
|
|
return configMap;
|
|
}
|
|
}
|
|
|
|
|
|
- private XMLStreamReader parse(URL url)
|
|
|
|
|
|
+ private XMLStreamReader parse(URL url, boolean restricted)
|
|
throws IOException, XMLStreamException {
|
|
throws IOException, XMLStreamException {
|
|
if (!quietmode) {
|
|
if (!quietmode) {
|
|
if (LOG.isDebugEnabled()) {
|
|
if (LOG.isDebugEnabled()) {
|
|
@@ -2735,11 +2804,11 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
// with other users.
|
|
// with other users.
|
|
connection.setUseCaches(false);
|
|
connection.setUseCaches(false);
|
|
}
|
|
}
|
|
- return parse(connection.getInputStream(), url.toString());
|
|
|
|
|
|
+ return parse(connection.getInputStream(), url.toString(), restricted);
|
|
}
|
|
}
|
|
|
|
|
|
- private XMLStreamReader parse(InputStream is, String systemIdStr)
|
|
|
|
- throws IOException, XMLStreamException {
|
|
|
|
|
|
+ private XMLStreamReader parse(InputStream is, String systemIdStr,
|
|
|
|
+ boolean restricted) throws IOException, XMLStreamException {
|
|
if (!quietmode) {
|
|
if (!quietmode) {
|
|
LOG.debug("parsing input stream " + is);
|
|
LOG.debug("parsing input stream " + is);
|
|
}
|
|
}
|
|
@@ -2747,9 +2816,12 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
SystemId systemId = SystemId.construct(systemIdStr);
|
|
SystemId systemId = SystemId.construct(systemIdStr);
|
|
- return XML_INPUT_FACTORY.createSR(XML_INPUT_FACTORY.createPrivateConfig(),
|
|
|
|
- systemId, StreamBootstrapper.getInstance(null, systemId, is), false,
|
|
|
|
- true);
|
|
|
|
|
|
+ ReaderConfig readerConfig = XML_INPUT_FACTORY.createPrivateConfig();
|
|
|
|
+ if (restricted) {
|
|
|
|
+ readerConfig.setProperty(XMLInputFactory.SUPPORT_DTD, false);
|
|
|
|
+ }
|
|
|
|
+ return XML_INPUT_FACTORY.createSR(readerConfig, systemId,
|
|
|
|
+ StreamBootstrapper.getInstance(null, systemId, is), false, true);
|
|
}
|
|
}
|
|
|
|
|
|
private void loadResources(Properties properties,
|
|
private void loadResources(Properties properties,
|
|
@@ -2757,7 +2829,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
boolean quiet) {
|
|
boolean quiet) {
|
|
if(loadDefaults) {
|
|
if(loadDefaults) {
|
|
for (String resource : defaultResources) {
|
|
for (String resource : defaultResources) {
|
|
- loadResource(properties, new Resource(resource), quiet);
|
|
|
|
|
|
+ loadResource(properties, new Resource(resource, false), quiet);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2777,12 +2849,13 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
name = wrapper.getName();
|
|
name = wrapper.getName();
|
|
XMLStreamReader2 reader = null;
|
|
XMLStreamReader2 reader = null;
|
|
boolean returnCachedProperties = false;
|
|
boolean returnCachedProperties = false;
|
|
|
|
+ boolean isRestricted = wrapper.isParserRestricted();
|
|
|
|
|
|
if (resource instanceof URL) { // an URL resource
|
|
if (resource instanceof URL) { // an URL resource
|
|
- reader = (XMLStreamReader2)parse((URL)resource);
|
|
|
|
|
|
+ reader = (XMLStreamReader2)parse((URL)resource, isRestricted);
|
|
} else if (resource instanceof String) { // a CLASSPATH resource
|
|
} else if (resource instanceof String) { // a CLASSPATH resource
|
|
URL url = getResource((String)resource);
|
|
URL url = getResource((String)resource);
|
|
- reader = (XMLStreamReader2)parse(url);
|
|
|
|
|
|
+ reader = (XMLStreamReader2)parse(url, isRestricted);
|
|
} else if (resource instanceof Path) { // a file resource
|
|
} else if (resource instanceof Path) { // a file resource
|
|
// Can't use FileSystem API or we get an infinite loop
|
|
// Can't use FileSystem API or we get an infinite loop
|
|
// since FileSystem uses Configuration API. Use java.io.File instead.
|
|
// since FileSystem uses Configuration API. Use java.io.File instead.
|
|
@@ -2793,10 +2866,12 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
LOG.debug("parsing File " + file);
|
|
LOG.debug("parsing File " + file);
|
|
}
|
|
}
|
|
reader = (XMLStreamReader2)parse(new BufferedInputStream(
|
|
reader = (XMLStreamReader2)parse(new BufferedInputStream(
|
|
- new FileInputStream(file)), ((Path)resource).toString());
|
|
|
|
|
|
+ new FileInputStream(file)), ((Path)resource).toString(),
|
|
|
|
+ isRestricted);
|
|
}
|
|
}
|
|
} else if (resource instanceof InputStream) {
|
|
} else if (resource instanceof InputStream) {
|
|
- reader = (XMLStreamReader2)parse((InputStream)resource, null);
|
|
|
|
|
|
+ reader = (XMLStreamReader2)parse((InputStream)resource, null,
|
|
|
|
+ isRestricted);
|
|
returnCachedProperties = true;
|
|
returnCachedProperties = true;
|
|
} else if (resource instanceof Properties) {
|
|
} else if (resource instanceof Properties) {
|
|
overlay(properties, (Properties)resource);
|
|
overlay(properties, (Properties)resource);
|
|
@@ -2878,6 +2953,10 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
if (confInclude == null) {
|
|
if (confInclude == null) {
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ if (isRestricted) {
|
|
|
|
+ throw new RuntimeException("Error parsing resource " + wrapper
|
|
|
|
+ + ": XInclude is not supported for restricted resources");
|
|
|
|
+ }
|
|
// Determine if the included resource is a classpath resource
|
|
// Determine if the included resource is a classpath resource
|
|
// otherwise fallback to a file resource
|
|
// otherwise fallback to a file resource
|
|
// xi:include are treated as inline and retain current source
|
|
// xi:include are treated as inline and retain current source
|
|
@@ -2992,7 +3071,7 @@ public class Configuration implements Iterable<Map.Entry<String,String>>,
|
|
|
|
|
|
if (returnCachedProperties) {
|
|
if (returnCachedProperties) {
|
|
overlay(properties, toAddTo);
|
|
overlay(properties, toAddTo);
|
|
- return new Resource(toAddTo, name);
|
|
|
|
|
|
+ return new Resource(toAddTo, name, wrapper.isParserRestricted());
|
|
}
|
|
}
|
|
return null;
|
|
return null;
|
|
} catch (IOException e) {
|
|
} catch (IOException e) {
|