#!/bin/bash
# v1.06
# 2020-10-29

# Defaults
. /etc/ntools/mail-config

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

This script list a mail users in LDAP

OPTIONS
  -h         Show this message
  -d <dom>   Domain
EOF
	exit
}

function show_mailbox() {
	local PARAMS
	ADDRESS="$1"
	OLD_IFS="$IFS"
	PARAMS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAddress=${ADDRESS}))")
	IFS=$'\n'
	for U in $PARAMS; do
		[[ "$U" =~ ^objectClass ]] && continue
		[[ "$U" =~ ^userPassword ]] && continue
		[[ "$U" =~ ^shadow ]] && continue
		echo "$U"
	done
	IFS="$OLD_IFS"
}

function show_domains() {
	local DOMAINS
	DOMAINS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_DOMAINS_DN}" -D "${LDAP_BIND_DN}" -LLL "(objectClass=mailDomain)" mailDomain | grep -e '^mail' | cut -d':' -f2 | sort)
	echo "Domains:"
	for cdom in $DOMAINS; do
		local ACTIVE
		ACTIVE=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_DOMAINS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailDomain)(mailDomain=${cdom}))" active | grep -e '^active' | cut -d':' -f2)
		local STATE
		STATE='unknown'
		[ "$ACTIVE" == " TRUE" ] && STATE='active'
		[ "$ACTIVE" == " FALSE" ] && STATE='inactive'
		echo "  $cdom - $STATE"
	done
	echo
}

function show_all_users() {
	local USERS
	USERS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(objectClass=mailAccount)" mailAddress | grep -e '^mail' | cut -d':' -f2 | sort)
	echo "Users:"
	for caddr in $USERS; do
		local ACTIVE
		ACTIVE=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAddress=${caddr}))" active | grep -e '^active' | cut -d':' -f2)
		local STATE
		STATE='unknown'
		[ "$ACTIVE" == " TRUE" ] && STATE='active'
		[ "$ACTIVE" == " FALSE" ] && STATE='inactive'
		local DESCRIPTION
		DESCRIPTION=$(ldapsearch -o ldif-wrap=no -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAddress=${caddr}))" description | grep -e '^description' | cut -d: -f2-)
		if [ "${DESCRIPTION:0:1}" == ':' ]; then
			DESCRIPTION=$(echo "${DESCRIPTION:2}" | base64 -d)
		else
			DESCRIPTION="${DESCRIPTION:1}"
		fi
		if [ -n "$DESCRIPTION" ]; then
			echo "  $caddr - $STATE ($DESCRIPTION)"
		else
			echo "  $caddr - $STATE"
		fi
	done
	echo
}

function show_domain_users() {
	local CDOM
	CDOM="$1"
	local USERS
	USERS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailDomain=${CDOM}))" mailAddress | grep -e '^mail' | cut -d':' -f2 | sort)
	echo "Users:"
	for caddr in $USERS; do
		local ACTIVE
		ACTIVE=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAddress=${caddr}))" active | grep -e '^active' | cut -d':' -f2)
		local STATE
		STATE='unknown'
		[ "$ACTIVE" == " TRUE" ] && STATE='active'
		[ "$ACTIVE" == " FALSE" ] && STATE='inactive'
		local DESCRIPTION
		DESCRIPTION=$(ldapsearch -o ldif-wrap=no -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAddress=${caddr}))" description | grep -e '^description' | cut -d: -f2-)
		if [ "${DESCRIPTION:0:1}" == ':' ]; then
			DESCRIPTION=$(echo "${DESCRIPTION:2}" | base64 -d)
		else
			DESCRIPTION="${DESCRIPTION:1}"
		fi
		if [ -n "$DESCRIPTION" ]; then
			echo "  $caddr - $STATE ($DESCRIPTION)"
		else
			echo "  $caddr - $STATE"
		fi
	done
	echo
}

function show_all_aliases() {
	local ALIASES
	ALIASES=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(objectClass=mailAccount)" mailAlias | grep -e '^mail' | cut -d':' -f2 | sort | uniq)
	echo "Aliases:"
	for cal in $ALIASES; do
		echo "  $cal"
		local USERS
		USERS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAlias=${cal}))" mailAddress | grep -e '^mail' | cut -d':' -f2 | sort)
			for caddr in $USERS; do
				echo "    $caddr"
			done
		echo
	done
}

function show_domain_aliases() {
	local CDOM
	CDOM="$1"
	local ALIASES
	ALIASES=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailDomain=${CDOM}))" mailAlias | grep -e '^mail' | cut -d':' -f2 | sort | uniq)
	echo "Aliases:"
	for cal in $ALIASES; do
		echo "  $cal"
		local USERS
		USERS=$(ldapsearch -x -w "$LDAP_BIND_PASSWORD" -b "${LDAP_USERS_DN}" -D "${LDAP_BIND_DN}" -LLL "(&(objectClass=mailAccount)(mailAlias=${cal}))" mailAddress | grep -e '^mail' | cut -d':' -f2 | sort)
			for caddr in $USERS; do
				echo "    $caddr"
			done
		echo
	done
	echo
}

function show_all_forward() {
	local ADDRESSES
	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
	echo
}

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

shift $((OPTIND -1))

MAIL_ADDRESS="$1"

if [ -n "$MAIL_ADDRESS" ]; then
	show_mailbox "$MAIL_ADDRESS"
	exit
fi

if [ -z "$MAIL_DOMAIN" ]; then
	show_domains
	show_all_users
	show_all_aliases
else
	show_domain_users "$MAIL_DOMAIN"
	show_domain_aliases "$MAIL_DOMAIN"
fi

show_all_forward
