178 lines
7.7 KiB
Diff
178 lines
7.7 KiB
Diff
From 7d1e91d1a9504ab1bc03894038f90a8e87a4e982 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
Date: Tue, 2 Apr 2019 11:22:56 +0200
|
|
Subject: [PATCH] shared/unit-file: add a function to validate unit alias
|
|
symlinks
|
|
|
|
It turns out most possible symlinks are invalid, because the type has to match,
|
|
and template units can only be linked to template units.
|
|
|
|
I'm not sure if the existing code made the same checks consistently. At least
|
|
I don't see the same rules expressed in a single place.
|
|
|
|
revert shared unit file add a function to validate unit alias symlinks
|
|
---
|
|
src/shared/unit-file.c | 73 -----------------------------------------------
|
|
src/shared/unit-file.h | 2 --
|
|
src/test/meson.build | 4 ---
|
|
src/test/test-unit-file.c | 34 ----------------------
|
|
4 files changed, 113 deletions(-)
|
|
delete mode 100644 src/test/test-unit-file.c
|
|
|
|
diff --git a/src/shared/unit-file.c b/src/shared/unit-file.c
|
|
index cde38c4..deed7dc 100644
|
|
--- a/src/shared/unit-file.c
|
|
+++ b/src/shared/unit-file.c
|
|
@@ -1,7 +1,6 @@
|
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
|
|
#include "macro.h"
|
|
-#include "string-util.h"
|
|
#include "unit-file.h"
|
|
|
|
bool unit_type_may_alias(UnitType type) {
|
|
@@ -22,75 +21,3 @@ bool unit_type_may_template(UnitType type) {
|
|
UNIT_TIMER,
|
|
UNIT_PATH);
|
|
}
|
|
-
|
|
-int unit_validate_alias_symlink_and_warn(const char *filename, const char *target) {
|
|
- const char *src, *dst;
|
|
- _cleanup_free_ char *src_instance = NULL, *dst_instance = NULL;
|
|
- UnitType src_unit_type, dst_unit_type;
|
|
- int src_name_type, dst_name_type;
|
|
-
|
|
- /* Check if the *alias* symlink is valid. This applies to symlinks like
|
|
- * /etc/systemd/system/dbus.service → dbus-broker.service, but not to .wants or .requires symlinks
|
|
- * and such. Neither does this apply to symlinks which *link* units, i.e. symlinks to outside of the
|
|
- * unit lookup path.
|
|
- *
|
|
- * -EINVAL is returned if the something is wrong with the source filename or the source unit type is
|
|
- * not allowed to symlink,
|
|
- * -EXDEV if the target filename is not a valid unit name or doesn't match the source.
|
|
- */
|
|
-
|
|
- src = basename(filename);
|
|
- dst = basename(target);
|
|
-
|
|
- /* src checks */
|
|
-
|
|
- src_name_type = unit_name_to_instance(src, &src_instance);
|
|
- if (src_name_type < 0)
|
|
- return log_notice_errno(src_name_type,
|
|
- "%s: not a valid unit name \"%s\": %m", filename, src);
|
|
-
|
|
- src_unit_type = unit_name_to_type(src);
|
|
- assert(src_unit_type >= 0); /* unit_name_to_instance() checked the suffix already */
|
|
-
|
|
- if (!unit_type_may_alias(src_unit_type))
|
|
- return log_notice_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
- "%s: symlinks are not allowed for units of this type, rejecting.",
|
|
- filename);
|
|
-
|
|
- if (src_name_type != UNIT_NAME_PLAIN &&
|
|
- !unit_type_may_template(src_unit_type))
|
|
- return log_notice_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
- "%s: templates not allowed for %s units, rejecting.",
|
|
- filename, unit_type_to_string(src_unit_type));
|
|
-
|
|
- /* dst checks */
|
|
-
|
|
- dst_name_type = unit_name_to_instance(dst, &dst_instance);
|
|
- if (dst_name_type < 0)
|
|
- return log_notice_errno(dst_name_type == -EINVAL ? SYNTHETIC_ERRNO(EXDEV) : dst_name_type,
|
|
- "%s points to \"%s\" which is not a valid unit name: %m",
|
|
- filename, dst);
|
|
-
|
|
- if (!(dst_name_type == src_name_type ||
|
|
- (src_name_type == UNIT_NAME_INSTANCE && dst_name_type == UNIT_NAME_TEMPLATE)))
|
|
- return log_notice_errno(SYNTHETIC_ERRNO(EXDEV),
|
|
- "%s: symlink target name type \"%s\" does not match source, rejecting.",
|
|
- filename, dst);
|
|
-
|
|
- if (dst_name_type == UNIT_NAME_INSTANCE) {
|
|
- assert(src_instance);
|
|
- assert(dst_instance);
|
|
- if (!streq(src_instance, dst_instance))
|
|
- return log_notice_errno(SYNTHETIC_ERRNO(EXDEV),
|
|
- "%s: unit symlink target \"%s\" instance name doesn't match, rejecting.",
|
|
- filename, dst);
|
|
- }
|
|
-
|
|
- dst_unit_type = unit_name_to_type(dst);
|
|
- if (dst_unit_type != src_unit_type)
|
|
- return log_notice_errno(SYNTHETIC_ERRNO(EXDEV),
|
|
- "%s: symlink target \"%s\" has incompatible suffix, rejecting.",
|
|
- filename, dst);
|
|
-
|
|
- return 0;
|
|
-}
|
|
diff --git a/src/shared/unit-file.h b/src/shared/unit-file.h
|
|
index e57f472..2b9df65 100644
|
|
--- a/src/shared/unit-file.h
|
|
+++ b/src/shared/unit-file.h
|
|
@@ -35,5 +35,3 @@ enum UnitFileScope {
|
|
|
|
bool unit_type_may_alias(UnitType type) _const_;
|
|
bool unit_type_may_template(UnitType type) _const_;
|
|
-
|
|
-int unit_validate_alias_symlink_and_warn(const char *filename, const char *target);
|
|
diff --git a/src/test/meson.build b/src/test/meson.build
|
|
index de31e97..5625e68 100644
|
|
--- a/src/test/meson.build
|
|
+++ b/src/test/meson.build
|
|
@@ -137,10 +137,6 @@ tests += [
|
|
[],
|
|
'ENABLE_EFI'],
|
|
|
|
- [['src/test/test-unit-file.c'],
|
|
- [],
|
|
- []],
|
|
-
|
|
[['src/test/test-unit-name.c',
|
|
'src/test/test-helper.c'],
|
|
[libcore,
|
|
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
|
|
deleted file mode 100644
|
|
index b626b5f..0000000
|
|
--- a/src/test/test-unit-file.c
|
|
+++ /dev/null
|
|
@@ -1,34 +0,0 @@
|
|
-/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
-
|
|
-#include "path-lookup.h"
|
|
-#include "set.h"
|
|
-#include "strv.h"
|
|
-#include "tests.h"
|
|
-#include "unit-file.h"
|
|
-
|
|
-static void test_unit_validate_alias_symlink_and_warn(void) {
|
|
- log_info("/* %s */", __func__);
|
|
-
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b.service") == 0);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b.socket") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b.foobar") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b@.service") == 0);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b@.socket") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@YYY.service") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@YYY.socket") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b@YYY.service") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@XXX.service") == 0);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@XXX.service", "/other/b@.service") == 0);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@.service", "/other/b.service") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a.service", "/other/b@.service") == -EXDEV);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a@.slice", "/other/b.slice") == -EINVAL);
|
|
- assert_se(unit_validate_alias_symlink_and_warn("/path/a.slice", "/other/b.slice") == -EINVAL);
|
|
-}
|
|
-
|
|
-int main(int argc, char **argv) {
|
|
- test_setup_logging(LOG_DEBUG);
|
|
-
|
|
- test_unit_validate_alias_symlink_and_warn();
|
|
-
|
|
- return 0;
|
|
-}
|
|
--
|
|
1.8.3.1
|
|
|