mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-27 11:55:06 +00:00
Merge commit '850ef5ae11d69ea3381bd310f564f025fc8caea3'
Merge vendor sendmail 8.18.1 into HEAD
This commit is contained in:
commit
d39bd2c138
@ -25,7 +25,7 @@ This list is not guaranteed to be complete.
|
||||
For Linux the default is to use fcntl() for file locking. However,
|
||||
this does not work with Berkeley DB 5.x and probably later.
|
||||
Switching to flock(), i.e., compile with -DHASFLOCK fixes this
|
||||
(however, the have been problems with flock() on some Linux
|
||||
(however, there have been problems with flock() on some Linux
|
||||
versions). Alternatively, use CDB or an earlier BDB version.
|
||||
|
||||
* Delivery to programs that generate too much output may cause problems
|
||||
@ -105,11 +105,6 @@ Kresolve sequence dnsmx canon
|
||||
DSN does not contain the illegal address, but only the valid
|
||||
address(es).
|
||||
|
||||
* \231 considered harmful.
|
||||
|
||||
Header addresses that have the \231 character (and possibly others
|
||||
in the range \201 - \237) behave in odd and usually unexpected ways.
|
||||
|
||||
* AuthRealm for Cyrus SASL may not work as expected. The man page
|
||||
and the actual usage for sasl_server_new() seem to differ.
|
||||
Feedback for the "correct" usage is welcome, a patch to match
|
||||
@ -178,11 +173,11 @@ Kresolve sequence dnsmx canon
|
||||
|
||||
* Client ignores SIZE parameter.
|
||||
|
||||
When sendmail acts as client and the server specifies a limit
|
||||
for the mail size, sendmail will ignore this and try to send the
|
||||
mail anyway. The server will usually reject the MAIL command
|
||||
which specifies the size of the message and hence this problem
|
||||
is not significant.
|
||||
When sendmail acts as client and the server specifies a limit for
|
||||
the mail size, sendmail will ignore this and try to send the mail
|
||||
anyway (unless _FFR_CLIENT_SIZE is used). The server will usually
|
||||
reject the MAIL command which specifies the size of the message
|
||||
and hence this problem is not significant.
|
||||
|
||||
* Paths to programs being executed and the mode of program files are
|
||||
not checked. Essentially, the RunProgramInUnsafeDirPath and
|
||||
|
@ -187,6 +187,625 @@ mk6wxhyuojEHuR7it6IU5BP8vaAGrL1jb1c2EeAe+pdJwpAb1Aq6MU6uWqOGup8t
|
||||
=xY3m
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub rsa4096/0xC4065A87C71F6844 2024-01-02 [SC]
|
||||
Key fingerprint = 8AB0 63D7 A4C5 939D A9C0 1E38 C406 5A87 C71F 6844
|
||||
uid [ultimate] Sendmail Signing Key/2024 <sendmail@Sendmail.ORG>
|
||||
sub rsa4096/0x8DBCFBC42AF9E161 2024-01-02 [E]
|
||||
Key fingerprint = 2B52 755B 17D4 44EB EC39 5497 8DBC FBC4 2AF9 E161
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
=2S83
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub rsa4096/0xCFF9F96740ED9550 2023-01-12 [SC]
|
||||
Key fingerprint = 8186 4A03 75F2 7810 64FE 8E4D CFF9 F967 40ED 9550
|
||||
uid [ full ] Sendmail Signing Key/2023 <sendmail@Sendmail.ORG>
|
||||
sub rsa4096/0x592DCD45F765BAB2 2023-01-12 [E]
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
kYi0
|
||||
=c0eH
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub 4096R/81D9210A 2022-01-22
|
||||
Key fingerprint = 6327 DDCB 5E7E 80E4 987E A3B7 FD79 DC0C 81D9 210A
|
||||
uid Sendmail Signing Key/2022 <sendmail@Sendmail.ORG>
|
||||
sub 4096R/03142938 2022-01-22
|
||||
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
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
|
||||
0Kb4rGd12E5b+czXoxg=
|
||||
=LSBA
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
pub 4096R/4BEE1BEE 2021-01-24
|
||||
Key fingerprint = F4CE 2263 2102 53D6 A9F9 79B0 4C66 EA8D 4BEE 1BEE
|
||||
@ -363,7 +982,6 @@ ra/bqVWSpZTlHZ0xT9seCUSs1urxGw9Z
|
||||
=3HCo
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub rsa4096/0xD583210EF51471A7 2020-04-08 [SC]
|
||||
Key fingerprint = ADFD B709 FE1E A682 E585 5971 D583 210E F514 71A7
|
||||
uid [ full ] Sendmail Signing Key/2020 <sendmail@Sendmail.ORG>
|
||||
@ -557,7 +1175,6 @@ gmOJ78JKVfONBpmdVsw/emTMU5I/C/8m9l0nO0P4Q6diao23krgWk73x7dBoBqDn
|
||||
=jgHV
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub rsa4096/0x09E01FA03C0C504E 2019-01-09 [SC]
|
||||
Key fingerprint = 50A3 0309 8EA2 DD7B CBEE 2ADA 09E0 1FA0 3C0C 504E
|
||||
uid Sendmail Signing Key/2019 <sendmail@Sendmail.ORG>
|
||||
@ -739,7 +1356,6 @@ HcRQfq7rqZkS3NE+iD9D/lUyXVYfH9A=
|
||||
=jN/3
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub 4096R/0xF06059FD5DC7CC3F 2018-04-24 [SC]
|
||||
Key fingerprint = A687 3D24 A4D6 D628 4AE4 2A75 F060 59FD 5DC7 CC3F
|
||||
uid Sendmail Signing Key/2018 <sendmail@Sendmail.ORG>
|
||||
@ -883,7 +1499,6 @@ fvZ+LS/6hJ9C77uOaBqoDPmtpn0WDqc3oDeT81Ans73BZhwhFAjzpHp+XnJQ
|
||||
=K0Kz
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub 4096R/6BF726AD 2016-12-31
|
||||
Key fingerprint = 3C8A 1E8E 7F44 CADE 114F ED46 4BC9 BDA6 6BF7 26AD
|
||||
uid Sendmail Signing Key/2017 <sendmail@Sendmail.ORG>
|
||||
@ -1069,7 +1684,6 @@ FtJxkIHVIx/VvvBqS3HEm8QCRvr+o10/Ue7NljolDV13B7fljxgvLFyJ8T91jWsz
|
||||
=Lt+h
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub 2048R/29FB03DE 2016-01-04
|
||||
fingerprint: 0F5C 96AE C8E6 9E9C 8E54 2E5C 6D4C D194 29FB 03DE
|
||||
uid Sendmail Signing Key/2016 <sendmail@Sendmail.ORG>
|
||||
@ -1269,7 +1883,6 @@ j68I
|
||||
=MdUt
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
|
||||
pub 2048R/0xAAF5B5DE05BDCC53 2015-01-02
|
||||
fingerprint: 30BC A747 05FA 4154 5573 1D7B AAF5 B5DE 05BD CC53
|
||||
uid Sendmail Signing Key/2015 <sendmail@Sendmail.ORG>
|
||||
|
@ -4,11 +4,12 @@
|
||||
This directory has the latest sendmail(TM) software from Proofpoint, Inc.
|
||||
|
||||
Report any bugs to sendmail-bugs-YYYY@support.sendmail.org
|
||||
where YYYY is the current year, e.g., 2005.
|
||||
where YYYY is the current year, e.g., 2023.
|
||||
|
||||
There is a web site at http://www.sendmail.org/ -- see that site for
|
||||
There is a web site at https://www.sendmail.org/ -- see that site for
|
||||
the latest updates.
|
||||
|
||||
|
||||
+--------------+
|
||||
| INTRODUCTION |
|
||||
+--------------+
|
||||
@ -40,6 +41,7 @@ the latest updates.
|
||||
Sendmail is a trademark of Proofpoint, Inc.
|
||||
US Patent Numbers 6865671, 6986037.
|
||||
|
||||
|
||||
+-----------------------+
|
||||
| DIRECTORY PERMISSIONS |
|
||||
+-----------------------+
|
||||
@ -197,14 +199,6 @@ There are other files you should read. Rooted in this directory are:
|
||||
|
||||
This sets a word in a smaller pointsize.
|
||||
|
||||
- with new groff versions (1.18 seems affected)
|
||||
|
||||
GROFF_NO_SGR=1
|
||||
|
||||
needs to be set, e.g., in doc/op/Makefile:
|
||||
|
||||
ROFF_CMD= GROFF_NO_SGR=1 groff
|
||||
|
||||
|
||||
+--------------+
|
||||
| RELATED RFCS |
|
||||
@ -248,6 +242,13 @@ Important RFCs for electronic mail are:
|
||||
RFC2822 Internet Message Format
|
||||
RFC2852 Deliver By SMTP Service Extension
|
||||
RFC2920 SMTP Service Extension for Command Pipelining
|
||||
RFC5321 Simple Mail Transfer Protocol
|
||||
RFC5322 Internet Message Format
|
||||
RFC6530 Overview and Framework for Internationalized Email
|
||||
RFC6531 SMTP Extension for Internationalized Email
|
||||
RFC6532 Internationalized Email Headers
|
||||
RFC6533 Internationalized Delivery Status and Disposition Notifications
|
||||
RFC8461 SMTP MTA Strict Transport Security (MTA-STS)
|
||||
|
||||
Other standards that may be of interest (but which are less directly
|
||||
relevant to sendmail) are:
|
||||
@ -325,6 +326,10 @@ DB 2.X and 3.X. If you are upgrading from one of those versions, you must
|
||||
recreate your database file(s). Do this by rebuilding all maps with
|
||||
makemap and rebuilding the alias file with newaliases.
|
||||
|
||||
File locking using fcntl() does not interoperate with Berkeley DB
|
||||
5.x (and probably later). Use CDB, flock() (-DHASFLOCK), or an
|
||||
earlier Berkeley DB version.
|
||||
|
||||
|
||||
+--------------------+
|
||||
| HOST NAME SERVICES |
|
||||
@ -391,6 +396,7 @@ CommuniGate Pro
|
||||
in .mc file if you have compiled sendmail with Cyrus SASL
|
||||
and you communicate with CommuniGate Pro servers.
|
||||
|
||||
|
||||
+---------------------+
|
||||
| DIRECTORY STRUCTURE |
|
||||
+---------------------+
|
||||
|
@ -5,6 +5,187 @@ This listing shows the version of the sendmail binary, the version
|
||||
of the sendmail configuration files, the date of release, and a
|
||||
summary of the changes in that release.
|
||||
|
||||
|
||||
8.18.1/8.18.1 2024/01/31
|
||||
sendmail is now stricter in following the RFCs and rejects
|
||||
some invalid input with respect to line endings
|
||||
and pipelining:
|
||||
- Prevent transaction stuffing by ensuring SMTP clients
|
||||
wait for the HELO/EHLO and DATA response before sending
|
||||
further SMTP commands. This can be disabled using
|
||||
the new srv_features option 'F'. Issue reported by
|
||||
Yepeng Pan and Christian Rossow from CISPA Helmholtz
|
||||
Center for Information Security.
|
||||
- Accept only CRLF . CRLF as end of an SMTP message
|
||||
as required by the RFCs, which can disabled by the
|
||||
new srv_features option 'O'.
|
||||
- Do not accept a CR or LF except in the combination
|
||||
CRLF (as required by the RFCs). These checks can
|
||||
be disabled by the new srv_features options
|
||||
'U' and 'G', respectively. In this case it is
|
||||
suggested to use 'u2' and 'g2' instead so the server
|
||||
replaces offending bare CR or bare LF with a space.
|
||||
It is recommended to only turn these protections off
|
||||
for trusted networks due to the potential for abuse.
|
||||
Full DANE support is available if OpenSSL versions 1.1.1 or 3.x
|
||||
are used, i.e., TLSA RR 2-x-y and 3-x-y are supported
|
||||
as required by RFC 7672.
|
||||
OpenSSL version 3.0.x is supported. Note: OpenSSL 3 loads by
|
||||
default an openssl.cnf file from a location specified
|
||||
in the library which may cause unwanted behaviour
|
||||
in sendmail. Hence sendmail sets the environment
|
||||
variable OPENSSL_CONF to /etc/mail/sendmail.ossl
|
||||
to override the default. The file name can be
|
||||
changed by defining confOPENSSL_CNF in the mc file;
|
||||
using an empty value prevents setting OPENSSL_CONF.
|
||||
Note: referring to a file which does not exist does
|
||||
not cause an an error.
|
||||
Two new values have been added for {verify}:
|
||||
"DANE_TEMP": DANE verification failed temporarily.
|
||||
"DANE_NOTLS": DANE was required but STARTTLS was not
|
||||
offered by the server.
|
||||
The default rules return a temporary error for these
|
||||
cases, so delivery is not attempted.
|
||||
If the TLS setup code in the client fails and DANE requirements
|
||||
exist then {verify} will be set to "DANE_TEMP" thus
|
||||
preventing delivery by default.
|
||||
DANE related logging has been slightly changed for clarification:
|
||||
"DANE configured in DNS but no STARTTLS available"
|
||||
changed to
|
||||
"DANE configured in DNS but STARTTLS not offered"
|
||||
When the compile time option USE_EAI is enabled, vacation could
|
||||
fail to respond when it should (the code change in
|
||||
8.17.2 was incomplete). Problem reported by Alex
|
||||
Hautequest.
|
||||
If SMTPUTF8 BODY=7BIT are used as parameters for the MAIL command
|
||||
the parsing of UTF8 addresses could fail (USE_EAI).
|
||||
If a reply to a previous RCPT was received while sending
|
||||
another RCPT in pipelining mode then parts of the
|
||||
reply could have been assigned to the wrong RCPT.
|
||||
New DontBlameSendmail option CertOwner to relax requirement
|
||||
for certificate public and private key ownership.
|
||||
Based on suggestion from Marius Strobl of the
|
||||
FreeBSD project.
|
||||
clt_features was not checked for connections via Unix domain
|
||||
sockets.
|
||||
CONFIG: FEATURE(`enhdnsbl') did not handle multiple replies
|
||||
from DNS lookups thus potentially causing random
|
||||
"false negatives".
|
||||
Note: the fix creates an incompatibility:
|
||||
the arguments must not have a trailing dot anymore
|
||||
because the -a. option has been removed (as it only
|
||||
applies to the entire result, not individual values).
|
||||
CONFIG: New FEATURE(`fips3') for basic FIPS support in OpenSSL 3.
|
||||
VACATION: Add support for Return-Path header to set sender
|
||||
to match OpenBSD and NetBSD functionality.
|
||||
VACATION: Honor RFC3834 and avoid an auto-reply if
|
||||
'Auto-Submitted: no' is found in the headers to
|
||||
match OpenBSD and NetBSD functionality.
|
||||
VACATION: Avoid an auto-reply if a 'List-Id:' is found in
|
||||
the headers to match OpenBSD functionality.
|
||||
VACATION: Add support for $SUBJECT in .vacation.msg which
|
||||
is replaced with the first line of the subject of the
|
||||
original message to match OpenBSD and NetBSD
|
||||
functionality.
|
||||
Portability:
|
||||
Add support for Darwin 23.
|
||||
New Files:
|
||||
cf/feature/fips3.m4
|
||||
devtools/OS/Darwin.23.x
|
||||
|
||||
8.17.2/8.17.2 2023/06/03
|
||||
Make sure DANE checks (if enabled) are performed even if
|
||||
CACertPath or CACertFile are not set or unusable.
|
||||
Note: if the code to set up TLS in the client fails, then
|
||||
{verify} will be set to TEMP but DANE requirements
|
||||
will be ignored, i.e., by default mail will be sent
|
||||
without STARTTLS. This can be changed via a
|
||||
LOCAL_TLS_SERVER ruleset.
|
||||
Pass server name to clt_features ruleset instead of client
|
||||
name to account for limitations in macro availability
|
||||
described below in CONFIG section. This may break
|
||||
custom clt_features rulesets which expect to receive
|
||||
the client name as input.
|
||||
Fix a regression introduced in 8.17.1: aliases file which
|
||||
contain continuation lines caused parsing errors.
|
||||
Add an FFR (for future release) compile time option _FFR_LOG_STAGE
|
||||
to log the protocol stage as stage= for some errors during
|
||||
delivery attempts to make troubleshooting simpler. This
|
||||
new logging may be enabled in a future release.
|
||||
When EAI is enabled, milters also got the arguments of MAIL/RCPT
|
||||
commands in argv[0] for xxfi_envfrom()/xxfi_envrcpt()
|
||||
callbacks instead of just the mail address.
|
||||
Problem reported by Dilyan Palauzo.
|
||||
When EAI is enabled, mailq prints UTF-8 addresses as such
|
||||
if SMTPUTF8 was used.
|
||||
When EAI is enabled, the $h macro is now in the correct format.
|
||||
Previously this could cause wrong values for relay=
|
||||
in log entries and the mailer argument vector.
|
||||
When the compile time option USE_EAI is enabled, vacation could
|
||||
fail to respond when it should. Problem reported by
|
||||
Alex Hautequest.
|
||||
When EAI was enabled, header truncation might not have been
|
||||
logged even when it happened. Problem reported by
|
||||
Werner Wiethege.
|
||||
Handle a possible change in an upcoming release of Cyrus-SASL
|
||||
(2.1.28) by changing the definition of an internal flag.
|
||||
Patch from Dilyan Palauzo.
|
||||
Avoid an assertion failure when an smtps connection is made
|
||||
to the server and a milter is unavailable.
|
||||
Problem reported by Dilyan Palauzo.
|
||||
Fixed some spelling errors in documentation and comments,
|
||||
based on a codespell report by Jens Schleusener
|
||||
of fossies.org.
|
||||
The result of try_tls is now logged using status= instead
|
||||
of reject=.
|
||||
If tls_rcpt rejected the delivery of a recipient then a bogus
|
||||
dsn= entry might have been logged under some circumstances.
|
||||
If a server replied with 421 to a RCPT command then a bogus reply=
|
||||
might have been logged.
|
||||
When quoting the value for ${currHeader} avoid causing a syntax
|
||||
error (Unbalanced '"') when truncating a header value
|
||||
which is too long. Problem reported by Werner Wiethege.
|
||||
Reduce the performance impact of a change introduced in
|
||||
8.12.9: the default for MaxMimeHeaderLength was
|
||||
set to 2048/1024. Problem reported by Tabata
|
||||
Shintaro of Internet Initiative Japan Inc.
|
||||
CONFIG: The default clt_features ruleset tried to access
|
||||
${server_name} and ${server_addr} which are not set
|
||||
when the ruleset is invoked. Only the server name
|
||||
is available which is passed as an argument.
|
||||
CONFIG: Properly quote host variable to prevent cf build
|
||||
breakage when a hostname contains 'dnl'. Problem
|
||||
reported by Maxim Shalomikhin of Kaspersky.
|
||||
DEVTOOLS: Add configure.sh support for BSD's mandoc as an
|
||||
alternative man page formatting tool.
|
||||
DOC: Document that USAGE is a possible value for {verify}.
|
||||
LIBMILTER: The macros for the EOH and EOM callbacks are
|
||||
sent in reverse order which means accessing macros
|
||||
in the EOM callback got the macro for the EOH
|
||||
callback. Store those macros in the expected order
|
||||
in libmilter. Note: this does not affect sendmail
|
||||
because the macros for both callbacks are the same
|
||||
because the message is sent to libmilter after it
|
||||
is completely read by sendmail. Fix and problem
|
||||
report from David Buergin.
|
||||
Portability:
|
||||
Make use of IN_LOOPBACK, if defined, to determine if
|
||||
using a loopback address. Patch from Mike Karels of
|
||||
FreeBSD.
|
||||
On Linux use gethostbyname2(3) if glibc 2.19 or newer
|
||||
is used to avoid potential problems with IPv6 lookups.
|
||||
Patch from Werner Wiethege.
|
||||
Add support for Darwin 21 and Darwin 22.
|
||||
Solaris 12 has been renamed to Solaris 11.4, hence
|
||||
adapt a condition for sigwait(2) taking one argument.
|
||||
Patch from John Beck.
|
||||
New Files:
|
||||
devtools/M4/UNIX/sharedlib.m4
|
||||
devtools/OS/Darwin.21.x
|
||||
devtools/OS/Darwin.22.x
|
||||
sendmail/sched.c
|
||||
libsm/notify.h
|
||||
|
||||
8.17.1/8.17.1 2021/08/17
|
||||
Deprecation notice: due to compatibility problems with some
|
||||
third party code, we plan to finally switch from K&R
|
||||
@ -37,6 +218,9 @@ summary of the changes in that release.
|
||||
in the SMTP client per server. Currently only two
|
||||
flags are available: D/M to disable DANE/MTA-STS,
|
||||
respectively.
|
||||
New compile time option NO_EOH_FIELDS to disable the special
|
||||
meaning of the headers Message: and Text: to denote the
|
||||
end of the message header.
|
||||
Avoid leaking session macros for an envelope between
|
||||
delivery attempts to different servers. This problem
|
||||
could have affected check_compat.
|
||||
@ -76,10 +260,17 @@ summary of the changes in that release.
|
||||
properly, as the persistent macro applies to all
|
||||
RCPTs and hence implicitly to all destinations (servers).
|
||||
The option TLSFallbacktoClear should be used if needed.
|
||||
CONTRIB: AuthRealm.p0 has been modified for 8.16.1 by Anne Bennett.
|
||||
CONTRIB: Added cidrexpand -O option for suppressing duplicates from
|
||||
a CIDR expansion that overlaps a later entry and -S option
|
||||
for skipping comments exactly like makemap does.
|
||||
MAIL.LOCAL: Enhance some error messages to simplify
|
||||
troubleshooting.
|
||||
Portability:
|
||||
Add support for Darwin 19 & 20.
|
||||
Use proper FreeBSD version define to allow for cross
|
||||
compiling. Fix from Brooks Davis of the FreeBSD
|
||||
project.
|
||||
NOTE: File locking using fcntl() does not interoperate
|
||||
with Berkeley DB 5.x (and probably later). Use
|
||||
CDB, flock() (-DHASFLOCK), or an earlier Berkeley
|
||||
@ -104,22 +295,6 @@ summary of the changes in that release.
|
||||
libsmutil/t-lockfile-0.sh
|
||||
libsmutil/t-maplock-0.sh
|
||||
|
||||
8.16.2/8.16.2 202X/XX/XX
|
||||
New compile time option NO_EOH_FIELDS to disable the special
|
||||
meaning of the headers Message: and Text: to denote the
|
||||
end of the message header.
|
||||
CONTRIB: AuthRealm.p0 has been modified for 8.16.1 by Anne Bennett.
|
||||
CONTRIB: Added cidrexpand -O option for suppressing duplicates from
|
||||
a CIDR expansion that overlaps a later entry and -S option
|
||||
for skipping comments exactly like makemap does.
|
||||
Portability:
|
||||
Add support for Darwin 19 (Mac OS X 10.15).
|
||||
Use proper FreeBSD version define to allow for cross
|
||||
compiling. Fix from Brooks Davis of the FreeBSD
|
||||
project.
|
||||
New Files:
|
||||
devtools/OS/Darwin.19.x
|
||||
|
||||
8.16.1/8.16.1 2020/07/05
|
||||
SECURITY: If sendmail tried to reuse an SMTP session which had
|
||||
already been closed by the server, then the connection
|
||||
@ -5392,7 +5567,7 @@ summary of the changes in that release.
|
||||
characters (in LMTP mode), mail.local split the incoming
|
||||
line up into 2046-character output lines (excluding the
|
||||
newline). If an input line was 2047 characters long
|
||||
(excluding CR-LF) and the last character was a '.',
|
||||
(excluding CRLF) and the last character was a '.',
|
||||
mail.local saw it as the end of input, transferred it to the
|
||||
user mailbox and tried to write an `ok' back to sendmail.
|
||||
If the message was much longer, both sendmail and
|
||||
@ -7675,7 +7850,7 @@ summary of the changes in that release.
|
||||
files that are group writable are considered "unsafe" -- that
|
||||
is, programs and files referenced from such files are not
|
||||
valid recipients.
|
||||
Delete bogosity test for FallBackMX host; this prevented it to be a
|
||||
Delete bogosity test for FallBackMXhost; this prevented it to be a
|
||||
name that was not in DNS or was a domain-literal. Problem
|
||||
noted by Tom May.
|
||||
Change the introduction to error messages to more clearly delineate
|
||||
@ -8414,7 +8589,7 @@ summary of the changes in that release.
|
||||
should show the pathname rather than hex bytes.
|
||||
Restore ``-ba'' mode -- this reads a file from stdin and parses
|
||||
the header for envelope sender information and uses
|
||||
CR-LF as message terminators. It was thought to be
|
||||
CRLF as message terminators. It was thought to be
|
||||
obsolete (used only for Arpanet NCP protocols), but it
|
||||
turns out that the UK ``Grey Book'' protocols require
|
||||
that functionality.
|
||||
@ -10742,7 +10917,7 @@ summary of the changes in that release.
|
||||
as well as the effective. The program test/t_setreuid.c
|
||||
will test to see if your implementation of setreuid(2)
|
||||
is appropriately functional.
|
||||
The FallBackMX (option V) handling failed to properly identify
|
||||
The FallBackMXhost (option V) handling failed to properly identify
|
||||
fallback to yourself -- most of the code was there,
|
||||
but it wasn't being enabled. Problem noted by Murray
|
||||
Kucherawy of the University of Waterloo.
|
||||
|
@ -1301,6 +1301,8 @@ dnsbl Turns on rejection, discarding, or quarantining of hosts
|
||||
definition from `host'. Set the DNSBL_MAP_OPT mc option
|
||||
to add additional options to the map specification used.
|
||||
|
||||
Note: currently only IPv4 addresses are checked.
|
||||
|
||||
Some DNS based rejection lists cause failures if asked
|
||||
for AAAA records. If your sendmail version is compiled
|
||||
with IPv6 support (NETINET6) and you experience this
|
||||
@ -1326,10 +1328,10 @@ enhdnsbl Enhanced version of dnsbl (see above). Further arguments
|
||||
compared with the supplied argument(s), and only if a match
|
||||
occurs an error is generated. For example,
|
||||
|
||||
FEATURE(`enhdnsbl', `dnsbl.example.com', `', `t', `127.0.0.2.')
|
||||
FEATURE(`enhdnsbl', `dnsbl.example.com', `', `t', `127.0.0.2')
|
||||
|
||||
will reject the e-mail if the lookup returns the value
|
||||
``127.0.0.2.'', or generate a 451 response if the lookup
|
||||
``127.0.0.2'', or generate a 451 response if the lookup
|
||||
temporarily failed. The arguments can contain metasymbols
|
||||
as they are allowed in the LHS of rules. As the example
|
||||
shows, the default values are also used if an empty argument,
|
||||
@ -1616,6 +1618,12 @@ sts Experimental support for Strict Transport Security
|
||||
for the default value).
|
||||
For more information see doc/op/op.me.
|
||||
|
||||
fips3 Basic support for FIPS in OpenSSL 3 by setting
|
||||
the environment variables OPENSSL_CONF and
|
||||
OPENSSL_MODULES to the first and second argument,
|
||||
respectively. For details, see the file and
|
||||
the OpenSSL documentation.
|
||||
|
||||
+-------+
|
||||
| HACKS |
|
||||
+-------+
|
||||
@ -1688,6 +1696,7 @@ The macro LOCAL_UUCP can be used to add rules into the generated
|
||||
cf file at the place where MAILER(`uucp') inserts its rules. This
|
||||
should only be used if really necessary.
|
||||
|
||||
|
||||
+--------------------+
|
||||
| USING UUCP MAILERS |
|
||||
+--------------------+
|
||||
@ -3183,8 +3192,8 @@ VERIFY:bits verification must have succeeded and ${cipher_bits} must
|
||||
ENCR:bits ${cipher_bits} must be greater than or equal bits.
|
||||
|
||||
The RHS can optionally be prefixed by TEMP+ or PERM+ to select a temporary
|
||||
or permanent error. The default is a temporary error code (403 4.7.0)
|
||||
unless the macro TLS_PERM_ERR is set during generation of the .cf file.
|
||||
or permanent error. The default is a temporary error code unless
|
||||
the macro TLS_PERM_ERR is set during generation of the .cf file.
|
||||
|
||||
If a certain level of encryption is required, then it might also be
|
||||
possible that this level is provided by the security layer from a SASL
|
||||
@ -3256,9 +3265,10 @@ default TLS options are not modified.
|
||||
About 2): the rulesets try_tls, srv_features, and clt_features can
|
||||
be used together with the access map. Entries for the access map
|
||||
must be tagged with Try_TLS, Srv_Features, Clt_Features and refer
|
||||
to the hostname or IP address of the connecting system. A default
|
||||
case can be specified by using just the tag. For example, the
|
||||
following entries in the access map:
|
||||
to the hostname or IP address of the connecting system (the latter
|
||||
is not available for clt_features). A default case can be specified
|
||||
by using just the tag. For example, the following entries in the
|
||||
access map:
|
||||
|
||||
Try_TLS:broken.server NO
|
||||
Srv_Features:my.domain v
|
||||
@ -3376,6 +3386,7 @@ or FEATURE(`authinfo') must be used which provides a separate map.
|
||||
Notice: It is not checked whether the map is actually
|
||||
group/world-unreadable, this is left to the user.
|
||||
|
||||
|
||||
+--------------------------------+
|
||||
| ADDING NEW MAILERS OR RULESETS |
|
||||
+--------------------------------+
|
||||
@ -3461,6 +3472,7 @@ groups can be defined using the command:
|
||||
|
||||
For details about queue groups, please see doc/op/op.{me,ps,txt}.
|
||||
|
||||
|
||||
+-------------------------------+
|
||||
| NON-SMTP BASED CONFIGURATIONS |
|
||||
+-------------------------------+
|
||||
@ -4406,6 +4418,9 @@ confCERT_FINGERPRINT_ALGORITHM CertFingerprintAlgorithm
|
||||
confSSL_ENGINE SSLEngine [undefined] Name of SSLEngine.
|
||||
confSSL_ENGINE_PATH SSLEnginePath [undefined] Path to dynamic library
|
||||
for SSLEngine.
|
||||
confOPENSSL_CNF [/etc/mail/sendmail.ossl] Set the
|
||||
environment variable OPENSSL_CONF.
|
||||
An empty value disables setting it.
|
||||
confNICE_QUEUE_RUN NiceQueueRun [undefined] If set, the priority of
|
||||
queue runners is set the given value
|
||||
(nice(3)).
|
||||
|
@ -16,8 +16,8 @@
|
||||
#####
|
||||
##### SENDMAIL CONFIGURATION FILE
|
||||
#####
|
||||
##### built by ca@lab.smi.sendmail.com on Sun Aug 15 23:05:00 PDT 2021
|
||||
##### in /var/tmp/ca/sm8.head/sendmail/OpenSource/sendmail-8.17.1/cf/cf
|
||||
##### built by xbuild@xenon14.us.proofpoint.com on Tue Jan 30 22:39:25 PST 2024
|
||||
##### in /export/jenkins/jenkins3/workspace/pps-sendmail/OpenSource/sendmail-8.18.1/cf/cf
|
||||
##### using ../ as configuration include directory
|
||||
#####
|
||||
######################################################################
|
||||
@ -111,11 +111,13 @@ Kdequote dequote
|
||||
DnMAILER-DAEMON
|
||||
|
||||
|
||||
|
||||
D{MTAHost}[127.0.0.1]
|
||||
|
||||
EOPENSSL_CONF=/etc/mail/sendmail.ossl
|
||||
|
||||
# Configuration version number
|
||||
DZ8.17.1/Submit
|
||||
DZ8.18.1/Submit
|
||||
|
||||
|
||||
###############
|
||||
@ -1248,6 +1250,7 @@ Stry_tls
|
||||
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
### tls_rcpt: is connection with server "good" enough?
|
||||
### (done in client, per recipient)
|
||||
@ -1256,7 +1259,10 @@ Stry_tls
|
||||
### $1: recipient
|
||||
######################################################################
|
||||
Stls_rcpt
|
||||
|
||||
R$* $: $1 $| $&{verify}
|
||||
R$* $| DANE_NOTLS $#error $@ 4.7.0 $: "454 DANE: missing STARTTLS."
|
||||
R$* $| DANE_TEMP $#error $@ 4.7.0 $: "454 DANE check failed temporarily."
|
||||
R$* $| DANE_FAIL $#error $@ 4.7.0 $: "454 DANE check failed."
|
||||
|
||||
######################################################################
|
||||
### tls_client: is connection with client "good" enough?
|
||||
@ -1288,7 +1294,6 @@ R$* $@ $>"TLS_connection" $1
|
||||
######################################################################
|
||||
STLS_connection
|
||||
RSOFTWARE $#error $@ 4.7.0 $: "454 TLS handshake failed."
|
||||
RDANE_FAIL $#error $@ 4.7.0 $: "454 DANE check failed."
|
||||
RPROTOCOL $#error $@ 4.7.0 $: "454 STARTTLS failed."
|
||||
RCONFIG $#error $@ 4.7.0 $: "454 STARTTLS temporarily not possible."
|
||||
|
||||
|
@ -13,5 +13,5 @@ divert(0)dnl
|
||||
VERSIONID(`$Id: check_cert_altnames.m4 1.0 2019-01-01 01:01:01 ca Exp $')
|
||||
divert(-1)
|
||||
define(`_FFR_TLS_ALTNAMES', `1')
|
||||
divert(6)dnl
|
||||
LOCAL_CONFIG
|
||||
O SetCertAltnames=true
|
||||
|
@ -17,7 +17,7 @@ VERSIONID(`$Id: enhdnsbl.m4,v 1.13 2013-11-22 20:51:11 ca Exp $')
|
||||
LOCAL_CONFIG
|
||||
define(`_EDNSBL_R_',`')dnl
|
||||
# map for enhanced DNS based blocklist lookups
|
||||
Kednsbl dns -R A -a. -T<TMP> -r`'ifdef(`EDNSBL_TO',`EDNSBL_TO',`5')
|
||||
Kednsbl dns -R A -T<TMP> -z -Z32 -r`'ifdef(`EDNSBL_TO',`EDNSBL_TO',`5')
|
||||
')
|
||||
divert(-1)
|
||||
define(`_EDNSBL_SRV_', `_ARG_')dnl
|
||||
@ -39,15 +39,15 @@ R<?>OK $: OKSOFAR
|
||||
ifelse(len(X`'_ARG3_),`1',
|
||||
`R<?>$+<TMP> $: TMPOK',
|
||||
`R<?>$+<TMP> $#error $@ 4.4.3 $: _EDNSBL_MSG_TMP_')
|
||||
R<?>_EDNSBL_MATCH_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_
|
||||
R<?>$* patsubst(_EDNSBL_MATCH_, `\.$', `') $* _EDNSBL_ACTION_ $: _EDNSBL_MSG_
|
||||
ifelse(len(X`'_ARG5_),`1',`dnl',
|
||||
`R<?>_ARG5_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
`R<?>$* patsubst(_ARG5_, `\.$', `') $* _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
ifelse(len(X`'_ARG6_),`1',`dnl',
|
||||
`R<?>_ARG6_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
`R<?>$* patsubst(_ARG6_, `\.$', `') $* _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
ifelse(len(X`'_ARG7_),`1',`dnl',
|
||||
`R<?>_ARG7_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
`R<?>$* patsubst(_ARG7_, `\.$', `') $* _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
ifelse(len(X`'_ARG8_),`1',`dnl',
|
||||
`R<?>_ARG8_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
`R<?>$* patsubst(_ARG8_, `\.$', `') $* _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
ifelse(len(X`'_ARG9_),`1',`dnl',
|
||||
`R<?>_ARG9_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
`R<?>$* patsubst(_ARG9_, `\.$', `') $* _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
|
||||
divert(-1)
|
||||
|
16
contrib/sendmail/cf/feature/fips3.m4
Normal file
16
contrib/sendmail/cf/feature/fips3.m4
Normal file
@ -0,0 +1,16 @@
|
||||
divert(-1)
|
||||
#
|
||||
# Copyright (c) 2023 Proofpoint, Inc. and its suppliers.
|
||||
# All rights reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set
|
||||
# forth in the LICENSE file which can be found at the top level of
|
||||
# the sendmail distribution.
|
||||
#
|
||||
#
|
||||
|
||||
divert(0)
|
||||
define(`confOPENSSL_CNF', dnl
|
||||
ifelse(defn(`_ARG_'), `', `/etc/mail/fips.ossl', `_ARG_'))dnl
|
||||
ifelse(len(X`'_ARG2_),`1',`',`LOCAL_CONFIG
|
||||
EOPENSSL_MODULES=_ARG2_')
|
@ -18,7 +18,7 @@ ifelse(len(X`'_ARG1_), `1', `define(`_LDAP_ROUTING_WARN_', `yes')')
|
||||
ifelse(len(X`'_ARG2_), `1', `define(`_LDAP_ROUTING_WARN_', `yes')')
|
||||
ifelse(len(X`'_ARG5_), `1', `', `define(`_LDAP_ROUTE_NODOMAIN_', `yes')')
|
||||
|
||||
# Check for third argument to indicate how to deal with non-existant
|
||||
# Check for third argument to indicate how to deal with non-existent
|
||||
# LDAP records
|
||||
ifelse(len(X`'_ARG3_), `1', `define(`_LDAP_ROUTING_', `_PASS_THROUGH_')',
|
||||
_ARG3_, `passthru', `define(`_LDAP_ROUTING_', `_PASS_THROUGH_')',
|
||||
|
@ -20,6 +20,8 @@ LOCAL_RULESETS
|
||||
#
|
||||
# x_connect ruleset for looking up XConnect: tag in access DB to enable
|
||||
# XCONNECT support in MTA
|
||||
# if the RHS of the map entry is haproxy1,
|
||||
# then HAproxy protocol version 1 is used
|
||||
#
|
||||
Sx_connect
|
||||
dnl workspace: {client_name} $| {client_addr}
|
||||
@ -32,6 +34,6 @@ R<?> <$+> $: $>A < $1 > <?> <! XConnect> <> no: another lookup
|
||||
dnl workspace: <result-of-lookup> (<>|<{client_addr}>)
|
||||
R<?> <$*> $# no found nothing
|
||||
dnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK
|
||||
R<$+> <$*> $@ yes found in access DB',
|
||||
R<$+> <$*> $@ $1 found in access DB',
|
||||
`errprint(`*** ERROR: HACK(xconnect) requires FEATURE(access_db)
|
||||
')')
|
||||
|
@ -247,7 +247,9 @@ DM`'MASQUERADE_NAME')
|
||||
# my name for error messages
|
||||
ifdef(`confMAILER_NAME', `Dn`'confMAILER_NAME', `#DnMAILER-DAEMON')
|
||||
|
||||
ifdef(`confOPENSSL_CNF',, `define(`confOPENSSL_CNF', `/etc/mail/sendmail.ossl')')
|
||||
undivert(6)dnl LOCAL_CONFIG
|
||||
ifelse(defn(`confOPENSSL_CNF'), `', `', `EOPENSSL_CONF=confOPENSSL_CNF')
|
||||
include(_CF_DIR_`m4/version.m4')
|
||||
|
||||
###############
|
||||
@ -938,7 +940,7 @@ ifdef(`_CANONIFY_HOSTS_', `dnl
|
||||
dnl this should only apply to unqualified hostnames
|
||||
dnl but if a valid character inside an unqualified hostname is an OperatorChar
|
||||
dnl then $- does not work.
|
||||
# lookup unqualified hostnames
|
||||
# look up unqualified hostnames
|
||||
R$* $| $* < @ $* > $* $: $2 < @ $[ $3 $] > $4', `dnl')', `dnl
|
||||
dnl _NO_CANONIFY_ is not set: canonify unless:
|
||||
dnl {daemon_flags} contains CC (do not canonify)
|
||||
@ -1234,7 +1236,7 @@ R$+ . USENET $#usenet $@ usenet $: $1',
|
||||
|
||||
ifdef(`_LOCAL_RULES_',
|
||||
`# figure out what should stay in our local mail system
|
||||
undivert(1)', `dnl')
|
||||
undivert(1)dnl LOCAL_NET_CONFIG', `dnl')
|
||||
|
||||
# pass names that still have a host to a smarthost (if defined)
|
||||
R$* < @ $* > $* $: $>MailerToTriple < $S > $1 < @ $2 > $3 glue on smarthost name
|
||||
@ -1436,11 +1438,12 @@ dnl if generics should be applied add a @ as mark
|
||||
R$+ < @ *LOCAL* > $: < $1@$j > $1 < @ *LOCAL* > @ mark
|
||||
dnl workspace: either user<@domain> or <user@domain> user <@domain> @
|
||||
dnl ignore the first case for now
|
||||
dnl if it has the mark lookup full address
|
||||
dnl if it has the mark look up full address
|
||||
dnl broken: %1 is full address not just detail
|
||||
R< $+ > $+ < $* > @ $: < $(generics $1 $: @ $1 $) > $2 < $3 >
|
||||
dnl workspace: ... or <match|@user@domain> user <@domain>
|
||||
dnl no match, try user+detail@domain
|
||||
dnl no match, try user+detail@domain:
|
||||
dnl look up user+*@domain and user@domain
|
||||
R<@$+ + $* @ $+> $+ < @ $+ >
|
||||
$: < $(generics $1+*@$3 $@ $2 $:@$1 + $2@$3 $) > $4 < @ $5 >
|
||||
R<@$+ + $* @ $+> $+ < @ $+ >
|
||||
@ -1527,7 +1530,7 @@ R$={SMTPOpModes} $| TMPF <e r> $| $+ $#error $@ 4.3.0 $: _TMPFMSG_(`OPM')')
|
||||
# ... return original address for MTA to queue up
|
||||
R$* $| TMPF <$*> $| $+ $@ $3
|
||||
|
||||
# if mailRoutingAddress and local or non-existant mailHost,
|
||||
# if mailRoutingAddress and local or non-existent mailHost,
|
||||
# return the new mailRoutingAddress
|
||||
ifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl
|
||||
R<$+@$+> <$=w> <$+> <$+> <$*> $@ $>Parse0 $>canonify $1 $6 @ $2
|
||||
@ -1610,14 +1613,14 @@ dnl <result> <passthru>
|
||||
|
||||
SD
|
||||
dnl workspace <key> <default> <passthru> <mark>
|
||||
dnl lookup with tag (in front, no delimiter here)
|
||||
dnl look up with tag (in front, no delimiter here)
|
||||
dnl 2 3 4 5
|
||||
R<$*> <$+> <$- $-> <$*> $: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
|
||||
dnl workspace <result-of-lookup|?> <key> <default> <passthru> <mark>
|
||||
dnl lookup without tag?
|
||||
dnl look up without tag?
|
||||
dnl 1 2 3 4
|
||||
R<?> <$+> <$+> <+ $-> <$*> $: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
|
||||
ifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: lookup .rest
|
||||
ifdef(`_LOOKUPDOTDOMAIN_', `dnl omit first component: look up .rest
|
||||
dnl XXX apply this also to IP addresses?
|
||||
dnl currently it works the wrong way round for [1.2.3.4]
|
||||
dnl 1 2 3 4 5 6
|
||||
@ -1640,7 +1643,7 @@ R<?> <[$+:$-]> <$+> <$- $-> <$*> $: $>D <[$1]> <$3> <$4 $5> <$6>')
|
||||
dnl not found, but subdomain: try again
|
||||
dnl 1 2 3 4 5 6
|
||||
R<?> <$+.$+> <$+> <$- $-> <$*> $@ $>D <$2> <$3> <$4 $5> <$6>
|
||||
ifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag:
|
||||
ifdef(`_FFR_LOOKUPTAG_', `dnl look up Tag:
|
||||
dnl 1 2 3 4
|
||||
R<?> <$+> <$+> <! $-> <$*> $: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl')
|
||||
dnl not found, no subdomain: return <default> and <passthru>
|
||||
@ -1669,10 +1672,10 @@ dnl <result> <passthru>
|
||||
######################################################################
|
||||
|
||||
SA
|
||||
dnl lookup with tag
|
||||
dnl look up with tag
|
||||
dnl 2 3 4 5
|
||||
R<$+> <$+> <$- $-> <$*> $: < $(access $4`'_TAG_DELIM_`'$1 $: ? $) > <$1> <$2> <$3 $4> <$5>
|
||||
dnl lookup without tag
|
||||
dnl look up without tag
|
||||
dnl 1 2 3 4
|
||||
R<?> <$+> <$+> <+ $-> <$*> $: < $(access $1 $: ? $) > <$1> <$2> <+ $3> <$4>
|
||||
dnl workspace <result-of-lookup|?> <key> <default> <mark> <passthru>
|
||||
@ -2402,7 +2405,7 @@ dnl otherwise call tls_client; see above
|
||||
R$+ $| $#$* $@ $>"Delay_TLS_Clt" $2
|
||||
R$+ $| $* $: <?> $>FullAddr $>CanonAddr $1
|
||||
ifdef(`_SPAM_FH_',
|
||||
`dnl lookup user@ and user@address
|
||||
`dnl look up user@ and user@address
|
||||
ifdef(`_ACCESS_TABLE_', `',
|
||||
`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
|
||||
')')dnl
|
||||
@ -2412,7 +2415,7 @@ dnl and simplified by omitting some < >.
|
||||
R<?> $+ < @ $=w > $: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
|
||||
R<?> $+ < @ $* > $: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
|
||||
dnl R<?> $@ something_is_very_wrong_here
|
||||
# lookup the addresses only with Spam tag
|
||||
# look up the addresses only with Spam tag
|
||||
R<> $* $| <$+> $: <@> $1 $| $>SearchList <! Spam> $| <$2> <>
|
||||
R<@> $* $| $* $: $2 $1 reverse result
|
||||
dnl', `dnl')
|
||||
@ -2608,16 +2611,16 @@ R<$+> <$*> <$- $-> <$*> $@ <$1> <$5>
|
||||
### Parameters:
|
||||
### <exact tag> $| <mark:address> <mark:address> ... <>
|
||||
dnl maybe we should have a @ (again) in front of the mark to
|
||||
dnl avoid errorneous matches (with error messages?)
|
||||
dnl avoid erroneous matches (with error messages?)
|
||||
dnl if we can make sure that tag is always a single token
|
||||
dnl then we can omit the delimiter $|, otherwise we need it
|
||||
dnl to avoid errorneous matchs (first rule: D: if there
|
||||
dnl to avoid erroneous matches (first rule: D: if there
|
||||
dnl is that mark somewhere in the list, it will be taken).
|
||||
dnl moreover, we can do some tricks to enforce lookup with
|
||||
dnl the tag only, e.g.:
|
||||
### where "exact" is either "+" or "!":
|
||||
### <+ TAG> lookup with and w/o tag
|
||||
### <! TAG> lookup with tag
|
||||
### <+ TAG> look up with and w/o tag
|
||||
### <! TAG> look up with tag
|
||||
dnl Warning: + and ! should be in OperatorChars (otherwise there must be
|
||||
dnl a blank between them and the tag.
|
||||
### possible values for "mark" are:
|
||||
@ -2706,8 +2709,9 @@ R$* $: $1 $| $>"Local_clt_features" $1
|
||||
R$* $| $#$* $#$2
|
||||
R$* $| $* $: $1', `dnl')
|
||||
ifdef(`_ACCESS_TABLE_', `dnl
|
||||
R$* $: $>D <$&{client_name}> <?> <! CLT_FEAT_TAG> <>
|
||||
R<?>$* $: $>A <$&{client_addr}> <?> <! CLT_FEAT_TAG> <>
|
||||
dnl the servername can have a trailing dot from canonification
|
||||
R$* . $1
|
||||
R$+ $: $>D <$1> <?> <! CLT_FEAT_TAG> <>
|
||||
R<?>$* $: <$(access CLT_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
|
||||
R<?>$* $@ OK
|
||||
ifdef(`_ATMPF_', `dnl tempfail?
|
||||
@ -2802,6 +2806,18 @@ R:$* $| $-.$+ $: $(macro {TLS_Name} $@ .$3 $) $>TLS_NameInList :$1
|
||||
R$* ok $@ $>STS_SAN
|
||||
R:$*: $#error $@ 4.7.0 $: 450 $&{server_name} not found in " "$1', `dnl')
|
||||
|
||||
ifdef(`TLS_PERM_ERR', `dnl
|
||||
define(`TLS_DSNCODE', `5.7.0')dnl
|
||||
define(`TLS_ERRCODE', `554')',`dnl
|
||||
define(`TLS_DSNCODE', `4.7.0')dnl
|
||||
define(`TLS_ERRCODE', `454')')dnl
|
||||
define(`SW_MSG', `TLS handshake failed.')dnl
|
||||
define(`DANE_MSG', `DANE check failed.')dnl
|
||||
define(`DANE_TEMP_MSG', `DANE check failed temporarily.')dnl
|
||||
define(`DANE_NOTLS_MSG', `DANE: missing STARTTLS.')dnl
|
||||
define(`PROT_MSG', `STARTTLS failed.')dnl
|
||||
define(`CNF_MSG', `STARTTLS temporarily not possible.')dnl
|
||||
|
||||
######################################################################
|
||||
### tls_rcpt: is connection with server "good" enough?
|
||||
### (done in client, per recipient)
|
||||
@ -2833,12 +2849,22 @@ R<?> $+ $: $1 $| <U:$1@> <E:>
|
||||
dnl look it up
|
||||
dnl also look up a default value via E:
|
||||
R$* $| $+ $: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
|
||||
dnl no applicable requirements; trigger an error on DANE_FAIL
|
||||
dnl note: this allows to disable DANE per RCPT.
|
||||
R$* $| <?> $: $1 $| $&{verify} $| <?>
|
||||
R$* $| DANE_FAIL $| <?> $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"
|
||||
R$* $| DANE_NOTLS $| <?> $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_NOTLS_MSG"
|
||||
R$* $| DANE_TEMP $| <?> $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_TEMP_MSG"
|
||||
dnl found nothing: stop here
|
||||
R$* $| <?> $@ OK
|
||||
ifdef(`_ATMPF_', `dnl tempfail?
|
||||
R$* $| <$* _ATMPF_> $#error $@ 4.3.0 $: _TMPFMSG_(`TR')', `dnl')
|
||||
dnl use the generic routine (for now)
|
||||
R$* $| <$+> $@ $>"TLS_connection" $&{verify} $| <$2>')
|
||||
R$* $| <$+> $@ $>"TLS_connection" $&{verify} $| <$2>', `dnl
|
||||
R$* $: $1 $| $&{verify}
|
||||
R$* $| DANE_NOTLS $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_NOTLS_MSG"
|
||||
R$* $| DANE_TEMP $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_TEMP_MSG"
|
||||
R$* $| DANE_FAIL $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"')
|
||||
|
||||
######################################################################
|
||||
### tls_client: is connection with client "good" enough?
|
||||
@ -2915,22 +2941,14 @@ dnl [(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
|
||||
dnl extensions: could be a list of further requirements
|
||||
dnl for now: CN:string {cn_subject} == string
|
||||
######################################################################
|
||||
ifdef(`TLS_PERM_ERR', `dnl
|
||||
define(`TLS_DSNCODE', `5.7.0')dnl
|
||||
define(`TLS_ERRCODE', `554')',`dnl
|
||||
define(`TLS_DSNCODE', `4.7.0')dnl
|
||||
define(`TLS_ERRCODE', `454')')dnl
|
||||
define(`SW_MSG', `TLS handshake failed.')dnl
|
||||
define(`DANE_MSG', `DANE check failed.')dnl
|
||||
define(`PROT_MSG', `STARTTLS failed.')dnl
|
||||
define(`CNF_MSG', `STARTTLS temporarily not possible.')dnl
|
||||
STLS_connection
|
||||
ifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl', `dnl use default error
|
||||
dnl deal with TLS handshake failures: abort
|
||||
RSOFTWARE $#error $@ TLS_DSNCODE $: "TLS_ERRCODE SW_MSG"
|
||||
RDANE_FAIL $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"
|
||||
dnl RDANE_FAIL $#error $@ TLS_DSNCODE $: "TLS_ERRCODE DANE_MSG"
|
||||
RPROTOCOL $#error $@ TLS_DSNCODE $: "TLS_ERRCODE PROT_MSG"
|
||||
RCONFIG $#error $@ TLS_DSNCODE $: "TLS_ERRCODE CNF_MSG"
|
||||
dnl RDANE_TEMP $#error $@ 4.7.0 $: "454 DANE_TEMP_MSG"
|
||||
divert(-1)')
|
||||
dnl common ruleset for tls_{client|server}
|
||||
dnl input: ${verify} $| <ResultOfLookup> [<>]
|
||||
@ -2953,10 +2971,12 @@ R`'$1 $| $`'* $`'#error $`'@ TLS_DSNCODE $: "TLS_ERRCODE $2"')dnl
|
||||
TLS_ERRORS(SOFTWARE,SW_MSG)
|
||||
# deal with TLS protocol errors: abort
|
||||
TLS_ERRORS(PROTOCOL,PROT_MSG)
|
||||
# deal with DANE errors: abort
|
||||
TLS_ERRORS(DANE_FAIL,DANE_MSG)
|
||||
dnl # deal with DANE errors: abort
|
||||
dnl TLS_ERRORS(DANE_FAIL,DANE_MSG)
|
||||
# deal with CONFIG (tls_clt_features) errors: abort
|
||||
TLS_ERRORS(CONFIG,CNF_MSG)
|
||||
dnl # deal with DANE tempfail: abort
|
||||
dnl TLS_ERRORS(DANE_TEMP,DANE_TEMP_MSG)
|
||||
R$* $| <$*> <VERIFY> $: <$2> <VERIFY> <> $1
|
||||
dnl separate optional requirements
|
||||
R$* $| <$*> <VERIFY + $+> $: <$2> <VERIFY> <$3> $1
|
||||
|
@ -15,4 +15,4 @@ VERSIONID(`$Id: version.m4,v 8.237 2014-01-27 12:55:17 ca Exp $')
|
||||
#
|
||||
divert(0)
|
||||
# Configuration version number
|
||||
DZ8.17.1`'ifdef(`confCF_VERSION', `/confCF_VERSION')
|
||||
DZ8.18.1`'ifdef(`confCF_VERSION', `/confCF_VERSION')
|
||||
|
@ -57,4 +57,4 @@ fi
|
||||
echo '#####' built by $user@$host
|
||||
echo '#####' in `pwd` | sed 's/\/tmp_mnt//'
|
||||
echo '#####' using $1 as configuration include directory | sed 's/\/tmp_mnt//'
|
||||
echo "define(\`__HOST__', $host)dnl"
|
||||
echo "define(\`__HOST__', \`$host')dnl"
|
||||
|
@ -170,7 +170,7 @@ LINE: while (<DOMAIN>)
|
||||
warn "Bogus line $line in $virts/$domain\n";
|
||||
}
|
||||
|
||||
# Variable subsitution
|
||||
# Variable substitution
|
||||
$key =~ s/\$DOMAIN/$domain/g;
|
||||
$value =~ s/\$DOMAIN/$domain/g;
|
||||
$value =~ s/\$LHS/$lhs/g;
|
||||
|
@ -13,9 +13,12 @@ PIC= ${PIC_CMD} -C
|
||||
EQNASCII= ${EQN_CMD} -C -Tascii
|
||||
EQNPS= ${EQN_CMD} -C -Tps
|
||||
ROFFASCII= ${ROFF_CMD} -Tascii ${MACROS}
|
||||
ROFFNOSGR= GROFF_NO_SGR=1 ${ROFFASCII}
|
||||
ROFFPS= ${ROFF_CMD} -Tps -mps ${MACROS}
|
||||
ULASCII= ${UL_CMD} -t dumb
|
||||
PS2PDF= ${PS2PDF_CMD}
|
||||
OPTXT_CMD= ${PIC} ${SRCS} | ${EQNASCII} | ${ROFFASCII} | ${ULASCII} 2>/dev/null
|
||||
OPTXTNS_CMD= ${PIC} ${SRCS} | ${EQNASCII} | ${ROFFNOSGR} | ${ULASCII}
|
||||
|
||||
all: ${OBJS}
|
||||
|
||||
@ -26,8 +29,7 @@ op.ps: ${SRCS}
|
||||
|
||||
op.txt: ${SRCS}
|
||||
rm -f $@
|
||||
@echo "Note: see README file in case of errors."
|
||||
${PIC} ${SRCS} | ${EQNASCII} | ${ROFFASCII} | ${ULASCII} > $@
|
||||
${OPTXT_CMD} > $@ || ${OPTXTNS_CMD} > $@
|
||||
|
||||
op.pdf: op.ps
|
||||
rm -f $@
|
||||
|
@ -92,7 +92,7 @@ Version \\$2
|
||||
..
|
||||
.rm Ve
|
||||
.sp
|
||||
For Sendmail Version 8.17
|
||||
For Sendmail Version 8.18
|
||||
.)l
|
||||
.(f
|
||||
Sendmail is a trademark of Proofpoint, Inc.
|
||||
@ -1690,22 +1690,17 @@ Blank lines and lines beginning with a sharp sign
|
||||
.q # )
|
||||
are comments.
|
||||
.pp
|
||||
The second form is processed by the
|
||||
The second form is processed by one of the available map types,
|
||||
e.g.,
|
||||
.i ndbm \|(3)\**
|
||||
.(f
|
||||
\**The
|
||||
.i gdbm
|
||||
package does not work.
|
||||
.)f
|
||||
or the Berkeley DB library.
|
||||
This form is in the file
|
||||
.i /etc/mail/aliases.db
|
||||
(if using NEWDB)
|
||||
the Berkeley DB library,
|
||||
or
|
||||
.i /etc/mail/aliases.dir
|
||||
and
|
||||
.i /etc/mail/aliases.pag
|
||||
(if using NDBM).
|
||||
.i cdb .
|
||||
This is the form that
|
||||
.i sendmail
|
||||
actually uses to resolve aliases.
|
||||
@ -3246,6 +3241,9 @@ often cannot assume that a given file was created by the owner,
|
||||
particularly when it is in a writable directory.
|
||||
You can set this flag if you know that file giveaway is restricted
|
||||
on your system.
|
||||
.ip CertOwner
|
||||
Accept certificate public and private key files
|
||||
which are not owned by RunAsUser for STARTTLS.
|
||||
.ip ClassFileInUnsafeDirPath
|
||||
When reading class files (using the
|
||||
.b F
|
||||
@ -4415,17 +4413,18 @@ It can accept or reject the command.
|
||||
The
|
||||
.i clt_features
|
||||
ruleset is called with the server's host name
|
||||
when sendmail connects to it.
|
||||
before sendmail connects to it
|
||||
(only if sendmail is compiled with STARTTLS or SASL).
|
||||
This ruleset should return
|
||||
.b $#
|
||||
followed by a list of options
|
||||
(single characters delimited by white space).
|
||||
(in general, single characters delimited by white space).
|
||||
If the return value starts with anything else it is silently ignored.
|
||||
Generally upper case characters turn off a feature
|
||||
while lower case characters turn it on.
|
||||
Options `D'/`M' cause the client to not use DANE/MTA-STS,
|
||||
respectively,
|
||||
which is useful to interact with MTAs/MUs that have broken
|
||||
which is useful to interact with MTAs that have broken
|
||||
DANE/MTA-STS setups by simply not using it.
|
||||
Note:
|
||||
The
|
||||
@ -4454,15 +4453,18 @@ not passed on to the next relay.
|
||||
.pp
|
||||
The
|
||||
.i tls_client
|
||||
ruleset is called when sendmail acts as server, after a STARTTLS command
|
||||
has been issued, and from
|
||||
ruleset is called when sendmail acts as server:
|
||||
after a STARTTLS command has been issued and the TLS handshake
|
||||
was performed,
|
||||
and from
|
||||
.i check_mail.
|
||||
The parameter is the value of
|
||||
.b ${verify}
|
||||
and STARTTLS or MAIL, respectively.
|
||||
If the ruleset does resolve to the
|
||||
.q error
|
||||
mailer, the appropriate error code is returned to the client.
|
||||
mailer, the appropriate error code is returned to the client,
|
||||
for STARTTLS this happens for (most) subsequent commands.
|
||||
.sh 4 "tls_server"
|
||||
.pp
|
||||
The
|
||||
@ -4506,8 +4508,8 @@ ruleset is called with the connecting client's host name
|
||||
when a client connects to sendmail.
|
||||
This ruleset should return
|
||||
.b $#
|
||||
followed by a list of options (single characters
|
||||
delimited by white space).
|
||||
followed by a list of options
|
||||
(in general, single characters delimited by white space).
|
||||
If the return value starts with anything else it is silently ignored.
|
||||
Generally upper case characters turn off a feature
|
||||
while lower case characters turn it on.
|
||||
@ -4526,6 +4528,40 @@ If a client sends one of the (HTTP) commands GET, POST, CONNECT, or USER
|
||||
the connection is immediately terminated in the following cases:
|
||||
if sent as first command, if sent as first command after STARTTLS,
|
||||
or if the 'h' option is set.
|
||||
Option 'F' disables SMTP transaction stuffing protection which is
|
||||
enabled by default.
|
||||
The protection checks for clients which try to send commands
|
||||
without waiting for the server HELO/EHLO and DATA response.
|
||||
Option 'o' causes the server to accept only
|
||||
CRLF . CRLF
|
||||
as end of an SMTP message as required by the RFCs
|
||||
which is also a defense against SMTP smuggling (CVE-2023-51765).
|
||||
Option 'O' allows the server to accept a single dot on a line by itself
|
||||
as end of an SMTP message.
|
||||
Option 'g' instructs the server to fail SMTP messages
|
||||
which have a LF without a CR directly before it ("bare LF")
|
||||
by dropping the session with a 421 error.
|
||||
Option 'G' accepts SMTP messages which have a "bare LF".
|
||||
Option 'u' instructs the server to fail SMTP messages
|
||||
which have a CR without a LF directly after it ("bare CR")
|
||||
by dropping the session with a 421 error.
|
||||
Option 'U' accepts SMTP messages which have a "bare CR".
|
||||
There is a variant for the options 'u' and 'g':
|
||||
a '2' can be appended to the single character,
|
||||
in which case the server will replace the offending bare CR
|
||||
or bare LF with a space.
|
||||
This allows to accept mail from broken systems,
|
||||
but the message is modified to avoid SMTP smuggling.
|
||||
If needed, systems with broken SMTP implementations
|
||||
can be allowed some violations, e.g., a combination of
|
||||
.(b
|
||||
G U g2 u2 O
|
||||
.)b
|
||||
A command like
|
||||
.(b
|
||||
egrep 'Bare.*(CR|LF).*not allowed' $MAILLOG
|
||||
.)b
|
||||
can be used to find hosts which send bare CR or LF.
|
||||
.(b
|
||||
.ta 9n
|
||||
A Do not offer AUTH
|
||||
@ -4539,13 +4575,24 @@ D Do not offer DSN
|
||||
d Offer DSN (default)
|
||||
E Do not offer ETRN
|
||||
e Offer ETRN (default)
|
||||
F Disable transaction stuffing protection
|
||||
f Enforce transaction stuffing protection (default)
|
||||
G Accept "bare LF"s in a message
|
||||
g Do not accept "bare LF"s in a message (default)
|
||||
g2 Replace "bare LF" in a message with space
|
||||
h Terminate session after HTTP commands
|
||||
L Do not require AUTH (default)
|
||||
l Require AUTH
|
||||
O Accept a single dot on a line by itself
|
||||
as end of an SMTP message
|
||||
o Require CRLF . CRLF as end of an SMTP message (default)
|
||||
P Do not offer PIPELINING
|
||||
p Offer PIPELINING (default)
|
||||
S Do not offer STARTTLS
|
||||
s Offer STARTTLS (default)
|
||||
U Accept "bare CR"s in a message
|
||||
u Do not accept "bare CR"s in a message (default)
|
||||
u2 Replace "bare CR" in a message with space
|
||||
V Do not request a client certificate
|
||||
v Request a client certificate (default)
|
||||
X Do not offer EXPN
|
||||
@ -4566,6 +4613,7 @@ accept email.
|
||||
The
|
||||
.i try_tls
|
||||
ruleset is called when sendmail connects to another MTA.
|
||||
The argument for the ruleset is the name of the server.
|
||||
If the ruleset does resolve to the
|
||||
.q error
|
||||
mailer, sendmail does not try STARTTLS even if it is offered.
|
||||
@ -4667,6 +4715,10 @@ specifying only one is an error.
|
||||
The
|
||||
.i authinfo
|
||||
ruleset is called when sendmail tries to authenticate to another MTA.
|
||||
The arguments for the ruleset are the host name and IP address
|
||||
of the server separated by
|
||||
.b $|
|
||||
(which is a metacharacter).
|
||||
It should return
|
||||
.b $#
|
||||
followed by a list of tokens that are used for SMTP AUTH.
|
||||
@ -4713,6 +4765,10 @@ The
|
||||
.i greet_pause
|
||||
ruleset is used to specify the amount of time to pause before sending the
|
||||
initial SMTP 220 greeting.
|
||||
The arguments for the ruleset are the host name and IP address
|
||||
of the client separated by
|
||||
.b $|
|
||||
(which is a metacharacter).
|
||||
If any traffic is received during that pause, an SMTP 554 rejection
|
||||
response is given instead of the 220 greeting and all SMTP commands are
|
||||
rejected during that connection.
|
||||
@ -4967,26 +5023,6 @@ a richer set of operators is
|
||||
which adds support for UUCP, the %-hack, and X.400 addresses.
|
||||
.ip $p
|
||||
Sendmail's process id.
|
||||
.ip $q\(dg
|
||||
Default format of sender address.
|
||||
The
|
||||
.b $q
|
||||
macro specifies how an address should appear in a message
|
||||
when it is defaulted.
|
||||
Defaults to
|
||||
.q "<$g>" .
|
||||
It is commonly redefined to be
|
||||
.q "$?x$x <$g>$|$g$."
|
||||
or
|
||||
.q "$g$?x ($x)$." ,
|
||||
corresponding to the following two formats:
|
||||
.(b
|
||||
Eric Allman <eric@CS.Berkeley.EDU>
|
||||
eric@CS.Berkeley.EDU (Eric Allman)
|
||||
.)b
|
||||
.i Sendmail
|
||||
properly quotes names that have special characters
|
||||
if the first form is used.
|
||||
.ip $r
|
||||
Protocol used to receive the message.
|
||||
Set from the
|
||||
@ -5356,16 +5392,21 @@ Possible values are:
|
||||
.(b
|
||||
.ta 13n
|
||||
TRUSTED verification via DANE succeeded.
|
||||
DANE_FAIL verification via DANE failed.
|
||||
DANE_TEMP verification via DANE failed temporarily.
|
||||
DANE_NOTLS DANE required but STARTTLS was not available.
|
||||
OK verification succeeded.
|
||||
NO no cert presented.
|
||||
NOT no cert requested.
|
||||
FAIL cert presented but could not be verified,
|
||||
e.g., the signing CA is missing.
|
||||
NONE STARTTLS has not been performed.
|
||||
CLEAR STARTTLS has been disabled internally for a clear text delivery attempt.
|
||||
CLEAR STARTTLS has been disabled internally
|
||||
for a clear text delivery attempt.
|
||||
TEMP temporary error occurred.
|
||||
PROTOCOL some protocol error occurred
|
||||
at the ESMTP level (not TLS).
|
||||
CONFIG tls_*_features failed due to a syntax error.
|
||||
SOFTWARE STARTTLS handshake failed,
|
||||
which is a fatal error for this session,
|
||||
the e-mail will be queued.
|
||||
@ -5670,7 +5711,7 @@ will fill the class
|
||||
.b $={VirtHosts}
|
||||
from an LDAP map lookup and
|
||||
.b $={MyClass}
|
||||
from a hash database map lookup of the
|
||||
from a hash database map lookup of the key
|
||||
.b foo .
|
||||
There is also a built-in schema that can be accessed by only specifying:
|
||||
.(b
|
||||
@ -5703,7 +5744,7 @@ Some classes have internal meaning to
|
||||
.nr ii 0.5i
|
||||
.\".ip $=b
|
||||
.\"A set of Content-Types that will not have the newline character
|
||||
.\"translated to CR-LF before encoding into base64 MIME.
|
||||
.\"translated to CRLF before encoding into base64 MIME.
|
||||
.\"The class can have major times
|
||||
.\"(e.g.,
|
||||
.\".q image )
|
||||
@ -5793,6 +5834,24 @@ file into a class, use
|
||||
FL/etc/passwd %[^:]
|
||||
.)b
|
||||
which reads every line up to the first colon.
|
||||
.sh 2 "E \*- Set or Propagate Environment Variables"
|
||||
.pp
|
||||
.b E
|
||||
configuration lines set or propagate environment variables into children.
|
||||
.(b F
|
||||
.b E \c
|
||||
.i name
|
||||
.)b
|
||||
will propagate the named variable from the environment when
|
||||
.i sendmail
|
||||
was invoked into any children it calls;
|
||||
.(b F
|
||||
.b E \c
|
||||
.i name =\c
|
||||
.i value
|
||||
.)b
|
||||
sets the named variable to the indicated value.
|
||||
Any variables not explicitly named will not be in the child environment.
|
||||
.sh 2 "M \*- Define Mailer"
|
||||
.pp
|
||||
Programs and interfaces to mailers
|
||||
@ -5819,7 +5878,7 @@ Path The pathname of the mailer
|
||||
Flags Special flags for this mailer
|
||||
Sender Rewriting set(s) for sender addresses
|
||||
Recipient Rewriting set(s) for recipient addresses
|
||||
recipients Maximum number of recipients per connection
|
||||
recipients Maximum number of recipients per envelope
|
||||
Argv An argument vector to pass to this mailer
|
||||
Eol The end-of-line string for this mailer
|
||||
Maxsize The maximum message length to this mailer
|
||||
@ -6146,7 +6205,7 @@ Do not apply
|
||||
.b FallbackMXhost
|
||||
either.
|
||||
.ip 1
|
||||
Don't send null characters ('\\0') to this mailer.
|
||||
Strip null characters ('\\0') when sending to this mailer.
|
||||
.ip 2
|
||||
Don't use ESMTP even if offered; this is useful for broken
|
||||
systems that offer ESMTP but fail on EHLO (without recovering
|
||||
@ -6187,7 +6246,7 @@ do
|
||||
7\(->8 bit MIME conversions.
|
||||
These conversions are limited to text/plain data.
|
||||
.ip :
|
||||
Check addresses to see if they begin
|
||||
Check addresses to see if they begin with
|
||||
.q :include: ;
|
||||
if they do, convert them to the
|
||||
.q *include*
|
||||
@ -6679,13 +6738,11 @@ If it does not appear in the
|
||||
.i timeout
|
||||
interval issue a warning.
|
||||
.ip AllowBogusHELO
|
||||
[no short name]
|
||||
If set, allow HELO SMTP commands that don't include a host name.
|
||||
Setting this violates RFC 1123 section 5.2.5,
|
||||
but is necessary to interoperate with several SMTP clients.
|
||||
If there is a value, it is still checked for legitimacy.
|
||||
.ip AuthMaxBits=\fIN\fP
|
||||
[no short name]
|
||||
Limit the maximum encryption strength for the security layer in
|
||||
SMTP AUTH (SASL). Default is essentially unlimited.
|
||||
This allows to turn off additional encryption in SASL if
|
||||
@ -6698,7 +6755,6 @@ Hence setting
|
||||
.b AuthMaxBits
|
||||
to 168 will disable any encryption in SASL.
|
||||
.ip AuthMechanisms
|
||||
[no short name]
|
||||
List of authentication mechanisms for AUTH (separated by spaces).
|
||||
The advertised list of authentication mechanisms will be the
|
||||
intersection of this list and the list of available mechanisms as
|
||||
@ -6706,7 +6762,6 @@ determined by the Cyrus SASL library.
|
||||
If STARTTLS is active, EXTERNAL will be added to this list.
|
||||
In that case, the value of {cert_subject} is used as authentication id.
|
||||
.ip AuthOptions
|
||||
[no short name]
|
||||
List of options for SMTP AUTH consisting of single characters
|
||||
with intervening white space or commas.
|
||||
.(b
|
||||
@ -6743,14 +6798,12 @@ The options 'a', 'c', 'd', 'f', 'p', and 'y' refer to properties of the
|
||||
selected SASL mechanisms.
|
||||
Explanations of these properties can be found in the Cyrus SASL documentation.
|
||||
.ip AuthRealm
|
||||
[no short name]
|
||||
The authentication realm that is passed to the Cyrus SASL library.
|
||||
If no realm is specified,
|
||||
.b $j
|
||||
is used.
|
||||
See also KNOWNBUGS.
|
||||
.ip BadRcptThrottle=\fIN\fP
|
||||
[no short name]
|
||||
If set and the specified number of recipients in a single SMTP
|
||||
transaction have been rejected, sleep for one second after each subsequent
|
||||
RCPT command in that transaction.
|
||||
@ -6761,12 +6814,10 @@ Set the blank substitution character to
|
||||
Unquoted spaces in addresses are replaced by this character.
|
||||
Defaults to space (i.e., no change is made).
|
||||
.ip CACertPath
|
||||
[no short name]
|
||||
Path to directory with certificates of CAs.
|
||||
This directory directory must contain the hashes of each CA certificate
|
||||
as filenames (or as links to them).
|
||||
.ip CACertFile
|
||||
[no short name]
|
||||
File containing one or more CA certificates;
|
||||
see section about STARTTLS for more information.
|
||||
.ip CertFingerprintAlgorithm
|
||||
@ -6811,19 +6862,16 @@ and subtracted from the priority.
|
||||
Thus, messages with a higher Priority: will be favored.
|
||||
Defaults to 1800.
|
||||
.ip ClientCertFile
|
||||
[no short name]
|
||||
File containing the certificate of the client, i.e., this certificate
|
||||
is used when
|
||||
.i sendmail
|
||||
acts as client (for STARTTLS).
|
||||
.ip ClientKeyFile
|
||||
[no short name]
|
||||
File containing the private key belonging to the client certificate
|
||||
(for STARTTLS if
|
||||
.i sendmail
|
||||
runs as client).
|
||||
.ip ClientPortOptions=\fIoptions\fP
|
||||
[no short name]
|
||||
Set client SMTP options.
|
||||
The options are
|
||||
.i key=value
|
||||
@ -6886,7 +6934,6 @@ Options can be cleared by preceding them with a minus sign.
|
||||
It is also possible to specify numerical values, e.g.,
|
||||
.b -0x0010 .
|
||||
.ip ColonOkInAddr
|
||||
[no short name]
|
||||
If set, colons are acceptable in e-mail addresses
|
||||
(e.g.,
|
||||
.q host:user ).
|
||||
@ -6935,11 +6982,9 @@ and avoid using up excessive resources
|
||||
on the other end.
|
||||
The default is five minutes.
|
||||
.ip ConnectOnlyTo=\fIaddress\fP
|
||||
[no short name]
|
||||
This can be used to
|
||||
override the connection address (for testing purposes).
|
||||
.ip ConnectionRateThrottle=\fIN\fP
|
||||
[no short name]
|
||||
If set to a positive value,
|
||||
allow no more than
|
||||
.i N
|
||||
@ -6948,12 +6993,10 @@ This is intended to flatten out peaks
|
||||
and allow the load average checking to cut in.
|
||||
Defaults to zero (no limits).
|
||||
.ip ConnectionRateWindowSize=\fIN\fP
|
||||
[no short name]
|
||||
Define the length of the interval for which
|
||||
the number of incoming connections is maintained.
|
||||
The default is 60 seconds.
|
||||
.ip ControlSocketName=\fIname\fP
|
||||
[no short name]
|
||||
Name of the control socket for daemon management.
|
||||
A running
|
||||
.i sendmail
|
||||
@ -6974,13 +7017,11 @@ and the load average of the machine expressed as an integer.
|
||||
If not set, no control socket will be available.
|
||||
Solaris and pre-4.4BSD kernel users should see the note in sendmail/README .
|
||||
.ip CRLFile=\fIname\fP
|
||||
[no short name]
|
||||
Name of file that contains certificate
|
||||
revocation status, useful for X.509v3 authentication.
|
||||
Note: if a CRLFile is specified but the file is unusable,
|
||||
STARTTLS is disabled.
|
||||
.ip CRLPath=\fIname\fP
|
||||
[no short name]
|
||||
Name of directory that contains hashes pointing to
|
||||
certificate revocation status files.
|
||||
Symbolic links can be generated with the following
|
||||
@ -7142,7 +7183,6 @@ The modifier ``O'' causes sendmail to ignore a socket
|
||||
if it can't be opened.
|
||||
This applies to failures from the socket(2) and bind(2) calls.
|
||||
.ip DefaultAuthInfo
|
||||
[no short name]
|
||||
Filename that contains default authentication information for outgoing
|
||||
connections. This file must contain the user id, the authorization id,
|
||||
the password (plain text), the realm and the list of mechanisms to use
|
||||
@ -7162,7 +7202,6 @@ will complain).
|
||||
Use the authinfo ruleset instead which provides more control over
|
||||
the usage of the data anyway.
|
||||
.ip DefaultCharSet=\fIcharset\fP
|
||||
[no short name]
|
||||
When a message that has 8-bit characters but is not in MIME format
|
||||
is converted to MIME
|
||||
(see the EightBitMode option)
|
||||
@ -7174,7 +7213,6 @@ If this option is not set, the value
|
||||
.q unknown-8bit
|
||||
is used.
|
||||
.ip DataFileBufferSize=\fIthreshold\fP
|
||||
[no short name]
|
||||
Set the
|
||||
.i threshold ,
|
||||
in bytes,
|
||||
@ -7183,7 +7221,6 @@ queue data file
|
||||
becomes disk-based.
|
||||
The default is 4096 bytes.
|
||||
.ip DeadLetterDrop=\fIfile\fP
|
||||
[no short name]
|
||||
Defines the location of the system-wide dead.letter file,
|
||||
formerly hardcoded to /usr/tmp/dead.letter.
|
||||
If this option is not set (the default),
|
||||
@ -7224,14 +7261,12 @@ option has been combined into the
|
||||
option.
|
||||
.)f
|
||||
.ip DelayLA=\fILA\fP
|
||||
[no short name]
|
||||
When the system load average exceeds
|
||||
.i LA ,
|
||||
.i sendmail
|
||||
will sleep for one second on most SMTP commands and
|
||||
before accepting connections.
|
||||
.ip DeliverByMin=\fItime\fP
|
||||
[no short name]
|
||||
Set minimum time for Deliver By SMTP Service Extension (RFC 2852).
|
||||
If 0, no time is listed, if less than 0, the extension is not offered,
|
||||
if greater than 0, it is listed as minimum time
|
||||
@ -7260,7 +7295,6 @@ Note: for internal reasons,
|
||||
if a milter is enabled which can reject or delete recipients.
|
||||
In that case the mode will be changed to ``b''.
|
||||
.ip DialDelay=\fIsleeptime\fP
|
||||
[no short name]
|
||||
Dial-on-demand network connections can see timeouts
|
||||
if a connection is opened before the call is set up.
|
||||
If this is set to an interval and a connection times out
|
||||
@ -7287,7 +7321,6 @@ is either "CC f" if the option
|
||||
is used or "c u" otherwise.
|
||||
Note that only the "CC", "c", "f", and "u" flags are checked.
|
||||
.ip DontBlameSendmail=\fIoption,option,...\fP
|
||||
[no short name]
|
||||
In order to avoid possible cracking attempts
|
||||
caused by world- and group-writable files and directories,
|
||||
.i sendmail
|
||||
@ -7304,7 +7337,6 @@ The details of these flags are described above.
|
||||
.\"XXX should have more here!!! XXX
|
||||
.b "Use of this option is not recommended."
|
||||
.ip DontExpandCnames
|
||||
[no short name]
|
||||
The standards say that all host addresses used in a mail message
|
||||
must be fully canonical.
|
||||
For example, if your host is named
|
||||
@ -7322,7 +7354,6 @@ so the behavior may become acceptable.
|
||||
Please note that hosts downstream may still rewrite the address
|
||||
to be the true canonical name however.
|
||||
.ip DontInitGroups
|
||||
[no short name]
|
||||
If set,
|
||||
.i sendmail
|
||||
will avoid using the initgroups(3) call.
|
||||
@ -7334,7 +7365,6 @@ will be their primary group (the one in the password file),
|
||||
which will make file access permissions somewhat more restrictive.
|
||||
Has no effect on systems that don't have group lists.
|
||||
.ip DontProbeInterfaces
|
||||
[no short name]
|
||||
.i Sendmail
|
||||
normally finds the names of all interfaces active on your machine
|
||||
when it starts up
|
||||
@ -7375,7 +7405,6 @@ and the mail will be sent to the first address in the route,
|
||||
even if later addresses are known.
|
||||
This may be useful if you are caught behind a firewall.
|
||||
.ip DoubleBounceAddress=\fIerror-address\fP
|
||||
[no short name]
|
||||
If an error occurs when sending an error message,
|
||||
send the error report
|
||||
(termed a
|
||||
@ -7483,7 +7512,7 @@ background delivery.
|
||||
If specified, the
|
||||
.i fallbackhost
|
||||
acts like a very low priority MX
|
||||
on every host.
|
||||
on a host.
|
||||
MX records will be looked up for this host,
|
||||
unless the name is surrounded by square brackets.
|
||||
This is intended to be used by sites with poor network connectivity.
|
||||
@ -7493,12 +7522,11 @@ also go to the FallbackMXhost.
|
||||
.ip FallBackSmartHost=\fIhostname\fP
|
||||
If specified, the
|
||||
.i FallBackSmartHost
|
||||
will be used in a last-ditch effort for each host.
|
||||
will be used in a last-ditch effort for a host.
|
||||
This is intended to be used by sites with "fake internal DNS",
|
||||
e.g., a company whose DNS accurately reflects the world
|
||||
inside that company's domain but not outside.
|
||||
.ip FastSplit
|
||||
[no short name]
|
||||
If set to a value greater than zero (the default is one),
|
||||
it suppresses the MX lookups on addresses
|
||||
when they are initially sorted, i.e., for the first delivery attempt.
|
||||
@ -7538,7 +7566,6 @@ and then in
|
||||
.i ~username /.forward
|
||||
(but only if the first file does not exist).
|
||||
.ip HeloName=\fIname\fP
|
||||
[no short name]
|
||||
Set the name to be used for HELO/EHLO (instead of $j).
|
||||
.ip HelpFile=\fIfile\fP
|
||||
[H]
|
||||
@ -7555,7 +7582,6 @@ To avoid providing this information to a client specify an empty file.
|
||||
If an outgoing mailer is marked as being expensive,
|
||||
don't connect immediately.
|
||||
.ip HostsFile=\fIpath\fP
|
||||
[no short name]
|
||||
The path to the hosts database,
|
||||
normally
|
||||
.q /etc/hosts .
|
||||
@ -7573,7 +7599,6 @@ that is under the control of the system
|
||||
.i gethostbyname (3)
|
||||
routine.
|
||||
.ip HostStatusDirectory=\fIpath\fP
|
||||
[no short name]
|
||||
The location of the long term host status information.
|
||||
When set,
|
||||
information about the status of hosts
|
||||
@ -7592,16 +7617,15 @@ A suggested value for sites desiring persistent host status is
|
||||
(i.e., a subdirectory of the queue directory).
|
||||
.ip IgnoreDots
|
||||
[i]
|
||||
Ignore dots in incoming messages.
|
||||
This is always disabled (that is, dots are always accepted)
|
||||
when reading SMTP mail.
|
||||
Do not treat leading dots in incoming messages in a special way,
|
||||
e.g., as end of a message if it is the only character in a line.
|
||||
This is always disabled when reading SMTP mail.
|
||||
.ip InputMailFilters=\fIname,name,...\fP
|
||||
A comma separated list of filters which determines which filters
|
||||
(see the "X \*- Mail Filter (Milter) Definitions" section)
|
||||
and the invocation sequence are contacted for incoming SMTP messages.
|
||||
If none are set, no filters will be contacted.
|
||||
.ip LDAPDefaultSpec=\fIspec\fP
|
||||
[no short name]
|
||||
Sets a default map specification for LDAP maps.
|
||||
The value should only contain LDAP specific settings
|
||||
such as
|
||||
@ -7625,14 +7649,12 @@ The
|
||||
.b \-M
|
||||
flag is preferred.
|
||||
.ip MailboxDatabase
|
||||
[no short name]
|
||||
Type of lookup to find information about local mailboxes,
|
||||
defaults to ``pw'' which uses
|
||||
.i getpwnam .
|
||||
Other types can be introduced by adding them to the source code,
|
||||
see libsm/mbdb.c for details.
|
||||
.ip UseMSP
|
||||
[no short name]
|
||||
Use as mail submission program, i.e.,
|
||||
allow group writable queue files
|
||||
if the group is the same as that of a set-group-ID sendmail binary.
|
||||
@ -7653,10 +7675,8 @@ This also requires that MATCHGECOS
|
||||
be turned on during compilation.
|
||||
This option is not recommended.
|
||||
.ip MaxAliasRecursion=\fIN\fP
|
||||
[no short name]
|
||||
The maximum depth of alias recursion (default: 10).
|
||||
.ip MaxDaemonChildren=\fIN\fP
|
||||
[no short name]
|
||||
If set,
|
||||
.i sendmail
|
||||
will refuse connections when it has more than
|
||||
@ -7676,7 +7696,6 @@ other than background must be used.
|
||||
If not set, there is no limit to the number of children --
|
||||
that is, the system load average controls this.
|
||||
.ip MaxHeadersLength=\fIN\fP
|
||||
[no short name]
|
||||
If set to a value greater than zero it specifies
|
||||
the maximum length of the sum of all headers.
|
||||
This can be used to prevent a denial of service attack.
|
||||
@ -7689,7 +7708,6 @@ Messages that have been processed more than
|
||||
times are assumed to be in a loop and are rejected.
|
||||
Defaults to 25.
|
||||
.ip MaxMessageSize=\fIN\fP
|
||||
[no short name]
|
||||
Specify the maximum message size
|
||||
to be advertised in the ESMTP EHLO response.
|
||||
Messages larger than this will be rejected.
|
||||
@ -7698,7 +7716,6 @@ that value will be listed in the SIZE response,
|
||||
otherwise SIZE is advertised in the ESMTP EHLO response
|
||||
without a parameter.
|
||||
.ip MaxMimeHeaderLength=\fIN[/M]\fP
|
||||
[no short name]
|
||||
Sets the maximum length of certain MIME header field values to
|
||||
.i N
|
||||
characters.
|
||||
@ -7724,7 +7741,6 @@ for the number of
|
||||
commands, see Section
|
||||
"Measures against Denial of Service Attacks".
|
||||
.ip MaxQueueChildren=\fIN\fP
|
||||
[no short name]
|
||||
When set, this limits the number of concurrent queue runner processes to
|
||||
.i N.
|
||||
This helps to control the amount of system resources used when processing
|
||||
@ -7748,7 +7764,6 @@ imposed by
|
||||
This discrepancy can be large if some queue runners have to wait
|
||||
for a slow server and if short intervals are used.
|
||||
.ip MaxQueueRunSize=\fIN\fP
|
||||
[no short name]
|
||||
The maximum number of jobs that will be processed
|
||||
in a single queue run.
|
||||
If not set, there is no limit on the size.
|
||||
@ -7773,14 +7788,12 @@ then only
|
||||
.b N
|
||||
entries are printed per queue group.
|
||||
.ip MaxRecipientsPerMessage=\fIN\fP
|
||||
[no short name]
|
||||
The maximum number of recipients that will be accepted per message
|
||||
in an SMTP transaction.
|
||||
Note: setting this too low can interfere with sending mail from
|
||||
MUAs that use SMTP for initial submission.
|
||||
If not set, there is no limit on the number of recipients per envelope.
|
||||
.ip MaxRunnersPerQueue=\fIN\fP
|
||||
[no short name]
|
||||
This sets the default maximum number of queue runners for queue groups.
|
||||
Up to
|
||||
.i N
|
||||
@ -7799,7 +7812,6 @@ even if I am in an alias expansion.
|
||||
This option is deprecated
|
||||
and will be removed from a future version.
|
||||
.ip Milter
|
||||
[no short name]
|
||||
This option has several sub(sub)options.
|
||||
The names of the suboptions are separated by dots.
|
||||
At the first level the following options are available:
|
||||
@ -7840,14 +7852,12 @@ gives a 452 response
|
||||
to the MAIL command.
|
||||
This invites the sender to try again later.
|
||||
.ip MaxQueueAge=\fIage\fP
|
||||
[no short name]
|
||||
If this is set to a value greater than zero,
|
||||
entries in the queue will be retried during a queue run
|
||||
only if the individual retry time has been reached
|
||||
which is doubled for each attempt.
|
||||
The maximum retry time is limited by the specified value.
|
||||
.ip MinQueueAge=\fIage\fP
|
||||
[no short name]
|
||||
Don't process any queued jobs
|
||||
that have been in the queue less than the indicated time interval.
|
||||
This is intended to allow you to get responsiveness
|
||||
@ -7859,7 +7869,6 @@ This option is ignored for queue runs that select a subset
|
||||
of the queue, i.e.,
|
||||
.q \-q[!][I|R|S|Q][string]
|
||||
.ip MustQuoteChars=\fIs\fP
|
||||
[no short name]
|
||||
Sets the list of characters that must be quoted if used in a full name
|
||||
that is in the phrase part of a ``phrase <address>'' syntax.
|
||||
The default is ``\'.''.
|
||||
@ -7871,11 +7880,9 @@ O MustQuoteChars=.
|
||||
.)b
|
||||
Moreover, relaxed header signing should be used for DKIM signatures.
|
||||
.ip NiceQueueRun
|
||||
[no short name]
|
||||
The priority of queue runners (nice(3)).
|
||||
This value must be greater or equal zero.
|
||||
.ip NoRecipientAction
|
||||
[no short name]
|
||||
The action to take when you receive a message that has no valid
|
||||
recipient headers (To:, Cc:, Bcc:, or Apparently-To: \(em
|
||||
the last included for back compatibility with old
|
||||
@ -7933,7 +7940,6 @@ are always operators.
|
||||
Note that OperatorChars must be set in the
|
||||
configuration file before any rulesets.
|
||||
.ip PidFile=\fIfilename\fP
|
||||
[no short name]
|
||||
Filename of the pid file.
|
||||
(default is _PATH_SENDMAILPID).
|
||||
The
|
||||
@ -8029,7 +8035,6 @@ Authentication Warnings add warnings about various conditions
|
||||
that may indicate attempts to spoof the mail system,
|
||||
such as using a non-standard queue directory.
|
||||
.ip ProcessTitlePrefix=\fIstring\fP
|
||||
[no short name]
|
||||
Prefix the process title shown on 'ps' listings with
|
||||
.i string .
|
||||
The
|
||||
@ -8092,12 +8097,10 @@ Defaults to 8 multiplied by
|
||||
the number of processors online on the system
|
||||
(if that can be determined).
|
||||
.ip QueueFileMode=\fImode\fP
|
||||
[no short name]
|
||||
Default permissions for queue files (octal).
|
||||
If not set, sendmail uses 0600 unless its real
|
||||
and effective uid are different in which case it uses 0644.
|
||||
.ip QueueSortOrder=\fIalgorithm\fP
|
||||
[no short name]
|
||||
Sets the
|
||||
.i algorithm
|
||||
used for sorting the queue.
|
||||
@ -8142,7 +8145,6 @@ Use that form instead of the
|
||||
.q QueueTimeout
|
||||
form.
|
||||
.ip RandFile
|
||||
[no short name]
|
||||
Name of file containing random data or the name of the UNIX socket
|
||||
if EGD is used.
|
||||
A (required) prefix "egd:" or "file:" specifies the type.
|
||||
@ -8191,7 +8193,6 @@ Notice: it might be necessary to apply the same (or similar) options to
|
||||
.i submit.cf
|
||||
too.
|
||||
.ip RequiresDirfsync
|
||||
[no short name]
|
||||
This option can be used to override the compile time flag
|
||||
.b REQUIRES_DIR_FSYNC
|
||||
at runtime by setting it to
|
||||
@ -8205,14 +8206,12 @@ it is enabled by default for Linux.
|
||||
According to some information this flag is not needed
|
||||
anymore for kernel 2.4.16 and newer.
|
||||
.ip RrtImpliesDsn
|
||||
[no short name]
|
||||
If this option is set, a
|
||||
.q Return-Receipt-To:
|
||||
header causes the request of a DSN, which is sent to
|
||||
the envelope sender as required by RFC 1891,
|
||||
not to the address given in the header.
|
||||
.ip RunAsUser=\fIuser\fP
|
||||
[no short name]
|
||||
The
|
||||
.i user
|
||||
parameter may be a user name
|
||||
@ -8276,7 +8275,6 @@ Defaults to 12 multiplied by
|
||||
the number of processors online on the system
|
||||
(if that can be determined).
|
||||
.ip RejectLogInterval=\fItimeout\fP
|
||||
[no short name]
|
||||
Log interval when refusing connections for this long
|
||||
(default: 3h).
|
||||
.ip RetryFactor=\fIfact\fP
|
||||
@ -8292,7 +8290,6 @@ In most environments this should be positive,
|
||||
since hosts that are down are all too often down for a long time.
|
||||
Defaults to 90000.
|
||||
.ip SafeFileEnvironment=\fIdir\fP
|
||||
[no short name]
|
||||
If this option is set,
|
||||
.i sendmail
|
||||
will do a
|
||||
@ -8332,12 +8329,10 @@ will not return the DSN keyword in response to an EHLO
|
||||
and will not do Delivery Status Notification processing as described in
|
||||
RFC 1891.
|
||||
.ip ServerCertFile
|
||||
[no short name]
|
||||
File containing the certificate of the server, i.e., this certificate
|
||||
is used when sendmail acts as server
|
||||
(used for STARTTLS).
|
||||
.ip ServerKeyFile
|
||||
[no short name]
|
||||
File containing the private key belonging to the server certificate
|
||||
(used for STARTTLS).
|
||||
.ip ServerSSLOptions
|
||||
@ -8357,7 +8352,6 @@ Options can be cleared by preceding them with a minus sign.
|
||||
It is also possible to specify numerical values, e.g.,
|
||||
.b -0x0010 .
|
||||
.ip ServiceSwitchFile=\fIfilename\fP
|
||||
[no short name]
|
||||
If your host operating system has a service switch abstraction
|
||||
(e.g., /etc/nsswitch.conf on Solaris
|
||||
or /etc/svc.conf on Ultrix and DEC OSF/1)
|
||||
@ -8397,7 +8391,6 @@ The default file is
|
||||
Strip input to seven bits for compatibility with old systems.
|
||||
This shouldn't be necessary.
|
||||
.ip SharedMemoryKey
|
||||
[no short name]
|
||||
Key to use for shared memory segment;
|
||||
if not set (or 0), shared memory will not be used.
|
||||
If set to
|
||||
@ -8417,7 +8410,6 @@ This allows for more efficient program execution, since only
|
||||
one process needs to update the data instead of each individual
|
||||
process gathering the data each time it is required.
|
||||
.ip SharedMemoryKeyFile
|
||||
[no short name]
|
||||
If
|
||||
.b SharedMemoryKey
|
||||
is set to
|
||||
@ -8425,13 +8417,11 @@ is set to
|
||||
then the automatically selected shared memory key will be stored
|
||||
in the specified file.
|
||||
.ip SingleLineFromHeader
|
||||
[no short name]
|
||||
If set, From: lines that have embedded newlines are unwrapped
|
||||
onto one line.
|
||||
This is to get around a botch in Lotus Notes
|
||||
that apparently cannot understand legally wrapped RFC 822 headers.
|
||||
.ip SingleThreadDelivery
|
||||
[no short name]
|
||||
If set, a client machine will never try to open two SMTP connections
|
||||
to a single server machine at the same time,
|
||||
even in different processes.
|
||||
@ -8532,7 +8522,6 @@ PostMilter is useful only when
|
||||
is running as an SMTP server; in all other situations it
|
||||
acts the same as True.
|
||||
.ip TLSFallbacktoClear
|
||||
[no short name]
|
||||
If set,
|
||||
.i sendmail
|
||||
immediately tries an outbound connection again without STARTTLS
|
||||
@ -8548,7 +8537,6 @@ Hence such requirements will cause an error on a retry without STARTTLS.
|
||||
Therefore they should only trigger a temporary failure so the connection
|
||||
is later on tried again.
|
||||
.ip TLSSrvOptions
|
||||
[no short name]
|
||||
List of options for SMTP STARTTLS for the server
|
||||
consisting of single characters
|
||||
with intervening white space or commas.
|
||||
@ -8587,7 +8575,6 @@ the TZ environment variable is cleared (so the system default is used);
|
||||
if set but null, the user's TZ variable is used,
|
||||
and if set and non-null the TZ variable is set to this value.
|
||||
.ip TrustedUser=\fIuser\fP
|
||||
[no short name]
|
||||
The
|
||||
.i user
|
||||
parameter may be a user name
|
||||
@ -8633,7 +8620,6 @@ Defaults to
|
||||
Don't change this unless your system uses a different UNIX mailbox format
|
||||
(very unlikely).
|
||||
.ip UnsafeGroupWrites
|
||||
[no short name]
|
||||
If set (default),
|
||||
:include: and .forward files that are group writable are considered
|
||||
.q unsafe ,
|
||||
@ -8645,7 +8631,6 @@ Note: use
|
||||
.b DontBlameSendmail
|
||||
instead; this option is deprecated.
|
||||
.ip UseCompressedIPv6Addresses
|
||||
[no short name]
|
||||
If set, the compressed format of IPv6 addresses,
|
||||
such as IPV6:::1, will be used,
|
||||
instead of the uncompressed format,
|
||||
@ -8699,7 +8684,6 @@ SMTP command with a suitable
|
||||
.b PrivacyOptions
|
||||
setting.
|
||||
.ip XscriptFileBufferSize=\fIthreshold\fP
|
||||
[no short name]
|
||||
Set the
|
||||
.i threshold ,
|
||||
in bytes,
|
||||
@ -9004,7 +8988,7 @@ For example, the rule
|
||||
.ta 1.5i
|
||||
R$\- ! $+ $: $(uucp $1 $@ $2 $: $2 @ $1 . UUCP $)
|
||||
.)b
|
||||
Looks up the UUCP name in a (user defined) UUCP map;
|
||||
looks up the UUCP name in a (user defined) UUCP map;
|
||||
if not found it turns it into
|
||||
.q \&.UUCP
|
||||
form.
|
||||
@ -10226,7 +10210,7 @@ the new version of the DBM library
|
||||
that allows multiple databases will be used.
|
||||
If neither CDB, NDBM, nor NEWDB are set,
|
||||
a much less efficient method of alias lookup is used.
|
||||
.ip CWDB
|
||||
.ip CDB
|
||||
If set, use the cdb (tinycdb) package.
|
||||
.ip NEWDB
|
||||
If set, use the new database package from Berkeley (from 4.4BSD).
|
||||
@ -11251,12 +11235,30 @@ as well as
|
||||
{auth_authen} and {auth_author}.
|
||||
.sh 2 "DANE"
|
||||
.pp
|
||||
Initial support for DANE (see RFC 7672 et.al.)
|
||||
Support for DANE (see RFC 7672 et.al.)
|
||||
is available if
|
||||
.i sendmail
|
||||
is compiled with the option
|
||||
.b DANE .
|
||||
Only TLSA RR 3-1-x (DANE-EE) is currently implemented.
|
||||
If OpenSSL 1.1.1 or at least 3.0.0 are used,
|
||||
then full DANE support for DANE-EE and DANE-TA
|
||||
(as required by RFC 7672)
|
||||
is available via the functions
|
||||
provided by those OpenSSL versions
|
||||
(run
|
||||
.(b
|
||||
sendmail -bt -d0.3 < /dev/null
|
||||
.)b
|
||||
and check that HAVE_SSL_CTX_dane_enable is in the output),
|
||||
otherwise support for TLSA RR 3-1-x
|
||||
is implemented directly in
|
||||
.i sendmail .
|
||||
Note: if OpenSSL functions related to DANE cause a failure,
|
||||
then the macro
|
||||
.b ${verify}
|
||||
is set to
|
||||
.b DANE_TEMP .
|
||||
This also applies if TLS cannot be initialized at all.
|
||||
The option
|
||||
.(b
|
||||
O DANE=true
|
||||
@ -11270,8 +11272,10 @@ to
|
||||
.(b
|
||||
O ResolverOptions
|
||||
.)b
|
||||
This requires a (preferrably local)
|
||||
validating DNS resolver which supports those options.
|
||||
This requires a DNSSEC-validating recursive resolver
|
||||
which supports those options.
|
||||
The resolver must be reachable via a trusted connection,
|
||||
hence it is best to run it locally.
|
||||
|
||||
If the client finds a usable TLSA RR and the check
|
||||
succeeds the macro
|
||||
@ -11281,9 +11285,8 @@ is set to
|
||||
All non-DNS maps are considered
|
||||
.i secure
|
||||
just like DNS lookups with DNSSEC.
|
||||
Be aware that the implementation might not handle all
|
||||
error conditions as required by the RFCs.
|
||||
Moreover, TLSA RRs are not looked up for some features,
|
||||
Be aware that
|
||||
TLSA RRs are not looked up for some features,
|
||||
e.g.,
|
||||
.i FallBackSmartHost .
|
||||
.sh 2 "EAI"
|
||||
@ -11943,6 +11946,8 @@ and
|
||||
.ip Z
|
||||
The original envelope id (from the ESMTP transaction).
|
||||
For Deliver Status Notifications only.
|
||||
.ip !
|
||||
Information for Deliver-By SMTP extension.
|
||||
.pp
|
||||
As an example,
|
||||
the following is a queue file sent to
|
||||
|
@ -117,7 +117,7 @@ typedef int (*db_get_func) __P((SMDB_DATABASE *db,
|
||||
** key -- The key to use.
|
||||
** data -- The data to store.
|
||||
** flags -- put options:
|
||||
** SMDBF_NO_OVERWRITE - Return an error if key alread
|
||||
** SMDBF_NO_OVERWRITE - Return an error if key already
|
||||
** exists.
|
||||
**
|
||||
** Returns:
|
||||
|
@ -118,6 +118,7 @@ extern bool filechanged __P((char *, int, struct stat *));
|
||||
#define DBS_WORLDWRITABLEINCLUDEFILE 40
|
||||
#define DBS_GROUPREADABLEKEYFILE 41
|
||||
#define DBS_GROUPREADABLEAUTHINFOFILE 42
|
||||
#define DBS_CERTOWNER 43
|
||||
|
||||
/* struct defining such things */
|
||||
struct dbsval
|
||||
|
@ -473,8 +473,8 @@ typedef int pid_t;
|
||||
# ifndef HASGETUSERSHELL
|
||||
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps pre-2.7 */
|
||||
# endif
|
||||
# if SOLARIS < 21200
|
||||
# define SIGWAIT_TAKES_1_ARG 1 /* S12 moves to UNIX V7 semantic */
|
||||
# if SOLARIS < 21140
|
||||
# define SIGWAIT_TAKES_1_ARG 1 /* S11.4 moves to UNIX V7 semantic */
|
||||
# endif
|
||||
|
||||
# else /* SOLARIS */
|
||||
@ -1575,9 +1575,11 @@ extern void *malloc();
|
||||
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,36)) && !defined(HASFCHMOD)
|
||||
# define HASFCHMOD 1 /* fchmod(2) */
|
||||
# endif
|
||||
# if (__GLIBC__ >= 2 && __GLIBC_MINOR__ >= 19) && !defined(HAS_GETHOSTBYNAME2)
|
||||
# define HAS_GETHOSTBYNAME2 1
|
||||
# endif
|
||||
# endif /* __linux__ */
|
||||
|
||||
|
||||
/*
|
||||
** DELL SVR4 Issue 2.2, and others
|
||||
** From Kimmo Suominen <kim@grendel.lut.fi>
|
||||
|
@ -17,6 +17,7 @@
|
||||
** before.
|
||||
*/
|
||||
|
||||
#define SM_FD_CLR(fd, pfdset) FD_CLR(fd, pfdset)
|
||||
#define SM_FD_SET(fd, pfdset) FD_SET(fd, pfdset)
|
||||
#define SM_FD_ISSET(fd, pfdset) FD_ISSET(fd, pfdset)
|
||||
#define SM_FD_SETSIZE FD_SETSIZE
|
||||
|
@ -89,4 +89,8 @@ typedef unsigned int SM_ATOMIC_UINT_T;
|
||||
# define _FFR_8BITENVADDR 1
|
||||
#endif
|
||||
|
||||
#if _FFR_HAPROXY && !defined(_FFR_XCNCT)
|
||||
# define _FFR_XCNCT 1
|
||||
#endif
|
||||
|
||||
#endif /* SM_GEN_H */
|
||||
|
@ -27,6 +27,7 @@ extern int xleni __P((const char *));
|
||||
|
||||
# if USE_EAI
|
||||
extern bool asciistr __P((const char *));
|
||||
extern bool asciinstr __P((const char *, size_t));
|
||||
extern int uxtext_unquote __P((const char *, char *, int));
|
||||
extern char *sm_lowercase __P((const char *));
|
||||
extern bool utf8_valid __P((const char *, size_t));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 2021 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
@ -10,13 +10,10 @@
|
||||
#ifndef SM_NOTIFY_H
|
||||
#define SM_NOTIFY_H
|
||||
|
||||
/* microseconds */
|
||||
#define SM_MICROS 1000000L
|
||||
|
||||
int sm_notify_init __P((int));
|
||||
int sm_notify_start __P((bool, int));
|
||||
int sm_notify_stop __P((bool, int));
|
||||
int sm_notify_rcv __P((char *, size_t, long));
|
||||
int sm_notify_snd __P((char *, size_t));
|
||||
|
||||
#endif /* ! SM_MSG_H */
|
||||
#endif /* ! SM_NOTIFY_H */
|
||||
|
@ -18,20 +18,6 @@
|
||||
|
||||
#define SM_OS_NAME "openbsd"
|
||||
|
||||
/*
|
||||
** Temporary HACK for newer icu4c versions which include stdbool.h:
|
||||
** pretend that it is already included
|
||||
** otherwise compilation will break because bool is then
|
||||
** redefined between the prototype declaration and
|
||||
** the function definition, e.g.,
|
||||
** lowercase.c: error: conflicting types for 'asciistr'
|
||||
** ../../include/sm/ixlen.h:29:13: note: previous declaration is here
|
||||
*/
|
||||
|
||||
#if USE_EAI && !SM_CONF_STDBOOL_H
|
||||
# define _STDBOOL_H_ 1
|
||||
#endif
|
||||
|
||||
#define SM_CONF_SYS_CDEFS_H 1
|
||||
#ifndef SM_CONF_SHM
|
||||
# define SM_CONF_SHM 1
|
||||
|
@ -163,6 +163,8 @@ extern void *
|
||||
sm_rpool_malloc __P((
|
||||
SM_RPOOL_T *_rpool,
|
||||
size_t _size));
|
||||
# define sm_rpool_malloc_tagged(rpool, size, file, line, group) sm_rpool_malloc(rpool, size)
|
||||
# define sm_rpool_malloc_tagged_x(rpool, size, file, line, group) sm_rpool_malloc_x(rpool, size)
|
||||
# endif /* SM_HEAP_CHECK */
|
||||
|
||||
#if DO_NOT_USE_STRCPY
|
||||
|
@ -15,6 +15,7 @@ the milter API.
|
||||
Note: if you want to write a milter in Java, then see
|
||||
http://sendmail-jilter.sourceforge.net/
|
||||
|
||||
|
||||
+----------------+
|
||||
| SECURITY HINTS |
|
||||
+----------------+
|
||||
@ -26,6 +27,7 @@ if really necessary. A milter should probably check first whether
|
||||
it runs as root and refuse to start in that case. libmilter will
|
||||
not unlink a socket when running as root.
|
||||
|
||||
|
||||
+----------------------+
|
||||
| CONFIGURATION MACROS |
|
||||
+----------------------+
|
||||
@ -36,6 +38,7 @@ features of the C compiler and standard C libraries.
|
||||
SM_CONF_POLL
|
||||
Set to 1 if poll(2) should be used instead of select(2).
|
||||
|
||||
|
||||
+-------------------+
|
||||
| BUILDING A FILTER |
|
||||
+-------------------+
|
||||
|
@ -60,7 +60,7 @@ returns to <CODE>MESSAGE</CODE>.
|
||||
For each of N connections
|
||||
{
|
||||
For each filter
|
||||
egotiate MTA/milter capabilities/requirements (<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>)
|
||||
negotiate MTA/milter capabilities/requirements (<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>)
|
||||
For each filter
|
||||
process connection (<A HREF="xxfi_connect.html">xxfi_connect</A>)
|
||||
For each filter
|
||||
|
@ -76,13 +76,18 @@ By default, the following macros are valid in the given contexts:
|
||||
<TR><TD>xxfi_eom</TD> <TD>msg_id</TD></TR>
|
||||
</TABLE>
|
||||
<P>
|
||||
All macros stay in effect from the point they are received
|
||||
until the end of the connection for the first two sets,
|
||||
the end of the message for the third (xxfi_envfrom) and last (xxfi_eom),
|
||||
and just for each recipient for xxfi_envrcpt.
|
||||
All macros stay in effect from the point they are received until
|
||||
<UL>
|
||||
<LI>the end of the connection for the first two sets,
|
||||
<LI>just for each recipient for xxfi_envrcpt.
|
||||
<LI>and the end of the message for the rest.
|
||||
</UL>
|
||||
<P>
|
||||
The macro list can be changed using the confMILTER_MACROS_* options in
|
||||
sendmail.mc.
|
||||
The macro list can be changed using
|
||||
the confMILTER_MACROS_* options in sendmail.mc
|
||||
or via the
|
||||
<A HREF="smfi_setsymlist.html">smfi_setsymlist</A>
|
||||
function.
|
||||
The scopes of such macros will be determined by when they are set by sendmail.
|
||||
For descriptions of macros' values,
|
||||
please see the
|
||||
|
@ -45,7 +45,7 @@ body.
|
||||
<TD>Opaque context structure.
|
||||
</TD></TR>
|
||||
<TR valign="top"><TD>bodyp</TD>
|
||||
<TD>A pointer to the start of the new body data, which does not have to be null-terminated. If bodyp is NULL, it is treated as having length == 0. Body data should be in CR/LF form.
|
||||
<TD>A pointer to the start of the new body data, which does not have to be null-terminated. If bodyp is NULL, it is treated as having length == 0. Body data should be in CRLF form.
|
||||
</TD></TR>
|
||||
<TR valign="top"><TD>bodylen</TD>
|
||||
<TD>The number of data bytes pointed to by bodyp.
|
||||
|
@ -64,7 +64,7 @@ Hence even if a trailing '\0' is added, C string functions may still fail
|
||||
to work as expected.
|
||||
<LI>Since message bodies can be very large, defining xxfi_body can
|
||||
significantly impact filter performance.
|
||||
<LI>End-of-lines are represented as received from SMTP (normally CR/LF).
|
||||
<LI>End-of-lines are represented as received from SMTP (normally CRLF).
|
||||
<LI>Later filters will see body changes made by earlier ones.
|
||||
<LI>Message bodies may be sent in multiple chunks, with one call to
|
||||
xxfi_body per chunk.
|
||||
|
@ -48,8 +48,8 @@ Handle a message header.
|
||||
<TD>Header field value.
|
||||
The content of the header may include folded white space,
|
||||
i.e., multiple lines with following white space
|
||||
where lines are separated by LF (not CR/LF).
|
||||
The trailing line terminator (CR/LF) is removed.
|
||||
where lines are separated by LF (not CRLF).
|
||||
The trailing line terminator (CRLF) is removed.
|
||||
</TD></TR>
|
||||
</TABLE>
|
||||
</TD></TR>
|
||||
|
@ -60,32 +60,32 @@ typedef struct cmdfct_t cmdfct;
|
||||
#define CI_MAIL 2
|
||||
#define CI_RCPT 3
|
||||
#define CI_DATA 4
|
||||
#define CI_EOM 5
|
||||
#define CI_EOH 6
|
||||
#define CI_LAST CI_EOH
|
||||
#define CI_EOH 5
|
||||
#define CI_EOM 6
|
||||
#define CI_LAST CI_EOM
|
||||
#if CI_LAST < CI_DATA
|
||||
# ERROR "do not compile with CI_LAST < CI_DATA"
|
||||
# error "do not compile with CI_LAST < CI_DATA"
|
||||
#endif
|
||||
#if CI_LAST < CI_EOM
|
||||
# ERROR "do not compile with CI_LAST < CI_EOM"
|
||||
# error "do not compile with CI_LAST < CI_EOM"
|
||||
#endif
|
||||
#if CI_LAST < CI_EOH
|
||||
# ERROR "do not compile with CI_LAST < CI_EOH"
|
||||
# error "do not compile with CI_LAST < CI_EOH"
|
||||
#endif
|
||||
#if CI_LAST < CI_RCPT
|
||||
# ERROR "do not compile with CI_LAST < CI_RCPT"
|
||||
# error "do not compile with CI_LAST < CI_RCPT"
|
||||
#endif
|
||||
#if CI_LAST < CI_MAIL
|
||||
# ERROR "do not compile with CI_LAST < CI_MAIL"
|
||||
# error "do not compile with CI_LAST < CI_MAIL"
|
||||
#endif
|
||||
#if CI_LAST < CI_HELO
|
||||
# ERROR "do not compile with CI_LAST < CI_HELO"
|
||||
# error "do not compile with CI_LAST < CI_HELO"
|
||||
#endif
|
||||
#if CI_LAST < CI_CONN
|
||||
# ERROR "do not compile with CI_LAST < CI_CONN"
|
||||
# error "do not compile with CI_LAST < CI_CONN"
|
||||
#endif
|
||||
#if CI_LAST >= MAX_MACROS_ENTRIES
|
||||
# ERROR "do not compile with CI_LAST >= MAX_MACROS_ENTRIES"
|
||||
# error "do not compile with CI_LAST >= MAX_MACROS_ENTRIES"
|
||||
#endif
|
||||
|
||||
/* function prototypes */
|
||||
@ -111,7 +111,7 @@ static int dec_arg2 __P((char *, size_t, char **, char **));
|
||||
static void mi_clr_symlist __P((SMFICTX_PTR));
|
||||
|
||||
#if _FFR_WORKERS_POOL
|
||||
static bool mi_rd_socket_ready __P((int));
|
||||
static bool mi_rd_socket_ready __P((int));
|
||||
#endif
|
||||
|
||||
/* states */
|
||||
|
@ -45,7 +45,6 @@ dnl ? smcheck(`t-isprint', `compile-run')
|
||||
smcheck(`t-ixlen', `compile')
|
||||
smcheck(`t-ixlen.sh', `run')
|
||||
smcheck(`t-streq', `compile')
|
||||
smcheck(`t-utf8_valid', `compile')
|
||||
smcheck(`t-streq.sh', `run')
|
||||
divert(bldTARGETS_SECTION)
|
||||
divert(0)
|
||||
|
@ -34,6 +34,7 @@ The programs are:
|
||||
|
||||
b-strcmp.c tests strcasecmp().
|
||||
|
||||
|
||||
+----------------------+
|
||||
| CONFIGURATION MACROS |
|
||||
+----------------------+
|
||||
@ -106,9 +107,6 @@ SM_CONF_SEM
|
||||
SM_CONF_BROKEN_STRTOD
|
||||
Set to 1 if your strtod() does not work properly.
|
||||
|
||||
SM_CONF_GETOPT
|
||||
Set to 1 if your operating system does not include getopt(3).
|
||||
|
||||
SM_CONF_LDAP_INITIALIZE
|
||||
Set to 1 if your LDAP client libraries include ldap_initialize(3).
|
||||
|
||||
|
@ -101,7 +101,7 @@ main(argc, argv)
|
||||
** the copy.
|
||||
*/
|
||||
(void) strlcpy(source,
|
||||
" This is the longer string that will be used for catenation and copying for the the performace testing. The longer the string being catenated or copied the greater the difference in measureable performance\n",
|
||||
" This is the longer string that will be used for catenation and copying for the the performance testing. The longer the string being catenated or copied the greater the difference in measureable performance\n",
|
||||
SRC_SIZE - 1);
|
||||
|
||||
/* Run-time comments to the user */
|
||||
|
@ -350,7 +350,7 @@ of type SM_EXC_TYPE_T, which has the following members:
|
||||
<dt><tt>"E"</tt>
|
||||
<dd>The function could not complete its task because an error occurred.
|
||||
(It might be useful to define subclasses of this category,
|
||||
in which case our taxonony becomes a tree, and 'F' becomes
|
||||
in which case our taxonomy becomes a tree, and 'F' becomes
|
||||
a subclass of 'E'.)
|
||||
|
||||
<dt><tt>"J"</tt>
|
||||
|
@ -242,7 +242,7 @@ size_t SmHeapMaxTotal = 0;
|
||||
*/
|
||||
|
||||
SM_DEBUG_T SmHeapLimit = SM_DEBUG_INITIALIZER("sm_heap_limit",
|
||||
"@(#)$Debug: sm_heap_limit - max # of bytes permitted in heap $");
|
||||
"@(#)$Debug: sm_heap_limit - max # of bytes permitted in heap $");
|
||||
|
||||
/*
|
||||
** This is the data structure that keeps track of all currently
|
||||
|
@ -481,7 +481,7 @@ close file descriptors 0, 1 and 2).
|
||||
Thus <tt>sm_io_open()</tt> should
|
||||
never be called: the named file pointers should be used directly.
|
||||
Calls to <b>stdio</b> are safe to make when using these three<b>sm_io</b>
|
||||
file pointers though no code is shared between the two libaries.
|
||||
file pointers though no code is shared between the two libraries.
|
||||
However, the input and output between <i>sm_io</i> and <i>stdio</i> is
|
||||
coordinated for these three file pointers: <i>smiostdin</i>,
|
||||
<i>smiostdout</i> and <i>smiostderr</i> are layered on-top-of
|
||||
@ -574,10 +574,12 @@ SM_FILE_T. The file pointer content (internal structure members) of an active
|
||||
file should only be set and observed with the "info" functions.
|
||||
The two exceptions to the above statement are the structure members
|
||||
<i>cookie</i> and <i>ival</i>. <i>Cookie</i> is of type <tt>void *</tt>
|
||||
while <i>ival</i> is of type <tt>int</tt>. These two structure members exist
|
||||
specificly for your created file type to use. The <i>sm_io</i> functions
|
||||
will not change or set these two structure members; only specific file type
|
||||
will change or set these variables.
|
||||
while <i>ival</i> is of type <tt>int</tt>.
|
||||
These two structure members exist specifically
|
||||
for your created file type to use.
|
||||
The <i>sm_io</i> functions
|
||||
will not change or set these two structure members;
|
||||
only specific file type will change or set these variables.
|
||||
</p>
|
||||
<p>
|
||||
For maintaining information privately about status for a file type the
|
||||
@ -598,7 +600,7 @@ For the <i>cookie</i> to be passed to all members of a function type
|
||||
cleanly the location of the cookie must assigned during
|
||||
the call to open. The file type functions should not attempt to
|
||||
maintain the <i>cookie</i> internally since the file type may have
|
||||
serveral instances (file pointers).
|
||||
several instances (file pointers).
|
||||
</p>
|
||||
<p>
|
||||
The SM_FILE_T's member <i>ival</i> may be used in a manner similar to
|
||||
|
@ -36,6 +36,8 @@ SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap",
|
||||
static bool sm_ldap_has_objectclass __P((SM_LDAP_STRUCT *, LDAPMessage *, char *));
|
||||
static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **, char *, int, SM_RPOOL_T *));
|
||||
|
||||
static char *sm_ldap_geterror __P((LDAP *));
|
||||
|
||||
/*
|
||||
** SM_LDAP_CLEAR -- set default values for SM_LDAP_STRUCT
|
||||
**
|
||||
@ -49,10 +51,10 @@ static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **,
|
||||
|
||||
# if _FFR_LDAP_VERSION
|
||||
# if defined(LDAP_VERSION_MAX) && _FFR_LDAP_VERSION > LDAP_VERSION_MAX
|
||||
# ERROR "_FFR_LDAP_VERSION > LDAP_VERSION_MAX"
|
||||
# error "_FFR_LDAP_VERSION > LDAP_VERSION_MAX"
|
||||
# endif
|
||||
# if defined(LDAP_VERSION_MIN) && _FFR_LDAP_VERSION < LDAP_VERSION_MIN
|
||||
# ERROR "_FFR_LDAP_VERSION < LDAP_VERSION_MAX"
|
||||
# error "_FFR_LDAP_VERSION < LDAP_VERSION_MAX"
|
||||
# endif
|
||||
# define SM_LDAP_VERSION_DEFAULT _FFR_LDAP_VERSION
|
||||
# else /* _FFR_LDAP_VERSION */
|
||||
@ -79,6 +81,9 @@ sm_ldap_clear(lmap)
|
||||
lmap->ldap_options = 0;
|
||||
# endif
|
||||
lmap->ldap_attrsep = '\0';
|
||||
# if LDAP_NETWORK_TIMEOUT
|
||||
lmap->ldap_networktmo = 0;
|
||||
# endif
|
||||
lmap->ldap_binddn = NULL;
|
||||
lmap->ldap_secret = NULL;
|
||||
lmap->ldap_method = LDAP_AUTH_SIMPLE;
|
||||
@ -229,6 +234,23 @@ sm_ldap_setopts(ld, lmap)
|
||||
# ifdef LDAP_OPT_RESTART
|
||||
ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
|
||||
# endif
|
||||
# if _FFR_TESTS
|
||||
if (sm_debug_active(&SmLDAPTrace, 101))
|
||||
{
|
||||
char *cert;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
cert = getcwd(buf, sizeof(buf));
|
||||
if (NULL != cert)
|
||||
{
|
||||
int r;
|
||||
|
||||
(void) sm_strlcat(buf, "/ldaps.pem", sizeof(buf));
|
||||
r = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTFILE, cert);
|
||||
sm_dprintf("LDAP_OPT_X_TLS_CACERTFILE(%s)=%d\n", cert, r);
|
||||
}
|
||||
}
|
||||
# endif /* _FFR_TESTS */
|
||||
|
||||
# else /* USE_LDAP_SET_OPTION */
|
||||
/* From here on in we can use ldap internal timelimits */
|
||||
@ -305,6 +327,7 @@ sm_ldap_start(name, lmap)
|
||||
{
|
||||
int save_errno = 0;
|
||||
char *id;
|
||||
char *errmsg;
|
||||
# if !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT
|
||||
SM_EVENT *ev = NULL;
|
||||
# endif
|
||||
@ -312,6 +335,7 @@ sm_ldap_start(name, lmap)
|
||||
struct timeval tmo;
|
||||
int msgid, err, r;
|
||||
|
||||
errmsg = NULL;
|
||||
if (sm_debug_active(&SmLDAPTrace, 2))
|
||||
sm_dprintf("ldapmap_start(%s)\n", name == NULL ? "" : name);
|
||||
|
||||
@ -439,37 +463,66 @@ sm_ldap_start(name, lmap)
|
||||
lmap->ldap_method);
|
||||
save_errno = errno;
|
||||
if (sm_debug_active(&SmLDAPTrace, 9))
|
||||
sm_dprintf("ldap_bind(%s)=%d, errno=%d, tmo=%ld\n",
|
||||
{
|
||||
errmsg = sm_ldap_geterror(ld);
|
||||
sm_dprintf("ldap_bind(%s)=%d, errno=%d, ldaperr=%d, ld_error=%s, tmo=%lld\n",
|
||||
lmap->ldap_uri, msgid, save_errno,
|
||||
(long) tmo.tv_sec);
|
||||
sm_ldap_geterrno(ld), errmsg, (long long) tmo.tv_sec);
|
||||
if (NULL != errmsg)
|
||||
{
|
||||
ldap_memfree(errmsg);
|
||||
errmsg = NULL;
|
||||
}
|
||||
}
|
||||
if (-1 == msgid)
|
||||
{
|
||||
r = -1;
|
||||
err = sm_ldap_geterrno(ld);
|
||||
if (LDAP_SUCCESS != err)
|
||||
save_errno = err + E_LDAPBASE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
r = ldap_result(ld, msgid, LDAP_MSG_ALL,
|
||||
tmo.tv_sec == 0 ? NULL : &(tmo), &(lmap->ldap_res));
|
||||
save_errno = errno;
|
||||
if (sm_debug_active(&SmLDAPTrace, 9))
|
||||
sm_dprintf("ldap_result(%s)=%d, errno=%d\n", lmap->ldap_uri, r, errno);
|
||||
{
|
||||
errmsg = sm_ldap_geterror(ld);
|
||||
sm_dprintf("ldap_result(%s)=%d, errno=%d, ldaperr=%d, ld_error=%s\n",
|
||||
lmap->ldap_uri, r, errno,
|
||||
sm_ldap_geterrno(ld), errmsg);
|
||||
if (NULL != errmsg)
|
||||
{
|
||||
ldap_memfree(errmsg);
|
||||
errmsg = NULL;
|
||||
}
|
||||
}
|
||||
if (-1 == r)
|
||||
{
|
||||
err = sm_ldap_geterrno(ld);
|
||||
if (LDAP_SUCCESS != err)
|
||||
save_errno = err + E_LDAPBASE;
|
||||
goto fail;
|
||||
}
|
||||
if (0 == r)
|
||||
{
|
||||
save_errno = ETIMEDOUT;
|
||||
r = -1;
|
||||
goto fail;
|
||||
}
|
||||
r = ldap_parse_result(ld, lmap->ldap_res, &err, NULL, NULL, NULL, NULL,
|
||||
1);
|
||||
r = ldap_parse_result(ld, lmap->ldap_res, &err, NULL, &errmsg, NULL,
|
||||
NULL, 1);
|
||||
save_errno = errno;
|
||||
if (sm_debug_active(&SmLDAPTrace, 9))
|
||||
sm_dprintf("ldap_parse_result(%s)=%d, err=%d\n", lmap->ldap_uri, r, err);
|
||||
sm_dprintf("ldap_parse_result(%s)=%d, err=%d, errmsg=%s\n",
|
||||
lmap->ldap_uri, r, err, errmsg);
|
||||
if (r != LDAP_SUCCESS)
|
||||
goto fail;
|
||||
if (err != LDAP_SUCCESS)
|
||||
{
|
||||
r = -1;
|
||||
r = err;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -487,12 +540,22 @@ sm_ldap_start(name, lmap)
|
||||
errno = save_errno;
|
||||
else
|
||||
errno = r + E_LDAPBASE;
|
||||
if (NULL != errmsg)
|
||||
{
|
||||
ldap_memfree(errmsg);
|
||||
errmsg = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Save PID to make sure only this PID closes the LDAP connection */
|
||||
lmap->ldap_pid = getpid();
|
||||
lmap->ldap_ld = ld;
|
||||
if (NULL != errmsg)
|
||||
{
|
||||
ldap_memfree(errmsg);
|
||||
errmsg = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -536,7 +599,7 @@ sm_ldap_search_m(lmap, argv)
|
||||
if (lmap->ldap_multi_args)
|
||||
{
|
||||
# if SM_LDAP_ARGS < 10
|
||||
# ERROR _SM_LDAP_ARGS must be 10
|
||||
# error _SM_LDAP_ARGS must be 10
|
||||
# endif
|
||||
if (q[1] == 's')
|
||||
key = argv[0];
|
||||
@ -1559,7 +1622,6 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
|
||||
**
|
||||
** Returns:
|
||||
** None.
|
||||
**
|
||||
*/
|
||||
|
||||
void
|
||||
@ -1574,6 +1636,7 @@ sm_ldap_close(lmap)
|
||||
lmap->ldap_ld = NULL;
|
||||
lmap->ldap_pid = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** SM_LDAP_GETERRNO -- get ldap errno value
|
||||
**
|
||||
@ -1582,7 +1645,6 @@ sm_ldap_close(lmap)
|
||||
**
|
||||
** Returns:
|
||||
** LDAP errno.
|
||||
**
|
||||
*/
|
||||
|
||||
int
|
||||
@ -1614,4 +1676,28 @@ sm_ldap_geterrno(ld)
|
||||
# endif /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
** SM_LDAP_GETERROR -- get ldap error value
|
||||
**
|
||||
** Parameters:
|
||||
** ld -- LDAP session handle
|
||||
**
|
||||
** Returns:
|
||||
** LDAP error
|
||||
*/
|
||||
|
||||
static char *
|
||||
sm_ldap_geterror(ld)
|
||||
LDAP *ld;
|
||||
{
|
||||
char *error = NULL;
|
||||
|
||||
# if defined(LDAP_OPT_DIAGNOSTIC_MESSAGE)
|
||||
(void) ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &error);
|
||||
# endif
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
#endif /* LDAPMAP */
|
||||
|
@ -15,10 +15,11 @@
|
||||
#include <sm/string.h>
|
||||
#include <sm/heap.h>
|
||||
#if USE_EAI
|
||||
# include <sm/ixlen.h>
|
||||
# include <sm/limits.h>
|
||||
# include <unicode/ucasemap.h>
|
||||
# include <unicode/ustring.h>
|
||||
# include <unicode/uchar.h>
|
||||
# include <sm/ixlen.h>
|
||||
|
||||
/*
|
||||
** ASCIISTR -- check whether a string is printable ASCII
|
||||
@ -42,6 +43,38 @@ asciistr(str)
|
||||
str++;
|
||||
return ch == '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
** ASCIINSTR -- check whether a string is printable ASCII up to len
|
||||
**
|
||||
** Parameters:
|
||||
** str -- string
|
||||
** len -- length to check
|
||||
**
|
||||
** Returns:
|
||||
** TRUE iff printable ASCII
|
||||
*/
|
||||
|
||||
bool
|
||||
asciinstr(str, len)
|
||||
const char *str;
|
||||
size_t len;
|
||||
{
|
||||
unsigned char ch;
|
||||
int n;
|
||||
|
||||
if (str == NULL)
|
||||
return true;
|
||||
SM_REQUIRE(len < INT_MAX);
|
||||
n = 0;
|
||||
while (n < len && (ch = (unsigned char)*str) != '\0'
|
||||
&& ch >= 32 && ch < 127)
|
||||
{
|
||||
n++;
|
||||
str++;
|
||||
}
|
||||
return n == len || ch == '\0';
|
||||
}
|
||||
#endif /* USE_EAI */
|
||||
|
||||
/*
|
||||
|
@ -314,7 +314,7 @@ sendmail_mpe_getpwnam(name)
|
||||
/*
|
||||
** SENDMAIL_MPE_GETPWUID -- shadow function for getpwuid()
|
||||
**
|
||||
** Initializes the uninitalized fields in the passwd struct.
|
||||
** Initializes the uninitialized fields in the passwd struct.
|
||||
**
|
||||
** Parameters:
|
||||
** uid -- uid to obtain passwd data for
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 2020 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
@ -10,11 +10,12 @@
|
||||
|
||||
#include <sm/gen.h>
|
||||
|
||||
#if _FFR_DMTRIGGER
|
||||
#if _FFR_DMTRIGGER && _FFR_NOTIFY < 2
|
||||
#include <sm/conf.h> /* FDSET_CAST */
|
||||
#include <sm/fdset.h>
|
||||
#include <sm/assert.h>
|
||||
#include <sm/notify.h>
|
||||
#include "notify.h"
|
||||
#include <sm/time.h>
|
||||
#include <sm/string.h>
|
||||
|
||||
@ -28,12 +29,6 @@
|
||||
#include <fcntl.h>
|
||||
#include <string.h> /* for memset() */
|
||||
|
||||
#if SM_NOTIFY_DEBUG
|
||||
#define SM_DBG(p) fprintf p
|
||||
#else
|
||||
#define SM_DBG(p)
|
||||
#endif
|
||||
|
||||
static int Notifypipe[2];
|
||||
#define NotifyRDpipe Notifypipe[0]
|
||||
#define NotifyWRpipe Notifypipe[1]
|
||||
@ -129,9 +124,6 @@ sm_notify_stop(owner, flags)
|
||||
** <0: -errno
|
||||
*/
|
||||
|
||||
#define MAX_NETSTR 1024
|
||||
#define NETSTRPRE 5
|
||||
|
||||
int
|
||||
sm_notify_snd(buf, buflen)
|
||||
char *buf;
|
||||
@ -152,7 +144,7 @@ sm_notify_snd(buf, buflen)
|
||||
len = sm_snprintf(netstr, sizeof(netstr), "%04d:%s,", (int)buflen, buf);
|
||||
r = write(NotifyWRpipe, netstr, len);
|
||||
save_errno = errno;
|
||||
SM_DBG((stderr, "write=%d, fd=%d, e=%d\n", r, NotifyWRpipe, save_errno));
|
||||
SM_DBG((stderr, "pid=%ld, write=%d, fd=%d, e=%d\n", (long)getpid(), r, NotifyWRpipe, save_errno));
|
||||
return r >= 0 ? 0 : -save_errno;
|
||||
}
|
||||
|
||||
@ -165,7 +157,8 @@ sm_notify_snd(buf, buflen)
|
||||
** tmo -- timeout (micro seconds)
|
||||
**
|
||||
** Returns:
|
||||
** 0: success
|
||||
** 0: EOF (XXX need to provide info about client)
|
||||
** >0: length of received data
|
||||
** <0: -errno
|
||||
*/
|
||||
|
||||
@ -186,55 +179,14 @@ sm_notify_rcv(buf, buflen, tmo)
|
||||
return -EINVAL;
|
||||
FD_ZERO(&readfds);
|
||||
SM_FD_SET(NotifyRDpipe, &readfds);
|
||||
if (tmo < 0)
|
||||
tval = NULL;
|
||||
else
|
||||
{
|
||||
timeout.tv_sec = (long) (tmo / SM_MICROS);
|
||||
timeout.tv_usec = tmo % SM_MICROS;
|
||||
tval = &timeout;
|
||||
}
|
||||
SM_MICROS2TVAL(tmo, tval, timeout);
|
||||
|
||||
do {
|
||||
r = select(NotifyRDpipe + 1, FDSET_CAST &readfds, NULL, NULL, tval);
|
||||
save_errno = errno;
|
||||
SM_DBG((stderr, "select=%d, fd=%d, e=%d\n", r, NotifyRDpipe, save_errno));
|
||||
SM_DBG((stderr, "pid=%ld, select=%d, fd=%d, e=%d\n", (long)getpid(), r, NotifyRDpipe, save_errno));
|
||||
} while (r < 0 && save_errno == EINTR);
|
||||
|
||||
if (r <= 0)
|
||||
{
|
||||
SM_DBG((stderr, "select=%d, e=%d\n", r, save_errno));
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* bogus... need to check again? */
|
||||
if (!FD_ISSET(NotifyRDpipe, &readfds))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
r = read(NotifyRDpipe, buf, NETSTRPRE);
|
||||
if (NETSTRPRE != r)
|
||||
return -1; /* ??? */
|
||||
|
||||
if (sm_io_sscanf(buf, "%4u:", &len) != 1)
|
||||
return -EINVAL; /* ??? */
|
||||
if (len >= MAX_NETSTR)
|
||||
return -E2BIG; /* ??? */
|
||||
if (len >= buflen - 1)
|
||||
return -E2BIG; /* ??? */
|
||||
if (len <= 0)
|
||||
return -EINVAL; /* ??? */
|
||||
r = read(NotifyRDpipe, buf, len + 1);
|
||||
save_errno = errno;
|
||||
SM_DBG((stderr, "read=%d, e=%d\n", r, save_errno));
|
||||
if (r == 0)
|
||||
return -1; /* ??? */
|
||||
if (r < 0)
|
||||
return -save_errno;
|
||||
if (len + 1 != r)
|
||||
return -1; /* ??? */
|
||||
if (buf[len] != ',')
|
||||
return -EINVAL; /* ??? */
|
||||
buf[len] = '\0';
|
||||
return r;
|
||||
RDNETSTR(r, NotifyRDpipe, (void)0);
|
||||
}
|
||||
#endif /* _FFR_DMTRIGGER */
|
||||
#endif /* _FFR_DMTRIGGER && _FFR_NOTIFY < 2 */
|
||||
|
111
contrib/sendmail/libsm/notify.h
Normal file
111
contrib/sendmail/libsm/notify.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the sendmail distribution.
|
||||
*/
|
||||
|
||||
#ifndef LIBSM_NOTIFY_H
|
||||
#define LIBSM_NOTIFY_H
|
||||
|
||||
#if SM_NOTIFY_DEBUG
|
||||
#define SM_DBG(p) fprintf p
|
||||
#else
|
||||
#define SM_DBG(p)
|
||||
#endif
|
||||
|
||||
/* microseconds */
|
||||
#define SM_MICROS 1000000L
|
||||
|
||||
#define SM_MICROS2TVAL(tmo, tval, timeout) \
|
||||
do \
|
||||
{ \
|
||||
if (tmo < 0) \
|
||||
tval = NULL; \
|
||||
else \
|
||||
{ \
|
||||
timeout.tv_sec = (long) (tmo / SM_MICROS); \
|
||||
timeout.tv_usec = tmo % SM_MICROS; \
|
||||
tval = &timeout; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MAX_NETSTR 1024
|
||||
#define NETSTRPRE 5
|
||||
|
||||
/* flow through code, be careful how to use! */
|
||||
#define RDNETSTR(rc, fd, SM_NOTIFY_EOF) \
|
||||
if ((rc) <= 0) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, select=%d, e=%d\n", (long)getpid(), (rc), save_errno)); \
|
||||
return -ETIMEDOUT; \
|
||||
} \
|
||||
\
|
||||
/* bogus... need to check again? */ \
|
||||
if (!FD_ISSET(fd, &readfds)) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, isset=false\n", (long)getpid(), fd)); \
|
||||
return -ETIMEDOUT; \
|
||||
} \
|
||||
r = read(fd, buf, NETSTRPRE); \
|
||||
if (0 == r) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read1=EOF, e=%d\n", (long)getpid(), fd, errno)); \
|
||||
SM_NOTIFY_EOF; \
|
||||
return r; \
|
||||
} \
|
||||
if (NETSTRPRE != r) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read1=%d, e=%d\n", (long)getpid(), fd, r, errno)); \
|
||||
return -1; /* ??? */ \
|
||||
} \
|
||||
\
|
||||
if (sm_io_sscanf(buf, "%4u:", &len) != 1) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, scanf, e=%d\n", (long)getpid(), errno)); \
|
||||
return -EINVAL; /* ??? */ \
|
||||
} \
|
||||
if (len >= MAX_NETSTR) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, 1: len=%d\n", (long)getpid(), len)); \
|
||||
return -E2BIG; /* ??? */ \
|
||||
} \
|
||||
if (len >= buflen - 1) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, 2: len=%d\n", (long)getpid(), len)); \
|
||||
return -E2BIG; /* ??? */ \
|
||||
} \
|
||||
if (len <= 0) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, 3: len=%d\n", (long)getpid(), len)); \
|
||||
return -EINVAL; /* ??? */ \
|
||||
} \
|
||||
r = read(fd, buf, len + 1); \
|
||||
save_errno = errno; \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read=%d, len=%d, e=%d\n", (long)getpid(), fd, r, len+1, save_errno)); \
|
||||
if (r == 0) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read2=%d, e=%d\n", (long)getpid(), fd, r, save_errno)); \
|
||||
return -1; /* ??? */ \
|
||||
} \
|
||||
if (r < 0) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read3=%d, e=%d\n", (long)getpid(), fd, r, save_errno)); \
|
||||
return -save_errno; \
|
||||
} \
|
||||
if (len + 1 != r) \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read4=%d, len=%d\n", (long)getpid(), fd, r, len)); \
|
||||
return -1; /* ??? */ \
|
||||
} \
|
||||
if (buf[len] != ',') \
|
||||
{ \
|
||||
SM_DBG((stderr, "pid=%ld, fd=%d, read5=%d, f=%d\n", (long)getpid(), fd, r, buf[len])); \
|
||||
return -EINVAL; /* ??? */ \
|
||||
} \
|
||||
buf[len] = '\0'; \
|
||||
return r
|
||||
|
||||
#endif /* ! LIBSM_MSG_H */
|
@ -25,7 +25,7 @@ SM_RCSID("@(#)$Id: rewind.c,v 1.19 2013-11-22 20:51:43 ca Exp $")
|
||||
** Seeks the file to the beginning and clears any outstanding errors.
|
||||
**
|
||||
** Parameters:
|
||||
** fp -- the flie pointer for rewind
|
||||
** fp -- the file pointer for rewind
|
||||
** timeout -- time to complete the rewind
|
||||
**
|
||||
** Returns:
|
||||
|
@ -17,6 +17,7 @@ SM_RCSID("@(#)$Id: setvbuf.c,v 1.33 2013-11-22 20:51:43 ca Exp $")
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sm/limits.h>
|
||||
#include <sm/io.h>
|
||||
#include <sm/heap.h>
|
||||
#include <sm/assert.h>
|
||||
@ -67,7 +68,7 @@ sm_io_setvbuf(fp, timeout, buf, mode, size)
|
||||
|
||||
if (mode != SM_IO_NBF)
|
||||
if ((mode != SM_IO_FBF && mode != SM_IO_LBF &&
|
||||
mode != SM_IO_NOW) || (int) size < 0)
|
||||
mode != SM_IO_NOW) || size > INT_MAX)
|
||||
return SM_IO_EOF;
|
||||
|
||||
/*
|
||||
|
@ -162,7 +162,7 @@ sm_stdwrite(fp, buf, n)
|
||||
/*
|
||||
** SM_STDSEEK -- set the file offset position
|
||||
**
|
||||
** Parmeters:
|
||||
** Parameters:
|
||||
** fp -- file pointer to position
|
||||
** offset -- how far to position from "base" (set by 'whence')
|
||||
** whence -- indicates where the "base" of the 'offset' to start
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <sm/ixlen.h>
|
||||
|
||||
/*
|
||||
** SM_STRCASEEQ -- are two strings equal (case-insenstive)?
|
||||
** SM_STRCASEEQ -- are two strings equal (case-insensitive)?
|
||||
**
|
||||
** Parameters:
|
||||
** s1 -- string
|
||||
@ -63,7 +63,7 @@ sm_strcaseeq(s1, s2)
|
||||
}
|
||||
|
||||
/*
|
||||
** SM_STRNCASEEQ -- are two strings (up to a length) equal (case-insenstive)?
|
||||
** SM_STRNCASEEQ -- are two strings (up to a length) equal (case-insensitive)?
|
||||
**
|
||||
** Parameters:
|
||||
** s1 -- string
|
||||
@ -86,13 +86,13 @@ sm_strncaseeq(s1, s2, n)
|
||||
|
||||
if (0 == n)
|
||||
return true;
|
||||
if (asciistr(s1))
|
||||
if (asciinstr(s1, n))
|
||||
{
|
||||
if (!asciistr(s2))
|
||||
if (!asciinstr(s2, n))
|
||||
return false;
|
||||
return (sm_strncasecmp(s1, s2, n) == 0);
|
||||
}
|
||||
if (asciistr(s2))
|
||||
if (asciinstr(s2, n))
|
||||
return false;
|
||||
l1 = sm_lowercase(s1);
|
||||
if (l1 != s1)
|
||||
@ -104,7 +104,7 @@ sm_strncaseeq(s1, s2, n)
|
||||
f1 = NULL;
|
||||
l2 = sm_lowercase(s2);
|
||||
|
||||
while (*l1 == *l2 && '\0' != *l1 && n-- > 0)
|
||||
while (*l1 == *l2 && '\0' != *l1 && --n > 0)
|
||||
l1++, l2++;
|
||||
same = *l1 == *l2;
|
||||
|
||||
|
@ -19,6 +19,7 @@ SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
|
||||
|
||||
#if _FFR_8BITENVADDR
|
||||
extern bool SmTestVerbose;
|
||||
static int Verbose = 0;
|
||||
|
||||
static void
|
||||
chkilenx(str, len)
|
||||
@ -30,10 +31,41 @@ chkilenx(str, len)
|
||||
xlen = ilenx(str);
|
||||
SM_TEST(len == xlen);
|
||||
if (len != xlen)
|
||||
fprintf(stderr, "str=\"%s\", len=%d, excpected=%d\n",
|
||||
fprintf(stderr, "str=\"%s\", len=%d, expected=%d\n",
|
||||
str, xlen, len);
|
||||
}
|
||||
|
||||
static void
|
||||
chkilen(str)
|
||||
char *str;
|
||||
{
|
||||
char *obp;
|
||||
int outlen, leni, lenx, ilen;
|
||||
char line_in[1024];
|
||||
XLENDECL
|
||||
|
||||
lenx = strlen(str);
|
||||
sm_strlcpy(line_in, str, sizeof(line_in));
|
||||
obp = quote_internal_chars(str, NULL, &outlen, NULL);
|
||||
leni = strlen(obp);
|
||||
|
||||
for (ilen = 0; *obp != '\0'; obp++, ilen++)
|
||||
{
|
||||
XLEN(*obp);
|
||||
}
|
||||
if (Verbose)
|
||||
fprintf(stderr, "str=\"%s\", ilen=%d, xlen=%d\n",
|
||||
str, ilen, xlen);
|
||||
SM_TEST(ilen == leni);
|
||||
if (ilen != leni)
|
||||
fprintf(stderr, "str=\"%s\", ilen=%d, leni=%d\n",
|
||||
str, ilen, leni);
|
||||
SM_TEST(xlen == lenx);
|
||||
if (xlen != lenx)
|
||||
fprintf(stderr, "str=\"%s\", xlen=%d, lenx=%d\n",
|
||||
str, xlen, lenx);
|
||||
}
|
||||
|
||||
static void
|
||||
chkxleni(str, len)
|
||||
const char *str;
|
||||
@ -44,7 +76,7 @@ chkxleni(str, len)
|
||||
ilen = xleni(str);
|
||||
SM_TEST(len == ilen);
|
||||
if (len != ilen)
|
||||
fprintf(stderr, "str=\"%s\", len=%d, excpected=%d\n",
|
||||
fprintf(stderr, "str=\"%s\", len=%d, expected=%d\n",
|
||||
str, ilen, len);
|
||||
}
|
||||
|
||||
@ -64,18 +96,26 @@ main(argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
int o, len;
|
||||
bool x;
|
||||
bool x, both;
|
||||
char line[1024];
|
||||
|
||||
x = false;
|
||||
while ((o = getopt(argc, argv, "x")) != -1)
|
||||
x = both = false;
|
||||
while ((o = getopt(argc, argv, "bxV")) != -1)
|
||||
{
|
||||
switch ((char) o)
|
||||
{
|
||||
case 'b':
|
||||
both = true;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
x = true;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
Verbose++;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(1);
|
||||
@ -84,6 +124,12 @@ main(argc, argv)
|
||||
|
||||
sm_test_begin(argc, argv, "test ilenx");
|
||||
|
||||
if (both)
|
||||
{
|
||||
while (fscanf(stdin, "%s\n", line) == 1)
|
||||
chkilen(line);
|
||||
return sm_test_end();
|
||||
}
|
||||
while (fscanf(stdin, "%d:%s\n", &len, line) == 2)
|
||||
{
|
||||
if (x)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 2020 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
@ -8,7 +8,6 @@
|
||||
*/
|
||||
|
||||
#include <sm/gen.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if _FFR_DMTRIGGER || _FFR_NOTIFY
|
||||
@ -20,23 +19,32 @@
|
||||
# include <sm/test.h>
|
||||
# include <sm/notify.h>
|
||||
# include <sm/conf.h>
|
||||
# include "notify.h"
|
||||
|
||||
static int Verbose = 0;
|
||||
#define MAX_CHILDREN 256
|
||||
#define MAX_MSGS 1024
|
||||
static pid_t pids[MAX_CHILDREN];
|
||||
static char msgs[MAX_CHILDREN][MAX_MSGS];
|
||||
|
||||
/*
|
||||
** NOTIFY_WR -- test of notify feature
|
||||
** NOTIFY_WR -- test of notify write feature
|
||||
**
|
||||
** Parameters:
|
||||
** pid -- pid of process
|
||||
** nmsgs -- number of messages to write
|
||||
**
|
||||
** Returns:
|
||||
** 0 on success
|
||||
** >=0 on success
|
||||
** < 0 on failure
|
||||
*/
|
||||
|
||||
static int
|
||||
notify_wr(pid)
|
||||
notify_wr(pid, nmsgs)
|
||||
pid_t pid;
|
||||
int nmsgs;
|
||||
{
|
||||
int r;
|
||||
int r, i;
|
||||
size_t len;
|
||||
char buf[64];
|
||||
#define TSTSTR "qf0001"
|
||||
@ -48,16 +56,38 @@ notify_wr(pid)
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = sm_snprintf(buf, sizeof(buf), "%s-%ld", TSTSTR, (long) pid);
|
||||
r = sm_notify_snd(buf, len);
|
||||
SM_TEST(r >= 0);
|
||||
for (i = 0; i < nmsgs; i++)
|
||||
{
|
||||
len = sm_snprintf(buf, sizeof(buf), "%s-%ld_%d", TSTSTR,
|
||||
(long) pid, i);
|
||||
r = sm_notify_snd(buf, len);
|
||||
SM_TEST(r >= 0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
validpid(nproc, cpid)
|
||||
int nproc;
|
||||
pid_t cpid;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nproc; i++)
|
||||
if (cpid == pids[i])
|
||||
return i;
|
||||
if (Verbose > 0)
|
||||
fprintf(stderr, "pid=%ld not found, nproc=%d\n",
|
||||
(long) cpid, nproc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
** NOTIFY_RD -- test of notify feature
|
||||
** NOTIFY_RD -- test of notify read feature
|
||||
**
|
||||
** Parameters:
|
||||
** nproc -- number of processes started
|
||||
** nmsgs -- number of messages to read for each process
|
||||
**
|
||||
** Returns:
|
||||
** 0 on success
|
||||
@ -65,11 +95,13 @@ notify_wr(pid)
|
||||
*/
|
||||
|
||||
static int
|
||||
notify_rd(nproc)
|
||||
notify_rd(nproc, nmsgs)
|
||||
int nproc;
|
||||
int nmsgs;
|
||||
{
|
||||
int r, i;
|
||||
char buf[64];
|
||||
int r, i, pidx;
|
||||
long cpid;
|
||||
char buf[64], *p;
|
||||
#define TSTSTR "qf0001"
|
||||
|
||||
r = sm_notify_start(true, 0);
|
||||
@ -79,21 +111,52 @@ notify_rd(nproc)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nproc; i++)
|
||||
for (i = 0; i < nmsgs * nproc; i++)
|
||||
{
|
||||
r = sm_notify_rcv(buf, sizeof(buf), 5 * SM_MICROS);
|
||||
SM_TEST(r >= 0);
|
||||
do
|
||||
{
|
||||
r = sm_notify_rcv(buf, sizeof(buf), 5 * SM_MICROS);
|
||||
SM_TEST(r >= 0);
|
||||
} while (0 == r);
|
||||
if (r < 0)
|
||||
{
|
||||
fprintf(stderr, "rcv=%d\n", r);
|
||||
fprintf(stderr, "pid=%ld, rcv=%d, i=%d\n",
|
||||
(long)getpid(), r, i);
|
||||
return r;
|
||||
}
|
||||
if (r > 0 && r < sizeof(buf))
|
||||
buf[r] = '\0';
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
if (Verbose > 0)
|
||||
fprintf(stderr, "pid=%ld, buf=\"%s\", i=%d\n",
|
||||
(long)getpid(), buf, i);
|
||||
|
||||
SM_TEST(strncmp(buf, TSTSTR, sizeof(TSTSTR) - 1) == 0);
|
||||
SM_TEST(r > sizeof(TSTSTR));
|
||||
fprintf(stderr, "buf=\"%s\"\n", buf);
|
||||
|
||||
r = sscanf(buf + sizeof(TSTSTR), "%ld", &cpid);
|
||||
SM_TEST(1 == r);
|
||||
pidx = validpid(nproc, (pid_t)cpid);
|
||||
SM_TEST(pidx >= 0);
|
||||
SM_TEST(pidx < nproc);
|
||||
|
||||
p = strchr(buf, '_');
|
||||
SM_TEST(NULL != p);
|
||||
if (NULL != p && pidx < nproc && pidx >= 0)
|
||||
{
|
||||
int n;
|
||||
|
||||
r = sscanf(p + 1, "%d", &n);
|
||||
SM_TEST(1 == r);
|
||||
SM_TEST(n >= 0);
|
||||
SM_TEST(n < nmsgs);
|
||||
if (1 == r && n < nmsgs && n >= 0)
|
||||
{
|
||||
SM_TEST('\0' == msgs[pidx][n]);
|
||||
msgs[pidx][n] = 'f';
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -106,27 +169,53 @@ main(argc, argv)
|
||||
int i;
|
||||
int r = 0;
|
||||
int nproc = 1;
|
||||
int nmsgs = 1;
|
||||
pid_t pid;
|
||||
|
||||
# define OPTIONS "p:"
|
||||
# define OPTIONS "n:p:V"
|
||||
while ((i = getopt(argc, argv, OPTIONS)) != -1)
|
||||
{
|
||||
switch ((char) i)
|
||||
{
|
||||
case 'n':
|
||||
nmsgs = atoi(optarg);
|
||||
if (nmsgs < 1)
|
||||
{
|
||||
errno = EINVAL;
|
||||
fprintf(stderr, "-%c: must be >0\n", (char) i);
|
||||
return 1;
|
||||
}
|
||||
if (nmsgs >= MAX_MSGS)
|
||||
{
|
||||
errno = EINVAL;
|
||||
fprintf(stderr, "-%c: must be <%d\n", (char) i, MAX_MSGS);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
nproc = atoi(optarg);
|
||||
if (nproc < 1)
|
||||
{
|
||||
errno = EINVAL;
|
||||
perror("-p: must be >0\n");
|
||||
return r;
|
||||
fprintf(stderr, "-%c: must be >0\n", (char) i);
|
||||
return 1;
|
||||
}
|
||||
if (nproc >= MAX_CHILDREN)
|
||||
{
|
||||
errno = EINVAL;
|
||||
fprintf(stderr, "-%c: must be <%d\n", (char) i, MAX_CHILDREN);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
++Verbose;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(msgs, '\0', sizeof(msgs));
|
||||
sm_test_begin(argc, argv, "test notify");
|
||||
r = sm_notify_init(0);
|
||||
SM_TEST(r >= 0);
|
||||
@ -149,12 +238,14 @@ main(argc, argv)
|
||||
{
|
||||
/* give the parent the chance to set up data */
|
||||
sleep(1);
|
||||
r = notify_wr(getpid());
|
||||
r = notify_wr(getpid(), nmsgs);
|
||||
break;
|
||||
}
|
||||
if (pid > 0)
|
||||
pids[i] = pid;
|
||||
}
|
||||
if (pid > 0)
|
||||
r = notify_rd(nproc);
|
||||
r = notify_rd(nproc, nmsgs);
|
||||
SM_TEST(r >= 0);
|
||||
return sm_test_end();
|
||||
}
|
||||
@ -164,7 +255,7 @@ main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
printf("SKIPPED: no _FFR_DMTRIGGER\n");
|
||||
printf("SKIPPED: no _FFR_DMTRIGGER || _FFR_NOTIFY\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* _FFR_DMTRIGGER */
|
||||
#endif /* _FFR_DMTRIGGER || _FFR_NOTIFY */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 2006, 2023 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
@ -19,7 +19,6 @@ SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
|
||||
|
||||
extern bool SmTestVerbose;
|
||||
|
||||
|
||||
void
|
||||
show_diff(s1, s2)
|
||||
const char *s1;
|
||||
@ -107,6 +106,8 @@ main(argc, argv)
|
||||
int i, los, cmp, mode;
|
||||
sm_qic_T inout[] = {
|
||||
{ "", "", 0 }
|
||||
, { "\t", "\t", 0 }
|
||||
, { "\tuser", "\tuser", 0 }
|
||||
, { "abcdef", "abcdef", 0 }
|
||||
, { "01234567890123456789", "01234567890123456789", 0 }
|
||||
, { "\\", "\\", 0 }
|
||||
@ -242,5 +243,16 @@ main(argc, argv)
|
||||
}
|
||||
}
|
||||
|
||||
los = -1;
|
||||
obp = quote_internal_chars(NULL, NULL, &los, NULL);
|
||||
SM_TEST(NULL == obp);
|
||||
SM_TEST(-1 == los);
|
||||
|
||||
sm_strlcpy(line_in, "nothing", sizeof(line_in));
|
||||
los = -123;
|
||||
obp = quote_internal_chars(line_in, NULL, &los, NULL);
|
||||
SM_TEST(NULL != obp);
|
||||
SM_TEST(los > 0);
|
||||
|
||||
return sm_test_end();
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
|
||||
#include <sm/ixlen.h>
|
||||
#include <sm/test.h>
|
||||
|
||||
#if _FFR_8BITENVADDR
|
||||
extern bool SmTestVerbose;
|
||||
|
||||
static int
|
||||
@ -37,6 +36,32 @@ usage(prg)
|
||||
fprintf(stderr, "options:\n");
|
||||
}
|
||||
|
||||
static void
|
||||
hack(str)
|
||||
char *str;
|
||||
{
|
||||
char c;
|
||||
|
||||
/* replace just one \x char */
|
||||
while ((c = *str++) != '\0')
|
||||
{
|
||||
if (c != '\\')
|
||||
continue;
|
||||
c = *str;
|
||||
switch (c)
|
||||
{
|
||||
case 'n': c ='\n'; break;
|
||||
case 't': c ='\t'; break;
|
||||
case 'r': c ='\r'; break;
|
||||
/* case 'X': c ='\X'; break; */
|
||||
default: c ='\0'; break;
|
||||
}
|
||||
*(str - 1) = c;
|
||||
*str = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
@ -61,17 +86,14 @@ main(argc, argv)
|
||||
while (fscanf(stdin, "%d:%s\n", &len, s1) == 2 &&
|
||||
fscanf(stdin, "%d:%s\n", &o,s2) == 2)
|
||||
{
|
||||
int r;
|
||||
|
||||
hack(s1);
|
||||
hack(s2);
|
||||
SM_TEST(tstrncaseeq(s1, s2, len) == o);
|
||||
if ((r = tstrncaseeq(s1, s2, len)) != o)
|
||||
fprintf(stderr, "\"%s\"\n\"%s\"\n%d!=%d\n", s1, s2, o, r);
|
||||
}
|
||||
|
||||
return sm_test_end();
|
||||
}
|
||||
#else /* _FFR_8BITENVADDR */
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* _FFR_8BITENVADDR */
|
||||
|
@ -12,6 +12,13 @@
|
||||
|
||||
PRG=./t-streq
|
||||
R=0
|
||||
# format:
|
||||
# two lines:
|
||||
# len:string1
|
||||
# result:string2
|
||||
# result:
|
||||
# 1: equal
|
||||
# 0: not equal
|
||||
${PRG} <<EOF
|
||||
0:a
|
||||
1:X
|
||||
@ -23,6 +30,18 @@ ${PRG} <<EOF
|
||||
1:AC
|
||||
2:aB
|
||||
0:AC
|
||||
2:aB\n
|
||||
1:AB
|
||||
20:xabcez@uabcey.por.az\n
|
||||
1:xabcez@uabcey.por.az
|
||||
7:ünchen\n
|
||||
1:ünchen
|
||||
7:ünchen\n
|
||||
0:üncheX
|
||||
22:iseadmin@somest.sld.br>\n
|
||||
1:iseadmin@somest.sld.br
|
||||
22:iseadmin@somest.sld.br
|
||||
1:iseadmin@somest.sld.br>\n
|
||||
EOF
|
||||
R=$?
|
||||
|
||||
|
@ -96,7 +96,7 @@ sm_test_begin(argc, argv, testname)
|
||||
** SM_TEST -- single test.
|
||||
**
|
||||
** Parameters:
|
||||
** success -- did test succeeed?
|
||||
** success -- did test succeed?
|
||||
** expr -- expression that has been evaluated.
|
||||
** filename -- guess...
|
||||
** lineno -- line number.
|
||||
|
@ -132,10 +132,11 @@ str2prt(s)
|
||||
** ibp -- a pointer to the string to translate [x]
|
||||
** obp -- a pointer to an output buffer [i][m:A]
|
||||
** bsp -- pointer to the length of the output buffer
|
||||
** rpool -- rpool for allocations
|
||||
**
|
||||
** Returns:
|
||||
** A possibly new bp (if the buffer needed to grow); if
|
||||
** it is different, *bsp will updated to the size of
|
||||
** A possibly new obp (if the buffer needed to grow);
|
||||
** if it is different, *bsp will updated to the size of
|
||||
** the new buffer and the caller is responsible for
|
||||
** freeing the memory.
|
||||
*/
|
||||
@ -171,7 +172,12 @@ quote_internal_chars
|
||||
int bufused, olen;
|
||||
bool buffer_same, needs_quoting;
|
||||
|
||||
if (NULL == ibp)
|
||||
return NULL;
|
||||
buffer_same = ibp == obp;
|
||||
SM_REQUIRE(NULL != bsp);
|
||||
if (NULL == obp)
|
||||
*bsp = 0;
|
||||
needs_quoting = false;
|
||||
|
||||
/* determine length of output string (starts at 1 for trailing '\0') */
|
||||
|
@ -74,7 +74,7 @@ sm_print(fp, timeout, uio)
|
||||
}
|
||||
|
||||
/*
|
||||
** SM_BPRINTF -- allow formating to an unbuffered file.
|
||||
** SM_BPRINTF -- allow formatting to an unbuffered file.
|
||||
**
|
||||
** Helper function for `fprintf to unbuffered unix file': creates a
|
||||
** temporary buffer (via a "fake" file pointer).
|
||||
@ -84,11 +84,11 @@ sm_print(fp, timeout, uio)
|
||||
** Parameters:
|
||||
** fp -- the file to send the o/p to
|
||||
** fmt -- format instructions for the o/p
|
||||
** ap -- vectors of data units used for formating
|
||||
** ap -- vectors of data units used for formatting
|
||||
**
|
||||
** Results:
|
||||
** Failure: SM_IO_EOF and errno set
|
||||
** Success: number of data units used in the formating
|
||||
** Success: number of data units used in the formatting
|
||||
**
|
||||
** Side effects:
|
||||
** formatted o/p can be SM_IO_BUFSIZ length maximum
|
||||
@ -156,13 +156,13 @@ sm_bprintf(fp, fmt, ap)
|
||||
#define FPT 0x100 /* Floating point number */
|
||||
|
||||
/*
|
||||
** SM_IO_VFPRINTF -- performs actual formating for o/p
|
||||
** SM_IO_VFPRINTF -- performs actual formatting for o/p
|
||||
**
|
||||
** Parameters:
|
||||
** fp -- file pointer for o/p
|
||||
** timeout -- time to complete the print
|
||||
** fmt0 -- formating directives
|
||||
** ap -- vectors with data units for formating
|
||||
** fmt0 -- formatting directives
|
||||
** ap -- vectors with data units for formatting
|
||||
**
|
||||
** Results:
|
||||
** Success: number of data units used for formatting
|
||||
@ -816,8 +816,8 @@ number: if ((dprec = prec) >= 0)
|
||||
** It will be replaced with a malloc-ed one if it overflows.
|
||||
**
|
||||
** Parameters:
|
||||
** fmt0 -- formating directives
|
||||
** ap -- vector list of data unit for formating consumption
|
||||
** fmt0 -- formatting directives
|
||||
** ap -- vector list of data unit for formatting consumption
|
||||
** argtable -- an indexable table (returned) of 'ap'
|
||||
**
|
||||
** Results:
|
||||
|
@ -655,7 +655,7 @@ again: c = *fmt++;
|
||||
c = *fp->f_p;
|
||||
|
||||
/*
|
||||
** This code mimicks the integer conversion
|
||||
** This code mimics the integer conversion
|
||||
** code, but is much simpler.
|
||||
*/
|
||||
|
||||
|
@ -409,7 +409,7 @@ smcdb_cursor(database, cursor, flags)
|
||||
** Parameters:
|
||||
** database -- An unallocated database pointer to a pointer.
|
||||
** db_name -- The name of the database without extension.
|
||||
** mode -- File permisions for a created database.
|
||||
** mode -- File permissions for a created database.
|
||||
** mode_mask -- Mode bits that must match on an opened database.
|
||||
** sff -- Flags for safefile.
|
||||
** type -- The type of database to open
|
||||
|
@ -333,10 +333,9 @@ smdb_lock_file(lock_fd, db_name, mode, sff, extension)
|
||||
|
||||
return SMDBE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** SMDB_UNLOCK_FILE -- Unlocks a file
|
||||
**
|
||||
** Unlocks a file.
|
||||
** SMDB_UNLOCK_FILE -- Unlocks a file - via close()
|
||||
**
|
||||
** Parameters:
|
||||
** lock_fd -- The descriptor for the locked file.
|
||||
@ -488,7 +487,7 @@ smdb_filechanged(db_name, extension, db_fd, stat_info)
|
||||
** SMDB_PRINT_AVAILABLE_TYPES -- Prints the names of the available types.
|
||||
**
|
||||
** Parameters:
|
||||
** None
|
||||
** ext - also show extension?
|
||||
**
|
||||
** Returns:
|
||||
** None
|
||||
|
@ -423,7 +423,7 @@ smdb1_cursor(database, cursor, flags)
|
||||
** Parameters:
|
||||
** database -- An unallocated database pointer to a pointer.
|
||||
** db_name -- The name of the database without extension.
|
||||
** mode -- File permisions on the database if created.
|
||||
** mode -- File permissions on the database if created.
|
||||
** mode_mask -- Mode bits that must match on an existing database.
|
||||
** sff -- Flags for safefile.
|
||||
** type -- The type of database to open
|
||||
|
@ -549,7 +549,7 @@ smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
|
||||
** Parameters:
|
||||
** database -- An unallocated database pointer to a pointer.
|
||||
** db_name -- The name of the database without extension.
|
||||
** mode -- File permisions for a created database.
|
||||
** mode -- File permissions for a created database.
|
||||
** mode_mask -- Mode bits that must match on an opened database.
|
||||
** sff -- Flags for safefile.
|
||||
** type -- The type of database to open
|
||||
|
@ -17,7 +17,7 @@ SM_RCSID("@(#)$Id: smndbm.c,v 8.55 2013-11-22 20:51:49 ca Exp $")
|
||||
#include <sendmail/sendmail.h>
|
||||
#include <libsmdb/smdb.h>
|
||||
|
||||
#ifdef NDBM
|
||||
#if NDBM
|
||||
|
||||
# define SMNDB_PAG_FILE_EXTENSION "pag"
|
||||
|
||||
@ -465,7 +465,7 @@ smdbm_cursor(database, cursor, flags)
|
||||
** Parameters:
|
||||
** database -- An unallocated database pointer to a pointer.
|
||||
** db_name -- The name of the database without extension.
|
||||
** mode -- File permisions on a created database.
|
||||
** mode -- File permissions on a created database.
|
||||
** mode_mask -- Mode bits that much match on an opened database.
|
||||
** sff -- Flags to safefile.
|
||||
** type -- The type of database to open.
|
||||
|
@ -21,7 +21,20 @@ char iobuf[IOBUFSZ];
|
||||
static int noio, chk;
|
||||
static pid_t pid;
|
||||
|
||||
int
|
||||
/*
|
||||
** OPENFILE -- open a file
|
||||
**
|
||||
** Parameters:
|
||||
** owner -- create file?
|
||||
** filename -- name of file.
|
||||
** flags -- flags for open(2)
|
||||
**
|
||||
** Returns:
|
||||
** >=0 fd
|
||||
** <0 on failure.
|
||||
*/
|
||||
|
||||
static int
|
||||
openfile(owner, filename, flags)
|
||||
int owner;
|
||||
char *filename;
|
||||
@ -36,10 +49,21 @@ openfile(owner, filename, flags)
|
||||
return fd;
|
||||
fprintf(stderr, "%d: %ld: owner=%d, open(%s) failed\n",
|
||||
(int) pid, (long) time(NULL), owner, filename);
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
/*
|
||||
** WRBUF -- write iobuf to fd
|
||||
**
|
||||
** Parameters:
|
||||
** fd -- file descriptor.
|
||||
**
|
||||
** Returns:
|
||||
** ==0 write was ok
|
||||
** !=0 on failure.
|
||||
*/
|
||||
|
||||
static int
|
||||
wrbuf(fd)
|
||||
int fd;
|
||||
{
|
||||
@ -55,7 +79,19 @@ wrbuf(fd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
/*
|
||||
** RDBUF -- read from fd
|
||||
**
|
||||
** Parameters:
|
||||
** fd -- file descriptor.
|
||||
** xbuf -- expected content.
|
||||
**
|
||||
** Returns:
|
||||
** ==0 read was ok and content matches
|
||||
** !=0 otherwise
|
||||
*/
|
||||
|
||||
static int
|
||||
rdbuf(fd, xbuf)
|
||||
int fd;
|
||||
const char *xbuf;
|
||||
@ -81,7 +117,7 @@ rdbuf(fd, xbuf)
|
||||
}
|
||||
|
||||
/*
|
||||
** LOCKTEST -- test of file locking
|
||||
** LOCKTESTWR -- test WR/EX file locking
|
||||
**
|
||||
** Parameters:
|
||||
** owner -- create file?
|
||||
@ -102,7 +138,7 @@ rdbuf(fd, xbuf)
|
||||
fprintf(stderr, str, filename, shared ? "RD" : "EX"); \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
static int
|
||||
locktestwr(filename, flags, delay)
|
||||
char *filename;
|
||||
int flags;
|
||||
@ -128,7 +164,8 @@ locktestwr(filename, flags, delay)
|
||||
sm_strlcpy(iobuf, FIRSTLINE, sizeof(iobuf));
|
||||
if (wrbuf(fd))
|
||||
return 1;
|
||||
sleep(delay);
|
||||
if (delay > 0)
|
||||
sleep(delay);
|
||||
sm_strlcpy(iobuf, LASTLINE, sizeof(iobuf));
|
||||
if (wrbuf(fd))
|
||||
return 1;
|
||||
@ -149,7 +186,22 @@ locktestwr(filename, flags, delay)
|
||||
return 0;
|
||||
}
|
||||
|
||||
long
|
||||
/*
|
||||
** CHKLCK -- check whether fd is locked (only for fcntl())
|
||||
**
|
||||
** Parameters:
|
||||
** owner -- create file?
|
||||
** filename -- name of file.
|
||||
** flags -- flags for open(2)
|
||||
** delay -- how long to keep file locked?
|
||||
**
|
||||
** Returns:
|
||||
** 0 if not locked
|
||||
** >0 pid of process which holds a WR lock
|
||||
** <0 error
|
||||
*/
|
||||
|
||||
static long
|
||||
chklck(fd)
|
||||
int fd;
|
||||
{
|
||||
@ -168,13 +220,27 @@ chklck(fd)
|
||||
return (long)lfd.l_pid;
|
||||
return 0L;
|
||||
#else /* !HASFLOCK */
|
||||
fprintf(stderr, "%d: %ld: flock: no lock test\n",
|
||||
fprintf(stderr, "%d: %ld: flock(): no lock test\n",
|
||||
(int) pid, (long) time(NULL));
|
||||
return -1L;
|
||||
#endif /* !HASFLOCK */
|
||||
}
|
||||
|
||||
int
|
||||
/*
|
||||
** LOCKTESTRD -- test file locking for reading
|
||||
**
|
||||
** Parameters:
|
||||
** filename -- name of file.
|
||||
** flags -- flags for open(2)
|
||||
** delay -- how long is file locked by owner?
|
||||
** shared -- LOCK_{EX/SH}
|
||||
**
|
||||
** Returns:
|
||||
** 0 on success
|
||||
** != 0 on failure.
|
||||
*/
|
||||
|
||||
static int
|
||||
locktestrd(filename, flags, delay, shared)
|
||||
char *filename;
|
||||
int flags;
|
||||
@ -252,6 +318,16 @@ locktestrd(filename, flags, delay, shared)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** USAGE -- show usage
|
||||
**
|
||||
** Parameters:
|
||||
** prg -- name of program
|
||||
**
|
||||
** Returns:
|
||||
** nothing.
|
||||
*/
|
||||
|
||||
static void
|
||||
usage(prg)
|
||||
const char *prg;
|
||||
@ -264,6 +340,12 @@ usage(prg)
|
||||
"-r use shared locking for reader\n"
|
||||
"-s delay sleep delay seconds before unlocking\n"
|
||||
"-W only start writer process\n"
|
||||
#if !HASFLOCK
|
||||
"uses fcntl()\n"
|
||||
#else
|
||||
"uses flock()\n"
|
||||
#endif
|
||||
|
||||
, prg);
|
||||
}
|
||||
|
||||
@ -335,7 +417,7 @@ main(argc, argv)
|
||||
r = 0;
|
||||
if (reader || fpid == 0)
|
||||
{
|
||||
/* give the parent the chance to setup data */
|
||||
/* give the parent the chance to set up data */
|
||||
pid = getpid();
|
||||
sleep(1);
|
||||
r = locktestrd(filename, flags, nb ? delay : 0, shared);
|
||||
|
@ -1702,7 +1702,7 @@ hashname(name)
|
||||
MD5_CTX ctx;
|
||||
unsigned char md5[18];
|
||||
# if MAXPATHLEN <= 24
|
||||
# ERROR "MAXPATHLEN <= 24"
|
||||
# error "MAXPATHLEN <= 24"
|
||||
# endif
|
||||
char b64[24];
|
||||
MD5_LONG bits;
|
||||
|
@ -26,6 +26,8 @@ makemap
|
||||
.IR commentchar ]
|
||||
.RB [ \-e ]
|
||||
.RB [ \-f ]
|
||||
.RB [ \-i
|
||||
.IR type ]
|
||||
.RB [ \-l ]
|
||||
.RB [ \-o ]
|
||||
.RB [ \-r ]
|
||||
@ -144,6 +146,12 @@ This is intended to mesh with the
|
||||
line in sendmail.cf.
|
||||
The value is never case folded.
|
||||
.TP
|
||||
.B \-i
|
||||
Use the specified type as fallback
|
||||
if the given
|
||||
.I maptype
|
||||
is not available.
|
||||
.TP
|
||||
.B \-l
|
||||
List supported map types.
|
||||
.TP
|
||||
|
@ -53,12 +53,17 @@ bool DontInitGroups = false;
|
||||
uid_t TrustedUid = 0;
|
||||
BITMAP256 DontBlameSendmail;
|
||||
|
||||
static bool verbose = false;
|
||||
static int exitstat;
|
||||
|
||||
#define BUFSIZE 1024
|
||||
#define ISASCII(c) isascii((unsigned char)(c))
|
||||
#define ISSPACE(c) (ISASCII(c) && isspace(c))
|
||||
#define ISSEP(c) (sep == '\0' ? ISASCII(c) && isspace(c) : (c) == sep)
|
||||
|
||||
static void usage __P((const char *));
|
||||
static char *readcf __P((const char *, char *, bool));
|
||||
static void db_put __P((SMDB_DATABASE *, SMDB_DBENT, SMDB_DBENT, int, const char *, int, const char *));
|
||||
|
||||
static void
|
||||
usage(progname)
|
||||
@ -68,7 +73,7 @@ usage(progname)
|
||||
"Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n",
|
||||
progname);
|
||||
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
" %*s [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter]\n",
|
||||
" %*s [-d] [-e] [-f] [-i type] [-l] [-o] [-r] [-s] [-t delimiter]\n",
|
||||
(int) strlen(progname), "");
|
||||
#if _FFR_TESTS
|
||||
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
@ -81,6 +86,69 @@ usage(progname)
|
||||
exit(EX_USAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
** DB_PUT -- do the DB insert
|
||||
**
|
||||
** Parameters:
|
||||
** database -- DB to use
|
||||
** db_key -- key
|
||||
** db_val -- value
|
||||
** putflags -- flags for smdb_put()
|
||||
** mapname -- name of map (for error reporting)
|
||||
** lineno -- line number (for error reporting)
|
||||
** progname -- name of program (for error reporting)
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
**
|
||||
** Side effects:
|
||||
** Sets exitstat so makemap exits with error if put fails
|
||||
*/
|
||||
|
||||
static void
|
||||
db_put(database, db_key, db_val, putflags, mapname, lineno, progname)
|
||||
SMDB_DATABASE *database;
|
||||
SMDB_DBENT db_key, db_val;
|
||||
int putflags;
|
||||
const char *mapname;
|
||||
int lineno;
|
||||
const char *progname;
|
||||
{
|
||||
int errcode;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"key=`%s', val=`%s'\n",
|
||||
(char *) db_key.data,
|
||||
(char *) db_val.data);
|
||||
}
|
||||
|
||||
errcode = database->smdb_put(database, &db_key, &db_val, putflags);
|
||||
if (0 == errcode)
|
||||
return;
|
||||
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s: %s: ",
|
||||
progname, mapname);
|
||||
if (lineno >= 0)
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "line %u: ",
|
||||
lineno);
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "key %s: ",
|
||||
(char *) db_key.data);
|
||||
if (SMDBE_KEY_EXIST == errcode)
|
||||
{
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
"duplicate key\n");
|
||||
exitstat = EX_DATAERR;
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
"put error: %s\n", sm_errstring(errcode));
|
||||
exitstat = EX_IOERR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** READCF -- read some settings from configuration file.
|
||||
**
|
||||
@ -106,7 +174,7 @@ readcf(cfile, mapfile, fullpath)
|
||||
SM_FILE_T *cfp;
|
||||
char buf[MAXLINE];
|
||||
static char classbuf[MAXLINE];
|
||||
char *classname;
|
||||
char *classname, *mapname;
|
||||
char *p;
|
||||
|
||||
if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile,
|
||||
@ -120,13 +188,21 @@ readcf(cfile, mapfile, fullpath)
|
||||
classname = NULL;
|
||||
classbuf[0] = '\0';
|
||||
|
||||
mapname = mapfile;
|
||||
if (!fullpath && mapfile != NULL)
|
||||
{
|
||||
p = strrchr(mapfile, '/');
|
||||
if (p != NULL)
|
||||
mapfile = ++p;
|
||||
p = strrchr(mapfile, '.');
|
||||
if (p != NULL)
|
||||
mapname = strdup(mapfile);
|
||||
if (NULL == mapname)
|
||||
{
|
||||
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
"makemap: strdup(%s) failed: %s\n",
|
||||
mapfile, sm_errstring(errno));
|
||||
exit(EX_OSERR);
|
||||
}
|
||||
if ((p = strchr(mapname, '.')) != NULL)
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
@ -184,18 +260,19 @@ readcf(cfile, mapfile, fullpath)
|
||||
case 'K': /* Keyfile (map) */
|
||||
if (classname != NULL) /* found it already */
|
||||
continue;
|
||||
if (mapfile == NULL || *mapfile == '\0')
|
||||
if (mapname == NULL || *mapname == '\0')
|
||||
continue;
|
||||
|
||||
/* cut off trailing spaces */
|
||||
for (p = buf + strlen(buf) - 1; ISASCII(*p) && isspace(*p) && p > buf; p--)
|
||||
for (p = buf + strlen(buf) - 1;
|
||||
ISASCII(*p) && isspace(*p) && p > buf; p--)
|
||||
*p = '\0';
|
||||
|
||||
/* find the last argument */
|
||||
p = strrchr(buf, ' ');
|
||||
if (p == NULL)
|
||||
continue;
|
||||
b = strstr(p, mapfile);
|
||||
b = strstr(p, mapname);
|
||||
if (b == NULL)
|
||||
continue;
|
||||
if (b <= buf)
|
||||
@ -208,7 +285,7 @@ readcf(cfile, mapfile, fullpath)
|
||||
}
|
||||
|
||||
/* allow trailing white space? */
|
||||
if (strcmp(mapfile, b) != 0)
|
||||
if (strcmp(mapname, b) != 0)
|
||||
continue;
|
||||
/* SM_ASSERT(b > buf); */
|
||||
--b;
|
||||
@ -253,6 +330,12 @@ readcf(cfile, mapfile, fullpath)
|
||||
}
|
||||
(void) sm_io_close(cfp, SM_TIME_DEFAULT);
|
||||
|
||||
/* not really needed because it is just a "one time leak" */
|
||||
if (mapname != mapfile && mapname != NULL)
|
||||
{
|
||||
free(mapname);
|
||||
mapname = NULL;
|
||||
}
|
||||
return classbuf;
|
||||
}
|
||||
|
||||
@ -267,19 +350,24 @@ main(argc, argv)
|
||||
bool notrunc = false;
|
||||
bool allowreplace = false;
|
||||
bool allowempty = false;
|
||||
bool verbose = false;
|
||||
bool foldcase = true;
|
||||
bool unmake = false;
|
||||
#if _FFR_MM_ALIASES
|
||||
/*
|
||||
** NOTE: this does not work properly:
|
||||
** sendmail does address rewriting which is not done here.
|
||||
*/
|
||||
|
||||
bool aliases = false;
|
||||
#endif
|
||||
bool didreadcf = false;
|
||||
char sep = '\0';
|
||||
char comment = '#';
|
||||
int exitstat;
|
||||
int opt;
|
||||
char *typename = NULL;
|
||||
char *fallback = NULL;
|
||||
char *mapname = NULL;
|
||||
unsigned int lineno;
|
||||
int st;
|
||||
int mode;
|
||||
int smode;
|
||||
int putflags = 0;
|
||||
@ -327,12 +415,17 @@ main(argc, argv)
|
||||
SMDB_MAX_USER_NAME_LEN);
|
||||
|
||||
#define OPTIONS "C:D:Nc:defi:Llorst:uvx"
|
||||
#if _FFR_MM_ALIASES
|
||||
# define A_OPTIONS "a"
|
||||
#else
|
||||
# define A_OPTIONS
|
||||
#endif
|
||||
#if _FFR_TESTS
|
||||
# define X_OPTIONS "S:"
|
||||
#else
|
||||
# define X_OPTIONS
|
||||
#endif
|
||||
while ((opt = getopt(argc, argv, OPTIONS X_OPTIONS)) != -1)
|
||||
while ((opt = getopt(argc, argv, A_OPTIONS OPTIONS X_OPTIONS)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
@ -344,6 +437,14 @@ main(argc, argv)
|
||||
inclnull = true;
|
||||
break;
|
||||
|
||||
#if _FFR_MM_ALIASES
|
||||
case 'a':
|
||||
/* Note: this doesn't verify e-mail addresses */
|
||||
sep = ':';
|
||||
aliases = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'c':
|
||||
params.smdbp_cache_size = atol(optarg);
|
||||
break;
|
||||
@ -669,6 +770,10 @@ main(argc, argv)
|
||||
*p++ = '\0';
|
||||
while (*p != '\0' && ISSEP(*p))
|
||||
p++;
|
||||
#if _FFR_MM_ALIASES
|
||||
while (aliases && *p != '\0' && ISSPACE(*p))
|
||||
p++;
|
||||
#endif
|
||||
if (!allowempty && *p == '\0')
|
||||
{
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
@ -688,50 +793,22 @@ main(argc, argv)
|
||||
** Do the database insert.
|
||||
*/
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"key=`%s', val=`%s'\n",
|
||||
(char *) db_key.data,
|
||||
(char *) db_val.data);
|
||||
}
|
||||
|
||||
errno = database->smdb_put(database, &db_key, &db_val,
|
||||
putflags);
|
||||
switch (errno)
|
||||
{
|
||||
case SMDBE_KEY_EXIST:
|
||||
st = 1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
st = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
st = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (st < 0)
|
||||
{
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
"%s: %s: line %u: key %s: put error: %s\n",
|
||||
progname, mapname, lineno,
|
||||
(char *) db_key.data,
|
||||
sm_errstring(errno));
|
||||
exitstat = EX_IOERR;
|
||||
}
|
||||
else if (st > 0)
|
||||
{
|
||||
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
|
||||
"%s: %s: line %u: key %s: duplicate key\n",
|
||||
progname, mapname,
|
||||
lineno,
|
||||
(char *) db_key.data);
|
||||
exitstat = EX_DATAERR;
|
||||
}
|
||||
db_put(database, db_key, db_val, putflags, mapname,
|
||||
lineno, progname);
|
||||
}
|
||||
#if _FFR_MM_ALIASES
|
||||
if (aliases)
|
||||
{
|
||||
char magic[2] = "@";
|
||||
|
||||
db_key.data = magic;
|
||||
db_val.data = magic;
|
||||
db_key.size = 1;
|
||||
db_val.size = 1;
|
||||
db_put(database, db_key, db_val, putflags, mapname, -1,
|
||||
progname);
|
||||
}
|
||||
#endif /* _FFR_MM_ALIASES */
|
||||
}
|
||||
|
||||
#if _FFR_TESTS
|
||||
|
@ -51,7 +51,7 @@ the bin directory used by smrsh.
|
||||
path.
|
||||
-DSMRSH_CMDDIR=\"dir\" \"/usr/adm/sm.bin\" The default smrsh
|
||||
program directory
|
||||
|
||||
|
||||
These can be added to the devtools/Site/site.config.m4 file using the
|
||||
global M4 macro confENVDEF or the smrsh specific M4 macro
|
||||
conf_smrsh_ENVDEF.
|
||||
|
@ -6,7 +6,7 @@ define(`confREQUIRE_SM_OS_H', `true')
|
||||
bldPRODUCT_START(`executable', `sendmail')
|
||||
define(`bldBIN_TYPE', `G')
|
||||
define(`bldINSTALL_DIR', `')
|
||||
define(`bldSOURCES', `main.c alias.c arpadate.c bf.c collect.c conf.c control.c convtime.c daemon.c deliver.c domain.c envelope.c err.c headers.c macro.c map.c mci.c milter.c mime.c parseaddr.c queue.c ratectrl.c readcf.c recipient.c sasl.c savemail.c sfsasl.c shmticklib.c sm_resolve.c srvrsmtp.c stab.c stats.c sysexits.c timers.c tlsh.c tls.c trace.c udb.c usersmtp.c util.c version.c ')
|
||||
define(`bldSOURCES', `main.c alias.c arpadate.c bf.c collect.c conf.c control.c convtime.c daemon.c deliver.c domain.c envelope.c err.c headers.c macro.c map.c mci.c milter.c mime.c parseaddr.c queue.c ratectrl.c readcf.c recipient.c sasl.c savemail.c sched.c sfsasl.c shmticklib.c sm_resolve.c srvrsmtp.c stab.c stats.c sysexits.c timers.c tlsh.c tls.c trace.c udb.c usersmtp.c util.c version.c ')
|
||||
PREPENDDEF(`confENVDEF', `confMAPDEF')
|
||||
bldPUSH_SMLIB(`sm')
|
||||
bldPUSH_SMLIB(`smutil')
|
||||
|
@ -232,8 +232,8 @@ HASFLOCK Set this if you prefer to use the flock(2) system call
|
||||
rather than using fcntl-based locking. Fcntl locking
|
||||
has some semantic gotchas, but many vendor systems
|
||||
also interface it to lockd(8) to do NFS-style locking.
|
||||
Unfortunately, may vendors implementations of fcntl locking
|
||||
is just plain broken (e.g., locks are never released,
|
||||
Unfortunately, many vendor implementations of fcntl locking
|
||||
are just plain broken (e.g., locks are never released,
|
||||
causing your sendmail to deadlock; when the kernel runs
|
||||
out of locks your system crashes). For this reason, I
|
||||
recommend always defining this unless you are absolutely
|
||||
@ -309,9 +309,9 @@ HASSTRERROR Define this if you have the libc strerror(3) function (which
|
||||
HASCLOSEFROM Define this if your system has closefrom(3).
|
||||
HASFDWALK Define this if your system has fdwalk(3).
|
||||
SM_CONF_GETOPT Define this as 0 if you need a reimplementation of getopt(3).
|
||||
On some systems, getopt does very odd things if called
|
||||
On some systems, getopt() does very odd things if called
|
||||
to scan the arguments twice. This flag will ask sendmail
|
||||
to compile in a local version of getopt that works
|
||||
to compile in a local version of getopt() that works
|
||||
properly. You may also need this if you build with
|
||||
another library that introduces a non-standard getopt(3).
|
||||
NEEDSTRTOL Define this if your standard C library does not define
|
||||
@ -625,7 +625,7 @@ SHARE_V1 Support for the fair share scheduler, version 1. Setting to
|
||||
resource limitations. So far as I know, this is only
|
||||
supported on ConvexOS.
|
||||
SASL Enables SMTP AUTH (RFC 2554). This requires the Cyrus SASL
|
||||
library (ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/). Please
|
||||
library (https://github.com/cyrusimap/cyrus-sasl). Please
|
||||
install at least version 1.5.13. See below for further
|
||||
information: SASL COMPILATION AND CONFIGURATION. If your
|
||||
SASL library is older than 1.5.10, you have to set this
|
||||
@ -640,7 +640,9 @@ EGD Define this if your system has EGD installed, see
|
||||
http://egd.sourceforge.net/ . It should be used to
|
||||
seed the PRNG for STARTTLS if HASURANDOMDEV is not defined.
|
||||
STARTTLS Enables SMTP STARTTLS (RFC 2487). This requires OpenSSL
|
||||
(http://www.OpenSSL.org/); use OpenSSL 0.9.8zc or later.
|
||||
(http://www.OpenSSL.org/); use an OpenSSL version
|
||||
which is supported by sendmail and preferably your
|
||||
OS distribution or OpenSSL.
|
||||
See STARTTLS COMPILATION AND CONFIGURATION for further
|
||||
information.
|
||||
TLS_EC Enable use of elliptic curve cryptography in STARTTLS.
|
||||
@ -765,6 +767,10 @@ From: Garrett Wollman <wollman@lcs.mit.edu>
|
||||
certificate authentication -- even some of those which already support
|
||||
SSL/TLS for confidentiality.
|
||||
|
||||
OpenSSL 3 deprecated a lot of functionality which sendmail uses by
|
||||
default. However, the code can be disabled via compile time options
|
||||
if needed:
|
||||
-DNO_DH: related to DH and DSA.
|
||||
|
||||
+------------------------------------+
|
||||
| SASL COMPILATION AND CONFIGURATION |
|
||||
@ -1804,6 +1810,7 @@ conf.h Configuration that must be known everywhere.
|
||||
control.c Routines to implement control socket.
|
||||
convtime.c A routine to sanely process times.
|
||||
daemon.c Routines to implement daemon mode.
|
||||
daemon.h Header file for daemon.c.
|
||||
deliver.c Routines to deliver mail.
|
||||
domain.c Routines that interface with DNS (the Domain Name
|
||||
System).
|
||||
@ -1818,17 +1825,21 @@ main.c The main routine to sendmail. This file also
|
||||
contains some miscellaneous routines.
|
||||
makesendmail A convenience for calling ./Build.
|
||||
map.c Support for database maps.
|
||||
map.h Header file for map.c.
|
||||
mci.c Routines that handle mail connection information caching.
|
||||
milter.c MTA portions of the mail filter API.
|
||||
mime.c MIME conversion routines.
|
||||
newaliases.1 Man page for the newaliases command.
|
||||
parseaddr.c The routines which do address parsing.
|
||||
queue.c Routines to implement message queueing.
|
||||
ratectrl.c Routines for rate/connnection control.
|
||||
ratectrl.h Header file for rate/connnection control.
|
||||
readcf.c The routine that reads the configuration file and
|
||||
translates it to internal form.
|
||||
recipient.c Routines that manipulate the recipient list.
|
||||
sasl.c Routines to interact with Cyrys-SASL.
|
||||
savemail.c Routines which save the letter on processing errors.
|
||||
sched.c Routines for scheduling queue management.
|
||||
sendmail.8 Man page for the sendmail command.
|
||||
sendmail.h Main header file for sendmail.
|
||||
sfsasl.c I/O interface between SASL/TLS and the MTA.
|
||||
@ -1846,6 +1857,8 @@ sysexits.h List of error codes for systems that lack their own.
|
||||
timers.c Routines to provide microtimers.
|
||||
timers.h Data structure and function declarations for timers.h.
|
||||
tls.c Routines for TLS.
|
||||
tls.h Header file for tls*.c
|
||||
tlsh.c Helper routines for TLS, mostly DANE.
|
||||
trace.c The trace package. These routines allow setting and
|
||||
testing of trace flags with a high granularity.
|
||||
udb.c The user database interface module.
|
||||
|
@ -14,12 +14,12 @@ people who are very security conscious (you should be...).
|
||||
Even though sendmail goes through great lengths to assure that it
|
||||
can't be compromised even if the system it is running on is
|
||||
incorrectly or insecurely configured, it can't work around everything.
|
||||
This has been demonstrated by recent OS problems which have
|
||||
subsequently been used to compromise the root account using sendmail
|
||||
as a vector. One way to minimize the possibility of such problems
|
||||
is to install sendmail without set-user-ID root, which avoids local
|
||||
exploits. This configuration, which is the default starting with
|
||||
8.12, is described in the first section of this security guide.
|
||||
This has been demonstrated by OS problems which have subsequently
|
||||
been used to compromise the root account using sendmail as a vector.
|
||||
One way to minimize the possibility of such problems is to install
|
||||
sendmail without set-user-ID root, which avoids local exploits.
|
||||
This configuration, which is the default starting with 8.12, is
|
||||
described in the first section of this security guide.
|
||||
|
||||
|
||||
*****************************************************
|
||||
@ -112,6 +112,7 @@ information.) You can start this program as root, it will change
|
||||
its user id to RunAsUser (smmsp by default, recommended uid: 25).
|
||||
This way smmsp does not need a valid shell.
|
||||
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
@ -186,6 +187,7 @@ You can use
|
||||
to install a sendmail program to act as daemon etc under the name
|
||||
sm-mta.
|
||||
|
||||
|
||||
Set-User-Id
|
||||
-----------
|
||||
|
||||
|
@ -71,15 +71,14 @@
|
||||
57 util.c snprintf
|
||||
58 bf.c bf* routines
|
||||
59 parseaddr.c cataddr
|
||||
60 map.c
|
||||
60 parseaddr.c map_lookup
|
||||
61 conf.c sm_gethostbyname
|
||||
62 multiple file descriptor checking
|
||||
63 queue.c runqueue process watching
|
||||
64 multiple Milter
|
||||
65 main.c permission checks
|
||||
#if DANE
|
||||
66 domain.c force port=25 for TLSA RR lookups
|
||||
67 domain.c TLSA RR lookups
|
||||
66,>99 domain.c force port=25 for TLSA RR lookups
|
||||
#endif
|
||||
68 unused
|
||||
#if _FFR_QUEUE_SCHED_DBG
|
||||
@ -105,19 +104,26 @@
|
||||
83 collect.c timeout
|
||||
84 deliver.c timeout
|
||||
85 map.c dprintf map
|
||||
#if _FFR_TESTS
|
||||
86,>99 milter.c macro tests
|
||||
#endif
|
||||
#if _FFR_PROXY
|
||||
87 srvrsmtp.c proxy mode
|
||||
#endif
|
||||
88,>99 tls.c disable the effect of _FFR_VRFY_TRUSTED_FIRST
|
||||
89 conf.c >=8 use sm_dprintf() instead of syslog()
|
||||
90 unused
|
||||
#if _FFR_TESTS
|
||||
90,>99 tls.c deliver.c Simulate error for OpenSSL functions related to DANE
|
||||
#endif
|
||||
91 mci.c syslogging of MCI cache information
|
||||
92 EF_LOGSENDER
|
||||
93,>99 * Prevent daemon connection fork for profiling/debugging
|
||||
94,>99 srvrsmtp.c cause commands to fail (for protocol testing)
|
||||
95 srvrsmtp.c AUTH
|
||||
95 usersmtp.c AUTH
|
||||
96 tls.c DHparam info, Activate SSL_CTX_set_info_callback()
|
||||
96 tls.c DHparam info, activate SSL_CTX_set_info_callback(), etc
|
||||
97 srvrsmtp.c Trace automode settings for I/O
|
||||
#if _FFR_TIMERS
|
||||
98 * timers
|
||||
#endif
|
||||
99 main.c avoid backgrounding (no printed output)
|
||||
|
@ -381,10 +381,11 @@ setalias(spec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** ALIASWAIT -- wait for distinguished @:@ token to appear.
|
||||
**
|
||||
** This can decide to reopen or rebuild the alias file
|
||||
** This can decide to reopen the alias file
|
||||
**
|
||||
** Parameters:
|
||||
** map -- a pointer to the map descriptor for this alias file.
|
||||
@ -402,7 +403,7 @@ setalias(spec)
|
||||
bool
|
||||
aliaswait(map, ext, isopen)
|
||||
MAP *map;
|
||||
char *ext;
|
||||
const char *ext;
|
||||
bool isopen;
|
||||
{
|
||||
bool attimeout = false;
|
||||
@ -411,13 +412,14 @@ aliaswait(map, ext, isopen)
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
if (tTd(27, 3))
|
||||
sm_dprintf("aliaswait(%s:%s)\n",
|
||||
map->map_class->map_cname, map->map_file);
|
||||
sm_dprintf("aliaswait(%s:%s), open=%d, wait=%d\n",
|
||||
map->map_class->map_cname, map->map_file,
|
||||
isopen, bitset(MF_ALIASWAIT, map->map_mflags));
|
||||
if (bitset(MF_ALIASWAIT, map->map_mflags))
|
||||
return isopen;
|
||||
map->map_mflags |= MF_ALIASWAIT;
|
||||
|
||||
if (SafeAlias > 0)
|
||||
if (isopen && SafeAlias > 0)
|
||||
{
|
||||
auto int st;
|
||||
unsigned int sleeptime = 2;
|
||||
@ -448,7 +450,7 @@ aliaswait(map, ext, isopen)
|
||||
|
||||
map->map_mflags |= MF_CLOSING;
|
||||
map->map_class->map_close(map);
|
||||
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
|
||||
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING|MF_CHKED_CHGD);
|
||||
(void) sleep(sleeptime);
|
||||
sleeptime *= 2;
|
||||
if (sleeptime > 60)
|
||||
@ -456,6 +458,7 @@ aliaswait(map, ext, isopen)
|
||||
isopen = map->map_class->map_open(map, O_RDONLY);
|
||||
}
|
||||
}
|
||||
map->map_mflags &= ~MF_CHKED_CHGD;
|
||||
|
||||
/* see if we need to go into auto-rebuild mode */
|
||||
if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
|
||||
@ -499,20 +502,17 @@ aliaswait(map, ext, isopen)
|
||||
**
|
||||
** Parameters:
|
||||
** map -- the database to rebuild.
|
||||
** automatic -- set if this was automatically generated.
|
||||
**
|
||||
** Returns:
|
||||
** true if successful; false otherwise.
|
||||
**
|
||||
** Side Effects:
|
||||
** Reads the text version of the database, builds the
|
||||
** DBM or DB version.
|
||||
** Reads the text version of the database, builds the map.
|
||||
*/
|
||||
|
||||
bool
|
||||
rebuildaliases(map, automatic)
|
||||
rebuildaliases(map)
|
||||
register MAP *map;
|
||||
bool automatic;
|
||||
{
|
||||
SM_FILE_T *af;
|
||||
bool nolock = false;
|
||||
@ -538,7 +538,7 @@ rebuildaliases(map, automatic)
|
||||
{
|
||||
struct stat stb;
|
||||
|
||||
if ((errno != EACCES && errno != EROFS) || automatic ||
|
||||
if ((errno != EACCES && errno != EROFS) ||
|
||||
(af = safefopen(map->map_file, O_RDONLY, 0, sff)) == NULL)
|
||||
{
|
||||
int saveerr = errno;
|
||||
@ -546,7 +546,7 @@ rebuildaliases(map, automatic)
|
||||
if (tTd(27, 1))
|
||||
sm_dprintf("Can't open %s: %s\n",
|
||||
map->map_file, sm_errstring(saveerr));
|
||||
if (!automatic && !bitset(MF_OPTIONAL, map->map_mflags))
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
message("newaliases: cannot open %s: %s",
|
||||
map->map_file, sm_errstring(saveerr));
|
||||
errno = 0;
|
||||
@ -590,13 +590,12 @@ rebuildaliases(map, automatic)
|
||||
if (LogLevel > 7)
|
||||
{
|
||||
sm_syslog(LOG_NOTICE, NOQID,
|
||||
"alias database %s %srebuilt by %s",
|
||||
map->map_file, automatic ? "auto" : "",
|
||||
username());
|
||||
"alias database %s rebuilt by %s",
|
||||
map->map_file, username());
|
||||
}
|
||||
map->map_mflags |= MF_OPEN|MF_WRITABLE;
|
||||
map->map_pid = CurrentPid;
|
||||
readaliases(map, af, !automatic, true);
|
||||
readaliases(map, af, true, true);
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
@ -604,9 +603,8 @@ rebuildaliases(map, automatic)
|
||||
if (tTd(27, 1))
|
||||
sm_dprintf("Can't create database for %s: %s\n",
|
||||
map->map_file, sm_errstring(errno));
|
||||
if (!automatic)
|
||||
syserr("Cannot create database for alias file %s",
|
||||
map->map_file);
|
||||
syserr("Cannot create database for alias file %s",
|
||||
map->map_file);
|
||||
}
|
||||
|
||||
/* close the file, thus releasing locks */
|
||||
@ -621,8 +619,10 @@ rebuildaliases(map, automatic)
|
||||
int sl;
|
||||
|
||||
sl = tTdlevel(78) - 100;
|
||||
sm_dprintf("rebuildaliases: sleep=%d\n", sl);
|
||||
sm_dprintf("rebuildaliases: sleep=%d, file=%s\n",
|
||||
sl, map->map_file);
|
||||
sleep(sl);
|
||||
sm_dprintf("rebuildaliases: done\n");
|
||||
}
|
||||
#endif
|
||||
map->map_mflags |= MF_CLOSING;
|
||||
@ -638,6 +638,54 @@ rebuildaliases(map, automatic)
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
** CONTLINE -- handle potential continuation line
|
||||
**
|
||||
** Parameters:
|
||||
** fp -- file to read
|
||||
** line -- current line
|
||||
**
|
||||
** Returns:
|
||||
** pointer to end of current line if there is a continuation line
|
||||
** NULL otherwise
|
||||
**
|
||||
** Side Effects:
|
||||
** Modifies line if it is a continuation line
|
||||
*/
|
||||
|
||||
static char *contline __P((SM_FILE_T *, char *));
|
||||
static char *
|
||||
contline(fp, line)
|
||||
SM_FILE_T *fp;
|
||||
char *line;
|
||||
{
|
||||
char *p;
|
||||
int c;
|
||||
|
||||
if ((p = strchr(line, '\n')) != NULL && p > line && p[-1] == '\\')
|
||||
{
|
||||
*p = '\0';
|
||||
*--p = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
c = sm_io_getc(fp, SM_TIME_DEFAULT);
|
||||
if (!sm_io_eof(fp))
|
||||
(void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c);
|
||||
if (c == ' ' || c == '\t')
|
||||
{
|
||||
char *nlp;
|
||||
|
||||
p = line;
|
||||
nlp = &p[strlen(p)];
|
||||
if (nlp > p && nlp[-1] == '\n')
|
||||
*--nlp = '\0';
|
||||
return nlp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
** READALIASES -- read and process the alias file.
|
||||
**
|
||||
@ -688,48 +736,74 @@ readaliases(map, af, announcestats, logstats)
|
||||
naliases = bytes = longest = 0;
|
||||
skipping = false;
|
||||
line = NULL;
|
||||
|
||||
while (sm_io_fgets(af, SM_TIME_DEFAULT, lbuf, sizeof(lbuf)) >= 0)
|
||||
{
|
||||
int lhssize, rhssize;
|
||||
int c;
|
||||
char *newp;
|
||||
|
||||
LineNumber++;
|
||||
#if _FFR_8BITENVADDR
|
||||
if (line != lbuf)
|
||||
SM_FREE(line);
|
||||
len = 0;
|
||||
line = quote_internal_chars(lbuf, NULL, &len, NULL);
|
||||
#else
|
||||
line = lbuf;
|
||||
#endif
|
||||
p = strchr(line, '\n');
|
||||
|
||||
/* XXX what if line="a\\" ? */
|
||||
while (p != NULL && p > line && p[-1] == '\\')
|
||||
line = lbuf;
|
||||
p = line;
|
||||
while ((newp = contline(af, line)) != NULL)
|
||||
{
|
||||
p--;
|
||||
if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
|
||||
SPACELEFT(line, p)) < 0)
|
||||
p = newp;
|
||||
if ((c = sm_io_fgets(af, SM_TIME_DEFAULT, p,
|
||||
SPACELEFT(lbuf, p))) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
LineNumber++;
|
||||
p = strchr(p, '\n');
|
||||
}
|
||||
#if _FFR_8BITENVADDR
|
||||
if (SMTP_UTF8 || EightBitAddrOK)
|
||||
{
|
||||
if (line != lbuf)
|
||||
SM_FREE(line);
|
||||
line = quote_internal_chars(lbuf, NULL, &len, NULL);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* "else" in #if code above */
|
||||
line = lbuf;
|
||||
|
||||
p = strchr(line, '\n');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
else if (!sm_io_eof(af))
|
||||
{
|
||||
int prev;
|
||||
bool cl;
|
||||
|
||||
errno = 0;
|
||||
syserr("554 5.3.0 alias line too long");
|
||||
|
||||
/* flush to end of line */
|
||||
while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) !=
|
||||
SM_IO_EOF && c != '\n')
|
||||
continue;
|
||||
prev = '\0';
|
||||
cl = false;
|
||||
|
||||
do {
|
||||
/* flush to end of "virtual" line */
|
||||
while ((c = sm_io_getc(af, SM_TIME_DEFAULT)) !=
|
||||
SM_IO_EOF && c != '\n')
|
||||
{
|
||||
prev = c;
|
||||
}
|
||||
cl = ('\\' == prev && '\n' == c);
|
||||
if (!cl)
|
||||
{
|
||||
c = sm_io_getc(af, SM_TIME_DEFAULT);
|
||||
if (!sm_io_eof(af))
|
||||
(void) sm_io_ungetc(af, SM_TIME_DEFAULT, c);
|
||||
cl = (c == ' ' || c == '\t');
|
||||
}
|
||||
} while (cl);
|
||||
|
||||
/* skip any continuation lines */
|
||||
skipping = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (line[0])
|
||||
{
|
||||
case '#':
|
||||
@ -779,7 +853,6 @@ readaliases(map, af, announcestats, logstats)
|
||||
while (SM_ISSPACE(*p))
|
||||
p++;
|
||||
rhs = p;
|
||||
for (;;)
|
||||
{
|
||||
register char *nlp;
|
||||
|
||||
@ -810,31 +883,7 @@ readaliases(map, af, announcestats, logstats)
|
||||
{
|
||||
p = nlp;
|
||||
}
|
||||
|
||||
/* see if there should be a continuation line */
|
||||
c = sm_io_getc(af, SM_TIME_DEFAULT);
|
||||
if (!sm_io_eof(af))
|
||||
(void) sm_io_ungetc(af, SM_TIME_DEFAULT, c);
|
||||
if (c != ' ' && c != '\t')
|
||||
break;
|
||||
|
||||
/* read continuation line */
|
||||
if (sm_io_fgets(af, SM_TIME_DEFAULT, p,
|
||||
sizeof(line) - (p-line)) < 0)
|
||||
break;
|
||||
LineNumber++;
|
||||
|
||||
/* check for line overflow */
|
||||
if (strchr(p, '\n') == NULL && !sm_io_eof(af))
|
||||
{
|
||||
usrerr("554 5.3.5 alias too long");
|
||||
while ((c = sm_io_getc(af, SM_TIME_DEFAULT))
|
||||
!= SM_IO_EOF && c != '\n')
|
||||
continue;
|
||||
skipping = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (skipping)
|
||||
continue;
|
||||
@ -868,17 +917,20 @@ readaliases(map, af, announcestats, logstats)
|
||||
{
|
||||
syserr("554 5.3.5 %.40s... missing value for alias",
|
||||
line);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
#if _FFR_8BITENVADDR
|
||||
dequote_internal_chars(al.q_user, lhsbuf, sizeof(lhsbuf));
|
||||
dequote_internal_chars(rhs, rhsbuf, sizeof(rhsbuf));
|
||||
map->map_class->map_store(map, lhsbuf, rhsbuf);
|
||||
#else
|
||||
map->map_class->map_store(map, al.q_user, rhs);
|
||||
if (SMTP_UTF8 || EightBitAddrOK)
|
||||
{
|
||||
dequote_internal_chars(al.q_user, lhsbuf, sizeof(lhsbuf));
|
||||
dequote_internal_chars(rhs, rhsbuf, sizeof(rhsbuf));
|
||||
map->map_class->map_store(map, lhsbuf, rhsbuf);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* "else" in #if code above */
|
||||
map->map_class->map_store(map, al.q_user, rhs);
|
||||
|
||||
/* statistics */
|
||||
naliases++;
|
||||
@ -947,7 +999,16 @@ forward(user, sendq, aliaslevel, e)
|
||||
/* good address -- look for .forward file in home */
|
||||
macdefine(&e->e_macro, A_PERM, 'z', user->q_home);
|
||||
macdefine(&e->e_macro, A_PERM, 'u', user->q_user);
|
||||
macdefine(&e->e_macro, A_PERM, 'h', user->q_host);
|
||||
pp = user->q_host;
|
||||
#if _FFR_8BITENVADDR
|
||||
if (NULL != pp)
|
||||
{
|
||||
int len;
|
||||
|
||||
pp = quote_internal_chars(pp, NULL, &len, NULL);
|
||||
}
|
||||
#endif
|
||||
macdefine(&e->e_macro, A_PERM, 'h', pp);
|
||||
if (ForwardPath == NULL)
|
||||
ForwardPath = newstr("\201z/.forward");
|
||||
|
||||
|
@ -61,7 +61,7 @@ struct bf
|
||||
int bf_buffilled; /* Bytes of buffer actually filled */
|
||||
char *bf_filename; /* Name of buffered file, if ever committed */
|
||||
MODE_T bf_filemode; /* Mode of buffered file, if ever committed */
|
||||
off_t bf_offset; /* Currect file offset */
|
||||
off_t bf_offset; /* Current file offset */
|
||||
int bf_size; /* Total current size of file */
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2006, 2008 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 1998-2006, 2008, 2023, 2024 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
@ -34,7 +34,7 @@ static SM_FILE_T *collect_eoh __P((ENVELOPE *, int, int));
|
||||
** numhdrs -- number of headers
|
||||
** hdrslen -- length of headers
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** NULL, or handle to open data file
|
||||
**
|
||||
** Side Effects:
|
||||
@ -82,7 +82,7 @@ collect_eoh(e, numhdrs, hdrslen)
|
||||
** Parameters:
|
||||
** e -- envelope
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** none.
|
||||
**
|
||||
** Side Effects:
|
||||
@ -179,7 +179,7 @@ collect_doheader(e)
|
||||
** Parameters:
|
||||
** e -- envelope
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** NULL, or a pointer to an open data file,
|
||||
** into which the message body will be written by collect().
|
||||
**
|
||||
@ -232,6 +232,70 @@ collect_dfopen(e)
|
||||
return df;
|
||||
}
|
||||
|
||||
/*
|
||||
** INCBUFLEN -- increase buflen for the header buffer in collect()
|
||||
**
|
||||
** Parameters:
|
||||
** buflen -- current size of buffer
|
||||
**
|
||||
** Returns:
|
||||
** new buflen
|
||||
*/
|
||||
|
||||
static int incbuflen __P((int));
|
||||
static int
|
||||
incbuflen(buflen)
|
||||
int buflen;
|
||||
{
|
||||
int newlen;
|
||||
|
||||
/* this also handles the case of MaxMessageSize == 0 */
|
||||
if (MaxMessageSize <= MEMCHUNKSIZE)
|
||||
{
|
||||
if (buflen < MEMCHUNKSIZE)
|
||||
return buflen * 2;
|
||||
else
|
||||
return buflen + MEMCHUNKSIZE;
|
||||
}
|
||||
|
||||
/* MaxMessageSize > MEMCHUNKSIZE */
|
||||
newlen = buflen * 2;
|
||||
if (newlen > 0 && newlen < MaxMessageSize)
|
||||
return newlen;
|
||||
else
|
||||
return MaxMessageSize;
|
||||
}
|
||||
|
||||
#if _FFR_TESTS
|
||||
/* just for testing/debug output */
|
||||
static const char *
|
||||
makeprint(c)
|
||||
char c;
|
||||
{
|
||||
static char prt[6];
|
||||
|
||||
prt[1] = '\0';
|
||||
prt[2] = '\0';
|
||||
if (isprint((unsigned char)c))
|
||||
prt[0] = c;
|
||||
else if ('\n' == c)
|
||||
{
|
||||
prt[0] = 'L';
|
||||
prt[1] = 'F';
|
||||
}
|
||||
else if ('\r' == c)
|
||||
{
|
||||
prt[0] = 'C';
|
||||
prt[1] = 'R';
|
||||
}
|
||||
else
|
||||
snprintf(prt, sizeof(prt), "%o", c);
|
||||
return prt;
|
||||
}
|
||||
#else /* _FFR_TESTS */
|
||||
# define makeprint(c) "X"
|
||||
#endif /* _FFR_TESTS */
|
||||
|
||||
/*
|
||||
** COLLECT -- read & parse message header & make temp file.
|
||||
**
|
||||
@ -241,10 +305,10 @@ collect_dfopen(e)
|
||||
**
|
||||
** Parameters:
|
||||
** fp -- file to read.
|
||||
** smtpmode -- if set, we are running SMTP: give an RFC821
|
||||
** style message to say we are ready to collect
|
||||
** input, and never ignore a single dot to mean
|
||||
** end of message.
|
||||
** smtpmode -- if >= SMTPMODE_LAX we are running SMTP:
|
||||
** give an RFC821 style message to say we are
|
||||
** ready to collect input, and never ignore
|
||||
** a single dot to mean end of message.
|
||||
** hdrp -- the location to stash the header.
|
||||
** e -- the current envelope.
|
||||
** rsetsize -- reset e_msgsize?
|
||||
@ -267,20 +331,26 @@ collect_dfopen(e)
|
||||
/* values for input state machine */
|
||||
#define IS_NORM 0 /* middle of line */
|
||||
#define IS_BOL 1 /* beginning of line */
|
||||
#define IS_DOT 2 /* read a dot at beginning of line */
|
||||
#define IS_DOT 2 /* read "." at beginning of line */
|
||||
#define IS_DOTCR 3 /* read ".\r" at beginning of line */
|
||||
#define IS_CR 4 /* read a carriage return */
|
||||
#define IS_CR 4 /* read "\r" */
|
||||
|
||||
/* hack to enhance readability of debug output */
|
||||
static const char *istates[] = { "NORM", "BOL", "DOT", "DOTCR", "CR" };
|
||||
#define ISTATE istates[istate]
|
||||
|
||||
/* values for message state machine */
|
||||
#define MS_UFROM 0 /* reading Unix from line */
|
||||
#define MS_HEADER 1 /* reading message header */
|
||||
#define MS_BODY 2 /* reading message body */
|
||||
#define MS_DISCARD 3 /* discarding rest of message */
|
||||
#define BARE_LF_MSG "Bare linefeed (LF) not allowed"
|
||||
#define BARE_CR_MSG "Bare carriage return (CR) not allowed"
|
||||
|
||||
void
|
||||
collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
SM_FILE_T *fp;
|
||||
bool smtpmode;
|
||||
int smtpmode;
|
||||
HDR **hdrp;
|
||||
register ENVELOPE *e;
|
||||
bool rsetsize;
|
||||
@ -306,12 +376,26 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
#if _FFR_REJECT_NUL_BYTE
|
||||
bool hasNUL; /* has at least one NUL input byte */
|
||||
#endif
|
||||
int bare_lf, bare_cr;
|
||||
|
||||
#define SMTPMODE (smtpmode >= SMTPMODE_LAX)
|
||||
#define SMTPMODE_STRICT ((smtpmode & SMTPMODE_CRLF) != 0)
|
||||
#define BARE_LF_421 ((smtpmode & SMTPMODE_LF_421) != 0)
|
||||
#define BARE_CR_421 ((smtpmode & SMTPMODE_CR_421) != 0)
|
||||
#define BARE_LF_SP ((smtpmode & SMTPMODE_LF_SP) != 0)
|
||||
#define BARE_CR_SP ((smtpmode & SMTPMODE_CR_SP) != 0)
|
||||
|
||||
/* for bare_{lf,cr} */
|
||||
#define BARE_IN_HDR 0x01
|
||||
#define BARE_IN_BDY 0x02
|
||||
#define BARE_WHERE ((MS_BODY == mstate) ? BARE_IN_BDY : BARE_IN_HDR)
|
||||
|
||||
df = NULL;
|
||||
ignrdot = smtpmode ? false : IgnrDot;
|
||||
ignrdot = SMTPMODE ? false : IgnrDot;
|
||||
bare_lf = bare_cr = 0;
|
||||
|
||||
/* timeout for I/O functions is in milliseconds */
|
||||
dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000)
|
||||
dbto = SMTPMODE ? ((int) TimeOuts.to_datablock * 1000)
|
||||
: SM_TIME_FOREVER;
|
||||
sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto);
|
||||
old_rd_tmo = set_tls_rd_tmo(TimeOuts.to_datablock);
|
||||
@ -334,15 +418,15 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
** Tell ARPANET to go ahead.
|
||||
*/
|
||||
|
||||
if (smtpmode)
|
||||
message("354 Enter mail, end with \".\" on a line by itself");
|
||||
if (SMTPMODE)
|
||||
message("354 End data with <CR><LF>.<CR><LF>");
|
||||
|
||||
/* simulate an I/O timeout when used as sink */
|
||||
if (tTd(83, 101))
|
||||
sleep(319);
|
||||
|
||||
if (tTd(30, 2))
|
||||
sm_dprintf("collect\n");
|
||||
sm_dprintf("collect, smtpmode=%#x\n", smtpmode);
|
||||
|
||||
/*
|
||||
** Read the message.
|
||||
@ -358,7 +442,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
for (;;)
|
||||
{
|
||||
if (tTd(30, 35))
|
||||
sm_dprintf("top, istate=%d, mstate=%d\n", istate,
|
||||
sm_dprintf("top, istate=%s, mstate=%d\n", ISTATE,
|
||||
mstate);
|
||||
for (;;)
|
||||
{
|
||||
@ -379,7 +463,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
|
||||
/* timeout? */
|
||||
if (c == SM_IO_EOF && errno == EAGAIN
|
||||
&& smtpmode)
|
||||
&& SMTPMODE)
|
||||
{
|
||||
/*
|
||||
** Override e_message in
|
||||
@ -417,15 +501,32 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
hasNUL = true;
|
||||
#endif
|
||||
if (c == SM_IO_EOF)
|
||||
goto readerr;
|
||||
if (SevenBitInput)
|
||||
goto readdone;
|
||||
if (SevenBitInput ||
|
||||
bitset(EF_7BITBODY, e->e_flags))
|
||||
c &= 0x7f;
|
||||
else
|
||||
HasEightBits |= bitset(0x80, c);
|
||||
}
|
||||
if (tTd(30, 94))
|
||||
sm_dprintf("istate=%d, c=%c (0x%x)\n",
|
||||
istate, (char) c, c);
|
||||
sm_dprintf("istate=%s, c=%s (0x%x)\n",
|
||||
ISTATE, makeprint((char) c), c);
|
||||
if ('\n' == c && SMTPMODE &&
|
||||
!(IS_CR == istate || IS_DOTCR == istate))
|
||||
{
|
||||
bare_lf |= BARE_WHERE;
|
||||
if (BARE_LF_421)
|
||||
{
|
||||
inputerr = true;
|
||||
goto readabort;
|
||||
}
|
||||
if (BARE_LF_SP)
|
||||
{
|
||||
if (TTD(30, 64))
|
||||
sm_dprintf("LF: c=%s %#x\n", makeprint((char) c), c);
|
||||
c = ' ';
|
||||
}
|
||||
}
|
||||
switch (istate)
|
||||
{
|
||||
case IS_BOL:
|
||||
@ -437,8 +538,8 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
break;
|
||||
|
||||
case IS_DOT:
|
||||
if (c == '\n' && !ignrdot)
|
||||
goto readerr;
|
||||
if (c == '\n' && !ignrdot && !SMTPMODE_STRICT)
|
||||
goto readdone;
|
||||
else if (c == '\r')
|
||||
{
|
||||
istate = IS_DOTCR;
|
||||
@ -460,7 +561,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
|
||||
case IS_DOTCR:
|
||||
if (c == '\n' && !ignrdot)
|
||||
goto readerr;
|
||||
goto readdone;
|
||||
else
|
||||
{
|
||||
/* push back the ".\rx" */
|
||||
@ -483,12 +584,30 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
|
||||
case IS_CR:
|
||||
if (c == '\n')
|
||||
{
|
||||
if (TTD(30, 64))
|
||||
sm_dprintf("state=CR, c=%s %#x -> BOL\n", makeprint((char) c), c);
|
||||
istate = IS_BOL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TTD(30, 64))
|
||||
sm_dprintf("state=CR, c=%s %#x -> NORM\n", makeprint((char) c), c);
|
||||
if (SMTPMODE)
|
||||
{
|
||||
bare_cr |= BARE_WHERE;
|
||||
if (BARE_CR_421)
|
||||
{
|
||||
inputerr = true;
|
||||
goto readabort;
|
||||
}
|
||||
}
|
||||
(void) sm_io_ungetc(fp, SM_TIME_DEFAULT,
|
||||
c);
|
||||
c = '\r';
|
||||
if (BARE_CR_SP)
|
||||
c = ' ';
|
||||
else
|
||||
c = '\r';
|
||||
istate = IS_NORM;
|
||||
}
|
||||
goto bufferchar;
|
||||
@ -499,7 +618,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
istate = IS_CR;
|
||||
continue;
|
||||
}
|
||||
else if (c == '\n')
|
||||
else if (c == '\n' && !SMTPMODE_STRICT)
|
||||
istate = IS_BOL;
|
||||
else
|
||||
istate = IS_NORM;
|
||||
@ -524,7 +643,8 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
if (!bitset(EF_TOOBIG, e->e_flags))
|
||||
(void) sm_io_putc(df, SM_TIME_DEFAULT,
|
||||
c);
|
||||
|
||||
if (TTD(30, 64))
|
||||
sm_dprintf("state=%s, put=%s %#x\n", ISTATE, makeprint((char) c), c);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case MS_DISCARD:
|
||||
@ -540,10 +660,9 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
|
||||
/* out of space for header */
|
||||
obuf = buf;
|
||||
if (buflen < MEMCHUNKSIZE)
|
||||
buflen *= 2;
|
||||
else
|
||||
buflen += MEMCHUNKSIZE;
|
||||
buflen = incbuflen(buflen);
|
||||
if (tTd(30, 32))
|
||||
sm_dprintf("buflen=%d, hdrslen=%d\n", buflen, hdrslen);
|
||||
if (buflen <= 0)
|
||||
{
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
@ -592,8 +711,8 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
|
||||
nextstate:
|
||||
if (tTd(30, 35))
|
||||
sm_dprintf("nextstate, istate=%d, mstate=%d, line=\"%s\"\n",
|
||||
istate, mstate, buf);
|
||||
sm_dprintf("nextstate, istate=%s, mstate=%d, line=\"%s\"\n",
|
||||
ISTATE, mstate, buf);
|
||||
switch (mstate)
|
||||
{
|
||||
case MS_UFROM:
|
||||
@ -624,7 +743,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
|
||||
/* timeout? */
|
||||
if (c == SM_IO_EOF && errno == EAGAIN
|
||||
&& smtpmode)
|
||||
&& SMTPMODE)
|
||||
{
|
||||
/*
|
||||
** Override e_message in
|
||||
@ -653,7 +772,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
/* guaranteed by isheader(buf) */
|
||||
SM_ASSERT(*(bp - 1) != '\n' || bp > buf + 1);
|
||||
|
||||
/* trim off trailing CRLF or NL */
|
||||
/* trim off trailing CRLF or LF */
|
||||
if (*--bp != '\n' || *--bp != '\r')
|
||||
bp++;
|
||||
*bp = '\0';
|
||||
@ -673,7 +792,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
sm_dprintf("EOH\n");
|
||||
|
||||
if (headeronly)
|
||||
goto readerr;
|
||||
goto readdone;
|
||||
|
||||
df = collect_eoh(e, numhdrs, hdrslen);
|
||||
if (df == NULL)
|
||||
@ -700,8 +819,8 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
bp = buf;
|
||||
}
|
||||
|
||||
readerr:
|
||||
if ((sm_io_eof(fp) && smtpmode) || sm_io_error(fp))
|
||||
readdone:
|
||||
if ((sm_io_eof(fp) && SMTPMODE) || sm_io_error(fp))
|
||||
{
|
||||
const char *errmsg;
|
||||
|
||||
@ -741,7 +860,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
}
|
||||
else if (SuperSafe == SAFE_NO ||
|
||||
SuperSafe == SAFE_INTERACTIVE ||
|
||||
(SuperSafe == SAFE_REALLY_POSTMILTER && smtpmode))
|
||||
(SuperSafe == SAFE_REALLY_POSTMILTER && SMTPMODE))
|
||||
{
|
||||
/* skip next few clauses */
|
||||
/* EMPTY */
|
||||
@ -806,33 +925,43 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
readabort:
|
||||
if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
|
||||
{
|
||||
char *host;
|
||||
char *problem;
|
||||
ADDRESS *q;
|
||||
|
||||
host = RealHostName;
|
||||
if (host == NULL)
|
||||
host = "localhost";
|
||||
|
||||
if (sm_io_eof(fp))
|
||||
problem = "unexpected close";
|
||||
else if (sm_io_error(fp))
|
||||
problem = "I/O error";
|
||||
else if (0 != bare_lf)
|
||||
problem = BARE_LF_MSG;
|
||||
else if (0 != bare_cr)
|
||||
problem = BARE_CR_MSG;
|
||||
else
|
||||
problem = "read timeout";
|
||||
if (LogLevel > 0 && sm_io_eof(fp))
|
||||
|
||||
#define LOG_CLT ((NULL != RealHostName) ? RealHostName: "localhost")
|
||||
#define CONN_ERR_TXT "collect: relay=%s, from=%s, info=%s%s%s%s"
|
||||
#define CONN_ERR_CODE "421 4.4.1 "
|
||||
#define CONN_LOG_FROM shortenstring(e->e_from.q_paddr, MAXSHORTSTR)
|
||||
#define CONN_ERR_BARE (0 != bare_lf) ? BARE_LF_MSG : ((0 != bare_cr) ? BARE_CR_MSG : "")
|
||||
#define CONN_ERR_WHERE(bare_xy) (BARE_IN_HDR==(bare_xy) ? "header" : \
|
||||
(BARE_IN_BDY==(bare_xy) ? "body" : "header+body"))
|
||||
|
||||
#define HAS_BARE_XY (0 != (bare_lf | bare_cr))
|
||||
#define CONN_ERR_ARGS LOG_CLT, CONN_LOG_FROM, problem, \
|
||||
HAS_BARE_XY ? ", where=" : "", \
|
||||
HAS_BARE_XY ? CONN_ERR_WHERE(bare_lf|bare_cr) : "", \
|
||||
HAS_BARE_XY ? ", status=tempfail" : ""
|
||||
|
||||
if (LogLevel > 0 && (sm_io_eof(fp) || (0 != (bare_lf | bare_cr))))
|
||||
sm_syslog(LOG_NOTICE, e->e_id,
|
||||
"collect: %s on connection from %.100s, sender=%s",
|
||||
problem, host,
|
||||
shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
|
||||
if (sm_io_eof(fp))
|
||||
usrerr("421 4.4.1 collect: %s on connection from %s, from=%s",
|
||||
problem, host,
|
||||
shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
|
||||
CONN_ERR_TXT, CONN_ERR_ARGS);
|
||||
if (0 != (bare_lf | bare_cr))
|
||||
usrerr("421 4.5.0 %s", CONN_ERR_BARE);
|
||||
else if (sm_io_eof(fp))
|
||||
usrerr(CONN_ERR_CODE CONN_ERR_TXT, CONN_ERR_ARGS);
|
||||
else
|
||||
syserr("421 4.4.1 collect: %s on connection from %s, from=%s",
|
||||
problem, host,
|
||||
shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
|
||||
syserr(CONN_ERR_CODE CONN_ERR_TXT, CONN_ERR_ARGS);
|
||||
flush_errors(true);
|
||||
|
||||
/* don't return an error indication */
|
||||
@ -863,6 +992,21 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
e->e_flags &= ~EF_LOGSENDER;
|
||||
}
|
||||
|
||||
#define LOG_BARE_XY(bare_xy, bare_xy_sp, bare_xy_msg) \
|
||||
do \
|
||||
{ \
|
||||
if ((0 != bare_xy) && LogLevel > 8) \
|
||||
sm_syslog(LOG_NOTICE, e->e_id, \
|
||||
"collect: relay=%s, from=%s, info=%s, where=%s%s" \
|
||||
, LOG_CLT, CONN_LOG_FROM, bare_xy_msg \
|
||||
, CONN_ERR_WHERE(bare_xy) \
|
||||
, bare_xy_sp ? ", status=replaced" : "" \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
LOG_BARE_XY(bare_lf, BARE_LF_SP, BARE_LF_MSG);
|
||||
LOG_BARE_XY(bare_cr, BARE_CR_SP, BARE_CR_MSG);
|
||||
|
||||
/* check for message too large */
|
||||
if (bitset(EF_TOOBIG, e->e_flags))
|
||||
{
|
||||
@ -947,7 +1091,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
|
||||
/*
|
||||
** DFERROR -- signal error on writing the data file.
|
||||
**
|
||||
** Called by collect(). Collect() always terminates the process
|
||||
** Called by collect(). collect() always terminates the process
|
||||
** immediately after calling dferror(), which means that the SMTP
|
||||
** session will be terminated, which means that any error message
|
||||
** issued by dferror must be a 421 error, as per RFC 821.
|
||||
|
@ -81,7 +81,6 @@ static struct hostent *sm_getipnodebyaddr __P((const void *, size_t, int, int *)
|
||||
** this file too much, you may be making a mistake!
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Header info table
|
||||
** Final (null) entry contains the flags used for any other field.
|
||||
@ -164,14 +163,14 @@ struct prival PrivacyValues[] =
|
||||
{ "needvrfyhelo", PRIV_NEEDVRFYHELO },
|
||||
{ "noexpn", PRIV_NOEXPN },
|
||||
{ "novrfy", PRIV_NOVRFY },
|
||||
{ "restrictexpand", PRIV_RESTRICTEXPAND },
|
||||
{ "authwarnings", PRIV_AUTHWARNINGS },
|
||||
{ "noverb", PRIV_NOVERB },
|
||||
{ "restrictmailq", PRIV_RESTRICTMAILQ },
|
||||
{ "restrictqrun", PRIV_RESTRICTQRUN },
|
||||
{ "restrictexpand", PRIV_RESTRICTEXPAND },
|
||||
{ "noetrn", PRIV_NOETRN },
|
||||
{ "noverb", PRIV_NOVERB },
|
||||
{ "authwarnings", PRIV_AUTHWARNINGS },
|
||||
{ "noreceipts", PRIV_NORECEIPTS },
|
||||
{ "nobodyreturn", PRIV_NOBODYRETN },
|
||||
{ "noreceipts", PRIV_NORECEIPTS },
|
||||
{ "goaway", PRIV_GOAWAY },
|
||||
{ "noactualrecipient", PRIV_NOACTUALRECIPIENT },
|
||||
#if _FFR_NOREFLECT
|
||||
@ -196,7 +195,6 @@ struct dbsval DontBlameSendmailValues[] =
|
||||
{ "groupwritablealiasfile", DBS_GROUPWRITABLEALIASFILE },
|
||||
{ "worldwritablealiasfile", DBS_WORLDWRITABLEALIASFILE },
|
||||
{ "forwardfileinunsafedirpath", DBS_FORWARDFILEINUNSAFEDIRPATH },
|
||||
{ "includefileinunsafedirpath", DBS_INCLUDEFILEINUNSAFEDIRPATH },
|
||||
{ "mapinunsafedirpath", DBS_MAPINUNSAFEDIRPATH },
|
||||
{ "linkedaliasfileinwritabledir",
|
||||
DBS_LINKEDALIASFILEINWRITABLEDIR },
|
||||
@ -228,6 +226,7 @@ struct dbsval DontBlameSendmailValues[] =
|
||||
DBS_INCLUDEFILEINUNSAFEDIRPATHSAFE },
|
||||
{ "runprograminunsafedirpath", DBS_RUNPROGRAMINUNSAFEDIRPATH },
|
||||
{ "runwritableprogram", DBS_RUNWRITABLEPROGRAM },
|
||||
{ "includefileinunsafedirpath", DBS_INCLUDEFILEINUNSAFEDIRPATH },
|
||||
{ "nonrootsafeaddr", DBS_NONROOTSAFEADDR },
|
||||
{ "truststickybit", DBS_TRUSTSTICKYBIT },
|
||||
{ "dontwarnforwardfileinunsafedirpath",
|
||||
@ -242,6 +241,7 @@ struct dbsval DontBlameSendmailValues[] =
|
||||
{ "groupreadablekeyfile", DBS_GROUPREADABLEKEYFILE },
|
||||
{ "groupreadabledefaultauthinfofile",
|
||||
DBS_GROUPREADABLEAUTHINFOFILE },
|
||||
{ "certowner", DBS_CERTOWNER },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -1409,7 +1409,6 @@ init_md(argc, argv)
|
||||
# endif /* _SCO_unix_ */
|
||||
#endif /* SECUREWARE || defined(_SCO_unix_) */
|
||||
|
||||
|
||||
#ifdef VENDOR_DEFAULT
|
||||
VendorCode = VENDOR_DEFAULT;
|
||||
#else
|
||||
@ -2317,7 +2316,6 @@ refuseconnections(e, dn, active)
|
||||
conncnt[dn] = 0;
|
||||
}
|
||||
|
||||
|
||||
#if _FFR_MEMSTAT
|
||||
if (RefuseLowMem > 0 &&
|
||||
sm_memstat_get(MemoryResource, &memfree) >= 0 &&
|
||||
@ -2432,7 +2430,6 @@ refuseconnections(e, dn, active)
|
||||
# define SPT_TYPE SPT_REUSEARGV
|
||||
#endif
|
||||
|
||||
|
||||
#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
|
||||
|
||||
# if SPT_TYPE == SPT_PSTAT
|
||||
@ -3057,7 +3054,6 @@ dgux_inet_addr(host)
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** this version hacked to add `atend' flag to allow state machine
|
||||
** to reset if invoked by the program to scan args for a 2nd time
|
||||
@ -3637,8 +3633,11 @@ lockfile(fd, filename, ext, type)
|
||||
action = F_SETLKW;
|
||||
|
||||
if (tTd(55, 60))
|
||||
sm_dprintf("lockfile(%s%s, action=%d, type=%d): ",
|
||||
filename, ext, action, lfd.l_type);
|
||||
sm_dprintf("lockfile(%s%s, fd=%d, action=%s, type=%s): ",
|
||||
filename, ext, fd,
|
||||
bitset(LOCK_NB, type) ? "nb" : "block",
|
||||
bitset(LOCK_UN, type) ? "unlock" :
|
||||
(bitset(LOCK_EX, type) ? "wr" : "rd"));
|
||||
while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
|
||||
continue;
|
||||
if (i >= 0)
|
||||
@ -3684,7 +3683,9 @@ lockfile(fd, filename, ext, type)
|
||||
ext = "";
|
||||
|
||||
if (tTd(55, 60))
|
||||
sm_dprintf("lockfile(%s%s, type=%o): ", filename, ext, type);
|
||||
sm_dprintf("lockfile(%s%s, fd=%d, type=%s): ", filename, ext,
|
||||
fd, bitset(LOCK_UN, type) ? "unlock" :
|
||||
(bitset(LOCK_EX, type) ? "wr" : "rd"));
|
||||
|
||||
while ((i = flock(fd, type)) < 0 && errno == EINTR)
|
||||
continue;
|
||||
@ -3981,7 +3982,6 @@ vendor_pre_defaults(e)
|
||||
#endif /* apollo */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vendor_post_defaults(e)
|
||||
ENVELOPE *e;
|
||||
@ -4701,7 +4701,7 @@ add_hostnames(sa)
|
||||
char **ha;
|
||||
char hnb[MAXHOSTNAMELEN];
|
||||
|
||||
/* lookup name with IP address */
|
||||
/* look up name with IP address */
|
||||
switch (sa->sa.sa_family)
|
||||
{
|
||||
#if NETINET
|
||||
@ -5290,8 +5290,12 @@ isloopback(sa)
|
||||
SOCKADDR sa;
|
||||
{
|
||||
/* XXX how to correctly extract IN_LOOPBACKNET part? */
|
||||
#define SM_IS_IPV4_LOOP(a) (((ntohl(a) & IN_CLASSA_NET) \
|
||||
#ifdef IN_LOOPBACK
|
||||
# define SM_IS_IPV4_LOOP(a) IN_LOOPBACK(ntohl(a))
|
||||
#else /* IN_LOOPBACK */
|
||||
# define SM_IS_IPV4_LOOP(a) (((ntohl(a) & IN_CLASSA_NET) \
|
||||
>> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
|
||||
# endif /* IN_LOOPBACK */
|
||||
#if NETINET6
|
||||
if (sa.sa.sa_family == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&sa.sin6.sin6_addr) &&
|
||||
@ -5524,7 +5528,7 @@ sm_syslog(level, id, fmt, va_alist)
|
||||
|
||||
/* clean up buf after it has been expanded with args */
|
||||
#if _FFR_LOGASIS >= 5
|
||||
/* for testing! */
|
||||
/* for testing! maybe make it an -d option (hence runtime)? */
|
||||
newstring = buf;
|
||||
#else
|
||||
newstring = str2prt(buf);
|
||||
@ -5850,6 +5854,12 @@ char *CompileOptions[] =
|
||||
#if DANE
|
||||
"DANE",
|
||||
#endif
|
||||
#if HAVE_SSL_CTX_dane_enable
|
||||
"HAVE_SSL_CTX_dane_enable",
|
||||
#endif
|
||||
#if MAX_TLSA_RR
|
||||
"MAX_TLSA_RR=" SM_XSTR(MAX_TLSA_RR),
|
||||
#endif
|
||||
#if NAMED_BIND
|
||||
# if DNSMAP
|
||||
"DNSMAP",
|
||||
@ -5875,19 +5885,11 @@ char *CompileOptions[] =
|
||||
"LDAPMAP",
|
||||
#endif
|
||||
#if LDAP_NETWORK_TIMEOUT
|
||||
# if LDAPMAP
|
||||
/* set LDAP_OPT_NETWORK_TIMEOUT if available (-c) */
|
||||
"LDAP_NETWORK_TIMEOUT",
|
||||
# else
|
||||
# ERROR "LDAP_NETWORK_TIMEOUT requires LDAPMAP"
|
||||
# endif
|
||||
#endif
|
||||
#if LDAP_REFERRALS
|
||||
# if LDAPMAP
|
||||
"LDAP_REFERRALS",
|
||||
# else
|
||||
# ERROR "LDAP_REFERRALS requires LDAPMAP"
|
||||
# endif
|
||||
#endif
|
||||
#if LOG
|
||||
"LOG",
|
||||
@ -5921,6 +5923,10 @@ char *CompileOptions[] =
|
||||
#endif
|
||||
#if NAMED_BIND
|
||||
"NAMED_BIND",
|
||||
#else
|
||||
# if DANE
|
||||
# error "DANE requires NAMED_BIND"
|
||||
# endif
|
||||
#endif
|
||||
#if NDBM
|
||||
"NDBM",
|
||||
@ -5951,8 +5957,23 @@ char *CompileOptions[] =
|
||||
#endif
|
||||
#if NEWDB
|
||||
# if defined(DB_VERSION_MAJOR) && defined(DB_VERSION_MINOR)
|
||||
# if DB_VERSION_MAJOR >= 5 && !HASFLOCK
|
||||
# ERROR "Berkeley DB file locking needs flock() for version 5.x (and greater?)"
|
||||
# if DB_VERSION_MAJOR >= 5 && !defined(SOLARIS) && !HASFLOCK && !ACCEPT_BROKEN_BDB_LOCKING
|
||||
|
||||
/*
|
||||
** NOTE: disabling this check by setting ACCEPT_BROKEN_BDB_LOCKING
|
||||
** means you are taking full responsibility for any problems
|
||||
** which may arise!
|
||||
**
|
||||
** Map locking will not work, and making a change to a map
|
||||
** while sendmail is using it can break mail handling.
|
||||
** At least you must stop all sendmail processes when using
|
||||
** makemap or newaliases - but there might be other things
|
||||
** which could break.
|
||||
**
|
||||
** You have been warned - use at your own risk!
|
||||
*/
|
||||
|
||||
# error "Berkeley DB file locking needs flock() for version 5.x (and greater?)"
|
||||
# endif
|
||||
"NEWDB=" SM_XSTR(DB_VERSION_MAJOR) "." SM_XSTR(DB_VERSION_MINOR),
|
||||
# else
|
||||
@ -6015,8 +6036,12 @@ char *CompileOptions[] =
|
||||
"TLS_NO_RSA",
|
||||
#endif
|
||||
#if TLS_EC
|
||||
# if NO_DH
|
||||
# error "NO_DH disables TLS_EC"
|
||||
# else
|
||||
/* elliptic curves */
|
||||
"TLS_EC",
|
||||
# endif
|
||||
#endif
|
||||
#if TLS_VRFY_PER_CTX
|
||||
"TLS_VRFY_PER_CTX",
|
||||
@ -6033,10 +6058,10 @@ char *CompileOptions[] =
|
||||
*/
|
||||
|
||||
# if !ALLOW_255
|
||||
# ERROR "USE_EAI requires ALLOW_255"
|
||||
# error "USE_EAI requires ALLOW_255"
|
||||
# endif
|
||||
# if _FFR_EIGHT_BIT_ADDR_OK
|
||||
# ERROR "Cannot enable both USE_EAI and _FFR_EIGHT_BIT_ADDR_OK"
|
||||
# error "Cannot enable both USE_EAI and _FFR_EIGHT_BIT_ADDR_OK"
|
||||
# endif
|
||||
"USE_EAI",
|
||||
#endif
|
||||
@ -6055,7 +6080,6 @@ char *CompileOptions[] =
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** OS compile options.
|
||||
*/
|
||||
@ -6333,7 +6357,7 @@ char *FFRCompileOptions[] =
|
||||
#endif
|
||||
#if _FFR_ALLOW_SASLINFO
|
||||
/* DefaultAuthInfo can be specified by user. */
|
||||
/* DefaultAuthInfo doesn't really work in 8.13 anymore. */
|
||||
/* DefaultAuthInfo doesn't really work in 8.13ff anymore. */
|
||||
"_FFR_ALLOW_SASLINFO",
|
||||
#endif
|
||||
#if _FFR_BADRCPT_SHUTDOWN
|
||||
@ -6361,6 +6385,10 @@ char *FFRCompileOptions[] =
|
||||
/* Stricter checks about queue directory permissions. */
|
||||
"_FFR_CHK_QUEUE",
|
||||
#endif
|
||||
#if _FFR_CLASS_RM_ENTRY
|
||||
/* WIP: remove entries from a class: C-{name}entry */
|
||||
"_FFR_CLASS_RM_ENTRY",
|
||||
#endif
|
||||
#if _FFR_CLIENTCA
|
||||
/*
|
||||
** Allow to set client specific CA values.
|
||||
@ -6441,8 +6469,17 @@ char *FFRCompileOptions[] =
|
||||
|
||||
"_FFR_DROP_TRUSTUSER_WARNING",
|
||||
#endif
|
||||
#if _FFR_DYN_CLASS
|
||||
/* dynamic classes based on maps */
|
||||
"_FFR_DYN_CLASS",
|
||||
#endif
|
||||
#if _FFR_EIGHT_BIT_ADDR_OK
|
||||
/* EightBitAddrOK: allow 8-bit e-mail addresses */
|
||||
/*
|
||||
** EightBitAddrOK: allow all 8-bit e-mail addresses.
|
||||
** By default only ((ch & 0340) == 0200) is blocked
|
||||
** because that range is used for "META" chars.
|
||||
*/
|
||||
|
||||
"_FFR_EIGHT_BIT_ADDR_OK",
|
||||
#endif
|
||||
#if _FFR_EXPAND_HELONAME
|
||||
@ -6523,6 +6560,10 @@ char *FFRCompileOptions[] =
|
||||
/* Local daemon mode (-bl) which only accepts loopback connections */
|
||||
"_FFR_LOCAL_DAEMON",
|
||||
#endif
|
||||
#if _FFR_LOG_FAILOVER
|
||||
/* WIP: log reason why trying another host */
|
||||
"_FFR_LOG_FAILOVER",
|
||||
#endif
|
||||
#if _FFR_LOG_MORE1
|
||||
/* log some TLS/AUTH info in from= too */
|
||||
"_FFR_LOG_MORE1=" SM_XSTR(_FFR_LOG_MORE1),
|
||||
@ -6531,10 +6572,18 @@ char *FFRCompileOptions[] =
|
||||
/* log some TLS info in to= too */
|
||||
"_FFR_LOG_MORE2=" SM_XSTR(_FFR_LOG_MORE2),
|
||||
#endif
|
||||
#if _FFR_LOG_STAGE
|
||||
/* log protocol stage for delivery problems */
|
||||
"_FFR_LOG_STAGE",
|
||||
#endif
|
||||
#if _FFR_MAIL_MACRO
|
||||
/* make the "real" sender address available in {mail_from} */
|
||||
"_FFR_MAIL_MACRO",
|
||||
#endif
|
||||
#if _FFR_MAP_CHK_FILE
|
||||
/* check whether the underlying map file was changed */
|
||||
"_FFR_MAP_CHK_FILE=" SM_XSTR(_FFR_MAP_CHK_FILE),
|
||||
#endif
|
||||
#if _FFR_MAXDATASIZE
|
||||
/*
|
||||
** It is possible that a header is larger than MILTER_CHUNK_SIZE,
|
||||
@ -6564,6 +6613,7 @@ char *FFRCompileOptions[] =
|
||||
"_FFR_MEMSTAT",
|
||||
#endif
|
||||
#if _FFR_MILTER_CHECK
|
||||
/* for (lib)milter testing */
|
||||
"_FFR_MILTER_CHECK",
|
||||
#endif
|
||||
#if _FFR_MILTER_CONNECT_REPLYCODE
|
||||
@ -6619,13 +6669,13 @@ char *FFRCompileOptions[] =
|
||||
#endif
|
||||
#if _FFR_MTA_STS
|
||||
# if !MAP_REGEX
|
||||
# ERROR "_FFR_MTA_STS requires MAP_REGEX"
|
||||
# error "_FFR_MTA_STS requires MAP_REGEX"
|
||||
# endif
|
||||
# if !STARTTLS
|
||||
# ERROR "_FFR_MTA_STS requires STARTTLS"
|
||||
# error "_FFR_MTA_STS requires STARTTLS"
|
||||
# endif
|
||||
# if !_FFR_TLS_ALTNAMES
|
||||
# ERROR "_FFR_MTA_STS requires _FFR_TLS_ALTNAMES"
|
||||
# error "_FFR_MTA_STS requires _FFR_TLS_ALTNAMES"
|
||||
# endif
|
||||
/* MTA STS support */
|
||||
"_FFR_MTA_STS",
|
||||
@ -6667,7 +6717,7 @@ char *FFRCompileOptions[] =
|
||||
/* outgoing connection control (not yet working) */
|
||||
"_FFR_OCC",
|
||||
# else
|
||||
# ERROR "_FFR_OCC requires SM_CONF_SHM"
|
||||
# error "_FFR_OCC requires SM_CONF_SHM"
|
||||
# endif
|
||||
#endif
|
||||
#if _FFR_PROXY
|
||||
@ -6741,12 +6791,19 @@ char *FFRCompileOptions[] =
|
||||
"_FFR_SESSID",
|
||||
#endif
|
||||
#if _FFR_SETANYOPT
|
||||
/*
|
||||
** if _FFR_SETOPT_MAP is used: allow to set any option
|
||||
** (which probably does not work as expected for many options).
|
||||
*/
|
||||
|
||||
"_FFR_SETANYOPT",
|
||||
#endif
|
||||
#if _FFR_SETDEBUG_MAP
|
||||
/* enable setdebug map to set debug levels from rules */
|
||||
"_FFR_SETDEBUG_MAP",
|
||||
#endif
|
||||
#if _FFR_SETOPT_MAP
|
||||
/* enable setopt map to set options from rules */
|
||||
"_FFR_SETOPT_MAP",
|
||||
#endif
|
||||
#if _FFR_SHM_STATUS
|
||||
@ -6762,11 +6819,11 @@ char *FFRCompileOptions[] =
|
||||
"_FFR_SLEEP_USE_SELECT",
|
||||
#endif
|
||||
#if _FFR_SM_LDAP_DBG
|
||||
# if LDAPMAP && defined(LBER_OPT_LOG_PRINT_FN)
|
||||
# if defined(LBER_OPT_LOG_PRINT_FN)
|
||||
/* LDAP debugging */
|
||||
"_FFR_SM_LDAP_DBG",
|
||||
# else
|
||||
# ERROR "_FFR_SM_LDAP_DBG requires LDAPMAP and LBER_OPT_LOG_PRINT_FN"
|
||||
# error "_FFR_SM_LDAP_DBG requires LBER_OPT_LOG_PRINT_FN"
|
||||
# endif
|
||||
#endif
|
||||
#if _FFR_SPT_ALIGN
|
||||
@ -6846,7 +6903,7 @@ char *FFRCompileOptions[] =
|
||||
# if defined(X509_V_FLAG_TRUSTED_FIRST)
|
||||
"_FFR_VRFY_TRUSTED_FIRST",
|
||||
# else
|
||||
# ERROR "_FFR_VRFY_TRUSTED_FIRST set but X509_V_FLAG_TRUSTED_FIRST not defined"
|
||||
# error "_FFR_VRFY_TRUSTED_FIRST set but X509_V_FLAG_TRUSTED_FIRST not defined"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -6863,11 +6920,20 @@ char *FFRCompileOptions[] =
|
||||
/* X-Connect support */
|
||||
"_FFR_XCNCT",
|
||||
#endif
|
||||
#if _FFR_HAPROXY
|
||||
/* HAproxy support */
|
||||
"_FFR_HAPROXY",
|
||||
#endif
|
||||
#if _FFR_LOGASIS
|
||||
/* only convert char <= 31 to something printable for logging etc */
|
||||
"_FFR_LOGASIS=" SM_XSTR(_FFR_LOGASIS),
|
||||
#endif
|
||||
#if _FFR_NAMESERVER
|
||||
/* Allow to override nameserver set by OS */
|
||||
"_FFR_NAMESERVER",
|
||||
#endif
|
||||
#if _FFR_NOREFLECT
|
||||
/* Don't forget to update docs for "goaway" to include this */
|
||||
/* Do not include input from a client in a reply of the server */
|
||||
"_FFR_NOREFLECT",
|
||||
#endif
|
||||
#if _FFR_AUTH_PASSING
|
||||
@ -6880,8 +6946,8 @@ char *FFRCompileOptions[] =
|
||||
#endif
|
||||
#if _FFR_MSP_PARANOIA
|
||||
/*
|
||||
** Forbid queue groups, multiple queues, and dangerous queue permissions
|
||||
** when operating as an MSP
|
||||
** Forbid queue groups, multiple queues, and
|
||||
** dangerous queue permissions when operating as an MSP
|
||||
*/
|
||||
|
||||
"_FFR_MSP_PARANOIA",
|
||||
@ -6901,6 +6967,14 @@ char *FFRCompileOptions[] =
|
||||
*/
|
||||
|
||||
"_FFR_MIME_CR_OK",
|
||||
#endif
|
||||
#if _FFR_M_ONLY_IPV4
|
||||
/* mailer flag 4: use only IPv4 for delivery attempts */
|
||||
"_FFR_M_ONLY_IPV4",
|
||||
#endif
|
||||
#if _FFR_SMTPS_CLIENT
|
||||
/* SMTP over TLS client (defaults to port 465/tcp outbound) */
|
||||
"_FFR_SMTPS_CLIENT",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
@ -78,7 +78,11 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
||||
#define SMTPLINELIM 990 /* max SMTP line length */
|
||||
#define MAXUDBKEY 128 /* max size of a database key (udb only) */
|
||||
#define MAXKEY 1024 /* max size of a database key */
|
||||
#define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */
|
||||
#define MEMCHUNKSIZE 4096 /* chunk size for memory allocation */
|
||||
#if MEMCHUNKSIZE < MAXLINE
|
||||
/* see usage in collect.c */
|
||||
# error "MEMCHUNKSIZE must be at least MAXLINE"
|
||||
#endif
|
||||
#define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */
|
||||
#define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */
|
||||
#if MILTER
|
||||
@ -132,7 +136,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
|
||||
/* must be less than BITMAPBITS for DoQueueRun */
|
||||
#endif
|
||||
#if MAXQUEUEGROUPS >= BITMAPBITS
|
||||
# ERROR "MAXQUEUEGROUPS must be less than BITMAPBITS"
|
||||
# error "MAXQUEUEGROUPS must be less than BITMAPBITS"
|
||||
#endif
|
||||
|
||||
#ifndef MAXWORKGROUPS
|
||||
|
@ -41,8 +41,6 @@ static struct cmd CmdTab[] =
|
||||
{ NULL, CMDERROR }
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void controltimeout __P((int));
|
||||
int ControlSocket = -1;
|
||||
|
||||
|
@ -25,12 +25,7 @@ SM_RCSID("@(#)$Id: daemon.c,v 8.698 2013-11-22 20:51:55 ca Exp $")
|
||||
# if NETINET || NETINET6
|
||||
# include <arpa/inet.h>
|
||||
# endif
|
||||
# if NAMED_BIND
|
||||
# ifndef NO_DATA
|
||||
# define NO_DATA NO_ADDRESS
|
||||
# endif
|
||||
# endif /* NAMED_BIND */
|
||||
#endif /* defined(USE_SOCK_STREAM) */
|
||||
#endif
|
||||
|
||||
#if STARTTLS
|
||||
# include <openssl/rand.h>
|
||||
@ -170,7 +165,6 @@ getrequests(e)
|
||||
#endif
|
||||
extern ENVELOPE BlankEnvelope;
|
||||
|
||||
|
||||
/* initialize data for function that generates queue ids */
|
||||
init_qid_alg();
|
||||
for (idx = 0; idx < NDaemons; idx++)
|
||||
@ -868,7 +862,6 @@ getrequests(e)
|
||||
}
|
||||
else
|
||||
setbitn(t, Daemons[curdaemon].d_flags);
|
||||
|
||||
#endif /* _FFR_XCNCT */
|
||||
|
||||
#if XLA
|
||||
@ -1871,12 +1864,18 @@ static struct dflags DaemonFlags[] =
|
||||
{ "UNQUALOK", D_UNQUALOK },
|
||||
{ "NOAUTH", D_NOAUTH },
|
||||
{ "NOCANON", D_NOCANON },
|
||||
{ "NODANE", D_NODANE },
|
||||
{ "NOETRN", D_NOETRN },
|
||||
{ "NOSTS", D_NOSTS },
|
||||
{ "NOTLS", D_NOTLS },
|
||||
{ "ETRNONLY", D_ETRNONLY },
|
||||
{ "OPTIONAL", D_OPTIONAL },
|
||||
{ "DISABLE", D_DISABLE },
|
||||
{ "ISSET", D_ISSET },
|
||||
#if _FFR_XCNCT
|
||||
{ "XCNCT", D_XCNCT },
|
||||
{ "XCNCT_M", D_XCNCT_M },
|
||||
#endif
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -2160,7 +2159,7 @@ makeconnection(host, port, mci, e, enough
|
||||
#if NETINET6
|
||||
volatile bool v6found = false;
|
||||
#endif
|
||||
volatile int family = InetMode;
|
||||
volatile int family;
|
||||
SOCKADDR_LEN_T len;
|
||||
volatile SOCKADDR_LEN_T socksize = 0;
|
||||
volatile bool clt_bind;
|
||||
@ -2179,8 +2178,14 @@ makeconnection(host, port, mci, e, enough
|
||||
#if DANE
|
||||
SM_REQUIRE(ptlsa_flags != NULL);
|
||||
tlsa_flags = *ptlsa_flags;
|
||||
*ptlsa_flags &= ~(TLSAFLALWAYS|TLSAFLSECURE);
|
||||
*ptlsa_flags &= ~TLSAFLADIP;
|
||||
#endif
|
||||
#if _FFR_M_ONLY_IPV4
|
||||
if (bitnset(M_ONLY_IPV4, mci->mci_mailer->m_flags))
|
||||
family = AF_INET;
|
||||
else
|
||||
#endif
|
||||
family = InetMode;
|
||||
|
||||
/* retranslate {daemon_flags} into bitmap */
|
||||
clrbitmap(d_flags);
|
||||
@ -2385,7 +2390,7 @@ makeconnection(host, port, mci, e, enough
|
||||
p = &host[strlen(host) - 1];
|
||||
#if DANE
|
||||
if (tTd(16, 40))
|
||||
sm_dprintf("makeconnection: tlsa_flags=%lX, host=%s\n",
|
||||
sm_dprintf("makeconnection: tlsa_flags=%#lx, host=%s\n",
|
||||
tlsa_flags, host);
|
||||
if (DANEMODE(tlsa_flags) == DANE_SECURE
|
||||
# if DNSSEC_TEST
|
||||
@ -2408,13 +2413,16 @@ makeconnection(host, port, mci, e, enough
|
||||
|
||||
if (rr != NULL && rr->dns_r_h.ad == 1)
|
||||
{
|
||||
*ptlsa_flags |= DANE_SECURE;
|
||||
*ptlsa_flags |= TLSAFLADIP;
|
||||
if ((TLSAFLTEMP & *ptlsa_flags) != 0)
|
||||
{
|
||||
dns_free_data(rr);
|
||||
rr = NULL;
|
||||
return EX_TEMPFAIL;
|
||||
}
|
||||
}
|
||||
if (rr != NULL)
|
||||
{
|
||||
hp = dns2he(rr, family);
|
||||
# if NETINET6
|
||||
hs = hp;
|
||||
@ -2428,7 +2436,7 @@ makeconnection(host, port, mci, e, enough
|
||||
dns_free_data(rr);
|
||||
rr = NULL;
|
||||
}
|
||||
#endif
|
||||
#endif /* DANE */
|
||||
if (hp == NULL)
|
||||
hp = sm_gethostbyname(host, family);
|
||||
if (hp == NULL && *p == '.')
|
||||
@ -2544,21 +2552,21 @@ makeconnection(host, port, mci, e, enough
|
||||
}
|
||||
|
||||
#if _FFR_TESTS
|
||||
/*
|
||||
** Hack for testing.
|
||||
** Hardcoded:
|
||||
** 10.1.1.12: see meta1.tns XREF IP address
|
||||
** 8754: see common.sh XREF SNKPORT2
|
||||
*/
|
||||
/*
|
||||
** Hack for testing.
|
||||
** Hardcoded:
|
||||
** 10.1.1.12: see meta1.tns XREF IP address
|
||||
** 8754: see common.sh XREF SNKPORT2
|
||||
*/
|
||||
|
||||
if (tTd(77, 101) && hp != NULL && hp->h_addrtype == AF_INET &&
|
||||
addr.sin.sin_addr.s_addr == inet_addr("10.1.1.12"))
|
||||
{
|
||||
addr.sin.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
port = htons(8754);
|
||||
sm_dprintf("hack host=%s addr=[%s].%d\n", host,
|
||||
anynet_ntoa(&addr), ntohs(port));
|
||||
}
|
||||
if (tTd(77, 101) && hp != NULL && hp->h_addrtype == AF_INET &&
|
||||
addr.sin.sin_addr.s_addr == inet_addr("10.1.1.12"))
|
||||
{
|
||||
addr.sin.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
port = htons(8754);
|
||||
sm_dprintf("hack host=%s addr=[%s].%d\n", host,
|
||||
anynet_ntoa(&addr), ntohs(port));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -2568,16 +2576,34 @@ makeconnection(host, port, mci, e, enough
|
||||
if (port == 0)
|
||||
{
|
||||
#ifdef NO_GETSERVBYNAME
|
||||
port = htons(25);
|
||||
# if _FFR_SMTPS_CLIENT
|
||||
if (bitnset(M_SMTPS_CLIENT, mci->mci_mailer->m_flags))
|
||||
port = htons(465);
|
||||
else
|
||||
# endif /* _FFR_SMTPS_CLIENT */
|
||||
port = htons(25);
|
||||
#else /* NO_GETSERVBYNAME */
|
||||
register struct servent *sp = getservbyname("smtp", "tcp");
|
||||
register struct servent *sp;
|
||||
|
||||
# if _FFR_SMTPS_CLIENT
|
||||
if (bitnset(M_SMTPS_CLIENT, mci->mci_mailer->m_flags))
|
||||
p = "smtps";
|
||||
else
|
||||
# endif /* _FFR_SMTPS_CLIENT */
|
||||
p = "smtp";
|
||||
sp = getservbyname(p, "tcp");
|
||||
|
||||
if (sp == NULL)
|
||||
{
|
||||
if (LogLevel > 2)
|
||||
sm_syslog(LOG_ERR, NOQID,
|
||||
"makeconnection: service \"smtp\" unknown");
|
||||
port = htons(25);
|
||||
"makeconnection: service \"%s\" unknown", p);
|
||||
# if _FFR_SMTPS_CLIENT
|
||||
if (bitnset(M_SMTPS_CLIENT, mci->mci_mailer->m_flags))
|
||||
port = htons(465);
|
||||
else
|
||||
# endif /* _FFR_SMTPS_CLIENT */
|
||||
port = htons(25);
|
||||
}
|
||||
else
|
||||
port = sp->s_port;
|
||||
@ -2787,6 +2813,9 @@ makeconnection(host, port, mci, e, enough
|
||||
if (setjmp(CtxConnectTimeout) == 0)
|
||||
{
|
||||
int i;
|
||||
#if _FFR_TESTS
|
||||
int c_errno;
|
||||
#endif
|
||||
|
||||
if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0)
|
||||
ev = sm_setevent(TimeOuts.to_iconnect,
|
||||
@ -2796,6 +2825,28 @@ makeconnection(host, port, mci, e, enough
|
||||
connecttimeout, 0);
|
||||
else
|
||||
ev = NULL;
|
||||
#if _FFR_TESTS
|
||||
i = 0;
|
||||
c_errno = 0;
|
||||
if (tTd(77, 101)
|
||||
/* && AF_INET == addr.sin.sin_family */
|
||||
&& ntohl(addr.sin.sin_addr.s_addr) >=
|
||||
ntohl(inet_addr("255.255.255.1"))
|
||||
&& ntohl(addr.sin.sin_addr.s_addr) <=
|
||||
ntohl(inet_addr("255.255.255.255"))
|
||||
)
|
||||
{
|
||||
i = -1;
|
||||
c_errno = ntohl(addr.sin.sin_addr.s_addr) -
|
||||
ntohl(inet_addr("255.255.255.0"));
|
||||
sm_dprintf("hack: fail connection=%d, ip=%#x, lower=%#x\n",
|
||||
c_errno
|
||||
, ntohl(addr.sin.sin_addr.s_addr)
|
||||
, ntohl(inet_addr("255.255.255.0")));
|
||||
}
|
||||
else
|
||||
#endif /* _FFR_TESTS */
|
||||
/* "else" in #if code above */
|
||||
|
||||
switch (ConnectOnlyTo.sa.sa_family)
|
||||
{
|
||||
@ -2829,24 +2880,11 @@ makeconnection(host, port, mci, e, enough
|
||||
anynet_ntoa(&addr), ntohs(port));
|
||||
|
||||
#if _FFR_TESTS
|
||||
if (tTd(77, 101)
|
||||
/* && AF_INET == addr.sin.sin_family */
|
||||
&& addr.sin.sin_addr.s_addr >=
|
||||
inet_addr("255.255.255.1")
|
||||
&& addr.sin.sin_addr.s_addr <=
|
||||
inet_addr("255.255.255.255")
|
||||
)
|
||||
{
|
||||
i = -1;
|
||||
save_errno = ntohl(addr.sin.sin_addr.s_addr) -
|
||||
ntohl(inet_addr("255.255.255.0"));
|
||||
sm_dprintf("hack: fail connection=%d\n",
|
||||
save_errno);
|
||||
errno = save_errno;
|
||||
}
|
||||
if (-1 == i)
|
||||
errno = c_errno;
|
||||
else
|
||||
/* Watch out of changes below! */
|
||||
#endif /* _FFR_TESTS */
|
||||
#endif
|
||||
/* "else" in #if code above */
|
||||
i = connect(s, (struct sockaddr *) &addr, addrlen);
|
||||
save_errno = errno;
|
||||
if (ev != NULL)
|
||||
@ -4200,7 +4238,7 @@ host_map_lookup(map, name, av, statp)
|
||||
#if USE_EAI
|
||||
bool utf8;
|
||||
|
||||
utf8 = !addr_is_ascii(name);
|
||||
utf8 = !str_is_print(name);
|
||||
if (utf8)
|
||||
{
|
||||
(void) sm_strlcpy(hbuf, hn2alabel(name), sizeof(hbuf));
|
||||
@ -4314,7 +4352,6 @@ host_map_lookup(map, name, av, statp)
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
||||
/* No match found */
|
||||
s->s_namecanon.nc_errno = errno;
|
||||
#if NAMED_BIND
|
||||
|
@ -13,7 +13,7 @@
|
||||
#define DAEMON_H 1
|
||||
|
||||
#if DAEMON_C
|
||||
# define EXTERN
|
||||
# define EXTERN
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2004, 2006, 2010 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 1998-2004, 2006, 2010, 2020-2023 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1986, 1995-1997 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
@ -13,9 +13,6 @@
|
||||
|
||||
#include <sendmail.h>
|
||||
#include "map.h"
|
||||
#if USE_EAI
|
||||
#include <unicode/uidna.h>
|
||||
#endif
|
||||
|
||||
#if NAMED_BIND
|
||||
SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (with name server)")
|
||||
@ -27,7 +24,7 @@ SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (without name s
|
||||
|
||||
#if NAMED_BIND
|
||||
# include <arpa/inet.h>
|
||||
# include <sm_resolve.h>
|
||||
# include "sm_resolve.h"
|
||||
# if DANE
|
||||
# include <tls.h>
|
||||
# ifndef SM_NEG_TTL
|
||||
@ -35,6 +32,10 @@ SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (without name s
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#if USE_EAI
|
||||
#include <unicode/uidna.h>
|
||||
#endif
|
||||
|
||||
|
||||
# ifndef MXHOSTBUFSIZE
|
||||
# define MXHOSTBUFSIZE (128 * MAXMXHOSTS)
|
||||
@ -53,10 +54,6 @@ static char MXHostBuf[MXHOSTBUFSIZE];
|
||||
# define RES_DNSRCH_VARIABLE _res.dnsrch
|
||||
# endif
|
||||
|
||||
# ifndef NO_DATA
|
||||
# define NO_DATA NO_ADDRESS
|
||||
# endif
|
||||
|
||||
# ifndef HFIXEDSZ
|
||||
# define HFIXEDSZ 12 /* sizeof(HEADER) */
|
||||
# endif
|
||||
@ -74,6 +71,230 @@ static int fallbackmxrr __P((int, unsigned short *, char **));
|
||||
|
||||
# if DANE
|
||||
|
||||
static void tlsa_rr_print __P((const unsigned char *, unsigned int));
|
||||
|
||||
static void
|
||||
tlsa_rr_print(rr, len)
|
||||
const unsigned char *rr;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i, l;
|
||||
|
||||
if (!tTd(8, 2))
|
||||
return;
|
||||
|
||||
sm_dprintf("len=%u, %02x-%02x-%02x",
|
||||
len, (int)rr[0], (int)rr[1], (int)rr[2]);
|
||||
l = tTd(8, 8) ? len : 4;
|
||||
for (i = 3; i < l; i++)
|
||||
sm_dprintf(":%02X", (int)rr[i]);
|
||||
sm_dprintf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
** TLSA_RR_CMP -- Compare two TLSA RRs
|
||||
**
|
||||
** Parameters:
|
||||
** rr1 -- TLSA RR (entry to be added)
|
||||
** l1 -- length of rr1
|
||||
** rr2 -- TLSA RR
|
||||
** l2 -- length of rr2
|
||||
**
|
||||
** Returns:
|
||||
** 0: rr1 == rr2
|
||||
** 1: rr1 is unsupported
|
||||
*/
|
||||
|
||||
static int tlsa_rr_cmp __P((unsigned char *, int, unsigned char *, int));
|
||||
|
||||
static int
|
||||
tlsa_rr_cmp(rr1, l1, rr2, l2)
|
||||
unsigned char *rr1;
|
||||
int l1;
|
||||
unsigned char *rr2;
|
||||
int l2;
|
||||
{
|
||||
/* temporary #if while investigating the implications of the alternative */
|
||||
#if FULL_COMPARE
|
||||
unsigned char r1, r2;
|
||||
int cmp;
|
||||
#endif /* FULL_COMPARE */
|
||||
|
||||
SM_REQUIRE(NULL != rr1);
|
||||
SM_REQUIRE(NULL != rr2);
|
||||
SM_REQUIRE(l1 > 3);
|
||||
SM_REQUIRE(l2 > 3);
|
||||
|
||||
#if FULL_COMPARE
|
||||
/*
|
||||
** certificate usage
|
||||
** 3: cert/fp must match
|
||||
** 2: cert/fp must be trust anchor
|
||||
*/
|
||||
|
||||
/* preference[]: lower value: higher preference */
|
||||
r1 = rr1[0];
|
||||
r2 = rr2[0];
|
||||
if (r1 != r2)
|
||||
{
|
||||
int preference[] = { 3, 2, 1, 0 };
|
||||
|
||||
SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
|
||||
SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
|
||||
return preference[r1] - preference[r2];
|
||||
}
|
||||
|
||||
/*
|
||||
** selector:
|
||||
** 0: full cert
|
||||
** 1: fp
|
||||
*/
|
||||
|
||||
r1 = rr1[1];
|
||||
r2 = rr2[1];
|
||||
if (r1 != r2)
|
||||
{
|
||||
int preference[] = { 1, 0 };
|
||||
|
||||
SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
|
||||
SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
|
||||
return preference[r1] - preference[r2];
|
||||
}
|
||||
|
||||
/*
|
||||
** matching type:
|
||||
** 0 -- Exact match
|
||||
** 1 -- SHA-256 hash
|
||||
** 2 -- SHA-512 hash
|
||||
*/
|
||||
|
||||
r1 = rr1[2];
|
||||
r2 = rr2[2];
|
||||
if (r1 != r2)
|
||||
{
|
||||
int preference[] = { 2, 0, 1 };
|
||||
|
||||
SM_ASSERT(r1 <= SM_ARRAY_SIZE(preference));
|
||||
SM_ASSERT(r2 <= SM_ARRAY_SIZE(preference));
|
||||
return preference[r1] - preference[r2];
|
||||
}
|
||||
|
||||
/* not the same length despite the same type? */
|
||||
if (l1 != l2)
|
||||
return 1;
|
||||
cmp = memcmp(rr1, rr2, l1);
|
||||
if (0 == cmp)
|
||||
return 0;
|
||||
return 1;
|
||||
#else /* FULL_COMPARE */
|
||||
/* identical? */
|
||||
if (l1 == l2 && 0 == memcmp(rr1, rr2, l1))
|
||||
return 0;
|
||||
|
||||
/* new entry is unsupported? -> append */
|
||||
if (TLSA_UNSUPP == dane_tlsa_chk(rr1, l1, "", false))
|
||||
return 1;
|
||||
/* current entry is unsupported? -> insert new one */
|
||||
if (TLSA_UNSUPP == dane_tlsa_chk(rr2, l2, "", false))
|
||||
return -1;
|
||||
|
||||
/* default: preserve order */
|
||||
return 1;
|
||||
#endif /* FULL_COMPARE */
|
||||
}
|
||||
|
||||
/*
|
||||
** TLSAINSERT -- Insert a TLSA RR
|
||||
**
|
||||
** Parameters:
|
||||
** dane_tlsa -- dane_tlsa entry
|
||||
** rr -- TLSA RR
|
||||
** pn -- (point to) number of entries
|
||||
**
|
||||
** Returns:
|
||||
** SM_SUCCESS: rr inserted
|
||||
** SM_NOTDONE: rr not inserted: exists
|
||||
** SM_FULL: rr not inserted: no space left
|
||||
*/
|
||||
|
||||
static int tlsainsert __P((dane_tlsa_P, RESOURCE_RECORD_T *, int *));
|
||||
|
||||
static int
|
||||
tlsainsert(dane_tlsa, rr, pn)
|
||||
dane_tlsa_P dane_tlsa;
|
||||
RESOURCE_RECORD_T *rr;
|
||||
int *pn;
|
||||
{
|
||||
int i, l1, ret;
|
||||
unsigned char *r1;
|
||||
|
||||
SM_ASSERT(pn != NULL);
|
||||
SM_ASSERT(*pn <= MAX_TLSA_RR);
|
||||
r1 = rr->rr_u.rr_data;
|
||||
l1 = rr->rr_size;
|
||||
|
||||
ret = SM_SUCCESS;
|
||||
for (i = 0; i < *pn; i++)
|
||||
{
|
||||
int r, j;
|
||||
|
||||
r = tlsa_rr_cmp(r1, l1, dane_tlsa->dane_tlsa_rr[i],
|
||||
dane_tlsa->dane_tlsa_len[i]);
|
||||
|
||||
if (0 == r)
|
||||
{
|
||||
if (tTd(8, 80))
|
||||
sm_dprintf("func=tlsainsert, i=%d, n=%d, status=exists\n", i, *pn);
|
||||
ret = SM_NOTDONE;
|
||||
goto done;
|
||||
}
|
||||
if (r > 0)
|
||||
continue;
|
||||
|
||||
if (*pn + 1 >= MAX_TLSA_RR)
|
||||
{
|
||||
j = MAX_TLSA_RR - 1;
|
||||
SM_FREE(dane_tlsa->dane_tlsa_rr[j]);
|
||||
dane_tlsa->dane_tlsa_len[j] = 0;
|
||||
}
|
||||
else
|
||||
(*pn)++;
|
||||
|
||||
for (j = MAX_TLSA_RR - 2; j >= i; j--)
|
||||
{
|
||||
dane_tlsa->dane_tlsa_rr[j + 1] = dane_tlsa->dane_tlsa_rr[j];
|
||||
dane_tlsa->dane_tlsa_len[j + 1] = dane_tlsa->dane_tlsa_len[j];
|
||||
}
|
||||
SM_ASSERT(i < MAX_TLSA_RR);
|
||||
dane_tlsa->dane_tlsa_rr[i] = r1;
|
||||
dane_tlsa->dane_tlsa_len[i] = l1;
|
||||
if (tTd(8, 80))
|
||||
sm_dprintf("func=tlsainsert, i=%d, n=%d, status=inserted\n", i, *pn);
|
||||
goto added;
|
||||
}
|
||||
|
||||
if (*pn + 1 <= MAX_TLSA_RR)
|
||||
{
|
||||
dane_tlsa->dane_tlsa_rr[*pn] = r1;
|
||||
dane_tlsa->dane_tlsa_len[*pn] = l1;
|
||||
(*pn)++;
|
||||
if (tTd(8, 80))
|
||||
sm_dprintf("func=tlsainsert, n=%d, status=appended\n", *pn);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tTd(8, 80))
|
||||
sm_dprintf("func=tlsainsert, n=%d, status=full\n", *pn);
|
||||
return SM_FULL;
|
||||
}
|
||||
|
||||
added:
|
||||
/* hack: instead of copying the data, just "take it over" */
|
||||
rr->rr_u.rr_data = NULL;
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
** TLSAADD -- add TLSA records to dane_tlsa entry
|
||||
**
|
||||
@ -82,24 +303,27 @@ static int fallbackmxrr __P((int, unsigned short *, char **));
|
||||
** dr -- DNS reply
|
||||
** dane_tlsa -- dane_tlsa entry
|
||||
** dnsrc -- DNS lookup return code (h_errno)
|
||||
** n -- current number of TLSA records in dane_tlsa entry
|
||||
** nr -- current number of TLSA records in dane_tlsa entry
|
||||
** pttl -- (pointer to) TTL (in/out)
|
||||
** level -- recursion level (CNAMEs)
|
||||
**
|
||||
** Returns:
|
||||
** new number of TLSA records
|
||||
**
|
||||
** NOTE: the array for TLSA RRs could be "full" which is not
|
||||
** handled well (yet).
|
||||
*/
|
||||
|
||||
static int tlsaadd __P((const char *, DNS_REPLY_T *, dane_tlsa_P, int, int,
|
||||
unsigned int *, int));
|
||||
|
||||
static int
|
||||
tlsaadd(name, dr, dane_tlsa, dnsrc, n, pttl, level)
|
||||
tlsaadd(name, dr, dane_tlsa, dnsrc, nr, pttl, level)
|
||||
const char *name;
|
||||
DNS_REPLY_T *dr;
|
||||
dane_tlsa_P dane_tlsa;
|
||||
int dnsrc;
|
||||
int n;
|
||||
int nr;
|
||||
unsigned int *pttl;
|
||||
int level;
|
||||
{
|
||||
@ -110,7 +334,7 @@ tlsaadd(name, dr, dane_tlsa, dnsrc, n, pttl, level)
|
||||
if (dnsrc != 0)
|
||||
{
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("tlsaadd(%s), prev=%d, dnsrc=%d\n",
|
||||
sm_dprintf("tlsaadd, name=%s, prev=%d, dnsrc=%d\n",
|
||||
name, dane_tlsa->dane_tlsa_dnsrc, dnsrc);
|
||||
|
||||
/* check previous error and keep the "most important" one? */
|
||||
@ -122,61 +346,79 @@ tlsaadd(name, dr, dane_tlsa, dnsrc, n, pttl, level)
|
||||
# endif
|
||||
/* "else" in #if code above */
|
||||
*pttl = SM_NEG_TTL;
|
||||
return n;
|
||||
return nr;
|
||||
}
|
||||
if (dr == NULL)
|
||||
return n;
|
||||
return nr;
|
||||
if (dr->dns_r_h.ad != 1 && Dane == DANE_SECURE) /* not secure? */
|
||||
return n;
|
||||
return nr;
|
||||
ttl = *pttl;
|
||||
|
||||
/* first: try to find TLSA records */
|
||||
nprev = n;
|
||||
for (rr = dr->dns_r_head; rr != NULL && n < MAX_TLSA_RR;
|
||||
rr = rr->rr_next)
|
||||
nprev = nr;
|
||||
for (rr = dr->dns_r_head; rr != NULL; rr = rr->rr_next)
|
||||
{
|
||||
int tlsa_chk;
|
||||
int tlsa_chk, r;
|
||||
|
||||
if (rr->rr_type != T_TLSA)
|
||||
{
|
||||
if (rr->rr_type != T_CNAME && tTd(8, 8))
|
||||
sm_dprintf("tlsaadd(%s), type=%s\n", name,
|
||||
sm_dprintf("tlsaadd: name=%s, type=%s\n", name,
|
||||
dns_type_to_string(rr->rr_type));
|
||||
continue;
|
||||
}
|
||||
tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data, rr->rr_size, name,
|
||||
true);
|
||||
if (TLSA_UNSUPP == tlsa_chk)
|
||||
TLSA_SET_FL(dane_tlsa, TLSAFLUNS);
|
||||
if (!TLSA_IS_VALID(tlsa_chk))
|
||||
continue;
|
||||
if (TLSA_IS_SUPPORTED(tlsa_chk))
|
||||
TLSA_SET_FL(dane_tlsa, TLSAFLSUP);
|
||||
|
||||
/*
|
||||
** To do: the RRs should be sorted (by "complexity") --
|
||||
** when more than one type is supported.
|
||||
** Note: rr_u.rr_data might be NULL after tlsainsert()
|
||||
** for nice debug output: print the data into a string
|
||||
** and then use it after tlsainsert().
|
||||
*/
|
||||
|
||||
dane_tlsa->dane_tlsa_rr[n] = rr->rr_u.rr_data;
|
||||
dane_tlsa->dane_tlsa_len[n] = rr->rr_size;
|
||||
if (tTd(8, 2))
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
p = rr->rr_u.rr_data;
|
||||
sm_dprintf("tlsaadd(%s), n=%d, %d-%d-%d:%02x\n", name,
|
||||
n, (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
|
||||
sm_dprintf("tlsaadd: name=%s, nr=%d, ", name, nr);
|
||||
tlsa_rr_print(rr->rr_u.rr_data, rr->rr_size);
|
||||
}
|
||||
r = tlsainsert(dane_tlsa, rr, &nr);
|
||||
if (SM_FULL == r)
|
||||
TLSA_SET_FL(dane_tlsa, TLSAFL2MANY);
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("tlsainsert=%d, nr=%d\n", r, nr);
|
||||
|
||||
/* require some minimum TTL? */
|
||||
if (ttl > rr->rr_ttl && rr->rr_ttl > 0)
|
||||
ttl = rr->rr_ttl;
|
||||
}
|
||||
|
||||
/* hack: instead of copying the data, just "take it over" */
|
||||
rr->rr_u.rr_data = NULL;
|
||||
++n;
|
||||
if (tTd(8, 2))
|
||||
{
|
||||
unsigned int ui;
|
||||
|
||||
SM_ASSERT(nr <= MAX_TLSA_RR);
|
||||
for (ui = 0; ui < (unsigned int)nr; ui++)
|
||||
{
|
||||
sm_dprintf("tlsaadd: name=%s, ui=%u, ", name, ui);
|
||||
tlsa_rr_print(dane_tlsa->dane_tlsa_rr[ui],
|
||||
dane_tlsa->dane_tlsa_len[ui]);
|
||||
}
|
||||
}
|
||||
|
||||
if (TLSA_IS_FL(dane_tlsa, TLSAFL2MANY))
|
||||
{
|
||||
if (tTd(8, 20))
|
||||
sm_dprintf("tlsaadd: name=%s, rr=%p, nr=%d, toomany=%d\n", name, rr, nr, TLSA_IS_FL(dane_tlsa, TLSAFL2MANY));
|
||||
}
|
||||
|
||||
/* second: check for CNAME records, but only if no TLSA RR was added */
|
||||
for (rr = dr->dns_r_head; rr != NULL && n < MAX_TLSA_RR && nprev == n;
|
||||
rr = rr->rr_next)
|
||||
for (rr = dr->dns_r_head; rr != NULL && nprev == nr; rr = rr->rr_next)
|
||||
{
|
||||
DNS_REPLY_T *drc;
|
||||
int err, herr;
|
||||
@ -186,30 +428,35 @@ tlsaadd(name, dr, dane_tlsa, dnsrc, n, pttl, level)
|
||||
if (level > 1)
|
||||
{
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("tlsaadd(%s), CNAME=%s, level=%d\n",
|
||||
sm_dprintf("tlsaadd: name=%s, CNAME=%s, level=%d\n",
|
||||
name, rr->rr_u.rr_txt, level);
|
||||
continue;
|
||||
}
|
||||
|
||||
drc = dns_lookup_int(rr->rr_u.rr_txt, C_IN, T_TLSA, 0, 0,
|
||||
(Dane == DANE_SECURE &&
|
||||
!TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX))
|
||||
? SM_RES_DNSSEC : 0,
|
||||
Dane == DANE_SECURE ? SM_RES_DNSSEC : 0,
|
||||
RR_RAW, &err, &herr);
|
||||
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("tlsaadd(%s), CNAME=%s, level=%d, dr=%p, ad=%d, err=%d, herr=%d\n",
|
||||
sm_dprintf("tlsaadd: name=%s, CNAME=%s, level=%d, dr=%p, ad=%d, err=%d, herr=%d\n",
|
||||
name, rr->rr_u.rr_txt, level,
|
||||
(void *)drc, drc != NULL ? drc->dns_r_h.ad : -1,
|
||||
err, herr);
|
||||
nprev = n = tlsaadd(name, drc, dane_tlsa, herr, n, pttl,
|
||||
nprev = nr = tlsaadd(name, drc, dane_tlsa, herr, nr, pttl,
|
||||
level + 1);
|
||||
dns_free_data(drc);
|
||||
drc = NULL;
|
||||
}
|
||||
|
||||
if (TLSA_IS_FL(dane_tlsa, TLSAFLUNS) &&
|
||||
!TLSA_IS_FL(dane_tlsa, TLSAFLSUP) && LogLevel > 9)
|
||||
{
|
||||
sm_syslog(LOG_NOTICE, NOQID,
|
||||
"TLSA=%s, records=%d%s",
|
||||
name, nr, ONLYUNSUPTLSARR);
|
||||
}
|
||||
*pttl = ttl;
|
||||
return n;
|
||||
return nr;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -221,7 +468,7 @@ tlsaadd(name, dr, dane_tlsa, dnsrc, n, pttl, level)
|
||||
** pste -- (pointer to) stab entry (output)
|
||||
** flags -- TLSAFL*
|
||||
** mxttl -- TTL of MX (or host)
|
||||
** port -- port
|
||||
** port -- port number used in TLSA queries (_PORT._tcp.)
|
||||
**
|
||||
** Returns:
|
||||
** The number of TLSA records found.
|
||||
@ -248,7 +495,7 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
time_t now;
|
||||
unsigned int ttl;
|
||||
int n_rrs, len, err, herr;
|
||||
bool isrname;
|
||||
bool isrname, expired;
|
||||
char nbuf[MAXDNAME];
|
||||
char key[MAXDNAME];
|
||||
|
||||
@ -258,9 +505,26 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
if ('\0' == *host)
|
||||
return 0;
|
||||
|
||||
expired = false;
|
||||
isrname = NULL == name;
|
||||
if (isrname)
|
||||
name = host;
|
||||
|
||||
/*
|
||||
** If host->MX lookup was not secure then do not look up TLSA RRs.
|
||||
** Note: this is currently a hack: TLSAFLADMX is used as input flag,
|
||||
** it is (SHOULD!) NOT stored in dane_tlsa->dane_tlsa_flags
|
||||
*/
|
||||
|
||||
if (DANE_SECURE == Dane && 0 == (TLSAFLADMX & flags) &&
|
||||
0 != (TLSAFLNEW & flags))
|
||||
{
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("gettlsa: host=%s, flags=%#lx, no ad but Dane=Secure\n",
|
||||
host, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
now = 0;
|
||||
n_rrs = 0;
|
||||
dr = NULL;
|
||||
@ -273,35 +537,37 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
}
|
||||
else
|
||||
len = -1;
|
||||
if (0 == port || tTd(66, 10))
|
||||
if (0 == port || tTd(66, 101))
|
||||
port = 25;
|
||||
(void) sm_snprintf(key, sizeof(key), "_%u..%s", port, name);
|
||||
(void) sm_snprintf(key, sizeof(key), "_%u.%s", port, name);
|
||||
ste = stab(key, ST_TLSA_RR, ST_FIND);
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("gettlsa(%s, %s, ste=%p, pste=%p, flags=%lX, port=%d)\n",
|
||||
sm_dprintf("gettlsa: host=%s, %s, ste=%p, pste=%p, flags=%#lx, port=%d\n",
|
||||
host, isrname ? "" : name, (void *)ste, (void *)pste,
|
||||
flags, port);
|
||||
|
||||
if (ste != NULL)
|
||||
{
|
||||
dane_tlsa = ste->s_tlsa;
|
||||
if ((TLSAFLADMX & flags) != 0)
|
||||
TLSA_CLR_FL(ste->s_tlsa, TLSAFLNOADMX);
|
||||
}
|
||||
|
||||
/* Do not reload TLSA RRs if the MX RRs were not securely retrieved. */
|
||||
if (pste != NULL
|
||||
&& dane_tlsa != NULL && TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX)
|
||||
&& DANE_SECURE == Dane)
|
||||
goto end;
|
||||
|
||||
#if 0
|
||||
// /* Do not reload TLSA RRs if the MX RRs were not securely retrieved. */
|
||||
// if (pste != NULL
|
||||
// && dane_tlsa != NULL && TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX)
|
||||
// && DANE_SECURE == Dane)
|
||||
// goto end;
|
||||
#endif
|
||||
if (ste != NULL)
|
||||
{
|
||||
SM_ASSERT(dane_tlsa != NULL);
|
||||
now = curtime();
|
||||
if (tTd(8, 20))
|
||||
sm_dprintf("gettlsa: host=%s, found-ste=%p, ste_flags=%#lx, expired=%d\n", host, ste, ste->s_tlsa->dane_tlsa_flags, dane_tlsa->dane_tlsa_exp <= now);
|
||||
if (dane_tlsa->dane_tlsa_exp <= now
|
||||
&& 0 == (TLSAFLNOEXP & flags))
|
||||
{
|
||||
dane_tlsa_clr(dane_tlsa);
|
||||
expired = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_rrs = dane_tlsa->dane_tlsa_n;
|
||||
@ -309,6 +575,10 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
}
|
||||
}
|
||||
|
||||
/* get entries if none exist yet? */
|
||||
if ((0 == (TLSAFLNEW & flags)) && !expired)
|
||||
goto end;
|
||||
|
||||
if (dane_tlsa == NULL)
|
||||
{
|
||||
dane_tlsa = (dane_tlsa_P) sm_malloc(sizeof(*dane_tlsa));
|
||||
@ -330,11 +600,38 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
|
||||
(void) sm_snprintf(nbuf, sizeof(nbuf), "_%u._tcp.%s", port, host);
|
||||
dr = dns_lookup_int(nbuf, C_IN, T_TLSA, 0, 0,
|
||||
TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX) ? 0 : SM_RES_DNSSEC,
|
||||
(TLSAFLADMX & flags) ? SM_RES_DNSSEC : 0,
|
||||
RR_RAW, &err, &herr);
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("gettlsa(%s), dr=%p, ad=%d, err=%d, herr=%d\n", host,
|
||||
(void *)dr, dr != NULL ? dr->dns_r_h.ad : -1, err, herr);
|
||||
{
|
||||
#if 0
|
||||
/* disabled -- what to do with these two counters? log them "somewhere"? */
|
||||
// if (NULL != dr && tTd(8, 12))
|
||||
// {
|
||||
// RESOURCE_RECORD_T *rr;
|
||||
// unsigned int ntlsarrs, usable;
|
||||
//
|
||||
// ntlsarrs = usable = 0;
|
||||
// for (rr = dr->dns_r_head; rr != NULL; rr = rr->rr_next)
|
||||
// {
|
||||
// int tlsa_chk;
|
||||
//
|
||||
// if (rr->rr_type != T_TLSA)
|
||||
// continue;
|
||||
// ++ntlsarrs;
|
||||
// tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data,
|
||||
// rr->rr_size, name, false);
|
||||
// if (TLSA_IS_SUPPORTED(tlsa_chk))
|
||||
// ++usable;
|
||||
//
|
||||
// }
|
||||
// sm_dprintf("gettlsa: host=%s, ntlsarrs=%u, usable\%u\n", host, ntlsarrs, usable);
|
||||
// }
|
||||
#endif /* 0 */
|
||||
sm_dprintf("gettlsa: host=%s, dr=%p, ad=%d, err=%d, herr=%d\n",
|
||||
host, (void *)dr,
|
||||
dr != NULL ? dr->dns_r_h.ad : -1, err, herr);
|
||||
}
|
||||
ttl = UINT_MAX;
|
||||
n_rrs = tlsaadd(key, dr, dane_tlsa, herr, n_rrs, &ttl, 0);
|
||||
|
||||
@ -342,7 +639,7 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
if (n_rrs == 0 && !TLSA_RR_TEMPFAIL(dane_tlsa))
|
||||
{
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("gettlsa(%s), n_rrs=%d, herr=%d, status=NOT_ADDED\n",
|
||||
sm_dprintf("gettlsa: host=%s, n_rrs=%d, herr=%d, status=NOT_ADDED\n",
|
||||
host, n_rrs, dane_tlsa->dane_tlsa_dnsrc);
|
||||
goto cleanup;
|
||||
}
|
||||
@ -370,7 +667,7 @@ gettlsa(host, name, pste, flags, mxttl, port)
|
||||
|
||||
error:
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("gettlsa(%s, %s), status=error\n", host, key);
|
||||
sm_dprintf("gettlsa: host=%s, key=%s, status=error\n", host, key);
|
||||
n_rrs = -1;
|
||||
cleanup:
|
||||
if (NULL == ste)
|
||||
@ -426,15 +723,18 @@ getfallbackmxrr(host)
|
||||
if (NumFallbackMXHosts > 0 && renew > curtime())
|
||||
return NumFallbackMXHosts;
|
||||
|
||||
/* for DANE we need to invoke getmxrr() to get the TLSA RRs. */
|
||||
# if !DANE
|
||||
if (host[0] == '[')
|
||||
/*
|
||||
** For DANE we need to invoke getmxrr() to get the TLSA RRs.
|
||||
** Hack: don't do that if its not a FQHN (e.g., [localhost])
|
||||
** This also triggers for IPv4 addresses, but not IPv6!
|
||||
*/
|
||||
|
||||
if (host[0] == '[' && (!Dane || strchr(host, '.') == NULL))
|
||||
{
|
||||
fbhosts[0] = host;
|
||||
NumFallbackMXHosts = 1;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
/* free old data */
|
||||
for (i = 0; i < NumFallbackMXHosts; i++)
|
||||
@ -448,10 +748,9 @@ getfallbackmxrr(host)
|
||||
|
||||
NumFallbackMXHosts = getmxrr(host, fbhosts, NULL,
|
||||
# if DANE
|
||||
(DANE_SECURE == Dane) ? ISAD :
|
||||
(DANE_SECURE == Dane) ? ISAD :
|
||||
# endif
|
||||
0,
|
||||
&rcode, &ttl, 0);
|
||||
0, &rcode, &ttl, 0, NULL);
|
||||
renew = curtime() + ttl;
|
||||
for (i = 0; i < NumFallbackMXHosts; i++)
|
||||
fbhosts[i] = newstr(fbhosts[i]);
|
||||
@ -518,7 +817,7 @@ hn2alabel(hostname)
|
||||
UIDNA *idna;
|
||||
static char buf[MAXNAME_I]; /* XXX ??? */
|
||||
|
||||
if (addr_is_ascii(hostname))
|
||||
if (str_is_print(hostname))
|
||||
return hostname;
|
||||
idna = uidna_openUTS46(UIDNA_NONTRANSITIONAL_TO_ASCII, &error);
|
||||
(void) uidna_nameToASCII_UTF8(idna, hostname, strlen(hostname),
|
||||
@ -538,13 +837,15 @@ hn2alabel(hostname)
|
||||
** mxprefs -- a pointer to a return buffer of MX preferences.
|
||||
** If NULL, don't try to populate.
|
||||
** flags -- flags:
|
||||
** DROPLOCALHOSt -- If true, all MX records less preferred
|
||||
** DROPLOCALHOST -- If true, all MX records less preferred
|
||||
** than the local host (as determined by $=w) will
|
||||
** be discarded.
|
||||
** TRYFALLBACK -- add also fallback MX host?
|
||||
** ISAD -- host lookup was secure?
|
||||
** rcode -- a pointer to an EX_ status code.
|
||||
** pttl -- pointer to return TTL (can be NULL).
|
||||
** port -- port number used in TLSA queries (_PORT._tcp.)
|
||||
** pad -- (output parameter, pointer to) AD flag (can be NULL)
|
||||
**
|
||||
** Returns:
|
||||
** The number of MX records found.
|
||||
@ -559,7 +860,7 @@ hn2alabel(hostname)
|
||||
*/
|
||||
|
||||
int
|
||||
getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port, pad)
|
||||
char *host;
|
||||
char **mxhosts;
|
||||
unsigned short *mxprefs;
|
||||
@ -567,6 +868,7 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
int *rcode;
|
||||
int *pttl;
|
||||
int port;
|
||||
int *pad;
|
||||
{
|
||||
register unsigned char *eom, *cp;
|
||||
register int i, j, n;
|
||||
@ -640,7 +942,7 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
# endif /* DANE */
|
||||
|
||||
# if USE_EAI
|
||||
if (!addr_is_ascii(host))
|
||||
if (!str_is_print(host))
|
||||
{
|
||||
/* XXX memory leak? */
|
||||
host = sm_rpool_strdup_x(CurEnv->e_rpool, hn2alabel(host));
|
||||
@ -727,6 +1029,8 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
ad = ad && hp->ad;
|
||||
if (tTd(8, 2))
|
||||
sm_dprintf("getmxrr(%s), hp=%p, ad=%d\n", host, (void*)hp, ad);
|
||||
if (pad != NULL)
|
||||
*pad = ad;
|
||||
|
||||
/* avoid problems after truncation in tcp packets */
|
||||
if (n > sizeof(answer))
|
||||
@ -813,14 +1117,22 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
int nrr;
|
||||
unsigned long flags;
|
||||
|
||||
flags = ad ? TLSAFLADMX : TLSAFLNOADMX;
|
||||
flags = TLSAFLNEW;
|
||||
if (pad != NULL && *pad)
|
||||
flags |= TLSAFLADMX;
|
||||
if (tTd(8, 20))
|
||||
sm_dprintf("getmxrr: 1: host=%s, mx=%s, flags=%#lx\n", host, bp, flags);
|
||||
nrr = gettlsa(bp, NULL, NULL, flags, ttl, port);
|
||||
|
||||
/* Only check qname if no TLSA RRs were found */
|
||||
if (0 == nrr && cname2mx && '\0' != qname[0] &&
|
||||
strcmp(qname, bp))
|
||||
{
|
||||
if (tTd(8, 20))
|
||||
sm_dprintf("getmxrr: 2: host=%s, qname=%s, flags=%#lx\n", host, qname, flags);
|
||||
gettlsa(qname, bp, NULL, flags, ttl, port);
|
||||
/* XXX is this the right ad flag? */
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
@ -1009,7 +1321,7 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
char *hn;
|
||||
|
||||
hn = MXHostBuf + 1;
|
||||
if (!addr_is_ascii(hn))
|
||||
if (!str_is_print(hn))
|
||||
{
|
||||
const char *ahn;
|
||||
|
||||
@ -1058,8 +1370,16 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
else
|
||||
cttl = SM_DEFAULT_TTL;
|
||||
|
||||
flags = (ad && n == HOST_SECURE)
|
||||
? TLSAFLADMX : TLSAFLNOADMX;
|
||||
flags = TLSAFLNEW;
|
||||
if (ad && HOST_SECURE == n)
|
||||
{
|
||||
flags |= TLSAFLADMX;
|
||||
if (pad != NULL)
|
||||
*pad = ad;
|
||||
}
|
||||
if (TTD(8, 20))
|
||||
sm_dprintf("getmxrr: 3: host=%s, mx=%s, flags=%#lx, ad=%d\n",
|
||||
host, mxhosts[0], flags, ad);
|
||||
nrr = gettlsa(mxhosts[0], NULL, NULL, flags,
|
||||
cttl, port);
|
||||
|
||||
@ -1070,9 +1390,13 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
|
||||
if (0 == nrr && '\0' != qname[0] &&
|
||||
strcmp(qname, mxhosts[0]))
|
||||
{
|
||||
gettlsa(qname, mxhosts[0], NULL, flags,
|
||||
cttl, port);
|
||||
if (tTd(8, 20))
|
||||
sm_dprintf("getmxrr: 4: host=%s, qname=%s, flags=%#lx\n", host, qname, flags);
|
||||
/* XXX is this the right ad flag? */
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
@ -1081,7 +1405,7 @@ getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
|
||||
/* if we have a default lowest preference, include that */
|
||||
if (fallbackMX != NULL && !seenlocal)
|
||||
{
|
||||
/* TODO: DNSsec status of fallbacks */
|
||||
/* TODO: DNSSEC status of fallbacks */
|
||||
nmx = fallbackmxrr(nmx, prefs, mxhosts);
|
||||
}
|
||||
done:
|
||||
@ -1175,7 +1499,7 @@ bestmx_map_lookup(map, name, av, statp)
|
||||
# endif
|
||||
|
||||
_res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
|
||||
nmx = getmxrr(name, mxhosts, NULL, 0, statp, NULL, -1);
|
||||
nmx = getmxrr(name, mxhosts, NULL, 0, statp, NULL, -1, NULL);
|
||||
_res.options = saveopts;
|
||||
if (nmx <= 0)
|
||||
return NULL;
|
||||
|
@ -114,10 +114,6 @@ fatal_error(exc)
|
||||
char MsgBuf[BUFSIZ*2]; /* text of most recent message */
|
||||
static char HeldMessageBuf[sizeof(MsgBuf)]; /* for held messages */
|
||||
|
||||
#if NAMED_BIND && !defined(NO_DATA)
|
||||
# define NO_DATA NO_ADDRESS
|
||||
#endif
|
||||
|
||||
void
|
||||
/*VARARGS1*/
|
||||
#ifdef __STDC__
|
||||
|
@ -331,6 +331,12 @@ dochompheader(line, pflag, hdrp, e)
|
||||
case '\015': /* cr */
|
||||
qval[l++] = ' ';
|
||||
break;
|
||||
case '\\':
|
||||
qval[l++] = fvalue[k];
|
||||
++k;
|
||||
XLEN(fvalue[k]);
|
||||
qval[l++] = fvalue[k];
|
||||
break;
|
||||
case '"':
|
||||
XLEN('\\');
|
||||
qval[l++] = '\\';
|
||||
@ -344,14 +350,22 @@ dochompheader(line, pflag, hdrp, e)
|
||||
XLEN('"');
|
||||
qval[l++] = '"';
|
||||
qval[l] = '\0';
|
||||
k += strlen(fvalue + k);
|
||||
if (k >= sizeof(qval))
|
||||
l = strlen(fvalue + k);
|
||||
|
||||
/*
|
||||
** If there is something left in fvalue
|
||||
** then it has been truncated.
|
||||
** Note: the log entry might not be correct
|
||||
** in the EAI case: to get the "real" length
|
||||
** ilenx() would have to be applied to fvalue.
|
||||
*/
|
||||
|
||||
if (l > 0)
|
||||
{
|
||||
if (LogLevel > 9)
|
||||
sm_syslog(LOG_WARNING, e->e_id,
|
||||
"Warning: truncated header '%s' before check with '%s' len=%d max=%d",
|
||||
fname, rs, k,
|
||||
(int) (sizeof(qval) - 1));
|
||||
fname, rs, xlen + l, MAXNAME);
|
||||
}
|
||||
macdefine(&e->e_macro, A_TEMP,
|
||||
macid("{currHeader}"), qval);
|
||||
@ -498,7 +512,6 @@ dochompheader(line, pflag, hdrp, e)
|
||||
** Contents of 'line' are destroyed.
|
||||
*/
|
||||
|
||||
|
||||
unsigned long
|
||||
chompheader(line, pflag, hdrp, e)
|
||||
char *line;
|
||||
@ -1122,7 +1135,6 @@ eatheader(e, full, log)
|
||||
** none
|
||||
*/
|
||||
|
||||
|
||||
#define XBUFLEN MAXNAME
|
||||
#if (SYSLOG_BUFSIZE) >= 256
|
||||
# ifndef MSGIDLOGLEN
|
||||
@ -1130,11 +1142,11 @@ eatheader(e, full, log)
|
||||
# define FIRSTLOGLEN 850
|
||||
# else
|
||||
# if MSGIDLOGLEN < 100
|
||||
# ERROR "MSGIDLOGLEN too short"
|
||||
# error "MSGIDLOGLEN too short"
|
||||
# endif
|
||||
/* XREF: this is "sizeof(sbuf)", see above */
|
||||
# if MSGIDLOGLEN >= MAXLINE / 2
|
||||
# ERROR "MSGIDLOGLEN too long"
|
||||
# error "MSGIDLOGLEN too long"
|
||||
# endif
|
||||
|
||||
/* 850 - 100 for original MSGIDLOGLEN */
|
||||
@ -1142,7 +1154,7 @@ eatheader(e, full, log)
|
||||
|
||||
/* check that total length is ok */
|
||||
# if FIRSTLOGLEN + 200 >= MAXLINE
|
||||
# ERROR "MSGIDLOGLEN too long"
|
||||
# error "MSGIDLOGLEN too long"
|
||||
# endif
|
||||
# if MSGIDLOGLEN > MAXNAME
|
||||
# undef XBUFLEN
|
||||
@ -1371,7 +1383,7 @@ priencode(p)
|
||||
} while (0)
|
||||
|
||||
#if MAXNAME < 10
|
||||
# ERROR "MAXNAME must be at least 10"
|
||||
# error "MAXNAME must be at least 10"
|
||||
#endif
|
||||
|
||||
char *
|
||||
|
@ -11,8 +11,6 @@ cpyr By using this file, you agree to the terms and conditions set
|
||||
cpyr forth in the LICENSE file which can be found at the top level of
|
||||
cpyr the sendmail distribution.
|
||||
cpyr
|
||||
cpyr $$Id: helpfile,v 8.49 2013-11-22 20:51:55 ca Exp $$
|
||||
cpyr
|
||||
smtp This is sendmail version $v
|
||||
smtp Topics:
|
||||
smtp HELO EHLO MAIL RCPT DATA
|
||||
@ -39,7 +37,6 @@ ehlo TURN Turn the operation around [RFC821]
|
||||
ehlo 8BITMIME Use 8-bit data [RFC1652]
|
||||
ehlo SIZE Message size declaration [RFC1870]
|
||||
ehlo VERB Verbose [Allman]
|
||||
ehlo CHUNKING Chunking [RFC1830]
|
||||
ehlo BINARYMIME Binary MIME [RFC1830]
|
||||
ehlo PIPELINING Command Pipelining [RFC1854]
|
||||
ehlo DSN Delivery Status Notification [RFC1891]
|
||||
@ -48,6 +45,7 @@ ehlo STARTTLS Secure SMTP [RFC2487]
|
||||
ehlo AUTH Authentication [RFC2554]
|
||||
ehlo ENHANCEDSTATUSCODES Enhanced status codes [RFC2034]
|
||||
ehlo DELIVERBY Deliver By [RFC2852]
|
||||
ehlo SMTPUTF8 Internationalized Email [RFC6530]
|
||||
mail MAIL From:<sender> [ <parameters> ]
|
||||
mail Specifies the sender. Parameters are ESMTP extensions.
|
||||
mail See "HELP DSN" for details.
|
||||
@ -56,7 +54,7 @@ rcpt Specifies the recipient. Can be used any number of times.
|
||||
rcpt Parameters are ESMTP extensions. See "HELP DSN" for details.
|
||||
data DATA
|
||||
data Following text is collected as the message.
|
||||
data End with a single dot.
|
||||
data End with a single dot on a line by itself.
|
||||
rset RSET
|
||||
rset Resets the system.
|
||||
quit QUIT
|
||||
|
@ -83,7 +83,6 @@ int NextMacroId = 0240; /* codes for long named macros */
|
||||
#define NEXTMACROID(mid) ((mid) + 1)
|
||||
#endif /* _FFR_MORE_MACROS */
|
||||
|
||||
|
||||
/*
|
||||
** INITMACROS -- initialize the macro system
|
||||
**
|
||||
@ -411,6 +410,9 @@ mactabclear(mac)
|
||||
** id -- Macro id. This is a single character macro name
|
||||
** such as 'g', or a value returned by macid().
|
||||
** value -- Macro value: either NULL, or a string.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
@ -442,8 +444,8 @@ macdefine(mac, vclass, id, value)
|
||||
sm_dprintf(")\n");
|
||||
}
|
||||
#if USE_EAI && 0
|
||||
if (('j' == id || 'm' == id) && !addr_is_ascii(value))
|
||||
return an error/warning to caller and let them handle it.
|
||||
// if (('j' == id || 'm' == id) && !addr_is_ascii(value))
|
||||
// return an error/warning to caller and let them handle it.
|
||||
#endif
|
||||
|
||||
if (mac->mac_rpool == NULL)
|
||||
@ -504,6 +506,9 @@ macdefine(mac, vclass, id, value)
|
||||
** mac -- Macro table.
|
||||
** i -- Macro name, specified as an integer offset.
|
||||
** value -- Macro value: either NULL, or a string.
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
@ -758,7 +763,51 @@ wordinclass(str, cl)
|
||||
int cl;
|
||||
{
|
||||
STAB *s;
|
||||
#if _FFR_DYN_CLASS
|
||||
MAP *map;
|
||||
int status;
|
||||
char *p;
|
||||
char key[MAXLINE];
|
||||
|
||||
s = stab(str, ST_CLASS, ST_FIND);
|
||||
return s != NULL && bitnset(bitidx(cl), s->s_class);
|
||||
p = macname(cl);
|
||||
s = stab(p, ST_DYNMAP, ST_FIND);
|
||||
if (NULL == s)
|
||||
{
|
||||
#endif
|
||||
s = stab(str, ST_CLASS, ST_FIND);
|
||||
return s != NULL && bitnset(bitidx(cl), s->s_class);
|
||||
#if _FFR_DYN_CLASS
|
||||
}
|
||||
map = &s->s_dynclass;
|
||||
SM_REQUIRE(NULL != map);
|
||||
SM_REQUIRE(!SM_IS_EMPTY(str));
|
||||
if (bitset(MF_OPENBOGUS, map->map_mflags))
|
||||
{
|
||||
/* need to set some error! */
|
||||
return false;
|
||||
}
|
||||
|
||||
key[0] = '\0';
|
||||
if (!SM_IS_EMPTY(map->map_tag))
|
||||
{
|
||||
sm_strlcpy(key, map->map_tag, sizeof(key));
|
||||
sm_strlcat(key, ":", sizeof(key));
|
||||
}
|
||||
sm_strlcat(key, str, sizeof(key));
|
||||
status = EX_OK;
|
||||
p = (map->map_class->map_lookup)(map, key, NULL, &status);
|
||||
if (NULL != p)
|
||||
return true;
|
||||
if ((EX_OK == status && NULL == p) || EX_NOTFOUND == status)
|
||||
return false;
|
||||
|
||||
sm_syslog(LOG_WARNING, CurEnv->e_id,
|
||||
"dynamic class: A{%s}: map lookup failed: key=%s, status=%d",
|
||||
map->map_mname, key, status);
|
||||
|
||||
/* Note: this error is shown to the client, so do not "leak" info */
|
||||
usrerr("451 4.3.1 temporary error");
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
@ -326,9 +326,7 @@ main(argc, argv, envp)
|
||||
V6LoopbackAddrFound = false;
|
||||
# endif
|
||||
#endif
|
||||
#if XDEBUG
|
||||
checkfd012("after openlog");
|
||||
#endif
|
||||
|
||||
tTsetup(tTdvect, sizeof(tTdvect), "0-99.1,*_trace_*.1");
|
||||
|
||||
@ -672,6 +670,11 @@ main(argc, argv, envp)
|
||||
sm_dprintf(" OpenSSL: linked 0x%08x\n",
|
||||
(uint) TLS_version_num());
|
||||
}
|
||||
# if defined(LIBRESSL_VERSION_NUMBER)
|
||||
if (tTd(0, 15))
|
||||
sm_dprintf(" LibreSSL: compiled 0x%08x\n",
|
||||
(uint) LIBRESSL_VERSION_NUMBER);
|
||||
# endif
|
||||
#endif /* STARTTLS */
|
||||
|
||||
/* clear sendmail's environment */
|
||||
@ -1276,9 +1279,7 @@ main(argc, argv, envp)
|
||||
** Extract special fields for local use.
|
||||
*/
|
||||
|
||||
#if XDEBUG
|
||||
checkfd012("before readcf");
|
||||
#endif
|
||||
vendor_pre_defaults(&BlankEnvelope);
|
||||
|
||||
readcf(getcfname(OpMode, SubmitMode, cftype, conffile),
|
||||
@ -1377,7 +1378,7 @@ main(argc, argv, envp)
|
||||
makeworkgroups();
|
||||
|
||||
#if USE_EAI
|
||||
if (!SMTPUTF8 && MainEnvelope.e_smtputf8)
|
||||
if (!SMTP_UTF8 && MainEnvelope.e_smtputf8)
|
||||
{
|
||||
usrerr("-U requires SMTPUTF8");
|
||||
finis(false, true, EX_USAGE);
|
||||
@ -1507,8 +1508,8 @@ main(argc, argv, envp)
|
||||
usrerr("Illegal body type %s", BlankEnvelope.e_bodytype);
|
||||
BlankEnvelope.e_bodytype = NULL;
|
||||
}
|
||||
else if (i != BODYTYPE_NONE)
|
||||
SevenBitInput = (i == BODYTYPE_7BIT);
|
||||
else if (BODYTYPE_7BIT == i)
|
||||
BlankEnvelope.e_flags |= EF_7BITBODY;
|
||||
|
||||
/* tweak default DSN notifications */
|
||||
if (DefaultNotify == 0)
|
||||
@ -2014,9 +2015,7 @@ main(argc, argv, envp)
|
||||
sm_sasl_init();
|
||||
#endif
|
||||
|
||||
#if XDEBUG
|
||||
checkfd012("before main() initmaps");
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Do operation-mode-dependent initialization.
|
||||
@ -2625,7 +2624,6 @@ main(argc, argv, envp)
|
||||
/* init TLS for server, ignore result for now */
|
||||
(void) initsrvtls(tls_ok);
|
||||
#endif
|
||||
|
||||
nextreq:
|
||||
p_flags = getrequests(&MainEnvelope);
|
||||
|
||||
@ -2663,8 +2661,8 @@ main(argc, argv, envp)
|
||||
authinfo = buf;
|
||||
if (tTd(75, 9))
|
||||
sm_syslog(LOG_INFO, NOQID,
|
||||
"main: where=not_calling_getauthinfo, RealHostAddr=%s",
|
||||
anynet_ntoa(&RealHostAddr));
|
||||
"main: where=not_calling_getauthinfo, RealHostAddr=%s, RealHostName=%s",
|
||||
anynet_ntoa(&RealHostAddr), RealHostName);
|
||||
}
|
||||
else
|
||||
/* WARNING: "non-braced" else */
|
||||
@ -2818,7 +2816,7 @@ main(argc, argv, envp)
|
||||
(MainEnvelope.e_smtputf8 = !asciistr(fromaddr))))
|
||||
{
|
||||
/* not very efficient: asciistr() may be called above already */
|
||||
if (!SMTPUTF8 && !asciistr(fromaddr))
|
||||
if (!SMTP_UTF8 && !asciistr(fromaddr))
|
||||
{
|
||||
usrerr("non-ASCII sender address %s requires SMTPUTF8",
|
||||
fromaddr);
|
||||
@ -2879,7 +2877,8 @@ main(argc, argv, envp)
|
||||
|
||||
/* collect body for UUCP return */
|
||||
if (OpMode != MD_VERIFY)
|
||||
collect(InChannel, false, NULL, &MainEnvelope, true);
|
||||
collect(InChannel, SMTPMODE_NO, NULL, &MainEnvelope,
|
||||
true);
|
||||
finis(true, true, EX_USAGE);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@ -2922,24 +2921,13 @@ main(argc, argv, envp)
|
||||
int savederrors;
|
||||
unsigned long savedflags;
|
||||
|
||||
/*
|
||||
** workaround for compiler warning on Irix:
|
||||
** do not initialize variable in the definition, but
|
||||
** later on:
|
||||
** warning(1548): transfer of control bypasses
|
||||
** initialization of:
|
||||
** variable "savederrors" (declared at line 2570)
|
||||
** variable "savedflags" (declared at line 2571)
|
||||
** goto giveup;
|
||||
*/
|
||||
|
||||
savederrors = Errors;
|
||||
savedflags = MainEnvelope.e_flags & EF_FATALERRS;
|
||||
MainEnvelope.e_flags |= EF_GLOBALERRS;
|
||||
MainEnvelope.e_flags &= ~EF_FATALERRS;
|
||||
Errors = 0;
|
||||
buffer_errors();
|
||||
collect(InChannel, false, NULL, &MainEnvelope, true);
|
||||
collect(InChannel, SMTPMODE_NO, NULL, &MainEnvelope, true);
|
||||
|
||||
/* header checks failed */
|
||||
if (Errors > 0)
|
||||
@ -3285,6 +3273,10 @@ sigterm(sig)
|
||||
FIX_SYSV_SIGNAL(sig, sigterm);
|
||||
ShutdownRequest = "signal";
|
||||
errno = save_errno;
|
||||
#if _FFR_DMTRIGGER
|
||||
/* temporary? */
|
||||
proc_list_signal(PROC_QM, sig);
|
||||
#endif
|
||||
return SIGFUNC_RETURN;
|
||||
}
|
||||
/*
|
||||
@ -3427,7 +3419,7 @@ intsig(sig)
|
||||
** none
|
||||
**
|
||||
** Side Effects:
|
||||
** Trys to insure that we are immune to vagaries of
|
||||
** Try to insure that we are immune to vagaries of
|
||||
** the controlling tty.
|
||||
*/
|
||||
|
||||
@ -3530,9 +3522,7 @@ disconnect(droplev, e)
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
#if XDEBUG
|
||||
checkfd012("disconnect");
|
||||
#endif
|
||||
|
||||
if (LogLevel > 71)
|
||||
sm_syslog(LOG_DEBUG, LOGID(e), "in background, pid=%d",
|
||||
@ -4219,6 +4209,10 @@ testmodeline(line, e)
|
||||
#if _FFR_8BITENVADDR
|
||||
int len = sizeof(exbuf);
|
||||
#endif
|
||||
#if _FFR_TESTS
|
||||
extern void t_hostsig __P((ADDRESS *, char *, MAILER *));
|
||||
extern void t_parsehostsig __P((char *, MAILER *));
|
||||
#endif
|
||||
|
||||
/* skip leading spaces */
|
||||
while (*line == ' ')
|
||||
@ -4226,6 +4220,7 @@ testmodeline(line, e)
|
||||
|
||||
lbp = NULL;
|
||||
eightbit = false;
|
||||
maps_reset_chged("testmodeline");
|
||||
switch (line[0])
|
||||
{
|
||||
case '#':
|
||||
@ -4376,7 +4371,36 @@ testmodeline(line, e)
|
||||
case '$':
|
||||
if (line[1] == '=')
|
||||
{
|
||||
#if _FFR_DYN_CLASS
|
||||
MAP *dynmap;
|
||||
STAB *st;
|
||||
#endif
|
||||
|
||||
mid = macid(&line[2]);
|
||||
#if _FFR_DYN_CLASS
|
||||
if (mid != 0 &&
|
||||
(st = stab(macname(mid), ST_DYNMAP, ST_FIND)) != NULL)
|
||||
{
|
||||
dynmap = &st->s_dynclass;
|
||||
q = dynmap->map_class->map_cname;
|
||||
if (SM_IS_EMPTY(q))
|
||||
q = "implicit";
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"$=%s not possible for a dynamic class, use\n",
|
||||
line + 2);
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"makemap -u %s %s",
|
||||
q, dynmap->map_file);
|
||||
if (!SM_IS_EMPTY(dynmap->map_tag))
|
||||
{
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
" | grep -i '^%s:'",
|
||||
dynmap->map_tag);
|
||||
}
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (mid != 0)
|
||||
stabapply(dump_class, mid);
|
||||
return;
|
||||
@ -4435,7 +4459,7 @@ testmodeline(line, e)
|
||||
return;
|
||||
}
|
||||
nmx = getmxrr(p, mxhosts, NULL, TRYFALLBACK, &rcode,
|
||||
NULL, -1);
|
||||
NULL, -1, NULL);
|
||||
if (nmx == NULLMX)
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"getmxrr(%s) returns null MX (See RFC7505)\n",
|
||||
@ -4626,7 +4650,11 @@ testmodeline(line, e)
|
||||
macdefine(&e->e_macro, A_TEMP,
|
||||
macid("{addr_type}"), exbuf);
|
||||
}
|
||||
else if (SM_STRCASEEQ(&line[1], "parse"))
|
||||
else if (SM_STRCASEEQ(&line[1], "parse")
|
||||
#if _FFR_TESTS
|
||||
|| SM_STRCASEEQ(&line[1], "hostsig")
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if (*p == '\0')
|
||||
{
|
||||
@ -4653,11 +4681,20 @@ testmodeline(line, e)
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"Cannot parse\n");
|
||||
else if (a.q_host != NULL && a.q_host[0] != '\0')
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
{
|
||||
#if _FFR_TESTS
|
||||
if (SM_STRCASEEQ(&line[1], "hostsig"))
|
||||
t_hostsig(&a, NULL, NULL);
|
||||
else
|
||||
#endif /* _FFR_TESTS */
|
||||
{
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"mailer %s, host %s, user %s\n",
|
||||
a.q_mailer->m_name,
|
||||
a.q_host,
|
||||
a.q_user);
|
||||
}
|
||||
}
|
||||
else
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"mailer %s, user %s\n",
|
||||
@ -4743,6 +4780,31 @@ testmodeline(line, e)
|
||||
r = NULL;
|
||||
}
|
||||
}
|
||||
# if _FFR_TESTS
|
||||
else if (SM_STRCASEEQ(&line[1], "hostsignature"))
|
||||
{
|
||||
STAB *st;
|
||||
MAILER *m;
|
||||
|
||||
st = stab("esmtp", ST_MAILER, ST_FIND);
|
||||
if (NULL == st)
|
||||
{
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"Unknown mailer esmtp\n");
|
||||
return;
|
||||
}
|
||||
m = st->s_mailer;
|
||||
if (NULL == m)
|
||||
{
|
||||
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
|
||||
"Unknown mailer esmtp\n");
|
||||
return;
|
||||
}
|
||||
t_hostsig(NULL, p, m);
|
||||
}
|
||||
else if (SM_STRCASEEQ(&line[1], "parsesig"))
|
||||
t_parsehostsig(p, NULL);
|
||||
# endif /* _FFR_TESTS */
|
||||
#endif /* DANE */
|
||||
else
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ static bool extract_canonname __P((char *, char *, char *, char[], int));
|
||||
static void map_close __P((STAB *, int));
|
||||
static void map_init __P((STAB *, int));
|
||||
#ifdef LDAPMAP
|
||||
static STAB * ldapmap_findconn __P((SM_LDAP_STRUCT *));
|
||||
static STAB *ldapmap_findconn __P((SM_LDAP_STRUCT *));
|
||||
#endif
|
||||
#if NISPLUS
|
||||
static bool nisplus_getcanonname __P((char *, int, int *));
|
||||
@ -90,6 +90,176 @@ static STAB *socket_map_findconn __P((const char*));
|
||||
# endif
|
||||
#endif /* ENOSYS */
|
||||
|
||||
/*
|
||||
** MAP_HAS_CHGED -- check whether fd was updated or fn refers to a different file
|
||||
**
|
||||
** Parameters:
|
||||
** map -- map being checked
|
||||
** fn -- (full) file name of map.
|
||||
** fd -- fd of map.
|
||||
**
|
||||
** Returns:
|
||||
** true iff file referenced by fd was updated
|
||||
** or fn refers to a different file.
|
||||
*/
|
||||
|
||||
static bool map_has_chged __P((MAP *, const char *, int));
|
||||
|
||||
static bool
|
||||
map_has_chged(map, fn, fd)
|
||||
MAP *map;
|
||||
const char *fn;
|
||||
int fd;
|
||||
{
|
||||
struct stat stbuf;
|
||||
#if _FFR_MAP_CHK_FILE
|
||||
struct stat nstbuf;
|
||||
#endif
|
||||
|
||||
#if _FFR_MAP_CHK_FILE > 1
|
||||
if (tTd(38, 8))
|
||||
sm_dprintf("map_has_chged: fn=%s, fd=%d, checked=%d\n",
|
||||
fn, fd, bitset(MF_CHKED_CHGD, map->map_mflags));
|
||||
if (fd < 0)
|
||||
return true;
|
||||
|
||||
/* XXX check can be disabled via -d38.101 for testing */
|
||||
if (bitset(MF_CHKED_CHGD, map->map_mflags) && !tTd(38, 101))
|
||||
return false;
|
||||
map->map_mflags |= MF_CHKED_CHGD;
|
||||
#endif
|
||||
if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
|
||||
{
|
||||
if (tTd(38, 4))
|
||||
sm_dprintf("reopen map: name=%s, fd=%d\n", map->map_mname, fd);
|
||||
return true;
|
||||
}
|
||||
#if _FFR_MAP_CHK_FILE
|
||||
if (stat(fn, &nstbuf) == 0 &&
|
||||
(nstbuf.st_dev != stbuf.st_dev || nstbuf.st_ino != stbuf.st_ino))
|
||||
{
|
||||
if (tTd(38, 4) && stat(fn, &nstbuf) == 0)
|
||||
sm_dprintf("reopen map: fn=%s, ndev=%d, dev=%d, nino=%d, ino=%d\n",
|
||||
fn, (int) nstbuf.st_dev, (int) stbuf.st_dev,
|
||||
(int) nstbuf.st_ino, (int) stbuf.st_ino);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
#if _FFR_MAP_CHK_FILE > 1
|
||||
|
||||
/*
|
||||
** MAP_RESET_CHGD -- reset MF_CHKED_CHGD in a map
|
||||
**
|
||||
** Parameters:
|
||||
** s -- STAB entry: if map: reset MF_CHKED_CHGD
|
||||
** unused -- unused variable
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
static void map_reset_chged __P((STAB *, int));
|
||||
|
||||
/* ARGSUSED1 */
|
||||
static void
|
||||
map_reset_chged(s, unused)
|
||||
STAB *s;
|
||||
int unused;
|
||||
{
|
||||
MAP *map;
|
||||
|
||||
/* has to be a map */
|
||||
if (ST_MAP != s->s_symtype
|
||||
#if _FFR_DYN_CLASS
|
||||
&& ST_DYNMAP != s->s_symtype
|
||||
#endif
|
||||
)
|
||||
return;
|
||||
map = &s->s_map;
|
||||
if (!bitset(MF_VALID, map->map_mflags))
|
||||
return;
|
||||
if (tTd(38, 8))
|
||||
sm_dprintf("map_reset_chged: name=%s, checked=%d\n",
|
||||
map->map_mname, bitset(MF_CHKED_CHGD, map->map_mflags));
|
||||
map->map_mflags &= ~MF_CHKED_CHGD;
|
||||
}
|
||||
|
||||
/*
|
||||
** MAPS_RESET_CHGD -- reset MF_CHKED_CHGD in all maps
|
||||
**
|
||||
** Parameters:
|
||||
** msg - caller (for debugging)
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
void
|
||||
maps_reset_chged(msg)
|
||||
const char *msg;
|
||||
{
|
||||
if (tTd(38, 16))
|
||||
sm_dprintf("maps_reset_chged: msg=%s\n", msg);
|
||||
stabapply(map_reset_chged, 0);
|
||||
}
|
||||
#endif /* _FFR_MAP_CHK_FILE > 1 */
|
||||
|
||||
|
||||
#if NEWDB || CDB || (NDBM && _FFR_MAP_CHK_FILE)
|
||||
static bool smdb_add_extension __P((char *, int, char *, char *));
|
||||
|
||||
/*
|
||||
** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
|
||||
**
|
||||
** Just adds a . followed by a string to a db_name if there
|
||||
** is room and the db_name does not already have that extension.
|
||||
**
|
||||
** Parameters:
|
||||
** full_name -- The final file name.
|
||||
** max_full_name_len -- The max length for full_name.
|
||||
** db_name -- The name of the db.
|
||||
** extension -- The extension to add.
|
||||
**
|
||||
** Returns:
|
||||
** SMDBE_OK -- Success.
|
||||
** Anything else is an error. Look up more info about the
|
||||
** error in the comments for the specific open() used.
|
||||
*/
|
||||
|
||||
static bool
|
||||
smdb_add_extension(full_name, max_full_name_len, db_name, extension)
|
||||
char *full_name;
|
||||
int max_full_name_len;
|
||||
char *db_name;
|
||||
char *extension;
|
||||
{
|
||||
int extension_len;
|
||||
int db_name_len;
|
||||
|
||||
if (full_name == NULL || db_name == NULL || extension == NULL)
|
||||
return false; /* SMDBE_INVALID_PARAMETER; */
|
||||
|
||||
extension_len = strlen(extension);
|
||||
db_name_len = strlen(db_name);
|
||||
|
||||
if (extension_len + db_name_len + 2 > max_full_name_len)
|
||||
return false; /* SMDBE_DB_NAME_TOO_LONG; */
|
||||
|
||||
if (db_name_len < extension_len + 1 ||
|
||||
db_name[db_name_len - extension_len - 1] != '.' ||
|
||||
strcmp(&db_name[db_name_len - extension_len], extension) != 0)
|
||||
(void) sm_snprintf(full_name, max_full_name_len, "%s.%s",
|
||||
db_name, extension);
|
||||
else
|
||||
(void) sm_strlcpy(full_name, db_name, max_full_name_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* NEWDB || CDB || (NDBM && _FFR_MAP_CHK_FILE) */
|
||||
|
||||
/*
|
||||
** MAP.C -- implementations for various map classes.
|
||||
**
|
||||
@ -130,6 +300,7 @@ static STAB *socket_map_findconn __P((const char*));
|
||||
** to be more properly integrated into the map structure.
|
||||
*/
|
||||
|
||||
/* XREF: conf.c must use the same expression */
|
||||
#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
|
||||
# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
|
||||
#else
|
||||
@ -459,6 +630,52 @@ map_rewrite(map, s, slen, av)
|
||||
sm_dprintf("map_rewrite => %s\n", buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
** MAPCHOWN -- if available fchown() the fds to TrustedUid
|
||||
**
|
||||
** Parameters:
|
||||
** mapname - name of map (for error reporting)
|
||||
** fd0 - first fd (must be valid)
|
||||
** fd1 - second fd (<0: do not use)
|
||||
** filename - name of file (for error reporting)
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
*/
|
||||
|
||||
static void mapchown __P((const char *, int, int, const char *));
|
||||
|
||||
static void
|
||||
mapchown(mapname, fd0, fd1, filename)
|
||||
const char *mapname;
|
||||
int fd0;
|
||||
int fd1;
|
||||
const char *filename;
|
||||
{
|
||||
if (!(geteuid() == 0 && TrustedUid != 0))
|
||||
return;
|
||||
#if HASFCHOWN
|
||||
if (fchown(fd0, TrustedUid, -1) < 0 ||
|
||||
(fd1 >= 0 && fchown(fd1, TrustedUid, -1) < 0))
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"ownership change on %s failed: %s",
|
||||
filename, sm_errstring(err));
|
||||
message("050 ownership change on %s failed: %s",
|
||||
filename, sm_errstring(err));
|
||||
}
|
||||
#else /* HASFCHOWN */
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"no fchown(): cannot change ownership on %s",
|
||||
mapname);
|
||||
message("050 no fchown(): cannot change ownership on %s",
|
||||
mapname);
|
||||
#endif /* HASFCHOWN */
|
||||
}
|
||||
|
||||
/*
|
||||
** INITMAPS -- rebuild alias maps
|
||||
**
|
||||
@ -472,14 +689,11 @@ map_rewrite(map, s, slen, av)
|
||||
void
|
||||
initmaps()
|
||||
{
|
||||
#if XDEBUG
|
||||
checkfd012("entering initmaps");
|
||||
#endif
|
||||
stabapply(map_init, 0);
|
||||
#if XDEBUG
|
||||
checkfd012("exiting initmaps");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** MAP_INIT -- rebuild a map
|
||||
**
|
||||
@ -533,7 +747,7 @@ map_init(s, unused)
|
||||
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
|
||||
}
|
||||
|
||||
(void) rebuildaliases(map, false);
|
||||
(void) rebuildaliases(map);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -692,7 +906,7 @@ map_close(s, bogus)
|
||||
map->map_mflags |= MF_CLOSING;
|
||||
map->map_class->map_close(map);
|
||||
}
|
||||
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_OPENBOGUS|MF_CLOSING);
|
||||
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_OPENBOGUS|MF_CLOSING|MF_CHKED_CHGD);
|
||||
}
|
||||
|
||||
#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
|
||||
@ -1072,14 +1286,14 @@ dns_map_parseargs(map,args)
|
||||
break;
|
||||
switch (*++p)
|
||||
{
|
||||
# if DNSSEC_TEST
|
||||
# if DNSSEC_TEST || _FFR_NAMESERVER
|
||||
case '@':
|
||||
++p;
|
||||
if (nsportip(p) < 0)
|
||||
syserr("dns map %s: nsportip(%s)=failed",
|
||||
map->map_mname, p);
|
||||
break;
|
||||
# endif /* DNSSEC_TEST */
|
||||
# endif /* DNSSEC_TEST || _FFR_NAMESERVER */
|
||||
|
||||
case 'A':
|
||||
map->map_mflags |= MF_APPEND;
|
||||
@ -1243,7 +1457,7 @@ dns_map_parseargs(map,args)
|
||||
**
|
||||
** Parameters:
|
||||
** map -- pointer to MAP
|
||||
** name -- name to lookup
|
||||
** name -- name to look up
|
||||
** av -- arguments to interpolate into buf.
|
||||
** statp -- pointer to status (EX_)
|
||||
**
|
||||
@ -1694,28 +1908,7 @@ ndbm_map_open(map, mode)
|
||||
else
|
||||
{
|
||||
map->map_mflags |= MF_LOCKED;
|
||||
if (geteuid() == 0 && TrustedUid != 0)
|
||||
{
|
||||
# if HASFCHOWN
|
||||
if (fchown(dfd, TrustedUid, -1) < 0 ||
|
||||
fchown(pfd, TrustedUid, -1) < 0)
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"ownership change on %s failed: %s",
|
||||
map->map_file, sm_errstring(err));
|
||||
message("050 ownership change on %s failed: %s",
|
||||
map->map_file, sm_errstring(err));
|
||||
}
|
||||
# else /* HASFCHOWN */
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"no fchown(): cannot change ownership on %s",
|
||||
map->map_file);
|
||||
message("050 no fchown(): cannot change ownership on %s",
|
||||
map->map_file);
|
||||
# endif /* HASFCHOWN */
|
||||
}
|
||||
mapchown(map->map_file, dfd, pfd, map->map_file);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -1735,7 +1928,10 @@ ndbm_map_lookup(map, name, av, statp)
|
||||
datum key, val;
|
||||
int dfd, pfd;
|
||||
char keybuf[MAXNAME + 1]; /* EAI:ok */
|
||||
struct stat stbuf;
|
||||
# if _FFR_MAP_CHK_FILE
|
||||
char buf[MAXPATHLEN];
|
||||
# endif
|
||||
const char *fn = NULL;
|
||||
|
||||
if (tTd(38, 20))
|
||||
sm_dprintf("ndbm_map_lookup(%s, %s)\n",
|
||||
@ -1752,13 +1948,24 @@ ndbm_map_lookup(map, name, av, statp)
|
||||
makelower_buf(keybuf, keybuf, sizeof(keybuf));
|
||||
key.dptr = keybuf;
|
||||
}
|
||||
# if _FFR_MAP_CHK_FILE
|
||||
if (!smdb_add_extension(buf, sizeof(buf), map->map_file, "pag"))
|
||||
{
|
||||
errno = 0;
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
syserr("ndbm map \"%s\": map file %s name too long",
|
||||
map->map_mname, map->map_file);
|
||||
return NULL;
|
||||
}
|
||||
fn = buf;
|
||||
# endif
|
||||
lockdbm:
|
||||
dfd = dbm_dirfno((DBM *) map->map_db1);
|
||||
if (dfd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
|
||||
(void) lockfile(dfd, map->map_file, ".dir", LOCK_SH);
|
||||
pfd = dbm_pagfno((DBM *) map->map_db1);
|
||||
if (pfd < 0 || fstat(pfd, &stbuf) < 0 ||
|
||||
stbuf.st_mtime > map->map_mtime)
|
||||
|
||||
if (map_has_chged(map, fn, pfd))
|
||||
{
|
||||
/* Reopen the database to sync the cache */
|
||||
int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
|
||||
@ -2070,26 +2277,14 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
/* do initial file and directory checks */
|
||||
if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf))
|
||||
if (!smdb_add_extension(buf, sizeof(buf), map->map_file, "db"))
|
||||
{
|
||||
errno = 0;
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
syserr("map \"%s\": map file %s name too long",
|
||||
syserr("db map \"%s\": map file %s name too long",
|
||||
map->map_mname, map->map_file);
|
||||
return false;
|
||||
}
|
||||
i = strlen(buf);
|
||||
if (i < 3 || strcmp(&buf[i - 3], ".db") != 0)
|
||||
{
|
||||
if (sm_strlcat(buf, ".db", sizeof(buf)) >= sizeof(buf))
|
||||
{
|
||||
errno = 0;
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
syserr("map \"%s\": map file %s name too long",
|
||||
map->map_mname, map->map_file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mode &= O_ACCMODE;
|
||||
omode = mode;
|
||||
@ -2121,7 +2316,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
|
||||
if (i == ENOENT)
|
||||
prob = "missing";
|
||||
if (tTd(38, 2))
|
||||
sm_dprintf("\t%s map file: %s\n", prob, sm_errstring(i));
|
||||
sm_dprintf("\t%s map file %s: %s\n", prob, buf, sm_errstring(i));
|
||||
errno = i;
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
syserr("%s map \"%s\": %s map file %s",
|
||||
@ -2299,36 +2494,14 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
|
||||
map->map_mflags |= MF_LOCKED;
|
||||
# if LOCK_ON_OPEN
|
||||
if (fd >= 0 && mode == O_RDONLY)
|
||||
{
|
||||
(void) lockfile(fd, buf, NULL, LOCK_UN);
|
||||
}
|
||||
# endif /* LOCK_ON_OPEN */
|
||||
# endif
|
||||
|
||||
/* try to make sure that at least the database header is on disk */
|
||||
if (mode == O_RDWR)
|
||||
{
|
||||
(void) db->sync(db, 0);
|
||||
if (geteuid() == 0 && TrustedUid != 0)
|
||||
{
|
||||
# if HASFCHOWN
|
||||
if (fchown(fd, TrustedUid, -1) < 0)
|
||||
{
|
||||
int err = errno;
|
||||
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"ownership change on %s failed: %s",
|
||||
buf, sm_errstring(err));
|
||||
message("050 ownership change on %s failed: %s",
|
||||
buf, sm_errstring(err));
|
||||
}
|
||||
# else /* HASFCHOWN */
|
||||
sm_syslog(LOG_ALERT, NOQID,
|
||||
"no fchown(): cannot change ownership on %s",
|
||||
map->map_file);
|
||||
message("050 no fchown(): cannot change ownership on %s",
|
||||
map->map_file);
|
||||
# endif /* HASFCHOWN */
|
||||
}
|
||||
mapchown(map->map_file, fd, -1, buf);
|
||||
}
|
||||
|
||||
map->map_db2 = (ARBPTR_T) db;
|
||||
@ -2342,6 +2515,18 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
|
||||
if (fd >= 0 && fstat(fd, &st) >= 0)
|
||||
map->map_mtime = st.st_mtime;
|
||||
|
||||
# if _FFR_TESTS
|
||||
if (tTd(68, 101) && fd >= 0 && mode == O_RDONLY)
|
||||
{
|
||||
int sl;
|
||||
|
||||
sl = tTdlevel(68) - 100;
|
||||
/* XXX test checks for map type!!! */
|
||||
sm_dprintf("hash_map_open: sleep=%d\n", sl);
|
||||
sleep(sl);
|
||||
}
|
||||
# endif
|
||||
|
||||
if (mode == O_RDONLY && bitset(MF_ALIAS, map->map_mflags) &&
|
||||
!aliaswait(map, ".db", true))
|
||||
return false;
|
||||
@ -2362,11 +2547,9 @@ db_map_lookup(map, name, av, statp)
|
||||
{
|
||||
DBT key, val;
|
||||
register DB *db = (DB *) map->map_db2;
|
||||
int i;
|
||||
int st;
|
||||
int save_errno;
|
||||
int fd;
|
||||
struct stat stbuf;
|
||||
char keybuf[MAXNAME + 1]; /* EAI:ok */
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
@ -2376,18 +2559,14 @@ db_map_lookup(map, name, av, statp)
|
||||
if (tTd(38, 20))
|
||||
sm_dprintf("db_map_lookup(%s, %s)\n",
|
||||
map->map_mname, name);
|
||||
|
||||
if (sm_strlcpy(buf, map->map_file, sizeof(buf)) >= sizeof(buf))
|
||||
if (!smdb_add_extension(buf, sizeof(buf), map->map_file, "db"))
|
||||
{
|
||||
errno = 0;
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
syserr("map \"%s\": map file %s name too long",
|
||||
syserr("db map \"%s\": map file %s name too long",
|
||||
map->map_mname, map->map_file);
|
||||
return NULL;
|
||||
}
|
||||
i = strlen(buf);
|
||||
if (i > 3 && strcmp(&buf[i - 3], ".db") == 0)
|
||||
buf[i - 3] = '\0';
|
||||
|
||||
key.size = strlen(name);
|
||||
if (key.size > sizeof(keybuf) - 1)
|
||||
@ -2405,15 +2584,15 @@ db_map_lookup(map, name, av, statp)
|
||||
errno = db->fd(db, &fd);
|
||||
# endif /* DB_VERSION_MAJOR < 2 */
|
||||
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
|
||||
(void) lockfile(fd, buf, ".db", LOCK_SH);
|
||||
if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
|
||||
(void) lockfile(fd, buf, NULL, LOCK_SH);
|
||||
if (map_has_chged(map, buf, fd))
|
||||
{
|
||||
/* Reopen the database to sync the cache */
|
||||
int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
|
||||
: O_RDONLY;
|
||||
|
||||
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
|
||||
(void) lockfile(fd, buf, ".db", LOCK_UN);
|
||||
(void) lockfile(fd, buf, NULL, LOCK_UN);
|
||||
map->map_mflags |= MF_CLOSING;
|
||||
map->map_class->map_close(map);
|
||||
map->map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
|
||||
@ -2498,7 +2677,7 @@ db_map_lookup(map, name, av, statp)
|
||||
}
|
||||
save_errno = errno;
|
||||
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
|
||||
(void) lockfile(fd, buf, ".db", LOCK_UN);
|
||||
(void) lockfile(fd, buf, NULL, LOCK_UN);
|
||||
if (st != 0)
|
||||
{
|
||||
errno = save_errno;
|
||||
@ -2686,56 +2865,6 @@ db_map_close(map)
|
||||
** CDB Modules
|
||||
*/
|
||||
|
||||
static bool smdb_add_extension __P((char *, int, char *, char *));
|
||||
|
||||
/*
|
||||
** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
|
||||
**
|
||||
** Just adds a . followed by a string to a db_name if there
|
||||
** is room and the db_name does not already have that extension.
|
||||
**
|
||||
** Parameters:
|
||||
** full_name -- The final file name.
|
||||
** max_full_name_len -- The max length for full_name.
|
||||
** db_name -- The name of the db.
|
||||
** extension -- The extension to add.
|
||||
**
|
||||
** Returns:
|
||||
** SMDBE_OK -- Success.
|
||||
** Anything else is an error. Look up more info about the
|
||||
** error in the comments for the specific open() used.
|
||||
*/
|
||||
|
||||
static bool
|
||||
smdb_add_extension(full_name, max_full_name_len, db_name, extension)
|
||||
char *full_name;
|
||||
int max_full_name_len;
|
||||
char *db_name;
|
||||
char *extension;
|
||||
{
|
||||
int extension_len;
|
||||
int db_name_len;
|
||||
|
||||
if (full_name == NULL || db_name == NULL || extension == NULL)
|
||||
return false; /* SMDBE_INVALID_PARAMETER; */
|
||||
|
||||
extension_len = strlen(extension);
|
||||
db_name_len = strlen(db_name);
|
||||
|
||||
if (extension_len + db_name_len + 2 > max_full_name_len)
|
||||
return false; /* SMDBE_DB_NAME_TOO_LONG; */
|
||||
|
||||
if (db_name_len < extension_len + 1 ||
|
||||
db_name[db_name_len - extension_len - 1] != '.' ||
|
||||
strcmp(&db_name[db_name_len - extension_len], extension) != 0)
|
||||
(void) sm_snprintf(full_name, max_full_name_len, "%s.%s",
|
||||
db_name, extension);
|
||||
else
|
||||
(void) sm_strlcpy(full_name, db_name, max_full_name_len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
cdb_map_open(map, mode)
|
||||
MAP *map;
|
||||
@ -2748,8 +2877,9 @@ cdb_map_open(map, mode)
|
||||
char buf[MAXPATHLEN];
|
||||
|
||||
if (tTd(38, 2))
|
||||
sm_dprintf("cdb_map_open(%s, %s, %d)\n",
|
||||
map->map_mname, map->map_file, mode);
|
||||
sm_dprintf("cdb_map_open(%s, %s, %s)\n",
|
||||
map->map_mname, map->map_file,
|
||||
O_RDWR == (mode & O_ACCMODE) ? "rdwr" : "rdonly");
|
||||
map->map_db1 = (ARBPTR_T)NULL;
|
||||
map->map_db2 = (ARBPTR_T)NULL;
|
||||
|
||||
@ -2844,6 +2974,10 @@ cdb_map_open(map, mode)
|
||||
/* actually lock the opened file */
|
||||
if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
|
||||
syserr("cdb_map_open: cannot lock %s", buf);
|
||||
# else /* !LOCK_ON_OPEN */
|
||||
if (tTd(55, 60))
|
||||
sm_dprintf("lockopen(%s, fd=%d, action=nb, type=%s): SUCCESS\n",
|
||||
buf, fd, mode == O_RDONLY ? "rd" : "wr");
|
||||
# endif /* !LOCK_ON_OPEN */
|
||||
|
||||
map->map_lockfd = fd;
|
||||
@ -2867,8 +3001,20 @@ cdb_map_open(map, mode)
|
||||
}
|
||||
|
||||
map->map_db2 = (ARBPTR_T)cdbmp;
|
||||
mapchown(map->map_file, fd, -1, buf);
|
||||
return true;
|
||||
}
|
||||
(void) lockfile(fd, buf, NULL, LOCK_UN);
|
||||
# if _FFR_TESTS
|
||||
if (tTd(68, 101))
|
||||
{
|
||||
int sl;
|
||||
|
||||
sl = tTdlevel(68) - 100;
|
||||
sm_dprintf("cdb_map_open: sleep=%d\n", sl);
|
||||
sleep(sl);
|
||||
}
|
||||
# endif
|
||||
|
||||
cdbp = (struct cdb *) xalloc(sizeof(*cdbp));
|
||||
status = cdb_init(cdbp, fd);
|
||||
@ -2879,7 +3025,13 @@ cdb_map_open(map, mode)
|
||||
syserr("initialization of cdb map failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
map->map_db1 = (ARBPTR_T)cdbp;
|
||||
if (bitset(MF_ALIAS, map->map_mflags) && !aliaswait(map, CDBEXT, true))
|
||||
{
|
||||
close(fd); /* XXX more error handling needed? */
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2896,7 +3048,6 @@ cdb_map_lookup(map, name, av, statp)
|
||||
int st, fd;
|
||||
char key[MAXNAME + 1]; /* EAI:ok */
|
||||
char buf[MAXPATHLEN];
|
||||
struct stat stbuf;
|
||||
|
||||
data = NULL;
|
||||
cdbmap = map->map_db1;
|
||||
@ -2909,7 +3060,7 @@ cdb_map_lookup(map, name, av, statp)
|
||||
if (!bitset(MF_OPTIONAL, map->map_mflags))
|
||||
syserr("cdb map \"%s\": map file %s name too long",
|
||||
map->map_mname, map->map_file);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
klen = strlen(name);
|
||||
@ -2925,8 +3076,7 @@ cdb_map_lookup(map, name, av, statp)
|
||||
fd = map->map_lockfd;
|
||||
if (fd >= 0 && !bitset(MF_LOCKED, map->map_mflags))
|
||||
(void) lockfile(fd, buf, NULL, LOCK_SH);
|
||||
|
||||
if (fd < 0 || fstat(fd, &stbuf) < 0 || stbuf.st_mtime > map->map_mtime)
|
||||
if (map_has_chged(map, buf, fd))
|
||||
{
|
||||
/* Reopen the database to sync the cache */
|
||||
int omode = bitset(map->map_mflags, MF_WRITABLE) ? O_RDWR
|
||||
@ -3097,7 +3247,7 @@ cdb_map_close(map)
|
||||
# endif
|
||||
|
||||
/*
|
||||
** NIS_MAP_OPEN -- open DBM map
|
||||
** NIS_MAP_OPEN -- open NIS map
|
||||
*/
|
||||
|
||||
bool
|
||||
@ -4037,7 +4187,7 @@ ldapmap_lookup(map, name, av, statp)
|
||||
char *argv[SM_LDAP_ARGS];
|
||||
char keybuf[MAXKEY];
|
||||
# if SM_LDAP_ARGS != MAX_MAP_ARGS
|
||||
# ERROR "SM_LDAP_ARGS must be the same as MAX_MAP_ARGS"
|
||||
# error "SM_LDAP_ARGS must be the same as MAX_MAP_ARGS"
|
||||
# endif
|
||||
|
||||
# define AV_FREE(av) \
|
||||
|
@ -54,6 +54,10 @@ extern char *macro_map_lookup __P((MAP *, char *, char **, int *));
|
||||
|
||||
extern bool map_parseargs __P((MAP *, char *));
|
||||
|
||||
#if LDAPMAP
|
||||
extern bool ldapmap_parseargs __P((MAP *, char *));
|
||||
#endif
|
||||
|
||||
#if NDBM
|
||||
extern char *ndbm_map_lookup __P((MAP *, char *, char **, int *));
|
||||
extern void ndbm_map_store __P((MAP *, char *, char *));
|
||||
@ -68,6 +72,10 @@ extern void null_map_close __P((MAP *));
|
||||
extern char *null_map_lookup __P((MAP *, char *, char **, int *));
|
||||
extern void null_map_store __P((MAP *, char *, char *));
|
||||
|
||||
#if PH_MAP
|
||||
extern bool ph_map_parseargs __P((MAP *, char *));
|
||||
#endif
|
||||
|
||||
extern char *prog_map_lookup __P((MAP *, char *, char **, int *));
|
||||
|
||||
extern bool regex_map_init __P((MAP *, char *));
|
||||
|
@ -351,7 +351,6 @@ mci_clear(mci)
|
||||
mactabclear(&mci->mci_macro);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** MCI_GET -- get information about a particular host
|
||||
**
|
||||
@ -617,6 +616,7 @@ struct mcifbits
|
||||
};
|
||||
static struct mcifbits MciFlags[] =
|
||||
{
|
||||
{ MCIF_OCC_INCR, "OCC_INCR" },
|
||||
{ MCIF_CACHED, "CACHED" },
|
||||
{ MCIF_ESMTP, "ESMTP" },
|
||||
{ MCIF_EXPN, "EXPN" },
|
||||
@ -630,7 +630,6 @@ static struct mcifbits MciFlags[] =
|
||||
{ MCIF_CVT7TO8, "CVT7TO8" },
|
||||
{ MCIF_INMIME, "INMIME" },
|
||||
{ MCIF_AUTH, "AUTH" },
|
||||
{ MCIF_AUTH2, "AUTH2" },
|
||||
{ MCIF_AUTHACT, "AUTHACT" },
|
||||
{ MCIF_ENHSTAT, "ENHSTAT" },
|
||||
{ MCIF_PIPELINED, "PIPELINED" },
|
||||
@ -640,8 +639,16 @@ static struct mcifbits MciFlags[] =
|
||||
{ MCIF_TLSACT, "TLSACT" },
|
||||
#endif
|
||||
{ MCIF_DLVR_BY, "DLVR_BY" },
|
||||
#if _FFR_IGNORE_EXT_ON_HELO
|
||||
{ MCIF_HELO, "HELO" },
|
||||
#endif
|
||||
{ MCIF_INLONGLINE, "INLONGLINE" },
|
||||
{ MCIF_AUTH2, "AUTH2" },
|
||||
{ MCIF_ONLY_EHLO, "ONLY_EHLO" },
|
||||
{ MCIF_NOTSTICKY, "NOTSTICKY" },
|
||||
#if USE_EAI
|
||||
{ MCIF_EAI, "EAI" },
|
||||
#endif
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
@ -1200,7 +1207,7 @@ mci_traverse_persistent(action, pathname)
|
||||
struct dirent *e;
|
||||
char newpath[MAXPATHLEN];
|
||||
#if MAXPATHLEN <= MAXNAMLEN - 3
|
||||
# ERROR "MAXPATHLEN <= MAXNAMLEN - 3"
|
||||
# error "MAXPATHLEN <= MAXNAMLEN - 3"
|
||||
#endif
|
||||
|
||||
if ((d = opendir(pathname)) == NULL)
|
||||
|
@ -71,7 +71,6 @@ static void milter_delrcpt __P((char *, ssize_t, ENVELOPE *, const char *));
|
||||
static int milter_replbody __P((char *, ssize_t, bool, ENVELOPE *, const char *));
|
||||
static int milter_set_macros __P((char *, char **, char *, int));
|
||||
|
||||
|
||||
/* milter states */
|
||||
# define SMFS_CLOSED 'C' /* closed for all further actions */
|
||||
# define SMFS_OPEN 'O' /* connected to remote milter filter */
|
||||
@ -1877,6 +1876,24 @@ milter_abort_filter(m, e)
|
||||
** none
|
||||
*/
|
||||
|
||||
#if _FFR_TESTS
|
||||
# define TST_EO \
|
||||
do \
|
||||
{ \
|
||||
if (tTd(86, 100) && \
|
||||
(SMFIC_EOH == cmd || SMFIC_BODYEOB == cmd) && \
|
||||
strncmp(macros[i], "{EO", 3) == 0) \
|
||||
{ \
|
||||
if (SMFIC_EOH == cmd) \
|
||||
v = "at_EOH"; \
|
||||
else if (SMFIC_BODYEOB == cmd) \
|
||||
v = "at_EOM"; \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
# define TST_EO ((void) 0)
|
||||
#endif
|
||||
|
||||
static void
|
||||
milter_send_macros(m, macros, cmd, e)
|
||||
struct milter *m;
|
||||
@ -1904,6 +1921,7 @@ milter_send_macros(m, macros, cmd, e)
|
||||
if (mid == 0)
|
||||
continue;
|
||||
v = macvalue(mid, e);
|
||||
TST_EO;
|
||||
if (v == NULL)
|
||||
continue;
|
||||
expand(v, exp, sizeof(exp), e);
|
||||
@ -1928,6 +1946,7 @@ milter_send_macros(m, macros, cmd, e)
|
||||
if (mid == 0)
|
||||
continue;
|
||||
v = macvalue(mid, e);
|
||||
TST_EO;
|
||||
if (v == NULL)
|
||||
continue;
|
||||
expand(v, exp, sizeof(exp), e);
|
||||
@ -2289,7 +2308,7 @@ milter_command(cmd, data, sz, stage, e, state, where, cmd_error)
|
||||
/* log the time it took for the command per filter */
|
||||
sm_syslog(LOG_INFO, e->e_id,
|
||||
"Milter (%s): time command (%c), %d",
|
||||
m->mf_name, command, (int) (tn - curtime()));
|
||||
m->mf_name, command, (int) (curtime() - tn));
|
||||
}
|
||||
|
||||
if (*state != SMFIR_CONTINUE)
|
||||
@ -3329,9 +3348,9 @@ milter_changeheader(m, response, rlen, e)
|
||||
** MILTER_SPLIT_RESPONSE -- Split response into fields.
|
||||
**
|
||||
** Parameters:
|
||||
** response -- encoded repsonse.
|
||||
** response -- encoded response.
|
||||
** rlen -- length of response.
|
||||
** pargc -- number of arguments (ouput)
|
||||
** pargc -- number of arguments (output)
|
||||
**
|
||||
** Returns:
|
||||
** array of pointers to the individual strings
|
||||
|
@ -347,7 +347,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
|
||||
goto writeerr;
|
||||
if (tTd(43, 35))
|
||||
sm_dprintf(" ...%s\n", buf);
|
||||
collect(e->e_dfp, false, &hdr, e, false);
|
||||
collect(e->e_dfp, SMTPMODE_NO, &hdr, e, false);
|
||||
if (tTd(43, 101))
|
||||
putline("+++after collect", mci);
|
||||
if (!putheader(mci, hdr, e, flags))
|
||||
@ -409,7 +409,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
|
||||
goto writeerr;
|
||||
|
||||
mci->mci_flags |= MCIF_INMIME;
|
||||
collect(e->e_dfp, false, &hdr, e, false);
|
||||
collect(e->e_dfp, SMTPMODE_NO, &hdr, e, false);
|
||||
if (tTd(43, 101))
|
||||
putline("+++after collect", mci);
|
||||
if (!putheader(mci, hdr, e, flags))
|
||||
@ -483,7 +483,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
|
||||
** If more than 1/8 of the total characters have the
|
||||
** eighth bit set, use base64; else use quoted-printable.
|
||||
** However, only encode binary encoded data as base64,
|
||||
** since otherwise the NL=>CRLF mapping will be a problem.
|
||||
** since otherwise the LF=>CRLF mapping will be a problem.
|
||||
*/
|
||||
|
||||
if (tTd(43, 8))
|
||||
@ -837,7 +837,7 @@ mime_getchar(fp, boundaries, btp)
|
||||
return *bp++;
|
||||
}
|
||||
/*
|
||||
** MIME_GETCHAR_CRLF -- do mime_getchar, but translate NL => CRLF
|
||||
** MIME_GETCHAR_CRLF -- do mime_getchar, but translate LF => CRLF
|
||||
**
|
||||
** Parameters:
|
||||
** fp -- the input file.
|
||||
|
@ -89,7 +89,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
|
||||
#if _FFR_8BITENVADDR
|
||||
if (bitset(RF_IS_EXT, flags) && addr != NULL)
|
||||
{
|
||||
int len = 0;
|
||||
int len;
|
||||
|
||||
addr = quote_internal_chars(addr, NULL, &len, NULL);
|
||||
}
|
||||
@ -155,8 +155,9 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
|
||||
|
||||
a = buildaddr(pvp, a, flags, e);
|
||||
#if _FFR_8BITENVADDR
|
||||
if (NULL != a->q_user)
|
||||
{
|
||||
int len = 0;
|
||||
int len;
|
||||
|
||||
a->q_user = quote_internal_chars(a->q_user, NULL, &len, e->e_rpool); /* EAI: ok */
|
||||
}
|
||||
@ -267,7 +268,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
|
||||
** isrcpt -- true iff the address is for a recipient.
|
||||
**
|
||||
** Returns:
|
||||
** true -- if the address has characters that are reservered
|
||||
** true -- if the address has characters that are reserved
|
||||
** for macros or is too long.
|
||||
** false -- otherwise.
|
||||
*/
|
||||
@ -398,7 +399,7 @@ hasctrlchar(addr, isrcpt, complain)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!SMTPUTF8 && !EightBitAddrOK && (*addr & 0340) == 0200)
|
||||
if (!SMTP_UTF8 && !EightBitAddrOK && (*addr & 0340) == 0200)
|
||||
{
|
||||
setstat(EX_USAGE);
|
||||
result = "8-bit character";
|
||||
@ -447,7 +448,7 @@ allocaddr(a, flags, paddr, e)
|
||||
ENVELOPE *e;
|
||||
{
|
||||
if (tTd(24, 4))
|
||||
sm_dprintf("allocaddr(flags=%x, paddr=%s, ad=%d)\n", flags, paddr, bitset(EF_SECURE, e->e_flags));
|
||||
sm_dprintf("allocaddr: flags=%x, paddr=%s, ad=%d\n", flags, paddr, bitset(EF_SECURE, e->e_flags));
|
||||
|
||||
a->q_paddr = paddr;
|
||||
|
||||
@ -688,7 +689,6 @@ unsigned char TokTypeNoC[256] =
|
||||
ATM,ATM,ATM,ATM,ATM,ATM,ATM,ATM, ATM,ATM,ATM,ATM,ATM,ATM,ATM,ONE
|
||||
};
|
||||
|
||||
|
||||
#define NOCHAR (-1) /* signal nothing in lookahead token */
|
||||
|
||||
char **
|
||||
@ -2015,6 +2015,9 @@ buildaddr(tv, a, flags, e)
|
||||
char **hostp;
|
||||
char hbuf[MAXNAME + 1]; /* EAI:ok */
|
||||
static char ubuf[MAXNAME_I + 2];
|
||||
#if _FFR_8BITENVADDR
|
||||
int len;
|
||||
#endif
|
||||
|
||||
if (tTd(24, 5))
|
||||
{
|
||||
@ -2211,7 +2214,12 @@ buildaddr(tv, a, flags, e)
|
||||
}
|
||||
|
||||
/* rewrite according recipient mailer rewriting rules */
|
||||
macdefine(&e->e_macro, A_PERM, 'h', a->q_host);
|
||||
#if _FFR_8BITENVADDR
|
||||
p = quote_internal_chars(a->q_host, NULL, &len, NULL);
|
||||
#else
|
||||
p = a->q_host;
|
||||
#endif
|
||||
macdefine(&e->e_macro, A_PERM, 'h', p);
|
||||
|
||||
if (ConfigLevel >= 10 ||
|
||||
!bitset(RF_SENDERADDR|RF_HEADERADDR, flags))
|
||||
@ -2477,7 +2485,6 @@ static struct qflags AddressFlags[] =
|
||||
{ "QEXPANDED", QEXPANDED },
|
||||
{ "QDELIVERED", QDELIVERED },
|
||||
{ "QDELAYED", QDELAYED },
|
||||
{ "QTHISPASS", QTHISPASS },
|
||||
{ "QALIAS", QALIAS },
|
||||
{ "QBYTRACE", QBYTRACE },
|
||||
{ "QBYNDELAY", QBYNDELAY },
|
||||
@ -2485,9 +2492,11 @@ static struct qflags AddressFlags[] =
|
||||
{ "QINTBCC", QINTBCC },
|
||||
{ "QDYNMAILER", QDYNMAILER },
|
||||
{ "QSECURE", QSECURE },
|
||||
{ "QQUEUED", QQUEUED },
|
||||
{ "QINTREPLY", QINTREPLY },
|
||||
{ "QMXSECURE", QMXSECURE },
|
||||
{ "QTHISPASS", QTHISPASS },
|
||||
{ "QRCPTOK", QRCPTOK },
|
||||
{ "QQUEUED", QQUEUED },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
@ -2880,7 +2889,11 @@ maplocaluser(a, sendq, aliaslevel, e)
|
||||
{
|
||||
register char **pvp;
|
||||
register ADDRESS *SM_NONVOLATILE a1 = NULL;
|
||||
char *p;
|
||||
char pvpbuf[PSBUFSIZE];
|
||||
#if _FFR_8BITENVADDR
|
||||
int len;
|
||||
#endif
|
||||
|
||||
if (tTd(29, 1))
|
||||
{
|
||||
@ -2897,7 +2910,12 @@ maplocaluser(a, sendq, aliaslevel, e)
|
||||
return;
|
||||
}
|
||||
|
||||
macdefine(&e->e_macro, A_PERM, 'h', a->q_host);
|
||||
#if _FFR_8BITENVADDR
|
||||
p = quote_internal_chars(a->q_host, NULL, &len, NULL);
|
||||
#else
|
||||
p = a->q_host;
|
||||
#endif
|
||||
macdefine(&e->e_macro, A_PERM, 'h', p);
|
||||
macdefine(&e->e_macro, A_PERM, 'u', a->q_user);
|
||||
macdefine(&e->e_macro, A_PERM, 'z', a->q_home);
|
||||
|
||||
@ -3321,8 +3339,10 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr, addrstr)
|
||||
rwset, p1, lbuf, ubuf);
|
||||
else
|
||||
sm_syslog(LOG_NOTICE, logid,
|
||||
"ruleset=%s, arg1=%s%s, reject=%s",
|
||||
rwset, p1, lbuf, MsgBuf);
|
||||
"ruleset=%s, arg1=%s%s, %s=%s",
|
||||
rwset, p1, lbuf,
|
||||
bitset(RSF_STATUS, flags) ? "status" : "reject",
|
||||
MsgBuf);
|
||||
}
|
||||
|
||||
finis: ;
|
||||
|
@ -21,6 +21,9 @@ SM_RCSID("@(#)$Id: queue.c,v 8.1000 2013-11-22 20:51:56 ca Exp $")
|
||||
#if _FFR_DMTRIGGER
|
||||
# include <sm/notify.h>
|
||||
#endif
|
||||
#if USE_EAI
|
||||
# include <sm/ixlen.h>
|
||||
#endif
|
||||
|
||||
#define RELEASE_QUEUE (void) 0
|
||||
#define ST_INODE(st) (st).st_ino
|
||||
@ -295,7 +298,6 @@ hash_q(p, h)
|
||||
#define FILE_SYS_BLKSIZE(i) FILE_SYS(i).fs_blksize
|
||||
#define FILE_SYS_DEV(i) FILE_SYS(i).fs_dev
|
||||
|
||||
|
||||
/*
|
||||
** Current qf file field assignments:
|
||||
**
|
||||
@ -744,6 +746,8 @@ queueup(e, flags)
|
||||
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'D');
|
||||
if (bitset(QINTBCC, q->q_flags))
|
||||
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'B');
|
||||
if (bitset(QMXSECURE, q->q_flags))
|
||||
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'X');
|
||||
if (q->q_alias != NULL &&
|
||||
bitset(QALIAS, q->q_alias->q_flags))
|
||||
(void) sm_io_putc(tfp, SM_TIME_DEFAULT, 'A');
|
||||
@ -1637,7 +1641,6 @@ runqueue(forkflag, verbose, persistent, runall)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if SM_HEAP_CHECK
|
||||
if (sm_debug_active(&DebugLeakQ, 1))
|
||||
sm_heap_setgroup(oldgroup);
|
||||
@ -1698,7 +1701,7 @@ skip_domains(skip)
|
||||
/*
|
||||
** RUNNER_WORK -- have a queue runner do its work
|
||||
**
|
||||
** Have a queue runner do its work a list of entries.
|
||||
** Have a queue runner do its work on a list of entries (WorkQ).
|
||||
** When work isn't directly being done then this process can take a signal
|
||||
** and terminate immediately (in a clean fashion of course).
|
||||
** When work is directly being done, it's not to be interrupted
|
||||
@ -2525,7 +2528,7 @@ runqueueevent(ignore)
|
||||
** full -- (optional) to be set 'true' if WorkList is full
|
||||
** more -- (optional) to be set 'true' if there are still more
|
||||
** messages in this queue not added to WorkList
|
||||
** pnentries -- (optional) total nuber of entries in queue
|
||||
** pnentries -- (optional) total number of entries in queue
|
||||
**
|
||||
** Returns:
|
||||
** The number of request in the queue (not necessarily
|
||||
@ -3708,6 +3711,7 @@ dowork(qgrp, qdir, id, forkflag, requeueflag, e)
|
||||
else
|
||||
{
|
||||
pid = 0;
|
||||
maps_reset_chged("dowork");
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
@ -3947,6 +3951,7 @@ doworklist(el, forkflag, requeueflag)
|
||||
ei->e_quarmsg != NULL)
|
||||
continue;
|
||||
|
||||
maps_reset_chged("doworklist");
|
||||
rpool = sm_rpool_new_x(NULL);
|
||||
clearenvelope(&e, true, rpool);
|
||||
e.e_flags |= EF_QUEUERUN|EF_GLOBALERRS;
|
||||
@ -4509,6 +4514,10 @@ readqf(e, openonly)
|
||||
qflags |= QINTBCC;
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
qflags |= QMXSECURE;
|
||||
break;
|
||||
|
||||
case QDYNMAILFLG:
|
||||
qflags |= QDYNMAILER;
|
||||
break;
|
||||
@ -4887,6 +4896,28 @@ printqueue()
|
||||
** Prints a listing of the mail queue on the standard output.
|
||||
*/
|
||||
|
||||
#if USE_EAI
|
||||
# define PRINTADDR(addr, len) \
|
||||
do \
|
||||
{ \
|
||||
if (smtputf8) \
|
||||
{ \
|
||||
char xbuf[MAXNAME]; \
|
||||
(void) dequote_internal_chars(addr, xbuf, sizeof(xbuf));\
|
||||
if (utf8_valid(xbuf, strlen(xbuf))) \
|
||||
{ \
|
||||
(void) sm_io_fprintf(smioout, \
|
||||
SM_TIME_DEFAULT, \
|
||||
"%.*s ", len, xbuf); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
prtstr(addr, len); \
|
||||
} while (0)
|
||||
#else
|
||||
# define PRINTADDR(addr, len) prtstr(addr, len)
|
||||
#endif /* USE_EAI */
|
||||
|
||||
int
|
||||
print_single_queue(qgrp, qdir)
|
||||
int qgrp;
|
||||
@ -4998,6 +5029,9 @@ print_single_queue(qgrp, qdir)
|
||||
char statmsg[MAXLINE];
|
||||
char bodytype[MAXNAME + 1]; /* EAI:ok */
|
||||
char qf[MAXPATHLEN];
|
||||
#if USE_EAI
|
||||
bool smtputf8 = false;
|
||||
#endif
|
||||
|
||||
if (StopRequest)
|
||||
stop_sendmail();
|
||||
@ -5114,7 +5148,7 @@ print_single_queue(qgrp, qdir)
|
||||
bitset(EF_WARNING, flags)
|
||||
? '+' : ' ',
|
||||
ctime(&submittime) + 4);
|
||||
prtstr(&buf[1], 78);
|
||||
PRINTADDR(buf+1, 78);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5123,7 +5157,7 @@ print_single_queue(qgrp, qdir)
|
||||
"%8ld %.16s ",
|
||||
dfsize,
|
||||
ctime(&submittime));
|
||||
prtstr(&buf[1], 39);
|
||||
PRINTADDR(buf+1, 39);
|
||||
}
|
||||
|
||||
if (quarmsg[0] != '\0')
|
||||
@ -5174,14 +5208,14 @@ print_single_queue(qgrp, qdir)
|
||||
(void) sm_io_fprintf(smioout,
|
||||
SM_TIME_DEFAULT,
|
||||
"\n\t\t\t\t\t\t");
|
||||
prtstr(p, 71);
|
||||
PRINTADDR(p, 71);
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) sm_io_fprintf(smioout,
|
||||
SM_TIME_DEFAULT,
|
||||
"\n\t\t\t\t\t ");
|
||||
prtstr(p, 38);
|
||||
PRINTADDR(p, 38);
|
||||
}
|
||||
if (Verbose && statmsg[0] != '\0')
|
||||
{
|
||||
@ -5202,6 +5236,11 @@ print_single_queue(qgrp, qdir)
|
||||
{
|
||||
switch (*p)
|
||||
{
|
||||
#if USE_EAI
|
||||
case 'e':
|
||||
smtputf8 = true;
|
||||
break;
|
||||
#endif /* USE_EAI */
|
||||
case 'w':
|
||||
flags |= EF_WARNING;
|
||||
break;
|
||||
@ -5593,7 +5632,6 @@ unlockqueue(e)
|
||||
sm_dprintf("unlockqueue(%s)\n",
|
||||
e->e_id == NULL ? "NOQUEUE" : e->e_id);
|
||||
|
||||
|
||||
/* if there is a lock file in the envelope, close it */
|
||||
SM_CLOSE_FP(e->e_lockfp);
|
||||
|
||||
@ -5840,7 +5878,7 @@ qid_printqueue(qgrp, qdir)
|
||||
** fsize -- file size in bytes
|
||||
** e -- envelope, or NULL
|
||||
**
|
||||
** Result:
|
||||
** Returns:
|
||||
** NOQDIR if no queue directory in qg has enough free space to
|
||||
** hold a file of size 'fsize', otherwise the index of
|
||||
** a randomly selected queue directory which resides on a
|
||||
@ -6351,7 +6389,6 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
|
||||
qg->qg_qpaths[qg->qg_numqueues].qp_subdirs |= flag; \
|
||||
else
|
||||
|
||||
|
||||
CHKRSUBDIR("qf", QP_SUBQF);
|
||||
CHKRSUBDIR("df", QP_SUBDF);
|
||||
CHKRSUBDIR("xf", QP_SUBXF);
|
||||
@ -7233,7 +7270,6 @@ init_shm(qn, owner, hash)
|
||||
}
|
||||
#endif /* SM_CONF_SHM */
|
||||
|
||||
|
||||
/*
|
||||
** SETUP_QUEUES -- set up all queue groups
|
||||
**
|
||||
@ -7333,7 +7369,6 @@ setup_queues(owner)
|
||||
for (i = 0; i < NumQueue && Queue[i] != NULL; i++)
|
||||
Queue[i]->qg_nextrun = now;
|
||||
|
||||
|
||||
if (UseMSP && OpMode != MD_TEST)
|
||||
{
|
||||
long sff = SFF_CREAT;
|
||||
@ -8017,7 +8052,7 @@ makeworkgroups()
|
||||
** old -- old envelope.
|
||||
** new -- new envelope.
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** Returns true on success, false on failure.
|
||||
**
|
||||
** Side Effects:
|
||||
@ -8119,7 +8154,7 @@ dup_df(old, new)
|
||||
** qgrp -- index of queue group.
|
||||
** qdir -- queue directory.
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** new envelope.
|
||||
**
|
||||
*/
|
||||
@ -8190,7 +8225,7 @@ split_env(e, sendqueue, qgrp, qdir)
|
||||
** Parameters:
|
||||
** e -- envelope.
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** SM_SPLIT_FAIL on failure
|
||||
** SM_SPLIT_NONE if no splitting occurred,
|
||||
** or 1 + the number of additional envelopes created.
|
||||
@ -8413,7 +8448,7 @@ split_across_queue_groups(e)
|
||||
** Parameters:
|
||||
** e -- envelope.
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** SM_SPLIT_FAIL on failure
|
||||
** SM_SPLIT_NONE if no splitting occurred,
|
||||
** or 1 + the number of additional envelopes created.
|
||||
@ -8605,7 +8640,7 @@ split_within_queue(e)
|
||||
** Parameters:
|
||||
** e -- envelope.
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** Returns true on success, false on failure.
|
||||
**
|
||||
** Side Effects:
|
||||
@ -8703,7 +8738,7 @@ split_by_recipient(e)
|
||||
** e -- envelope information for the item
|
||||
** reason -- quarantine reason, NULL means unquarantine.
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** true if item changed, false otherwise
|
||||
**
|
||||
** Side Effects:
|
||||
@ -8936,7 +8971,6 @@ quarantine_queue_item(qgrp, qdir, e, reason)
|
||||
failing = true;
|
||||
}
|
||||
|
||||
|
||||
/* Figure out the new filename */
|
||||
newtype = (reason == NULL ? NORMQF_LETTER : QUARQF_LETTER);
|
||||
if (oldtype == newtype)
|
||||
@ -9062,7 +9096,7 @@ quarantine_queue_item(qgrp, qdir, e, reason)
|
||||
** reason -- quarantine reason, "." means unquarantine.
|
||||
** qgrplimit -- limit to single queue group unless NOQGRP
|
||||
**
|
||||
** Results:
|
||||
** Returns:
|
||||
** none.
|
||||
**
|
||||
** Side Effects:
|
||||
@ -9169,141 +9203,3 @@ quarantine_queue(reason, qgrplimit)
|
||||
changed == 1 ? "" : "s");
|
||||
}
|
||||
}
|
||||
|
||||
#if _FFR_DMTRIGGER
|
||||
/*
|
||||
** QM -- queue "manager"
|
||||
**
|
||||
** Parameters:
|
||||
** none.
|
||||
**
|
||||
** Results:
|
||||
** false on error
|
||||
**
|
||||
** Side Effects:
|
||||
** fork()s and runs as process to deliver queue entries
|
||||
*/
|
||||
|
||||
bool
|
||||
qm()
|
||||
{
|
||||
int r;
|
||||
pid_t pid;
|
||||
long tmo;
|
||||
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: start");
|
||||
|
||||
(void) sm_blocksignal(SIGCHLD);
|
||||
(void) sm_signal(SIGCHLD, reapchild);
|
||||
|
||||
pid = dofork();
|
||||
if (pid == -1)
|
||||
{
|
||||
const char *msg = "queue manager -- fork() failed";
|
||||
const char *err = sm_errstring(errno);
|
||||
|
||||
if (LogLevel > 8)
|
||||
sm_syslog(LOG_INFO, NOQID, "%s: %s",
|
||||
msg, err);
|
||||
(void) sm_releasesignal(SIGCHLD);
|
||||
return false;
|
||||
}
|
||||
if (pid != 0)
|
||||
{
|
||||
/* parent -- pick up intermediate zombie */
|
||||
(void) sm_releasesignal(SIGCHLD);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* XXX put this into a macro/function because it is used several times? */
|
||||
/* child -- clean up signals */
|
||||
|
||||
/* Reset global flags */
|
||||
RestartRequest = NULL;
|
||||
RestartWorkGroup = false;
|
||||
ShutdownRequest = NULL;
|
||||
PendingSignal = 0;
|
||||
CurrentPid = getpid();
|
||||
close_sendmail_pid();
|
||||
|
||||
/*
|
||||
** Initialize exception stack and default exception
|
||||
** handler for child process.
|
||||
*/
|
||||
|
||||
sm_exc_newthread(fatal_error);
|
||||
clrcontrol();
|
||||
proc_list_clear();
|
||||
|
||||
/* Add parent process as first child item */
|
||||
proc_list_add(CurrentPid, "Queue manager", PROC_QM, 0, -1, NULL);
|
||||
(void) sm_releasesignal(SIGCHLD);
|
||||
(void) sm_signal(SIGCHLD, SIG_DFL);
|
||||
(void) sm_signal(SIGHUP, SIG_DFL);
|
||||
(void) sm_signal(SIGTERM, intsig);
|
||||
|
||||
/* drop privileges */
|
||||
if (geteuid() == (uid_t) 0)
|
||||
(void) drop_privileges(false);
|
||||
disconnect(1, NULL);
|
||||
QuickAbort = false;
|
||||
|
||||
r = sm_notify_start(true, 0);
|
||||
if (r != 0)
|
||||
syserr("sm_notify_start() failed=%d", r);
|
||||
|
||||
/*
|
||||
** Initially wait indefinitely, then only wait
|
||||
** until something needs to get done (not yet implemented).
|
||||
*/
|
||||
|
||||
tmo = -1;
|
||||
while (true)
|
||||
{
|
||||
char buf[64];
|
||||
ENVELOPE *e;
|
||||
SM_RPOOL_T *rpool;
|
||||
|
||||
/*
|
||||
** TODO: This should try to receive multiple ids:
|
||||
** after it got one, check for more with a very short timeout
|
||||
** and collect them in a list.
|
||||
** but them some other code should be used to run all of them.
|
||||
*/
|
||||
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=start");
|
||||
r = sm_notify_rcv(buf, sizeof(buf), tmo);
|
||||
if (-ETIMEDOUT == r)
|
||||
{
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=timed_out");
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
{
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=%d", r);
|
||||
goto end;
|
||||
}
|
||||
if (r > 0 && r < sizeof(buf))
|
||||
buf[r] = '\0';
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: got=%s", buf);
|
||||
CurEnv = &QueueEnvelope;
|
||||
rpool = sm_rpool_new_x(NULL);
|
||||
e = newenvelope(&QueueEnvelope, CurEnv, rpool);
|
||||
e->e_flags = BlankEnvelope.e_flags;
|
||||
e->e_parent = NULL;
|
||||
r = sm_io_sscanf(buf, "N:%d:%d:%s", &e->e_qgrp, &e->e_qdir, e->e_id);
|
||||
if (r != 3)
|
||||
{
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: buf=%s, scan=%d", buf, r);
|
||||
goto end;
|
||||
}
|
||||
dowork(e->e_qgrp, e->e_qdir, e->e_id, true, false, e);
|
||||
}
|
||||
|
||||
end:
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: stop");
|
||||
finis(false, false, EX_OK);
|
||||
return false;
|
||||
}
|
||||
#endif /* _FFR_DMTRIGGER */
|
||||
|
@ -228,7 +228,7 @@ gen_hash(saddr)
|
||||
}
|
||||
}
|
||||
#else /* HASH_ALG == 1 */
|
||||
# ERROR "unsupported HASH_ALG"
|
||||
# error "unsupported HASH_ALG"
|
||||
hv = ((hv << 1) ^ (*p & 0377)) % cctx->cc_size; ???
|
||||
#endif /* HASH_ALG == 1 */
|
||||
|
||||
@ -419,7 +419,6 @@ conn_limits(e, now, saddr, clflags, hashary, ratelimit, conclimit)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if RATECTL_DEBUG
|
||||
logit = true;
|
||||
#endif
|
||||
|
@ -16,8 +16,8 @@
|
||||
#if STARTTLS
|
||||
# include <tls.h>
|
||||
#endif
|
||||
#if DNSSEC_TEST
|
||||
# include <sm_resolve.h>
|
||||
#if DNSSEC_TEST || _FFR_NAMESERVER
|
||||
# include "sm_resolve.h"
|
||||
#endif
|
||||
|
||||
SM_RCSID("@(#)$Id: readcf.c,v 8.692 2013-11-22 20:51:56 ca Exp $")
|
||||
@ -33,12 +33,18 @@ SM_RCSID("@(#)$Id: readcf.c,v 8.692 2013-11-22 20:51:56 ca Exp $")
|
||||
#define HOURS HOUR
|
||||
|
||||
static void fileclass __P((int, char *, char *, bool, bool, bool));
|
||||
#if _FFR_DYN_CLASS
|
||||
static void dynclass __P((int, char *));
|
||||
#endif
|
||||
static char **makeargv __P((char *));
|
||||
static void settimeout __P((char *, char *, bool));
|
||||
static void toomany __P((int, int));
|
||||
static char *extrquotstr __P((char *, char **, char *, bool *));
|
||||
static void parse_class_words __P((int, char *));
|
||||
|
||||
#if _FFR_CLASS_RM_ENTRY
|
||||
static void classrmentry __P((int, char *));
|
||||
#endif
|
||||
|
||||
#if _FFR_BOUNCE_QUEUE
|
||||
static char *bouncequeue = NULL;
|
||||
@ -161,6 +167,11 @@ readcf(cfname, safe, e)
|
||||
char pvpbuf[MAXLINE + MAXATOM];
|
||||
static char *null_list[1] = { NULL };
|
||||
extern unsigned char TokTypeNoC[];
|
||||
#if _FFR_CLASS_RM_ENTRY
|
||||
int off;
|
||||
#else
|
||||
# define off 1
|
||||
#endif
|
||||
|
||||
FileName = cfname;
|
||||
LineNumber = 0;
|
||||
@ -463,7 +474,6 @@ readcf(cfname, safe, e)
|
||||
endtoken = 0;
|
||||
break;
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** This doesn't work yet as there are maps defined *after* the cf
|
||||
@ -534,12 +544,12 @@ readcf(cfname, safe, e)
|
||||
if (mid == 0)
|
||||
break;
|
||||
#if USE_EAI && 0
|
||||
if ('j' == mid && !addr_is_ascii(ep))
|
||||
{
|
||||
usrerr("hostname %s must be ASCII", ep);
|
||||
finis(false, true, EX_CONFIG);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
// if ('j' == mid && !addr_is_ascii(ep))
|
||||
// {
|
||||
// usrerr("hostname %s must be ASCII", ep);
|
||||
// finis(false, true, EX_CONFIG);
|
||||
// /* NOTREACHED */
|
||||
// }
|
||||
#endif
|
||||
p = munchstring(ep, NULL, '\0');
|
||||
macdefine(&e->e_macro, A_TEMP, mid, p);
|
||||
@ -551,9 +561,15 @@ readcf(cfname, safe, e)
|
||||
|
||||
case 'C': /* word class */
|
||||
case 'T': /* trusted user (set class `t') */
|
||||
#if _FFR_CLASS_RM_ENTRY
|
||||
if (bp[0] != '\0' && bp[1] == '-')
|
||||
off = 2;
|
||||
else
|
||||
off = 1;
|
||||
#endif
|
||||
if (bp[0] == 'C')
|
||||
{
|
||||
mid = macid_parse(&bp[1], &ep);
|
||||
mid = macid_parse(&bp[off], &ep);
|
||||
if (mid == 0)
|
||||
break;
|
||||
expand(ep, exbuf, sizeof(exbuf), e);
|
||||
@ -565,7 +581,7 @@ readcf(cfname, safe, e)
|
||||
else
|
||||
{
|
||||
mid = 't';
|
||||
p = &bp[1];
|
||||
p = &bp[off];
|
||||
}
|
||||
while (*p != '\0')
|
||||
{
|
||||
@ -580,11 +596,29 @@ readcf(cfname, safe, e)
|
||||
delim = *p;
|
||||
*p = '\0';
|
||||
if (wd[0] != '\0')
|
||||
setclass(mid, wd);
|
||||
{
|
||||
if (off < 2)
|
||||
setclass(mid, wd);
|
||||
#if _FFR_CLASS_RM_ENTRY
|
||||
else
|
||||
classrmentry(mid, wd);
|
||||
#endif /* _FFR_CLASS_RM_ENTRY */
|
||||
}
|
||||
*p = delim;
|
||||
}
|
||||
break;
|
||||
|
||||
#if _FFR_DYN_CLASS
|
||||
case 'A': /* dynamic class */
|
||||
mid = macid_parse(&bp[1], &ep);
|
||||
if (mid == 0)
|
||||
break;
|
||||
for (p = ep; SM_ISSPACE(*p); )
|
||||
p++;
|
||||
dynclass(mid, p);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'F': /* word class from file */
|
||||
mid = macid_parse(&bp[1], &ep);
|
||||
if (mid == 0)
|
||||
@ -940,11 +974,11 @@ toomany(id, maxcnt)
|
||||
syserr("too many %c lines, %d max", id, maxcnt);
|
||||
}
|
||||
/*
|
||||
** FILECLASS -- read members of a class from a file
|
||||
** FILECLASS -- read members of a class from a file, program, or map
|
||||
**
|
||||
** Parameters:
|
||||
** class -- class to define.
|
||||
** filename -- name of file to read.
|
||||
** filename -- name of file to read/specification of map and key.
|
||||
** fmt -- scanf string to use for match.
|
||||
** ismap -- if set, this is a map lookup.
|
||||
** safe -- if set, this is a safe read.
|
||||
@ -955,8 +989,10 @@ toomany(id, maxcnt)
|
||||
** none
|
||||
**
|
||||
** Side Effects:
|
||||
** puts all lines in filename that match a scanf into
|
||||
** the named class.
|
||||
** puts all entries retrieved from a file, program, or map
|
||||
** into the named class:
|
||||
** - file or |prg: all words in lines that match a scanf fmt
|
||||
** - map: all words in value (rhs) of a map lookup of a key
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -1109,7 +1145,6 @@ fileclass(class, filename, fmt, ismap, safe, optional)
|
||||
sm_dprintf("fileclass: F{%s}: map class %s, key %s, spec %s\n",
|
||||
mn, cl, key, spec);
|
||||
|
||||
|
||||
/* parse map spec */
|
||||
if (!map.map_class->map_parse(&map, spec))
|
||||
{
|
||||
@ -1229,6 +1264,124 @@ fileclass(class, filename, fmt, ismap, safe, optional)
|
||||
(void) waitfor(pid);
|
||||
}
|
||||
|
||||
#if _FFR_DYN_CLASS
|
||||
|
||||
/*
|
||||
** DYNCLASS -- open a dynamic class
|
||||
**
|
||||
** Parameters:
|
||||
** class -- class to define.
|
||||
** arg -- rest of class definition from cf.
|
||||
**
|
||||
** Returns:
|
||||
** none
|
||||
*/
|
||||
|
||||
static void
|
||||
dynclass(class, arg)
|
||||
int class;
|
||||
char *arg;
|
||||
{
|
||||
char *p;
|
||||
char *tag;
|
||||
char *mn;
|
||||
char *maptype, *spec;
|
||||
STAB *mapclass, *dynmap;
|
||||
|
||||
mn = newstr(macname(class));
|
||||
if (*arg == '\0')
|
||||
{
|
||||
syserr("dynamic class: A{%s}: missing class definition", mn);
|
||||
return;
|
||||
}
|
||||
tag = arg;
|
||||
dynmap = stab(mn, ST_DYNMAP, ST_FIND);
|
||||
if (NULL != dynmap)
|
||||
{
|
||||
syserr("dynamic class: A{%s}: already defined", mn);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* skip past tag */
|
||||
if ((p = strchr(arg, '@')) == NULL)
|
||||
{
|
||||
/* should not happen */
|
||||
syserr("dynamic class: A{%s}: bogus map specification", mn);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* skip past '@' */
|
||||
*p++ = '\0';
|
||||
maptype = p;
|
||||
|
||||
if ((spec = strchr(maptype, ':')) == NULL)
|
||||
{
|
||||
syserr("dynamic class: A{%s}: missing map class", mn);
|
||||
goto error;
|
||||
}
|
||||
*spec++ ='\0';
|
||||
|
||||
/* set up map structure */
|
||||
mapclass = stab(maptype, ST_MAPCLASS, ST_FIND);
|
||||
if (NULL == mapclass)
|
||||
{
|
||||
syserr("dynamic class: A{%s}: map type %s not available",
|
||||
mn, maptype);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tTd(37, 5))
|
||||
sm_dprintf("dynamic class: A{%s}: type='%s', tag='%s', spec='%s'\n",
|
||||
mn, maptype, tag, spec);
|
||||
|
||||
/* enter map in stab */
|
||||
dynmap = stab(mn, ST_DYNMAP, ST_ENTER);
|
||||
if (NULL == dynmap)
|
||||
{
|
||||
syserr("dynamic class: A{%s}: cannot enter", mn);
|
||||
goto error2;
|
||||
}
|
||||
dynmap->s_dynclass.map_class = &mapclass->s_mapclass;
|
||||
dynmap->s_dynclass.map_mname = newstr(mn);
|
||||
|
||||
/* parse map spec */
|
||||
if (!dynmap->s_dynclass.map_class->map_parse(&dynmap->s_dynclass, spec))
|
||||
{
|
||||
/* map_parse() showed the error already */
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* open map */
|
||||
if (dynmap->s_dynclass.map_class->map_open(&dynmap->s_dynclass, O_RDONLY))
|
||||
{
|
||||
dynmap->s_dynclass.map_mflags |= MF_OPEN;
|
||||
dynmap->s_dynclass.map_pid = getpid();
|
||||
}
|
||||
else
|
||||
{
|
||||
syserr("dynamic class: A{%s}: map open failed", mn);
|
||||
goto error;
|
||||
}
|
||||
dynmap->s_dynclass.map_mflags |= MF_VALID;
|
||||
dynmap->s_dynclass.map_tag = newstr(tag);
|
||||
|
||||
#if 0
|
||||
/* close map: where to do this? */
|
||||
dynmap->s_dynclass.map_mflags |= MF_CLOSING;
|
||||
dynmap->s_dynclass.map_class->map_close(&map);
|
||||
dynmap->s_dynclass.map_mflags &= ~(MF_OPEN|MF_WRITABLE|MF_CLOSING);
|
||||
#endif
|
||||
sm_free(mn);
|
||||
return;
|
||||
|
||||
error:
|
||||
dynmap->s_dynclass.map_mflags |= MF_OPENBOGUS;
|
||||
error2:
|
||||
sm_free(mn);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if _FFR_RCPTFLAGS
|
||||
/* first character for dynamically created mailers */
|
||||
static char dynmailerp = ' ';
|
||||
@ -1380,7 +1533,6 @@ newmodmailer(rcpt, fl)
|
||||
** enters the mailer into the mailer table.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
makemailer(line)
|
||||
char *line;
|
||||
@ -2958,7 +3110,7 @@ static struct optioninfo
|
||||
#endif
|
||||
#if _FFR_EIGHT_BIT_ADDR_OK
|
||||
# if !ALLOW_255
|
||||
# ERROR "_FFR_EIGHT_BIT_ADDR_OK requires ALLOW_255"
|
||||
# error "_FFR_EIGHT_BIT_ADDR_OK requires ALLOW_255"
|
||||
# endif
|
||||
# define O_EIGHT_BIT_ADDR_OK 0xdf
|
||||
{ "EightBitAddrOK", O_EIGHT_BIT_ADDR_OK, OI_NONE },
|
||||
@ -3013,7 +3165,7 @@ static struct optioninfo
|
||||
# define O_TLSFB2CLEAR 0xef
|
||||
{ "TLSFallbacktoClear", O_TLSFB2CLEAR, OI_NONE },
|
||||
#endif
|
||||
#if DNSSEC_TEST
|
||||
#if DNSSEC_TEST || _FFR_NAMESERVER
|
||||
# define O_NSPORTIP 0xf0
|
||||
{ "NameServer", O_NSPORTIP, OI_NONE },
|
||||
#endif
|
||||
@ -3021,7 +3173,7 @@ static struct optioninfo
|
||||
# define O_DANE 0xf1
|
||||
{ "DANE", O_DANE, OI_NONE },
|
||||
#endif
|
||||
#if DNSSEC_TEST
|
||||
#if DNSSEC_TEST || _FFR_NAMESERVER
|
||||
# define O_NSSRCHLIST 0xf2
|
||||
{ "NameSearchList", O_NSSRCHLIST, OI_NONE },
|
||||
#endif
|
||||
@ -3744,7 +3896,6 @@ setoption(opt, val, safe, sticky, e)
|
||||
WkTimeFact = atoi(val);
|
||||
break;
|
||||
|
||||
|
||||
#if _FFR_QUEUE_GROUP_SORTORDER
|
||||
/* coordinate this with makequeue() */
|
||||
#endif
|
||||
@ -4737,7 +4888,7 @@ setoption(opt, val, safe, sticky, e)
|
||||
UseCompressedIPv6Addresses = atobool(val);
|
||||
break;
|
||||
|
||||
#if DNSSEC_TEST
|
||||
#if DNSSEC_TEST || _FFR_NAMESERVER
|
||||
case O_NSPORTIP:
|
||||
nsportip(val);
|
||||
break;
|
||||
@ -4776,9 +4927,9 @@ setoption(opt, val, safe, sticky, e)
|
||||
#if USE_EAI
|
||||
/* hack for testing */
|
||||
if (isascii(*val) && isdigit(*val))
|
||||
SMTPUTF8 = (int) strtol(val, NULL, 0);
|
||||
SMTP_UTF8 = (int) strtol(val, NULL, 0);
|
||||
else
|
||||
SMTPUTF8 = atobool(val);
|
||||
SMTP_UTF8 = atobool(val);
|
||||
#else
|
||||
if (atobool(val))
|
||||
syserr("readcf: option: %s set but no USE_EAI support",
|
||||
@ -4861,6 +5012,42 @@ setclass(class, str)
|
||||
setbitn(bitidx(class), s->s_class);
|
||||
}
|
||||
}
|
||||
|
||||
#if _FFR_CLASS_RM_ENTRY
|
||||
/*
|
||||
** CLASSRMENTRY -- remove a string from a class
|
||||
**
|
||||
** Parameters:
|
||||
** class -- the class from which to remove the string.
|
||||
** str -- the string to remove
|
||||
**
|
||||
** Returns:
|
||||
** none.
|
||||
**
|
||||
** Side Effects:
|
||||
** removes the string from the class (if it was in there).
|
||||
*/
|
||||
|
||||
static void
|
||||
classrmentry(class, str)
|
||||
int class;
|
||||
char *str;
|
||||
{
|
||||
STAB *s;
|
||||
|
||||
s = stab(str, ST_CLASS, ST_FIND);
|
||||
if (NULL == s /* || ST_CLASS != s->s_symtype */)
|
||||
{
|
||||
if (tTd(37, 8))
|
||||
sm_dprintf("classrmentry: entry=%s not in class %s\n", str, macname(class));
|
||||
return;
|
||||
}
|
||||
clrbitn(bitidx(class), s->s_class);
|
||||
if (tTd(37, 8))
|
||||
sm_dprintf("classrmentry(%s, %s)=%d\n", macname(class), str, bitnset(bitidx(class), s->s_class));
|
||||
}
|
||||
#endif /* _FFR_CLASS_RM_ENTRY */
|
||||
|
||||
/*
|
||||
** MAKEMAPENTRY -- create a map entry
|
||||
**
|
||||
@ -5169,7 +5356,6 @@ static struct timeoutinfo
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
settimeout(name, val, sticky)
|
||||
char *name;
|
||||
|
@ -117,9 +117,11 @@ sortbysignature(xx, yy)
|
||||
|
||||
/* Let's avoid redoing the signature over and over again */
|
||||
if (xx->q_signature == NULL)
|
||||
xx->q_signature = hostsignature(xx->q_mailer, xx->q_host, xx->q_flags & QSECURE);
|
||||
xx->q_signature = hostsignature(xx->q_mailer, xx->q_host,
|
||||
QISSECURE(xx), NULL);
|
||||
if (yy->q_signature == NULL)
|
||||
yy->q_signature = hostsignature(yy->q_mailer, yy->q_host, yy->q_flags & QSECURE);
|
||||
yy->q_signature = hostsignature(yy->q_mailer, yy->q_host,
|
||||
QISSECURE(yy), NULL);
|
||||
ret = strcmp(xx->q_signature, yy->q_signature);
|
||||
|
||||
/*
|
||||
@ -748,7 +750,7 @@ recipient(new, sendq, aliaslevel, e)
|
||||
if (i == 0) /* equal */
|
||||
{
|
||||
/*
|
||||
** Sortbysignature() has said that the two have
|
||||
** sortbysignature() has said that the two have
|
||||
** equal MX RR's and the same user. Calling sameaddr()
|
||||
** now checks if the two hosts are as identical as the
|
||||
** MX RR's are (which might not be the case)
|
||||
@ -1600,7 +1602,6 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e)
|
||||
else
|
||||
ev = NULL;
|
||||
|
||||
|
||||
/* check for writable parent directory */
|
||||
p = strrchr(fname, '/');
|
||||
if (p != NULL)
|
||||
@ -1977,7 +1978,7 @@ sendtoargv(argv, e)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (!SMTPUTF8 && !asciistr(p))
|
||||
if (!SMTP_UTF8 && !asciistr(p))
|
||||
{
|
||||
usrerr("non-ASCII recipient address %s requires SMTPUTF8",
|
||||
p);
|
||||
|
@ -1887,8 +1887,8 @@ pruneroute(addr)
|
||||
|
||||
while (start != NULL)
|
||||
{
|
||||
if (getmxrr(hostbuf, mxhosts, NULL, TRYFALLBACK, &rcode, NULL, -1)
|
||||
> 0)
|
||||
if (getmxrr(hostbuf, mxhosts, NULL, TRYFALLBACK, &rcode, NULL,
|
||||
-1, NULL) > 0)
|
||||
{
|
||||
(void) sm_strlcpy(addr + 1, start + 1,
|
||||
strlen(addr) - 1);
|
||||
|
172
contrib/sendmail/src/sched.c
Normal file
172
contrib/sendmail/src/sched.c
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
*
|
||||
* By using this file, you agree to the terms and conditions set
|
||||
* forth in the LICENSE file which can be found at the top level of
|
||||
* the sendmail distribution.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sendmail.h>
|
||||
|
||||
#if _FFR_DMTRIGGER
|
||||
#include <sm/sendmail.h>
|
||||
#include <sm/notify.h>
|
||||
|
||||
static ENVELOPE QmEnvelope;
|
||||
|
||||
/*
|
||||
** Macro for fork():
|
||||
** FORK_P1(): parent
|
||||
** FORK_C1(): child
|
||||
** Note: these are not "universal", e.g.,
|
||||
** proc_list_add() might be used in parent or child.
|
||||
** maybe check pname != NULL to invoke proc_list_add()?
|
||||
*/
|
||||
|
||||
#define FORK_P1(emsg, pname, ptype) \
|
||||
do { \
|
||||
(void) sm_blocksignal(SIGCHLD); \
|
||||
(void) sm_signal(SIGCHLD, reapchild); \
|
||||
\
|
||||
pid = dofork(); \
|
||||
if (pid == -1) \
|
||||
{ \
|
||||
const char *msg = emsg; \
|
||||
const char *err = sm_errstring(errno); \
|
||||
\
|
||||
if (LogLevel > 8) \
|
||||
sm_syslog(LOG_INFO, NOQID, "%s: %s", \
|
||||
msg, err); \
|
||||
(void) sm_releasesignal(SIGCHLD); \
|
||||
return false; \
|
||||
} \
|
||||
if (pid != 0) \
|
||||
{ \
|
||||
proc_list_add(pid, pname, ptype, 0, -1, NULL); \
|
||||
/* parent -- pick up intermediate zombie */ \
|
||||
(void) sm_releasesignal(SIGCHLD); \
|
||||
return true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FORK_C1() \
|
||||
do { \
|
||||
/* child -- clean up signals */ \
|
||||
\
|
||||
/* Reset global flags */ \
|
||||
RestartRequest = NULL; \
|
||||
RestartWorkGroup = false; \
|
||||
ShutdownRequest = NULL; \
|
||||
PendingSignal = 0; \
|
||||
CurrentPid = getpid(); \
|
||||
close_sendmail_pid(); \
|
||||
\
|
||||
/* \
|
||||
** Initialize exception stack and default exception \
|
||||
** handler for child process. \
|
||||
*/ \
|
||||
\
|
||||
sm_exc_newthread(fatal_error); \
|
||||
clrcontrol(); \
|
||||
proc_list_clear(); \
|
||||
\
|
||||
(void) sm_releasesignal(SIGCHLD); \
|
||||
(void) sm_signal(SIGCHLD, SIG_DFL); \
|
||||
(void) sm_signal(SIGHUP, SIG_DFL); \
|
||||
(void) sm_signal(SIGTERM, intsig); \
|
||||
\
|
||||
/* drop privileges */ \
|
||||
if (geteuid() == (uid_t) 0) \
|
||||
(void) drop_privileges(false); \
|
||||
disconnect(1, NULL); \
|
||||
QuickAbort = false; \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
** QM -- queue "manager"
|
||||
**
|
||||
** Parameters:
|
||||
** none.
|
||||
**
|
||||
** Returns:
|
||||
** false on error
|
||||
**
|
||||
** Side Effects:
|
||||
** fork()s and runs as process to deliver queue entries
|
||||
*/
|
||||
|
||||
bool
|
||||
qm()
|
||||
{
|
||||
int r;
|
||||
pid_t pid;
|
||||
long tmo;
|
||||
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: start");
|
||||
|
||||
FORK_P1("Queue manager -- fork() failed", "QM", PROC_QM);
|
||||
FORK_C1();
|
||||
|
||||
r = sm_notify_start(true, 0);
|
||||
if (r != 0)
|
||||
syserr("sm_notify_start() failed=%d", r);
|
||||
|
||||
/*
|
||||
** Initially wait indefinitely, then only wait
|
||||
** until something needs to get done (not yet implemented).
|
||||
*/
|
||||
|
||||
tmo = -1;
|
||||
while (true)
|
||||
{
|
||||
char buf[64];
|
||||
ENVELOPE *e;
|
||||
SM_RPOOL_T *rpool;
|
||||
|
||||
/*
|
||||
** TODO: This should try to receive multiple ids:
|
||||
** after it got one, check for more with a very short timeout
|
||||
** and collect them in a list.
|
||||
** but them some other code should be used to run all of them.
|
||||
*/
|
||||
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=start");
|
||||
r = sm_notify_rcv(buf, sizeof(buf), tmo);
|
||||
if (-ETIMEDOUT == r)
|
||||
{
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=timed_out");
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
{
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: rcv=%d", r);
|
||||
goto end;
|
||||
}
|
||||
if (r > 0 && r < sizeof(buf))
|
||||
buf[r] = '\0';
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: got=%s", buf);
|
||||
CurEnv = &QmEnvelope;
|
||||
rpool = sm_rpool_new_x(NULL);
|
||||
e = newenvelope(&QmEnvelope, CurEnv, rpool);
|
||||
e->e_flags = BlankEnvelope.e_flags;
|
||||
e->e_parent = NULL;
|
||||
r = sm_io_sscanf(buf, "N:%d:%d:%s", &e->e_qgrp, &e->e_qdir, e->e_id);
|
||||
if (r != 3)
|
||||
{
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: buf=%s, scan=%d", buf, r);
|
||||
goto end;
|
||||
}
|
||||
dowork(e->e_qgrp, e->e_qdir, e->e_id, true, false, e);
|
||||
}
|
||||
|
||||
end:
|
||||
sm_syslog(LOG_DEBUG, NOQID, "queue manager: stop");
|
||||
finis(false, false, EX_OK);
|
||||
/* NOTREACHED */
|
||||
return false;
|
||||
}
|
||||
#endif /* _FFR_DMTRIGGER */
|
@ -87,8 +87,8 @@ or
|
||||
Go into
|
||||
ARPANET
|
||||
mode.
|
||||
All input lines must end with a CR-LF,
|
||||
and all messages will be generated with a CR-LF at the end.
|
||||
All input lines must end with a CRLF,
|
||||
and all messages will be generated with a CRLF at the end.
|
||||
Also,
|
||||
the ``From:'' and ``Sender:''
|
||||
fields are examined for the name of the sender.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2013 Proofpoint, Inc. and its suppliers.
|
||||
* Copyright (c) 1998-2013, 2023,2024 Proofpoint, Inc. and its suppliers.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
|
||||
* Copyright (c) 1988, 1993
|
||||
@ -46,16 +46,16 @@
|
||||
# endif
|
||||
#else /* STARTTLS */
|
||||
# if DANE
|
||||
# ERROR "DANE set but STARTTLS not defined"
|
||||
# error "DANE set but STARTTLS not defined"
|
||||
# endif
|
||||
# if _FFR_TLS_ALTNAMES
|
||||
# ERROR "_FFR_TLS_ALTNAMES set but STARTTLS not defined"
|
||||
# error "_FFR_TLS_ALTNAMES set but STARTTLS not defined"
|
||||
# endif
|
||||
# if _FFR_TLSFB2CLEAR
|
||||
# ERROR "_FFR_TLSFB2CLEAR set but STARTTLS not defined"
|
||||
# error "_FFR_TLSFB2CLEAR set but STARTTLS not defined"
|
||||
# endif
|
||||
# if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
|
||||
# ERROR "_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE set but STARTTLS not defined"
|
||||
# error "_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE set but STARTTLS not defined"
|
||||
# endif
|
||||
#endif /* STARTTLS */
|
||||
|
||||
@ -124,9 +124,12 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:5
|
||||
# undef NOERROR /* avoid <sys/streams.h> conflict */
|
||||
# endif
|
||||
# include <resolv.h>
|
||||
# if !defined(NO_DATA)
|
||||
# define NO_DATA NO_ADDRESS
|
||||
# endif
|
||||
#else /* NAMED_BIND */
|
||||
# undef SM_SET_H_ERRNO
|
||||
# define SM_SET_H_ERRNO(err)
|
||||
# undef SM_SET_H_ERRNO
|
||||
# define SM_SET_H_ERRNO(err)
|
||||
#endif /* NAMED_BIND */
|
||||
|
||||
#if HESIOD
|
||||
@ -140,29 +143,39 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:5
|
||||
# define ALLOW_255 1
|
||||
#endif
|
||||
#if _FFR_EAI && _FFR_EIGHT_BIT_ADDR_OK
|
||||
# ERROR "Cannot enable both of these FFRs: _FFR_EAI _FFR_EIGHT_BIT_ADDR_OK"
|
||||
# error "Cannot enable both of these FFRs: _FFR_EAI _FFR_EIGHT_BIT_ADDR_OK"
|
||||
#endif
|
||||
|
||||
#if _FFR_OCC && !SM_CONF_SHM
|
||||
# ERROR "_FFR_OCC requires SM_CONF_SHM"
|
||||
# error "_FFR_OCC requires SM_CONF_SHM"
|
||||
#endif
|
||||
|
||||
#if _FFR_SM_LDAP_DBG && !(LDAPMAP && defined(LBER_OPT_LOG_PRINT_FN))
|
||||
# ERROR "_FFR_SM_LDAP_DBG requires LDAPMAP and LBER_OPT_LOG_PRINT_FN"
|
||||
#if !NOT_SENDMAIL
|
||||
# if _FFR_SM_LDAP_DBG && !(LDAPMAP && defined(LBER_OPT_LOG_PRINT_FN))
|
||||
# error "_FFR_SM_LDAP_DBG requires LDAPMAP and LBER_OPT_LOG_PRINT_FN"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _FFR_LOG_MORE1 > 1 || _FFR_LOG_MORE2 > 1
|
||||
# if _FFR_LOG_MORE1 != _FFR_LOG_MORE2
|
||||
# ERROR "_FFR_LOG_MORE1 != _FFR_LOG_MORE2"
|
||||
# error "_FFR_LOG_MORE1 != _FFR_LOG_MORE2"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if LDAP_NETWORK_TIMEOUT && !(LDAPMAP && defined(LDAP_OPT_NETWORK_TIMEOUT))
|
||||
# ERROR "LDAP_NETWORK_TIMEOUT requires LDAPMAP"
|
||||
#if !NOT_SENDMAIL
|
||||
# if LDAP_NETWORK_TIMEOUT && !(LDAPMAP && defined(LDAP_OPT_NETWORK_TIMEOUT))
|
||||
# error "LDAP_NETWORK_TIMEOUT requires LDAPMAP"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !NOT_SENDMAIL
|
||||
# if LDAP_REFERRALS && !LDAPMAP
|
||||
# error "LDAP_REFERRALS requires LDAPMAP"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _FFR_VRFY_TRUSTED_FIRST && !defined(X509_V_FLAG_TRUSTED_FIRST)
|
||||
# ERROR "_FFR_VRFY_TRUSTED_FIRST set but X509_V_FLAG_TRUSTED_FIRST not defined"
|
||||
# error "_FFR_VRFY_TRUSTED_FIRST set but X509_V_FLAG_TRUSTED_FIRST not defined"
|
||||
#endif
|
||||
|
||||
#if _FFR_8BITENVADDR
|
||||
@ -171,26 +184,37 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:5
|
||||
# define MAXNAME_I MAXNAME
|
||||
#endif
|
||||
|
||||
#if !defined(_FFR_M_ONLY_IPV4)
|
||||
# define _FFR_M_ONLY_IPV4 1
|
||||
#endif
|
||||
|
||||
#define SM_IS_EMPTY(s) (NULL == (s) || '\0' == *(s))
|
||||
|
||||
#if STARTTLS
|
||||
# if DANE
|
||||
# define DANE_FP_LOG_LEN 256
|
||||
# define DANE_FP_DBG_LEN 4096
|
||||
struct dane_vrfy_ctx_S
|
||||
{
|
||||
/* see tls.h: values for DANE option and dane_vrfy_chk */
|
||||
int dane_vrfy_chk;
|
||||
int dane_vrfy_res;
|
||||
int dane_vrfy_port;
|
||||
|
||||
/* use OpenSSL functions for DANE checks? */
|
||||
bool dane_vrfy_dane_enabled;
|
||||
|
||||
/* look up TLSA RRs, SNI unless dane_tlsa_sni is set. */
|
||||
char *dane_vrfy_host;
|
||||
char *dane_vrfy_sni; /* if not NULL: use for SNI */
|
||||
|
||||
/* full fingerprint in printable format */
|
||||
char dane_vrfy_fp[1024];
|
||||
/* fingerprint in printable format - just for logging */
|
||||
char dane_vrfy_fp[DANE_FP_LOG_LEN];
|
||||
};
|
||||
|
||||
typedef struct dane_tlsa_S dane_tlsa_T, *dane_tlsa_P;
|
||||
typedef struct dane_vrfy_ctx_S dane_vrfy_ctx_T, *dane_vrfy_ctx_P;
|
||||
|
||||
# endif /* DANE */
|
||||
|
||||
/* TLS information context */
|
||||
@ -208,8 +232,8 @@ typedef struct tlsi_ctx_S tlsi_ctx_T, *tlsi_ctx_P;
|
||||
#define TLSI_FL_CRLREQ 'R' /* CRL required */
|
||||
#define TLSI_FL_FB2CLR 'C' /* fall back to clear text is ok */
|
||||
#define TLSI_FL_NOFB2CLR 'c' /* do not fall back to clear text */
|
||||
#define TLSI_FL_NODANE 'd' /* do not use/lookup DANE */
|
||||
#define TLSI_FL_NOSTS 'M' /* do not use/lookup STS */
|
||||
#define TLSI_FL_NODANE 'd' /* do not use/look up DANE */
|
||||
#define TLSI_FL_NOSTS 'M' /* do not use/look up STS */
|
||||
/* internal */
|
||||
#define TLSI_FL_STS_NOFB2CLR 0x01 /* no clear text: STS is used */
|
||||
#define SM_TLSI_IS(tlsi_ctx, flag) \
|
||||
@ -265,14 +289,14 @@ typedef int (*sasl_callback_ft)(void);
|
||||
# define SASL SASL_VERSION
|
||||
# else /* SASL == 1 || SASL == 2 */
|
||||
# if SASL != SASL_VERSION
|
||||
# ERROR "README: -DSASL (SASL) does not agree with the version of the CYRUS_SASL library (SASL_VERSION)"
|
||||
# ERROR "README: see README!"
|
||||
# error "README: -DSASL (SASL) does not agree with the version of the CYRUS_SASL library (SASL_VERSION)"
|
||||
# error "README: see README!"
|
||||
# endif /* SASL != SASL_VERSION */
|
||||
# endif /* SASL == 1 || SASL == 2 */
|
||||
# else /* defined(SASL_VERSION_MAJOR) && defined(SASL_VERSION_MINOR) && defined(SASL_VERSION_STEP) */
|
||||
# if SASL == 1
|
||||
# ERROR "README: please set -DSASL to the version of the CYRUS_SASL library"
|
||||
# ERROR "README: see README!"
|
||||
# error "README: please set -DSASL to the version of the CYRUS_SASL library"
|
||||
# error "README: see README!"
|
||||
# endif /* SASL == 1 */
|
||||
# endif /* defined(SASL_VERSION_MAJOR) && defined(SASL_VERSION_MINOR) && defined(SASL_VERSION_STEP) */
|
||||
#endif /* SASL */
|
||||
@ -351,7 +375,7 @@ struct address
|
||||
char *q_paddr; /* the printname for the address */
|
||||
char *q_user; /* user name */
|
||||
char *q_ruser; /* real user name, or NULL if q_user */
|
||||
char *q_host; /* host name */
|
||||
char *q_host; /* host name [x] */
|
||||
#if DANE
|
||||
char *q_qname; /* original query (host) name */
|
||||
#endif
|
||||
@ -382,6 +406,18 @@ struct address
|
||||
|
||||
typedef struct address ADDRESS;
|
||||
|
||||
|
||||
/*
|
||||
** Note: only some of the flags are saved in the queue;
|
||||
** the code in queue.c does not use the actual value but maps each flag
|
||||
** to/from an associated character.
|
||||
** If the values would not change then those could be stored/retrieved
|
||||
** directly (applying a mask to select those flags which should be kep) --
|
||||
** the mapping to/from characters provides a "defined" external interface
|
||||
** provided those mappings are kept (and if an old mapping is removed then
|
||||
** it should be kept as comment so it is not reused "too soon").
|
||||
*/
|
||||
|
||||
/* bit values for q_flags */
|
||||
#define QGOODUID 0x00000001 /* the q_uid q_gid fields are good */
|
||||
#define QPRIMARY 0x00000002 /* set from RCPT or argv */
|
||||
@ -403,9 +439,10 @@ typedef struct address ADDRESS;
|
||||
#define QBYNRELAY 0x00020000 /* DeliverBy: notify, relayed */
|
||||
#define QINTBCC 0x00040000 /* internal Bcc */
|
||||
#define QDYNMAILER 0x00080000 /* "dynamic mailer" */
|
||||
#define QSECURE 0x00100000 /* DNSSEC ok */
|
||||
#define QSECURE 0x00100000 /* DNSSEC ok for host lookup */
|
||||
#define QQUEUED 0x00200000 /* queued */
|
||||
#define QINTREPLY 0x00400000 /* internally rejected (delivery) */
|
||||
#define QMXSECURE 0x00800000 /* DNSSEC ok for MX lookup */
|
||||
#define QTHISPASS 0x40000000 /* temp: address set this pass */
|
||||
#define QRCPTOK 0x80000000 /* recipient() processed address */
|
||||
|
||||
@ -413,6 +450,8 @@ typedef struct address ADDRESS;
|
||||
|
||||
#define Q_PINGFLAGS (QPINGONSUCCESS|QPINGONFAILURE|QPINGONDELAY)
|
||||
|
||||
#define QISSECURE(r) (0 != ((r)->q_flags & QSECURE))
|
||||
|
||||
#if _FFR_RCPTFLAGS
|
||||
# define QMATCHFLAGS (QINTBCC|QDYNMAILER)
|
||||
# define QMATCH_FLAG(a) ((a)->q_flags & QMATCHFLAGS)
|
||||
@ -617,8 +656,8 @@ struct mailer
|
||||
#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) */
|
||||
/* '4' free? */
|
||||
#define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */
|
||||
#define M_ONLY_IPV4 '4' /* Use only IPv4 */
|
||||
#define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */
|
||||
#define M_7BITHDRS '6' /* strip headers to 7 bits even in 8 bit path */
|
||||
#define M_7BITS '7' /* use 7-bit path */
|
||||
@ -633,6 +672,9 @@ struct mailer
|
||||
#define M_PLUS '+' /* Reserved: Used in mc for adding new flags */
|
||||
#define M_MINUS '-' /* Reserved: Used in mc for removing flags */
|
||||
#define M_NOMHHACK '!' /* Don't perform HM hack dropping explicit from */
|
||||
#if _FFR_SMTPS_CLIENT
|
||||
# define M_SMTPS_CLIENT '_' /* use SMTP over TLS (465/TCP) */
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
extern void initerrmailers __P((void));
|
||||
@ -767,12 +809,12 @@ extern bool filesys_free __P((long));
|
||||
(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!"
|
||||
# error "change SASL_SEC_MASK notify sendmail.org!"
|
||||
# endif /* SASL_SEC_NOPLAINTEXT & SASL_SEC_MASK) == 0 ... */
|
||||
# endif /* SASL >= 20101 */
|
||||
# define MAXOUTLEN 8192 /* length of output buffer, should be 2^n */
|
||||
# if (SASL_AUTH_AUTH & SASL_SEC_MASK) != 0
|
||||
# ERROR "change SASL_AUTH_AUTH notify sendmail.org!"
|
||||
# error "change SASL_AUTH_AUTH notify sendmail.org!"
|
||||
# endif
|
||||
|
||||
/* functions */
|
||||
@ -875,7 +917,7 @@ MCI
|
||||
#define MCIF_8BITMIME 0x00000040 /* BODY=8BITMIME supported */
|
||||
#define MCIF_7BIT 0x00000080 /* strip this message to 7 bits */
|
||||
/* 0x00000100 unused, was MCIF_MULTSTAT: MAIL11V3: handles MULT status */
|
||||
#define MCIF_INHEADER 0x00000200 /* currently outputing header */
|
||||
#define MCIF_INHEADER 0x00000200 /* currently outputting header */
|
||||
#define MCIF_CVT8TO7 0x00000400 /* convert from 8 to 7 bits */
|
||||
#define MCIF_DSN 0x00000800 /* DSN extension supported */
|
||||
#define MCIF_8BITOK 0x00001000 /* OK to send 8 bit characters */
|
||||
@ -915,6 +957,7 @@ MCI
|
||||
#define MCIF_EXTENS (MCIF_EXPN|MCIF_SIZE|MCIF_8BITMIME|MCIF_DSN|MCIF_8BITOK|MCIF_AUTH|MCIF_ENHSTAT|MCIF_PIPELINED|MCIF_VERB|MCIF_TLS|MCIF_DLVR_BY|MCIF_AUTH2|MCIF_EAI)
|
||||
|
||||
/* states */
|
||||
/* XREF: deliver.c: mcis[] -- any changes here must be reflected there! */
|
||||
#define MCIS_CLOSED 0 /* no traffic on this connection */
|
||||
#define MCIS_OPENING 1 /* sending initial protocol */
|
||||
#define MCIS_OPEN 2 /* open, initial protocol sent */
|
||||
@ -1032,7 +1075,6 @@ TIMERS
|
||||
TIMER ti_overall; /* the whole process */
|
||||
};
|
||||
|
||||
|
||||
#define PUSHTIMER(l, t) { if (tTd(98, l)) pushtimer(&t); }
|
||||
#define POPTIMER(l, t) { if (tTd(98, l)) poptimer(&t); }
|
||||
|
||||
@ -1115,11 +1157,13 @@ struct envelope
|
||||
MCI *e_mci; /* connection info */
|
||||
char *e_auth_param; /* readonly; NULL or static storage or
|
||||
* allocated from e_rpool */
|
||||
#if _FFR_TIMERS
|
||||
TIMERS e_timers; /* per job timers */
|
||||
#endif
|
||||
long e_deliver_by; /* deliver by */
|
||||
int e_dlvr_flag; /* deliver by flag */
|
||||
SM_RPOOL_T *e_rpool; /* resource pool for this envelope */
|
||||
unsigned int e_features; /* server features */
|
||||
unsigned long e_features; /* server features */
|
||||
#define ENHSC_LEN 11
|
||||
#if _FFR_MILTER_ENHSC
|
||||
char e_enhsc[ENHSC_LEN]; /* enhanced status code */
|
||||
@ -1128,6 +1172,9 @@ struct envelope
|
||||
int e_rcode; /* reply code */
|
||||
char e_renhsc[ENHSC_LEN]; /* enhanced status code */
|
||||
char *e_text; /* reply text */
|
||||
#if _FFR_LOG_STAGE
|
||||
int e_estate; /* protocol state when error happened */
|
||||
#endif
|
||||
};
|
||||
|
||||
#define PRT_NONNEGL(v) ((v) < 0 ? LONG_MAX : (v))
|
||||
@ -1151,8 +1198,8 @@ struct envelope
|
||||
#define EF_LOGSENDER 0x00008000L /* need to log the sender */
|
||||
#define EF_NORECEIPT 0x00010000L /* suppress all return-receipts */
|
||||
#define EF_HAS8BIT 0x00020000L /* at least one 8-bit char in body */
|
||||
/* was: EF_NL_NOT_EOL 0x00040000L * don't accept raw NL as EOLine */
|
||||
/* was: EF_CRLF_NOT_EOL 0x00080000L * don't accept CR-LF as EOLine */
|
||||
/* was: EF_NL_NOT_EOL 0x00040000L * don't accept raw LF as EOLine */
|
||||
/* was: EF_CRLF_NOT_EOL 0x00080000L * don't accept CRLF as EOLine */
|
||||
#define EF_RET_PARAM 0x00100000L /* RCPT command had RET argument */
|
||||
#define EF_HAS_DF 0x00200000L /* set when data file is instantiated */
|
||||
#define EF_IS_MIME 0x00400000L /* really is a MIME message */
|
||||
@ -1163,6 +1210,7 @@ struct envelope
|
||||
#define EF_UNSAFE 0x08000000L /* unsafe: read from untrusted source */
|
||||
#define EF_TOODEEP 0x10000000L /* message is nested too deep */
|
||||
#define EF_SECURE 0x20000000L /* DNSSEC for currently parsed addr */
|
||||
#define EF_7BITBODY 0x40000000L /* strip body to 7bit on input */
|
||||
|
||||
#define DLVR_NOTIFY 0x01
|
||||
#define DLVR_RETURN 0x02
|
||||
@ -1414,8 +1462,8 @@ typedef union
|
||||
|
||||
/* functions */
|
||||
extern int getcanonname __P((char *, int, bool, int *));
|
||||
extern int getmxrr __P((char *, char **, unsigned short *, unsigned int, int *, int *, int));
|
||||
extern char *hostsignature __P((MAILER *, char *, bool));
|
||||
extern int getmxrr __P((char *, char **, unsigned short *, unsigned int, int *, int *, int, int *));
|
||||
extern char *hostsignature __P((MAILER *, char *, bool, unsigned long *));
|
||||
extern int getfallbackmxrr __P((char *));
|
||||
|
||||
/*
|
||||
@ -1462,6 +1510,9 @@ MAP
|
||||
short map_return[MAXMAPACTIONS]; /* return bitmaps for stacked maps */
|
||||
};
|
||||
|
||||
#if _FFR_DYN_CLASS
|
||||
# define map_tag map_domain /* overload map field */
|
||||
#endif
|
||||
|
||||
/* bit values for map_mflags */
|
||||
#define MF_VALID 0x00000001 /* this entry is valid */
|
||||
@ -1474,7 +1525,8 @@ MAP
|
||||
#define MF_ALIAS 0x00000080 /* this is an alias file */
|
||||
#define MF_TRY0NULL 0x00000100 /* try with no null byte */
|
||||
#define MF_TRY1NULL 0x00000200 /* try with the null byte */
|
||||
#define MF_LOCKED 0x00000400 /* this map is currently locked */
|
||||
#define MF_LOCKED 0x00000400 /* map is locked (RDWR) */
|
||||
/* that means: no extra lockfile() calls must be made (in *map_lookup()) */
|
||||
#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 */
|
||||
@ -1491,6 +1543,7 @@ MAP
|
||||
#define MF_CLOSING 0x01000000 /* map is being closed */
|
||||
#define MF_SECURE 0x02000000 /* DNSSEC result is "secure" */
|
||||
#define MF_KEEPXFMT 0x04000000 /* keep [x] format */
|
||||
#define MF_CHKED_CHGD 0x08000000 /* checked whether underlying map changed */
|
||||
|
||||
#define DYNOPENMAP(map) \
|
||||
do \
|
||||
@ -1552,6 +1605,11 @@ extern int udbexpand __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
extern void _udbx_close __P((void));
|
||||
extern char *udbsender __P((char *, SM_RPOOL_T *));
|
||||
#endif
|
||||
#if _FFR_MAP_CHK_FILE > 1
|
||||
extern void maps_reset_chged __P((const char *));
|
||||
#else
|
||||
# define maps_reset_chged(msg)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** LDAP related items
|
||||
@ -1579,7 +1637,6 @@ struct lssvalues
|
||||
};
|
||||
|
||||
/* functions */
|
||||
extern bool ldapmap_parseargs __P((MAP *, char *));
|
||||
extern void ldapmap_set_defaults __P((char *));
|
||||
#endif /* LDAPMAP */
|
||||
|
||||
@ -1711,6 +1768,9 @@ struct symtab
|
||||
QUEUEGRP *sv_queue; /* pointer to queue */
|
||||
#if DANE
|
||||
dane_tlsa_P sv_tlsa; /* pointer to TLSA RRs */
|
||||
#endif
|
||||
#if _FFR_DYN_CLASS
|
||||
MAP sv_dynclass; /* map for dynamic class */
|
||||
#endif
|
||||
} s_value;
|
||||
};
|
||||
@ -1746,9 +1806,12 @@ typedef struct symtab STAB;
|
||||
#if DANE
|
||||
# define ST_TLSA_RR 17 /* cached TLSA RRs */
|
||||
#endif
|
||||
#if _FFR_DYN_CLASS
|
||||
# define ST_DYNMAP 18 /* dynamic map */
|
||||
#endif
|
||||
|
||||
/* This entry must be last */
|
||||
#define ST_MCI 18 /* mailer connection info (offset) */
|
||||
#define ST_MCI 19 /* mailer connection info (offset) */
|
||||
|
||||
#define s_class s_value.sv_class
|
||||
#define s_mailer s_value.sv_mailer
|
||||
@ -1775,6 +1838,9 @@ typedef struct symtab STAB;
|
||||
#if DANE
|
||||
# define s_tlsa s_value.sv_tlsa
|
||||
#endif
|
||||
#if _FFR_DYN_CLASS
|
||||
# define s_dynclass s_value.sv_dynclass
|
||||
#endif
|
||||
|
||||
/* opcodes to stab */
|
||||
#define ST_FIND 0 /* find entry */
|
||||
@ -1960,6 +2026,7 @@ EXTERN unsigned long PrivacyFlags; /* privacy flags */
|
||||
#define RSF_COUNT 0x0004 /* count rejections (statistics)? */
|
||||
#define RSF_ADDR 0x0008 /* reassemble address */
|
||||
#define RSF_STRING 0x0010 /* reassemble address as string */
|
||||
#define RSF_STATUS 0x0020 /* log "status" instead of "reject" */
|
||||
|
||||
/*
|
||||
** Flags passed to mime8to7 and putheader.
|
||||
@ -2246,6 +2313,7 @@ extern void sync_dir __P((char *, bool));
|
||||
#endif
|
||||
#if _FFR_DMTRIGGER
|
||||
extern bool qm __P((void));
|
||||
extern int deliver __P((ENVELOPE *, ADDRESS *));
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -2320,6 +2388,11 @@ extern void inittimeouts __P((char *, bool));
|
||||
# define tTd(flag, level) (tTdvect[flag] >= (unsigned char)level)
|
||||
#else
|
||||
# define tTd(flag, level) (tTdvect[flag] >= (unsigned char)level && !IntSig)
|
||||
# if _FFR_TESTS
|
||||
# define TTD(flag, level) (tTdvect[flag] >= (unsigned char)level && !IntSig)
|
||||
# else
|
||||
# define TTD(flag, level) false
|
||||
# endif
|
||||
#endif
|
||||
#define tTdlevel(flag) (tTdvect[flag])
|
||||
|
||||
@ -2402,6 +2475,7 @@ extern unsigned char tTdvect[100]; /* trace vector */
|
||||
} while (0)
|
||||
|
||||
/* reply types (text in SmtpMsgBuffer) */
|
||||
/* XREF: deliver.c: xs_states[] -- any changes here must be reflected there! */
|
||||
#define XS_DEFAULT 0 /* other commands, e.g., RSET */
|
||||
#define XS_STARTTLS 1
|
||||
#define XS_AUTH 2
|
||||
@ -2509,6 +2583,8 @@ EXTERN int volatile CurChildren; /* current number of daemonic children */
|
||||
EXTERN int CurrentLA; /* current load average */
|
||||
#if DANE
|
||||
EXTERN int Dane; /* DANE */
|
||||
#else
|
||||
# define Dane 0 /* XREF: see tls.h: #define DANE_NEVER */
|
||||
#endif
|
||||
EXTERN int DefaultNotify; /* default DSN notification flags */
|
||||
EXTERN int DelayLA; /* load average to delay connections */
|
||||
@ -2560,9 +2636,9 @@ EXTERN char *MemoryResource;/* memory resource to look up */
|
||||
#endif /* _FFR_MEMSTAT */
|
||||
EXTERN int SuperSafe; /* be extra careful, even if expensive */
|
||||
#if USE_EAI
|
||||
EXTERN int SMTPUTF8; /* enable SMTPUTF8 support */
|
||||
EXTERN int SMTP_UTF8; /* enable SMTPUTF8 support */
|
||||
#else
|
||||
# define SMTPUTF8 false
|
||||
# define SMTP_UTF8 false
|
||||
#endif
|
||||
EXTERN int VendorCode; /* vendor-specific operation enhancements */
|
||||
EXTERN int Verbose; /* set if blow-by-blow desired */
|
||||
@ -2691,10 +2767,10 @@ extern int skipaddrhost __P((const char *, bool));
|
||||
|
||||
/* alias file */
|
||||
extern void alias __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
extern bool aliaswait __P((MAP *, char *, bool));
|
||||
extern bool aliaswait __P((MAP *, const char *, bool));
|
||||
extern void forward __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
|
||||
extern void readaliases __P((MAP *, SM_FILE_T *, bool, bool));
|
||||
extern bool rebuildaliases __P((MAP *, bool));
|
||||
extern bool rebuildaliases __P((MAP *));
|
||||
extern void setalias __P((char *));
|
||||
|
||||
/* logging */
|
||||
@ -2704,7 +2780,7 @@ 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 *, ADDRESS *));
|
||||
extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)__P((char *, bool, MAILER *, MCI *, ENVELOPE *)), char **, int));
|
||||
extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)__P((char *, bool, MAILER *, MCI *, ENVELOPE *)), char **, int, char **));
|
||||
extern void smtp __P((char *volatile, BITMAP256, ENVELOPE *volatile));
|
||||
#if SASL
|
||||
extern int smtpauth __P((MAILER *, MCI *, ENVELOPE *));
|
||||
@ -2784,9 +2860,12 @@ 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
|
||||
#if XDEBUG
|
||||
extern void checkfd012 __P((char *));
|
||||
extern void checkfdopen __P((int, char *));
|
||||
#else
|
||||
# define checkfd012(str) ((void) 0)
|
||||
# define checkfdopen(n, str) ((void) 0)
|
||||
#endif
|
||||
extern void checkfds __P((char *));
|
||||
extern bool chownsafe __P((int, bool));
|
||||
@ -2796,7 +2875,7 @@ extern void cleanup_shm __P((bool));
|
||||
#endif
|
||||
extern void close_sendmail_pid __P((void));
|
||||
extern void clrdaemon __P((void));
|
||||
extern void collect __P((SM_FILE_T *, bool, HDR **, ENVELOPE *, bool));
|
||||
extern void collect __P((SM_FILE_T *, int, HDR **, ENVELOPE *, bool));
|
||||
extern time_t convtime __P((char *, int));
|
||||
extern char **copyplist __P((char **, bool, SM_RPOOL_T *));
|
||||
extern void copy_class __P((int, int));
|
||||
@ -2979,6 +3058,15 @@ extern bool xtextok __P((char *));
|
||||
extern int xunlink __P((char *));
|
||||
extern char *xuntextify __P((char *));
|
||||
|
||||
/* flags for collect() */
|
||||
#define SMTPMODE_NO 0
|
||||
#define SMTPMODE_LAX 0x01
|
||||
#define SMTPMODE_CRLF 0x02 /* CRLF.CRLF required for EOM */
|
||||
#define SMTPMODE_LF_421 0x04 /* bare LF: drop connection */
|
||||
#define SMTPMODE_CR_421 0x08 /* bare CR: drop connection */
|
||||
#define SMTPMODE_LF_SP 0x10 /* bare LF: replace with space */
|
||||
#define SMTPMODE_CR_SP 0x20 /* bare CR: replace with space */
|
||||
|
||||
#define ASSIGN_IFDIFF(old, new) \
|
||||
do \
|
||||
{ \
|
||||
@ -2992,6 +3080,7 @@ extern char *xuntextify __P((char *));
|
||||
|
||||
#if USE_EAI
|
||||
extern bool addr_is_ascii __P((const char *));
|
||||
extern bool str_is_print __P((const char *));
|
||||
extern const char *hn2alabel __P((const char *));
|
||||
#endif
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user