Make PL/pgSQL function feed back identity for mailboxes/relocated when there
are catchall destinations.
Without catchall aliases, if no virtual_alias matches, the query can just
return NULL and Postfix will later check mailboxes/relocated for the address
to rewrite.
However, since virtual aliases are handled long before mailboxes/relocated,
a catchall alias would also catch mail to mailboxes and relocated addresses,
which we do not want.
The way to tell postfix to keep delivering is for the virtual alias map to
return the search key itself (identity function).
This patch changes the postfix_virtual_alias_maps Pl/pgSQL function to do
exactly that, but only if there are catchall destinations defined for the
domain in question — otherwise it returns NULL when no match is found.
# -*- coding: UTF-8 -*-# Copyright (c) 2008 - 2011, Pascal Volk# See COPYING for distribution information.""" VirtualMailManager.aliasdomain ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Virtual Mail Manager's AliasDomain class to manage alias domains."""fromVirtualMailManager.domainimportDomain,check_domainnamefromVirtualMailManager.constantsimport \ALIASDOMAIN_EXISTS,ALIASDOMAIN_ISDOMAIN,ALIASDOMAIN_NO_DOMDEST, \NO_SUCH_ALIASDOMAIN,NO_SUCH_DOMAINfromVirtualMailManager.errorsimportAliasDomainErrorasADErr_=lambdamsg:msgclassAliasDomain(object):"""Class to manage e-mail alias domains."""__slots__=('_gid','_name','_domain','_dbh')def__init__(self,dbh,domainname):"""Creates a new AliasDomain instance. Arguments: `dbh` : pyPgSQL.PgSQL.Connection a database connection for the database access `domainname` : basestring the name of the AliasDomain"""self._dbh=dbhself._name=check_domainname(domainname)self._gid=0self._domain=Noneself._load()def_load(self):"""Loads the AliasDomain's GID from the database and checks if the domain name is marked as primary."""dbc=self._dbh.cursor()dbc.execute('SELECT gid, is_primary FROM domain_name WHERE ''domainname = %s',(self._name,))result=dbc.fetchone()dbc.close()ifresult:ifresult[1]:raiseADErr(_(u"The domain '%s' is a primary domain.")%self._name,ALIASDOMAIN_ISDOMAIN)self._gid=result[0]defset_destination(self,dest_domain):"""Set the destination of a new AliasDomain or updates the destination of an existing AliasDomain. Argument: `dest_domain` : VirtualMailManager.Domain.Domain the AliasDomain's destination domain """assertisinstance(dest_domain,Domain)self._domain=dest_domaindefsave(self):"""Stores information about the new AliasDomain in the database."""ifself._gid>0:raiseADErr(_(u"The alias domain '%s' already exists.")%self._name,ALIASDOMAIN_EXISTS)ifnotself._domain:raiseADErr(_(u'No destination domain set for the alias domain.'),ALIASDOMAIN_NO_DOMDEST)ifself._domain.gid<1:raiseADErr(_(u"The target domain '%s' does not exist.")%self._domain.name,NO_SUCH_DOMAIN)dbc=self._dbh.cursor()dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) ''VALUES (%s, %s, FALSE)',(self._name,self._domain.gid))self._dbh.commit()dbc.close()self._gid=self._domain.giddefinfo(self):"""Returns a dict (keys: "alias" and "domain") with the names of the AliasDomain and its primary domain."""ifself._gid<1:raiseADErr(_(u"The alias domain '%s' does not exist.")%self._name,NO_SUCH_ALIASDOMAIN)dbc=self._dbh.cursor()dbc.execute('SELECT domainname FROM domain_name WHERE gid = %s AND ''is_primary',(self._gid,))domain=dbc.fetchone()dbc.close()ifdomain:return{'alias':self._name,'domain':domain[0]}else:# an almost unlikely case, isn't it?raiseADErr(_(u'There is no primary domain for the alias domain 'u"'%s'.")%self._name,NO_SUCH_DOMAIN)defswitch(self):"""Switch the destination of the AliasDomain to the new destination, set with the method `set_destination()`. """ifnotself._domain:raiseADErr(_(u'No destination domain set for the alias domain.'),ALIASDOMAIN_NO_DOMDEST)ifself._domain.gid<1:raiseADErr(_(u"The target domain '%s' does not exist.")%self._domain.name,NO_SUCH_DOMAIN)ifself._gid<1:raiseADErr(_(u"The alias domain '%s' does not exist.")%self._name,NO_SUCH_ALIASDOMAIN)ifself._gid==self._domain.gid:raiseADErr(_(u"The alias domain '%(alias)s' is already assigned "u"to the domain '%(domain)s'.")%{'alias':self._name,'domain':self._domain.name},ALIASDOMAIN_EXISTS)dbc=self._dbh.cursor()dbc.execute('UPDATE domain_name SET gid = %s WHERE gid = %s AND ''domainname = %s AND NOT is_primary',(self._domain.gid,self._gid,self._name))self._dbh.commit()dbc.close()self._gid=self._domain.giddefdelete(self):"""Delete the AliasDomain's record form the database. Raises an AliasDomainError if the AliasDomain doesn't exist. """ifself._gid<1:raiseADErr(_(u"The alias domain '%s' does not exist.")%self._name,NO_SUCH_ALIASDOMAIN)dbc=self._dbh.cursor()dbc.execute('DELETE FROM domain_name WHERE domainname = %s AND NOT ''is_primary',(self._name,))ifdbc.rowcount>0:self._dbh.commit()self._gid=0dbc.close()del_