mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2024-11-22 02:17:26 +00:00
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')
|
c.execute('SELECT source, destination FROM aliases')
|
||||||
return [(row[0], row[1]) for row in c.fetchall()]
|
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):
|
def get_domain(emailaddr):
|
||||||
return emailaddr.split('@', 1)[1]
|
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):
|
def add_mail_user(email, pw, env):
|
||||||
if not validate_email(email, True):
|
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")
|
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)
|
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")
|
return kick(env, "mail user added")
|
||||||
|
|
||||||
def set_mail_password(email, pw, env):
|
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)
|
return ("That's not a user (%s)." % email, 400)
|
||||||
conn.commit()
|
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")
|
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):
|
if not validate_email(source, False):
|
||||||
return ("Invalid email address.", 400)
|
return ("Invalid email address.", 400)
|
||||||
|
|
||||||
@ -127,28 +130,84 @@ def add_mail_alias(source, destination, env):
|
|||||||
return ("Alias already exists (%s)." % source, 400)
|
return ("Alias already exists (%s)." % source, 400)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
# Update DNS/web in case any new domains are added.
|
if do_kick:
|
||||||
return kick(env, "alias added")
|
# 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)
|
conn, c = open_database(env, with_connection=True)
|
||||||
c.execute("DELETE FROM aliases WHERE source=?", (source,))
|
c.execute("DELETE FROM aliases WHERE source=?", (source,))
|
||||||
if c.rowcount != 1:
|
if c.rowcount != 1:
|
||||||
return ("That's not an alias (%s)." % source, 400)
|
return ("That's not an alias (%s)." % source, 400)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
|
|
||||||
# Update DNS and nginx in case any domains are removed.
|
if do_kick:
|
||||||
return kick(env, "alias removed")
|
# 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.
|
# Update DNS and nginx in case any domains are added/removed.
|
||||||
|
|
||||||
from dns_update import do_dns_update
|
from dns_update import do_dns_update
|
||||||
|
results.append( do_dns_update(env) )
|
||||||
|
|
||||||
from web_update import do_web_update
|
from web_update import do_web_update
|
||||||
results = [
|
results.append( do_web_update(env) )
|
||||||
do_dns_update(env),
|
|
||||||
mail_result + "\n",
|
|
||||||
do_web_update(env),
|
|
||||||
]
|
|
||||||
return "".join(s for s in results if s != "")
|
return "".join(s for s in results if s != "")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
@ -159,3 +218,7 @@ if __name__ == "__main__":
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
else:
|
else:
|
||||||
sys.exit(1)
|
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"]:
|
if domain == env["PRIMARY_HOSTNAME"]:
|
||||||
check_primary_hostname_dns(domain, env)
|
check_primary_hostname_dns(domain, env)
|
||||||
|
check_alias_exists("administrator@" + domain, env)
|
||||||
|
|
||||||
if domain in dns_domains:
|
if domain in dns_domains:
|
||||||
check_dns_zone(domain, env, dns_zonefiles)
|
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."
|
echo "Okay. I'm about to set up $EMAIL_ADDR for you."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
tools/mail.py user add $EMAIL_ADDR $EMAIL_PW # will ask for password if none given
|
# Create the user's mail account. This will ask for a password if none was given above.
|
||||||
tools/mail.py alias add hostmaster@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
tools/mail.py user add $EMAIL_ADDR $EMAIL_PW
|
||||||
tools/mail.py alias add postmaster@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
|
||||||
|
# Create an alias to which we'll direct all automatically-created administrative aliases.
|
||||||
|
tools/mail.py alias add administrator@$PRIMARY_HOSTNAME $EMAIL_ADDR
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user