|
|
@@ -19,6 +19,7 @@ import org.elasticsearch.entitlement.runtime.policy.entitlements.ExitVMEntitleme
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.InboundNetworkEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.LoadNativeLibrariesEntitlement;
|
|
|
+import org.elasticsearch.entitlement.runtime.policy.entitlements.ManageThreadsEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.OutboundNetworkEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.ReadStoreAttributesEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.SetHttpsConnectionPropertiesEntitlement;
|
|
|
@@ -102,9 +103,9 @@ public class PolicyManager {
|
|
|
|
|
|
final Map<Module, ModuleEntitlements> moduleEntitlementsMap = new ConcurrentHashMap<>();
|
|
|
|
|
|
- protected final Map<String, List<Entitlement>> serverEntitlements;
|
|
|
- protected final List<Entitlement> apmAgentEntitlements;
|
|
|
- protected final Map<String, Map<String, List<Entitlement>>> pluginsEntitlements;
|
|
|
+ private final Map<String, List<Entitlement>> serverEntitlements;
|
|
|
+ private final List<Entitlement> apmAgentEntitlements;
|
|
|
+ private final Map<String, Map<String, List<Entitlement>>> pluginsEntitlements;
|
|
|
private final Function<Class<?>, String> pluginResolver;
|
|
|
|
|
|
public static final String ALL_UNNAMED = "ALL-UNNAMED";
|
|
|
@@ -200,7 +201,7 @@ public class PolicyManager {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- throw new NotEntitledException(
|
|
|
+ notEntitled(
|
|
|
Strings.format(
|
|
|
"Not entitled: component [%s], module [%s], class [%s], operation [%s]",
|
|
|
getEntitlements(requestingClass).componentName(),
|
|
|
@@ -224,17 +225,19 @@ public class PolicyManager {
|
|
|
}
|
|
|
|
|
|
public void checkChangeJVMGlobalState(Class<?> callerClass) {
|
|
|
- neverEntitled(callerClass, () -> {
|
|
|
- // Look up the check$ method to compose an informative error message.
|
|
|
- // This way, we don't need to painstakingly describe every individual global-state change.
|
|
|
- Optional<String> checkMethodName = StackWalker.getInstance()
|
|
|
- .walk(
|
|
|
- frames -> frames.map(StackFrame::getMethodName)
|
|
|
- .dropWhile(not(methodName -> methodName.startsWith(InstrumentationService.CHECK_METHOD_PREFIX)))
|
|
|
- .findFirst()
|
|
|
- );
|
|
|
- return checkMethodName.map(this::operationDescription).orElse("change JVM global state");
|
|
|
- });
|
|
|
+ neverEntitled(callerClass, () -> walkStackForCheckMethodName().orElse("change JVM global state"));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Optional<String> walkStackForCheckMethodName() {
|
|
|
+ // Look up the check$ method to compose an informative error message.
|
|
|
+ // This way, we don't need to painstakingly describe every individual global-state change.
|
|
|
+ return StackWalker.getInstance()
|
|
|
+ .walk(
|
|
|
+ frames -> frames.map(StackFrame::getMethodName)
|
|
|
+ .dropWhile(not(methodName -> methodName.startsWith(InstrumentationService.CHECK_METHOD_PREFIX)))
|
|
|
+ .findFirst()
|
|
|
+ )
|
|
|
+ .map(this::operationDescription);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -257,11 +260,11 @@ public class PolicyManager {
|
|
|
|
|
|
ModuleEntitlements entitlements = getEntitlements(requestingClass);
|
|
|
if (entitlements.fileAccess().canRead(path) == false) {
|
|
|
- throw new NotEntitledException(
|
|
|
+ notEntitled(
|
|
|
Strings.format(
|
|
|
"Not entitled: component [%s], module [%s], class [%s], entitlement [file], operation [read], path [%s]",
|
|
|
entitlements.componentName(),
|
|
|
- requestingClass.getModule(),
|
|
|
+ requestingClass.getModule().getName(),
|
|
|
requestingClass,
|
|
|
path
|
|
|
)
|
|
|
@@ -282,11 +285,11 @@ public class PolicyManager {
|
|
|
|
|
|
ModuleEntitlements entitlements = getEntitlements(requestingClass);
|
|
|
if (entitlements.fileAccess().canWrite(path) == false) {
|
|
|
- throw new NotEntitledException(
|
|
|
+ notEntitled(
|
|
|
Strings.format(
|
|
|
"Not entitled: component [%s], module [%s], class [%s], entitlement [file], operation [write], path [%s]",
|
|
|
entitlements.componentName(),
|
|
|
- requestingClass.getModule(),
|
|
|
+ requestingClass.getModule().getName(),
|
|
|
requestingClass,
|
|
|
path
|
|
|
)
|
|
|
@@ -340,7 +343,7 @@ public class PolicyManager {
|
|
|
Class<?> requestingClass
|
|
|
) {
|
|
|
if (classEntitlements.hasEntitlement(entitlementClass) == false) {
|
|
|
- throw new NotEntitledException(
|
|
|
+ notEntitled(
|
|
|
Strings.format(
|
|
|
"Not entitled: component [%s], module [%s], class [%s], entitlement [%s]",
|
|
|
classEntitlements.componentName(),
|
|
|
@@ -380,7 +383,7 @@ public class PolicyManager {
|
|
|
);
|
|
|
return;
|
|
|
}
|
|
|
- throw new NotEntitledException(
|
|
|
+ notEntitled(
|
|
|
Strings.format(
|
|
|
"Not entitled: component [%s], module [%s], class [%s], entitlement [write_system_properties], property [%s]",
|
|
|
entitlements.componentName(),
|
|
|
@@ -391,6 +394,14 @@ public class PolicyManager {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ private static void notEntitled(String message) {
|
|
|
+ throw new NotEntitledException(message);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void checkManageThreadsEntitlement(Class<?> callerClass) {
|
|
|
+ checkEntitlementPresent(callerClass, ManageThreadsEntitlement.class);
|
|
|
+ }
|
|
|
+
|
|
|
private void checkEntitlementPresent(Class<?> callerClass, Class<? extends Entitlement> entitlementClass) {
|
|
|
var requestingClass = requestingClass(callerClass);
|
|
|
if (isTriviallyAllowed(requestingClass)) {
|