#!/bin/bash
# Script zum Anlegen eines neuen virtuellen Mailkontos oder einer Weiterleitung
# Version: 0.4a
# (C) 2010 ivins-server.org
# Author: Stefan Schaefer <stefan@invis-server.org>
# Questions: http://forum.invis-server.org
# License: GPLv3

# Globale Einstellungen
rootpackdir="/etc/rootpack"
rootpackconfig="$rootpackdir/rootpack.cfg"

usage() {
    echo "-------------------------------------------------------------------------------------"
    echo "Übergeben Sie diesem Script die gewünschte neue Mailadresse sowie einen Adresstyp."
    echo
    echo "Beispiel: \$> mkvmailaccount adresse@example.com type"
    echo
    echo "Als Adresstyp (type) stehen \"mailaccount\", \"mailalias\" und \"extalias\" zur Verfügung."
    echo -e "\"mailaccount\"\tlegt einen neuen Benutzer nebst Postfach an,\n\"mailalias\"\tlediglich eine Weiterleitung auf ein lokal bestehendes Postfach.\n\"extalias\"\terzeugt eine Weiterleitung auf eine externe Adresse."
    echo "-------------------------------------------------------------------------------------"
}

# Konfigurationsparameter tauschen
changevalues() {
    # Arg1 = Pfad, Arg2 = Datei, Arg3 = sed String
    cat $1/$2|sed "s%$3%g" > $1/$2.new
    mv $1/$2.new $1/$2
}

getconfvalue() {
    cat $rootpackconfig | grep "$1:" | cut -d ":" -f 2
}

checkmailaddress() {
    ## Prüfen, ob es sich um eine gültige Adresse handelt
    if [[ ! $1 =~ ^[a-zA-Z0-9-]+([._a-zA-Z0-9.-]+)*@[a-zA-Z0-9.-]+\.([a-zA-Z]{2,4}) ]]; then
	echo "----------------------------------------------------------------------------------------"
	echo "Sie haben keine gültige EMail-Adresse nach dem Muster \"adresse@example.com\" angegeben."
	echo "----------------------------------------------------------------------------------------"
	exit
    fi
}

clear

# Adresse und Typ übernehmen
if [[ -z $1 || -z $2 ]]; then
    usage
    exit
else
    mailaddress="$1"
    acounttype="$2"
fi

checkmailaddress $mailaddress

## Verschluesselungsalgorithmus ermitteln
scheme=$(getconfvalue DCPWScheme)

## Prüfen ob Postfix für die zugehörige Domain verantwortlich ist
pf_rdomains=$(getconfvalue RelayDB)
domain=$(echo "$mailaddress" |cut -d "@" -f2)

punycodedomain=$(idn --quiet $domain)

## Virtual_DB ermitteln
pf_virtual=$(getconfvalue VirtualDB)

# Abgefragt wird die Postfix Lookup-Table "virtual_domains"
# Nebeneffekt ist, dass wir damit den Besitzer der Domain ermitteln. Dieser wurde durch das Script mkzone
# in die Table virtual_domains eingetragen. Er wird später benötigt.
domowner=$(postmap -q $punycodedomain $pf_rdomains)

if [[ -z $domowner ]]; then
    echo "-----------------------------------------------------------------------------------------------"
    echo -e "Die in der EMail-Adresse angegebene Domain \"$domain\" ist diesem Server unbekannt oder\nsie wird als virtuelle Postfix-Domain geführt. Verwenden Sie in diesem Fall das Script\n\"mkmailaccount\" zum Anlegen der Postfächer."
    echo "-----------------------------------------------------------------------------------------------"
    exit
fi

## Prüfen, ob die angegebene Adresse bereits existiert
if [[ -n $(cat /etc/dovecot/passwd|grep -v "#"|cut -d ":" -f1|grep -x "$mailaddress") ]]; then
    echo "----------------------------------------------------------------------------------"
    echo "Die angegebene Adresse \"$mailaddress\" existiert bereits."
    echo "----------------------------------------------------------------------------------"
    exit
fi

## Prüfen, ob eine Quota-Vorgabe fuer Postfaecher existiert
quota=$(getconfvalue MailQuota)

# Quota-Praefix
qpraefix='userdb_quota_rule=*:storage='

# Quota-Regel erzeugen
if [[ $quota != "0" ]]; then
    quotarule="$qpraefix$quota"
else
    quotarule=""
fi

# Useranteil der Adresse ermitteln
userpart=$(echo "$mailaddress" |cut -d "@" -f1)
punycodeaddress="$userpart@$punycodedomain"
case $acounttype in
    mailaccount)
	    echo "------------------------------------"
	    echo "Es wird ein neues Postfach angelegt."
	    echo "------------------------------------"
	    # Mailuser-Account anlegen
	    mailhome=$(getconfvalue MailHome)
	    # Homeverzeichnis anlegen
	    mkdir -p $mailhome/$mailaddress/Maildir
	    chown -R vmail.vmail $mailhome/$mailaddress
	    chmod -R o-rwx $mailhome/$mailaddress
	    # Zufallspasswort generieren -- 8 Zeichen, mindestens 1 Grossbuchstabe und 1 Zahl.
	    pass=$(pwgen -cn 8 1)
	    dpw=$(dovecotpw -s $scheme -p $pass)
	    echo -e "Bitte übermitteln Sie das vergebene Passwort: \"$pass\" an den Besitzer des Postfaches \"$mailaddress\"."
	    # Eintrag in /etc/dovecot/passwd erzeugen
	    echo "$punycodeaddress:$dpw::::::$quotarule" >> /etc/dovecot/passwd
	    # Eintrag in Postfix Lookup-Tables erzeugen -- nicht notwendig bei virtuellen Dovecot Konten
	    #echo -e "$mailaddress\t$domowner-$userpart" >> $pf_virtual
	    #postmap $pf_virtual
	    #postfix reload
	    ;;
    mailalias)
	    echo "-------------------------------------"
	    echo "Es wird ein neuer Mailalias angelegt."
	    echo "-------------------------------------"
	    echo
	    echo "Wählen Sie das Mail-Konto dem die Adresse \"$mailaddress\" zugeordnet werden soll."
	    echo "Tippen Sie einfach nur die entsprechende Nummer ein."
	    echo
	    # Alle zur angegebenen Domain gehörenden Mail-User-Accounts ermitteln. 
	    accounts1=($(cat $pf_virtual| grep -v ^#| grep $punycodedomain | tr '\t' " " | tr -s " " | cut -d " " -f2 | sort -u))
	    accounts2=($(cat /etc/dovecot/passwd|grep -v ^#| grep $punycodedomain|cut -d":" -f1|sort -u))
	    accounts=(${accounts1[*]} ${accounts2[*]})
	    select account in ${accounts[@]}; do
		seladdress=$account

		break
	    done
	    #echo $seladdress
	    echo -e "$punycodeaddress\t$seladdress" >> $pf_virtual
	    postmap $pf_virtual
	    postfix reload
	
	    ;;
    extalias)
	    echo "--------------------------------------------"
	    echo "Es wird eine externe Weiterleitung angelegt."
	    echo "--------------------------------------------"
	    echo
	    # Solange fragen, bis verdammt nochmal eine Adresse angegeben wurde.
	    while [[ -z $extaddress ]]; do
	        read -p "Geben Sie bitte die externe Zieladresse der Weiterleitung ein: " extaddress
	    done
	    checkmailaddress $extaddress
	    echo -e "$punycodeaddress\t$extaddress" >> $pf_virtual
	    postmap $pf_virtual
	    postfix reload
	
	    ;;
    *)
	    echo "--------------------------------------------"
	    echo "Es wurde kein korrekter Adresstyp angegeben."
	    echo "--------------------------------------------"
	    echo
	    usage
	    exit
	    ;;
esac

