Authentication backends

Introduction

Modules described in this man page can be used to provide functionality to check validity of username-password pairs in accordance with some database. That is, they authenticate users.

Most likely, you are going to use these modules with 'auth' directive of IMAP (maddy-imap(5)) or SMTP endpoint (maddy-smtp(5)).

Most modules listed here are also usable as a table (see maddy-tables(5)) that contains all usernames known to the module. Exceptions are auth.external and pam as underlying interfaces do not define a way to check credentials existence.

External authentication module (auth.external)

Module for authentication using external helper binary. It looks for binary named maddy-auth-helper in $PATH and libexecdir and uses it for authentication using username/password pair.

The protocol is very simple: Program is launched for each authentication. Username and password are written to stdin, adding \n to the end. If binary exits with 0 status code - authentication is considered successful. If the status code is 1 - authentication is failed. If the status code is 2 - another unrelated error has happened. Additional information should be written to stderr.

auth.external {
    helper /usr/bin/ldap-helper
    perdomain no
    domains example.org
}

Configuration directives

Syntax: helper _file_path_

Location of the helper binary. Required.

Syntax: perdomain boolean
Default: no

Don't remove domain part of username when authenticating and require it to be present. Can be used if you want user@domain1 and user@domain2 to be different accounts.

Syntax: domains domains...
Default: not specified

Domains that should be allowed in username during authentication.

For example, if 'domains' is set to "domain1 domain2", then username, username@domain1 and username@domain2 will be accepted as valid login name in addition to just username.

If used without 'perdomain', domain part will be removed from login before check with underlying auth. mechanism. If 'perdomain' is set, then domains must be also set and domain part WILL NOT be removed before check.

PAM module (auth.pam)

Implements authentication using libpam. Alternatively it can be configured to use helper binary like auth.external module does.

maddy should be built with libpam build tag to use this module without 'use_helper' directive.

go get -tags 'libpam' ...
auth.pam {
    debug no
    use_helper no
}

Configuration directives

Syntax: debug boolean
Default: no

Enable verbose logging for all modules. You don't need that unless you are reporting a bug.

Syntax: use_helper boolean
Default: no

Use LibexecDirectory/maddy-pam-helper instead of directly calling libpam. You need to use that if: 1. maddy is not compiled with libpam, but maddy-pam-helper is built separately. 2. maddy is running as an unprivileged user and used PAM configuration requires additional privileges (e.g. when using system accounts).

For 2, you need to make maddy-pam-helper binary setuid, see README.md in source tree for details.

TL;DR (assuming you have the maddy group):

chown root:maddy /usr/lib/maddy/maddy-pam-helper
chmod u+xs,g+x,o-x /usr/lib/maddy/maddy-pam-helper

Shadow database authentication module (auth.shadow)

Implements authentication by reading /etc/shadow. Alternatively it can be configured to use helper binary like auth.external does.

auth.shadow {
    debug no
    use_helper no
}

Configuration directives

Syntax: debug boolean
Default: no

Enable verbose logging for all modules. You don't need that unless you are reporting a bug.

Syntax: use_helper boolean
Default: no

Use LibexecDirectory/maddy-shadow-helper instead of directly reading /etc/shadow. You need to use that if maddy is running as an unprivileged user privileges (e.g. when using system accounts).

You need to make maddy-shadow-helper binary setuid, see cmd/maddy-shadow-helper/README.md in source tree for details.

TL;DR (assuming you have maddy group):

chown root:maddy /usr/lib/maddy/maddy-shadow-helper
chmod u+xs,g+x,o-x /usr/lib/maddy/maddy-shadow-helper

Table-based password hash lookup (auth.pass_table)

This module implements username:password authentication by looking up the password hash using a table module (maddy-tables(5)). It can be used to load user credentials from text file (file module) or SQL query (sql_table module).

Definition:

auth.pass_table [block name] {
    table <table config>

}

Shortened variant for inline use:

pass_table <table> [table arguments] {
    [additional table config]
}

Example, read username:password pair from the text file:

smtp tcp://0.0.0.0:587 {
    auth pass_table file /etc/maddy/smtp_passwd
    ...
}

Password hashes

pass_table expects the used table to contain certain structured values with hash algorithm name, salt and other necessary parameters.

You should use 'maddyctl hash' command to generate suitable values. See 'maddyctl hash --help' for details.

maddyctl creds

If the underlying table is a "mutable" table (see maddy-tables(5)) then the 'maddyctl creds' command can be used to modify the underlying tables via pass_table module. It will act a "local credentials store" and will write appropriate hash values to the table.

Separate username and password lookup (auth.plain_separate)

This module implements authentication using username:password pairs but can use zero or more "table modules" (maddy-tables(5)) and one or more authentication providers to verify credentials.

auth.plain_separate {
    user ...
    user ...
    ...
    pass ...
    pass ...
    ...
}

How it works: - Initial username input is normalized using PRECIS UsernameCaseMapped profile. - Each table specified with the 'user' directive looked up using normalized username. If match is not found in any table, authentication fails. - Each authentication provider specified with the 'pass' directive is tried. If authentication with all providers fails - an error is returned.

Configuration directives

Syntax: user _table module_

Configuration block for any module from maddy-tables(5) can be used here.

Example:

user file /etc/maddy/allowed_users

Syntax: pass _auth provider_

Configuration block for any auth. provider module can be used here, even 'plain_split' itself.

The used auth. provider must provide username:password pair-based authentication.

Dovecot authentication client (auth.dovecot_sasl)

The 'dovecot_sasl' module implements the client side of the Dovecot authentication protocol, allowing maddy to use it as a credentials source.

Currently SASL mechanisms support is limited to mechanisms supported by maddy so you cannot get e.g. SCRAM-MD5 this way.

auth.dovecot_sasl {
    endpoint unix://socket_path
}

dovecot_sasl unix://socket_path

Configuration directives

Syntax: endpoint schema://address
Default: not set

Set the address to use to contact Dovecot SASL server in the standard endpoint format.

tcp://10.0.0.1:2222 for TCP, unix:///var/lib/dovecot/auth.sock for Unix domain sockets.