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

