summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-07-13 11:32:39 +0200
committerLennart Poettering <lennart@poettering.net>2022-07-20 23:53:22 +0200
commit1d77721f30a821464cd715a63b89ef18419de7b0 (patch)
tree3c20d7dc1ddbcc38fb35bfd007cb2f02da9a6702
parent74c1cf626730a34fbd2d39ed016db21c9748d944 (diff)
downloadsystemd-1d77721f30a821464cd715a63b89ef18419de7b0.tar.gz
tmpfiles: accept additional tmpfiles lines via credential
-rw-r--r--man/systemd-tmpfiles.xml25
-rw-r--r--src/tmpfiles/tmpfiles.c31
-rwxr-xr-xtest/TEST-54-CREDS/test.sh2
-rwxr-xr-xtest/units/testsuite-54.sh3
-rw-r--r--units/systemd-tmpfiles-clean.service1
-rw-r--r--units/systemd-tmpfiles-setup-dev.service1
-rw-r--r--units/systemd-tmpfiles-setup.service1
7 files changed, 62 insertions, 2 deletions
diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml
index 425ed23dd3..92ab322ba0 100644
--- a/man/systemd-tmpfiles.xml
+++ b/man/systemd-tmpfiles.xml
@@ -231,6 +231,31 @@
</refsect1>
<refsect1>
+ <title>Credentials</title>
+
+ <para><command>systemd-tmpfiles</command> supports the service credentials logic as implemented by
+ <varname>LoadCredential=</varname>/<varname>SetCredential=</varname> (see
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
+ details). The following credentials are used when passed in:</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>tmpfiles.extra</literal></term>
+
+ <listitem><para> The contents of this credential may contain additional lines to operate on. The
+ credential contents should follow the same format as any other <filename>tmpfiles.d/</filename>
+ drop-in configuration file. If this credential is passed it is processed after all of the drop-in
+ files read from the file system. The lines in the credential can hence augment existing lines of the
+ OS, but not override them.</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Note that by default the <filename>systemd-tmpfiles-setup.service</filename> unit file (and related
+ unit files) is set up to inherit the <literal>tmpfiles.extra</literal> credential from the service
+ manager.</para>
+ </refsect1>
+
+ <refsect1>
<title>Environment</title>
<variablelist class='environment-variables'>
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 0c50c8e1ee..e2451f1b95 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -25,6 +25,7 @@
#include "chattr-util.h"
#include "conf-files.h"
#include "copy.h"
+#include "creds-util.h"
#include "def.h"
#include "devnum-util.h"
#include "dirent-util.h"
@@ -3594,7 +3595,12 @@ static int parse_argv(int argc, char *argv[]) {
return 1;
}
-static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoent, bool *invalid_config) {
+static int read_config_file(
+ char **config_dirs,
+ const char *fn,
+ bool ignore_enoent,
+ bool *invalid_config) {
+
_cleanup_(hashmap_freep) Hashmap *uid_cache = NULL, *gid_cache = NULL;
_cleanup_fclose_ FILE *_f = NULL;
_cleanup_free_ char *pp = NULL;
@@ -3736,6 +3742,25 @@ static int read_config_files(char **config_dirs, char **args, bool *invalid_conf
return 0;
}
+static int read_credential_lines(bool *invalid_config) {
+ _cleanup_free_ char *j = NULL;
+ const char *d;
+ int r;
+
+ r = get_credentials_dir(&d);
+ if (r == -ENXIO)
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to get credentials directory: %m");
+
+ j = path_join(d, "tmpfiles.extra");
+ if (!j)
+ return log_oom();
+
+ (void) read_config_file(/* config_dirs= */ NULL, j, /* ignore_enoent= */ true, invalid_config);
+ return 0;
+}
+
static int link_parent(ItemArray *a) {
const char *path;
char *prefix;
@@ -3892,6 +3917,10 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
+ r = read_credential_lines(&invalid_config);
+ if (r < 0)
+ return r;
+
/* Let's now link up all child/parent relationships */
ORDERED_HASHMAP_FOREACH(a, items) {
r = link_parent(a);
diff --git a/test/TEST-54-CREDS/test.sh b/test/TEST-54-CREDS/test.sh
index 8f66f1c7b8..ac6777be31 100755
--- a/test/TEST-54-CREDS/test.sh
+++ b/test/TEST-54-CREDS/test.sh
@@ -4,7 +4,7 @@ set -e
TEST_DESCRIPTION="test credentials"
NSPAWN_ARGUMENTS="${NSPAWN_ARGUMENTS:-} --set-credential=mynspawncredential:strangevalue"
-QEMU_OPTIONS="${QEMU_OPTIONS:-} -fw_cfg name=opt/io.systemd.credentials/myqemucredential,string=othervalue -smbios type=11,value=io.systemd.credential:smbioscredential=magicdata -smbios type=11,value=io.systemd.credential.binary:binarysmbioscredential=bWFnaWNiaW5hcnlkYXRh -smbios type=11,value=io.systemd.credential.binary:sysusers.extra=dSBjcmVkdGVzdHVzZXIK"
+QEMU_OPTIONS="${QEMU_OPTIONS:-} -fw_cfg name=opt/io.systemd.credentials/myqemucredential,string=othervalue -smbios type=11,value=io.systemd.credential:smbioscredential=magicdata -smbios type=11,value=io.systemd.credential.binary:binarysmbioscredential=bWFnaWNiaW5hcnlkYXRh -smbios type=11,value=io.systemd.credential.binary:sysusers.extra=dSBjcmVkdGVzdHVzZXIK -smbios type=11,value=io.systemd.credential.binary:tmpfiles.extra=ZiAvdG1wL3NvdXJjZWRmcm9tY3JlZGVudGlhbCAtIC0gLSAtIHRtcGZpbGVzc2VjcmV0Cg=="
KERNEL_APPEND="${KERNEL_APPEND:-} systemd.set_credential=kernelcmdlinecred:uff systemd.set_credential=sysctl.extra:kernel.domainname=sysctltest rd.systemd.import_credentials=no"
# shellcheck source=test/test-functions
diff --git a/test/units/testsuite-54.sh b/test/units/testsuite-54.sh
index a7ccdca032..8eff47028d 100755
--- a/test/units/testsuite-54.sh
+++ b/test/units/testsuite-54.sh
@@ -43,6 +43,9 @@ elif [ -d /sys/firmware/qemu_fw_cfg/by_name ]; then
# Verify that creating a user via sysusers via the kernel cmdline worked
grep -q ^credtestuser: /etc/passwd
+
+ # Verify that writing a file via tmpfiles worked
+ [ "$(cat /tmp/sourcedfromcredential)" = "tmpfilessecret" ]
else
echo "qemu_fw_cfg support missing in kernel. Sniff!"
expected_credential=""
diff --git a/units/systemd-tmpfiles-clean.service b/units/systemd-tmpfiles-clean.service
index 7aee6463bd..6ae4e74ddd 100644
--- a/units/systemd-tmpfiles-clean.service
+++ b/units/systemd-tmpfiles-clean.service
@@ -20,3 +20,4 @@ Type=oneshot
ExecStart=systemd-tmpfiles --clean
SuccessExitStatus=DATAERR
IOSchedulingClass=idle
+LoadCredential=tmpfiles.extra
diff --git a/units/systemd-tmpfiles-setup-dev.service b/units/systemd-tmpfiles-setup-dev.service
index 0babe78767..ad0e54fcc4 100644
--- a/units/systemd-tmpfiles-setup-dev.service
+++ b/units/systemd-tmpfiles-setup-dev.service
@@ -20,3 +20,4 @@ Type=oneshot
RemainAfterExit=yes
ExecStart=systemd-tmpfiles --prefix=/dev --create --boot
SuccessExitStatus=DATAERR CANTCREAT
+LoadCredential=tmpfiles.extra
diff --git a/units/systemd-tmpfiles-setup.service b/units/systemd-tmpfiles-setup.service
index bc29dbc8c9..6c1ee91a40 100644
--- a/units/systemd-tmpfiles-setup.service
+++ b/units/systemd-tmpfiles-setup.service
@@ -21,3 +21,4 @@ Type=oneshot
RemainAfterExit=yes
ExecStart=systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
SuccessExitStatus=DATAERR CANTCREAT
+LoadCredential=tmpfiles.extra