Skip to content

Commit cde5011

Browse files
authored
Clarify error message on keystore write permissions (#46321)
When the Elasticsearch process does not have write permissions to upgrade the Elasticsearch keystore, we bail with an error message that indicates there is a filesystem permissions problem. This commit clarifies that error message by pointing out the directory where write permissions are required, or that the user can also run the elasticsearch-keystore upgrade command manually before starting the Elasticsearch process. In this case, the upgrade would not be needed at runtime, so the permissions would not be needed then.
1 parent 995be00 commit cde5011

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.common.settings;
21+
22+
import org.apache.lucene.util.Constants;
23+
import org.apache.lucene.util.LuceneTestCase;
24+
import org.elasticsearch.cli.ExitCodes;
25+
import org.elasticsearch.cli.UserException;
26+
import org.elasticsearch.test.ESTestCase;
27+
28+
import java.nio.file.AccessDeniedException;
29+
import java.nio.file.Files;
30+
import java.nio.file.Path;
31+
import java.nio.file.attribute.PosixFileAttributeView;
32+
import java.nio.file.attribute.PosixFilePermissions;
33+
import java.util.Locale;
34+
35+
import static org.hamcrest.Matchers.containsString;
36+
import static org.hamcrest.Matchers.equalTo;
37+
import static org.hamcrest.Matchers.hasToString;
38+
import static org.hamcrest.Matchers.instanceOf;
39+
40+
@LuceneTestCase.SuppressFileSystems("ExtrasFS")
41+
public class EvilKeyStoreWrapperTests extends ESTestCase {
42+
43+
public void testWritePermissions() throws Exception {
44+
assumeFalse("requires POSIX file permissions", Constants.WINDOWS);
45+
final Path configDir = createTempDir();
46+
PosixFileAttributeView attrs = Files.getFileAttributeView(configDir, PosixFileAttributeView.class);
47+
if (attrs != null) {
48+
// don't rely on umask: ensure the keystore has minimal permissions
49+
attrs.setPermissions(PosixFilePermissions.fromString("r--r-----"));
50+
}
51+
try {
52+
final KeyStoreWrapper wrapper = KeyStoreWrapper.create();
53+
final UserException e = expectThrows(UserException.class, () -> wrapper.save(configDir, new char[0]));
54+
final String expected = String.format(
55+
Locale.ROOT,
56+
"unable to create temporary keystore at [%s], write permissions required for [%s] or run [elasticsearch-keystore upgrade]",
57+
configDir.resolve("elasticsearch.keystore.tmp"),
58+
configDir);
59+
assertThat(e, hasToString(containsString(expected)));
60+
assertThat(e.exitCode, equalTo(ExitCodes.CONFIG));
61+
assertThat(e.getCause(), instanceOf(AccessDeniedException.class));
62+
} finally {
63+
// so the test framework can cleanup
64+
attrs.setPermissions(PosixFilePermissions.fromString("rw-rw----"));
65+
}
66+
}
67+
68+
}

server/src/main/java/org/elasticsearch/common/settings/KeyStoreWrapper.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,9 +502,10 @@ public synchronized void save(Path configDir, char[] password) throws Exception
502502

503503
} catch (final AccessDeniedException e) {
504504
final String message = String.format(
505-
Locale.ROOT,
506-
"unable to create temporary keystore at [%s], please check filesystem permissions",
507-
configDir.resolve(tmpFile));
505+
Locale.ROOT,
506+
"unable to create temporary keystore at [%s], write permissions required for [%s] or run [elasticsearch-keystore upgrade]",
507+
configDir.resolve(tmpFile),
508+
configDir);
508509
throw new UserException(ExitCodes.CONFIG, message, e);
509510
}
510511

0 commit comments

Comments
 (0)