Adding upstream version 0.8.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
c44f6858f9
commit
47ba6c9762
6 changed files with 688 additions and 0 deletions
49
Makefile
Normal file
49
Makefile
Normal file
|
@ -0,0 +1,49 @@
|
|||
PREFIX?=/usr
|
||||
cfgdir?=/etc/molly-guard
|
||||
libdir?=$(PREFIX)/lib
|
||||
sbindir?=$(PREFIX)/sbin
|
||||
REALPATH?=$(libdir)/molly-guard
|
||||
|
||||
all: molly-guard.8 shutdown
|
||||
|
||||
%.8: DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl
|
||||
%.8: XP=xsltproc -''-nonet
|
||||
%.8: %.xml
|
||||
$(XP) $(DB2MAN) $<
|
||||
|
||||
man: molly-guard.8
|
||||
man -l $<
|
||||
.PHONY: man
|
||||
|
||||
clean:
|
||||
rm -f shutdown
|
||||
rm -f molly-guard.8
|
||||
.PHONY: clean
|
||||
|
||||
shutdown: shutdown.in
|
||||
sed -e 's,@cfgdir@,$(cfgdir),g;s,@REALPATH@,$(REALPATH),g' $< > $@
|
||||
|
||||
install: shutdown molly-guard.8
|
||||
mkdir -m755 --parent $(DESTDIR)$(libdir)/molly-guard
|
||||
install -m755 -oroot -oroot shutdown $(DESTDIR)$(libdir)/molly-guard/molly-guard
|
||||
|
||||
mkdir -m755 --parent $(DESTDIR)$(sbindir)
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/poweroff
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/halt
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/reboot
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/shutdown
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/coldreboot
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/pm-hibernate
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/pm-suspend
|
||||
ln -s $(libdir)/molly-guard/molly-guard $(DESTDIR)$(sbindir)/pm-suspend-hybrid
|
||||
|
||||
mkdir -m755 --parent $(DESTDIR)$(cfgdir)
|
||||
install -m644 -oroot -oroot rc $(DESTDIR)$(cfgdir)
|
||||
cp -r run.d $(DESTDIR)$(cfgdir) \
|
||||
&& chown root.root $(DESTDIR)$(cfgdir)/run.d && chmod 755 $(DESTDIR)$(cfgdir)/run.d
|
||||
|
||||
mkdir -m755 --parent $(DESTDIR)$(cfgdir)/messages.d
|
||||
|
||||
mkdir -m755 --parent $(DESTDIR)$(PREFIX)/share/man/man8
|
||||
install -m644 -oroot -groot molly-guard.8 $(DESTDIR)$(PREFIX)/share/man/man8
|
||||
.PHONY: install
|
344
molly-guard.xml
Normal file
344
molly-guard.xml
Normal file
|
@ -0,0 +1,344 @@
|
|||
<?xml version='1.0' encoding='ISO-8859-1'?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!--
|
||||
|
||||
Process this file with an XSLT processor: `xsltproc \
|
||||
-''-nonet /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
|
||||
manpages/docbook.xsl manpage.dbk'. A manual page
|
||||
<package>.<section> will be generated. You may view the
|
||||
manual page with: nroff -man <package>.<section> | less'. A
|
||||
typical entry in a Makefile or Makefile.am is:
|
||||
|
||||
DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
|
||||
manpages/docbook.xsl
|
||||
XP=xsltproc -''-nonet
|
||||
|
||||
manpage.1: manpage.dbk
|
||||
$(XP) $(DB2MAN) $<
|
||||
|
||||
The xsltproc binary is found in the xsltproc package. The
|
||||
XSL files are in docbook-xsl. Please remember that if you
|
||||
create the nroff version in one of the debian/rules file
|
||||
targets (such as build), you will need to include xsltproc
|
||||
and docbook-xsl in your Build-Depends control field.
|
||||
|
||||
-->
|
||||
|
||||
<!-- Fill in your name for FIRSTNAME and SURNAME. -->
|
||||
<!ENTITY dhfirstname "<firstname>martin f.</firstname>">
|
||||
<!ENTITY dhsurname "<surname>krafft</surname>">
|
||||
<!-- Please adjust the date whenever revising the manpage. -->
|
||||
<!ENTITY dhdate "<date>Apr 19, 2008</date>">
|
||||
<!-- SECTION should be 1-8, maybe w/ subsection other parameters are
|
||||
allowed: see man(7), man(1). -->
|
||||
<!ENTITY dhsection "<manvolnum>8</manvolnum>">
|
||||
<!ENTITY dhemail "<email>madduck@madduck.net</email>">
|
||||
<!ENTITY dhusername "martin f. krafft">
|
||||
<!ENTITY dhucpackage "<refentrytitle>molly-guard</refentrytitle>">
|
||||
<!ENTITY dhpackage "molly-guard">
|
||||
<!ENTITY dhcommand "<command>molly-guard</command>">
|
||||
|
||||
<!ENTITY debian "<productname>Debian</productname>">
|
||||
<!ENTITY gnu "<acronym>GNU</acronym>">
|
||||
<!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
|
||||
]>
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<address>
|
||||
&dhemail;
|
||||
</address>
|
||||
<copyright>
|
||||
<year>2008</year>
|
||||
<holder>&dhusername;</holder>
|
||||
</copyright>
|
||||
&dhdate;
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
&dhucpackage;
|
||||
|
||||
&dhsection;
|
||||
</refmeta>
|
||||
<refnamediv>
|
||||
<refname>&dhcommand;</refname>
|
||||
|
||||
<refpurpose>guard against accidental shutdowns/reboots</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>shutdown</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>halt</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>reboot</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>poweroff</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>coldreboot</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>pm-hibernate</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>pm-suspend</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>pm-suspend-hybrid</command>
|
||||
<arg choice="opt">
|
||||
-<option>hV</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
<option>--molly-guard-do-nothing</option>
|
||||
</arg>
|
||||
<arg choice="opt">
|
||||
-- <replaceable>script_options</replaceable>
|
||||
</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>DESCRIPTION</title>
|
||||
|
||||
<para> &dhcommand; attempts to prevent you from accidentally shutting down
|
||||
or rebooting machines. It does this by injecting a couple of checks
|
||||
before the existing commands: <command>coldreboot</command>,
|
||||
<command>halt</command>, <command>reboot</command>,
|
||||
<command>shutdown</command>, <command>poweroff</command>,
|
||||
<command>pm-hibernate</command>,<command>pm-suspend</command>
|
||||
and <command>pm-suspend-hybrid</command>.</para>
|
||||
|
||||
<para> Before &dhcommand; invokes the real command, all scripts in
|
||||
<filename>/etc/molly-guard/run.d/</filename> have to run and exit
|
||||
successfully; else, it aborts the command.
|
||||
<command>run-parts(1)</command> is used to process the directory.</para>
|
||||
|
||||
<para> &dhcommand; passes any <replaceable>script_options</replaceable> to the
|
||||
scripts, and also populates the environment with the following
|
||||
variables:</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><envar>MOLLYGUARD_CMD</envar> - the actual command
|
||||
invoked by the user.</para></listitem>
|
||||
|
||||
<listitem><para><envar>MOLLYGUARD_DO_NOTHING</envar> - set to
|
||||
<option>1</option> if this is a demo-run.</para></listitem>
|
||||
|
||||
<listitem><para><envar>MOLLYGUARD_SETTINGS</envar> - the path to
|
||||
a shell script snippet which scripts can source to obtain
|
||||
settings.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para> &dhcommand; prints the contents of
|
||||
<filename>/etc/molly-guard/messages.d/COMMAND</filename> or
|
||||
<filename>/etc/molly-guard/messages.d/default</filename> to the console,
|
||||
if either exists. This is due to
|
||||
<filename>/etc/molly-guard/run.d/10-print-message</filename>.</para>
|
||||
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>GUARDING SSH SESSIONS</title>
|
||||
|
||||
<para> &dhcommand; was primarily designed to shield SSH connections. This
|
||||
functionality (which should arguably be provided by the
|
||||
<package>openssh-server</package> package) is implemented in
|
||||
<filename>/etc/molly-guard/run.d/30-query-hostname</filename>.</para>
|
||||
|
||||
<para> This script first tests whether the command is being executed from
|
||||
a <filename>tty</filename> which has been created by
|
||||
<command>sshd</command>. It also checks whether the variable
|
||||
<envar>SSH_CONNECTION</envar> is defined. If any of these tests are
|
||||
successful, test script queries the user for the machine's hostname,
|
||||
which should be sufficient to prevent the user from doing something by
|
||||
accident.</para>
|
||||
|
||||
<para> You can pass the <option>--pretend-ssh</option> script option to
|
||||
&dhcommand; to pretend that those tests succeeds. Alternatively, setting
|
||||
<envar>ALWAYS_QUERY_HOSTNAME</envar> in
|
||||
<filename>/etc/molly-guard/rc</filename> causes the script to
|
||||
always query.</para>
|
||||
|
||||
<para> The following situations are still UNGUARDED. If you can think of
|
||||
ways to protect against those, please let me know!</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>running <application>sudo</application> within
|
||||
<application>screen</application> or <application>screen</application> within
|
||||
<application>sudo</application>; <application>sudo</application> eats the
|
||||
<envar>SSH_CONNECTION</envar> variable, and
|
||||
<application>screen</application> creates a new
|
||||
<filename>pty</filename>.</para></listitem>
|
||||
<listitem><para>executing those command in a remote terminal window,
|
||||
that is a <application>XTerm</application> started on a remote
|
||||
machine but displaying on the local <application>X</application>
|
||||
server.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para> You have been warned. You can use the
|
||||
<option>--molly-guard-do-nothing</option> switch to prevent anything
|
||||
from happening, e.g. <userinput>halt
|
||||
--molly-guard-do-nothing</userinput>. </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>OPTIONS</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>--molly-guard-do-nothing</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Cause &dhcommand; to print the command which would be executed,
|
||||
after processing all scripts, instead of executing it.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<term>--help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display usage information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-V</term>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display version information.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>SEE ALSO</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>shutdown</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
<citerefentry>
|
||||
<refentrytitle>halt</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>,
|
||||
<citerefentry>
|
||||
<refentrytitle>reboot</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>,
|
||||
<citerefentry>
|
||||
<refentrytitle>poweroff</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>.
|
||||
<citerefentry>
|
||||
<refentrytitle>coldreboot</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>.
|
||||
<citerefentry>
|
||||
<refentrytitle>pm-hibernate</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>.
|
||||
<citerefentry>
|
||||
<refentrytitle>pm-suspend</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>.
|
||||
<citerefentry>
|
||||
<refentrytitle>pm-suspend-hybrid</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</citerefentry>.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>LEGALESE</title>
|
||||
|
||||
<para>
|
||||
&dhpackage; is copyright by &dhusername;. Andrew Ruthven came up with
|
||||
the idea of using the scripts directory and submitted a patch, which
|
||||
I modified a bit.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This manual page was written by &dhusername; &dhemail;.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the Artistic License 2.0
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
19
rc
Normal file
19
rc
Normal file
|
@ -0,0 +1,19 @@
|
|||
# molly-guard settings
|
||||
#
|
||||
# ALWAYS_QUERY_HOSTNAME
|
||||
# When set, causes the 30-query-hostname script to always ask for the
|
||||
# hostname, even if no SSH session was detected.
|
||||
#ALWAYS_QUERY_HOSTNAME=true
|
||||
|
||||
# USE_FQDN
|
||||
# When set, causes the 30-query-hostname script to ask for the fully-qualified
|
||||
# hostname, rather than the short name
|
||||
#USE_FQDN=true
|
||||
|
||||
# ANSIBLE_SEARCH_STRING
|
||||
# The string to search for in the broadcast message provided to shutdown
|
||||
# set by Ansible. Used to detect if Ansible has initiated a reboot via
|
||||
# the ansible.builtin.reboot module the default message is "Reboot initiated
|
||||
# by Ansible" but can be changed by setting the "msg" parameter. This is
|
||||
# a case insensitive search.
|
||||
#ANSIBLE_SEARCH_STRING="ansible"
|
22
run.d/10-print-message
Executable file
22
run.d/10-print-message
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# 10-print-message - print a (command-specific or default) message
|
||||
#
|
||||
# Copyright © Andrew Ruthven <andrew@etc.gen.nz>
|
||||
# Copyright © martin f. krafft <madduck@madduck.net>
|
||||
# Released under the terms of the Artistic Licence 2.0
|
||||
#
|
||||
# Prints either /etc/molly-guard/messages.d/$MOLLYGUARD_CMD
|
||||
# or /etc/molly-guard/messages.d/default
|
||||
# depending on whether the first exists.
|
||||
#
|
||||
set -eu
|
||||
|
||||
MESSAGESDIR=/etc/molly-guard/messages.d
|
||||
|
||||
for i in $MOLLYGUARD_CMD default; do
|
||||
if [ -f "$MESSAGESDIR/$i" ] && [ -r "$MESSAGESDIR/$i" ]; then
|
||||
cat $MESSAGESDIR/$i
|
||||
exit 0
|
||||
fi
|
||||
done
|
102
run.d/30-query-hostname
Executable file
102
run.d/30-query-hostname
Executable file
|
@ -0,0 +1,102 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# 30-ask-hostname - request the user to type in the hostname of the local host
|
||||
#
|
||||
# Copyright © 2006-2009 martin f. krafft <madduck@madduck.net>
|
||||
# Copyright © 2012 Ludovico Gardenghi <lu@dovi.co>
|
||||
# Copyright © 2014 Josh Triplett <josh@joshtriplett.org>
|
||||
# Copyright © 2015 Francois Marier <francois@debian.org>
|
||||
# Copyright © 2017 Simó Albert i Beltran <sim6@probeta.net>
|
||||
# Copyright © 2023 Andrew Ruthven <andrew@etc.gen.nz>
|
||||
# Released under the terms of the Artistic Licence 2.0
|
||||
#
|
||||
set -eu
|
||||
|
||||
ME=molly-guard
|
||||
|
||||
# Skip if we're being run by configuration management.
|
||||
[ $CONFIGURATION_MANAGEMENT -eq 1 ] && exit 0
|
||||
|
||||
# Walk up the process tree until PID 1 is reached or a process with 'sshd' in
|
||||
# its /proc/<pid>/cmdline is met. Return success if such a process is found.
|
||||
is_child_of_sshd_or_mosh_server() {
|
||||
pid=$$
|
||||
ppid=$PPID
|
||||
# Be a bit paranoid with the guard, should some horribly broken system
|
||||
# provide a strange process hierarchy. '[ $pid -ne 1 ]' should be enough for
|
||||
# sane systems.
|
||||
[ -z "$pid" ] || [ -z "$ppid" ] && return 2
|
||||
while [ $pid -gt 1 ] && [ $pid -ne $ppid ]; do
|
||||
if egrep -q 'sshd|mosh-server|etterminal' /proc/$ppid/cmdline; then
|
||||
return 0
|
||||
fi
|
||||
pid=$ppid
|
||||
ppid=$(grep ^PPid: /proc/$pid/status | tr -dc 0-9)
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
[ -f "$MOLLYGUARD_SETTINGS" ] && . "$MOLLYGUARD_SETTINGS"
|
||||
|
||||
PRETEND_SSH=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
(*-pretend-ssh) PRETEND_SSH=1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# require an interactive terminal connected to stdin
|
||||
test -t 0 || exit 0
|
||||
|
||||
# we've been asked to always protect this host
|
||||
case "${ALWAYS_QUERY_HOSTNAME:-0}" in
|
||||
0|false|False|no|No|off|Off)
|
||||
# only run if we are being called over SSH, that is if the current terminal
|
||||
# was created by sshd.
|
||||
command -v tty >/dev/null 2>&1 || exit 0
|
||||
PTS=$(tty)
|
||||
if ! pgrep -f "^sshd.+${PTS#/dev/}\>" >/dev/null \
|
||||
&& [ -z "${SSH_CONNECTION:-}" ] \
|
||||
&& ! is_child_of_sshd_or_mosh_server; then
|
||||
if [ $PRETEND_SSH -eq 1 ]; then
|
||||
echo "I: $ME: this is not an SSH session, but --pretend-ssh was given..." >&2
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
echo "W: $ME: SSH session detected!" >&2
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "I: $ME: $MOLLYGUARD_CMD is always molly-guarded on this system." >&2
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${USE_FQDN:-0}" in
|
||||
0|false|False|no|No|off|Off)
|
||||
HOSTNAME="$(hostname --short)"
|
||||
;;
|
||||
*)
|
||||
HOSTNAME="$(hostname --fqdn)"
|
||||
;;
|
||||
esac
|
||||
|
||||
sigh()
|
||||
{
|
||||
echo "Good thing I asked; I won't $MOLLYGUARD_CMD $HOSTNAME ..." >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
trap 'echo;sigh' 1 2 3 9 10 12 15
|
||||
|
||||
echo -n "Please type in hostname of the machine to $MOLLYGUARD_CMD: "
|
||||
read HOSTNAME_USER || :
|
||||
|
||||
HOSTNAME="$(echo "$HOSTNAME" | tr '[:upper:]' '[:lower:]')"
|
||||
HOSTNAME_USER="$(echo "$HOSTNAME_USER" | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
[ "$HOSTNAME_USER" = "$HOSTNAME" ] || sigh
|
||||
|
||||
trap - 1 2 3 9 10 12 15
|
||||
|
||||
exit 0
|
152
shutdown.in
Executable file
152
shutdown.in
Executable file
|
@ -0,0 +1,152 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# shutdown -- wrapper script to guard against accidental shutdowns
|
||||
#
|
||||
# Copyright © martin f. krafft <madduck@madduck.net>
|
||||
# Released under the terms of the Artistic Licence 2.0
|
||||
#
|
||||
set -eu
|
||||
|
||||
ME=molly-guard
|
||||
VERSION=0.8
|
||||
|
||||
SCRIPTSDIR="@cfgdir@/run.d"
|
||||
|
||||
CMD="${0##*/}"
|
||||
|
||||
case "$CMD" in
|
||||
halt|reboot|shutdown|poweroff|coldreboot|pm-hibernate|pm-suspend|pm-suspend-hybrid)
|
||||
if ! EXEC=$(command -v "$CMD.no-molly-guard"); then
|
||||
if ! EXEC=$(command -v "$CMD.no-molly-guard.usr-is-merged"); then
|
||||
echo "E: not a regular file: $EXEC" >&2
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
if [ "$EXEC" -ef /usr/lib/molly-guard/molly-guard ]; then
|
||||
# Symlink forwards to ourselves. Resolve!
|
||||
LINKTARGET=$(readlink "$EXEC")
|
||||
if ! EXEC=$(command -v "$LINKTARGET.no-molly-guard"); then
|
||||
if ! EXEC=$(command -v "$LINKTARGET.no-molly-guard.usr-is-merged"); then
|
||||
echo "E: not a regular file $EXEC" >&2
|
||||
exit 4
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ ! -x $EXEC ]; then
|
||||
echo "E: not an executable: $EXEC" >&2
|
||||
exit 3
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "E: unsupported command: $CMD" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
usage()
|
||||
{
|
||||
cat <<-_eousage
|
||||
Usage: $ME [options] [-- script options]
|
||||
(shielding $EXEC)
|
||||
|
||||
molly-guard's primary goal is to guard against accidental
|
||||
shutdowns/reboots. $ME will run all scripts in $SCRIPTSDIR and only
|
||||
invokes $EXEC if all scripts exited successfully.
|
||||
|
||||
Specifying --molly-guard-do-nothing as argument to the command will
|
||||
make $ME echo the command it would execute rather than actually
|
||||
executing it.
|
||||
|
||||
Options following the double hyphen will be passed unchanged to the
|
||||
scripts.
|
||||
|
||||
Please see molly-guard(8) for more information.
|
||||
|
||||
The actual command's help output follows:
|
||||
|
||||
_eousage
|
||||
}
|
||||
|
||||
CMDARGS=
|
||||
SCRIPTARGS=
|
||||
END_OF_ARGS=0
|
||||
DO_NOTHING=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
(*-molly-guard-do-nothing) DO_NOTHING=1;;
|
||||
(*-help)
|
||||
usage 2>&1
|
||||
( exec bash -c 'exec -a "$0" "$@"' "$CMD" "$EXEC" --help 2>&1 )
|
||||
exit 0
|
||||
;;
|
||||
--) END_OF_ARGS=1;;
|
||||
*\"*)
|
||||
echo 'E: cannot use double-quotes (") in arguments' >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
if [ $END_OF_ARGS -eq 0 ]; then
|
||||
CMDARGS="${CMDARGS:+$CMDARGS }\"$arg\""
|
||||
else
|
||||
SCRIPTARGS="${SCRIPTARGS:+$SCRIPTARGS }--arg \"$arg\""
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
do_real_cmd()
|
||||
{
|
||||
if [ $DO_NOTHING -eq 1 ]; then
|
||||
echo "$ME: would run: $EXEC $CMDARGS"
|
||||
exit 0
|
||||
else
|
||||
eval exec bash -c "'"'exec -a "$0" "$@"'"'" "'$CMD'" "'$EXEC'" "$CMDARGS"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ $DO_NOTHING -eq 1 ]; then
|
||||
echo "I: demo mode; $ME will not do anything due to --molly-guard-do-nothing." >&2
|
||||
fi
|
||||
|
||||
if [ -n "${MOLLYGUARD_CMD:-}" ]; then
|
||||
do_real_cmd
|
||||
fi
|
||||
|
||||
MOLLYGUARD_CMD=$CMD; export MOLLYGUARD_CMD
|
||||
MOLLYGUARD_DO_NOTHING=$DO_NOTHING; export MOLLYGUARD_DO_NOTHING
|
||||
MOLLYGUARD_SETTINGS="@cfgdir@/rc"; export MOLLYGUARD_SETTINGS
|
||||
|
||||
# pass through certain commands
|
||||
case "$CMD $CMDARGS" in
|
||||
(*shutdown\ *-c*|*halt\ *-w*|*halt\ *-f*|*reboot\ *-f*)
|
||||
# allow canceling shutdowns, only write wtmp and force immediate halt
|
||||
echo "I: executing $CMD $CMDARGS regardless of check results." >&2
|
||||
do_real_cmd
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check for execution from configuration management tools that might use an
|
||||
# interactive shell.
|
||||
CONFIGURATION_MANAGEMENT=0
|
||||
|
||||
[ -f "$MOLLYGUARD_SETTINGS" ] && . "$MOLLYGUARD_SETTINGS"
|
||||
|
||||
# Ansible uses an interactive shell, but by default puts Ansible in the
|
||||
# broadcast message, we can look for that. Allow for it be changed per site.
|
||||
ANSIBLE_SEARCH_STRING="${ANSIBLE_SEARCH_STRING:-ansible}"
|
||||
if echo $CMDARGS | grep -qi $ANSIBLE_SEARCH_STRING; then
|
||||
CONFIGURATION_MANAGEMENT=1
|
||||
fi
|
||||
|
||||
export CONFIGURATION_MANAGEMENT
|
||||
|
||||
for script in $(run-parts --test $SCRIPTSDIR); do
|
||||
ret=0
|
||||
eval $script $SCRIPTARGS || ret=$?
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo "W: aborting $CMD due to ${script##*/} exiting with code $ret." >&2
|
||||
exit $ret
|
||||
fi
|
||||
done
|
||||
|
||||
do_real_cmd
|
Loading…
Add table
Add a link
Reference in a new issue