Copilot commented on code in PR #6450:
URL: https://github.com/apache/hive/pull/6450#discussion_r3134787792
##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java:
##########
@@ -649,8 +711,17 @@ List<String> listTableNamesByFilter(String catName, String
dbName, String filter
* @return list of partition names.
* @throws MetaException there was an error accessing the RDBMS
*/
- List<String> listPartitionNames(String catName, String db_name,
- String tbl_name, short max_parts) throws MetaException;
+ default List<String> listPartitionNames(String catName, String db_name,
+ String tbl_name, short max_parts) throws MetaException {
+ try {
+ return unwrap(TableStore.class).listPartitionNames(new
TableName(catName, db_name, tbl_name),
+ MetaStoreUtils.getDefaultCatalog(getConf()), null, null, max_parts);
+ } catch (NoSuchObjectException nse) {
Review Comment:
`listPartitionNames(catName, db_name, tbl_name, max_parts)` passes
`MetaStoreUtils.getDefaultCatalog(getConf())` as the *default partition name*
argument to `TableStore.listPartitionNames`. That value is a catalog name, not
the default partition name, and will break partition-name pruning (e.g., it
will treat the catalog string as the default partition value). Pass `null` (so
TableStoreImpl uses MetastoreConf.DEFAULTPARTITIONNAME) or the actual default
partition name instead.
##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/RawStore.java:
##########
@@ -1420,8 +1610,10 @@ List<HiveObjectPrivilege> listPartitionGrantsAll(
* @param columnName column name
* @return all privileges on this column in this table
*/
- List<HiveObjectPrivilege> listTableColumnGrantsAll(
- String catName, String dbName, String tableName, String columnName);
+ default List<HiveObjectPrivilege> listTableColumnGrantsAll(
+ String catName, String dbName, String tableName, String columnName) {
+ return unwrap(PrivilegeStore.class).listPartitionGrantsAll(new
TableName(catName, dbName, tableName), columnName);
Review Comment:
`listTableColumnGrantsAll` delegates to
`PrivilegeStore.listPartitionGrantsAll(...)` with `columnName` passed as the
partition name. This is the wrong underlying API and will return incorrect
results (or throw) for table-column grants. Delegate to
`PrivilegeStore.listTableColumnGrantsAll(tableName, columnName)` instead.
```suggestion
return unwrap(PrivilegeStore.class)
.listTableColumnGrantsAll(new TableName(catName, dbName, tableName),
columnName);
```
##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metastore/PersistenceManagerProxy.java:
##########
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.metastore;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+import java.util.Objects;
+
+import org.datanucleus.ExecutionContext;
+
+public class PersistenceManagerProxy implements InvocationHandler {
+ private final PersistenceManager target;
+ private final MethodHandle getExecutionContext;
+ private final List<Query> openedQueries;
+
+ private PersistenceManagerProxy(PersistenceManager pm, List<Query>
trackOpenedQueries) {
+ this.target = Objects.requireNonNull(pm);
+ this.openedQueries = Objects.requireNonNull(trackOpenedQueries);
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ try {
+ java.lang.invoke.MethodType type =
java.lang.invoke.MethodType.methodType(ExecutionContext.class);
+ this.getExecutionContext = lookup.findVirtual(target.getClass(),
"getExecutionContext", type);
+ } catch (Exception e) {
+ throw new RuntimeException("Method getExecutionContext not found", e);
+ }
+ }
+
+ public static PersistenceManager getProxy(PersistenceManager pm, List<Query>
trackOpenedQueries) {
+ return (PersistenceManager)
Proxy.newProxyInstance(pm.getClass().getClassLoader(),
+ new Class[] {PersistenceManager.class,
ExecutionContextReference.class},
+ new PersistenceManagerProxy(pm, trackOpenedQueries));
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
+ // Redirect if the interface method "getExecutionContext" is called
+ if (method.getName().equals("getExecutionContext")) {
+ return getExecutionContext.bindTo(target).invokeWithArguments(args);
Review Comment:
For no-arg methods on a dynamic proxy, `args` is `null`. Calling
`invokeWithArguments(args)` will throw NPE when
`ExecutionContextReference.getExecutionContext()` is invoked (e.g., from
MetastoreDirectSqlUtils). Handle the `null` case by calling
`invokeWithArguments()` with no arguments (or an empty array).
```suggestion
MethodHandle boundGetExecutionContext =
getExecutionContext.bindTo(target);
return args == null ? boundGetExecutionContext.invokeWithArguments()
: boundGetExecutionContext.invokeWithArguments(args);
```
##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metastore/iface/PrivilegeStore.java:
##########
@@ -0,0 +1,328 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.metastore.iface;
+
+import java.util.List;
+
+import org.apache.hadoop.hive.common.TableName;
+import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege;
+import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
+import org.apache.hadoop.hive.metastore.api.InvalidObjectException;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.apache.hadoop.hive.metastore.api.PrincipalPrivilegeSet;
+import org.apache.hadoop.hive.metastore.api.PrincipalType;
+import org.apache.hadoop.hive.metastore.api.PrivilegeBag;
+import org.apache.hadoop.hive.metastore.api.Role;
+import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant;
+import org.apache.hadoop.hive.metastore.metastore.MetaDescriptor;
+import org.apache.hadoop.hive.metastore.metastore.impl.PrivilegeStoreImpl;
+import org.apache.hadoop.hive.metastore.model.MDBPrivilege;
+import org.apache.hadoop.hive.metastore.model.MDCPrivilege;
+
+@MetaDescriptor(alias = "privilege", defaultImpl = PrivilegeStoreImpl.class)
+public interface PrivilegeStore {
+ boolean addRole(String rowName, String ownerName)
Review Comment:
Parameter name `rowName` in `addRole(String rowName, ...)` looks like a typo
(should be `roleName`). While it doesn't affect bytecode, it leaks into
generated docs/IDE hints and is inconsistent with `removeRole(String roleName)`
and other role APIs.
```suggestion
boolean addRole(String roleName, String ownerName)
```
##########
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/metastore/impl/PrivilegeStoreImpl.java:
##########
@@ -0,0 +1,2372 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hive.metastore.metastore.impl;
+
+import com.google.common.base.Preconditions;
+
+import javax.jdo.Query;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.common.TableName;
+import org.apache.hadoop.hive.metastore.RawStore;
+import org.apache.hadoop.hive.metastore.Warehouse;
+import org.apache.hadoop.hive.metastore.api.HiveObjectPrivilege;
+import org.apache.hadoop.hive.metastore.api.HiveObjectRef;
+import org.apache.hadoop.hive.metastore.api.HiveObjectType;
+import org.apache.hadoop.hive.metastore.api.InvalidObjectException;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.apache.hadoop.hive.metastore.api.PrincipalPrivilegeSet;
+import org.apache.hadoop.hive.metastore.api.PrincipalType;
+import org.apache.hadoop.hive.metastore.api.PrivilegeBag;
+import org.apache.hadoop.hive.metastore.api.PrivilegeGrantInfo;
+import org.apache.hadoop.hive.metastore.api.Role;
+import org.apache.hadoop.hive.metastore.api.RolePrincipalGrant;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.metastore.RawStoreAware;
+import org.apache.hadoop.hive.metastore.metastore.iface.TableStore;
+import org.apache.hadoop.hive.metastore.model.MDBPrivilege;
+import org.apache.hadoop.hive.metastore.model.MDCPrivilege;
+import org.apache.hadoop.hive.metastore.model.MDataConnector;
+import org.apache.hadoop.hive.metastore.model.MDatabase;
+import org.apache.hadoop.hive.metastore.model.MGlobalPrivilege;
+import org.apache.hadoop.hive.metastore.model.MPartition;
+import org.apache.hadoop.hive.metastore.model.MPartitionColumnPrivilege;
+import org.apache.hadoop.hive.metastore.model.MPartitionPrivilege;
+import org.apache.hadoop.hive.metastore.model.MRole;
+import org.apache.hadoop.hive.metastore.model.MRoleMap;
+import org.apache.hadoop.hive.metastore.model.MTable;
+import org.apache.hadoop.hive.metastore.model.MTableColumnPrivilege;
+import org.apache.hadoop.hive.metastore.model.MTablePrivilege;
+import org.apache.hadoop.hive.metastore.metastore.GetHelper;
+import org.apache.hadoop.hive.metastore.metastore.GetListHelper;
+import org.apache.hadoop.hive.metastore.metastore.iface.PrivilegeStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.hadoop.hive.metastore.ObjectStore.convert;
+import static
org.apache.hadoop.hive.metastore.utils.MetaStoreUtils.getDefaultCatalog;
+import static
org.apache.hadoop.hive.metastore.utils.StringUtils.normalizeIdentifier;
+
+public class PrivilegeStoreImpl extends RawStoreAware implements
PrivilegeStore {
+ private static final Logger LOG =
LoggerFactory.getLogger(PrivilegeStoreImpl.class);
+ private Configuration conf;
+
+ @Override
+ public boolean addRole(String roleName, String ownerName)
+ throws InvalidObjectException, MetaException, NoSuchObjectException {
+ MRole nameCheck = this.getMRole(roleName);
+ if (nameCheck != null) {
+ throw new InvalidObjectException("Role " + roleName + " already
exists.");
+ }
+ int now = (int) (System.currentTimeMillis() / 1000);
+ MRole mRole = new MRole(roleName, now, ownerName);
+ pm.makePersistent(mRole);
+ return true;
+ }
+
+ @Override
+ public boolean grantRole(Role role, String userName,
+ PrincipalType principalType, String grantor, PrincipalType grantorType,
+ boolean grantOption) throws MetaException,
NoSuchObjectException,InvalidObjectException {
+ MRoleMap roleMap = null;
+ try {
+ roleMap = this.getMSecurityUserRoleMap(userName, principalType, role
+ .getRoleName());
+ } catch (Exception e) {
+ }
+ if (roleMap != null) {
+ throw new InvalidObjectException("Principal " + userName
+ + " already has the role " + role.getRoleName());
+ }
+ if (principalType == PrincipalType.ROLE) {
+ validateRole(userName);
+ }
+ MRole mRole = getMRole(role.getRoleName());
+ long now = System.currentTimeMillis()/1000;
+ MRoleMap roleMember = new MRoleMap(userName, principalType.toString(),
+ mRole, (int) now, grantor, grantorType.toString(), grantOption);
+ pm.makePersistent(roleMember);
+ return true;
+ }
+
+ /**
+ * Verify that role with given name exists, if not throw exception
+ */
+ private void validateRole(String roleName) throws NoSuchObjectException {
+ // if grantee is a role, check if it exists
+ MRole granteeRole = getMRole(roleName);
+ if (granteeRole == null) {
+ throw new NoSuchObjectException("Role " + roleName + " does not exist");
+ }
+ }
+
+ @Override
+ public boolean revokeRole(Role role, String userName, PrincipalType
principalType,
+ boolean grantOption) throws MetaException, NoSuchObjectException {
+ MRoleMap roleMember = getMSecurityUserRoleMap(userName, principalType,
+ role.getRoleName());
+ if (grantOption) {
+ // Revoke with grant option - only remove the grant option but keep the
role.
+ if (roleMember.getGrantOption()) {
+ roleMember.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with role " + role.getRoleName());
+ }
+ } else {
+ // No grant option in revoke, remove the whole role.
+ pm.deletePersistent(roleMember);
+ }
+ return true;
+ }
+
+ private MRoleMap getMSecurityUserRoleMap(String userName, PrincipalType
principalType,
+ String roleName) {
+ MRoleMap mRoleMember = null;
+ Query query =
+ pm.newQuery(MRoleMap.class,
+ "principalName == t1 && principalType == t2 && role.roleName ==
t3");
+ query.declareParameters("java.lang.String t1, java.lang.String t2,
java.lang.String t3");
+ query.setUnique(true);
+ mRoleMember = (MRoleMap) query.executeWithArray(userName,
principalType.toString(), roleName);
+ pm.retrieve(mRoleMember);;
+ return mRoleMember;
+ }
+
+ @Override
+ public boolean removeRole(String roleName) throws MetaException,
+ NoSuchObjectException {
+ try {
+ MRole mRol = getMRole(roleName);
+ pm.retrieve(mRol);
+ if (mRol != null) {
+ // first remove all the membership, the membership that this role has
+ // been granted
+ List<MRoleMap> roleMap = listMRoleMembers(mRol.getRoleName());
+ if (CollectionUtils.isNotEmpty(roleMap)) {
+ pm.deletePersistentAll(roleMap);
+ }
+ List<MRoleMap> roleMember = listMSecurityPrincipalMembershipRole(mRol
+ .getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(roleMember)) {
+ pm.deletePersistentAll(roleMember);
+ }
+
+ // then remove all the grants
+ List<MGlobalPrivilege> userGrants = listPrincipalMGlobalGrants(
+ mRol.getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(userGrants)) {
+ pm.deletePersistentAll(userGrants);
+ }
+
+ List<MDBPrivilege> dbGrants = listPrincipalAllDBGrant(mRol
+ .getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(dbGrants)) {
+ pm.deletePersistentAll(dbGrants);
+ }
+
+ List<MDCPrivilege> dcGrants = listPrincipalAllDCGrant(mRol
+ .getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(dcGrants)) {
+ pm.deletePersistentAll(dcGrants);
+ }
+
+ List<MTablePrivilege> tabPartGrants = listPrincipalAllTableGrants(
+ mRol.getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(tabPartGrants)) {
+ pm.deletePersistentAll(tabPartGrants);
+ }
+
+ List<MPartitionPrivilege> partGrants = listPrincipalAllPartitionGrants(
+ mRol.getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(partGrants)) {
+ pm.deletePersistentAll(partGrants);
+ }
+
+ List<MTableColumnPrivilege> tblColumnGrants =
listPrincipalAllTableColumnGrants(
+ mRol.getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(tblColumnGrants)) {
+ pm.deletePersistentAll(tblColumnGrants);
+ }
+
+ List<MPartitionColumnPrivilege> partColumnGrants =
listPrincipalAllPartitionColumnGrants(
+ mRol.getRoleName(), PrincipalType.ROLE);
+ if (CollectionUtils.isNotEmpty(partColumnGrants)) {
+ pm.deletePersistentAll(partColumnGrants);
+ }
+
+ // finally remove the role
+ pm.deletePersistent(mRol);
+ }
+ return true;
+ } catch (Exception e) {
+ throw new MetaException(e.getMessage());
+ }
+ }
+
+ /**
+ * Get all the roles in the role hierarchy that this user and groupNames
belongs to
+ */
+ private Set<String> listAllRolesInHierarchy(String userName,
+ List<String> groupNames) {
+ List<MRoleMap> ret = new ArrayList<>();
+ if(userName != null) {
+ ret.addAll(listMRoles(userName, PrincipalType.USER));
+ }
+ if (groupNames != null) {
+ for (String groupName: groupNames) {
+ ret.addAll(listMRoles(groupName, PrincipalType.GROUP));
+ }
+ }
+ // get names of these roles and its ancestors
+ Set<String> roleNames = new HashSet<>();
+ getAllRoleAncestors(roleNames, ret);
+ return roleNames;
+ }
+
+ /**
+ * Add role names of parentRoles and its parents to processedRoles
+ */
+ private void getAllRoleAncestors(Set<String> processedRoleNames,
List<MRoleMap> parentRoles) {
+ for (MRoleMap parentRole : parentRoles) {
+ String parentRoleName = parentRole.getRole().getRoleName();
+ if (!processedRoleNames.contains(parentRoleName)) {
+ // unprocessed role: get its parents, add it to processed, and call
this
+ // function recursively
+ List<MRoleMap> nextParentRoles = listMRoles(parentRoleName,
PrincipalType.ROLE);
+ processedRoleNames.add(parentRoleName);
+ getAllRoleAncestors(processedRoleNames, nextParentRoles);
+ }
+ }
+ }
+
+ public List<MRoleMap> listMRoles(String principalName,
+ PrincipalType principalType) {
+ Query query = pm.newQuery(MRoleMap.class, "principalName == t1 &&
principalType == t2");
+ query.declareParameters("java.lang.String t1, java.lang.String t2");
+ query.setUnique(false);
+ List<MRoleMap> mRoles =
+ (List<MRoleMap>) query.executeWithArray(principalName,
principalType.toString());
+ pm.retrieveAll(mRoles);;
+ List<MRoleMap> mRoleMember = new ArrayList<>(mRoles);
+
+ if (principalType == PrincipalType.USER) {
+ // All users belong to public role implicitly, add that role
+ // TODO MS-SPLIT Change this back to HMSHandler.PUBLIC once
HiveMetaStore has moved to
+ // stand-alone metastore.
+ //MRole publicRole = new MRole(HMSHandler.PUBLIC, 0, HMSHandler.PUBLIC);
+ MRole publicRole = new MRole("public", 0, "public");
+ mRoleMember.add(new MRoleMap(principalName, principalType.toString(),
publicRole, 0, null,
+ null, false));
+ }
+
+ return mRoleMember;
+ }
+
+ @Override
+ public List<Role> listRoles(String principalName, PrincipalType
principalType) {
+ List<Role> result = new ArrayList<>();
+ List<MRoleMap> roleMaps = listMRoles(principalName, principalType);
+ if (roleMaps != null) {
+ for (MRoleMap roleMap : roleMaps) {
+ MRole mrole = roleMap.getRole();
+ Role role = new Role(mrole.getRoleName(), mrole.getCreateTime(),
mrole.getOwnerName());
+ result.add(role);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public List<RolePrincipalGrant> listRolesWithGrants(String principalName,
+ PrincipalType principalType) {
+ List<RolePrincipalGrant> result = new ArrayList<>();
+ List<MRoleMap> roleMaps = listMRoles(principalName, principalType);
+ if (roleMaps != null) {
+ for (MRoleMap roleMap : roleMaps) {
+ RolePrincipalGrant rolePrinGrant = new RolePrincipalGrant(
+ roleMap.getRole().getRoleName(),
+ roleMap.getPrincipalName(),
+ PrincipalType.valueOf(roleMap.getPrincipalType()),
+ roleMap.getGrantOption(),
+ roleMap.getAddTime(),
+ roleMap.getGrantor(),
+ // no grantor type for public role, hence the null check
+ roleMap.getGrantorType() == null ? null
+ : PrincipalType.valueOf(roleMap.getGrantorType())
+ );
+ result.add(rolePrinGrant);
+ }
+ }
+ return result;
+ }
+
+ private List<MRoleMap> listMSecurityPrincipalMembershipRole(final String
roleName,
+ final PrincipalType principalType) throws Exception {
+ LOG.debug("Executing listMSecurityPrincipalMembershipRole");
+ Query query = pm.newQuery(MRoleMap.class, "principalName == t1 &&
principalType == t2");
+ query.declareParameters("java.lang.String t1, java.lang.String t2");
+ final List<MRoleMap> mRoleMemebership = (List<MRoleMap>)
query.execute(roleName, principalType.toString());
+
+ LOG.debug("Retrieving all objects for
listMSecurityPrincipalMembershipRole");
+ pm.retrieveAll(mRoleMemebership);
+ LOG.debug("Done retrieving all objects for
listMSecurityPrincipalMembershipRole: {}", mRoleMemebership);
+
+ return Collections.unmodifiableList(new ArrayList<>(mRoleMemebership));
+ }
+
+ @Override
+ public Role getRole(String roleName) throws NoSuchObjectException {
+ MRole mRole = this.getMRole(roleName);
+ if (mRole == null) {
+ throw new NoSuchObjectException(roleName + " role can not be found.");
+ }
+ return new Role(mRole.getRoleName(), mRole.getCreateTime(), mRole
+ .getOwnerName());
+ }
+
+ private MRole getMRole(String roleName) {
+ MRole mrole = null;
+ Query query = pm.newQuery(MRole.class, "roleName == t1");
+ query.declareParameters("java.lang.String t1");
+ query.setUnique(true);
+ mrole = (MRole) query.execute(roleName);
+ pm.retrieve(mrole);
+ return mrole;
+ }
+
+ @Override
+ public List<String> listRoleNames() {
+ LOG.debug("Executing listAllRoleNames");
+ Query query = pm.newQuery("select roleName from
org.apache.hadoop.hive.metastore.model.MRole");
+ query.setResult("roleName");
+ Collection names = (Collection) query.execute();
+ List<String> roleNames = new ArrayList<>();
+ for (Iterator i = names.iterator(); i.hasNext();) {
+ roleNames.add((String) i.next());
+ }
+ return roleNames;
+ }
+
+ @Override
+ public PrincipalPrivilegeSet getUserPrivilegeSet(String userName,
+ List<String> groupNames) throws InvalidObjectException, MetaException {
+ PrincipalPrivilegeSet ret = new PrincipalPrivilegeSet();
+ if (userName != null) {
+ List<MGlobalPrivilege> user = this.listPrincipalMGlobalGrants(userName,
PrincipalType.USER);
+ if(CollectionUtils.isNotEmpty(user)) {
+ Map<String, List<PrivilegeGrantInfo>> userPriv = new HashMap<>();
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(user.size());
+ for (int i = 0; i < user.size(); i++) {
+ MGlobalPrivilege item = user.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(), getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ userPriv.put(userName, grantInfos);
+ ret.setUserPrivileges(userPriv);
+ }
+ }
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ Map<String, List<PrivilegeGrantInfo>> groupPriv = new HashMap<>();
+ for(String groupName: groupNames) {
+ List<MGlobalPrivilege> group =
+ this.listPrincipalMGlobalGrants(groupName, PrincipalType.GROUP);
+ if(CollectionUtils.isNotEmpty(group)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(group.size());
+ for (int i = 0; i < group.size(); i++) {
+ MGlobalPrivilege item = group.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(),
getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ groupPriv.put(groupName, grantInfos);
+ }
+ }
+ ret.setGroupPrivileges(groupPriv);
+ }
+ return ret;
+ }
+
+ private List<PrivilegeGrantInfo> getDBPrivilege(String catName, String
dbName,
+ String principalName, PrincipalType principalType) {
+ catName = normalizeIdentifier(catName);
+ dbName = normalizeIdentifier(dbName);
+
+ if (principalName != null) {
+ List<MDBPrivilege> userNameDbPriv = this.listPrincipalMDBGrants(
+ principalName, principalType, catName, dbName);
+ if (CollectionUtils.isNotEmpty(userNameDbPriv)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(
+ userNameDbPriv.size());
+ for (int i = 0; i < userNameDbPriv.size(); i++) {
+ MDBPrivilege item = userNameDbPriv.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(), getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ return grantInfos;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+
+ @Override
+ public PrincipalPrivilegeSet getDBPrivilegeSet(String catName, String dbName,
+ String userName, List<String> groupNames) throws InvalidObjectException,
+ MetaException {
+ catName = normalizeIdentifier(catName);
+ dbName = normalizeIdentifier(dbName);
+
+ PrincipalPrivilegeSet ret = new PrincipalPrivilegeSet();
+ if (userName != null) {
+ Map<String, List<PrivilegeGrantInfo>> dbUserPriv = new HashMap<>();
+ dbUserPriv.put(userName, getDBPrivilege(catName, dbName, userName,
+ PrincipalType.USER));
+ ret.setUserPrivileges(dbUserPriv);
+ }
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ Map<String, List<PrivilegeGrantInfo>> dbGroupPriv = new HashMap<>();
+ for (String groupName : groupNames) {
+ dbGroupPriv.put(groupName, getDBPrivilege(catName, dbName, groupName,
+ PrincipalType.GROUP));
+ }
+ ret.setGroupPrivileges(dbGroupPriv);
+ }
+ Set<String> roleNames = listAllRolesInHierarchy(userName, groupNames);
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ Map<String, List<PrivilegeGrantInfo>> dbRolePriv = new HashMap<>();
+ for (String roleName : roleNames) {
+ dbRolePriv
+ .put(roleName, getDBPrivilege(catName, dbName, roleName,
PrincipalType.ROLE));
+ }
+ ret.setRolePrivileges(dbRolePriv);
+ }
+ return ret;
+ }
+
+ private List<PrivilegeGrantInfo> getConnectorPrivilege(String catName,
String connectorName,
+ String principalName, PrincipalType principalType) {
+
+ // normalize string name
+ catName = normalizeIdentifier(catName);
+ connectorName = normalizeIdentifier(connectorName);
+
+ if (principalName != null) {
+ // get all data connector granted privilege
+ List<MDCPrivilege> userNameDcPriv = this.listPrincipalMDCGrants(
+ principalName, principalType, catName, connectorName);
+
+ // populate and return grantInfos
+ if (CollectionUtils.isNotEmpty(userNameDcPriv)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(
+ userNameDcPriv.size());
+ for (int i = 0; i < userNameDcPriv.size(); i++) {
+ MDCPrivilege item = userNameDcPriv.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(), getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ return grantInfos;
+ }
+ }
+
+ // return empty list if no principalName
+ return Collections.emptyList();
+ }
+
+ @Override
+ public PrincipalPrivilegeSet getConnectorPrivilegeSet (String catName,
String connectorName,
+ String userName, List<String> groupNames) throws InvalidObjectException,
+ MetaException {
+ catName = normalizeIdentifier(catName);
+ connectorName = normalizeIdentifier(connectorName);
+
+ PrincipalPrivilegeSet ret = new PrincipalPrivilegeSet();
+ // get user privileges
+ if (userName != null) {
+ Map<String, List<PrivilegeGrantInfo>> connectorUserPriv = new
HashMap<>();
+ connectorUserPriv.put(userName, getConnectorPrivilege(catName,
connectorName, userName,
+ PrincipalType.USER));
+ ret.setUserPrivileges(connectorUserPriv);
+ }
+
+ // get group privileges
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ Map<String, List<PrivilegeGrantInfo>> dbGroupPriv = new HashMap<>();
+ for (String groupName : groupNames) {
+ dbGroupPriv.put(groupName, getConnectorPrivilege(catName,
connectorName, groupName,
+ PrincipalType.GROUP));
+ }
+ ret.setGroupPrivileges(dbGroupPriv);
+ }
+
+ // get role privileges
+ Set<String> roleNames = listAllRolesInHierarchy(userName, groupNames);
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ Map<String, List<PrivilegeGrantInfo>> dbRolePriv = new HashMap<>();
+ for (String roleName : roleNames) {
+ dbRolePriv.put(roleName, getConnectorPrivilege(catName, connectorName,
roleName,
+ PrincipalType.ROLE));
+ }
+ ret.setRolePrivileges(dbRolePriv);
+ }
+ return ret;
+ }
+
+ @Override
+ public PrincipalPrivilegeSet getPartitionPrivilegeSet(TableName table,
String partition, String userName,
+ List<String> groupNames) throws InvalidObjectException, MetaException {
+ PrincipalPrivilegeSet ret = new PrincipalPrivilegeSet();
+ String tableName = normalizeIdentifier(table.getTable());
+ String dbName = normalizeIdentifier(table.getDb());
+ String catName = normalizeIdentifier(table.getCat());
+ if (userName != null) {
+ Map<String, List<PrivilegeGrantInfo>> partUserPriv = new HashMap<>();
+ partUserPriv.put(userName, getPartitionPrivilege(catName, dbName,
+ tableName, partition, userName, PrincipalType.USER));
+ ret.setUserPrivileges(partUserPriv);
+ }
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ Map<String, List<PrivilegeGrantInfo>> partGroupPriv = new HashMap<>();
+ for (String groupName : groupNames) {
+ partGroupPriv.put(groupName, getPartitionPrivilege(catName, dbName,
tableName,
+ partition, groupName, PrincipalType.GROUP));
+ }
+ ret.setGroupPrivileges(partGroupPriv);
+ }
+ Set<String> roleNames = listAllRolesInHierarchy(userName, groupNames);
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ Map<String, List<PrivilegeGrantInfo>> partRolePriv = new HashMap<>();
+ for (String roleName : roleNames) {
+ partRolePriv.put(roleName, getPartitionPrivilege(catName, dbName,
tableName,
+ partition, roleName, PrincipalType.ROLE));
+ }
+ ret.setRolePrivileges(partRolePriv);
+ }
+ return ret;
+ }
+
+ @Override
+ public PrincipalPrivilegeSet getTablePrivilegeSet(TableName table, String
userName, List<String> groupNames)
+ throws InvalidObjectException, MetaException {
+ boolean commited = false;
+ PrincipalPrivilegeSet ret = new PrincipalPrivilegeSet();
+ String tableName = normalizeIdentifier(table.getTable());
+ String catName = normalizeIdentifier(table.getCat());
+ String dbName = normalizeIdentifier(table.getDb());
+
+ if (userName != null) {
+ Map<String, List<PrivilegeGrantInfo>> tableUserPriv = new HashMap<>();
+ tableUserPriv.put(userName, getTablePrivilege(catName, dbName,
+ tableName, userName, PrincipalType.USER));
+ ret.setUserPrivileges(tableUserPriv);
+ }
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ Map<String, List<PrivilegeGrantInfo>> tableGroupPriv = new HashMap<>();
+ for (String groupName : groupNames) {
+ tableGroupPriv.put(groupName, getTablePrivilege(catName, dbName,
tableName,
+ groupName, PrincipalType.GROUP));
+ }
+ ret.setGroupPrivileges(tableGroupPriv);
+ }
+ Set<String> roleNames = listAllRolesInHierarchy(userName, groupNames);
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ Map<String, List<PrivilegeGrantInfo>> tableRolePriv = new HashMap<>();
+ for (String roleName : roleNames) {
+ tableRolePriv.put(roleName, getTablePrivilege(catName, dbName,
tableName,
+ roleName, PrincipalType.ROLE));
+ }
+ ret.setRolePrivileges(tableRolePriv);
+ }
+ return ret;
+ }
+
+ @Override
+ public PrincipalPrivilegeSet getColumnPrivilegeSet(TableName table, String
partitionName, String columnName,
+ String userName, List<String> groupNames) throws InvalidObjectException,
+ MetaException {
+ String tableName = normalizeIdentifier(table.getTable());
+ String dbName = normalizeIdentifier(table.getDb());
+ columnName = normalizeIdentifier(columnName);
+ String catName = normalizeIdentifier(table.getCat());
+
+ PrincipalPrivilegeSet ret = new PrincipalPrivilegeSet();
+ if (userName != null) {
+ Map<String, List<PrivilegeGrantInfo>> columnUserPriv = new HashMap<>();
+ columnUserPriv.put(userName, getColumnPrivilege(catName, dbName,
tableName,
+ columnName, partitionName, userName, PrincipalType.USER));
+ ret.setUserPrivileges(columnUserPriv);
+ }
+ if (CollectionUtils.isNotEmpty(groupNames)) {
+ Map<String, List<PrivilegeGrantInfo>> columnGroupPriv = new HashMap<>();
+ for (String groupName : groupNames) {
+ columnGroupPriv.put(groupName, getColumnPrivilege(catName, dbName,
tableName,
+ columnName, partitionName, groupName, PrincipalType.GROUP));
+ }
+ ret.setGroupPrivileges(columnGroupPriv);
+ }
+ Set<String> roleNames = listAllRolesInHierarchy(userName, groupNames);
+ if (CollectionUtils.isNotEmpty(roleNames)) {
+ Map<String, List<PrivilegeGrantInfo>> columnRolePriv = new HashMap<>();
+ for (String roleName : roleNames) {
+ columnRolePriv.put(roleName, getColumnPrivilege(catName, dbName,
tableName,
+ columnName, partitionName, roleName, PrincipalType.ROLE));
+ }
+ ret.setRolePrivileges(columnRolePriv);
+ }
+ return ret;
+ }
+
+ private List<PrivilegeGrantInfo> getPartitionPrivilege(String catName,
String dbName,
+ String tableName, String partName, String principalName,
+ PrincipalType principalType) {
+
+ tableName = normalizeIdentifier(tableName);
+ dbName = normalizeIdentifier(dbName);
+ catName = normalizeIdentifier(catName);
+
+ if (principalName != null) {
+ List<MPartitionPrivilege> userNameTabPartPriv = this
+ .listPrincipalMPartitionGrants(principalName, principalType,
+ catName, dbName, tableName, partName);
+ if (CollectionUtils.isNotEmpty(userNameTabPartPriv)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(
+ userNameTabPartPriv.size());
+ for (int i = 0; i < userNameTabPartPriv.size(); i++) {
+ MPartitionPrivilege item = userNameTabPartPriv.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(),
+ getPrincipalTypeFromStr(item.getGrantorType()),
item.getGrantOption()));
+
+ }
+ return grantInfos;
+ }
+ }
+ return new ArrayList<>(0);
+ }
+
+ public static PrincipalType getPrincipalTypeFromStr(String str) {
+ return str == null ? null : PrincipalType.valueOf(str);
+ }
+
+ private List<PrivilegeGrantInfo> getTablePrivilege(String catName, String
dbName,
+ String tableName, String principalName, PrincipalType principalType) {
+ tableName = normalizeIdentifier(tableName);
+ dbName = normalizeIdentifier(dbName);
+ catName = normalizeIdentifier(catName);
+
+ if (principalName != null) {
+ List<MTablePrivilege> userNameTabPartPriv = this
+ .listAllMTableGrants(principalName, principalType,
+ catName, dbName, tableName);
+ if (CollectionUtils.isNotEmpty(userNameTabPartPriv)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(
+ userNameTabPartPriv.size());
+ for (int i = 0; i < userNameTabPartPriv.size(); i++) {
+ MTablePrivilege item = userNameTabPartPriv.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(), getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ return grantInfos;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ private List<PrivilegeGrantInfo> getColumnPrivilege(String catName, String
dbName,
+ String tableName, String columnName, String partitionName,
+ String principalName, PrincipalType principalType) {
+
+ tableName = normalizeIdentifier(tableName);
+ dbName = normalizeIdentifier(dbName);
+ columnName = normalizeIdentifier(columnName);
+ catName = normalizeIdentifier(catName);
+
+ if (partitionName == null) {
+ List<MTableColumnPrivilege> userNameColumnPriv = this
+ .listPrincipalMTableColumnGrants(principalName, principalType,
+ catName, dbName, tableName, columnName);
+ if (CollectionUtils.isNotEmpty(userNameColumnPriv)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(
+ userNameColumnPriv.size());
+ for (int i = 0; i < userNameColumnPriv.size(); i++) {
+ MTableColumnPrivilege item = userNameColumnPriv.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(), getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ return grantInfos;
+ }
+ } else {
+ List<MPartitionColumnPrivilege> userNameColumnPriv = this
+ .listPrincipalMPartitionColumnGrants(principalName,
+ principalType, catName, dbName, tableName, partitionName,
columnName);
+ if (CollectionUtils.isNotEmpty(userNameColumnPriv)) {
+ List<PrivilegeGrantInfo> grantInfos = new ArrayList<>(
+ userNameColumnPriv.size());
+ for (int i = 0; i < userNameColumnPriv.size(); i++) {
+ MPartitionColumnPrivilege item = userNameColumnPriv.get(i);
+ grantInfos.add(new PrivilegeGrantInfo(item.getPrivilege(), item
+ .getCreateTime(), item.getGrantor(), getPrincipalTypeFromStr(item
+ .getGrantorType()), item.getGrantOption()));
+ }
+ return grantInfos;
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean grantPrivileges(PrivilegeBag privileges) throws
InvalidObjectException,
+ MetaException, NoSuchObjectException {
+ int now = (int) (System.currentTimeMillis() / 1000);
+ List<Object> persistentObjs = new ArrayList<>();
+
+ List<HiveObjectPrivilege> privilegeList = privileges.getPrivileges();
+
+ if (CollectionUtils.isNotEmpty(privilegeList)) {
+ Iterator<HiveObjectPrivilege> privIter = privilegeList.iterator();
+ Set<String> privSet = new HashSet<>();
+ while (privIter.hasNext()) {
+ HiveObjectPrivilege privDef = privIter.next();
+ HiveObjectRef hiveObject = privDef.getHiveObject();
+ String privilegeStr = privDef.getGrantInfo().getPrivilege();
+ String[] privs = privilegeStr.split(",");
+ String userName = privDef.getPrincipalName();
+ String authorizer = privDef.getAuthorizer();
+ PrincipalType principalType = privDef.getPrincipalType();
+ String grantor = privDef.getGrantInfo().getGrantor();
+ String grantorType =
privDef.getGrantInfo().getGrantorType().toString();
+ boolean grantOption = privDef.getGrantInfo().isGrantOption();
+ privSet.clear();
+
+ if(principalType == PrincipalType.ROLE){
+ validateRole(userName);
+ }
+
+ String catName = hiveObject.isSetCatName() ? hiveObject.getCatName() :
+ getDefaultCatalog(conf);
+ if (hiveObject.getObjectType() == HiveObjectType.GLOBAL) {
+ List<MGlobalPrivilege> globalPrivs = this
+ .listPrincipalMGlobalGrants(userName, principalType, authorizer);
+ for (MGlobalPrivilege priv : globalPrivs) {
+ if (priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted by " + grantor);
+ }
+ MGlobalPrivilege mGlobalPrivs = new MGlobalPrivilege(userName,
+ principalType.toString(), privilege, now, grantor,
grantorType, grantOption,
+ authorizer);
+ persistentObjs.add(mGlobalPrivs);
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.DATABASE) {
+ MDatabase dbObj = baseStore.ensureGetMDatabase(catName,
hiveObject.getDbName());
+ List<MDBPrivilege> dbPrivs = this.listPrincipalMDBGrants(
+ userName, principalType, catName, hiveObject.getDbName(),
authorizer);
+ for (MDBPrivilege priv : dbPrivs) {
+ if (priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted on database "
+ + hiveObject.getDbName() + " by " + grantor);
+ }
+ MDBPrivilege mDb = new MDBPrivilege(userName, principalType
+ .toString(), dbObj, privilege, now, grantor, grantorType,
grantOption, authorizer);
+ persistentObjs.add(mDb);
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.DATACONNECTOR)
{
+ MDataConnector dcObj =
convert(baseStore.getDataConnector(hiveObject.getObjectName()));
+ List<MDCPrivilege> dcPrivs = this.listPrincipalMDCGrants(userName,
principalType,
+ hiveObject.getObjectName(), authorizer);
+ for (MDCPrivilege priv : dcPrivs) {
+ if (priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted on data connector "
+ + hiveObject.getDbName() + " by " + grantor);
+ }
+ MDCPrivilege mDc = new MDCPrivilege(userName, principalType
+ .toString(), dcObj, privilege, now, grantor, grantorType,
grantOption, authorizer);
+ persistentObjs.add(mDc);
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.TABLE) {
+ MTable tblObj = baseStore.ensureGetMTable(catName,
hiveObject.getDbName(), hiveObject
+ .getObjectName());
+ if (tblObj != null) {
+ List<MTablePrivilege> tablePrivs = this
+ .listAllMTableGrants(userName, principalType,
+ catName, hiveObject.getDbName(),
hiveObject.getObjectName(), authorizer);
+ for (MTablePrivilege priv : tablePrivs) {
+ if (priv.getGrantor() != null
+ && priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted on table ["
+ + hiveObject.getDbName() + ","
+ + hiveObject.getObjectName() + "] by " + grantor);
+ }
+ MTablePrivilege mTab = new MTablePrivilege(
+ userName, principalType.toString(), tblObj,
+ privilege, now, grantor, grantorType, grantOption,
authorizer);
+ persistentObjs.add(mTab);
+ }
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.PARTITION) {
+ MPartition partObj = baseStore.ensureGetMPartition(new
TableName(catName, hiveObject.getDbName(),
+ hiveObject.getObjectName()), hiveObject.getPartValues());
+ String partName = null;
+ if (partObj != null) {
+ partName = partObj.getPartitionName();
+ List<MPartitionPrivilege> partPrivs = this
+ .listPrincipalMPartitionGrants(userName,
+ principalType, catName, hiveObject.getDbName(), hiveObject
+ .getObjectName(), partObj.getPartitionName(),
authorizer);
+ for (MPartitionPrivilege priv : partPrivs) {
+ if (priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted on partition ["
+ + hiveObject.getDbName() + ","
+ + hiveObject.getObjectName() + ","
+ + partName + "] by " + grantor);
+ }
+ MPartitionPrivilege mTab = new MPartitionPrivilege(userName,
+ principalType.toString(), partObj, privilege, now, grantor,
+ grantorType, grantOption, authorizer);
+ persistentObjs.add(mTab);
+ }
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.COLUMN) {
+ MTable tblObj = baseStore.ensureGetMTable(catName,
hiveObject.getDbName(), hiveObject
+ .getObjectName());
+ if (tblObj != null) {
+ if (hiveObject.getPartValues() != null) {
+ MPartition partObj = null;
+ List<MPartitionColumnPrivilege> colPrivs = null;
+ partObj = baseStore.ensureGetMPartition(new TableName(catName,
hiveObject.getDbName(), hiveObject
+ .getObjectName()), hiveObject.getPartValues());
+ if (partObj == null) {
+ continue;
+ }
+ colPrivs = this.listPrincipalMPartitionColumnGrants(
+ userName, principalType, catName, hiveObject.getDbName(),
hiveObject
+ .getObjectName(), partObj.getPartitionName(),
+ hiveObject.getColumnName(), authorizer);
+
+ for (MPartitionColumnPrivilege priv : colPrivs) {
+ if (priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted on column "
+ + hiveObject.getColumnName() + " ["
+ + hiveObject.getDbName() + ","
+ + hiveObject.getObjectName() + ","
+ + partObj.getPartitionName() + "] by " + grantor);
+ }
+ MPartitionColumnPrivilege mCol = new
MPartitionColumnPrivilege(userName,
+ principalType.toString(), partObj, hiveObject
+ .getColumnName(), privilege, now, grantor, grantorType,
+ grantOption, authorizer);
+ persistentObjs.add(mCol);
+ }
+
+ } else {
+ List<MTableColumnPrivilege> colPrivs = null;
+ colPrivs = this.listPrincipalMTableColumnGrants(
+ userName, principalType, catName, hiveObject.getDbName(),
hiveObject
+ .getObjectName(), hiveObject.getColumnName(),
authorizer);
+
+ for (MTableColumnPrivilege priv : colPrivs) {
+ if (priv.getGrantor().equalsIgnoreCase(grantor)) {
+ privSet.add(priv.getPrivilege());
+ }
+ }
+ for (String privilege : privs) {
+ if (privSet.contains(privilege)) {
+ throw new InvalidObjectException(privilege
+ + " is already granted on column "
+ + hiveObject.getColumnName() + " ["
+ + hiveObject.getDbName() + ","
+ + hiveObject.getObjectName() + "] by " + grantor);
+ }
+ MTableColumnPrivilege mCol = new
MTableColumnPrivilege(userName,
+ principalType.toString(), tblObj, hiveObject
+ .getColumnName(), privilege, now, grantor, grantorType,
+ grantOption, authorizer);
+ persistentObjs.add(mCol);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (CollectionUtils.isNotEmpty(persistentObjs)) {
+ pm.makePersistentAll(persistentObjs);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean revokePrivileges(PrivilegeBag privileges, boolean grantOption)
+ throws InvalidObjectException, MetaException, NoSuchObjectException {
+ List<Object> persistentObjs = new ArrayList<>();
+
+ List<HiveObjectPrivilege> privilegeList = privileges.getPrivileges();
+
+ if (CollectionUtils.isNotEmpty(privilegeList)) {
+ Iterator<HiveObjectPrivilege> privIter = privilegeList.iterator();
+
+ while (privIter.hasNext()) {
+ HiveObjectPrivilege privDef = privIter.next();
+ HiveObjectRef hiveObject = privDef.getHiveObject();
+ String privilegeStr = privDef.getGrantInfo().getPrivilege();
+ if (privilegeStr == null || privilegeStr.trim().equals("")) {
+ continue;
+ }
+ String[] privs = privilegeStr.split(",");
+ String userName = privDef.getPrincipalName();
+ PrincipalType principalType = privDef.getPrincipalType();
+
+ String catName = hiveObject.isSetCatName() ? hiveObject.getCatName() :
+ getDefaultCatalog(conf);
+ if (hiveObject.getObjectType() == HiveObjectType.GLOBAL) {
+ List<MGlobalPrivilege> mSecUser = this.listPrincipalMGlobalGrants(
+ userName, principalType);
+ boolean found = false;
+ for (String privilege : privs) {
+ for (MGlobalPrivilege userGrant : mSecUser) {
+ String userGrantPrivs = userGrant.getPrivilege();
+ if (privilege.equals(userGrantPrivs)) {
+ found = true;
+ if (grantOption) {
+ if (userGrant.getGrantOption()) {
+ userGrant.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(userGrant);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException(
+ "No user grant found for privileges " + privilege);
+ }
+ }
+
+ } else if (hiveObject.getObjectType() == HiveObjectType.DATABASE) {
+ String db = hiveObject.getDbName();
+ boolean found = false;
+ List<MDBPrivilege> dbGrants = this.listPrincipalMDBGrants(
+ userName, principalType, catName, db);
+ for (String privilege : privs) {
+ for (MDBPrivilege dbGrant : dbGrants) {
+ String dbGrantPriv = dbGrant.getPrivilege();
+ if (privilege.equals(dbGrantPriv)) {
+ found = true;
+ if (grantOption) {
+ if (dbGrant.getGrantOption()) {
+ dbGrant.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(dbGrant);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException(
+ "No database grant found for privileges " + privilege
+ + " on database " + db);
+ }
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.DATACONNECTOR)
{
+ String dc = hiveObject.getObjectName();
+ boolean found = false;
+ List<MDCPrivilege> dcGrants = this.listPrincipalMDCGrants(
+ userName, principalType, catName, dc);
+ for (String privilege : privs) {
+ for (MDCPrivilege dcGrant : dcGrants) {
+ String dcGrantPriv = dcGrant.getPrivilege();
+ if (privilege.equals(dcGrantPriv)) {
+ found = true;
+ if (grantOption) {
+ if (dcGrant.getGrantOption()) {
+ dcGrant.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(dcGrant);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException(
+ "No dataconnector grant found for privileges " + privilege
+ + " on data connector " + dc);
+ }
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.TABLE) {
+ boolean found = false;
+ List<MTablePrivilege> tableGrants = this
+ .listAllMTableGrants(userName, principalType,
+ catName, hiveObject.getDbName(), hiveObject.getObjectName());
+ for (String privilege : privs) {
+ for (MTablePrivilege tabGrant : tableGrants) {
+ String tableGrantPriv = tabGrant.getPrivilege();
+ if (privilege.equalsIgnoreCase(tableGrantPriv)) {
+ found = true;
+ if (grantOption) {
+ if (tabGrant.getGrantOption()) {
+ tabGrant.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(tabGrant);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException("No grant (" + privilege
+ + ") found " + " on table " + hiveObject.getObjectName()
+ + ", database is " + hiveObject.getDbName());
+ }
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.PARTITION) {
+ boolean found = false;
+ Table tabObj = baseStore.unwrap(TableStore.class).getTable(
+ new TableName(catName, hiveObject.getDbName(),
hiveObject.getObjectName()), null, -1);
+ String partName = null;
+ if (hiveObject.getPartValues() != null) {
+ partName = Warehouse.makePartName(tabObj.getPartitionKeys(),
hiveObject.getPartValues());
+ }
+ List<MPartitionPrivilege> partitionGrants = this
+ .listPrincipalMPartitionGrants(userName, principalType,
+ catName, hiveObject.getDbName(), hiveObject.getObjectName(),
partName);
+ for (String privilege : privs) {
+ for (MPartitionPrivilege partGrant : partitionGrants) {
+ String partPriv = partGrant.getPrivilege();
+ if (partPriv.equalsIgnoreCase(privilege)) {
+ found = true;
+ if (grantOption) {
+ if (partGrant.getGrantOption()) {
+ partGrant.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(partGrant);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException("No grant (" + privilege
+ + ") found " + " on table " + tabObj.getTableName()
+ + ", partition is " + partName + ", database is " +
tabObj.getDbName());
+ }
+ }
+ } else if (hiveObject.getObjectType() == HiveObjectType.COLUMN) {
+ Table tabObj = baseStore.unwrap(TableStore.class).getTable(
+ new TableName(catName, hiveObject.getDbName(),
hiveObject.getObjectName()), null, -1);
+ String partName = null;
+ if (hiveObject.getPartValues() != null) {
+ partName = Warehouse.makePartName(tabObj.getPartitionKeys(),
hiveObject.getPartValues());
+ }
+
+ if (partName != null) {
+ List<MPartitionColumnPrivilege> mSecCol =
listPrincipalMPartitionColumnGrants(
+ userName, principalType, catName, hiveObject.getDbName(),
hiveObject
+ .getObjectName(), partName, hiveObject.getColumnName());
+ boolean found = false;
+ for (String privilege : privs) {
+ for (MPartitionColumnPrivilege col : mSecCol) {
+ String colPriv = col.getPrivilege();
+ if (colPriv.equalsIgnoreCase(privilege)) {
+ found = true;
+ if (grantOption) {
+ if (col.getGrantOption()) {
+ col.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(col);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException("No grant (" + privilege
+ + ") found " + " on table " + tabObj.getTableName()
+ + ", partition is " + partName + ", column name = "
+ + hiveObject.getColumnName() + ", database is "
+ + tabObj.getDbName());
+ }
+ }
+ } else {
+ List<MTableColumnPrivilege> mSecCol =
listPrincipalMTableColumnGrants(
+ userName, principalType, catName, hiveObject.getDbName(),
hiveObject
+ .getObjectName(), hiveObject.getColumnName());
+ boolean found = false;
+ for (String privilege : privs) {
+ for (MTableColumnPrivilege col : mSecCol) {
+ String colPriv = col.getPrivilege();
+ if (colPriv.equalsIgnoreCase(privilege)) {
+ found = true;
+ if (grantOption) {
+ if (col.getGrantOption()) {
+ col.setGrantOption(false);
+ } else {
+ throw new MetaException("User " + userName
+ + " does not have grant option with privilege " +
privilege);
+ }
+ }
+ persistentObjs.add(col);
+ break;
+ }
+ }
+ if (!found) {
+ throw new InvalidObjectException("No grant (" + privilege
+ + ") found " + " on table " + tabObj.getTableName()
+ + ", column name = "
+ + hiveObject.getColumnName() + ", database is "
+ + tabObj.getDbName());
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ if (CollectionUtils.isNotEmpty(persistentObjs)) {
+ if (grantOption) {
+ // If grant option specified, only update the privilege, don't remove
it.
+ // Grant option has already been removed from the privileges in the
section above
+ } else {
+ pm.deletePersistentAll(persistentObjs);
+ }
+ }
+ return true;
+ }
+
+ class PrivilegeWithoutCreateTimeComparator implements
Comparator<HiveObjectPrivilege> {
+ @Override
+ public int compare(HiveObjectPrivilege o1, HiveObjectPrivilege o2) {
+ int createTime1 = o1.getGrantInfo().getCreateTime();
+ int createTime2 = o2.getGrantInfo().getCreateTime();
+ o1.getGrantInfo().setCreateTime(0);
+ o2.getGrantInfo().setCreateTime(0);
+ int result = o1.compareTo(o2);
+ o1.getGrantInfo().setCreateTime(createTime1);
+ o2.getGrantInfo().setCreateTime(createTime2);
+ return result;
+ }
+ }
+
+ @Override
+ public boolean refreshPrivileges(HiveObjectRef objToRefresh, String
authorizer, PrivilegeBag grantPrivileges)
+ throws InvalidObjectException, MetaException, NoSuchObjectException {
+ Set<HiveObjectPrivilege> revokePrivilegeSet
+ = new TreeSet<>(new PrivilegeWithoutCreateTimeComparator());
+ Set<HiveObjectPrivilege> grantPrivilegeSet
+ = new TreeSet<>(new PrivilegeWithoutCreateTimeComparator());
+
+ List<HiveObjectPrivilege> grants = null;
+ String catName = objToRefresh.isSetCatName() ? objToRefresh.getCatName() :
+ getDefaultCatalog(conf);
+ switch (objToRefresh.getObjectType()) {
+ case DATABASE:
+ try {
+ grants = this.listDBGrantsAll(catName, objToRefresh.getDbName(),
authorizer);
+ } catch (Exception e) {
+ throw new MetaException(e.getMessage());
+ }
+ break;
+ case DATACONNECTOR:
+ try {
+ grants = this.listDCGrantsAll(objToRefresh.getObjectName(),
authorizer);
+ } catch (Exception e) {
+ throw new MetaException(e.getMessage());
+ }
+ break;
+ case TABLE:
+ grants = listTableGrantsAll(new TableName(catName,
objToRefresh.getDbName(), objToRefresh.getObjectName()), authorizer);
+ break;
+ case COLUMN:
+ Preconditions.checkArgument(objToRefresh.getColumnName()==null,
"columnName must be null");
+ grants = getTableAllColumnGrants(catName, objToRefresh.getDbName(),
+ objToRefresh.getObjectName(), authorizer);
+ break;
Review Comment:
In the `COLUMN` case, this asserts `objToRefresh.getColumnName() == null`,
but `HiveObjectRef.columnName` is a required thrift field and callers (e.g.,
PrivilegeHandler) pass an actual column name. This will cause
`refresh_privileges` to fail for column objects. Also, the code fetches *all*
column grants for the table; it should load only the relevant
column/partition-column grants based on `objToRefresh` (columnName + optional
partValues).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]