#!/bin/bash
# v 1.02
# 2025-09-03

# Defaults
. /etc/ntools/mail-config

function usage() {
cat << EOF
usage $0 [options] <action> [mail@address] [mail@address]

This script manage a mail forwards in LDAP

ACTIONS
  add <from@mail> <to@mail>[ toanother@mail][ ...]
  mod <from@mail> <+/-to@mail>[ +/-toanother@mail][ ...]
  del <from@mail>
  list
  enable <from@mail>
  disable <from@mail>

OPTIONS
  -h         Show this message
  -v         Verbose
EOF
	exit
}

function add_forward() {
	local ADDRESS
	ADDRESS="$1"
	shift
	[ -z "$1" ] && usage
	local LDIF
	LDIF=$(cat<<EOF
dn: mailAddress=${ADDRESS},${LDAP_FORWARD_DN}
changetype: add
objectClass: mailForward
active: TRUE
mailAddress: ${ADDRESS}
EOF
	)
	for cal in "$@"; do
		LDIF="$LDIF
mailForward: ${cal}"
	done
	local RESULT
	RESULT=$(echo "$LDIF" | ldapmodify -x -w "${LDAP_BIND_PASSWORD}" -D "${LDAP_BIND_DN}")
	[ "$IS_VERBOSE" ] && echo "$RESULT"
}

function del_forward() {
	local ADDRESS
	ADDRESS="$1"
	local RESULT
	RESULT=$(cat <<EOF | ldapmodify -x -w "${LDAP_BIND_PASSWORD}" -D "${LDAP_BIND_DN}"
dn: mailAddress=${ADDRESS},${LDAP_FORWARD_DN}
changetype: delete
EOF
	)
	[ "$IS_VERBOSE" ] && echo "$RESULT"
}

function disable_forward() {
	local ADDRESS
	ADDRESS="$1"
	local RESULT
	RESULT=$(cat <<EOF | ldapmodify -x -w "${LDAP_BIND_PASSWORD}" -D "${LDAP_BIND_DN}"
dn: mailAddress=${ADDRESS},${LDAP_FORWARD_DN}
changetype: modify
replace: active
active: FALSE
EOF
	)
	[ "$IS_VERBOSE" ] && echo "$RESULT"
}

function enable_forward() {
	local ADDRESS
	ADDRESS="$1"
	local RESULT
	RESULT=$(cat <<EOF | ldapmodify -x -w "${LDAP_BIND_PASSWORD}" -D "${LDAP_BIND_DN}"
dn: mailAddress=${ADDRESS},${LDAP_FORWARD_DN}
changetype: modify
replace: active
active: TRUE
EOF
	)
	[ "$IS_VERBOSE" ] && echo "$RESULT"
}

function list_forwards() {
	local ADDRESS
	ADDRESSES=$(ldapsearch -x -w "${LDAP_BIND_PASSWORD}" -b "${LDAP_FORWARD_DN}" -D "${LDAP_BIND_DN}" -LLL "(objectClass=mailForward)" mailAddress | grep -e '^mail' | cut -d':' -f2 | sort)
	echo "Forwards:"
	for cfwd in $ADDRESSES; do 
		local ACTIVE
		ACTIVE=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_FORWARD_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailForward)(mailAddress=${cfwd}))" active | grep -e '^active' | cut -d':' -f2)
		local STATE
		STATE='unknown'
		[ "$ACTIVE" == " TRUE" ] && STATE='active'
		[ "$ACTIVE" == " FALSE" ] && STATE='inactive'
		echo "  $cfwd - $STATE"
		local MAILS
		MAILS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_FORWARD_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailForward)(mailAddress=${cfwd}))" mailForward | grep -e '^mail' | cut -d':' -f2 | sort)
		for cmail in $MAILS; do
			echo "    $cmail"
		done
		echo
	done
}

function mod_forward() {
	local ADDRESS
	ADDRESS="$1"
	shift
	[ -z "$1" ] && usage
	local LDIF
	LDIF=$(cat<<EOF
dn: mailAddress=${ADDRESS},${LDAP_FORWARD_DN}
changetype: modify
EOF
	)
	local ALIST
	ALIST=''
	local RLIST
	RLIST=''
	for cal in "$@"; do
		if [[ "$cal" =~ ^- ]]; then
			RLIST="$RLIST
mailForward: ${cal:1}"
		elif [[ "$cal" =~ ^\+ ]]; then
			ALIST="$ALIST
mailForward: ${cal:1}"
		else
			ALIST="$ALIST
mailForward: ${cal}"
		fi
	done
	if [ -n "$ALIST" ]; then
		LDIF="${LDIF}
add: mailForward$ALIST"
	fi
	if [ -n "$RLIST" ]; then
		LDIF="${LDIF}
delete: mailForward$RLIST"
	fi
	local RESULT
	RESULT=$(echo "$LDIF" | ldapmodify -x -w "${LDAP_BIND_PASSWORD}" -D "${LDAP_BIND_DN}")
	[ "$IS_VERBOSE" ] && echo "$RESULT"
}

while getopts ":hv" OPTION; do
	case $OPTION in
		h)
			usage
		;;
		v)
			IS_VERBOSE=1
		;;
		\?)
			echo "Invalid option: -$OPTARG" >&2
			usage
		;;
		:)
			echo "Option -$OPTARG requires an argument." >&2
			usage
		;;
	esac
done

shift $((OPTIND -1))

ACTION=$1
shift
case $ACTION in
	add)
		add_forward "$@"
	;;
	del)
		MAIL_ADDRESS="$1"
		[ -z "$MAIL_ADDRESS" ] && usage
		[ -n "$2" ] && usage
		del_forward "${MAIL_ADDRESS}"
	;;
	disable)
		MAIL_ADDRESS="$1"
		[ -z "$MAIL_ADDRESS" ] && usage
		[ -n "$2" ] && usage
		disable_forward "${MAIL_ADDRESS}"
	;;
	enable)
		MAIL_ADDRESS="$1"
		[ -z "$MAIL_ADDRESS" ] && usage
		[ -n "$2" ] && usage
		enable_forward "${MAIL_ADDRESS}"
	;;
	list)
		list_forwards
	;;
	mod)
		mod_forward "$@"
	;;
	*)
		usage
	;;
esac

