diff -urN upstart-0.3.8-orig/compat/sysv/man/reboot.8 upstart-0.3.8/compat/sysv/man/reboot.8 --- upstart-0.3.8-orig/compat/sysv/man/reboot.8 2007-03-09 17:03:02.000000000 +0000 +++ upstart-0.3.8/compat/sysv/man/reboot.8 2007-05-27 16:53:53.000000000 +0100 @@ -23,6 +23,16 @@ .\" .SH OPTIONS .TP +.BR -m, "--host "\fIHOST +Specify the host that you belive you are rebooting. This is required +when called from a terminal unless overridden with --nohostcheck. +.\" +.TP +.BR --nohostcheck +Allow the action to be performed even with no hostname specified +even when used on a terminal. +.\" +.TP .BR -f Does not invoke .BR shutdown (8) diff -urN upstart-0.3.8-orig/compat/sysv/man/shutdown.8 upstart-0.3.8/compat/sysv/man/shutdown.8 --- upstart-0.3.8-orig/compat/sysv/man/shutdown.8 2007-03-09 17:12:57.000000000 +0000 +++ upstart-0.3.8/compat/sysv/man/shutdown.8 2007-05-27 16:54:08.000000000 +0100 @@ -35,6 +35,16 @@ .\" .SH OPTIONS .TP +.BR -m, "--host "\fIHOST +Specify the host that you belive you are shutting down. This is required +when called from a terminal unless overridden with --nohostcheck. +.\" +.TP +.BR --nohostcheck +Allow the action to be performed even with no hostname specified +even when used on a terminal. +.\" +.TP .BR -r Requests that the system be rebooted after it has been brought down. .\" diff -urN upstart-0.3.8-orig/compat/sysv/reboot.c upstart-0.3.8/compat/sysv/reboot.c --- upstart-0.3.8-orig/compat/sysv/reboot.c 2007-03-09 17:00:51.000000000 +0000 +++ upstart-0.3.8/compat/sysv/reboot.c 2007-05-27 16:26:18.000000000 +0100 @@ -89,6 +89,19 @@ /** + * host + * + * The name of the host the user belives they are bringing down. + **/ +static char* host = NULL; + +/** + * no_host_check: + * TRUE if user has specified not to check host. + **/ +static int no_host_check = FALSE; + +/** * no_sync: * * TRUE if we do not wish to call sync() before reboot(). @@ -130,13 +143,16 @@ **/ static int exit_only = FALSE; - /** * options: * * Command-line options accepted. **/ static NihOption options[] = { + { 'm', "host", N_("specify the host you believe you want to reboot"), + NULL, "HOST", &host, NULL }, + { 0, "nohostcheck", N_("Don't require a host name even on a tty"), + NULL, NULL, &no_host_check, NULL }, { 'n', NULL, N_("don't sync before reboot or halt"), NULL, NULL, &no_sync, NULL }, { 'f', NULL, N_("force reboot or halt, don't call shutdown(8)"), @@ -185,6 +201,9 @@ "to reboot or halt the system; when run without the -f " "option it will actually execute /sbin/shutdown.\n" "\n" + "If called from a terminal the host you believe is " + "being rebooted must be specified with -m/--host.\n" + "\n" "Before the system is rebooted or halted, the disks are " "syncd; this can be avoided by giving -n.\n" "\n" @@ -197,6 +216,31 @@ if (! args) exit (1); + /* Check they specified the host name */ + if (host) { + /* The comments in uname(2) seem to suggest using gethostname. + * The comments in gethostname(2) tell you glibc implements it + * using uname(2). + */ + char hostname[HOST_NAME_MAX+1]; + if (gethostname(hostname, HOST_NAME_MAX+1)) { + nih_fatal (_("Unable to got hostname: %s"), + strerror (errno)); + exit (1); + } + if (strcmp(host,hostname)) { + nih_fatal (_("The hostname you gave '%s', does not match the system hostname: '%s'"), + host, hostname); + exit (1); + } + } else { + /* They didn't specify a hostname */ + if ((isatty(0)) && !no_host_check) { + nih_fatal (_("You must specify the host you think you are rebooting with -m/--host")); + exit (1); + }; + } /* hostname checks */ + /* Check we're root */ setuid (geteuid ()); if (getuid ()) { @@ -220,6 +264,8 @@ int i = 0; args[i++] = SHUTDOWN; + /* since we've already done the check */ + args[i++] = "--nohostcheck"; switch (mode) { case REBOOT: diff -urN upstart-0.3.8-orig/compat/sysv/shutdown.c upstart-0.3.8/compat/sysv/shutdown.c --- upstart-0.3.8-orig/compat/sysv/shutdown.c 2007-03-09 12:49:21.000000000 +0000 +++ upstart-0.3.8/compat/sysv/shutdown.c 2007-05-27 16:49:45.000000000 +0100 @@ -99,6 +99,19 @@ /** + * host + * + * The name of the host the user belives they are bringing down. + **/ +static char* host = NULL; + +/** + * no_host_check: + * TRUE if user has specified not to check host. + **/ +static int no_host_check = FALSE; + +/** * runlevel: * * Runlevel to switch to. @@ -155,6 +168,10 @@ * Command-line options accepted for all arguments. **/ static NihOption options[] = { + { 'm', "host", N_("specify the host you believe you want to shutdown"), + NULL, "HOST", &host, NULL }, + { 0, "nohostcheck", N_("Don't require a host name even on a tty"), + NULL, NULL, &no_host_check, NULL }, { 'r', NULL, N_("reboot after shutdown"), NULL, NULL, &runlevel, runlevel_setter }, { 'h', NULL, N_("halt or power off after shutdown"), @@ -214,6 +231,9 @@ "foreground until the shutdown occurs. It can be cancelled " "by Control-C, or by another user using the -c option.\n" "\n" + "If called from a terminal the host you believe is " + "being rebooted must be specified with -m/--host.\n" + "\n" "The system is brought down into maintenance (single-user) " "mode by default, you can change this with either the -r or " "-h option which specify a reboot or system halt " @@ -248,6 +268,34 @@ arg = 0; } + /* Check they specified the host name */ + if (host) { + /* The comments in uname(2) seem to suggest using gethostname. + * The comments in gethostname(2) tell you glibc implements it + * using uname(2). + */ + char hostname[HOST_NAME_MAX+1]; + if (gethostname(hostname, HOST_NAME_MAX+1)) { + nih_fatal (_("Unable to got hostname: %s"), + strerror (errno)); + exit (1); + } + if (strcmp(host,hostname)) { + nih_fatal (_("The hostname you gave '%s', does not match the system hostname: '%s'"), + host, hostname); + exit (1); + } + } else { + /* They didn't specify a hostname, but we will let them get away with it if + * they ask us to, it isn't a tty or we're just canceling an + * existing shutdown or just giving a warning + */ + if ((isatty(0)) && !no_host_check && !cancel && !warn_only) { + nih_fatal (_("You must specify the host you think you are shutting down with -m/--host")); + exit (1); + }; + } /* hostname checks */ + /* Parse the time argument */ if (when) { if (! strcmp (when, "now")) {