From e4902257d6d8bc913011dc7f6137056094cd1fcd Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 17 Apr 2021 00:41:11 -0500 Subject: [PATCH] Feature: controller program must support "with full_path". This is necessary to accomodate fickle programs like SSHD where the full path in argument[0] is required. This implements a general feature called "with" which is provided to add flags on a per Rule Type basis. These flags will tweak the Rule Type is some manner. Only one flag is suppoted at this time: "full_path". The "full_path" provides the necessary functionality to make SSHD happy. --- level_3/controller/c/private-common.h | 7 +++ level_3/controller/c/private-rule.c | 59 ++++++++++++++-------- .../data/settings/example/rules/service/sshd.rule | 3 +- level_3/controller/documents/rule.txt | 5 ++ level_3/controller/specifications/rule.txt | 10 ++-- 5 files changed, 57 insertions(+), 27 deletions(-) diff --git a/level_3/controller/c/private-common.h b/level_3/controller/c/private-common.h index 9d27729..02a860e 100644 --- a/level_3/controller/c/private-common.h +++ b/level_3/controller/c/private-common.h @@ -46,6 +46,7 @@ extern "C" { #define controller_string_fifo "fifo" #define controller_string_freeze "freeze" #define controller_string_fsize "fsize" + #define controller_string_full_path "full_path" #define controller_string_group "group" #define controller_string_groups "groups" #define controller_string_how "how" @@ -104,6 +105,7 @@ extern "C" { #define controller_string_wait "wait" #define controller_string_want "want" #define controller_string_wish "wish" + #define controller_string_with "with" #define controller_string_yes "yes" #define controller_string_action_length 6 @@ -134,6 +136,7 @@ extern "C" { #define controller_string_fifo_length 4 #define controller_string_freeze_length 6 #define controller_string_fsize_length 5 + #define controller_string_full_path_length 9 #define controller_string_group_length 5 #define controller_string_how_length 3 #define controller_string_idle_length 4 @@ -191,6 +194,7 @@ extern "C" { #define controller_string_wait_length 4 #define controller_string_want_length 4 #define controller_string_wish_length 4 + #define controller_string_with_length 4 #define controller_string_yes_length 3 const static f_string_t controller_string_action_s = controller_string_action; @@ -221,6 +225,7 @@ extern "C" { const static f_string_t controller_string_fifo_s = controller_string_fifo; const static f_string_t controller_string_freeze_s = controller_string_freeze; const static f_string_t controller_string_fsize_s = controller_string_fsize; + const static f_string_t controller_string_full_path_s = controller_string_full_path; const static f_string_t controller_string_group_s = controller_string_group; const static f_string_t controller_string_groups_s = controller_string_groups; const static f_string_t controller_string_how_s = controller_string_how; @@ -279,6 +284,7 @@ extern "C" { const static f_string_t controller_string_wait_s = controller_string_wait; const static f_string_t controller_string_want_s = controller_string_want; const static f_string_t controller_string_wish_s = controller_string_wish; + const static f_string_t controller_string_with_s = controller_string_with; const static f_string_t controller_string_yes_s = controller_string_yes; #endif // _di_controller_string_ @@ -494,6 +500,7 @@ extern "C" { controller_rule_action_type_thaw, controller_rule_action_type_use, controller_rule_action_type_user, + controller_rule_action_type_with, }; typedef struct { diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index d15789f..9a203c3 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -178,6 +178,11 @@ extern "C" { buffer.string = controller_string_user_s; buffer.used = controller_string_user_length; break; + + case controller_rule_action_type_with: + buffer.string = controller_string_with_s; + buffer.used = controller_string_with_length; + break; } buffer.size = buffer.used; @@ -768,6 +773,8 @@ extern "C" { f_string_dynamic_t *pid_file = 0; uint8_t pid_type = 0; + bool with_full_path = F_false; + // child processes should receive all signals and handle the signals as they see fit. f_signal_how_t signals = f_signal_how_t_initialize; f_signal_set_empty(&signals.block); @@ -838,6 +845,24 @@ extern "C" { if (process->rule.items.array[i].type == controller_rule_item_type_setting) continue; + with_full_path = F_false; + + for (j = 0; j < process->rule.items.array[i].actions.used; ++j) { + + if (process->rule.items.array[i].actions.array[j].type == controller_rule_action_type_with) { + for (k = 0; k < process->rule.items.array[i].actions.array[j].parameters.used; ++k) { + + if (fl_string_dynamic_compare_string(controller_string_full_path_s, process->rule.items.array[i].actions.array[j].parameters.array[k], controller_string_full_path_length) == F_equal_to) { + with_full_path = F_true; + + break; + } + } // for + + if (with_full_path) break; + } + } // for + for (j = 0; j < process->rule.items.array[i].actions.used; ++j) { if (!main.thread->enabled) { @@ -850,12 +875,11 @@ extern "C" { execute_set.parameter.data = 0; execute_set.parameter.option = fl_execute_parameter_option_threadsafe | fl_execute_parameter_option_return; - if (process->rule.items.array[i].type == controller_rule_item_type_command) { - - if (strchr(process->rule.items.array[i].actions.array[j].parameters.array[0].string, f_path_separator_s[0])) { - execute_set.parameter.option |= fl_execute_parameter_option_path; - } + if (with_full_path) { + execute_set.parameter.option |= fl_execute_parameter_option_path; + } + if (process->rule.items.array[i].type == controller_rule_item_type_command) { status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], 0, process->rule.items.array[i].actions.array[j].parameters, options, main, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; @@ -872,13 +896,8 @@ extern "C" { } } else if (process->rule.items.array[i].type == controller_rule_item_type_script) { - execute_set.parameter.data = &process->rule.items.array[i].actions.array[j].parameters.array[0]; - if (process->rule.script.used && strchr(process->rule.script.string, f_path_separator_s[0])) { - execute_set.parameter.option |= fl_execute_parameter_option_path; - } - status = controller_rule_execute_foreground(process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, main, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; @@ -895,7 +914,6 @@ extern "C" { } } else if (process->rule.items.array[i].type == controller_rule_item_type_service) { - pid_file = 0; pid_type = 0; @@ -914,10 +932,6 @@ extern "C" { } // for if (pid_file) { - if (strchr(process->rule.items.array[i].actions.array[j].parameters.array[0].string, f_path_separator_s[0])) { - execute_set.parameter.option |= fl_execute_parameter_option_path; - } - status = controller_rule_execute_pid_with(pid_file, pid_type, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], 0, process->rule.items.array[i].actions.array[j].parameters, options, main, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; @@ -941,7 +955,6 @@ extern "C" { } } else if (process->rule.items.array[i].type == controller_rule_item_type_utility) { - pid_file = 0; pid_type = 0; @@ -962,10 +975,6 @@ extern "C" { if (pid_file) { execute_set.parameter.data = &process->rule.items.array[i].actions.array[j].parameters.array[0]; - if (process->rule.script.used && strchr(process->rule.script.string, f_path_separator_s[0])) { - execute_set.parameter.option |= fl_execute_parameter_option_path; - } - status = controller_rule_execute_pid_with(pid_file, pid_type, process->rule.items.array[i].type, process->rule.items.array[i].actions.array[j], process->rule.script.used ? process->rule.script.string : controller_default_program_script, arguments_none, options, main, &execute_set, process); if (status == F_child || status == F_signal || F_status_set_fine(status) == F_lock) break; @@ -1334,6 +1343,8 @@ extern "C" { if (!WIFEXITED(result)) { status = F_status_set_error(F_failure); } + + // @fixme needs a custom option to desginate what is an error. } else { if (!main.thread->enabled) { @@ -1526,6 +1537,9 @@ extern "C" { else if (fl_string_dynamic_compare_string(controller_string_user_s, cache->action.name_action, controller_string_user_length) == F_equal_to) { type = controller_rule_action_type_user; } + else if (fl_string_dynamic_compare_string(controller_string_with_s, cache->action.name_action, controller_string_with_length) == F_equal_to) { + type = controller_rule_action_type_with; + } else { if (main.data->warning.verbosity == f_console_verbosity_debug) { f_thread_mutex_lock(&main.thread->lock.print); @@ -1819,7 +1833,7 @@ extern "C" { } if ((process->options & controller_process_option_simulate) && main.data->parameters[controller_parameter_validate].result == f_console_result_found) { - controller_rule_validate(process->rule, controller_rule_action_type_start, process->options, main, &process->cache); + controller_rule_validate(process->rule, action, process->options, main, &process->cache); } f_array_length_t i = 0; @@ -1991,7 +2005,7 @@ extern "C" { } // synchronously execute dependency. - status = controller_rule_process_begin(0, alias_other, controller_rule_action_type_start, options_process, process->stack, main, process_other->cache); + status = controller_rule_process_begin(0, alias_other, action, options_process, process->stack, main, process_other->cache); if (status == F_child || status == F_signal) { f_thread_unlock(&process_other->active); @@ -2594,6 +2608,7 @@ extern "C" { } if (F_status_is_error_not(status)) { + // @todo this needs to support passing different (supported) types, particularly when the "control" is written, (an entry will always send start and an exit will always send stop). status = controller_rule_process(controller_rule_action_type_start, main, process); } } diff --git a/level_3/controller/data/settings/example/rules/service/sshd.rule b/level_3/controller/data/settings/example/rules/service/sshd.rule index f044d7f..2961de4 100644 --- a/level_3/controller/data/settings/example/rules/service/sshd.rule +++ b/level_3/controller/data/settings/example/rules/service/sshd.rule @@ -10,4 +10,5 @@ setting: service: use /var/run/sshd.pid - start /usr/sbin/sshd + with full_path + start sshd diff --git a/level_3/controller/documents/rule.txt b/level_3/controller/documents/rule.txt index b0bf63e..8726e04 100644 --- a/level_3/controller/documents/rule.txt +++ b/level_3/controller/documents/rule.txt @@ -89,3 +89,8 @@ Rule Documentation: The "create" Content designates that this controller program to create the PID file after successfully starting a Service or Utility. The "use" Content designates that the called program will provide the PID file after successfully starting the Service or Utility. For both "create" and "program" the PID file is expected to only exist on success and the existence thereof designates the success or failure. + + The "with" Content designates special flags designating very specific behavior to be applied to any single Rule Type. + The following flags are supported: + "full_path": Used only by Rule Types that execute something, wherein the entire full path is used for execution and is assigned as argument[0] (such as "/bin/bash"). + When not specified, the path provided is used and the argument[0] will be the base name (such as "bash"). diff --git a/level_3/controller/specifications/rule.txt b/level_3/controller/specifications/rule.txt index 63b19c6..c880022 100644 --- a/level_3/controller/specifications/rule.txt +++ b/level_3/controller/specifications/rule.txt @@ -47,10 +47,6 @@ Rule Specification: "want": Two Content, the first being a partial path and the second being a rule file name without extension (such as "boot" "modules"). "wish": Two Content, the first being a partial path and the second being a rule file name without extension (such as "boot" "modules"). - The "service" and "utility" Rule Types allow the following the FSS-0001 (Extended)\: - "create": One Content representing the path to a PID file. - "use": One Content representing the path to a PID file. - The "command" and "script" Rule Types allow the following the FSS-0001 (Extended)\: "kill": One or more Content representing a program being executed and its arguments. "pause": One or more Content representing a program being executed and its arguments. @@ -59,6 +55,12 @@ Rule Specification: "resume": One or more Content representing a program being executed and its arguments. "start": One or more Content representing a program being executed and its arguments. "stop": One or more Content representing a program being executed and its arguments. + "with": One or more Content representing special options for the Rule Type. + + The "service" and "utility" Rule Types allow the following the FSS-0001 (Extended)\: + "create": One Content representing the path to a PID file. + "use": One Content representing the path to a PID file. + "with": One or more Content representing special options for the Rule Type. The "command" and "service" Rule Types allow the following the FSS-0003 (Extended List)\: "kill": A list repesenting multiple programs and their respective arguments to execute. -- 1.8.3.1