Skip to content

Mapping features offered by the formula not sufficient to mirror postfix reqs #83

@ixs

Description

@ixs

Turns out, the mapping features offered by the formula are not sufficient to mirror real-life postfix deployments.

This issue serves as a discussion point to consider how to improve the current situation. It would probably also make a lot of sense to have a chat on IRC and discuss our options...

(NB: When I say mapping this can be read as lookup tables as well)

Postfix offers basically three ways of using mapping tables:

  • Static, in-memory or network based lookup tables which are set in main.cf:
    • transport_maps = static:relay_example.com:25
    • sender_canonical_maps = tcp:127.0.0.1:10001
  • External files which can optionally be hashed and generally follow a newline separated "key: value" format.
    transport_maps = hash:/etc/postfix/transports
  • Databases backends, e.g. ldap, mysql etc.
    • main.cf config item points at an external configuration file:
      transport_maps = mysql:/etc/postfix/transports.cf
    • external configuration file contains e.g. mysql query and connection parameters:
      dbname = mail
      hosts = db.example.com
      user = dbuser
      password = dbsecret
      query = SELECT "relay_example.com:25";
      

Detailed descriptions of the various types can be found at http://www.postfix.org/DATABASE_README.html.

The formula currently has a handful of different ways of configuring maps:

  • Configured as a static or in-memory lookup table in main.cf:
    virtual_uid_maps: static:5000
    This is handled as a regular parameter in main.cf
  • External hash-table:
    • Lookup table configured in main.cf:
      relay_recipient_maps: hash:/etc/postfix/relay_domains
    • Content configured via the pillar:
       postfix:
        mapping:
          relay_recipient_maps:
             - example.com: OK
      
  • VirtualUser support introduced in 65f86e6 which adds MySQL support to the lookup tables for virtual_alias_maps, virtual_mailbox_domains and virtual_mailbox_maps configured in the vmail pillar as well as a regular hashed transport lookup table configured in the transport pillar. The resulting configuration file uses a syntax that is found under the heading "OBSOLETE QUERY INTERFACE" in http://www.postfix.org/mysql_table.5.html.
  • An additional change layered on top in f8514b3 that does not really add new functionality but just adds a new pillar named mysql and uses the data included in that pillar to build a mysql query using the newer syntax described in http://www.postfix.org/mysql_table.5.html.

There are multiple shortcomings of the current design.

  1. Only a single parameter is supported per configuration item. Postfix has no trouble consulting multiple files per map item: e.g. transport_maps = hash:/etc/postfix/transport, mysql:/etc/postfix/transports.cf configured in main.cf would have postfix first try a lookup in the on-disk hashed file and if nothing found try a mysql query to a database. This is not supported by the formula.

  2. The VirtualUser related commits should probably never have been merged as is in the first place.
    The first commit adding VirtualUser support is written in a very specific way that is probably only usable for a single site as it encodes too many assumptions about the SQL database layout in the formula. Furthermore, the transport pillar should not have been added at all but instead the regular mapping pillar should have been used.
    The second commit repeats the mistake of the first commit by encoding site-specifics db schema assumptions in the SQL query and thus the formula.
    Furthermore, creating a new pillar entry to replicate the same functionality as already exists is kinda useless as well.

  3. A generic mapping configuration is not provided.

    • We'd need something that is able to do multiple entries per lookup table configuration item.
    • We'd need to both support traditional hashed key:value files as well as lookup configuration files for database backends.

I am not sure however, how to do these changes without breaking backwards compatibility.
I am not really worried about the virtualuser changes to be honest as I consider them broken already: They are that limited that most likely nobody other than the original contributors are using them.
I am unclear however, how to best allow for multiple entries per lookup table without breaking existing configurations as shown in the pillar.example file:

Currently supported:

postfix:
  config:
    smtp_sasl_password_maps: hash:/etc/postfix/sasl_passwd
  mapping:
    smtp_sasl_password_maps:
      - smtp.example.com: myaccount:somepassword

Future version, which might break backwards compatibility in case we cannot convert internally using jinja:

postfix:
  config:
    smtp_sasl_password_maps:
      - hash:/etc/postfix/sasl_passwd
      - mysql:/etc/postfix/sasl_passwd.cf
  mapping:
    smtp_sasl_password_maps:
      /etc/postfix/sasl_passwd:
        - smtp.example.com: myaccount:somepassword
      /etc/postfix/sasl_passwd.cf:
        dbname = mail
        hosts = db.example.com
        user = dbuser
        password = dbsecret
        query = SELECT password FROM sasl_passwd WHERE user == '%s';

This would basically move the existing mapping entries one level down and add a dict keyed off the filename to separate these. Alternatively, instead of a dict we could use a list and key it off the position, mapping the main.cf entry with the mapping entry.
It might be possible to offer backwards compatibility for existing setups but I am not 100% sure.

Before I start off and actually do the work, I'd like some feedback about the viability. What do other committers think? Worth it? Not mergeable because it breaks backwards compat?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions