From 739c6ee525a4f7bb76b8fe2bd75e81a122764ced Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sat, 12 Oct 2019 12:43:24 +0300 Subject: Split maidag into three single-purpose tools Maidag operated in three modes: mda, url and lmtp. In mda mode it is normally started by sendmail with non-root privileges. In order to be able to write to other users' mailboxes, the binary must be setuid, which creates certain security threats. As these appear to be impossible to avoid in a single multi-purpose program, it has been decided to replace maidag with three single-purpose tools: mda, putmail, and lmtpd. The mda tool is a local mail delivery agent. It is the only one for which the setuid bit is required, so special measures have been taken to secure it. In particular, to avoid unverified user inputs it disallows to override any configuration settings from the command line. The two other tools provide the functionality of the url and lmtp mode. * Makefile.am (MAIDAG_DIR): Replace with MDA_DIR * configure.ac (MU_COND_MAILBOX_QUOTA): New conditional. Use names relative to ${top_builddir} instead of ".". * maidag: Remove. * mda/.gitignore: New file. * mda/Makefile.am: New file. * mda/lib/Makefile.am: New file. * mda/lib/deliver.c: New file. * mda/lib/forward.c: New file. * mda/lib/libmda.h: New file. * mda/lib/mailquota.c: New file. * mda/lib/script.c: New file. * mda/lib/util.c: New file. * mda/lmtpd.c: New file. * mda/mda.c: New file. * mda/putmail.c: New file. * mda/tests/.gitignore: New file. * mda/tests/Makefile.am: New file. * mda/tests/atlocal.in: New file. * mda/tests/input.msg: New file. * mda/tests/lmtpd.at: New file. * mda/tests/putmail.at: New file. * mda/tests/testsuite.at: New file. * doc/texinfo/programs/maidag.texi: Remove. * doc/texinfo/programs/mda.texi: New file. * doc/texinfo/programs/lmtpd.texi: New file. --- Makefile.am | 6 +- configure.ac | 16 +- doc/texinfo/Makefile.am | 4 +- doc/texinfo/mailutils.texi | 61 +-- doc/texinfo/programs.texi | 20 +- doc/texinfo/programs/lmtpd.texi | 66 +++ doc/texinfo/programs/maidag.texi | 671 ---------------------------- doc/texinfo/programs/mda.texi | 694 +++++++++++++++++++++++++++++ doc/texinfo/programs/putmail.texi | 83 ++++ doc/texinfo/sieve.texi | 6 +- maidag/.gitignore | 6 - maidag/Makefile.am | 59 --- maidag/deliver.c | 399 ----------------- maidag/forward.c | 229 ---------- maidag/lmtp.c | 710 ------------------------------ maidag/maidag.c | 592 ------------------------- maidag/maidag.h | 205 --------- maidag/mailquota.c | 319 -------------- maidag/script.c | 135 ------ maidag/tests/.gitignore | 6 - maidag/tests/Makefile.am | 69 --- maidag/tests/atlocal.in | 6 - maidag/tests/forward.at | 79 ---- maidag/tests/input.msg | 44 -- maidag/tests/lmtp.at | 58 --- maidag/tests/mda.at | 50 --- maidag/tests/testsuite.at | 32 -- maidag/tests/url-mbox.at | 34 -- maidag/util.c | 180 -------- mda/.gitignore | 3 + mda/Makefile.am | 72 +++ mda/lib/Makefile.am | 34 ++ mda/lib/deliver.c | 445 +++++++++++++++++++ mda/lib/forward.c | 268 +++++++++++ mda/lib/libmda.h | 129 ++++++ mda/lib/mailquota.c | 341 ++++++++++++++ mda/lib/script.c | 260 +++++++++++ mda/lib/util.c | 185 ++++++++ mda/lmtpd.c | 902 ++++++++++++++++++++++++++++++++++++++ mda/mda.c | 143 ++++++ mda/putmail.c | 76 ++++ mda/tests/.gitignore | 6 + mda/tests/Makefile.am | 67 +++ mda/tests/atlocal.in | 6 + mda/tests/input.msg | 44 ++ mda/tests/lmtpd.at | 58 +++ mda/tests/putmail.at | 34 ++ mda/tests/testsuite.at | 33 ++ 48 files changed, 4015 insertions(+), 3930 deletions(-) create mode 100644 doc/texinfo/programs/lmtpd.texi delete mode 100644 doc/texinfo/programs/maidag.texi create mode 100644 doc/texinfo/programs/mda.texi create mode 100644 doc/texinfo/programs/putmail.texi delete mode 100644 maidag/.gitignore delete mode 100644 maidag/Makefile.am delete mode 100644 maidag/deliver.c delete mode 100644 maidag/forward.c delete mode 100644 maidag/lmtp.c delete mode 100644 maidag/maidag.c delete mode 100644 maidag/maidag.h delete mode 100644 maidag/mailquota.c delete mode 100644 maidag/script.c delete mode 100644 maidag/tests/.gitignore delete mode 100644 maidag/tests/Makefile.am delete mode 100644 maidag/tests/atlocal.in delete mode 100644 maidag/tests/forward.at delete mode 100644 maidag/tests/input.msg delete mode 100644 maidag/tests/lmtp.at delete mode 100644 maidag/tests/mda.at delete mode 100644 maidag/tests/testsuite.at delete mode 100644 maidag/tests/url-mbox.at delete mode 100644 maidag/util.c create mode 100644 mda/.gitignore create mode 100644 mda/Makefile.am create mode 100644 mda/lib/Makefile.am create mode 100644 mda/lib/deliver.c create mode 100644 mda/lib/forward.c create mode 100644 mda/lib/libmda.h create mode 100644 mda/lib/mailquota.c create mode 100644 mda/lib/script.c create mode 100644 mda/lib/util.c create mode 100644 mda/lmtpd.c create mode 100644 mda/mda.c create mode 100644 mda/putmail.c create mode 100644 mda/tests/.gitignore create mode 100644 mda/tests/Makefile.am create mode 100644 mda/tests/atlocal.in create mode 100644 mda/tests/input.msg create mode 100644 mda/tests/lmtpd.at create mode 100644 mda/tests/putmail.at create mode 100644 mda/tests/testsuite.at diff --git a/Makefile.am b/Makefile.am index a0fb57c50..716be7a72 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,8 +32,8 @@ if MU_COND_IMAP4D IMAP4D_DIR = imap4d endif -if MU_COND_MAIDAG - MAIDAG_DIR = maidag +if MU_COND_MDA + MDA_DIR = mda endif if MU_COND_MAIL @@ -105,7 +105,7 @@ SUBDIRS = . \ $(FRM_DIR)\ $(POP3D_DIR)\ $(IMAP4D_DIR)\ - $(MAIDAG_DIR)\ + $(MDA_DIR)\ $(MAIL_DIR)\ $(SIEVE_DIR)\ $(MESSAGES_DIR)\ diff --git a/configure.ac b/configure.ac index c841acfbf..5c7717289 100644 --- a/configure.ac +++ b/configure.ac @@ -933,7 +933,7 @@ if test -n "$SQL_MODULES"; then USE_SQL=1 AC_DEFINE(USE_SQL) BUILD_SQL=libsql.la - SQLLIB=../sql/libsql.la + SQLLIB='${top_builddir}/sql/libsql.la' for module in $SQL_MODULES do @@ -957,7 +957,6 @@ if test -n "$SQL_MODULES"; then SQL_MODULES="$SQL_MODULES" fi]) fi - # LDAP support AC_ARG_WITH(ldap, @@ -980,6 +979,10 @@ if test $status_ldap = maybe; then fi +# Mailbox quota support +AM_CONDITIONAL([MU_COND_MAILBOX_QUOTA],[test -n "$status_dbm$status_mysql"]) + + # Virtual domain support MU_ENABLE_SUPPORT(virtual-domains) AC_SUBST(SITE_VIRTUAL_PWDDIR) @@ -1182,7 +1185,7 @@ GINT_INIT([gint],[2.2.0 with-guile], if test -z "$GUILE_BINDIR"; then GUILE_BINDIR="`guile-config info prefix`/bin" fi - LIBMU_SCM=../libmu_scm/libmu_scm.la + LIBMU_SCM='${top_builddir}/libmu_scm/libmu_scm.la' LIBMU_SCM_DEPS='${MU_LIB_MAILBOX} ${MU_LIB_MAILER}' MU_GUILE_SIEVE_MOD_DIR='$(GUILE_SITE)/$(PACKAGE)/sieve-modules' GINT_INCLUDES='${MU_APP_COMMON_INCLUDES}' @@ -1324,7 +1327,7 @@ MU_ENABLE_BUILD(imap4d,,,["$mu_build_servers" = yes],,[server_list]) MU_ENABLE_BUILD(comsat,,,["$mu_build_servers" = yes],,[server_list]) MU_ENABLE_BUILD(frm,,,["$mu_build_clients" = yes],,[client_list]) -MU_ENABLE_BUILD(maidag,,,["$mu_build_clients" = yes],,[client_list]) +MU_ENABLE_BUILD(mda,,,["$mu_build_clients" = yes],,[client_list]) MU_ENABLE_BUILD(mail,,,["$mu_build_clients" = yes],,[client_list]) AC_SUBST([MAILBINDIR],'${bindir}') @@ -1363,7 +1366,7 @@ AC_CONFIG_FILES([testsuite/Makefile testsuite/atlocal]) MU_CONFIG_TESTSUITE(libmailutils) MU_CONFIG_TESTSUITE(frm) -MU_CONFIG_TESTSUITE(maidag) +MU_CONFIG_TESTSUITE(mda) MU_CONFIG_TESTSUITE(mail) MU_CONFIG_TESTSUITE(messages) MU_CONFIG_TESTSUITE(readmsg) @@ -1518,7 +1521,8 @@ AC_CONFIG_FILES([ libproto/Makefile libproto/mbox/Makefile libproto/mailer/Makefile - maidag/Makefile + mda/Makefile + mda/lib/Makefile mail/Makefile mail/testsuite/Makefile libmailutils/auth/Makefile diff --git a/doc/texinfo/Makefile.am b/doc/texinfo/Makefile.am index 453997fbc..95438eb00 100644 --- a/doc/texinfo/Makefile.am +++ b/doc/texinfo/Makefile.am @@ -36,7 +36,9 @@ programs_TEXINFOS = \ programs/readmsg.texi\ programs/sieve.texi\ programs/guimb.texi\ - programs/maidag.texi\ + programs/mda.texi\ + programs/lmtpd.texi\ + programs/putmail.texi\ programs/mimeview.texi\ programs/pop3d.texi\ programs/imap4d.texi\ diff --git a/doc/texinfo/mailutils.texi b/doc/texinfo/mailutils.texi index b1a0a2724..f93f23367 100644 --- a/doc/texinfo/mailutils.texi +++ b/doc/texinfo/mailutils.texi @@ -141,7 +141,9 @@ Mailutils Programs * sieve:: Mail Filtering Utility. * guimb:: Mailbox Scanning and Processing Language. -* maidag:: General-purpose Mail Delivery Agent. +* mda:: Local Mail Delivery Agent. +* lmtpd:: LMTP Daemon. +* putmail:: Incorporate a Message to a Mailbox. * mimeview:: Universal File Viewer. @@ -202,29 +204,13 @@ Debugging @command{mail} --- Send and Receive Mail * Invoking Mail:: Command Line Options. +* Reading Mail:: Reading Mail. * Composing Mail:: Composing Mail. * MIME:: How to Attach Files. -* Reading Mail:: Reading Mail. * Scripting:: Scripting. * Mail Variables:: How to Alter the Behavior of @command{mail}. * Mail Configuration Files:: Personal and System-wide Configuration Files. -Composing Mail - -* Quitting Compose Mode:: -* Getting Help on Compose Escapes:: -* Editing the Message:: -* Modifying the Headers:: -* Enclosing Another Message:: -* Adding a File to the Message:: -* Attaching a File to the Message:: -* Printing And Saving the Message:: -* Signing the Message:: -* Printing Another Message:: -* Inserting Value of a Mail Variable:: -* Executing Other Mail Commands:: -* Executing Shell Commands:: - Reading Mail * Command Syntax:: Syntax of mail internal commands. @@ -245,6 +231,22 @@ Reading Mail * Incorporating New Mail:: * Shell Escapes:: +Composing Mail + +* Quitting Compose Mode:: +* Getting Help on Compose Escapes:: +* Editing the Message:: +* Modifying the Headers:: +* Enclosing Another Message:: +* Adding a File to the Message:: +* Attaching a File to the Message:: +* Printing And Saving the Message:: +* Signing the Message:: +* Printing Another Message:: +* Inserting Value of a Mail Variable:: +* Executing Other Mail Commands:: +* Executing Shell Commands:: + @command{movemail} --- Moves Mail from the User Maildrop to the Local File * Movemail Configuration:: @@ -274,28 +276,27 @@ A Sieve Interpreter * Passing Options to Scheme:: * Command Line Option Summary:: -maidag +mda -* Sendmail-maidag:: Using @command{maidag} with Sendmail. -* Exim-maidag:: Using @command{maidag} with Exim. -* MeTA1-maidag:: Using @command{maidag} with MeTA1. +* Sendmail-mda:: Using @command{mda} with Sendmail. +* Exim-mda:: Using @command{mda} with Exim. +* MeTA1-mda:: Using @command{mda} with MeTA1. * Mailbox Quotas:: -* Maidag Scripting:: +* MDA Scripting:: * Forwarding:: -* Url-mode:: Delivering Messages to a URL. -* Remote Mailbox Delivery:: -* Conf-maidag:: Maidag Configuration File Summary +* Conf-mda:: @command{mda} Configuration File Summary. +* Mailing lists:: How to implement Mailing Lists with @command{mda}. Mailbox Quotas * DBM Quotas:: Keeping Quotas in DBM File. * SQL Quotas:: Keeping Quotas in SQL Database. -Maidag Scripting +Scripting in @command{mda} -* Sieve Maidag Filters:: -* Scheme Maidag Filters:: -* Python Maidag Filters:: +* Sieve MDA Filters:: +* Scheme MDA Filters:: +* Python MDA Filters:: mimeview diff --git a/doc/texinfo/programs.texi b/doc/texinfo/programs.texi index c8c3b978d..f2de68767 100644 --- a/doc/texinfo/programs.texi +++ b/doc/texinfo/programs.texi @@ -32,7 +32,9 @@ syntax. * sieve:: Mail Filtering Utility. * guimb:: Mailbox Scanning and Processing Language. -* maidag:: General-purpose Mail Delivery Agent. +* mda:: Local Mail Delivery Agent. +* lmtpd:: LMTP Daemon. +* putmail:: Incorporate a Message to a Mailbox. * mimeview:: Universal File Viewer. @@ -2890,9 +2892,19 @@ Show payload information @include programs/guimb.texi @page -@node maidag -@section maidag -@include programs/maidag.texi +@node mda +@section mda +@include programs/mda.texi + +@page +@node lmtpd +@section lmtpd +@include programs/lmtpd.texi + +@page +@node putmail +@section putmail +@include programs/putmail.texi @page @node mimeview diff --git a/doc/texinfo/programs/lmtpd.texi b/doc/texinfo/programs/lmtpd.texi new file mode 100644 index 000000000..e0212db2f --- /dev/null +++ b/doc/texinfo/programs/lmtpd.texi @@ -0,0 +1,66 @@ +@c This is part of the GNU Mailutils manual. +@c Copyright (C) 1999-2019 Free Software Foundation, Inc. +@c See file mailutils.texi for copying conditions. +@comment ******************************************************************* +@pindex lmtpd +The @acronym{LMTP} is a local mail transport protocol defined in RFC +2033. GNU Mailutils is shipped with @command{lmtpd} - a daemon for +delivering messages using this protocol. + +The daemon shares most of its codebase and configuration with +@command{mda} and consequently provides the same features. +@xref{mda}, for a detailed description of these. + +The behavior of @command{lmtpd} is affected by the following configuration +statements: + +@multitable @columnfractions 0.3 0.6 +@headitem Statement @tab Reference +@item server @tab @xref{Server Settings} +@item acl @tab @xref{acl statement}. +@item tcp-wrappers @tab @xref{tcp-wrappers statement}. +@item debug @tab @xref{debug statement}. +@item mailbox @tab @xref{mailbox statement}. +@item locking @tab @xref{locking statement}. +@item pam @tab @xref{pam statement}. +@item sql @tab @xref{sql statement}. +@item virtdomain @tab @xref{virtdomain statement}. +@item radius @tab @xref{radius statement}. +@item ldap @tab @xref{ldap statement}. +@item auth @tab @xref{auth statement}. +@item mailer @tab @xref{mailer statement}. +@end multitable + +@menu +* MeTA1-lmtpd:: Using @command{lmtpd} with MeTA1. +@end menu + +@node MeTA1-lmtpd +@subsection Using @command{lmtpd} with MeTA1. +MeTA1 (@uref{http://meta1.org}) communicates with the delivery agent +using @acronym{LMTP}. + +The socket to listen for LMTP requests must be specified using the +@code{server} statement (@pxref{Server Settings}). For the purposes of +this section, let's suppose @command{lmtpd} will listen on a +@acronym{UNIX} socket @file{/var/spool/meta1/lmtpsock}. Then, the +following (minimal) @command{lmtpd} configuration will do the job: + +@example +# @r{Run as daemon.} +mode daemon; +# @r{Switch to this group after startup.} +group meta1c; +# @r{Configure server:} +server unix:///var/spool/meta1/lmtpsock @{ + transcript no; +@}; +@end example + +To configure MeTA1 to use this socket, add the following statement to +the @samp{smtpc} section in @file{/etc/meta1/meta1.conf}: + +@example + LMTP_socket="lmtpsock"; +@end example + diff --git a/doc/texinfo/programs/maidag.texi b/doc/texinfo/programs/maidag.texi deleted file mode 100644 index c66d4aefa..000000000 --- a/doc/texinfo/programs/maidag.texi +++ /dev/null @@ -1,671 +0,0 @@ -@c This is part of the GNU Mailutils manual. -@c Copyright (C) 1999-2019 Free Software Foundation, Inc. -@c See file mailutils.texi for copying conditions. -@comment ******************************************************************* -@pindex maidag -@UNREVISED - -The name @samp{maidag} stands for @i{Mai}l @i{d}elivery @i{ag}ent. It -is a general-purpose @acronym{MDA} offering a rich set of -features. It can operate both in traditional mode, reading the message -from its standard input, and in @acronym{LMTP} mode. @command{Maidag} -is able to deliver mail to any mailbox format, supported by GNU -Mailutils. These formats, among others, include @samp{smtp://}, -@samp{prog://} and @samp{sendmail://} which are -equivalent to forwarding a message over @acronym{SMTP} to a remote -node. Thus, @command{maidag} supersedes both @command{mail.local} and -@command{mail.remote} utilities from GNU Mailutils versions prior to -2.0. - -@command{Maidag} is also able to process incoming messages using -Sieve, Scheme or Python scripts and, based on results of this -processing, to take a decision on whether to actually deliver and -where to deliver them. Due to its extensive scripting facilities, -@command{maidag} offers much more flexibility than other popular -@acronym{MDA}s, such as @command{procmail}. - -@menu -* Sendmail-maidag:: Using @command{maidag} with Sendmail. -* Exim-maidag:: Using @command{maidag} with Exim. -* MeTA1-maidag:: Using @command{maidag} with MeTA1. -* Mailbox Quotas:: -* Maidag Scripting:: -* Forwarding:: -* Url-mode:: Delivering Messages to a URL. -* Remote Mailbox Delivery:: -* Conf-maidag:: Maidag Configuration File Summary -@end menu - -@node Sendmail-maidag -@subsection Using @command{maidag} with Sendmail. -@cindex Sendmail -When used as a @acronym{MDA} with Sendmail, @command{maidag} must be -invoked from the local mailer definition in the @file{sendmail.cf} -file. It must have the following flags set: @samp{lswS}. These mean: -the mailer is local, quote characters should be stripped off the -address before invoking the mailer, the user must have a valid account -on this machine and the userid should not be reset before calling the -mailer. Additionally, the flags @samp{fn} may be specified to allow -@command{maidag} to generate the usual @samp{From } envelope instead -of the one supplied by @command{sendmail}. - -If you wish to use @command{maidag} with non-local authentication, -such as @acronym{SQL} or @acronym{LDAP}, you also need to remove the -@samp{w} flag, since in that case the user is not required to have a -valid account on the machine that runs @command{sendmail}. - -Here is an example of mailer definition in @file{sendmail.cf} - -@example -Mlocal, P=/usr/local/sbin/maidag, - F=lsDFMAw5:/|@@qSPfhn9, - S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, - T=DNS/RFC822/X-Unix, - A=mail $u -@end example - -To define local mailer in @samp{mc} source file, it will suffice to -set: - -@example -define(`LOCAL_MAILER_PATH', `/usr/local/sbin/maidag') -define(`LOCAL_MAILER_ARGS', `mail $u') -@end example - -@node Exim-maidag -@subsection Using @command{maidag} with Exim. -@cindex Exim - -Using @command{maidag} with Exim is quite straightforward. The -following example illustrates the definition of the appropriate transport -and director in @file{exim.conf}: - -@example -# transport -maidag_pipe: - driver = pipe - command = /usr/local/sbin/maidag $local_part - return_path_add - delivery_date_add - envelope_to_add - -# director -maidag: - driver = localuser - transport = maidag_pipe -@end example - -@node MeTA1-maidag -@subsection Using @command{maidag} with MeTA1. -@cindex LMTP -@cindex MeTA1 -MeTA1 (@uref{http://meta1.org}) communicates with the delivery agent -using @acronym{LMTP}. - -LMTP mode is enabled in @command{maidag} by the @samp{delivery-mode lmtp} -statement. The socket to listen on must be specified using -@code{server} statement (@pxref{Server Settings}). For the purposes of -this section, let's suppose @command{maidag} will listen on a -@acronym{UNIX} socket @file{/var/spool/meta1/lmtpsock}. Then, the -following (minimal) @command{maidag} configuration will do the job: - -@example -# @r{Start in LMTP mode.} -delivery-mode lmtp; -# @r{Run as daemon.} -mode daemon; -# @r{Switch to this group after startup.} -group meta1c; -# @r{Configure server:} -server unix:///var/spool/meta1/lmtpsock @{ - transcript no; -@}; -@end example - -To configure MeTA1 to use this socket, add the following statement to -the @samp{smtpc} section in @file{/etc/meta1/meta1.conf}: - -@example - LMTP_socket="lmtpsock"; -@end example - -@node Mailbox Quotas -@subsection Mailbox Quotas - -@dfn{Mailbox quota} is a limit on the size of the mailbox. When a -mailbox size reaches this limit, @command{maidag} stops accepting -messages for this recipient and returns an error condition to the -sender. The error code is accompanied by the following error message: - -@example -@var{user}: mailbox quota exceeded for this recipient -@end example - -Furthermore, if accepting the incoming message would make the -mailbox size exceed the quota, such a message will be rejected as -well. In this case, the error message is: - -@example -@var{user}: message would exceed maximum mailbox size for this recipient -@end example - -In both cases, the default return code will be @samp{service -unavailable} (corresponding to the @acronym{SMTP} return code -@samp{550}), unless the following statement is present in the -@command{maidag} configuration file: - -@example -exit-quota-tempfail yes; -@end example - -@noindent -in which case a temporary error will be returned. - -The mailbox quota can be retrieved from the following sources: - -@enumerate 1 -@item Authentication method. -@item @acronym{DBM} file. -@item @acronym{SQL} database. -@end enumerate - -@menu -* DBM Quotas:: Keeping Quotas in DBM File. -* SQL Quotas:: Keeping Quotas in SQL Database. -@end menu - -@node DBM Quotas -@subsubsection Keeping Quotas in DBM File - -To use @acronym{DBM} quota database, GNU Mailutils must -be compiled with one of the following command line options: -@option{--with-gdbm}, @option{--with-berkeley-db}, @option{--with-ndbm}, -@option{--with-tokyocabinet}, or @option{--with-kyotocabinet}. -Examine the output of @command{maidag --show-config-options}, if not sure. - -The quota database should have the following structure: - -@table @asis -@item Key -Key represents the user name. Special key @samp{DEFAULT} means default -quota value, i.e. the one to be used if the user is not explicitly -listed in the database. - -@item Value -Mailbox quota for this user. If it is a number, it represents the -maximum mailbox size in bytes. A number may optionally be followed by -@samp{kb} or @samp{mb}, meaning kilobytes and megabytes, respectively. - -A special value @samp{NONE} means no mailbox size limit for this user. -@end table - -Here is an example of a valid quota database - -@example -# Default quota value: -DEFAULT 5mb - -# Following users have unlimited mailbox size -root NONE -smith NONE - -# Rest of users -plog 26214400 -karin 10mB -@end example - -To use the @acronym{DBM} quota database, specify its absolute name using -@code{quota-db} configuration statement, e.g.: - -@example -quota-db /etc/mail/quota.db; -@end example - -@node SQL Quotas -@subsubsection Keeping Quotas in SQL Database - -Configuration statement @code{quota-query} allows to specify a special -query to retrieve the quota from the database. Currently (as of mailutils -version @value{VERSION}) it is assumed that this table can be accessed -using the credentials set in @samp{sql} configuration statement -(@pxref{SQL Statement}). - -For example, suppose you have the following quota table: - -@example -create table mailbox_quota ( - user_name varchar(32) binary not null, - quota int, - unique (user_name) -); -@end example - -@noindent - -To retrieve user quota the following query can be used: - -@example -SELECT quota FROM mailbox_quota WHERE user_name='$@{user@}' -@end example - -There are no special provisions for specifying group quotas, similar to -@samp{DEFAULT} in @acronym{DBM} databases. This is because group quotas can -easily be implemented using @acronym{SQL} language. @command{Maidag} -always uses the first tuple from the set returned by mailbox quota -query. So, you may add a special entry to the @code{mailbox_quota} -table that would keep the group quota. In the discussion below we assume -that the @code{user_name} column for this entry is lexicographically -less than any other user name in the table. Let's suppose the group -quota name is @samp{00DEFAULT}. Then the following query: - -@example -SELECT quota -FROM mailbox_quota -WHERE user_name IN ('$@{user@}','00DEFAULT') -ORDER BY user_name DESC -@end example - -@noindent -will return two tuples if the user is found in -@code{mailbox_quota}. Due to @code{ORDER} statement, the first tuple -will contain the quota for the user, which will be used by -@command{maidag}. On the other hand, if the requested user name is not -present in the table, the above query will return a single tuple -containing the group quota. - -The following configuration statement instructs @command{maidag} to -use this query for retrieving the user quota: - -@example -quota-query "SELECT quota " - "FROM mailbox_quota " - "WHERE user_name IN ('$@{user@}','00DEFAULT') " - "ORDER BY user_name DESC"; -@end example - -@node Maidag Scripting -@subsection Maidag Scripting -@command{Maidag} can use global or per-user @dfn{mail filters} to -decide whether to deliver the message, and where to deliver it. As of -Mailutils version @value{VERSION}, such mail filters may be written in -the following languages: - -@itemize @bullet -@item Sieve -@xref{Sieve Language}. - -@item Scheme -@item Python -@end itemize - -Mail filters to use are specified using @samp{script} configuration -statement. The following meta-symbols can be used in its argument: - -@table @asis -@item ~ -@itemx %h -Expands to the recipient home directory. - -@item %u -Expands to the recipient user name. -@end table - -By default, the filename extension decides which scripting language will -be used. User can alter the choice using @samp{language} configuration -statement. For example: - -@example -language "python" -script "~/.maidag-py-filter" -@end example - -@menu -* Sieve Maidag Filters:: -* Scheme Maidag Filters:: -* Python Maidag Filters:: -@end menu - -@node Sieve Maidag Filters -@subsubsection Sieve Maidag Filters -@kwindex script -The file name of the Sieve filter to use is specified using -@samp{script} configuration statement. For example, the following -configuration statement: - -@example -script "~/.maidag.sv" -@end example - -@noindent -instructs @command{maidag} to use file @file{.maidag.sv} in the -recipient home directory as a Sieve filter. - -Normal message delivery is attempted if execution of the Sieve code -ended with @code{keep} action (either implicit or explicit). - -Other Sieve actions are executed as described in @ref{Actions}. For -example, to deliver message to another mailbox, use the -@code{fileinto} action. - -Any modifications to headers or body of the message performed by the -Sieve code will be visible in the delivered message. - -@node Scheme Maidag Filters -@subsubsection Scheme Maidag Filters -@kwindex script -The file name of the Scheme mail filter is specified using -@samp{script} configuration statement. For example, the following -configuration statement: - -@example -script "~/.maidag.scm" -@end example - -@noindent -instructs `maidag' to use file `.maidag.scm' in the recipient home -directory as a Scheme filter. - -@node Python Maidag Filters -@subsubsection Python Maidag Filters -@kwindex script - -The file name of the Python mail filter is specified using -@samp{script} configuration statement. For example, the following -configuration statement: - -@example -script "~/.maidag.py" -@end example - -@noindent -instructs `maidag' to use file `.maidag.py' in the recipient home -directory as a Python filter. - -@noindent -A simple example of a mail filter written in Python: - -@example -from mailutils import * -import maidag -import re - -msg = message.Message (maidag.message) -hdr = msg.header - -try: - if 'List-Post' in hdr and 'Received' in hdr \ - and hdr['Received'].find ('fencepost.gnu.org') != -1: - - # check envelope's sender address - m = re.search (r'([\w\-]+)-bounces\+([\w]+)=.*', - msg.envelope.get_sender ()) - if m: - lbox = m.group (1) - user = m.group (2) - # open destination mailbox and append message - dst = mailbox.MailboxDefault ('~/Mail/%s' % lbox) - dst.open ('ac') - dst.append_message (msg) - dst.close () - # set deleted flag so maidag will not deliver msg elsewhere - msg.attribute.set_deleted () -except Exception: - pass -@end example - -@node Forwarding -@subsection Forwarding -@cindex forward -@dfn{Forward file} is a special file in the user's home directory that -contains the email address of the mailbox where the user wants to -forward his mail. Normally, forward files are processed by -@acronym{MTA}. However, there are some @acronym{MTA} that lack this -feature. One of them is MeTA1. - -@command{Maidag} provides a forwarding feature that is useful to -compensate the lack of it. - -@kwindex forward-file -Name of the forward file is given using @code{forward-file} -configuration statement. A common usage is: - -@example -forward-file .forward; -@end example - -The forward file is always searched in the recipient home directory. - -@kwindex forward-file-checks -Before actually using the file, a number of safety checks are -performed on it. If the file fails to pass one of these checks, no -forwarding is performed and the message is delivered as usual. These -checks can be configured using @code{forward-file-checks} statement. -Its argument is a list of the following keywords: - -@table @asis -@item groupwritablefile -@itemx file_iwgrp -The file must not be group writable. - -@item worldwritablefile -@itemx file_iwoth -The file must not be world writable. - -@item linkedfileinwritabledir -@itemx link -The file cannot be a symlink in a writable directory. - -@item fileingroupwritabledir -@itemx dir_iwgrp -The file cannot reside in a group writable directory. - -@item fileinworldwritabledir -@itemx dir_iwoth -The file cannot reside in a world writable directory. - -@item all -All of the above checks. -@end table - -The default is @samp{forward-file-checks all}. - -Each of these keywords may be prefixed by @samp{no} to disable this -particular check. For example: - -@example -forward-file-checks (nodir_iwoth, nodir_iwgrp); -@end example - -@node Url-mode -@subsection Delivering Messages to a URL. -When invoked with the @option{--url} command line option, -@command{maidag} treats its arguments as a list of mailbox -@acronym{URL}s and attempts to deliver the message to each of them. - -For example: - -@example -$ maidag --url maildir:///home/smith/Mail -@end example - -The same effect has the @samp{delivery-mode url} configuration statement. - -@node Remote Mailbox Delivery -@subsection Remote Mailbox Delivery -@command{Maidag} can be used to deliver mail to remote mailboxes, such -as @samp{imap} or @samp{smtp}. If the mailbox @acronym{URL} -is @samp{smtp} or @samp{sendmail}, the message is -actually forwarded over @acronym{SMTP} to the remote node, so -@command{maidag} acts as a message transfer agent. For example: - -@example -$ maidag --url smtp://10.10.1.100:24 -@end example - -This command line will send the message to the machine -@samp{10.10.1.100} using port @samp{24} (private mail system). - -The @samp{prog} mailbox may be of special use. Delivering to -this mailbox results in invoking the specified command with the given -arguments and passing the message to its standard input. There are two -ways to specify a @samp{prog} mailbox: - -@table @asis -@item prog://@var{program}?@var{args} -Here, @var{program} is the absolute pathname of the program binary, -and @var{args} are its arguments, separated by @samp{&} signs. - -@item |@var{program} @var{args} -In this notation, @var{args} are command line arguments separated by -white space. -@end table - -In both cases, @var{args} do not include @code{argv[0]}. - -The @samp{prog} mailbox may be used, in particular, to implement -mailing lists with MeTA1. - -For example, suppose that the @command{maidag} configuration contains: - -@example -auth @{ - authorization sql:system; - authentication generic:system; -@} - -sql @{ - interface mysql; - db mail; - getpwnam "SELECT user as name, mailbox, " - "'x' as passwd, 500 as uid, 2 as gid, " - "'/nonexistent' as dir, '/sbin/nologin' as shell " - "FROM userdb " - "WHERE user='$@{user@}'"; -@} -@end example - -Then, the following entries in the @samp{userdb} table implement -@email{mailman@@yourdomain} mailing list: - -@example -mysql> select * from userdb; -+---------------------+---------------------------------------+ -| user | mailbox | -+---------------------+---------------------------------------+ -| mailman | |/usr/bin/mailman post mailman | -| mailman-admin | |/usr/bin/mailman admin mailman | -| mailman-bounces | |/usr/bin/mailman bounces mailman | -| mailman-confirm | |/usr/bin/mailman confirm mailman | -| mailman-join | |/usr/bin/mailman join mailman | -| mailman-leave | |/usr/bin/mailman leave mailman | -| mailman-owner | |/usr/bin/mailman owner mailman | -| mailman-request | |/usr/bin/mailman request mailman | -| mailman-subscribe | |/usr/bin/mailman subscribe mailman | -| mailman-unsubscribe | |/usr/bin/mailman unsubscribe mailman | -+---------------------+---------------------------------------+ -@end example - -@node Conf-maidag -@subsection Maidag Configuration File Summary - -The behavior of @command{maidag} is affected by the following configuration -statements: - -@multitable @columnfractions 0.3 0.6 -@headitem Statement @tab Reference -@item debug @tab @xref{debug statement}. -@item mailbox @tab @xref{mailbox statement}. -@item locking @tab @xref{locking statement}. -@item pam @tab @xref{pam statement}. -@item sql @tab @xref{sql statement}. -@item virtdomain @tab @xref{virtdomain statement}. -@item radius @tab @xref{radius statement}. -@item ldap @tab @xref{ldap statement}. -@item auth @tab @xref{auth statement}. -@item mailer @tab @xref{mailer statement}. -@item server @tab @xref{Server Settings}. Used only in -@acronym{LMTP} mode. -@item acl @tab @xref{acl statement}. -@item tcp-wrappers @tab @xref{tcp-wrappers statement}. -@end multitable - -@deffn {Maidag Config} delivery-mode @var{mode} -Configure delivery mode. The argument is one of: @samp{mda} (default), -@samp{url}, or @samp{lmtp}. -@end deffn - -@deffn {Maidag Config} ex-multiple-delivery-success @var{bool} -In case of multiple delivery, exit with code 0 if at least one -delivery has succeeded. -@end deffn - -@deffn {Maidag Config} ex-quota-tempfail @var{bool} -Indicate temporary failure if the recipient is over his mail quota. -By default, permanent failure is returned. @xref{Mailbox Quotas}. -@end deffn - -@deffn {Maidag Config} quota-db @var{file} -Set the name of DBM quota database file. @xref{DBM Quotas}. -@end deffn - -@deffn {Maidag Config} sieve-filter @var{pattern} -Set file name or name pattern of the Sieve filter file. -@xref{Sieve Maidag Filters}. -@end deffn - -@deffn {Maidag Config} message-id-header @var{name} -When logging Sieve actions, identify messages by the value of this -header. -@end deffn - -@deffn {Maidag Config} guile-filter @var{pattern} -File name or name pattern for Guile filter file. -@xref{Scheme Maidag Filters}. -@end deffn - -@deffn {Maidag Config} debug @var{flags} -Set additional debugging flags. Valid flags are: - -@table @asis -@item g -Print @command{guimb} stack traces. - -@item t -Enable @command{sieve} trace (@code{MU_SIEVE_DEBUG_TRACE}). - -@item i -Enable @command{sieve} instructions trace -(@code{MU_SIEVE_DEBUG_INSTR}). - -@item l -Log executed Sieve actions. -@end table -@end deffn - -@deffn {Maidag Config} stderr @var{bool} -Log to stderr instead of syslog. -@end deffn - -@deffn {Maidag Config} forward-file @var{file} -Process forward file @var{file}. @xref{Forwarding}. -@end deffn - -@deffn {Maidag Config} forward-file-checks @var{list} -Configure safety checks for the forward file. -@xref{Forwarding, forward-file-checks}. -@end deffn - -@deffn {Maidag Config} group @var{list} -In @acronym{LMTP} mode, retain supplementary groups from @var{list}. -@end deffn - -@deffn {Maidag Config} listen @var{url} -In @acronym{LMTP} mode, listen on @var{url}. Valid @acronym{URL}s are: -@samp{tcp://@var{host}:@var{port}} (note that port is mandatory), -@samp{file://@var{socket-file-name}} or -@samp{socket://@var{socket-file-name}}. -@end deffn - -@deffn {Maidag Config} reuse-address @var{bool} -Reuse existing address (@acronym{LMTP} mode). Default is @samp{yes}. -@end deffn diff --git a/doc/texinfo/programs/mda.texi b/doc/texinfo/programs/mda.texi new file mode 100644 index 000000000..acce8301f --- /dev/null +++ b/doc/texinfo/programs/mda.texi @@ -0,0 +1,694 @@ +@c This is part of the GNU Mailutils manual. +@c Copyright (C) 1999-2019 Free Software Foundation, Inc. +@c See file mailutils.texi for copying conditions. +@comment ******************************************************************* +@pindex mda +GNU local mail delivery agent reads a message from its standard input +and delivers it to one or more local recipients listed in the command +line. When we speak about @i{local} recipients, we mean that these +are system users that are known to the system that runs @command{mda}. +However, the mailboxes of these users can be local as well as remote +ones. @command{mda} is able to deliver mail to any mailbox format, +supported by GNU Mailutils. These formats, among others, include +@samp{smtp://}, @samp{prog://} and @samp{sendmail://} which are +equivalent to forwarding a message over @acronym{SMTP} to a remote +node. + +@command{Mda} is also able to process incoming messages using +Sieve, Scheme or Python scripts and, based on results of this +processing, to take a decision on whether to actually deliver and +where to deliver them. Due to its extensive scripting facilities, +@command{mda} offers much more flexibility than other popular +@acronym{MDA}s. + +@menu +* Sendmail-mda:: Using @command{mda} with Sendmail. +* Exim-mda:: Using @command{mda} with Exim. +* MeTA1-mda:: Using @command{mda} with MeTA1. +* Mailbox Quotas:: +* MDA Scripting:: +* Forwarding:: +* Conf-mda:: @command{mda} Configuration File Summary. +* Mailing lists:: How to implement Mailing Lists with @command{mda}. +@end menu + +@node Sendmail-mda +@subsection Using @command{mda} with Sendmail. +@cindex Sendmail +When used with Sendmail, @command{mda} must be invoked from the local +mailer definition in the @file{sendmail.cf} file. The flags +@samp{lswS} must be set for the mailer. These mean: the mailer is +local, quote characters should be stripped off the address before +invoking the mailer, the user must have a valid account on this +machine and the userid should not be reset before calling the mailer. +Additionally, the @samp{fn} flags may be specified to allow +@command{mda} to generate the usual @samp{From } envelope instead +of the one supplied by @command{sendmail}. + +If you wish to use @command{mda} with non-local authentication, +such as @acronym{SQL} or @acronym{LDAP}, you also need to remove the +@samp{w} flag, since in that case the user is not required to have a +valid account on the machine that runs @command{sendmail}. + +Here is an example of mailer definition in @file{sendmail.cf} + +@example +Mlocal, P=/usr/local/sbin/mda, + F=lsDFMAw5:/|@@qSPfhn9, + S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, + T=DNS/RFC822/X-Unix, + A=mail $u +@end example + +To define local mailer in @samp{mc} source file, it will suffice to +set: + +@example +define(`LOCAL_MAILER_PATH', `/usr/local/sbin/mda') +define(`LOCAL_MAILER_ARGS', `mail $u') +@end example + +@node Exim-mda +@subsection Using @command{mda} with Exim. +@cindex Exim + +Using @command{mda} with Exim is quite straightforward. The +following example illustrates the definition of the appropriate transport +and director in @file{exim.conf}: + +@example +# transport +mda_pipe: + driver = pipe + command = /usr/local/sbin/mda $local_part + return_path_add + delivery_date_add + envelope_to_add + +# director +mda: + driver = localuser + transport = mda_pipe +@end example + +@node MeTA1-mda +@subsection Using @command{mda} with MeTA1. +@cindex MeTA1 +MeTA1 (@uref{http://meta1.org}) communicates with the delivery agent +using @acronym{LMTP}. Instead of using @command{mda} you will have to +start the @acronym{LMTP} daemon @command{lmtpd} and configure MeTA1 to +communicate with it. @xref{MeTA1-lmtpd}, for details. + +@node Mailbox Quotas +@subsection Mailbox Quotas + +@dfn{Mailbox quota} is a limit on the size of the mailbox. When a +mailbox size reaches this limit, @command{mda} stops accepting +messages for this recipient and returns an error condition to the +sender. The error code is accompanied by the following error message: + +@example +@var{user}: mailbox quota exceeded for this recipient +@end example + +Furthermore, if accepting the incoming message would make the +mailbox size exceed the quota, such a message will be rejected as +well. In this case, the error message is: + +@example +@var{user}: message would exceed maximum mailbox size for this recipient +@end example + +In both cases, the default return code will be @samp{service +unavailable} (corresponding to the @acronym{SMTP} return code +@samp{550}), unless the following statement is present in the +@command{maidag} configuration file: + +@example +quota @{ + exit-tempfail yes; +@} +@end example + +@noindent +in which case a temporary error will be returned. + +The mailbox quota can be retrieved from the following sources: + +@enumerate 1 +@item Authentication method. +@item @acronym{DBM} file. +@item @acronym{SQL} database. +@end enumerate + +@menu +* DBM Quotas:: Keeping Quotas in DBM File. +* SQL Quotas:: Keeping Quotas in SQL Database. +@end menu + +@node DBM Quotas +@subsubsection Keeping Quotas in DBM File + +To use @acronym{DBM} quota database, GNU Mailutils must +be compiled with one of the following command line options: +@option{--with-gdbm}, @option{--with-berkeley-db}, @option{--with-ndbm}, +@option{--with-tokyocabinet}, or @option{--with-kyotocabinet}. +Examine the output of @command{mda --show-config-options}, if not sure. + +The quota database should have the following structure: + +@table @asis +@item Key +Key represents the user name. Special key @samp{DEFAULT} means default +quota value, i.e. the one to be used if the user is not explicitly +listed in the database. + +@item Value +Mailbox quota for this user. If it is a number, it represents the +maximum mailbox size in bytes. A number may optionally be followed by +@samp{kb} or @samp{mb}, meaning kilobytes and megabytes, respectively. + +A special value @samp{NONE} means no mailbox size limit for this user. +@end table + +Here is an example of a quota database in text form: + +@example +# Default quota value: +DEFAULT 5mb + +# Following users have unlimited mailbox size +root NONE +smith NONE + +# Rest of users +plog 26214400 +karin 10mB +@end example + +To use the @acronym{DBM} quota database, specify its absolute name using +the @code{database} configuration statement in the @code{quota} +section, e.g.: + +@example +quota @{ + database /etc/mail/quota.db; +@} +@end example + +@node SQL Quotas +@subsubsection Keeping Quotas in SQL Database + +User quotas can be kept in an SQL table as well. Currently (as of mailutils +version @value{VERSION}) it is assumed that this table can be accessed +using the credentials set in @samp{sql} configuration statement +(@pxref{SQL Statement}). + +For example, suppose you have the following quota table: + +@example +create table mailbox_quota ( + user_name varchar(32) binary not null, + quota int, + unique (user_name) +); +@end example + +@noindent + +To retrieve user quota the following query can be used: + +@example +SELECT quota FROM mailbox_quota WHERE user_name='$@{user@}' +@end example + +To define this query use the @code{sql-query} statement: + +@example +quota @{ + sql-query "SELECT quota " + "FROM mailbox_quota " + "WHERE user_name='$@{user@}'"; +@} +@end example + +There are no special provisions for specifying group quotas, similar to +@samp{DEFAULT} in @acronym{DBM} databases. This is because group quotas can +easily be implemented using @acronym{SQL} language. @command{Mda} +always uses the first tuple from the set returned by mailbox quota +query. So, you can add a special entry to the @code{mailbox_quota} +table that would keep the group quota. In the discussion below we assume +that the @code{user_name} column for this entry is lexicographically +less than any other user name in the table. Let's suppose the group +quota name is @samp{00DEFAULT}. Then the following query: + +@example +SELECT quota +FROM mailbox_quota +WHERE user_name IN ('$@{user@}','00DEFAULT') +ORDER BY user_name DESC +@end example + +@noindent +will return two tuples if the user is found in +@code{mailbox_quota}. Due to @code{ORDER} statement, the first tuple +will contain quota for the user, which will be used by +@command{mda}. On the other hand, if the requested user name is not +present in the table, the above query will return a single tuple +containing the group quota. + +The following configuration statement instructs @command{maidag} to +use this query for retrieving the user quota: + +@example +quota @{ + sql-query "SELECT quota " + "FROM mailbox_quota " + "WHERE user_name IN ('$@{user@}','00DEFAULT') " + "ORDER BY user_name DESC"; +@} +@end example + +@node MDA Scripting +@subsection Scripting in @command{mda} +@command{Mda} can use global or per-user @dfn{mail filters} to +decide whether to deliver the message, and where to deliver it. As of +Mailutils version @value{VERSION}, such mail filters may be written in +the following languages: + +@itemize @bullet +@item Sieve +@xref{Sieve Language}. + +@item Scheme +@item Python +@end itemize + +Mail filters to use are specified using @samp{script} configuration +statement. The following meta-symbols can be used in its argument: + +@table @asis +@item ~ +@itemx %h +Expands to the recipient home directory. + +@item %u +Expands to the recipient user name. +@end table + +@anchor{scripting language} +By default, the filename extension decides which scripting language will +be used. User can alter the choice using @samp{language} configuration +statement. For example: + +@example +script @{ + language python; + pattern "~/.maidag-py-filter"; +@} +@end example + +@menu +* Sieve MDA Filters:: +* Scheme MDA Filters:: +* Python MDA Filters:: +@end menu + +@node Sieve MDA Filters +@subsubsection Sieve MDA Filters +@kwindex script +The file name of the Sieve filter to use is specified using +@samp{script} configuration statement. For example, the following +configuration statement: + +@example +script @{ + pattern "~/.maidag.sv"; +@} +@end example + +@noindent +instructs @command{maidag} to use file @file{.maidag.sv} in the +recipient home directory as a Sieve filter. + +Normal message delivery is attempted if execution of the Sieve code +ended with @code{keep} action (either implicit or explicit). + +Other Sieve actions are executed as described in @ref{Actions}. For +example, to deliver message to another mailbox, use the +@code{fileinto} action. + +Any modifications to headers or body of the message performed by the +Sieve code will be visible in the delivered message. + +@node Scheme MDA Filters +@subsubsection Scheme MDA Filters +@kwindex script +The file name of the Scheme mail filter is specified using +@samp{script} configuration statement. For example, the following +configuration statement: + +@example +script @{ + pattern "~/.maidag.scm"; +@} +@end example + +@noindent +instructs @command{mda} to use file @file{.maidag.scm} in the +recipient home directory as a Scheme filter. + +@node Python MDA Filters +@subsubsection Python MDA Filters +@kwindex script + +The file name of the Python mail filter is specified using +@samp{script} configuration statement. For example, the following +configuration statement: + +@example +script @{ + pattern "~/.maidag.py"; +@} +@end example + +@noindent +instructs @command{mda} to use the file @file{.maidag.py} in the +recipient home directory as a Python filter. + +@noindent +A simple example of a mail filter written in Python: + +@example +from mailutils import * +import maidag +import re + +msg = message.Message (maidag.message) +hdr = msg.header + +try: + if 'List-Post' in hdr and 'Received' in hdr \ + and hdr['Received'].find ('fencepost.gnu.org') != -1: + + # check envelope's sender address + m = re.search (r'([\w\-]+)-bounces\+([\w]+)=.*', + msg.envelope.get_sender ()) + if m: + lbox = m.group (1) + user = m.group (2) + # open destination mailbox and append message + dst = mailbox.MailboxDefault ('~/Mail/%s' % lbox) + dst.open ('ac') + dst.append_message (msg) + dst.close () + # set deleted flag so maidag will not deliver msg elsewhere + msg.attribute.set_deleted () +except Exception: + pass +@end example + +@node Forwarding +@subsection Forwarding +@cindex forward +A @dfn{forward file} is a special file in the user's home directory that +contains the email address of the mailbox where the user wants to +forward his mail. Normally, forward files are processed by +@acronym{MTA}. However, there are some @acronym{MTA} that lack this +feature. One of them is MeTA1. + +@command{Mda} provides a forwarding feature that is useful to +compensate the lack of it. This feature is controlled by the +@code{forward} section in the configuration file: + +@example +forward @{ + # Process forward file. + file @var{name}; + # Configure safety checks for the forward file. + file-checks (@var{list}); +@} +@end example + +@kwindex file, forward +The name of the forward file is given by the @code{file} +statement in the @code{forward} section. A common usage is: + +@example +forward @{ + file .forward; +@} +@end example + +The forward file is always searched in the recipient home directory. + +Before actually using the forward file, a number of safety checks are +performed on it. If the file fails to pass one of these checks, no +forwarding is performed and the message is delivered as usual. These +checks are configured using the @code{forward.file-checks} statement: + +@example +forward @{ + file .forward; + file-checks (@var{list}); +@} +@end example + +Its argument is a list of the following keywords: + +@table @asis +@item groupwritablefile +@itemx file_iwgrp +The file must not be group writable. + +@item worldwritablefile +@itemx file_iwoth +The file must not be world writable. + +@item linkedfileinwritabledir +@itemx link +The file cannot be a symlink in a writable directory. + +@item fileingroupwritabledir +@itemx dir_iwgrp +The file cannot reside in a group writable directory. + +@item fileinworldwritabledir +@itemx dir_iwoth +The file cannot reside in a world writable directory. + +@item all +All of the above checks. +@end table + +The default is @samp{file-checks all}. + +Each of these keywords may be prefixed by @samp{no} to disable this +particular check. For example: + +@example +forward @{ + file-checks (nodir_iwoth, nodir_iwgrp); + file .forward; +@} +@end example + +@node Conf-mda +@subsection MDA Configuration File Summary + +The behavior of @command{mda} is affected by the following configuration +statements: + +@multitable @columnfractions 0.3 0.6 +@headitem Statement @tab Reference +@item debug @tab @xref{debug statement}. +@item mailbox @tab @xref{mailbox statement}. +@item locking @tab @xref{locking statement}. +@item pam @tab @xref{pam statement}. +@item sql @tab @xref{sql statement}. +@item virtdomain @tab @xref{virtdomain statement}. +@item radius @tab @xref{radius statement}. +@item ldap @tab @xref{ldap statement}. +@item auth @tab @xref{auth statement}. +@item mailer @tab @xref{mailer statement}. +@end multitable + +@deffn {MDA Config} stderr @var{bool} +If @var{bool} is true, log to standard error instead of syslog. +@end deffn + +@deffn {MDA Config} deliver @{ ... @} +This section contains general delivery settings: + +@example +deliver @{ + domain @var{string}; + exit-multiple-delivery-success @var{arg}; +@}; +@end example +@end deffn + +@deffn {deliver} domain @var{name} +Default email domain. +@end deffn + +@deffn {deliver} exit-multiple-delivery-success @var{arg}; +In case of multiple delivery, exit with code 0 if at least +one delivery succeeded. +@end deffn + + +@deffn {MDA Config} forward @{ ... @} +Controls the forwarding support: + +@example +forward @{ + file @var{name}; + file-checks (@var{list}); +@} +@end example +@end deffn + +@deffn {forward} file @var{name} +Defines the name of the forward file. E.g.: + +@example +forward @{ + file .forward; +@} +@end example + +@xref{Forwarding}, for a detailed description. +@end deffn + +@deffn {forward} file-checks (@var{list}) +Configures safety checks to be performed on the forward file prior to +using it. @xref{Forwarding}, for a detailed description. +@end deffn + +@deffn {MDA Config} quota @{ ... @} +This section configures mail quota support. @xref{Mailbox Quotas}, +for a detailed description. + +@example +quota @{ + database @var{name}; + sql-query @var{query}; + exit-tempfail @var{bool}; +@} +@end example +@end deffn + +@deffn {quota} database @var{name} +Sets the name of the quota database in DBM format. @xref{DBM Quotas}. +@end deffn + +@deffn {quota} sql-query @var{query} +If the quotas are kept in a SQL table, this statement defines the SQL +query to retrieve the quota for a given user name. @xref{SQL Quotas}. +@end deffn + +@deffn {quota} exit-tempfail @var{bool} +By default, if a message cannot be delivered because the user has +exceeded its mail quota, or its delivery would cause it to be +exceeded, @command{MDA} exits with the @samp{service unavailable} +status, which causes MTA to return the 550 code. If +@code{exit-tempfail} is set to true, it will return a temporary error +instead. +@end deffn + +@deffn {MDA Config} script @{ ... @} +Controls scripting. @xref{MDA Scripting}. + +@example +script @{ + language @var{lang}; + pattern @var{glob}; +@} +@end example +@end deffn + +@deffn {script} language @var{lang} +Defines the language that is used for scripting. Allowed values for +@var{lang} are: @samp{sieve}, @samp{scheme}, or @samp{python}. +@xref{scripting language}. +@end deffn + +@deffn {script} pattern @var{pat} +Defines the pattern for the script file name. The @samp{~} at the +begiining of the pattern will be replaced with the name of the home +directory of the recipient user. The @samp{%u} in pattern will be +replaced with the recipient user name, and @samp{%h} with the home +directory for that user. +@end deffn + +@node Mailing lists +@subsection Mailing list implementation + +This subsection explains how to implement mailing lists in +@command{mda} using the @samp{prog} mailbox scheme. + +Delivery to the @samp{prog} mailbox results in invoking the specified +command with the given arguments and passing the message to its +standard input. There are two ways to specify a @samp{prog} mailbox: + +@table @asis +@item prog://@var{program}?@var{args} +Here, @var{program} is the absolute pathname of the program binary, +and @var{args} are its arguments, separated by @samp{&} signs. + +@item |@var{program} @var{args} +In this notation, @var{args} are command line arguments separated by +white space. +@end table + +In both cases, @var{args} do not include @code{argv[0]}. + +The @samp{prog} mailbox can be used to implement mailing lists. + +For example, suppose that the @command{mda} configuration contains: + +@example +auth @{ + authorization (sql, system); + authentication (generic, system); +@} + +sql @{ + interface mysql; + db mail; + getpwnam "SELECT user as name, mailbox, " + "'x' as passwd, 500 as uid, 2 as gid, " + "'/nonexistent' as dir, '/sbin/nologin' as shell " + "FROM userdb " + "WHERE user='$@{user@}'"; +@} +@end example + +Then, the following entries in the @samp{userdb} table implement the +@email{mailman@@yourdomain} mailing list: + +@example +mysql> select * from userdb; ++---------------------+---------------------------------------+ +| user | mailbox | ++---------------------+---------------------------------------+ +| mailman | |/usr/bin/mailman post mailman | +| mailman-admin | |/usr/bin/mailman admin mailman | +| mailman-bounces | |/usr/bin/mailman bounces mailman | +| mailman-confirm | |/usr/bin/mailman confirm mailman | +| mailman-join | |/usr/bin/mailman join mailman | +| mailman-leave | |/usr/bin/mailman leave mailman | +| mailman-owner | |/usr/bin/mailman owner mailman | +| mailman-request | |/usr/bin/mailman request mailman | +| mailman-subscribe | |/usr/bin/mailman subscribe mailman | +| mailman-unsubscribe | |/usr/bin/mailman unsubscribe mailman | ++---------------------+---------------------------------------+ +@end example + + + + + + + diff --git a/doc/texinfo/programs/putmail.texi b/doc/texinfo/programs/putmail.texi new file mode 100644 index 000000000..9c6a02454 --- /dev/null +++ b/doc/texinfo/programs/putmail.texi @@ -0,0 +1,83 @@ +@c This is part of the GNU Mailutils manual. +@c Copyright (C) 1999-2019 Free Software Foundation, Inc. +@c See file mailutils.texi for copying conditions. +@comment ******************************************************************* +@pindex putmail +The @command{putmail} utility reads a message from its standard input +and delivers it to the specified mailbox URL. The usage is: + +@example +putmail @var{URL} +@end example + +For example, to deliver mail to a local mailbox +@file{/var/spool/mail/test}: + +@example +putmail /var/spool/mail/test +@end example + +Of course, this would work only it the @file{test} mailbox is writable +for the user invoking @command{putmail}. + +The @code{smtp} mailbox scheme can be used for remote delivery. For +example: + +@example +putmail 'smtp://mail.example.org;to=ovr' +@end example + +The program will initiate SMTP dialog with the server +@samp{mail.example.org} and will send the message from its standard +input to the user @samp{ovr} on that server. + +@menu +* putmail options:: +* putmail configuration:: +@end menu + +@node putmail options +@subsection putmail options + +@table @option +@item -f @var{email} +@itemx -r @var{email} +@itemx --from=@var{email} +Specify the sender address. If not used, the current user name +will be used. + +@item -l @var{name} +@itemx --language=@var{name} +Define scripting language for the next @option{--script} option. +Valid arguments are @samp{sieve}, @samp{scheme} and @samp{python}. + +@item --message-id-header=@var{header} +Use this header to identify messages when logging Sieve actions + +@item -s @var{name} +@itemx --script=@var{name} +Set the name of the user-defined mail filter. @xref{MDA Scripting}, +for a detailed discussion of the scripting feature. +@end table + +@node putmail configuration +@subsection putmail configuration + +The behavior of @command{putmail} is affected by the following configuration +statements: + +@multitable @columnfractions 0.3 0.6 +@headitem Statement @tab Reference +@item debug @tab @xref{debug statement}. +@item mailbox @tab @xref{mailbox statement}. +@item locking @tab @xref{locking statement}. +@item pam @tab @xref{pam statement}. +@item sql @tab @xref{sql statement}. +@item virtdomain @tab @xref{virtdomain statement}. +@item radius @tab @xref{radius statement}. +@item ldap @tab @xref{ldap statement}. +@item auth @tab @xref{auth statement}. +@item mailer @tab @xref{mailer statement}. +@end multitable + +The utility also accepts all MDA configuration statements: @xref{Conf-mda}. diff --git a/doc/texinfo/sieve.texi b/doc/texinfo/sieve.texi index 7d0a9168d..57f5980cf 100644 --- a/doc/texinfo/sieve.texi +++ b/doc/texinfo/sieve.texi @@ -1472,14 +1472,14 @@ and @code{:body} control what parts of the message to pipe to the command. @*Example: -The example below uses the @command{maidag} utility -(@pxref{maidag}) to forward the message to user @samp{gray} on +The example below uses the @command{putmail} utility +(@pxref{putmail}) to forward the message to user @samp{gray} on the machine @samp{mail.gnu.org}. @smallexample require "pipe"; -pipe "/usr/sbin/maidag --url smtp://gray@@mail.gnu.org" +pipe "/usr/bin/putmail smtp://gray@@mail.gnu.org" @end smallexample @end deftypefn diff --git a/maidag/.gitignore b/maidag/.gitignore deleted file mode 100644 index 6e29f25e4..000000000 --- a/maidag/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.gdbinit -.libs -Makefile -Makefile.in -maidag diff --git a/maidag/Makefile.am b/maidag/Makefile.am deleted file mode 100644 index db53c09d4..000000000 --- a/maidag/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2007-2019 Free Software Foundation, Inc. -# -# GNU Mailutils is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 3, or (at -# your option) any later version. -# -# GNU Mailutils is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Mailutils. If not, see . - -SUBDIRS = . tests - -sbin_PROGRAMS=maidag -maidag_SOURCES=\ - deliver.c\ - forward.c\ - lmtp.c\ - maidag.c\ - maidag.h\ - mailquota.c\ - script.c\ - util.c - -if MU_COND_DBM - LIBMU_DBM=../libmu_dbm/libmu_dbm.la -endif - -maidag_LDADD = \ - ../lib/libmuscript.a\ - ${MU_APP_LIBRARIES}\ - ${MU_LIB_SIEVE}\ - ${MU_LIB_MAILBOX}\ - ${MU_LIB_AUTH}\ - ${MU_LIB_MAILER}\ - @MU_AUTHLIBS@\ - ${MU_LIB_MAILUTILS} \ - @MU_COMMON_LIBRARIES@\ - @LIBMU_SCM@\ - @LIBMU_SCM_DEPS@\ - @MU_LIB_PY@\ - $(LIBMU_DBM)\ - @GUILE_LIBS@\ - @PYTHON_LIBS@\ - @DBMLIBS@\ - @MU_TCPWRAP_LIBRARIES@ - -AM_CPPFLAGS = -I${top_srcdir} @MU_APP_COMMON_INCLUDES@ @GUILE_INCLUDES@ \ - @PYTHON_INCLUDES@ - -install-exec-hook: - for i in $(sbin_PROGRAMS); do\ - chown root:mail $(DESTDIR)$(sbindir)/$$i;\ - chmod 4755 $(DESTDIR)$(sbindir)/$$i;\ - done diff --git a/maidag/deliver.c b/maidag/deliver.c deleted file mode 100644 index b074abe12..000000000 --- a/maidag/deliver.c +++ /dev/null @@ -1,399 +0,0 @@ -/* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 1999-2019 Free Software Foundation, Inc. - - GNU Mailutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - GNU Mailutils is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the