HBASE-3582 Allow HMaster and HRegionServer to login from keytab when running on secure Hadoop
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1078225 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2a530e891c
commit
4d28e95a61
|
@ -136,6 +136,8 @@ Release 0.90.2 - Unreleased
|
||||||
log4j.properties
|
log4j.properties
|
||||||
HBASE-3591 completebulkload doesn't honor generic -D options
|
HBASE-3591 completebulkload doesn't honor generic -D options
|
||||||
HBASE-3594 Rest server fails because of missing asm jar
|
HBASE-3594 Rest server fails because of missing asm jar
|
||||||
|
HBASE-3582 Allow HMaster and HRegionServer to login from keytab
|
||||||
|
when on secure Hadoop
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
HBASE-3542 MultiGet methods in Thrift
|
HBASE-3542 MultiGet methods in Thrift
|
||||||
|
|
|
@ -75,6 +75,7 @@ import org.apache.hadoop.hbase.master.handler.TableModifyFamilyHandler;
|
||||||
import org.apache.hadoop.hbase.master.metrics.MasterMetrics;
|
import org.apache.hadoop.hbase.master.metrics.MasterMetrics;
|
||||||
import org.apache.hadoop.hbase.regionserver.HRegion;
|
import org.apache.hadoop.hbase.regionserver.HRegion;
|
||||||
import org.apache.hadoop.hbase.replication.regionserver.Replication;
|
import org.apache.hadoop.hbase.replication.regionserver.Replication;
|
||||||
|
import org.apache.hadoop.hbase.security.User;
|
||||||
import org.apache.hadoop.hbase.util.Bytes;
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
import org.apache.hadoop.hbase.util.InfoServer;
|
import org.apache.hadoop.hbase.util.InfoServer;
|
||||||
import org.apache.hadoop.hbase.util.Pair;
|
import org.apache.hadoop.hbase.util.Pair;
|
||||||
|
@ -203,6 +204,10 @@ implements HMasterInterface, HMasterRegionInterface, MasterServices, Server {
|
||||||
0); // this is a DNC w/o high priority handlers
|
0); // this is a DNC w/o high priority handlers
|
||||||
this.address = new HServerAddress(rpcServer.getListenerAddress());
|
this.address = new HServerAddress(rpcServer.getListenerAddress());
|
||||||
|
|
||||||
|
// initialize server principal (if using secure Hadoop)
|
||||||
|
User.login(conf, "hbase.master.keytab.file",
|
||||||
|
"hbase.master.kerberos.principal", this.address.getHostname());
|
||||||
|
|
||||||
// set the thread name now we have an address
|
// set the thread name now we have an address
|
||||||
setName(MASTER + "-" + this.address);
|
setName(MASTER + "-" + this.address);
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,7 @@ import org.apache.hadoop.hbase.regionserver.metrics.RegionServerMetrics;
|
||||||
import org.apache.hadoop.hbase.regionserver.wal.HLog;
|
import org.apache.hadoop.hbase.regionserver.wal.HLog;
|
||||||
import org.apache.hadoop.hbase.regionserver.wal.WALObserver;
|
import org.apache.hadoop.hbase.regionserver.wal.WALObserver;
|
||||||
import org.apache.hadoop.hbase.replication.regionserver.Replication;
|
import org.apache.hadoop.hbase.replication.regionserver.Replication;
|
||||||
|
import org.apache.hadoop.hbase.security.User;
|
||||||
import org.apache.hadoop.hbase.util.Bytes;
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
import org.apache.hadoop.hbase.util.CompressionTest;
|
import org.apache.hadoop.hbase.util.CompressionTest;
|
||||||
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
|
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
|
||||||
|
@ -344,6 +345,10 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
|
||||||
throw new NullPointerException("Server address cannot be null; "
|
throw new NullPointerException("Server address cannot be null; "
|
||||||
+ "hbase-958 debugging");
|
+ "hbase-958 debugging");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// login the server principal (if using secure Hadoop)
|
||||||
|
User.login(conf, "hbase.regionserver.keytab.file",
|
||||||
|
"hbase.regionserver.kerberos.principal", serverInfo.getHostname());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int NORMAL_QOS = 0;
|
private static final int NORMAL_QOS = 0;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.hadoop.security.UserGroupInformation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
@ -96,7 +97,7 @@ public abstract class User {
|
||||||
/**
|
/**
|
||||||
* Returns the {@code User} instance within current execution context.
|
* Returns the {@code User} instance within current execution context.
|
||||||
*/
|
*/
|
||||||
public static User getCurrent() {
|
public static User getCurrent() throws IOException {
|
||||||
if (IS_SECURE_HADOOP) {
|
if (IS_SECURE_HADOOP) {
|
||||||
return new SecureHadoopUser();
|
return new SecureHadoopUser();
|
||||||
} else {
|
} else {
|
||||||
|
@ -118,6 +119,31 @@ public abstract class User {
|
||||||
return HadoopUser.createUserForTesting(conf, name, groups);
|
return HadoopUser.createUserForTesting(conf, name, groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log in the current process using the given configuration keys for the
|
||||||
|
* credential file and login principal.
|
||||||
|
*
|
||||||
|
* <p><strong>This is only applicable when
|
||||||
|
* running on secure Hadoop</strong> -- see
|
||||||
|
* {@link org.apache.hadoop.security.SecurityUtil#login(Configuration,String,String,String)}.
|
||||||
|
* On regular Hadoop (without security features), this will safely be ignored.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param conf The configuration data to use
|
||||||
|
* @param fileConfKey Property key used to configure path to the credential file
|
||||||
|
* @param principalConfKey Property key used to configure login principal
|
||||||
|
* @param localhost Current hostname to use in any credentials
|
||||||
|
* @throws IOException underlying exception from SecurityUtil.login() call
|
||||||
|
*/
|
||||||
|
public static void login(Configuration conf, String fileConfKey,
|
||||||
|
String principalConfKey, String localhost) throws IOException {
|
||||||
|
if (IS_SECURE_HADOOP) {
|
||||||
|
SecureHadoopUser.login(conf, fileConfKey, principalConfKey, localhost);
|
||||||
|
} else {
|
||||||
|
HadoopUser.login(conf, fileConfKey, principalConfKey, localhost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Concrete implementations */
|
/* Concrete implementations */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,7 +155,14 @@ public abstract class User {
|
||||||
private static class HadoopUser extends User {
|
private static class HadoopUser extends User {
|
||||||
|
|
||||||
private HadoopUser() {
|
private HadoopUser() {
|
||||||
ugi = (UserGroupInformation) callStatic("getCurrentUGI");
|
try {
|
||||||
|
ugi = (UserGroupInformation) callStatic("getCurrentUGI");
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected exception HadoopUser<init>");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private HadoopUser(UserGroupInformation ugi) {
|
private HadoopUser(UserGroupInformation ugi) {
|
||||||
|
@ -143,30 +176,46 @@ public abstract class User {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T runAs(PrivilegedAction<T> action) {
|
public <T> T runAs(PrivilegedAction<T> action) {
|
||||||
UserGroupInformation previous =
|
T result = null;
|
||||||
(UserGroupInformation) callStatic("getCurrentUGI");
|
UserGroupInformation previous = null;
|
||||||
if (ugi != null) {
|
try {
|
||||||
callStatic("setCurrentUser", new Class[]{UserGroupInformation.class},
|
previous = (UserGroupInformation) callStatic("getCurrentUGI");
|
||||||
new Object[]{ugi});
|
try {
|
||||||
|
if (ugi != null) {
|
||||||
|
callStatic("setCurrentUser", new Class[]{UserGroupInformation.class},
|
||||||
|
new Object[]{ugi});
|
||||||
|
}
|
||||||
|
result = action.run();
|
||||||
|
} finally {
|
||||||
|
callStatic("setCurrentUser", new Class[]{UserGroupInformation.class},
|
||||||
|
new Object[]{previous});
|
||||||
|
}
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected exception in runAs()");
|
||||||
}
|
}
|
||||||
T result = action.run();
|
|
||||||
callStatic("setCurrentUser", new Class[]{UserGroupInformation.class},
|
|
||||||
new Object[]{previous});
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T runAs(PrivilegedExceptionAction<T> action)
|
public <T> T runAs(PrivilegedExceptionAction<T> action)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
UserGroupInformation previous =
|
|
||||||
(UserGroupInformation) callStatic("getCurrentUGI");
|
|
||||||
if (ugi != null) {
|
|
||||||
callStatic("setCurrentUGI", new Class[]{UserGroupInformation.class},
|
|
||||||
new Object[]{ugi});
|
|
||||||
}
|
|
||||||
T result = null;
|
T result = null;
|
||||||
try {
|
try {
|
||||||
result = action.run();
|
UserGroupInformation previous =
|
||||||
|
(UserGroupInformation) callStatic("getCurrentUGI");
|
||||||
|
try {
|
||||||
|
if (ugi != null) {
|
||||||
|
callStatic("setCurrentUGI", new Class[]{UserGroupInformation.class},
|
||||||
|
new Object[]{ugi});
|
||||||
|
}
|
||||||
|
result = action.run();
|
||||||
|
} finally {
|
||||||
|
callStatic("setCurrentUGI", new Class[]{UserGroupInformation.class},
|
||||||
|
new Object[]{previous});
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (e instanceof IOException) {
|
if (e instanceof IOException) {
|
||||||
throw (IOException)e;
|
throw (IOException)e;
|
||||||
|
@ -177,9 +226,6 @@ public abstract class User {
|
||||||
} else {
|
} else {
|
||||||
throw new UndeclaredThrowableException(e, "Unknown exception in runAs()");
|
throw new UndeclaredThrowableException(e, "Unknown exception in runAs()");
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
callStatic("setCurrentUGI", new Class[]{UserGroupInformation.class},
|
|
||||||
new Object[]{previous});
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -199,14 +245,22 @@ public abstract class User {
|
||||||
conf.set("hadoop.job.ugi", newUser.toString());
|
conf.set("hadoop.job.ugi", newUser.toString());
|
||||||
return new HadoopUser(newUser);
|
return new HadoopUser(newUser);
|
||||||
} catch (ClassNotFoundException cnfe) {
|
} catch (ClassNotFoundException cnfe) {
|
||||||
LOG.error("UnixUserGroupInformation not found, is this secure Hadoop?", cnfe);
|
throw new RuntimeException(
|
||||||
|
"UnixUserGroupInformation not found, is this secure Hadoop?", cnfe);
|
||||||
} catch (NoSuchMethodException nsme) {
|
} catch (NoSuchMethodException nsme) {
|
||||||
LOG.error("No valid constructor found for UnixUserGroupInformation!", nsme);
|
throw new RuntimeException(
|
||||||
|
"No valid constructor found for UnixUserGroupInformation!", nsme);
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOG.error("Error instantiating new UnixUserGroupInformation", e);
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected exception instantiating new UnixUserGroupInformation");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
public static void login(Configuration conf, String fileConfKey,
|
||||||
|
String principalConfKey, String localhost) throws IOException {
|
||||||
|
LOG.info("Skipping login, not running on secure Hadoop");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,8 +270,17 @@ public abstract class User {
|
||||||
* 0.20 and versions 0.21 and above.
|
* 0.20 and versions 0.21 and above.
|
||||||
*/
|
*/
|
||||||
private static class SecureHadoopUser extends User {
|
private static class SecureHadoopUser extends User {
|
||||||
private SecureHadoopUser() {
|
private SecureHadoopUser() throws IOException {
|
||||||
ugi = (UserGroupInformation) callStatic("getCurrentUser");
|
try {
|
||||||
|
ugi = (UserGroupInformation) callStatic("getCurrentUser");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw ioe;
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected exception getting current secure user");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SecureHadoopUser(UserGroupInformation ugi) {
|
private SecureHadoopUser(UserGroupInformation ugi) {
|
||||||
|
@ -226,54 +289,149 @@ public abstract class User {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getShortName() {
|
public String getShortName() {
|
||||||
return (String)call(ugi, "getShortUserName", null, null);
|
try {
|
||||||
|
return (String)call(ugi, "getShortUserName", null, null);
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected error getting user short name");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T runAs(PrivilegedAction<T> action) {
|
public <T> T runAs(PrivilegedAction<T> action) {
|
||||||
return (T) call(ugi, "doAs", new Class[]{PrivilegedAction.class},
|
try {
|
||||||
new Object[]{action});
|
return (T) call(ugi, "doAs", new Class[]{PrivilegedAction.class},
|
||||||
|
new Object[]{action});
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected exception in runAs()");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T runAs(PrivilegedExceptionAction<T> action)
|
public <T> T runAs(PrivilegedExceptionAction<T> action)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
return (T) call(ugi, "doAs",
|
try {
|
||||||
new Class[]{PrivilegedExceptionAction.class},
|
return (T) call(ugi, "doAs",
|
||||||
new Object[]{action});
|
new Class[]{PrivilegedExceptionAction.class},
|
||||||
|
new Object[]{action});
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw ioe;
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
throw ie;
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unexpected exception in runAs(PrivilegedExceptionAction)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static User createUserForTesting(Configuration conf,
|
public static User createUserForTesting(Configuration conf,
|
||||||
String name, String[] groups) {
|
String name, String[] groups) {
|
||||||
return new SecureHadoopUser(
|
try {
|
||||||
(UserGroupInformation)callStatic("createUserForTesting",
|
return new SecureHadoopUser(
|
||||||
new Class[]{String.class, String[].class},
|
(UserGroupInformation)callStatic("createUserForTesting",
|
||||||
new Object[]{name, groups})
|
new Class[]{String.class, String[].class},
|
||||||
);
|
new Object[]{name, groups})
|
||||||
|
);
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Error creating secure test user");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void login(Configuration conf, String fileConfKey,
|
||||||
|
String principalConfKey, String localhost) throws IOException {
|
||||||
|
// check for SecurityUtil class
|
||||||
|
try {
|
||||||
|
Class c = Class.forName("org.apache.hadoop.security.SecurityUtil");
|
||||||
|
Class[] types = new Class[]{
|
||||||
|
Configuration.class, String.class, String.class, String.class };
|
||||||
|
Object[] args = new Object[]{
|
||||||
|
conf, fileConfKey, principalConfKey, localhost };
|
||||||
|
call(c, null, "login", types, args);
|
||||||
|
} catch (ClassNotFoundException cnfe) {
|
||||||
|
throw new RuntimeException("Unable to login using " +
|
||||||
|
"org.apache.hadoop.security.Security.login(). SecurityUtil class " +
|
||||||
|
"was not found! Is this a version of secure Hadoop?", cnfe);
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw ioe;
|
||||||
|
} catch (RuntimeException re) {
|
||||||
|
throw re;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new UndeclaredThrowableException(e,
|
||||||
|
"Unhandled exception in User.login()");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reflection helper methods */
|
/* Reflection helper methods */
|
||||||
private static Object callStatic(String methodName) {
|
private static Object callStatic(String methodName) throws Exception {
|
||||||
return call(null, methodName, null, null);
|
return call(null, methodName, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object callStatic(String methodName, Class[] types,
|
private static Object callStatic(String methodName, Class[] types,
|
||||||
Object[] args) {
|
Object[] args) throws Exception {
|
||||||
return call(null, methodName, types, args);
|
return call(null, methodName, types, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object call(UserGroupInformation instance, String methodName,
|
private static Object call(UserGroupInformation instance, String methodName,
|
||||||
Class[] types, Object[] args) {
|
Class[] types, Object[] args) throws Exception {
|
||||||
|
return call(UserGroupInformation.class, instance, methodName, types, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> Object call(Class<T> clazz, T instance, String methodName,
|
||||||
|
Class[] types, Object[] args) throws Exception {
|
||||||
try {
|
try {
|
||||||
Method m = UserGroupInformation.class.getMethod(methodName, types);
|
Method m = clazz.getMethod(methodName, types);
|
||||||
return m.invoke(instance, args);
|
return m.invoke(instance, args);
|
||||||
|
} catch (IllegalArgumentException arge) {
|
||||||
|
LOG.fatal("Constructed invalid call. class="+clazz.getName()+
|
||||||
|
" method=" + methodName + " types=" + stringify(types), arge);
|
||||||
|
throw arge;
|
||||||
} catch (NoSuchMethodException nsme) {
|
} catch (NoSuchMethodException nsme) {
|
||||||
LOG.fatal("Can't find method "+methodName+" in UserGroupInformation!",
|
throw new IllegalArgumentException(
|
||||||
nsme);
|
"Can't find method "+methodName+" in "+clazz.getName()+"!", nsme);
|
||||||
} catch (Exception e) {
|
} catch (InvocationTargetException ite) {
|
||||||
LOG.fatal("Error calling method "+methodName, e);
|
// unwrap the underlying exception and rethrow
|
||||||
|
if (ite.getTargetException() != null) {
|
||||||
|
if (ite.getTargetException() instanceof Exception) {
|
||||||
|
throw (Exception)ite.getTargetException();
|
||||||
|
} else if (ite.getTargetException() instanceof Error) {
|
||||||
|
throw (Error)ite.getTargetException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new UndeclaredThrowableException(ite,
|
||||||
|
"Unknown exception invoking "+clazz.getName()+"."+methodName+"()");
|
||||||
|
} catch (IllegalAccessException iae) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Denied access calling "+clazz.getName()+"."+methodName+"()", iae);
|
||||||
|
} catch (SecurityException se) {
|
||||||
|
LOG.fatal("SecurityException calling method. class="+clazz.getName()+
|
||||||
|
" method=" + methodName + " types=" + stringify(types), se);
|
||||||
|
throw se;
|
||||||
}
|
}
|
||||||
return null;
|
}
|
||||||
|
|
||||||
|
private static String stringify(Class[] classes) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
if (classes != null) {
|
||||||
|
for (Class c : classes) {
|
||||||
|
if (buf.length() > 0) {
|
||||||
|
buf.append(",");
|
||||||
|
}
|
||||||
|
buf.append(c.getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf.append("NULL");
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,6 +459,45 @@
|
||||||
used for client / server RPC call marshalling.
|
used for client / server RPC call marshalling.
|
||||||
</description>
|
</description>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<!-- The following properties configure authentication information for
|
||||||
|
HBase processes when using Kerberos security. There are no default
|
||||||
|
values, included here for documentation purposes -->
|
||||||
|
<property>
|
||||||
|
<name>hbase.master.keytab.file</name>
|
||||||
|
<value></value>
|
||||||
|
<description>Full path to the kerberos keytab file to use for logging in
|
||||||
|
the configured HMaster server principal.
|
||||||
|
</description>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>hbase.master.kerberos.principal</name>
|
||||||
|
<value></value>
|
||||||
|
<description>Ex. "hbase/_HOST@EXAMPLE.COM". The kerberos principal name
|
||||||
|
that should be used to run the HMaster process. The principal name should
|
||||||
|
be in the form: user/hostname@DOMAIN. If "_HOST" is used as the hostname
|
||||||
|
portion, it will be replaced with the actual hostname of the running
|
||||||
|
instance.
|
||||||
|
</description>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>hbase.regionserver.keytab.file</name>
|
||||||
|
<value></value>
|
||||||
|
<description>Full path to the kerberos keytab file to use for logging in
|
||||||
|
the configured HRegionServer server principal.
|
||||||
|
</description>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>hbase.regionserver.kerberos.principal</name>
|
||||||
|
<value></value>
|
||||||
|
<description>Ex. "hbase/_HOST@EXAMPLE.COM". The kerberos principal name
|
||||||
|
that should be used to run the HRegionServer process. The principal name
|
||||||
|
should be in the form: user/hostname@DOMAIN. If "_HOST" is used as the
|
||||||
|
hostname portion, it will be replaced with the actual hostname of the
|
||||||
|
running instance. An entry for this principal must exist in the file
|
||||||
|
specified in hbase.regionserver.keytab.file
|
||||||
|
</description>
|
||||||
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>zookeeper.session.timeout</name>
|
<name>zookeeper.session.timeout</name>
|
||||||
<value>180000</value>
|
<value>180000</value>
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.hbase.HBaseConfiguration;
|
import org.apache.hadoop.hbase.HBaseConfiguration;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
|
||||||
|
@ -42,10 +43,10 @@ public class TestUser {
|
||||||
public void testRunAs() throws Exception {
|
public void testRunAs() throws Exception {
|
||||||
Configuration conf = HBaseConfiguration.create();
|
Configuration conf = HBaseConfiguration.create();
|
||||||
final User user = User.createUserForTesting(conf, "testuser", new String[]{"foo"});
|
final User user = User.createUserForTesting(conf, "testuser", new String[]{"foo"});
|
||||||
final PrivilegedAction<String> action = new PrivilegedAction<String>(){
|
final PrivilegedExceptionAction<String> action = new PrivilegedExceptionAction<String>(){
|
||||||
public String run() {
|
public String run() throws IOException {
|
||||||
User u = User.getCurrent();
|
User u = User.getCurrent();
|
||||||
return u.getName();
|
return u.getName();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -68,8 +69,8 @@ public class TestUser {
|
||||||
assertEquals("User name in runAs() should match", "testuser", username);
|
assertEquals("User name in runAs() should match", "testuser", username);
|
||||||
|
|
||||||
// verify that nested contexts work
|
// verify that nested contexts work
|
||||||
user2.runAs(new PrivilegedAction(){
|
user2.runAs(new PrivilegedExceptionAction(){
|
||||||
public Object run() {
|
public Object run() throws IOException, InterruptedException{
|
||||||
String nestedName = user.runAs(action);
|
String nestedName = user.runAs(action);
|
||||||
assertEquals("Nest name should match nested user", "testuser", nestedName);
|
assertEquals("Nest name should match nested user", "testuser", nestedName);
|
||||||
assertEquals("Current name should match current user",
|
assertEquals("Current name should match current user",
|
||||||
|
|
Loading…
Reference in New Issue