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.
Showing
15 changed files
with
299 additions
and
168 deletions
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, "a)) | 281 | switch (retrieve_quota (auth, "a)) |
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) | ... | ... |
-
Please register or sign in to post a comment