]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add possibility to set action for ctrl-alt-del burst (#4105)
authorLukáš Nykrýn <lnykryn@redhat.com>
Fri, 7 Oct 2016 01:08:21 +0000 (03:08 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 7 Oct 2016 01:08:21 +0000 (21:08 -0400)
For some certification, it should not be possible to reboot the machine through ctrl-alt-delete. Currently we suggest our customers to mask the ctrl-alt-delete target, but that is obviously not enough.

Patching the keymaps to disable that is really not a way to go for them, because the settings need to be easily checked by some SCAP tools.

man/systemd-system.conf.xml
src/core/main.c
src/core/manager.c
src/core/manager.h
src/core/system.conf

index 1bb40fd234aac4b34b3001fd2c675cb20bf801c5..a268397d09ba77e08f0508fd46aae4ff262003cf 100644 (file)
         arguments.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>CtrlAltDelBurstAction=</varname></term>
+
+        <listitem><para>Defines what action will be performed
+        if user presses Ctr-Alt-Delete more than 7 times in 2s.
+        Can be set to <literal>reboot-force</literal>, <literal>poweroff-force</literal>
+        or disabled with <literal>ignore</literal>. Defaults to
+        <literal>reboot-force</literal>.
+        </para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>CPUAffinity=</varname></term>
 
index be0cb0b6d1da78c2121c7d247ca8da19c160bd59..6fe440277ecca6237aad07ff04cf3017b6ff5f18 100644 (file)
@@ -131,6 +131,7 @@ static bool arg_default_memory_accounting = false;
 static bool arg_default_tasks_accounting = true;
 static uint64_t arg_default_tasks_max = UINT64_MAX;
 static sd_id128_t arg_machine_id = {};
+static CADBurstAction arg_cad_burst_action = CAD_BURST_ACTION_REBOOT;
 
 noreturn static void freeze_or_reboot(void) {
 
@@ -648,6 +649,8 @@ static int config_parse_join_controllers(const char *unit,
         return 0;
 }
 
+static DEFINE_CONFIG_PARSE_ENUM(config_parse_cad_burst_action, cad_burst_action, CADBurstAction, "Failed to parse service restart specifier");
+
 static int parse_config_file(void) {
 
         const ConfigTableItem items[] = {
@@ -702,6 +705,7 @@ static int parse_config_file(void) {
                 { "Manager", "DefaultMemoryAccounting",   config_parse_bool,             0, &arg_default_memory_accounting         },
                 { "Manager", "DefaultTasksAccounting",    config_parse_bool,             0, &arg_default_tasks_accounting          },
                 { "Manager", "DefaultTasksMax",           config_parse_tasks_max,        0, &arg_default_tasks_max                 },
+                { "Manager", "CtrlAltDelBurstAction",     config_parse_cad_burst_action, 0, &arg_cad_burst_action},
                 {}
         };
 
@@ -1794,6 +1798,7 @@ int main(int argc, char *argv[]) {
         m->initrd_timestamp = initrd_timestamp;
         m->security_start_timestamp = security_start_timestamp;
         m->security_finish_timestamp = security_finish_timestamp;
+        m->cad_burst_action = arg_cad_burst_action;
 
         manager_set_defaults(m);
         manager_set_show_status(m, arg_show_status);
index dd0d1fa984cb2ff1106fa81c417f1106ad812de2..5253cb3712a35650b0d42179879044ad4473a501 100644 (file)
@@ -1894,6 +1894,35 @@ static int manager_start_target(Manager *m, const char *name, JobMode mode) {
         return r;
 }
 
+static void manager_handle_ctrl_alt_del(Manager *m) {
+        /* If the user presses C-A-D more than
+         * 7 times within 2s, we reboot/shutdown immediately,
+         * unless it was disabled in system.conf */
+
+        if (ratelimit_test(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == CAD_BURST_ACTION_IGNORE)
+                manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
+        else {
+                switch (m->cad_burst_action) {
+
+                case CAD_BURST_ACTION_REBOOT:
+                        m->exit_code = MANAGER_REBOOT;
+                        break;
+
+                case CAD_BURST_ACTION_POWEROFF:
+                        m->exit_code = MANAGER_POWEROFF;
+                        break;
+
+                default:
+                        assert_not_reached("Unknown action.");
+                }
+
+                log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, performing immediate %s.",
+                                cad_burst_action_to_string(m->cad_burst_action));
+                status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, performing immediate %s.",
+                                cad_burst_action_to_string(m->cad_burst_action));
+        }
+}
+
 static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
         Manager *m = userdata;
         ssize_t n;
@@ -1945,19 +1974,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
 
                 case SIGINT:
                         if (MANAGER_IS_SYSTEM(m)) {
-
-                                /* If the user presses C-A-D more than
-                                 * 7 times within 2s, we reboot
-                                 * immediately. */
-
-                                if (ratelimit_test(&m->ctrl_alt_del_ratelimit))
-                                        manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY);
-                                else {
-                                        log_notice("Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
-                                        status_printf(NULL, true, false, "Ctrl-Alt-Del was pressed more than 7 times within 2s, rebooting immediately.");
-                                        m->exit_code = MANAGER_REBOOT;
-                                }
-
+                                manager_handle_ctrl_alt_del(m);
                                 break;
                         }
 
@@ -3544,3 +3561,11 @@ static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);
+
+static const char *const cad_burst_action_table[_CAD_BURST_ACTION_MAX] = {
+        [CAD_BURST_ACTION_IGNORE] = "ignore",
+        [CAD_BURST_ACTION_REBOOT] = "reboot-force",
+        [CAD_BURST_ACTION_POWEROFF] = "poweroff-force",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(cad_burst_action, CADBurstAction);
index a592f1cb941a5010f9528dc66e4b51305cbdf037..495440b44624a33f522676ec8d6d884e95bdbcfe 100644 (file)
@@ -62,6 +62,14 @@ typedef enum ManagerExitCode {
         _MANAGER_EXIT_CODE_INVALID = -1
 } ManagerExitCode;
 
+typedef enum CADBurstAction {
+        CAD_BURST_ACTION_IGNORE,
+        CAD_BURST_ACTION_REBOOT,
+        CAD_BURST_ACTION_POWEROFF,
+        _CAD_BURST_ACTION_MAX,
+        _CAD_BURST_ACTION_INVALID = -1
+} CADBurstAction;
+
 typedef enum StatusType {
         STATUS_TYPE_EPHEMERAL,
         STATUS_TYPE_NORMAL,
@@ -304,8 +312,9 @@ struct Manager {
         Hashmap *uid_refs;
         Hashmap *gid_refs;
 
-        /* When the user hits C-A-D more than 7 times per 2s, reboot immediately... */
+        /* When the user hits C-A-D more than 7 times per 2s, do something immediately... */
         RateLimit ctrl_alt_del_ratelimit;
+        CADBurstAction cad_burst_action;
 
         const char *unit_log_field;
         const char *unit_log_format_string;
@@ -398,3 +407,6 @@ void manager_deserialize_gid_refs_one(Manager *m, const char *value);
 
 const char *manager_state_to_string(ManagerState m) _const_;
 ManagerState manager_state_from_string(const char *s) _pure_;
+
+const char *cad_burst_action_to_string(CADBurstAction a) _const_;
+CADBurstAction cad_burst_action_from_string(const char *s) _pure_;
index c6bb050aaccce4bc1524f8b85c31240dc4897e68..746572b7ff25db7c0c54028a3a2b49ce9a152777 100644 (file)
@@ -21,6 +21,7 @@
 #CrashChangeVT=no
 #CrashShell=no
 #CrashReboot=no
+#CtrlAltDelBurstAction=reboot-force
 #CPUAffinity=1 2
 #JoinControllers=cpu,cpuacct net_cls,net_prio
 #RuntimeWatchdogSec=0