#!/bin/bash

#  Copyright (C) 2005 Arnaud Fontaine
#
#  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 of the License, or
#  (at your option) any later version.
#
#  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.

export PATH="/usr/sbin:/sbin:/bin:/usr/bin"

### Name of the script
NAME=$(basename $0)

### Paths of binaries
SUDO=$(which sudo)
MYSQL=$(which mysql)
USERADD=$(which useradd)
PWGEN=$(which pwgen)
MAIL=$(which mail)
GROUPADD=$(which groupadd)
RNDC=$(which rndc)
DELUSER=$(which deluser)
DELGROUP=$(which delgroup)
OPENSSL=$(which openssl)

### Some other variables
PWGEN_ARG="-N 1 -s"
MAIL_SUBJECT='Bienvenue chez Oxic'
MAIL_FROM="admin@oxic.org"

## Paths of configuration files
TPL=$(pwd)/templates
SQL_BASE=$TPL/base.sql
MSG_MAIL=$TPL/mail.txt
MSG_MAIL_TMP=$TPL/mail.txt
SQL_POSTFIX=$TPL/postfix.sql
APACHE_ROOT=/home/services/apache
APACHE_WWW=$APACHE_ROOT/home/www
VSFTPD_USERS=/etc/vsftpd.userlist_file
BIND_ROOT=/home/services/bind
BIND_DIR=$BIND_ROOT/var/cache/bind
BIND_CONF=$BIND_ROOT/etc/bind/named.conf
BIND_TPL=$TPL/tpl.hosts
EDQUOTA=$(which edquota)

### We need help in order to know how to use the script
function help()
{
    cat << EOF
usage: -a : add an user or domain name
       -r : remove an user or domain name
       -d : specify a domain name
       -u : specify an user
       -e : specify user's email
       -t : pack type (1|3|5)
       -p : sql root password
       -v : verbose

example:
       # Create an account
       $NAME -a -d jdoe.org -u j.doe -e foo@bar.com \ 
           -t 1 -p sql_password
       # Remove an account
       $NAME -r -d jdoe.org -u j.doe -t 1 -p sql_password
EOF
    exit 1
}

function more_parameters ()
{
    ### Not enough parameters
    echo "ERROR: Please, specify all the arguments..."
    help
    exit 1
}
    
### We parse the arguments given in the command line
while getopts ru:vhe:t:ad:p: options; do
    case $options in
	u) username=$OPTARG;;
	a) create=true remove=false;;
	e) email=$OPTARG;;
	d) domain=$OPTARG;;
	v) verbose=true;;
	r) remove=true create=false;;
	p) sql_root=$OPTARG;;
	t) pack=$OPTARG;;
	h) help;;
    esac
done

### If we give no argument to the script
if [ -z "$1" ]; then
    help
fi

### We want the script to be verbose
if [ $verbose ]; then
    set -x
fi

APACHE_DOMAIN=$APACHE_WWW/$domain
APACHE_INDEX=$APACHE_DOMAIN/www/index.html

## (Egrep|Emacs) rocks, we must have a valid domain name
if [ -z $(echo $domain | egrep '^[-a-zA-Z]+\.(org|com|net|fr|info|biz)$') ]; then
    echo "ERROR: Invalid domain name ``$domain''"
    exit 1
fi

## Username must be like ``j.doe''
if [ -z $(echo $username | egrep '^[a-zA-Z]\.[a-zA-Z]+$') ]; then
    echo "ERROR: Invalid username ``$username'', it must be like that : ``j.doe''"
    exit 1
fi

### Only 3 packs are available
if [ $pack -ne 1 ] && [ $pack -ne 3 ] && [ $pack -ne 5 ]; then
    echo "ERROR: Invalid pack type."
    exit 1
fi

### SQL root password
if [ -z "$sql_root" ]; then
    echo "ERROR: Please specify a MySQL root password"
    exit 1
fi

### Verify that MySQL root password is correct
if [ -n "$sql_root" ]; then
    echo "Hmm, is MySQL root password correct..."
    echo "USE mysql" | $MYSQL -h 127.0.0.1 -u root --password="$sql_root" || exit 1
fi

## Useradd doesn't like domain.tld and prefer domain_tld
domain_grp=${domain/./_}
username_sed=${username/./_}

## Check for valid domain\|user
valid_domain="$(cat /etc/group | egrep "^$domain_grp")"
valid_username="$(cat /etc/passwd | egrep "^$username_sed")"

## Creation of a new user account
if [ $create == true ]; then
    ### We need some arguments in order to create an account
    if [ -n "$email" ]; then
	## The group must not exist already !
	if [ -n "$valid_domain" ]; then
	    echo "ERROR: Domain ``$domain'' already exists."
	    exit 1
	fi
	
        ## Generate user's password
	passwd_www=$($PWGEN $PWGEN_ARG)

	## The user must not exist already !
	if [ -n "$valid_username" ]; then
	    echo "ERROR: User ``$username'' already exists."
	    exit 1
	fi

	## Add the corresponding group and user
	$GROUPADD $domain_grp
	$USERADD -g $domain_grp -d $APACHE_DOMAIN -p "$($OPENSSL passwd $passwd_www)" -s /bin/sh $username_sed

	## FTP
	echo $username_sed >> $VSFTPD_USERS
	
	## Create directories
	mkdir -m 775 -p $APACHE_DOMAIN/www/ $APACHE_DOMAIN/stats/
	echo "Bienvenue sur $domain" > $APACHE_INDEX
	chown -R www-data.$domain_grp $APACHE_DOMAIN
	
	## FIXME: Quota
	# $EDQUOTA -g "$domain_grp"

	## SQL (We read data from templates/base.sql)
	# Is the file readable ?
	if [ ! -r "$SQL_BASE" ]; then
	    echo "ERROR: Rrrr, ``$SQL_BASE'' is not readable. Please chmod it !"
	    exit 1
	fi

	## Create base following the ``-t'' argument
	j=1
	passwd_sql=$($PWGEN $PWGEN_ARG)
	while [ "$j" -le "$pack" ]; do
	    sql_name[$j]=${domain_grp}_${j}
	    ## Login must not be more than 6 characters wide
	    sql_username=${username_sed:0:6}

	    cat $SQL_BASE | \
		sed "s/%DOMAIN%/${sql_name[$j]}/g" | \
		sed "s/%USERNAME%/$sql_username/g" | \
		sed "s/%PASSWD%/${passwd_sql}/g" | \
		$MYSQL -h 127.0.0.1 -u root --password="$sql_root" || exit 1
	
	    # Message send by mail to the new user for MySQL
	    MSG_MYSQL="${MSG_MYSQL}${sql_name[$j]}"

	    ## MySQL message to user
	    if [ "$j" -eq "$pack" ]; then
		MSG_MYSQL="$MSG_MYSQL."
	    else
		MSG_MYSQL="$MSG_MYSQL,"
	    fi

	    ## Next database
	    j=$(($j+1))
	done
	
	MSG_MYSQL="(${passwd_sql}) $MSG_MYSQL"

	## Mail adresses
	# Is the file readable ?
	if [ ! -r $SQL_POSTFIX ]; then
	    echo "ERROR: Rrrr, ``$SQL_POSTFIX'' is not readable. Please chmod it !"
	    exit 1
	fi
	
	# Is the email address correct ! It should be or you suck.
	if [ -z "$(echo "$email" | egrep '^[-_.a-zA-Z1-9]+@[-a-zA-Z1-9]+.(org|com|net|fr|info|biz)$')" ]; then
	    echo "ERROR: Invalid address email ``$email''"
	    exit 1
	fi

	## We are parsing the file
	passwd_mail=$($PWGEN $PWGEN_ARG)
	cat "$SQL_POSTFIX"  | \
	    sed "s/%DOMAIN%/$domain/g" | \
	    sed "s/%PASSWD%/$passwd_mail/g" | \
	    sed "s/%USERNAME%/$username_sed/g" | \
	    $MYSQL -h 127.0.0.1 -u root --password="$sql_root" || exit 1

	## Send mail to new user
	sed -e "s/%SQL_USERNAME%/$sql_username/g;s/%DOMAIN%/$domain/g;s/%USERNAME%/$username_sed/g;s/%PASSWD_MAIL%/$passwd_mail/g;s/%PASSWD_FTP%/$passwd_www/g;s/%MSG_MYSQL%/$MSG_MYSQL/g" $MSG_MAIL | \
		$MAIL -a "From: $MAIL_FROM" -s "$MAIL_SUBJECT" "$email" || exit 1
	
	sed -e "s/%SQL_USERNAME%/$sql_username/g;s/%DOMAIN%/$domain/g;s/%USERNAME%/$username_sed/g;s/%PASSWD_MAIL%/$passwd_mail/g;s/%PASSWD_FTP%/$passwd_www/g;s/%MSG_MYSQL%/$MSG_MYSQL/g" $MSG_MAIL | \
		$MAIL -a "From: $MAIL_FROM" -s "$MAIL_SUBJECT" "postmaster@${domain}" || exit 1

	### Bind configuration
	echo "
zone \"$domain\" {
    type master; 
    file \"/var/cache/bind/${domain}.hosts\";
    allow-query { any; };
};" >> $BIND_CONF || exit 1
   	
	sed -e "s#domain.tld#${domain}#g" $BIND_TPL  > $BIND_DIR/${domain}.hosts
    else
	more_parameters
    fi
### Remove an user or domain name
elif [ $remove ]; then
    if [ -z "$valid_username" ]; then
	echo "ERROR: Username ``$username'' doesn't exist."
	exit 1
    fi
    
    if [ -z "$valid_domain" ]; then
	echo "ERROR: Domain ``$domain'' doesn't exist."
	exit 1
    fi
    
    ## Delete directories
    rm -rf $APACHE_DOMAIN

    ## Remove users from domain group
    group_target="$(cat /etc/group | grep "^$domain_grp" | awk -F':' '{print $3}')"
    users_remove="$(cat /etc/passwd | grep "^.*:.*:.*:$group_target:.*" | awk -F':' '{print $1}')"

    if [ -n "$users_remove" ]; then
	for i in $users_remove; do
		$DELUSER $i || exit 1
	done
    fi

    $DELGROUP $domain_grp

    ## Drop database
    j=1
    while [ "$j" -le "$pack" ]; do
	echo "DROP DATABASE ${domain_grp}_${j}; DELETE FROM mysql.db WHERE User=\"${username_sed:0:6}\"; DELETE FROM mysql.user WHERE User=\"${username_sed:0:6}\"; " | \
	    $MYSQL -h 127.0.0.1 -u root --password="$sql_root" || exit 1
        # Next database
	j=$(($j+1))
    done

    ## Remove Vsftpd account
    acc_remove="(`echo "$users_remove" | sed 's/ /)|(/'`)"
    cat $VSFTPD_USERS | egrep -v "^${acc_remove}" > $VSFTPD_USERS.new
    mv $VSFTPD_USERS.new $VSFTPD_USERS

    ## Remove mails accounts
    echo "USE postfix; DELETE FROM transport WHERE domain=\"$domain\"; DELETE FROM users WHERE address LIKE \"%$domain%\"; DELETE FROM virtual WHERE address LIKE \"%$domain%\";" | \
	$MYSQL -h 127.0.0.1 -u root --password="$sql_root" || exit 1

    ## Remove domain from bind
    rm -f $BIND_DIR/${domain}.hosts
    l=$(grep -n "^zone \"$domain\"" $BIND_CONF | awk -F':' '{print $1}')
    if [ -n "$l" ]; then
	cat $BIND_CONF | sed "$l,$(($l+5))d" > $BIND_CONF.new
	mv $BIND_CONF.new $BIND_CONF
    fi
    rm -f $BIND_DIR/${domain}.hosts
else
    more_parameters
fi

### Reload bind configuration
/etc/init.d/bind9 reload || exit 1

### All done
echo "That's all folks !"
exit 0

