~ubuntu-branches/ubuntu/dapper/postfix/dapper-security

« back to all changes in this revision

Viewing changes to src/lmtp/lmtp.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2005-02-27 09:33:07 UTC
  • Revision ID: james.westby@ubuntu.com-20050227093307-cn789t27ibnlh6tf
Tags: upstream-2.1.5
ImportĀ upstreamĀ versionĀ 2.1.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*++
 
2
/* NAME
 
3
/*      lmtp 8
 
4
/* SUMMARY
 
5
/*      Postfix local delivery via LMTP
 
6
/* SYNOPSIS
 
7
/*      \fBlmtp\fR [generic Postfix daemon options]
 
8
/* DESCRIPTION
 
9
/*      The LMTP client processes message delivery requests from
 
10
/*      the queue manager. Each request specifies a queue file, a sender
 
11
/*      address, a domain or host to deliver to, and recipient information.
 
12
/*      This program expects to be run from the \fBmaster\fR(8) process
 
13
/*      manager.
 
14
/*
 
15
/*      The LMTP client updates the queue file and marks recipients
 
16
/*      as finished, or it informs the queue manager that delivery should
 
17
/*      be tried again at a later time. Delivery status reports are sent
 
18
/*      to the \fBbounce\fR(8), \fBdefer\fR(8) or \fBtrace\fR(8) daemon as
 
19
/*      appropriate.
 
20
/*
 
21
/*      The LMTP client connects to the destination specified in the message
 
22
/*      delivery request. The destination, usually specified in the Postfix
 
23
/*      \fBtransport\fR(5) table, has the form:
 
24
/* .IP \fBunix\fR:\fIpathname\fR
 
25
/*      Connect to the local UNIX-domain server that is bound to the specified
 
26
/*      \fIpathname\fR. If the process runs chrooted, an absolute pathname
 
27
/*      is interpreted relative to the changed root directory.
 
28
/* .IP "\fBinet\fR:\fIhost\fR, \fBinet\fB:\fIhost\fR:\fIport\fR (symbolic host)"
 
29
/* .IP "\fBinet\fR:[\fIaddr\fR], \fBinet\fR:[\fIaddr\fR]:\fIport\fR (numeric host)"
 
30
/*      Connect to the specified IPV4 TCP port on the specified local or
 
31
/*      remote host. If no port is specified, connect to the port defined as
 
32
/*      \fBlmtp\fR in \fBservices\fR(4).
 
33
/*      If no such service is found, the \fBlmtp_tcp_port\fR configuration
 
34
/*      parameter (default value of 24) will be used.
 
35
/*
 
36
/*      The LMTP client does not perform MX (mail exchanger) lookups since
 
37
/*      those are defined only for mail delivery via SMTP.
 
38
/* .PP
 
39
/*      If neither \fBunix:\fR nor \fBinet:\fR are specified, \fBinet:\fR
 
40
/*      is assumed.
 
41
/* SECURITY
 
42
/* .ad
 
43
/* .fi
 
44
/*      The LMTP client is moderately security-sensitive. It talks to LMTP
 
45
/*      servers and to DNS servers on the network. The LMTP client can be
 
46
/*      run chrooted at fixed low privilege.
 
47
/* STANDARDS
 
48
/*      RFC 821 (SMTP protocol)
 
49
/*      RFC 1651 (SMTP service extensions)
 
50
/*      RFC 1652 (8bit-MIME transport)
 
51
/*      RFC 1870 (Message Size Declaration)
 
52
/*      RFC 2033 (LMTP protocol)
 
53
/*      RFC 2554 (AUTH command)
 
54
/*      RFC 2821 (SMTP protocol)
 
55
/*      RFC 2920 (SMTP Pipelining)
 
56
/* DIAGNOSTICS
 
57
/*      Problems and transactions are logged to \fBsyslogd\fR(8).
 
58
/*      Corrupted message files are marked so that the queue manager can
 
59
/*      move them to the \fBcorrupt\fR queue for further inspection.
 
60
/*
 
61
/*      Depending on the setting of the \fBnotify_classes\fR parameter,
 
62
/*      the postmaster is notified of bounces, protocol problems, and of
 
63
/*      other trouble.
 
64
/* CONFIGURATION PARAMETERS
 
65
/* .ad
 
66
/* .fi
 
67
/*      Changes to \fBmain.cf\fR are picked up automatically, as lmtp(8)
 
68
/*      processes run for only a limited amount of time. Use the command
 
69
/*      "\fBpostfix reload\fR" to speed up a change.
 
70
/*
 
71
/*      The text below provides only a parameter summary. See
 
72
/*      postconf(5) for more details including examples.
 
73
/* COMPATIBILITY CONTROLS
 
74
/* .ad
 
75
/* .fi
 
76
/* .IP "\fBlmtp_skip_quit_response (no)\fR"
 
77
/*      Wait for the response to the LMTP QUIT command.
 
78
/* TROUBLE SHOOTING CONTROLS
 
79
/* .ad
 
80
/* .fi
 
81
/* .IP "\fBdebug_peer_level (2)\fR"
 
82
/*      The increment in verbose logging level when a remote client or
 
83
/*      server matches a pattern in the debug_peer_list parameter.
 
84
/* .IP "\fBdebug_peer_list (empty)\fR"
 
85
/*      Optional list of remote client or server hostname or network
 
86
/*      address patterns that cause the verbose logging level to increase
 
87
/*      by the amount specified in $debug_peer_level.
 
88
/* .IP "\fBerror_notice_recipient (postmaster)\fR"
 
89
/*      The recipient of postmaster notifications about mail delivery
 
90
/*      problems that are caused by policy, resource, software or protocol
 
91
/*      errors.
 
92
/* .IP "\fBnotify_classes (resource, software)\fR"
 
93
/*      The list of error classes that are reported to the postmaster.
 
94
/* EXTERNAL CONTENT INSPECTION CONTROLS
 
95
/* .ad
 
96
/* .fi
 
97
/*      Available in Postfix version 2.1 and later:
 
98
/* .IP "\fBlmtp_send_xforward_command (no)\fR"
 
99
/*      Send an XFORWARD command to the LMTP server when the LMTP LHLO
 
100
/*      server response announces XFORWARD support.
 
101
/* SASL AUTHENTICATION CONTROLS
 
102
/* .ad
 
103
/* .fi
 
104
/* .IP "\fBlmtp_sasl_auth_enable (no)\fR"
 
105
/*      Enable SASL authentication in the Postfix LMTP client.
 
106
/* .IP "\fBlmtp_sasl_password_maps (empty)\fR"
 
107
/*      Optional LMTP client lookup tables with one username:password entry
 
108
/*      per host or domain.
 
109
/* .IP "\fBlmtp_sasl_security_options (noplaintext, noanonymous)\fR"
 
110
/*      What authentication mechanisms the Postfix LMTP client is allowed
 
111
/*      to use.
 
112
/* RESOURCE AND RATE CONTROLS
 
113
/* .ad
 
114
/* .fi
 
115
/*      In the text below, \fItransport\fR is the name
 
116
/*      of the service as specified in the \fBmaster.cf\fR file.
 
117
/* .IP "\fBlmtp_cache_connection (yes)\fR"
 
118
/*      Keep Postfix LMTP client connections open for up to $max_idle
 
119
/*      seconds.
 
120
/* .IP "\fItransport_\fBdestination_concurrency_limit ($default_destination_concurrency_limit)\fR"
 
121
/*      Limit the number of parallel deliveries to the same destination
 
122
/*      via this mail delivery transport.
 
123
/* .IP "\fItransport_\fBdestination_recipient_limit ($default_destination_recipient_limit)\fR"
 
124
/*      Limit the number of recipients per message delivery via this mail
 
125
/*      delivery transport.
 
126
/*
 
127
/*      This parameter becomes significant if the LMTP client is used
 
128
/*      for local delivery.  Some LMTP servers can optimize delivery of
 
129
/*      the same message to multiple recipients. The default limit for
 
130
/*      local mail delivery is 1.
 
131
/*
 
132
/*      Setting this parameter to 0 will lead to an unbounded number of
 
133
/*      recipients per delivery.  However, this could be risky since it may
 
134
/*      make the machine vulnerable to running out of resources if messages
 
135
/*      are encountered with an inordinate number of recipients.  Exercise
 
136
/*      care when setting this parameter.
 
137
/* .IP "\fBlmtp_connect_timeout (0s)\fR"
 
138
/*      The LMTP client time limit for completing a TCP connection, or
 
139
/*      zero (use the operating system built-in time limit).
 
140
/* .IP "\fBlmtp_lhlo_timeout (300s)\fR"
 
141
/*      The LMTP client time limit for receiving the LMTP greeting
 
142
/*      banner.
 
143
/* .IP "\fBlmtp_xforward_timeout (300s)\fR"
 
144
/*      The LMTP client time limit for sending the XFORWARD command, and
 
145
/*      for receiving the server response.
 
146
/* .IP "\fBlmtp_mail_timeout (300s)\fR"
 
147
/*      The LMTP client time limit for sending the MAIL FROM command, and
 
148
/*      for receiving the server response.
 
149
/* .IP "\fBlmtp_rcpt_timeout (300s)\fR"
 
150
/*      The LMTP client time limit for sending the RCPT TO command, and
 
151
/*      for receiving the server response.
 
152
/* .IP "\fBlmtp_data_init_timeout (120s)\fR"
 
153
/*      The LMTP client time limit for sending the LMTP DATA command, and
 
154
/*      for receiving the server response.
 
155
/* .IP "\fBlmtp_data_xfer_timeout (180s)\fR"
 
156
/*      The LMTP client time limit for sending the LMTP message content.
 
157
/* .IP "\fBlmtp_data_done_timeout (600s)\fR"
 
158
/*      The LMTP client time limit for sending the LMTP ".", and for
 
159
/*      receiving the server response.
 
160
/* .IP "\fBlmtp_rset_timeout (120s)\fR"
 
161
/*      The LMTP client time limit for sending the RSET command, and for
 
162
/*      receiving the server response.
 
163
/* .IP "\fBlmtp_quit_timeout (300s)\fR"
 
164
/*      The LMTP client time limit for sending the QUIT command, and for
 
165
/*      receiving the server response.
 
166
/* MISCELLANEOUS CONTROLS
 
167
/* .ad
 
168
/* .fi
 
169
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
 
170
/*      The default location of the Postfix main.cf and master.cf
 
171
/*      configuration files.
 
172
/* .IP "\fBdaemon_timeout (18000s)\fR"
 
173
/*      How much time a Postfix daemon process may take to handle a
 
174
/*      request before it is terminated by a built-in watchdog timer.
 
175
/* .IP "\fBdisable_dns_lookups (no)\fR"
 
176
/*      Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
177
/* .IP "\fBipc_timeout (3600s)\fR"
 
178
/*      The time limit for sending or receiving information over an internal
 
179
/*      communication channel.
 
180
/* .IP "\fBlmtp_tcp_port (24)\fR"
 
181
/*      The default TCP port that the Postfix LMTP client connects to.
 
182
/* .IP "\fBmax_idle (100s)\fR"
 
183
/*      The maximum amount of time that an idle Postfix daemon process
 
184
/*      waits for the next service request before exiting.
 
185
/* .IP "\fBmax_use (100)\fR"
 
186
/*      The maximal number of connection requests before a Postfix daemon
 
187
/*      process terminates.
 
188
/* .IP "\fBprocess_id (read-only)\fR"
 
189
/*      The process ID of a Postfix command or daemon process.
 
190
/* .IP "\fBprocess_name (read-only)\fR"
 
191
/*      The process name of a Postfix command or daemon process.
 
192
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
 
193
/*      The location of the Postfix top-level queue directory.
 
194
/* .IP "\fBsyslog_facility (mail)\fR"
 
195
/*      The syslog facility of Postfix logging.
 
196
/* .IP "\fBsyslog_name (postfix)\fR"
 
197
/*      The mail system name that is prepended to the process name in syslog
 
198
/*      records, so that "smtpd" becomes, for example, "postfix/smtpd".
 
199
/* SEE ALSO
 
200
/*      bounce(8), delivery status reports
 
201
/*      qmgr(8), queue manager
 
202
/*      postconf(5), configuration parameters
 
203
/*      services(4), Internet services and aliases
 
204
/*      master(8), process manager
 
205
/*      syslogd(8), system logging
 
206
/* README FILES
 
207
/* .ad
 
208
/* .fi
 
209
/*      Use "\fBpostconf readme_directory\fR" or
 
210
/*      "\fBpostconf html_directory\fR" to locate this information.
 
211
/* .na
 
212
/* .nf
 
213
/*      LMTP_README, Postfix LMTP client howto
 
214
/*      VIRTUAL_README, virtual delivery agent howto
 
215
/* LICENSE
 
216
/* .ad
 
217
/* .fi
 
218
/*      The Secure Mailer license must be distributed with this software.
 
219
/* AUTHOR(S)
 
220
/*      Wietse Venema
 
221
/*      IBM T.J. Watson Research
 
222
/*      P.O. Box 704
 
223
/*      Yorktown Heights, NY 10598, USA
 
224
/*
 
225
/*      Alterations for LMTP by:
 
226
/*      Philip A. Prindeville
 
227
/*      Mirapoint, Inc.
 
228
/*      USA.
 
229
/*
 
230
/*      Additional work on LMTP by:
 
231
/*      Amos Gouaux
 
232
/*      University of Texas at Dallas
 
233
/*      P.O. Box 830688, MC34
 
234
/*      Richardson, TX 75083, USA
 
235
/*--*/
 
236
 
 
237
/* System library. */
 
238
 
 
239
#include <sys_defs.h>
 
240
#include <unistd.h>
 
241
#include <stdlib.h>
 
242
#include <string.h>
 
243
#include <fcntl.h>
 
244
#include <dict.h>
 
245
 
 
246
/* Utility library. */
 
247
 
 
248
#include <msg.h>
 
249
#include <argv.h>
 
250
#include <mymalloc.h>
 
251
#include <name_mask.h>
 
252
#include <split_at.h>
 
253
 
 
254
/* Global library. */
 
255
 
 
256
#include <deliver_request.h>
 
257
#include <mail_queue.h>
 
258
#include <mail_params.h>
 
259
#include <mail_conf.h>
 
260
#include <debug_peer.h>
 
261
#include <mail_error.h>
 
262
#include <flush_clnt.h>
 
263
 
 
264
/* Single server skeleton. */
 
265
 
 
266
#include <mail_server.h>
 
267
 
 
268
/* Application-specific. */
 
269
 
 
270
#include "lmtp.h"
 
271
#include "lmtp_sasl.h"
 
272
 
 
273
 /*
 
274
  * Tunable parameters. These have compiled-in defaults that can be overruled
 
275
  * by settings in the global Postfix configuration file.
 
276
  */
 
277
int     var_lmtp_tcp_port;
 
278
int     var_lmtp_conn_tmout;
 
279
int     var_lmtp_rset_tmout;
 
280
int     var_lmtp_lhlo_tmout;
 
281
int     var_lmtp_xfwd_tmout;
 
282
int     var_lmtp_mail_tmout;
 
283
int     var_lmtp_rcpt_tmout;
 
284
int     var_lmtp_data0_tmout;
 
285
int     var_lmtp_data1_tmout;
 
286
int     var_lmtp_data2_tmout;
 
287
int     var_lmtp_quit_tmout;
 
288
int     var_lmtp_cache_conn;
 
289
int     var_lmtp_skip_quit_resp;
 
290
char   *var_notify_classes;
 
291
char   *var_error_rcpt;
 
292
char   *var_lmtp_sasl_opts;
 
293
char   *var_lmtp_sasl_passwd;
 
294
bool    var_lmtp_sasl_enable;
 
295
bool    var_lmtp_send_xforward;
 
296
 
 
297
 /*
 
298
  * Global variables.
 
299
  * 
 
300
  * lmtp_errno is set by the address lookup routines and by the connection
 
301
  * management routines.
 
302
  * 
 
303
  * state is global for the connection caching to work.
 
304
  */
 
305
int     lmtp_errno;
 
306
static LMTP_STATE *state = 0;
 
307
 
 
308
/* deliver_message - deliver message with extreme prejudice */
 
309
 
 
310
static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
 
311
{
 
312
    char   *myname = "deliver_message";
 
313
    VSTRING *why;
 
314
    int     result;
 
315
 
 
316
    if (msg_verbose)
 
317
        msg_info("%s: from %s", myname, request->sender);
 
318
 
 
319
    /*
 
320
     * Sanity checks.
 
321
     */
 
322
    if (request->rcpt_list.len <= 0)
 
323
        msg_fatal("%s: recipient count: %d", myname, request->rcpt_list.len);
 
324
 
 
325
    /*
 
326
     * Initialize. Bundle all information about the delivery request, so that
 
327
     * we can produce understandable diagnostics when something goes wrong
 
328
     * many levels below. The alternative would be to make everything global.
 
329
     * 
 
330
     * Note: `state' was made global (to this file) so that we can cache
 
331
     * connections and so that we can close a cached connection via the
 
332
     * MAIL_SERVER_EXIT function (cleanup). The alloc for `state' is
 
333
     * performed in the MAIL_SERVER_PRE_INIT function (pre_init).
 
334
     * 
 
335
     */
 
336
    why = vstring_alloc(100);
 
337
    state->request = request;
 
338
    state->src = request->fp;
 
339
 
 
340
    /*
 
341
     * See if we can reuse an existing connection.
 
342
     */
 
343
    if (state->session != 0) {
 
344
 
 
345
        /*
 
346
         * Disconnect if we're going to a different destination. Discard
 
347
         * transcript and status information for sending QUIT.
 
348
         * 
 
349
         * XXX Should transform nexthop into canonical form (unix:/path or
 
350
         * inet:host:port) before doing connection cache lookup. See also the
 
351
         * connection cache updating code in lmtp_connect.c.
 
352
         */
 
353
        if (strcasecmp(state->session->dest, request->nexthop) != 0) {
 
354
            lmtp_quit(state);
 
355
            lmtp_chat_reset(state);
 
356
            state->session = lmtp_session_free(state->session);
 
357
#ifdef USE_SASL_AUTH
 
358
            if (var_lmtp_sasl_enable)
 
359
                lmtp_sasl_cleanup(state);
 
360
#endif
 
361
        }
 
362
 
 
363
        /*
 
364
         * Disconnect if RSET can't be sent over an existing connection.
 
365
         * Discard transcript and status information for sending RSET.
 
366
         */
 
367
        else if (lmtp_rset(state) != 0) {
 
368
            lmtp_chat_reset(state);
 
369
            state->session = lmtp_session_free(state->session);
 
370
#ifdef USE_SASL_AUTH
 
371
            if (var_lmtp_sasl_enable)
 
372
                lmtp_sasl_cleanup(state);
 
373
#endif
 
374
        }
 
375
 
 
376
        /*
 
377
         * Ready to go with another load. The reuse counter is logged for
 
378
         * statistical analysis purposes. Given the Postfix architecture,
 
379
         * connection cacheing makes sense only for dedicated transports.
 
380
         * Logging the reuse count can help to convince people.
 
381
         */
 
382
        else {
 
383
            ++state->reuse;
 
384
            if (msg_verbose)
 
385
                msg_info("%s: reusing (count %d) session with: %s",
 
386
                         myname, state->reuse, state->session->host);
 
387
        }
 
388
    }
 
389
 
 
390
    /*
 
391
     * See if we need to establish an LMTP connection.
 
392
     */
 
393
    if (state->session == 0) {
 
394
 
 
395
        /*
 
396
         * Bounce or defer the recipients if no connection can be made.
 
397
         */
 
398
        if ((state->session = lmtp_connect(request->nexthop, why)) == 0) {
 
399
            lmtp_site_fail(state, lmtp_errno == LMTP_RETRY ? 450 : 550,
 
400
                           "%s", vstring_str(why));
 
401
        }
 
402
 
 
403
        /*
 
404
         * Bounce or defer the recipients if the LMTP handshake fails.
 
405
         */
 
406
        else if (lmtp_lhlo(state) != 0) {
 
407
            state->session = lmtp_session_free(state->session);
 
408
#ifdef USE_SASL_AUTH
 
409
            if (var_lmtp_sasl_enable)
 
410
                lmtp_sasl_cleanup(state);
 
411
#endif
 
412
        }
 
413
 
 
414
        /*
 
415
         * Congratulations. We just established a new LMTP connection.
 
416
         */
 
417
        else
 
418
            state->reuse = 0;
 
419
    }
 
420
 
 
421
    /*
 
422
     * If a session exists, deliver this message to all requested recipients.
 
423
     */
 
424
    if (state->session != 0)
 
425
        lmtp_xfer(state);
 
426
 
 
427
    /*
 
428
     * Optionally, notify the postmaster of problems with establishing a
 
429
     * session or with delivering mail.
 
430
     */
 
431
    if (state->history != 0
 
432
     && (state->error_mask & name_mask(VAR_NOTIFY_CLASSES, mail_error_masks,
 
433
                                       var_notify_classes)))
 
434
        lmtp_chat_notify(state);
 
435
 
 
436
    /*
 
437
     * Disconnect if we're not caching connections. The pipelined protocol
 
438
     * state machine knows if it should have sent a QUIT command. Do not
 
439
     * cache a broken connection.
 
440
     */
 
441
    if (state->session != 0
 
442
        && (!var_lmtp_cache_conn
 
443
            || vstream_ferror(state->session->stream)
 
444
            || vstream_feof(state->session->stream)))
 
445
        state->session = lmtp_session_free(state->session);
 
446
 
 
447
    /*
 
448
     * Clean up.
 
449
     */
 
450
    vstring_free(why);
 
451
    result = state->status;
 
452
    lmtp_chat_reset(state);
 
453
 
 
454
    /*
 
455
     * XXX State persists until idle timeout, but these fields will be
 
456
     * dangling pointers. Nuke them.
 
457
     */
 
458
    state->request = 0;
 
459
    state->src = 0;
 
460
 
 
461
    return (result);
 
462
}
 
463
 
 
464
/* lmtp_service - perform service for client */
 
465
 
 
466
static void lmtp_service(VSTREAM *client_stream, char *unused_service, char **argv)
 
467
{
 
468
    DELIVER_REQUEST *request;
 
469
    int     status;
 
470
 
 
471
    /*
 
472
     * Sanity check. This service takes no command-line arguments.
 
473
     */
 
474
    if (argv[0])
 
475
        msg_fatal("unexpected command-line argument: %s", argv[0]);
 
476
 
 
477
    /*
 
478
     * This routine runs whenever a client connects to the UNIX-domain socket
 
479
     * dedicated to remote LMTP delivery service. What we see below is a
 
480
     * little protocol to (1) tell the queue manager that we are ready, (2)
 
481
     * read a request from the queue manager, and (3) report the completion
 
482
     * status of that request. All connection-management stuff is handled by
 
483
     * the common code in single_server.c.
 
484
     */
 
485
    if ((request = deliver_request_read(client_stream)) != 0) {
 
486
        status = deliver_message(request, argv);
 
487
        deliver_request_done(client_stream, request, status);
 
488
    }
 
489
}
 
490
 
 
491
/* post_init - post-jail initialization */
 
492
 
 
493
static void post_init(char *unused_name, char **unused_argv)
 
494
{
 
495
    state = lmtp_state_alloc();
 
496
}
 
497
 
 
498
/* pre_init - pre-jail initialization */
 
499
 
 
500
static void pre_init(char *unused_name, char **unused_argv)
 
501
{
 
502
    debug_peer_init();
 
503
    if (var_lmtp_sasl_enable)
 
504
#ifdef USE_SASL_AUTH
 
505
        lmtp_sasl_initialize();
 
506
#else
 
507
        msg_warn("%s is true, but SASL support is not compiled in",
 
508
                 VAR_LMTP_SASL_ENABLE);
 
509
#endif
 
510
 
 
511
    /*
 
512
     * flush client.
 
513
     */
 
514
    flush_init();
 
515
}
 
516
 
 
517
/* cleanup - close any open connections, etc. */
 
518
 
 
519
static void cleanup(void)
 
520
{
 
521
    if (state->session != 0) {
 
522
        lmtp_quit(state);
 
523
        lmtp_chat_reset(state);
 
524
        state->session = lmtp_session_free(state->session);
 
525
        if (msg_verbose)
 
526
            msg_info("cleanup: just closed down session");
 
527
    }
 
528
    lmtp_state_free(state);
 
529
#ifdef USE_SASL_AUTH
 
530
    if (var_lmtp_sasl_enable)
 
531
        sasl_done();
 
532
#endif
 
533
}
 
534
 
 
535
/* pre_accept - see if tables have changed */
 
536
 
 
537
static void pre_accept(char *unused_name, char **unused_argv)
 
538
{
 
539
    const char *table;
 
540
 
 
541
    if ((table = dict_changed_name()) != 0) {
 
542
        msg_info("table %s has changed -- restarting", table);
 
543
        cleanup();
 
544
        exit(0);
 
545
    }
 
546
}
 
547
 
 
548
/* main - pass control to the single-threaded skeleton */
 
549
 
 
550
int     main(int argc, char **argv)
 
551
{
 
552
    static CONFIG_STR_TABLE str_table[] = {
 
553
        VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
 
554
        VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
 
555
        VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_lmtp_sasl_passwd, 0, 0,
 
556
        VAR_LMTP_SASL_OPTS, DEF_LMTP_SASL_OPTS, &var_lmtp_sasl_opts, 0, 0,
 
557
        0,
 
558
    };
 
559
    static CONFIG_INT_TABLE int_table[] = {
 
560
        VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0,
 
561
        0,
 
562
    };
 
563
    static CONFIG_TIME_TABLE time_table[] = {
 
564
        VAR_LMTP_CONN_TMOUT, DEF_LMTP_CONN_TMOUT, &var_lmtp_conn_tmout, 0, 0,
 
565
        VAR_LMTP_RSET_TMOUT, DEF_LMTP_RSET_TMOUT, &var_lmtp_rset_tmout, 1, 0,
 
566
        VAR_LMTP_LHLO_TMOUT, DEF_LMTP_LHLO_TMOUT, &var_lmtp_lhlo_tmout, 1, 0,
 
567
        VAR_LMTP_XFWD_TMOUT, DEF_LMTP_XFWD_TMOUT, &var_lmtp_xfwd_tmout, 1, 0,
 
568
        VAR_LMTP_MAIL_TMOUT, DEF_LMTP_MAIL_TMOUT, &var_lmtp_mail_tmout, 1, 0,
 
569
        VAR_LMTP_RCPT_TMOUT, DEF_LMTP_RCPT_TMOUT, &var_lmtp_rcpt_tmout, 1, 0,
 
570
        VAR_LMTP_DATA0_TMOUT, DEF_LMTP_DATA0_TMOUT, &var_lmtp_data0_tmout, 1, 0,
 
571
        VAR_LMTP_DATA1_TMOUT, DEF_LMTP_DATA1_TMOUT, &var_lmtp_data1_tmout, 1, 0,
 
572
        VAR_LMTP_DATA2_TMOUT, DEF_LMTP_DATA2_TMOUT, &var_lmtp_data2_tmout, 1, 0,
 
573
        VAR_LMTP_QUIT_TMOUT, DEF_LMTP_QUIT_TMOUT, &var_lmtp_quit_tmout, 1, 0,
 
574
        0,
 
575
    };
 
576
    static CONFIG_BOOL_TABLE bool_table[] = {
 
577
        VAR_LMTP_CACHE_CONN, DEF_LMTP_CACHE_CONN, &var_lmtp_cache_conn,
 
578
        VAR_LMTP_SKIP_QUIT_RESP, DEF_LMTP_SKIP_QUIT_RESP, &var_lmtp_skip_quit_resp,
 
579
        VAR_LMTP_SASL_ENABLE, DEF_LMTP_SASL_ENABLE, &var_lmtp_sasl_enable,
 
580
        VAR_LMTP_SEND_XFORWARD, DEF_LMTP_SEND_XFORWARD, &var_lmtp_send_xforward,
 
581
        0,
 
582
    };
 
583
 
 
584
    single_server_main(argc, argv, lmtp_service,
 
585
                       MAIL_SERVER_INT_TABLE, int_table,
 
586
                       MAIL_SERVER_STR_TABLE, str_table,
 
587
                       MAIL_SERVER_BOOL_TABLE, bool_table,
 
588
                       MAIL_SERVER_TIME_TABLE, time_table,
 
589
                       MAIL_SERVER_PRE_INIT, pre_init,
 
590
                       MAIL_SERVER_POST_INIT, post_init,
 
591
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
 
592
                       MAIL_SERVER_EXIT, cleanup,
 
593
                       0);
 
594
}