Guanghao Zhang created HBASE-22503:
--------------------------------------
Summary: Failed to upgrade to 2.2+ as the global permission which
storaged in zk is not right
Key: HBASE-22503
URL: https://issues.apache.org/jira/browse/HBASE-22503
Project: HBase
Issue Type: Improvement
Reporter: Guanghao Zhang
Before 2.2, the global permission which storaged in zk is not right. It was
storaged as a table permission. After HBASE-21255, 2.2+ will read it as a
global permission and will throw a cast error.
{code:java}
Caused by: java.lang.ClassCastException:
org.apache.hadoop.hbase.security.access.TablePermission cannot be cast to
org.apache.hadoop.hbase.security.access.GlobalPermission
at
org.apache.hadoop.hbase.security.access.AuthManager.updateGlobalCache(AuthManager.java:171)
at
org.apache.hadoop.hbase.security.access.AuthManager.refreshTableCacheFromWritable(AuthManager.java:129)
at
org.apache.hadoop.hbase.security.access.ZKPermissionWatcher.refreshAuthManager(ZKPermissionWatcher.java:252)
at
org.apache.hadoop.hbase.security.access.ZKPermissionWatcher.refreshNodes(ZKPermissionWatcher.java:235)
{code}
Before 2.2, the acl update logic is complicated. Client sent the grant/revoke
rpc call to AccessControl coprocessor directly. And only the RS which has acl
region will put a acl record to hbase:acl table. And the AccessControl override
postPut/postDelete method, too. It will update zk when postPut/postDelete found
this is a put/delete for acl region...And there is a TODO
"{color:#FF0000}global entry should be handled differently"{color}. The global
entry was handled as a table permission, too.
{code:java}
private static Pair<String, TablePermission> parsePermissionRecord(
byte[] entryName, Cell kv) {
// return X given a set of permissions encoded in the permissionRecord kv.
byte[] family = CellUtil.cloneFamily(kv);
if (!Bytes.equals(family, ACL_LIST_FAMILY)) {
return null;
}
byte[] key = CellUtil.cloneQualifier(kv);
byte[] value = CellUtil.cloneValue(kv);
if (LOG.isDebugEnabled()) {
LOG.debug("Read acl: kv ["+
Bytes.toStringBinary(key)+": "+
Bytes.toStringBinary(value)+"]");
}
// check for a column family appended to the key
// TODO: avoid the string conversion to make this more efficient
String username = Bytes.toString(key);
//Handle namespace entry
if(isNamespaceEntry(entryName)) {
return new Pair<>(username, new
TablePermission(Bytes.toString(fromNamespaceEntry(entryName)), value));
}
//Handle table and global entry
//TODO global entry should be handled differently
int idx = username.indexOf(ACL_KEY_DELIMITER);
byte[] permFamily = null;
byte[] permQualifier = null;
if (idx > 0 && idx < username.length()-1) {
String remainder = username.substring(idx+1);
username = username.substring(0, idx);
idx = remainder.indexOf(ACL_KEY_DELIMITER);
if (idx > 0 && idx < remainder.length()-1) {
permFamily = Bytes.toBytes(remainder.substring(0, idx));
permQualifier = Bytes.toBytes(remainder.substring(idx+1));
} else {
permFamily = Bytes.toBytes(remainder);
}
}
return new Pair<>(username, new TablePermission(TableName.valueOf(entryName),
permFamily, permQualifier, value));
}
{code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)