tmpfiles: accept additional tmpfiles lines via credential

This commit is contained in:
Lennart Poettering 2022-07-13 11:32:39 +02:00
parent 74c1cf6267
commit 1d77721f30
7 changed files with 62 additions and 2 deletions

View file

@ -230,6 +230,31 @@
<programlisting>systemd-tmpfiles --remove --create</programlisting>
</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>

View file

@ -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);

View file

@ -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

View file

@ -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=""

View file

@ -20,3 +20,4 @@ Type=oneshot
ExecStart=systemd-tmpfiles --clean
SuccessExitStatus=DATAERR
IOSchedulingClass=idle
LoadCredential=tmpfiles.extra

View file

@ -20,3 +20,4 @@ Type=oneshot
RemainAfterExit=yes
ExecStart=systemd-tmpfiles --prefix=/dev --create --boot
SuccessExitStatus=DATAERR CANTCREAT
LoadCredential=tmpfiles.extra

View file

@ -21,3 +21,4 @@ Type=oneshot
RemainAfterExit=yes
ExecStart=systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
SuccessExitStatus=DATAERR CANTCREAT
LoadCredential=tmpfiles.extra