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)

Reply via email to