implement aliasing for systemd-analyze verify

This commit is contained in:
Albert Brox 2021-09-29 10:09:34 -04:00 committed by Luca Boccassi
parent a6d1760024
commit da845dabf5
3 changed files with 94 additions and 2 deletions

View file

@ -551,7 +551,8 @@ NAutoVTs=8
<title><command>systemd-analyze verify <replaceable>FILE</replaceable>...</command></title>
<para>This command will load unit files and print warnings if any errors are detected. Files specified
on the command line will be loaded, but also any other units referenced by them. The full unit search
on the command line will be loaded, but also any other units referenced by them. A unit's name on disk
can be overridden by specifying an alias after a colon; see below for an example. The full unit search
path is formed by combining the directories for all command line arguments, and the usual unit load
paths. The variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be used to replace or
augment the compiled in set of unit load paths; see
@ -613,6 +614,27 @@ Service a.service not loaded, a.socket cannot be started.
Service b@0.service not loaded, b.socket cannot be started.
</programlisting>
</example>
<example>
<title>Aliasing a unit</title>
<programlisting>$ cat /tmp/source
[Unit]
Description=Hostname printer
[Service]
Type=simple
ExecStart=/usr/bin/echo %H
MysteryKey=true
$ systemd-analyze verify /tmp/source
Failed to prepare filename /tmp/source: Invalid argument
$ systemd-analyze verify /tmp/source:alias.service
/tmp/systemd-analyze-XXXXXX/alias.service:7: Unknown key name 'MysteryKey' in section 'Service', ignoring.
</programlisting>
</example>
</refsect2>
<refsect2>

View file

@ -26,6 +26,7 @@
#include "copy.h"
#include "def.h"
#include "exit-status.h"
#include "extract-word.h"
#include "fd-util.h"
#include "fileio.h"
#include "filesystems.h"
@ -42,6 +43,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "pretty-print.h"
#include "rm-rf.h"
#if HAVE_SECCOMP
# include "seccomp-util.h"
#endif
@ -53,6 +55,7 @@
#include "strxcpyx.h"
#include "terminal-util.h"
#include "time-util.h"
#include "tmpfile-util.h"
#include "unit-name.h"
#include "util.h"
#include "verb-log-control.h"
@ -230,6 +233,53 @@ static int compare_unit_start(const UnitTimes *a, const UnitTimes *b) {
return CMP(a->activating, b->activating);
}
static int process_aliases(char *argv[], char *tempdir, char ***ret) {
_cleanup_strv_free_ char **filenames = NULL;
char **filename;
int r;
assert(argv);
assert(tempdir);
assert(ret);
STRV_FOREACH(filename, strv_skip(argv, 1)) {
_cleanup_free_ char *src = NULL, *dst = NULL, *arg = NULL;
char *parse_arg;
arg = strdup(*filename);
if (!arg)
return -ENOMEM;
parse_arg = arg;
r = extract_first_word((const char **) &parse_arg, &src, ":", 0);
if (r < 0)
return r;
if (!parse_arg) {
r = strv_extend(&filenames, src);
if (r < 0)
return -ENOMEM;
continue;
}
dst = path_join(tempdir, basename(parse_arg));
if (!dst)
return -ENOMEM;
r = copy_file(src, dst, 0, 0644, 0, 0, COPY_REFLINK);
if (r < 0)
return r;
r = strv_consume(&filenames, TAKE_PTR(dst));
if (r < 0)
return -ENOMEM;
}
*ret = TAKE_PTR(filenames);
return 0;
}
static UnitTimes* unit_times_free_array(UnitTimes *t) {
for (UnitTimes *p = t; p && p->has_data; p++)
free(p->name);
@ -2257,7 +2307,19 @@ static int do_condition(int argc, char *argv[], void *userdata) {
}
static int do_verify(int argc, char *argv[], void *userdata) {
return verify_units(strv_skip(argv, 1), arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root);
_cleanup_strv_free_ char **filenames = NULL;
_cleanup_(rm_rf_physical_and_freep) char *tempdir = NULL;
int r;
r = mkdtemp_malloc("/tmp/systemd-analyze-XXXXXX", &tempdir);
if (r < 0)
return log_error_errno(r, "Failed to setup working directory: %m");
r = process_aliases(argv, tempdir, &filenames);
if (r < 0)
return log_error_errno(r, "Couldn't process aliases: %m");
return verify_units(filenames, arg_scope, arg_man, arg_generators, arg_recursive_errors, arg_root);
}
static int do_security(int argc, char *argv[], void *userdata) {

View file

@ -76,6 +76,14 @@ systemd-analyze verify /tmp/.testfile.service
rm /tmp/.testfile.service
# Alias a unit file's name on disk (see #20061)
cp /tmp/testfile.service /tmp/testsrvc
systemd-analyze verify /tmp/testsrvc \
&& { echo 'unexpected success'; exit 1; }
systemd-analyze verify /tmp/testsrvc:alias.service
# Zero exit status since the value used for comparison determine exposure to security threats is by default 100
systemd-analyze security --offline=true /tmp/testfile.service