mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-27 17:10:22 -04:00
Add exclusive access files for security module (#123676)
This commit fills out missing entitlements for the security module. Specifically they are config files which require exclusive access.
This commit is contained in:
parent
f15cc9667b
commit
7e1195dc9a
19 changed files with 115 additions and 90 deletions
|
@ -23,8 +23,12 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static java.util.Comparator.comparing;
|
||||
|
@ -42,27 +46,47 @@ public final class FileAccessTree {
|
|||
/**
|
||||
* An intermediary structure to help globally validate exclusive paths, and then build exclusive paths for individual modules.
|
||||
*/
|
||||
record ExclusivePath(String componentName, String moduleName, String path) {
|
||||
record ExclusivePath(String componentName, Set<String> moduleNames, String path) {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[[" + componentName + "] [" + moduleName + "] [" + path + "]]";
|
||||
return "[[" + componentName + "] " + moduleNames + " [" + path + "]]";
|
||||
}
|
||||
}
|
||||
|
||||
static List<ExclusivePath> buildExclusivePathList(List<ExclusiveFileEntitlement> exclusiveFileEntitlements, PathLookup pathLookup) {
|
||||
List<ExclusivePath> exclusivePaths = new ArrayList<>();
|
||||
Map<String, ExclusivePath> exclusivePaths = new LinkedHashMap<>();
|
||||
for (ExclusiveFileEntitlement efe : exclusiveFileEntitlements) {
|
||||
for (FilesEntitlement.FileData fd : efe.filesEntitlement().filesData()) {
|
||||
if (fd.exclusive()) {
|
||||
List<Path> paths = fd.resolvePaths(pathLookup).toList();
|
||||
for (Path path : paths) {
|
||||
exclusivePaths.add(new ExclusivePath(efe.componentName(), efe.moduleName(), normalizePath(path)));
|
||||
String normalizedPath = normalizePath(path);
|
||||
var exclusivePath = exclusivePaths.computeIfAbsent(
|
||||
normalizedPath,
|
||||
k -> new ExclusivePath(efe.componentName(), new HashSet<>(), normalizedPath)
|
||||
);
|
||||
if (exclusivePath.componentName().equals(efe.componentName()) == false) {
|
||||
throw new IllegalArgumentException(
|
||||
"Path ["
|
||||
+ normalizedPath
|
||||
+ "] is already exclusive to ["
|
||||
+ exclusivePath.componentName()
|
||||
+ "]"
|
||||
+ exclusivePath.moduleNames
|
||||
+ ", cannot add exclusive access for ["
|
||||
+ efe.componentName()
|
||||
+ "]["
|
||||
+ efe.moduleName
|
||||
+ "]"
|
||||
);
|
||||
}
|
||||
exclusivePath.moduleNames.add(efe.moduleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return exclusivePaths.stream().sorted(comparing(ExclusivePath::path, PATH_ORDER)).distinct().toList();
|
||||
return exclusivePaths.values().stream().sorted(comparing(ExclusivePath::path, PATH_ORDER)).distinct().toList();
|
||||
}
|
||||
|
||||
static void validateExclusivePaths(List<ExclusivePath> exclusivePaths) {
|
||||
|
@ -97,7 +121,7 @@ public final class FileAccessTree {
|
|||
) {
|
||||
List<String> updatedExclusivePaths = new ArrayList<>();
|
||||
for (ExclusivePath exclusivePath : exclusivePaths) {
|
||||
if (exclusivePath.componentName().equals(componentName) == false || exclusivePath.moduleName().equals(moduleName) == false) {
|
||||
if (exclusivePath.componentName().equals(componentName) == false || exclusivePath.moduleNames().contains(moduleName) == false) {
|
||||
updatedExclusivePaths.add(exclusivePath.path());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,8 @@ public record FilesEntitlement(List<FileData> filesData) implements Entitlement
|
|||
public Stream<Path> resolveRelativePaths(PathLookup pathLookup) {
|
||||
Stream<String> result = pathLookup.settingResolver()
|
||||
.apply(setting)
|
||||
.filter(s -> s.toLowerCase(Locale.ROOT).startsWith("https://") == false);
|
||||
.filter(s -> s.toLowerCase(Locale.ROOT).startsWith("https://") == false)
|
||||
.distinct();
|
||||
return result.map(Path::of);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.elasticsearch.core.PathUtils.getDefaultFileSystem;
|
||||
import static org.elasticsearch.entitlement.runtime.policy.FileAccessTree.buildExclusivePathList;
|
||||
|
@ -386,7 +387,7 @@ public class FileAccessTreeTests extends ESTestCase {
|
|||
original.moduleName(),
|
||||
new FilesEntitlement(List.of(originalFileData.withPlatform(WINDOWS)))
|
||||
);
|
||||
var originalExclusivePath = new ExclusivePath("component1", "module1", normalizePath(path("/a/b")));
|
||||
var originalExclusivePath = new ExclusivePath("component1", Set.of("module1"), normalizePath(path("/a/b")));
|
||||
|
||||
// Some basic tests
|
||||
|
||||
|
@ -406,27 +407,14 @@ public class FileAccessTreeTests extends ESTestCase {
|
|||
var distinctEntitlements = List.of(original, differentComponent, differentModule, differentPath);
|
||||
var distinctPaths = List.of(
|
||||
originalExclusivePath,
|
||||
new ExclusivePath("component2", original.moduleName(), originalExclusivePath.path()),
|
||||
new ExclusivePath(original.componentName(), "module2", originalExclusivePath.path()),
|
||||
new ExclusivePath(original.componentName(), original.moduleName(), normalizePath(path("/c/d")))
|
||||
new ExclusivePath("component2", Set.of(original.moduleName()), originalExclusivePath.path()),
|
||||
new ExclusivePath(original.componentName(), Set.of("module2"), originalExclusivePath.path()),
|
||||
new ExclusivePath(original.componentName(), Set.of(original.moduleName()), normalizePath(path("/c/d")))
|
||||
);
|
||||
assertEquals(
|
||||
"Distinct elements should not be combined",
|
||||
distinctPaths,
|
||||
buildExclusivePathList(distinctEntitlements, TEST_PATH_LOOKUP)
|
||||
);
|
||||
|
||||
// Do merge things we should
|
||||
|
||||
List<ExclusiveFileEntitlement> interleavedEntitlements = new ArrayList<>();
|
||||
distinctEntitlements.forEach(e -> {
|
||||
interleavedEntitlements.add(e);
|
||||
interleavedEntitlements.add(original);
|
||||
});
|
||||
assertEquals(
|
||||
"Identical elements should be combined wherever they are in the list",
|
||||
distinctPaths,
|
||||
buildExclusivePathList(interleavedEntitlements, TEST_PATH_LOOKUP)
|
||||
var iae = expectThrows(IllegalArgumentException.class, () -> buildExclusivePathList(distinctEntitlements, TEST_PATH_LOOKUP));
|
||||
assertThat(
|
||||
iae.getMessage(),
|
||||
equalTo("Path [/a/b] is already exclusive to [component1][module1], cannot add exclusive access for [component2][module1]")
|
||||
);
|
||||
|
||||
var equivalentEntitlements = List.of(original, differentMode, differentPlatform);
|
||||
|
@ -486,7 +474,7 @@ public class FileAccessTreeTests extends ESTestCase {
|
|||
static List<ExclusivePath> exclusivePaths(String componentName, String moduleName, String... paths) {
|
||||
List<ExclusivePath> exclusivePaths = new ArrayList<>();
|
||||
for (String path : paths) {
|
||||
exclusivePaths.add(new ExclusivePath(componentName, moduleName, normalizePath(path(path))));
|
||||
exclusivePaths.add(new ExclusivePath(componentName, Set.of(moduleName), normalizePath(path(path))));
|
||||
}
|
||||
return exclusivePaths;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ import static java.util.Map.entry;
|
|||
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ALL_UNNAMED;
|
||||
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.SERVER_COMPONENT_NAME;
|
||||
import static org.hamcrest.Matchers.aMapWithSize;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.sameInstance;
|
||||
|
||||
|
@ -444,9 +445,9 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testFilesEntitlementsWithExclusive() {
|
||||
var baseTestPath = Path.of("/tmp").toAbsolutePath();
|
||||
var testPath1 = Path.of("/tmp/test").toAbsolutePath();
|
||||
var testPath2 = Path.of("/tmp/test/foo").toAbsolutePath();
|
||||
var baseTestPath = Path.of("/base").toAbsolutePath();
|
||||
var testPath1 = Path.of("/base/test").toAbsolutePath();
|
||||
var testPath2 = Path.of("/base/test/foo").toAbsolutePath();
|
||||
var iae = expectThrows(
|
||||
IllegalArgumentException.class,
|
||||
() -> new PolicyManager(
|
||||
|
@ -458,7 +459,7 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
"test",
|
||||
List.of(
|
||||
new Scope(
|
||||
"test",
|
||||
"test.module1",
|
||||
List.of(
|
||||
new FilesEntitlement(
|
||||
List.of(FilesEntitlement.FileData.ofPath(testPath1, FilesEntitlement.Mode.READ).withExclusive(true))
|
||||
|
@ -472,7 +473,7 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
"test",
|
||||
List.of(
|
||||
new Scope(
|
||||
"test",
|
||||
"test.module2",
|
||||
List.of(
|
||||
new FilesEntitlement(
|
||||
List.of(FilesEntitlement.FileData.ofPath(testPath1, FilesEntitlement.Mode.READ).withExclusive(true))
|
||||
|
@ -490,8 +491,13 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
Set.of()
|
||||
)
|
||||
);
|
||||
assertTrue(iae.getMessage().contains("duplicate/overlapping exclusive paths found in files entitlements:"));
|
||||
assertTrue(iae.getMessage().contains(Strings.format("[test] [%s]]", testPath1.toString())));
|
||||
assertThat(
|
||||
iae.getMessage(),
|
||||
equalTo(
|
||||
"Path [/base/test] is already exclusive to [plugin1][test.module1],"
|
||||
+ " cannot add exclusive access for [plugin2][test.module2]"
|
||||
)
|
||||
);
|
||||
|
||||
iae = expectThrows(
|
||||
IllegalArgumentException.class,
|
||||
|
|
|
@ -10,11 +10,9 @@
|
|||
package org.elasticsearch.common.ssl;
|
||||
|
||||
import org.elasticsearch.core.Tuple;
|
||||
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
|
@ -126,10 +124,8 @@ public final class PemKeyConfig implements SslKeyConfig {
|
|||
throw new SslConfigException("could not load ssl private key file [" + path + "]");
|
||||
}
|
||||
return privateKey;
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
throw SslFileUtil.accessControlFailure(KEY_FILE_TYPE, List.of(path), e, configBasePath);
|
||||
} catch (NotEntitledException e) {
|
||||
throw SslFileUtil.notEntitledFailure(KEY_FILE_TYPE, List.of(path), e, configBasePath);
|
||||
} catch (IOException e) {
|
||||
throw SslFileUtil.ioException(KEY_FILE_TYPE, List.of(path), e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
|
@ -140,7 +136,7 @@ public final class PemKeyConfig implements SslKeyConfig {
|
|||
private List<Certificate> getCertificates(Path path) {
|
||||
try {
|
||||
return PemUtils.readCertificates(Collections.singleton(path));
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
throw SslFileUtil.accessControlFailure(CERT_FILE_TYPE, List.of(path), e, configBasePath);
|
||||
} catch (IOException e) {
|
||||
throw SslFileUtil.ioException(CERT_FILE_TYPE, List.of(path), e);
|
||||
|
|
|
@ -9,12 +9,9 @@
|
|||
|
||||
package org.elasticsearch.common.ssl;
|
||||
|
||||
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
|
@ -99,10 +96,8 @@ public final class PemTrustConfig implements SslTrustConfig {
|
|||
private List<Certificate> readCertificates(List<Path> paths) {
|
||||
try {
|
||||
return PemUtils.readCertificates(paths);
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
throw SslFileUtil.accessControlFailure(CA_FILE_TYPE, paths, e, basePath);
|
||||
} catch (NotEntitledException e) {
|
||||
throw SslFileUtil.notEntitledFailure(CA_FILE_TYPE, paths, e, basePath);
|
||||
} catch (IOException e) {
|
||||
throw SslFileUtil.ioException(CA_FILE_TYPE, paths, e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
package org.elasticsearch.common.ssl;
|
||||
|
||||
import org.elasticsearch.core.CharArrays;
|
||||
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
@ -19,7 +18,6 @@ import java.math.BigInteger;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyFactory;
|
||||
|
@ -111,10 +109,8 @@ public final class PemUtils {
|
|||
throw new SslConfigException("could not load ssl private key file [" + path + "]");
|
||||
}
|
||||
return privateKey;
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
throw SslFileUtil.accessControlFailure("PEM private key", List.of(path), e, null);
|
||||
} catch (NotEntitledException e) {
|
||||
throw SslFileUtil.notEntitledFailure("PEM private key", List.of(path), e, null);
|
||||
} catch (IOException e) {
|
||||
throw SslFileUtil.ioException("PEM private key", List.of(path), e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
|
|
|
@ -16,7 +16,6 @@ import java.io.IOException;
|
|||
import java.nio.file.AccessDeniedException;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.util.List;
|
||||
|
@ -84,7 +83,7 @@ final class SslFileUtil {
|
|||
return innerAccessControlFailure(fileType, paths, cause, basePath);
|
||||
}
|
||||
|
||||
static SslConfigException accessControlFailure(String fileType, List<Path> paths, AccessControlException cause, Path basePath) {
|
||||
static SslConfigException accessControlFailure(String fileType, List<Path> paths, SecurityException cause, Path basePath) {
|
||||
return innerAccessControlFailure(fileType, paths, cause, basePath);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,9 @@ package org.elasticsearch.common.ssl;
|
|||
|
||||
import org.elasticsearch.core.Nullable;
|
||||
import org.elasticsearch.core.Tuple;
|
||||
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
|
@ -167,10 +165,8 @@ public class StoreKeyConfig implements SslKeyConfig {
|
|||
private KeyStore readKeyStore(Path path) {
|
||||
try {
|
||||
return KeyStoreUtil.readKeyStore(path, type, storePassword);
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
throw SslFileUtil.accessControlFailure("[" + type + "] keystore", List.of(path), e, configBasePath);
|
||||
} catch (NotEntitledException e) {
|
||||
throw SslFileUtil.notEntitledFailure("[" + type + "] keystore", List.of(path), e, configBasePath);
|
||||
} catch (IOException e) {
|
||||
throw SslFileUtil.ioException("[" + type + "] keystore", List.of(path), e);
|
||||
} catch (GeneralSecurityException e) {
|
||||
|
|
|
@ -9,11 +9,8 @@
|
|||
|
||||
package org.elasticsearch.common.ssl;
|
||||
|
||||
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
@ -95,10 +92,8 @@ public final class StoreTrustConfig implements SslTrustConfig {
|
|||
private KeyStore readKeyStore(Path path) {
|
||||
try {
|
||||
return KeyStoreUtil.readKeyStore(path, type, password);
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
throw SslFileUtil.accessControlFailure(fileTypeForException(), List.of(path), e, configBasePath);
|
||||
} catch (NotEntitledException e) {
|
||||
throw SslFileUtil.notEntitledFailure(fileTypeForException(), List.of(path), e, configBasePath);
|
||||
} catch (IOException e) {
|
||||
throw SslFileUtil.ioException(fileTypeForException(), List.of(path), e, getAdditionalErrorDetails());
|
||||
} catch (GeneralSecurityException e) {
|
||||
|
|
|
@ -64,7 +64,6 @@ import java.nio.charset.CharacterCodingException;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
@ -247,7 +246,7 @@ public class Analysis {
|
|||
} catch (IOException ioe) {
|
||||
String message = Strings.format("IOException while reading %s: %s", settingPath, path);
|
||||
throw new IllegalArgumentException(message, ioe);
|
||||
} catch (AccessControlException ace) {
|
||||
} catch (SecurityException ace) {
|
||||
throw new IllegalArgumentException(Strings.format("Access denied trying to read file %s: %s", settingPath, path), ace);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import java.nio.file.DirectoryStream;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
|
@ -256,7 +255,7 @@ public class FileWatcher extends AbstractResourceWatcher<FileChangesListener> {
|
|||
FileObserver child = new FileObserver(file);
|
||||
child.init(initial);
|
||||
return child;
|
||||
} catch (AccessControlException e) {
|
||||
} catch (SecurityException e) {
|
||||
// don't have permissions, use a placeholder
|
||||
logger.debug(() -> Strings.format("Don't have permissions to watch path [%s]", file), e);
|
||||
return new DeniedObserver(file);
|
||||
|
|
|
@ -45,7 +45,6 @@ import java.io.IOException;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
@ -259,7 +258,7 @@ public class StoreRecoveryTests extends ESTestCase {
|
|||
BasicFileAttributes sourceAttr = Files.readAttributes(path.resolve("foo.bar"), BasicFileAttributes.class);
|
||||
// we won't get here - no permission ;)
|
||||
return destAttr.fileKey() != null && destAttr.fileKey().equals(sourceAttr.fileKey());
|
||||
} catch (AccessControlException ex) {
|
||||
} catch (SecurityException ex) {
|
||||
return true; // if we run into that situation we know it's supported.
|
||||
} catch (UnsupportedOperationException ex) {
|
||||
return false;
|
||||
|
|
|
@ -10,6 +10,7 @@ package org.elasticsearch.xpack.security;
|
|||
import org.elasticsearch.watcher.FileWatcher;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -34,6 +35,15 @@ public class PrivilegedFileWatcher extends FileWatcher {
|
|||
super(path);
|
||||
}
|
||||
|
||||
public PrivilegedFileWatcher(Path path, boolean checkFileContents) {
|
||||
super(path, checkFileContents);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InputStream newInputStream(Path path) throws IOException {
|
||||
return Files.newInputStream(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean fileExists(Path path) {
|
||||
return doPrivileged((PrivilegedAction<Boolean>) () -> Files.exists(path));
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.elasticsearch.xpack.core.XPackPlugin;
|
|||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
||||
import org.elasticsearch.xpack.core.security.support.Validation;
|
||||
import org.elasticsearch.xpack.security.PrivilegedFileWatcher;
|
||||
import org.elasticsearch.xpack.security.support.SecurityFiles;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -57,7 +58,7 @@ public class FileUserRolesStore {
|
|||
file = resolveFile(config.env());
|
||||
userRoles = parseFileLenient(file, logger);
|
||||
listeners = new CopyOnWriteArrayList<>(Collections.singletonList(listener));
|
||||
FileWatcher watcher = new FileWatcher(file.getParent());
|
||||
FileWatcher watcher = new PrivilegedFileWatcher(file.getParent());
|
||||
watcher.addListener(new FileListener());
|
||||
try {
|
||||
watcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.xpack.core.security.action.service.TokenInfo;
|
|||
import org.elasticsearch.xpack.core.security.action.service.TokenInfo.TokenSource;
|
||||
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
|
||||
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
||||
import org.elasticsearch.xpack.security.PrivilegedFileWatcher;
|
||||
import org.elasticsearch.xpack.security.authc.service.ServiceAccount.ServiceAccountId;
|
||||
import org.elasticsearch.xpack.security.support.CacheInvalidatorRegistry;
|
||||
import org.elasticsearch.xpack.security.support.FileLineParser;
|
||||
|
@ -59,7 +60,7 @@ public class FileServiceAccountTokenStore extends CachingServiceAccountTokenStor
|
|||
super(env.settings(), threadPool);
|
||||
this.clusterService = clusterService;
|
||||
file = resolveFile(env);
|
||||
FileWatcher watcher = new FileWatcher(file.getParent());
|
||||
FileWatcher watcher = new PrivilegedFileWatcher(file.getParent());
|
||||
watcher.addListener(new FileReloadListener(file, this::tryReload));
|
||||
try {
|
||||
resourceWatcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.elasticsearch.xpack.core.security.authz.store.RoleRetrievalResult;
|
|||
import org.elasticsearch.xpack.core.security.authz.support.DLSRoleQueryValidator;
|
||||
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
||||
import org.elasticsearch.xpack.core.security.support.Validation;
|
||||
import org.elasticsearch.xpack.security.PrivilegedFileWatcher;
|
||||
import org.elasticsearch.xpack.security.authz.FileRoleValidator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -110,7 +111,7 @@ public class FileRolesStore implements BiConsumer<Set<String>, ActionListener<Ro
|
|||
}
|
||||
this.licenseState = licenseState;
|
||||
this.xContentRegistry = xContentRegistry;
|
||||
FileWatcher watcher = new FileWatcher(file.getParent());
|
||||
FileWatcher watcher = new PrivilegedFileWatcher(file.getParent());
|
||||
watcher.addListener(new FileListener());
|
||||
watcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||
permissions = parseFile(file, logger, settings, licenseState, xContentRegistry, roleValidator);
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
|
|||
import org.elasticsearch.xpack.core.security.authc.file.FileRealmSettings;
|
||||
import org.elasticsearch.xpack.core.security.authc.jwt.JwtRealmSettings;
|
||||
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountSettings;
|
||||
import org.elasticsearch.xpack.security.PrivilegedFileWatcher;
|
||||
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -59,7 +60,7 @@ public class FileOperatorUsersStore {
|
|||
public FileOperatorUsersStore(Environment env, ResourceWatcherService watcherService) {
|
||||
this.file = XPackPlugin.resolveConfigFile(env, "operator_users.yml");
|
||||
this.operatorUsersDescriptor = parseFile(this.file, logger);
|
||||
FileWatcher watcher = new FileWatcher(file.getParent(), true);
|
||||
FileWatcher watcher = new PrivilegedFileWatcher(file.getParent(), true);
|
||||
watcher.addListener(new FileOperatorUsersStore.FileListener());
|
||||
try {
|
||||
watcherService.add(watcher, ResourceWatcherService.Frequency.HIGH);
|
||||
|
|
|
@ -4,6 +4,35 @@ org.elasticsearch.security:
|
|||
- relative_path: ""
|
||||
relative_to: config
|
||||
mode: read
|
||||
- relative_path: users
|
||||
relative_to: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
- relative_path: x-pack/users
|
||||
relative_to: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
- path_setting: xpack.security.authc.realms.ldap.*.files.role_mapping
|
||||
basedir_if_relative: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
- path_setting: xpack.security.authc.realms.pki.*.files.role_mapping
|
||||
basedir_if_relative: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
- path_setting: xpack.security.authc.realms.kerberos.*.keytab.path
|
||||
basedir_if_relative: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
- path_setting: xpack.security.authc.realms.jwt.*.pkc_jwkset_path
|
||||
basedir_if_relative: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
- path_setting: xpack.security.authc.realms.saml.*.idp.metadata.path
|
||||
basedir_if_relative: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
|
||||
io.netty.transport:
|
||||
- manage_threads
|
||||
- inbound_network
|
||||
|
@ -25,18 +54,7 @@ org.opensaml.xmlsec.impl:
|
|||
- org.apache.xml.security.ignoreLineBreaks
|
||||
org.opensaml.saml.impl:
|
||||
- files:
|
||||
- relative_path: idp-docs-metadata.xml
|
||||
relative_to: config
|
||||
mode: read
|
||||
- relative_path: idp-metadata.xml
|
||||
relative_to: config
|
||||
mode: read
|
||||
- relative_path: saml-metadata.xml
|
||||
relative_to: config
|
||||
mode: read
|
||||
- relative_path: metadata.xml
|
||||
relative_to: config
|
||||
mode: read
|
||||
- relative_path: "saml/"
|
||||
relative_to: config
|
||||
- path_setting: xpack.security.authc.realms.saml.*.idp.metadata.path
|
||||
basedir_if_relative: config
|
||||
mode: read
|
||||
exclusive: true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue