diff options
author | gshapiro <gshapiro@FreeBSD.org> | 2002-02-17 21:56:45 +0000 |
---|---|---|
committer | gshapiro <gshapiro@FreeBSD.org> | 2002-02-17 21:56:45 +0000 |
commit | 8449595fe97f4474b9b9a7e4edee1ef35dcff393 (patch) | |
tree | e7a33b132264d449a512ddf4a8685df097669c1d /contrib/sendmail/src/sendmail.h | |
parent | 289b381b31415647269c7520d881017e2dcb27f1 (diff) | |
download | FreeBSD-src-8449595fe97f4474b9b9a7e4edee1ef35dcff393.zip FreeBSD-src-8449595fe97f4474b9b9a7e4edee1ef35dcff393.tar.gz |
Import sendmail 8.12.2
Diffstat (limited to 'contrib/sendmail/src/sendmail.h')
-rw-r--r-- | contrib/sendmail/src/sendmail.h | 1415 |
1 files changed, 878 insertions, 537 deletions
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h index 611116c..86a3c48 100644 --- a/contrib/sendmail/src/sendmail.h +++ b/contrib/sendmail/src/sendmail.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -15,13 +15,10 @@ */ #ifndef _SENDMAIL_H -#define _SENDMAIL_H 1 +# define _SENDMAIL_H 1 #ifdef _DEFINE # define EXTERN -# ifndef lint -static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.70 2001/08/14 23:08:12 ca Exp $"; -# endif /* ! lint */ #else /* _DEFINE */ # define EXTERN extern #endif /* _DEFINE */ @@ -29,18 +26,9 @@ static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.70 2001/08/14 23:08:12 ca #include <unistd.h> -#if SFIO -# include <sfio/stdio.h> -# if defined(SFIO_VERSION) && SFIO_VERSION > 20000000L - ERROR README: SFIO 2000 does not work with sendmail, use SFIO 1999 instead. -# endif /* defined(SFIO_VERSION) && SFIO_VERSION > 20000000L */ -#endif /* SFIO */ - #include <stddef.h> #include <stdlib.h> -#if !SFIO -# include <stdio.h> -#endif /* !SFIO */ +#include <stdio.h> #include <ctype.h> #include <setjmp.h> #include <string.h> @@ -48,11 +36,36 @@ static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.70 2001/08/14 23:08:12 ca # ifdef EX_OK # undef EX_OK /* for SVr4.2 SMP */ # endif /* EX_OK */ -#include <sysexits.h> #include "sendmail/sendmail.h" + +/* profiling? */ +#if MONCONTROL +# define SM_PROF(x) moncontrol(x) +#else /* MONCONTROL */ +# define SM_PROF(x) +#endif /* MONCONTROL */ + +#ifdef _DEFINE +# ifndef lint +SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.902 2002/01/09 00:10:11 ca Exp $"; +# endif /* ! lint */ +#endif /* _DEFINE */ + #include "bf.h" #include "timers.h" +#include <sm/exc.h> +#include <sm/heap.h> +#include <sm/debug.h> +#include <sm/rpool.h> +#include <sm/io.h> +#include <sm/path.h> +#include <sm/signal.h> +#include <sm/clock.h> +#include <sm/mbdb.h> +#include <sm/errstring.h> +#include <sm/sysexits.h> +#include <sm/shm.h> #ifdef LOG # include <syslog.h> @@ -91,9 +104,12 @@ static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.70 2001/08/14 23:08:12 ca # undef NOERROR /* avoid <sys/streams.h> conflict */ # endif /* NOERROR */ # include <resolv.h> +# else /* NAMED_BIND */ +# undef SM_SET_H_ERRNO +# define SM_SET_H_ERRNO(err) # endif /* NAMED_BIND */ -# ifdef HESIOD +# if HESIOD # include <hesiod.h> # if !defined(HES_ER_OK) || defined(HESIOD_INTERFACES) # define HESIOD_INIT /* support for the new interface */ @@ -101,13 +117,10 @@ static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.70 2001/08/14 23:08:12 ca # endif /* HESIOD */ #if STARTTLS -# if !SFIO && !_FFR_TLS_TOREK - ERROR README: STARTTLS requires SFIO -# endif /* !SFIO && !_FFR_TLS_TOREK */ -# if SFIO && _FFR_TLS_TOREK - ERROR README: Can not do both SFIO and _FFR_TLS_TOREK -# endif /* SFIO && _FFR_TLS_TOREK */ # include <openssl/ssl.h> +# if !TLS_NO_RSA +# define RSA_KEYLENGTH 512 +# endif /* !TLS_NO_RSA */ #endif /* STARTTLS */ #if SASL /* include the sasl include files if we have them */ @@ -165,11 +178,28 @@ static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.70 2001/08/14 23:08:12 ca #endif /* ! INADDR_NONE */ +/* +** An 'argument class' describes the storage allocation status +** of an object pointed to by an argument to a function. +*/ + +typedef enum +{ + A_HEAP, /* the storage was allocated by malloc, and the + * ownership of the storage is ceded by the caller + * to the called function. */ + A_TEMP, /* The storage is temporary, and is only guaranteed + * to be valid for the duration of the function call. */ + A_PERM /* The storage is 'permanent': this might mean static + * storage, or rpool storage. */ +} ARGCLASS_T; + /* forward references for prototypes */ typedef struct envelope ENVELOPE; typedef struct mailer MAILER; +typedef struct queuegrp QUEUEGRP; -/* +/* ** Address structure. ** Addresses are stored internally in this structure. */ @@ -181,7 +211,7 @@ struct address char *q_ruser; /* real user name, or NULL if q_user */ char *q_host; /* host name */ struct mailer *q_mailer; /* mailer to use */ - u_long q_flags; /* status flags, see below */ + unsigned long q_flags; /* status flags, see below */ uid_t q_uid; /* user-id of receiver (if known) */ gid_t q_gid; /* group-id of receiver (if known) */ char *q_home; /* home dir (local mailer only) */ @@ -190,13 +220,20 @@ struct address struct address *q_alias; /* address this results from */ char *q_owner; /* owner of q_alias */ struct address *q_tchain; /* temporary use chain */ +#if PIPELINING + struct address *q_pchain; /* chain for pipelining */ +#endif /* PIPELINING */ + char *q_finalrcpt; /* Final-Recipient: DSN header */ char *q_orcpt; /* ORCPT parameter from RCPT TO: line */ char *q_status; /* status code for DSNs */ char *q_rstatus; /* remote status message for DSNs */ time_t q_statdate; /* date of status messages */ char *q_statmta; /* MTA generating q_rstatus */ short q_state; /* address state, see below */ - short q_specificity; /* how "specific" this address is */ + char *q_signature; /* MX-based sorting value */ + int q_qgrp; /* index into queue groups */ + int q_qdir; /* queue directory inside group */ + char *q_message; /* error message */ }; typedef struct address ADDRESS; @@ -211,12 +248,15 @@ typedef struct address ADDRESS; #define QPINGONSUCCESS 0x00000040 /* give return on successful delivery */ #define QPINGONFAILURE 0x00000080 /* give return on failure */ #define QPINGONDELAY 0x00000100 /* give return on message delay */ -#define QHASNOTIFY 0x00000200 /* propogate notify parameter */ +#define QHASNOTIFY 0x00000200 /* propagate notify parameter */ #define QRELAYED 0x00000400 /* DSN: relayed to non-DSN aware sys */ #define QEXPANDED 0x00000800 /* DSN: undergone list expansion */ #define QDELIVERED 0x00001000 /* DSN: successful final delivery */ #define QDELAYED 0x00002000 /* DSN: message delayed */ #define QALIAS 0x00004000 /* expanded alias */ +#define QBYTRACE 0x00008000 /* DeliverBy: trace */ +#define QBYNDELAY 0x00010000 /* DeliverBy: notify, delay */ +#define QBYNRELAY 0x00020000 /* DeliverBy: notify, relayed */ #define QTHISPASS 0x40000000 /* temp: address set this pass */ #define QRCPTOK 0x80000000 /* recipient() processed address */ @@ -227,41 +267,47 @@ typedef struct address ADDRESS; #define QS_SENT 1 /* good address, delivery complete */ #define QS_BADADDR 2 /* illegal address */ #define QS_QUEUEUP 3 /* save address in queue */ -#define QS_VERIFIED 4 /* verified, but not expanded */ -#define QS_DONTSEND 5 /* don't send to this address */ -#define QS_EXPANDED 6 /* QS_DONTSEND: expanded */ -#define QS_SENDER 7 /* QS_DONTSEND: message sender (MeToo) */ -#define QS_CLONED 8 /* QS_DONTSEND: addr cloned to split envelope */ -#define QS_DISCARDED 9 /* QS_DONTSEND: rcpt discarded (EF_DISCARD) */ -#define QS_REPLACED 10 /* QS_DONTSEND: maplocaluser()/UserDB replaced */ -#define QS_REMOVED 11 /* QS_DONTSEND: removed (removefromlist()) */ -#define QS_DUPLICATE 12 /* QS_DONTSEND: duplicate suppressed */ -#define QS_INCLUDED 13 /* QS_DONTSEND: :include: delivery */ +#define QS_RETRY 4 /* retry delivery for next MX */ +#define QS_VERIFIED 5 /* verified, but not expanded */ + +/* +** Notice: all of the following values are variations of QS_DONTSEND. +** If new states are added, they must be inserted in the proper place! +** See the macro definition of QS_IS_DEAD() down below. +*/ + +#define QS_DONTSEND 6 /* don't send to this address */ +#define QS_EXPANDED 7 /* expanded */ +#define QS_SENDER 8 /* message sender (MeToo) */ +#define QS_CLONED 9 /* addr cloned to split envelope */ +#define QS_DISCARDED 10 /* rcpt discarded (EF_DISCARD) */ +#define QS_REPLACED 11 /* maplocaluser()/UserDB replaced */ +#define QS_REMOVED 12 /* removed (removefromlist()) */ +#define QS_DUPLICATE 13 /* duplicate suppressed */ +#define QS_INCLUDED 14 /* :include: delivery */ /* address state testing primitives */ #define QS_IS_OK(s) ((s) == QS_OK) #define QS_IS_SENT(s) ((s) == QS_SENT) #define QS_IS_BADADDR(s) ((s) == QS_BADADDR) #define QS_IS_QUEUEUP(s) ((s) == QS_QUEUEUP) +#define QS_IS_RETRY(s) ((s) == QS_RETRY) #define QS_IS_VERIFIED(s) ((s) == QS_VERIFIED) #define QS_IS_EXPANDED(s) ((s) == QS_EXPANDED) #define QS_IS_REMOVED(s) ((s) == QS_REMOVED) #define QS_IS_UNDELIVERED(s) ((s) == QS_OK || \ (s) == QS_QUEUEUP || \ + (s) == QS_RETRY || \ (s) == QS_VERIFIED) +#define QS_IS_UNMARKED(s) ((s) == QS_OK || \ + (s) == QS_RETRY) #define QS_IS_SENDABLE(s) ((s) == QS_OK || \ - (s) == QS_QUEUEUP) + (s) == QS_QUEUEUP || \ + (s) == QS_RETRY) #define QS_IS_ATTEMPTED(s) ((s) == QS_QUEUEUP || \ + (s) == QS_RETRY || \ (s) == QS_SENT) -#define QS_IS_DEAD(s) ((s) == QS_DONTSEND || \ - (s) == QS_CLONED || \ - (s) == QS_SENDER || \ - (s) == QS_DISCARDED || \ - (s) == QS_REPLACED || \ - (s) == QS_REMOVED || \ - (s) == QS_DUPLICATE || \ - (s) == QS_INCLUDED || \ - (s) == QS_EXPANDED) +#define QS_IS_DEAD(s) ((s) >= QS_DONTSEND) #define NULLADDR ((ADDRESS *) NULL) @@ -274,19 +320,25 @@ extern char *crackaddr __P((char *)); extern bool emptyaddr __P((ADDRESS *)); extern ADDRESS *getctladdr __P((ADDRESS *)); extern int include __P((char *, bool, ADDRESS *, ADDRESS **, int, ENVELOPE *)); -extern bool invalidaddr __P((char *, char *)); -extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *)); -extern char **prescan __P((char *, int, char[], int, char **, u_char *)); +extern bool invalidaddr __P((char *, char *, bool)); +extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, + ENVELOPE *, bool)); +extern char **prescan __P((char *, int, char[], int, char **, unsigned char *)); extern void printaddr __P((ADDRESS *, bool)); extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, int, ENVELOPE *)); extern char *remotename __P((char *, MAILER *, int, int *, ENVELOPE *)); -extern int rewrite __P((char **, int, int, ENVELOPE *)); +extern int rewrite __P((char **, int, int, ENVELOPE *, int)); extern bool sameaddr __P((ADDRESS *, ADDRESS *)); extern int sendtolist __P((char *, ADDRESS *, ADDRESS **, int, ENVELOPE *)); +#if MILTER extern int removefromlist __P((char *, ADDRESS **, ENVELOPE *)); +#endif /* MILTER */ extern void setsender __P((char *, ENVELOPE *, char **, int, bool)); -/* +/* macro to simplify the common call to rewrite() */ +#define REWRITE(pvp, rs, env) rewrite(pvp, rs, 0, env, MAXATOM) + +/* ** Mailer definition structure. ** Every mailer known to the system is declared in this ** structure. It defines the pathname of the mailer, some @@ -323,13 +375,12 @@ struct mailer gid_t m_gid; /* GID to run as */ char *m_defcharset; /* default character set */ time_t m_wait; /* timeout to wait for end */ -#if _FFR_DYNAMIC_TOBUF int m_maxrcpt; /* max recipients per envelope client-side */ -#endif /* _FFR_DYNAMIC_TOBUF */ + short m_qgrp; /* queue group for this mailer */ }; /* bits for m_flags */ -#define M_ESMTP 'a' /* run Extended SMTP protocol */ +#define M_ESMTP 'a' /* run Extended SMTP */ #define M_ALIASABLE 'A' /* user can be LHS of an alias */ #define M_BLANKEND 'b' /* ensure blank line at end of message */ #define M_NOCOMMENT 'c' /* don't include comment part of address */ @@ -370,8 +421,10 @@ struct mailer /* 'x' CF: include Full-Name: */ #define M_XDOT 'X' /* use hidden-dot algorithm */ #define M_LMTP 'z' /* run Local Mail Transport Protocol */ +#define M_DIALDELAY 'Z' /* apply dial delay sleeptime */ #define M_NOMX '0' /* turn off MX lookups */ #define M_NONULLS '1' /* don't send null bytes */ +#define M_FSMTP '2' /* force SMTP (no ESMTP even if offered) */ #define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */ #define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */ #define M_7BITHDRS '6' /* strip headers to 7 bits even in 8 bit path */ @@ -390,8 +443,162 @@ struct mailer /* functions */ extern void initerrmailers __P((void)); extern void makemailer __P((char *)); +extern void makequeue __P((char *, bool)); +extern void runqueueevent __P((int)); + +EXTERN MAILER *FileMailer; /* ptr to *file* mailer */ +EXTERN MAILER *InclMailer; /* ptr to *include* mailer */ +EXTERN MAILER *LocalMailer; /* ptr to local mailer */ +EXTERN MAILER *ProgMailer; /* ptr to program mailer */ +EXTERN MAILER *Mailer[MAXMAILERS + 1]; + +/* +** Queue group definition structure. +** Every queue group known to the system is declared in this structure. +** It defines the basic pathname of the queue group, some flags +** associated with it, and the argument vector to pass to it. +*/ + +struct qpaths_s +{ + char *qp_name; /* name of queue dir, relative path */ + short qp_subdirs; /* use subdirs? */ + short qp_fsysidx; /* file system index of this directory */ +# if SM_CONF_SHM + int qp_idx; /* index into array for queue information */ +# endif /* SM_CONF_SHM */ +}; + +typedef struct qpaths_s QPATHS; + +struct queuegrp +{ + char *qg_name; /* symbolic name of this queue group */ + + /* + ** For now this is the same across all queue groups. + ** Otherwise we have to play around with chdir(). + */ + + char *qg_qdir; /* common component of queue directory */ + short qg_index; /* queue number internally, index in Queue[] */ + int qg_maxqrun; /* max # of jobs in 1 queuerun */ + int qg_numqueues; /* number of queues in this queue */ + + /* + ** qg_queueintvl == 0 denotes that no individual value is used. + ** Whatever accesses this must deal with "<= 0" as + ** "not set, use appropriate default". + */ + + time_t qg_queueintvl; /* interval for queue runs */ + QPATHS *qg_qpaths; /* list of queue directories */ + BITMAP256 qg_flags; /* status flags, see below */ + short qg_nice; /* niceness for queue run */ + int qg_wgrp; /* Assigned to this work group */ + int qg_maxlist; /* max items in work queue for this group */ + int qg_curnum; /* current number of queue for queue runs */ + int qg_maxrcpt; /* max recipients per envelope, 0==no limit */ + +#if 0 + short qg_sortorder; /* how do we sort this queuerun */ + long qg_wkrcptfact; /* multiplier for # recipients -> priority */ + long qg_qfactor; /* slope of queue function */ + bool qg_doqueuerun; /* XXX flag is it time to do a queuerun */ +#endif /* 0 */ +}; + +/* bits for qg_flags (XXX: unused as of now) */ +#define QD_DEFINED ((char) 1) /* queue group has been defined */ +#define QD_FORK 'f' /* fork queue runs */ + +extern void filesys_update __P((void)); +#if _FFR_ANY_FREE_FS +extern bool filesys_free __P((long)); +#endif /* _FFR_ANY_FREE_FS */ + +#if SASL +/* +** SASL +*/ + +/* lines in authinfo file or index into SASL_AI_T */ +# define SASL_WRONG (-1) +# define SASL_USER 0 /* authorization id (user) */ +# define SASL_AUTHID 1 /* authentication id */ +# define SASL_PASSWORD 2 /* password fuer authid */ +# define SASL_DEFREALM 3 /* realm to use */ +# define SASL_MECHLIST 4 /* list of mechanisms to try */ +# define SASL_ID_REALM 5 /* authid@defrealm */ + +/* +** Current mechanism; this is just used to convey information between +** invocation of SASL callback functions. +** It must be last in the list, because it's not allocated by us +** and hence we don't free() it. +*/ +# define SASL_MECH 6 +# define SASL_ENTRIES 7 /* number of entries in array */ + +# define SASL_USER_BIT (1 << SASL_USER) +# define SASL_AUTHID_BIT (1 << SASL_AUTHID) +# define SASL_PASSWORD_BIT (1 << SASL_PASSWORD) +# define SASL_DEFREALM_BIT (1 << SASL_DEFREALM) +# define SASL_MECHLIST_BIT (1 << SASL_MECHLIST) + +/* authenticated? */ +# define SASL_NOT_AUTH 0 /* not authenticated */ +# define SASL_PROC_AUTH 1 /* in process of authenticating */ +# define SASL_IS_AUTH 2 /* authenticated */ + +/* SASL options */ +# define SASL_AUTH_AUTH 0x1000 /* use auth= only if authenticated */ +# define SASL_SEC_MASK 0x0fff /* mask for SASL_SEC_* values: sasl.h */ +# if (SASL_SEC_NOPLAINTEXT & SASL_SEC_MASK) == 0 || \ + (SASL_SEC_NOACTIVE & SASL_SEC_MASK) == 0 || \ + (SASL_SEC_NODICTIONARY & SASL_SEC_MASK) == 0 || \ + (SASL_SEC_FORWARD_SECRECY & SASL_SEC_MASK) == 0 || \ + (SASL_SEC_NOANONYMOUS & SASL_SEC_MASK) == 0 || \ + (SASL_SEC_PASS_CREDENTIALS & SASL_SEC_MASK) == 0 +ERROR: change SASL_SEC_MASK_ notify sendmail.org! +# endif /* SASL_SEC_NOPLAINTEXT & SASL_SEC_MASK) == 0 ... */ +# define MAXOUTLEN 1024 /* length of output buffer */ + +/* functions */ +extern char *intersect __P((char *, char *, SM_RPOOL_T *)); +extern char *iteminlist __P((char *, char *, char *)); +extern int proxy_policy __P((void *, const char *, const char *, const char **, const char **)); +# if SASL > 10515 +extern int safesaslfile __P((void *, char *, int)); +# else /* SASL > 10515 */ +extern int safesaslfile __P((void *, char *)); +# endif /* SASL > 10515 */ +extern int sasl_decode64 __P((const char *, unsigned, char *, unsigned *)); +extern int sasl_encode64 __P((const char *, unsigned, char *, unsigned, unsigned *)); +extern void stop_sasl_client __P((void)); + +/* structure to store authinfo */ +typedef char *SASL_AI_T[SASL_ENTRIES]; + +EXTERN char *AuthMechanisms; /* AUTH mechanisms */ +EXTERN char *SASLInfo; /* file with AUTH info */ +EXTERN int SASLOpts; /* options for SASL */ +EXTERN int MaxSLBits; /* max. encryption bits for SASL */ +#endif /* SASL */ -/* +/* +** Structure to store macros. +*/ +typedef struct +{ + SM_RPOOL_T *mac_rpool; /* resource pool */ + BITMAP256 mac_allocated; /* storage has been alloc()? */ + char *mac_table[MAXMACROID + 1]; /* macros */ +} MACROS_T; + +EXTERN MACROS_T GlobalMacros; + +/* ** Information about currently open connections to mailers, or to ** hosts that we have looked up recently. */ @@ -400,20 +607,15 @@ extern void makemailer __P((char *)); MCI { - u_long mci_flags; /* flag bits, see below */ + unsigned long mci_flags; /* flag bits, see below */ short mci_errno; /* error number on last connection */ short mci_herrno; /* h_errno from last DNS lookup */ short mci_exitstat; /* exit status from last connection */ short mci_state; /* SMTP state */ int mci_deliveries; /* delivery attempts for connection */ long mci_maxsize; /* max size this server will accept */ -#if SFIO - Sfio_t *mci_in; /* input side of connection */ - Sfio_t *mci_out; /* output side of connection */ -#else /* SFIO */ - FILE *mci_in; /* input side of connection */ - FILE *mci_out; /* output side of connection */ -#endif /* SFIO */ + SM_FILE_T *mci_in; /* input side of connection */ + SM_FILE_T *mci_out; /* output side of connection */ pid_t mci_pid; /* process id of subordinate proc */ char *mci_phase; /* SMTP phase string */ struct mailer *mci_mailer; /* ptr to the mailer for this conn */ @@ -421,9 +623,18 @@ MCI char *mci_status; /* DSN status to be copied to addrs */ char *mci_rstatus; /* SMTP status to be copied to addrs */ time_t mci_lastuse; /* last usage time */ - FILE *mci_statfile; /* long term status file */ + SM_FILE_T *mci_statfile; /* long term status file */ char *mci_heloname; /* name to use as HELO arg */ + long mci_min_by; /* minimum DELIVERBY */ + bool mci_retryrcpt; /* tempfail for at least one rcpt */ + char *mci_tolist; /* list of valid recipients */ + SM_RPOOL_T *mci_rpool; /* resource pool */ +#if PIPELINING + int mci_okrcpts; /* number of valid recipients */ + ADDRESS *mci_nextaddr; /* next address for pipelined status */ +#endif /* PIPELINING */ #if SASL + SASL_AI_T mci_sai; /* authentication info */ bool mci_sasl_auth; /* authenticated? */ int mci_sasl_string_len; char *mci_sasl_string; /* sasl reply string */ @@ -433,12 +644,13 @@ MCI #if STARTTLS SSL *mci_ssl; /* SSL connection */ #endif /* STARTTLS */ + MACROS_T mci_macro; /* macro definitions */ }; /* flag bits */ #define MCIF_VALID 0x00000001 /* this entry is valid */ -#define MCIF_TEMP 0x00000002 /* don't cache this connection */ +/* 0x00000002 unused, was MCIF_TEMP */ #define MCIF_CACHED 0x00000004 /* currently in open cache */ #define MCIF_ESMTP 0x00000008 /* this host speaks ESMTP */ #define MCIF_EXPN 0x00000010 /* EXPN command supported */ @@ -455,6 +667,7 @@ MCI #define MCIF_AUTH 0x00008000 /* AUTH= supported */ #define MCIF_AUTHACT 0x00010000 /* SASL (AUTH) active */ #define MCIF_ENHSTAT 0x00020000 /* ENHANCEDSTATUSCODES supported */ +#define MCIF_PIPELINED 0x00040000 /* PIPELINING supported */ #if STARTTLS #define MCIF_TLS 0x00100000 /* STARTTLS supported */ #define MCIF_TLSACT 0x00200000 /* STARTTLS active */ @@ -462,17 +675,22 @@ MCI #else /* STARTTLS */ #define MCIF_EXTENS (MCIF_EXPN | MCIF_SIZE | MCIF_8BITMIME | MCIF_DSN | MCIF_8BITOK | MCIF_AUTH | MCIF_ENHSTAT) #endif /* STARTTLS */ +#define MCIF_DLVR_BY 0x00400000 /* DELIVERBY */ +#if _FFR_IGNORE_EXT_ON_HELO +# define MCIF_HELO 0x00800000 /* we used HELO: ignore extensions */ +#endif /* _FFR_IGNORE_EXT_ON_HELO */ #define MCIF_ONLY_EHLO 0x10000000 /* use only EHLO in smtpinit */ - /* states */ #define MCIS_CLOSED 0 /* no traffic on this connection */ #define MCIS_OPENING 1 /* sending initial protocol */ #define MCIS_OPEN 2 /* open, initial protocol sent */ -#define MCIS_ACTIVE 3 /* message being sent */ -#define MCIS_QUITING 4 /* running quit protocol */ -#define MCIS_SSD 5 /* service shutting down */ -#define MCIS_ERROR 6 /* I/O error on connection */ +#define MCIS_MAIL 3 /* MAIL command sent */ +#define MCIS_RCPT 4 /* RCPT commands being sent */ +#define MCIS_DATA 5 /* DATA command sent */ +#define MCIS_QUITING 6 /* running quit protocol */ +#define MCIS_SSD 7 /* service shutting down */ +#define MCIS_ERROR 8 /* I/O error on connection */ /* functions */ extern void mci_cache __P((MCI *)); @@ -490,7 +708,11 @@ extern void mci_store_persistent __P((MCI *)); extern int mci_traverse_persistent __P((int (*)(), char *)); extern void mci_unlock_host __P((MCI *)); -/* +EXTERN int MaxMciCache; /* maximum entries in MCI cache */ +EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */ +EXTERN time_t MciInfoTimeout; /* how long 'til we retry down hosts */ + +/* ** Header structure. ** This structure is used internally to store header items. */ @@ -500,8 +722,8 @@ struct header char *h_field; /* the name of the field */ char *h_value; /* the value of that field */ struct header *h_link; /* the next header */ - u_char h_macro; /* include header if macro defined */ - u_long h_flags; /* status bits, see below */ + unsigned char h_macro; /* include header if macro defined */ + unsigned long h_flags; /* status bits, see below */ BITMAP256 h_mflags; /* m_flags bits needed */ }; @@ -515,9 +737,9 @@ typedef struct header HDR; struct hdrinfo { - char *hi_field; /* the name of the field */ - u_long hi_flags; /* status bits, see below */ - char *hi_ruleset; /* validity check ruleset */ + char *hi_field; /* the name of the field */ + unsigned long hi_flags; /* status bits, see below */ + char *hi_ruleset; /* validity check ruleset */ }; extern struct hdrinfo HdrInfo[]; @@ -547,20 +769,20 @@ extern struct hdrinfo HdrInfo[]; #define CHHDR_DEF 0x0001 /* default header */ #define CHHDR_CHECK 0x0002 /* call ruleset for header */ #define CHHDR_USER 0x0004 /* header from user */ -#define CHHDR_QUEUE 0x0008 /* header from qf file */ +#define CHHDR_QUEUE 0x0008 /* header from queue file */ /* functions */ -extern void addheader __P((char *, char *, int, HDR **)); -extern u_long chompheader __P((char *, int, HDR **, ENVELOPE *)); +extern void addheader __P((char *, char *, int, ENVELOPE *)); +extern unsigned long chompheader __P((char *, int, HDR **, ENVELOPE *)); extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *)); -extern HDR *copyheader __P((HDR *)); -extern void eatheader __P((ENVELOPE *, bool)); +extern HDR *copyheader __P((HDR *, SM_RPOOL_T *)); +extern void eatheader __P((ENVELOPE *, bool, bool)); extern char *hvalue __P((char *, HDR *)); extern bool isheader __P((char *)); extern void putfromline __P((MCI *, ENVELOPE *)); extern void setupheaders __P((void)); -/* +/* ** Performance monitoring */ @@ -575,7 +797,7 @@ TIMERS #define PUSHTIMER(l, t) { if (tTd(98, l)) pushtimer(&t); } #define POPTIMER(l, t) { if (tTd(98, l)) poptimer(&t); } -/* +/* ** Envelope structure. ** This structure defines the message itself. There is usually ** only one of these -- for the message that we originally read @@ -589,7 +811,7 @@ struct envelope HDR *e_header; /* head of header list */ long e_msgpriority; /* adjusted priority of this message */ time_t e_ctime; /* time message appeared in the queue */ - char *e_to; /* the target person */ + char *e_to; /* (list of) target person(s) */ ADDRESS e_from; /* the person it is from */ char *e_sender; /* e_from.q_paddr w comments stripped */ char **e_fromdomain; /* the domain part of the sender */ @@ -601,8 +823,10 @@ struct envelope ** to unsigned. We don't use unsigned and == ULONG_MAX because ** some libc's don't have strtoul(), see mail_esmtp_args(). */ + long e_msgsize; /* size of the message in bytes */ - long e_flags; /* flags, see below */ + char *e_msgid; /* message id (for logging) */ + unsigned long e_flags; /* flags, see below */ int e_nrcpts; /* number of recipients */ short e_class; /* msg class (priority, junk, etc.) */ short e_hopcount; /* number of times processed */ @@ -617,29 +841,46 @@ struct envelope ENVELOPE *e_parent; /* the message this one encloses */ ENVELOPE *e_sibling; /* the next envelope of interest */ char *e_bodytype; /* type of message body */ - FILE *e_dfp; /* data file */ + SM_FILE_T *e_dfp; /* data file */ char *e_id; /* code for this entry in queue */ - int e_queuedir; /* index into queue directories */ - FILE *e_xfp; /* transcript file */ - FILE *e_lockfp; /* the lock file for this message */ - char *e_message; /* error message */ - char *e_statmsg; /* stat msg (changes per delivery) */ + int e_qgrp; /* queue group (index into queues) */ + int e_qdir; /* index into queue directories */ + int e_dfqgrp; /* data file queue group index */ + int e_dfqdir; /* data file queue directory index */ + int e_xfqgrp; /* queue group (index into queues) */ + int e_xfqdir; /* index into queue directories (xf) */ + SM_FILE_T *e_xfp; /* transcript file */ + SM_FILE_T *e_lockfp; /* the lock file for this message */ + char *e_message; /* error message; readonly; NULL, or + * static storage, or allocated from + * e_rpool */ + char *e_statmsg; /* stat msg (changes per delivery). + * readonly. NULL or allocated from + * e_rpool. */ +#if _FFR_QUARANTINE + char *e_quarmsg; /* why envelope is quarantined */ + char e_qfletter; /* queue file letter on disk */ +#endif /* _FFR_QUARANTINE */ char *e_msgboundary; /* MIME-style message part boundary */ char *e_origrcpt; /* original recipient (one only) */ char *e_envid; /* envelope id from MAIL FROM: line */ char *e_status; /* DSN status for this message */ time_t e_dtime; /* time of last delivery attempt */ int e_ntries; /* number of delivery attempts */ - dev_t e_dfdev; /* df file's device, for crash recov */ - ino_t e_dfino; /* df file's ino, for crash recovery */ - char *e_macro[MAXMACROID + 1]; /* macro definitions */ - char *e_if_macros[2]; /* HACK: incoming interface info */ - char *e_auth_param; + dev_t e_dfdev; /* data file device (crash recovery) */ + ino_t e_dfino; /* data file inode (crash recovery) */ + MACROS_T e_macro; /* macro definitions */ + MCI *e_mci; /* connection info */ + char *e_auth_param; /* readonly; NULL or static storage or + * allocated from e_rpool */ TIMERS e_timers; /* per job timers */ #if _FFR_QUEUEDELAY int e_queuealg; /* algorithm for queue delay */ time_t e_queuedelay; /* current delay */ #endif /* _FFR_QUEUEDELAY */ + long e_deliver_by; /* deliver by */ + int e_dlvr_flag; /* deliver by flag */ + SM_RPOOL_T *e_rpool; /* resource pool for this envelope */ }; /* values for e_flags */ @@ -664,24 +905,39 @@ struct envelope #define EF_NL_NOT_EOL 0x0040000L /* don't accept raw NL as EOLine */ #define EF_CRLF_NOT_EOL 0x0080000L /* don't accept CR-LF as EOLine */ #define EF_RET_PARAM 0x0100000L /* RCPT command had RET argument */ -#define EF_HAS_DF 0x0200000L /* set when df file is instantiated */ +#define EF_HAS_DF 0x0200000L /* set when data file is instantiated */ #define EF_IS_MIME 0x0400000L /* really is a MIME message */ #define EF_DONT_MIME 0x0800000L /* never MIME this message */ #define EF_DISCARD 0x1000000L /* discard the message */ #define EF_TOOBIG 0x2000000L /* message is too big */ +#define EF_SPLIT 0x4000000L /* envelope has been split */ +#define EF_UNSAFE 0x8000000L /* unsafe: read from untrusted source */ -/* values for e_if_macros */ -#define EIF_ADDR 0 /* ${if_addr} */ +#define DLVR_NOTIFY 0x01 +#define DLVR_RETURN 0x02 +#define DLVR_TRACE 0x10 +#define IS_DLVR_NOTIFY(e) (((e)->e_dlvr_flag & DLVR_NOTIFY) != 0) +#define IS_DLVR_RETURN(e) (((e)->e_dlvr_flag & DLVR_RETURN) != 0) +#define IS_DLVR_TRACE(e) (((e)->e_dlvr_flag & DLVR_TRACE) != 0) +#define IS_DLVR_BY(e) ((e)->e_dlvr_flag != 0) + +#define BODYTYPE_NONE (0) +#define BODYTYPE_7BIT (1) +#define BODYTYPE_8BITMIME (2) +#define BODYTYPE_ILLEGAL (-1) +#define BODYTYPE_VALID(b) ((b) == BODYTYPE_7BIT || (b) == BODYTYPE_8BITMIME) + +extern ENVELOPE BlankEnvelope; /* functions */ -extern void clearenvelope __P((ENVELOPE *, bool)); -extern void dropenvelope __P((ENVELOPE *, bool)); -extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *)); +extern void clearenvelope __P((ENVELOPE *, bool, SM_RPOOL_T *)); +extern void dropenvelope __P((ENVELOPE *, bool, bool)); +extern ENVELOPE *newenvelope __P((ENVELOPE *, ENVELOPE *, SM_RPOOL_T *)); extern void printenvflags __P((ENVELOPE *)); extern void putbody __P((MCI *, ENVELOPE *, char *)); extern void putheader __P((MCI *, HDR *, ENVELOPE *, int)); -/* +/* ** Message priority classes. ** ** The message class is read directly from the Priority: header @@ -711,7 +967,10 @@ struct priority int pri_val; /* internal value for same */ }; -/* +EXTERN int NumPriorities; /* pointer into Priorities */ +EXTERN struct priority Priorities[MAXPRIORITIES]; + +/* ** Rewrite rules. */ @@ -732,35 +991,35 @@ struct rewrite */ /* left hand side items */ -#define MATCHZANY ((u_char)0220) /* match zero or more tokens */ -#define MATCHANY ((u_char)0221) /* match one or more tokens */ -#define MATCHONE ((u_char)0222) /* match exactly one token */ -#define MATCHCLASS ((u_char)0223) /* match one token in a class */ -#define MATCHNCLASS ((u_char)0224) /* match anything not in class */ -#define MATCHREPL ((u_char)0225) /* replacement on RHS for above */ +#define MATCHZANY ((unsigned char)0220) /* match zero or more tokens */ +#define MATCHANY ((unsigned char)0221) /* match one or more tokens */ +#define MATCHONE ((unsigned char)0222) /* match exactly one token */ +#define MATCHCLASS ((unsigned char)0223) /* match one token in a class */ +#define MATCHNCLASS ((unsigned char)0224) /* match anything not in class */ +#define MATCHREPL ((unsigned char)0225) /* replacement on RHS for above */ /* right hand side items */ -#define CANONNET ((u_char)0226) /* canonical net, next token */ -#define CANONHOST ((u_char)0227) /* canonical host, next token */ -#define CANONUSER ((u_char)0230) /* canonical user, next N tokens */ -#define CALLSUBR ((u_char)0231) /* call another rewriting set */ +#define CANONNET ((unsigned char)0226) /* canonical net, next token */ +#define CANONHOST ((unsigned char)0227) /* canonical host, next token */ +#define CANONUSER ((unsigned char)0230) /* canonical user, next N tokens */ +#define CALLSUBR ((unsigned char)0231) /* call another rewriting set */ /* conditionals in macros */ -#define CONDIF ((u_char)0232) /* conditional if-then */ -#define CONDELSE ((u_char)0233) /* conditional else */ -#define CONDFI ((u_char)0234) /* conditional fi */ +#define CONDIF ((unsigned char)0232) /* conditional if-then */ +#define CONDELSE ((unsigned char)0233) /* conditional else */ +#define CONDFI ((unsigned char)0234) /* conditional fi */ /* bracket characters for host name lookup */ -#define HOSTBEGIN ((u_char)0235) /* hostname lookup begin */ -#define HOSTEND ((u_char)0236) /* hostname lookup end */ +#define HOSTBEGIN ((unsigned char)0235) /* hostname lookup begin */ +#define HOSTEND ((unsigned char)0236) /* hostname lookup end */ /* bracket characters for generalized lookup */ -#define LOOKUPBEGIN ((u_char)0205) /* generalized lookup begin */ -#define LOOKUPEND ((u_char)0206) /* generalized lookup end */ +#define LOOKUPBEGIN ((unsigned char)0205) /* generalized lookup begin */ +#define LOOKUPEND ((unsigned char)0206) /* generalized lookup end */ /* macro substitution character */ -#define MACROEXPAND ((u_char)0201) /* macro expansion */ -#define MACRODEXPAND ((u_char)0202) /* deferred macro expansion */ +#define MACROEXPAND ((unsigned char)0201) /* macro expansion */ +#define MACRODEXPAND ((unsigned char)0202) /* deferred macro expansion */ /* to make the code clearer */ #define MATCHZERO CANONHOST @@ -770,26 +1029,50 @@ struct rewrite /* external <==> internal mapping table */ struct metamac { - char metaname; /* external code (after $) */ - u_char metaval; /* internal code (as above) */ + char metaname; /* external code (after $) */ + unsigned char metaval; /* internal code (as above) */ }; /* values for macros with external names only */ #define MID_OPMODE 0202 /* operation mode */ /* functions */ -extern void define __P((int, char *, ENVELOPE *)); +#if SM_HEAP_CHECK +extern void +macdefine_tagged __P(( + MACROS_T *_mac, + ARGCLASS_T _vclass, + int _id, + char *_value, + char *_file, + int _line, + int _group)); +# define macdefine(mac,c,id,v) \ + macdefine_tagged(mac,c,id,v,__FILE__,__LINE__,sm_heap_group()) +#else /* SM_HEAP_CHECK */ +extern void +macdefine __P(( + MACROS_T *_mac, + ARGCLASS_T _vclass, + int _id, + char *_value)); +# define macdefine_tagged(mac,c,id,v,file,line,grp) macdefine(mac,c,id,v) +#endif /* SM_HEAP_CHECK */ +extern void macset __P((MACROS_T *, int, char *)); +#define macget(mac, i) (mac)->mac_table[i] extern void expand __P((char *, char *, size_t, ENVELOPE *)); -extern int macid __P((char *, char **)); +extern int macid_parse __P((char *, char **)); +#define macid(name) macid_parse(name, NULL) extern char *macname __P((int)); extern char *macvalue __P((int, ENVELOPE *)); -extern int rscheck __P((char *, char *, char *, ENVELOPE *, bool, bool, int, char *)); +extern int rscheck __P((char *, char *, char *, ENVELOPE *, bool, bool, int, char *, char *)); +extern int rscap __P((char *, char *, char *, ENVELOPE *, char ***, char *, int)); extern void setclass __P((int, char *)); extern int strtorwset __P((char *, char **, int)); extern void translate_dollars __P((char *)); extern bool wordinclass __P((char *, int)); -/* +/* ** Name canonification short circuit. ** ** If the name server for a host is down, the process of trying to @@ -808,16 +1091,29 @@ NAMECANON short nc_stat; /* cached exit status code */ short nc_flags; /* flag bits */ char *nc_cname; /* the canonical name */ + time_t nc_exp; /* entry expires at */ }; /* values for nc_flags */ #define NCF_VALID 0x0001 /* entry valid */ +/* hostsignature structure */ + +struct hostsig_t +{ + char *hs_sig; /* hostsignature */ + time_t hs_exp; /* entry expires at */ +}; + +typedef struct hostsig_t HOSTSIG_T; + /* functions */ -extern bool getcanonname __P((char *, int, bool)); -extern int getmxrr __P((char *, char **, u_short *, bool, int *)); +extern bool getcanonname __P((char *, int, bool, int *)); +extern int getmxrr __P((char *, char **, unsigned short *, bool, int *, bool, int *)); +extern char *hostsignature __P((MAILER *, char *)); +extern int getfallbackmxrr __P((char *)); -/* +/* ** Mapping functions ** ** These allow arbitrary mappings in the config file. The idea @@ -836,6 +1132,7 @@ extern int getmxrr __P((char *, char **, u_short *, bool, int *)); MAP { MAPCLASS *map_class; /* the class of this map */ + MAPCLASS *map_orgclass; /* the original class of this map */ char *map_mname; /* name of this map */ long map_mflags; /* flags, see below */ char *map_file; /* the (nominal) filename */ @@ -843,8 +1140,8 @@ MAP ARBPTR_T map_db2; /* an "extra" database pointer */ char *map_keycolnm; /* key column name */ char *map_valcolnm; /* value column name */ - u_char map_keycolno; /* key column number */ - u_char map_valcolno; /* value column number */ + unsigned char map_keycolno; /* key column number */ + unsigned char map_valcolno; /* value column number */ char map_coldelim; /* column delimiter */ char map_spacesub; /* spacesub */ char *map_app; /* to append to successful matches */ @@ -852,6 +1149,8 @@ MAP char *map_domain; /* the (nominal) NIS domain */ char *map_rebuild; /* program to run to do auto-rebuild */ time_t map_mtime; /* last database modification time */ + time_t map_timeout; /* timeout for map accesses */ + int map_retry; /* # of retries for map accesses */ pid_t map_pid; /* PID of process which opened map */ int map_lockfd; /* auxiliary lock file descriptor */ short map_specificity; /* specificity of aliases */ @@ -875,15 +1174,17 @@ MAP #define MF_ALIASWAIT 0x00000800 /* alias map in aliaswait state */ #define MF_IMPL_HASH 0x00001000 /* implicit: underlying hash database */ #define MF_IMPL_NDBM 0x00002000 /* implicit: underlying NDBM database */ -#define MF_UNSAFEDB 0x00004000 /* this map is world writable */ +/* 0x00004000 */ #define MF_APPEND 0x00008000 /* append new entry on rebuild */ #define MF_KEEPQUOTES 0x00010000 /* don't dequote key before lookup */ #define MF_NODEFER 0x00020000 /* don't defer if map lookup fails */ #define MF_REGEX_NOT 0x00040000 /* regular expression negation */ #define MF_DEFER 0x00080000 /* don't lookup map in defer mode */ #define MF_SINGLEMATCH 0x00100000 /* successful only if match one key */ -#define MF_NOREWRITE 0x00200000 /* don't rewrite result, return as-is */ -#define MF_CLOSING 0x00400000 /* map is being closed */ +/* 0x00200000 available for use */ +#define MF_FILECLASS 0x00400000 /* this is a file class map */ +#define MF_OPENBOGUS 0x00800000 /* open failed, don't call map_close */ +#define MF_CLOSING 0x01000000 /* map is being closed */ #define DYNOPENMAP(map) if (!bitset(MF_OPEN, (map)->map_mflags)) \ { \ @@ -897,6 +1198,15 @@ MAP #define MA_UNAVAIL 1 /* member map is not available */ #define MA_TRYAGAIN 2 /* member map returns temp failure */ +/* macros to handle MapTempFail */ +#define BIT_IS_MTP 0x01 /* temp.failure occurred */ +#define BIT_ASK_MTP 0x02 /* do we care about MapTempFail? */ +#define RESET_MAPTEMPFAIL MapTempFail = 0 +#define INIT_MAPTEMPFAIL MapTempFail = BIT_ASK_MTP +#define SET_MAPTEMPFAIL MapTempFail |= BIT_IS_MTP +#define IS_MAPTEMPFAIL bitset(BIT_IS_MTP, MapTempFail) +#define ASK_MAPTEMPFAIL bitset(BIT_ASK_MTP, MapTempFail) + /* ** The class of a map -- essentially the functions to call */ @@ -923,9 +1233,10 @@ MAPCLASS #define MCF_ALIASONLY 0x0002 /* usable only for aliases */ #define MCF_REBUILDABLE 0x0004 /* can rebuild alias files */ #define MCF_OPTFILE 0x0008 /* file name is optional */ +#define MCF_NOTPERSIST 0x0010 /* don't keep map open all the time */ /* functions */ -extern void closemaps __P((void)); +extern void closemaps __P((bool)); extern bool impl_map_open __P((MAP *, int)); extern void initmaps __P((void)); extern MAP *makemapentry __P((char *)); @@ -938,47 +1249,13 @@ extern bool openmap __P((MAP *)); #if USERDB extern void _udbx_close __P((void)); extern int udbexpand __P((ADDRESS *, ADDRESS **, int, ENVELOPE *)); -extern char *udbsender __P((char *)); +extern char *udbsender __P((char *, SM_RPOOL_T *)); #endif /* USERDB */ -/* + +/* ** LDAP related items */ -#ifdef LDAPMAP -struct ldapmap_struct -{ - /* needed for ldap_open or ldap_init */ - char *ldap_host; - int ldap_port; - - /* options set in ld struct before ldap_bind_s */ - int ldap_deref; - time_t ldap_timelimit; - int ldap_sizelimit; - int ldap_options; - - /* args for ldap_bind_s */ - LDAP *ldap_ld; - char *ldap_binddn; - char *ldap_secret; - int ldap_method; - - /* args for ldap_search */ - char *ldap_base; - int ldap_scope; - char *ldap_filter; - char *ldap_attr[LDAPMAP_MAX_ATTR + 1]; - bool ldap_attrsonly; - - /* args for ldap_result */ - struct timeval ldap_timeout; - LDAPMessage *ldap_res; - - /* Linked list of maps sharing the same LDAP binding */ - MAP *ldap_next; -}; - -typedef struct ldapmap_struct LDAPMAP_STRUCT; - +#if LDAPMAP /* struct defining LDAP Auth Methods */ struct lamvalues { @@ -1005,35 +1282,29 @@ extern bool ldapmap_parseargs __P((MAP *, char *)); extern void ldapmap_set_defaults __P((char *)); #endif /* LDAPMAP */ -/* +/* ** PH related items */ -#ifdef PH_MAP +#if PH_MAP + +# include <phclient.h> + struct ph_map_struct { - char *ph_servers; /* list of ph servers */ - char *ph_field_list; /* list of fields to search for match */ - FILE *ph_to_server; - FILE *ph_from_server; - int ph_sockfd; - time_t ph_timeout; + char *ph_servers; /* list of ph servers */ + char *ph_field_list; /* list of fields to search for match */ + PH *ph; /* PH server handle */ + int ph_fastclose; /* send "quit" command on close */ + time_t ph_timeout; /* timeout interval */ }; typedef struct ph_map_struct PH_MAP_STRUCT; -# define DEFAULT_PH_MAP_FIELDS "alias callsign name spacedname" #endif /* PH_MAP */ -/* +/* ** Process List (proclist) */ -struct procs -{ - pid_t proc_pid; - char *proc_task; - int proc_type; -}; - #define NO_PID ((pid_t) 0) #ifndef PROC_LIST_SEG # define PROC_LIST_SEG 32 /* number of pids to alloc at a time */ @@ -1049,22 +1320,22 @@ struct procs #define PROC_CONTROL_CHILD 5 /* functions */ -extern void proc_list_add __P((pid_t, char *, int)); +extern void proc_list_add __P((pid_t, char *, int, int, int)); extern void proc_list_clear __P((void)); -extern void proc_list_display __P((FILE *)); -extern int proc_list_drop __P((pid_t)); +extern void proc_list_display __P((SM_FILE_T *, char *)); +extern void proc_list_drop __P((pid_t, int, int *)); extern void proc_list_probe __P((void)); extern void proc_list_set __P((pid_t, char *)); +extern void proc_list_signal __P((int, int)); -/* +/* ** Symbol table definitions */ struct symtab { char *s_name; /* name to be entered */ - short s_type; /* general type (see below) */ - short s_len; /* length of this entry */ + short s_symtype; /* general type (see below) */ struct symtab *s_next; /* pointer to next in chain */ union { @@ -1074,19 +1345,20 @@ struct symtab char *sv_alias; /* alias */ MAPCLASS sv_mapclass; /* mapping function class */ MAP sv_map; /* mapping function */ - char *sv_hostsig; /* host signature */ + HOSTSIG_T sv_hostsig; /* host signature */ MCI sv_mci; /* mailer connection info */ NAMECANON sv_namecanon; /* canonical name cache */ int sv_macro; /* macro name => id mapping */ int sv_ruleset; /* ruleset index */ struct hdrinfo sv_header; /* header metainfo */ char *sv_service[MAXMAPSTACK]; /* service switch */ -#ifdef LDAPMAP +#if LDAPMAP MAP *sv_lmap; /* Maps for LDAP connection */ #endif /* LDAPMAP */ -#if _FFR_MILTER +#if MILTER struct milter *sv_milter; /* milter filter name */ -#endif /* _FFR_MILTER */ +#endif /* MILTER */ + QUEUEGRP *sv_queue; /* pointer to queue */ } s_value; }; @@ -1106,12 +1378,15 @@ typedef struct symtab STAB; #define ST_RULESET 10 /* ruleset index */ #define ST_SERVICE 11 /* service switch entry */ #define ST_HEADER 12 /* special header flags */ -#ifdef LDAPMAP +#if LDAPMAP # define ST_LMAP 13 /* List head of maps for LDAP connection */ #endif /* LDAPMAP */ -#if _FFR_MILTER +#if MILTER # define ST_MILTER 14 /* milter filter */ -#endif /* _FFR_MILTER */ +#endif /* MILTER */ +#define ST_QUEUE 15 /* a queue entry */ + +/* This entry must be last */ #define ST_MCI 16 /* mailer connection info (offset) */ #define s_class s_value.sv_class @@ -1127,12 +1402,13 @@ typedef struct symtab STAB; #define s_ruleset s_value.sv_ruleset #define s_service s_value.sv_service #define s_header s_value.sv_header -#ifdef LDAPMAP +#if LDAPMAP # define s_lmap s_value.sv_lmap #endif /* LDAPMAP */ -#if _FFR_MILTER +#if MILTER # define s_milter s_value.sv_milter -#endif /* _FFR_MILTER */ +#endif /* MILTER */ +#define s_quegrp s_value.sv_queue /* opcodes to stab */ #define ST_FIND 0 /* find entry */ @@ -1142,34 +1418,7 @@ typedef struct symtab STAB; extern STAB *stab __P((char *, int, int)); extern void stabapply __P((void (*)(STAB *, int), int)); -/* -** STRUCT EVENT -- event queue. -** -** Maintained in sorted order. -** -** We store the pid of the process that set this event to insure -** that when we fork we will not take events intended for the parent. -*/ - -struct event -{ - time_t ev_time; /* time of the function call */ - void (*ev_func)__P((int)); - /* function to call */ - int ev_arg; /* argument to ev_func */ - pid_t ev_pid; /* pid that set this event */ - struct event *ev_link; /* link to next item */ -}; - -typedef struct event EVENT; - -/* functions */ -extern void clrevent __P((EVENT *)); -extern void clear_events __P((void)); -extern EVENT *setevent __P((time_t, void(*)(), int)); -extern EVENT *sigsafe_setevent __P((time_t, void(*)(), int)); - -/* +/* ** Operation, send, error, and MIME modes ** ** The operation mode describes the basic operation of sendmail. @@ -1177,7 +1426,7 @@ extern EVENT *sigsafe_setevent __P((time_t, void(*)(), int)); ** default. ** ** The send mode tells how to send mail. It can be set in the -** configuration file. It's setting determines how quickly the +** configuration file. Its setting determines how quickly the ** mail will be delivered versus the load on your system. If the ** -v (verbose) flag is given, it will be forced to SM_DELIVER ** mode. @@ -1194,11 +1443,14 @@ extern EVENT *sigsafe_setevent __P((time_t, void(*)(), int)); #define MD_TEST 't' /* test mode: resolve addrs only */ #define MD_INITALIAS 'i' /* initialize alias database */ #define MD_PRINT 'p' /* print the queue */ +#define MD_PRINTNQE 'P' /* print number of entries in queue */ #define MD_FREEZE 'z' /* freeze the configuration file */ #define MD_HOSTSTAT 'h' /* print persistent host stat info */ #define MD_PURGESTAT 'H' /* purge persistent host stat info */ #define MD_QUEUERUN 'q' /* queue run */ +/* Note: see also include/sendmail/pathnames.h: GET_CLIENT_CF */ + /* values for e_sendmode -- send modes */ #define SM_DELIVER 'i' /* interactive delivery */ #define SM_FORK 'b' /* deliver in background */ @@ -1206,6 +1458,7 @@ extern EVENT *sigsafe_setevent __P((time_t, void(*)(), int)); #define SM_DEFER 'd' /* defer map lookups as well as queue */ #define SM_VERIFY 'v' /* verify only (used internally) */ +#define WILL_BE_QUEUED(m) ((m) == SM_QUEUE || (m) == SM_DEFER) /* used only as a parameter to sendall */ #define SM_DEFAULT '\0' /* unspecified, use SendMode */ @@ -1246,30 +1499,33 @@ extern void set_delivery_mode __P((int, ENVELOPE *)); ** These are bit values for the PrivacyFlags word. */ -#define PRIV_PUBLIC 0 /* what have I got to hide? */ -#define PRIV_NEEDMAILHELO 0x0001 /* insist on HELO for MAIL, at least */ -#define PRIV_NEEDEXPNHELO 0x0002 /* insist on HELO for EXPN */ -#define PRIV_NEEDVRFYHELO 0x0004 /* insist on HELO for VRFY */ -#define PRIV_NOEXPN 0x0008 /* disallow EXPN command entirely */ -#define PRIV_NOVRFY 0x0010 /* disallow VRFY command entirely */ -#define PRIV_AUTHWARNINGS 0x0020 /* flag possible authorization probs */ -#define PRIV_NORECEIPTS 0x0040 /* disallow return receipts */ -#define PRIV_NOVERB 0x0100 /* disallow VERB command entirely */ -#define PRIV_RESTRICTMAILQ 0x1000 /* restrict mailq command */ -#define PRIV_RESTRICTQRUN 0x2000 /* restrict queue run */ -#define PRIV_NOETRN 0x4000 /* disallow ETRN command entirely */ -#define PRIV_NOBODYRETN 0x8000 /* do not return bodies on bounces */ +#define PRIV_PUBLIC 0 /* what have I got to hide? */ +#define PRIV_NEEDMAILHELO 0x00000001 /* insist on HELO for MAIL */ +#define PRIV_NEEDEXPNHELO 0x00000002 /* insist on HELO for EXPN */ +#define PRIV_NEEDVRFYHELO 0x00000004 /* insist on HELO for VRFY */ +#define PRIV_NOEXPN 0x00000008 /* disallow EXPN command */ +#define PRIV_NOVRFY 0x00000010 /* disallow VRFY command */ +#define PRIV_AUTHWARNINGS 0x00000020 /* flag possible auth probs */ +#define PRIV_NOVERB 0x00000040 /* disallow VERB command */ +#define PRIV_RESTRICTMAILQ 0x00010000 /* restrict mailq command */ +#define PRIV_RESTRICTQRUN 0x00020000 /* restrict queue run */ +#define PRIV_RESTRICTEXPAND 0x00040000 /* restrict alias/forward expansion */ +#define PRIV_NOETRN 0x00080000 /* disallow ETRN command */ +#define PRIV_NOBODYRETN 0x00100000 /* do not return bodies on bounces */ +#define PRIV_NORECEIPTS 0x00200000 /* disallow return receipts */ /* don't give no info, anyway, anyhow */ -#define PRIV_GOAWAY (0x0fff & ~PRIV_NORECEIPTS) +#define PRIV_GOAWAY 0x0000ffff /* struct defining such things */ struct prival { - char *pv_name; /* name of privacy flag */ - u_short pv_flag; /* numeric level */ + char *pv_name; /* name of privacy flag */ + unsigned long pv_flag; /* numeric level */ }; +EXTERN unsigned long PrivacyFlags; /* privacy flags */ + /* ** Flags passed to remotename, parseaddr, allocaddr, and buildaddr. @@ -1344,35 +1600,32 @@ union bigsockaddr extern char *anynet_ntoa __P((SOCKADDR *)); # if NETINET6 extern char *anynet_ntop __P((struct in6_addr *, char *, size_t)); +extern int anynet_pton __P((int, const char *, void *)); # endif /* NETINET6 */ extern char *hostnamebyanyaddr __P((SOCKADDR *)); -# if DAEMON extern char *validate_connection __P((SOCKADDR *, char *, ENVELOPE *)); -# endif /* DAEMON */ #endif /* NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 */ -#if _FFR_MILTER -/* +#if MILTER +/* ** Mail Filters (milter) */ -#include <libmilter/milter.h> - -#define SMFTO_WRITE 0 /* Timeout for sending information */ -#define SMFTO_READ 1 /* Timeout waiting for a response */ -#define SMFTO_EOM 2 /* Timeout for ACK/NAK to EOM */ -#define SMFTO_CONNECT 3 /* Timeout for connect() */ +# define SMFTO_WRITE 0 /* Timeout for sending information */ +# define SMFTO_READ 1 /* Timeout waiting for a response */ +# define SMFTO_EOM 2 /* Timeout for ACK/NAK to EOM */ +# define SMFTO_CONNECT 3 /* Timeout for connect() */ -#define SMFTO_NUM_TO 4 /* Total number of timeouts */ +# define SMFTO_NUM_TO 4 /* Total number of timeouts */ struct milter { char *mf_name; /* filter name */ BITMAP256 mf_flags; /* MTA flags */ - u_long mf_fvers; /* filter version */ - u_long mf_fflags; /* filter flags */ - u_long mf_pflags; /* protocol flags */ + unsigned long mf_fvers; /* filter version */ + unsigned long mf_fflags; /* filter flags */ + unsigned long mf_pflags; /* protocol flags */ char *mf_conn; /* connection info */ int mf_sock; /* connected socket */ char mf_state; /* state of filter */ @@ -1392,12 +1645,22 @@ struct milter # define SMFS_ERROR 'E' /* error state */ # define SMFS_READY 'R' /* ready for action */ -/* 32-bit type used by milter */ -typedef SM_INT32 mi_int32; - EXTERN struct milter *InputFilters[MAXFILTERS]; EXTERN char *InputFilterList; -#endif /* _FFR_MILTER */ +EXTERN int MilterLogLevel; + +# if _FFR_MILTER_PERDAEMON +/* functions */ +extern void setup_daemon_milters __P(()); +# endif /* _FFR_MILTER_PERDAEMON */ +#endif /* MILTER */ + +/* +** 32-bit type used by milter +** (needed by libmilter even if MILTER isn't defined) +*/ + +typedef SM_INT32 mi_int32; /* ** Vendor codes @@ -1419,6 +1682,7 @@ EXTERN char *InputFilterList; #define VENDOR_HP 3 /* Hewlett-Packard specific config syntax */ #define VENDOR_IBM 4 /* IBM specific config syntax */ #define VENDOR_SENDMAIL 5 /* Sendmail, Inc. specific config syntax */ +#define VENDOR_DEC 6 /* Compaq, DEC, Digital */ /* prototypes for vendor-specific hook routines */ extern void vendor_daemon_setup __P((ENVELOPE *)); @@ -1437,60 +1701,36 @@ struct termescape char *te_rv_off; /* turn reverse-video off */ }; -/* +/* ** Additional definitions */ -/* d_flags, see daemon.c */ -/* general rule: lower case: required, upper case: No */ +/* +** d_flags, see daemon.c +** general rule: lower case: required, upper case: No +*/ + #define D_AUTHREQ 'a' /* authentication required */ #define D_BINDIF 'b' /* use if_addr for outgoing connection */ #define D_CANONREQ 'c' /* canonification required (cf) */ #define D_IFNHELO 'h' /* use if name for HELO */ #define D_FQMAIL 'f' /* fq sender address required (cf) */ -#if _FFR_TLS_CLT1 -#define D_CLTNOTLS 'S' /* don't use STARTTLS in client */ -#endif /* _FFR_TLS_CLT1 */ #define D_FQRCPT 'r' /* fq recipient address required (cf) */ +#if _FFR_SMTP_SSL +# define D_SMTPS 's' /* SMTP over SSL (smtps) */ +#endif /* _FFR_SMTP_SSL */ #define D_UNQUALOK 'u' /* unqualified address is ok (cf) */ +#define D_NOAUTH 'A' /* no AUTH */ #define D_NOCANON 'C' /* no canonification (cf) */ #define D_NOETRN 'E' /* no ETRN (MSA) */ +#define D_NOTLS 'S' /* don't use STARTTLS */ #define D_ETRNONLY ((char)0x01) /* allow only ETRN (disk low) */ - -/* Flags for submitmode */ -#define SUBMIT_UNKNOWN 0x0000 /* unknown agent type */ -#define SUBMIT_MTA 0x0001 /* act like a message transfer agent */ -#define SUBMIT_MSA 0x0002 /* act like a message submission agent */ - -#if SASL -/* -** SASL -*/ - -/* authenticated? */ -# define SASL_NOT_AUTH 0 /* not authenticated */ -# define SASL_PROC_AUTH 1 /* in process of authenticating */ -# define SASL_IS_AUTH 2 /* authenticated */ - -/* SASL options */ -# define SASL_AUTH_AUTH 0x1000 /* use auth= only if authenticated */ -# if _FFR_SASL_OPTS -# define SASL_SEC_MASK 0x0fff /* mask for SASL_SEC_* values: sasl.h */ -# if (SASL_SEC_NOPLAINTEXT & SASL_SEC_MASK) == 0 || \ - (SASL_SEC_NOACTIVE & SASL_SEC_MASK) == 0 || \ - (SASL_SEC_NODICTIONARY & SASL_SEC_MASK) == 0 || \ - (SASL_SEC_FORWARD_SECRECY & SASL_SEC_MASK) == 0 || \ - (SASL_SEC_NOANONYMOUS & SASL_SEC_MASK) == 0 || \ - (SASL_SEC_PASS_CREDENTIALS & SASL_SEC_MASK) == 0 -ERROR: change SASL_SEC_MASK_ notify sendmail.org! -# endif -# endif /* _FFR_SASL_OPTS */ - -# define MAXOUTLEN 1024 /* length of output buffer */ -#endif /* SASL */ +#define D_OPTIONAL 'O' /* optional socket */ +#define D_DISABLE ((char)0x02) /* optional socket disabled */ +#define D_ISSET ((char)0x03) /* this client struct is set */ #if STARTTLS -/* +/* ** TLS */ @@ -1517,65 +1757,178 @@ ERROR: change SASL_SEC_MASK_ notify sendmail.org! #define TLS_I_DH512 0x00040000 /* generate 512bit DH param */ #define TLS_I_DH1024 0x00080000 /* generate 1024bit DH param */ #define TLS_I_DH2048 0x00100000 /* generate 2048bit DH param */ +#define TLS_I_NO_VRFY 0x00200000 /* do not require authentication */ +#define TLS_I_KEY_OUNR 0x00400000 /* KEY must be o unreadable */ + +/* require server cert */ +#define TLS_I_SRV_CERT (TLS_I_CERT_EX | TLS_I_KEY_EX | \ + TLS_I_KEY_UNR | TLS_I_KEY_OUNR | \ + TLS_I_CERTP_EX | TLS_I_CERTF_EX | \ + TLS_I_USE_KEY | TLS_I_USE_CERT) /* server requirements */ -#define TLS_I_SRV (TLS_I_CERT_EX | TLS_I_KEY_EX | TLS_I_KEY_UNR | \ - TLS_I_CERTP_EX | TLS_I_CERTF_EX | TLS_I_RSA_TMP | \ - TLS_I_USE_KEY | TLS_I_USE_CERT | TLS_I_VRFY_PATH | \ - TLS_I_VRFY_LOC | TLS_I_TRY_DH | \ - TLS_I_DH512) +#define TLS_I_SRV (TLS_I_SRV_CERT | TLS_I_RSA_TMP | TLS_I_VRFY_PATH | \ + TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_DH512) /* client requirements */ -#define TLS_I_CLT (TLS_I_KEY_UNR) +#define TLS_I_CLT (TLS_I_KEY_UNR | TLS_I_KEY_OUNR) #define TLS_AUTH_OK 0 #define TLS_AUTH_NO 1 #define TLS_AUTH_FAIL (-1) -#endif /* STARTTLS */ + +/* functions */ +extern bool init_tls_library __P((void)); +extern bool inittls __P((SSL_CTX **, unsigned long, bool, char *, char *, char *, char *, char *)); +extern bool initclttls __P((bool)); +extern void setclttls __P((bool)); +extern bool initsrvtls __P((bool)); +extern int tls_get_info __P((SSL *, bool, char *, MACROS_T *, bool)); +extern int endtls __P((SSL *, char *)); +extern void tlslogerr __P((char *)); -/* +EXTERN char *CACERTpath; /* path to CA certificates (dir. with hashes) */ +EXTERN char *CACERTfile; /* file with CA certificate */ +EXTERN char *CltCERTfile; /* file with client certificate */ +EXTERN char *Cltkeyfile; /* file with client private key */ +# if _FFR_TLS_1 +EXTERN char *CipherList; /* list of ciphers */ +EXTERN char *DHParams5; /* file with DH parameters (512) */ +# endif /* _FFR_TLS_1 */ +EXTERN char *DHParams; /* file with DH parameters */ +EXTERN char *RandFile; /* source of random data */ +EXTERN char *SrvCERTfile; /* file with server certificate */ +EXTERN char *Srvkeyfile; /* file with server private key */ +EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ +#endif /* STARTTLS */ + +/* ** Queue related items */ +/* queue file names */ +#if _FFR_QUARANTINE +# define ANYQFL_LETTER '?' +# define QUARQF_LETTER 'h' +#else /* _FFR_QUARANTINE */ +/* Before quarantining, ANYQF == NORMQF */ +# define ANYQFL_LETTER 'q' +#endif /* _FFR_QUARANTINE */ +#define DATAFL_LETTER 'd' +#define XSCRPT_LETTER 'x' +#define NORMQF_LETTER 'q' +#define NEWQFL_LETTER 't' + +# define TEMPQF_LETTER 'T' +# define LOSEQF_LETTER 'Q' + /* queue sort order */ #define QSO_BYPRIORITY 0 /* sort by message priority */ #define QSO_BYHOST 1 /* sort by first host name */ #define QSO_BYTIME 2 /* sort by submission time */ #define QSO_BYFILENAME 3 /* sort by file name only */ +#define QSO_RANDOM 4 /* sort in random order */ +#define QSO_BYMODTIME 5 /* sort by modification time */ +#if _FFR_RHS +# define QSO_BYSHUFFLE 6 /* sort by shuffled host name */ +#endif /* _FFR_RHS */ #if _FFR_QUEUEDELAY -#define QD_LINEAR 0 /* linear (old) delay alg */ -#define QD_EXP 1 /* exponential delay alg */ +# define QD_LINEAR 0 /* linear (old) delay alg */ +# define QD_EXP 1 /* exponential delay alg */ #endif /* _FFR_QUEUEDELAY */ -#define NOQDIR (-1) /* no queue directory (yet) */ - -#define NOW ((time_t) (-1)) /* queue return: now */ +#define NOQGRP (-1) /* no queue group (yet) */ +#define ENVQGRP (-2) /* use queue group of envelope */ +#define NOAQGRP (-3) /* no queue group in addr (yet) */ +#define ISVALIDQGRP(x) ((x) >= 0) /* valid queue group? */ +#define NOQDIR (-1) /* no queue directory (yet) */ +#define ENVQDIR (-2) /* use queue directory of envelope */ +#define NOAQDIR (-3) /* no queue directory in addr (yet) */ +#define ISVALIDQDIR(x) ((x) >= 0) /* valid queue directory? */ +#define RS_QUEUEGROUP "queuegroup" /* ruleset for queue group selection */ + +#define NOW ((time_t) (-1)) /* queue return: now */ + +/* SuperSafe values */ +#define SAFE_NO 0 /* no fsync(): don't use... */ +#define SAFE_INTERACTIVE 1 /* limit fsync() in -odi */ +#define SAFE_REALLY 2 /* always fsync() */ + +#if _FFR_QUARANTINE +/* QueueMode bits */ +# define QM_NORMAL ' ' +# define QM_QUARANTINE 'Q' +# define QM_LOST 'L' +#endif /* _FFR_QUARANTINE */ /* Queue Run Limitations */ struct queue_char { - char *queue_match; /* string to match */ - struct queue_char *queue_next; + char *queue_match; /* string to match */ + bool queue_negate; /* or not match, if set */ + struct queue_char *queue_next; }; -typedef struct queue_char QUEUE_CHAR; +typedef struct queue_char QUEUE_CHAR; + +EXTERN int volatile CurRunners; /* current number of runner children */ +EXTERN int MaxQueueRun; /* maximum number of jobs in one queue run */ +EXTERN int MaxQueueChildren; /* max # of forked queue children */ +EXTERN int MaxRunnersPerQueue; /* max # proc's active in queue group */ +EXTERN int NiceQueueRun; /* nice queue runs to this value */ +EXTERN int NumQueue; /* number of queue groups */ +EXTERN int QueueFileMode; /* mode on files in mail queue */ +#if _FFR_QUARANTINE +EXTERN int QueueMode; /* which queue items to act upon */ +#endif /* _FFR_QUARANTINE */ +EXTERN int QueueSortOrder; /* queue sorting order algorithm */ +EXTERN time_t MinQueueAge; /* min delivery interval */ +EXTERN time_t QueueIntvl; /* intervals between running the queue */ +EXTERN char *QueueDir; /* location of queue directory */ +#if _FFR_QUEUEDELAY +EXTERN int QueueAlg; /* algorithm for queue delays */ +EXTERN time_t QueueInitDelay; /* initial queue delay */ +EXTERN time_t QueueMaxDelay; /* maximum queue delay */ +#endif /* _FFR_QUEUEDELAY */ +EXTERN QUEUE_CHAR *QueueLimitId; /* limit queue run to id */ +#if _FFR_QUARANTINE +EXTERN QUEUE_CHAR *QueueLimitQuarantine; /* limit queue run to quarantine reason */ +#endif /* _FFR_QUARANTINE */ +EXTERN QUEUE_CHAR *QueueLimitRecipient; /* limit queue run to rcpt */ +EXTERN QUEUE_CHAR *QueueLimitSender; /* limit queue run to sender */ +EXTERN QUEUEGRP *Queue[MAXQUEUEGROUPS + 1]; /* queue groups */ /* functions */ extern void assign_queueid __P((ENVELOPE *)); -extern ADDRESS *copyqueue __P((ADDRESS *)); +extern ADDRESS *copyqueue __P((ADDRESS *, SM_RPOOL_T *)); +extern void cleanup_queues __P((void)); +extern bool doqueuerun __P((void)); extern void initsys __P((ENVELOPE *)); extern void loseqfile __P((ENVELOPE *, char *)); -extern void multiqueue_cache __P((void)); +extern int name2qid __P((char *)); extern char *qid_printname __P((ENVELOPE *)); -extern char *qid_printqueue __P((int)); +extern char *qid_printqueue __P((int, int)); +#if _FFR_QUARANTINE +extern void quarantine_queue __P((char *, int)); +#endif /* _FFR_QUARANTINE */ extern char *queuename __P((ENVELOPE *, int)); -extern void queueup __P((ENVELOPE *, bool)); -extern bool runqueue __P((bool, bool)); -extern void setnewqueue __P((ENVELOPE *)); +extern void queueup __P((ENVELOPE *, bool, bool)); +extern bool runqueue __P((bool, bool, bool, bool)); +extern int run_work_group __P((int, bool, bool, bool, bool)); +extern void set_def_queueval __P((QUEUEGRP *, bool)); +extern void setup_queues __P((bool)); +extern bool setnewqueue __P((ENVELOPE *)); extern bool shouldqueue __P((long, time_t)); extern void sync_queue_time __P((void)); +extern int print_single_queue __P((int, int)); +#if REQUIRES_DIR_FSYNC +# define SYNC_DIR(path, panic) sync_dir(path, panic) +extern void sync_dir __P((char *, bool)); +#else /* REQUIRES_DIR_FSYNC */ +# define SYNC_DIR(path, panic) ((void) 0) +#endif /* REQUIRES_DIR_FSYNC */ /* ** Timeouts @@ -1596,6 +1949,7 @@ EXTERN struct /* following timeouts are not mentioned in RFC 1123 */ time_t to_iconnect; /* initial connection timeout (first try) */ time_t to_connect; /* initial connection timeout (later tries) */ + time_t to_aconnect; /* all connections timeout (MX and A records) */ time_t to_rset; /* RSET command */ time_t to_helo; /* HELO command */ time_t to_quit; /* QUIT command */ @@ -1603,6 +1957,13 @@ EXTERN struct time_t to_ident; /* IDENT protocol requests */ time_t to_fileopen; /* opening :include: and .forward files */ time_t to_control; /* process a control socket command */ + time_t to_lhlo; /* LMTP: LHLO command */ +#if SASL + time_t to_auth; /* AUTH dialogue [10m] */ +#endif /* SASL */ +#if STARTTLS + time_t to_starttls; /* STARTTLS dialogue [10m] */ +#endif /* STARTTLS */ /* following are per message */ time_t to_q_return[MAXTOCLASS]; /* queue return timeouts */ time_t to_q_warning[MAXTOCLASS]; /* queue warning timeouts */ @@ -1624,62 +1985,25 @@ EXTERN struct extern void inittimeouts __P((char *, bool)); /* -** Trace information +** Interface probing */ -/* macros for debugging flags */ -#define tTd(flag, level) (tTdvect[flag] >= (u_char)level) -#define tTdlevel(flag) (tTdvect[flag]) +#define DPI_PROBENONE 0 /* Don't probe any interfaces */ +#define DPI_PROBEALL 1 /* Probe all interfaces */ +#define DPI_SKIPLOOPBACK 2 /* Don't probe loopback interfaces */ -/* variables */ -extern u_char tTdvect[100]; /* trace vector */ -/* -** Critical signal sections +/* +** Trace information */ -#define PEND_SIGHUP 0x0001 -#define PEND_SIGINT 0x0002 -#define PEND_SIGTERM 0x0004 -#define PEND_SIGUSR1 0x0008 - -#define ENTER_CRITICAL() InCriticalSection++ - -#define LEAVE_CRITICAL() \ -do \ -{ \ - if (InCriticalSection > 0) \ - InCriticalSection--; \ -} while (0) - -#define CHECK_CRITICAL(sig) \ -do \ -{ \ - if (InCriticalSection > 0 && (sig) != 0) \ - { \ - pend_signal((sig)); \ - return SIGFUNC_RETURN; \ - } \ -} while (0) - -/* reset signal in case System V semantics */ -#ifdef SYS5SIGNALS -# define FIX_SYSV_SIGNAL(sig, handler) \ -{ \ - if ((sig) != 0) \ - (void) setsignal((sig), (handler)); \ -} -#else /* SYS5SIGNALS */ -# define FIX_SYSV_SIGNAL(sig, handler) { /* EMPTY */ } -#endif /* SYS5SIGNALS */ +/* macros for debugging flags */ +#define tTd(flag, level) (tTdvect[flag] >= (unsigned char)level) +#define tTdlevel(flag) (tTdvect[flag]) /* variables */ -EXTERN u_int volatile InCriticalSection; /* >0 if in a critical section */ -EXTERN int volatile PendingSignal; /* pending signal to resend */ - -/* functions */ -extern void pend_signal __P((int)); +extern unsigned char tTdvect[100]; /* trace vector */ -/* +/* ** Miscellaneous information. */ @@ -1689,6 +2013,10 @@ extern void pend_signal __P((int)); #define NOQID "*~*" +/* use id or NOQID (to avoid NOQUEUE in logfile) */ +#define E_ID(id) ((id) == NULL ? NOQID : (id)) + +#define CURHOSTNAME (CurHostName == NULL ? "local" : CurHostName) /* ** Some in-line functions @@ -1704,25 +2032,59 @@ extern void pend_signal __P((int)); #define newstr(s) strcpy(xalloc(strlen(s) + 1), s) #define STRUCTCOPY(s, d) d = s -/* + +/* free a pointer if it isn't NULL and set it to NULL */ +#define SM_FREE_CLR(p) \ + if ((p) != NULL) \ + { \ + sm_free(p); \ + (p) = NULL; \ + } \ + else + +/* +** Update a permanent string variable with a new value. +** The old value is freed, the new value is strdup'ed. +** +** We use sm_pstrdup_x to duplicate the string because it raises +** an exception on error, and because it allocates "permanent storage" +** which is not expected to be freed before process exit. +** The latter is important for memory leak analysis. +** +** If an exception occurs while strdup'ing the new value, +** then the variable remains set to the old value. +** That's why the strdup must occur before we free the old value. +** +** The macro uses a do loop so that this idiom will work: +** if (...) +** PSTRSET(var, val1); +** else +** PSTRSET(var, val2); +*/ +#define PSTRSET(var, val) \ + do \ + { \ + char *_newval = sm_pstrdup_x(val); \ + if (var != NULL) \ + sm_free(var); \ + var = _newval; \ + } while (0) + +/* ** Global variables. */ EXTERN bool AllowBogusHELO; /* allow syntax errors on HELO command */ -#if !_FFR_REMOVE_AUTOREBUILD -EXTERN bool AutoRebuild; /* auto-rebuild the alias database as needed */ -#endif /* !_FFR_REMOVE_AUTOREBUILD */ EXTERN bool CheckAliases; /* parse addresses during newaliases */ -EXTERN bool ChownAlwaysSafe; /* treat chown(2) as safe */ EXTERN bool ColonOkInAddr; /* single colon legal in address */ +#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) EXTERN bool ConfigFileRead; /* configuration file has been read */ +#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */ EXTERN bool volatile DataProgress; /* have we sent anything since last check */ -EXTERN bool DisConnected; /* running with OutChannel redirected to xf */ -EXTERN bool volatile DoQueueRun; /* non-interrupt time queue run needed */ +EXTERN bool DisConnected; /* running with OutChannel redirect to transcript file */ EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */ EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */ EXTERN bool DontLockReadFiles; /* don't read lock support files */ -EXTERN bool DontProbeInterfaces; /* don't probe interfaces for names */ EXTERN bool DontPruneRoutes; /* don't prune source routes */ EXTERN bool ForkQueueRuns; /* fork for each job when running the queue */ EXTERN bool FromFlag; /* if set, "From" person is explicit */ @@ -1732,42 +2094,46 @@ EXTERN bool HasWildcardMX; /* don't use MX records when canonifying */ EXTERN bool HoldErrs; /* only output errors to transcript */ EXTERN bool IgnoreHostStatus; /* ignore long term host status files */ EXTERN bool IgnrDot; /* don't let dot end messages */ -EXTERN bool InChild; /* true if running in an SMTP subprocess */ EXTERN bool LogUsrErrs; /* syslog user errors (e.g., SMTP RCPT cmd) */ -EXTERN bool MapOpenErr; /* error opening a non-optional map */ EXTERN bool MatchGecos; /* look for user names in gecos field */ EXTERN bool MeToo; /* send to the sender also */ EXTERN bool NoAlias; /* suppress aliasing */ EXTERN bool NoConnect; /* don't connect to non-local mailers */ EXTERN bool OnlyOneError; /* .... or only want to give one SMTP reply */ EXTERN bool QuickAbort; /* .... but only if we want a quick abort */ +EXTERN bool ResNoAliases; /* don't use $HOSTALIASES */ +EXTERN bool volatile RestartWorkGroup; /* daemon needs to restart some work groups */ EXTERN bool RrtImpliesDsn; /* turn Return-Receipt-To: into DSN */ EXTERN bool SaveFrom; /* save leading "From" lines */ EXTERN bool SendMIMEErrors; /* send error messages in MIME format */ EXTERN bool SevenBitInput; /* force 7-bit data on input */ EXTERN bool SingleLineFromHeader; /* force From: header to be one line */ EXTERN bool SingleThreadDelivery; /* single thread hosts on delivery */ +#if _FFR_SOFT_BOUNCE +EXTERN bool SoftBounce; /* replace 5xy by 4xy (for testing) */ +#endif /* _FFR_SOFT_BOUNCE */ EXTERN bool volatile StopRequest; /* stop sending output */ -EXTERN bool SuperSafe; /* be extra careful, even if expensive */ EXTERN bool SuprErrs; /* set if we are suppressing errors */ EXTERN bool TryNullMXList; /* if we are the best MX, try host directly */ -#if _FFR_WORKAROUND_BROKEN_NAMESERVERS +EXTERN bool UseMSP; /* mail submission: group writable queue ok? */ EXTERN bool WorkAroundBrokenAAAA; /* some nameservers return SERVFAIL on AAAA queries */ -#endif /* _FFR_WORKAROUND_BROKEN_NAMESERVERS */ EXTERN bool UseErrorsTo; /* use Errors-To: header (back compat) */ -EXTERN bool UseHesiod; /* using Hesiod -- interpret Hesiod errors */ EXTERN bool UseNameServer; /* using DNS -- interpret h_errno & MX RRs */ EXTERN char InetMode; /* default network for daemon mode */ EXTERN char OpMode; /* operation mode, see below */ EXTERN char SpaceSub; /* substitution for <lwsp> */ +EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */ EXTERN int CheckpointInterval; /* queue file checkpoint interval */ EXTERN int ConfigLevel; /* config file level */ EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */ EXTERN int volatile CurChildren; /* current number of daemonic children */ EXTERN int CurrentLA; /* current load average */ EXTERN int DefaultNotify; /* default DSN notification flags */ +EXTERN int DelayLA; /* load average to delay connections */ +EXTERN int DontProbeInterfaces; /* don't probe interfaces for names */ EXTERN int Errors; /* set if errors (local to single pass) */ EXTERN int ExitStat; /* exit status code */ +EXTERN int FastSplit; /* fast initial splitting of envelopes */ EXTERN int FileMode; /* mode on files */ EXTERN int LineNumber; /* line number in current input */ EXTERN int LogLevel; /* level of logging to perform */ @@ -1777,43 +2143,46 @@ EXTERN int MaxForwardEntries; /* maximum number of forward entries */ EXTERN int MaxHeadersLength; /* max length of headers */ EXTERN int MaxHopCount; /* max # of hops until bounce */ EXTERN int MaxMacroRecursion; /* maximum depth of macro recursion */ -EXTERN int MaxMciCache; /* maximum entries in MCI cache */ EXTERN int MaxMimeFieldLength; /* maximum MIME field length */ EXTERN int MaxMimeHeaderLength; /* maximum MIME header length */ - -EXTERN int MaxQueueRun; /* maximum number of jobs in one queue run */ EXTERN int MaxRcptPerMsg; /* max recipients per SMTP message */ EXTERN int MaxRuleRecursion; /* maximum depth of ruleset recursion */ EXTERN int MimeMode; /* MIME processing mode */ EXTERN int NoRecipientAction; -EXTERN int NumPriorities; /* pointer into Priorities */ -EXTERN u_short PrivacyFlags; /* privacy flags */ -#if _FFR_QUEUE_FILE_MODE -EXTERN int QueueFileMode; /* mode on qf/tf/df files */ -#endif /* _FFR_QUEUE_FILE_MODE */ + +#if SM_CONF_SHM +EXTERN int Numfilesys; /* number of queue file systems */ +EXTERN int *PNumFileSys; +# define NumFileSys (*PNumFileSys) +# else /* SM_CONF_SHM */ +EXTERN int NumFileSys; /* number of queue file systems */ +# endif /* SM_CONF_SHM */ + EXTERN int QueueLA; /* load average starting forced queueing */ -EXTERN int QueueSortOrder; /* queue sorting order algorithm */ -EXTERN int RefuseLA; /* load average refusing connections are */ +EXTERN int RefuseLA; /* load average refusing connections */ +EXTERN int SuperSafe; /* be extra careful, even if expensive */ EXTERN int VendorCode; /* vendor-specific operation enhancements */ EXTERN int Verbose; /* set if blow-by-blow desired */ EXTERN gid_t DefGid; /* default gid to run as */ EXTERN gid_t RealGid; /* real gid of caller */ EXTERN gid_t RunAsGid; /* GID to become for bulk of run */ +EXTERN gid_t EffGid; /* effective gid */ +#if SM_CONF_SHM +EXTERN key_t ShmKey; /* shared memory key */ +#endif /* SM_CONF_SHM */ +EXTERN pid_t CurrentPid; /* current process id */ +EXTERN pid_t DaemonPid; /* process id of daemon */ EXTERN uid_t DefUid; /* default uid to run as */ EXTERN uid_t RealUid; /* real uid of caller */ EXTERN uid_t RunAsUid; /* UID to become for bulk of run */ EXTERN uid_t TrustedUid; /* uid of trusted user for files and startup */ -EXTERN size_t DataFileBufferSize; /* size of buffer for in-core df */ -EXTERN size_t XscriptFileBufferSize; /* size of buffer for in-core xf */ +EXTERN size_t DataFileBufferSize; /* size of buf for in-core data file */ +EXTERN time_t DeliverByMin; /* deliver by minimum time */ EXTERN time_t DialDelay; /* delay between dial-on-demand tries */ -EXTERN time_t MciCacheTimeout; /* maximum idle time on connections */ -EXTERN time_t MciInfoTimeout; /* how long 'til we retry down hosts */ -EXTERN time_t MinQueueAge; /* min delivery interval */ -EXTERN time_t QueueIntvl; /* intervals between running the queue */ EXTERN time_t SafeAlias; /* interval to wait until @:@ in alias file */ EXTERN time_t ServiceCacheMaxAge; /* refresh interval for cache */ -EXTERN time_t ServiceCacheTime; /* time service switch was cached */ +EXTERN size_t XscriptFileBufferSize; /* size of buf for in-core transcript file */ EXTERN MODE_T OldUmask; /* umask when sendmail starts up */ EXTERN long MaxMessageSize; /* advertised max size we will accept */ EXTERN long MinBlocksFree; /* min # of blocks free on queue fs */ @@ -1821,26 +2190,6 @@ EXTERN long QueueFactor; /* slope of queue function */ EXTERN long WkClassFact; /* multiplier for message class -> priority */ EXTERN long WkRecipFact; /* multiplier for # of recipients -> priority */ EXTERN long WkTimeFact; /* priority offset each time this job is run */ -#if SASL -EXTERN char *AuthMechanisms; /* AUTH mechanisms */ -EXTERN char *SASLInfo; /* file with AUTH info */ -#endif /* SASL */ -EXTERN int SASLOpts; /* options for SASL */ -#if STARTTLS -EXTERN char *CACERTpath; /* path to CA certificates (dir. with hashes) */ -EXTERN char *CACERTfile; /* file with CA certificate */ -EXTERN char *SrvCERTfile; /* file with server certificate */ -EXTERN char *Srvkeyfile; /* file with server private key */ -EXTERN char *CltCERTfile; /* file with client certificate */ -EXTERN char *Cltkeyfile; /* file with client private key */ -EXTERN char *DHParams; /* file with DH parameters */ -EXTERN char *RandFile; /* source of random data */ -# if _FFR_TLS_1 -EXTERN char *DHParams5; /* file with DH parameters (512) */ -EXTERN char *CipherList; /* list of ciphers */ -# endif /* _FFR_TLS_1 */ -#endif /* STARTTLS */ -EXTERN char *ConfFile; /* location of configuration file [conf.c] */ EXTERN char *ControlSocketName; /* control socket filename [control.c] */ EXTERN char *CurHostName; /* current host we are dealing with */ EXTERN char *DeadLetterDrop; /* path to dead letter office */ @@ -1854,18 +2203,13 @@ EXTERN char *ForwardPath; /* path to search for .forward files */ EXTERN char *HelpFile; /* location of SMTP help file */ EXTERN char *HostStatDir; /* location of host status information */ EXTERN char *HostsFile; /* path to /etc/hosts file */ +extern char *Mbdb; /* mailbox database type */ EXTERN char *MustQuoteChars; /* quote these characters in phrases */ EXTERN char *MyHostName; /* name of this host for SMTP messages */ EXTERN char *OperatorChars; /* operators (old $o macro) */ EXTERN char *PidFile; /* location of proc id file [conf.c] */ EXTERN char *PostMasterCopy; /* address to get errs cc's */ EXTERN char *ProcTitlePrefix; /* process title prefix */ -EXTERN char *QueueDir; /* location of queue directory */ -#if _FFR_QUEUEDELAY -EXTERN int QueueAlg; /* algorithm for queue delays */ -EXTERN time_t QueueInitDelay; /* initial queue delay */ -EXTERN time_t QueueMaxDelay; /* maximum queue delay */ -#endif /* _FFR_QUEUEDELAY */ EXTERN char *RealHostName; /* name of host we are talking to */ EXTERN char *RealUserName; /* real user name of caller */ EXTERN char *volatile RestartRequest;/* a sendmail restart has been requested */ @@ -1880,70 +2224,30 @@ EXTERN char *StatFile; /* location of statistics summary */ EXTERN char *TimeZoneSpec; /* override time zone specification */ EXTERN char *UdbSpec; /* user database source spec */ EXTERN char *UnixFromLine; /* UNIX From_ line (old $l macro) */ -EXTERN char **ExternalEnviron; /* input environment */ - /* saved user environment */ +EXTERN char **ExternalEnviron; /* saved user (input) environment */ EXTERN char **SaveArgv; /* argument vector for re-execing */ EXTERN BITMAP256 DontBlameSendmail; /* DontBlameSendmail bits */ -#if SFIO -EXTERN Sfio_t *InChannel; /* input connection */ -EXTERN Sfio_t *OutChannel; /* output connection */ -#else /* SFIO */ -EXTERN FILE *InChannel; /* input connection */ -EXTERN FILE *OutChannel; /* output connection */ -#endif /* SFIO */ -EXTERN FILE *TrafficLogFile; /* file in which to log all traffic */ -#ifdef HESIOD +EXTERN SM_FILE_T *InChannel; /* input connection */ +EXTERN SM_FILE_T *OutChannel; /* output connection */ +EXTERN SM_FILE_T *TrafficLogFile; /* file in which to log all traffic */ +#if HESIOD EXTERN void *HesiodContext; #endif /* HESIOD */ EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */ -EXTERN MAILER *LocalMailer; /* ptr to local mailer */ -EXTERN MAILER *ProgMailer; /* ptr to program mailer */ -EXTERN MAILER *FileMailer; /* ptr to *file* mailer */ -EXTERN MAILER *InclMailer; /* ptr to *include* mailer */ -EXTERN QUEUE_CHAR *QueueLimitRecipient; /* limit queue run to rcpt */ -EXTERN QUEUE_CHAR *QueueLimitSender; /* limit queue run to sender */ -EXTERN QUEUE_CHAR *QueueLimitId; /* limit queue run to id */ -EXTERN MAILER *Mailer[MAXMAILERS + 1]; -EXTERN struct rewrite *RewriteRules[MAXRWSETS]; EXTERN char *RuleSetNames[MAXRWSETS]; /* ruleset number to name */ EXTERN char *UserEnviron[MAXUSERENVIRON + 1]; -EXTERN struct priority Priorities[MAXPRIORITIES]; +EXTERN struct rewrite *RewriteRules[MAXRWSETS]; EXTERN struct termescape TermEscape; /* terminal escape codes */ EXTERN SOCKADDR ConnectOnlyTo; /* override connection address (for testing) */ EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */ -EXTERN jmp_buf TopFrame; /* branch-to-top-of-loop-on-error frame */ -EXTERN TIMERS Timers; +extern const SM_EXC_TYPE_T EtypeQuickAbort; /* type of a QuickAbort exception */ + + /* ** Declarations of useful functions */ -#if SASL -extern char *intersect __P((char *, char *)); -extern char *iteminlist __P((char *, char *, char *)); -extern int proxy_policy __P((void *, const char *, const char *, const char **, const char **)); -# if SASL > 10515 -extern int safesaslfile __P((void *, char *, int)); -# else /* SASL > 10515 */ -extern int safesaslfile __P((void *, char *)); -# endif /* SASL > 10515 */ -extern int sasl_decode64 __P((const char *, unsigned, char *, unsigned *)); -extern int sasl_encode64 __P((const char *, unsigned, char *, unsigned, unsigned *)); -#endif /* SASL */ - -#if STARTTLS -extern void apps_ssl_info_cb __P((SSL *, int , int)); -extern bool init_tls_library __P((void)); -extern bool inittls __P((SSL_CTX **, u_long, bool, char *, char *, char *, char *, char *)); -extern bool initclttls __P((void)); -extern bool initsrvtls __P((void)); -extern int tls_get_info __P((SSL *, ENVELOPE *, bool, char *, bool)); -extern int endtls __P((SSL *, char *)); -extern int endtlsclt __P((MCI *)); -extern void tlslogerr __P((void)); -extern bool tls_rand_init __P((char *, int)); -#endif /* STARTTLS */ - /* Transcript file */ extern void closexscript __P((ENVELOPE *)); extern void openxscript __P((ENVELOPE *)); @@ -1951,11 +2255,11 @@ extern void openxscript __P((ENVELOPE *)); /* error related */ extern void buffer_errors __P((void)); extern void flush_errors __P((bool)); -extern void message __P((const char *, ...)); -extern void nmessage __P((const char *, ...)); -extern void syserr __P((const char *, ...)); -extern void usrerrenh __P((char *, const char *, ...)); -extern void usrerr __P((const char *, ...)); +extern void PRINTFLIKE(1, 2) message __P((const char *, ...)); +extern void PRINTFLIKE(1, 2) nmessage __P((const char *, ...)); +extern void PRINTFLIKE(1, 2) syserr __P((const char *, ...)); +extern void PRINTFLIKE(2, 3) usrerrenh __P((char *, const char *, ...)); +extern void PRINTFLIKE(1, 2) usrerr __P((const char *, ...)); extern int isenhsc __P((const char *, int)); extern int extenhsc __P((const char *, int, char *)); @@ -1963,23 +2267,23 @@ extern int extenhsc __P((const char *, int, char *)); extern void alias __P((ADDRESS *, ADDRESS **, int, ENVELOPE *)); extern bool aliaswait __P((MAP *, char *, bool)); extern void forward __P((ADDRESS *, ADDRESS **, int, ENVELOPE *)); -extern void readaliases __P((MAP *, FILE *, bool, bool)); +extern void readaliases __P((MAP *, SM_FILE_T *, bool, bool)); extern bool rebuildaliases __P((MAP *, bool)); extern void setalias __P((char *)); /* logging */ extern void logdelivery __P((MAILER *, MCI *, char *, const char *, ADDRESS *, time_t, ENVELOPE *)); extern void logsender __P((ENVELOPE *, char *)); -extern void sm_syslog __P((int, const char *, const char *, ...)); +extern void PRINTFLIKE(3, 4) sm_syslog __P((int, const char *, const char *, ...)); /* SMTP */ -extern void giveresponse __P((int, char *, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *)); +extern void giveresponse __P((int, char *, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *, ADDRESS *)); extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)(), char **)); extern void smtp __P((char *volatile, BITMAP256, ENVELOPE *volatile)); #if SASL extern int smtpauth __P((MAILER *, MCI *, ENVELOPE *)); #endif /* SASL */ -extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *)); +extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *, ADDRESS *, time_t)); extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *)); extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *)); extern void smtpmessage __P((char *, MAILER *, MCI *, ...)); @@ -1987,7 +2291,7 @@ extern void smtpinit __P((MAILER *, MCI *, ENVELOPE *, bool)); extern char *smtptodsn __P((int)); extern int smtpprobe __P((MCI *)); extern void smtpquit __P((MAILER *, MCI *, ENVELOPE *)); -extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *)); +extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *, ADDRESS *, time_t)); extern void smtprset __P((MAILER *, MCI *, ENVELOPE *)); #define ISSMTPCODE(c) (isascii(c[0]) && isdigit(c[0]) && \ @@ -1997,13 +2301,20 @@ extern void smtprset __P((MAILER *, MCI *, ENVELOPE *)); (c[3] == ' ' || c[3] == '-' || c[3] == '\0')) /* delivery */ -extern pid_t dowork __P((int, char *, bool, bool, ENVELOPE *)); +extern pid_t dowork __P((int, int, char *, bool, bool, ENVELOPE *)); +extern pid_t doworklist __P((ENVELOPE *, bool, bool)); extern int endmailer __P((MCI *, ENVELOPE *, char **)); extern int mailfile __P((char *volatile, MAILER *volatile, ADDRESS *, volatile long, ENVELOPE *)); extern void sendall __P((ENVELOPE *, int)); /* stats */ -extern void markstats __P((ENVELOPE *, ADDRESS *, bool)); +#define STATS_NORMAL 'n' +#if _FFR_QUARANTINE +# define STATS_QUARANTINE 'q' +#endif /* _FFR_QUARANTINE */ +#define STATS_REJECT 'r' + +extern void markstats __P((ENVELOPE *, ADDRESS *, int)); extern void clearstats __P((void)); extern void poststats __P((char *)); @@ -2013,13 +2324,13 @@ extern void clrcontrol __P((void)); extern void control_command __P((int, ENVELOPE *)); extern int opencontrolsocket __P((void)); -#if _FFR_MILTER +#if MILTER /* milter functions */ -extern void milter_parse_list __P((char *, struct milter **, int)); +extern void milter_config __P((char *, struct milter **, int)); extern void milter_setup __P((char *)); extern void milter_set_option __P((char *, char *, bool)); extern bool milter_can_delrcpts __P((void)); -extern void milter_init __P((ENVELOPE *, char *)); +extern bool milter_init __P((ENVELOPE *, char *)); extern void milter_quit __P((ENVELOPE *)); extern void milter_abort __P((ENVELOPE *)); extern char *milter_connect __P((char *, SOCKADDR, ENVELOPE *, char *)); @@ -2027,10 +2338,9 @@ extern char *milter_helo __P((char *, ENVELOPE *, char *)); extern char *milter_envfrom __P((char **, ENVELOPE *, char *)); extern char *milter_envrcpt __P((char **, ENVELOPE *, char *)); extern char *milter_data __P((ENVELOPE *, char *)); -#endif /* _FFR_MILTER */ +#endif /* MILTER */ -extern char *addquotes __P((char *)); -extern void allsignals __P((bool)); +extern char *addquotes __P((char *, SM_RPOOL_T *)); extern char *arpadate __P((char *)); extern bool atobool __P((char *)); extern int atooct __P((char *)); @@ -2038,7 +2348,10 @@ extern void auth_warning __P((ENVELOPE *, const char *, ...)); extern int blocksignal __P((int)); extern bool bitintersect __P((BITMAP256, BITMAP256)); extern bool bitzerop __P((BITMAP256)); +extern int check_bodytype __P((char *)); extern void buildfname __P((char *, char *, char *, int)); +extern bool chkclientmodifiers __P((int)); +extern bool chkdaemonmodifiers __P((int)); extern int checkcompat __P((ADDRESS *, ENVELOPE *)); #ifdef XDEBUG extern void checkfd012 __P((char *)); @@ -2047,40 +2360,45 @@ extern void checkfdopen __P((int, char *)); extern void checkfds __P((char *)); extern bool chownsafe __P((int, bool)); extern void cleanstrcpy __P((char *, char *, int)); +#if SM_CONF_SHM +extern void cleanup_shm __P((bool)); +#endif /* SM_CONF_SHM */ extern void clrdaemon __P((void)); -extern void collect __P((FILE *, bool, HDR **, ENVELOPE *)); +extern void collect __P((SM_FILE_T *, bool, HDR **, ENVELOPE *)); extern time_t convtime __P((char *, int)); -extern char **copyplist __P((char **, bool)); +extern char **copyplist __P((char **, bool, SM_RPOOL_T *)); extern void copy_class __P((int, int)); extern time_t curtime __P((void)); extern char *defcharset __P((ENVELOPE *)); extern char *denlstring __P((char *, bool, bool)); extern void disconnect __P((int, ENVELOPE *)); -extern bool dns_getcanonname __P((char *, int, bool, int *)); +#if _FFR_CONTROL_MSTAT +extern void disk_status __P((SM_FILE_T *, char *)); +#endif /* _FFR_CONTROL_MSTAT */ +extern bool dns_getcanonname __P((char *, int, bool, int *, int *)); extern pid_t dofork __P((void)); extern int drop_privileges __P((bool)); extern int dsntoexitstat __P((char *)); extern void dumpfd __P((int, bool, bool)); extern void dumpstate __P((char *)); -extern bool enoughdiskspace __P((long, bool)); +extern bool enoughdiskspace __P((long, ENVELOPE *)); extern char *exitstat __P((char *)); -extern char *fgetfolded __P((char *, int, FILE *)); +extern void fatal_error __P((SM_EXC_T *)); +extern char *fgetfolded __P((char *, int, SM_FILE_T *)); extern void fill_fd __P((int, char *)); extern char *find_character __P((char *, int)); -extern struct passwd *finduser __P((char *, bool *)); -extern void finis __P((bool, volatile int)); +extern int finduser __P((char *, bool *, SM_MBDB_T *)); +extern void finis __P((bool, bool, volatile int)); extern void fixcrlf __P((char *, bool)); extern long freediskspace __P((char *, long *)); #if NETINET6 && NEEDSGETIPNODE -# if _FFR_FREEHOSTENT extern void freehostent __P((struct hostent *)); -# endif /* _FFR_FREEHOSTENT */ -#endif /* NEEDSGETIPNODE && NETINET6 */ +#endif /* NETINET6 && NEEDSGETIPNODE */ extern char *get_column __P((char *, int, int, char *, int)); extern char *getauthinfo __P((int, bool *)); -extern char *getcfname __P((void)); -extern char *getextenv __P((const char *)); extern int getdtsize __P((void)); +extern int getla __P((void)); +extern char *getmodifiers __P((char *, BITMAP256)); extern BITMAP256 *getrequests __P((ENVELOPE *)); extern char *getvendor __P((int)); extern void help __P((char *, ENVELOPE *)); @@ -2095,31 +2413,37 @@ extern bool isloopback __P((SOCKADDR sa)); extern void load_if_names __P((void)); extern bool lockfile __P((int, char *, char *, int)); extern void log_sendmail_pid __P((ENVELOPE *)); +extern void logundelrcpts __P((ENVELOPE *, char *, int, bool)); extern char lower __P((int)); extern void makelower __P((char *)); extern int makeconnection_ds __P((char *, MCI *)); -extern int makeconnection __P((char *, volatile u_int, MCI *, ENVELOPE *)); +extern int makeconnection __P((char *, volatile unsigned int, MCI *, ENVELOPE *, time_t)); +extern void makeworkgroups __P((void)); +extern void mark_work_group_restart __P((int, int)); extern char * munchstring __P((char *, char **, int)); extern struct hostent *myhostname __P((char *, int)); extern char *nisplus_default_domain __P((void)); /* extern for Sun */ extern bool path_is_dir __P((char *, bool)); +extern int pickqdir __P((QUEUEGRP *qg, long fsize, ENVELOPE *e)); extern char *pintvl __P((time_t, bool)); extern void printav __P((char **)); extern void printmailer __P((MAILER *)); +extern void printnqe __P((SM_FILE_T *, char *)); extern void printopenfds __P((bool)); extern void printqueue __P((void)); extern void printrules __P((void)); extern pid_t prog_open __P((char **, int *, ENVELOPE *)); extern void putline __P((char *, MCI *)); extern void putxline __P((char *, size_t, MCI *, int)); -extern void queueup_macros __P((int, FILE *, ENVELOPE *)); +extern void queueup_macros __P((int, SM_FILE_T *, ENVELOPE *)); extern void readcf __P((char *, bool, ENVELOPE *)); extern SIGFUNC_DECL reapchild __P((int)); extern int releasesignal __P((int)); extern void resetlimits __P((void)); +extern void restart_daemon __P((void)); +extern void restart_marked_work_groups __P(()); extern bool rfc822_string __P((char *)); -extern FILE *safefopen __P((char *, int, int, long)); -extern void savemail __P((ENVELOPE *, bool)); +extern bool savemail __P((ENVELOPE *, bool)); extern void seed_random __P((void)); extern void sendtoargv __P((char **, ENVELOPE *)); extern void setclientoptions __P((char *)); @@ -2127,49 +2451,66 @@ extern bool setdaemonoptions __P((char *)); extern void setdefaults __P((ENVELOPE *)); extern void setdefuser __P((void)); extern bool setvendor __P((char *)); +extern void set_op_mode __P((int)); extern void setoption __P((int, char *, bool, bool, ENVELOPE *)); extern sigfunc_t setsignal __P((int, sigfunc_t)); extern void setuserenv __P((const char *, const char *)); extern void settime __P((ENVELOPE *)); -extern char *sfgets __P((char *, int, FILE *, time_t, char *)); -extern char *shortenstring __P((const char *, int)); +extern char *sfgets __P((char *, int, SM_FILE_T *, time_t, char *)); +extern char *shortenstring __P((const char *, size_t)); extern char *shorten_hostname __P((char [])); extern bool shorten_rfc822_string __P((char *, size_t)); extern void shutdown_daemon __P((void)); -extern void sm_dopr __P((char *, const char *, va_list)); -extern void sm_free __P((void *)); extern struct hostent *sm_gethostbyname __P((char *, int)); extern struct hostent *sm_gethostbyaddr __P((char *, int, int)); -extern int sm_getla __P((ENVELOPE *)); +extern void sm_getla __P((void)); extern struct passwd *sm_getpwnam __P((char *)); extern struct passwd *sm_getpwuid __P((UID_T)); extern void sm_setproctitle __P((bool, ENVELOPE *, const char *, ...)); -extern SIGFUNC_DECL sm_signal_noop __P((int)); -extern int sm_strcasecmp __P((const char *, const char *)); +extern pid_t sm_wait __P((int *)); +extern bool split_by_recipient __P((ENVELOPE *e)); extern void stop_sendmail __P((void)); -extern bool strcontainedin __P((char *, char *)); -extern void stripquotes __P((char *)); +extern char *str2prt __P((char *)); +extern bool strcontainedin __P((bool, char *, char *)); extern int switch_map_find __P((char *, char *[], short [])); extern bool transienterror __P((int)); +#if _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI +extern void truncate_at_delim __P((char *, size_t, int)); +#endif /* _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI */ extern void tTflag __P((char *)); -extern void tTsetup __P((u_char *, int, char *)); +extern void tTsetup __P((unsigned char *, unsigned int, char *)); +extern SIGFUNC_DECL tick __P((int)); extern char *ttypath __P((void)); extern void unlockqueue __P((ENVELOPE *)); #if !HASUNSETENV extern void unsetenv __P((char *)); #endif /* !HASUNSETENV */ + +/* update file system information: +/- some blocks */ +#if SM_CONF_SHM +extern void upd_qs __P((ENVELOPE *, bool, bool)); +# define updfs(e, delete, avail) upd_qs(e, delete, avail) +#else /* SM_CONF_SHM */ +# define updfs(e, delete, avail) +#endif /* SM_CONF_SHM */ + extern char *username __P((void)); extern bool usershellok __P((char *, char *)); extern void vendor_post_defaults __P((ENVELOPE *)); extern void vendor_pre_defaults __P((ENVELOPE *)); extern int waitfor __P((pid_t)); extern bool writable __P((char *, ADDRESS *, long)); -extern char *xalloc __P((int)); -extern char *xcalloc __P((size_t, size_t)); -extern char *xrealloc __P((void *, size_t)); +#if SM_HEAP_CHECK +# define xalloc(size) xalloc_tagged(size, __FILE__, __LINE__) +extern char *xalloc_tagged __P((int, char*, int)); +#else /* SM_HEAP_CHECK */ +extern char *xalloc __P((int)); +#endif /* SM_HEAP_CHECK */ extern void xputs __P((const char *)); extern char *xtextify __P((char *, char *)); extern bool xtextok __P((char *)); -extern void xunlink __P((char *)); +extern int xunlink __P((char *)); extern char *xuntextify __P((char *)); -#endif /* _SENDMAIL_H */ + + +#endif /* ! _SENDMAIL_H */ |