Il y a quelques temps, j’ai décidé de centraliser au maximum la gestion des utilisateurs dans ma structure et sur les projets associés. L’idée centrale a été d’interfacer au LDAP le maximum de services, d’appuyer l’authentification à tous les services que nous utilisons sur le LDAP et de limiter au maximum les interventions manuelles lors de la création d’un utilisateur.
J’ai d’ailleurs présenté sur ce blog pas mal d’outils et de méthodes que j’ai mises en place dans ce cadre :
- Gestion des listes de diffusion de Mailman depuis le LDAP avec Ldap2Mailman
- Export des coordonnées vCard depuis le LDAP
- Synchronisation des tables Postfix de Mailman
- Personnaliser un modèle de document LibreOffice (ou Word) avec les données du LDAP
L’une des choses à laquelle je souhaitait répondre par ailleurs était lié à la gestion d’adresses emails virtuelles.
Expliquons-nous : dans le cadre de certains projets ou de certaines activités, j’ai besoin de créer des adresses email “virtuelles” sur un nouveau nom de domaine. L’idée étant de fournir à un certain nombre d’utilisateurs, spécifiquement pour un projet, une adresse email ayant pour domaine le nom de domaine du projet, mais sans pour autant héberger de boites mails. Il ne s’agit donc que d'”alias”, c’est-à-dire des adresses email qui ne sont que des relais vers d’autres adresses emails. Pour l’utilisateur c’est transparent, il n’a pas de nouvelle boite à paramétrer, ce qui a le mérite de s’intégrer complètement sans heurt aux environnements de travail de chacun.
Postfix gère ce type d’alias de manière très simple, il suffit de lui déclarer une table pour ce routage.
Paramétrage de Postfix pour la gestion des alias d’emails
Avant d’attaquer la configuration, je suppose que vous avez fait le nécessaire dans vos enregistrements DNS MX pour que votre serveur soit destinataire des mails adressés sur le domaine pour lequel vous souhaitez créer des adresses mail virtuelles. De même je pars du principe que vous avez une configuration de Postfix fonctionnelle sur ce serveur.
Pour utiliser l’outil que je propose, il faut déjà débuter par paramétrer correctement Postfix pour le domaine en question.
En premier lieu, il nous faut déclarer le domaine de destination dans les “virtual_alias_domains” de Postfix. Editez pour cela le fichier /etc/postfix/main.cf
, et cherchez la ligne qui débute par virtual_alias_domains
et ajouter le domaine en question. Si il y a déjà un domaine (ou plusieurs) dans les domaines virtuels, séparez par des virgules :
virtual_alias_domains = domaine_virtuel1.com, domaine_virtuel2.fr
Si vous utilisez déjà Mailman en mode multidomaine, votre domaine est peut-être déjà dans les “relay_domains” de Postfix. Dans ce cas, pas besoin de l’ajouter à nouveau dans les “virtual_alias_domains” de Postfix.
Ensuite, nous allons générer un fichier qui contiendra les correspondances entre les adresses “relayées” et les adresses “réelles”. Choisissez un nom de fichier facilement repérable (par défaut, j’utilise pour ma part le nom de domaine) :
touch /etc/postfix/domaine_virtuel2.fr
Puis retournons éditer le fichier /etc/postfix/main.cf
. Localisez la ligne qui débute pas “virtual_alias_maps =” et ajoutez le nom de fichier créé précédemment avec la commande touch
, précédé de “hash:”. Si il y a déjà une table d’adresse virtuelles enregistrée, séparez les valeurs par des virgules :
virtual_alias_maps = hash:/etc/postfix/virtual, hash:/etc/postfix/domaine_virtuel1.com, hash:/etc/postfix/domaine_virtuel2.fr
puis lancez les commandes suivantes (en remplaçant /etc/postfix/domaine_virtuel2.fr
par le nom de fichier créé avec la commande touch
) :
postmap /etc/postfix/domaine_virtuel2.fr /etc/init.d/postfix reload /etc/init.d/postfix restart
Utilisation du script Ldap2PostfixMap.sh pour générer la table d’adresses virtuelles
Commencez par vous positionner dans le dossier dans lequel vous souhaitez installer l’outil que j’ai écrit pour remplir votre table d’adresses virtuelles pour Postfix.
git clone https://github.com/yvangodard/Ldap2PostfixMap.git sudo chmod -R 750 Ldap2PostfixMap
Pour une aide complète sur les options supportées, installez le script et lancez l’aide : ./Ldap2PostfixMap.sh help
Le script fonctionne avec la syntaxe suivante :
./Ldap2PostfixMap.sh [-h] | -d <base namespace> -f <map filename> -v <virtual domain relayed> [-s <LDAP server>] [-u <relative DN of user banch>] [-t <LDAP group objectClass>] [-g <relative DN of LDAP group>] [-a <LDAP admin UID>] [-p <LDAP admin password>] [-c <postmap command>] [-D <main domain>] [-e <email report option>] [-E <email address>] [-j <log file>]
Les options obligatoires sont :
-d <base namespace>
: DN de base pour toutes les entrées du serveur LDAP source qui sera utilisé (ex :dc=server,dc=office,dc=com
)-f <map filename>
: chemin complet du fichier contenant le mapping entre les adresses virtuelles et adresses réelles (le même que plus haut, créé avec la commandetouch
) (ex :/etc/postfix/domaine_virtuel2.fr
)-v <virtual domain relayed>
: nom de domaine qui sera relayé avec ou sans@
(ex :@domaine_virtuel2.fr
ou domaine_virtuel2.fr
)
Options facultatives :
-s <LDAP server>
: adresse du serveur LDAP (par défaut :ldap://127.0.0.1
)-u <relative DN of user banch>
: DN relatif de la branche LDAP qui contient les entrées utilisateurs (ex :cn=allusers
, par défaut :cn=users
)-t <LDAP group objectClass>
: le type de groupe que vous voulez utiliser pour restreindre les utilisateurs à traiter, la valeur doit êtreposixGroup
ougroupOfNames
. Si cette option n’est pas utilisée, le script traitera la totalité des utilisateurs de la branche utilisateur qui a été renseignée.-g <relative DN of LDAP group>
: DN relatif du groupe que vous voulez utiliser pour restreindre les utilisateurs à traiter (ex :cn=mygroup,cn=groups
oucn=my_virtual_group2,ou=virutal_users
). Cette option doit obligatoirement être renseignée si l’option-t
est utilisée.-a <LDAP admin UID>
: UID de l’administrateur LDAP, si nécessaire pour accéder à l’annuaire (ex :diradmin
)-p <LDAP admin password>
: mot de passe de l’administrateur LDAP, si nécessaire pour accéder à l’annuaire (sera demandé si manquant)-c <postmap command>
: chemin complet de la commandepostmap
de Postfix (par défaut :/usr/sbin/postmap
)-D <main domain>
: domaine principal vers lequel relayer les adresses virtuelles dans le cas où un utilisateur a plusieurs adresses emails renseignée dans le LDAP. Peut débuter ou pas par@
(ex :mon_domaine_prioritaire.fr
)-e <email report option>
: paramètre pour l’envoi d’email de rapport d’exécution. Doit être renseigné paronerror
(envoi d’email uniquement en cas d’erreur),forcemail
(envoi d’email à chaque exécution) ounomail
(aucun email) (par défaut :nomail
)-E <email address>
: adresse email à laquelle sera envoyé le rapport d’exécution (doit être renseignée si l’option-e forcemail
ou-e onerror
est utilisée)-j <log file>
: cette option active la journalisation à la place de la sortie standard. Renseigner en argument le chemin du fichier de log (ex :/var/log/ldap2postfixmap.log
) ou utilisezdefault
(pour le chemin par défaut/var/log/ldap2postfixmap.log
)
Avec toutes ces options vous pouvez donc faire face à à peu près tous les cas de figure.
L’étape suivante est donc de renseigner dans votre annuaire LDAP les adresses email nécessaires. Imaginons que je veuille avoir des adresses email @domaine_virtuel2.fr
relayées, il faudra que pour chaque utilisateur qui doit pouvoir avoir une adresse de ce type j’ajoute deux attributs (à minima) dans leur entrée LDAP :
- une entrée mail :
adresse_virtuelle@domaine_virtuel2.fr
, qui sera l’adresse virtuelle - au moins une autre adresse email, qui ne contient pas
@domaine_virtuel2.fr
, par exemplemonadresse@gmail.com
Je vous conseille ensuite de tester votre commande, avant de la rentrer dans la table Cron
.
Une fois que vous aurez bien pris en main l’outil Ldap2PostfixMap.sh, il ne vous restera plus qu’à créer une entrée dans la table Cron
, par exemple
# LDAP -> Postfix Map */1 * * * * /usr/local/bin/Ldap2PostfixMap/Ldap2PostfixMap.sh -d dc=serveur,dc=monserveur,dc=fr -s ldap://monserveurldap.fr -f /etc/postfix/domaine_virtuel2.fr -v domaine_virtuel2.fr -e onerror -E moi@monadresse.fr -j default
Le seul problème que ne sait pas gérer ce script est l’erreur “manuelle” qui consiste à créer plus d’une fois dans le LDAP une adresse relayée. Seul le premier utilisateur contenant cet email sera traité et un rapport d’erreur vous donnera les utilisateurs en conflit pour que vous puissiez modifier cette erreur.
Le code complet, pour les curieux
#! /bin/bash #------------------------------------------# # LDAP2PostfixMap # #------------------------------------------# # # # Script that updates a Postfix virtual # # map with emails on LDAP # # # # Yvan Godard # # godardyvan@gmail.com # # # # Version 0.2 -- may, 29 2015 # # Under Licence # # Creative Commons 4.0 BY NC SA # # # # http://goo.gl/9FauYh # # # #------------------------------------------# # Variables initialisation VERSION="Ldap2PostfixMap v0.2 - 2013, Yvan Godard [godardyvan@gmail.com]" help="no" SCRIPT_DIR=$(dirname $0) SCRIPT_NAME=$(basename $0) DNBASE="" VIRTUAL_MAP_FILE="" VIRTUAL_MAP_FILE_NEW=$(mktemp /tmp/ldap2postfixmap_mapfilenew.XXXXX) VIRTUAL_DOMAIN_RELAYED="" LDAP_SERVER_URL="ldap://127.0.0.1" DN_USER_BRANCH="cn=users" LDAPGROUP_OBJECTCLASS="allusers" LDAPGROUP="" LDAPADMIN_UID="" WITH_LDAP_BIND="no" LDAPADMIN_PASS="" POSTMAP_COMMAND="/usr/sbin/postmap" MAIN_DOMAIN="" MAIN_DOMAIN_DEFINED="no" EMAIL_REPORT="nomail" EMAIL_LEVEL=0 LOG="/var/log/ldap2postfixmap.log" LOG_ACTIVE=0 EMAIL_ADDRESS="" LOG_TEMP=$(mktemp /tmp/ldap2postfixmap_log.XXXXX) LIST_USERS=$(mktemp /tmp/ldap2postfixmap_users.XXXXX) LIST_DUPLICATED_EMAILS=$(mktemp /tmp/ldap2postfixmap_duplicatedemails.XXXXX) DUPLICATED_EMAILS=0 help () { echo -e "$VERSION\n" echo -e "This tool is designed to create/update a Postifx virtual map with addresses from a LDAP group or alls users on LDAP." echo -e "It works both with LDAP groups defined by objectClass posixGroup or groupOfNames." echo -e "The domain name of virtual addresses must be defined in /etc/postfix/main.cf as (e.g. as 'virtual_alias_domain')" echo -e "and the Postfix map filename must be defined as 'virtual_alias_maps' in /etc/postfix/main.cf." echo -e "\nDisclamer:" echo -e "This tool is provide without any support and guarantee." echo -e "\nSynopsis:" echo -e "./$SCRIPT_NAME [-h] | -d <base namespace> -f <map filename> -v <virtual domain relayed>" echo -e " [-s <LDAP server>] [-u <relative DN of user banch>]" echo -e " [-t <LDAP group objectClass>] [-g <relative DN of LDAP group>]" echo -e " [-a <LDAP admin UID>] [-p <LDAP admin password>] [-c <postmap command>]" echo -e " [-D <main domain>] [-e <email report option>] [-E <email address>] [-j <log file>]" echo -e "\n\t-h: prints this help then exit" echo -e "\nMandatory options:" echo -e "\t-d <base namespace>: the base DN for each LDAP entry (e.g.: 'dc=server,dc=office,dc=com')" echo -e "\t-f <map filename>: the full name of Postfix map filename (e.g.: '/etc/postfix/virtual_domain1')" echo -e "\t-v <virtual domain relayed>: the domain that must be relayed with or without '@' (e.g.: '@myvirtualdomain.com' or 'my.virtual_domain.com')" echo -e "\nOptional options:" echo -e "\t-s <LDAP server>: the LDAP server URL (default: '${LDAP_SERVER_URL}')" echo -e "\t-u <relative DN of user banch>: the relative DN of the LDAP branch that contains the users (e.g.: 'cn=allusers', default: '${DN_USER_BRANCH}')" echo -e "\t-t <LDAP group objectClass>: the type of group you want to sync, must be 'posixGroup' or 'groupOfNames'," echo -e "\t if unset, all users in LDAP user branch will be treated." echo -e "\t-g <relative DN of LDAP group>: the relative DN of the LDAP group to sync (e.g.: 'cn=mygroup,cn=groups' or 'cn=mygroup,ou=lists')," echo -e "\t must be filled if '-t' is used. " echo -e "\t-a <LDAP admin UID>: LDAP administrator UID, if bind is needed to access LDAP (e.g.: 'diradmin')" echo -e "\t-p <LDAP admin password>: the password of the LDAP administrator (asked if missing)" echo -e "\t-c <postmap command>: the full name of 'postmap' command (default: '${POSTMAP_COMMAND}')" echo -e "\t-D <main domain>: main domain to map to if the user has multiple email addresses registered in the LDAP, with or without '@' (e.g.: 'myrealdoamain.fr')" echo -e "\t-e <email report option>: settings for sending a report by email, must be 'onerror', 'forcemail' or 'nomail' (default: '${EMAIL_REPORT}')" echo -e "\t-E <email address>: email address to send the report (must be filled if '-e forcemail' or '-e onerror' options is used)" echo -e "\t-j <log file>: enables logging instead of standard output. Specify an argument for the full path to the log file" echo -e "\t (e.g.: '${LOG}') or use 'default' (${LOG})" exit 0 } error () { echo -e "\n*** Error ***" echo -e "Error ${1}: ${2}" echo -e "\n"${VERSION} alldone ${1} } alldone () { # Redirect standard outpout exec 1>&6 6>&- # Logging if needed [ $LOG_ACTIVE -eq 1 ] && cat $LOG_TEMP >> $LOG # Print current log to standard outpout [ $LOG_ACTIVE -ne 1 ] && cat $LOG_TEMP [ $EMAIL_LEVEL -ne 0 ] && [ $1 -ne 0 ] && cat $LOG_TEMP | mail -s "[ERROR : ldap2postfixmap.sh] on $(hostname)" ${EMAIL_ADDRESS} [ $EMAIL_LEVEL -eq 2 ] && [ $1 -eq 0 ] && cat $LOG_TEMP | mail -s "[OK : ldap2postfixmap.sh] on $(hostname)" ${EMAIL_ADDRESS} # Remove temp files rm -R /tmp/ldap2postfixmap* exit ${1} } optsCount=0 while getopts "hd:f:v:s:u:t:g:a:p:c:D:e:E:j:" OPTION do case "$OPTION" in h) help="yes" ;; d) DNBASE=${OPTARG} let optsCount=$optsCount+1 ;; f) VIRTUAL_MAP_FILE=${OPTARG} let optsCount=$optsCount+1 ;; v) VIRTUAL_DOMAIN_RELAYED=${OPTARG} let optsCount=$optsCount+1 ;; s) LDAP_SERVER_URL=${OPTARG} ;; u) DN_USER_BRANCH=${OPTARG} ;; t) LDAPGROUP_OBJECTCLASS=${OPTARG} ;; g) LDAPGROUP=${OPTARG} ;; a) LDAPADMIN_UID=${OPTARG} [[ ${LDAPADMIN_UID} != "" ]] && WITH_LDAP_BIND="yes" ;; p) LDAPADMIN_PASS=${OPTARG} ;; c) POSTMAP_COMMAND=${OPTARG} ;; D) MAIN_DOMAIN=${OPTARG} MAIN_DOMAIN_DEFINED="yes" ;; e) EMAIL_REPORT=${OPTARG} ;; E) EMAIL_ADDRESS=${OPTARG} ;; j) [ $OPTARG != "default" ] && LOG=${OPTARG} LOG_ACTIVE=1 ;; esac done if [[ ${optsCount} != "3" ]] then help alldone 1 fi if [[ ${help} = "yes" ]] then help fi if [[ ${WITH_LDAP_BIND} = "yes" ]] && [[ ${LDAPADMIN_PASS} = "" ]] then echo "Password for $LDAPADMIN_UID,$DN_USER_BRANCH,$DNBASE?" read -s LDAPADMIN_PASS fi # Redirect standard outpout to temp file exec 6>&1 exec >> $LOG_TEMP # Start temp log file echo -e "\n****************************** `date` ******************************\n" echo -e "$0 started for:" echo -e "\t-f <map filename>: ${VIRTUAL_MAP_FILE}" echo -e "\t-v <virtual domain relayed>: ${VIRTUAL_DOMAIN_RELAYED}" # Test of sending email parameter and check the consistency of the parameter email address if [[ ${EMAIL_REPORT} = "forcemail" ]]; then EMAIL_LEVEL=2 if [[ -z $EMAIL_ADDRESS ]]; then echo -e "You used option '-e ${EMAIL_REPORT}' but you have not entered any email info.\n\t-> We continue the process without sending email." EMAIL_LEVEL=0 else echo "${EMAIL_ADDRESS}" | grep '^[a-zA-Z0-9._-]*@[a-zA-Z0-9._-]*\.[a-zA-Z0-9._-]*$' > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "This address '${EMAIL_ADDRESS}' does not seem valid.\n\t-> We continue the process without sending email." EMAIL_LEVEL=0 fi fi elif [[ ${EMAIL_REPORT} = "onerror" ]]; then EMAIL_LEVEL=1 if [[ -z $EMAIL_ADDRESS ]]; then echo -e "You used option '-e ${EMAIL_REPORT}' but you have not entered any email info.\n\t-> We continue the process without sending email." EMAIL_LEVEL=0 else echo "${EMAIL_ADDRESS}" | grep '^[a-zA-Z0-9._-]*@[a-zA-Z0-9._-]*\.[a-zA-Z0-9._-]*$' > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "This address '${EMAIL_ADDRESS}' does not seem valid.\n\t-> We continue the process without sending email." EMAIL_LEVEL=0 fi fi elif [[ ${EMAIL_REPORT} != "nomail" ]]; then echo -e "\nOption '-e ${EMAIL_REPORT}' is not valid (must be: 'onerror', 'forcemail' or 'nomail').\n\t-> We continue the process without sending email." EMAIL_LEVEL=0 elif [[ ${EMAIL_REPORT} = "nomail" ]]; then EMAIL_LEVEL=0 fi # Verification of LDAPGROUP_OBJECTCLASS parameter [[ ${LDAPGROUP_OBJECTCLASS} != "allusers" ]] && [[ ${LDAPGROUP_OBJECTCLASS} != "posixGroup" ]] && [[ ${LDAPGROUP_OBJECTCLASS} != "groupOfNames" ]] && error 1 "Parameter '-t ${LDAPGROUP_OBJECTCLASS}' is not correct.\n-t must be 'posixGroup' or 'groupOfNames'" [[ ${LDAPGROUP_OBJECTCLASS} != "allusers" ]] && [[ ${LDAPGROUP} = "" ]] && error 1 "Parameter '-t ${LDAPGROUP_OBJECTCLASS}' is not used but -g is empty.\n-g must be filled with group name." # Verification of LDAP_SERVER_URL parameter [[ ${LDAP_SERVER_URL} = "" ]] && echo -e "You used option '-s' but you have not entered any LDAP url. Wi'll try to continue with url 'ldap://127.0.0.1'" && LDAP_SERVER_URL="ldap://127.0.0.1" # LDAP connection test echo -e "\nConnecting LDAP at $LDAP_SERVER_URL ..." [[ ${WITH_LDAP_BIND} = "yes" ]] && LDAP_COMMAND_BEGIN="ldapsearch -LLL -H ${LDAP_SERVER_URL} -D uid=${LDAPADMIN_UID},${DN_USER_BRANCH},${DNBASE} -w ${LDAPADMIN_PASS}" [[ ${WITH_LDAP_BIND} = "no" ]] && LDAP_COMMAND_BEGIN="ldapsearch -LLL -H ${LDAP_SERVER_URL} -x" ${LDAP_COMMAND_BEGIN} -b ${DN_USER_BRANCH},${DNBASE} > /dev/null 2>&1 if [ $? -ne 0 ]; then error 2 "Error connecting to LDAP server.\nPlease verify your LDAP_SERVER_URL and, if needed to bind LDAP, user and pass." else echo "OK!" fi # Test if user list is not empty if [[ ${LDAPGROUP_OBJECTCLASS} = "groupOfNames" ]]; then if [[ -z $(${LDAP_COMMAND_BEGIN} -b ${LDAPGROUP},${DNBASE} member | grep member: | awk '{print $2}' | awk -F',' '{print $1}') ]]; then error 3 "User list on LDAP group is empty!" else ${LDAP_COMMAND_BEGIN} -b ${LDAPGROUP},${DNBASE} member | grep member: | awk '{print $2}' | awk -F',' '{print $1}' >> $LIST_USERS fi elif [[ ${LDAPGROUP_OBJECTCLASS} = "posixGroup" ]]; then if [[ -z $(${LDAP_COMMAND_BEGIN} -b ${LDAPGROUP},${DNBASE} memberUid | grep memberUid: | awk '{print $2}' | sed -e 's/^./uid=&/g') ]]; then error 3 "User list on LDAP group is empty!" else ${LDAP_COMMAND_BEGIN} -b ${LDAPGROUP},${DNBASE} memberUid | grep memberUid: | awk '{print $2}' | sed -e 's/^./uid=&/g' >> $LIST_USERS fi elif [[ ${LDAPGROUP_OBJECTCLASS} = "allusers" ]]; then if [[ -z $(${LDAP_COMMAND_BEGIN} -b ${DN_USER_BRANCH},${DNBASE} uid | grep uid: | awk '{print $2}' | sed -e 's/^./uid=&/g') ]]; then error 3 "User list on LDAP ${DN_USER_BRANCH},${DNBASE} is empty" else ${LDAP_COMMAND_BEGIN} -b ${DN_USER_BRANCH},${DNBASE} uid | grep uid: | awk '{print $2}' | sed -e 's/^./uid=&/g' >> $LIST_USERS fi fi [[ ! -d ${VIRTUAL_MAP_FILE} ]] && mkdir -p $(dirname ${VIRTUAL_MAP_FILE}) # Processing each user echo -e "" for USER in $(sort -d -f -b ${LIST_USERS}) do PRINCIPAL_EMAIL="" echo "- Processing user: $USER" EMAILS=$(mktemp /tmp/ldap2postfixmap_emails.XXXXX) OTHER_EMAILS=$(mktemp /tmp/ldap2postfixmap_secondry_emails.XXXXX) ${LDAP_COMMAND_BEGIN} -b ${DN_USER_BRANCH},${DNBASE} $USER mail | grep mail: | awk '{print $2}' | grep '.' | sed '/^$/d' | awk '!x[$0]++' >> $EMAILS LINES_NUMBER=$(cat ${EMAILS} | grep "." | wc -l) echo -e "\tNumber of lines/emails: ${LINES_NUMBER}" if [[ ${LINES_NUMBER} -lt "2" ]]; then echo -e "\t-> This user doesn't have enough email addresses registered in LDAP. Skip this user." elif [[ ${LINES_NUMBER} -gt "1" ]]; then cat ${EMAILS} | grep ${VIRTUAL_DOMAIN_RELAYED} > /dev/null 2>&1 if [ $? -ne 0 ]; then echo -e "\t-> No email containing the virtual domain defined in LDAP. Skip this user." else cat ${EMAILS} | grep -v ${VIRTUAL_DOMAIN_RELAYED} >> ${OTHER_EMAILS} if [[ ${MAIN_DOMAIN_DEFINED} = "no" ]]; then PRINCIPAL_EMAIL=$(cat ${OTHER_EMAILS} | head -n 1) else if [[ -z $(cat ${OTHER_EMAILS} | grep ${MAIN_DOMAIN}) ]]; then PRINCIPAL_EMAIL=$(cat ${OTHER_EMAILS} | head -n 1) else PRINCIPAL_EMAIL=$(cat ${OTHER_EMAILS} | grep ${MAIN_DOMAIN} | head -n 1) fi fi if [[ -z ${PRINCIPAL_EMAIL} ]]; then echo -e "\t-> No email destination found not containing the virtual domain. Skip this user." else # Add test to avoid duplicate emails in postfix map table for VIRTUAL_EMAIL_ADDRESS in $(cat ${EMAILS} | grep ${VIRTUAL_DOMAIN_RELAYED}) do cat ${VIRTUAL_MAP_FILE_NEW} | grep ${VIRTUAL_EMAIL_ADDRESS} > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "# User ${USER},${DN_USER_BRANCH},${DNBASE}" >> ${VIRTUAL_MAP_FILE_NEW} echo "${VIRTUAL_EMAIL_ADDRESS} ${PRINCIPAL_EMAIL}" >> ${VIRTUAL_MAP_FILE_NEW} echo -e "\t${VIRTUAL_EMAIL_ADDRESS} > ${PRINCIPAL_EMAIL}" else DUPLICATED_EMAILS=1 echo "${VIRTUAL_EMAIL_ADDRESS}" >> ${LIST_DUPLICATED_EMAILS} echo "# User ${USER},${DN_USER_BRANCH},${DNBASE}" >> ${VIRTUAL_MAP_FILE_NEW} echo "# ... this email ${VIRTUAL_EMAIL_ADDRESS} is already used in postfix map." >> ${VIRTUAL_MAP_FILE_NEW} echo "# ... in order to avoid postmap crashes, we skip this user." >> ${VIRTUAL_MAP_FILE_NEW} echo -e "\t!!! ${VIRTUAL_EMAIL_ADDRESS} is already used in postfix map !!!" fi done fi fi fi done [[ ${DUPLICATED_EMAILS} -eq 1 ]] && DUPLICATED_EMAILS_INLINE=$(cat ${LIST_DUPLICATED_EMAILS} | sort -d -f -b | perl -p -e 's/\n/ /g') if [[ -z $(cat ${VIRTUAL_MAP_FILE_NEW}) ]]; then echo -e "\n-> Nothing to import in ${VIRTUAL_MAP_FILE}" else [[ -f ${VIRTUAL_MAP_FILE} ]] && mv ${VIRTUAL_MAP_FILE} ${VIRTUAL_MAP_FILE}.old echo "# Postmap file generated by ${SCRIPT_DIR}/${SCRIPT_NAME}" > ${VIRTUAL_MAP_FILE} echo "# ${VERSION}" >> ${VIRTUAL_MAP_FILE} echo "# `date`" >> ${VIRTUAL_MAP_FILE} echo "" >> ${VIRTUAL_MAP_FILE} cat ${VIRTUAL_MAP_FILE_NEW} >> ${VIRTUAL_MAP_FILE} ${POSTMAP_COMMAND} ${VIRTUAL_MAP_FILE} if [ $? -ne 0 ]; then ERROR_MESSAGE=$(echo ${?}) error 4 "Error while running command: ${POSTMAP_COMMAND} ${VIRTUAL_MAP_FILE}.\n${ERROR_MESSAGE}." else echo -e "\n-> Postmap OK" fi [[ ${DUPLICATED_EMAILS} -eq 1 ]] && error 5 "Problem with LDAP email entries.\nA virtual email address can only be used one time in a postfix virtual map.\nHave a look to these emails: ${DUPLICATED_EMAILS_INLINE}!" fi alldone 0