Merge commit '28fbd2825d216dafca4d991ad96d05b312f4f9a3'

Merge vendor sendmail 8.17.1 into HEAD
This commit is contained in:
Gregory Neil Shapiro 2023-01-15 21:20:22 +00:00
commit 2fb4f839f3
159 changed files with 7671 additions and 2933 deletions

View file

@ -1,7 +1,7 @@
# This file contains some CA certificates that are used to sign the # This file contains some CA certificates that are used to sign the
# certificates of mail servers of members of the sendmail consortium # certificates of mail servers of members of the sendmail consortium
# who may reply to questions etc sent to sendmail.org. # who may reply to questions etc sent to support.sendmail.org.
# It is useful to allow connections from those MTAs that can present # It is useful to allow connections from those MTAs which can present
# a certificate signed by one of these CA certificates. # a certificate signed by one of these CA certificates.
# #
@ -9,92 +9,92 @@ Certificate:
Data: Data:
Version: 3 (0x2) Version: 3 (0x2)
Serial Number: Serial Number:
81:9d:41:0f:40:55:ac:4a 92:a1:3b:d3:90:0b:ea:a7
Signature Algorithm: sha1WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=CA/emailAddress=ca+ca-rsa2018@esmtp.org Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=CA/emailAddress=ca+ca-rsa2021@esmtp.org
Validity Validity
Not Before: Feb 27 02:30:55 2018 GMT Not Before: Feb 25 17:44:02 2021 GMT
Not After : Feb 26 02:30:55 2021 GMT Not After : Feb 25 17:44:02 2024 GMT
Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=CA/emailAddress=ca+ca-rsa2018@esmtp.org Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=CA/emailAddress=ca+ca-rsa2021@esmtp.org
Subject Public Key Info: Subject Public Key Info:
Public Key Algorithm: rsaEncryption Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit) Public-Key: (2048 bit)
Modulus: Modulus:
00:b8:a3:8d:79:28:c1:1f:9c:11:74:43:26:e1:3b: 00:cc:8c:39:bd:cf:55:4f:66:2a:78:c7:65:47:81:
cc:14:87:5b:6b:64:4c:ed:79:1b:7f:2a:03:d0:7b: dd:d1:3f:08:12:4b:87:40:48:95:5c:24:52:65:a1:
ef:9e:88:b0:64:36:ee:58:ef:fd:d9:c7:20:b3:71: 82:1c:f4:90:a1:7c:f7:27:8f:02:e5:cb:ac:89:ae:
e9:6d:1e:a7:bc:c1:7c:3b:fe:2a:e4:16:2f:bc:d6: b8:25:4e:26:da:14:20:07:29:a4:59:03:61:b4:44:
2c:f5:98:f9:c4:21:1c:ca:c3:7e:57:89:c8:a9:2f: ae:45:55:b4:72:7d:66:9a:88:de:59:bf:6f:31:23:
da:6b:9b:52:d6:c9:9d:98:97:6d:08:7c:a6:37:4e: 06:29:ab:c2:b9:a0:6c:6a:5d:d0:ac:e6:b8:ac:8a:
d4:26:bb:db:73:b0:38:ef:7d:1e:dd:8e:dd:8e:17: 6f:5e:bb:f3:19:b5:8d:e1:df:2e:d1:7f:1a:bc:2c:
2f:a0:3d:a9:0e:4d:f0:2b:b8:14:23:33:ad:c8:a0: 13:10:65:46:7f:68:c7:60:49:c6:30:4e:a0:24:ed:
e5:9d:0f:27:ad:83:a2:78:90:05:ec:29:06:91:07: d4:a8:27:cf:b2:d0:c5:7c:96:47:82:b6:f1:17:0a:
45:6c:5f:ba:8e:1d:f1:d7:1b:2d:f9:99:ba:2e:27: 5a:35:82:0b:85:0f:17:71:a9:bd:3a:4c:e6:32:95:
e1:03:7d:e9:d2:54:35:cc:39:79:07:83:d8:93:9b: 3e:68:f7:3d:f5:04:33:16:19:1e:4c:0a:04:c3:1f:
d6:ef:72:ab:d4:63:8e:6b:f7:00:66:5f:77:e8:b6: 9e:ba:db:e2:0d:29:c8:3f:29:cf:47:cb:11:db:d2:
bc:de:5f:8c:d0:ce:1a:c4:db:03:9d:e4:ee:0a:ec: cd:d0:26:2f:35:eb:7d:a2:60:18:e7:7b:a2:43:15:
77:c5:f2:30:69:7e:70:12:e5:c2:4a:28:3f:e7:19: 59:d7:ea:9d:38:60:f1:48:df:57:54:df:8a:50:b9:
eb:af:41:fb:e6:a6:1d:b5:fd:2b:99:03:f5:20:90: e3:5c:72:82:51:b7:05:78:c2:14:08:71:71:1c:06:
38:73:bd:43:70:da:cf:1f:34:5d:ab:17:4b:73:cf: 44:4a:85:73:08:a8:49:50:b2:d2:fb:da:a2:a5:5a:
f9:3d:e1:a2:79:14:de:d8:40:85:82:c4:5a:84:82: 36:49:a8:4b:38:56:f6:67:0f:12:34:39:cc:fb:9c:
32:f1 bd:d3
Exponent: 65537 (0x10001) Exponent: 65537 (0x10001)
X509v3 extensions: X509v3 extensions:
X509v3 Subject Key Identifier: X509v3 Subject Key Identifier:
42:37:75:E7:8F:12:CF:D9:EB:21:22:7D:8A:E8:49:21:FD:E2:3A:3A 86:F0:F9:7A:CD:66:A9:16:CC:A3:26:08:3D:B3:B2:42:C2:E5:A9:13
X509v3 Authority Key Identifier: X509v3 Authority Key Identifier:
keyid:42:37:75:E7:8F:12:CF:D9:EB:21:22:7D:8A:E8:49:21:FD:E2:3A:3A keyid:86:F0:F9:7A:CD:66:A9:16:CC:A3:26:08:3D:B3:B2:42:C2:E5:A9:13
DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=CA/emailAddress=ca+ca-rsa2018@esmtp.org DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=CA/emailAddress=ca+ca-rsa2021@esmtp.org
serial:81:9D:41:0F:40:55:AC:4A serial:92:A1:3B:D3:90:0B:EA:A7
X509v3 Basic Constraints: X509v3 Basic Constraints:
CA:TRUE CA:TRUE
X509v3 Subject Alternative Name: X509v3 Subject Alternative Name:
email:ca+ca-rsa2018@esmtp.org email:ca+ca-rsa2021@esmtp.org
X509v3 Issuer Alternative Name: X509v3 Issuer Alternative Name:
email:ca+ca-rsa2018@esmtp.org email:ca+ca-rsa2021@esmtp.org
Signature Algorithm: sha1WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
0b:4c:e5:c2:ed:0a:e5:7b:95:29:22:d4:8f:5f:cb:1b:b1:e3: 41:14:09:49:01:5f:51:ff:20:7b:c2:41:79:9d:11:3c:7c:48:
4c:fc:90:e7:2e:97:87:87:a2:63:0d:6d:4d:f0:1f:0d:84:11: d6:43:d4:c6:0d:55:e6:76:bb:2c:c7:fb:dd:10:53:79:30:1a:
dc:df:b7:fa:c3:c6:2e:07:e9:a0:e9:a6:9f:54:17:ad:1a:d0: 35:64:2c:d0:64:b6:5a:fd:a9:d3:e3:09:8c:7d:22:81:b7:71:
36:be:31:cc:a5:85:a0:45:4a:87:45:80:7e:de:ea:97:68:e0: a6:7d:bf:80:24:79:24:c1:61:6d:54:ab:14:4b:5a:54:cb:75:
2b:09:5d:9a:31:6f:f5:78:22:c5:66:2a:99:70:9e:6d:c4:ab: 47:2e:e5:51:6f:cb:91:b6:a7:e8:aa:8d:78:c5:7e:05:56:3b:
f6:90:01:70:53:07:66:6c:a6:b5:ce:4b:36:05:83:87:0c:a7: 31:02:bd:0c:e4:af:78:27:7d:6d:bf:fd:0f:0d:2a:00:1d:cc:
e0:1e:34:d0:5e:76:a4:20:71:cd:9d:c1:ae:82:27:e0:6f:16: a2:34:4d:a3:9e:70:45:89:56:2d:d2:35:ee:26:ea:0f:9d:fc:
57:74:e7:63:9f:d0:3d:72:91:6d:97:a4:82:23:84:dd:6e:0d: c0:2c:64:f6:55:af:de:e0:72:64:e2:20:8f:e2:f2:e9:e2:6c:
da:43:00:a7:ce:2f:f8:79:04:67:6a:e5:b0:ab:30:d8:f1:90: 3a:0c:45:23:dd:80:57:25:fa:18:bb:25:f8:7e:3c:3b:a7:ef:
10:43:3b:09:77:27:34:a4:d4:c0:25:4e:21:32:a3:ab:60:1c: 40:f0:ba:6f:ce:b1:eb:f9:14:03:04:34:3d:e0:43:a6:8d:95:
9d:6e:e2:65:39:51:7f:cd:9f:88:3a:7e:f4:38:af:7b:5b:a7: d0:a4:dc:df:e4:79:ce:8d:e2:1e:30:ff:55:0c:e6:9d:e4:1d:
bb:7b:70:97:21:59:fc:5c:55:a1:db:74:0a:37:1e:33:97:5f: 62:cc:a5:4f:9a:6f:c0:b4:1f:05:7c:a7:c7:b1:72:58:98:ad:
70:32:98:b3:d9:99:4e:08:3c:de:01:82:17:9b:49:d7:fa:c9: 2f:f9:8a:41:0c:48:d5:78:ad:af:eb:ff:59:0b:4a:99:26:5b:
45:8d:93:cc:42:d6:36:f2:39:3a:47:28:3f:6f:6a:e5:23:f3: e8:8c:e3:e5:6b:01:d9:a0:db:a2:1b:d8:8e:f1:82:38:58:ba:
5c:d4:a3:1b 8c:11:65:36
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIE4jCCA8qgAwIBAgIJAIGdQQ9AVaxKMA0GCSqGSIb3DQEBBQUAMIGOMQswCQYD MIIE4jCCA8qgAwIBAgIJAJKhO9OQC+qnMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYD
VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkx VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkx
FDASBgNVBAoMC0VuZG1haWwgT3JnMQwwCgYDVQQLDANNVEExCzAJBgNVBAMMAkNB FDASBgNVBAoMC0VuZG1haWwgT3JnMQwwCgYDVQQLDANNVEExCzAJBgNVBAMMAkNB
MSYwJAYJKoZIhvcNAQkBFhdjYStjYS1yc2EyMDE4QGVzbXRwLm9yZzAeFw0xODAy MSYwJAYJKoZIhvcNAQkBFhdjYStjYS1yc2EyMDIxQGVzbXRwLm9yZzAeFw0yMTAy
MjcwMjMwNTVaFw0yMTAyMjYwMjMwNTVaMIGOMQswCQYDVQQGEwJVUzETMBEGA1UE MjUxNzQ0MDJaFw0yNDAyMjUxNzQ0MDJaMIGOMQswCQYDVQQGEwJVUzETMBEGA1UE
CAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkxFDASBgNVBAoMC0VuZG1h CAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkxFDASBgNVBAoMC0VuZG1h
aWwgT3JnMQwwCgYDVQQLDANNVEExCzAJBgNVBAMMAkNBMSYwJAYJKoZIhvcNAQkB aWwgT3JnMQwwCgYDVQQLDANNVEExCzAJBgNVBAMMAkNBMSYwJAYJKoZIhvcNAQkB
FhdjYStjYS1yc2EyMDE4QGVzbXRwLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP FhdjYStjYS1yc2EyMDIxQGVzbXRwLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALijjXkowR+cEXRDJuE7zBSHW2tkTO15G38qA9B7756IsGQ27ljv ADCCAQoCggEBAMyMOb3PVU9mKnjHZUeB3dE/CBJLh0BIlVwkUmWhghz0kKF89yeP
/dnHILNx6W0ep7zBfDv+KuQWL7zWLPWY+cQhHMrDfleJyKkv2mubUtbJnZiXbQh8 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
I/Nc1KMb WLqMEWU2
-----END CERTIFICATE----- -----END CERTIFICATE-----

View file

@ -20,6 +20,14 @@ This list is not guaranteed to be complete.
then it will be truncated which may result in a syntactically then it will be truncated which may result in a syntactically
invalid address. invalid address.
* Berkeley DB map locking problem with fcntl().
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
versions). Alternatively, use CDB or an earlier BDB version.
* Delivery to programs that generate too much output may cause problems * Delivery to programs that generate too much output may cause problems
If e-mail is delivered to a program which generates too much If e-mail is delivered to a program which generates too much

View file

@ -10,8 +10,8 @@ OPTIONS= $(CONFIG) $(FLAGS)
all: FRC all: FRC
@for x in $(SUBDIRS); \ @for x in $(SUBDIRS); \
do \ do \
(cd $$x; echo Making $@ in:; pwd; \ (cd $$x && echo Making $@ in: && pwd && \
$(SHELL) $(BUILD) $(OPTIONS)); \ $(SHELL) $(BUILD) $(OPTIONS)) || exit; \
done done
clean: FRC clean: FRC
@ -24,22 +24,22 @@ clean: FRC
install: FRC install: FRC
@for x in $(SUBDIRS); \ @for x in $(SUBDIRS); \
do \ do \
(cd $$x; echo Making $@ in:; pwd; \ (cd $$x && echo Making $@ in: && pwd && \
$(SHELL) $(BUILD) $(OPTIONS) $@); \ $(SHELL) $(BUILD) $(OPTIONS) $@) || exit; \
done done
install-docs: FRC install-docs: FRC
@for x in $(SUBDIRS); \ @for x in $(SUBDIRS); \
do \ do \
(cd $$x; echo Making $@ in:; pwd; \ (cd $$x && echo Making $@ in: && pwd && \
$(SHELL) $(BUILD) $(OPTIONS) $@); \ $(SHELL) $(BUILD) $(OPTIONS) $@) || exit; \
done done
fresh: FRC fresh: FRC
@for x in $(SUBDIRS); \ @for x in $(SUBDIRS); \
do \ do \
(cd $$x; echo Making $@ in:; pwd; \ (cd $$x && echo Making $@ in: && pwd && \
$(SHELL) $(BUILD) $(OPTIONS) -c); \ $(SHELL) $(BUILD) $(OPTIONS) -c) || exit; \
done done
$(SUBDIRS): FRC $(SUBDIRS): FRC

View file

@ -188,6 +188,182 @@ mk6wxhyuojEHuR7it6IU5BP8vaAGrL1jb1c2EeAe+pdJwpAb1Aq6MU6uWqOGup8t
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----
pub 4096R/4BEE1BEE 2021-01-24
Key fingerprint = F4CE 2263 2102 53D6 A9F9 79B0 4C66 EA8D 4BEE 1BEE
uid Sendmail Signing Key/2021 <sendmail@Sendmail.ORG>
sub 4096R/A9C0321B 2021-01-24
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGANHTwBEACw6b3NmDyyB6uPll+h+pyOmQrbX+up2S007yTXhj2EnYiriLcL
MdMspVLXl/wtABtfTZ9Lf3v3FuNwHZsVdSZWCFmwlWPptsRrF0VWwYBzxgH6QIUK
Qx9sFAD+KVD/9Cfl7YXeu5lZrNn3D8FoQB480jJJRaxshXcB6y9QCyKHeCZx/3Ct
1TE/tlFOgGoKJzNADOimH5SeEZ2gHhB6WB/yKLQYWS8EAvTlGdgZVo6VY6Ar35cd
3Z9TCQxS8YDsA0p6zENCJ4QgiwolmgZHa4R3/9jObxhVrIpCKCUN+rSdmKDotugP
GPDyZ0rZRAaRlyqt3rYKVAztkLTU6TbDNLmDpw3CQv3Tpbb2TT39ySmruVVJLA1C
DYQrh8f35ic0mDwYxKA5KIPZNj9vcReVrwxPDAV5to4n/ZjNNfnqxRiiq4+IzGZ4
dTlwh4pECps0WdqphLAoTotFcdvYg8cfHMBULdIGqciAGfu7G0yqvlxt4nRe1k8D
60yAwDtqgO3ThtiTzuYkHZAUmAYOBYPF4e/X/zicWoL+whirV6AELnmv6lft5TaW
UfXbcx0njY/QPa1iy3g8qkQcY8durY9OVYnA5X4von1vMC4naEEf/cFsdDBl+nZG
/XxBHr1QX5/P7egbnnF9qMqry856oPE8bjv1KBqZ52UxmGRl14k8gKcfowARAQAB
tDFTZW5kbWFpbCBTaWduaW5nIEtleS8yMDIxIDxzZW5kbWFpbEBTZW5kbWFpbC5P
Ukc+iQJVBBMBCgA/FiEE9M4iYyECU9ap+XmwTGbqjUvuG+4FAmANHTwCGwMLCwkN
CAoMBwsEAwIGFQoJCAsDBRYCAwEAAh4BAheAAAoJEExm6o1L7hvuZlcP/1ipTzk+
UT36bM/DbeBHaGhQ4yOSg0iiHzu+bzzP3jZslG7rlLgzowEPk7plDlnVbY6MUeXQ
4hO7keoAn5Cskg8jsrh+kpWYlNTPPKFdjgcuWbUEVAoRIprq1kEVqcG2ai0t1iaH
CmrUwFRqCCEPoHKg1U2GKcKafFaxOZwM27kV6yTLM5sYFVsoSh+bJ7sa9hymdwrf
/d1Rh5E+MHJatn3TXGh06aPkVGozyufTXipsxzd5VaBjLDTYbMFkiOt9MC9Sx2IS
BO5Ws2tOlNslGiAeXQG8EaJB4xrvhOi4i99nBA5TYWVdOAwfJGUZ+X4hItMwlCIg
4TaJcYHQ7GASELGSGA7azd2JeqbEskiCdabWF8aSbUxA68HRCOjAAUk5afxqEc5J
BVfT1QmWAPK5cNQTojbd7msrlGXmcSQyFBUDSzoeQNFhpmDpAXCLnGt0vcwbqTik
Ft+2vJ9nbSczKHkxmN1hudpVdsUNfgGi7p4VzyQq/OzYFVeMXrBBt6aLyATjCoY9
b7chMDyJBFLEk47U0qQe2VhexI8Fk9Z8wFTPF97gb3rSk5pAfIbCZ9eDcIZuR5eD
yDDd23vxsMJK0haD/nZ6gQNqBeCg+zDE8g4T9zCdOtavLuqwOqPUZDnNdke9cA0m
6GSo2MccibyMdqijETcDOPOC47hrIu68QE54iQEzBBABCgAdFiEEsICXn00EPhnQ
WjacYp747gyLgzMFAmANHmsACgkQYp747gyLgzP1zgf/QJi9+sMvoNVks4+lU4xW
9fy4C7+fAO96dJtSO5jSn+9M/C55UmU0kWz8XEU88XCVyChLmpSb+Y+2sf5XhWEY
+KDLUHgqiT6NItozXKVggNFMsxkzDi7mzdkCIevTlcGbQSxai7hbKwZzGPb/OzUK
pRtLl6hTV5wLlsit41EAwILnRmmn6Iix6SPaCx0YvAIKBiy7CSiJyhPbGEKAeEx9
OTZ9ce0iQWxaCGNgXv22HPvJ7V3VwmfZBJnHcY0ooxEjz/Ky9kHXc+3yHznlATXs
pzOMH0z+zmHldvIBz0djgVlhn2TRkKSSTaGd4kbLKLmci4Ax/il5noR1hZ82aVhl
TokBMwQQAQoAHRYhBLF1lkRTA13O3XvpGWBN+/KFQQq+BQJgDR6pAAoJEGBN+/KF
QQq+4OAH/RpvOktec2Y0AvzWjHorXWmPLi9xEMIuj2GVVVsg+eXP2CDpYuEOVYLP
8VCWpObXADj+w0DIOMcyqUbMPxkps+CPXjTRc/qED3FLvGNTfNQMe5hDTbbs/tw2
FtfI9Jzlwsmhcfg5ZxnQKDCPGPQufN9AbQHWc4VIEwhQRc9T/cfBhioWUwrtkgPT
BBTPnJp/nA10Rn+ycURA+BLdlhAFwuTYBH7nWHkDJUGLHFIat2RhHRakZNhcMrhE
cXBrg5ONK9qJYtJXzlHiQhM6NP2RPVvYCzLlqkT13SqvLsPMSncyKlIlUuQZqdcE
QOwGRgp2jkZeRYVBYfFzfIpu5gxVQYOJATMEEAEKAB0WIQRYcmIYqRNADeZgNgE5
pMd9qXiEsAUCYA0esAAKCRA5pMd9qXiEsAB0CAChpLMwocSQ6hpY7nfVl6wAb3SP
9C2Dwr89YxzqBYS7i3b/0pB4t1c4cg0vC72DeOIUwuAwUOq6NVgPYnh/NpovWouP
HN/3WrI013yGkNZIYz3fb8w2+pk0FFndU121pn3IbVYyMxegyHyN+F5NKZCfsTu+
imlqje26ecBPuz4wcVqYyl/jnR/MU54uMhQW8q0lxCMS67uta0wd2EaTXNxq17Lp
Z48pNOBiAXxZnXaP996T+7whtLBr9isgeZyeizenjupX69bllRVbwuO8uboTsisC
LlUbOLzdvTjuSrAQAzNaAfVjNsxzEvLcxxKaPKPG1ubrHT50k3zpB/Ixi+oliQEz
BBABCgAdFiEEynqPOaJBn/+wqasnjlrp+87u9DsFAmANHrcACgkQjlrp+87u9DtA
kQf/SLAdxTmR/l95WdeOgvxINcV5ADxCkpO1iJeLp440uddscRrrfHdibEngfAA+
ARwPv2/jhJgInCOQe+4lmsd+4NtKtanXiRZai1MXCxcF5VLTOMs8Vl7EUMAL5JWG
IlvmT4/H7Zhji64KpDFkwEjsE8SdZ6HJokJMFSq+YYBgvnsu/GDSfDpb/HtdM845
pjxHJ+r93KPRepncLedgyDsQpzzRIgUJNhuC+UGtRp+3qRf1eWSkO6qbyL8DtFfW
WwX1gG099nr8m9Gj+R8zH6HTnWWuFnUyDTHdTN7/25vZ9eoAgjIx0I3g+O02l42B
G5HeOuLSMdUoqqvOq8313wvWSIkBMwQQAQoAHRYhBLh9RWmG8ZSEB+XMtD1osl1S
B8rTBQJgDR69AAoJED1osl1SB8rThsMH/0JcgLmhr3K4t0cxt94u6UN1pVQZDrgG
uMEDpOxW4nPMwN3SkWMM3K7zw0TiGkksyFifRi7zY1BqRilJOGyLkyB3zCY76hKV
SuLx3U4B6eyrAY8gsPownOdY8FJB3o27uXhPX17qLWOl83/GQMoyRfmmwkBnL4hc
puJcPT4bOt3OhDK7bs1vGabS9L3HuX0lUIcp8VKquJHXgS+xIr/lMBk5Jit1Qx/p
VjqmL2qIxTMubmKxU5RxsCZygdV92kBLzYqZ3JO6LOPCwD1a4fZRlwAW2hpC2gtW
KHK1/QZBSgJGjJUgXGV3fYYR3WH5qmTCAWu2HEloLRSdzdHLldWCsUOJATMEEAEK
AB0WIQRJ9qi+hHM5SVGRbzth3hHs4nY6cwUCYA0ewgAKCRBh3hHs4nY6c4ygB/44
pigG2UoBQNZq7R9ajbU5nRkl9mVCZ4dEqY6i3QJs5tGew+r774jMouL/sBTXMnvS
zD1XgJevJYnQq5U/08zvYDvqrhm4yTkbgg9UqhD9UI8M/XgN0DtbFT6EU/N92lO4
2xWBMTyAwjVl9JPPjhMoUsGVScZ8pjplJZlgJNuy8GVu6vUoW8j1Gw0jIPKJ0ufy
20uc4jLuKVmxjj7Z5NsFnWJtiFFq/TknppOQZ8KvZjVzrH6EIOmCJfCnuSATiVsb
YJzMAjshhG+fJsm24loUjmDDAzy4Nwf18IJb+wSe1oFCSAz3euhIAIxBFkihA8wk
G4QmCnvdbPfYy4WIMDNEiQEzBBABCgAdFiEEMLynRwX6QVRVcx17qvW13gW9zFMF
AmANHsgACgkQqvW13gW9zFNuYggAwSZ7y+qCvdvFu6LD4qvk/phRF5VINZIHfl1k
aOVQWA+DZaDM8lRsvn2lxGFksaPzK9ZXd5QnF3QTlOkEsCILE1tmL7Myob27PaGV
4mQXjY9bUXe/Ulj4VbHlWjkt5wpwGj9bRuxnn/RKKRNCpknzqv8VTCMVwUyCF4xE
P0BGFXiyPV+PTNN2GwV5l46zn1FWzTlSgbAxjwQBh43RMuBWG320w+YEysJMs4y9
k0f3i16hO4G/MiD4WRIaohqjBN6ii/sksYf6mgsZieUlAeQPnovi8pScq6s2cYzJ
krZNxX6PCNQFTLs1GvLh6IQgypN9Lxxu4FW82wKQMS9yIKkIMokBMwQQAQoAHRYh
BA9clq7I5p6cjlQuXG1M0ZQp+wPeBQJgDR7SAAoJEG1M0ZQp+wPeFfcH+wUQdI/R
eMuLByF9cjdC0AfnOXD46azyt7Lgyzdi5OK8xAMmfTGH0iYGGv3pNfcbTxblJ868
PPjUc2arF6CkLZ5hIQ6dUBmmxG+YOecOZF4jO6Z0WFi1XqxRomhy0m9TNQ931I88
VRpd0/XepnvJc1lTOiTmxKTFex7mKqzTNBeXlNkVOXpM4aCq4AejEgnEzr5imfyF
P2qyITbyGpWrnTKtg4ASYWVU+JAZ3/eZIl/0pNuD0/C9MGRmS2yGM82KKMYrRV3X
QNAdg6LPi8MicUZWlcVYqR/7jEkJeppUpM46EtEo5YoXQR9UflSdu1xjpBzgU56d
MjXtTE5ROtVDl42JAjMEEAEKAB0WIQQ8ih6Of0TK3hFP7UZLyb2ma/cmrQUCYA0e
2AAKCRBLyb2ma/cmrdDSD/92AidTGYuf+D3SbIOBhQttWp3SvnOj5UuqgXtHrmuq
vbhawUAAby+CL0hMOqYk/Z30N/Sr+OQmNyH+Q1C4nuoq4KOINBuaKpcioQai/Jre
TthuVzeFDk33bQd+IQ4n0WXnVWg0DlpIhDDtZyA2Qqj4nPPsnjuw+Y62VuXFahr1
ci+8sVns9VZJyVKPzGAKo/4rKjRlAqqVTlh5/RvMJ01TvWwSXSg1+yM08e/zaOCz
tuIfZAjDZNqXKIU+3xlKKvQGnNxUB+Bxn6ZaXW/YCzf/uabYfy2i4GIBhyj3dRSH
zbDSg0b/l0zJDIi6qzTzXZFEQr5AFu3CZeLR8maRU/1olCFR2aE29XoAtEF+SyPh
eI8ZhXqL2ccJqStD37TMsUmemTgBkH1Rig3eelRDeaZ6oh5UjuKcg7IpdmyYdRNE
5KO3afHdhM6C/CXoh689273ddasvdYcGCIYku6AjiNjcr4sNbGdmqDNc/6emHqp4
WxyKfc5AuqZpmbEVhIYG1PTmldJl78EZBYoLjea6fai+6LH3c75p85lUWbfcpq7s
QczweRPz/X+YMnNpCo8+psngSBIjDiJF7JFrVCFPyH8zFbva/TWCZ3Cf8Z4GLm0d
e1gBJfFeXaQHHL2qaX5FXiYqwL2cjmr09lV3hWmQC9bA4q7Z/q2BEjZtZuPJn/qZ
NIkCMwQQAQoAHRYhBKaHPSSk1tYoSuQqdfBgWf1dx8w/BQJgDR7dAAoJEPBgWf1d
x8w/SdkP/1uvi7L2ZVvq564VXA+5YFNq+BvzMDYkf/8RaAAFFUVbblQQBjlHN8nA
ViZZepOJOmba639e8E/uXsXF5z0l7Y1XEiuU6xofjmX8i9Px3MG5G1mXQGgaozW7
fimU81f5DlLFv3W9lrZ1iQdpfZQYpBMdE6PuBl4wvElHPB6rVTxBIigjVsQceXMV
b64RttDSX84glqv15rTrPQLPg5duX+YzMOVKyH7tWuuOsPuWaUZejNieX7UubA4s
E1pnpH0OBpw/d8r0Rte9ZifmSavfPygaLC3w5ihXKwPLVikhOIF7PgsVaRRBzJQL
pw7BTt+nGOZIQofW1TM8gOPPrbWzwyCnPEMzjyM6g46zsW8FRxTq8/qRXwB7dg9v
wZRVSX4+Dzuuvyt/p3p8OX5nhv2UrqXSeZx5gcWrof+td7X8lGj4j/kvFI6lotqL
+DTf4ndH8OyVjVL3Kzdc6e1+F/odgjurPW20GiNasLFpRz7aNUTtoSMc1zHi7tmW
EB0HMrCvdTwUuDOHVcebaR0xOPVcPcJhLoJDDQPRCFC93RvWL8qf5XPXwxYu9+tk
Kx22lFNJqnQeYH6s0QqJowcGwchpM23JlAyQ4y8qCb8Rng4V2KvmonWO5iadM+/9
sNFmf7APUzeCMP0LGO+YLKgf3aPe2lQZOF3nQXpQ7iSDW33C45QpiQIzBBABCgAd
FiEEUKMDCY6i3XvL7iraCeAfoDwMUE4FAmANHuMACgkQCeAfoDwMUE47RxAAsbz1
94m0hNMFUkzXc947B9qozcQMQJRhKsouBaMMwR+F1RgLH0oSAhYESsl+o8ngsyTo
AKYAP5p/N/wMzSZY0/B1XoQkTJT7HCX6G1gBKr6C5US4wL4Y2xQtBBVipAONK21p
RiSVUcvtOVfdUTSd2NNBUcVq9NCnWjtawu+8Z8fwJYa74gy8u9QQi9QjNPcupz63
PKzB8WG1NjEI6Jx1TkZbGLoyXDQ/J7lfnoqGQoqIXMJjQHiDuNV8gIaPo2isHx6H
VOXYm+kx3mG/3cpTlWS1yfehHPrRYg/CB6joHYUUu9oe8HI1C8GF/4VxRsW6bfaZ
6rByBoPiCIb39xTLyCASXrXZ3n5wJ2blSCN3GPRxOcrNKQRgfNiXEc2jZtVA6sKU
a5DvvHYvIBqD6M9E8hPd5EomOW7t8zNCaFCvqWOanMmJmCqSlgSavZqEMOyTvcOM
ARyjZBseIIQZxwcfiKfJyI17adP/0fRdB5ypUUGaLPcbdh7JWJHzEbplGPj9VHrX
+xBN9fk2l8iXwPxD85C7lvup4SX+HEav3ofIJSrL47yC0DDrmia/JS3U/omD4raL
yfLSoVu0Qf6G6Z1MSLV1sfaMLNWssuwKYx2wHEsjRoURlWuQVR78KuCE8x+GZQ++
Qa75Wuf0h6myzktUkfvddz6oW5W2yfVbAkuFR+yJAjMEEAEKAB0WIQSt/bcJ/h6m
guWFWXHVgyEO9RRxpwUCYA0e6AAKCRDVgyEO9RRxp277EACTAyRqNIaZPaSMAdw/
AcYNX+/0G5+3m2+baSEPjcJUYOdwqQeUFAFZ3Sf9H4cm4zfNafQ0AjWUm9NYpwt8
YKhN78dOpFaNdER43SAjVGmJb7Vs/yEX4EQZ3j7uRtypwAm6tehdo8kiKtMr774H
DZHGUp7NYdbBnCwiQWHFcwcK1ZWdgIY4Nw61pK5/iDl0ZIOZDXPgZWutB3ULNwBg
2PHBLOJaSvzl9jhC7Zjgpus6dEiTU/Ij6dKX+U0X9Hh5c2O3FQ08UwBffTBjTZTm
ThXGN8RN3a3cuBlpP5rTArU412yV4/+GkDPP/hv9iAgRAhwXomskyoC1Wq7I/1O1
Ipzac19walDjLDvIBEVZmzi7YODEMU0F/EobW6+aByp9/cBGlBBn2Ppy+RQRevHm
Lf6jpvHcmdSEMvIDXDDJfUHVYfcpVnZJ3LfPE1kfdOhOKpCju8ZF9OPHUokhjKRM
frKLWOD2rxNQmqrfhvVsh8NSBNNaL9NkwnwevGo4ap2PaKwA2gxzZrMSrH3au9jE
K9+pnE94hdhRRfKINNME5r2Uo5Rcs6OIiuDM1wCmrIT2f4n0imXJoTiA/jwHWFAK
27EPnxXWZkbjR/oiIm5vaKqB9NbZDVtTw/4H7+pQ3E47THD+KY718FVUuV3cnOtM
MdoRGDkrd8ZS/I6ze7pOnCJy4IkBMwQQAQoAHRYhBK0g4aqLQTZwpkJS2L0nbS5v
z6iFBQJgDR7wAAoJEL0nbS5vz6iFz58IAIJRgMKRz4cOUy5iIPvtswXMb9tFR37U
PyLGJR1CbclXwUxTe6brN+8kWGka/g40qoG0Wr6GgQheYBjmV1CvXwOvZv83/FkK
GkGUZDjNhbfSXlrBMUczUEk3d6w2h8XHOoHozmWgf7fJk06MIJAwEt4ENK3Bfm+k
CCrCJuma8WzccyBLyU2iMLS14w7GOxJVyV37L8XcwmhysNyCpF0TVLPlPeGrvHO3
hsw+lJZiZeXKUrU2hnzoM29A71PmkLVUYLN1JzvASwWCVsMfIO5T/bUzSLBysuEU
msqRL+vJQvzNDJs9gVrAtCnfZRQFHRYVYHsqqayhsj3/mk7x9a8Q6ZCJAjMEEAEK
AB0WIQQpbJTb0CgCRb/Tkdd7UpZI7oVyZAUCYA0e+AAKCRB7UpZI7oVyZKXLD/96
55HOR12CYECMhU33Y5fqs10tYTdyoJjjStp+t2oApyaswr+DQPs6UVFUJWgMy478
ro2DqW9kYHZeX0BumiQ5zrCeyBQYU+RUUNH7MU0pzdGuYWiL9PXqHNacuzV8GrIs
r4NFB1SJ66nbaKRMdJJnnfvtnJyHPfJ2VloxizYLNYptKUVbcP0j5ahXPbhy6Cyy
qlsAK28/gSRhDOqdq4/mKcNrc656bsmOqoaOl5po1N0sGStYQCuFWKjawujG5ZvF
x4hbwJUSU5gOFrBZgm2cYjypIO/GQz6CYbhGt77qV7f7hzo9qwA6UeIqrECvr83W
Jtp4e+FnjVQ6AfSwLI8oOPRa6DvJDdU+EGYPaWLbXnmq1fMu1nNn9SfHtkR+uDlN
GiQJk9EZSz30msacuEXZlXiypA2zTQFYAvtBZmYR4qjBX0qHImqmukjZZFhJ0sxR
LXE66HgvdxMTbYCVCWJY6u21yXF0O0a+nEvx0v1doux1247jzGXwyQTKXZsUZhv1
qLv8igtMaJkSLZz1E1U703PdsMhU9jH6RKlwkW3KI/2NHEsxw7nDuhS6ez0UIM6O
sur53HCnDcA7k9eUaa+Sm0yCBeccZ9zmUgG2K3cFKdpQlljyt4WJTsKDrK4AkAHR
FjAJ0wOvv4apnz5LYNobKc/oTbjJacbTczB2lwGe17kCDQRgDR08ARAA9XG4WjRg
7cOfk6ur3Tj0TsmoiZ5jDKQ+ObZqk2aeIk5WutraEFe0OkI46F4oEbIwLB8rChHX
uVq18EM1mDD99tM3xTUoSm6BCdQeNx0Hh6enLZK49LBSMqTn3Fd9PNLL/QBABYWc
wgrazwxOlTrLOpX+XcgvRuxK36CisNr5i7Ocuc7EIuUurF6YoSaaxDT9XZHpuSSV
AI//sH+GmeBVgIs6f+8MSGe5R4g3aiyYqykwMtgSVgKqxi6Bo5UD8HeXpEAIgtNT
2gOxLgvar6vwlbTFamv+vy4C2RXY+7paEjGnlwI4nJrIWh0c1z3qIvAkEzhN88/J
fVCtjtKFjPAhGf48LxnRnURGb9anyexrRTPkGcmxx7/sxGMe/M31lpHOVKUZduWV
83/9/7NpSWU0BRmWyzK9CzQC/97Vb8JJhZG3N7RmTZgiO1GKAWFAKgd6X6oo6O/V
n5zngHY3jfKkb+wlcVa76IIDv3dc3JIENkmghfvuzdrx2IIqK+NSrBzp7OeTtgJE
vR5yTysS6wdlihY5zJgIBJh+GAy7lA8gzB3MhZe/qPSvnmK3ZTb1RnM5y5ySMZsU
mZnUVqjqjgUbY7NdXRpPeYLzwzzsvT+vlQX4P7LjGaienI6EP+AO7v2Ei+zv1NMI
jkXPPNtPwp01B3M09nYihjDnM/dviPF8J1sAEQEAAYkCNgQYAQoAIBYhBPTOImMh
AlPWqfl5sExm6o1L7hvuBQJgDR08AhsMAAoJEExm6o1L7hvuW6gP/iTNEyA96lc6
3WxvkrpqiyZN4vdDwWv9FoEuZohlOCwQZpQy8wZlbtmjYcKAz1mRF3uBqZRvgzu4
7ggzny8lF0m93PnyroRO5O6I8lT95HWH5+7mcoYpbDY1XII+QbP+Xdxi2mkUXqkY
3TRcp9VzwWyQb/0sgGch7ZOnd7bK12Q8wd2YmkCq5dQ8BXxFbnom6VoRpHnu1AsU
6ZKYbK5ogKXUoBxYKRqX6vMxMjALd/yJFKZwrCWkOxj0ipXCgHOlqbqgi5wH/gRu
qGkMYJ6fAnVcEdyfK5IRrtMB/3ZHlIDFXyEIA+K0AxpqE098KwnemOjrSYZV8Ek5
48tVsKlmqqgJ1QkacR54OLw9CjNm0bXX1iqMfR89NfdIWqfyq732vqKb7UDfcjOK
IV4VP4sS8rBNrlzGpnkCOejE6YqxqwUt9ggtk9Q3SjqTrPTDZ3hExjcigchwnG5m
rZzBKYo7vQxoK+Y6Kx+BZHo2tUloURtsgqW7mLrfbY68Vbm4O1Ev5mjWA4bmOTrD
ivZF0HKBAdHG0B8JolpbSmoPVB0V9UAQvbb/amMK1zo36/cDrSZ9fid3Pbwyuupg
058rgvZPvBknm6p+k1mGb9XBGJlJaOR9Q0cmKobZhVmnSuCkRBJdLixHRvzcfygi
ra/bqVWSpZTlHZ0xT9seCUSs1urxGw9Z
=3HCo
-----END PGP PUBLIC KEY BLOCK-----
pub rsa4096/0xD583210EF51471A7 2020-04-08 [SC] pub rsa4096/0xD583210EF51471A7 2020-04-08 [SC]
Key fingerprint = ADFD B709 FE1E A682 E585 5971 D583 210E F514 71A7 Key fingerprint = ADFD B709 FE1E A682 E585 5971 D583 210E F514 71A7
uid [ full ] Sendmail Signing Key/2020 <sendmail@Sendmail.ORG> uid [ full ] Sendmail Signing Key/2020 <sendmail@Sendmail.ORG>
@ -3715,4 +3891,3 @@ Nq5nZ04BGHdVToZvUf2ABdQnWx94uOCRJp2bLJiEepNtaL2OPqe2EQVF7ia2Y0PT
q8WNeh9erYZriQ== q8WNeh9erYZriQ==
=VuMX =VuMX
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----

View file

@ -371,11 +371,6 @@ for a response. As of 8.10.0, the default Timeout.ident is 5 seconds
as many sites have adopted the practice of dropping IDENT queries. as many sites have adopted the practice of dropping IDENT queries.
This has lead to delays processing mail. This has lead to delays processing mail.
No ident server is included with this distribution. It is available
from:
ftp://ftp.lysator.liu.se/pub/ident/servers/
http://sf.www.lysator.liu.se/~pen/pidentd/
+-------------------------+ +-------------------------+
| INTEROPERATION PROBLEMS | | INTEROPERATION PROBLEMS |

View file

@ -5,6 +5,121 @@ This listing shows the version of the sendmail binary, the version
of the sendmail configuration files, the date of release, and a of the sendmail configuration files, the date of release, and a
summary of the changes in that release. summary of the changes in that release.
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
to ANSI C. If you are using sendmail on a system
which does not have a compiler for ANSI C contact us
with details as soon as possible so we can determine
how to proceed.
Experimental support for SMTPUTF8 (EAI, see RFC 6530-6533)
is available when using the compile time option USE_EAI
(see also devtools/Site/site.config.m4.sample for other
required settings) and the cf option SMTPUTF8.
If a mail submission via the command line requires
the use of SMTPUTF8, e.g., because a header uses UTF-8
encoding, but the addresses on the command line are all
ASCII, then the new option -U must be used, and
the cf option SMTPUTF8 must be set in submit.cf.
Please test and provide feedback.
Experimental support for SMTP MTA Strict Transport Security
(MTA-STS, see RFC 8461) is available when using
- the compile time option _FFR_MTA_STS (which requires
STARTTLS, MAP_REGEX, SOCKETMAP, and _FFR_TLS_ALTNAMES),
- FEATURE(sts), which implicitly sets the cf option
StrictTransportSecurity,
- postfix-mta-sts-resolver, see
https://github.com/Snawoot/postfix-mta-sts-resolver.git
New ruleset check_other which is called for all unknown SMTP
commands in the server and for commands which do not
have specific rulesets, e.g., NOOP and VERB.
New ruleset clt_features which can be used to select features
in the SMTP client per server. Currently only two
flags are available: D/M to disable DANE/MTA-STS,
respectively.
Avoid leaking session macros for an envelope between
delivery attempts to different servers. This problem
could have affected check_compat.
Avoid leaking actual SMTP replies between delivery attempts
to different servers which could cause bogus logging
of reply= entries.
Change default SMTP reply code for STARTTLS related problems
from 403 to 454 to better match the RFCs.
Fix a theoretical buffer overflow when encountering an
unknown/unsupported socket address family on an
operating system where sa_data is larger than 30
(the standard is 14). Based on patch by Toomas Soome.
Several potential memory leaks and other similar problems
(mostly in error handling code) have been fixed.
Problems reported by Tomas Korbar of RedHat.
Previously the commands GET, POST, CONNECT, or USER terminate
a connection immediately only if sent as first command.
Now this is also done if any of these is sent directly
after STARTTLS or if the 'h' option is set via
srv_features.
CDB map locking has been changed so a sendmail process which
does have a CDB map open does not block an in-place
update of the map by makemap. The simple workaround
for that problem in earlier versions is to create
the map under a different name and then move it
into place.
On some systems the rejection of a RCPT by a milter could
silently fail.
CONFIG: New FEATURE(`check_other') to provide a default
check_other ruleset.
CONFIG: FEATURE(`tls_failures') is deprecated and will be
removed in future versions because it has a fundamental
problem: it is message oriented but STARTTLS is
session oriented. For example, having multiple
RCPTs in one envelope for different destinations,
with different temporary errors, does not work
properly, as the persistent macro applies to all
RCPTs and hence implicitly to all destinations (servers).
The option TLSFallbacktoClear should be used if needed.
MAIL.LOCAL: Enhance some error messages to simplify
troubleshooting.
Portability:
Add support for Darwin 19 & 20.
NOTE: 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. Problem noted by Harald Hannelius.
New Files:
cf/feature/check_other.m4
cf/feature/sts.m4
devtools/OS/Darwin.19.x
devtools/OS/Darwin.20.x
include/sm/ixlen.h
libsm/ilenx.c
libsm/lowercase.c
libsm/strcaseeq.c
libsm/t-ixlen.c
libsm/t-ixlen.sh
libsm/t-streq.c
libsm/t-streq.sh
libsm/utf8_valid.c
libsm/uxtext_unquote.c
libsm/xleni.c
libsmutil/t-lockfile.c
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 8.16.1/8.16.1 2020/07/05
SECURITY: If sendmail tried to reuse an SMTP session which had SECURITY: If sendmail tried to reuse an SMTP session which had
already been closed by the server, then the connection already been closed by the server, then the connection
@ -114,14 +229,22 @@ summary of the changes in that release.
changes in sys/sem.h changes in sys/sem.h
On Linux set MAXHOSTNAMELEN (the maximum length On Linux set MAXHOSTNAMELEN (the maximum length
of a FQHN) to 256 if it is less than that value. of a FQHN) to 256 if it is less than that value.
Added Files: New Files:
cf/feature/blocklist_recipients.m4 cf/feature/blocklist_recipients.m4
cf/feature/check_cert_altnames.m4
cf/feature/tls_failures.m4 cf/feature/tls_failures.m4
devtools/OS/Darwin.14.x devtools/OS/Darwin.14.x
devtools/OS/Darwin.15.x devtools/OS/Darwin.15.x
devtools/OS/Darwin.16.x devtools/OS/Darwin.16.x
devtools/OS/Darwin.17.x
devtools/OS/Darwin.18.x
include/sm/notify.h
libsm/notify.c
libsm/t-notify.c
libsmdb/smcdb.c libsmdb/smcdb.c
sendmail/ratectrl.h sendmail/ratectrl.h
sendmail/tls.h
sendmail/tlsh.c
8.15.2/8.15.2 2015/07/03 8.15.2/8.15.2 2015/07/03
If FEATURE(`nopercenthack') is used then some bogus input triggered If FEATURE(`nopercenthack') is used then some bogus input triggered
@ -335,7 +458,7 @@ summary of the changes in that release.
On Linux use socklen_t as the type for the 3rd argument On Linux use socklen_t as the type for the 3rd argument
for getsockname/getpeername if the glibc version is at for getsockname/getpeername if the glibc version is at
least 2.1. least 2.1.
Added Files: New Files:
devtools/OS/Darwin.12.x devtools/OS/Darwin.12.x
devtools/OS/Darwin.13.x devtools/OS/Darwin.13.x
@ -416,7 +539,7 @@ summary of the changes in that release.
Add support for Darwin 11.x (Mac OS X 10.7). Add support for Darwin 11.x (Mac OS X 10.7).
Add support for SunOS 5.12 (aka Solaris 12). Patch from Add support for SunOS 5.12 (aka Solaris 12). Patch from
John Beck of Oracle. John Beck of Oracle.
Added Files: New Files:
devtools/OS/Darwin.11.x devtools/OS/Darwin.11.x
devtools/OS/SunOS.5.12 devtools/OS/SunOS.5.12
@ -601,7 +724,7 @@ summary of the changes in that release.
Chris Behrens of Concentric. Chris Behrens of Concentric.
Add support for SCO OpenServer 6, patch from Boyd Gerber. Add support for SCO OpenServer 6, patch from Boyd Gerber.
DEVTOOLS: Clarify that confSHAREDLIBDIR requires a trailing slash. DEVTOOLS: Clarify that confSHAREDLIBDIR requires a trailing slash.
Added Files: New Files:
devtools/OS/Darwin.9.x devtools/OS/Darwin.9.x
devtools/OS/OSR.i386 devtools/OS/OSR.i386
@ -1825,7 +1948,7 @@ summary of the changes in that release.
Use strerror(3) on Linux. If this causes a problem on Use strerror(3) on Linux. If this causes a problem on
your Linux distribution, compile with your Linux distribution, compile with
-DHASSTRERROR=0 and tell sendmail.org about it. -DHASSTRERROR=0 and tell sendmail.org about it.
Added Files: New Files:
devtools/OS/AIX.5.2 devtools/OS/AIX.5.2
8.12.9/8.12.9 2003/03/29 8.12.9/8.12.9 2003/03/29
@ -3987,7 +4110,7 @@ summary of the changes in that release.
have a From line. have a From line.
VACATION: Read all of the headers before deciding whether or not VACATION: Read all of the headers before deciding whether or not
to respond instead of stopping after finding recipient. to respond instead of stopping after finding recipient.
Added Files: New Files:
cf/ostype/darwin.m4 cf/ostype/darwin.m4
contrib/cidrexpand contrib/cidrexpand
contrib/link_hash.sh contrib/link_hash.sh
@ -4004,7 +4127,7 @@ summary of the changes in that release.
Purczynski of elzabsoft.pl. Purczynski of elzabsoft.pl.
SECURITY: Add more vigilance around set*uid(), setgid(), setgroups(), SECURITY: Add more vigilance around set*uid(), setgid(), setgroups(),
initgroups(), and chroot() calls. initgroups(), and chroot() calls.
Added Files: New Files:
test/t_setuid.c test/t_setuid.c
8.10.1/8.10.1 2000/04/06 8.10.1/8.10.1 2000/04/06
@ -4109,7 +4232,7 @@ summary of the changes in that release.
VACATION: Fix -t option which is ignored but available for VACATION: Fix -t option which is ignored but available for
compatibility with Sun's version, based on patch from compatibility with Sun's version, based on patch from
Volker Dobler of Infratest Burke. Volker Dobler of Infratest Burke.
Added Files: New Files:
devtools/M4/UNIX/smlib.m4 devtools/M4/UNIX/smlib.m4
devtools/OS/OSF1.V5.0 devtools/OS/OSF1.V5.0
Deleted Files: Deleted Files:

View file

@ -1120,9 +1120,8 @@ local_procmail Use procmail or another delivery agent as the local mailer.
setreuid() call, you may need to add -f $f to the procmail setreuid() call, you may need to add -f $f to the procmail
argument vector to pass the proper sender to procmail. argument vector to pass the proper sender to procmail.
For example, this allows it to use the maildrop For example, this allows it to use the maildrop mailer
(http://www.flounder.net/~mrsam/maildrop/) mailer instead instead by specifying:
by specifying:
FEATURE(`local_procmail', `/usr/local/bin/maildrop', FEATURE(`local_procmail', `/usr/local/bin/maildrop',
`maildrop -d $u') `maildrop -d $u')
@ -1132,7 +1131,7 @@ local_procmail Use procmail or another delivery agent as the local mailer.
FEATURE(`local_procmail', `/usr/local/bin/scanmails') FEATURE(`local_procmail', `/usr/local/bin/scanmails')
WARNING: This feature sets LOCAL_MAILER_FLAGS unconditionally, WARNING: This feature sets LOCAL_MAILER_FLAGS unconditionally,
i.e., without respecting any definitions in an OSTYPE setting. i.e., without respecting any definitions in an OSTYPE setting.
bestmx_is_local Accept mail as though locally addressed for any host that bestmx_is_local Accept mail as though locally addressed for any host that
lists us as the best possible MX record. This generates lists us as the best possible MX record. This generates
@ -1267,6 +1266,12 @@ delay_checks The rulesets check_mail and check_relay will not be called
section. Note: this feature is incompatible to the versions section. Note: this feature is incompatible to the versions
in 8.10 and 8.11. in 8.10 and 8.11.
check_other Enable a default check_other ruleset which terminates
an SMTP session when it encounters a command which matches
a regular expression given as argument. If no argument
is given, then the default (to match potential headers) is:
^[[:print:]]+ *:
use_client_ptr If this feature is enabled then check_relay will override use_client_ptr If this feature is enabled then check_relay will override
its first argument with $&{client_ptr}. This is useful for its first argument with $&{client_ptr}. This is useful for
rejections based on the unverified hostname of client, rejections based on the unverified hostname of client,
@ -1578,9 +1583,9 @@ require_rdns Reject mail from connecting SMTP clients without proper
Entries such as Entries such as
Connect:1.2.3.4 OK Connect:1.2.3.4 OK
Connect:1.2 RELAY Connect:1.3 RELAY
will allowlist IP address 1.2.3.4, so that the rDNS will allowlist IP address 1.2.3.4 and IP net 1.3.*
blocking does apply to that IP address so that the rDNS blocking does apply not to those IPs.
Entries such as Entries such as
Connect:1.2.3.4 REJECT Connect:1.2.3.4 REJECT
@ -1603,6 +1608,14 @@ badmx Reject envelope sender addresses (MAIL) whose domain part
has been compiled with the options MAP_REGEX and has been compiled with the options MAP_REGEX and
DNSMAP. DNSMAP.
sts Experimental support for Strict Transport Security
(MTA-STS, see RFC 8461). It sets the option
StrictTransportSecurity and takes one optional
argument: the socket map specification to access
postfix-mta-sts-resolver (see feature/sts.m4
for the default value).
For more information see doc/op/op.me.
+-------+ +-------+
| HACKS | | HACKS |
+-------+ +-------+
@ -2581,7 +2594,7 @@ top level domain TLD, 192.168.212.* network, and the IPv6 address
2002:c0a8:02c7::/48. 2002:c0a8:02c7::/48.
Entries in the access map should be tagged according to their type. Entries in the access map should be tagged according to their type.
Three tags are available: These tags are applicable:
Connect: connection information (${client_addr}, ${client_name}) Connect: connection information (${client_addr}, ${client_name})
From: envelope sender From: envelope sender
@ -2818,7 +2831,7 @@ regex map:
# check address against various regex checks # check address against various regex checks
R$* $: $>Parse0 $>3 $1 R$* $: $>Parse0 $>3 $1
R$+ < @ bigisp.com. > $* $: $(allnumbers $1 $) R$+ < @ bigisp.com. > $* $: $(allnumbers $1 $)
R@MATCH $#error $: 553 Header Error R@MATCH $#error $: 553 Address Error
These rules are called with the original arguments of the corresponding These rules are called with the original arguments of the corresponding
check_* ruleset. If the local ruleset returns $#OK, no further checking check_* ruleset. If the local ruleset returns $#OK, no further checking
@ -3081,8 +3094,8 @@ Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org
(line breaks have been inserted for readability). (line breaks have been inserted for readability).
The macros which are subject to this encoding are ${cert_subject}, The macros which are subject to this encoding are ${cert_subject},
${cert_issuer}, ${cn_subject}, and ${cn_issuer}. ${cert_issuer}, ${cn_subject}, and ${cn_issuer}.
Examples: Examples:
@ -3223,13 +3236,13 @@ options:
- CertFile, KeyFile: {Server,Client}{Cert,Key}File - CertFile, KeyFile: {Server,Client}{Cert,Key}File
- Flags: see doc/op/op.me for details. - Flags: see doc/op/op.me for details.
If FEATURE(`tls_session_features') is used, then default rulesets If FEATURE(`tls_session_features') and FEATURE(`access_db') are
are activated which look up entries in the access map with the tags used, then default rulesets are activated which look up entries in
TLS_Srv_features and TLS_Clt_features, respectively. the access map with the tags TLS_Srv_features and TLS_Clt_features,
For example, these entries: respectively. For example, these entries:
TLS_Srv_features:10.0.2.4 CipherList=MEDIUM+aRSA; TLS_Srv_features:10.0.2.4 CipherList=MEDIUM+aRSA;
TLS_Clt_features:10.1.0.1 Options=SSL_OP_NO_TLSv1_2; CipherList=ALL:-EXPORT TLS_Clt_features:10.1.0.1 Options=SSL_OP_NO_TLSv1_2; CipherList=ALL:-EXPORT
specify a cipherlist with MEDIUM strength ciphers that use RSA specify a cipherlist with MEDIUM strength ciphers that use RSA
certificates only for the client with the IP address 10.0.2.4, certificates only for the client with the IP address 10.0.2.4,
@ -3240,21 +3253,23 @@ their own rulesets which must return the appropriate data.
If the rulesets are not defined or do not return a value, the If the rulesets are not defined or do not return a value, the
default TLS options are not modified. default TLS options are not modified.
About 2): the ruleset try_tls (srv_features) can be used together About 2): the rulesets try_tls, srv_features, and clt_features can
with the access map. Entries for the access map must be tagged be used together with the access map. Entries for the access map
with Try_TLS (Srv_Features) and refer to the hostname or IP address must be tagged with Try_TLS, Srv_Features, Clt_Features and refer
of the connecting system. A default case can be specified by using to the hostname or IP address of the connecting system. A default
just the tag. For example, the following entries in the access map: case can be specified by using just the tag. For example, the
following entries in the access map:
Try_TLS:broken.server NO Try_TLS:broken.server NO
Srv_Features:my.domain v Srv_Features:my.domain v
Srv_Features: V Srv_Features: V
Clt_Features:broken.sts M
will turn off STARTTLS when sending to broken.server (or any host will turn off STARTTLS when sending to broken.server (or any host
in that domain), and request a client certificate during the TLS in that domain), request a client certificate during the TLS handshake
handshake only for hosts in my.domain. The valid entries on the RHS only for hosts in my.domain, and disable MTA-STS for broken.sts.
for Srv_Features are listed in the Sendmail Installation and The valid entries on the RHS for Srv_Features and Clt_Features are
Operations Guide. listed in the Sendmail Installation and Operations Guide.
Received: Header Received: Header
@ -3377,11 +3392,11 @@ LOCAL_RULESETS respectively. For example:
Smyruleset Smyruleset
... ...
Local additions for the rulesets srv_features, try_tls, tls_rcpt, Local additions for the rulesets srv_features, clt_features, try_tls,
tls_client, and tls_server can be made using LOCAL_SRV_FEATURES, tls_rcpt, tls_client, and tls_server can be made using LOCAL_SRV_FEATURES,
LOCAL_TRY_TLS, LOCAL_TLS_RCPT, LOCAL_TLS_CLIENT, and LOCAL_TLS_SERVER, LOCAL_CLT_FEATURES, LOCAL_TRY_TLS, LOCAL_TLS_RCPT, LOCAL_TLS_CLIENT,
respectively. For example, to add a local ruleset that decides and LOCAL_TLS_SERVER, respectively. For example, to add a local
whether to try STARTTLS in a sendmail client, use: ruleset that decides whether to try STARTTLS in a sendmail client, use:
LOCAL_TRY_TLS LOCAL_TRY_TLS
R... R...
@ -4288,7 +4303,7 @@ confXF_BUFFER_SIZE XScriptFileBufferSize
memory-buffered transcript (xf) memory-buffered transcript (xf)
file before a disk-based file is file before a disk-based file is
used. used.
confAUTH_MECHANISMS AuthMechanisms [GSSAPI KERBEROS_V4 DIGEST-MD5 confAUTH_MECHANISMS AuthMechanisms [EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5
CRAM-MD5] List of authentication CRAM-MD5] List of authentication
mechanisms for AUTH (separated by mechanisms for AUTH (separated by
spaces). The advertised list of spaces). The advertised list of

View file

@ -100,23 +100,36 @@ M4FILES=\
${CFDIR}/feature/access_db.m4 \ ${CFDIR}/feature/access_db.m4 \
${CFDIR}/feature/allmasquerade.m4 \ ${CFDIR}/feature/allmasquerade.m4 \
${CFDIR}/feature/always_add_domain.m4 \ ${CFDIR}/feature/always_add_domain.m4 \
${CFDIR}/feature/authinfo.m4 \
${CFDIR}/feature/badmx.m4 \
${CFDIR}/feature/bcc.m4 \ ${CFDIR}/feature/bcc.m4 \
${CFDIR}/feature/bestmx_is_local.m4 \ ${CFDIR}/feature/bestmx_is_local.m4 \
${CFDIR}/feature/bitdomain.m4 \ ${CFDIR}/feature/bitdomain.m4 \
${CFDIR}/feature/block_bad_helo.m4 \
${CFDIR}/feature/blocklist_recipients.m4 \ ${CFDIR}/feature/blocklist_recipients.m4 \
${CFDIR}/feature/check_cert_altnames.m4 \
${CFDIR}/feature/check_other.m4 \
${CFDIR}/feature/compat_check.m4 \
${CFDIR}/feature/conncontrol.m4 \ ${CFDIR}/feature/conncontrol.m4 \
${CFDIR}/feature/delay_checks.m4 \
${CFDIR}/feature/dnsbl.m4 \ ${CFDIR}/feature/dnsbl.m4 \
${CFDIR}/feature/domaintable.m4 \ ${CFDIR}/feature/domaintable.m4 \
${CFDIR}/feature/enhdnsbl.m4 \
${CFDIR}/feature/generics_entire_domain.m4 \ ${CFDIR}/feature/generics_entire_domain.m4 \
${CFDIR}/feature/genericstable.m4 \ ${CFDIR}/feature/genericstable.m4 \
${CFDIR}/feature/greet_pause.m4 \
${CFDIR}/feature/ldap_routing.m4 \ ${CFDIR}/feature/ldap_routing.m4 \
${CFDIR}/feature/limited_masquerade.m4 \ ${CFDIR}/feature/limited_masquerade.m4 \
${CFDIR}/feature/local_lmtp.m4 \ ${CFDIR}/feature/local_lmtp.m4 \
${CFDIR}/feature/local_no_masquerade.m4 \
${CFDIR}/feature/local_procmail.m4 \ ${CFDIR}/feature/local_procmail.m4 \
${CFDIR}/feature/lookupdotdomain.m4 \
${CFDIR}/feature/loose_relay_check.m4 \ ${CFDIR}/feature/loose_relay_check.m4 \
${CFDIR}/feature/mailertable.m4 \ ${CFDIR}/feature/mailertable.m4 \
${CFDIR}/feature/masquerade_entire_domain.m4 \ ${CFDIR}/feature/masquerade_entire_domain.m4 \
${CFDIR}/feature/masquerade_envelope.m4 \ ${CFDIR}/feature/masquerade_envelope.m4 \
${CFDIR}/feature/msp.m4 \
${CFDIR}/feature/mtamark.m4 \
${CFDIR}/feature/no_default_msa.m4 \ ${CFDIR}/feature/no_default_msa.m4 \
${CFDIR}/feature/nocanonify.m4 \ ${CFDIR}/feature/nocanonify.m4 \
${CFDIR}/feature/nopercenthack.m4 \ ${CFDIR}/feature/nopercenthack.m4 \
@ -124,17 +137,24 @@ M4FILES=\
${CFDIR}/feature/nouucp.m4 \ ${CFDIR}/feature/nouucp.m4 \
${CFDIR}/feature/nullclient.m4 \ ${CFDIR}/feature/nullclient.m4 \
${CFDIR}/feature/prefixmod.m4 \ ${CFDIR}/feature/prefixmod.m4 \
${CFDIR}/feature/preserve_local_plus_detail.m4 \
${CFDIR}/feature/preserve_luser_host.m4 \
${CFDIR}/feature/promiscuous_relay.m4 \ ${CFDIR}/feature/promiscuous_relay.m4 \
${CFDIR}/feature/redirect.m4 \ ${CFDIR}/feature/queuegroup.m4 \
${CFDIR}/feature/ratecontrol.m4 \ ${CFDIR}/feature/ratecontrol.m4 \
${CFDIR}/feature/redirect.m4 \
${CFDIR}/feature/relay_based_on_MX.m4 \ ${CFDIR}/feature/relay_based_on_MX.m4 \
${CFDIR}/feature/relay_entire_domain.m4 \ ${CFDIR}/feature/relay_entire_domain.m4 \
${CFDIR}/feature/relay_hosts_only.m4 \ ${CFDIR}/feature/relay_hosts_only.m4 \
${CFDIR}/feature/relay_local_from.m4 \ ${CFDIR}/feature/relay_local_from.m4 \
${CFDIR}/feature/relay_mail_from.m4 \ ${CFDIR}/feature/relay_mail_from.m4 \
${CFDIR}/feature/require_rdns.m4 \
${CFDIR}/feature/smrsh.m4 \ ${CFDIR}/feature/smrsh.m4 \
${CFDIR}/feature/stickyhost.m4 \ ${CFDIR}/feature/stickyhost.m4 \
${CFDIR}/feature/sts.m4 \
${CFDIR}/feature/tls_failures.m4 \
${CFDIR}/feature/tls_session_features.m4 \ ${CFDIR}/feature/tls_session_features.m4 \
${CFDIR}/feature/use_client_ptr.m4 \
${CFDIR}/feature/use_ct_file.m4 \ ${CFDIR}/feature/use_ct_file.m4 \
${CFDIR}/feature/use_cw_file.m4 \ ${CFDIR}/feature/use_cw_file.m4 \
${CFDIR}/feature/uucpdomain.m4 \ ${CFDIR}/feature/uucpdomain.m4 \
@ -147,6 +167,7 @@ M4FILES=\
${CFDIR}/m4/proto.m4 \ ${CFDIR}/m4/proto.m4 \
${CFDIR}/m4/version.m4 \ ${CFDIR}/m4/version.m4 \
${CFDIR}/mailer/cyrus.m4 \ ${CFDIR}/mailer/cyrus.m4 \
${CFDIR}/mailer/cyrusv2.m4 \
${CFDIR}/mailer/fax.m4 \ ${CFDIR}/mailer/fax.m4 \
${CFDIR}/mailer/local.m4 \ ${CFDIR}/mailer/local.m4 \
${CFDIR}/mailer/mail11.m4 \ ${CFDIR}/mailer/mail11.m4 \
@ -159,6 +180,7 @@ M4FILES=\
${CFDIR}/mailer/uucp.m4 \ ${CFDIR}/mailer/uucp.m4 \
${CFDIR}/ostype/aix3.m4 \ ${CFDIR}/ostype/aix3.m4 \
${CFDIR}/ostype/aix4.m4 \ ${CFDIR}/ostype/aix4.m4 \
${CFDIR}/ostype/aix5.m4 \
${CFDIR}/ostype/altos.m4 \ ${CFDIR}/ostype/altos.m4 \
${CFDIR}/ostype/amdahl-uts.m4 \ ${CFDIR}/ostype/amdahl-uts.m4 \
${CFDIR}/ostype/a-ux.m4 \ ${CFDIR}/ostype/a-ux.m4 \
@ -167,6 +189,7 @@ M4FILES=\
${CFDIR}/ostype/bsdi.m4 \ ${CFDIR}/ostype/bsdi.m4 \
${CFDIR}/ostype/bsdi1.0.m4 \ ${CFDIR}/ostype/bsdi1.0.m4 \
${CFDIR}/ostype/bsdi2.0.m4 \ ${CFDIR}/ostype/bsdi2.0.m4 \
${CFDIR}/ostype/darwin.m4 \
${CFDIR}/ostype/dgux.m4 \ ${CFDIR}/ostype/dgux.m4 \
${CFDIR}/ostype/domainos.m4 \ ${CFDIR}/ostype/domainos.m4 \
${CFDIR}/ostype/dragonfly.m4 \ ${CFDIR}/ostype/dragonfly.m4 \
@ -200,10 +223,14 @@ M4FILES=\
${CFDIR}/ostype/solaris2.ml.m4 \ ${CFDIR}/ostype/solaris2.ml.m4 \
${CFDIR}/ostype/solaris2.pre5.m4 \ ${CFDIR}/ostype/solaris2.pre5.m4 \
${CFDIR}/ostype/solaris8.m4 \ ${CFDIR}/ostype/solaris8.m4 \
${CFDIR}/ostype/solaris11.m4 \
${CFDIR}/ostype/sunos3.5.m4 \ ${CFDIR}/ostype/sunos3.5.m4 \
${CFDIR}/ostype/sunos4.1.m4 \ ${CFDIR}/ostype/sunos4.1.m4 \
${CFDIR}/ostype/svr4.m4 \ ${CFDIR}/ostype/svr4.m4 \
${CFDIR}/ostype/ultrix4.m4 \ ${CFDIR}/ostype/ultrix4.m4 \
${CFDIR}/ostype/unicos.m4 \
${CFDIR}/ostype/unicosmk.m4 \
${CFDIR}/ostype/unicosmp.m4 \
${CFDIR}/ostype/unixware7.m4 \ ${CFDIR}/ostype/unixware7.m4 \
${CFDIR}/ostype/unknown.m4 \ ${CFDIR}/ostype/unknown.m4 \
${CFDIR}/ostype/uxpds.m4 ${CFDIR}/ostype/uxpds.m4

View file

@ -16,8 +16,8 @@
##### #####
##### SENDMAIL CONFIGURATION FILE ##### SENDMAIL CONFIGURATION FILE
##### #####
##### built by ca@lab.smi.sendmail.com on Thu Jul 2 22:41:57 PDT 2020 ##### built by ca@lab.smi.sendmail.com on Sun Aug 15 23:05:00 PDT 2021
##### in /var/tmp/ca/sm8.git/sendmail/OpenSource/sendmail-8.16.1/cf/cf ##### in /var/tmp/ca/sm8.head/sendmail/OpenSource/sendmail-8.17.1/cf/cf
##### using ../ as configuration include directory ##### using ../ as configuration include directory
##### #####
###################################################################### ######################################################################
@ -88,6 +88,7 @@ C{ResOk}OKR
# Hosts for which relaying is permitted ($=R) # Hosts for which relaying is permitted ($=R)
FR-o /etc/mail/relay-domains FR-o /etc/mail/relay-domains
# arithmetic map # arithmetic map
Karith arith Karith arith
@ -114,7 +115,7 @@ D{MTAHost}[127.0.0.1]
# Configuration version number # Configuration version number
DZ8.16.1/Submit DZ8.17.1/Submit
############### ###############
@ -362,7 +363,7 @@ O TimeZoneSpec=
# maximum number of new connections per second # maximum number of new connections per second
#O ConnectionRateThrottle=0 #O ConnectionRateThrottle=0
# Width of the window # Width of the window
#O ConnectionRateWindowSize=60s #O ConnectionRateWindowSize=60s
# work recipient factor # work recipient factor
@ -536,7 +537,7 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid
#O ClientCertFile #O ClientCertFile
# Client private key # Client private key
#O ClientKeyFile #O ClientKeyFile
# File containing certificate revocation lists # File containing certificate revocation lists
#O CRLFile #O CRLFile
# Directory containing hashes pointing to certificate revocation status files # Directory containing hashes pointing to certificate revocation status files
#O CRLPath #O CRLPath
@ -802,7 +803,7 @@ R< @ $=w . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ...
R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here
R< @ $+ > $#error $@ 5.1.3 $: "553 User address required" R< @ $+ > $#error $@ 5.1.3 $: "553 User address required"
R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ... R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ...
R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo"
R< @ *LOCAL* > $#error $@ 5.1.3 $: "553 User address required" R< @ *LOCAL* > $#error $@ 5.1.3 $: "553 User address required"
R$* $=O $* < @ *LOCAL* > R$* $=O $* < @ *LOCAL* >
$@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ...
@ -896,7 +897,7 @@ R< $+ > $+ $@ $>MailerToTriple < $1 > $2 < @ $1 >
SMailerToTriple=95 SMailerToTriple=95
R< > $* $@ $1 strip off null relay R< > $* $@ $1 strip off null relay
R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4
R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2 R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2
R< error : $+ > $* $#error $: $1 R< error : $+ > $* $#error $: $1
R< local : $* > $* $>CanonLocal < $1 > $2 R< local : $* > $* $>CanonLocal < $1 > $2
@ -926,7 +927,7 @@ R< $+ @ $+ > $* < @ $* > $: < $1 > $3 < @ $4 >
# handle local:user syntax # handle local:user syntax
R< $+ > $* <@ $* > $* $#local $@ $2@$3 $: $1 R< $+ > $* <@ $* > $* $#local $@ $2@$3 $: $1
R< $+ > $* $#local $@ $2 $: $1 R< $+ > $* $#local $@ $2 $: $1
################################################################### ###################################################################
### Ruleset 93 -- convert header names to masqueraded form ### ### Ruleset 93 -- convert header names to masqueraded form ###
@ -1189,7 +1190,7 @@ R<FORGED> $#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $
R<FAIL> $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name} R<FAIL> $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name}
R$* $: <@> $&{client_name} R$* $: <@> $&{client_name}
# pass to name server to make hostname canonical # pass to name server to make hostname canonical
R<@> $* $=P $:<?> $1 $2 R<@> $* $=P $:<?> $1 $2
R<@> $+ $:<?> $[ $1 $] R<@> $+ $:<?> $[ $1 $]
R$* . $1 strip trailing dots R$* . $1 strip trailing dots
R<?> $=w $@ RELAY R<?> $=w $@ RELAY
@ -1232,6 +1233,13 @@ SLocal_Relay_Auth
Ssrv_features Ssrv_features
######################################################################
### clt_features: which features to use with a server?
### (done in client)
######################################################################
Sclt_features
###################################################################### ######################################################################
### try_tls: try to use STARTTLS? ### try_tls: try to use STARTTLS?
### (done in client) ### (done in client)
@ -1239,6 +1247,7 @@ Ssrv_features
Stry_tls Stry_tls
###################################################################### ######################################################################
### tls_rcpt: is connection with server "good" enough? ### tls_rcpt: is connection with server "good" enough?
### (done in client, per recipient) ### (done in client, per recipient)
@ -1278,8 +1287,12 @@ R$* $@ $>"TLS_connection" $1
### Requirement: RHS from access map, may be ? for none. ### Requirement: RHS from access map, may be ? for none.
###################################################################### ######################################################################
STLS_connection STLS_connection
RSOFTWARE $#error $@ 4.7.0 $: "403 TLS handshake." RSOFTWARE $#error $@ 4.7.0 $: "454 TLS handshake failed."
RDANE_FAIL $#error $@ 4.7.0 $: "403 DANE check 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."
@ -1478,6 +1491,7 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L=
T=DNS/RFC822/SMTP, T=DNS/RFC822/SMTP,
A=TCP $h A=TCP $h
### submit.mc ### ### submit.mc ###
# divert(-1) # divert(-1)
# # # #
@ -1505,3 +1519,6 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L=
# dnl # dnl
# dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1] # dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1]
# FEATURE(`msp', `[127.0.0.1]')dnl # FEATURE(`msp', `[127.0.0.1]')dnl
# dnl enable this for SMTPUTF8 support
# dnl LOCAL_CONFIG
# dnl O SMTPUTF8=true

View file

@ -24,3 +24,6 @@ define(`confDONT_INIT_GROUPS', `True')dnl
dnl dnl
dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1] dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:0:0:0:0:0:0:0:1]
FEATURE(`msp', `[127.0.0.1]')dnl FEATURE(`msp', `[127.0.0.1]')dnl
dnl enable this for SMTPUTF8 support
dnl LOCAL_CONFIG
dnl O SMTPUTF8=true

View file

@ -10,7 +10,7 @@ divert(-1)
# #
divert(0)dnl divert(0)dnl
VERSIONID(`$Id: block_bad_helo.m4,v 1.2 2013-11-22 20:51:11 ca Exp $') VERSIONID(`$Id: check_cert_altnames.m4 1.0 2019-01-01 01:01:01 ca Exp $')
divert(-1) divert(-1)
define(`_FFR_TLS_ALTNAMES', `1') define(`_FFR_TLS_ALTNAMES', `1')
divert(6)dnl divert(6)dnl

View file

@ -0,0 +1,46 @@
divert(-1)
#
# 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.
#
#
dnl bogus Id, just here to show up in the generated cf file
divert(0)
VERSIONID(`$Id: check_other.m4,v 1.0 2021-04-30 00:01:11 ca Exp $')
divert(-1)
dnl
dnl Options:
dnl first arg:
dnl empty: use default regex
dnl else: use as regex
dnl [not implemented: NOREGEX: do not use any regex]
dnl
dnl Possible enhancements:
dnl select which SMTP reply type(s) should be allowed to match?
dnl maybe add "exceptions":
dnl - via an "OK" regex?
dnl - access map lookup for clients to be "ok" (Connect:... {ok,relay})
dnl more args? possible matches for rejections:
dnl does not seem to worth the effort: too inflexible.
dnl
dnl Note: sendmail removes whitespace before ':' ("tokenization")
ifelse(
defn(`_ARG_'), `', `define(`CHKORX', `^[[:print:]]+ *:')',
dnl defn(`_ARG_'), `NOREGEX', `define(`CHKORX', `')',
`define(`CHKORX', defn(`_ARG_'))')
LOCAL_CONFIG
ifelse(defn(`CHKORX'), `', `', `dnl
Kbadcmd regex -m -a<BADCMD> defn(`CHKORX')')
LOCAL_RULESETS
Scheck_other
dnl accept anything that will be accepted by the MTA
R$* $| 2 $@ ok
ifelse(defn(`CHKORX'), `', `', `dnl
R$+ $| 5 $: $(badcmd $1 $)
R$*<BADCMD> $#error $@ 4.7.0 $: 421 bad command')
dnl terminate on any bad command?
dnl R$* $| 5 $#error $@ 4.7.0 $: 421 bad command

View file

@ -21,5 +21,5 @@ ifelse(defn(`_ARG_'), `', `',
') ')
') ')
dnl be backward compatible by default dnl be backward compatible by default
ifelse(len(X`'_ARG2_), `1', `define(`_DELAY_COMPAT_8_10_', 1)', `') ifelse(len(X`'_ARG2_), `1', `define(`_DELAY_COMPAT_8_10_', 1)', `')

View file

@ -14,7 +14,7 @@ divert(0)
ifdef(`_DNSBL_R_',`dnl',`dnl ifdef(`_DNSBL_R_',`dnl',`dnl
VERSIONID(`$Id: dnsbl.m4,v 8.34 2013-11-22 20:51:11 ca Exp $') VERSIONID(`$Id: dnsbl.m4,v 8.34 2013-11-22 20:51:11 ca Exp $')
define(`_DNSBL_R_',`') define(`_DNSBL_R_',`')
ifelse(defn(`_ARG_'), `', ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(`dnsbl')')') `errprint(`*** ERROR: missing argument for FEATURE(`dnsbl')')')
LOCAL_CONFIG LOCAL_CONFIG
# map for DNS based blocklist lookups # map for DNS based blocklist lookups

View file

@ -9,7 +9,7 @@ divert(-1)
# #
# #
ifelse(defn(`_ARG_'), `', ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(`enhdnsbl')')') `errprint(`*** ERROR: missing argument for FEATURE(`enhdnsbl')')')
divert(0) divert(0)
ifdef(`_EDNSBL_R_',`dnl',`dnl ifdef(`_EDNSBL_R_',`dnl',`dnl

View file

@ -16,7 +16,7 @@ divert(0)
VERSIONID(`$Id: nopercenthack.m4,v 8.14 2013/01/31 15:07:00 ca Exp $') VERSIONID(`$Id: nopercenthack.m4,v 8.14 2013/01/31 15:07:00 ca Exp $')
divert(-1) divert(-1)
ifelse(defn(`_ARG_'), `', ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(nopercenthack): `errprint(`*** ERROR: missing argument for FEATURE(nopercenthack):
use `reject' or `nospecial'. See cf/README. use `reject' or `nospecial'. See cf/README.
')define(`_NO_PERCENTHACK_', `e')', ')define(`_NO_PERCENTHACK_', `e')',

View file

@ -16,7 +16,7 @@ divert(0)
VERSIONID(`$Id: nouucp.m4,v 8.14 2013-11-22 20:51:11 ca Exp $') VERSIONID(`$Id: nouucp.m4,v 8.14 2013-11-22 20:51:11 ca Exp $')
divert(-1) divert(-1)
ifelse(defn(`_ARG_'), `', ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(nouucp): `errprint(`*** ERROR: missing argument for FEATURE(nouucp):
use `reject' or `nospecial'. See cf/README. use `reject' or `nospecial'. See cf/README.
')define(`_NO_UUCP_', `e')', ')define(`_NO_UUCP_', `e')',

View file

@ -0,0 +1,19 @@
divert(-1)
#
# Copyright (c) 2020 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(-1)
define(`_MTA_STS_', `')
define(`_NEED_MACRO_MAP_', `1')
ifelse(_ARG2_,`NO_SAN_TST',`',`define(`_STS_SAN', `1')')
LOCAL_CONFIG
O StrictTransportSecurity=true
ifelse(_ARG2_,`NO_SAN_TST',`',`O SetCertAltnames=true')
Ksts ifelse(defn(`_ARG_'), `', socket -d5 -T<TMPF> inet:5461@127.0.0.1,
defn(`_NARG_'), `', `_ARG_', `_NARG_')

View file

@ -171,6 +171,12 @@ ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCA
')') ')')
divert(9) divert(9)
SLocal_srv_features') SLocal_srv_features')
define(`LOCAL_CLT_FEATURES',
`define(`_LOCAL_CLT_FEATURES_')
ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_CLT_FEATURES
')')
divert(9)
SLocal_clt_features')
define(`LOCAL_TRY_TLS', define(`LOCAL_TRY_TLS',
`define(`_LOCAL_TRY_TLS_') `define(`_LOCAL_TRY_TLS_')
ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TRY_TLS ifdef(`_MAILER_DEFINED_',,`errprint(`*** WARNING: MAILER() should be before LOCAL_TRY_TLS
@ -213,7 +219,7 @@ define(`SITE', `ifelse(CONCAT($'2`, $3), SU,
sinclude(_CF_DIR_`'siteconfig/$1.m4)') sinclude(_CF_DIR_`'siteconfig/$1.m4)')
define(`EXPOSED_USER', `PUSHDIVERT(5)C{E}$1 define(`EXPOSED_USER', `PUSHDIVERT(5)C{E}$1
POPDIVERT`'dnl`'') POPDIVERT`'dnl`'')
define(`EXPOSED_USER_FILE', `PUSHDIVERT(5)F{E}$1 define(`EXPOSED_USER_FILE', `PUSHDIVERT(5)F{E}$1
POPDIVERT`'dnl`'') POPDIVERT`'dnl`'')
define(`LOCAL_USER', `PUSHDIVERT(5)C{L}$1 define(`LOCAL_USER', `PUSHDIVERT(5)C{L}$1
POPDIVERT`'dnl`'') POPDIVERT`'dnl`'')

View file

@ -183,16 +183,20 @@ ifdef(`confCR_FILE', `dnl
FR`'confCR_FILE', FR`'confCR_FILE',
`dnl') `dnl')
ifdef(`_ACCESS_TABLE_', `dnl
define(`_FULL_TLS_CONNECTION_CHECK_', `1')', `dnl
ifdef(`_MTA_STS_', `define(`_FULL_TLS_CONNECTION_CHECK_', `1')')')
define(`TLS_SRV_TAG', `"TLS_Srv"')dnl define(`TLS_SRV_TAG', `"TLS_Srv"')dnl
define(`TLS_CLT_TAG', `"TLS_Clt"')dnl define(`TLS_CLT_TAG', `"TLS_Clt"')dnl
define(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl define(`TLS_RCPT_TAG', `"TLS_Rcpt"')dnl
define(`TLS_TRY_TAG', `"Try_TLS"')dnl define(`TLS_TRY_TAG', `"Try_TLS"')dnl
define(`SRV_FEAT_TAG', `"Srv_Features"')dnl define(`SRV_FEAT_TAG', `"Srv_Features"')dnl
define(`CLT_FEAT_TAG', `"Clt_Features"')dnl
dnl this may be useful in other contexts too dnl this may be useful in other contexts too
ifdef(`_ARITH_MAP_', `', `# arithmetic map ifdef(`_ARITH_MAP_', `', `# arithmetic map
define(`_ARITH_MAP_', `1')dnl define(`_ARITH_MAP_', `1')dnl
Karith arith') Karith arith')
ifdef(`_ACCESS_TABLE_', `dnl ifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl
ifdef(`_MACRO_MAP_', `', `# macro storage map ifdef(`_MACRO_MAP_', `', `# macro storage map
define(`_MACRO_MAP_', `1')dnl define(`_MACRO_MAP_', `1')dnl
Kmacro macro') Kmacro macro')
@ -206,6 +210,13 @@ KCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
ifdef(`_CERT_REGEX_SUBJECT_', `dnl ifdef(`_CERT_REGEX_SUBJECT_', `dnl
# extract relevant part from cert subject # extract relevant part from cert subject
KCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl') KCERTSubject regex _CERT_REGEX_SUBJECT_', `dnl')
ifdef(`_MTA_STS_', `dnl
Kstsxsni regex -a: -s3 (.*)(servername=)(.*)
Kstsxsni2 regex -a: -s2 (.*)(servername=.*)
Kstsxmatch regex -a: -s2 (match=)(.*)
# flag d: turn off DANE
Kstsxnodaneflag regex -a@ -s3 (.*)(flags=)([^;]*d)(.*)
', `dnl')
ifdef(`LOCAL_RELAY', `dnl ifdef(`LOCAL_RELAY', `dnl
# who I send unqualified names to if `FEATURE(stickyhost)' is used # who I send unqualified names to if `FEATURE(stickyhost)' is used
@ -502,7 +513,7 @@ _OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0')
# maximum number of new connections per second # maximum number of new connections per second
_OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0') _OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0')
# Width of the window # Width of the window
_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s') _OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s')
# work recipient factor # work recipient factor
@ -688,7 +699,7 @@ _OPTION(ServerKeyFile, `confSERVER_KEY', `')
_OPTION(ClientCertFile, `confCLIENT_CERT', `') _OPTION(ClientCertFile, `confCLIENT_CERT', `')
# Client private key # Client private key
_OPTION(ClientKeyFile, `confCLIENT_KEY', `') _OPTION(ClientKeyFile, `confCLIENT_KEY', `')
# File containing certificate revocation lists # File containing certificate revocation lists
_OPTION(CRLFile, `confCRL', `') _OPTION(CRLFile, `confCRL', `')
# Directory containing hashes pointing to certificate revocation status files # Directory containing hashes pointing to certificate revocation status files
_OPTION(CRLPath, `confCRL_PATH', `') _OPTION(CRLPath, `confCRL_PATH', `')
@ -868,7 +879,7 @@ R$* < @@ $+ > $* $@ $1 < @ $2 > $3 canon IP addr
ifdef(`_DOMAIN_TABLE_', `dnl ifdef(`_DOMAIN_TABLE_', `dnl
# look up domains in the domain table # look up domains in the domain table
R$* < @ $+ > $* $: $1 < @ $(domaintable $2 $) > $3', `dnl') R$* < @ $+ > $* $: $1 < @ $(domaintable $2 $) > $3', `dnl')
undivert(2)dnl LOCAL_RULE_3 undivert(2)dnl LOCAL_RULE_3
@ -953,14 +964,14 @@ ifdef(`_MASQUERADE_ENTIRE_DOMAIN_',
ifdef(`_VIRTUSER_TABLE_', `dnl ifdef(`_VIRTUSER_TABLE_', `dnl
dnl virtual hosts are also canonical dnl virtual hosts are also canonical
ifdef(`_VIRTUSER_ENTIRE_DOMAIN_', ifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
`R$* < @ $* $={VirtHost} > $* $: $1 < @ $2 $3 . > $4', `R$* < @ $* $={VirtHost} > $* $: $1 < @ $2 $3 . > $4',
`R$* < @ $={VirtHost} > $* $: $1 < @ $2 . > $3')', `R$* < @ $={VirtHost} > $* $: $1 < @ $2 . > $3')',
`dnl') `dnl')
ifdef(`_GENERICS_TABLE_', `dnl ifdef(`_GENERICS_TABLE_', `dnl
dnl hosts for genericstable are also canonical dnl hosts for genericstable are also canonical
ifdef(`_GENERICS_ENTIRE_DOMAIN_', ifdef(`_GENERICS_ENTIRE_DOMAIN_',
`R$* < @ $* $=G > $* $: $1 < @ $2 $3 . > $4', `R$* < @ $* $=G > $* $: $1 < @ $2 $3 . > $4',
`R$* < @ $=G > $* $: $1 < @ $2 . > $3')', `R$* < @ $=G > $* $: $1 < @ $2 . > $3')',
`dnl') `dnl')
dnl remove superfluous dots (maybe repeatedly) which may have been added dnl remove superfluous dots (maybe repeatedly) which may have been added
dnl by one of the rules before dnl by one of the rules before
@ -1062,7 +1073,7 @@ R< @ $=w . > : $* $@ $>Parse0 $>canonify $2 @here:... -> ...
R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here R$- < @ $=w . > $: $(dequote $1 $) < @ $2 . > dequote "foo"@here
R< @ $+ > $#error $@ 5.1.3 $: "_CODE553 User address required" R< @ $+ > $#error $@ 5.1.3 $: "_CODE553 User address required"
R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ... R$* $=O $* < @ $=w . > $@ $>Parse0 $>canonify $1 $2 $3 ...@here -> ...
R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo" R$- $: $(dequote $1 $) < @ *LOCAL* > dequote "foo"
R< @ *LOCAL* > $#error $@ 5.1.3 $: "_CODE553 User address required" R< @ *LOCAL* > $#error $@ 5.1.3 $: "_CODE553 User address required"
R$* $=O $* < @ *LOCAL* > R$* $=O $* < @ *LOCAL* >
$@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ... $@ $>Parse0 $>canonify $1 $2 $3 ...@*LOCAL* -> ...
@ -1105,17 +1116,17 @@ dnl are identical, i.e., if address A is mapped to A.
dnl it does not deal with multi-level recursion dnl it does not deal with multi-level recursion
# handle full domains in RHS of virtusertable # handle full domains in RHS of virtusertable
R$+ < @ $+ > $: $(macro {RecipientAddress} $) $1 < @ $2 > R$+ < @ $+ > $: $(macro {RecipientAddress} $) $1 < @ $2 >
R$+ < @ $+ > $: <?> $1 < @ $2 > $| $>final $1 < @ $2 > R$+ < @ $+ > $: <?> $1 < @ $2 > $| $>final $1 < @ $2 >
R<?> $+ $| $+ $: $1 $(macro {RecipientAddress} $@ $2 $) R<?> $+ $| $+ $: $1 $(macro {RecipientAddress} $@ $2 $)
R<?> $+ $| $* $: $1', R<?> $+ $| $* $: $1',
`dnl') `dnl')
R$+ $: <!> $1 Mark for lookup R$+ $: <!> $1 Mark for lookup
dnl input: <!> local<@domain> dnl input: <!> local<@domain>
ifdef(`_VIRTUSER_ENTIRE_DOMAIN_', ifdef(`_VIRTUSER_ENTIRE_DOMAIN_',
`R<!> $+ < @ $* $={VirtHost} . > $: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >', `R<!> $+ < @ $* $={VirtHost} . > $: < $(virtuser $1 @ $2 $3 $@ $1 $: @ $) > $1 < @ $2 $3 . >',
`R<!> $+ < @ $={VirtHost} . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >') `R<!> $+ < @ $={VirtHost} . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >')
dnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain> dnl input: <result-of-lookup | @> local<@domain> | <!> local<@domain>
R<!> $+ < @ $=w . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . > R<!> $+ < @ $=w . > $: < $(virtuser $1 @ $2 $@ $1 $: @ $) > $1 < @ $2 . >
dnl if <@> local<@domain>: no match but try lookup dnl if <@> local<@domain>: no match but try lookup
dnl user+detail: try user++@domain if detail not empty dnl user+detail: try user++@domain if detail not empty
R<@> $+ + $+ < @ $* . > R<@> $+ + $+ < @ $* . >
@ -1140,14 +1151,14 @@ dnl no match
R<@> $+ $: $1 R<@> $+ $: $1
dnl remove mark dnl remove mark
R<!> $+ $: $1 R<!> $+ $: $1
R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4
R< error : $- $+ > $* $#error $@ $(dequote $1 $) $: $2 R< error : $- $+ > $* $#error $@ $(dequote $1 $) $: $2
ifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl ifdef(`_VIRTUSER_STOP_ONE_LEVEL_RECURSION_',`dnl
# check virtuser input address against output address, if same, skip recursion # check virtuser input address against output address, if same, skip recursion
R< $+ > $+ < @ $+ > $: < $1 > $2 < @ $3 > $| $1 R< $+ > $+ < @ $+ > $: < $1 > $2 < @ $3 > $| $1
# it is the same: stop now # it is the same: stop now
R< $+ > $+ < @ $+ > $| $&{RecipientAddress} $: $>ParseLocal $>Parse0 $>canonify $1 R< $+ > $+ < @ $+ > $| $&{RecipientAddress} $: $>ParseLocal $>Parse0 $>canonify $1
R< $+ > $+ < @ $+ > $| $* $: < $1 > $2 < @ $3 > R< $+ > $+ < @ $+ > $| $* $: < $1 > $2 < @ $3 >
dnl', `dnl') dnl', `dnl')
dnl this is not a documented option dnl this is not a documented option
dnl it performs no looping at all for virtusertable dnl it performs no looping at all for virtusertable
@ -1176,7 +1187,7 @@ R$* <@ $+ > $* $: < $2 > $1 < @ $2 > $3 extract host name
R< $+ . > $* $: < $1 > $2 strip trailing dot R< $+ . > $* $: < $1 > $2 strip trailing dot
R< $+ > $* $: < $(mailertable $1 $) > $2 lookup R< $+ > $* $: < $(mailertable $1 $) > $2 lookup
dnl it is $~[ instead of $- to avoid matches on IPv6 addresses dnl it is $~[ instead of $- to avoid matches on IPv6 addresses
R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 check -- resolved? R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 check -- resolved?
R< $+ > $* $: $>Mailertable <$1> $2 try domain', R< $+ > $* $: $>Mailertable <$1> $2 try domain',
`dnl') `dnl')
undivert(4)dnl UUCP rules from `MAILER(uucp)' undivert(4)dnl UUCP rules from `MAILER(uucp)'
@ -1285,7 +1296,7 @@ R< > $+ + $* $: < ? $L > <+ $2> $(user $1 $) look up user+
R< > $+ $: < ? $L > < > $(user $1 $) look up user R< > $+ $: < ? $L > < > $(user $1 $) look up user
R< ? $* > < $* > $+ <> $: < > $3 $2 found; strip $L R< ? $* > < $* > $+ <> $: < > $3 $2 found; strip $L
R< ? $* > < $* > $+ $: < $1 > $3 $2 not found', ` R< ? $* > < $* > $+ $: < $1 > $3 $2 not found', `
R< > $+ $: < $L > $(user $1 $) look up user R< > $+ $: < $L > $(user $1 $) look up user
R< $* > $+ <> $: < > $2 found; strip $L') R< $* > $+ <> $: < > $2 found; strip $L')
ifdef(`_PRESERVE_LUSER_HOST_', `dnl ifdef(`_PRESERVE_LUSER_HOST_', `dnl
R< $+ > $+ $: < $1 > $2 $&{Host}') R< $+ > $+ $: < $1 > $2 $&{Host}')
@ -1336,7 +1347,7 @@ R< $+ > $* $#_RELAY_ $@ $1 $: $2 not found, direct relay',
`dnl') `dnl')
################################################################### ###################################################################
### Ruleset 90 -- try domain part of mailertable entry ### ### Ruleset 90 -- try domain part of mailertable entry ###
dnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress dnl input: LeftPartOfDomain <RightPartOfDomain> FullAddress
################################################################### ###################################################################
@ -1346,7 +1357,7 @@ dnl %2 is not documented in cf/README
R$* <$- . $+ > $* $: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4 R$* <$- . $+ > $* $: $1$2 < $(mailertable .$3 $@ $1$2 $@ $2 $) > $4
dnl it is $~[ instead of $- to avoid matches on IPv6 addresses dnl it is $~[ instead of $- to avoid matches on IPv6 addresses
R$* <$~[ : $* > $* $>MailerToTriple < $2 : $3 > $4 check -- resolved? R$* <$~[ : $* > $* $>MailerToTriple < $2 : $3 > $4 check -- resolved?
R$* < . $+ > $* $@ $>Mailertable $1 . <$2> $3 no -- strip & try again R$* < . $+ > $* $@ $>Mailertable $1 . <$2> $3 no -- strip & try again
dnl is $2 always empty? dnl is $2 always empty?
R$* < $* > $* $: < $(mailertable . $@ $1$2 $) > $3 try "." R$* < $* > $* $: < $(mailertable . $@ $1$2 $) > $3 try "."
R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 "." found? R< $~[ : $* > $* $>MailerToTriple < $1 : $2 > $3 "." found?
@ -1369,7 +1380,7 @@ dnl <host> address -> relay host address
SMailerToTriple=95 SMailerToTriple=95
R< > $* $@ $1 strip off null relay R< > $* $@ $1 strip off null relay
R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4 R< error : $-.$-.$- : $+ > $* $#error $@ $1.$2.$3 $: $4
R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2 R< error : $- : $+ > $* $#error $@ $(dequote $1 $) $: $2
R< error : $+ > $* $#error $: $1 R< error : $+ > $* $#error $: $1
R< local : $* > $* $>CanonLocal < $1 > $2 R< local : $* > $* $>CanonLocal < $1 > $2
@ -1408,7 +1419,7 @@ R< $+ @ $+ > $* < @ $* > $: < $1 > $3 < @ $4 >
# handle local:user syntax # handle local:user syntax
R< $+ > $* <@ $* > $* $#_LOCAL_ $@ $2@$3 $: $1 R< $+ > $* <@ $* > $* $#_LOCAL_ $@ $2@$3 $: $1
R< $+ > $* $#_LOCAL_ $@ $2 $: $1 R< $+ > $* $#_LOCAL_ $@ $2 $: $1
################################################################### ###################################################################
### Ruleset 93 -- convert header names to masqueraded form ### ### Ruleset 93 -- convert header names to masqueraded form ###
@ -1440,9 +1451,9 @@ dnl no match, try @domain for exceptions
R< > $+ < @ $+ . > $: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . > R< > $+ < @ $+ . > $: < $(generics @$2 $@ $1 $: $) > $1 < @ $2 . >
dnl workspace: ... or <match> user <@domain> dnl workspace: ... or <match> user <@domain>
dnl no match, try local part dnl no match, try local part
R< > $+ < @ $+ > $: < $(generics $1 $: $) > $1 < @ $2 > R< > $+ < @ $+ > $: < $(generics $1 $: $) > $1 < @ $2 >
R< > $+ + $* < @ $+ > $: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 > R< > $+ + $* < @ $+ > $: < $(generics $1+* $@ $2 $: $) > $1 + $2 < @ $3 >
R< > $+ + $* < @ $+ > $: < $(generics $1 $: $) > $1 + $2 < @ $3 > R< > $+ + $* < @ $+ > $: < $(generics $1 $: $) > $1 + $2 < @ $3 >
R< $* @ $* > $* < $* > $@ $>canonify $1 @ $2 found qualified R< $* @ $* > $* < $* > $@ $>canonify $1 @ $2 found qualified
R< $+ > $* < $* > $: $>canonify $1 @ *LOCAL* found unqualified R< $+ > $* < $* > $: $>canonify $1 @ *LOCAL* found unqualified
R< > $* $: $1 not found', R< > $* $: $1 not found',
@ -1594,7 +1605,7 @@ dnl must not be empty
### + does lookup with and without tag ### + does lookup with and without tag
### <$4> -- passthru (additional data passed unchanged through) ### <$4> -- passthru (additional data passed unchanged through)
dnl returns: <default> <passthru> dnl returns: <default> <passthru>
dnl <result> <passthru> dnl <result> <passthru>
###################################################################### ######################################################################
SD SD
@ -2183,10 +2194,10 @@ R$* $| $* $: $1
dnl workspace: localpart<@domain> | localpart dnl workspace: localpart<@domain> | localpart
ifelse(defn(`_NO_UUCP_'), `r', ifelse(defn(`_NO_UUCP_'), `r',
`R$* ! $* < @ $* > $: <REMOTE> $2 < @ BANG_PATH > `R$* ! $* < @ $* > $: <REMOTE> $2 < @ BANG_PATH >
R$* ! $* $: <REMOTE> $2 < @ BANG_PATH >', `dnl') R$* ! $* $: <REMOTE> $2 < @ BANG_PATH >', `dnl')
ifelse(defn(`_NO_PERCENTHACK_'), `r', ifelse(defn(`_NO_PERCENTHACK_'), `r',
`R$* % $* < @ $* > $: <REMOTE> $1 < @ PERCENT_HACK > `R$* % $* < @ $* > $: <REMOTE> $1 < @ PERCENT_HACK >
R$* % $* $: <REMOTE> $1 < @ PERCENT_HACK >', `dnl') R$* % $* $: <REMOTE> $1 < @ PERCENT_HACK >', `dnl')
# anything terminating locally is ok # anything terminating locally is ok
ifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl ifdef(`_RELAY_ENTIRE_DOMAIN_', `dnl
R$+ < @ $* $=m > $@ RELAY', `dnl') R$+ < @ $* $=m > $@ RELAY', `dnl')
@ -2273,13 +2284,13 @@ RIPv6:::1 $@ RELAY originated locally
R$=R $* $@ RELAY relayable IP address R$=R $* $@ RELAY relayable IP address
ifdef(`_ACCESS_TABLE_', `dnl ifdef(`_ACCESS_TABLE_', `dnl
R$* $: $>A <$1> <?> <+ Connect> <$1> R$* $: $>A <$1> <?> <+ Connect> <$1>
R<RELAY> $* $@ RELAY relayable IP address R<RELAY> $* $@ RELAY relayable IP address
ifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl ifdef(`_FFR_REJECT_IP_IN_CHECK_RCPT_',`dnl
dnl this will cause rejections in cases like: dnl this will cause rejections in cases like:
dnl Connect:My.Host.Domain RELAY dnl Connect:My.Host.Domain RELAY
dnl Connect:My.Net REJECT dnl Connect:My.Net REJECT
dnl since in check_relay client_name is checked before client_addr dnl since in check_relay client_name is checked before client_addr
R<REJECT> $* $@ REJECT rejected IP address') R<REJECT> $* $@ REJECT rejected IP address')
ifdef(`_ATMPF_', `R<_ATMPF_> $* $#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl') ifdef(`_ATMPF_', `R<_ATMPF_> $* $#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl')
R<$*> <$*> $: $2', `dnl') R<$*> <$*> $: $2', `dnl')
R$* $: [ $1 ] put brackets around it... R$* $: [ $1 ] put brackets around it...
@ -2326,7 +2337,7 @@ dnl nevertheless, removing the rule doesn't hurt.
dnl R<@> $@ RELAY dnl R<@> $@ RELAY
dnl workspace: <@> ${client_name} (not empty) dnl workspace: <@> ${client_name} (not empty)
# pass to name server to make hostname canonical # pass to name server to make hostname canonical
R<@> $* $=P $:<?> $1 $2 R<@> $* $=P $:<?> $1 $2
R<@> $+ $:<?> $[ $1 $] R<@> $+ $:<?> $[ $1 $]
dnl workspace: <?> ${client_name} (canonified) dnl workspace: <?> ${client_name} (canonified)
R$* . $1 strip trailing dots R$* . $1 strip trailing dots
@ -2471,7 +2482,7 @@ dnl must not be empty
### + does lookup with and without tag ### + does lookup with and without tag
### <$4> -- passthru (additional data passed unchanged through) ### <$4> -- passthru (additional data passed unchanged through)
dnl returns: <default> <passthru> dnl returns: <default> <passthru>
dnl <result> <passthru> dnl <result> <passthru>
###################################################################### ######################################################################
SF SF
@ -2520,7 +2531,7 @@ dnl must not be empty
### + does lookup with and without tag ### + does lookup with and without tag
### <$4> -- passthru (additional data passed unchanged through) ### <$4> -- passthru (additional data passed unchanged through)
dnl returns: <default> <passthru> dnl returns: <default> <passthru>
dnl <result> <passthru> dnl <result> <passthru>
###################################################################### ######################################################################
SE SE
@ -2554,7 +2565,7 @@ dnl must not be empty
### + does lookup with and without tag ### + does lookup with and without tag
### <$4> -- passthru (additional data passed unchanged through) ### <$4> -- passthru (additional data passed unchanged through)
dnl returns: <default> <passthru> dnl returns: <default> <passthru>
dnl <result> <passthru> dnl <result> <passthru>
###################################################################### ######################################################################
SU SU
@ -2685,6 +2696,24 @@ ifdef(`_ATMPF_', `dnl tempfail?
R<$* _ATMPF_>$* $#temp', `dnl') R<$* _ATMPF_>$* $#temp', `dnl')
R<$+>$* $# $1') R<$+>$* $# $1')
######################################################################
### clt_features: which features to use with a server?
### (done in client)
######################################################################
Sclt_features
ifdef(`_LOCAL_CLT_FEATURES_', `dnl
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> <>
R<?>$* $: <$(access CLT_FEAT_TAG`'_TAG_DELIM_ $: ? $)>
R<?>$* $@ OK
ifdef(`_ATMPF_', `dnl tempfail?
R<$* _ATMPF_>$* $#temp', `dnl')
R<$+>$* $# $1')
###################################################################### ######################################################################
### try_tls: try to use STARTTLS? ### try_tls: try to use STARTTLS?
### (done in client) ### (done in client)
@ -2703,6 +2732,76 @@ ifdef(`_ATMPF_', `dnl tempfail?
R<$* _ATMPF_>$* $#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl') R<$* _ATMPF_>$* $#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl')
R<NO>$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"') R<NO>$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
ifdef(`_MTA_STS_', `dnl
STLS_NameInList
R$* :$&{TLS_Name}: $* $@ ok
R$* $@ $1
dnl check SAN for STS
SSTS_SAN
ifdef(`_STS_SAN', `dnl
R$* $: $&{server_name}
dnl exact match
R$={cert_altnames} $@ ok
# strip only one level (no recursion!)
R$-.$+ $: $2
dnl wildcard: *. or just .?
R *.$={cert_altnames} $@ ok
dnl R .$={cert_altnames} $@ ok
dnl always temporary error? make it an option (of the feature)?
R$* $#error $@ 4.7.0 $: 450 $&{server_name} not listed in SANs', `dnl')
dnl input: ${verify}
dnl output: $# error ... (from TLS_connection)
dnl everything else: ok
SSTS_secure
R$* $: $&{rcpt_addr} $| $1
# no {rcpt_addr}, no STS check
R $| $* $@ ok
dnl canonify to extract domain part?
R$*@$+ $| $* $2 $| $3
R$+. $| $* $1 $| $2
R$+ $| $* $: $(sts $1 $: none $) $| $2
R$* <TMPF> $| $* $#error $@ 4.7.0 $: 450 STS lookup temp fail
dnl check whether connection is "secure"
dnl always temporary error? make it an option (of the feature)?
R$* secure $* $| $* $@ $>"TLS_connection" $3 $| <TEMP+VERIFY:128>
R$* $| $* $: $2
dnl check STS policy: secure and match? if so, check list
SSTS_Check
R$* $: $&{rcpt_addr} $| $1
# no {rcpt_addr}, no STS check
R $| $* $@ ok
# use the original argument for the test, not {rcpt_addr}
R$* $| $* $: $2 $| $2
dnl canonify to extract domain part?
R$*@$+ $| $* $2 $| $3
R$+. $| $* $1 $| $2
R$* $| $* $: $(sts $1 $: none $) $| mark
R$* <TMPF> $| $* $#error $@ 4.7.0 $: 450 STS lookup temp fail
dnl STS check only for "secure"
dnl do this only if {sts_sni} is set?
dnl workspace: result of sts lookup $| mark
R$* secure $* $| mark $: $2 $| trmatch
dnl not "secure": no check
R$* $| mark $@ ok
dnl remove servername=hostname, keep match=
R$* servername=hostname $| trmatch $: $1 $| trmatch
dnl extra list of matches, i.e., remove match=
R$+ $| trmatch $: : $(stsxmatch $1 $: : $)
dnl no match= data
R$* $| trmatch $@ $>STS_SAN
dnl Remove trailing dots from each entry in the list;
dnl those should not be there, but better safe than sorry.
R$*:$+.:$* $1:$2:$3
R:$+: $: $(macro {TLS_Name} $@ $&{server_name} $) $>TLS_NameInList :$1:
R$* ok $@ $>STS_SAN
R$* $: $1 $| $&{server_name}
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')
###################################################################### ######################################################################
### tls_rcpt: is connection with server "good" enough? ### tls_rcpt: is connection with server "good" enough?
### (done in client, per recipient) ### (done in client, per recipient)
@ -2716,6 +2815,10 @@ ifdef(`_LOCAL_TLS_RCPT_', `dnl
R$* $: $1 $| $>"Local_tls_rcpt" $1 R$* $: $1 $| $>"Local_tls_rcpt" $1
R$* $| $#$* $#$2 R$* $| $#$* $#$2
R$* $| $* $: $1', `dnl') R$* $| $* $: $1', `dnl')
ifdef(`_MTA_STS_', `dnl
R$* $: $1 $| $>"STS_Check" $1
R$* $| $#$* $#$2
R$* $| $* $: $1', `dnl')
ifdef(`_ACCESS_TABLE_', `dnl ifdef(`_ACCESS_TABLE_', `dnl
dnl store name of other side dnl store name of other side
R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1
@ -2783,6 +2886,10 @@ R$* $| $#$* $#$2
R$* $| $* $: $1', `dnl') R$* $| $* $: $1', `dnl')
ifdef(`_TLS_FAILURES_',`dnl ifdef(`_TLS_FAILURES_',`dnl
R$* $: $(macro {saved_verify} $@ $1 $) $1') R$* $: $(macro {saved_verify} $@ $1 $) $1')
ifdef(`_MTA_STS_', `dnl
R$* $: $1 $| $>"STS_secure" $1
R$* $| $#$* $#$2
R$* $| $* $: $1', `dnl')
ifdef(`_ACCESS_TABLE_', `dnl ifdef(`_ACCESS_TABLE_', `dnl
dnl store name of other side dnl store name of other side
R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1
@ -2808,11 +2915,22 @@ dnl [(PERM|TEMP)+] (VERIFY[:bits]|ENCR:bits) [+extensions]
dnl extensions: could be a list of further requirements dnl extensions: could be a list of further requirements
dnl for now: CN:string {cn_subject} == string 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 STLS_connection
ifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error ifdef(`_FULL_TLS_CONNECTION_CHECK_', `dnl', `dnl use default error
dnl deal with TLS handshake failures: abort dnl deal with TLS handshake failures: abort
RSOFTWARE $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake." RSOFTWARE $#error $@ TLS_DSNCODE $: "TLS_ERRCODE SW_MSG"
RDANE_FAIL $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed." 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"
divert(-1)') divert(-1)')
dnl common ruleset for tls_{client|server} dnl common ruleset for tls_{client|server}
dnl input: ${verify} $| <ResultOfLookup> [<>] dnl input: ${verify} $| <ResultOfLookup> [<>]
@ -2824,23 +2942,21 @@ dnl permanent or temporary error?
R$* $| <PERM + $={Tls} $*> $: $1 $| <503:5.7.0> <$2 $3> R$* $| <PERM + $={Tls} $*> $: $1 $| <503:5.7.0> <$2 $3>
R$* $| <TEMP + $={Tls} $*> $: $1 $| <403:4.7.0> <$2 $3> R$* $| <TEMP + $={Tls} $*> $: $1 $| <403:4.7.0> <$2 $3>
dnl default case depends on TLS_PERM_ERR dnl default case depends on TLS_PERM_ERR
R$* $| <$={Tls} $*> $: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')> <$2 $3> R$* $| <$={Tls} $*> $: $1 $| <TLS_ERRCODE:TLS_DSNCODE> <$2 $3>
dnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup> dnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
define(`TLS_ERRORS', `dnl
R`'$1 $| <$-:$+> $`'* $`'#error $`'@ $`'2 $: $`'1 " $2"
dnl no <reply:dns> i.e. no requirements in the access map
dnl use default error
R`'$1 $| $`'* $`'#error $`'@ TLS_DSNCODE $: "TLS_ERRCODE $2"')dnl
# deal with TLS handshake failures: abort # deal with TLS handshake failures: abort
RSOFTWARE $| <$-:$+> $* $#error $@ $2 $: $1 " TLS handshake failed." TLS_ERRORS(SOFTWARE,SW_MSG)
dnl no <reply:dns> i.e. no requirements in the access map
dnl use default error
RSOFTWARE $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
# deal with TLS protocol errors: abort # deal with TLS protocol errors: abort
RPROTOCOL $| <$-:$+> $* $#error $@ $2 $: $1 " STARTTLS failed." TLS_ERRORS(PROTOCOL,PROT_MSG)
dnl no <reply:dns> i.e. no requirements in the access map
dnl use default error
RPROTOCOL $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed."
# deal with DANE errors: abort # deal with DANE errors: abort
RDANE_FAIL $| <$-:$+> $* $#error $@ $2 $: $1 " DANE check failed." TLS_ERRORS(DANE_FAIL,DANE_MSG)
dnl no <reply:dns> i.e. no requirements in the access map # deal with CONFIG (tls_clt_features) errors: abort
dnl use default error TLS_ERRORS(CONFIG,CNF_MSG)
RDANE_FAIL $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed."
R$* $| <$*> <VERIFY> $: <$2> <VERIFY> <> $1 R$* $| <$*> <VERIFY> $: <$2> <VERIFY> <> $1
dnl separate optional requirements dnl separate optional requirements
R$* $| <$*> <VERIFY + $+> $: <$2> <VERIFY> <$3> $1 R$* $| <$*> <VERIFY + $+> $: <$2> <VERIFY> <$3> $1
@ -2958,25 +3074,116 @@ R$-:$-:$- $: $2
dnl endif _ACCESS_TABLE_ dnl endif _ACCESS_TABLE_
divert(0) divert(0)
dnl this must also be activated without _TLS_SESSION_FEATURES_
ifdef(`_MTA_STS_', `dnl
dnl caller preserves workspace
SSet_SNI
R$* $: <$&{rcpt_addr}>
# no {rcpt_addr}, no STS check
R<> $@ ""
dnl canonify to extract domain part?
R<$*@$+> $2
R$+. $1
R$+ $: $(sts $1 $: none $)
R$* <TMPF> $#error $@ 4.7.0 $: 450 STS lookup temp fail
Rnone $@ ""
dnl get servername=sni and store it in {sts_sni}
dnl stsxsni extracts the value of servername= (sni)
dnl stsxsni2 extracts servername=sni so it can be returned to the caller
R$* secure $* $: $(stsxsni $2 $: : $) $| sts=secure; $(stsxsni2 $2 $: : $)
dnl store {server_addr} as sni if there was a match
dnl Note: this implies that only servername=hostname (literally!)
dnl is only ever returned.
R$+: $| $+ : $: $(macro {sts_sni} $@ $&{server_name} $) set $| $2
R$* $| $* $@ $2
R$* $@ ""
dnl', `dnl')
ifdef(`_TLS_SESSION_FEATURES_', `dnl ifdef(`_TLS_SESSION_FEATURES_', `dnl
define(`_NEED_TLS_CLT_FEATURES')
Stls_srv_features Stls_srv_features
ifdef(`_ACCESS_TABLE_', `dnl ifdef(`_ACCESS_TABLE_', `dnl
R$* $| $* $: $>D <$1> <?> <! TLS_Srv_Features> <$2> R$* $| $* $: $>D <$1> <?> <! TLS_Srv_Features> <$2>
R<?> <$*> $: $>A <$1> <?> <! TLS_Srv_Features> <$1> R<?> <$*> $: $>A <$1> <?> <! TLS_Srv_Features> <$1>
R<?> <$*> $@ "" R<?> <$*> $@ ""
R<$+> <$*> $@ $1 R<$+> <$*> $@ $1
', `dnl ', `dnl
R$* $@ ""') R$* $@ ""')
', `dnl
ifdef(`_MTA_STS_',`define(`_NEED_TLS_CLT_FEATURES')')dnl
')dnl
ifdef(`_NEED_TLS_CLT_FEATURES', `dnl
ifdef(`_ACCESS_TABLE_', `dnl
Stls_clt_feat_acc
R$* $| $* $: $>D <$1> <?> <! TLS_Clt_Features> <$2>
R<?> <$*> $: $>A <$1> <?> <! TLS_Clt_Features> <$1>
R<?> <$*> $@ ""
R<$+> <$*> $@ $1')
SDANE_disabled
dnl Note: most of this is handled in the binary.
dnl input: access map lookup for tls_clt_features
dnl output:
dnl <>: disabled
dnl <DANE>: enabled
R$+ $: < $(stsxnodaneflag $1 $: NOFLAGS $) >
R<$* @> $@ <>
R$* $: < $&{sts_sni} >
R<> $@ <>
# check this too?
# R$* $: $&{client_flags}
# R$* DD $* $@ <>
R$* $@ <DANE>
SSTS_disabled
dnl input: ignored
dnl output:
dnl <>: disabled
dnl <STS>: enabled
R$* $: $&{client_flags}
R$* MM $* $@ <>
dnl
R$* $: $&{rcpt_addr} $| $1
# no {rcpt_addr}, no STS check
R $| $* $@ <>
R$* $@ <STS>
Stls_clt_features Stls_clt_features
dnl host $| ip
R$* $: $1 $| <>
ifdef(`_ACCESS_TABLE_', `dnl ifdef(`_ACCESS_TABLE_', `dnl
R$* $| $* $: $>D <$1> <?> <! TLS_Clt_Features> <$2> R$* $| <> $: $1 $| $>"tls_clt_feat_acc" $1
R<?> <$*> $: $>A <$1> <?> <! TLS_Clt_Features> <$1> R$* $| $* $| $* $: $1 $| $2 $| <$3>', `dnl')
R<?> <$*> $@ "" ifdef(`_MTA_STS_', `dnl
R<$+> <$*> $@ $1 dnl host $| ip $| <acc result - might be empty>
', `dnl R$* $| $* $| <$*> $: $1 $| $2 $| <$3> $| $>"STS_disabled" sts
R$* $@ ""') dnl host $| ip $| <acc result - might be empty> $| STS_disabled result
') dnl disable STS check? return access result
R$* $| $* $| <$*> $| <> $@ $3
dnl host $| ip $| <acc result - might be empty> $| STS_disabled result
R$* $| $* $| <$*> $| $* $: $1 $| $2 $| <$3> $| $>"DANE_disabled" $3
dnl DANE enabled: return access result; take care of empty return
R$* $| $* $| <$+> $| <DANE> $@ $3
R$* $| $* $| <> $| <DANE> $@ ""
dnl host $| ip $| <acc result - might be empty> $| <DANE_disabled result>
R$* $| $* $| <$*> $| <$*> $: $1 $| $2 $| <$3> $| $>"Set_SNI" $1
dnl host $| ip $| <acc result - might be empty> $| sni result
dnl return sni result if not empty but acc is
R$* $| $* $| <""> $| $+ $@ $3
dnl return acc + sni result if not empty
R$* $| $* $| <$+;> $| $+ $@ $3 ; $4
dnl return acc + sni result if not empty
R$* $| $* $| <$+> $| $+ $@ $3 ; $4
dnl return sni result if not empty
R$* $| $* $| <> $| $+ $@ $3
dnl remove sni result
R$* $| $* $| $* $| $* $: $1 $| $2 $| $3
', `dnl')
dnl host $| ip $| <acc result - might be empty>
R$* $| $* $| <""> $@ ""
R$* $| $* $| <$+> $@ $3
R$* $@ ""')
###################################################################### ######################################################################
### RelayTLS: allow relaying based on TLS authentication ### RelayTLS: allow relaying based on TLS authentication
@ -3046,7 +3253,7 @@ dnl', `dnl')')
ifdef(`_RATE_CONTROL_',`dnl ifdef(`_RATE_CONTROL_',`dnl
###################################################################### ######################################################################
### RateControl: ### RateControl:
### Parameters: ignored ### Parameters: ignored
### return: $#error or OK ### return: $#error or OK
###################################################################### ######################################################################
@ -3068,7 +3275,7 @@ R<$+> $| TRUE $#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exce
ifdef(`_CONN_CONTROL_',`dnl ifdef(`_CONN_CONTROL_',`dnl
###################################################################### ######################################################################
### ConnControl: ### ConnControl:
### Parameters: ignored ### Parameters: ignored
### return: $#error or OK ### return: $#error or OK
###################################################################### ######################################################################
@ -3108,3 +3315,10 @@ _MAIL_FILTERS_
###################################################################### ######################################################################
undivert(7)dnl MAILER_DEFINITIONS undivert(7)dnl MAILER_DEFINITIONS
dnl Helper ruleset for -bt mode to invoke rulesets
dnl which take two arguments separated by $|
dnl For example:
dnl Start,check_relay host.name $| I.P.V.4
dnl SStart
dnl R$* $$| $* $: $1 $| $2

View file

@ -15,4 +15,4 @@ VERSIONID(`$Id: version.m4,v 8.237 2014-01-27 12:55:17 ca Exp $')
# #
divert(0) divert(0)
# Configuration version number # Configuration version number
DZ8.16.1`'ifdef(`confCF_VERSION', `/confCF_VERSION') DZ8.17.1`'ifdef(`confCF_VERSION', `/confCF_VERSION')

View file

@ -79,7 +79,7 @@ R$* $: $>MasqHdr $1 do all-masquerading')',
# #
SAddDomain SAddDomain
ifdef(`_ALWAYS_ADD_DOMAIN_', `dnl ifdef(`_ALWAYS_ADD_DOMAIN_', `dnl
R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified R$* < @ $* > $* $@ $1 < @ $2 > $3 already fully qualified
ifelse(len(X`'_ALWAYS_ADD_DOMAIN_),`1',` ifelse(len(X`'_ALWAYS_ADD_DOMAIN_),`1',`
R$+ $@ $1 < @ *LOCAL* > add local qualification', R$+ $@ $1 < @ *LOCAL* > add local qualification',
`R$+ $@ $1 < @ _ALWAYS_ADD_DOMAIN_ > add qualification')', `R$+ $@ $1 < @ _ALWAYS_ADD_DOMAIN_ > add qualification')',

View file

@ -1,19 +1,18 @@
Patch from John Marshall (slightly modified). Patch from John Marshall (slightly modified).
Modified for 8.16.1 by Anne Bennett.
diff --git a/sendmail/srvrsmtp.c b/sendmail/srvrsmtp.c --- a/sendmail/srvrsmtp.c 2020-09-28 17:51:12.497535563 -0400
index 7dba983..bf804ab 100644 +++ b/sendmail/srvrsmtp.c 2020-09-28 18:21:30.482890337 -0400
--- a/sendmail/srvrsmtp.c @@ -116,7 +116,7 @@
+++ b/sendmail/srvrsmtp.c
@@ -84,7 +84,7 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
# define RESET_SASLCONN \
do \ do \
{ \ { \
RESET_AUTH_FAIL_LOG_USER; \
- result = reset_saslconn(&conn, AuthRealm, remoteip, \ - result = reset_saslconn(&conn, AuthRealm, remoteip, \
+ result = reset_saslconn(&conn, hostname, remoteip, \ + result = reset_saslconn(&conn, hostname, remoteip, \
localip, auth_id, &ext_ssf); \ localip, auth_id, &ext_ssf); \
if (result != SASL_OK) \ if (result != SASL_OK) \
sasl_ok = false; \ sasl_ok = false; \
@@ -938,8 +938,6 @@ smtp(nullserver, d_flags, e) @@ -1018,8 +1018,6 @@
e->e_features = features; e->e_features = features;
hostname = macvalue('j', e); hostname = macvalue('j', e);
#if SASL #if SASL
@ -22,7 +21,7 @@ index 7dba983..bf804ab 100644
sasl_ok = bitset(SRV_OFFER_AUTH, features); sasl_ok = bitset(SRV_OFFER_AUTH, features);
n_mechs = 0; n_mechs = 0;
authenticating = SASL_NOT_AUTH; authenticating = SASL_NOT_AUTH;
@@ -948,8 +946,8 @@ smtp(nullserver, d_flags, e) @@ -1028,8 +1026,8 @@
if (sasl_ok) if (sasl_ok)
{ {
# if SASL >= 20000 # if SASL >= 20000
@ -33,7 +32,7 @@ index 7dba983..bf804ab 100644
# elif SASL > 10505 # elif SASL > 10505
/* use empty realm: only works in SASL > 1.5.5 */ /* use empty realm: only works in SASL > 1.5.5 */
result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn); result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn);
@@ -5392,7 +5390,7 @@ reset_saslconn(sasl_conn_t **conn, char *hostname, @@ -5559,7 +5557,7 @@
sasl_dispose(conn); sasl_dispose(conn);
# if SASL >= 20000 # if SASL >= 20000

View file

@ -3,7 +3,7 @@
# usage: # usage:
# cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access # cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
# #
# v 0.4 # v 1.1
# #
# 17 July 2000 Derek J. Balling (dredd@megacity.org) # 17 July 2000 Derek J. Balling (dredd@megacity.org)
# #
@ -73,16 +73,25 @@
# Report bugs to: <dredd@megacity.org> # Report bugs to: <dredd@megacity.org>
# #
our $VERSION = '1.1';
use strict; use strict;
use Net::CIDR qw(cidr2octets cidrvalidate); use Net::CIDR qw(cidr2octets cidrvalidate);
use Getopt::Std; use Getopt::Std;
$Getopt::Std::STANDARD_HELP_VERSION = 1;
sub VERSION_MESSAGE;
sub HELP_MESSAGE;
sub print_expanded_v4network; sub print_expanded_v4network;
sub print_expanded_v6network; sub print_expanded_v6network;
our %opts; our %opts;
getopts('ct:', \%opts); getopts('cfhOSt:', \%opts);
if ($opts{h}) {
HELP_MESSAGE(\*STDOUT);
exit 0;
}
# Delimiter between the key and value # Delimiter between the key and value
my $space_re = exists $opts{t} ? $opts{t} : '\s+'; my $space_re = exists $opts{t} ? $opts{t} : '\s+';
@ -94,11 +103,13 @@ my $ipv4_re = qr"(?:\d+\.){3}\d+";
# Further checks are required for verifying that it's really one # Further checks are required for verifying that it's really one
my $ipv6_re = qr"[0-9A-Fa-f:]{2,39}(?:\.\d+\.\d+\.\d+)?"; my $ipv6_re = qr"[0-9A-Fa-f:]{2,39}(?:\.\d+\.\d+\.\d+)?";
my %pending;
while (<>) while (<>)
{ {
chomp; chomp;
my ($prefix, $network, $len, $right); my ($prefix, $network, $len, $right);
next if /^#/ && $opts{S};
if ( (/\#/) && $opts{c} ) if ( (/\#/) && $opts{c} )
{ {
# print "checking...\n"; # print "checking...\n";
@ -129,12 +140,12 @@ while (<>)
} }
if (($prefix, $network, $len, $right) = if (($prefix, $network, $len, $right) =
m!^(|\S+:)(${ipv4_re})/(\d+)(${space_re}.*)$!) m!^(|[^\s:]+:)(${ipv4_re})/(\d+)(${space_re}.*)$!)
{ {
print_expanded_v4network($network, $len, $prefix, $right); print_expanded_v4network($network, $len, $prefix, $right);
} }
elsif ((($prefix, $network, $len, $right) = elsif ((($prefix, $network, $len, $right) =
m!^((?:\S+:)?[Ii][Pp][Vv]6:)(${ipv6_re})(?:/(\d+))?(${space_re}.*)$!) && m!^((?:[^\s:]+:)?[Ii][Pp][Vv]6:)(${ipv6_re})(?:/(\d+))?(${space_re}.*)$!) &&
(!defined($len) || $len <= 128) && (!defined($len) || $len <= 128) &&
defined(cidrvalidate($network))) defined(cidrvalidate($network)))
{ {
@ -142,19 +153,31 @@ while (<>)
} }
else else
{ {
if (%pending && m!^(.+?)${space_re}!)
{
delete $pending{$opts{f} ? $1 : lc($1)};
}
print "$_\n"; print "$_\n";
} }
} }
print foreach values %pending;
sub print_expanded_v4network sub print_expanded_v4network
{ {
my ($network, $len, $prefix, $suffix) = @_; my ($network, $len, $prefix, $suffix) = @_;
my $fp = $opts{f} ? $prefix : lc($prefix);
# cidr2octets() doesn't handle a prefix-length of zero, so do # cidr2octets() doesn't handle a prefix-length of zero, so do
# that ourselves # that ourselves
foreach my $nl ($len == 0 ? (0..255) : cidr2octets("$network/$len")) foreach my $nl ($len == 0 ? (0..255) : cidr2octets("$network/$len"))
{ {
print "$prefix$nl$suffix\n"; my $val = "$prefix$nl$suffix\n";
if ($opts{O})
{
$pending{"$fp$nl"} = $val;
next;
}
print $val;
} }
} }
@ -171,11 +194,53 @@ sub print_expanded_v6network
} }
else else
{ {
my $fp = $opts{f} ? $prefix : lc($prefix);
foreach my $nl (cidr2octets("$network/$len")) foreach my $nl (cidr2octets("$network/$len"))
{ {
# trim leading zeros from each group # trim leading zeros from each group
$nl =~ s/(^|:)0+(?=[^:])/$1/g; $nl =~ s/(^|:)0+(?=[^:])/$1/g;
print "$prefix$nl$suffix\n"; my $val = "$prefix$nl$suffix\n";
if ($opts{O})
{
$pending{"$fp$nl"} = $val;
next;
}
print $val;
} }
} }
} }
sub VERSION_MESSAGE
{
my ($fh) = @_;
print $fh "cidrexpand - Version $VERSION\n";
}
sub HELP_MESSAGE
{
my ($fh) = @_;
print $fh <<'EOF';
Usage: cidrexpand [-cfhOS] [-t regexp] files...
Expand CIDR format inside the keys of map entries for makemap.
-c Truncate lines at the first unquoted '#'
-f Treat keys as case-sensitive when doing override detection
for the -O option. By default overlap detection is
case-insensitive.
-h Print this usage
-O When a CIDR expansion would generate a partial conflict
with a later entry, suppress the overlap from the earlier
expansion
-S Skip lines that start with '#'
-t regexp
Use 'regexp' to match the delimiter between key and value,
defaulting to \s+
EOF
}

0
contrib/sendmail/contrib/doublebounce.pl Normal file → Executable file
View file

0
contrib/sendmail/contrib/link_hash.sh Normal file → Executable file
View file

0
contrib/sendmail/contrib/re-mqueue.pl Normal file → Executable file
View file

View file

@ -92,7 +92,7 @@ Version \\$2
.. ..
.rm Ve .rm Ve
.sp .sp
For Sendmail Version 8.16 For Sendmail Version 8.17
.)l .)l
.(f .(f
Sendmail is a trademark of Proofpoint, Inc. Sendmail is a trademark of Proofpoint, Inc.
@ -1613,6 +1613,20 @@ hosts files dns
will not avoid DNS lookups even if a host can be found will not avoid DNS lookups even if a host can be found
in /etc/hosts. in /etc/hosts.
.pp .pp
Note: in contrast to the
.i sendmail
stub implementation
some operating systems do not preserve temporary failures.
For example, if DNS returns a TRY_AGAIN status for this setup
.(b
hosts files dns myhostname
.)b
but myhostname does not find the requested entry,
then a permanent error is returned to
.i sendmail
which obviously can cause problems,
e.g., an immediate bounce instead of a deferral.
.pp
Service switches are not completely integrated. Service switches are not completely integrated.
For example, despite the fact that the host entry listed in the above example For example, despite the fact that the host entry listed in the above example
specifies to look in NIS, specifies to look in NIS,
@ -4255,6 +4269,43 @@ ruleset is called after the
.sm "SMTP DATA" .sm "SMTP DATA"
command, its parameter is the number of recipients. command, its parameter is the number of recipients.
It can accept or reject the command. It can accept or reject the command.
.sh 4 "check_other"
.pp
The
.i check_other
ruleset is invoked for all unknown SMTP commands
and for commands which do not have specific rulesets,
e.g., NOOP and VERB.
Internal checks, e.g., those explained in
"Measures against Denial of Service Attacks",
are performed first.
The ruleset is passed
.(b
entire-SMTP-command $| SMTP-reply-first-digit
.)b
where
.b $|
is a metacharacter separating the two parts.
For example,
.(b
VERB $| 2
.)b
reflects receiving the "VERB" SMTP command and the
intent to return a "2XX" SMTP success reply.
Alternatively,
.(b
JUNK TYPE=I $| 5
.)b
reflects receiving the unknown "JUNK TYPE=I" SMTP command
and the intent to return a "5XX" SMTP failure reply.
If the ruleset returns the SMTP reply code 421:
.(b
$#error $@ 4.7.0 $: 421 bad command
.)b
the session is terminated.
Note: it is a bad idea to return the original command in the error text
to the client as that might be abused for certain attacks.
The ruleset cannot override a rejection triggered by the built-in rules.
.sh 4 "check_compat" .sh 4 "check_compat"
.pp .pp
The The
@ -4359,6 +4410,30 @@ ruleset is passed the user name parameter of the
.sm "SMTP VRFY" .sm "SMTP VRFY"
command. command.
It can accept or reject the command. It can accept or reject the command.
.sh 4 "clt_features"
.pp
The
.i clt_features
ruleset is called with the server's host name
when sendmail connects to it.
This ruleset should return
.b $#
followed by a list of options
(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
DANE/MTA-STS setups by simply not using it.
Note:
The
.i d
option in
.i tls_clt_features
to turn off DANE does not work when the server does not
even offer STARTTLS.
.sh 4 "trust_auth" .sh 4 "trust_auth"
.pp .pp
The The
@ -4404,11 +4479,11 @@ mailer, the connection is aborted
.pp .pp
The The
.i tls_rcpt .i tls_rcpt
ruleset is called each time before a RCPT TO command is sent. ruleset is called each time before a RCPT command is sent.
The parameter is the current recipient. The parameter is the current recipient.
If the ruleset does resolve to the If the ruleset does resolve to the
.q error .q error
mailer, the RCPT TO command is suppressed mailer, the RCPT command is suppressed
(treated as non-deliverable with a permanent or temporary error). (treated as non-deliverable with a permanent or temporary error).
This ruleset allows to require encryption or verification of This ruleset allows to require encryption or verification of
the recipient's MTA even if the mail is somehow redirected the recipient's MTA even if the mail is somehow redirected
@ -4447,6 +4522,10 @@ passive attack (e.g., PLAIN, LOGIN), unless a security layer is active.
Option `l' requires SMTP AUTH for a connection. Option `l' requires SMTP AUTH for a connection.
Options 'B', 'D', 'E', and 'X' suppress SMTP VERB, DSN, ETRN, and EXPN, Options 'B', 'D', 'E', and 'X' suppress SMTP VERB, DSN, ETRN, and EXPN,
respectively. respectively.
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.
.(b .(b
.ta 9n .ta 9n
A Do not offer AUTH A Do not offer AUTH
@ -4460,6 +4539,7 @@ D Do not offer DSN
d Offer DSN (default) d Offer DSN (default)
E Do not offer ETRN E Do not offer ETRN
e Offer ETRN (default) e Offer ETRN (default)
h Terminate session after HTTP commands
L Do not require AUTH (default) L Do not require AUTH (default)
l Require AUTH l Require AUTH
P Do not offer PIPELINING P Do not offer PIPELINING
@ -4495,10 +4575,14 @@ by simply not using it.
.pp .pp
The The
.i tls_clt_features .i tls_clt_features
ruleset is called when sendmail connects to another MTA ruleset is called right before sendmail issues the
.i STARTTLS
command to another MTA
and the and the
.i tls_srv_features .i tls_srv_features
ruleset is called when a client connects to ruleset is called when a client sends the
.i STARTTLS
command to
.i sendmail . .i sendmail .
The arguments for the rulesets are the host name and IP address The arguments for the rulesets are the host name and IP address
of the other side separated by of the other side separated by
@ -5134,6 +5218,13 @@ The current delivery mode sendmail is using.
It is initially set to the value of the It is initially set to the value of the
.b DeliveryMode .b DeliveryMode
option. option.
.ip ${dsn_envid}
The envelope id parameter (ENVID=) passed to sendmail as part of the envelope.
.ip ${dsn_notify}
Value of DSN NOTIFY= parameter
(never, success, failure, delay, or empty string).
.ip ${dsn_ret}
Value of DSN RET= parameter (hdrs, full, or empty string).
.ip ${envid} .ip ${envid}
The envelope id parameter (ENVID=) passed to sendmail as part of the envelope. The envelope id parameter (ENVID=) passed to sendmail as part of the envelope.
.ip ${hdrlen} .ip ${hdrlen}
@ -5243,8 +5334,10 @@ Defined in the SMTP server only after a RCPT command.
.ip ${server_addr} .ip ${server_addr}
The address of the server of the current outgoing SMTP connection. The address of the server of the current outgoing SMTP connection.
For LMTP delivery the macro is set to the name of the mailer. For LMTP delivery the macro is set to the name of the mailer.
(only if sendmail is compiled with STARTTLS or SASL.)
.ip ${server_name} .ip ${server_name}
The name of the server of the current outgoing SMTP or LMTP connection. The name of the server of the current outgoing SMTP or LMTP connection.
(only if sendmail is compiled with STARTTLS or SASL.)
.ip ${time} .ip ${time}
The output of the The output of the
.i time (3) .i time (3)
@ -5262,6 +5355,7 @@ only defined after STARTTLS has been used (or attempted).
Possible values are: Possible values are:
.(b .(b
.ta 13n .ta 13n
TRUSTED verification via DANE succeeded.
OK verification succeeded. OK verification succeeded.
NO no cert presented. NO no cert presented.
NOT no cert requested. NOT no cert requested.
@ -5950,7 +6044,7 @@ This flag is ignored if the
flag is set. flag is set.
.ip p .ip p
Use the route-addr style reverse-path in the SMTP Use the route-addr style reverse-path in the SMTP
.q "MAIL FROM:" .sm "SMTP MAIL"
command command
rather than just the return address; rather than just the return address;
although this is required in RFC 821 section 3.1, although this is required in RFC 821 section 3.1,
@ -6018,7 +6112,7 @@ i.e.,
must succeed. must succeed.
If not, the mail is bounced. If not, the mail is bounced.
See also the See also the
.b MailBoxDatabase .b MailboxDatabase
option. option.
This is required to get This is required to get
.q \&.forward .q \&.forward
@ -6253,7 +6347,7 @@ is used when converting a message to MIME;
this is the character set used in the this is the character set used in the
Content-Type: header. Content-Type: header.
If this is not set, the If this is not set, the
.b DefaultCharset .b DefaultCharSet
option is used, option is used,
and if that is not set, the value and if that is not set, the value
.q unknown-8bit .q unknown-8bit
@ -6599,7 +6693,7 @@ STARTTLS is already encrypting the communication, because the
existing encryption strength is taken into account when choosing existing encryption strength is taken into account when choosing
an algorithm for the security layer. an algorithm for the security layer.
For example, if STARTTLS is used and the symmetric cipher is 3DES, For example, if STARTTLS is used and the symmetric cipher is 3DES,
then the the keylength (in bits) is 168. then the keylength (in bits) is 168.
Hence setting Hence setting
.b AuthMaxBits .b AuthMaxBits
to 168 will disable any encryption in SASL. to 168 will disable any encryption in SASL.
@ -6617,7 +6711,7 @@ List of options for SMTP AUTH consisting of single characters
with intervening white space or commas. with intervening white space or commas.
.(b .(b
.ta 4n .ta 4n
A Use the AUTH= parameter for the MAIL FROM A Use the AUTH= parameter for the MAIL
command only when authentication succeeded. command only when authentication succeeded.
This can be used as a workaround for broken This can be used as a workaround for broken
MTAs that do not implement RFC 2554 correctly. MTAs that do not implement RFC 2554 correctly.
@ -6729,7 +6823,7 @@ File containing the private key belonging to the client certificate
.i sendmail .i sendmail
runs as client). runs as client).
.ip ClientPortOptions=\fIoptions\fP .ip ClientPortOptions=\fIoptions\fP
[O] [no short name]
Set client SMTP options. Set client SMTP options.
The options are The options are
.i key=value .i key=value
@ -7137,7 +7231,7 @@ When the system load average exceeds
will sleep for one second on most SMTP commands and will sleep for one second on most SMTP commands and
before accepting connections. before accepting connections.
.ip DeliverByMin=\fItime\fP .ip DeliverByMin=\fItime\fP
[0] [no short name]
Set minimum time for Deliver By SMTP Service Extension (RFC 2852). 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 0, no time is listed, if less than 0, the extension is not offered,
if greater than 0, it is listed as minimum time if greater than 0, it is listed as minimum time
@ -7191,7 +7285,7 @@ If not set,
is either "CC f" if the option is either "CC f" if the option
.b \-G .b \-G
is used or "c u" otherwise. is used or "c u" otherwise.
Note that only the the "CC", "c", "f", and "u" flags are checked. Note that only the "CC", "c", "f", and "u" flags are checked.
.ip DontBlameSendmail=\fIoption,option,...\fP .ip DontBlameSendmail=\fIoption,option,...\fP
[no short name] [no short name]
In order to avoid possible cracking attempts In order to avoid possible cracking attempts
@ -7450,6 +7544,12 @@ Set the name to be used for HELO/EHLO (instead of $j).
[H] [H]
Specify the help file for SMTP. Specify the help file for SMTP.
If no file name is specified, "helpfile" is used. If no file name is specified, "helpfile" is used.
If the help file does not exist (cannot be opened for reading)
.i sendmail
will print a note including its version in response to a
.b HELP
command.
To avoid providing this information to a client specify an empty file.
.ip HoldExpensive .ip HoldExpensive
[c] [c]
If an outgoing mailer is marked as being expensive, If an outgoing mailer is marked as being expensive,
@ -7716,8 +7816,8 @@ after a certain event occurred.
.ta \w'envfrom'u+3n .ta \w'envfrom'u+3n
connect After session connection start connect After session connection start
helo After EHLO/HELO command helo After EHLO/HELO command
envfrom After MAIL From command envfrom After MAIL command
envrcpt After RCPT To command envrcpt After RCPT command
data After DATA command. data After DATA command.
eoh After DATA command and header eoh After DATA command and header
eom After DATA command and terminating ``.'' eom After DATA command and terminating ``.''
@ -8105,7 +8205,7 @@ it is enabled by default for Linux.
According to some information this flag is not needed According to some information this flag is not needed
anymore for kernel 2.4.16 and newer. anymore for kernel 2.4.16 and newer.
.ip RrtImpliesDsn .ip RrtImpliesDsn
[R] [no short name]
If this option is set, a If this option is set, a
.q Return-Receipt-To: .q Return-Receipt-To:
header causes the request of a DSN, which is sent to header causes the request of a DSN, which is sent to
@ -8361,6 +8461,8 @@ option.
The message printed when the SMTP server starts up. The message printed when the SMTP server starts up.
Defaults to Defaults to
.q "$j Sendmail $v ready at $b". .q "$j Sendmail $v ready at $b".
.ip SMTPUTF8
Enable runtime support for SMTPUTF8.
.ip SoftBounce .ip SoftBounce
If set, issue temporary errors (4xy) instead of permanent errors (5xy). If set, issue temporary errors (4xy) instead of permanent errors (5xy).
This can be useful during testing of a new configuration to avoid This can be useful during testing of a new configuration to avoid
@ -9188,7 +9290,7 @@ flag is used. Without it, the key is discarded or if
.b \-s .b \-s
if used, it is substituted by the substring matches, delimited by if used, it is substituted by the substring matches, delimited by
.b $| .b $|
or the string specified with the the or the string specified with the
.b \-d .b \-d
option. option.
The options available for the map are The options available for the map are
@ -9575,7 +9677,7 @@ number to override the default LDAP port.
LDAP service port. LDAP service port.
.ip "\-H \fILDAPURI\fP" .ip "\-H \fILDAPURI\fP"
Use the specified LDAP URI instead of specifying the hostname and port Use the specified LDAP URI instead of specifying the hostname and port
separately with the the separately with the
.b \-h .b \-h
and and
.b \-p .b \-p
@ -11184,6 +11286,61 @@ error conditions as required by the RFCs.
Moreover, TLSA RRs are not looked up for some features, Moreover, TLSA RRs are not looked up for some features,
e.g., e.g.,
.i FallBackSmartHost . .i FallBackSmartHost .
.sh 2 "EAI"
.pp
Experimental support for SMTPUTF8 (EAI, see RFC 6530-6533)
is available when
the compile time option
.b USE_EAI,
(see also
.i devtools/Site/site.config.m4.sample
for other settings that might be needed),
and the cf option
.i SMTPUTF8
are used.
This allows the use of UTF-8 for envelope addresses
as well as the entire message.
DNS lookups are done using the A-label format (Punycode)
as required by the RFCs.
For all other interactions with external programs and maps,
the actual value are used,
i.e., no conversions between UTF-8 and ASCII encodings are made.
This applies to
.\" how to make a list?
.\" .(l
the keys in map lookups, which might require to specify both versions in a map;
the data exchanged with a milter, i.e., each milter must be "8 bit clean";
mail delivery agents which must be able to handle 8 bit addresses.
.\" .)l
Some values must be ASCII as those are used before SMTPUTF8 support
can be requested, e.g.,
the macros
.b $j
and
.b $m.
Please test and provide feedback.
.sh 2 "MTA-STS"
.pp
Experimental support for SMTP MTA Strict Transport Security
(MTA-STS, see RFC 8461)
is available when using
the compile time option _FFR_MTA_STS
(as well as some others, e.g., _FFR_TLS_ALTNAMES and obviously STARTTLS),
.\"(which requires in a default setting
.\"MAP_REGEX, SOCKETMAP, _FFR_TLS_ALTNAMES, and obviously STARTTLS),
FEATURE(sts)
(which implicitly sets the cf option StrictTransportSecurity),
and
postfix-mta-sts-resolver
(see https://github.com/Snawoot/postfix-mta-sts-resolver.git).
.pp
Note: this implementation uses a socket map to communicate with
postfix-mta-sts-resolver
and handles only the values returned by that program,
which might not fully implement MTA-STS.
.pp
If both DANE and MTA-STS are enabled and available for the receiving domain,
DANE is used because it offers a much higher level of security.
.sh 1 "ACKNOWLEDGEMENTS" .sh 1 "ACKNOWLEDGEMENTS"
.pp .pp
I've worked on I've worked on
@ -11517,6 +11674,19 @@ The
line will be deleted before sending. line will be deleted before sending.
Any addresses in the argument vector will be deleted Any addresses in the argument vector will be deleted
from the send list. from the send list.
.ip \-U
This option is required when sending mail using UTF-8;
it sets the
.q SMTPUTF8
argument for
.q MAIL
command.
Only available if
.q EAI
support is enabled,
and the
.q SMTPUTF8
option is set.
.ip "\-V envid" .ip "\-V envid"
The indicated The indicated
.i envid .i envid
@ -11641,7 +11811,8 @@ file to
and send it again. and send it again.
.pp .pp
The queue control file is structured as a series of lines The queue control file is structured as a series of lines
each beginning with a code letter. each beginning with a code letter;
the file must end with a line containing only a single dot.
The lines are as follows: The lines are as follows:
.ip V .ip V
The version number of the queue file format, The version number of the queue file format,
@ -11650,10 +11821,10 @@ used to allow new
binaries to read queue files created by older versions. binaries to read queue files created by older versions.
Defaults to version zero. Defaults to version zero.
Must be the first line of the file if present. Must be the first line of the file if present.
For 8.12 the version number is 6. For 8.13 and later the version number is 8.
.ip A .ip A
The information given by the AUTH= parameter of the The information given by the AUTH= parameter of the
.q "MAIL FROM:" .sm "SMTP MAIL"
command or $f@$j command or $f@$j
if sendmail has been called directly. if sendmail has been called directly.
.ip H .ip H
@ -11809,6 +11980,9 @@ H?x?Full-name: Eric Allman
H??Message-id: <9207170931.AA22757@foo.bar.baz.de> H??Message-id: <9207170931.AA22757@foo.bar.baz.de>
H??To: sendmail@vangogh.CS.Berkeley.EDU H??To: sendmail@vangogh.CS.Berkeley.EDU
H??Subject: this is an example message H??Subject: this is an example message
.cc '
.
'cc
.)b .)b
This shows This shows
the person who sent the message, the person who sent the message,

View file

@ -30,27 +30,31 @@ directed to standard output.
.PP .PP
Depending on how it is compiled, Depending on how it is compiled,
.B editmap .B editmap
handles up to three different database formats, handles different database formats,
selected using the selected using the
.I maptype .I maptype
parameter. parameter.
They may be They may be
.TP .TP
dbm dbm
DBM format maps. DBM format maps.
This requires the This requires the
ndbm(3) ndbm(3)
library. library.
.TP .TP
btree btree
B-Tree format maps. B-Tree format maps.
This requires the new Berkeley DB This requires the new Berkeley DB
library. library.
.TP .TP
hash hash
Hash format maps. Hash format maps.
This also requires the Berkeley DB This also requires the Berkeley DB
library. library.
.TP
cdb
CDB (Constant DataBase) format maps.
This requires the tinycdb library.
.PP .PP
If the If the
.I TrustedUser .I TrustedUser

View file

@ -38,6 +38,7 @@ SM_UNUSED(static char id[]) = "@(#)$Id: editmap.c,v 1.26 2013-11-22 20:51:26 ca
#endif #endif
#include <sysexits.h> #include <sysexits.h>
#include <assert.h> #include <assert.h>
#include <sm/sendmail.h>
#include <sendmail/sendmail.h> #include <sendmail/sendmail.h>
#include <sendmail/pathnames.h> #include <sendmail/pathnames.h>
#include <libsmdb/smdb.h> #include <libsmdb/smdb.h>
@ -194,13 +195,13 @@ main(argc, argv)
if (foldcase) if (foldcase)
{ {
char *p; char *lower;
for (p = keyname; *p != '\0'; p++) lower = makelower(keyname);
{
if (isascii(*p) && isupper(*p)) /* if it is different then it is a static variable */
*p = tolower(*p); if (keyname != lower)
} keyname = lower;
} }

View file

@ -476,7 +476,7 @@ LIBMILTER_API int smfi_insheader __P((SMFICTX *, int, char *, char *));
** as a result of adding this header. ** as a result of adding this header.
** **
** SMFICTX *ctx; Opaque context structure ** SMFICTX *ctx; Opaque context structure
** int idx; index into the header list where the insertion should happen ** int idx; index into the header list where the insertion should happen
** char *headerh; Header field name ** char *headerh; Header field name
** char *headerv; Header field value ** char *headerv; Header field value
*/ */

View file

@ -357,12 +357,12 @@ extern smdb_open_func smdb_open_database;
# if NEWDB # if NEWDB
extern smdb_open_func smdb_db_open; extern smdb_open_func smdb_db_open;
# else # else
# define smdb_db_open NULL # define smdb_db_open NULL
# endif # endif
# if NDBM # if NDBM
extern smdb_open_func smdb_ndbm_open; extern smdb_open_func smdb_ndbm_open;
# else # else
# define smdb_ndbm_open NULL # define smdb_ndbm_open NULL
# endif # endif
extern int smdb_add_extension __P((char *, int, char *, char *)); extern int smdb_add_extension __P((char *, int, char *, char *));
extern int smdb_setup_file __P((char *, char *, int, long, extern int smdb_setup_file __P((char *, char *, int, long,
@ -380,6 +380,6 @@ extern int smdb_unlock_map __P((SMDB_DATABASE *));
# if CDB # if CDB
extern smdb_open_func smdb_cdb_open; extern smdb_open_func smdb_cdb_open;
# else # else
# define smdb_cdb_open NULL # define smdb_cdb_open NULL
# endif # endif
#endif /* ! _SMDB_H_ */ #endif /* ! _SMDB_H_ */

View file

@ -33,7 +33,7 @@
# endif /* ! _PATH_SENDMAILPID */ # endif /* ! _PATH_SENDMAILPID */
# ifndef _PATH_SENDMAIL # ifndef _PATH_SENDMAIL
# define _PATH_SENDMAIL "/usr/lib/sendmail" # define _PATH_SENDMAIL "/usr/lib/sendmail"
# endif # endif
# ifndef _PATH_MAILDIR # ifndef _PATH_MAILDIR

View file

@ -37,9 +37,9 @@
# define DBTXN # define DBTXN
# if !HASFLOCK && defined(DB_FCNTL_LOCKING) # if !HASFLOCK && defined(DB_FCNTL_LOCKING)
# define SM_DB_FLAG_ADD(flag) (flag) |= DB_FCNTL_LOCKING # define SM_DB_FLAG_ADD(flag) (flag) |= DB_FCNTL_LOCKING
# else /* !HASFLOCK && defined(DB_FCNTL_LOCKING) */ # else
# define SM_DB_FLAG_ADD(flag) ((void) 0) # define SM_DB_FLAG_ADD(flag) ((void) 0)
# endif /* !HASFLOCK && defined(DB_FCNTL_LOCKING) */ # endif
# endif /* (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) || DB_VERSION_MAJOR >= 5 */ # endif /* (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) || DB_VERSION_MAJOR >= 5 */
#endif /* NEWDB */ #endif /* NEWDB */

View file

@ -997,6 +997,7 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define USESYSCTL 1 /* use sysctl(3) for getting ncpus */ # define USESYSCTL 1 /* use sysctl(3) for getting ncpus */
# include <sys/param.h> # include <sys/param.h>
# include <sys/sysctl.h> # include <sys/sysctl.h>
# define HAVE_IFC_BUF_VOID 1 /* void *ifc_buf instead of caddr_t */
# endif # endif
# if defined(__DragonFly__) # if defined(__DragonFly__)
# define HASSETLOGIN 1 /* has setlogin(2) */ # define HASSETLOGIN 1 /* has setlogin(2) */

View file

@ -77,4 +77,16 @@
typedef int SM_ATOMIC_INT_T; typedef int SM_ATOMIC_INT_T;
typedef unsigned int SM_ATOMIC_UINT_T; typedef unsigned int SM_ATOMIC_UINT_T;
#if _FFR_EAI && !defined(USE_EAI)
# define USE_EAI 1
#endif
#if USE_EAI && !defined(_FFR_LOGASIS)
# define _FFR_LOGASIS 1
#endif
#if USE_EAI || _FFR_EIGHT_BIT_ADDR_OK
# define _FFR_8BITENVADDR 1
#endif
#endif /* SM_GEN_H */ #endif /* SM_GEN_H */

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2020 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 _SM_IXLEN_H
# define _SM_IXLEN_H 1
#define SM_IS_MQ(ch) (((ch) & 0377) == METAQUOTE)
#if _FFR_8BITENVADDR
# define XLENDECL bool mq=false; \
int xlen = 0;
# define XLENRESET mq=false, xlen = 0
# define XLEN(c) do { \
if (mq) { ++xlen; mq=false; } \
else if (SM_IS_MQ(c)) mq=true; \
else ++xlen; \
} while (0)
extern int ilenx __P((const char *));
extern int xleni __P((const char *));
# if USE_EAI
extern bool asciistr __P((const char *));
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));
# endif
#else /* _FFR_8BITENVADDR */
# define XLENDECL int xlen = 0;
# define XLENRESET xlen = 0
# define XLEN(c) ++xlen
# define ilenx(str) strlen(str)
# define xleni(str) strlen(str)
#endif /* _FFR_8BITENVADDR */
#endif /* ! _SM_IXLEN_H */

View file

@ -10,10 +10,13 @@
#ifndef SM_NOTIFY_H #ifndef SM_NOTIFY_H
#define SM_NOTIFY_H #define SM_NOTIFY_H
/* microseconds */
#define SM_MICROS 1000000L
int sm_notify_init __P((int)); int sm_notify_init __P((int));
int sm_notify_start __P((bool, int)); int sm_notify_start __P((bool, int));
int sm_notify_stop __P((bool, int)); int sm_notify_stop __P((bool, int));
int sm_notify_rcv __P((char *, size_t, int)); int sm_notify_rcv __P((char *, size_t, long));
int sm_notify_snd __P((char *, size_t)); int sm_notify_snd __P((char *, size_t));
#endif /* ! SM_MSG_H */ #endif /* ! SM_MSG_H */

View file

@ -26,6 +26,11 @@
# define SM_CONF_STRL 1 # define SM_CONF_STRL 1
# endif # endif
# endif # endif
# if __FreeBSD_version >= 1200059
# ifndef SM_CONF_SEM
# define SM_CONF_SEM 2 /* union semun is no longer declared by default */
# endif
# endif
#endif #endif
#ifndef SM_CONF_SHM #ifndef SM_CONF_SHM

View file

@ -18,13 +18,27 @@
#define SM_OS_NAME "openbsd" #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 #define SM_CONF_SYS_CDEFS_H 1
#ifndef SM_CONF_SHM #ifndef SM_CONF_SHM
# define SM_CONF_SHM 1 # define SM_CONF_SHM 1
#endif /* SM_CONF_SHM */ #endif
#ifndef SM_CONF_SEM #ifndef SM_CONF_SEM
# define SM_CONF_SEM 1 # define SM_CONF_SEM 1
#endif /* SM_CONF_SEM */ #endif
#ifndef SM_CONF_MSG #ifndef SM_CONF_MSG
# define SM_CONF_MSG 1 # define SM_CONF_MSG 1
#endif /* SM_CONF_MSG */ #endif

View file

@ -15,7 +15,7 @@
*/ */
#ifndef SM_RPOOL_H #ifndef SM_RPOOL_H
# define SM_RPOOL_H # define SM_RPOOL_H 1
# include <sm/gen.h> # include <sm/gen.h>
# include <sm/heap.h> # include <sm/heap.h>
@ -166,7 +166,15 @@ sm_rpool_malloc __P((
# endif /* SM_HEAP_CHECK */ # endif /* SM_HEAP_CHECK */
#if DO_NOT_USE_STRCPY #if DO_NOT_USE_STRCPY
# if SM_HEAP_CHECK > 2
extern char *sm_rpool_strdup_tagged_x __P((SM_RPOOL_T *rpool, const char *s, char *, int, int));
# define sm_rpool_strdup_x(rpool, str) sm_rpool_strdup_tagged_x(rpool, str, "sm_rpool_strdup_x:" __FILE__, __LINE__, SmHeapGroup)
# else
extern char *sm_rpool_strdup_x __P((SM_RPOOL_T *rpool, const char *s)); extern char *sm_rpool_strdup_x __P((SM_RPOOL_T *rpool, const char *s));
# define sm_rpool_strdup_tagged_x(rpool, str, tag, line, group) sm_rpool_strdup_x(rpool, str)
# endif
#else #else
# define sm_rpool_strdup_x(rpool, str) \ # define sm_rpool_strdup_x(rpool, str) \
strcpy(sm_rpool_malloc_x(rpool, strlen(str) + 1), str) strcpy(sm_rpool_malloc_x(rpool, strlen(str) + 1), str)

View file

@ -47,7 +47,7 @@ extern int sm_sem_stop __P((int));
extern int sm_sem_acq __P((int, int, int)); extern int sm_sem_acq __P((int, int, int));
extern int sm_sem_rel __P((int, int, int)); extern int sm_sem_rel __P((int, int, int));
extern int sm_sem_get __P((int, int)); extern int sm_sem_get __P((int, int));
extern int sm_semsetowner __P((int, uid_t, gid_t, mode_t)); extern int sm_semsetowner __P((int, uid_t, gid_t, MODE_T));
# else /* SM_CONF_SEM > 0 */ # else /* SM_CONF_SEM > 0 */
# define sm_sem_start(key, nsem, semflg, owner) 0 # define sm_sem_start(key, nsem, semflg, owner) 0

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006 Proofpoint, Inc. and its suppliers. * Copyright (c) 2006, 2020 Proofpoint, Inc. and its suppliers.
* All rights reserved. * All rights reserved.
* *
* By using this file, you agree to the terms and conditions set * By using this file, you agree to the terms and conditions set
@ -14,11 +14,31 @@
#ifndef _SM_SENDMAIL_H #ifndef _SM_SENDMAIL_H
# define _SM_SENDMAIL_H 1 # define _SM_SENDMAIL_H 1
#include <sm/rpool.h>
/* "out of band" indicator */ /* "out of band" indicator */
#define METAQUOTE ((unsigned char)0377) /* quotes the next octet */ #define METAQUOTE ((unsigned char)0377) /* quotes the next octet */
#define SM_MM_QUOTE(ch) (((ch) & 0377) == METAQUOTE || (((ch) & 0340) == 0200))
extern int dequote_internal_chars __P((char *, char *, int)); extern int dequote_internal_chars __P((char *, char *, int));
extern char *quote_internal_chars __P((char *, char *, int *)); #if SM_HEAP_CHECK > 2
extern char *quote_internal_chars_tagged __P((char *, char *, int *, SM_RPOOL_T *, char *, int, int));
# define quote_internal_chars(ibp, obp, bsp, rpool) quote_internal_chars_tagged(ibp, obp, bsp, rpool, "quote_internal_chars:" __FILE__, __LINE__, SmHeapGroup)
#else
extern char *quote_internal_chars __P((char *, char *, int *, SM_RPOOL_T *));
# define quote_internal_chars_tagged(ibp, obp, bsp, rpool, file, line, group) quote_internal_chars(ibp, obp, bsp, rpool)
#endif
extern char *str2prt __P((char *)); extern char *str2prt __P((char *));
extern char *makelower __P((char *));
#if USE_EAI
extern bool sm_strcaseeq __P((const char *, const char *));
extern bool sm_strncaseeq __P((const char *, const char *, size_t));
# define SM_STRCASEEQ(a, b) sm_strcaseeq((a), (b))
# define SM_STRNCASEEQ(a, b, n) sm_strncaseeq((a), (b), (n))
#else
# define SM_STRCASEEQ(a, b) (sm_strcasecmp((a), (b)) == 0)
# define SM_STRNCASEEQ(a, b, n) (sm_strncasecmp((a), (b), (n)) == 0)
#endif
#endif /* ! _SM_SENDMAIL_H */ #endif /* ! _SM_SENDMAIL_H */

View file

@ -28,7 +28,7 @@
extern void *sm_shmstart __P((key_t, int , int , int *, bool)); extern void *sm_shmstart __P((key_t, int , int , int *, bool));
extern int sm_shmstop __P((void *, int, bool)); extern int sm_shmstop __P((void *, int, bool));
extern int sm_shmsetowner __P((int, uid_t, gid_t, mode_t)); extern int sm_shmsetowner __P((int, uid_t, gid_t, MODE_T));
/* for those braindead systems... (e.g., SunOS 4) */ /* for those braindead systems... (e.g., SunOS 4) */

View file

@ -74,6 +74,10 @@
** CANTCREAT, but rather for higher level permissions. ** CANTCREAT, but rather for higher level permissions.
*/ */
# ifdef EX_OK
# undef EX_OK /* for SVr4.2 SMP */
# endif
# if SM_CONF_SYSEXITS_H # if SM_CONF_SYSEXITS_H
# include <sysexits.h> # include <sysexits.h>
# else /* SM_CONF_SYSEXITS_H */ # else /* SM_CONF_SYSEXITS_H */

View file

@ -13,7 +13,6 @@
# define SM_TIME_H 1 # define SM_TIME_H 1
# include <sm/config.h> # include <sm/config.h>
# include <sys/time.h> # include <sys/time.h>
/* should be defined in sys/time.h */ /* should be defined in sys/time.h */
@ -52,5 +51,4 @@
((tvp)->tv_sec cmp (uvp)->tv_sec)) ((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif /* !timercmp */ #endif /* !timercmp */
#endif /* ! SM_TIME_H */ #endif /* ! SM_TIME_H */

View file

@ -75,8 +75,9 @@ MESSAGE:For each message in this connection (sequentially)
process recipient (<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A>) process recipient (<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A>)
} }
For each filter For each filter
{
process DATA (<A HREF="xxfi_data.html">xxfi_data</A>) process DATA (<A HREF="xxfi_data.html">xxfi_data</A>)
For each filter
{
For each header For each header
process header (<A HREF="xxfi_header.html">xxfi_header</A>) process header (<A HREF="xxfi_header.html">xxfi_header</A>)
process end of headers (<A HREF="xxfi_eoh.html">xxfi_eoh</A>) process end of headers (<A HREF="xxfi_eoh.html">xxfi_eoh</A>)

View file

@ -33,7 +33,8 @@ other than xxfi_connect.</TD>
<TR align="left" valign=top> <TR align="left" valign=top>
<TH width="80">Effects</TH> <TH width="80">Effects</TH>
<TD>Directly set the SMTP error reply code for this connection to the given <TD>Directly set the SMTP error reply code for this connection to the given
lines after the xcode. The list of arguments must be NULL terminated. lines after the xcode.
The list of arguments must be NULL terminated.
This code will be used on subsequent error replies resulting from actions This code will be used on subsequent error replies resulting from actions
taken by this filter.</TD> taken by this filter.</TD>
</TR> </TR>
@ -48,25 +49,28 @@ taken by this filter.</TD>
<TD>Opaque context structure. <TD>Opaque context structure.
</TD></TR> </TD></TR>
<TR valign="top"><TD>rcode</TD> <TR valign="top"><TD>rcode</TD>
<TD>The three-digit (RFC 821/2821) SMTP reply code, as a <TD>The three-digit (RFC 821/2821) SMTP reply code,
null-terminated string. rcode cannot be NULL, and must be a valid as a null-terminated string.
4XX or 5XX reply code. rcode cannot be NULL, and must be a valid 4XX or 5XX reply code.
</TD></TR> </TD></TR>
<TR valign="top"><TD>xcode</TD> <TR valign="top"><TD>xcode</TD>
<TD>The extended (RFC 1893/2034) reply code. If xcode is NULL, no <TD>The extended (RFC 1893/2034) reply code.
extended code is used. Otherwise, xcode must conform to RFC 1893/2034. If xcode is NULL, a generic X.0.0 code is used,
where X is the first digit of rcode.
Otherwise, xcode must conform to RFC 1893/2034.
</TD></TR> </TD></TR>
<TR valign="top"><TD>...</TD> <TR valign="top"><TD>...</TD>
<TD>The remainder of the arguments are single lines of text, up to <TD>The remainder of the arguments are single lines of text,
32 arguments, which will be used as the text part of the SMTP up to 32 arguments,
reply. The list must be NULL terminated. which will be used as the text part of the SMTP reply.
The list must be NULL terminated.
</TD></TR> </TD></TR>
</TABLE> </TABLE>
</TD></TR> </TD></TR>
<!----------- Example ----------> <!----------- Example ---------->
<TR> <TR>
<TH valign="top" align=left>RETURN VALUES</TH> <TH valign="top" align=left>EXAMPLE</TH>
<TD> <TD>
For example, the code:<BR> For example, the code:<BR>
<PRE> <PRE>

View file

@ -64,28 +64,28 @@ typedef struct cmdfct_t cmdfct;
#define CI_EOH 6 #define CI_EOH 6
#define CI_LAST CI_EOH #define CI_LAST CI_EOH
#if CI_LAST < CI_DATA #if CI_LAST < CI_DATA
ERROR: do not compile with CI_LAST < CI_DATA # ERROR "do not compile with CI_LAST < CI_DATA"
#endif #endif
#if CI_LAST < CI_EOM #if CI_LAST < CI_EOM
ERROR: do not compile with CI_LAST < CI_EOM # ERROR "do not compile with CI_LAST < CI_EOM"
#endif #endif
#if CI_LAST < CI_EOH #if CI_LAST < CI_EOH
ERROR: do not compile with CI_LAST < CI_EOH # ERROR "do not compile with CI_LAST < CI_EOH"
#endif #endif
#if CI_LAST < CI_RCPT #if CI_LAST < CI_RCPT
ERROR: do not compile with CI_LAST < CI_RCPT # ERROR "do not compile with CI_LAST < CI_RCPT"
#endif #endif
#if CI_LAST < CI_MAIL #if CI_LAST < CI_MAIL
ERROR: do not compile with CI_LAST < CI_MAIL # ERROR "do not compile with CI_LAST < CI_MAIL"
#endif #endif
#if CI_LAST < CI_HELO #if CI_LAST < CI_HELO
ERROR: do not compile with CI_LAST < CI_HELO # ERROR "do not compile with CI_LAST < CI_HELO"
#endif #endif
#if CI_LAST < CI_CONN #if CI_LAST < CI_CONN
ERROR: do not compile with CI_LAST < CI_CONN # ERROR "do not compile with CI_LAST < CI_CONN"
#endif #endif
#if CI_LAST >= MAX_MACROS_ENTRIES #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 #endif
/* function prototypes */ /* function prototypes */
@ -1190,7 +1190,7 @@ st_connectinfo(g)
s = g->a_buf; s = g->a_buf;
i = 0; i = 0;
l = g->a_len; l = g->a_len;
while (i <= l && s[i] != '\0') while (i <= l && s[i] != '\0')
++i; ++i;
if (i + 1 >= l) if (i + 1 >= l)
return _SMFIS_ABORT; return _SMFIS_ABORT;
@ -1216,7 +1216,7 @@ st_connectinfo(g)
/* make sure string is terminated */ /* make sure string is terminated */
if (s[l - 1] != '\0') if (s[l - 1] != '\0')
return _SMFIS_ABORT; return _SMFIS_ABORT;
# if NETINET #if NETINET
if (family == SMFIA_INET) if (family == SMFIA_INET)
{ {
if (inet_aton(s + i, (struct in_addr *) &sockaddr.sin.sin_addr) if (inet_aton(s + i, (struct in_addr *) &sockaddr.sin.sin_addr)
@ -1233,8 +1233,8 @@ st_connectinfo(g)
sockaddr.sin.sin_port = port; sockaddr.sin.sin_port = port;
} }
else else
# endif /* NETINET */ #endif /* NETINET */
# if NETINET6 #if NETINET6
if (family == SMFIA_INET6) if (family == SMFIA_INET6)
{ {
if (mi_inet_pton(AF_INET6, s + i, if (mi_inet_pton(AF_INET6, s + i,
@ -1251,8 +1251,8 @@ st_connectinfo(g)
sockaddr.sin6.sin6_port = port; sockaddr.sin6.sin6_port = port;
} }
else else
# endif /* NETINET6 */ #endif /* NETINET6 */
# if NETUNIX #if NETUNIX
if (family == SMFIA_UNIX) if (family == SMFIA_UNIX)
{ {
if (sm_strlcpy(sockaddr.sunix.sun_path, s + i, if (sm_strlcpy(sockaddr.sunix.sun_path, s + i,
@ -1268,7 +1268,7 @@ st_connectinfo(g)
sockaddr.sunix.sun_family = AF_UNIX; sockaddr.sunix.sun_family = AF_UNIX;
} }
else else
# endif /* NETUNIX */ #endif /* NETUNIX */
{ {
smi_log(SMI_LOG_ERR, smi_log(SMI_LOG_ERR,
"%s: connect[%ld]: unknown family %d", "%s: connect[%ld]: unknown family %d",
@ -1870,21 +1870,21 @@ mi_rd_socket_ready (sd)
{ {
int n; int n;
int nerr = 0; int nerr = 0;
#if SM_CONF_POLL # if SM_CONF_POLL
struct pollfd pfd; struct pollfd pfd;
#else # else
fd_set rd_set, exc_set; fd_set rd_set, exc_set;
#endif # endif
do do
{ {
#if SM_CONF_POLL # if SM_CONF_POLL
pfd.fd = sd; pfd.fd = sd;
pfd.events = POLLIN; pfd.events = POLLIN;
pfd.revents = 0; pfd.revents = 0;
n = poll(&pfd, 1, MI_RD_CMD_TO); n = poll(&pfd, 1, MI_RD_CMD_TO);
#else /* SM_CONF_POLL */ # else /* SM_CONF_POLL */
struct timeval timeout; struct timeval timeout;
FD_ZERO(&rd_set); FD_ZERO(&rd_set);
@ -1895,7 +1895,7 @@ mi_rd_socket_ready (sd)
timeout.tv_sec = MI_RD_CMD_TO / 1000; timeout.tv_sec = MI_RD_CMD_TO / 1000;
timeout.tv_usec = 0; timeout.tv_usec = 0;
n = select(sd + 1, &rd_set, NULL, &exc_set, &timeout); n = select(sd + 1, &rd_set, NULL, &exc_set, &timeout);
#endif /* SM_CONF_POLL */ # endif /* SM_CONF_POLL */
if (n < 0) if (n < 0)
{ {
@ -1914,10 +1914,10 @@ mi_rd_socket_ready (sd)
if (nerr >= MI_RD_MAX_ERR) if (nerr >= MI_RD_MAX_ERR)
return false; return false;
#if SM_CONF_POLL # if SM_CONF_POLL
return (pfd.revents != 0); return (pfd.revents != 0);
#else # else
return FD_ISSET(sd, &rd_set) || FD_ISSET(sd, &exc_set); return FD_ISSET(sd, &rd_set) || FD_ISSET(sd, &exc_set);
#endif # endif
} }
#endif /* _FFR_WORKERS_POOL */ #endif /* _FFR_WORKERS_POOL */

View file

@ -22,13 +22,13 @@ SM_RCSID("@(#)$Id: listener.c,v 8.127 2013-11-22 20:51:36 ca Exp $")
#include <sys/stat.h> #include <sys/stat.h>
# if NETINET || NETINET6 #if NETINET || NETINET6
# include <arpa/inet.h> # include <arpa/inet.h>
# endif #endif
# if SM_CONF_POLL #if SM_CONF_POLL
# undef SM_FD_OK_SELECT # undef SM_FD_OK_SELECT
# define SM_FD_OK_SELECT(fd) true # define SM_FD_OK_SELECT(fd) true
# endif #endif
static smutex_t L_Mutex; static smutex_t L_Mutex;
static int L_family; static int L_family;
@ -815,9 +815,9 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
if (ValidSocket(connfd) && if (ValidSocket(connfd) &&
(clilen == 0 || (clilen == 0 ||
# ifdef BSD4_4_SOCKADDR #ifdef BSD4_4_SOCKADDR
cliaddr.sa.sa_len == 0 || cliaddr.sa.sa_len == 0 ||
# endif #endif
cliaddr.sa.sa_family != L_family)) cliaddr.sa.sa_family != L_family))
{ {
(void) closesocket(connfd); (void) closesocket(connfd);
@ -961,7 +961,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
tcnt++; tcnt++;
smi_log(SMI_LOG_ERR, smi_log(SMI_LOG_ERR,
LOG_CRT_FAIL, LOG_CRT_FAIL,
smfi->xxfi_name, r, smfi->xxfi_name, r,
tcnt >= MAX_FAILS_T ? "abort" : "try again"); tcnt >= MAX_FAILS_T ? "abort" : "try again");
MI_SLEEP(tcnt); MI_SLEEP(tcnt);
(void) closesocket(connfd); (void) closesocket(connfd);
@ -980,8 +980,10 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
else else
{ {
if (mistop != MILTER_CONT) if (mistop != MILTER_CONT)
smi_log(SMI_LOG_INFO, "%s: mi_stop=%d", smi_log(SMI_LOG_INFO, "%s=%s",
smfi->xxfi_name, mistop); smfi->xxfi_name,
MILTER_STOP == mistop ? "terminating"
: "aborting");
mi_closener(); mi_closener();
} }
(void) smutex_destroy(&L_Mutex); (void) smutex_destroy(&L_Mutex);

View file

@ -149,9 +149,9 @@ mi_gethostbyname(name, family)
/* the function is supposed to return only the requested family */ /* the function is supposed to return only the requested family */
if (h != NULL && h->h_addrtype != family) if (h != NULL && h->h_addrtype != family)
{ {
# if NETINET6 #if NETINET6
freehostent(h); freehostent(h);
# endif #endif
h = NULL; h = NULL;
SM_SET_H_ERRNO(NO_DATA); SM_SET_H_ERRNO(NO_DATA);
} }

View file

@ -6,11 +6,12 @@ define(`confREQUIRE_LIBSM', `true')
define(`confREQUIRE_SM_OS_H', `true') define(`confREQUIRE_SM_OS_H', `true')
PREPENDDEF(`confENVDEF', `confMAPDEF') PREPENDDEF(`confENVDEF', `confMAPDEF')
bldPRODUCT_START(`library', `libsm') bldPRODUCT_START(`library', `libsm')
define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c inet6_ntop.c notify.c ') define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c inet6_ntop.c notify.c ilenx.c xleni.c utf8_valid.c uxtext_unquote.c lowercase.c strcaseeq.c ')
bldPRODUCT_END bldPRODUCT_END
dnl msg.c dnl msg.c
dnl syslogio.c dnl syslogio.c
srcdir=${SRCDIR}/libsm
define(`confCHECK_LIBS',`libsm.a')dnl define(`confCHECK_LIBS',`libsm.a')dnl
include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/check.m4') include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/check.m4')
smcheck(`t-event', `compile-run') smcheck(`t-event', `compile-run')
@ -32,8 +33,6 @@ smcheck(`t-scanf', `compile-run')
smcheck(`t-shm', `compile-run') smcheck(`t-shm', `compile-run')
smcheck(`t-sem', `compile-run') smcheck(`t-sem', `compile-run')
smcheck(`t-inet6_ntop', `compile-run') smcheck(`t-inet6_ntop', `compile-run')
smcheck(`t-notify', `compile-run')
dnl smcheck(`t-msg', `compile-run')
smcheck(`t-cf') smcheck(`t-cf')
smcheck(`b-strcmp') smcheck(`b-strcmp')
dnl SM_CONF_STRL cannot be turned off dnl SM_CONF_STRL cannot be turned off
@ -41,6 +40,13 @@ dnl smcheck(`b-strl')
smcheck(`t-memstat') smcheck(`t-memstat')
smcheck(`t-qic', `compile-run') smcheck(`t-qic', `compile-run')
smcheck(`t-str2prt', `compile-run')
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(bldTARGETS_SECTION)
divert(0) divert(0)

View file

@ -18,6 +18,7 @@ SM_RCSID("@(#)$Id: cf.c,v 1.8 2013-11-22 20:51:42 ca Exp $")
#include <sm/io.h> #include <sm/io.h>
#include <sm/string.h> #include <sm/string.h>
#include <sm/heap.h> #include <sm/heap.h>
#include <sm/sendmail.h>
/* /*
** SM_CF_GETOPT -- look up option values in the sendmail.cf file ** SM_CF_GETOPT -- look up option values in the sendmail.cf file
@ -80,7 +81,7 @@ sm_cf_getopt(path, optc, optv)
for (i = 0; i < optc; ++i) for (i = 0; i < optc; ++i)
{ {
if (sm_strcasecmp(optv[i].opt_name, id) == 0) if (SM_STRCASEEQ(optv[i].opt_name, id))
{ {
optv[i].opt_val = sm_strdup_x(val); optv[i].opt_val = sm_strdup_x(val);
break; break;

View file

@ -162,7 +162,7 @@ sm_sigsafe_seteventm(intvl, func, arg)
LEAVE_CRITICAL(); LEAVE_CRITICAL();
(void) sm_signal(SIGALRM, sm_tick); (void) sm_signal(SIGALRM, sm_tick);
# if SM_CONF_SETITIMER #if SM_CONF_SETITIMER
timersub(&SmEventQueue->ev_time, &now, &itime.it_value); timersub(&SmEventQueue->ev_time, &now, &itime.it_value);
itime.it_interval.tv_sec = 0; itime.it_interval.tv_sec = 0;
itime.it_interval.tv_usec = 0; itime.it_interval.tv_usec = 0;
@ -171,10 +171,10 @@ sm_sigsafe_seteventm(intvl, func, arg)
if (itime.it_value.tv_sec == 0 && itime.it_value.tv_usec == 0) if (itime.it_value.tv_sec == 0 && itime.it_value.tv_usec == 0)
itime.it_value.tv_usec = 1000; itime.it_value.tv_usec = 1000;
(void) setitimer(ITIMER_REAL, &itime, NULL); (void) setitimer(ITIMER_REAL, &itime, NULL);
# else /* SM_CONF_SETITIMER */ #else /* SM_CONF_SETITIMER */
intvl = SmEventQueue->ev_time - now; intvl = SmEventQueue->ev_time - now;
(void) alarm((unsigned) (intvl < 1 ? 1 : intvl)); (void) alarm((unsigned) (intvl < 1 ? 1 : intvl));
# endif /* SM_CONF_SETITIMER */ #endif /* SM_CONF_SETITIMER */
if (wasblocked == 0) if (wasblocked == 0)
(void) sm_releasesignal(SIGALRM); (void) sm_releasesignal(SIGALRM);
return ev; return ev;
@ -198,9 +198,9 @@ sm_clrevent(ev)
{ {
register SM_EVENT **evp; register SM_EVENT **evp;
int wasblocked; int wasblocked;
# if SM_CONF_SETITIMER #if SM_CONF_SETITIMER
struct itimerval clr; struct itimerval clr;
# endif #endif
if (ev == NULL) if (ev == NULL)
return; return;
@ -233,15 +233,15 @@ sm_clrevent(ev)
else else
{ {
/* nothing left in event queue, no need for an alarm */ /* nothing left in event queue, no need for an alarm */
# if SM_CONF_SETITIMER #if SM_CONF_SETITIMER
clr.it_interval.tv_sec = 0; clr.it_interval.tv_sec = 0;
clr.it_interval.tv_usec = 0; clr.it_interval.tv_usec = 0;
clr.it_value.tv_sec = 0; clr.it_value.tv_sec = 0;
clr.it_value.tv_usec = 0; clr.it_value.tv_usec = 0;
(void) setitimer(ITIMER_REAL, &clr, NULL); (void) setitimer(ITIMER_REAL, &clr, NULL);
# else /* SM_CONF_SETITIMER */ #else /* SM_CONF_SETITIMER */
(void) alarm(0); (void) alarm(0);
# endif /* SM_CONF_SETITIMER */ #endif /* SM_CONF_SETITIMER */
} }
} }
/* /*
@ -496,10 +496,10 @@ sm_tick(sig)
*/ */
# if !HAVE_NANOSLEEP #if !HAVE_NANOSLEEP
static void sm_endsleep __P((int)); static void sm_endsleep __P((int));
static bool volatile SmSleepDone; static bool volatile SmSleepDone;
# endif #endif
#ifndef SLEEP_T #ifndef SLEEP_T
# define SLEEP_T unsigned int # define SLEEP_T unsigned int
@ -521,70 +521,70 @@ sleep(intvl)
#else /* HAVE_NANOSLEEP */ #else /* HAVE_NANOSLEEP */
int was_held; int was_held;
SM_EVENT *ev; SM_EVENT *ev;
#if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
int r; int r;
# if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
struct timeval sm_io_to; struct timeval sm_io_to;
# endif # endif
#endif /* _FFR_SLEEP_USE_SELECT > 0 */ # endif /* _FFR_SLEEP_USE_SELECT > 0 */
#if SM_CONF_SETITIMER # if SM_CONF_SETITIMER
struct timeval now, begin, diff; struct timeval now, begin, diff;
# if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
struct timeval slpv; struct timeval slpv;
# endif # endif
#else /* SM_CONF_SETITIMER */ # else /* SM_CONF_SETITIMER */
time_t begin, now; time_t begin, now;
#endif /* SM_CONF_SETITIMER */ # endif /* SM_CONF_SETITIMER */
if (intvl == 0) if (intvl == 0)
return (SLEEP_T) 0; return (SLEEP_T) 0;
#if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 # if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2
if (intvl > _FFR_MAX_SLEEP_TIME) if (intvl > _FFR_MAX_SLEEP_TIME)
{ {
syslog(LOG_ERR, "sleep: interval=%u exceeds max value %d", syslog(LOG_ERR, "sleep: interval=%u exceeds max value %d",
intvl, _FFR_MAX_SLEEP_TIME); intvl, _FFR_MAX_SLEEP_TIME);
# if 0 # if 0
SM_ASSERT(intvl < (unsigned int) INT_MAX); SM_ASSERT(intvl < (unsigned int) INT_MAX);
# endif # endif
intvl = _FFR_MAX_SLEEP_TIME; intvl = _FFR_MAX_SLEEP_TIME;
} }
#endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */ # endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */
SmSleepDone = false; SmSleepDone = false;
#if SM_CONF_SETITIMER # if SM_CONF_SETITIMER
# if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
slpv.tv_sec = intvl; slpv.tv_sec = intvl;
slpv.tv_usec = 0; slpv.tv_usec = 0;
# endif # endif
(void) gettimeofday(&now, NULL); (void) gettimeofday(&now, NULL);
begin = now; begin = now;
#else /* SM_CONF_SETITIMER */ # else /* SM_CONF_SETITIMER */
now = begin = time(NULL); now = begin = time(NULL);
#endif /* SM_CONF_SETITIMER */ # endif /* SM_CONF_SETITIMER */
ev = sm_setevent((time_t) intvl, sm_endsleep, 0); ev = sm_setevent((time_t) intvl, sm_endsleep, 0);
if (ev == NULL) if (ev == NULL)
{ {
/* COMPLAIN */ /* COMPLAIN */
#if 0 # if 0
syslog(LOG_ERR, "sleep: sm_setevent(%u) failed", intvl); syslog(LOG_ERR, "sleep: sm_setevent(%u) failed", intvl);
#endif # endif
SmSleepDone = true; SmSleepDone = true;
} }
was_held = sm_releasesignal(SIGALRM); was_held = sm_releasesignal(SIGALRM);
while (!SmSleepDone) while (!SmSleepDone)
{ {
#if SM_CONF_SETITIMER # if SM_CONF_SETITIMER
(void) gettimeofday(&now, NULL); (void) gettimeofday(&now, NULL);
timersub(&now, &begin, &diff); timersub(&now, &begin, &diff);
if (diff.tv_sec < 0 || if (diff.tv_sec < 0 ||
(diff.tv_sec == 0 && diff.tv_usec == 0)) (diff.tv_sec == 0 && diff.tv_usec == 0))
break; break;
# if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
timersub(&slpv, &diff, &sm_io_to); timersub(&slpv, &diff, &sm_io_to);
# endif # endif
#else /* SM_CONF_SETITIMER */ # else /* SM_CONF_SETITIMER */
now = time(NULL); now = time(NULL);
/* /*
@ -595,14 +595,14 @@ sleep(intvl)
if (!(begin + (time_t) intvl + 1 > now)) if (!(begin + (time_t) intvl + 1 > now))
break; break;
# if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
sm_io_to.tv_sec = intvl - (now - begin); sm_io_to.tv_sec = intvl - (now - begin);
if (sm_io_to.tv_sec <= 0) if (sm_io_to.tv_sec <= 0)
sm_io_to.tv_sec = 1; sm_io_to.tv_sec = 1;
sm_io_to.tv_usec = 0; sm_io_to.tv_usec = 0;
# endif /* _FFR_SLEEP_USE_SELECT > 0 */ # endif /* _FFR_SLEEP_USE_SELECT > 0 */
#endif /* SM_CONF_SETITIMER */ # endif /* SM_CONF_SETITIMER */
#if _FFR_SLEEP_USE_SELECT > 0 # if _FFR_SLEEP_USE_SELECT > 0
if (intvl <= _FFR_SLEEP_USE_SELECT) if (intvl <= _FFR_SLEEP_USE_SELECT)
{ {
r = select(0, NULL, NULL, NULL, &sm_io_to); r = select(0, NULL, NULL, NULL, &sm_io_to);
@ -610,7 +610,8 @@ sleep(intvl)
break; break;
} }
else else
#endif /* _FFR_SLEEP_USE_SELECT > 0 */ # endif /* _FFR_SLEEP_USE_SELECT > 0 */
/* "else" in #if code above */
(void) pause(); (void) pause();
} }

View file

@ -219,12 +219,10 @@ char *SmCompileOptions[] =
"SM_CONF_STDDEF_H", "SM_CONF_STDDEF_H",
#endif #endif
#if 0
/* XXX this is always enabled (for now) */ /* XXX this is always enabled (for now) */
#if SM_CONF_STRL #if SM_CONF_STRL && 0
"SM_CONF_STRL", "SM_CONF_STRL",
#endif #endif
#endif /* 0 */
#if SM_CONF_SYS_CDEFS_H #if SM_CONF_SYS_CDEFS_H
"SM_CONF_SYS_CDEFS_H", "SM_CONF_SYS_CDEFS_H",

View file

@ -25,6 +25,13 @@ SM_RCSID("@(#)$Id: heap.c,v 1.52 2013-11-22 20:51:43 ca Exp $")
#include <sm/signal.h> #include <sm/signal.h>
#include <sm/xtrap.h> #include <sm/xtrap.h>
#if SM_HEAP_CHECK
# include <unistd.h>
# include <sm/types.h>
# include <sm/time.h>
# include <time.h>
#endif
/* undef all macro versions of the "functions" so they can be specified here */ /* undef all macro versions of the "functions" so they can be specified here */
#undef sm_malloc #undef sm_malloc
#undef sm_malloc_x #undef sm_malloc_x
@ -458,7 +465,7 @@ sm_malloc_tagged_x(size, tag, num, group)
** Parameters: ** Parameters:
** ptr -- pointer to register. ** ptr -- pointer to register.
** size -- size of requested memory. ** size -- size of requested memory.
** tag -- tag for debugging. ** tag -- tag for debugging (this is NOT copied!)
** num -- additional value for debugging. ** num -- additional value for debugging.
** group -- heap group for debugging. ** group -- heap group for debugging.
** **
@ -754,6 +761,9 @@ sm_heap_report(stream, verbosity)
{ {
int i; int i;
unsigned long group0total, group1total, otherstotal, grandtotal; unsigned long group0total, group1total, otherstotal, grandtotal;
static char str[32] = "[1900-00-00/00:00:00] ";
struct tm *tmp;
time_t currt;
if (!HEAP_CHECK || verbosity <= 0) if (!HEAP_CHECK || verbosity <= 0)
return; return;
@ -804,11 +814,18 @@ sm_heap_report(stream, verbosity)
hi = hi->hi_next; hi = hi->hi_next;
} }
} }
currt = time((time_t *)0);
tmp = localtime(&currt);
snprintf(str, sizeof(str), "[%d-%02d-%02d/%02d:%02d:%02d] ",
1900 + tmp->tm_year, /* HACK */
tmp->tm_mon + 1,
tmp->tm_mday,
tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
sm_io_fprintf(stream, SM_TIME_DEFAULT, sm_io_fprintf(stream, SM_TIME_DEFAULT,
"heap max=%lu, total=%lu, ", "pid=%ld time=%s\nheap max=%lu, total=%lu, group 0=%lu, group 1=%lu, others=%lu\n",
(unsigned long) SmHeapMaxTotal, grandtotal); (long) getpid(), str,
sm_io_fprintf(stream, SM_TIME_DEFAULT, (unsigned long) SmHeapMaxTotal, grandtotal,
"group 0=%lu, group 1=%lu, others=%lu\n",
group0total, group1total, otherstotal); group0total, group1total, otherstotal);
if (grandtotal != SmHeapTotal) if (grandtotal != SmHeapTotal)
{ {

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
#include <sm/sendmail.h>
#include <sm/ixlen.h>
#if _FFR_8BITENVADDR
/*
** ILENX -- determine the e'x'ternal length of a string in 'i'internal format
**
** Parameters:
** str -- string [i]
**
** Returns:
** e'x'ternal length of a string in 'i'internal format
*/
int
ilenx(str)
const char *str;
{
char c;
int idx;
XLENDECL
if (NULL == str)
return -1;
for (idx = 0; (c = str[idx]) != '\0'; idx++)
XLEN(c);
return xlen;
}
#endif /* _FFR_8BITENVADDR */

View file

@ -27,10 +27,8 @@ SM_RCSID("@(#)$Id: ldap.c,v 1.86 2013-11-22 20:51:43 ca Exp $")
# include <sm/errstring.h> # include <sm/errstring.h>
# include <sm/ldap.h> # include <sm/ldap.h>
# include <sm/string.h> # include <sm/string.h>
# ifdef EX_OK
# undef EX_OK /* for SVr4.2 SMP */
# endif
# include <sm/sysexits.h> # include <sm/sysexits.h>
# include <sm/sendmail.h>
SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap", SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap",
"@(#)$Debug: sm_trace_ldap - trace LDAP operations $"); "@(#)$Debug: sm_trace_ldap - trace LDAP operations $");
@ -49,17 +47,17 @@ static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **,
** **
*/ */
#if _FFR_LDAP_VERSION # if _FFR_LDAP_VERSION
# if defined(LDAP_VERSION_MAX) && _FFR_LDAP_VERSION > LDAP_VERSION_MAX # 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 # endif
# if defined(LDAP_VERSION_MIN) && _FFR_LDAP_VERSION < LDAP_VERSION_MIN # if defined(LDAP_VERSION_MIN) && _FFR_LDAP_VERSION < LDAP_VERSION_MIN
ERROR FFR_LDAP_VERSION < _LDAP_VERSION_MIN # ERROR "_FFR_LDAP_VERSION < LDAP_VERSION_MAX"
# endif # endif
# define SM_LDAP_VERSION_DEFAULT _FFR_LDAP_VERSION # define SM_LDAP_VERSION_DEFAULT _FFR_LDAP_VERSION
#else /* _FFR_LDAP_VERSION */ # else /* _FFR_LDAP_VERSION */
# define SM_LDAP_VERSION_DEFAULT 0 # define SM_LDAP_VERSION_DEFAULT 0
#endif /* _FFR_LDAP_VERSION */ # endif /* _FFR_LDAP_VERSION */
void void
sm_ldap_clear(lmap) sm_ldap_clear(lmap)
@ -100,7 +98,7 @@ sm_ldap_clear(lmap)
lmap->ldap_multi_args = false; lmap->ldap_multi_args = false;
} }
# if _FFR_SM_LDAP_DBG && defined(LBER_OPT_LOG_PRINT_FN) # if _FFR_SM_LDAP_DBG && defined(LBER_OPT_LOG_PRINT_FN)
static void ldap_debug_cb __P((const char *msg)); static void ldap_debug_cb __P((const char *msg));
static void static void
@ -110,7 +108,7 @@ ldap_debug_cb(msg)
if (sm_debug_active(&SmLDAPTrace, 4)) if (sm_debug_active(&SmLDAPTrace, 4))
sm_dprintf("%s", msg); sm_dprintf("%s", msg);
} }
# endif /* _FFR_SM_LDAP_DBG && defined(LBER_OPT_LOG_PRINT_FN) */ # endif /* _FFR_SM_LDAP_DBG && defined(LBER_OPT_LOG_PRINT_FN) */
# if LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) # if LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT)
@ -298,7 +296,7 @@ do \
if (ev != NULL) \ if (ev != NULL) \
sm_clrevent(ev); \ sm_clrevent(ev); \
} while (0) } while (0)
#endif /* !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT */ # endif /* !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT */
bool bool
sm_ldap_start(name, lmap) sm_ldap_start(name, lmap)
@ -336,7 +334,7 @@ sm_ldap_start(name, lmap)
if (lmap->ldap_uri != NULL) if (lmap->ldap_uri != NULL)
{ {
#if SM_CONF_LDAP_INITIALIZE # if SM_CONF_LDAP_INITIALIZE
if (sm_debug_active(&SmLDAPTrace, 9)) if (sm_debug_active(&SmLDAPTrace, 9))
sm_dprintf("ldap_initialize(%s)\n", lmap->ldap_uri); sm_dprintf("ldap_initialize(%s)\n", lmap->ldap_uri);
/* LDAP server supports URIs so use them directly */ /* LDAP server supports URIs so use them directly */
@ -345,7 +343,7 @@ sm_ldap_start(name, lmap)
sm_dprintf("ldap_initialize(%s)=%d, ld=%p\n", lmap->ldap_uri, save_errno, ld); sm_dprintf("ldap_initialize(%s)=%d, ld=%p\n", lmap->ldap_uri, save_errno, ld);
sm_ldap_setoptsg(lmap); sm_ldap_setoptsg(lmap);
#else /* SM_CONF_LDAP_INITIALIZE */ # else /* SM_CONF_LDAP_INITIALIZE */
LDAPURLDesc *ludp = NULL; LDAPURLDesc *ludp = NULL;
/* Blast apart URL and use the ldap_init/ldap_open below */ /* Blast apart URL and use the ldap_init/ldap_open below */
@ -365,7 +363,7 @@ sm_ldap_start(name, lmap)
} }
lmap->ldap_port = ludp->lud_port; lmap->ldap_port = ludp->lud_port;
ldap_free_urldesc(ludp); ldap_free_urldesc(ludp);
#endif /* SM_CONF_LDAP_INITIALIZE */ # endif /* SM_CONF_LDAP_INITIALIZE */
} }
if (ld == NULL) if (ld == NULL)
@ -537,9 +535,9 @@ sm_ldap_search_m(lmap, argv)
if (lmap->ldap_multi_args) if (lmap->ldap_multi_args)
{ {
#if SM_LDAP_ARGS < 10 # if SM_LDAP_ARGS < 10
# ERROR _SM_LDAP_ARGS must be 10 # ERROR _SM_LDAP_ARGS must be 10
#endif /* SM_LDAP_ARGS < 10 */ # endif
if (q[1] == 's') if (q[1] == 's')
key = argv[0]; key = argv[0];
else if (q[1] >= '0' && q[1] <= '9') else if (q[1] >= '0' && q[1] <= '9')
@ -549,9 +547,9 @@ sm_ldap_search_m(lmap, argv)
{ {
# if SM_LDAP_ERROR_ON_MISSING_ARGS # if SM_LDAP_ERROR_ON_MISSING_ARGS
return SM_LDAP_ERR_ARG_MISS; return SM_LDAP_ERR_ARG_MISS;
# else /* SM_LDAP_ERROR_ON_MISSING_ARGS */ # else
key = ""; key = "";
# endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */ # endif
} }
} }
else else
@ -907,7 +905,7 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
continue; continue;
} }
#if _FFR_LDAP_SINGLEDN # if _FFR_LDAP_SINGLEDN
if (bitset(SM_LDAP_SINGLEDN, flags) && *result != NULL) if (bitset(SM_LDAP_SINGLEDN, flags) && *result != NULL)
{ {
/* only wanted one match */ /* only wanted one match */
@ -915,7 +913,7 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
errno = ENOENT; errno = ENOENT;
return EX_NOTFOUND; return EX_NOTFOUND;
} }
#endif /* _FFR_LDAP_SINGLEDN */ # endif /* _FFR_LDAP_SINGLEDN */
/* record completed DN's to prevent loops */ /* record completed DN's to prevent loops */
dn = ldap_get_dn(lmap->ldap_ld, entry); dn = ldap_get_dn(lmap->ldap_ld, entry);
@ -970,8 +968,8 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
type = SM_LDAP_ATTR_NONE; type = SM_LDAP_ATTR_NONE;
for (i = 0; lmap->ldap_attr[i] != NULL; i++) for (i = 0; lmap->ldap_attr[i] != NULL; i++)
{ {
if (sm_strcasecmp(lmap->ldap_attr[i], if (SM_STRCASEEQ(lmap->ldap_attr[i],
attr) == 0) attr))
{ {
type = lmap->ldap_attr_type[i]; type = lmap->ldap_attr_type[i];
needobjclass = lmap->ldap_attr_needobjclass[i]; needobjclass = lmap->ldap_attr_needobjclass[i];
@ -1342,9 +1340,9 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
statp = EX_TEMPFAIL; statp = EX_TEMPFAIL;
switch (save_errno) switch (save_errno)
{ {
#ifdef LDAP_SERVER_DOWN # ifdef LDAP_SERVER_DOWN
case LDAP_SERVER_DOWN: case LDAP_SERVER_DOWN:
#endif /* LDAP_SERVER_DOWN */ # endif
case LDAP_TIMEOUT: case LDAP_TIMEOUT:
case ETIMEDOUT: case ETIMEDOUT:
case LDAP_UNAVAILABLE: case LDAP_UNAVAILABLE:
@ -1504,9 +1502,9 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
statp = EX_TEMPFAIL; statp = EX_TEMPFAIL;
switch (save_errno) switch (save_errno)
{ {
#ifdef LDAP_SERVER_DOWN # ifdef LDAP_SERVER_DOWN
case LDAP_SERVER_DOWN: case LDAP_SERVER_DOWN:
#endif /* LDAP_SERVER_DOWN */ # endif
case LDAP_TIMEOUT: case LDAP_TIMEOUT:
case ETIMEDOUT: case ETIMEDOUT:
case LDAP_UNAVAILABLE: case LDAP_UNAVAILABLE:
@ -1616,4 +1614,4 @@ sm_ldap_geterrno(ld)
# endif /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */ # endif /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */
return err; return err;
} }
# endif /* LDAPMAP */ #endif /* LDAPMAP */

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
#include <sm/sendmail.h>
#include <ctype.h>
#include <sm/string.h>
#include <sm/heap.h>
#if USE_EAI
# include <sm/ixlen.h>
# include <unicode/ucasemap.h>
# include <unicode/ustring.h>
# include <unicode/uchar.h>
/*
** ASCIISTR -- check whether a string is printable ASCII
**
** Parameters:
** str -- string
**
** Returns:
** TRUE iff printable ASCII
*/
bool
asciistr(str)
const char *str;
{
unsigned char ch;
if (str == NULL)
return true;
while ((ch = (unsigned char)*str) != '\0' && ch >= 32 && ch < 127)
str++;
return ch == '\0';
}
#endif /* USE_EAI */
/*
** MAKELOWER -- Translate a line into lower case
**
** Parameters:
** p -- string to translate (modified in place if possible). [A]
**
** Returns:
** lower cased string
**
** Side Effects:
** String p is translated to lower case if possible.
*/
char *
makelower(p)
char *p;
{
char c;
char *orig;
if (p == NULL)
return p;
orig = p;
#if USE_EAI
if (!asciistr(p))
return (char *)sm_lowercase(p);
#endif
for (; (c = *p) != '\0'; p++)
if (isascii(c) && isupper(c))
*p = tolower(c);
return orig;
}
#if USE_EAI
/*
** SM_LOWERCASE -- lower case a UTF-8 string
** Note: this should ONLY be applied to a UTF-8 string,
** i.e., the caller should check first if it isn't an ASCII string.
**
** Parameters:
** str -- original string
**
** Returns:
** lower case version of string [S]
**
** How to return an error description due to failed unicode calls?
** However, is that even relevant?
*/
char *
sm_lowercase(str)
const char *str;
{
int olen, ilen;
UErrorCode error;
ssize_t req;
int n;
static UCaseMap *csm = NULL;
static char *out = NULL;
static int outlen = 0;
# if SM_CHECK_REQUIRE
if (sm_debug_active(&SmExpensiveRequire, 3))
SM_REQUIRE(!asciistr(str));
# endif
/* an empty string is always ASCII */
SM_REQUIRE(NULL != str && '\0' != *str);
if (NULL == csm)
{
error = U_ZERO_ERROR;
csm = ucasemap_open("en_US", U_FOLD_CASE_DEFAULT, &error);
if (U_SUCCESS(error) == 0)
{
/* syserr("ucasemap_open error: %s", u_errorName(error)); */
return NULL;
}
}
ilen = strlen(str);
olen = ilen + 1;
if (olen > outlen)
{
outlen = olen;
out = sm_realloc_x(out, outlen);
}
for (n = 0; n < 3; n++)
{
error = U_ZERO_ERROR;
req = ucasemap_utf8FoldCase(csm, out, olen, str, ilen, &error);
if (U_SUCCESS(error))
{
if (req >= olen)
{
outlen = req + 1;
out = sm_realloc_x(out, outlen);
out[req] = '\0';
}
break;
}
else if (error == U_BUFFER_OVERFLOW_ERROR)
{
outlen = req + 1;
out = sm_realloc_x(out, outlen);
olen = outlen;
}
else
{
/* syserr("conversion error for \"%s\": %s", str, u_errorName(error)); */
return NULL;
}
}
return out;
}
#endif /* USE_EAI */

View file

@ -124,7 +124,7 @@ sm_whatbuf(fp, bufsize, couldbetty)
st.st_blksize = SM_IO_MAX_BUF; st.st_blksize = SM_IO_MAX_BUF;
# if SM_IO_MIN_BUF > 0 # if SM_IO_MIN_BUF > 0
else else
# endif /* SM_IO_MIN_BUF > 0 */ # endif
# endif /* SM_IO_MAX_BUF > 0 */ # endif /* SM_IO_MAX_BUF > 0 */
# if SM_IO_MIN_BUF > 0 # if SM_IO_MIN_BUF > 0
if (st.st_blksize < SM_IO_MIN_BUF) if (st.st_blksize < SM_IO_MIN_BUF)

View file

@ -27,16 +27,11 @@ SM_RCSID("@(#)$Id: mbdb.c,v 1.43 2014-01-08 17:03:15 ca Exp $")
#include <sm/heap.h> #include <sm/heap.h>
#include <sm/mbdb.h> #include <sm/mbdb.h>
#include <sm/string.h> #include <sm/string.h>
# ifdef EX_OK
# undef EX_OK /* for SVr4.2 SMP */
# endif
#include <sm/sysexits.h> #include <sm/sysexits.h>
#if LDAPMAP #if LDAPMAP && _LDAP_EXAMPLE_
# if _LDAP_EXAMPLE_ # include <sm/ldap.h>
# include <sm/ldap.h> #endif
# endif
#endif /* LDAPMAP */
typedef struct typedef struct
{ {
@ -50,23 +45,19 @@ static int mbdb_pw_initialize __P((char *));
static int mbdb_pw_lookup __P((char *name, SM_MBDB_T *user)); static int mbdb_pw_lookup __P((char *name, SM_MBDB_T *user));
static void mbdb_pw_terminate __P((void)); static void mbdb_pw_terminate __P((void));
#if LDAPMAP #if LDAPMAP && _LDAP_EXAMPLE_
# if _LDAP_EXAMPLE_
static struct sm_ldap_struct LDAPLMAP; static struct sm_ldap_struct LDAPLMAP;
static int mbdb_ldap_initialize __P((char *)); static int mbdb_ldap_initialize __P((char *));
static int mbdb_ldap_lookup __P((char *name, SM_MBDB_T *user)); static int mbdb_ldap_lookup __P((char *name, SM_MBDB_T *user));
static void mbdb_ldap_terminate __P((void)); static void mbdb_ldap_terminate __P((void));
# endif /* _LDAP_EXAMPLE_ */ #endif /* LDAPMAP && _LDAP_EXAMPLE_ */
#endif /* LDAPMAP */
static SM_MBDB_TYPE_T SmMbdbTypes[] = static SM_MBDB_TYPE_T SmMbdbTypes[] =
{ {
{ "pw", mbdb_pw_initialize, mbdb_pw_lookup, mbdb_pw_terminate }, { "pw", mbdb_pw_initialize, mbdb_pw_lookup, mbdb_pw_terminate },
#if LDAPMAP #if LDAPMAP && _LDAP_EXAMPLE_
# if _LDAP_EXAMPLE_
{ "ldap", mbdb_ldap_initialize, mbdb_ldap_lookup, mbdb_ldap_terminate }, { "ldap", mbdb_ldap_initialize, mbdb_ldap_lookup, mbdb_ldap_terminate },
# endif #endif
#endif /* LDAPMAP */
{ NULL, NULL, NULL, NULL } { NULL, NULL, NULL, NULL }
}; };
@ -268,6 +259,7 @@ sm_pwfullname(gecos, user, buf, buflen)
*bp++ = Latin1ToASCII[(unsigned char) *p - 128]; *bp++ = Latin1ToASCII[(unsigned char) *p - 128];
else else
#endif #endif
/* "else" in #if code above */
*bp++ = *p; *bp++ = *p;
} }
} }
@ -365,8 +357,7 @@ mbdb_pw_terminate()
endpwent(); endpwent();
} }
#if LDAPMAP #if LDAPMAP && _LDAP_EXAMPLE_
# if _LDAP_EXAMPLE_
/* /*
** LDAP example implementation based on RFC 2307, "An Approach for Using ** LDAP example implementation based on RFC 2307, "An Approach for Using
** LDAP as a Network Information Service": ** LDAP as a Network Information Service":
@ -404,19 +395,19 @@ mbdb_pw_terminate()
** **
*/ */
# define MBDB_LDAP_LABEL "MailboxDatabase" # define MBDB_LDAP_LABEL "MailboxDatabase"
# ifndef MBDB_LDAP_FILTER # ifndef MBDB_LDAP_FILTER
# define MBDB_LDAP_FILTER "(&(objectClass=posixAccount)(uid=%0))" # define MBDB_LDAP_FILTER "(&(objectClass=posixAccount)(uid=%0))"
# endif # endif
# ifndef MBDB_DEFAULT_LDAP_BASEDN # ifndef MBDB_DEFAULT_LDAP_BASEDN
# define MBDB_DEFAULT_LDAP_BASEDN NULL # define MBDB_DEFAULT_LDAP_BASEDN NULL
# endif # endif
# ifndef MBDB_DEFAULT_LDAP_SERVER # ifndef MBDB_DEFAULT_LDAP_SERVER
# define MBDB_DEFAULT_LDAP_SERVER NULL # define MBDB_DEFAULT_LDAP_SERVER NULL
# endif # endif
/* /*
** MBDB_LDAP_INITIALIZE -- initialize LDAP version ** MBDB_LDAP_INITIALIZE -- initialize LDAP version
@ -526,13 +517,13 @@ mbdb_ldap_lookup(name, user)
if (msgid == -1) if (msgid == -1)
{ {
save_errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld) + E_LDAPBASE; save_errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld) + E_LDAPBASE;
# ifdef LDAP_SERVER_DOWN # ifdef LDAP_SERVER_DOWN
if (errno == LDAP_SERVER_DOWN) if (errno == LDAP_SERVER_DOWN)
{ {
/* server disappeared, try reopen on next search */ /* server disappeared, try reopen on next search */
sm_ldap_close(&LDAPLMAP); sm_ldap_close(&LDAPLMAP);
} }
# endif /* LDAP_SERVER_DOWN */ # endif /* LDAP_SERVER_DOWN */
errno = save_errno; errno = save_errno;
return EX_TEMPFAIL; return EX_TEMPFAIL;
} }
@ -776,5 +767,4 @@ mbdb_ldap_terminate()
{ {
sm_ldap_close(&LDAPLMAP); sm_ldap_close(&LDAPLMAP);
} }
# endif /* _LDAP_EXAMPLE_ */ #endif /* LDAPMAP && _LDAP_EXAMPLE_ */
#endif /* LDAPMAP */

View file

@ -79,7 +79,7 @@ sm_memstat_get(resource, pvalue)
return (errno != 0) ? errno : -1; return (errno != 0) ? errno : -1;
r = ai.ani_max - ai.ani_resv; r = ai.ani_max - ai.ani_resv;
r *= sc_page_size >> 10; r *= sc_page_size >> 10;
*pvalue = r; *pvalue = r;
return 0; return 0;
} }
@ -167,7 +167,7 @@ sm_memstat_get(resource, pvalue)
(resource != NULL) ? resource: "freemem"); (resource != NULL) ? resource: "freemem");
if (kn == NULL) if (kn == NULL)
return (errno != 0) ? errno : -3; return (errno != 0) ? errno : -3;
*pvalue = kn->value.ul; *pvalue = kn->value.ul;
return 0; return 0;
} }

View file

@ -95,11 +95,11 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
} }
(void) sm_strlcat(keybuf, keyval, sizeof keybuf); (void) sm_strlcat(keybuf, keyval, sizeof keybuf);
#if 0 # if 0
if (tTd(38, 21)) if (tTd(38, 21))
sm_dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n", sm_dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
keydir, keyprop, keyval, valprop, sepchar, keybuf); keydir, keyprop, keyval, valprop, sepchar, keybuf);
#endif # endif
/* /*
** If the passed directory and property name are found ** If the passed directory and property name are found
@ -114,10 +114,10 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
if (i == 0) if (i == 0)
{ {
nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni); nis = ni_open(NULL, LOCAL_NETINFO_DOMAIN, &ni);
#if 0 # if 0
if (tTd(38, 20)) if (tTd(38, 20))
sm_dprintf("ni_open(LOCAL) = %d\n", nis); sm_dprintf("ni_open(LOCAL) = %d\n", nis);
#endif # endif
} }
else else
{ {
@ -125,10 +125,10 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
ni_free(lastni); ni_free(lastni);
lastni = ni; lastni = ni;
nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni); nis = ni_open(lastni, PARENT_NETINFO_DOMAIN, &ni);
#if 0 # if 0
if (tTd(38, 20)) if (tTd(38, 20))
sm_dprintf("ni_open(PARENT) = %d\n", nis); sm_dprintf("ni_open(PARENT) = %d\n", nis);
#endif # endif
} }
/* /*
@ -156,11 +156,11 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0) if (ni_lookupprop(ni, &nid, valprop, &ninl) != 0)
continue; continue;
#if 0 # if 0
if (tTd(38, 20)) if (tTd(38, 20))
sm_dprintf("ni_lookupprop: len=%d\n", sm_dprintf("ni_lookupprop: len=%d\n",
ninl.ni_namelist_len); ninl.ni_namelist_len);
#endif # endif
/* /*
** See if we have an acceptable number of values. ** See if we have an acceptable number of values.
@ -203,10 +203,10 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
ni_free(ni); ni_free(ni);
if (lastni != NULL && ni != lastni) if (lastni != NULL && ni != lastni)
ni_free(lastni); ni_free(lastni);
#if 0 # if 0
if (tTd(38, 20)) if (tTd(38, 20))
sm_dprintf("ni_propval returns: '%s'\n", propval); sm_dprintf("ni_propval returns: '%s'\n", propval);
#endif # endif
return propval; return propval;
} }

View file

@ -10,6 +10,14 @@
#include <sm/gen.h> #include <sm/gen.h>
#if _FFR_DMTRIGGER
#include <sm/conf.h> /* FDSET_CAST */
#include <sm/fdset.h>
#include <sm/assert.h>
#include <sm/notify.h>
#include <sm/time.h>
#include <sm/string.h>
#include <sys/types.h> #include <sys/types.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
@ -20,11 +28,6 @@
#include <fcntl.h> #include <fcntl.h>
#include <string.h> /* for memset() */ #include <string.h> /* for memset() */
#include <sm/conf.h> /* FDSET_CAST */
#include <sm/fdset.h>
#include <sm/assert.h>
#include <sm/notify.h>
#if SM_NOTIFY_DEBUG #if SM_NOTIFY_DEBUG
#define SM_DBG(p) fprintf p #define SM_DBG(p) fprintf p
#else #else
@ -126,6 +129,9 @@ sm_notify_stop(owner, flags)
** <0: -errno ** <0: -errno
*/ */
#define MAX_NETSTR 1024
#define NETSTRPRE 5
int int
sm_notify_snd(buf, buflen) sm_notify_snd(buf, buflen)
char *buf; char *buf;
@ -133,13 +139,18 @@ sm_notify_snd(buf, buflen)
{ {
int r; int r;
int save_errno; int save_errno;
size_t len;
char netstr[MAX_NETSTR];
SM_REQUIRE(buf != NULL); SM_REQUIRE(buf != NULL);
SM_REQUIRE(buflen > 0); SM_REQUIRE(buflen > 0);
if (NotifyWRpipe < 0) if (NotifyWRpipe < 0)
return -EINVAL; return -EINVAL;
if (buflen >= MAX_NETSTR - 7)
return -E2BIG; /* XXX "TOO LARGE"? */
r = write(NotifyWRpipe, buf, buflen); len = sm_snprintf(netstr, sizeof(netstr), "%04d:%s,", (int)buflen, buf);
r = write(NotifyWRpipe, netstr, len);
save_errno = errno; save_errno = errno;
SM_DBG((stderr, "write=%d, fd=%d, e=%d\n", r, NotifyWRpipe, save_errno)); SM_DBG((stderr, "write=%d, fd=%d, e=%d\n", r, NotifyWRpipe, save_errno));
return r >= 0 ? 0 : -save_errno; return r >= 0 ? 0 : -save_errno;
@ -151,7 +162,7 @@ sm_notify_snd(buf, buflen)
** Parameters: ** Parameters:
** buf -- where to write data ** buf -- where to write data
** buflen -- len of buffer ** buflen -- len of buffer
** tmo -- timeout ** tmo -- timeout (micro seconds)
** **
** Returns: ** Returns:
** 0: success ** 0: success
@ -162,24 +173,30 @@ int
sm_notify_rcv(buf, buflen, tmo) sm_notify_rcv(buf, buflen, tmo)
char *buf; char *buf;
size_t buflen; size_t buflen;
int tmo; long tmo;
{ {
int r; int r, len;
int save_errno; int save_errno;
fd_set readfds; fd_set readfds;
struct timeval timeout; struct timeval timeout, *tval;
SM_REQUIRE(buf != NULL); SM_REQUIRE(buf != NULL);
SM_REQUIRE(buflen > 0); SM_REQUIRE(buflen > NETSTRPRE + 2);
if (NotifyRDpipe < 0) if (NotifyRDpipe < 0)
return -EINVAL; return -EINVAL;
FD_ZERO(&readfds); FD_ZERO(&readfds);
SM_FD_SET(NotifyRDpipe, &readfds); SM_FD_SET(NotifyRDpipe, &readfds);
timeout.tv_sec = tmo; if (tmo < 0)
timeout.tv_usec = 0; tval = NULL;
else
{
timeout.tv_sec = (long) (tmo / SM_MICROS);
timeout.tv_usec = tmo % SM_MICROS;
tval = &timeout;
}
do { do {
r = select(NotifyRDpipe + 1, FDSET_CAST &readfds, NULL, NULL, &timeout); r = select(NotifyRDpipe + 1, FDSET_CAST &readfds, NULL, NULL, tval);
save_errno = errno; save_errno = errno;
SM_DBG((stderr, "select=%d, fd=%d, e=%d\n", r, NotifyRDpipe, save_errno)); SM_DBG((stderr, "select=%d, fd=%d, e=%d\n", r, NotifyRDpipe, save_errno));
} while (r < 0 && save_errno == EINTR); } while (r < 0 && save_errno == EINTR);
@ -194,12 +211,30 @@ sm_notify_rcv(buf, buflen, tmo)
if (!FD_ISSET(NotifyRDpipe, &readfds)) if (!FD_ISSET(NotifyRDpipe, &readfds))
return -ETIMEDOUT; return -ETIMEDOUT;
r = read(NotifyRDpipe, buf, buflen); 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; save_errno = errno;
SM_DBG((stderr, "read=%d, e=%d\n", r, save_errno)); SM_DBG((stderr, "read=%d, e=%d\n", r, save_errno));
if (r == 0) if (r == 0)
return -1; /* ??? */ return -1; /* ??? */
if (r < 0) if (r < 0)
return -save_errno; return -save_errno;
if (len + 1 != r)
return -1; /* ??? */
if (buf[len] != ',')
return -EINVAL; /* ??? */
buf[len] = '\0';
return r; return r;
} }
#endif /* _FFR_DMTRIGGER */

View file

@ -80,7 +80,7 @@ static int sm_lflush __P((SM_FILE_T *, int *));
do \ do \
{ \ { \
(sel_ret) = select((fd) + 1, &sm_io_to_mask, NULL, \ (sel_ret) = select((fd) + 1, &sm_io_to_mask, NULL, \
&sm_io_x_mask, (to)); \ &sm_io_x_mask, (to)); \
} while ((sel_ret) < 0 && errno == EINTR); \ } while ((sel_ret) < 0 && errno == EINTR); \
if ((sel_ret) < 0) \ if ((sel_ret) < 0) \
{ \ { \

View file

@ -508,17 +508,44 @@ sm_rpool_attach_x(rpool, rfree, rcontext)
*/ */
char * char *
sm_rpool_strdup_x(rpool, s) # if SM_HEAP_CHECK > 2
sm_rpool_strdup_tagged_x
# else
sm_rpool_strdup_x
# endif
(rpool, s
# if SM_HEAP_CHECK > 2
, tag, line, group
# endif
)
SM_RPOOL_T *rpool; SM_RPOOL_T *rpool;
const char *s; const char *s;
# if SM_HEAP_CHECK > 2
char *tag;
int line;
int group;
# else
# define tag "sm_rpool_strdup_x"
# define line 1
# define group 1
# endif
{ {
size_t l; size_t l;
char *n; char *n;
l = strlen(s); l = strlen(s);
SM_ASSERT(l + 1 > l); SM_ASSERT(l + 1 > l);
# if SM_HEAP_CHECK
n = sm_rpool_malloc_tagged_x(rpool, l + 1, tag, line, group);
# else
n = sm_rpool_malloc_x(rpool, l + 1); n = sm_rpool_malloc_x(rpool, l + 1);
# endif
sm_strlcpy(n, s, l + 1); sm_strlcpy(n, s, l + 1);
return n; return n;
} }
# if SM_HEAP_CHECK <= 2
# undef tag
# undef line
# undef group
# endif
#endif /* DO_NOT_USE_STRCPY */ #endif /* DO_NOT_USE_STRCPY */

View file

@ -13,10 +13,11 @@ SM_RCSID("@(#)$Id: sem.c,v 1.15 2013-11-22 20:51:43 ca Exp $")
#if SM_CONF_SEM #if SM_CONF_SEM
# include <stdlib.h> # include <stdlib.h>
# include <unistd.h> # include <unistd.h>
# include <sm/string.h>
# include <sm/sem.h>
# include <sm/heap.h>
# include <errno.h> # include <errno.h>
# include <sm/string.h>
# include <sm/heap.h>
# include <sm/conf.h>
# include <sm/sem.h>
/* /*
** SM_SEM_START -- initialize semaphores ** SM_SEM_START -- initialize semaphores
@ -156,10 +157,10 @@ sm_sem_rel(semid, semnum, timeout)
int r; int r;
struct sembuf semops[1]; struct sembuf semops[1];
#if PARANOID # if PARANOID
/* XXX should we check whether the value is already 0 ? */ /* XXX should we check whether the value is already 0 ? */
SM_REQUIRE(sm_get_sem(semid, semnum) > 0); SM_REQUIRE(sm_get_sem(semid, semnum) > 0);
#endif # endif
semops[0].sem_num = semnum; semops[0].sem_num = semnum;
semops[0].sem_op = 1; semops[0].sem_op = 1;
@ -216,12 +217,17 @@ sm_sem_get(semid, semnum)
** < 0 on failure. ** < 0 on failure.
*/ */
#ifdef __STDC__
int
sm_semsetowner(int semid, uid_t uid, gid_t gid, MODE_T mode)
#else /* __STDC__ */
int int
sm_semsetowner(semid, uid, gid, mode) sm_semsetowner(semid, uid, gid, mode)
int semid; int semid;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
mode_t mode; MODE_T mode;
#endif /* __STDC__ */
{ {
int r; int r;
struct semid_ds semidds; struct semid_ds semidds;

View file

@ -15,6 +15,7 @@ SM_RCSID("@(#)$Id: shm.c,v 1.20 2013-11-22 20:51:43 ca Exp $")
# include <unistd.h> # include <unistd.h>
# include <errno.h> # include <errno.h>
# include <sm/string.h> # include <sm/string.h>
# include <sm/conf.h>
# include <sm/shm.h> # include <sm/shm.h>
@ -119,12 +120,17 @@ sm_shmstop(shm, shmid, owner)
** < 0 on failure. ** < 0 on failure.
*/ */
#ifdef __STDC__
int
sm_shmsetowner(int shmid, uid_t uid, gid_t gid, MODE_T mode)
#else /* __STDC__ */
int int
sm_shmsetowner(shmid, uid, gid, mode) sm_shmsetowner(shmid, uid, gid, mode)
int shmid; int shmid;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
mode_t mode; MODE_T mode;
#endif /* __STDC__ */
{ {
int r; int r;
struct shmid_ds shmid_ds; struct shmid_ds shmid_ds;

View file

@ -40,41 +40,41 @@ sm_signal(sig, handler)
int sig; int sig;
sigfunc_t handler; sigfunc_t handler;
{ {
# if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) #if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3))
struct sigaction n, o; struct sigaction n, o;
# endif #endif
/* /*
** First, try for modern signal calls ** First, try for modern signal calls
** and restartable syscalls ** and restartable syscalls
*/ */
# ifdef SA_RESTART #ifdef SA_RESTART
(void) memset(&n, '\0', sizeof n); (void) memset(&n, '\0', sizeof n);
# if USE_SA_SIGACTION # if USE_SA_SIGACTION
n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler; n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler;
n.sa_flags = SA_RESTART|SA_SIGINFO; n.sa_flags = SA_RESTART|SA_SIGINFO;
# else # else
n.sa_handler = handler; n.sa_handler = handler;
n.sa_flags = SA_RESTART; n.sa_flags = SA_RESTART;
# endif # endif
if (sigaction(sig, &n, &o) < 0) if (sigaction(sig, &n, &o) < 0)
return SIG_ERR; return SIG_ERR;
return o.sa_handler; return o.sa_handler;
# else /* SA_RESTART */ #else /* SA_RESTART */
/* /*
** Else check for SYS5SIGNALS or ** Else check for SYS5SIGNALS or
** BSD4_3 signals ** BSD4_3 signals
*/ */
# if defined(SYS5SIGNALS) || defined(BSD4_3) # if defined(SYS5SIGNALS) || defined(BSD4_3)
# ifdef BSD4_3 # ifdef BSD4_3
return signal(sig, handler); return signal(sig, handler);
# else # else
return sigset(sig, handler); return sigset(sig, handler);
# endif # endif
# else /* defined(SYS5SIGNALS) || defined(BSD4_3) */ # else /* defined(SYS5SIGNALS) || defined(BSD4_3) */
/* /*
** Finally, if nothing else is available, ** Finally, if nothing else is available,
@ -86,8 +86,8 @@ sm_signal(sig, handler)
if (sigaction(sig, &n, &o) < 0) if (sigaction(sig, &n, &o) < 0)
return SIG_ERR; return SIG_ERR;
return o.sa_handler; return o.sa_handler;
# endif /* defined(SYS5SIGNALS) || defined(BSD4_3) */ # endif /* defined(SYS5SIGNALS) || defined(BSD4_3) */
# endif /* SA_RESTART */ #endif /* SA_RESTART */
} }
/* /*
** SM_BLOCKSIGNAL -- hold a signal to prevent delivery ** SM_BLOCKSIGNAL -- hold a signal to prevent delivery
@ -105,13 +105,13 @@ int
sm_blocksignal(sig) sm_blocksignal(sig)
int sig; int sig;
{ {
# ifdef BSD4_3 #ifdef BSD4_3
# ifndef sigmask # ifndef sigmask
# define sigmask(s) (1 << ((s) - 1)) # define sigmask(s) (1 << ((s) - 1))
# endif # endif
return (sigblock(sigmask(sig)) & sigmask(sig)) != 0; return (sigblock(sigmask(sig)) & sigmask(sig)) != 0;
# else /* BSD4_3 */ #else /* BSD4_3 */
# ifdef ALTOS_SYSTEM_V # ifdef ALTOS_SYSTEM_V
sigfunc_t handler; sigfunc_t handler;
handler = sigset(sig, SIG_HOLD); handler = sigset(sig, SIG_HOLD);
@ -119,7 +119,7 @@ sm_blocksignal(sig)
return -1; return -1;
else else
return handler == SIG_HOLD; return handler == SIG_HOLD;
# else /* ALTOS_SYSTEM_V */ # else /* ALTOS_SYSTEM_V */
sigset_t sset, oset; sigset_t sset, oset;
(void) sigemptyset(&sset); (void) sigemptyset(&sset);
@ -128,8 +128,8 @@ sm_blocksignal(sig)
return -1; return -1;
else else
return sigismember(&oset, sig); return sigismember(&oset, sig);
# endif /* ALTOS_SYSTEM_V */ # endif /* ALTOS_SYSTEM_V */
# endif /* BSD4_3 */ #endif /* BSD4_3 */
} }
/* /*
** SM_RELEASESIGNAL -- release a held signal ** SM_RELEASESIGNAL -- release a held signal
@ -147,10 +147,10 @@ int
sm_releasesignal(sig) sm_releasesignal(sig)
int sig; int sig;
{ {
# ifdef BSD4_3 #ifdef BSD4_3
return (sigsetmask(sigblock(0) & ~sigmask(sig)) & sigmask(sig)) != 0; return (sigsetmask(sigblock(0) & ~sigmask(sig)) & sigmask(sig)) != 0;
# else /* BSD4_3 */ #else /* BSD4_3 */
# ifdef ALTOS_SYSTEM_V # ifdef ALTOS_SYSTEM_V
sigfunc_t handler; sigfunc_t handler;
handler = sigset(sig, SIG_HOLD); handler = sigset(sig, SIG_HOLD);
@ -158,7 +158,7 @@ sm_releasesignal(sig)
return -1; return -1;
else else
return handler == SIG_HOLD; return handler == SIG_HOLD;
# else /* ALTOS_SYSTEM_V */ # else /* ALTOS_SYSTEM_V */
sigset_t sset, oset; sigset_t sset, oset;
(void) sigemptyset(&sset); (void) sigemptyset(&sset);
@ -167,8 +167,8 @@ sm_releasesignal(sig)
return -1; return -1;
else else
return sigismember(&oset, sig); return sigismember(&oset, sig);
# endif /* ALTOS_SYSTEM_V */ # endif /* ALTOS_SYSTEM_V */
# endif /* BSD4_3 */ #endif /* BSD4_3 */
} }
/* /*
** PEND_SIGNAL -- Add a signal to the pending signal list ** PEND_SIGNAL -- Add a signal to the pending signal list
@ -263,10 +263,10 @@ void
sm_allsignals(block) sm_allsignals(block)
bool block; bool block;
{ {
# ifdef BSD4_3 #ifdef BSD4_3
# ifndef sigmask # ifndef sigmask
# define sigmask(s) (1 << ((s) - 1)) # define sigmask(s) (1 << ((s) - 1))
# endif # endif
if (block) if (block)
{ {
int mask = 0; int mask = 0;
@ -282,8 +282,8 @@ sm_allsignals(block)
} }
else else
sigsetmask(0); sigsetmask(0);
# else /* BSD4_3 */ #else /* BSD4_3 */
# ifdef ALTOS_SYSTEM_V # ifdef ALTOS_SYSTEM_V
if (block) if (block)
{ {
(void) sigset(SIGALRM, SIG_HOLD); (void) sigset(SIGALRM, SIG_HOLD);
@ -302,7 +302,7 @@ sm_allsignals(block)
(void) sigset(SIGTERM, SIG_DFL); (void) sigset(SIGTERM, SIG_DFL);
(void) sigset(SIGUSR1, SIG_DFL); (void) sigset(SIGUSR1, SIG_DFL);
} }
# else /* ALTOS_SYSTEM_V */ # else /* ALTOS_SYSTEM_V */
sigset_t sset; sigset_t sset;
(void) sigemptyset(&sset); (void) sigemptyset(&sset);
@ -313,8 +313,8 @@ sm_allsignals(block)
(void) sigaddset(&sset, SIGTERM); (void) sigaddset(&sset, SIGTERM);
(void) sigaddset(&sset, SIGUSR1); (void) sigaddset(&sset, SIGUSR1);
(void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL); (void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL);
# endif /* ALTOS_SYSTEM_V */ # endif /* ALTOS_SYSTEM_V */
# endif /* BSD4_3 */ #endif /* BSD4_3 */
} }
/* /*
** SM_SIGNAL_NOOP -- A signal no-op function ** SM_SIGNAL_NOOP -- A signal no-op function

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
#include <sm/sendmail.h>
#if USE_EAI
#include <sm/string.h>
#include <sm/heap.h>
#include <sm/ixlen.h>
/*
** SM_STRCASEEQ -- are two strings equal (case-insenstive)?
**
** Parameters:
** s1 -- string
** s2 -- string
**
** Returns:
** true iff s1 == s2
*/
bool
sm_strcaseeq(s1, s2)
const char *s1;
const char *s2;
{
char *l1, *l2;
char *f1;
bool same;
if (asciistr(s1))
{
if (!asciistr(s2))
return false;
return (sm_strcasecmp(s1, s2) == 0);
}
if (asciistr(s2))
return false;
l1 = sm_lowercase(s1);
if (l1 != s1)
{
f1 = sm_strdup_x(l1);
l1 = f1;
}
else
f1 = NULL;
l2 = sm_lowercase(s2);
while (*l1 == *l2 && '\0' != *l1)
l1++, l2++;
same = *l1 == *l2;
SM_FREE(f1);
return same;
}
/*
** SM_STRNCASEEQ -- are two strings (up to a length) equal (case-insenstive)?
**
** Parameters:
** s1 -- string
** s2 -- string
** n -- maximum length to compare
**
** Returns:
** true iff s1 == s2 (for up to the first n char)
*/
bool
sm_strncaseeq(s1, s2, n)
const char *s1;
const char *s2;
size_t n;
{
char *l1, *l2;
char *f1;
bool same;
if (0 == n)
return true;
if (asciistr(s1))
{
if (!asciistr(s2))
return false;
return (sm_strncasecmp(s1, s2, n) == 0);
}
if (asciistr(s2))
return false;
l1 = sm_lowercase(s1);
if (l1 != s1)
{
f1 = sm_strdup_x(l1);
l1 = f1;
}
else
f1 = NULL;
l2 = sm_lowercase(s2);
while (*l1 == *l2 && '\0' != *l1 && n-- > 0)
l1++, l2++;
same = *l1 == *l2;
SM_FREE(f1);
return same;
}
#endif /* USE_EAI */

View file

@ -27,9 +27,6 @@ SM_RCSID("@(#)$Id: string.c,v 1.4 2013-11-22 20:51:43 ca Exp $")
** **
** Returns: ** Returns:
** none. ** none.
**
** Side Effects:
** none.
*/ */
void void

View file

@ -71,7 +71,7 @@ sm_stringf_x(fmt, va_alist)
char * char *
sm_vstringf_x(fmt, ap) sm_vstringf_x(fmt, ap)
const char *fmt; const char *fmt;
SM_VA_LOCAL_DECL va_list ap;
{ {
char *s; char *s;

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sm/sendmail.h>
#include <sm/ixlen.h>
#include <sm/test.h>
#if _FFR_8BITENVADDR
extern bool SmTestVerbose;
static void
chkilenx(str, len)
const char *str;
int len;
{
int xlen;
xlen = ilenx(str);
SM_TEST(len == xlen);
if (len != xlen)
fprintf(stderr, "str=\"%s\", len=%d, excpected=%d\n",
str, xlen, len);
}
static void
chkxleni(str, len)
const char *str;
int len;
{
int ilen;
ilen = xleni(str);
SM_TEST(len == ilen);
if (len != ilen)
fprintf(stderr, "str=\"%s\", len=%d, excpected=%d\n",
str, ilen, len);
}
static void
usage(prg)
const char *prg;
{
fprintf(stderr, "usage: %s [options]\n", prg);
fprintf(stderr, "options:\n");
fprintf(stderr, "-x xleni\n");
}
int
main(argc, argv)
int argc;
char *argv[];
{
int o, len;
bool x;
char line[1024];
x = false;
while ((o = getopt(argc, argv, "x")) != -1)
{
switch ((char) o)
{
case 'x':
x = true;
break;
default:
usage(argv[0]);
exit(1);
}
}
sm_test_begin(argc, argv, "test ilenx");
while (fscanf(stdin, "%d:%s\n", &len, line) == 2)
{
if (x)
chkxleni(line, len);
else
chkilenx(line, len);
}
return sm_test_end();
}
#else /* _FFR_8BITENVADDR */
int
main(argc, argv)
int argc;
char *argv[];
{
return 0;
}
#endif /* _FFR_8BITENVADDR */

View file

@ -0,0 +1,41 @@
#!/bin/sh
# Copyright (c) 2020 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.
#
# ----------------------------------------
# test ilenx() and xleni(), using t-ixlen
# ----------------------------------------
PRG=./t-ixlen
R=0
${PRG} <<EOF
1:1
3:123
1:ÿ1
1:ÿÿ
1:˜
1:ÿ˜
3:1ÿ˜2
4:ÿÿmqÿ˜
17:ÿÿmqÿ˜@sendmail.com
0:ÿ
1:ÿÿÿ
EOF
# note: the last two entries are not "valid" [i] strings,
# so the results could be considered bogus.
R=$?
${PRG} -x <<EOF
1:1
3:123
3:ÿ1
6:1ÿ˜2
EOF
R1=$?
[ $R -eq 0 ] && R=$R1
exit $R

View file

@ -11,64 +11,88 @@
#include <stdio.h> #include <stdio.h>
#if _FFR_DMTRIGGER || _FFR_NOTIFY
# include <stdlib.h> # include <stdlib.h>
# include <unistd.h> # include <unistd.h>
# include <errno.h>
# include <sm/heap.h> # include <sm/heap.h>
# include <sm/string.h> # include <sm/string.h>
# include <sm/test.h> # include <sm/test.h>
# include <sm/notify.h> # include <sm/notify.h>
# include <sm/conf.h>
# define MAX_CNT 10
/* /*
** MSGTEST -- test of message queue. ** NOTIFY_WR -- test of notify feature
** **
** Parameters: ** Parameters:
** owner -- create message queue. ** pid -- pid of process
** **
** Returns: ** Returns:
** 0 on success ** 0 on success
** < 0 on failure. ** < 0 on failure
*/ */
static int static int
notifytest(owner) notify_wr(pid)
int owner; pid_t pid;
{ {
int r; int r;
size_t len; size_t len;
char buf[64]; char buf[64];
#define TSTSTR "qf0001" #define TSTSTR "qf0001"
r = sm_notify_start(owner, 0); r = sm_notify_start(false, 0);
if (r < 0) if (r < 0)
{ {
perror("sm_notify_start failed"); perror("sm_notify_start failed");
return -1; return -1;
} }
if (!owner) len = sm_snprintf(buf, sizeof(buf), "%s-%ld", TSTSTR, (long) pid);
{ r = sm_notify_snd(buf, len);
len = sm_strlcpy(buf, TSTSTR, sizeof(buf)); SM_TEST(r >= 0);
r = sm_notify_snd(buf, len); return r;
SM_TEST(r >= 0); }
if (r < 0)
goto end;
end: /*
return r; ** NOTIFY_RD -- test of notify feature
} **
else ** Parameters:
**
** Returns:
** 0 on success
** < 0 on failure
*/
static int
notify_rd(nproc)
int nproc;
{
int r, i;
char buf[64];
#define TSTSTR "qf0001"
r = sm_notify_start(true, 0);
if (r < 0)
{ {
r = sm_notify_rcv(buf, sizeof(buf), 5); perror("sm_notify_start failed");
return -1;
}
for (i = 0; i < nproc; i++)
{
r = sm_notify_rcv(buf, sizeof(buf), 5 * SM_MICROS);
SM_TEST(r >= 0); SM_TEST(r >= 0);
if (r < 0) if (r < 0)
{
fprintf(stderr, "rcv=%d\n", r);
return r; return r;
}
if (r > 0 && r < sizeof(buf)) if (r > 0 && r < sizeof(buf))
buf[r] = '\0'; buf[r] = '\0';
buf[sizeof(buf) - 1] = '\0'; buf[sizeof(buf) - 1] = '\0';
SM_TEST(strcmp(buf, TSTSTR) == 0); SM_TEST(strncmp(buf, TSTSTR, sizeof(TSTSTR) - 1) == 0);
SM_TEST(r > sizeof(TSTSTR));
fprintf(stderr, "buf=\"%s\"\n", buf); fprintf(stderr, "buf=\"%s\"\n", buf);
} }
return 0; return 0;
@ -79,44 +103,68 @@ main(argc, argv)
int argc; int argc;
char *argv[]; char *argv[];
{ {
int ch; int i;
int r = 0; int r = 0;
int nproc = 1;
pid_t pid; pid_t pid;
# define OPTIONS "" # define OPTIONS "p:"
while ((ch = getopt(argc, argv, OPTIONS)) != -1) while ((i = getopt(argc, argv, OPTIONS)) != -1)
{ {
switch ((char) ch) switch ((char) i)
{ {
case 'p':
nproc = atoi(optarg);
if (nproc < 1)
{
errno = EINVAL;
perror("-p: must be >0\n");
return r;
}
break;
default: default:
break; break;
} }
} }
sm_test_begin(argc, argv, "test notify");
r = sm_notify_init(0); r = sm_notify_init(0);
SM_TEST(r >= 0);
if (r < 0) if (r < 0)
{ {
perror("sm_notify_init failed\n"); perror("sm_notify_init failed\n");
return -1; return r;
} }
if ((pid = fork()) < 0) pid = 0;
for (i = 0; i < nproc; i++)
{ {
perror("fork failed\n"); if ((pid = fork()) < 0)
return -1; {
} perror("fork failed\n");
return -1;
}
sm_test_begin(argc, argv, "test notify"); if (pid == 0)
if (pid == 0) {
{ /* give the parent the chance to set up data */
/* give the parent the chance to setup data */ sleep(1);
sleep(1); r = notify_wr(getpid());
r = notifytest(false); break;
} }
else
{
r = notifytest(true);
} }
if (pid > 0)
r = notify_rd(nproc);
SM_TEST(r >= 0); SM_TEST(r >= 0);
return sm_test_end(); return sm_test_end();
} }
#else /* _FFR_DMTRIGGER */
int
main(argc, argv)
int argc;
char *argv[];
{
printf("SKIPPED: no _FFR_DMTRIGGER\n");
return 0;
}
#endif /* _FFR_DMTRIGGER */

View file

@ -44,14 +44,15 @@ show_diff(s1, s2)
} }
} }
char *quote_unquote __P((char *, char *, int, int)); char *quote_unquote __P((char *, char *, int, int, int));
char * char *
quote_unquote(in, out, outlen, exp) quote_unquote(in, out, outlen, exp, mode)
char *in; char *in;
char *out; char *out;
int outlen; int outlen;
int exp; int exp;
int mode;
{ {
char *obp, *bp; char *obp, *bp;
char line_back[1024]; char line_back[1024];
@ -59,9 +60,14 @@ quote_unquote(in, out, outlen, exp)
int cmp; int cmp;
sm_strlcpy(line_in, in, sizeof(line_in)); sm_strlcpy(line_in, in, sizeof(line_in));
obp = quote_internal_chars(in, out, &outlen); obp = quote_internal_chars(in, out, &outlen, NULL);
bp = str2prt(line_in); bp = str2prt(line_in);
dequote_internal_chars(obp, line_back, sizeof(line_back)); if (0 == mode)
dequote_internal_chars(obp, line_back, sizeof(line_back));
else if (1 == mode)
dequote_internal_chars(obp, line_back, strlen(obp));
else if (2 == mode)
dequote_internal_chars(obp, line_back, strlen(obp) + 1);
cmp = strcmp(line_in, line_back); cmp = strcmp(line_in, line_back);
SM_TEST(exp == cmp); SM_TEST(exp == cmp);
if (cmp != exp && !SmTestVerbose) if (cmp != exp && !SmTestVerbose)
@ -98,11 +104,13 @@ main(argc, argv)
char *argv[]; char *argv[];
{ {
char line_in[1024], line[256], line_out[32], *obp; char line_in[1024], line[256], line_out[32], *obp;
int i, los, cmp; int i, los, cmp, mode;
sm_qic_T inout[] = { sm_qic_T inout[] = {
{ "", "", 0 } { "", "", 0 }
, { "abcdef", "abcdef", 0 } , { "abcdef", "abcdef", 0 }
, { "01234567890123456789", "01234567890123456789", 0 } , { "01234567890123456789", "01234567890123456789", 0 }
, { "\\", "\\", 0 }
, { "\\A", "\\A", 0 }
, { "01234567890123456789\001", "01234567890123456789\001", , { "01234567890123456789\001", "01234567890123456789\001",
0 } 0 }
, { "012345\2067890123456789", "012345\377\2067890123456789", , { "012345\2067890123456789", "012345\377\2067890123456789",
@ -121,6 +129,9 @@ main(argc, argv)
}; };
sm_test_begin(argc, argv, "test meta quoting"); sm_test_begin(argc, argv, "test meta quoting");
mode = 0;
if (argc > 1)
mode = atoi(argv[1]);
for (i = 0; i < sizeof(line_out); i++) for (i = 0; i < sizeof(line_out); i++)
line_out[i] = '\0'; line_out[i] = '\0';
for (i = 0; i < sizeof(line_in); i++) for (i = 0; i < sizeof(line_in); i++)
@ -135,7 +146,7 @@ main(argc, argv)
line_in[i] = ch; line_in[i] = ch;
} }
los = sizeof(line_out) / 2; los = sizeof(line_out) / 2;
obp = quote_unquote(line_in, line_out, los, 0); obp = quote_unquote(line_in, line_out, los, 0, mode);
if (obp != line_out) if (obp != line_out)
SM_FREE(obp); SM_FREE(obp);
@ -151,7 +162,7 @@ main(argc, argv)
line_in[i] = ch; line_in[i] = ch;
} }
los = sizeof(line_in); los = sizeof(line_in);
obp = quote_unquote(line_in, line_in, los, 0); obp = quote_unquote(line_in, line_in, los, 0, mode);
if (obp != line_in) if (obp != line_in)
SM_FREE(obp); SM_FREE(obp);
@ -159,7 +170,7 @@ main(argc, argv)
{ {
los = sizeof(line_out) / 2; los = sizeof(line_out) / 2;
obp = quote_unquote(inout[i].qic_in, line_out, los, obp = quote_unquote(inout[i].qic_in, line_out, los,
inout[i].qic_exp); inout[i].qic_exp, mode);
cmp = strcmp(inout[i].qic_out, obp); cmp = strcmp(inout[i].qic_out, obp);
SM_TEST(inout[i].qic_exp == cmp); SM_TEST(inout[i].qic_exp == cmp);
if (inout[i].qic_exp != cmp && !SmTestVerbose) if (inout[i].qic_exp != cmp && !SmTestVerbose)
@ -186,7 +197,7 @@ main(argc, argv)
los = sm_strlcpy(line, inout[i].qic_in, sizeof(line)); los = sm_strlcpy(line, inout[i].qic_in, sizeof(line));
SM_TEST(los + 1 < sizeof(line)); SM_TEST(los + 1 < sizeof(line));
++los; ++los;
obp = quote_unquote(line, line, los, inout[i].qic_exp); obp = quote_unquote(line, line, los, inout[i].qic_exp, mode);
cmp = strcmp(inout[i].qic_out, obp); cmp = strcmp(inout[i].qic_out, obp);
SM_TEST(inout[i].qic_exp == cmp); SM_TEST(inout[i].qic_exp == cmp);
if (inout[i].qic_exp != cmp && !SmTestVerbose) if (inout[i].qic_exp != cmp && !SmTestVerbose)
@ -214,7 +225,7 @@ main(argc, argv)
{ {
los = 0; los = 0;
obp = quote_unquote(inout[i].qic_in, NULL, los, obp = quote_unquote(inout[i].qic_in, NULL, los,
inout[i].qic_exp); inout[i].qic_exp, mode);
SM_TEST(obp != NULL); SM_TEST(obp != NULL);
cmp = strcmp(inout[i].qic_out, obp); cmp = strcmp(inout[i].qic_out, obp);
SM_TEST(inout[i].qic_exp == cmp); SM_TEST(inout[i].qic_exp == cmp);

View file

@ -20,6 +20,7 @@ SM_RCSID("@(#)$Id: t-sem.c,v 1.18 2013-11-22 20:51:43 ca Exp $")
# include <sm/string.h> # include <sm/string.h>
# include <sm/signal.h> # include <sm/signal.h>
# include <sm/test.h> # include <sm/test.h>
# include <sm/conf.h>
# include <sm/sem.h> # include <sm/sem.h>
# define T_SM_SEM_KEY (4321L) # define T_SM_SEM_KEY (4321L)
@ -31,14 +32,14 @@ delay(t, s)
{ {
if (t > 0) if (t > 0)
{ {
#if DEBUG # if DEBUG
fprintf(stderr, "sleep(%d) before %s\n", t, s); fprintf(stderr, "sleep(%d) before %s\n", t, s);
#endif # endif
sleep(t); sleep(t);
} }
#if DEBUG # if DEBUG
fprintf(stderr, "%s\n", s); fprintf(stderr, "%s\n", s);
#endif # endif
} }

View file

@ -20,6 +20,7 @@ SM_RCSID("@(#)$Id: t-shm.c,v 1.23 2013-11-22 20:51:43 ca Exp $")
# include <sm/heap.h> # include <sm/heap.h>
# include <sm/string.h> # include <sm/string.h>
# include <sm/test.h> # include <sm/test.h>
# include <sm/conf.h>
# include <sm/shm.h> # include <sm/shm.h>
# define SHMSIZE 1024 # define SHMSIZE 1024

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2006 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 <sm/gen.h>
SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
#include <stdio.h>
#include <sm/sendmail.h>
#include <sm/assert.h>
#include <sm/heap.h>
#include <sm/string.h>
#include <sm/test.h>
extern bool SmTestVerbose;
struct sm_qic_S
{
char *qic_in;
char *qic_out;
int qic_exp;
};
typedef struct sm_qic_S sm_qic_T;
int
main(argc, argv)
int argc;
char *argv[];
{
char *obp;
int i, cmp;
sm_qic_T inout[] = {
{ "", "", 0 }
, { "abcdef", "abcdef", 0 }
, { "01234567890123456789", "01234567890123456789", 0 }
, { "\\", "\\\\", 0 }
, { "\\001", "\\\\001", 0 }
, { "01234567890123456789\\001", "01234567890123456789\\\\001",
0 }
, { NULL, NULL, 0 }
};
sm_test_begin(argc, argv, "test meta quoting");
for (i = 0; inout[i].qic_in != NULL; i++)
{
obp = str2prt(inout[i].qic_in);
cmp = strcmp(inout[i].qic_out, obp);
SM_TEST(inout[i].qic_exp == cmp);
if (inout[i].qic_exp != cmp && SmTestVerbose)
{
fprintf(stderr, "in: %s\n", inout[i].qic_in);
fprintf(stderr, "got: %s\n", obp);
fprintf(stderr, "exp: %s\n", inout[i].qic_out);
fprintf(stderr, "cmp=%d\n", cmp);
}
}
return sm_test_end();
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
SM_IDSTR(id, "@(#)$Id: t-qic.c,v 1.10 2013-11-22 20:51:43 ca Exp $")
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sm/sendmail.h>
#include <sm/ixlen.h>
#include <sm/test.h>
#if _FFR_8BITENVADDR
extern bool SmTestVerbose;
static int
tstrncaseeq(s1, s2, len)
char *s1;
char *s2;
size_t len;
{
return SM_STRNCASEEQ(s1, s2, len);
}
static void
usage(prg)
const char *prg;
{
fprintf(stderr, "usage: %s [options]\n", prg);
fprintf(stderr, "options:\n");
}
int
main(argc, argv)
int argc;
char *argv[];
{
int o, len;
#define MAXL 1024
char s1[MAXL], s2[MAXL];
while ((o = getopt(argc, argv, "h")) != -1)
{
switch ((char) o)
{
default:
usage(argv[0]);
exit(1);
}
}
sm_test_begin(argc, argv, "test strncaseeq");
while (fscanf(stdin, "%d:%s\n", &len, s1) == 2 &&
fscanf(stdin, "%d:%s\n", &o,s2) == 2)
{
SM_TEST(tstrncaseeq(s1, s2, len) == o);
}
return sm_test_end();
}
#else /* _FFR_8BITENVADDR */
int
main(argc, argv)
int argc;
char *argv[];
{
return 0;
}
#endif /* _FFR_8BITENVADDR */

View file

@ -0,0 +1,29 @@
#!/bin/sh
# Copyright (c) 2020 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.
#
# ----------------------------------------
# test SM_STRNCASEEQ
# ----------------------------------------
PRG=./t-streq
R=0
${PRG} <<EOF
0:a
1:X
1:a
1:A
2:a
1:A
1:aB
1:AC
2:aB
0:AC
EOF
R=$?
exit $R

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
#include <sm/sendmail.h>
#include <sm/ixlen.h>
#if USE_EAI
/*
** legal utf-8 byte sequence
** http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf - page 94
**
** Code Points 1st 2s 3s 4s
** U+0000..U+007F 00..7F
** U+0080..U+07FF C2..DF 80..BF
** U+0800..U+0FFF E0 A0..BF 80..BF
** U+1000..U+CFFF E1..EC 80..BF 80..BF
** U+D000..U+D7FF ED 80..9F 80..BF
** U+E000..U+FFFF EE..EF 80..BF 80..BF
** U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
** U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
** U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
*/
/*
** based on
** https://github.com/lemire/fastvalidate-utf-8.git
** which is distributed under an MIT license (besides others).
*/
bool
utf8_valid(b, length)
const char *b;
size_t length;
{
const unsigned char *bytes;
size_t index;
bytes = (const unsigned char *)b;
index = 0;
while (true)
{
unsigned char byte1;
do { /* fast ASCII Path */
if (index >= length)
return true;
byte1 = bytes[index++];
} while (byte1 < 0x80);
if (byte1 < 0xE0)
{
/* Two-byte form. */
if (index == length)
return false;
if (byte1 < 0xC2 || bytes[index++] > 0xBF)
return false;
}
else if (byte1 < 0xF0)
{
/* Three-byte form. */
if (index + 1 >= length)
return false;
unsigned char byte2 = bytes[index++];
if (byte2 > 0xBF
/* Overlong? 5 most significant bits must not all be zero. */
|| (byte1 == 0xE0 && byte2 < 0xA0)
/* Check for illegal surrogate codepoints. */
|| (byte1 == 0xED && 0xA0 <= byte2)
/* Third byte trailing-byte test. */
|| bytes[index++] > 0xBF)
return false;
}
else
{
/* Four-byte form. */
if (index + 2 >= length)
return false;
int byte2 = bytes[index++];
if (byte2 > 0xBF
/* Check that 1 <= plane <= 16. Tricky optimized form of: */
/* if (byte1 > (byte) 0xF4 */
/* || byte1 == (byte) 0xF0 && byte2 < (byte) 0x90 */
/* || byte1 == (byte) 0xF4 && byte2 > (byte) 0x8F) */
|| (((byte1 << 28) + (byte2 - 0x90)) >> 30) != 0
/* Third byte trailing-byte test */
|| bytes[index++] > 0xBF
/* Fourth byte trailing-byte test */
|| bytes[index++] > 0xBF)
return false;
}
}
/* NOTREACHED */
return false;
}
#endif /* USE_EAI */

View file

@ -21,12 +21,13 @@ SM_RCSID("@(#)$Id: util.c,v 1.10 2013-11-22 20:51:44 ca Exp $")
/* /*
** STR2PRT -- convert "unprintable" characters in a string to \oct ** STR2PRT -- convert "unprintable" characters in a string to \oct
** (except for some special chars, see below)
** **
** Parameters: ** Parameters:
** s -- string to convert ** s -- string to convert [A]
** **
** Returns: ** Returns:
** converted string. ** converted string [S][U]
** This is a static local buffer, string must be copied ** This is a static local buffer, string must be copied
** before this function is called again! ** before this function is called again!
*/ */
@ -41,6 +42,12 @@ str2prt(s)
static int len = 0; static int len = 0;
static char *buf = NULL; static char *buf = NULL;
#if _FFR_LOGASIS >= 1
#define BADCHAR(ch) ((unsigned char)(ch) <= 31)
#else
#define BADCHAR(ch) (!(isascii(ch) && isprint(ch)))
#endif
if (s == NULL) if (s == NULL)
return NULL; return NULL;
ok = true; ok = true;
@ -51,7 +58,7 @@ str2prt(s)
++l; ++l;
ok = false; ok = false;
} }
else if (!(isascii(*h) && isprint(*h))) else if (BADCHAR(*h))
{ {
l += 3; l += 3;
ok = false; ok = false;
@ -71,7 +78,7 @@ str2prt(s)
for (h = buf; *s != '\0' && l > 0; s++, l--) for (h = buf; *s != '\0' && l > 0; s++, l--)
{ {
c = *s; c = *s;
if (isascii(c) && isprint(c) && c != '\\') if (c != '\\' && !BADCHAR(c))
{ {
*h++ = c; *h++ = c;
} }
@ -99,9 +106,8 @@ str2prt(s)
(unsigned int)((unsigned char) c)); (unsigned int)((unsigned char) c));
/* /*
** XXX since l is unsigned this may ** XXX since l is unsigned this may wrap
** wrap around if the calculation is screwed ** around if the calculation is screwed up...
** up...
*/ */
l -= 2; l -= 2;
@ -123,8 +129,8 @@ str2prt(s)
** The input and output pointers can be the same. ** The input and output pointers can be the same.
** **
** Parameters: ** Parameters:
** ibp -- a pointer to the string to translate ** ibp -- a pointer to the string to translate [x]
** obp -- a pointer to an output buffer ** obp -- a pointer to an output buffer [i][m:A]
** bsp -- pointer to the length of the output buffer ** bsp -- pointer to the length of the output buffer
** **
** Returns: ** Returns:
@ -137,10 +143,29 @@ str2prt(s)
#define SM_MM_QUOTE(ch) (((ch) & 0377) == METAQUOTE || (((ch) & 0340) == 0200)) #define SM_MM_QUOTE(ch) (((ch) & 0377) == METAQUOTE || (((ch) & 0340) == 0200))
char * char *
quote_internal_chars(ibp, obp, bsp) #if SM_HEAP_CHECK > 2
quote_internal_chars_tagged
#else
quote_internal_chars
#endif
(ibp, obp, bsp, rpool
#if SM_HEAP_CHECK > 2
, tag, line, group
#endif
)
char *ibp; char *ibp;
char *obp; char *obp;
int *bsp; int *bsp;
SM_RPOOL_T *rpool;
#if SM_HEAP_CHECK > 2
char *tag;
int line;
int group;
#else
# define tag "quote_internal_chars"
# define line 1
# define group 1
#endif
{ {
char *ip, *op; char *ip, *op;
int bufused, olen; int bufused, olen;
@ -162,7 +187,7 @@ quote_internal_chars(ibp, obp, bsp)
/* is the output buffer big enough? */ /* is the output buffer big enough? */
if (olen > *bsp) if (olen > *bsp)
{ {
obp = sm_malloc_x(olen); obp = sm_rpool_malloc_tagged_x(rpool, olen, tag, line, group);
buffer_same = false; buffer_same = false;
*bsp = olen; *bsp = olen;
} }
@ -187,7 +212,7 @@ quote_internal_chars(ibp, obp, bsp)
if (buffer_same) if (buffer_same)
{ {
obp = sm_malloc_x(olen); obp = sm_malloc_tagged_x(olen, tag, line + 1, group);
buffer_same = false; buffer_same = false;
*bsp = olen; *bsp = olen;
} }
@ -205,14 +230,19 @@ quote_internal_chars(ibp, obp, bsp)
op[bufused] = '\0'; op[bufused] = '\0';
return obp; return obp;
} }
#if SM_HEAP_CHECK <= 2
# undef tag
# undef line
# undef group
#endif
/* /*
** DEQUOTE_INTERNAL_CHARS -- undo the effect of quote_internal_chars ** DEQUOTE_INTERNAL_CHARS -- undo the effect of quote_internal_chars
** **
** Parameters: ** Parameters:
** ibp -- a pointer to the string to be translated. ** ibp -- a pointer to the string to be translated. [i]
** obp -- a pointer to the output buffer. Can be the ** obp -- a pointer to the output buffer. [x]
** same as ibp. ** Can be the same as ibp.
** obs -- the size of the output buffer. ** obs -- the size of the output buffer.
** **
** Returns: ** Returns:

View file

@ -0,0 +1,204 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
#include <sm/sendmail.h>
/*
** based on
** https://github.com/aox/encodings/utf.cpp
** see license.txt included below.
*/
#if USE_EAI
#include <ctype.h>
#define SM_ISDIGIT(c) (isascii(c) && isdigit(c))
#include <sm/assert.h>
/* for prototype */
#include <sm/ixlen.h>
# if 0
/*
** RFC 6533:
**
** In the ABNF below, all productions not defined in this document are
** defined in Appendix B of [RFC5234], in Section 4 of [RFC3629], or in
** [RFC3464].
**
** utf-8-type-addr = "utf-8;" utf-8-enc-addr
** utf-8-address = Mailbox ; Mailbox as defined in [RFC6531].
** utf-8-enc-addr = utf-8-addr-xtext /
** utf-8-addr-unitext /
** utf-8-address
** utf-8-addr-xtext = 1*(QCHAR / EmbeddedUnicodeChar)
** ; 7bit form of utf-8-addr-unitext.
** ; Safe for use in the ORCPT [RFC3461]
** ; parameter even when SMTPUTF8 SMTP
** ; extension is not advertised.
** utf-8-addr-unitext = 1*(QUCHAR / EmbeddedUnicodeChar)
** ; MUST follow utf-8-address ABNF when
** ; dequoted.
** ; Safe for using in the ORCPT [RFC3461]
** ; parameter when SMTPUTF8 SMTP extension
** ; is also advertised.
** QCHAR = %x21-2a / %x2c-3c / %x3e-5b / %x5d-7e
** ; ASCII printable characters except
** ; CTLs, SP, '\', '+', '='.
** QUCHAR = QCHAR / UTF8-2 / UTF8-3 / UTF8-4
** ; ASCII printable characters except
** ; CTLs, SP, '\', '+' and '=', plus
** ; other Unicode characters encoded in UTF-8
** EmbeddedUnicodeChar = %x5C.78 "{" HEXPOINT "}"
** ; starts with "\x"
** HEXPOINT = ( ( "0"/"1" ) %x31-39 ) / "10" / "20" /
** "2B" / "3D" / "7F" / ; all xtext-specials
** "5C" / (HEXDIG8 HEXDIG) / ; 2-digit forms
** ( NZHEXDIG 2(HEXDIG) ) / ; 3-digit forms
** ( NZDHEXDIG 3(HEXDIG) ) / ; 4-digit forms excluding
** ( "D" %x30-37 2(HEXDIG) ) / ; ... surrogate
** ( NZHEXDIG 4(HEXDIG) ) / ; 5-digit forms
** ( "10" 4*HEXDIG ) ; 6-digit forms
** ; represents either "\" or a Unicode code point outside
** ; the ASCII repertoire
** HEXDIG8 = %x38-39 / "A" / "B" / "C" / "D" / "E" / "F"
** ; HEXDIG excluding 0-7
** NZHEXDIG = %x31-39 / "A" / "B" / "C" / "D" / "E" / "F"
** ; HEXDIG excluding "0"
** NZDHEXDIG = %x31-39 / "A" / "B" / "C" / "E" / "F"
** ; HEXDIG excluding "0" and "D"
*/
# endif /* 0 */
/*
** UXTEXT_UNQUOTE -- "unquote" a utf-8-addr-unitext
**
** Parameters:
** quoted -- original string [x]
** unquoted -- "decoded" string [x] (buffer provided by caller)
** if NULL this is basically a syntax check.
** olen -- length of unquoted (must be > 0)
**
** Returns:
** >0: length of "decoded" string
** <0: error
*/
int
uxtext_unquote(quoted, unquoted, olen)
const char *quoted;
char *unquoted;
int olen;
{
const unsigned char *cp;
int ch, len;
#define APPCH(ch) do \
{ \
if (len >= olen) \
return 0 - olen; \
if (NULL != unquoted) \
unquoted[len] = (char) (ch); \
len++; \
} while (0)
SM_REQUIRE(olen > 0);
SM_REQUIRE(NULL != quoted);
len = 0;
for (cp = (const unsigned char *) quoted; (ch = *cp) != 0; cp++)
{
if (ch == '\\' && cp[1] == 'x' && cp[2] == '{')
{
int uc = 0;
cp += 2;
while ((ch = *++cp) != '}')
{
if (SM_ISDIGIT(ch))
uc = (uc << 4) + (ch - '0');
else if (ch >= 'a' && ch <= 'f')
uc = (uc << 4) + (ch - 'a' + 10);
else if (ch >= 'A' && ch <= 'F')
uc = (uc << 4) + (ch - 'A' + 10);
else
return 0 - len;
if (uc > 0x10ffff)
return 0 - len;
}
if (uc < 0x80)
APPCH(uc);
else if (uc < 0x800)
{
APPCH(0xc0 | ((char) (uc >> 6)));
APPCH(0x80 | ((char) (uc & 0x3f)));
}
else if (uc < 0x10000)
{
APPCH(0xe0 | ((char) (uc >> 12)));
APPCH(0x80 | ((char) (uc >> 6) & 0x3f));
APPCH(0x80 | ((char) (uc & 0x3f)));
}
else if (uc < 0x200000)
{
APPCH(0xf0 | ((char) (uc >> 18)));
APPCH(0x80 | ((char) (uc >> 12) & 0x3f));
APPCH(0x80 | ((char) (uc >> 6) & 0x3f));
APPCH(0x80 | ((char) (uc & 0x3f)));
}
else if (uc < 0x4000000)
{
APPCH(0xf8 | ((char) (uc >> 24)));
APPCH(0x80 | ((char) (uc >> 18) & 0x3f));
APPCH(0x80 | ((char) (uc >> 12) & 0x3f));
APPCH(0x80 | ((char) (uc >> 6) & 0x3f));
APPCH(0x80 | ((char) (uc & 0x3f)));
}
else
{
APPCH(0xfc | ((char) (uc >> 30)));
APPCH(0x80 | ((char) (uc >> 24) & 0x3f));
APPCH(0x80 | ((char) (uc >> 18) & 0x3f));
APPCH(0x80 | ((char) (uc >> 12) & 0x3f));
APPCH(0x80 | ((char) (uc >> 6) & 0x3f));
APPCH(0x80 | ((char) (uc & 0x3f)));
}
}
else
APPCH(ch);
}
APPCH('\0');
return len;
}
# if 0
aox/doc/readme/license.txt
Copyright (c) 2003-2014, Archiveopteryx and its contributors.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written
agreement is hereby granted, provided that the above copyright notice
and this paragraph and the following two paragraphs appear in all
copies.
IN NO EVENT SHALL ORYX BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
ORYX HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ORYX SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
BASIS, AND ORYX HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
# endif /* 0 */
#endif /* USE_EAI */

View file

@ -56,7 +56,7 @@ int
sm_vasprintf(str, fmt, ap) sm_vasprintf(str, fmt, ap)
char **str; char **str;
const char *fmt; const char *fmt;
SM_VA_LOCAL_DECL va_list ap;
{ {
int ret; int ret;
SM_FILE_T fake; SM_FILE_T fake;

View file

@ -98,7 +98,7 @@ static int
sm_bprintf(fp, fmt, ap) sm_bprintf(fp, fmt, ap)
SM_FILE_T *fp; SM_FILE_T *fp;
const char *fmt; const char *fmt;
SM_VA_LOCAL_DECL va_list ap;
{ {
int ret; int ret;
SM_FILE_T fake; SM_FILE_T fake;
@ -174,7 +174,7 @@ sm_io_vfprintf(fp, timeout, fmt0, ap)
SM_FILE_T *fp; SM_FILE_T *fp;
int timeout; int timeout;
const char *fmt0; const char *fmt0;
SM_VA_LOCAL_DECL va_list ap;
{ {
register char *fmt; /* format string */ register char *fmt; /* format string */
register int ch; /* character from fmt */ register int ch; /* character from fmt */
@ -827,7 +827,7 @@ number: if ((dprec = prec) >= 0)
static void static void
sm_find_arguments(fmt0, ap, argtable) sm_find_arguments(fmt0, ap, argtable)
const char *fmt0; const char *fmt0;
SM_VA_LOCAL_DECL va_list ap;
va_list **argtable; va_list **argtable;
{ {
register char *fmt; /* format string */ register char *fmt; /* format string */
@ -1076,6 +1076,7 @@ reswitch: switch (ch)
(void) SM_VA_ARG(ap, void *); (void) SM_VA_ARG(ap, void *);
break; break;
} }
SM_VA_END_COPY((*argtable)[n]);
} }
if ((typetable != NULL) && (typetable != stattypetable)) if ((typetable != NULL) && (typetable != stattypetable))

View file

@ -33,7 +33,7 @@ int
sm_vprintf(timeout, fmt, ap) sm_vprintf(timeout, fmt, ap)
int timeout; int timeout;
char const *fmt; char const *fmt;
SM_VA_LOCAL_DECL va_list ap;
{ {
return sm_io_vfprintf(smiostdout, timeout, fmt, ap); return sm_io_vfprintf(smiostdout, timeout, fmt, ap);
} }

View file

@ -42,7 +42,7 @@ sm_vsnprintf(str, n, fmt, ap)
char *str; char *str;
size_t n; size_t n;
const char *fmt; const char *fmt;
SM_VA_LOCAL_DECL va_list ap;
{ {
int ret; int ret;
char dummy; char dummy;

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2020 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 <sm/gen.h>
#include <sm/sendmail.h>
#include <sm/ixlen.h>
#if _FFR_8BITENVADDR
/*
** XLENI -- determine the 'i'internal length of a string in e'x'ternal format
**
** Parameters:
** str -- string [x]
**
** Returns:
** 'i'internal length of a string in e'x'ternal format
*/
int
xleni(str)
const char *str;
{
char c;
int idx, ilen;
if (NULL == str)
return -1;
for (ilen = 0, idx = 0; (c = str[idx]) != '\0'; ilen++, idx++)
{
if (SM_MM_QUOTE(c))
ilen++;
}
return ilen;
}
#endif /* _FFR_8BITENVADDR */

View file

@ -70,14 +70,14 @@ static int smcdb_cursor __P((SMDB_DATABASE *database, SMDB_CURSOR **cursor, SMDB
** **
*/ */
#if 0 # if 0
static int static int
smdb_type_to_cdb_type(type) smdb_type_to_cdb_type(type)
SMDB_DBTYPE type; SMDB_DBTYPE type;
{ {
return 0; /* XXX */ return 0; /* XXX */
} }
#endif # endif
/* /*
** CDB_ERROR_TO_SMDB -- Translates cdb errors to smdbe errors ** CDB_ERROR_TO_SMDB -- Translates cdb errors to smdbe errors
@ -404,7 +404,7 @@ smcdb_cursor(database, cursor, flags)
} }
/* /*
** SMDB_DB_OPEN -- Opens a db database. ** SMDB_CDB_OPEN -- Opens a cdb database.
** **
** Parameters: ** Parameters:
** database -- An unallocated database pointer to a pointer. ** database -- An unallocated database pointer to a pointer.
@ -415,19 +415,12 @@ smcdb_cursor(database, cursor, flags)
** type -- The type of database to open ** type -- The type of database to open
** See smdb_type_to_cdb_type for valid types. ** See smdb_type_to_cdb_type for valid types.
** user_info -- User information for file permissions. ** user_info -- User information for file permissions.
** db_params -- ** db_params -- unused
** An SMDB_DBPARAMS struct including params. These
** are processed according to the type of the
** database. Currently supported params (only for
** HASH type) are:
** num_elements
** cache_size
** **
** Returns: ** Returns:
** SMDBE_OK -- Success, other errno: ** SMDBE_OK -- Success, other errno:
** SMDBE_MALLOC -- Cannot allocate memory. ** SMDBE_MALLOC -- Cannot allocate memory.
** SMDBE_BAD_OPEN -- db_open didn't return an error, but ** SMDBE_BAD_OPEN -- various (OS) errors.
** somehow the DB pointer is NULL.
** Anything else: translated error from cdb ** Anything else: translated error from cdb
*/ */
@ -492,7 +485,7 @@ smdb_cdb_open(database, db_name, mode, mode_mask, sff, type, user_info, db_param
sm_cdbmap->smcdb_lock_fd = lock_fd; sm_cdbmap->smcdb_lock_fd = lock_fd;
#if 0 # if 0
db = NULL; db = NULL;
db_flags = 0; db_flags = 0;
if (bitset(O_CREAT, mode)) if (bitset(O_CREAT, mode))
@ -502,7 +495,7 @@ smdb_cdb_open(database, db_name, mode, mode_mask, sff, type, user_info, db_param
if (mode == O_RDONLY) if (mode == O_RDONLY)
db_flags |= DB_RDONLY; db_flags |= DB_RDONLY;
SM_DB_FLAG_ADD(db_flags); SM_DB_FLAG_ADD(db_flags);
#endif # endif
result = -1; /* smdb_db_open_internal(db_file_name, db_type, db_flags, db_params, &db); */ result = -1; /* smdb_db_open_internal(db_file_name, db_type, db_flags, db_params, &db); */
db_fd = open(db_file_name, mode, DBMMODE); db_fd = open(db_file_name, mode, DBMMODE);

View file

@ -478,18 +478,18 @@ smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
static void static void
db_err_cb( db_err_cb(
#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3 # if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3
dbenv, dbenv,
#endif # endif
errpfx, msg) errpfx, msg)
#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3 # if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3
const DB_ENV *dbenv; const DB_ENV *dbenv;
const char *errpfx; const char *errpfx;
const char *msg; const char *msg;
#else # else
const char *errpfx; const char *errpfx;
char *msg; char *msg;
#endif # endif
{ {
/* do not print/log any errors... */ /* do not print/log any errors... */
return; return;

View file

@ -12,4 +12,10 @@ define(`bldSOURCES', `debug.c err.c lockfile.c safefile.c snprintf.c cf.c ')
APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL') APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL')
bldPRODUCT_END bldPRODUCT_END
srcdir=${SRCDIR}/libsmutil
define(`confCHECK_LIBS',`libsmutil.a ../libsm/libsm.a')dnl
include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/check.m4')
smcheck(`t-lockfile', `compile')
smcheck(`t-lockfile-0.sh', `run')
bldFINISH bldFINISH

View file

@ -61,8 +61,11 @@ getcfname(opmode, submitmode, cftype, conffile)
(void) sm_strlcpy(cf, cflocation, sizeof cf); (void) sm_strlcpy(cf, cflocation, sizeof cf);
else else
#endif /* NETINFO */ #endif /* NETINFO */
/* "else" in #if code above */
{
(void) sm_strlcpyn(cf, sizeof cf, 2, _DIR_SENDMAILCF, (void) sm_strlcpyn(cf, sizeof cf, 2, _DIR_SENDMAILCF,
"submit.cf"); "submit.cf");
}
if (cftype == SM_GET_SUBMIT_CF || stat(cf, &sbuf) == 0) if (cftype == SM_GET_SUBMIT_CF || stat(cf, &sbuf) == 0)
return cf; return cf;
} }

View file

@ -78,12 +78,12 @@ safefile(fn, uid, gid, user, flags, mode, st)
flags &= ~SFF_SAFEDIRPATH; flags &= ~SFF_SAFEDIRPATH;
/* first check to see if the file exists at all */ /* first check to see if the file exists at all */
# if HASLSTAT #if HASLSTAT
if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st) if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st)
: stat(fn, st)) < 0) : stat(fn, st)) < 0)
# else #else
if (stat(fn, st) < 0) if (stat(fn, st) < 0)
# endif #endif
{ {
file_errno = errno; file_errno = errno;
} }
@ -97,21 +97,21 @@ safefile(fn, uid, gid, user, flags, mode, st)
** soon here! ** soon here!
*/ */
# ifdef SUID_ROOT_FILES_OK #ifdef SUID_ROOT_FILES_OK
if (bitset(S_ISUID, st->st_mode)) if (bitset(S_ISUID, st->st_mode))
# else #else
if (bitset(S_ISUID, st->st_mode) && st->st_uid != 0 && if (bitset(S_ISUID, st->st_mode) && st->st_uid != 0 &&
st->st_uid != TrustedUid) st->st_uid != TrustedUid)
# endif #endif
{ {
uid = st->st_uid; uid = st->st_uid;
user = NULL; user = NULL;
} }
# ifdef SUID_ROOT_FILES_OK #ifdef SUID_ROOT_FILES_OK
if (bitset(S_ISGID, st->st_mode)) if (bitset(S_ISGID, st->st_mode))
# else #else
if (bitset(S_ISGID, st->st_mode) && st->st_gid != 0) if (bitset(S_ISGID, st->st_mode) && st->st_gid != 0)
# endif #endif
gid = st->st_gid; gid = st->st_gid;
} }
@ -142,7 +142,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
} }
else else
{ {
# if HASLSTAT #if HASLSTAT
/* Need lstat() information if called stat() before */ /* Need lstat() information if called stat() before */
if (!bitset(SFF_NOSLINK, flags) && lstat(fn, st) < 0) if (!bitset(SFF_NOSLINK, flags) && lstat(fn, st) < 0)
{ {
@ -151,7 +151,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
sm_dprintf("\t%s\n", sm_errstring(ret)); sm_dprintf("\t%s\n", sm_errstring(ret));
return ret; return ret;
} }
# endif /* HASLSTAT */ #endif /* HASLSTAT */
/* directory is writable: disallow links */ /* directory is writable: disallow links */
flags |= SFF_NOLINK; flags |= SFF_NOLINK;
} }
@ -218,7 +218,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
if (stbuf.st_gid == gid) if (stbuf.st_gid == gid)
/* EMPTY */ /* EMPTY */
; ;
# ifndef NO_GROUP_SET #ifndef NO_GROUP_SET
else if (user != NULL && !DontInitGroups && else if (user != NULL && !DontInitGroups &&
((gr != NULL && ((gr != NULL &&
gr->gr_gid == stbuf.st_gid) || gr->gr_gid == stbuf.st_gid) ||
@ -232,7 +232,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
if (*gp == NULL) if (*gp == NULL)
md >>= 3; md >>= 3;
} }
# endif /* ! NO_GROUP_SET */ #endif /* ! NO_GROUP_SET */
else else
md >>= 3; md >>= 3;
} }
@ -252,7 +252,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
return ret; return ret;
} }
# ifdef S_ISLNK #ifdef S_ISLNK
if (bitset(SFF_NOSLINK, flags) && S_ISLNK(st->st_mode)) if (bitset(SFF_NOSLINK, flags) && S_ISLNK(st->st_mode))
{ {
if (tTd(44, 4)) if (tTd(44, 4))
@ -260,7 +260,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
(unsigned long) st->st_mode); (unsigned long) st->st_mode);
return E_SM_NOSLINK; return E_SM_NOSLINK;
} }
# endif /* S_ISLNK */ #endif /* S_ISLNK */
if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode)) if (bitset(SFF_REGONLY, flags) && !S_ISREG(st->st_mode))
{ {
if (tTd(44, 4)) if (tTd(44, 4))
@ -332,7 +332,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
if (st->st_gid == gid) if (st->st_gid == gid)
/* EMPTY */ /* EMPTY */
; ;
# ifndef NO_GROUP_SET #ifndef NO_GROUP_SET
else if (user != NULL && !DontInitGroups && else if (user != NULL && !DontInitGroups &&
((gr != NULL && gr->gr_gid == st->st_gid) || ((gr != NULL && gr->gr_gid == st->st_gid) ||
(gr = getgrgid(st->st_gid)) != NULL)) (gr = getgrgid(st->st_gid)) != NULL))
@ -345,7 +345,7 @@ safefile(fn, uid, gid, user, flags, mode, st)
if (*gp == NULL) if (*gp == NULL)
mode >>= 3; mode >>= 3;
} }
# endif /* ! NO_GROUP_SET */ #endif /* ! NO_GROUP_SET */
else else
mode >>= 3; mode >>= 3;
} }
@ -470,18 +470,18 @@ safedirpath(fn, uid, gid, user, flags, level, offset)
if (tTd(44, 20)) if (tTd(44, 20))
sm_dprintf("\t[dir %s]\n", s); sm_dprintf("\t[dir %s]\n", s);
# if HASLSTAT #if HASLSTAT
ret = lstat(s, &stbuf); ret = lstat(s, &stbuf);
# else #else
ret = stat(s, &stbuf); ret = stat(s, &stbuf);
# endif #endif
if (ret < 0) if (ret < 0)
{ {
ret = errno; ret = errno;
break; break;
} }
# ifdef S_ISLNK #ifdef S_ISLNK
/* Follow symlinks */ /* Follow symlinks */
if (S_ISLNK(stbuf.st_mode)) if (S_ISLNK(stbuf.st_mode))
{ {
@ -637,7 +637,7 @@ safedirpath(fn, uid, gid, user, flags, level, offset)
if (stbuf.st_gid == gid && if (stbuf.st_gid == gid &&
bitset(S_IXGRP, stbuf.st_mode)) bitset(S_IXGRP, stbuf.st_mode))
continue; continue;
# ifndef NO_GROUP_SET #ifndef NO_GROUP_SET
if (user != NULL && !DontInitGroups && if (user != NULL && !DontInitGroups &&
((gr != NULL && gr->gr_gid == stbuf.st_gid) || ((gr != NULL && gr->gr_gid == stbuf.st_gid) ||
(gr = getgrgid(stbuf.st_gid)) != NULL)) (gr = getgrgid(stbuf.st_gid)) != NULL))
@ -651,7 +651,7 @@ safedirpath(fn, uid, gid, user, flags, level, offset)
bitset(S_IXGRP, stbuf.st_mode)) bitset(S_IXGRP, stbuf.st_mode))
continue; continue;
} }
# endif /* ! NO_GROUP_SET */ #endif /* ! NO_GROUP_SET */
if (!bitset(S_IXOTH, stbuf.st_mode)) if (!bitset(S_IXOTH, stbuf.st_mode))
{ {
ret = EACCES; ret = EACCES;
@ -869,13 +869,13 @@ filechanged(fn, fd, stb)
if (stb->st_mode == ST_MODE_NOFILE) if (stb->st_mode == ST_MODE_NOFILE)
{ {
# if HASLSTAT && BOGUS_O_EXCL #if HASLSTAT && BOGUS_O_EXCL
/* only necessary if exclusive open follows symbolic links */ /* only necessary if exclusive open follows symbolic links */
if (lstat(fn, stb) < 0 || stb->st_nlink != 1) if (lstat(fn, stb) < 0 || stb->st_nlink != 1)
return true; return true;
# else #else
return false; return false;
# endif #endif
} }
if (fstat(fd, &sta) < 0) if (fstat(fd, &sta) < 0)
return true; return true;
@ -883,9 +883,9 @@ filechanged(fn, fd, stb)
if (sta.st_nlink != stb->st_nlink || if (sta.st_nlink != stb->st_nlink ||
sta.st_dev != stb->st_dev || sta.st_dev != stb->st_dev ||
sta.st_ino != stb->st_ino || sta.st_ino != stb->st_ino ||
# if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */ #if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
sta.st_gen != stb->st_gen || sta.st_gen != stb->st_gen ||
# endif #endif
sta.st_uid != stb->st_uid || sta.st_uid != stb->st_uid ||
sta.st_gid != stb->st_gid) sta.st_gid != stb->st_gid)
{ {
@ -899,10 +899,10 @@ filechanged(fn, fd, stb)
sm_dprintf(" ino = %llu/%llu\n", sm_dprintf(" ino = %llu/%llu\n",
(ULONGLONG_T) stb->st_ino, (ULONGLONG_T) stb->st_ino,
(ULONGLONG_T) sta.st_ino); (ULONGLONG_T) sta.st_ino);
# if HAS_ST_GEN #if HAS_ST_GEN
sm_dprintf(" gen = %ld/%ld\n", sm_dprintf(" gen = %ld/%ld\n",
(long) stb->st_gen, (long) sta.st_gen); (long) stb->st_gen, (long) sta.st_gen);
# endif #endif
sm_dprintf(" uid = %ld/%ld\n", sm_dprintf(" uid = %ld/%ld\n",
(long) stb->st_uid, (long) sta.st_uid); (long) stb->st_uid, (long) sta.st_uid);
sm_dprintf(" gid = %ld/%ld\n", sm_dprintf(" gid = %ld/%ld\n",

View file

@ -0,0 +1,70 @@
#!/bin/sh
# 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.
#
# ----------------------------------------
# test t-lockfile, analyze result
# ----------------------------------------
fail()
{
echo "$0: $@"
exit 1
}
PRG=./t-lockfile
O=l.log
analyze()
{
# the "owner" unlock operation must be before
# the "client" lock operation can succeed
U=`grep -n 'owner=1, unlock.*done' $O | cut -d: -f1 | head -n1`
[ x"$U" = "x" ] && U=`grep -n '_close' $O | cut -d: -f1 | head -n1`
L=`grep -n 'owner=0, lock.* ok' $O | cut -d: -f1`
[ x"$U" = "x" ] && return 1
[ x"$L" = "x" ] && return 1
[ $U -lt $L ]
}
all=true
while getopts 2a: FLAG
do
case "${FLAG}" in
2) all=false;;
a) O=${OPTARG}
analyze || fail "$opts: unlock1=$U, lock2=$L"
exit;;
esac
done
shift `expr ${OPTIND} - 1`
[ -x ${PRG} ] || fail "missing ${PRG}"
if $all
then
for opts in "" "-r" "-n" "-nr"
do
${PRG} $opts > $O 2>&1 || fail "$opts: $?"
analyze || fail "$opts: unlock1=$U, lock2=$L"
done
fi
# try with two processes
for opts in "" "-r"
do
rm -f $O
${PRG} -W >> $O 2>&1 || fail "-W: $?"
wpid=$!
${PRG} -R $opts >> $O 2>&1 || fail "-R $opts: $?"
rpid=$!
analyze || fail "$opts: unlock1=$U, lock2=$L"
wait $wpid
wait $rpid
done
exit 0

View file

@ -0,0 +1,351 @@
/*
* Copyright (c) 2005 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 <sm/gen.h>
SM_IDSTR(id, "@(#)$Id: t-lockfile.c,v 1.2 2013-11-22 20:51:50 ca Exp $")
#include <stdlib.h>
#include <stdio.h>
#include <sendmail.h>
#define IOBUFSZ 64
char iobuf[IOBUFSZ];
#define FIRSTLINE "first line\n"
#define LASTLINE "last line\n"
static int noio, chk;
static pid_t pid;
int
openfile(owner, filename, flags)
int owner;
char *filename;
int flags;
{
int fd;
if (owner)
flags |= O_CREAT;
fd = open(filename, flags, 0640);
if (fd >= 0)
return fd;
fprintf(stderr, "%d: %ld: owner=%d, open(%s) failed\n",
(int) pid, (long) time(NULL), owner, filename);
return 1;
}
int
wrbuf(fd)
int fd;
{
int r;
if (noio)
return 0;
r = write(fd, iobuf, sizeof(iobuf));
if (sizeof(iobuf) == r)
return 0;
fprintf(stderr, "%d: %ld: owner=1, write(%s)=fail\n",
(int) pid, (long) time(NULL), iobuf);
return 1;
}
int
rdbuf(fd, xbuf)
int fd;
const char *xbuf;
{
int r;
if (noio)
return 0;
r = read(fd, iobuf, sizeof(iobuf));
if (sizeof(iobuf) != r)
{
fprintf(stderr, "%d: %ld: owner=0, read()=fail\n",
(int) pid, (long) time(NULL));
return 1;
}
if (strncmp(iobuf, xbuf, strlen(xbuf)))
{
fprintf(stderr, "%d: %ld: owner=0, read=%s expected=%s\n",
(int) pid, (long) time(NULL), iobuf, xbuf);
return 1;
}
return 0;
}
/*
** LOCKTEST -- test of file locking
**
** Parameters:
** owner -- create file?
** filename -- name of file.
** flags -- flags for open(2)
** delay -- how long to keep file locked?
**
** Returns:
** 0 on success
** != 0 on failure.
*/
#define DBGPRINTR(str) \
do \
{ \
fprintf(stderr, "%d: %ld: owner=0, ", (int) pid, \
(long) time(NULL)); \
fprintf(stderr, str, filename, shared ? "RD" : "EX"); \
} while (0)
int
locktestwr(filename, flags, delay)
char *filename;
int flags;
int delay;
{
int fd;
bool locked;
fd = openfile(1, filename, flags);
if (fd < 0)
return errno;
locked = lockfile(fd, filename, "[owner]", LOCK_EX);
if (!locked)
{
fprintf(stderr, "%d: %ld: owner=1, lock(%s) failed\n",
(int) pid, (long) time(NULL), filename);
return 1;
}
else
fprintf(stderr, "%d: %ld: owner=1, lock(%s) ok\n",
(int) pid, (long) time(NULL), filename);
sm_strlcpy(iobuf, FIRSTLINE, sizeof(iobuf));
if (wrbuf(fd))
return 1;
sleep(delay);
sm_strlcpy(iobuf, LASTLINE, sizeof(iobuf));
if (wrbuf(fd))
return 1;
locked = lockfile(fd, filename, "[owner]", LOCK_UN);
if (!locked)
{
fprintf(stderr, "%d: %ld: owner=1, unlock(%s) failed\n",
(int) pid, (long) time(NULL), filename);
return 1;
}
fprintf(stderr, "%d: %ld: owner=1, unlock(%s) done\n",
(int) pid, (long) time(NULL), filename);
if (fd > 0)
{
close(fd);
fd = -1;
}
return 0;
}
long
chklck(fd)
int fd;
{
#if !HASFLOCK
int action, i;
struct flock lfd;
(void) memset(&lfd, '\0', sizeof lfd);
lfd.l_type = F_RDLCK;
action = F_GETLK;
while ((i = fcntl(fd, action, &lfd)) < 0 && errno == EINTR)
continue;
if (i < 0)
return (long)i;
if (F_WRLCK == lfd.l_type)
return (long)lfd.l_pid;
return 0L;
#else /* !HASFLOCK */
fprintf(stderr, "%d: %ld: flock: no lock test\n",
(int) pid, (long) time(NULL));
return -1L;
#endif /* !HASFLOCK */
}
int
locktestrd(filename, flags, delay, shared)
char *filename;
int flags;
int delay;
int shared;
{
int fd, cnt;
int lt;
bool locked;
fd = openfile(0, filename, flags);
if (fd < 0)
return errno;
if (chk)
{
long locked;
locked = chklck(fd);
if (locked > 0)
fprintf(stderr, "%d: %ld: file=%s status=locked pid=%ld\n",
(int) pid, (long) time(NULL), filename, locked);
else if (0 == locked)
fprintf(stderr, "%d: %ld: file=%s status=not_locked\n",
(int) pid, (long) time(NULL), filename);
else
fprintf(stderr, "%d: %ld: file=%s status=unknown\n",
(int) pid, (long) time(NULL), filename);
goto end;
}
if (shared)
lt = LOCK_SH;
else
lt = LOCK_EX;
for (cnt = 0; cnt < delay - 2; cnt++)
{
/* try to get lock: should fail (nonblocking) */
locked = lockfile(fd, filename, "[client]", lt|LOCK_NB);
if (locked)
{
DBGPRINTR("lock(%s)=%s succeeded\n");
return 1;
}
sleep(1);
}
if (delay > 0)
sleep(2);
locked = lockfile(fd, filename, "[client]", lt);
if (!locked)
{
DBGPRINTR("lock(%s)=%s failed\n");
return 1;
}
DBGPRINTR("lock(%s)=%s ok\n");
if (rdbuf(fd, FIRSTLINE))
return 1;
if (rdbuf(fd, LASTLINE))
return 1;
sleep(1);
locked = lockfile(fd, filename, "[client]", LOCK_UN);
if (!locked)
{
DBGPRINTR("unlock(%s)=%s failed\n");
return 1;
}
DBGPRINTR("unlock(%s)=%s done\n");
end:
if (fd > 0)
{
close(fd);
fd = -1;
}
return 0;
}
static void
usage(prg)
const char *prg;
{
fprintf(stderr, "usage: %s [options]\n"
"-f filename use filename\n"
"-i do not perform I/O\n"
"-n do not try non-blocking locking first\n"
"-R only start reader process\n"
"-r use shared locking for reader\n"
"-s delay sleep delay seconds before unlocking\n"
"-W only start writer process\n"
, prg);
}
int
main(argc, argv)
int argc;
char *argv[];
{
int ch, delay, r, status, flags, shared, nb, reader, writer;
char *filename;
pid_t fpid;
extern char *optarg;
delay = 5;
filename = "testlock";
flags = O_RDWR;
shared = nb = noio = reader = writer = chk = 0;
#define OPTIONS "cf:inRrs:W"
while ((ch = getopt(argc, argv, OPTIONS)) != -1)
{
switch ((char) ch)
{
case 'c':
chk = 1;
break;
case 'f':
filename = optarg;
break;
case 'i':
noio = 1;
break;
case 'n':
nb = 0;
break;
case 'R':
reader = 1;
break;
case 'r':
shared = 1;
break;
case 's':
delay = atoi(optarg);
break;
case 'W':
writer = 1;
break;
default:
usage(argv[0]);
exit(69);
break;
}
}
fpid = -1;
if (0 == reader && 0 == writer && (fpid = fork()) < 0)
{
perror("fork failed\n");
return 1;
}
r = 0;
if (reader || fpid == 0)
{
/* give the parent the chance to setup data */
pid = getpid();
sleep(1);
r = locktestrd(filename, flags, nb ? delay : 0, shared);
}
if (writer || fpid > 0)
{
fpid = getpid();
r = locktestwr(filename, flags, delay);
(void) wait(&status);
}
/* (void) unlink(filename); */
return r;
}

View file

@ -0,0 +1,111 @@
#!/bin/sh
# 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.
#
# ----------------------------------------
# test map locking.
# Note: this is mostly for systems which use fcntl().
# just invoke it from the obj.*/libsmutil/ directory;
# otherwise use the -l and -m options to specify the paths.
# ----------------------------------------
fail()
{
echo "$0: $@"
exit 1
}
err()
{
echo "$0: $@"
rc=1
}
O=`basename $0`.0
V=vt
M=../makemap/makemap
CHKL=./t-lockfile
usage()
{
cat <<EOF
$0: test basic makemap locking;
requires `basename ${CHKL}` and `basename ${M}`.
usage:
$0 [options]
options:
-l locktest path to `basename ${CHKL}` [default: ${CHKL}]
-m makemap path to `basename ${M}` [default: $M]
EOF
}
tries=0
rc=0
while getopts l:m:t: FLAG
do
case "${FLAG}" in
l) CHKL="${OPTARG}";;
m) M="${OPTARG}";;
t) tries="${OPTARG}";;
*) usage
exit 69
;;
esac
done
shift `expr ${OPTIND} - 1`
[ -x $M ] || fail "missing $M"
[ -x ${CHKL} ] || fail "missing ${CHKL}"
MAPTX=`$M -x | egrep 'hash|cdb'`
mm()
{
(echo "l1 l2"; sleep 5; echo "e1 e2") |
$M -v $MT $F >> $O 2>&1
}
chkl()
{
${CHKL} -Rrc -f $F >> $O 2>&1
}
for XT in ${MAPTX}
do
MT=`echo $XT | cut -d: -f1`
EXT=`echo $XT | cut -d: -f2`
F=$V.${EXT}
rm -f $O
mm &
wpid=$!
sleep 1
chkl&
rpid=$!
while [ $tries -gt 0 ]
do
sleep 1; chkl
tries=`expr $tries - 1 `
done
wait $wpid
wait $rpid
if grep "status=unknown" $O >/dev/null
then
:
else
# get the makemap pid, not the "mm" pid, for checks?
grep "status=locked pid=" $O || err "$MT map not locked"
fi
done
exit $rc

View file

@ -23,14 +23,12 @@ SM_IDSTR(copyright,
SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $") SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $")
#include <stdlib.h> #include <stdlib.h>
#include <sm/sendmail.h>
#include <sm/errstring.h> #include <sm/errstring.h>
#include <sm/io.h> #include <sm/io.h>
#include <sm/limits.h> #include <sm/limits.h>
# include <unistd.h> #include <unistd.h>
# ifdef EX_OK #define LOCKFILE_PMODE 0
# undef EX_OK /* unistd.h may have another use for this */
# endif
# define LOCKFILE_PMODE 0
#include <sm/mbdb.h> #include <sm/mbdb.h>
#include <sm/sysexits.h> #include <sm/sysexits.h>
@ -150,6 +148,9 @@ off_t BodyLength;
#endif #endif
bool EightBitMime = true; /* advertise 8BITMIME in LMTP */ bool EightBitMime = true; /* advertise 8BITMIME in LMTP */
#if USE_EAI
bool EAI = true; /* advertise SMTPUTF8 in LMTP */
#endif
char ErrBuf[10240]; /* error buffer */ char ErrBuf[10240]; /* error buffer */
int ExitVal = EX_OK; /* sysexits.h error value. */ int ExitVal = EX_OK; /* sysexits.h error value. */
bool nobiff = false; bool nobiff = false;
@ -222,11 +223,11 @@ main(argc, argv)
/* use a reasonable umask */ /* use a reasonable umask */
(void) umask(0077); (void) umask(0077);
# ifdef LOG_MAIL #ifdef LOG_MAIL
openlog("mail.local", 0, LOG_MAIL); openlog("mail.local", 0, LOG_MAIL);
# else #else
openlog("mail.local", 0); openlog("mail.local", 0);
# endif #endif
from = NULL; from = NULL;
@ -237,14 +238,16 @@ main(argc, argv)
mailerr("421", "Configuration error: _PATH_MAILDIR too large"); mailerr("421", "Configuration error: _PATH_MAILDIR too large");
sm_exit(EX_CONFIG); sm_exit(EX_CONFIG);
} }
/* HACK: add U to all options - this should be only for USE_EAI */
#if HASHSPOOL #if HASHSPOOL
while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lH:p:ns")) != -1) while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lH:p:nsUV")) != -1)
#else /* HASHSPOOL */ #else /* HASHSPOOL */
# if _FFR_SPOOL_PATH # if _FFR_SPOOL_PATH
while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lp:s")) != -1) while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lp:sUV")) != -1)
# else # else
while ((ch = getopt(argc, argv, "7BbdD:f:h:r:ls")) != -1) while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lsUV")) != -1)
# endif # endif
#endif /* HASHSPOOL */ #endif /* HASHSPOOL */
{ {
switch(ch) switch(ch)
@ -353,6 +356,22 @@ main(argc, argv)
break; break;
#endif /* HASHSPOOL || _FFR_SPOOL_PATH */ #endif /* HASHSPOOL || _FFR_SPOOL_PATH */
#if USE_EAI
case 'U':
EAI = false;
break;
#endif
case 'V':
fprintf(stderr, "compiled with\n");
#if MAIL_LOCAL_TEST
fprintf(stderr, "MAIL_LOCAL_TEST\n");
#endif
#if USE_EAI
/* test scripts should look for SMTPUTF8 */
fprintf(stderr, "USE_EAI\n");
#endif
break;
case '?': case '?':
default: default:
usage(); usage();
@ -585,7 +604,7 @@ dolmtp()
{ {
case 'd': case 'd':
case 'D': case 'D':
if (sm_strcasecmp(buf, "data") == 0) if (SM_STRCASEEQ(buf, "data"))
{ {
bool inbody = false; bool inbody = false;
@ -639,6 +658,10 @@ dolmtp()
printf("250-%s\r\n", myhostname); printf("250-%s\r\n", myhostname);
if (EightBitMime) if (EightBitMime)
printf("250-8BITMIME\r\n"); printf("250-8BITMIME\r\n");
#if USE_EAI
if (EAI)
printf("250-SMTPUTF8\r\n");
#endif
printf("250-ENHANCEDSTATUSCODES\r\n"); printf("250-ENHANCEDSTATUSCODES\r\n");
printf("250 PIPELINING\r\n"); printf("250 PIPELINING\r\n");
continue; continue;
@ -674,7 +697,7 @@ dolmtp()
case 'n': case 'n':
case 'N': case 'N':
if (sm_strcasecmp(buf, "noop") == 0) if (SM_STRCASEEQ(buf, "noop"))
{ {
printf("250 2.0.0 Ok\r\n"); printf("250 2.0.0 Ok\r\n");
continue; continue;
@ -685,7 +708,7 @@ dolmtp()
case 'q': case 'q':
case 'Q': case 'Q':
if (sm_strcasecmp(buf, "quit") == 0) if (SM_STRCASEEQ(buf, "quit"))
{ {
printf("221 2.0.0 Bye\r\n"); printf("221 2.0.0 Bye\r\n");
sm_exit(EX_OK); sm_exit(EX_OK);
@ -736,7 +759,7 @@ dolmtp()
printf("250 2.1.5 Ok\r\n"); printf("250 2.1.5 Ok\r\n");
continue; continue;
} }
else if (sm_strcasecmp(buf, "rset") == 0) else if (SM_STRCASEEQ(buf, "rset"))
{ {
printf("250 2.0.0 Ok\r\n"); printf("250 2.0.0 Ok\r\n");
@ -971,7 +994,7 @@ store(from, inbody)
if (fp == NULL || fflush(fp) == EOF || ferror(fp) != 0) if (fp == NULL || fflush(fp) == EOF || ferror(fp) != 0)
{ {
mailerr("451 4.3.0", "Temporary file write error"); mailerr("451 4.3.0", "Temporary file flush error");
if (fp != NULL) if (fp != NULL)
(void) fclose(fp); (void) fclose(fp);
return -1; return -1;
@ -1058,7 +1081,7 @@ deliver(fd, name)
if (HomeMailFile == NULL) if (HomeMailFile == NULL)
{ {
if (sm_strlcpyn(path, sizeof(path), if (sm_strlcpyn(path, sizeof(path),
#if HASHSPOOL #if HASHSPOOL
4, 4,
#else #else
@ -1162,7 +1185,7 @@ deliver(fd, name)
goto tryagain; goto tryagain;
/* open failed, don't try again */ /* open failed, don't try again */
mailerr("450 4.2.0", "%s: %s", path, mailerr("450 4.2.0", "Create %s: %s", path,
sm_errstring(save_errno)); sm_errstring(save_errno));
goto err0; goto err0;
} }
@ -1205,7 +1228,11 @@ deliver(fd, name)
} }
/* change UID for quota checks */ /* change UID for quota checks */
if (setreuid(0, user.mbdb_uid) < 0) if (
#if MAIL_LOCAL_TEST
(HomeMailFile == NULL || user.mbdb_uid != getuid()) &&
#endif
setreuid(0, user.mbdb_uid) < 0)
{ {
mailerr("450 4.2.0", "setreuid(0, %d): %s (r=%d, e=%d)", mailerr("450 4.2.0", "setreuid(0, %d): %s (r=%d, e=%d)",
(int) user.mbdb_uid, sm_errstring(errno), (int) user.mbdb_uid, sm_errstring(errno),
@ -1218,7 +1245,7 @@ deliver(fd, name)
mbfd = open(path, O_APPEND|O_WRONLY, 0); mbfd = open(path, O_APPEND|O_WRONLY, 0);
if (mbfd < 0) if (mbfd < 0)
{ {
mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); mailerr("450 4.2.0", "Append %s: %s", path, sm_errstring(errno));
goto err0; goto err0;
} }
else if (fstat(mbfd, &fsb) < 0 || else if (fstat(mbfd, &fsb) < 0 ||
@ -1227,9 +1254,9 @@ deliver(fd, name)
!S_ISREG(fsb.st_mode) || !S_ISREG(fsb.st_mode) ||
sb.st_dev != fsb.st_dev || sb.st_dev != fsb.st_dev ||
sb.st_ino != fsb.st_ino || sb.st_ino != fsb.st_ino ||
# if HAS_ST_GEN && 0 /* AFS returns random values for st_gen */ #if HAS_ST_GEN && 0 /* AFS returns random values for st_gen */
sb.st_gen != fsb.st_gen || sb.st_gen != fsb.st_gen ||
# endif #endif
sb.st_uid != fsb.st_uid) sb.st_uid != fsb.st_uid)
{ {
ExitVal = EX_TEMPFAIL; ExitVal = EX_TEMPFAIL;
@ -1279,7 +1306,7 @@ deliver(fd, name)
/* Wait until we can get a lock on the file. */ /* Wait until we can get a lock on the file. */
if (flock(mbfd, LOCK_EX) < 0) if (flock(mbfd, LOCK_EX) < 0)
{ {
mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); mailerr("450 4.2.0", "Lock %s: %s", path, sm_errstring(errno));
goto err1; goto err1;
} }
@ -1295,7 +1322,7 @@ deliver(fd, name)
/* Copy the message into the file. */ /* Copy the message into the file. */
if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1) if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1)
{ {
mailerr("450 4.2.0", "Temporary file: %s", mailerr("450 4.2.0", "Temporary file seek error: %s",
sm_errstring(errno)); sm_errstring(errno));
goto err1; goto err1;
} }
@ -1337,7 +1364,7 @@ deliver(fd, name)
if (errno == EDQUOT && BounceQuota) if (errno == EDQUOT && BounceQuota)
errcode = "552 5.2.2"; errcode = "552 5.2.2";
#endif #endif
mailerr(errcode, "%s: %s", mailerr(errcode, "Write %s: %s",
path, sm_errstring(errno)); path, sm_errstring(errno));
goto err3; goto err3;
} }
@ -1345,7 +1372,7 @@ deliver(fd, name)
} }
if (nr < 0) if (nr < 0)
{ {
mailerr("450 4.2.0", "Temporary file: %s", mailerr("450 4.2.0", "Temporary file read error: %s",
sm_errstring(errno)); sm_errstring(errno));
goto err3; goto err3;
} }
@ -1353,7 +1380,7 @@ deliver(fd, name)
/* Flush to disk, don't wait for update. */ /* Flush to disk, don't wait for update. */
if (!nofsync && fsync(mbfd) < 0) if (!nofsync && fsync(mbfd) < 0)
{ {
mailerr("450 4.2.0", "%s: %s", path, sm_errstring(errno)); mailerr("450 4.2.0", "Sync %s: %s", path, sm_errstring(errno));
err3: err3:
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "reset euid = %d\n", (int) geteuid()); fprintf(stderr, "reset euid = %d\n", (int) geteuid());
@ -1362,7 +1389,11 @@ deliver(fd, name)
(void) ftruncate(mbfd, curoff); (void) ftruncate(mbfd, curoff);
err1: if (mbfd >= 0) err1: if (mbfd >= 0)
(void) close(mbfd); (void) close(mbfd);
err0: (void) setreuid(0, 0); err0:
#if MAIL_LOCAL_TEST
if (HomeMailFile == NULL || user.mbdb_uid != getuid())
#endif
(void) setreuid(0, 0);
unlockmbox(); unlockmbox();
return; return;
} }
@ -1390,7 +1421,7 @@ err0: (void) setreuid(0, 0);
if (errno == EDQUOT && BounceQuota) if (errno == EDQUOT && BounceQuota)
errcode = "552 5.2.2"; errcode = "552 5.2.2";
#endif #endif
mailerr(errcode, "%s: %s", path, sm_errstring(errno)); mailerr(errcode, "Close %s: %s", path, sm_errstring(errno));
mbfd = open(path, O_WRONLY, 0); mbfd = open(path, O_WRONLY, 0);
if (mbfd < 0 || if (mbfd < 0 ||
cursize == 0 cursize == 0
@ -1401,9 +1432,9 @@ err0: (void) setreuid(0, 0);
!S_ISREG(sb.st_mode) || !S_ISREG(sb.st_mode) ||
sb.st_dev != fsb.st_dev || sb.st_dev != fsb.st_dev ||
sb.st_ino != fsb.st_ino || sb.st_ino != fsb.st_ino ||
# if HAS_ST_GEN && 0 /* AFS returns random values for st_gen */ #if HAS_ST_GEN && 0 /* AFS returns random values for st_gen */
sb.st_gen != fsb.st_gen || sb.st_gen != fsb.st_gen ||
# endif #endif
sb.st_uid != fsb.st_uid sb.st_uid != fsb.st_uid
) )
{ {
@ -1421,7 +1452,11 @@ err0: (void) setreuid(0, 0);
else if (!nobiff) else if (!nobiff)
notifybiff(biffmsg); notifybiff(biffmsg);
if (setreuid(0, 0) < 0) if (
#if MAIL_LOCAL_TEST
(HomeMailFile == NULL || user.mbdb_uid != getuid()) &&
#endif
setreuid(0, 0) < 0)
{ {
mailerr("450 4.2.0", "setreuid(0, 0): %s", mailerr("450 4.2.0", "setreuid(0, 0): %s",
sm_errstring(errno)); sm_errstring(errno));
@ -1597,11 +1632,12 @@ void
usage() usage()
{ {
ExitVal = EX_USAGE; ExitVal = EX_USAGE;
# if _FFR_SPOOL_PATH /* XXX add U to options for USE_EAI */
#if _FFR_SPOOL_PATH
mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] [-p path] user ..."); mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] [-p path] user ...");
# else #else
mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] user ..."); mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] user ...");
# endif #endif
sm_exit(ExitVal); sm_exit(ExitVal);
} }
@ -1666,7 +1702,7 @@ hashname(name)
MD5_CTX ctx; MD5_CTX ctx;
unsigned char md5[18]; unsigned char md5[18];
# if MAXPATHLEN <= 24 # if MAXPATHLEN <= 24
ERROR _MAXPATHLEN <= 24 # ERROR "MAXPATHLEN <= 24"
# endif # endif
char b64[24]; char b64[24];
MD5_LONG bits; MD5_LONG bits;

View file

@ -15,7 +15,7 @@ mailstats
.SH SYNOPSIS .SH SYNOPSIS
.B mailstats .B mailstats
.RB [ \-c "] [" \-o "] [" \-p "] [" \-P ] .RB [ \-c "] [" \-o "] [" \-p "] [" \-P ]
.RB [ \-C .RB [ \-C
.IR cffile ] .IR cffile ]
.RB [ \-f .RB [ \-f
.IR stfile ] .IR stfile ]
@ -25,10 +25,10 @@ The
utility displays the current mail statistics. utility displays the current mail statistics.
.PP .PP
First, the time at which statistics started being kept is displayed, First, the time at which statistics started being kept is displayed,
in the format specified by in the format specified by
ctime(3). ctime(3).
Then, Then,
the statistics for each mailer are displayed on a single line, the statistics for each mailer are displayed on a single line,
each with the following white space separated fields: each with the following white space separated fields:
.sp .sp
.RS .RS
@ -36,7 +36,7 @@ each with the following white space separated fields:
.TP 1.2i .TP 1.2i
.B M .B M
The mailer number. The mailer number.
.TP .TP
.B msgsfr .B msgsfr
Number of messages from the mailer. Number of messages from the mailer.
.TP .TP
@ -63,15 +63,15 @@ The name of the mailer.
.PD .PD
.RE .RE
.PP .PP
After this display, a line totaling the values for all of the mailers After this display, a line totaling the values for all of the mailers
is displayed (preceded with a ``T''), is displayed (preceded with a ``T''),
separated from the previous information by a line containing only equals separated from the previous information by a line containing only equals
(``='') (``='')
characters. characters.
Another line preceded with a ``C'' lists the number of TCP connections. Another line preceded with a ``C'' lists the number of TCP connections.
.PP .PP
The options are as follows: The options are as follows:
.TP .TP
.B \-C .B \-C
Read the specified file instead of the default Read the specified file instead of the default
.B sendmail .B sendmail
@ -85,9 +85,9 @@ configuration file.
.B \-f .B \-f
Read the specified statistics file instead of the statistics file Read the specified statistics file instead of the statistics file
specified in the specified in the
.B sendmail .B sendmail
configuration file. configuration file.
.TP .TP
.B \-P .B \-P
Output information in program-readable mode without clearing statistics. Output information in program-readable mode without clearing statistics.
.TP .TP
@ -114,5 +114,5 @@ The default
statistics file. statistics file.
.PD .PD
.SH SEE ALSO .SH SEE ALSO
mailq(1), mailq(1),
sendmail(8) sendmail(8)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998-2002, 2004, 2008 Proofpoint, Inc. and its suppliers. * Copyright (c) 1998-2002, 2004, 2008, 2020 Proofpoint, Inc. and its suppliers.
* All rights reserved. * All rights reserved.
* Copyright (c) 1992 Eric P. Allman. All rights reserved. * Copyright (c) 1992 Eric P. Allman. All rights reserved.
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -38,6 +38,9 @@ SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.183 2013-11-22 20:51:52 ca Exp $")
#include <sm/path.h> #include <sm/path.h>
#include <sendmail/pathnames.h> #include <sendmail/pathnames.h>
#include <libsmdb/smdb.h> #include <libsmdb/smdb.h>
#if USE_EAI
# include <sm/ixlen.h>
#endif
uid_t RealUid; uid_t RealUid;
gid_t RealGid; gid_t RealGid;
@ -67,6 +70,11 @@ usage(progname)
sm_io_fprintf(smioerr, SM_TIME_DEFAULT, sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
" %*s [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter]\n", " %*s [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter]\n",
(int) strlen(progname), ""); (int) strlen(progname), "");
#if _FFR_TESTS
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
" %*s [-S n]\n",
(int) strlen(progname), "");
#endif
sm_io_fprintf(smioerr, SM_TIME_DEFAULT, sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
" %*s [-u] [-v] type mapname\n", " %*s [-u] [-v] type mapname\n",
(int) strlen(progname), ""); (int) strlen(progname), "");
@ -286,6 +294,12 @@ main(argc, argv)
static char rnamebuf[MAXNAME]; /* holds RealUserName */ static char rnamebuf[MAXNAME]; /* holds RealUserName */
extern char *optarg; extern char *optarg;
extern int optind; extern int optind;
#if USE_EAI
bool ascii = true;
#endif
#if _FFR_TESTS
int slp = 0;
#endif
memset(&params, '\0', sizeof params); memset(&params, '\0', sizeof params);
params.smdbp_cache_size = 1024 * 1024; params.smdbp_cache_size = 1024 * 1024;
@ -313,7 +327,12 @@ main(argc, argv)
SMDB_MAX_USER_NAME_LEN); SMDB_MAX_USER_NAME_LEN);
#define OPTIONS "C:D:Nc:defi:Llorst:uvx" #define OPTIONS "C:D:Nc:defi:Llorst:uvx"
while ((opt = getopt(argc, argv, OPTIONS)) != -1) #if _FFR_TESTS
# define X_OPTIONS "S:"
#else
# define X_OPTIONS
#endif
while ((opt = getopt(argc, argv, OPTIONS X_OPTIONS)) != -1)
{ {
switch (opt) switch (opt)
{ {
@ -369,6 +388,12 @@ main(argc, argv)
allowreplace = true; allowreplace = true;
break; break;
#if _FFR_TESTS
case 'S':
slp = atoi(optarg);
break;
#endif
case 's': case 's':
setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail); setbitn(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail);
setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail); setbitn(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail);
@ -393,7 +418,7 @@ main(argc, argv)
case 'v': case 'v':
verbose = true; verbose = true;
break; break;
case 'x': case 'x':
smdb_print_available_types(true); smdb_print_available_types(true);
exit(EX_OK); exit(EX_OK);
@ -602,12 +627,41 @@ main(argc, argv)
memset(&db_val, '\0', sizeof db_val); memset(&db_val, '\0', sizeof db_val);
db_key.data = ibuf; db_key.data = ibuf;
for (p = ibuf; *p != '\0' && !(ISSEP(*p)); p++) #if USE_EAI
db_key.size = 0;
if (foldcase)
{
for (p = ibuf; *p != '\0' && !ISSEP(*p); p++)
{
if (!ISASCII(*p))
ascii = false;
}
if (!ascii)
{
char sep;
char *lkey;
sep = *p;
*p = '\0';
lkey = sm_lowercase(ibuf);
db_key.data = lkey;
db_key.size = strlen(lkey);
*p = sep;
}
}
if (ascii)
#endif /* USE_EAI */
/* NOTE: see if () above! */
for (p = ibuf; *p != '\0' && !ISSEP(*p); p++)
{ {
if (foldcase && ISASCII(*p) && isupper(*p)) if (foldcase && ISASCII(*p) && isupper(*p))
*p = tolower(*p); *p = tolower(*p);
} }
db_key.size = p - ibuf; #if USE_EAI
if (0 == db_key.size)
#endif
db_key.size = p - ibuf;
if (inclnull) if (inclnull)
db_key.size++; db_key.size++;
@ -680,6 +734,11 @@ main(argc, argv)
} }
} }
#if _FFR_TESTS
if (slp > 0)
sleep(slp);
#endif
/* /*
** Now close the database. ** Now close the database.
*/ */

Some files were not shown because too many files have changed in this diff Show more