manage hostmaster@ and postmaster@ automatically, create administrator@ during setup instead
closes #94
This commit is contained in:
parent
22a010ecb9
commit
41b3df6d78
|
@ -43,10 +43,13 @@ def get_mail_aliases(env):
|
|||
c.execute('SELECT source, destination FROM aliases')
|
||||
return [(row[0], row[1]) for row in c.fetchall()]
|
||||
|
||||
def get_mail_domains(env):
|
||||
def get_mail_domains(env, filter_aliases=lambda alias : True):
|
||||
def get_domain(emailaddr):
|
||||
return emailaddr.split('@', 1)[1]
|
||||
return set([get_domain(addr) for addr in get_mail_users(env)] + [get_domain(addr1) for addr1, addr2 in get_mail_aliases(env)])
|
||||
return set(
|
||||
[get_domain(addr) for addr in get_mail_users(env)]
|
||||
+ [get_domain(source) for source, target in get_mail_aliases(env) if filter_aliases((source, target)) ]
|
||||
)
|
||||
|
||||
def add_mail_user(email, pw, env):
|
||||
if not validate_email(email, True):
|
||||
|
@ -91,7 +94,7 @@ def add_mail_user(email, pw, env):
|
|||
shutil.copyfile(utils.CONF_DIR + "/dovecot_sieve.txt", user_mail_dir + "/.dovecot.sieve")
|
||||
os.chown(user_mail_dir + "/.dovecot.sieve", maildirstat.st_uid, maildirstat.st_gid)
|
||||
|
||||
# Update DNS/web in case any new domains are added.
|
||||
# Update things in case any new domains are added.
|
||||
return kick(env, "mail user added")
|
||||
|
||||
def set_mail_password(email, pw, env):
|
||||
|
@ -113,10 +116,10 @@ def remove_mail_user(email, env):
|
|||
return ("That's not a user (%s)." % email, 400)
|
||||
conn.commit()
|
||||
|
||||
# Update DNS/web in case any domains are removed.
|
||||
# Update things in case any domains are removed.
|
||||
return kick(env, "mail user removed")
|
||||
|
||||
def add_mail_alias(source, destination, env):
|
||||
def add_mail_alias(source, destination, env, do_kick=True):
|
||||
if not validate_email(source, False):
|
||||
return ("Invalid email address.", 400)
|
||||
|
||||
|
@ -127,28 +130,84 @@ def add_mail_alias(source, destination, env):
|
|||
return ("Alias already exists (%s)." % source, 400)
|
||||
conn.commit()
|
||||
|
||||
# Update DNS/web in case any new domains are added.
|
||||
return kick(env, "alias added")
|
||||
if do_kick:
|
||||
# Update things in case any new domains are added.
|
||||
return kick(env, "alias added")
|
||||
|
||||
def remove_mail_alias(source, env):
|
||||
def remove_mail_alias(source, env, do_kick=True):
|
||||
conn, c = open_database(env, with_connection=True)
|
||||
c.execute("DELETE FROM aliases WHERE source=?", (source,))
|
||||
if c.rowcount != 1:
|
||||
return ("That's not an alias (%s)." % source, 400)
|
||||
conn.commit()
|
||||
|
||||
# Update DNS and nginx in case any domains are removed.
|
||||
return kick(env, "alias removed")
|
||||
if do_kick:
|
||||
# Update things in case any domains are removed.
|
||||
return kick(env, "alias removed")
|
||||
|
||||
def kick(env, mail_result=None):
|
||||
results = []
|
||||
|
||||
# Inclde the current operation's result in output.
|
||||
|
||||
if mail_result is not None:
|
||||
results.append(mail_result + "\n")
|
||||
|
||||
# Create hostmaster@ for the primary domain if it does not already exist.
|
||||
# Default the target to administrator@ which the user is responsible for
|
||||
# setting and keeping up to date.
|
||||
|
||||
existing_aliases = get_mail_aliases(env)
|
||||
|
||||
administrator = "administrator@" + env['PRIMARY_HOSTNAME']
|
||||
|
||||
def ensure_admin_alias_exists(source):
|
||||
# Does this alias exists?
|
||||
for s, t in existing_aliases:
|
||||
if s == source:
|
||||
return
|
||||
|
||||
# Doesn't exist.
|
||||
add_mail_alias(source, administrator, env, do_kick=False)
|
||||
results.append("added alias %s (=> %s)\n" % (source, administrator))
|
||||
|
||||
ensure_admin_alias_exists("hostmaster@" + env['PRIMARY_HOSTNAME'])
|
||||
|
||||
# Get a list of domains we serve mail for, except ones for which the only
|
||||
# email on that domain is a postmaster/admin alias to the administrator.
|
||||
|
||||
real_mail_domains = get_mail_domains(env,
|
||||
filter_aliases = lambda alias : \
|
||||
(not alias[0].startswith("postmaster@") \
|
||||
and not alias[0].startswith("admin@")) \
|
||||
or alias[1] != administrator \
|
||||
)
|
||||
|
||||
# Create postmaster@ and admin@ for all domains we serve mail on.
|
||||
# postmaster@ is assumed to exist by our Postfix configuration. admin@
|
||||
# isn't anything, but it might save the user some trouble e.g. when
|
||||
# buying an SSL certificate.
|
||||
for domain in real_mail_domains:
|
||||
ensure_admin_alias_exists("postmaster@" + domain)
|
||||
ensure_admin_alias_exists("admin@" + domain)
|
||||
|
||||
# Remove auto-generated hostmaster/postmaster/admin on domains we no
|
||||
# longer have any other email addresses for.
|
||||
for source, target in existing_aliases:
|
||||
user, domain = source.split("@")
|
||||
if user in ("postmaster", "admin") and domain not in real_mail_domains \
|
||||
and target == administrator:
|
||||
remove_mail_alias(source, env, do_kick=False)
|
||||
results.append("removed alias %s (was to %s; domain no longer used for email)\n" % (source, target))
|
||||
|
||||
def kick(env, mail_result):
|
||||
# Update DNS and nginx in case any domains are added/removed.
|
||||
|
||||
from dns_update import do_dns_update
|
||||
results.append( do_dns_update(env) )
|
||||
|
||||
from web_update import do_web_update
|
||||
results = [
|
||||
do_dns_update(env),
|
||||
mail_result + "\n",
|
||||
do_web_update(env),
|
||||
]
|
||||
results.append( do_web_update(env) )
|
||||
|
||||
return "".join(s for s in results if s != "")
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -159,3 +218,7 @@ if __name__ == "__main__":
|
|||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "update":
|
||||
from utils import load_environment
|
||||
print(kick(load_environment()))
|
||||
|
|
|
@ -55,6 +55,7 @@ def run_domain_checks(env):
|
|||
|
||||
if domain == env["PRIMARY_HOSTNAME"]:
|
||||
check_primary_hostname_dns(domain, env)
|
||||
check_alias_exists("administrator@" + domain, env)
|
||||
|
||||
if domain in dns_domains:
|
||||
check_dns_zone(domain, env, dns_zonefiles)
|
||||
|
|
|
@ -222,8 +222,10 @@ if [ -z "`tools/mail.py user`" ]; then
|
|||
echo "Okay. I'm about to set up $EMAIL_ADDR for you."
|
||||
fi
|
||||
|
||||
tools/mail.py user add $EMAIL_ADDR $EMAIL_PW # will ask for password if none given
|
||||
tools/mail.py alias add hostmaster@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
||||
tools/mail.py alias add postmaster@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
||||
# Create the user's mail account. This will ask for a password if none was given above.
|
||||
tools/mail.py user add $EMAIL_ADDR $EMAIL_PW
|
||||
|
||||
# Create an alias to which we'll direct all automatically-created administrative aliases.
|
||||
tools/mail.py alias add administrator@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
||||
fi
|
||||
|
||||
|
|
Loading…
Reference in New Issue