Mlalias
mlalias in the overarching name for CSE's Postfix-based system for receiving and forwarding emails sent to addresses in the "@cse.unsw.edu.au" domain.
mlalias
is also the name of the command-line utility used to configure user-managed email forwarding and mailing lists.
- CSE does not provide email storage and so any email received for a CSE-domain address must be forwarded to one or more external email boxes, otherwise the email will be discarded.
- If a user has not used to
mlalias
to configure email forwarding, the email system will make a best-effort attempt to forward emails received for them to their UNSW-maintained "zID@unsw.edu.au" address.
- The email system allows email to be flexibly addressed to lists of users which are dynamically generated at time of receipt, such as all tutors, all tutors of a particular course, all students of a particular course in a particular teaching term, etc.
- The email system is primarily hosted on the server maillard, uses Postfix to receive and deliver emails, and accesss the New UDB and mlalias database tables hosted on the PostgreSQL server running on bandleader.
Database tables
The mlalias database tables are stored in the same database as those of the New UDB because of the loose coupling between zID and UNSW official email address. I.e., "zID@unsw.edu.au".
Here are the tables:
xcse=# \dt mlalias* List of relations Schema | Name | Type | Owner --------+-----------------------+-------+---------- public | mlalias_address | table | postgres public | mlalias_control | table | postgres public | mlalias_owner | table | postgres public | mlalias_sender | table | postgres public | mlalias_user_external | table | ldapudb (5 rows)
And here's an example output from the mlalias
command for reference:
vx01:~$ mlalias dude Alias: dude Description: CSE Special Dude Flags: personal, private, unprivileged, unmoderated, closed Addresses: cse.dude@unsw.edu.au assistant.dude@unsw.edu.au another.person@cse.unsw.edu.au Owners: root Senders:
Very quickly:
- The alias is the part of the email address before the "@" sign. In other words, the example above is for the address "dude@cse.unsw.edu.au"
- The flags determine the operation of the alias. Too complicated to explain in detail here, but some of it is to do with mlaliases being used as mailing lists rather than just for simple email forwarding.
- The list of addresses is to whom emails to this email should be forwarded. In this example there are three recipients listed. It is also possible to have an empty list which means any email to the alias would silently disappear.
- Owners are the CSE accounts which can make changes to the mlalias, such as change flags, alter the list of addresses, etc.
- Senders is list of email addresses which are authorised, on top of the owners, to send to the alias. This is typically used for moderated lists. In such case, if an email arrives for the alias from a non-listed sender it will be forwarded to the list owners for their attention.
mlalias_control
This table contains the "header" of each mlalias, its name and the configuration flags.
xcse=# \d mlalias_control Table "public.mlalias_control" Column | Type | Modifiers -------------------------+------------------------------+----------- name | character varying(128) | not null description | character varying(128) | personal_system | personal_system_type | not null public_private | public_private_type | not null privileged_unprivileged | privileged_unprivileged_type | not null moderated | moderated_type | not null open_closed_optional | open_closed_optional_type | not null
For an explanation of the flags, run mlalias -h flags
.
mlalias_owner, mlalias_address, mlalias_sender
Each entry in these tables is an entry in the corresponding field for a single mlalias.
xcse=# \d mlalias_owner Table "public.mlalias_owner" Column | Type | Modifiers -----------+------------------------+----------- mlalias | character varying | not null owner | character varying(128) | not null moderator | boolean | not null xcse=# \d mlalias_address Table "public.mlalias_address" Column | Type | Modifiers ----------------+------------------------+----------- mlalias | character varying | not null address | character varying(128) | not null address_action | address_action_type | not null xcse=# \d mlalias_sender Table "public.mlalias_sender" Column | Type | Modifiers ---------+------------------------+----------- mlalias | character varying | not null sender | character varying(128) | not null
Where the action happens
Email for "@cse.unsw.edu.au" is received by UNSW's IronPort email servers (which look for and filter out naughtiness) which then forward the email to CSE's maillard server.
maillard runs Postfix, so see /etc/postfix/main.cf
for its general configuration.
Postfix's /etc/postfix/master.cf
sets up a filter which does the mlalias magic. In master.cf
look for "mlalias_smtpd_filter" which points to the custom script /usr/local/mlalias/sbin/mlalias_smtpd_filter
.
mlalias_smtpd_filter
receives each email on its standard input, spools it, and then runs the custom /usr/local/mlalias/sbin/smartemail
to do the cleverness.
smartemail
then does the necessary content parsing, database queries and re-queuing the emails with new addresses via sendmail
. Emails may be queued, processed and expanded multiple times when mlaliases themselves refer to other mlaliases.
[Eventually] emails depart maillard, either going to UNSW's own email service for UNSW users, or to external email servers (such as gmail).
Note that when an mlalias destination address doesn't contain a "@" smartemail
will apply some simple heuristics to determine the full destination path, such as assuming an address that looks like z1234567 is a zID and sending it blindly to "z1234567@unsw.edu.au", or attempting to look for a CSE account in the New UDB with that name and then looking for any zID-like aliases for that user to send to.
mlalias expansion
Because the system allows mlaliases to refer to other mlaliases ad infinitum, it can be useful when debugging non-delivery problems to view a fully-expanded mlalias without actually sending anything.
There's a way of doing that:
vx01:~$ mlalias -E ss cse.csg@unsw.edu.au csgmail@local.delivery filtertest@local.delivery vx01:~$
Note that the addresses returned are fully-expanded and will always contain a domain component.
The "@local.delivery" addresses send to dynamically-generated address lists (see below).
Dynamically-generated address lists
As well as supporting static destination address lists configured by the mlalias
command, the email system recognises some destination domains as special virtual domains. Emails to ANY address in one of these domains will invoke a script which treats the address (before the "@") as a parameter to a list-generation script.
See /etc/postfix/virtual
for the list of such domains.
There are two parts to how this works.
local.delivery
The "@local.delivery" domain is configured in /etc/postfix/main.cf
to attempt local delivery, ie., on maillard itself, of emails sent to any address in that domain.
Let's take the "@enrol.program" virtual domain (configured in /etc/postfix/virtual
as an example).
Any email sent to "thing@enrol.program" inside CSE, including via mlalias exapnsion, will pass through maillard on its way out. Postfix on maillard will recognise this as an address in one of our virtual domains and will redirect the email to "enroldotprogram@local.delivery" as per the above file.
The "@local.delivery" tells Postfix that that delivery should be attempted to the local user account of enroldotprogram. The UDB shows that this user account's home directory is at /import/maillard/1/enroldotprogram
.
When Postfix attempts to deliver the email, it will find a .forward
file which contains:
|/home/enroldotprogram/dispatch
Which tells Postfix to run that script with the email as its standard input. The script can then do whatever it wants with it.
In fact, this example is how the enrol pageboy™ works. See The Enrol Pageboy.