Skip to content

Commit

Permalink
PHOENIX-6908 KerberosName$NoMatchingRule exception in QueryServer.Pho…
Browse files Browse the repository at this point in the history
…enixRemoteUserExtractor
  • Loading branch information
stoty committed Mar 18, 2023
1 parent 76dc256 commit d086ca5
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ public void testSuccessfulImpersonation() throws Exception {
final String doAsUrlTemplate = getUrlTemplate();
final String tableName = "POSITIVE_IMPERSONATION";
final int numRows = 5;
final UserGroupInformation serviceUgi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(environment.getServicePrincipal(), environment.getServiceKeytab().getAbsolutePath());
final UserGroupInformation serviceUgi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(environment.getServicePrincipal() + "@" + environment.getRealm(), environment.getServiceKeytab().getAbsolutePath());
serviceUgi.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
createTable(tableName, numRows);
grantUsersToPhoenixSystemTables(Arrays.asList(user1.getKey(), user2.getKey()));
return null;
}
});
UserGroupInformation user1Ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(user1.getKey(), user1.getValue().getAbsolutePath());
UserGroupInformation user1Ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(user1.getKey() + "@" + environment.getRealm(), user1.getValue().getAbsolutePath());
user1Ugi.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
// This user should not be able to read the table
Expand All @@ -146,15 +146,15 @@ public void testDisallowedImpersonation() throws Exception {
final String doAsUrlTemplate = getUrlTemplate();
final String tableName = "DISALLOWED_IMPERSONATION";
final int numRows = 5;
final UserGroupInformation serviceUgi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(environment.getServicePrincipal(), environment.getServiceKeytab().getAbsolutePath());
final UserGroupInformation serviceUgi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(environment.getServicePrincipal() + "@" + environment.getRealm(), environment.getServiceKeytab().getAbsolutePath());
serviceUgi.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
createTable(tableName, numRows);
grantUsersToPhoenixSystemTables(Arrays.asList(user2.getKey()));
return null;
}
});
UserGroupInformation user2Ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(user2.getKey(), user2.getValue().getAbsolutePath());
UserGroupInformation user2Ugi = UserGroupInformation.loginUserFromKeytabAndReturnUGI(user2.getKey() + "@" + environment.getRealm(), user2.getValue().getAbsolutePath());
user2Ugi.doAs(new PrivilegedExceptionAction<Void>() {
@Override public Void run() throws Exception {
// This user is disallowed to read this table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public class QueryServerEnvironment {
private final File KEYTAB_DIR = new File(TEMP_DIR, "keytabs");
private final List<File> USER_KEYTAB_FILES = new ArrayList<>();

private static final String LOCAL_HOST_REVERSE_DNS_LOOKUP_NAME;
static final String LOCAL_HOST_REVERSE_DNS_LOOKUP_NAME;

static {
try {
Expand Down Expand Up @@ -142,7 +142,7 @@ private void createUsers(int numUsers) throws Exception {
for (int i = 1; i <= numUsers; i++) {
String principal = "user" + i;
File keytabFile = new File(KEYTAB_DIR, principal + ".keytab");
KDC.createPrincipal(keytabFile, principal);
KDC.createPrincipal(keytabFile, principal + "/"+ LOCAL_HOST_REVERSE_DNS_LOOKUP_NAME + "@" + KDC.getRealm());
USER_KEYTAB_FILES.add(keytabFile);
}
}
Expand All @@ -151,7 +151,7 @@ public Map.Entry<String, File> getUser(int offset) {
if (!(offset > 0 && offset <= NUM_CREATED_USERS)) {
throw new IllegalArgumentException();
}
return new AbstractMap.SimpleImmutableEntry<String, File>("user" + offset, USER_KEYTAB_FILES.get(offset - 1));
return new AbstractMap.SimpleImmutableEntry<String, File>("user" + offset + "/" + LOCAL_HOST_REVERSE_DNS_LOOKUP_NAME, USER_KEYTAB_FILES.get(offset - 1));
}

/**
Expand Down Expand Up @@ -325,6 +325,10 @@ public Void run() {
: "");
}

public String getRealm() {
return KDC.getRealm();
}

public void stop() throws Exception {
// Remove our custom ConfigurationFactory for future tests
InstanceResolver.clearSingletons();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,9 @@ public PhoenixRemoteUserExtractor(Configuration conf) {
public String extract(HttpServletRequest request) throws RemoteUserExtractionException {
if (request.getParameter(userExtractParam) != null) {
String extractedUser = paramRemoteUserExtractor.extract(request);
UserGroupInformation ugi = UserGroupInformation.createRemoteUser(request.getRemoteUser());
UserGroupInformation ugi =
UserGroupInformation
.createRemoteUser(stripHostNameFromPrincipal(request.getRemoteUser()));
UserGroupInformation proxyUser = UserGroupInformation.createProxyUser(extractedUser, ugi);

// Check if this user is allowed to be impersonated.
Expand Down Expand Up @@ -597,17 +599,7 @@ public <T> T doAsRemoteUser(String remoteUserName, String remoteAddress,

// Proxy this user on top of the server's user (the real user). Get a cached instance, the
// LoadingCache will create a new instance for us if one isn't cached.

// realm got removed from remoteUserName in CALCITE-4152
// so we remove the instance name to avoid geting KerberosName$NoMatchingRule exception

int atSignIndex = remoteUserName.indexOf('@');
int separatorIndex = remoteUserName.indexOf('/');
if (atSignIndex == -1 && separatorIndex > 0) {
remoteUserName = remoteUserName.substring(0, separatorIndex);
}

UserGroupInformation proxyUser = createProxyUser(remoteUserName);
UserGroupInformation proxyUser = createProxyUser(stripHostNameFromPrincipal(remoteUserName));

// Execute the actual call as this proxy user
return proxyUser.doAs(new PrivilegedExceptionAction<T>() {
Expand All @@ -633,6 +625,27 @@ SimpleLRUCache<String,UserGroupInformation> getCache() {
}
}

/**
* The new Jetty kerberos implementation that we use strips the realm from the principal, which
* and Hadoop cannot process that.
* This strips the hostname part as well, so that only the username remains.
* @param remoteUserName the principal as received from Jetty
* @return the principal without the hostname part
*/
//TODO We are probably compensating for a Jetty a bug, which should really be fixed in Jetty
// See PHOENIX-6913
private static String stripHostNameFromPrincipal(String remoteUserName) {
// realm got removed from remoteUserName in CALCITE-4152
// so we remove the instance name to avoid geting KerberosName$NoMatchingRule exception
int atSignIndex = remoteUserName.indexOf('@');
int separatorIndex = remoteUserName.indexOf('/');
if (atSignIndex == -1 && separatorIndex > 0) {
remoteUserName = remoteUserName.substring(0, separatorIndex);
}
return remoteUserName;
}

public static void main(String[] argv) throws Exception {
int ret = ToolRunner.run(HBaseConfiguration.create(), new QueryServer(), argv);
System.exit(ret);
Expand Down

0 comments on commit d086ca5

Please sign in to comment.