Commit 11637b0f 11637b0f262db62b4dc466cefb9315098a1a995a by Sergey Poznyakoff

New maidag mode: --url

* NEWS: Update.
* doc/texinfo/libmuauth.texi: Update.
* doc/texinfo/mailutils.texi: Update.
* doc/texinfo/programs.texi: Update.

* include/mailutils/mailbox.h (mu_mailbox_create_from_url): New
function.
* include/mailutils/mutil.h (mu_aget_user_email_domain): New
function.
* libproto/include/address0.h: Remove obsolete comment.
* libproto/remote/mbox.c (remote_mbox_append_message): If
recipient address is not given, try to construct it from the URL.
* mailbox/mailbox.c (mu_mailbox_create_from_url): New function.
* mailbox/mutil.c (mu_aget_user_email_domain): New function.

* maidag/deliver.c (deliver_to_user): Mailbox and auth must be
freed by the caller.
(deliver_url): New function.
(deliver): Rewrite to allow for delivering to mailboxes explicitly
specified by URLs (--url command line option).
* maidag/maidag.c (options): New option --url.
(main): Handle --url.
* maidag/maidag.h (url_option): New global.
* maidag/mailquota.c (check_quota): Return if auth == NULL.
1 parent 9106fc88
1 2008-10-19 Sergey Poznyakoff <gray@gnu.org.ua>
2
3 * NEWS: Update.
4 * doc/texinfo/libmuauth.texi: Update.
5 * doc/texinfo/mailutils.texi: Update.
6 * doc/texinfo/programs.texi: Update.
7
8 * include/mailutils/mailbox.h (mu_mailbox_create_from_url): New
9 function.
10 * include/mailutils/mutil.h (mu_aget_user_email_domain): New
11 function.
12 * libproto/include/address0.h: Remove obsolete comment.
13 * libproto/remote/mbox.c (remote_mbox_append_message): If
14 recipient address is not given, try to construct it from the URL.
15 * mailbox/mailbox.c (mu_mailbox_create_from_url): New function.
16 * mailbox/mutil.c (mu_aget_user_email_domain): New function.
17
18 * maidag/deliver.c (deliver_to_user): Mailbox and auth must be
19 freed by the caller.
20 (deliver_url): New function.
21 (deliver): Rewrite to allow for delivering to mailboxes explicitly
22 specified by URLs (--url command line option).
23 * maidag/maidag.c (options): New option --url.
24 (main): Handle --url.
25 * maidag/maidag.h (url_option): New global.
26 * maidag/mailquota.c (check_quota): Return if auth == NULL.
27
1 2008-10-17 Sergey Poznyakoff <gray@gnu.org.ua> 28 2008-10-17 Sergey Poznyakoff <gray@gnu.org.ua>
2 29
3 * include/mailutils/libsieve.h (mu_sieve_match_part_checker): New 30 * include/mailutils/libsieve.h (mu_sieve_match_part_checker): New
......
1 GNU mailutils NEWS -- history of user-visible changes. 2008-08-20 1 GNU mailutils NEWS -- history of user-visible changes. 2008-10-16
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
3 2008 Free Software Foundation, Inc. 3 2008 Free Software Foundation, Inc.
4 See the end of file for copying conditions. 4 See the end of file for copying conditions.
...@@ -124,6 +124,8 @@ PREAUTH mode: ...@@ -124,6 +124,8 @@ PREAUTH mode:
124 124
125 * Libraries 125 * Libraries
126 126
127 ** Support for ESMTP SIZE extension (RFC 1870).
128
127 ** Diagnostic and debugging functions essentially rewritten. 129 ** Diagnostic and debugging functions essentially rewritten.
128 130
129 A set of debugging macros, MU_DEBUG0 through MU_DEBUG11, is provided. 131 A set of debugging macros, MU_DEBUG0 through MU_DEBUG11, is provided.
......
...@@ -8,9 +8,9 @@ The functions from @file{libmailbox} library get user information from ...@@ -8,9 +8,9 @@ The functions from @file{libmailbox} library get user information from
8 the system user database. The library @file{libmuauth} extends this 8 the system user database. The library @file{libmuauth} extends this
9 functionality, allowing @file{libmailbox} functions to obtain 9 functionality, allowing @file{libmailbox} functions to obtain
10 information about a user from several places, like @sc{sql} database, 10 information about a user from several places, like @sc{sql} database,
11 etc. The method used is described in detail in @ref{authentication}. 11 etc. The method used is described in detail in @ref{Auth Statement,
12 This chapter contains a very succinct description of the underlying 12 authentication}. This chapter contains a very succinct description of
13 library mechanism. 13 the underlying library mechanism.
14 14
15 @menu 15 @menu
16 * Data Types:: 16 * Data Types::
......
...@@ -112,10 +112,15 @@ Indices ...@@ -112,10 +112,15 @@ Indices
112 @detailmenu 112 @detailmenu
113 --- The Detailed Node Listing --- 113 --- The Detailed Node Listing ---
114 114
115 Introduction
116
117 * Book Contents:: What this Book Contains
118 * History:: A bit of History
119
115 Mailutils Programs 120 Mailutils Programs
116 121
122 * command line:: Command Line Syntax.
117 * configuration:: Common Configuration File. 123 * configuration:: Common Configuration File.
118 * authentication:: Authorization and Authentication Principles.
119 124
120 * frm and from:: List Headers from a Mailbox. 125 * frm and from:: List Headers from a Mailbox.
121 * mail:: Send and Receive Mail. 126 * mail:: Send and Receive Mail.
...@@ -139,6 +144,41 @@ Mailutils Programs ...@@ -139,6 +144,41 @@ Mailutils Programs
139 144
140 * mailutils-config:: Get the Information about the Mailutils Build. 145 * mailutils-config:: Get the Information about the Mailutils Build.
141 146
147 Command Line
148
149 * Option Basics:: Basic Notions About Command Line Options.
150 * Common Options:: Options That are Common for All Utilities.
151
152 Mailutils Configuration File
153
154 * conf-syntax:: Configuration File Syntax
155 * Include:: Include Statement
156 * Logging Statement::
157 * Debug Statement::
158 * Mailbox Statement::
159 * Locking Statement::
160 * ACL Statement::
161 * Tcp-wrappers Statement::
162 * Server Settings::
163 * Auth Statement::
164 * PAM Statement::
165 * Virtdomain Statement::
166 * Radius Statement::
167 * SQL Statement::
168 * LDAP Statement::
169 * TLS Statement::
170 * GSASL Statement::
171
172 Configuration File Syntax
173
174 * Comments::
175 * Statements::
176 * Block Statements::
177
178 Server Settings
179
180 * General Server Configuration::
181 * Server Statement::
142 182
143 @command{mail} --- Send and Receive Mail 183 @command{mail} --- Send and Receive Mail
144 184
......
...@@ -22,7 +22,6 @@ syntax. ...@@ -22,7 +22,6 @@ syntax.
22 @menu 22 @menu
23 * command line:: Command Line Syntax. 23 * command line:: Command Line Syntax.
24 * configuration:: Common Configuration File. 24 * configuration:: Common Configuration File.
25 * authentication:: Authorization and Authentication Principles.
26 25
27 * frm and from:: List Headers from a Mailbox. 26 * frm and from:: List Headers from a Mailbox.
28 * mail:: Send and Receive Mail. 27 * mail:: Send and Receive Mail.
...@@ -1474,7 +1473,6 @@ and is denied if any one of them denies it. ...@@ -1474,7 +1473,6 @@ and is denied if any one of them denies it.
1474 1473
1475 @node Auth Statement 1474 @node Auth Statement
1476 @subsection Auth Statement 1475 @subsection Auth Statement
1477 @UNREVISED
1478 @cindex authorization 1476 @cindex authorization
1479 @cindex authentication 1477 @cindex authentication
1480 @kwindex auth 1478 @kwindex auth
...@@ -1534,6 +1532,12 @@ e.g. if the package was compiled without @acronym{sql} support then ...@@ -1534,6 +1532,12 @@ e.g. if the package was compiled without @acronym{sql} support then
1534 the module @samp{sql} in the above example will always fail, thus 1532 the module @samp{sql} in the above example will always fail, thus
1535 passing the execution on to the next module. 1533 passing the execution on to the next module.
1536 1534
1535 The @code{auth} statement configures authentication and authorization.
1536
1537 @deffn {Configuration} authorization @var{module-list}
1538 Define a sequence of modules to use for authorization. Modules will
1539 be tried in the same order as listed in @var{module-list}.
1540
1537 The modules available for use in authorization list are: 1541 The modules available for use in authorization list are:
1538 1542
1539 @table @asis 1543 @table @asis
...@@ -1549,6 +1553,20 @@ User credentials are retrieved from a ``virtual domain'' user ...@@ -1549,6 +1553,20 @@ User credentials are retrieved from a ``virtual domain'' user
1549 database. 1553 database.
1550 @end table 1554 @end table
1551 1555
1556 Unless overridden by @code{authorization} statement,
1557 the default list of authorization modules is:
1558
1559 @smallexample
1560 (system, sql, virtdomains)
1561 @end smallexample
1562 @end deffn
1563
1564 @deffn {Configuration} authentication @var{module-list}
1565 Define a sequence of modules to use for authentication. Modules will
1566 be tried in the same order as listed in @var{module-list}.
1567
1568 The following table lists modules available for use in @var{module-list}:
1569
1552 @table @asis 1570 @table @asis
1553 @item generic 1571 @item generic
1554 The generic authentication type. User password is hashed and compared 1572 The generic authentication type. User password is hashed and compared
...@@ -1572,19 +1590,10 @@ the list of authentication modules is: ...@@ -1572,19 +1590,10 @@ the list of authentication modules is:
1572 @smallexample 1590 @smallexample
1573 (generic, system, pam, sql) 1591 (generic, system, pam, sql)
1574 @end smallexample 1592 @end smallexample
1575 1593 @end deffn
1576 @noindent
1577 Unless overridden by @code{authorization} statement,
1578 the list of authorization modules is:
1579
1580 @smallexample
1581 (system, sql, virtdomains)
1582 @end smallexample
1583
1584 1594
1585 @node PAM Statement 1595 @node PAM Statement
1586 @subsection PAM Statement 1596 @subsection PAM Statement
1587 @UNREVISED
1588 @kwindex pam 1597 @kwindex pam
1589 @subheading Syntax 1598 @subheading Syntax
1590 @smallexample 1599 @smallexample
...@@ -1594,6 +1603,18 @@ pam @{ ...@@ -1594,6 +1603,18 @@ pam @{
1594 @} 1603 @}
1595 @end smallexample 1604 @end smallexample
1596 1605
1606 @subheading Description
1607 The @code{pam} statement configures @acronym{PAM} authentication. It
1608 contains a single sub-statement:
1609
1610 @deffn {Configuration} service @var{text}
1611 Define service name to look for in @acronym{PAM} configuration. By
1612 default, the base name of the Mailutils binary is used.
1613 @end deffn
1614
1615 This statement takes effect only if @samp{pam} is listed in
1616 @code{authentication} statement (@pxref{Auth Statement}).
1617
1597 @node Virtdomain Statement 1618 @node Virtdomain Statement
1598 @subsection Virtdomain Statement 1619 @subsection Virtdomain Statement
1599 @UNREVISED 1620 @UNREVISED
...@@ -1606,6 +1627,10 @@ virtdomain @{ ...@@ -1606,6 +1627,10 @@ virtdomain @{
1606 @} 1627 @}
1607 @end smallexample 1628 @end smallexample
1608 1629
1630 @subheading Description
1631 The @code{virtdomain} statement configures virtual mail domain
1632 database. @dfn{Virtual mail domain}...@FIXME
1633
1609 @node Radius Statement 1634 @node Radius Statement
1610 @subsection Radius Statement 1635 @subsection Radius Statement
1611 @UNREVISED 1636 @UNREVISED
...@@ -1728,108 +1753,7 @@ gsasl @{ ...@@ -1728,108 +1753,7 @@ gsasl @{
1728 1753
1729 1754
1730 @c ------------------------------------------------------------------- 1755 @c -------------------------------------------------------------------
1731 @node authentication
1732 @section Authorization and Authentication Principles
1733 @UNREVISED
1734 @cindex authorization
1735 @cindex authentication
1736
1737 Some mail utilities provide access to their services only after
1738 verifying that the user is actually the person he is claiming
1739 to be. Such programs are, for example, @command{pop3d} and
1740 @command{imap4d}. The process of the verification is broken
1741 down into two stages: @dfn{authorization} and @dfn{authentication}.
1742 In @dfn{authorization} stage the program retrieves the information
1743 about a particular user. In @dfn{authentication} stage, this information
1744 is compared against the user-supplied credentials. Only if both stages
1745 succeed is the user allowed to use the service.
1746
1747 A set of @dfn{modules} is involved in performing each stage. For
1748 example, the authorization stage can retrieve the user description
1749 from various sources: system database, sql database, virtual domain
1750 table, etc. Each module is responsible for retrieving the description
1751 from a particular source of information. The modules are arranged in
1752 a @dfn{module list}. The modules from the list are invoked in turn, until
1753 either a one of them succeeds or the list is exhausted. In latter case
1754 the authorization fails. Otherwise the data returned by the succeeded
1755 module are used in authentication.
1756
1757 Similarly, authentication may be performed in several ways. The
1758 authentication modules are also grouped in a list. Each module
1759 is tried in turn until either a module succeeds, in which case the
1760 authentication succeeds, or the end of the list is reached.
1761
1762 We represent the module lists as column-separated lists of module
1763 names. For example, the authorization list
1764 1756
1765 @smallexample
1766 system:sql:virtdomains
1767 @end smallexample
1768
1769 @noindent
1770 means that first the system user database (@file{/etc/password}) is
1771 searched for a description of a user in question. If the search fails,
1772 the @acronym{sql} database is searched. Finally, if it also fails, the
1773 search is performed in the virtual domain database.
1774
1775 @emph{Note}, that some authentication and/or authorization modules may
1776 be disabled when configuring the package before compilation. The names
1777 of the disabled modules are nevertheless available for use in runtime
1778 configuration options, but they represent a ``fail-only'' functionality,
1779 e.g. if the package was compiled without @acronym{sql} support then the
1780 module @samp{sql} in the above example will always fail, thus passing
1781 the execution on to the next module.
1782
1783 The modules available for use in authorization list are:
1784
1785 @table @asis
1786 @item system
1787 User credentials are retrieved from the system user database
1788 (@file{/etc/password}).
1789 @item sql
1790 User credentials are retrieved from the @acronym{sql} database. The set
1791 of @option{--sql-} options (@FIXME-pxref{auth}) is used to configure
1792 access to the database.
1793 @item virtdomain
1794 User credentials are retrieved from a ``virtual domain'' user
1795 database.
1796 @end table
1797
1798 The modules available for use in authentication list are:
1799
1800 @table @asis
1801 @item generic
1802 The generic authentication type. User password is hashed and compared
1803 against the hash value returned in authorization stage.
1804 @item system
1805 The hashed value of the user password is retrieved from
1806 @file{/etc/shadow} file on systems that support it.
1807 @item sql
1808 The hashed value of the user password is retrieved from the @acronym{sql}
1809 database using query supplied by @option{--sql-getpass} option
1810 (@FIXME-pxref{auth}).
1811 @item pam
1812 The user is authenticated via pluggable authentication module
1813 (@acronym{pam}). The @acronym{pam} service name to be used is
1814 configured via @option{--pam-service} option (@FIXME-pxref{auth})
1815 @end table
1816
1817 Unless overridden by @option{--authentication} command line option,
1818 the list of authentication modules is:
1819
1820 @smallexample
1821 generic:system:pam:sql
1822 @end smallexample
1823
1824 @noindent
1825 Unless overridden by @option{--authorization} command line option,
1826 the list of authorization modules is:
1827
1828 @smallexample
1829 system:sql:virtdomains
1830 @end smallexample
1831
1832 @page
1833 @node frm and from 1757 @node frm and from
1834 @section @command{frm} and @command{from} --- List Headers from a Mailbox 1758 @section @command{frm} and @command{from} --- List Headers from a Mailbox
1835 1759
......
...@@ -41,6 +41,8 @@ const char *mu_mailbox_get_default_proto (void); ...@@ -41,6 +41,8 @@ const char *mu_mailbox_get_default_proto (void);
41 41
42 /* Constructor/destructor and possible types. */ 42 /* Constructor/destructor and possible types. */
43 extern int mu_mailbox_create (mu_mailbox_t *, const char *); 43 extern int mu_mailbox_create (mu_mailbox_t *, const char *);
44 extern int mu_mailbox_create_from_url (mu_mailbox_t *, mu_url_t);
45
44 extern void mu_mailbox_destroy (mu_mailbox_t *); 46 extern void mu_mailbox_destroy (mu_mailbox_t *);
45 extern int mu_mailbox_create_default (mu_mailbox_t *, const char *); 47 extern int mu_mailbox_create_default (mu_mailbox_t *, const char *);
46 48
......
...@@ -88,6 +88,9 @@ extern int mu_set_user_email_domain (const char *domain); ...@@ -88,6 +88,9 @@ extern int mu_set_user_email_domain (const char *domain);
88 /* Return the currently set user email domain, or NULL if not set. */ 88 /* Return the currently set user email domain, or NULL if not set. */
89 extern int mu_get_user_email_domain (const char** domain); 89 extern int mu_get_user_email_domain (const char** domain);
90 90
91 /* Same, but allocates memory */
92 extern int mu_aget_user_email_domain (char **pdomain);
93
91 /* 94 /*
92 * Get the default email address for user name. A NULL name is taken 95 * Get the default email address for user name. A NULL name is taken
93 * to mean the current user. 96 * to mean the current user.
......
...@@ -55,9 +55,6 @@ struct _mu_address ...@@ -55,9 +55,6 @@ struct _mu_address
55 char *route; 55 char *route;
56 /* the optional ROUTE in the ROUTE-ADDR form of MAILBOX */ 56 /* the optional ROUTE in the ROUTE-ADDR form of MAILBOX */
57 57
58 /* size_t num; this didn't appear to be used anywhere... so I commented
59 it out, is that ok? -sam */
60
61 struct _mu_address *next; 58 struct _mu_address *next;
62 }; 59 };
63 60
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
29 #include <mailutils/property.h> 29 #include <mailutils/property.h>
30 #include <mailutils/mailer.h> 30 #include <mailutils/mailer.h>
31 #include <mailutils/url.h> 31 #include <mailutils/url.h>
32 #include <mailutils/mutil.h>
32 #include <mailbox0.h> 33 #include <mailbox0.h>
33 34
34 struct remote_mbox_data 35 struct remote_mbox_data
...@@ -134,6 +135,39 @@ remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg) ...@@ -134,6 +135,39 @@ remote_mbox_append_message (mu_mailbox_t mbox, mu_message_t msg)
134 135
135 mkaddr (mbox, property, "FROM", &from); 136 mkaddr (mbox, property, "FROM", &from);
136 mkaddr (mbox, property, "TO", &to); 137 mkaddr (mbox, property, "TO", &to);
138 if (!to)
139 {
140 const char *rcpt, *host;
141 char *domain = NULL;
142
143 status = mu_url_sget_user (mbox->url, &rcpt);
144 if (status != MU_ERR_NOENT)
145 {
146 if (status)
147 {
148 MU_DEBUG1 (mbox->debug, MU_DEBUG_ERROR,
149 "failed to get recipient from the url: %s\n",
150 mu_strerror (status));
151 return status;
152 }
153
154 /* FIXME: Set before if? */
155 mu_aget_user_email_domain (&domain);
156 mu_url_sget_host (mbox->url, &host);
157 mu_set_user_email_domain (host);
158 status = mu_address_create (&to, rcpt);
159 mu_set_user_email_domain (domain);
160 free (domain);
161
162 if (status)
163 {
164 MU_DEBUG3 (mbox->debug, MU_DEBUG_ERROR,
165 "%s: %s mu_address_create failed: %s\n",
166 rcpt, "TO", mu_strerror (status));
167 return status;
168 }
169 }
170 }
137 171
138 status = mu_mailer_send_message (dat->mailer, msg, from, to); 172 status = mu_mailer_send_message (dat->mailer, msg, from, to);
139 173
......
...@@ -82,7 +82,7 @@ maidag_stdio_delivery (int argc, char **argv) ...@@ -82,7 +82,7 @@ maidag_stdio_delivery (int argc, char **argv)
82 82
83 static int biff_fd = -1; 83 static int biff_fd = -1;
84 static struct sockaddr_in biff_in; 84 static struct sockaddr_in biff_in;
85 static char *biff_user_name; 85 static const char *biff_user_name;
86 86
87 static int 87 static int
88 notify_action (mu_observer_t obs, size_t type, void *data, void *action_data) 88 notify_action (mu_observer_t obs, size_t type, void *data, void *action_data)
...@@ -161,7 +161,6 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg, ...@@ -161,7 +161,6 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg,
161 { 161 {
162 maidag_error (_("Cannot open mailbox %s: %s"), 162 maidag_error (_("Cannot open mailbox %s: %s"),
163 path, mu_strerror (status)); 163 path, mu_strerror (status));
164 mu_mailbox_destroy (&mbox);
165 return EX_TEMPFAIL; 164 return EX_TEMPFAIL;
166 } 165 }
167 166
...@@ -179,7 +178,6 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg, ...@@ -179,7 +178,6 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg,
179 { 178 {
180 maidag_error (_("Cannot lock mailbox `%s': %s"), path, 179 maidag_error (_("Cannot lock mailbox `%s': %s"), path,
181 mu_strerror (status)); 180 mu_strerror (status));
182 mu_mailbox_destroy (&mbox);
183 exit_code = EX_TEMPFAIL; 181 exit_code = EX_TEMPFAIL;
184 return EX_TEMPFAIL; 182 return EX_TEMPFAIL;
185 } 183 }
...@@ -198,10 +196,7 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg, ...@@ -198,10 +196,7 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg,
198 if (status == ENOSYS) 196 if (status == ENOSYS)
199 mbsize = 0; /* Try to continue anyway */ 197 mbsize = 0; /* Try to continue anyway */
200 else 198 else
201 { 199 return EX_TEMPFAIL;
202 mu_mailbox_destroy (&mbox);
203 return EX_TEMPFAIL;
204 }
205 } 200 }
206 201
207 switch (check_quota (auth, mbsize, &n)) 202 switch (check_quota (auth, mbsize, &n))
...@@ -266,40 +261,51 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg, ...@@ -266,40 +261,51 @@ deliver_to_user (mu_mailbox_t imbx, mu_mailbox_t mbox, mu_message_t msg,
266 switch_user_id (auth, 0); 261 switch_user_id (auth, 0);
267 } 262 }
268 263
269 mu_auth_data_free (auth);
270 mu_mailbox_close (mbox); 264 mu_mailbox_close (mbox);
271 mu_locker_unlock (lock); 265 mu_locker_unlock (lock);
272 mu_mailbox_destroy (&mbox);
273 return failed ? exit_code : 0; 266 return failed ? exit_code : 0;
274 } 267 }
275 268
269 static int
270 is_remote_url (mu_url_t url)
271 {
272 const char *scheme;
273 int rc = mu_url_sget_scheme (url, &scheme);
274 return rc == 0 && strncasecmp (scheme, "remote+", 7) == 0;
275 }
276
276 int 277 int
277 deliver (mu_mailbox_t imbx, char *name, char **errp) 278 deliver_url (mu_url_t url, mu_mailbox_t imbx, const char *name, char **errp)
278 { 279 {
279 struct mu_auth_data *auth; 280 struct mu_auth_data *auth = NULL;
280 mu_mailbox_t mbox; 281 mu_mailbox_t mbox;
281 mu_message_t msg; 282 mu_message_t msg;
282 int status; 283 int status;
283 284
284 auth = mu_get_auth_by_name (name); 285 if (is_remote_url (url))
285 if (!auth) 286 auth = NULL;
287 else
286 { 288 {
287 maidag_error (_("%s: no such user"), name); 289 auth = mu_get_auth_by_name (name);
288 if (errp) 290 if (!auth)
289 asprintf (errp, "%s: no such user", name); 291 {
290 exit_code = EX_UNAVAILABLE; 292 maidag_error (_("%s: no such user"), name);
291 return EX_UNAVAILABLE; 293 if (errp)
292 } 294 asprintf (errp, "%s: no such user", name);
293 if (current_uid) 295 exit_code = EX_UNAVAILABLE;
294 auth->change_uid = 0; 296 return EX_UNAVAILABLE;
297 }
298 if (current_uid)
299 auth->change_uid = 0;
295 300
296 if (!sieve_test (auth, imbx)) 301 if (!sieve_test (auth, imbx))
297 { 302 {
298 exit_code = EX_OK; 303 exit_code = EX_OK;
299 mu_auth_data_free (auth); 304 mu_auth_data_free (auth);
300 return 0; 305 return 0;
306 }
301 } 307 }
302 308
303 if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0) 309 if ((status = mu_mailbox_get_message (imbx, 1, &msg)) != 0)
304 { 310 {
305 maidag_error (_("Cannot get message from the temporary mailbox: %s"), 311 maidag_error (_("Cannot get message from the temporary mailbox: %s"),
...@@ -308,10 +314,16 @@ deliver (mu_mailbox_t imbx, char *name, char **errp) ...@@ -308,10 +314,16 @@ deliver (mu_mailbox_t imbx, char *name, char **errp)
308 return EX_TEMPFAIL; 314 return EX_TEMPFAIL;
309 } 315 }
310 316
311 if ((status = mu_mailbox_create (&mbox, auth->mailbox)) != 0) 317 if (url)
318 status = mu_mailbox_create_from_url (&mbox, url);
319 else
320 status = mu_mailbox_create (&mbox, auth->mailbox);
321
322 if (status)
312 { 323 {
313 maidag_error (_("Cannot open mailbox %s: %s"), 324 maidag_error (_("Cannot open mailbox %s: %s"),
314 auth->mailbox, mu_strerror (status)); 325 url ? mu_url_to_string (url): auth->mailbox,
326 mu_strerror (status));
315 mu_auth_data_free (auth); 327 mu_auth_data_free (auth);
316 return EX_TEMPFAIL; 328 return EX_TEMPFAIL;
317 } 329 }
...@@ -326,5 +338,53 @@ deliver (mu_mailbox_t imbx, char *name, char **errp) ...@@ -326,5 +338,53 @@ deliver (mu_mailbox_t imbx, char *name, char **errp)
326 status = deliver_to_user (imbx, mbox, msg, auth, name, errp); 338 status = deliver_to_user (imbx, mbox, msg, auth, name, errp);
327 if (switch_user_id (auth, 0)) 339 if (switch_user_id (auth, 0))
328 return EX_TEMPFAIL; 340 return EX_TEMPFAIL;
341
342 mu_auth_data_free (auth);
343 mu_mailbox_destroy (&mbox);
344
329 return status; 345 return status;
330 } 346 }
347
348 int
349 deliver (mu_mailbox_t imbx, char *dest_id, char **errp)
350 {
351 int status;
352 const char *name;
353 mu_url_t url = NULL;
354
355 if (url_option)
356 {
357 status = mu_url_create (&url, dest_id);
358 if (status)
359 {
360 maidag_error (_("%s: cannot create url: %s"), dest_id,
361 mu_strerror (status));
362 return EX_NOUSER;
363 }
364 status = mu_url_parse (url);
365 if (status)
366 {
367 maidag_error (_("%s: cannot parse url: %s"), dest_id,
368 mu_strerror (status));
369 mu_url_destroy (&url);
370 return EX_NOUSER;
371 }
372 status = mu_url_sget_user (url, &name);
373 if (status == MU_ERR_NOENT)
374 name = NULL;
375 else if (status)
376 {
377 maidag_error (_("%s: cannot get user name from url: %s"),
378 dest_id, mu_strerror (status));
379 mu_url_destroy (&url);
380 return EX_NOUSER;
381 }
382 }
383 else
384 {
385 name = dest_id;
386 dest_id = NULL;
387 }
388 return deliver_url (url, imbx, name, errp);
389 }
390
......
...@@ -45,6 +45,7 @@ char *message_id_header; /* Use the value of this header as message ...@@ -45,6 +45,7 @@ char *message_id_header; /* Use the value of this header as message
45 /* For LMTP mode */ 45 /* For LMTP mode */
46 mu_m_server_t server; 46 mu_m_server_t server;
47 int lmtp_mode; 47 int lmtp_mode;
48 int url_option;
48 char *lmtp_url_string; 49 char *lmtp_url_string;
49 int reuse_lmtp_address = 1; 50 int reuse_lmtp_address = 1;
50 char *lmtp_group = "mail"; 51 char *lmtp_group = "mail";
...@@ -66,6 +67,7 @@ static char args_doc[] = N_("[recipient...]"); ...@@ -66,6 +67,7 @@ static char args_doc[] = N_("[recipient...]");
66 #define MESSAGE_ID_HEADER_OPTION 257 67 #define MESSAGE_ID_HEADER_OPTION 257
67 #define LMTP_OPTION 258 68 #define LMTP_OPTION 258
68 #define FOREGROUND_OPTION 260 69 #define FOREGROUND_OPTION 260
70 #define URL_OPTION 261
69 71
70 static struct argp_option options[] = 72 static struct argp_option options[] =
71 { 73 {
...@@ -73,7 +75,7 @@ static struct argp_option options[] = ...@@ -73,7 +75,7 @@ static struct argp_option options[] =
73 { "inetd", 'i', 0, 0, N_("Run in inetd mode"), 0 }, 75 { "inetd", 'i', 0, 0, N_("Run in inetd mode"), 0 },
74 { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, 76 { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL,
75 N_("Runs in daemon mode with a maximum of NUMBER children"), 0 }, 77 N_("Runs in daemon mode with a maximum of NUMBER children"), 0 },
76 78 { "url", URL_OPTION, 0, 0, N_("Deliver to given URLs"), 0 },
77 { "from", 'f', N_("EMAIL"), 0, 79 { "from", 'f', N_("EMAIL"), 0,
78 N_("Specify the sender's name") }, 80 N_("Specify the sender's name") },
79 { NULL, 'r', NULL, OPTION_ALIAS, NULL }, 81 { NULL, 'r', NULL, OPTION_ALIAS, NULL },
...@@ -221,6 +223,10 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -221,6 +223,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
221 case STDERR_OPTION: 223 case STDERR_OPTION:
222 mu_argp_node_list_new (&lst, "stderr", "yes"); 224 mu_argp_node_list_new (&lst, "stderr", "yes");
223 break; 225 break;
226
227 case URL_OPTION:
228 url_option = 1;
229 break;
224 230
225 case ARGP_KEY_INIT: 231 case ARGP_KEY_INIT:
226 mu_argp_node_list_init (&lst); 232 mu_argp_node_list_init (&lst);
...@@ -492,7 +498,7 @@ main (int argc, char *argv[]) ...@@ -492,7 +498,7 @@ main (int argc, char *argv[])
492 current_uid = getuid (); 498 current_uid = getuid ();
493 499
494 if (log_to_stderr == -1) 500 if (log_to_stderr == -1)
495 log_to_stderr = !lmtp_mode && (current_uid != 0); 501 log_to_stderr = url_option || (!lmtp_mode && (current_uid != 0));
496 502
497 if (!log_to_stderr) 503 if (!log_to_stderr)
498 { 504 {
...@@ -508,7 +514,7 @@ main (int argc, char *argv[]) ...@@ -508,7 +514,7 @@ main (int argc, char *argv[])
508 argc -= arg_index; 514 argc -= arg_index;
509 argv += arg_index; 515 argv += arg_index;
510 516
511 if (lmtp_mode) 517 if (lmtp_mode && !url_option)
512 { 518 {
513 if (argc) 519 if (argc)
514 { 520 {
...@@ -521,24 +527,30 @@ main (int argc, char *argv[]) ...@@ -521,24 +527,30 @@ main (int argc, char *argv[])
521 { 527 {
522 if (current_uid) 528 if (current_uid)
523 { 529 {
524 static char *s_argv[2]; 530 if (url_option)
525 struct mu_auth_data *auth = mu_get_auth_by_uid (current_uid);
526
527 if (!current_uid)
528 { 531 {
529 mu_error (_("Cannot get username")); 532 /* FIXME: Verify if the urls are deliverable? */
530 return EX_UNAVAILABLE;
531 } 533 }
532 534 else
533 if (argc > 1 || (argc > 0 && strcmp (auth->name, argv[0])))
534 { 535 {
535 mu_error (_("Recipients given when running as non-root")); 536 static char *s_argv[2];
536 return EX_USAGE; 537 struct mu_auth_data *auth = mu_get_auth_by_uid (current_uid);
538
539 if (!current_uid)
540 {
541 mu_error (_("Cannot get username"));
542 return EX_UNAVAILABLE;
543 }
544
545 if (argc > 0 && strcmp (auth->name, argv[0]))
546 {
547 mu_error (_("Recipients given when running as non-root"));
548 return EX_USAGE;
549 }
550 s_argv[0] = auth->name;
551 argv = s_argv;
552 argc = 1;
537 } 553 }
538
539 s_argv[0] = auth->name;
540 argv = s_argv;
541 argc = 1;
542 } 554 }
543 return maidag_stdio_delivery (argc, argv); 555 return maidag_stdio_delivery (argc, argv);
544 } 556 }
......
...@@ -123,6 +123,7 @@ extern char *sieve_pattern; ...@@ -123,6 +123,7 @@ extern char *sieve_pattern;
123 123
124 extern mu_m_server_t server; 124 extern mu_m_server_t server;
125 extern int lmtp_mode; 125 extern int lmtp_mode;
126 extern int url_option;
126 extern char *lmtp_url_string; 127 extern char *lmtp_url_string;
127 extern int reuse_lmtp_address; 128 extern int reuse_lmtp_address;
128 extern char *lmtp_group; 129 extern char *lmtp_group;
......
...@@ -274,6 +274,9 @@ int ...@@ -274,6 +274,9 @@ int
274 check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest) 274 check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest)
275 { 275 {
276 mu_off_t quota; 276 mu_off_t quota;
277
278 if (!auth)
279 return MQUOTA_OK;
277 280
278 switch (retrieve_quota (auth, &quota)) 281 switch (retrieve_quota (auth, &quota))
279 { 282 {
...@@ -292,7 +295,6 @@ check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest) ...@@ -292,7 +295,6 @@ check_quota (struct mu_auth_data *auth, mu_off_t size, mu_off_t *rest)
292 } 295 }
293 296
294 return MQUOTA_OK; 297 return MQUOTA_OK;
295
296 } 298 }
297 299
298 #endif /* USE_MAIL_QUOTA */ 300 #endif /* USE_MAIL_QUOTA */
......
...@@ -247,6 +247,14 @@ mu_mailbox_create (mu_mailbox_t *pmbox, const char *name) ...@@ -247,6 +247,14 @@ mu_mailbox_create (mu_mailbox_t *pmbox, const char *name)
247 return rc; 247 return rc;
248 } 248 }
249 249
250 int
251 mu_mailbox_create_from_url (mu_mailbox_t *pmbox, mu_url_t url)
252 {
253 if (pmbox == NULL)
254 return MU_ERR_OUT_PTR_NULL;
255 return _create_mailbox0 (pmbox, url, mu_url_to_string (url));
256 }
257
250 void 258 void
251 mu_mailbox_destroy (mu_mailbox_t *pmbox) 259 mu_mailbox_destroy (mu_mailbox_t *pmbox)
252 { 260 {
......
...@@ -411,6 +411,7 @@ mu_set_user_email_domain (const char *domain) ...@@ -411,6 +411,7 @@ mu_set_user_email_domain (const char *domain)
411 return 0; 411 return 0;
412 } 412 }
413 413
414 /* FIXME: must be called _sget_ */
414 int 415 int
415 mu_get_user_email_domain (const char **domain) 416 mu_get_user_email_domain (const char **domain)
416 { 417 {
...@@ -427,6 +428,24 @@ mu_get_user_email_domain (const char **domain) ...@@ -427,6 +428,24 @@ mu_get_user_email_domain (const char **domain)
427 return 0; 428 return 0;
428 } 429 }
429 430
431 int
432 mu_aget_user_email_domain (char **pdomain)
433 {
434 const char *domain;
435 int status = mu_get_user_email_domain (&domain);
436 if (status)
437 return status;
438 if (domain == NULL)
439 *pdomain = domain;
440 else
441 {
442 *pdomain = strdup (domain);
443 if (*pdomain == NULL)
444 return ENOMEM;
445 }
446 return 0;
447 }
448
430 /* Note: allocates memory */ 449 /* Note: allocates memory */
431 char * 450 char *
432 mu_get_user_email (const char *name) 451 mu_get_user_email (const char *name)
......