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