HADOOP-17304. KMS ACL: Allow DeleteKey Operation to Invalidate Cache. Contributed by Xiaoyu.
Reviewed-by: Ayush Saxena <ayushsaxena@apache.org> Signed-off-by: He Xiaoqiao <hexiaoqiao@apache.org>
This commit is contained in:
parent
a308a1ec22
commit
ddc0ee27fa
|
@ -52,10 +52,12 @@ import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.apache.hadoop.crypto.key.kms.server.KMSACLs.INVALIDATE_CACHE_TYPES;
|
||||||
import static org.apache.hadoop.util.KMSUtil.checkNotEmpty;
|
import static org.apache.hadoop.util.KMSUtil.checkNotEmpty;
|
||||||
import static org.apache.hadoop.util.KMSUtil.checkNotNull;
|
import static org.apache.hadoop.util.KMSUtil.checkNotNull;
|
||||||
|
|
||||||
|
@ -95,6 +97,12 @@ public class KMS {
|
||||||
KMSWebApp.getACLs().assertAccess(aclType, ugi, operation, key);
|
KMSWebApp.getACLs().assertAccess(aclType, ugi, operation, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertAccess(EnumSet<KMSACLs.Type> aclTypes,
|
||||||
|
UserGroupInformation ugi, KMSOp operation, String key)
|
||||||
|
throws AccessControlException {
|
||||||
|
KMSWebApp.getACLs().assertAccess(aclTypes, ugi, operation, key);
|
||||||
|
}
|
||||||
|
|
||||||
private static KeyProvider.KeyVersion removeKeyMaterial(
|
private static KeyProvider.KeyVersion removeKeyMaterial(
|
||||||
KeyProvider.KeyVersion keyVersion) {
|
KeyProvider.KeyVersion keyVersion) {
|
||||||
return new KMSClientProvider.KMSKeyVersion(keyVersion.getName(),
|
return new KMSClientProvider.KMSKeyVersion(keyVersion.getName(),
|
||||||
|
@ -270,7 +278,7 @@ public class KMS {
|
||||||
KMSWebApp.getAdminCallsMeter().mark();
|
KMSWebApp.getAdminCallsMeter().mark();
|
||||||
checkNotEmpty(name, "name");
|
checkNotEmpty(name, "name");
|
||||||
UserGroupInformation user = HttpUserGroupInformation.get();
|
UserGroupInformation user = HttpUserGroupInformation.get();
|
||||||
assertAccess(KMSACLs.Type.ROLLOVER, user, KMSOp.INVALIDATE_CACHE, name);
|
assertAccess(INVALIDATE_CACHE_TYPES, user, KMSOp.INVALIDATE_CACHE, name);
|
||||||
LOG.debug("Invalidating cache with key name {}.", name);
|
LOG.debug("Invalidating cache with key name {}.", name);
|
||||||
|
|
||||||
user.doAs(new PrivilegedExceptionAction<Void>() {
|
user.doAs(new PrivilegedExceptionAction<Void>() {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.hadoop.security.authorize.AuthorizationException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
@ -69,6 +70,10 @@ public class KMSACLs implements Runnable, KeyACLs {
|
||||||
|
|
||||||
public static final int RELOADER_SLEEP_MILLIS = 1000;
|
public static final int RELOADER_SLEEP_MILLIS = 1000;
|
||||||
|
|
||||||
|
// Allow both ROLLOVER and DELETE to invalidate cache.
|
||||||
|
public static final EnumSet<KMSACLs.Type> INVALIDATE_CACHE_TYPES =
|
||||||
|
EnumSet.of(KMSACLs.Type.ROLLOVER, KMSACLs.Type.DELETE);
|
||||||
|
|
||||||
private volatile Map<Type, AccessControlList> acls;
|
private volatile Map<Type, AccessControlList> acls;
|
||||||
private volatile Map<Type, AccessControlList> blacklistedAcls;
|
private volatile Map<Type, AccessControlList> blacklistedAcls;
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -273,6 +278,27 @@ public class KMSACLs implements Runnable, KeyACLs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void assertAccess(EnumSet<Type> aclTypes,
|
||||||
|
UserGroupInformation ugi, KMSOp operation, String key)
|
||||||
|
throws AccessControlException {
|
||||||
|
boolean accessAllowed = false;
|
||||||
|
for (KMSACLs.Type type : aclTypes) {
|
||||||
|
if (KMSWebApp.getACLs().hasAccess(type, ugi)){
|
||||||
|
accessAllowed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!accessAllowed) {
|
||||||
|
KMSWebApp.getUnauthorizedCallsMeter().mark();
|
||||||
|
KMSWebApp.getKMSAudit().unauthorized(ugi, operation, key);
|
||||||
|
throw new AuthorizationException(String.format(
|
||||||
|
(key != null) ? UNAUTHORIZED_MSG_WITH_KEY
|
||||||
|
: UNAUTHORIZED_MSG_WITHOUT_KEY,
|
||||||
|
ugi.getShortUserName(), operation, key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasAccessToKey(String keyName, UserGroupInformation ugi,
|
public boolean hasAccessToKey(String keyName, UserGroupInformation ugi,
|
||||||
KeyOpType opType) {
|
KeyOpType opType) {
|
||||||
|
|
Loading…
Reference in New Issue