Creating Lists in Sympa

Creating a list in Sympa involves a whole host of files interacting with each other, and all sorts of configuration snippets are used to create the filename of a resource needed to build the list. This attempts to describe what is taken from where, when a list is created from the command-line with a “sympa.pl --create_list” command.

The command (run as root) is
sympa.pl --create_list --input_file=<xml-file>

<xml-file> is a copy of /etc/sympa/sotontemplate.xml with tokens substituted in to set values which are inserted into the template config file. The <xml-file> can be deleted immediately after the list is created, it is not needed.

The
<xml-file> looks like this (note the *1* and so on for footnotes):

<?xml version="1.0" ?>
<list>
    <listname>comp3020</listname> *1*
    <type>soton</type> *2*
    <listtitle>comp3020</listtitle> *3*
    <subject>Students enrolled on COMP3020</subject>
    <editor>false</editor>
    <replypolicy>other_email</replypolicy>
    <replyaddress>god@ecs.soton.ac.uk</replyaddress>
    <tag>true</tag>
    <ismodule>true</ismodule>
    <isbuilding>false</isbuilding>
    <isuos>false</isuos>
    <owner multiple="1"><email>jkf@ecs.soton.ac.uk</email></owner> *4*
</list>

Notes:
  1. Sets the name of the list. Must be set in the XML file, not the template config file.
  2. Sets the value of "type" which is used to determine the location of the template config file used to construct the list's own config file. Must be set in the XML file. Location is /etc/sympa/create_list_templates/<type>/config.tt2
  3. These all set lower-case-named variables which are referenced in the template config file just mentioned.
  4. This sets the owner(s) of the list. Must be set in the XML file, not the template config file.
  5. Any characters such as “&”, "<" and ">" must be encoded as XML entities “&amp;", “&lt;” and “&gt;” or it errors out.

The XML file is meshed into the template config file in
/etc/sympa/create_list_templates/<type>/config.tt2 and then interpreted as a TT2 template (see www.tt2.org), and the output goes into the list's own individual config file which is at
    
/var/lib/sympa/list_data/all.soton.ac.uk/<listname>/config
That file is compiled by Sympa automatically when needed. It can be edited manually at any time, and Sympa will automatically recompile it as and when needed, without you needing to tell it about the change.

Note that the syntax of the template config file config.tt2 is very strict. It is constructed of a series of "paragraphs" which are a bunch of lines, with a blank line terminating the paragraph. It does not support comments, blank lines are *very* important, and leading white space on a line breaks everything. You have been warned!

Editors / Moderators


"Editors" is what Sympa calls list moderators. When they are used depends on the setting of the "send" parameter in the list config file. See the section on "Authorisation Scenarios".
The editors of a list are not statically defined, but are pulled from a SQL database query as needed. The data is cached by Sympa for speed.
If the list has any editors, the editors are defined in the list's config file by a "paragraph" like this:

editor_include
source editors *1*
reception mail
visibility conceal
source_parameters fpas-ecs-sys *2*

Notes:
  1. The <source> name is used to tell Sympa where to get the SQL query that will produce a list of the email addresses of the editors. The SQL query is defined in a data source file at
        
    /etc/sympa/data_sources/<source>.incl
  2. The comma-separated list of source_parameters are passed into the SQL data source file as param.0, param.1 and so on.

The data source file looks like this:

include_sql_query
  db_type mysql
  host localhost
  db_name all_lists
  user secretusername!
  passwd secretpassword!
  sql_query SELECT email FROM list_moderators WHERE list_address='[% param.0 %]'

Note this file *does* handle leading white space on lines.
Most of this is obvious, and it can handle any
<db_type> that is available in the Perl DBI modules.
The "source_parameters" from the list's config file are received as the "param" array, and the data source file is again a TT2 file (see www.tt2.org).

The default editor address for every list is “postmaster@ecs.soton.ac.uk".

Subscribers / Members


"Subscribers" are what Sympa calls list members. Only list subscribers receive a copy of postings to the list. So people can be able to post to a list without being able to receive a copy of their own posting. Posters who are subscribers always receive a copy of their own posting.

The subscriber list for a list is generated by an SQL query defined directly in the list's config file, it does not use a .incl file like the editors. The paragraphs defining the subscribers (taken from the template config file, not a list's real config file) look like this:

user_data_source include2 *1*

include_sql_queryname subscribers *2*
db_type mysql *3*
host localhost
db_name all_lists
user secretusername!
passwd secretpassword!
sql_query SELECT email FROM list_members WHERE list_address='[% listname %]' *4*

Notes:
  1. This tells Sympa what sort of data source it is. Only "include2" exists in Sympa now.
  2. Note this is for information only, and has no apparent effect.
  3. The database type can be anything supported by the Perl DBI modules.
  4. The [% listname %] is replaced with the name of the list when the list is created, it cannot be written indirectly like that in the list's own config file.

The list of subscribers for each list is cached by Sympa for a length of time defined by the
/etc/sympa/sympa.conf setting "default_ttl" and is set to 3600 seconds (1 hour) at the time of writing. So all changes to the table of list subscribers in the "all_lists" database will take up to 1 hour to propagate to the lists. There is no way for force an update of a list's subscribers.

Authorisation Scenari (Who Can Post?)


For the purposes of my project, virtually everything is closed and blocked, as users don't need to be able to use the capabilities of the email-driven or web-driven interface to manage lists, as they are all done automatically anyway. The only time authorisation scenari are used is to control who can post to a list.

The people that can post to a list are defined in the list's config file by the paragraph:

send <scenario-name>
where <scenario-name> tells it to read the rules of the scenario from
    
/etc/sympa/scenari/send.<scenario-name>

There is also a zero-length file
    
/etc/sympa/scenari/send.<scenario-name>:ignore
which tells Sympa not to tell anyone about the name or details of the scenario in the web management interface (which we're not using anyway).

The scenario file looks like this:

title.gettext Building list, Private, moderated for University staff

CustomCondition::not_from_campus([msg_header->Received]) smtp,dkim,smime,md5 -> reject(reason='from_offcampus')
is_subscriber([listname],[sender]) smtp,dkim,md5,smime -> do_it
is_editor([listname],[sender])     smtp,dkim,md5,smime -> do_it
is_subscriber('uos-staff',[sender]) smtp,dkim,md5,smime -> editorkey
true()                 smtp,dkim,smime,md5 -> reject(reason='send_building')

No comments are allowed. The syntax is strict. Each rule contains a condition, a list of methods, "->" and an action. The "smtp" method is the one we're interested in, it takes the address from the "From:" line of the email message. Rule conditions are matched in order from top to bottom, and the first matching rule is used, at which point rule processing stops.

Condition


This returns true or false. If true and the method used is listed, the action happened. You can include single-quoted strings like 'uos-staff', aliases for the name of the list, address of the sender and so on, function calls, all sorts of stuff. The '[sender]' can also be a regexp like '
/\@soton\.ac\.uk$/' to cause regexp matches instead of simple string comparison. You can also calls Perl functions, SQL queries, LDAP queries, all sorts of stuff. In a Perl condition, the name of the file is taken from "CustomCondition::<custom-filename>" and the file is located in
    
/etc/sympa/custom_conditions/<custom-filename>.pm
In this example the list of "Received:" headers is passed to it as a parameter. If it returns 1, the action is executed. If it returns 0, the action is not executed. If it returns undef, there was an error. Changes to the
<custom-filename>.pm file only take effect if Sympa is restarted with "service sympa restart".

Method


  • "smtp" is the one we're interested in. This takes the [sender] from the "From:" line of the incoming email message.

Action


  • "do_it" says the operation should be done (in this case, the message should be posted).
  • "reject(reason='<reason_code>')" says the message should be rejected and a message sent to the sender explaining why. See the "Responses and Messages" section below for information about the <reason_code>.
  • "editorkey" says the message should be saved locally and sent to all the editors of the list with an MD5 checksum. If the editor then sends Sympa the MD5 checksum in an email message telling it to proceed, the message will be posted. If the editor tells Sympa the message should be rejected, it is rejected (don't know what the sender is sent in this case). There are many other actions.

I have created a
send.<scenario-name> file for each type of list we use. Sympa does not notice changes to the scenari unless the datestamp on the list's config file is updated, at which point it updates the scenari for that one list. If you change a scenario file, you have to update the datestamp of the config files for all the lists that use it, forcing on-the-fly recompilation of the lists' config files.

Responses and Messages


You can change every bit of text ever output by Sympa, and the whole thing is multilingual too. I have stuck with en_US.

All the text output by email to users is contained in the TT2 files in
    
/etc/sympa/mail_tt2

Changes to files in this directory are automatically noticed by Sympa and processed immediately. Note this does not apply to the file "
sympa.po" below.

For example, the "
<reason_code>" above, used as a parameter to the "reject()" action, is defined in
    
/etc/sympa/mail_tt2/authorization_reject.tt2
The best way of finding which file contains the string you are trying to change is to search for a small bit of it in all the
mail_tt2/*.tt2 files. Beware the actual text output will not be in these files, but something very close to it will be if you are working in English. Continue reading to find out why...

Let's take the example of the
<reason_code> being "send_building". The "reject()" output messages are all defined in the file mentioned above, which is basically a huge "if...then...elsif...elsif...else" statement with hundreds of conditional expressions defined to test the "reason" parameter it is passed by Sympa.

Look through that file and find the "
send_building" "ELSIF" condition. That will produce this bit of code:

[% ELSIF reason == 'send_building' -%]
[%|loc()%]send_building[%END%]

The actual text output to the user is taken by internationalising the string "
send_building", which is passed to the "loc()" function which does the translation. The "loc()" function can have parameters passed to it which are used to insert various bits of text into the translated text. Most of the original text to be translated is *almost* exactly the same as the output of the English translation, but not quite. More fun that way round. A few greps will find the text you're looking to change. Happy

The translation (into better English) is done using the file
    
/usr/share/locale/en_US/LC_MESSAGES/sympa.mo
This file is a compiled version of the file
    
/etc/sympa/sympa.po
You can compile it by running
    
cd /etc/sympa && msgfmt -c -o /usr/share/locale/en_US/LC_MESSAGES/sympa.mo sympa.po

In
sympa.po there are multiple definitions which look like this:

msgid "send_building"
msgstr "University Building lists are restricted to occupants of the building, and Estates and Facilities staff.\n\n"
"If you think you should be able to post to this list, use http://all.soton.ac.uk/search to search for yourself by staff/student number, and be sure you are sending from the correct address."
  • msgid -- This is the text value passed to loc() in the file authorization_reject.tt2 described above.
  • msgstr -- This line, and every line starting '"' immediately after it, define the actual text that is sent to the user.
If you change sympa.po, you must restart Sympa completely with
    
service sympa restart
Changes will not take effect until Sympa restarts.

Regular Tasks


Many mailing lists email all their subscribers automatically at the start of each month telling them they are subscribed to that list, and how to unsubscribe and post successfully. The frequency of such actions are given in the list's config file by the paragraphs:

expire_task never

remind_task never

The frequency in the "<action>_task <task_model>" statement is described in the list task model file
    
/etc/sympa/list_task_models/<action>.<task_model>.task
so "
expire_task never" is described in
    
/etc/sympa/list_task_models/expire.never.task

In my project expiry and reminders are not needed nor wanted. So to stop them working, their frequencies have been set to 1000 years. The reason for this is fairly obvious if you look at the structure and syntax of one of the task model files.
Comments

Resending Unix Mbox Files

Unfortunately someone screwed up the installation of one of our servers so that mail to local addresses was being delivered into /var/spool/mail/ instead of being sent onwards to our SMTP server.

Getting the sendmail.mc correct was the easy bit, there is a simple
“null client” sendmail.mc file I wrote years ago which does that nicely.

The hard bit was taking all the Unix mbox files in /var/spool/mail and /var/mail and re-delivering them all to their intended recipients. The bit most people get wrong is the separator between messages. The separator is
not a line starting with “From “. The separator is a blank line followed by a line starting with “From “. So I wrote my own script to do it which you are very welcome to download and use.
Comments