Details
-
Bug
-
Status: Resolved
-
Blocker
-
Resolution: Fixed
-
2.2.0
-
None
-
None
Description
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.
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)
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 "global entry should be handled differently". The global entry was handled as a table permission, too.
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)); }
Attachments
Issue Links
- is broken by
-
HBASE-21255 [acl] Refactor TablePermission into three classes (Global, Namespace, Table)
- Resolved
- links to