summaryrefslogtreecommitdiffstats
path: root/src/shared/creds-util.c
diff options
context:
space:
mode:
authorAlberto Planas <aplanas@suse.com>2023-01-13 15:31:39 +0100
committerAlberto Planas <aplanas@suse.com>2023-01-16 13:31:17 +0100
commit1615578f2792fdeecaf65606861bd3db9eb949c3 (patch)
treeb1c3aa0bc1f808959bc7de1521f15836ebbe9234 /src/shared/creds-util.c
parentman: udev_enumerate_new: fix typo (diff)
downloadsystemd-1615578f2792fdeecaf65606861bd3db9eb949c3.tar.xz
systemd-1615578f2792fdeecaf65606861bd3db9eb949c3.zip
creds-util: check for CAP_DAC_READ_SEARCH
In make_credential_host_secret, the credential.secret file is generated first as a temporary anonymous file that is later instantiated with linkat(2). This system call requires CAP_DAC_READ_SEARCH capability when the flag AT_EMPTY_PATH is used. This patch check if the capability is effective, and if not uses the alternative codepath for creating named temporary files. Non-root users can now create per-user credentials with: export SYSTEMD_CREDENTIAL_SECRET=$HOME/.config/systemd/credential.secret systemd-creds setup Signed-off-by: Alberto Planas <aplanas@suse.com>
Diffstat (limited to 'src/shared/creds-util.c')
-rw-r--r--src/shared/creds-util.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/shared/creds-util.c b/src/shared/creds-util.c
index a68837b70b..e60dce8425 100644
--- a/src/shared/creds-util.c
+++ b/src/shared/creds-util.c
@@ -9,6 +9,7 @@
#include "sd-id128.h"
#include "blockdev-util.h"
+#include "capability-util.h"
#include "chattr-util.h"
#include "constants.h"
#include "creds-util.h"
@@ -223,10 +224,15 @@ static int make_credential_host_secret(
assert(dfd >= 0);
assert(fn);
- fd = openat(dfd, ".", O_CLOEXEC|O_WRONLY|O_TMPFILE, 0400);
+ /* For non-root users creating a temporary file using the openat(2) over "." will fail later, in the
+ * linkat(2) step at the end. The reason is that linkat(2) requires the CAP_DAC_READ_SEARCH
+ * capability when it uses the AT_EMPTY_PATH flag. */
+ if (have_effective_cap(CAP_DAC_READ_SEARCH) > 0) {
+ fd = openat(dfd, ".", O_CLOEXEC|O_WRONLY|O_TMPFILE, 0400);
+ if (fd < 0)
+ log_debug_errno(errno, "Failed to create temporary credential file with O_TMPFILE, proceeding without: %m");
+ }
if (fd < 0) {
- log_debug_errno(errno, "Failed to create temporary credential file with O_TMPFILE, proceeding without: %m");
-
if (asprintf(&t, "credential.secret.%016" PRIx64, random_u64()) < 0)
return -ENOMEM;