#!/bin/bash
# -*- sh -*-
# Copyright (C) 2008 Matthias Schmitz
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#


####
# prints usage
function usage() {
    echo "Usage: munin-check [options]
Options:
   -h|--help		Show this help.
   -f|--fix-permissions Fix the permissions of the munin dirs and files.
   			Needs superuser rights.

Please don't use this script if you are using 'graph_strategy cgi'!
It doesn't care about the right permissions for www-data yet...
"
}

# Get options from the command line
TEMP=$(getopt -o fh --long fix-permissions,help -n 'munin-check' -- "$@")

if [[ $? -ne 0 ]]; then
    echo "Terminating..." >&2
    exit 1
fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while :; do
    case "$1" in
	-h|--help) usage ; exit 0; shift ;;
	-f|--fix-permissions) PLEASE_FIXME="true" ;  shift ;;
	--) shift ; break ;;
	*) echo "Internal error!" ; exit 1 ;;
    esac
done

####
# sets owner to "munin"
function fix_owner() {
    fix_object=$1; shift
    fix_owner=$1; shift

    if [[ $(id -u) -eq 0 ]]; then
	# -R is wrong, in case we're not recursing, and if we are
	# recursing then fix_owner will be called again.  OK, that's
	# slower, but still more correct.
	chown $fix_owner $fix_object;
    else
	echo "Fixing the permissions needs superuser rights. You should run \"munin-check -f\" as root."
	exit 0;
    fi
}

####
# check if "munin" is owner, if PLEASE_FIXME set it calls fix_owner()

function owner_ok() {
    object=$1; shift || exit 1
    correctowner=$1; shift || exit 1

    owner=$(ls -ld $object | awk '{print $3}')
    if [[ "$owner" != "$correctowner" ]]; then
	echo "# $object : Wrong owner ($owner != $correctowner)";
	if [[ "$PLEASE_FIXME" == "true" ]]; then
	    fix_owner $object $correctowner
	fi
    fi

    if [[ -d $object ]]; then
	if [[ -n "$norec" ]]; then
	    # The $norec variable cuts off recursion
	    return 0
	fi

	case $object in
	    "lost+found") return 0;;
	esac

	# ... and then dive into it
	for subobject in $object/*; do
		owner_ok $subobject $correctowner
	done
    fi
}


function perm_ok(){
    object=$1; shift || exit 1
    correctperm=$1; shift || exit 1

    perm=$(perl -e 'printf "%o\n", 07777 & (stat $ARGV[0])[2]' $object)
    if [[ $perm -ne $correctperm ]]; then
	echo "# $object : Wrong permissions ($perm != $correctperm)";
	if [[ "$PLEASE_FIXME" == "true" ]]; then
	    chmod $correctperm $object
	fi
    fi

    if [[ -d $object ]]; then
	# check the owner of the dir ...

	if [[ -n "$norec" ]]; then
	    # The $norec variable cuts off recursion
	    return 0
	fi

	case $object in
	    "lost+found") return 0;;
	esac

	# ... and then dive into it
	for subobject in $object/*; do
	    perm_ok $subobject $correctperm
	done
    fi
}

####
# main

echo "check /usr/share/munin/www"
owner_ok /usr/share/munin/www munin

for dir in /var/lib/munin/*; do
    # Do not check the plugin-state directory
    case $dir in
	*/plugin-state)
	    continue;;
    esac
    echo "check $dir"
    owner_ok $dir munin
done

echo "check miscellaneous"
norec=yes owner_ok /var/log/munin munin

norec=yes owner_ok /var/lib/munin munin
norec=yes perm_ok /var/lib/munin 755

for dir in /var/lib/munin/datafile /var/lib/munin/limits /var/lib/munin/*.stats; do
    norec=yes owner_ok $dir munin
    norec=yes perm_ok $dir 644
done

norec=yes owner_ok /var/lib/munin/plugin-state nobody
norec=yes perm_ok /var/lib/munin/plugin-state 775

norec=yes perm_ok /etc/munin/plugin-conf.d 755

echo "Check done.  Please note that this script only checks most things,"
echo "not all things."
echo
echo "Please also note that this script may be buggy."
echo
