From c27d1b3eecbd00aecb67d3ec6e3063e7f991693a Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Mon, 2 Feb 2026 16:24:00 +0100 Subject: [PATCH] ssh-generator: follow symlink when searching for sshd@.service unit_file_exists() currently does not follow symlinks, as it is mainly used to test whether the unit (of any install state) has been seen under search dirs. However, in ssh-generator we should search for and honor whatever the distro ships, which might be an alias or linked externally. --- src/shared/install.c | 10 ++++++++-- src/shared/install.h | 10 ++++++++-- src/ssh-generator/ssh-generator.c | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/shared/install.c b/src/shared/install.c index dc27d53f098..4c68821562c 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -3239,7 +3239,13 @@ int unit_file_get_state( return unit_file_lookup_state(scope, &lp, name, ret); } -int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char *name, char **ret_path) { +int unit_file_exists_full( + RuntimeScope scope, + const LookupPaths *lp, + bool follow, + const char *name, + char **ret_path) { + _cleanup_(install_context_done) InstallContext c = { .scope = scope, }; @@ -3256,7 +3262,7 @@ int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char &c, lp, name, - /* flags= */ 0, + follow ? SEARCH_FOLLOW_CONFIG_SYMLINKS : 0, ret_path ? &info : NULL, /* changes= */ NULL, /* n_changes= */ NULL); diff --git a/src/shared/install.h b/src/shared/install.h index c4592fed358..98d5a41d3e5 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -181,9 +181,15 @@ int unit_file_lookup_state( int unit_file_get_state(RuntimeScope scope, const char *root_dir, const char *filename, UnitFileState *ret); -int unit_file_exists_full(RuntimeScope scope, const LookupPaths *lp, const char *name, char **ret_path); +int unit_file_exists_full( + RuntimeScope scope, + const LookupPaths *lp, + bool follow, + const char *name, + char **ret_path); + static inline int unit_file_exists(RuntimeScope scope, const LookupPaths *lp, const char *name) { - return unit_file_exists_full(scope, lp, name, NULL); + return unit_file_exists_full(scope, lp, false, name, NULL); } int unit_file_get_list(RuntimeScope scope, const char *root_dir, char * const *states, char * const *patterns, Hashmap **ret); diff --git a/src/ssh-generator/ssh-generator.c b/src/ssh-generator/ssh-generator.c index 2364f86e256..5cb4c98b8a1 100644 --- a/src/ssh-generator/ssh-generator.c +++ b/src/ssh-generator/ssh-generator.c @@ -475,7 +475,10 @@ static int run(const char *dest, const char *dest_early, const char *dest_late) return r; _cleanup_free_ char *found_sshd_template_unit = NULL; - r = unit_file_exists_full(RUNTIME_SCOPE_SYSTEM, &lp, "sshd@.service", &found_sshd_template_unit); + r = unit_file_exists_full(RUNTIME_SCOPE_SYSTEM, &lp, + /* follow = */ true, + "sshd@.service", + &found_sshd_template_unit); if (r < 0) return log_error_errno(r, "Unable to detect if sshd@.service exists: %m"); -- 2.47.3