From b869a0d50f36686666e79c604470953b92d40c59 Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Mon, 2 Dec 2019 21:13:32 +1000 Subject: [PATCH] Implement additional checks for reload The settings/flags inittab-id, inittab-line, shares-console, runs-on-console, and pid-file cannot be changed for a running service. --- src/includes/proc-service.h | 29 ++++++++++++++++++++++++++++- src/includes/service.h | 8 +++----- src/load-service.cc | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/includes/proc-service.h b/src/includes/proc-service.h index 99aad59..7056a6d 100644 --- a/src/includes/proc-service.h +++ b/src/includes/proc-service.h @@ -434,6 +434,21 @@ class process_service : public base_process_service strncpy(inittab_line, line, sizeof(inittab_line)); } + // Get the utmp (inittab) id, may not be nul terminated if maximum length! + const char *get_utmp_id() + { + return inittab_id; + } + + // Get the utmp (inittab) line, may not be nul terminated if maximum length! + const char *get_utmp_line() + { + return inittab_line; + } + + constexpr size_t get_utmp_id_size() { return sizeof(inittab_id); } + constexpr size_t get_utmp_line_size() { return sizeof(inittab_line); } + #endif ~process_service() noexcept @@ -454,7 +469,9 @@ class bgproc_service : public base_process_service TERMINATED // read pid successfully, but the process already terminated }; - // Read the pid-file, return false on failure + string pid_file; + + // Read the pid-file contents pid_result_t read_pid_file(bp_sys::exit_status *exit_status) noexcept; public: @@ -469,6 +486,16 @@ class bgproc_service : public base_process_service ~bgproc_service() noexcept { } + + void set_pid_file(string &&pid_file) noexcept + { + this->pid_file = std::move(pid_file); + } + + const std::string &get_pid_file() noexcept + { + return pid_file; + } }; // Service which is started and stopped via separate commands diff --git a/src/includes/service.h b/src/includes/service.h index 5ebb8b9..c4f8dcf 100644 --- a/src/includes/service.h +++ b/src/includes/service.h @@ -196,8 +196,6 @@ class service_record service_state_t desired_state = service_state_t::STOPPED; protected: - string pid_file; - service_flags_t onstart_flags; string logfile; // log file name, empty string specifies /dev/null @@ -481,11 +479,11 @@ class service_record this->onstart_flags = flags; } - void set_pid_file(string &&pid_file) noexcept + service_flags_t get_flags() noexcept { - this->pid_file = std::move(pid_file); + return onstart_flags; } - + void set_socket_details(string &&socket_path, int socket_perms, uid_t socket_uid, uid_t socket_gid) noexcept { diff --git a/src/load-service.cc b/src/load-service.cc index f5f01fd..08c7fee 100644 --- a/src/load-service.cc +++ b/src/load-service.cc @@ -488,9 +488,36 @@ service_record * dirload_service_set::reload_service(service_record * service) } } - // XXX cannot change pid_file - // XXX cannot change service flags: runs_on_console, shares_console - // XXX cannot change inittab_id/inittab_line + // Cannot change certain flags + auto current_flags = service->get_flags(); + if (current_flags.starts_on_console != settings.onstart_flags.starts_on_console + || current_flags.shares_console != settings.onstart_flags.shares_console) { + throw service_description_exc(name, "Cannot change starts_on_console/" + "shares_console flags for a running service."); + } + + // Cannot change pid file + if (service->get_type() == service_type_t::BGPROCESS) { + auto *bgp_service = static_cast(service); + if (bgp_service->get_pid_file() != settings.pid_file) { + throw service_description_exc(name, "Cannot change pid_file for running service."); + } + } + + // Cannot change inittab_id/inittab_line + #if USE_UTMPX + if (service->get_type() == service_type_t::PROCESS) { + auto *proc_service = static_cast(service); + auto *svc_utmp_id = proc_service->get_utmp_id(); + auto *svc_utmp_ln = proc_service->get_utmp_line(); + if (strncmp(svc_utmp_id, settings.inittab_id, proc_service->get_utmp_id_size()) != 0 + || strncmp(svc_utmp_ln, settings.inittab_line, + proc_service->get_utmp_line_size()) != 0) { + throw service_description_exc(name, "Cannot change inittab-id or inittab-line " + "settings for running service."); + } + } + #endif // Already started; we must replace settings on existing service record create_new_record = false; -- 2.25.1