diff --git a/contrib/sendmail/CACerts b/contrib/sendmail/CACerts new file mode 100644 index 000000000000..c708677e902e --- /dev/null +++ b/contrib/sendmail/CACerts @@ -0,0 +1,302 @@ +# $Id: CACerts,v 8.1 2004/03/01 22:05:47 ca Exp $ +# This file contains some CA certificates that are used to sign the +# certificates of mail servers of members of the sendmail consortium +# who may reply to questions etc sent to sendmail.org. +# It is useful to allow connections from those MTAs that can present +# a certificate signed by one of these CA certificates. +# + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=California, L=Berkeley, O=Sendmail Consortium, CN=Certificate Authority/emailAddress=certificates@sendmail.org + Validity + Not Before: Feb 1 21:51:47 2003 GMT + Not After : Jan 31 21:51:47 2008 GMT + Subject: C=US, ST=California, L=Berkeley, O=Sendmail Consortium, CN=Certificate Authority/emailAddress=certificates@sendmail.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:9a:fb:dc:4c:a3:58:21:1b:84:78:0a:53:56:b3: + 8d:84:05:b7:db:dd:d7:81:ea:dd:c1:ab:d4:be:d9: + 2b:12:e0:6d:3a:31:d5:f0:7b:13:fc:d8:da:09:0b: + 71:11:8e:b9:48:c4:ab:ae:f5:9c:4c:e2:04:27:8e: + c8:03:3a:aa:00:8b:46:f2:79:09:ae:65:b2:9a:66: + e7:ac:a9:ea:32:f7:4a:4e:fd:da:41:48:34:5a:9d: + b0:42:ea:55:40:17:27:5e:67:9e:e5:ce:dc:84:6d: + 1d:48:37:23:11:68:9d:a8:d4:58:02:05:ea:88:35: + bd:0d:b6:28:d5:cd:d4:d8:95 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + DE:CD:6E:B8:89:34:06:3D:E9:CD:A7:FE:45:4F:4E:FB:E1:8D:E7:79 + X509v3 Authority Key Identifier: + keyid:DE:CD:6E:B8:89:34:06:3D:E9:CD:A7:FE:45:4F:4E:FB:E1:8D:E7:79 + DirName:/C=US/ST=California/L=Berkeley/O=Sendmail Consortium/CN=Certificate Authority/emailAddress=certificates@sendmail.org + serial:00 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: md5WithRSAEncryption + 66:92:b9:57:17:3b:6a:0e:72:b1:85:29:53:9f:11:68:a0:0d: + 79:43:d0:7c:48:73:b9:71:09:50:08:02:03:0b:28:0c:33:9a: + 00:ac:94:69:4f:bc:0f:45:6b:f5:3a:ca:6a:87:a1:7f:28:f7: + 9a:c4:b6:b0:f3:dc:a3:eb:42:95:9f:99:19:f8:b8:84:6d:f1: + 1d:bc:9f:f0:a0:cc:60:2d:00:6b:17:55:33:16:85:d1:73:e1: + 00:59:89:33:19:c4:2e:29:5a:39:a7:0e:e7:9b:d2:4c:c7:b9: + 7d:6a:3e:b4:00:83:86:d3:16:28:fd:ad:55:65:60:4e:14:02: + 46:d3 +-----BEGIN CERTIFICATE----- +MIIDsDCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBnTELMAkGA1UEBhMCVVMx +EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCEJlcmtlbGV5MRwwGgYDVQQK +ExNTZW5kbWFpbCBDb25zb3J0aXVtMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRo +b3JpdHkxKDAmBgkqhkiG9w0BCQEWGWNlcnRpZmljYXRlc0BzZW5kbWFpbC5vcmcw +HhcNMDMwMjAxMjE1MTQ3WhcNMDgwMTMxMjE1MTQ3WjCBnTELMAkGA1UEBhMCVVMx +EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCEJlcmtlbGV5MRwwGgYDVQQK +ExNTZW5kbWFpbCBDb25zb3J0aXVtMR4wHAYDVQQDExVDZXJ0aWZpY2F0ZSBBdXRo +b3JpdHkxKDAmBgkqhkiG9w0BCQEWGWNlcnRpZmljYXRlc0BzZW5kbWFpbC5vcmcw +gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJr73EyjWCEbhHgKU1azjYQFt9vd +14Hq3cGr1L7ZKxLgbTox1fB7E/zY2gkLcRGOuUjEq671nEziBCeOyAM6qgCLRvJ5 +Ca5lsppm56yp6jL3Sk792kFINFqdsELqVUAXJ15nnuXO3IRtHUg3IxFonajUWAIF +6og1vQ22KNXN1NiVAgMBAAGjgf0wgfowHQYDVR0OBBYEFN7NbriJNAY96c2n/kVP +Tvvhjed5MIHKBgNVHSMEgcIwgb+AFN7NbriJNAY96c2n/kVPTvvhjed5oYGjpIGg +MIGdMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMI +QmVya2VsZXkxHDAaBgNVBAoTE1NlbmRtYWlsIENvbnNvcnRpdW0xHjAcBgNVBAMT +FUNlcnRpZmljYXRlIEF1dGhvcml0eTEoMCYGCSqGSIb3DQEJARYZY2VydGlmaWNh +dGVzQHNlbmRtYWlsLm9yZ4IBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUA +A4GBAGaSuVcXO2oOcrGFKVOfEWigDXlD0HxIc7lxCVAIAgMLKAwzmgCslGlPvA9F +a/U6ymqHoX8o95rEtrDz3KPrQpWfmRn4uIRt8R28n/CgzGAtAGsXVTMWhdFz4QBZ +iTMZxC4pWjmnDueb0kzHuX1qPrQAg4bTFij9rVVlYE4UAkbT +-----END CERTIFICATE----- + + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=California, L=Emeryville, O=gshapiro.net, CN=Certificate Authority/emailAddress=certificates@gshapiro.net + Validity + Not Before: Jan 1 04:39:54 2002 GMT + Not After : Dec 31 04:39:54 2006 GMT + Subject: C=US, ST=California, L=Emeryville, O=gshapiro.net, CN=Certificate Authority/emailAddress=certificates@gshapiro.net + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:aa:dd:a2:fe:3b:fa:2f:5c:3d:f1:e1:d4:1d:55: + 04:27:6b:01:62:00:d7:02:cb:74:47:69:84:d7:c6: + c5:71:55:79:35:3a:a8:ce:de:48:23:53:80:3c:cd: + 54:2e:e9:fe:b1:76:5a:be:cb:fd:2d:dc:a3:36:c5: + c7:1e:4e:ef:76:f0:55:8f:a0:a5:f8:07:c5:52:1d: + a2:42:81:4d:8a:c8:42:3f:f3:01:80:f9:46:35:a6: + bc:c0:9b:9f:33:8b:49:9b:1d:87:8f:19:48:15:21: + 23:57:df:6e:4d:03:ed:ae:9f:0b:91:b7:a9:47:66: + f1:0d:1b:1c:5d:b4:57:60:c7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + A0:6D:E0:06:AF:61:94:B4:C6:84:15:B4:8B:74:22:67:4A:43:60:CA + X509v3 Authority Key Identifier: + keyid:A0:6D:E0:06:AF:61:94:B4:C6:84:15:B4:8B:74:22:67:4A:43:60:CA + DirName:/C=US/ST=California/L=Emeryville/O=gshapiro.net/CN=Certificate Authority/emailAddress=certificates@gshapiro.net + serial:00 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: md5WithRSAEncryption + 87:27:d2:2a:3a:dc:04:cd:ef:e8:7b:1c:34:47:2e:13:34:a5: + 08:f9:4d:df:d8:e1:6d:e6:9a:db:38:ee:20:6d:4a:ae:6f:1e: + bc:71:61:a4:b4:d6:40:24:ee:65:ca:e9:81:5a:ef:ee:62:57: + 70:05:46:91:6b:d0:c6:a6:e9:38:65:ae:ea:50:b3:5c:27:c4: + 7a:bd:95:8c:cb:45:ef:fc:fc:99:e5:6a:61:c3:44:77:d8:1f: + d6:b4:17:44:15:9a:bc:26:5b:ec:4e:29:5d:fd:cf:61:f3:be: + 91:a4:3b:51:e6:73:5b:17:82:9d:5a:56:2c:63:c2:f1:d6:a2: + 4c:5a +-----BEGIN CERTIFICATE----- +MIIDoTCCAwqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmDELMAkGA1UEBhMCVVMx +EzARBgNVBAgTCkNhbGlmb3JuaWExEzARBgNVBAcTCkVtZXJ5dmlsbGUxFTATBgNV +BAoTDGdzaGFwaXJvLm5ldDEeMBwGA1UEAxMVQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MSgwJgYJKoZIhvcNAQkBFhljZXJ0aWZpY2F0ZXNAZ3NoYXBpcm8ubmV0MB4XDTAy +MDEwMTA0Mzk1NFoXDTA2MTIzMTA0Mzk1NFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQHEwpFbWVyeXZpbGxlMRUwEwYDVQQKEwxn +c2hhcGlyby5uZXQxHjAcBgNVBAMTFUNlcnRpZmljYXRlIEF1dGhvcml0eTEoMCYG +CSqGSIb3DQEJARYZY2VydGlmaWNhdGVzQGdzaGFwaXJvLm5ldDCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAqt2i/jv6L1w98eHUHVUEJ2sBYgDXAst0R2mE18bF +cVV5NTqozt5II1OAPM1ULun+sXZavsv9LdyjNsXHHk7vdvBVj6Cl+AfFUh2iQoFN +ishCP/MBgPlGNaa8wJufM4tJmx2HjxlIFSEjV99uTQPtrp8LkbepR2bxDRscXbRX +YMcCAwEAAaOB+DCB9TAdBgNVHQ4EFgQUoG3gBq9hlLTGhBW0i3QiZ0pDYMowgcUG +A1UdIwSBvTCBuoAUoG3gBq9hlLTGhBW0i3QiZ0pDYMqhgZ6kgZswgZgxCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQHEwpFbWVyeXZpbGxl +MRUwEwYDVQQKEwxnc2hhcGlyby5uZXQxHjAcBgNVBAMTFUNlcnRpZmljYXRlIEF1 +dGhvcml0eTEoMCYGCSqGSIb3DQEJARYZY2VydGlmaWNhdGVzQGdzaGFwaXJvLm5l +dIIBADAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAIcn0io63ATN7+h7 +HDRHLhM0pQj5Td/Y4W3mmts47iBtSq5vHrxxYaS01kAk7mXK6YFa7+5iV3AFRpFr +0Mam6ThlrupQs1wnxHq9lYzLRe/8/JnlamHDRHfYH9a0F0QVmrwmW+xOKV39z2Hz +vpGkO1Hmc1sXgp1aVixjwvHWokxa +-----END CERTIFICATE----- + + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=Illinois, L=De Kalb, O=Northern Illinois University, OU=Computer Science, CN=Neil Rickert/emailAddress=rickert@cs.niu.edu + Validity + Not Before: May 12 00:40:50 2000 GMT + Not After : May 20 00:40:50 2010 GMT + Subject: C=US, ST=Illinois, L=De Kalb, O=Northern Illinois University, OU=Computer Science, CN=Neil Rickert/emailAddress=rickert@cs.niu.edu + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (1024 bit) + Modulus (1024 bit): + 00:b1:1b:49:06:ef:3f:44:e0:93:ad:8c:a7:f7:21: + 7c:87:cb:da:35:f6:4b:a2:fd:8a:a0:07:5b:cc:6a: + 9b:89:33:fc:24:f5:b1:24:59:5a:25:50:fd:16:d7: + d4:bc:c7:04:1d:df:90:9b:5e:c3:a8:e9:8b:7d:a3: + 5d:9a:e9:7f:e5:2b:ea:15:a7:ad:ba:58:26:0a:11: + 49:4f:da:9a:67:7f:b0:a6:66:f4:27:b6:61:4e:3c: + c8:3e:a0:2f:6a:b4:0e:15:d6:39:f8:92:60:85:df: + a6:34:f3:fa:a4:a5:e4:47:49:e7:87:a4:a5:5c:8e: + 6a:2f:13:76:5f:29:f3:64:73 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + B6:31:78:BB:7E:AA:4D:A1:5D:FD:A2:24:18:C6:90:5A:2D:2F:19:48 + X509v3 Authority Key Identifier: + keyid:B6:31:78:BB:7E:AA:4D:A1:5D:FD:A2:24:18:C6:90:5A:2D:2F:19:48 + DirName:/C=US/ST=Illinois/L=De Kalb/O=Northern Illinois University/OU=Computer Science/CN=Neil Rickert/emailAddress=rickert@cs.niu.edu + serial:00 + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: md5WithRSAEncryption + 60:69:23:65:97:51:5c:06:a4:42:cb:00:e7:9a:dc:39:70:c3: + d3:5d:bf:0f:e0:04:54:4d:d9:dc:12:57:12:6c:67:fd:5b:b0: + 39:63:ea:c4:12:65:51:bb:3d:f1:f7:25:b4:cd:0b:f6:5b:7a: + 61:25:ad:06:0a:01:55:dc:71:05:29:0d:73:e9:30:51:be:d3: + e1:b2:89:fc:0f:28:f7:06:75:96:1b:34:75:e0:07:e5:3b:b3: + 0b:28:24:e5:79:ea:55:39:e7:d2:ee:ec:63:b4:e4:c6:ee:cb: + 15:d0:c8:eb:3b:4f:36:10:a4:6a:c0:6b:03:e8:29:72:c7:a7: + 10:00 +-----BEGIN CERTIFICATE----- +MIID5TCCA06gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBrjELMAkGA1UEBhMCVVMx +ETAPBgNVBAgTCElsbGlub2lzMRAwDgYDVQQHEwdEZSBLYWxiMSUwIwYDVQQKExxO +b3J0aGVybiBJbGxpbm9pcyBVbml2ZXJzaXR5MRkwFwYDVQQLExBDb21wdXRlciBT +Y2llbmNlMRUwEwYDVQQDEwxOZWlsIFJpY2tlcnQxITAfBgkqhkiG9w0BCQEWEnJp +Y2tlcnRAY3Mubml1LmVkdTAeFw0wMDA1MTIwMDQwNTBaFw0xMDA1MjAwMDQwNTBa +MIGuMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0Rl +IEthbGIxJTAjBgNVBAoTHE5vcnRoZXJuIElsbGlub2lzIFVuaXZlcnNpdHkxGTAX +BgNVBAsTEENvbXB1dGVyIFNjaWVuY2UxFTATBgNVBAMTDE5laWwgUmlja2VydDEh +MB8GCSqGSIb3DQEJARYScmlja2VydEBjcy5uaXUuZWR1MIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQCxG0kG7z9E4JOtjKf3IXyHy9o19kui/YqgB1vMapuJM/wk +9bEkWVolUP0W19S8xwQd35CbXsOo6Yt9o12a6X/lK+oVp626WCYKEUlP2ppnf7Cm +ZvQntmFOPMg+oC9qtA4V1jn4kmCF36Y08/qkpeRHSeeHpKVcjmovE3ZfKfNkcwID +AQABo4IBDzCCAQswHQYDVR0OBBYEFLYxeLt+qk2hXf2iJBjGkFotLxlIMIHbBgNV +HSMEgdMwgdCAFLYxeLt+qk2hXf2iJBjGkFotLxlIoYG0pIGxMIGuMQswCQYDVQQG +EwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0RlIEthbGIxJTAjBgNV +BAoTHE5vcnRoZXJuIElsbGlub2lzIFVuaXZlcnNpdHkxGTAXBgNVBAsTEENvbXB1 +dGVyIFNjaWVuY2UxFTATBgNVBAMTDE5laWwgUmlja2VydDEhMB8GCSqGSIb3DQEJ +ARYScmlja2VydEBjcy5uaXUuZWR1ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEEBQADgYEAYGkjZZdRXAakQssA55rcOXDD012/D+AEVE3Z3BJXEmxn/VuwOWPq +xBJlUbs98fcltM0L9lt6YSWtBgoBVdxxBSkNc+kwUb7T4bKJ/A8o9wZ1lhs0deAH +5TuzCygk5XnqVTnn0u7sY7Tkxu7LFdDI6ztPNhCkasBrA+gpcsenEAA= +-----END CERTIFICATE----- + +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: md5WithRSAEncryption + Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2003/emailAddress=ca+ca-rsa2003@esmtp.org + Validity + Not Before: Aug 7 15:56:45 2003 GMT + Not After : Aug 6 15:56:45 2006 GMT + Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2003/emailAddress=ca+ca-rsa2003@esmtp.org + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:aa:37:0f:09:a9:1c:e3:1a:0c:fe:bd:6c:37:a4: + cf:87:db:af:6b:b4:19:d4:11:db:c6:56:ca:39:80: + c6:a4:38:b0:bc:ac:7e:be:71:30:86:2c:dc:fa:b5: + fd:58:23:a0:c1:ad:11:53:85:ca:fb:e6:d8:7e:28: + eb:84:3b:cd:a3:fa:28:a5:cb:c7:b2:54:99:3e:40: + 2a:27:43:4b:0c:26:4b:af:97:3d:92:82:d9:eb:2c: + 7f:77:fd:b8:cd:7e:1e:04:81:17:3c:e2:44:68:ce: + 88:66:02:90:24:35:24:c4:4c:ad:77:04:1a:3a:d5: + 59:28:28:03:da:03:9d:f4:2e:52:6e:b5:36:96:4b: + 14:f8:fc:8e:c6:d3:9b:e2:80:90:8b:71:d7:d0:5c: + 43:b2:49:f1:5a:26:f3:5d:9e:3b:01:98:db:e3:ed: + 5e:8d:dd:cf:aa:68:9d:0b:c9:e2:4e:fc:16:44:72: + 93:07:62:18:05:c1:47:81:3c:3d:e4:e4:22:da:2c: + d6:4a:44:52:06:7a:83:b5:e9:52:38:97:2f:75:a6: + 5c:6f:87:8a:8d:83:f4:d0:04:a5:34:18:5e:a1:06: + 16:b3:54:ce:64:47:ca:70:56:a3:6f:b9:7f:af:91: + 76:78:70:b4:ab:ae:8e:d5:22:26:57:b1:ba:e7:4b: + 18:21 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 3A:12:03:DB:0F:9E:28:45:A6:34:8D:38:AB:BA:47:8C:2A:A0:E4:2E + X509v3 Authority Key Identifier: + keyid:3A:12:03:DB:0F:9E:28:45:A6:34:8D:38:AB:BA:47:8C:2A:A0:E4:2E + DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=Claus Assmann CA RSA 2003/emailAddress=ca+ca-rsa2003@esmtp.org + serial:00 + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Alternative Name: + email:ca+ca-rsa2003@esmtp.org + X509v3 Issuer Alternative Name: + email:ca+ca-rsa2003@esmtp.org + Signature Algorithm: md5WithRSAEncryption + 96:83:b6:54:93:df:38:d0:48:a7:a1:c8:08:c9:0f:e9:80:05: + e3:7e:c3:61:51:88:7b:7a:bb:24:b0:69:a3:22:e4:98:38:da: + c8:c3:eb:52:70:63:e2:66:f2:59:ef:56:be:aa:7c:87:6e:94: + 85:d4:71:ba:35:f7:ee:d0:6e:52:1d:1f:e4:fd:2f:e2:70:31: + 5d:b7:8b:13:cc:70:10:21:fa:34:29:8f:8d:d8:4a:c7:0f:b2: + 36:e7:1e:1e:46:d1:11:84:80:7c:bb:24:c4:63:be:2a:24:53: + 74:0c:89:e0:6a:f4:08:63:bf:54:d3:0a:d9:fc:fe:6c:de:4f: + 97:61:08:a0:10:92:eb:af:06:ec:50:86:c4:cc:6b:31:32:60: + 25:7a:09:47:f8:42:7a:a2:d5:90:fa:48:be:bf:0a:e1:03:b8: + 56:24:b9:12:e9:ba:09:30:47:be:a5:8e:a2:92:a4:dc:a6:a7: + c6:29:39:65:6e:64:4a:1b:b2:c3:07:29:f5:c0:7e:78:e0:22: + 9b:98:d4:87:91:ca:e1:66:9d:2f:70:f1:4c:a5:8e:2e:68:52: + b3:bd:95:76:56:40:0e:46:47:e4:b3:ec:aa:3c:e8:86:96:5a: + ed:fa:c9:10:95:53:04:13:71:01:91:ce:cd:3a:51:c6:30:e9: + 48:49:64:a3 +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBpTELMAkGA1UEBhMCVVMx +EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCEJlcmtlbGV5MRQwEgYDVQQK +EwtFbmRtYWlsIE9yZzEMMAoGA1UECxMDTVRBMSIwIAYDVQQDExlDbGF1cyBBc3Nt +YW5uIENBIFJTQSAyMDAzMSYwJAYJKoZIhvcNAQkBFhdjYStjYS1yc2EyMDAzQGVz +bXRwLm9yZzAeFw0wMzA4MDcxNTU2NDVaFw0wNjA4MDYxNTU2NDVaMIGlMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIQmVya2VsZXkx +FDASBgNVBAoTC0VuZG1haWwgT3JnMQwwCgYDVQQLEwNNVEExIjAgBgNVBAMTGUNs +YXVzIEFzc21hbm4gQ0EgUlNBIDIwMDMxJjAkBgkqhkiG9w0BCQEWF2NhK2NhLXJz +YTIwMDNAZXNtdHAub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +qjcPCakc4xoM/r1sN6TPh9uva7QZ1BHbxlbKOYDGpDiwvKx+vnEwhizc+rX9WCOg +wa0RU4XK++bYfijrhDvNo/oopcvHslSZPkAqJ0NLDCZLr5c9koLZ6yx/d/24zX4e +BIEXPOJEaM6IZgKQJDUkxEytdwQaOtVZKCgD2gOd9C5SbrU2lksU+PyOxtOb4oCQ +i3HX0FxDsknxWibzXZ47AZjb4+1ejd3PqmidC8niTvwWRHKTB2IYBcFHgTw95OQi +2izWSkRSBnqDtelSOJcvdaZcb4eKjYP00ASlNBheoQYWs1TOZEfKcFajb7l/r5F2 +eHC0q66O1SImV7G650sYIQIDAQABo4IBTjCCAUowHQYDVR0OBBYEFDoSA9sPnihF +pjSNOKu6R4wqoOQuMIHSBgNVHSMEgcowgceAFDoSA9sPnihFpjSNOKu6R4wqoOQu +oYGrpIGoMIGlMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8G +A1UEBxMIQmVya2VsZXkxFDASBgNVBAoTC0VuZG1haWwgT3JnMQwwCgYDVQQLEwNN +VEExIjAgBgNVBAMTGUNsYXVzIEFzc21hbm4gQ0EgUlNBIDIwMDMxJjAkBgkqhkiG +9w0BCQEWF2NhK2NhLXJzYTIwMDNAZXNtdHAub3JnggEAMAwGA1UdEwQFMAMBAf8w +IgYDVR0RBBswGYEXY2ErY2EtcnNhMjAwM0Blc210cC5vcmcwIgYDVR0SBBswGYEX +Y2ErY2EtcnNhMjAwM0Blc210cC5vcmcwDQYJKoZIhvcNAQEEBQADggEBAJaDtlST +3zjQSKehyAjJD+mABeN+w2FRiHt6uySwaaMi5Jg42sjD61JwY+Jm8lnvVr6qfIdu +lIXUcbo19+7QblIdH+T9L+JwMV23ixPMcBAh+jQpj43YSscPsjbnHh5G0RGEgHy7 +JMRjviokU3QMieBq9Ahjv1TTCtn8/mzeT5dhCKAQkuuvBuxQhsTMazEyYCV6CUf4 +Qnqi1ZD6SL6/CuEDuFYkuRLpugkwR76ljqKSpNymp8YpOWVuZEobssMHKfXAfnjg +IpuY1IeRyuFmnS9w8Uylji5oUrO9lXZWQA5GR+Sz7Ko86IaWWu36yRCVUwQTcQGR +zs06UcYw6UhJZKM= +-----END CERTIFICATE----- diff --git a/contrib/sendmail/KNOWNBUGS b/contrib/sendmail/KNOWNBUGS index b2c6c44327f0..1d45bef88150 100644 --- a/contrib/sendmail/KNOWNBUGS +++ b/contrib/sendmail/KNOWNBUGS @@ -241,4 +241,4 @@ Kresolve sequence dnsmx canon be used if set instead of LOCAL_RELAY ($R). This will be fixed in a future version. -$Revision: 8.55.2.1 $, Last updated $Date: 2002/12/18 22:38:48 $ +$Revision: 8.56 $, Last updated $Date: 2002/12/18 22:39:06 $ diff --git a/contrib/sendmail/LICENSE b/contrib/sendmail/LICENSE index 7602ad4689ec..e8639f5a5a92 100644 --- a/contrib/sendmail/LICENSE +++ b/contrib/sendmail/LICENSE @@ -33,7 +33,7 @@ each of the following conditions is met: forth as paragraph 6 below, in the documentation and/or other materials provided with the distribution. For the purposes of binary distribution the "Copyright Notice" refers to the following language: - "Copyright (c) 1998-2003 Sendmail, Inc. All rights reserved." + "Copyright (c) 1998-2004 Sendmail, Inc. All rights reserved." 4. Neither the name of Sendmail, Inc. nor the University of California nor the names of their contributors may be used to endorse or promote @@ -76,4 +76,4 @@ each of the following conditions is met: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -$Revision: 8.11.2.1 $, Last updated $Date: 2003/04/19 14:30:36 $ +$Revision: 8.13 $, Last updated $Date: 2004/05/11 23:57:57 $ diff --git a/contrib/sendmail/PGPKEYS b/contrib/sendmail/PGPKEYS index 860252b6e672..ddd08baeaf10 100644 --- a/contrib/sendmail/PGPKEYS +++ b/contrib/sendmail/PGPKEYS @@ -1022,4 +1022,4 @@ SIXqPke2iCW6+zdG1T/gS5T9T9/Lf2c9FQf0FjURAi3ynDA2RBLA5FDsI8v3 =dbDm -----END PGP PUBLIC KEY BLOCK----- -$Revision: 8.13.2.4 $, Last updated $Date: 2004/01/13 21:18:06 $ +$Revision: 8.17 $, Last updated $Date: 2004/01/13 21:17:49 $ diff --git a/contrib/sendmail/README b/contrib/sendmail/README index ec4d441e335b..c93c11f1f410 100644 --- a/contrib/sendmail/README +++ b/contrib/sendmail/README @@ -463,4 +463,4 @@ sendmail Source for the sendmail program itself. test Some test scripts (currently only for compilation aids). vacation Source for the vacation program. NOT PART OF SENDMAIL! -$Revision: 8.90.2.1 $, Last updated $Date: 2002/11/09 23:32:28 $ +$Revision: 8.91 $, Last updated $Date: 2002/11/09 23:33:07 $ diff --git a/contrib/sendmail/RELEASE_NOTES b/contrib/sendmail/RELEASE_NOTES index 0d6377d420c6..6df95cf3d4fb 100644 --- a/contrib/sendmail/RELEASE_NOTES +++ b/contrib/sendmail/RELEASE_NOTES @@ -1,11 +1,474 @@ SENDMAIL RELEASE NOTES - $Id: RELEASE_NOTES,v 8.1340.2.189 2004/01/18 17:50:57 ca Exp $ + $Id: RELEASE_NOTES,v 8.1679 2004/07/30 18:03:07 ca Exp $ This listing shows the version of the sendmail binary, the version of the sendmail configuration files, the date of release, and a summary of the changes in that release. +8.13.1/8.13.1 2004/07/30 + Using the default AliasFile ldap: specification would cause the + objectClasses of the LDAP response to be included in the + alias expansion. Problem noted by Brenden Conte of + Rensselaer Polytechnic Institute. + Fix support for a fallback smart host for system where DNS is + (partially) available. From John Beck of Sun Microsystems. + Fix SuperSafe=PostMilter behavior when a milter replaces a body + but the data file is not yet stored on disk because it is + smaller than the size of the memory buffer. Problem noted + by David Russell. + Fix certificate revocation list support; if a CRL was specified + but the other side presented a cert that was signed by + a different (trusted) CA than the one which issued the CRL, + verification would always fail. Problem noted by Al Smith. + Run mailer programs as the RunAsUser when RunAsUser is set and + the F=S mailer flag is set without a U= mailer equate. + Problem noted by John Gardiner Myers of Proofpoint. + ${nbadrcpts} was off by one if BadRcptThrottle is zero. + Patch from Sung-hoon Choi of DreamWiz Inc. + CONFIG: Emit a warning if FEATURE(`access_db') is used after + FEATURE(`greet_pause') because then the latter will not + use the access map. Note: if no default value is given + for FEATURE(`greet_pause') then it issues an error if + FEATURE(`access_db') is not specified before it. + Problem noted by Alexander Dalloz of University of + Bielefeld. + CONFIG: Invoke ruleset Local_greet_pause if FEATURE(`greet_pause') + is used to give more flexibility for local changes. + Portability: + Fix a 64 bit problem in the socket map code. Problem + noted by Geoff Adams. + NetBSD 2.0F has closefrom(3). Patch from Andrew Brown. + NetBSD can use sysctl(3) to get the number of CPUs in + a system. Patch from Andrew Brown. + Add a README file in doc/op/ to explain potential + incompatibilities with various *roff related + tools. Problem tracked down by Per Hedeland. + New Files: + doc/op/README + +8.13.0/8.13.0 2004/06/20 + Do not include AUTH data in a bounce to avoid leaking confidential + information. See also cf/README about MSP and the section + "Providing SMTP AUTH Data when sendmail acts as Client". + Problem noted by Neil Rickert of Northern Illinois + University. + Fix compilation error in libsm/clock.c for -D_FFR_SLEEP_USE_SELECT=n + and -DSM_CONF_SETITIMER=0. Problem noted by Juergen Georgi + of RUS University of Stuttgart. + Fix bug in conversion from 8bit to quoted-printable. Problem found + by Christof Haerens, patch from Per Hedeland. + Add support for LDAP recursion based on types given to attribute + specifications in an LDAP map definition. This allows + LDAP queries to return a new query, a DN, or an LDAP + URL which will in turn be queried. See the ``LDAP + Recursion'' section of doc/op/op.me for more information. + Based on patch from Andrew Baucom. + Extend the default LDAP specifications for AliasFile + (O AliasFile=ldap:) and file classes (F{X}@LDAP) to + include support for LDAP recursion via new attributes. + See ``USING LDAP FOR ALIASES, MAPS, and CLASSES'' section + of cf/README for more information. + New option for LDAP maps: the -w option allows you to specify the + LDAP API/protocol version to use. The default depends on + the LDAP library. + New option for LDAP maps: the -H option allows you to specify an + LDAP URI instead of specifying the LDAP server via -h host + and -p port. This also allows for the use of LDAP over + SSL and connections via named sockets if your LDAP + library supports it. + New compile time flag SM_CONF_LDAP_INITIALIZE: set this if + ldap_initialize(3) is available (and LDAPMAP is set). + If MaxDaemonChildren is set and a command is repeated too often + during a SMTP session then terminate it just like it is + done for too many bad SMTP commands. + Basic connection rate control support has been added: the daemon + maintains the number of incoming connections per client + IP address and total in the macros {client_rate} and + {total_rate}, respectively. These macros can be used + in the cf file to impose connection rate limits. + A new option ConnectionRateWindowSize (default: 60s) + determines the length of the interval for which the + number of connections is stored. Based on patch from + Jose Marcio Martins da Cruz, Ecole des Mines de Paris. + Add optional protection from open proxies and SMTP slammers which + send SMTP traffic without waiting for the SMTP greeting. + If enabled by the new ruleset greet_pause (see + FEATURE(`greet_pause')), sendmail will wait the specified + amount of time before sending the initial 220 SMTP + greeting. If any traffic is received before then, a 554 + SMTP response is sent and all SMTP commands are rejected + during that connection. + If 32 NOOP (or unknown/bad) commands are issued by a client the SMTP + server could sleep for a very long time. Fix based on + patch from Tadashi Kobayashi of IIJ. + Fix a potential memory leak in persistent queue runners if the + number of entries in the queue exceeds the limit of jobs. + Problem noted by Steve Hubert of University of Washington. + Do not use 4.7.1 as enhanced status code because some broken systems + misinterpret it as a permanent error. + New value for SuperSafe: PostMilter which will delay fsync() until + all milters accepted the mail. This can increase + performance if many mails are rejected by milters due to + body scans. Based on patch from David F. Skoll. + New macro {msg_id} which contains the value of the Message-Id: + header, whether provided by the client or generated by + sendmail. + New macro {client_connections} which contains the number of open + connections in the SMTP server for the client IP address. + Based on patch from Jose Marcio Martins da Cruz, Ecole des + Mines de Paris. + sendmail will now remove its pidfile when it exits. This was done + to prevent confusion caused by running sendmail stop + scripts two or more times, where the second and subsequent + runs would report misleading error messages about sendmail's + pid no longer existing. See section 1.3.15 of doc/op/op.me + for a discussion of the implications of this, including + how to correct broken scripts which may have depended on + the old behavior. From John Beck of Sun Microsystems. + Support per-daemon input filter lists which override the default + filter list specified in InputMailFilters. The filters + can be listed in the I= equate of DaemonPortOptions. + Do not add all domain prefixes of the hostname to class 'w'. If + your configuration relies on this behavior, you have to + add those names to class 'w' yourself. Problem noted + by Sander Eerkes. + Support message quarantining in the mail queue. Quarantined + messages are not run on normal queue displays or runs + unless specifically requested with -qQ. Quarantined queue + files are named with an hf prefix instead of a qf prefix. + The -q command line option now can specify which queue to display + or run. -qQ operates on quarantined queue items. -qL + operates on lost queue items. + Restricted mail queue runs and displays can be done based on the + quarantined reason using -qQtext to run or display + quarantined items if the quarantine reason contains the + given text. Similarly, -q!Qtext will run or display + quarantined items which do not have the given text in the + quarantine reason. + Items in the queue can be quarantined or unquarantined using the + new -Q option. See doc/op/op.me for more information. + When displaying the quarantine mailq with 'mailq -qQ', the + quarantine reason is shown in a new line prefixed by + "QUARANTINE:". + A new error code for the $#error mailer, $@ quarantine, can be used + to quarantine messages in check_* (except check_compat) and + header check rulesets. The $: of the mailer triplet will + be used for the quarantine reason. + Add a new quarantine count to the mailstats collected. + Add a new macro ${quarantine} which is the quarantine reason for a + message if it is quarantined. + New map type "socket" for a trivial query protocol over UNIX domain + or TCP sockets (requires compile time option SOCKETMAP). + See sendmail/README and doc/op/op.me for details as well as + socketmapServer.pl and socketmapClient.pl in contrib. + Code donated by Bastiaan Bakker of LifeLine Networks. + Define new macro ${client_ptr} which holds the result of the PTR + lookup for the client IP address. Note: this is the same + as ${client_name} if and only if ${client_resolve} is OK. + Add a new macro ${nbadrcpts} which contains the number of bad + recipients received so far in a transaction. + Call check_relay with the value of ${client_name} to deal with bogus + DNS entries. See also FEATURE(`use_client_ptr'). Problem + noted by Kai Schlichting. + Treat Delivery-Receipt-To: headers the same as Return-Receipt-To: + headers (turn them into DSNs). Delivery-Receipt-To: is + apparently used by SIMS (Sun Internet Mail System). + Enable connection caching for LPC mailers. Patch from Christophe + Wolfhugel of France Telecom Oleane. + Do not silently truncate long strings in address rewriting. + Add support for Cyrus SASL version 2. From Kenneth Murchison of + Oceana Matrix Ltd. + Add a new AuthOption=m flag to require the use of mechanisms which + support mutual authentication. From Kenneth Murchison of + Oceana Matrix Ltd. + Fix logging of TLS related problems (introduced in 8.12.11). + The macros {auth_author} and {auth_authen} are stored in xtext + format just like the STARTTLS related macros to avoid + problems with parsing them. Problem noted by Pierangelo + Masarati of SysNet s.n.c. + New option AuthRealm to set the authentication realm that is + passed to the Cyrus SASL library. Patch from Gary Mills + of the University of Manitoba. + Enable AUTH mechanism EXTERNAL if STARTTLS verification was + successful, otherwise relaying would be allowed if + EXTERNAL is listed in TRUST_AUTH_MECH() and STARTTLS + is active. + Add basic support for certificate revocation lists. Note: if a + CRLFile is specified but the file is unusable, STARTTLS + is disabled. Based on patch by Ralf Hornik. + Enable workaround for inconsistent Cyrus SASLv1 API for mechanisms + DIGEST-MD5 and LOGIN. + Write pid to file also if sendmail only acts as persistent queue + runner. Proposed by Gary Mills of the University of Manitoba. + Keep daemon pid file(s) locked so other daemons don't try to + overwrite each other's pid files. + Increase maximum length of logfile fields for {cert_subject} and + {cert_issuer} from 128 to 256. Requested by Christophe + Wolfhugel of France Telecom. + Log the TLS verification message on the STARTTLS= log line at + LogLevel 12 or higher. + If the MSP is invoked with the verbose option (-v) then it will + try to use the SMTP command VERB to propagate this option + to the MTA which in turn will show the delivery just like + it was done before the default 8.12 separation of MSP and + MTA. Based on patch by Per Hedeland. + If a daemon is refusing connections for longer than the time specified + by the new option RejectLogInterval (default: 3 hours) due + to high load, log this information. Patch from John Beck + of Sun Microsystems. + Remove the ability for non-trusted users to raise the value of + CheckpointInterval on the command line. + New mailer flag 'B' to strip leading backslashes, which is a + subset of the functionality of the 's' flag. + New mailer flag 'W' to ignore long term host status information. + Patch from Juergen Georgi of RUS University of Stuttgart. + Enable generic mail filter API (milter) by default. To turn + it off, add -DMILTER=0 to the compile time options. + An internal SMTP session discard flag was lost after an RSET/HELO/EHLO + causing subsequent messages to be sent instead of being + discarded. This also caused milter callbacks to be called + out of order after the SMTP session was reset. + New option RequiresDirfsync to turn off the compile time flag + REQUIRES_DIR_FSYNC at runtime. See sendmail/README for + further information. + New command line option -D logfile to send debug output to + the indicated log file instead of stdout. + Add Timeout.queuereturn.dsn and Timeout.queuewarn.dsn to control + queue return and warning times for delivery status + notifications. + New queue sort order option: 'n'one for not sorting the queue entries + at all. + Several more return values for ruleset srv_features have been added + to enable/disable certain features in the server per + connection. See doc/op/op.me for details. + Support for SMTP over SSL (smtps), activated by Modifier=s + for DaemonPortOptions. + Continue with DNS lookups on ECONNREFUSED and TRY_AGAIN when + trying to canonify hostnames. Suggested by Neil Rickert + of Northern Illinois University. + Add support for a fallback smart host (option FallbackSmartHost) to + be tried as a last resort after all other fallbacks. This + is designed for sites with partial DNS (e.g., an accurate + view of inside the company, but an incomplete view of + outside). From John Beck of Sun Microsystems. + Enable timeout for STARTTLS even if client does not start the TLS + handshake. Based on patch by Andrey J. Melnikoff. + Remove deprecated -v option for PH map, use -k instead. Patch from + Mark Roth of the University of Illinois at Urbana-Champaign. + libphclient is version 1.2.x by default, if version 1.1.x is required + then compile with -DNPH_VERSION=10100. Patch from Mark Roth + of the University of Illinois at Urbana-Champaign. + Add Milter.macros.eom, allowing macros to be sent to milter + applications for use in the xxfi_eom() callback. + New macro {time} which contains the output of the time(3) function, + i.e., the number of seconds since 0 hours, 0 minutes, + 0 seconds, January 1, 1970, Coordinated Universal Time (UTC). + If check_relay sets the reply code to "421" the SMTP server will + terminate the SMTP session with a 421 error message. + Get rid of dead code that tried to access the environment variable + HOSTALIASES. + Deprecate the use of ErrorMode=write. To enable this in 8.13 + compile with -DUSE_TTYPATH=1. + Header check rulesets using $>+ (do not strip comments) will get + the header value passed in without balancing quotes, + parentheses, and angle brackets. Based on patch from + Oleg Bulyzhin. + Do not complain and fix up unbalanced quotes, parentheses, and + angle brackets when reading in rulesets. This allows + rules to be written for header checks to catch strings + that contain quotes, parentheses, and/or angle brackets. + Based on patch from Oleg Bulyzhin. + Do not close socket when accept(2) in the daemon encounters + some temporary errors like ECONNABORTED. + Added list of CA certificates that are used by members of the + sendmail consortium, see CACerts. + Portability: + Two new compile options have been added: + HASCLOSEFROM System has closefrom(3). + HASFDWALK System has fdwalk(3). + Based on patch from John Beck of Sun Microsystems. + The Linux kernel version 2.4 series has a broken flock() so + change to using fcntl() locking until they can fix + it. Be sure to update other sendmail related + programs to match locking techniques. + New compile time option NEEDINTERRNO which should be set + if does not declare errno itself. + Support for UNICOS/mk and UNICOS/mp added, some changes for + UNICOS. Patches contributed by Aaron Davis and + Brian Ginsbach, Cray Inc., and Manu Mahonen of + Center for Scientific Computing. + Add support for Darwin 7.0/Mac OS X 10.3 (a.k.a. Panther). + Extend support to Darwin 7.x/Mac OS X 10.3 (a.k.a. Panther). + Remove path from compiler definition for Interix because + Interix 3.0 and 3.5 put gcc in different locations. + Also use to get the correct + major()/minor() definitions. Based on feedback + from Mark Funkenhauser. + CONFIG: Add support for LDAP recursion to the default LDAP searches + for maps via new attributes. See the ``USING LDAP FOR + ALIASES, MAPS, and CLASSES'' section of cf/README and + cf/sendmail.schema for more information. + CONFIG: Make sure confTRUSTED_USER is valid even if confRUN_AS_USER + is of the form "user:group" when used for submit.mc. + Problem noted by Carsten P. Gehrke, patch from Neil Rickert + of Northern Illinois University. + CONFIG: Add a new access DB value of QUARANTINE:reason which + instructs the check_* (except check_compat) to quarantine + the message using the given reason. + CONFIG: Use "dns -R A" as map type for dnsbl (just as for enhdnsbl) + instead of "host" to avoid problem with looking up other + DNS records than just A. + CONFIG: New option confCONNECTION_RATE_WINDOW_SIZE to define the + length of the interval for which the number of incoming + connections is maintained. + CONFIG: New FEATURE(`ratecontrol') to set the limits for connection + rate control for individual hosts or nets. + CONFIG: New FEATURE(`conncontrol') to set the limits for the + number of open SMTP connections for individual hosts or nets. + CONFIG: New FEATURE(`greet_pause') enables open proxy and SMTP + slamming protection described above. The feature can + take an argument specifying the milliseconds to wait and/or + use the access database to look the pause time based on + client hostname, domain, IP address, or subnet. + CONFIG: New FEATURE(`use_client_ptr') to have check_relay use + $&{client_ptr} as its first argument. This is useful for + rejections based on the unverified hostname of client, + which turns on the same behavior as in earlier sendmail + versions when delay_checks was not in use. See also entry + above about check_relay being invoked with ${client_name}. + CONFIG: New option confREJECT_LOG_INTERVAL to specify the log + interval when refusing connections for this long. + CONFIG: Remove quotes around usage of confREJECT_MSG; in some cases + this requires a change in a mc file. Requested by + Ted Roberts of Electronic Data Systems. + CONFIG: New option confAUTH_REALM to set the authentication realm + that is passed to the Cyrus SASL library. Patch from + Gary Mills of the University of Manitoba. + CONFIG: Rename the (internal) classes {tls}/{src} to {Tls}/{Src} + to follow the naming conventions. + CONFIG: Add a third optional argument to local_lmtp to specify + the A= argument. + CONFIG: Remove the f flag from the default mailer flags of + local_lmtp. + CONFIG: New option confREQUIRES_DIR_FSYNC to turn off the compile + time flag REQUIRES_DIR_FSYNC at runtime. + CONFIG: New LOCAL_UUCP macro to insert rules into the generated + cf file at the same place where MAILER(`uucp') inserts + its rules. + CONFIG: New options confTO_QUEUERETURN_DSN and confTO_QUEUEWARN_DSN + to control queue return and warning times for delivery + status notifications. + CONFIG: New option confFALLBACK_SMARTHOST to define FallbackSmartHost. + CONFIG: Add the mc file which has been used to create the cf + file to the end of the cf file when using make in cf/cf/. + Patch from Richard Rognlie. + CONFIG: FEATURE(nodns) has been removed, it was a no-op since 8.9. + Use ServiceSwitchFile to turn off DNS lookups, see + doc/op/op.me. + CONFIG: New option confMILTER_MACROS_EOM (sendmail Milter.macros.eom + option) defines macros to be sent to milter applications for + use in the xxfi_eom() callback. + CONFIG: New option confCRL to specify file which contains + certificate revocations lists. + CONFIG: Add a new value (sendertoo) for the third argument to + FEATURE(`ldap_routing') which will reject the SMTP + MAIL From: command if the sender address doesn't exist + in LDAP. See cf/README for more information. + CONFIG: Add a fifth argument to FEATURE(`ldap_routing') which + instructs the rulesets on whether or not to do a domain + lookup if a full address lookup doesn't match. See cf/README + for more information. + CONFIG: Add a sixth argument to FEATURE(`ldap_routing') which + instructs the rulesets on whether or not to queue the mail + or give an SMTP temporary error if the LDAP server can't be + reached. See cf/README for more information. Based on + patch from Billy Ray Miller of Caterpillar. + CONFIG: Experimental support for MTAMark, see cf/README for details. + CONFIG: New option confMESSAGEID_HEADER to define a different + Message-Id: header format. Patch from Bastiaan Bakker + of LifeLine Networks. + CONTRIB: New version of cidrexpand which uses Net::CIDR. From + Derek J. Balling. + CONTRIB: oldbind.compat.c has been removed due to security problems. + Found by code inspection done by Reasoning, Inc. + DEVTOOLS: Add an example file for devtools/Site/, contributed + by Neil Rickert of Northern Illinois University. + LIBMILTER: Add new function smfi_quarantine() which allows the + filter's EOM routine to quarantine the current message. + Filters which use this function must include the + SMFIF_QUARANTINE flag in the registered smfiDesc structure. + LIBMILTER: If a milter sets the reply code to "421", the SMTP server + will terminate the SMTP session with that error. + LIBMILTER: Upon filter shutdown, libmilter will not remove a + named socket in the file system if it is running as root. + LIBMILTER: Add new function smfi_progress() which allows the filter + to notify the MTA that an EOM operation is still in progress, + resetting the timeout. + LIBMILTER: Add new function smfi_opensocket() which allows the filter + to attempt to establish the interface socket, and detect + failure to do so before calling smfi_main(). + LIBMILTER: Add new function smfi_setmlreply() which allows the + filter to return a multi-line SMTP reply. + LIBMILTER: Deal with more temporary errors in accept() by ignoring + them instead of stopping after too many occurred. + Suggested by James Carlson of Sun Microsystems. + LIBMILTER: Fix a descriptor leak in the sample program found in + docs/sample.html. Reported by Dmitry Adamushko. + LIBMILTER: The sample program also needs to use SMFIF_ADDRCPT. + Reported by Carl Byington of 510 Software Group. + LIBMILTER: Document smfi_stop() and smfi_setdbg(). Patches + from Bryan Costales. + LIBMILTER: New compile time option SM_CONF_POLL; define this if + poll(2) should be used instead of select(2). + LIBMILTER: New function smfi_insheader() and related protocol + amendments to support header insertion operations. + MAIL.LOCAL: Add support for hashed mail directories, see + mail.local/README. Contributed by Chris Adams of HiWAAY + Informations Services. + MAILSTATS: Display quarantine message counts. + MAKEMAP: Add new flag -D to specify the comment character to use + instead of '#'. + VACATION: Add new flag -j to auto-respond to messages regardless of + whether or not the recipient is listed in the To: or Cc: + headers. + VACATION: Add new flag -R to specify the envelope sender address + for the auto-response message. + New Files: + CACerts + cf/feature/conncontrol.m4 + cf/feature/greet_pause.m4 + cf/feature/mtamark.m4 + cf/feature/ratecontrol.m4 + cf/feature/use_client_ptr.m4 + cf/ostype/unicos.m4 + cf/ostype/unicosmk.m4 + cf/ostype/unicosmp.m4 + contrib/socketmapClient.pl + contrib/socketmapServer.pl + devtools/OS/Darwin.7.0 + devtools/OS/UNICOS-mk + devtools/OS/UNICOS-mp + devtools/Site/site.config.m4.sample + include/sm/os/sm_os_unicos.h + include/sm/os/sm_os_unicosmk.h + include/sm/os/sm_os_unicosmp.h + libmilter/docs/smfi_insheader.html + libmilter/docs/smfi_progress.html + libmilter/docs/smfi_quarantine.html + libmilter/docs/smfi_setdbg.html + libmilter/docs/smfi_setmlreply.html + libmilter/docs/smfi_stop.html + sendmail/ratectrl.c + Deleted Files: + cf/feature/nodns.m4 + contrib/oldbind.compat.c + devtools/OS/CRAYT3E.2.0.x + devtools/OS/CRAYTS.10.0.x + libsm/vsprintf.c + Renamed Files: + devtools/OS/Darwin.7.0 => devtools/OS/Darwin.7.x + 8.12.11/8.12.11 2004/01/18 Use QueueFileMode when opening qf files. This error was a regression in 8.12.10. Problem detected and diagnosed diff --git a/contrib/sendmail/cf/README b/contrib/sendmail/cf/README index ff7057944b75..52985bb33de5 100644 --- a/contrib/sendmail/cf/README +++ b/contrib/sendmail/cf/README @@ -28,6 +28,7 @@ MASQUERADING AND RELAYING USING LDAP FOR ALIASES, MAPS, AND CLASSES LDAP ROUTING ANTI-SPAM CONFIGURATION CONTROL +CONNECTION CONTROL STARTTLS SMTP AUTHENTICATION ADDING NEW MAILERS OR RULESETS @@ -76,7 +77,7 @@ Let's examine a typical .mc file: divert(-1) # - # Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. + # Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -130,8 +131,8 @@ definition appropriate for your environment. These describe the mailers used at the default CS site. The local mailer is always included automatically. Beware: MAILER declarations -should always be at the end of the configuration file. The general -rules are that the order should be: +should only be followed by LOCAL_* sections. The general rules are +that the order should be: VERSIONID OSTYPE @@ -1051,6 +1052,12 @@ local_lmtp Use an LMTP capable local mailer. The argument to this LMTP capable. The path to mail.local is set by the confEBINDIR m4 variable -- making the default LOCAL_MAILER_PATH /usr/libexec/mail.local. + If a different LMTP capable mailer is used, its pathname + can be specified as second parameter and the arguments + passed to it (A=) as third parameter, e.g., + + FEATURE(`local_lmtp', `/usr/local/bin/lmtp', `lmtp') + WARNING: This feature sets LOCAL_MAILER_FLAGS unconditionally, i.e., without respecting any definitions in an OSTYPE setting. @@ -1226,6 +1233,13 @@ delay_checks The rulesets check_mail and check_relay will not be called section. Note: this feature is incompatible to the versions in 8.10 and 8.11. +use_client_ptr If this feature is enabled then check_relay will override + its first argument with $&{client_ptr}. This is useful for + rejections based on the unverified hostname of client, + which turns on the same behavior as in earlier sendmail + versions when delay_checks was not in use. See doc/op/op.* + about check_relay, {client_name}, and {client_ptr}. + dnsbl Turns on rejection of hosts found in an DNS based rejection list. If an argument is provided it is used as the domain in which blocked hosts are listed; otherwise it defaults to @@ -1299,6 +1313,67 @@ enhdnsbl Enhanced version of dnsbl (see above). Further arguments will be logged). +ratecontrol Enable simple ruleset to do connection rate control + checking. This requires entries in access_db of the form + + ClientRate:IP.ADD.RE.SS LIMIT + + The RHS specifies the maximum number of connections + (an integer number) over the time interval defined + by ConnectionRateWindowSize, where 0 means unlimited. + + Take the following example: + + ClientRate:10.1.2.3 4 + ClientRate:127.0.0.1 0 + ClientRate: 10 + + 10.1.2.3 can only make up to 4 connections, the + general limit it 10, and 127.0.0.1 can make an unlimited + number of connections per ConnectionRateWindowSize. + + See also CONNECTION CONTROL. + +conncontrol Enable a simple check of the number of incoming SMTP + connections. This requires entries in access_db of the + form + + ClientConn:IP.ADD.RE.SS LIMIT + + The RHS specifies the maximum number of open connections + (an integer number). + + Take the following example: + + ClientConn:10.1.2.3 4 + ClientConn:127.0.0.1 0 + ClientConn: 10 + + 10.1.2.3 can only have up to 4 open connections, the + general limit it 10, and 127.0.0.1 does not have any + explicit limit. + + See also CONNECTION CONTROL. + +mtamark Experimental support for "Marking Mail Transfer Agents in + Reverse DNS with TXT RRs" (MTAMark), see + draft-stumpf-dns-mtamark-01. Optional arguments are: + + 1. Error message, default: + + 550 Rejected: $&{client_addr} not listed as MTA + + 2. Temporary lookup failures are ignored unless a second + argument is given, which must be either `t' or a full + error message. + + 3. Lookup prefix, default: _perm._smtp._srv. This should + not be changed unless the draft changes it. + + Example: + + FEATURE(`mtamark', `', `t') + lookupdotdomain Look up also .domain in the access map. This allows to match only subdomains. It does not work well with FEATURE(`relay_hosts_only'), because most lookups for @@ -1393,6 +1468,32 @@ queuegroup A simple example how to select a queue group based Note: please read the warning in doc/op/op.me about queue groups and possible queue manipulations. +greet_pause Adds the greet_pause ruleset which enables open proxy + and SMTP slamming protection. The feature can take an + argument specifying the milliseconds to wait: + + FEATURE(`greet_pause', `5000') dnl 5 seconds + + If FEATURE(`access_db') is enabled, an access database + lookup with the GreetPause tag is done using client + hostname, domain, IP address, or subnet to determine the + pause time: + + GreetPause:my.domain 0 + GreetPause:example.com 5000 + GreetPause:10.1.2 2000 + GreetPause:127.0.0.1 0 + + When using FEATURE(`access_db'), the optional + FEATURE(`greet_pause') argument becomes the default if + nothing is found in the access database. A ruleset called + Local_greet_pause can be used for local modifications, e.g., + + LOCAL_RULESETS + SLocal_greet_pause + R$* $: $&{daemon_flags} + R$* a $* $# 0 + +-------+ | HACKS | +-------+ @@ -1461,6 +1562,9 @@ The second example demonstrates that you can use two names on the same line; these are usually aliases for the same host (or are at least in the same company). +The macro LOCAL_UUCP can be used to add rules into the generated +cf file at the place where MAILER(`uucp') inserts its rules. This +should only be used if really necessary. +--------------------+ | USING UUCP MAILERS | @@ -1787,7 +1891,8 @@ declared as follows: (|(sendmailMTACluster=${sendmailMTACluster}) (sendmailMTAHost=$j)) (sendmailMTAKey=%0)) - -v sendmailMTAAliasValue + -v sendmailMTAAliasValue,sendmailMTAAliasSearch:FILTER:sendmailMTAAliasObject,sendmailMTAAliasURL:URL:sendmailMTAAliasObject + NOTE: The macros shown above ${sendmailMTACluster} and $j are not actually used when the binary expands the `ldap:' token as the AliasFile option is @@ -1893,7 +1998,7 @@ For example, FEATURE(`mailertable', `LDAP') would use the map definition: (|(sendmailMTACluster=${sendmailMTACluster}) (sendmailMTAHost=$j)) (sendmailMTAKey=%0)) - -1 -v sendmailMTAMapValue + -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject An example LDAP LDIF entry using this map might be: @@ -1960,7 +2065,7 @@ specification: (sendmailMTAClassName=R) (|(sendmailMTACluster=${sendmailMTACluster}) (sendmailMTAHost=$j))) - -v sendmailMTAClassValue + -v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass NOTE: The macros shown above ${sendmailMTACluster} and $j are not actually used when the binary expands the `@LDAP' token as class declarations are @@ -2053,18 +2158,25 @@ and will not reject addresses not found by the LDAP lookup. However, this behavior can be changed by giving additional arguments to the FEATURE() command: - FEATURE(`ldap_routing', , , , ) + FEATURE(`ldap_routing', , , , + , , ) where is a map definition describing how to lookup an alternative mail host for a particular address; is a map definition describing how to lookup an alternative address for a particular address; the argument, if present and not the word "passthru", dictates that mail should be bounced if neither a mailHost nor mailRoutingAddress -is found; and indicates what actions to take if the address +is found, if set to "sendertoo", the sender will be rejected if not +found in LDAP; and indicates what actions to take if the address contains +detail information -- `strip' tries the lookup with the +detail and if no matches are found, strips the +detail and tries the lookup again; `preserve', does the same as `strip' but if a mailRoutingAddress match is -found, the +detail information is copied to the new address. +found, the +detail information is copied to the new address; the +argument, if present, will prevent the @domain lookup if the full +address is not found in LDAP; the argument, if set to +"tempfail", instructs the rules to give an SMTP 4XX temporary +error if the LDAP server gives the MTA a temporary failure, or if set to +"queue" (the default), the MTA will locally queue the mail. The default map definition is: @@ -2237,12 +2349,11 @@ access map. If an optional argument `domain' (this is the literal word `domain', not a placeholder) is given, the domain portion of the mail sender is also checked to allowing relaying. This option only works together with the tag From: for the LHS of the access -map entries (see below: Finer control...). This feature allows -spammers to abuse your mail server by specifying a return address -that you enabled in your access file. This may be harder to figure -out for spammers, but it should not be used unless necessary. -Instead use SMTP AUTH or STARTTLS to allow relaying for roaming -users. +map entries. This feature allows spammers to abuse your mail server +by specifying a return address that you enabled in your access file. +This may be harder to figure out for spammers, but it should not +be used unless necessary. Instead use SMTP AUTH or STARTTLS to +allow relaying for roaming users. If source routing is used in the recipient address (e.g., @@ -2338,12 +2449,13 @@ The table itself uses e-mail addresses, domain names, and network numbers as keys. Note that IPv6 addresses must be prefaced with "IPv6:". For example, - spammer@aol.com REJECT - cyberspammer.com REJECT - TLD REJECT - 192.168.212 REJECT - IPv6:2002:c0a8:02c7 RELAY - IPv6:2002:c0a8:51d2::23f4 REJECT + From:spammer@aol.com REJECT + From:cyberspammer.com REJECT + Connect:cyberspammer.com REJECT + Connect:TLD REJECT + Connect:192.168.212 REJECT + Connect:IPv6:2002:c0a8:02c7 RELAY + Connect:IPv6:2002:c0a8:51d2::23f4 REJECT would refuse mail from spammer@aol.com, any user from cyberspammer.com (or any host within the cyberspammer.com domain), any host in the entire @@ -2351,6 +2463,41 @@ top level domain TLD, 192.168.212.* network, and the IPv6 address 2002:c0a8:51d2::23f4. It would allow relay for the IPv6 network 2002:c0a8:02c7::/48. +Entries in the access map should be tagged according to their type. +Three tags are available: + + Connect: connection information (${client_addr}, ${client_name}) + From: envelope sender + To: envelope recipient + +Notice: untagged entries are deprecated. + +If the required item is looked up in a map, it will be tried first +with the corresponding tag in front, then (as fallback to enable +backward compatibility) without any tag, unless the specific feature +requires a tag. For example, + + From:spammer@some.dom REJECT + To:friend.domain RELAY + Connect:friend.domain OK + Connect:from.domain RELAY + From:good@another.dom OK + From:another.dom REJECT + +This would deny mails from spammer@some.dom but you could still +send mail to that address even if FEATURE(`blacklist_recipients') +is enabled. Your system will allow relaying to friend.domain, but +not from it (unless enabled by other means). Connections from that +domain will be allowed even if it ends up in one of the DNS based +rejection lists. Relaying is enabled from from.domain but not to +it (since relaying is based on the connection information for +outgoing relaying, the tag Connect: must be used; for incoming +relaying, which is based on the recipient address, To: must be +used). The last two entries allow mails from good@another.dom but +reject mail from all other addresses with another.dom as domain +part. + + The value part of the map can contain: OK Accept mail even if other rules in the running @@ -2377,38 +2524,46 @@ The value part of the map can contain: "any text" is a message to return for the command. The string should be quoted to avoid surprises, e.g., sendmail may remove spaces otherwise. - This type is deprecated, use one the two + This type is deprecated, use one of the two ERROR: entries below instead. ERROR:### any text as above, but useful to mark error messages as such. ERROR:D.S.N:### any text where D.S.N is an RFC 1893 compliant error code and the rest as above. + QUARANTINE:any text + Quarantine the message using the given text as the + quarantining reason. For example: - cyberspammer.com ERROR:"550 We don't accept mail from spammers" - okay.cyberspammer.com OK - sendmail.org RELAY - 128.32 RELAY - IPv6:1:2:3:4:5:6:7 RELAY - [127.0.0.3] OK - [IPv6:1:2:3:4:5:6:7:8] OK + From:cyberspammer.com ERROR:"550 We don't accept mail from spammers" + From:okay.cyberspammer.com OK + Connect:sendmail.org RELAY + To:sendmail.org RELAY + Connect:128.32 RELAY + Connect:128.32.2 SKIP + Connect:IPv6:1:2:3:4:5:6:7 RELAY + Connect:suspicious.example.com QUARANTINE:Mail from suspicious host + Connect:[127.0.0.3] OK + Connect:[IPv6:1:2:3:4:5:6:7:8] OK -would accept mail from okay.cyberspammer.com, but would reject mail from -all other hosts at cyberspammer.com with the indicated message. It would -allow relaying mail from and to any hosts in the sendmail.org domain, and -allow relaying from the 128.32.*.* network and the IPv6 1:2:3:4:5:6:7:* -network. The latter two entries are for checks against ${client_name} if -the IP address doesn't resolve to a hostname (or is considered as "may be -forged"). That is, using square brackets means these are host names, -not network numbers. +would accept mail from okay.cyberspammer.com, but would reject mail +from all other hosts at cyberspammer.com with the indicated message. +It would allow relaying mail from and to any hosts in the sendmail.org +domain, and allow relaying from the IPv6 1:2:3:4:5:6:7:* network +and from the 128.32.*.* network except for the 128.32.2.* network, +which shows how SKIP is useful to exempt subnets/subdomains. The +last two entries are for checks against ${client_name} if the IP +address doesn't resolve to a hostname (or is considered as "may be +forged"). That is, using square brackets means these are host +names, not network numbers. Warning: if you change the RFC 821 compliant error code from the default value of 550, then you should probably also change the RFC 1893 compliant error code to match it. For example, if you use - user@example.com ERROR:450 mailbox full + To:user@example.com ERROR:450 mailbox full the error returned would be "450 5.0.0 mailbox full" which is wrong. Use "ERROR:4.2.2:450 mailbox full" instead. @@ -2427,7 +2582,7 @@ hosts listed in class {R} to be fully qualified host names. You can also use the access database to block sender addresses based on the username portion of the address. For example: - FREE.STEALTH.MAILER@ ERROR:550 Spam not accepted + From:FREE.STEALTH.MAILER@ ERROR:550 Spam not accepted Note that you must include the @ after the username to signify that this database entry is for checking only the username portion of the @@ -2440,24 +2595,24 @@ If you use: then you can add entries to the map for local users, hosts in your domains, or addresses in your domain which should not receive mail: - badlocaluser@ ERROR:550 Mailbox disabled for this username - host.mydomain.com ERROR:550 That host does not accept mail - user@otherhost.mydomain.com ERROR:550 Mailbox disabled for this recipient + To:badlocaluser@ ERROR:550 Mailbox disabled for badlocaluser + To:host.my.TLD ERROR:550 That host does not accept mail + To:user@other.my.TLD ERROR:550 Mailbox disabled for this recipient -This would prevent a recipient of badlocaluser@mydomain.com, any -user at host.mydomain.com, and the single address -user@otherhost.mydomain.com from receiving mail. Please note: a -local username must be now tagged with an @ (this is consistent -with the check of the sender address, and hence it is possible to -distinguish between hostnames and usernames). Enabling this feature -will keep you from sending mails to all addresses that have an -error message or REJECT as value part in the access map. Taking -the example from above: +This would prevent a recipient of badlocaluser in any of the local +domains (class {w}), any user at host.my.TLD, and the single address +user@other.my.TLD from receiving mail. Please note: a local username +must be now tagged with an @ (this is consistent with the check of +the sender address, and hence it is possible to distinguish between +hostnames and usernames). Enabling this feature will keep you from +sending mails to all addresses that have an error message or REJECT +as value part in the access map. Taking the example from above: spammer@aol.com REJECT cyberspammer.com REJECT Mail can't be sent to spammer@aol.com or anyone at cyberspammer.com. +That's why tagged entries should be used. There are several DNS based blacklists, the first of which was the RBL (``Realtime Blackhole List'') run by the MAPS project, @@ -2533,46 +2688,12 @@ regex map: These rules are called with the original arguments of the corresponding check_* ruleset. If the local ruleset returns $#OK, no further checking -is done by the features described above and the mail is accepted. If the -local ruleset resolves to a mailer (such as $#error or $#discard), the -appropriate action is taken. Otherwise, the results of the local -rewriting are ignored. - -Finer control by using tags for the LHS of the access map ---------------------------------------------------------- - -Read this section only if the options listed so far are not sufficient -for your purposes. There is now the option to tag entries in the -access map according to their type. Three tags are available: - - Connect: connection information (${client_addr}, ${client_name}) - From: envelope sender - To: envelope recipient - -If the required item is looked up in a map, it will be tried first -with the corresponding tag in front, then (as fallback to enable -backward compatibility) without any tag, unless the specific feature -requires a tag. For example, - - From:spammer@some.dom REJECT - To:friend.domain RELAY - Connect:friend.domain OK - Connect:from.domain RELAY - From:good@another.dom OK - From:another.dom REJECT - -This would deny mails from spammer@some.dom but you could still -send mail to that address even if FEATURE(`blacklist_recipients') -is enabled. Your system will allow relaying to friend.domain, but -not from it (unless enabled by other means). Connections from that -domain will be allowed even if it ends up in one of the DNS based -rejection lists. Relaying is enabled from from.domain but not to -it (since relaying is based on the connection information for -outgoing relaying, the tag Connect: must be used; for incoming -relaying, which is based on the recipient address, To: must be -used). The last two entries allow mails from good@another.dom but -reject mail from all other addresses with another.dom as domain -part. +is done by the features described above and the mail is accepted. If +the local ruleset resolves to a mailer (such as $#error or $#discard), +the appropriate action is taken. Other results starting with $# are +interpreted by sendmail and may lead to unspecified behavior. Note: do +NOT create a mailer with the name OK. Return values that do not start +with $# are ignored, i.e., normal processing continues. Delay all checks ---------------- @@ -2677,6 +2798,8 @@ to $&{currHeader}. 2. There are no default rulesets coming with this distribution of sendmail. You can either write your own or you can search the WWW for examples, e.g., http://www.digitalanswers.org/check_local/ +3. When using a default ruleset for headers, the name of the header +currently being checked can be found in the $&{hdr_name} macro. After all of the headers are read, the check_eoh ruleset will be called for any final header-related checks. The ruleset is called with the number of @@ -2711,6 +2834,38 @@ probably not be used in production. # Otherwise, reject the mail R$* $#error $: 553 Header Error + ++--------------------+ +| CONNECTION CONTROL | ++--------------------+ + +The features ratecontrol and conncontrol allow to establish connection +limits per client IP address or net. These features can limit the +rate of connections (connections per time unit) or the number of +incoming SMTP connections, respectively. If enabled, appropriate +rulesets are called at the end of check_relay, i.e., after DNS +blacklists and generic access_db operations. The features require +FEATURE(`access_db') to be listed earlier in the mc file. + +Note: FEATURE(`delay_checks') delays those connection control checks +after a recipient address has been received, hence making these +connection control features less useful. To run the checks as early +as possible, specify the parameter `nodelay', e.g., + + FEATURE(`ratecontrol', `nodelay') + +In that case, FEATURE(`delay_checks') has no effect on connection +control (and it must be specified earlier in the mc file). + +An optional second argument `terminate' specifies whether the +rulesets should return the error code 421 which will cause +sendmail to terminate the session with that error if it is +returned from check_relay, i.e., not delayed as explained in +the previous paragraph. Example: + + FEATURE(`ratecontrol', `nodelay', `terminate') + + +----------+ | STARTTLS | +----------+ @@ -2774,6 +2929,7 @@ If it is SUBJECT, the DN of the cert subject is looked up next in the access map using the tag CERTSUBJECT. If the value is RELAY, relaying is allowed. +To make things a bit more flexible (or complicated), the values for ${cert_issuer} and ${cert_subject} can be optionally modified by regular expressions defined in the m4 variables _CERT_REGEX_ISSUER_ and _CERT_REGEX_SUBJECT_, respectively. To avoid problems with those macros in @@ -2818,8 +2974,11 @@ Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org SUBJECT CertSubject:/C=US/ST=California/O=endmail.org/OU=private/CN= DeathStar/Email=deathstar@endmail.org RELAY -Note: line breaks have been inserted after "CN=" for readability, -each tagged entry must be one (long) line in the access map. +Notes: +- line breaks have been inserted after "CN=" for readability, + each tagged entry must be one (long) line in the access map. +- if OpenSSL 0.9.7 or newer is used then the "Email=" part of a DN + is replaced by "emailAddress=". Of course it is also possible to write a simple ruleset that allows relaying for everyone who can present a cert that can be verified, e.g., @@ -2952,7 +3111,7 @@ R$* $: $&{auth_type} R$+ $# OK which checks whether a user has successfully authenticated using -any available mechanism. Depending on the setup of the CYRUS SASL +any available mechanism. Depending on the setup of the Cyrus SASL library, more sophisticated rulesets might be required, e.g., SLocal_check_rcpt @@ -2980,6 +3139,9 @@ If the selected mechanism provides a security layer the number of bits used for the key of the symmetric cipher is stored in the macro ${auth_ssf}. +Providing SMTP AUTH Data when sendmail acts as Client +----------------------------------------------------- + If sendmail acts as client, it needs some information how to authenticate against another MTA. This information can be provided by the ruleset authinfo or by the option DefaultAuthInfo. The @@ -2991,6 +3153,12 @@ only performed if the access map is used; if the authinfo feature is used then only up to three lookups are performed (two exact matches, one default). +Note: If your daemon does client authentication when sending, and +if it uses either PLAIN or LOGIN authentication, then you *must* +prevent ordinary users from seeing verbose output. Do NOT install +sendmail set-user-ID. Use PrivacyOptions to turn off verbose output +("goaway" works for this). + Notice: the default configuration file causes the option DefaultAuthInfo to fail since the ruleset authinfo is in the .cf file. If you really want to use DefaultAuthInfo (it is deprecated) then you have to @@ -3341,12 +3509,17 @@ off, do so. +--------------------------------+ There are a large number of configuration options that don't normally -need to be changed. However, if you feel you need to tweak them, you -can define the following M4 variables. This list is shown in four -columns: the name you define, the default value for that definition, -the option or macro that is affected (either Ox for an option or Dx -for a macro), and a brief description. Greater detail of the semantics -can be found in the Installation and Operations Guide. +need to be changed. However, if you feel you need to tweak them, +you can define the following M4 variables. Note that some of these +variables require formats that are defined in RFC 2821 or RFC 2822. +Before changing them you need to make sure you do not violate those +(and other relevant) RFCs. + +This list is shown in four columns: the name you define, the default +value for that definition, the option or macro that is affected +(either Ox for an option or Dx for a macro), and a brief description. +Greater detail of the semantics can be found in the Installation +and Operations Guide. Some options are likely to be deprecated in future versions -- that is, the option is only included to provide back-compatibility. These are @@ -3358,7 +3531,7 @@ be ``double quoted, like this phrase'' to avoid having the comma confuse things. This is common for alias file definitions and for the read timeout. -M4 Variable Name Configuration Description & [Default] +M4 Variable Name Configuration [Default] & Description ================ ============= ======================= confMAILER_NAME $n macro [MAILER-DAEMON] The sender name used for internally generated outgoing @@ -3387,6 +3560,9 @@ confRECEIVED_HEADER Received: The format of the Received: header in messages passed through this host. It is unwise to try to change this. +confMESSAGEID_HEADER Message-Id: [<$t.$i@$j>] The format of an + internally generated Message-Id: + header. confCW_FILE Fw class [/etc/mail/local-host-names] Name of file used to get the local additions to class {w} (local host @@ -3590,6 +3766,10 @@ confTO_QUEUERETURN_NONURGENT Timeout.queuereturn.non-urgent [undefined] As above, for non-urgent (low) priority messages. +confTO_QUEUERETURN_DSN + Timeout.queuereturn.dsn + [undefined] As above, for delivery + status notification messages. confTO_QUEUEWARN Timeout.queuewarn [4h] The timeout before a warning message is sent to the sender telling @@ -3605,6 +3785,10 @@ confTO_QUEUEWARN_NONURGENT Timeout.queuewarn.non-urgent [undefined] As above, for non-urgent (low) priority messages. +confTO_QUEUEWARN_DSN + Timeout.queuewarn.dsn + [undefined] As above, for delivery + status notification messages. confTO_HOSTSTATUS Timeout.hoststatus [30m] How long information about host statuses will be maintained before it @@ -3653,6 +3837,8 @@ confUSERDB_SPEC UserDatabaseSpec [undefined] User database specification. confFALLBACK_MX FallbackMXhost [undefined] Fallback MX host. +confFALLBACK_SMARTHOST FallbackSmartHost + [undefined] Fallback smart host. confTRY_NULL_MX_LIST TryNullMXList [False] If this host is the best MX for a host and other arrangements haven't been made, try connecting @@ -3670,6 +3856,8 @@ confREFUSE_LA RefuseLA [varies] Load average at which numproc) where numproc is the number of processors online (if that can be determined). +confREJECT_LOG_INTERVAL RejectLogInterval [3h] Log interval when + refusing connections for this long. confDELAY_LA DelayLA [0] Load average at which sendmail will sleep for one second on most SMTP commands and before accepting @@ -3688,7 +3876,6 @@ confMAX_HEADERS_LENGTH MaxHeadersLength confMAX_MIME_HEADER_LENGTH MaxMimeHeaderLength [undefined] Maximum length of certain MIME header field values. - If not set, sendmail uses 2048/1024. confCONNECTION_RATE_THROTTLE ConnectionRateThrottle [undefined] The maximum number of connections permitted per second per @@ -3696,6 +3883,10 @@ confCONNECTION_RATE_THROTTLE ConnectionRateThrottle are accepted, further connections will be delayed. If not set or <= 0, there is no limit. +confCONNECTION_RATE_WINDOW_SIZE ConnectionRateWindowSize + [60s] Define the length of the + interval for which the number of + incoming connections is maintained. confWORK_RECIPIENT_FACTOR RecipientFactor [30000] Cost of each recipient. confSEPARATE_PROC ForkEachJob [False] Run all deliveries in a @@ -3768,7 +3959,7 @@ confMAX_QUEUE_CHILDREN MaxQueueChildren of concurrent queue runners active. This is to keep system resources used within a reasonable limit. Relates to - Queue Groups and ForkAllJobs. + Queue Groups and ForkEachJob. confMAX_RUNNERS_PER_QUEUE MaxRunnersPerQueue [1] Only active when MaxQueueChildren defined. Controls the maximum number @@ -3909,7 +4100,11 @@ confAUTH_MECHANISMS AuthMechanisms [GSSAPI KERBEROS_V4 DIGEST-MD5 authentication mechanisms will be the intersection of this list and the list of available mechanisms as determined - by the CYRUS SASL library. + by the Cyrus SASL library. +confAUTH_REALM AuthRealm [undefined] The authentication realm + that is passed to the Cyrus SASL + library. If no realm is specified, + $j is used. confDEF_AUTH_INFO DefaultAuthInfo [undefined] Name of file that contains authentication information for outgoing connections. This file must @@ -3973,6 +4168,10 @@ confCLIENT_CERT ClientCertFile [undefined] File containing the confCLIENT_KEY ClientKeyFile [undefined] File containing the private key belonging to the client cert. +confCRL CRLFile [undefined] File containing certificate + revocation status, useful for X.509v3 + authentication. Note that CRL requires + at least OpenSSL version 0.9.7. confDH_PARAMETERS DHParameters [undefined] File containing the DH parameters. confRAND_FILE RandFile [undefined] File containing random @@ -3992,6 +4191,10 @@ confUSE_MSP UseMSP [false] Use as mail submission program, see sendmail/SECURITY. confDELIVER_BY_MIN DeliverByMin [0] Minimum time for Deliver By SMTP Service Extension (RFC 2852). +confREQUIRES_DIR_FSYNC RequiresDirfsync [true] RequiresDirfsync can + be used to turn off the compile time + flag REQUIRES_DIR_FSYNC at runtime. + See sendmail/README for details. confSHARED_MEMORY_KEY SharedMemoryKey [0] Key for shared memory. confFAST_SPLIT FastSplit [1] If set to a value greater than zero, the initial MX lookups on @@ -4035,6 +4238,9 @@ confMILTER_MACROS_ENVRCPT Milter.macros.envrcpt [{rcpt_mailer}, {rcpt_host}, {rcpt_addr}] Macros to transmit to milters after RCPT TO command. +confMILTER_MACROS_EOM Milter.macros.eom + [{msg_id}] Macros to transmit to + milters after DATA command. See also the description of OSTYPE for some parameters that can be @@ -4177,6 +4383,12 @@ adding the following to your sendmail.mc file: R$* $: $&{auth_authen} Rsmmsp $# OK +Note: the authentication data can leak to local users who invoke +the MSP with debug options or even with -v. For that reason either +an authentication mechanism that does not show the password in the +AUTH dialogue (e.g., DIGEST-MD5) or a different authentication +method like STARTTLS should be used. + feature/msp.m4 defines almost all settings for the MSP. Most of those should not be changed at all. Some of the features and options can be overridden if really necessary. It is a bit tricky to do @@ -4375,4 +4587,4 @@ M4 DIVERSIONS 8 DNS based blacklists 9 special local rulesets (1 and 2) -$Revision: 8.623.2.27 $, Last updated $Date: 2004/01/11 17:58:25 $ +$Revision: 8.691 $, Last updated $Date: 2004/07/19 17:47:34 $ diff --git a/contrib/sendmail/cf/cf/Makefile b/contrib/sendmail/cf/cf/Makefile index 9a69a1805af0..04d5eeeec137 100644 --- a/contrib/sendmail/cf/cf/Makefile +++ b/contrib/sendmail/cf/cf/Makefile @@ -1,7 +1,7 @@ # # Makefile for configuration files. # -# $Id: Makefile,v 8.56 2001/12/13 23:56:37 gshapiro Exp $ +# $Id: Makefile,v 8.58 2003/10/20 22:01:00 ca Exp $ # # @@ -19,6 +19,8 @@ SUBMIT= submit MAILDIR=/etc/mail M4= m4 CFDIR= .. +SED= sed +ECHO= echo CHMOD= chmod ROMODE= 444 RM= rm -f @@ -35,6 +37,8 @@ CFMODE=0444 .mc.cf: $(RM) $@ $(M4) ${CFDIR}/m4/cf.m4 $*.mc > $@ || ( $(RM) $@ && exit 1 ) + $(ECHO) "### $*.mc ###" >>$@ + $(SED) -e 's/^/# /' $*.mc >>$@ $(CHMOD) $(ROMODE) $@ GENERIC=generic-bsd4.4.cf generic-hpux9.cf generic-hpux10.cf \ @@ -99,6 +103,7 @@ M4FILES=\ ${CFDIR}/feature/bestmx_is_local.m4 \ ${CFDIR}/feature/bitdomain.m4 \ ${CFDIR}/feature/blacklist_recipients.m4 \ + ${CFDIR}/feature/conncontrol.m4 \ ${CFDIR}/feature/dnsbl.m4 \ ${CFDIR}/feature/domaintable.m4 \ ${CFDIR}/feature/generics_entire_domain.m4 \ @@ -113,12 +118,12 @@ M4FILES=\ ${CFDIR}/feature/masquerade_envelope.m4 \ ${CFDIR}/feature/no_default_msa.m4 \ ${CFDIR}/feature/nocanonify.m4 \ - ${CFDIR}/feature/nodns.m4 \ ${CFDIR}/feature/notsticky.m4 \ ${CFDIR}/feature/nouucp.m4 \ ${CFDIR}/feature/nullclient.m4 \ ${CFDIR}/feature/promiscuous_relay.m4 \ ${CFDIR}/feature/redirect.m4 \ + ${CFDIR}/feature/ratecontrol.m4 \ ${CFDIR}/feature/relay_based_on_MX.m4 \ ${CFDIR}/feature/relay_entire_domain.m4 \ ${CFDIR}/feature/relay_hosts_only.m4 \ diff --git a/contrib/sendmail/cf/cf/knecht.mc b/contrib/sendmail/cf/cf/knecht.mc index 6c370fdc7fa1..98dbef9eea54 100644 --- a/contrib/sendmail/cf/cf/knecht.mc +++ b/contrib/sendmail/cf/cf/knecht.mc @@ -19,16 +19,15 @@ divert(-1) # divert(0) -VERSIONID(`$Id: knecht.mc,v 8.55 2001/08/01 22:20:40 eric Exp $') +VERSIONID(`$Id: knecht.mc,v 8.58 2004/01/28 00:54:41 eric Exp $') OSTYPE(bsd4.4) DOMAIN(generic) -define(`ALIAS_FILE', ``/etc/mail/aliases, /var/listmanager/aliases'') +define(`ALIAS_FILE', ``/etc/mail/aliases, /etc/mail/lists/sendmail.org/aliases, /var/listmanager/aliases'') define(`confFORWARD_PATH', `$z/.forward.$w:$z/.forward+$h:$z/.forward') define(`confDEF_USER_ID', `mailnull') define(`confHOST_STATUS_DIRECTORY', `.hoststat') define(`confTO_ICONNECT', `10s') -define(`confCOPY_ERRORS_TO', `Postmaster') define(`confTO_QUEUEWARN', `8h') define(`confMIN_QUEUE_AGE', `27m') define(`confTRUSTED_USERS', ``www listmgr'') @@ -42,9 +41,12 @@ define(`confSERVER_KEY', `CERT_DIR/MYkey.pem') define(`confCLIENT_CERT', `CERT_DIR/MYcert.pem') define(`confCLIENT_KEY', `CERT_DIR/MYkey.pem') +define(`CYRUS_MAILER_PATH', `/usr/local/cyrus/bin/deliver') + FEATURE(access_db) FEATURE(local_lmtp) FEATURE(virtusertable) +FEATURE(mailertable) FEATURE(`nocanonify', `canonify_hosts') CANONIFY_DOMAIN(`sendmail.org') @@ -61,8 +63,17 @@ define(`confFAST_SPLIT', `10') dnl # 10 runners, split into at most 15 recipients per envelope QUEUE_GROUP(`mqueue', `P=/var/spool/mqueue, R=5, r=15, F=f') + +dnl # enable spam assassin +INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m') + MAILER(local) MAILER(smtp) +MAILER(cyrus) + +LOCAL_RULE_0 +Rcyrus.$+ + $+ < @ $=w . > $#cyrus $@ $2 $: $1 +Rcyrus.$+ < @ $=w . > $#cyrus $: $1 LOCAL_CONFIG # @@ -73,6 +84,7 @@ LOCAL_CONFIG Kcheckaddress regex -a@MATCH ^([0-9]+<@(aol|msn)\.com|[0-9][^<]*<@juno\.com)\.?> +###################################################################### # # Names that won't be allowed in a To: line (local-part and domains) # @@ -86,18 +98,42 @@ SCheckTo R$={RejectToLocalparts}@$* $#error $: "553 Header error" R$*@$={RejectToDomains} $#error $: "553 Header error" +###################################################################### HMessage-Id: $>CheckMessageId SCheckMessageId +# Record the presence of the header +R$* $: $(storage {MessageIdCheck} $@ OK $) $1 + +# validate syntax R< $+ @ $+ > $@ OK R$* $#error $: "554 Header error" + +###################################################################### HReceived: $>CheckReceived SCheckReceived +# Record the presence of any Received header +R$* $: $(storage {ReceivedCheck} $@ OK $) $1 + +# check syntax R$* ......................................................... $* $#error $: "554 Header error" +###################################################################### +# +# Reject advertising subjects +# + +Kadvsubj regex -b -a@MATCH ±?°í +HSubject: $>+CheckSubject +SCheckSubject +R$* $: $(advsubj $&{currHeader} $: OK $) +ROK $@ OK +R$* $#error $@ 5.7.0 $: 550 5.7.0 spam rejected. + +###################################################################### # # Reject certain senders # Regex match to catch things in quotes @@ -159,13 +195,65 @@ LOCAL_RULESETS KSirCamWormMarker regex -f -aSUSPECT multipart/mixed;boundary=----.+_Outlook_Express_message_boundary HContent-Type: $>CheckContentType +###################################################################### SCheckContentType R$+ $: $(SirCamWormMarker $1 $) RSUSPECT $#error $: "553 Possible virus, see http://www.symantec.com/avcenter/venc/data/w32.sircam.worm@mm.html" HContent-Disposition: $>CheckContentDisposition +###################################################################### SCheckContentDisposition R$- $@ OK R$- ; $+ $@ OK R$* $#error $: "553 Illegal Content-Disposition" + + +# +# Sobig.F +# + +LOCAL_CONFIG +Kstorage macro + +LOCAL_RULESETS +###################################################################### +### check for the existance of the X-MailScanner Header +HX-MailScanner: $>+CheckXMSc +D{SobigFPat}Found to be clean +D{SobigFMsg}This message may contain the Sobig.F virus. + +SCheckXMSc +### if it exists, and the defined value is set, record the presence +R${SobigFPat} $* $: $(storage {SobigFCheck} $@ SobigF $) $1 +R$* $@ OK + +###################################################################### +Scheck_eoh +# Check if a Message-Id was found +R$* $: < $&{MessageIdCheck} > + +# If Message-Id was found clear the X-MailScanner store and return with OK +R< $+ > $@ OK $>ClearStorage + +# Are we the first Hop? +R$* $: < $&{ReceivedCheck} > +R< $+ > $@ OK $>ClearStorage + +# no Message-Id->check X-Mailscanner presence, too +R$* $: < $&{SobigFCheck} > + +# clear store +R$* $: $>ClearStorage $1 +# no msgid, first hop and Header found? -> reject the message +R < SobigF > $#error $: 553 ${SobigFMsg} + +# No Header! Fine, take the message +R$* $@ OK + +###################################################################### +SClearStorage +R$* $: $(storage {SobigFCheck} $) $1 +R$* $: $(storage {ReceivedCheck} $) $1 +R$* $: $(storage {MessageIdCheck} $) $1 +R$* $@ $1 diff --git a/contrib/sendmail/cf/cf/submit.cf b/contrib/sendmail/cf/cf/submit.cf index cb9f8c708d02..ee9ae0936d36 100644 --- a/contrib/sendmail/cf/cf/submit.cf +++ b/contrib/sendmail/cf/cf/submit.cf @@ -1,5 +1,5 @@ # -# Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983, 1995 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -16,6 +16,9 @@ ##### ##### SENDMAIL CONFIGURATION FILE ##### +##### built by ca@wiz.smi.sendmail.com on Fri Jul 30 11:06:26 PDT 2004 +##### in /extra/home/ca/sm-8.13.1/OpenSource/sendmail-8.13.1/cf/cf +##### using ../ as configuration include directory ##### ###################################################################### ##### @@ -24,15 +27,15 @@ ###################################################################### ###################################################################### -##### $Id: cfhead.m4,v 8.108.2.6 2003/12/05 02:26:47 ca Exp $ ##### +##### $Id: cfhead.m4,v 8.116 2004/01/28 22:02:22 ca Exp $ ##### ##### $Id: cf.m4,v 8.32 1999/02/07 07:26:14 gshapiro Exp $ ##### -##### $Id: submit.mc,v 8.6.2.7 2003/09/10 22:11:56 ca Exp $ ##### -##### $Id: msp.m4,v 1.32 2002/03/26 22:02:03 ca Exp $ ##### +##### $Id: submit.mc,v 8.13 2003/09/10 22:12:48 ca Exp $ ##### +##### $Id: msp.m4,v 1.33 2004/02/09 22:32:38 ca Exp $ ##### ##### $Id: no_default_msa.m4,v 8.2 2001/02/14 05:03:22 gshapiro Exp $ ##### -##### $Id: proto.m4,v 8.649.2.30 2004/01/11 17:54:06 ca Exp $ ##### +##### $Id: proto.m4,v 8.710 2004/07/27 17:32:48 ca Exp $ ##### # level 10 config file format V10/Berkeley @@ -111,7 +114,7 @@ D{MTAHost}[127.0.0.1] # Configuration version number -DZ8.12.11/Submit +DZ8.13.1/Submit ############### @@ -134,7 +137,7 @@ O AliasWait=10 O MinFreeBlocks=100 # maximum message size -#O MaxMessageSize=1000000 +#O MaxMessageSize=0 # substitution for space (blank) characters O BlankSub=. @@ -277,19 +280,19 @@ O QueueDirectory=/var/spool/clientmqueue #O Timeout.quit=2m #O Timeout.misc=2m #O Timeout.command=1h -O Timeout.ident=0 +#O Timeout.ident=5s #O Timeout.fileopen=60s #O Timeout.control=2m O Timeout.queuereturn=5d #O Timeout.queuereturn.normal=5d #O Timeout.queuereturn.urgent=2d #O Timeout.queuereturn.non-urgent=7d - +#O Timeout.queuereturn.dsn=5d O Timeout.queuewarn=4h #O Timeout.queuewarn.normal=4h #O Timeout.queuewarn.urgent=1h #O Timeout.queuewarn.non-urgent=12h - +#O Timeout.queuewarn.dsn=4h #O Timeout.hoststatus=30m #O Timeout.resolver.retrans=5s #O Timeout.resolver.retrans.first=5s @@ -328,6 +331,9 @@ O TimeZoneSpec= # fallback MX host #O FallbackMXhost=fall.back.host.net +# fallback smart host +#O FallbackSmartHost=fall.back.host.net + # if we are the best MX host for a site, try it directly instead of config err #O TryNullMXList=False @@ -337,6 +343,9 @@ O TimeZoneSpec= # load average at which we refuse connections #O RefuseLA=12 +# log interval when refusing connections for this long +#O RejectLogInterval=3h + # load average at which we delay connections; 0 means no limit #O DelayLA=0 @@ -346,6 +355,9 @@ O TimeZoneSpec= # maximum number of new connections per second #O ConnectionRateThrottle=0 +# Width of the window +#O ConnectionRateWindowSize=60s + # work recipient factor #O RecipientFactor=30000 @@ -418,11 +430,11 @@ O DontInitGroups=True O RunAsUser=smmsp # maximum number of recipients per SMTP envelope -#O MaxRecipientsPerMessage=100 +#O MaxRecipientsPerMessage=0 # limit the rate recipients per SMTP envelope are accepted # once the threshold number of recipients have been rejected -#O BadRcptThrottle=20 +#O BadRcptThrottle=0 # shall we get local names from our installed interfaces? O DontProbeInterfaces=True @@ -440,7 +452,7 @@ O TrustedUser=smmsp #O ControlSocketName=/var/spool/mqueue/.control # Maximum MIME header length to protect MUAs -#O MaxMimeHeaderLength=2048/1024 +#O MaxMimeHeaderLength=0/0 # Maximum length of the sum of all headers #O MaxHeadersLength=32768 @@ -463,9 +475,15 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid # lookup type to find information about local mailboxes #O MailboxDatabase=pw +# override compile time flag REQUIRES_DIR_FSYNC +#O RequiresDirfsync=true + # list of authentication mechanisms #O AuthMechanisms=EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5 +# Authentication realm +#O AuthRealm + # default authentication information for outgoing connections #O DefaultAuthInfo=/etc/mail/default-auth-info @@ -494,6 +512,8 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid #O ClientCertFile # Client private key #O ClientKeyFile +# File containing certificate revocation lists +#O CRLFile # DHParameters (only required if DSA/DH is used) #O DHParameters # Random data source (required for systems without /dev/urandom under OpenSSL) @@ -944,6 +964,8 @@ R<$+> $* $@ $2 ### check_relay -- check hostname/address on SMTP startup ###################################################################### + + SLocal_check_relay Scheck_relay R$* $: $1 $| $>"Local_check_relay" $1 @@ -1086,6 +1108,7 @@ R$+ < @ $* $=R > $@ RELAY + # check for local user (i.e. unqualified address) R$* $: $1 R $* < @ $+ > $: $1 < @ $2 > @@ -1111,7 +1134,7 @@ R$=w $@ RELAY ... and see if it is local # check client name: first: did it resolve? R$* $: < $&{client_resolve} > -R $#TEMP $@ 4.7.1 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr} +R $#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr} R $#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name} R $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name} R$* $: <@> $&{client_name} @@ -1151,6 +1174,28 @@ R$* $#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{au ###################################################################### SLocal_Relay_Auth +###################################################################### +### srv_features: which features to offer to a client? +### (done in server) +###################################################################### +Ssrv_features + + +###################################################################### +### try_tls: try to use STARTTLS? +### (done in client) +###################################################################### +Stry_tls + + +###################################################################### +### tls_rcpt: is connection with server "good" enough? +### (done in client, per recipient) +### +### Parameters: +### $1: recipient +###################################################################### +Stls_rcpt ###################################################################### @@ -1205,6 +1250,10 @@ Sauthinfo + + + + SLocal_localaddr R$+ $: $>ParseRecipient $1 R$* < @ $+ > $* $#relay $@ ${MTAHost} $: $1 < @ $2 > $3 @@ -1374,3 +1423,30 @@ Mrelay, P=[IPC], F=mDFMuXa8k, S=EnvFromSMTP/HdrFromSMTP, R=MasqSMTP, E=\r\n, L= T=DNS/RFC822/SMTP, A=TCP $h +### submit.mc ### +# divert(-1) +# # +# # Copyright (c) 2001-2003 Sendmail, 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. +# # +# # +# +# # +# # This is the prototype file for a set-group-ID sm-msp sendmail that +# # acts as a initial mail submission program. +# # +# +# divert(0)dnl +# VERSIONID(`$Id: submit.mc,v 8.13 2003/09/10 22:12:48 ca Exp $') +# define(`confCF_VERSION', `Submit')dnl +# define(`__OSTYPE__',`')dnl dirty hack to keep proto.m4 from complaining +# define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet +# define(`confTIME_ZONE', `USE_TZ')dnl +# define(`confDONT_INIT_GROUPS', `True')dnl +# dnl +# dnl If you use IPv6 only, change [127.0.0.1] to [IPv6:::1] +# FEATURE(`msp', `[127.0.0.1]')dnl diff --git a/contrib/sendmail/cf/cf/submit.mc b/contrib/sendmail/cf/cf/submit.mc index 26393c381969..610bbeff32a4 100644 --- a/contrib/sendmail/cf/cf/submit.mc +++ b/contrib/sendmail/cf/cf/submit.mc @@ -15,7 +15,7 @@ divert(-1) # divert(0)dnl -VERSIONID(`$Id: submit.mc,v 8.6.2.7 2003/09/10 22:11:56 ca Exp $') +VERSIONID(`$Id: submit.mc,v 8.13 2003/09/10 22:12:48 ca Exp $') define(`confCF_VERSION', `Submit')dnl define(`__OSTYPE__',`')dnl dirty hack to keep proto.m4 from complaining define(`_USE_DECNET_SYNTAX_', `1')dnl support DECnet diff --git a/contrib/sendmail/cf/feature/access_db.m4 b/contrib/sendmail/cf/feature/access_db.m4 index 796cc13219d2..5488a452745e 100644 --- a/contrib/sendmail/cf/feature/access_db.m4 +++ b/contrib/sendmail/cf/feature/access_db.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2002, 2004 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: access_db.m4,v 8.24 2002/03/06 21:50:25 ca Exp $') +VERSIONID(`$Id: access_db.m4,v 8.26 2004/06/24 18:10:02 ca Exp $') divert(-1) define(`_ACCESS_TABLE_', `') @@ -33,9 +33,12 @@ ifelse(defn(`_ARG_'), `', `', ') ') ') +ifdef(`_GREET_PAUSE_', + `errprint(`*** WARNING: FEATURE(`greet_pause') before FEATURE(`access_db') + greet_pause will not use access_db!')') LOCAL_CONFIG # Access list database (for spam stomping) Kaccess ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE -T`'_ATMPF_ MAIL_SETTINGS_DIR`access', - defn(`_ARG_'), `LDAP', `ldap -T`'_ATMPF_ -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=access)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -T`'_ATMPF_ -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=access)(sendmailMTAKey=%0))', defn(`_NARG_'), `', `_ARG_', `_NARG_') diff --git a/contrib/sendmail/cf/feature/authinfo.m4 b/contrib/sendmail/cf/feature/authinfo.m4 index 3533d3067946..99dd6e9e2361 100644 --- a/contrib/sendmail/cf/feature/authinfo.m4 +++ b/contrib/sendmail/cf/feature/authinfo.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: authinfo.m4,v 1.7 2001/03/16 00:51:25 gshapiro Exp $') +VERSIONID(`$Id: authinfo.m4,v 1.9 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_AUTHINFO_TABLE_', `') @@ -18,5 +18,5 @@ define(`_AUTHINFO_TABLE_', `') LOCAL_CONFIG # authinfo list database: contains info for authentication as client Kauthinfo ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`authinfo', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=authinfo)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=authinfo)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/feature/bitdomain.m4 b/contrib/sendmail/cf/feature/bitdomain.m4 index 3232be80d316..2ff3fa6eecd0 100644 --- a/contrib/sendmail/cf/feature/bitdomain.m4 +++ b/contrib/sendmail/cf/feature/bitdomain.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: bitdomain.m4,v 8.28 2001/03/16 00:51:25 gshapiro Exp $') +VERSIONID(`$Id: bitdomain.m4,v 8.30 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_BITDOMAIN_TABLE_', `') @@ -21,5 +21,5 @@ define(`_BITDOMAIN_TABLE_', `') LOCAL_CONFIG # BITNET mapping table Kbitdomain ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`bitdomain', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=bitdomain)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=bitdomain)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/feature/conncontrol.m4 b/contrib/sendmail/cf/feature/conncontrol.m4 new file mode 100644 index 000000000000..87c23b0fd548 --- /dev/null +++ b/contrib/sendmail/cf/feature/conncontrol.m4 @@ -0,0 +1,36 @@ +divert(-1) +# +# Copyright (c) 2003, 2004 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Id: conncontrol.m4,v 1.4 2004/02/19 21:31:47 ca Exp $') + +divert(-1) +ifdef(`_ACCESS_TABLE_', ` + define(`_CONN_CONTROL_', `1') + ifelse(defn(`_ARG_'), `', `', + strcasecmp(defn(`_ARG_'), `nodelay'), `1', + `ifdef(`_DELAY_CHECKS_', + ` + define(`_CONN_CONTROL_IMMEDIATE_', `1') + define(`_CONTROL_IMMEDIATE_', `1') + ', + `errprint(`*** ERROR: FEATURE(`conncontrol', `nodelay') requires FEATURE(`delay_checks')')' + )', + `errprint(`*** ERROR: unknown parameter '"defn(`_ARG_')"` for FEATURE(`conncontrol')')') + define(`_FFR_SRCHLIST_A', `1') + ifelse(len(X`'_ARG2_), `1', `', + _ARG2_, `terminate', `define(`_CONN_CONTROL_REPLY', `421')', + `errprint(`*** ERROR: FEATURE(`conncontrol'): unknown argument '"_ARG2_" +)' + ) + ', `errprint(`*** ERROR: FEATURE(`conncontrol') requires FEATURE(`access_db') +')') +ifdef(`_CONN_CONTROL_REPLY',,`define(`_CONN_CONTROL_REPLY', `452')') diff --git a/contrib/sendmail/cf/feature/dnsbl.m4 b/contrib/sendmail/cf/feature/dnsbl.m4 index 7389646bec1a..c560586cf460 100644 --- a/contrib/sendmail/cf/feature/dnsbl.m4 +++ b/contrib/sendmail/cf/feature/dnsbl.m4 @@ -9,11 +9,10 @@ divert(-1) # # -dnl 8.13: ifdef(`DNSBL_MAP', `', `define(`DNSBL_MAP', `dns -R A')') -ifdef(`DNSBL_MAP', `', `define(`DNSBL_MAP', `host')') +ifdef(`DNSBL_MAP', `', `define(`DNSBL_MAP', `dns -R A')') divert(0) ifdef(`_DNSBL_R_',`dnl',`dnl -VERSIONID(`$Id: dnsbl.m4,v 8.28 2002/05/19 21:22:40 gshapiro Exp $') +VERSIONID(`$Id: dnsbl.m4,v 8.29 2002/08/09 21:02:08 ca Exp $') define(`_DNSBL_R_',`') LOCAL_CONFIG # map for DNS based blacklist lookups diff --git a/contrib/sendmail/cf/feature/domaintable.m4 b/contrib/sendmail/cf/feature/domaintable.m4 index b04b4971b863..fadf816ca0ff 100644 --- a/contrib/sendmail/cf/feature/domaintable.m4 +++ b/contrib/sendmail/cf/feature/domaintable.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: domaintable.m4,v 8.22 2001/03/16 00:51:25 gshapiro Exp $') +VERSIONID(`$Id: domaintable.m4,v 8.24 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_DOMAIN_TABLE_', `') @@ -21,5 +21,5 @@ define(`_DOMAIN_TABLE_', `') LOCAL_CONFIG # Domain table (adding domains) Kdomaintable ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`domaintable', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=domain)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=domain)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/feature/genericstable.m4 b/contrib/sendmail/cf/feature/genericstable.m4 index c20022a91850..dfdfeac86272 100644 --- a/contrib/sendmail/cf/feature/genericstable.m4 +++ b/contrib/sendmail/cf/feature/genericstable.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: genericstable.m4,v 8.21 2001/03/16 00:51:26 gshapiro Exp $') +VERSIONID(`$Id: genericstable.m4,v 8.23 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_GENERICS_TABLE_', `') @@ -21,5 +21,5 @@ define(`_GENERICS_TABLE_', `') LOCAL_CONFIG # Generics table (mapping outgoing addresses) Kgenerics ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`genericstable', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=generics)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=generics)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/feature/greet_pause.m4 b/contrib/sendmail/cf/feature/greet_pause.m4 new file mode 100644 index 000000000000..1dddb58e5054 --- /dev/null +++ b/contrib/sendmail/cf/feature/greet_pause.m4 @@ -0,0 +1,44 @@ +divert(-1) +# +# Copyright (c) 2004 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Id: greet_pause.m4,v 1.4 2004/07/06 20:49:51 ca Exp $') +divert(-1) + +ifelse(len(X`'_ARG_),`1',`ifdef(`_ACCESS_TABLE_', `', + `errprint(`*** ERROR: FEATURE(`greet_pause') requires FEATURE(`access_db') +')')') + +define(`_GREET_PAUSE_', `') + +LOCAL_RULESETS +###################################################################### +### greet_pause: lookup pause time before 220 greeting +### +### Parameters: +### $1: {client_name} +### $2: {client_addr} +###################################################################### +SLocal_greet_pause +Sgreet_pause +R$* $: <$1> $| $>"Local_greet_pause" $1 +R<$*> $| $#$* $#$2 +R<$*> $| $* $: $1 +ifdef(`_ACCESS_TABLE_', `dnl +R$+ $| $+ $: $>D < $1 > < $2 > +R $| $+ $: $>A < $1 > <> empty client_name +R <$+> $: $>A < $1 > <> no: another lookup +ifelse(len(X`'_ARG_),`1', +`R <$*> $@', +`R <$*> $# _ARG_') +R<$* > <$*> $@ +R<$+> <$*> $# $1',`dnl +R$* $# _ARG_') diff --git a/contrib/sendmail/cf/feature/ldap_routing.m4 b/contrib/sendmail/cf/feature/ldap_routing.m4 index 72a6e2643da7..ad7f142aafc5 100644 --- a/contrib/sendmail/cf/feature/ldap_routing.m4 +++ b/contrib/sendmail/cf/feature/ldap_routing.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. +# Copyright (c) 1999-2002, 2004 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -10,24 +10,31 @@ divert(-1) # divert(0) -VERSIONID(`$Id: ldap_routing.m4,v 8.10 2002/03/27 22:17:43 ca Exp $') +VERSIONID(`$Id: ldap_routing.m4,v 8.14 2004/02/18 02:45:11 gshapiro Exp $') divert(-1) # Check first two arguments. If they aren't set, may need to warn in proto.m4 ifelse(len(X`'_ARG1_), `1', `define(`_LDAP_ROUTING_WARN_', `yes')') ifelse(len(X`'_ARG2_), `1', `define(`_LDAP_ROUTING_WARN_', `yes')') +ifelse(len(X`'_ARG5_), `1', `', `define(`_LDAP_ROUTE_NODOMAIN_', `yes')') # Check for third argument to indicate how to deal with non-existant # LDAP records ifelse(len(X`'_ARG3_), `1', `define(`_LDAP_ROUTING_', `_PASS_THROUGH_')', _ARG3_, `passthru', `define(`_LDAP_ROUTING_', `_PASS_THROUGH_')', + _ARG3_, `sendertoo', `define(`_LDAP_ROUTING_', `_MUST_EXIST_')define(`_LDAP_SENDER_MUST_EXIST_')', `define(`_LDAP_ROUTING_', `_MUST_EXIST_')') -# Check for fouth argument to indicate how to deal with +detail info +# Check for fourth argument to indicate how to deal with +detail info ifelse(len(X`'_ARG4_), `1', `', _ARG4_, `strip', `define(`_LDAP_ROUTE_DETAIL_', `_STRIP_')', _ARG4_, `preserve', `define(`_LDAP_ROUTE_DETAIL_', `_PRESERVE_')') +# Check for sixth argument to indicate how to deal with tempfails +ifelse(len(X`'_ARG6_), `1', `define(`_LDAP_ROUTE_MAPTEMP_', `_QUEUE_')', + _ARG6_, `tempfail', `define(`_LDAP_ROUTE_MAPTEMP_', `_TEMPFAIL_')', + _ARG6_, `queue', `define(`_LDAP_ROUTE_MAPTEMP_', `_QUEUE_')') + LOCAL_CONFIG # LDAP routing maps Kldapmh ifelse(len(X`'_ARG1_), `1', diff --git a/contrib/sendmail/cf/feature/local_lmtp.m4 b/contrib/sendmail/cf/feature/local_lmtp.m4 index f3c371b9384f..6f3888add2bc 100644 --- a/contrib/sendmail/cf/feature/local_lmtp.m4 +++ b/contrib/sendmail/cf/feature/local_lmtp.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2000, 2002 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: local_lmtp.m4,v 8.16 2000/08/18 18:58:45 ca Exp $') +VERSIONID(`$Id: local_lmtp.m4,v 8.17 2002/11/17 04:41:04 ca Exp $') divert(-1) ifdef(`_MAILER_local_', @@ -21,7 +21,8 @@ define(`LOCAL_MAILER_PATH', ifelse(defn(`_ARG_'), `', ifdef(`confEBINDIR', confEBINDIR, `/usr/libexec')`/mail.local', _ARG_)) -define(`LOCAL_MAILER_FLAGS', `PSXfmnz9') -define(`LOCAL_MAILER_ARGS', `mail.local -l') +define(`LOCAL_MAILER_FLAGS', `PSXmnz9') +define(`LOCAL_MAILER_ARGS', + ifelse(len(X`'_ARG2_), `1', `mail.local -l', _ARG2_)) define(`LOCAL_MAILER_DSN_DIAGNOSTIC_CODE', `SMTP') define(`_LOCAL_LMTP_', `1') diff --git a/contrib/sendmail/cf/feature/local_procmail.m4 b/contrib/sendmail/cf/feature/local_procmail.m4 index eaf83eab3828..694c3d9ef9b8 100644 --- a/contrib/sendmail/cf/feature/local_procmail.m4 +++ b/contrib/sendmail/cf/feature/local_procmail.m4 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: local_procmail.m4,v 8.21.42.1 2002/11/17 04:25:07 ca Exp $') +VERSIONID(`$Id: local_procmail.m4,v 8.22 2002/11/17 04:24:19 ca Exp $') divert(-1) ifdef(`_MAILER_local_', diff --git a/contrib/sendmail/cf/feature/mailertable.m4 b/contrib/sendmail/cf/feature/mailertable.m4 index e4dcd701cd41..e3e1d0344b8b 100644 --- a/contrib/sendmail/cf/feature/mailertable.m4 +++ b/contrib/sendmail/cf/feature/mailertable.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: mailertable.m4,v 8.23 2001/03/16 00:51:26 gshapiro Exp $') +VERSIONID(`$Id: mailertable.m4,v 8.25 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_MAILER_TABLE_', `') @@ -21,5 +21,5 @@ define(`_MAILER_TABLE_', `') LOCAL_CONFIG # Mailer table (overriding domains) Kmailertable ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`mailertable', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=mailer)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=mailer)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/feature/msp.m4 b/contrib/sendmail/cf/feature/msp.m4 index f4bc64a9d733..6ecf3342555a 100644 --- a/contrib/sendmail/cf/feature/msp.m4 +++ b/contrib/sendmail/cf/feature/msp.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. +# Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ divert(-1) # divert(0)dnl -VERSIONID(`$Id: msp.m4,v 1.32 2002/03/26 22:02:03 ca Exp $') +VERSIONID(`$Id: msp.m4,v 1.33 2004/02/09 22:32:38 ca Exp $') divert(-1) undefine(`ALIAS_FILE') define(`confDELIVERY_MODE', `i') @@ -21,7 +21,9 @@ define(`confDONT_PROBE_INTERFACES', `True') dnl --------------------------------------------- dnl run as this user (even if called by root) ifdef(`confRUN_AS_USER',,`define(`confRUN_AS_USER', `smmsp')') -ifdef(`confTRUSTED_USER',,`define(`confTRUSTED_USER', confRUN_AS_USER)') +ifdef(`confTRUSTED_USER',,`define(`confTRUSTED_USER', +`ifelse(index(confRUN_AS_USER,`:'), -1, `confRUN_AS_USER', +`substr(confRUN_AS_USER,0,index(confRUN_AS_USER,`:'))')')') dnl --------------------------------------------- dnl This queue directory must have the same group dnl as sendmail and it must be group-writable. diff --git a/contrib/sendmail/cf/feature/mtamark.m4 b/contrib/sendmail/cf/feature/mtamark.m4 new file mode 100644 index 000000000000..ae5f07a24b5a --- /dev/null +++ b/contrib/sendmail/cf/feature/mtamark.m4 @@ -0,0 +1,33 @@ +divert(-1) +# +# Copyright (c) 2004 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +ifdef(`_MTAMARK_R',`dnl',`dnl +VERSIONID(`$Id: mtamark.m4,v 1.1 2004/03/22 19:22:40 ca Exp $') +LOCAL_CONFIG +define(`_MTAMARK_R',`')dnl +# map for MTA mark +Kmtamark dns -R TXT -a. -T -r`'ifdef(`MTAMARK_TO',`MTAMARK_TO',`5') +') +divert(-1) +define(`_MTAMARK_RR_', `ifelse(len(X`'_ARG3_),`1',`_perm._smtp._srv',`_ARG3_')')dnl +define(`_MTAMARK_MSG_', `ifelse(len(X`'_ARG_),`1',`"550 Rejected: " $`'&{client_addr} " not listed as MTA"',`_ARG_')')dnl +define(`_MTAMARK_MSG_TMP_', `ifelse(_ARG2_,`t',`"451 Temporary lookup failure of " _MTAMARK_RR_.$`'&{client_addr}',`_ARG2_')')dnl +divert(8) +# DNS based IP MTA list +R$* $: $&{client_addr} +R$-.$-.$-.$- $: $(mtamark _MTAMARK_RR_.$4.$3.$2.$1.in-addr.arpa. $: OK $) +R1. $: OKSOFAR +R0. $#error $@ 5.7.1 $: _MTAMARK_MSG_ +ifelse(len(X`'_ARG2_),`1', +`R$+ $: TMPOK', +`R$+ $#error $@ 4.7.1 $: _MTAMARK_MSG_TMP_') +divert(-1) diff --git a/contrib/sendmail/cf/feature/ratecontrol.m4 b/contrib/sendmail/cf/feature/ratecontrol.m4 new file mode 100644 index 000000000000..e3389c0c1b41 --- /dev/null +++ b/contrib/sendmail/cf/feature/ratecontrol.m4 @@ -0,0 +1,36 @@ +divert(-1) +# +# Copyright (c) 2003, 2004 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Id: ratecontrol.m4,v 1.5 2004/02/19 21:31:47 ca Exp $') + +divert(-1) +ifdef(`_ACCESS_TABLE_', ` + define(`_RATE_CONTROL_', `1') + ifelse(defn(`_ARG_'), `', `', + strcasecmp(defn(`_ARG_'), `nodelay'), `1', + `ifdef(`_DELAY_CHECKS_', + ` + define(`_RATE_CONTROL_IMMEDIATE_', `1') + define(`_CONTROL_IMMEDIATE_', `1') + ', + `errprint(`*** ERROR: FEATURE(`ratecontrol', `nodelay') requires FEATURE(`delay_checks')')' + )', + `errprint(`*** ERROR: unknown parameter '"defn(`_ARG_')"` for FEATURE(`ratecontrol')')') + define(`_FFR_SRCHLIST_A', `1') + ifelse(len(X`'_ARG2_), `1', `', + _ARG2_, `terminate', `define(`_RATE_CONTROL_REPLY', `421')', + `errprint(`*** ERROR: FEATURE(`ratecontrol'): unknown argument '"_ARG2_" +)' + ) + ', `errprint(`*** ERROR: FEATURE(`ratecontrol') requires FEATURE(`access_db') +')') +ifdef(`_RATE_CONTROL_REPLY',,`define(`_RATE_CONTROL_REPLY', `452')') diff --git a/contrib/sendmail/cf/feature/use_client_ptr.m4 b/contrib/sendmail/cf/feature/use_client_ptr.m4 new file mode 100644 index 000000000000..918dff13c651 --- /dev/null +++ b/contrib/sendmail/cf/feature/use_client_ptr.m4 @@ -0,0 +1,21 @@ +divert(-1) +# +# Copyright (c) 2004 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Id: use_client_ptr.m4,v 1.1 2004/04/20 22:27:14 ca Exp $') +divert(-1) + +# if defined, check_relay will use {client_ptr} instead of whatever +# is passed in as its first argument. + +define(`_USE_CLIENT_PTR_', `1') + +divert(0) diff --git a/contrib/sendmail/cf/feature/uucpdomain.m4 b/contrib/sendmail/cf/feature/uucpdomain.m4 index 4d23229135f6..c6fbc5cc3a64 100644 --- a/contrib/sendmail/cf/feature/uucpdomain.m4 +++ b/contrib/sendmail/cf/feature/uucpdomain.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: uucpdomain.m4,v 8.27 2001/03/16 00:51:26 gshapiro Exp $') +VERSIONID(`$Id: uucpdomain.m4,v 8.29 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_UUDOMAIN_TABLE_', `') @@ -21,5 +21,5 @@ define(`_UUDOMAIN_TABLE_', `') LOCAL_CONFIG # UUCP domain table Kuudomain ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`uudomain', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=uucpdomain)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=uucpdomain)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/feature/virtusertable.m4 b/contrib/sendmail/cf/feature/virtusertable.m4 index d9c628f5fbaf..1717b663b20e 100644 --- a/contrib/sendmail/cf/feature/virtusertable.m4 +++ b/contrib/sendmail/cf/feature/virtusertable.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: virtusertable.m4,v 8.21 2001/03/16 00:51:26 gshapiro Exp $') +VERSIONID(`$Id: virtusertable.m4,v 8.23 2002/06/27 23:23:57 gshapiro Exp $') divert(-1) define(`_VIRTUSER_TABLE_', `') @@ -21,5 +21,5 @@ define(`_VIRTUSER_TABLE_', `') LOCAL_CONFIG # Virtual user table (maps incoming users) Kvirtuser ifelse(defn(`_ARG_'), `', DATABASE_MAP_TYPE MAIL_SETTINGS_DIR`virtusertable', - defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=virtuser)(sendmailMTAKey=%0))', + defn(`_ARG_'), `LDAP', `ldap -1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject -k (&(objectClass=sendmailMTAMapObject)(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))(sendmailMTAMapName=virtuser)(sendmailMTAKey=%0))', `_ARG_') diff --git a/contrib/sendmail/cf/m4/proto.m4 b/contrib/sendmail/cf/m4/proto.m4 index 48f4eabda02b..2397bc7283db 100644 --- a/contrib/sendmail/cf/m4/proto.m4 +++ b/contrib/sendmail/cf/m4/proto.m4 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Id: proto.m4,v 8.649.2.30 2004/01/11 17:54:06 ca Exp $') +VERSIONID(`$Id: proto.m4,v 8.710 2004/07/27 17:32:48 ca Exp $') # level CF_LEVEL config file format V`'CF_LEVEL/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Berkeley') @@ -197,7 +197,7 @@ ifdef(`_MACRO_MAP_', `', `# macro storage map define(`_MACRO_MAP_', `1')dnl Kmacro macro') # possible values for TLS_connection in access map -C{tls}VERIFY ENCR', `dnl') +C{Tls}VERIFY ENCR', `dnl') ifdef(`_CERT_REGEX_ISSUER_', `dnl # extract relevant part from cert issuer KCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl') @@ -261,7 +261,7 @@ _OPTION(AliasFile, `ALIAS_FILE', `MAIL_SETTINGS_DIR`'aliases') _OPTION(MinFreeBlocks, `confMIN_FREE_BLOCKS', `100') # maximum message size -_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `1000000') +_OPTION(MaxMessageSize, `confMAX_MESSAGE_SIZE', `0') # substitution for space (blank) characters _OPTION(BlankSub, `confBLANK_SUB', `_') @@ -425,14 +425,12 @@ _OPTION(Timeout.queuereturn, `confTO_QUEUERETURN', `5d') _OPTION(Timeout.queuereturn.normal, `confTO_QUEUERETURN_NORMAL', `5d') _OPTION(Timeout.queuereturn.urgent, `confTO_QUEUERETURN_URGENT', `2d') _OPTION(Timeout.queuereturn.non-urgent, `confTO_QUEUERETURN_NONURGENT', `7d') -ifdef(`confTO_QUEUERETURN_DSN', `dnl -O Timeout.queuereturn.dsn=confTO_QUEUERETURN_DSN') +_OPTION(Timeout.queuereturn.dsn, `confTO_QUEUERETURN_DSN', `5d') _OPTION(Timeout.queuewarn, `confTO_QUEUEWARN', `4h') _OPTION(Timeout.queuewarn.normal, `confTO_QUEUEWARN_NORMAL', `4h') _OPTION(Timeout.queuewarn.urgent, `confTO_QUEUEWARN_URGENT', `1h') _OPTION(Timeout.queuewarn.non-urgent, `confTO_QUEUEWARN_NONURGENT', `12h') -ifdef(`confTO_QUEUEWARN_DSN', `dnl -O Timeout.queuewarn.dsn=confTO_QUEUEWARN_DSN') +_OPTION(Timeout.queuewarn.dsn, `confTO_QUEUEWARN_DSN', `4h') _OPTION(Timeout.hoststatus, `confTO_HOSTSTATUS', `30m') _OPTION(Timeout.resolver.retrans, `confTO_RESOLVER_RETRANS', `5s') _OPTION(Timeout.resolver.retrans.first, `confTO_RESOLVER_RETRANS_FIRST', `5s') @@ -473,6 +471,9 @@ _OPTION(UserDatabaseSpec, `confUSERDB_SPEC', `MAIL_SETTINGS_DIR`'userdb') # fallback MX host _OPTION(FallbackMXhost, `confFALLBACK_MX', `fall.back.host.net') +# fallback smart host +_OPTION(FallbackSmartHost, `confFALLBACK_SMARTHOST', `fall.back.host.net') + # if we are the best MX host for a site, try it directly instead of config err _OPTION(TryNullMXList, `confTRY_NULL_MX_LIST', `False') @@ -482,6 +483,9 @@ _OPTION(QueueLA, `confQUEUE_LA', `8') # load average at which we refuse connections _OPTION(RefuseLA, `confREFUSE_LA', `12') +# log interval when refusing connections for this long +_OPTION(RejectLogInterval, `confREJECT_LOG_INTERVAL', `3h') + # load average at which we delay connections; 0 means no limit _OPTION(DelayLA, `confDELAY_LA', `0') @@ -491,6 +495,9 @@ _OPTION(MaxDaemonChildren, `confMAX_DAEMON_CHILDREN', `0') # maximum number of new connections per second _OPTION(ConnectionRateThrottle, `confCONNECTION_RATE_THROTTLE', `0') +# Width of the window +_OPTION(ConnectionRateWindowSize, `confCONNECTION_RATE_WINDOW_SIZE', `60s') + # work recipient factor _OPTION(RecipientFactor, `confWORK_RECIPIENT_FACTOR', `30000') @@ -565,11 +572,11 @@ _OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter') _OPTION(RunAsUser, `confRUN_AS_USER', `sendmail') # maximum number of recipients per SMTP envelope -_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `100') +_OPTION(MaxRecipientsPerMessage, `confMAX_RCPTS_PER_MESSAGE', `0') # limit the rate recipients per SMTP envelope are accepted # once the threshold number of recipients have been rejected -_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `20') +_OPTION(BadRcptThrottle, `confBAD_RCPT_THROTTLE', `0') # shall we get local names from our installed interfaces? _OPTION(DontProbeInterfaces, `confDONT_PROBE_INTERFACES', `False') @@ -587,7 +594,7 @@ _OPTION(TrustedUser, `confTRUSTED_USER', `root') _OPTION(ControlSocketName, `confCONTROL_SOCKET_NAME', `/var/spool/mqueue/.control') # Maximum MIME header length to protect MUAs -_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `2048/1024') +_OPTION(MaxMimeHeaderLength, `confMAX_MIME_HEADER_LENGTH', `0/0') # Maximum length of the sum of all headers _OPTION(MaxHeadersLength, `confMAX_HEADERS_LENGTH', `32768') @@ -610,9 +617,15 @@ _OPTION(XscriptFileBufferSize, `confXF_BUFFER_SIZE', `4096') # lookup type to find information about local mailboxes _OPTION(MailboxDatabase, `confMAILBOX_DATABASE', `pw') +# override compile time flag REQUIRES_DIR_FSYNC +_OPTION(RequiresDirfsync, `confREQUIRES_DIR_FSYNC', `true') + # list of authentication mechanisms _OPTION(AuthMechanisms, `confAUTH_MECHANISMS', `EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5') +# Authentication realm +_OPTION(AuthRealm, `confAUTH_REALM', `') + # default authentication information for outgoing connections _OPTION(DefaultAuthInfo, `confDEF_AUTH_INFO', `MAIL_SETTINGS_DIR`'default-auth-info') @@ -635,7 +648,7 @@ _OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `') _OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `') _OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `') _OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `') -') +_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')') # CA directory _OPTION(CACertPath, `confCACERT_PATH', `') @@ -649,6 +662,8 @@ _OPTION(ServerKeyFile, `confSERVER_KEY', `') _OPTION(ClientCertFile, `confCLIENT_CERT', `') # Client private key _OPTION(ClientKeyFile, `confCLIENT_KEY', `') +# File containing certificate revocation lists +_OPTION(CRLFile, `confCRL', `') # DHParameters (only required if DSA/DH is used) _OPTION(DHParameters, `confDH_PARAMETERS', `') # Random data source (required for systems without /dev/urandom under OpenSSL) @@ -685,6 +700,7 @@ ifdef(`confTRUSTED_USERS', `T`'confTRUSTED_USERS', `dnl') ######################### ifdef(`confFROM_HEADER',, `define(`confFROM_HEADER', `$?x$x <$g>$|$g$.')')dnl +ifdef(`confMESSAGEID_HEADER',, `define(`confMESSAGEID_HEADER', `<$t.$i@$j>')')dnl H?P?Return-Path: <$g> HReceived: confRECEIVED_HEADER H?D?Resent-Date: $a @@ -694,8 +710,8 @@ H?F?From: confFROM_HEADER H?x?Full-Name: $x # HPosted-Date: $a # H?l?Received-Date: $b -H?M?Resent-Message-Id: <$t.$i@$j> -H?M?Message-Id: <$t.$i@$j> +H?M?Resent-Message-Id: confMESSAGEID_HEADER +H?M?Message-Id: confMESSAGEID_HEADER # ###################################################################### @@ -1429,13 +1445,21 @@ ifdef(`_LDAP_ROUTING_', `dnl ### Parsed address (user < @ domain . >) ###################################################################### +# SMTP operation modes +C{SMTPOpModes} s d D + SLDAPExpand # do the LDAP lookups R<$+><$+><$*> $: <$(ldapmra $2 $: $)> <$(ldapmh $2 $: $)> <$1> <$2> <$3> -# look for temporary failures (return original address, MTA will queue up) -R<$* > <$*> <$+> <$+> <$*> $@ $3 -R<$*> <$* > <$+> <$+> <$*> $@ $3 +# look for temporary failures and... +R<$* > <$*> <$+> <$+> <$*> $: $&{opMode} $| TMPF <$&{addr_type}> $| $3 +R<$*> <$* > <$+> <$+> <$*> $: $&{opMode} $| TMPF <$&{addr_type}> $| $3 +ifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl +# ... temp fail RCPT SMTP commands +R$={SMTPOpModes} $| TMPF $| $+ $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."') +# ... return original address for MTA to queue up +R$* $| TMPF <$*> $| $+ $@ $3 # if mailRoutingAddress and local or non-existant mailHost, # return the new mailRoutingAddress @@ -1475,11 +1499,12 @@ ifdef(`_LDAP_ROUTE_DETAIL_', # try without +detail R<> <> <$+> <$+ + $* @ $+> <> $@ $>LDAPExpand <$1> <$2 @ $4> <+$3>')dnl +ifdef(`_LDAP_ROUTE_NODOMAIN_', `dnl', ` # if still no mailRoutingAddress and no mailHost, # try @domain ifelse(_LDAP_ROUTE_DETAIL_, `_PRESERVE_', `dnl R<> <> <$+> <$+ + $* @ $+> <> $@ $>LDAPExpand <$1> <@ $4> <+$3>') -R<> <> <$+> <$+ @ $+> <$*> $@ $>LDAPExpand <$1> <@ $3> <$4> +R<> <> <$+> <$+ @ $+> <$*> $@ $>LDAPExpand <$1> <@ $3> <$4>') # if no mailRoutingAddress and no mailHost and this was a domain attempt, ifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl @@ -1487,6 +1512,9 @@ ifelse(_LDAP_ROUTING_, `_MUST_EXIST_', `dnl R<> <> <$+> <@ $+> <$*> $: < $&{addr_type} > < $1 > # only give error for envelope recipient R <$+> $#error $@ nouser $: "550 User unknown" +ifdef(`_LDAP_SENDER_MUST_EXIST_', `dnl +# and the sender too +R <$+> $#error $@ nouser $: "550 User unknown"') R <$*> <$+> $@ $2', `dnl # return the original address @@ -1675,7 +1703,7 @@ R<$+> <$+> $: <$1> $2',`dnl')') ifdef(`_RELAY_MX_SERVED_', `dnl dnl do "we" ($=w) act as backup MX server for the destination domain? R $* < @ $+ > $: < : $(mxserved $2 $) : > < $1 < @$2 > > -R < : $* : > $* $#TEMP $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1 +R < : $* : > $* $#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1 dnl yes: mark it as R < $* : $=w. : $* > < $+ > $: $4 dnl no: put old mark back @@ -1691,8 +1719,20 @@ R<$+> $* $@ $2 ### check_relay -- check hostname/address on SMTP startup ###################################################################### +ifdef(`_CONTROL_IMMEDIATE_',`dnl +Scheck_relay +ifdef(`_RATE_CONTROL_IMMEDIATE_',`dnl +dnl workspace: ignored... +R$* $: $>"RateControl" dummy', `dnl') +ifdef(`_CONN_CONTROL_IMMEDIATE_',`dnl +dnl workspace: ignored... +R$* $: $>"ConnControl" dummy', `dnl') +dnl') + SLocal_check_relay Scheck`'_U_`'relay +ifdef(`_USE_CLIENT_PTR_',`dnl +R$* $| $* $: $&{client_ptr} $| $2', `dnl') R$* $: $1 $| $>"Local_check_relay" $1 R$* $| $* $| $#$* $#$3 R$* $| $* $| $* $@ $>"Basic_check_relay" $1 $| $2 @@ -1715,10 +1755,9 @@ dnl workspace: (<>|<{client_addr}>) R <$*> $: OK found nothing dnl workspace: (<>|<{client_addr}>) | OK R<$={Accept}> <$*> $@ $1 return value of lookup -R <$*> $#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"') +R <$*> $#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"') R <$*> $#discard $: discard -ifdef(`_FFR_QUARANTINE', -`R <$*> $#error $@ quarantine $: $1', `dnl') +R <$*> $#error $@ quarantine $: $1 dnl error tag R <$*> $#error $@ $1.$2.$3 $: $4 R <$*> $#error $: $1 @@ -1734,6 +1773,14 @@ R$-.$-.$-.$- $: $(host $4.$3.$2.$1._RBL_. $: OK $) ROK $: OKSOFAR R$+ $#error $@ 5.7.1 $: "550 Rejected: " $&{client_addr} " listed at _RBL_"', `dnl') +ifdef(`_RATE_CONTROL_',`dnl +ifdef(`_RATE_CONTROL_IMMEDIATE_',`', `dnl +dnl workspace: ignored... +R$* $: $>"RateControl" dummy')', `dnl') +ifdef(`_CONN_CONTROL_',`dnl +ifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl +dnl workspace: ignored... +R$* $: $>"ConnControl" dummy')', `dnl') undivert(8) ###################################################################### @@ -1866,9 +1913,8 @@ R $* $#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does ifdef(`_ACCESS_TABLE_', `dnl R<$={Accept}> $* $# $1 accept from access map R $* $#discard $: discard -ifdef(`_FFR_QUARANTINE', -`R $* $#error $@ quarantine $: $1', `dnl') -R $* $#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"') +R $* $#error $@ quarantine $: $1 +R $* $#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $: "550 Access denied"') dnl error tag R $* $#error $@ $1.$2.$3 $: $4 R $* $#error $: $1 @@ -2007,8 +2053,7 @@ dnl maybe we should stop checks already here (if SPAM_xyx)? R<$={SpamTag}> <$*> $: @ $2 mark address as no match') R $* $#error $@ 5.2.1 $: confRCPTREJ_MSG R $* $#discard $: discard -ifdef(`_FFR_QUARANTINE', -`R $* $#error $@ quarantine $: $1', `dnl') +R $* $#error $@ quarantine $: $1 dnl error tag R $* $#error $@ $1.$2.$3 $: $4 R $* $#error $: $1 @@ -2053,7 +2098,11 @@ dnl workspace: > R <$+ < @ $+ >> $: <$(access $2 $: ? $)> <$1 < @ $2 >>',`dnl')', `R$+ < @ $* $=R > $@ RELAY ifdef(`_ACCESS_TABLE_', `dnl -R$+ < @ $+ > $: $>D <$2> <+ To> <$1 < @ $2 >>',`dnl')') +ifdef(`_RELAY_FULL_ADDR_', `dnl +R$+ < @ $+ > $: $1 < @ $2 > $| $>SearchList <+ To> $| <> +R$+ < @ $+ > $| <$*> $: <$3> <$1 <@ $2>> +R$+ < @ $+ > $| $* $: <$3> <$1 <@ $2>>', +`R$+ < @ $+ > $: $>D <$2> <+ To> <$1 < @ $2 >>')')') ifdef(`_ACCESS_TABLE_', `dnl dnl workspace: > R $* $@ RELAY @@ -2065,7 +2114,7 @@ ifdef(`_RELAY_MX_SERVED_', `dnl # allow relaying for hosts which we MX serve R$+ < @ $+ > $: < : $(mxserved $2 $) : > $1 < @ $2 > dnl this must not necessarily happen if the client is checked first... -R< : $* : > $* $#TEMP $@ 4.7.1 $: "450 Can not check MX records for recipient host " $1 +R< : $* : > $* $#TEMP $@ 4.4.0 $: "450 Can not check MX records for recipient host " $1 R<$* : $=w . : $*> $* $@ RELAY R< : $* : > $* $: $2', `dnl') @@ -2158,7 +2207,7 @@ dnl the input. otherwise these rules must "clean up" the workspace. # check client name: first: did it resolve? dnl input: ignored R$* $: < $&{client_resolve} > -R $#TEMP $@ 4.7.1 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr} +R $#TEMP $@ 4.4.0 $: "450 Relaying temporarily denied. Cannot resolve PTR record for " $&{client_addr} R $#error $@ 5.7.1 $: "550 Relaying denied. IP name possibly forged " $&{client_name} R $#error $@ 5.7.1 $: "550 Relaying denied. IP name lookup failed " $&{client_name} dnl ${client_resolve} should be OK, so go ahead @@ -2441,11 +2490,11 @@ dnl A: recursive address lookup (LookUpAddress) [not yet required] # class with valid marks for SearchList dnl if A is activated: add it -C{src}E F D U ifdef(`_FFR_SRCHLIST_A', `A') +C{Src}E F D U ifdef(`_FFR_SRCHLIST_A', `A') SSearchList # just call the ruleset with the name of the tag... nice trick... dnl 2 3 4 -R<$+> $| <$={src}:$*> <$*> $: <$1> $| <$4> $| $>$2 <$3> <$1> <> +R<$+> $| <$={Src}:$*> <$*> $: <$1> $| <$4> $| $>$2 <$3> <$1> <> dnl workspace: $| $| <> dnl no match and nothing left: return R<$+> $| <> $| <> $@ @@ -2488,7 +2537,6 @@ R$* $#error $@ 5.7.1 $: "550 " $&{auth_authen} " not allowed to act as " $&{au ###################################################################### SLocal_Relay_Auth -ifdef(`_ACCESS_TABLE_', `dnl ###################################################################### ### srv_features: which features to offer to a client? ### (done in server) @@ -2498,13 +2546,14 @@ ifdef(`_LOCAL_SRV_FEATURES_', `dnl R$* $: $1 $| $>"Local_srv_features" $1 R$* $| $#$* $#$2 R$* $| $* $: $1', `dnl') +ifdef(`_ACCESS_TABLE_', `dnl R$* $: $>D <$&{client_name}> <> R$* $: $>A <$&{client_addr}> <> R$* $: <$(access SRV_FEAT_TAG`'_TAG_DELIM_ $: ? $)> R$* $@ OK ifdef(`_ATMPF_', `dnl tempfail? R<$* _ATMPF_>$* $#temp', `dnl') -R<$+>$* $# $1 +R<$+>$* $# $1') ###################################################################### ### try_tls: try to use STARTTLS? @@ -2515,14 +2564,15 @@ ifdef(`_LOCAL_TRY_TLS_', `dnl R$* $: $1 $| $>"Local_try_tls" $1 R$* $| $#$* $#$2 R$* $| $* $: $1', `dnl') +ifdef(`_ACCESS_TABLE_', `dnl R$* $: $>D <$&{server_name}> <> R$* $: $>A <$&{server_addr}> <> R$* $: <$(access TLS_TRY_TAG`'_TAG_DELIM_ $: ? $)> R$* $@ OK ifdef(`_ATMPF_', `dnl tempfail? R<$* _ATMPF_>$* $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl') -R$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]" - +R$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"') + ###################################################################### ### tls_rcpt: is connection with server "good" enough? ### (done in client, per recipient) @@ -2536,6 +2586,7 @@ ifdef(`_LOCAL_TLS_RCPT_', `dnl R$* $: $1 $| $>"Local_tls_rcpt" $1 R$* $| $#$* $#$2 R$* $| $* $: $1', `dnl') +ifdef(`_ACCESS_TABLE_', `dnl dnl store name of other side R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1 dnl canonify recipient address @@ -2637,10 +2688,10 @@ R$* $| <$*>$* $: $1 $| <$2> dnl workspace: ${verify} $| # create the appropriate error codes dnl permanent or temporary error? -R$* $| $: $1 $| <503:5.7.0> <$2 $3> -R$* $| $: $1 $| <403:4.7.0> <$2 $3> +R$* $| $: $1 $| <503:5.7.0> <$2 $3> +R$* $| $: $1 $| <403:4.7.0> <$2 $3> dnl default case depends on TLS_PERM_ERR -R$* $| <$={tls} $*> $: $1 $| <$2 $3> +R$* $| <$={Tls} $*> $: $1 $| <$2 $3> dnl workspace: ${verify} $| [] # deal with TLS handshake failures: abort RSOFTWARE $| <$-:$+> $* $#error $@ $2 $: $1 " TLS handshake failed." @@ -2650,9 +2701,9 @@ RSOFTWARE $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(` R$* $| <$*> $: <$2> <> $1 dnl separate optional requirements R$* $| <$*> $: <$2> <$3> $1 -R$* $| <$*> <$={tls}:$->$* $: <$2> <$3:$4> <> $1 +R$* $| <$*> <$={Tls}:$->$* $: <$2> <$3:$4> <> $1 dnl separate optional requirements -R$* $| <$*> <$={tls}:$- + $+>$* $: <$2> <$3:$4> <$5> $1 +R$* $| <$*> <$={Tls}:$- + $+>$* $: <$2> <$3:$4> <$5> $1 dnl some other value in access map: accept dnl this also allows to override the default case (if used) R$* $| $* $@ OK @@ -2821,6 +2872,50 @@ R$* $| $* $@ no no authinfo available R$* $| <$*> <> $# $2 dnl', `dnl')') +ifdef(`_RATE_CONTROL_',`dnl +###################################################################### +### RateControl: +### Parameters: ignored +### return: $#error or OK +###################################################################### +SRateControl +ifdef(`_ACCESS_TABLE_', `dnl +R$* $: +dnl also look up a default value via E: +R$+ $: $>SearchList $| $1 <> +dnl found nothing: stop here +R $@ OK +ifdef(`_ATMPF_', `dnl tempfail? +R<$* _ATMPF_> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl') +dnl use the generic routine (for now) +R<0> $@ OK no limit +R<$+> $: <$1> $| $(arith l $@ $&{client_rate} $@ $1 $) +dnl log this? Connection rate $&{client_rate} exceeds limit $1. +R<$+> $| FALSE $#error $@ 4.3.2 $: _RATE_CONTROL_REPLY Connection rate limit exceeded. +')') + +ifdef(`_CONN_CONTROL_',`dnl +###################################################################### +### ConnControl: +### Parameters: ignored +### return: $#error or OK +###################################################################### +SConnControl +ifdef(`_ACCESS_TABLE_', `dnl +R$* $: +dnl also look up a default value via E: +R$+ $: $>SearchList $| $1 <> +dnl found nothing: stop here +R $@ OK +ifdef(`_ATMPF_', `dnl tempfail? +R<$* _ATMPF_> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl') +dnl use the generic routine (for now) +R<0> $@ OK no limit +R<$+> $: <$1> $| $(arith l $@ $&{client_connections} $@ $1 $) +dnl log this: Open connections $&{client_connections} exceeds limit $1. +R<$+> $| FALSE $#error $@ 4.3.2 $: _CONN_CONTROL_REPLY Too many open connections. +')') + undivert(9)dnl LOCAL_RULESETS # ###################################################################### diff --git a/contrib/sendmail/cf/m4/version.m4 b/contrib/sendmail/cf/m4/version.m4 index b6cc2289bc7c..d06e15d7edc2 100644 --- a/contrib/sendmail/cf/m4/version.m4 +++ b/contrib/sendmail/cf/m4/version.m4 @@ -11,8 +11,8 @@ divert(-1) # the sendmail distribution. # # -VERSIONID(`$Id: version.m4,v 8.92.2.26 2004/01/13 00:29:26 ca Exp $') +VERSIONID(`$Id: version.m4,v 8.117 2004/07/30 18:03:07 ca Exp $') # divert(0) # Configuration version number -DZ8.12.11`'ifdef(`confCF_VERSION', `/confCF_VERSION') +DZ8.13.1`'ifdef(`confCF_VERSION', `/confCF_VERSION') diff --git a/contrib/sendmail/cf/mailer/usenet.m4 b/contrib/sendmail/cf/mailer/usenet.m4 index d28c3214d397..39f49b8bf06d 100644 --- a/contrib/sendmail/cf/mailer/usenet.m4 +++ b/contrib/sendmail/cf/mailer/usenet.m4 @@ -21,7 +21,7 @@ POPDIVERT ### USENET Mailer specification ### #################################### -VERSIONID(`$Id: usenet.m4,v 8.21.4.1 2003/03/03 22:53:03 ca Exp $') +VERSIONID(`$Id: usenet.m4,v 8.22 2003/02/20 21:16:13 ca Exp $') Musenet, P=USENET_MAILER_PATH, F=_MODMF_(USENET_MAILER_FLAGS, `USENET'), S=EnvFromL, R=EnvToL, _OPTINS(`USENET_MAILER_MAX', `M=', `, ')T=X-Usenet/X-Usenet/X-Unix,_USENET_QGRP diff --git a/contrib/sendmail/cf/ostype/unicos.m4 b/contrib/sendmail/cf/ostype/unicos.m4 new file mode 100644 index 000000000000..d73f3faaec0c --- /dev/null +++ b/contrib/sendmail/cf/ostype/unicos.m4 @@ -0,0 +1,22 @@ +divert(-1) +# +# Copyright (c) 2003 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# +# + +divert(0) +VERSIONID(`$Id: unicos.m4,v 1.1 2003/04/21 17:03:51 ca Exp $') +define(`ALIAS_FILE', `/usr/lib/aliases') +define(`HELP_FILE', `/usr/lib/sendmail.hf') +define(`QUEUE_DIR', `/usr/spool/mqueue') +define(`STATUS_FILE', `/usr/lib/sendmail.st') +MODIFY_MAILER_FLAGS(`LOCAL', `+aSPpmnxXu') +MODIFY_MAILER_FLAGS(`SMTP', `+anpeLC') +define(`LOCAL_SHELL_FLAGS', `pxehu') +define(`confPID_FILE', `/etc/sendmail.pid')dnl diff --git a/contrib/sendmail/cf/ostype/unicosmk.m4 b/contrib/sendmail/cf/ostype/unicosmk.m4 new file mode 100644 index 000000000000..e9cec04fe674 --- /dev/null +++ b/contrib/sendmail/cf/ostype/unicosmk.m4 @@ -0,0 +1,22 @@ +divert(-1) +# +# Copyright (c) 2003 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# +# + +divert(0) +VERSIONID(`$Id: unicosmk.m4,v 1.1 2003/04/21 17:03:51 ca Exp $') +define(`ALIAS_FILE', `/usr/lib/aliases') +define(`HELP_FILE', `/usr/lib/sendmail.hf') +define(`QUEUE_DIR', `/usr/spool/mqueue') +define(`STATUS_FILE', `/usr/lib/sendmail.st') +MODIFY_MAILER_FLAGS(`LOCAL' , `+aSPpmnxXu') +MODIFY_MAILER_FLAGS(`SMTP', `+anpeLC') +define(`LOCAL_SHELL_FLAGS', `lsDFMpxehuo') +define(`confPID_FILE', `/etc/sendmail.pid')dnl diff --git a/contrib/sendmail/cf/ostype/unicosmp.m4 b/contrib/sendmail/cf/ostype/unicosmp.m4 new file mode 100644 index 000000000000..79543d2ffb58 --- /dev/null +++ b/contrib/sendmail/cf/ostype/unicosmp.m4 @@ -0,0 +1,27 @@ +divert(-1) +# +# Copyright (c) 2003 Sendmail, 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. +# +# +# + +# +# Notes: +# - In UNICOSMP seems that TZ variable is needed that correct time is marked +# to syslog +# + +divert(0) +VERSIONID(`$Id: unicosmp.m4,v 1.1 2003/04/21 17:03:51 ca Exp $') +_DEFIFNOT(`LOCAL_MAILER_FLAGS', `Ehm9')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail -s -d $u')')dnl +ifdef(`QUEUE_DIR',, `define(`QUEUE_DIR', /var/spool/mqueue)')dnl +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', `/var/log/sendmail.st')')dnl +define(`LOCAL_MAILER_PATH', `/usr/bin/mail')dnl +define(`confTIME_ZONE', USE_TZ)dnl +define(`confEBINDIR', `/usr/lib')dnl diff --git a/contrib/sendmail/cf/sendmail.schema b/contrib/sendmail/cf/sendmail.schema index f16782229f14..a532f8b33f65 100644 --- a/contrib/sendmail/cf/sendmail.schema +++ b/contrib/sendmail/cf/sendmail.schema @@ -5,13 +5,12 @@ # forth in the LICENSE file which can be found at the top level of # the sendmail distribution. # -# $Id: sendmail.schema,v 8.19.2.1 2002/11/20 23:13:27 gshapiro Exp $ +# $Id: sendmail.schema,v 8.21 2002/11/20 23:13:50 gshapiro Exp $ # Note that this schema is experimental at this point as it has had little # public review. Therefore, it may change in future versions. Feedback # via sendmail@sendmail.org is encouraged. - # OID arcs for Sendmail # enterprise: 1.3.6.1.4.1 # sendmail: enterprise.6152 @@ -88,6 +87,19 @@ attributetype ( 1.3.6.1.4.1.6152.10.3.1.16 EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) +# attribute sendmailMTAMapSearch cis +attributetype ( 1.3.6.1.4.1.6152.10.3.1.24 + NAME 'sendmailMTAMapSearch' + DESC 'recursive search for values of a map entry' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +# attribute sendmailMTAMapURL cis +attributetype ( 1.3.6.1.4.1.6152.10.3.1.25 + NAME 'sendmailMTAMapURL' + DESC 'recursive search URL for values of a map entry' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) #objectClass sendmailMTAMap # requires @@ -110,18 +122,22 @@ objectclass ( 1.3.6.1.4.1.6152.10.3.2.11 # objectClass, # sendmailMTAMapName, # sendmailMTAKey, -# sendmailMTAMapValue, # allows # sendmailMTACluster, # sendmailMTAHost, +# sendmailMTAMapValue, +# sendmailMTAMapSearch, +# sendmailMTAMapURL, # Description objectclass ( 1.3.6.1.4.1.6152.10.3.2.12 NAME 'sendmailMTAMapObject' SUP sendmailMTAMap STRUCTURAL DESC 'Sendmail MTA map object' - MUST ( sendmailMTAMapName $ sendmailMTAKey $ sendmailMTAMapValue ) - MAY ( sendmailMTACluster $ sendmailMTAHost $ Description ) ) + MUST ( sendmailMTAMapName $ sendmailMTAKey ) + MAY ( sendmailMTACluster $ sendmailMTAHost $ + sendmailMTAMapValue $ sendmailMTAMapSearch $ + sendmailMTAMapURL $ Description ) ) ########################################################################### @@ -145,6 +161,19 @@ attributetype ( 1.3.6.1.4.1.6152.10.3.1.20 EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +# attribute sendmailMTAAliasSearch cis +attributetype ( 1.3.6.1.4.1.6152.10.3.1.26 + NAME 'sendmailMTAAliasSearch' + DESC 'recursive search for values of an alias' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +# attribute sendmailMTAAliasURL cis +attributetype ( 1.3.6.1.4.1.6152.10.3.1.27 + NAME 'sendmailMTAAliasURL' + DESC 'recursive search URL for values of an alias' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) #objectClass sendmailMTAAlias # requires @@ -166,20 +195,23 @@ objectclass ( 1.3.6.1.4.1.6152.10.3.2.13 # requires # objectClass, # sendmailMTAKey, -# sendmailMTAAliasValue, # allows # sendmailMTAAliasGrouping, # sendmailMTACluster, # sendmailMTAHost, +# sendmailMTAAliasValue, +# sendmailMTAAliasSearch, +# sendmailMTAAliasURL, # Description objectclass ( 1.3.6.1.4.1.6152.10.3.2.14 NAME 'sendmailMTAAliasObject' SUP sendmailMTAAlias STRUCTURAL DESC 'Sendmail MTA alias object' - MUST ( sendmailMTAKey $ sendmailMTAAliasValue ) - MAY ( sendmailMTAAliasGrouping $ - sendmailMTACluster $ sendmailMTAHost $ Description ) ) + MUST sendmailMTAKey + MAY ( sendmailMTAAliasGrouping $ sendmailMTACluster $ + sendmailMTAHost $ sendmailMTAAliasValue $ + sendmailMTAAliasSearch $ sendmailMTAAliasURL $ Description ) ) ########################################################################### # @@ -201,20 +233,37 @@ attributetype ( 1.3.6.1.4.1.6152.10.3.1.23 EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 ) +# attribute sendmailMTAClassSearch cis +attributetype ( 1.3.6.1.4.1.6152.10.3.1.28 + NAME 'sendmailMTAClassSearch' + DESC 'recursive search for members of a class' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) + +# attribute sendmailMTAClassURL cis +attributetype ( 1.3.6.1.4.1.6152.10.3.1.29 + NAME 'sendmailMTAClassURL' + DESC 'recursive search URL for members of a class' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE ) #objectClass sendmailMTAClass # requires # objectClass, # sendmailMTAClassName, -# sendmailMTAClassValue, # allows # sendmailMTACluster, # sendmailMTAHost, +# sendmailMTAClassValue, +# sendmailMTAClassSearch, +# sendmailMTAClassURL, # Description objectclass ( 1.3.6.1.4.1.6152.10.3.2.15 NAME 'sendmailMTAClass' SUP sendmailMTA STRUCTURAL DESC 'Sendmail MTA class definition' - MUST ( sendmailMTAClassName $ sendmailMTAClassValue ) - MAY ( sendmailMTACluster $ sendmailMTAHost $ Description ) ) + MUST sendmailMTAClassName + MAY ( sendmailMTACluster $ sendmailMTAHost $ + sendmailMTAClassValue $ sendmailMTAClassSearch $ + sendmailMTAClassURL $ Description ) ) diff --git a/contrib/sendmail/contrib/buildvirtuser b/contrib/sendmail/contrib/buildvirtuser index 8c0aa44777aa..abed167bbb51 100755 --- a/contrib/sendmail/contrib/buildvirtuser +++ b/contrib/sendmail/contrib/buildvirtuser @@ -27,7 +27,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -# $Id: buildvirtuser,v 1.5.2.1 2003/03/15 23:30:26 gshapiro Exp $ +# $Id: buildvirtuser,v 1.6 2003/03/15 23:30:09 gshapiro Exp $ =head1 NAME diff --git a/contrib/sendmail/contrib/cidrexpand b/contrib/sendmail/contrib/cidrexpand index 67b62c565849..b7ace25adfbe 100755 --- a/contrib/sendmail/contrib/cidrexpand +++ b/contrib/sendmail/contrib/cidrexpand @@ -1,17 +1,13 @@ -#!/usr/local/bin/perl -w +#!/usr/bin/perl -w -# v 0.2-very-beta +# $Id: cidrexpand,v 8.4 2002/11/22 21:13:14 ca Exp $ +# +# v 0.4 # # 17 July 2000 Derek J. Balling (dredd@megacity.org) -# -# The $SENDMAIL flag tells the code to lump networks in sendmail format -# if applicable. If this flag is disabled, cidrexpand will literally create -# a single line for each entry, which may or may not be what you want. :) -# makes for a rather large hash table... -# +# # Acts as a preparser on /etc/mail/access_db to allow you to use address/bit -# notation. Caveat: the address portion MUST be the start address or your -# results will NOT be what what you want. +# notation. # # If you have two overlapping CIDR blocks with conflicting actions # e.g. 10.2.3.128/25 REJECT and 10.2.3.143 ACCEPT @@ -22,27 +18,35 @@ # # Modifications # ------------- -# 5 Nov 2002 Richard Rognlie (richard@sendmail.com) +# 26 Jul 2001 Derek Balling (dredd@megacity.org) +# Now uses Net::CIDR because it makes life a lot easier. +# +# 5 Nov 2002 Richard Rognlie (richard@sendmail.com) # Added code to deal with the prefix tags that may now be included in # the access_db # # Added clarification in the notes for what to do if you have # exceptions to a larger CIDR block. # -# usage: +# usage: # cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access # -# Report bugs to: dredd@megacity.org # +# Report bugs to: +# + + +use strict; +use Net::CIDR; my $spaceregex = '\s+'; while (my $arg = shift @ARGV) { - if ($arg eq '-t') - { + if ($arg eq '-t') + { $spaceregex = shift; - } + } } use strict; @@ -51,109 +55,40 @@ my $SENDMAIL = 1; while (<>) { - my ($prefix,$left,$right,$space); + my ($prefix,$left,$right,$space); - if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ ) - { + if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ ) + { print; - } - else - { + } + else + { ($prefix,$left,$space,$right) = /^(|\S\S*:)((?:\d+\.){3}\d+\/\d\d?)($spaceregex)(.*)$/; - + my @new_lefts = expand_network($left); foreach my $nl (@new_lefts) { print "$prefix$nl$space$right\n"; } - - } + } } sub expand_network { - my ($network,$mask) = split /\//, shift; - my @diffs = calc_changes($network,$mask); - my ($first,$second,$third,$fourth) = split /\./, $network; - - my @rc = (); - - for my $f ($first..($first+$diffs[0])) - { - if ( ( $SENDMAIL ) and ($diffs[1] == 255)) + my $left_input = shift; + my @rc = ($left_input); + my ($network,$mask) = split /\//, $left_input; + if (defined $mask) + { + my @parts = split /\./, $network; + while ($#parts < 3) { - push @rc, "$f"; + push @parts, "0"; } - else - { - for my $s ($second..($second+$diffs[1])) - { - if ( ($SENDMAIL) and ($diffs[2] == 255) ) - { - push @rc,"$f\.$s"; - } - else - { - for my $t ($third..($third+$diffs[2])) - { - if ( ($SENDMAIL) and ($diffs[3] == 255)) - { - push @rc, "$f\.$s\.$t"; - } - else - { - for my $fr ($fourth..($fourth+$diffs[3])) - { - push @rc, "$f\.$s\.$t\.$fr"; - } - } - } - } - } - } - } - return @rc; -} - -sub calc_changes -{ - my ($network,$mask) = @_; - - my @octs = split /\./, $network; - - my ($first,$second,$third,$fourth) = (0,0,0,0); - - my $power = 32 - $mask; - - if ($mask > 24) - { - $fourth = 2**$power - 1; - } - elsif ($mask > 16) - { - $fourth = 255; - $third = 2**($power-8) - 1; - } - elsif ($mask > 8) - { - $fourth = 255; - $third = 255; - $second = 2**($power-16) - 1; - } - elsif ($mask > 0) - { - $fourth = 255; - $third = 255; - $second = 255; - $first = 2**($power-24) - 1; - } - elsif ($mask == 0) - { - $fourth = 255; - $third = 255; - $second = 255; - $first = 255; - } - - return ($first,$second,$third,$fourth); + my $clean_input = join '.', @parts; + $clean_input .= "/$mask"; + my @octets = Net::CIDR::cidr2octets($clean_input); + @rc = @octets; + } + return @rc; } diff --git a/contrib/sendmail/contrib/qtool.8 b/contrib/sendmail/contrib/qtool.8 index fbc90fac466d..0a4cbffee023 100644 --- a/contrib/sendmail/contrib/qtool.8 +++ b/contrib/sendmail/contrib/qtool.8 @@ -6,9 +6,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: qtool.8,v 8.17 2002/01/29 21:55:49 ca Exp $ +.\" $Id: qtool.8,v 8.20 2004/06/28 17:49:41 ca Exp $ .\" -.TH QTOOL 8 "$Date: 2002/01/29 21:55:49 $" +.TH QTOOL 8 "$Date: 2004/06/28 17:49:41 $" .SH NAME qtool \- manipulate sendmail queues @@ -56,7 +56,7 @@ Defaults to /etc/mail/sendmail.cf. Delete all of the messages specified by source. .TP \fB\-e\fP \fIperl_expression\fP -Evalute \fIperl_expression\fP for each queue file as specified +Evaluate \fIperl_expression\fP for each queue file as specified by \fIsource\fP. If \fIperl_expression\fP evaluates to true, then that queue file is moved. See below for more detail on \fIperl_expression\fP. .TP @@ -102,9 +102,6 @@ The size of the control file in bytes. \fBcreation_time\fP The time when the control file was created. .TP -\fBcurrent_delay\fP -Current delay for queue delay algorithm if _FFR_QUEUEDELAY is enabled. -.TP \fBdata_file_name\fP The data file name (deprecated). .TP @@ -173,11 +170,7 @@ Original recipient (ORCPT= parameter). Adjusted priority of message. .TP \fBquarantine_reason\fP -Quarantine reason for quarantined (held) envelopes if _FFR_QUARANTINE is -enabled. -.TP -\fBqueue_delay\fP -Queue delay algorithm if _FFR_QUEUEDELAY is enabled. +Quarantine reason for quarantined (held) envelopes. .TP \fBrecipient\fP Array of character flags followed by colon and recipient name. Flags: diff --git a/contrib/sendmail/contrib/qtool.pl b/contrib/sendmail/contrib/qtool.pl index 08f808bb9914..ba944c2e14eb 100755 --- a/contrib/sendmail/contrib/qtool.pl +++ b/contrib/sendmail/contrib/qtool.pl @@ -3,7 +3,7 @@ ## Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. ## All rights reserved. ## -## $Id: qtool.pl,v 8.27 2002/01/29 21:55:49 ca Exp $ +## $Id: qtool.pl,v 8.28 2002/06/27 23:06:16 gshapiro Exp $ ## use strict; use File::Basename; @@ -485,7 +485,6 @@ sub parse 'E' => 'error_recipient', 'F' => 'flags', 'H' => 'parse_header', - 'G' => 'queue_delay', 'I' => 'inode_number', 'K' => 'next_delivery_time', 'L' => 'content-length', diff --git a/contrib/sendmail/contrib/socketmapClient.pl b/contrib/sendmail/contrib/socketmapClient.pl new file mode 100755 index 000000000000..28fe603980ab --- /dev/null +++ b/contrib/sendmail/contrib/socketmapClient.pl @@ -0,0 +1,67 @@ +#!/usr/bin/perl -w +# +# Contributed by Bastiaan Bakker for SOCKETMAP +# $Id: socketmapClient.pl,v 1.1 2003/05/21 15:36:33 ca Exp $ + +use strict; +use IO::Socket; + +die "usage: $0 [ ...]" if (@ARGV < 3); + +my $connection = shift @ARGV; +my $mapname = shift @ARGV; + +my $sock; + +if ($connection =~ /tcp:(.+):([0-9]*)/) { + $sock = new IO::Socket::INET ( + PeerAddr => $1, + PeerPort => $2, + Proto => 'tcp', + ); +} elsif ($connection =~ /((unix)|(local)):(.+)/) { + $sock = new IO::Socket::UNIX ( + Type => SOCK_STREAM, + Peer => $4 + ); +} else { + die "unrecognized connection specification $connection"; +} + +die "Could not create socket: $!\n" unless $sock; + +while(my $key = shift @ARGV) { + my $request = "$mapname $key"; + netstringWrite($sock, $request); + $sock->flush(); + my $response = netstringRead($sock); + + print "$key => $response\n"; +} + +$sock->close(); + +sub netstringWrite { + my $sock = shift; + my $data = shift; + + print $sock length($data).':'.$data.','; +} + +sub netstringRead { + my $sock = shift; + my $saveSeparator = $/; + $/ = ':'; + my $dataLength = <$sock>; + die "cannot read netstring length" unless defined($dataLength); + chomp $dataLength; + my $data; + if ($sock->read($data, $dataLength) == $dataLength) { + ($sock->getc() eq ',') or die "data misses closing ,"; + } else { + die "received only ".length($data)." of $dataLength bytes"; + } + + $/ = $saveSeparator; + return $data; +} diff --git a/contrib/sendmail/contrib/socketmapServer.pl b/contrib/sendmail/contrib/socketmapServer.pl new file mode 100755 index 000000000000..153e9ef0abee --- /dev/null +++ b/contrib/sendmail/contrib/socketmapServer.pl @@ -0,0 +1,98 @@ +#!/usr/bin/perl -w +# +# Contributed by Bastiaan Bakker for SOCKETMAP +# $Id: socketmapServer.pl,v 1.1 2003/05/21 15:36:33 ca Exp $ + +use strict; +use IO::Socket; + +die "usage: $0 " if (@ARGV < 1); +my $connection = shift @ARGV; +my $sock; + +if ($connection =~ /tcp:(.+):([0-9]*)/) { + $sock = new IO::Socket::INET ( + LocalAddr => $1, + LocalPort => $2, + Proto => 'tcp', + Listen => 32, + ReuseAddr => 1 + ); +} elsif ($connection =~ /((unix)|(local)):(.+)/) { + unlink($4); + $sock = new IO::Socket::UNIX ( + Type => SOCK_STREAM, + Local => $4, + Listen => 32 + ); +} else { + die "unrecognized connection specification $connection"; +} + +while(my $client = $sock->accept()) { + my $childpid = fork(); + if ($childpid) { + $client->close(); + } else { + die "can't fork $!" unless defined($childpid); + $sock->close(); + handleConnection($client); + $client->close(); + exit; + } +} + +$sock->close(); + +sub handleConnection { + my $client = shift; + $client->autoflush(1); + + while(!eof($client)) { + eval { + my $request = netstringRead($client); + my ($mapName, $key) = split(' ', $request); + my $value = mapLookup($mapName, $key); + my $result = (defined($value)) ? "OK $value" : "NOTFOUND"; + netstringWrite($client, $result); + }; + if ($@) { + print STDERR "$@\n"; + last; + } + } +} + +sub mapLookup { + my %mapping = ('bastiaan.bakker@example.com' => 'bastiaan', + 'wolter.eldering@example.com' => 'wolter@other.example.com'); + my $mapName = shift; + my $key = shift; + my $value = ($mapName eq "virtuser") ? $mapping{$key} : undef; + return $value; +} + +sub netstringWrite { + my $sock = shift; + my $data = shift; + + print $sock length($data).':'.$data.','; +} + +sub netstringRead { + my $sock = shift; + my $saveSeparator = $/; + $/ = ':'; + my $dataLength = <$sock>; + die "cannot read netstring length" unless defined($dataLength); + chomp $dataLength; + my $data; + if ($sock->read($data, $dataLength) == $dataLength) { + ($sock->getc() eq ',') or die "data misses closing ,"; + } else { + die "received only ".length($data)." of $dataLength bytes"; + } + + $/ = $saveSeparator; + return $data; +} diff --git a/contrib/sendmail/doc/op/Makefile b/contrib/sendmail/doc/op/Makefile index 09f459234a84..ffa4e76d19d4 100644 --- a/contrib/sendmail/doc/op/Makefile +++ b/contrib/sendmail/doc/op/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 8.14 2002/01/07 22:24:36 gshapiro Exp $ +# $Id: Makefile,v 8.15 2004/07/20 20:25:10 ca Exp $ DIR= smm/08.sendmailop SRCS= op.me @@ -25,6 +25,7 @@ op.ps: ${SRCS} op.txt: ${SRCS} rm -f $@ + @echo "Note: see README file in case of errors." ${PIC} ${SRCS} | ${EQNASCII} | ${ROFFASCII} | ${ULASCII} > $@ op.pdf: op.ps diff --git a/contrib/sendmail/doc/op/README b/contrib/sendmail/doc/op/README new file mode 100644 index 000000000000..9ad8f5a9d677 --- /dev/null +++ b/contrib/sendmail/doc/op/README @@ -0,0 +1,13 @@ +Known Problems with some *roff versions + +If you encounter the error: + +Unknown escape sequence in input: 33, 133 + +when trying to create op.txt then set the GROFF_NO_SGR environment +variable (see grotty(1) man page), e.g., + +csh% setenv GROFF_NO_SGR 1 +sh$ GROFF_NO_SGR=1; export GROFF_NO_SGR + +$Id: README,v 8.1 2004/07/20 20:25:10 ca Exp $ diff --git a/contrib/sendmail/doc/op/op.me b/contrib/sendmail/doc/op/op.me index d34b7b4966b4..098d75cad1d0 100644 --- a/contrib/sendmail/doc/op/op.me +++ b/contrib/sendmail/doc/op/op.me @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1983, 1995 Eric P. Allman. All rights reserved. .\" Copyright (c) 1983, 1993 @@ -9,7 +9,7 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: op.me,v 8.609.2.29 2004/01/11 17:58:24 ca Exp $ +.\" $Id: op.me,v 8.699 2004/06/03 18:29:01 ca Exp $ .\" .\" eqn op.me | pic | troff -me .\" @@ -83,17 +83,17 @@ This documentation is under modification. .sp .r Eric Allman -Gregory Neil Shapiro Claus Assmann +Gregory Neil Shapiro Sendmail, Inc. .sp .de Ve Version \\$2 .. -.Ve $Revision: 8.609.2.29 $ +.Ve $Revision: 8.699 $ .rm Ve .sp -For Sendmail Version 8.12 +For Sendmail Version 8.13 .)l .(f Sendmail is a trademark of Sendmail, Inc. @@ -869,14 +869,16 @@ and causes it to run the queue every half hour. .pp Some people use a more complex startup script, -removing zero length qf files and df files for which there is no qf file. +removing zero length qf/hf/Qf files and df files for which there is no +qf/hf/Qf file. +Note this is not advisable. For example, see Figure 1 for an example of a complex script which does this clean up. .(z .hl #!/bin/sh -# remove zero length qf files -for qffile in qf* +# remove zero length qf/hf/Qf files +for qffile in qf* hf* Qf* do if [ \-r $qffile ] then @@ -903,11 +905,13 @@ do fi fi done -# remove df files with no corresponding qf files +# remove df files with no corresponding qf/hf/Qf files for dffile in df* do qffile=`echo $dffile | sed 's/d/q/'` - if [ \-r $dffile \-a ! \-f $qffile ] + hffile=`echo $dffile | sed 's/d/h/'` + Qffile=`echo $dffile | sed 's/d/Q/'` + if [ \-r $dffile \-a ! \-f $qffile \-a ! \-f $hffile \-a ! \-f $Qffile ] then echo \-n " " > /dev/console mv $dffile `echo $dffile | sed 's/d/D/'` @@ -995,6 +999,31 @@ change the permissions accordingly, e.g., .(b chmod 0600 /var/run/sendmail.pid .)b +Note that as of version 8.13, this file is unlinked when +.i sendmail +exits. +As a result of this change, a script such as the following, +which may have worked prior to 8.13, will no longer work: +.(b +# stop & start sendmail +PIDFILE=/var/run/sendmail.pid +kill `head -1 $PIDFILE` +`tail -1 $PIDFILE` +.)b +because it assumes that the pidfile will still exist even +after killing the process to which it refers. +Below is a script which will work correctly +on both newer and older versions: +.(b +# stop & start sendmail +PIDFILE=/var/run/sendmail.pid +pid=`head -1 $PIDFILE` +cmd=`tail -1 $PIDFILE` +kill $pid +$cmd +.)b +This is just an example script, it does not perform any error checks, +e.g., whether the pidfile exists at all. .sh 3 "Map Files" .pp To prevent local denial of service attacks @@ -1123,9 +1152,7 @@ Levels from 11\-64 are reserved for verbose information that some sites might want. .pp A complete description of the log levels -is given in section -.\" XREF -4.7. +is given in section ``Log Level''. .sh 2 "Dumping State" .pp You can ask @@ -1171,6 +1198,10 @@ messages are queued rather than immediately delivered. One or more addresses are marked as expensive and delivery is postponed until the next queue run or one or more address are marked as held via mailer which uses the hold mailer flag. +.bu +The mail message has been marked as quarantined via a mail filter or +rulesets. +.bu .sh 3 "Queue Groups and Queue Directories" .pp There are one or more mail queues. @@ -1372,7 +1403,7 @@ You can also specify the moved queue directory on the command line but this requires that you do not have queue groups in the configuration file, because those are not subdirectories of the moved directory. -See the section about "Queue Group Declaration" for details; +See the section about ``Queue Group Declaration'' for details; you most likely need a different configuration file to correctly deal with this problem. However, a proper configuration of queue groups should avoid @@ -1388,6 +1419,51 @@ you can remove the directory: .(b rmdir /var/spool/omqueue .)b +.sh 3 "Quarantined Queue Items" +.pp +It is possible to "quarantine" mail messages, +otherwise known as envelopes. +Envelopes (queue files) are stored but not considered for delivery or +display unless the "quarantine" state of the envelope is undone or +delivery or display of quarantined items is requested. +Quarantined messages are tagged by using a different name for the queue +file, 'hf' instead of 'qf', and by adding the quarantine reason to the +queue file. +.pp +Delivery or display of quarantined items can be requested using the +.b \-qQ +flag to +.i sendmail +or +.i mailq . +Additionally, messages already in the queue can be quarantined or +unquarantined using the new +.b \-Q +flag to sendmail. +For example, +.(b +sendmail -Qreason -q[!][I|R|S][matchstring] +.)b +Quarantines the normal queue items matching the criteria specified by the +.b "-q[!][I|R|S][matchstring]" +using the reason given on the +.b \-Q +flag. +Likewise, +.(b +sendmail -qQ -Q[reason] -q[!][I|R|S|Q][matchstring] +.)b +Change the quarantine reason for the quarantined items matching the +criteria specified by the +.b "-q[!][I|R|S|Q][matchstring]" +using the reason given on the +.b \-Q +flag. +If there is no reason, + unquarantine the matching items and make them normal queue items. +Note that the +.b \-qQ +flag tells sendmail to operate on quarantined items instead of normal items. .sh 2 "Disk Based Connection Information" .pp .i Sendmail @@ -2013,7 +2089,7 @@ when this is done to watch what happens: .)b .pp You can also limit the jobs to those with a particular queue identifier, -recipient, sender, or queue group +recipient, sender, quarantine reason, or queue group using one of the queue modifiers. For example, .q \-qRberkeley @@ -2025,6 +2101,9 @@ Similarly, limits the run to particular senders, .q \-qIstring limits it to particular queue identifiers, and +.q \-qQstring +limits it to particular quarantined reasons and only operated on +quarantined queue items, and .q \-qGstring limits it to a particular queue group. The named queue group will be run even if it is set to have 0 runners. @@ -2036,6 +2115,8 @@ or .b R or .b S +or +.b Q to indicate that jobs are limited to not including a particular queue identifier, recipient or sender. For example, @@ -2063,7 +2144,9 @@ You should .b never run a production sendmail server in debug mode. Many of the debug flags will result in debug output being sent over the -SMTP channel. +SMTP channel unless the option +.b \-D +is used. This will confuse many mail programs. However, for testing purposes, it can be useful when sending mail manually via @@ -2622,7 +2705,7 @@ can be further qualified with a tag based on the Precedence: field in the message; they must be one of .q urgent -(indicating a positive non-zero precedence) +(indicating a positive non-zero precedence), .q normal (indicating a zero precedence), or .q non-urgent @@ -2633,6 +2716,13 @@ sets the warning timeout for urgent messages only to one hour. The default if no precedence is indicated is to set the timeout for all precedences. +If the message has a normal (default) precedence +and it is a delivery status notification (DSN), +.b Timeout.queuereturn.dsn +and +.b Timeout.queuewarn.dsn +can be used to give an alternative warn and return time +for DSNs. The value "now" can be used for -O Timeout.queuereturn to return entries immediately during a queue run, @@ -2827,6 +2917,42 @@ For example, if then an attacker needs to open only 10 SMTP sessions to the server, leave them idle for most of the time, and no more connections will be accepted. +If this option is set then the timeouts used in a SMTP session +should be lowered from their default values to +their minimum values as specified in RFC 2821 and listed in +section +.\"XREF +4.1.2. +.sh 2 "Measures against Denial of Service Attacks" +.pp +.i Sendmail +has some built-in measures against simple denial of service (DoS) attacks. +The SMTP server by default slows down if too many bad commands are +issued or if some commands are repeated too often within a session. +Details can be found in the source file +.b sendmail/srvrsmtp.c +by looking for the macro definitions of +.b MAXBADCOMMANDS , +.b MAXNOOPCOMMANDS , +.b MAXHELOCOMMANDS , +.b MAXVRFYCOMMANDS , +and +.b MAXETRNCOMMANDS . +If an SMTP command is issued more often than the corresponding +.b MAXcmdCOMMANDS +value, then the response is delayed exponentially, +starting with a sleep time of one second, +up to a maximum of four minutes (as defined by +.b MAXTIMEOUT ). +If the option +.b MaxDaemonChildren +is set to a value greater than zero, +then this could make a DoS attack even worse since it +keeps a connection open longer than necessary. +Therefore a connection is terminated with a 421 SMTP reply code +if the number of commands exceeds the limit by a factor of two and +.b MAXBADCOMMANDS +is set to a value greater than zero (the default is 25). .sh 2 "Delivery Mode" .pp There are a number of delivery modes that @@ -3229,7 +3355,7 @@ When processing the queue, .i sendmail will try to keep the last few open connections open to avoid startup and shutdown costs. -This only applies to IPC connections. +This only applies to IPC and LPC connections. .pp When trying to open a connection the cache is first searched. @@ -3366,7 +3492,7 @@ Notice: it might be necessary to apply the same (or similar) options to too. .pp Version level 1 configurations (see the section about -Configuration Version Level) +``Configuration Version Level'') turn DNSRCH and DEFNAMES off when doing delivery lookups, but leave them on everywhere else. Version 8 of @@ -3998,6 +4124,16 @@ is defined into the .b $h macro for use in the argv expansion of the specified mailer. +Notice: since the envelope sender address will be used if +a delivery status notification must be send, +i.e., is may specify a recipient, +it is also run through ruleset zero. +If ruleset zero returns a temporary error +.b 4xy +then delivery is deferred. +This can be used to temporarily disable delivery, +e.g., based on the time of the day or other varying parameters. +It should not be used to quarantine e-mails. .pp Rulesets one and two are applied to all sender and recipient addresses respectively. @@ -4028,7 +4164,13 @@ forms all give accept/reject status; falling off the end or returning normally is an accept, and resolving to .b $#error -is a reject. +is a reject or quarantine. +Quarantining is chosen by specifying +.b quarantine +in the second part of the mailer triplet: +.(b +$#error $@ quarantine $: Reason for quarantine +.)b Many of these can also resolve to the special mailer name .b $#discard ; this accepts the message as though it were successful @@ -4252,12 +4394,47 @@ 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. -The option `S' causes the server not to offer STARTTLS. -This is useful to interact with MTAs/MUAs that have broken +Option `S' causes the server not to offer STARTTLS, +which is useful to interact with MTAs/MUAs that have broken STARTTLS implementations by simply not offering it. -`V' turns off the request for a client certificate -during the TLS handshake. -Option `A' and `P' suppress SMTP AUTH and PIPELINING, respectively. +`V' turns off the request for a client certificate during the TLS handshake. +Options `A' and `P' suppress SMTP AUTH and PIPELINING, respectively. +`c' is the equivalent to AuthOptions=p, i.e., +it doesn't permit mechanisms susceptible to simple +passive attack (e.g., PLAIN, LOGIN), unless a security layer is active. +Option `l' requires SMTP AUTH for a connection. +Options 'B', 'D', 'E', and 'X' suppress SMTP VERB, DSN, ETRN, and EXPN, +respectively. +.(b +.ta 9n +A Do not offer AUTH +a Offer AUTH (default) +B Do not offer VERB +b Offer VERB (default) +C Do not require security layer for + plaintext AUTH (default) +c Require security layer for plaintext AUTH +D Do not offer DSN +d Offer DSN (default) +E Do not offer ETRN +e Offer ETRN (default) +L Do not require AUTH (default) +l Require AUTH +P Do not offer PIPELINING +p Offer PIPELINING (default) +S Do not offer STARTTLS +s Offer STARTTLS (default) +V Do not request a client certificate +v Request a client certificate (default) +X Do not offer EXPN +x Offer EXPN (default) +.)b +Note: the entries marked as ``(default)'' may require that some +configuration has been made, e.g., SMTP AUTH is only available if +properly configured. +Moreover, many options can be changed on a global basis via other +settings as explained in this document, e.g., via DaemonPortOptions. +.pp The ruleset may return `$#temp' to indicate that there is a temporary problem determining the correct features, e.g., if a map is unavailable. In that case, the SMTP server issues a temporary failure and does not @@ -4315,8 +4492,32 @@ The ruleset should return .b $# followed by the name of a queue group. If the return value starts with anything else it is silently ignored. -See the section about Queue Groups and Queue Directories +See the section about ``Queue Groups and Queue Directories'' for further information. +.sh 4 "greet_pause" +.pp +The +.i greet_pause +ruleset is used to specify the amount of time to pause before sending the +initial SMTP 220 greeting. +If any traffic is received during that pause, an SMTP 554 rejection +response is given instead of the 220 greeting and all SMTP commands are +rejected during that connection. +This helps protect sites from open proxies and SMTP slammers. +The ruleset should return +.b $# +followed by the number of milliseconds (thousandths of a second) to +pause. +If the return value starts with anything else or is not a number, +it is silently ignored. +Note: this ruleset is not invoked (and hence the feature is disabled) +when the smtps (SMTP over SSL) is used, i.e., +the +.i s +modifier is set for the daemon via +.b DaemonPortOptions , +because in this case the SSL handshake is performed before +the greeting is sent. .sh 3 "IPC mailers" .pp Some special processing occurs @@ -4582,7 +4783,9 @@ Set from the .b \-p command line flag or by the SMTP server code. .ip $t -A numeric representation of the current time. +A numeric representation of the current time in the format YYYYMMDDHHmm +(4 digit year 1900-9999, 2 digit month 01-12, 2 digit day 01-31, +2 digit hours 00-23, 2 digit minutes 00-59). .ip $u The recipient user. .ip $v @@ -4655,6 +4858,8 @@ used for a TLS connection. The IP address of the SMTP client. IPv6 addresses are tagged with "IPv6:" before the address. Defined in the SMTP server only. +.ip ${client_connections} +The number of open connections in the SMTP server for the client IP address. .ip ${client_name} The host name of the SMTP client. This may be the client's bracketed IP address @@ -4670,6 +4875,17 @@ See also .ip ${client_port} The port number of the SMTP client. Defined in the SMTP server only. +.ip ${client_ptr} +The result of the PTR lookup for the client IP address. +Note: this is the same as +.b ${client_name} +if and only if +.b ${client_resolve} +is OK. +Defined in the SMTP server only. +.ip ${client_rate} +The number of incoming connections for the client IP address +over the time interval specified by ConnectionRateWindowSize. .ip ${client_resolve} Holds the result of the resolve call for .b ${client_name} . @@ -4804,6 +5020,8 @@ The mailer from the resolved triple of the address given for the .sm "SMTP MAIL" command. Defined in the SMTP server only. +.ip ${msg_id} +The value of the Message-Id: header. .ip ${msg_size} The value of the SIZE= parameter, i.e., usually the size of the message (in an ESMTP dialogue), @@ -4811,6 +5029,8 @@ before the message has been collected, thereafter the message size as computed by .i sendmail (and can be used in check_compat). +.ip ${nbadrcpts} +The number of bad recipients for a single message. .ip ${nrcpts} The number of validated recipients for a single message. Note: since recipient validation happens after @@ -4823,6 +5043,9 @@ The number of delivery attempts. The current operation mode (from the .b \-b flag). +.ip ${quarantine} +The quarantine reason for the envelope, +if it is quarantined. .ip ${queue_interval} The queue run interval given by the .b \-q @@ -4853,9 +5076,17 @@ The address of the server of the current outgoing SMTP connection. For LMTP delivery the macro is set to the name of the mailer. .ip ${server_name} The name of the server of the current outgoing SMTP or LMTP connection. +.ip ${time} +The output of the +.i time (3) +function, i.e., the number of seconds since 0 hours, 0 minutes, +0 seconds, January 1, 1970, Coordinated Universal Time (UTC). .ip ${tls_version} The TLS/SSL version used for the connection, e.g., TLSv1, SSLv3, SSLv2; defined after STARTTLS has been used. +.ip ${total_rate} +The total number of incoming connections over the time interval specified +by ConnectionRateWindowSize. .ip ${verify} The result of the verification of the presented cert; only defined after STARTTLS has been used. @@ -5373,6 +5604,11 @@ This is intended to work around some stupid versions of /bin/mail that require a blank line, but do not provide it themselves. It would not normally be used on network mail. +.ip B +Strip leading backslashes (\e) off of the address; +this is a subset of the functionality of the +.b s +flag. .ip c Do not include comments in addresses. This should only be used if you have to work around @@ -5616,6 +5852,9 @@ option. This is required to get .q \&.forward capability. +.ip W +Ignore long term host status information (see Section +"Persistent Host Status Information"). .ip x\(dg This mailer wants a .q Full-Name: @@ -5735,6 +5974,9 @@ exit status to be returned if the LHS matches. This mailer is only functional in rulesets 0, 5, or one of the check_* rulesets. +The host field can also contain the special token +.b quarantine +which instructs sendmail to quarantine the current message. .pp The mailer with the special name .q discard @@ -5977,7 +6219,7 @@ is called for the specified .i Header , and can return .b $#error -to reject the message or +to reject or quarantine the message or .b $#discard to discard the message (as with the other @@ -6209,6 +6451,8 @@ d don't permit mechanisms susceptible to passive dictionary attack. f require forward secrecy between sessions (breaking one won't help break next). +m require mechanisms which provide mutual authentication + (only available if using Cyrus SASL v2 or later). p don't permit mechanisms susceptible to simple passive attack (e.g., PLAIN, LOGIN), unless a security layer is active. @@ -6225,6 +6469,12 @@ provided by STARTTLS) is already active. The options 'a', 'c', 'd', 'f', 'p', and 'y' refer to properties of the selected SASL mechanisms. Explanations of these properties can be found in the Cyrus SASL documentation. +.ip AuthRealm +[no short name] +The authentication realm that is passed to the Cyrus SASL library. +If no realm is specified, +.b $j +is used. .ip BadRcptThrottle=\fIN\fP [no short name] If set and the specified number of recipients in a single SMTP @@ -6384,6 +6634,11 @@ incoming connections in a one second period per daemon. This is intended to flatten out peaks and allow the load average checking to cut in. Defaults to zero (no limits). +.ip ConnectionRateWindowSize=\fIN\fP +[no short name] +Define the length of the interval for which +the number of incoming connections is maintained. +The default is 60 seconds. .ip ControlSocketName=\fIname\fP [no short name] Name of the control socket for daemon management. @@ -6404,6 +6659,13 @@ the free disk space (in blocks) of the queue directory, and the load average of the machine expressed as an integer. If not set, no control socket will be available. Solaris and pre-4.4BSD kernel users should see the note in sendmail/README . +.ip CRLFile=\fIname\fP +[no short name] +Name of file that contains certificate +revocation status, useful for X.509v3 authentication. +CRL checking requires at least OpenSSL version 0.9.7. +Note: if a CRLFile is specified but the file is unusable, +STARTTLS is disabled. .ip DHParameters File with DH parameters for STARTTLS. This is only required if a ciphersuite containing DSA/DH is used. @@ -6425,6 +6687,7 @@ Name User-definable name for the daemon (defaults to "Daemon#") Port Name/number of listening port (defaults to "smtp") Addr Address mask (defaults INADDR_ANY) Family Address family (defaults to INET) +InputMailFilters List of input mail filters for the daemon Listen Size of listen queue (defaults to 10) Modifier Options (flags) for the daemon SndBufSize Size of TCP send buffer @@ -6444,6 +6707,13 @@ IPv6 users who wish to also accept IPv6 connections should add additional Family=inet6 .b DaemonPortOptions lines. +The +.i InputMailFilters +key overrides the default list of input mail filters listed in the +.b InputMailFilters +option. +If multiple input mail filters are required, they must be separated +by semicolons (not commas). .i Modifier can be a sequence (without any delimiters) of the following characters: @@ -6453,6 +6723,7 @@ a always require authentication b bind to interface through which mail has been received c perform hostname canonification (.cf) f require fully qualified hostname (.cf) +s Run smtps (SMTP over SSL) instead of smtp u allow unqualified addresses (.cf) A disable AUTH (overrides 'a' modifier) C don't perform hostname canonification @@ -6839,6 +7110,13 @@ This is intended to be used by sites with poor network connectivity. Messages which are undeliverable due to temporary address failures (e.g., DNS failure) also go to the FallbackMXhost. +.ip FallBackSmartHost=\fIhostname\fP +If specified, the +.i FallBackSmartHost +will be used in a last-ditch effort for each host. +This is intended to be used by sites with "fake internal DNS", +e.g., a company whose DNS accurately reflects the world +inside that company's domain but not outside. .ip FastSplit [no short name] If set to a value greater than zero (the default is one), @@ -7124,6 +7402,7 @@ connect After session connection start helo After HELO command envfrom After MAIL FROM command envrcpt After RCPT TO command +eom After DATA command and terminating ``.'' .)b By default the lists of macros are empty. Example: @@ -7224,7 +7503,9 @@ Filename of the pid file. (default is _PATH_SENDMAILPID). The .i filename -is macro-expanded before it is opened. +is macro-expanded before it is opened, and unlinked when +.i sendmail +exits. .ip PostmasterCopy=\fIpostmaster\fP [P] If set, @@ -7395,6 +7676,8 @@ Legal values are (to order randomly), .q modification (to order by the modification time of the qf file (older entries first)), +.q none +(to not order), and .q priority (to order by message priority). @@ -7470,6 +7753,20 @@ which return SERVFAIL (a temporary failure) on T_AAAA (IPv6) lookups. Notice: it might be necessary to apply the same (or similar) options to .i submit.cf too. +.ip RequiresDirfsync +[no short name] +This option can be used to override the compile time flag +.b REQUIRES_DIR_FSYNC +at runtime by setting it to +.sm false . +If the compile time flag is not set, the option is ignored. +The flag turns on support for file systems that require to call +.i fsync() +for a directory if the meta-data in it has been changed. +This should be turned on at least for older versions of ReiserFS; +it is enabled by default for Linux. +According to some information this flag is not needed +anymore for kernel 2.4.16 and newer. .ip RrtImpliesDsn [R] If this option is set, a @@ -7541,6 +7838,10 @@ refuse incoming SMTP connections. Defaults to 12 multiplied by the number of processors online on the system (if that can be determined). +.ip RejectLogInterval=\fItimeout\fP +[no short name] +Log interval when refusing connections for this long +(default: 3h). .ip RetryFactor=\fIfact\fP [Z] The @@ -7706,7 +8007,7 @@ It can be printed using the program. .ip SuperSafe [s] -This option can be set to True, False, or Interactive. +This option can be set to True, False, Interactive, or PostMilter. If set to True, .i sendmail will be super-safe when running things, @@ -7724,6 +8025,14 @@ be used together with .b DeliveryMode=i . It skips some synchronization calls which are effectively doubled in the code execution path for this mode. +If set to PostMilter, +.i sendmail +defers synchronizing the queue file until any milters have +signaled acceptance of the message. +PostMilter is useful only when +.i sendmail +is running as an SMTP server; in all other situations it +acts the same as True. .ip TLSSrvOptions [no short name] List of options for SMTP STARTTLS for the server @@ -7852,6 +8161,19 @@ should .i never be set in the configuration file; it is intended for command line use only. +Note that the use of option +.b Verbose +can cause authentication information to leak, if you use a +sendmail client to authenticate to a server. +If the authentication mechanism uses plain text passwords +(as with LOGIN or PLAIN), +then the password could be compromised. +To avoid this, do not install sendmail set-user-ID root, +and disable the +.b VERB +SMTP command with a suitable +.b PrivacyOptions +setting. .ip XscriptFileBufferSize=\fIthreshold\fP [no short name] Set the @@ -8487,6 +8809,68 @@ Scheck_etrn R$* $: $(comp l $@ $&{load_avg} $@ 7 $) $1 RFALSE $# error \&... .)b +.ip socket +The socket map uses a simple request/reply protocol over TCP or UNIX domain +sockets to query an external server. +Both requests and replies are text based and encoded as netstrings, +i.e., a string "hello there" becomes: +.(b +11:hello there, +.)b +Note: neither requests nor replies end with CRLF. + +The request consists of the database map name and the lookup key separated +by a space character: + +.(b + ' ' +.)b + +The server responds with a status indicator and the result (if any): + +.(b + ' ' +.)b + +The status indicator is one of the following upper case words: +.(b +.ta 9n +OK the key was found, result contains the looked up value +NOTFOUND the key was not found, the result is empty +TEMP a temporary failure occured +TIMEOUT a timeout occured on the server side +PERM a permanent failure occured +.)b + +In case of errors (status TEMP, TIMEOUT or PERM) the result field may +contain an explanatory message. + +Example replies: +.(b +31:OK resolved.address@example.com, +.)b + +in case of a successful lookup, or: +.(b +8:NOTFOUND, +.)b + +in case the key was not found, or: +.(b +55:TEMP this text explains that we had a temporary failure, +.)b + +in case of a failure. + +The socket map uses the same syntax as milters +(see Section "X \*- Mail Filter (Milter) Definitions") +to specify the remote endpoint, e.g., +.(b +Ksocket mySocketMap inet:12345@127.0.0.1 +.)b + +If multiple socket maps define the same remote endpoint, they will share +a single connection to this endpoint. .pp Most of these accept as arguments the same optional flags and a filename @@ -8578,6 +8962,8 @@ attributes to be returned; multiple attributes can be separated by commas. If not specified, all attributes found in the match will be returned. +The attributes listed can also include a type and one or more +objectClass values for matching as described in the LDAP section. .ip "\-z\fIdelim\fP" The column delimiter (for text lookups). It can be a single character or one of the special strings @@ -8678,10 +9064,40 @@ Some LDAP libraries allow you to specify multiple, space-separated hosts for redundancy. In addition, each of the hosts listed can be followed by a colon and a port number to override the default LDAP port. -.ip "\-b\fIbase\fP" -LDAP search base. .ip "\-p\fIport\fP" LDAP service port. +.ip "\-H \fILDAPURI\fP" +Use the specified LDAP URI instead of specifying the hostname and port +separately with the the +.b \-h +and +.b \-p +options shown above. +For example, +.(b +-h server.example.com -p 389 -b dc=example,dc=com +.)b +is equivalent to +.(b +-H ldap://server.example.com:389/dc=example,dc=com +.)b +If the LDAP library supports it, +the LDAP URI format however can also request LDAP over SSL by using +.b ldaps:// +instead of +.b ldap:// . +For example: +.(b +O LDAPDefaultSpec=-H ldaps://ldap.example.com/dc=example,dc=com +.)b +Similarly, if the LDAP library supports it, +It can also be used to specify a UNIX domain socket using +.b ldapi:// : +.(b +O LDAPDefaultSpec=-H ldapi://socketfile/dc=example,dc=com +.)b +.ip "\-b\fIbase\fP" +LDAP search base. .ip "\-l\fItimelimit\fP" Time limit for LDAP queries. .ip "\-Z\fIsizelimit\fP" @@ -8705,6 +9121,14 @@ or the name of the Kerberos ticket file for Force LDAP searches to only succeed if a single match is found. If multiple values are found, the search is treated as if no match was found. +.ip "\-w\fIversion\fP" +Set the LDAP API/protocol version to use. +The default depends on the LDAP client libraries in use. +For example, +.b "\-w 3" +will cause +.i sendmail +to use LDAPv3 when communicating with the LDAP server. .pp The .i dbm @@ -8777,8 +9201,9 @@ where is the symbolic name of the queue group under which it can be referenced in various places and the -.q field=name +.q field=value pairs define attributes of the queue group. +The name must only consist of alphanumeric characters. Fields are: .ip Flags Flags for this queue group. @@ -9934,6 +10359,107 @@ if you wanted to generalize .b $] lookups. We now recommend that you create a new keyed map instead. +.sh 2 "LDAP" +.pp +In this section we assume that +.i sendmail +has been compiled with support for LDAP. +.sh 3 "LDAP Recursion" +.pp +LDAP Recursion allows you to add types to the search attributes on an +LDAP map specification. +The syntax is: +.ip "\-v \fIATTRIBUTE\fP[:\fITYPE\fP[:\fIOBJECTCLASS\fP[|\fIOBJECTCLASS\fP|...]]] +.pp +The new \fITYPE\fPs are: +.nr ii 1i +.ip NORMAL +This attribute type specifies the attribute to add to the results string. +This is the default. +.ip DN +Any matches for this attribute are expected to have a value of a +fully qualified distinguished name. +.i sendmail +will lookup that DN and apply the attributes requested to the +returned DN record. +.ip FILTER +Any matches for this attribute are expected to have a value of an +LDAP search filter. +.i sendmail +will perform a lookup with the same parameters as the original +search but replaces the search filter with the one specified here. +.ip URL +Any matches for this attribute are expected to have a value of an LDAP URL. +.i sendmail +will perform a lookup of that URL and use the results from the attributes +named in that URL. +Note however that the search is done using the current LDAP connection, +regardless of what is specified as the scheme, LDAP host, and LDAP +port in the LDAP URL. +.lp +Any untyped attributes are considered +.sm NORMAL +attributes as described above. +.pp +The optional \fIOBJECTCLASS\fP (| separated) list contains the +objectClass values for which that attribute applies. +If the list is given, +the attribute named will only be used if the LDAP record being returned is a +member of that object class. +Note that if these new value attribute \fITYPE\fPs are used in an +AliasFile +option setting, it will need to be double quoted to prevent +.i sendmail +from misparsing the colons. +.pp +Note that LDAP recursion attributes which do not ultimately point to an +LDAP record are not considered an error. +.sh 4 "Example" +.pp +Since examples usually help clarify, here is an example which uses all +four of the new types: +.(b +O LDAPDefaultSpec=-h ldap.example.com -b dc=example,dc=com + +Kexample ldap + -z, + -k (&(objectClass=sendmailMTAAliasObject)(sendmailMTAKey=%0)) + -v sendmailMTAAliasValue,mail:NORMAL:inetOrgPerson, + uniqueMember:DN:groupOfUniqueNames, + sendmailMTAAliasSearch:FILTER:sendmailMTAAliasObject, + sendmailMTAAliasURL:URL:sendmailMTAAliasObject +.)b +.pp +That definition specifies that: +.bu +Any value in a +.sm sendmailMTAAliasValue +attribute will be added to the result string regardless of object class. +.bu +The +.sm mail +attribute will be added to the result string if +the LDAP record is a member of the +.sm inetOrgPerson +object class. +.bu +The +.sm uniqueMember +attribute is a recursive attribute, used only in +.sm groupOfUniqueNames +records, and should contain an LDAP DN pointing to another LDAP record. +The desire here is to return the +.sm mail +attribute from those DNs. +.bu +The +.sm sendmailMTAAliasSearch +attribute and +.sm sendmailMTAAliasURL +are both used only if referenced in a +.sm sendmailMTAAliasObject . +They are both recursive, the first for a new LDAP search string and the +latter for an LDAP URL. .sh 2 "STARTTLS" .pp In this section we assume that @@ -9991,27 +10517,6 @@ To allow for automatic startup of sendmail, private keys must be stored unencrypted. The keys are only protected by the permissions of the file system. Never make a private key available to a third party. -.sh 3 "Encoding of STARTTLS related Macros" -.pp -Macros that contain STARTTLS related data which comes from outside -sources, e.g., all macros containing information from certificates, -are encoded to avoid problems with non-printable or special characters. -The latter are '<', '>', '(', ')', '"', '+', and ' '. -All of these characters are replaced by their value in hexadecimal -with a leading '+'. -For example: -.(b -/C=US/ST=California/O=endmail.org/OU=private/CN=Darth Mail (Cert)/ -Email=darth+cert@endmail.org -.)b -is encoded as: -.(b -/C=US/ST=California/O=endmail.org/OU=private/ -CN=Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org -.)b -(line breaks have been inserted for readability). -The macros which are subject to this encoding are -{cert_subject}, {cert_issuer}, {cn_subject}, and {cn_issuer}. .sh 3 "PRNG for STARTTLS" .pp STARTTLS requires a strong pseudo random number generator (PRNG) @@ -10059,6 +10564,29 @@ generation of (temporary) keys. Please see the OpenSSL documentation or other sources for further information about certificates, their creation and their usage, the importance of a good PRNG, and other aspects of TLS. +.sh 2 "Encoding of STARTTLS and AUTH related Macros" +.pp +Macros that contain STARTTLS and AUTH related data which comes from outside +sources, e.g., all macros containing information from certificates, +are encoded to avoid problems with non-printable or special characters. +The latter are '\\', '<', '>', '(', ')', '"', '+', and ' '. +All of these characters are replaced by their value in hexadecimal +with a leading '+'. +For example: +.(b +/C=US/ST=California/O=endmail.org/OU=private/CN=Darth Mail (Cert)/ +Email=darth+cert@endmail.org +.)b +is encoded as: +.(b +/C=US/ST=California/O=endmail.org/OU=private/ +CN=Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org +.)b +(line breaks have been inserted for readability). +The macros which are subject to this encoding are +{cert_subject}, {cert_issuer}, {cn_subject}, {cn_issuer}, +as well as +{auth_authen} and {auth_author}. .sh 1 "ACKNOWLEDGEMENTS" .pp I've worked on @@ -10193,6 +10721,10 @@ Use a different configuration file. .i Sendmail runs as the invoking user (rather than root) when this flag is specified. +.ip "\-D \fIlogfile\fP" +Send debugging output to the indicated +.i logfile +instead of stdout. .ip \-d\fIlevel\fP Set debugging level. .ip "\-f\ \fIaddr\fP" @@ -10340,10 +10872,12 @@ can be to limit based on queue identifier, .b R to limit based on recipient, -or .b S -to limit based on sender. -A particular queued job is accepted if one of the corresponding addresses +to limit based on sender, +or +.b Q +to limit based on quarantine reason for quarantined jobs. +A particular queued job is accepted if one of the corresponding attributes contains the indicated .i string . The optional ! character negates the condition tested. @@ -10355,6 +10889,12 @@ with items with the same key letter together, and items with different key letters .q and'ed together. +.ip "\-Q[reason]" +Quarantine a normal queue items with the given reason or +unquarantine quarantined queue items if no reason is given. +This should only be used with some sort of item matching using +.b \-q[!]\fIXstring\fP +as described above. .ip "\-R ret" What information you want returned if the message bounces; .i ret @@ -10413,7 +10953,7 @@ running as daemon. .pp This appendix describes the format of the queue files. These files live in a queue directory. -The individual qf, df, and xf files +The individual qf, hf, Qf, df, and xf files may be stored in separate .i qf/ , .i df/ , @@ -10462,6 +11002,8 @@ The types are: .ip qf The queue control file. This file contains the information necessary to process the job. +.ip hf +The same as a queue control file, but for a quarantined queue job. .ip df The data file. The message body (excluding the header) is kept in this file. @@ -10501,9 +11043,7 @@ file to .b qf and send it again. .pp -The -.b qf -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. The lines are as follows: .ip V @@ -10537,6 +11077,8 @@ will be flagged so that deliveries will be run as the .i aliasname is the name of the alias that expanded to this address (used for printing messages). +.ip q +The quarantine reason for quarantined queue items. .ip Q The ``original recipient'', specified by the ORCPT= field in an ESMTP transaction. @@ -10768,7 +11310,7 @@ replace it with a blank sheet for double-sided output. .\".sz 10 .\"Eric Allman .\".sp -.\"Version $Revision: 8.609.2.29 $ +.\"Version $Revision: 8.699 $ .\".ce 0 .bp 3 .ce diff --git a/contrib/sendmail/editmap/Makefile.m4 b/contrib/sendmail/editmap/Makefile.m4 index 566b6e2bbb6c..d9c611ca4fdc 100644 --- a/contrib/sendmail/editmap/Makefile.m4 +++ b/contrib/sendmail/editmap/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 1.4.6.1 2002/06/21 21:58:27 ca Exp $ +dnl $Id: Makefile.m4,v 1.5 2002/06/21 22:01:30 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/editmap/editmap.8 b/contrib/sendmail/editmap/editmap.8 index deb2f672ec8e..9b0b3ad13e6f 100644 --- a/contrib/sendmail/editmap/editmap.8 +++ b/contrib/sendmail/editmap/editmap.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" .\" By using this file, you agree to the terms and conditions set @@ -6,9 +6,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: editmap.8,v 1.8.4.1 2003/03/15 23:38:57 gshapiro Exp $ +.\" $Id: editmap.8,v 1.9 2003/02/01 17:07:42 ca Exp $ .\" -.TH EDITMAP 8 "$Date: 2003/03/15 23:38:57 $" +.TH EDITMAP 8 "$Date: 2003/02/01 17:07:42 $" .SH NAME .B editmap \- query and edit single records in database maps for sendmail diff --git a/contrib/sendmail/include/libmilter/mfapi.h b/contrib/sendmail/include/libmilter/mfapi.h index 9a7e7d8b17b3..b226a1a408b7 100644 --- a/contrib/sendmail/include/libmilter/mfapi.h +++ b/contrib/sendmail/include/libmilter/mfapi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -7,7 +7,7 @@ * the sendmail distribution. * * - * $Id: mfapi.h,v 8.44.2.4 2003/10/20 21:51:49 msk Exp $ + * $Id: mfapi.h,v 8.59 2004/07/07 21:41:31 ca Exp $ */ /* @@ -17,14 +17,23 @@ #ifndef _LIBMILTER_MFAPI_H # define _LIBMILTER_MFAPI_H 1 -# include +#ifndef SMFI_VERSION +# define SMFI_VERSION 2 /* version number */ +#endif /* ! SMFI_VERSION */ +# include # include -# include "libmilter/mfdef.h" + +#include "libmilter/mfdef.h" # define LIBMILTER_API extern +/* Only need to export C interface if used by C++ source code */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + #ifndef _SOCK_ADDR # define _SOCK_ADDR struct sockaddr #endif /* ! _SOCK_ADDR */ @@ -66,6 +75,19 @@ typedef int sfsistat; # endif /* __STDC__ */ #endif /* __P */ +#if SM_CONF_STDBOOL_H +# include +#else /* SM_CONF_STDBOOL_H */ +# ifndef __cplusplus +# ifndef bool +# ifndef __bool_true_false_are_defined +typedef int bool; +# define __bool_true_false_are_defined 1 +# endif /* ! __bool_true_false_are_defined */ +# endif /* bool */ +# endif /* ! __cplusplus */ +#endif /* SM_CONF_STDBOOL_H */ + /* ** structure describing one milter */ @@ -105,11 +127,19 @@ struct smfiDesc /* connection cleanup */ sfsistat (*xxfi_close) SM__P((SMFICTX *)); + +#if SMFI_VERSION > 2 + /* any unrecognized or unimplemented command filter */ + sfsistat (*xxfi_unknown) SM__P((SMFICTX *, char *)); +#endif /* SMFI_VERSION > 2 */ + +#if SMFI_VERSION > 3 + /* any unrecognized or unimplemented command filter */ + sfsistat (*xxfi_data) SM__P((SMFICTX *)); +#endif /* SMFI_VERSION > 3 */ }; -#if _FFR_SMFI_OPENSOCKET LIBMILTER_API int smfi_opensocket __P((bool)); -#endif /* _FFR_SMFI_OPENSOCKET */ LIBMILTER_API int smfi_register __P((struct smfiDesc)); LIBMILTER_API int smfi_main __P((void)); LIBMILTER_API int smfi_setbacklog __P((int)); @@ -117,8 +147,9 @@ LIBMILTER_API int smfi_setdbg __P((int)); LIBMILTER_API int smfi_settimeout __P((int)); LIBMILTER_API int smfi_setconn __P((char *)); LIBMILTER_API int smfi_stop __P((void)); - -#define SMFI_VERSION 2 /* version number */ +#if _FFR_MAXDATASIZE +LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t)); +#endif /* _FFR_MAXDATASIZE */ /* ** What the filter might do -- values to be ORed together for @@ -132,9 +163,7 @@ LIBMILTER_API int smfi_stop __P((void)); #define SMFIF_ADDRCPT 0x00000004L /* filter may add recipients */ #define SMFIF_DELRCPT 0x00000008L /* filter may delete recipients */ #define SMFIF_CHGHDRS 0x00000010L /* filter may change/delete headers */ -#if _FFR_QUARANTINE -# define SMFIF_QUARANTINE 0x00000020L /* filter may quarantine envelope */ -#endif /* _FFR_QUARANTINE */ +#define SMFIF_QUARANTINE 0x00000020L /* filter may quarantine envelope */ /* ** Continue processing message/connection. @@ -230,6 +259,16 @@ extern sfsistat xxfi_envrcpt __P((SMFICTX *, char **)); ** Later arguments are the ESMTP arguments. */ +/* unknown command filter */ + +extern sfsistat *xxfi_unknown __P((SMFICTX *, char *)); + +/* +** xxfi_unknown(ctx, arg) Invoked when SMTP command is not recognized or not +** implemented. +** char *arg; Null-terminated SMTP command +*/ + /* header filter */ extern sfsistat xxfi_header __P((SMFICTX *, char *, char *)); @@ -311,14 +350,12 @@ LIBMILTER_API char * smfi_getsymval __P((SMFICTX *, char *)); LIBMILTER_API int smfi_setreply __P((SMFICTX *, char *, char *, char *)); -#if _FFR_MULTILINE /* ** Alternatively, smfi_setmlreply can be called if a multi-line SMTP reply ** is needed. */ LIBMILTER_API int smfi_setmlreply __P((SMFICTX *, const char *, const char *, ...)); -#endif /* _FFR_MULTILINE */ /* ** Set the specific reply code to be used in response to the active @@ -342,10 +379,9 @@ LIBMILTER_API int smfi_setmlreply __P((SMFICTX *, const char *, const char *, .. LIBMILTER_API int smfi_addheader __P((SMFICTX *, char *, char *)); /* -** Add a header to the message. This header is not passed to other -** filters. It is not checked for standards compliance; the mail filter -** must ensure that no protocols are violated as a result of adding this -** header. +** Add a header to the message. It is not checked for standards +** compliance; the mail filter must ensure that no protocols are violated +** as a result of adding this header. ** ** SMFICTX *ctx; Opaque context structure ** char *headerf; Header field name @@ -365,6 +401,19 @@ LIBMILTER_API int smfi_chgheader __P((SMFICTX *, char *, int, char *)); ** char *headerv; New header field value (empty for delete header) */ +LIBMILTER_API int smfi_insheader __P((SMFICTX *, int, char *, char *)); + +/* +** Insert a header into the message. It is not checked for standards +** compliance; the mail filter must ensure that no protocols are violated +** as a result of adding this header. +** +** SMFICTX *ctx; Opaque context structure +** int idx; index into the header list where the insertion should happen +** char *headerh; Header field name +** char *headerv; Header field value +*/ + LIBMILTER_API int smfi_addrcpt __P((SMFICTX *, char *)); /* @@ -413,7 +462,6 @@ LIBMILTER_API int smfi_replacebody __P((SMFICTX *, unsigned char *, int)); ** xxfi_abort is called. This can be used to reset state. */ -#if _FFR_QUARANTINE /* ** Quarantine an envelope ** @@ -422,7 +470,6 @@ LIBMILTER_API int smfi_replacebody __P((SMFICTX *, unsigned char *, int)); */ LIBMILTER_API int smfi_quarantine __P((SMFICTX *ctx, char *reason)); -#endif /* _FFR_QUARANTINE */ /* ** Connection-private data (specific to an SMTP connection) can be @@ -441,5 +488,8 @@ LIBMILTER_API int smfi_setpriv __P((SMFICTX *, void *)); LIBMILTER_API void *smfi_getpriv __P((SMFICTX *)); +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif /* ! _LIBMILTER_MFAPI_H */ diff --git a/contrib/sendmail/include/libmilter/mfdef.h b/contrib/sendmail/include/libmilter/mfdef.h index ab543e826ca2..3261d4bb2826 100644 --- a/contrib/sendmail/include/libmilter/mfdef.h +++ b/contrib/sendmail/include/libmilter/mfdef.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -7,7 +7,7 @@ * the sendmail distribution. * * - * $Id: mfdef.h,v 8.11.2.1 2002/11/11 23:22:28 ca Exp $ + * $Id: mfdef.h,v 8.21 2004/07/07 21:41:31 ca Exp $ */ /* @@ -21,14 +21,11 @@ # define MILTER_LEN_BYTES 4 /* length of 32 bit integer in bytes */ # define MILTER_OPTLEN (MILTER_LEN_BYTES * 3) /* length of options */ # define MILTER_CHUNK_SIZE 65535 /* body chunk size */ +# define MILTER_MAX_DATA_SIZE 65535 /* default milter command data limit */ /* These apply to SMFIF_* flags */ #define SMFI_V1_ACTS 0x0000000FL /* The actions of V1 filter */ -#if _FFR_QUARANTINE -# define SMFI_V2_ACTS 0x0000003FL /* The actions of V2 filter */ -#else /* _FFR_QUARANTINE */ -# define SMFI_V2_ACTS 0x0000001FL /* The actions of V2 filter */ -#endif /* _FFR_QUARANTINE */ +#define SMFI_V2_ACTS 0x0000003FL /* The actions of V2 filter */ #define SMFI_CURR_ACTS SMFI_V2_ACTS /* The current version */ /* address families */ @@ -50,6 +47,12 @@ # define SMFIC_OPTNEG 'O' /* Option negotiation */ # define SMFIC_QUIT 'Q' /* QUIT */ # define SMFIC_RCPT 'R' /* RCPT to */ +# if SMFI_VERSION > 3 +# define SMFIC_DATA 'T' /* DATA */ +# endif /* SMFI_VERSION > 3 */ +# if SMFI_VERSION > 2 +# define SMFIC_UNKNOWN 'U' /* Any unknown command */ +# endif /* SMFI_VERSION > 2 */ /* actions (replies) */ # define SMFIR_ADDRCPT '+' /* add recipient */ @@ -62,14 +65,11 @@ # define SMFIR_PROGRESS 'p' /* progress */ # define SMFIR_REJECT 'r' /* reject */ # define SMFIR_TEMPFAIL 't' /* tempfail */ -# if _FFR_MILTER_421 -# define SMFIR_SHUTDOWN '4' /* 421: shutdown (internal to MTA) */ -# endif /* _FFR_MILTER_421 */ +# define SMFIR_SHUTDOWN '4' /* 421: shutdown (internal to MTA) */ # define SMFIR_ADDHEADER 'h' /* add header */ +# define SMFIR_INSHEADER 'i' /* insert header */ # define SMFIR_REPLYCODE 'y' /* reply code etc */ -# if _FFR_QUARANTINE -# define SMFIR_QUARANTINE 'q' /* quarantine */ -# endif /* _FFR_QUARANTINE */ +# define SMFIR_QUARANTINE 'q' /* quarantine */ /* What the MTA can send/filter wants in protocol */ # define SMFIP_NOCONNECT 0x00000001L /* MTA should not send connect info */ @@ -79,9 +79,16 @@ # define SMFIP_NOBODY 0x00000010L /* MTA should not send body */ # define SMFIP_NOHDRS 0x00000020L /* MTA should not send headers */ # define SMFIP_NOEOH 0x00000040L /* MTA should not send EOH */ +# if _FFR_MILTER_NOHDR_RESP +# define SMFIP_NOHREPL 0x00000080L /* No reply for headers */ +# endif /* _FFR_MILTER_NOHDR_RESP */ # define SMFI_V1_PROT 0x0000003FL /* The protocol of V1 filter */ # define SMFI_V2_PROT 0x0000007FL /* The protocol of V2 filter */ -# define SMFI_CURR_PROT SMFI_V2_PROT /* The current version */ +# if _FFR_MILTER_NOHDR_RESP +# define SMFI_CURR_PROT 0x000000FFL /* The current version */ +# else /* _FFR_MILTER_NOHDR_RESP */ +# define SMFI_CURR_PROT SMFI_V2_PROT /* The current version */ +# endif /* _FFR_MILTER_NOHDR_RESP */ #endif /* !_LIBMILTER_MFDEF_H */ diff --git a/contrib/sendmail/include/libmilter/milter.h b/contrib/sendmail/include/libmilter/milter.h index c18be73e34e0..5178f75620fa 100644 --- a/contrib/sendmail/include/libmilter/milter.h +++ b/contrib/sendmail/include/libmilter/milter.h @@ -7,7 +7,7 @@ * the sendmail distribution. * * - * $Id: milter.h,v 8.37.2.3 2003/12/02 00:19:51 msk Exp $ + * $Id: milter.h,v 8.39 2003/12/02 00:21:42 msk Exp $ */ /* @@ -25,11 +25,7 @@ typedef pthread_t sthread_t; typedef int socket_t; -#if _FFR_MILTER_MACROS_EOM # define MAX_MACROS_ENTRIES 5 /* max size of macro pointer array */ -#else /* _FFR_MILTER_MACROS_EOM */ -# define MAX_MACROS_ENTRIES 4 /* max size of macro pointer array */ -#endif /* _FFR_MILTER_MACROS_EOM */ /* ** context for milter diff --git a/contrib/sendmail/include/libsmdb/smdb.h b/contrib/sendmail/include/libsmdb/smdb.h index c891ea56d0e4..6db0103ccd8b 100644 --- a/contrib/sendmail/include/libsmdb/smdb.h +++ b/contrib/sendmail/include/libsmdb/smdb.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: smdb.h,v 8.40.2.1 2002/10/05 17:04:51 ca Exp $ + * $Id: smdb.h,v 8.41 2002/09/24 19:53:28 ca Exp $ * */ diff --git a/contrib/sendmail/include/sendmail/mailstats.h b/contrib/sendmail/include/sendmail/mailstats.h index 9a8a6350cc3b..faa83cb45036 100644 --- a/contrib/sendmail/include/sendmail/mailstats.h +++ b/contrib/sendmail/include/sendmail/mailstats.h @@ -10,14 +10,10 @@ * the sendmail distribution. * * - * $Id: mailstats.h,v 8.18 2001/11/21 13:39:10 gshapiro Exp $ + * $Id: mailstats.h,v 8.19 2002/06/27 22:47:22 gshapiro Exp $ */ -#if _FFR_QUARANTINE -# define STAT_VERSION 4 -#else /* _FFR_QUARANTINE */ -# define STAT_VERSION 3 -#endif /* _FFR_QUARANTINE */ +#define STAT_VERSION 4 #define STAT_MAGIC 0x1B1DE /* @@ -39,7 +35,5 @@ struct statistics long stat_bt[MAXMAILERS]; /* kbytes to each mailer */ long stat_nr[MAXMAILERS]; /* # rejects by each mailer */ long stat_nd[MAXMAILERS]; /* # discards by each mailer */ -#if _FFR_QUARANTINE long stat_nq[MAXMAILERS]; /* # quarantines by each mailer */ -#endif /* _FFR_QUARANTINE */ }; diff --git a/contrib/sendmail/include/sendmail/sendmail.h b/contrib/sendmail/include/sendmail/sendmail.h index bbd3177a8a89..b12a5a1af605 100644 --- a/contrib/sendmail/include/sendmail/sendmail.h +++ b/contrib/sendmail/include/sendmail/sendmail.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Id: sendmail.h,v 8.67 2001/09/08 01:20:57 gshapiro Exp $ + * $Id: sendmail.h,v 8.68 2002/07/01 22:18:53 gshapiro Exp $ */ /* @@ -55,6 +55,7 @@ #define SFF_NOWRFILES 0x00010000L /* disallow o readable files */ #define SFF_NOTEXCL 0x00020000L /* creates don't need to be exclusive */ #define SFF_EXECOK 0x00040000L /* executable files are ok (E_SM_ISEXEC) */ +#define SFF_NBLOCK 0x00080000L /* use a non-blocking lock */ #define SFF_NORFILES (SFF_NOGRFILES|SFF_NOWRFILES) /* pseudo-flags */ diff --git a/contrib/sendmail/include/sm/bdb.h b/contrib/sendmail/include/sm/bdb.h index 453eaa706c5e..babe1fff9961 100644 --- a/contrib/sendmail/include/sm/bdb.h +++ b/contrib/sendmail/include/sm/bdb.h @@ -7,7 +7,7 @@ * the sendmail distribution. * * - * $Id: bdb.h,v 1.1.2.4 2003/03/06 16:27:38 ca Exp $ + * $Id: bdb.h,v 1.4 2003/03/06 16:30:05 ca Exp $ */ #ifndef SM_BDB_H diff --git a/contrib/sendmail/include/sm/cdefs.h b/contrib/sendmail/include/sm/cdefs.h index 7b06e797bdd9..046ea04920e4 100644 --- a/contrib/sendmail/include/sm/cdefs.h +++ b/contrib/sendmail/include/sm/cdefs.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: cdefs.h,v 1.15.2.1 2003/12/05 22:44:17 ca Exp $ + * $Id: cdefs.h,v 1.16 2003/12/05 22:45:25 ca Exp $ */ /* diff --git a/contrib/sendmail/include/sm/conf.h b/contrib/sendmail/include/sm/conf.h index 055b958ea389..355d4278d490 100644 --- a/contrib/sendmail/include/sm/conf.h +++ b/contrib/sendmail/include/sm/conf.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Id: conf.h,v 1.90.2.20 2004/01/07 00:52:16 ca Exp $ + * $Id: conf.h,v 1.116 2004/07/26 18:08:35 ca Exp $ */ /* @@ -436,6 +436,8 @@ typedef int pid_t; # endif /* SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) */ # if SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) # define HASURANDOMDEV 1 /* /dev/[u]random added in S9 */ +# define HASCLOSEFROM 1 /* closefrom(3c) added in S9 */ +# define HASFDWALK 1 /* fdwalk(3c) added in S9 */ # endif /* SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) */ # if SOLARIS >= 21000 || (SOLARIS < 10000 && SOLARIS >= 210) # define HASUNSETENV 1 /* unsetenv() added in S10 */ @@ -481,7 +483,7 @@ extern char *getenv(); # else /* SUNOS403 */ /* 4.1.x specifics */ -# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASSETVBUF 1 /* we have setvbuf(3) in libc */ # endif /* SUNOS403 */ @@ -510,7 +512,7 @@ extern char *getenv(); # define LA_TYPE LA_DGUX # define HASSETREUID 1 /* has setreuid(2) call */ # define HASUNAME 1 /* use System V uname(2) system call */ -# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASINITGROUPS 1 /* has initgroups(3) call */ # define IP_SRCROUTE 0 /* does not have */ # define HASGETUSERSHELL 0 /* does not have getusershell(3) */ @@ -714,8 +716,7 @@ typedef int pid_t; # endif /* NeXT */ /* -** Apple Darwin (aka Rhapsody) -** +** Apple Darwin ** Contributed by Wilfredo Sanchez */ @@ -725,7 +726,7 @@ typedef int pid_t; # define HASFLOCK 1 /* has flock(2) */ # define HASUNAME 1 /* has uname(2) */ # define HASUNSETENV 1 /* has unsetenv(3) */ -# define HASSETSID 1 /* has the setsid(2) */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASINITGROUPS 1 /* has initgroups(3) */ # define HASSETVBUF 1 /* has setvbuf (3) */ # define HASSETREUID 0 /* setreuid(2) unusable */ @@ -794,7 +795,7 @@ extern unsigned int sleepX __P((unsigned int seconds)); # include # define HASUNSETENV 1 /* has the unsetenv(3) call */ # define HASSETREUID 0 /* BSD-OS has broken setreuid(2) emulation */ -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define USESETEUID 1 /* has usable seteuid(2) call */ # define HASFCHMOD 1 /* has fchmod(2) syscall */ # define HASSETLOGIN 1 /* has setlogin(2) */ @@ -842,7 +843,7 @@ extern unsigned int sleepX __P((unsigned int seconds)); # include # include # undef NGROUPS_MAX -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define USESETEUID 1 /* has usable seteuid(2) call */ # define HASFCHMOD 1 /* has fchmod(2) syscall */ # define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ @@ -876,10 +877,10 @@ extern unsigned int sleepX __P((unsigned int seconds)); # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) # include # define HASUNSETENV 1 /* has unsetenv(3) call */ -# define HASSETSID 1 /* has the setsid(2) POSIX syscall */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define USESETEUID 1 /* has usable seteuid(2) call */ # define HASFCHMOD 1 /* has fchmod(2) syscall */ -# define HASFCHOWN 1 /* fchown(2) */ +# define HASFCHOWN 1 /* has fchown(2) syscall */ # define HASUNAME 1 /* has uname(2) syscall */ # define HASSTRERROR 1 /* has strerror(3) */ # define HAS_ST_GEN 1 /* has st_gen field in stat struct */ @@ -894,7 +895,12 @@ extern unsigned int sleepX __P((unsigned int seconds)); # ifndef LA_TYPE # define LA_TYPE LA_SUBR # endif /* ! LA_TYPE */ -# define SFS_TYPE SFS_MOUNT /* use statfs() impl */ +# if defined(__NetBSD__) && defined(__NetBSD_Version__) && __NetBSD_Version__ >= 200040000 +# undef SFS_TYPE +# define SFS_TYPE SFS_STATVFS +# else +# define SFS_TYPE SFS_MOUNT /* use statfs() impl */ +# endif # if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1) # undef SPT_TYPE # define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ @@ -902,6 +908,17 @@ extern unsigned int sleepX __P((unsigned int seconds)); # if defined(__NetBSD__) && ((__NetBSD_Version__ > 102070000) || (NetBSD1_2 > 8) || defined(NetBSD1_4) || defined(NetBSD1_3)) # define HASURANDOMDEV 1 /* has /dev/urandom(4) */ # endif /* defined(__NetBSD__) && ((__NetBSD_Version__ > 102070000) || (NetBSD1_2 > 8) || defined(NetBSD1_4) || defined(NetBSD1_3)) */ +# if defined(__NetBSD__) && defined(__NetBSD_Version__) && __NetBSD_Version__ >= 104170000 +# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */ +# endif +# if defined(__NetBSD__) && defined(__NetBSD_Version__) && __NetBSD_Version__ >= 200060000 +# define HASCLOSEFROM 1 /* closefrom(3) added in 2.0F */ +# endif +# if defined(__NetBSD__) +# define USESYSCTL 1 /* use sysctl(3) for getting ncpus */ +# include +# include +# endif # if defined(__FreeBSD__) # define HASSETLOGIN 1 /* has setlogin(2) */ # if __FreeBSD_version >= 227001 @@ -949,6 +966,9 @@ extern unsigned int sleepX __P((unsigned int seconds)); # if OpenBSD >= 200012 # define HASSETUSERCONTEXT 1 /* BSDI-style login classes */ # endif /* OpenBSD >= 200012 */ +# if OpenBSD >= 200405 +# define HASCLOSEFROM 1 /* closefrom(3) added in 3.5 */ +# endif /* OpenBSD >= 200405 */ # endif /* defined(__OpenBSD__) */ # endif /* defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) */ @@ -1365,7 +1385,11 @@ extern void *malloc(); # if LINUX_VERSION_CODE < 66399 # define HASFLOCK 0 /* flock(2) is broken after 0.99.13 */ # else /* LINUX_VERSION_CODE < 66399 */ -# define HASFLOCK 1 /* flock(2) fixed after 1.3.95 */ +# if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +# define HASFLOCK 1 /* flock(2) fixed after 1.3.95 */ +# else /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) */ +# define HASFLOCK 0 /* flock(2) is broken (again) after 2.4.0 */ +# endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) */ # endif /* LINUX_VERSION_CODE < 66399 */ # endif /* ! HASFLOCK */ # ifndef LA_TYPE @@ -1379,9 +1403,7 @@ extern void *malloc(); # endif /* ! HASURANDOMDEV */ # endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0)) */ # if defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# ifndef HASSTRERROR -# define HASSTRERROR 1 /* has strerror(3) */ -# endif /* HASSTRERROR */ +# define HASSTRERROR 1 /* has strerror(3) */ # endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */ # ifndef TZ_TYPE # define TZ_TYPE TZ_NONE /* no standard for Linux */ @@ -1600,22 +1622,66 @@ typedef int pid_t; # endif /* ! _PATH_SENDMAILPID */ # endif /* _SEQUENT_ */ - /* -** Cray Unicos +** Cray UNICOS, UNICOS/mk, and UNICOS/mp ** +** UNICOS: ** Ported by David L. Kensiski, Sterling Sofware +** Update Brian Ginsbach +** UNICOS/mk (Cray T3E): +** Contributed by Manu Mahonen +** of Center for Scientific Computing. +** Update Brian Ginsbach +** UNICOS/mp: +** From Aaron Davis & Brian Ginsbach */ -# ifdef UNICOS +# if defined(_CRAY) || defined(UNICOS) || defined(_UNICOSMP) # define SYSTEM5 1 /* include all the System V defines */ -# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define MAXPATHLEN PATHSIZE -# define LA_TYPE LA_ZERO +# define HASFCHMOD 1 /* has fchmod(2) syscall */ +# define HASFCHOWN 1 /* has fchown(2) */ +# define HASUNSETENV 1 /* has unsetenv(3) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASSETREUID 1 /* has setreuid(2) call */ +# define USESETEUID 1 /* has usable seteuid(2) call */ +# define HASGETDTABLESIZE 1 /* has getdtablesize(2) syscall */ +# define HASSTRERROR 1 /* has strerror(3) */ +# define GIDSET_T gid_t # define SFS_TYPE SFS_4ARGS /* four argument statfs() call */ -# define SFS_BAVAIL f_bfree /* alternate field name */ -# endif /* UNICOS */ - +# define SFS_BAVAIL f_bfree /* alternate field name */ +# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */ +# ifdef UNICOS +# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ +# define LA_TYPE LA_ZERO +# define _PATH_MAILDIR "/usr/spool/mail" +# define GET_IPOPT_DST(dst) *(struct in_addr *)&(dst) +# ifndef MAXPATHLEN +# define MAXPATHLEN PATHSIZE +# endif /* ! MAXPATHLEN */ +# ifndef _PATH_UNIX +# ifdef UNICOSMK +# define _PATH_UNIX "/unicosmk.ar" +# else +# define _PATH_UNIX "/unicos" +# endif /* UNICOSMK */ +# endif /* ! _PATH_UNIX */ +# ifndef _PATH_VENDOR_CF +# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" +# endif /* ! _PATH_VENDOR_CF */ +# endif /* UNICOS */ +# ifdef _UNICOSMP +# if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN) + /* _SC_NPROC_ONLN is 'mpadmin -u', total # of unrestricted processors */ +# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN +# endif /* if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN) */ +# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define HASSETRLIMIT 1 /* has setrlimit(2) syscall */ +# define LA_TYPE LA_IRIX6 /* figure out at run time */ +# include +# include +# define ARGV_T char *const * +# endif /* _UNICOSMP */ +# endif /* _CRAY */ /* ** Apollo DomainOS @@ -1731,7 +1797,7 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t)); # define __svr4__ # define SYS5SIGNALS 1 # define HASFCHOWN 1 /* has fchown(2) call */ -# define HASSETSID 1 +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASSETREUID 1 # define HASWAITPID 1 # define HASGETDTABLESIZE 1 @@ -1781,7 +1847,7 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t)); # define SYSTEM5 1 # define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ # define HASSETREUID 1 -# define HASSETSID 1 +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASINITGROUPS 1 # define GIDSET_T gid_t # define SLEEP_T unsigned @@ -2003,7 +2069,7 @@ typedef int (*sigfunc_t)(); # ifndef __svr4__ # define __svr4__ /* use all System V Release 4 defines below */ # endif /* ! __svr4__ */ -# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASGETUSERSHELL 1 /* DOES have getusershell(3) call in libc */ # define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */ # ifndef SPT_TYPE @@ -2082,7 +2148,7 @@ extern char *getenv(); # define __svr4__ /* use all System V Release 4 defines below */ # endif /* ! __svr4__ */ # define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */ -# define HASSETSID 1 /* has Posix setsid(2) call */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define LA_TYPE LA_READKSYM /* use MIOC_READSYM ioctl */ # define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */ # define GIDSET_T gid_t @@ -2204,19 +2270,6 @@ typedef struct msgb mblk_t; # define SM_INT32 int /* 32bit integer */ # endif /* sinix */ -/* -** CRAY T3E -** -** Contributed by Manu Mahonen -** of Center for Scientific Computing. -*/ -# ifdef _CRAY -# define GET_IPOPT_DST(dst) *(struct in_addr *)&(dst) -# define _PATH_MAILDIR "/usr/spool/mail" -# if !defined(MAXPATHLEN) -# define MAXPATHLEN PATHSIZE -# endif /* !defined(MAXPATHLEN) */ -# endif /* _CRAY */ /* ** Motorola 922, MC88110, UNIX SYSTEM V/88 Release 4.0 Version 4.3 @@ -2227,7 +2280,7 @@ typedef struct msgb mblk_t; # ifdef MOTO # define HASFCHMOD 1 # define HASSETRLIMIT 0 -# define HASSETSID 1 +# define HASSETSID 1 /* has POSIX setsid(2) call */ # define HASSETREUID 1 # define HASULIMIT 1 # define HASWAITPID 1 @@ -2257,8 +2310,13 @@ typedef struct msgb mblk_t; # undef HAVE_SYS_ERRLIST # define sys_errlist __sys_errlist # define sys_nerr __sys_nerr -# define major(dev) ((int)(((dev) >> 8) & 0xff)) -# define minor(dev) ((int)((dev) & 0xff)) +# include +# ifndef major +# define major(dev) ((int)(((dev) >> 8) & 0xff)) +# endif /* ! major */ +# ifndef minor +# define minor(dev) ((int)((dev) & 0xff)) +# endif /* ! minor */ # endif /* defined(__INTERIX) */ @@ -2359,8 +2417,8 @@ typedef struct msgb mblk_t; /* general POSIX defines */ # ifdef _POSIX_VERSION -# define HASSETSID 1 /* has Posix setsid(2) call */ -# define HASWAITPID 1 /* has Posix waitpid(2) call */ +# define HASSETSID 1 /* has POSIX setsid(2) call */ +# define HASWAITPID 1 /* has POSIX waitpid(2) call */ # if _POSIX_VERSION >= 199500 && !defined(USESETEUID) # define USESETEUID 1 /* has usable seteuid(2) call */ # endif /* _POSIX_VERSION >= 199500 && !defined(USESETEUID) */ @@ -2578,7 +2636,7 @@ typedef struct msgb mblk_t; #endif /* ! EX_NOTFOUND */ /* pseudo-code used for mci_setstat */ -# define EX_NOTSTICKY -5 /* don't save persistent status */ +# define EX_NOTSTICKY (-5) /* don't save persistent status */ /* diff --git a/contrib/sendmail/include/sm/config.h b/contrib/sendmail/include/sm/config.h index 791a525326a2..3e4a91281fc5 100644 --- a/contrib/sendmail/include/sm/config.h +++ b/contrib/sendmail/include/sm/config.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2003 Sendmail, 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. * - * $Id: config.h,v 1.44 2002/01/23 17:47:15 gshapiro Exp $ + * $Id: config.h,v 1.46 2003/12/10 03:19:06 gshapiro Exp $ */ /* @@ -143,8 +143,12 @@ # define SM_CONF_TEST_LLONG 1 # endif /* !SM_CONF_TEST_LLONG */ -/* Does LDAP library have ldap_memfree()? */ -# ifndef SM_CONF_LDAP_MEMFREE +/* LDAP Checks */ +# if LDAPMAP +# include + +/* Does the LDAP library have ldap_memfree()? */ +# ifndef SM_CONF_LDAP_MEMFREE /* ** The new LDAP C API (draft-ietf-ldapext-ldap-c-api-04.txt) includes @@ -152,11 +156,31 @@ ** of 2004 to identify the API. */ -# if USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 -# define SM_CONF_LDAP_MEMFREE 1 -# else /* USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 */ -# define SM_CONF_LDAP_MEMFREE 0 -# endif /* USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 */ -# endif /* ! SM_CONF_LDAP_MEMFREE */ +# if USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 +# define SM_CONF_LDAP_MEMFREE 1 +# else /* USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 */ +# define SM_CONF_LDAP_MEMFREE 0 +# endif /* USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 */ +# endif /* ! SM_CONF_LDAP_MEMFREE */ + +/* Does the LDAP library have ldap_initialize()? */ +# ifndef SM_CONF_LDAP_INITIALIZE + +/* +** Check for ldap_initialize() support for support for LDAP URI's with +** non-ldap:// schemes. +*/ + +/* OpenLDAP does it with LDAP_OPT_URI */ +# ifdef LDAP_OPT_URI +# define SM_CONF_LDAP_INITIALIZE 1 +# endif /* LDAP_OPT_URI */ +# endif /* !SM_CONF_LDAP_INITIALIZE */ +# endif /* LDAPMAP */ + +/* don't use strcpy() */ +# ifndef DO_NOT_USE_STRCPY +# define DO_NOT_USE_STRCPY 1 +# endif /* ! DO_NOT_USE_STRCPY */ #endif /* ! SM_CONFIG_H */ diff --git a/contrib/sendmail/include/sm/debug.h b/contrib/sendmail/include/sm/debug.h index eba29ad25013..e3142b2fa423 100644 --- a/contrib/sendmail/include/sm/debug.h +++ b/contrib/sendmail/include/sm/debug.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000, 2001, 2003 Sendmail, 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. * - * $Id: debug.h,v 1.15 2001/03/08 03:23:07 ca Exp $ + * $Id: debug.h,v 1.16 2003/01/10 00:26:06 ca Exp $ */ /* @@ -28,29 +28,26 @@ extern SM_FILE_T * sm_debug_file __P((void)); extern void -sm_debug_setfile __P(( - SM_FILE_T *)); +sm_debug_setfile __P(( SM_FILE_T *)); extern void PRINTFLIKE(1, 2) -sm_dprintf __P(( - char *_fmt, - ...)); +sm_dprintf __P((char *_fmt, ...)); extern void sm_dflush __P((void)); +extern void +sm_debug_close __P((void)); + /* ** abstractions for setting and testing debug activation levels */ extern void -sm_debug_addsettings_x __P(( - const char *)); +sm_debug_addsettings_x __P((const char *)); extern void -sm_debug_addsetting_x __P(( - const char *, - int)); +sm_debug_addsetting_x __P((const char *, int)); # define SM_DEBUG_UNKNOWN ((SM_ATOMIC_UINT_T)(-1)) @@ -123,13 +120,10 @@ struct sm_debug # endif /* SM_DEBUG_CHECK */ extern bool -sm_debug_loadactive __P(( - SM_DEBUG_T *, - int)); +sm_debug_loadactive __P((SM_DEBUG_T *, int)); extern int -sm_debug_loadlevel __P(( - SM_DEBUG_T *)); +sm_debug_loadlevel __P((SM_DEBUG_T *)); # define SM_DEBUG_INITIALIZER(name, desc) { \ SmDebugMagic, \ diff --git a/contrib/sendmail/include/sm/errstring.h b/contrib/sendmail/include/sm/errstring.h index cc69c51c4aab..2b937328fd72 100644 --- a/contrib/sendmail/include/sm/errstring.h +++ b/contrib/sendmail/include/sm/errstring.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: errstring.h,v 1.4.4.3 2003/06/24 17:16:10 ca Exp $ + * $Id: errstring.h,v 1.9 2003/12/10 03:19:06 gshapiro Exp $ */ /* @@ -17,7 +17,9 @@ # define SM_ERRSTRING_H #include +#if NEEDINTERRNO extern int errno; +#endif /* NEEDINTERRNO */ /* ** These are used in a few cases where we need some special @@ -44,6 +46,7 @@ extern int errno; #define E_DNSBASE (E_PSEUDOBASE + 20) /* base for DNS h_errno */ #define E_SMDBBASE (E_PSEUDOBASE + 40) /* base for libsmdb errors */ #define E_LDAPBASE (E_PSEUDOBASE + 70) /* base for LDAP errors */ +#define E_LDAPURLBASE (E_PSEUDOBASE + 200) /* base for LDAP URL errors */ /* libsmdb */ diff --git a/contrib/sendmail/include/sm/fdset.h b/contrib/sendmail/include/sm/fdset.h index 31a0e3045591..bb42185647ee 100644 --- a/contrib/sendmail/include/sm/fdset.h +++ b/contrib/sendmail/include/sm/fdset.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: fdset.h,v 1.3.10.2 2002/12/10 04:02:25 ca Exp $ + * $Id: fdset.h,v 1.5 2002/12/10 19:48:19 ca Exp $ */ #ifndef SM_FDSET_H diff --git a/contrib/sendmail/include/sm/gen.h b/contrib/sendmail/include/sm/gen.h index 61b6e1b8f34d..6fec06c23a34 100644 --- a/contrib/sendmail/include/sm/gen.h +++ b/contrib/sendmail/include/sm/gen.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: gen.h,v 1.22 2002/04/03 00:40:42 ca Exp $ + * $Id: gen.h,v 1.23 2003/11/04 18:51:54 ca Exp $ */ /* @@ -43,7 +43,7 @@ # else /* SM_CONF_STDDEF_H */ # ifndef NULL # define NULL 0 -# endif +# endif /* ! NULL */ # define offsetof(type, member) ((size_t)(&((type *)0)->member)) # endif /* SM_CONF_STDDEF_H */ @@ -58,7 +58,8 @@ typedef int bool; # define false 0 # define true 1 -# endif +# define __bool_true_false_are_defined 1 +# endif /* ! __cplusplus */ # endif /* SM_CONF_STDBOOL_H */ /* diff --git a/contrib/sendmail/include/sm/io.h b/contrib/sendmail/include/sm/io.h index 0e50c235b2e8..d3f21d073686 100644 --- a/contrib/sendmail/include/sm/io.h +++ b/contrib/sendmail/include/sm/io.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1990 * The Regents of the University of California. All rights reserved. @@ -11,7 +11,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: io.h,v 1.23.2.2 2003/09/05 20:35:28 ca Exp $ + * $Id: io.h,v 1.24 2004/03/03 19:14:49 ca Exp $ */ /*- @@ -34,15 +34,15 @@ #define SM_IO_RDWRTR 6 /* read-write with truncation indicated */ # define SM_IO_BINARY 0x0 /* binary mode: not used in Unix */ -#define SM_IS_BINARY(mode) ((mode) & SM_IO_BINARY != 0) +#define SM_IS_BINARY(mode) (((mode) & SM_IO_BINARY) != 0) #define SM_IO_MODE(mode) ((mode) & 0x0f) -#define SM_IO_RDWR_B (SM_IO_RDWR|SM_IO_BINARY) -#define SM_IO_RDONLY_B (SM_IO_RDONLY|SM_IO_BINARY) -#define SM_IO_WRONLY_B (SM_IO_WRONLY|SM_IO_BINARY) -#define SM_IO_APPEND_B (SM_IO_APPEND|SM_IO_BINARY) +#define SM_IO_RDWR_B (SM_IO_RDWR|SM_IO_BINARY) +#define SM_IO_RDONLY_B (SM_IO_RDONLY|SM_IO_BINARY) +#define SM_IO_WRONLY_B (SM_IO_WRONLY|SM_IO_BINARY) +#define SM_IO_APPEND_B (SM_IO_APPEND|SM_IO_BINARY) #define SM_IO_APPENDRW_B (SM_IO_APPENDRW|SM_IO_BINARY) -#define SM_IO_RDWRTR_B (SM_IO_RDWRTR|SM_IO_BINARY) +#define SM_IO_RDWRTR_B (SM_IO_RDWRTR|SM_IO_BINARY) /* for sm_io_fseek, et al api's (exposed) */ #define SM_IO_SEEK_SET 0 diff --git a/contrib/sendmail/include/sm/ldap.h b/contrib/sendmail/include/sm/ldap.h index dfa0463b6266..8df8fe14b846 100644 --- a/contrib/sendmail/include/sm/ldap.h +++ b/contrib/sendmail/include/sm/ldap.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: ldap.h,v 1.22 2002/03/05 02:17:26 ca Exp $ + * $Id: ldap.h,v 1.27 2003/12/20 09:23:47 gshapiro Exp $ */ #ifndef SM_LDAP_H @@ -32,34 +32,26 @@ # if LDAPMAP -# if _FFR_LDAP_RECURSION - /* Attribute types */ -# define SM_LDAP_ATTR_NONE (-1) -# define SM_LDAP_ATTR_OBJCLASS 0 -# define SM_LDAP_ATTR_NORMAL 1 -# define SM_LDAP_ATTR_DN 2 -# define SM_LDAP_ATTR_FILTER 3 -# define SM_LDAP_ATTR_URL 4 +# define SM_LDAP_ATTR_NONE (-1) +# define SM_LDAP_ATTR_OBJCLASS 0 +# define SM_LDAP_ATTR_NORMAL 1 +# define SM_LDAP_ATTR_DN 2 +# define SM_LDAP_ATTR_FILTER 3 +# define SM_LDAP_ATTR_URL 4 /* sm_ldap_results() flags */ -# define SM_LDAP_SINGLEMATCH 0x0001 -# define SM_LDAP_MATCHONLY 0x0002 -# define SM_LDAP_USE_ALLATTR 0x0004 - -# endif /* _FFR_LDAP_RECURSION */ +# define SM_LDAP_SINGLEMATCH 0x0001 +# define SM_LDAP_MATCHONLY 0x0002 +# define SM_LDAP_USE_ALLATTR 0x0004 struct sm_ldap_struct { /* needed for ldap_open or ldap_init */ - char *ldap_target; + char *ldap_uri; + char *ldap_host; int ldap_port; -# if _FFR_LDAP_URI - bool ldap_uri; -# endif /* _FFR_LDAP_URI */ -# if _FFR_LDAP_SETVERSION int ldap_version; -# endif /* _FFR_LDAP_SETVERSION */ pid_t ldap_pid; /* options set in ld struct before ldap_bind_s */ @@ -79,10 +71,8 @@ struct sm_ldap_struct int ldap_scope; char *ldap_filter; char *ldap_attr[LDAPMAP_MAX_ATTR + 1]; -# if _FFR_LDAP_RECURSION int ldap_attr_type[LDAPMAP_MAX_ATTR + 1]; char *ldap_attr_needobjclass[LDAPMAP_MAX_ATTR + 1]; -# endif /* _FFR_LDAP_RECURSION */ bool ldap_attrsonly; /* args for ldap_result */ @@ -98,11 +88,12 @@ struct sm_ldap_struct typedef struct sm_ldap_struct SM_LDAP_STRUCT; -# if _FFR_LDAP_RECURSION struct sm_ldap_recurse_entry { char *lr_search; int lr_type; + LDAPURLDesc *lr_ludp; + char **lr_attrs; bool lr_done; }; @@ -115,17 +106,14 @@ struct sm_ldap_recurse_list typedef struct sm_ldap_recurse_entry SM_LDAP_RECURSE_ENTRY; typedef struct sm_ldap_recurse_list SM_LDAP_RECURSE_LIST; -# endif /* _FFR_LDAP_RECURSION */ /* functions */ extern void sm_ldap_clear __P((SM_LDAP_STRUCT *)); extern bool sm_ldap_start __P((char *, SM_LDAP_STRUCT *)); extern int sm_ldap_search __P((SM_LDAP_STRUCT *, char *)); -# if _FFR_LDAP_RECURSION extern int sm_ldap_results __P((SM_LDAP_STRUCT *, int, int, int, SM_RPOOL_T *, char **, int *, int *, SM_LDAP_RECURSE_LIST *)); -# endif /* _FFR_LDAP_RECURSION */ extern void sm_ldap_setopts __P((LDAP *, SM_LDAP_STRUCT *)); extern int sm_ldap_geterrno __P((LDAP *)); extern void sm_ldap_close __P((SM_LDAP_STRUCT *)); diff --git a/contrib/sendmail/include/sm/os/sm_os_aix.h b/contrib/sendmail/include/sm/os/sm_os_aix.h index 9c3f469cefec..4669a3cecfc4 100644 --- a/contrib/sendmail/include/sm/os/sm_os_aix.h +++ b/contrib/sendmail/include/sm/os/sm_os_aix.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: sm_os_aix.h,v 1.9.2.1 2003/04/28 23:11:07 ca Exp $ + * $Id: sm_os_aix.h,v 1.11 2003/04/28 23:42:23 ca Exp $ */ /* diff --git a/contrib/sendmail/include/sm/os/sm_os_unicos.h b/contrib/sendmail/include/sm/os/sm_os_unicos.h new file mode 100644 index 000000000000..57d6b72f863b --- /dev/null +++ b/contrib/sendmail/include/sm/os/sm_os_unicos.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2003 Sendmail, 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. + * + * $Id: sm_os_unicos.h,v 1.1 2003/04/21 17:03:51 ca Exp $ + */ + +/* +** Cray UNICOS +*/ + +#define SM_OS_NAME "unicos" + +#define SM_CONF_LONGLONG 1 +#define SM_CONF_SETITIMER 0 diff --git a/contrib/sendmail/include/sm/os/sm_os_unicosmk.h b/contrib/sendmail/include/sm/os/sm_os_unicosmk.h new file mode 100644 index 000000000000..ce87c04e35af --- /dev/null +++ b/contrib/sendmail/include/sm/os/sm_os_unicosmk.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2003 Sendmail, 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. + * + * $Id: sm_os_unicosmk.h,v 1.1 2003/04/21 17:03:51 ca Exp $ + */ + +/* +** Cray UNICOS/mk +*/ + +#define SM_OS_NAME "unicosmk" + +#define SM_CONF_LONGLONG 1 diff --git a/contrib/sendmail/include/sm/os/sm_os_unicosmp.h b/contrib/sendmail/include/sm/os/sm_os_unicosmp.h new file mode 100644 index 000000000000..b11350b78c4d --- /dev/null +++ b/contrib/sendmail/include/sm/os/sm_os_unicosmp.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2003 Sendmail, 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. + * + * $Id: sm_os_unicosmp.h,v 1.1 2003/04/21 17:03:51 ca Exp $ + */ + +/* +** Cray UNICOS/mp +*/ + +#define SM_OS_NAME "unicosmp" + +#define SM_CONF_LONGLONG 1 +#define SM_CONF_SYS_CDEFS_H 1 +#define SM_CONF_MSG 1 +#define SM_CONF_SHM 1 +#define SM_CONF_SEM 1 diff --git a/contrib/sendmail/include/sm/os/sm_os_unixware.h b/contrib/sendmail/include/sm/os/sm_os_unixware.h index aac431eb91da..6c7bfe62ad8f 100644 --- a/contrib/sendmail/include/sm/os/sm_os_unixware.h +++ b/contrib/sendmail/include/sm/os/sm_os_unixware.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: sm_os_unixware.h,v 1.7.2.1 2002/10/24 18:02:14 ca Exp $ + * $Id: sm_os_unixware.h,v 1.8 2002/10/24 18:04:54 ca Exp $ */ #define SM_OS_NAME "unixware" diff --git a/contrib/sendmail/include/sm/rpool.h b/contrib/sendmail/include/sm/rpool.h index e750fcb7d3fd..cdff4c774292 100644 --- a/contrib/sendmail/include/sm/rpool.h +++ b/contrib/sendmail/include/sm/rpool.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001, 2003 Sendmail, 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. * - * $Id: rpool.h,v 1.15 2001/09/04 22:41:55 ca Exp $ + * $Id: rpool.h,v 1.16 2003/09/05 23:07:49 ca Exp $ */ /* @@ -165,8 +165,12 @@ sm_rpool_malloc __P(( size_t _size)); # endif /* SM_HEAP_CHECK */ +#if DO_NOT_USE_STRCPY +extern char *sm_rpool_strdup_x __P((SM_RPOOL_T *rpool, const char *s)); +#else /* DO_NOT_USE_STRCPY */ # define sm_rpool_strdup_x(rpool, str) \ strcpy(sm_rpool_malloc_x(rpool, strlen(str) + 1), str) +#endif /* DO_NOT_USE_STRCPY */ extern SM_RPOOL_ATTACH_T sm_rpool_attach_x __P(( diff --git a/contrib/sendmail/include/sm/shm.h b/contrib/sendmail/include/sm/shm.h index 36033ed3d1b4..0334ae340376 100644 --- a/contrib/sendmail/include/sm/shm.h +++ b/contrib/sendmail/include/sm/shm.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: shm.h,v 1.8.2.2 2003/05/17 18:34:16 ca Exp $ + * $Id: shm.h,v 1.10 2003/05/17 18:34:54 ca Exp $ */ #ifndef SM_SHM_H diff --git a/contrib/sendmail/include/sm/string.h b/contrib/sendmail/include/sm/string.h index c8cb59f690e9..7c96b8f6d44a 100644 --- a/contrib/sendmail/include/sm/string.h +++ b/contrib/sendmail/include/sm/string.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001, 2003 Sendmail, 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. * - * $Id: string.h,v 1.36 2001/06/17 21:31:11 ca Exp $ + * $Id: string.h,v 1.38 2003/10/10 17:56:57 ca Exp $ */ /* @@ -24,25 +24,30 @@ #define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf)) extern int PRINTFLIKE(3, 4) -sm_snprintf __P(( - char *, - size_t, - const char *, - ...)); +sm_snprintf __P((char *, size_t, const char *, ...)); extern bool -sm_match __P(( - const char *_str, - const char *_pattern)); +sm_match __P((const char *_str, const char *_pattern)); extern char * -sm_strdup __P(( - char *)); +sm_strdup __P((char *)); extern char * -sm_strndup_x __P(( - const char *_str, - size_t _len)); +sm_strndup_x __P((const char *_str, size_t _len)); + +#if DO_NOT_USE_STRCPY +/* for "normal" data (free'd before end of process) */ +extern char * +sm_strdup_x __P((const char *_str)); + +/* for data that is supposed to be persistent. */ +extern char * +sm_pstrdup_x __P((const char *_str)); + +extern char * +sm_strdup_tagged_x __P((const char *str, char *file, int line, int group)); + +#else /* DO_NOT_USE_STRCPY */ /* for "normal" data (free'd before end of process) */ # define sm_strdup_x(str) strcpy(sm_malloc_x(strlen(str) + 1), str) @@ -52,35 +57,22 @@ sm_strndup_x __P(( # define sm_strdup_tagged_x(str, file, line, group) \ strcpy(sm_malloc_tagged_x(strlen(str) + 1, file, line, group), str) +#endif /* DO_NOT_USE_STRCPY */ extern char * -sm_stringf_x __P(( - const char *_fmt, - ...)); +sm_stringf_x __P((const char *_fmt, ...)); extern char * -sm_vstringf_x __P(( - const char *_fmt, - va_list _ap)); +sm_vstringf_x __P((const char *_fmt, va_list _ap)); extern size_t -sm_strlcpy __P(( - char *_dst, - const char *_src, - ssize_t _len)); +sm_strlcpy __P((char *_dst, const char *_src, ssize_t _len)); extern size_t -sm_strlcat __P(( - char *_dst, - const char *_src, - ssize_t _len)); +sm_strlcat __P((char *_dst, const char *_src, ssize_t _len)); extern size_t -sm_strlcat2 __P(( - char *, - const char *, - const char *, - ssize_t)); +sm_strlcat2 __P((char *, const char *, const char *, ssize_t)); extern size_t #ifdef __STDC__ @@ -94,40 +86,26 @@ sm_strlcpyn __P((char *, # if !HASSTRERROR extern char * -strerror __P(( - int _errno)); +strerror __P((int _errno)); # endif /* !HASSTRERROR */ extern int -sm_strrevcmp __P(( - const char *, - const char *)); +sm_strrevcmp __P((const char *, const char *)); extern int -sm_strrevcasecmp __P(( - const char *, - const char *)); +sm_strrevcasecmp __P((const char *, const char *)); extern int -sm_strcasecmp __P(( - const char *, - const char *)); +sm_strcasecmp __P((const char *, const char *)); extern int -sm_strncasecmp __P(( - const char *, - const char *, - size_t)); +sm_strncasecmp __P((const char *, const char *, size_t)); extern LONGLONG_T -sm_strtoll __P(( - const char *, - char**, int)); +sm_strtoll __P((const char *, char**, int)); extern ULONGLONG_T -sm_strtoull __P(( - const char *, - char**, int)); +sm_strtoull __P((const char *, char**, int)); extern void stripquotes __P((char *)); diff --git a/contrib/sendmail/include/sm/varargs.h b/contrib/sendmail/include/sm/varargs.h index 34f75124af11..7746e3a62d77 100644 --- a/contrib/sendmail/include/sm/varargs.h +++ b/contrib/sendmail/include/sm/varargs.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: varargs.h,v 1.7.2.1 2002/07/29 21:43:20 gshapiro Exp $ + * $Id: varargs.h,v 1.8 2002/07/29 21:31:00 gshapiro Exp $ */ /* diff --git a/contrib/sendmail/libmilter/Makefile.m4 b/contrib/sendmail/libmilter/Makefile.m4 index d824298ed501..5bc1a92a4a39 100644 --- a/contrib/sendmail/libmilter/Makefile.m4 +++ b/contrib/sendmail/libmilter/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.30.2.1 2002/06/21 21:58:28 ca Exp $ +dnl $Id: Makefile.m4,v 8.31 2002/06/21 22:01:31 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') dnl only required for compilation of EXTRAS diff --git a/contrib/sendmail/libmilter/README b/contrib/sendmail/libmilter/README index 96fba669755a..ec1f84b7eb04 100644 --- a/contrib/sendmail/libmilter/README +++ b/contrib/sendmail/libmilter/README @@ -9,11 +9,8 @@ through reference to a sample filter which is attached at the end of this file. It is necessary to first build libmilter.a, which can be done by issuing the './Build' command in SRCDIR/libmilter . -NOTE: If you intend to use filters in sendmail, you must compile sendmail -with -DMILTER defined. You can do this by adding the following to -your devtools/Site/site.config.m4 file: - - APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') +Starting with 8.13 sendmail is compiled by default with support for +the milter API. +----------------+ | SECURITY HINTS | @@ -23,13 +20,18 @@ Note: we strongly recommend not to run any milter as root. Libmilter does not need root access to communicate with sendmail. It is a good security practice to run a program only with root privileges if really necessary. A milter should probably check first whether -it runs as root and refuse to start in that case. There is a -compile time option _FFR_MILTER_ROOT_UNSAFE which keeps libmilter -from unlinking a socket when running as root. It is recommended -to turn on this option: +it runs as root and refuse to start in that case. libmilter will +not unlink a socket when running as root. - APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER_ROOT_UNSAFE ') ++----------------------+ +| CONFIGURATION MACROS | ++----------------------+ +Libmilter uses a set of C preprocessor macros to specify platform specific +features of the C compiler and standard C libraries. + +SM_CONF_POLL + Set to 1 if poll(2) should be used instead of select(2). +-------------------+ | BUILDING A FILTER | @@ -464,4 +466,4 @@ main(argc, argv) /* eof */ -$Revision: 8.35.2.2 $, Last updated $Date: 2003/05/26 04:10:06 $ +$Revision: 8.40 $, Last updated $Date: 2003/12/11 18:14:34 $ diff --git a/contrib/sendmail/libmilter/comm.c b/contrib/sendmail/libmilter/comm.c index aa48cf78791d..552e7e492351 100644 --- a/contrib/sendmail/libmilter/comm.c +++ b/contrib/sendmail/libmilter/comm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,10 +9,36 @@ */ #include -SM_RCSID("@(#)$Id: comm.c,v 8.54.2.6 2003/01/03 22:14:40 ca Exp $") +SM_RCSID("@(#)$Id: comm.c,v 8.65 2004/07/07 21:41:30 ca Exp $") #include "libmilter.h" #include +#include + +static size_t Maxdatasize = MILTER_MAX_DATA_SIZE; + +#if _FFR_MAXDATASIZE +/* +** SMFI_SETMAXDATASIZE -- set limit for milter data read/write. +** +** Parameters: +** sz -- new limit. +** +** Returns: +** old limit +*/ + +size_t +smfi_setmaxdatasize(sz) + size_t sz; +{ + size_t old; + + old = Maxdatasize; + Maxdatasize = sz; + return old; +} +#endif /* _FFR_MAXDATASIZE */ /* ** MI_RD_CMD -- read a command @@ -107,7 +133,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) expl = ntohl(expl) - 1; if (expl <= 0) return NULL; - if (expl > MILTER_CHUNK_SIZE) + if (expl > Maxdatasize) { *cmd = SMFIC_TOOBIG; return NULL; @@ -195,12 +221,94 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) *cmd = SMFIC_UNKNERR; return NULL; } + +/* +** RETRY_WRITEV -- Keep calling the writev() system call +** until all the data is written out or an error occurs. +** +** Parameters: +** fd -- socket descriptor +** iov -- io vector +** iovcnt -- number of elements in io vector +** must NOT exceed UIO_MAXIOV. +** timeout -- maximum time to wait +** +** Returns: +** success: number of bytes written +** otherwise: MI_FAILURE +*/ + +static ssize_t +retry_writev(fd, iov, iovcnt, timeout) + socket_t fd; + struct iovec *iov; + int iovcnt; + struct timeval *timeout; +{ + int i; + ssize_t n, written; + FD_WR_VAR(wrs); + + written = 0; + for (;;) + { + while (iovcnt > 0 && iov[0].iov_len == 0) + { + iov++; + iovcnt--; + } + if (iovcnt <= 0) + return written; + + /* + ** We don't care much about the timeout here, + ** it's very long anyway; correct solution would be + ** to take the time before the loop and reduce the + ** timeout after each invocation. + ** FD_SETSIZE is checked when socket is created. + */ + + FD_WR_INIT(fd, wrs); + i = FD_WR_READY(fd, wrs, timeout); + if (i == 0) + return MI_FAILURE; + if (i < 0) + { + if (errno == EINTR || errno == EAGAIN) + continue; + return MI_FAILURE; + } + n = writev(fd, iov, iovcnt); + if (n == -1) + { + if (errno == EINTR || errno == EAGAIN) + continue; + return MI_FAILURE; + } + + written += n; + for (i = 0; i < iovcnt; i++) + { + if (iov[i].iov_len > (unsigned int) n) + { + iov[i].iov_base = (char *)iov[i].iov_base + n; + iov[i].iov_len -= (unsigned int) n; + break; + } + n -= (int) iov[i].iov_len; + iov[i].iov_len = 0; + } + if (i == iovcnt) + return written; + } +} + /* ** MI_WR_CMD -- write a cmd to sd ** ** Parameters: ** sd -- socket descriptor -** timeout -- maximum time to wait (currently unused) +** timeout -- maximum time to wait ** cmd -- single character command to write ** buf -- buffer with further data ** len -- length of buffer (without cmd!) @@ -209,38 +317,6 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) ** MI_SUCCESS/MI_FAILURE */ -/* -** we don't care much about the timeout here, it's very long anyway -** FD_SETSIZE is checked when socket is created. -** XXX l == 0 ? -*/ - -#define MI_WR(data) \ - while (sl > 0) \ - { \ - FD_WR_INIT(sd, wrs); \ - ret = FD_WR_READY(sd, wrs, timeout); \ - if (ret == 0) \ - return MI_FAILURE; \ - if (ret < 0) \ - { \ - if (errno == EINTR) \ - continue; \ - else \ - return MI_FAILURE; \ - } \ - l = MI_SOCK_WRITE(sd, (void *) ((data) + i), sl); \ - if (l < 0) \ - { \ - if (errno == EINTR) \ - continue; \ - else \ - return MI_FAILURE; \ - } \ - i += l; \ - sl -= l; \ - } - int mi_wr_cmd(sd, timeout, cmd, buf, len) socket_t sd; @@ -252,27 +328,32 @@ mi_wr_cmd(sd, timeout, cmd, buf, len) size_t sl, i; ssize_t l; mi_int32 nl; - int ret; - FD_WR_VAR(wrs); + int iovcnt; + struct iovec iov[2]; char data[MILTER_LEN_BYTES + 1]; - if (len > MILTER_CHUNK_SIZE) + if (len > Maxdatasize || (len > 0 && buf == NULL)) return MI_FAILURE; + nl = htonl(len + 1); /* add 1 for the cmd char */ (void) memcpy(data, (void *) &nl, MILTER_LEN_BYTES); data[MILTER_LEN_BYTES] = (char) cmd; i = 0; sl = MILTER_LEN_BYTES + 1; - /* use writev() instead to send the whole stuff at once? */ - - MI_WR(data); - if (len > 0 && buf == NULL) + /* set up the vector for the size / command */ + iov[0].iov_base = (void *) data; + iov[0].iov_len = sl; + iovcnt = 1; + if (len >= 0 && buf != NULL) + { + iov[1].iov_base = (void *) buf; + iov[1].iov_len = len; + iovcnt = 2; + } + + l = retry_writev(sd, iov, iovcnt, timeout); + if (l == MI_FAILURE) return MI_FAILURE; - if (len == 0 || buf == NULL) - return MI_SUCCESS; - i = 0; - sl = len; - MI_WR(buf); return MI_SUCCESS; } diff --git a/contrib/sendmail/libmilter/docs/api.html b/contrib/sendmail/libmilter/docs/api.html index 936abed0d0db..23c4de41b42d 100644 --- a/contrib/sendmail/libmilter/docs/api.html +++ b/contrib/sendmail/libmilter/docs/api.html @@ -1,6 +1,9 @@ Milter API +

Milter API

Contents

@@ -26,12 +29,20 @@ href="smfi_main.html">smfi_main.

+ + + + + + + +
FunctionDescription
smfi_opensocketTry to create the interface socket.
smfi_registerRegister a filter.
smfi_setconnSpecify socket to use.
smfi_settimeoutSet timeout.
smfi_setbacklogDefine the incoming listen(2) queue size.
smfi_setdbgSet the milter library debugging (tracing) level.
smfi_stopCause an orderly shutdown.
smfi_mainHand control to libmilter.
@@ -54,6 +65,9 @@ pointer. smfi_setreplySet the specific reply code to be used. +smfi_setmlreplySet the +specific multi-line reply to be used. +

Message Modification Functions

@@ -85,6 +99,9 @@ the message.SMFIF_ADDHDRS smfi_chgheaderChange or delete a header.SMFIF_CHGHDRS +smfi_insheaderInsert a +header into the message.SMFIF_ADDHDRS + smfi_addrcptAdd a recipient to the envelope.SMFIF_ADDRCPT @@ -96,7 +113,29 @@ body of the message.SMFIF_CHGBODY -

Callbacks

+

Other Message Handling Functions

+ +The following functions provide special case handling instructions for +milter or the MTA, without altering the content or status of the message. +They too may only be called in xxfi_eom. +All of these functions may invoke additional communication with the MTA. +They will return either MI_SUCCESS or MI_FAILURE to indicate the status of +the operation. + +

+Note that the status returned indicates only whether or not the +filter's message was successfully sent to the MTA, not whether or not +the MTA performed the requested operation. + +

+ + + + + +
FunctionDescription
smfi_progressReport operation in progress.
smfi_quarantineQuarantine a message.
+ +

Callbacks

The filter should implement one or more of the following callbacks, which are registered via smfi_register: @@ -131,7 +170,7 @@ having the indicated meanings. Any return other than one of the below values constitutes an error, and will cause sendmail to terminate its connection to the offending filter. -

Milter distinguishes between recipient-, +

Milter distinguishes between recipient-, message-, and connection-oriented routines. Recipient-oriented callbacks may affect the processing of a single message recipient; message-oriented callbacks, a single message; connection-oriented diff --git a/contrib/sendmail/libmilter/docs/design.html b/contrib/sendmail/libmilter/docs/design.html index 91804861e0a0..3cf289829d88 100644 --- a/contrib/sendmail/libmilter/docs/design.html +++ b/contrib/sendmail/libmilter/docs/design.html @@ -3,6 +3,9 @@ Architecture +

Architecture

diff --git a/contrib/sendmail/libmilter/docs/index.html b/contrib/sendmail/libmilter/docs/index.html index 93eb3f83432b..3c39abf478f5 100644 --- a/contrib/sendmail/libmilter/docs/index.html +++ b/contrib/sendmail/libmilter/docs/index.html @@ -4,7 +4,7 @@

Filtering Mail with Sendmail

diff --git a/contrib/sendmail/libmilter/docs/installation.html b/contrib/sendmail/libmilter/docs/installation.html index 370f1d3baf07..5353ea74a6d0 100644 --- a/contrib/sendmail/libmilter/docs/installation.html +++ b/contrib/sendmail/libmilter/docs/installation.html @@ -2,6 +2,9 @@ Installation and Configuration +

Installation

Contents

    diff --git a/contrib/sendmail/libmilter/docs/other.html b/contrib/sendmail/libmilter/docs/other.html index 4647c5380872..22ef8229adbe 100644 --- a/contrib/sendmail/libmilter/docs/other.html +++ b/contrib/sendmail/libmilter/docs/other.html @@ -2,6 +2,9 @@ Other Resources + FAQ? Mailing list? More sample filters?
    diff --git a/contrib/sendmail/libmilter/docs/overview.html b/contrib/sendmail/libmilter/docs/overview.html index 981856446c22..f06fbdf22f87 100644 --- a/contrib/sendmail/libmilter/docs/overview.html +++ b/contrib/sendmail/libmilter/docs/overview.html @@ -4,7 +4,7 @@

    Technical Overview

    diff --git a/contrib/sendmail/libmilter/docs/sample.html b/contrib/sendmail/libmilter/docs/sample.html index 2cc1948dd381..29ee67ab7c1d 100644 --- a/contrib/sendmail/libmilter/docs/sample.html +++ b/contrib/sendmail/libmilter/docs/sample.html @@ -1,6 +1,9 @@ A Sample Filter +

    A Sample Filter

    The following sample logs each message to a separate temporary file, @@ -121,9 +124,10 @@ sfsistat SMFICTX *ctx; char **argv; { + int fd = -1; + int argc = 0; struct mlfiPriv *priv = MLFIPRIV; char *mailaddr = smfi_getsymval(ctx, "{mail_addr}"); - int argc = 0; /* open a file to store this message */ if ((priv->mlfi_fname = strdup("/tmp/msg.XXXXXX")) == NULL) @@ -132,14 +136,15 @@ sfsistat return SMFIS_TEMPFAIL; } - if (mkstemp(priv->mlfi_fname) == -1) + if ((fd = mkstemp(priv->mlfi_fname)) == -1) { (void) mlfi_cleanup(ctx, FALSE); return SMFIS_TEMPFAIL; } - if ((priv->mlfi_fp = fopen(priv->mlfi_fname, "w+")) == NULL) + if ((priv->mlfi_fp = fdopen(fd, "w+")) == NULL) { + (void) close(fd); (void) mlfi_cleanup(ctx, FALSE); return SMFIS_TEMPFAIL; } @@ -361,7 +366,8 @@ struct smfiDesc smfilter = { "SampleFilter", /* filter name */ SMFI_VERSION, /* version code -- do not change */ - SMFIF_ADDHDRS, /* flags */ + SMFIF_ADDHDRS|SMFIF_ADDRCPT, + /* flags */ mlfi_connect, /* connection info filter */ mlfi_helo, /* SMTP HELO command filter */ mlfi_envfrom, /* envelope sender filter */ @@ -488,7 +494,7 @@ main(argc, argv)
    -Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. +Copyright (c) 2000-2004 Sendmail, Inc. and its suppliers. All rights reserved.
    By using this file, you agree to the terms and conditions set diff --git a/contrib/sendmail/libmilter/docs/smfi_addheader.html b/contrib/sendmail/libmilter/docs/smfi_addheader.html index a49c648780ff..e1fe69d648c8 100644 --- a/contrib/sendmail/libmilter/docs/smfi_addheader.html +++ b/contrib/sendmail/libmilter/docs/smfi_addheader.html @@ -1,6 +1,9 @@ smfi_addheader +

    smfi_addheader

    @@ -69,7 +72,7 @@ Otherwise, it returns MI_SUCCESS. To change a header's current value, use smfi_chgheader.
  • A filter which calls smfi_addheader must have set the SMFIF_ADDHDRS flag in the smfiDesc_str passed to smfi_register. -
  • For smfi_chgheader, filter order is important. Later filters will see the header changes made by earlier ones. +
  • For smfi_addheader, filter order is important. Later filters will see the header changes made by earlier ones.
  • Neither the name nor the value of the header is checked for standards compliance. However, each line of the header must be under 2048 characters and should be under 998 characters. If longer headers diff --git a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html index 16f86c949770..05770bf28d11 100644 --- a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html +++ b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html @@ -1,6 +1,9 @@ smfi_addrcpt +

    smfi_addrcpt

  • diff --git a/contrib/sendmail/libmilter/docs/smfi_chgheader.html b/contrib/sendmail/libmilter/docs/smfi_chgheader.html index 53ad73ce3cd8..5c7e50794945 100644 --- a/contrib/sendmail/libmilter/docs/smfi_chgheader.html +++ b/contrib/sendmail/libmilter/docs/smfi_chgheader.html @@ -1,6 +1,9 @@ smfi_chgheader +

    smfi_chgheader

    diff --git a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html index 9608e61eaeff..7776a4369a86 100644 --- a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html +++ b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html @@ -1,6 +1,9 @@ smfi_delrcpt +

    smfi_delrcpt

    diff --git a/contrib/sendmail/libmilter/docs/smfi_getpriv.html b/contrib/sendmail/libmilter/docs/smfi_getpriv.html index 85c994cd89f5..3d9f9850388c 100644 --- a/contrib/sendmail/libmilter/docs/smfi_getpriv.html +++ b/contrib/sendmail/libmilter/docs/smfi_getpriv.html @@ -1,6 +1,9 @@ smfi_getpriv +

    smfi_getpriv

    diff --git a/contrib/sendmail/libmilter/docs/smfi_getsymval.html b/contrib/sendmail/libmilter/docs/smfi_getsymval.html index 7f3db6ae0ce0..0e9bc58f6560 100644 --- a/contrib/sendmail/libmilter/docs/smfi_getsymval.html +++ b/contrib/sendmail/libmilter/docs/smfi_getsymval.html @@ -1,6 +1,9 @@ smfi_getsymval +

    smfi_getsymval

    diff --git a/contrib/sendmail/libmilter/docs/smfi_insheader.html b/contrib/sendmail/libmilter/docs/smfi_insheader.html new file mode 100644 index 000000000000..837a1fd9b07d --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_insheader.html @@ -0,0 +1,123 @@ + +smfi_insheader + + +

    smfi_insheader

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_insheader(
    +	SMFICTX *ctx,
    +	int hdridx,
    +	char *headerf,
    +	char *headerv
    +);
    +
    +Prepend a header to the current message. +
    DESCRIPTION + + + + + + + + + +
    Called WhenCalled only from xxfi_eom.
    EffectsPrepends a header to the current message.
    + + +
    ARGUMENTS + + + + + + + + + + +
    ArgumentDescription
    ctxOpaque context structure. +
    hdridxThe location in the internal header list where this header should + be inserted; 0 makes it the topmost header, etc. +
    headerfThe header name, a non-NULL, null-terminated string. +
    headervThe header value to be added, a non-NULL, null-terminated string. This may be the empty string. +
    +
    RETURN VALUESsmfi_insheader returns MI_FAILURE if: +
    • headerf or headerv is NULL. +
    • Adding headers in the current connection state is invalid. +
    • Memory allocation fails. +
    • A network error occurs. +
    • SMFIF_ADDHDRS was not set when smfi_register was called. +
    +Otherwise, it returns MI_SUCCESS. +
    NOTES +
    • smfi_insheader does not change a message's existing headers. +To change a header's current value, use smfi_chgheader. +
    • A filter which calls smfi_insheader must have set the SMFIF_ADDHDRS flag in the smfiDesc_str passed to smfi_register. +
    • For smfi_insheader, filter order is important. Later filters will see the header changes made by earlier ones. +
    • If hdridx is a number larger than the number of headers in the message, the header will simply be appended. +
    • Neither the name nor the value of the header is checked for + standards compliance. However, each line of the header must be under + 2048 characters and should be under 998 characters. If longer headers + are needed, make them multi-line. To make a multi-line header, insert + a line feed (ASCII 0x0a, or \n in C) followed by at least + one whitespace character such as a space (ASCII 0x20) or tab (ASCII 0x09, + or \t in C). The line feed should NOT be preceded by a + carriage return (ASCII 0x0d); the MTA will add this automatically. + It is the filter writer's responsibility to ensure that no standards + are violated. +
    +
    EXAMPLE +
    +  int ret;
    +  SMFICTX *ctx;
    +
    +  ...
    +
    +  ret = smfi_insheader(ctx, 0, "First", "See me?");
    + 
    +
    + +
    + +Copyright (c) 2004 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/smfi_main.html b/contrib/sendmail/libmilter/docs/smfi_main.html index 674ef69a282f..4e772a10d62d 100644 --- a/contrib/sendmail/libmilter/docs/smfi_main.html +++ b/contrib/sendmail/libmilter/docs/smfi_main.html @@ -1,6 +1,9 @@ smfi_main +

    smfi_main

    diff --git a/contrib/sendmail/libmilter/docs/smfi_opensocket.html b/contrib/sendmail/libmilter/docs/smfi_opensocket.html new file mode 100644 index 000000000000..914ae5036b14 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_opensocket.html @@ -0,0 +1,78 @@ + +smfi_opensocket + + +

    smfi_opensocket

    + +
    + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_opensocket(
    +	bool rmsocket
    +);
    +
    +Attempt to create the interface socket MTAs will use to connect to the +filter. +
    DESCRIPTION + + + + + + + + + +
    Called WhenCalled only from program mainline, before calling +smfi_main().
    Effectssmfi_opensocket attempts to create the socket specified previously by +a call to smfi_setconn() which will be the interface between MTAs +and the filter. This allows the calling application to ensure that the +socket can be created. If this is not called, smfi_main() will +do so implicitly.
    + + +
    ARGUMENTS + + + + +
    ArgumentDescription
    rmsocketA flag indicating whether or not the library should try to + remove any existing UNIX domain socket before trying to create + a new one. +
    +
    RETURN VALUESsmfi_opensocket will fail and return MI_FAILURE if: +
      +
    • The interface socket could not be created for any reason. +
    • rmsocket was true, and either the socket could + not be examined, or exists and could not be removed. +
    • smfi_setconn() has not been called. +
    +Otherwise, it will return MI_SUCCESS +
    + +
    + +Copyright (c) 2003 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/smfi_progress.html b/contrib/sendmail/libmilter/docs/smfi_progress.html new file mode 100644 index 000000000000..85f12195b519 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_progress.html @@ -0,0 +1,68 @@ + +smfi_progress + + +

    smfi_progress

    + + + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_progress(
    +	SMFICTX *ctx;
    +);
    +
    +Notify the MTA that an operation is still in progress. +
    DESCRIPTION + + + + + + + + + +
    Called WhenCalled only from xxfi_eom.
    Effectssmfi_progress notifies the MTA that the filter is still working +on a message, causing the MTA to re-start its timeouts.
    + + +
    ARGUMENTS + + + + +
    ArgumentDescription
    ctxOpaque context structure. +
    +
    RETURN VALUESsmfi_progress will fail and return MI_FAILURE if: +
      +
    • A network error occurs. +
    +Otherwise, it will return MI_SUCCESS +
    + +
    + +Copyright (c) 2003 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/smfi_quarantine.html b/contrib/sendmail/libmilter/docs/smfi_quarantine.html new file mode 100644 index 000000000000..066cce81d739 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_quarantine.html @@ -0,0 +1,73 @@ + +smfi_quarantine + + +

    smfi_quarantine

    + + + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_quarantine(
    +	SMFICTX *ctx;
    +	char *reason;
    +);
    +
    +Quarantine the message using the given reason. +
    DESCRIPTION + + + + + + + + + +
    Called WhenCalled only from xxfi_eom.
    Effectssmfi_quarantine quarantines the message using the given reason.
    + + +
    ARGUMENTS + + + + + + +
    ArgumentDescription
    ctxOpaque context structure. +
    reasonThe quarantine reason, a non-NULL and non-empty null-terminated string. +
    +
    RETURN VALUESsmfi_quarantine will fail and return MI_FAILURE if: +
      +
    • reason is NULL or empty. +
    • A network error occurs. +
    • SMFIF_QUARANTINE was not set when smfi_register was called. +
    +Otherwise, it will return MI_SUCCESS +
    + +
    + +Copyright (c) 2002-2003 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/smfi_register.html b/contrib/sendmail/libmilter/docs/smfi_register.html index 0aac254a6b40..3f6ed8301ee2 100644 --- a/contrib/sendmail/libmilter/docs/smfi_register.html +++ b/contrib/sendmail/libmilter/docs/smfi_register.html @@ -1,6 +1,9 @@ smfi_register +

    smfi_register

    diff --git a/contrib/sendmail/libmilter/docs/smfi_replacebody.html b/contrib/sendmail/libmilter/docs/smfi_replacebody.html index 2ef0f4933529..91ac8822ec9a 100644 --- a/contrib/sendmail/libmilter/docs/smfi_replacebody.html +++ b/contrib/sendmail/libmilter/docs/smfi_replacebody.html @@ -1,6 +1,9 @@ smfi_replacebody +

    smfi_replacebody

    diff --git a/contrib/sendmail/libmilter/docs/smfi_setbacklog.html b/contrib/sendmail/libmilter/docs/smfi_setbacklog.html index d55926619002..79d8d527209b 100644 --- a/contrib/sendmail/libmilter/docs/smfi_setbacklog.html +++ b/contrib/sendmail/libmilter/docs/smfi_setbacklog.html @@ -1,6 +1,9 @@ smfi_setbacklog +

    smfi_setbacklog

    diff --git a/contrib/sendmail/libmilter/docs/smfi_setconn.html b/contrib/sendmail/libmilter/docs/smfi_setconn.html index 0f810b4b3385..07461ccced2f 100644 --- a/contrib/sendmail/libmilter/docs/smfi_setconn.html +++ b/contrib/sendmail/libmilter/docs/smfi_setconn.html @@ -1,6 +1,9 @@ smfi_setconn +

    smfi_setconn

    diff --git a/contrib/sendmail/libmilter/docs/smfi_setdbg.html b/contrib/sendmail/libmilter/docs/smfi_setdbg.html new file mode 100644 index 000000000000..3203f0ff8bfd --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_setdbg.html @@ -0,0 +1,67 @@ + +smfi_setdbg + + +

    smfi_setdbg

    + +
    + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_setdbg(
    +	int level;
    +);
    +
    +Set the debugging (tracing) level for the milter library. +
    DESCRIPTION + + + + + + + + + +
    Called WhenCalled from any any routine at any time.
    Effectssmfi_setdbg sets the milter library's internal debugging level +to a new level so that code details may be traced. +A level of zero turns off debugging. The greater +(more positive) the level the more detailed the debugging. Six is +the current, highest, useful value.
    + + +
    ARGUMENTS + + + + +
    ArgumentDescription
    levelThe new debugging level +
    +
    RETURN VALUESsmfi_setdbg returns MI_SUCCESS by default. +
    + +
    + +Copyright (c) 2003 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/smfi_setmlreply.html b/contrib/sendmail/libmilter/docs/smfi_setmlreply.html new file mode 100644 index 000000000000..060c81d4d944 --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_setmlreply.html @@ -0,0 +1,147 @@ + +smfi_setmlreply + + +

    smfi_setmlreply

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_setmlreply(
    +	SMFICTX *ctx,
    +	char *rcode,
    +	char *xcode,
    +	...
    +);
    +
    +Set the default SMTP error reply code to a multi-line response. Only 4XX +and 5XX replies are accepted. +
    DESCRIPTION + + + + + + + + + +
    Called Whensmfi_setmlreply may be called from any of the xxfi_ callbacks +other than xxfi_connect.
    EffectsDirectly set the SMTP error reply code for this connection to the given +lines after the xcode. The list of arguments must be NULL terminated. +This code will be used on subsequent error replies resulting from actions +taken by this filter.
    + + +
    ARGUMENTS + + + + + + + + + + +
    ArgumentDescription
    ctxOpaque context structure. +
    rcodeThe three-digit (RFC 821/2821) SMTP reply code, as a + null-terminated string. rcode cannot be NULL, and must be a valid + 4XX or 5XX reply code. +
    xcodeThe extended (RFC 1893/2034) reply code. If xcode is NULL, no + extended code is used. Otherwise, xcode must conform to RFC 1893/2034. +
    ...The remainder of the arguments are single lines of text, up to + 32 arguments, which will be used as the text part of the SMTP + reply. The list must be NULL terminated. +
    +
    RETURN VALUES +For example, the code:
    +
    +	ret = smfi_setmlreply(ctx, "550", "5.7.0",
    +			      "Spammer access rejected",
    +			      "Please see our policy at:",
    +			      "http://www.example.com/spampolicy.html",
    +			      NULL);
    +
    +
    would give the SMTP response:
    +
    +550-5.7.0 Spammer access rejected
    +550-5.7.0 Please see our policy at:
    +550 5.7.0 http://www.example.com/spampolicy.html
    +
    RETURN VALUESsmfi_setmlreply will fail and return MI_FAILURE if: +
      +
    • The rcode or xcode argument is invalid. +
    • A memory-allocation failure occurs. +
    • If any text line contains a carraige return or line feed. +
    • The length of any text line is more than MAXREPLYLEN (980). +
    • More than 32 lines of text replies are given. +
    +Otherwise, it return MI_SUCCESS. +
    NOTES +
      +
    • Values passed to smfi_setmlreply are not checked for standards compliance. +
    • The message parameter should contain only printable characters, +other characters may lead to undefined behavior. +For example, CR or LF will cause the call to fail, +single '%' characters will cause the text to be ignored +(if there really should be a '%' in the string, +use '%%' just like for printf(3)). +
    • For details about reply codes and their meanings, please see RFC's +821/ +2821 +and +1893/ +2034. +
    • If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used +for the message, the custom reply is not used. +
    • Similarly, if the reply code (rcode) given is a '5XX' code but +SMFI_TEMPFAIL is used for the message, the custom reply is not used. +
      +Note: in neither of the last two cases an error is returned to the milter, +libmilter silently ignores the reply code. +
    • +If the milter returns SMFI_TEMPFAIL +and sets the reply code to '421', +then the SMTP server will terminate the SMTP session with a 421 +error code. +
    +
    + +
    + +Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/smfi_setpriv.html b/contrib/sendmail/libmilter/docs/smfi_setpriv.html index 6bd79965da60..61e30a9841b1 100644 --- a/contrib/sendmail/libmilter/docs/smfi_setpriv.html +++ b/contrib/sendmail/libmilter/docs/smfi_setpriv.html @@ -1,6 +1,9 @@ smfi_setpriv +

    smfi_setpriv

    diff --git a/contrib/sendmail/libmilter/docs/smfi_setreply.html b/contrib/sendmail/libmilter/docs/smfi_setreply.html index d5b0e2453306..f62196b7a6cb 100644 --- a/contrib/sendmail/libmilter/docs/smfi_setreply.html +++ b/contrib/sendmail/libmilter/docs/smfi_setreply.html @@ -1,6 +1,9 @@ smfi_setreply +

    smfi_setreply

    @@ -91,6 +94,14 @@ and for the message, the custom reply is not used.
  • Similarly, if the reply code (rcode) given is a '5XX' code but SMFI_TEMPFAIL is used for the message, the custom reply is not used. +
    +Note: in neither of the last two cases an error is returned to the milter, +libmilter silently ignores the reply code. +
  • +If the milter returns SMFI_TEMPFAIL +and sets the reply code to '421', +then the SMTP server will terminate the SMTP session with a 421 +error code. diff --git a/contrib/sendmail/libmilter/docs/smfi_settimeout.html b/contrib/sendmail/libmilter/docs/smfi_settimeout.html index c27f8176f5aa..08f01ed97801 100644 --- a/contrib/sendmail/libmilter/docs/smfi_settimeout.html +++ b/contrib/sendmail/libmilter/docs/smfi_settimeout.html @@ -1,6 +1,9 @@ smfi_settimeout +

    smfi_settimeout

  • diff --git a/contrib/sendmail/libmilter/docs/smfi_stop.html b/contrib/sendmail/libmilter/docs/smfi_stop.html new file mode 100644 index 000000000000..bf934231c99e --- /dev/null +++ b/contrib/sendmail/libmilter/docs/smfi_stop.html @@ -0,0 +1,73 @@ + +smfi_stop + + +

    smfi_stop

    + +
    + + + + + + + + + + + + + +
    SYNOPSIS +
    +#include <libmilter/mfapi.h>
    +int smfi_stop(void);
    +
    +Start an orderly shutdown of the milter. No connections will be accepted +after this call. +
    DESCRIPTION + + + + + + + + + +
    Called WhenCalled from any of the Callback routines +or any error-handling routines at any time.
    EffectsThe smfi_stop routine +causes each thread to finish its current connection, then exit. +When all threads have exited, the call +to smfi_main returns to your calling program, +which may then exit or warm-restart. +
    + + +
    ARGUMENTS + + + + +
    ArgumentDescription
    voidTakes no arguement. +
    +
    RETURN VALUESsmfi_stop always returns SMFI_CONTINUE. But note: +
      +
    • Another internal routine may already have asked the milter to abort. +
    • Another routine may already have asked the milter to stop. +
    • There is no way to cancel the stop process once it has begun. +
    +
    + +
    + +Copyright (c) 2003 Sendmail, Inc. and its suppliers. +All rights reserved. +
    +By using this file, you agree to the terms and conditions set +forth in the LICENSE. +
    + + diff --git a/contrib/sendmail/libmilter/docs/xxfi_abort.html b/contrib/sendmail/libmilter/docs/xxfi_abort.html index d47b50518bff..3db1117c0d1a 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_abort.html +++ b/contrib/sendmail/libmilter/docs/xxfi_abort.html @@ -1,6 +1,9 @@ xxfi_abort +

    xxfi_abort

    diff --git a/contrib/sendmail/libmilter/docs/xxfi_body.html b/contrib/sendmail/libmilter/docs/xxfi_body.html index 6aed207c8480..044e9ce22f33 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_body.html +++ b/contrib/sendmail/libmilter/docs/xxfi_body.html @@ -1,6 +1,9 @@ xxfi_body +

    xxfi_body

    diff --git a/contrib/sendmail/libmilter/docs/xxfi_close.html b/contrib/sendmail/libmilter/docs/xxfi_close.html index 30db78643d7f..99b36e66acc7 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_close.html +++ b/contrib/sendmail/libmilter/docs/xxfi_close.html @@ -1,6 +1,9 @@ xxfi_close +

    xxfi_close

    @@ -43,6 +46,18 @@ The current connection is being closed.
    NOTES
      +
    • xxfi_close may be called "out-of-order", i.e. before even the +xxfi_connect is called. +After a connection is established by the MTA to the filter, +if the MTA decides this connection's traffic will be discarded +(e.g. via an access_db result), no data will be passed to the +filter from the MTA until the client closes down. +At that time, xxfi_close is called. +It can therefore be the only callback ever used for a given connection, +and developers should anticipate this possibility when crafting their +xxfi_close code. +In particular, it is incorrect to assume the private context pointer +will be something other than NULL in this callback.
    • xxfi_close is called on close even if the previous mail transaction was aborted.
    • xxfi_close is responsible for freeing any resources allocated on a @@ -56,7 +71,7 @@ currently ignored.
      -Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers. +Copyright (c) 2000, 2003, 2004 Sendmail, Inc. and its suppliers. All rights reserved.
      By using this file, you agree to the terms and conditions set diff --git a/contrib/sendmail/libmilter/docs/xxfi_connect.html b/contrib/sendmail/libmilter/docs/xxfi_connect.html index 85d02e412663..b39bc946f1bc 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_connect.html +++ b/contrib/sendmail/libmilter/docs/xxfi_connect.html @@ -1,6 +1,9 @@ xxfi_connect +

      xxfi_connect

      @@ -78,7 +81,9 @@ is passed to smfi_register(). + temporary failure reply code. If also used in conjunction + with smfi_setreply() to set a reply whose SMTP + code is 421, the MTA will drop the connection immediately. diff --git a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html index 5eeaa376fdc9..df9e0fc2cd95 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html +++ b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html @@ -1,6 +1,9 @@ xxfi_envfrom +

      xxfi_envfrom

      SMFIS_TEMPFAIL Reject all commands and messages from this client with a - temporary failure reply code.
      SMFIS_REJECT
      diff --git a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html index a96ac95f2e15..e0c609421b91 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html +++ b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html @@ -1,6 +1,9 @@ xxfi_envrcpt +

      xxfi_envrcpt

      diff --git a/contrib/sendmail/libmilter/docs/xxfi_eoh.html b/contrib/sendmail/libmilter/docs/xxfi_eoh.html index b745959594c0..350ca969f56f 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_eoh.html +++ b/contrib/sendmail/libmilter/docs/xxfi_eoh.html @@ -1,6 +1,9 @@ xxfi_eoh +

      xxfi_eoh

      diff --git a/contrib/sendmail/libmilter/docs/xxfi_eom.html b/contrib/sendmail/libmilter/docs/xxfi_eom.html index 1c99103cd1e8..78c6943babb1 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_eom.html +++ b/contrib/sendmail/libmilter/docs/xxfi_eom.html @@ -1,6 +1,9 @@ xxfi_eom +

      xxfi_eom

      diff --git a/contrib/sendmail/libmilter/docs/xxfi_header.html b/contrib/sendmail/libmilter/docs/xxfi_header.html index 1be49584c808..3ad3e5b2e71b 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_header.html +++ b/contrib/sendmail/libmilter/docs/xxfi_header.html @@ -1,6 +1,9 @@ xxfi_header +

      xxfi_header

      diff --git a/contrib/sendmail/libmilter/docs/xxfi_helo.html b/contrib/sendmail/libmilter/docs/xxfi_helo.html index 0eb8df6703cb..dc7bbf33ca5f 100644 --- a/contrib/sendmail/libmilter/docs/xxfi_helo.html +++ b/contrib/sendmail/libmilter/docs/xxfi_helo.html @@ -1,6 +1,9 @@ xxfi_helo +

      xxfi_helo

      diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c index 6bd225ce5542..66ed99223f96 100644 --- a/contrib/sendmail/libmilter/engine.c +++ b/contrib/sendmail/libmilter/engine.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: engine.c,v 8.109.2.8 2003/12/01 23:57:45 msk Exp $") +SM_RCSID("@(#)$Id: engine.c,v 8.119 2003/12/02 18:53:57 ca Exp $") #include "libmilter.h" @@ -64,16 +64,10 @@ typedef struct cmdfct_t cmdfct; #define CI_HELO 1 #define CI_MAIL 2 #define CI_RCPT 3 -#if _FFR_MILTER_MACROS_EOM -# define CI_EOM 4 -# if CI_EOM >= MAX_MACROS_ENTRIES +#define CI_EOM 4 +#if CI_EOM >= MAX_MACROS_ENTRIES ERROR: do not compile with CI_EOM >= MAX_MACROS_ENTRIES -# endif -#else /* _FFR_MILTER_MACROS_EOM */ -# if CI_RCPT >= MAX_MACROS_ENTRIES -ERROR: do not compile with CI_RCPT >= MAX_MACROS_ENTRIES -# endif -#endif /* _FFR_MILTER_MACROS_EOM */ +#endif /* function prototypes */ static int st_abortfct __P((genarg *)); @@ -86,6 +80,12 @@ static int st_helo __P((genarg *)); static int st_header __P((genarg *)); static int st_sender __P((genarg *)); static int st_rcpt __P((genarg *)); +#if SMFI_VERSION > 2 +static int st_unknown __P((genarg *)); +#endif /* SMFI_VERSION > 2 */ +#if SMFI_VERSION > 3 +static int st_data __P((genarg *)); +#endif /* SMFI_VERSION > 3 */ static int st_eoh __P((genarg *)); static int st_quit __P((genarg *)); static int sendreply __P((sfsistat, socket_t, struct timeval *, SMFICTX_PTR)); @@ -102,13 +102,15 @@ static int dec_arg2 __P((char *, size_t, char **, char **)); #define ST_HELO 3 /* helo */ #define ST_MAIL 4 /* mail from */ #define ST_RCPT 5 /* rcpt to */ -#define ST_HDRS 6 /* headers */ -#define ST_EOHS 7 /* end of headers */ -#define ST_BODY 8 /* body */ -#define ST_ENDM 9 /* end of message */ -#define ST_QUIT 10 /* quit */ -#define ST_ABRT 11 /* abort */ -#define ST_LAST ST_ABRT +#define ST_DATA 6 /* data */ +#define ST_HDRS 7 /* headers */ +#define ST_EOHS 8 /* end of headers */ +#define ST_BODY 9 /* body */ +#define ST_ENDM 10 /* end of message */ +#define ST_QUIT 11 /* quit */ +#define ST_ABRT 12 /* abort */ +#define ST_UNKN 13 /* unknown SMTP command */ +#define ST_LAST ST_UNKN /* last valid state */ #define ST_SKIP 15 /* not a state but required for the state table */ /* in a mail transaction? must be before eom according to spec. */ @@ -125,19 +127,25 @@ static int dec_arg2 __P((char *, size_t, char **, char **)); #define MI_MASK(x) (0x0001 << (x)) /* generate a bit "mask" for a state */ #define NX_INIT (MI_MASK(ST_OPTS)) -#define NX_OPTS (MI_MASK(ST_CONN)) -#define NX_CONN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL)) -#define NX_HELO (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL)) -#define NX_MAIL (MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT)) -#define NX_RCPT (MI_MASK(ST_HDRS) | MI_MASK(ST_EOHS) | \ +#define NX_OPTS (MI_MASK(ST_CONN) | MI_MASK(ST_UNKN)) +#define NX_CONN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN)) +#define NX_HELO (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN)) +#define NX_MAIL (MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | MI_MASK(ST_UNKN)) +#define NX_RCPT (MI_MASK(ST_HDRS) | MI_MASK(ST_EOHS) | MI_MASK(ST_DATA) | \ MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | \ - MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT)) + MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | MI_MASK(ST_UNKN)) +#define NX_DATA (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT)) #define NX_HDRS (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT)) #define NX_EOHS (MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | MI_MASK(ST_ABRT)) #define NX_BODY (MI_MASK(ST_ENDM) | MI_MASK(ST_BODY) | MI_MASK(ST_ABRT)) -#define NX_ENDM (MI_MASK(ST_QUIT) | MI_MASK(ST_MAIL)) +#define NX_ENDM (MI_MASK(ST_QUIT) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN)) #define NX_QUIT 0 #define NX_ABRT 0 +#define NX_UNKN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | \ + MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | \ + MI_MASK(ST_DATA) | \ + MI_MASK(ST_BODY) | MI_MASK(ST_UNKN) | \ + MI_MASK(ST_ABRT) | MI_MASK(ST_QUIT)) #define NX_SKIP MI_MASK(ST_SKIP) static int next_states[] = @@ -148,12 +156,14 @@ static int next_states[] = NX_HELO, NX_MAIL, NX_RCPT, + NX_DATA, NX_HDRS, NX_EOHS, NX_BODY, NX_ENDM, NX_QUIT, - NX_ABRT + NX_ABRT, + NX_UNKN }; /* commands received by milter */ @@ -163,18 +173,20 @@ static cmdfct cmds[] = {SMFIC_MACRO, CM_ARGV, ST_NONE, CT_KEEP, CI_NONE, st_macros }, {SMFIC_BODY, CM_ARG1, ST_BODY, CT_CONT, CI_NONE, st_bodychunk }, {SMFIC_CONNECT, CM_ARG2, ST_CONN, CT_CONT, CI_CONN, st_connectinfo }, -#if _FFR_MILTER_MACROS_EOM {SMFIC_BODYEOB, CM_ARG1, ST_ENDM, CT_CONT, CI_EOM, st_bodyend }, -#else /* _FFR_MILTER_MACROS_EOM */ -{SMFIC_BODYEOB, CM_ARG1, ST_ENDM, CT_CONT, CI_NONE, st_bodyend }, -#endif /* _FFR_MILTER_MACROS_EOM */ {SMFIC_HELO, CM_ARG1, ST_HELO, CT_CONT, CI_HELO, st_helo }, {SMFIC_HEADER, CM_ARG2, ST_HDRS, CT_CONT, CI_NONE, st_header }, {SMFIC_MAIL, CM_ARGV, ST_MAIL, CT_CONT, CI_MAIL, st_sender }, {SMFIC_OPTNEG, CM_ARGO, ST_OPTS, CT_CONT, CI_NONE, st_optionneg }, {SMFIC_EOH, CM_ARG0, ST_EOHS, CT_CONT, CI_NONE, st_eoh }, {SMFIC_QUIT, CM_ARG0, ST_QUIT, CT_END, CI_NONE, st_quit }, +#if SMFI_VERSION > 3 +{SMFIC_DATA, CM_ARG0, ST_DATA, CT_CONT, CI_NONE, st_data }, +#endif /* SMFI_VERSION > 3 */ {SMFIC_RCPT, CM_ARGV, ST_RCPT, CT_IGNO, CI_RCPT, st_rcpt } +#if SMFI_VERSION > 2 +,{SMFIC_UNKNOWN,CM_ARG1, ST_UNKN, CT_IGNO, CI_NONE, st_unknown } +#endif /* SMFI_VERSION > 2 */ }; /* additional (internal) reply codes */ @@ -698,6 +710,7 @@ st_connectinfo(g) return (*fi_connect)(g->a_ctx, g->a_buf, family != SMFIA_UNKNOWN ? &sockaddr : NULL); } + /* ** ST_EOH -- end of headers ** @@ -721,6 +734,33 @@ st_eoh(g) return (*fi_eoh)(g->a_ctx); return SMFIS_CONTINUE; } + +#if SMFI_VERSION > 3 +/* +** ST_DATA -- DATA command +** +** Parameters: +** g -- generic argument structure +** +** Returns: +** continue or filter-specified value +*/ + +static int +st_data(g) + genarg *g; +{ + sfsistat (*fi_data) __P((SMFICTX *)); + + if (g == NULL) + return _SMFIS_ABORT; + if (g->a_ctx->ctx_smfi != NULL && + (fi_data = g->a_ctx->ctx_smfi->xxfi_data) != NULL) + return (*fi_data)(g->a_ctx); + return SMFIS_CONTINUE; +} +#endif /* SMFI_VERSION > 3 */ + /* ** ST_HELO -- helo/ehlo command ** @@ -826,6 +866,34 @@ st_rcpt(g) { ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT) } + +#if SMFI_VERSION > 2 +/* +** ST_UNKNOWN -- unrecognized or unimplemented command +** +** Parameters: +** g -- generic argument structure +** +** Returns: +** continue or filter-specified value +*/ + +static int +st_unknown(g) + genarg *g; +{ + sfsistat (*fi_unknown) __P((SMFICTX *, char *)); + + if (g == NULL) + return _SMFIS_ABORT; + mi_clr_macros(g->a_ctx, g->a_idx + 1); + if (g->a_ctx->ctx_smfi != NULL && + (fi_unknown = g->a_ctx->ctx_smfi->xxfi_unknown) != NULL) + return (*fi_unknown)(g->a_ctx, g->a_buf); + return SMFIS_CONTINUE; +} +#endif /* SMFI_VERSION > 2 */ + /* ** ST_MACROS -- deal with macros received from the MTA ** @@ -864,11 +932,9 @@ st_macros(g) case SMFIC_RCPT: i = CI_RCPT; break; -#if _FFR_MILTER_MACROS_EOM case SMFIC_BODYEOB: i = CI_EOM; break; -#endif /* _FFR_MILTER_MACROS_EOM */ default: free(argv); return _SMFIS_FAIL; diff --git a/contrib/sendmail/libmilter/handler.c b/contrib/sendmail/libmilter/handler.c index db3cc4645d8d..3acfc5fca379 100644 --- a/contrib/sendmail/libmilter/handler.c +++ b/contrib/sendmail/libmilter/handler.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: handler.c,v 8.30.2.4 2003/01/23 22:28:36 ca Exp $") +SM_RCSID("@(#)$Id: handler.c,v 8.36 2003/09/08 21:27:14 yuri Exp $") #include "libmilter.h" diff --git a/contrib/sendmail/libmilter/libmilter.h b/contrib/sendmail/libmilter/libmilter.h index 13bddcefea1d..65b0a47d9abe 100644 --- a/contrib/sendmail/libmilter/libmilter.h +++ b/contrib/sendmail/libmilter/libmilter.h @@ -19,7 +19,7 @@ #ifdef _DEFINE # define EXTERN # define INIT(x) = x -SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.33.2.13 2003/10/20 21:51:50 msk Exp $") +SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.50 2003/12/11 18:14:34 ca Exp $") #else /* _DEFINE */ # define EXTERN extern # define INIT(x) @@ -49,7 +49,7 @@ typedef pthread_mutex_t smutex_t; # define smutex_unlock(mp) (pthread_mutex_unlock(mp) == 0) # define smutex_trylock(mp) (pthread_mutex_trylock(mp) == 0) -#if _FFR_USE_POLL +#if SM_CONF_POLL # include # define MI_POLLSELECT "poll" @@ -86,7 +86,7 @@ typedef pthread_mutex_t smutex_t; # define FD_RD_READY(sd, rds, excs, timeout) \ poll(&(rds), 1, MI_MS(timeout)) -#else /* _FFR_USE_POLL */ +#else /* SM_CONF_POLL */ # include # define MI_POLLSELECT "select" @@ -113,7 +113,7 @@ typedef pthread_mutex_t smutex_t; # define FD_RD_READY(sd, rds, excs, timeout) \ select((sd) + 1, &(rds), NULL, &(excs), (timeout)) -#endif /* _FFR_USE_POLL */ +#endif /* SM_CONF_POLL */ #include diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c index bb7a297d44df..ee88f2325c72 100644 --- a/contrib/sendmail/libmilter/listener.c +++ b/contrib/sendmail/libmilter/listener.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: listener.c,v 8.85.2.17 2003/10/21 17:22:57 ca Exp $") +SM_RCSID("@(#)$Id: listener.c,v 8.109 2004/02/04 22:55:59 ca Exp $") /* ** listener.c -- threaded network listener @@ -41,7 +41,7 @@ static socket_t mi_milteropen __P((char *, int, bool, char *)); ** backlog -- listen backlog ** dbg -- debug level ** rmsocket -- if true, try to unlink() the socket first -** (UNIX domain sockets only) +** (UNIX domain sockets only) ** smfi -- filter structure to use ** ** Return value: @@ -79,7 +79,7 @@ mi_opensocket(conn, backlog, dbg, rmsocket, smfi) (void) smutex_unlock(&L_Mutex); return MI_FAILURE; } -#if !_FFR_USE_POLL +#if !SM_CONF_POLL if (!SM_FD_OK_SELECT(listenfd)) { smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d", @@ -87,7 +87,7 @@ mi_opensocket(conn, backlog, dbg, rmsocket, smfi) (void) smutex_unlock(&L_Mutex); return MI_FAILURE; } -#endif /* !_FFR_USE_POLL */ +#endif /* !SM_CONF_POLL */ return MI_SUCCESS; } @@ -585,9 +585,7 @@ mi_closener() struct stat fileinfo; removable = sockpath != NULL && -#if _FFR_MILTER_ROOT_UNSAFE geteuid() != 0 && -#endif /* _FFR_MILTER_ROOT_UNSAFE */ fstat(listenfd, &sockinfo) == 0 && (S_ISFIFO(sockinfo.st_mode) # ifdef S_ISSOCK @@ -635,8 +633,6 @@ mi_closener() ** Parameters: ** conn -- connection description ** dbg -- debug level -** rmsocket -- if true, try to unlink() the socket first -** (UNIX domain sockets only) ** smfi -- filter structure to use ** timeout -- timeout for reads/writes ** backlog -- listen queue backlog size @@ -704,6 +700,9 @@ mi_listener(conn, dbg, smfi, timeout, backlog) int backlog; { socket_t connfd = INVALID_SOCKET; +#if _FFR_DUP_FD + socket_t dupfd = INVALID_SOCKET; +#endif /* _FFR_DUP_FD */ int sockopt = 1; int r, mistop; int ret = MI_SUCCESS; @@ -802,7 +801,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) save_errno = EINVAL; } -#if !_FFR_USE_POLL +#if !SM_CONF_POLL /* check if acceptable for select() */ if (ValidSocket(connfd) && !SM_FD_OK_SELECT(connfd)) { @@ -810,11 +809,36 @@ mi_listener(conn, dbg, smfi, timeout, backlog) connfd = INVALID_SOCKET; save_errno = ERANGE; } -#endif /* !_FFR_USE_POLL */ +#endif /* !SM_CONF_POLL */ if (!ValidSocket(connfd)) { - if (save_errno == EINTR) + if (save_errno == EINTR +#ifdef EAGAIN + || save_errno == EAGAIN +#endif /* EAGAIN */ +#ifdef ECONNABORTED + || save_errno == ECONNABORTED +#endif /* ECONNABORTED */ +#ifdef EMFILE + || save_errno == EMFILE +#endif /* EMFILE */ +#ifdef ENFILE + || save_errno == ENFILE +#endif /* ENFILE */ +#ifdef ENOBUFS + || save_errno == ENOBUFS +#endif /* ENOBUFS */ +#ifdef ENOMEM + || save_errno == ENOMEM +#endif /* ENOMEM */ +#ifdef ENOSR + || save_errno == ENOSR +#endif /* ENOSR */ +#ifdef EWOULDBLOCK + || save_errno == EWOULDBLOCK +#endif /* EWOULDBLOCK */ + ) continue; acnt++; smi_log(SMI_LOG_ERR, @@ -830,6 +854,19 @@ mi_listener(conn, dbg, smfi, timeout, backlog) continue; } acnt = 0; /* reset error counter for accept() */ +#if _FFR_DUP_FD + dupfd = fcntl(connfd, F_DUPFD, 256); + if (ValidSocket(dupfd) +# if !SM_CONF_POLL + && SM_FD_OK_SELECT(dupfd) +# endif /* !SM_CONF_POLL */ + ) + { + close(connfd); + connfd = dupfd; + dupfd = INVALID_SOCKET; + } +#endif /* _FFR_DUP_FD */ if (setsockopt(connfd, SOL_SOCKET, SO_KEEPALIVE, (void *) &sockopt, sizeof sockopt) < 0) diff --git a/contrib/sendmail/libmilter/main.c b/contrib/sendmail/libmilter/main.c index 36b99f0e63dc..8692127b834a 100644 --- a/contrib/sendmail/libmilter/main.c +++ b/contrib/sendmail/libmilter/main.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: main.c,v 8.64.2.13 2003/10/20 22:27:13 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.79 2003/10/20 22:25:09 ca Exp $") #define _DEFINE 1 #include "libmilter.h" @@ -95,10 +95,9 @@ static char *conn = NULL; static int timeout = MI_TIMEOUT; static int backlog = MI_SOMAXCONN; -#if _FFR_SMFI_OPENSOCKET /* ** SMFI_OPENSOCKET -- try the socket setup to make sure we'll be -** able to start up +** able to start up ** ** Parameters: ** rmsocket -- if true, instructs libmilter to attempt @@ -118,7 +117,6 @@ smfi_opensocket(rmsocket) return mi_opensocket(conn, backlog, dbg, rmsocket, smfi); } -#endif /* _FFR_SMFI_OPENSOCKET */ /* ** SMFI_SETDBG -- set debug level. @@ -239,6 +237,7 @@ smfi_main() /* Startup the listener */ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS) r = MI_FAILURE; + return r; } diff --git a/contrib/sendmail/libmilter/signal.c b/contrib/sendmail/libmilter/signal.c index 94e7f153bd70..eed8b7cdb4aa 100644 --- a/contrib/sendmail/libmilter/signal.c +++ b/contrib/sendmail/libmilter/signal.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: signal.c,v 8.37.2.4 2003/11/19 00:22:40 ca Exp $") +SM_RCSID("@(#)$Id: signal.c,v 8.41 2003/11/19 00:25:20 ca Exp $") #include "libmilter.h" diff --git a/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c index 032a6acb288f..ead2c04beffd 100644 --- a/contrib/sendmail/libmilter/smfi.c +++ b/contrib/sendmail/libmilter/smfi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,14 +9,71 @@ */ #include -SM_RCSID("@(#)$Id: smfi.c,v 8.64 2002/04/30 22:22:02 msk Exp $") +SM_RCSID("@(#)$Id: smfi.c,v 8.72 2004/05/05 00:07:21 msk Exp $") #include #include "libmilter.h" +static int smfi_header __P((SMFICTX *, int, int, char *, char *)); + /* for smfi_set{ml}reply, let's be generous. 256/16 should be sufficient */ #define MAXREPLYLEN 980 /* max. length of a reply string */ #define MAXREPLIES 32 /* max. number of reply strings */ +/* +** SMFI_HEADER -- send a header to the MTA +** +** Parameters: +** ctx -- Opaque context structure +** cmd -- Header modification command +** hdridx -- Header index +** headerf -- Header field name +** headerv -- Header field value +** +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +static int +smfi_header(ctx, cmd, hdridx, headerf, headerv) + SMFICTX *ctx; + int cmd; + int hdridx; + char *headerf; + char *headerv; +{ + size_t len, l1, l2, offset; + int r; + mi_int32 v; + char *buf; + struct timeval timeout; + + if (headerf == NULL || *headerf == '\0' || headerv == NULL) + return MI_FAILURE; + timeout.tv_sec = ctx->ctx_timeout; + timeout.tv_usec = 0; + l1 = strlen(headerf) + 1; + l2 = strlen(headerv) + 1; + len = l1 + l2; + if (hdridx >= 0) + len += MILTER_LEN_BYTES; + buf = malloc(len); + if (buf == NULL) + return MI_FAILURE; + offset = 0; + if (hdridx >= 0) + { + v = htonl(hdridx); + (void) memcpy(&(buf[0]), (void *) &v, MILTER_LEN_BYTES); + offset += MILTER_LEN_BYTES; + } + (void) memcpy(buf + offset, headerf, l1); + (void) memcpy(buf + offset + l1, headerv, l2); + r = mi_wr_cmd(ctx->ctx_sd, &timeout, cmd, buf, len); + free(buf); + return r; +} + /* ** SMFI_ADDHEADER -- send a new header to the MTA ** @@ -35,29 +92,36 @@ smfi_addheader(ctx, headerf, headerv) char *headerf; char *headerv; { - /* do we want to copy the stuff or have a special mi_wr_cmd call? */ - size_t len, l1, l2; - int r; - char *buf; - struct timeval timeout; - - if (headerf == NULL || *headerf == '\0' || headerv == NULL) - return MI_FAILURE; if (!mi_sendok(ctx, SMFIF_ADDHDRS)) return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; - l1 = strlen(headerf); - l2 = strlen(headerv); - len = l1 + l2 + 2; - buf = malloc(len); - if (buf == NULL) + + return smfi_header(ctx, SMFIR_ADDHEADER, -1, headerf, headerv); +} + +/* +** SMFI_INSHEADER -- send a new header to the MTA (to be inserted) +** +** Parameters: +** ctx -- Opaque context structure +** hdridx -- index into header list where insertion should occur +** headerf -- Header field name +** headerv -- Header field value +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +int +smfi_insheader(ctx, hdridx, headerf, headerv) + SMFICTX *ctx; + int hdridx; + char *headerf; + char *headerv; +{ + if (!mi_sendok(ctx, SMFIF_ADDHDRS) || hdridx < 0) return MI_FAILURE; - (void) memcpy(buf, headerf, l1 + 1); - (void) memcpy(buf + l1 + 1, headerv, l2 + 1); - r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_ADDHEADER, buf, len); - free(buf); - return r; + + return smfi_header(ctx, SMFIR_INSHEADER, hdridx, headerf, headerv); } /* @@ -80,36 +144,12 @@ smfi_chgheader(ctx, headerf, hdridx, headerv) mi_int32 hdridx; char *headerv; { - /* do we want to copy the stuff or have a special mi_wr_cmd call? */ - size_t len, l1, l2; - int r; - mi_int32 v; - char *buf; - struct timeval timeout; - - if (headerf == NULL || *headerf == '\0') + if (!mi_sendok(ctx, SMFIF_CHGHDRS) || hdridx < 0) return MI_FAILURE; - if (hdridx < 0) - return MI_FAILURE; - if (!mi_sendok(ctx, SMFIF_CHGHDRS)) - return MI_FAILURE; - timeout.tv_sec = ctx->ctx_timeout; - timeout.tv_usec = 0; if (headerv == NULL) headerv = ""; - l1 = strlen(headerf); - l2 = strlen(headerv); - len = l1 + l2 + 2 + MILTER_LEN_BYTES; - buf = malloc(len); - if (buf == NULL) - return MI_FAILURE; - v = htonl(hdridx); - (void) memcpy(&(buf[0]), (void *) &v, MILTER_LEN_BYTES); - (void) memcpy(buf + MILTER_LEN_BYTES, headerf, l1 + 1); - (void) memcpy(buf + MILTER_LEN_BYTES + l1 + 1, headerv, l2 + 1); - r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_CHGHEADER, buf, len); - free(buf); - return r; + + return smfi_header(ctx, SMFIR_CHGHEADER, hdridx, headerf, headerv); } /* @@ -214,7 +254,6 @@ smfi_replacebody(ctx, bodyp, bodylen) return MI_SUCCESS; } -#if _FFR_QUARANTINE /* ** SMFI_QUARANTINE -- quarantine an envelope ** @@ -251,7 +290,6 @@ smfi_quarantine(ctx, reason) free(buf); return r; } -#endif /* _FFR_QUARANTINE */ /* ** MYISENHSC -- check whether a string contains an enhanced status code @@ -365,7 +403,6 @@ smfi_setreply(ctx, rcode, xcode, message) return MI_SUCCESS; } -#if _FFR_MULTILINE /* ** SMFI_SETMLREPLY -- set multiline reply code for the next reply to the MTA ** @@ -477,7 +514,6 @@ smfi_setmlreply(ctx, rcode, xcode, va_alist) SM_VA_END(ap); return MI_SUCCESS; } -#endif /* _FFR_MULTILINE */ /* ** SMFI_SETPRIV -- set private data @@ -584,7 +620,6 @@ smfi_getsymval(ctx, symname) return NULL; } -#if _FFR_SMFI_PROGRESS /* ** SMFI_PROGRESS -- send "progress" message to the MTA to prevent premature ** timeouts during long milter-side operations @@ -610,4 +645,3 @@ smfi_progress(ctx) return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_PROGRESS, NULL, 0); } -#endif /* _FFR_SMFI_PROGRESS */ diff --git a/contrib/sendmail/libsm/Makefile.m4 b/contrib/sendmail/libsm/Makefile.m4 index 563cf1083834..f028c24476d6 100644 --- a/contrib/sendmail/libsm/Makefile.m4 +++ b/contrib/sendmail/libsm/Makefile.m4 @@ -1,11 +1,11 @@ -dnl $Id: Makefile.m4,v 1.64.2.1 2002/06/21 21:58:29 ca Exp $ +dnl $Id: Makefile.m4,v 1.66 2003/11/03 18:28:26 ca Exp $ define(`confREQUIRE_LIBUNIX') include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') PREPENDDEF(`confENVDEF', `confMAPDEF') 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 vsprintf.c vsscanf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.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 vsscanf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c ') bldPRODUCT_END dnl sem.c msg.c dnl syslogio.c diff --git a/contrib/sendmail/libsm/README b/contrib/sendmail/libsm/README index d75d55f8ea87..aff25a1c9e8f 100644 --- a/contrib/sendmail/libsm/README +++ b/contrib/sendmail/libsm/README @@ -5,7 +5,7 @@ # forth in the LICENSE file which can be found at the top level of # the sendmail distribution. # -# $Id: README,v 1.21 2002/01/23 17:30:48 gshapiro Exp $ +# $Id: README,v 1.24 2003/12/20 09:23:48 gshapiro Exp $ # Libsm is a library of generally useful C abstractions. @@ -109,6 +109,9 @@ SM_CONF_BROKEN_STRTOD SM_CONF_GETOPT Set to 1 if your operating system does not include getopt(3). +SM_CONF_LDAP_INITIALIZE + Set to 1 if your LDAP client libraries include ldap_initialize(3). + SM_CONF_LDAP_MEMFREE Set to 1 if your LDAP client libraries include ldap_memfree(3). diff --git a/contrib/sendmail/libsm/assert.c b/contrib/sendmail/libsm/assert.c index 7ba5c1a78e27..7200a0f4cb88 100644 --- a/contrib/sendmail/libsm/assert.c +++ b/contrib/sendmail/libsm/assert.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: assert.c,v 1.25.2.1 2003/12/05 22:44:17 ca Exp $") +SM_RCSID("@(#)$Id: assert.c,v 1.26 2003/12/05 22:45:24 ca Exp $") /* ** Abnormal program termination and assertion checking. diff --git a/contrib/sendmail/libsm/clock.c b/contrib/sendmail/libsm/clock.c index 4d70cb83b482..580555448540 100644 --- a/contrib/sendmail/libsm/clock.c +++ b/contrib/sendmail/libsm/clock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -12,7 +12,7 @@ */ #include -SM_RCSID("@(#)$Id: clock.c,v 1.35.2.10 2003/06/26 16:36:49 ca Exp $") +SM_RCSID("@(#)$Id: clock.c,v 1.45 2004/01/19 19:32:08 ca Exp $") #include #include #include @@ -523,11 +523,14 @@ sleep(intvl) SM_EVENT *ev; #if _FFR_SLEEP_USE_SELECT > 0 int r; +# if _FFR_SLEEP_USE_SELECT > 0 + struct timeval sm_io_to; +# endif /* _FFR_SLEEP_USE_SELECT > 0 */ #endif /* _FFR_SLEEP_USE_SELECT > 0 */ #if SM_CONF_SETITIMER struct timeval now, begin, diff; # if _FFR_SLEEP_USE_SELECT > 0 - struct timeval sm_io_to, slpv; + struct timeval slpv; # endif /* _FFR_SLEEP_USE_SELECT > 0 */ #else /* SM_CONF_SETITIMER */ time_t begin, now; @@ -596,7 +599,7 @@ sleep(intvl) sm_io_to.tv_sec = intvl - (now - begin); if (sm_io_to.tv_sec <= 0) sm_io_to.tv_sec = 1; - sm_io_to.utv_sec = 0; + sm_io_to.tv_usec = 0; # endif /* _FFR_SLEEP_USE_SELECT > 0 */ #endif /* SM_CONF_SETITIMER */ #if _FFR_SLEEP_USE_SELECT > 0 diff --git a/contrib/sendmail/libsm/config.c b/contrib/sendmail/libsm/config.c index ea6aeb96bcb7..a5e13270a096 100644 --- a/contrib/sendmail/libsm/config.c +++ b/contrib/sendmail/libsm/config.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: config.c,v 1.27.2.1 2003/03/06 02:16:24 ca Exp $") +SM_RCSID("@(#)$Id: config.c,v 1.30 2003/12/10 03:19:07 gshapiro Exp $") #include #include @@ -176,6 +176,9 @@ char *SmCompileOptions[] = #if SM_CONF_GETOPT "SM_CONF_GETOPT", #endif /* SM_CONF_GETOPT */ +#if SM_CONF_LDAP_INITIALIZE + "SM_CONF_LDAP_INITIALIZE", +#endif /* SM_CONF_LDAP_INITIALIZE */ #if SM_CONF_LDAP_MEMFREE "SM_CONF_LDAP_MEMFREE", #endif /* SM_CONF_LDAP_MEMFREE */ @@ -232,6 +235,9 @@ char *SmCompileOptions[] = #if SM_CONF_UID_GID "SM_CONF_UID_GID", #endif /* SM_CONF_UID_GID */ +#if DO_NOT_USE_STRCPY + "DO_NOT_USE_STRCPY", +#endif /* DO_NOT_USE_STRCPY */ #if SM_HEAP_CHECK "SM_HEAP_CHECK", #endif /* SM_HEAP_CHECK */ diff --git a/contrib/sendmail/libsm/debug.c b/contrib/sendmail/libsm/debug.c index 37e5e829cb31..a6582aeb4ce6 100644 --- a/contrib/sendmail/libsm/debug.c +++ b/contrib/sendmail/libsm/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000, 2001, 2003 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: debug.c,v 1.28 2001/09/25 19:57:05 gshapiro Exp $") +SM_RCSID("@(#)$Id: debug.c,v 1.29 2003/01/10 00:26:06 ca Exp $") /* ** libsm debugging and tracing @@ -76,6 +76,29 @@ sm_debug_setfile(fp) SmDebugOutput = fp; } +/* +** SM_DEBUG_CLOSE -- Close debug file pointer. +** +** Parameters: +** none. +** +** Returns: +** none. +** +** Side Effects: +** Closes SmDebugOutput. +*/ + +void +sm_debug_close() +{ + if (SmDebugOutput != NULL && SmDebugOutput != smioout) + { + sm_io_close(SmDebugOutput, SM_TIME_DEFAULT); + SmDebugOutput = NULL; + } +} + /* ** SM_DPRINTF -- printf() for debug output. ** diff --git a/contrib/sendmail/libsm/errstring.c b/contrib/sendmail/libsm/errstring.c index 74387a96d5c5..b2999bdec971 100644 --- a/contrib/sendmail/libsm/errstring.c +++ b/contrib/sendmail/libsm/errstring.c @@ -11,7 +11,7 @@ */ #include -SM_RCSID("@(#)$Id: errstring.c,v 1.12.2.4 2003/06/24 17:16:09 ca Exp $") +SM_RCSID("@(#)$Id: errstring.c,v 1.19 2003/12/10 03:53:05 gshapiro Exp $") #include #include /* sys_errlist, on some platforms */ @@ -189,13 +189,84 @@ sm_errstring(errnum) case SMDBE_VERSION_MISMATCH: return "Berkeley DB version mismatch between include file and library"; + +#if LDAPMAP + + /* + ** LDAP URL error messages. + */ + + /* OpenLDAP errors */ +# ifdef LDAP_URL_ERR_MEM + case E_LDAPURLBASE + LDAP_URL_ERR_MEM: + return "LDAP URL can't allocate memory space"; +# endif /* LDAP_URL_ERR_MEM */ + +# ifdef LDAP_URL_ERR_PARAM + case E_LDAPURLBASE + LDAP_URL_ERR_PARAM: + return "LDAP URL parameter is bad"; +# endif /* LDAP_URL_ERR_PARAM */ + +# ifdef LDAP_URL_ERR_BADSCHEME + case E_LDAPURLBASE + LDAP_URL_ERR_BADSCHEME: + return "LDAP URL doesn't begin with \"ldap[si]://\""; +# endif /* LDAP_URL_ERR_BADSCHEME */ + +# ifdef LDAP_URL_ERR_BADENCLOSURE + case E_LDAPURLBASE + LDAP_URL_ERR_BADENCLOSURE: + return "LDAP URL is missing trailing \">\""; +# endif /* LDAP_URL_ERR_BADENCLOSURE */ + +# ifdef LDAP_URL_ERR_BADURL + case E_LDAPURLBASE + LDAP_URL_ERR_BADURL: + return "LDAP URL is bad"; +# endif /* LDAP_URL_ERR_BADURL */ + +# ifdef LDAP_URL_ERR_BADHOST + case E_LDAPURLBASE + LDAP_URL_ERR_BADHOST: + return "LDAP URL host port is bad"; +# endif /* LDAP_URL_ERR_BADHOST */ + +# ifdef LDAP_URL_ERR_BADATTRS + case E_LDAPURLBASE + LDAP_URL_ERR_BADATTRS: + return "LDAP URL bad (or missing) attributes"; +# endif /* LDAP_URL_ERR_BADATTRS */ + +# ifdef LDAP_URL_ERR_BADSCOPE + case E_LDAPURLBASE + LDAP_URL_ERR_BADSCOPE: + return "LDAP URL scope string is invalid (or missing)"; +# endif /* LDAP_URL_ERR_BADSCOPE */ + +# ifdef LDAP_URL_ERR_BADFILTER + case E_LDAPURLBASE + LDAP_URL_ERR_BADFILTER: + return "LDAP URL bad or missing filter"; +# endif /* LDAP_URL_ERR_BADFILTER */ + +# ifdef LDAP_URL_ERR_BADEXTS + case E_LDAPURLBASE + LDAP_URL_ERR_BADEXTS: + return "LDAP URL bad or missing extensions"; +# endif /* LDAP_URL_ERR_BADEXTS */ + + /* Sun LDAP errors */ +# ifdef LDAP_URL_ERR_NOTLDAP + case E_LDAPURLBASE + LDAP_URL_ERR_NOTLDAP: + return "LDAP URL doesn't begin with \"ldap://\""; +# endif /* LDAP_URL_ERR_NOTLDAP */ + +# ifdef LDAP_URL_ERR_NODN + case E_LDAPURLBASE + LDAP_URL_ERR_NODN: + return "LDAP URL has no DN (required)"; +# endif /* LDAP_URL_ERR_NODN */ + +#endif /* LDAPMAP */ } +#if LDAPMAP + /* ** LDAP error messages. */ -#if LDAPMAP if (errnum >= E_LDAPBASE) return ldap_err2string(errnum - E_LDAPBASE); #endif /* LDAPMAP */ diff --git a/contrib/sendmail/libsm/exc.c b/contrib/sendmail/libsm/exc.c index e2360c624850..26ad020ba753 100644 --- a/contrib/sendmail/libsm/exc.c +++ b/contrib/sendmail/libsm/exc.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: exc.c,v 1.47.2.1 2003/12/05 22:44:17 ca Exp $") +SM_RCSID("@(#)$Id: exc.c,v 1.48 2003/12/05 22:45:24 ca Exp $") /* ** exception handling diff --git a/contrib/sendmail/libsm/flags.c b/contrib/sendmail/libsm/flags.c index 7e2b0e2486d4..94ecd5cbe9e1 100644 --- a/contrib/sendmail/libsm/flags.c +++ b/contrib/sendmail/libsm/flags.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001, 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -13,7 +13,7 @@ */ #include -SM_RCSID("@(#)$Id: flags.c,v 1.20.2.1 2003/09/03 18:51:56 ca Exp $") +SM_RCSID("@(#)$Id: flags.c,v 1.22 2004/03/03 19:20:29 ca Exp $") #include #include #include diff --git a/contrib/sendmail/libsm/ldap.c b/contrib/sendmail/libsm/ldap.c index 0e1c7185725d..570c3cdb77c0 100644 --- a/contrib/sendmail/libsm/ldap.c +++ b/contrib/sendmail/libsm/ldap.c @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: ldap.c,v 1.44.2.5 2003/12/23 21:21:56 gshapiro Exp $") +SM_RCSID("@(#)$Id: ldap.c,v 1.59 2003/12/23 21:20:15 gshapiro Exp $") #if LDAPMAP # include @@ -52,14 +52,10 @@ sm_ldap_clear(lmap) if (lmap == NULL) return; - lmap->ldap_target = NULL; + lmap->ldap_host = NULL; lmap->ldap_port = LDAP_PORT; -#if _FFR_LDAP_URI - lmap->ldap_uri = false; -#endif /* _FFR_LDAP_URI */ -# if _FFR_LDAP_SETVERSION + lmap->ldap_uri = NULL; lmap->ldap_version = 0; -# endif /* _FFR_LDAP_SETVERSION */ lmap->ldap_deref = LDAP_DEREF_NEVER; lmap->ldap_timelimit = LDAP_NO_LIMIT; lmap->ldap_sizelimit = LDAP_NO_LIMIT; @@ -80,10 +76,8 @@ sm_ldap_clear(lmap) lmap->ldap_ld = NULL; lmap->ldap_filter = NULL; lmap->ldap_attr[0] = NULL; -#if _FFR_LDAP_RECURSION lmap->ldap_attr_type[0] = SM_LDAP_ATTR_NONE; lmap->ldap_attr_needobjclass[0] = NULL; -#endif /* _FFR_LDAP_RECURSION */ lmap->ldap_res = NULL; lmap->ldap_next = NULL; lmap->ldap_pid = 0; @@ -133,39 +127,79 @@ sm_ldap_start(name, lmap) { int bind_result; int save_errno; + char *id; SM_EVENT *ev = NULL; - LDAP *ld; + LDAP *ld = NULL; if (sm_debug_active(&SmLDAPTrace, 2)) sm_dprintf("ldapmap_start(%s)\n", name == NULL ? "" : name); - if (sm_debug_active(&SmLDAPTrace, 9)) - sm_dprintf("ldapmap_start(%s, %d)\n", - lmap->ldap_target == NULL ? "localhost" : lmap->ldap_target, - lmap->ldap_port); - -# if USE_LDAP_INIT -# if _FFR_LDAP_URI - if (lmap->ldap_uri) - errno = ldap_initialize(&ld, lmap->ldap_target); + if (lmap->ldap_host != NULL) + id = lmap->ldap_host; + else if (lmap->ldap_uri != NULL) + id = lmap->ldap_uri; else -# endif /* _FFR_LDAP_URI */ - ld = ldap_init(lmap->ldap_target, lmap->ldap_port); - save_errno = errno; + id = "localhost"; + + if (sm_debug_active(&SmLDAPTrace, 9)) + { + /* Don't print a port number for LDAP URIs */ + if (lmap->ldap_uri != NULL) + sm_dprintf("ldapmap_start(%s)\n", id); + else + sm_dprintf("ldapmap_start(%s, %d)\n", id, + lmap->ldap_port); + } + + if (lmap->ldap_uri != NULL) + { +#if SM_CONF_LDAP_INITIALIZE + /* LDAP server supports URIs so use them directly */ + save_errno = ldap_initialize(&ld, lmap->ldap_uri); +#else /* SM_CONF_LDAP_INITIALIZE */ + int err; + LDAPURLDesc *ludp = NULL; + + /* Blast apart URL and use the ldap_init/ldap_open below */ + err = ldap_url_parse(lmap->ldap_uri, &ludp); + if (err != 0) + { + errno = err + E_LDAPURLBASE; + return false; + } + lmap->ldap_host = sm_strdup_x(ludp->lud_host); + if (lmap->ldap_host == NULL) + { + save_errno = errno; + ldap_free_urldesc(ludp); + errno = save_errno; + return false; + } + lmap->ldap_port = ludp->lud_port; + ldap_free_urldesc(ludp); +#endif /* SM_CONF_LDAP_INITIALIZE */ + } + + if (ld == NULL) + { +# if USE_LDAP_INIT + ld = ldap_init(lmap->ldap_host, lmap->ldap_port); + save_errno = errno; # else /* USE_LDAP_INIT */ - /* - ** If using ldap_open(), the actual connection to the server - ** happens now so we need the timeout here. For ldap_init(), - ** the connection happens at bind time. - */ + /* + ** If using ldap_open(), the actual connection to the server + ** happens now so we need the timeout here. For ldap_init(), + ** the connection happens at bind time. + */ - SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec); - ld = ldap_open(lmap->ldap_target, lmap->ldap_port); - save_errno = errno; + SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec); + ld = ldap_open(lmap->ldap_host, lmap->ldap_port); + save_errno = errno; - /* clear the event if it has not sprung */ - SM_LDAP_CLEARTIMEOUT(); + /* clear the event if it has not sprung */ + SM_LDAP_CLEARTIMEOUT(); # endif /* USE_LDAP_INIT */ + } errno = save_errno; if (ld == NULL) @@ -232,7 +266,7 @@ ldaptimeout(unused) } /* -** SM_LDAP_SEARCH -- iniate LDAP search +** SM_LDAP_SEARCH -- initiate LDAP search ** ** Initiate an LDAP search, return the msgid. ** The calling function must collect the results. @@ -319,7 +353,6 @@ sm_ldap_search(lmap, key) return msgid; } -# if _FFR_LDAP_RECURSION /* ** SM_LDAP_HAS_OBJECTCLASS -- determine if an LDAP entry is part of a ** particular objectClass @@ -509,6 +542,8 @@ sm_ldap_add_recurse(top, item, type, rpool) newe->lr_search = sm_rpool_strdup_x(rpool, item); newe->lr_type = type; + newe->lr_ludp = NULL; + newe->lr_attrs = NULL; newe->lr_done = false; ((*top)->lr_data)[insertat] = newe; @@ -941,6 +976,16 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result, /* mark this DN as done */ rl->lr_done = true; + if (rl->lr_ludp != NULL) + { + ldap_free_urldesc(rl->lr_ludp); + rl->lr_ludp = NULL; + } + if (rl->lr_attrs != NULL) + { + free(rl->lr_attrs); + rl->lr_attrs = NULL; + } /* We don't want multiple values and we have one */ if ((char) delim == '\0' && *result != NULL) @@ -1050,10 +1095,71 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result, } else if (rl->lr_type == SM_LDAP_ATTR_URL) { - /* do new URL search */ - sid = ldap_url_search(lmap->ldap_ld, - rl->lr_search, - lmap->ldap_attrsonly); + /* Parse URL */ + sid = ldap_url_parse(rl->lr_search, + &rl->lr_ludp); + + if (sid != 0) + { + errno = sid + E_LDAPURLBASE; + return EX_TEMPFAIL; + } + + /* We need to add objectClass */ + if (rl->lr_ludp->lud_attrs != NULL) + { + int attrnum = 0; + + while (rl->lr_ludp->lud_attrs[attrnum] != NULL) + { + if (strcasecmp(rl->lr_ludp->lud_attrs[attrnum], + "objectClass") == 0) + { + /* already requested */ + attrnum = -1; + break; + } + attrnum++; + } + + if (attrnum >= 0) + { + int i; + + rl->lr_attrs = (char **)malloc(sizeof(char *) * (attrnum + 2)); + if (rl->lr_attrs == NULL) + { + save_errno = errno; + ldap_free_urldesc(rl->lr_ludp); + errno = save_errno; + return EX_TEMPFAIL; + } + for (i = 0 ; i < attrnum; i++) + { + rl->lr_attrs[i] = rl->lr_ludp->lud_attrs[i]; + } + rl->lr_attrs[i++] = "objectClass"; + rl->lr_attrs[i++] = NULL; + } + } + + /* + ** Use the existing connection + ** for this search. It really + ** should use lud_scheme://lud_host:lud_port/ + ** instead but that would require + ** opening a new connection. + ** This should be fixed ASAP. + */ + + sid = ldap_search(lmap->ldap_ld, + rl->lr_ludp->lud_dn, + rl->lr_ludp->lud_scope, + rl->lr_ludp->lud_filter, + rl->lr_attrs, + lmap->ldap_attrsonly); + + /* Use the attributes specified by URL */ newflags |= SM_LDAP_USE_ALLATTR; } else @@ -1100,6 +1206,16 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result, /* Mark as done */ rl->lr_done = true; + if (rl->lr_ludp != NULL) + { + ldap_free_urldesc(rl->lr_ludp); + rl->lr_ludp = NULL; + } + if (rl->lr_attrs != NULL) + { + free(rl->lr_attrs); + rl->lr_attrs = NULL; + } /* Reset rlidx as new items may have been added */ rlidx = -1; @@ -1107,7 +1223,6 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result, } return statp; } -#endif /* _FFR_LDAP_RECURSION */ /* ** SM_LDAP_CLOSE -- close LDAP connection @@ -1151,13 +1266,11 @@ sm_ldap_setopts(ld, lmap) SM_LDAP_STRUCT *lmap; { # if USE_LDAP_SET_OPTION -# if _FFR_LDAP_SETVERSION if (lmap->ldap_version != 0) { ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &lmap->ldap_version); } -# endif /* _FFR_LDAP_SETVERSION */ ldap_set_option(ld, LDAP_OPT_DEREF, &lmap->ldap_deref); if (bitset(LDAP_OPT_REFERRALS, lmap->ldap_options)) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON); diff --git a/contrib/sendmail/libsm/local.h b/contrib/sendmail/libsm/local.h index 610663daf601..6d64195d515e 100644 --- a/contrib/sendmail/libsm/local.h +++ b/contrib/sendmail/libsm/local.h @@ -11,7 +11,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Id: local.h,v 1.51.2.2 2004/01/09 18:32:44 ca Exp $ + * $Id: local.h,v 1.53 2004/01/09 18:34:22 ca Exp $ */ /* diff --git a/contrib/sendmail/libsm/mbdb.c b/contrib/sendmail/libsm/mbdb.c index 0c338fe9a409..ad0e7ccbd13f 100644 --- a/contrib/sendmail/libsm/mbdb.c +++ b/contrib/sendmail/libsm/mbdb.c @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: mbdb.c,v 1.38.2.1 2002/11/20 22:59:06 gshapiro Exp $") +SM_RCSID("@(#)$Id: mbdb.c,v 1.40 2003/12/10 03:19:07 gshapiro Exp $") #include @@ -441,13 +441,13 @@ mbdb_ldap_initialize(arg) { sm_ldap_clear(&LDAPLMAP); LDAPLMAP.ldap_base = MBDB_DEFAULT_LDAP_BASEDN; - LDAPLMAP.ldap_target = MBDB_DEFAULT_LDAP_SERVER; + LDAPLMAP.ldap_host = MBDB_DEFAULT_LDAP_SERVER; LDAPLMAP.ldap_filter = MBDB_LDAP_FILTER; /* Only want one match */ LDAPLMAP.ldap_sizelimit = 1; - /* interpolate new ldap_base and ldap_target from arg if given */ + /* interpolate new ldap_base and ldap_host from arg if given */ if (arg != NULL && *arg != '\0') { char *new; @@ -463,7 +463,7 @@ mbdb_ldap_initialize(arg) if (sep != NULL) { *sep++ = '\0'; - LDAPLMAP.ldap_target = sep; + LDAPLMAP.ldap_host = sep; } LDAPLMAP.ldap_base = new; } diff --git a/contrib/sendmail/libsm/refill.c b/contrib/sendmail/libsm/refill.c index 6e06783d05da..c3db17222957 100644 --- a/contrib/sendmail/libsm/refill.c +++ b/contrib/sendmail/libsm/refill.c @@ -13,7 +13,7 @@ */ #include -SM_RCSID("@(#)$Id: refill.c,v 1.49.2.1 2002/09/09 21:38:08 gshapiro Exp $") +SM_RCSID("@(#)$Id: refill.c,v 1.50 2002/09/09 21:50:10 gshapiro Exp $") #include #include #include diff --git a/contrib/sendmail/libsm/rpool.c b/contrib/sendmail/libsm/rpool.c index 863216660f7b..57c03939b0d8 100644 --- a/contrib/sendmail/libsm/rpool.c +++ b/contrib/sendmail/libsm/rpool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: rpool.c,v 1.24 2002/01/11 21:54:43 ca Exp $") +SM_RCSID("@(#)$Id: rpool.c,v 1.27 2003/10/09 17:49:47 ca Exp $") /* ** resource pools @@ -491,3 +491,31 @@ sm_rpool_attach_x(rpool, rfree, rcontext) --rpool->sm_ravail; return a; } + +#if DO_NOT_USE_STRCPY +/* +** SM_RPOOL_STRDUP_X -- Create a copy of a C string +** +** Parameters: +** rpool -- rpool to use. +** s -- the string to copy. +** +** Returns: +** pointer to newly allocated string. +*/ + +char * +sm_rpool_strdup_x(rpool, s) + SM_RPOOL_T *rpool; + const char *s; +{ + size_t l; + char *n; + + l = strlen(s); + SM_ASSERT(l + 1 > l); + n = sm_rpool_malloc_x(rpool, l + 1); + sm_strlcpy(n, s, l + 1); + return n; +} +#endif /* DO_NOT_USE_STRCPY */ diff --git a/contrib/sendmail/libsm/shm.c b/contrib/sendmail/libsm/shm.c index 2299aed34a80..4cef8929e283 100644 --- a/contrib/sendmail/libsm/shm.c +++ b/contrib/sendmail/libsm/shm.c @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: shm.c,v 1.10.2.6 2003/06/13 21:17:48 ca Exp $") +SM_RCSID("@(#)$Id: shm.c,v 1.16 2003/06/13 21:18:08 ca Exp $") #if SM_CONF_SHM # include diff --git a/contrib/sendmail/libsm/smstdio.c b/contrib/sendmail/libsm/smstdio.c index d561e8d67a02..e8637c15f0af 100644 --- a/contrib/sendmail/libsm/smstdio.c +++ b/contrib/sendmail/libsm/smstdio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002, 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include -SM_IDSTR(id, "@(#)$Id: smstdio.c,v 1.32.2.2 2003/09/05 20:35:28 ca Exp $") +SM_IDSTR(id, "@(#)$Id: smstdio.c,v 1.33 2004/03/03 19:14:51 ca Exp $") #include #include #include diff --git a/contrib/sendmail/libsm/stdio.c b/contrib/sendmail/libsm/stdio.c index 23cc2af3c08e..0df98ab8b088 100644 --- a/contrib/sendmail/libsm/stdio.c +++ b/contrib/sendmail/libsm/stdio.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -13,7 +13,7 @@ */ #include -SM_RCSID("@(#)$Id: stdio.c,v 1.56.2.13 2003/09/04 01:18:08 ca Exp $") +SM_RCSID("@(#)$Id: stdio.c,v 1.68 2004/03/03 19:20:29 ca Exp $") #include #include #include diff --git a/contrib/sendmail/libsm/strdup.c b/contrib/sendmail/libsm/strdup.c index 64fe5c2a9a9c..7094275e046c 100644 --- a/contrib/sendmail/libsm/strdup.c +++ b/contrib/sendmail/libsm/strdup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: strdup.c,v 1.13 2001/09/11 04:04:49 gshapiro Exp $") +SM_RCSID("@(#)$Id: strdup.c,v 1.15 2003/10/10 17:56:57 ca Exp $") #include #include @@ -70,3 +70,97 @@ sm_strdup(s) (void) sm_strlcpy(d, s, l); return d; } + +#if DO_NOT_USE_STRCPY + +/* +** SM_STRDUP_X -- Duplicate a string +** +** Allocates memory and copies source string into it. +** +** Parameters: +** s -- string to copy. +** +** Returns: +** copy of string, exception if out of memory. +** +** Side Effects: +** allocate memory for new string. +*/ + +char * +sm_strdup_x(s) + const char *s; +{ + size_t l; + char *d; + + l = strlen(s) + 1; + d = sm_malloc_tagged_x(l, "sm_strdup_x", 0, sm_heap_group()); + (void) sm_strlcpy(d, s, l); + return d; +} + +/* +** SM_PSTRDUP_X -- Duplicate a string (using "permanent" memory) +** +** Allocates memory and copies source string into it. +** +** Parameters: +** s -- string to copy. +** +** Returns: +** copy of string, exception if out of memory. +** +** Side Effects: +** allocate memory for new string. +*/ + +char * +sm_pstrdup_x(s) + const char *s; +{ + size_t l; + char *d; + + l = strlen(s) + 1; + d = sm_pmalloc_x(l); + (void) sm_strlcpy(d, s, l); + return d; +} + +/* +** SM_STRDUP_X -- Duplicate a string +** +** Allocates memory and copies source string into it. +** +** Parameters: +** s -- string to copy. +** file -- name of source file +** line -- line in source file +** group -- heap group +** +** Returns: +** copy of string, exception if out of memory. +** +** Side Effects: +** allocate memory for new string. +*/ + +char * +sm_strdup_tagged_x(s, file, line, group) + const char *s; + char *file; + int line, group; +{ + size_t l; + char *d; + + l = strlen(s) + 1; + d = sm_malloc_tagged_x(l, file, line, group); + (void) sm_strlcpy(d, s, l); + return d; +} + +#endif /* DO_NOT_USE_STRCPY */ + diff --git a/contrib/sendmail/libsm/t-shm.c b/contrib/sendmail/libsm/t-shm.c index 5da07c1e369b..b20040a35639 100644 --- a/contrib/sendmail/libsm/t-shm.c +++ b/contrib/sendmail/libsm/t-shm.c @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: t-shm.c,v 1.18 2002/01/31 04:11:41 ca Exp $") +SM_RCSID("@(#)$Id: t-shm.c,v 1.19 2004/04/20 23:14:21 ca Exp $") #include @@ -45,7 +45,7 @@ shminter(owner) bool owner; { int *shm, shmid; - int i, j, t; + int i, t; shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner); if (shm == (int *) 0) @@ -74,7 +74,6 @@ shminter(owner) t = *shm; for (i = 0; i < SHM_MAX; i++) { - j += i; ++*shm; } if (*shm != SHM_MAX + t) diff --git a/contrib/sendmail/libsm/vasprintf.c b/contrib/sendmail/libsm/vasprintf.c index 3441a3dee074..69d857633995 100644 --- a/contrib/sendmail/libsm/vasprintf.c +++ b/contrib/sendmail/libsm/vasprintf.c @@ -24,7 +24,7 @@ */ #include -SM_RCSID("@(#)$Id: vasprintf.c,v 1.26.2.1 2003/06/03 02:14:09 ca Exp $") +SM_RCSID("@(#)$Id: vasprintf.c,v 1.27 2003/06/03 02:14:24 ca Exp $") #include #include #include diff --git a/contrib/sendmail/libsmdb/Makefile.m4 b/contrib/sendmail/libsmdb/Makefile.m4 index 23f39d0b561f..caadfe8c88c6 100644 --- a/contrib/sendmail/libsmdb/Makefile.m4 +++ b/contrib/sendmail/libsmdb/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.13.4.1 2002/06/21 21:58:33 ca Exp $ +dnl $Id: Makefile.m4,v 8.14 2002/06/21 22:01:34 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/libsmdb/smdb2.c b/contrib/sendmail/libsmdb/smdb2.c index 0e505e6e096b..be07d636b47f 100644 --- a/contrib/sendmail/libsmdb/smdb2.c +++ b/contrib/sendmail/libsmdb/smdb2.c @@ -8,7 +8,7 @@ */ #include -SM_RCSID("@(#)$Id: smdb2.c,v 8.72.2.7 2003/06/24 17:16:10 ca Exp $") +SM_RCSID("@(#)$Id: smdb2.c,v 8.79 2003/06/13 21:33:11 ca Exp $") #include #include diff --git a/contrib/sendmail/libsmutil/Makefile.m4 b/contrib/sendmail/libsmutil/Makefile.m4 index 36c5d7a5a479..ea3730562923 100644 --- a/contrib/sendmail/libsmutil/Makefile.m4 +++ b/contrib/sendmail/libsmutil/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.16.4.1 2002/06/21 21:58:35 ca Exp $ +dnl $Id: Makefile.m4,v 8.17 2002/06/21 22:01:34 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/libsmutil/cf.c b/contrib/sendmail/libsmutil/cf.c index 1db2a6793f91..f313762f5577 100644 --- a/contrib/sendmail/libsmutil/cf.c +++ b/contrib/sendmail/libsmutil/cf.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: cf.c,v 8.18.2.1 2002/09/24 21:48:23 ca Exp $") +SM_RCSID("@(#)$Id: cf.c,v 8.19 2002/09/24 20:40:59 ca Exp $") #include /* diff --git a/contrib/sendmail/libsmutil/lockfile.c b/contrib/sendmail/libsmutil/lockfile.c index 5eca360ce8f9..17d6237eaa64 100644 --- a/contrib/sendmail/libsmutil/lockfile.c +++ b/contrib/sendmail/libsmutil/lockfile.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: lockfile.c,v 8.19 2001/09/11 04:04:55 gshapiro Exp $") +SM_RCSID("@(#)$Id: lockfile.c,v 8.21 2003/11/10 22:57:38 ca Exp $") /* @@ -43,7 +43,6 @@ lockfile(fd, filename, ext, type) #if !HASFLOCK int action; struct flock lfd; - extern int errno; memset(&lfd, '\0', sizeof lfd); if (bitset(LOCK_UN, type)) diff --git a/contrib/sendmail/libsmutil/safefile.c b/contrib/sendmail/libsmutil/safefile.c index aed40a0482e0..c6cfb53ef876 100644 --- a/contrib/sendmail/libsmutil/safefile.c +++ b/contrib/sendmail/libsmutil/safefile.c @@ -15,7 +15,7 @@ #include #include -SM_RCSID("@(#)$Id: safefile.c,v 8.124 2002/05/24 20:50:15 gshapiro Exp $") +SM_RCSID("@(#)$Id: safefile.c,v 8.127 2004/05/27 22:37:51 msk Exp $") /* @@ -304,7 +304,7 @@ safefile(fn, uid, gid, user, flags, mode, st) bitset(S_IXUSR|S_IXGRP|S_IXOTH, st->st_mode)) { if (tTd(44, 4)) - sm_dprintf("\t[exec bits %lo]\tE_SM_ISEXEC]\n", + sm_dprintf("\t[exec bits %lo]\tE_SM_ISEXEC\n", (unsigned long) st->st_mode); return E_SM_ISEXEC; } @@ -684,6 +684,9 @@ safeopen(fn, omode, cmode, sff) int cmode; long sff; { +#if !NOFTRUNCATE + bool truncate; +#endif /* !NOFTRUNCATE */ int rval; int fd; int smode; @@ -735,6 +738,12 @@ safeopen(fn, omode, cmode, sff) return -1; } +#if !NOFTRUNCATE + truncate = bitset(O_TRUNC, omode); + if (truncate) + omode &= ~O_TRUNC; +#endif /* !NOFTRUNCATE */ + fd = dfopen(fn, omode, cmode, sff); if (fd < 0) return fd; @@ -745,6 +754,22 @@ safeopen(fn, omode, cmode, sff) errno = E_SM_FILECHANGE; return -1; } + +#if !NOFTRUNCATE + if (truncate && + ftruncate(fd, (off_t) 0) < 0) + { + int save_errno; + + save_errno = errno; + syserr("554 5.3.0 cannot open: file %s could not be truncated", + fn); + (void) close(fd); + errno = save_errno; + return -1; + } +#endif /* !NOFTRUNCATE */ + return fd; } /* @@ -940,6 +965,9 @@ dfopen(filename, omode, cmode, sff) locktype = LOCK_EX; else locktype = LOCK_SH; + if (bitset(SFF_NBLOCK, sff)) + locktype |= LOCK_NB; + if (!lockfile(fd, filename, NULL, locktype)) { int save_errno = errno; diff --git a/contrib/sendmail/mail.local/Makefile.m4 b/contrib/sendmail/mail.local/Makefile.m4 index 63c14e0dfac3..3a06a3b44b80 100644 --- a/contrib/sendmail/mail.local/Makefile.m4 +++ b/contrib/sendmail/mail.local/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.49.2.1 2002/06/21 21:58:36 ca Exp $ +dnl $Id: Makefile.m4,v 8.50 2002/06/21 22:01:39 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/mail.local/README b/contrib/sendmail/mail.local/README index 651de4bc9113..2ab9dbc4af97 100644 --- a/contrib/sendmail/mail.local/README +++ b/contrib/sendmail/mail.local/README @@ -36,4 +36,29 @@ delivery agent without LMTP mode, use: in the .mc file. -$Revision: 8.10 $, Last updated $Date: 2001/09/08 01:21:04 $ +Defining HASHSPOOL (-DHASHSPOOL) will build a mail.local which supports +delivering to subdirectories of the mail spool, based on a hash of the +username (i.e., a hash depth of 2 and a username of "user" will result in +/var/spool/mail/u/s/user). If the hash depth is greater than the length +of the username, "_" will be used. The necessary subdirectories must +exist; mail.local will not create them. Use the "-H" option to set the +hash type and depth (like "-H u2" for a username hash two levels deep). + +The HASHSPOOL option also adds two other options: "-p path" to specify +an alternate mail spool path (i.e., "-p /local/mail") and "-n" to specify +that mail.local should not strip the @domain part of recipient addresses +in LMTP mode. + +In addition to HASHSPOOL, defining HASHSPOOLMD5 and linking against +libcrypto from OpenSSL like: + + APPENDDEF(`conf_mail_local_ENVDEF', `-DHASHSPOOL -DHASHSPOOLMD5') + APPENDDEF(`conf_mail_local_LIBS', `-lcrypto') + +will offer an alternate hash, using a base64 encoding (changing / to _) +of an MD5 hash of the username. This results in a more balanced +subdirectory tree. The subdirectories will be named with A-Z, a-z, 0-9, ++, and _. The hash type is "m", so use "-H m3" to get a three level MD5 +based hash. + +$Revision: 8.11 $, Last updated $Date: 2003/10/20 20:19:13 $ diff --git a/contrib/sendmail/mailstats/Makefile.m4 b/contrib/sendmail/mailstats/Makefile.m4 index e981401d1917..61f56924b538 100644 --- a/contrib/sendmail/mailstats/Makefile.m4 +++ b/contrib/sendmail/mailstats/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.34.4.1 2002/06/21 21:58:37 ca Exp $ +dnl $Id: Makefile.m4,v 8.35 2002/06/21 22:01:40 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/mailstats/mailstats.8 b/contrib/sendmail/mailstats/mailstats.8 index 582055d11617..d6c25def5d9e 100644 --- a/contrib/sendmail/mailstats/mailstats.8 +++ b/contrib/sendmail/mailstats/mailstats.8 @@ -6,9 +6,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: mailstats.8,v 8.30.2.1 2002/09/26 23:03:39 gshapiro Exp $ +.\" $Id: mailstats.8,v 8.31 2002/06/27 22:47:29 gshapiro Exp $ .\" -.TH MAILSTATS 8 "$Date: 2002/09/26 23:03:39 $" +.TH MAILSTATS 8 "$Date: 2002/06/27 22:47:29 $" .SH NAME mailstats \- display mail statistics @@ -55,6 +55,9 @@ Number of messages rejected. .B msgsdis Number of messages discarded. .TP +.B msgsqur +Number of messages quarantined. +.TP .B Mailer The name of the mailer. .PD diff --git a/contrib/sendmail/makemap/Makefile.m4 b/contrib/sendmail/makemap/Makefile.m4 index 2396311ae952..a4664cf4369e 100644 --- a/contrib/sendmail/makemap/Makefile.m4 +++ b/contrib/sendmail/makemap/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.42.4.1 2002/06/21 21:58:38 ca Exp $ +dnl $Id: Makefile.m4,v 8.43 2002/06/21 22:01:44 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/makemap/makemap.8 b/contrib/sendmail/makemap/makemap.8 index 9faaef7fcb60..96338e79cb0f 100644 --- a/contrib/sendmail/makemap/makemap.8 +++ b/contrib/sendmail/makemap/makemap.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1988, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -8,9 +8,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: makemap.8,v 8.29 2001/10/10 03:23:02 ca Exp $ +.\" $Id: makemap.8,v 8.30 2002/06/27 23:41:04 gshapiro Exp $ .\" -.TH MAKEMAP 8 "$Date: 2001/10/10 03:23:02 $" +.TH MAKEMAP 8 "$Date: 2002/06/27 23:41:04 $" .SH NAME makemap \- create database maps for sendmail @@ -22,6 +22,8 @@ makemap .RB [ \-c .IR cachesize ] .RB [ \-d ] +.RB [ \-D +.IR commentchar ] .RB [ \-e ] .RB [ \-f ] .RB [ \-l ] @@ -111,6 +113,10 @@ This must match the \-N flag in the sendmail.cf .B \-c Use the specified hash and B-Tree cache size. .TP +.B \-D +Use to specify the character to use to indicate a comment (which is ignored) +instead of the default of '#'. +.TP .B \-d Allow duplicate keys in the map. This is only allowed on B-Tree format maps. diff --git a/contrib/sendmail/praliases/Makefile.m4 b/contrib/sendmail/praliases/Makefile.m4 index 248fccd2e5ac..2ba5c7eb06a0 100644 --- a/contrib/sendmail/praliases/Makefile.m4 +++ b/contrib/sendmail/praliases/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.34.4.1 2002/06/21 21:58:39 ca Exp $ +dnl $Id: Makefile.m4,v 8.35 2002/06/21 22:01:47 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/rmail/Makefile.m4 b/contrib/sendmail/rmail/Makefile.m4 index 6b2a0498f13c..f8ee2ff54be9 100644 --- a/contrib/sendmail/rmail/Makefile.m4 +++ b/contrib/sendmail/rmail/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.42.4.1 2002/06/21 21:58:46 ca Exp $ +dnl $Id: Makefile.m4,v 8.43 2002/06/21 22:01:49 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/smrsh/Makefile.m4 b/contrib/sendmail/smrsh/Makefile.m4 index f090250ff185..1fa55349b02b 100644 --- a/contrib/sendmail/smrsh/Makefile.m4 +++ b/contrib/sendmail/smrsh/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.34.2.1 2002/06/21 21:58:48 ca Exp $ +dnl $Id: Makefile.m4,v 8.35 2002/06/21 22:01:52 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/smrsh/README b/contrib/sendmail/smrsh/README index d2b0b643201d..0719a3f506c9 100644 --- a/contrib/sendmail/smrsh/README +++ b/contrib/sendmail/smrsh/README @@ -163,4 +163,4 @@ a typical system follows: host.domain# /usr/sbin/sendmail -bd -q30m -$Revision: 8.8.4.1 $, Last updated $Date: 2003/05/26 04:29:42 $ +$Revision: 8.9 $, Last updated $Date: 2003/05/26 04:30:58 $ diff --git a/contrib/sendmail/src/Makefile.m4 b/contrib/sendmail/src/Makefile.m4 index 1100dea5572d..5cf0f78411ab 100644 --- a/contrib/sendmail/src/Makefile.m4 +++ b/contrib/sendmail/src/Makefile.m4 @@ -1,11 +1,11 @@ -dnl $Id: Makefile.m4,v 8.91.2.4 2002/09/09 02:48:54 gshapiro Exp $ +dnl $Id: Makefile.m4,v 8.96 2003/08/08 20:31:17 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') bldPRODUCT_START(`executable', `sendmail') define(`bldBIN_TYPE', `G') define(`bldINSTALL_DIR', `') -define(`bldSOURCES', `main.c alias.c arpadate.c bf.c collect.c conf.c control.c convtime.c daemon.c deliver.c domain.c envelope.c err.c headers.c macro.c map.c mci.c milter.c mime.c parseaddr.c queue.c readcf.c recipient.c sasl.c savemail.c sfsasl.c shmticklib.c sm_resolve.c srvrsmtp.c stab.c stats.c sysexits.c timers.c tls.c trace.c udb.c usersmtp.c util.c version.c ') +define(`bldSOURCES', `main.c alias.c arpadate.c bf.c collect.c conf.c control.c convtime.c daemon.c deliver.c domain.c envelope.c err.c headers.c macro.c map.c mci.c milter.c mime.c parseaddr.c queue.c ratectrl.c readcf.c recipient.c sasl.c savemail.c sfsasl.c shmticklib.c sm_resolve.c srvrsmtp.c stab.c stats.c sysexits.c timers.c tls.c trace.c udb.c usersmtp.c util.c version.c ') PREPENDDEF(`confENVDEF', `confMAPDEF') bldPUSH_SMLIB(`sm') bldPUSH_SMLIB(`smutil') diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README index e0af96b1d8c6..b2e11c436722 100644 --- a/contrib/sendmail/src/README +++ b/contrib/sendmail/src/README @@ -1,4 +1,4 @@ -# Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. # Copyright (c) 1988 @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Id: README,v 8.355.2.16 2004/01/08 21:54:55 ca Exp $ +# $Id: README,v 8.384 2004/07/26 18:03:55 ca Exp $ # This directory contains the source files for sendmail(TM). @@ -127,6 +127,8 @@ DNSMAP DNS map support. Requires NAMED_BIND. PH_MAP PH map support. You will need the libphclient library from the nph package (http://www-dev.cites.uiuc.edu/ph/nph/). MAP_NSD nsd map support (IRIX 6.5 and later). +SOCKETMAP Support for a trivial query protocol over UNIX domain or TCP + sockets. >>> NOTE WELL for NEWDB support: If you want to get ndbm support, for >>> Berkeley DB versions under 2.0, it is CRITICAL that you remove @@ -180,6 +182,15 @@ addresses, so "^[0-9]+$" would match this. By using such a map in a check_* rule-set, you can block a certain range of addresses that would otherwise be considered valid. +The socket map uses a simple request/reply protocol over TCP or +UNIX domain sockets to query an external server. Both requests and +replies are text based and encoded as netstrings. The socket map +uses the same syntax as milters the specify the remote endpoint, +e.g.: + +Ksocket mySocketMap inet:12345@127.0.0.1 + +See doc/op/op.me for details. +---------------+ | COMPILE FLAGS | @@ -287,6 +298,8 @@ HASURANDOMDEV Define this if your system has /dev/urandom(4). HASSTRERROR Define this if you have the libc strerror(3) function (which should be declared in ), and it should be used instead of sys_errlist. +HASCLOSEFROM Define this if your system has closefrom(3). +HASFDWALK Define this if your system has fdwalk(3). SM_CONF_GETOPT Define this as 0 if you need a reimplementation of getopt(3). On some systems, getopt does very odd things if called to scan the arguments twice. This flag will ask sendmail @@ -481,6 +494,11 @@ USE_DOUBLE_FORK By default this is on (1). Set it to 0 to suppress the ALLOW_255 Do not convert (char)0xff to (char)0x7f in headers etc. This can also be done at runtime with the command line option -d82.101. +NEEDINTERRNO Set this if does not declare errno, i.e., if an + application needs to use + extern int errno; +USE_TTYPATH Set this to 1 to enable ErrorMode=write. +USESYSCTL Use sysctl(3) to determine the number of CPUs in a system. +-----------------------+ @@ -604,8 +622,11 @@ STARTTLS Enables SMTP STARTTLS (RFC 2487). This requires OpenSSL See STARTTLS COMPILATION AND CONFIGURATION for further information. TLS_NO_RSA Turn off support for RSA algorithms in STARTTLS. -MILTER Turn on support for external filters using the Milter API. - See libmilter/README for more information. +MILTER Turn on support for external filters using the Milter API; + this option is set by default, to turn it off use + APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') + in devtools/Site/site.config.m4 (see devtools/README). + See libmilter/README for more information about milter. REQUIRES_DIR_FSYNC Turn on support for file systems that require to call fsync() for a directory if the meta-data in it has been changed. This should be turned on at least for older @@ -1303,12 +1324,12 @@ Linux Something broke between versions 0.99.13 and 0.99.14 of Linux: the flock() system call gives errors. If you are running .14, you must not use flock. You can do this with -DHASFLOCK=0. We have also - been getting complaints since version 2.4.X was released. Unless - the bug is fixed before sendmail 8.13 is shipped, 8.13 will change - the default locking method to fcntl() for Linux kernel version 2.4 - and later. Be sure to update other sendmail related programs to - match locking techniques (some examples, besides makemap and - mail.local, include procmail, mailx, mutt, elm, etc). + been getting complaints since version 2.4.X was released. + sendmail 8.13 has changed the default locking method to fcntl() + for Linux kernel version 2.4 and later. Be sure to update other + sendmail related programs to match locking techniques (some + examples, besides makemap and mail.local, include procmail, mailx, + mutt, elm, etc). Around the inclusion of bind-4.9.3 & Linux libc-4.6.20, the initialization of the _res structure changed. If /etc/hosts.conf @@ -1802,4 +1823,4 @@ util.c Some general purpose routines used by sendmail. version.c The version number and information about this version of sendmail. -(Version $Revision: 8.355.2.16 $, last update $Date: 2004/01/08 21:54:55 $ ) +(Version $Revision: 8.384 $, last update $Date: 2004/07/26 18:03:55 $ ) diff --git a/contrib/sendmail/src/SECURITY b/contrib/sendmail/src/SECURITY index 71b4643ae10f..0445e445235c 100644 --- a/contrib/sendmail/src/SECURITY +++ b/contrib/sendmail/src/SECURITY @@ -5,7 +5,7 @@ # forth in the LICENSE file which can be found at the top level of # the sendmail distribution. # -# $Id: SECURITY,v 1.50.2.1 2002/09/23 21:28:48 ca Exp $ +# $Id: SECURITY,v 1.51 2002/09/23 21:29:18 ca Exp $ # This file gives some hints how to configure and run sendmail for diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS index 1d7d28b244fc..9927922072fa 100644 --- a/contrib/sendmail/src/TRACEFLAGS +++ b/contrib/sendmail/src/TRACEFLAGS @@ -1,4 +1,4 @@ -# $Id: TRACEFLAGS,v 8.37.2.4 2003/06/13 21:59:45 lijian Exp $ +# $Id: TRACEFLAGS,v 8.42 2003/06/13 22:29:11 lijian Exp $ 0, 4 main.c main canonical name, UUCP node name, a.k.a.s 0, 15 main.c main print configuration 0, 44 util.c printav print address of each string @@ -75,15 +75,13 @@ 63 queue.c runqueue process watching 64 multiple Milter 65 main.c permission checks -#if _FFR_ADAPTIVE_EOL -66 srvrsmtp.c conformance checks -#endif /* _FFR_ADAPTIVE_EOL */ -#if _FFR_QUEUE_SCHED_DBG -69 queue.c scheduling -#endif /* _FFR_QUEUE_SCHED_DBG */ -#if _FFR_QUARANTINE +#if _FFR_ADAPTIVE_EOL +66 srvrsmtp.c conformance checks +#endif /* _FFR_ADAPTIVE_EOL */ +#if _FFR_QUEUE_SCHED_DBG +69 queue.c scheduling +#endif /* _FFR_QUEUE_SCHED_DBG */ 70 queue.c quarantining -#endif /* _FFR_QUARANTINE */ 71,>99 milter.c quarantine on errors 80 content length 81 sun remote mode diff --git a/contrib/sendmail/src/TUNING b/contrib/sendmail/src/TUNING index 61121cbbfd15..6ccff9a19407 100644 --- a/contrib/sendmail/src/TUNING +++ b/contrib/sendmail/src/TUNING @@ -5,7 +5,7 @@ # forth in the LICENSE file which can be found at the top level of # the sendmail distribution. # -# $Id: TUNING,v 1.18.4.1 2003/02/07 18:19:51 ca Exp $ +# $Id: TUNING,v 1.19 2003/01/25 23:06:02 ca Exp $ # ******************************************** diff --git a/contrib/sendmail/src/alias.c b/contrib/sendmail/src/alias.c index c944388bcb80..3c052123a4b5 100644 --- a/contrib/sendmail/src/alias.c +++ b/contrib/sendmail/src/alias.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: alias.c,v 8.214.2.2 2003/10/06 20:43:29 ca Exp $") +SM_RCSID("@(#)$Id: alias.c,v 8.217 2003/07/28 17:47:18 ca Exp $") #define SEPARATOR ':' # define ALIAS_SPEC_SEPARATORS " ,/:" @@ -139,7 +139,7 @@ alias(a, sendq, aliaslevel, e) if (tTd(27, 5)) { sm_dprintf("alias: QS_EXPANDED "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } a->q_state = QS_EXPANDED; diff --git a/contrib/sendmail/src/bf.c b/contrib/sendmail/src/bf.c index 4e672b9431ce..211ed02f6db4 100644 --- a/contrib/sendmail/src/bf.c +++ b/contrib/sendmail/src/bf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2002, 2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -18,7 +18,7 @@ */ #include -SM_RCSID("@(#)$Id: bf.c,v 8.54.2.3 2003/09/03 19:58:26 ca Exp $") +SM_RCSID("@(#)$Id: bf.c,v 8.60 2004/04/14 18:12:49 ca Exp $") #include #include @@ -701,7 +701,8 @@ sm_bfcommit(fp) /* Clear umask as bf_filemode are the true perms */ omask = umask(0); - retval = OPEN(bfp->bf_filename, O_RDWR | O_CREAT | O_EXCL, + retval = OPEN(bfp->bf_filename, + O_RDWR | O_CREAT | O_EXCL | QF_O_EXTRA, bfp->bf_filemode, bfp->bf_flags); save_errno = errno; (void) umask(omask); diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c index 20a2c1cabc9c..392941ba43cb 100644 --- a/contrib/sendmail/src/collect.c +++ b/contrib/sendmail/src/collect.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,10 +13,9 @@ #include -SM_RCSID("@(#)$Id: collect.c,v 8.242.2.8 2003/07/08 01:16:35 ca Exp $") +SM_RCSID("@(#)$Id: collect.c,v 8.254 2004/04/05 18:41:38 ca Exp $") static void collecttimeout __P((time_t)); -static void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *)); static void eatfrom __P((char *volatile, ENVELOPE *)); static void collect_doheader __P((ENVELOPE *)); static SM_FILE_T *collect_dfopen __P((ENVELOPE *)); @@ -724,7 +723,9 @@ collect(fp, smtpmode, hdrp, e, rsetsize) finis(true, true, ExitStat); /* NOTREACHED */ } - else if (SuperSafe != SAFE_REALLY) + else if (SuperSafe == SAFE_NO || + SuperSafe == SAFE_INTERACTIVE || + (SuperSafe == SAFE_REALLY_POSTMILTER && smtpmode)) { /* skip next few clauses */ /* EMPTY */ @@ -743,7 +744,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize) if (stat(dfile, &st) < 0) st.st_size = -1; errno = EEXIST; - syserr("@collect: bfcommit(%s): already on disk, size = %ld", + syserr("@collect: bfcommit(%s): already on disk, size=%ld", dfile, (long) st.st_size); dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); if (dfd >= 0) @@ -754,8 +755,14 @@ collect(fp, smtpmode, hdrp, e, rsetsize) flush_errors(true); finis(save_errno != EEXIST, true, ExitStat); } - else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) >= 0 && - fsync(afd) < 0) + else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0) + { + dferror(df, "sm_io_getinfo", e); + flush_errors(true); + finis(true, true, ExitStat); + /* NOTREACHED */ + } + else if (fsync(afd) < 0) { dferror(df, "fsync", e); flush_errors(true); @@ -873,7 +880,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize) { char *dfname = queuename(e, DATAFL_LETTER); if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, - SM_IO_RDONLY, NULL)) == NULL) + SM_IO_RDONLY_B, NULL)) == NULL) { /* we haven't acked receipt yet, so just chuck this */ syserr("@Cannot reopen %s", dfname); @@ -896,10 +903,6 @@ collect(fp, smtpmode, hdrp, e, rsetsize) e->e_msgpriority = e->e_msgsize - e->e_class * WkClassFact + e->e_nrcpts * WkRecipFact; - if (tTd(90, 1)) - sm_syslog(LOG_INFO, e->e_id, - "collect: at end: msgsize=%ld, msgpriority=%ld", - e->e_msgsize, e->e_msgpriority); markstats(e, (ADDRESS *) NULL, STATS_NORMAL); } } @@ -958,7 +961,7 @@ collecttimeout(timeout) ** Arranges for following output to go elsewhere. */ -static void +void dferror(df, msg, e) SM_FILE_T *volatile df; char *msg; @@ -989,7 +992,7 @@ dferror(df, msg, e) < 0) st.st_size = 0; (void) sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, dfname, - SM_IO_WRONLY, NULL, df); + SM_IO_WRONLY_B, NULL, df); if (st.st_size <= 0) (void) sm_io_fprintf(df, SM_TIME_DEFAULT, "\n*** Mail could not be accepted"); diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c index d93f0cf80122..60eab3ca328e 100644 --- a/contrib/sendmail/src/control.c +++ b/contrib/sendmail/src/control.c @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: control.c,v 8.118.4.8 2003/06/24 17:45:27 ca Exp $") +SM_RCSID("@(#)$Id: control.c,v 8.125 2003/06/24 17:46:06 ca Exp $") #include diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c index 88c55cdc5339..c5939013fe2d 100644 --- a/contrib/sendmail/src/daemon.c +++ b/contrib/sendmail/src/daemon.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: daemon.c,v 8.613.2.20 2003/11/25 19:02:24 ca Exp $") +SM_RCSID("@(#)$Id: daemon.c,v 8.649 2004/07/14 21:57:52 ca Exp $") #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) # define USE_SOCK_STREAM 1 @@ -74,10 +74,8 @@ struct daemon char *d_mflags; /* flags for use in macro */ char *d_name; /* user-supplied name */ #if MILTER -# if _FFR_MILTER_PERDAEMON char *d_inputfilterlist; struct milter *d_inputfilters[MAXFILTERS]; -# endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ }; @@ -212,7 +210,7 @@ getrequests(e) #endif /* XDEBUG */ /* Add parent process as first item */ - proc_list_add(CurrentPid, "Sendmail daemon", PROC_DAEMON, 0, -1); + proc_list_add(CurrentPid, "Sendmail daemon", PROC_DAEMON, 0, -1, NULL); if (tTd(15, 1)) { @@ -280,6 +278,7 @@ getrequests(e) /* May have been sleeping above, check again */ CHECK_RESTART; + getrequests_checkdiskspace(e); #if XDEBUG @@ -490,6 +489,21 @@ getrequests(e) if (t < 0) { errno = save_errno; + + /* let's ignore these temporary errors */ + if (save_errno == EINTR +#ifdef EAGAIN + || save_errno == EAGAIN +#endif /* EAGAIN */ +#ifdef ECONNABORTED + || save_errno == ECONNABORTED +#endif /* ECONNABORTED */ +#ifdef EWOULDBLOCK + || save_errno == EWOULDBLOCK +#endif /* EWOULDBLOCK */ + ) + continue; + syserr("getrequests: accept"); /* arrange to re-open the socket next time around */ @@ -567,6 +581,16 @@ getrequests(e) macid("{daemon_flags}"), ""); } + /* + ** If connection rate is exceeded here, connection shall be + ** refused later by a new call after fork() by the + ** validate_connection() function. Closing the connection + ** at this point violates RFC 2821. + ** Do NOT remove this call, its side effects are needed. + */ + + connection_rate_check(&RealHostAddr, NULL); + /* ** Create a subprocess to process the mail. */ @@ -594,13 +618,13 @@ getrequests(e) #if NAMED_BIND /* - ** Update MX records for FallBackMX. + ** Update MX records for FallbackMX. ** Let's hope this is fast otherwise we screw up the ** response time. */ - if (FallBackMX != NULL) - (void) getfallbackmxrr(FallBackMX); + if (FallbackMX != NULL) + (void) getfallbackmxrr(FallbackMX); #endif /* NAMED_BIND */ if (tTd(93, 100)) @@ -655,6 +679,7 @@ getrequests(e) ShutdownRequest = NULL; PendingSignal = 0; CurrentPid = getpid(); + close_sendmail_pid(); (void) sm_releasesignal(SIGALRM); (void) sm_releasesignal(SIGCHLD); @@ -697,7 +722,7 @@ getrequests(e) /* Add control socket process */ proc_list_add(CurrentPid, "console socket child", - PROC_CONTROL_CHILD, 0, -1); + PROC_CONTROL_CHILD, 0, -1, NULL); } else { @@ -708,7 +733,7 @@ getrequests(e) /* Add parent process as first child item */ proc_list_add(CurrentPid, "daemon child", - PROC_DAEMON_CHILD, 0, -1); + PROC_DAEMON_CHILD, 0, -1, NULL); /* don't schedule queue runs if ETRN */ QueueIntvl = 0; @@ -759,21 +784,23 @@ getrequests(e) h_errno == TRY_AGAIN ? "TEMP" : "FAIL"); } else + { macdefine(&BlankEnvelope.e_macro, A_PERM, - macid("{client_resolve}"), "OK"); + macid("{client_resolve}"), "OK"); + } sm_setproctitle(true, e, "startup with %s", p); markstats(e, NULL, STATS_CONNECT); if ((inchannel = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &t, - SM_IO_RDONLY, + SM_IO_RDONLY_B, NULL)) == NULL || (t = dup(t)) < 0 || (outchannel = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &t, - SM_IO_WRONLY, + SM_IO_WRONLY_B, NULL)) == NULL) { syserr("cannot open SMTP server channel, fd=%d", @@ -856,14 +883,15 @@ getrequests(e) { (void) sm_snprintf(status, sizeof status, "control socket server child"); - proc_list_add(pid, status, PROC_CONTROL, 0, -1); + proc_list_add(pid, status, PROC_CONTROL, 0, -1, NULL); } else { (void) sm_snprintf(status, sizeof status, "SMTP server child for %s", anynet_ntoa(&RealHostAddr)); - proc_list_add(pid, status, PROC_DAEMON, 0, -1); + proc_list_add(pid, status, PROC_DAEMON, 0, -1, + &RealHostAddr); } (void) sm_releasesignal(SIGCHLD); @@ -888,7 +916,6 @@ getrequests(e) sm_dprintf("getreq: returning\n"); #if MILTER -# if _FFR_MILTER_PERDAEMON /* set the filters for this daemon */ if (Daemons[curdaemon].d_inputfilterlist != NULL) { @@ -902,7 +929,6 @@ getrequests(e) if (i < MAXFILTERS) InputFilters[i] = NULL; } -# endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ return &Daemons[curdaemon].d_flags; } @@ -1465,11 +1491,9 @@ setsockaddroptions(p, d) break; #if MILTER -# if _FFR_MILTER_PERDAEMON case 'I': d->d_inputfilterlist = v; break; -# endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ case 'P': /* port */ @@ -1711,9 +1735,7 @@ static struct dflags DaemonFlags[] = { "IFNHELO", D_IFNHELO }, { "FQMAIL", D_FQMAIL }, { "FQRCPT", D_FQRCPT }, -#if _FFR_SMTP_SSL { "SMTPS", D_SMTPS }, -#endif /* _FFR_SMTP_SSL */ { "UNQUALOK", D_UNQUALOK }, { "NOAUTH", D_NOAUTH }, { "NOCANON", D_NOCANON }, @@ -1738,15 +1760,13 @@ printdaemonflags(d) if (!bitnset(df->d_flag, d->d_flags)) continue; if (first) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "<%s", - df->d_name); + sm_dprintf("<%s", df->d_name); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ",%s", - df->d_name); + sm_dprintf(",%s", df->d_name); first = false; } if (!first) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ">"); + sm_dprintf(">"); } bool @@ -1761,10 +1781,8 @@ setdaemonoptions(p) setsockaddroptions(p, &Daemons[NDaemons]); #if MILTER -# if _FFR_MILTER_PERDAEMON if (Daemons[NDaemons].d_inputfilterlist != NULL) Daemons[NDaemons].d_inputfilterlist = newstr(Daemons[NDaemons].d_inputfilterlist); -# endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ if (Daemons[NDaemons].d_name != NULL) @@ -1929,7 +1947,6 @@ chkclientmodifiers(flag) } #if MILTER -# if _FFR_MILTER_PERDAEMON /* ** SETUP_DAEMON_FILTERS -- Parse per-socket filters ** @@ -1961,7 +1978,6 @@ setup_daemon_milters() } } } -# endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ /* ** MAKECONNECTION -- make a connection to an SMTP socket on a machine. @@ -2673,11 +2689,11 @@ makeconnection(host, port, mci, e, enough) mci->mci_out = NULL; if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &s, - SM_IO_WRONLY, NULL)) == NULL || + SM_IO_WRONLY_B, NULL)) == NULL || (s = dup(s)) < 0 || (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &s, - SM_IO_RDONLY, NULL)) == NULL) + SM_IO_RDONLY_B, NULL)) == NULL) { save_errno = errno; syserr("cannot open SMTP client channel, fd=%d", s); @@ -2746,6 +2762,13 @@ makeconnection(host, port, mci, e, enough) macdefine(&BlankEnvelope.e_macro, A_PERM, macid("{if_family_out}"), NULL); } + +#if _FFR_HELONAME + /* Use the configured HeloName as appropriate */ + if (HeloName != NULL && HeloName[0] != '\0') + mci->mci_heloname = newstr(HeloName); +#endif /* _FFR_HELONAME */ + mci_setstat(mci, EX_OK, NULL, NULL); return EX_OK; } @@ -2795,7 +2818,8 @@ makeconnection_ds(mux_path, mci) if (rval != 0) { - syserr("makeconnection_ds: unsafe domain socket"); + syserr("makeconnection_ds: unsafe domain socket %s", + mux_path); mci_setstat(mci, EX_TEMPFAIL, "4.3.5", NULL); errno = rval; return EX_TEMPFAIL; @@ -2807,7 +2831,8 @@ makeconnection_ds(mux_path, mci) if (strlen(mux_path) >= sizeof unix_addr.sun_path) { - syserr("makeconnection_ds: domain socket name too long"); + syserr("makeconnection_ds: domain socket name %s too long", + mux_path); /* XXX why TEMPFAIL but 5.x.y ? */ mci_setstat(mci, EX_TEMPFAIL, "5.3.5", NULL); @@ -2822,7 +2847,8 @@ makeconnection_ds(mux_path, mci) if (sock == -1) { save_errno = errno; - syserr("makeconnection_ds: could not create domain socket"); + syserr("makeconnection_ds: could not create domain socket %s", + mux_path); mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); errno = save_errno; return EX_TEMPFAIL; @@ -2843,11 +2869,11 @@ makeconnection_ds(mux_path, mci) /* connection ok, put it into canonical form */ mci->mci_out = NULL; if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &sock, SM_IO_WRONLY, NULL)) + (void *) &sock, SM_IO_WRONLY_B, NULL)) == NULL || (sock = dup(sock)) < 0 || (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &sock, SM_IO_RDONLY, NULL)) + (void *) &sock, SM_IO_RDONLY_B, NULL)) == NULL) { save_errno = errno; @@ -2891,8 +2917,8 @@ shutdown_daemon() ShutdownRequest = NULL; PendingSignal = 0; - if (LogLevel > 79) - sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt (%s)", + if (LogLevel > 9) + sm_syslog(LOG_INFO, CurEnv->e_id, "stopping daemon, reason=%s", reason == NULL ? "implicit call" : reason); FileName = NULL; @@ -2964,7 +2990,6 @@ void restart_daemon() { bool drop; - int i; int save_errno; char *reason; sigfunc_t ignore, oalrm, ousr1; @@ -2996,6 +3021,9 @@ restart_daemon() cleanup_shm(DaemonPid == getpid()); #endif /* SM_CONF_SHM */ + /* close locked pid file */ + close_sendmail_pid(); + /* ** Want to drop to the user who started the process in all cases ** *but* when running as "smmsp" for the clientmqueue queue run @@ -3016,14 +3044,7 @@ restart_daemon() /* NOTREACHED */ } - /* arrange for all the files to be closed */ - for (i = 3; i < DtableSize; i++) - { - register int j; - - if ((j = fcntl(i, F_GETFD, 0)) != -1) - (void) fcntl(i, F_SETFD, j | FD_CLOEXEC); - } + sm_close_on_exec(STDERR_FILENO + 1, DtableSize); /* ** Need to allow signals before execve() to make them "harmless". @@ -3340,6 +3361,7 @@ getauthinfo(fd, may_be_forged) hp = sm_gethostbyname(RealHostName, family); if (hp == NULL) { + /* XXX: Could be a temporary error on forward lookup */ *may_be_forged = true; } else @@ -3826,7 +3848,7 @@ host_map_lookup(map, name, av, statp) return NULL; if (s->s_namecanon.nc_cname == NULL) { - syserr("host_map_lookup(%s): bogus NULL cache entry, errno = %d, h_errno = %d", + syserr("host_map_lookup(%s): bogus NULL cache entry, errno=%d, h_errno=%d", name, s->s_namecanon.nc_errno, s->s_namecanon.nc_herrno); diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c index eb98f8374984..5839cbe6a4c5 100644 --- a/contrib/sendmail/src/deliver.c +++ b/contrib/sendmail/src/deliver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: deliver.c,v 8.940.2.20 2003/09/26 18:26:19 ca Exp $") +SM_RCSID("@(#)$Id: deliver.c,v 8.976 2004/07/23 20:45:01 gshapiro Exp $") #if HASSETUSERCONTEXT # include @@ -123,11 +123,11 @@ sendall(e, mode) { sm_dprintf("\n===== SENDALL: mode %c, id %s, e_from ", mode, e->e_id); - printaddr(&e->e_from, false); + printaddr(sm_debug_file(), &e->e_from, false); sm_dprintf("\te_flags = "); printenvflags(e); sm_dprintf("sendqueue:\n"); - printaddr(e->e_sendqueue, true); + printaddr(sm_debug_file(), e->e_sendqueue, true); } /* @@ -184,7 +184,7 @@ sendall(e, mode) if (tTd(13, 5)) { sm_dprintf("sendall: QS_SENDER "); - printaddr(&e->e_from, false); + printaddr(sm_debug_file(), &e->e_from, false); } e->e_from.q_state = QS_SENDER; (void) recipient(&e->e_from, &e->e_sendqueue, 0, e); @@ -215,7 +215,7 @@ sendall(e, mode) if (tTd(13, 25)) { sm_dprintf("\nAfter first owner pass, sendq =\n"); - printaddr(e->e_sendqueue, true); + printaddr(sm_debug_file(), e->e_sendqueue, true); } owner = ""; @@ -233,7 +233,7 @@ sendall(e, mode) if (tTd(13, 30)) { sm_dprintf("Checking "); - printaddr(q, false); + printaddr(sm_debug_file(), q, false); } if (QS_IS_DEAD(q->q_state)) { @@ -244,7 +244,7 @@ sendall(e, mode) if (tTd(13, 29) && !tTd(13, 30)) { sm_dprintf("Checking "); - printaddr(q, false); + printaddr(sm_debug_file(), q, false); } if (q->q_owner != NULL) @@ -304,8 +304,8 @@ sendall(e, mode) ** set, send directly to the fallback MX host. */ - if (FallBackMX != NULL && - !wordinclass(FallBackMX, 'w') && + if (FallbackMX != NULL && + !wordinclass(FallbackMX, 'w') && mode != SM_VERIFY && !bitnset(M_NOMX, m->m_flags) && strcmp(m->m_mailer, "[IPC]") == 0 && @@ -316,11 +316,11 @@ sendall(e, mode) char *p; if (tTd(13, 30)) - sm_dprintf(" ... FallBackMX\n"); + sm_dprintf(" ... FallbackMX\n"); - len = strlen(FallBackMX) + 1; + len = strlen(FallbackMX) + 1; p = sm_rpool_malloc_x(e->e_rpool, len); - (void) sm_strlcpy(p, FallBackMX, len); + (void) sm_strlcpy(p, FallbackMX, len); q->q_state = QS_OK; q->q_host = p; } @@ -359,7 +359,6 @@ sendall(e, mode) q->q_state = QS_QUEUEUP; expensive = true; } -#if _FFR_QUARANTINE else if (QueueMode != QM_QUARANTINE && e->e_quarmsg != NULL) { @@ -369,7 +368,6 @@ sendall(e, mode) q->q_state = QS_QUEUEUP; expensive = true; } -#endif /* _FFR_QUARANTINE */ else { if (tTd(13, 30)) @@ -407,7 +405,7 @@ sendall(e, mode) if (tTd(13, 5)) { sm_dprintf("sendall(split): QS_SENDER "); - printaddr(&ee->e_from, false); + printaddr(sm_debug_file(), &ee->e_from, false); } ee->e_from.q_state = QS_SENDER; ee->e_dfp = NULL; @@ -418,11 +416,9 @@ sendall(e, mode) ee->e_errormode = EM_MAIL; ee->e_sibling = splitenv; ee->e_statmsg = NULL; -#if _FFR_QUARANTINE if (e->e_quarmsg != NULL) ee->e_quarmsg = sm_rpool_strdup_x(ee->e_rpool, e->e_quarmsg); -#endif /* _FFR_QUARANTINE */ splitenv = ee; for (q = e->e_sendqueue; q != NULL; q = q->q_next) @@ -485,7 +481,7 @@ sendall(e, mode) if (tTd(13, 5)) { sm_dprintf("sendall(owner): QS_SENDER "); - printaddr(&e->e_from, false); + printaddr(sm_debug_file(), &e->e_from, false); } e->e_from.q_state = QS_SENDER; e->e_errormode = EM_MAIL; @@ -517,7 +513,9 @@ sendall(e, mode) } if ((WILL_BE_QUEUED(mode) || mode == SM_FORK || - (mode != SM_VERIFY && SuperSafe == SAFE_REALLY)) && + (mode != SM_VERIFY && + (SuperSafe == SAFE_REALLY || + SuperSafe == SAFE_REALLY_POSTMILTER))) && (!bitset(EF_INQUEUE, e->e_flags) || splitenv != NULL)) { bool msync; @@ -555,12 +553,12 @@ sendall(e, mode) sm_dprintf("\n================ Final Send Queue(s) =====================\n"); sm_dprintf("\n *** Envelope %s, e_from=%s ***\n", e->e_id, e->e_from.q_paddr); - printaddr(e->e_sendqueue, true); + printaddr(sm_debug_file(), e->e_sendqueue, true); for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { sm_dprintf("\n *** Envelope %s, e_from=%s ***\n", ee->e_id, ee->e_from.q_paddr); - printaddr(ee->e_sendqueue, true); + printaddr(sm_debug_file(), ee->e_sendqueue, true); } sm_dprintf("==========================================================\n\n"); } @@ -623,6 +621,7 @@ sendall(e, mode) /* and save qid for reacquisition */ ee->e_id = qid; } + #endif /* !HASFLOCK */ /* @@ -953,10 +952,8 @@ sync_dir(filename, panic) char *dirp; char dir[MAXPATHLEN]; -#if _FFR_REQ_DIR_FSYNC_OPT if (!RequiresDirfsync) return; -#endif /* _FFR_REQ_DIR_FSYNC_OPT */ /* filesystems which require the directory be synced */ dirp = strrchr(filename, '/'); @@ -1180,6 +1177,50 @@ coloncmp(a, b) return ret; } + +/* +** SHOULD_TRY_FBSH -- Should try FallbackSmartHost? +** +** Parameters: +** e -- envelope +** tried_fallbacksmarthost -- has been tried already? (in/out) +** hostbuf -- buffer for hostname (expand FallbackSmartHost) (out) +** hbsz -- size of hostbuf +** status -- current delivery status +** +** Returns: +** true iff FallbackSmartHost should be tried. +*/ + +static bool +should_try_fbsh(e, tried_fallbacksmarthost, hostbuf, hbsz, status) + ENVELOPE *e; + bool *tried_fallbacksmarthost; + char *hostbuf; + size_t hbsz; + int status; +{ + /* + ** If the host was not found and a FallbackSmartHost is defined + ** (and we have not yet tried it), then make one last try with + ** it as the host. + */ + + if (status == EX_NOHOST && FallbackSmartHost != NULL && + !*tried_fallbacksmarthost) + { + *tried_fallbacksmarthost = true; + expand(FallbackSmartHost, hostbuf, hbsz, e); + if (!wordinclass(hostbuf, 'w')) + { + if (tTd(11, 1)) + sm_dprintf("one last try with FallbackSmartHost %s\n", + hostbuf); + return true; + } + } + return false; +} /* ** DELIVER -- Deliver a message to a list of addresses. ** @@ -1241,13 +1282,6 @@ coloncmp(a, b) ** The standard input is passed off to someone. */ -#ifndef NO_UID -# define NO_UID -1 -#endif /* ! NO_UID */ -#ifndef NO_GID -# define NO_GID -1 -#endif /* ! NO_GID */ - static int deliver(e, firstto) register ENVELOPE *e; @@ -1284,9 +1318,7 @@ deliver(e, firstto) bool anyok; /* at least one address was OK */ SM_NONVOLATILE bool goodmxfound = false; /* at least one MX was OK */ bool ovr; -#if _FFR_QUARANTINE bool quarantine; -#endif /* _FFR_QUARANTINE */ int strsize; int rcptcount; int ret; @@ -1327,6 +1359,7 @@ deliver(e, firstto) if (bitset(EF_RESPONSE, e->e_flags)) { macdefine(&e->e_macro, A_PERM, macid("{client_name}"), ""); + macdefine(&e->e_macro, A_PERM, macid("{client_ptr}"), ""); macdefine(&e->e_macro, A_PERM, macid("{client_addr}"), ""); macdefine(&e->e_macro, A_PERM, macid("{client_port}"), ""); macdefine(&e->e_macro, A_PERM, macid("{client_resolve}"), ""); @@ -1369,6 +1402,10 @@ deliver(e, firstto) pvp = pv; *pvp++ = m->m_argv[0]; + /* ignore long term host status information if mailer flag W is set */ + if (bitnset(M_NOHOSTSTAT, m->m_flags)) + IgnoreHostStatus = true; + /* insert -f or -r flag as appropriate */ if (FromFlag && (bitnset(M_FOPT, m->m_flags) || @@ -1507,7 +1544,7 @@ deliver(e, firstto) if (tTd(10, 1)) { sm_dprintf("\nsend to "); - printaddr(to, false); + printaddr(sm_debug_file(), to, false); } /* compute effective uid/gid when sending */ @@ -1521,7 +1558,7 @@ deliver(e, firstto) if (tTd(10, 2)) { sm_dprintf("ctladdr="); - printaddr(ctladdr, false); + printaddr(sm_debug_file(), ctladdr, false); } user = to->q_user; @@ -1555,9 +1592,7 @@ deliver(e, firstto) ovr = true; /* do config file checking of compatibility */ -#if _FFR_QUARANTINE quarantine = (e->e_quarmsg != NULL); -#endif /* _FFR_QUARANTINE */ rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr, e, RSF_RMCOMM|RSF_COUNT, 3, NULL, e->e_id); @@ -1577,7 +1612,6 @@ deliver(e, firstto) NULL, ctladdr, xstart, e, to); continue; } -#if _FFR_QUARANTINE if (!quarantine && e->e_quarmsg != NULL) { /* @@ -1590,13 +1624,12 @@ deliver(e, firstto) macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); } -#endif /* _FFR_QUARANTINE */ if (bitset(EF_DISCARD, e->e_flags)) { if (tTd(10, 5)) { sm_dprintf("deliver: discarding recipient "); - printaddr(to, false); + printaddr(sm_debug_file(), to, false); } /* pretend the message was sent */ @@ -1624,7 +1657,7 @@ deliver(e, firstto) stripquotes(user); stripquotes(host); } -#if _FFR_STRIPBACKSL + /* ** Strip one leading backslash if requested and the ** next character is alphanumerical (the latter can @@ -1633,7 +1666,6 @@ deliver(e, firstto) if (bitnset(M_STRIPBACKSL, m->m_flags) && user[0] == '\\') stripbackslash(user); -#endif /* _FFR_STRIPBACKSL */ /* hack attack -- delivermail compatibility */ if (m == ProgMailer && *user == '|') @@ -1827,7 +1859,7 @@ deliver(e, firstto) if (tTd(11, 1)) { sm_dprintf("openmailer:"); - printav(pv); + printav(sm_debug_file(), pv); } errno = 0; SM_SET_H_ERRNO(0); @@ -1879,7 +1911,6 @@ deliver(e, firstto) /* check for Local Person Communication -- not for mortals!!! */ if (strcmp(m->m_mailer, "[LPC]") == 0) { -#if _FFR_CACHE_LPC if (clever) { /* flush any expired connections */ @@ -1913,13 +1944,6 @@ deliver(e, firstto) } else mci->mci_state = MCIS_OPEN; -#else /* _FFR_CACHE_LPC */ - mci = mci_new(e->e_rpool); - mci->mci_in = smioin; - mci->mci_out = smioout; - mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN; - mci->mci_mailer = m; -#endif /* _FFR_CACHE_LPC */ } else if (strcmp(m->m_mailer, "[IPC]") == 0) { @@ -1989,6 +2013,7 @@ deliver(e, firstto) char sep = ':'; char *endp; static char hostbuf[MAXNAME + 1]; + bool tried_fallbacksmarthost = false; # if NETINET6 if (*mxhosts[hostnum] == '[') @@ -2040,6 +2065,7 @@ deliver(e, firstto) if (endp != NULL) *endp = sep; + one_last_try: /* see if we already know that this host is fried */ CurHostName = hostbuf; mci = mci_get(hostbuf, m); @@ -2050,7 +2076,7 @@ deliver(e, firstto) if (tTd(11, 1)) { sm_dprintf("openmailer: "); - mci_dump(mci, false); + mci_dump(sm_debug_file(), mci, false); } CurHostName = mci->mci_host; if (bitnset(M_LMTP, m->m_flags)) @@ -2069,6 +2095,13 @@ deliver(e, firstto) { if (mci->mci_exitstat == EX_TEMPFAIL) goodmxfound = true; + + /* Try FallbackSmartHost? */ + if (should_try_fbsh(e, &tried_fallbacksmarthost, + hostbuf, sizeof hostbuf, + mci->mci_exitstat)) + goto one_last_try; + continue; } @@ -2121,9 +2154,9 @@ deliver(e, firstto) { int h; # if NAMED_BIND - extern int NumFallBackMXHosts; + extern int NumFallbackMXHosts; # else /* NAMED_BIND */ - const int NumFallBackMXHosts = 0; + const int NumFallbackMXHosts = 0; # endif /* NAMED_BIND */ if (hostnum < nummxhosts && LogLevel > 9) @@ -2131,11 +2164,11 @@ deliver(e, firstto) "Timeout.to_aconnect occurred before exhausting all addresses"); /* turn off timeout if fallback available */ - if (NumFallBackMXHosts > 0) + if (NumFallbackMXHosts > 0) enough = 0; /* skip to a fallback MX host */ - h = nummxhosts - NumFallBackMXHosts; + h = nummxhosts - NumFallbackMXHosts; if (hostnum < h) hostnum = h; } @@ -2155,6 +2188,11 @@ deliver(e, firstto) } else { + /* Try FallbackSmartHost? */ + if (should_try_fbsh(e, &tried_fallbacksmarthost, + hostbuf, sizeof hostbuf, i)) + goto one_last_try; + if (tTd(11, 1)) sm_dprintf("openmailer: makeconnection => stat=%d, errno=%d\n", i, errno); @@ -2320,7 +2358,6 @@ deliver(e, firstto) } else if (pid == 0) { - int i; int save_errno; int sff; int new_euid = NO_UID; @@ -2396,7 +2433,12 @@ deliver(e, firstto) /* reset group id */ if (bitnset(M_SPECIFIC_UID, m->m_flags)) - new_gid = m->m_gid; + { + if (m->m_gid == NO_GID) + new_gid = RunAsGid; + else + new_gid = m->m_gid; + } else if (bitset(S_ISGID, stb.st_mode)) new_gid = stb.st_gid; else if (ctladdr != NULL && ctladdr->q_gid != 0) @@ -2455,7 +2497,7 @@ deliver(e, firstto) exit(EX_TEMPFAIL); } } - if (m->m_gid == 0) + if (m->m_gid == NO_GID) new_gid = DefGid; else new_gid = m->m_gid; @@ -2507,7 +2549,10 @@ deliver(e, firstto) sm_mbdb_terminate(); if (bitnset(M_SPECIFIC_UID, m->m_flags)) { - new_euid = m->m_uid; + if (m->m_uid == NO_UID) + new_euid = RunAsUid; + else + new_euid = m->m_uid; /* ** Undo the effects of the uid change in main @@ -2537,7 +2582,7 @@ deliver(e, firstto) new_ruid = stb.st_uid; else if (ctladdr != NULL && ctladdr->q_uid != 0) new_ruid = ctladdr->q_uid; - else if (m->m_uid != 0) + else if (m->m_uid != NO_UID) new_ruid = m->m_uid; else new_ruid = DefUid; @@ -2679,14 +2724,7 @@ deliver(e, firstto) (void) close(mpvect[0]); /* arrange for all the files to be closed */ - for (i = 3; i < DtableSize; i++) - { - register int j; - - if ((j = fcntl(i, F_GETFD, 0)) != -1) - (void) fcntl(i, F_SETFD, - j | FD_CLOEXEC); - } + sm_close_on_exec(STDERR_FILENO + 1, DtableSize); # if !_FFR_USE_SETLOGIN /* run disconnected from terminal */ @@ -2743,7 +2781,7 @@ deliver(e, firstto) mci->mci_pid = pid; (void) close(mpvect[0]); mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &(mpvect[1]), SM_IO_WRONLY, + (void *) &(mpvect[1]), SM_IO_WRONLY_B, NULL); if (mci->mci_out == NULL) { @@ -2758,7 +2796,7 @@ deliver(e, firstto) (void) close(rpvect[1]); mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &(rpvect[0]), SM_IO_RDONLY, + (void *) &(rpvect[0]), SM_IO_RDONLY_B, NULL); if (mci->mci_in == NULL) { @@ -3118,7 +3156,7 @@ deliver(e, firstto) /* avoid bogus error msg */ mci->mci_errno = 0; rcode = EX_TEMPFAIL; - mci_setstat(mci, rcode, "4.7.1", p); + mci_setstat(mci, rcode, "4.3.0", p); /* ** hack to get the error message into @@ -3162,7 +3200,7 @@ deliver(e, firstto) if (tTd(11, 1)) { sm_dprintf("openmailer: "); - mci_dump(mci, false); + mci_dump(sm_debug_file(), mci, false); } #if _FFR_CLIENT_SIZE @@ -3208,7 +3246,7 @@ deliver(e, firstto) syserr("554 5.3.5 deliver: mci=%lx rcode=%d errno=%d state=%d sig=%s", (unsigned long) mci, rcode, errno, mci->mci_state, firstsig); - mci_dump_all(true); + mci_dump_all(smioout, true); rcode = EX_SOFTWARE; } else if (nummxhosts > hostnum) @@ -4197,7 +4235,6 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) anynet_ntoa(&CurHostAddr)); } } -#if _FFR_QUARANTINE else if (strcmp(status, "quarantined") == 0) { if (e->e_quarmsg != NULL) @@ -4205,7 +4242,6 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) ", quarantine=%s", shortenstring(e->e_quarmsg, 40)); } -#endif /* _FFR_QUARANTINE */ else if (strcmp(status, "queued") != 0) { p = macvalue('h', e); @@ -4344,7 +4380,6 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) " [%.100s]", anynet_ntoa(&CurHostAddr)); } -#if _FFR_QUARANTINE else if (strcmp(status, "quarantined") == 0) { if (e->e_quarmsg != NULL) @@ -4352,7 +4387,6 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) ", quarantine=%.100s", e->e_quarmsg); } -#endif /* _FFR_QUARANTINE */ else if (strcmp(status, "queued") != 0) { p = macvalue('h', e); @@ -5036,7 +5070,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e) if (tTd(11, 1)) { sm_dprintf("mailfile %s\n ctladdr=", filename); - printaddr(ctladdr, false); + printaddr(sm_debug_file(), ctladdr, false); } if (mailer == NULL) @@ -5226,7 +5260,10 @@ mailfile(filename, mailer, ctladdr, sfflags, e) if (bitnset(M_SPECIFIC_UID, mailer->m_flags)) { RealUserName = NULL; - RealUid = mailer->m_uid; + if (mailer->m_uid == NO_UID) + RealUid = RunAsUid; + else + RealUid = mailer->m_uid; if (RunAsUid != 0 && RealUid != RunAsUid) { /* Only root can change the uid */ @@ -5248,7 +5285,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e) RealUserName = ctladdr->q_user; RealUid = ctladdr->q_uid; } - else if (mailer != NULL && mailer->m_uid != 0) + else if (mailer != NULL && mailer->m_uid != NO_UID) { RealUserName = DefUser; RealUid = mailer->m_uid; @@ -5262,7 +5299,10 @@ mailfile(filename, mailer, ctladdr, sfflags, e) /* select a new group to run as */ if (bitnset(M_SPECIFIC_UID, mailer->m_flags)) { - RealGid = mailer->m_gid; + if (mailer->m_gid == NO_GID) + RealGid = RunAsGid; + else + RealGid = mailer->m_gid; if (RunAsUid != 0 && (RealGid != getgid() || RealGid != getegid())) @@ -5291,7 +5331,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e) } else if (ctladdr != NULL && ctladdr->q_uid != 0) RealGid = ctladdr->q_gid; - else if (mailer != NULL && mailer->m_gid != 0) + else if (mailer != NULL && mailer->m_gid != NO_GID) RealGid = mailer->m_gid; else RealGid = DefGid; @@ -6014,7 +6054,8 @@ starttls(m, mci, e) smtpmessage("STARTTLS", m, mci); /* get the reply */ - smtpresult = reply(m, mci, e, TimeOuts.to_starttls, NULL, NULL); + smtpresult = reply(m, mci, e, TimeOuts.to_starttls, NULL, NULL, + XS_STARTTLS); /* check return code from server */ if (smtpresult == 454) diff --git a/contrib/sendmail/src/domain.c b/contrib/sendmail/src/domain.c index f4a8810a27cc..dd2427207e1f 100644 --- a/contrib/sendmail/src/domain.c +++ b/contrib/sendmail/src/domain.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1986, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,9 +14,9 @@ #include #if NAMED_BIND -SM_RCSID("@(#)$Id: domain.c,v 8.181.2.9 2003/08/11 23:23:40 gshapiro Exp $ (with name server)") +SM_RCSID("@(#)$Id: domain.c,v 8.194 2004/01/14 01:47:34 ca Exp $ (with name server)") #else /* NAMED_BIND */ -SM_RCSID("@(#)$Id: domain.c,v 8.181.2.9 2003/08/11 23:23:40 gshapiro Exp $ (without name server)") +SM_RCSID("@(#)$Id: domain.c,v 8.194 2004/01/14 01:47:34 ca Exp $ (without name server)") #endif /* NAMED_BIND */ #if NAMED_BIND @@ -76,7 +76,6 @@ static char MXHostBuf[MXHOSTBUFSIZE]; # define RES_UNC_T unsigned char * # endif /* defined(__RES) && (__RES >= 19940415) */ -static char *gethostalias __P((char *)); static int mxrand __P((char *)); static int fallbackmxrr __P((int, unsigned short *, char **)); @@ -96,11 +95,11 @@ static int fallbackmxrr __P((int, unsigned short *, char **)); ** number of MX records. ** ** Side Effects: -** Populates NumFallBackMXHosts and fbhosts. +** Populates NumFallbackMXHosts and fbhosts. ** Sets renewal time (based on TTL). */ -int NumFallBackMXHosts = 0; /* Number of fallback MX hosts (after MX expansion) */ +int NumFallbackMXHosts = 0; /* Number of fallback MX hosts (after MX expansion) */ static char *fbhosts[MAXMXHOSTS + 1]; int @@ -116,27 +115,27 @@ getfallbackmxrr(host) if (host == NULL || *host == '\0') return 0; #endif /* 0 */ - if (NumFallBackMXHosts > 0 && renew > curtime()) - return NumFallBackMXHosts; + if (NumFallbackMXHosts > 0 && renew > curtime()) + return NumFallbackMXHosts; if (host[0] == '[') { fbhosts[0] = host; - NumFallBackMXHosts = 1; + NumFallbackMXHosts = 1; } else { /* free old data */ - for (i = 0; i < NumFallBackMXHosts; i++) + for (i = 0; i < NumFallbackMXHosts; i++) sm_free(fbhosts[i]); /* get new data */ - NumFallBackMXHosts = getmxrr(host, fbhosts, NULL, false, + NumFallbackMXHosts = getmxrr(host, fbhosts, NULL, false, &rcode, false, &ttl); renew = curtime() + ttl; - for (i = 0; i < NumFallBackMXHosts; i++) + for (i = 0; i < NumFallbackMXHosts; i++) fbhosts[i] = newstr(fbhosts[i]); } - return NumFallBackMXHosts; + return NumFallbackMXHosts; } /* @@ -151,7 +150,7 @@ getfallbackmxrr(host) ** new number of MX records. ** ** Side Effects: -** If FallBackMX was set, it appends the MX records for +** If FallbackMX was set, it appends the MX records for ** that host to mxhosts (and modifies prefs accordingly). */ @@ -163,7 +162,7 @@ fallbackmxrr(nmx, prefs, mxhosts) { int i; - for (i = 0; i < NumFallBackMXHosts && nmx < MAXMXHOSTS; i++) + for (i = 0; i < NumFallbackMXHosts && nmx < MAXMXHOSTS; i++) { if (nmx > 0) prefs[nmx] = prefs[nmx - 1] + 1; @@ -221,7 +220,7 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl) bool seenlocal = false; unsigned short pref, type; unsigned short localpref = 256; - char *fallbackMX = FallBackMX; + char *fallbackMX = FallbackMX; bool trycanon = false; unsigned short *prefs; int (*resfunc)(); @@ -342,7 +341,7 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl) ancount = ntohs((unsigned short) hp->ancount); /* See RFC 1035 for layout of RRs. */ - /* XXX leave room for FallBackMX ? */ + /* XXX leave room for FallbackMX ? */ while (--ancount >= 0 && cp < eom && nmx < MAXMXHOSTS - 1) { if ((n = dn_expand((unsigned char *)&answer, eom, cp, @@ -805,7 +804,6 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl) int qtype; int initial; int loopcnt; - char *xp; char nbuf[SM_MAX(MAXPACKET, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH + 2]; @@ -839,24 +837,6 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl) if (*cp == '.') n++; - /* - ** If this is a simple name, determine whether it matches an - ** alias in the file defined by the environment variable HOSTALIASES. - */ - - if (n == 0 && (xp = gethostalias(host)) != NULL) - { - if (loopcnt++ > MAXCNAMEDEPTH) - { - syserr("loop in ${HOSTALIASES} file"); - } - else - { - (void) sm_strlcpy(host, xp, hbsize); - goto cnameloop; - } - } - /* ** Build the search list. ** If there is at least one dot in name, start with a null @@ -933,14 +913,12 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl) */ SM_SET_H_ERRNO(TRY_AGAIN); -# if _FFR_DONT_STOP_LOOKING if (**dp == '\0') { if (*statp == EX_OK) *statp = EX_TEMPFAIL; goto nexttype; } -# endif /* _FFR_DONT_STOP_LOOKING */ *statp = EX_TEMPFAIL; if (WorkAroundBrokenAAAA) @@ -962,9 +940,7 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl) return false; } -# if _FFR_DONT_STOP_LOOKING nexttype: -# endif /* _FFR_DONT_STOP_LOOKING */ if (h_errno != HOST_NOT_FOUND) { /* might have another type of interest */ @@ -1189,56 +1165,4 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl) *pttl = ttl; return true; } - -static char * -gethostalias(host) - char *host; -{ - char *fname; - SM_FILE_T *fp; - register char *p = NULL; - long sff = SFF_REGONLY; - char buf[MAXLINE]; - static char hbuf[MAXDNAME]; - - if (ResNoAliases) - return NULL; - if (DontLockReadFiles) - sff |= SFF_NOLOCK; - fname = getenv("HOSTALIASES"); - if (fname == NULL || - (fp = safefopen(fname, O_RDONLY, 0, sff)) == NULL) - return NULL; - while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) - { - for (p = buf; p != '\0' && !(isascii(*p) && isspace(*p)); p++) - continue; - if (*p == 0) - { - /* syntax error */ - continue; - } - *p++ = '\0'; - if (sm_strcasecmp(buf, host) == 0) - break; - } - - if (sm_io_eof(fp)) - { - /* no match */ - (void) sm_io_close(fp, SM_TIME_DEFAULT); - return NULL; - } - (void) sm_io_close(fp, SM_TIME_DEFAULT); - - /* got a match; extract the equivalent name */ - while (*p != '\0' && isascii(*p) && isspace(*p)) - p++; - host = p; - while (*p != '\0' && !(isascii(*p) && isspace(*p))) - p++; - *p = '\0'; - (void) sm_strlcpy(hbuf, host, sizeof hbuf); - return hbuf; -} #endif /* NAMED_BIND */ diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c index c29871f3b806..1aedd3e57157 100644 --- a/contrib/sendmail/src/envelope.c +++ b/contrib/sendmail/src/envelope.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: envelope.c,v 8.282.2.2 2002/12/04 15:44:08 ca Exp $") +SM_RCSID("@(#)$Id: envelope.c,v 8.293 2004/02/18 00:46:18 gshapiro Exp $") /* ** CLRSESSENVELOPE -- clear session oriented data in an envelope @@ -101,7 +101,6 @@ newenvelope(e, parent, rpool) if (parent != NULL) { e->e_msgpriority = parent->e_msgsize; -#if _FFR_QUARANTINE if (parent->e_quarmsg == NULL) { e->e_quarmsg = NULL; @@ -115,7 +114,6 @@ newenvelope(e, parent, rpool) macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), e->e_quarmsg); } -#endif /* _FFR_QUARANTINE */ } e->e_puthdr = putheader; e->e_putbody = putbody; @@ -176,13 +174,13 @@ dropenvelope(e, fulldrop, split) if (tTd(50, 1)) { sm_dprintf("dropenvelope %p: id=", e); - xputs(e->e_id); + xputs(sm_debug_file(), e->e_id); sm_dprintf(", flags="); printenvflags(e); if (tTd(50, 10)) { sm_dprintf("sendq="); - printaddr(e->e_sendqueue, true); + printaddr(sm_debug_file(), e->e_sendqueue, true); } } @@ -507,7 +505,6 @@ dropenvelope(e, fulldrop, split) } if (!panic) (void) xunlink(queuename(e, DATAFL_LETTER)); -#if _FFR_QUARANTINE if (panic && QueueMode == QM_LOST) { /* @@ -518,7 +515,6 @@ dropenvelope(e, fulldrop, split) /* EMPTY */ } else -#endif /* _FFR_QUARANTINE */ if (xunlink(queuename(e, ANYQFL_LETTER)) == 0) { /* add to available space in filesystem */ @@ -655,11 +651,9 @@ clearenvelope(e, fullclear, rpool) *e = BlankEnvelope; e->e_message = NULL; -#if _FFR_QUARANTINE e->e_qfletter = '\0'; e->e_quarmsg = NULL; macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); -#endif /* _FFR_QUARANTINE */ /* ** Copy the macro table. @@ -732,13 +726,7 @@ initsys(e) openxscript(e); e->e_ctime = curtime(); -#if _FFR_QUARANTINE e->e_qfletter = '\0'; -#endif /* _FFR_QUARANTINE */ -#if _FFR_QUEUEDELAY - e->e_queuealg = QueueAlg; - e->e_queuedelay = QueueInitDelay; -#endif /* _FFR_QUEUEDELAY */ /* ** Set OutChannel to something useful if stdout isn't it. @@ -807,6 +795,8 @@ settime(e) register struct tm *tm; now = curtime(); + (void) sm_snprintf(buf, sizeof buf, "%ld", (long) now); + macdefine(&e->e_macro, A_TEMP, macid("{time}"), buf); tm = gmtime(&now); (void) sm_snprintf(buf, sizeof buf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, @@ -1044,7 +1034,7 @@ setsender(from, e, delimptr, delimchar, internal) if (tTd(45, 5)) { sm_dprintf("setsender: QS_SENDER "); - printaddr(&e->e_from, false); + printaddr(sm_debug_file(), &e->e_from, false); } SuprErrs = false; @@ -1140,7 +1130,7 @@ setsender(from, e, delimptr, delimchar, internal) ** links in the net. */ - pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL); + pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL, false); if (pvp == NULL) { /* don't need to give error -- prescan did that already */ @@ -1180,15 +1170,17 @@ setsender(from, e, delimptr, delimchar, internal) /* strip off to the last "@" sign */ for (lastat = NULL; *pvp != NULL; pvp++) + { if (strcmp(*pvp, "@") == 0) lastat = pvp; + } if (lastat != NULL) { e->e_fromdomain = copyplist(lastat, true, e->e_rpool); if (tTd(45, 3)) { sm_dprintf("Saving from domain: "); - printav(e->e_fromdomain); + printav(sm_debug_file(), e->e_fromdomain); } } } @@ -1249,19 +1241,17 @@ printenvflags(e) register struct eflags *ef; bool first = true; - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%lx", e->e_flags); + sm_dprintf("%lx", e->e_flags); for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++) { if (!bitset(ef->ef_bit, e->e_flags)) continue; if (first) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "<%s", - ef->ef_name); + sm_dprintf("<%s", ef->ef_name); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ",%s", - ef->ef_name); + sm_dprintf(",%s", ef->ef_name); first = false; } if (!first) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ">\n"); + sm_dprintf(">\n"); } diff --git a/contrib/sendmail/src/macro.c b/contrib/sendmail/src/macro.c index fc7a2c277c84..af8f6d5b1945 100644 --- a/contrib/sendmail/src/macro.c +++ b/contrib/sendmail/src/macro.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2001, 2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: macro.c,v 8.86 2001/09/11 04:05:14 gshapiro Exp $") +SM_RCSID("@(#)$Id: macro.c,v 8.88 2003/09/05 23:11:18 ca Exp $") #if MAXMACROID != (BITMAPBITS - 1) ERROR Read the comment in conf.h @@ -130,7 +130,7 @@ expand(s, buf, bufsize, e) if (tTd(35, 24)) { sm_dprintf("expand("); - xputs(s); + xputs(sm_debug_file(), s); sm_dprintf(")\n"); } @@ -223,7 +223,7 @@ expand(s, buf, bufsize, e) if (tTd(35, 24)) { sm_dprintf("expand ==> "); - xputs(xbuf); + xputs(sm_debug_file(), xbuf); sm_dprintf("\n"); } @@ -305,7 +305,7 @@ macdefine(mac, vclass, id, value) { sm_dprintf("%sdefine(%s as ", mac->mac_table[id] == NULL ? "" : "re", macname(id)); - xputs(value); + xputs(sm_debug_file(), value); sm_dprintf(")\n"); } @@ -325,7 +325,11 @@ macdefine(mac, vclass, id, value) } else { +#if SM_HEAP_CHECK newvalue = sm_strdup_tagged_x(value, file, line, 0); +#else /* SM_HEAP_CHECK */ + newvalue = sm_strdup_x(value); +#endif /* SM_HEAP_CHECK */ setbitn(id, mac->mac_allocated); } mac->mac_table[id] = newvalue; @@ -377,7 +381,7 @@ macset(mac, i, value) if (tTd(35, 9)) { sm_dprintf("macset(%s as ", macname(i)); - xputs(value); + xputs(sm_debug_file(), value); sm_dprintf(")\n"); } mac->mac_table[i] = value; @@ -487,7 +491,7 @@ macid_parse(p, ep) if (tTd(35, 14)) { sm_dprintf("macid("); - xputs(p); + xputs(sm_debug_file(), p); sm_dprintf(") => "); } diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c index 0d8c0ce4d5e5..f274ad871d87 100644 --- a/contrib/sendmail/src/main.c +++ b/contrib/sendmail/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -18,14 +18,14 @@ #ifndef lint SM_UNUSED(static char copyright[]) = -"@(#) Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.\n\ +"@(#) Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.\n\ All rights reserved.\n\ Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.\n\ Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ -SM_RCSID("@(#)$Id: main.c,v 8.887.2.29 2003/11/07 00:09:31 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.939 2004/06/17 16:39:21 ca Exp $") #if NETINET || NETINET6 @@ -175,15 +175,14 @@ main(argc, argv, envp) char *sysloglabel = NULL; /* label for syslog */ char *conffile = NULL; /* name of .cf file */ char *queuegroup = NULL; /* queue group to process */ -#if _FFR_QUARANTINE char *quarantining = NULL; /* quarantine queue items? */ -#endif /* _FFR_QUARANTINE */ bool extraprivs; bool forged, negate; bool queuepersistent = false; /* queue runner process runs forever */ bool foregroundqueue = false; /* queue run in foreground */ bool save_val; /* to save some bool var. */ int cftype; /* which cf file to use? */ + SM_FILE_T *smdebug; static time_t starttime = 0; /* when was process started */ struct stat traf_st; /* for TrafficLog FIFO check */ char buf[MAXLINE]; @@ -268,14 +267,9 @@ main(argc, argv, envp) if (errno != 0) fill_errno = errno; - i = DtableSize; - while (--i > 0) - { - if (i != STDIN_FILENO && i != STDOUT_FILENO && - i != STDERR_FILENO) - (void) close(i); - } + sm_closefrom(STDERR_FILENO + 1, DtableSize); errno = 0; + smdebug = NULL; #if LOG # ifndef SM_LOG_STR @@ -371,27 +365,15 @@ main(argc, argv, envp) else if (strcmp(p, "purgestat") == 0) OpMode = MD_PURGESTAT; -#if _FFR_QUARANTINE -# if defined(__osf__) || defined(_AIX3) -# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:xQ:" -# endif /* defined(__osf__) || defined(_AIX3) */ -# if defined(sony_news) -# define OPTIONS "A:B:b:C:cd:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:q:R:r:sTtV:vX:Q:" -# endif /* defined(sony_news) */ -# ifndef OPTIONS -# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:Q:" -# endif /* ! OPTIONS */ -#else /* _FFR_QUARANTINE */ -# if defined(__osf__) || defined(_AIX3) -# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:x" -# endif /* defined(__osf__) || defined(_AIX3) */ -# if defined(sony_news) -# define OPTIONS "A:B:b:C:cd:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:q:R:r:sTtV:vX:" -# endif /* defined(sony_news) */ -# ifndef OPTIONS -# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:" -# endif /* ! OPTIONS */ -#endif /* _FFR_QUARANTINE */ +#if defined(__osf__) || defined(_AIX3) +# define OPTIONS "A:B:b:C:cD:d:e:F:f:Gh:IiL:M:mN:nO:o:p:Q:q:R:r:sTtV:vX:x" +#endif /* defined(__osf__) || defined(_AIX3) */ +#if defined(sony_news) +# define OPTIONS "A:B:b:C:cD:d:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:Q:q:R:r:sTtV:vX:" +#endif /* defined(sony_news) */ +#ifndef OPTIONS +# define OPTIONS "A:B:b:C:cD:d:e:F:f:Gh:IiL:M:mN:nO:o:p:Q:q:R:r:sTtV:vX:" +#endif /* ! OPTIONS */ /* Set to 0 to allow -b; need to check optarg before using it! */ opterr = 0; @@ -431,10 +413,31 @@ main(argc, argv, envp) } break; + case 'D': + if (debug) + { + errno = 0; + syserr("-D file must be before -d"); + ExitStat = EX_USAGE; + break; + } + dp = drop_privileges(true); + setstat(dp); + smdebug = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, + optarg, SM_IO_APPEND, NULL); + if (smdebug == NULL) + { + syserr("cannot open %s", optarg); + ExitStat = EX_CANTCREAT; + break; + } + sm_debug_setfile(smdebug); + break; + case 'd': debug = true; tTflag(optarg); - (void) sm_io_setvbuf(smioout, SM_TIME_DEFAULT, + (void) sm_io_setvbuf(sm_debug_file(), SM_TIME_DEFAULT, (char *) NULL, SM_IO_NBF, SM_IO_BUFSIZ); break; @@ -451,16 +454,14 @@ main(argc, argv, envp) (char) j); return EX_USAGE; } - j = SM_MIN(strlen(optarg), 24) + 1; + j = SM_MIN(strlen(optarg), 32) + 1; sysloglabel = xalloc(j); (void) sm_strlcpy(sysloglabel, optarg, j); SyslogPrefixLen = PIDLEN + (MAXQFNAME - 3) + SL_FUDGE + j; break; -#if _FFR_QUARANTINE case 'Q': -#endif /* _FFR_QUARANTINE */ case 'q': /* just check if it is there */ queuerun = true; @@ -474,6 +475,7 @@ main(argc, argv, envp) { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "WARNING: Can not use -d with -q. Disabling debugging.\n"); + sm_debug_close(); sm_debug_setfile(NULL); (void) memset(tTdvect, '\0', sizeof tTdvect); } @@ -667,8 +669,6 @@ main(argc, argv, envp) else _res.options &= ~RES_DEBUG; # ifdef RES_NOALIASES - if (bitset(RES_NOALIASES, _res.options)) - ResNoAliases = true; _res.options |= RES_NOALIASES; # endif /* RES_NOALIASES */ TimeOuts.res_retry[RES_TO_DEFAULT] = _res.retry; @@ -701,23 +701,8 @@ main(argc, argv, envp) setclass('w', jbuf); p = strchr(jbuf, '.'); - if (p != NULL) - { - if (p[1] != '\0') - { - macdefine(&BlankEnvelope.e_macro, A_TEMP, 'm', - &p[1]); - } - while (p != NULL && strchr(&p[1], '.') != NULL) - { - *p = '\0'; - if (tTd(0, 4)) - sm_dprintf("\ta.k.a.: %s\n", jbuf); - setclass('w', jbuf); - *p++ = '.'; - p = strchr(p, '.'); - } - } + if (p != NULL && p[1] != '\0') + macdefine(&BlankEnvelope.e_macro, A_TEMP, 'm', &p[1]); if (uname(&utsname) >= 0) p = utsname.nodename; @@ -806,9 +791,7 @@ main(argc, argv, envp) QueueLimitRecipient = (QUEUE_CHAR *) NULL; QueueLimitSender = (QUEUE_CHAR *) NULL; QueueLimitId = (QUEUE_CHAR *) NULL; -#if _FFR_QUARANTINE QueueLimitQuarantine = (QUEUE_CHAR *) NULL; -#endif /* _FFR_QUARANTINE */ /* ** Crack argv. @@ -842,6 +825,7 @@ main(argc, argv, envp) safecf = false; break; + case 'D': case 'd': /* debugging */ /* already done */ break; @@ -957,7 +941,6 @@ main(argc, argv, envp) } break; -#if _FFR_QUARANTINE case 'Q': /* change quarantining on queued items */ /* sanity check */ if (OpMode != MD_DELIVER && @@ -975,7 +958,6 @@ main(argc, argv, envp) quarantining = newstr(optarg); break; -#endif /* _FFR_QUARANTINE */ case 'q': /* run queue files at intervals */ /* sanity check */ @@ -1049,7 +1031,6 @@ main(argc, argv, envp) foregroundqueue = true; break; -#if _FFR_QUARANTINE case 'Q': /* Limit by quarantine message */ if (optarg[1] != '\0') { @@ -1065,7 +1046,6 @@ main(argc, argv, envp) case 'L': /* act on lost items */ QueueMode = QM_LOST; break; -#endif /* _FFR_QUARANTINE */ case 'p': /* Persistent queue */ queuepersistent = true; @@ -1308,8 +1288,8 @@ main(argc, argv, envp) } #if NAMED_BIND - if (FallBackMX != NULL) - (void) getfallbackmxrr(FallBackMX); + if (FallbackMX != NULL) + (void) getfallbackmxrr(FallbackMX); #endif /* NAMED_BIND */ if (SuperSafe == SAFE_INTERACTIVE && CurEnv->e_sendmode != SM_DELIVER) @@ -1418,13 +1398,13 @@ main(argc, argv, envp) { sm_dprintf("\n============ SYSTEM IDENTITY (after readcf) ============"); sm_dprintf("\n (short domain name) $w = "); - xputs(macvalue('w', &BlankEnvelope)); + xputs(sm_debug_file(), macvalue('w', &BlankEnvelope)); sm_dprintf("\n (canonical domain name) $j = "); - xputs(macvalue('j', &BlankEnvelope)); + xputs(sm_debug_file(), macvalue('j', &BlankEnvelope)); sm_dprintf("\n (subdomain name) $m = "); - xputs(macvalue('m', &BlankEnvelope)); + xputs(sm_debug_file(), macvalue('m', &BlankEnvelope)); sm_dprintf("\n (node name) $k = "); - xputs(macvalue('k', &BlankEnvelope)); + xputs(sm_debug_file(), macvalue('k', &BlankEnvelope)); sm_dprintf("\n========================================================\n\n"); } @@ -1459,10 +1439,6 @@ main(argc, argv, envp) if (DefaultNotify == 0) DefaultNotify = QPINGONFAILURE|QPINGONDELAY; - /* be sure we don't pick up bogus HOSTALIASES environment variable */ - if (OpMode == MD_QUEUERUN && RealUid != 0) - (void) unsetenv("HOSTALIASES"); - /* check for sane configuration level */ if (ConfigLevel > MAXCONFIGLEVEL) { @@ -1495,14 +1471,14 @@ main(argc, argv, envp) switch (OpMode) { case MD_QUEUERUN: -#if _FFR_QUARANTINE if (quarantining != NULL) action = "quarantine jobs"; else -#endif /* _FFR_QUARANTINE */ - /* Normal users can do a single queue run */ - if (QueueIntvl == 0) - break; + { + /* Normal users can do a single queue run */ + if (QueueIntvl == 0) + break; + } /* but not persistent queue runners */ if (action == NULL) @@ -1757,7 +1733,7 @@ main(argc, argv, envp) else PSTRSET(MyHostName, jbuf); if (strchr(MyHostName, '.') == NULL) - message("WARNING: local host name (%s) is not qualified; fix $j in config file", + message("WARNING: local host name (%s) is not qualified; see cf/README: WHO AM I?", MyHostName); /* make certain that this name is part of the $=w class */ @@ -1917,9 +1893,7 @@ main(argc, argv, envp) if (OpMode == MD_DAEMON || OpMode == MD_SMTP) { milter_config(InputFilterList, InputFilters, MAXFILTERS); -# if _FFR_MILTER_PERDAEMON setup_daemon_milters(); -# endif /* _FFR_MILTER_PERDAEMON */ } #endif /* MILTER */ @@ -1991,7 +1965,6 @@ main(argc, argv, envp) /* NOTREACHED */ break; -#if _FFR_QUARANTINE case MD_QUEUERUN: /* only handle quarantining here */ if (quarantining == NULL) @@ -2009,7 +1982,6 @@ main(argc, argv, envp) quarantine_queue(quarantining, qgrp); finis(false, true, EX_OK); break; -#endif /* _FFR_QUARANTINE */ case MD_HOSTSTAT: (void) sm_signal(SIGPIPE, sigpipe); @@ -2056,7 +2028,7 @@ main(argc, argv, envp) for (i = 0; i < MAXMAILERS; i++) { if (Mailer[i] != NULL) - printmailer(Mailer[i]); + printmailer(sm_debug_file(), Mailer[i]); } } @@ -2286,7 +2258,7 @@ main(argc, argv, envp) if (OpMode == MD_SMTP) { proc_list_add(CurrentPid, "Sendmail SMTP Agent", - PROC_DAEMON, 0, -1); + PROC_DAEMON, 0, -1, NULL); /* clean up background delivery children */ (void) sm_signal(SIGCHLD, reapchild); @@ -2385,6 +2357,13 @@ main(argc, argv, envp) if (OpMode != MD_DAEMON && queuepersistent) { + /* + ** Write the pid to file + ** XXX Overwrites sendmail.pid + */ + + log_sendmail_pid(&MainEnvelope); + /* set the title to make it easier to find */ sm_setproctitle(true, CurEnv, "Queue control"); (void) sm_signal(SIGCHLD, SIG_DFL); @@ -2488,7 +2467,9 @@ main(argc, argv, envp) for (;;) { (void) pause(); + CHECK_RESTART; + if (doqueuerun()) (void) runqueue(true, false, false, false); @@ -2554,6 +2535,8 @@ main(argc, argv, envp) else macdefine(&BlankEnvelope.e_macro, A_PERM, macid("{client_name}"), RealHostName); + macdefine(&BlankEnvelope.e_macro, A_PERM, + macid("{client_ptr}"), RealHostName); macdefine(&BlankEnvelope.e_macro, A_TEMP, macid("{client_addr}"), anynet_ntoa(&RealHostAddr)); sm_getla(); @@ -2584,8 +2567,9 @@ main(argc, argv, envp) /* validate the connection */ HoldErrs = true; nullserver = validate_connection(&RealHostAddr, - RealHostName, - &MainEnvelope); + macvalue(macid("{client_name}"), + &MainEnvelope), + &MainEnvelope); HoldErrs = false; } else if (p_flags == NULL) @@ -2785,11 +2769,9 @@ main(argc, argv, envp) sm_dprintf("From person = \"%s\"\n", MainEnvelope.e_from.q_paddr); -#if _FFR_QUARANTINE /* Check if quarantining stats should be updated */ if (MainEnvelope.e_quarmsg != NULL) markstats(&MainEnvelope, NULL, STATS_QUARANTINE); -#endif /* _FFR_QUARANTINE */ /* ** Actually send everything. @@ -2813,7 +2795,7 @@ main(argc, argv, envp) if (tTd(1, 5)) { sm_dprintf("main[%d]: QS_SENDER ", i); - printaddr(&e->e_from, false); + printaddr(sm_debug_file(), &e->e_from, false); } e->e_to = NULL; sm_getla(); @@ -2881,6 +2863,7 @@ finis(drop, cleanup, exitstat) bool cleanup; volatile int exitstat; { + char pidpath[MAXPATHLEN]; /* Still want to process new timeouts added below */ sm_clear_events(); @@ -2953,6 +2936,16 @@ finis(drop, cleanup, exitstat) cleanup_shm(DaemonPid == getpid()); #endif /* SM_CONF_SHM */ + /* close locked pid file */ + close_sendmail_pid(); + + if (DaemonPid == getpid() || PidFilePid == getpid()) + { + /* blow away the pid file */ + expand(PidFile, pidpath, sizeof pidpath, CurEnv); + (void) unlink(pidpath); + } + /* reset uid for process accounting */ endpwent(); sm_mbdb_terminate(); @@ -3309,7 +3302,6 @@ obsolete(argv) if (ap[0] != '-' || ap[1] == '-') return; -#if _FFR_QUARANTINE /* Don't allow users to use "-Q." or "-Q ." */ if ((ap[1] == 'Q' && ap[2] == '.') || (ap[1] == 'Q' && argv[1] != NULL && @@ -3319,7 +3311,6 @@ obsolete(argv) "Can not use -Q.\n"); exit(EX_USAGE); } -#endif /* _FFR_QUARANTINE */ /* skip over options that do have a value */ op = strchr(OPTIONS, ap[1]); @@ -3347,11 +3338,9 @@ obsolete(argv) if (ap[1] == 'q' && ap[2] == '\0') *argv = "-q0"; -#if _FFR_QUARANTINE /* If -Q doesn't have an argument, disable quarantining */ if (ap[1] == 'Q' && ap[2] == '\0') *argv = "-Q."; -#endif /* _FFR_QUARANTINE */ /* if -d doesn't have an argument, use 0-99.1 */ if (ap[1] == 'd' && ap[2] == '\0') @@ -3531,7 +3520,7 @@ dumpstate(when) sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- open file descriptors: ---"); printopenfds(true); sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- connection cache: ---"); - mci_dump_all(true); + mci_dump_all(smioout, true); rs = strtorwset("debug_dumpstate", NULL, ST_FIND); if (rs > 0) { @@ -3999,7 +3988,7 @@ testmodeline(line, e) s = rw->r_lhs; while (*s != NULL) { - xputs(*s++); + xputs(smioout, *s++); (void) sm_io_putc(smioout, SM_TIME_DEFAULT, ' '); } @@ -4010,7 +3999,7 @@ testmodeline(line, e) s = rw->r_rhs; while (*s != NULL) { - xputs(*s++); + xputs(smioout, *s++); (void) sm_io_putc(smioout, SM_TIME_DEFAULT, ' '); } @@ -4023,7 +4012,7 @@ testmodeline(line, e) for (i = 0; i < MAXMAILERS; i++) { if (Mailer[i] != NULL) - printmailer(Mailer[i]); + printmailer(smioout, Mailer[i]); } break; @@ -4075,7 +4064,7 @@ testmodeline(line, e) "Undefined\n"); else { - xputs(p); + xputs(smioout, p); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); } @@ -4292,7 +4281,7 @@ testmodeline(line, e) q = crackaddr(p, e); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "Cracked address = "); - xputs(q); + xputs(smioout, q); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\nParsing %s %s address\n", bitset(RF_HEADERADDR, tryflags) ? @@ -4344,8 +4333,8 @@ testmodeline(line, e) register char **pvp; char pvpbuf[PSBUFSIZE]; - pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf, - &delimptr, ConfigLevel >= 9 ? TokTypeNoC : NULL); + pvp = prescan(++p, ',', pvpbuf, sizeof pvpbuf, &delimptr, + ConfigLevel >= 9 ? TokTypeNoC : NULL, false); if (pvp == NULL) continue; p = q; diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c index 83623276aca5..ad9fa70e5913 100644 --- a/contrib/sendmail/src/map.c +++ b/contrib/sendmail/src/map.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: map.c,v 8.645.2.10 2003/07/24 18:24:17 ca Exp $") +SM_RCSID("@(#)$Id: map.c,v 8.664 2004/06/28 17:46:13 ca Exp $") #if LDAPMAP # include @@ -66,6 +66,12 @@ static bool nis_getcanonname __P((char *, int, int *)); static bool ni_getcanonname __P((char *, int, int *)); #endif /* NETINFO */ static bool text_getcanonname __P((char *, int, int *)); +#if SOCKETMAP +static STAB *socket_map_findconn __P((const char*)); + +/* XXX arbitrary limit for sanity */ +# define SOCKETMAP_MAXL 1000000 +#endif /* SOCKETMAP */ /* default error message for trying to open a map in write mode */ #ifdef ENOSYS @@ -3307,6 +3313,7 @@ ldapmap_open(map, mode) { SM_LDAP_STRUCT *lmap; STAB *s; + char *id; if (tTd(38, 2)) sm_dprintf("ldapmap_open(%s, %d): ", map->map_mname, mode); @@ -3342,6 +3349,13 @@ ldapmap_open(map, mode) if (tTd(38, 2)) sm_dprintf("opening new connection\n"); + if (lmap->ldap_host != NULL) + id = lmap->ldap_host; + else if (lmap->ldap_uri != NULL) + id = lmap->ldap_uri; + else + id = "localhost"; + /* No connection yet, connect */ if (!sm_ldap_start(map->map_mname, lmap)) { @@ -3350,31 +3364,31 @@ ldapmap_open(map, mode) if (LogLevel > 1) sm_syslog(LOG_NOTICE, CurEnv->e_id, "timeout conning to LDAP server %.100s", - lmap->ldap_target == NULL ? "localhost" : lmap->ldap_target); + id); } if (!bitset(MF_OPTIONAL, map->map_mflags)) { if (bitset(MF_NODEFER, map->map_mflags)) + { syserr("%s failed to %s in map %s", # if USE_LDAP_INIT "ldap_init/ldap_bind", # else /* USE_LDAP_INIT */ "ldap_open", # endif /* USE_LDAP_INIT */ - lmap->ldap_target == NULL ? "localhost" - : lmap->ldap_target, - map->map_mname); + id, map->map_mname); + } else + { syserr("451 4.3.5 %s failed to %s in map %s", # if USE_LDAP_INIT "ldap_init/ldap_bind", # else /* USE_LDAP_INIT */ "ldap_open", # endif /* USE_LDAP_INIT */ - lmap->ldap_target == NULL ? "localhost" - : lmap->ldap_target, - map->map_mname); + id, map->map_mname); + } } return false; } @@ -3470,19 +3484,14 @@ ldapmap_lookup(map, name, av, statp) char **av; int *statp; { -# if _FFR_LDAP_RECURSION + int flags; int plen = 0; int psize = 0; -# else /* _FFR_LDAP_RECURSION */ - int entries = 0; - int i; - int ret; - int vsize; -# endif /* _FFR_LDAP_RECURSION */ int msgid; int save_errno; char *vp, *p; char *result = NULL; + SM_RPOOL_T *rpool; SM_LDAP_STRUCT *lmap = NULL; char keybuf[MAXNAME + 1]; @@ -3537,391 +3546,37 @@ ldapmap_lookup(map, name, av, statp) *statp = EX_NOTFOUND; vp = NULL; -# if _FFR_LDAP_RECURSION + flags = 0; + if (bitset(MF_SINGLEMATCH, map->map_mflags)) + flags |= SM_LDAP_SINGLEMATCH; + if (bitset(MF_MATCHONLY, map->map_mflags)) + flags |= SM_LDAP_MATCHONLY; + + /* Create an rpool for search related memory usage */ + rpool = sm_rpool_new_x(NULL); + + p = NULL; + *statp = sm_ldap_results(lmap, msgid, flags, map->map_coldelim, + rpool, &p, &plen, &psize, NULL); + save_errno = errno; + + /* Copy result so rpool can be freed */ + if (*statp == EX_OK && p != NULL) + vp = newstr(p); + sm_rpool_free(rpool); + + /* need to restart LDAP connection? */ + if (*statp == EX_RESTART) { - int flags; - SM_RPOOL_T *rpool; - - flags = 0; - if (bitset(MF_SINGLEMATCH, map->map_mflags)) - flags |= SM_LDAP_SINGLEMATCH; - if (bitset(MF_MATCHONLY, map->map_mflags)) - flags |= SM_LDAP_MATCHONLY; - - /* Create an rpool for search related memory usage */ - rpool = sm_rpool_new_x(NULL); - - p = NULL; - *statp = sm_ldap_results(lmap, msgid, flags, map->map_coldelim, - rpool, &p, &plen, &psize, NULL); - save_errno = errno; - - /* Copy result so rpool can be freed */ - if (*statp == EX_OK && p != NULL) - vp = newstr(p); - sm_rpool_free(rpool); - - /* need to restart LDAP connection? */ - if (*statp == EX_RESTART) - { - *statp = EX_TEMPFAIL; - ldapmap_close(map); - } - - errno = save_errno; - if (*statp != EX_OK && *statp != EX_NOTFOUND) - { - if (!bitset(MF_OPTIONAL, map->map_mflags)) - { - if (bitset(MF_NODEFER, map->map_mflags)) - syserr("Error getting LDAP results in map %s", - map->map_mname); - else - syserr("451 4.3.5 Error getting LDAP results in map %s", - map->map_mname); - } - errno = save_errno; - return NULL; - } - } -# else /* _FFR_LDAP_RECURSION */ - - /* Get results */ - while ((ret = ldap_result(lmap->ldap_ld, msgid, 0, - (lmap->ldap_timeout.tv_sec == 0 ? NULL : - &(lmap->ldap_timeout)), - &(lmap->ldap_res))) == LDAP_RES_SEARCH_ENTRY) - { - LDAPMessage *entry; - - if (bitset(MF_SINGLEMATCH, map->map_mflags)) - { - entries += ldap_count_entries(lmap->ldap_ld, - lmap->ldap_res); - if (entries > 1) - { - *statp = EX_NOTFOUND; - if (lmap->ldap_res != NULL) - { - ldap_msgfree(lmap->ldap_res); - lmap->ldap_res = NULL; - } - (void) ldap_abandon(lmap->ldap_ld, msgid); - if (vp != NULL) - sm_free(vp); /* XXX */ - if (tTd(38, 25)) - sm_dprintf("ldap search found multiple on a single match query\n"); - return NULL; - } - } - - /* If we don't want multiple values and we have one, break */ - if (map->map_coldelim == '\0' && vp != NULL) - break; - - /* Cycle through all entries */ - for (entry = ldap_first_entry(lmap->ldap_ld, lmap->ldap_res); - entry != NULL; - entry = ldap_next_entry(lmap->ldap_ld, lmap->ldap_res)) - { - BerElement *ber; - char *attr; - char **vals = NULL; - - /* - ** If matching only and found an entry, - ** no need to spin through attributes - */ - - if (*statp == EX_OK && - bitset(MF_MATCHONLY, map->map_mflags)) - continue; - -# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT) - /* - ** Reset value to prevent lingering - ** LDAP_DECODING_ERROR due to - ** OpenLDAP 1.X's hack (see below) - */ - - lmap->ldap_ld->ld_errno = LDAP_SUCCESS; -# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */ - - for (attr = ldap_first_attribute(lmap->ldap_ld, entry, - &ber); - attr != NULL; - attr = ldap_next_attribute(lmap->ldap_ld, entry, - ber)) - { - char *tmp, *vp_tmp; - - if (lmap->ldap_attrsonly == LDAPMAP_FALSE) - { - vals = ldap_get_values(lmap->ldap_ld, - entry, - attr); - if (vals == NULL) - { - save_errno = sm_ldap_geterrno(lmap->ldap_ld); - if (save_errno == LDAP_SUCCESS) - { - ldap_memfree(attr); - continue; - } - - /* Must be an error */ - save_errno += E_LDAPBASE; - if (!bitset(MF_OPTIONAL, - map->map_mflags)) - { - errno = save_errno; - if (bitset(MF_NODEFER, - map->map_mflags)) - syserr("Error getting LDAP values in map %s", - map->map_mname); - else - syserr("451 4.3.5 Error getting LDAP values in map %s", - map->map_mname); - } - *statp = EX_TEMPFAIL; - ldap_memfree(attr); - if (lmap->ldap_res != NULL) - { - ldap_msgfree(lmap->ldap_res); - lmap->ldap_res = NULL; - } - (void) ldap_abandon(lmap->ldap_ld, - msgid); - if (vp != NULL) - sm_free(vp); /* XXX */ - errno = save_errno; - return NULL; - } - } - - *statp = EX_OK; - -# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT) - /* - ** Reset value to prevent lingering - ** LDAP_DECODING_ERROR due to - ** OpenLDAP 1.X's hack (see below) - */ - - lmap->ldap_ld->ld_errno = LDAP_SUCCESS; -# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */ - - /* - ** If matching only, - ** no need to spin through entries - */ - - if (bitset(MF_MATCHONLY, map->map_mflags)) - { - if (lmap->ldap_attrsonly == LDAPMAP_FALSE) - ldap_value_free(vals); - - ldap_memfree(attr); - continue; - } - - /* - ** If we don't want multiple values, - ** return first found. - */ - - if (map->map_coldelim == '\0') - { - if (lmap->ldap_attrsonly == LDAPMAP_TRUE) - { - vp = newstr(attr); - ldap_memfree(attr); - break; - } - - if (vals[0] == NULL) - { - ldap_value_free(vals); - ldap_memfree(attr); - continue; - } - - vsize = strlen(vals[0]) + 1; - if (lmap->ldap_attrsep != '\0') - vsize += strlen(attr) + 1; - vp = xalloc(vsize); - if (lmap->ldap_attrsep != '\0') - sm_snprintf(vp, vsize, - "%s%c%s", - attr, - lmap->ldap_attrsep, - vals[0]); - else - sm_strlcpy(vp, vals[0], vsize); - ldap_value_free(vals); - ldap_memfree(attr); - break; - } - - /* attributes only */ - if (lmap->ldap_attrsonly == LDAPMAP_TRUE) - { - if (vp == NULL) - vp = newstr(attr); - else - { - vsize = strlen(vp) + - strlen(attr) + 2; - tmp = xalloc(vsize); - (void) sm_snprintf(tmp, - vsize, "%s%c%s", - vp, map->map_coldelim, - attr); - sm_free(vp); /* XXX */ - vp = tmp; - } - ldap_memfree(attr); - continue; - } - - /* - ** If there is more than one, - ** munge then into a map_coldelim - ** separated string - */ - - vsize = 0; - for (i = 0; vals[i] != NULL; i++) - { - vsize += strlen(vals[i]) + 1; - if (lmap->ldap_attrsep != '\0') - vsize += strlen(attr) + 1; - } - vp_tmp = xalloc(vsize); - *vp_tmp = '\0'; - - p = vp_tmp; - for (i = 0; vals[i] != NULL; i++) - { - if (lmap->ldap_attrsep != '\0') - { - p += sm_strlcpy(p, attr, - vsize - (p - vp_tmp)); - if (p >= vp_tmp + vsize) - syserr("ldapmap_lookup: Internal error: buffer too small for LDAP values"); - *p++ = lmap->ldap_attrsep; - } - p += sm_strlcpy(p, vals[i], - vsize - (p - vp_tmp)); - if (p >= vp_tmp + vsize) - syserr("ldapmap_lookup: Internal error: buffer too small for LDAP values"); - if (vals[i + 1] != NULL) - *p++ = map->map_coldelim; - } - - ldap_value_free(vals); - ldap_memfree(attr); - if (vp == NULL) - { - vp = vp_tmp; - continue; - } - vsize = strlen(vp) + strlen(vp_tmp) + 2; - tmp = xalloc(vsize); - (void) sm_snprintf(tmp, vsize, "%s%c%s", - vp, map->map_coldelim, vp_tmp); - - sm_free(vp); /* XXX */ - sm_free(vp_tmp); /* XXX */ - vp = tmp; - } - save_errno = sm_ldap_geterrno(lmap->ldap_ld); - - /* - ** We check errno != LDAP_DECODING_ERROR since - ** OpenLDAP 1.X has a very ugly *undocumented* - ** hack of returning this error code from - ** ldap_next_attribute() if the library freed the - ** ber attribute. See: - ** http://www.openldap.org/lists/openldap-devel/9901/msg00064.html - */ - - if (save_errno != LDAP_SUCCESS && - save_errno != LDAP_DECODING_ERROR) - { - /* Must be an error */ - save_errno += E_LDAPBASE; - if (!bitset(MF_OPTIONAL, map->map_mflags)) - { - errno = save_errno; - if (bitset(MF_NODEFER, map->map_mflags)) - syserr("Error getting LDAP attributes in map %s", - map->map_mname); - else - syserr("451 4.3.5 Error getting LDAP attributes in map %s", - map->map_mname); - } - *statp = EX_TEMPFAIL; - if (lmap->ldap_res != NULL) - { - ldap_msgfree(lmap->ldap_res); - lmap->ldap_res = NULL; - } - (void) ldap_abandon(lmap->ldap_ld, msgid); - if (vp != NULL) - sm_free(vp); /* XXX */ - errno = save_errno; - return NULL; - } - - /* We don't want multiple values and we have one */ - if (map->map_coldelim == '\0' && vp != NULL) - break; - } - save_errno = sm_ldap_geterrno(lmap->ldap_ld); - if (save_errno != LDAP_SUCCESS && - save_errno != LDAP_DECODING_ERROR) - { - /* Must be an error */ - save_errno += E_LDAPBASE; - if (!bitset(MF_OPTIONAL, map->map_mflags)) - { - errno = save_errno; - if (bitset(MF_NODEFER, map->map_mflags)) - syserr("Error getting LDAP entries in map %s", - map->map_mname); - else - syserr("451 4.3.5 Error getting LDAP entries in map %s", - map->map_mname); - } - *statp = EX_TEMPFAIL; - if (lmap->ldap_res != NULL) - { - ldap_msgfree(lmap->ldap_res); - lmap->ldap_res = NULL; - } - (void) ldap_abandon(lmap->ldap_ld, msgid); - if (vp != NULL) - sm_free(vp); /* XXX */ - errno = save_errno; - return NULL; - } - ldap_msgfree(lmap->ldap_res); - lmap->ldap_res = NULL; + *statp = EX_TEMPFAIL; + ldapmap_close(map); } - if (ret == 0) - save_errno = ETIMEDOUT; - else - save_errno = sm_ldap_geterrno(lmap->ldap_ld); - if (save_errno != LDAP_SUCCESS) + errno = save_errno; + if (*statp != EX_OK && *statp != EX_NOTFOUND) { - if (ret != 0) - save_errno += E_LDAPBASE; - if (!bitset(MF_OPTIONAL, map->map_mflags)) { - errno = save_errno; if (bitset(MF_NODEFER, map->map_mflags)) syserr("Error getting LDAP results in map %s", map->map_mname); @@ -3929,25 +3584,9 @@ ldapmap_lookup(map, name, av, statp) syserr("451 4.3.5 Error getting LDAP results in map %s", map->map_mname); } - *statp = EX_TEMPFAIL; - if (vp != NULL) - sm_free(vp); /* XXX */ - - switch (save_errno - E_LDAPBASE) - { -# ifdef LDAP_SERVER_DOWN - case LDAP_SERVER_DOWN: -# endif /* LDAP_SERVER_DOWN */ - case LDAP_TIMEOUT: - case LDAP_UNAVAILABLE: - /* server disappeared, try reopen on next search */ - ldapmap_close(map); - break; - } errno = save_errno; return NULL; } -# endif /* _FFR_LDAP_RECURSION */ /* Did we match anything? */ if (vp == NULL && !bitset(MF_MATCHONLY, map->map_mflags)) @@ -3994,23 +3633,24 @@ ldapmap_findconn(lmap) { char *format; char *nbuf; + char *id; STAB *SM_NONVOLATILE s = NULL; -# if _FFR_LDAP_SETVERSION + if (lmap->ldap_host != NULL) + id = lmap->ldap_host; + else if (lmap->ldap_uri != NULL) + id = lmap->ldap_uri; + else + id = "localhost"; + format = "%s%c%d%c%d%c%s%c%s%d"; -# else /* _FFR_LDAP_SETVERSION */ - format = "%s%c%d%c%s%c%s%d"; -# endif /* _FFR_LDAP_SETVERSION */ nbuf = sm_stringf_x(format, - (lmap->ldap_target == NULL ? "localhost" - : lmap->ldap_target), + id, CONDELSE, lmap->ldap_port, CONDELSE, -# if _FFR_LDAP_SETVERSION lmap->ldap_version, CONDELSE, -# endif /* _FFR_LDAP_SETVERSION */ (lmap->ldap_binddn == NULL ? "" : lmap->ldap_binddn), CONDELSE, @@ -4061,9 +3701,7 @@ ldapmap_parseargs(map, args) char *args; { bool secretread = true; -# if _FFR_LDAP_URI - bool ldaphost = false; -# endif /* _FFR_LDAP_URI */ + bool attrssetup = false; int i; register char *p = args; SM_LDAP_STRUCT *lmap; @@ -4132,8 +3770,22 @@ ldapmap_parseargs(map, args) /* default args for an alias LDAP entry */ lmap->ldap_filter = ldapfilt; - lmap->ldap_attr[0] = "sendmailMTAAliasValue"; - lmap->ldap_attr[1] = NULL; + lmap->ldap_attr[0] = "objectClass"; + lmap->ldap_attr_type[0] = SM_LDAP_ATTR_OBJCLASS; + lmap->ldap_attr_needobjclass[0] = NULL; + lmap->ldap_attr[1] = "sendmailMTAAliasValue"; + lmap->ldap_attr_type[1] = SM_LDAP_ATTR_NORMAL; + lmap->ldap_attr_needobjclass[1] = NULL; + lmap->ldap_attr[2] = "sendmailMTAAliasSearch"; + lmap->ldap_attr_type[2] = SM_LDAP_ATTR_FILTER; + lmap->ldap_attr_needobjclass[2] = "sendmailMTAMapObject"; + lmap->ldap_attr[3] = "sendmailMTAAliasURL"; + lmap->ldap_attr_type[3] = SM_LDAP_ATTR_URL; + lmap->ldap_attr_needobjclass[3] = "sendmailMTAMapObject"; + lmap->ldap_attr[4] = NULL; + lmap->ldap_attr_type[4] = SM_LDAP_ATTR_NONE; + lmap->ldap_attr_needobjclass[4] = NULL; + attrssetup = true; } } else if (bitset(MF_FILECLASS, map->map_mflags)) @@ -4345,16 +3997,13 @@ ldapmap_parseargs(map, args) case 'h': /* ldap host */ while (isascii(*++p) && isspace(*p)) continue; -# if _FFR_LDAP_URI - if (lmap->ldap_uri) + if (lmap->ldap_uri != NULL) { syserr("Can not specify both an LDAP host and an LDAP URI in map %s", map->map_mname); return false; } - ldaphost = true; -# endif /* _FFR_LDAP_URI */ - lmap->ldap_target = p; + lmap->ldap_host = p; break; case 'b': /* search base */ @@ -4436,14 +4085,13 @@ ldapmap_parseargs(map, args) secretread = false; break; -# if _FFR_LDAP_URI case 'H': /* Use LDAP URI */ # if !USE_LDAP_INIT syserr("Must compile with -DUSE_LDAP_INIT to use LDAP URIs (-H) in map %s", map->map_mname); return false; -# else /* !USE_LDAP_INIT */ - if (ldaphost) +# else /* !USE_LDAP_INIT */ + if (lmap->ldap_host != NULL) { syserr("Can not specify both an LDAP host and an LDAP URI in map %s", map->map_mname); @@ -4451,19 +4099,16 @@ ldapmap_parseargs(map, args) } while (isascii(*++p) && isspace(*p)) continue; - lmap->ldap_target = p; - lmap->ldap_uri = true; + lmap->ldap_uri = p; break; # endif /* !USE_LDAP_INIT */ -# endif /* _FFR_LDAP_URI */ -# if _FFR_LDAP_SETVERSION case 'w': /* -w should be for passwd, -P should be for version */ while (isascii(*++p) && isspace(*p)) continue; lmap->ldap_version = atoi(p); -# ifdef LDAP_VERSION_MAX +# ifdef LDAP_VERSION_MAX if (lmap->ldap_version > LDAP_VERSION_MAX) { syserr("LDAP version %d exceeds max of %d in map %s", @@ -4471,8 +4116,8 @@ ldapmap_parseargs(map, args) map->map_mname); return false; } -# endif /* LDAP_VERSION_MAX */ -# ifdef LDAP_VERSION_MIN +# endif /* LDAP_VERSION_MAX */ +# ifdef LDAP_VERSION_MIN if (lmap->ldap_version < LDAP_VERSION_MIN) { syserr("LDAP version %d is lower than min of %d in map %s", @@ -4480,9 +4125,8 @@ ldapmap_parseargs(map, args) map->map_mname); return false; } -# endif /* LDAP_VERSION_MIN */ +# endif /* LDAP_VERSION_MIN */ break; -# endif /* _FFR_LDAP_SETVERSION */ default: syserr("Illegal option %c map %s", *p, map->map_mname); @@ -4517,12 +4161,19 @@ ldapmap_parseargs(map, args) ** and dump it into map->map_dbptr1 */ - if (lmap->ldap_target != NULL && + if (lmap->ldap_host != NULL && (LDAPDefaults == NULL || LDAPDefaults == lmap || - LDAPDefaults->ldap_target != lmap->ldap_target)) - lmap->ldap_target = newstr(ldapmap_dequote(lmap->ldap_target)); - map->map_domain = lmap->ldap_target; + LDAPDefaults->ldap_host != lmap->ldap_host)) + lmap->ldap_host = newstr(ldapmap_dequote(lmap->ldap_host)); + map->map_domain = lmap->ldap_host; + + if (lmap->ldap_uri != NULL && + (LDAPDefaults == NULL || + LDAPDefaults == lmap || + LDAPDefaults->ldap_uri != lmap->ldap_uri)) + lmap->ldap_uri = newstr(ldapmap_dequote(lmap->ldap_uri)); + map->map_domain = lmap->ldap_uri; if (lmap->ldap_binddn != NULL && (LDAPDefaults == NULL || @@ -4649,24 +4300,20 @@ ldapmap_parseargs(map, args) } } - if (lmap->ldap_attr[0] != NULL) + if (!attrssetup && lmap->ldap_attr[0] != NULL) { -# if _FFR_LDAP_RECURSION bool recurse = false; bool normalseen = false; -# endif /* _FFR_LDAP_RECURSION */ i = 0; p = ldapmap_dequote(lmap->ldap_attr[0]); lmap->ldap_attr[0] = NULL; -# if _FFR_LDAP_RECURSION /* Prime the attr list with the objectClass attribute */ lmap->ldap_attr[i] = "objectClass"; lmap->ldap_attr_type[i] = SM_LDAP_ATTR_OBJCLASS; lmap->ldap_attr_needobjclass[i] = NULL; i++; -# endif /* _FFR_LDAP_RECURSION */ while (p != NULL) { @@ -4689,7 +4336,6 @@ ldapmap_parseargs(map, args) } if (*v != '\0') { -# if _FFR_LDAP_RECURSION int j; int use; char *type; @@ -4781,14 +4427,11 @@ ldapmap_parseargs(map, args) lmap->ldap_attr_type[use] = SM_LDAP_ATTR_NORMAL; normalseen = true; } -# else /* _FFR_LDAP_RECURSION */ - lmap->ldap_attr[i] = newstr(v); -# endif /* _FFR_LDAP_RECURSION */ i++; } } lmap->ldap_attr[i] = NULL; -# if _FFR_LDAP_RECURSION + attrssetup = true; if (recurse && !normalseen) { syserr("LDAP recursion requested in %s but no returnable attribute given", @@ -4801,7 +4444,6 @@ ldapmap_parseargs(map, args) map->map_mname); return false; } -# endif /* _FFR_LDAP_RECURSION */ } map->map_db1 = (ARBPTR_T) lmap; return true; @@ -4889,9 +4531,9 @@ static char phmap_id[128]; /* sendmail version for phmap id string */ extern const char Version[]; -/* assume we're using nph-1.1.x if not specified */ +/* assume we're using nph-1.2.x if not specified */ # ifndef NPH_VERSION -# define NPH_VERSION 10100 +# define NPH_VERSION 10200 # endif /* compatibility for versions older than nph-1.2.0 */ @@ -5000,12 +4642,6 @@ ph_map_parseargs(map, args) pmap->ph_servers = p; break; - case 'v': - sm_syslog(LOG_WARNING, NULL, - "ph_map_parseargs: WARNING: -v option will be removed in a future release - please use -k instead"); - /* intentional fallthrough for backward compatibility */ - /* FALLTHROUGH */ - case 'k': /* fields to search for */ while (isascii(*++p) && isspace(*p)) continue; @@ -7399,3 +7035,638 @@ arith_map_lookup(map, name, av, statp) *statp = EX_CONFIG; return NULL; } + +#if SOCKETMAP + +# if NETINET || NETINET6 +# include +# endif /* NETINET || NETINET6 */ + +# define socket_map_next map_stack[0] + +/* +** SOCKET_MAP_OPEN -- open socket table +*/ + +bool +socket_map_open(map, mode) + MAP *map; + int mode; +{ + STAB *s; + int sock = 0; + SOCKADDR_LEN_T addrlen = 0; + int addrno = 0; + int save_errno; + char *p; + char *colon; + char *at; + struct hostent *hp = NULL; + SOCKADDR addr; + + if (tTd(38, 2)) + sm_dprintf("socket_map_open(%s, %s, %d)\n", + map->map_mname, map->map_file, mode); + + mode &= O_ACCMODE; + + /* sendmail doesn't have the ability to write to SOCKET (yet) */ + if (mode != O_RDONLY) + { + /* issue a pseudo-error message */ + errno = SM_EMAPCANTWRITE; + return false; + } + + if (*map->map_file == '\0') + { + syserr("socket map \"%s\": empty or missing socket information", + map->map_mname); + return false; + } + + s = socket_map_findconn(map->map_file); + if (s->s_socketmap != NULL) + { + /* Copy open connection */ + map->map_db1 = s->s_socketmap->map_db1; + + /* Add this map as head of linked list */ + map->socket_map_next = s->s_socketmap; + s->s_socketmap = map; + + if (tTd(38, 2)) + sm_dprintf("using cached connection\n"); + return true; + } + + if (tTd(38, 2)) + sm_dprintf("opening new connection\n"); + + /* following code is ripped from milter.c */ + /* XXX It should be put in a library... */ + + /* protocol:filename or protocol:port@host */ + memset(&addr, '\0', sizeof addr); + p = map->map_file; + colon = strchr(p, ':'); + if (colon != NULL) + { + *colon = '\0'; + + if (*p == '\0') + { +# if NETUNIX + /* default to AF_UNIX */ + addr.sa.sa_family = AF_UNIX; +# else /* NETUNIX */ +# if NETINET + /* default to AF_INET */ + addr.sa.sa_family = AF_INET; +# else /* NETINET */ +# if NETINET6 + /* default to AF_INET6 */ + addr.sa.sa_family = AF_INET6; +# else /* NETINET6 */ + /* no protocols available */ + syserr("socket map \"%s\": no valid socket protocols available", + map->map_mname); + return false; +# endif /* NETINET6 */ +# endif /* NETINET */ +# endif /* NETUNIX */ + } +# if NETUNIX + else if (sm_strcasecmp(p, "unix") == 0 || + sm_strcasecmp(p, "local") == 0) + addr.sa.sa_family = AF_UNIX; +# endif /* NETUNIX */ +# if NETINET + else if (sm_strcasecmp(p, "inet") == 0) + addr.sa.sa_family = AF_INET; +# endif /* NETINET */ +# if NETINET6 + else if (sm_strcasecmp(p, "inet6") == 0) + addr.sa.sa_family = AF_INET6; +# endif /* NETINET6 */ + else + { +# ifdef EPROTONOSUPPORT + errno = EPROTONOSUPPORT; +# else /* EPROTONOSUPPORT */ + errno = EINVAL; +# endif /* EPROTONOSUPPORT */ + syserr("socket map \"%s\": unknown socket type %s", + map->map_mname, p); + return false; + } + *colon++ = ':'; + } + else + { + colon = p; +#if NETUNIX + /* default to AF_UNIX */ + addr.sa.sa_family = AF_UNIX; +#else /* NETUNIX */ +# if NETINET + /* default to AF_INET */ + addr.sa.sa_family = AF_INET; +# else /* NETINET */ +# if NETINET6 + /* default to AF_INET6 */ + addr.sa.sa_family = AF_INET6; +# else /* NETINET6 */ + syserr("socket map \"%s\": unknown socket type %s", + map->map_mname, p); + return false; +# endif /* NETINET6 */ +# endif /* NETINET */ +#endif /* NETUNIX */ + } + +# if NETUNIX + if (addr.sa.sa_family == AF_UNIX) + { + long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; + + at = colon; + if (strlen(colon) >= sizeof addr.sunix.sun_path) + { + syserr("socket map \"%s\": local socket name %s too long", + map->map_mname, colon); + return false; + } + errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, + S_IRUSR|S_IWUSR, NULL); + + if (errno != 0) + { + /* if not safe, don't create */ + syserr("socket map \"%s\": local socket name %s unsafe", + map->map_mname, colon); + return false; + } + + (void) sm_strlcpy(addr.sunix.sun_path, colon, + sizeof addr.sunix.sun_path); + addrlen = sizeof (struct sockaddr_un); + } + else +# endif /* NETUNIX */ +# if NETINET || NETINET6 + if (false +# if NETINET + || addr.sa.sa_family == AF_INET +# endif /* NETINET */ +# if NETINET6 + || addr.sa.sa_family == AF_INET6 +# endif /* NETINET6 */ + ) + { + unsigned short port; + + /* Parse port@host */ + at = strchr(colon, '@'); + if (at == NULL) + { + syserr("socket map \"%s\": bad address %s (expected port@host)", + map->map_mname, colon); + return false; + } + *at = '\0'; + if (isascii(*colon) && isdigit(*colon)) + port = htons((unsigned short) atoi(colon)); + else + { +# ifdef NO_GETSERVBYNAME + syserr("socket map \"%s\": invalid port number %s", + map->map_mname, colon); + return false; +# else /* NO_GETSERVBYNAME */ + register struct servent *sp; + + sp = getservbyname(colon, "tcp"); + if (sp == NULL) + { + syserr("socket map \"%s\": unknown port name %s", + map->map_mname, colon); + return false; + } + port = sp->s_port; +# endif /* NO_GETSERVBYNAME */ + } + *at++ = '@'; + if (*at == '[') + { + char *end; + + end = strchr(at, ']'); + if (end != NULL) + { + bool found = false; +# if NETINET + unsigned long hid = INADDR_NONE; +# endif /* NETINET */ +# if NETINET6 + struct sockaddr_in6 hid6; +# endif /* NETINET6 */ + + *end = '\0'; +# if NETINET + if (addr.sa.sa_family == AF_INET && + (hid = inet_addr(&at[1])) != INADDR_NONE) + { + addr.sin.sin_addr.s_addr = hid; + addr.sin.sin_port = port; + found = true; + } +# endif /* NETINET */ +# if NETINET6 + (void) memset(&hid6, '\0', sizeof hid6); + if (addr.sa.sa_family == AF_INET6 && + anynet_pton(AF_INET6, &at[1], + &hid6.sin6_addr) == 1) + { + addr.sin6.sin6_addr = hid6.sin6_addr; + addr.sin6.sin6_port = port; + found = true; + } +# endif /* NETINET6 */ + *end = ']'; + if (!found) + { + syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"", + map->map_mname, at); + return false; + } + } + else + { + syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"", + map->map_mname, at); + return false; + } + } + else + { + hp = sm_gethostbyname(at, addr.sa.sa_family); + if (hp == NULL) + { + syserr("socket map \"%s\": Unknown host name %s", + map->map_mname, at); + return false; + } + addr.sa.sa_family = hp->h_addrtype; + switch (hp->h_addrtype) + { +# if NETINET + case AF_INET: + memmove(&addr.sin.sin_addr, + hp->h_addr, INADDRSZ); + addr.sin.sin_port = port; + addrlen = sizeof (struct sockaddr_in); + addrno = 1; + break; +# endif /* NETINET */ + +# if NETINET6 + case AF_INET6: + memmove(&addr.sin6.sin6_addr, + hp->h_addr, IN6ADDRSZ); + addr.sin6.sin6_port = port; + addrlen = sizeof (struct sockaddr_in6); + addrno = 1; + break; +# endif /* NETINET6 */ + + default: + syserr("socket map \"%s\": Unknown protocol for %s (%d)", + map->map_mname, at, hp->h_addrtype); +# if NETINET6 + freehostent(hp); +# endif /* NETINET6 */ + return false; + } + } + } + else +# endif /* NETINET || NETINET6 */ + { + syserr("socket map \"%s\": unknown socket protocol", + map->map_mname); + return false; + } + + /* nope, actually connecting */ + for (;;) + { + sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); + if (sock < 0) + { + save_errno = errno; + if (tTd(38, 5)) + sm_dprintf("socket map \"%s\": error creating socket: %s\n", + map->map_mname, + sm_errstring(save_errno)); +# if NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* NETINET6 */ + return false; + } + + if (connect(sock, (struct sockaddr *) &addr, addrlen) >= 0) + break; + + /* couldn't connect.... try next address */ + save_errno = errno; + p = CurHostName; + CurHostName = at; + if (tTd(38, 5)) + sm_dprintf("socket_open (%s): open %s failed: %s\n", + map->map_mname, at, sm_errstring(save_errno)); + CurHostName = p; + (void) close(sock); + + /* try next address */ + if (hp != NULL && hp->h_addr_list[addrno] != NULL) + { + switch (addr.sa.sa_family) + { +# if NETINET + case AF_INET: + memmove(&addr.sin.sin_addr, + hp->h_addr_list[addrno++], + INADDRSZ); + break; +# endif /* NETINET */ + +# if NETINET6 + case AF_INET6: + memmove(&addr.sin6.sin6_addr, + hp->h_addr_list[addrno++], + IN6ADDRSZ); + break; +# endif /* NETINET6 */ + + default: + if (tTd(38, 5)) + sm_dprintf("socket map \"%s\": Unknown protocol for %s (%d)\n", + map->map_mname, at, + hp->h_addrtype); +# if NETINET6 + freehostent(hp); +# endif /* NETINET6 */ + return false; + } + continue; + } + p = CurHostName; + CurHostName = at; + if (tTd(38, 5)) + sm_dprintf("socket map \"%s\": error connecting to socket map: %s\n", + map->map_mname, sm_errstring(save_errno)); + CurHostName = p; +# if NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* NETINET6 */ + return false; + } +# if NETINET6 + if (hp != NULL) + { + freehostent(hp); + hp = NULL; + } +# endif /* NETINET6 */ + if ((map->map_db1 = (ARBPTR_T) sm_io_open(SmFtStdiofd, + SM_TIME_DEFAULT, + (void *) &sock, + SM_IO_RDWR, + NULL)) == NULL) + { + close(sock); + if (tTd(38, 2)) + sm_dprintf("socket_open (%s): failed to create stream: %s\n", + map->map_mname, sm_errstring(errno)); + return false; + } + + /* Save connection for reuse */ + s->s_socketmap = map; + return true; +} + +/* +** SOCKET_MAP_FINDCONN -- find a SOCKET connection to the server +** +** Cache SOCKET connections based on the connection specifier +** and PID so we don't have multiple connections open to +** the same server for different maps. Need a separate connection +** per PID since a parent process may close the map before the +** child is done with it. +** +** Parameters: +** conn -- SOCKET map connection specifier +** +** Returns: +** Symbol table entry for the SOCKET connection. +*/ + +static STAB * +socket_map_findconn(conn) + const char *conn; +{ + char *nbuf; + STAB *SM_NONVOLATILE s = NULL; + + nbuf = sm_stringf_x("%s%c%d", conn, CONDELSE, (int) CurrentPid); + SM_TRY + s = stab(nbuf, ST_SOCKETMAP, ST_ENTER); + SM_FINALLY + sm_free(nbuf); + SM_END_TRY + return s; +} + +/* +** SOCKET_MAP_CLOSE -- close the socket +*/ + +void +socket_map_close(map) + MAP *map; +{ + STAB *s; + MAP *smap; + + if (tTd(38, 20)) + sm_dprintf("socket_map_close(%s), pid=%ld\n", map->map_file, + (long) CurrentPid); + + /* Check if already closed */ + if (map->map_db1 == NULL) + { + if (tTd(38, 20)) + sm_dprintf("socket_map_close(%s) already closed\n", + map->map_file); + return; + } + sm_io_close((SM_FILE_T *)map->map_db1, SM_TIME_DEFAULT); + + /* Mark all the maps that share the connection as closed */ + s = socket_map_findconn(map->map_file); + smap = s->s_socketmap; + while (smap != NULL) + { + MAP *next; + + if (tTd(38, 2) && smap != map) + sm_dprintf("socket_map_close(%s): closed %s (shared SOCKET connection)\n", + map->map_mname, smap->map_mname); + + smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE); + smap->map_db1 = NULL; + next = smap->socket_map_next; + smap->socket_map_next = NULL; + smap = next; + } + s->s_socketmap = NULL; +} + +/* +** SOCKET_MAP_LOOKUP -- look up a datum in a SOCKET table +*/ + +char * +socket_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; +{ + unsigned int nettolen, replylen, recvlen; + char *replybuf, *rval, *value, *status; + SM_FILE_T *f; + + replybuf = NULL; + rval = NULL; + f = (SM_FILE_T *)map->map_db1; + if (tTd(38, 20)) + sm_dprintf("socket_map_lookup(%s, %s) %s\n", + map->map_mname, name, map->map_file); + + nettolen = strlen(map->map_mname) + 1 + strlen(name); + SM_ASSERT(nettolen > strlen(map->map_mname)); + SM_ASSERT(nettolen > strlen(name)); + if ((sm_io_fprintf(f, SM_TIME_DEFAULT, "%u:%s %s,", + nettolen, map->map_mname, name) == SM_IO_EOF) || + (sm_io_flush(f, SM_TIME_DEFAULT) != 0) || + (sm_io_error(f))) + { + syserr("451 4.3.0 socket_map_lookup(%s): failed to send lookup request", + map->map_mname); + *statp = EX_TEMPFAIL; + goto errcl; + } + + if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1) + { + syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply", + map->map_mname); + *statp = EX_TEMPFAIL; + goto errcl; + } + if (replylen > SOCKETMAP_MAXL) + { + syserr("451 4.3.0 socket_map_lookup(%s): reply too long: %u", + map->map_mname, replylen); + *statp = EX_TEMPFAIL; + goto errcl; + } + if (sm_io_getc(f, SM_TIME_DEFAULT) != ':') + { + syserr("451 4.3.0 socket_map_lookup(%s): missing ':' in reply", + map->map_mname); + *statp = EX_TEMPFAIL; + goto error; + } + + replybuf = (char *) sm_malloc(replylen + 1); + if (replybuf == NULL) + { + syserr("451 4.3.0 socket_map_lookup(%s): can't allocate %u bytes", + map->map_mname, replylen + 1); + *statp = EX_OSERR; + goto error; + } + + recvlen = sm_io_read(f, SM_TIME_DEFAULT, replybuf, replylen); + if (recvlen < replylen) + { + syserr("451 4.3.0 socket_map_lookup(%s): received only %u of %u reply characters", + map->map_mname, recvlen, replylen); + *statp = EX_TEMPFAIL; + goto errcl; + } + if (sm_io_getc(f, SM_TIME_DEFAULT) != ',') + { + syserr("451 4.3.0 socket_map_lookup(%s): missing ',' in reply", + map->map_mname); + *statp = EX_TEMPFAIL; + goto errcl; + } + status = replybuf; + replybuf[recvlen] = '\0'; + value = strchr(replybuf, ' '); + if (value != NULL) + { + *value = '\0'; + value++; + } + if (strcmp(status, "OK") == 0) + { + *statp = EX_OK; + + /* collect the return value */ + if (bitset(MF_MATCHONLY, map->map_mflags)) + rval = map_rewrite(map, name, strlen(name), NULL); + else + rval = map_rewrite(map, value, strlen(value), av); + } + else if (strcmp(status, "NOTFOUND") == 0) + { + *statp = EX_NOTFOUND; + if (tTd(38, 20)) + sm_dprintf("socket_map_lookup(%s): %s not found\n", + map->map_mname, name); + } + else + { + if (tTd(38, 5)) + sm_dprintf("socket_map_lookup(%s, %s): server returned error: type=%s, reason=%s\n", + map->map_mname, name, status, + value ? value : ""); + if ((strcmp(status, "TEMP") == 0) || + (strcmp(status, "TIMEOUT") == 0)) + *statp = EX_TEMPFAIL; + else if(strcmp(status, "PERM") == 0) + *statp = EX_UNAVAILABLE; + else + *statp = EX_PROTOCOL; + } + + if (replybuf != NULL) + sm_free(replybuf); + return rval; + + errcl: + socket_map_close(map); + error: + if (replybuf != NULL) + sm_free(replybuf); + return rval; +} +#endif /* SOCKETMAP */ diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c index c25101c24562..b89fac093df7 100644 --- a/contrib/sendmail/src/milter.c +++ b/contrib/sendmail/src/milter.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: milter.c,v 8.197.2.10 2003/12/01 23:57:44 msk Exp $") +SM_RCSID("@(#)$Id: milter.c,v 8.225 2004/07/08 21:52:20 ca Exp $") #if MILTER # include @@ -18,9 +18,13 @@ SM_RCSID("@(#)$Id: milter.c,v 8.197.2.10 2003/12/01 23:57:44 msk Exp $") # include # include +# include # if NETINET || NETINET6 # include +# if _FFR_MILTER_NAGLE +# include +# endif /* _FFR_MILTER_NAGLE */ # endif /* NETINET || NETINET6 */ # include @@ -34,9 +38,9 @@ static char *MilterConnectMacros[MAXFILTERMACROS + 1]; static char *MilterHeloMacros[MAXFILTERMACROS + 1]; static char *MilterEnvFromMacros[MAXFILTERMACROS + 1]; static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; -#if _FFR_MILTER_MACROS_EOM +static char *MilterDataMacros[MAXFILTERMACROS + 1]; static char *MilterEOMMacros[MAXFILTERMACROS + 1]; -#endif /* _FFR_MILTER_MACROS_EOM */ +static size_t MilterMaxDataSize = MILTER_MAX_DATA_SIZE; # define MILTER_CHECK_DONE_MSG() \ if (*state == SMFIR_REPLYCODE || \ @@ -48,8 +52,7 @@ static char *MilterEOMMacros[MAXFILTERMACROS + 1]; milter_abort(e); \ } -# if _FFR_QUARANTINE -# define MILTER_CHECK_ERROR(initial, action) \ +# define MILTER_CHECK_ERROR(initial, action) \ if (!initial && tTd(71, 100)) \ { \ if (e->e_quarmsg == NULL) \ @@ -76,15 +79,6 @@ static char *MilterEOMMacros[MAXFILTERMACROS + 1]; *state = SMFIR_REJECT; \ else \ action; -# else /* _FFR_QUARANTINE */ -# define MILTER_CHECK_ERROR(initial, action) \ - if (bitnset(SMF_TEMPFAIL, m->mf_flags)) \ - *state = SMFIR_TEMPFAIL; \ - else if (bitnset(SMF_REJECT, m->mf_flags)) \ - *state = SMFIR_REJECT; \ - else \ - action; -# endif /* _FFR_QUARANTINE */ # define MILTER_CHECK_REPLYCODE(default) \ if (response == NULL || \ @@ -346,6 +340,11 @@ milter_read(m, cmd, rlen, to, e) time_t readstart = 0; ssize_t expl; mi_int32 i; +# if _FFR_MILTER_NAGLE +# ifdef TCP_CORK + int cork = 0; +# endif +# endif /* _FFR_MILTER_NAGLE */ char *buf; char data[MILTER_LEN_BYTES + 1]; @@ -355,9 +354,24 @@ milter_read(m, cmd, rlen, to, e) if (to > 0) readstart = curtime(); +# if _FFR_MILTER_NAGLE +# ifdef TCP_CORK + setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork, + sizeof(cork)); +# endif +# endif /* _FFR_MILTER_NAGLE */ + if (milter_sysread(m, data, sizeof data, to, e) == NULL) return NULL; +# if _FFR_MILTER_NAGLE +# ifdef TCP_CORK + cork = 1; + setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork, + sizeof(cork)); +# endif +# endif /* _FFR_MILTER_NAGLE */ + /* reset timeout */ if (to > 0) { @@ -418,6 +432,7 @@ milter_read(m, cmd, rlen, to, e) *rlen = expl; return buf; } + /* ** MILTER_WRITE -- write to a remote milter filter ** @@ -446,11 +461,19 @@ milter_write(m, cmd, buf, len, to, e) { time_t writestart = (time_t) 0; ssize_t sl, i; + int num_vectors; mi_int32 nl; char data[MILTER_LEN_BYTES + 1]; bool started = false; + struct iovec vector[2]; - if (len < 0 || len > MILTER_CHUNK_SIZE) + /* + ** At most two buffers will be written, though + ** only one may actually be used (see num_vectors). + ** The first is the size/command and the second is the command data. + */ + + if (len < 0 || len > MilterMaxDataSize) { if (tTd(64, 5)) sm_dprintf("milter_write(%s): length %ld out of range\n", @@ -472,68 +495,51 @@ milter_write(m, cmd, buf, len, to, e) data[MILTER_LEN_BYTES] = cmd; sl = MILTER_LEN_BYTES + 1; + /* set up the vector for the size / command */ + vector[0].iov_base = (void *) data; + vector[0].iov_len = sl; + + /* + ** Determine if there is command data. If so, there will be two + ** vectors. If not, there will be only one. The vectors are set + ** up here and 'num_vectors' and 'sl' are set appropriately. + */ + + /* NOTE: len<0 has already been checked for. Pedantic */ + if (len <= 0 || buf == NULL) + { + /* There is no command data -- only a size / command data */ + num_vectors = 1; + } + else + { + /* + ** There is both size / command and command data. + ** Set up the vector for the command data. + */ + + num_vectors = 2; + sl += len; + vector[1].iov_base = (void *) buf; + vector[1].iov_len = len; + + if (tTd(64, 50)) + sm_dprintf("milter_write(%s): Sending %*s\n", + m->mf_name, (int) len, buf); + } + if (to > 0) { writestart = curtime(); MILTER_TIMEOUT("write", to, true, started); } - /* use writev() instead to send the whole stuff at once? */ - i = write(m->mf_sock, (void *) data, sl); + /* write the vector(s) */ + i = writev(m->mf_sock, vector, num_vectors); if (i != sl) { int save_errno = errno; - if (tTd(64, 5)) - sm_dprintf("milter_write (%s): write(%c) returned %ld, expected %ld: %s\n", - m->mf_name, cmd, (long) i, (long) sl, - sm_errstring(save_errno)); - if (MilterLogLevel > 0) - sm_syslog(LOG_ERR, e->e_id, - "Milter (%s): write(%c) returned %ld, expected %ld: %s", - m->mf_name, cmd, (long) i, (long) sl, - sm_errstring(save_errno)); - milter_error(m, e); - return buf; - } - - if (len <= 0 || buf == NULL) - return buf; - - if (tTd(64, 50)) - sm_dprintf("milter_write(%s): Sending %*s\n", - m->mf_name, (int) len, buf); - started = true; - - if (to > 0) - { - time_t now; - - now = curtime(); - if (now - writestart >= to) - { - if (tTd(64, 5)) - sm_dprintf("milter_write(%s): timeout before data write\n", - m->mf_name); - if (MilterLogLevel > 0) - sm_syslog(LOG_ERR, e->e_id, - "Milter (%s): timeout before data write", - m->mf_name); - milter_error(m, e); - return NULL; - } - else - { - to -= now - writestart; - MILTER_TIMEOUT("write", to, true, started); - } - } - - i = write(m->mf_sock, (void *) buf, len); - if (i != len) - { - int save_errno = errno; - if (tTd(64, 5)) sm_dprintf("milter_write(%s): write(%c) returned %ld, expected %ld: %s\n", m->mf_name, cmd, (long) i, (long) sl, @@ -541,7 +547,7 @@ milter_write(m, cmd, buf, len, to, e) if (MilterLogLevel > 0) sm_syslog(LOG_ERR, e->e_id, "Milter (%s): write(%c) returned %ld, expected %ld: %s", - m->mf_name, cmd, (long) i, (long) len, + m->mf_name, cmd, (long) i, (long) sl, sm_errstring(save_errno)); milter_error(m, e); return NULL; @@ -1107,6 +1113,16 @@ milter_open(m, parseonly, e) hp = NULL; } # endif /* NETINET6 */ +# if _FFR_MILTER_NAGLE +# ifndef TCP_CORK + { + int nodelay = 1; + + setsockopt(m->mf_sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&nodelay, sizeof(nodelay)); + } +# endif /* TCP_CORK */ +# endif /* _FFR_MILTER_NAGLE */ return sock; } @@ -1270,11 +1286,7 @@ milter_config(spec, list, max) list[0] = NULL; return; } -#if _FFR_MILTER_PERDAEMON p = strpbrk(p, ";,"); -#else /* _FFR_MILTER_PERDAEMON */ - p = strpbrk(p, ","); -#endif /* _FFR_MILTER_PERDAEMON */ if (p != NULL) *p++ = '\0'; @@ -1312,6 +1324,7 @@ milter_parse_timeouts(spec, m) struct milter *m; { char fcode; + int tcode; register char *p; p = spec; @@ -1339,40 +1352,25 @@ milter_parse_timeouts(spec, m) /* p now points to the field body */ p = munchstring(p, &delimptr, ';'); + tcode = -1; /* install the field into the filter struct */ switch (fcode) { case 'C': - m->mf_timeout[SMFTO_CONNECT] = convtime(p, 's'); - if (tTd(64, 5)) - sm_dprintf("X%s: %c=%lu\n", - m->mf_name, fcode, - (unsigned long) m->mf_timeout[SMFTO_CONNECT]); + tcode = SMFTO_CONNECT; break; case 'S': - m->mf_timeout[SMFTO_WRITE] = convtime(p, 's'); - if (tTd(64, 5)) - sm_dprintf("X%s: %c=%lu\n", - m->mf_name, fcode, - (unsigned long) m->mf_timeout[SMFTO_WRITE]); + tcode = SMFTO_WRITE; break; case 'R': - m->mf_timeout[SMFTO_READ] = convtime(p, 's'); - if (tTd(64, 5)) - sm_dprintf("X%s: %c=%lu\n", - m->mf_name, fcode, - (unsigned long) m->mf_timeout[SMFTO_READ]); + tcode = SMFTO_READ; break; case 'E': - m->mf_timeout[SMFTO_EOM] = convtime(p, 's'); - if (tTd(64, 5)) - sm_dprintf("X%s: %c=%lu\n", - m->mf_name, fcode, - (unsigned long) m->mf_timeout[SMFTO_EOM]); + tcode = SMFTO_EOM; break; default: @@ -1383,6 +1381,14 @@ milter_parse_timeouts(spec, m) m->mf_name, fcode); break; } + if (tcode >= 0) + { + m->mf_timeout[tcode] = convtime(p, 's'); + if (tTd(64, 5)) + sm_dprintf("X%s: %c=%ld\n", + m->mf_name, fcode, + (u_long) m->mf_timeout[tcode]); + } p = delimptr; } } @@ -1416,12 +1422,16 @@ static struct milteropt { "macros.envfrom", MO_MACROS_ENVFROM }, # define MO_MACROS_ENVRCPT 0x04 { "macros.envrcpt", MO_MACROS_ENVRCPT }, -# define MO_LOGLEVEL 0x05 - { "loglevel", MO_LOGLEVEL }, -#if _FFR_MILTER_MACROS_EOM +# define MO_MACROS_DATA 0x05 + { "macros.data", MO_MACROS_DATA }, # define MO_MACROS_EOM 0x06 { "macros.eom", MO_MACROS_EOM }, -#endif /* _FFR_MILTER_MACROS_EOM */ +# define MO_LOGLEVEL 0x07 + { "loglevel", MO_LOGLEVEL }, +# if _FFR_MAXDATASIZE +# define MO_MAXDATASIZE 0x08 + { "maxdatasize", MO_MAXDATASIZE }, +# endif /* _FFR_MAXDATASIZE */ { NULL, 0 }, }; @@ -1477,6 +1487,12 @@ milter_set_option(name, val, sticky) MilterLogLevel = atoi(val); break; +#if _FFR_MAXDATASIZE + case MO_MAXDATASIZE: + MilterMaxDataSize = (size_t)atol(val); + break; +#endif /* _FFR_MAXDATASIZE */ + case MO_MACROS_CONNECT: if (macros == NULL) macros = MilterConnectMacros; @@ -1495,13 +1511,16 @@ milter_set_option(name, val, sticky) case MO_MACROS_ENVRCPT: if (macros == NULL) macros = MilterEnvRcptMacros; -#if _FFR_MILTER_MACROS_EOM /* FALLTHROUGH */ case MO_MACROS_EOM: if (macros == NULL) macros = MilterEOMMacros; -#endif /* _FFR_MILTER_MACROS_EOM */ + /* FALLTHROUGH */ + + case MO_MACROS_DATA: + if (macros == NULL) + macros = MilterDataMacros; p = newstr(val); while (*p != '\0') @@ -1567,9 +1586,8 @@ milter_reopen_df(e) ** read only again). ** ** In SuperSafe != SAFE_REALLY mode, e->e_dfp still points at the - ** buffered file I/O descriptor, still open for writing - ** so there isn't as much work to do, just truncate it - ** and go. + ** buffered file I/O descriptor, still open for writing so there + ** isn't any work to do here (except checking for consistency). */ if (SuperSafe == SAFE_REALLY) @@ -1861,6 +1879,9 @@ milter_send_command(m, command, data, sz, e, state) char rcmd; ssize_t rlen; unsigned long skipflag; +#if _FFR_MILTER_NOHDR_RESP + unsigned long norespflag = 0; +#endif /* _FFR_MILTER_NOHDR_RESP */ char *action; char *defresponse; char *response; @@ -1898,6 +1919,9 @@ milter_send_command(m, command, data, sz, e, state) case SMFIC_HEADER: skipflag = SMFIP_NOHDRS; +#if _FFR_MILTER_NOHDR_RESP + norespflag = SMFIP_NOHREPL; +#endif /* _FFR_MILTER_NOHDR_RESP */ action = "header"; defresponse = "550 5.7.1 Command rejected"; break; @@ -1914,6 +1938,13 @@ milter_send_command(m, command, data, sz, e, state) defresponse = "550 5.7.1 Command rejected"; break; +#if SMFI_VERSION > 2 + case SMFIC_UNKNOWN: + action = "unknown"; + defresponse = "550 5.7.1 Command rejected"; + break; +#endif /* SMFI_VERSION > 2 */ + case SMFIC_BODYEOB: case SMFIC_OPTNEG: case SMFIC_MACRO: @@ -1943,6 +1974,12 @@ milter_send_command(m, command, data, sz, e, state) return NULL; } +#if _FFR_MILTER_NOHDR_RESP + /* check if filter sends response to this command */ + if (norespflag != 0 && bitset(norespflag, m->mf_pflags)) + return NULL; +#endif /* _FFR_MILTER_NOHDR_RESP */ + /* get the response from the filter */ response = milter_read(m, &rcmd, &rlen, m->mf_timeout[SMFTO_READ], e); @@ -2364,7 +2401,7 @@ milter_headers(m, e, state) /* don't send over deleted headers */ if (h->h_value == NULL) { - /* strip H_USER so not counted in milter_chgheader() */ + /* strip H_USER so not counted in milter_changeheader() */ h->h_flags &= ~H_USER; continue; } @@ -2621,6 +2658,84 @@ milter_addheader(response, rlen, e) } } /* +** MILTER_INSHEADER -- Insert the supplied header +** +** Parameters: +** response -- encoded form of header/value. +** rlen -- length of response. +** e -- current envelope. +** +** Returns: +** none +** +** Notes: +** Unlike milter_addheader(), this does not attempt to determine +** if the header already exists in the envelope, even a +** deleted version. It just blindly inserts. +*/ + +static void +milter_insheader(response, rlen, e) + char *response; + ssize_t rlen; + ENVELOPE *e; +{ + mi_int32 idx, i; + char *field; + char *val; + + if (tTd(64, 10)) + sm_dprintf("milter_insheader: "); + + /* sanity checks */ + if (response == NULL) + { + if (tTd(64, 10)) + sm_dprintf("NULL response\n"); + return; + } + + if (rlen < 2 || strlen(response) + 1 >= (size_t) rlen) + { + if (tTd(64, 10)) + sm_dprintf("didn't follow protocol (total len)\n"); + return; + } + + /* decode */ + (void) memcpy((char *) &i, response, MILTER_LEN_BYTES); + idx = ntohl(i); + field = response + MILTER_LEN_BYTES; + val = field + strlen(field) + 1; + + /* another sanity check */ + if (MILTER_LEN_BYTES + strlen(field) + 1 + + strlen(val) + 1 != (size_t) rlen) + { + if (tTd(64, 10)) + sm_dprintf("didn't follow protocol (part len)\n"); + return; + } + + if (*field == '\0') + { + if (tTd(64, 10)) + sm_dprintf("empty field name\n"); + return; + } + + /* add to e_msgsize */ + e->e_msgsize += strlen(response) + 2 + strlen(val); + + if (tTd(64, 10)) + sm_dprintf("Insert (%d) %s: %s\n", idx, response, val); + if (MilterLogLevel > 8) + sm_syslog(LOG_INFO, e->e_id, + "Milter insert (%d): header: %s: %s", + idx, field, val); + insheader(idx, newstr(field), val, H_USER, e); +} +/* ** MILTER_CHANGEHEADER -- Change the supplied header in the message ** ** Parameters: @@ -2753,7 +2868,7 @@ milter_changeheader(response, rlen, e) if (*val == '\0') { sm_syslog(LOG_INFO, e->e_id, - "Milter delete: header %s %s: %s", + "Milter delete: header%s %s: %s", h == sysheader ? " (default header)" : "", field, h->h_value == NULL ? "" : h->h_value); @@ -2761,7 +2876,7 @@ milter_changeheader(response, rlen, e) else { sm_syslog(LOG_INFO, e->e_id, - "Milter change: header %s %s: from %s to %s", + "Milter change: header%s %s: from %s to %s", h == sysheader ? " (default header)" : "", field, h->h_value == NULL ? "" : h->h_value, @@ -2848,8 +2963,8 @@ milter_addrcpt(response, rlen, e) if (MilterLogLevel > 8) sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response); olderrors = Errors; - (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); - Errors = olderrors; + (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); + Errors = olderrors; return; } /* @@ -3113,6 +3228,7 @@ milter_init(e, state) /* if negotation failure, close socket */ milter_error(m, e); MILTER_CHECK_ERROR(true, continue); + continue; } if (MilterLogLevel > 9) sm_syslog(LOG_INFO, e->e_id, @@ -3256,11 +3372,9 @@ milter_connect(hostname, addr, e, state) if (response != NULL && *response == '4') { -#if _FFR_MILTER_421 if (strncmp(response, "421 ", 4) == 0) *state = SMFIR_SHUTDOWN; else -#endif /* _FFR_MILTER_421 */ *state = SMFIR_TEMPFAIL; } else @@ -3419,6 +3533,7 @@ milter_envfrom(args, e, state) sm_syslog(LOG_INFO, e->e_id, "Milter: reject, senders"); return response; } + /* ** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters ** @@ -3487,6 +3602,32 @@ milter_envrcpt(args, e, state) sm_free(buf); /* XXX */ return response; } + +#if SMFI_VERSION > 3 +/* +** MILTER_DATA_CMD -- send SMTP DATA command info to milter filters +** +** Parameters: +** e -- current envelope. +** state -- return state from response. +** +** Returns: +** response string (may be NULL) +*/ + +char * +milter_data_cmd(e, state) + ENVELOPE *e; + char *state; +{ + if (tTd(64, 10)) + sm_dprintf("milter_data_cmd\n"); + + /* send it over */ + return milter_command(SMFIC_DATA, NULL, 0, MilterDataMacros, e, state); +} +#endif /* SMFI_VERSION > 3 */ + /* ** MILTER_DATA -- send message headers/body and gather final message results ** @@ -3608,10 +3749,9 @@ milter_data(e, state) MILTER_CHECK_RESULTS(); } -#if _FFR_MILTER_MACROS_EOM if (MilterEOMMacros[0] != NULL) - milter_send_macros(m, MilterEOMMacros, SMFIC_BODYEOB, e); -#endif /* _FFR_MILTER_MACROS_EOM */ + milter_send_macros(m, MilterEOMMacros, + SMFIC_BODYEOB, e); /* send the final body chunk */ (void) milter_write(m, SMFIC_BODYEOB, NULL, 0, @@ -3696,7 +3836,6 @@ milter_data(e, state) case SMFIR_PROGRESS: break; -# if _FFR_QUARANTINE case SMFIR_QUARANTINE: if (!bitset(SMFIF_QUARANTINE, m->mf_fflags)) { @@ -3716,7 +3855,6 @@ milter_data(e, state) macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), e->e_quarmsg); break; -# endif /* _FFR_QUARANTINE */ case SMFIR_ADDHEADER: if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) @@ -3729,6 +3867,17 @@ milter_data(e, state) milter_addheader(response, rlen, e); break; + case SMFIR_INSHEADER: + if (!bitset(SMFIF_ADDHDRS, m->mf_fflags)) + { + if (MilterLogLevel > 9) + sm_syslog(LOG_WARNING, e->e_id, + "milter_data(%s): lied about adding headers, honoring request anyway", + m->mf_name); + } + milter_insheader(response, rlen, e); + break; + case SMFIR_CHGHEADER: if (!bitset(SMFIF_CHGHDRS, m->mf_fflags)) { @@ -3765,7 +3914,7 @@ milter_data(e, state) case SMFIR_REPLBODY: if (!bitset(SMFIF_MODBODY, m->mf_fflags)) { - if (MilterLogLevel > 9) + if (MilterLogLevel > 0) sm_syslog(LOG_ERR, e->e_id, "milter_data(%s): lied about replacing body, rejecting request and tempfailing message", m->mf_name); @@ -3878,6 +4027,36 @@ milter_data(e, state) sm_syslog(LOG_INFO, e->e_id, "Milter: reject, data"); return response; } + +#if SMFI_VERSION > 2 +/* +** MILTER_UNKNOWN -- send any unrecognized or unimplemented command +** string to milter filters +** +** Parameters: +** cmd -- the string itself. +** e -- current envelope. +** state -- return state from response. +** +** +** Returns: +** response string (may be NULL) +*/ + +char * +milter_unknown(cmd, e, state) + char *cmd; + ENVELOPE *e; + char *state; +{ + if (tTd(64, 10)) + sm_dprintf("milter_unknown(%s)\n", cmd); + + return milter_command(SMFIC_UNKNOWN, cmd, strlen(cmd) + 1, + NULL, e, state); +} +#endif /* SMFI_VERSION > 2 */ + /* ** MILTER_QUIT -- informs the filter(s) we are done and closes connection(s) ** diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c index a9a26c4f4a51..6f4e78231b72 100644 --- a/contrib/sendmail/src/mime.c +++ b/contrib/sendmail/src/mime.c @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: mime.c,v 8.130.2.3 2004/01/08 21:42:56 ca Exp $") +SM_RCSID("@(#)$Id: mime.c,v 8.136 2004/03/22 18:21:34 ca Exp $") /* ** MIME support. @@ -137,7 +137,7 @@ mime8to7(mci, header, e, boundaries, flags) p = hvalue("Content-Transfer-Encoding", header); if (p == NULL || (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, - MimeTokenTab)) == NULL || + MimeTokenTab, false)) == NULL || pvp[0] == NULL) { cte = NULL; @@ -159,7 +159,7 @@ mime8to7(mci, header, e, boundaries, flags) } if (p != NULL && (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, - MimeTokenTab)) != NULL && + MimeTokenTab, false)) != NULL && pvp[0] != NULL) { if (tTd(43, 40)) @@ -768,11 +768,11 @@ mime_getchar(fp, boundaries, btp) return SM_IO_EOF; } - atbol = c == '\n'; - if (c != SM_IO_EOF) + if (bp < &buf[sizeof buf - 2] && c != SM_IO_EOF) *bp++ = c; } + atbol = c == '\n'; buflen = bp - buf - 1; if (buflen < 0) { @@ -990,7 +990,7 @@ mime7to8(mci, header, e) p = hvalue("Content-Transfer-Encoding", header); if (p == NULL || (pvp = prescan(p, '\0', pvpbuf, sizeof pvpbuf, NULL, - MimeTokenTab)) == NULL || + MimeTokenTab, false)) == NULL || pvp[0] == NULL) { /* "can't happen" -- upper level should have caught this */ diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c index 48ed142dc5df..e1c60c8178ef 100644 --- a/contrib/sendmail/src/parseaddr.c +++ b/contrib/sendmail/src/parseaddr.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: parseaddr.c,v 8.359.2.9 2003/09/16 18:07:50 ca Exp $") +SM_RCSID("@(#)$Id: parseaddr.c,v 8.378 2004/05/18 20:01:54 ca Exp $") static void allocaddr __P((ADDRESS *, int, char *, ENVELOPE *)); static int callsubr __P((char**, int, ENVELOPE *)); @@ -90,7 +90,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt) if (delimptr == NULL) delimptr = &delimptrbuf; - pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL); + pvp = prescan(addr, delim, pvpbuf, sizeof pvpbuf, delimptr, NULL, false); if (pvp == NULL) { if (tTd(20, 1)) @@ -228,7 +228,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt) if (tTd(20, 1)) { sm_dprintf("parseaddr-->"); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } return a; @@ -460,6 +460,7 @@ allocaddr(a, flags, paddr, e) ** terminating delimiter. ** toktab -- if set, a token table to use for parsing. ** If NULL, use the default table. +** ignore -- if true, ignore unbalanced addresses ** ** Returns: ** A pointer to a vector of tokens. @@ -611,13 +612,14 @@ unsigned char TokTypeNoC[256] = #define NOCHAR (-1) /* signal nothing in lookahead token */ char ** -prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) +prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab, ignore) char *addr; int delim; char pvpbuf[]; int pvpbsize; char **delimptr; unsigned char *toktab; + bool ignore; { register char *p; register char *q; @@ -633,7 +635,6 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) char *saveto = CurEnv->e_to; static char *av[MAXATOM + 1]; static bool firsttime = true; - extern int errno; if (firsttime) { @@ -678,7 +679,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (tTd(22, 11)) { sm_dprintf("prescan: "); - xputs(p); + xputs(sm_debug_file(), p); sm_dprintf("\n"); } @@ -722,7 +723,9 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (c == '\0') { /* diagnose and patch up bad syntax */ - if (state == QST) + if (ignore) + break; + else if (state == QST) { usrerr("553 Unbalanced '\"'"); c = '"'; @@ -748,7 +751,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) break; /* special case for better error management */ - if (delim == ',' && !route_syntax) + if (delim == ',' && !route_syntax && !ignore) { usrerr("553 Unbalanced '<'"); c = '>'; @@ -799,8 +802,11 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) { if (cmntcnt <= 0) { - usrerr("553 Unbalanced ')'"); - c = NOCHAR; + if (!ignore) + { + usrerr("553 Unbalanced ')'"); + c = NOCHAR; + } } else cmntcnt--; @@ -823,8 +829,11 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) { if (anglecnt <= 0) { - usrerr("553 Unbalanced '>'"); - c = NOCHAR; + if (!ignore) + { + usrerr("553 Unbalanced '>'"); + c = NOCHAR; + } } else anglecnt--; @@ -868,7 +877,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (tTd(22, 36)) { sm_dprintf("tok="); - xputs(tok); + xputs(sm_debug_file(), tok); sm_dprintf("\n"); } if (avp >= &av[MAXATOM]) @@ -894,7 +903,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (tTd(22, 12)) { sm_dprintf("prescan==>"); - printav(av); + printav(sm_debug_file(), av); } CurEnv->e_to = saveto; if (av[0] == NULL) @@ -997,12 +1006,12 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s%-16.16s input:", prefix, rulename); - printav(pvp); + printav(smioout, pvp); } else if (tTd(21, 1)) { sm_dprintf("%s%-16.16s input:", prefix, rulename); - printav(pvp); + printav(sm_debug_file(), pvp); } if (reclevel++ > MaxRuleRecursion) { @@ -1037,7 +1046,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) rwr->r_line); else sm_dprintf("-----trying rule:"); - printav(rwr->r_lhs); + printav(sm_debug_file(), rwr->r_lhs); } /* try to match on this rule */ @@ -1051,7 +1060,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) if (tTd(21, 1)) { sm_dprintf("workspace: "); - printav(pvp); + printav(sm_debug_file(), pvp); } break; } @@ -1062,9 +1071,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) if (tTd(21, 35)) { sm_dprintf("ADVANCE rp="); - xputs(rp); + xputs(sm_debug_file(), rp); sm_dprintf(", ap="); - xputs(ap); + xputs(sm_debug_file(), ap); sm_dprintf("\n"); } if (rp == NULL) @@ -1097,9 +1106,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) if (tTd(21, 36)) { sm_dprintf("EXTEND rp="); - xputs(rp); + xputs(sm_debug_file(), rp); sm_dprintf(", ap="); - xputs(ap); + xputs(sm_debug_file(), ap); sm_dprintf("\n"); } goto extendclass; @@ -1195,9 +1204,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) if (tTd(21, 36)) { sm_dprintf("BACKUP rp="); - xputs(rp); + xputs(sm_debug_file(), rp); sm_dprintf(", ap="); - xputs(ap); + xputs(sm_debug_file(), ap); sm_dprintf("\n"); } @@ -1248,7 +1257,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) if (tTd(21, 12)) { sm_dprintf("-----rule matches:"); - printav(rvp); + printav(sm_debug_file(), rvp); } rp = *rvp; @@ -1359,7 +1368,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) /* scan the new replacement */ xpvp = prescan(mval, '\0', pvpbuf, sizeof pvpbuf, NULL, - NULL); + NULL, false); if (xpvp == NULL) { /* prescan pre-printed error */ @@ -1531,7 +1540,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) { /* scan the new replacement */ xpvp = prescan(replac, '\0', pvpbuf, - sizeof pvpbuf, NULL, NULL); + sizeof pvpbuf, NULL, NULL, false); if (xpvp == NULL) { /* prescan already printed error */ @@ -1571,7 +1580,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) if (tTd(21, 4)) { sm_dprintf("rewritten as:"); - printav(pvp); + printav(sm_debug_file(), pvp); } } @@ -1579,12 +1588,12 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s%-16.16s returns:", prefix, rulename); - printav(pvp); + printav(smioout, pvp); } else if (tTd(21, 1)) { sm_dprintf("%s%-16.16s returns:", prefix, rulename); - printav(pvp); + printav(sm_debug_file(), pvp); } return rstat; } @@ -1896,7 +1905,7 @@ buildaddr(tv, a, flags, e) if (tTd(24, 5)) { sm_dprintf("buildaddr, flags=%x, tv=", flags); - printav(tv); + printav(sm_debug_file(), tv); } maxatom = MAXATOM; @@ -1913,7 +1922,6 @@ buildaddr(tv, a, flags, e) { syserr("554 5.3.5 buildaddr: no mailer in parsed address"); badaddr: -#if _FFR_ALLOW_S0_ERROR_4XX /* ** ExitStat may have been set by an earlier map open ** failure (to a permanent error (EX_OSERR) in syserr()) @@ -1923,11 +1931,7 @@ buildaddr(tv, a, flags, e) ** XXX the real fix is probably to set ExitStat correctly, ** i.e., to EX_TEMPFAIL if the map open is just a temporary ** error. - ** - ** tempfail is tested here even if _FFR_ALLOW_S0_ERROR_4XX - ** is not set; that's ok because it is initialized to false. */ -#endif /* _FFR_ALLOW_S0_ERROR_4XX */ if (ExitStat == EX_TEMPFAIL || tempfail) a->q_state = QS_QUEUEUP; @@ -2027,10 +2031,8 @@ buildaddr(tv, a, flags, e) else usrerr(fmt, ubuf + off); /* XXX ubuf[off - 1] = ' '; */ -#if _FFR_ALLOW_S0_ERROR_4XX if (ubuf[0] == '4') tempfail = true; -#endif /* _FFR_ALLOW_S0_ERROR_4XX */ } else { @@ -2123,7 +2125,7 @@ buildaddr(tv, a, flags, e) if (tTd(24, 6)) { sm_dprintf("buildaddr => "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } return a; } @@ -2182,19 +2184,19 @@ cataddr(pvp, evp, buf, sz, spacesub) if (--sz <= 0) break; } - if ((i = sm_strlcpy(p, *pvp, sz)) >= sz) + i = sm_strlcpy(p, *pvp, sz); + sz -= i; + if (sz <= 0) break; oatomtok = natomtok; p += i; - sz -= i; if (pvp++ == evp) break; } -#if _FFR_CATCH_LONG_STRINGS - /* Don't silently truncate long strings; broken for evp != NULL */ - if (*pvp != NULL) + + /* Don't silently truncate long strings */ + if (sz <= 0) syserr("cataddr: string too long"); -#endif /* _FFR_CATCH_LONG_STRINGS */ *p = '\0'; } /* @@ -2298,7 +2300,8 @@ static struct qflags AddressFlags[] = }; void -printaddr(a, follow) +printaddr(fp, a, follow) + SM_FILE_T *fp; register ADDRESS *a; bool follow; { @@ -2309,14 +2312,14 @@ printaddr(a, follow) if (a == NULL) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "[NULL]\n"); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "[NULL]\n"); return; } while (a != NULL) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%p=", a); - (void) sm_io_flush(smioout, SM_TIME_DEFAULT); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%p=", a); + (void) sm_io_flush(fp, SM_TIME_DEFAULT); /* find the mailer -- carefully */ m = a->q_mailer; @@ -2327,100 +2330,100 @@ printaddr(a, follow) m->m_name = "NULL"; } - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s:\n\tmailer %d (%s), host `%s'\n", a->q_paddr == NULL ? "" : a->q_paddr, m->m_mno, m->m_name, a->q_host == NULL ? "" : a->q_host); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\tuser `%s', ruser `%s'\n", a->q_user, a->q_ruser == NULL ? "" : a->q_ruser); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\tstate="); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\tstate="); switch (a->q_state) { case QS_OK: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "OK"); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "OK"); break; case QS_DONTSEND: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "DONTSEND"); break; case QS_BADADDR: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "BADADDR"); break; case QS_QUEUEUP: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "QUEUEUP"); break; case QS_RETRY: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "RETRY"); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "RETRY"); break; case QS_SENT: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "SENT"); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "SENT"); break; case QS_VERIFIED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "VERIFIED"); break; case QS_EXPANDED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "EXPANDED"); break; case QS_SENDER: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "SENDER"); break; case QS_CLONED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "CLONED"); break; case QS_DISCARDED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "DISCARDED"); break; case QS_REPLACED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "REPLACED"); break; case QS_REMOVED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "REMOVED"); break; case QS_DUPLICATE: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "DUPLICATE"); break; case QS_INCLUDED: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "INCLUDED"); break; default: - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d", a->q_state); break; } - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, ", next=%p, alias %p, uid %d, gid %d\n", a->q_next, a->q_alias, (int) a->q_uid, (int) a->q_gid); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\tflags=%lx<", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\tflags=%lx<", a->q_flags); firstone = true; for (qfp = AddressFlags; qfp->qf_name != NULL; qfp++) @@ -2428,30 +2431,30 @@ printaddr(a, follow) if (!bitset(qfp->qf_bit, a->q_flags)) continue; if (!firstone) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, ","); firstone = false; - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s", qfp->qf_name); } - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ">\n"); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, ">\n"); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\towner=%s, home=\"%s\", fullname=\"%s\"\n", a->q_owner == NULL ? "(none)" : a->q_owner, a->q_home == NULL ? "(none)" : a->q_home, a->q_fullname == NULL ? "(none)" : a->q_fullname); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\torcpt=\"%s\", statmta=%s, status=%s\n", a->q_orcpt == NULL ? "(none)" : a->q_orcpt, a->q_statmta == NULL ? "(none)" : a->q_statmta, a->q_status == NULL ? "(none)" : a->q_status); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\tfinalrcpt=\"%s\"\n", a->q_finalrcpt == NULL ? "(none)" : a->q_finalrcpt); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\trstatus=\"%s\"\n", a->q_rstatus == NULL ? "(none)" : a->q_rstatus); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\tstatdate=%s\n", a->q_statdate == 0 ? "(none)" : ctime(&a->q_statdate)); @@ -2559,7 +2562,7 @@ remotename(name, m, flags, pstat, e) ** domain will be appended. */ - pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL); + pvp = prescan(name, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL, false); if (pvp == NULL) return name; if (REWRITE(pvp, 3, e) == EX_TEMPFAIL) @@ -2684,9 +2687,9 @@ maplocaluser(a, sendq, aliaslevel, e) if (tTd(29, 1)) { sm_dprintf("maplocaluser: "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } - pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL); + pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL, false); if (pvp == NULL) { if (tTd(29, 9)) @@ -2748,7 +2751,7 @@ maplocaluser(a, sendq, aliaslevel, e) if (tTd(29, 5)) { sm_dprintf("maplocaluser: QS_REPLACED "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } a1->q_alias = a; allocaddr(a1, RF_COPYALL, sm_rpool_strdup_x(e->e_rpool, a->q_paddr), e); @@ -2942,10 +2945,8 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid) auto ADDRESS a1; bool saveQuickAbort = QuickAbort; bool saveSuprErrs = SuprErrs; -#if _FFR_QUARANTINE bool quarantine = false; char ubuf[BUFSIZ * 2]; -#endif /* _FFR_QUARANTINE */ char buf0[MAXLINE]; char pvpbuf[PSBUFSIZE]; extern char MsgBuf[]; @@ -2987,7 +2988,8 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid) SuprErrs = true; QuickAbort = false; pvp = prescan(buf, '\0', pvpbuf, sizeof pvpbuf, NULL, - bitset(RSF_RMCOMM, flags) ? NULL : TokTypeNoC); + bitset(RSF_RMCOMM, flags) ? NULL : TokTypeNoC, + bitset(RSF_RMCOMM, flags) ? false : true); SuprErrs = saveSuprErrs; if (pvp == NULL) { @@ -3019,7 +3021,6 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid) e->e_flags |= EF_DISCARD; discard = true; } -#if _FFR_QUARANTINE else if (strcmp(pvp[1], "error") == 0 && pvp[2] != NULL && (pvp[2][0] & 0377) == CANONHOST && pvp[3] != NULL && strcmp(pvp[3], "quarantine") == 0) @@ -3040,7 +3041,6 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid) macid("{quarantine}"), e->e_quarmsg); quarantine = true; } -#endif /* _FFR_QUARANTINE */ else { int savelogusrerrs = LogUsrErrs; @@ -3091,12 +3091,10 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid) sm_syslog(LOG_NOTICE, logid, "ruleset=%s, arg1=%s%s, discard", rwset, p1, lbuf); -#if _FFR_QUARANTINE else if (quarantine) sm_syslog(LOG_NOTICE, logid, "ruleset=%s, arg1=%s%s, quarantine=%s", rwset, p1, lbuf, ubuf); -#endif /* _FFR_QUARANTINE */ else sm_syslog(LOG_NOTICE, logid, "ruleset=%s, arg1=%s%s, reject=%s", @@ -3198,7 +3196,7 @@ rscap(rwset, p1, p2, e, pvp, pvpbuf, size) { SuprErrs = true; QuickAbort = false; - *pvp = prescan(buf, '\0', pvpbuf, size, NULL, NULL); + *pvp = prescan(buf, '\0', pvpbuf, size, NULL, NULL, false); if (*pvp != NULL) rstat = rewrite(*pvp, rsno, 0, e, size); else diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c index e71b8f2ebadb..f37a293f4922 100644 --- a/contrib/sendmail/src/queue.c +++ b/contrib/sendmail/src/queue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: queue.c,v 8.863.2.67 2003/12/02 23:56:01 ca Exp $") +SM_RCSID("@(#)$Id: queue.c,v 8.938 2004/06/03 19:02:10 ca Exp $") #include @@ -37,23 +37,15 @@ SM_RCSID("@(#)$Id: queue.c,v 8.863.2.67 2003/12/02 23:56:01 ca Exp $") ** Historical notes: ** QF_VERSION == 4 was sendmail 8.10/8.11 without _FFR_QUEUEDELAY ** QF_VERSION == 5 was sendmail 8.10/8.11 with _FFR_QUEUEDELAY -** QF_VERSION == 6 is sendmail 8.12 without _FFR_QUEUEDELAY -** QF_VERSION == 7 is sendmail 8.12 with _FFR_QUEUEDELAY +** QF_VERSION == 6 was sendmail 8.12 without _FFR_QUEUEDELAY +** QF_VERSION == 7 was sendmail 8.12 with _FFR_QUEUEDELAY +** QF_VERSION == 8 is sendmail 8.13 */ -#if _FFR_QUEUEDELAY -# define QF_VERSION 7 /* version number of this queue format */ -static time_t queuedelay __P((ENVELOPE *)); -# define queuedelay_qfver_unsupported(qfver) false -#else /* _FFR_QUEUEDELAY */ -# define QF_VERSION 6 /* version number of this queue format */ -# define queuedelay(e) MinQueueAge -# define queuedelay_qfver_unsupported(qfver) ((qfver) == 5 || (qfver) == 7) -#endif /* _FFR_QUEUEDELAY */ -#if _FFR_QUARANTINE +#define QF_VERSION 8 /* version number of this queue format */ + static char queue_letter __P((ENVELOPE *, int)); static bool quarantine_queue_item __P((int, int, ENVELOPE *, char *)); -#endif /* _FFR_QUARANTINE */ /* Naming convention: qgrp: index of queue group, qg: QUEUEGROUP */ @@ -304,7 +296,7 @@ hash_q(p, h) ** d data file directory name (added in 8.12) ** E error recipient ** F flag bits -** G queue delay algorithm (_FFR_QUEUEDELAY) +** G free (was: queue delay algorithm if _FFR_QUEUEDELAY) ** H header ** I data file's inode number ** K time of last delivery attempt @@ -312,7 +304,7 @@ hash_q(p, h) ** M message ** N number of delivery attempts ** P message priority -** q quarantine reason (_FFR_QUARANTINE) +** q quarantine reason ** Q original recipient (ORCPT=) ** r final recipient (Final-Recipient: DSN field) ** R recipient @@ -320,7 +312,7 @@ hash_q(p, h) ** T init time ** V queue file version ** X free (was: character set if _FFR_SAVE_CHARSET) -** Y current delay (_FFR_QUEUEDELAY) +** Y free (was: current delay if _FFR_QUEUEDELAY) ** Z original envelope id from ESMTP ** ! deliver by (added in 8.12) ** $ define macro @@ -397,15 +389,15 @@ queueup(e, announce, msync) !lockfile(tfd, tf, NULL, LOCK_EX|LOCK_NB) || #endif /* !SM_OPEN_EXLOCK */ (tfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &tfd, SM_IO_WRONLY_B, + (void *) &tfd, SM_IO_WRONLY, NULL)) == NULL) { int save_errno = errno; printopenfds(true); errno = save_errno; - syserr("!queueup: cannot create queue file %s, euid=%d", - tf, (int) geteuid()); + syserr("!queueup: cannot create queue file %s, euid=%d, fd=%d, fp=%p", + tf, (int) geteuid(), tfd, tfp); /* NOTREACHED */ } e->e_lockfp = tfp; @@ -490,7 +482,7 @@ queueup(e, announce, msync) if (tTd(40, 32)) { sm_dprintf(" sendq="); - printaddr(e->e_sendqueue, true); + printaddr(sm_debug_file(), e->e_sendqueue, true); } if (tTd(40, 9)) { @@ -513,6 +505,7 @@ queueup(e, announce, msync) { if (e->e_dfp != NULL && SuperSafe != SAFE_REALLY && + SuperSafe != SAFE_REALLY_POSTMILTER && sm_io_setinfo(e->e_dfp, SM_BF_COMMIT, NULL) < 0 && errno != EINVAL) { @@ -574,6 +567,7 @@ queueup(e, announce, msync) (*e->e_putbody)(&mcibuf, e, NULL); if (SuperSafe == SAFE_REALLY || + SuperSafe == SAFE_REALLY_POSTMILTER || (SuperSafe == SAFE_INTERACTIVE && msync)) { if (tTd(40,32)) @@ -610,17 +604,7 @@ queueup(e, announce, msync) (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "T%ld\n", (long) e->e_ctime); /* output last delivery time */ -#if _FFR_QUEUEDELAY (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "K%ld\n", (long) e->e_dtime); - (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "G%d\n", e->e_queuealg); - (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "Y%ld\n", (long) e->e_queuedelay); - if (tTd(40, 64)) - sm_syslog(LOG_INFO, e->e_id, - "queue alg: %d delay %ld next: %ld (now: %ld)\n", - e->e_queuealg, e->e_queuedelay, e->e_dtime, curtime()); -#else /* _FFR_QUEUEDELAY */ - (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "K%ld\n", (long) e->e_dtime); -#endif /* _FFR_QUEUEDELAY */ /* output number of delivery attempts */ (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "N%d\n", e->e_ntries); @@ -654,12 +638,10 @@ queueup(e, announce, msync) (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "B%s\n", denlstring(e->e_bodytype, true, false)); -#if _FFR_QUARANTINE /* quarantine reason */ if (e->e_quarmsg != NULL) (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "q%s\n", denlstring(e->e_quarmsg, true, false)); -#endif /* _FFR_QUARANTINE */ /* message from envelope, if it exists */ if (e->e_message != NULL) @@ -753,10 +735,8 @@ queueup(e, announce, msync) { char *tag = "queued"; -#if _FFR_QUARANTINE if (e->e_quarmsg != NULL) tag = "quarantined"; -#endif /* _FFR_QUARANTINE */ e->e_to = q->q_paddr; message(tag); @@ -768,7 +748,7 @@ queueup(e, announce, msync) if (tTd(40, 1)) { sm_dprintf("queueing "); - printaddr(q, false); + printaddr(sm_debug_file(), q, false); } } @@ -879,6 +859,7 @@ queueup(e, announce, msync) if (sm_io_flush(tfp, SM_TIME_DEFAULT) != 0 || ((SuperSafe == SAFE_REALLY || + SuperSafe == SAFE_REALLY_POSTMILTER || (SuperSafe == SAFE_INTERACTIVE && msync)) && fsync(sm_io_getinfo(tfp, SM_IO_WHAT_FD, NULL)) < 0) || sm_io_error(tfp)) @@ -891,9 +872,7 @@ queueup(e, announce, msync) if (!newid) { -#if _FFR_QUARANTINE char new = queue_letter(e, ANYQFL_LETTER); -#endif /* _FFR_QUARANTINE */ /* rename (locked) tf to be (locked) [qh]f */ (void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER), @@ -901,7 +880,6 @@ queueup(e, announce, msync) if (rename(tf, qf) < 0) syserr("cannot rename(%s, %s), uid=%d", tf, qf, (int) geteuid()); -# if _FFR_QUARANTINE else { /* @@ -931,7 +909,6 @@ queueup(e, announce, msync) } } e->e_qfletter = new; -# endif /* _FFR_QUARANTINE */ /* ** fsync() after renaming to make sure metadata is @@ -965,9 +942,7 @@ queueup(e, announce, msync) if (LogLevel > 79) sm_syslog(LOG_DEBUG, e->e_id, "queueup %s", tf); -#if _FFR_QUARANTINE e->e_qfletter = queue_letter(e, ANYQFL_LETTER); -#endif /* _FFR_QUARANTINE */ } errno = 0; @@ -1538,9 +1513,6 @@ runqueue(forkflag, verbose, persistent, runall) ** Increment CurRunners before calling run_work_group() ** to avoid a "race condition" with proc_list_drop() which ** decrements CurRunners if the queue runners terminate. - ** This actually doesn't cause any harm, but CurRunners - ** might become negative which is at least confusing. - ** ** Notice: CurRunners is an upper limit, in some cases ** (too few jobs in the queue) this value is larger than ** the actual number of queue runners. The discrepancy can @@ -1595,6 +1567,57 @@ runqueue(forkflag, verbose, persistent, runall) #endif /* SM_HEAP_CHECK */ return ret; } + +#if _FFR_SKIP_DOMAINS +/* +** SKIP_DOMAINS -- Skip 'skip' number of domains in the WorkQ. +** +** Added by Stephen Frost to support +** having each runner process every N'th domain instead of +** every N'th message. +** +** Parameters: +** skip -- number of domains in WorkQ to skip. +** +** Returns: +** total number of messages skipped. +** +** Side Effects: +** may change WorkQ +*/ + +static int +skip_domains(skip) + int skip; +{ + int n, seqjump; + + for (n = 0, seqjump = 0; n < skip && WorkQ != NULL; seqjump++) + { + if (WorkQ->w_next != NULL) + { + if (WorkQ->w_host != NULL && + WorkQ->w_next->w_host != NULL) + { + if (sm_strcasecmp(WorkQ->w_host, + WorkQ->w_next->w_host) != 0) + n++; + } + else + { + if ((WorkQ->w_host != NULL && + WorkQ->w_next->w_host == NULL) || + (WorkQ->w_host == NULL && + WorkQ->w_next->w_host != NULL)) + n++; + } + } + WorkQ = WorkQ->w_next; + } + return seqjump; +} +#endif /* _FFR_SKIP_DOMAINS */ + /* ** RUNNER_WORK -- have a queue runner do its work ** @@ -1627,7 +1650,7 @@ runner_work(e, sequenceno, didfork, skip, njobs) int skip; int njobs; { - int n; + int n, seqjump; WORK *w; time_t now; @@ -1641,6 +1664,7 @@ runner_work(e, sequenceno, didfork, skip, njobs) */ BlockOldsh = true; + seqjump = skip; /* process them once at a time */ while (WorkQ != NULL) @@ -1675,10 +1699,49 @@ runner_work(e, sequenceno, didfork, skip, njobs) ** It is set 'skip' ahead (the number of parallel queue ** runners working on WorkQ together) since each runner ** works on every 'skip'th (N-th) item. +#if _FFR_SKIP_DOMAINS + ** In the case of the BYHOST Queue Sort Order, the 'item' + ** is a domain, so we work on every 'skip'th (N-th) domain. +#endif * _FFR_SKIP_DOMAINS * */ - for (n = 0; n < skip && WorkQ != NULL; n++) - WorkQ = WorkQ->w_next; +#if _FFR_SKIP_DOMAINS + if (QueueSortOrder == QSO_BYHOST) + { + seqjump = 1; + if (WorkQ->w_next != NULL) + { + if (WorkQ->w_host != NULL && + WorkQ->w_next->w_host != NULL) + { + if (sm_strcasecmp(WorkQ->w_host, + WorkQ->w_next->w_host) + != 0) + seqjump = skip_domains(skip); + else + WorkQ = WorkQ->w_next; + } + else + { + if ((WorkQ->w_host != NULL && + WorkQ->w_next->w_host == NULL) || + (WorkQ->w_host == NULL && + WorkQ->w_next->w_host != NULL)) + seqjump = skip_domains(skip); + else + WorkQ = WorkQ->w_next; + } + } + else + WorkQ = WorkQ->w_next; + } + else +#endif /* _FFR_SKIP_DOMAINS */ + { + for (n = 0; n < skip && WorkQ != NULL; n++) + WorkQ = WorkQ->w_next; + } + e->e_to = NULL; /* @@ -1753,7 +1816,7 @@ runner_work(e, sequenceno, didfork, skip, njobs) if (w->w_host != NULL) sm_free(w->w_host); /* XXX */ sm_free((char *) w); /* XXX */ - sequenceno += skip; /* next sequence number */ + sequenceno += seqjump; /* next sequence number */ #if SM_HEAP_CHECK if (sm_debug_active(&DebugLeakQ, 1)) sm_heap_setgroup(oldgroup); @@ -1883,7 +1946,8 @@ run_work_group(wgrp, flags) /* wgrp only used when queue runners are persistent */ proc_list_add(pid, "Queue runner", PROC_QUEUE, WorkGrp[wgrp].wg_maxact, - bitset(RWG_PERSISTENT, flags) ? wgrp : -1); + bitset(RWG_PERSISTENT, flags) ? wgrp : -1, + NULL); (void) sm_releasesignal(SIGALRM); (void) sm_releasesignal(SIGCHLD); return true; @@ -1897,6 +1961,7 @@ run_work_group(wgrp, flags) ShutdownRequest = NULL; PendingSignal = 0; CurrentPid = getpid(); + close_sendmail_pid(); /* ** Initialize exception stack and default exception @@ -1909,7 +1974,7 @@ run_work_group(wgrp, flags) /* Add parent process as first child item */ proc_list_add(CurrentPid, "Queue runner child process", - PROC_QUEUE_CHILD, 0, -1); + PROC_QUEUE_CHILD, 0, -1, NULL); (void) sm_releasesignal(SIGCHLD); (void) sm_signal(SIGCHLD, SIG_DFL); (void) sm_signal(SIGHUP, SIG_DFL); @@ -1952,9 +2017,7 @@ run_work_group(wgrp, flags) */ if (QueueLimitId != NULL || QueueLimitSender != NULL || -#if _FFR_QUARANTINE QueueLimitQuarantine != NULL || -#endif /* _FFR_QUARANTINE */ QueueLimitRecipient != NULL) { IgnoreHostStatus = true; @@ -2099,10 +2162,20 @@ run_work_group(wgrp, flags) { /* parent -- clean out connection cache */ mci_flush(false, NULL); - WorkQ = WorkQ->w_next; /* for the skip */ - sequenceno++; +#if _FFR_SKIP_DOMAINS + if (QueueSortOrder == QSO_BYHOST) + { + sequenceno += skip_domains(1); + } + else +#endif /* _FFR_SKIP_DOMAINS */ + { + /* for the skip */ + WorkQ = WorkQ->w_next; + sequenceno++; + } proc_list_add(pid, "Queue child runner process", - PROC_QUEUE_CHILD, 0, -1); + PROC_QUEUE_CHILD, 0, -1, NULL); /* No additional work, no additional runners */ if (WorkQ == NULL) @@ -2116,6 +2189,7 @@ run_work_group(wgrp, flags) ShutdownRequest = NULL; PendingSignal = 0; CurrentPid = getpid(); + close_sendmail_pid(); /* ** Initialize exception stack and default @@ -2227,9 +2301,9 @@ run_work_group(wgrp, flags) rmexpstab(); #if NAMED_BIND - /* Update MX records for FallBackMX. */ - if (FallBackMX != NULL) - (void) getfallbackmxrr(FallBackMX); + /* Update MX records for FallbackMX. */ + if (FallbackMX != NULL) + (void) getfallbackmxrr(FallbackMX); #endif /* NAMED_BIND */ #if USERDB @@ -2371,10 +2445,8 @@ runqueueevent() #define NEED_R 0004 /* 'R': recipient */ #define NEED_S 0010 /* 'S': sender */ #define NEED_H 0020 /* host */ -#if _FFR_QUARANTINE -# define HAS_QUARANTINE 0040 /* has an unexpected 'q' line */ -# define NEED_QUARANTINE 0100 /* 'q': reason */ -#endif /* _FFR_QUARANTINE */ +#define HAS_QUARANTINE 0040 /* has an unexpected 'q' line */ +#define NEED_QUARANTINE 0100 /* 'q': reason */ static WORK *WorkList = NULL; /* list of unsort work */ static int WorkListSize = 0; /* current max size of WorkList */ @@ -2440,7 +2512,6 @@ gatherq(qgrp, qdir, doall, full, more) check = check->queue_next; } -#if _FFR_QUARANTINE if (QueueMode == QM_QUARANTINE) { check = QueueLimitQuarantine; @@ -2452,7 +2523,6 @@ gatherq(qgrp, qdir, doall, full, more) check = check->queue_next; } } -#endif /* _FFR_QUARANTINE */ } /* open the queue directory */ @@ -2483,7 +2553,6 @@ gatherq(qgrp, qdir, doall, full, more) sm_dprintf("gatherq: checking %s..", d->d_name); /* is this an interesting entry? */ -#if _FFR_QUARANTINE if (!(((QueueMode == QM_NORMAL && d->d_name[0] == NORMQF_LETTER) || (QueueMode == QM_QUARANTINE && @@ -2491,9 +2560,6 @@ gatherq(qgrp, qdir, doall, full, more) (QueueMode == QM_LOST && d->d_name[0] == LOSEQF_LETTER)) && d->d_name[1] == 'f')) -#else /* _FFR_QUARANTINE */ - if (d->d_name[0] != NORMQF_LETTER || d->d_name[1] != 'f') -#endif /* _FFR_QUARANTINE */ { if (tTd(41, 50)) sm_dprintf(" skipping\n"); @@ -2564,10 +2630,8 @@ gatherq(qgrp, qdir, doall, full, more) /* Yikes! Skip it or we will hang on open! */ if (!((d->d_name[0] == DATAFL_LETTER || d->d_name[0] == NORMQF_LETTER || -#if _FFR_QUARANTINE d->d_name[0] == QUARQF_LETTER || d->d_name[0] == LOSEQF_LETTER || -#endif /* _FFR_QUARANTINE */ d->d_name[0] == XSCRPT_LETTER) && d->d_name[1] == 'f' && d->d_name[2] == '\0')) syserr("gatherq: %s/%s is not a regular file", @@ -2580,9 +2644,7 @@ gatherq(qgrp, qdir, doall, full, more) if ((QueueSortOrder == QSO_BYFILENAME || QueueSortOrder == QSO_BYMODTIME || QueueSortOrder == QSO_RANDOM) && -#if _FFR_QUARANTINE QueueLimitQuarantine == NULL && -#endif /* _FFR_QUARANTINE */ QueueLimitSender == NULL && QueueLimitRecipient == NULL) { @@ -2644,10 +2706,8 @@ gatherq(qgrp, qdir, doall, full, more) i |= NEED_S; if (QueueLimitRecipient != NULL) i |= NEED_R; -#if _FFR_QUARANTINE if (QueueLimitQuarantine != NULL) i |= NEED_QUARANTINE; -#endif /* _FFR_QUARANTINE */ while (cf != NULL && i != 0 && sm_io_fgets(cf, SM_TIME_DEFAULT, lbuf, sizeof lbuf) != NULL) @@ -2682,7 +2742,6 @@ gatherq(qgrp, qdir, doall, full, more) i &= ~NEED_T; break; -#if _FFR_QUARANTINE case 'q': if (QueueMode != QM_QUARANTINE && QueueMode != QM_LOST) @@ -2715,7 +2774,6 @@ gatherq(qgrp, qdir, doall, full, more) i &= ~NEED_QUARANTINE; } break; -#endif /* _FFR_QUARANTINE */ case 'R': if (w->w_host == NULL && @@ -2787,27 +2845,14 @@ gatherq(qgrp, qdir, doall, full, more) if (atol(&lbuf[1]) == 0) w->w_tooyoung = false; break; - -#if _FFR_QUEUEDELAY -/* - case 'G': - queuealg = atoi(lbuf[1]); - break; - case 'Y': - queuedelay = (time_t) atol(&lbuf[1]); - break; -*/ -#endif /* _FFR_QUEUEDELAY */ } } if (cf != NULL) (void) sm_io_close(cf, SM_TIME_DEFAULT); if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) || -#if _FFR_QUARANTINE bitset(HAS_QUARANTINE, i) || bitset(NEED_QUARANTINE, i) || -#endif /* _FFR_QUARANTINE */ bitset(NEED_R|NEED_S, i)) { /* don't even bother sorting this job in */ @@ -2866,19 +2911,17 @@ sortq(max) if (WorkQ != NULL) { - /* Clear out old WorkQ. */ - for (w = WorkQ; w != NULL; ) - { - register WORK *nw = w->w_next; + WORK *nw; - WorkQ = nw; + /* Clear out old WorkQ. */ + for (w = WorkQ; w != NULL; w = nw) + { + nw = w->w_next; sm_free(w->w_name); /* XXX */ if (w->w_host != NULL) sm_free(w->w_host); /* XXX */ sm_free((char *) w); /* XXX */ - w = nw; } - sm_free((char *) WorkQ); WorkQ = NULL; } @@ -2990,7 +3033,7 @@ sortq(max) qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf7); } #endif /* _FFR_RHS */ - else + else if (QueueSortOrder == QSO_BYPRIORITY) { /* ** Simple sort based on queue priority only. @@ -2998,6 +3041,7 @@ sortq(max) qsort((char *) WorkList, wc, sizeof *WorkList, workcmpf0); } + /* else don't sort at all */ /* ** Convert the work list into canonical form. @@ -3021,6 +3065,15 @@ sortq(max) w->w_next = WorkQ; WorkQ = w; } + + /* free the rest of the list */ + for (i = WorkListCount; --i >= wc; ) + { + sm_free(WorkList[i].w_name); + if (WorkList[i].w_host != NULL) + sm_free(WorkList[i].w_host); + } + if (WorkList != NULL) sm_free(WorkList); /* XXX */ WorkList = NULL; @@ -3755,11 +3808,9 @@ doworklist(el, forkflag, requeueflag) if (WILL_BE_QUEUED(ei->e_sendmode)) continue; -#if _FFR_QUARANTINE else if (QueueMode != QM_QUARANTINE && ei->e_quarmsg != NULL) continue; -#endif /* _FFR_QUARANTINE */ rpool = sm_rpool_new_x(NULL); clearenvelope(&e, true, rpool); @@ -4051,9 +4102,7 @@ readqf(e, openonly) e->e_flags |= EF_GLOBALERRS; set_op_mode(MD_QUEUERUN); ctladdr = NULL; -#if _FFR_QUARANTINE e->e_qfletter = queue_letter(e, ANYQFL_LETTER); -#endif /* _FFR_QUARANTINE */ e->e_dfqgrp = e->e_qgrp; e->e_dfqdir = e->e_qdir; #if _FFR_QUEUE_MACRO @@ -4062,10 +4111,6 @@ readqf(e, openonly) #endif /* _FFR_QUEUE_MACRO */ e->e_dfino = -1; e->e_msgsize = -1; -#if _FFR_QUEUEDELAY - e->e_queuealg = QD_LINEAR; - e->e_queuedelay = (time_t) 0; -#endif /* _FFR_QUEUEDELAY */ while ((bp = fgetfolded(buf, sizeof buf, qfp)) != NULL) { unsigned long qflags; @@ -4188,19 +4233,11 @@ readqf(e, openonly) } break; -#if _FFR_QUEUEDELAY - case 'G': /* queue delay algorithm */ - e->e_queuealg = atoi(&buf[1]); - break; -#endif /* _FFR_QUEUEDELAY */ - -#if _FFR_QUARANTINE case 'q': /* quarantine reason */ e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, &bp[1]); macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), e->e_quarmsg); break; -#endif /* _FFR_QUARANTINE */ case 'H': /* header */ @@ -4233,7 +4270,7 @@ readqf(e, openonly) /* if this has been tried recently, let it be */ now = curtime(); if (e->e_ntries > 0 && e->e_dtime <= now && - now < e->e_dtime + queuedelay(e)) + now < e->e_dtime + MinQueueAge) { char *howlong; @@ -4363,10 +4400,6 @@ readqf(e, openonly) case 'V': /* queue file version number */ qfver = atoi(&bp[1]); - if (queuedelay_qfver_unsupported(qfver)) - syserr("queue file version %d not supported: %s", - qfver, - "sendmail not compiled with _FFR_QUEUEDELAY"); if (qfver <= QF_VERSION) break; syserr("Version number in queue file (%d) greater than max (%d)", @@ -4376,12 +4409,6 @@ readqf(e, openonly) /* NOTREACHED */ break; -#if _FFR_QUEUEDELAY - case 'Y': /* current delay */ - e->e_queuedelay = (time_t) atol(&buf[1]); - break; -#endif /* _FFR_QUEUEDELAY */ - case 'Z': /* original envelope id from ESMTP */ e->e_envid = sm_rpool_strdup_x(e->e_rpool, &bp[1]); macdefine(&e->e_macro, A_PERM, @@ -4411,6 +4438,24 @@ readqf(e, openonly) nomore = true; break; +#if _FFR_QUEUEDELAY + case 'G': + case 'Y': + + /* + ** Maintain backward compatibility for + ** users who defined _FFR_QUEUEDELAY in + ** previous releases. Remove this + ** code in 8.14 or 8.15. + */ + + if (qfver == 5 || qfver == 7) + break; + + /* If not qfver 5 or 7, then 'G' or 'Y' is invalid */ + /* FALLTHROUGH */ +#endif /* _FFR_QUEUEDELAY */ + default: syserr("readqf: %s: line %d: bad line \"%s\"", qf, LineNumber, shortenstring(bp, MAXSHORTSTR)); @@ -4782,9 +4827,7 @@ print_single_queue(qgrp, qdir) long dfsize; int flags = 0; int qfver; -#if _FFR_QUARANTINE char quarmsg[MAXLINE]; -#endif /* _FFR_QUARANTINE */ char statmsg[MAXLINE]; char bodytype[MAXNAME + 1]; char qf[MAXPATHLEN]; @@ -4847,10 +4890,8 @@ print_single_queue(qgrp, qdir) } if (w->w_lock) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "*"); -#if _FFR_QUARANTINE else if (QueueMode == QM_LOST) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "?"); -#endif /* _FFR_QUARANTINE */ else if (w->w_tooyoung) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "-"); else if (shouldqueue(w->w_pri, w->w_ctime)) @@ -4860,9 +4901,7 @@ print_single_queue(qgrp, qdir) errno = 0; -#if _FFR_QUARANTINE quarmsg[0] = '\0'; -#endif /* _FFR_QUARANTINE */ statmsg[0] = bodytype[0] = '\0'; qfver = 0; while (sm_io_fgets(f, SM_TIME_DEFAULT, buf, sizeof buf) != NULL) @@ -4887,14 +4926,12 @@ print_single_queue(qgrp, qdir) statmsg[i] = '\0'; break; -#if _FFR_QUARANTINE case 'q': /* quarantine reason */ if ((i = strlen(&buf[1])) >= sizeof quarmsg) i = sizeof quarmsg - 1; memmove(quarmsg, &buf[1], i); quarmsg[i] = '\0'; break; -#endif /* _FFR_QUARANTINE */ case 'B': /* body type */ if ((i = strlen(&buf[1])) >= sizeof bodytype) @@ -4925,7 +4962,7 @@ print_single_queue(qgrp, qdir) ctime(&submittime)); prtstr(&buf[1], 39); } -#if _FFR_QUARANTINE + if (quarmsg[0] != '\0') { (void) sm_io_fprintf(smioout, @@ -4935,7 +4972,7 @@ print_single_queue(qgrp, qdir) quarmsg); quarmsg[0] = '\0'; } -#endif /* _FFR_QUARANTINE */ + if (statmsg[0] != '\0' || bodytype[0] != '\0') { (void) sm_io_fprintf(smioout, @@ -5018,7 +5055,6 @@ print_single_queue(qgrp, qdir) return nrequests; } -#if _FFR_QUARANTINE /* ** QUEUE_LETTER -- get the proper queue letter for the current QueueMode. ** @@ -5066,7 +5102,6 @@ queue_letter(e, type) } return type; } -#endif /* _FFR_QUARANTINE */ /* ** QUEUENAME -- build a file name in the queue directory for this envelope. @@ -5098,10 +5133,7 @@ queuename(e, type) /* Assign an ID if needed */ if (e->e_id == NULL) assign_queueid(e); - -#if _FFR_QUARANTINE type = queue_letter(e, type); -#endif /* _FFR_QUARANTINE */ /* begin of filename */ pref[0] = (char) type; @@ -5169,9 +5201,7 @@ queuename(e, type) sub = "/df/"; break; -#if _FFR_QUARANTINE case QUARQF_LETTER: -#endif /* _FFR_QUARANTINE */ case TEMPQF_LETTER: case NEWQFL_LETTER: case LOSEQF_LETTER: @@ -5252,8 +5282,8 @@ static const char QueueIdChars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh ** Note: the length is "officially" 60 because minutes and seconds are ** usually only 0-59. However (Linux): ** tm_sec The number of seconds after the minute, normally in -** the range 0 to 59, but can be up to 61 to allow for -** leap seconds. +** the range 0 to 59, but can be up to 61 to allow for +** leap seconds. ** Hence the real length of the string is 62 to take this into account. ** Alternatively % QIC_LEN can (should) be used for access everywhere. */ @@ -5326,10 +5356,10 @@ assign_queueid(e) e->e_qdir = NOQDIR; e->e_xfqgrp = NOQGRP; #endif /* 0 */ -#if _FFR_QUARANTINE + /* New ID means it's not on disk yet */ e->e_qfletter = '\0'; -#endif /* _FFR_QUARANTINE */ + if (tTd(7, 1)) sm_dprintf("assign_queueid: assigned id %s, e=%p\n", e->e_id, e); @@ -5517,10 +5547,8 @@ loseqfile(e, why) return; if (!bitset(EF_INQUEUE, e->e_flags)) queueup(e, false, true); -#if _FFR_QUARANTINE else if (QueueMode == QM_LOST) loseit = false; -#endif /* _FFR_QUARANTINE */ /* if already lost, no need to re-lose */ if (loseit) @@ -7210,6 +7238,11 @@ makequeue(line, qdef) break; # endif /* _FFR_RHS */ + case 'n': /* none */ + case 'N': + qg->qg_sortorder = QSO_NONE; + break; + default: syserr("Invalid queue sort order \"%s\"", p); } @@ -7335,44 +7368,6 @@ hashfqn(fqn, buckets) } #endif /* 0 */ -#if _FFR_QUEUEDELAY -/* -** QUEUEDELAY -- compute queue delay time -** -** Parameters: -** e -- the envelope to queue up. -** -** Returns: -** queue delay time -** -** Side Effects: -** may change e_queuedelay -*/ - -static time_t -queuedelay(e) - ENVELOPE *e; -{ - time_t qd; - - if (e->e_queuealg == QD_EXP) - { - if (e->e_queuedelay == 0) - e->e_queuedelay = QueueInitDelay; - else - { - e->e_queuedelay *= 2; - if (e->e_queuedelay > QueueMaxDelay) - e->e_queuedelay = QueueMaxDelay; - } - qd = e->e_queuedelay; - } - else - qd = MinQueueAge; - return qd; -} -#endif /* _FFR_QUEUEDELAY */ - /* ** A structure for sorting Queue according to maxqrun without ** screwing up Queue itself. @@ -7720,11 +7715,9 @@ split_env(e, sendqueue, qgrp, qdir) ee->e_qdir = ee->e_dfqdir = qdir; ee->e_errormode = EM_MAIL; ee->e_statmsg = NULL; -#if _FFR_QUARANTINE if (e->e_quarmsg != NULL) ee->e_quarmsg = sm_rpool_strdup_x(ee->e_rpool, e->e_quarmsg); -#endif /* _FFR_QUARANTINE */ /* ** XXX Not sure if this copying is necessary. @@ -8255,7 +8248,6 @@ split_by_recipient(e) return split; } -#if _FFR_QUARANTINE /* ** QUARANTINE_QUEUE_ITEM -- {un,}quarantine a single envelope ** @@ -8483,7 +8475,9 @@ quarantine_queue_item(qgrp, qdir, e, reason) /* Make sure we wrote things out safely */ if (!failing && (sm_io_flush(tempqfp, SM_TIME_DEFAULT) != 0 || - ((SuperSafe == SAFE_REALLY || SuperSafe == SAFE_INTERACTIVE) && + ((SuperSafe == SAFE_REALLY || + SuperSafe == SAFE_REALLY_POSTMILTER || + SuperSafe == SAFE_INTERACTIVE) && fsync(sm_io_getinfo(tempqfp, SM_IO_WHAT_FD, NULL)) < 0) || ((errno = sm_io_error(tempqfp)) != 0))) { @@ -8728,4 +8722,3 @@ quarantine_queue(reason, qgrplimit) changed == 1 ? "" : "s"); } } -#endif /* _FFR_QUARANTINE */ diff --git a/contrib/sendmail/src/ratectrl.c b/contrib/sendmail/src/ratectrl.c new file mode 100644 index 000000000000..d141125e27c0 --- /dev/null +++ b/contrib/sendmail/src/ratectrl.c @@ -0,0 +1,534 @@ +/* + * Copyright (c) 2003 Sendmail, 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. + * + * Contributed by Jose Marcio Martins da Cruz - Ecole des Mines de Paris + * Jose-Marcio.Martins@ensmp.fr + */ + +/* a part of this code is based on inetd.c for which this copyright applies: */ +/* + * Copyright (c) 1983, 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +SM_RCSID("@(#)$Id: ratectrl.c,v 8.9 2004/07/07 21:23:57 ca Exp $") + +/* +** stuff included - given some warnings (inet_ntoa) +** - surely not everything is needed +*/ + +#if NETINET || NETINET6 +# include +#endif /* NETINET || NETINET6 */ + +#include + +#ifndef HASH_ALG +# define HASH_ALG 2 +#endif /* HASH_ALG */ + +#ifndef RATECTL_DEBUG +# define RATECTL_DEBUG 0 +#endif /* RATECTL_DEBUG */ + +/* forward declarations */ +static int client_rate __P((time_t, SOCKADDR *, bool)); +static int total_rate __P((time_t, bool)); +#if 0 +static int sockaddrcmp __P((SOCKADDR *, SOCKADDR *)); +#endif /* 0 */ + +/* +** CONNECTION_RATE_CHECK - updates connection history data +** and computes connection rate for the given host +** +** Parameters: +** hostaddr -- ip address of smtp client +** e -- envelope +** +** Returns: +** true (always) +** +** Side Effects: +** updates connection history +** +** Warnings: +** For each connection, this call shall be +** done only once with the value true for the +** update parameter. +** Typically, this call is done with the value +** true by the father, and once again with +** the value false by the children. +** +*/ + +bool +connection_rate_check(hostaddr, e) + SOCKADDR *hostaddr; + ENVELOPE *e; +{ + time_t now; + int totalrate, clientrate; + static int clientconn = 0; + + now = time(NULL); +#if RATECTL_DEBUG + sm_syslog(LOG_INFO, NOQID, "connection_rate_check entering..."); +#endif /* RATECTL_DEBUG */ + + /* update server connection rate */ + totalrate = total_rate(now, e == NULL); +#if RATECTL_DEBUG + sm_syslog(LOG_INFO, NOQID, "global connection rate: %d", globalRate); +#endif /* RATECTL_DEBUG */ + + /* update client connection rate */ + clientrate = client_rate(now, hostaddr, e == NULL); + + if (e == NULL) + clientconn = count_open_connections(hostaddr); + + if (e != NULL) + { + char s[16]; + + sm_snprintf(s, sizeof(s), "%d", clientrate); + macdefine(&e->e_macro, A_TEMP, macid("{client_rate}"), s); + sm_snprintf(s, sizeof(s), "%d", totalrate); + macdefine(&e->e_macro, A_TEMP, macid("{total_rate}"), s); + sm_snprintf(s, sizeof(s), "%d", clientconn); + macdefine(&e->e_macro, A_TEMP, macid("{client_connections}"), + s); + } + return true; +} + +/* +** Data declarations needed to evaluate connection rate +*/ + +static int CollTime = 60; + +/* this should be a power of 2, otherwise CPMHMASK doesn't work well */ +#ifndef CPMHSIZE +# define CPMHSIZE 1024 +#endif /* CPMHSIZE */ + +#define CPMHMASK (CPMHSIZE-1) + +#ifndef MAX_CT_STEPS +# define MAX_CT_STEPS 10 +#endif /* MAX_CT_STEPS */ + +/* +** time granularity: 10s (that's one "tick") +** will be initialised to ConnectionRateWindowSize/CHTSIZE +** before being used the first time +*/ + +static int ChtGran = -1; + +#define CHTSIZE 6 + +/* Number of connections for a certain "tick" */ +typedef struct CTime +{ + unsigned long ct_Ticks; + int ct_Count; +} +CTime_T; + +typedef struct CHash +{ +#if NETINET6 && NETINET + union + { + struct in_addr c4_Addr; + struct in6_addr c6_Addr; + } cu_Addr; +# define ch_Addr4 cu_Addr.c4_Addr +# define ch_Addr6 cu_Addr.c6_Addr +#else /* NETINET6 && NETINET */ +# if NETINET6 + struct in6_addr ch_Addr; +# define ch_Addr6 ch_Addr +# else /* NETINET6 */ + struct in_addr ch_Addr; +# define ch_Addr4 ch_Addr +# endif /* NETINET6 */ +#endif /* NETINET6 && NETINET */ + + int ch_Family; + time_t ch_LTime; + unsigned long ch_colls; + + /* 6 buckets for ticks: 60s */ + CTime_T ch_Times[CHTSIZE]; +} +CHash_T; + +static CHash_T CHashAry[CPMHSIZE]; +static bool CHashAryOK = false; + +/* +** CLIENT_RATE - Evaluate connection rate per smtp client +** +** Parameters: +** now - current time in secs +** saddr - client address +** update - update data / check only +** +** Returns: +** connection rate (connections / ConnectionRateWindowSize) +** +** Side effects: +** update static global data +** +*/ + +static int +client_rate(now, saddr, update) + time_t now; + SOCKADDR *saddr; + bool update; +{ + unsigned int hv; + int i; + int cnt; + bool coll; + CHash_T *chBest = NULL; + unsigned int ticks; + + cnt = 0; + hv = 0xABC3D20F; + if (ChtGran < 0) + ChtGran = ConnectionRateWindowSize / CHTSIZE; + if (ChtGran <= 0) + ChtGran = 10; + + ticks = now / ChtGran; + + if (!CHashAryOK) + { + memset(CHashAry, 0, sizeof (CHashAry)); + CHashAryOK = true; + } + + { + char *p; + int addrlen; +#if HASH_ALG != 1 + int c, d; +#endif /* HASH_ALG != 1 */ + + switch (saddr->sa.sa_family) + { +#if NETINET + case AF_INET: + p = (char *)&saddr->sin.sin_addr; + addrlen = sizeof(struct in_addr); + break; +#endif /* NETINET */ +#if NETINET6 + case AF_INET6: + p = (char *)&saddr->sin6.sin6_addr; + addrlen = sizeof(struct in6_addr); + break; +#endif /* NETINET6 */ + default: + /* should not happen */ + return -1; + } + + /* compute hash value */ + for (i = 0; i < addrlen; ++i, ++p) +#if HASH_ALG == 1 + hv = (hv << 5) ^ (hv >> 23) ^ *p; + hv = (hv ^ (hv >> 16)); +#elif HASH_ALG == 2 + { + d = *p; + c = d; + c ^= c<<6; + hv += (c<<11) ^ (c>>1); + hv ^= (d<<14) + (d<<7) + (d<<4) + d; + } +#elif HASH_ALG == 3 + { + hv = (hv << 4) + *p; + d = hv & 0xf0000000; + if (d != 0) + { + hv ^= (d >> 24); + hv ^= d; + } + } +#else /* HASH_ALG == 1 */ + hv = ((hv << 1) ^ (*p & 0377)) % cctx->cc_size; +#endif /* HASH_ALG == 1 */ + } + + coll = true; + for (i = 0; i < MAX_CT_STEPS; ++i) + { + CHash_T *ch = &CHashAry[(hv + i) & CPMHMASK]; + +#if NETINET + if (saddr->sa.sa_family == AF_INET && + ch->ch_Family == AF_INET && + (saddr->sin.sin_addr.s_addr == ch->ch_Addr4.s_addr || + ch->ch_Addr4.s_addr == 0)) + { + chBest = ch; + coll = false; + break; + } +#endif /* NETINET */ +#if NETINET6 + if (saddr->sa.sa_family == AF_INET6 && + ch->ch_Family == AF_INET6 && + (IN6_ARE_ADDR_EQUAL(&saddr->sin6.sin6_addr, + &ch->ch_Addr6) != 0 || + IN6_IS_ADDR_UNSPECIFIED(&ch->ch_Addr6))) + { + chBest = ch; + coll = false; + break; + } +#endif /* NETINET6 */ + if (chBest == NULL || ch->ch_LTime == 0 || + ch->ch_LTime < chBest->ch_LTime) + chBest = ch; + } + + /* Let's update data... */ + if (update) + { + if (coll && (now - chBest->ch_LTime < CollTime)) + { + /* + ** increment the number of collisions last + ** CollTime for this client + */ + + chBest->ch_colls++; + + /* + ** Maybe shall log if collision rate is too high... + ** and take measures to resize tables + ** if this is the case + */ + } + + /* + ** If it's not a match, then replace the data. + ** Note: this purges the history of a colliding entry, + ** which may cause "overruns", i.e., if two entries are + ** "cancelling" each other out, then they may exceed + ** the limits that are set. This might be mitigated a bit + ** by the above "best of 5" function however. + ** + ** Alternative approach: just use the old data, which may + ** cause false positives however. + ** To activate this, change deactivate following memset call. + */ + + if (coll) + { +#if NETINET + if (saddr->sa.sa_family == AF_INET) + { + chBest->ch_Family = AF_INET; + chBest->ch_Addr4 = saddr->sin.sin_addr; + } +#endif /* NETINET */ +#if NETINET6 + if (saddr->sa.sa_family == AF_INET6) + { + chBest->ch_Family = AF_INET6; + chBest->ch_Addr6 = saddr->sin6.sin6_addr; + } +#endif /* NETINET6 */ +#if 1 + memset(chBest->ch_Times, '\0', + sizeof (chBest->ch_Times)); +#endif /* 1 */ + } + + chBest->ch_LTime = now; + { + CTime_T *ct = &chBest->ch_Times[ticks % CHTSIZE]; + + if (ct->ct_Ticks != ticks) + { + ct->ct_Ticks = ticks; + ct->ct_Count = 0; + } + ++ct->ct_Count; + } + } + + /* Now let's count connections on the window */ + for (i = 0; i < CHTSIZE; ++i) + { + CTime_T *ct = &chBest->ch_Times[i]; + + if (ct->ct_Ticks <= ticks && ct->ct_Ticks >= ticks - CHTSIZE) + cnt += ct->ct_Count; + } + +#if RATECTL_DEBUG + sm_syslog(LOG_WARNING, NOQID, + "cln: cnt=(%d), CHTSIZE=(%d), ChtGran=(%d)", + cnt, CHTSIZE, ChtGran); +#endif /* RATECTL_DEBUG */ + return cnt; +} + +/* +** TOTAL_RATE - Evaluate global connection rate +** +** Parameters: +** now - current time in secs +** update - update data / check only +** +** Returns: +** connection rate (connections / ConnectionRateWindowSize) +*/ + +static CTime_T srv_Times[CHTSIZE]; +static bool srv_Times_OK = false; + +static int +total_rate(now, update) + time_t now; + bool update; +{ + int i; + int cnt = 0; + CTime_T *ct; + unsigned int ticks; + + if (ChtGran < 0) + ChtGran = ConnectionRateWindowSize / CHTSIZE; + if (ChtGran == 0) + ChtGran = 10; + ticks = now / ChtGran; + if (!srv_Times_OK) + { + memset(srv_Times, 0, sizeof(srv_Times)); + srv_Times_OK = true; + } + + /* Let's update data */ + if (update) + { + ct = &srv_Times[ticks % CHTSIZE]; + + if (ct->ct_Ticks != ticks) + { + ct->ct_Ticks = ticks; + ct->ct_Count = 0; + } + ++ct->ct_Count; + } + + /* Let's count connections on the window */ + for (i = 0; i < CHTSIZE; ++i) + { + ct = &srv_Times[i]; + + if (ct->ct_Ticks <= ticks && ct->ct_Ticks >= ticks - CHTSIZE) + cnt += ct->ct_Count; + } + +#if RATECTL_DEBUG + sm_syslog(LOG_WARNING, NOQID, + "srv: cnt=(%d), CHTSIZE=(%d), ChtGran=(%d)", + cnt, CHTSIZE, ChtGran); +#endif /* RATECTL_DEBUG */ + + return cnt; +} + +#if 0 +/* +** SOCKADDRCMP - compare two SOCKADDR structures +** this function may be used to compare SOCKADDR +** structures when using bsearch and qsort functions +** in the same way we do with strcmp +** +** Parameters: +** a, b - addresses +** +** Returns: +** 1 if a > b +** -1 if a < b +** 0 if a = b +** +** OBS: This call isn't used at the moment, it will +** be used when code will be extended to work with IPV6 +*/ + +static int +sockaddrcmp(a, b) + SOCKADDR *a; + SOCKADDR *b; +{ + if (a->sa.sa_family > b->sa.sa_family) + return 1; + if (a->sa.sa_family < b->sa.sa_family) + return -1; + + switch (a->sa.sa_family) + { + case AF_INET: + if (a->sin.sin_addr.s_addr > b->sin.sin_addr.s_addr) + return 1; + if (a->sin.sin_addr.s_addr < b->sin.sin_addr.s_addr) + return -1; + return 0; + break; + + case AF_INET6: + /* TO BE DONE */ + break; + } + return 0; +} +#endif /* 0 */ diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c index 161e7d57f859..49eb12008489 100644 --- a/contrib/sendmail/src/readcf.c +++ b/contrib/sendmail/src/readcf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: readcf.c,v 8.607.2.12 2003/10/07 17:45:28 ca Exp $") +SM_RCSID("@(#)$Id: readcf.c,v 8.641 2004/07/23 20:45:02 gshapiro Exp $") #if NETINET || NETINET6 # include @@ -200,7 +200,8 @@ readcf(cfname, safe, e) expand(&bp[1], exbuf, sizeof exbuf, e); rwp->r_lhs = prescan(exbuf, '\t', pvpbuf, sizeof pvpbuf, NULL, - ConfigLevel >= 9 ? TokTypeNoC : NULL); + ConfigLevel >= 9 ? TokTypeNoC : NULL, + true); nfuzzy = 0; if (rwp->r_lhs != NULL) { @@ -287,7 +288,8 @@ readcf(cfname, safe, e) expand(q, exbuf, sizeof exbuf, e); rwp->r_rhs = prescan(exbuf, '\t', pvpbuf, sizeof pvpbuf, NULL, - ConfigLevel >= 9 ? TokTypeNoC : NULL); + ConfigLevel >= 9 ? TokTypeNoC : NULL, + true); if (rwp->r_rhs != NULL) { register char **ap; @@ -960,7 +962,7 @@ fileclass(class, filename, fmt, ismap, safe, optional) cl = "ldap"; n = sm_snprintf(buf, sizeof buf, - "-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=%s)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))) -v sendmailMTAClassValue", + "-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=%s)(|(sendmailMTACluster=%s)(sendmailMTAHost=%s))) -v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass", mn, lc, jbuf); if (n >= sizeof buf) { @@ -1185,6 +1187,8 @@ makemailer(line) } m->m_name = newstr(line); m->m_qgrp = NOQGRP; + m->m_uid = NO_UID; + m->m_gid = NO_GID; /* now scan through and assign info from the fields */ while (*p != '\0') @@ -1793,17 +1797,14 @@ printrules() { if (RewriteRules[ruleset] == NULL) continue; - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - "\n----Rule Set %d:", ruleset); + sm_dprintf("\n----Rule Set %d:", ruleset); for (rwp = RewriteRules[ruleset]; rwp != NULL; rwp = rwp->r_next) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - "\nLHS:"); - printav(rwp->r_lhs); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - "RHS:"); - printav(rwp->r_rhs); + sm_dprintf("\nLHS:"); + printav(sm_debug_file(), rwp->r_lhs); + sm_dprintf("RHS:"); + printav(sm_debug_file(), rwp->r_rhs); } } } @@ -1811,6 +1812,7 @@ printrules() ** PRINTMAILER -- print mailer structure (for debugging) ** ** Parameters: +** fp -- output file ** m -- the mailer to print ** ** Returns: @@ -1818,71 +1820,72 @@ printrules() */ void -printmailer(m) +printmailer(fp, m) + SM_FILE_T *fp; register MAILER *m; { int j; - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "mailer %d (%s): P=%s S=", m->m_mno, m->m_name, m->m_mailer); if (RuleSetNames[m->m_se_rwset] == NULL) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%d/", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", m->m_se_rwset); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s/", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", RuleSetNames[m->m_se_rwset]); if (RuleSetNames[m->m_sh_rwset] == NULL) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%d R=", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d R=", m->m_sh_rwset); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s R=", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s R=", RuleSetNames[m->m_sh_rwset]); if (RuleSetNames[m->m_re_rwset] == NULL) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%d/", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d/", m->m_re_rwset); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s/", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s/", RuleSetNames[m->m_re_rwset]); if (RuleSetNames[m->m_rh_rwset] == NULL) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%d ", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%d ", m->m_rh_rwset); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s ", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s ", RuleSetNames[m->m_rh_rwset]); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "M=%ld U=%d:%d F=", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "M=%ld U=%d:%d F=", m->m_maxsize, (int) m->m_uid, (int) m->m_gid); for (j = '\0'; j <= '\177'; j++) if (bitnset(j, m->m_flags)) - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, j); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " L=%d E=", + (void) sm_io_putc(fp, SM_TIME_DEFAULT, j); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " L=%d E=", m->m_linelimit); - xputs(m->m_eol); + xputs(fp, m->m_eol); if (m->m_defcharset != NULL) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " C=%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " C=%s", m->m_defcharset); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " T=%s/%s/%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " T=%s/%s/%s", m->m_mtatype == NULL ? "" : m->m_mtatype, m->m_addrtype == NULL ? "" : m->m_addrtype, m->m_diagtype == NULL ? "" : m->m_diagtype); - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " r=%d", m->m_maxrcpt); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " r=%d", m->m_maxrcpt); if (m->m_argv != NULL) { char **a = m->m_argv; - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " A="); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " A="); while (*a != NULL) { if (a != m->m_argv) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, " "); - xputs(*a++); + xputs(fp, *a++); } } - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\n"); } /* ** SETOPTION -- set global processing option @@ -2103,10 +2106,6 @@ static struct optioninfo { "XscriptFileBufferSize", O_XF_BUFSIZE, OI_NONE }, #define O_LDAPDEFAULTSPEC 0xb2 { "LDAPDefaultSpec", O_LDAPDEFAULTSPEC, OI_NONE }, -#if _FFR_QUEUEDELAY -# define O_QUEUEDELAY 0xb3 - { "QueueDelay", O_QUEUEDELAY, OI_NONE }, -#endif /* _FFR_QUEUEDELAY */ #define O_SRVCERTFILE 0xb4 { "ServerCertFile", O_SRVCERTFILE, OI_NONE }, #define O_SRVKEYFILE 0xb5 @@ -2171,14 +2170,27 @@ static struct optioninfo # define O_SHMKEYFILE 0xd0 { "SharedMemoryKeyFile", O_SHMKEYFILE, OI_NONE }, #endif /* _FFR_SELECT_SHM */ -#if _FFR_REJECT_LOG -# define O_REJECTLOGINTERVAL 0xd1 +#define O_REJECTLOGINTERVAL 0xd1 { "RejectLogInterval", O_REJECTLOGINTERVAL, OI_NONE }, -#endif /* _FFR_REJECT_LOG */ -#if _FFR_REQ_DIR_FSYNC_OPT -# define O_REQUIRES_DIR_FSYNC 0xd2 +#define O_REQUIRES_DIR_FSYNC 0xd2 { "RequiresDirfsync", O_REQUIRES_DIR_FSYNC, OI_NONE }, -#endif /* _FFR_REQ_DIR_FSYNC_OPT */ +#define O_CONNECTION_RATE_WINDOW_SIZE 0xd3 + { "ConnectionRateWindowSize", O_CONNECTION_RATE_WINDOW_SIZE, OI_NONE }, +#define O_CRLFILE 0xd4 + { "CRLFile", O_CRLFILE, OI_NONE }, +#define O_FALLBACKSMARTHOST 0xd5 + { "FallbackSmartHost", O_FALLBACKSMARTHOST, OI_NONE }, +#define O_SASLREALM 0xd6 + { "AuthRealm", O_SASLREALM, OI_NONE }, +#if _FFR_CRLPATH +# define O_CRLPATH 0xd7 + { "CRLPath", O_CRLPATH, OI_NONE }, +#endif /* _FFR_CRLPATH */ +#if _FFR_HELONAME +# define O_HELONAME 0xd8 + { "HeloName", O_HELONAME, OI_NONE }, +#endif /* _FFR_HELONAME */ + { NULL, '\0', OI_NONE } }; @@ -2318,7 +2330,7 @@ setoption(opt, val, safe, sticky, e) "setoption %s (0x%x)%s%s=", OPTNAME, opt, subopt == NULL ? "" : ".", subopt == NULL ? "" : subopt); - xputs(val); + xputs(sm_debug_file(), val); } /* @@ -2444,7 +2456,8 @@ setoption(opt, val, safe, sticky, e) break; case 'C': /* checkpoint every N addresses */ - CheckpointInterval = atoi(val); + if (safe || CheckpointInterval > atoi(val)) + CheckpointInterval = atoi(val); break; case 'd': /* delivery mode */ @@ -2726,6 +2739,13 @@ setoption(opt, val, safe, sticky, e) case 's': /* be super safe, even if expensive */ if (tolower(*val) == 'i') SuperSafe = SAFE_INTERACTIVE; + else if (tolower(*val) == 'p') +#if MILTER + SuperSafe = SAFE_REALLY_POSTMILTER; +#else /* MILTER */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n"); +#endif /* MILTER */ else SuperSafe = atobool(val) ? SAFE_REALLY : SAFE_NO; break; @@ -2802,7 +2822,7 @@ setoption(opt, val, safe, sticky, e) case 'V': /* fallback MX host */ if (val[0] != '\0') - FallBackMX = newstr(val); + FallbackMX = newstr(val); break; case 'v': /* run in verbose mode */ @@ -2887,48 +2907,16 @@ setoption(opt, val, safe, sticky, e) break; #endif /* _FFR_RHS */ + case 'n': /* none */ + case 'N': + QueueSortOrder = QSO_NONE; + break; + default: syserr("Invalid queue sort order \"%s\"", val); } break; -#if _FFR_QUEUEDELAY - case O_QUEUEDELAY: /* queue delay algorithm */ - switch (*val) - { - case 'e': /* exponential */ - case 'E': - QueueAlg = QD_EXP; - QueueInitDelay = 10 MINUTES; - QueueMaxDelay = 2 HOURS; - p = strchr(val, '/'); - if (p != NULL) - { - char *q; - - *p++ = '\0'; - q = strchr(p, '/'); - if (q != NULL) - *q++ = '\0'; - QueueInitDelay = convtime(p, 's'); - if (q != NULL) - { - QueueMaxDelay = convtime(q, 's'); - } - } - break; - - case 'l': /* linear */ - case 'L': - QueueAlg = QD_LINEAR; - break; - - default: - syserr("Invalid queue delay algorithm \"%s\"", val); - } - break; -#endif /* _FFR_QUEUEDELAY */ - case O_HOSTSFILE: /* pathname of /etc/hosts file */ CANONIFY(val); HostsFile = newstr(val); @@ -3408,6 +3396,15 @@ setoption(opt, val, safe, sticky, e) AuthMechanisms = NULL; break; + case O_SASLREALM: + if (AuthRealm != NULL) + sm_free(AuthRealm); + if (*val != '\0') + AuthRealm = newstr(val); + else + AuthRealm = NULL; + break; + case O_SASLOPTS: while (val != NULL && *val != '\0') { @@ -3433,14 +3430,11 @@ setoption(opt, val, safe, sticky, e) SASLOpts |= SASL_SEC_FORWARD_SECRECY; break; -# if _FFR_SASL_OPT_M -/* to be activated in 8.13 */ # if SASL >= 20101 case 'm': SASLOpts |= SASL_SEC_MUTUAL_AUTH; break; # endif /* SASL >= 20101 */ -# endif /* _FFR_SASL_OPT_M */ case 'p': SASLOpts |= SASL_SEC_NOPLAINTEXT; @@ -3478,6 +3472,7 @@ setoption(opt, val, safe, sticky, e) #else /* SASL */ case O_SASLINFO: case O_SASLMECH: + case O_SASLREALM: case O_SASLOPTS: case O_SASLBITS: (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, @@ -3507,6 +3502,27 @@ setoption(opt, val, safe, sticky, e) case O_CIPHERLIST: SET_STRING_EXP(CipherList); # endif /* _FFR_TLS_1 */ + case O_CRLFILE: +# if OPENSSL_VERSION_NUMBER > 0x00907000L + SET_STRING_EXP(CRLFile); +# else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Warning: Option: %s requires at least OpenSSL 0.9.7\n", + OPTNAME); + break; +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ + +# if _FFR_CRLPATH + case O_CRLPATH: +# if OPENSSL_VERSION_NUMBER > 0x00907000L + SET_STRING_EXP(CRLPath); +# else /* OPENSSL_VERSION_NUMBER > 0x00907000L */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Warning: Option: %s requires at least OpenSSL 0.9.7\n", + OPTNAME); + break; +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ +# endif /* _FFR_CRLPATH */ /* ** XXX How about options per daemon/client instead of globally? @@ -3575,6 +3591,10 @@ setoption(opt, val, safe, sticky, e) case O_DHPARAMS5: case O_CIPHERLIST: # endif /* _FFR_TLS_1 */ + case O_CRLFILE: +# if _FFR_CRLPATH + case O_CRLPATH: +# endif /* _FFR_CRLPATH */ case O_RANDFILE: (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "Warning: Option: %s requires TLS support\n", @@ -3663,21 +3683,32 @@ setoption(opt, val, safe, sticky, e) break; #endif /* _FFR_SOFT_BOUNCE */ -#if _FFR_REJECT_LOG case O_REJECTLOGINTERVAL: /* time btwn log msgs while refusing */ RejectLogInterval = convtime(val, 'h'); break; -#endif /* _FFR_REJECT_LOG */ -#if _FFR_REQ_DIR_FSYNC_OPT case O_REQUIRES_DIR_FSYNC: -# if REQUIRES_DIR_FSYNC +#if REQUIRES_DIR_FSYNC RequiresDirfsync = atobool(val); -# else /* REQUIRES_DIR_FSYNC */ +#else /* REQUIRES_DIR_FSYNC */ /* silently ignored... required for cf file option */ -# endif /* REQUIRES_DIR_FSYNC */ +#endif /* REQUIRES_DIR_FSYNC */ break; -#endif /* _FFR_REQ_DIR_FSYNC_OPT */ + + case O_CONNECTION_RATE_WINDOW_SIZE: + ConnectionRateWindowSize = convtime(val, 's'); + break; + + case O_FALLBACKSMARTHOST: /* fallback smart host */ + if (val[0] != '\0') + FallbackSmartHost = newstr(val); + break; + +#if _FFR_HELONAME + case O_HELONAME: + HeloName = newstr(val); + break; +#endif /* _FFR_HELONAME */ default: if (tTd(37, 1)) @@ -4047,12 +4078,10 @@ static struct timeoutinfo { "starttls", TO_STARTTLS }, #define TO_ACONNECT 0x23 { "aconnect", TO_ACONNECT }, -#if _FFR_QUEUERETURN_DSN -# define TO_QUEUEWARN_DSN 0x24 +#define TO_QUEUEWARN_DSN 0x24 { "queuewarn.dsn", TO_QUEUEWARN_DSN }, -# define TO_QUEUERETURN_DSN 0x25 +#define TO_QUEUERETURN_DSN 0x25 { "queuereturn.dsn", TO_QUEUERETURN_DSN }, -#endif /* _FFR_QUEUERETURN_DSN */ { NULL, 0 }, }; @@ -4171,9 +4200,7 @@ settimeout(name, val, sticky) TimeOuts.to_q_warning[TOC_NORMAL] = toval; TimeOuts.to_q_warning[TOC_URGENT] = toval; TimeOuts.to_q_warning[TOC_NONURGENT] = toval; -#if _FFR_QUEUERETURN_DSN TimeOuts.to_q_warning[TOC_DSN] = toval; -#endif /* _FFR_QUEUERETURN_DSN */ addopts = 2; break; @@ -4192,21 +4219,17 @@ settimeout(name, val, sticky) TimeOuts.to_q_warning[TOC_NONURGENT] = toval; break; -#if _FFR_QUEUERETURN_DSN case TO_QUEUEWARN_DSN: toval = convtime(val, 'h'); TimeOuts.to_q_warning[TOC_DSN] = toval; break; -#endif /* _FFR_QUEUERETURN_DSN */ case TO_QUEUERETURN: toval = convtime(val, 'd'); TimeOuts.to_q_return[TOC_NORMAL] = toval; TimeOuts.to_q_return[TOC_URGENT] = toval; TimeOuts.to_q_return[TOC_NONURGENT] = toval; -#if _FFR_QUEUERETURN_DSN TimeOuts.to_q_return[TOC_DSN] = toval; -#endif /* _FFR_QUEUERETURN_DSN */ addopts = 2; break; @@ -4225,12 +4248,10 @@ settimeout(name, val, sticky) TimeOuts.to_q_return[TOC_NONURGENT] = toval; break; -#if _FFR_QUEUERETURN_DSN case TO_QUEUERETURN_DSN: toval = convtime(val, 'd'); TimeOuts.to_q_return[TOC_DSN] = toval; break; -#endif /* _FFR_QUEUERETURN_DSN */ case TO_HOSTSTATUS: MciInfoTimeout = toval; diff --git a/contrib/sendmail/src/recipient.c b/contrib/sendmail/src/recipient.c index b7b6660df1cc..02ef8d76eb80 100644 --- a/contrib/sendmail/src/recipient.c +++ b/contrib/sendmail/src/recipient.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: recipient.c,v 8.330.2.4 2003/10/06 20:43:29 ca Exp $") +SM_RCSID("@(#)$Id: recipient.c,v 8.336 2004/07/23 20:45:02 gshapiro Exp $") static void includetimeout __P((void)); static ADDRESS *self_reference __P((ADDRESS *)); @@ -183,7 +183,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e) if (tTd(25, 1)) { sm_dprintf("sendto: %s\n ctladdr=", list); - printaddr(ctladdr, false); + printaddr(sm_debug_file(), ctladdr, false); } /* heuristic to determine old versus new style addresses */ @@ -245,7 +245,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e) if (tTd(27, 5)) { sm_dprintf("sendtolist: QSELFREF "); - printaddr(ctladdr, false); + printaddr(sm_debug_file(), ctladdr, false); } ctladdr->q_flags |= QSELFREF; } @@ -258,14 +258,14 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e) if (tTd(27, 5)) { sm_dprintf("sendtolist: QSELFREF "); - printaddr(b, false); + printaddr(sm_debug_file(), b, false); } if (a != b) { if (tTd(27, 5)) { sm_dprintf("sendtolist: QS_DONTSEND "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } a->q_state = QS_DONTSEND; b->q_flags |= a->q_flags & QNOTREMOTE; @@ -403,7 +403,7 @@ removefromlist(list, sendq, e) if (tTd(25, 5)) { sm_dprintf("removefromlist: QS_REMOVED "); - printaddr(&a, false); + printaddr(sm_debug_file(), &a, false); } q->q_state = QS_REMOVED; naddrs++; @@ -476,7 +476,7 @@ recipient(new, sendq, aliaslevel, e) if (tTd(26, 1)) { sm_dprintf("\nrecipient (%d): ", aliaslevel); - printaddr(new, false); + printaddr(sm_debug_file(), new, false); } /* if this is primary, use it as original recipient */ @@ -727,7 +727,7 @@ recipient(new, sendq, aliaslevel, e) { sm_dprintf("%s in sendq: ", new->q_paddr); - printaddr(q, false); + printaddr(sm_debug_file(), q, false); } if (!bitset(QPRIMARY, q->q_flags)) { @@ -800,7 +800,7 @@ recipient(new, sendq, aliaslevel, e) if (tTd(29, 7)) { sm_dprintf("at trylocaluser: "); - printaddr(new, false); + printaddr(sm_debug_file(), new, false); } if (!QS_IS_OK(new->q_state)) @@ -930,7 +930,7 @@ recipient(new, sendq, aliaslevel, e) { sm_dprintf("recipient: testing local? cl=%d, rr5=%p\n\t", ConfigLevel, RewriteRules[5]); - printaddr(new, false); + printaddr(sm_debug_file(), new, false); } if (ConfigLevel >= 2 && RewriteRules[5] != NULL && bitnset(M_TRYRULESET5, m->m_flags) && @@ -1028,11 +1028,11 @@ recipient(new, sendq, aliaslevel, e) if (tTd(26, 8)) { sm_dprintf("testselfdestruct: "); - printaddr(new, false); + printaddr(sm_debug_file(), new, false); if (tTd(26, 10)) { sm_dprintf("SENDQ:\n"); - printaddr(*sendq, true); + printaddr(sm_debug_file(), *sendq, true); sm_dprintf("----\n"); } } @@ -1309,9 +1309,20 @@ writable(filename, ctladdr, flags) } else if (FileMailer != NULL && !bitset(SFF_ROOTOK, flags)) { - euid = FileMailer->m_uid; - egid = FileMailer->m_gid; - user = NULL; + if (FileMailer->m_uid == NO_UID) + { + euid = DefUid; + user = DefUser; + } + else + { + euid = FileMailer->m_uid; + user = NULL; + } + if (FileMailer->m_gid == NO_GID) + egid = DefGid; + else + egid = FileMailer->m_gid; } else { @@ -1417,7 +1428,7 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e) if (tTd(27, 14)) { sm_dprintf("ctladdr "); - printaddr(ctladdr, false); + printaddr(sm_debug_file(), ctladdr, false); } if (tTd(27, 9)) @@ -1850,7 +1861,7 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e) if (tTd(27, 5)) { sm_dprintf("include: QS_DONTSEND "); - printaddr(ctladdr, false); + printaddr(sm_debug_file(), ctladdr, false); } ctladdr->q_state = QS_DONTSEND; } diff --git a/contrib/sendmail/src/sasl.c b/contrib/sendmail/src/sasl.c index 4b30f4748793..e2bf415275f2 100644 --- a/contrib/sendmail/src/sasl.c +++ b/contrib/sendmail/src/sasl.c @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: sasl.c,v 8.19.2.2 2002/09/26 23:03:40 gshapiro Exp $") +SM_RCSID("@(#)$Id: sasl.c,v 8.20 2004/06/02 22:48:06 ca Exp $") #if SASL # include @@ -208,7 +208,7 @@ intersect(s1, s2, rpool) # if SASL >= 20000 /* ** IPTOSTRING -- create string for SASL_IP*PORT property -** (borrowed from lib/iptostring.c in Cyrus-IMAP) +** (borrowed from lib/iptostring.c in Cyrus-IMAP) ** ** Parameters: ** addr -- (pointer to) socket address diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h index 2e1b732dc7d0..306605ef4abb 100644 --- a/contrib/sendmail/src/sendmail.h +++ b/contrib/sendmail/src/sendmail.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -17,6 +17,10 @@ #ifndef _SENDMAIL_H # define _SENDMAIL_H 1 +#ifndef MILTER +# define MILTER 1 /* turn on MILTER by default */ +#endif /* MILTER */ + #ifdef _DEFINE # define EXTERN #else /* _DEFINE */ @@ -48,7 +52,7 @@ #ifdef _DEFINE # ifndef lint -SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.919.2.29 2003/11/07 00:08:02 ca Exp $"; +SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.984 2004/07/14 21:54:22 ca Exp $"; # endif /* ! lint */ #endif /* _DEFINE */ @@ -336,8 +340,8 @@ extern int include __P((char *, bool, ADDRESS *, ADDRESS **, int, ENVELOPE *)); extern bool invalidaddr __P((char *, char *, bool)); extern ADDRESS *parseaddr __P((char *, ADDRESS *, int, int, char **, ENVELOPE *, bool)); -extern char **prescan __P((char *, int, char[], int, char **, unsigned char *)); -extern void printaddr __P((ADDRESS *, bool)); +extern char **prescan __P((char *, int, char[], int, char **, unsigned char *, bool)); +extern void printaddr __P((SM_FILE_T *, ADDRESS *, bool)); extern ADDRESS *recipient __P((ADDRESS *, ADDRESS **, int, ENVELOPE *)); extern char *remotename __P((char *, MAILER *, int, int *, ENVELOPE *)); extern int rewrite __P((char **, int, int, ENVELOPE *, int)); @@ -396,9 +400,7 @@ struct mailer #define M_ESMTP 'a' /* run Extended SMTP */ #define M_ALIASABLE 'A' /* user can be LHS of an alias */ #define M_BLANKEND 'b' /* ensure blank line at end of message */ -#if _FFR_STRIPBACKSL -# define M_STRIPBACKSL 'B' /* strip leading backslash from user */ -#endif /* _FFR_STRIPBACKSL */ +#define M_STRIPBACKSL 'B' /* strip leading backslash from user */ #define M_NOCOMMENT 'c' /* don't include comment part of address */ #define M_CANONICAL 'C' /* make addresses canonical "u@dom" */ #define M_NOBRACKET 'd' /* never angle bracket envelope route-addrs */ @@ -434,6 +436,7 @@ struct mailer #define M_CONTENT_LEN 'v' /* add Content-Length: header (SVr4) */ /* 'V' UIUC: !-relativize all addresses */ #define M_HASPWENT 'w' /* check for /etc/passwd entry */ +#define M_NOHOSTSTAT 'W' /* ignore long term host status information */ /* 'x' CF: include Full-Name: */ #define M_XDOT 'X' /* use hidden-dot algorithm */ #define M_LMTP 'z' /* run Local Mail Transport Protocol */ @@ -610,6 +613,7 @@ extern void stop_sasl_client __P((void)); typedef char *SASL_AI_T[SASL_ENTRIES]; EXTERN char *AuthMechanisms; /* AUTH mechanisms */ +EXTERN char *AuthRealm; /* AUTH realm */ EXTERN char *SASLInfo; /* file with AUTH info */ EXTERN int SASLOpts; /* options for SASL */ EXTERN int MaxSLBits; /* max. encryption bits for SASL */ @@ -724,8 +728,8 @@ MCI /* functions */ extern void mci_cache __P((MCI *)); -extern void mci_dump __P((MCI *, bool)); -extern void mci_dump_all __P((bool)); +extern void mci_dump __P((SM_FILE_T *, MCI *, bool)); +extern void mci_dump_all __P((SM_FILE_T *, bool)); extern void mci_flush __P((bool, MCI *)); extern MCI *mci_get __P((char *, MAILER *)); extern int mci_lock_host __P((MCI *)); @@ -808,6 +812,7 @@ extern void commaize __P((HDR *, char *, bool, MCI *, ENVELOPE *)); extern HDR *copyheader __P((HDR *, SM_RPOOL_T *)); extern void eatheader __P((ENVELOPE *, bool, bool)); extern char *hvalue __P((char *, HDR *)); +extern void insheader __P((int, char *, char *, int, ENVELOPE *)); extern bool isheader __P((char *)); extern void putfromline __P((MCI *, ENVELOPE *)); extern void setupheaders __P((void)); @@ -887,10 +892,8 @@ struct envelope char *e_statmsg; /* stat msg (changes per delivery). * readonly. NULL or allocated from * e_rpool. */ -#if _FFR_QUARANTINE char *e_quarmsg; /* why envelope is quarantined */ char e_qfletter; /* queue file letter on disk */ -#endif /* _FFR_QUARANTINE */ char *e_msgboundary; /* MIME-style message part boundary */ char *e_origrcpt; /* original recipient (one only) */ char *e_envid; /* envelope id from MAIL FROM: line */ @@ -904,10 +907,6 @@ struct envelope char *e_auth_param; /* readonly; NULL or static storage or * allocated from e_rpool */ TIMERS e_timers; /* per job timers */ -#if _FFR_QUEUEDELAY - int e_queuealg; /* algorithm for queue delay */ - time_t e_queuedelay; /* current delay */ -#endif /* _FFR_QUEUEDELAY */ long e_deliver_by; /* deliver by */ int e_dlvr_flag; /* deliver by flag */ SM_RPOOL_T *e_rpool; /* resource pool for this envelope */ @@ -1333,6 +1332,52 @@ struct ph_map_struct typedef struct ph_map_struct PH_MAP_STRUCT; #endif /* PH_MAP */ + +/* +** Regular UNIX sockaddrs are too small to handle ISO addresses, so +** we are forced to declare a supertype here. +*/ + +#if NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 +union bigsockaddr +{ + struct sockaddr sa; /* general version */ +# if NETUNIX + struct sockaddr_un sunix; /* UNIX family */ +# endif /* NETUNIX */ +# if NETINET + struct sockaddr_in sin; /* INET family */ +# endif /* NETINET */ +# if NETINET6 + struct sockaddr_in6 sin6; /* INET/IPv6 */ +# endif /* NETINET6 */ +# if NETISO + struct sockaddr_iso siso; /* ISO family */ +# endif /* NETISO */ +# if NETNS + struct sockaddr_ns sns; /* XNS family */ +# endif /* NETNS */ +# if NETX25 + struct sockaddr_x25 sx25; /* X.25 family */ +# endif /* NETX25 */ +}; + +# define SOCKADDR union bigsockaddr + +/* functions */ +extern char *anynet_ntoa __P((SOCKADDR *)); +# if NETINET6 +extern char *anynet_ntop __P((struct in6_addr *, char *, size_t)); +extern int anynet_pton __P((int, const char *, void *)); +# endif /* NETINET6 */ +extern char *hostnamebyanyaddr __P((SOCKADDR *)); +extern char *validate_connection __P((SOCKADDR *, char *, ENVELOPE *)); +# if SASL >= 20000 +extern bool iptostring __P((SOCKADDR *, SOCKADDR_LEN_T, char *, unsigned)); +# endif /* SASL >= 20000 */ + +#endif /* NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 */ + /* ** Process List (proclist) */ @@ -1352,7 +1397,7 @@ typedef struct ph_map_struct PH_MAP_STRUCT; #define PROC_CONTROL_CHILD 5 /* functions */ -extern void proc_list_add __P((pid_t, char *, int, int, int)); +extern void proc_list_add __P((pid_t, char *, int, int, int, SOCKADDR *)); extern void proc_list_clear __P((void)); extern void proc_list_display __P((SM_FILE_T *, char *)); extern void proc_list_drop __P((pid_t, int, int *)); @@ -1387,6 +1432,9 @@ struct symtab #if LDAPMAP MAP *sv_lmap; /* Maps for LDAP connection */ #endif /* LDAPMAP */ +#if SOCKETMAP + MAP *sv_socketmap; /* Maps for SOCKET connection */ +#endif /* SOCKETMAP */ #if MILTER struct milter *sv_milter; /* milter filter name */ #endif /* MILTER */ @@ -1418,8 +1466,12 @@ typedef struct symtab STAB; #endif /* MILTER */ #define ST_QUEUE 15 /* a queue entry */ +#if SOCKETMAP +# define ST_SOCKETMAP 16 /* List head of maps for SOCKET connection */ +#endif /* SOCKETMAP */ + /* This entry must be last */ -#define ST_MCI 16 /* mailer connection info (offset) */ +#define ST_MCI 17 /* mailer connection info (offset) */ #define s_class s_value.sv_class #define s_address s_value.sv_addr @@ -1437,6 +1489,9 @@ typedef struct symtab STAB; #if LDAPMAP # define s_lmap s_value.sv_lmap #endif /* LDAPMAP */ +#if SOCKETMAP +# define s_socketmap s_value.sv_socketmap +#endif /* SOCKETMAP */ #if MILTER # define s_milter s_value.sv_milter #endif /* MILTER */ @@ -1605,51 +1660,6 @@ extern int mime8to7 __P((MCI *, HDR *, ENVELOPE *, char **, int)); /* functions */ extern int returntosender __P((char *, ADDRESS *, int, ENVELOPE *)); -/* -** Regular UNIX sockaddrs are too small to handle ISO addresses, so -** we are forced to declare a supertype here. -*/ - -#if NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 -union bigsockaddr -{ - struct sockaddr sa; /* general version */ -# if NETUNIX - struct sockaddr_un sunix; /* UNIX family */ -# endif /* NETUNIX */ -# if NETINET - struct sockaddr_in sin; /* INET family */ -# endif /* NETINET */ -# if NETINET6 - struct sockaddr_in6 sin6; /* INET/IPv6 */ -# endif /* NETINET6 */ -# if NETISO - struct sockaddr_iso siso; /* ISO family */ -# endif /* NETISO */ -# if NETNS - struct sockaddr_ns sns; /* XNS family */ -# endif /* NETNS */ -# if NETX25 - struct sockaddr_x25 sx25; /* X.25 family */ -# endif /* NETX25 */ -}; - -# define SOCKADDR union bigsockaddr - -/* functions */ -extern char *anynet_ntoa __P((SOCKADDR *)); -# if NETINET6 -extern char *anynet_ntop __P((struct in6_addr *, char *, size_t)); -extern int anynet_pton __P((int, const char *, void *)); -# endif /* NETINET6 */ -extern char *hostnamebyanyaddr __P((SOCKADDR *)); -extern char *validate_connection __P((SOCKADDR *, char *, ENVELOPE *)); -# if SASL >= 20000 -extern bool iptostring __P((SOCKADDR *, SOCKADDR_LEN_T, char *, unsigned)); -# endif /* SASL >= 20000 */ - -#endif /* NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 */ - /* ** Mail Filters (milter) */ @@ -1699,10 +1709,8 @@ EXTERN struct milter *InputFilters[MAXFILTERS]; EXTERN char *InputFilterList; EXTERN int MilterLogLevel; -# if _FFR_MILTER_PERDAEMON /* functions */ extern void setup_daemon_milters __P((void)); -# endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ /* @@ -1759,9 +1767,7 @@ struct termescape #define D_IFNHELO 'h' /* use if name for HELO */ #define D_FQMAIL 'f' /* fq sender address required (cf) */ #define D_FQRCPT 'r' /* fq recipient address required (cf) */ -#if _FFR_SMTP_SSL -# define D_SMTPS 's' /* SMTP over SSL (smtps) */ -#endif /* _FFR_SMTP_SSL */ +#define D_SMTPS 's' /* SMTP over SSL (smtps) */ #define D_UNQUALOK 'u' /* unqualified address is ok (cf) */ #define D_NOAUTH 'A' /* no AUTH */ #define D_NOCANON 'C' /* no canonification (cf) */ @@ -1802,6 +1808,8 @@ struct termescape #define TLS_I_DH2048 0x00100000 /* generate 2048bit DH param */ #define TLS_I_NO_VRFY 0x00200000 /* do not require authentication */ #define TLS_I_KEY_OUNR 0x00400000 /* Key must be other unreadable */ +#define TLS_I_CRLF_EX 0x00800000 /* CRL file must exist */ +#define TLS_I_CRLF_UNR 0x01000000 /* CRL file must be g/o unreadable */ /* require server cert */ #define TLS_I_SRV_CERT (TLS_I_CERT_EX | TLS_I_KEY_EX | \ @@ -1843,6 +1851,10 @@ EXTERN char *DHParams; /* file with DH parameters */ EXTERN char *RandFile; /* source of random data */ EXTERN char *SrvCertFile; /* file with server certificate */ EXTERN char *SrvKeyFile; /* file with server private key */ +EXTERN char *CRLFile; /* file CRLs */ +#if _FFR_CRLPATH +EXTERN char *CRLPath; /* path to CRLs (dir. with hashes) */ +#endif /* _FFR_CRLPATH */ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ #endif /* STARTTLS */ @@ -1851,13 +1863,8 @@ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ */ /* queue file names */ -#if _FFR_QUARANTINE -# define ANYQFL_LETTER '?' -# define QUARQF_LETTER 'h' -#else /* _FFR_QUARANTINE */ -/* Before quarantining, ANYQF == NORMQF */ -# define ANYQFL_LETTER 'q' -#endif /* _FFR_QUARANTINE */ +#define ANYQFL_LETTER '?' +#define QUARQF_LETTER 'h' #define DATAFL_LETTER 'd' #define XSCRPT_LETTER 'x' #define NORMQF_LETTER 'q' @@ -1873,15 +1880,11 @@ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ #define QSO_BYFILENAME 3 /* sort by file name only */ #define QSO_RANDOM 4 /* sort in random order */ #define QSO_BYMODTIME 5 /* sort by modification time */ +#define QSO_NONE 6 /* do not sort */ #if _FFR_RHS -# define QSO_BYSHUFFLE 6 /* sort by shuffled host name */ +# define QSO_BYSHUFFLE 7 /* sort by shuffled host name */ #endif /* _FFR_RHS */ -#if _FFR_QUEUEDELAY -# define QD_LINEAR 0 /* linear (old) delay alg */ -# define QD_EXP 1 /* exponential delay alg */ -#endif /* _FFR_QUEUEDELAY */ - #define NOQGRP (-1) /* no queue group (yet) */ #define ENVQGRP (-2) /* use queue group of envelope */ #define NOAQGRP (-3) /* no queue group in addr (yet) */ @@ -1898,13 +1901,12 @@ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ #define SAFE_NO 0 /* no fsync(): don't use... */ #define SAFE_INTERACTIVE 1 /* limit fsync() in -odi */ #define SAFE_REALLY 2 /* always fsync() */ +#define SAFE_REALLY_POSTMILTER 3 /* fsync() if milter says OK */ -#if _FFR_QUARANTINE /* QueueMode bits */ -# define QM_NORMAL ' ' -# define QM_QUARANTINE 'Q' -# define QM_LOST 'L' -#endif /* _FFR_QUARANTINE */ +#define QM_NORMAL ' ' +#define QM_QUARANTINE 'Q' +#define QM_LOST 'L' /* Queue Run Limitations */ struct queue_char @@ -1931,22 +1933,13 @@ EXTERN int MaxRunnersPerQueue; /* max # proc's active in queue group */ EXTERN int NiceQueueRun; /* nice queue runs to this value */ EXTERN int NumQueue; /* number of queue groups */ EXTERN int QueueFileMode; /* mode on files in mail queue */ -#if _FFR_QUARANTINE EXTERN int QueueMode; /* which queue items to act upon */ -#endif /* _FFR_QUARANTINE */ EXTERN int QueueSortOrder; /* queue sorting order algorithm */ EXTERN time_t MinQueueAge; /* min delivery interval */ EXTERN time_t QueueIntvl; /* intervals between running the queue */ EXTERN char *QueueDir; /* location of queue directory */ -#if _FFR_QUEUEDELAY -EXTERN int QueueAlg; /* algorithm for queue delays */ -EXTERN time_t QueueInitDelay; /* initial queue delay */ -EXTERN time_t QueueMaxDelay; /* maximum queue delay */ -#endif /* _FFR_QUEUEDELAY */ EXTERN QUEUE_CHAR *QueueLimitId; /* limit queue run to id */ -#if _FFR_QUARANTINE EXTERN QUEUE_CHAR *QueueLimitQuarantine; /* limit queue run to quarantine reason */ -#endif /* _FFR_QUARANTINE */ EXTERN QUEUE_CHAR *QueueLimitRecipient; /* limit queue run to rcpt */ EXTERN QUEUE_CHAR *QueueLimitSender; /* limit queue run to sender */ EXTERN QUEUEGRP *Queue[MAXQUEUEGROUPS + 1]; /* queue groups */ @@ -1961,9 +1954,7 @@ extern void loseqfile __P((ENVELOPE *, char *)); extern int name2qid __P((char *)); extern char *qid_printname __P((ENVELOPE *)); extern char *qid_printqueue __P((int, int)); -#if _FFR_QUARANTINE extern void quarantine_queue __P((char *, int)); -#endif /* _FFR_QUARANTINE */ extern char *queuename __P((ENVELOPE *, int)); extern void queueup __P((ENVELOPE *, bool, bool)); extern bool runqueue __P((bool, bool, bool, bool)); @@ -2027,9 +2018,7 @@ EXTERN struct #define TOC_NORMAL 0 /* normal delivery */ #define TOC_URGENT 1 /* urgent delivery */ #define TOC_NONURGENT 2 /* non-urgent delivery */ -#if _FFR_QUEUERETURN_DSN -# define TOC_DSN 3 /* DSN delivery */ -#endif /* _FFR_QUEUERETURN_DSN */ +#define TOC_DSN 3 /* DSN delivery */ /* resolver timeout specifiers */ #define RES_TO_FIRST 0 /* first attempt */ @@ -2083,8 +2072,6 @@ extern unsigned char tTdvect[100]; /* trace vector */ ExitStat = s; \ } -/* make a copy of a string */ -#define newstr(s) strcpy(xalloc(strlen(s) + 1), s) #define STRUCTCOPY(s, d) d = s @@ -2138,6 +2125,11 @@ extern unsigned char tTdvect[100]; /* trace vector */ # define CHECK_RESTART _CHECK_RESTART +/* reply types (text in SmtpMsgBuffer) */ +#define XS_DEFAULT 0 +#define XS_STARTTLS 1 +#define XS_AUTH 2 + /* ** Global variables. */ @@ -2169,10 +2161,9 @@ EXTERN bool NoAlias; /* suppress aliasing */ EXTERN bool NoConnect; /* don't connect to non-local mailers */ EXTERN bool OnlyOneError; /* .... or only want to give one SMTP reply */ EXTERN bool QuickAbort; /* .... but only if we want a quick abort */ -#if _FFR_REQ_DIR_FSYNC_OPT +#if REQUIRES_DIR_FSYNC EXTERN bool RequiresDirfsync; /* requires fsync() for directory */ -#endif /* _FFR_REQ_DIR_FSYNC_OPT */ -EXTERN bool ResNoAliases; /* don't use $HOSTALIASES */ +#endif /* REQUIRES_DIR_FSYNC */ EXTERN bool volatile RestartWorkGroup; /* daemon needs to restart some work groups */ EXTERN bool RrtImpliesDsn; /* turn Return-Receipt-To: into DSN */ EXTERN bool SaveFrom; /* save leading "From" lines */ @@ -2232,9 +2223,7 @@ EXTERN int NumFileSys; /* number of queue file systems */ EXTERN int QueueLA; /* load average starting forced queueing */ EXTERN int RefuseLA; /* load average refusing connections */ -#if _FFR_REJECT_LOG EXTERN time_t RejectLogInterval; /* time btwn log msgs while refusing */ -#endif /* _FFR_REJECT_LOG */ EXTERN int SuperSafe; /* be extra careful, even if expensive */ EXTERN int VendorCode; /* vendor-specific operation enhancements */ EXTERN int Verbose; /* set if blow-by-blow desired */ @@ -2250,6 +2239,7 @@ EXTERN char *ShmKeyFile; /* shared memory key file */ #endif /* SM_CONF_SHM */ EXTERN pid_t CurrentPid; /* current process id */ EXTERN pid_t DaemonPid; /* process id of daemon */ +EXTERN pid_t PidFilePid; /* daemon/queue runner who wrote pid file */ EXTERN uid_t DefUid; /* default uid to run as */ EXTERN uid_t RealUid; /* real uid of caller */ EXTERN uid_t RunAsUid; /* UID to become for bulk of run */ @@ -2274,9 +2264,13 @@ EXTERN char *DefUser; /* default user to run as (from DefUid) */ EXTERN char *DefaultCharSet; /* default character set for MIME */ EXTERN char *DoubleBounceAddr; /* where to send double bounces */ EXTERN char *ErrMsgFile; /* file to prepend to all error messages */ -EXTERN char *FallBackMX; /* fall back MX host */ +EXTERN char *FallbackMX; /* fall back MX host */ +EXTERN char *FallbackSmartHost; /* fall back smart host */ EXTERN char *FileName; /* name to print on error messages */ EXTERN char *ForwardPath; /* path to search for .forward files */ +#if _FFR_HELONAME +EXTERN char *HeloName; /* hostname to announce in HELO */ +#endif /* _FFR_HELONAME */ EXTERN char *HelpFile; /* location of SMTP help file */ EXTERN char *HostStatDir; /* location of host status information */ EXTERN char *HostsFile; /* path to /etc/hosts file */ @@ -2320,6 +2314,7 @@ EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */ extern const SM_EXC_TYPE_T EtypeQuickAbort; /* type of a QuickAbort exception */ +EXTERN int ConnectionRateWindowSize; /* ** Declarations of useful functions @@ -2355,7 +2350,7 @@ extern void PRINTFLIKE(3, 4) sm_syslog __P((int, const char *, const char *, ... /* SMTP */ extern void giveresponse __P((int, char *, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *, ADDRESS *)); -extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)(), char **)); +extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)(), char **, int)); extern void smtp __P((char *volatile, BITMAP256, ENVELOPE *volatile)); #if SASL extern int smtpauth __P((MAILER *, MCI *, ENVELOPE *)); @@ -2386,9 +2381,7 @@ extern void sendall __P((ENVELOPE *, int)); /* stats */ #define STATS_NORMAL 'n' -#if _FFR_QUARANTINE -# define STATS_QUARANTINE 'q' -#endif /* _FFR_QUARANTINE */ +#define STATS_QUARANTINE 'q' #define STATS_REJECT 'r' #define STATS_CONNECT 'c' @@ -2414,8 +2407,10 @@ extern void milter_abort __P((ENVELOPE *)); extern char *milter_connect __P((char *, SOCKADDR, ENVELOPE *, char *)); extern char *milter_helo __P((char *, ENVELOPE *, char *)); extern char *milter_envfrom __P((char **, ENVELOPE *, char *)); +extern char *milter_data_cmd __P((ENVELOPE *, char *)); extern char *milter_envrcpt __P((char **, ENVELOPE *, char *)); extern char *milter_data __P((ENVELOPE *, char *)); +extern char *milter_unknown __P((char *, ENVELOPE *, char *)); #endif /* MILTER */ extern char *addquotes __P((char *, SM_RPOOL_T *)); @@ -2441,14 +2436,18 @@ extern void cleanstrcpy __P((char *, char *, int)); #if SM_CONF_SHM extern void cleanup_shm __P((bool)); #endif /* SM_CONF_SHM */ +extern void close_sendmail_pid __P((void)); extern void clrdaemon __P((void)); extern void collect __P((SM_FILE_T *, bool, HDR **, ENVELOPE *, bool)); +extern bool connection_rate_check __P((SOCKADDR *, ENVELOPE *)); extern time_t convtime __P((char *, int)); extern char **copyplist __P((char **, bool, SM_RPOOL_T *)); extern void copy_class __P((int, int)); +extern int count_open_connections __P((SOCKADDR *)); extern time_t curtime __P((void)); extern char *defcharset __P((ENVELOPE *)); extern char *denlstring __P((char *, bool, bool)); +extern void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *)); extern void disconnect __P((int, ENVELOPE *)); #if _FFR_CONTROL_MSTAT extern void disk_status __P((SM_FILE_T *, char *)); @@ -2500,14 +2499,15 @@ extern void makeworkgroups __P((void)); extern void mark_work_group_restart __P((int, int)); extern char * munchstring __P((char *, char **, int)); extern struct hostent *myhostname __P((char *, int)); +extern char *newstr __P((const char *)); #if NISPLUS extern char *nisplus_default_domain __P((void)); /* extern for Sun */ #endif /* NISPLUS */ extern bool path_is_dir __P((char *, bool)); extern int pickqdir __P((QUEUEGRP *qg, long fsize, ENVELOPE *e)); extern char *pintvl __P((time_t, bool)); -extern void printav __P((char **)); -extern void printmailer __P((MAILER *)); +extern void printav __P((SM_FILE_T *, char **)); +extern void printmailer __P((SM_FILE_T *, MAILER *)); extern void printnqe __P((SM_FILE_T *, char *)); extern void printopenfds __P((bool)); extern void printqueue __P((void)); @@ -2541,6 +2541,8 @@ extern char *shortenstring __P((const char *, size_t)); extern char *shorten_hostname __P((char [])); extern bool shorten_rfc822_string __P((char *, size_t)); extern void shutdown_daemon __P((void)); +extern void sm_closefrom __P((int lowest, int highest)); +extern void sm_close_on_exec __P((int lowest, int highest)); extern struct hostent *sm_gethostbyname __P((char *, int)); extern struct hostent *sm_gethostbyaddr __P((char *, int, int)); extern void sm_getla __P((void)); @@ -2551,9 +2553,7 @@ extern pid_t sm_wait __P((int *)); extern bool split_by_recipient __P((ENVELOPE *e)); extern void stop_sendmail __P((void)); extern char *str2prt __P((char *)); -#if _FFR_STRIPBACKSL extern void stripbackslash __P((char *)); -#endif /* _FFR_STRIPBACKSL */ extern bool strreplnonprt __P((char *, int)); extern bool strcontainedin __P((bool, char *, char *)); extern int switch_map_find __P((char *, char *[], short [])); @@ -2590,7 +2590,7 @@ extern char *xalloc_tagged __P((int, char*, int)); #else /* SM_HEAP_CHECK */ extern char *xalloc __P((int)); #endif /* SM_HEAP_CHECK */ -extern void xputs __P((const char *)); +extern void xputs __P((SM_FILE_T *, const char *)); extern char *xtextify __P((char *, char *)); extern bool xtextok __P((char *)); extern int xunlink __P((char *)); diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c index 48afb9acc170..ab8aca3edbaf 100644 --- a/contrib/sendmail/src/sfsasl.c +++ b/contrib/sendmail/src/sfsasl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: sfsasl.c,v 8.91.2.5 2003/08/08 17:30:11 ca Exp $") +SM_RCSID("@(#)$Id: sfsasl.c,v 8.98 2004/03/03 19:20:31 ca Exp $") #include #include #include @@ -349,16 +349,16 @@ sfdcsasl(fin, fout, conn) SM_TIME_FOREVER); info.fp = *fin; info.conn = conn; - newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY, - NULL); + newin = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, + SM_IO_RDONLY_B, NULL); if (newin == NULL) return -1; info.fp = *fout; info.conn = conn; - newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY, - NULL); + newout = sm_io_open(&sasl_vector, SM_TIME_DEFAULT, &info, + SM_IO_WRONLY_B, NULL); if (newout == NULL) { @@ -750,13 +750,13 @@ sfdctls(fin, fout, con) SM_TIME_FOREVER); info.fp = *fin; info.con = con; - tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY, + tlsin = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_RDONLY_B, NULL); if (tlsin == NULL) return -1; info.fp = *fout; - tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY, + tlsout = sm_io_open(&tls_vector, SM_TIME_DEFAULT, &info, SM_IO_WRONLY_B, NULL); if (tlsout == NULL) { diff --git a/contrib/sendmail/src/sm_resolve.c b/contrib/sendmail/src/sm_resolve.c index 8828fd162546..d788d00a5834 100644 --- a/contrib/sendmail/src/sm_resolve.c +++ b/contrib/sendmail/src/sm_resolve.c @@ -46,7 +46,7 @@ # if NAMED_BIND # include "sm_resolve.h" -SM_RCSID("$Id: sm_resolve.c,v 8.24.4.7 2003/03/22 22:55:37 ca Exp $") +SM_RCSID("$Id: sm_resolve.c,v 8.32 2003/03/22 22:57:26 ca Exp $") static struct stot { diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c index e752aa081cc0..cb0366e7d656 100644 --- a/contrib/sendmail/src/srvrsmtp.c +++ b/contrib/sendmail/src/srvrsmtp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,13 +13,16 @@ #include #if MILTER +# include # include #endif /* MILTER */ -SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.829.2.34 2004/01/14 19:13:46 ca Exp $") +SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.900 2004/07/08 23:29:33 ca Exp $") + +#include +#include #if SASL || STARTTLS -# include # include "sfsasl.h" #endif /* SASL || STARTTLS */ #if SASL @@ -56,12 +59,14 @@ extern void tls_set_verify __P((SSL_CTX *, SSL *, bool)); # endif /* _FFR_NO_PIPE */ #endif /* PIPELINING */ #define SRV_REQ_AUTH 0x0400 /* require AUTH */ +#define SRV_REQ_SEC 0x0800 /* require security - equiv to AuthOptions=p */ #define SRV_TMP_FAIL 0x1000 /* ruleset caused a temporary failure */ static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int)); -static time_t checksmtpattack __P((volatile unsigned int *, int, bool, - char *, ENVELOPE *)); +#define STOP_ATTACK ((time_t) -1) +static time_t checksmtpattack __P((volatile unsigned int *, unsigned int, + bool, char *, ENVELOPE *)); static void mail_esmtp_args __P((char *, char *, ENVELOPE *)); static void printvrfyaddr __P((ADDRESS *, bool, bool)); static void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *)); @@ -75,7 +80,7 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, char *_auth_id, sasl_ssf_t *_ext_ssf)); # define RESET_SASLCONN \ - result = reset_saslconn(&conn, hostname, remoteip, localip, auth_id, \ + result = reset_saslconn(&conn, AuthRealm, remoteip, localip, auth_id, \ &ext_ssf); \ if (result != SASL_OK) \ { \ @@ -89,7 +94,7 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, struct sockaddr_in *_saddr_l, sasl_external_properties_t *_ext_ssf)); # define RESET_SASLCONN \ - result = reset_saslconn(&conn, hostname, &saddr_r, &saddr_l, &ext_ssf); \ + result = reset_saslconn(&conn, AuthRealm, &saddr_r, &saddr_l, &ext_ssf); \ if (result != SASL_OK) \ { \ /* This is pretty fatal */ \ @@ -101,6 +106,16 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, extern ENVELOPE BlankEnvelope; +#define NBADRCPTS \ + do \ + { \ + char buf[16]; \ + (void) sm_snprintf(buf, sizeof buf, "%d", \ + BadRcptThrottle > 0 && n_badrcpts > BadRcptThrottle \ + ? n_badrcpts - 1 : n_badrcpts); \ + macdefine(&e->e_macro, A_TEMP, macid("{nbadrcpts}"), buf); \ + } while (0) + #define SKIP_SPACE(s) while (isascii(*s) && isspace(*s)) \ (s)++ @@ -221,6 +236,31 @@ static char *CurSmtpClient; /* who's at the other end of channel */ # define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */ #endif /* ! MAXTIMEOUT */ +/* +** Maximum shift value to compute timeout for bad commands. +** This introduces an upper limit of 2^MAXSHIFT for the timeout. +*/ + +#ifndef MAXSHIFT +# define MAXSHIFT 8 +#endif /* ! MAXSHIFT */ +#if MAXSHIFT > 31 + ERROR _MAXSHIFT > 31 is invalid +#endif /* MAXSHIFT */ + + +#if MAXBADCOMMANDS > 0 +# define STOP_IF_ATTACK(r) do \ + { \ + if ((r) == STOP_ATTACK) \ + goto stopattack; \ + } while (0) + +#else /* MAXBADCOMMANDS > 0 */ +# define STOP_IF_ATTACK(r) r +#endif /* MAXBADCOMMANDS > 0 */ + + #if SM_HEAP_CHECK static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp", "@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $"); @@ -230,38 +270,21 @@ typedef struct { bool sm_gotmail; /* mail command received */ unsigned int sm_nrcpts; /* number of successful RCPT commands */ -#if _FFR_ADAPTIVE_EOL -WARNING: do NOT use this FFR, it is most likely broken - bool sm_crlf; /* input in CRLF form? */ -#endif /* _FFR_ADAPTIVE_EOL */ bool sm_discard; #if MILTER bool sm_milterize; bool sm_milterlist; /* any filters in the list? */ #endif /* MILTER */ -#if _FFR_QUARANTINE char *sm_quarmsg; /* carry quarantining across messages */ -#endif /* _FFR_QUARANTINE */ } SMTP_T; -static void smtp_data __P((SMTP_T *, ENVELOPE *)); +static bool smtp_data __P((SMTP_T *, ENVELOPE *)); -#define MSG_TEMPFAIL "451 4.7.1 Please try again later" +#define MSG_TEMPFAIL "451 4.3.2 Please try again later" #if MILTER # define MILTER_ABORT(e) milter_abort((e)) -#if _FFR_MILTER_421 -# define MILTER_SHUTDOWN \ - if (strncmp(response, "421 ", 4) == 0) \ - { \ - e->e_sendqueue = NULL; \ - goto doquit; \ - } -#else /* _FFR_MILTER_421 */ -# define MILTER_SHUTDOWN -#endif /* _FFR_MILTER_421 */ - # define MILTER_REPLY(str) \ { \ int savelogusrerrs = LogUsrErrs; \ @@ -276,8 +299,18 @@ static void smtp_data __P((SMTP_T *, ENVELOPE *)); str, addr, response); \ LogUsrErrs = false; \ } \ - usrerr(response); \ - MILTER_SHUTDOWN \ + if (strncmp(response, "421 ", 4) == 0) \ + { \ + bool tsave = QuickAbort; \ + \ + QuickAbort = false; \ + usrerr(response); \ + QuickAbort = tsave; \ + e->e_sendqueue = NULL; \ + goto doquit; \ + } \ + else \ + usrerr(response); \ break; \ \ case SMFIR_REJECT: \ @@ -321,6 +354,7 @@ static void smtp_data __P((SMTP_T *, ENVELOPE *)); /* clear all SMTP state (for HELO/EHLO/RSET) */ #define CLEAR_STATE(cmd) \ +do \ { \ /* abort milter filters */ \ MILTER_ABORT(e); \ @@ -347,7 +381,26 @@ static void smtp_data __P((SMTP_T *, ENVELOPE *)); sm_rpool_free(e->e_rpool); \ e = newenvelope(e, CurEnv, sm_rpool_new_x(NULL)); \ CurEnv = e; \ -} + \ + /* put back discard bit */ \ + if (smtp.sm_discard) \ + e->e_flags |= EF_DISCARD; \ + \ + /* restore connection quarantining */ \ + if (smtp.sm_quarmsg == NULL) \ + { \ + e->e_quarmsg = NULL; \ + macdefine(&e->e_macro, A_PERM, \ + macid("{quarantine}"), ""); \ + } \ + else \ + { \ + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, \ + smtp.sm_quarmsg); \ + macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), \ + e->e_quarmsg); \ + } \ +} while (0) /* sleep to flatten out connection load */ #define MIN_DELAY_LOG 15 /* wait before logging this again */ @@ -401,9 +454,9 @@ smtp(nullserver, d_flags, e) volatile unsigned int n_helo = 0; /* count of HELO/EHLO */ volatile int save_sevenbitinput; bool ok; -#if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL +#if _FFR_BLOCK_PROXIES volatile bool first; -#endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */ +#endif /* _FFR_BLOCK_PROXIES */ volatile bool tempfail = false; volatile time_t wt; /* timeout after too many commands */ volatile time_t previous; /* time after checksmtpattack() */ @@ -448,13 +501,12 @@ smtp(nullserver, d_flags, e) volatile unsigned int n_mechs; unsigned int len; #endif /* SASL */ -#if STARTTLS int r; +#if STARTTLS + int fdfl; int rfd, wfd; volatile bool tls_active = false; -# if _FFR_SMTP_SSL - volatile bool smtps = false; -# endif /* _FFR_SMTP_SSL */ + volatile bool smtps = bitnset(D_SMTPS, d_flags); bool saveQuickAbort; bool saveSuprErrs; time_t tlsstart; @@ -521,6 +573,8 @@ smtp(nullserver, d_flags, e) : SRV_OFFER_DSN) #if SASL | (bitnset(D_NOAUTH, d_flags) ? SRV_NONE : SRV_OFFER_AUTH) + | (bitset(SASL_SEC_NOPLAINTEXT, SASLOpts) ? SRV_REQ_SEC + : SRV_NONE) #endif /* SASL */ #if PIPELINING | SRV_OFFER_PIPE @@ -542,19 +596,35 @@ smtp(nullserver, d_flags, e) CurSmtpClient); nullserver = "450 4.3.0 Please try again later."; } + else + { #if PIPELINING # if _FFR_NO_PIPE - else if (bitset(SRV_NO_PIPE, features)) - { - /* for consistency */ - features &= ~SRV_OFFER_PIPE; - } + if (bitset(SRV_NO_PIPE, features)) + { + /* for consistency */ + features &= ~SRV_OFFER_PIPE; + } # endif /* _FFR_NO_PIPE */ #endif /* PIPELINING */ +#if SASL + if (bitset(SRV_REQ_SEC, features)) + SASLOpts |= SASL_SEC_NOPLAINTEXT; + else + SASLOpts &= ~SASL_SEC_NOPLAINTEXT; +#endif /* SASL */ + } + } + else if (strncmp(nullserver, "421 ", 4) == 0) + { + message(nullserver); + goto doquit; } hostname = macvalue('j', e); #if SASL + if (AuthRealm == NULL) + AuthRealm = hostname; sasl_ok = bitset(SRV_OFFER_AUTH, features); n_mechs = 0; authenticating = SASL_NOT_AUTH; @@ -563,14 +633,14 @@ smtp(nullserver, d_flags, e) if (sasl_ok) { # if SASL >= 20000 - result = sasl_server_new("smtp", hostname, NULL, NULL, NULL, + result = sasl_server_new("smtp", AuthRealm, NULL, NULL, NULL, NULL, 0, &conn); # elif SASL > 10505 /* use empty realm: only works in SASL > 1.5.5 */ - result = sasl_server_new("smtp", hostname, "", NULL, 0, &conn); + result = sasl_server_new("smtp", AuthRealm, "", NULL, 0, &conn); # else /* SASL >= 20000 */ /* use no realm -> realm is set to hostname by SASL lib */ - result = sasl_server_new("smtp", hostname, NULL, NULL, 0, + result = sasl_server_new("smtp", AuthRealm, NULL, NULL, 0, &conn); # endif /* SASL >= 20000 */ sasl_ok = result == SASL_OK; @@ -775,7 +845,6 @@ smtp(nullserver, d_flags, e) smtp.sm_milterize = false; break; -#if _FFR_MILTER_421 case SMFIR_SHUTDOWN: if (MilterLogLevel > 3) sm_syslog(LOG_INFO, e->e_id, @@ -790,18 +859,75 @@ smtp(nullserver, d_flags, e) /* arrange to ignore send list */ e->e_sendqueue = NULL; goto doquit; -#endif /* _FFR_MILTER_421 */ } if (response != NULL) - sm_free(response); /* XXX */ } #endif /* MILTER */ + /* + ** Broken proxies and SMTP slammers + ** push data without waiting, catch them + */ + + if ( +#if STARTTLS + !smtps && +#endif /* STARTTLS */ + *greetcode == '2') + { + time_t msecs = 0; + char **pvp; + char pvpbuf[PSBUFSIZE]; + + /* Ask the rulesets how long to pause */ + pvp = NULL; + r = rscap("greet_pause", peerhostname, + anynet_ntoa(&RealHostAddr), e, + &pvp, pvpbuf, sizeof(pvpbuf)); + if (r == EX_OK && pvp != NULL && pvp[0] != NULL && + (pvp[0][0] & 0377) == CANONNET && pvp[1] != NULL) + { + msecs = strtol(pvp[1], NULL, 10); + } + + if (msecs > 0) + { + int fd; + fd_set readfds; + struct timeval timeout; + + /* pause for a moment */ + timeout.tv_sec = msecs / 1000; + timeout.tv_usec = (msecs % 1000) * 1000; + + /* Obey RFC 2821: 4.3.5.2: 220 timeout of 5 minutes */ + if (timeout.tv_sec >= 300) + { + timeout.tv_sec = 300; + timeout.tv_usec = 0; + } + + /* check if data is on the socket during the pause */ + fd = sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL); + FD_ZERO(&readfds); + SM_FD_SET(fd, &readfds); + if (select(fd + 1, FDSET_CAST &readfds, + NULL, NULL, &timeout) > 0 && + FD_ISSET(fd, &readfds)) + { + greetcode = "554"; + nullserver = "Command rejected"; + sm_syslog(LOG_INFO, e->e_id, + "rejecting commands from %s [%s] due to pre-greeting traffic", + peerhostname, + anynet_ntoa(&RealHostAddr)); + } + } + } + #if STARTTLS -# if _FFR_SMTP_SSL /* If this an smtps connection, start TLS now */ - smtps = bitnset(D_SMTPS, d_flags); if (smtps) { Errors = 0; @@ -810,7 +936,6 @@ smtp(nullserver, d_flags, e) greeting: -# endif /* _FFR_SMTP_SSL */ #endif /* STARTTLS */ /* output the first line, inserting "ESMTP" as second word */ @@ -854,20 +979,18 @@ smtp(nullserver, d_flags, e) protocol = NULL; sendinghost = macvalue('s', e); -#if _FFR_QUARANTINE /* If quarantining by a connect/ehlo action, save between messages */ if (e->e_quarmsg == NULL) smtp.sm_quarmsg = NULL; else smtp.sm_quarmsg = newstr(e->e_quarmsg); -#endif /* _FFR_QUARANTINE */ /* sendinghost's storage must outlive the current envelope */ if (sendinghost != NULL) sendinghost = sm_strdup_x(sendinghost); -#if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL +#if _FFR_BLOCK_PROXIES first = true; -#endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */ +#endif /* _FFR_BLOCK_PROXIES */ gothello = false; smtp.sm_gotmail = false; for (;;) @@ -932,10 +1055,9 @@ smtp(nullserver, d_flags, e) goto doquit; } -#if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL +#if _FFR_BLOCK_PROXIES if (first) { -#if _FFR_BLOCK_PROXIES size_t inplen, cmdlen; int idx; char *http_cmd; @@ -960,27 +1082,9 @@ smtp(nullserver, d_flags, e) goto doquit; } } -#endif /* _FFR_BLOCK_PROXIES */ -#if _FFR_ADAPTIVE_EOL - char *p; - - smtp.sm_crlf = true; - p = strchr(inp, '\n'); - if (p == NULL || p <= inp || p[-1] != '\r') - { - smtp.sm_crlf = false; - if (tTd(66, 1) && LogLevel > 8) - { - /* how many bad guys are there? */ - sm_syslog(LOG_INFO, NOQID, - "%s did not use CRLF", - CurSmtpClient); - } - } -#endif /* _FFR_ADAPTIVE_EOL */ first = false; } -#endif /* _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL */ +#endif /* _FFR_BLOCK_PROXIES */ /* clean up end of line */ fixcrlf(inp, true); @@ -1090,7 +1194,8 @@ smtp(nullserver, d_flags, e) { macdefine(&BlankEnvelope.e_macro, A_TEMP, - macid("{auth_authen}"), user); + macid("{auth_authen}"), + xtextify(user, "<>\")")); } # if 0 @@ -1353,15 +1458,15 @@ smtp(nullserver, d_flags, e) sm_syslog(LOG_INFO, e->e_id, "SMTP AUTH command (%.100s) from %s tempfailed (due to previous checks)", p, CurSmtpClient); - usrerr("454 4.7.1 Please try again later"); + usrerr("454 4.3.0 Please try again later"); break; } ismore = false; /* crude way to avoid crack attempts */ - (void) checksmtpattack(&n_auth, n_mechs + 1, true, - "AUTH", e); + STOP_IF_ATTACK(checksmtpattack(&n_auth, n_mechs + 1, + true, "AUTH", e)); /* make sure mechanism (p) is a valid string */ for (q = p; *q != '\0' && isascii(*q); q++) @@ -1524,12 +1629,10 @@ smtp(nullserver, d_flags, e) sm_syslog(LOG_INFO, e->e_id, "SMTP STARTTLS command (%.100s) from %s tempfailed (due to previous checks)", p, CurSmtpClient); - usrerr("454 4.7.1 Please try again later"); + usrerr("454 4.7.0 Please try again later"); break; } -# if _FFR_SMTP_SSL starttls: -# endif /* _FFR_SMTP_SSL */ # if TLS_NO_RSA /* ** XXX do we need a temp key ? @@ -1554,11 +1657,7 @@ smtp(nullserver, d_flags, e) message("454 4.3.3 TLS not available: error generating SSL handle"); if (LogLevel > 8) tlslogerr("server"); -# if _FFR_SMTP_SSL goto tls_done; -# else /* _FFR_SMTP_SSL */ - break; -# endif /* _FFR_SMTP_SSL */ } # if !TLS_VRFY_PER_CTX @@ -1581,15 +1680,9 @@ smtp(nullserver, d_flags, e) message("454 4.3.3 TLS not available: error set fd"); SSL_free(srv_ssl); srv_ssl = NULL; -# if _FFR_SMTP_SSL goto tls_done; -# else /* _FFR_SMTP_SSL */ - break; -# endif /* _FFR_SMTP_SSL */ } -# if _FFR_SMTP_SSL if (!smtps) -# endif /* _FFR_SMTP_SSL */ message("220 2.0.0 Ready to start TLS"); # if PIPELINING (void) sm_io_flush(OutChannel, SM_TIME_DEFAULT); @@ -1600,6 +1693,9 @@ smtp(nullserver, d_flags, e) # define SSL_ACC(s) SSL_accept(s) tlsstart = curtime(); + fdfl = fcntl(rfd, F_GETFL); + if (fdfl != -1) + fcntl(rfd, F_SETFL, fdfl|O_NONBLOCK); ssl_retry: if ((r = SSL_ACC(srv_ssl)) <= 0) { @@ -1702,6 +1798,9 @@ smtp(nullserver, d_flags, e) goto doquit; } + if (fdfl != -1) + fcntl(rfd, F_SETFL, fdfl); + /* ignore return code for now, it's in {verify} */ (void) tls_get_info(srv_ssl, true, CurSmtpClient, @@ -1739,25 +1838,31 @@ smtp(nullserver, d_flags, e) # if SASL if (sasl_ok) { - char *s; + int cipher_bits; + bool verified; + char *s, *v, *c; s = macvalue(macid("{cipher_bits}"), e); + v = macvalue(macid("{verify}"), e); + c = macvalue(macid("{cert_subject}"), e); + verified = (v != NULL && strcmp(v, "OK") == 0); + if (s != NULL && (cipher_bits = atoi(s)) > 0) + { # if SASL >= 20000 - if (s != NULL && (ext_ssf = atoi(s)) > 0) - { - auth_id = macvalue(macid("{cert_subject}"), - e); - sasl_ok = ((sasl_setprop(conn, SASL_SSF_EXTERNAL, - &ext_ssf) == SASL_OK) && - (sasl_setprop(conn, SASL_AUTH_EXTERNAL, - auth_id) == SASL_OK)); + ext_ssf = cipher_bits; + auth_id = verified ? c : NULL; + sasl_ok = ((sasl_setprop(conn, + SASL_SSF_EXTERNAL, + &ext_ssf) == SASL_OK) && + (sasl_setprop(conn, + SASL_AUTH_EXTERNAL, + auth_id) == SASL_OK)); # else /* SASL >= 20000 */ - if (s != NULL && (ext_ssf.ssf = atoi(s)) > 0) - { - ext_ssf.auth_id = macvalue(macid("{cert_subject}"), - e); - sasl_ok = sasl_setprop(conn, SASL_SSF_EXTERNAL, - &ext_ssf) == SASL_OK; + ext_ssf.ssf = cipher_bits; + ext_ssf.auth_id = verified ? c : NULL; + sasl_ok = sasl_setprop(conn, + SASL_SSF_EXTERNAL, + &ext_ssf) == SASL_OK; # endif /* SASL >= 20000 */ mechlist = NULL; if (sasl_ok) @@ -1789,7 +1894,6 @@ smtp(nullserver, d_flags, e) nullserver = "454 4.3.3 TLS not available: can't switch to encrypted layer"; syserr("STARTTLS: can't switch to encrypted layer"); } -# if _FFR_SMTP_SSL tls_done: if (smtps) { @@ -1798,7 +1902,6 @@ smtp(nullserver, d_flags, e) else goto doquit; } -# endif /* _FFR_SMTP_SSL */ break; #endif /* STARTTLS */ @@ -1817,8 +1920,8 @@ smtp(nullserver, d_flags, e) } /* avoid denial-of-service */ - (void) checksmtpattack(&n_helo, MAXHELOCOMMANDS, true, - "HELO/EHLO", e); + STOP_IF_ATTACK(checksmtpattack(&n_helo, MAXHELOCOMMANDS, + true, "HELO/EHLO", e)); #if 0 /* RFC2821 4.1.4 allows duplicate HELO/EHLO */ @@ -1891,24 +1994,6 @@ smtp(nullserver, d_flags, e) if (gothello) { CLEAR_STATE(cmdbuf); - -#if _FFR_QUARANTINE - /* restore connection quarantining */ - if (smtp.sm_quarmsg == NULL) - { - e->e_quarmsg = NULL; - macdefine(&e->e_macro, A_PERM, - macid("{quarantine}"), ""); - } - else - { - e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, - smtp.sm_quarmsg); - macdefine(&e->e_macro, A_PERM, - macid("{quarantine}"), - e->e_quarmsg); - } -#endif /* _FFR_QUARANTINE */ } #if MILTER @@ -1951,7 +2036,6 @@ smtp(nullserver, d_flags, e) if (response != NULL) sm_free(response); -# if _FFR_QUARANTINE /* ** If quarantining by a connect/ehlo action, ** save between messages @@ -1960,7 +2044,6 @@ smtp(nullserver, d_flags, e) if (smtp.sm_quarmsg == NULL && e->e_quarmsg != NULL) smtp.sm_quarmsg = newstr(e->e_quarmsg); -# endif /* _FFR_QUARANTINE */ } #endif /* MILTER */ gothello = true; @@ -2113,6 +2196,8 @@ smtp(nullserver, d_flags, e) n_badrcpts = 0; macdefine(&e->e_macro, A_PERM, macid("{ntries}"), "0"); macdefine(&e->e_macro, A_PERM, macid("{nrcpts}"), "0"); + macdefine(&e->e_macro, A_PERM, macid("{nbadrcpts}"), + "0"); e->e_flags |= EF_CLRQUEUE; sm_setproctitle(true, e, "%s %s: %.80s", qid_printname(e), @@ -2352,6 +2437,7 @@ smtp(nullserver, d_flags, e) /* To avoid duplicated message */ n_badrcpts++; } + NBADRCPTS; /* ** Don't use exponential backoff for now. @@ -2556,20 +2642,25 @@ smtp(nullserver, d_flags, e) } rcpt_done: if (Errors > 0) + { ++n_badrcpts; + NBADRCPTS; + } } SM_EXCEPT(exc, "[!F]*") { /* An exception occurred while processing RCPT */ e->e_flags &= ~(EF_FATALERRS|EF_PM_NOTIFY); ++n_badrcpts; + NBADRCPTS; } SM_END_TRY break; case CMDDATA: /* data -- text of mail */ DELAY_CONN("DATA"); - smtp_data(&smtp, e); + if (!smtp_data(&smtp, e)) + goto doquit; break; case CMDRSET: /* rset -- reset state */ @@ -2578,22 +2669,6 @@ smtp(nullserver, d_flags, e) else message("250 2.0.0 Reset state"); CLEAR_STATE(cmdbuf); -#if _FFR_QUARANTINE - /* restore connection quarantining */ - if (smtp.sm_quarmsg == NULL) - { - e->e_quarmsg = NULL; - macdefine(&e->e_macro, A_PERM, - macid("{quarantine}"), ""); - } - else - { - e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, - smtp.sm_quarmsg); - macdefine(&e->e_macro, A_PERM, - macid("{quarantine}"), e->e_quarmsg); - } -#endif /* _FFR_QUARANTINE */ break; case CMDVRFY: /* vrfy -- verify address */ @@ -2614,6 +2689,7 @@ smtp(nullserver, d_flags, e) } wt = checksmtpattack(&n_verifies, MAXVRFYCOMMANDS, false, vrfy ? "VRFY" : "EXPN", e); + STOP_IF_ATTACK(wt); previous = curtime(); if ((vrfy && bitset(PRIV_NOVRFY, PrivacyFlags)) || (!vrfy && !bitset(SRV_OFFER_EXPN, features))) @@ -2741,8 +2817,8 @@ smtp(nullserver, d_flags, e) } /* crude way to avoid denial-of-service attacks */ - (void) checksmtpattack(&n_etrn, MAXETRNCOMMANDS, true, - "ETRN", e); + STOP_IF_ATTACK(checksmtpattack(&n_etrn, MAXETRNCOMMANDS, + true, "ETRN", e)); /* ** Do config file checking of the parameter. @@ -2817,8 +2893,8 @@ smtp(nullserver, d_flags, e) case CMDNOOP: /* noop -- do nothing */ DELAY_CONN("NOOP"); - (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true, - "NOOP", e); + STOP_IF_ATTACK(checksmtpattack(&n_noop, MAXNOOPCOMMANDS, + true, "NOOP", e)); message("250 2.0.0 OK"); break; @@ -2900,8 +2976,8 @@ smtp(nullserver, d_flags, e) message("502 5.7.0 Verbose unavailable"); break; } - (void) checksmtpattack(&n_noop, MAXNOOPCOMMANDS, true, - "VERB", e); + STOP_IF_ATTACK(checksmtpattack(&n_noop, MAXNOOPCOMMANDS, + true, "VERB", e)); Verbose = 1; set_delivery_mode(SM_DELIVER, e); message("250 2.0.0 Verbose mode"); @@ -2911,7 +2987,7 @@ smtp(nullserver, d_flags, e) case CMDDBGQSHOW: /* show queues */ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "Send Queue="); - printaddr(e->e_sendqueue, true); + printaddr(smioout, e->e_sendqueue, true); break; case CMDDBGDEBUG: /* set debug mode */ @@ -2937,6 +3013,7 @@ smtp(nullserver, d_flags, e) #if MAXBADCOMMANDS > 0 if (++n_badcmds > MAXBADCOMMANDS) { + stopattack: message("421 4.7.0 %s Too many bad commands; closing connection", MyHostName); @@ -2946,6 +3023,28 @@ smtp(nullserver, d_flags, e) } #endif /* MAXBADCOMMANDS > 0 */ +#if MILTER && SMFI_VERSION > 2 + if (smtp.sm_milterlist && smtp.sm_milterize && + !bitset(EF_DISCARD, e->e_flags)) + { + char state; + char *response; + + if (MilterLogLevel > 9) + sm_syslog(LOG_INFO, e->e_id, + "Sending \"%s\" to Milter", inp); + response = milter_unknown(inp, e, &state); + MILTER_REPLY("unknown"); + if (state == SMFIR_REPLYCODE || + state == SMFIR_REJECT || + state == SMFIR_TEMPFAIL) + { + /* MILTER_REPLY already gave an error */ + break; + } + } +#endif /* MILTER && SMFI_VERSION > 2 */ + usrerr("500 5.5.1 Command unrecognized: \"%s\"", shortenstring(inp, MAXSHORTSTR)); break; @@ -2984,13 +3083,13 @@ smtp(nullserver, d_flags, e) ** e -- envelope. ** ** Returns: -** none. +** true iff SMTP session can continue. ** ** Side Effects: ** possibly sends message. */ -static void +static bool smtp_data(smtp, e) SMTP_T *smtp; ENVELOPE *e; @@ -3010,18 +3109,79 @@ smtp_data(smtp, e) if (!smtp->sm_gotmail) { usrerr("503 5.0.0 Need MAIL command"); - return; + return true; } else if (smtp->sm_nrcpts <= 0) { usrerr("503 5.0.0 Need RCPT (recipient)"); - return; + return true; } (void) sm_snprintf(buf, sizeof buf, "%u", smtp->sm_nrcpts); if (rscheck("check_data", buf, NULL, e, RSF_RMCOMM|RSF_UNSTRUCTURED|RSF_COUNT, 3, NULL, e->e_id) != EX_OK) - return; + return true; + +#if MILTER && SMFI_VERSION > 3 + if (smtp->sm_milterlist && smtp->sm_milterize && + !bitset(EF_DISCARD, e->e_flags)) + { + char state; + char *response; + int savelogusrerrs = LogUsrErrs; + + response = milter_data_cmd(e, &state); + switch (state) + { + case SMFIR_REPLYCODE: + if (MilterLogLevel > 3) + { + sm_syslog(LOG_INFO, e->e_id, + "Milter: cmd=data, reject=%s", + response); + LogUsrErrs = false; + } + usrerr(response); + if (strncmp(response, "421 ", 4) == 0) + { + e->e_sendqueue = NULL; + return false; + } + return true; + + case SMFIR_REJECT: + if (MilterLogLevel > 3) + { + sm_syslog(LOG_INFO, e->e_id, + "Milter: cmd=data, reject=550 5.7.1 Command rejected"); + LogUsrErrs = false; + } + usrerr("550 5.7.1 Command rejected"); + return true; + + case SMFIR_DISCARD: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: cmd=data, discard"); + e->e_flags |= EF_DISCARD; + break; + + case SMFIR_TEMPFAIL: + if (MilterLogLevel > 3) + { + sm_syslog(LOG_INFO, e->e_id, + "Milter: cmd=data, reject=%s", + MSG_TEMPFAIL); + LogUsrErrs = false; + } + usrerr(MSG_TEMPFAIL); + return true; + } + LogUsrErrs = savelogusrerrs; + if (response != NULL) + sm_free(response); /* XXX */ + } +#endif /* MILTER && SMFI_VERSION > 3 */ /* put back discard bit */ if (smtp->sm_discard) @@ -3049,12 +3209,6 @@ smtp_data(smtp, e) SmtpPhase = "collect"; buffer_errors(); -#if _FFR_ADAPTIVE_EOL - /* triggers error in collect, disabled for now */ - if (smtp->sm_crlf) - e->e_flags |= EF_NL_NOT_EOL; -#endif /* _FFR_ADAPTIVE_EOL */ - collect(InChannel, true, NULL, e, true); /* redefine message size */ @@ -3128,13 +3282,86 @@ smtp_data(smtp, e) if (milteraccept && MilterLogLevel > 9) sm_syslog(LOG_INFO, e->e_id, "Milter accept: message"); } + + /* + ** If SuperSafe is SAFE_REALLY_POSTMILTER, and we don't have milter or + ** milter accepted message, sync it now + ** + ** XXX This is almost a copy of the code in collect(): put it into + ** a function that is called from both places? + */ + + if (milteraccept && SuperSafe == SAFE_REALLY_POSTMILTER) + { + int afd; + SM_FILE_T *volatile df; + char *dfname; + + df = e->e_dfp; + dfname = queuename(e, DATAFL_LETTER); + if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0 + && errno != EINVAL) + { + int save_errno; + + save_errno = errno; + if (save_errno == EEXIST) + { + struct stat st; + int dfd; + + if (stat(dfname, &st) < 0) + st.st_size = -1; + errno = EEXIST; + syserr("@collect: bfcommit(%s): already on disk, size=%ld", + dfname, (long) st.st_size); + dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); + if (dfd >= 0) + dumpfd(dfd, true, true); + } + errno = save_errno; + dferror(df, "bfcommit", e); + flush_errors(true); + finis(save_errno != EEXIST, true, ExitStat); + } + else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0) + { + dferror(df, "sm_io_getinfo", e); + flush_errors(true); + finis(true, true, ExitStat); + /* NOTREACHED */ + } + else if (fsync(afd) < 0) + { + dferror(df, "fsync", e); + flush_errors(true); + finis(true, true, ExitStat); + /* NOTREACHED */ + } + else if (sm_io_close(df, SM_TIME_DEFAULT) < 0) + { + dferror(df, "sm_io_close", e); + flush_errors(true); + finis(true, true, ExitStat); + /* NOTREACHED */ + } + + /* Now reopen the df file */ + e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, + SM_IO_RDONLY, NULL); + if (e->e_dfp == NULL) + { + /* we haven't acked receipt yet, so just chuck this */ + syserr("@Cannot reopen %s", dfname); + finis(true, true, ExitStat); + /* NOTREACHED */ + } + } #endif /* MILTER */ -#if _FFR_QUARANTINE /* Check if quarantining stats should be updated */ if (e->e_quarmsg != NULL) markstats(e, NULL, STATS_QUARANTINE); -#endif /* _FFR_QUARANTINE */ /* ** If a header/body check (header checks or milter) @@ -3148,9 +3375,7 @@ smtp_data(smtp, e) aborting = Errors > 0; if (!(aborting || bitset(EF_DISCARD, e->e_flags)) && -#if _FFR_QUARANTINE (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) && -#endif /* _FFR_QUARANTINE */ !split_by_recipient(e)) aborting = bitset(EF_FATALERRS, e->e_flags); @@ -3248,14 +3473,12 @@ smtp_data(smtp, e) ee->e_sendmode = SM_QUEUE; continue; } -#if _FFR_QUARANTINE else if (QueueMode != QM_QUARANTINE && ee->e_quarmsg != NULL) { ee->e_sendmode = SM_QUEUE; continue; } -#endif /* _FFR_QUARANTINE */ anything_to_send = true; /* close all the queue files */ @@ -3300,7 +3523,6 @@ smtp_data(smtp, e) { for (ee = e; ee != NULL; ee = ee->e_sibling) { -#if _FFR_QUARANTINE if (!doublequeue && QueueMode != QM_QUARANTINE && ee->e_quarmsg != NULL) @@ -3308,7 +3530,6 @@ smtp_data(smtp, e) dropenvelope(ee, true, false); continue; } -#endif /* _FFR_QUARANTINE */ if (WILL_BE_QUEUED(ee->e_sendmode)) dropenvelope(ee, true, false); } @@ -3326,7 +3547,6 @@ smtp_data(smtp, e) newenvelope(e, e, sm_rpool_new_x(NULL)); e->e_flags = BlankEnvelope.e_flags; -#if _FFR_QUARANTINE /* restore connection quarantining */ if (smtp->sm_quarmsg == NULL) { @@ -3339,7 +3559,7 @@ smtp_data(smtp, e) macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), e->e_quarmsg); } -#endif /* _FFR_QUARANTINE */ + return true; } /* ** LOGUNDELRCPTS -- log undelivered (or all) recipients. @@ -3395,7 +3615,9 @@ logundelrcpts(e, msg, level, all) ** e -- the current envelope. ** ** Returns: -** time to wait. +** time to wait, +** STOP_ATTACK if twice as many commands as allowed and +** MaxChildren > 0. ** ** Side Effects: ** Slows down if we seem to be under attack. @@ -3404,7 +3626,7 @@ logundelrcpts(e, msg, level, all) static time_t checksmtpattack(pcounter, maxcount, waitnow, cname, e) volatile unsigned int *pcounter; - int maxcount; + unsigned int maxcount; bool waitnow; char *cname; ENVELOPE *e; @@ -3414,6 +3636,7 @@ checksmtpattack(pcounter, maxcount, waitnow, cname, e) if (++(*pcounter) >= maxcount) { + unsigned int shift; time_t s; if (*pcounter == maxcount && LogLevel > 5) @@ -3422,19 +3645,25 @@ checksmtpattack(pcounter, maxcount, waitnow, cname, e) "%s: possible SMTP attack: command=%.40s, count=%u", CurSmtpClient, cname, *pcounter); } - s = 1 << (*pcounter - maxcount); - if (s >= MAXTIMEOUT || s <= 0) + shift = *pcounter - maxcount; + s = 1 << shift; + if (shift > MAXSHIFT || s >= MAXTIMEOUT || s <= 0) s = MAXTIMEOUT; +#define IS_ATTACK(s) ((MaxChildren > 0 && *pcounter >= maxcount * 2) \ + ? STOP_ATTACK : (time_t) s) + /* sleep at least 1 second before returning */ (void) sleep(*pcounter / maxcount); s -= *pcounter / maxcount; - if (waitnow) + if (s >= MAXTIMEOUT || s < 0) + s = MAXTIMEOUT; + if (waitnow && s > 0) { (void) sleep(s); - return 0; + return IS_ATTACK(0); } - return s; + return IS_ATTACK(s); } return (time_t) 0; } @@ -3688,7 +3917,6 @@ mail_esmtp_args(kp, vp, e) bool saveQuickAbort = QuickAbort; bool saveSuprErrs = SuprErrs; bool saveExitStat = ExitStat; - char pbuf[256]; if (vp == NULL) { @@ -3713,12 +3941,9 @@ mail_esmtp_args(kp, vp, e) /* NOTREACHED */ } - /* XXX this might be cut off */ - (void) sm_strlcpy(pbuf, xuntextify(auth_param), sizeof pbuf); - /* xalloc() the buffer instead? */ - /* XXX define this always or only if trusted? */ - macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), pbuf); + macdefine(&e->e_macro, A_TEMP, macid("{auth_author}"), + auth_param); /* ** call Strust_auth to find out whether @@ -3730,14 +3955,14 @@ mail_esmtp_args(kp, vp, e) SuprErrs = true; QuickAbort = false; if (strcmp(auth_param, "<>") != 0 && - (rscheck("trust_auth", pbuf, NULL, e, RSF_RMCOMM, + (rscheck("trust_auth", auth_param, NULL, e, RSF_RMCOMM, 9, NULL, NOQID) != EX_OK || Errors > 0)) { if (tTd(95, 8)) { q = e->e_auth_param; sm_dprintf("auth=\"%.100s\" not trusted user=\"%.100s\"\n", - pbuf, (q == NULL) ? "" : q); + auth_param, (q == NULL) ? "" : q); } /* not trusted */ @@ -3750,7 +3975,7 @@ mail_esmtp_args(kp, vp, e) else { if (tTd(95, 8)) - sm_dprintf("auth=\"%.100s\" trusted\n", pbuf); + sm_dprintf("auth=\"%.100s\" trusted\n", auth_param); e->e_auth_param = sm_rpool_strdup_x(e->e_rpool, auth_param); } @@ -4169,21 +4394,22 @@ static struct } srv_feat_table[] = { { 'A', SRV_OFFER_AUTH }, - { 'B', SRV_OFFER_VERB }, /* FFR; not documented in 8.12 */ - { 'D', SRV_OFFER_DSN }, /* FFR; not documented in 8.12 */ - { 'E', SRV_OFFER_ETRN }, /* FFR; not documented in 8.12 */ - { 'L', SRV_REQ_AUTH }, /* FFR; not documented in 8.12 */ + { 'B', SRV_OFFER_VERB }, + { 'C', SRV_REQ_SEC }, + { 'D', SRV_OFFER_DSN }, + { 'E', SRV_OFFER_ETRN }, + { 'L', SRV_REQ_AUTH }, #if PIPELINING # if _FFR_NO_PIPE { 'N', SRV_NO_PIPE }, # endif /* _FFR_NO_PIPE */ { 'P', SRV_OFFER_PIPE }, #endif /* PIPELINING */ - { 'R', SRV_VRFY_CLT }, /* FFR; not documented in 8.12 */ + { 'R', SRV_VRFY_CLT }, /* same as V; not documented */ { 'S', SRV_OFFER_TLS }, /* { 'T', SRV_TMP_FAIL }, */ { 'V', SRV_VRFY_CLT }, - { 'X', SRV_OFFER_EXPN }, /* FFR; not documented in 8.12 */ + { 'X', SRV_OFFER_EXPN }, /* { 'Y', SRV_OFFER_VRFY }, */ { '\0', SRV_NONE } }; diff --git a/contrib/sendmail/src/stab.c b/contrib/sendmail/src/stab.c index 4d1d2ddd7526..2a7151496e6e 100644 --- a/contrib/sendmail/src/stab.c +++ b/contrib/sendmail/src/stab.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: stab.c,v 8.86.4.1 2003/03/31 17:44:24 ca Exp $") +SM_RCSID("@(#)$Id: stab.c,v 8.88 2003/05/21 15:36:30 ca Exp $") /* ** STAB -- manage the symbol table @@ -173,6 +173,12 @@ stab(name, type, op) len = sizeof s->s_quegrp; break; +#if SOCKETMAP + case ST_SOCKETMAP: + len = sizeof s->s_socketmap; + break; +#endif /* SOCKETMAP */ + default: /* ** Each mailer has its own MCI stab entry: diff --git a/contrib/sendmail/src/stats.c b/contrib/sendmail/src/stats.c index bf9d33a009fe..5725219298bc 100644 --- a/contrib/sendmail/src/stats.c +++ b/contrib/sendmail/src/stats.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: stats.c,v 8.55 2002/05/21 22:28:52 gshapiro Exp $") +SM_RCSID("@(#)$Id: stats.c,v 8.56 2002/06/27 22:47:37 gshapiro Exp $") #include @@ -47,12 +47,10 @@ markstats(e, to, type) { switch (type) { -#if _FFR_QUARANTINE case STATS_QUARANTINE: if (e->e_from.q_mailer != NULL) Stat.stat_nq[e->e_from.q_mailer->m_mno]++; break; -#endif /* _FFR_QUARANTINE */ case STATS_REJECT: if (e->e_from.q_mailer != NULL) @@ -180,9 +178,7 @@ poststats(sfile) stats.stat_bt[i] += Stat.stat_bt[i]; stats.stat_nr[i] += Stat.stat_nr[i]; stats.stat_nd[i] += Stat.stat_nd[i]; -#if _FFR_QUARANTINE stats.stat_nq[i] += Stat.stat_nq[i]; -#endif /* _FFR_QUARANTINE */ } stats.stat_cr += Stat.stat_cr; stats.stat_ct += Stat.stat_ct; diff --git a/contrib/sendmail/src/sysexits.c b/contrib/sendmail/src/sysexits.c index 2781b0751eb5..990ffe341a8e 100644 --- a/contrib/sendmail/src/sysexits.c +++ b/contrib/sendmail/src/sysexits.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: sysexits.c,v 8.33.4.1 2002/09/09 02:42:37 gshapiro Exp $") +SM_RCSID("@(#)$Id: sysexits.c,v 8.34 2002/09/09 02:43:00 gshapiro Exp $") /* ** DSNTOEXITSTAT -- convert DSN-style error code to EX_ style. diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c index 598c1872a738..6a8e8a170916 100644 --- a/contrib/sendmail/src/tls.c +++ b/contrib/sendmail/src/tls.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: tls.c,v 8.79.4.5 2003/12/28 04:23:28 gshapiro Exp $") +SM_RCSID("@(#)$Id: tls.c,v 8.95 2004/07/13 21:37:33 ca Exp $") #if STARTTLS # include @@ -29,6 +29,10 @@ static int tls_verify_cb __P((X509_STORE_CTX *)); static int tls_verify_cb __P((X509_STORE_CTX *, void *)); # endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ +# if OPENSSL_VERSION_NUMBER > 0x00907000L +static int x509_verify_cb __P((int, X509_STORE_CTX *)); +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ + # if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L # define CONST097 # else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */ @@ -332,6 +336,8 @@ tls_set_verify(ctx, ssl, vrfy) # define TLS_S_CERTP_OK 0x00000020 /* CA cert path is ok */ # define TLS_S_CERTF_EX 0x00000040 /* CA cert file exists */ # define TLS_S_CERTF_OK 0x00000080 /* CA cert file is ok */ +# define TLS_S_CRLF_EX 0x00000100 /* CRL file exists */ +# define TLS_S_CRLF_OK 0x00000200 /* CRL file is ok */ # if _FFR_TLS_1 # define TLS_S_CERT2_EX 0x00001000 /* 2nd cert file exists */ @@ -373,7 +379,7 @@ tls_ok_f(var, fn, type) if (LogLevel > 12) sm_syslog(LOG_WARNING, NOQID, "STARTTLS: %s%s missing", type == TLS_T_SRV ? "Server" : - (type == TLS_T_CLT ? "Client" : ""), var); + (type == TLS_T_CLT ? "Client" : ""), fn); return false; } /* @@ -508,6 +514,11 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) # if SM_CONF_SHM extern int ShmId; # endif /* SM_CONF_SHM */ +# if OPENSSL_VERSION_NUMBER > 0x00907000L + BIO *crl_file; + X509_CRL *crl; + X509_STORE *store; +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ status = TLS_S_NONE; who = srv ? "server" : "client"; @@ -553,6 +564,11 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) TLS_OK_F(cacertfile, "CACertFile", bitset(TLS_I_CERTF_EX, req), TLS_S_CERTF_EX, TLS_T_OTHER); +# if OPENSSL_VERSION_NUMBER > 0x00907000L + TLS_OK_F(CRLFile, "CRLFile", bitset(TLS_I_CRLF_EX, req), + TLS_S_CRLF_EX, TLS_T_OTHER); +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ + # if _FFR_TLS_1 /* ** if the second file is specified it must exist @@ -630,6 +646,11 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) TLS_SAFE_F(dhparam, sff | TLS_UNR(TLS_I_DHPAR_UNR, req), bitset(TLS_I_DHPAR_EX, req), bitset(TLS_S_DHPAR_EX, status), TLS_S_DHPAR_OK, srv); +# if OPENSSL_VERSION_NUMBER > 0x00907000L + TLS_SAFE_F(CRLFile, sff | TLS_UNR(TLS_I_CRLF_UNR, req), + bitset(TLS_I_CRLF_EX, req), + bitset(TLS_S_CRLF_EX, status), TLS_S_CRLF_OK, srv); +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ if (!ok) return ok; # if _FFR_TLS_1 @@ -660,6 +681,68 @@ inittls(ctx, req, srv, certfile, keyfile, cacertpath, cacertfile, dhparam) return false; } +# if OPENSSL_VERSION_NUMBER > 0x00907000L + if (CRLFile != NULL) + { + /* get a pointer to the current certificate validation store */ + store = SSL_CTX_get_cert_store(*ctx); /* does not fail */ + crl_file = BIO_new(BIO_s_file_internal()); + if (crl_file != NULL) + { + if (BIO_read_filename(crl_file, CRLFile) >= 0) + { + crl = PEM_read_bio_X509_CRL(crl_file, NULL, + NULL, NULL); + BIO_free(crl_file); + X509_STORE_add_crl(store, crl); + X509_CRL_free(crl); + X509_STORE_set_flags(store, + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + X509_STORE_set_verify_cb_func(store, + x509_verify_cb); + } + else + { + if (LogLevel > 9) + { + sm_syslog(LOG_WARNING, NOQID, + "STARTTLS=%s, error: PEM_read_bio_X509_CRL(%s)=failed", + who, CRLFile); + } + + /* avoid memory leaks */ + BIO_free(crl_file); + return false; + } + + } + else if (LogLevel > 9) + sm_syslog(LOG_WARNING, NOQID, + "STARTTLS=%s, error: BIO_new=failed", who); + } +# if _FFR_CRLPATH + if (CRLPath != NULL) + { + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + { + if (LogLevel > 9) + { + sm_syslog(LOG_WARNING, NOQID, + "STARTTLS=%s, error: X509_STORE_add_lookup(hash)=failed", + who, CRLFile); + } + return false; + } + X509_LOOKUP_add_dir(lookup, CRLPath, X509_FILETYPE_PEM); + X509_STORE_set_flags(store, + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + } +# endif /* _FFR_CRLPATH */ +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ + # if TLS_NO_RSA /* turn off backward compatibility, required for no-rsa */ SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2); @@ -1020,6 +1103,7 @@ tls_get_info(ssl, srv, host, mac, certreq) { SSL_CIPHER *c; int b, r; + long verifyok; char *s, *who; char bitstr[16]; X509 *cert; @@ -1041,11 +1125,11 @@ tls_get_info(ssl, srv, host, mac, certreq) who = srv ? "server" : "client"; cert = SSL_get_peer_certificate(ssl); + verifyok = SSL_get_verify_result(ssl); if (LogLevel > 14) sm_syslog(LOG_INFO, NOQID, "STARTTLS=%s, get_verify: %ld get_peer: 0x%lx", - who, SSL_get_verify_result(ssl), - (unsigned long) cert); + who, verifyok, (unsigned long) cert); if (cert != NULL) { unsigned int n; @@ -1094,7 +1178,7 @@ tls_get_info(ssl, srv, host, mac, certreq) macdefine(mac, A_PERM, macid("{cn_issuer}"), ""); macdefine(mac, A_TEMP, macid("{cert_md5}"), ""); } - switch (SSL_get_verify_result(ssl)) + switch (verifyok) { case X509_V_OK: if (cert != NULL) @@ -1148,8 +1232,9 @@ tls_get_info(ssl, srv, host, mac, certreq) s1 = macget(mac, macid("{cert_subject}")); s2 = macget(mac, macid("{cert_issuer}")); sm_syslog(LOG_INFO, NOQID, - "STARTTLS=%s, cert-subject=%.128s, cert-issuer=%.128s", - who, s1, s2); + "STARTTLS=%s, cert-subject=%.256s, cert-issuer=%.256s, verifymsg=%s", + who, s1, s2, + X509_verify_cert_error_string(verifyok)); } } return r; @@ -1393,9 +1478,10 @@ apps_ssl_info_cb(s, where, ret) */ static int -tls_verify_log(ok, ctx) +tls_verify_log(ok, ctx, name) int ok; X509_STORE_CTX *ctx; + char *name; { SSL *ssl; X509 *cert; @@ -1418,10 +1504,11 @@ tls_verify_log(ok, ctx) X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof buf); sm_syslog(LOG_INFO, NOQID, - "STARTTLS: cert verify: depth=%d %s, state=%d, reason=%s", - depth, buf, ok, X509_verify_cert_error_string(reason)); + "STARTTLS: %s cert verify: depth=%d %s, state=%d, reason=%s", + name, depth, buf, ok, X509_verify_cert_error_string(reason)); return 1; } + /* ** TLS_VERIFY_CB -- verify callback for TLS certificates ** @@ -1449,7 +1536,7 @@ tls_verify_cb(ctx, unused) if (ok == 0) { if (LogLevel > 13) - return tls_verify_log(ok, ctx); + return tls_verify_log(ok, ctx, "TLS"); return 1; /* override it */ } return ok; @@ -1486,4 +1573,35 @@ tlslogerr(who) bitset(ERR_TXT_STRING, flags) ? data : ""); } } + +# if OPENSSL_VERSION_NUMBER > 0x00907000L +/* +** X509_VERIFY_CB -- verify callback +** +** Parameters: +** ctx -- x509 context +** +** Returns: +** accept connection? +** currently: always yes. +*/ + +static int +x509_verify_cb(ok, ctx) + int ok; + X509_STORE_CTX *ctx; +{ + if (ok == 0) + { + if (LogLevel > 13) + tls_verify_log(ok, ctx, "x509"); + if (ctx->error == X509_V_ERR_UNABLE_TO_GET_CRL) + { + ctx->error = 0; + return 1; /* override it */ + } + } + return ok; +} +# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ #endif /* STARTTLS */ diff --git a/contrib/sendmail/src/trace.c b/contrib/sendmail/src/trace.c index a10b9f172f4f..4a9051e58fe4 100644 --- a/contrib/sendmail/src/trace.c +++ b/contrib/sendmail/src/trace.c @@ -15,7 +15,7 @@ #include #include -SM_RCSID("@(#)$Id: trace.c,v 8.37.4.1 2002/12/05 17:28:05 ca Exp $") +SM_RCSID("@(#)$Id: trace.c,v 8.38 2002/12/05 17:28:35 ca Exp $") static char *tTnewflag __P((char *)); static char *tToldflag __P((char *)); diff --git a/contrib/sendmail/src/udb.c b/contrib/sendmail/src/udb.c index 3f218cc178f1..aaf856928615 100644 --- a/contrib/sendmail/src/udb.c +++ b/contrib/sendmail/src/udb.c @@ -14,9 +14,9 @@ #include #if USERDB -SM_RCSID("@(#)$Id: udb.c,v 8.153.4.5 2003/04/03 16:31:00 ca Exp $ (with USERDB)") +SM_RCSID("@(#)$Id: udb.c,v 8.160 2003/04/03 16:32:46 ca Exp $ (with USERDB)") #else /* USERDB */ -SM_RCSID("@(#)$Id: udb.c,v 8.153.4.5 2003/04/03 16:31:00 ca Exp $ (without USERDB)") +SM_RCSID("@(#)$Id: udb.c,v 8.160 2003/04/03 16:32:46 ca Exp $ (without USERDB)") #endif /* USERDB */ #if USERDB @@ -334,7 +334,7 @@ udbexpand(a, sendq, aliaslevel, e) if (tTd(28, 5)) { sm_dprintf("udbexpand: QS_EXPANDED "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } a->q_state = QS_EXPANDED; } @@ -474,7 +474,7 @@ udbexpand(a, sendq, aliaslevel, e) if (tTd(28, 5)) { sm_dprintf("udbexpand: QS_EXPANDED "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } a->q_state = QS_EXPANDED; } @@ -525,7 +525,7 @@ udbexpand(a, sendq, aliaslevel, e) if (tTd(28, 5)) { sm_dprintf("udbexpand: QS_EXPANDED "); - printaddr(a, false); + printaddr(sm_debug_file(), a, false); } a->q_state = QS_EXPANDED; } diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c index e76036170edf..5c2b8f8b7090 100644 --- a/contrib/sendmail/src/usersmtp.c +++ b/contrib/sendmail/src/usersmtp.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: usersmtp.c,v 8.437.2.10 2003/05/05 23:51:47 ca Exp $") +SM_RCSID("@(#)$Id: usersmtp.c,v 8.451 2004/03/01 21:50:36 ca Exp $") #include @@ -82,7 +82,7 @@ smtpinit(m, mci, e, onlyhelo) if (tTd(18, 1)) { sm_dprintf("smtpinit "); - mci_dump(mci, false); + mci_dump(sm_debug_file(), mci, false); } /* @@ -138,7 +138,8 @@ smtpinit(m, mci, e, onlyhelo) SmtpPhase = mci->mci_phase = "client greeting"; sm_setproctitle(true, e, "%s %s: %s", qid_printname(e), CurHostName, mci->mci_phase); - r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check, NULL); + r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check, NULL, + XS_DEFAULT); if (r < 0) goto tempfail1; if (REPLYTYPE(r) == 4) @@ -184,7 +185,7 @@ smtpinit(m, mci, e, onlyhelo) r = reply(m, mci, e, bitnset(M_LMTP, m->m_flags) ? TimeOuts.to_lhlo : TimeOuts.to_helo, - helo_options, NULL); + helo_options, NULL, XS_DEFAULT); if (r < 0) goto tempfail1; else if (REPLYTYPE(r) == 5) @@ -226,21 +227,19 @@ smtpinit(m, mci, e, onlyhelo) /* ** If this is expected to be another sendmail, send some internal ** commands. + ** If we're running as MSP, "propagate" -v flag if possible. */ - if (false + if ((UseMSP && Verbose && bitset(MCIF_VERB, mci->mci_flags)) # if !_FFR_DEPRECATE_MAILER_FLAG_I || bitnset(M_INTERNAL, m->m_flags) # endif /* !_FFR_DEPRECATE_MAILER_FLAG_I */ -# if _FFR_MSP_VERBOSE - /* If we're running as MSP, "propagate" -v flag if possible. */ - || (UseMSP && Verbose && bitset(MCIF_VERB, mci->mci_flags)) -# endif /* _FFR_MSP_VERBOSE */ ) { /* tell it to be verbose */ smtpmessage("VERB", m, mci); - r = reply(m, mci, e, TimeOuts.to_miscshort, NULL, &enhsc); + r = reply(m, mci, e, TimeOuts.to_miscshort, NULL, &enhsc, + XS_DEFAULT); if (r < 0) goto tempfail1; } @@ -1744,12 +1743,10 @@ attemptauth(m, mci, e, sai) /* send the info across the wire */ if (out == NULL -#if _FFR_SASL_INITIAL_WORKAROUND /* login and digest-md5 up to 1.5.28 set out="" */ || (outlen == 0 && (sm_strcasecmp(mechusing, "LOGIN") == 0 || sm_strcasecmp(mechusing, "DIGEST-MD5") == 0)) -#endif /* _FFR_SASL_INITIAL_WORKAROUND */ ) { /* no initial response */ @@ -1782,7 +1779,8 @@ attemptauth(m, mci, e, sai) # endif /* SASL < 20000 */ /* get the reply */ - smtpresult = reply(m, mci, e, TimeOuts.to_auth, getsasldata, NULL); + smtpresult = reply(m, mci, e, TimeOuts.to_auth, getsasldata, NULL, + XS_AUTH); for (;;) { @@ -1826,7 +1824,7 @@ attemptauth(m, mci, e, sai) */ smtpresult = reply(m, mci, e, TimeOuts.to_auth, - getsasldata, NULL); + getsasldata, NULL, XS_AUTH); return EX_NOPERM; } @@ -1848,7 +1846,7 @@ attemptauth(m, mci, e, sai) # endif /* SASL < 20000 */ smtpmessage("%s", m, mci, in64); smtpresult = reply(m, mci, e, TimeOuts.to_auth, - getsasldata, NULL); + getsasldata, NULL, XS_AUTH); } /* NOTREACHED */ } @@ -2168,7 +2166,7 @@ smtpmailfrom(m, mci, e) SmtpPhase = mci->mci_phase = "client MAIL"; sm_setproctitle(true, e, "%s %s: %s", qid_printname(e), CurHostName, mci->mci_phase); - r = reply(m, mci, e, TimeOuts.to_mail, NULL, &enhsc); + r = reply(m, mci, e, TimeOuts.to_mail, NULL, &enhsc, XS_DEFAULT); if (r < 0) { /* communications failure */ @@ -2420,7 +2418,7 @@ smtprcptstat(to, m, mci, e) } enhsc = NULL; - r = reply(m, mci, e, TimeOuts.to_rcpt, NULL, &enhsc); + r = reply(m, mci, e, TimeOuts.to_rcpt, NULL, &enhsc, XS_DEFAULT); save_errno = errno; to->q_rstatus = sm_rpool_strdup_x(e->e_rpool, SmtpReplyBuffer); to->q_status = ENHSCN_RPOOL(enhsc, smtptodsn(r), e->e_rpool); @@ -2570,7 +2568,7 @@ smtpdata(m, mci, e, ctladdr, xstart) mci->mci_state = MCIS_DATA; sm_setproctitle(true, e, "%s %s: %s", qid_printname(e), CurHostName, mci->mci_phase); - r = reply(m, mci, e, TimeOuts.to_datainit, NULL, &enhsc); + r = reply(m, mci, e, TimeOuts.to_datainit, NULL, &enhsc, XS_DEFAULT); if (r < 0 || REPLYTYPE(r) == 4) { if (r >= 0) @@ -2723,7 +2721,7 @@ smtpdata(m, mci, e, ctladdr, xstart) CurHostName, mci->mci_phase); if (bitnset(M_LMTP, m->m_flags)) return EX_OK; - r = reply(m, mci, e, TimeOuts.to_datafinal, NULL, &enhsc); + r = reply(m, mci, e, TimeOuts.to_datafinal, NULL, &enhsc, XS_DEFAULT); if (r < 0) return EX_TEMPFAIL; mci->mci_state = MCIS_OPEN; @@ -2830,7 +2828,7 @@ smtpgetstat(m, mci, e) enhsc = NULL; /* check for the results of the transaction */ - r = reply(m, mci, e, TimeOuts.to_datafinal, NULL, &enhsc); + r = reply(m, mci, e, TimeOuts.to_datafinal, NULL, &enhsc, XS_DEFAULT); if (r < 0) return EX_TEMPFAIL; xstat = EX_NOTSTICKY; @@ -2913,7 +2911,8 @@ smtpquit(m, mci, e) SmtpPhase = "client QUIT"; mci->mci_state = MCIS_QUITING; smtpmessage("QUIT", m, mci); - (void) reply(m, mci, e, TimeOuts.to_quit, NULL, NULL); + (void) reply(m, mci, e, TimeOuts.to_quit, NULL, NULL, + XS_DEFAULT); SuprErrs = oldSuprErrs; if (mci->mci_state == MCIS_CLOSED) goto end; @@ -2988,7 +2987,7 @@ smtprset(m, mci, e) SmtpPhase = "client RSET"; smtpmessage("RSET", m, mci); - r = reply(m, mci, e, TimeOuts.to_rset, NULL, NULL); + r = reply(m, mci, e, TimeOuts.to_rset, NULL, NULL, XS_DEFAULT); if (r < 0) return; @@ -3033,7 +3032,7 @@ smtpprobe(mci) e = &BlankEnvelope; SmtpPhase = "client probe"; smtpmessage("RSET", m, mci); - r = reply(m, mci, e, TimeOuts.to_miscshort, NULL, NULL); + r = reply(m, mci, e, TimeOuts.to_miscshort, NULL, NULL, XS_DEFAULT); if (REPLYTYPE(r) != 2) smtpquit(m, mci, e); return r; @@ -3049,6 +3048,7 @@ smtpprobe(mci) ** pfunc -- processing function called on each line of response. ** If null, no special processing is done. ** enhstat -- optional, returns enhanced error code string (if set) +** rtype -- type of SmtpMsgBuffer: does it contains secret data? ** ** Returns: ** reply code it reads. @@ -3058,13 +3058,14 @@ smtpprobe(mci) */ int -reply(m, mci, e, timeout, pfunc, enhstat) +reply(m, mci, e, timeout, pfunc, enhstat, rtype) MAILER *m; MCI *mci; ENVELOPE *e; time_t timeout; void (*pfunc)(); char **enhstat; + int rtype; { register char *bufp; register int r; @@ -3207,9 +3208,17 @@ reply(m, mci, e, timeout, pfunc, enhstat) SmtpNeedIntro = false; } if (SmtpMsgBuffer[0] != '\0') - (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, - ">>> %s\n", SmtpMsgBuffer); - SmtpMsgBuffer[0] = '\0'; + { + (void) sm_io_fprintf(e->e_xfp, + SM_TIME_DEFAULT, + ">>> %s\n", + (rtype == XS_STARTTLS) + ? "STARTTLS dialogue" + : ((rtype == XS_AUTH) + ? "AUTH dialogue" + : SmtpMsgBuffer)); + SmtpMsgBuffer[0] = '\0'; + } /* now log the message as from the other side */ (void) sm_io_fprintf(e->e_xfp, SM_TIME_DEFAULT, diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c index 911f6923bd2d..6945e64eb1d3 100644 --- a/contrib/sendmail/src/util.c +++ b/contrib/sendmail/src/util.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,11 +13,35 @@ #include -SM_RCSID("@(#)$Id: util.c,v 8.363.2.10 2003/10/15 17:19:14 ca Exp $") +SM_RCSID("@(#)$Id: util.c,v 8.382 2004/03/26 19:01:10 ca Exp $") #include #include +/* +** NEWSTR -- Create a copy of a C string +** +** Parameters: +** s -- the string to copy. +** +** Returns: +** pointer to newly allocated string. +*/ + +char * +newstr(s) + const char *s; +{ + size_t l; + char *n; + + l = strlen(s); + SM_ASSERT(l + 1 > l); + n = xalloc(l + 1); + sm_strlcpy(n, s, l + 1); + return n; +} + /* ** ADDQUOTES -- Adds quotes & quote bits to a string. ** @@ -68,7 +92,6 @@ addquotes(s, rpool) return r; } -#if _FFR_STRIPBACKSL /* ** STRIPBACKSLASH -- Strip leading backslash from a string. ** @@ -97,7 +120,6 @@ stripbackslash(s) c = *q++ = *p++; } while (c != '\0'); } -#endif /* _FFR_STRIPBACKSL */ /* ** RFC822_STRING -- Checks string for proper RFC822 string quoting. @@ -540,48 +562,81 @@ copyqueue(addr, rpool) ** ** Side Effects: ** writes pidfile, logs command line. +** keeps file open and locked to prevent overwrite of active file */ +static SM_FILE_T *Pidf = NULL; + void log_sendmail_pid(e) ENVELOPE *e; { long sff; - SM_FILE_T *pidf; char pidpath[MAXPATHLEN]; extern char *CommandLineArgs; /* write the pid to the log file for posterity */ - sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT; + sff = SFF_NOLINK|SFF_ROOTOK|SFF_REGONLY|SFF_CREAT|SFF_NBLOCK; if (TrustedUid != 0 && RealUid == TrustedUid) sff |= SFF_OPENASROOT; expand(PidFile, pidpath, sizeof pidpath, e); - pidf = safefopen(pidpath, O_WRONLY|O_TRUNC, FileMode, sff); - if (pidf == NULL) + Pidf = safefopen(pidpath, O_WRONLY|O_TRUNC, FileMode, sff); + if (Pidf == NULL) { - sm_syslog(LOG_ERR, NOQID, "unable to write %s: %s", - pidpath, sm_errstring(errno)); + if (errno == EWOULDBLOCK) + sm_syslog(LOG_ERR, NOQID, + "unable to write pid to %s: file in use by another process", + pidpath); + else + sm_syslog(LOG_ERR, NOQID, + "unable to write pid to %s: %s", + pidpath, sm_errstring(errno)); } else { - pid_t pid; - - pid = getpid(); + PidFilePid = getpid(); /* write the process id on line 1 */ - (void) sm_io_fprintf(pidf, SM_TIME_DEFAULT, "%ld\n", - (long) pid); + (void) sm_io_fprintf(Pidf, SM_TIME_DEFAULT, "%ld\n", + (long) PidFilePid); /* line 2 contains all command line flags */ - (void) sm_io_fprintf(pidf, SM_TIME_DEFAULT, "%s\n", + (void) sm_io_fprintf(Pidf, SM_TIME_DEFAULT, "%s\n", CommandLineArgs); - /* flush and close */ - (void) sm_io_close(pidf, SM_TIME_DEFAULT); + /* flush */ + (void) sm_io_flush(Pidf, SM_TIME_DEFAULT); + + /* + ** Leave pid file open until process ends + ** so it's not overwritten by another + ** process. + */ } if (LogLevel > 9) sm_syslog(LOG_INFO, NOQID, "started as: %s", CommandLineArgs); } + +/* +** CLOSE_SENDMAIL_PID -- close sendmail pid file +** +** Parameters: +** none. +** +** Returns: +** none. +*/ + +void +close_sendmail_pid() +{ + if (Pidf == NULL) + return; + + (void) sm_io_close(Pidf, SM_TIME_DEFAULT); + Pidf = NULL; +} + /* ** SET_DELIVERY_MODE -- set and record the delivery mode ** @@ -638,6 +693,7 @@ set_op_mode(mode) ** PRINTAV -- print argument vector. ** ** Parameters: +** fp -- output file pointer. ** av -- argument vector. ** ** Returns: @@ -648,7 +704,8 @@ set_op_mode(mode) */ void -printav(av) +printav(fp, av) + SM_FILE_T *fp; register char **av; { while (*av != NULL) @@ -656,15 +713,16 @@ printav(av) if (tTd(0, 44)) sm_dprintf("\n\t%08lx=", (unsigned long) *av); else - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, ' '); - xputs(*av++); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, ' '); + xputs(fp, *av++); } - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, '\n'); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, '\n'); } /* ** XPUTS -- put string doing control escapes. ** ** Parameters: +** fp -- output file pointer. ** s -- string to put. ** ** Returns: @@ -675,7 +733,8 @@ printav(av) */ void -xputs(s) +xputs(fp, s) + SM_FILE_T *fp; register const char *s; { register int c; @@ -707,7 +766,7 @@ xputs(s) if (s == NULL) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s%s", TermEscape.te_rv_on, TermEscape.te_rv_off); return; } @@ -715,7 +774,7 @@ xputs(s) { if (shiftout) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s", TermEscape.te_rv_off); shiftout = false; } @@ -723,7 +782,7 @@ xputs(s) { if (c == MATCHREPL) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s$", TermEscape.te_rv_on); shiftout = true; @@ -734,26 +793,26 @@ xputs(s) } if (c == MACROEXPAND || c == MACRODEXPAND) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s$", TermEscape.te_rv_on); if (c == MACRODEXPAND) - (void) sm_io_putc(smioout, + (void) sm_io_putc(fp, SM_TIME_DEFAULT, '&'); shiftout = true; if (*s == '\0') continue; if (strchr("=~&?", *s) != NULL) - (void) sm_io_putc(smioout, + (void) sm_io_putc(fp, SM_TIME_DEFAULT, *s++); if (bitset(0200, *s)) - (void) sm_io_fprintf(smioout, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "{%s}", macname(bitidx(*s++))); else - (void) sm_io_fprintf(smioout, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%c", *s++); @@ -763,7 +822,7 @@ xputs(s) { if (bitidx(mp->metaval) == c) { - (void) sm_io_fprintf(smioout, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s$%c", TermEscape.te_rv_on, @@ -775,12 +834,12 @@ xputs(s) if (c == MATCHCLASS || c == MATCHNCLASS) { if (bitset(0200, *s)) - (void) sm_io_fprintf(smioout, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "{%s}", macname(bitidx(*s++))); else if (*s != '\0') - (void) sm_io_fprintf(smioout, + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%c", *s++); @@ -789,7 +848,7 @@ xputs(s) continue; /* unrecognized meta character */ - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%sM-", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%sM-", TermEscape.te_rv_on); shiftout = true; c &= 0177; @@ -797,7 +856,7 @@ xputs(s) printchar: if (isprint(c)) { - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, c); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, c); continue; } @@ -818,25 +877,25 @@ xputs(s) } if (!shiftout) { - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s", TermEscape.te_rv_on); shiftout = true; } if (isprint(c)) { - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, '\\'); - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, c); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, '\\'); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, c); } else { - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, '^'); - (void) sm_io_putc(smioout, SM_TIME_DEFAULT, c ^ 0100); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, '^'); + (void) sm_io_putc(fp, SM_TIME_DEFAULT, c ^ 0100); } } if (shiftout) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s", + (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%s", TermEscape.te_rv_off); - (void) sm_io_flush(smioout, SM_TIME_DEFAULT); + (void) sm_io_flush(fp, SM_TIME_DEFAULT); } /* ** MAKELOWER -- Translate a line into lower case @@ -1697,7 +1756,7 @@ printopenfds(logit) ** fd -- the file descriptor to dump. ** printclosed -- if set, print a notification even if ** it is closed; otherwise print nothing. -** logit -- if set, send output to syslog instead of stdout. +** logit -- if set, use sm_syslog instead of sm_dprintf() ** ** Returns: ** none. @@ -1877,7 +1936,7 @@ dumpfd(fd, printclosed, logit) sm_syslog(LOG_DEBUG, CurEnv ? CurEnv->e_id : NULL, "%.800s", buf); else - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n", buf); + sm_dprintf("%s\n", buf); } /* ** SHORTEN_HOSTNAME -- strip local domain information off of hostname. @@ -1945,7 +2004,6 @@ prog_open(argv, pfd, e) ENVELOPE *e; { pid_t pid; - int i; int save_errno; int sff; int ret; @@ -2086,13 +2144,7 @@ prog_open(argv, pfd, e) argv[0], sm_errstring(ret)); /* arrange for all the files to be closed */ - for (i = 3; i < DtableSize; i++) - { - register int j; - - if ((j = fcntl(i, F_GETFD, 0)) != -1) - (void) fcntl(i, F_SETFD, j | FD_CLOEXEC); - } + sm_close_on_exec(STDERR_FILENO + 1, DtableSize); /* now exec the process */ (void) execve(argv[0], (ARGV_T) argv, (ARGV_T) UserEnviron); @@ -2469,23 +2521,25 @@ typedef struct procs PROCS_T; struct procs { - pid_t proc_pid; - char *proc_task; - int proc_type; - int proc_count; - int proc_other; + pid_t proc_pid; + char *proc_task; + int proc_type; + int proc_count; + int proc_other; + SOCKADDR proc_hostaddr; }; static PROCS_T *volatile ProcListVec = NULL; static int ProcListSize = 0; void -proc_list_add(pid, task, type, count, other) +proc_list_add(pid, task, type, count, other, hostaddr) pid_t pid; char *task; int type; int count; int other; + SOCKADDR *hostaddr; { int i; @@ -2537,6 +2591,11 @@ proc_list_add(pid, task, type, count, other) ProcListVec[i].proc_type = type; ProcListVec[i].proc_count = count; ProcListVec[i].proc_other = other; + if (hostaddr != NULL) + ProcListVec[i].proc_hostaddr = *hostaddr; + else + memset(&ProcListVec[i].proc_hostaddr, 0, + sizeof(ProcListVec[i].proc_hostaddr)); /* if process adding itself, it's not a child */ if (pid != CurrentPid) @@ -2774,3 +2833,47 @@ proc_list_signal(type, signal) if (chldwasblocked == 0) (void) sm_releasesignal(SIGCHLD); } + +/* +** COUNT_OPEN_CONNECTIONS +** +** Parameters: +** hostaddr - ClientAddress +** +** Returns: +** the number of open connections for this client +** +*/ + +int +count_open_connections(hostaddr) + SOCKADDR *hostaddr; +{ + int i, n; + + if (hostaddr == NULL) + return 0; + n = 0; + for (i = 0; i < ProcListSize; i++) + { + if (ProcListVec[i].proc_pid == NO_PID) + continue; + + if (hostaddr->sa.sa_family != + ProcListVec[i].proc_hostaddr.sa.sa_family) + continue; +#if NETINET + if (hostaddr->sa.sa_family == AF_INET && + (hostaddr->sin.sin_addr.s_addr == + ProcListVec[i].proc_hostaddr.sin.sin_addr.s_addr)) + n++; +#endif /* NETINET */ +#if NETINET6 + if (hostaddr->sa.sa_family == AF_INET6 && + IN6_ARE_ADDR_EQUAL(&(hostaddr->sin6.sin6_addr), + &(ProcListVec[i].proc_hostaddr.sin6.sin6_addr))) + n++; +#endif /* NETINET6 */ + } + return n; +} diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c index ec91cfeec324..6ea57aa4194a 100644 --- a/contrib/sendmail/src/version.c +++ b/contrib/sendmail/src/version.c @@ -13,6 +13,6 @@ #include -SM_RCSID("@(#)$Id: version.c,v 8.104.2.26 2004/01/13 00:29:26 ca Exp $") +SM_RCSID("@(#)$Id: version.c,v 8.130 2004/07/30 18:03:07 ca Exp $") -char Version[] = "8.12.11"; +char Version[] = "8.13.1"; diff --git a/contrib/sendmail/test/Makefile.m4 b/contrib/sendmail/test/Makefile.m4 index 579eb4edb239..1d38d6252ccb 100644 --- a/contrib/sendmail/test/Makefile.m4 +++ b/contrib/sendmail/test/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 1.3.2.1 2002/06/21 21:58:49 ca Exp $ +dnl $Id: Makefile.m4,v 1.4 2002/06/21 22:01:54 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') bldPRODUCT_START(`executable', `test') diff --git a/contrib/sendmail/vacation/Makefile.m4 b/contrib/sendmail/vacation/Makefile.m4 index 0cd52361d719..ed4967ee5495 100644 --- a/contrib/sendmail/vacation/Makefile.m4 +++ b/contrib/sendmail/vacation/Makefile.m4 @@ -1,4 +1,4 @@ -dnl $Id: Makefile.m4,v 8.24.4.1 2002/06/21 21:58:50 ca Exp $ +dnl $Id: Makefile.m4,v 8.25 2002/06/21 22:01:57 ca Exp $ include(confBUILDTOOLSDIR`/M4/switch.m4') define(`confREQUIRE_LIBSM', `true') diff --git a/contrib/sendmail/vacation/vacation.c b/contrib/sendmail/vacation/vacation.c index 281119392bd2..45aeba190247 100644 --- a/contrib/sendmail/vacation/vacation.c +++ b/contrib/sendmail/vacation/vacation.c @@ -20,7 +20,7 @@ SM_IDSTR(copyright, The Regents of the University of California. All rights reserved.\n\ Copyright (c) 1983 Eric P. Allman. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Id: vacation.c,v 8.137.2.2 2002/11/01 16:48:55 ca Exp $") +SM_IDSTR(id, "@(#)$Id: vacation.c,v 8.141 2002/11/01 16:49:40 ca Exp $") #include @@ -211,11 +211,9 @@ main(argc, argv) initdb = true; break; -#if _FFR_RESPOND_ALL case 'j': alwaysrespond = true; break; -#endif /* _FFR_RESPOND_ALL */ case 'l': list = true; /* list the database */ @@ -225,11 +223,9 @@ main(argc, argv) msgfilename = optarg; break; -#if _FFR_RETURN_ADDR case 'R': returnaddr = optarg; break; -#endif /* _FFR_RETURN_ADDR */ case 'r': if (isascii(*optarg) && isdigit(*optarg)) @@ -1042,20 +1038,9 @@ sendmessage(myname, msgfn, sender) void usage() { - char *retusage = ""; - char *respusage = ""; - -#if _FFR_RETURN_ADDR - retusage = "[-R returnaddr] "; -#endif /* _FFR_RETURN_ADDR */ - -#if _FFR_RESPOND_ALL - respusage = "[-j] "; -#endif /* _FFR_RESPOND_ALL */ - msglog(LOG_NOTICE, - "uid %u: usage: vacation [-a alias] [-C cfpath] [-d] [-f db] [-i] %s[-l] [-m msg] %s[-r interval] [-s sender] [-t time] [-U] [-x] [-z] login\n", - getuid(), respusage, retusage); + "uid %u: usage: vacation [-a alias] [-C cfpath] [-d] [-f db] [-i] [-j] [-l] [-m msg] [-R returnaddr] [-r interval] [-s sender] [-t time] [-U] [-x] [-z] login\n", + getuid()); exit(EX_USAGE); }