1010package org .elasticsearch .entitlement .runtime .policy ;
1111
1212import org .elasticsearch .entitlement .runtime .policy .entitlements .FilesEntitlement ;
13+ import org .elasticsearch .entitlement .runtime .policy .entitlements .FilesEntitlement .Mode ;
14+ import org .elasticsearch .logging .LogManager ;
15+ import org .elasticsearch .logging .Logger ;
1316
17+ import java .io .IOException ;
18+ import java .io .UncheckedIOException ;
19+ import java .nio .file .Files ;
1420import java .nio .file .Path ;
21+ import java .nio .file .Paths ;
1522import java .util .ArrayList ;
1623import java .util .Arrays ;
1724import java .util .Comparator ;
1825import java .util .List ;
1926import java .util .Objects ;
27+ import java .util .function .BiConsumer ;
2028
2129import static org .elasticsearch .core .PathUtils .getDefaultFileSystem ;
2230
2331public final class FileAccessTree {
2432
33+ private static final Logger logger = LogManager .getLogger (FileAccessTree .class );
2534 private static final String FILE_SEPARATOR = getDefaultFileSystem ().getSeparator ();
2635
2736 private final String [] readPaths ;
@@ -30,6 +39,27 @@ public final class FileAccessTree {
3039 private FileAccessTree (FilesEntitlement filesEntitlement , PathLookup pathLookup ) {
3140 List <String > readPaths = new ArrayList <>();
3241 List <String > writePaths = new ArrayList <>();
42+ BiConsumer <Path , Mode > addPath = (path , mode ) -> {
43+ var normalized = normalizePath (path );
44+ if (mode == Mode .READ_WRITE ) {
45+ writePaths .add (normalized );
46+ }
47+ readPaths .add (normalized );
48+ };
49+ BiConsumer <Path , Mode > addPathAndMaybeLink = (path , mode ) -> {
50+ addPath .accept (path , mode );
51+ // also try to follow symlinks. Lucene does this and writes to the target path.
52+ if (Files .exists (path )) {
53+ try {
54+ Path realPath = path .toRealPath ();
55+ if (realPath .equals (path ) == false ) {
56+ addPath .accept (realPath , mode );
57+ }
58+ } catch (IOException e ) {
59+ throw new UncheckedIOException (e );
60+ }
61+ }
62+ };
3363 for (FilesEntitlement .FileData fileData : filesEntitlement .filesData ()) {
3464 var platform = fileData .platform ();
3565 if (platform != null && platform .isCurrent () == false ) {
@@ -38,18 +68,20 @@ private FileAccessTree(FilesEntitlement filesEntitlement, PathLookup pathLookup)
3868 var mode = fileData .mode ();
3969 var paths = fileData .resolvePaths (pathLookup );
4070 paths .forEach (path -> {
41- var normalized = normalizePath ( path );
42- if ( mode == FilesEntitlement . Mode . READ_WRITE ) {
43- writePaths . add ( normalized ) ;
71+ if ( path == null ) {
72+ // TODO: null paths shouldn't be allowed, but they can occur due to repo paths
73+ return ;
4474 }
45- readPaths . add ( normalized );
75+ addPathAndMaybeLink . accept ( path , mode );
4676 });
4777 }
4878
49- // everything has access to the temp dir
50- String tempDir = normalizePath (pathLookup .tempDir ());
51- readPaths .add (tempDir );
52- writePaths .add (tempDir );
79+ // everything has access to the temp dir and the jdk
80+ addPathAndMaybeLink .accept (pathLookup .tempDir (), Mode .READ_WRITE );
81+
82+ // TODO: watcher uses javax.activation which looks for known mime types configuration, should this be global or explicit in watcher?
83+ Path jdk = Paths .get (System .getProperty ("java.home" ));
84+ addPathAndMaybeLink .accept (jdk .resolve ("conf" ), Mode .READ );
5385
5486 readPaths .sort (PATH_ORDER );
5587 writePaths .sort (PATH_ORDER );
0 commit comments