On Tue, 12 Jul 2005, Heiko Schlichting wrote:
> Adam Stephens wrote:
>> Here's a patch for exim's LMTP transport, implementing the IGNOREQUOTA
>> extension to LMTP*. Set 'ignore_quota = yes' in the transport options to
>> deliver even to overquota mailboxes.
>
> Quoting http://www.oceana.com/ftp/drafts/draft-murchison-lmtp-ignorequota-02.txt:
>
> | If the LMTP server responds with code 250 to the LHLO command, and the response
> | includes the LHLO keyword IGNOREQUOTA, then the server supports the Ignore
> | Quota extension and will accept the extended ver sion of the RCPT command.
>
> Your patch does not check the response to LHLO or do I miss something? It
> uses "IGNOREQUOTA" even if the server does not accounce this feature. This
> might work in some cases but is not conform to the draft and could be
> harmful if the server does not understand IGNOREQUOTA and drops the input.
Well, whilst I wouldn't agree that it violates the draft (that quote
only specifies server behaviour) it really should check the response.
This new version checks the LHLO response if ignore_quota is set. It
will defer the delivery if IGNOREQUOTA isn't supported - it's not really
a temporary failure, as it's a configuration error, but bouncing mail
simply because the admin hasn't read the instructions is embarassing...
cheers,
Adam.
--------------------------------
Adam Stephens
Network Specialist - Email & DNS
adam.stephens@???diff -ur src/transports.old/lmtp.c src/transports/lmtp.c
--- src/transports.old/lmtp.c 2005-07-11 16:33:29.000000000 +0100
+++ src/transports/lmtp.c 2005-07-15 17:00:06.833413648 +0100
@@ -28,6 +28,8 @@
(void *)offsetof(transport_instance, batch_max) },
{ "command", opt_stringptr,
(void *)offsetof(lmtp_transport_options_block, cmd) },
+ { "ignore_quota", opt_bool,
+ (void *)offsetof(lmtp_transport_options_block, ignore_quota) },
{ "socket", opt_stringptr,
(void *)offsetof(lmtp_transport_options_block, skt) },
{ "timeout", opt_time,
@@ -44,6 +46,7 @@
lmtp_transport_options_block lmtp_transport_option_defaults = {
NULL, /* cmd */
+ FALSE, /* ignore_quota */
NULL, /* skt */
5*60, /* timeout */
0 /* options */
@@ -455,6 +458,7 @@
int fd_in = -1, fd_out = -1;
int code, save_errno;
BOOL send_data;
+BOOL ignore_quota = ob->ignore_quota;
BOOL yield = FALSE;
address_item *addr;
uschar *sockname = NULL;
@@ -561,6 +565,18 @@
if (!lmtp_read_response(out, buffer, sizeof(buffer), '2',
timeout)) goto RESPONSE_FAILED;
+/*check for IGNOREQUOTA, is ignore_quota is true*/
+if (ignore_quota && !Ustrstr(buffer, "IGNOREQUOTA"))
+ {
+ (void) lmtp_write_command(fd_in, "QUIT\r\n");
+ (void) lmtp_read_response(out, buffer, sizeof(buffer), '2', 1);
+ addrlist->transport_return = DEFER;
+ addrlist->basic_errno = ERRNO_UNKNOWNERROR;
+ addrlist->message = string_sprintf("LMTP error: ignore_quota set in transport, but not advertised by server");
+ goto KILL_AND_RETURN;
+ }
+
+
/* Now the envelope sender */
if (!lmtp_write_command(fd_in, "MAIL FROM:<%s>\r\n", return_path))
@@ -575,8 +591,10 @@
send_data = FALSE;
for (addr = addrlist; addr != NULL; addr = addr->next)
{
- if (!lmtp_write_command(fd_in, "RCPT TO:<%s>\r\n",
- transport_rcpt_address(addr, tblock->rcpt_include_affixes)))
+ if ( ignore_quota == TRUE ) Ustrcpy(buffer, " IGNOREQUOTA");
+ else Ustrcpy(buffer, "");
+ if (!lmtp_write_command(fd_in, "RCPT TO:<%s>%s\r\n",
+ transport_rcpt_address(addr, tblock->rcpt_include_affixes), buffer ))
goto WRITE_FAILED;
if (lmtp_read_response(out, buffer, sizeof(buffer), '2', timeout))
{
diff -ur src/transports.old/lmtp.h src/transports/lmtp.h
--- src/transports.old/lmtp.h 2005-07-11 16:33:30.000000000 +0100
+++ src/transports/lmtp.h 2005-07-15 16:33:46.820612104 +0100
@@ -11,6 +11,7 @@
typedef struct {
uschar *cmd;
+ BOOL ignore_quota;
uschar *skt;
int timeout;
int options;