diff --git a/core/src/main/java/org/elasticsearch/plugins/PluginManager.java b/core/src/main/java/org/elasticsearch/plugins/PluginManager.java index f3b5c5b5c57..c8db1ad9cbd 100644 --- a/core/src/main/java/org/elasticsearch/plugins/PluginManager.java +++ b/core/src/main/java/org/elasticsearch/plugins/PluginManager.java @@ -359,25 +359,37 @@ public class PluginManager { throw new IOException("Could not move [" + sourcePluginBinDirectory + "] to [" + destPluginBinDirectory + "]", e); } if (Environment.getFileStore(destPluginBinDirectory).supportsFileAttributeView(PosixFileAttributeView.class)) { - // add read and execute permissions to existing perms, so execution will work. - // read should generally be set already, but set it anyway: don't rely on umask... - final Set executePerms = new HashSet<>(); - executePerms.add(PosixFilePermission.OWNER_READ); - executePerms.add(PosixFilePermission.GROUP_READ); - executePerms.add(PosixFilePermission.OTHERS_READ); - executePerms.add(PosixFilePermission.OWNER_EXECUTE); - executePerms.add(PosixFilePermission.GROUP_EXECUTE); - executePerms.add(PosixFilePermission.OTHERS_EXECUTE); + PosixFileAttributes parentDirAttributes = Files.getFileAttributeView(destPluginBinDirectory.getParent(), PosixFileAttributeView.class).readAttributes(); + //copy permissions from parent bin directory + Set filePermissions = new HashSet<>(); + for (PosixFilePermission posixFilePermission : parentDirAttributes.permissions()) { + switch (posixFilePermission) { + case OWNER_EXECUTE: + case GROUP_EXECUTE: + case OTHERS_EXECUTE: + break; + default: + filePermissions.add(posixFilePermission); + } + } + // add file execute permissions to existing perms, so execution will work. + filePermissions.add(PosixFilePermission.OWNER_EXECUTE); + filePermissions.add(PosixFilePermission.GROUP_EXECUTE); + filePermissions.add(PosixFilePermission.OTHERS_EXECUTE); Files.walkFileTree(destPluginBinDirectory, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (attrs.isRegularFile()) { - Set perms = Files.getPosixFilePermissions(file); - perms.addAll(executePerms); - Files.setPosixFilePermissions(file, perms); + setPosixFileAttributes(file, parentDirAttributes.owner(), parentDirAttributes.group(), filePermissions); } return FileVisitResult.CONTINUE; } + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + setPosixFileAttributes(dir, parentDirAttributes.owner(), parentDirAttributes.group(), parentDirAttributes.permissions()); + return FileVisitResult.CONTINUE; + } }); } else { terminal.println(VERBOSE, "Skipping posix permissions - filestore doesn't support posix permission"); diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginManagerPermissionTests.java b/core/src/test/java/org/elasticsearch/plugins/PluginManagerPermissionTests.java index a8cbe62ccb2..8c92537fd17 100644 --- a/core/src/test/java/org/elasticsearch/plugins/PluginManagerPermissionTests.java +++ b/core/src/test/java/org/elasticsearch/plugins/PluginManagerPermissionTests.java @@ -41,6 +41,7 @@ import java.util.Set; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import static java.nio.file.attribute.PosixFilePermission.*; import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.elasticsearch.plugins.PluginInfoTests.writeProperties; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*; @@ -283,6 +284,39 @@ public class PluginManagerPermissionTests extends ESTestCase { assertThat(pluginConfigFileAttributes.permissions(), equalTo(expectedFilePermissions)); } + public void testBinDirectoryOwnerGroupAndPermissions() throws IOException { + assumeTrue("File system does not support permissions, skipping", supportsPermissions); + URL pluginUrl = createPlugin(true, false); + PluginManager pluginManager = new PluginManager(environment, pluginUrl, PluginManager.OutputMode.VERBOSE, TimeValue.timeValueSeconds(10)); + pluginManager.downloadAndExtract(pluginName, terminal); + PosixFileAttributes parentFileAttributes = Files.getFileAttributeView(environment.binFile(), PosixFileAttributeView.class).readAttributes(); + Path binPath = environment.binFile().resolve(pluginName); + PosixFileAttributes pluginBinDirAttributes = Files.getFileAttributeView(binPath, PosixFileAttributeView.class).readAttributes(); + assertThat(pluginBinDirAttributes.owner(), equalTo(parentFileAttributes.owner())); + assertThat(pluginBinDirAttributes.group(), equalTo(parentFileAttributes.group())); + assertThat(pluginBinDirAttributes.permissions(), equalTo(parentFileAttributes.permissions())); + Path executableFile = binPath.resolve("my-binary"); + PosixFileAttributes pluginExecutableFileAttributes = Files.getFileAttributeView(executableFile, PosixFileAttributeView.class).readAttributes(); + assertThat(pluginExecutableFileAttributes.owner(), equalTo(parentFileAttributes.owner())); + assertThat(pluginExecutableFileAttributes.group(), equalTo(parentFileAttributes.group())); + Set expectedFilePermissions = new HashSet<>(); + expectedFilePermissions.add(OWNER_EXECUTE); + expectedFilePermissions.add(GROUP_EXECUTE); + expectedFilePermissions.add(OTHERS_EXECUTE); + for (PosixFilePermission parentPermission : parentFileAttributes.permissions()) { + switch(parentPermission) { + case OWNER_EXECUTE: + case GROUP_EXECUTE: + case OTHERS_EXECUTE: + break; + default: + expectedFilePermissions.add(parentPermission); + } + } + + assertThat(pluginExecutableFileAttributes.permissions(), equalTo(expectedFilePermissions)); + } + private URL createPlugin(boolean withBinDir, boolean withConfigDir) throws IOException { final Path structure = createTempDir().resolve("fake-plugin"); writeProperties(structure, "description", "fake desc", @@ -301,7 +335,7 @@ public class PluginManagerPermissionTests extends ESTestCase { // create executable Path executable = binDir.resolve("my-binary"); Files.createFile(executable); - Files.setPosixFilePermissions(executable, PosixFilePermissions.fromString("rwxr-xr-x")); + Files.setPosixFilePermissions(executable, PosixFilePermissions.fromString("rw-r--r--")); } if (withConfigDir) { // create bin dir diff --git a/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash b/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash index b467d79f256..8052fc1340c 100644 --- a/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash +++ b/qa/vagrant/src/test/resources/packaging/scripts/plugins.bash @@ -79,8 +79,13 @@ install_jvm_example() { local relativePath=${1:-$(readlink -m jvm-example-*.zip)} install_jvm_plugin jvm-example "$relativePath" - assert_file_exist "$ESHOME/bin/jvm-example" - assert_file_exist "$ESHOME/bin/jvm-example/test" + #owner group and permissions vary depending on how es was installed + #just make sure that everything is the same as the parent bin dir, which was properly set up during install + bin_user=$(find "$ESHOME/bin" -maxdepth 0 -printf "%u") + bin_owner=$(find "$ESHOME/bin" -maxdepth 0 -printf "%g") + bin_privileges=$(find "$ESHOME/bin" -maxdepth 0 -printf "%m") + assert_file "$ESHOME/bin/jvm-example" d $bin_user $bin_owner $bin_privileges + assert_file "$ESHOME/bin/jvm-example/test" f $bin_user $bin_owner $bin_privileges #owner group and permissions vary depending on how es was installed #just make sure that everything is the same as $CONFIG_DIR, which was properly set up during install