#!/bin/sh
#
# vfixpermissions
# John Simpson <jms1@jms1.net> 2005-09-21
#
# Fixes permissions on the vpopmail directory. If your vpopmail user is 
# not "vpopmail", specify the userid on the command line.
#
# 2006-01-16 jms1 - added a line to fix ~vpopmail itself. thanks to Adam
#   Sloan for pointing out the oversight.
#
# 2006-02-27 jms1 - explicitly setting permissions on the files and 
#   directories in the "domains" directory.. thanks to Adam Kane 
#   ("derxob" on the #qmailrocks IRC channel) for finding the problem.
#
# 2006-03-21 jms1 - adding code to open up the minimum needed permissions
#   on any "parent" directories of the ~vpopmail directory. this assumes
#   that the location of ~vpopmail is not more than eight "layers deep"
#   in the filesystem.
#
# 2006-09-18 jms1 - adding code to adjust for differences between the
#   original "xargs" and the GNU version. explicitly setting permissions for
#   etc/onchange as well. thanks to bookworm for pointing out the problems
#   and Jukka Kurkela for reminding me about it a few months later, when i
#   forgot to actually ADD the new code.
#
# 2006-11-27 jms1 - adding an explicit chmod for the "onchange" script,
#   just in case a user has one which isn't marked executable to start
#   with.
#
# 2007-06-16 jms1 - adding "-c" option for "chmod" and "chown", but only for
#   linux systems. this will show the user what files are being changed.
#   thanks to Thanos Rizoulis for the suggestion.
#
# 2007-06-17 jms1 - adding "-vv" option for FreeBSD, since it seems to work
#   the same way that linux's "-c" option does (i.e. it shows any changes it
#   makes, but doesn't list every file it looks at.)
#
# 2007-06-22 jms1 - adding an explicit "chmod 0711" for ~vpopmail itself,
#   just in case the permissions were REALLY messed up to start with.
#   thanks to Nigel Mundy for making me re-think that part of the script.
#
# 2007-06-23 jms1 - fixed a typo in the lines that i "re-thought" last night.
#   thanks to Bill Olson for forwarding me an IRC transcript where some joker
#   on IRC made an ass of himself in the process of illustrating the bug.
#
# 2007-06-25 jms1 - fixed another bug where the ~vpopmail/bin/* files 
#   were being made non-executable ... samuel adams is NOT a good coder.
#
# 2007-10-05 jms1 - making "vchkpw" setuid/setgid is now an option, which is
#   not enabled by default.
#
# 2007-12-13 jms1 - forgot to remove "-s" from the command line after using
#   it as the "make vchkpw setuid" flag. thanks to Ingo Claro for pointing
#   out the problem.
#
###############################################################################
#
# Copyright (C) 2005,2006,2007 John Simpson.
#
# 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, either version 2 or version 3 of the
# license, at your option.
#
# 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, see <http://www.gnu.org/licenses/>.
#
###############################################################################

# are we being told to make "vchkpw" setuid/setgid?
if [ "$1" = "-s" ]
then
	VCHKPW_SETUID=yes
	shift
fi

# we want "chmod" to show us the changes it's making. the options are
# different for linux, *bsd, and possibly other OS's.

if uname -s | grep -q Linux
then
	OPTS="-c"
elif uname -s | grep -q FreeBSD
then
	OPTS="-vv"
else
	OPTS=""
fi

# user defaults to "vpopmail" if not specified on the command line
VUSER=${1:-vpopmail}

PL=`grep "^$VUSER:" /etc/passwd`
if [ -z "$PL" ]
then
	echo User \"$VUSER\" does not exist
	exit 1
fi

# these may need to be adjusted for systems where the field numbers are
# different from the standard layout. these work for linux.
#
# we could get the UID/GID with VUID=`id -u $USER`, but there's no
# ready-made utility to give you a user's home directory, so you have to
# cut their /etc/passwd line to get it... and since we have to slice and
# dice the passwd line anyway, we may as well get the UID/GID from there
# as well.

VUID=`echo "$PL" | cut -d: -f3`
VGID=`echo "$PL" | cut -d: -f4`
VDIR=`echo "$PL" | cut -d: -f6`

# compensate for the GNU version of xargs

if xargs --version >/dev/null 2>&1
then
	# GNU version of xargs needs "-r" to work correctly
	# (i.e. to not run the command if stdin is empty)
	XAR="-r"
else
	# normal xargs works correctly without "-r"
	XAR=""
fi

###############################################################################
#
# this does the actual work...

cd $VDIR
chown $OPTS -R $VUID:$VGID .
chmod $OPTS    0711        .

find bin doc etc include lib -type d -print0 | xargs -0 $XAR chmod $OPTS 0755
find bin -type f -print0 | xargs -0 $XAR chmod $OPTS 0755
find doc etc include lib -type f -print0 | xargs -0 $XAR chmod $OPTS 0644

if [ -n "${VCHKPW_SETUID:-}" ]
then
	chmod $OPTS 6711 bin/vchkpw
fi

if [ -f etc/vpopmail.mysql ]
then
	chmod $OPTS 600 etc/vpopmail.mysql
fi

if [ -f etc/onchange ]
then
	chmod $OPTS 755 etc/onchange
	chown $OPTS 0:0 etc/onchange
fi

find domains -type d -print0 | xargs -0 $XAR chmod $OPTS 0700
find domains -type f -print0 | xargs -0 $XAR chmod $OPTS 0600

chmod $OPTS go+x \
	.. \
	../.. \
	../../.. \
	../../../.. \
	../../../../.. \
	../../../../../.. \
	../../../../../../.. \
	../../../../../../../..