aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorGlen Barber <gjb@FreeBSD.org>2020-07-16 17:14:34 +0000
committerGlen Barber <gjb@FreeBSD.org>2020-07-16 17:14:34 +0000
commite2c0e292e8a7ca00ba99bcfccc9e637f45c3e8b1 (patch)
tree2f8dd797ac01b5db8e5aec5691d022a77a972ba6 /contrib
parent50050b2f41417051d04ef95b176d41988a9d5b9d (diff)
parentf903a308a1b11599b6ff33725fd591a2ef685b4c (diff)
downloadsrc-e2c0e292e8a7ca00ba99bcfccc9e637f45c3e8b1.tar.gz
src-e2c0e292e8a7ca00ba99bcfccc9e637f45c3e8b1.zip
MFH
Sponsored by: Rubicon Communications, LLC (netgate.com)
Notes
Notes: svn path=/projects/release-git/; revision=363257
Diffstat (limited to 'contrib')
-rw-r--r--contrib/byacc/test/calc.tab.c668
-rw-r--r--contrib/ofed/infiniband-diags/src/ibdiag_common.c8
-rw-r--r--contrib/ofed/infiniband-diags/src/ibdiag_sa.c2
-rw-r--r--contrib/ofed/infiniband-diags/src/iblinkinfo.c5
-rw-r--r--contrib/ofed/infiniband-diags/src/ibportstate.c1
-rw-r--r--contrib/ofed/infiniband-diags/src/ibqueryerrors.c7
-rw-r--r--contrib/ofed/infiniband-diags/src/ibroute.c3
-rw-r--r--contrib/ofed/libibumad/umad_str.c3
-rw-r--r--contrib/ofed/libibverbs/device.c3
-rw-r--r--contrib/ofed/libibverbs/examples/rc_pingpong.c6
-rw-r--r--contrib/ofed/libibverbs/examples/srq_pingpong.c6
-rw-r--r--contrib/ofed/libibverbs/examples/uc_pingpong.c6
-rw-r--r--contrib/ofed/libibverbs/examples/ud_pingpong.c6
-rw-r--r--contrib/ofed/libibverbs/examples/xsrq_pingpong.c6
-rw-r--r--contrib/ofed/libmlx5/bitmap.h8
-rw-r--r--contrib/ofed/librdmacm/examples/mckey.c3
-rw-r--r--contrib/ofed/opensm/opensm/osm_perfmgr.c4
-rw-r--r--contrib/ofed/opensm/opensm/osm_port.c4
-rw-r--r--contrib/ofed/opensm/opensm/osm_sa_mad_ctrl.c1
-rw-r--r--contrib/sendmail/CACerts240
-rw-r--r--contrib/sendmail/FREEBSD-upgrade16
-rw-r--r--contrib/sendmail/KNOWNBUGS1
-rw-r--r--contrib/sendmail/LICENSE2
-rw-r--r--contrib/sendmail/PGPKEYS1334
-rw-r--r--contrib/sendmail/README4
-rw-r--r--contrib/sendmail/RELEASE_NOTES144
-rw-r--r--contrib/sendmail/cf/README89
-rw-r--r--contrib/sendmail/cf/cf/Makefile2
-rw-r--r--contrib/sendmail/cf/cf/knecht.mc4
-rw-r--r--contrib/sendmail/cf/cf/submit.cf18
-rw-r--r--contrib/sendmail/cf/feature/bcc.m42
-rw-r--r--contrib/sendmail/cf/feature/blacklist_recipients.m47
-rw-r--r--contrib/sendmail/cf/feature/blocklist_recipients.m419
-rw-r--r--contrib/sendmail/cf/feature/check_cert_altnames.m417
-rw-r--r--contrib/sendmail/cf/feature/dnsbl.m42
-rw-r--r--contrib/sendmail/cf/feature/enhdnsbl.m42
-rw-r--r--contrib/sendmail/cf/feature/tls_failures.m413
-rw-r--r--contrib/sendmail/cf/m4/cfhead.m49
-rw-r--r--contrib/sendmail/cf/m4/proto.m485
-rw-r--r--contrib/sendmail/cf/m4/version.m44
-rw-r--r--contrib/sendmail/cf/ostype/hpux10.m42
-rw-r--r--contrib/sendmail/cf/ostype/hpux9.m42
-rwxr-xr-xcontrib/sendmail/contrib/cidrexpand149
-rw-r--r--contrib/sendmail/contrib/dnsblaccess.m44
-rwxr-xr-xcontrib/sendmail/contrib/expn.pl2
-rw-r--r--contrib/sendmail/contrib/mmuegel28
-rw-r--r--contrib/sendmail/doc/op/op.me342
-rw-r--r--contrib/sendmail/editmap/Makefile2
-rw-r--r--contrib/sendmail/editmap/editmap.c8
-rw-r--r--contrib/sendmail/include/libmilter/mfapi.h20
-rw-r--r--contrib/sendmail/include/libmilter/mfdef.h4
-rw-r--r--contrib/sendmail/include/libsmdb/smdb.h77
-rw-r--r--contrib/sendmail/include/sendmail/pathnames.h16
-rw-r--r--contrib/sendmail/include/sendmail/sendmail.h2
-rw-r--r--contrib/sendmail/include/sm/assert.h8
-rw-r--r--contrib/sendmail/include/sm/bdb.h2
-rw-r--r--contrib/sendmail/include/sm/cdefs.h20
-rw-r--r--contrib/sendmail/include/sm/clock.h6
-rw-r--r--contrib/sendmail/include/sm/conf.h662
-rw-r--r--contrib/sendmail/include/sm/config.h40
-rw-r--r--contrib/sendmail/include/sm/debug.h2
-rw-r--r--contrib/sendmail/include/sm/errstring.h9
-rw-r--r--contrib/sendmail/include/sm/gen.h2
-rw-r--r--contrib/sendmail/include/sm/heap.h2
-rw-r--r--contrib/sendmail/include/sm/io.h6
-rw-r--r--contrib/sendmail/include/sm/ldap.h15
-rw-r--r--contrib/sendmail/include/sm/limits.h10
-rw-r--r--contrib/sendmail/include/sm/notify.h19
-rw-r--r--contrib/sendmail/include/sm/os/sm_os_freebsd.h16
-rw-r--r--contrib/sendmail/include/sm/rpool.h6
-rw-r--r--contrib/sendmail/include/sm/sem.h4
-rw-r--r--contrib/sendmail/include/sm/shm.h4
-rw-r--r--contrib/sendmail/include/sm/string.h6
-rw-r--r--contrib/sendmail/include/sm/test.h4
-rw-r--r--contrib/sendmail/include/sm/types.h4
-rw-r--r--contrib/sendmail/include/sm/varargs.h5
-rw-r--r--contrib/sendmail/include/sm/xtrap.h4
-rw-r--r--contrib/sendmail/libmilter/Makefile4
-rw-r--r--contrib/sendmail/libmilter/README19
-rw-r--r--contrib/sendmail/libmilter/comm.c6
-rw-r--r--contrib/sendmail/libmilter/docs/api.html71
-rw-r--r--contrib/sendmail/libmilter/docs/design.html12
-rw-r--r--contrib/sendmail/libmilter/docs/index.html2
-rw-r--r--contrib/sendmail/libmilter/docs/installation.html4
-rw-r--r--contrib/sendmail/libmilter/docs/overview.html16
-rw-r--r--contrib/sendmail/libmilter/docs/sample.html4
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_addheader.html16
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_addrcpt.html12
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html15
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_chgfrom.html12
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_chgheader.html12
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_delrcpt.html11
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_getpriv.html3
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_getsymval.html5
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_insheader.html17
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_main.html3
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_opensocket.html9
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_progress.html3
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_quarantine.html5
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_register.html25
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_replacebody.html15
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setbacklog.html3
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setconn.html9
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setdbg.html3
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setmlreply.html11
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setpriv.html5
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setreply.html13
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_setsymlist.html7
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_settimeout.html10
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_stop.html3
-rw-r--r--contrib/sendmail/libmilter/docs/smfi_version.html1
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_abort.html3
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_body.html5
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_close.html5
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_connect.html10
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_data.html7
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_envfrom.html5
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_envrcpt.html7
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_eoh.html1
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_eom.html3
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_header.html5
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_helo.html3
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_negotiate.html18
-rw-r--r--contrib/sendmail/libmilter/docs/xxfi_unknown.html9
-rw-r--r--contrib/sendmail/libmilter/engine.c42
-rw-r--r--contrib/sendmail/libmilter/example.c2
-rw-r--r--contrib/sendmail/libmilter/handler.c2
-rw-r--r--contrib/sendmail/libmilter/libmilter.h16
-rw-r--r--contrib/sendmail/libmilter/listener.c66
-rw-r--r--contrib/sendmail/libmilter/main.c2
-rw-r--r--contrib/sendmail/libmilter/monitor.c2
-rw-r--r--contrib/sendmail/libmilter/sm_gethost.c41
-rw-r--r--contrib/sendmail/libmilter/smfi.c3
-rw-r--r--contrib/sendmail/libmilter/worker.c8
-rw-r--r--contrib/sendmail/libsm/Makefile4
-rw-r--r--contrib/sendmail/libsm/Makefile.m43
-rw-r--r--contrib/sendmail/libsm/assert.c2
-rw-r--r--contrib/sendmail/libsm/clock.c46
-rw-r--r--contrib/sendmail/libsm/config.c54
-rw-r--r--contrib/sendmail/libsm/debug.c36
-rw-r--r--contrib/sendmail/libsm/errstring.c26
-rw-r--r--contrib/sendmail/libsm/exc.c4
-rw-r--r--contrib/sendmail/libsm/findfp.c18
-rw-r--r--contrib/sendmail/libsm/flags.c2
-rw-r--r--contrib/sendmail/libsm/fopen.c8
-rw-r--r--contrib/sendmail/libsm/fpos.c2
-rw-r--r--contrib/sendmail/libsm/fscanf.c2
-rw-r--r--contrib/sendmail/libsm/io.html17
-rw-r--r--contrib/sendmail/libsm/ldap.c351
-rw-r--r--contrib/sendmail/libsm/local.h2
-rw-r--r--contrib/sendmail/libsm/makebuf.c4
-rw-r--r--contrib/sendmail/libsm/mbdb.c16
-rw-r--r--contrib/sendmail/libsm/memstat.c2
-rw-r--r--contrib/sendmail/libsm/niprop.c10
-rw-r--r--contrib/sendmail/libsm/notify.c205
-rw-r--r--contrib/sendmail/libsm/refill.c4
-rw-r--r--contrib/sendmail/libsm/rewind.c2
-rw-r--r--contrib/sendmail/libsm/rpool.c12
-rw-r--r--contrib/sendmail/libsm/sem.c2
-rw-r--r--contrib/sendmail/libsm/signal.c18
-rw-r--r--contrib/sendmail/libsm/stdio.c6
-rw-r--r--contrib/sendmail/libsm/strdup.c2
-rw-r--r--contrib/sendmail/libsm/strerror.c2
-rw-r--r--contrib/sendmail/libsm/string.c31
-rw-r--r--contrib/sendmail/libsm/strio.c8
-rw-r--r--contrib/sendmail/libsm/strto.c4
-rw-r--r--contrib/sendmail/libsm/syslogio.c2
-rw-r--r--contrib/sendmail/libsm/t-event.c2
-rw-r--r--contrib/sendmail/libsm/t-exc.c2
-rw-r--r--contrib/sendmail/libsm/t-heap.c4
-rw-r--r--contrib/sendmail/libsm/t-notify.c122
-rw-r--r--contrib/sendmail/libsm/t-scanf.c2
-rw-r--r--contrib/sendmail/libsm/t-sem.c4
-rw-r--r--contrib/sendmail/libsm/vfprintf.c9
-rw-r--r--contrib/sendmail/libsm/vfscanf.c4
-rw-r--r--contrib/sendmail/libsmdb/Makefile2
-rw-r--r--contrib/sendmail/libsmdb/Makefile.m42
-rw-r--r--contrib/sendmail/libsmdb/smcdb.c575
-rw-r--r--contrib/sendmail/libsmdb/smdb.c183
-rw-r--r--contrib/sendmail/libsmdb/smdb1.c16
-rw-r--r--contrib/sendmail/libsmdb/smdb2.c107
-rw-r--r--contrib/sendmail/libsmdb/smndbm.c1
-rw-r--r--contrib/sendmail/libsmutil/Makefile2
-rw-r--r--contrib/sendmail/libsmutil/cf.c4
-rw-r--r--contrib/sendmail/libsmutil/safefile.c35
-rw-r--r--contrib/sendmail/mail.local/Makefile2
-rw-r--r--contrib/sendmail/mail.local/mail.local.c130
-rw-r--r--contrib/sendmail/mailstats/Makefile2
-rw-r--r--contrib/sendmail/mailstats/mailstats.c2
-rw-r--r--contrib/sendmail/makemap/Makefile2
-rw-r--r--contrib/sendmail/makemap/Makefile.m41
-rw-r--r--contrib/sendmail/makemap/makemap.815
-rw-r--r--contrib/sendmail/makemap/makemap.c316
-rw-r--r--contrib/sendmail/praliases/Makefile2
-rw-r--r--contrib/sendmail/praliases/praliases.c8
-rw-r--r--contrib/sendmail/rmail/Makefile2
-rw-r--r--contrib/sendmail/rmail/rmail.c2
-rw-r--r--contrib/sendmail/smrsh/Makefile2
-rw-r--r--contrib/sendmail/smrsh/smrsh.c48
-rw-r--r--contrib/sendmail/src/Makefile4
-rw-r--r--contrib/sendmail/src/Makefile.m44
-rw-r--r--contrib/sendmail/src/README30
-rw-r--r--contrib/sendmail/src/TRACEFLAGS15
-rw-r--r--contrib/sendmail/src/alias.c30
-rw-r--r--contrib/sendmail/src/arpadate.c6
-rw-r--r--contrib/sendmail/src/bf.c10
-rw-r--r--contrib/sendmail/src/collect.c31
-rw-r--r--contrib/sendmail/src/conf.c718
-rw-r--r--contrib/sendmail/src/conf.h90
-rw-r--r--contrib/sendmail/src/control.c7
-rw-r--r--contrib/sendmail/src/daemon.c452
-rw-r--r--contrib/sendmail/src/daemon.h4
-rw-r--r--contrib/sendmail/src/deliver.c660
-rw-r--r--contrib/sendmail/src/domain.c739
-rw-r--r--contrib/sendmail/src/envelope.c47
-rw-r--r--contrib/sendmail/src/err.c64
-rw-r--r--contrib/sendmail/src/headers.c87
-rw-r--r--contrib/sendmail/src/macro.c42
-rw-r--r--contrib/sendmail/src/main.c224
-rw-r--r--contrib/sendmail/src/map.c998
-rw-r--r--contrib/sendmail/src/map.h33
-rw-r--r--contrib/sendmail/src/mci.c87
-rw-r--r--contrib/sendmail/src/milter.c256
-rw-r--r--contrib/sendmail/src/mime.c16
-rw-r--r--contrib/sendmail/src/parseaddr.c62
-rw-r--r--contrib/sendmail/src/queue.c362
-rw-r--r--contrib/sendmail/src/ratectrl.c512
-rw-r--r--contrib/sendmail/src/ratectrl.h128
-rw-r--r--contrib/sendmail/src/readcf.c383
-rw-r--r--contrib/sendmail/src/recipient.c29
-rw-r--r--contrib/sendmail/src/sasl.c8
-rw-r--r--contrib/sendmail/src/savemail.c97
-rw-r--r--contrib/sendmail/src/sendmail.h631
-rw-r--r--contrib/sendmail/src/sfsasl.c49
-rw-r--r--contrib/sendmail/src/sfsasl.h4
-rw-r--r--contrib/sendmail/src/sm_resolve.c1340
-rw-r--r--contrib/sendmail/src/sm_resolve.h72
-rw-r--r--contrib/sendmail/src/srvrsmtp.c638
-rw-r--r--contrib/sendmail/src/stab.c27
-rw-r--r--contrib/sendmail/src/timers.c2
-rw-r--r--contrib/sendmail/src/tls.c1317
-rw-r--r--contrib/sendmail/src/tls.h237
-rw-r--r--contrib/sendmail/src/tlsh.c263
-rw-r--r--contrib/sendmail/src/udb.c59
-rw-r--r--contrib/sendmail/src/usersmtp.c178
-rw-r--r--contrib/sendmail/src/util.c72
-rw-r--r--contrib/sendmail/src/version.c4
-rw-r--r--contrib/sendmail/test/Results2
-rw-r--r--contrib/sendmail/vacation/Makefile2
-rw-r--r--contrib/sendmail/vacation/vacation.c20
250 files changed, 13050 insertions, 5528 deletions
diff --git a/contrib/byacc/test/calc.tab.c b/contrib/byacc/test/calc.tab.c
deleted file mode 100644
index 1f3a81f58dbc..000000000000
--- a/contrib/byacc/test/calc.tab.c
+++ /dev/null
@@ -1,668 +0,0 @@
-#ifndef lint
-static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93";
-#endif
-
-#define YYBYACC 1
-#define YYMAJOR 1
-#define YYMINOR 9
-
-#define YYEMPTY (-1)
-#define yyclearin (yychar = YYEMPTY)
-#define yyerrok (yyerrflag = 0)
-#define YYRECOVERING() (yyerrflag != 0)
-
-
-#ifndef yyparse
-#define yyparse calc_parse
-#endif /* yyparse */
-
-#ifndef yylex
-#define yylex calc_lex
-#endif /* yylex */
-
-#ifndef yyerror
-#define yyerror calc_error
-#endif /* yyerror */
-
-#ifndef yychar
-#define yychar calc_char
-#endif /* yychar */
-
-#ifndef yyval
-#define yyval calc_val
-#endif /* yyval */
-
-#ifndef yylval
-#define yylval calc_lval
-#endif /* yylval */
-
-#ifndef yydebug
-#define yydebug calc_debug
-#endif /* yydebug */
-
-#ifndef yynerrs
-#define yynerrs calc_nerrs
-#endif /* yynerrs */
-
-#ifndef yyerrflag
-#define yyerrflag calc_errflag
-#endif /* yyerrflag */
-
-#ifndef yylhs
-#define yylhs calc_lhs
-#endif /* yylhs */
-
-#ifndef yylen
-#define yylen calc_len
-#endif /* yylen */
-
-#ifndef yydefred
-#define yydefred calc_defred
-#endif /* yydefred */
-
-#ifndef yydgoto
-#define yydgoto calc_dgoto
-#endif /* yydgoto */
-
-#ifndef yysindex
-#define yysindex calc_sindex
-#endif /* yysindex */
-
-#ifndef yyrindex
-#define yyrindex calc_rindex
-#endif /* yyrindex */
-
-#ifndef yygindex
-#define yygindex calc_gindex
-#endif /* yygindex */
-
-#ifndef yytable
-#define yytable calc_table
-#endif /* yytable */
-
-#ifndef yycheck
-#define yycheck calc_check
-#endif /* yycheck */
-
-#ifndef yyname
-#define yyname calc_name
-#endif /* yyname */
-
-#ifndef yyrule
-#define yyrule calc_rule
-#endif /* yyrule */
-#define YYPREFIX "calc_"
-
-#define YYPURE 0
-
-#line 2 "calc.y"
-# include <stdio.h>
-# include <ctype.h>
-
-int regs[26];
-int base;
-
-extern int yylex(void);
-static void yyerror(const char *s);
-
-#line 109 "calc.tab.c"
-
-#ifndef YYSTYPE
-typedef int YYSTYPE;
-#endif
-
-/* compatibility with bison */
-#ifdef YYPARSE_PARAM
-/* compatibility with FreeBSD */
-# ifdef YYPARSE_PARAM_TYPE
-# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
-# else
-# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
-# endif
-#else
-# define YYPARSE_DECL() yyparse(void)
-#endif
-
-/* Parameters sent to lex. */
-#ifdef YYLEX_PARAM
-# define YYLEX_DECL() yylex(void *YYLEX_PARAM)
-# define YYLEX yylex(YYLEX_PARAM)
-#else
-# define YYLEX_DECL() yylex(void)
-# define YYLEX yylex()
-#endif
-
-/* Parameters sent to yyerror. */
-#ifndef YYERROR_DECL
-#define YYERROR_DECL() yyerror(const char *s)
-#endif
-#ifndef YYERROR_CALL
-#define YYERROR_CALL(msg) yyerror(msg)
-#endif
-
-extern int YYPARSE_DECL();
-
-#define DIGIT 257
-#define LETTER 258
-#define UMINUS 259
-#define YYERRCODE 256
-static const short calc_lhs[] = { -1,
- 0, 0, 0, 1, 1, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 3, 3,
-};
-static const short calc_len[] = { 2,
- 0, 3, 3, 1, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 2, 1, 1, 1, 2,
-};
-static const short calc_defred[] = { 1,
- 0, 0, 17, 0, 0, 0, 0, 0, 0, 3,
- 0, 15, 14, 0, 2, 0, 0, 0, 0, 0,
- 0, 0, 18, 0, 6, 0, 0, 0, 0, 9,
- 10, 11,
-};
-static const short calc_dgoto[] = { 1,
- 7, 8, 9,
-};
-static const short calc_sindex[] = { 0,
- -40, -7, 0, -55, -38, -38, 1, -29, -247, 0,
- -38, 0, 0, 22, 0, -38, -38, -38, -38, -38,
- -38, -38, 0, -29, 0, 51, 60, -20, -20, 0,
- 0, 0,
-};
-static const short calc_rindex[] = { 0,
- 0, 0, 0, 2, 0, 0, 0, 9, -9, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 10, 0, -6, 14, 5, 13, 0,
- 0, 0,
-};
-static const short calc_gindex[] = { 0,
- 0, 65, 0,
-};
-#define YYTABLESIZE 220
-static const short calc_table[] = { 6,
- 16, 6, 10, 13, 5, 11, 5, 22, 17, 23,
- 15, 15, 20, 18, 7, 19, 22, 21, 4, 5,
- 0, 20, 8, 12, 0, 0, 21, 16, 16, 0,
- 0, 16, 16, 16, 13, 16, 0, 16, 15, 15,
- 0, 0, 7, 15, 15, 7, 15, 7, 15, 7,
- 8, 12, 0, 8, 12, 8, 0, 8, 22, 17,
- 0, 0, 25, 20, 18, 0, 19, 0, 21, 13,
- 14, 0, 0, 0, 0, 24, 0, 0, 0, 0,
- 26, 27, 28, 29, 30, 31, 32, 22, 17, 0,
- 0, 0, 20, 18, 16, 19, 22, 21, 0, 0,
- 0, 20, 18, 0, 19, 0, 21, 0, 0, 0,
- 0, 0, 0, 0, 16, 0, 0, 13, 0, 0,
- 0, 0, 0, 0, 0, 15, 0, 0, 7, 0,
- 0, 0, 0, 0, 0, 0, 8, 12, 0, 0,
- 0, 0, 0, 0, 0, 16, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 2, 3, 4, 3, 12,
-};
-static const short calc_check[] = { 40,
- 10, 40, 10, 10, 45, 61, 45, 37, 38, 257,
- 10, 10, 42, 43, 10, 45, 37, 47, 10, 10,
- -1, 42, 10, 10, -1, -1, 47, 37, 38, -1,
- -1, 41, 42, 43, 41, 45, -1, 47, 37, 38,
- -1, -1, 38, 42, 43, 41, 45, 43, 47, 45,
- 38, 38, -1, 41, 41, 43, -1, 45, 37, 38,
- -1, -1, 41, 42, 43, -1, 45, -1, 47, 5,
- 6, -1, -1, -1, -1, 11, -1, -1, -1, -1,
- 16, 17, 18, 19, 20, 21, 22, 37, 38, -1,
- -1, -1, 42, 43, 124, 45, 37, 47, -1, -1,
- -1, 42, 43, -1, 45, -1, 47, -1, -1, -1,
- -1, -1, -1, -1, 124, -1, -1, 124, -1, -1,
- -1, -1, -1, -1, -1, 124, -1, -1, 124, -1,
- -1, -1, -1, -1, -1, -1, 124, 124, -1, -1,
- -1, -1, -1, -1, -1, 124, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 256, 257, 258, 257, 258,
-};
-#define YYFINAL 1
-#ifndef YYDEBUG
-#define YYDEBUG 0
-#endif
-#define YYMAXTOKEN 259
-#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a))
-#if YYDEBUG
-static const char *yyname[] = {
-
-"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,
-0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,"DIGIT","LETTER","UMINUS","illegal-symbol",
-};
-static const char *yyrule[] = {
-"$accept : list",
-"list :",
-"list : list stat '\\n'",
-"list : list error '\\n'",
-"stat : expr",
-"stat : LETTER '=' expr",
-"expr : '(' expr ')'",
-"expr : expr '+' expr",
-"expr : expr '-' expr",
-"expr : expr '*' expr",
-"expr : expr '/' expr",
-"expr : expr '%' expr",
-"expr : expr '&' expr",
-"expr : expr '|' expr",
-"expr : '-' expr",
-"expr : LETTER",
-"expr : number",
-"number : DIGIT",
-"number : number DIGIT",
-
-};
-#endif
-
-int yydebug;
-int yynerrs;
-
-int yyerrflag;
-int yychar;
-YYSTYPE yyval;
-YYSTYPE yylval;
-
-/* define the initial stack-sizes */
-#ifdef YYSTACKSIZE
-#undef YYMAXDEPTH
-#define YYMAXDEPTH YYSTACKSIZE
-#else
-#ifdef YYMAXDEPTH
-#define YYSTACKSIZE YYMAXDEPTH
-#else
-#define YYSTACKSIZE 10000
-#define YYMAXDEPTH 10000
-#endif
-#endif
-
-#define YYINITSTACKSIZE 200
-
-typedef struct {
- unsigned stacksize;
- short *s_base;
- short *s_mark;
- short *s_last;
- YYSTYPE *l_base;
- YYSTYPE *l_mark;
-} YYSTACKDATA;
-/* variables for the parser stack */
-static YYSTACKDATA yystack;
-#line 66 "calc.y"
- /* start of programs */
-
-int
-main (void)
-{
- while(!feof(stdin)) {
- yyparse();
- }
- return 0;
-}
-
-static void
-yyerror(const char *s)
-{
- fprintf(stderr, "%s\n", s);
-}
-
-int
-yylex(void)
-{
- /* lexical analysis routine */
- /* returns LETTER for a lower case letter, yylval = 0 through 25 */
- /* return DIGIT for a digit, yylval = 0 through 9 */
- /* all other characters are returned immediately */
-
- int c;
-
- while( (c=getchar()) == ' ' ) { /* skip blanks */ }
-
- /* c is now nonblank */
-
- if( islower( c )) {
- yylval = c - 'a';
- return ( LETTER );
- }
- if( isdigit( c )) {
- yylval = c - '0';
- return ( DIGIT );
- }
- return( c );
-}
-#line 347 "calc.tab.c"
-
-#if YYDEBUG
-#include <stdio.h> /* needed for printf */
-#endif
-
-#include <stdlib.h> /* needed for malloc, etc */
-#include <string.h> /* needed for memset */
-
-/* allocate initial stack or double stack size, up to YYMAXDEPTH */
-static int yygrowstack(YYSTACKDATA *data)
-{
- int i;
- unsigned newsize;
- short *newss;
- YYSTYPE *newvs;
-
- if ((newsize = data->stacksize) == 0)
- newsize = YYINITSTACKSIZE;
- else if (newsize >= YYMAXDEPTH)
- return -1;
- else if ((newsize *= 2) > YYMAXDEPTH)
- newsize = YYMAXDEPTH;
-
- i = (int) (data->s_mark - data->s_base);
- newss = (short *)realloc(data->s_base, newsize * sizeof(*newss));
- if (newss == 0)
- return -1;
-
- data->s_base = newss;
- data->s_mark = newss + i;
-
- newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs));
- if (newvs == 0)
- return -1;
-
- data->l_base = newvs;
- data->l_mark = newvs + i;
-
- data->stacksize = newsize;
- data->s_last = data->s_base + newsize - 1;
- return 0;
-}
-
-#if YYPURE || defined(YY_NO_LEAKS)
-static void yyfreestack(YYSTACKDATA *data)
-{
- free(data->s_base);
- free(data->l_base);
- memset(data, 0, sizeof(*data));
-}
-#else
-#define yyfreestack(data) /* nothing */
-#endif
-
-#define YYABORT goto yyabort
-#define YYREJECT goto yyabort
-#define YYACCEPT goto yyaccept
-#define YYERROR goto yyerrlab
-
-int
-YYPARSE_DECL()
-{
- int yym, yyn, yystate;
-#if YYDEBUG
- const char *yys;
-
- if ((yys = getenv("YYDEBUG")) != 0)
- {
- yyn = *yys;
- if (yyn >= '0' && yyn <= '9')
- yydebug = yyn - '0';
- }
-#endif
-
- yynerrs = 0;
- yyerrflag = 0;
- yychar = YYEMPTY;
- yystate = 0;
-
-#if YYPURE
- memset(&yystack, 0, sizeof(yystack));
-#endif
-
- if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow;
- yystack.s_mark = yystack.s_base;
- yystack.l_mark = yystack.l_base;
- yystate = 0;
- *yystack.s_mark = 0;
-
-yyloop:
- if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
- if (yychar < 0)
- {
- if ((yychar = YYLEX) < 0) yychar = 0;
-#if YYDEBUG
- if (yydebug)
- {
- yys = yyname[YYTRANSLATE(yychar)];
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, yystate, yychar, yys);
- }
-#endif
- }
- if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: state %d, shifting to state %d\n",
- YYPREFIX, yystate, yytable[yyn]);
-#endif
- if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
- {
- goto yyoverflow;
- }
- yystate = yytable[yyn];
- *++yystack.s_mark = yytable[yyn];
- *++yystack.l_mark = yylval;
- yychar = YYEMPTY;
- if (yyerrflag > 0) --yyerrflag;
- goto yyloop;
- }
- if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
- {
- yyn = yytable[yyn];
- goto yyreduce;
- }
- if (yyerrflag) goto yyinrecovery;
-
- yyerror("syntax error");
-
- goto yyerrlab;
-
-yyerrlab:
- ++yynerrs;
-
-yyinrecovery:
- if (yyerrflag < 3)
- {
- yyerrflag = 3;
- for (;;)
- {
- if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: state %d, error recovery shifting\
- to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]);
-#endif
- if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
- {
- goto yyoverflow;
- }
- yystate = yytable[yyn];
- *++yystack.s_mark = yytable[yyn];
- *++yystack.l_mark = yylval;
- goto yyloop;
- }
- else
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: error recovery discarding state %d\n",
- YYPREFIX, *yystack.s_mark);
-#endif
- if (yystack.s_mark <= yystack.s_base) goto yyabort;
- --yystack.s_mark;
- --yystack.l_mark;
- }
- }
- }
- else
- {
- if (yychar == 0) goto yyabort;
-#if YYDEBUG
- if (yydebug)
- {
- yys = yyname[YYTRANSLATE(yychar)];
- printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
- YYPREFIX, yystate, yychar, yys);
- }
-#endif
- yychar = YYEMPTY;
- goto yyloop;
- }
-
-yyreduce:
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: state %d, reducing by rule %d (%s)\n",
- YYPREFIX, yystate, yyn, yyrule[yyn]);
-#endif
- yym = yylen[yyn];
- if (yym)
- yyval = yystack.l_mark[1-yym];
- else
- memset(&yyval, 0, sizeof yyval);
- switch (yyn)
- {
-case 3:
-#line 28 "calc.y"
- { yyerrok ; }
-break;
-case 4:
-#line 32 "calc.y"
- { printf("%d\n",yystack.l_mark[0]);}
-break;
-case 5:
-#line 34 "calc.y"
- { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; }
-break;
-case 6:
-#line 38 "calc.y"
- { yyval = yystack.l_mark[-1]; }
-break;
-case 7:
-#line 40 "calc.y"
- { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; }
-break;
-case 8:
-#line 42 "calc.y"
- { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; }
-break;
-case 9:
-#line 44 "calc.y"
- { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; }
-break;
-case 10:
-#line 46 "calc.y"
- { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; }
-break;
-case 11:
-#line 48 "calc.y"
- { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; }
-break;
-case 12:
-#line 50 "calc.y"
- { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; }
-break;
-case 13:
-#line 52 "calc.y"
- { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; }
-break;
-case 14:
-#line 54 "calc.y"
- { yyval = - yystack.l_mark[0]; }
-break;
-case 15:
-#line 56 "calc.y"
- { yyval = regs[yystack.l_mark[0]]; }
-break;
-case 17:
-#line 61 "calc.y"
- { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; }
-break;
-case 18:
-#line 63 "calc.y"
- { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; }
-break;
-#line 609 "calc.tab.c"
- }
- yystack.s_mark -= yym;
- yystate = *yystack.s_mark;
- yystack.l_mark -= yym;
- yym = yylhs[yyn];
- if (yystate == 0 && yym == 0)
- {
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: after reduction, shifting from state 0 to\
- state %d\n", YYPREFIX, YYFINAL);
-#endif
- yystate = YYFINAL;
- *++yystack.s_mark = YYFINAL;
- *++yystack.l_mark = yyval;
- if (yychar < 0)
- {
- if ((yychar = YYLEX) < 0) yychar = 0;
-#if YYDEBUG
- if (yydebug)
- {
- yys = yyname[YYTRANSLATE(yychar)];
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, YYFINAL, yychar, yys);
- }
-#endif
- }
- if (yychar == 0) goto yyaccept;
- goto yyloop;
- }
- if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
- yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
- yystate = yytable[yyn];
- else
- yystate = yydgoto[yym];
-#if YYDEBUG
- if (yydebug)
- printf("%sdebug: after reduction, shifting from state %d \
-to state %d\n", YYPREFIX, *yystack.s_mark, yystate);
-#endif
- if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
- {
- goto yyoverflow;
- }
- *++yystack.s_mark = (short) yystate;
- *++yystack.l_mark = yyval;
- goto yyloop;
-
-yyoverflow:
- yyerror("yacc stack overflow");
-
-yyabort:
- yyfreestack(&yystack);
- return (1);
-
-yyaccept:
- yyfreestack(&yystack);
- return (0);
-}
diff --git a/contrib/ofed/infiniband-diags/src/ibdiag_common.c b/contrib/ofed/infiniband-diags/src/ibdiag_common.c
index ddaee8c5b559..28dedc19b7ff 100644
--- a/contrib/ofed/infiniband-diags/src/ibdiag_common.c
+++ b/contrib/ofed/infiniband-diags/src/ibdiag_common.c
@@ -120,6 +120,7 @@ static inline int val_str_true(const char *val_str)
void read_ibdiag_config(const char *file)
{
char buf[1024];
+ char orig_buf[1024];
FILE *config_fd = NULL;
char *p_prefix, *p_last;
char *name;
@@ -142,8 +143,14 @@ void read_ibdiag_config(const char *file)
if (*p_prefix == '#')
continue; /* ignore comment lines */
+ strlcpy(orig_buf, buf, sizeof(orig_buf));
name = strtok_r(p_prefix, "=", &p_last);
val_str = strtok_r(NULL, "\n", &p_last);
+ if (!name || !val_str) {
+ fprintf(stderr, "%s: malformed line in \"%s\":\n%s\n",
+ prog_name, file, orig_buf);
+ continue;
+ }
if (strncmp(name, "CA", strlen("CA")) == 0) {
free(ibd_ca);
@@ -165,6 +172,7 @@ void read_ibdiag_config(const char *file)
ibd_sakey = strtoull(val_str, 0, 0);
} else if (strncmp(name, "nd_format",
strlen("nd_format")) == 0) {
+ free(ibd_nd_format);
ibd_nd_format = strdup(val_str);
}
}
diff --git a/contrib/ofed/infiniband-diags/src/ibdiag_sa.c b/contrib/ofed/infiniband-diags/src/ibdiag_sa.c
index ea272a976d75..7154ac1b7d2c 100644
--- a/contrib/ofed/infiniband-diags/src/ibdiag_sa.c
+++ b/contrib/ofed/infiniband-diags/src/ibdiag_sa.c
@@ -222,7 +222,7 @@ static const char *ib_mad_inv_field_str[] = {
"MAD Reserved",
"MAD Reserved",
"MAD Reserved",
- "MAD Invalid value in Attribute field(s) or Attribute Modifier"
+ "MAD Invalid value in Attribute field(s) or Attribute Modifier",
"MAD UNKNOWN ERROR"
};
#define MAD_ERR_UNKNOWN (ARR_SIZE(ib_mad_inv_field_str) - 1)
diff --git a/contrib/ofed/infiniband-diags/src/iblinkinfo.c b/contrib/ofed/infiniband-diags/src/iblinkinfo.c
index 40e012d44769..13ac3e2eabc5 100644
--- a/contrib/ofed/infiniband-diags/src/iblinkinfo.c
+++ b/contrib/ofed/infiniband-diags/src/iblinkinfo.c
@@ -293,7 +293,8 @@ void print_node_header(ibnd_node_t *node, int *out_header_flag,
printf("%s%s: %s:\n",
out_prefix ? out_prefix : "",
nodetype_str(node), remap);
- (*out_header_flag)++;
+ if (out_header_flag)
+ (*out_header_flag)++;
free(remap);
}
}
@@ -397,7 +398,7 @@ void diff_node_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
}
if (output_diff && fabric2_port) {
- print_node_header(fabric1_node,
+ print_node_header(fabric2_node,
head_print,
NULL);
print_port(fabric2_node,
diff --git a/contrib/ofed/infiniband-diags/src/ibportstate.c b/contrib/ofed/infiniband-diags/src/ibportstate.c
index 06bd5d217550..7bea3398fb76 100644
--- a/contrib/ofed/infiniband-diags/src/ibportstate.c
+++ b/contrib/ofed/infiniband-diags/src/ibportstate.c
@@ -564,6 +564,7 @@ int main(int argc, char **argv)
printf("Port is already in enable state\n");
goto close_port;
}
+ /* FALLTHROUGH */
case ENABLE:
case RESET:
/* Polling */
diff --git a/contrib/ofed/infiniband-diags/src/ibqueryerrors.c b/contrib/ofed/infiniband-diags/src/ibqueryerrors.c
index 2329f9147718..3efaf135e62f 100644
--- a/contrib/ofed/infiniband-diags/src/ibqueryerrors.c
+++ b/contrib/ofed/infiniband-diags/src/ibqueryerrors.c
@@ -130,6 +130,7 @@ static void set_thres(char *name, uint32_t val)
static void set_thresholds(char *threshold_file)
{
char buf[1024];
+ char orig_buf[1024];
int val = 0;
FILE *thresf = fopen(threshold_file, "r");
char *p_prefix, *p_last;
@@ -156,8 +157,14 @@ static void set_thresholds(char *threshold_file)
if (*p_prefix == '#')
continue; /* ignore comment lines */
+ strlcpy(orig_buf, buf, sizeof(orig_buf));
name = strtok_r(p_prefix, "=", &p_last);
val_str = strtok_r(NULL, "\n", &p_last);
+ if (!name || !val_str) {
+ fprintf(stderr, "malformed line in \"%s\":\n%s\n",
+ threshold_file, orig_buf);
+ continue;
+ }
val = strtoul(val_str, NULL, 0);
set_thres(name, val);
diff --git a/contrib/ofed/infiniband-diags/src/ibroute.c b/contrib/ofed/infiniband-diags/src/ibroute.c
index 8e4544edb6e3..62abb9a8e1ae 100644
--- a/contrib/ofed/infiniband-diags/src/ibroute.c
+++ b/contrib/ofed/infiniband-diags/src/ibroute.c
@@ -354,6 +354,8 @@ char *dump_unicast_tables(ib_portid_t * portid, int startlid, int endlid)
" (%s):\n", startlid, endlid, portid2str(portid), nodeguid,
mapnd);
+ free(mapnd);
+
DEBUG("Switch top is 0x%x\n", top);
printf(" Lid Out Destination\n");
@@ -390,7 +392,6 @@ char *dump_unicast_tables(ib_portid_t * portid, int startlid, int endlid)
}
printf("%d %slids dumped \n", n, dump_all ? "" : "valid ");
- free(mapnd);
return 0;
}
diff --git a/contrib/ofed/libibumad/umad_str.c b/contrib/ofed/libibumad/umad_str.c
index 0a014f7e2021..412441375a2f 100644
--- a/contrib/ofed/libibumad/umad_str.c
+++ b/contrib/ofed/libibumad/umad_str.c
@@ -246,7 +246,6 @@ static const char * umad_sm_attr_str(__be16 attr_id)
default:
return (umad_common_attr_str(attr_id));
}
- return ("<unknown>");
}
static const char * umad_sa_attr_str(__be16 attr_id)
@@ -301,7 +300,6 @@ static const char * umad_sa_attr_str(__be16 attr_id)
default:
return (umad_common_attr_str(attr_id));
}
- return ("<unknown>");
}
static const char * umad_cm_attr_str(__be16 attr_id)
@@ -336,7 +334,6 @@ static const char * umad_cm_attr_str(__be16 attr_id)
default:
return (umad_common_attr_str(attr_id));
}
- return ("<unknown>");
}
const char * umad_attribute_str(uint8_t mgmt_class, __be16 attr_id)
diff --git a/contrib/ofed/libibverbs/device.c b/contrib/ofed/libibverbs/device.c
index 8b52dd51306b..d5cd2173cd8b 100644
--- a/contrib/ofed/libibverbs/device.c
+++ b/contrib/ofed/libibverbs/device.c
@@ -264,7 +264,6 @@ int __ibv_close_device(struct ibv_context *context)
{
int async_fd = context->async_fd;
int cmd_fd = context->cmd_fd;
- int cq_fd = -1;
struct verbs_context *context_ex;
struct verbs_device *verbs_device = verbs_get_device(context->device);
@@ -279,8 +278,6 @@ int __ibv_close_device(struct ibv_context *context)
close(async_fd);
close(cmd_fd);
- if (abi_ver <= 2)
- close(cq_fd);
return 0;
}
diff --git a/contrib/ofed/libibverbs/examples/rc_pingpong.c b/contrib/ofed/libibverbs/examples/rc_pingpong.c
index d01bdb80092a..12e427d6bd5e 100644
--- a/contrib/ofed/libibverbs/examples/rc_pingpong.c
+++ b/contrib/ofed/libibverbs/examples/rc_pingpong.c
@@ -273,7 +273,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
return NULL;
}
- listen(sockfd, 1);
+ if (listen(sockfd, 1) < 0) {
+ perror("listen() failed");
+ close(sockfd);
+ return NULL;
+ }
connfd = accept(sockfd, NULL, NULL);
close(sockfd);
if (connfd < 0) {
diff --git a/contrib/ofed/libibverbs/examples/srq_pingpong.c b/contrib/ofed/libibverbs/examples/srq_pingpong.c
index 1b40aa6076c0..703ebd6077c5 100644
--- a/contrib/ofed/libibverbs/examples/srq_pingpong.c
+++ b/contrib/ofed/libibverbs/examples/srq_pingpong.c
@@ -283,7 +283,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
return NULL;
}
- listen(sockfd, 1);
+ if (listen(sockfd, 1) < 0) {
+ perror("listen() failed");
+ close(sockfd);
+ return NULL;
+ }
connfd = accept(sockfd, NULL, NULL);
close(sockfd);
if (connfd < 0) {
diff --git a/contrib/ofed/libibverbs/examples/uc_pingpong.c b/contrib/ofed/libibverbs/examples/uc_pingpong.c
index fb030dc535b8..5eed25a2c25f 100644
--- a/contrib/ofed/libibverbs/examples/uc_pingpong.c
+++ b/contrib/ofed/libibverbs/examples/uc_pingpong.c
@@ -247,7 +247,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
return NULL;
}
- listen(sockfd, 1);
+ if (listen(sockfd, 1) < 0) {
+ perror("listen() failed");
+ close(sockfd);
+ return NULL;
+ }
connfd = accept(sockfd, NULL, NULL);
close(sockfd);
if (connfd < 0) {
diff --git a/contrib/ofed/libibverbs/examples/ud_pingpong.c b/contrib/ofed/libibverbs/examples/ud_pingpong.c
index 419925ab1d40..0dec9a34980c 100644
--- a/contrib/ofed/libibverbs/examples/ud_pingpong.c
+++ b/contrib/ofed/libibverbs/examples/ud_pingpong.c
@@ -245,7 +245,11 @@ static struct pingpong_dest *pp_server_exch_dest(struct pingpong_context *ctx,
return NULL;
}
- listen(sockfd, 1);
+ if (listen(sockfd, 1) < 0) {
+ perror("listen() failed");
+ close(sockfd);
+ return NULL;
+ }
connfd = accept(sockfd, NULL, NULL);
close(sockfd);
if (connfd < 0) {
diff --git a/contrib/ofed/libibverbs/examples/xsrq_pingpong.c b/contrib/ofed/libibverbs/examples/xsrq_pingpong.c
index b3c7f703441f..4247f84ad1b5 100644
--- a/contrib/ofed/libibverbs/examples/xsrq_pingpong.c
+++ b/contrib/ofed/libibverbs/examples/xsrq_pingpong.c
@@ -630,7 +630,11 @@ static int pp_server_connect(int port)
return 1;
}
- listen(sockfd, ctx.num_clients);
+ if (listen(sockfd, ctx.num_clients) < 0) {
+ perror("listen() failed");
+ close(sockfd);
+ return 1;
+ }
for (i = 0; i < ctx.num_clients; i++) {
connfd = accept(sockfd, NULL, NULL);
diff --git a/contrib/ofed/libmlx5/bitmap.h b/contrib/ofed/libmlx5/bitmap.h
index 4b1869053e84..f7e50375ab36 100644
--- a/contrib/ofed/libmlx5/bitmap.h
+++ b/contrib/ofed/libmlx5/bitmap.h
@@ -95,17 +95,17 @@ found:
static inline void mlx5_set_bit(unsigned int nr, unsigned long *addr)
{
- addr[(nr / BITS_PER_LONG)] |= (1 << (nr % BITS_PER_LONG));
+ addr[(nr / BITS_PER_LONG)] |= (1UL << (nr % BITS_PER_LONG));
}
-static inline void mlx5_clear_bit(unsigned int nr, unsigned long *addr)
+static inline void mlx5_clear_bit(unsigned int nr, unsigned long *addr)
{
- addr[(nr / BITS_PER_LONG)] &= ~(1 << (nr % BITS_PER_LONG));
+ addr[(nr / BITS_PER_LONG)] &= ~(1UL << (nr % BITS_PER_LONG));
}
static inline int mlx5_test_bit(unsigned int nr, const unsigned long *addr)
{
- return !!(addr[(nr / BITS_PER_LONG)] & (1 << (nr % BITS_PER_LONG)));
+ return !!(addr[(nr / BITS_PER_LONG)] & (1UL << (nr % BITS_PER_LONG)));
}
#endif
diff --git a/contrib/ofed/librdmacm/examples/mckey.c b/contrib/ofed/librdmacm/examples/mckey.c
index b39a2e0c9371..65c80d4efc7f 100644
--- a/contrib/ofed/librdmacm/examples/mckey.c
+++ b/contrib/ofed/librdmacm/examples/mckey.c
@@ -469,8 +469,7 @@ static int get_dst_addr(char *dst, struct sockaddr *addr)
sib = (struct sockaddr_ib *) addr;
memset(sib, 0, sizeof *sib);
sib->sib_family = AF_IB;
- inet_pton(AF_INET6, dst, &sib->sib_addr);
- return 0;
+ return inet_pton(AF_INET6, dst, &sib->sib_addr) != 1;
}
static int run(void)
diff --git a/contrib/ofed/opensm/opensm/osm_perfmgr.c b/contrib/ofed/opensm/opensm/osm_perfmgr.c
index 3116cb3a49b8..6cd8bb7cfcff 100644
--- a/contrib/ofed/opensm/opensm/osm_perfmgr.c
+++ b/contrib/ofed/opensm/opensm/osm_perfmgr.c
@@ -1935,7 +1935,9 @@ ib_api_status_t osm_perfmgr_init(osm_perfmgr_t * pm, osm_opensm_t * osm,
pm->state =
p_opt->perfmgr ? PERFMGR_STATE_ENABLED : PERFMGR_STATE_DISABLE;
pm->sweep_state = PERFMGR_SWEEP_SLEEP;
- cl_spinlock_init(&pm->lock);
+ status = cl_spinlock_init(&pm->lock);
+ if (status != IB_SUCCESS)
+ goto Exit;
pm->sweep_time_s = p_opt->perfmgr_sweep_time_s;
pm->max_outstanding_queries = p_opt->perfmgr_max_outstanding_queries;
pm->ignore_cas = p_opt->perfmgr_ignore_cas;
diff --git a/contrib/ofed/opensm/opensm/osm_port.c b/contrib/ofed/opensm/opensm/osm_port.c
index 35010e31bbfd..47b9e920d29e 100644
--- a/contrib/ofed/opensm/opensm/osm_port.c
+++ b/contrib/ofed/opensm/opensm/osm_port.c
@@ -161,8 +161,10 @@ osm_port_t *osm_port_new(IN const ib_node_info_t * p_ni,
only the singular part that has this GUID is owned.
*/
p_physp = osm_node_get_physp_ptr(p_parent_node, port_num);
- if (!p_physp)
+ if (!p_physp) {
+ osm_port_delete(&p_port);
return NULL;
+ }
CL_ASSERT(port_guid == osm_physp_get_port_guid(p_physp));
p_port->p_physp = p_physp;
diff --git a/contrib/ofed/opensm/opensm/osm_sa_mad_ctrl.c b/contrib/ofed/opensm/opensm/osm_sa_mad_ctrl.c
index dbab4a95ecf2..2df6f18237ff 100644
--- a/contrib/ofed/opensm/opensm/osm_sa_mad_ctrl.c
+++ b/contrib/ofed/opensm/opensm/osm_sa_mad_ctrl.c
@@ -373,6 +373,7 @@ static void sa_mad_ctrl_rcv_callback(IN osm_madw_t * p_madw, IN void *context,
case IB_MAD_METHOD_GETMULTI:
#endif
is_get_request = TRUE;
+ /* FALLTHROUGH */
case IB_MAD_METHOD_SET:
case IB_MAD_METHOD_DELETE:
/* if we are closing down simply do nothing */
diff --git a/contrib/sendmail/CACerts b/contrib/sendmail/CACerts
index b5deb36b19b1..630707555657 100644
--- a/contrib/sendmail/CACerts
+++ b/contrib/sendmail/CACerts
@@ -1,4 +1,3 @@
-# $Id: CACerts,v 8.6 2013-01-18 15:14:17 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.
@@ -10,189 +9,92 @@ Certificate:
Data:
Version: 3 (0x2)
Serial Number:
- 92:91:67:de:e0:ef:2c:e4
+ 81:9d:41:0f:40:55:ac:4a
Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2015/emailAddress=ca+ca-rsa2015@esmtp.org
+ Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=CA/emailAddress=ca+ca-rsa2018@esmtp.org
Validity
- Not Before: Mar 2 19:15:29 2015 GMT
- Not After : Mar 1 19:15:29 2018 GMT
- Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2015/emailAddress=ca+ca-rsa2015@esmtp.org
+ Not Before: Feb 27 02:30:55 2018 GMT
+ Not After : Feb 26 02:30:55 2021 GMT
+ Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=CA/emailAddress=ca+ca-rsa2018@esmtp.org
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
- 00:b9:1a:a1:56:ce:cb:16:af:4f:96:ba:2a:70:31:
- 70:d3:86:6c:7a:46:26:47:42:3f:de:49:57:3e:08:
- 1e:10:25:bf:06:8f:ca:fd:f4:5e:6a:01:7d:31:4d:
- 50:88:18:43:71:66:65:42:9c:90:97:0d:95:f2:14:
- ef:d7:5e:77:ef:7d:b5:49:3f:02:bb:83:20:f7:e6:
- fc:9a:cd:13:df:60:41:28:8e:39:07:a6:a4:40:98:
- 15:1e:46:b6:04:2e:f9:ab:32:d1:8b:fe:52:81:f1:
- d2:e1:c3:cf:bf:ab:40:a7:f0:e4:e5:a2:82:37:30:
- 8c:10:7d:aa:a8:7c:7e:76:cc:5f:1a:24:d0:8c:94:
- f6:f2:7f:4a:be:2f:38:67:c0:06:e6:9e:51:ad:55:
- d0:cb:26:71:cf:f4:af:7d:5a:41:81:16:fb:26:ec:
- f0:35:01:6e:db:f9:e9:00:d7:d0:89:7b:cf:88:16:
- 8b:1c:8f:77:1f:5d:ef:70:04:28:76:c5:1b:c6:23:
- 8d:49:6b:f0:b8:21:56:d6:7d:68:6c:be:21:e3:e6:
- e3:1d:6f:a5:ea:dc:83:e4:27:b3:6f:5f:1b:3d:33:
- a1:d5:d3:f0:73:1a:12:eb:d9:95:00:71:59:16:b4:
- e4:60:38:b2:2e:7f:b7:d4:c5:e9:3f:74:e4:48:38:
- 29:89
+ 00:b8:a3:8d:79:28:c1:1f:9c:11:74:43:26:e1:3b:
+ cc:14:87:5b:6b:64:4c:ed:79:1b:7f:2a:03:d0:7b:
+ ef:9e:88:b0:64:36:ee:58:ef:fd:d9:c7:20:b3:71:
+ e9:6d:1e:a7:bc:c1:7c:3b:fe:2a:e4:16:2f:bc:d6:
+ 2c:f5:98:f9:c4:21:1c:ca:c3:7e:57:89:c8:a9:2f:
+ da:6b:9b:52:d6:c9:9d:98:97:6d:08:7c:a6:37:4e:
+ d4:26:bb:db:73:b0:38:ef:7d:1e:dd:8e:dd:8e:17:
+ 2f:a0:3d:a9:0e:4d:f0:2b:b8:14:23:33:ad:c8:a0:
+ e5:9d:0f:27:ad:83:a2:78:90:05:ec:29:06:91:07:
+ 45:6c:5f:ba:8e:1d:f1:d7:1b:2d:f9:99:ba:2e:27:
+ e1:03:7d:e9:d2:54:35:cc:39:79:07:83:d8:93:9b:
+ d6:ef:72:ab:d4:63:8e:6b:f7:00:66:5f:77:e8:b6:
+ bc:de:5f:8c:d0:ce:1a:c4:db:03:9d:e4:ee:0a:ec:
+ 77:c5:f2:30:69:7e:70:12:e5:c2:4a:28:3f:e7:19:
+ eb:af:41:fb:e6:a6:1d:b5:fd:2b:99:03:f5:20:90:
+ 38:73:bd:43:70:da:cf:1f:34:5d:ab:17:4b:73:cf:
+ f9:3d:e1:a2:79:14:de:d8:40:85:82:c4:5a:84:82:
+ 32:f1
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
- B1:69:DB:5E:9B:CE:1A:B4:1D:B2:6A:FC:5A:22:97:B6:24:14:6F:32
+ 42:37:75:E7:8F:12:CF:D9:EB:21:22:7D:8A:E8:49:21:FD:E2:3A:3A
X509v3 Authority Key Identifier:
- keyid:B1:69:DB:5E:9B:CE:1A:B4:1D:B2:6A:FC:5A:22:97:B6:24:14:6F:32
- DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=Claus Assmann CA RSA 2015/emailAddress=ca+ca-rsa2015@esmtp.org
- serial:92:91:67:DE:E0:EF:2C:E4
-
+ keyid:42:37:75:E7:8F:12:CF:D9:EB:21:22:7D:8A:E8:49:21:FD:E2:3A:3A
+ DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=CA/emailAddress=ca+ca-rsa2018@esmtp.org
+ serial:81:9D:41:0F:40:55:AC:4A
X509v3 Basic Constraints:
CA:TRUE
X509v3 Subject Alternative Name:
- email:ca+ca-rsa2015@esmtp.org
+ email:ca+ca-rsa2018@esmtp.org
X509v3 Issuer Alternative Name:
- email:ca+ca-rsa2015@esmtp.org
+ email:ca+ca-rsa2018@esmtp.org
Signature Algorithm: sha1WithRSAEncryption
- 0a:ce:07:39:77:08:c5:3a:00:04:e8:a0:3b:f7:d2:4c:79:02:
- 23:0b:da:c0:55:39:82:71:0a:0c:83:e2:de:f2:3b:fe:23:bc:
- 9b:13:34:d1:29:0a:16:3f:01:7d:9f:fb:4b:aa:12:dc:3b:7e:
- b9:27:7b:ec:0c:3f:c0:d9:f5:d8:a8:a1:9c:1c:3a:2f:40:df:
- 27:1a:1a:a0:74:00:19:b7:82:0e:f9:45:86:bf:32:da:0e:72:
- 0a:4c:2c:39:21:63:c3:1f:61:6e:e2:4d:ba:7a:26:1a:15:ce:
- b1:f6:1a:59:04:70:ed:e8:72:05:4c:fc:84:c6:a5:f4:e2:4a:
- 40:e4:42:70:87:9a:a7:02:26:3a:47:34:09:e0:7b:88:ca:fb:
- 99:d9:9b:bb:0c:52:8a:93:d5:59:30:0b:55:42:b4:bb:d2:b1:
- 49:55:81:a4:70:a0:49:19:f2:4f:61:94:af:e9:d7:62:68:65:
- 97:67:00:26:b8:9b:b2:2c:d0:2c:83:7d:3e:b3:31:73:b9:55:
- 49:53:fa:a3:ad:1b:02:67:08:9e:ce:9e:eb:9f:47:0d:6c:95:
- e9:6c:30:92:c1:94:67:ad:d9:e3:b9:61:ea:a9:72:98:81:3a:
- 62:80:70:20:9a:3e:c4:1f:6f:bd:b4:00:ec:b1:fe:71:da:91:
- 15:89:f7:8f
------BEGIN CERTIFICATE-----
-MIIFJzCCBA+gAwIBAgIJAJKRZ97g7yzkMA0GCSqGSIb3DQEBBQUAMIGlMQswCQYD
-VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkx
-FDASBgNVBAoMC0VuZG1haWwgT3JnMQwwCgYDVQQLDANNVEExIjAgBgNVBAMMGUNs
-YXVzIEFzc21hbm4gQ0EgUlNBIDIwMTUxJjAkBgkqhkiG9w0BCQEWF2NhK2NhLXJz
-YTIwMTVAZXNtdHAub3JnMB4XDTE1MDMwMjE5MTUyOVoXDTE4MDMwMTE5MTUyOVow
-gaUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMREwDwYDVQQHDAhC
-ZXJrZWxleTEUMBIGA1UECgwLRW5kbWFpbCBPcmcxDDAKBgNVBAsMA01UQTEiMCAG
-A1UEAwwZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAxNTEmMCQGCSqGSIb3DQEJARYX
-Y2ErY2EtcnNhMjAxNUBlc210cC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQC5GqFWzssWr0+WuipwMXDThmx6RiZHQj/eSVc+CB4QJb8Gj8r99F5q
-AX0xTVCIGENxZmVCnJCXDZXyFO/XXnfvfbVJPwK7gyD35vyazRPfYEEojjkHpqRA
-mBUeRrYELvmrMtGL/lKB8dLhw8+/q0Cn8OTlooI3MIwQfaqofH52zF8aJNCMlPby
-f0q+LzhnwAbmnlGtVdDLJnHP9K99WkGBFvsm7PA1AW7b+ekA19CJe8+IFoscj3cf
-Xe9wBCh2xRvGI41Ja/C4IVbWfWhsviHj5uMdb6Xq3IPkJ7NvXxs9M6HV0/BzGhLr
-2ZUAcVkWtORgOLIuf7fUxek/dORIOCmJAgMBAAGjggFWMIIBUjAdBgNVHQ4EFgQU
-sWnbXpvOGrQdsmr8WiKXtiQUbzIwgdoGA1UdIwSB0jCBz4AUsWnbXpvOGrQdsmr8
-WiKXtiQUbzKhgaukgagwgaUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9y
-bmlhMREwDwYDVQQHDAhCZXJrZWxleTEUMBIGA1UECgwLRW5kbWFpbCBPcmcxDDAK
-BgNVBAsMA01UQTEiMCAGA1UEAwwZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAxNTEm
-MCQGCSqGSIb3DQEJARYXY2ErY2EtcnNhMjAxNUBlc210cC5vcmeCCQCSkWfe4O8s
-5DAMBgNVHRMEBTADAQH/MCIGA1UdEQQbMBmBF2NhK2NhLXJzYTIwMTVAZXNtdHAu
-b3JnMCIGA1UdEgQbMBmBF2NhK2NhLXJzYTIwMTVAZXNtdHAub3JnMA0GCSqGSIb3
-DQEBBQUAA4IBAQAKzgc5dwjFOgAE6KA799JMeQIjC9rAVTmCcQoMg+Le8jv+I7yb
-EzTRKQoWPwF9n/tLqhLcO365J3vsDD/A2fXYqKGcHDovQN8nGhqgdAAZt4IO+UWG
-vzLaDnIKTCw5IWPDH2Fu4k26eiYaFc6x9hpZBHDt6HIFTPyExqX04kpA5EJwh5qn
-AiY6RzQJ4HuIyvuZ2Zu7DFKKk9VZMAtVQrS70rFJVYGkcKBJGfJPYZSv6ddiaGWX
-ZwAmuJuyLNAsg30+szFzuVVJU/qjrRsCZwiezp7rn0cNbJXpbDCSwZRnrdnjuWHq
-qXKYgTpigHAgmj7EH2+9tADssf5x2pEVifeP
------END CERTIFICATE-----
+ 0b:4c:e5:c2:ed:0a:e5:7b:95:29:22:d4:8f:5f:cb:1b:b1:e3:
+ 4c:fc:90:e7:2e:97:87:87:a2:63:0d:6d:4d:f0:1f:0d:84:11:
+ dc:df:b7:fa:c3:c6:2e:07:e9:a0:e9:a6:9f:54:17:ad:1a:d0:
+ 36:be:31:cc:a5:85:a0:45:4a:87:45:80:7e:de:ea:97:68:e0:
+ 2b:09:5d:9a:31:6f:f5:78:22:c5:66:2a:99:70:9e:6d:c4:ab:
+ f6:90:01:70:53:07:66:6c:a6:b5:ce:4b:36:05:83:87:0c:a7:
+ e0:1e:34:d0:5e:76:a4:20:71:cd:9d:c1:ae:82:27:e0:6f:16:
+ 57:74:e7:63:9f:d0:3d:72:91:6d:97:a4:82:23:84:dd:6e:0d:
+ da:43:00:a7:ce:2f:f8:79:04:67:6a:e5:b0:ab:30:d8:f1:90:
+ 10:43:3b:09:77:27:34:a4:d4:c0:25:4e:21:32:a3:ab:60:1c:
+ 9d:6e:e2:65:39:51:7f:cd:9f:88:3a:7e:f4:38:af:7b:5b:a7:
+ bb:7b:70:97:21:59:fc:5c:55:a1:db:74:0a:37:1e:33:97:5f:
+ 70:32:98:b3:d9:99:4e:08:3c:de:01:82:17:9b:49:d7:fa:c9:
+ 45:8d:93:cc:42:d6:36:f2:39:3a:47:28:3f:6f:6a:e5:23:f3:
+ 5c:d4:a3:1b
-
-Certificate:
- Data:
- Version: 3 (0x2)
- Serial Number:
- f1:41:b3:3d:ba:bd:33:49
- Signature Algorithm: sha1WithRSAEncryption
- Issuer: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2012/emailAddress=ca+ca-rsa2012@esmtp.org
- Validity
- Not Before: Mar 10 02:47:46 2012 GMT
- Not After : Mar 10 02:47:46 2015 GMT
- Subject: C=US, ST=California, L=Berkeley, O=Endmail Org, OU=MTA, CN=Claus Assmann CA RSA 2012/emailAddress=ca+ca-rsa2012@esmtp.org
- Subject Public Key Info:
- Public Key Algorithm: rsaEncryption
- Public-Key: (2048 bit)
- Modulus:
- 00:a2:80:fc:c6:ce:7f:60:38:65:f4:38:f9:7a:d9:
- 87:fd:47:eb:3f:2c:4a:c9:38:77:6a:77:94:92:7f:
- 83:3d:99:57:2c:5f:37:bb:ba:12:10:17:56:fa:eb:
- 43:a6:4b:4c:1e:30:32:07:94:2f:5a:d8:65:49:29:
- fa:24:d1:f0:0b:45:2d:e5:d5:cb:7d:60:dc:a6:ce:
- a4:47:35:30:ee:5e:8d:c2:30:e7:a7:63:32:b0:59:
- 80:cc:8c:99:64:77:8f:50:8e:88:51:47:36:ea:9a:
- f3:b4:c0:8c:a6:ab:c6:42:57:88:b9:5f:9f:61:15:
- bb:79:65:93:ca:a9:fd:17:eb:87:26:8b:eb:b7:2b:
- 7e:33:05:2b:ba:c0:46:f7:08:fd:da:c1:50:9b:3d:
- 26:83:5c:53:97:89:2c:cc:5f:f2:7b:a8:b7:3d:fb:
- f2:b4:89:0d:43:ef:18:5c:21:75:71:cc:f0:c2:a3:
- 84:69:c0:a7:f3:9b:de:c1:c7:5a:5c:7e:68:da:49:
- 71:af:58:a8:51:9f:bd:f9:3d:bb:a5:92:fa:7b:1d:
- 52:f5:fe:90:59:95:27:65:a4:af:97:9a:4f:01:39:
- 59:7d:08:6f:a1:8f:42:47:49:bf:12:52:53:39:74:
- 8d:62:3b:bd:4c:4f:05:0f:c4:b9:3e:da:a8:0e:96:
- 05:2d
- Exponent: 65537 (0x10001)
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 08:38:E3:88:92:53:6E:F1:56:69:27:44:B5:4C:A0:18:CA:06:97:EB
- X509v3 Authority Key Identifier:
- keyid:08:38:E3:88:92:53:6E:F1:56:69:27:44:B5:4C:A0:18:CA:06:97:EB
- DirName:/C=US/ST=California/L=Berkeley/O=Endmail Org/OU=MTA/CN=Claus Assmann CA RSA 2012/emailAddress=ca+ca-rsa2012@esmtp.org
- serial:F1:41:B3:3D:BA:BD:33:49
-
- X509v3 Basic Constraints:
- CA:TRUE
- X509v3 Subject Alternative Name:
- email:ca+ca-rsa2012@esmtp.org
- X509v3 Issuer Alternative Name:
- email:ca+ca-rsa2012@esmtp.org
- Signature Algorithm: sha1WithRSAEncryption
- 9a:8f:4d:23:5b:30:80:e1:94:e4:66:9c:3a:17:8b:79:49:5b:
- ec:5d:e5:a1:22:2d:71:37:a1:51:e7:1d:b1:0d:a9:9b:aa:a9:
- 0d:c7:cd:d6:24:f9:e0:f0:57:be:4f:74:0c:4b:7a:42:4c:70:
- 19:2e:8e:eb:cb:1b:00:26:27:eb:1c:42:33:d5:ec:32:b4:6c:
- 7d:a3:04:a1:5c:00:49:c9:0d:4c:4d:28:37:06:22:77:ec:40:
- 15:25:3a:23:84:ae:1f:da:90:dd:c9:dc:27:ee:7c:ec:e5:df:
- b8:ba:1e:3f:ee:c2:91:a2:3f:22:92:1e:f3:06:7e:aa:e9:c3:
- 11:2d:3d:2f:85:f7:fc:d7:e2:f8:6d:70:a6:40:62:69:e7:52:
- ed:1b:19:38:72:86:08:a1:3d:47:c8:68:82:41:db:db:2a:52:
- 25:d7:49:aa:9e:c5:83:22:7d:2f:0b:df:8c:90:2d:b5:aa:33:
- c7:9b:e8:39:8f:bb:79:5b:13:2d:4e:a9:69:59:c7:09:26:e2:
- b5:53:80:86:72:bb:7c:be:e9:46:5b:d8:b2:78:42:d6:5d:c3:
- bb:3a:3b:5f:0f:e8:c3:60:fb:88:9f:3a:2b:9f:d3:7d:9f:c7:
- 32:aa:4d:34:a7:66:a1:25:16:95:a6:69:e7:86:a3:5c:b9:b9:
- df:58:05:e3
-----BEGIN CERTIFICATE-----
-MIIFJzCCBA+gAwIBAgIJAPFBsz26vTNJMA0GCSqGSIb3DQEBBQUAMIGlMQswCQYD
-VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIQmVya2VsZXkx
-FDASBgNVBAoTC0VuZG1haWwgT3JnMQwwCgYDVQQLEwNNVEExIjAgBgNVBAMTGUNs
-YXVzIEFzc21hbm4gQ0EgUlNBIDIwMTIxJjAkBgkqhkiG9w0BCQEWF2NhK2NhLXJz
-YTIwMTJAZXNtdHAub3JnMB4XDTEyMDMxMDAyNDc0NloXDTE1MDMxMDAyNDc0Nlow
-gaUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhC
-ZXJrZWxleTEUMBIGA1UEChMLRW5kbWFpbCBPcmcxDDAKBgNVBAsTA01UQTEiMCAG
-A1UEAxMZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAxMjEmMCQGCSqGSIb3DQEJARYX
-Y2ErY2EtcnNhMjAxMkBlc210cC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCigPzGzn9gOGX0OPl62Yf9R+s/LErJOHdqd5SSf4M9mVcsXze7uhIQ
-F1b660OmS0weMDIHlC9a2GVJKfok0fALRS3l1ct9YNymzqRHNTDuXo3CMOenYzKw
-WYDMjJlkd49QjohRRzbqmvO0wIymq8ZCV4i5X59hFbt5ZZPKqf0X64cmi+u3K34z
-BSu6wEb3CP3awVCbPSaDXFOXiSzMX/J7qLc9+/K0iQ1D7xhcIXVxzPDCo4RpwKfz
-m97Bx1pcfmjaSXGvWKhRn735Pbulkvp7HVL1/pBZlSdlpK+Xmk8BOVl9CG+hj0JH
-Sb8SUlM5dI1iO71MTwUPxLk+2qgOlgUtAgMBAAGjggFWMIIBUjAdBgNVHQ4EFgQU
-CDjjiJJTbvFWaSdEtUygGMoGl+swgdoGA1UdIwSB0jCBz4AUCDjjiJJTbvFWaSdE
-tUygGMoGl+uhgaukgagwgaUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9y
-bmlhMREwDwYDVQQHEwhCZXJrZWxleTEUMBIGA1UEChMLRW5kbWFpbCBPcmcxDDAK
-BgNVBAsTA01UQTEiMCAGA1UEAxMZQ2xhdXMgQXNzbWFubiBDQSBSU0EgMjAxMjEm
-MCQGCSqGSIb3DQEJARYXY2ErY2EtcnNhMjAxMkBlc210cC5vcmeCCQDxQbM9ur0z
-STAMBgNVHRMEBTADAQH/MCIGA1UdEQQbMBmBF2NhK2NhLXJzYTIwMTJAZXNtdHAu
-b3JnMCIGA1UdEgQbMBmBF2NhK2NhLXJzYTIwMTJAZXNtdHAub3JnMA0GCSqGSIb3
-DQEBBQUAA4IBAQCaj00jWzCA4ZTkZpw6F4t5SVvsXeWhIi1xN6FR5x2xDambqqkN
-x83WJPng8Fe+T3QMS3pCTHAZLo7ryxsAJifrHEIz1ewytGx9owShXABJyQ1MTSg3
-BiJ37EAVJTojhK4f2pDdydwn7nzs5d+4uh4/7sKRoj8ikh7zBn6q6cMRLT0vhff8
-1+L4bXCmQGJp51LtGxk4coYIoT1HyGiCQdvbKlIl10mqnsWDIn0vC9+MkC21qjPH
-m+g5j7t5WxMtTqlpWccJJuK1U4CGcrt8vulGW9iyeELWXcO7OjtfD+jDYPuInzor
-n9N9n8cyqk00p2ahJRaVpmnnhqNcubnfWAXj
+MIIE4jCCA8qgAwIBAgIJAIGdQQ9AVaxKMA0GCSqGSIb3DQEBBQUAMIGOMQswCQYD
+VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkx
+FDASBgNVBAoMC0VuZG1haWwgT3JnMQwwCgYDVQQLDANNVEExCzAJBgNVBAMMAkNB
+MSYwJAYJKoZIhvcNAQkBFhdjYStjYS1yc2EyMDE4QGVzbXRwLm9yZzAeFw0xODAy
+MjcwMjMwNTVaFw0yMTAyMjYwMjMwNTVaMIGOMQswCQYDVQQGEwJVUzETMBEGA1UE
+CAwKQ2FsaWZvcm5pYTERMA8GA1UEBwwIQmVya2VsZXkxFDASBgNVBAoMC0VuZG1h
+aWwgT3JnMQwwCgYDVQQLDANNVEExCzAJBgNVBAMMAkNBMSYwJAYJKoZIhvcNAQkB
+FhdjYStjYS1yc2EyMDE4QGVzbXRwLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBALijjXkowR+cEXRDJuE7zBSHW2tkTO15G38qA9B7756IsGQ27ljv
+/dnHILNx6W0ep7zBfDv+KuQWL7zWLPWY+cQhHMrDfleJyKkv2mubUtbJnZiXbQh8
+pjdO1Ca723OwOO99Ht2O3Y4XL6A9qQ5N8Cu4FCMzrcig5Z0PJ62DoniQBewpBpEH
+RWxfuo4d8dcbLfmZui4n4QN96dJUNcw5eQeD2JOb1u9yq9Rjjmv3AGZfd+i2vN5f
+jNDOGsTbA53k7grsd8XyMGl+cBLlwkooP+cZ669B++amHbX9K5kD9SCQOHO9Q3Da
+zx80XasXS3PP+T3honkU3thAhYLEWoSCMvECAwEAAaOCAT8wggE7MB0GA1UdDgQW
+BBRCN3XnjxLP2eshIn2K6Ekh/eI6OjCBwwYDVR0jBIG7MIG4gBRCN3XnjxLP2esh
+In2K6Ekh/eI6OqGBlKSBkTCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExETAPBgNVBAcMCEJlcmtlbGV5MRQwEgYDVQQKDAtFbmRtYWlsIE9yZzEM
+MAoGA1UECwwDTVRBMQswCQYDVQQDDAJDQTEmMCQGCSqGSIb3DQEJARYXY2ErY2Et
+cnNhMjAxOEBlc210cC5vcmeCCQCBnUEPQFWsSjAMBgNVHRMEBTADAQH/MCIGA1Ud
+EQQbMBmBF2NhK2NhLXJzYTIwMThAZXNtdHAub3JnMCIGA1UdEgQbMBmBF2NhK2Nh
+LXJzYTIwMThAZXNtdHAub3JnMA0GCSqGSIb3DQEBBQUAA4IBAQALTOXC7Qrle5Up
+ItSPX8sbseNM/JDnLpeHh6JjDW1N8B8NhBHc37f6w8YuB+mg6aafVBetGtA2vjHM
+pYWgRUqHRYB+3uqXaOArCV2aMW/1eCLFZiqZcJ5txKv2kAFwUwdmbKa1zks2BYOH
+DKfgHjTQXnakIHHNncGugifgbxZXdOdjn9A9cpFtl6SCI4Tdbg3aQwCnzi/4eQRn
+auWwqzDY8ZAQQzsJdyc0pNTAJU4hMqOrYBydbuJlOVF/zZ+IOn70OK97W6e7e3CX
+IVn8XFWh23QKNx4zl19wMpiz2ZlOCDzeAYIXm0nX+slFjZPMQtY28jk6Ryg/b2rl
+I/Nc1KMb
-----END CERTIFICATE-----
diff --git a/contrib/sendmail/FREEBSD-upgrade b/contrib/sendmail/FREEBSD-upgrade
index 451a2a0c9daf..1afee1bfd07c 100644
--- a/contrib/sendmail/FREEBSD-upgrade
+++ b/contrib/sendmail/FREEBSD-upgrade
@@ -1,6 +1,6 @@
$FreeBSD$
-sendmail 8.15.2
+sendmail 8.16.1
originals can be found at: ftp://ftp.sendmail.org/pub/sendmail/
For the import of sendmail, the following directories were renamed:
@@ -13,12 +13,16 @@ http://www.freebsd.org/doc/en_US.ISO8859-1/articles/committers-guide/subversion-
Then merged using:
-% set FSVN=svn+ssh://svn.freebsd.org/base
+% set FSVN=svn+ssh://repo.freebsd.org/base
% svn checkout $FSVN/head/contrib/sendmail head
% cd head
-% svn merge --accept=postpone $FSVN/vendor/sendmail/dist .
-% svn rm --force */Build [e-v]*/*.0 cf/cf/generic-*.cf cf/cf/Build
-% svn rm --force Build devtools doc/op/op.ps src/makesendmail src/sysexits.h
+### Replace XXXXXX with import revision number in next command:
+% svn merge -c rXXXXXX --accept=postpone '^/vendor/sendmail/dist' .
+% svn resolve --accept working cf/cf/Build \
+ cf/cf/generic-{bsd4.4,hpux{9,10},linux,mpeix,nextstep3.3,osf1,solaris,sunos4.1,ultrix4}.cf \
+ devtools doc/op/op.ps editmap/editmap.0 mail.local/mail.local.0 mailstats/mailstats.0 \
+ makemap/makemap.0 praliases/praliases.0 rmail/rmail.0 smrsh/smrsh.0 \
+ src/{aliases,mailq,newaliases,sendmail}.0 vacation/vacation.0
% svn propset -R svn:keywords FreeBSD=%H .
% svn propdel svn:keywords libmilter/docs/*.jpg
% svn diff --no-diff-deleted --old=$FSVN/vendor/sendmail/dist --new=.
@@ -98,4 +102,4 @@ infrastructure in FreeBSD:
usr.sbin/mailwrapper/Makefile
gshapiro@FreeBSD.org
-06-July-2015
+15-July-2020
diff --git a/contrib/sendmail/KNOWNBUGS b/contrib/sendmail/KNOWNBUGS
index de8bd0e15638..d3c0a2ff416d 100644
--- a/contrib/sendmail/KNOWNBUGS
+++ b/contrib/sendmail/KNOWNBUGS
@@ -271,4 +271,3 @@ Kresolve sequence dnsmx canon
be used if set instead of LOCAL_RELAY ($R). This will be fixed in a
future version.
-$Revision: 8.61 $, Last updated $Date: 2011-04-07 17:48:23 $
diff --git a/contrib/sendmail/LICENSE b/contrib/sendmail/LICENSE
index 9652abdc30d0..b0885930cc0c 100644
--- a/contrib/sendmail/LICENSE
+++ b/contrib/sendmail/LICENSE
@@ -37,7 +37,7 @@ each of the following conditions is met:
the "Copyright Notice" refers to the following language:
"Copyright (c) 1998-2014 Proofpoint, Inc. All rights reserved."
-3. Neither the name of Proofpoint, Inc. nor the University of California nor
+4. Neither the name of Proofpoint, Inc. nor the University of California nor
names of their contributors may be used to endorse or promote
products derived from this software without specific prior written
permission. The name "sendmail" is a trademark of Proofpoint, Inc.
diff --git a/contrib/sendmail/PGPKEYS b/contrib/sendmail/PGPKEYS
index 361d3e7b8e15..03476f63a5ed 100644
--- a/contrib/sendmail/PGPKEYS
+++ b/contrib/sendmail/PGPKEYS
@@ -8,137 +8,1089 @@ GPG: gpg --import PGPKEYS
Other versions of PGP may require you to separate each key into a
separate file and add them one at a time.
-Type Bits KeyID Created Expires Algorithm Use
-pub 1024 0x16F4CCE9 1999-06-23 ---------- RSA Sign & Encrypt
-f16 Fingerprint16 = 18 A4 51 78 CA 72 D4 A7 ED 80 BA 8A C4 98 71 1D
-uid Sendmail Security <sendmail-security@sendmail.org>
+Note that PGP 2.X and 5.X are deprecated and may not properly
+function with newer keys.
+
+pub 4096R/CA28E5A4 2016-03-04
+fingerprint: 8E6A 5575 0635 A7EA F56C FE80 3D67 CBA7 CA28 E5A4
+uid Sendmail Security <sendmail-security@sendmail.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.2.4 (Darwin)
+Version: GnuPG v1
-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
+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
-b3JnPokAlQMFEDdxaGvAKcpAFvTM6QEB1bsD/jj+vTodXqoJphCrBLwFmwymopZp
-/HHu8o8FURlL6jQ6ihCruCw6PxNMzSdgmnOgyXxyRZIVO1pUyWf/RnS/r09tPLlq
-nZxdAPquhB2pkawvFp+Y///lb92SgfbS3/dtSDDAJ8FO+CDUKS5dKuZ6vSDU6ezH
-BDYjhd6pPYVd5hz3iQCVAwUQN3Fv9XxLZ22gDhVjAQH4BQQAuCNG977A4v0xjQi8
-AJsJmlS5mKMqn/Lw+sl1h4yQwF2vzNDdxhNWjZVziK3lUIUPh86u8m5CSdN2BB1Y
-1RawLvyfpl4b9KtyXxF4fh2BYmygJ4iG+WxhpaT5RS0eFvsSefO7/w13bx5U0Z7A
-YfHMt7+CKHm7bAx3l17g3I9aCMCJAJUDBRA3cXDdzx61AyIyegEBAeZmA/4zCJxF
-aathJ0soRJOcyRDzHKbAqlShF+Mx0tzcwbE3hAZrIqJ3TRK2MbrsBNnkFHPuPF0e
-eKr7TQsXOa+ig57wlHsCOc/fd9jLITjSYKxrQuZz3CrNefPKvv6v6Ctc6TT4GwhC
-zHglLC9Bfy9zgbv2wHswRvQBmRlCaERH3HLb1okAlQMFEDd41z8j5GLUv3ukIQEB
-9WcD/iFFF2kfSTyD+IfcLl4WCaYSeD/q/fAplpOOZWnC9PB1x3YrMHn/H8zd3S5B
-05D8+MR/QL8n8/5P+pyHa4VNRbeX8g8E34ocZf48y6FeqGi8qmcTBJDgqUTO5yMu
-t+b57G2pAIzasGcoZDqC3aJnFKwPjGRxnUFJaxlogrbUYCNOiQCVAwUQN3jwKW9S
-k9ijm6ZVAQEtugP/ewRrMCdhCbWsSUOrYn1a/pfN2KiJbhs0YyOyWbU6RvJiSFY1
-0BNAxYTbymHDOn2UhUhCrUpqatmgCuxmUsoH2Y4AAFC/94/oltwDUfnw6muqqn2K
-7AelRBbJ5wUs65pHu8kfzVB5wJh8eDacKFkK0lqgtRQCE0suhqCSFUfvtzuJAJUD
-BRA3fTCCXx7Ib4gMnlUBAWddA/oD0RKLIkLspmJC3ccmkncviMSv0rME4vY0NIfm
-IC0zsYITlU/E6H/CqVmU4Hmr5hmr5GUNNtrVZ0oLH1PUjobmZcTITJZbQSS2nY02
-N6JZT5BSAwQBfUfSMwURISRQBUOfi1kLqYk3f6UTee37/+Ig2kb388T6ClcXCv82
-FrZuwIg/AwUQN30wxNTeeNh4KRvYEQLtAACfaxVaX5D1r7hrfi/zbszQ7oekyssA
-n1suZQU7/6nIhFvdusr+/VG0RFrAiQCVAwUQN307ugDy2QnruxtBAQGKlwP/asS+
-h9ct4R66OSEjXepsMvl0So8djX15ugXb3EEJjWRH1epu7obhDymAgdQOD9NEr7BF
-0FSNCUOylASGszdcS1n5AlqV+TYihXVn265Azy+hg8g2ek97tD+x6JseKsx2nh8n
-/Es+zd3mACk21qvHB0U4FjdiQeSSirNrUHGYHZiIPwMFEDd9ihWDAqGhPt8C6hEC
-tSMAn0fo1QmxEoscgdF0esw7Bn/J+Bj6AKDNzo63lHEhUpf+JIGlfA2zzS01Z4kA
-lQMFEDd9lxoA/N7tSC51jQEBmvgD/ilLDoFPLbycEorpXFP6V0toEtTelueAeQty
-SoqD3YB+pSjTtXDqFenNWaBu0hZb7B5tg40YXqyxMEYQVpJh5coy6SlupmF2fzBi
-63++FHkxuGym9EeALPJixtM9r6pTzbX8rfvElKENiU9DBUXNhRkAocYs3pxmUge0
-9THHIyDPiQB1AwUQN32t3XLJQtjqWiN5AQEIYQL/QZEjtc1pMYlnO7i0IzvZX/mI
-RfX/0l+/+jneoSqP2EbmyvH3KMyl5SeuAifohkjK0SGRlygSMl8kceUHndeIynxg
-mM6hr9SKTByFiTy8SZeV8ovYyJ2vMk3OhUVpvGmAiD8DBRA3gbAczsKIjL9qTKER
-AhdDAJwKqcVkm9TBCmutXxwVTcffjINlBgCgrMqc6UOHlUtZps33xWZLgZh4awiJ
-AJUDBRA3g9C+TCpm+b/C9j0BAaJMBACskZxjnZbvDgm0qdvESy5+jcluxTh5fUeH
-DpnkfOP0AUAe8Ykwt8syWOQZ+3Midez8JqTAu+uvNbUckuR5XL8nMYpN06ogjg1T
-CgjLito6IptqYUZgWFvGDCdDgC+m8vw7pUbqh59mDTe0X5Q/x9Cu5JxfhxnXTNBQ
-+pI8lLAmsYkAlQMFEDeD0Jt3HZKuiXLHwQEBMZoD/2FaLFJ03tEAfNQhLmSgunWV
-akXz8udE+pY7IWi6LJGu5iwtIDJ/r0nCrJ6/aqzu9JLpGhfTnhPPCXlz4NfhriRz
-12cv2Rlg+gI3Y0Fiju5eo5TWnu+qB36vQsv73xpfQ7oCmoVY2ZntQVBaf8dyFrAd
-FBf1y33xWo58zRsg2u2hiQCVAwUQN695leHU/BTm0HRxAQGANwQAmIO4anB29bKY
-vm6ulYAm1yAyzTD5TibUnk2Ecne5st4AKGJdSrmaN7i5djxkCfimT6MnAIBRG8y9
-nXW4mCMGjfDkwve800HkrSGy8uWhHs4T8TiY8mZsIgkW5tBWnHfSyOVlc7QUbCDD
-7AzrIO3x9vYIdHMM3LAdnG9PKcLjNN6IRgQQEQIABgUCOCrZQgAKCRA/9E8kOH04
-7XJEAKC7Fzj0Mr7JxxwYEqwVgMhpbmhJkQCg7Sa+dR2qpuhYH80RPvtSEpBS6NWI
-RgQQEQIABgUCOCsObAAKCRDAz2v13mRiHprlAJ9z24xI7kHeunGE41pQ3eb32dSO
-iQCcDBmlk2RVM+ecYTwf5RyT0qyk9lqIRgQQEQIABgUCOCpmUQAKCRDUpU1Ixb5z
-WIjFAJ9lIJTH5y24d7TiWlspj8R49Wz/VQCg+EdEulY4h5A5wk1D8eCs5ar5gbCJ
-AJUDBRA4YClQmAfmW9hLWSEBAb+cA/4mRKQMyimXZDCr+0FPjazysN5/GXR9wK9F
-Q0Gb++nT2Hli/oWQ6F3t1mTLI4vprpiIaFK83HZjRHHU0FEELYL7Lg3F2mirYFNt
-Yx1Ag0jZKc+ernLLXEJK8weM7KMADWz1544eMpfb9PRNdmjRyrzBYVfR+vQ1/OBp
-zwm6aLAtb4kAlQMFEDjKizecHL3i41xWNQEBjYUD/06hAwd2PGvWynmZP6BxUHW1
-iJ5YnJC/Jlr3d7AyM4I0I1twKTDHLiqUoLvqOWPO4qqO1iFNkX6/8kCjqa6ERaBq
-j50vr84knCHc6tin/df+qTR5iOKeLTFkIZVWEHKusVgLN4jNdTUoavxAUgaZxcqv
-W7JzYEMIXJ6WyA+JRLDXiQCVAwUQO1XXe3xLZ22gDhVjAQENbgP9FStaWIfIhNEo
-JTkCgxd8QkJEc/yumlv7Cw46BmDqwZLwV6sE06YPL0jiPIu9Tv8I3HqlKcK6FBOq
-aAvv6ccA7mY6PPIVtk+EZQckSX1ALOcETDNYTOSMVxbq7b0ovvm4sG6D/A28k9b+
-s2ghGKVquYdnn6rEbr8bqmUTwN7RgiqJAJUDBRA7Vdd/1uCh/k++Kt0BAXoYA/9j
-jKJfxi4Km64nHG4PhM5bm+OPoymX3uPkyOYXzHerwGIRmVl29FxG0szDPsO0gK2h
-f3B2WOGxqMpZrzR4DIdNrtC+R3KO+3FJU0F6+T4dqAOhSvIbVQ8Ic3Wf1M69rJq2
-FID4zk6B4ymesNZVK9hoY7RuuMefUZS8cODoxWlz4Yg/AwUQOCo8e/1viMYh0Kcb
-EQJ+/ACfZCL7u2dfVhIfLYqoWqcuuBJeALQAn2pIu6Qg3R0uVJt+gSIH636QM5n/
-iEYEEBECAAYFAjtUu4QACgkQorv7JAz5VvfWuACgmY47eZClnIakMnE2bOaL161Y
-iqYAoI7/PnKgJT+LU/WjXwOZHGsoMXOUiQCVAwUQO1jKrwZ+Xti/tWVpAQEYaAQA
-pM5VPqRJqQ941YdezQ1jjE7nsLOQ6SJPVUeFguvVHWSTDEcPvp0TEKUTFRruwmKx
-yLCR9Ux3Olh0rqXHydT+k6f6++FKzXj/vtHTtNOPIVQisV7K1rDS9Mvj1WdTMJxF
-300EXlUpWtAADiEYqxxIeGJ1FWcxUjRCaqA0WUMFXe2JAJUDBRA8H4S+iWliuGeM
-CgMBAUo4A/0f+n2BvpudIcJVyVBxUZK9EGdDiZSYZWEUaXnvTWbS9FtjLTIWjzmP
-kbz9gnJ+KPcXr/5RpD5XCdCC1rjQ0EpNjWLHnsaTjTDsJ9NGkLPp0lASEdUMK9NW
-tG+CCGCMDo/MHhiw09tH5gzCR1KJTFuDiHiINrk5dS+IHIXzCYYB1ohGBBARAgAG
-BQI77DSdAAoJEL+2fm9BJ4pEGE8AoPniG1xspcy7o94D3yOKlXAq4wVoAKC6sDFu
-ZS2Lja5FbtL4Tl3sl7k7hYhGBBARAgAGBQI79sVoAAoJEPFmQMK+QtymVjgAoIB7
-dEOcSKt2fYJAEtgAiIoVtKHtAJ9S6bqdAT9Xgomd79JN1KPlXRVOJohGBBARAgAG
-BQI8+g9kAAoJEC+cdg2xRYLBiEwAn3S/QfwawMiDcpQm7K7q8BTxmcrQAKDaSfAd
-Zea7tsIsjVpL627gpCf1uIhGBBARAgAGBQI9hM4xAAoJEHrsMNJ+GHnpSWoAoOsf
-gbKx+mCMRbLOEYgAU9DB13qdAJ4zkAaZCijpqqvTi0XjnPMkq7RbpYhGBBIRAgAG
-BQI+W7nOAAoJEDBS/CoUw26Bv5wAnjvZsj0SetF/Jth5uvw+jHDLp1QuAJwKy8ZY
-e1E+7dOU8CQgYD1Zy5nuaohGBBIRAgAGBQI/aaJkAAoJEC27dr+t1MkzoLcAoLEq
-jwJzYeTGbrIfhc4t4/SJnuD2AJ4gIPGnbL6fl9+9TRMlAMHo4xNcVYhGBBMRAgAG
-BQI887P9AAoJEEq61lpJwpzCcmMAoKp4ZauTD+oEBfvXtL/eBSxTA0rKAJ9uADQB
-IiVBWy54UnhJ7F6NSb2R14hGBBARAgAGBQI+9wRgAAoJELghiQKdsrW873oAn15C
-080LnClmIjRoGKppUynk7LqTAJ0RXLkjiepVsgZCW/pXYy6wK5DkeYhGBBARAgAG
-BQI/1fplAAoJEFIY2mCt64GL6UAAn1FrBfweuTEy3p+i+ekJdKf4Je4bAKC8SrPC
-WVEl5Pr+XpuP92f3KxQJtohGBBARAgAGBQI/1ftLAAoJEKTWXDNQN2ZnOuYAn36o
-95rvUoSFIiTVytWm5go8arkYAKC9rUwywbYx49u/rdUtj396kocq9YhGBBARAgAG
-BQJAC08wAAoJEIHC9+viE7aStBkAn2DN85MEaydtxX1S0Sz22Qawre//AJ9NYpd/
-BKPMY3o80IuYy6k+E5e4cIhGBBARAgAGBQJAC09qAAoJEGtw7Nldw/RzMlYAoLeH
-NbcbFnINRaU3vJLp7ieZCUrKAKC/+N6FEM2JNJzkeRsHhOvOn7EXmYhGBBARAgAG
-BQJAkTWOAAoJEKn24r/sjo2pIp4AoISelNVVxuIBl2i3t7ajQaUpruJpAKCGDYPg
-RaGIuII/2fwEGzIpZzYE5IhGBBIRAgAGBQJCNCwxAAoJEFMx5x175C/jTPMAoKFG
-qbOkCtxD3edRmA3PzE+dg39xAKCCgjpb4Y0PXk8Xu9tvaDPZcul93ohGBBMRAgAG
-BQJAC07iAAoJEBhZ0B9ne6HsIlIAn0adP67A4L45/4m8xExRv4Uc6twdAJ9PTE4G
-X3XennlL+6cVXB961V1NL4kCHAQQAQIABgUCQX8prQAKCRCq4+bOZqFEaGUHEACf
-4Om9MDBS9SilmZ22Ssa8WtrUzUL1yOuO3+n/XhvJ5lGjUwi0oW4EcMJFCKZI7DOX
-aN7zlD5akd9N0ZNg8W23xz29nnp6/upeQRQ7ckqDL/+o8DgjwCyQVH+ZzDrBDsip
-PqtVTcogBx07CioJSX1jy7CVnsaZVH111hgghSsLM3S9KrlmwQ8zzN56FbwmDyoG
-Qi3oyH9Xh+1YeCxUM4hS6Gk1wCAFCYx7Y53dDALB0MvsFMSWDflJLhae652rSot3
-jjFzH4FOdKk2/1uSVOKS8YQtLBu/Vf83q/gacdxtkyj7zdUYtSg4OHuR9JVfF+Yx
-g9v+U5PkqVSymLEv523nEoq1LMPtWhPNb5Om/T/5H2N/x+z1jSxTCZajRoMchG0R
-9k9GtcGZQqfUrdC0lztB+03KzZRJvPRUV0m2Ia0fNPUvUlTcLCdk3/brYuxEC13h
-A9qh8dIwWrX60aHanrqmeH2RSEqbnBMn1g9NRvFkV9QbGofCezKAvvRq7vZ1vFC4
-5/X3NqqHm45ISN6MitDJhJOnD+ZoARVAnFpC6pdpAg1+Ld7v1PtEj7rRAVzGOVZr
-U55f3gBIx9Ezdeh6+7HfCFSv1sKkGcYlVvriCswpUrJn5sqaFYYZvjxin1D2kwvT
-aG/4sOQOooHBU+JpdGecir2Jme+ET41NZ7/Q+OuPGIkAlQMFEEQbRB44IttHzDdP
-LQEBlmYEANBwFJxl7HWGdKLSg3PD9rd/UuPsA2iS4EcMk9h1Mz8lm1WwmE9s4mvx
-0DmNtfSHwV/GF3TwfrkvofoqXxU+b0CkNIaHPkCKP+FzFTT1dC5ZBrGBqLi6Izu2
-wDmenjGMCosR9Xv/ss8CQ4L2XF2uCGyVEmel58UHx/StYvjEeL4MiQCVAwUQRBtE
-RSGD4bE5bweJAQEAywP6A0jdCALabHlRXk2mgfdqBKEWn1H8waZLgRjebwzn0lnK
-3a2pSYZOqaDg9x4TNrHi+FZ0RZJC1u+q/nBfQw9Fqr4tavnHXuEagTJhTpzBREIc
-fNEW0vhziJPpd1Cab8ErZKICCEiVu/CFG08M+benCSEAfJN9ZS1ER/mZMvqyY/OJ
-AJUDBRBEG0RRyNXtKZX2F3EBAb47A/9WlKsdMPQuTcekXtiyImUxMIw4isRkEw/o
-Hq7Xo/TiCfa+7CyvfZ26VXa+hdh+GTtUfQeb1QP8Q/S42qfuz5t+geT06phBy1lK
-lIf7zdeptHkEfqzQ1p4/PVul9YChMAzH+qZH6RN6jh0w/aSj28fhw67rHch62fAb
-Xnn0lXBdcokAlQMFEEQbRGdwoCRNHvmSUQEB9CUEALuAxKlHjjo0Cd0Wv+VnhDr5
-+fmR9vNgpvgt3t4qHNcgTVGZza6e+T7gk8daWDP/HhHNa5he7EpNeVK+yu3SCyiI
-Y9p+e+JSx2FnOLqqddG86l3cexFahlNuxfyCnC/2c3yGsLFIKtb3vZClwvyUzfGQ
-rTqPF6sqL4TU7uv0UplNiQCVAwUQRBtEdx57s8ivlZYlAQH0YQQAlsgJ6wcI37au
-F5hG5wHYhxGSv4YNIRWAgYNFIDnk90AsG7XPcuhgyuKVfcAn6jEdVjRLhogpxo+I
-PNOeIV3kiS9LFfLgWGrx7arnrmMPOP/0l32VCum5n06CM2G7D+o7uTAU8qul1nNN
-gpExpdV7qPrw9k01j5rod5PjZlG8zV0=
-=SR28
+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
+9T92qg==
+=xY3m
+-----END PGP PUBLIC KEY BLOCK-----
+
+
+pub rsa4096/0xD583210EF51471A7 2020-04-08 [SC]
+ Key fingerprint = ADFD B709 FE1E A682 E585 5971 D583 210E F514 71A7
+uid [ full ] Sendmail Signing Key/2020 <sendmail@Sendmail.ORG>
+sub rsa4096/0x5C092A1B257B1C27 2020-04-08 [E]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+4XUsDQOZ8aKrTpMO+Q==
+=jgHV
+-----END PGP PUBLIC KEY BLOCK-----
+
+
+pub rsa4096/0x09E01FA03C0C504E 2019-01-09 [SC]
+ Key fingerprint = 50A3 0309 8EA2 DD7B CBEE 2ADA 09E0 1FA0 3C0C 504E
+uid Sendmail Signing Key/2019 <sendmail@Sendmail.ORG>
+sub rsa4096/0xEF9F24EFDC48FA66 2019-01-09 [E]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+HcRQfq7rqZkS3NE+iD9D/lUyXVYfH9A=
+=jN/3
+-----END PGP PUBLIC KEY BLOCK-----
+
+
+pub 4096R/0xF06059FD5DC7CC3F 2018-04-24 [SC]
+ Key fingerprint = A687 3D24 A4D6 D628 4AE4 2A75 F060 59FD 5DC7 CC3F
+uid Sendmail Signing Key/2018 <sendmail@Sendmail.ORG>
+sub rsa4096/0xC5A902D4AFC5E1F1 2018-04-24 [E]
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+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
+=K0Kz
+-----END PGP PUBLIC KEY BLOCK-----
+
+
+pub 4096R/6BF726AD 2016-12-31
+ Key fingerprint = 3C8A 1E8E 7F44 CADE 114F ED46 4BC9 BDA6 6BF7 26AD
+uid Sendmail Signing Key/2017 <sendmail@Sendmail.ORG>
+sub 4096R/18F184A2 2016-12-31
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+9M1ae1yHng==
+=Lt+h
+-----END PGP PUBLIC KEY BLOCK-----
+
+
+pub 2048R/29FB03DE 2016-01-04
+fingerprint: 0F5C 96AE C8E6 9E9C 8E54 2E5C 6D4C D194 29FB 03DE
+uid Sendmail Signing Key/2016 <sendmail@Sendmail.ORG>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1
+
+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
+j68I
+=MdUt
-----END PGP PUBLIC KEY BLOCK-----
@@ -1581,7 +2533,7 @@ ZNSR6KHm3A2ICdH9y0fM14u2NAlZuC0QzqbUotpwSXgDMwm3P4He9CwO7IEp0e1l
-----END PGP PUBLIC KEY BLOCK-----
Type Bits KeyID Created Expires Algorithm Use
-sec+ 1024 0x678C0A03 2001-12-18 ---------- RSA Sign & Encrypt
+sec+ 1024 0x678C0A03 2001-12-18 ---------- RSA Sign & Encrypt
f16 Fingerprint16 = 7B 02 F4 AA FC C0 22 DA 47 3E 2A 9A 9B 35 22 45
uid Sendmail Signing Key/2002 <sendmail@Sendmail.ORG>
@@ -1676,7 +2628,7 @@ AgAGBQJCGjKcAAoJEA8Ne4Mg5YjtoAQAoIvQpUF9X4yoHZWEONKNd0xTHg9dAJ9P
-----END PGP PUBLIC KEY BLOCK-----
Type Bits KeyID Created Expires Algorithm Use
-pub 1024 0xCC374F2D 2000-12-14 ---------- RSA Sign & Encrypt
+pub 1024 0xCC374F2D 2000-12-14 ---------- RSA Sign & Encrypt
f16 Fingerprint16 = 59 AF DC 3E A2 7D 29 56 89 FA 25 70 90 0D 7E C1
uid Sendmail Signing Key/2001 <sendmail@Sendmail.ORG>
@@ -1778,7 +2730,7 @@ RFljVEUVKZ/GGg==
-----END PGP PUBLIC KEY BLOCK-----
Type Bits KeyID Created Expires Algorithm Use
-pub 1024 0xE35C5635 1999-12-13 ---------- RSA Sign & Encrypt
+pub 1024 0xE35C5635 1999-12-13 ---------- RSA Sign & Encrypt
f16 Fingerprint16 = 81 8C 58 EA 7A 9D 7C 1B 09 78 AC 5E EB 99 08 5D
uid Sendmail Signing Key/2000 <sendmail@Sendmail.ORG>
@@ -2712,83 +3664,55 @@ ThUt9uNU6kU29eAHZEBI4WheX5e2wu1BxgjVAn1LqiPRyPK3jr9kzy4=
=eOEB
-----END PGP PUBLIC KEY BLOCK-----
-Type Bits KeyID Created Expires Algorithm Use
-pub 1024 0x22327A01 1999-05-30 ---------- RSA Sign & Encrypt
-f16 Fingerprint16 = 03 3D 49 6D E4 D9 D6 01 F8 9D B0 3A 3D 68 6A 86
-uid Claus Assmann (PGP2) <ca+pgp2@Sendmail.ORG>
+pub 2048R/A5AA5BE6 2013-09-06
+fingerprint: D0EF B47E 909D 1550 525E 9DF5 1090 AF20 A5AA 5BE6
+uid Claus Assmann <ca+gpg@sendmail.org>
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.2.4 (Darwin)
+Version: GnuPG v1
-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
-=nES8
+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
+q8WNeh9erYZriQ==
+=VuMX
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/sendmail/README b/contrib/sendmail/README
index a87989846590..5b11d025b866 100644
--- a/contrib/sendmail/README
+++ b/contrib/sendmail/README
@@ -431,8 +431,7 @@ makemap A program that creates the keyed maps used by the $( ... $)
expect to preprocess must human-convenient formats
using sed scripts before this program will like them.
But it should be functionally complete.
-praliases A program to print the DBM or NEWDB version of the
- aliases file.
+praliases A program to print the map version of the aliases file.
rmail Source for rmail(8). This is used as a delivery
agent for for UUCP, and could presumably be used by
other non-socket oriented mailers. Older versions of
@@ -447,4 +446,3 @@ 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.96 $, Last updated $Date: 2013-11-22 20:51:01 $
diff --git a/contrib/sendmail/RELEASE_NOTES b/contrib/sendmail/RELEASE_NOTES
index 18a7cae9faca..6a0f0c52f844 100644
--- a/contrib/sendmail/RELEASE_NOTES
+++ b/contrib/sendmail/RELEASE_NOTES
@@ -5,6 +5,124 @@ 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.16.1/8.16.1 2020/07/05
+ SECURITY: If sendmail tried to reuse an SMTP session which had
+ already been closed by the server, then the connection
+ cache could have invalid information about the session.
+ One possible consequence was that STARTTLS was not
+ used even if offered. This problem has been fixed
+ by clearing out all relevant status information
+ when a closed session is encountered.
+ OpenSSL versions before 0.9.8 are no longer supported.
+ OpenSSL version 1.1.0 and 1.1.1 are supported.
+ Initial support for DANE (see RFC 7672 et.al.) is available if
+ the compile time option DANE is set. Only TLSA RR 3-1-x
+ is currently implemented.
+ New options SSLEngine and SSLEnginePath to support OpenSSL engines.
+ Note: this feature has so far only been tested with the
+ "chil" engine; please report problems with other engines
+ if you encounter any.
+ New option CRLPath to specify a directory which contains
+ hashes pointing to certificate revocations files.
+ Based on patch from Al Smith.
+ New rulesets tls_srv_features and tls_clt_features which
+ can return a (semicolon separated) list of TLS related
+ options, e.g., CipherList, CertFile, KeyFile,
+ see doc/op/op.me for details.
+ To automatically handle TLS interoperability problems for outgoing
+ mail, sendmail can now immediately try a connection again
+ without STARTTLS after a TLS handshake failure.
+ This can be configured globally via the option
+ TLSFallbacktoClear or per session via the 'C' flag
+ of tls_clt_features.
+ This also adds the new value "CLEAR" for the macro
+ {verify}: STARTTLS has been disabled internally for
+ a clear text delivery attempt.
+ Apply Timeout.starttls also to the server waiting for the TLS
+ handshake to begin. Based on patch from Simon Hradecky.
+ New compile time option TLS_EC to enable the use of elliptic
+ curve cryptography in STARTTLS (previously available as
+ _FFR_TLS_EC).
+ Handle MIME boundaries specified in headers which contain CRLF.
+ Fix detection of loopback net (it was broken when compiled
+ with NETINET6) and only set the macros {if_addr_out}
+ and {if_family_out} if the interface of the outgoing
+ connection does not belong to the loopback net.
+ Fix logic to enable a milter to delete a recipient in
+ DeliveryMode=interactive even if it might be subject
+ to alias expansion.
+ Log name of a milter making changes (this was missing for
+ some functions).
+ Log the actual reply of a server when an SMTP delivery problem
+ occurs in a "reply=" field if possible.
+ Log user= for failed AUTH attempts if possible. Based on
+ patch from Packet Hack, Jim Hranicky, Kevin A. McGrail,
+ and Joe Quinn.
+ Add CDB as map type. Note: CDB is a "Constant DataBase", i.e.,
+ no changes can be made after it is created, hence it
+ does not work with vacation(1) nor editmap(8) (except
+ for query mode).
+ Fix some memory leaks (mostly in error cases) and properly handle
+ copied varargs in sm_io_vfprintf(). The issues were found
+ using Coverity Scan and reported (including patches) by
+ Ondřej Lysoněk of Red Hat.
+ Do not override ServerSSLOptions and ClientSSLOptions when they
+ are specified on the command line. Based on patch from
+ Hiroki Sato.
+ Add RFC7505 Null MX support for domains that declare they do not
+ accept mail.
+ New compile time option LDAP_NETWORK_TIMEOUT which is set
+ automatically when LDAPMAP is used and
+ LDAP_OPT_NETWORK_TIMEOUT is available to enable the
+ new -c option for LDAP maps to specify the network timeout.
+ CONFIG: New FEATURE(`tls_session_features') to enable standard
+ rules for tls_srv_features and tls_clt_features; for
+ details see cf/README.
+ CONFIG: New options confSSL_ENGINE and confSSL_ENGINE_PATH
+ for SSLEngine and SSLEnginePath, respectively.
+ CONFIG: New options confDANE to enable DANE support.
+ CONFIG: New option confTLS_FALLBACK_TO_CLEAR for TLSFallbacktoClear.
+ CONFIG: New extension CITag: for TLS restrictions, see cf/README
+ for details.
+ CONFIG: FEATURE(`blacklist_recipients') renamed to
+ FEATURE(`blocklist_recipients').
+ CONTRIB: cidrexpand updated to support IPv6 CIDR ranges and to
+ canonicalize IPv6 addresses; if cidrexpand is used with IPv6
+ addresses then UseCompressedIPv6Addresses must be disabled.
+ DOC: The dns map can return multiple values in a single result
+ if the -z option is used.
+ DOC: Note to set MustQuoteChars=. due to DKIM signatures.
+ LIBMILTER: Fix typo in a macro. Patch from Ignacio Goyret
+ of Alcatel-Lucent.
+ LIBMILTER: Fix reference in xxfi_negotiate documentation.
+ Patch from Sven Neuhaus.
+ LIBMILTER: Fix function name in smfi_addrcpt_par documentation.
+ Patch from G.W. Haywood.
+ LIBMILTER: Fix a potential memory leak in smfi_setsymlist().
+ Patch from Martin Svec.
+ MAKEMAP: New map type "implicit" refers to the first available type,
+ i.e., it depends on the compile time options NEWDB, DBM,
+ and CDB. This can be used in conjunction with the
+ "implicit" map type in sendmail.cf.
+ Note: makemap, libsmdb, and sendmail must be compiled
+ with the same options (and library versions of course).
+ Portability:
+ Add support for Darwin 14-18 (Mac OS X 10.x).
+ New option HAS_GETHOSTBYNAME2: set if your system
+ supports gethostbyname2(2).
+ Set SM_CONF_SEM=2 for FreeBSD 12 and later due to
+ changes in sys/sem.h
+ On Linux set MAXHOSTNAMELEN (the maximum length
+ of a FQHN) to 256 if it is less than that value.
+ Added Files:
+ cf/feature/blocklist_recipients.m4
+ cf/feature/tls_failures.m4
+ devtools/OS/Darwin.14.x
+ devtools/OS/Darwin.15.x
+ devtools/OS/Darwin.16.x
+ libsmdb/smcdb.c
+ sendmail/ratectrl.h
+
8.15.2/8.15.2 2015/07/03
If FEATURE(`nopercenthack') is used then some bogus input triggered
a recursion which was caught and logged as
@@ -104,7 +222,7 @@ summary of the changes in that release.
The option CipherList sets the list of ciphers for STARTTLS.
See ciphers(1) for possible values.
Do not log "STARTTLS: internal error: tls_verify_cb: ssl == NULL"
- if a CRLFfile is in use (and LogLevel is 14 or higher.)
+ if a CRLFile is in use (and LogLevel is 14 or higher.)
Store a more specific TLS protocol version in ${tls_version}
instead of a generic one, e.g., TLSv1 instead of
TLSv1/SSLv3.
@@ -127,7 +245,7 @@ summary of the changes in that release.
A new map type "arpa" is available to reverse an IP (IPv4 or IPv6)
address. It returns the string for the PTR lookup, but
without trailing {ip6,in-addr}.arpa.
- New operation mode 'C' just checks the configuration file, e.g.,
+ New operation mode 'C' just checks the configuration file, e.g.,
sendmail -C new.cf -bC
will perform a basic syntax/consistency check of new.cf.
The mailer flag 'I' is deprecated and will be removed in a
@@ -740,7 +858,7 @@ summary of the changes in that release.
Patches from Nelson Fung.
CONTRIB: cidrexpand uses a hash symbol as comment character and
ignores everything after it unless it is in quotes or
- preceeded by a backslash.
+ preceded by a backslash.
DEVTOOLS: New macro confMKDIR: if set to a program that creates
directories, then it used for "make install" to create
the required installation directories.
@@ -2465,7 +2583,7 @@ summary of the changes in that release.
noted by Greg Robinson of the Defence Science and
Technology Organisation of Australia.
CONFIG: dnsbl: If an argument specifies an error message in case
- of temporary lookup failures for DNS based blacklists
+ of temporary lookup failures for DNS based blocklists
then use it.
LIBMILTER: Install mfdef.h, required by mfapi.h. Problem noted by
Richard A. Nelson of Debian.
@@ -2539,7 +2657,7 @@ summary of the changes in that release.
is "pw", which means to use getpwnam(). New mailbox database
types can be added by adding custom code to libsm/mbdb.c.
Queue file names are now 15 characters long, rather than 14 characters
- long, to accomodate envelope splitting. File systems with
+ long, to accommodate envelope splitting. File systems with
a 14 character file name length limit are no longer
supported.
Recipient list used for delivery now gets internally ordered by
@@ -2580,7 +2698,7 @@ summary of the changes in that release.
New ruleset srv_features to enable/disable certain features in the
server per connection. See doc/op/op.me for details.
New ruleset tls_rcpt to decide whether to send e-mail to a particular
- recipient; useful to decide whether a conection is secure
+ recipient; useful to decide whether a connection is secure
enough on a per recipient basis.
New option TLSSrvOptions to modify some aspects of the server
for STARTTLS.
@@ -2591,7 +2709,7 @@ summary of the changes in that release.
Macro expand filenames/directories for certs and keys in the .cf file.
Proposed by Neil Rickert of Northern Illinois University.
Generate an ephemeral RSA key for a STARTTLS connection only if
- really required. This change results in a noticable
+ really required. This change results in a noticeable
performance gains on most machines. Moreover, if shared
memory is in use, reuse the key several times.
Add queue groups which can be used to group queue directories with
@@ -3500,7 +3618,7 @@ summary of the changes in that release.
CONFIG: Reject addresses of the form a!b if FEATURE(`nouucp', `r')
is used. Problem noted by Phil Homewood of Asia Online,
patch from Neil Rickert of Northern Illinois University.
- CONFIG: Change the default DNS based blacklist server for
+ CONFIG: Change the default DNS based blocklist server for
FEATURE(`dnsbl') to blackholes.mail-abuse.org.
CONFIG: Deal correctly with the 'C' flag in {daemon_flags}, i.e.,
implicitly assume canonical host names.
@@ -4736,7 +4854,7 @@ summary of the changes in that release.
from Per Hedeland of Ericsson.
If a resolver ANY query is larger than the UDP packet size, the
resolver will fall back to TCP. However, some
- misconfigured firewalls black 53/TCP so the ANY lookup
+ misconfigured firewalls block 53/TCP so the ANY lookup
fails whereas an MX or A record might succeed. Therefore,
don't fail on ANY queries.
If an SMTP recipient is rejected due to syntax errors in the
@@ -5152,7 +5270,7 @@ summary of the changes in that release.
line up into 2046-character output lines (excluding the
newline). If an input line was 2047 characters long
(excluding CR-LF) and the last character was a '.',
- mail.local saw it as the end of input, transfered it to the
+ mail.local saw it as the end of input, transferred it to the
user mailbox and tried to write an `ok' back to sendmail.
If the message was much longer, both sendmail and
mail.local would deadlock waiting for each other to read
@@ -6039,7 +6157,7 @@ summary of the changes in that release.
CONFIG: FEATURE(nodns) now warns the user that the feature is a
no-op. Patch from Kari Hurtta of the Finnish
Meteorological Institute.
- CONFIG: OSTYPE(osf1) now sets DefaultUserID (confDEF_USER_ID) to
+ CONFIG: OSTYPE(osf1) now sets DefaultUser (confDEF_USER_ID) to
daemon since DEC's /bin/mail will drop the envelope
sender if run as mailnull. See the Digital UNIX section
of src/README for more information. Problem noted by
@@ -7632,7 +7750,7 @@ summary of the changes in that release.
instead of 0644. Suggested by Ann-Kian Yeo of the
National University of Singapore.
Print errors if setgid/setuid/etc. fail during delivery. This helps
- detect cases where DefaultUid is set to something that the
+ detect cases where DefaultUser is set to something that the
system can't cope with.
PORTABILITY FIXES:
Support for AIX/RS 2.2.1 from Mark Whetzel of Western
@@ -9840,7 +9958,7 @@ summary of the changes in that release.
gethostname() (instead of myhostname(), which tries
to fully qualify the name) to be consistent with
SunOS. If your hostname is unqualified, this fixes
- transfers to slave servers. Bug noted by Keith
+ transfers to secondary servers. Bug noted by Keith
McMillan of Ameritech Services, Inc.
Fix Ultrix problem: gethostbyname() can return a very large
(> 500) h_length field, which causes the sockaddr
diff --git a/contrib/sendmail/cf/README b/contrib/sendmail/cf/README
index 91e69a918223..983aa2821a1a 100644
--- a/contrib/sendmail/cf/README
+++ b/contrib/sendmail/cf/README
@@ -396,7 +396,7 @@ SMTP_MAILER_MAXMSGS [undefined] If defined, the maximum number of
messages to deliver in a single connection for the
smtp, smtp8, esmtp, or dsmtp mailers.
SMTP_MAILER_MAXRCPTS [undefined] If defined, the maximum number of
- recipients to deliver in a single connection for the
+ recipients to deliver in a single envelope for the
smtp, smtp8, esmtp, or dsmtp mailers.
SMTP_MAILER_ARGS [TCP $h] The arguments passed to the smtp mailer.
About the only reason you would want to change this
@@ -1250,7 +1250,7 @@ access_db Turns on the access database feature. The access db gives
important information about this feature. Notice:
"-T<TMPF>" is meant literal, do not replace it by anything.
-blacklist_recipients
+blocklist_recipients
Turns on the ability to block incoming mail for certain
recipient usernames, hostnames, or addresses. For
example, you can block incoming mail to user nobody,
@@ -1579,7 +1579,7 @@ require_rdns Reject mail from connecting SMTP clients without proper
Entries such as
Connect:1.2.3.4 OK
Connect:1.2 RELAY
- will whitelist IP address 1.2.3.4, so that the rDNS
+ will allowlist IP address 1.2.3.4, so that the rDNS
blocking does apply to that IP address
Entries such as
@@ -2602,7 +2602,7 @@ requires a tag. For example,
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')
+send mail to that address even if FEATURE(`blocklist_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
@@ -2723,7 +2723,7 @@ sender address.
If you use:
- FEATURE(`blacklist_recipients')
+ FEATURE(`blocklist_recipients')
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:
@@ -2747,14 +2747,14 @@ as value part in the access map. Taking the example from above:
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 which can be found by
+There are several DNS based blocklists which can be found by
querying a search engine. These are databases of spammers
maintained in DNS. To use such a database, specify
FEATURE(`dnsbl', `dnsbl.example.com')
This will cause sendmail to reject mail from any site listed in the
-DNS based blacklist. You must select a DNS based blacklist domain
+DNS based blocklist. You must select a DNS based blocklist domain
to check by specifying an argument to the FEATURE. The default
error message is
@@ -2789,14 +2789,14 @@ This FEATURE can be included several times to query different
DNS based rejection lists.
Notice: to avoid checking your own local domains against those
-blacklists, use the access_db feature and add:
+blocklists, use the access_db feature and add:
Connect:10.1 OK
Connect:127.0.0.1 RELAY
to the access map, where 10.1 is your local network. You may
want to use "RELAY" instead of "OK" to allow also relaying
-instead of just disabling the DNS lookups in the blacklists.
+instead of just disabling the DNS lookups in the blocklists.
The features described above make use of the check_relay, check_mail,
@@ -2849,7 +2849,7 @@ my.domain and you have
in the access map, then any e-mail with a sender address of
<user@my.domain> will not be rejected by check_relay even though
it would match the hostname or IP address. This allows spammers
-to get around DNS based blacklist by faking the sender address. To
+to get around DNS based blocklist by faking the sender address. To
avoid this problem you have to use tagged entries:
To:my.domain RELAY
@@ -2978,7 +2978,7 @@ 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
+blocklists 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
@@ -3071,13 +3071,13 @@ rulesets and map lookups, they are modified as follows: each non-printable
character and the characters '<', '>', '(', ')', '"', '+', ' ' are replaced
by their HEX value with a leading '+'. For example:
-/C=US/ST=California/O=endmail.org/OU=private/CN=Darth Mail (Cert)/Email=
+/C=US/ST=California/O=endmail.org/OU=private/CN=Darth Mail (Cert)/emailAddress=
darth+cert@endmail.org
is encoded as:
/C=US/ST=California/O=endmail.org/OU=private/CN=
-Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org
+Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org
(line breaks have been inserted for readability).
@@ -3089,30 +3089,27 @@ Examples:
To allow relaying for everyone who can present a cert signed by
/C=US/ST=California/O=endmail.org/OU=private/CN=
-Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org
+Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org
simply use:
CertIssuer:/C=US/ST=California/O=endmail.org/OU=private/CN=
-Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org RELAY
+Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org RELAY
To allow relaying only for a subset of machines that have a cert signed by
/C=US/ST=California/O=endmail.org/OU=private/CN=
-Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org
+Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org
use:
CertIssuer:/C=US/ST=California/O=endmail.org/OU=private/CN=
-Darth+20Mail+20+28Cert+29/Email=darth+2Bcert@endmail.org SUBJECT
+Darth+20Mail+20+28Cert+29/emailAddress=darth+2Bcert@endmail.org SUBJECT
CertSubject:/C=US/ST=California/O=endmail.org/OU=private/CN=
-DeathStar/Email=deathstar@endmail.org RELAY
+DeathStar/emailAddress=deathstar@endmail.org RELAY
-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=".
+Note: line breaks have been inserted after "CN=" for readability,
+each tagged entry must be one (long) line in the access map.
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.,
@@ -3188,16 +3185,23 @@ CN:name name must match ${cn_subject}
CN ${client_name}/${server_name} must match ${cn_subject}
CS:name name must match ${cert_subject}
CI:name name must match ${cert_issuer}
+CITag:MYTag look up MYTag:${cert_issuer} in access map; the check
+ only succeeds if it is found with a RHS of OK.
Example: e-mail sent to secure.example.com should only use an encrypted
connection. E-mail received from hosts within the laptop.example.com domain
should only be accepted if they have been authenticated. The host which
receives e-mail for darth@endmail.org must present a cert that uses the
-CN smtp.endmail.org.
+CN smtp.endmail.org. E-mail sent to safe.example.com must be verified,
+have a matching CN, and must present a cert signed by a CA with one of
+the listed DNs.
-TLS_Srv:secure.example.com ENCR:112
-TLS_Clt:laptop.example.com PERM+VERIFY:112
+TLS_Srv:secure.example.com ENCR:112
+TLS_Clt:laptop.example.com PERM+VERIFY:112
TLS_Rcpt:darth@endmail.org ENCR:112+CN:smtp.endmail.org
+TLS_Srv:safe.example.net VERIFY+CN++CITag:MyCA
+MyCA:/C=US/ST=CA/O=safe/CN=example.net/ OK
+MyCA:/C=US/ST=CA/O=secure/CN=example.net/ OK
TLS Options per Session
@@ -3217,6 +3221,7 @@ options:
- Options: compare {Server,Client}SSLOptions.
- CipherList: same as the global option.
- CertFile, KeyFile: {Server,Client}{Cert,Key}File
+- Flags: see doc/op/op.me for details.
If FEATURE(`tls_session_features') is used, then default rulesets
are activated which look up entries in the access map with the tags
@@ -3234,15 +3239,12 @@ If FEATURE(`tls_session_features') is not used the user can provide
their own rulesets which must return the appropriate data.
If the rulesets are not defined or do not return a value, the
default TLS options are not modified.
-(These rulesets require the sendmail binary to be built with
-_FFR_TLS_SE_OPTS enabled.)
-About 2): the ruleset try_tls (srv_features) can be used that work
-together with the access map. Entries for the access map must be
-tagged with Try_TLS (Srv_Features) and refer to the hostname or IP
-address of the connecting system. A default case can be specified
-by using just the tag. For example, the following entries in the
-access map:
+About 2): the ruleset try_tls (srv_features) can be used together
+with the access map. Entries for the access map must be tagged
+with Try_TLS (Srv_Features) and refer to the hostname or IP address
+of the connecting system. A default case can be specified by using
+just the tag. For example, the following entries in the access map:
Try_TLS:broken.server NO
Srv_Features:my.domain v
@@ -3654,7 +3656,7 @@ for. In particular:
if your system allows "file giveaways" (that is, if a non-root
user can chown any file they own to any other user).
-* If your system allows file giveaways, DO NOT create a publically
+* If your system allows file giveaways, DO NOT create a publicly
writable directory for forward files. This will allow anyone
to steal anyone else's e-mail. Instead, create a script that
copies the .forward file from users' home directories once a
@@ -4011,6 +4013,10 @@ confUSERDB_SPEC UserDatabaseSpec
confFALLBACK_MX FallbackMXhost [undefined] Fallback MX host.
confFALLBACK_SMARTHOST FallbackSmartHost
[undefined] Fallback smart host.
+confTLS_FALLBACK_TO_CLEAR TLSFallbacktoClear
+ [undefined] If set, immediately try
+ a connection again without STARTTLS
+ after a TLS handshake failure.
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
@@ -4364,10 +4370,13 @@ confCLIENT_KEY ClientKeyFile [undefined] File containing the
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.
+ authentication.
+confCRL_PATH CRLPath [undefined] Directory containing
+ hashes pointing to certificate
+ revocation status files.
confDH_PARAMETERS DHParameters [undefined] File containing the
DH parameters.
+confDANE DANE [false] Enable DANE support.
confRAND_FILE RandFile [undefined] File containing random
data (use prefix file:) or the
name of the UNIX socket if EGD is
@@ -4379,6 +4388,9 @@ confCERT_FINGERPRINT_ALGORITHM CertFingerprintAlgorithm
[undefined] The fingerprint algorithm
(digest) to use for the presented
cert.
+confSSL_ENGINE SSLEngine [undefined] Name of SSLEngine.
+confSSL_ENGINE_PATH SSLEnginePath [undefined] Path to dynamic library
+ for SSLEngine.
confNICE_QUEUE_RUN NiceQueueRun [undefined] If set, the priority of
queue runners is set the given value
(nice(3)).
@@ -4799,7 +4811,6 @@ M4 DIVERSIONS
5 locally interpreted names (overrides $R)
6 local configuration (at top of file)
7 mailer definitions
- 8 DNS based blacklists
+ 8 DNS based blocklists
9 special local rulesets (1 and 2)
-$Revision: 8.730 $, Last updated $Date: 2014-01-16 15:55:51 $
diff --git a/contrib/sendmail/cf/cf/Makefile b/contrib/sendmail/cf/cf/Makefile
index efec478cb95a..bf6f031b2f11 100644
--- a/contrib/sendmail/cf/cf/Makefile
+++ b/contrib/sendmail/cf/cf/Makefile
@@ -103,7 +103,7 @@ M4FILES=\
${CFDIR}/feature/bcc.m4 \
${CFDIR}/feature/bestmx_is_local.m4 \
${CFDIR}/feature/bitdomain.m4 \
- ${CFDIR}/feature/blacklist_recipients.m4 \
+ ${CFDIR}/feature/blocklist_recipients.m4 \
${CFDIR}/feature/conncontrol.m4 \
${CFDIR}/feature/dnsbl.m4 \
${CFDIR}/feature/domaintable.m4 \
diff --git a/contrib/sendmail/cf/cf/knecht.mc b/contrib/sendmail/cf/cf/knecht.mc
index 720389189eb4..2b79eb227927 100644
--- a/contrib/sendmail/cf/cf/knecht.mc
+++ b/contrib/sendmail/cf/cf/knecht.mc
@@ -46,7 +46,7 @@ define(`CYRUS_MAILER_PATH', `/usr/local/cyrus/bin/deliver')
define(`CYRUS_MAILER_FLAGS', `fAh5@/:|')
FEATURE(`access_db')
-FEATURE(`blacklist_recipients')
+FEATURE(`blocklist_recipients')
FEATURE(`local_lmtp')
FEATURE(`virtusertable')
FEATURE(`mailertable')
@@ -234,7 +234,7 @@ Kstorage macro
LOCAL_RULESETS
######################################################################
-### check for the existance of the X-MailScanner Header
+### check for the existence of the X-MailScanner Header
HX-MailScanner: $>+CheckXMSc
D{SobigFPat}Found to be clean
D{SobigFMsg}This message may contain the Sobig.F virus.
diff --git a/contrib/sendmail/cf/cf/submit.cf b/contrib/sendmail/cf/cf/submit.cf
index 6295d32db006..63d7cb720eb7 100644
--- a/contrib/sendmail/cf/cf/submit.cf
+++ b/contrib/sendmail/cf/cf/submit.cf
@@ -16,8 +16,8 @@
#####
##### SENDMAIL CONFIGURATION FILE
#####
-##### built by ca@sandman.dev-lab.sendmail.com on Thu Jul 2 05:24:31 PDT 2015
-##### in /x/ca/smi.git/sendmail/OpenSource/sendmail-8.15.2/cf/cf
+##### built by ca@lab.smi.sendmail.com on Thu Jul 2 22:41:57 PDT 2020
+##### in /var/tmp/ca/sm8.git/sendmail/OpenSource/sendmail-8.16.1/cf/cf
##### using ../ as configuration include directory
#####
######################################################################
@@ -114,7 +114,7 @@ D{MTAHost}[127.0.0.1]
# Configuration version number
-DZ8.15.2/Submit
+DZ8.16.1/Submit
###############
@@ -513,6 +513,12 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid
#O ServerSSLOptions
# client side SSL options
#O ClientSSLOptions
+# SSL Engine
+#O SSLEngine
+# Path to dynamic library for SSLEngine
+#O SSLEnginePath
+# TLS: fall back to clear text after handshake failure?
+#O TLSFallbacktoClear
# Input mail filters
#O InputMailFilters
@@ -532,12 +538,16 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid
#O ClientKeyFile
# File containing certificate revocation lists
#O CRLFile
+# Directory containing hashes pointing to certificate revocation status files
+#O CRLPath
# DHParameters (only required if DSA/DH is used)
#O DHParameters
# Random data source (required for systems without /dev/urandom under OpenSSL)
#O RandFile
# fingerprint algorithm (digest) to use for the presented cert
#O CertFingerprintAlgorithm
+# enable DANE?
+#O DANE=false
# Maximum number of "useless" commands before slowing down
#O MaxNOOPCommands=20
@@ -1257,6 +1267,7 @@ R$* $| $* $@ $>"TLS_connection" $1
### ${verify}
######################################################################
Stls_server
+
R$* $@ $>"TLS_connection" $1
######################################################################
@@ -1268,6 +1279,7 @@ R$* $@ $>"TLS_connection" $1
######################################################################
STLS_connection
RSOFTWARE $#error $@ 4.7.0 $: "403 TLS handshake."
+RDANE_FAIL $#error $@ 4.7.0 $: "403 DANE check failed."
diff --git a/contrib/sendmail/cf/feature/bcc.m4 b/contrib/sendmail/cf/feature/bcc.m4
index 9454143f2060..5bb754bd04a3 100644
--- a/contrib/sendmail/cf/feature/bcc.m4
+++ b/contrib/sendmail/cf/feature/bcc.m4
@@ -76,7 +76,7 @@ R$* $| $* $: ifelse(len(X`'_ARG3_),`1', `$1', `_ARG3_')
ifdef(`_CANONIFY_BCC_', `dnl
R$+ @ $+ $: $1@$2 $| <$(canonicalRcpt $1 @ $2 $: $)>
R$* $| <> $@
-R$* $| <$* <TMPF>> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."
+R$* $| <$* <TMPF>> $#error $@ 4.3.0 $: _TMPFMSG_(`BCC')
R$* $| <$+> $@ $2 map matched?
')
diff --git a/contrib/sendmail/cf/feature/blacklist_recipients.m4 b/contrib/sendmail/cf/feature/blacklist_recipients.m4
index 706d11754393..5312a2e50687 100644
--- a/contrib/sendmail/cf/feature/blacklist_recipients.m4
+++ b/contrib/sendmail/cf/feature/blacklist_recipients.m4
@@ -13,7 +13,6 @@ divert(0)
VERSIONID(`$Id: blacklist_recipients.m4,v 8.14 2013-11-22 20:51:11 ca Exp $')
divert(-1)
-ifdef(`_ACCESS_TABLE_',
- `define(`_BLACKLIST_RCPT_', 1)',
- `errprint(`*** ERROR: FEATURE(blacklist_recipients) requires FEATURE(access_db)
-')')
+errprint(`WARNING: FEATURE(blacklist_recipients) is deprecated; use FEATURE(blocklist_recipients.m4).
+')
+FEATURE(`blocklist_recipients')
diff --git a/contrib/sendmail/cf/feature/blocklist_recipients.m4 b/contrib/sendmail/cf/feature/blocklist_recipients.m4
new file mode 100644
index 000000000000..7c5a1df02218
--- /dev/null
+++ b/contrib/sendmail/cf/feature/blocklist_recipients.m4
@@ -0,0 +1,19 @@
+divert(-1)
+#
+# Copyright (c) 1998, 1999 Proofpoint, Inc. and its suppliers.
+# All rights reserved.
+#
+# By using this file, you agree to the terms and conditions set
+# forth in the LICENSE file which can be found at the top level of
+# the sendmail distribution.
+#
+#
+
+divert(0)
+VERSIONID(`$Id: blocklist_recipients.m4,v 8.14 2013-11-22 20:51:11 ca Exp $')
+divert(-1)
+
+ifdef(`_ACCESS_TABLE_',
+ `define(`_BLOCKLIST_RCPT_', 1)',
+ `errprint(`*** ERROR: FEATURE(blocklist_recipients) requires FEATURE(access_db)
+')')
diff --git a/contrib/sendmail/cf/feature/check_cert_altnames.m4 b/contrib/sendmail/cf/feature/check_cert_altnames.m4
new file mode 100644
index 000000000000..9fae74ef0a3c
--- /dev/null
+++ b/contrib/sendmail/cf/feature/check_cert_altnames.m4
@@ -0,0 +1,17 @@
+divert(-1)
+#
+# Copyright (c) 2019 Proofpoint, Inc. and its suppliers.
+# All rights reserved.
+#
+# By using this file, you agree to the terms and conditions set
+# forth in the LICENSE file which can be found at the top level of
+# the sendmail distribution.
+#
+#
+
+divert(0)dnl
+VERSIONID(`$Id: block_bad_helo.m4,v 1.2 2013-11-22 20:51:11 ca Exp $')
+divert(-1)
+define(`_FFR_TLS_ALTNAMES', `1')
+divert(6)dnl
+O SetCertAltnames=true
diff --git a/contrib/sendmail/cf/feature/dnsbl.m4 b/contrib/sendmail/cf/feature/dnsbl.m4
index 63b86759c320..dd8fd52583f9 100644
--- a/contrib/sendmail/cf/feature/dnsbl.m4
+++ b/contrib/sendmail/cf/feature/dnsbl.m4
@@ -17,7 +17,7 @@ define(`_DNSBL_R_',`')
ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(`dnsbl')')')
LOCAL_CONFIG
-# map for DNS based blacklist lookups
+# map for DNS based blocklist lookups
Kdnsbl DNSBL_MAP -T<TMP>ifdef(`DNSBL_MAP_OPT',` DNSBL_MAP_OPT')')
divert(-1)
define(`_DNSBL_SRV_', `_ARG_')dnl
diff --git a/contrib/sendmail/cf/feature/enhdnsbl.m4 b/contrib/sendmail/cf/feature/enhdnsbl.m4
index b3a86b969c26..f0ba5c50d482 100644
--- a/contrib/sendmail/cf/feature/enhdnsbl.m4
+++ b/contrib/sendmail/cf/feature/enhdnsbl.m4
@@ -16,7 +16,7 @@ ifdef(`_EDNSBL_R_',`dnl',`dnl
VERSIONID(`$Id: enhdnsbl.m4,v 1.13 2013-11-22 20:51:11 ca Exp $')
LOCAL_CONFIG
define(`_EDNSBL_R_',`')dnl
-# map for enhanced DNS based blacklist lookups
+# map for enhanced DNS based blocklist lookups
Kednsbl dns -R A -a. -T<TMP> -r`'ifdef(`EDNSBL_TO',`EDNSBL_TO',`5')
')
divert(-1)
diff --git a/contrib/sendmail/cf/feature/tls_failures.m4 b/contrib/sendmail/cf/feature/tls_failures.m4
new file mode 100644
index 000000000000..94982110f0b8
--- /dev/null
+++ b/contrib/sendmail/cf/feature/tls_failures.m4
@@ -0,0 +1,13 @@
+divert(-1)
+#
+# Copyright (c) 2020 Proofpoint, Inc. and its suppliers.
+# All rights reserved.
+#
+# By using this file, you agree to the terms and conditions set
+# forth in the LICENSE file which can be found at the top level of
+# the sendmail distribution.
+#
+
+errprint(`*** ERROR: FEATURE(tls_failures) has been replaced by confTLS_FALLBACK_TO_CLEAR
+')
+define(`confTLS_FALLBACK_TO_CLEAR', `true')
diff --git a/contrib/sendmail/cf/m4/cfhead.m4 b/contrib/sendmail/cf/m4/cfhead.m4
index d808955db389..7e5fa99e0ef5 100644
--- a/contrib/sendmail/cf/m4/cfhead.m4
+++ b/contrib/sendmail/cf/m4/cfhead.m4
@@ -73,6 +73,15 @@ define(`_ARG9_',`_ACC_ARG_9_(_ARGS_)')
dnl define if not yet defined: if `$1' is not defined it will be `$2'
define(`_DEFIFNOT',`ifdef(`$1',`',`define(`$1',`$2')')')
dnl ----------------------------------------
+dnl Use a "token" for this error message to make them unique?
+dnl Note: this is not a documented option. To enable it, use:
+dnl define(`_USETMPFTOKEN_', `1')dnl
+ifdef(`_USETMPFTOKEN_', `
+define(_TMPFMSG_, `"451 Temporary system failure $1. Please try again later."')
+', `dnl
+define(_TMPFMSG_, `"451 Temporary system failure. Please try again later."')
+')
+dnl ----------------------------------------
dnl add a char $2 to a string $1 if it is not there
define(`_ADDCHAR_',`define(`_I_',`eval(index(`$1',`$2') >= 0)')`'ifelse(_I_,`1',`$1',`$1$2')')
dnl ----
diff --git a/contrib/sendmail/cf/m4/proto.m4 b/contrib/sendmail/cf/m4/proto.m4
index 696bf36a5357..618dde00e24a 100644
--- a/contrib/sendmail/cf/m4/proto.m4
+++ b/contrib/sendmail/cf/m4/proto.m4
@@ -161,7 +161,7 @@ ifdef(`_ACCESS_TABLE_', `dnl
# access_db acceptance class
C{Accept}OK RELAY
ifdef(`_DELAY_COMPAT_8_10_',`dnl
-ifdef(`_BLACKLIST_RCPT_',`dnl
+ifdef(`_BLOCKLIST_RCPT_',`dnl
# possible access_db RHS for spam friends/haters
C{SpamTag}SPAMFRIEND SPAMHATER')')',
`dnl')
@@ -197,7 +197,9 @@ 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
+C{TlsVerified}OK TRUSTED
+dnl', `dnl')
ifdef(`_CERT_REGEX_ISSUER_', `dnl
# extract relevant part from cert issuer
KCERTIssuer regex _CERT_REGEX_ISSUER_', `dnl')
@@ -653,6 +655,12 @@ _OPTION(CipherList, `confCIPHER_LIST', `')
_OPTION(ServerSSLOptions, `confSERVER_SSL_OPTIONS', `')
# client side SSL options
_OPTION(ClientSSLOptions, `confCLIENT_SSL_OPTIONS', `')
+# SSL Engine
+_OPTION(SSLEngine, `confSSL_ENGINE', `')
+# Path to dynamic library for SSLEngine
+_OPTION(SSLEnginePath, `confSSL_ENGINE_PATH', `')
+# TLS: fall back to clear text after handshake failure?
+_OPTION(TLSFallbacktoClear, `confTLS_FALLBACK_TO_CLEAR', `')
# Input mail filters
_OPTION(InputMailFilters, `confINPUT_MAIL_FILTERS', `')
@@ -682,12 +690,16 @@ _OPTION(ClientCertFile, `confCLIENT_CERT', `')
_OPTION(ClientKeyFile, `confCLIENT_KEY', `')
# File containing certificate revocation lists
_OPTION(CRLFile, `confCRL', `')
+# Directory containing hashes pointing to certificate revocation status files
+_OPTION(CRLPath, `confCRL_PATH', `')
# DHParameters (only required if DSA/DH is used)
_OPTION(DHParameters, `confDH_PARAMETERS', `')
# Random data source (required for systems without /dev/urandom under OpenSSL)
_OPTION(RandFile, `confRAND_FILE', `')
# fingerprint algorithm (digest) to use for the presented cert
_OPTION(CertFingerprintAlgorithm, `confCERT_FINGERPRINT_ALGORITHM', `')
+# enable DANE?
+_OPTION(DANE, `confDANE', `false')
# Maximum number of "useless" commands before slowing down
_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
@@ -1500,7 +1512,7 @@ R<$* <TMPF>> <$*> <$+> <$+> <$*> $: $&{opMode} $| TMPF <$&{addr_type}> $| $3
R<$*> <$* <TMPF>> <$+> <$+> <$*> $: $&{opMode} $| TMPF <$&{addr_type}> $| $3
ifelse(_LDAP_ROUTE_MAPTEMP_, `_TEMPFAIL_', `dnl
# ... temp fail RCPT SMTP commands
-R$={SMTPOpModes} $| TMPF <e r> $| $+ $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."')
+R$={SMTPOpModes} $| TMPF <e r> $| $+ $#error $@ 4.3.0 $: _TMPFMSG_(`OPM')')
# ... return original address for MTA to queue up
R$* $| TMPF <$*> $| $+ $@ $3
@@ -1733,7 +1745,7 @@ dnl if mark is <NO> then change it to <RELAY> if domain is "authorized"
dnl what if access map returns something else than RELAY?
dnl we are only interested in RELAY entries...
-dnl other To: entries: blacklist recipient; generic entries?
+dnl other To: entries: blocklist recipient; generic entries?
dnl if it is an error we probably do not want to relay anyway
ifdef(`_RELAY_HOSTS_ONLY_',
`R<NO> $* < @ $=R > $: <RELAY> $1 < @ $2 >
@@ -1807,7 +1819,7 @@ R<QUARANTINE:$+> <$*> $#error $@ quarantine $: $1
dnl error tag
R<ERROR:$-.$-.$-:$+> <$*> $#error $@ $1.$2.$3 $: $4
R<ERROR:$+> <$*> $#error $: $1
-ifdef(`_ATMPF_', `R<$* _ATMPF_> <$*> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<$* _ATMPF_> <$*> $#error $@ 4.3.0 $: _TMPFMSG_(`CR')', `dnl')
dnl generic error from access map
R<$+> <$*> $#error $: $1', `dnl')
@@ -1976,7 +1988,7 @@ R<REJECT> $* $#error ifdef(`confREJECT_MSG', `$: confREJECT_MSG', `$@ 5.7.1 $:
dnl error tag
R<ERROR:$-.$-.$-:$+> $* $#error $@ $1.$2.$3 $: $4
R<ERROR:$+> $* $#error $: $1
-ifdef(`_ATMPF_', `R<_ATMPF_> $* $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<_ATMPF_> $* $#error $@ 4.3.0 $: _TMPFMSG_(`CM')', `dnl')
dnl generic error from access map
R<$+> $* $#error $: $1 error from access db',
`dnl')
@@ -2108,9 +2120,9 @@ R$* $=O $* < @ $* @@ $=w . > $* $@ $>"Rcpt_ok" $1 $2 $3
R$* < @ $* @@ $=w . > $* $: $1 < @ $3 > $4
R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4')
-ifdef(`_BLACKLIST_RCPT_',`dnl
+ifdef(`_BLOCKLIST_RCPT_',`dnl
ifdef(`_ACCESS_TABLE_', `dnl
-# blacklist local users or any host from receiving mail
+# blocklist local users or any host from receiving mail
R$* $: <?> $1
dnl user is now tagged with @ to be consistent with check_mail
dnl and to distinguish users from hosts (com would be host, com@ would be user)
@@ -2143,7 +2155,7 @@ R<QUARANTINE:$+> $* $#error $@ quarantine $: $1
dnl error tag
R<ERROR:$-.$-.$-:$+> $* $#error $@ $1.$2.$3 $: $4
R<ERROR:$+> $* $#error $: $1
-ifdef(`_ATMPF_', `R<_ATMPF_> $* $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<_ATMPF_> $* $#error $@ 4.3.0 $: _TMPFMSG_(`ROK1')', `dnl')
dnl generic error from access map
R<$+> $* $#error $: $1 error from access db
R@ $* $1 remove mark', `dnl')', `dnl')
@@ -2198,7 +2210,7 @@ R$+ < @ $+ > $| $* $: <$3> <$1 <@ $2>>',
ifdef(`_ACCESS_TABLE_', `dnl
dnl workspace: <Result-of-lookup | ?> <localpart<@domain>>
R<RELAY> $* $@ RELAY
-ifdef(`_ATMPF_', `R<$* _ATMPF_> $* $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<$* _ATMPF_> $* $#TEMP $@ 4.3.0 $: _TMPFMSG_(`ROK2')', `dnl')
R<$*> <$*> $: $2',`dnl')
@@ -2268,7 +2280,7 @@ dnl Connect:My.Host.Domain RELAY
dnl Connect:My.Net REJECT
dnl since in check_relay client_name is checked before client_addr
R<REJECT> $* $@ REJECT rejected IP address')
-ifdef(`_ATMPF_', `R<_ATMPF_> $* $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<_ATMPF_> $* $#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK1')', `dnl')
R<$*> <$*> $: $2', `dnl')
R$* $: [ $1 ] put brackets around it...
R$=w $@ RELAY ... and see if it is local
@@ -2287,7 +2299,7 @@ R<?> $+ < @ $=w > $@ RELAY FROM local', `dnl')
ifdef(`_RELAY_DB_FROM_', `dnl
R<?> $+ < @ $+ > $: <@> $>SearchList <! From> $| <F:$1@$2> ifdef(`_RELAY_DB_FROM_DOMAIN_', ifdef(`_RELAY_HOSTS_ONLY_', `<E:$2>', `<D:$2>')) <>
R<@> <RELAY> $@ RELAY RELAY FROM sender ok
-ifdef(`_ATMPF_', `R<@> <_ATMPF_> $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<@> <_ATMPF_> $#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK2')', `dnl')
', `dnl
ifdef(`_RELAY_DB_FROM_DOMAIN_',
`errprint(`*** ERROR: _RELAY_DB_FROM_DOMAIN_ requires _RELAY_DB_FROM_
@@ -2331,7 +2343,7 @@ ifdef(`_ACCESS_TABLE_', `dnl
R<?> $* $: $>D <$1> <?> <+ Connect> <$1>',`dnl')')
ifdef(`_ACCESS_TABLE_', `dnl
R<RELAY> $* $@ RELAY
-ifdef(`_ATMPF_', `R<$* _ATMPF_> $* $#TEMP $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+ifdef(`_ATMPF_', `R<$* _ATMPF_> $* $#TEMP $@ 4.3.0 $: _TMPFMSG_(`YOK3')', `dnl')
R<$*> <$*> $: $2',`dnl')
dnl end of _PROMISCUOUS_RELAY_
divert(0)
@@ -2384,7 +2396,7 @@ ifdef(`_ACCESS_TABLE_', `',
`errprint(`*** ERROR: FEATURE(`delay_checks', `argument') requires FEATURE(`access_db')
')')dnl
dnl one of the next two rules is supposed to match
-dnl this code has been copied from BLACKLIST... etc
+dnl this code has been copied from BLOCKLIST... etc
dnl and simplified by omitting some < >.
R<?> $+ < @ $=w > $: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 > <U: $1@>
R<?> $+ < @ $* > $: <> $1 < @ $2 > $| <F: $1@$2 > <D: $2 >
@@ -2688,7 +2700,7 @@ R<?>$* $: $>A <$&{server_addr}> <?> <! TLS_TRY_TAG> <>
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<$* _ATMPF_>$* $#error $@ 4.3.0 $: _TMPFMSG_(`TT')', `dnl')
R<NO>$* $#error $@ 5.7.1 $: "550 do not try TLS with " $&{server_name} " ["$&{server_addr}"]"')
######################################################################
@@ -2721,7 +2733,7 @@ R$* $| $+ $: $1 $| $>SearchList <! TLS_RCPT_TAG> $| $2 <>
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')
+R$* $| <$* _ATMPF_> $#error $@ 4.3.0 $: _TMPFMSG_(`TR')', `dnl')
dnl use the generic routine (for now)
R$* $| <$+> $@ $>"TLS_connection" $&{verify} $| <$2>')
@@ -2751,7 +2763,7 @@ R$* $| <?>$* $: $1 $| $>A <$&{client_addr}> <?> <! TLS_CLT_TAG> <>
dnl do a default lookup: just TLS_CLT_TAG
R$* $| <?>$* $: $1 $| <$(access TLS_CLT_TAG`'_TAG_DELIM_ $: ? $)>
ifdef(`_ATMPF_', `dnl tempfail?
-R$* $| <$* _ATMPF_> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+R$* $| <$* _ATMPF_> $#error $@ 4.3.0 $: _TMPFMSG_(`TC')', `dnl')
R$* $@ $>"TLS_connection" $1', `dnl
R$* $| $* $@ $>"TLS_connection" $1')
@@ -2769,6 +2781,8 @@ ifdef(`_LOCAL_TLS_SERVER_', `dnl
R$* $: $1 $| $>"Local_tls_server" $1
R$* $| $#$* $#$2
R$* $| $* $: $1', `dnl')
+ifdef(`_TLS_FAILURES_',`dnl
+R$* $: $(macro {saved_verify} $@ $1 $) $1')
ifdef(`_ACCESS_TABLE_', `dnl
dnl store name of other side
R$* $: $(macro {TLS_Name} $@ $&{server_name} $) $1
@@ -2777,7 +2791,7 @@ R$* $| <?>$* $: $1 $| $>A <$&{server_addr}> <?> <! TLS_SRV_TAG> <>
dnl do a default lookup: just TLS_SRV_TAG
R$* $| <?>$* $: $1 $| <$(access TLS_SRV_TAG`'_TAG_DELIM_ $: ? $)>
ifdef(`_ATMPF_', `dnl tempfail?
-R$* $| <$* _ATMPF_> $#error $@ 4.3.0 $: "451 Temporary system failure. Please try again later."', `dnl')
+R$* $| <$* _ATMPF_> $#error $@ 4.3.0 $: _TMPFMSG_(`TS')', `dnl')
R$* $@ $>"TLS_connection" $1', `dnl
R$* $@ $>"TLS_connection" $1')
@@ -2798,6 +2812,7 @@ STLS_connection
ifdef(`_ACCESS_TABLE_', `dnl', `dnl use default error
dnl deal with TLS handshake failures: abort
RSOFTWARE $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake."
+RDANE_FAIL $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed."
divert(-1)')
dnl common ruleset for tls_{client|server}
dnl input: ${verify} $| <ResultOfLookup> [<>]
@@ -2813,14 +2828,19 @@ R$* $| <$={Tls} $*> $: $1 $| <ifdef(`TLS_PERM_ERR', `503:5.7.0', `403:4.7.0')>
dnl workspace: ${verify} $| [<SMTP:ESC>] <ResultOfLookup>
# deal with TLS handshake failures: abort
RSOFTWARE $| <$-:$+> $* $#error $@ $2 $: $1 " TLS handshake failed."
-dnl no <reply:dns> i.e. not requirements in the access map
+dnl no <reply:dns> i.e. no requirements in the access map
dnl use default error
RSOFTWARE $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') TLS handshake failed."
# deal with TLS protocol errors: abort
RPROTOCOL $| <$-:$+> $* $#error $@ $2 $: $1 " STARTTLS failed."
-dnl no <reply:dns> i.e. not requirements in the access map
+dnl no <reply:dns> i.e. no requirements in the access map
dnl use default error
RPROTOCOL $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') STARTTLS failed."
+# deal with DANE errors: abort
+RDANE_FAIL $| <$-:$+> $* $#error $@ $2 $: $1 " DANE check failed."
+dnl no <reply:dns> i.e. no requirements in the access map
+dnl use default error
+RDANE_FAIL $| $* $#error $@ ifdef(`TLS_PERM_ERR', `5.7.0', `4.7.0') $: "ifdef(`TLS_PERM_ERR', `503', `403') DANE check failed."
R$* $| <$*> <VERIFY> $: <$2> <VERIFY> <> $1
dnl separate optional requirements
R$* $| <$*> <VERIFY + $+> $: <$2> <VERIFY> <$3> $1
@@ -2834,16 +2854,16 @@ R$* $| $* $@ OK
# other side did authenticate (via STARTTLS)
dnl workspace: <SMTP:ESC> <{VERIFY,ENCR}[:BITS]> <[extensions]> ${verify}
dnl only verification required and it succeeded
-R<$*><VERIFY> <> OK $@ OK
+R<$*><VERIFY> <> $={TlsVerified} $@ OK
dnl verification required and it succeeded but extensions are given
dnl change it to <SMTP:ESC> <REQ:0> <extensions>
-R<$*><VERIFY> <$+> OK $: <$1> <REQ:0> <$2>
+R<$*><VERIFY> <$+> $={TlsVerified} $: <$1> <REQ:0> <$2>
dnl verification required + some level of encryption
-R<$*><VERIFY:$-> <$*> OK $: <$1> <REQ:$2> <$3>
+R<$*><VERIFY:$-> <$*> $={TlsVerified} $: <$1> <REQ:$2> <$3>
dnl just some level of encryption required
R<$*><ENCR:$-> <$*> $* $: <$1> <REQ:$2> <$3>
dnl workspace:
-dnl 1. <SMTP:ESC> <VERIFY [:bits]> <[extensions]> {verify} (!= OK)
+dnl 1. <SMTP:ESC> <VERIFY [:bits]> <[extensions]> {verify} (!~ $={TlsVerified})
dnl 2. <SMTP:ESC> <REQ:bits> <[extensions]>
dnl verification required but ${verify} is not set (case 1.)
R<$-:$+><VERIFY $*> <$*> $#error $@ $2 $: $1 " authentication required"
@@ -2851,6 +2871,7 @@ R<$-:$+><VERIFY $*> <$*> FAIL $#error $@ $2 $: $1 " authentication failed"
R<$-:$+><VERIFY $*> <$*> NO $#error $@ $2 $: $1 " not authenticated"
R<$-:$+><VERIFY $*> <$*> NOT $#error $@ $2 $: $1 " no authentication requested"
R<$-:$+><VERIFY $*> <$*> NONE $#error $@ $2 $: $1 " other side does not support STARTTLS"
+R<$-:$+><VERIFY $*> <$*> CLEAR $#error $@ $2 $: $1 " STARTTLS disabled locally"
dnl some other value for ${verify}
R<$-:$+><VERIFY $*> <$*> $+ $#error $@ $2 $: $1 " authentication failure " $4
dnl some level of encryption required: get the maximum level (case 2.)
@@ -2884,7 +2905,6 @@ R<$-:$+> $+ $@ $>"TLS_req" $3 $| <$1:$2>
dnl further requirements for this ruleset:
dnl name of "other side" is stored is {TLS_name} (client/server_name)
dnl
-dnl currently only CN[:common_name] is implemented
dnl right now this is only a logical AND
dnl i.e. all requirements must be true
dnl how about an OR? CN must be X or CN must be Y or ..
@@ -2896,6 +2916,11 @@ dnl no additional requirements: ok
R $| $+ $@ OK
dnl require CN: but no CN specified: use name of other side
R<CN> $* $| <$+> $: <CN:$&{TLS_Name}> $1 $| <$2>
+ifdef(`_FFR_TLS_ALTNAMES', `dnl
+R<CN:$={cert_altnames}> $* $| <$+> $@ $>"TLS_req" $2 $| <$3>
+R<CN:$-.$+> $* $| <$+> $: <CN:*.$2> $3 $| <$4>
+R<CN:$={cert_altnames}> $* $| <$+> $@ $>"TLS_req" $3 $| <$3>
+R<CN:$*> $* $| <$+> $: <CN:$&{TLS_Name}> $2 $| <$3>', `dnl')
dnl match, check rest
R<CN:$&{cn_subject}> $* $| <$+> $@ $>"TLS_req" $1 $| <$2>
dnl CN does not match
@@ -2911,6 +2936,10 @@ R<CI:$&{cert_issuer}> $* $| <$+> $@ $>"TLS_req" $1 $| <$2>
dnl CI does not match
dnl 1 2 3 4
R<CI:$+> $* $| <$-:$+> $#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
+dnl
+R<CITag:$-> $* $| <$+> $: <$(access $1:$&{cert_issuer} $: ? $)> $2 $| <$3>
+R<?> $* $| <$-:$+> $#error $@ $3 $: $2 " Cert Issuer " $&{cert_issuer} " not acceptable"
+R<OK> $* $| <$+> $@ $>"TLS_req" $1 $| <$2>
dnl return from recursive call
ROK $@ OK
@@ -2970,7 +2999,7 @@ dnl if it returns SUBJECT we perform a similar check on the
dnl cert subject.
ifdef(`_ACCESS_TABLE_', `dnl
R$* $: <?> $&{verify}
-R<?> OK $: OK authenticated: continue
+R<?> $={TlsVerified} $: OK authenticated: continue
R<?> $* $@ NO not authenticated
ifdef(`_CERT_REGEX_ISSUER_', `dnl
R$* $: $(CERTIssuer $&{cert_issuer} $)',
@@ -3029,7 +3058,7 @@ R$+ $: $>SearchList <! ClientRate> $| $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')
+R<$* _ATMPF_> $#error $@ 4.3.0 $: _TMPFMSG_(`RC')', `dnl')
dnl use the generic routine (for now)
R<0> $@ OK no limit
R<$+> $: <$1> $| $(arith l $@ $1 $@ $&{client_rate} $)
@@ -3051,7 +3080,7 @@ R$+ $: $>SearchList <! ClientConn> $| $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')
+R<$* _ATMPF_> $#error $@ 4.3.0 $: _TMPFMSG_(`CC')', `dnl')
dnl use the generic routine (for now)
R<0> $@ OK no limit
R<$+> $: <$1> $| $(arith l $@ $1 $@ $&{client_connections} $)
diff --git a/contrib/sendmail/cf/m4/version.m4 b/contrib/sendmail/cf/m4/version.m4
index 8d2680534a4a..dadff627bb2e 100644
--- a/contrib/sendmail/cf/m4/version.m4
+++ b/contrib/sendmail/cf/m4/version.m4
@@ -1,6 +1,6 @@
divert(-1)
#
-# Copyright (c) 1998-2015 Proofpoint, Inc. and its suppliers.
+# Copyright (c) 1998-2016 Proofpoint, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
@@ -15,4 +15,4 @@ VERSIONID(`$Id: version.m4,v 8.237 2014-01-27 12:55:17 ca Exp $')
#
divert(0)
# Configuration version number
-DZ8.15.2`'ifdef(`confCF_VERSION', `/confCF_VERSION')
+DZ8.16.1`'ifdef(`confCF_VERSION', `/confCF_VERSION')
diff --git a/contrib/sendmail/cf/ostype/hpux10.m4 b/contrib/sendmail/cf/ostype/hpux10.m4
index c59828cedaa1..423bd5bb16d1 100644
--- a/contrib/sendmail/cf/ostype/hpux10.m4
+++ b/contrib/sendmail/cf/ostype/hpux10.m4
@@ -23,5 +23,5 @@ ifdef(`LOCAL_SHELL_PATH',, `define(`LOCAL_SHELL_PATH', /usr/bin/sh)')dnl
ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -a$g -gC $h!rmail ($u)')')dnl
define(`confTIME_ZONE', `USE_TZ')dnl
dnl
-dnl For maximum compability with HP-UX, use:
+dnl For maximum compatibility with HP-UX, use:
dnl define(`confME_TOO', True)dnl
diff --git a/contrib/sendmail/cf/ostype/hpux9.m4 b/contrib/sendmail/cf/ostype/hpux9.m4
index d9fa69faf7d0..76c2258183cb 100644
--- a/contrib/sendmail/cf/ostype/hpux9.m4
+++ b/contrib/sendmail/cf/ostype/hpux9.m4
@@ -23,5 +23,5 @@ ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -a$g -gC $h!rma
define(`confTIME_ZONE', `USE_TZ')dnl
define(`confEBINDIR', `/usr/lib')dnl
dnl
-dnl For maximum compability with HP-UX, use:
+dnl For maximum compatibility with HP-UX, use:
dnl define(`confME_TOO', True)dnl
diff --git a/contrib/sendmail/contrib/cidrexpand b/contrib/sendmail/contrib/cidrexpand
index efa5323a010c..ee24ee865275 100755
--- a/contrib/sendmail/contrib/cidrexpand
+++ b/contrib/sendmail/contrib/cidrexpand
@@ -1,13 +1,14 @@
#!/usr/bin/perl -w
-
-# $Id: cidrexpand,v 8.8 2006-08-07 17:18:37 ca Exp $
+#
+# usage:
+# cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
#
# v 0.4
#
# 17 July 2000 Derek J. Balling (dredd@megacity.org)
-#
+#
# Acts as a preparser on /etc/mail/access_db to allow you to use address/bit
-# notation.
+# 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
@@ -25,114 +26,156 @@
# 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
+# Added clarification in the notes for what to do if you have
# exceptions to a larger CIDR block.
#
-# 26 Jul 2006 Richard Rognlie (richard@sendmail.com>
+# 26 Jul 2006 Richard Rognlie (richard@sendmail.com)
# Added code to strip "comments" (anything after a non-escaped #)
# # characters after a \ or within quotes (single and double) are
-# left intact.
+# left intact.
#
# e.g.
# From:1.2.3.4 550 Die spammer # spammed us 2006.07.26
# becomes
-# From:1.2.3.4 550 Die spammer
+# From:1.2.3.4 550 Die spammer
#
# 3 August 2006
-#
# Corrected a bug to have it handle the special case of "0.0.0.0/0"
# since Net::CIDR doesn't handle it properly.
#
-# usage:
-# cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
+# 27 April 2016
+# Corrected IPv6 handling. Note that UseCompressedIPv6Addresses must
+# be turned off for this to work; there are three reasons for this:
+# 1) if the MTA uses compressed IPv6 addresses then CIDR 'cuts'
+# in the compressed range *cannot* be matched, as the MTA simply
+# won't look for them. E.g., there's no way to accurately
+# match "IPv6:fe80::/64" when for the address "IPv6:fe80::54ad"
+# the MTA doesn't lookup up "IPv6:fe80:0:0:0"
+# 2) cidrexpand only generates uncompressed addresses, so CIDR
+# 'cuts' to the right of the compressed range won't be matched
+# either. Why doesn't it generate compressed address output?
+# Oh, because:
+# 3) compressed addresses are ambiguous when colon-groups are
+# chopped off! You want an access map entry for
+# IPv6:fe80::0:5420
+# but not for
+# IPv6:fe80::5420:1234
+# ? Sorry, the former is really
+# IPv6:fe80::5420
+# which will also match the latter!
#
+# 25 July 2016
+# Since cidrexpand already requires UseCompressedIPv6Addresses to be
+# turned off, it can also canonicalize non-CIDR IPv6 addresses to the
+# format that sendmail looks up, expanding compressed addresses and
+# trimming superfluous leading zeros.
#
# Report bugs to: <dredd@megacity.org>
#
use strict;
-use Net::CIDR;
+use Net::CIDR qw(cidr2octets cidrvalidate);
use Getopt::Std;
-our ($opt_c,$opt_t);
-getopts('ct:');
+sub print_expanded_v4network;
+sub print_expanded_v6network;
-my $spaceregex = '\s+';
-if ($opt_t)
-{
- $spaceregex = $opt_t;
-}
+our %opts;
+getopts('ct:', \%opts);
+
+# Delimiter between the key and value
+my $space_re = exists $opts{t} ? $opts{t} : '\s+';
+
+# Regexp that matches IPv4 address literals
+my $ipv4_re = qr"(?:\d+\.){3}\d+";
+
+# Regexp that matches IPv6 address literals, plus a lot more.
+# Further checks are required for verifying that it's really one
+my $ipv6_re = qr"[0-9A-Fa-f:]{2,39}(?:\.\d+\.\d+\.\d+)?";
while (<>)
{
chomp;
- my ($prefix,$left,$right,$space);
+ my ($prefix, $network, $len, $right);
- if ( (/\#/) && $opt_c )
+ if ( (/\#/) && $opts{c} )
{
# print "checking...\n";
my $i;
my $qtype='';
- for ($i=0 ; $i<length($_) ; $i++)
+ for ($i=0 ; $i<length($_) ; $i++)
{
my $ch = substr($_,$i,1);
- if ($ch eq '\\')
+ if ($ch eq '\\')
{
$i++;
next;
}
- elsif ($qtype eq '' && $ch eq '#')
+ elsif ($qtype eq '' && $ch eq '#')
{
substr($_,$i) = '';
last;
}
- elsif ($qtype ne '' && $ch eq $qtype)
+ elsif ($qtype ne '' && $ch eq $qtype)
{
$qtype = '';
}
- elsif ($qtype eq '' && $ch =~ /[\'\"]/)
+ elsif ($qtype eq '' && $ch =~ /[\'\"]/)
{
$qtype = $ch;
}
}
- }
-
- if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ )
+ }
+
+ if (($prefix, $network, $len, $right) =
+ m!^(|\S+:)(${ipv4_re})/(\d+)(${space_re}.*)$!)
{
- print "$_\n";
+ print_expanded_v4network($network, $len, $prefix, $right);
+ }
+ elsif ((($prefix, $network, $len, $right) =
+ m!^((?:\S+:)?[Ii][Pp][Vv]6:)(${ipv6_re})(?:/(\d+))?(${space_re}.*)$!) &&
+ (!defined($len) || $len <= 128) &&
+ defined(cidrvalidate($network)))
+ {
+ print_expanded_v6network($network, $len // 128, $prefix, $right);
}
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";
- }
+ print "$_\n";
}
}
-
-sub expand_network
+
+sub print_expanded_v4network
{
- my $left_input = shift;
- my @rc = ($left_input);
- my ($network,$mask) = split /\//, $left_input;
- if (defined $mask)
+ my ($network, $len, $prefix, $suffix) = @_;
+
+ # cidr2octets() doesn't handle a prefix-length of zero, so do
+ # that ourselves
+ foreach my $nl ($len == 0 ? (0..255) : cidr2octets("$network/$len"))
{
- return (0..255) if $mask == 0;
+ print "$prefix$nl$suffix\n";
+ }
+}
+
+sub print_expanded_v6network
+{
+ my ($network, $len, $prefix, $suffix) = @_;
- my @parts = split /\./, $network;
- while ($#parts < 3)
+ # cidr2octets() doesn't handle a prefix-length of zero, so do
+ # that ourselves. Easiest is to just recurse on bottom and top
+ # halves with a length of 1
+ if ($len == 0) {
+ print_expanded_v6network("::", 1, $prefix, $suffix);
+ print_expanded_v6network("8000::", 1, $prefix, $suffix);
+ }
+ else
+ {
+ foreach my $nl (cidr2octets("$network/$len"))
{
- push @parts, "0";
+ # trim leading zeros from each group
+ $nl =~ s/(^|:)0+(?=[^:])/$1/g;
+ print "$prefix$nl$suffix\n";
}
- 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/dnsblaccess.m4 b/contrib/sendmail/contrib/dnsblaccess.m4
index da8e13a0a6a7..0075dba92fe8 100644
--- a/contrib/sendmail/contrib/dnsblaccess.m4
+++ b/contrib/sendmail/contrib/dnsblaccess.m4
@@ -24,7 +24,7 @@ dnl ## email. A tempfail-message value of `t' temporarily rejects
dnl ## with a default message. Otherwise the value should be your
dnl ## own message. The keytag is used to lookup the access map to
dnl ## further refine the result. I recommend a qualified keytag
-dnl ## (containing a ".") as less likely to accidently conflict with
+dnl ## (containing a ".") as less likely to accidentally conflict with
dnl ## other access tags.
dnl ##
dnl ## This is best illustrated with an example. Please do not use
@@ -66,7 +66,7 @@ ifdef(`_ACCESS_TABLE_', `dnl',
ifdef(`_EDNSBL_R_',`dnl',`dnl
define(`_EDNSBL_R_', `1')dnl ## prevent multiple redefines of the map.
LOCAL_CONFIG
-# map for enhanced DNS based blacklist lookups
+# map for enhanced DNS based blocklist lookups
Kednsbl dns -R A -a. -T<TMP> -r`'ifdef(`EDNSBL_TO',`EDNSBL_TO',`5')
')
divert(-1)
diff --git a/contrib/sendmail/contrib/expn.pl b/contrib/sendmail/contrib/expn.pl
index 85de08a7f419..317391238685 100755
--- a/contrib/sendmail/contrib/expn.pl
+++ b/contrib/sendmail/contrib/expn.pl
@@ -945,7 +945,7 @@ sub mxredirect
return undef;
}
# follow mx records, return a hostname
-# also follow temporary redirections comming from &domainify and
+# also follow temporary redirections coming from &domainify and
# &mxlookup
sub mx
{
diff --git a/contrib/sendmail/contrib/mmuegel b/contrib/sendmail/contrib/mmuegel
index 6db4a45189c1..e1610efa8606 100644
--- a/contrib/sendmail/contrib/mmuegel
+++ b/contrib/sendmail/contrib/mmuegel
@@ -268,7 +268,7 @@ sed 's/^X//' << 'SHAR_EOF' > 'libs/date.pl' &&
;# Fixed a couple of problems with &ls as pointed out by
;# Thomas Richter (richter@ki1.chemie.fu-berlin.de), thanks Thomas!
;# Also added a couple of SunOS 4.1.1 strftime-ish formats, %i and %k
-;# for space padded hours (` 1' to `12' and ` 0' to `23' respectivly),
+;# for space padded hours (` 1' to `12' and ` 0' to `23' respectively),
;# and %C for locale long date/time format. Changed &ampmH to take a
;# pad char parameter to make to evaled code for %i and %k simpler.
;# Added %E for suffixed day-of-month (ie 1st, 3rd, 4th etc).
@@ -398,7 +398,7 @@ X
X # watch out in 2070...
X $year += ($year < 70) ? 2000 : 1900;
X
-X # now loop throught the supplied format looking for tags...
+X # now loop through the supplied format looking for tags...
X while (($pos = index ($format, '%')) != -1) {
X
X # grab the format tag
@@ -471,7 +471,7 @@ sub ls {
X return ((&gettime ($TZ, time))[5] == @_[0]) ? "%R" : " %Y";
}
X
-# pad - pad $in with leading $pad until lenght $len
+# pad - pad $in with leading $pad until length $len
sub pad {
X local ($in, $len, $pad) = @_;
X local ($out) = "$in";
@@ -661,7 +661,7 @@ X
;# otherwise, $Status will be 0 and $Error_Msg will contain an error message.
;#
;# If $Use_Sendmail is 1 then sendmail is used to send the message. Normally
-;# a mailer such as Mail is used. By specifiying this you can include
+;# a mailer such as Mail is used. By specifying this you can include
;# headers in addition to text in either $Message or $Message_Is_File.
;# If either $Message or $Message_Is_File contain a Subject: header then
;# $Subject is ignored; otherwise, a Subject: header is automatically created.
@@ -1026,15 +1026,15 @@ X
;#
;# Does not care about order of switches, options, and arguments like
;# getopts.pl. Thus all non-switches/options will be kept in ARGV even if they
-;# are not at the end. If $Pass_Invalid is set all unkown options will be
+;# are not at the end. If $Pass_Invalid is set all unknown options will be
;# passed back to the caller by keeping them in @ARGV. This is useful when
;# parsing a command line for your script while ignoring options that you
;# may pass to another script. If this is set New_Getopts tries to maintain
-;# the switch clustering on the unkown switches.
+;# the switch clustering on the unknown switches.
;#
;# Accepts the special argument -usage to print the Usage string. Also accepts
;# the special option -version which prints the contents of the string
-;# $VERSION. $VERSION may or may not have an embeded \n in it. If -usage
+;# $VERSION. $VERSION may or may not have an embedded \n in it. If -usage
;# or -version are specified a status of -1 is returned. Note that the usage
;# option is only accepted if the usage string is not null.
;#
@@ -1048,8 +1048,8 @@ X
;# $Switch_To_Order {"v"} = 1;
;# $Switch_To_Order {"x"} = 2;
;#
-;# Note that in the case of multiple occurances of an option $Switch_To_Order
-;# will store each occurance of the argument via a string that emulates
+;# Note that in the case of multiple occurrences of an option $Switch_To_Order
+;# will store each occurrence of the argument via a string that emulates
;# an array. This is done by using join ($;, ...). You can retrieve the
;# array by using split (/$;/, ...).
;#
@@ -1062,7 +1062,7 @@ X
;# Another exciting ;-) feature that newgetopts has. Along with creating the
;# normal $opt_ scalars for the last value of an argument the list @opt_ is
;# created. It is an array which contains all the values of arguments to the
-;# basename of the variable. They are stored in the order which they occured
+;# basename of the variable. They are stored in the order which they occurred
;# on the command line starting with $[. Note that blank arguments are stored
;# as "". Along with providing support for multiple options on the command
;# line this also provides a method of counting the number of times an option
@@ -1293,8 +1293,8 @@ X
;# All other lines will be indented to match the amount of whitespace of
;# $Offset.
;#
-;# + If $Bullet_Indent is $TRUE $Offset will only be applied to the begining
-;# of lines as they occured in the original $String. Lines that are created
+;# + If $Bullet_Indent is $TRUE $Offset will only be applied to the beginning
+;# of lines as they occurred in the original $String. Lines that are created
;# by this routine will always be indented by blank spaces.
;#
;# + If $Columns is 0 no word-wrap is done. This might be useful to still
@@ -1306,7 +1306,7 @@ X
;# + If $Offset_Blank is $TRUE then empty lines will have $Offset pre-pended
;# to them. Otherwise, they will still empty.
;#
-;# This is a realy workhorse routine that I use in many places because of its
+;# This is a really workhorse routine that I use in many places because of its
;# veratility.
;#
;# Arguments:
@@ -1668,7 +1668,7 @@ sed 's/^X//' << 'SHAR_EOF' > 'man/postclip.1' &&
of the message. This keeps bounced mail private and helps to avoid disk space problems. \*(mp tries its best to keep as much of the header trail as possible.
Hopefully only the original body of the message will be filtered. Only messages
that have a subject that begins with 'Returned mail:' are filtered. This
-ensures that other mail is not accidently mucked with. Finally, note that
+ensures that other mail is not accidentally mucked with. Finally, note that
\fBsendmail\fR is used to deliver the message after it has been (possibly)
filtered. All of the original headers will remain intact.
.sp 1
diff --git a/contrib/sendmail/doc/op/op.me b/contrib/sendmail/doc/op/op.me
index 57e25cd0940f..4d7ead30d4bb 100644
--- a/contrib/sendmail/doc/op/op.me
+++ b/contrib/sendmail/doc/op/op.me
@@ -90,10 +90,9 @@ Proofpoint, Inc.
.de Ve
Version \\$2
..
-.Ve $Revision: 8.759 $
.rm Ve
.sp
-For Sendmail Version 8.15
+For Sendmail Version 8.16
.)l
.(f
Sendmail is a trademark of Proofpoint, Inc.
@@ -149,8 +148,9 @@ RFC 2554 (SMTP Service Extension for Authentication),
RFC 2821 (Simple Mail Transfer Protocol),
RFC 2822 (Internet Message Format),
RFC 2852 (Deliver By SMTP Service Extension),
+RFC 2920 (SMTP Service Extension for Command Pipelining),
and
-RFC 2920 (SMTP Service Extension for Command Pipelining).
+RFC 7505 (A "Null MX" No Service Resource Record for Domains That Accept No Mail).
However, since
.i sendmail
is designed to work in a wider world,
@@ -309,9 +309,8 @@ program; for details see
.sh 3 "Creating a Site Configuration File"
.\"XXX
.pp
-(This section is not yet complete.
-For now, see the file devtools/README for details.)
-See sendmail/README for various compilation flags that can be set.
+See sendmail/README for various compilation flags that can be set,
+and devtools/README for details how to set them.
.sh 3 "Tweaking the Makefile"
.pp
.\" .b "XXX This should all be in the Site Configuration File section."
@@ -323,6 +322,8 @@ notably the
database.
At least one of these should be defined if at all possible.
.nr ii 1i
+.ip CDB
+Constant DataBase (tinycdb).
.ip NDBM
The ``new DBM'' format,
available on nearly all systems around today.
@@ -1224,7 +1225,9 @@ A recipient address is mapped to a queue group as follows.
First, if there is a ruleset called ``queuegroup'',
and if this ruleset maps the address to a queue group name,
then that queue group is chosen.
-That is, the argument for the ruleset is the recipient address
+That is, the argument for the ruleset is
+the recipient address
+(i.e., the address part of the resolved triple)
and the result should be
.b $#
followed by the name of a queue group.
@@ -1282,7 +1285,7 @@ In case one of the queue runners tries delivery to a slow recipient site
at the end of a queue run, the next queue run may be substantially delayed.
In general this should be smoothed out due to the distribution of
those slow jobs, however, for sites with small number of
-queue entries this might introduce noticable delays.
+queue entries this might introduce noticeable delays.
In general, persistent queue runners are only useful for
sites with big queues.
.sh 3 "Manual Intervention"
@@ -2908,7 +2911,7 @@ Therefore it is necessary to run the client mail queue periodically.
.pp
.i Sendmail
has several parameters to control resource usage.
-Besides those mentionted in the previous section, there are at least
+Besides those mentioned in the previous section, there are at least
.b MaxDaemonChildren ,
.b ConnectionRateThrottle ,
.b MaxQueueChildren ,
@@ -2954,7 +2957,7 @@ by looking for the macro definitions of
and
.b MAXETRNCOMMANDS .
If an SMTP command is issued more often than the corresponding
-.b MAXcmdCOMMANDS
+.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
@@ -2966,7 +2969,7 @@ 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
+.b MAXBADCOMMANDS
is set to a value greater than zero (the default is 25).
.sh 2 "Delivery Mode"
.pp
@@ -3038,8 +3041,9 @@ should not be used by the SMTP server.
.pp
The level of logging can be set for
.i sendmail .
-The default using a standard configuration table is level 9.
-The levels are as follows:
+The default using a standard configuration is level 9.
+The levels are approximately as follows
+(some log types are using different level depending on various factors):
.nr ii 0.5i
.ip 0
Minimal logging.
@@ -3078,7 +3082,7 @@ questionable situations.
.ip 14
Logs refused connections.
.ip 15
-Log all incoming and outgoing SMTP commands.
+Log all incoming SMTP commands.
.ip 20
Logs attempts to run locked queue files.
These are not errors,
@@ -3280,7 +3284,7 @@ Accept group-writable
.i \&.forward
files as safe for program and file delivery.
.ip GroupWritableIncludeFile
-Allow group wriable
+Allow group writable
.i :include:
files.
.ip GroupWritableIncludeFileSafe
@@ -3355,7 +3359,7 @@ Allow world writable
.i \&.forward
files.
.ip WorldWritableIncludefile
-Allow world wriable
+Allow world writable
.i :include:
files.
.ip WriteMapToHardLink
@@ -3932,7 +3936,7 @@ The complete syntax for ruleset 0 is:
.)b
This specifies the
{mailer, host, user}
-3-tuple necessary to direct the mailer.
+3-tuple (triple) necessary to direct the mailer.
Note: the third element (
.i user
) is often also called
@@ -3964,9 +3968,11 @@ If the
is the built-in IPC mailer,
the
.i host
-may be a colon-separated list of hosts
-that are searched in order for the first working address
-(exactly like MX records).
+may be a colon (or comma) separated list of hosts.
+Each is separately MX expanded and the results are concatenated
+to make (essentially) one long MX list.
+Hosts separated by a comma have the same MX preference,
+and for each colon separated host the MX preference is increased.
The
.i user
is later rewritten by the mailer-specific envelope rewriting set
@@ -4148,7 +4154,7 @@ 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,
+i.e., it may specify a recipient,
it is also run through ruleset zero.
If ruleset zero returns a temporary error
.b 4xy
@@ -4515,7 +4521,7 @@ for details, as well as
and note this warning:
Options already set before are not cleared!
.ip CipherList
-Specify cipher list for STARTTLS,
+Specify cipher list for STARTTLS (does not apply to TLSv1.3),
see
.i ciphers (1)
for possible values.
@@ -4526,6 +4532,28 @@ for the session.
File containing a certificate.
.ip KeyFile
File containing the private key for the certificate.
+.ip Flags
+Currently the only valid flags are
+.br
+.i R
+to require a CRL for each encountered certificate during verification
+(by default a missing CRL is ignored),
+.br
+.i c
+and
+.i C
+which basically clears/sets the option
+.i TLSFallbacktoClear
+for just this session, respectively,
+.br
+.i d
+to turn off DANE which is obviously only valid for
+.i tls_clt_features
+and requires DANE to be compiled in.
+This might be needed in case of a misconfiguration,
+e.g.,
+specifying invalid TLSA RRs.
+.br
.lp
.lp
Example:
@@ -4550,9 +4578,6 @@ and
.i KeyFile
must be specified together;
specifying only one is an error.
-.pp
-These rulesets require the sendmail binary to be built with _FFR_TLS_SE_OPTS
-enabled (see the "For Future Release" section).
.sh 4 "authinfo"
.pp
The
@@ -4589,9 +4614,9 @@ is ignored (even if the ruleset does not return a ``useful'' result).
The
.i queuegroup
ruleset is used to map a recipient address to a queue group name.
-The input for the ruleset is a recipient address as specified by the
-.sm "SMTP RCPT"
-command.
+The input for the ruleset is
+the recipient address
+(i.e., the address part of the resolved triple)
The ruleset should return
.b $#
followed by the name of a queue group.
@@ -4615,7 +4640,7 @@ 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.,
+when smtps (SMTP over SSL) is used, i.e.,
the
.i s
modifier is set for the daemon via
@@ -4651,9 +4676,11 @@ to an IP host address.
.pp
The host name passed in after the
.q $@
-may also be a colon-separated list of hosts.
+may also be a colon or comma separated list of hosts.
Each is separately MX expanded and the results are concatenated
to make (essentially) one long MX list.
+Hosts separated by a comma have the same MX preference,
+and for each colon separated host the MX preference is increased.
The intent here is to create
.q fake
MX records that are not published in DNS
@@ -5224,7 +5251,7 @@ The output of the
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;
+The TLS/SSL version used for the connection, e.g., TLSv1.2, TLSv1;
defined after STARTTLS has been used.
.ip ${total_rate}
The total number of incoming connections over the time interval specified
@@ -5241,6 +5268,7 @@ NOT no cert requested.
FAIL cert presented but could not be verified,
e.g., the signing CA is missing.
NONE STARTTLS has not been performed.
+CLEAR STARTTLS has been disabled internally for a clear text delivery attempt.
TEMP temporary error occurred.
PROTOCOL some protocol error occurred
at the ESMTP level (not TLS).
@@ -5859,7 +5887,7 @@ Do User Database rewriting on recipients as well as senders.
Normally when
.i sendmail
connects to a host via SMTP,
-it checks to make sure that this isn't accidently the same host name
+it checks to make sure that this isn't accidentally the same host name
as might happen if
.i sendmail
is misconfigured or if a long-haul network interface is set in loopback mode.
@@ -5893,7 +5921,7 @@ macro occurs in the
part of the mailer definition,
that field will be repeated as necessary
for all qualifying users.
-Removing this flag can defeat duplicate supression on a remote site
+Removing this flag can defeat duplicate suppression on a remote site
as each recipient is sent in a separate transaction.
.ip M\(dg
This mailer wants a
@@ -6519,6 +6547,10 @@ is specified),
(if
.sm NDBM
is specified),
+.q cdb
+(if
+.sm CDB
+is specified),
.q stab
(internal symbol table \*- not normally used
unless you have no other database lookup),
@@ -6647,7 +6679,7 @@ see section about STARTTLS for more information.
Specify the fingerprint algorithm (digest) to use for the presented cert.
If the option is not set,
md5 is used and the macro
-.p ${cert_md5}
+.b ${cert_md5}
contains the cert fingerprint.
If the option is explicitly set,
the specified algorithm (e.g., sha1) is used
@@ -6655,7 +6687,7 @@ and the macro
.b ${cert_fp}
contains the cert fingerprint.
.ip CipherList
-Specify cipher list for STARTTLS.
+Specify cipher list for STARTTLS (does not apply to TLSv1.3).
See
.i ciphers (1)
for possible values.
@@ -6756,7 +6788,7 @@ By default,
.i -SSL_OP_TLSEXT_PADDING
are used
(if those options are available).
-Options can be cleared by preceeding them with a minus sign.
+Options can be cleared by preceding them with a minus sign.
It is also possible to specify numerical values, e.g.,
.b -0x0010 .
.ip ColonOkInAddr
@@ -6851,9 +6883,18 @@ Solaris and pre-4.4BSD kernel users should see the note in sendmail/README .
[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 CRLPath=\fIname\fP
+[no short name]
+Name of directory that contains hashes pointing to
+certificate revocation status files.
+Symbolic links can be generated with the following
+two (Bourne) shell commands:
+.(b
+C=FileName_of_CRL
+ln -s $C `openssl crl -noout -hash < $C`.r0
+.)b
.ip DHParameters
This option applies to the server side only.
Possible values are:
@@ -6948,7 +6989,7 @@ can be a sequence (without any delimiters)
of the following characters:
.(b
.ta 1i
-a always require authentication
+a always require AUTH
b bind to interface through which mail has been received
c perform hostname canonification (.cf)
f require fully qualified hostname (.cf)
@@ -6961,7 +7002,7 @@ O optional; if opening the socket fails ignore it
S don't offer STARTTLS
.)b
That is, one way to specify a message submission agent (MSA) that
-always requires authentication is:
+always requires AUTH is:
.(b
O DaemonPortOptions=Name=MSA, Port=587, M=Ea
.)b
@@ -7000,7 +7041,7 @@ This will also override possible settings via
Note,
.i sendmail
will listen on a new socket
-for each occurence of the
+for each occurrence of the
.b DaemonPortOptions
option in a configuration file.
The modifier ``O'' causes sendmail to ignore a socket
@@ -7296,6 +7337,18 @@ are:
.\"8BITMIME\(->7BIT conversions are done.
In all cases properly declared 8BITMIME data will be converted to 7BIT
as needed.
+.p
+Note: if an automatic conversion is performed, a header with
+the following format will be added:
+.(b
+X-MIME-Autoconverted: from OLD to NEW by $j id $i
+.)b
+where
+.\" format?
+OLD
+and
+NEW
+describe the original format and the converted format, respectively.
.ip ErrorHeader=\fIfile-or-message\fP
[E]
Prepend error messages with the indicated message.
@@ -7393,6 +7446,10 @@ and then in
.ip HeloName=\fIname\fP
[no short name]
Set the name to be used for HELO/EHLO (instead of $j).
+.ip HelpFile=\fIfile\fP
+[H]
+Specify the help file for SMTP.
+If no file name is specified, "helpfile" is used.
.ip HoldExpensive
[c]
If an outgoing mailer is marked as being expensive,
@@ -7520,9 +7577,10 @@ If not set, there is no limit to the number of children --
that is, the system load average controls this.
.ip MaxHeadersLength=\fIN\fP
[no short name]
-The maximum length of the sum of all headers.
+If set to a value greater than zero it specifies
+the maximum length of the sum of all headers.
This can be used to prevent a denial of service attack.
-The default is no limit.
+The default is 32K.
.ip MaxHopCount=\fIN\fP
[h]
The maximum hop count.
@@ -7706,6 +7764,12 @@ Sets the list of characters that must be quoted if used in a full name
that is in the phrase part of a ``phrase <address>'' syntax.
The default is ``\'.''.
The characters ``@,;:\e()[]'' are always added to this list.
+Note: To avoid potential breakage of
+DKIM signatures it is useful to set
+.(b
+O MustQuoteChars=.
+.)b
+Moreover, relaxed header signing should be used for DKIM signatures.
.ip NiceQueueRun
[no short name]
The priority of queue runners (nice(3)).
@@ -8189,7 +8253,7 @@ By default,
.i -SSL_OP_TLSEXT_PADDING
are used
(if those options are available).
-Options can be cleared by preceeding them with a minus sign.
+Options can be cleared by preceding them with a minus sign.
It is also possible to specify numerical values, e.g.,
.b -0x0010 .
.ip ServiceSwitchFile=\fIfilename\fP
@@ -8301,6 +8365,31 @@ Defaults to
If set, issue temporary errors (4xy) instead of permanent errors (5xy).
This can be useful during testing of a new configuration to avoid
erroneous bouncing of mails.
+.ip SSLEngine
+Name of SSL engine to use.
+The available values depend on the OpenSSL version against which
+.i sendmail
+is compiled,
+see
+.(b
+openssl engine -v
+.)b
+for some information.
+.ip SSLEnginePath
+Path to dynamic library for SSL engine.
+This option is only useful if
+.i SSLEngine
+is set.
+If both are set, the engine will be loaded dynamically at runtime
+using the concatenation of the path,
+a slash "/",
+the string "lib",
+the value of
+.i SSLEngine ,
+and the string ".so".
+If only
+.i SSLEngine
+is set then the static version of the engine is used.
.ip StatusFile=\fIfile\fP
[S]
Log summary statistics in the named
@@ -8340,6 +8429,22 @@ PostMilter is useful only when
.i sendmail
is running as an SMTP server; in all other situations it
acts the same as True.
+.ip TLSFallbacktoClear
+[no short name]
+If set,
+.i sendmail
+immediately tries an outbound connection again without STARTTLS
+after a TLS handshake failure.
+Note:
+this applies to all connections even if TLS specific requirements are set
+(see rulesets
+.i tls_rcpt
+and
+.i tls_client
+).
+Hence such requirements will cause an error on a retry without STARTTLS.
+Therefore they should only trigger a temporary failure so the connection
+is later on tried again.
.ip TLSSrvOptions
[no short name]
List of options for SMTP STARTTLS for the server
@@ -8824,6 +8929,12 @@ $[\fIhostname\fP$]
.)b
.pp
There are many defined classes.
+.ip cdb
+Database lookups using the cdb(3) library.
+.i Sendmail
+must be compiled with
+.b CDB
+defined.
.ip dbm
Database lookups using the ndbm(3) library.
.i Sendmail
@@ -8885,7 +8996,7 @@ only the first value will be returned
unless the
.b \-z
(value separator)
-map flag is set.
+map option is set.
Also, the
.b \-1
map flag will treat a multiple value return
@@ -8906,14 +9017,11 @@ The format of the text file is defined by the
and
.b \-z
(field delimiter)
-flags.
+options.
.ip ph
PH query map.
Contributed and supported by
Mark Roth, roth@uiuc.edu.
-For more information,
-consult the web site
-.q http://www-dev.cites.uiuc.edu/sendmail/ .
.ip nsd
nsd map for IRIX 6.5 and later.
Contributed and supported by Bob Mende of SGI,
@@ -8922,11 +9030,15 @@ mende@sgi.com.
Internal symbol table lookups.
Used internally for aliasing.
.ip implicit
-Really should be called
-.q alias
-\(em this is used to get the default lookups
-for alias files,
-and is the default if no class is specified for alias files.
+Sequentially try a list of available map types:
+.i hash ,
+.i dbm ,
+and
+.i cdb .
+It is the default for alias files if no class is specified.
+If is no matching map type is found,
+the text version is used for the alias file,
+but other maps fail to open.
.ip user
Looks up users using
.i getpwnam (3).
@@ -8948,15 +9060,24 @@ This can be used to find out if this machine is the target for an MX record,
and mail can be accepted on that basis.
If the
.b \-z
-flag is given, then all MX names are returned,
+option is given, then all MX names are returned,
separated by the given delimiter.
+Note: the return value is deterministic,
+i.e., even if multiple MX records have the same preference,
+they will be returned in the same order.
.ip dns
This map requires the option -R to specify the DNS resource record
-type to lookup. The following types are supported:
+type to lookup.
+The following types are supported:
A, AAAA, AFSDB, CNAME, MX, NS, PTR, SRV, and TXT.
-A map lookup will return only one record.
+A map lookup will return only one record
+unless the
+.b \-z
+(value separator)
+option is set.
Hence for some types, e.g., MX records, the return value might be a random
-element of the list due to randomizing in the DNS resolver.
+element of the results due to randomizing in the DNS resolver,
+if only one element is returned.
.ip arpa
Returns the ``reverse'' for the given IP (IPv4 or IPv6) address,
i.e., the string for the PTR lookup,
@@ -8969,7 +9090,7 @@ For example, the following configuration lines:
Karpa arpa
SArpa
R$+ $: $(arpa $1 $)
-.)b
+.)b
work like this in test mode:
.(b
sendmail -bt
@@ -9069,33 +9190,45 @@ if used, it is substituted by the substring matches, delimited by
.b $|
or the string specified with the the
.b \-d
-flag. The flags available for the map are
+option.
+The options available for the map are
.(b
.ta 4n
-n not
-f case sensitive
-b basic regular expressions (default is extended)
-s substring match
--d set the delimiter used for -s
+-d set the delimiter string used for -s
-a append string to key
-m match only, do not replace/discard value
-D perform no lookup in deferred delivery mode.
.)b
The
.b \-s
-flag can include an optional parameter which can be used
-to select the substrings in the result of the lookup. For example,
+option can include an optional parameter which can be used
+to select the substrings in the result of the lookup.
+For example,
.(b
-s1,3,4
.)b
+The delimiter string specified via the
+.b \-d
+option is the sequence of characters after
+.b d
+ending at the first space.
+Hence it isn't possible to specify a space as delimiter,
+so if the option is immediately followed by a space
+the delimiter string is empty,
+which means the substrings are joined.
+
Notes: to match a
.b $
in a string,
\\$$
must be used.
-If the pattern contains spaces, they must be replaced
-with the blank substitution character, unless it is
-space itself.
+If the pattern contains spaces,
+they must be replaced with the blank substitution character,
+unless it is space itself.
.ip program
The arguments on the
.b K
@@ -9185,12 +9318,12 @@ and is one of the following upper case words:
.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
+TEMP a temporary failure occurred
+TIMEOUT a timeout occurred on the server side
+PERM a permanent failure occurred
.)b
-In case of errors (status TEMP, TIMEOUT or PERM) the result field may
+In case of errors (status TEMP, TIMEOUT or PERM) the result field may
contain an explanatory message.
However, the explanatory message is not used any further by
.i sendmail .
@@ -9206,7 +9339,7 @@ Example replies:
in case of successful lookups, or:
.(b
-8:NOTFOUND,
+8:NOTFOUND,
.)b
in case the key was not found, or:
@@ -9331,7 +9464,7 @@ or
to indicate newline or tab respectively.
If omitted entirely,
the column separator is any sequence of white space.
-For LDAP maps this is the separator character
+For LDAP and some other maps this is the separator character
to combine multiple values
into a single return string.
If not set,
@@ -9413,6 +9546,11 @@ timeout: specify the timeout (in seconds) for communication
with the socket map server.
.pp
The following additional flags are present in the ldap map only:
+.ip "\-c\fItimeout\fP"
+Set the LDAP network timeout.
+sendmail must be compiled with
+.b \-DLDAP_OPT_NETWORK_TIMEOUT
+to use this flag.
.ip "\-R"
Do not auto chase referrals. sendmail must be compiled with
.b \-DLDAP_REFERRALS
@@ -9480,6 +9618,9 @@ Should be one of
.b LDAP_AUTH_SIMPLE ,
or
.b LDAP_AUTH_KRBV4 .
+The leading
+.b LDAP_AUTH_
+can be omitted and the value is case-insensitive.
.ip "\-P\fIpasswordfile\fP"
The file containing the secret key for the
.b LDAP_AUTH_SIMPLE
@@ -9530,8 +9671,9 @@ and the data is located in
.pp
The program
.i makemap (8)
-can be used to build any of the three database-oriented maps.
-It takes the following flags:
+can be used to build database-oriented maps.
+It takes at least the following flags
+(for a complete list see its man page):
.ip \-f
Do not fold upper to lower case in the map.
.ip \-N
@@ -9980,8 +10122,10 @@ configuration file.
If set,
the new version of the DBM library
that allows multiple databases will be used.
-If neither NDBM nor NEWDB are set,
+If neither CDB, NDBM, nor NEWDB are set,
a much less efficient method of alias lookup is used.
+.ip CWDB
+If set, use the cdb (tinycdb) package.
.ip NEWDB
If set, use the new database package from Berkeley (from 4.4BSD).
This package is substantially faster than DBM or NDBM.
@@ -10418,7 +10562,7 @@ Addresses in this header should receive error messages.
This header is a Content-Transfer-Encoding header.
.ip H_CTYPE
This header is a Content-Type header.
-.ip H_STRIPVAL
+.ip H_BCC
Strip the value from the header (for Bcc:).
.nr ii 5n
.lp
@@ -10440,7 +10584,7 @@ struct hdrinfo HdrInfo[] =
"to", H_RCPT,
"resent-to", H_RCPT,
"cc", H_RCPT,
- "bcc", H_RCPT\^|\^H_STRIPVAL,
+ "bcc", H_RCPT\^|\^H_BCC,
/* message identification and control */
"message", H_EOH,
"text", H_EOH,
@@ -10864,7 +11008,7 @@ it is necessary to understand at least some basics about X.509 certificates
and public key cryptography.
This information can be found in books about SSL/TLS
or on WWW sites, e.g.,
-.q http://www.OpenSSL.org/ .
+.q https://www.OpenSSL.org/ .
.sh 3 "Certificates for STARTTLS"
.pp
When acting as a server,
@@ -11003,6 +11147,43 @@ 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 2 "DANE"
+.pp
+Initial support for DANE (see RFC 7672 et.al.)
+is available if
+.i sendmail
+is compiled with the option
+.b DANE .
+Only TLSA RR 3-1-x (DANE-EE) is currently implemented.
+The option
+.(b
+O DANE=true
+.)b
+enables this feature at run time
+and it automatically adds
+.b use_dnssec
+and
+.b use_edns0
+to
+.(b
+O ResolverOptions
+.)b
+This requires a (preferrably local)
+validating DNS resolver which supports those options.
+
+If the client finds a usable TLSA RR and the check
+succeeds the macro
+.b ${verify}
+is set to
+.b TRUSTED .
+All non-DNS maps are considered
+.i secure
+just like DNS lookups with DNSSEC.
+Be aware that the implementation might not handle all
+error conditions as required by the RFCs.
+Moreover, TLSA RRs are not looked up for some features,
+e.g.,
+.i FallBackSmartHost .
.sh 1 "ACKNOWLEDGEMENTS"
.pp
I've worked on
@@ -11243,7 +11424,6 @@ this is equivalent to using \-p.)
.ip \-q\fItime\fP
Try to process the queued up mail.
If the time is given,
-a
.i sendmail
will start one or more processes to run through the queue(s) at the specified
time interval to deliver queued mail; otherwise, it only runs once.
@@ -11307,7 +11487,7 @@ together, and items with different key letters
.q and'ed
together.
.ip "\-Q[reason]"
-Quarantine a normal queue items with the given reason or
+Quarantine 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
@@ -11512,11 +11692,10 @@ but is actually realiased when the job is processed.
There will be one line for each recipient.
Version 1 qf files
also include a leading colon-terminated list of flags,
-which can be
+some of which are
`S' to return a message on successful final delivery,
`F' to return a message on failure,
`D' to return a message if the message is delayed,
-`B' to indicate that the body should be returned,
`N' to suppress returning the body,
and
`P' to declare this as a ``primary'' (command line or SMTP-session) address.
@@ -11727,7 +11906,6 @@ replace it with a blank sheet for double-sided output.
.\".sz 10
.\"Eric Allman
.\".sp
-.\"Version $Revision: 8.759 $
.\".ce 0
.bp 3
.ce
diff --git a/contrib/sendmail/editmap/Makefile b/contrib/sendmail/editmap/Makefile
index f08d5a7ccde9..b173ba9fa62b 100644
--- a/contrib/sendmail/editmap/Makefile
+++ b/contrib/sendmail/editmap/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/editmap/editmap.c b/contrib/sendmail/editmap/editmap.c
index 66ee5793d5d7..c3454cb495ae 100644
--- a/contrib/sendmail/editmap/editmap.c
+++ b/contrib/sendmail/editmap/editmap.c
@@ -23,19 +23,19 @@ SM_UNUSED(static char copyright[]) =
#ifndef lint
SM_UNUSED(static char id[]) = "@(#)$Id: editmap.c,v 1.26 2013-11-22 20:51:26 ca Exp $";
-#endif /* ! lint */
+#endif
#include <sys/types.h>
#ifndef ISC_UNIX
# include <sys/file.h>
-#endif /* ! ISC_UNIX */
+#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
+#endif
#include <sysexits.h>
#include <assert.h>
#include <sendmail/sendmail.h>
@@ -100,7 +100,7 @@ main(argc, argv)
#if HASFCHOWN
FILE *cfp;
char buf[MAXLINE];
-#endif /* HASFCHOWN */
+#endif
static char rnamebuf[MAXNAME]; /* holds RealUserName */
extern char *optarg;
extern int optind;
diff --git a/contrib/sendmail/include/libmilter/mfapi.h b/contrib/sendmail/include/libmilter/mfapi.h
index 039a16a94481..2b012d86af2b 100644
--- a/contrib/sendmail/include/libmilter/mfapi.h
+++ b/contrib/sendmail/include/libmilter/mfapi.h
@@ -43,11 +43,11 @@
/* Only need to export C interface if used by C++ source code */
#ifdef __cplusplus
extern "C" {
-#endif /* __cplusplus */
+#endif
#ifndef _SOCK_ADDR
# define _SOCK_ADDR struct sockaddr
-#endif /* ! _SOCK_ADDR */
+#endif
/*
** libmilter functions return one of the following to indicate
@@ -58,7 +58,7 @@ extern "C" {
#define MI_FAILURE (-1)
#if _FFR_WORKERS_POOL
# define MI_CONTINUE 1
-#endif /* _FFR_WORKERS_POOL */
+#endif
/* "forward" declarations */
typedef struct smfi_str SMFICTX;
@@ -76,17 +76,17 @@ typedef int sfsistat;
#if defined(__linux__) && defined(__GNUC__) && defined(__cplusplus) && __GNUC_MINOR__ >= 8
# define SM__P(X) __PMT(X)
-#else /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */
+#else
# define SM__P(X) __P(X)
-#endif /* __linux__ && __GNUC__ && __cplusplus && _GNUC_MINOR__ >= 8 */
+#endif
/* Some platforms don't define __P -- do it for them here: */
#ifndef __P
# ifdef __STDC__
# define __P(X) X
-# else /* __STDC__ */
+# else
# define __P(X) ()
-# endif /* __STDC__ */
+# endif
#endif /* __P */
#if SM_CONF_STDBOOL_H
@@ -464,7 +464,7 @@ LIBMILTER_API int smfi_chgheader __P((SMFICTX *, char *, int, char *));
**
** SMFICTX *ctx; Opaque context structure
** char *headerf; Header field name
-** int index; The Nth occurence of header field name
+** int index; The Nth occurrence of header field name
** char *headerv; New header field value (empty for delete header)
*/
@@ -594,10 +594,10 @@ LIBMILTER_API int smfi_setsymlist __P((SMFICTX *, int, char *));
#if _FFR_THREAD_MONITOR
LIBMILTER_API int smfi_set_max_exec_time __P((unsigned int));
-#endif /* _FFR_THREAD_MONITOR */
+#endif
#ifdef __cplusplus
}
-#endif /* __cplusplus */
+#endif
#endif /* ! _LIBMILTER_MFAPI_H */
diff --git a/contrib/sendmail/include/libmilter/mfdef.h b/contrib/sendmail/include/libmilter/mfdef.h
index 7dc9d5eb4341..02a34d3a2028 100644
--- a/contrib/sendmail/include/libmilter/mfdef.h
+++ b/contrib/sendmail/include/libmilter/mfdef.h
@@ -19,7 +19,7 @@
#ifndef SMFI_PROT_VERSION
# define SMFI_PROT_VERSION 6 /* MTA - libmilter protocol version */
-#endif /* SMFI_PROT_VERSION */
+#endif
/* Shared protocol constants */
#define MILTER_LEN_BYTES 4 /* length of 32 bit integer in bytes */
@@ -121,6 +121,6 @@
#if _FFR_MILTER_CHECK
# define SMFIP_TEST 0x80000000L
-#endif /* _FFR_MILTER_CHECK */
+#endif
#endif /* !_LIBMILTER_MFDEF_H */
diff --git a/contrib/sendmail/include/libsmdb/smdb.h b/contrib/sendmail/include/libsmdb/smdb.h
index a1df6d7ae801..427599ce206c 100644
--- a/contrib/sendmail/include/libsmdb/smdb.h
+++ b/contrib/sendmail/include/libsmdb/smdb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2002 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1999-2002, 2018 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -18,13 +18,13 @@
# include <sm/gen.h>
# include <sm/errstring.h>
-# ifdef NDBM
+# if NDBM
# include <ndbm.h>
-# endif /* NDBM */
+# endif
-# ifdef NEWDB
+# if NEWDB
# include "sm/bdb.h"
-# endif /* NEWDB */
+# endif
/*
** Some size constants
@@ -119,7 +119,6 @@ typedef int (*db_get_func) __P((SMDB_DATABASE *db,
** flags -- put options:
** SMDBF_NO_OVERWRITE - Return an error if key alread
** exists.
-** SMDBF_ALLOW_DUP - Allow duplicates in btree maps.
**
** Returns:
** 0 - Success, otherwise errno.
@@ -190,6 +189,7 @@ struct database_struct
db_lockfd_func smdb_lockfd;
void *smdb_impl;
};
+
/*
** DB_CURSOR_CLOSE -- Close a cursor
**
@@ -244,10 +244,10 @@ typedef int (*db_cursor_get_func) __P((SMDB_CURSOR *cursor,
** Flags for DB_CURSOR_GET
*/
-#define SMDB_CURSOR_GET_FIRST 0
-#define SMDB_CURSOR_GET_LAST 1
+#define SMDB_CURSOR_GET_FIRST 0 /* NOT USED by any application */
+#define SMDB_CURSOR_GET_LAST 1 /* NOT USED by any application */
#define SMDB_CURSOR_GET_NEXT 2
-#define SMDB_CURSOR_GET_RANGE 3
+#define SMDB_CURSOR_GET_RANGE 3 /* NOT USED by any application */
/*
** DB_CURSOR_PUT -- Put the key/value at this cursor.
@@ -313,12 +313,34 @@ typedef unsigned int SMDB_FLAG;
# define SMDB_TYPE_DEFAULT NULL
# define SMDB_TYPE_DEFAULT_LEN 0
+# define SMDB_TYPE_IMPL "implicit"
+# define SMDB_TYPE_IMPL_LEN 9
# define SMDB_TYPE_HASH "hash"
# define SMDB_TYPE_HASH_LEN 5
# define SMDB_TYPE_BTREE "btree"
# define SMDB_TYPE_BTREE_LEN 6
# define SMDB_TYPE_NDBM "dbm"
# define SMDB_TYPE_NDBM_LEN 4
+# define SMDB_TYPE_CDB "cdb"
+# define SMDB_TYPE_CDB_LEN 4
+
+# define SMDB_IS_TYPE_HASH(type) (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
+# define SMDB_IS_TYPE_BTREE(type) (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
+# define SMDB_IS_TYPE_NDBM(type) (strncmp(type, SMDB_TYPE_NDBM, SMDB_TYPE_NDBM_LEN) == 0)
+# define SMDB_IS_TYPE_CDB(type) (strncmp(type, SMDB_TYPE_CDB, SMDB_TYPE_CDB_LEN) == 0)
+
+# define SMDB_IS_TYPE_DEFAULT(t) (((t) == SMDB_TYPE_DEFAULT) \
+ || (strncmp(type, SMDB_TYPE_IMPL, SMDB_TYPE_IMPL_LEN) == 0) \
+ )
+
+# if CDB >= 2
+# define SMCDB_FILE_EXTENSION "db"
+# else
+# define SMCDB_FILE_EXTENSION "cdb"
+# endif
+# define SMDB1_FILE_EXTENSION "db"
+# define SMDB2_FILE_EXTENSION "db"
+# define SMNDB_DIR_FILE_EXTENSION "dir"
/*
** These are flags
@@ -326,26 +348,22 @@ typedef unsigned int SMDB_FLAG;
/* Flags for put */
# define SMDBF_NO_OVERWRITE 0x00000001
-# define SMDBF_ALLOW_DUP 0x00000002
+typedef int (smdb_open_func) __P((SMDB_DATABASE **, char *, int, int, long, SMDB_DBTYPE, SMDB_USER_INFO *, SMDB_DBPARAMS *));
extern SMDB_DATABASE *smdb_malloc_database __P((void));
extern void smdb_free_database __P((SMDB_DATABASE *));
-extern int smdb_open_database __P((SMDB_DATABASE **, char *, int,
- int, long, SMDB_DBTYPE,
- SMDB_USER_INFO *,
- SMDB_DBPARAMS *));
-# ifdef NEWDB
-extern int smdb_db_open __P((SMDB_DATABASE **, char *, int, int,
- long, SMDB_DBTYPE, SMDB_USER_INFO *,
- SMDB_DBPARAMS *));
-# endif /* NEWDB */
-# ifdef NDBM
-extern int smdb_ndbm_open __P((SMDB_DATABASE **, char *, int, int,
- long, SMDB_DBTYPE,
- SMDB_USER_INFO *,
- SMDB_DBPARAMS *));
-# endif /* NDBM */
+extern smdb_open_func smdb_open_database;
+# if NEWDB
+extern smdb_open_func smdb_db_open;
+# else
+# define smdb_db_open NULL
+# endif
+# if NDBM
+extern smdb_open_func smdb_ndbm_open;
+# else
+# define smdb_ndbm_open NULL
+# endif
extern int smdb_add_extension __P((char *, int, char *, char *));
extern int smdb_setup_file __P((char *, char *, int, long,
SMDB_USER_INFO *, struct stat *));
@@ -353,8 +371,15 @@ extern int smdb_lock_file __P((int *, char *, int, long, char *));
extern int smdb_unlock_file __P((int));
extern int smdb_filechanged __P((char *, char *, int,
struct stat *));
-extern void smdb_print_available_types __P((void));
+extern void smdb_print_available_types __P((bool));
+extern bool smdb_is_db_type __P((const char *));
extern char *smdb_db_definition __P((SMDB_DBTYPE));
extern int smdb_lock_map __P((SMDB_DATABASE *, int));
extern int smdb_unlock_map __P((SMDB_DATABASE *));
+
+# if CDB
+extern smdb_open_func smdb_cdb_open;
+# else
+# define smdb_cdb_open NULL
+# endif
#endif /* ! _SMDB_H_ */
diff --git a/contrib/sendmail/include/sendmail/pathnames.h b/contrib/sendmail/include/sendmail/pathnames.h
index 1e7bab58ccf1..67be3a2d0184 100644
--- a/contrib/sendmail/include/sendmail/pathnames.h
+++ b/contrib/sendmail/include/sendmail/pathnames.h
@@ -19,34 +19,34 @@
# ifndef _PATH_SENDMAILCF
# if defined(USE_VENDOR_CF_PATH) && defined(_PATH_VENDOR_CF)
# define _PATH_SENDMAILCF _PATH_VENDOR_CF
-# else /* defined(USE_VENDOR_CF_PATH) && defined(_PATH_VENDOR_CF) */
+# else
# define _PATH_SENDMAILCF "/etc/mail/sendmail.cf"
-# endif /* defined(USE_VENDOR_CF_PATH) && defined(_PATH_VENDOR_CF) */
+# endif
# endif /* ! _PATH_SENDMAILCF */
# ifndef _PATH_SENDMAILPID
# ifdef BSD4_4
# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
-# else /* BSD4_4 */
+# else
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
-# endif /* BSD4_4 */
+# endif
# endif /* ! _PATH_SENDMAILPID */
# ifndef _PATH_SENDMAIL
# define _PATH_SENDMAIL "/usr/lib/sendmail"
-# endif /* ! _PATH_SENDMAIL */
+# endif
# ifndef _PATH_MAILDIR
# define _PATH_MAILDIR "/var/spool/mail"
-# endif /* ! _PATH_MAILDIR */
+# endif
# ifndef _PATH_LOCTMP
# define _PATH_LOCTMP "/tmp/local.XXXXXX"
-# endif /* ! _PATH_LOCTMP */
+# endif
# ifndef _PATH_HOSTS
# define _PATH_HOSTS "/etc/hosts"
-# endif /* ! _PATH_HOSTS */
+# endif
diff --git a/contrib/sendmail/include/sendmail/sendmail.h b/contrib/sendmail/include/sendmail/sendmail.h
index c79072299b60..6ab789bd3679 100644
--- a/contrib/sendmail/include/sendmail/sendmail.h
+++ b/contrib/sendmail/include/sendmail/sendmail.h
@@ -29,7 +29,7 @@
**********************************************************************/
#ifndef MAXMAILERS
# define MAXMAILERS 25 /* maximum mailers known to system */
-#endif /* ! MAXMAILERS */
+#endif
/*
** Flags passed to safefile/safedirpath.
diff --git a/contrib/sendmail/include/sm/assert.h b/contrib/sendmail/include/sm/assert.h
index 9d0ae54e6274..57d8c5f52f32 100644
--- a/contrib/sendmail/include/sm/assert.h
+++ b/contrib/sendmail/include/sm/assert.h
@@ -47,19 +47,19 @@ sm_abort __P((
# ifndef SM_CHECK_ALL
# define SM_CHECK_ALL 1
-# endif /* ! SM_CHECK_ALL */
+# endif
# ifndef SM_CHECK_REQUIRE
# define SM_CHECK_REQUIRE SM_CHECK_ALL
-# endif /* ! SM_CHECK_REQUIRE */
+# endif
# ifndef SM_CHECK_ENSURE
# define SM_CHECK_ENSURE SM_CHECK_ALL
-# endif /* ! SM_CHECK_ENSURE */
+# endif
# ifndef SM_CHECK_ASSERT
# define SM_CHECK_ASSERT SM_CHECK_ALL
-# endif /* ! SM_CHECK_ASSERT */
+# endif
# if SM_CHECK_REQUIRE
# if defined(__STDC__) || defined(__cplusplus)
diff --git a/contrib/sendmail/include/sm/bdb.h b/contrib/sendmail/include/sm/bdb.h
index 893d815229fe..832de252ca65 100644
--- a/contrib/sendmail/include/sm/bdb.h
+++ b/contrib/sendmail/include/sm/bdb.h
@@ -17,7 +17,7 @@
# include <db.h>
# ifndef DB_VERSION_MAJOR
# define DB_VERSION_MAJOR 1
-# endif /* ! DB_VERSION_MAJOR */
+# endif
# if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1) || DB_VERSION_MAJOR >= 5
diff --git a/contrib/sendmail/include/sm/cdefs.h b/contrib/sendmail/include/sm/cdefs.h
index 0802d5941c97..52f7f7586f0b 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.17 2013-11-22 20:51:31 ca Exp $
+ * $Id: cdefs.h,v 1.17 2013/11/22 20:51:31 ca Exp $
*/
/*
@@ -27,7 +27,7 @@
# if SM_CONF_SYS_CDEFS_H
# include <sys/cdefs.h>
-# endif /* SM_CONF_SYS_CDEFS_H */
+# endif
/*
** Define the standard C language portability macros
@@ -86,9 +86,9 @@
# if __GNUC__ >= 2
# if __GNUC__ == 2 && __GNUC_MINOR__ < 7
# define SM_UNUSED(decl) decl
-# else /* __GNUC__ == 2 && __GNUC_MINOR__ < 7 */
+# else
# define SM_UNUSED(decl) decl __attribute__((__unused__))
-# endif /* __GNUC__ == 2 && __GNUC_MINOR__ < 7 */
+# endif
# else /* __GNUC__ >= 2 */
# define SM_UNUSED(decl) decl
# endif /* __GNUC__ >= 2 */
@@ -112,9 +112,9 @@
# ifdef SM_OMIT_BOGUS_WARNINGS
# define SM_NONVOLATILE volatile
-# else /* SM_OMIT_BOGUS_WARNINGS */
+# else
# define SM_NONVOLATILE
-# endif /* SM_OMIT_BOGUS_WARNINGS */
+# endif
/*
** Turn on format string argument checking.
@@ -131,17 +131,17 @@
# ifndef PRINTFLIKE
# if SM_CONF_FORMAT_TEST
# define PRINTFLIKE(x,y) __attribute__ ((__format__ (__printf__, x, y)))
-# else /* SM_CONF_FORMAT_TEST */
+# else
# define PRINTFLIKE(x,y)
-# endif /* SM_CONF_FORMAT_TEST */
+# endif
# endif /* ! PRINTFLIKE */
# ifndef SCANFLIKE
# if SM_CONF_FORMAT_TEST
# define SCANFLIKE(x,y) __attribute__ ((__format__ (__scanf__, x, y)))
-# else /* SM_CONF_FORMAT_TEST */
+# else
# define SCANFLIKE(x,y)
-# endif /* SM_CONF_FORMAT_TEST */
+# endif
# endif /* ! SCANFLIKE */
#endif /* ! SM_CDEFS_H */
diff --git a/contrib/sendmail/include/sm/clock.h b/contrib/sendmail/include/sm/clock.h
index 2c7a8e45e45c..264f9b277c41 100644
--- a/contrib/sendmail/include/sm/clock.h
+++ b/contrib/sendmail/include/sm/clock.h
@@ -22,7 +22,7 @@
# include <sm/signal.h>
# if SM_CONF_SETITIMER
# include <sys/time.h>
-# endif /* SM_CONF_SETITIMER */
+# endif
/*
** STRUCT SM_EVENT -- event queue.
@@ -37,9 +37,9 @@ struct sm_event
{
# if SM_CONF_SETITIMER
struct timeval ev_time; /* time of the call (microseconds) */
-# else /* SM_CONF_SETITIMER */
+# else
time_t ev_time; /* time of the call (seconds) */
-# endif /* SM_CONF_SETITIMER */
+# endif
void (*ev_func)__P((int));
/* function to call */
int ev_arg; /* argument to ev_func */
diff --git a/contrib/sendmail/include/sm/conf.h b/contrib/sendmail/include/sm/conf.h
index 761e01f1f244..7bb031bb0bc0 100644
--- a/contrib/sendmail/include/sm/conf.h
+++ b/contrib/sendmail/include/sm/conf.h
@@ -42,7 +42,7 @@
# ifdef __STDC__
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
-# endif /* __STDC__ */
+# endif
/*
** Assume you have standard calls; can be #undefed below if necessary.
@@ -50,15 +50,15 @@
# ifndef HASLSTAT
# define HASLSTAT 1 /* has lstat(2) call */
-# endif /* ! HASLSTAT */
+# endif
# ifndef HASNICE
# define HASNICE 1 /* has nice(2) call */
-# endif /* ! HASNICE */
+# endif
# ifndef HASRRESVPORT
# define HASRRESVPORT 1 /* has rrsevport(3) call */
-# endif /* ! HASRRESVPORT */
+# endif
/**********************************************************************
** "Hard" compilation options.
@@ -101,27 +101,27 @@
# define LDA_USE_LOCKF 1
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
-# endif /* ! HASGETUSERSHELL */
+# endif
# ifdef HPUX10
# define _PATH_SENDMAIL "/usr/sbin/sendmail"
# ifndef SMRSH_CMDDIR
# define SMRSH_CMDDIR "/var/adm/sm.bin"
-# endif /* ! SMRSH_CMDDIR */
-# endif /* HPUX10 */
+# endif
+# endif
# ifdef HPUX11
# define HASSETREUID 1 /* setreuid(2) works on HP-UX 11.x */
# define HASFCHOWN 1 /* has fchown(2) */
# ifndef BROKEN_RES_SEARCH
# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */
-# endif /* ! BROKEN_RES_SEARCH */
+# endif
# ifndef SMRSH_CMDDIR
# define SMRSH_CMDDIR "/var/adm/sm.bin"
-# endif /* ! SMRSH_CMDDIR */
+# endif
# define _PATH_SENDMAIL "/usr/sbin/sendmail"
# else /* HPUX11 */
# ifndef NOT_SENDMAIL
# define syslog hard_syslog
-# endif /* ! NOT_SENDMAIL */
+# endif
# endif /* HPUX11 */
# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */
@@ -130,28 +130,28 @@
# define _PATH_UNIX "/stand/vmunix"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# ifndef IDENTPROTO
# define IDENTPROTO 1 /* TCP/IP implementation fixed in 10.0 */
-# endif /* ! IDENTPROTO */
+# endif
# include <sys/mpctl.h> /* for mpctl() in get_num_procs_online() */
# else /* V4FS */
/* HP-UX 9.x */
# define _PATH_UNIX "/hp-ux"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# ifdef __STDC__
extern void hard_syslog(int, char *, ...);
-# else /* __STDC__ */
+# else
extern void hard_syslog();
-# endif /* __STDC__ */
+# endif
# define FDSET_CAST (int *) /* cast for fd_set parameters to select */
# endif /* V4FS */
@@ -169,7 +169,7 @@ extern void hard_syslog();
# define SOCKOPT_LEN_T socklen_t /* arg#5 to getsockopt */
# if _AIX5 >= 50200
# define HASUNSETENV 1 /* has unsetenv(3) call */
-# endif /* _AIX5 >= 50200 */
+# endif
# endif /* _AIX5 */
/*
@@ -183,12 +183,12 @@ extern void hard_syslog();
# define TZ_TYPE TZ_NAME /* use tzname[] vector */
# ifndef SOCKOPT_LEN_T
# define SOCKOPT_LEN_T size_t /* arg#5 to getsockopt */
-# endif /* SOCKOPT_LEN_T */
+# endif
# if _AIX4 >= 40200
# define HASSETREUID 1 /* setreuid(2) works as of AIX 4.2 */
# ifndef SOCKADDR_LEN_T
# define SOCKADDR_LEN_T size_t /* e.g., arg#3 to accept, getsockname */
-# endif /* SOCKADDR_LEN_T */
+# endif
# endif /* _AIX4 >= 40200 */
# if defined(_ILS_MACROS) /* IBM versions aren't side-effect clean */
# undef isascii
@@ -220,17 +220,17 @@ extern void hard_syslog();
# define SPT_PADCHAR '\0' /* pad process title with nulls */
# ifndef LA_TYPE
# define LA_TYPE LA_INT
-# endif /* LA_TYPE */
+# endif
# define FSHIFT 16
# define LA_AVENRUN "avenrun"
# if !defined(_AIX4) || _AIX4 < 40300
# ifndef __BIT_TYPES_DEFINED__
# define SM_INT32 int
-# endif /* __BIT_TYPES_DEFINED__ */
+# endif
# endif /* !defined(_AIX4) || _AIX4 < 40300 */
# if !defined(_AIX4) || _AIX4 < 40200
# define SM_CONF_SYSLOG 0
-# endif /* !defined(_AIX4) || _AIX4 < 40200 */
+# endif
# endif /* _AIX3 */
@@ -272,16 +272,16 @@ typedef int pid_t;
/* make this sendmail in a completely different place */
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/local/newmail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/local/newmail/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# endif /* AIX */
# if defined(_AIX)
# define LDA_USE_LOCKF 1
# define LDA_USE_SETEUID 1
-# endif /* defined(_AIX) */
+# endif
/*
** Silicon Graphics IRIX
@@ -310,7 +310,7 @@ typedef int pid_t;
# 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) */
+# endif
# ifdef IRIX6
# define STAT64 1
# define QUAD_T unsigned long long
@@ -360,7 +360,7 @@ typedef int pid_t;
# define SAFENFSPATHCONF 1 /* pathconf(2) pessimizes on NFS filesystems */
# ifndef HASFCHOWN
# define HASFCHOWN 1 /* fchown(2) */
-# endif /* ! HASFCHOWN */
+# endif
# ifdef __svr4__
# define LDA_USE_LOCKF 1
@@ -374,67 +374,67 @@ typedef int pid_t;
# if defined(NOT_SENDMAIL) && !defined(SOLARIS) && defined(sun) && (defined(__svr4__) || defined(__SVR4))
# define SOLARIS 1 /* unknown Solaris version */
-# endif /* defined(NOT_SENDMAIL) && !defined(SOLARIS) && defined(sun) && (defined(__svr4__) || defined(__SVR4)) */
+# endif
# ifdef SOLARIS
/* Solaris 2.x (a.k.a. SunOS 5.x) */
# ifndef __svr4__
# define __svr4__ /* use all System V Release 4 defines below */
-# endif /* ! __svr4__ */
+# endif
# if SOLARIS >= 21100
# include <paths.h>
-# endif /* SOLARIS >= 21100 */
+# endif
# ifndef _PATH_VARRUN
# define _PATH_VARRUN "/var/run/"
-# endif /* _PATH_VARRUN */
+# endif
# define GIDSET_T gid_t
# define USE_SA_SIGACTION 1 /* use sa_sigaction field */
# define BROKEN_PTHREAD_SLEEP 1 /* sleep after pthread_create() fails */
# define HASSTRERROR 1 /* has strerror(3) */
# ifndef _PATH_UNIX
# define _PATH_UNIX "/dev/ksyms"
-# endif /* ! _PATH_UNIX */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# ifndef _PATH_HOSTS
# define _PATH_HOSTS "/etc/inet/hosts"
-# endif /* ! _PATH_HOSTS */
+# endif
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
# ifndef TZ_TYPE
# define TZ_TYPE TZ_TZNAME
-# endif /* ! TZ_TYPE */
+# endif
# if SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203)
# define USESETEUID 1 /* seteuid works as of 2.3 */
# define LDA_CONTENTLENGTH 1 /* Needs the Content-Length header */
-# endif /* SOLARIS >= 20300 || (SOLARIS < 10000 && SOLARIS >= 203) */
+# endif
# if SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205)
# define HASSETREUID 1 /* setreuid works as of 2.5 */
# define HASSETREGID 1 /* use setregid(2) to set saved gid */
# if SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206)
# define HASSNPRINTF 1 /* has snprintf(3c) starting in 2.6 */
-# endif /* SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) */
+# endif
# if SOLARIS < 207 || (SOLARIS > 10000 && SOLARIS < 20700)
# ifndef LA_TYPE
# define LA_TYPE LA_KSTAT /* use kstat(3k) -- may work in < 2.5 */
-# endif /* ! LA_TYPE */
-# ifndef RANDOMSHIFT /* random() doesn't work well (sometimes) */
+# endif
+# ifndef RANDOMSHIFT /* random() doesn't work well (sometimes) */
# define RANDOMSHIFT 8
-# endif /* ! RANDOMSHIFT */
+# endif
# endif /* SOLARIS < 207 || (SOLARIS > 10000 && SOLARIS < 20700) */
# else /* SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205) */
# ifndef HASRANDOM
# define HASRANDOM 0 /* doesn't have random(3) */
-# endif /* ! HASRANDOM */
+# endif
# endif /* SOLARIS >= 20500 || (SOLARIS < 10000 && SOLARIS >= 205) */
# if (SOLARIS > 10000 && SOLARIS < 20600) || SOLARIS < 206
# define SM_INT32 int /* 32bit integer */
-# endif /* (SOLARIS > 10000 && SOLARIS < 20600) || SOLARIS < 206 */
+# endif
# if SOLARIS >= 20700 || (SOLARIS < 10000 && SOLARIS >= 207)
# ifndef LA_TYPE
# include <sys/loadavg.h>
@@ -452,7 +452,7 @@ typedef int pid_t;
# define _PATH_SENDMAILPID _PATH_VARRUN "sendmail.pid"
# ifndef SMRSH_CMDDIR
# define SMRSH_CMDDIR "/var/adm/sm.bin"
-# endif /* ! SMRSH_CMDDIR */
+# endif
# define SL_FUDGE 34 /* fudge offset for SyslogPrefixLen */
# define HASLDAPGETALIASBYNAME 1 /* added in S8 */
# endif /* SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) */
@@ -463,7 +463,7 @@ typedef int pid_t;
# endif /* SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209) */
# if SOLARIS >= 21000 || (SOLARIS < 10000 && SOLARIS >= 210)
# define HASUNSETENV 1 /* unsetenv() added in S10 */
-# endif /* SOLARIS >= 21000 || (SOLARIS < 10000 && SOLARIS >= 210) */
+# endif
# if SOLARIS >= 21100 || (SOLARIS < 10000 && SOLARIS >= 211)
# define GETLDAPALIASBYNAME_VERSION 2 /* changed in S11 */
# define HAVE_NANOSLEEP 1 /* moved from librt to libc in S11 */
@@ -472,10 +472,10 @@ typedef int pid_t;
# endif /* SOLARIS >= 21100 || (SOLARIS < 10000 && SOLARIS >= 211) */
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps pre-2.7 */
-# endif /* ! HASGETUSERSHELL */
+# endif
# if SOLARIS < 21200
# define SIGWAIT_TAKES_1_ARG 1 /* S12 moves to UNIX V7 semantic */
-# endif /* SOLARIS < 21200 */
+# endif
# else /* SOLARIS */
/* SunOS 4.0.3 or 4.1.x */
@@ -483,14 +483,14 @@ typedef int pid_t;
# define HASSETREUID 1 /* has setreuid(2) call */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone */
# include <memory.h>
# include <vfork.h>
# ifdef __GNUC__
# define strtoul strtol /* gcc library bogosity */
-# endif /* __GNUC__ */
+# endif
# define memmove(d, s, l) (bcopy((s), (d), (l)))
# define atexit(f) on_exit((f), 0) /* ugly hack for SunOS */
# define SM_INT32 int /* 32bit integer */
@@ -522,7 +522,7 @@ extern char *getenv();
# ifndef LA_TYPE
# define LA_TYPE LA_INT
-# endif /* ! LA_TYPE */
+# endif
# endif /* defined(sun) && !defined(BSD) */
@@ -536,7 +536,7 @@ extern char *getenv();
# ifdef DGUX_5_4_2
# define DGUX 1
-# endif /* DGUX_5_4_2 */
+# endif
# ifdef DGUX
# define SYSTEM5 1
@@ -549,7 +549,7 @@ extern char *getenv();
# define HASGETUSERSHELL 0 /* does not have getusershell(3) */
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# define SPT_TYPE SPT_NONE /* don't use setproctitle */
# define SFS_TYPE SFS_4ARGS /* four argument statfs() call */
# define LDA_USE_LOCKF 1
@@ -585,14 +585,14 @@ extern long dgux_inet_addr();
# define HASFCHOWN 1 /* has fchown(2) syscall */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
# ifndef BROKEN_RES_SEARCH
# define BROKEN_RES_SEARCH 1 /* res_search(unknown) returns h_errno=0 */
-# endif /* ! BROKEN_RES_SEARCH */
+# endif
# if !defined(NEEDLOCAL_HOSTNAME_LENGTH) && NAMED_BIND && __RES >= 19931104 && __RES < 19950621
# define NEEDLOCAL_HOSTNAME_LENGTH 1 /* see sendmail/README */
-# endif /* !defined(NEEDLOCAL_HOSTNAME_LENGTH) && NAMED_BIND && __RES >= 19931104 && __RES < 19950621 */
+# endif
# ifdef vax
# define LA_TYPE LA_FLOAT
# else /* vax */
@@ -602,7 +602,7 @@ extern long dgux_inet_addr();
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* pre-4.4 TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# define SYSLOG_BUFSIZE 256
# define SM_CONF_SYSLOG 0
# endif /* ultrix */
@@ -618,7 +618,7 @@ extern long dgux_inet_addr();
# define __osf__ 1 /* get OSF/1 defines below */
# ifndef TZ_TYPE
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
-# endif /* ! TZ_TYPE */
+# endif
# endif /* __ksr__ */
@@ -626,14 +626,14 @@ extern long dgux_inet_addr();
** OSF/1 for Intel Paragon.
**
** Contributed by Jeff A. Earickson <jeff@ssd.intel.com>
-** of Intel Scalable Systems Divison.
+** of Intel Scalable Systems Division.
*/
# ifdef __PARAGON__
# define __osf__ 1 /* get OSF/1 defines below */
# ifndef TZ_TYPE
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
-# endif /* ! TZ_TYPE */
+# endif
# define GIDSET_T gid_t
# define MAXNAMLEN NAME_MAX
# endif /* __PARAGON__ */
@@ -661,18 +661,18 @@ extern long dgux_inet_addr();
# include <standards.h>
# if _XOPEN_SOURCE+0 >= 400
# define HASFLOCK 0 /* 5.0 and later has bad flock(2) call */
-# else /* _XOPEN_SOURCE+0 >= 400 */
+# else
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* _XOPEN_SOURCE+0 >= 400 */
+# endif
# endif /* ! HASFLOCK */
# define LA_TYPE LA_ALPHAOSF
# define SFS_TYPE SFS_STATVFS /* use <sys/statvfs.h> statfs() impl */
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/var/adm/sendmail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# if _FFR_DIGUNIX_SAFECHOWN
/*
** Testing on a Digital UNIX 4.0a system showed this to be the correct
@@ -694,17 +694,17 @@ extern long dgux_inet_addr();
# define NEEDPUTENV 2 /* need putenv(3) call; no setenv(3) call */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# define UID_T int /* compiler gripes on uid_t */
# define GID_T int /* ditto for gid_t */
# define MODE_T int /* and mode_t */
# define setpgid setpgrp
# ifndef NOT_SENDMAIL
# define sleep sleepX
-# endif /* ! NOT_SENDMAIL */
+# endif
# ifndef LA_TYPE
# define LA_TYPE LA_MACH
-# endif /* ! LA_TYPE */
+# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# ifdef _POSIX_SOURCE
extern struct passwd *getpwent();
@@ -719,31 +719,31 @@ typedef int pid_t;
# endif /* _POSIX_SOURCE */
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/etc/sendmail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# define SM_INT32 int /* 32bit integer */
# ifdef TCPWRAPPERS
# ifndef HASUNSETENV
# define HASUNSETENV 1
-# endif /* ! HASUNSETENV */
+# endif
# undef NEEDPUTENV
# endif /* TCPWRAPPERS */
# ifndef __APPLE__
# include <libc.h>
# ifndef S_IRUSR
# define S_IRUSR S_IREAD
-# endif /* ! S_IRUSR */
+# endif
# ifndef S_IWUSR
# define S_IWUSR S_IWRITE
-# endif /* ! S_IWUSR */
+# endif
# define _PATH_MAILDIR "/usr/spool/mail"
# endif /* ! __APPLE__ */
# ifndef isascii
# define isascii(c) ((unsigned)(c) <= 0177)
-# endif /* ! isascii */
+# endif
# endif /* NeXT */
/*
@@ -774,6 +774,12 @@ typedef int pid_t;
# define HASURANDOMDEV 1 /* has urandom(4) */
# define HASSTRERROR 1 /* has strerror(3) */
# define HASGETUSERSHELL 1 /* had getusershell(3) */
+# if DARWIN >=180000
+# ifdef HASRRESVPORT
+# undef HASRRESVPORT
+# endif
+# define HASRRESVPORT 0 /* deprecated rresvport() */
+# endif
# define GIDSET_T gid_t /* getgroups(2) takes gid_t */
# define LA_TYPE LA_SUBR /* use getloadavg(3) */
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
@@ -820,7 +826,7 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define NETLINK 1 /* supports AF_LINK */
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
-# endif /* ! LA_TYPE */
+# endif
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# define SPT_TYPE SPT_PSSTRINGS /* use PS_STRINGS pointer */
# endif /* defined(BSD4_4) && !defined(__bsdi__) && !defined(__GNU__) && !defined(DARWIN)*/
@@ -849,7 +855,7 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define SFS_TYPE SFS_MOUNT /* use <sys/mount.h> statfs() impl */
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
-# endif /* ! LA_TYPE */
+# endif
# define GIDSET_T gid_t
# define QUAD_T quad_t
# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312
@@ -862,13 +868,13 @@ extern unsigned int sleepX __P((unsigned int seconds));
# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312 */
# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199701 /* on 3.x */
# define HASSETUSERCONTEXT 1 /* has setusercontext */
-# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199701 */
+# endif
# if defined(_BSDI_VERSION) && _BSDI_VERSION <= 199701 /* 3.1 and earlier */
# define MODE_T int /* va_arg() can't handle less than int */
-# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION <= 199701 */
+# endif
# if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199910 /* on 4.x */
# define HASURANDOMDEV 1 /* has /dev/urandom(4) */
-# endif /* defined(_BSDI_VERSION) && _BSDI_VERSION >= 199910 */
+# endif
# endif /* __bsdi__ */
@@ -963,7 +969,7 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define HASSNPRINTF 1 /* has snprintf(3) (all versions?) */
# ifndef LA_TYPE
# define LA_TYPE LA_SUBR
-# endif /* ! LA_TYPE */
+# endif
# if defined(__NetBSD__) && defined(__NetBSD_Version__) && \
((__NetBSD_Version__ >= 200040000 && __NetBSD_Version__ < 200090000) || \
(__NetBSD_Version__ >= 299000900))
@@ -975,10 +981,10 @@ extern unsigned int sleepX __P((unsigned int seconds));
# if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1)
# undef SPT_TYPE
# define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */
-# endif /* defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1) */
+# endif
# 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)) */
+# endif
# if defined(__NetBSD__) && defined(__NetBSD_Version__) && __NetBSD_Version__ >= 104170000
# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */
# endif
@@ -1002,10 +1008,10 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */
# ifndef SMRSH_CMDDIR
# define SMRSH_CMDDIR "/usr/libexec/sm.bin"
-# endif /* ! SMRSH_CMDDIR */
+# endif
# ifndef SMRSH_PATH
# define SMRSH_PATH "/bin:/usr/bin"
-# endif /* ! SMRSH_PATH */
+# endif
# define USESYSCTL 1 /* use sysctl(3) for getting ncpus */
# include <sys/sysctl.h>
# endif /* defined(__DragonFly__) */
@@ -1019,24 +1025,24 @@ extern unsigned int sleepX __P((unsigned int seconds));
# if __FreeBSD__ >= 2
# include <osreldate.h>
# if __FreeBSD_version >= 199512 /* 2.2-current when it appeared */
-# if __FreeBSD_version < 500012
-# include <libutil.h>
-# endif
+# if __FreeBSD_version < 500012 /* Moved to libc in 2000 */
+# include <libutil.h>
+# endif
# define SPT_TYPE SPT_BUILTIN
# endif /* __FreeBSD_version >= 199512 */
# if __FreeBSD_version >= 222000 /* 2.2.2-release and later */
# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */
-# endif /* __FreeBSD_version >= 222000 */
+# endif
# if __FreeBSD_version >= 300000 /* 3.0.0-release and later */
# define HAVE_NANOSLEEP 1 /* has nanosleep(2) */
-# endif /* __FreeBSD_version >= 300000 */
+# endif
# if __FreeBSD_version >= 330000 /* 3.3.0-release and later */
# ifndef SMRSH_CMDDIR
# define SMRSH_CMDDIR "/usr/libexec/sm.bin"
-# endif /* ! SMRSH_CMDDIR */
+# endif
# ifndef SMRSH_PATH
# define SMRSH_PATH "/bin:/usr/bin"
-# endif /* ! SMRSH_PATH */
+# endif
# endif /* __FreeBSD_version >= 330000 */
# if __FreeBSD_version >= 430000 /* 4.3.0-release and later */
# define SOCKADDR_LEN_T socklen_t /* e.g., arg#3 to accept, getsockname */
@@ -1048,7 +1054,7 @@ extern unsigned int sleepX __P((unsigned int seconds));
# ifndef SPT_TYPE
# define SPT_TYPE SPT_REUSEARGV
# define SPT_PADCHAR '\0' /* pad process title with nulls */
-# endif /* ! SPT_TYPE */
+# endif
# endif /* defined(__FreeBSD__) */
# if defined(__OpenBSD__)
# undef SPT_TYPE
@@ -1056,24 +1062,30 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define HASSETLOGIN 1 /* has setlogin(2) */
# if OpenBSD < 200305
# define HASSETREUID 0 /* setreuid(2) broken in OpenBSD < 3.3 */
-# endif /* OpenBSD < 200305 */
+# endif
# define HASSETEGID 1 /* use setegid(2) to set saved gid */
# define HASURANDOMDEV 1 /* has /dev/urandom(4) */
# if OpenBSD >= 200006
# define HASSRANDOMDEV 1 /* has srandomdev(3) */
-# endif /* OpenBSD >= 200006 */
+# endif
# if OpenBSD >= 200012
# define HASSETUSERCONTEXT 1 /* BSDI-style login classes */
-# endif /* OpenBSD >= 200012 */
+# endif
# if OpenBSD >= 200405
# define HASCLOSEFROM 1 /* closefrom(3) added in 3.5 */
-# endif /* OpenBSD >= 200405 */
+# endif
# if OpenBSD >= 200505
# undef NETISO /* iso.h removed in 3.7 */
-# endif /* OpenBSD >= 200505 */
+# endif
# if OpenBSD >= 200800
# define HAVE_NANOSLEEP 1 /* has nanosleep(2) */
-# endif /* OpenBSD >= 200800 */
+# endif
+# ifndef SOCKADDR_LEN_T
+# define SOCKADDR_LEN_T socklen_t /* e.g., arg#3 to accept, getsockname */
+# endif
+# ifndef SOCKOPT_LEN_T
+# define SOCKOPT_LEN_T socklen_t /* arg#5 to getsockopt */
+# endif
# endif /* defined(__OpenBSD__) */
# endif /* defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) */
@@ -1090,23 +1102,23 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define HASINITGROUPS 1 /* has initgroups(3) call */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# define SM_CONF_GETOPT 0 /* need a replacement for getopt(3) */
# define NEEDSTRTOL 1 /* need the strtol() function */
# define setpgid setpgrp
# ifndef LA_TYPE
# define LA_TYPE LA_FLOAT
-# endif /* ! LA_TYPE */
+# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# undef HASSETVBUF /* don't actually have setvbuf(3) */
# undef WEXITSTATUS
# undef WIFEXITED
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# endif /* defined(MACH) && defined(i386) && !defined(__GNU__) */
@@ -1162,13 +1174,13 @@ extern unsigned int sleepX __P((unsigned int seconds));
# define setpgid setpgrp
# ifndef LA_TYPE
# define LA_TYPE LA_FLOAT
-# endif /* ! LA_TYPE */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# undef WEXITSTATUS
# undef WIFEXITED
typedef short pid_t;
@@ -1207,7 +1219,7 @@ typedef short pid_t;
# define LDA_USE_LOCKF 1
# ifndef LA_TYPE
# define LA_TYPE LA_DEVSHORT
-# endif /* ! LA_TYPE */
+# endif
# define _PATH_AVENRUN "/dev/table/avenrun"
# ifndef _SCO_unix_4_2
# define _SCO_unix_4_2
@@ -1231,7 +1243,7 @@ typedef short pid_t;
# define NOFTRUNCATE 0 /* has (simulated) ftruncate call */
# ifndef USE_SIGLONGJMP
# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */
-# endif /* ! USE_SIGLONGJMP */
+# endif
# define MAXPATHLEN PATHSIZE
# define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */
# define SFS_BAVAIL f_bfree /* alternate field name */
@@ -1243,15 +1255,15 @@ typedef short pid_t;
# define _PATH_UNIX "/unix"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
/* stuff fixed in later releases */
# ifndef _SCO_unix_4_2
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
-# endif /* ! _SCO_unix_4_2 */
+# endif
# ifndef _SCO_DS
# define ftruncate chsize /* use chsize(2) to emulate ftruncate */
@@ -1285,10 +1297,10 @@ typedef short pid_t;
# define _PATH_UNIX "/unix"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# endif /* ISC_UNIX */
@@ -1364,7 +1376,7 @@ extern struct group *getgrnam();
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef S_IREAD
# define S_IREAD _S_IREAD
# define S_IWRITE _S_IWRITE
@@ -1375,22 +1387,22 @@ extern struct group *getgrnam();
# endif /* ! S_IREAD */
# ifndef TZ_TYPE
# define TZ_TYPE TZ_TIMEZONE
-# endif /* ! TZ_TYPE */
+# endif
# ifndef IDENTPROTO
# define IDENTPROTO 1
-# endif /* ! IDENTPROTO */
+# endif
# ifndef SHARE_V1
# define SHARE_V1 1 /* version 1 of the fair share scheduler */
-# endif /* ! SHARE_V1 */
+# endif
# if !defined(__GNUC__ )
-# define UID_T int /* GNUC gets it right, ConvexC botches */
-# define GID_T int /* GNUC gets it right, ConvexC botches */
-# endif /* !defined(__GNUC__ ) */
+# define UID_T int /* GNUC gets it right, ConvexC botches */
+# define GID_T int /* GNUC gets it right, ConvexC botches */
+# endif
# if SECUREWARE
# define FORK fork /* SecureWare wants the real fork! */
-# else /* SECUREWARE */
+# else
# define FORK vfork /* the rest of the OS versions don't care */
-# endif /* SECUREWARE */
+# endif
# endif /* _CONVEX_SOURCE */
@@ -1405,7 +1417,7 @@ extern struct group *getgrnam();
# define HASUNSETENV 1 /* has unsetenv(3) call */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# define WAITUNION 1 /* use "union wait" as wait argument type */
# define SM_CONF_GETOPT 0 /* need a replacement for getopt(3) */
# define NEEDPUTENV 1 /* need putenv(3) call */
@@ -1430,7 +1442,7 @@ extern void *malloc();
# ifdef RISCOS_4_0
# ifndef ARBPTR_T
# define ARBPTR_T char *
-# endif /* ! ARBPTR_T */
+# endif
# undef HASFLOCK
# define HASFLOCK 0
# endif /* RISCOS_4_0 */
@@ -1460,15 +1472,15 @@ extern void *malloc();
# include <linux/version.h>
# if !defined(KERNEL_VERSION) /* not defined in 2.0.x kernel series */
# define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
-# endif /* !defined(KERNEL_VERSION) */
+# endif
# define BSD 1 /* include BSD defines */
# define HASSETREGID 1 /* use setregid(2) to set saved gid */
# ifndef REQUIRES_DIR_FSYNC
# define REQUIRES_DIR_FSYNC 1 /* requires fsync() on directory */
-# endif /* REQUIRES_DIR_FSYNC */
+# endif
# ifndef USESETEUID
# define USESETEUID 0 /* has it due to POSIX, but doesn't work */
-# endif /* USESETEUID */
+# endif
# define SM_CONF_GETOPT 0 /* need a replacement for getopt(3) */
# define HASUNAME 1 /* use System V uname(2) system call */
# define HASUNSETENV 1 /* has unsetenv(3) call */
@@ -1476,51 +1488,60 @@ extern void *malloc();
# define GIDSET_T gid_t /* from <linux/types.h> */
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) broken in Slackware 2.0 */
-# endif /* HASGETUSERSHELL */
+# endif
# ifndef IP_SRCROUTE
# define IP_SRCROUTE 0 /* linux <= 1.2.8 doesn't support IP_OPTIONS */
-# endif /* ! IP_SRCROUTE */
+# endif
# ifndef HAS_IN_H
# define HAS_IN_H 1 /* use netinet/in.h */
-# endif /* ! HAS_IN_H */
+# endif
# ifndef USE_SIGLONGJMP
# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */
-# endif /* ! USE_SIGLONGJMP */
+# endif
# ifndef HASFLOCK
# if LINUX_VERSION_CODE < 66399
# define HASFLOCK 0 /* flock(2) is broken after 0.99.13 */
# else /* LINUX_VERSION_CODE < 66399 */
# 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)) */
+# else
# define HASFLOCK 0 /* flock(2) is broken (again) after 2.4.0 */
-# endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) */
+# endif
# endif /* LINUX_VERSION_CODE < 66399 */
# endif /* ! HASFLOCK */
# ifndef LA_TYPE
# define LA_TYPE LA_PROCSTR
-# endif /* ! LA_TYPE */
+# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() impl */
# define SPT_PADCHAR '\0' /* pad process title with nulls */
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0))
# ifndef HASURANDOMDEV
# define HASURANDOMDEV 1 /* 2.0 (at least) has linux/drivers/char/random.c */
-# endif /* ! HASURANDOMDEV */
+# endif
# endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0)) */
# if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
# define HASSTRERROR 1 /* has strerror(3) */
-# endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */
+# endif
# ifndef TZ_TYPE
# define TZ_TYPE TZ_NONE /* no standard for Linux */
-# endif /* ! TZ_TYPE */
+# endif
# if (__GLIBC__ >= 2)
# include <paths.h>
-# endif /* (__GLIBC__ >= 2) */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/var/run/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# include <sys/sysmacros.h>
# undef atol /* wounded in <stdlib.h> */
+
+# if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
+# define GLIBC_VERSION ((__GLIBC__ << 9) + __GLIBC_MINOR__)
+# if (GLIBC_VERSION >= 0x201)
+# define SOCKADDR_LEN_T socklen_t
+# define SOCKOPT_LEN_T socklen_t
+# endif
+# endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */
+
# if NETINET6
/*
** Linux doesn't have a good way to tell userland what interfaces are
@@ -1535,27 +1556,24 @@ extern void *malloc();
** in 2.1 and later, but the APIs appear before the functions.
*/
# if defined(__GLIBC__) && defined(__GLIBC_MINOR__)
-# define GLIBC_VERSION ((__GLIBC__ << 8) + __GLIBC_MINOR__)
# if (GLIBC_VERSION >= 0x201)
-# define SOCKADDR_LEN_T socklen_t
-# define SOCKOPT_LEN_T socklen_t
# undef IPPROTO_ICMPV6 /* linux #defines, glibc enums */
-# else /* (GLIBC_VERSION >= 0x201) */
+# else
# include <linux/in6.h> /* IPv6 support */
-# endif /* (GLIBC_VERSION >= 0x201) */
+# endif
# if (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE))
/* Have APIs in <netdb.h>, but no support in glibc */
# define NEEDSGETIPNODE 1
-# endif /* (GLIBC_VERSION >= 0x201 && !defined(NEEDSGETIPNODE)) */
+# endif
# undef GLIBC_VERSION
# endif /* defined(__GLIBC__) && defined(__GLIBC_MINOR__) */
# endif /* NETINET6 */
# ifndef HASFCHOWN
# define HASFCHOWN 1 /* fchown(2) */
-# endif /* ! HASFCHOWN */
+# endif
# if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,36)) && !defined(HASFCHMOD)
# define HASFCHMOD 1 /* fchmod(2) */
-# endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,36)) && !defined(HASFCHMOD) */
+# endif
# endif /* __linux__ */
@@ -1598,20 +1616,20 @@ extern void *malloc();
# define ERRLIST_PREDEFINED 1
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# ifndef LA_TYPE
# define LA_TYPE LA_INT
# define FSHIFT 16
-# endif /* ! LA_TYPE */
+# endif
# define LA_AVENRUN "avenrun"
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# define TZ_TYPE TZ_TZNAME
# ifndef _PATH_UNIX
# define _PATH_UNIX "/unix" /* should be in <paths.h> */
-# endif /* ! _PATH_UNIX */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# undef WIFEXITED
# undef WEXITSTATUS
# endif /* _AUX_SOURCE */
@@ -1672,7 +1690,7 @@ typedef int pid_t;
# define LA_TYPE LA_FLOAT
# ifdef _POSIX_VERSION
# undef _POSIX_VERSION /* set in <unistd.h> */
-# endif /* _POSIX_VERSION */
+# endif
# undef HASSETVBUF /* don't actually have setvbuf(3) */
# define setpgid setpgrp
@@ -1686,14 +1704,14 @@ typedef int pid_t;
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# ifndef _PATH_UNIX
# define _PATH_UNIX "/dynix"
-# endif /* ! _PATH_UNIX */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# endif /* sequent */
@@ -1720,20 +1738,20 @@ typedef int pid_t;
# define SPT_TYPE SPT_NONE /* don't use setproctitle */
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# endif /* _SEQUENT_ */
/*
** Cray UNICOS, UNICOS/mk, and UNICOS/mp
**
** UNICOS:
-** Ported by David L. Kensiski, Sterling Sofware <kensiski@nas.nasa.gov>
+** Ported by David L. Kensiski, Sterling Software <kensiski@nas.nasa.gov>
** Update Brian Ginsbach <ginsbach@cray.com>
** UNICOS/mk (Cray T3E):
** Contributed by Manu Mahonen <mailadm@csc.fi>
@@ -1764,23 +1782,23 @@ typedef int pid_t;
# define GET_IPOPT_DST(dst) *(struct in_addr *)&(dst)
# ifndef MAXPATHLEN
# define MAXPATHLEN PATHSIZE
-# endif /* ! MAXPATHLEN */
+# endif
# ifndef _PATH_UNIX
# ifdef UNICOSMK
# define _PATH_UNIX "/unicosmk.ar"
# else
# define _PATH_UNIX "/unicos"
-# endif /* UNICOSMK */
+# endif
# endif /* ! _PATH_UNIX */
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# 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) */
+# endif
# 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 */
@@ -1810,20 +1828,20 @@ typedef int pid_t;
# define TZ_TYPE TZ_TZNAME
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# undef S_IFSOCK /* S_IFSOCK and S_IFIFO are the same */
# undef S_IFIFO
# define S_IFIFO 0010000
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# define RLIMIT_NEEDS_SYS_TIME_H 1
# if defined(NGROUPS_MAX) && !NGROUPS_MAX
# undef NGROUPS_MAX
-# endif /* defined(NGROUPS_MAX) && !NGROUPS_MAX */
+# endif
# endif /* apollo */
/*
@@ -1844,17 +1862,17 @@ typedef int pid_t;
# define HASGETUSERSHELL 0 /* lacks getusershell() */
# ifdef HASNICE
# undef HASNICE
-# endif /* HASNICE */
+# endif
# define HASNICE 0 /* lacks nice() */
# define HASRANDOM 0 /* lacks random() */
# ifdef HASRRESVPORT
# undef HASRRESVPORT
-# endif /* HASRRESVPORT */
+# endif
# define HASRRESVPORT 0 /* lacks rresvport() */
# define IP_SRCROUTE 0 /* lacks IP source routing fields */
# ifdef MATCHGECOS
# undef MATCHGECOS
-# endif /* MATCHGECOS */
+# endif
# define MATCHGECOS 0 /* lacks an initialized GECOS field */
# define NEEDFSYNC 1 /* use sendmail's fsync() */
# define NEEDLINK 1 /* use sendmail's link() */
@@ -1914,21 +1932,21 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t));
# define SIGWAIT_TAKES_1_ARG 1
# ifndef _PATH_UNIX
# define _PATH_UNIX "/stand/unix"
-# endif /* ! _PATH_UNIX */
+# endif
# define SPT_PADCHAR '\0' /* pad process title with nulls */
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 1024 /* unsure */
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/etc/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# undef offsetof /* avoid stddefs.h, sys/sysmacros.h conflict */
#if !defined(SM_SET_H_ERRNO) && defined(_REENTRANT)
# define SM_SET_H_ERRNO(err) set_h_errno((err))
-#endif /* ! SM_SET_H_ERRNO && _REENTRANT */
+#endif
# endif /* __svr5__ */
/* ###################################################################### */
@@ -1965,13 +1983,13 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t));
# undef WEXITSTATUS
# ifndef _PATH_UNIX
# define _PATH_UNIX "/unix"
-# endif /* ! _PATH_UNIX */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# define SYSLOG_BUFSIZE 128
# endif /* UNIXWARE */
@@ -1986,7 +2004,7 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t));
# define SYSTEM5 1 /* looks like System V */
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
-# endif /* ! HASGETUSERSHELL */
+# endif
# define DEV_BSIZE 512 /* device block size not defined */
# define GIDSET_T gid_t
# undef LOG /* syslog not available */
@@ -2066,22 +2084,22 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t));
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# ifndef HASSETVBUF
# define HASSETVBUF /* HI-UX has no setlinebuf */
-# endif /* ! HASSETVBUF */
+# endif
# ifndef GIDSET_T
# define GIDSET_T gid_t
-# endif /* ! GIDSET_T */
+# endif
# ifndef _PATH_UNIX
# define _PATH_UNIX "/HI-UX"
-# endif /* ! _PATH_UNIX */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */
-# endif /* ! HASGETUSERSHELL */
+# endif
# define FDSET_CAST (int *) /* cast for fd_set parameters to select */
/*
@@ -2112,7 +2130,7 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t));
# define HASSETVBUF 1 /* has setvbuf(3) function */
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* does not have getusershell(3) function */
-# endif /* ! HASGETUSERSHELL */
+# endif
# define GIDSET_T gid_t /* type of 2nd arg to getgroups(2) isn't int */
# define LA_TYPE LA_ZERO /* doesn't have load average */
# define SFS_TYPE SFS_4ARGS /* use 4-arg statfs() */
@@ -2120,7 +2138,7 @@ extern struct passwd * sendmail_mpe_getpwuid __P((uid_t));
# define _PATH_UNIX "/unix"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/lib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# endif /* _UTS */
/*
@@ -2153,7 +2171,7 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid();
/* NEWS-OS 4.2.1R */
# ifndef BSD
# define BSD /* has BSD routines */
-# endif /* ! BSD */
+# endif
# define HASUNSETENV 1 /* has unsetenv(2) call */
# undef HASSETVBUF /* don't actually have setvbuf(3) */
# define WAITUNION 1 /* use "union wait" as wait argument type */
@@ -2161,7 +2179,7 @@ extern struct group *getgrent(), *getgrnam(), *getgrgid();
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# define setpgid setpgrp
# undef WIFEXITED
# undef WEXITSTATUS
@@ -2176,26 +2194,26 @@ typedef int (*sigfunc_t)();
/* NEWS-OS 6.0.3 with /bin/cc */
# ifndef __svr4__
# define __svr4__ /* use all System V Release 4 defines below */
-# endif /* ! __svr4__ */
+# endif
# 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
# define SPT_TYPE SPT_SYSMIPS /* use sysmips() (OS 6.0.2 or later) */
-# endif /* ! SPT_TYPE */
+# endif
# define GIDSET_T gid_t
# undef WIFEXITED
# undef WEXITSTATUS
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 256
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
# define _PATH_UNIX "/stand/unix"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# endif /* ! __svr4 */
# endif /* sony_news */
@@ -2210,7 +2228,7 @@ typedef int (*sigfunc_t)();
# ifdef luna
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# define HASUNSETENV 1 /* has unsetenv(2) call */
# define NEEDPUTENV 1 /* need putenv(3) call */
# define SM_CONF_GETOPT 0 /* need a replacement for getopt(3) */
@@ -2228,7 +2246,7 @@ typedef int (*sigfunc_t)();
# endif /* luna2 */
# ifdef luna88k
# define LA_TYPE LA_INT
-# endif /* luna88k */
+# endif
# define SFS_TYPE SFS_VFS /* use <sys/vfs.h> statfs() implementation */
# define setpgid setpgrp
# undef WIFEXITED
@@ -2254,7 +2272,7 @@ extern char *getenv();
# if defined(nec_ews_svr4) || defined(_nec_ews_svr4)
# ifndef __svr4__
# define __svr4__ /* use all System V Release 4 defines below */
-# endif /* ! __svr4__ */
+# endif
# define SYS5SIGNALS 1 /* SysV signal semantics -- reset on each sig */
# define HASSETSID 1 /* has POSIX setsid(2) call */
# define LA_TYPE LA_READKSYM /* use MIOC_READSYM ioctl */
@@ -2265,13 +2283,13 @@ extern char *getenv();
# define NAMELISTMASK 0x7fffffff /* mask for nlist() values */
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 1024 /* allow full size syslog buffer */
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
# endif /* defined(nec_ews_svr4) || defined(_nec_ews_svr4) */
@@ -2293,10 +2311,10 @@ extern char *getenv();
# define _PATH_UNIX "/stand/unix"
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# endif /* __uxp__ */
/*
@@ -2309,7 +2327,7 @@ extern char *getenv();
# define GIDSET_T gid_t
# ifndef IDENTPROTO
# define IDENTPROTO 0 /* TCP/IP implementation is broken */
-# endif /* ! IDENTPROTO */
+# endif
# endif /* DCOSx */
/*
@@ -2333,7 +2351,7 @@ extern char *getenv();
# define SFS_BAVAIL f_bavail
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 256 /* Use 256 bytes */
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
# undef WUNTRACED
# undef WIFEXITED
@@ -2354,13 +2372,13 @@ extern char *getenv();
# ifdef _PowerUX
# ifndef __svr4__
# define __svr4__
-# endif /* ! __svr4__ */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/etc/mail/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/etc/mail/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# define SYSLOG_BUFSIZE 1024
# define LA_TYPE LA_ZERO
typedef struct msgb mblk_t;
@@ -2421,10 +2439,10 @@ typedef struct msgb mblk_t;
# include <sys/mkdev.h>
# ifndef major
# define major(dev) ((int)(((dev) >> 8) & 0xff))
-# endif /* ! major */
+# endif
# ifndef minor
# define minor(dev) ((int)((dev) & 0xff))
-# endif /* ! minor */
+# endif
# endif /* defined(__INTERIX) */
@@ -2440,20 +2458,20 @@ typedef struct msgb mblk_t;
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
# ifndef HASSETREUID
# define HASSETREUID 1 /* has setreuid(2) call */
-# endif /* ! HASSETREUID */
+# endif
# define HASINITGROUPS 1 /* has initgroups(3) call */
# ifndef IP_SRCROUTE
# define IP_SRCROUTE 1 /* can check IP source routing */
-# endif /* ! IP_SRCROUTE */
+# endif
# ifndef HASSETRLIMIT
# define HASSETRLIMIT 1 /* has setrlimit(2) call */
-# endif /* ! HASSETRLIMIT */
+# endif
# ifndef HASFLOCK
# define HASFLOCK 1 /* has flock(2) call */
-# endif /* ! HASFLOCK */
+# endif
# ifndef TZ_TYPE
# define TZ_TYPE TZ_TM_ZONE /* use tm->tm_zone variable */
-# endif /* ! TZ_TYPE */
+# endif
# endif /* BSD */
/* general System V Release 4 defines */
@@ -2464,33 +2482,33 @@ typedef struct msgb mblk_t;
# define BSD_COMP 1 /* get BSD ioctl calls */
# ifndef HASSETRLIMIT
# define HASSETRLIMIT 1 /* has setrlimit(2) call */
-# endif /* ! HASSETRLIMIT */
+# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 0 /* does not have getusershell(3) call */
-# endif /* ! HASGETUSERSHELL */
+# endif
# ifndef HASFCHMOD
# define HASFCHMOD 1 /* most (all?) SVr4s seem to have fchmod(2) */
-# endif /* ! HASFCHMOD */
+# endif
# ifndef _PATH_UNIX
# define _PATH_UNIX "/unix"
-# endif /* ! _PATH_UNIX */
+# endif
# ifndef _PATH_VENDOR_CF
# define _PATH_VENDOR_CF "/usr/ucblib/sendmail.cf"
-# endif /* ! _PATH_VENDOR_CF */
+# endif
# ifndef _PATH_SENDMAILPID
# define _PATH_SENDMAILPID "/usr/ucblib/sendmail.pid"
-# endif /* ! _PATH_SENDMAILPID */
+# endif
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 128
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
# ifndef SFS_TYPE
# define SFS_TYPE SFS_STATVFS
-# endif /* ! SFS_TYPE */
+# endif
# ifndef USE_SIGLONGJMP
# define USE_SIGLONGJMP 1 /* sigsetjmp needed for signal handling */
-# endif /* ! USE_SIGLONGJMP */
+# endif
# endif /* __svr4__ */
# ifdef __SVR4
@@ -2507,20 +2525,20 @@ typedef struct msgb mblk_t;
# define HASSETVBUF 1 /* we have setvbuf(3) in libc */
# ifndef HASULIMIT
# define HASULIMIT 1 /* has the ulimit(2) syscall */
-# endif /* ! HASULIMIT */
+# endif
# ifndef LA_TYPE
# ifdef MIOC_READKSYM
# define LA_TYPE LA_READKSYM /* use MIOC_READKSYM ioctl */
-# else /* MIOC_READKSYM */
+# else
# define LA_TYPE LA_INT /* assume integer load average */
-# endif /* MIOC_READKSYM */
+# endif
# endif /* ! LA_TYPE */
# ifndef SFS_TYPE
# define SFS_TYPE SFS_USTAT /* use System V ustat(2) syscall */
-# endif /* ! SFS_TYPE */
+# endif
# ifndef TZ_TYPE
# define TZ_TYPE TZ_TZNAME /* use tzname[] vector */
-# endif /* ! TZ_TYPE */
+# endif
# endif /* SYSTEM5 */
/* general POSIX defines */
@@ -2538,15 +2556,15 @@ typedef struct msgb mblk_t;
# ifdef titan
# undef HASINITGROUPS /* doesn't have initgroups(3) call */
-# endif /* titan */
+# endif
# ifdef _CRAYCOM
# undef HASSETSID /* despite POSIX claim, doesn't have setsid */
-# endif /* _CRAYCOM */
+# endif
# ifdef MOTO
# undef USESETEUID
-# endif /* MOTO */
+# endif
/*
** Due to a "feature" in some operating systems such as Ultrix 4.3 and
@@ -2561,67 +2579,67 @@ typedef struct msgb mblk_t;
# ifndef IDENTPROTO
# define IDENTPROTO 1 /* use IDENT proto (RFC 1413) */
-# endif /* ! IDENTPROTO */
+# endif
# ifndef IP_SRCROUTE
# define IP_SRCROUTE 1 /* Detect IP source routing */
-# endif /* ! IP_SRCROUTE */
+# endif
# ifndef HASGETUSERSHELL
# define HASGETUSERSHELL 1 /* libc has getusershell(3) call */
-# endif /* ! HASGETUSERSHELL */
+# endif
# ifndef NETUNIX
# define NETUNIX 1 /* include unix domain support */
-# endif /* ! NETUNIX */
+# endif
# ifndef HASRANDOM
# define HASRANDOM 1 /* has random(3) support */
-# endif /* ! HASRANDOM */
+# endif
# ifndef HASFLOCK
# define HASFLOCK 0 /* assume no flock(2) support */
-# endif /* ! HASFLOCK */
+# endif
# ifndef HASSETREUID
# define HASSETREUID 0 /* assume no setreuid(2) call */
-# endif /* ! HASSETREUID */
+# endif
# ifndef HASFCHMOD
# define HASFCHMOD 0 /* assume no fchmod(2) syscall */
-# endif /* ! HASFCHMOD */
+# endif
# ifndef USESETEUID
# define USESETEUID 0 /* assume no seteuid(2) call or no saved ids */
-# endif /* ! USESETEUID */
+# endif
# ifndef HASSETRLIMIT
# define HASSETRLIMIT 0 /* assume no setrlimit(2) support */
-# endif /* ! HASSETRLIMIT */
+# endif
# ifndef HASULIMIT
# define HASULIMIT 0 /* assume no ulimit(2) support */
-# endif /* ! HASULIMIT */
+# endif
# ifndef SECUREWARE
# define SECUREWARE 0 /* assume no SecureWare C2 auditing hooks */
-# endif /* ! SECUREWARE */
+# endif
# ifndef USE_DOUBLE_FORK
# define USE_DOUBLE_FORK 1 /* avoid intermediate zombies */
-# endif /* ! USE_DOUBLE_FORK */
+# endif
# ifndef USE_ENVIRON
# define USE_ENVIRON 0 /* use main() envp instead of extern environ */
-# endif /* ! USE_ENVIRON */
+# endif
# ifndef USE_SIGLONGJMP
# define USE_SIGLONGJMP 0 /* assume setjmp handles signals properly */
-# endif /* ! USE_SIGLONGJMP */
+# endif
# ifndef FDSET_CAST
# define FDSET_CAST /* (empty) cast for fd_set arg to select */
-# endif /* ! FDSET_CAST */
+# endif
/*
** Pick a mailer setuid method for changing the current uid
@@ -2636,9 +2654,9 @@ typedef struct msgb mblk_t;
# else /* USESETEUID */
# if HASSETREUID
# define MAILER_SETUID_METHOD USE_SETREUID
-# else /* HASSETREUID */
+# else
# define MAILER_SETUID_METHOD USE_SETUID
-# endif /* HASSETREUID */
+# endif
# endif /* USESETEUID */
/*
@@ -2649,35 +2667,35 @@ typedef struct msgb mblk_t;
# ifndef GIDSET_T
# define GIDSET_T int
-# endif /* ! GIDSET_T */
+# endif
# ifndef UID_T
# define UID_T uid_t
-# endif /* ! UID_T */
+# endif
# ifndef GID_T
# define GID_T gid_t
-# endif /* ! GID_T */
+# endif
# ifndef MODE_T
# define MODE_T mode_t
-# endif /* ! MODE_T */
+# endif
# ifndef ARGV_T
# define ARGV_T char **
-# endif /* ! ARGV_T */
+# endif
# ifndef SOCKADDR_LEN_T
# define SOCKADDR_LEN_T int
-# endif /* ! SOCKADDR_LEN_T */
+# endif
# ifndef SOCKOPT_LEN_T
# define SOCKOPT_LEN_T int
-# endif /* ! SOCKOPT_LEN_T */
+# endif
# ifndef QUAD_T
# define QUAD_T unsigned long
-# endif /* ! QUAD_T */
+# endif
/**********************************************************************
** Remaining definitions should never have to be changed. They are
** primarily to provide back compatibility for older systems -- for
@@ -2687,43 +2705,43 @@ typedef struct msgb mblk_t;
/* System 5 compatibility */
# ifndef S_ISREG
# define S_ISREG(foo) ((foo & S_IFMT) == S_IFREG)
-# endif /* ! S_ISREG */
+# endif
# ifndef S_ISDIR
# define S_ISDIR(foo) ((foo & S_IFMT) == S_IFDIR)
-# endif /* ! S_ISDIR */
+# endif
# if !defined(S_ISLNK) && defined(S_IFLNK)
# define S_ISLNK(foo) ((foo & S_IFMT) == S_IFLNK)
-# endif /* !defined(S_ISLNK) && defined(S_IFLNK) */
+# endif
# if !defined(S_ISFIFO)
# if defined(S_IFIFO)
# define S_ISFIFO(foo) ((foo & S_IFMT) == S_IFIFO)
-# else /* defined(S_IFIFO) */
+# else
# define S_ISFIFO(foo) false
-# endif /* defined(S_IFIFO) */
+# endif
# endif /* !defined(S_ISFIFO) */
# ifndef S_IRUSR
# define S_IRUSR 0400
-# endif /* ! S_IRUSR */
+# endif
# ifndef S_IWUSR
# define S_IWUSR 0200
-# endif /* ! S_IWUSR */
+# endif
# ifndef S_IRGRP
# define S_IRGRP 0040
-# endif /* ! S_IRGRP */
+# endif
# ifndef S_IWGRP
# define S_IWGRP 0020
-# endif /* ! S_IWGRP */
+# endif
# ifndef S_IROTH
# define S_IROTH 0004
-# endif /* ! S_IROTH */
+# endif
# ifndef S_IWOTH
# define S_IWOTH 0002
-# endif /* ! S_IWOTH */
+# endif
/* close-on-exec flag */
# ifndef FD_CLOEXEC
# define FD_CLOEXEC 1
-# endif /* ! FD_CLOEXEC */
+# endif
/*
** Older systems don't have this error code -- it should be in
@@ -2732,7 +2750,7 @@ typedef struct msgb mblk_t;
# ifndef EX_CONFIG
# define EX_CONFIG 78 /* configuration error */
-# endif /* ! EX_CONFIG */
+# endif
/* pseudo-codes */
# define EX_QUIT 22 /* drop out of server immediately */
@@ -2741,7 +2759,7 @@ typedef struct msgb mblk_t;
#ifndef EX_NOTFOUND
# define EX_NOTFOUND EX_NOHOST
-#endif /* ! EX_NOTFOUND */
+#endif
/* pseudo-code used for mci_setstat */
# define EX_NOTSTICKY (-5) /* don't save persistent status */
@@ -2757,27 +2775,27 @@ typedef struct msgb mblk_t;
/* type of arbitrary pointer */
# ifndef ARBPTR_T
# define ARBPTR_T void *
-# endif /* ! ARBPTR_T */
+# endif
# ifndef __P
# include "sm/cdefs.h"
-# endif /* ! __P */
+# endif
# if HESIOD && !defined(NAMED_BIND)
# define NAMED_BIND 1 /* not one without the other */
-# endif /* HESIOD && !defined(NAMED_BIND) */
+# endif
# if NAMED_BIND && !defined( __ksr__ ) && !defined( h_errno )
extern int h_errno;
-# endif /* NAMED_BIND && !defined( __ksr__ ) && !defined( h_errno ) */
+# endif
# if NEEDPUTENV
extern int putenv __P((char *));
-# endif /* NEEDPUTENV */
+# endif
#if !HASUNSETENV
extern void unsetenv __P((char *));
-#endif /* !HASUNSETENV */
+#endif
# ifdef LDAPMAP
# include <sys/time.h>
@@ -2797,7 +2815,15 @@ extern void unsetenv __P((char *));
# if defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_INIT)
# define USE_LDAP_INIT 1
-# endif /* defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_INIT) */
+# endif
+
+# if !defined(LDAP_NETWORK_TIMEOUT) && defined(_FFR_LDAP_NETWORK_TIMEOUT)
+# define LDAP_NETWORK_TIMEOUT _FFR_LDAP_NETWORK_TIMEOUT
+# endif
+
+# if !defined(LDAP_NETWORK_TIMEOUT) && defined(LDAP_OPT_NETWORK_TIMEOUT)
+# define LDAP_NETWORK_TIMEOUT 1
+# endif
/*
** LDAP_OPT_SIZELIMIT is not defined under Umich 3.x nor OpenLDAP 1.x,
@@ -2806,7 +2832,7 @@ extern void unsetenv __P((char *));
# if defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_SET_OPTION)
# define USE_LDAP_SET_OPTION 1
-# endif /* defined(LDAP_OPT_SIZELIMIT) && !defined(USE_LDAP_SET_OPTION) */
+# endif
# endif /* LDAPMAP */
@@ -2814,7 +2840,7 @@ extern void unsetenv __P((char *));
# include <sys/utsname.h>
# ifdef newstr
# undef newstr
-# endif /* newstr */
+# endif
# else /* HASUNAME */
# define NODE_LENGTH 32
struct utsname
@@ -2825,10 +2851,10 @@ struct utsname
# if !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYSTEM_V)
# define MAXHOSTNAMELEN 256
-# endif /* !defined(MAXHOSTNAMELEN) && !defined(_SCO_unix_) && !defined(NonStop_UX_BXX) && !defined(ALTOS_SYSTEM_V) */
+# endif
-# if _FFR_LINUX_MHNL && defined(__linux__) && MAXHOSTNAMELEN < 255
+# if defined(__linux__) && MAXHOSTNAMELEN < 255
/*
** override Linux weirdness: a FQHN can be 255 chars long
** SUSv3 requires HOST_NAME_MAX ("Maximum length of a host
@@ -2839,23 +2865,23 @@ struct utsname
*/
# undef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 256
-# endif /* _FFR_LINUX_MHNL && defined(__linux__) && MAXHOSTNAMELEN < 255 */
+# endif /* defined(__linux__) && MAXHOSTNAMELEN < 255 */
# if !defined(SIGCHLD) && defined(SIGCLD)
# define SIGCHLD SIGCLD
-# endif /* !defined(SIGCHLD) && defined(SIGCLD) */
+# endif
# ifndef STDIN_FILENO
# define STDIN_FILENO 0
-# endif /* ! STDIN_FILENO */
+# endif
# ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
-# endif /* ! STDOUT_FILENO */
+# endif
# ifndef STDERR_FILENO
# define STDERR_FILENO 2
-# endif /* ! STDERR_FILENO */
+# endif
# ifndef LOCK_SH
# define LOCK_SH 0x01 /* shared lock */
@@ -2866,19 +2892,19 @@ struct utsname
# ifndef S_IXOTH
# define S_IXOTH (S_IEXEC >> 6)
-# endif /* ! S_IXOTH */
+# endif
# ifndef S_IXGRP
# define S_IXGRP (S_IEXEC >> 3)
-# endif /* ! S_IXGRP */
+# endif
# ifndef S_IXUSR
# define S_IXUSR (S_IEXEC)
-# endif /* ! S_IXUSR */
+# endif
#ifndef O_ACCMODE
# define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
-#endif /* ! O_ACCMODE */
+#endif
# ifndef SEEK_SET
# define SEEK_SET 0
@@ -2888,47 +2914,47 @@ struct utsname
# ifndef SIG_ERR
# define SIG_ERR ((void (*)()) -1)
-# endif /* ! SIG_ERR */
+# endif
# ifndef WEXITSTATUS
# define WEXITSTATUS(st) (((st) >> 8) & 0377)
-# endif /* ! WEXITSTATUS */
+# endif
# ifndef WIFEXITED
# define WIFEXITED(st) (((st) & 0377) == 0)
-# endif /* ! WIFEXITED */
+# endif
# ifndef WIFSTOPPED
# define WIFSTOPPED(st) (((st) & 0100) == 0)
-# endif /* ! WIFSTOPPED */
+# endif
# ifndef WCOREDUMP
# define WCOREDUMP(st) (((st) & 0200) != 0)
-# endif /* ! WCOREDUMP */
+# endif
# ifndef WTERMSIG
# define WTERMSIG(st) (((st) & 0177))
-# endif /* ! WTERMSIG */
+# endif
# ifndef SIGFUNC_DEFINED
typedef void (*sigfunc_t) __P((int));
-# endif /* ! SIGFUNC_DEFINED */
+# endif
# ifndef SIGFUNC_RETURN
# define SIGFUNC_RETURN
-# endif /* ! SIGFUNC_RETURN */
+# endif
# ifndef SIGFUNC_DECL
# define SIGFUNC_DECL void
-# endif /* ! SIGFUNC_DECL */
+# endif
/* size of syslog buffer */
# ifndef SYSLOG_BUFSIZE
# define SYSLOG_BUFSIZE 1024
-# endif /* ! SYSLOG_BUFSIZE */
+# endif
/* for FD_SET() */
#ifndef FD_SETSIZE
# define FD_SETSIZE 256
-#endif /* ! FD_SETSIZE */
+#endif
#ifndef SIGWAIT_TAKES_1_ARG
# define SIGWAIT_TAKES_1_ARG 0
-#endif /* ! SIGWAIT_TAKES_1_ARG */
+#endif
/*
** Size of prescan buffer.
@@ -2941,16 +2967,16 @@ typedef void (*sigfunc_t) __P((int));
/* fork routine -- set above using #ifdef _osname_ or in Makefile */
# ifndef FORK
# define FORK fork /* function to call to fork mailer */
-# endif /* ! FORK */
+# endif
/* setting h_errno */
# ifndef SM_SET_H_ERRNO
# define SM_SET_H_ERRNO(err) h_errno = (err)
-# endif /* SM_SET_H_ERRNO */
+# endif
# ifndef SM_CONF_GETOPT
# define SM_CONF_GETOPT 1
-# endif /* ! SM_CONF_GETOPT */
+# endif
/* random routine -- set above using #ifdef _osname_ or in Makefile */
# if HASRANDOM
@@ -2959,7 +2985,7 @@ typedef void (*sigfunc_t) __P((int));
# define get_random() ((long) rand())
# ifndef RANDOMSHIFT
# define RANDOMSHIFT 8
-# endif /* ! RANDOMSHIFT */
+# endif
# endif /* HASRANDOM */
/*
@@ -2968,17 +2994,17 @@ typedef void (*sigfunc_t) __P((int));
# ifndef SCANF
# define SCANF 1
-# endif /* ! SCANF */
+# endif
/* XXX 32 bit type */
# ifndef SM_INT32
# define SM_INT32 int32_t
-# endif /* ! SM_INT32 */
+# endif
/* XXX 16 bit type */
# ifndef SM_UINT16
# define SM_UINT16 uint16_t
-# endif /* ! SM_UINT16 */
+# endif
/* additional valid chars in user/group names in passwd */
# ifndef SM_PWN_CHARS
@@ -2994,21 +3020,21 @@ typedef void (*sigfunc_t) __P((int));
# if USE_SIGLONGJMP
# ifdef jmp_buf
# undef jmp_buf
-# endif /* jmp_buf */
+# endif
# define jmp_buf sigjmp_buf
# ifdef setjmp
# undef setjmp
-# endif /* setjmp */
+# endif
# define setjmp(env) sigsetjmp(env, 1)
# ifdef longjmp
# undef longjmp
-# endif /* longjmp */
+# endif
# define longjmp(env, val) siglongjmp(env, val)
# endif /* USE_SIGLONGJMP */
# if !defined(NGROUPS_MAX) && defined(NGROUPS)
# define NGROUPS_MAX NGROUPS /* POSIX naming convention */
-# endif /* !defined(NGROUPS_MAX) && defined(NGROUPS) */
+# endif
/*
** Some snprintf() implementations are rumored not to NUL terminate.
@@ -3016,11 +3042,11 @@ typedef void (*sigfunc_t) __P((int));
# if SNPRINTF_IS_BROKEN
# ifdef snprintf
# undef snprintf
-# endif /* snprintf */
+# endif
# define snprintf sm_snprintf
# ifdef vsnprintf
# undef vsnprintf
-# endif /* vsnprintf */
+# endif
# define vsnprintf sm_vsnprintf
# endif /* SNPRINTF_IS_BROKEN */
@@ -3041,14 +3067,14 @@ typedef void (*sigfunc_t) __P((int));
# ifndef SM_CONF_SYSLOG
# define SM_CONF_SYSLOG 1 /* syslog.h has prototype for syslog() */
-# endif /* SM_CONF_SYSLOG */
+# endif
# if !SM_CONF_SYSLOG
# ifdef __STDC__
extern void syslog(int, const char *, ...);
-# else /* __STDC__ */
+# else
extern void syslog();
-# endif /* __STDC__ */
+# endif
# endif /* !SM_CONF_SYSLOG */
/* portable(?) definition for alignment */
diff --git a/contrib/sendmail/include/sm/config.h b/contrib/sendmail/include/sm/config.h
index 451f1360612b..3eb5662d20aa 100644
--- a/contrib/sendmail/include/sm/config.h
+++ b/contrib/sendmail/include/sm/config.h
@@ -31,9 +31,9 @@
# ifndef SM_CONF_STDBOOL_H
# if !defined(__clang__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
# define SM_CONF_STDBOOL_H 1
-# else /* !defined(__clang__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L */
+# else
# define SM_CONF_STDBOOL_H 0
-# endif /* !defined(__clang__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L */
+# endif
# endif /* ! SM_CONF_STDBOOL_H */
/*
@@ -42,7 +42,7 @@
# ifndef SM_CONF_SYS_CDEFS_H
# define SM_CONF_SYS_CDEFS_H 0
-# endif /* ! SM_CONF_SYS_CDEFS_H */
+# endif
/*
** SM_CONF_STDDEF_H is 1 if <stddef.h> exists
@@ -50,7 +50,7 @@
# ifndef SM_CONF_STDDEF_H
# define SM_CONF_STDDEF_H 1
-# endif /* ! SM_CONF_STDDEF_H */
+# endif
/*
** Configuration macro that specifies whether strlcpy/strlcat are available.
@@ -60,7 +60,7 @@
# ifndef SM_CONF_STRL
# define SM_CONF_STRL 0
-# endif /* ! SM_CONF_STRL */
+# endif
/*
** Configuration macro indicating that setitimer is available
@@ -68,7 +68,7 @@
# ifndef SM_CONF_SETITIMER
# define SM_CONF_SETITIMER 1
-# endif /* ! SM_CONF_SETITIMER */
+# endif
/*
** Does <sys/types.h> define uid_t and gid_t?
@@ -76,14 +76,14 @@
# ifndef SM_CONF_UID_GID
# define SM_CONF_UID_GID 1
-# endif /* ! SM_CONF_UID_GID */
+# endif
/*
** Does <sys/types.h> define ssize_t?
*/
# ifndef SM_CONF_SSIZE_T
# define SM_CONF_SSIZE_T 1
-# endif /* ! SM_CONF_SSIZE_T */
+# endif
/*
** Does the C compiler support long long?
@@ -95,9 +95,9 @@
# else /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L */
# if defined(__GNUC__)
# define SM_CONF_LONGLONG 1
-# else /* defined(__GNUC__) */
+# else
# define SM_CONF_LONGLONG 0
-# endif /* defined(__GNUC__) */
+# endif
# endif /* defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L */
# endif /* ! SM_CONF_LONGLONG */
@@ -108,7 +108,7 @@
# ifndef SM_CONF_QUAD_T
# define SM_CONF_QUAD_T 0
-# endif /* ! SM_CONF_QUAD_T */
+# endif
/*
** Configuration macro indicating that shared memory is available
@@ -116,7 +116,7 @@
# ifndef SM_CONF_SHM
# define SM_CONF_SHM 0
-# endif /* ! SM_CONF_SHM */
+# endif
/*
** Does <setjmp.h> define sigsetjmp?
@@ -124,7 +124,7 @@
# ifndef SM_CONF_SIGSETJMP
# define SM_CONF_SIGSETJMP 1
-# endif /* ! SM_CONF_SIGSETJMP */
+# endif
/*
** Does <sysexits.h> exist, and define the EX_* macros with values
@@ -133,17 +133,17 @@
# ifndef SM_CONF_SYSEXITS_H
# define SM_CONF_SYSEXITS_H 0
-# endif /* ! SM_CONF_SYSEXITS_H */
+# endif
/* has memchr() prototype? (if not: needs memory.h) */
# ifndef SM_CONF_MEMCHR
# define SM_CONF_MEMCHR 1
-# endif /* ! SM_CONF_MEMCHR */
+# endif
/* try LLONG tests in libsm/t-types.c? */
# ifndef SM_CONF_TEST_LLONG
# define SM_CONF_TEST_LLONG 1
-# endif /* !SM_CONF_TEST_LLONG */
+# endif
/* LDAP Checks */
# if LDAPMAP
@@ -161,9 +161,9 @@
# if USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004
# define SM_CONF_LDAP_MEMFREE 1
-# else /* USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 */
+# else
# define SM_CONF_LDAP_MEMFREE 0
-# endif /* USING_NETSCAPE_LDAP || LDAP_API_VERSION >= 2004 */
+# endif
# endif /* ! SM_CONF_LDAP_MEMFREE */
/* Does the LDAP library have ldap_initialize()? */
@@ -177,13 +177,13 @@
/* OpenLDAP does it with LDAP_OPT_URI */
# ifdef LDAP_OPT_URI
# define SM_CONF_LDAP_INITIALIZE 1
-# endif /* LDAP_OPT_URI */
+# endif
# 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
#endif /* ! SM_CONFIG_H */
diff --git a/contrib/sendmail/include/sm/debug.h b/contrib/sendmail/include/sm/debug.h
index 9c7bb803d128..eb045c8ffed5 100644
--- a/contrib/sendmail/include/sm/debug.h
+++ b/contrib/sendmail/include/sm/debug.h
@@ -94,7 +94,7 @@ struct sm_debug
# ifndef SM_DEBUG_CHECK
# define SM_DEBUG_CHECK 1
-# endif /* ! SM_DEBUG_CHECK */
+# endif
# if SM_DEBUG_CHECK
/*
diff --git a/contrib/sendmail/include/sm/errstring.h b/contrib/sendmail/include/sm/errstring.h
index 14c100773202..16d0598a45e6 100644
--- a/contrib/sendmail/include/sm/errstring.h
+++ b/contrib/sendmail/include/sm/errstring.h
@@ -18,12 +18,12 @@
#if defined(__QNX__)
# define E_PSEUDOBASE 512
-#endif /* defined(__QNX__) */
+#endif
#include <errno.h>
#if NEEDINTERRNO
extern int errno;
-#endif /* NEEDINTERRNO */
+#endif
/*
** These are used in a few cases where we need some special
@@ -33,7 +33,7 @@ extern int errno;
#ifndef E_PSEUDOBASE
# define E_PSEUDOBASE 256
-#endif /* ! E_PSEUDOBASE */
+#endif
#define E_SM_OPENTIMEOUT (E_PSEUDOBASE + 0) /* Timeout on file open */
#define E_SM_NOSLINK (E_PSEUDOBASE + 1) /* Symbolic links not allowed */
@@ -88,7 +88,6 @@ extern int errno;
#define SMDBE_OLD_VERSION (E_SMDBBASE + 23)
#define SMDBE_VERSION_MISMATCH (E_SMDBBASE + 24)
-extern const char *sm_errstring __P((int _errno));
-
+extern const char *sm_errstring __P((int _errnum));
#endif /* SM_ERRSTRING_H */
diff --git a/contrib/sendmail/include/sm/gen.h b/contrib/sendmail/include/sm/gen.h
index 522892982e9e..a66bae54b46c 100644
--- a/contrib/sendmail/include/sm/gen.h
+++ b/contrib/sendmail/include/sm/gen.h
@@ -43,7 +43,7 @@
# else /* SM_CONF_STDDEF_H */
# ifndef NULL
# define NULL 0
-# endif /* ! NULL */
+# endif
# define offsetof(type, member) ((size_t)(&((type *)0)->member))
# endif /* SM_CONF_STDDEF_H */
diff --git a/contrib/sendmail/include/sm/heap.h b/contrib/sendmail/include/sm/heap.h
index 152e3672fcc4..369894e9cd15 100644
--- a/contrib/sendmail/include/sm/heap.h
+++ b/contrib/sendmail/include/sm/heap.h
@@ -25,7 +25,7 @@
/* change default to 0 for production? */
# ifndef SM_HEAP_CHECK
# define SM_HEAP_CHECK 1
-# endif /* ! SM_HEAP_CHECK */
+# endif
# if SM_HEAP_CHECK
# define sm_malloc_x(sz) sm_malloc_tagged_x(sz, __FILE__, __LINE__, SmHeapGroup)
diff --git a/contrib/sendmail/include/sm/io.h b/contrib/sendmail/include/sm/io.h
index 1eceffd22cfb..838af38e3cfa 100644
--- a/contrib/sendmail/include/sm/io.h
+++ b/contrib/sendmail/include/sm/io.h
@@ -53,7 +53,7 @@
#define SM_IO_WHAT_MODE 1
#define SM_IO_WHAT_VECTORS 2
#define SM_IO_WHAT_FD 3
-#define SM_IO_WHAT_TYPE 4
+/* was WHAT_TYPE 4 unused */
#define SM_IO_WHAT_ISTYPE 5
#define SM_IO_IS_READABLE 6
#define SM_IO_WHAT_TIMEOUT 7
@@ -342,7 +342,7 @@ __END_DECLS
__BEGIN_DECLS
int sm_rget __P((SM_FILE_T *, int));
int sm_vfscanf __P((SM_FILE_T *, int SM_NONVOLATILE, const char *,
- va_list SM_NONVOLATILE));
+ va_list));
int sm_wbuf __P((SM_FILE_T *, int, int));
__END_DECLS
@@ -383,7 +383,7 @@ __END_DECLS
# ifndef _POSIX_SOURCE
# define sm_io_getc(fp, t) sm_getc(fp, t)
# define sm_io_putc(fp, t, x) sm_putc(fp, t, x)
-# endif /* _POSIX_SOURCE */
+# endif
#endif /* lint */
#endif /* SM_IO_H */
diff --git a/contrib/sendmail/include/sm/ldap.h b/contrib/sendmail/include/sm/ldap.h
index 9ce5d234e70a..8fcd872d5f84 100644
--- a/contrib/sendmail/include/sm/ldap.h
+++ b/contrib/sendmail/include/sm/ldap.h
@@ -22,13 +22,13 @@
# ifndef LDAPMAP_MAX_ATTR
# define LDAPMAP_MAX_ATTR 64
-# endif /* ! LDAPMAP_MAX_ATTR */
+# endif
# ifndef LDAPMAP_MAX_FILTER
# define LDAPMAP_MAX_FILTER 1024
-# endif /* ! LDAPMAP_MAX_FILTER */
+# endif
# ifndef LDAPMAP_MAX_PASSWD
# define LDAPMAP_MAX_PASSWD 256
-# endif /* ! LDAPMAP_MAX_PASSWD */
+# endif
# if LDAPMAP
@@ -91,9 +91,12 @@ struct sm_ldap_struct
/* ldapmap_lookup options */
char ldap_attrsep;
-# if _FFR_LDAP_NETWORK_TIMEOUT
+# if LDAP_NETWORK_TIMEOUT
int ldap_networktmo;
-# endif /* _FFR_LDAP_NETWORK_TIMEOUT */
+# endif
+# if _FFR_SM_LDAP_DBG
+ int ldap_debug;
+# endif
/* Linked list of maps sharing the same LDAP binding */
void *ldap_next;
@@ -135,7 +138,7 @@ extern void sm_ldap_close __P((SM_LDAP_STRUCT *));
/* Portability defines */
# if !SM_CONF_LDAP_MEMFREE
# define ldap_memfree(x) ((void) 0)
-# endif /* !SM_CONF_LDAP_MEMFREE */
+# endif
# endif /* LDAPMAP */
#endif /* ! SM_LDAP_H */
diff --git a/contrib/sendmail/include/sm/limits.h b/contrib/sendmail/include/sm/limits.h
index 001f81e190a4..fdc36bf81a62 100644
--- a/contrib/sendmail/include/sm/limits.h
+++ b/contrib/sendmail/include/sm/limits.h
@@ -31,13 +31,13 @@
# ifndef LLONG_MIN
# define LLONG_MIN ((LONGLONG_T)(~(ULLONG_MAX >> 1)))
-# endif /* ! LLONG_MIN */
+# endif
# ifndef LLONG_MAX
# define LLONG_MAX ((LONGLONG_T)(ULLONG_MAX >> 1))
-# endif /* ! LLONG_MAX */
+# endif
# ifndef ULLONG_MAX
# define ULLONG_MAX ((ULONGLONG_T)(-1))
-# endif /* ! ULLONG_MAX */
+# endif
/*
** PATH_MAX is defined by the POSIX standard. All modern systems
@@ -47,9 +47,9 @@
# ifndef PATH_MAX
# ifdef MAXPATHLEN
# define PATH_MAX MAXPATHLEN
-# else /* MAXPATHLEN */
+# else
# define PATH_MAX 2048
-# endif /* MAXPATHLEN */
+# endif
# endif /* ! PATH_MAX */
#endif /* ! SM_LIMITS_H */
diff --git a/contrib/sendmail/include/sm/notify.h b/contrib/sendmail/include/sm/notify.h
new file mode 100644
index 000000000000..e5c193e09b37
--- /dev/null
+++ b/contrib/sendmail/include/sm/notify.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ */
+
+#ifndef SM_NOTIFY_H
+#define SM_NOTIFY_H
+
+int sm_notify_init __P((int));
+int sm_notify_start __P((bool, int));
+int sm_notify_stop __P((bool, int));
+int sm_notify_rcv __P((char *, size_t, int));
+int sm_notify_snd __P((char *, size_t));
+
+#endif /* ! SM_MSG_H */
diff --git a/contrib/sendmail/include/sm/os/sm_os_freebsd.h b/contrib/sendmail/include/sm/os/sm_os_freebsd.h
index e97f5eb257b8..7c52edfe029f 100644
--- a/contrib/sendmail/include/sm/os/sm_os_freebsd.h
+++ b/contrib/sendmail/include/sm/os/sm_os_freebsd.h
@@ -1,12 +1,10 @@
/*
- * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 2000-2001, 2018 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
- *
- * $Id: sm_os_freebsd.h,v 1.12 2013-11-22 20:51:34 ca Exp $
*/
/*
@@ -32,10 +30,14 @@
#ifndef SM_CONF_SHM
# define SM_CONF_SHM 1
-#endif /* SM_CONF_SHM */
+#endif
#ifndef SM_CONF_SEM
-# define SM_CONF_SEM 2
-#endif /* SM_CONF_SEM */
+# if __FreeBSD__ > 11
+# define SM_CONF_SEM 2 /* union semun is now longer available by default */
+# else
+# define SM_CONF_SEM 1
+# endif
+#endif
#ifndef SM_CONF_MSG
# define SM_CONF_MSG 1
-#endif /* SM_CONF_MSG */
+#endif
diff --git a/contrib/sendmail/include/sm/rpool.h b/contrib/sendmail/include/sm/rpool.h
index b01050de3a58..52f76771321a 100644
--- a/contrib/sendmail/include/sm/rpool.h
+++ b/contrib/sendmail/include/sm/rpool.h
@@ -123,7 +123,7 @@ typedef struct
#if _FFR_PERF_RPOOL
int sm_nbigblocks;
int sm_npools;
-#endif /* _FFR_PERF_RPOOL */
+#endif
} SM_RPOOL_T;
@@ -167,10 +167,10 @@ sm_rpool_malloc __P((
#if DO_NOT_USE_STRCPY
extern char *sm_rpool_strdup_x __P((SM_RPOOL_T *rpool, const char *s));
-#else /* DO_NOT_USE_STRCPY */
+#else
# define sm_rpool_strdup_x(rpool, str) \
strcpy(sm_rpool_malloc_x(rpool, strlen(str) + 1), str)
-#endif /* DO_NOT_USE_STRCPY */
+#endif
extern SM_RPOOL_ATTACH_T
sm_rpool_attach_x __P((
diff --git a/contrib/sendmail/include/sm/sem.h b/contrib/sendmail/include/sm/sem.h
index 556400c39ca4..f188a15deca3 100644
--- a/contrib/sendmail/include/sm/sem.h
+++ b/contrib/sendmail/include/sm/sem.h
@@ -35,10 +35,10 @@ union semun
# ifndef SEM_A
# define SEM_A 0200
-# endif /* SEM_A */
+# endif
# ifndef SEM_R
# define SEM_R 0400
-# endif /* SEM_R */
+# endif
# define SM_NSEM 1
diff --git a/contrib/sendmail/include/sm/shm.h b/contrib/sendmail/include/sm/shm.h
index 1a3b3b4f8bd1..f6c5ad56c1c9 100644
--- a/contrib/sendmail/include/sm/shm.h
+++ b/contrib/sendmail/include/sm/shm.h
@@ -34,10 +34,10 @@ extern int sm_shmsetowner __P((int, uid_t, gid_t, mode_t));
/* for those braindead systems... (e.g., SunOS 4) */
# ifndef SHM_R
# define SHM_R 0400
-# endif /* SHM_R */
+# endif
# ifndef SHM_W
# define SHM_W 0200
-# endif /* SHM_W */
+# endif
# endif /* SM_CONF_SHM */
#endif /* ! SM_SHM_H */
diff --git a/contrib/sendmail/include/sm/string.h b/contrib/sendmail/include/sm/string.h
index 4fd87afe6003..1f2b587cc642 100644
--- a/contrib/sendmail/include/sm/string.h
+++ b/contrib/sendmail/include/sm/string.h
@@ -30,7 +30,7 @@ extern bool
sm_match __P((const char *_str, const char *_pattern));
extern char *
-sm_strdup __P((char *));
+sm_strdup __P((const char *));
extern char *
sm_strndup_x __P((const char *_str, size_t _len));
@@ -87,7 +87,7 @@ sm_strlcpyn __P((char *,
# if !HASSTRERROR
extern char *
strerror __P((int _errno));
-# endif /* !HASSTRERROR */
+# endif
extern int
sm_strrevcmp __P((const char *, const char *));
@@ -109,5 +109,7 @@ sm_strtoull __P((const char *, char**, int));
extern void
stripquotes __P((char *));
+extern void
+unfoldstripquotes __P((char *));
#endif /* SM_STRING_H */
diff --git a/contrib/sendmail/include/sm/test.h b/contrib/sendmail/include/sm/test.h
index fdcce848b7e7..b9b77b678fe2 100644
--- a/contrib/sendmail/include/sm/test.h
+++ b/contrib/sendmail/include/sm/test.h
@@ -20,9 +20,9 @@
# if defined(__STDC__) || defined(__cplusplus)
# define SM_TEST(cond) sm_test(cond, #cond, __FILE__, __LINE__)
-# else /* defined(__STDC__) || defined(__cplusplus) */
+# else
# define SM_TEST(cond) sm_test(cond, "cond", __FILE__, __LINE__)
-# endif /* defined(__STDC__) || defined(__cplusplus) */
+# endif
extern int SmTestIndex;
extern int SmTestNumErrors;
diff --git a/contrib/sendmail/include/sm/types.h b/contrib/sendmail/include/sm/types.h
index 32c696fb837d..68998af82ddf 100644
--- a/contrib/sendmail/include/sm/types.h
+++ b/contrib/sendmail/include/sm/types.h
@@ -38,11 +38,11 @@
# if !SM_CONF_UID_GID
# define uid_t int
# define gid_t int
-# endif /* !SM_CONF_UID_GID */
+# endif
# if !SM_CONF_SSIZE_T
# define ssize_t int
-# endif /* !SM_CONF_SSIZE_T */
+# endif
/*
** Define LONGLONG_T and ULONGLONG_T, which are portable locutions
diff --git a/contrib/sendmail/include/sm/varargs.h b/contrib/sendmail/include/sm/varargs.h
index 612858da9c1f..2609630d919d 100644
--- a/contrib/sendmail/include/sm/varargs.h
+++ b/contrib/sendmail/include/sm/varargs.h
@@ -32,6 +32,11 @@
# define SM_VA_COPY(dst, src) __va_copy((dst), (src))
# else
# define SM_VA_COPY(dst, src) memcpy(&(dst), &(src), sizeof((dst)))
+# define SM_VA_END_COPY(ap) do { } while (0)
+# endif
+
+# ifndef SM_VA_END_COPY
+# define SM_VA_END_COPY(ap) va_end(ap)
# endif
/*
diff --git a/contrib/sendmail/include/sm/xtrap.h b/contrib/sendmail/include/sm/xtrap.h
index ed5de5348fe4..31ddd1d36982 100644
--- a/contrib/sendmail/include/sm/xtrap.h
+++ b/contrib/sendmail/include/sm/xtrap.h
@@ -25,9 +25,9 @@ extern SM_DEBUG_T SmXtrapReport;
# if SM_DEBUG_CHECK
# define sm_xtrap_check() (++SmXtrapCount == sm_debug_level(&SmXtrapDebug))
-# else /* SM_DEBUG_CHECK */
+# else
# define sm_xtrap_check() (0)
-# endif /* SM_DEBUG_CHECK */
+# endif
# define sm_xtrap_raise_x(exc) \
if (sm_xtrap_check()) \
diff --git a/contrib/sendmail/libmilter/Makefile b/contrib/sendmail/libmilter/Makefile
index 825ddd52d9d6..181c3b671b91 100644
--- a/contrib/sendmail/libmilter/Makefile
+++ b/contrib/sendmail/libmilter/Makefile
@@ -6,10 +6,10 @@ OPTIONS= $(CONFIG) $(FLAGS)
all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
-check: FRC
- $(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/libmilter/README b/contrib/sendmail/libmilter/README
index 64e1cca1cf7c..73953823b670 100644
--- a/contrib/sendmail/libmilter/README
+++ b/contrib/sendmail/libmilter/README
@@ -115,7 +115,7 @@ T=C:5m;S:10s;R:10s;E:5m
where 's' is seconds and 'm' is minutes.
-Which filters are invoked and their sequencing is handled by the
+Which filters are invoked and their sequencing is handled by the
InputMailFilters option. Note: if InputMailFilters is not defined no filters
will be used.
@@ -207,28 +207,19 @@ libmilter requires pthread support in the operating system. Moreover, it
requires that the library functions it uses are thread safe; which is true
for the operating systems libmilter has been developed and tested on. On
some operating systems this requires special compile time options (e.g.,
-not just -pthread). libmilter is currently known to work on (modulo problems
-in the pthread support of some specific versions):
-
-FreeBSD 3.x, 4.x
-SunOS 5.x (x >= 5)
-AIX 4.3.x
-HP UX 11.x
-Linux (recent versions/distributions)
-
-libmilter is currently not supported on:
+not just -pthread).
+So far, libmilter is not supported on:
IRIX 6.x
Ultrix
Feedback about problems (and possible fixes) is welcome.
+
+--------------------------+
| SOURCE FOR SAMPLE FILTER |
+--------------------------+
Note that the filter example.c may not be thread safe on some operating
systems. You should check your system man pages for the functions used
-below to verify the functions are thread safe.
-
-$Revision: 8.42 $, Last updated $Date: 2006-06-29 17:10:16 $
+to verify they are thread safe.
diff --git a/contrib/sendmail/libmilter/comm.c b/contrib/sendmail/libmilter/comm.c
index a551a5253fd8..05dfdb61457c 100644
--- a/contrib/sendmail/libmilter/comm.c
+++ b/contrib/sendmail/libmilter/comm.c
@@ -139,9 +139,9 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name)
}
#if _FFR_ADD_NULL
buf = malloc(expl + 1);
-#else /* _FFR_ADD_NULL */
+#else
buf = malloc(expl);
-#endif /* _FFR_ADD_NULL */
+#endif
if (buf == NULL)
{
*cmd = SMFIC_MALLOC;
@@ -194,7 +194,7 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name)
#if _FFR_ADD_NULL
/* makes life simpler for common string routines */
buf[expl] = '\0';
-#endif /* _FFR_ADD_NULL */
+#endif
return buf;
}
i += len;
diff --git a/contrib/sendmail/libmilter/docs/api.html b/contrib/sendmail/libmilter/docs/api.html
index b314a0f4e96d..4a90e9a432e6 100644
--- a/contrib/sendmail/libmilter/docs/api.html
+++ b/contrib/sendmail/libmilter/docs/api.html
@@ -15,7 +15,7 @@ $Id: api.html,v 1.39 2013-11-22 20:51:39 ca Exp $
<LI><A HREF="#Miscellaneous">Miscellaneous</A>
</UL>
-<H2><A NAME="LibraryControlFunctions">Library Control Functions</A></H2>
+<H2><A NAME="LibraryControlFunctions">Library Control Functions</A></H2>
Before handing control to libmilter (by calling
<A HREF="smfi_main.html">smfi_main</A>), a filter may call the following
@@ -23,11 +23,12 @@ functions to set libmilter parameters.
In particular, the filter must call
<A HREF="smfi_register.html">smfi_register</A> to register its callbacks.
Each function will return either MI_SUCCESS or MI_FAILURE to
-indicate the status of the operation.
+indicate the status of the operation.
<P>
-None of these functions communicate with the MTA. All alter the
-library's state, some of which is communicated to the MTA inside
+None of these functions communicate with the MTA.
+All alter the library's state, some of which
+is communicated to the MTA inside
<A HREF="smfi_main.html">smfi_main</A>.
<P>
@@ -54,7 +55,7 @@ library's state, some of which is communicated to the MTA inside
<H2><A NAME="DataAccessFunctions">Data Access Functions</A></H2>
The following functions may be called from within the filter-defined callbacks
-to access information about the current connection or message.
+to access information about the current connection or message.
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR bgcolor="#dddddd"><TH>Function</TH><TH>Description</TH></TR>
<TR><TD><A HREF="smfi_getsymval.html">smfi_getsymval</A></TD><TD>Return the value
@@ -80,33 +81,38 @@ The following functions change a message's contents and attributes.
<EM>They may only be called in <A HREF="xxfi_eom.html">xxfi_eom</A></EM>.
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. Message data (senders, recipients, headers, body chunks)
+the operation.
+Message data (senders, recipients, headers, body chunks)
passed to these functions via parameters is copied and does not need to be
preserved (i.e., allocated memory can be freed).
<P>
-A filter must have set the appropriate flag (listed below) in the
-description passed to <A HREF="smfi_register.html">smfi_register</A>
-to call any message modification function. Failure to do so will
-cause the MTA to treat a call to the function as a failure of the
-filter, terminating its connection.
+A filter which might call a message modification function
+must set the appropriate flag
+(<A HREF="#SMFIF">listed below</A>),
+either
+in the description passed to <A HREF="smfi_register.html">smfi_register</A>
+or via <A HREF="xxfi_negotiate.html">xxfi_negotiate</A>.
+Failure to do so will cause the MTA to treat a call to the function
+as a failure of the filter, terminating its connection.
<P>
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. For example,
+the MTA performed the requested operation.
+For example,
<A HREF="smfi_addheader.html">smfi_addheader</A>, when called with an
illegal header name, will return MI_SUCCESS even though the MTA may
later refuse to add the illegal header.
<P>
-<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH><TH>SMFIF_* flag</TR>
+<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH><TH><A NAME="SMFIF">SMFIF_* flag</A></TH></TR>
<TR><TD><A HREF="smfi_addheader.html">smfi_addheader</A></TD><TD>Add a header to
-the message.</TD><TD>SMFIF_ADDHDRS</TD></TR>
+the message.</TD><TD>SMFIF_ADDHDRS</TD></TR>
-<TR><TD><A HREF="smfi_chgheader.html">smfi_chgheader</A></TD><TD>Change or delete a header.</TD><TD>SMFIF_CHGHDRS</TD></TR>
+<TR><TD><A HREF="smfi_chgheader.html">smfi_chgheader</A></TD><TD>Change or delete a header.</TD><TD>SMFIF_CHGHDRS</TD></TR>
<TR><TD><A HREF="smfi_insheader.html">smfi_insheader</A></TD><TD>Insert a
-header into the message.</TD><TD>SMFIF_ADDHDRS</TD></TR>
+header into the message.</TD><TD>SMFIF_ADDHDRS</TD></TR>
<TR><TD><A HREF="smfi_chgfrom.html">smfi_chgfrom</A></TD><TD>Change the
envelope sender address.</TD><TD>SMFIF_CHGFROM</TD></TR>
@@ -180,40 +186,43 @@ which are registered via <A HREF="smfi_register.html">smfi_register</A>:
<TR><TD><A HREF="xxfi_close.html">xxfi_close</A></TD><TD>connection cleanup</TD></TR>
-<TR><TD><A HREF="xxfi_negotiate.html">xxfi_negotiate</A></TD><TD>option negotiattion</TD></TR>
+<TR><TD><A HREF="xxfi_negotiate.html">xxfi_negotiate</A></TD><TD>option negotiation</TD></TR>
</TABLE>
<P>
The above callbacks should all return one of the following return values,
-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.
+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.
<P><A NAME="conn-spec">Milter</A> 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
-callbacks, an entire connection (during which multiple messages may be
-delivered to multiple sets of recipients).
+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 callbacks, an entire connection
+(during which multiple messages may be delivered
+to multiple sets of recipients).
<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A> is recipient-oriented.
+<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>,
<A HREF="xxfi_connect.html">xxfi_connect</A>,
<A HREF="xxfi_helo.html">xxfi_helo</A> and
-<A HREF="xxfi_close.html">xxfi_close</A> are connection-oriented. All
-other callbacks are message-oriented.
+<A HREF="xxfi_close.html">xxfi_close</A> are connection-oriented.
+All other callbacks are message-oriented.
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2>
<TR BGCOLOR="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR VALIGN="TOP">
- <TD>SMFIS_CONTINUE</TD>
+ <TD>SMFIS_CONTINUE</TD>
<TD>Continue processing the current connection, message, or recipient.
</TD>
</TR>
<TR VALIGN="TOP">
<TD>SMFIS_REJECT</TD>
<TD>For a connection-oriented routine, reject this connection; call <A HREF="xxfi_close.html">xxfi_close</A>.<BR>
- For a message-oriented routine (except
+ For a message-oriented routine (except
<A HREF="xxfi_abort.html">xxfi_abort</A>), reject this message.<BR>
For a recipient-oriented routine, reject the current recipient (but continue processing the current message).
</TD>
@@ -233,8 +242,8 @@ other callbacks are message-oriented.
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Return a temporary failure, i.e., the corresponding SMTP command will return an appropriate 4xx status code.
- For a message-oriented routine (except <A HREF="xxfi_envfrom.html">xxfi_envfrom</A>), fail for this message. <BR>
- For a connection-oriented routine, fail for this connection; call <A HREF="xxfi_close.html">xxfi_close</A>. <BR>
+ For a message-oriented routine (except <A HREF="xxfi_envfrom.html">xxfi_envfrom</A>), fail for this message.<BR>
+ For a connection-oriented routine, fail for this connection; call <A HREF="xxfi_close.html">xxfi_close</A>.<BR>
For a recipient-oriented routine, only fail for the current recipient; continue message processing.
</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/design.html b/contrib/sendmail/libmilter/docs/design.html
index 294f9a153d08..3636fc8158f5 100644
--- a/contrib/sendmail/libmilter/docs/design.html
+++ b/contrib/sendmail/libmilter/docs/design.html
@@ -31,11 +31,15 @@ administrator to combine multiple independently-developed filters.
<P>
We expect to see both vendor-supplied, configurable mail filtering
applications and a multiplicity of script-like filters designed by and
-for MTA administrators. A certain degree of coding sophistication and
-domain knowledge on the part of the filter provider is assumed. This
-allows filters to exercise fine-grained control at the SMTP level.
+for MTA administrators.
+A certain degree of coding sophistication and
+domain knowledge on the part of the filter provider is assumed.
+This allows filters to exercise fine-grained control at the SMTP level.
However, as will be seen in the example, many filtering applications
-can be written with relatively little protocol knowledge.
+can be written with relatively little protocol knowledge,
+but a basic understanding (e.g., as documented in RFC 5321:
+<EM>The dialog is purposely lock-step, one-at-a-time</EM>)
+is necessary.
<P>
Given these expectations, the API is designed to achieve the following
diff --git a/contrib/sendmail/libmilter/docs/index.html b/contrib/sendmail/libmilter/docs/index.html
index 57d9ebc6d74d..90df444f6265 100644
--- a/contrib/sendmail/libmilter/docs/index.html
+++ b/contrib/sendmail/libmilter/docs/index.html
@@ -10,7 +10,7 @@ $Id: index.html,v 1.14 2013-11-22 20:51:39 ca Exp $
<H1>Filtering Mail with Sendmail</H1>
<!--
-<P><B>Disclaimer</B>:
+<P><B>Disclaimer</B>:
This preliminary API description is provided for review only. This
specification may change based on feedback from reviewers, and does
not bind Sendmail to offer this functionality in any release.
diff --git a/contrib/sendmail/libmilter/docs/installation.html b/contrib/sendmail/libmilter/docs/installation.html
index 91fe0d818a3f..7405afd7f014 100644
--- a/contrib/sendmail/libmilter/docs/installation.html
+++ b/contrib/sendmail/libmilter/docs/installation.html
@@ -17,7 +17,7 @@ $Id: installation.html,v 1.24 2013-11-22 20:51:39 ca Exp $
To compile a filter, modify the Makefile provided with the sample program, or:
<UL>
<LI>Put the include and Sendmail directories in your include path
- (e.g. -I/path/to/include -I/path/to/sendmail).
+ (e.g. -I/path/to/include -I/path/to/sendmail).
<LI>Make sure libmilter.a is in your library path, and link your
application with it (e.g. "-lmilter").
@@ -71,7 +71,7 @@ connection.
The MTA will try to contact the filter again on each new connection.
<P>
-There are three fields inside of the <CODE>T=</CODE> equate: S, R, and E.
+There are four fields inside of the <CODE>T=</CODE> equate: C, S, R, and E.
Note the separator between each is a ";" (semicolon), as ","
(comma) already separates equates.
The value of each field is a decimal number followed by a single letter
diff --git a/contrib/sendmail/libmilter/docs/overview.html b/contrib/sendmail/libmilter/docs/overview.html
index 78676d377a11..b88e45136965 100644
--- a/contrib/sendmail/libmilter/docs/overview.html
+++ b/contrib/sendmail/libmilter/docs/overview.html
@@ -60,6 +60,8 @@ returns to <CODE>MESSAGE</CODE>.
For each of N connections
{
For each filter
+ egotiate MTA/milter capabilities/requirements (<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>)
+ For each filter
process connection (<A HREF="xxfi_connect.html">xxfi_connect</A>)
For each filter
process helo/ehlo (<A HREF="xxfi_helo.html">xxfi_helo</A>)
@@ -203,11 +205,21 @@ communication with the MTA happens.
Filters are not terminated asynchronously
(except by signals that can't be caught).
In the case of <TT>Abort</TT> the
-<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked.
+<A HREF="xxfi_abort.html">xxfi_abort</A> callback is usually invoked
+if there is an active transaction.
+However, if an invoked callback takes too long to execute
+(the maximum time <TT>Abort</TT> waits is currently 5s)
+<!-- XREF: MI_CHK_TIME -->
+then the filter is simply terminated, i.e.,
+neither the
+<A HREF="xxfi_abort.html">xxfi_abort</A> callback
+nor the
+<A HREF="xxfi_close.html">xxfi_close</A> callback
+is invoked.
<HR size="1">
<FONT size="-1">
-Copyright (c) 2000, 2001, 2003, 2006 Proofpoint, Inc. and its suppliers.
+Copyright (c) 2000, 2001, 2003, 2006, 2018 Proofpoint, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
diff --git a/contrib/sendmail/libmilter/docs/sample.html b/contrib/sendmail/libmilter/docs/sample.html
index de8d58947a39..b470ae390eee 100644
--- a/contrib/sendmail/libmilter/docs/sample.html
+++ b/contrib/sendmail/libmilter/docs/sample.html
@@ -187,7 +187,7 @@ sfsistat
++argc;
/* log this recipient */
- if (reject != NULL && rcptaddr != NULL &&
+ if (reject != NULL &amp;&amp; rcptaddr != NULL &amp;&amp;
(strcasecmp(rcptaddr, reject) == 0))
{
if (fprintf(priv-&gt;mlfi_fp, "RCPT %s -- REJECTED\n",
@@ -298,7 +298,7 @@ mlfi_cleanup(ctx, ok)
return rstat;
/* close the archive file */
- if (priv-&gt;mlfi_fp != NULL && fclose(priv-&gt;mlfi_fp) == EOF)
+ if (priv-&gt;mlfi_fp != NULL &amp;&amp; fclose(priv-&gt;mlfi_fp) == EOF)
{
/* failed; we have to wait until later */
fprintf(stderr, "Couldn't close archive file %s: %s\n",
diff --git a/contrib/sendmail/libmilter/docs/smfi_addheader.html b/contrib/sendmail/libmilter/docs/smfi_addheader.html
index e58c8d713c60..fff4dc7fe6fe 100644
--- a/contrib/sendmail/libmilter/docs/smfi_addheader.html
+++ b/contrib/sendmail/libmilter/docs/smfi_addheader.html
@@ -32,6 +32,7 @@ Add a header to the current message.
<TD>Adds a header to the current message.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -45,21 +46,21 @@ Add a header to the current message.
</TD></TR>
<TR valign="top"><TD>headerv</TD>
<TD>The header value to be added, a non-NULL, null-terminated string.
- This may be the empty string.
+ This may be the empty string.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_addheader returns MI_FAILURE if:
<UL><LI>headerf or headerv is NULL.
<LI>Adding headers in the current connection state is invalid.
<LI>Memory allocation fails.
<LI>A network error occurs.
- <LI>SMFIF_ADDHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_ADDHDRS">SMFIF_ADDHDRS</A> is not set.
</UL>
Otherwise, it returns MI_SUCCESS.
</TD>
@@ -67,14 +68,13 @@ Otherwise, it returns MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
<UL><LI>smfi_addheader does not change a message's existing headers.
To change a header's current value, use
<A HREF="smfi_chgheader.html">smfi_chgheader</A>.
- <LI>A filter which calls smfi_addheader must have set the SMFIF_ADDHDRS
- flag in the smfiDesc_str passed to
- <A href="smfi_register.html">smfi_register</A>.
+ <LI>A filter which calls smfi_addheader must have set the
+ <A HREF="smfi_register.html#SMFIF_ADDHDRS">SMFIF_ADDHDRS</A> flag.
<LI>For smfi_addheader, filter order is important.
<B>Later filters will see the header changes made by earlier ones.</B>
<LI>Neither the name nor the value of the header is checked for
@@ -101,7 +101,7 @@ To change a header's current value, use
<!----------- Example code ---------->
<TR>
-<TH valign="top" align=left>EXAMPLE</TH>
+<TH valign="top" align=left>EXAMPLE</TH>
<TD>
<PRE>
diff --git a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html
index 42014bf1d821..81eecaf0069e 100644
--- a/contrib/sendmail/libmilter/docs/smfi_addrcpt.html
+++ b/contrib/sendmail/libmilter/docs/smfi_addrcpt.html
@@ -31,6 +31,7 @@ Add a recipient for the current message.
<TD>Add a recipient to the message envelope.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -47,13 +48,13 @@ Add a recipient for the current message.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_addrcpt will fail and return MI_FAILURE if:
<UL><LI>rcpt is NULL.
<LI>Adding recipients in the current connection state is invalid.
<LI>A network error occurs.
- <LI>SMFIF_ADDRCPT was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_ADDRCPT">SMFIF_ADDRCPT</A> is not set.
</UL>
Otherwise, it will return MI_SUCCESS.
</TD>
@@ -61,11 +62,10 @@ Otherwise, it will return MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
-A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT flag
-in the smfiDesc_str passed to
-<A href="smfi_register.html">smfi_register</A>.
+A filter which calls smfi_addrcpt must have set the
+<A HREF="smfi_register.html#SMFIF_ADDRCPT">SMFIF_ADDRCPT</A> flag.
</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html b/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html
index 0176e69e0617..9d72cd6ca82b 100644
--- a/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html
+++ b/contrib/sendmail/libmilter/docs/smfi_addrcpt_par.html
@@ -32,6 +32,7 @@ Add a recipient for the current message including ESMTP arguments.
<TD>Add a recipient to the message envelope.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -51,14 +52,13 @@ Add a recipient for the current message including ESMTP arguments.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
-<TD>smfi_addrcpt will fail and return MI_FAILURE if:
+<TD>smfi_addrcpt_par will fail and return MI_FAILURE if:
<UL><LI>rcpt is NULL.
<LI>Adding recipients in the current connection state is invalid.
<LI>A network error occurs.
- <LI>SMFIF_ADDRCPT_PAR was not set when
- <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_ADDRCPT_PAR">SMFIF_ADDRCPT_PAR</A> is not set._PAR
</UL>
Otherwise, it will return MI_SUCCESS.
</TD>
@@ -66,11 +66,10 @@ Otherwise, it will return MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
-A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT_PAR flag
-in the smfiDesc_str passed to
-<A href="smfi_register.html">smfi_register</A>.
+A filter which calls smfi_addrcpt_par must have set the
+<A HREF="smfi_register.html#SMFIF_ADDRCPT_PAR">SMFIF_ADDRCPT_PAR</A> flag.
</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/smfi_chgfrom.html b/contrib/sendmail/libmilter/docs/smfi_chgfrom.html
index a107ee9ebebc..0cfe7b6fc800 100644
--- a/contrib/sendmail/libmilter/docs/smfi_chgfrom.html
+++ b/contrib/sendmail/libmilter/docs/smfi_chgfrom.html
@@ -32,6 +32,7 @@ Change the envelope sender (MAIL From) of the current message.
<TD>Change the envelope sender (MAIL From) of the current message.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -51,13 +52,13 @@ Change the envelope sender (MAIL From) of the current message.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_chgfrom will fail and return MI_FAILURE if:
<UL><LI>mail is NULL.
<LI>Changing the sender in the current connection state is invalid.
<LI>A network error occurs.
- <LI>SMFIF_CHGFROM was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_CHGFROM">SMFIF_CHGFROM</A> is not set.
</UL>
Otherwise, it will return MI_SUCCESS.
</TD>
@@ -65,11 +66,10 @@ Otherwise, it will return MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
-A filter which calls smfi_chgfrom must have set the SMFIF_CHGFROM flag
-in the smfiDesc_str passed to
-<A href="smfi_register.html">smfi_register</A>.
+A filter which calls smfi_chgfrom must have set the
+<A HREF="smfi_register.html#SMFIF_CHGFROM">SMFIF_CHGFROM</A> flag.
<BR>
Even though all ESMTP arguments could be set via this call,
it does not make sense to do so for many of them,
diff --git a/contrib/sendmail/libmilter/docs/smfi_chgheader.html b/contrib/sendmail/libmilter/docs/smfi_chgheader.html
index b3004032e4b8..de132f442b5b 100644
--- a/contrib/sendmail/libmilter/docs/smfi_chgheader.html
+++ b/contrib/sendmail/libmilter/docs/smfi_chgheader.html
@@ -33,6 +33,7 @@ Change or delete a message header.
<TD>Changes a header's value for the current message.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -55,7 +56,7 @@ Change or delete a message header.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>
smfi_chgheader will return MI_FAILURE if
@@ -63,17 +64,18 @@ smfi_chgheader will return MI_FAILURE if
<LI>Modifying headers in the current connection state is invalid.
<LI>Memory allocation fails.
<LI>A network error occurs.
- <LI>SMFIF_CHGHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_CHGHDRS">SMFIF_CHGHDRS</A> is not set.
</UL>
Otherwise, it returns MI_SUCCESS.
-</TR>
+</TD></TR>
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
<UL><LI>While smfi_chgheader may be used to add new headers, it is more efficient and far safer to use <A href="smfi_addheader.html">smfi_addheader</A>.
- <LI>A filter which calls smfi_chgheader must have set the SMFIF_CHGHDRS flag in the smfiDesc_str passed to <A href="smfi_register.html">smfi_register</A>.
+ <LI>A filter which calls smfi_chgheader must have set the
+ <A HREF="smfi_register.html#SMFIF_CHGHDRS">SMFIF_CHGHDRS</A> flag.
<LI>For smfi_chgheader, filter order is important. <B>Later filters will see the header changes made by earlier ones.</B>
<LI>Neither the name nor the value of the header is checked for
standards compliance. However, each line of the header must be under
diff --git a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html
index ec1412bd3778..bd42a7319e56 100644
--- a/contrib/sendmail/libmilter/docs/smfi_delrcpt.html
+++ b/contrib/sendmail/libmilter/docs/smfi_delrcpt.html
@@ -31,6 +31,7 @@ Remove a recipient from the current message's envelope.
<TD>smfi_delrcpt removes the named recipient from the current message's envelope.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -47,14 +48,14 @@ Remove a recipient from the current message's envelope.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_delrcpt will fail and return MI_FAILURE if:
<UL>
<LI>rcpt is NULL.
<LI>Deleting recipients in the current connection state is invalid.
<LI>A network error occurs.
- <LI>SMFIF_DELRCPT was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_DELRCPT">SMFIF_DELRCPT</A> is not set.
</UL>
Otherwise, it will return MI_SUCCESS
</TD>
@@ -62,9 +63,13 @@ Otherwise, it will return MI_SUCCESS
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
+<LI>
The addresses to be removed must match exactly. For example, an address and its expanded form do not match.
+<LI>
+A filter which calls smfi_delrcpt must have set the
+<A HREF="smfi_register.html#SMFIF_DELRCPT">SMFIF_DELRCPT</A> flag.
</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/smfi_getpriv.html b/contrib/sendmail/libmilter/docs/smfi_getpriv.html
index 783d6402ef45..5ed8a22c2c60 100644
--- a/contrib/sendmail/libmilter/docs/smfi_getpriv.html
+++ b/contrib/sendmail/libmilter/docs/smfi_getpriv.html
@@ -30,6 +30,7 @@ Get the connection-specific data pointer for this connection.
<TD>None.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -43,7 +44,7 @@ Get the connection-specific data pointer for this connection.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_getpriv returns the private data pointer stored by a prior call to <A href="smfi_setpriv.html">smfi_setpriv</A>, or NULL if none has been set.</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/smfi_getsymval.html b/contrib/sendmail/libmilter/docs/smfi_getsymval.html
index dff8dc638c84..7e3e4d559434 100644
--- a/contrib/sendmail/libmilter/docs/smfi_getsymval.html
+++ b/contrib/sendmail/libmilter/docs/smfi_getsymval.html
@@ -31,6 +31,7 @@ Get the value of a sendmail macro.
<TD>None.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -51,14 +52,14 @@ Get the value of a sendmail macro.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_getsymval returns the value of the given macro as a null-terminated string, or NULL if the macro is not defined.</TD>
</TR>
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH><A name="notes">NOTES</A></TH>
+<TH><A name="notes">NOTES</A></TH>
<TD>
By default, the following macros are valid in the given contexts:
diff --git a/contrib/sendmail/libmilter/docs/smfi_insheader.html b/contrib/sendmail/libmilter/docs/smfi_insheader.html
index 3f568864835c..7759dc90c1a5 100644
--- a/contrib/sendmail/libmilter/docs/smfi_insheader.html
+++ b/contrib/sendmail/libmilter/docs/smfi_insheader.html
@@ -33,6 +33,7 @@ Prepend a header to the current message.
<TD>Prepends a header to the current message.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -49,21 +50,21 @@ Prepend a header to the current message.
<TD>The header name, a non-NULL, null-terminated string.
</TD></TR>
<TR valign="top"><TD>headerv</TD>
- <TD>The header value to be added, a non-NULL, null-terminated string. This may be the empty string.
+ <TD>The header value to be added, a non-NULL, null-terminated string. This may be the empty string.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_insheader returns MI_FAILURE if:
<UL><LI>headerf or headerv is NULL.
<LI>Adding headers in the current connection state is invalid.
<LI>Memory allocation fails.
<LI>A network error occurs.
- <LI>SMFIF_ADDHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_ADDHDRS">SMFIF_ADDHDRS</A> is not set.
</UL>
Otherwise, it returns MI_SUCCESS.
</TD>
@@ -71,15 +72,15 @@ Otherwise, it returns MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
<UL>
<LI>smfi_insheader does not change a message's existing headers.
To change a header's current value, use
<A HREF="smfi_chgheader.html">smfi_chgheader</A>.
- <LI>A filter which calls smfi_insheader must have set the SMFIF_ADDHDRS
- flag in the smfiDesc_str passed to
- <A href="smfi_register.html">smfi_register</A>.
+ <LI>A filter which calls smfi_insheader must have set the
+ <A HREF="smfi_register.html#SMFIF_ADDHDRS">SMFIF_ADDHDRS</A>
+ flag.
<LI>For smfi_insheader, filter order is important.
<B>Later filters will see the header changes made by earlier ones.</B>
<LI>A filter will receive <EM>only</EM> headers that have been sent
@@ -122,7 +123,7 @@ Otherwise, it returns MI_SUCCESS.
<!----------- Example code ---------->
<TR>
-<TH valign="top" align=left>EXAMPLE</TH>
+<TH valign="top" align=left>EXAMPLE</TH>
<TD>
<PRE>
diff --git a/contrib/sendmail/libmilter/docs/smfi_main.html b/contrib/sendmail/libmilter/docs/smfi_main.html
index cb63f96bc5d0..87228fc166d0 100644
--- a/contrib/sendmail/libmilter/docs/smfi_main.html
+++ b/contrib/sendmail/libmilter/docs/smfi_main.html
@@ -29,10 +29,11 @@ Hand control to libmilter event loop.
<TD>smfi_main hands control to the Milter event loop.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_main will return MI_FAILURE if it fails to establish a connection. This may occur for any of a variety of reasons (e.g. invalid address passed to <A href="smfi_setconn.html">smfi_setconn</A>). The reason for the failure will be logged. Otherwise, smfi_main will return MI_SUCCESS.</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/smfi_opensocket.html b/contrib/sendmail/libmilter/docs/smfi_opensocket.html
index d4f7e3a705ed..7b9e49df97af 100644
--- a/contrib/sendmail/libmilter/docs/smfi_opensocket.html
+++ b/contrib/sendmail/libmilter/docs/smfi_opensocket.html
@@ -34,13 +34,14 @@ but before calling <TT>smfi_main()</TT>.
<TD>smfi_opensocket attempts to create the socket specified previously by
a call to <TT>smfi_setconn()</TT> which will be the interface between MTAs
and the filter.
-This allows the calling application to ensure that the
-socket can be created.
+This allows the calling application to ensure that the socket can be created.
If this is not called,
-<TT>smfi_main()</TT> will do so implicitly.
+<TT>smfi_main()</TT> will create the socket implicitly
+(without removing a potentially existing UNIX domain socket).
</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -56,7 +57,7 @@ If this is not called,
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_opensocket will fail and return MI_FAILURE if:
<UL>
diff --git a/contrib/sendmail/libmilter/docs/smfi_progress.html b/contrib/sendmail/libmilter/docs/smfi_progress.html
index 2b87b012422f..53205ad5dc31 100644
--- a/contrib/sendmail/libmilter/docs/smfi_progress.html
+++ b/contrib/sendmail/libmilter/docs/smfi_progress.html
@@ -31,6 +31,7 @@ Notify the MTA that an operation is still in progress.
on a message, causing the MTA to re-start its timeouts.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -44,7 +45,7 @@ on a message, causing the MTA to re-start its timeouts.</TD>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_progress will fail and return MI_FAILURE if:
<UL>
diff --git a/contrib/sendmail/libmilter/docs/smfi_quarantine.html b/contrib/sendmail/libmilter/docs/smfi_quarantine.html
index b63da2d6c50f..6c954c44036e 100644
--- a/contrib/sendmail/libmilter/docs/smfi_quarantine.html
+++ b/contrib/sendmail/libmilter/docs/smfi_quarantine.html
@@ -31,6 +31,7 @@ Quarantine the message using the given reason.
<TD>smfi_quarantine quarantines the message using the given reason.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -47,13 +48,13 @@ Quarantine the message using the given reason.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_quarantine will fail and return MI_FAILURE if:
<UL>
<LI>reason is NULL or empty.
<LI>A network error occurs.
- <LI>SMFIF_QUARANTINE was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_QUARANTINE">SMFIF_QUARANTINE</A> is not set.
</UL>
Otherwise, it will return MI_SUCCESS
</TD>
diff --git a/contrib/sendmail/libmilter/docs/smfi_register.html b/contrib/sendmail/libmilter/docs/smfi_register.html
index 30ab75cae497..5c61beefc1a5 100644
--- a/contrib/sendmail/libmilter/docs/smfi_register.html
+++ b/contrib/sendmail/libmilter/docs/smfi_register.html
@@ -37,6 +37,7 @@ is obeyed.
</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -96,12 +97,12 @@ simply returning SMFIS_CONTINUE.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>
smfi_register may return MI_FAILURE for any of the following reasons:
<UL>
-<LI>memory allocation failed.
+<LI>memory allocation failed.
<LI>incompatible version or illegal flags value.
</UL>
@@ -110,7 +111,7 @@ smfi_register may return MI_FAILURE for any of the following reasons:
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH><A NAME=Notes>NOTES</A></TH>
<TD>
<A NAME="flags">The xxfi_flags</A>
@@ -120,7 +121,7 @@ the following values, describing the actions the filter may take:
<TR valign="top" bgcolor="#dddddd"><TH align="left">Flag</TH><TH align="center">Description</TH></TR>
<TR align="left" valign=top>
<TD>
- SMFIF_ADDHDRS
+ <A NAME="SMFIF_ADDHDRS">SMFIF_ADDHDRS</A>
</TD>
<TD>
This filter may <A HREF="smfi_addheader.html">add headers</A>.
@@ -128,7 +129,7 @@ the following values, describing the actions the filter may take:
</TR>
<TR align="left" valign=top>
<TD>
- SMFIF_CHGHDRS
+ <A NAME="SMFIF_CHGHDRS">SMFIF_CHGHDRS</A>
</TD>
<TD>
This filter may
@@ -137,7 +138,7 @@ the following values, describing the actions the filter may take:
</TR>
<TR align="left" valign=top>
<TD VALIGN="TOP">
- SMFIF_CHGBODY
+ <A NAME="SMFIF_CHGBODY">SMFIF_CHGBODY</A>
</TD>
<TD>
This filter may
@@ -148,7 +149,7 @@ the following values, describing the actions the filter may take:
</TR>
<TR>
<TD VALIGN="TOP">
- SMFIF_ADDRCPT
+ <A NAME="SMFIF_ADDRCPT">SMFIF_ADDRCPT</A>
</TD>
<TD>
This filter may
@@ -158,7 +159,7 @@ the following values, describing the actions the filter may take:
</TR>
<TR>
<TD VALIGN="TOP">
- SMFIF_ADDRCPT_PAR
+ <A NAME="SMFIF_ADDRCPT_PAR">SMFIF_ADDRCPT_PAR</A>
</TD>
<TD>
This filter may
@@ -167,7 +168,7 @@ the following values, describing the actions the filter may take:
</TR>
<TR>
<TD VALIGN="TOP">
- SMFIF_DELRCPT
+ <A NAME="SMFIF_DELRCPT">SMFIF_DELRCPT</A>
</TD>
<TD>
This filter may
@@ -176,7 +177,7 @@ the following values, describing the actions the filter may take:
</TR>
<TR>
<TD VALIGN="TOP">
- SMFIF_QUARANTINE
+ <A NAME="SMFIF_QUARANTINE">SMFIF_QUARANTINE</A>
</TD>
<TD>
This filter may
@@ -186,7 +187,7 @@ the following values, describing the actions the filter may take:
<TR>
<TD VALIGN="TOP">
- SMFIF_CHGFROM
+ <A NAME="SMFIF_CHGFROM">SMFIF_CHGFROM</A>
</TD>
<TD>
This filter may
@@ -196,7 +197,7 @@ the following values, describing the actions the filter may take:
<TR>
<TD VALIGN="TOP">
- SMFIF_SETSYMLIST
+ <A NAME="SMFIF_SETSYMLIST">SMFIF_SETSYMLIST</A>
</TD>
<TD>
This filter can
diff --git a/contrib/sendmail/libmilter/docs/smfi_replacebody.html b/contrib/sendmail/libmilter/docs/smfi_replacebody.html
index 4a5117964a33..0842298bc62c 100644
--- a/contrib/sendmail/libmilter/docs/smfi_replacebody.html
+++ b/contrib/sendmail/libmilter/docs/smfi_replacebody.html
@@ -29,12 +29,13 @@ Replace message-body data.
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
-<TD>smfi_replacebody replaces the body of the current message. If called
-more than once, subsequent calls result in data being appended to the new
+<TD>smfi_replacebody replaces the body of the current message. If called
+more than once, subsequent calls result in data being appended to the new
body.
</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -54,14 +55,14 @@ body.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_replacebody fails and returns MI_FAILURE if:
<UL>
<LI>bodyp == NULL and bodylen &gt; 0.
<LI>Changing the body in the current connection state is invalid.
<LI>A network error occurs.
- <LI>SMFIF_CHGBODY was not set when <A href="smfi_register.html">smfi_register</A> was called.
+ <LI><A HREF="smfi_register.html#SMFIF_CHGBODY">SMFIF_CHGBODY</A> is not set.
</UL>
Otherwise, it will return MI_SUCCESS.
</TD>
@@ -69,12 +70,14 @@ Otherwise, it will return MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
<UL>
- <LI>Since the message body may be very large, setting SMFIF_CHGBODY may significantly affect filter performance.
+ <LI>Since the message body may be very large, calling smfi_replacebody may significantly affect filter performance.
<LI>If a filter sets SMFIF_CHGBODY but does not call smfi_replacebody, the original body remains unchanged.
<LI>For smfi_replacebody, filter order is important. <B>Later filters will see the new body contents created by earlier ones.</B>
+ <LI>A filter which calls smfi_replacebody must have set the
+ <A HREF="smfi_register.html#SMFIF_CHGBODY">SMFIF_CHGBODY</A> flag.
</UL>
</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/smfi_setbacklog.html b/contrib/sendmail/libmilter/docs/smfi_setbacklog.html
index 961285555442..f025009db7ed 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setbacklog.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setbacklog.html
@@ -31,6 +31,7 @@ Set the filter's <CODE>listen(2)</CODE> backlog value.
If smfi_setbacklog is not called, the operating system default is used.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -44,7 +45,7 @@ If smfi_setbacklog is not called, the operating system default is used.</TD>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_setbacklog returns MI_FAILURE if obacklog is less than or equal
to zero.</TD>
diff --git a/contrib/sendmail/libmilter/docs/smfi_setconn.html b/contrib/sendmail/libmilter/docs/smfi_setconn.html
index eba7c5b7e52e..8897f5aca5a7 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setconn.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setconn.html
@@ -30,14 +30,15 @@ Set the socket through which this filter should communicate with sendmail.
<TD>Sets the socket through which the filter communicates with sendmail.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>oconn</TD>
- <TD>The address of the desired communication socket.
- The address should be a NULL-terminated string in "proto:address"
+ <TD>The address of the desired communication socket.
+ The address should be a NULL-terminated string in "proto:address"
format:
<UL>
<LI><CODE>{unix|local}:/path/to/file</CODE> -- A named pipe.
@@ -50,7 +51,7 @@ Set the socket through which this filter should communicate with sendmail.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_setconn will not fail on an invalid address.
The failure will only be detected in <A href="smfi_main.html">smfi_main</A>.
@@ -60,7 +61,7 @@ due to a lack of memory.
</TR>
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
diff --git a/contrib/sendmail/libmilter/docs/smfi_setdbg.html b/contrib/sendmail/libmilter/docs/smfi_setdbg.html
index 58d519935e20..e7498391105b 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setdbg.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setdbg.html
@@ -34,6 +34,7 @@ A level of zero turns off debugging. The greater
the current, highest, useful value.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -47,7 +48,7 @@ the current, highest, useful value.</TD>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_setdbg returns MI_SUCCESS by default.
</TD>
diff --git a/contrib/sendmail/libmilter/docs/smfi_setmlreply.html b/contrib/sendmail/libmilter/docs/smfi_setmlreply.html
index e9118838fd39..3f36e5296430 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setmlreply.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setmlreply.html
@@ -38,6 +38,7 @@ This code will be used on subsequent error replies resulting from actions
taken by this filter.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -65,7 +66,7 @@ taken by this filter.</TD>
<!----------- Example ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>
For example, the code:<BR>
<PRE>
@@ -86,13 +87,13 @@ For example, the code:<BR>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_setmlreply will fail and return MI_FAILURE if:
<UL>
<LI>The rcode or xcode argument is invalid.
<LI>A memory-allocation failure occurs.
- <LI>If any text line contains a carraige return or line feed.
+ <LI>If any text line contains a carriage return or line feed.
<LI>The length of any text line is more than MAXREPLYLEN (980).
<LI>More than 32 lines of text replies are given.
</UL>
@@ -102,7 +103,7 @@ Otherwise, it return MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
<UL>
<LI>Values passed to smfi_setmlreply are not checked for standards compliance.
@@ -112,7 +113,7 @@ 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 <TT>printf(3)</TT>).
-<LI>For details about reply codes and their meanings, please see RFC's
+<LI>For details about reply codes and their meanings, please see RFC's
<A href="http://www.rfc-editor.org/rfc/rfc821.txt">821</A>/
<A href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</A>
and
diff --git a/contrib/sendmail/libmilter/docs/smfi_setpriv.html b/contrib/sendmail/libmilter/docs/smfi_setpriv.html
index 5b03456f47aa..a9cb37e598c9 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setpriv.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setpriv.html
@@ -31,6 +31,7 @@ Set the private data pointer for this connection.
<TD>Sets the private data pointer for the context ctx.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -47,14 +48,14 @@ Set the private data pointer for this connection.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_setpriv returns MI_FAILURE if ctx is an invalid context.
Otherwise, it returns MI_SUCCESS.</TD>
</TR>
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>There is only one private data pointer per connection; multiple
calls to smfi_setpriv with different values will cause previous values
diff --git a/contrib/sendmail/libmilter/docs/smfi_setreply.html b/contrib/sendmail/libmilter/docs/smfi_setreply.html
index 21ec5a57d092..615567107a4a 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setreply.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setreply.html
@@ -31,11 +31,12 @@ other than xxfi_connect.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
-<TD>Directly set the SMTP error reply code for this connection. This code
-will be used on subsequent error replies resulting from actions taken by
+<TD>Directly set the SMTP error reply code for this connection. This code
+will be used on subsequent error replies resulting from actions taken by
this filter.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -61,12 +62,14 @@ this filter.</TD>
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_setreply will fail and return MI_FAILURE if:
<UL>
<LI>The rcode or xcode argument is invalid.
<LI>A memory-allocation failure occurs.
+ <LI>The length of any text line is more than MAXREPLYLEN (980).
+ <LI>The message argument contains a carriage return or line feed.
</UL>
Otherwise, it return MI_SUCCESS.
</TD>
@@ -74,7 +77,7 @@ Otherwise, it return MI_SUCCESS.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>
<UL>
<LI>Values passed to smfi_setreply are not checked for standards compliance.
@@ -84,7 +87,7 @@ 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 <TT>printf(3)</TT>).
-<LI>For details about reply codes and their meanings, please see RFC's
+<LI>For details about reply codes and their meanings, please see RFC's
<A href="http://www.rfc-editor.org/rfc/rfc821.txt">821</A>/
<A href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</A>
and
diff --git a/contrib/sendmail/libmilter/docs/smfi_setsymlist.html b/contrib/sendmail/libmilter/docs/smfi_setsymlist.html
index c270d0b5647b..27bdd8a5f8ed 100644
--- a/contrib/sendmail/libmilter/docs/smfi_setsymlist.html
+++ b/contrib/sendmail/libmilter/docs/smfi_setsymlist.html
@@ -12,7 +12,7 @@ $Id: smfi_setsymlist.html,v 1.7 2013-11-22 20:51:39 ca Exp $
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setsymlist(
- SMFICTX *ctx,
+ SMFICTX *ctx,
int stage,
char *macros
);
@@ -37,6 +37,7 @@ milter wants to receive from the MTA.
</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -72,7 +73,7 @@ milter wants to receive from the MTA.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>MI_FAILURE is returned if
<UL>
@@ -88,7 +89,7 @@ Otherwise MI_SUCCESS is returned.
<!----------- Notes ---------->
<TR align="left" valign=top>
-<TH>NOTES</TH>
+<TH>NOTES</TH>
<TD>There is an internal limit on the number of macros
that can be set
<!-- XREF: MAXFILTERMACROS -->
diff --git a/contrib/sendmail/libmilter/docs/smfi_settimeout.html b/contrib/sendmail/libmilter/docs/smfi_settimeout.html
index 35cd51003ae6..aa135618a9d0 100644
--- a/contrib/sendmail/libmilter/docs/smfi_settimeout.html
+++ b/contrib/sendmail/libmilter/docs/smfi_settimeout.html
@@ -33,6 +33,7 @@ If smfi_settimeout is not called, a default timeout of 7210 seconds is used.
</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -47,24 +48,21 @@ If smfi_settimeout is not called, a default timeout of 7210 seconds is used.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_settimeout always returns MI_SUCCESS.</TD>
</TR>
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>
Decreasing the timeout is strongly discouraged
and may break the communication with the MTA.
Do <EM>not</EM> decrease this value without making sure that
the MTA also uses lower timeouts for communication
(with the milter and with the SMTP client).
-</TR>
-</TABLE>
-
-
+</TD></TR>
</TABLE>
<HR size="1">
diff --git a/contrib/sendmail/libmilter/docs/smfi_stop.html b/contrib/sendmail/libmilter/docs/smfi_stop.html
index aa725b9dbc25..c85a20d76ac5 100644
--- a/contrib/sendmail/libmilter/docs/smfi_stop.html
+++ b/contrib/sendmail/libmilter/docs/smfi_stop.html
@@ -36,6 +36,7 @@ which may then exit or warm-restart.
</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -49,7 +50,7 @@ which may then exit or warm-restart.
<!----------- Return values ---------->
<TR>
-<TH valign="top" align=left>RETURN VALUES</TH>
+<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_stop always returns SMFI_CONTINUE. But note:
<UL>
diff --git a/contrib/sendmail/libmilter/docs/smfi_version.html b/contrib/sendmail/libmilter/docs/smfi_version.html
index 64c4a4d8f8ac..f9b7bcb86b0c 100644
--- a/contrib/sendmail/libmilter/docs/smfi_version.html
+++ b/contrib/sendmail/libmilter/docs/smfi_version.html
@@ -32,6 +32,7 @@ Get the (runtime) version of libmilter.
<TD>None.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH VALIGN="TOP" ALIGN=LEFT>ARGUMENTS</TH><TD>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_abort.html b/contrib/sendmail/libmilter/docs/xxfi_abort.html
index 9ec8f4990737..4e20d0e18d52 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_abort.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_abort.html
@@ -30,6 +30,7 @@ Handle the current message's being aborted.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -43,7 +44,7 @@ Handle the current message's being aborted.
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>xxfi_abort must reclaim any resources allocated on a per-message
diff --git a/contrib/sendmail/libmilter/docs/xxfi_body.html b/contrib/sendmail/libmilter/docs/xxfi_body.html
index 811035065874..511eeb3aae68 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_body.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_body.html
@@ -32,6 +32,7 @@ Handle a piece of a message's body.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -51,7 +52,7 @@ Handle a piece of a message's body.
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>bodyp points to a sequence of bytes.
@@ -65,7 +66,7 @@ to work as expected.
significantly impact filter performance.
<LI>End-of-lines are represented as received from SMTP (normally CR/LF).
<LI>Later filters will see body changes made by earlier ones.
-<LI>Message bodies may be sent in multiple chunks, with one call to
+<LI>Message bodies may be sent in multiple chunks, with one call to
xxfi_body per chunk.
<LI>Return
<A HREF="api.html#SMFIS_SKIP">SMFIS_SKIP</A>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_close.html b/contrib/sendmail/libmilter/docs/xxfi_close.html
index b5cf2ff237ad..1999d0e3896b 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_close.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_close.html
@@ -30,6 +30,7 @@ The current connection is being closed.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -43,7 +44,7 @@ The current connection is being closed.
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>xxfi_close may be called "out-of-order", i.e. before even the
@@ -59,7 +60,7 @@ xxfi_close code.
In particular, it is incorrect to assume the private context pointer
will be something other than NULL in this callback.
<LI>xxfi_close is called on close even if the previous mail
-transaction was aborted.
+transaction was aborted.
<LI>xxfi_close is responsible for freeing any resources allocated on a
per-connection basis.
<LI>Since the connection is already closing, the return value is
diff --git a/contrib/sendmail/libmilter/docs/xxfi_connect.html b/contrib/sendmail/libmilter/docs/xxfi_connect.html
index 29a2c911153e..c84f9f281738 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_connect.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_connect.html
@@ -12,7 +12,7 @@ $Id: xxfi_connect.html,v 1.20 2013-11-22 20:51:39 ca Exp $
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_connect)(
- SMFICTX *ctx,
+ SMFICTX *ctx,
char *hostname,
_SOCK_ADDR *hostaddr);
</PRE>
@@ -29,16 +29,18 @@ sfsistat (*xxfi_connect)(
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+
<!--
-This callback function is invoked on each connection to the mail
+This callback function is invoked on each connection to the mail
filter program.
The callback is to be implemented by the Milter application developers.
The name of the callback can be any valid function name.
The function pointer is to be assigned to the
smfiDesc.xxfi_connect and the pointer to the smfiDesc structure
is passed to smfi_register().
-</TD></TR>
-->
+</TD></TR>
+
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
@@ -103,7 +105,7 @@ is passed to smfi_register().
-->
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>If an earlier filter rejects the connection in its xxfi_connect()
routine, this filter's xxfi_connect() will not be called.</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_data.html b/contrib/sendmail/libmilter/docs/xxfi_data.html
index 7dedb4183097..f8b715b5675e 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_data.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_data.html
@@ -23,13 +23,14 @@ Handle the DATA command.
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
-<TD>xxfi_data is called when the client uses the DATA command.
+<TD>xxfi_data is called when the client uses the DATA command.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -67,11 +68,11 @@ Handle the DATA command.
</TD>
</TR>
</TABLE>
-</TR>
+</TD></TR>
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>For more details on ESMTP responses, please see RFC
<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html
index 24811e14a6c1..b553b4d9fd63 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_envfrom.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_envfrom.html
@@ -33,6 +33,7 @@ before xxfi_envrcpt.</TD>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -75,11 +76,11 @@ before xxfi_envrcpt.</TD>
</TD>
</TR>
</TABLE>
-</TR>
+</TD></TR>
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>For more details on ESMTP responses, please see RFC
<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html
index 9503ab98c616..d15b70fdf187 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_envrcpt.html
@@ -31,6 +31,7 @@ Handle the envelope RCPT command.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -54,7 +55,7 @@ Handle the envelope RCPT command.
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
- <TD>Temporarily fail for this particular recipient; further recipients
+ <TD>Temporarily fail for this particular recipient; further recipients
may still be sent. <A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
@@ -76,11 +77,11 @@ Handle the envelope RCPT command.
</TD>
</TR>
</TABLE>
-</TR>
+</TD></TR>
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>For more details on ESMTP responses, please see RFC
<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD>
</TR>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_eoh.html b/contrib/sendmail/libmilter/docs/xxfi_eoh.html
index 33f5fc004983..4be41d758bc3 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_eoh.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_eoh.html
@@ -31,6 +31,7 @@ Handle the end of message headers.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_eom.html b/contrib/sendmail/libmilter/docs/xxfi_eom.html
index d473777e4b13..9bf040c02ad4 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_eom.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_eom.html
@@ -30,6 +30,7 @@ End of a message.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -43,7 +44,7 @@ End of a message.
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>A filter is required to make all its modifications to the message headers, body, and envelope in xxfi_eom.
Modifications are made via the smfi_* routines.
</TD>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_header.html b/contrib/sendmail/libmilter/docs/xxfi_header.html
index 16e814b47c48..bccada7e524f 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_header.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_header.html
@@ -32,6 +32,7 @@ Handle a message header.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -55,7 +56,7 @@ Handle a message header.
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>Starting with sendmail 8.14, spaces after the colon in a header
@@ -90,7 +91,7 @@ it was:
<LI>Later filters will see header changes/additions made by earlier ones.
-<LI>For much more detail about header format, please see
+<LI>For much more detail about header format, please see
RFC <A href="http://www.rfc-editor.org/rfc/rfc822.html">822</A>
and
RFC <A href="http://www.rfc-editor.org/rfc/rfc2822.html">2822</A>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_helo.html b/contrib/sendmail/libmilter/docs/xxfi_helo.html
index 716eb9290f17..8c4309cd5bf2 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_helo.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_helo.html
@@ -12,7 +12,7 @@ $Id: xxfi_helo.html,v 1.13 2013-11-22 20:51:39 ca Exp $
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_helo)(
- SMFICTX *ctx,
+ SMFICTX *ctx,
char *helohost
);
</PRE>
@@ -34,6 +34,7 @@ some restrictions can be imposed by the MTA configuration.
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
diff --git a/contrib/sendmail/libmilter/docs/xxfi_negotiate.html b/contrib/sendmail/libmilter/docs/xxfi_negotiate.html
index b0502f47a711..e858a39c0e98 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_negotiate.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_negotiate.html
@@ -13,7 +13,7 @@ $Id: xxfi_negotiate.html,v 1.24 2013-11-22 20:51:39 ca Exp $
#include &lt;libmilter/mfapi.h&gt;
#include &lt;libmilter/mfdef.h&gt;
sfsistat (*xxfi_negotiate)(
- SMFICTX *ctx,
+ SMFICTX *ctx,
unsigned long f0,
unsigned long f1,
unsigned long f2,
@@ -36,6 +36,8 @@ sfsistat (*xxfi_negotiate)(
<TD>Return SMFIS_ALL_OPTS to change nothing.</TD>
</TR>
</TABLE>
+</TD></TR>
+
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
@@ -48,6 +50,7 @@ sfsistat (*xxfi_negotiate)(
</TD></TR>
<TR><TD>f1</TD>
<TD>the protocol steps offered by the MTA.
+ </TD></TR>
<TR><TD>f2</TD>
<TD>for future extensions.
</TD></TR>
@@ -59,6 +62,7 @@ sfsistat (*xxfi_negotiate)(
</TD></TR>
<TR><TD>pf1</TD>
<TD>the protocol steps requested by the milter.
+ </TD></TR>
<TR><TD>pf2</TD>
<TD>for future extensions.
</TD></TR>
@@ -101,11 +105,11 @@ as they will be ignored.
</TD>
</TR>
</TABLE>
-</TR>
+</TD></TR>
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>This function allows a milter to dynamically determine and
request operations and actions during startup.
In previous versions, the actions (f0) were fixed in the
@@ -140,6 +144,11 @@ By setting this bit, a milter can request that the
MTA should also send <CODE>RCPT</CODE> commands that have been rejected
because the user is unknown (or similar reasons), but not those
which have been rejected because of syntax errors etc.
+<!--
+In order for this request to have effect,
+sendmail must have been built with the compile time option
+<TT>_FFR_MILTER_CHECK_REJECTIONS_TOO</TT>.
+-->
If a milter requests this protocol step,
then it should check the macro
<CODE>{rcpt_mailer}</CODE>:
@@ -204,11 +213,12 @@ space to headers when they are added, inserted, or changed.
<LI>The MTA can be instructed not to send information about
various SMTP stages, these flags start with:
<A NAME="SMFIP_NO"><CODE>SMFIP_NO*</CODE></A>.
+Setting any of these flags affects all connections.
<UL>
<LI><A NAME="SMFIP_NOCONNECT"><CODE>SMFIP_NOCONNECT</CODE></A>:
<A HREF="xxfi_connect.html">xxfi_connect()</A>
<LI><A NAME="SMFIP_NOHELO"><CODE>SMFIP_NOHELO</CODE></A>:
-<A HREF="xxfi_header.html">xxfi_header()</A>
+<A HREF="xxfi_helo.html">xxfi_helo()</A>
<LI><A NAME="SMFIP_NOMAIL"><CODE>SMFIP_NOMAIL</CODE></A>:
<A HREF="xxfi_envfrom.html">xxfi_envfrom()</A>
<LI><A NAME="SMFIP_NORCPT"><CODE>SMFIP_NORCPT</CODE></A>:
diff --git a/contrib/sendmail/libmilter/docs/xxfi_unknown.html b/contrib/sendmail/libmilter/docs/xxfi_unknown.html
index 38c1c3d47166..94e4f39d9592 100644
--- a/contrib/sendmail/libmilter/docs/xxfi_unknown.html
+++ b/contrib/sendmail/libmilter/docs/xxfi_unknown.html
@@ -25,13 +25,14 @@ Handle unknown and unimplemented SMTP commands.
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_unknown is called when the client uses an SMTP command
-that is either unknown or not implemented by the MTA.
+that is either unknown or not implemented by the MTA.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
+</TD></TR>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
@@ -62,13 +63,13 @@ that is either unknown or not implemented by the MTA.
</TD>
</TR>
</TABLE>
-</TR>
+</TD></TR>
<!----------- Notes ---------->
<TR>
-<TH valign="top" align=left>NOTES</TH>
+<TH valign="top" align=left>NOTES</TH>
<TD>The SMTP command will always be rejected by the server,
-it is only possible to return a different error code.
+it is only possible to return a different error code.</TD>
</TR>
</TABLE>
diff --git a/contrib/sendmail/libmilter/engine.c b/contrib/sendmail/libmilter/engine.c
index 808ffdbf608a..2619395a6eb1 100644
--- a/contrib/sendmail/libmilter/engine.c
+++ b/contrib/sendmail/libmilter/engine.c
@@ -15,7 +15,7 @@ SM_RCSID("@(#)$Id: engine.c,v 8.168 2013-11-22 20:51:36 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
/* generic argument for functions in the command table */
struct arg_struct
@@ -72,17 +72,17 @@ ERROR: do not compile with CI_LAST < CI_EOM
#if CI_LAST < CI_EOH
ERROR: do not compile with CI_LAST < CI_EOH
#endif
-#if CI_LAST < CI_ENVRCPT
-ERROR: do not compile with CI_LAST < CI_ENVRCPT
+#if CI_LAST < CI_RCPT
+ERROR: do not compile with CI_LAST < CI_RCPT
#endif
-#if CI_LAST < CI_ENVFROM
-ERROR: do not compile with CI_LAST < CI_ENVFROM
+#if CI_LAST < CI_MAIL
+ERROR: do not compile with CI_LAST < CI_MAIL
#endif
#if CI_LAST < CI_HELO
ERROR: do not compile with CI_LAST < CI_HELO
#endif
-#if CI_LAST < CI_CONNECT
-ERROR: do not compile with CI_LAST < CI_CONNECT
+#if CI_LAST < CI_CONN
+ERROR: do not compile with CI_LAST < CI_CONN
#endif
#if CI_LAST >= MAX_MACROS_ENTRIES
ERROR: do not compile with CI_LAST >= MAX_MACROS_ENTRIES
@@ -112,7 +112,7 @@ static void mi_clr_symlist __P((SMFICTX_PTR));
#if _FFR_WORKERS_POOL
static bool mi_rd_socket_ready __P((int));
-#endif /* _FFR_WORKERS_POOL */
+#endif
/* states */
#define ST_NONE (-1)
@@ -458,7 +458,7 @@ mi_engine(ctx)
if (ctx->ctx_state != ST_QUIT
#if _FFR_WORKERS_POOL
&& ret != MI_CONTINUE
-#endif /* _FFR_WORKERS_POOL */
+#endif
)
{
if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL)
@@ -468,7 +468,7 @@ mi_engine(ctx)
free(buf);
#if !_FFR_WORKERS_POOL
mi_clr_macros(ctx, 0);
-#endif /* _FFR_WORKERS_POOL */
+#endif
return ret;
}
@@ -628,7 +628,7 @@ sendreply(r, sd, timeout_ptr, ctx)
{
/* milter said it wouldn't reply, but it lied... */
smi_log(SMI_LOG_ERR,
- "%s: milter claimed not to reply in state %d but did anyway %d\n",
+ "%s: milter claimed not to reply in state %d but did anyway %d",
ctx->ctx_smfi->xxfi_name,
ctx->ctx_state, r);
@@ -703,8 +703,12 @@ sendreply(r, sd, timeout_ptr, ctx)
(void *) &v, MILTER_LEN_BYTES);
len = milter_addsymlist(ctx, buf, &buffer);
if (buffer != NULL)
+ {
ret = mi_wr_cmd(sd, timeout_ptr, SMFIC_OPTNEG,
buffer, len);
+ if (buffer != buf)
+ free(buffer);
+ }
else
ret = MI_FAILURE;
}
@@ -843,7 +847,7 @@ st_optionneg(g)
SMFICTX_PTR ctx;
#if _FFR_MILTER_CHECK
bool testmode = false;
-#endif /* _FFR_MILTER_CHECK */
+#endif
int (*fi_negotiate) __P((SMFICTX *,
unsigned long, unsigned long,
unsigned long, unsigned long,
@@ -1000,7 +1004,7 @@ st_optionneg(g)
testmode = bitset(SMFIP_TEST, m_pflags);
if (testmode)
m_pflags &= ~SMFIP_TEST;
-#endif /* _FFR_MILTER_CHECK */
+#endif
/*
** Types of protocol flags (pflags):
@@ -1100,7 +1104,7 @@ st_optionneg(g)
{
/*
** Older MTAs do not support some protocol steps.
- ** As this protocol is a bit "wierd" (it asks for steps
+ ** As this protocol is a bit "weird" (it asks for steps
** NOT to be taken/sent) we have to check whether we
** should turn off those "negative" requests.
** Currently these are only SMFIP_NODATA and SMFIP_NOUNKNOWN.
@@ -1186,7 +1190,7 @@ st_connectinfo(g)
s = g->a_buf;
i = 0;
l = g->a_len;
- while (s[i] != '\0' && i <= l)
+ while (i <= l && s[i] != '\0')
++i;
if (i + 1 >= l)
return _SMFIS_ABORT;
@@ -1868,9 +1872,9 @@ mi_rd_socket_ready (sd)
int nerr = 0;
#if SM_CONF_POLL
struct pollfd pfd;
-#else /* SM_CONF_POLL */
+#else
fd_set rd_set, exc_set;
-#endif /* SM_CONF_POLL */
+#endif
do
{
@@ -1912,8 +1916,8 @@ mi_rd_socket_ready (sd)
#if SM_CONF_POLL
return (pfd.revents != 0);
-#else /* SM_CONF_POLL */
+#else
return FD_ISSET(sd, &rd_set) || FD_ISSET(sd, &exc_set);
-#endif /* SM_CONF_POLL */
+#endif
}
#endif /* _FFR_WORKERS_POOL */
diff --git a/contrib/sendmail/libmilter/example.c b/contrib/sendmail/libmilter/example.c
index f078eb7ba304..e0fef80b6d4e 100644
--- a/contrib/sendmail/libmilter/example.c
+++ b/contrib/sendmail/libmilter/example.c
@@ -28,7 +28,7 @@
#ifndef true
# define false 0
# define true 1
-#endif /* ! true */
+#endif
struct mlfiPriv
{
diff --git a/contrib/sendmail/libmilter/handler.c b/contrib/sendmail/libmilter/handler.c
index 7622839d65e4..17ee7f8dac0a 100644
--- a/contrib/sendmail/libmilter/handler.c
+++ b/contrib/sendmail/libmilter/handler.c
@@ -35,7 +35,7 @@ mi_handle_session(ctx)
ctx->ctx_id = (sthread_t) sthread_get_id();
/*
- ** Detach so resources are free when the thread returns.
+ ** Detach so resources are freed when the thread returns.
** If we ever "wait" for threads, this call must be removed.
*/
diff --git a/contrib/sendmail/libmilter/libmilter.h b/contrib/sendmail/libmilter/libmilter.h
index 3c572ec9a9e8..f9fe38ca4a9f 100644
--- a/contrib/sendmail/libmilter/libmilter.h
+++ b/contrib/sendmail/libmilter/libmilter.h
@@ -20,10 +20,10 @@
# define EXTERN
# define INIT(x) = x
SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.78 2013-11-22 20:51:36 ca Exp $")
-#else /* _DEFINE */
+#else
# define EXTERN extern
# define INIT(x)
-#endif /* _DEFINE */
+#endif
#include "sm/tailq.h"
@@ -111,7 +111,7 @@ struct smfi_str
#if _FFR_THREAD_MONITOR
time_t ctx_start; /* start time of thread */
SM_TAILQ_ENTRY(smfi_str) ctx_mon_link;
-#endif /* _FFR_THREAD_MONITOR */
+#endif
#if _FFR_WORKERS_POOL
long ctx_sid; /* session identifier */
@@ -142,7 +142,7 @@ typedef pthread_mutex_t smutex_t;
/* SM_CONF_POLL shall be defined with _FFR_WORKERS_POOL */
# if !SM_CONF_POLL
# define SM_CONF_POLL 1
-# endif /* SM_CONF_POLL */
+# endif
#endif /* _FFR_WORKERS_POOL */
typedef pthread_cond_t scond_t;
@@ -173,7 +173,7 @@ typedef pthread_cond_t scond_t;
# define MI_POLL_RD_FLAGS (POLLIN | POLLPRI)
# define MI_POLL_WR_FLAGS (POLLOUT)
-# define MI_MS(timeout) (((timeout)->tv_sec * 1000) + (timeout)->tv_usec)
+# define MI_MS(timeout) (((timeout)->tv_sec * 1000) + (((timeout)->tv_usec) / 1000))
# define FD_RD_VAR(rds, excs) struct pollfd rds
# define FD_WR_VAR(wrs) struct pollfd wrs
@@ -197,7 +197,7 @@ typedef pthread_cond_t scond_t;
# define FD_IS_RD_RDY(sd, rds, excs) \
(((rds).revents & MI_POLL_RD_FLAGS) != 0)
-# define FD_WR_READY(sd, excs, timeout) \
+# define FD_WR_READY(sd, wrs, timeout) \
poll(&(wrs), 1, MI_MS(timeout))
# define FD_RD_READY(sd, rds, excs, timeout) \
@@ -241,9 +241,9 @@ typedef pthread_cond_t scond_t;
#ifndef MI_SOMAXCONN
# if SOMAXCONN > 20
# define MI_SOMAXCONN SOMAXCONN
-# else /* SOMAXCONN */
+# else
# define MI_SOMAXCONN 20
-# endif /* SOMAXCONN */
+# endif
#endif /* ! MI_SOMAXCONN */
/* maximum number of repeated failures in mi_listener() */
diff --git a/contrib/sendmail/libmilter/listener.c b/contrib/sendmail/libmilter/listener.c
index 11d92bb09fdf..0468a6231cce 100644
--- a/contrib/sendmail/libmilter/listener.c
+++ b/contrib/sendmail/libmilter/listener.c
@@ -24,11 +24,11 @@ SM_RCSID("@(#)$Id: listener.c,v 8.127 2013-11-22 20:51:36 ca Exp $")
# if NETINET || NETINET6
# include <arpa/inet.h>
-# endif /* NETINET || NETINET6 */
+# endif
# if SM_CONF_POLL
# undef SM_FD_OK_SELECT
# define SM_FD_OK_SELECT(fd) true
-# endif /* SM_CONF_POLL */
+# endif
static smutex_t L_Mutex;
static int L_family;
@@ -38,7 +38,7 @@ static socket_t listenfd = INVALID_SOCKET;
static socket_t mi_milteropen __P((char *, int, bool, char *));
#if !_FFR_WORKERS_POOL
static void *mi_thread_handle_wrapper __P((void *));
-#endif /* !_FFR_WORKERS_POOL */
+#endif
/*
** MI_OPENSOCKET -- create the socket where this filter and the MTA will meet
@@ -116,7 +116,7 @@ mi_opensocket(conn, backlog, dbg, rmsocket, smfi)
#if NETUNIX
static char *sockpath = NULL;
-#endif /* NETUNIX */
+#endif
static socket_t
mi_milteropen(conn, backlog, rmsocket, name)
@@ -269,13 +269,13 @@ mi_milteropen(conn, backlog, rmsocket, name)
if (
# if NETINET
addr.sa.sa_family == AF_INET
-# endif /* NETINET */
+# endif
# if NETINET && NETINET6
||
-# endif /* NETINET && NETINET6 */
+# endif
# if NETINET6
addr.sa.sa_family == AF_INET6
-# endif /* NETINET6 */
+# endif
)
{
unsigned short port;
@@ -290,13 +290,13 @@ mi_milteropen(conn, backlog, rmsocket, name)
case AF_INET:
addr.sin.sin_addr.s_addr = INADDR_ANY;
break;
-# endif /* NETINET */
+# endif
# if NETINET6
case AF_INET6:
addr.sin6.sin6_addr = in6addr_any;
break;
-# endif /* NETINET6 */
+# endif
}
}
else
@@ -337,10 +337,10 @@ mi_milteropen(conn, backlog, rmsocket, name)
bool found = false;
# if NETINET
unsigned long hid = INADDR_NONE;
-# endif /* NETINET */
+# endif
# if NETINET6
struct sockaddr_in6 hid6;
-# endif /* NETINET6 */
+# endif
*end = '\0';
# if NETINET
@@ -421,7 +421,7 @@ mi_milteropen(conn, backlog, rmsocket, name)
}
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
}
}
else
@@ -432,12 +432,12 @@ mi_milteropen(conn, backlog, rmsocket, name)
case AF_INET:
addr.sin.sin_port = port;
break;
-# endif /* NETINET */
+# endif
# if NETINET6
case AF_INET6:
addr.sin6.sin6_port = port;
break;
-# endif /* NETINET6 */
+# endif
}
}
}
@@ -465,7 +465,7 @@ mi_milteropen(conn, backlog, rmsocket, name)
if (
#if NETUNIX
addr.sa.sa_family != AF_UNIX &&
-#endif /* NETUNIX */
+#endif
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *) &sockopt,
sizeof(sockopt)) == -1)
{
@@ -607,7 +607,7 @@ mi_closener()
(S_ISFIFO(sockinfo.st_mode)
# ifdef S_ISSOCK
|| S_ISSOCK(sockinfo.st_mode)
-# endif /* S_ISSOCK */
+# endif
);
#endif /* NETUNIX */
@@ -624,13 +624,13 @@ mi_closener()
fileinfo.st_ino == sockinfo.st_ino)
# ifdef S_ISSOCK
|| S_ISSOCK(fileinfo.st_mode)
-# endif /* S_ISSOCK */
+# endif
)
&&
(S_ISFIFO(fileinfo.st_mode)
# ifdef S_ISSOCK
|| S_ISSOCK(fileinfo.st_mode)
-# endif /* S_ISSOCK */
+# endif
))
(void) unlink(sockpath);
free(sockpath);
@@ -719,7 +719,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
socket_t connfd = INVALID_SOCKET;
#if _FFR_DUP_FD
socket_t dupfd = INVALID_SOCKET;
-#endif /* _FFR_DUP_FD */
+#endif
int sockopt = 1;
int r, mistop;
int ret = MI_SUCCESS;
@@ -731,7 +731,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
int fdflags;
#if !_FFR_WORKERS_POOL
sthread_t thread_id;
-#endif /* !_FFR_WORKERS_POOL */
+#endif
_SOCK_ADDR cliaddr;
SOCKADDR_LEN_T clilen;
SMFICTX_PTR ctx;
@@ -744,7 +744,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
#if _FFR_WORKERS_POOL
if (mi_pool_controller_init() == MI_FAILURE)
return MI_FAILURE;
-#endif /* _FFR_WORKERS_POOL */
+#endif
clilen = L_socksize;
while ((mistop = mi_stop()) == MILTER_CONT)
@@ -817,7 +817,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
(clilen == 0 ||
# ifdef BSD4_4_SOCKADDR
cliaddr.sa.sa_len == 0 ||
-# endif /* BSD4_4_SOCKADDR */
+# endif
cliaddr.sa.sa_family != L_family))
{
(void) closesocket(connfd);
@@ -838,28 +838,28 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
if (save_errno == EINTR
#ifdef EAGAIN
|| save_errno == EAGAIN
-#endif /* EAGAIN */
+#endif
#ifdef ECONNABORTED
|| save_errno == ECONNABORTED
-#endif /* ECONNABORTED */
+#endif
#ifdef EMFILE
|| save_errno == EMFILE
-#endif /* EMFILE */
+#endif
#ifdef ENFILE
|| save_errno == ENFILE
-#endif /* ENFILE */
+#endif
#ifdef ENOBUFS
|| save_errno == ENOBUFS
-#endif /* ENOBUFS */
+#endif
#ifdef ENOMEM
|| save_errno == ENOMEM
-#endif /* ENOMEM */
+#endif
#ifdef ENOSR
|| save_errno == ENOSR
-#endif /* ENOSR */
+#endif
#ifdef EWOULDBLOCK
|| save_errno == EWOULDBLOCK
-#endif /* EWOULDBLOCK */
+#endif
)
continue;
acnt++;
@@ -886,7 +886,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
}
#endif /* _FFR_DUP_FD */
- /*
+ /*
** Need to set close-on-exec for connfd in case a user's
** filter starts other applications.
** Note: errors will not stop processing (for now).
@@ -951,12 +951,12 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
#if _FFR_WORKERS_POOL
# define LOG_CRT_FAIL "%s: mi_start_session() failed: %d, %s"
if ((r = mi_start_session(ctx)) != MI_SUCCESS)
-#else /* _FFR_WORKERS_POOL */
+#else
# define LOG_CRT_FAIL "%s: thread_create() failed: %d, %s"
if ((r = thread_create(&thread_id,
mi_thread_handle_wrapper,
(void *) ctx)) != 0)
-#endif /* _FFR_WORKERS_POOL */
+#endif
{
tcnt++;
smi_log(SMI_LOG_ERR,
diff --git a/contrib/sendmail/libmilter/main.c b/contrib/sendmail/libmilter/main.c
index ef3242feff05..ff7bf99bcc82 100644
--- a/contrib/sendmail/libmilter/main.c
+++ b/contrib/sendmail/libmilter/main.c
@@ -206,7 +206,7 @@ smfi_setbacklog(obacklog)
/*
-** SMFI_MAIN -- setup milter connnection and start listener.
+** SMFI_MAIN -- setup milter connection and start listener.
**
** Parameters:
** none.
diff --git a/contrib/sendmail/libmilter/monitor.c b/contrib/sendmail/libmilter/monitor.c
index 9916bb59598d..ec08e53d0b2e 100644
--- a/contrib/sendmail/libmilter/monitor.c
+++ b/contrib/sendmail/libmilter/monitor.c
@@ -39,7 +39,7 @@ static scond_t Mon_cv;
** after a mutex_lock() attempt, the order might not be strict,
** i.e., if the list contains e1 and e2 (in that order) then
** the the start time of e2 can be (slightly) smaller than that of e1.
-** However, this slight inaccurracy should not matter for the proper
+** However, this slight inaccuracy should not matter for the proper
** working of this algorithm.
*/
diff --git a/contrib/sendmail/libmilter/sm_gethost.c b/contrib/sendmail/libmilter/sm_gethost.c
index 2423c34419c1..262edb6c541c 100644
--- a/contrib/sendmail/libmilter/sm_gethost.c
+++ b/contrib/sendmail/libmilter/sm_gethost.c
@@ -14,13 +14,13 @@ SM_RCSID("@(#)$Id: sm_gethost.c,v 8.32 2013-11-22 20:51:36 ca Exp $")
#include <sendmail.h>
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
#include "libmilter.h"
/*
** MI_GETHOSTBY{NAME,ADDR} -- compatibility routines for gethostbyXXX
**
-** Some operating systems have wierd problems with the gethostbyXXX
+** Some operating systems have weird problems with the gethostbyXXX
** routines. For example, Solaris versions at least through 2.3
** don't properly deliver a canonical h_name field. This tries to
** work around these problems.
@@ -34,13 +34,13 @@ static struct hostent *sm_getipnodebyname __P((const char *, int, int, int *));
# ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0 /* dummy */
-# endif /* ! AI_ADDRCONFIG */
+# endif
# ifndef AI_ALL
# define AI_ALL 0 /* dummy */
-# endif /* ! AI_ALL */
+# endif
# ifndef AI_DEFAULT
# define AI_DEFAULT 0 /* dummy */
-# endif /* ! AI_DEFAULT */
+# endif
static struct hostent *
sm_getipnodebyname(name, family, flags, err)
@@ -49,8 +49,17 @@ sm_getipnodebyname(name, family, flags, err)
int flags;
int *err;
{
- bool resv6 = true;
struct hostent *h;
+# if HAS_GETHOSTBYNAME2
+
+ h = gethostbyname2(name, family);
+ if (h == NULL)
+ *err = h_errno;
+ return h;
+
+# else /* HAS_GETHOSTBYNAME2 */
+# ifdef RES_USE_INET6
+ bool resv6 = true;
if (family == AF_INET6)
{
@@ -58,23 +67,27 @@ sm_getipnodebyname(name, family, flags, err)
resv6 = bitset(RES_USE_INET6, _res.options);
_res.options |= RES_USE_INET6;
}
+# endif /* RES_USE_INET6 */
SM_SET_H_ERRNO(0);
h = gethostbyname(name);
- if (family == AF_INET6 && !resv6)
+# ifdef RES_USE_INET6
+ if (!resv6)
_res.options &= ~RES_USE_INET6;
+# endif
/* the function is supposed to return only the requested family */
if (h != NULL && h->h_addrtype != family)
{
-# if NETINET6
+# if NETINET6
freehostent(h);
-# endif /* NETINET6 */
+# endif
h = NULL;
*err = NO_DATA;
}
else
*err = h_errno;
return h;
+# endif /* HAS_GETHOSTBYNAME2 */
}
void
@@ -89,7 +102,7 @@ freehostent(h)
return;
}
#else /* NEEDSGETIPNODE && NETINET6 */
-#define sm_getipnodebyname getipnodebyname
+#define sm_getipnodebyname getipnodebyname
#endif /* NEEDSGETIPNODE && NETINET6 */
struct hostent *
@@ -115,7 +128,7 @@ mi_gethostbyname(name, family)
# ifndef SM_IPNODEBYNAME_FLAGS
/* For IPv4-mapped addresses, use: AI_DEFAULT|AI_ALL */
# define SM_IPNODEBYNAME_FLAGS AI_ADDRCONFIG
-# endif /* SM_IPNODEBYNAME_FLAGS */
+# endif
int flags = SM_IPNODEBYNAME_FLAGS;
int err;
@@ -124,7 +137,7 @@ mi_gethostbyname(name, family)
# if NETINET6
# if ADDRCONFIG_IS_BROKEN
flags &= ~AI_ADDRCONFIG;
-# endif /* ADDRCONFIG_IS_BROKEN */
+# endif
h = sm_getipnodebyname(name, family, flags, &err);
SM_SET_H_ERRNO(err);
# else /* NETINET6 */
@@ -138,7 +151,7 @@ mi_gethostbyname(name, family)
{
# if NETINET6
freehostent(h);
-# endif /* NETINET6 */
+# endif
h = NULL;
SM_SET_H_ERRNO(NO_DATA);
}
@@ -158,7 +171,7 @@ mi_gethostbyname(name, family)
**
** Returns:
** 1 if the address was valid
-** 0 if the address wasn't parseable
+** 0 if the address wasn't parsable
** -1 if error
*/
diff --git a/contrib/sendmail/libmilter/smfi.c b/contrib/sendmail/libmilter/smfi.c
index d6c63a2ce800..a0fcd1184e46 100644
--- a/contrib/sendmail/libmilter/smfi.c
+++ b/contrib/sendmail/libmilter/smfi.c
@@ -103,7 +103,7 @@ smfi_addheader(ctx, headerf, headerv)
**
** Parameters:
** ctx -- Opaque context structure
-** hdridx -- index into header list where insertion should occur
+** hdridx -- index into header list where insertion should occur
** headerf -- Header field name
** headerv -- Header field value
**
@@ -267,7 +267,6 @@ send2(ctx, cmd, arg0, arg1)
if (arg1 != NULL)
{
- l1 = strlen(arg1) + 1;
SM_ASSERT(offset < len);
SM_ASSERT(offset + l1 <= len);
(void) memcpy(buf + offset, arg1, l1);
diff --git a/contrib/sendmail/libmilter/worker.c b/contrib/sendmail/libmilter/worker.c
index bf7086a95187..74bf98a39435 100644
--- a/contrib/sendmail/libmilter/worker.c
+++ b/contrib/sendmail/libmilter/worker.c
@@ -56,7 +56,7 @@ static taskmgr_T Tskmgr = {0};
#ifndef USE_PIPE_WAKE_POLL
# define USE_PIPE_WAKE_POLL 1
-#endif /* USE_PIPE_WAKE_POLL */
+#endif
/* poll check periodicity (default 10000 - 10 s) */
#define POLL_TIMEOUT 10000
@@ -83,7 +83,7 @@ static int mi_list_del_ctx __P((SMFICTX_PTR));
#ifndef OLD_SESSION_TIMEOUT
# define OLD_SESSION_TIMEOUT ctx->ctx_timeout
-#endif /* OLD_SESSION_TIMEOUT */
+#endif
/* session states - with respect to the pool of workers */
#define WKST_INIT 0 /* initial state */
@@ -143,7 +143,7 @@ static int mi_list_del_ctx __P((SMFICTX_PTR));
# define POOL_LEV_DPRINTF(lev, x) \
do \
{ \
- if ((lev) < ctx->ctx_dbg) \
+ if (ctx != NULL && (lev) < ctx->ctx_dbg) \
sm_dprintf x; \
} while (0)
#else /* POOL_DEBUG */
@@ -381,8 +381,6 @@ mi_pool_controller(arg)
int nfd, r, i;
time_t now;
- POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
-
if (mi_stop() != MILTER_CONT)
break;
diff --git a/contrib/sendmail/libsm/Makefile b/contrib/sendmail/libsm/Makefile
index e4b9871f98cd..4f43b9294576 100644
--- a/contrib/sendmail/libsm/Makefile
+++ b/contrib/sendmail/libsm/Makefile
@@ -8,10 +8,10 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
-install: FRC
- $(SHELL) $(BUILD) $(OPTIONS) $@
check: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+install: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
fresh: FRC
$(SHELL) $(BUILD) $(OPTIONS) -c
diff --git a/contrib/sendmail/libsm/Makefile.m4 b/contrib/sendmail/libsm/Makefile.m4
index 5882bb63f4e6..0dcb2d02b68d 100644
--- a/contrib/sendmail/libsm/Makefile.m4
+++ b/contrib/sendmail/libsm/Makefile.m4
@@ -6,7 +6,7 @@ define(`confREQUIRE_LIBSM', `true')
define(`confREQUIRE_SM_OS_H', `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 wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c inet6_ntop.c ')
+define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c inet6_ntop.c notify.c ')
bldPRODUCT_END
dnl msg.c
dnl syslogio.c
@@ -32,6 +32,7 @@ smcheck(`t-scanf', `compile-run')
smcheck(`t-shm', `compile-run')
smcheck(`t-sem', `compile-run')
smcheck(`t-inet6_ntop', `compile-run')
+smcheck(`t-notify', `compile-run')
dnl smcheck(`t-msg', `compile-run')
smcheck(`t-cf')
smcheck(`b-strcmp')
diff --git a/contrib/sendmail/libsm/assert.c b/contrib/sendmail/libsm/assert.c
index 6393e9eca419..e77720109028 100644
--- a/contrib/sendmail/libsm/assert.c
+++ b/contrib/sendmail/libsm/assert.c
@@ -83,7 +83,7 @@ sm_abort_defaulthandler(filename, lineno, msg)
#ifdef SIGSTOP
if (sm_debug_active(&SmAbortStop, 1))
kill(getpid(), SIGSTOP);
-#endif /* SIGSTOP */
+#endif
abort();
}
diff --git a/contrib/sendmail/libsm/clock.c b/contrib/sendmail/libsm/clock.c
index 5e4d7598dba8..6e300b0a5ca4 100644
--- a/contrib/sendmail/libsm/clock.c
+++ b/contrib/sendmail/libsm/clock.c
@@ -18,7 +18,7 @@ SM_RCSID("@(#)$Id: clock.c,v 1.48 2013-11-22 20:51:42 ca Exp $")
#include <errno.h>
#if SM_CONF_SETITIMER
# include <sm/time.h>
-#endif /* SM_CONF_SETITIMER */
+#endif
#include <sm/heap.h>
#include <sm/debug.h>
#include <sm/bitops.h>
@@ -26,14 +26,14 @@ SM_RCSID("@(#)$Id: clock.c,v 1.48 2013-11-22 20:51:42 ca Exp $")
#include "local.h"
#if _FFR_SLEEP_USE_SELECT > 0
# include <sys/types.h>
-#endif /* _FFR_SLEEP_USE_SELECT > 0 */
+#endif
#if defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2
# include <syslog.h>
-#endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */
+#endif
#ifndef sigmask
# define sigmask(s) (1 << ((s) - 1))
-#endif /* ! sigmask */
+#endif
/*
@@ -94,9 +94,9 @@ sm_sigsafe_seteventm(intvl, func, arg)
#if SM_CONF_SETITIMER
auto struct timeval now, nowi, ival;
auto struct itimerval itime;
-#else /* SM_CONF_SETITIMER */
+#else
auto time_t now, nowi;
-#endif /* SM_CONF_SETITIMER */
+#endif
int wasblocked;
/* negative times are not allowed */
@@ -122,9 +122,9 @@ sm_sigsafe_seteventm(intvl, func, arg)
{
#if SM_CONF_SETITIMER
if (timercmp(&(ev->ev_time), &nowi, >=))
-#else /* SM_CONF_SETITIMER */
+#else
if (ev->ev_time >= nowi)
-#endif /* SM_CONF_SETITIMER */
+#endif
break;
}
@@ -200,7 +200,7 @@ sm_clrevent(ev)
int wasblocked;
# if SM_CONF_SETITIMER
struct itimerval clr;
-# endif /* SM_CONF_SETITIMER */
+# endif
if (ev == NULL)
return;
@@ -260,7 +260,7 @@ sm_clear_events()
register SM_EVENT *ev;
#if SM_CONF_SETITIMER
struct itimerval clr;
-#endif /* SM_CONF_SETITIMER */
+#endif
int wasblocked;
/* nothing will be left in event queue, no need for an alarm */
@@ -325,7 +325,7 @@ sm_tick(sig)
#if SM_CONF_SETITIMER
struct itimerval clr;
struct timeval now;
-#else /* SM_CONF_SETITIMER */
+#else
register time_t now;
#endif /* SM_CONF_SETITIMER */
@@ -382,16 +382,16 @@ sm_tick(sig)
#if SM_CONF_SETITIMER
gettimeofday(&now, NULL);
-#else /* SM_CONF_SETITIMER */
+#else
now = time(NULL);
-#endif /* SM_CONF_SETITIMER */
+#endif
while ((ev = SmEventQueue) != NULL &&
(ev->ev_pid != mypid ||
#if SM_CONF_SETITIMER
timercmp(&ev->ev_time, &now, <=)
-#else /* SM_CONF_SETITIMER */
+#else
ev->ev_time <= now
-#endif /* SM_CONF_SETITIMER */
+#endif
))
{
void (*f)__P((int));
@@ -499,11 +499,11 @@ sm_tick(sig)
# if !HAVE_NANOSLEEP
static void sm_endsleep __P((int));
static bool volatile SmSleepDone;
-# endif /* !HAVE_NANOSLEEP */
+# endif
#ifndef SLEEP_T
# define SLEEP_T unsigned int
-#endif /* ! SLEEP_T */
+#endif
SLEEP_T
sleep(intvl)
@@ -525,13 +525,13 @@ sleep(intvl)
int r;
# if _FFR_SLEEP_USE_SELECT > 0
struct timeval sm_io_to;
-# endif /* _FFR_SLEEP_USE_SELECT > 0 */
+# endif
#endif /* _FFR_SLEEP_USE_SELECT > 0 */
#if SM_CONF_SETITIMER
struct timeval now, begin, diff;
# if _FFR_SLEEP_USE_SELECT > 0
struct timeval slpv;
-# endif /* _FFR_SLEEP_USE_SELECT > 0 */
+# endif
#else /* SM_CONF_SETITIMER */
time_t begin, now;
#endif /* SM_CONF_SETITIMER */
@@ -545,7 +545,7 @@ sleep(intvl)
intvl, _FFR_MAX_SLEEP_TIME);
# if 0
SM_ASSERT(intvl < (unsigned int) INT_MAX);
-# endif /* 0 */
+# endif
intvl = _FFR_MAX_SLEEP_TIME;
}
#endif /* defined(_FFR_MAX_SLEEP_TIME) && _FFR_MAX_SLEEP_TIME > 2 */
@@ -555,7 +555,7 @@ sleep(intvl)
# if _FFR_SLEEP_USE_SELECT > 0
slpv.tv_sec = intvl;
slpv.tv_usec = 0;
-# endif /* _FFR_SLEEP_USE_SELECT > 0 */
+# endif
(void) gettimeofday(&now, NULL);
begin = now;
#else /* SM_CONF_SETITIMER */
@@ -568,7 +568,7 @@ sleep(intvl)
/* COMPLAIN */
#if 0
syslog(LOG_ERR, "sleep: sm_setevent(%u) failed", intvl);
-#endif /* 0 */
+#endif
SmSleepDone = true;
}
was_held = sm_releasesignal(SIGALRM);
@@ -583,7 +583,7 @@ sleep(intvl)
break;
# if _FFR_SLEEP_USE_SELECT > 0
timersub(&slpv, &diff, &sm_io_to);
-# endif /* _FFR_SLEEP_USE_SELECT > 0 */
+# endif
#else /* SM_CONF_SETITIMER */
now = time(NULL);
diff --git a/contrib/sendmail/libsm/config.c b/contrib/sendmail/libsm/config.c
index b8f77d9bbe55..b96a4a0c8aba 100644
--- a/contrib/sendmail/libsm/config.c
+++ b/contrib/sendmail/libsm/config.c
@@ -172,89 +172,89 @@ char *SmCompileOptions[] =
{
#if SM_CONF_BROKEN_STRTOD
"SM_CONF_BROKEN_STRTOD",
-#endif /* SM_CONF_BROKEN_STRTOD */
+#endif
#if SM_CONF_GETOPT
"SM_CONF_GETOPT",
-#endif /* SM_CONF_GETOPT */
+#endif
#if SM_CONF_LDAP_INITIALIZE
"SM_CONF_LDAP_INITIALIZE",
-#endif /* SM_CONF_LDAP_INITIALIZE */
+#endif
#if SM_CONF_LDAP_MEMFREE
"SM_CONF_LDAP_MEMFREE",
-#endif /* SM_CONF_LDAP_MEMFREE */
+#endif
#if SM_CONF_LONGLONG
"SM_CONF_LONGLONG",
-#endif /* SM_CONF_LONGLONG */
+#endif
#if SM_CONF_MEMCHR
"SM_CONF_MEMCHR",
-#endif /* SM_CONF_MEMCHR */
+#endif
#if SM_CONF_MSG
"SM_CONF_MSG",
-#endif /* SM_CONF_MSG */
+#endif
#if SM_CONF_QUAD_T
"SM_CONF_QUAD_T",
-#endif /* SM_CONF_QUAD_T */
+#endif
#if SM_CONF_SEM
"SM_CONF_SEM",
-#endif /* SM_CONF_SEM */
+#endif
#if SM_CONF_SETITIMER
"SM_CONF_SETITIMER",
-#endif /* SM_CONF_SETITIMER */
+#endif
#if SM_CONF_SIGSETJMP
"SM_CONF_SIGSETJMP",
-#endif /* SM_CONF_SIGSETJMP */
+#endif
#if SM_CONF_SHM
"SM_CONF_SHM",
-#endif /* SM_CONF_SHM */
+#endif
#if SM_CONF_SHM_DELAY
"SM_CONF_SHM_DELAY",
-#endif /* SM_CONF_SHM_DELAY */
+#endif
#if SM_CONF_SSIZE_T
"SM_CONF_SSIZE_T",
-#endif /* SM_CONF_SSIZE_T */
+#endif
#if SM_CONF_STDBOOL_H
"SM_CONF_STDBOOL_H",
-#endif /* SM_CONF_STDBOOL_H */
+#endif
#if SM_CONF_STDDEF_H
"SM_CONF_STDDEF_H",
-#endif /* SM_CONF_STDDEF_H */
+#endif
#if 0
/* XXX this is always enabled (for now) */
#if SM_CONF_STRL
"SM_CONF_STRL",
-#endif /* SM_CONF_STRL */
+#endif
#endif /* 0 */
#if SM_CONF_SYS_CDEFS_H
"SM_CONF_SYS_CDEFS_H",
-#endif /* SM_CONF_SYS_CDEFS_H */
+#endif
#if SM_CONF_SYSEXITS_H
"SM_CONF_SYSEXITS_H",
-#endif /* SM_CONF_SYSEXITS_H */
+#endif
#if SM_CONF_UID_GID
"SM_CONF_UID_GID",
-#endif /* SM_CONF_UID_GID */
+#endif
#if DO_NOT_USE_STRCPY
"DO_NOT_USE_STRCPY",
-#endif /* DO_NOT_USE_STRCPY */
+#endif
#if SM_HEAP_CHECK
"SM_HEAP_CHECK",
-#endif /* SM_HEAP_CHECK */
+#endif
#if defined(SM_OS_NAME) && defined(__STDC__)
"SM_OS=sm_os_" SM_OS_NAME,
-#endif /* defined(SM_OS_NAME) && defined(__STDC__) */
+#endif
#if SM_VA_STD
"SM_VA_STD",
-#endif /* SM_VA_STD */
+#endif
#if USEKSTAT
"USEKSTAT",
-#endif /* USEKSTAT */
+#endif
#if USEPROCMEMINFO
"USEPROCMEMINFO",
-#endif /* USEPROCMEMINFO */
+#endif
#if USESWAPCTL
"USESWAPCTL",
-#endif /* USESWAPCTL */
+#endif
NULL
};
diff --git a/contrib/sendmail/libsm/debug.c b/contrib/sendmail/libsm/debug.c
index 0dbc25733f14..2ebef889380e 100644
--- a/contrib/sendmail/libsm/debug.c
+++ b/contrib/sendmail/libsm/debug.c
@@ -19,6 +19,8 @@ SM_RCSID("@(#)$Id: debug.c,v 1.33 2013-11-22 20:51:42 ca Exp $")
#include <stdlib.h>
#if _FFR_DEBUG_PID_TIME
#include <unistd.h>
+#include <sm/types.h>
+#include <sm/time.h>
#include <time.h>
#endif /* _FFR_DEBUG_PID_TIME */
#include <setjmp.h>
@@ -119,7 +121,7 @@ sm_debug_close()
#if _FFR_DEBUG_PID_TIME
SM_DEBUG_T SmDBGPidTime = SM_DEBUG_INITIALIZER("sm_trace_pid_time",
"@(#)$Debug: sm_trace_pid_time - print pid and time in debug $");
-#endif /* _FFR_DEBUG_PID_TIME */
+#endif
void
#if SM_VA_STD
@@ -131,12 +133,42 @@ sm_dprintf(fmt, va_alist)
#endif /* SM_VA_STD */
{
SM_VA_LOCAL_DECL
+#if _FFR_DEBUG_PID_TIME
+ static struct timeval lasttv;
+#endif
if (SmDebugOutput == NULL)
return;
#if _FFR_DEBUG_PID_TIME
/* note: this is ugly if the output isn't a full line! */
- if (sm_debug_active(&SmDBGPidTime, 1))
+ if (sm_debug_active(&SmDBGPidTime, 3))
+ {
+ struct timeval tv, tvd;
+
+ gettimeofday(&tv, NULL);
+ if (timerisset(&lasttv))
+ timersub(&tv, &lasttv, &tvd);
+ else
+ timerclear(&tvd);
+ sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout,
+ "%ld: %ld.%06ld ",
+ (long) getpid(),
+ (long) tvd.tv_sec,
+ (long) tvd.tv_usec);
+ lasttv = tv;
+ }
+ else if (sm_debug_active(&SmDBGPidTime, 2))
+ {
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ sm_io_fprintf(SmDebugOutput, SmDebugOutput->f_timeout,
+ "%ld: %ld.%06ld ",
+ (long) getpid(),
+ (long) tv.tv_sec,
+ (long) tv.tv_usec);
+ }
+ else if (sm_debug_active(&SmDBGPidTime, 1))
{
static char str[32] = "[1900-00-00/00:00:00] ";
struct tm *tmp;
diff --git a/contrib/sendmail/libsm/errstring.c b/contrib/sendmail/libsm/errstring.c
index 01d5a6419f41..fd1af9b5dcbf 100644
--- a/contrib/sendmail/libsm/errstring.c
+++ b/contrib/sendmail/libsm/errstring.c
@@ -27,7 +27,7 @@ SM_RCSID("@(#)$Id: errstring.c,v 1.20 2013-11-22 20:51:42 ca Exp $")
#if LDAPMAP
# include <lber.h>
# include <ldap.h> /* for LDAP error codes */
-#endif /* LDAPMAP */
+#endif
/*
** Notice: this file is used by libmilter. Please try to avoid
@@ -200,63 +200,63 @@ sm_errstring(errnum)
# 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 */
+# endif
# ifdef LDAP_URL_ERR_PARAM
case E_LDAPURLBASE + LDAP_URL_ERR_PARAM:
return "LDAP URL parameter is bad";
-# endif /* LDAP_URL_ERR_PARAM */
+# endif
# 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 */
+# endif
# ifdef LDAP_URL_ERR_BADENCLOSURE
case E_LDAPURLBASE + LDAP_URL_ERR_BADENCLOSURE:
return "LDAP URL is missing trailing \">\"";
-# endif /* LDAP_URL_ERR_BADENCLOSURE */
+# endif
# ifdef LDAP_URL_ERR_BADURL
case E_LDAPURLBASE + LDAP_URL_ERR_BADURL:
return "LDAP URL is bad";
-# endif /* LDAP_URL_ERR_BADURL */
+# endif
# ifdef LDAP_URL_ERR_BADHOST
case E_LDAPURLBASE + LDAP_URL_ERR_BADHOST:
return "LDAP URL host port is bad";
-# endif /* LDAP_URL_ERR_BADHOST */
+# endif
# ifdef LDAP_URL_ERR_BADATTRS
case E_LDAPURLBASE + LDAP_URL_ERR_BADATTRS:
return "LDAP URL bad (or missing) attributes";
-# endif /* LDAP_URL_ERR_BADATTRS */
+# endif
# 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 */
+# endif
# ifdef LDAP_URL_ERR_BADFILTER
case E_LDAPURLBASE + LDAP_URL_ERR_BADFILTER:
return "LDAP URL bad or missing filter";
-# endif /* LDAP_URL_ERR_BADFILTER */
+# endif
# ifdef LDAP_URL_ERR_BADEXTS
case E_LDAPURLBASE + LDAP_URL_ERR_BADEXTS:
return "LDAP URL bad or missing extensions";
-# endif /* LDAP_URL_ERR_BADEXTS */
+# endif
/* 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 */
+# endif
# 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
#endif /* LDAPMAP */
}
diff --git a/contrib/sendmail/libsm/exc.c b/contrib/sendmail/libsm/exc.c
index d9ebe4419c84..4824d5f9bd0c 100644
--- a/contrib/sendmail/libsm/exc.c
+++ b/contrib/sendmail/libsm/exc.c
@@ -229,12 +229,12 @@ const SM_EXC_TYPE_T SmEtypeErr =
** an out-of-memory exception so that exc is not leaked.
*/
-static SM_EXC_T *sm_exc_vnew_x __P((const SM_EXC_TYPE_T *, va_list SM_NONVOLATILE));
+static SM_EXC_T *sm_exc_vnew_x __P((const SM_EXC_TYPE_T *, va_list));
static SM_EXC_T *
sm_exc_vnew_x(etype, ap)
const SM_EXC_TYPE_T *etype;
- va_list SM_NONVOLATILE ap;
+ va_list ap;
{
/*
** All variables that are modified in the SM_TRY clause and
diff --git a/contrib/sendmail/libsm/findfp.c b/contrib/sendmail/libsm/findfp.c
index 25f7663e8797..1b2ed884d499 100644
--- a/contrib/sendmail/libsm/findfp.c
+++ b/contrib/sendmail/libsm/findfp.c
@@ -327,11 +327,10 @@ sm_io_setinfo(fp, what, valp)
** SM_IO_GETINFO -- get information for an active file type (fp)
**
** This function supplies for all file types the answers for the
-** three requests SM_IO_WHAT_VECTORS, SM_IO_WHAT_TYPE and
-** SM_IO_WHAT_ISTYPE. Other requests are handled by the getinfo
+** three requests SM_IO_WHAT_VECTORS, and SM_IO_WHAT_ISTYPE.
+** Other requests are handled by the getinfo
** vector if available for the open file type.
** SM_IO_WHAT_VECTORS returns information for the file pointer vectors.
-** SM_IO_WHAT_TYPE returns the type identifier for the file pointer
** SM_IO_WHAT_ISTYPE returns >0 if the passed in type matches the
** file pointer's type.
** SM_IO_IS_READABLE returns 1 if there is data available for reading,
@@ -345,8 +344,8 @@ sm_io_setinfo(fp, what, valp)
** Returns:
** -1 on error and sets errno:
** - when valp==NULL and request expects otherwise
-** - when request is not SM_IO_WHAT_VECTORS and not
-** SM_IO_WHAT_TYPE and not SM_IO_WHAT_ISTYPE
+** - when request is not SM_IO_WHAT_VECTORS
+** and not SM_IO_WHAT_ISTYPE
** and getinfo vector is NULL
** - when getinfo type vector returns -1
** >=0 on success
@@ -382,15 +381,6 @@ sm_io_getinfo(fp, what, valp)
v->f_type = fp->f_type;
return 0;
- case SM_IO_WHAT_TYPE:
- if (valp == NULL)
- {
- errno = EINVAL;
- return -1;
- }
- valp = sm_strdup_x(fp->f_type);
- return 0;
-
case SM_IO_WHAT_ISTYPE:
if (valp == NULL)
{
diff --git a/contrib/sendmail/libsm/flags.c b/contrib/sendmail/libsm/flags.c
index 0786b026ffe4..49853271af5d 100644
--- a/contrib/sendmail/libsm/flags.c
+++ b/contrib/sendmail/libsm/flags.c
@@ -23,7 +23,7 @@ SM_RCSID("@(#)$Id: flags.c,v 1.24 2013-11-22 20:51:42 ca Exp $")
/*
** SM_FLAGS -- translate external (user) flags into internal flags
**
-** Paramters:
+** Parameters:
** flags -- user select flags
**
** Returns:
diff --git a/contrib/sendmail/libsm/fopen.c b/contrib/sendmail/libsm/fopen.c
index 33ddc6015b9b..7dd1751c98b3 100644
--- a/contrib/sendmail/libsm/fopen.c
+++ b/contrib/sendmail/libsm/fopen.c
@@ -89,7 +89,7 @@ reopenalrm(sig)
** Parameters:
** type -- type of file to open
** timeout -- time to complete the open
-** info -- info describing what is to be opened (type dependant)
+** info -- info describing what is to be opened (type dependent)
** flags -- user selected flags
** rpool -- pointer to rpool to be used for this open
**
@@ -159,7 +159,7 @@ sm_io_open(type, timeout, info, flags, rpool)
#if SM_RPOOL
if (rpool != NULL)
sm_rpool_attach_x(rpool, sm_io_fclose, fp);
-#endif /* SM_RPOOL */
+#endif
return fp;
}
@@ -205,7 +205,7 @@ sm_io_dup(fp)
** Parameters:
** type -- file type to be opened
** timeout -- time to complete the reopen
-** info -- infomation about what is to be "re-opened" (type dep.)
+** info -- information about what is to be "re-opened" (type dep.)
** flags -- user flags to map to internal flags
** rpool -- rpool file to be associated with
** fp -- the file pointer to reuse
@@ -311,7 +311,7 @@ sm_io_reopen(type, timeout, info, flags, rpool, fp)
#if SM_RPOOL
if (rpool != NULL)
sm_rpool_attach_x(rpool, sm_io_close, fp2);
-#endif /* SM_RPOOL */
+#endif
return fp2;
}
diff --git a/contrib/sendmail/libsm/fpos.c b/contrib/sendmail/libsm/fpos.c
index 30015f57599b..fc21f84d7c43 100644
--- a/contrib/sendmail/libsm/fpos.c
+++ b/contrib/sendmail/libsm/fpos.c
@@ -57,7 +57,7 @@ tellalrm(sig)
/*
** SM_IO_TELL -- position the file pointer
**
-** Paramters:
+** Parameters:
** fp -- the file pointer to get repositioned
** timeout -- time to complete the tell (milliseconds)
**
diff --git a/contrib/sendmail/libsm/fscanf.c b/contrib/sendmail/libsm/fscanf.c
index c45ef3a3cad0..0ca6f6f2d2db 100644
--- a/contrib/sendmail/libsm/fscanf.c
+++ b/contrib/sendmail/libsm/fscanf.c
@@ -26,7 +26,7 @@ SM_RCSID("@(#)$Id: fscanf.c,v 1.18 2013-11-22 20:51:42 ca Exp $")
** fp -- the file pointer to obtain the data from
** timeout -- time to complete scan
** fmt -- the format to translate the data to
-** ... -- memory locations to place the formated data
+** ... -- memory locations to place the formatted data
**
** Returns:
** Failure: returns SM_IO_EOF
diff --git a/contrib/sendmail/libsm/io.html b/contrib/sendmail/libsm/io.html
index 5304d26236bd..3efdfebb58c7 100644
--- a/contrib/sendmail/libsm/io.html
+++ b/contrib/sendmail/libsm/io.html
@@ -155,8 +155,7 @@ raising exceptions later.
<a href="#defaultapi">int sm_snprintf(char *str, size_t n, char const *fmt, ...)</a>
</pre>
-<a name="timeouts">
-<h2>Timeouts</h2>
+<h2><a name="timeouts">Timeouts</a></h2>
<p>
For many of the functions a <i>timeout</i> argument is given. This limits
the amount of time allowed for the function to complete. There are three
@@ -313,7 +312,7 @@ This will make the change for this SM_FILE_T only. The file
type that <i>sfp</i> originally belonged to will still be
configured the same way (this is to prevent side-effect
to other open's of the same file type, particularly with threads).
-The value of <i>what</i> will be file-type dependant since this function
+The value of <i>what</i> will be file-type dependent since this function
is one of the per file type setable functions.
One value for <i>what</i> that is valid for all file types is
SM_WHAT_VECTORS. This sets the currently open file with a new function
@@ -336,7 +335,7 @@ For the open file <i>sfp</i> get the indicated information (<i>what</i>)
and place the result in <i>(valp</i>).
This will obtain information for SM_FILE_T only and may be different than
the information for the file type it was originally opened as.
-The value of <i>what</i> will be file type dependant since this function
+The value of <i>what</i> will be file type dependent since this function
is one of the per file type setable functions.
One value for <i>what</i> that is valid for all file types is
SM_WHAT_VECTORS. This gets from the currently open file a copy of
@@ -370,7 +369,7 @@ previous association.
void
<br>
sm_io_automode(SM_FILE_T *fp1, *SM_FILE_T fp2)
-<dt><tt><a name="sm_io_automode">
+<dt>
</a></tt></dt>
<dd>
Associate the two file pointers for blocking/non-blocking mode changes.
@@ -379,7 +378,7 @@ a file between blocking and non-blocking. If the underlying file descriptor
has been duplicated with <tt>dup(2)</tt> and these descriptors are used
by <i>sm_io</i> (for example with an SmFtStdiofd file type), then this API
should be called to associate them. Otherwise odd behavior (i.e. errors)
-may result that is not consistently reproducable nor easily identifiable.
+may result that is not consistently reproducible nor easily identifiable.
</dd>
<!-- SM_IO_CLOSE -->
<p></p>
@@ -456,7 +455,7 @@ The three types <i>smioin</i>, <i>smioout</i> and <i>smioerr</i> are grouped
together. These three types
perform in the same manner as <b>stdio</b>'s <i>stdin</i>, <i>stdout</i>
and <i>stderr</i>. These types are both the names and the file pointers.
-They are already open when a program starts (unless the parent explictly
+They are already open when a program starts (unless the parent explicitly
closed file descriptors 0, 1 and 2).
Thus <tt>sm_io_open()</tt> should never be called for these types:
the named file pointers should be used directly.
@@ -477,7 +476,7 @@ The three types <i>smiostdin</i>, <i>smioostdut</i> and <i>smiostderr</i>
are grouped together. These three types
perform in the same manner as <b>stdio</b>'s <i>stdin</i>, <i>stdout</i>
and <i>stderr</i>. These types are both the names and file pointers.
-They are already open when a program starts (unless the parent explictly
+They are already open when a program starts (unless the parent explicitly
close file descriptors 0, 1 and 2).
Thus <tt>sm_io_open()</tt> should
never be called: the named file pointers should be used directly.
@@ -733,7 +732,7 @@ if a "file pointer" (FILE/SM_FILE_T)
is one of the arguments for the function, then it is now the first
argument. <i>Sm_io</i> is standardized so that when a file pointer is
one of the arguments to function then it will always be the first
-arguement. Many of the <i>sm_io</i> function take a <i>timeout</i>
+argument. Many of the <i>sm_io</i> function take a <i>timeout</i>
argument (see <a href="#timeouts"><b>Timeouts</b></a>).
</p>
<p>
diff --git a/contrib/sendmail/libsm/ldap.c b/contrib/sendmail/libsm/ldap.c
index 9359aedfdeda..116dc8fac343 100644
--- a/contrib/sendmail/libsm/ldap.c
+++ b/contrib/sendmail/libsm/ldap.c
@@ -29,13 +29,12 @@ SM_RCSID("@(#)$Id: ldap.c,v 1.86 2013-11-22 20:51:43 ca Exp $")
# include <sm/string.h>
# ifdef EX_OK
# undef EX_OK /* for SVr4.2 SMP */
-# endif /* EX_OK */
+# endif
# include <sm/sysexits.h>
SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap",
"@(#)$Debug: sm_trace_ldap - trace LDAP operations $");
-static void ldaptimeout __P((int));
static bool sm_ldap_has_objectclass __P((SM_LDAP_STRUCT *, LDAPMessage *, char *));
static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **, char *, int, SM_RPOOL_T *));
@@ -53,10 +52,10 @@ static SM_LDAP_RECURSE_ENTRY *sm_ldap_add_recurse __P((SM_LDAP_RECURSE_LIST **,
#if _FFR_LDAP_VERSION
# if defined(LDAP_VERSION_MAX) && _FFR_LDAP_VERSION > LDAP_VERSION_MAX
ERROR FFR_LDAP_VERSION > _LDAP_VERSION_MAX
-# endif /* defined(LDAP_VERSION_MAX) && _FFR_LDAP_VERSION > LDAP_VERSION_MAX */
+# endif
# if defined(LDAP_VERSION_MIN) && _FFR_LDAP_VERSION < LDAP_VERSION_MIN
ERROR FFR_LDAP_VERSION < _LDAP_VERSION_MIN
-# endif /* defined(LDAP_VERSION_MIN) && _FFR_LDAP_VERSION < LDAP_VERSION_MIN */
+# endif
# define SM_LDAP_VERSION_DEFAULT _FFR_LDAP_VERSION
#else /* _FFR_LDAP_VERSION */
# define SM_LDAP_VERSION_DEFAULT 0
@@ -78,9 +77,9 @@ sm_ldap_clear(lmap)
lmap->ldap_sizelimit = LDAP_NO_LIMIT;
# ifdef LDAP_REFERRALS
lmap->ldap_options = LDAP_OPT_REFERRALS;
-# else /* LDAP_REFERRALS */
+# else
lmap->ldap_options = 0;
-# endif /* LDAP_REFERRALS */
+# endif
lmap->ldap_attrsep = '\0';
lmap->ldap_binddn = NULL;
lmap->ldap_secret = NULL;
@@ -101,6 +100,147 @@ sm_ldap_clear(lmap)
lmap->ldap_multi_args = false;
}
+# if _FFR_SM_LDAP_DBG && defined(LBER_OPT_LOG_PRINT_FN)
+static void ldap_debug_cb __P((const char *msg));
+
+static void
+ldap_debug_cb(msg)
+ const char *msg;
+{
+ if (sm_debug_active(&SmLDAPTrace, 4))
+ sm_dprintf("%s", msg);
+}
+# endif /* _FFR_SM_LDAP_DBG && defined(LBER_OPT_LOG_PRINT_FN) */
+
+
+# if LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT)
+# define SET_LDAP_TMO(ld, lmap) \
+ do \
+ { \
+ if (lmap->ldap_networktmo > 0) \
+ { \
+ struct timeval tmo; \
+ \
+ if (sm_debug_active(&SmLDAPTrace, 9)) \
+ sm_dprintf("ldap_networktmo=%d\n", \
+ lmap->ldap_networktmo); \
+ tmo.tv_sec = lmap->ldap_networktmo; \
+ tmo.tv_usec = 0; \
+ ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tmo); \
+ } \
+ } while (0)
+# else /* LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) */
+# define SET_LDAP_TMO(ld, lmap)
+# endif /* LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) */
+
+/*
+** SM_LDAP_SETOPTSG -- set some (global) LDAP options
+**
+** Parameters:
+** lmap -- LDAP map information
+**
+** Returns:
+** None.
+**
+*/
+
+# if _FFR_SM_LDAP_DBG
+static bool dbg_init = false;
+# endif
+# if SM_CONF_LDAP_INITIALIZE
+static void sm_ldap_setoptsg __P((SM_LDAP_STRUCT *lmap));
+static void
+sm_ldap_setoptsg(lmap)
+ SM_LDAP_STRUCT *lmap;
+{
+# if USE_LDAP_SET_OPTION
+
+ SET_LDAP_TMO(NULL, lmap);
+
+# if _FFR_SM_LDAP_DBG
+ if (!dbg_init && sm_debug_active(&SmLDAPTrace, 1) &&
+ lmap->ldap_debug != 0)
+ {
+ int r;
+# if defined(LBER_OPT_LOG_PRINT_FN)
+ r = ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN, ldap_debug_cb);
+# endif
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_debug0=%d\n", lmap->ldap_debug);
+ r = ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
+ &(lmap->ldap_debug));
+ if (sm_debug_active(&SmLDAPTrace, 9) && r != LDAP_OPT_SUCCESS)
+ sm_dprintf("ber_set_option=%d\n", r);
+ r = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL,
+ &(lmap->ldap_debug));
+ if (sm_debug_active(&SmLDAPTrace, 9) && r != LDAP_OPT_SUCCESS)
+ sm_dprintf("ldap_set_option=%d\n", r);
+ dbg_init = true;
+ }
+# endif /* _FFR_SM_LDAP_DBG */
+# endif /* USE_LDAP_SET_OPTION */
+}
+# endif /* SM_CONF_LDAP_INITIALIZE */
+
+/*
+** SM_LDAP_SETOPTS -- set LDAP options
+**
+** Parameters:
+** ld -- LDAP session handle
+** lmap -- LDAP map information
+**
+** Returns:
+** None.
+**
+*/
+
+void
+sm_ldap_setopts(ld, lmap)
+ LDAP *ld;
+ SM_LDAP_STRUCT *lmap;
+{
+# if USE_LDAP_SET_OPTION
+ if (lmap->ldap_version != 0)
+ {
+ ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
+ &lmap->ldap_version);
+ }
+ 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);
+ else
+ ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
+ ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &lmap->ldap_sizelimit);
+ ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &lmap->ldap_timelimit);
+ SET_LDAP_TMO(ld, lmap);
+# if _FFR_SM_LDAP_DBG
+ if ((!dbg_init || ld != NULL) && sm_debug_active(&SmLDAPTrace, 1)
+ && lmap->ldap_debug > 0)
+ {
+ int r;
+
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_debug=%d, dbg_init=%d\n",
+ lmap->ldap_debug, dbg_init);
+ r = ldap_set_option(ld, LDAP_OPT_DEBUG_LEVEL,
+ &(lmap->ldap_debug));
+ if (sm_debug_active(&SmLDAPTrace, 9) && r != LDAP_OPT_SUCCESS)
+ sm_dprintf("ldap_set_option=%d\n", r);
+ }
+# endif /* _FFR_SM_LDAP_DBG */
+# ifdef LDAP_OPT_RESTART
+ ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
+# endif
+
+# else /* USE_LDAP_SET_OPTION */
+ /* From here on in we can use ldap internal timelimits */
+ ld->ld_deref = lmap->ldap_deref;
+ ld->ld_options = lmap->ldap_options;
+ ld->ld_sizelimit = lmap->ldap_sizelimit;
+ ld->ld_timelimit = lmap->ldap_timelimit;
+# endif /* USE_LDAP_SET_OPTION */
+}
+
/*
** SM_LDAP_START -- actually connect to an LDAP server
**
@@ -115,15 +255,36 @@ sm_ldap_clear(lmap)
** Populates lmap->ldap_ld.
*/
+# if !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT
static jmp_buf LDAPTimeout;
+static void ldaptimeout __P((int));
+
+/* ARGSUSED */
+static void
+ldaptimeout(unused)
+ int unused;
+{
+ /*
+ ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
+ ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
+ ** DOING.
+ */
+
+ errno = ETIMEDOUT;
+ longjmp(LDAPTimeout, 1);
+}
+
-#define SM_LDAP_SETTIMEOUT(to) \
+#define SM_LDAP_SETTIMEOUT(to, where) \
do \
{ \
if (to != 0) \
{ \
if (setjmp(LDAPTimeout) != 0) \
{ \
+ if (sm_debug_active(&SmLDAPTrace, 9)) \
+ sm_dprintf("ldap_settimeout(%s)=triggered\n",\
+ where); \
errno = ETIMEDOUT; \
return false; \
} \
@@ -137,17 +298,21 @@ do \
if (ev != NULL) \
sm_clrevent(ev); \
} while (0)
+#endif /* !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT */
bool
sm_ldap_start(name, lmap)
char *name;
SM_LDAP_STRUCT *lmap;
{
- int bind_result;
int save_errno = 0;
char *id;
+# if !USE_LDAP_INIT || !LDAP_NETWORK_TIMEOUT
SM_EVENT *ev = NULL;
+# endif
LDAP *ld = NULL;
+ struct timeval tmo;
+ int msgid, err, r;
if (sm_debug_active(&SmLDAPTrace, 2))
sm_dprintf("ldapmap_start(%s)\n", name == NULL ? "" : name);
@@ -172,10 +337,15 @@ sm_ldap_start(name, lmap)
if (lmap->ldap_uri != NULL)
{
#if SM_CONF_LDAP_INITIALIZE
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_initialize(%s)\n", lmap->ldap_uri);
/* LDAP server supports URIs so use them directly */
save_errno = ldap_initialize(&ld, lmap->ldap_uri);
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_initialize(%s)=%d, ld=%p\n", lmap->ldap_uri, save_errno, ld);
+ sm_ldap_setoptsg(lmap);
+
#else /* SM_CONF_LDAP_INITIALIZE */
- int err;
LDAPURLDesc *ludp = NULL;
/* Blast apart URL and use the ldap_init/ldap_open below */
@@ -201,8 +371,11 @@ sm_ldap_start(name, lmap)
if (ld == NULL)
{
# if USE_LDAP_INIT
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_init(%s, %d)\n", lmap->ldap_host, lmap->ldap_port);
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
@@ -210,7 +383,10 @@ sm_ldap_start(name, lmap)
** the connection happens at bind time.
*/
- SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec);
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_open(%s, %d)\n", lmap->ldap_host, lmap->ldap_port);
+
+ SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec, "ldap_open");
ld = ldap_open(lmap->ldap_host, lmap->ldap_port);
save_errno = errno;
@@ -221,18 +397,21 @@ sm_ldap_start(name, lmap)
errno = save_errno;
if (ld == NULL)
+ {
+ if (sm_debug_active(&SmLDAPTrace, 7))
+ sm_dprintf("FAIL: ldap_open(%s, %d)=%d\n", lmap->ldap_host, lmap->ldap_port, save_errno);
return false;
+ }
sm_ldap_setopts(ld, lmap);
-
-# if USE_LDAP_INIT
+# if USE_LDAP_INIT && !LDAP_NETWORK_TIMEOUT
/*
** If using ldap_init(), the actual connection to the server
** happens at ldap_bind_s() so we need the timeout here.
*/
- SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec);
-# endif /* USE_LDAP_INIT */
+ SM_LDAP_SETTIMEOUT(lmap->ldap_timeout.tv_sec, "ldap_bind");
+# endif /* USE_LDAP_INIT && !LDAP_NETWORK_TIMEOUT */
# ifdef LDAP_AUTH_KRBV4
if (lmap->ldap_method == LDAP_AUTH_KRBV4 &&
@@ -248,17 +427,68 @@ sm_ldap_start(name, lmap)
}
# endif /* LDAP_AUTH_KRBV4 */
- bind_result = ldap_bind_s(ld, lmap->ldap_binddn,
- lmap->ldap_secret, lmap->ldap_method);
+# if LDAP_NETWORK_TIMEOUT
+ tmo.tv_sec = lmap->ldap_networktmo;
+# else
+ tmo.tv_sec = lmap->ldap_timeout.tv_sec;
+# endif
+ tmo.tv_usec = 0;
-# if USE_LDAP_INIT
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_bind(%s)\n", lmap->ldap_uri);
+ errno = 0;
+ msgid = ldap_bind(ld, lmap->ldap_binddn, lmap->ldap_secret,
+ lmap->ldap_method);
+ save_errno = errno;
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_bind(%s)=%d, errno=%d, tmo=%ld\n",
+ lmap->ldap_uri, msgid, save_errno,
+ (long) tmo.tv_sec);
+ if (-1 == msgid)
+ {
+ r = -1;
+ goto fail;
+ }
+
+ errno = 0;
+ r = ldap_result(ld, msgid, LDAP_MSG_ALL,
+ tmo.tv_sec == 0 ? NULL : &(tmo), &(lmap->ldap_res));
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_result(%s)=%d, errno=%d\n", lmap->ldap_uri, r, errno);
+ if (-1 == r)
+ goto fail;
+ if (0 == r)
+ {
+ save_errno = ETIMEDOUT;
+ r = -1;
+ goto fail;
+ }
+ r = ldap_parse_result(ld, lmap->ldap_res, &err, NULL, NULL, NULL, NULL,
+ 1);
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_parse_result(%s)=%d, err=%d\n", lmap->ldap_uri, r, err);
+ if (r != LDAP_SUCCESS)
+ goto fail;
+ if (err != LDAP_SUCCESS)
+ {
+ r = -1;
+ goto fail;
+ }
+
+# if USE_LDAP_INIT && !LDAP_NETWORK_TIMEOUT
/* clear the event if it has not sprung */
SM_LDAP_CLEARTIMEOUT();
-# endif /* USE_LDAP_INIT */
+ if (sm_debug_active(&SmLDAPTrace, 9))
+ sm_dprintf("ldap_cleartimeout(%s)\n", lmap->ldap_uri);
+# endif /* USE_LDAP_INIT && !LDAP_NETWORK_TIMEOUT */
- if (bind_result != LDAP_SUCCESS)
+ if (r != LDAP_SUCCESS)
{
- errno = bind_result + E_LDAPBASE;
+ fail:
+ if (-1 == r)
+ errno = save_errno;
+ else
+ errno = r + E_LDAPBASE;
return false;
}
@@ -268,21 +498,6 @@ sm_ldap_start(name, lmap)
return true;
}
-/* ARGSUSED */
-static void
-ldaptimeout(unused)
- int unused;
-{
- /*
- ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
- ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
- ** DOING.
- */
-
- errno = ETIMEDOUT;
- longjmp(LDAPTimeout, 1);
-}
-
/*
** SM_LDAP_SEARCH_M -- initiate multi-key LDAP search
**
@@ -292,7 +507,7 @@ ldaptimeout(unused)
** Parameters:
** lmap -- LDAP map information
** argv -- key vector of substitutions in LDAP filter
-** NOTE: argv must have SM_LDAP_ARGS elements to prevent
+** NOTE: argv must have SM_LDAP_ARGS elements to prevent
** out of bound array references
**
** Returns:
@@ -1361,59 +1576,6 @@ sm_ldap_close(lmap)
lmap->ldap_ld = NULL;
lmap->ldap_pid = 0;
}
-
-/*
-** SM_LDAP_SETOPTS -- set LDAP options
-**
-** Parameters:
-** ld -- LDAP session handle
-** lmap -- LDAP map information
-**
-** Returns:
-** None.
-**
-*/
-
-void
-sm_ldap_setopts(ld, lmap)
- LDAP *ld;
- SM_LDAP_STRUCT *lmap;
-{
-# if USE_LDAP_SET_OPTION
- if (lmap->ldap_version != 0)
- {
- ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
- &lmap->ldap_version);
- }
- 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);
- else
- ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
- ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &lmap->ldap_sizelimit);
- ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &lmap->ldap_timelimit);
-# if _FFR_LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT)
- if (lmap->ldap_networktmo > 0)
- {
- struct timeval tmo;
-
- tmo.tv_sec = lmap->ldap_networktmo;
- tmo.tv_usec = 0;
- ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, &tmo);
- }
-# endif /* _FFR_LDAP_NETWORK_TIMEOUT && defined(LDAP_OPT_NETWORK_TIMEOUT) */
-# ifdef LDAP_OPT_RESTART
- ldap_set_option(ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
-# endif /* LDAP_OPT_RESTART */
-# else /* USE_LDAP_SET_OPTION */
- /* From here on in we can use ldap internal timelimits */
- ld->ld_deref = lmap->ldap_deref;
- ld->ld_options = lmap->ldap_options;
- ld->ld_sizelimit = lmap->ldap_sizelimit;
- ld->ld_timelimit = lmap->ldap_timelimit;
-# endif /* USE_LDAP_SET_OPTION */
-}
-
/*
** SM_LDAP_GETERRNO -- get ldap errno value
**
@@ -1432,11 +1594,16 @@ sm_ldap_geterrno(ld)
int err = LDAP_SUCCESS;
# if defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3
- (void) ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &err);
-# else /* defined(LDAP_VERSION_MAX) && LDAP_VERSION_MAX >= 3 */
+# ifdef LDAP_OPT_RESULT_CODE
+# define LDAP_GET_RESULT_CODE LDAP_OPT_RESULT_CODE
+# else
+# define LDAP_GET_RESULT_CODE LDAP_OPT_ERROR_NUMBER
+# endif
+ (void) ldap_get_option(ld, LDAP_GET_RESULT_CODE, &err);
+# else
# ifdef LDAP_OPT_SIZELIMIT
err = ldap_get_lderrno(ld, NULL, NULL);
-# else /* LDAP_OPT_SIZELIMIT */
+# else
err = ld->ld_errno;
/*
diff --git a/contrib/sendmail/libsm/local.h b/contrib/sendmail/libsm/local.h
index 304a52e292ce..0118d6169676 100644
--- a/contrib/sendmail/libsm/local.h
+++ b/contrib/sendmail/libsm/local.h
@@ -23,7 +23,7 @@
#include <sm/fdset.h>
#if !SM_CONF_MEMCHR
# include <memory.h>
-#endif /* !SM_CONF_MEMCHR */
+#endif
#include <sm/heap.h>
int sm_flush __P((SM_FILE_T *, int *));
diff --git a/contrib/sendmail/libsm/makebuf.c b/contrib/sendmail/libsm/makebuf.c
index 8d05e68bcb9c..2542d2982d6a 100644
--- a/contrib/sendmail/libsm/makebuf.c
+++ b/contrib/sendmail/libsm/makebuf.c
@@ -114,7 +114,7 @@ sm_whatbuf(fp, bufsize, couldbetty)
#if SM_IO_MAX_BUF_FILE > 0
if (S_ISREG(st.st_mode) && st.st_blksize > SM_IO_MAX_BUF_FILE)
st.st_blksize = SM_IO_MAX_BUF_FILE;
-#endif /* SM_IO_MAX_BUF_FILE > 0 */
+#endif
#if SM_IO_MAX_BUF > 0 || SM_IO_MIN_BUF > 0
if (!S_ISREG(st.st_mode))
@@ -129,7 +129,7 @@ sm_whatbuf(fp, bufsize, couldbetty)
# if SM_IO_MIN_BUF > 0
if (st.st_blksize < SM_IO_MIN_BUF)
st.st_blksize = SM_IO_MIN_BUF;
-# endif /* SM_IO_MIN_BUF > 0 */
+# endif
}
#endif /* SM_IO_MAX_BUF > 0 || SM_IO_MIN_BUF > 0 */
diff --git a/contrib/sendmail/libsm/mbdb.c b/contrib/sendmail/libsm/mbdb.c
index 3d7426cd5315..ff2d3d8150fa 100644
--- a/contrib/sendmail/libsm/mbdb.c
+++ b/contrib/sendmail/libsm/mbdb.c
@@ -29,13 +29,13 @@ SM_RCSID("@(#)$Id: mbdb.c,v 1.43 2014-01-08 17:03:15 ca Exp $")
#include <sm/string.h>
# ifdef EX_OK
# undef EX_OK /* for SVr4.2 SMP */
-# endif /* EX_OK */
+# endif
#include <sm/sysexits.h>
#if LDAPMAP
# if _LDAP_EXAMPLE_
# include <sm/ldap.h>
-# endif /* _LDAP_EXAMPLE_ */
+# endif
#endif /* LDAPMAP */
typedef struct
@@ -65,7 +65,7 @@ static SM_MBDB_TYPE_T SmMbdbTypes[] =
#if LDAPMAP
# if _LDAP_EXAMPLE_
{ "ldap", mbdb_ldap_initialize, mbdb_ldap_lookup, mbdb_ldap_terminate },
-# endif /* _LDAP_EXAMPLE_ */
+# endif
#endif /* LDAPMAP */
{ NULL, NULL, NULL, NULL }
};
@@ -267,7 +267,7 @@ sm_pwfullname(gecos, user, buf, buflen)
if ((unsigned char) *p >= 128)
*bp++ = Latin1ToASCII[(unsigned char) *p - 128];
else
-#endif /* _FFR_HANDLE_ISO8859_GECOS */
+#endif
*bp++ = *p;
}
}
@@ -408,15 +408,15 @@ mbdb_pw_terminate()
# ifndef MBDB_LDAP_FILTER
# define MBDB_LDAP_FILTER "(&(objectClass=posixAccount)(uid=%0))"
-# endif /* MBDB_LDAP_FILTER */
+# endif
# ifndef MBDB_DEFAULT_LDAP_BASEDN
# define MBDB_DEFAULT_LDAP_BASEDN NULL
-# endif /* MBDB_DEFAULT_LDAP_BASEDN */
+# endif
# ifndef MBDB_DEFAULT_LDAP_SERVER
# define MBDB_DEFAULT_LDAP_SERVER NULL
-# endif /* MBDB_DEFAULT_LDAP_SERVER */
+# endif
/*
** MBDB_LDAP_INITIALIZE -- initialize LDAP version
@@ -559,7 +559,7 @@ mbdb_ldap_lookup(name, user)
{
int rc;
- /*
+ /*
** We may have gotten an LDAP_RES_SEARCH_RESULT response
** with an error inside it, so we have to extract that
** with ldap_parse_result(). This can happen when talking
diff --git a/contrib/sendmail/libsm/memstat.c b/contrib/sendmail/libsm/memstat.c
index a58b4c2ed3e8..4ef49fad31d5 100644
--- a/contrib/sendmail/libsm/memstat.c
+++ b/contrib/sendmail/libsm/memstat.c
@@ -111,7 +111,7 @@ sm_memstat_open()
return (errno != 0) ? errno : -1;
kst = kstat_lookup(kc, "unix", 0,
(name != NULL) ? name : "system_pages");
- if (kst == 0)
+ if (kst == NULL)
return (errno != 0) ? errno : -2;
return 0;
}
diff --git a/contrib/sendmail/libsm/niprop.c b/contrib/sendmail/libsm/niprop.c
index ca60e38f53c5..a5056deb34c6 100644
--- a/contrib/sendmail/libsm/niprop.c
+++ b/contrib/sendmail/libsm/niprop.c
@@ -99,7 +99,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
if (tTd(38, 21))
sm_dprintf("ni_propval(%s, %s, %s, %s, %d) keybuf='%s'\n",
keydir, keyprop, keyval, valprop, sepchar, keybuf);
-#endif /* 0 */
+#endif
/*
** If the passed directory and property name are found
@@ -117,7 +117,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
#if 0
if (tTd(38, 20))
sm_dprintf("ni_open(LOCAL) = %d\n", nis);
-#endif /* 0 */
+#endif
}
else
{
@@ -128,7 +128,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
#if 0
if (tTd(38, 20))
sm_dprintf("ni_open(PARENT) = %d\n", nis);
-#endif /* 0 */
+#endif
}
/*
@@ -160,7 +160,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
if (tTd(38, 20))
sm_dprintf("ni_lookupprop: len=%d\n",
ninl.ni_namelist_len);
-#endif /* 0 */
+#endif
/*
** See if we have an acceptable number of values.
@@ -206,7 +206,7 @@ ni_propval(keydir, keyprop, keyval, valprop, sepchar)
#if 0
if (tTd(38, 20))
sm_dprintf("ni_propval returns: '%s'\n", propval);
-#endif /* 0 */
+#endif
return propval;
}
diff --git a/contrib/sendmail/libsm/notify.c b/contrib/sendmail/libsm/notify.c
new file mode 100644
index 000000000000..9f4cca27d7a8
--- /dev/null
+++ b/contrib/sendmail/libsm/notify.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ */
+
+#include <sm/gen.h>
+
+#include <sys/types.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h> /* for memset() */
+
+#include <sm/conf.h> /* FDSET_CAST */
+#include <sm/fdset.h>
+#include <sm/assert.h>
+#include <sm/notify.h>
+
+#if SM_NOTIFY_DEBUG
+#define SM_DBG(p) fprintf p
+#else
+#define SM_DBG(p)
+#endif
+
+static int Notifypipe[2];
+#define NotifyRDpipe Notifypipe[0]
+#define NotifyWRpipe Notifypipe[1]
+
+#define CLOSEFD(fd) do { \
+ if ((fd) != -1) { \
+ (void) close(fd); \
+ fd = - 1; \
+ } \
+ } while (0) \
+
+
+/*
+** SM_NOTIFY_INIT -- initialize notify system
+**
+** Parameters:
+** flags -- ignored
+**
+** Returns:
+** 0: success
+** <0: -errno
+*/
+
+int
+sm_notify_init(flags)
+ int flags;
+{
+ if (pipe(Notifypipe) < 0)
+ return -errno;
+ return 0;
+}
+
+/*
+** SM_NOTIFY_START -- start notify system
+**
+** Parameters:
+** owner -- owner.
+** flags -- currently ignored.
+**
+** Returns:
+** 0: success
+** <0: -errno
+*/
+
+int
+sm_notify_start(owner, flags)
+ bool owner;
+ int flags;
+{
+ int r;
+
+ r = 0;
+ if (owner)
+ CLOSEFD(NotifyWRpipe);
+ else
+ CLOSEFD(NotifyRDpipe);
+ return r;
+}
+
+/*
+** SM_NOTIFY_STOP -- stop notify system
+**
+** Parameters:
+** owner -- owner.
+** flags -- currently ignored.
+**
+** Returns:
+** 0: success
+** <0: -errno
+*/
+
+int
+sm_notify_stop(owner, flags)
+ bool owner;
+ int flags;
+{
+ if (owner)
+ CLOSEFD(NotifyRDpipe);
+ else
+ CLOSEFD(NotifyWRpipe);
+ return 0;
+}
+
+/*
+** SM_NOTIFY_SND -- send notification
+**
+** Parameters:
+** buf -- where to write data
+** buflen -- len of buffer
+**
+** Returns:
+** 0: success
+** <0: -errno
+*/
+
+int
+sm_notify_snd(buf, buflen)
+ char *buf;
+ size_t buflen;
+{
+ int r;
+ int save_errno;
+
+ SM_REQUIRE(buf != NULL);
+ SM_REQUIRE(buflen > 0);
+ if (NotifyWRpipe < 0)
+ return -EINVAL;
+
+ r = write(NotifyWRpipe, buf, buflen);
+ save_errno = errno;
+ SM_DBG((stderr, "write=%d, fd=%d, e=%d\n", r, NotifyWRpipe, save_errno));
+ return r >= 0 ? 0 : -save_errno;
+}
+
+/*
+** SM_NOTIFY_RCV -- receive notification
+**
+** Parameters:
+** buf -- where to write data
+** buflen -- len of buffer
+** tmo -- timeout
+**
+** Returns:
+** 0: success
+** <0: -errno
+*/
+
+int
+sm_notify_rcv(buf, buflen, tmo)
+ char *buf;
+ size_t buflen;
+ int tmo;
+{
+ int r;
+ int save_errno;
+ fd_set readfds;
+ struct timeval timeout;
+
+ SM_REQUIRE(buf != NULL);
+ SM_REQUIRE(buflen > 0);
+ if (NotifyRDpipe < 0)
+ return -EINVAL;
+ FD_ZERO(&readfds);
+ SM_FD_SET(NotifyRDpipe, &readfds);
+ timeout.tv_sec = tmo;
+ timeout.tv_usec = 0;
+
+ do {
+ r = select(NotifyRDpipe + 1, FDSET_CAST &readfds, NULL, NULL, &timeout);
+ save_errno = errno;
+ SM_DBG((stderr, "select=%d, fd=%d, e=%d\n", r, NotifyRDpipe, save_errno));
+ } while (r < 0 && save_errno == EINTR);
+
+ if (r <= 0)
+ {
+ SM_DBG((stderr, "select=%d, e=%d\n", r, save_errno));
+ return -ETIMEDOUT;
+ }
+
+ /* bogus... need to check again? */
+ if (!FD_ISSET(NotifyRDpipe, &readfds))
+ return -ETIMEDOUT;
+
+ r = read(NotifyRDpipe, buf, buflen);
+ save_errno = errno;
+ SM_DBG((stderr, "read=%d, e=%d\n", r, save_errno));
+ if (r == 0)
+ return -1; /* ??? */
+ if (r < 0)
+ return -save_errno;
+ return r;
+}
diff --git a/contrib/sendmail/libsm/refill.c b/contrib/sendmail/libsm/refill.c
index e13c831bed42..af3a84442f17 100644
--- a/contrib/sendmail/libsm/refill.c
+++ b/contrib/sendmail/libsm/refill.c
@@ -80,7 +80,7 @@ static int sm_lflush __P((SM_FILE_T *, int *));
do \
{ \
(sel_ret) = select((fd) + 1, &sm_io_to_mask, NULL, \
- &sm_io_x_mask, (to)); \
+ &sm_io_x_mask, (to)); \
} while ((sel_ret) < 0 && errno == EINTR); \
if ((sel_ret) < 0) \
{ \
@@ -95,7 +95,7 @@ static int sm_lflush __P((SM_FILE_T *, int *));
errno = EAGAIN; \
return SM_IO_EOF; \
} \
- /* calulate wall-clock time used */ \
+ /* calculate wall-clock time used */ \
if (gettimeofday(&sm_io_to_after, NULL) < 0) \
return SM_IO_EOF; \
timersub(&sm_io_to_after, &sm_io_to_before, &sm_io_to_diff); \
diff --git a/contrib/sendmail/libsm/rewind.c b/contrib/sendmail/libsm/rewind.c
index 9203ddb32f65..2bbb26d2a9a9 100644
--- a/contrib/sendmail/libsm/rewind.c
+++ b/contrib/sendmail/libsm/rewind.c
@@ -22,7 +22,7 @@ SM_RCSID("@(#)$Id: rewind.c,v 1.19 2013-11-22 20:51:43 ca Exp $")
/*
** SM_IO_REWIND -- rewind the file
**
-** Seeks the file to the begining and clears any outstanding errors.
+** Seeks the file to the beginning and clears any outstanding errors.
**
** Parameters:
** fp -- the flie pointer for rewind
diff --git a/contrib/sendmail/libsm/rpool.c b/contrib/sendmail/libsm/rpool.c
index 2624123cca91..9d883ffca194 100644
--- a/contrib/sendmail/libsm/rpool.c
+++ b/contrib/sendmail/libsm/rpool.c
@@ -22,7 +22,7 @@ SM_RCSID("@(#)$Id: rpool.c,v 1.29 2013-11-22 20:51:43 ca Exp $")
#include <sm/conf.h>
#if _FFR_PERF_RPOOL
# include <syslog.h>
-#endif /* _FFR_PERF_RPOOL */
+#endif
const char SmRpoolMagic[] = "sm_rpool";
@@ -181,7 +181,7 @@ sm_rpool_malloc_x(rpool, size)
{
#if _FFR_PERF_RPOOL
++rpool->sm_nbigblocks;
-#endif /* _FFR_PERF_RPOOL */
+#endif
return sm_rpool_allocblock_x(rpool, size);
}
SM_ASSERT(rpool->sm_bigobjectsize <= rpool->sm_poolsize);
@@ -190,7 +190,7 @@ sm_rpool_malloc_x(rpool, size)
rpool->sm_poolavail = rpool->sm_poolsize - size;
#if _FFR_PERF_RPOOL
++rpool->sm_npools;
-#endif /* _FFR_PERF_RPOOL */
+#endif
return ptr;
}
@@ -277,7 +277,7 @@ sm_rpool_malloc(rpool, size)
{
#if _FFR_PERF_RPOOL
++rpool->sm_nbigblocks;
-#endif /* _FFR_PERF_RPOOL */
+#endif
return sm_rpool_allocblock(rpool, size);
}
SM_ASSERT(rpool->sm_bigobjectsize <= rpool->sm_poolsize);
@@ -288,7 +288,7 @@ sm_rpool_malloc(rpool, size)
rpool->sm_poolavail = rpool->sm_poolsize - size;
#if _FFR_PERF_RPOOL
++rpool->sm_npools;
-#endif /* _FFR_PERF_RPOOL */
+#endif
return ptr;
}
@@ -336,7 +336,7 @@ sm_rpool_new_x(parent)
#if _FFR_PERF_RPOOL
rpool->sm_nbigblocks = 0;
rpool->sm_npools = 0;
-#endif /* _FFR_PERF_RPOOL */
+#endif
return rpool;
}
diff --git a/contrib/sendmail/libsm/sem.c b/contrib/sendmail/libsm/sem.c
index 23b2de70f318..ac28a61ae353 100644
--- a/contrib/sendmail/libsm/sem.c
+++ b/contrib/sendmail/libsm/sem.c
@@ -159,7 +159,7 @@ sm_sem_rel(semid, semnum, timeout)
#if PARANOID
/* XXX should we check whether the value is already 0 ? */
SM_REQUIRE(sm_get_sem(semid, semnum) > 0);
-#endif /* PARANOID */
+#endif
semops[0].sem_num = semnum;
semops[0].sem_op = 1;
diff --git a/contrib/sendmail/libsm/signal.c b/contrib/sendmail/libsm/signal.c
index 469b0fd7050b..bfbeaf555c2e 100644
--- a/contrib/sendmail/libsm/signal.c
+++ b/contrib/sendmail/libsm/signal.c
@@ -12,7 +12,7 @@ SM_RCSID("@(#)$Id: signal.c,v 1.18 2013-11-22 20:51:43 ca Exp $")
#if SM_CONF_SETITIMER
# include <sm/time.h>
-#endif /* SM_CONF_SETITIMER */
+#endif
#include <errno.h>
#include <stdlib.h>
#include <time.h>
@@ -42,7 +42,7 @@ sm_signal(sig, handler)
{
# if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3))
struct sigaction n, o;
-# endif /* defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) */
+# endif
/*
** First, try for modern signal calls
@@ -54,10 +54,10 @@ sm_signal(sig, handler)
# if USE_SA_SIGACTION
n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler;
n.sa_flags = SA_RESTART|SA_SIGINFO;
-# else /* USE_SA_SIGACTION */
+# else
n.sa_handler = handler;
n.sa_flags = SA_RESTART;
-# endif /* USE_SA_SIGACTION */
+# endif
if (sigaction(sig, &n, &o) < 0)
return SIG_ERR;
return o.sa_handler;
@@ -71,9 +71,9 @@ sm_signal(sig, handler)
# if defined(SYS5SIGNALS) || defined(BSD4_3)
# ifdef BSD4_3
return signal(sig, handler);
-# else /* BSD4_3 */
+# else
return sigset(sig, handler);
-# endif /* BSD4_3 */
+# endif
# else /* defined(SYS5SIGNALS) || defined(BSD4_3) */
/*
@@ -108,7 +108,7 @@ sm_blocksignal(sig)
# ifdef BSD4_3
# ifndef sigmask
# define sigmask(s) (1 << ((s) - 1))
-# endif /* ! sigmask */
+# endif
return (sigblock(sigmask(sig)) & sigmask(sig)) != 0;
# else /* BSD4_3 */
# ifdef ALTOS_SYSTEM_V
@@ -192,7 +192,7 @@ pend_signal(sig)
int save_errno = errno;
#if SM_CONF_SETITIMER
struct itimerval clr;
-#endif /* SM_CONF_SETITIMER */
+#endif
/*
** Don't want to interrupt something critical, hence delay
@@ -266,7 +266,7 @@ sm_allsignals(block)
# ifdef BSD4_3
# ifndef sigmask
# define sigmask(s) (1 << ((s) - 1))
-# endif /* ! sigmask */
+# endif
if (block)
{
int mask = 0;
diff --git a/contrib/sendmail/libsm/stdio.c b/contrib/sendmail/libsm/stdio.c
index 16277c09a8ec..7e045fa56fec 100644
--- a/contrib/sendmail/libsm/stdio.c
+++ b/contrib/sendmail/libsm/stdio.c
@@ -93,7 +93,7 @@ sm_stdopen(fp, info, flags, rpool)
#ifdef O_BINARY
if (SM_IS_BINARY(flags))
oflags |= O_BINARY;
-#endif /* O_BINARY */
+#endif
fp->f_file = open(path, oflags,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
if (fp->f_file < 0)
@@ -118,7 +118,7 @@ sm_stdopen(fp, info, flags, rpool)
** Success: number of bytes read
**
** Side Effects:
-** Updates internal offset into file.
+** Updates internal offset for file.
*/
ssize_t
@@ -433,7 +433,7 @@ sm_stdfdopen(fp, info, flags, rpool)
#ifdef O_BINARY
if (SM_IS_BINARY(flags))
oflags |= O_BINARY;
-#endif /* O_BINARY */
+#endif
/* Make sure the mode the user wants is a subset of the actual mode. */
if ((fdflags = fcntl(fd, F_GETFL, 0)) < 0)
diff --git a/contrib/sendmail/libsm/strdup.c b/contrib/sendmail/libsm/strdup.c
index 3ddf73b4629e..457c09970d94 100644
--- a/contrib/sendmail/libsm/strdup.c
+++ b/contrib/sendmail/libsm/strdup.c
@@ -59,7 +59,7 @@ sm_strndup_x(s, n)
char *
sm_strdup(s)
- char *s;
+ const char *s;
{
size_t l;
char *d;
diff --git a/contrib/sendmail/libsm/strerror.c b/contrib/sendmail/libsm/strerror.c
index b6b0b668ab5a..a6130f8612c7 100644
--- a/contrib/sendmail/libsm/strerror.c
+++ b/contrib/sendmail/libsm/strerror.c
@@ -29,7 +29,7 @@ SM_RCSID("@(#)$Id: strerror.c,v 1.24 2013-11-22 20:51:43 ca Exp $")
#if !defined(ERRLIST_PREDEFINED)
extern char *sys_errlist[];
extern int sys_nerr;
-#endif /* !defined(ERRLIST_PREDEFINED) */
+#endif
#if !HASSTRERROR
diff --git a/contrib/sendmail/libsm/string.c b/contrib/sendmail/libsm/string.c
index 2b06e2c7ec78..83577f19a84e 100644
--- a/contrib/sendmail/libsm/string.c
+++ b/contrib/sendmail/libsm/string.c
@@ -54,3 +54,34 @@ stripquotes(s)
*q++ = c;
} while (c != '\0');
}
+
+/*
+** UNFOLDSTRIPQUOTES -- Strip quotes & quote bits from a string.
+**
+** Parameters:
+** s -- the string to strip.
+**
+** Returns:
+** none.
+*/
+
+void
+unfoldstripquotes(s)
+ char *s;
+{
+ char *p, *q, c;
+
+ if (s == NULL)
+ return;
+
+ p = q = s;
+ do
+ {
+ c = *p++;
+ if (c == '\\' || c == '\n')
+ c = *p++;
+ else if (c == '"')
+ continue;
+ *q++ = c;
+ } while (c != '\0');
+}
diff --git a/contrib/sendmail/libsm/strio.c b/contrib/sendmail/libsm/strio.c
index 4fae8070ad00..de13af683deb 100644
--- a/contrib/sendmail/libsm/strio.c
+++ b/contrib/sendmail/libsm/strio.c
@@ -224,18 +224,18 @@ sm_stropen(fp, info, flags, rpool)
#if SM_RPOOL
s = sm_rpool_malloc_x(rpool, sizeof(SM_STR_OBJ_T));
-#else /* SM_RPOOL */
+#else
s = sm_malloc(sizeof(SM_STR_OBJ_T));
if (s == NULL)
return -1;
-#endif /* SM_RPOOL */
+#endif
fp->f_cookie = s;
s->strio_rpool = rpool;
s->strio_offset = 0;
s->strio_size = 0;
s->strio_base = NULL;
- s->strio_end = 0;
+ s->strio_end = NULL;
switch (flags)
{
@@ -297,7 +297,7 @@ sm_strclose(fp)
#if !SM_RPOOL
sm_free(s->strio_base);
s->strio_base = NULL;
-#endif /* !SM_RPOOL */
+#endif
return 0;
}
diff --git a/contrib/sendmail/libsm/strto.c b/contrib/sendmail/libsm/strto.c
index 7f53424faf5c..af741533e3b4 100644
--- a/contrib/sendmail/libsm/strto.c
+++ b/contrib/sendmail/libsm/strto.c
@@ -158,7 +158,7 @@ sm_strtoll(nptr, endptr, base)
}
}
}
- if (endptr != 0)
+ if (endptr != NULL)
*endptr = (char *) (any ? s - 1 : nptr);
return acc;
}
@@ -248,7 +248,7 @@ sm_strtoull(nptr, endptr, base)
}
if (neg && any > 0)
acc = -((LONGLONG_T) acc);
- if (endptr != 0)
+ if (endptr != NULL)
*endptr = (char *) (any ? s - 1 : nptr);
return acc;
}
diff --git a/contrib/sendmail/libsm/syslogio.c b/contrib/sendmail/libsm/syslogio.c
index 78cf700aff35..16f3aeafd0c5 100644
--- a/contrib/sendmail/libsm/syslogio.c
+++ b/contrib/sendmail/libsm/syslogio.c
@@ -16,7 +16,7 @@ SM_RCSID("@(#)$Id: syslogio.c,v 1.30 2013-11-22 20:51:43 ca Exp $")
#include <errno.h>
#ifdef SM_RPOOL
# include <sm/rpool.h>
-#endif /* SM_RPOOL */
+#endif
#include <sm/io.h>
#include "local.h"
diff --git a/contrib/sendmail/libsm/t-event.c b/contrib/sendmail/libsm/t-event.c
index 7f08b914bb53..fcdd02b28985 100644
--- a/contrib/sendmail/libsm/t-event.c
+++ b/contrib/sendmail/libsm/t-event.c
@@ -17,7 +17,7 @@ SM_RCSID("@(#)$Id: t-event.c,v 1.14 2013-11-22 20:51:43 ca Exp $")
# include <sys/wait.h>
#if SM_CONF_SETITIMER
# include <sm/time.h>
-#endif /* SM_CONF_SETITIMER */
+#endif
#include <sm/clock.h>
#include <sm/test.h>
diff --git a/contrib/sendmail/libsm/t-exc.c b/contrib/sendmail/libsm/t-exc.c
index e0b45a86d525..3136e3f80c37 100644
--- a/contrib/sendmail/libsm/t-exc.c
+++ b/contrib/sendmail/libsm/t-exc.c
@@ -132,7 +132,7 @@ main(argc, argv)
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"test 0 got an exception, as expected:\n");
sm_exc_print(exc, smioout);
-#endif /* DEBUG */
+#endif
return sm_test_end();
SM_END_TRY
diff --git a/contrib/sendmail/libsm/t-heap.c b/contrib/sendmail/libsm/t-heap.c
index d5e9e7e3f549..5e813ad333a7 100644
--- a/contrib/sendmail/libsm/t-heap.c
+++ b/contrib/sendmail/libsm/t-heap.c
@@ -19,7 +19,7 @@ SM_IDSTR(id, "@(#)$Id: t-heap.c,v 1.11 2013-11-22 20:51:43 ca Exp $")
#if SM_HEAP_CHECK
extern SM_DEBUG_T SmHeapCheck;
# define HEAP_CHECK sm_debug_active(&SmHeapCheck, 1)
-#else /* SM_HEAP_CHECK */
+#else
# define HEAP_CHECK 0
#endif /* SM_HEAP_CHECK */
@@ -58,7 +58,7 @@ main(argc, argv)
/* this will cause a core dump */
sm_dprintf("about to free %p for the second time\n", p);
sm_free(p);
-#endif /* DEBUG */
+#endif
return sm_test_end();
}
diff --git a/contrib/sendmail/libsm/t-notify.c b/contrib/sendmail/libsm/t-notify.c
new file mode 100644
index 000000000000..7103cad2559d
--- /dev/null
+++ b/contrib/sendmail/libsm/t-notify.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2016 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ */
+
+#include <sm/gen.h>
+
+#include <stdio.h>
+
+# include <stdlib.h>
+# include <unistd.h>
+
+# include <sm/heap.h>
+# include <sm/string.h>
+# include <sm/test.h>
+# include <sm/notify.h>
+
+# define MAX_CNT 10
+
+/*
+** MSGTEST -- test of message queue.
+**
+** Parameters:
+** owner -- create message queue.
+**
+** Returns:
+** 0 on success
+** < 0 on failure.
+*/
+
+static int
+notifytest(owner)
+ int owner;
+{
+ int r;
+ size_t len;
+ char buf[64];
+#define TSTSTR "qf0001"
+
+ r = sm_notify_start(owner, 0);
+ if (r < 0)
+ {
+ perror("sm_notify_start failed");
+ return -1;
+ }
+
+ if (!owner)
+ {
+ len = sm_strlcpy(buf, TSTSTR, sizeof(buf));
+ r = sm_notify_snd(buf, len);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ goto end;
+
+ end:
+ return r;
+ }
+ else
+ {
+ r = sm_notify_rcv(buf, sizeof(buf), 5);
+ SM_TEST(r >= 0);
+ if (r < 0)
+ return r;
+ if (r > 0 && r < sizeof(buf))
+ buf[r] = '\0';
+ buf[sizeof(buf) - 1] = '\0';
+ SM_TEST(strcmp(buf, TSTSTR) == 0);
+ fprintf(stderr, "buf=\"%s\"\n", buf);
+ }
+ return 0;
+}
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int ch;
+ int r = 0;
+ pid_t pid;
+
+# define OPTIONS ""
+ while ((ch = getopt(argc, argv, OPTIONS)) != -1)
+ {
+ switch ((char) ch)
+ {
+ default:
+ break;
+ }
+ }
+
+ r = sm_notify_init(0);
+ if (r < 0)
+ {
+ perror("sm_notify_init failed\n");
+ return -1;
+ }
+
+ if ((pid = fork()) < 0)
+ {
+ perror("fork failed\n");
+ return -1;
+ }
+
+ sm_test_begin(argc, argv, "test notify");
+ if (pid == 0)
+ {
+ /* give the parent the chance to setup data */
+ sleep(1);
+ r = notifytest(false);
+ }
+ else
+ {
+ r = notifytest(true);
+ }
+ SM_TEST(r >= 0);
+ return sm_test_end();
+}
diff --git a/contrib/sendmail/libsm/t-scanf.c b/contrib/sendmail/libsm/t-scanf.c
index d7c20f748abd..087792ecb959 100644
--- a/contrib/sendmail/libsm/t-scanf.c
+++ b/contrib/sendmail/libsm/t-scanf.c
@@ -31,7 +31,7 @@ main(argc, argv)
"If tests for \"h == 2\" fail, check whether size_t is signed on your OS.\n\
If that is the case, add -DSM_CONF_BROKEN_SIZE_T to confENVDEF\n\
and start over. Otherwise contact sendmail.org.\n");
-#endif /* !SM_CONF_BROKEN_SIZE_T */
+#endif
d = 2;
sm_snprintf(buf, sizeof(buf), "%d", d);
diff --git a/contrib/sendmail/libsm/t-sem.c b/contrib/sendmail/libsm/t-sem.c
index 4232b096ead7..b13e159ecebe 100644
--- a/contrib/sendmail/libsm/t-sem.c
+++ b/contrib/sendmail/libsm/t-sem.c
@@ -33,12 +33,12 @@ delay(t, s)
{
#if DEBUG
fprintf(stderr, "sleep(%d) before %s\n", t, s);
-#endif /* DEBUG */
+#endif
sleep(t);
}
#if DEBUG
fprintf(stderr, "%s\n", s);
-#endif /* DEBUG */
+#endif
}
diff --git a/contrib/sendmail/libsm/vfprintf.c b/contrib/sendmail/libsm/vfprintf.c
index 87c353c1bf14..b90a305b04d8 100644
--- a/contrib/sendmail/libsm/vfprintf.c
+++ b/contrib/sendmail/libsm/vfprintf.c
@@ -538,16 +538,16 @@ reswitch: switch (ch)
#if HASSNPRINTF
snprintf(out, sizeof(out), fmt, width,
prec, val);
-#else /* HASSNPRINTF */
+#else
sprintf(out, fmt, width, prec, val);
-#endif /* HASSNPRINTF */
+#endif
else
#if HASSNPRINTF
snprintf(out, sizeof(out), fmt, width,
val);
-#else /* HASSNPRINTF */
+#else
sprintf(out, fmt, width, val);
-#endif /* HASSNPRINTF */
+#endif
len = strlen(out);
PRINT(out, len);
FLUSH();
@@ -782,6 +782,7 @@ number: if ((dprec = prec) >= 0)
done:
FLUSH();
error:
+ SM_VA_END_COPY(orgap);
if ((argtable != NULL) && (argtable != statargtable))
sm_free(argtable);
return sm_error(fp) ? SM_IO_EOF : ret;
diff --git a/contrib/sendmail/libsm/vfscanf.c b/contrib/sendmail/libsm/vfscanf.c
index d043a1135884..c367f7682e37 100644
--- a/contrib/sendmail/libsm/vfscanf.c
+++ b/contrib/sendmail/libsm/vfscanf.c
@@ -110,7 +110,7 @@ sm_vfscanf(fp, timeout, fmt0, ap)
register SM_FILE_T *fp;
int SM_NONVOLATILE timeout;
char const *fmt0;
- va_list SM_NONVOLATILE ap;
+ va_list ap;
{
register unsigned char *SM_NONVOLATILE fmt = (unsigned char *) fmt0;
register int c; /* character from format, or conversion */
@@ -828,7 +828,7 @@ doswitch:
** z', but treats `a-a' as `the letter a, the
** character -, and the letter a'.
**
- ** For compatibility, the `-' is not considerd
+ ** For compatibility, the `-' is not considered
** to define a range if the character following
** it is either a close bracket (required by ANSI)
** or is not numerically greater than the character
diff --git a/contrib/sendmail/libsmdb/Makefile b/contrib/sendmail/libsmdb/Makefile
index 13c8af07a52c..ce0e752abc0a 100644
--- a/contrib/sendmail/libsmdb/Makefile
+++ b/contrib/sendmail/libsmdb/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/libsmdb/Makefile.m4 b/contrib/sendmail/libsmdb/Makefile.m4
index dfd62fa6a37e..69299e53fce0 100644
--- a/contrib/sendmail/libsmdb/Makefile.m4
+++ b/contrib/sendmail/libsmdb/Makefile.m4
@@ -8,7 +8,7 @@ PREPENDDEF(`confENVDEF', `confMAPDEF')
PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ')
bldPRODUCT_START(`library', `libsmdb')
-define(`bldSOURCES', `smdb.c smdb1.c smdb2.c smndbm.c ')
+define(`bldSOURCES', `smdb.c smdb1.c smdb2.c smndbm.c smcdb.c ')
APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL')
bldPRODUCT_END
diff --git a/contrib/sendmail/libsmdb/smcdb.c b/contrib/sendmail/libsmdb/smcdb.c
new file mode 100644
index 000000000000..84c1a9e1f90c
--- /dev/null
+++ b/contrib/sendmail/libsmdb/smcdb.c
@@ -0,0 +1,575 @@
+/*
+** Copyright (c) 2018 Proofpoint, Inc. and its suppliers.
+** All rights reserved.
+**
+** By using this file, you agree to the terms and conditions set
+** forth in the LICENSE file which can be found at the top level of
+** the sendmail distribution.
+*/
+
+#include <sm/gen.h>
+SM_RCSID("@(#)$Id: smcdb.c,v 8.55 2013-11-22 20:51:49 ca Exp $")
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sendmail/sendmail.h>
+#include <libsmdb/smdb.h>
+
+#if CDB
+#include <assert.h>
+#include <cdb.h>
+
+typedef struct cdb cdb_map_T, *cdb_map_P;
+typedef struct cdb_make cdb_make_T, *cdb_make_P;
+typedef union sm_cdbs_U sm_cdbs_T, *sm_cdbs_P;
+union sm_cdbs_U
+{
+ cdb_map_T cdbs_cdb_rd;
+ cdb_make_T cdbs_cdb_wr;
+};
+
+struct smdb_cdb_database
+{
+ sm_cdbs_T cdbmap_map;
+ int cdbmap_fd;
+ int smcdb_lock_fd;
+ bool cdbmap_create;
+ unsigned smcdb_pos;
+ int smcdb_n;
+};
+typedef struct smdb_cdb_database SMDB_CDB_DATABASE;
+
+/* static int smdb_type_to_cdb_type __P((SMDB_DBTYPE type)); */
+static int cdb_error_to_smdb __P((int error));
+static SMDB_CDB_DATABASE * smcdb_malloc_database __P((void));
+static int smcdb_close __P((SMDB_DATABASE *database));
+static int smcdb_del __P((SMDB_DATABASE *database, SMDB_DBENT *key, unsigned int flags));
+static int smcdb_fd __P((SMDB_DATABASE *database, int *fd));
+static int smcdb_lockfd __P((SMDB_DATABASE *database));
+static int smcdb_get __P((SMDB_DATABASE *database, SMDB_DBENT *key, SMDB_DBENT *data, unsigned int flags));
+static int smcdb_put __P((SMDB_DATABASE *database, SMDB_DBENT *key, SMDB_DBENT *data, unsigned int flags));
+static int smcdb_set_owner __P((SMDB_DATABASE *database, uid_t uid, gid_t gid));
+static int smcdb_sync __P((SMDB_DATABASE *database, unsigned int flags));
+static int smcdb_cursor_close __P((SMDB_CURSOR *cursor));
+static int smcdb_cursor_del __P((SMDB_CURSOR *cursor, SMDB_FLAG flags));
+static int smcdb_cursor_get __P((SMDB_CURSOR *cursor, SMDB_DBENT *key, SMDB_DBENT *value, SMDB_FLAG flags));
+static int smcdb_cursor_put __P((SMDB_CURSOR *cursor, SMDB_DBENT *key, SMDB_DBENT *value, SMDB_FLAG flags));
+static int smcdb_cursor __P((SMDB_DATABASE *database, SMDB_CURSOR **cursor, SMDB_FLAG flags));
+
+/*
+** SMDB_TYPE_TO_CDB_TYPE -- Translates smdb database type to cdb type.
+**
+** Parameters:
+** type -- The type to translate.
+**
+** Returns:
+** The CDB type that corresponsds to the passed in SMDB type.
+** Returns -1 if there is no equivalent type.
+**
+*/
+
+#if 0
+static int
+smdb_type_to_cdb_type(type)
+ SMDB_DBTYPE type;
+{
+ return 0; /* XXX */
+}
+#endif
+
+/*
+** CDB_ERROR_TO_SMDB -- Translates cdb errors to smdbe errors
+**
+** Parameters:
+** error -- The error to translate.
+**
+** Returns:
+** The SMDBE error corresponding to the cdb error.
+** If we don't have a corresponding error, it returns error.
+**
+*/
+
+static int
+cdb_error_to_smdb(error)
+ int error;
+{
+ int result;
+
+ switch (error)
+ {
+ case 0:
+ result = SMDBE_OK;
+ break;
+
+ default:
+ result = error;
+ }
+ return result;
+}
+
+SMDB_CDB_DATABASE *
+smcdb_malloc_database()
+{
+ SMDB_CDB_DATABASE *cdb;
+
+ cdb = (SMDB_CDB_DATABASE *) malloc(sizeof(SMDB_CDB_DATABASE));
+ if (cdb != NULL)
+ cdb->smcdb_lock_fd = -1;
+
+ return cdb;
+}
+
+static int
+smcdb_close(database)
+ SMDB_DATABASE *database;
+{
+ int result, fd;
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+
+ if (NULL == sm_cdbmap)
+ return -1;
+ result = 0;
+ if (sm_cdbmap->cdbmap_create)
+ result = cdb_make_finish(&sm_cdbmap->cdbmap_map.cdbs_cdb_wr);
+
+ fd = sm_cdbmap->cdbmap_fd;
+ if (fd >= 0)
+ {
+ close(fd);
+ sm_cdbmap->cdbmap_fd = -1;
+ }
+
+ free(sm_cdbmap);
+ database->smdb_impl = NULL;
+
+ return result;
+}
+
+static int
+smcdb_del(database, key, flags)
+ SMDB_DATABASE *database;
+ SMDB_DBENT *key;
+ unsigned int flags;
+{
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+
+ assert(sm_cdbmap != NULL);
+ return -1;
+}
+
+static int
+smcdb_fd(database, fd)
+ SMDB_DATABASE *database;
+ int *fd;
+{
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+ return sm_cdbmap->cdbmap_fd;
+}
+
+static int
+smcdb_lockfd(database)
+ SMDB_DATABASE *database;
+{
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+
+ return sm_cdbmap->smcdb_lock_fd;
+}
+
+/*
+** allocate/free: who does it: caller or callee?
+** If this code does it: the "last" entry will leak.
+*/
+
+#define DBEALLOC(dbe, l) \
+ do \
+ { \
+ if ((dbe)->size > 0 && l > (dbe)->size) \
+ { \
+ free((dbe)->data); \
+ (dbe)->size = 0; \
+ } \
+ if ((dbe)->size == 0) \
+ { \
+ (dbe)->data = malloc(l); \
+ if ((dbe)->data == NULL) \
+ return SMDBE_MALLOC; \
+ (dbe)->size = l; \
+ } \
+ if (l > (dbe)->size) \
+ return SMDBE_MALLOC; /* XXX bogus */ \
+ } while (0)
+
+
+static int
+smcdb_get(database, key, data, flags)
+ SMDB_DATABASE *database;
+ SMDB_DBENT *key;
+ SMDB_DBENT *data;
+ unsigned int flags;
+{
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+ size_t l;
+ int ret;
+
+ ret = SM_SUCCESS;
+
+ if (NULL == sm_cdbmap )
+ return -1;
+ /* SM_ASSERT(!sm_cdbmap->cdbmap_create); */
+
+ /* need to lock access? single threaded access! */
+ ret = cdb_find(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
+ key->data, key->size);
+ if (ret > 0)
+ {
+ l = cdb_datalen(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
+ DBEALLOC(data, l);
+ ret = cdb_read(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
+ data->data, l,
+ cdb_datapos(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd));
+ if (ret < 0)
+ ret = -1;
+ else
+ {
+ data->size = l;
+ ret = SM_SUCCESS;
+ }
+ }
+ else
+ ret = -1;
+
+ return ret;
+}
+
+static int
+smcdb_put(database, key, data, flags)
+ SMDB_DATABASE *database;
+ SMDB_DBENT *key;
+ SMDB_DBENT *data;
+ unsigned int flags;
+{
+ int r, cdb_flags;
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+
+ assert(sm_cdbmap != NULL);
+ if (bitset(SMDBF_NO_OVERWRITE, flags))
+ cdb_flags = CDB_PUT_INSERT;
+ else
+ cdb_flags = CDB_PUT_REPLACE;
+
+ r = cdb_make_put(&sm_cdbmap->cdbmap_map.cdbs_cdb_wr,
+ key->data, key->size, data->data, data->size,
+ cdb_flags);
+ if (r > 0)
+ {
+ if (bitset(SMDBF_NO_OVERWRITE, flags))
+ return SMDBE_DUPLICATE;
+ else
+ return SMDBE_OK;
+ }
+ return r;
+}
+
+
+static int
+smcdb_set_owner(database, uid, gid)
+ SMDB_DATABASE *database;
+ uid_t uid;
+ gid_t gid;
+{
+# if HASFCHOWN
+ int fd;
+ int result;
+ SMDB_CDB_DATABASE *sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+
+ assert(sm_cdbmap != NULL);
+ fd = sm_cdbmap->cdbmap_fd;
+ if (fd >= 0)
+ {
+ result = fchown(fd, uid, gid);
+ if (result < 0)
+ return errno;
+ }
+# endif /* HASFCHOWN */
+
+ return SMDBE_OK;
+}
+
+static int
+smcdb_sync(database, flags)
+ SMDB_DATABASE *database;
+ unsigned int flags;
+{
+ return 0;
+}
+
+static int
+smcdb_cursor_close(cursor)
+ SMDB_CURSOR *cursor;
+{
+ int ret;
+
+ ret = SMDBE_OK;
+ if (cursor != NULL)
+ free(cursor);
+ return ret;
+}
+
+static int
+smcdb_cursor_del(cursor, flags)
+ SMDB_CURSOR *cursor;
+ SMDB_FLAG flags;
+{
+ return -1;
+}
+
+static int
+smcdb_cursor_get(cursor, key, value, flags)
+ SMDB_CURSOR *cursor;
+ SMDB_DBENT *key;
+ SMDB_DBENT *value;
+ SMDB_FLAG flags;
+{
+ SMDB_CDB_DATABASE *sm_cdbmap;
+ size_t l;
+ int ret;
+
+ ret = SMDBE_OK;
+ sm_cdbmap = cursor->smdbc_impl;
+ ret = cdb_seqnext(&sm_cdbmap->smcdb_pos, &sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
+ if (ret == 0)
+ return SMDBE_LAST_ENTRY;
+ if (ret < 0)
+ return SMDBE_IO_ERROR;
+
+ l = cdb_keylen(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
+ DBEALLOC(key, l);
+
+ ret = cdb_read(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
+ key->data, l,
+ cdb_keypos(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd));
+ if (ret < 0)
+ return SMDBE_IO_ERROR;
+ key->size = l;
+
+ l = cdb_datalen(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
+
+ DBEALLOC(value, l);
+ ret = cdb_read(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd,
+ value->data, l,
+ cdb_datapos(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd));
+ if (ret < 0)
+ return SMDBE_IO_ERROR;
+ value->size = l;
+
+ return SMDBE_OK;
+}
+
+static int
+smcdb_cursor_put(cursor, key, value, flags)
+ SMDB_CURSOR *cursor;
+ SMDB_DBENT *key;
+ SMDB_DBENT *value;
+ SMDB_FLAG flags;
+{
+ return -1;
+}
+
+static int
+smcdb_cursor(database, cursor, flags)
+ SMDB_DATABASE *database;
+ SMDB_CURSOR **cursor;
+ SMDB_FLAG flags;
+{
+ int result;
+ SMDB_CDB_DATABASE *sm_cdbmap;
+
+ result = SMDBE_OK;
+ *cursor = (SMDB_CURSOR *) malloc(sizeof(SMDB_CURSOR));
+ if (*cursor == NULL)
+ return SMDBE_MALLOC;
+
+ sm_cdbmap = (SMDB_CDB_DATABASE *) database->smdb_impl;
+ (*cursor)->smdbc_close = smcdb_cursor_close;
+ (*cursor)->smdbc_del = smcdb_cursor_del;
+ (*cursor)->smdbc_get = smcdb_cursor_get;
+ (*cursor)->smdbc_put = smcdb_cursor_put;
+ (*cursor)->smdbc_impl = sm_cdbmap;
+
+ cdb_seqinit(&sm_cdbmap->smcdb_pos, &sm_cdbmap->cdbmap_map.cdbs_cdb_rd);
+
+ return result;
+}
+
+/*
+** SMDB_DB_OPEN -- Opens a db database.
+**
+** Parameters:
+** database -- An unallocated database pointer to a pointer.
+** db_name -- The name of the database without extension.
+** mode -- File permisions for a created database.
+** mode_mask -- Mode bits that must match on an opened database.
+** sff -- Flags for safefile.
+** type -- The type of database to open
+** See smdb_type_to_cdb_type for valid types.
+** user_info -- User information for file permissions.
+** db_params --
+** An SMDB_DBPARAMS struct including params. These
+** are processed according to the type of the
+** database. Currently supported params (only for
+** HASH type) are:
+** num_elements
+** cache_size
+**
+** Returns:
+** SMDBE_OK -- Success, other errno:
+** SMDBE_MALLOC -- Cannot allocate memory.
+** SMDBE_BAD_OPEN -- db_open didn't return an error, but
+** somehow the DB pointer is NULL.
+** Anything else: translated error from cdb
+*/
+
+int
+smdb_cdb_open(database, db_name, mode, mode_mask, sff, type, user_info, db_params)
+ SMDB_DATABASE **database;
+ char *db_name;
+ int mode;
+ int mode_mask;
+ long sff;
+ SMDB_DBTYPE type;
+ SMDB_USER_INFO *user_info;
+ SMDB_DBPARAMS *db_params;
+{
+ bool lockcreated = false;
+ int result;
+ int lock_fd;
+ int db_fd;
+ SMDB_DATABASE *smdb_db;
+ SMDB_CDB_DATABASE *sm_cdbmap;
+ struct stat stat_info;
+ char db_file_name[MAXPATHLEN];
+
+ *database = NULL;
+ result = smdb_add_extension(db_file_name, sizeof db_file_name,
+ db_name, SMCDB_FILE_EXTENSION);
+ if (result != SMDBE_OK)
+ return result;
+
+ result = smdb_setup_file(db_name, SMCDB_FILE_EXTENSION,
+ mode_mask, sff, user_info, &stat_info);
+ if (result != SMDBE_OK)
+ return result;
+
+ lock_fd = -1;
+
+ if (stat_info.st_mode == ST_MODE_NOFILE &&
+ bitset(mode, O_CREAT))
+ lockcreated = true;
+
+ result = smdb_lock_file(&lock_fd, db_name, mode, sff,
+ SMCDB_FILE_EXTENSION);
+ if (result != SMDBE_OK)
+ return result;
+
+ if (lockcreated)
+ {
+ mode |= O_TRUNC;
+ mode &= ~(O_CREAT|O_EXCL);
+ }
+
+ smdb_db = smdb_malloc_database();
+ sm_cdbmap = smcdb_malloc_database();
+ if (sm_cdbmap == NULL || smdb_db == NULL)
+ {
+ smdb_unlock_file(lock_fd);
+ smdb_free_database(smdb_db); /* ok to be NULL */
+ if (sm_cdbmap != NULL)
+ free(sm_cdbmap);
+ return SMDBE_MALLOC;
+ }
+
+ sm_cdbmap->smcdb_lock_fd = lock_fd;
+
+#if 0
+ db = NULL;
+ db_flags = 0;
+ if (bitset(O_CREAT, mode))
+ db_flags |= DB_CREATE;
+ if (bitset(O_TRUNC, mode))
+ db_flags |= DB_TRUNCATE;
+ if (mode == O_RDONLY)
+ db_flags |= DB_RDONLY;
+ SM_DB_FLAG_ADD(db_flags);
+#endif
+
+ result = -1; /* smdb_db_open_internal(db_file_name, db_type, db_flags, db_params, &db); */
+ db_fd = open(db_file_name, mode, DBMMODE);
+ if (db_fd == -1)
+ {
+ result = SMDBE_BAD_OPEN;
+ goto error;
+ }
+
+ sm_cdbmap->cdbmap_create = (mode != O_RDONLY);
+ if (mode == O_RDONLY)
+ result = cdb_init(&sm_cdbmap->cdbmap_map.cdbs_cdb_rd, db_fd);
+ else
+ result = cdb_make_start(&sm_cdbmap->cdbmap_map.cdbs_cdb_wr, db_fd);
+ if (result != 0)
+ {
+ result = SMDBE_BAD_OPEN;
+ goto error;
+ }
+
+ if (result == 0)
+ result = SMDBE_OK;
+ else
+ {
+ /* Try and narrow down on the problem */
+ if (result != 0)
+ result = cdb_error_to_smdb(result);
+ else
+ result = SMDBE_BAD_OPEN;
+ }
+
+ if (result == SMDBE_OK)
+ result = smdb_filechanged(db_name, SMCDB_FILE_EXTENSION, db_fd,
+ &stat_info);
+
+ if (result == SMDBE_OK)
+ {
+ /* Everything is ok. Setup driver */
+ /* smdb_db->smcdb_db = sm_cdbmap; */
+
+ smdb_db->smdb_close = smcdb_close;
+ smdb_db->smdb_del = smcdb_del;
+ smdb_db->smdb_fd = smcdb_fd;
+ smdb_db->smdb_lockfd = smcdb_lockfd;
+ smdb_db->smdb_get = smcdb_get;
+ smdb_db->smdb_put = smcdb_put;
+ smdb_db->smdb_set_owner = smcdb_set_owner;
+ smdb_db->smdb_sync = smcdb_sync;
+ smdb_db->smdb_cursor = smcdb_cursor;
+ smdb_db->smdb_impl = sm_cdbmap;
+
+ *database = smdb_db;
+
+ return SMDBE_OK;
+ }
+
+ error:
+ if (sm_cdbmap != NULL)
+ {
+ /* close */
+ }
+
+ smdb_unlock_file(sm_cdbmap->smcdb_lock_fd);
+ free(sm_cdbmap);
+ smdb_free_database(smdb_db);
+
+ return result;
+}
+
+#endif /* CDB */
diff --git a/contrib/sendmail/libsmdb/smdb.c b/contrib/sendmail/libsmdb/smdb.c
index 96473b89b173..9091b52520fa 100644
--- a/contrib/sendmail/libsmdb/smdb.c
+++ b/contrib/sendmail/libsmdb/smdb.c
@@ -21,13 +21,13 @@ SM_RCSID("@(#)$Id: smdb.c,v 8.59 2013-11-22 20:51:49 ca Exp $")
static bool smdb_lockfile __P((int, int));
/*
-** SMDB_MALLOC_DATABASE -- Allocates a database structure.
+** SMDB_MALLOC_DATABASE -- Allocates a database structure.
**
** Parameters:
** None
**
** Returns:
-** An pointer to an allocated SMDB_DATABASE structure or
+** A pointer to an allocated SMDB_DATABASE structure or
** NULL if it couldn't allocate the memory.
*/
@@ -44,9 +44,8 @@ smdb_malloc_database()
return db;
}
-
/*
-** SMDB_FREE_DATABASE -- Unallocates a database structure.
+** SMDB_FREE_DATABASE -- Unallocates a database structure.
**
** Parameters:
** database -- a SMDB_DATABASE pointer to deallocate.
@@ -62,6 +61,7 @@ smdb_free_database(database)
if (database != NULL)
free(database);
}
+
/*
** SMDB_LOCKFILE -- lock a file using flock or (shudder) fcntl locking
**
@@ -155,16 +155,16 @@ smdb_lockfile(fd, type)
errno = save_errno;
return false;
}
+
/*
-** SMDB_OPEN_DATABASE -- Opens a database.
+** SMDB_OPEN_DATABASE -- Opens a database.
**
** This opens a database. If type is SMDB_DEFAULT it tries to
-** use a DB1 or DB2 hash. If that isn't available, it will try
-** to use NDBM. If a specific type is given it will try to open
-** a database of that type.
+** use available DB types. If a specific type is given it will
+** try to open a database of that type.
**
** Parameters:
-** database -- An pointer to a SMDB_DATABASE pointer where the
+** database -- A pointer to a SMDB_DATABASE pointer where the
** opened database will be stored. This should
** be unallocated.
** db_name -- The name of the database to open. Do not include
@@ -186,6 +186,20 @@ smdb_lockfile(fd, type)
** error in the comments for the specific open() used.
*/
+struct type2func_s
+{
+ const char *t2f_type;
+ smdb_open_func *t2f_open_fun;
+};
+typedef struct type2func_s type2func_t;
+static type2func_t type2func[] = {
+ { SMDB_TYPE_HASH, smdb_db_open },
+ { SMDB_TYPE_BTREE, smdb_db_open },
+ { SMDB_TYPE_NDBM, smdb_ndbm_open},
+ { SMDB_TYPE_CDB, smdb_cdb_open },
+ { NULL, NULL }
+};
+
int
smdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info,
params)
@@ -198,63 +212,44 @@ smdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info,
SMDB_USER_INFO *user_info;
SMDB_DBPARAMS *params;
{
-#if defined(NEWDB) && defined(NDBM)
- bool type_was_default = false;
-#endif
-
- if (type == SMDB_TYPE_DEFAULT)
- {
-#ifdef NEWDB
-# ifdef NDBM
- type_was_default = true;
-# endif
- type = SMDB_TYPE_HASH;
-#else /* NEWDB */
-# ifdef NDBM
- type = SMDB_TYPE_NDBM;
-# endif /* NDBM */
-#endif /* NEWDB */
- }
-
- if (type == SMDB_TYPE_DEFAULT)
- return SMDBE_UNKNOWN_DB_TYPE;
-
- if ((strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0) ||
- (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0))
+ bool type_was_default;
+ int result, i;
+ const char *smdb_type;
+ smdb_open_func *smdb_open_fun;
+
+ result = SMDBE_UNSUPPORTED_DB_TYPE;
+ type_was_default = SMDB_IS_TYPE_DEFAULT(type);
+ for (i = 0; (smdb_type = type2func[i].t2f_type) != NULL; i++)
{
-#ifdef NEWDB
- int result;
-
- result = smdb_db_open(database, db_name, mode, mode_mask, sff,
- type, user_info, params);
-# ifdef NDBM
- if (result == ENOENT && type_was_default)
- type = SMDB_TYPE_NDBM;
- else
-# endif /* NDBM */
- return result;
-#else /* NEWDB */
- return SMDBE_UNSUPPORTED_DB_TYPE;
-#endif /* NEWDB */
- }
-
- if (strncmp(type, SMDB_TYPE_NDBM, SMDB_TYPE_NDBM_LEN) == 0)
- {
-#ifdef NDBM
- int result;
-
- result = smdb_ndbm_open(database, db_name, mode, mode_mask,
- sff, type, user_info, params);
- return result;
-#else /* NDBM */
- return SMDBE_UNSUPPORTED_DB_TYPE;
-#endif /* NDBM */
+ if (!type_was_default && strcmp(type, smdb_type) != 0)
+ continue;
+ smdb_open_fun = type2func[i].t2f_open_fun;
+ if (smdb_open_fun == NULL)
+ {
+ if (type_was_default)
+ continue;
+ else
+ return SMDBE_UNSUPPORTED_DB_TYPE;
+ }
+ result = (*smdb_open_fun)(database, db_name, mode, mode_mask, sff,
+ (char *)smdb_type, user_info, params);
+ if (!((result == ENOENT
+ || result == EINVAL
+#ifdef EFTYPE
+ || result == EFTYPE
+#endif
+ )
+ && type_was_default))
+ goto ret;
}
-
return SMDBE_UNKNOWN_DB_TYPE;
+
+ ret:
+ return result;
}
+
/*
-** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
+** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
**
** Just adds a . followed by a string to a db_name if there
** is room and the db_name does not already have that extension.
@@ -488,8 +483,9 @@ smdb_filechanged(db_name, extension, db_fd, stat_info)
return result;
return filechanged(db_file_name, db_fd, stat_info);
}
+
/*
-** SMDB_PRINT_AVAILABLE_TYPES -- Prints the names of the available types.
+** SMDB_PRINT_AVAILABLE_TYPES -- Prints the names of the available types.
**
** Parameters:
** None
@@ -499,18 +495,62 @@ smdb_filechanged(db_name, extension, db_fd, stat_info)
*/
void
-smdb_print_available_types()
+smdb_print_available_types(ext)
+ bool ext;
{
-#ifdef NDBM
- printf("dbm\n");
-#endif /* NDBM */
-#ifdef NEWDB
- printf("hash\n");
- printf("btree\n");
-#endif /* NEWDB */
+# define PEXT1 ((ext) ? ":" : "")
+# define PEXT2(x) ((ext) ? x : "")
+
+#if NDBM
+ printf("%s%s%s\n", SMDB_TYPE_NDBM, PEXT1, PEXT2(SMNDB_DIR_FILE_EXTENSION));
+#endif
+#if NEWDB
+/* # if SMDB1_FILE_EXTENSION == SMDB2_FILE_EXTENSION */
+ printf("%s%s%s\n", SMDB_TYPE_HASH, PEXT1, PEXT2(SMDB1_FILE_EXTENSION));
+ printf("%s%s%s\n", SMDB_TYPE_BTREE, PEXT1, PEXT2(SMDB1_FILE_EXTENSION));
+#endif
+#if CDB
+ printf("%s%s%s\n", SMDB_TYPE_CDB, PEXT1, PEXT2(SMCDB_FILE_EXTENSION));
+#endif
+#ifdef SMDB_TYPE_IMPL
+ printf("%s%s%s\n", SMDB_TYPE_IMPL, PEXT1, "");
+#endif
+}
+
+/*
+** SMDB_IS_DB_TYPE -- Does a name match an available DB type?
+**
+** Parameters:
+** type -- The name of the database type.
+**
+** Returns:
+** true iff match
+*/
+
+bool
+smdb_is_db_type(db_type)
+ const char *db_type;
+{
+#if NDBM
+ if (strcmp(db_type, SMDB_TYPE_NDBM) == 0)
+ return true;
+#endif
+#if NEWDB
+ if (strcmp(db_type, SMDB_TYPE_HASH) == 0)
+ return true;
+ if (strcmp(db_type, SMDB_TYPE_BTREE) == 0)
+ return true;
+#endif
+#if CDB
+ if (strcmp(db_type, SMDB_TYPE_CDB) == 0)
+ return true;
+#endif
+ return false;
}
+
+
/*
-** SMDB_DB_DEFINITION -- Given a database type, return database definition
+** SMDB_DB_DEFINITION -- Given a database type, return database definition
**
** Reads though a structure making an association with the database
** type and the required cpp define from sendmail/README.
@@ -534,6 +574,7 @@ static dbtype DatabaseDefs[] =
{ SMDB_TYPE_HASH, "NEWDB" },
{ SMDB_TYPE_BTREE, "NEWDB" },
{ SMDB_TYPE_NDBM, "NDBM" },
+ { SMDB_TYPE_CDB, "CDB" },
{ NULL, "OOPS" }
};
diff --git a/contrib/sendmail/libsmdb/smdb1.c b/contrib/sendmail/libsmdb/smdb1.c
index 9d4e958032a7..85dc7fcaf74c 100644
--- a/contrib/sendmail/libsmdb/smdb1.c
+++ b/contrib/sendmail/libsmdb/smdb1.c
@@ -19,8 +19,6 @@ SM_RCSID("@(#)$Id: smdb1.c,v 8.63 2013-11-22 20:51:49 ca Exp $")
#if (DB_VERSION_MAJOR == 1)
-# define SMDB1_FILE_EXTENSION "db"
-
struct smdb_db1_struct
{
DB *smdb1_db;
@@ -72,10 +70,10 @@ smdb_type_to_db1_type(type)
if (type == SMDB_TYPE_DEFAULT)
return DB_HASH;
- if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
+ if (SMDB_IS_TYPE_HASH(type))
return DB_HASH;
- if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
+ if (SMDB_IS_TYPE_BTREE(type))
return DB_BTREE;
/* Should never get here thanks to test in smdb_db_open() */
@@ -471,8 +469,8 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
char db_file_name[MAXPATHLEN];
if (type == NULL ||
- (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) != 0 &&
- strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) != 0))
+ (!SMDB_IS_TYPE_HASH(type) && !SMDB_IS_TYPE_BTREE(type)
+ ))
return SMDBE_UNKNOWN_DB_TYPE;
result = smdb_add_extension(db_file_name, sizeof db_file_name,
@@ -515,8 +513,7 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
db1->smdb1_lock_fd = lock_fd;
params = NULL;
- if (db_params != NULL &&
- (strncmp(SMDB_TYPE_HASH, type, SMDB_TYPE_HASH_LEN) == 0))
+ if (db_params != NULL && SMDB_IS_TYPE_HASH(type))
{
(void) memset(&hash_info, '\0', sizeof hash_info);
hash_info.nelem = db_params->smdbp_num_elements;
@@ -524,8 +521,7 @@ smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info,
params = &hash_info;
}
- if (db_params != NULL &&
- (strncmp(SMDB_TYPE_BTREE, type, SMDB_TYPE_BTREE_LEN) == 0))
+ if (db_params != NULL && SMDB_IS_TYPE_BTREE(type))
{
(void) memset(&btree_info, '\0', sizeof btree_info);
btree_info.cachesize = db_params->smdbp_cache_size;
diff --git a/contrib/sendmail/libsmdb/smdb2.c b/contrib/sendmail/libsmdb/smdb2.c
index 403040307a97..d208efb40324 100644
--- a/contrib/sendmail/libsmdb/smdb2.c
+++ b/contrib/sendmail/libsmdb/smdb2.c
@@ -20,8 +20,6 @@ SM_RCSID("@(#)$Id: smdb2.c,v 8.83 2013-11-22 20:51:49 ca Exp $")
#if (DB_VERSION_MAJOR >= 2)
-# define SMDB2_FILE_EXTENSION "db"
-
struct smdb_db2_database
{
DB *smdb2_db;
@@ -41,17 +39,17 @@ typedef struct smdb_db2_database SMDB_DB2_DATABASE;
**
*/
-DBTYPE
+static DBTYPE
smdb_type_to_db2_type(type)
SMDB_DBTYPE type;
{
if (type == SMDB_TYPE_DEFAULT)
return DB_HASH;
- if (strncmp(type, SMDB_TYPE_HASH, SMDB_TYPE_HASH_LEN) == 0)
+ if (SMDB_IS_TYPE_HASH(type))
return DB_HASH;
- if (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)
+ if (SMDB_IS_TYPE_BTREE(type))
return DB_BTREE;
return DB_UNKNOWN;
@@ -64,11 +62,11 @@ smdb_type_to_db2_type(type)
**
** Returns:
** The SMDBE error corresponding to the db2 error.
-** If we don't have a corresponding error, it returs errno.
+** If we don't have a corresponding error, it returns errno.
**
*/
-int
+static int
db2_error_to_smdb(error)
int error;
{
@@ -80,55 +78,55 @@ db2_error_to_smdb(error)
case DB_INCOMPLETE:
result = SMDBE_INCOMPLETE;
break;
-# endif /* DB_INCOMPLETE */
+# endif
# ifdef DB_NOTFOUND
case DB_NOTFOUND:
result = SMDBE_NOT_FOUND;
break;
-# endif /* DB_NOTFOUND */
+# endif
# ifdef DB_KEYEMPTY
case DB_KEYEMPTY:
result = SMDBE_KEY_EMPTY;
break;
-# endif /* DB_KEYEMPTY */
+# endif
# ifdef DB_KEYEXIST
case DB_KEYEXIST:
result = SMDBE_KEY_EXIST;
break;
-# endif /* DB_KEYEXIST */
+# endif
# ifdef DB_LOCK_DEADLOCK
case DB_LOCK_DEADLOCK:
result = SMDBE_LOCK_DEADLOCK;
break;
-# endif /* DB_LOCK_DEADLOCK */
+# endif
# ifdef DB_LOCK_NOTGRANTED
case DB_LOCK_NOTGRANTED:
result = SMDBE_LOCK_NOT_GRANTED;
break;
-# endif /* DB_LOCK_NOTGRANTED */
+# endif
# ifdef DB_LOCK_NOTHELD
case DB_LOCK_NOTHELD:
result = SMDBE_LOCK_NOT_HELD;
break;
-# endif /* DB_LOCK_NOTHELD */
+# endif
# ifdef DB_RUNRECOVERY
case DB_RUNRECOVERY:
result = SMDBE_RUN_RECOVERY;
break;
-# endif /* DB_RUNRECOVERY */
+# endif
# ifdef DB_OLD_VERSION
case DB_OLD_VERSION:
result = SMDBE_OLD_VERSION;
break;
-# endif /* DB_OLD_VERSION */
+# endif
case 0:
result = SMDBE_OK;
@@ -153,7 +151,7 @@ db2_error_to_smdb(error)
**
*/
-unsigned int
+static unsigned int
smdb_put_flags_to_db2_flags(flags)
SMDB_FLAG flags;
{
@@ -181,7 +179,7 @@ smdb_put_flags_to_db2_flags(flags)
**
*/
-int
+static int
smdb_cursor_get_flags_to_db2(flags)
SMDB_FLAG flags;
{
@@ -209,7 +207,7 @@ smdb_cursor_get_flags_to_db2(flags)
** interface laid out in smdb.h.
*/
-SMDB_DB2_DATABASE *
+static SMDB_DB2_DATABASE *
smdb2_malloc_database()
{
SMDB_DB2_DATABASE *db2;
@@ -221,7 +219,7 @@ smdb2_malloc_database()
return db2;
}
-int
+static int
smdb2_close(database)
SMDB_DATABASE *database;
{
@@ -239,7 +237,7 @@ smdb2_close(database)
return result;
}
-int
+static int
smdb2_del(database, key, flags)
SMDB_DATABASE *database;
SMDB_DBENT *key;
@@ -254,7 +252,7 @@ smdb2_del(database, key, flags)
return db2_error_to_smdb(db->del(db, NULL, &dbkey, flags));
}
-int
+static int
smdb2_fd(database, fd)
SMDB_DATABASE *database;
int *fd;
@@ -264,7 +262,7 @@ smdb2_fd(database, fd)
return db2_error_to_smdb(db->fd(db, fd));
}
-int
+static int
smdb2_lockfd(database)
SMDB_DATABASE *database;
{
@@ -273,7 +271,7 @@ smdb2_lockfd(database)
return db2->smdb2_lock_fd;
}
-int
+static int
smdb2_get(database, key, data, flags)
SMDB_DATABASE *database;
SMDB_DBENT *key;
@@ -295,7 +293,7 @@ smdb2_get(database, key, data, flags)
return db2_error_to_smdb(result);
}
-int
+static int
smdb2_put(database, key, data, flags)
SMDB_DATABASE *database;
SMDB_DBENT *key;
@@ -317,7 +315,7 @@ smdb2_put(database, key, data, flags)
}
-int
+static int
smdb2_set_owner(database, uid, gid)
SMDB_DATABASE *database;
uid_t uid;
@@ -340,7 +338,7 @@ smdb2_set_owner(database, uid, gid)
return SMDBE_OK;
}
-int
+static int
smdb2_sync(database, flags)
SMDB_DATABASE *database;
unsigned int flags;
@@ -350,7 +348,7 @@ smdb2_sync(database, flags)
return db2_error_to_smdb(db->sync(db, flags));
}
-int
+static int
smdb2_cursor_close(cursor)
SMDB_CURSOR *cursor;
{
@@ -362,7 +360,7 @@ smdb2_cursor_close(cursor)
return ret;
}
-int
+static int
smdb2_cursor_del(cursor, flags)
SMDB_CURSOR *cursor;
SMDB_FLAG flags;
@@ -372,7 +370,7 @@ smdb2_cursor_del(cursor, flags)
return db2_error_to_smdb(dbc->c_del(dbc, 0));
}
-int
+static int
smdb2_cursor_get(cursor, key, value, flags)
SMDB_CURSOR *cursor;
SMDB_DBENT *key;
@@ -398,7 +396,7 @@ smdb2_cursor_get(cursor, key, value, flags)
return db2_error_to_smdb(result);
}
-int
+static int
smdb2_cursor_put(cursor, key, value, flags)
SMDB_CURSOR *cursor;
SMDB_DBENT *key;
@@ -418,7 +416,7 @@ smdb2_cursor_put(cursor, key, value, flags)
return db2_error_to_smdb(dbc->c_put(dbc, &dbkey, &dbdata, 0));
}
-int
+static int
smdb2_cursor(database, cursor, flags)
SMDB_DATABASE *database;
SMDB_CURSOR **cursor;
@@ -430,9 +428,9 @@ smdb2_cursor(database, cursor, flags)
# if DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6
result = db->cursor(db, NULL, &db2_cursor, 0);
-# else /* DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6 */
+# else
result = db->cursor(db, NULL, &db2_cursor);
-# endif /* DB_VERSION_MAJOR > 2 || DB_VERSION_MINOR >= 6 */
+# endif
if (result != 0)
return db2_error_to_smdb(result);
@@ -477,6 +475,26 @@ smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
# endif /* DB_VERSION_MAJOR == 2 */
# if DB_VERSION_MAJOR > 2
+
+static void
+db_err_cb(
+#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3
+ dbenv,
+#endif
+ errpfx, msg)
+#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 3
+ const DB_ENV *dbenv;
+ const char *errpfx;
+ const char *msg;
+#else
+ const char *errpfx;
+ char *msg;
+#endif
+{
+ /* do not print/log any errors... */
+ return;
+}
+
static int
smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
char *db_name;
@@ -491,41 +509,31 @@ smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
if (result != 0 || *db == NULL)
return result;
+ (*db)->set_errcall(*db, db_err_cb);
if (db_params != NULL)
{
result = (*db)->set_cachesize(*db, 0,
db_params->smdbp_cache_size, 0);
if (result != 0)
- {
- (void) (*db)->close((*db), 0);
- *db = NULL;
- return db2_error_to_smdb(result);
- }
+ goto error;
if (db_type == DB_HASH)
{
result = (*db)->set_h_nelem(*db, db_params->smdbp_num_elements);
if (result != 0)
- {
- (void) (*db)->close(*db, 0);
- *db = NULL;
- return db2_error_to_smdb(result);
- }
+ goto error;
}
if (db_params->smdbp_allow_dup)
{
result = (*db)->set_flags(*db, DB_DUP);
if (result != 0)
- {
- (void) (*db)->close(*db, 0);
- *db = NULL;
- return db2_error_to_smdb(result);
- }
+ goto error;
}
}
result = (*db)->open(*db,
DBTXN /* transaction for DB 4.1 */
db_name, NULL, db_type, db_flags, DBMMODE);
+ error:
if (result != 0)
{
(void) (*db)->close(*db, 0);
@@ -534,6 +542,7 @@ smdb_db_open_internal(db_name, db_type, db_flags, db_params, db)
return db2_error_to_smdb(result);
}
# endif /* DB_VERSION_MAJOR > 2 */
+
/*
** SMDB_DB_OPEN -- Opens a db database.
**
diff --git a/contrib/sendmail/libsmdb/smndbm.c b/contrib/sendmail/libsmdb/smndbm.c
index 579c5f55171e..bd7bce54cf7f 100644
--- a/contrib/sendmail/libsmdb/smndbm.c
+++ b/contrib/sendmail/libsmdb/smndbm.c
@@ -19,7 +19,6 @@ SM_RCSID("@(#)$Id: smndbm.c,v 8.55 2013-11-22 20:51:49 ca Exp $")
#ifdef NDBM
-# define SMNDB_DIR_FILE_EXTENSION "dir"
# define SMNDB_PAG_FILE_EXTENSION "pag"
struct smdb_dbm_database_struct
diff --git a/contrib/sendmail/libsmutil/Makefile b/contrib/sendmail/libsmutil/Makefile
index baffab14d0d4..3bf1c4ba9b39 100644
--- a/contrib/sendmail/libsmutil/Makefile
+++ b/contrib/sendmail/libsmutil/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/libsmutil/cf.c b/contrib/sendmail/libsmutil/cf.c
index e447aca4f79d..f803b95ef607 100644
--- a/contrib/sendmail/libsmutil/cf.c
+++ b/contrib/sendmail/libsmutil/cf.c
@@ -39,7 +39,7 @@ getcfname(opmode, submitmode, cftype, conffile)
{
#if NETINFO
char *cflocation;
-#endif /* NETINFO */
+#endif
if (conffile != NULL)
return conffile;
@@ -71,6 +71,6 @@ getcfname(opmode, submitmode, cftype, conffile)
"sendmail.cf", '\0');
if (cflocation != NULL)
return cflocation;
-#endif /* NETINFO */
+#endif
return _PATH_SENDMAILCF;
}
diff --git a/contrib/sendmail/libsmutil/safefile.c b/contrib/sendmail/libsmutil/safefile.c
index 43d66eceee11..1c70c24440e5 100644
--- a/contrib/sendmail/libsmutil/safefile.c
+++ b/contrib/sendmail/libsmutil/safefile.c
@@ -25,8 +25,7 @@ SM_RCSID("@(#)$Id: safefile.c,v 8.130 2013-11-22 20:51:50 ca Exp $")
** fn -- filename to check.
** uid -- user id to compare against.
** gid -- group id to compare against.
-** user -- user name to compare against (used for group
-** sets).
+** user -- user name to compare against (used for group sets).
** flags -- modifiers:
** SFF_MUSTOWN -- "uid" must own this file.
** SFF_NOSLINK -- file cannot be a symbolic link.
@@ -82,9 +81,9 @@ safefile(fn, uid, gid, user, flags, mode, st)
# if HASLSTAT
if ((bitset(SFF_NOSLINK, flags) ? lstat(fn, st)
: stat(fn, st)) < 0)
-# else /* HASLSTAT */
+# else
if (stat(fn, st) < 0)
-# endif /* HASLSTAT */
+# endif
{
file_errno = errno;
}
@@ -100,19 +99,19 @@ safefile(fn, uid, gid, user, flags, mode, st)
# ifdef SUID_ROOT_FILES_OK
if (bitset(S_ISUID, st->st_mode))
-# else /* SUID_ROOT_FILES_OK */
+# else
if (bitset(S_ISUID, st->st_mode) && st->st_uid != 0 &&
st->st_uid != TrustedUid)
-# endif /* SUID_ROOT_FILES_OK */
+# endif
{
uid = st->st_uid;
user = NULL;
}
# ifdef SUID_ROOT_FILES_OK
if (bitset(S_ISGID, st->st_mode))
-# else /* SUID_ROOT_FILES_OK */
+# else
if (bitset(S_ISGID, st->st_mode) && st->st_gid != 0)
-# endif /* SUID_ROOT_FILES_OK */
+# endif
gid = st->st_gid;
}
@@ -473,9 +472,9 @@ safedirpath(fn, uid, gid, user, flags, level, offset)
# if HASLSTAT
ret = lstat(s, &stbuf);
-# else /* HASLSTAT */
+# else
ret = stat(s, &stbuf);
-# endif /* HASLSTAT */
+# endif
if (ret < 0)
{
ret = errno;
@@ -590,7 +589,7 @@ safedirpath(fn, uid, gid, user, flags, level, offset)
#ifdef S_ISVTX
!(bitnset(DBS_TRUSTSTICKYBIT, DontBlameSendmail) &&
bitset(S_ISVTX, stbuf.st_mode)) &&
-#endif /* S_ISVTX */
+#endif
bitset(mode, stbuf.st_mode))
{
if (tTd(44, 4))
@@ -686,7 +685,7 @@ safeopen(fn, omode, cmode, sff)
{
#if !NOFTRUNCATE
bool truncate;
-#endif /* !NOFTRUNCATE */
+#endif
int rval;
int fd;
int smode;
@@ -741,7 +740,7 @@ safeopen(fn, omode, cmode, sff)
truncate = bitset(O_TRUNC, omode);
if (truncate)
omode &= ~O_TRUNC;
-#endif /* !NOFTRUNCATE */
+#endif
fd = dfopen(fn, omode, cmode, sff);
if (fd < 0)
@@ -874,9 +873,9 @@ filechanged(fn, fd, stb)
/* only necessary if exclusive open follows symbolic links */
if (lstat(fn, stb) < 0 || stb->st_nlink != 1)
return true;
-# else /* HASLSTAT && BOGUS_O_EXCL */
+# else
return false;
-# endif /* HASLSTAT && BOGUS_O_EXCL */
+# endif
}
if (fstat(fd, &sta) < 0)
return true;
@@ -886,7 +885,7 @@ filechanged(fn, fd, stb)
sta.st_ino != stb->st_ino ||
# if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
sta.st_gen != stb->st_gen ||
-# endif /* HAS_ST_GEN && 0 */
+# endif
sta.st_uid != stb->st_uid ||
sta.st_gid != stb->st_gid)
{
@@ -903,7 +902,7 @@ filechanged(fn, fd, stb)
# if HAS_ST_GEN
sm_dprintf(" gen = %ld/%ld\n",
(long) stb->st_gen, (long) sta.st_gen);
-# endif /* HAS_ST_GEN */
+# endif
sm_dprintf(" uid = %ld/%ld\n",
(long) stb->st_uid, (long) sta.st_uid);
sm_dprintf(" gid = %ld/%ld\n",
@@ -947,7 +946,7 @@ dfopen(filename, omode, cmode, sff)
case EINTR: /* interrupted syscall */
#ifdef ETXTBSY
case ETXTBSY: /* Apollo: net file locked */
-#endif /* ETXTBSY */
+#endif
continue;
}
break;
diff --git a/contrib/sendmail/mail.local/Makefile b/contrib/sendmail/mail.local/Makefile
index f3776a9d502a..6cd2bc10511b 100644
--- a/contrib/sendmail/mail.local/Makefile
+++ b/contrib/sendmail/mail.local/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
force-install: FRC
diff --git a/contrib/sendmail/mail.local/mail.local.c b/contrib/sendmail/mail.local/mail.local.c
index 40387ef06e47..f193f9542375 100644
--- a/contrib/sendmail/mail.local/mail.local.c
+++ b/contrib/sendmail/mail.local/mail.local.c
@@ -29,17 +29,17 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $")
# include <unistd.h>
# ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-# endif /* EX_OK */
+# endif
# define LOCKFILE_PMODE 0
#include <sm/mbdb.h>
#include <sm/sysexits.h>
#ifndef HASHSPOOL
# define HASHSPOOL 0
-#endif /* ! HASHSPOOL */
+#endif
#ifndef HASHSPOOLMD5
# define HASHSPOOLMD5 0
-#endif /* ! HASHSPOOLMD5 */
+#endif
/*
** This is not intended to work on System V derived systems
@@ -78,7 +78,7 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $")
# if HASHSPOOLMD5
# define HASH_MD5 2
# include <openssl/md5.h>
-# endif /* HASHSPOOLMD5 */
+# endif
#endif /* HASHSPOOL */
#if _FFR_SPOOL_PATH
@@ -93,10 +93,10 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $")
#ifndef LOCKTO_RM
# define LOCKTO_RM 300 /* timeout for stale lockfile removal */
-#endif /* ! LOCKTO_RM */
+#endif
#ifndef LOCKTO_GLOB
# define LOCKTO_GLOB 400 /* global timeout for lockfile creation */
-#endif /* ! LOCKTO_GLOB */
+#endif
/* define a realloc() which works for NULL pointers */
#define REALLOC(ptr, size) (((ptr) == NULL) ? malloc(size) : realloc(ptr, size))
@@ -109,13 +109,13 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $")
# define flock(a, b) lockf(a, b, 0)
# ifdef LOCK_EX
# undef LOCK_EX
-# endif /* LOCK_EX */
+# endif
# define LOCK_EX F_LOCK
#endif /* LDA_USE_LOCKF */
#ifndef LOCK_EX
# include <sys/file.h>
-#endif /* ! LOCK_EX */
+#endif
/*
** If you don't have setreuid, and you have saved uids, and you have
@@ -125,29 +125,29 @@ SM_IDSTR(id, "@(#)$Id: mail.local.c,v 8.257 2013-11-22 20:51:51 ca Exp $")
#ifdef LDA_USE_SETEUID
# define setreuid(r, e) seteuid(e)
-#endif /* LDA_USE_SETEUID */
+#endif
#ifdef LDA_CONTENTLENGTH
# define CONTENTLENGTH 1
-#endif /* LDA_CONTENTLENGTH */
+#endif
#ifndef INADDRSZ
# define INADDRSZ 4 /* size of an IPv4 address in bytes */
-#endif /* ! INADDRSZ */
+#endif
#ifdef MAILLOCK
# include <maillock.h>
-#endif /* MAILLOCK */
+#endif
#ifndef MAILER_DAEMON
# define MAILER_DAEMON "MAILER-DAEMON"
-#endif /* ! MAILER_DAEMON */
+#endif
#ifdef CONTENTLENGTH
char ContentHdr[40] = "Content-Length: ";
off_t HeaderLength;
off_t BodyLength;
-#endif /* CONTENTLENGTH */
+#endif
bool EightBitMime = true; /* advertise 8BITMIME in LMTP */
char ErrBuf[10240]; /* error buffer */
@@ -164,9 +164,9 @@ char *HomeMailFile = NULL; /* store mail in homedir */
int HashType = HASH_NONE;
int HashDepth = 0;
bool StripRcptDomain = true;
-#else /* HASHSPOOL */
+#else
# define StripRcptDomain true
-#endif /* HASHSPOOL */
+#endif
char SpoolPath[MAXPATHLEN];
char *parseaddr __P((char *, bool));
@@ -183,7 +183,7 @@ void mailerr __P((const char *, const char *, ...));
void flush_error __P((void));
#if HASHSPOOL
const char *hashname __P((char *));
-#endif /* HASHSPOOL */
+#endif
static void sm_exit __P((int));
@@ -224,9 +224,9 @@ main(argc, argv)
# ifdef LOG_MAIL
openlog("mail.local", 0, LOG_MAIL);
-# else /* LOG_MAIL */
+# else
openlog("mail.local", 0);
-# endif /* LOG_MAIL */
+# endif
from = NULL;
@@ -242,9 +242,9 @@ main(argc, argv)
#else /* HASHSPOOL */
# if _FFR_SPOOL_PATH
while ((ch = getopt(argc, argv, "7BbdD:f:h:r:lp:s")) != -1)
-# else /* _FFR_SPOOL_PATH */
+# else
while ((ch = getopt(argc, argv, "7BbdD:f:h:r:ls")) != -1)
-# endif /* _FFR_SPOOL_PATH */
+# endif
#endif /* HASHSPOOL */
{
switch(ch)
@@ -313,7 +313,7 @@ main(argc, argv)
case 'm':
HashType = HASH_MD5;
break;
-# endif /* HASHSPOOLMD5 */
+# endif
default:
mailerr(NULL, "-H: unknown hash type");
@@ -815,7 +815,7 @@ store(from, inbody)
#ifdef CONTENTLENGTH
HeaderLength = 0;
BodyLength = -1;
-#endif /* CONTENTLENGTH */
+#endif
line[0] = '\0';
eline = true;
@@ -995,7 +995,7 @@ deliver(fd, name)
#ifdef CONTENTLENGTH
off_t headerbytes;
int readamount;
-#endif /* CONTENTLENGTH */
+#endif
char biffmsg[100], buf[8 * 1024];
SM_MBDB_T user;
@@ -1061,13 +1061,13 @@ deliver(fd, name)
if (sm_strlcpyn(path, sizeof(path),
#if HASHSPOOL
4,
-#else /* HASHSPOOL */
+#else
3,
-#endif /* HASHSPOOL */
+#endif
SpoolPath, "/",
#if HASHSPOOL
hashname(name),
-#endif /* HASHSPOOL */
+#endif
name) >= sizeof(path))
{
exitval = EX_UNAVAILABLE;
@@ -1115,9 +1115,9 @@ deliver(fd, name)
tryagain:
#ifdef MAILLOCK
p = name;
-#else /* MAILLOCK */
+#else
p = path;
-#endif /* MAILLOCK */
+#endif
if ((off = lockmbox(p)) != 0)
{
if (off == EX_TEMPFAIL || e_to_sys(off) == EX_TEMPFAIL)
@@ -1143,7 +1143,7 @@ tryagain:
(void) umask(0007);
gid = MAILGID;
mode |= S_IRGRP|S_IWGRP;
-#endif /* MAILGID */
+#endif
mbfd = open(path, O_APPEND|O_CREAT|O_EXCL|O_WRONLY,
mode);
@@ -1214,7 +1214,7 @@ tryagain:
}
#ifdef DEBUG
fprintf(stderr, "new euid = %d\n", (int) geteuid());
-#endif /* DEBUG */
+#endif
mbfd = open(path, O_APPEND|O_WRONLY, 0);
if (mbfd < 0)
{
@@ -1229,7 +1229,7 @@ tryagain:
sb.st_ino != fsb.st_ino ||
# if HAS_ST_GEN && 0 /* AFS returns random values for st_gen */
sb.st_gen != fsb.st_gen ||
-# endif /* HAS_ST_GEN && 0 */
+# endif
sb.st_uid != fsb.st_uid)
{
ExitVal = EX_TEMPFAIL;
@@ -1301,7 +1301,7 @@ tryagain:
}
#ifdef DEBUG
fprintf(stderr, "before writing: euid = %d\n", (int) geteuid());
-#endif /* DEBUG */
+#endif
#ifdef CONTENTLENGTH
headerbytes = (BodyLength >= 0) ? HeaderLength : -1 ;
for (;;)
@@ -1336,7 +1336,7 @@ tryagain:
#ifdef EDQUOT
if (errno == EDQUOT && BounceQuota)
errcode = "552 5.2.2";
-#endif /* EDQUOT */
+#endif
mailerr(errcode, "%s: %s",
path, sm_errstring(errno));
goto err3;
@@ -1357,7 +1357,7 @@ tryagain:
err3:
#ifdef DEBUG
fprintf(stderr, "reset euid = %d\n", (int) geteuid());
-#endif /* DEBUG */
+#endif
if (mbfd >= 0)
(void) ftruncate(mbfd, curoff);
err1: if (mbfd >= 0)
@@ -1389,7 +1389,7 @@ err0: (void) setreuid(0, 0);
#ifdef EDQUOT
if (errno == EDQUOT && BounceQuota)
errcode = "552 5.2.2";
-#endif /* EDQUOT */
+#endif
mailerr(errcode, "%s: %s", path, sm_errstring(errno));
mbfd = open(path, O_WRONLY, 0);
if (mbfd < 0 ||
@@ -1403,7 +1403,7 @@ err0: (void) setreuid(0, 0);
sb.st_ino != fsb.st_ino ||
# if HAS_ST_GEN && 0 /* AFS returns random values for st_gen */
sb.st_gen != fsb.st_gen ||
-# endif /* HAS_ST_GEN && 0 */
+# endif
sb.st_uid != fsb.st_uid
)
{
@@ -1429,7 +1429,7 @@ err0: (void) setreuid(0, 0);
}
#ifdef DEBUG
fprintf(stderr, "reset euid = %d\n", (int) geteuid());
-#endif /* DEBUG */
+#endif
unlockmbox();
if (LMTPMode)
printf("250 2.1.5 %s Ok\r\n", name);
@@ -1599,9 +1599,9 @@ usage()
ExitVal = EX_USAGE;
# if _FFR_SPOOL_PATH
mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] [-p path] user ...");
-# else /* _FFR_SPOOL_PATH */
+# else
mailerr(NULL, "usage: mail.local [-7] [-B] [-b] [-d] [-l] [-s] [-f from|-r from] [-h filename] user ...");
-# endif /* _FFR_SPOOL_PATH */
+# endif
sm_exit(ExitVal);
}
@@ -1667,7 +1667,7 @@ hashname(name)
unsigned char md5[18];
# if MAXPATHLEN <= 24
ERROR _MAXPATHLEN <= 24
-# endif /* MAXPATHLEN <= 24 */
+# endif
char b64[24];
MD5_LONG bits;
int j;
@@ -1751,73 +1751,73 @@ e_to_sys(num)
#endif /* EDQUOT */
#ifdef EAGAIN
case EAGAIN: /* Resource temporarily unavailable */
-#endif /* EAGAIN */
+#endif
#ifdef EBUSY
case EBUSY: /* Device busy */
-#endif /* EBUSY */
+#endif
#ifdef EPROCLIM
case EPROCLIM: /* Too many processes */
-#endif /* EPROCLIM */
+#endif
#ifdef EUSERS
case EUSERS: /* Too many users */
-#endif /* EUSERS */
+#endif
#ifdef ECONNABORTED
case ECONNABORTED: /* Software caused connection abort */
-#endif /* ECONNABORTED */
+#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: /* Connection refused */
-#endif /* ECONNREFUSED */
+#endif
#ifdef ECONNRESET
case ECONNRESET: /* Connection reset by peer */
-#endif /* ECONNRESET */
+#endif
#ifdef EDEADLK
case EDEADLK: /* Resource deadlock avoided */
-#endif /* EDEADLK */
+#endif
#ifdef EFBIG
case EFBIG: /* File too large */
-#endif /* EFBIG */
+#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: /* Host is down */
-#endif /* EHOSTDOWN */
+#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: /* No route to host */
-#endif /* EHOSTUNREACH */
+#endif
#ifdef EMFILE
case EMFILE: /* Too many open files */
-#endif /* EMFILE */
+#endif
#ifdef ENETDOWN
case ENETDOWN: /* Network is down */
-#endif /* ENETDOWN */
+#endif
#ifdef ENETRESET
case ENETRESET: /* Network dropped connection on reset */
-#endif /* ENETRESET */
+#endif
#ifdef ENETUNREACH
case ENETUNREACH: /* Network is unreachable */
-#endif /* ENETUNREACH */
+#endif
#ifdef ENFILE
case ENFILE: /* Too many open files in system */
-#endif /* ENFILE */
+#endif
#ifdef ENOBUFS
case ENOBUFS: /* No buffer space available */
-#endif /* ENOBUFS */
+#endif
#ifdef ENOMEM
case ENOMEM: /* Cannot allocate memory */
-#endif /* ENOMEM */
+#endif
#ifdef ENOSPC
case ENOSPC: /* No space left on device */
-#endif /* ENOSPC */
+#endif
#ifdef EROFS
case EROFS: /* Read-only file system */
-#endif /* EROFS */
+#endif
#ifdef ESTALE
case ESTALE: /* Stale NFS file handle */
-#endif /* ESTALE */
+#endif
#ifdef ETIMEDOUT
case ETIMEDOUT: /* Connection timed out */
-#endif /* ETIMEDOUT */
+#endif
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN && EWOULDBLOCK != EDEADLK
case EWOULDBLOCK: /* Operation would block. */
-#endif /* defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN && EWOULDBLOCK != EDEADLK */
+#endif
ExitVal = EX_TEMPFAIL;
break;
@@ -1864,7 +1864,7 @@ e_to_sys(num)
# if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)mktemp.c 8.1 (Berkeley) 6/4/93";
-# endif /* defined(LIBC_SCCS) && !defined(lint) */
+# endif
# include <sys/types.h>
# include <sys/stat.h>
diff --git a/contrib/sendmail/mailstats/Makefile b/contrib/sendmail/mailstats/Makefile
index b4137b7c451b..526cd161efd1 100644
--- a/contrib/sendmail/mailstats/Makefile
+++ b/contrib/sendmail/mailstats/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/mailstats/mailstats.c b/contrib/sendmail/mailstats/mailstats.c
index 7107e62744b5..6b34a576e851 100644
--- a/contrib/sendmail/mailstats/mailstats.c
+++ b/contrib/sendmail/mailstats/mailstats.c
@@ -30,7 +30,7 @@ SM_IDSTR(id, "@(#)$Id: mailstats.c,v 8.103 2013-11-22 20:51:51 ca Exp $")
#include <time.h>
#ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
+#endif
#include <sysexits.h>
#include <sm/errstring.h>
diff --git a/contrib/sendmail/makemap/Makefile b/contrib/sendmail/makemap/Makefile
index 953d28b37e7e..301a639d437e 100644
--- a/contrib/sendmail/makemap/Makefile
+++ b/contrib/sendmail/makemap/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/makemap/Makefile.m4 b/contrib/sendmail/makemap/Makefile.m4
index c6dffd0f57f5..9ff01cd25491 100644
--- a/contrib/sendmail/makemap/Makefile.m4
+++ b/contrib/sendmail/makemap/Makefile.m4
@@ -21,4 +21,5 @@ bldPRODUCT_START(`manpage', `makemap')
define(`bldSOURCES', `makemap.8')
bldPRODUCT_END
+
bldFINISH
diff --git a/contrib/sendmail/makemap/makemap.8 b/contrib/sendmail/makemap/makemap.8
index a6bfd21462c4..fa250109b842 100644
--- a/contrib/sendmail/makemap/makemap.8
+++ b/contrib/sendmail/makemap/makemap.8
@@ -46,7 +46,7 @@ and outputs them to the indicated
.PP
Depending on how it is compiled,
.B makemap
-handles up to three different database formats,
+handles different database formats,
selected using the
.I maptype
parameter.
@@ -67,6 +67,14 @@ hash
Hash format maps.
This also requires the Berkeley DB
library.
+.TP
+cdb
+CDB (Constant DataBase) format maps.
+This requires the tinycdb library.
+.TP
+implicit
+The first available format in the following order:
+hash, dbm, and cdb.
.PP
In all cases,
.B makemap
@@ -142,6 +150,8 @@ List supported map types.
.B \-o
Append to an old file.
This allows you to augment an existing file.
+Note: this might not be supported by all database types,
+e.g., cdb.
.TP
.B \-r
Allow replacement of existing keys.
@@ -164,6 +174,9 @@ dump (unmap) the content of the database to standard output.
.TP
.B \-v
Verbosely print what it is doing.
+.P
+.SH Example
+makemap hash /etc/mail/access < /etc/mail/access
.SH SEE ALSO
sendmail(8), newaliases(1)
.SH HISTORY
diff --git a/contrib/sendmail/makemap/makemap.c b/contrib/sendmail/makemap/makemap.c
index cf1f62c8ea9e..4aa8d6ddab38 100644
--- a/contrib/sendmail/makemap/makemap.c
+++ b/contrib/sendmail/makemap/makemap.c
@@ -26,15 +26,16 @@ SM_IDSTR(id, "@(#)$Id: makemap.c,v 8.183 2013-11-22 20:51:52 ca Exp $")
#include <sys/types.h>
#ifndef ISC_UNIX
# include <sys/file.h>
-#endif /* ! ISC_UNIX */
+#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
+#endif
#include <sysexits.h>
#include <sendmail/sendmail.h>
+#include <sm/path.h>
#include <sendmail/pathnames.h>
#include <libsmdb/smdb.h>
@@ -50,13 +51,15 @@ uid_t TrustedUid = 0;
BITMAP256 DontBlameSendmail;
#define BUFSIZE 1024
-#define ISSEP(c) (sep == '\0' ? isascii(c) && isspace(c) : (c) == sep)
+#define ISASCII(c) isascii((unsigned char)(c))
+#define ISSEP(c) (sep == '\0' ? ISASCII(c) && isspace(c) : (c) == sep)
-static void usage __P((char *));
+static void usage __P((const char *));
+static char *readcf __P((const char *, char *, bool));
static void
usage(progname)
- char *progname;
+ const char *progname;
{
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"Usage: %s [-C cffile] [-N] [-c cachesize] [-D commentchar]\n",
@@ -70,6 +73,181 @@ usage(progname)
exit(EX_USAGE);
}
+/*
+** READCF -- read some settings from configuration file.
+**
+** Parameters:
+** cfile -- configuration file name.
+** mapfile -- file name of map to look up (if not NULL/empty)
+** Note: this finds the first match, so in case someone
+** uses the same map file for different maps, they are
+** hopefully using the same map type.
+** fullpath -- compare the full paths or just the "basename"s?
+** (even excluding any .ext !)
+**
+** Returns:
+** pointer to map class name (static!)
+*/
+
+static char *
+readcf(cfile, mapfile, fullpath)
+ const char *cfile;
+ char *mapfile;
+ bool fullpath;
+{
+ SM_FILE_T *cfp;
+ char buf[MAXLINE];
+ static char classbuf[MAXLINE];
+ char *classname;
+ char *p;
+
+ if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile,
+ SM_IO_RDONLY, NULL)) == NULL)
+ {
+ sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
+ "makemap: %s: %s\n",
+ cfile, sm_errstring(errno));
+ exit(EX_NOINPUT);
+ }
+ classname = NULL;
+ classbuf[0] = '\0';
+
+ if (!fullpath && mapfile != NULL)
+ {
+ p = strrchr(mapfile, '/');
+ if (p != NULL)
+ mapfile = ++p;
+ p = strrchr(mapfile, '.');
+ if (p != NULL)
+ *p = '\0';
+ }
+
+ while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
+ {
+ char *b;
+
+ if ((b = strchr(buf, '\n')) != NULL)
+ *b = '\0';
+
+ b = buf;
+ switch (*b++)
+ {
+ case 'O': /* option */
+#if HASFCHOWN
+ if (strncasecmp(b, " TrustedUser", 12) == 0 &&
+ !(ISASCII(b[12]) && isalnum(b[12])))
+ {
+ b = strchr(b, '=');
+ if (b == NULL)
+ continue;
+ while (ISASCII(*++b) && isspace(*b))
+ continue;
+ if (ISASCII(*b) && isdigit(*b))
+ TrustedUid = atoi(b);
+ else
+ {
+ struct passwd *pw;
+
+ TrustedUid = 0;
+ pw = getpwnam(b);
+ if (pw == NULL)
+ (void) sm_io_fprintf(smioerr,
+ SM_TIME_DEFAULT,
+ "TrustedUser: unknown user %s\n", b);
+ else
+ TrustedUid = pw->pw_uid;
+ }
+
+# ifdef UID_MAX
+ if (TrustedUid > UID_MAX)
+ {
+ (void) sm_io_fprintf(smioerr,
+ SM_TIME_DEFAULT,
+ "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
+ (long) TrustedUid,
+ (long) UID_MAX);
+ TrustedUid = 0;
+ }
+# endif /* UID_MAX */
+ }
+#endif /* HASFCHOWN */
+ break;
+
+ case 'K': /* Keyfile (map) */
+ if (classname != NULL) /* found it already */
+ continue;
+ if (mapfile == NULL || *mapfile == '\0')
+ continue;
+
+ /* cut off trailing spaces */
+ for (p = buf + strlen(buf) - 1; ISASCII(*p) && isspace(*p) && p > buf; p--)
+ *p = '\0';
+
+ /* find the last argument */
+ p = strrchr(buf, ' ');
+ if (p == NULL)
+ continue;
+ b = strstr(p, mapfile);
+ if (b == NULL)
+ continue;
+ if (b <= buf)
+ continue;
+ if (!fullpath)
+ {
+ p = strrchr(b, '.');
+ if (p != NULL)
+ *p = '\0';
+ }
+
+ /* allow trailing white space? */
+ if (strcmp(mapfile, b) != 0)
+ continue;
+ /* SM_ASSERT(b > buf); */
+ --b;
+ if (!ISASCII(*b))
+ continue;
+ if (!isspace(*b) && fullpath)
+ continue;
+ if (!fullpath && !(SM_IS_DIR_DELIM(*b) || isspace(*b)))
+ continue;
+
+ /* basically from readcf.c */
+ for (b = buf + 1; ISASCII(*b) && isspace(*b); b++)
+ ;
+ if (!(ISASCII(*b) && isalnum(*b)))
+ {
+ /* syserr("readcf: config K line: no map name"); */
+ return NULL;
+ }
+
+ while ((ISASCII(*++b) && isalnum(*b)) || *b == '_' || *b == '.')
+ ;
+ if (*b != '\0')
+ *b++ = '\0';
+ while (ISASCII(*b) && isspace(*b))
+ b++;
+ if (!(ISASCII(*b) && isalnum(*b)))
+ {
+ /* syserr("readcf: config K line, map %s: no map class", b); */
+ return NULL;
+ }
+ classname = b;
+ while (ISASCII(*++b) && isalnum(*b))
+ ;
+ if (*b != '\0')
+ *b++ = '\0';
+ (void) sm_strlcpy(classbuf, classname, sizeof classbuf);
+ break;
+
+ default:
+ continue;
+ }
+ }
+ (void) sm_io_close(cfp, SM_TIME_DEFAULT);
+
+ return classbuf;
+}
+
int
main(argc, argv)
int argc;
@@ -84,11 +262,13 @@ main(argc, argv)
bool verbose = false;
bool foldcase = true;
bool unmake = false;
+ bool didreadcf = false;
char sep = '\0';
char comment = '#';
int exitstat;
int opt;
char *typename = NULL;
+ char *fallback = NULL;
char *mapname = NULL;
unsigned int lineno;
int st;
@@ -103,10 +283,6 @@ main(argc, argv)
SMDB_DBPARAMS params;
SMDB_USER_INFO user_info;
char ibuf[BUFSIZE];
-#if HASFCHOWN
- SM_FILE_T *cfp;
- char buf[MAXLINE];
-#endif /* HASFCHOWN */
static char rnamebuf[MAXNAME]; /* holds RealUserName */
extern char *optarg;
extern int optind;
@@ -136,7 +312,7 @@ main(argc, argv)
(void) sm_strlcpy(user_info.smdbu_name, RunAsUserName,
SMDB_MAX_USER_NAME_LEN);
-#define OPTIONS "C:D:Nc:deflorst:uv"
+#define OPTIONS "C:D:Nc:defi:Llorst:uvx"
while ((opt = getopt(argc, argv, OPTIONS)) != -1)
{
switch (opt)
@@ -165,12 +341,23 @@ main(argc, argv)
foldcase = false;
break;
+ case 'i':
+ fallback =optarg;
+ break;
+
case 'D':
comment = *optarg;
break;
+ case 'L':
+ smdb_print_available_types(false);
+ sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "cf\nCF\n");
+ exit(EX_OK);
+ break;
+
case 'l':
- smdb_print_available_types();
+ smdb_print_available_types(false);
exit(EX_OK);
break;
@@ -206,6 +393,11 @@ main(argc, argv)
case 'v':
verbose = true;
break;
+
+ case 'x':
+ smdb_print_available_types(true);
+ exit(EX_OK);
+ break;
default:
usage(progname);
@@ -233,68 +425,18 @@ main(argc, argv)
mapname = argv[1];
}
+#define TYPEFROMCF (strcasecmp(typename, "cf") == 0)
+#define FULLPATHFROMCF (strcmp(typename, "cf") == 0)
+
#if HASFCHOWN
- /* Find TrustedUser value in sendmail.cf */
- if ((cfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, cfile, SM_IO_RDONLY,
- NULL)) == NULL)
- {
- sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "makemap: %s: %s\n",
- cfile, sm_errstring(errno));
- exit(EX_NOINPUT);
- }
- while (sm_io_fgets(cfp, SM_TIME_DEFAULT, buf, sizeof(buf)) >= 0)
+ if (geteuid() == 0)
{
- register char *b;
-
- if ((b = strchr(buf, '\n')) != NULL)
- *b = '\0';
-
- b = buf;
- switch (*b++)
- {
- case 'O': /* option */
- if (strncasecmp(b, " TrustedUser", 12) == 0 &&
- !(isascii(b[12]) && isalnum(b[12])))
- {
- b = strchr(b, '=');
- if (b == NULL)
- continue;
- while (isascii(*++b) && isspace(*b))
- continue;
- if (isascii(*b) && isdigit(*b))
- TrustedUid = atoi(b);
- else
- {
- TrustedUid = 0;
- pw = getpwnam(b);
- if (pw == NULL)
- (void) sm_io_fprintf(smioerr,
- SM_TIME_DEFAULT,
- "TrustedUser: unknown user %s\n", b);
- else
- TrustedUid = pw->pw_uid;
- }
-
-# ifdef UID_MAX
- if (TrustedUid > UID_MAX)
- {
- (void) sm_io_fprintf(smioerr,
- SM_TIME_DEFAULT,
- "TrustedUser: uid value (%ld) > UID_MAX (%ld)",
- (long) TrustedUid,
- (long) UID_MAX);
- TrustedUid = 0;
- }
-# endif /* UID_MAX */
- break;
- }
-
-
- default:
- continue;
- }
+ if (TYPEFROMCF)
+ typename = readcf(cfile, mapname, FULLPATHFROMCF);
+ else
+ (void) readcf(cfile, NULL, false);
+ didreadcf = true;
}
- (void) sm_io_close(cfp, SM_TIME_DEFAULT);
#endif /* HASFCHOWN */
if (!params.smdbp_allow_dup && !allowreplace)
@@ -318,6 +460,36 @@ main(argc, argv)
params.smdbp_num_elements = 4096;
+ if (!didreadcf && TYPEFROMCF)
+ {
+ typename = readcf(cfile, mapname, FULLPATHFROMCF);
+ didreadcf = true;
+ }
+ if (didreadcf && (typename == NULL || *typename == '\0'))
+ {
+ if (fallback != NULL && *fallback != '\0')
+ {
+ typename = fallback;
+ if (verbose)
+ (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
+ "%s: mapfile %s: not found in %s, using fallback %s\n",
+ progname, mapname, cfile, fallback);
+ }
+ else
+ {
+ (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
+ "%s: mapfile %s: not found in %s\n",
+ progname, mapname, cfile);
+ exit(EX_DATAERR);
+ }
+ }
+
+ /*
+ ** Note: if "implicit" is selected it does not work like
+ ** sendmail: it will just use the first available DB type,
+ ** it won't try several (for -u) to find one that "works".
+ */
+
errno = smdb_open_database(&database, mapname, mode, smode, sff,
typename, &user_info, &params);
if (errno != SMDBE_OK)
@@ -417,7 +589,7 @@ main(argc, argv)
if (ibuf[0] == '\0' || ibuf[0] == comment)
continue;
- if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0]))
+ if (sep == '\0' && ISASCII(ibuf[0]) && isspace(ibuf[0]))
{
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"%s: %s: line %u: syntax error (leading space)\n",
@@ -432,7 +604,7 @@ main(argc, argv)
for (p = ibuf; *p != '\0' && !(ISSEP(*p)); p++)
{
- if (foldcase && isascii(*p) && isupper(*p))
+ if (foldcase && ISASCII(*p) && isupper(*p))
*p = tolower(*p);
}
db_key.size = p - ibuf;
diff --git a/contrib/sendmail/praliases/Makefile b/contrib/sendmail/praliases/Makefile
index adf435249c19..b7e69043d074 100644
--- a/contrib/sendmail/praliases/Makefile
+++ b/contrib/sendmail/praliases/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/praliases/praliases.c b/contrib/sendmail/praliases/praliases.c
index 67b28eaec91c..682d4e14d2ea 100644
--- a/contrib/sendmail/praliases/praliases.c
+++ b/contrib/sendmail/praliases/praliases.c
@@ -28,13 +28,13 @@ SM_IDSTR(id, "@(#)$Id: praliases.c,v 8.98 2013-11-22 20:51:53 ca Exp $")
#include <unistd.h>
#ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
+#endif
#include <sysexits.h>
#ifndef NOT_SENDMAIL
# define NOT_SENDMAIL
-#endif /* ! NOT_SENDMAIL */
+#endif
#include <sendmail/sendmail.h>
#include <sendmail/pathnames.h>
#include <libsmdb/smdb.h>
@@ -274,9 +274,7 @@ praliases(filename, argc, argv)
if (db_type != NULL && *db_type != '\0')
{
if (db_type != SMDB_TYPE_DEFAULT &&
- strcmp(db_type, "hash") != 0 &&
- strcmp(db_type, "btree") != 0 &&
- strcmp(db_type, "dbm") != 0)
+ !smdb_is_db_type(db_type))
{
sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"praliases: Skipping non-file based alias type %s\n",
diff --git a/contrib/sendmail/rmail/Makefile b/contrib/sendmail/rmail/Makefile
index eeace604b1d7..059e4c188b6d 100644
--- a/contrib/sendmail/rmail/Makefile
+++ b/contrib/sendmail/rmail/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
force-install: FRC
diff --git a/contrib/sendmail/rmail/rmail.c b/contrib/sendmail/rmail/rmail.c
index 60c0100c9ee1..e4317dad7dbd 100644
--- a/contrib/sendmail/rmail/rmail.c
+++ b/contrib/sendmail/rmail/rmail.c
@@ -60,7 +60,7 @@ SM_IDSTR(id, "@(#)$Id: rmail.c,v 8.63 2013-11-22 20:51:53 ca Exp $")
#include <unistd.h>
#ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
+#endif
#include <sysexits.h>
#include <sm/conf.h>
diff --git a/contrib/sendmail/smrsh/Makefile b/contrib/sendmail/smrsh/Makefile
index e5dd03089f19..90487fb2a24c 100644
--- a/contrib/sendmail/smrsh/Makefile
+++ b/contrib/sendmail/smrsh/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/smrsh/smrsh.c b/contrib/sendmail/smrsh/smrsh.c
index 86e20a4cf537..8c4e47ca200b 100644
--- a/contrib/sendmail/smrsh/smrsh.c
+++ b/contrib/sendmail/smrsh/smrsh.c
@@ -64,7 +64,7 @@ SM_IDSTR(id, "@(#)$Id: smrsh.c,v 8.66 2013-11-22 20:52:00 ca Exp $")
#include <errno.h>
#ifdef EX_OK
# undef EX_OK
-#endif /* EX_OK */
+#endif
#include <sysexits.h>
#include <syslog.h>
#include <stdlib.h>
@@ -76,9 +76,9 @@ SM_IDSTR(id, "@(#)$Id: smrsh.c,v 8.66 2013-11-22 20:52:00 ca Exp $")
#ifndef CMDDIR
# ifdef SMRSH_CMDDIR
# define CMDDIR SMRSH_CMDDIR
-# else /* SMRSH_CMDDIR */
+# else
# define CMDDIR "/usr/adm/sm.bin"
-# endif /* SMRSH_CMDDIR */
+# endif
#endif /* ! CMDDIR */
/* characters disallowed in the shell "-c" argument */
@@ -88,9 +88,9 @@ SM_IDSTR(id, "@(#)$Id: smrsh.c,v 8.66 2013-11-22 20:52:00 ca Exp $")
#ifndef PATH
# ifdef SMRSH_PATH
# define PATH SMRSH_PATH
-# else /* SMRSH_PATH */
+# else
# define PATH "/bin:/usr/bin:/usr/ucb"
-# endif /* SMRSH_PATH */
+# endif
#endif /* ! PATH */
char newcmdbuf[1000];
@@ -128,7 +128,7 @@ addcmd(s, cmd, len)
"%s: command too long: %s\n", prg, par);
#ifndef DEBUG
syslog(LOG_WARNING, "command too long: %.40s", par);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
if (cmd)
@@ -155,9 +155,9 @@ main(argc, argv)
#ifndef DEBUG
# ifndef LOG_MAIL
openlog("smrsh", 0);
-# else /* ! LOG_MAIL */
+# else
openlog("smrsh", LOG_ODELAY|LOG_CONS, LOG_MAIL);
-# endif /* ! LOG_MAIL */
+# endif
#endif /* ! DEBUG */
(void) sm_strlcpyn(pathbuf, sizeof pathbuf, 2, "PATH=", PATH);
@@ -176,7 +176,7 @@ main(argc, argv)
"Usage: %s -c command\n", prg);
#ifndef DEBUG
syslog(LOG_ERR, "usage");
-#endif /* ! DEBUG */
+#endif
exit(EX_USAGE);
}
@@ -193,7 +193,7 @@ main(argc, argv)
{
#ifndef DEBUG
syslog(LOG_ERR, "too many specials: %.40s", SPECIALS);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
(void) sm_strlcpy(specialbuf, SPECIALS, sizeof specialbuf);
@@ -211,7 +211,7 @@ main(argc, argv)
"%s: command too long: %s\n", prg, par);
#ifndef DEBUG
syslog(LOG_WARNING, "command too long: %.40s", par);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
@@ -238,7 +238,7 @@ main(argc, argv)
prg);
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: missing command to exec", (int) getuid());
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
break;
@@ -300,14 +300,14 @@ main(argc, argv)
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: attempt to use \"%s\" (filename too long)",
(int) getuid(), cmd);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
#ifdef DEBUG
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Trying %s\n", cmdbuf);
-#endif /* DEBUG */
+#endif
if (stat(cmdbuf, &st) < 0)
{
/* can't stat it */
@@ -319,13 +319,13 @@ main(argc, argv)
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: attempt to use \"%s\" (stat failed)",
(int) getuid(), cmd);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
if (!S_ISREG(st.st_mode)
#ifdef S_ISLNK
&& !S_ISLNK(st.st_mode)
-#endif /* S_ISLNK */
+#endif
)
{
/* can't stat it */
@@ -337,12 +337,12 @@ main(argc, argv)
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: attempt to use \"%s\" (not a file)",
(int) getuid(), cmd);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
if (access(cmdbuf, X_OK) < 0)
{
- /* oops.... crack attack possiblity */
+ /* oops.... crack attack possibility */
(void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT,
"%s: \"%s\" not available for sendmail programs\n",
prg, cmd);
@@ -351,7 +351,7 @@ main(argc, argv)
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: attempt to use \"%s\"",
(int) getuid(), cmd);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
@@ -395,7 +395,7 @@ main(argc, argv)
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: attempt to use %c in command: %s",
(int) getuid(), *r, par);
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
if (isexec)
@@ -405,7 +405,7 @@ main(argc, argv)
#ifndef DEBUG
syslog(LOG_CRIT, "uid %d: missing command to exec",
(int) getuid());
-#endif /* ! DEBUG */
+#endif
exit(EX_UNAVAILABLE);
}
/* make sure we created something */
@@ -415,7 +415,7 @@ main(argc, argv)
"Usage: %s -c command\n", prg);
#ifndef DEBUG
syslog(LOG_ERR, "usage");
-#endif /* ! DEBUG */
+#endif
exit(EX_USAGE);
}
@@ -425,13 +425,13 @@ main(argc, argv)
#ifdef DEBUG
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n", newcmdbuf);
-#endif /* DEBUG */
+#endif
(void) execle("/bin/sh", "/bin/sh", "-c", newcmdbuf,
(char *)NULL, newenv);
save_errno = errno;
#ifndef DEBUG
syslog(LOG_CRIT, "Cannot exec /bin/sh: %s", sm_errstring(errno));
-#endif /* ! DEBUG */
+#endif
errno = save_errno;
sm_perror("/bin/sh");
exit(EX_OSFILE);
diff --git a/contrib/sendmail/src/Makefile b/contrib/sendmail/src/Makefile
index 2326faf113ba..63554abaf1e0 100644
--- a/contrib/sendmail/src/Makefile
+++ b/contrib/sendmail/src/Makefile
@@ -6,10 +6,10 @@ OPTIONS= $(CONFIG) $(FLAGS)
all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
-check: FRC
- $(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/src/Makefile.m4 b/contrib/sendmail/src/Makefile.m4
index a666aa276e5b..e7f185162778 100644
--- a/contrib/sendmail/src/Makefile.m4
+++ b/contrib/sendmail/src/Makefile.m4
@@ -6,7 +6,7 @@ define(`confREQUIRE_SM_OS_H', `true')
bldPRODUCT_START(`executable', `sendmail')
define(`bldBIN_TYPE', `G')
define(`bldINSTALL_DIR', `')
-define(`bldSOURCES', `main.c alias.c arpadate.c bf.c collect.c conf.c control.c convtime.c daemon.c deliver.c domain.c envelope.c err.c headers.c macro.c map.c mci.c milter.c mime.c parseaddr.c queue.c ratectrl.c readcf.c recipient.c sasl.c savemail.c sfsasl.c shmticklib.c sm_resolve.c srvrsmtp.c stab.c stats.c sysexits.c timers.c 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 tlsh.c tls.c trace.c udb.c usersmtp.c util.c version.c ')
PREPENDDEF(`confENVDEF', `confMAPDEF')
bldPUSH_SMLIB(`sm')
bldPUSH_SMLIB(`smutil')
@@ -52,7 +52,7 @@ MSPQ=ifdef(`confMSP_QUEUE_DIR', `confMSP_QUEUE_DIR', `/var/spool/clientmqueue')
${DESTDIR}${MSPQ}:
@echo "Please read INSTALL if anything fails while installing the binary."
- @echo "You must have setup a new user ${MSPQOWN} and a new group ${GBINGRP}"
+ @echo "You must have set up a new user ${MSPQOWN} and a new group ${GBINGRP}"
@echo "as explained in sendmail/SECURITY."
mkdir -p ${DESTDIR}${MSPQ}
chown ${MSPQOWN} ${DESTDIR}${MSPQ}
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README
index fddce9d36f3b..06d727de4baf 100644
--- a/contrib/sendmail/src/README
+++ b/contrib/sendmail/src/README
@@ -91,6 +91,14 @@ attempt to be backward compatible.
The options are:
+CDB Constant DataBase, requires tinycdb (0.75), see
+ http://www.corpit.ru/mjt/tinycdb.html
+ CDB is included automatically if the Build script can find
+ a library named libcdb.a or libcdb.so.
+ By default, .cdb is used as extension for cdb maps, however,
+ if CDB is set to 2, then .db is used to make transition from
+ hash maps easier. Note: this usually requires to exclude cdb
+ from confLIBSEARCH, see devtools/README.
NEWDB The new Berkeley DB package. Some systems (e.g., BSD/OS and
Digital UNIX 4.0) have some version of this package
pre-installed. If your system does not have Berkeley DB
@@ -129,7 +137,7 @@ 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.
+ 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
@@ -292,6 +300,8 @@ HASULIMIT Define this if you have the ulimit(2) syscall (System V
HASWAITPID Define this if you have the waitpid(2) syscall.
HASGETDTABLESIZE
Define this if you have the getdtablesize(2) syscall.
+HAS_GETHOSTBYNAME2 Define this to 1 if your system supports
+ gethostbyname2(2).
HAS_ST_GEN Define this to 1 if your system has the st_gen field in
the stat structure (see stat(2)).
HASSRANDOMDEV Define this if your system has the srandomdev(3) function
@@ -525,6 +535,7 @@ Several are assumed based on other compilation flags -- if you want to
"un-assume" something, you probably need to edit conf.h. Compilation
flags that add support for special features include:
+CDB Include support for tinycdb.
NDBM Include support for "new" DBM library for aliases and maps.
Normally defined in the Makefile.
NEWDB Include support for Berkeley DB package (hash & btree)
@@ -634,6 +645,16 @@ STARTTLS Enables SMTP STARTTLS (RFC 2487). This requires OpenSSL
(http://www.OpenSSL.org/); use OpenSSL 0.9.8zc or later.
See STARTTLS COMPILATION AND CONFIGURATION for further
information.
+TLS_EC Enable use of elliptic curve cryptography in STARTTLS.
+ If set to 2 sendmail uses SSL_CTX_set_ecdh_auto(),
+ if set to 1 it selects the NID_X9_62_prime256v1 curve
+ (created via EC_KEY_new_by_curve_name()) and uses
+ SSL_CTX_set_tmp_ecdh().
+ Support offered by different TLS libraries varies
+ greatly: some old versions do not support elliptic curve
+ cryptography at all, some new versions have it enabled
+ by default (i.e., no need to set TLS_EC at all), while
+ others may require one of the above settings.
TLS_NO_RSA Turn off support for RSA algorithms in STARTTLS.
MILTER Turn on support for external filters using the Milter API;
this option is set by default, to turn it off use
@@ -1673,13 +1694,6 @@ Listproc 6.0c
cause it to use "HELO hostname" (which Z-mail apparently requires
as well. :)
-OpenSSL
- OpenSSL versions prior to 0.9.6 use a macro named Free which
- conflicts with existing macro names on some platforms, such as
- AIX.
- Do not use 0.9.3, but OpenSSL 0.9.5a or later if compatible with
- 0.9.5a.
-
PH
PH support is provided by Mark Roth <roth@uiuc.edu>. The map is
described at http://www-dev.cites.uiuc.edu/sendmail/ .
diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS
index 06efaa91c75f..df5df6bded58 100644
--- a/contrib/sendmail/src/TRACEFLAGS
+++ b/contrib/sendmail/src/TRACEFLAGS
@@ -77,19 +77,23 @@
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 DANE
+67 domain.c TLSA RR lookups
+#endif
#if _FFR_QUEUE_SCHED_DBG
69 queue.c scheduling
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
70 queue.c quarantining
71,>99 milter.c quarantine on errors
73 queue.c shared memory updates
74,>99 map.c LDAP map defer
#if _FFR_XCNCT
75 debug FFR_XC*
-#endif /* _FFR_XCNCT */
+#endif
+#if _FFR_TESTS
+76,>99 queue.c run_work_group: sleep
+77,>99 daemon.c change delivery host/port
+#endif
80 content length
81 sun remote mode
83 collect.c timeout
@@ -100,6 +104,7 @@
#endif
89 conf.c >=8 use sm_dprintf() instead of syslog()
91 mci.c syslogging of MCI cache information
+92 EF_LOGSENDER
93,>99 * Prevent daemon connection fork for profiling/debugging
94,>99 srvrsmtp.c cause commands to fail (for protocol testing)
95 srvrsmtp.c AUTH
diff --git a/contrib/sendmail/src/alias.c b/contrib/sendmail/src/alias.c
index c31d8d09317e..70d8452eb08c 100644
--- a/contrib/sendmail/src/alias.c
+++ b/contrib/sendmail/src/alias.c
@@ -215,7 +215,7 @@ aliaslookup(name, pstat, av)
#if _FFR_ALIAS_DETAIL
int i;
char *argv[4];
-#endif /* _FFR_ALIAS_DETAIL */
+#endif
if (map == NULL)
{
@@ -273,7 +273,7 @@ setalias(spec)
{
char buf[50];
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
break;
@@ -507,7 +507,7 @@ rebuildaliases(map, automatic)
sigfunc_t oldsigint, oldsigquit;
#ifdef SIGTSTP
sigfunc_t oldsigtstp;
-#endif /* SIGTSTP */
+#endif
if (!bitset(MCF_REBUILDABLE, map->map_class->map_cflags))
return false;
@@ -569,7 +569,7 @@ rebuildaliases(map, automatic)
oldsigquit = sm_signal(SIGQUIT, SIG_IGN);
#ifdef SIGTSTP
oldsigtstp = sm_signal(SIGTSTP, SIG_IGN);
-#endif /* SIGTSTP */
+#endif
if (map->map_class->map_open(map, O_RDWR))
{
@@ -611,7 +611,7 @@ rebuildaliases(map, automatic)
(void) sm_signal(SIGQUIT, oldsigquit);
#ifdef SIGTSTP
(void) sm_signal(SIGTSTP, oldsigtstp);
-#endif /* SIGTSTP */
+#endif
return success;
}
/*
@@ -736,7 +736,7 @@ readaliases(map, af, announcestats, logstats)
** 'p' points to the text of the RHS.
*/
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
rhs = p;
for (;;)
@@ -754,8 +754,7 @@ readaliases(map, af, announcestats, logstats)
{
auto char *delimptr;
- while ((isascii(*p) && isspace(*p)) ||
- *p == ',')
+ while ((SM_ISSPACE(*p)) || *p == ',')
p++;
if (*p == '\0')
break;
@@ -821,7 +820,7 @@ readaliases(map, af, announcestats, logstats)
{
/* is RHS empty (just spaces)? */
p = rhs;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
}
if (rhssize == 0 || *p == '\0')
@@ -840,19 +839,6 @@ readaliases(map, af, announcestats, logstats)
if (rhssize > longest)
longest = rhssize;
}
-
-#if 0
- /*
- ** address strings are now stored in the envelope rpool,
- ** and therefore cannot be freed.
- */
- if (al.q_paddr != NULL)
- sm_free(al.q_paddr); /* disabled */
- if (al.q_host != NULL)
- sm_free(al.q_host); /* disabled */
- if (al.q_user != NULL)
- sm_free(al.q_user); /* disabled */
-#endif /* 0 */
}
CurEnv->e_to = NULL;
diff --git a/contrib/sendmail/src/arpadate.c b/contrib/sendmail/src/arpadate.c
index 57d5a06ff7db..0458363c6a4c 100644
--- a/contrib/sendmail/src/arpadate.c
+++ b/contrib/sendmail/src/arpadate.c
@@ -43,7 +43,7 @@ SM_RCSID("@(#)$Id: arpadate.c,v 8.32 2013-11-22 20:51:55 ca Exp $")
#ifndef TZNAME_MAX
# define TZNAME_MAX 50 /* max size of timezone */
-#endif /* ! TZNAME_MAX */
+#endif
/* values for TZ_TYPE */
#define TZ_NONE 0 /* no character timezone support */
@@ -149,10 +149,10 @@ arpadate(ud)
tz = NULL;
#if TZ_TYPE == TZ_TM_NAME
tz = lt->tm_name;
-#endif /* TZ_TYPE == TZ_TM_NAME */
+#endif
#if TZ_TYPE == TZ_TM_ZONE
tz = lt->tm_zone;
-#endif /* TZ_TYPE == TZ_TM_ZONE */
+#endif
#if TZ_TYPE == TZ_TZNAME
{
extern char *tzname[];
diff --git a/contrib/sendmail/src/bf.c b/contrib/sendmail/src/bf.c
index 0f2c9c0195eb..6fb10c9252bd 100644
--- a/contrib/sendmail/src/bf.c
+++ b/contrib/sendmail/src/bf.c
@@ -67,9 +67,9 @@ struct bf
#ifdef BF_STANDALONE
# define OPEN(fn, omode, cmode, sff) open(fn, omode, cmode)
-#else /* BF_STANDALONE */
+#else
# define OPEN(fn, omode, cmode, sff) safeopen(fn, omode, cmode, sff)
-#endif /* BF_STANDALONE */
+#endif
struct bf_info
{
@@ -566,7 +566,7 @@ sm_bfwrite(fp, buf, nbytes)
if (!(errno == ENOSPC
#ifdef EDQUOT
|| errno == EDQUOT
-#endif /* EDQUOT */
+#endif
))
errno = EIO;
@@ -804,9 +804,9 @@ sm_bftruncate(fp)
/* XXX: Not much we can do except rewind it */
errno = EINVAL;
return -1;
-#else /* NOFTRUNCATE */
+#else
return ftruncate(bfp->bf_disk_fd, 0);
-#endif /* NOFTRUNCATE */
+#endif
}
return 0;
}
diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c
index 5f090b23a042..526519050ca6 100644
--- a/contrib/sendmail/src/collect.c
+++ b/contrib/sendmail/src/collect.c
@@ -303,7 +303,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
char bufbuf[MAXLINE];
#if _FFR_REJECT_NUL_BYTE
bool hasNUL; /* has at least one NUL input byte */
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
df = NULL;
ignrdot = smtpmode ? false : IgnrDot;
@@ -321,7 +321,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
HasEightBits = false;
#if _FFR_REJECT_NUL_BYTE
hasNUL = false;
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
buf = bp = bufbuf;
buflen = sizeof(bufbuf);
pbp = peekbuf;
@@ -413,7 +413,7 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
#if _FFR_REJECT_NUL_BYTE
if (c == '\0')
hasNUL = true;
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
if (c == SM_IO_EOF)
goto readerr;
if (SevenBitInput)
@@ -435,11 +435,9 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
break;
case IS_DOT:
- if (c == '\n' && !ignrdot &&
- !bitset(EF_NL_NOT_EOL, e->e_flags))
+ if (c == '\n' && !ignrdot)
goto readerr;
- else if (c == '\r' &&
- !bitset(EF_CRLF_NOT_EOL, e->e_flags))
+ else if (c == '\r')
{
istate = IS_DOTCR;
continue;
@@ -494,13 +492,12 @@ collect(fp, smtpmode, hdrp, e, rsetsize)
goto bufferchar;
}
- if (c == '\r' && !bitset(EF_CRLF_NOT_EOL, e->e_flags))
+ if (c == '\r')
{
istate = IS_CR;
continue;
}
- else if (c == '\n' && !bitset(EF_NL_NOT_EOL,
- e->e_flags))
+ else if (c == '\n')
istate = IS_BOL;
else
istate = IS_NORM;
@@ -683,10 +680,8 @@ nextstate:
bp = buf;
/* toss blank line */
- if ((!bitset(EF_CRLF_NOT_EOL, e->e_flags) &&
- bp[0] == '\r' && bp[1] == '\n') ||
- (!bitset(EF_NL_NOT_EOL, e->e_flags) &&
- bp[0] == '\n'))
+ if ((bp[0] == '\r' && bp[1] == '\n') ||
+ (bp[0] == '\n'))
{
break;
}
@@ -981,9 +976,9 @@ dferror(df, msg, e)
{
#if STAT64 > 0
struct stat64 st;
-#else /* STAT64 > 0 */
+#else
struct stat st;
-#endif /* STAT64 > 0 */
+#endif
long avail;
long bsize;
@@ -992,9 +987,9 @@ dferror(df, msg, e)
if (
#if STAT64 > 0
fstat64(sm_io_getinfo(df, SM_IO_WHAT_FD, NULL), &st)
-#else /* STAT64 > 0 */
+#else
fstat(sm_io_getinfo(df, SM_IO_WHAT_FD, NULL), &st)
-#endif /* STAT64 > 0 */
+#endif
< 0)
st.st_size = 0;
(void) sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, dfname,
diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c
index 8c7c94b15cfd..63c545cb27e1 100644
--- a/contrib/sendmail/src/conf.c
+++ b/contrib/sendmail/src/conf.c
@@ -19,10 +19,11 @@ SM_RCSID("@(#)$Id: conf.c,v 8.1192 2014-01-27 18:23:21 ca Exp $")
#include <sendmail/pathnames.h>
#if NEWDB
# include "sm/bdb.h"
-#endif /* NEWDB */
+#endif
#include <daemon.h>
#include "map.h"
+#include <ratectrl.h>
#ifdef DEC
# if NETINET6
@@ -38,10 +39,13 @@ SM_RCSID("@(#)$Id: conf.c,v 8.1192 2014-01-27 18:23:21 ca Exp $")
#include <limits.h>
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
#if HASULIMIT && defined(HPUX11)
# include <ulimit.h>
-#endif /* HASULIMIT && defined(HPUX11) */
+#endif
+#if STARTTLS
+# include "tls.h"
+#endif
static void setupmaps __P((void));
static void setupmailers __P((void));
@@ -117,8 +121,10 @@ struct hdrinfo HdrInfo[] =
/* message identification and control */
{ "message-id", 0, NULL },
{ "resent-message-id", H_RESENT, NULL },
+#if !NO_EOH_FIELDS
{ "message", H_EOH, NULL },
{ "text", H_EOH, NULL },
+#endif
/* date fields */
{ "date", 0, NULL },
@@ -262,7 +268,7 @@ int DtableSize = 50; /* max open files; reset in 4.2bsd */
#ifndef MAXRULERECURSION
# define MAXRULERECURSION 50 /* max ruleset recursion depth */
-#endif /* ! MAXRULERECURSION */
+#endif
void
setdefaults(e)
@@ -314,13 +320,16 @@ setdefaults(e)
e->e_xfqgrp = NOQGRP;
e->e_xfqdir = NOQDIR;
e->e_ctime = curtime();
+#if _FFR_EAI
+ e->e_smtputf8 = false;
+#endif
SevenBitInput = false; /* option 7 */
MaxMciCache = 1; /* option k */
MciCacheTimeout = 5 MINUTES; /* option K */
LogLevel = 9; /* option L */
#if MILTER
MilterLogLevel = -1;
-#endif /* MILTER */
+#endif
inittimeouts(NULL, false); /* option r */
PrivacyFlags = PRIV_PUBLIC; /* option p */
MeToo = true; /* option m */
@@ -329,9 +338,9 @@ setdefaults(e)
clrbitmap(DontBlameSendmail); /* DontBlameSendmail option */
#if MIME8TO7
MimeMode = MM_CVTMIME|MM_PASS8BIT; /* option 8 */
-#else /* MIME8TO7 */
+#else
MimeMode = MM_PASS8BIT;
-#endif /* MIME8TO7 */
+#endif
for (i = 0; i < MAXTOCLASS; i++)
{
TimeOuts.to_q_return[i] = 5 DAYS; /* option T */
@@ -360,11 +369,14 @@ setdefaults(e)
AuthMechanisms = newstr(AUTH_MECHANISMS);
AuthRealm = NULL;
MaxSLBits = INT_MAX;
-#endif /* SASL */
+#endif
#if STARTTLS
TLS_Srv_Opts = TLS_I_SRV;
if (NULL == EVP_digest)
EVP_digest = EVP_md5();
+# if _FFR_TLSFB2CLEAR
+ TLSFallbacktoClear = true;
+# endif
Srv_SSL_Options = SSL_OP_ALL;
Clt_SSL_Options = SSL_OP_ALL
# ifdef SSL_OP_NO_SSLv2
@@ -382,7 +394,7 @@ setdefaults(e)
#endif /* STARTTLS */
#ifdef HESIOD_INIT
HesiodContext = NULL;
-#endif /* HESIOD_INIT */
+#endif
#if NETINET6
/* Detect if IPv6 is available at run time */
i = socket(AF_INET6, SOCK_STREAM, 0);
@@ -407,25 +419,24 @@ setdefaults(e)
RuleSetNames[i] = NULL;
#if MILTER
InputFilters[0] = NULL;
-#endif /* MILTER */
+#endif
RejectLogInterval = 3 HOURS;
#if REQUIRES_DIR_FSYNC
RequiresDirfsync = true;
-#endif /* REQUIRES_DIR_FSYNC */
+#endif
#if _FFR_RCPTTHROTDELAY
BadRcptThrottleDelay = 1;
-#endif /* _FFR_RCPTTHROTDELAY */
+#endif
ConnectionRateWindowSize = 60;
#if _FFR_BOUNCE_QUEUE
BounceQueue = NOQGRP;
-#endif /* _FFR_BOUNCE_QUEUE */
+#endif
setupmaps();
setupqueues();
setupmailers();
setupheaders();
}
-
/*
** SETDEFUSER -- set/reset DefUser using DefUid (for initgroups())
*/
@@ -539,50 +550,56 @@ setupmaps()
MAPDEF("dbm", ".dir", MCF_ALIASOK|MCF_REBUILDABLE,
map_parseargs, ndbm_map_open, ndbm_map_close,
ndbm_map_lookup, ndbm_map_store);
-#endif /* NDBM */
+#endif
+
+#if CDB
+ MAPDEF("cdb", CDBEXT, MCF_ALIASOK|MCF_REBUILDABLE,
+ map_parseargs, cdb_map_open, cdb_map_close,
+ cdb_map_lookup, cdb_map_store);
+#endif
#if NIS
MAPDEF("nis", NULL, MCF_ALIASOK,
map_parseargs, nis_map_open, null_map_close,
nis_map_lookup, null_map_store);
-#endif /* NIS */
+#endif
#if NISPLUS
MAPDEF("nisplus", NULL, MCF_ALIASOK,
map_parseargs, nisplus_map_open, null_map_close,
nisplus_map_lookup, null_map_store);
-#endif /* NISPLUS */
+#endif
#if LDAPMAP
MAPDEF("ldap", NULL, MCF_ALIASOK|MCF_NOTPERSIST,
ldapmap_parseargs, ldapmap_open, ldapmap_close,
ldapmap_lookup, null_map_store);
-#endif /* LDAPMAP */
+#endif
#if PH_MAP
MAPDEF("ph", NULL, MCF_NOTPERSIST,
ph_map_parseargs, ph_map_open, ph_map_close,
ph_map_lookup, null_map_store);
-#endif /* PH_MAP */
+#endif
#if MAP_NSD
/* IRIX 6.5 nsd support */
MAPDEF("nsd", NULL, MCF_ALIASOK,
map_parseargs, null_map_open, null_map_close,
nsd_map_lookup, null_map_store);
-#endif /* MAP_NSD */
+#endif
#if HESIOD
- MAPDEF("hesiod", NULL, MCF_ALIASOK|MCF_ALIASONLY,
+ MAPDEF("hesiod", NULL, MCF_ALIASOK,
map_parseargs, hes_map_open, hes_map_close,
hes_map_lookup, null_map_store);
-#endif /* HESIOD */
+#endif
#if NETINFO
MAPDEF("netinfo", NULL, MCF_ALIASOK,
map_parseargs, ni_map_open, null_map_close,
ni_map_lookup, null_map_store);
-#endif /* NETINFO */
+#endif
#if 0
MAPDEF("dns", NULL, 0,
@@ -609,7 +626,7 @@ setupmaps()
MAPDEF("bestmx", NULL, MCF_OPTFILE,
map_parseargs, null_map_open, null_map_close,
bestmx_map_lookup, null_map_store);
-#endif /* NAMED_BIND */
+#endif
MAPDEF("host", NULL, 0,
host_map_init, null_map_open, null_map_close,
@@ -619,11 +636,11 @@ setupmaps()
map_parseargs, text_map_open, null_map_close,
text_map_lookup, null_map_store);
- MAPDEF("stab", NULL, MCF_ALIASOK|MCF_ALIASONLY,
+ MAPDEF("stab", NULL, MCF_ALIASOK,
map_parseargs, stab_map_open, null_map_close,
stab_map_lookup, stab_map_store);
- MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_ALIASONLY|MCF_REBUILDABLE,
+ MAPDEF("implicit", NULL, MCF_ALIASOK|MCF_REBUILDABLE,
map_parseargs, impl_map_open, impl_map_close,
impl_map_lookup, impl_map_store);
@@ -641,14 +658,14 @@ setupmaps()
MAPDEF("regex", NULL, 0,
regex_map_init, null_map_open, null_map_close,
regex_map_lookup, null_map_store);
-#endif /* MAP_REGEX */
+#endif
#if USERDB
/* user database */
MAPDEF("userdb", ".db", 0,
map_parseargs, null_map_open, null_map_close,
udb_map_lookup, null_map_store);
-#endif /* USERDB */
+#endif
/* arbitrary programs */
MAPDEF("program", NULL, MCF_ALIASOK,
@@ -695,14 +712,28 @@ setupmaps()
MAPDEF("socket", NULL, MCF_ALIASOK,
map_parseargs, socket_map_open, socket_map_close,
socket_map_lookup, null_map_store);
-#endif /* SOCKETMAP */
+#endif
#if _FFR_DPRINTF_MAP
/* dprintf map -- logs information to syslog */
MAPDEF("dprintf", NULL, 0,
dprintf_map_parseargs, null_map_open, null_map_close,
dprintf_map_lookup, null_map_store);
-#endif /* _FFR_DPRINTF_MAP */
+#endif
+
+#if _FFR_SETDEBUG_MAP
+ /* setdebug map -- set debug levels */
+ MAPDEF("setdebug", NULL, 0,
+ dequote_init, null_map_open, null_map_close,
+ setdebug_map_lookup, null_map_store);
+#endif
+
+#if _FFR_SETOPT_MAP
+ /* setopt map -- set option */
+ MAPDEF("setopt", NULL, 0,
+ dequote_init, null_map_open, null_map_close,
+ setopt_map_lookup, null_map_store);
+#endif
if (tTd(38, 2))
{
@@ -754,7 +785,7 @@ inithostmaps()
#if NAMED_BIND
if (ConfigLevel >= 2)
(void) sm_strlcat(buf, " -a. -D", sizeof(buf));
-#endif /* NAMED_BIND */
+#endif
(void) makemapentry(buf);
}
@@ -772,6 +803,14 @@ inithostmaps()
sizeof(buf));
(void) makemapentry(buf);
}
+#if CDB
+ else if (strcmp(maptype[i], "cdb") == 0 &&
+ stab("aliases.cdb", ST_MAP, ST_FIND) == NULL)
+ {
+ (void) sm_strlcpy(buf, "aliases.cdb null", sizeof(buf));
+ (void) makemapentry(buf);
+ }
+#endif /* CDB */
#if NISPLUS
else if (strcmp(maptype[i], "nisplus") == 0 &&
stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL)
@@ -848,25 +887,25 @@ inithostmaps()
#if defined(SOLARIS) || (defined(sony_news) && defined(__svr4))
# define _USE_SUN_NSSWITCH_
-#endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */
+#endif
#if _FFR_HPUX_NSSWITCH
# ifdef __hpux
# define _USE_SUN_NSSWITCH_
-# endif /* __hpux */
+# endif
#endif /* _FFR_HPUX_NSSWITCH */
#ifdef _USE_SUN_NSSWITCH_
# include <nsswitch.h>
-#endif /* _USE_SUN_NSSWITCH_ */
+#endif
#if defined(ultrix) || (defined(__osf__) && defined(__alpha))
# define _USE_DEC_SVC_CONF_
-#endif /* defined(ultrix) || (defined(__osf__) && defined(__alpha)) */
+#endif
#ifdef _USE_DEC_SVC_CONF_
# include <sys/svcinfo.h>
-#endif /* _USE_DEC_SVC_CONF_ */
+#endif
int
switch_map_find(service, maptype, mapreturn)
@@ -951,7 +990,7 @@ switch_map_find(service, maptype, mapreturn)
case SVC_HESIOD:
maptype[svcno] = "hesiod";
break;
-# endif /* SVC_HESIOD */
+# endif
case SVC_LAST:
errno = save_errno;
@@ -1001,7 +1040,7 @@ switch_map_find(service, maptype, mapreturn)
*p = '\0';
#ifndef SM_NSSWITCH_DELIMS
# define SM_NSSWITCH_DELIMS " \t"
-#endif /* SM_NSSWITCH_DELIMS */
+#endif
p = strpbrk(buf, SM_NSSWITCH_DELIMS);
if (p != NULL)
*p++ = '\0';
@@ -1015,7 +1054,7 @@ switch_map_find(service, maptype, mapreturn)
buf);
continue;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
continue;
@@ -1041,7 +1080,7 @@ switch_map_find(service, maptype, mapreturn)
if (p == NULL)
break;
*p++ = '\0';
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
}
if (svcno < MAXMAPSTACK)
@@ -1072,23 +1111,31 @@ switch_map_find(service, maptype, mapreturn)
/* if the service file doesn't work, use an absolute fallback */
# ifdef _USE_DEC_SVC_CONF_
punt:
-# endif /* _USE_DEC_SVC_CONF_ */
+# endif
for (svcno = 0; svcno < MAXMAPACTIONS; svcno++)
mapreturn[svcno] = 0;
svcno = 0;
if (strcmp(service, "aliases") == 0)
{
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "files";
+# if CDB
+ SM_ASSERT(svcno < MAXMAPSTACK);
+ maptype[svcno++] = "cdb";
+# endif
# if defined(AUTO_NETINFO_ALIASES) && defined (NETINFO)
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "netinfo";
-# endif /* defined(AUTO_NETINFO_ALIASES) && defined (NETINFO) */
+# endif
# ifdef AUTO_NIS_ALIASES
# if NISPLUS
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "nisplus";
-# endif /* NISPLUS */
+# endif
# if NIS
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "nis";
-# endif /* NIS */
+# endif
# endif /* AUTO_NIS_ALIASES */
errno = save_errno;
return svcno;
@@ -1096,16 +1143,20 @@ switch_map_find(service, maptype, mapreturn)
if (strcmp(service, "hosts") == 0)
{
# if NAMED_BIND
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "dns";
# else /* NAMED_BIND */
# if defined(sun) && !defined(BSD)
/* SunOS */
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "nis";
# endif /* defined(sun) && !defined(BSD) */
# endif /* NAMED_BIND */
# if defined(AUTO_NETINFO_HOSTS) && defined (NETINFO)
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "netinfo";
-# endif /* defined(AUTO_NETINFO_HOSTS) && defined (NETINFO) */
+# endif
+ SM_ASSERT(svcno < MAXMAPSTACK);
maptype[svcno++] = "files";
errno = save_errno;
return svcno;
@@ -1306,11 +1357,11 @@ init_md_sun()
#ifdef _AUX_SOURCE
# include <compat.h>
-#endif /* _AUX_SOURCE */
+#endif
#if SHARE_V1
# include <shares.h>
-#endif /* SHARE_V1 */
+#endif
void
init_md(argc, argv)
@@ -1319,16 +1370,16 @@ init_md(argc, argv)
{
#ifdef _AUX_SOURCE
setcompat(getcompat() | COMPAT_BSDPROT);
-#endif /* _AUX_SOURCE */
+#endif
#ifdef SUN_EXTENSIONS
init_md_sun();
-#endif /* SUN_EXTENSIONS */
+#endif
#if _CONVEX_SOURCE
/* keep gethostby*() from stripping the local domain name */
set_domain_trim_off();
-#endif /* _CONVEX_SOURCE */
+#endif
#if defined(__QNX__) && !defined(__QNXNTO__)
/*
** Due to QNX's network distributed nature, you can target a tcpip
@@ -1356,9 +1407,9 @@ init_md(argc, argv)
#ifdef VENDOR_DEFAULT
VendorCode = VENDOR_DEFAULT;
-#else /* VENDOR_DEFAULT */
+#else
VendorCode = VENDOR_BERKELEY;
-#endif /* VENDOR_DEFAULT */
+#endif
}
/*
** INIT_VENDOR_MACROS -- vendor-dependent macro initializations
@@ -1416,39 +1467,39 @@ init_vendor_macros(e)
/* do guesses based on general OS type */
#ifndef LA_TYPE
# define LA_TYPE LA_ZERO
-#endif /* ! LA_TYPE */
+#endif
#ifndef FSHIFT
# if defined(unixpc)
# define FSHIFT 5
-# endif /* defined(unixpc) */
+# endif
# if defined(__alpha) || defined(IRIX)
# define FSHIFT 10
-# endif /* defined(__alpha) || defined(IRIX) */
+# endif
#endif /* ! FSHIFT */
#ifndef FSHIFT
# define FSHIFT 8
-#endif /* ! FSHIFT */
+#endif
#ifndef FSCALE
# define FSCALE (1 << FSHIFT)
-#endif /* ! FSCALE */
+#endif
#ifndef LA_AVENRUN
# ifdef SYSTEM5
# define LA_AVENRUN "avenrun"
-# else /* SYSTEM5 */
+# else
# define LA_AVENRUN "_avenrun"
-# endif /* SYSTEM5 */
+# endif
#endif /* ! LA_AVENRUN */
/* _PATH_KMEM should be defined in <paths.h> */
#ifndef _PATH_KMEM
# define _PATH_KMEM "/dev/kmem"
-#endif /* ! _PATH_KMEM */
+#endif
#if (LA_TYPE == LA_INT) || (LA_TYPE == LA_FLOAT) || (LA_TYPE == LA_SHORT) || (LA_TYPE == LA_LONGLONG)
@@ -1458,9 +1509,9 @@ init_vendor_macros(e)
# ifndef _PATH_UNIX
# if defined(SYSTEM5)
# define _PATH_UNIX "/unix"
-# else /* defined(SYSTEM5) */
+# else
# define _PATH_UNIX "/vmunix"
-# endif /* defined(SYSTEM5) */
+# endif
# endif /* ! _PATH_UNIX */
# ifdef _AUX_SOURCE
@@ -1487,9 +1538,9 @@ getla()
# else
# if LA_TYPE == LA_LONGLONG
long long avenrun[3];
-# else /* LA_TYPE == LA_LONGLONG */
+# else
double avenrun[3];
-# endif /* LA_TYPE == LA_LONGLONG */
+# endif
# endif /* LA_TYPE == LA_SHORT */
# endif /* LA_TYPE == LA_INT */
extern off_t lseek();
@@ -1504,9 +1555,9 @@ getla()
# if defined(_AIX3) || defined(_AIX4)
if (knlist(Nl, 1, sizeof(Nl[0])) < 0)
-# else /* defined(_AIX3) || defined(_AIX4) */
+# else
if (nlist(_PATH_UNIX, Nl) < 0)
-# endif /* defined(_AIX3) || defined(_AIX4) */
+# endif
{
if (tTd(3, 1))
sm_dprintf("getla: nlist(%s): %s\n", _PATH_UNIX,
@@ -1522,7 +1573,7 @@ getla()
}
# ifdef NAMELISTMASK
Nl[X_AVENRUN].n_value &= NAMELISTMASK;
-# endif /* NAMELISTMASK */
+# endif
kmem = open(_PATH_KMEM, 0, 0);
if (kmem < 0)
@@ -1734,9 +1785,9 @@ getla()
# if defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0
# include <mach/mach.h>
-# else /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
+# else
# include <mach.h>
-# endif /* defined(NX_CURRENT_COMPILER_RELEASE) && NX_CURRENT_COMPILER_RELEASE > NX_COMPILER_RELEASE_3_0 */
+# endif
int
getla()
@@ -1792,7 +1843,7 @@ getla()
# ifndef _PATH_LOADAVG
# define _PATH_LOADAVG "/proc/loadavg"
-# endif /* ! _PATH_LOADAVG */
+# endif
int
getla()
@@ -1834,9 +1885,9 @@ getla()
# ifdef _UNICOSMP
# define CAST_SYSMP(x) (x)
-# else /* _UNICOSMP */
+# else
# define CAST_SYSMP(x) ((x) & 0x7fffffff)
-# endif /* _UNICOSMP */
+# endif
int
getla(void)
@@ -1950,7 +2001,7 @@ getla()
# ifndef _PATH_AVENRUN
# define _PATH_AVENRUN "/dev/table/avenrun"
-# endif /* ! _PATH_AVENRUN */
+# endif
int
getla()
@@ -2090,7 +2141,7 @@ getla()
/* Non Apollo stuff removed by Don Lewis 11/15/93 */
#ifndef lint
SM_UNUSED(static char rcsid[]) = "@(#)$OrigId: getloadavg.c,v 1.16 1991/06/21 12:51:15 paul Exp $";
-#endif /* ! lint */
+#endif
#ifdef apollo
# undef volatile
@@ -2163,7 +2214,7 @@ shouldqueue(pri, ct)
bool rval;
#if _FFR_MEMSTAT
long memfree;
-#endif /* _FFR_MEMSTAT */
+#endif
if (tTd(3, 30))
sm_dprintf("shouldqueue: CurrentLA=%d, pri=%ld: ",
@@ -2222,12 +2273,12 @@ refuseconnections(e, dn, active)
int limit;
#if _FFR_MEMSTAT
long memfree;
-#endif /* _FFR_MEMSTAT */
+#endif
#if XLA
if (!xla_smtp_ok())
return true;
-#endif /* XLA */
+#endif
SM_ASSERT(dn >= 0);
SM_ASSERT(dn < MAXDAEMONS);
@@ -2374,14 +2425,14 @@ refuseconnections(e, dn, active)
#ifndef SPT_TYPE
# define SPT_TYPE SPT_REUSEARGV
-#endif /* ! SPT_TYPE */
+#endif
#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
# if SPT_TYPE == SPT_PSTAT
# include <sys/pstat.h>
-# endif /* SPT_TYPE == SPT_PSTAT */
+# endif
# if SPT_TYPE == SPT_PSSTRINGS
# include <machine/vmparam.h>
# include <sys/exec.h>
@@ -2398,14 +2449,14 @@ typedef unsigned int *pt_entry_t;
# if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
# define SETPROC_STATIC static
-# else /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
+# else
# define SETPROC_STATIC
-# endif /* SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV */
+# endif
# if SPT_TYPE == SPT_SYSMIPS
# include <sys/sysmips.h>
# include <sys/sysnews.h>
-# endif /* SPT_TYPE == SPT_SYSMIPS */
+# endif
# if SPT_TYPE == SPT_SCO
# include <sys/immu.h>
@@ -2414,18 +2465,18 @@ typedef unsigned int *pt_entry_t;
# include <sys/fs/s5param.h>
# if PSARGSZ > MAXLINE
# define SPT_BUFSIZE PSARGSZ
-# endif /* PSARGSZ > MAXLINE */
+# endif
# endif /* SPT_TYPE == SPT_SCO */
# ifndef SPT_PADCHAR
# define SPT_PADCHAR ' '
-# endif /* ! SPT_PADCHAR */
+# endif
#endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
#ifndef SPT_BUFSIZE
# define SPT_BUFSIZE MAXLINE
-#endif /* ! SPT_BUFSIZE */
+#endif
#if _FFR_SPT_ALIGN
@@ -2439,9 +2490,9 @@ typedef unsigned int *pt_entry_t;
# ifdef SPT_ALIGN_SIZE
# define SPT_ALIGN(x, align) (((((x) + SPT_ALIGN_SIZE) >> (align)) << (align)) - 1)
-# else /* SPT_ALIGN_SIZE */
+# else
# define SPT_ALIGN(x, align) (x)
-# endif /* SPT_ALIGN_SIZE */
+# endif
#else /* _FFR_SPT_ALIGN */
# define SPT_ALIGN(x, align) (x)
#endif /* _FFR_SPT_ALIGN */
@@ -2455,7 +2506,7 @@ static char **Argv = NULL; /* pointer to argument vector */
static char *LastArgv = NULL; /* end of argv */
#if SPT_TYPE != SPT_BUILTIN
static void setproctitle __P((const char *, ...));
-#endif /* SPT_TYPE != SPT_BUILTIN */
+#endif
void
initsetproctitle(argc, argv, envp)
@@ -2464,7 +2515,9 @@ initsetproctitle(argc, argv, envp)
char **envp;
{
register int i;
+#if _FFR_SPT_ALIGN
int align;
+#endif
extern char **environ;
/*
@@ -2493,12 +2546,12 @@ initsetproctitle(argc, argv, envp)
** Use all contiguous argv and envp pointers starting at argv[0]
*/
- align = -1;
# if _FFR_SPT_ALIGN
+ align = -1;
# ifdef SPT_ALIGN_SIZE
for (i = SPT_ALIGN_SIZE; i > 0; i >>= 1)
align++;
-# endif /* SPT_ALIGN_SIZE */
+# endif
# endif /* _FFR_SPT_ALIGN */
for (i = 0; i < argc; i++)
@@ -2532,7 +2585,7 @@ setproctitle(fmt, va_alist)
SM_VA_LOCAL_DECL
# if SPT_TYPE == SPT_PSTAT
union pstun pst;
-# endif /* SPT_TYPE == SPT_PSTAT */
+# endif
# if SPT_TYPE == SPT_SCO
int j;
off_t seek_off;
@@ -2559,14 +2612,14 @@ setproctitle(fmt, va_alist)
# if SPT_TYPE == SPT_PSTAT
pst.pst_command = buf;
pstat(PSTAT_SETCMD, pst, i, 0, 0);
-# endif /* SPT_TYPE == SPT_PSTAT */
+# endif
# if SPT_TYPE == SPT_PSSTRINGS
PS_STRINGS->ps_nargvstr = 1;
PS_STRINGS->ps_argvstr = buf;
-# endif /* SPT_TYPE == SPT_PSSTRINGS */
+# endif
# if SPT_TYPE == SPT_SYSMIPS
sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
-# endif /* SPT_TYPE == SPT_SYSMIPS */
+# endif
# if SPT_TYPE == SPT_SCO
if (kmem < 0 || kmempid != CurrentPid)
{
@@ -2606,12 +2659,12 @@ setproctitle(fmt, va_alist)
# endif /* SPT_TYPE == SPT_REUSEARGV */
# if SPT_TYPE == SPT_CHANGEARGV
Argv[0] = buf;
- Argv[1] = 0;
-# endif /* SPT_TYPE == SPT_CHANGEARGV */
+ Argv[1] = NULL;
+# endif
# endif /* SPT_TYPE != SPT_NONE */
}
-
#endif /* SPT_TYPE != SPT_BUILTIN */
+
/*
** SM_SETPROCTITLE -- set process task and set process title for ps
**
@@ -2709,27 +2762,27 @@ sm_wait(status)
{
# ifdef WAITUNION
union wait st;
-# else /* WAITUNION */
+# else
auto int st;
-# endif /* WAITUNION */
+# endif
pid_t i;
# if defined(ISC_UNIX) || defined(_SCO_unix_)
int savesig;
-# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
+# endif
# if defined(ISC_UNIX) || defined(_SCO_unix_)
savesig = sm_releasesignal(SIGCHLD);
-# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
+# endif
i = wait(&st);
# if defined(ISC_UNIX) || defined(_SCO_unix_)
if (savesig > 0)
sm_blocksignal(SIGCHLD);
-# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */
+# endif
# ifdef WAITUNION
*status = st.w_status;
-# else /* WAITUNION */
+# else
*status = st;
-# endif /* WAITUNION */
+# endif
return i;
}
/*
@@ -2814,7 +2867,7 @@ reapchild(sig)
#ifdef SOLARIS
# include <sys/resource.h>
-#endif /* SOLARIS */
+#endif
int
getdtsize()
@@ -2831,9 +2884,9 @@ getdtsize()
# else /* HASGETDTABLESIZE */
# ifdef _SC_OPEN_MAX
return sysconf(_SC_OPEN_MAX);
-# else /* _SC_OPEN_MAX */
+# else
return NOFILE;
-# endif /* _SC_OPEN_MAX */
+# endif
# endif /* HASGETDTABLESIZE */
}
/*
@@ -2894,15 +2947,14 @@ uname(name)
*/
#if !HASINITGROUPS
-
initgroups(name, basegid)
char *name;
int basegid;
{
return 0;
}
-
#endif /* !HASINITGROUPS */
+
/*
** SETGROUPS -- set group list
**
@@ -2910,7 +2962,6 @@ initgroups(name, basegid)
*/
#ifndef NGROUPS_MAX
-
int
setgroups(ngroups, grouplist)
int ngroups;
@@ -2918,8 +2969,8 @@ setgroups(ngroups, grouplist)
{
return 0;
}
-
#endif /* ! NGROUPS_MAX */
+
/*
** SETSID -- set session id (for non-POSIX systems)
*/
@@ -2941,9 +2992,9 @@ setsid __P ((void))
# endif /* TIOCNOTTY */
# ifdef SYS5SETPGRP
return setpgrp();
-# else /* SYS5SETPGRP */
+# else
return setpgid(0, CurrentPid);
-# endif /* SYS5SETPGRP */
+# endif
}
#endif /* !HASSETSID */
@@ -2958,13 +3009,13 @@ fsync(fd)
{
# ifdef O_SYNC
return fcntl(fd, F_SETFL, O_SYNC);
-# else /* O_SYNC */
+# else
/* nothing we can do */
return 0;
-# endif /* O_SYNC */
+# endif
}
-
#endif /* NEEDFSYNC */
+
/*
** DGUX_INET_ADDR -- inet_addr for DG/UX
**
@@ -3008,7 +3059,7 @@ dgux_inet_addr(host)
# if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getopt.c 4.3 (Berkeley) 3/9/86";
-# endif /* defined(LIBC_SCCS) && !defined(lint) */
+# endif
/*
** get option letter from argument vector
@@ -3095,13 +3146,13 @@ getopt(nargc,nargv,ostr)
# ifndef _PATH_SHELLS
# define _PATH_SHELLS "/etc/shells"
-# endif /* ! _PATH_SHELLS */
+# endif
# if defined(_AIX3) || defined(_AIX4)
# include <userconf.h>
# if _AIX4 >= 40200
# include <userpw.h>
-# endif /* _AIX4 >= 40200 */
+# endif
# include <usersec.h>
# endif /* defined(_AIX3) || defined(_AIX4) */
@@ -3193,7 +3244,7 @@ usershellok(user, shell)
# else /* HASGETUSERSHELL */
# if USEGETCONFATTR
auto char *v;
-# endif /* USEGETCONFATTR */
+# endif
register SM_FILE_T *shellf;
char buf[MAXLINE];
@@ -3257,7 +3308,7 @@ usershellok(user, shell)
if (*p == '#' || *p == '\0')
continue;
q = p;
- while (*p != '\0' && *p != '#' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && *p != '#' && !(SM_ISSPACE(*p)))
p++;
*p = '\0';
if (strcmp(shell, q) == 0 || strcmp(WILDCARD_SHELL, q) == 0)
@@ -3299,23 +3350,23 @@ usershellok(user, shell)
# ifndef SFS_TYPE
# define SFS_TYPE SFS_NONE
-# endif /* ! SFS_TYPE */
+# endif
# if SFS_TYPE == SFS_USTAT
# include <ustat.h>
-# endif /* SFS_TYPE == SFS_USTAT */
+# endif
# if SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS
# include <sys/statfs.h>
-# endif /* SFS_TYPE == SFS_4ARGS || SFS_TYPE == SFS_STATFS */
+# endif
# if SFS_TYPE == SFS_VFS
# include <sys/vfs.h>
-# endif /* SFS_TYPE == SFS_VFS */
+# endif
# if SFS_TYPE == SFS_MOUNT
# include <sys/mount.h>
-# endif /* SFS_TYPE == SFS_MOUNT */
+# endif
# if SFS_TYPE == SFS_STATVFS
# include <sys/statvfs.h>
-# endif /* SFS_TYPE == SFS_STATVFS */
+# endif
long
freediskspace(dir, bsize)
@@ -3351,7 +3402,7 @@ freediskspace(dir, bsize)
# endif /* SFS_TYPE == SFS_USTAT */
# ifndef SFS_BAVAIL
# define SFS_BAVAIL f_bavail
-# endif /* ! SFS_BAVAIL */
+# endif
# if SFS_TYPE == SFS_USTAT
if (stat(dir, &statbuf) == 0 && ustat(statbuf.st_dev, &fs) == 0)
@@ -3412,7 +3463,7 @@ enoughdiskspace(msize, e)
#if _FFR_TESTS
if (tTd(4, 101))
return false;
-#endif /* _FFR_TESTS */
+#endif
if (MinBlocksFree <= 0 && msize <= 0)
{
if (tTd(4, 80))
@@ -3459,73 +3510,73 @@ transienterror(err)
case ETIMEDOUT: /* Connection timed out */
#ifdef ESTALE
case ESTALE: /* Stale NFS file handle */
-#endif /* ESTALE */
+#endif
#ifdef ENETDOWN
case ENETDOWN: /* Network is down */
-#endif /* ENETDOWN */
+#endif
#ifdef ENETUNREACH
case ENETUNREACH: /* Network is unreachable */
-#endif /* ENETUNREACH */
+#endif
#ifdef ENETRESET
case ENETRESET: /* Network dropped connection on reset */
-#endif /* ENETRESET */
+#endif
#ifdef ECONNABORTED
case ECONNABORTED: /* Software caused connection abort */
-#endif /* ECONNABORTED */
+#endif
#ifdef ECONNRESET
case ECONNRESET: /* Connection reset by peer */
-#endif /* ECONNRESET */
+#endif
#ifdef ENOBUFS
case ENOBUFS: /* No buffer space available */
-#endif /* ENOBUFS */
+#endif
#ifdef ESHUTDOWN
case ESHUTDOWN: /* Can't send after socket shutdown */
-#endif /* ESHUTDOWN */
+#endif
#ifdef ECONNREFUSED
case ECONNREFUSED: /* Connection refused */
-#endif /* ECONNREFUSED */
+#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: /* Host is down */
-#endif /* EHOSTDOWN */
+#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: /* No route to host */
-#endif /* EHOSTUNREACH */
+#endif
#ifdef EDQUOT
case EDQUOT: /* Disc quota exceeded */
-#endif /* EDQUOT */
+#endif
#ifdef EPROCLIM
case EPROCLIM: /* Too many processes */
-#endif /* EPROCLIM */
+#endif
#ifdef EUSERS
case EUSERS: /* Too many users */
-#endif /* EUSERS */
+#endif
#ifdef EDEADLK
case EDEADLK: /* Resource deadlock avoided */
-#endif /* EDEADLK */
+#endif
#ifdef EISCONN
case EISCONN: /* Socket already connected */
-#endif /* EISCONN */
+#endif
#ifdef EINPROGRESS
case EINPROGRESS: /* Operation now in progress */
-#endif /* EINPROGRESS */
+#endif
#ifdef EALREADY
case EALREADY: /* Operation already in progress */
-#endif /* EALREADY */
+#endif
#ifdef EADDRINUSE
case EADDRINUSE: /* Address already in use */
-#endif /* EADDRINUSE */
+#endif
#ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL: /* Can't assign requested address */
-#endif /* EADDRNOTAVAIL */
+#endif
#ifdef ETXTBSY
case ETXTBSY: /* (Apollo) file locked */
-#endif /* ETXTBSY */
+#endif
#if defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR))
case ENOSR: /* Out of streams resources */
-#endif /* defined(ENOSR) && (!defined(ENOBUFS) || (ENOBUFS != ENOSR)) */
+#endif
#ifdef ENOLCK
case ENOLCK: /* No locks available */
-#endif /* ENOLCK */
+#endif
case E_SM_OPENTIMEOUT: /* PSEUDO: open timed out */
return true;
}
@@ -3714,7 +3765,7 @@ lockfile(fd, filename, ext, type)
#ifndef IS_SAFE_CHOWN
# define IS_SAFE_CHOWN > 0
-#endif /* ! IS_SAFE_CHOWN */
+#endif
bool
chownsafe(fd, safedir)
@@ -3739,9 +3790,9 @@ chownsafe(fd, safedir)
rval = fpathconf(fd, _PC_CHOWN_RESTRICTED);
# if SAFENFSPATHCONF
return errno == 0 && rval IS_SAFE_CHOWN;
-# else /* SAFENFSPATHCONF */
+# else
return safedir && errno == 0 && rval IS_SAFE_CHOWN;
-# endif /* SAFENFSPATHCONF */
+# endif
# else /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
return bitnset(DBS_ASSUMESAFECHOWN, DontBlameSendmail);
# endif /* (!defined(_POSIX_CHOWN_RESTRICTED) || _POSIX_CHOWN_RESTRICTED != -1) && ... */
@@ -3761,7 +3812,7 @@ chownsafe(fd, safedir)
#if HASSETRLIMIT
# ifdef RLIMIT_NEEDS_SYS_TIME_H
# include <sm/time.h>
-# endif /* RLIMIT_NEEDS_SYS_TIME_H */
+# endif
# include <sys/resource.h>
#endif /* HASSETRLIMIT */
@@ -3777,12 +3828,12 @@ resetlimits()
# ifdef RLIMIT_NOFILE
lim.rlim_cur = lim.rlim_max = FD_SETSIZE;
(void) setrlimit(RLIMIT_NOFILE, &lim);
-# endif /* RLIMIT_NOFILE */
+# endif
#else /* HASSETRLIMIT */
# if HASULIMIT
(void) ulimit(2, 0x3fffff);
(void) ulimit(4, FD_SETSIZE);
-# endif /* HASULIMIT */
+# endif
#endif /* HASSETRLIMIT */
errno = 0;
}
@@ -3901,7 +3952,7 @@ getvendor(vendorcode)
#if SHARE_V1
int DefShareUid; /* default share uid to run as -- unused??? */
-#endif /* SHARE_V1 */
+#endif
void
vendor_pre_defaults(e)
@@ -3910,10 +3961,10 @@ vendor_pre_defaults(e)
#if SHARE_V1
/* OTHERUID is defined in shares.h, do not be alarmed */
DefShareUid = OTHERUID;
-#endif /* SHARE_V1 */
+#endif
#if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
sun_pre_defaults(e);
-#endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
+#endif
#ifdef apollo
/*
** stupid domain/os can't even open
@@ -3933,10 +3984,10 @@ vendor_post_defaults(e)
#ifdef __QNX__
/* Makes sure the SOCK environment variable remains */
sm_setuserenv("SOCK", NULL);
-#endif /* __QNX__ */
+#endif
#if defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES)
sun_post_defaults(e);
-#endif /* defined(SUN_EXTENSIONS) && defined(SUN_DEFAULT_VALUES) */
+#endif
}
/*
** VENDOR_DAEMON_SETUP -- special vendor setup needed for daemon mode
@@ -3948,7 +3999,7 @@ vendor_daemon_setup(e)
{
#if HASSETLOGIN
(void) setlogin(RunAsUserName);
-#endif /* HASSETLOGIN */
+#endif
#if SECUREWARE
if (getluid() != -1)
{
@@ -3981,10 +4032,10 @@ vendor_set_uid(uid)
#if SHARE_V1
if (setupshares(uid, syserr) != 0)
syserr("Unable to set up shares");
-#endif /* SHARE_V1 */
+#endif
#if SECUREWARE
(void) setup_secure(uid);
-#endif /* SECUREWARE */
+#endif
}
/*
** VALIDATE_CONNECTION -- check connection for rationality
@@ -4085,7 +4136,7 @@ validate_connection(sap, hostname, e)
# if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
-# endif /* defined(LIBC_SCCS) && !defined(lint) */
+# endif
/*
** Convert a string to a long integer.
@@ -4113,7 +4164,7 @@ strtol(nptr, endptr, base)
*/
do {
c = *s++;
- } while (isascii(c) && isspace(c));
+ } while (SM_ISSPACE(c));
if (c == '-') {
neg = 1;
c = *s++;
@@ -4170,7 +4221,7 @@ strtol(nptr, endptr, base)
errno = ERANGE;
} else if (neg)
acc = -acc;
- if (endptr != 0)
+ if (endptr != NULL)
*endptr = (char *)(any ? s - 1 : nptr);
return acc;
}
@@ -4228,16 +4279,16 @@ strstr(big, little)
# ifndef AI_DEFAULT
# define AI_DEFAULT 0 /* dummy */
-# endif /* ! AI_DEFAULT */
+# endif
# ifndef AI_ADDRCONFIG
# define AI_ADDRCONFIG 0 /* dummy */
-# endif /* ! AI_ADDRCONFIG */
+# endif
# ifndef AI_V4MAPPED
# define AI_V4MAPPED 0 /* dummy */
-# endif /* ! AI_V4MAPPED */
+# endif
# ifndef AI_ALL
# define AI_ALL 0 /* dummy */
-# endif /* ! AI_ALL */
+# endif
static struct hostent *
sm_getipnodebyname(name, family, flags, err)
@@ -4255,6 +4306,7 @@ sm_getipnodebyname(name, family, flags, err)
return h;
# else /* HAS_GETHOSTBYNAME2 */
+# ifdef RES_USE_INET6
bool resv6 = true;
if (family == AF_INET6)
@@ -4263,17 +4315,20 @@ sm_getipnodebyname(name, family, flags, err)
resv6 = bitset(RES_USE_INET6, _res.options);
_res.options |= RES_USE_INET6;
}
+# endif /* RES_USE_INET6 */
SM_SET_H_ERRNO(0);
h = gethostbyname(name);
+# ifdef RES_USE_INET6
if (!resv6)
_res.options &= ~RES_USE_INET6;
+# endif
/* the function is supposed to return only the requested family */
if (h != NULL && h->h_addrtype != family)
{
# if NETINET6
freehostent(h);
-# endif /* NETINET6 */
+# endif
h = NULL;
*err = NO_DATA;
}
@@ -4342,7 +4397,7 @@ sm_gethostbyname(name, family)
# ifndef SM_IPNODEBYNAME_FLAGS
/* For IPv4-mapped addresses, use: AI_DEFAULT|AI_ALL */
# define SM_IPNODEBYNAME_FLAGS AI_ADDRCONFIG
-# endif /* SM_IPNODEBYNAME_FLAGS */
+# endif
int flags = SM_IPNODEBYNAME_FLAGS;
int err;
@@ -4357,7 +4412,7 @@ sm_gethostbyname(name, family)
# if NETINET6
# if ADDRCONFIG_IS_BROKEN
flags &= ~AI_ADDRCONFIG;
-# endif /* ADDRCONFIG_IS_BROKEN */
+# endif
h = sm_getipnodebyname(name, family, flags, &err);
SM_SET_H_ERRNO(err);
# else /* NETINET6 */
@@ -4414,7 +4469,7 @@ sm_gethostbyname(name, family)
{
# if NETINET6
freehostent(h);
-# endif /* NETINET6 */
+# endif
h = NULL;
SM_SET_H_ERRNO(NO_DATA);
}
@@ -4433,7 +4488,7 @@ sm_gethostbyname(name, family)
#if NETINET6
struct in6_addr ia6;
char buf6[INET6_ADDRSTRLEN];
-#endif /* NETINET6 */
+#endif
if (h->h_aliases != NULL)
for (i = 0; h->h_aliases[i] != NULL;
@@ -4672,20 +4727,20 @@ add_hostnames(sa)
#if NETINET && defined(IN_LINKLOCAL)
!(sa->sa.sa_family == AF_INET &&
IN_LINKLOCAL(ntohl(sa->sin.sin_addr.s_addr))) &&
-#endif /* NETINET && defined(IN_LINKLOCAL) */
+#endif
#if NETINET6
!(sa->sa.sa_family == AF_INET6 &&
IN6_IS_ADDR_LINKLOCAL(&sa->sin6.sin6_addr)) &&
-#endif /* NETINET6 */
+#endif
true)
sm_syslog(LOG_WARNING, NOQID,
"gethostbyaddr(%.100s) failed: %d",
anynet_ntoa(sa),
#if NAMED_BIND
h_errno
-#else /* NAMED_BIND */
+#else
-1
-#endif /* NAMED_BIND */
+#endif
);
errno = save_errno;
return -1;
@@ -4731,7 +4786,7 @@ add_hostnames(sa)
}
#if NETINET6
freehostent(hp);
-#endif /* NETINET6 */
+#endif
return 0;
}
/*
@@ -4749,17 +4804,17 @@ add_hostnames(sa)
#if !NETINET
# define SIOCGIFCONF_IS_BROKEN 1 /* XXX */
-#endif /* !NETINET */
+#endif
#if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN
struct rtentry;
struct mbuf;
# ifndef SUNOS403
# include <sm/time.h>
-# endif /* ! SUNOS403 */
+# endif
# if (_AIX4 >= 40300) && !defined(_NET_IF_H)
# undef __P
-# endif /* (_AIX4 >= 40300) && !defined(_NET_IF_H) */
+# endif
# include <net/if.h>
#endif /* defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN */
@@ -4793,7 +4848,7 @@ load_if_names()
struct lifconf lifc;
# ifdef SIOCGLIFNUM
struct lifnum lifn;
-# endif /* SIOCGLIFNUM */
+# endif
s = socket(InetMode, SOCK_DGRAM, 0);
if (s == -1)
@@ -4802,7 +4857,7 @@ load_if_names()
/* get the list of known IP address from the kernel */
# ifdef __hpux
i = ioctl(s, SIOCGIFNUM, (char *) &numifs);
-# endif /* __hpux */
+# endif
# ifdef SIOCGLIFNUM
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = 0;
@@ -4836,7 +4891,7 @@ load_if_names()
# ifndef __hpux
lifc.lifc_family = AF_UNSPEC;
lifc.lifc_flags = 0;
-# endif /* ! __hpux */
+# endif
if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0)
{
if (tTd(0, 4))
@@ -4864,7 +4919,7 @@ load_if_names()
struct in_addr ia;
# ifdef SIOCGLIFFLAGS
struct lifreq ifrf;
-# endif /* SIOCGLIFFLAGS */
+# endif
char ip_addr[256];
char buf6[INET6_ADDRSTRLEN];
@@ -5063,15 +5118,15 @@ load_if_names()
# if NETINET6
char *addr;
struct in6_addr ia6;
-# endif /* NETINET6 */
+# endif
struct in_addr ia;
# ifdef SIOCGIFFLAGS
struct ifreq ifrf;
-# endif /* SIOCGIFFLAGS */
+# endif
char ip_addr[256];
# if NETINET6
char buf6[INET6_ADDRSTRLEN];
-# endif /* NETINET6 */
+# endif
/*
** If we don't have a complete ifr structure,
@@ -5095,7 +5150,7 @@ load_if_names()
if (af != AF_INET
# if NETINET6
&& af != AF_INET6
-# endif /* NETINET6 */
+# endif
)
continue;
@@ -5214,17 +5269,26 @@ bool
isloopback(sa)
SOCKADDR sa;
{
-#if NETINET6
- if (IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
- return true;
-#else /* NETINET6 */
/* XXX how to correctly extract IN_LOOPBACKNET part? */
- if (((ntohl(sa.sin.sin_addr.s_addr) & IN_CLASSA_NET)
+#define SM_IS_IPV4_LOOP(a) (((ntohl(a) & IN_CLASSA_NET) \
>> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
+#if NETINET6
+ if (sa.sa.sa_family == AF_INET6 &&
+ IN6_IS_ADDR_V4MAPPED(&sa.sin6.sin6_addr) &&
+ SM_IS_IPV4_LOOP(((uint32_t *) (&sa.sin6.sin6_addr))[3]))
return true;
-#endif /* NETINET6 */
+ if (sa.sa.sa_family == AF_INET6 &&
+ IN6_IS_ADDR_LOOPBACK(&sa.sin6.sin6_addr))
+ return true;
+#endif
+#if NETINET
+ if (sa.sa.sa_family == AF_INET &&
+ SM_IS_IPV4_LOOP(sa.sin.sin_addr.s_addr))
+ return true;
+#endif
return false;
}
+
/*
** GET_NUM_PROCS_ONLINE -- return the number of processors currently online
**
@@ -5367,9 +5431,9 @@ seed_random()
# if HASRANDOM
(void) srandom(seed);
-# else /* HASRANDOM */
+# else
(void) srand((unsigned int) seed);
-# endif /* HASRANDOM */
+# endif
#endif /* HASSRANDOMDEV */
}
/*
@@ -5579,10 +5643,10 @@ sm_syslog(level, id, fmt, va_alist)
# ifdef V4FS
# define XCNST const
# define CAST (const char *)
-# else /* V4FS */
+# else
# define XCNST
# define CAST
-# endif /* V4FS */
+# endif
void
# ifdef __STDC__
@@ -5750,11 +5814,21 @@ link(source, target)
** Compile-Time options
*/
+#define SM_STR(x) #x
+#define SM_XSTR(x) SM_STR(x)
+
char *CompileOptions[] =
{
#if ALLOW_255
"ALLOW_255",
#endif
+#if DANE
+# if STARTTLS
+ "DANE",
+# else
+# error "DANE set but STARTTLS not defined"
+# endif
+#endif
#if NAMED_BIND
# if DNSMAP
"DNSMAP",
@@ -5779,6 +5853,14 @@ char *CompileOptions[] =
#if LDAPMAP
"LDAPMAP",
#endif
+#if LDAP_NETWORK_TIMEOUT
+# if LDAPMAP && defined(LDAP_OPT_NETWORK_TIMEOUT)
+ /* set LDAP_OPT_NETWORK_TIMEOUT if available (-c) */
+ "LDAP_NETWORK_TIMEOUT",
+# else
+# ERROR: _LDAP_NETWORK_TIMEOUT requires _LDAPMAP
+# endif
+#endif
#if LDAP_REFERRALS
"LDAP_REFERRALS",
#endif
@@ -5794,6 +5876,12 @@ char *CompileOptions[] =
#if MATCHGECOS
"MATCHGECOS",
#endif
+#if MAXDAEMONS != 10
+ "MAXDAEMONS=" SM_XSTR(MAXDAEMONS),
+#endif
+#if defined(MSGIDLOGLEN)
+ "MSGIDLOGLEN=" SM_XSTR(MSGIDLOGLEN),
+#endif
#if MILTER
"MILTER",
#endif
@@ -5833,8 +5921,18 @@ char *CompileOptions[] =
#if NETX25
"NETX25",
#endif
+#if NO_EOH_FIELDS
+ "NO_EOH_FIELDS",
+#endif
#if NEWDB
+# if defined(DB_VERSION_MAJOR) && defined(DB_VERSION_MINOR)
+ "NEWDB=" SM_XSTR(DB_VERSION_MAJOR) "." SM_XSTR(DB_VERSION_MINOR),
+# else
"NEWDB",
+# endif
+#endif
+#if CDB
+ "CDB=" SM_XSTR(CDB),
#endif
#if NIS
"NIS",
@@ -5857,7 +5955,7 @@ char *CompileOptions[] =
#if SASL
# if SASL >= 20000
"SASLv2",
-# else /* SASL >= 20000 */
+# else
"SASL",
# endif
#endif
@@ -5879,12 +5977,19 @@ char *CompileOptions[] =
#if SUID_ROOT_FILES_OK
"SUID_ROOT_FILES_OK",
#endif
+#if SYSLOG_BUFSIZE > 1024
+ "SYSLOG_BUFSIZE=" SM_XSTR(SYSLOG_BUFSIZE),
+#endif
#if TCPWRAPPERS
"TCPWRAPPERS",
#endif
#if TLS_NO_RSA
"TLS_NO_RSA",
#endif
+#if TLS_EC
+ /* elliptic curves */
+ "TLS_EC",
+#endif
#if TLS_VRFY_PER_CTX
"TLS_VRFY_PER_CTX",
#endif
@@ -5934,6 +6039,9 @@ char *OsCompileOptions[] =
#if DEC_OSF_BROKEN_GETPWENT
"DEC_OSF_BROKEN_GETPWENT",
#endif
+#if DNSSEC_TEST
+ "DNSSEC_TEST",
+#endif
#if FAST_PID_RECYCLE
"FAST_PID_RECYCLE",
#endif
@@ -5955,6 +6063,9 @@ char *OsCompileOptions[] =
#if HASGETDTABLESIZE
"HASGETDTABLESIZE",
#endif
+#if HAS_GETHOSTBYNAME2
+ "HAS_GETHOSTBYNAME2",
+#endif
#if HASGETUSERSHELL
"HASGETUSERSHELL",
#endif
@@ -6138,8 +6249,17 @@ char *OsCompileOptions[] =
"USESYSCTL",
#endif
#if USE_OPENSSL_ENGINE
+ /*
+ ** 0: OpenSSL ENGINE?
+ ** 1: Support Sun OpenSSL patch for SPARC T4 pkcs11
+ ** 2: none
+ */
+# if USE_OPENSSL_ENGINE != 1
+ "USE_OPENSSL_ENGINE=" SM_XSTR(USE_OPENSSL_ENGINE),
+# else
"USE_OPENSSL_ENGINE",
#endif
+#endif
#if USING_NETSCAPE_LDAP
"USING_NETSCAPE_LDAP",
#endif
@@ -6156,6 +6276,7 @@ char *OsCompileOptions[] =
char *FFRCompileOptions[] =
{
#if _FFR_ADD_BCC
+ /* see cf/feature/bcc.m4 */
"_FFR_ADD_BCC",
#endif
#if _FFR_ADDR_TYPE_MODES
@@ -6179,6 +6300,10 @@ char *FFRCompileOptions[] =
/* Better truncation of list of MX records for dns map. */
"_FFR_BESTMX_BETTER_TRUNCATION",
#endif
+#if _FFR_BLANKENV_MACV
+ /* also look up macros in BlankEnvelope */
+ "_FFR_BLANKENV_MACV",
+#endif
#if _FFR_BOUNCE_QUEUE
/* Separate, unprocessed queue for DSNs */
/* John Gardiner Myers of Proofpoint */
@@ -6192,14 +6317,28 @@ char *FFRCompileOptions[] =
/* Stricter checks about queue directory permissions. */
"_FFR_CHK_QUEUE",
#endif
+#if _FFR_CLIENTCA
+ /*
+ ** Allow to set client specific CA values.
+ ** CACertFile: see doc/op.*:
+ ** "The DNs of these certificates are sent to the client
+ ** during the TLS handshake (as part of the CertificateRequest)
+ ** as the list of acceptable CAs.
+ ** However, do not list too many root CAs in that file,
+ ** otherwise the TLS handshake may fail;"
+ ** In TLSv1.3 the certs in CACertFile are also sent by
+ ** the client to the server and there is seemingly a
+ ** 16KB limit (just in OpenSSL?).
+ ** Having a separate CACertFile for the client
+ ** helps to avoid this problem.
+ */
+
+ "_FFR_CLIENTCA",
+#endif
#if _FFR_CLIENT_SIZE
/* Don't try to send mail if its size exceeds SIZE= of server. */
"_FFR_CLIENT_SIZE",
#endif
-#if _FFR_CRLPATH
- /* CRLPath; needs documentation; Al Smith */
- "_FFR_CRLPATH",
-#endif
#if _FFR_DM_ONE
/* deliver first TA in background, then queue */
"_FFR_DM_ONE",
@@ -6254,6 +6393,10 @@ char *FFRCompileOptions[] =
/* EightBitAddrOK: allow 8-bit e-mail addresses */
"_FFR_EIGHT_BIT_ADDR_OK",
#endif
+#if _FFR_EXPAND_HELONAME
+ /* perform macro expansion for heloname */
+ "_FFR_EXPAND_HELONAME",
+#endif
#if _FFR_EXTRA_MAP_CHECK
/* perform extra checks on $( $) in R lines */
"_FFR_EXTRA_MAP_CHECK",
@@ -6320,9 +6463,9 @@ char *FFRCompileOptions[] =
/* Ignore extensions offered in response to HELO */
"_FFR_IGNORE_EXT_ON_HELO",
#endif
-#if _FFR_LINUX_MHNL
- /* Set MAXHOSTNAMELEN to 256 (Linux) */
- "_FFR_LINUX_MHNL",
+#if _FFR_KEEPBCC
+ /* Keep Bcc header */
+ "_FFR_KEEPBCC",
#endif
#if _FFR_LOCAL_DAEMON
/* Local daemon mode (-bl) which only accepts loopback connections */
@@ -6330,16 +6473,19 @@ char *FFRCompileOptions[] =
#endif
#if _FFR_LOG_MORE1
/* log some TLS/AUTH info in from= too */
- "_FFR_LOG_MORE1",
+ "_FFR_LOG_MORE1=" SM_XSTR(_FFR_LOG_MORE1),
#endif
#if _FFR_LOG_MORE2
/* log some TLS info in to= too */
- "_FFR_LOG_MORE2",
+ "_FFR_LOG_MORE2=" SM_XSTR(_FFR_LOG_MORE2),
#endif
-#if _FFR_LOGREPLY
- "_FFR_LOGREPLY",
+#if _FFR_LOG_MORE1 > 1 || _FFR_LOG_MORE2 > 1
+# if _FFR_LOG_MORE1 != _FFR_LOG_MORE2
+ ERROR: FFR_LOG_MORE1 != FFR_LOG_MORE2
+# endif
#endif
#if _FFR_MAIL_MACRO
+ /* make the "real" sender address available in {mail_from} */
"_FFR_MAIL_MACRO",
#endif
#if _FFR_MAXDATASIZE
@@ -6363,7 +6509,7 @@ char *FFRCompileOptions[] =
"_FFR_MAX_SLEEP_TIME",
#endif
#if _FFR_MDS_NEGOTIATE
- /* MaxDataSize negotation with libmilter */
+ /* MaxDataSize negotiation with libmilter */
"_FFR_MDS_NEGOTIATE",
#endif
#if _FFR_MEMSTAT
@@ -6429,19 +6575,43 @@ char *FFRCompileOptions[] =
/* Disable PIPELINING, delay client if used. */
"_FFR_NO_PIPE",
#endif
-#if _FFR_LDAP_NETWORK_TIMEOUT
- /* set LDAP_OPT_NETWORK_TIMEOUT if available (-c) */
- "_FFR_LDAP_NETWORK_TIMEOUT",
+#if _FFR_LDAP_SINGLEDN
+ /*
+ ** The LDAP database map code in Sendmail 8.12.10, when
+ ** given the -1 switch, would match only a single DN,
+ ** but was able to return multiple attributes for that
+ ** DN. In Sendmail 8.13 this "bug" was corrected to
+ ** only return if exactly one attribute matched.
+ **
+ ** Unfortunately, our configuration uses the former
+ ** behaviour. Attached is a relatively simple patch
+ ** to 8.13.4 which adds a -2 switch (for lack of a
+ ** better option) which returns the single dn/multiple
+ ** attributes.
+ **
+ ** Jeffrey T. Eaton, Carnegie-Mellon University
+ */
+
+ "_FFR_LDAP_SINGLEDN",
#endif
#if _FFR_LOG_NTRIES
/* log ntries=, from Nik Clayton of FreeBSD */
"_FFR_LOG_NTRIES",
#endif
+#if _FFR_OCC
+# if SM_CONF_SHM
+ /* outgoing connection control (not yet working) */
+ "_FFR_OCC",
+# else
+# ERROR: FFR_OCC requires _SM_CONF_SHM
+# endif
+#endif
#if _FFR_PROXY
/* "proxy" (synchronous) delivery mode */
"_FFR_PROXY",
#endif
#if _FFR_QF_PARANOIA
+ /* Check to make sure key fields were read from qf */
"_FFR_QF_PARANOIA",
#endif
#if _FFR_QUEUE_GROUP_SORTORDER
@@ -6462,6 +6632,7 @@ char *FFRCompileOptions[] =
"_FFR_QUEUE_SCHED_DBG",
#endif
#if _FFR_RCPTFLAGS
+ /* dynamic mailer modifications via {rcpt_flags}*/
"_FFR_RCPTFLAGS",
#endif
#if _FFR_RCPTTHROTDELAY
@@ -6498,32 +6669,22 @@ char *FFRCompileOptions[] =
"_FFR_RUNPQG",
#endif
#if _FFR_SESSID
- /* session id (for logging) */
+ /* session id (for logging): WIP, no logging yet! */
"_FFR_SESSID",
#endif
+#if _FFR_SETANYOPT
+ "_FFR_SETANYOPT",
+#endif
+#if _FFR_SETDEBUG_MAP
+ "_FFR_SETDEBUG_MAP",
+#endif
+#if _FFR_SETOPT_MAP
+ "_FFR_SETOPT_MAP",
+#endif
#if _FFR_SHM_STATUS
/* Donated code (unused). */
"_FFR_SHM_STATUS",
#endif
-#if _FFR_LDAP_SINGLEDN
- /*
- ** The LDAP database map code in Sendmail 8.12.10, when
- ** given the -1 switch, would match only a single DN,
- ** but was able to return multiple attributes for that
- ** DN. In Sendmail 8.13 this "bug" was corrected to
- ** only return if exactly one attribute matched.
- **
- ** Unfortunately, our configuration uses the former
- ** behaviour. Attached is a relatively simple patch
- ** to 8.13.4 which adds a -2 switch (for lack of a
- ** better option) which returns the single dn/multiple
- ** attributes.
- **
- ** Jeffrey T. Eaton, Carnegie-Mellon University
- */
-
- "_FFR_LDAP_SINGLEDN",
-#endif
#if _FFR_SKIP_DOMAINS
/* process every N'th domain instead of every N'th message */
"_FFR_SKIP_DOMAINS",
@@ -6532,6 +6693,14 @@ char *FFRCompileOptions[] =
/* Use select(2) in libsm/clock.c to emulate sleep(2) */
"_FFR_SLEEP_USE_SELECT ",
#endif
+#if _FFR_SM_LDAP_DBG
+# if LDAPMAP && defined(LBER_OPT_LOG_PRINT_FN)
+ /* LDAP debugging */
+ "_FFR_SM_LDAP_DBG",
+# else
+# ERROR: FFR_SM_LDAP_DBG requires _LDAPMAP and LBER_OPT_LOG_PRINT_FN
+# endif
+#endif
#if _FFR_SPT_ALIGN
/*
** It looks like the Compaq Tru64 5.1A now aligns argv and envp to 64
@@ -6556,8 +6725,21 @@ char *FFRCompileOptions[] =
/* Donated code (unused). */
"_FFR_TIMERS",
#endif
-#if _FFR_TLS_EC
- "_FFR_TLS_EC",
+#if _FFR_TLS_ALTNAMES
+ /* store subjectAltNames in class {cert_altnames} */
+# if STARTTLS
+ "_FFR_TLS_ALTNAMES",
+# else
+# error "_FFR_TLS_ALTNAMES set but STARTTLS not defined"
+# endif
+#endif
+#if _FFR_TLSFB2CLEAR
+ /* set default for TLSFallbacktoClear to true */
+# if STARTTLS
+ "_FFR_TLSFB2CLEAR",
+# else
+# error "_FFR_TLSFB2CLEAR set but STARTTLS not defined"
+# endif
#endif
#if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
/*
@@ -6565,11 +6747,11 @@ char *FFRCompileOptions[] =
** instead of SSL_CTX_use_certificate_file()
*/
+# if STARTTLS
"_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE",
-#endif
-#if _FFR_TLS_SE_OPTS
- /* TLS session options */
- "_FFR_TLS_SE_OPTS",
+# else
+# error "_FFR_TLS_USE_CERTIFICATE_CHAIN_FILE set but STARTTLS not defined"
+# endif
#endif
#if _FFR_TRUSTED_QF
/*
@@ -6590,7 +6772,30 @@ char *FFRCompileOptions[] =
"_FFR_USE_GETPWNAM_ERRNO",
#endif
+#if _FFR_VRFY_TRUSTED_FIRST
+ /*
+ ** Sets X509_V_FLAG_TRUSTED_FIRST if -d88;.101 is used.
+ ** X509_VERIFY_PARAM_set_flags(3)
+ ** When X509_V_FLAG_TRUSTED_FIRST is set, construction of the
+ ** certificate chain in X509_verify_cert(3) will search the trust
+ ** store for issuer certificates before searching the provided
+ ** untrusted certificates. Local issuer certificates are often more
+ ** likely to satisfy local security requirements and lead to a locally
+ ** trusted root. This is especially important when some certificates
+ ** in the trust store have explicit trust settings (see "TRUST
+ ** SETTINGS" in x509(1)).
+ ** As of OpenSSL 1.1.0 this option is on by default.
+ */
+
+# if defined(X509_V_FLAG_TRUSTED_FIRST)
+ "_FFR_VRFY_TRUSTED_FIRST",
+# else
+# error "FFR_VRFY_TRUSTED_FIRST set but X509_V_FLAG_TRUSTED_FIRST not defined"
+# endif
+#endif
+
#if _FFR_USE_SEM_LOCKING
+ /* Use semaphore locking */
"_FFR_USE_SEM_LOCKING",
#endif
#if _FFR_USE_SETLOGIN
@@ -6599,8 +6804,27 @@ char *FFRCompileOptions[] =
"_FFR_USE_SETLOGIN",
#endif
#if _FFR_XCNCT
+ /* X-Connect support */
"_FFR_XCNCT",
#endif
+#if _FFR_EAI
+
+ /*
+ ** Initial/Partial/Experimental EAI (SMTPUTF8) support.
+ ** NOTE: This is currently BROKEN as the handling of
+ ** envelope addresses in sendmail is NOT 8-bit clean
+ ** (in contrast to header addresses/values).
+ ** Requires ICU include files and library depending on the OS.
+ ** Patch from Arnt Gulbrandsen.
+ */
+
+# if !ALLOW_255
+# ERROR FFR_EAI requires _ALLOW_255
+# endif
+# if _FFR_EIGHT_BIT_ADDR_OK
+# error "Cannot enable both of these FFRs: FFR_EAI FFR_EIGHT_BIT_ADDR_OK"
+# endif
+ "_FFR_EAI",
+#endif
NULL
};
-
diff --git a/contrib/sendmail/src/conf.h b/contrib/sendmail/src/conf.h
index 54b1d09fc0ac..b5b368f48d68 100644
--- a/contrib/sendmail/src/conf.h
+++ b/contrib/sendmail/src/conf.h
@@ -16,8 +16,9 @@
/*
** CONF.H -- All user-configurable parameters for sendmail
**
-** Send updates to sendmail@Sendmail.ORG so they will be
-** included in the next release.
+** Send updates to sendmail-YYYY@support.sendmail.org
+** (replace YYYY with the current year)
+** so they will be included in the next release.
*/
#ifndef CONF_H
@@ -25,7 +26,7 @@
#ifdef __GNUC__
struct rusage; /* forward declaration to get gcc to shut up in wait.h */
-#endif /* __GNUC__ */
+#endif
# include <sys/param.h>
# include <sys/types.h>
@@ -33,7 +34,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
# ifndef __QNX__
/* in QNX this grabs bogus LOCK_* manifests */
# include <sys/file.h>
-# endif /* ! __QNX__ */
+# endif
# include <sys/wait.h>
# include <limits.h>
# include <fcntl.h>
@@ -46,12 +47,12 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#ifdef ARG_MAX
# if ARG_MAX > 4096
# define SM_ARG_MAX 4096
-# else /* ARG_MAX > 4096 */
+# else
# define SM_ARG_MAX ARG_MAX
-# endif /* ARG_MAX > 4096 */
-#else /* ARG_MAX */
+# endif
+#else
# define SM_ARG_MAX 4096
-#endif /* ARG_MAX */
+#endif
/**********************************************************************
** Table sizes, etc....
@@ -62,13 +63,13 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#define MAXLINE 2048 /* max line length */
#if SASL
# define MAXINPLINE 12288 /* max input line length (for AUTH) */
-#else /* SASL */
+#else
# define MAXINPLINE MAXLINE /* max input line length */
-#endif /* SASL */
+#endif
#define MAXNAME 256 /* max length of a name */
#ifndef MAXAUTHINFO
# define MAXAUTHINFO 100 /* max length of authinfo token */
-#endif /* ! MAXAUTHINFO */
+#endif
#define MAXPV 256 /* max # of parms to mailers */
#define MAXATOM 1000 /* max atoms per address */
#define MAXRWSETS 200 /* max # of sets of rewriting rules */
@@ -83,7 +84,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#if MILTER
# define MAXFILTERS 25 /* max # of milter filters */
# define MAXFILTERMACROS 50 /* max # of macros per milter cmd */
-#endif /* MILTER */
+#endif
#define MAXSMTPARGS 20 /* max # of ESMTP args for MAIL/RCPT */
#define MAXTOCLASS 8 /* max # of message timeout classes */
#define MAXRESTOTYPES 3 /* max # of resolver timeout types */
@@ -93,7 +94,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#ifndef MAXNOOPCOMMANDS
# define MAXNOOPCOMMANDS 20 /* max "noise" commands before slowdown */
-#endif /* ! MAXNOOPCOMMANDS */
+#endif
/*
** MAXQFNAME == 2 (size of "qf", "df" prefix)
@@ -111,16 +112,17 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
/* Must match (BITMAPBITS - 1) */
#ifndef MAXHDRSLEN
# define MAXHDRSLEN (32 * 1024) /* max size of message headers */
-#endif /* ! MAXHDRSLEN */
+#endif
#ifndef MAXDAEMONS
# define MAXDAEMONS 10 /* max number of ports to listen to */
-#endif /* MAXDAEMONS */
+ /* XREF: conf.c: MAXDAEMONS != 10 */
+#endif
#ifndef MAXINTERFACES
# define MAXINTERFACES 512 /* number of interfaces to probe */
-#endif /* MAXINTERFACES */
+#endif
#ifndef MAXSYMLINKS
# define MAXSYMLINKS 32 /* max number of symlinks in a path */
-#endif /* ! MAXSYMLINKS */
+#endif
#define MAXLINKPATHLEN (MAXPATHLEN * MAXSYMLINKS) /* max link-expanded file */
#define DATA_PROGRESS_TIMEOUT 300 /* how often to check DATA progress */
#define ENHSCLEN 10 /* max len of enhanced status code */
@@ -128,32 +130,32 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#ifndef MAXQUEUEGROUPS
# define MAXQUEUEGROUPS 50 /* max # of queue groups */
/* must be less than BITMAPBITS for DoQueueRun */
-#endif /* MAXQUEUEGROUPS */
+#endif
#if MAXQUEUEGROUPS >= BITMAPBITS
ERROR _MAXQUEUEGROUPS must be less than _BITMAPBITS
-#endif /* MAXQUEUEGROUPS >= BITMAPBITS */
+#endif
#ifndef MAXWORKGROUPS
# define MAXWORKGROUPS 50 /* max # of work groups */
-#endif /* MAXWORKGROUPS */
+#endif
#define MAXFILESYS BITMAPBITS /* max # of queue file systems
* must be <= BITMAPBITS */
#ifndef FILESYS_UPDATE_INTERVAL
# define FILESYS_UPDATE_INTERVAL 300 /* how often to update FileSys table */
-#endif /* FILESYS_UPDATE_INTERVAL */
+#endif
#ifndef SM_DEFAULT_TTL
# define SM_DEFAULT_TTL 3600 /* default TTL for services that don't have one */
-#endif /* SM_DEFAULT_TTL */
+#endif
#if SASL
# ifndef AUTH_MECHANISMS
# if STARTTLS
# define AUTH_MECHANISMS "EXTERNAL GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5"
-# else /* STARTTLS */
+# else
# define AUTH_MECHANISMS "GSSAPI KERBEROS_V4 DIGEST-MD5 CRAM-MD5"
-# endif /* STARTTLS */
+# endif
# endif /* ! AUTH_MECHANISMS */
#endif /* SASL */
@@ -164,7 +166,7 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#ifndef DBMMODE
# define DBMMODE 0640
-#endif /* ! DBMMODE */
+#endif
/*
** Value which means a uid or gid value should not change
@@ -172,10 +174,10 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#ifndef NO_UID
# define NO_UID -1
-#endif /* ! NO_UID */
+#endif
#ifndef NO_GID
# define NO_GID -1
-#endif /* ! NO_GID */
+#endif
/**********************************************************************
** Compilation options.
@@ -186,58 +188,66 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */
#ifndef NETINET
# define NETINET 1 /* include internet support */
-#endif /* ! NETINET */
+#endif
#ifndef NETINET6
# define NETINET6 0 /* do not include IPv6 support */
-#endif /* ! NETINET6 */
+#endif
#ifndef NETISO
# define NETISO 0 /* do not include ISO socket support */
-#endif /* ! NETISO */
+#endif
#ifndef NAMED_BIND
# define NAMED_BIND 1 /* use Berkeley Internet Domain Server */
-#endif /* ! NAMED_BIND */
+#endif
#ifndef XDEBUG
# define XDEBUG 1 /* enable extended debugging */
-#endif /* ! XDEBUG */
+#endif
#ifndef MATCHGECOS
# define MATCHGECOS 1 /* match user names from gecos field */
-#endif /* ! MATCHGECOS */
+#endif
#ifndef DSN
# define DSN 1 /* include delivery status notification code */
-#endif /* ! DSN */
+#endif
#if !defined(USERDB) && (defined(NEWDB) || defined(HESIOD))
# define USERDB 1 /* look in user database */
-#endif /* !defined(USERDB) && (defined(NEWDB) || defined(HESIOD)) */
+#endif
#ifndef MIME8TO7
# define MIME8TO7 1 /* 8->7 bit MIME conversions */
-#endif /* ! MIME8TO7 */
+#endif
#ifndef MIME7TO8
# define MIME7TO8 1 /* 7->8 bit MIME conversions */
-#endif /* ! MIME7TO8 */
+#endif
#if NAMED_BIND
# ifndef DNSMAP
# define DNSMAP 1 /* DNS map type */
-# endif /* ! DNSMAP */
-#endif /* NAMED_BIND */
+# endif
+#endif
#ifndef PIPELINING
# define PIPELINING 1 /* SMTP PIPELINING */
-#endif /* PIPELINING */
+#endif
/**********************************************************************
** End of site-specific configuration.
**********************************************************************/
+#if CDB >= 2
+# define CDBEXT ".db"
+# define CDBext "db"
+#else
+# define CDBEXT ".cdb"
+# define CDBext "cdb"
+#endif
+
#include <sm/conf.h>
#endif /* ! CONF_H */
diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c
index 254197389476..a6d8ad631335 100644
--- a/contrib/sendmail/src/control.c
+++ b/contrib/sendmail/src/control.c
@@ -314,17 +314,16 @@ control_command(sock, e)
sm_setproctitle(false, e, "control: %s", inp);
/* break off command */
- for (p = inp; isascii(*p) && isspace(*p); p++)
+ for (p = inp; SM_ISSPACE(*p); p++)
continue;
cmd = cmdbuf;
while (*p != '\0' &&
- !(isascii(*p) && isspace(*p)) &&
- cmd < &cmdbuf[sizeof(cmdbuf) - 2])
+ !(SM_ISSPACE(*p)) && cmd < &cmdbuf[sizeof(cmdbuf) - 2])
*cmd++ = *p++;
*cmd = '\0';
/* throw away leading whitespace */
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* decode command */
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index 42883658db89..19a937815cbd 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -18,22 +18,40 @@ SM_RCSID("@(#)$Id: daemon.c,v 8.698 2013-11-22 20:51:55 ca Exp $")
#if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
# define USE_SOCK_STREAM 1
-#endif /* defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) */
+#endif
#if defined(USE_SOCK_STREAM)
# if NETINET || NETINET6
# include <arpa/inet.h>
-# endif /* NETINET || NETINET6 */
+# endif
# if NAMED_BIND
# ifndef NO_DATA
# define NO_DATA NO_ADDRESS
-# endif /* ! NO_DATA */
+# endif
# endif /* NAMED_BIND */
#endif /* defined(USE_SOCK_STREAM) */
#if STARTTLS
# include <openssl/rand.h>
-#endif /* STARTTLS */
+# if DANE
+# include "tls.h"
+# include "sm_resolve.h"
+# endif
+#endif
+
+#if NETINET6
+# define FREEHOSTENT(h, s) \
+ do \
+ { \
+ if ((h) != (s) && (h) != NULL) \
+ { \
+ freehostent((h)); \
+ (h) = NULL; \
+ } \
+ } while (0)
+#else
+# define FREEHOSTENT(h, s)
+#endif
#include <sm/time.h>
@@ -59,6 +77,8 @@ SM_RCSID("@(#)$Id: daemon.c,v 8.698 2013-11-22 20:51:55 ca Exp $")
#include <sm/fdset.h>
+#include <ratectrl.h>
+
#define DAEMON_C 1
#include <daemon.h>
@@ -133,16 +153,16 @@ getrequests(e)
int i, olddaemon = 0;
#if XDEBUG
bool j_has_dot;
-#endif /* XDEBUG */
+#endif
char status[MAXLINE];
SOCKADDR sa;
SOCKADDR_LEN_T len = sizeof(sa);
#if _FFR_QUEUE_RUN_PARANOIA
time_t lastrun;
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
-# if NETUNIX
+#endif
+#if NETUNIX
extern int ControlSocket;
-# endif /* NETUNIX */
+#endif
extern ENVELOPE BlankEnvelope;
@@ -215,7 +235,7 @@ getrequests(e)
time_t now;
#if STARTTLS
long seed;
-#endif /* STARTTLS */
+#endif
/* see if we are rejecting connections */
(void) sm_blocksignal(SIGALRM);
@@ -353,7 +373,7 @@ getrequests(e)
(void) runqueue(true, false, false, false);
#if _FFR_QUEUE_RUN_PARANOIA
lastrun = now;
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#endif
}
#if _FFR_QUEUE_RUN_PARANOIA
else if (CheckQueueRunners > 0 && QueueIntvl > 0 &&
@@ -405,9 +425,9 @@ getrequests(e)
if (t >= 0 &&
(lotherend == 0 ||
-# ifdef BSD4_4_SOCKADDR
+#ifdef BSD4_4_SOCKADDR
RealHostAddr.sa.sa_len == 0 ||
-# endif /* BSD4_4_SOCKADDR */
+#endif
RealHostAddr.sa.sa_family != Daemons[idx].d_addr.sa.sa_family))
{
(void) close(t);
@@ -442,7 +462,7 @@ getrequests(e)
(lotherend == 0 ||
# ifdef BSD4_4_SOCKADDR
sa_un.sun_len == 0 ||
-# endif /* BSD4_4_SOCKADDR */
+# endif
sa_un.sun_family != AF_UNIX))
{
(void) close(t);
@@ -477,13 +497,13 @@ getrequests(e)
if (save_errno == EINTR
#ifdef EAGAIN
|| save_errno == EAGAIN
-#endif /* EAGAIN */
+#endif
#ifdef ECONNABORTED
|| save_errno == ECONNABORTED
-#endif /* ECONNABORTED */
+#endif
#ifdef EWOULDBLOCK
|| save_errno == EWOULDBLOCK
-#endif /* EWOULDBLOCK */
+#endif
)
continue;
@@ -522,37 +542,37 @@ getrequests(e)
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "local");
break;
-#endif /* NETUNIX */
+#endif
#if NETINET
case AF_INET:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "inet");
break;
-#endif /* NETINET */
+#endif
#if NETINET6
case AF_INET6:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "inet6");
break;
-#endif /* NETINET6 */
+#endif
#if NETISO
case AF_ISO:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "iso");
break;
-#endif /* NETISO */
+#endif
#if NETNS
case AF_NS:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "ns");
break;
-#endif /* NETNS */
+#endif
#if NETX25
case AF_CCITT:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_family}"), "x.25");
break;
-#endif /* NETX25 */
+#endif
}
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{daemon_name}"),
@@ -1179,24 +1199,24 @@ opendaemonsocket(d, firsttime)
case AF_UNIX:
socksize = sizeof(d->d_addr.sunix);
break;
-#endif /* NETUNIX */
+#endif
#if NETINET
case AF_INET:
socksize = sizeof(d->d_addr.sin);
break;
-#endif /* NETINET */
+#endif
#if NETINET6
case AF_INET6:
socksize = sizeof(d->d_addr.sin6);
break;
-#endif /* NETINET6 */
+#endif
#if NETISO
case AF_ISO:
socksize = sizeof(d->d_addr.siso);
break;
-#endif /* NETISO */
+#endif
default:
socksize = sizeof(d->d_addr);
@@ -1255,7 +1275,7 @@ setupdaemon(daemonaddr)
memset(daemonaddr, '\0', sizeof(*daemonaddr));
#if NETINET
daemonaddr->sa.sa_family = AF_INET;
-#endif /* NETINET */
+#endif
}
switch (daemonaddr->sa.sa_family)
@@ -1310,13 +1330,13 @@ setupdaemon(daemonaddr)
case AF_INET:
daemonaddr->sin.sin_port = port;
break;
-#endif /* NETINET */
+#endif
#if NETINET6
case AF_INET6:
daemonaddr->sin6.sin6_port = port;
break;
-#endif /* NETINET6 */
+#endif
default:
/* unknown protocol */
@@ -1442,17 +1462,17 @@ setsockaddroptions(p, d)
{
#if NETISO
short portno;
-#endif /* NETISO */
+#endif
char *port = NULL;
char *addr = NULL;
#if NETINET
if (d->d_addr.sa.sa_family == AF_UNSPEC)
d->d_addr.sa.sa_family = AF_INET;
-#endif /* NETINET */
+#endif
#if _FFR_SS_PER_DAEMON
d->d_supersafe = DPO_NOTSET;
-#endif /* _FFR_SS_PER_DAEMON */
+#endif
d->d_dm = DM_NOTSET;
d->d_refuseLA = DPO_NOTSET;
d->d_queueLA = DPO_NOTSET;
@@ -1464,7 +1484,7 @@ setsockaddroptions(p, d)
register char *f;
register char *v;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
break;
@@ -1483,7 +1503,7 @@ setsockaddroptions(p, d)
case 'A': /* address */
#if !_FFR_DPO_CS
case 'a':
-#endif /* !_FFR_DPO_CS */
+#endif
addr = v;
break;
@@ -1500,7 +1520,7 @@ setsockaddroptions(p, d)
case SM_FORK:
#if _FFR_PROXY
case SM_PROXY_REQ:
-#endif /* _FFR_PROXY */
+#endif
d->d_dm = *v;
break;
default:
@@ -1517,34 +1537,34 @@ setsockaddroptions(p, d)
case 'F': /* address family */
#if !_FFR_DPO_CS
case 'f':
-#endif /* !_FFR_DPO_CS */
+#endif
if (isascii(*v) && isdigit(*v))
d->d_addr.sa.sa_family = atoi(v);
#ifdef NETUNIX
else if (sm_strcasecmp(v, "unix") == 0 ||
sm_strcasecmp(v, "local") == 0)
d->d_addr.sa.sa_family = AF_UNIX;
-#endif /* NETUNIX */
+#endif
#if NETINET
else if (sm_strcasecmp(v, "inet") == 0)
d->d_addr.sa.sa_family = AF_INET;
-#endif /* NETINET */
+#endif
#if NETINET6
else if (sm_strcasecmp(v, "inet6") == 0)
d->d_addr.sa.sa_family = AF_INET6;
-#endif /* NETINET6 */
+#endif
#if NETISO
else if (sm_strcasecmp(v, "iso") == 0)
d->d_addr.sa.sa_family = AF_ISO;
-#endif /* NETISO */
+#endif
#if NETNS
else if (sm_strcasecmp(v, "ns") == 0)
d->d_addr.sa.sa_family = AF_NS;
-#endif /* NETNS */
+#endif
#if NETX25
else if (sm_strcasecmp(v, "x.25") == 0)
d->d_addr.sa.sa_family = AF_CCITT;
-#endif /* NETX25 */
+#endif
else
syserr("554 5.3.5 Unknown address family %s in Family=option",
v);
@@ -1554,7 +1574,7 @@ setsockaddroptions(p, d)
case 'I':
# if !_FFR_DPO_CS
case 'i':
-# endif /* !_FFR_DPO_CS */
+# endif
d->d_inputfilterlist = v;
break;
#endif /* MILTER */
@@ -1562,28 +1582,28 @@ setsockaddroptions(p, d)
case 'L': /* listen queue size */
#if !_FFR_DPO_CS
case 'l':
-#endif /* !_FFR_DPO_CS */
+#endif
d->d_listenqueue = atoi(v);
break;
case 'M': /* modifiers (flags) */
#if !_FFR_DPO_CS
case 'm':
-#endif /* !_FFR_DPO_CS */
+#endif
d->d_mflags = getmodifiers(v, d->d_flags);
break;
case 'N': /* name */
#if !_FFR_DPO_CS
case 'n':
-#endif /* !_FFR_DPO_CS */
+#endif
d->d_name = v;
break;
case 'P': /* port */
#if !_FFR_DPO_CS
case 'p':
-#endif /* !_FFR_DPO_CS */
+#endif
port = v;
break;
@@ -1602,7 +1622,7 @@ setsockaddroptions(p, d)
case 'S': /* send buffer size */
#if !_FFR_DPO_CS
case 's':
-#endif /* !_FFR_DPO_CS */
+#endif
d->d_tcpsndbufsize = atoi(v);
break;
@@ -1677,10 +1697,7 @@ setsockaddroptions(p, d)
memmove(&d->d_addr.sin.sin_addr,
*(hp->h_addr_list),
INADDRSZ);
-# if NETINET6
- freehostent(hp);
- hp = NULL;
-# endif /* NETINET6 */
+ FREEHOSTENT(hp, NULL);
}
}
break;
@@ -1709,8 +1726,7 @@ setsockaddroptions(p, d)
memmove(&d->d_addr.sin6.sin6_addr,
*(hp->h_addr_list),
IN6ADDRSZ);
- freehostent(hp);
- hp = NULL;
+ FREEHOSTENT(hp, NULL);
}
}
break;
@@ -1885,7 +1901,7 @@ setdaemonoptions(p)
#if MILTER
if (Daemons[NDaemons].d_inputfilterlist != NULL)
Daemons[NDaemons].d_inputfilterlist = newstr(Daemons[NDaemons].d_inputfilterlist);
-#endif /* MILTER */
+#endif
if (Daemons[NDaemons].d_name != NULL)
Daemons[NDaemons].d_name = newstr(Daemons[NDaemons].d_name);
@@ -1985,7 +2001,7 @@ addr_family(addr)
{
#if NETINET6
SOCKADDR clt_addr;
-#endif /* NETINET6 */
+#endif
#if NETINET
if (inet_addr(addr) != INADDR_NONE)
@@ -2104,12 +2120,19 @@ static jmp_buf CtxConnectTimeout;
SOCKADDR CurHostAddr; /* address of current host */
int
-makeconnection(host, port, mci, e, enough)
+makeconnection(host, port, mci, e, enough
+#if DANE
+ , ptlsa_flags
+#endif
+ )
char *host;
volatile unsigned int port;
register MCI *mci;
ENVELOPE *e;
time_t enough;
+#if DANE
+ unsigned long *ptlsa_flags;
+#endif
{
register volatile int addrno = 0;
volatile int s;
@@ -2122,7 +2145,7 @@ makeconnection(host, port, mci, e, enough)
SM_EVENT *volatile ev = NULL;
#if NETINET6
volatile bool v6found = false;
-#endif /* NETINET6 */
+#endif
volatile int family = InetMode;
SOCKADDR_LEN_T len;
volatile SOCKADDR_LEN_T socksize = 0;
@@ -2130,6 +2153,20 @@ makeconnection(host, port, mci, e, enough)
BITMAP256 d_flags;
char *p;
extern ENVELOPE BlankEnvelope;
+#if DANE
+ unsigned long tlsa_flags;
+#endif
+#if DANE && NETINET6
+ struct hostent *volatile hs = (struct hostent *) NULL;
+#else
+# define hs ((struct hostent *) NULL)
+#endif
+
+#if DANE
+ SM_REQUIRE(ptlsa_flags != NULL);
+ tlsa_flags = *ptlsa_flags;
+ *ptlsa_flags &= ~(TLSAFLALWAYS|TLSAFLSECURE);
+#endif
/* retranslate {daemon_flags} into bitmap */
clrbitmap(d_flags);
@@ -2137,14 +2174,14 @@ makeconnection(host, port, mci, e, enough)
{
for (; *p != '\0'; p++)
{
- if (!(isascii(*p) && isspace(*p)))
+ if (!(SM_ISSPACE(*p)))
setbitn(bitidx(*p), d_flags);
}
}
#if NETINET6
v4retry:
-#endif /* NETINET6 */
+#endif
clt_bind = false;
/* Set up the address for outgoing connection. */
@@ -2154,7 +2191,7 @@ makeconnection(host, port, mci, e, enough)
{
#if NETINET6
char p6[INET6_ADDRSTRLEN];
-#endif /* NETINET6 */
+#endif
memset(&clt_addr, '\0', sizeof(clt_addr));
@@ -2264,15 +2301,15 @@ makeconnection(host, port, mci, e, enough)
{
#if NETINET
unsigned long hid = INADDR_NONE;
-#endif /* NETINET */
+#endif
#if NETINET6
struct sockaddr_in6 hid6;
-#endif /* NETINET6 */
+#endif
*p = '\0';
#if NETINET6
memset(&hid6, '\0', sizeof(hid6));
-#endif /* NETINET6 */
+#endif
#if NETINET
if (family == AF_INET &&
(hid = inet_addr(&host[1])) != INADDR_NONE)
@@ -2308,7 +2345,7 @@ makeconnection(host, port, mci, e, enough)
p[-1] = '.';
#if NAMED_BIND
_res.options = oldopts;
-#endif /* NAMED_BIND */
+#endif
}
*p = ']';
goto gothostent;
@@ -2332,20 +2369,67 @@ makeconnection(host, port, mci, e, enough)
/* contortion to get around SGI cc complaints */
{
p = &host[strlen(host) - 1];
- hp = sm_gethostbyname(host, family);
+#if DANE
+ if (tTd(16, 40))
+ sm_dprintf("makeconnection: tlsa_flags=%lX, host=%s\n",
+ tlsa_flags, host);
+ if (DANEMODE(tlsa_flags) == DANE_SECURE
+# if DNSSEC_TEST
+ || tTd(8, 120)
+# endif
+ )
+ {
+ DNS_REPLY_T *rr;
+ int err, herr;
+
+ rr = dns_lookup_int(host, C_IN, FAM2T_(family),
+ 0, 0, SM_RES_DNSSEC, 0, &err, &herr);
+
+ /*
+ ** Check for errors!
+ ** If no ad: turn off TLSA.
+ ** permail: use "normal" method?
+ ** tempfail: delay or use "normal" method?
+ */
+
+ if (rr != NULL && rr->dns_r_h.ad == 1)
+ {
+ *ptlsa_flags |= DANE_SECURE;
+ if ((TLSAFLTEMP & *ptlsa_flags) != 0)
+ {
+ dns_free_data(rr);
+ rr = NULL;
+ return EX_TEMPFAIL;
+ }
+ hp = dns2he(rr, family);
+#if NETINET6
+ hs = hp;
+#endif
+ }
+
+ /* other possible "tempfails"? */
+ if (rr == NULL && h_errno == TRY_AGAIN)
+ goto gothostent;
+
+ dns_free_data(rr);
+ rr = NULL;
+ }
+#endif
+ if (hp == NULL)
+ hp = sm_gethostbyname(host, family);
if (hp == NULL && *p == '.')
{
#if NAMED_BIND
int oldopts = _res.options;
_res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
-#endif /* NAMED_BIND */
+#endif
*p = '\0';
hp = sm_gethostbyname(host, family);
*p = '.';
#if NAMED_BIND
_res.options = oldopts;
-#endif /* NAMED_BIND */
+#endif
}
}
gothostent:
@@ -2374,10 +2458,10 @@ gothostent:
# if _FFR_GETHBN_ExFILE
# ifdef EMFILE
errno == EMFILE ||
-# endif /* EMFILE */
+# endif
# ifdef ENFILE
errno == ENFILE ||
-# endif /* ENFILE */
+# endif
# endif /* _FFR_GETHBN_ExFILE */
h_errno == TRY_AGAIN ||
(errno == ECONNREFUSED && UseNameServer))
@@ -2444,6 +2528,24 @@ gothostent:
addrno = 1;
}
+#if _FFR_TESTS
+ /*
+ ** Hack for testing.
+ ** Hardcoded:
+ ** 10.1.1.12: see meta1.tns XREF IP address
+ ** 8754: see common.sh XREF SNKPORT2
+ */
+
+ if (tTd(77, 101) && hp->h_addrtype == AF_INET &&
+ addr.sin.sin_addr.s_addr == inet_addr("10.1.1.12"))
+ {
+ addr.sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ port = htons(8754);
+ sm_dprintf("hack host=%s addr=[%s].%d\n", host,
+ anynet_ntoa(&addr), ntohs(port));
+ }
+#endif
+
/*
** Determine the port number.
*/
@@ -2510,10 +2612,7 @@ gothostent:
syserr("Can't connect to address family %d", addr.sa.sa_family);
mci_setstat(mci, EX_NOHOST, "5.1.2", NULL);
errno = EINVAL;
-#if NETINET6
- if (hp != NULL)
- freehostent(hp);
-#endif /* NETINET6 */
+ FREEHOSTENT(hp, hs);
return EX_NOHOST;
}
@@ -2525,14 +2624,34 @@ gothostent:
/* if too many connections, don't bother trying */
if (!xla_noqueue_ok(host))
{
-# if NETINET6
- if (hp != NULL)
- freehostent(hp);
-# endif /* NETINET6 */
+ FREEHOSTENT(hp, hs);
return EX_TEMPFAIL;
}
#endif /* XLA */
+#if _FFR_OCC
+# define OCC_CLOSE occ_close(e, mci, host, &addr)
+ /* HACK!!!! just to see if this can work at all... */
+ if (occ_exceeded(e, mci, host, &addr))
+ {
+ FREEHOSTENT(hp, hs);
+ sm_syslog(LOG_DEBUG, e->e_id,
+ "stat=occ_exceeded, host=%s, addr=%s",
+ host, anynet_ntoa(&addr));
+
+ /*
+ ** to get a more specific stat= message set errno
+ ** or make up one in sm, see sm_errstring()
+ */
+
+ mci_setstat(mci, EX_TEMPFAIL, "4.4.5", "450 occ_exceeded"); /* check D.S.N */
+ errno = EAGAIN;
+ return EX_TEMPFAIL;
+ }
+#else /* _FFR_OCC */
+# define OCC_CLOSE
+#endif /* _FFR_OCC */
+
for (;;)
{
if (tTd(16, 1))
@@ -2561,13 +2680,11 @@ gothostent:
syserr("makeconnection: cannot create socket");
#if XLA
xla_host_end(host);
-#endif /* XLA */
+#endif
mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
-#if NETINET6
- if (hp != NULL)
- freehostent(hp);
-#endif /* NETINET6 */
+ FREEHOSTENT(hp, hs);
errno = save_errno;
+ OCC_CLOSE;
return EX_TEMPFAIL;
}
@@ -2639,11 +2756,9 @@ gothostent:
errno = save_errno;
syserr("makeconnection: cannot bind socket [%s]",
anynet_ntoa(&clt_addr));
-#if NETINET6
- if (hp != NULL)
- freehostent(hp);
-#endif /* NETINET6 */
+ FREEHOSTENT(hp, hs);
errno = save_errno;
+ OCC_CLOSE;
return EX_TEMPFAIL;
}
}
@@ -2672,6 +2787,11 @@ gothostent:
case AF_INET:
addr.sin.sin_addr.s_addr = ConnectOnlyTo.sin.sin_addr.s_addr;
addr.sa.sa_family = ConnectOnlyTo.sa.sa_family;
+ if (ConnectOnlyTo.sin.sin_port != 0)
+ {
+ port = ConnectOnlyTo.sin.sin_port;
+ addr.sin.sin_port = port;
+ }
break;
#endif /* NETINET */
@@ -2680,11 +2800,18 @@ gothostent:
memmove(&addr.sin6.sin6_addr,
&ConnectOnlyTo.sin6.sin6_addr,
IN6ADDRSZ);
+ if (ConnectOnlyTo.sin6.sin6_port != 0)
+ {
+ port = ConnectOnlyTo.sin6.sin6_port;
+ addr.sin6.sin6_port = port;
+ }
break;
#endif /* NETINET6 */
}
if (tTd(16, 1))
- sm_dprintf("Connecting to [%s]...\n", anynet_ntoa(&addr));
+ sm_dprintf("Connecting to [%s].%d...\n",
+ anynet_ntoa(&addr), ntohs(port));
+
i = connect(s, (struct sockaddr *) &addr, addrlen);
save_errno = errno;
if (ev != NULL)
@@ -2712,8 +2839,9 @@ gothostent:
if (LogLevel > 13)
sm_syslog(LOG_INFO, e->e_id,
- "makeconnection (%s [%s]) failed: %s",
- host, anynet_ntoa(&addr),
+ "makeconnection (%s [%s].%d (%d)) failed: %s",
+ host, anynet_ntoa(&addr), ntohs(port),
+ (int) addr.sa.sa_family,
sm_errstring(save_errno));
#if NETINET6
@@ -2761,11 +2889,7 @@ nextaddr:
sm_errstring(save_errno));
v6found = true;
family = AF_INET;
- if (hp != NULL)
- {
- freehostent(hp);
- hp = NULL;
- }
+ FREEHOSTENT(hp, hs);
goto v4retry;
}
v6tempfail:
@@ -2774,30 +2898,22 @@ nextaddr:
#if NETINET6
/* Don't clobber an already saved errno from v4retry */
if (errno > 0)
-#endif /* NETINET6 */
+#endif
save_errno = errno;
if (tTd(16, 1))
sm_dprintf("Connect failed (%s)\n",
sm_errstring(save_errno));
#if XLA
xla_host_end(host);
-#endif /* XLA */
+#endif
mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL);
-#if NETINET6
- if (hp != NULL)
- freehostent(hp);
-#endif /* NETINET6 */
+ FREEHOSTENT(hp, hs);
errno = save_errno;
+ OCC_CLOSE;
return EX_TEMPFAIL;
}
-#if NETINET6
- if (hp != NULL)
- {
- freehostent(hp);
- hp = NULL;
- }
-#endif /* NETINET6 */
+ FREEHOSTENT(hp, hs);
/* connection ok, put it into canonical form */
mci->mci_out = NULL;
@@ -2816,6 +2932,7 @@ nextaddr:
(void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT);
(void) close(s);
errno = save_errno;
+ OCC_CLOSE;
return EX_TEMPFAIL;
}
sm_io_automode(mci->mci_out, mci->mci_in);
@@ -2843,14 +2960,25 @@ nextaddr:
if (getsockname(s, &addr.sa, &len) == 0)
{
char *name;
- char family[5];
- macdefine(&BlankEnvelope.e_macro, A_TEMP,
- macid("{if_addr_out}"), anynet_ntoa(&addr));
- (void) sm_snprintf(family, sizeof(family), "%d",
- addr.sa.sa_family);
- macdefine(&BlankEnvelope.e_macro, A_TEMP,
- macid("{if_family_out}"), family);
+ if (!isloopback(addr))
+ {
+ char familystr[5];
+
+ macdefine(&BlankEnvelope.e_macro, A_TEMP,
+ macid("{if_addr_out}"), anynet_ntoa(&addr));
+ (void) sm_snprintf(familystr, sizeof(familystr), "%d",
+ addr.sa.sa_family);
+ macdefine(&BlankEnvelope.e_macro, A_TEMP,
+ macid("{if_family_out}"), familystr);
+ }
+ else
+ {
+ macdefine(&BlankEnvelope.e_macro, A_PERM,
+ macid("{if_addr_out}"), NULL);
+ macdefine(&BlankEnvelope.e_macro, A_PERM,
+ macid("{if_family_out}"), NULL);
+ }
name = hostnamebyanyaddr(&addr);
macdefine(&BlankEnvelope.e_macro, A_TEMP,
@@ -2880,7 +3008,7 @@ nextaddr:
/* Use the configured HeloName as appropriate */
if (HeloName != NULL && HeloName[0] != '\0')
{
- SM_FREE_CLR(mci->mci_heloname);
+ SM_FREE(mci->mci_heloname);
mci->mci_heloname = newstr(HeloName);
}
@@ -3041,7 +3169,7 @@ shutdown_daemon()
closecontrolsocket(true);
#if XLA
xla_all_end();
-#endif /* XLA */
+#endif
for (i = 0; i < NDaemons; i++)
{
@@ -3133,7 +3261,7 @@ restart_daemon()
closecontrolsocket(true);
#if SM_CONF_SHM
cleanup_shm(DaemonPid == getpid());
-#endif /* SM_CONF_SHM */
+#endif
/* close locked pid file */
close_sendmail_pid();
@@ -3175,7 +3303,7 @@ restart_daemon()
SM_NOOP_SIGNAL(SIGTERM, ignore);
#ifdef SIGUSR1
SM_NOOP_SIGNAL(SIGUSR1, ousr1);
-#endif /* SIGUSR1 */
+#endif
/* Turn back on signals */
sm_allsignals(false);
@@ -3192,7 +3320,7 @@ restart_daemon()
#ifdef SIGUSR1
/* For debugging finis() */
(void) sm_signal(SIGUSR1, ousr1);
-#endif /* SIGUSR1 */
+#endif
errno = save_errno;
if (LogLevel > 0)
@@ -3285,7 +3413,7 @@ myhostname(hostbuf, size)
*/
if (strchr(hostbuf, '.') == NULL &&
- !getcanonname(hostbuf, size, true, NULL))
+ getcanonname(hostbuf, size, true, NULL) == HOST_NOTFOUND)
{
sm_syslog(LocalDaemon ? LOG_WARNING : LOG_CRIT, NOQID,
"My unqualified host name (%s) unknown; sleeping for retry",
@@ -3293,7 +3421,7 @@ myhostname(hostbuf, size)
message("My unqualified host name (%s) unknown; sleeping for retry",
hostbuf);
(void) sleep(60);
- if (!getcanonname(hostbuf, size, true, NULL))
+ if (getcanonname(hostbuf, size, true, NULL) == HOST_NOTFOUND)
{
sm_syslog(LocalDaemon ? LOG_WARNING : LOG_ALERT, NOQID,
"unable to qualify my own domain name (%s) -- using short name",
@@ -3325,7 +3453,7 @@ addrcmp(hp, ha, sa)
{
#if NETINET6
unsigned char *a;
-#endif /* NETINET6 */
+#endif
switch (sa->sa.sa_family)
{
@@ -3334,7 +3462,7 @@ addrcmp(hp, ha, sa)
if (hp->h_addrtype == AF_INET)
return memcmp(ha, (char *) &sa->sin.sin_addr, INADDRSZ);
break;
-#endif /* NETINET */
+#endif
#if NETINET6
case AF_INET6:
@@ -3398,10 +3526,10 @@ getauthinfo(fd, may_be_forged)
register struct servent *sp;
# if NETINET
static unsigned short port4 = 0;
-# endif /* NETINET */
+# endif
# if NETINET6
static unsigned short port6 = 0;
-# endif /* NETINET6 */
+# endif
#endif /* ! NO_GETSERVBYNAME */
volatile int s;
int i = 0;
@@ -3488,10 +3616,7 @@ getauthinfo(fd, may_be_forged)
break;
}
}
-#if NETINET6
- freehostent(hp);
- hp = NULL;
-#endif /* NETINET6 */
+ FREEHOSTENT(hp, NULL);
}
}
@@ -3667,7 +3792,7 @@ getauthinfo(fd, may_be_forged)
goto noident;
}
p += 6;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p++ != ':')
{
@@ -3676,7 +3801,7 @@ getauthinfo(fd, may_be_forged)
}
/* p now points to the OSTYPE field */
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
ostype = p;
p = strchr(p, ':');
@@ -3748,7 +3873,7 @@ postident:
#if IP_SRCROUTE
# ifndef GET_IPOPT_DST
# define GET_IPOPT_DST(dst) (dst)
-# endif /* ! GET_IPOPT_DST */
+# endif
/*
** Extract IP source routing information.
**
@@ -3922,17 +4047,17 @@ host_map_lookup(map, name, av, statp)
register struct hostent *hp;
#if NETINET
struct in_addr in_addr;
-#endif /* NETINET */
+#endif
#if NETINET6
struct in6_addr in6_addr;
-#endif /* NETINET6 */
+#endif
char *cp, *ans = NULL;
register STAB *s;
time_t now;
#if NAMED_BIND
time_t SM_NONVOLATILE retrans = 0;
int SM_NONVOLATILE retry = 0;
-#endif /* NAMED_BIND */
+#endif
char hbuf[MAXNAME + 1];
/*
@@ -3970,6 +4095,10 @@ host_map_lookup(map, name, av, statp)
s->s_namecanon.nc_herrno);
return NULL;
}
+ if (bitset(NCF_SECURE, s->s_namecanon.nc_flags))
+ map->map_mflags |= MF_SECURE;
+ else
+ map->map_mflags &= ~MF_SECURE;
if (bitset(MF_MATCHONLY, map->map_mflags))
cp = map_rewrite(map, name, strlen(name), NULL);
else
@@ -4021,15 +4150,28 @@ host_map_lookup(map, name, av, statp)
s->s_namecanon.nc_exp = now + SM_DEFAULT_TTL;
if (*name != '[')
{
- int ttl;
+ int ttl, r;
(void) sm_strlcpy(hbuf, name, sizeof(hbuf));
- if (getcanonname(hbuf, sizeof(hbuf) - 1, !HasWildcardMX, &ttl))
+
+ r = getcanonname(hbuf, sizeof(hbuf) - 1, !HasWildcardMX, &ttl);
+ if (r != HOST_NOTFOUND)
{
ans = hbuf;
if (ttl > 0)
s->s_namecanon.nc_exp = now + SM_MIN(ttl,
SM_DEFAULT_TTL);
+
+ if (HOST_SECURE == r)
+ {
+ s->s_namecanon.nc_flags |= NCF_SECURE;
+ map->map_mflags |= MF_SECURE;
+ }
+ else
+ {
+ s->s_namecanon.nc_flags &= ~NCF_SECURE;
+ map->map_mflags &= ~MF_SECURE;
+ }
}
}
else
@@ -4043,6 +4185,9 @@ host_map_lookup(map, name, av, statp)
*cp = '\0';
hp = NULL;
+
+ /* should this be considered secure? */
+ map->map_mflags &= ~MF_SECURE;
#if NETINET
if ((in_addr.s_addr = inet_addr(&name[1])) != INADDR_NONE)
hp = sm_gethostbyaddr((char *)&in_addr,
@@ -4069,8 +4214,7 @@ host_map_lookup(map, name, av, statp)
(void) sm_strlcpy(n, ans, sizeof(n));
ans = n;
}
- freehostent(hp);
- hp = NULL;
+ FREEHOSTENT(hp, NULL);
#endif /* NETINET6 */
}
}
@@ -4159,7 +4303,7 @@ host_map_init(map, args)
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -4210,7 +4354,7 @@ host_map_init(map, args)
map->map_retry = atoi(p);
break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -4284,7 +4428,7 @@ anynet_ntop(s6a, dst, dst_len)
**
** Returns:
** 1 if the address was valid
-** 0 if the address wasn't parseable
+** 0 if the address wasn't parsable
** -1 if error
*/
@@ -4313,7 +4457,7 @@ anynet_pton(family, src, dst)
# if NETLINK
# include <net/if_dl.h>
-# endif /* NETLINK */
+# endif
char *
anynet_ntoa(sap)
@@ -4345,7 +4489,7 @@ anynet_ntoa(sap)
# if NETINET
case AF_INET:
return (char *) inet_ntoa(sap->sin.sin_addr);
-# endif /* NETINET */
+# endif
# if NETINET6
case AF_INET6:
@@ -4400,7 +4544,7 @@ hostnamebyanyaddr(sap)
register struct hostent *hp;
# if NAMED_BIND
int saveretry;
-# endif /* NAMED_BIND */
+# endif
# if NETINET6
struct in6_addr in6_addr;
# endif /* NETINET6 */
@@ -4451,7 +4595,7 @@ hostnamebyanyaddr(sap)
# if NAMED_BIND
_res.retry = saveretry;
-# endif /* NAMED_BIND */
+# endif
# if NETINET || NETINET6
if (hp != NULL && hp->h_name[0] != '['
@@ -4460,7 +4604,7 @@ hostnamebyanyaddr(sap)
# endif /* NETINET6 */
# if NETINET
&& inet_addr(hp->h_name) == INADDR_NONE
-# endif /* NETINET */
+# endif
)
{
char *name;
@@ -4475,24 +4619,18 @@ hostnamebyanyaddr(sap)
(void) sm_strlcpy(n, name, sizeof(n));
name = n;
}
- freehostent(hp);
+ FREEHOSTENT(hp, NULL);
# endif /* NETINET6 */
return name;
}
# endif /* NETINET || NETINET6 */
-# if NETINET6
- if (hp != NULL)
- {
- freehostent(hp);
- hp = NULL;
- }
-# endif /* NETINET6 */
+ FREEHOSTENT(hp, NULL);
# if NETUNIX
if (sap->sa.sa_family == AF_UNIX && sap->sunix.sun_path[0] == '\0')
return "localhost";
-# endif /* NETUNIX */
+# endif
{
static char buf[203];
diff --git a/contrib/sendmail/src/daemon.h b/contrib/sendmail/src/daemon.h
index 649b4d5279a7..fa4e681a10b8 100644
--- a/contrib/sendmail/src/daemon.h
+++ b/contrib/sendmail/src/daemon.h
@@ -43,10 +43,10 @@ struct daemon
#if MILTER
char *d_inputfilterlist;
struct milter *d_inputfilters[MAXFILTERS];
-#endif /* MILTER */
+#endif
#if _FFR_SS_PER_DAEMON
int d_supersafe;
-#endif /* _FFR_SS_PER_DAEMON */
+#endif
};
typedef struct daemon DAEMON_T;
diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c
index 62d02b168b7f..ff4b21487700 100644
--- a/contrib/sendmail/src/deliver.c
+++ b/contrib/sendmail/src/deliver.c
@@ -18,15 +18,16 @@ SM_RCSID("@(#)$Id: deliver.c,v 8.1030 2013-11-22 20:51:55 ca Exp $")
#if HASSETUSERCONTEXT
# include <login_cap.h>
-#endif /* HASSETUSERCONTEXT */
+#endif
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
#if STARTTLS || SASL
# include "sfsasl.h"
-#endif /* STARTTLS || SASL */
+# include "tls.h"
+#endif
static int deliver __P((ENVELOPE *, ADDRESS *));
static void dup_queue_file __P((ENVELOPE *, ENVELOPE *, int));
@@ -38,12 +39,20 @@ static int coloncmp __P((const char *, const char *));
#if STARTTLS
# include <openssl/err.h>
+# if DANE
+static int starttls __P((MAILER *, MCI *, ENVELOPE *, dane_vrfy_ctx_P));
+# else
static int starttls __P((MAILER *, MCI *, ENVELOPE *));
+# endif
static int endtlsclt __P((MCI *));
#endif /* STARTTLS */
-# if STARTTLS || SASL
+#if STARTTLS || SASL
static bool iscltflgset __P((ENVELOPE *, int));
-# endif /* STARTTLS || SASL */
+#endif
+
+#if _FFR_OCC
+# include <ratectrl.h>
+#endif
/*
** SENDALL -- actually send all the messages.
@@ -529,9 +538,9 @@ sendall(e, mode)
#if !HASFLOCK
msync = false;
-#else /* !HASFLOCK */
+#else
msync = mode == SM_FORK;
-#endif /* !HASFLOCK */
+#endif
for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
queueup(ee, WILL_BE_QUEUED(mode), msync);
@@ -573,7 +582,7 @@ sendall(e, mode)
case SM_DEFER:
#if HASFLOCK
queueonly:
-#endif /* HASFLOCK */
+#endif
if (e->e_nrcpts > 0)
e->e_flags |= EF_INQUEUE;
(void) dropenvelope(e, splitenv != NULL, true);
@@ -672,7 +681,7 @@ sendall(e, mode)
#if USE_DOUBLE_FORK
/* catch intermediate zombie */
(void) waitfor(pid);
-#endif /* USE_DOUBLE_FORK */
+#endif
return;
}
@@ -719,9 +728,9 @@ sendall(e, mode)
syserr("deliver: fork 2");
#if HASFLOCK
e->e_flags |= EF_INQUEUE;
-#else /* HASFLOCK */
+#else
e->e_id = NULL;
-#endif /* HASFLOCK */
+#endif
finis(true, true, ExitStat);
}
@@ -928,7 +937,7 @@ sendenvelope(e, mode)
#if XDEBUG
checkfd012("end of sendenvelope");
-#endif /* XDEBUG */
+#endif
}
#if REQUIRES_DIR_FSYNC
@@ -1073,7 +1082,7 @@ dup_queue_file(e, ee, type)
#ifndef FORK
# define FORK fork
-#endif /* ! FORK */
+#endif
#define DOFORK(fORKfN) \
{\
@@ -1231,8 +1240,7 @@ should_try_fbsh(e, tried_fallbacksmarthost, hostbuf, hbsz, status)
** user on the head of the list. It is clever about mailers
** that don't handle multiple users. It is NOT guaranteed
** that it will deliver to all these addresses however -- so
-** deliver should be called once for each address on the
-** list.
+** deliver should be called once for each address on the list.
** Deliver tries to be as opportunistic as possible about piggybacking
** messages. Some definitions to make understanding easier follow below.
** Piggybacking occurs when an existing connection to a mail host can
@@ -1299,7 +1307,7 @@ deliver(e, firstto)
ADDRESS *volatile ctladdr;
#if HASSETUSERCONTEXT
ADDRESS *volatile contextaddr = NULL;
-#endif /* HASSETUSERCONTEXT */
+#endif
register MCI *volatile mci;
register ADDRESS *SM_NONVOLATILE to = firstto;
volatile bool clever = false; /* running user smtp to this mailer */
@@ -1315,13 +1323,43 @@ deliver(e, firstto)
SM_NONVOLATILE time_t enough = 0;
#if NETUNIX
char *SM_NONVOLATILE mux_path = NULL; /* path to UNIX domain socket */
-#endif /* NETUNIX */
+#endif
time_t xstart;
bool suidwarn;
bool anyok; /* at least one address was OK */
SM_NONVOLATILE bool goodmxfound = false; /* at least one MX was OK */
bool ovr;
bool quarantine;
+#if STARTTLS
+ /* 0: try TLS, 1: try without TLS again, >1: don't try again */
+ int tlsstate;
+# if DANE
+ dane_vrfy_ctx_T dane_vrfy_ctx;
+ STAB *ste;
+# endif
+#endif
+#if STARTTLS || SASL
+ int dotpos;
+
+# define RM_TRAIL_DOT(name) \
+ do { \
+ dotpos = strlen(name) - 1; \
+ if (dotpos >= 0) \
+ { \
+ if (name[dotpos] == '.') \
+ name[dotpos] = '\0'; \
+ else \
+ dotpos = -1; \
+ } \
+ } while (0)
+
+# define FIX_TRAIL_DOT(name) \
+ do { \
+ if (dotpos >= 0) \
+ name[dotpos] = '.'; \
+ } while (0)
+
+#endif
int strsize;
int rcptcount;
int ret;
@@ -1349,6 +1387,13 @@ deliver(e, firstto)
e->e_statmsg = NULL;
SmtpError[0] = '\0';
xstart = curtime();
+#if STARTTLS
+ tlsstate = 0;
+# if DANE
+ memset(&dane_vrfy_ctx, '\0', sizeof(dane_vrfy_ctx));
+ ste = NULL;
+# endif
+#endif
if (tTd(10, 1))
sm_dprintf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
@@ -1495,7 +1540,8 @@ deliver(e, firstto)
ctladdr = NULL;
if (firstto->q_signature == NULL)
firstto->q_signature = hostsignature(firstto->q_mailer,
- firstto->q_host);
+ firstto->q_host,
+ firstto->q_flags & QSECURE);
firstsig = firstto->q_signature;
for (; to != NULL; to = to->q_next)
@@ -1519,7 +1565,8 @@ deliver(e, firstto)
if (to->q_signature == NULL) /* for safety */
to->q_signature = hostsignature(to->q_mailer,
- to->q_host);
+ to->q_host,
+ to->q_flags & QSECURE);
/*
** This is for coincidental and tailcoat piggybacking messages
@@ -1558,11 +1605,11 @@ deliver(e, firstto)
/* compute effective uid/gid when sending */
if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
-# if HASSETUSERCONTEXT
+#if HASSETUSERCONTEXT
contextaddr = ctladdr = getctladdr(to);
-# else /* HASSETUSERCONTEXT */
+#else
ctladdr = getctladdr(to);
-# endif /* HASSETUSERCONTEXT */
+#endif
if (tTd(10, 2))
{
@@ -1816,7 +1863,7 @@ deliver(e, firstto)
strsize = TOBUFSIZE;
if (strsize > tobufsize)
{
- SM_FREE_CLR(tobuf);
+ SM_FREE(tobuf);
tobuf = sm_pmalloc_x(strsize);
tobufsize = strsize;
}
@@ -1863,7 +1910,7 @@ deliver(e, firstto)
#if NAMED_BIND
if (ConfigLevel < 2)
_res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
-#endif /* NAMED_BIND */
+#endif
if (tTd(11, 1))
{
@@ -1965,17 +2012,18 @@ deliver(e, firstto)
goto give_up;
}
-# if NETUNIX
+#if NETUNIX
if (strcmp(pv[0], "FILE") == 0)
{
curhost = CurHostName = "localhost";
mux_path = pv[1];
}
else
-# endif /* NETUNIX */
+#endif /* NETUNIX */
{
CurHostName = pv[1];
- curhost = hostsignature(m, pv[1]);
+ /* XXX ??? */
+ curhost = hostsignature(m, pv[1], firstto->q_flags & QSECURE);
}
if (curhost == NULL || curhost[0] == '\0')
@@ -1992,24 +2040,24 @@ deliver(e, firstto)
goto give_up;
}
if (pv[2] != NULL
-# if NETUNIX
+#if NETUNIX
&& mux_path == NULL
-# endif /* NETUNIX */
+#endif
)
{
port = htons((unsigned short) atoi(pv[2]));
if (port == 0)
{
-# ifdef NO_GETSERVBYNAME
+#ifdef NO_GETSERVBYNAME
syserr("Invalid port number: %s", pv[2]);
-# else /* NO_GETSERVBYNAME */
+#else /* NO_GETSERVBYNAME */
struct servent *sp = getservbyname(pv[2], "tcp");
if (sp == NULL)
syserr("Service %s unknown", pv[2]);
else
port = sp->s_port;
-# endif /* NO_GETSERVBYNAME */
+#endif /* NO_GETSERVBYNAME */
}
}
@@ -2023,8 +2071,13 @@ tryhost:
char *endp;
static char hostbuf[MAXNAME + 1];
bool tried_fallbacksmarthost = false;
+#if DANE
+ unsigned long tlsa_flags;
-# if NETINET6
+ ste = NULL;
+ tlsa_flags = 0;
+#endif
+#if NETINET6
if (*mxhosts[hostnum] == '[')
{
endp = strchr(mxhosts[hostnum] + 1, ']');
@@ -2033,9 +2086,9 @@ tryhost:
}
else
endp = strpbrk(mxhosts[hostnum], ":,");
-# else /* NETINET6 */
+#else /* NETINET6 */
endp = strpbrk(mxhosts[hostnum], ":,");
-# endif /* NETINET6 */
+#endif /* NETINET6 */
if (endp != NULL)
{
sep = *endp;
@@ -2073,6 +2126,9 @@ tryhost:
hostnum++;
if (endp != NULL)
*endp = sep;
+#if STARTTLS
+ tlsstate = 0;
+#endif
one_last_try:
/* see if we already know that this host is fried */
@@ -2100,6 +2156,23 @@ tryhost:
break;
}
mci->mci_mailer = m;
+#if DANE
+ tlsa_flags = 0;
+ if (CHK_DANE(Dane))
+ (void) GETTLSA(hostbuf, &ste, m->m_port);
+
+ /* XXX: check expiration! */
+ if (ste != NULL && TLSA_RR_TEMPFAIL(ste->s_tlsa))
+ {
+ if (tTd(11, 1))
+ sm_dprintf("skip: host=%s, TLSA_RR_lookup=%d\n"
+ , hostbuf
+ , ste->s_tlsa->dane_tlsa_dnsrc);
+
+ tlsa_flags |= TLSAFLTEMP;
+ }
+#endif /* DANE */
+
if (mci->mci_exitstat != EX_OK)
{
if (mci->mci_exitstat == EX_TEMPFAIL)
@@ -2125,7 +2198,7 @@ tryhost:
sm_setproctitle(true, e, "%s %s: %s",
qid_printname(e),
hostbuf, "user open");
-# if NETUNIX
+#if NETUNIX
if (mux_path != NULL)
{
message("Connecting to %s via %s...",
@@ -2133,7 +2206,7 @@ tryhost:
i = makeconnection_ds((char *) mux_path, mci);
}
else
-# endif /* NETUNIX */
+#endif /* NETUNIX */
{
if (port == 0)
message("Connecting to %s via %s...",
@@ -2142,17 +2215,45 @@ tryhost:
message("Connecting to %s port %d via %s...",
hostbuf, ntohs(port),
m->m_name);
+#if DANE
+ tlsa_flags |= (ste != NULL) ? Dane : DANE_NEVER;
+ dane_vrfy_ctx.dane_vrfy_chk = tlsa_flags;
+ dane_vrfy_ctx.dane_vrfy_port = m->m_port;
+ if (tTd(11, 11))
+ sm_dprintf("makeconnection: before: chk=%d, mode=%lX\n", dane_vrfy_ctx.dane_vrfy_chk, tlsa_flags);
+#endif
i = makeconnection(hostbuf, port, mci, e,
- enough);
+ enough
+#if DANE
+ , &tlsa_flags
+#endif
+ );
+#if DANE
+ if (tTd(11, 11))
+ sm_dprintf("makeconnection: after: chk=%d, mode=%lX\n", dane_vrfy_ctx.dane_vrfy_chk, tlsa_flags);
+ if (dane_vrfy_ctx.dane_vrfy_chk != DANE_ALWAYS)
+ dane_vrfy_ctx.dane_vrfy_chk = DANEMODE(tlsa_flags);
+ if (EX_TEMPFAIL == i &&
+ ((tlsa_flags & (TLSAFLTEMP|DANE_SECURE)) ==
+ (TLSAFLTEMP|DANE_SECURE)))
+ {
+ (void) sm_strlcpy(SmtpError,
+ " for TLSA RR",
+ sizeof(SmtpError));
+# if NAMED_BIND
+ SM_SET_H_ERRNO(TRY_AGAIN);
+# endif
+ }
+#endif
}
mci->mci_errno = errno;
mci->mci_lastuse = curtime();
mci->mci_deliveries = 0;
mci->mci_exitstat = i;
mci_clr_extensions(mci);
-# if NAMED_BIND
+#if NAMED_BIND
mci->mci_herrno = h_errno;
-# endif /* NAMED_BIND */
+#endif
/*
** Have we tried long enough to get a connection?
@@ -2163,11 +2264,11 @@ tryhost:
if (enough > 0 && mci->mci_lastuse >= enough)
{
int h;
-# if NAMED_BIND
+#if NAMED_BIND
extern int NumFallbackMXHosts;
-# else /* NAMED_BIND */
+#else
const int NumFallbackMXHosts = 0;
-# endif /* NAMED_BIND */
+#endif
if (hostnum < nummxhosts && LogLevel > 9)
sm_syslog(LOG_INFO, e->e_id,
@@ -2267,7 +2368,7 @@ tryhost:
#if XDEBUG
checkfd012("before creating mail pipe");
-#endif /* XDEBUG */
+#endif
/* create a pipe to shove the mail through */
if (pipe(mpvect) < 0)
@@ -2333,7 +2434,7 @@ tryhost:
#if XDEBUG
checkfdopen(rpvect[0], "rpvect[0]");
checkfdopen(rpvect[1], "rpvect[1]");
-#endif /* XDEBUG */
+#endif
/*
** Actually fork the mailer process.
@@ -2399,14 +2500,14 @@ tryhost:
(void) sm_signal(SIGHUP, SIG_IGN);
(void) sm_signal(SIGINT, SIG_IGN);
(void) sm_signal(SIGTERM, SIG_DFL);
-# ifdef SIGUSR1
+#ifdef SIGUSR1
(void) sm_signal(SIGUSR1, sm_signal_noop);
-# endif /* SIGUSR1 */
+#endif
if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
stb.st_mode = 0;
-# if HASSETUSERCONTEXT
+#if HASSETUSERCONTEXT
/*
** Set user resources.
*/
@@ -2421,15 +2522,15 @@ tryhost:
else
pwd = sm_getpwnam(contextaddr->q_user);
sucflags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY;
-#ifdef LOGIN_SETCPUMASK
+# ifdef LOGIN_SETCPUMASK
sucflags |= LOGIN_SETCPUMASK;
-#endif /* LOGIN_SETCPUMASK */
-#ifdef LOGIN_SETLOGINCLASS
+# endif
+# ifdef LOGIN_SETLOGINCLASS
sucflags |= LOGIN_SETLOGINCLASS;
-#endif /* LOGIN_SETLOGINCLASS */
-#ifdef LOGIN_SETMAC
+# endif
+# ifdef LOGIN_SETMAC
sucflags |= LOGIN_SETMAC;
-#endif /* LOGIN_SETMAC */
+# endif
if (pwd != NULL &&
setusercontext(NULL, pwd, pwd->pw_uid,
sucflags) == -1 &&
@@ -2439,7 +2540,7 @@ tryhost:
exit(EX_TEMPFAIL);
}
}
-# endif /* HASSETUSERCONTEXT */
+#endif /* HASSETUSERCONTEXT */
#if HASNICE
/* tweak niceness */
@@ -2579,19 +2680,19 @@ tryhost:
if (RealUid != 0 && RealUid != getuid())
{
-# if MAILER_SETUID_METHOD == USE_SETEUID
-# if HASSETREUID
+#if MAILER_SETUID_METHOD == USE_SETEUID
+# if HASSETREUID
if (setreuid(RealUid, geteuid()) < 0)
{
syserr("openmailer: setreuid(%d, %d) failed",
(int) RealUid, (int) geteuid());
exit(EX_OSERR);
}
-# endif /* HASSETREUID */
-# endif /* MAILER_SETUID_METHOD == USE_SETEUID */
-# if MAILER_SETUID_METHOD == USE_SETREUID
+# endif /* HASSETREUID */
+#endif /* MAILER_SETUID_METHOD == USE_SETEUID */
+#if MAILER_SETUID_METHOD == USE_SETREUID
new_ruid = RealUid;
-# endif /* MAILER_SETUID_METHOD == USE_SETREUID */
+#endif
}
}
else if (bitset(S_ISUID, stb.st_mode))
@@ -2603,7 +2704,7 @@ tryhost:
else
new_ruid = DefUid;
-# if _FFR_USE_SETLOGIN
+#if _FFR_USE_SETLOGIN
/* run disconnected from terminal and set login name */
if (setsid() >= 0 &&
ctladdr != NULL && ctladdr->q_uid != 0 &&
@@ -2616,7 +2717,7 @@ tryhost:
(void) setlogin(pwd->pw_name);
endpwent();
}
-# endif /* _FFR_USE_SETLOGIN */
+#endif /* _FFR_USE_SETLOGIN */
if (new_euid != NO_UID)
{
@@ -2629,30 +2730,30 @@ tryhost:
}
vendor_set_uid(new_euid);
-# if MAILER_SETUID_METHOD == USE_SETEUID
+#if MAILER_SETUID_METHOD == USE_SETEUID
if (seteuid(new_euid) < 0 && suidwarn)
{
syserr("openmailer: seteuid(%ld) failed",
(long) new_euid);
exit(EX_TEMPFAIL);
}
-# endif /* MAILER_SETUID_METHOD == USE_SETEUID */
-# if MAILER_SETUID_METHOD == USE_SETREUID
+#endif /* MAILER_SETUID_METHOD == USE_SETEUID */
+#if MAILER_SETUID_METHOD == USE_SETREUID
if (setreuid(new_ruid, new_euid) < 0 && suidwarn)
{
syserr("openmailer: setreuid(%ld, %ld) failed",
(long) new_ruid, (long) new_euid);
exit(EX_TEMPFAIL);
}
-# endif /* MAILER_SETUID_METHOD == USE_SETREUID */
-# if MAILER_SETUID_METHOD == USE_SETUID
+#endif /* MAILER_SETUID_METHOD == USE_SETREUID */
+#if MAILER_SETUID_METHOD == USE_SETUID
if (new_euid != geteuid() && setuid(new_euid) < 0 && suidwarn)
{
syserr("openmailer: setuid(%ld) failed",
(long) new_euid);
exit(EX_TEMPFAIL);
}
-# endif /* MAILER_SETUID_METHOD == USE_SETUID */
+#endif /* MAILER_SETUID_METHOD == USE_SETUID */
}
else if (new_ruid != NO_UID)
{
@@ -2742,10 +2843,10 @@ tryhost:
/* arrange for all the files to be closed */
sm_close_on_exec(STDERR_FILENO + 1, DtableSize);
-# if !_FFR_USE_SETLOGIN
+#if !_FFR_USE_SETLOGIN
/* run disconnected from terminal */
(void) setsid();
-# endif /* !_FFR_USE_SETLOGIN */
+#endif
/* try to execute the mailer */
(void) execve(m->m_mailer, (ARGV_T) pv,
@@ -2835,35 +2936,27 @@ tryhost:
mci->mci_flags |= MCIF_7BIT;
if (clever && mci->mci_state != MCIS_CLOSED)
{
-# if STARTTLS || SASL
- int dotpos;
+#if STARTTLS || SASL
char *srvname;
extern SOCKADDR CurHostAddr;
-# endif /* STARTTLS || SASL */
-
-# if SASL
-# define DONE_AUTH(f) bitset(MCIF_AUTHACT, f)
-# endif /* SASL */
-# if STARTTLS
-# define DONE_STARTTLS(f) bitset(MCIF_TLSACT, f)
-# endif /* STARTTLS */
-# define ONLY_HELO(f) bitset(MCIF_ONLY_EHLO, f)
-# define SET_HELO(f) f |= MCIF_ONLY_EHLO
-# define CLR_HELO(f) f &= ~MCIF_ONLY_EHLO
-
-# if STARTTLS || SASL
+#endif /* STARTTLS || SASL */
+
+#if SASL
+# define DONE_AUTH(f) bitset(MCIF_AUTHACT, f)
+#endif
+#if STARTTLS
+# define DONE_STARTTLS(f) bitset(MCIF_TLSACT, f)
+#endif
+#define ONLY_HELO(f) bitset(MCIF_ONLY_EHLO, f)
+#define SET_HELO(f) f |= MCIF_ONLY_EHLO
+#define CLR_HELO(f) f &= ~MCIF_ONLY_EHLO
+
+#if STARTTLS || SASL
/* don't use CurHostName, it is changed in many places */
if (mci->mci_host != NULL)
{
srvname = mci->mci_host;
- dotpos = strlen(srvname) - 1;
- if (dotpos >= 0)
- {
- if (srvname[dotpos] == '.')
- srvname[dotpos] = '\0';
- else
- dotpos = -1;
- }
+ RM_TRAIL_DOT(srvname);
}
else if (mci->mci_mailer != NULL)
{
@@ -2901,18 +2994,38 @@ tryhost:
macid("{server_addr}"), "0");
}
+# if DANE
+ SM_FREE(dane_vrfy_ctx.dane_vrfy_host);
+ SM_FREE(dane_vrfy_ctx.dane_vrfy_sni);
+ dane_vrfy_ctx.dane_vrfy_fp[0] = '\0';
+ if (ste != NULL && ste->s_tlsa != NULL &&
+ ste->s_tlsa->dane_tlsa_sni != NULL)
+ dane_vrfy_ctx.dane_vrfy_sni = sm_strdup(ste->s_tlsa->dane_tlsa_sni);
+ dane_vrfy_ctx.dane_vrfy_host = sm_strdup(srvname);
+# endif
+
/* undo change of srvname (mci->mci_host) */
- if (dotpos >= 0)
- srvname[dotpos] = '.';
+ FIX_TRAIL_DOT(srvname);
reconnect: /* after switching to an encrypted connection */
-# endif /* STARTTLS || SASL */
+# if DANE
+ if (DONE_STARTTLS(mci->mci_flags))
+ {
+ /* use a "reset" function? */
+ SM_FREE(dane_vrfy_ctx.dane_vrfy_host);
+ SM_FREE(dane_vrfy_ctx.dane_vrfy_sni);
+ dane_vrfy_ctx.dane_vrfy_fp[0] = '\0';
+ dane_vrfy_ctx.dane_vrfy_res = 0;
+ }
+# endif
+
+#endif /* STARTTLS || SASL */
/* set the current connection information */
e->e_mci = mci;
-# if SASL
+#if SASL
mci->mci_saslcap = NULL;
-# endif /* SASL */
+#endif
smtpinit(m, mci, e, ONLY_HELO(mci->mci_flags));
CLR_HELO(mci->mci_flags);
@@ -2938,14 +3051,15 @@ reconnect: /* after switching to an encrypted connection */
e->e_status = "5.4.7";
usrerrenh(e->e_status,
"554 Message can't be delivered in time; %ld < %ld",
- e->e_deliver_by - (curtime() - e->e_ctime),
+ e->e_deliver_by - (long) (curtime() -
+ e->e_ctime),
mci->mci_min_by);
rcode = EX_UNAVAILABLE;
goto give_up;
}
}
-# if STARTTLS
+#if STARTTLS
/* first TLS then AUTH to provide a security layer */
if (mci->mci_state != MCIS_CLOSED &&
!DONE_STARTTLS(mci->mci_flags))
@@ -2960,6 +3074,8 @@ reconnect: /* after switching to an encrypted connection */
usetls = bitset(MCIF_TLS, mci->mci_flags);
if (usetls)
usetls = !iscltflgset(e, D_NOTLS);
+ if (usetls)
+ usetls = tlsstate == 0;
host = macvalue(macid("{server_name}"), e);
if (usetls)
@@ -2980,7 +3096,11 @@ reconnect: /* after switching to an encrypted connection */
if (usetls)
{
- if ((rcode = starttls(m, mci, e)) == EX_OK)
+ if ((rcode = starttls(m, mci, e
+# if DANE
+ , &dane_vrfy_ctx
+# endif
+ )) == EX_OK)
{
/* start again without STARTTLS */
mci->mci_flags |= MCIF_TLSACT;
@@ -3025,8 +3145,32 @@ reconnect: /* after switching to an encrypted connection */
}
}
else
+ {
+ p = tlsstate == 0 ? "NONE": "CLEAR";
+# if DANE
+ /*
+ ** TLSA found but STARTTLS not offered?
+ ** What is the best way to "fail"?
+ ** XXX: check expiration!
+ */
+
+ if (!bitset(MCIF_TLS, mci->mci_flags) &&
+ ste != NULL &&
+ ste->s_tlsa != NULL &&
+ ste->s_tlsa->dane_tlsa_n > 0)
+ {
+ if (LogLevel > 8)
+ sm_syslog(LOG_NOTICE, NOQID,
+ "STARTTLS=client, relay=%.100s, warning=DANE configured in DNS but no STARTTLS available",
+ host);
+ /* XXX include TLSA RR from DNS? */
+
+ p = "DANE_FAIL";
+ }
+# endif /* DANE */
macdefine(&e->e_macro, A_PERM,
- macid("{verify}"), "NONE");
+ macid("{verify}"), p);
+ }
olderrors = Errors;
QuickAbort = false;
SuprErrs = true;
@@ -3077,6 +3221,20 @@ reconnect: /* after switching to an encrypted connection */
}
mci->mci_flags &= ~MCIF_TLSACT;
(void) endmailer(mci, e, pv);
+
+ if ((TLSFallbacktoClear ||
+ SM_TLSI_IS(&(mci->mci_tlsi),
+ TLSI_FL_FB2CLR)) &&
+ !SM_TLSI_IS(&(mci->mci_tlsi),
+ TLSI_FL_NOFB2CLR)
+# if DANE
+ && dane_vrfy_ctx.dane_vrfy_chk !=
+ DANE_SECURE
+# endif
+ )
+ {
+ ++tlsstate;
+ }
}
else
{
@@ -3119,9 +3277,31 @@ reconnect: /* after switching to an encrypted connection */
mci_clr_extensions(mci);
goto reconnect;
}
+ if (tlsstate == 1)
+ {
+ if (tTd(11, 1))
+ {
+ sm_syslog(LOG_DEBUG, NOQID,
+ "STARTTLS=client, relay=%.100s, tlsstate=%d, status=trying_again",
+ mci->mci_host, tlsstate);
+ mci_dump(NULL, mci, true);
+ }
+ ++tlsstate;
+
+ /*
+ ** Fake the status so a new connection is
+ ** tried, otherwise the TLS error will
+ ** "persist" during this delivery attempt.
+ */
+
+ mci->mci_errno = 0;
+ rcode = EX_OK;
+ mci_setstat(mci, rcode, NULL, NULL);
+ goto one_last_try;
+}
}
-# endif /* STARTTLS */
-# if SASL
+#endif /* STARTTLS */
+#if SASL
/* if other server supports authentication let's authenticate */
if (mci->mci_state != MCIS_CLOSED &&
mci->mci_saslcap != NULL &&
@@ -3137,9 +3317,9 @@ reconnect: /* after switching to an encrypted connection */
result = sasl_getprop(mci->mci_conn, SASL_SSF,
# if SASL >= 20000
(const void **) &ssf);
-# else /* SASL >= 20000 */
+# else
(void **) &ssf);
-# endif /* SASL >= 20000 */
+# endif
/* XXX authid? */
if (LogLevel > 9)
@@ -3203,10 +3383,9 @@ reconnect: /* after switching to an encrypted connection */
sizeof(SmtpError));
}
}
-# endif /* SASL */
+#endif /* SASL */
}
-
do_transfer:
/* clear out per-message flags from connection structure */
mci->mci_flags &= ~(MCIF_CVT7TO8|MCIF_CVT8TO7);
@@ -3344,18 +3523,18 @@ do_transfer:
if (rcode == EX_OK)
{
register int i;
-# if PIPELINING
+#if PIPELINING
ADDRESS *volatile pchain;
-# endif /* PIPELINING */
+#endif
/* send the recipient list */
tobuf[0] = '\0';
mci->mci_retryrcpt = false;
mci->mci_tolist = tobuf;
-# if PIPELINING
+#if PIPELINING
pchain = NULL;
mci->mci_nextaddr = NULL;
-# endif /* PIPELINING */
+#endif
for (to = tochain; to != NULL; to = to->q_tchain)
{
@@ -3365,7 +3544,7 @@ do_transfer:
/* mark recipient state as "ok so far" */
to->q_state = QS_OK;
e->e_to = to->q_paddr;
-# if STARTTLS
+#if STARTTLS
i = rscheck("tls_rcpt", to->q_user, NULL, e,
RSF_RMCOMM|RSF_COUNT, 3,
mci->mci_host, e->e_id, NULL, NULL);
@@ -3381,10 +3560,10 @@ do_transfer:
}
continue;
}
-# endif /* STARTTLS */
+#endif /* STARTTLS */
i = smtprcpt(to, m, mci, e, ctladdr, xstart);
-# if PIPELINING
+#if PIPELINING
if (i == EX_OK &&
bitset(MCIF_PIPELINED, mci->mci_flags))
{
@@ -3404,7 +3583,7 @@ do_transfer:
pchain = pchain->q_pchain;
}
}
-# endif /* PIPELINING */
+#endif /* PIPELINING */
if (i != EX_OK)
{
markfailure(e, to, mci, i, false);
@@ -3417,10 +3596,10 @@ do_transfer:
/* No recipients in list and no missing responses? */
if (tobuf[0] == '\0'
-# if PIPELINING
+#if PIPELINING
&& bitset(MCIF_PIPELINED, mci->mci_flags)
&& mci->mci_nextaddr == NULL
-# endif /* PIPELINING */
+#endif
)
{
rcode = EX_OK;
@@ -3443,7 +3622,7 @@ do_transfer:
#if NAMED_BIND
if (ConfigLevel < 2)
_res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */
-#endif /* NAMED_BIND */
+#endif
if (tTd(62, 1))
checkfds("after delivery");
@@ -3621,6 +3800,23 @@ do_transfer:
markstats(e, tochain, STATS_NORMAL);
mci_store_persistent(mci);
+#if _FFR_OCC
+ /*
+ ** HACK: this is NOT the right place to "close" a connection!
+ ** use smtpquit?
+ ** add a flag to mci to indicate that rate/conc. was increased?
+ */
+
+ if (clever)
+ {
+ extern SOCKADDR CurHostAddr;
+
+ /* check family... {} */
+ /* r = anynet_pton(AF_INET, p, dst); */
+ occ_close(e, mci, host, &CurHostAddr);
+ }
+#endif /* _FFR_OCC */
+
/* Some recipients were tempfailed, try them on the next host */
if (mci != NULL && mci->mci_retryrcpt && nummxhosts > hostnum)
{
@@ -3722,13 +3918,10 @@ markfailure(e, q, mci, rcode, ovr)
if (mci->mci_rstatus != NULL)
rstatus = sm_rpool_strdup_x(e->e_rpool,
mci->mci_rstatus);
- else
- rstatus = NULL;
}
else if (e->e_status != NULL)
{
status = e->e_status;
- rstatus = NULL;
}
else
{
@@ -3879,7 +4072,7 @@ endmailer(mci, e, pv)
#if STARTTLS
/* shutdown TLS */
(void) endtlsclt(mci);
-#endif /* STARTTLS */
+#endif
/* now close the input */
if (mci->mci_in != NULL)
@@ -4050,22 +4243,22 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
{
#ifdef ENETDOWN
case ENETDOWN: /* Network is down */
-#endif /* ENETDOWN */
+#endif
#ifdef ENETUNREACH
case ENETUNREACH: /* Network is unreachable */
-#endif /* ENETUNREACH */
+#endif
#ifdef ENETRESET
case ENETRESET: /* Network dropped connection on reset */
-#endif /* ENETRESET */
+#endif
#ifdef ECONNABORTED
case ECONNABORTED: /* Software caused connection abort */
-#endif /* ECONNABORTED */
+#endif
#ifdef EHOSTDOWN
case EHOSTDOWN: /* Host is down */
-#endif /* EHOSTDOWN */
+#endif
#ifdef EHOSTUNREACH
case EHOSTUNREACH: /* No route to host */
-#endif /* EHOSTUNREACH */
+#endif
if (mci != NULL && mci->mci_host != NULL)
{
(void) sm_strlcpyn(bp,
@@ -4078,6 +4271,16 @@ giveresponse(status, dsn, m, mci, ctladdr, xstart, e, to)
}
(void) sm_strlcpyn(bp, SPACELEFT(buf, bp), 2, ": ",
statmsg);
+#if DANE
+ if (errnum == 0 && SmtpError[0] != '\0' &&
+ h_errno == TRY_AGAIN &&
+ mci->mci_exitstat == EX_TEMPFAIL)
+ {
+ (void) sm_strlcat(bp, SmtpError,
+ SPACELEFT(buf, bp));
+ bp += strlen(bp);
+ }
+#endif /* DANE */
usestat = true;
}
statmsg = buf;
@@ -4284,14 +4487,8 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
}
# if _FFR_LOG_MORE2
-# if STARTTLS
- p = macvalue(macid("{verify}"), e);
- if (p == NULL || *p == '\0')
- p = "NONE";
- (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", tls_verify=%.20s", p);
- bp += strlen(bp);
-# endif /* STARTTLS */
-# endif /* _FFR_LOG_MORE2 */
+ LOG_MORE(buf, bp);
+# endif
/* pri: changes with each delivery attempt */
(void) sm_snprintf(bp, SPACELEFT(buf, bp), ", pri=%ld",
@@ -4339,7 +4536,7 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
bp += strlen(bp);
}
-#if _FFR_LOG_NTRIES
+# if _FFR_LOG_NTRIES
/* ntries */
if (e->e_ntries >= 0)
{
@@ -4347,7 +4544,7 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
", ntries=%d", e->e_ntries + 1);
bp += strlen(bp);
}
-#endif /* _FFR_LOG_NTRIES */
+# endif /* _FFR_LOG_NTRIES */
# define STATLEN (((SYSLOG_BUFSIZE) - 100) / 4)
# if (STATLEN) < 63
@@ -4359,7 +4556,6 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
# define STATLEN 203
# endif /* (STATLEN) > 203 */
-#if _FFR_LOGREPLY
/*
** Notes:
** per-rcpt status: to->q_rstatus
@@ -4373,6 +4569,9 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
** Note: this doesn't show the stage at which the error happened.
** can/should we log that?
** XS_* in reply() basically encodes the state.
+ **
+ ** Note: in some case the normal logging might show the same server
+ ** reply - how to avoid that?
*/
/* only show errors */
@@ -4394,7 +4593,6 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e, to, rcode)
shortenstring(e->e_text, STATLEN));
bp += strlen(bp);
}
-#endif
/* stat: max 210 bytes */
if ((bp - buf) > (sizeof(buf) - ((STATLEN) + 20)))
@@ -4633,7 +4831,7 @@ putbody(mci, e, separator)
char buf[MAXLINE];
#if MIME8TO7
char *boundaries[MAXMIMENESTING + 1];
-#endif /* MIME8TO7 */
+#endif
/*
** Output the body of the message
@@ -5671,7 +5869,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e)
#if !NOFTRUNCATE
(void) ftruncate(sm_io_getinfo(f, SM_IO_WHAT_FD, NULL),
curoff);
-#endif /* !NOFTRUNCATE */
+#endif
}
/* reset ISUID & ISGID bits for paranoid systems */
@@ -5728,6 +5926,58 @@ mailfiletimeout(ignore)
errno = ETIMEDOUT;
longjmp(CtxMailfileTimeout, 1);
}
+
+#if DANE
+
+/*
+** GETMPORT -- return the port of a mailer
+**
+** Parameters:
+** m -- the mailer describing this host.
+**
+** Returns:
+** the port of the mailer if defined.
+** 0 otherwise
+** <0 error
+*/
+
+static int getmport __P((MAILER *));
+
+static int
+getmport(m)
+ MAILER *m;
+{
+ unsigned long ulval;
+ char *buf, *ep;
+
+ if (m->m_port > 0)
+ return m->m_port;
+
+ if (NULL == m->m_argv[0] ||NULL == m->m_argv[1])
+ return -1;
+ buf = m->m_argv[2];
+ if (NULL == buf)
+ return 0;
+
+ errno = 0;
+ ulval = strtoul(buf, &ep, 0);
+ if (buf[0] == '\0' || *ep != '\0')
+ return -1;
+ if (errno == ERANGE && ulval == ULONG_MAX)
+ return -1;
+ if (ulval > USHRT_MAX)
+ return -1;
+ m->m_port = (unsigned short) ulval;
+ if (tTd(17, 30))
+ sm_dprintf("getmport: mailer=%s, port=%d\n", m->m_name,
+ m->m_port);
+ return m->m_port;
+}
+# define GETMPORT(m) getmport(m)
+#else /* DANE */
+# define GETMPORT(m) 25
+#endif /* DANE */
+
/*
** HOSTSIGNATURE -- return the "signature" for a host.
**
@@ -5738,6 +5988,7 @@ mailfiletimeout(ignore)
** Parameters:
** m -- the mailer describing this host.
** host -- the host name.
+** ad -- DNSSEC: ad
**
** Returns:
** The signature for this host.
@@ -5749,9 +6000,10 @@ mailfiletimeout(ignore)
#define MAXHOSTSIGNATURE 8192 /* max len of hostsignature */
char *
-hostsignature(m, host)
+hostsignature(m, host, ad)
register MAILER *m;
char *host;
+ bool ad;
{
register char *p;
register STAB *s;
@@ -5771,7 +6023,7 @@ hostsignature(m, host)
#endif /* NAMED_BIND */
if (tTd(17, 3))
- sm_dprintf("hostsignature(%s)\n", host);
+ sm_dprintf("hostsignature(%s), ad=%d\n", host, ad);
/*
** If local delivery (and not remote), just return a constant.
@@ -5839,7 +6091,7 @@ hostsignature(m, host)
for (hp = host; hp != NULL; hp = endp)
{
-#if NETINET6
+# if NETINET6
if (*hp == '[')
{
endp = strchr(hp + 1, ']');
@@ -5848,9 +6100,9 @@ hostsignature(m, host)
}
else
endp = strpbrk(hp, ":,");
-#else /* NETINET6 */
+# else /* NETINET6 */
endp = strpbrk(hp, ":,");
-#endif /* NETINET6 */
+# endif /* NETINET6 */
if (endp != NULL)
{
sep = *endp;
@@ -5868,8 +6120,10 @@ hostsignature(m, host)
auto int rcode;
int ttl;
- nmx = getmxrr(hp, mxhosts, mxprefs, true, &rcode, true,
- &ttl);
+ GETMPORT(m);
+ nmx = getmxrr(hp, mxhosts, mxprefs,
+ DROPLOCALHOST|TRYFALLBACK|(ad ? ISAD :0),
+ &rcode, &ttl, M_PORT(m));
if (nmx <= 0)
{
int save_errno;
@@ -5881,7 +6135,10 @@ hostsignature(m, host)
mci->mci_errno = save_errno;
mci->mci_herrno = h_errno;
mci->mci_lastuse = now;
- if (rcode == EX_NOHOST)
+ if (nmx == NULLMX)
+ mci_setstat(mci, rcode, "5.7.27",
+ "550 Host does not accept mail");
+ else if (rcode == EX_NOHOST)
mci_setstat(mci, rcode, "5.1.2",
"550 Host unknown");
else
@@ -6090,7 +6347,7 @@ parse_hostsignature(sig, mxhosts, mailer)
return nmx;
}
-# if STARTTLS
+#if STARTTLS
static SSL_CTX *clt_ctx = NULL;
static bool tls_ok_clt = true;
@@ -6139,8 +6396,16 @@ initclttls(tls_ok)
if (clt_ctx != NULL)
return true; /* already done */
tls_ok_clt = inittls(&clt_ctx, TLS_I_CLT, Clt_SSL_Options, false,
- CltCertFile, CltKeyFile,
- CACertPath, CACertFile, DHParams);
+ CltCertFile, CltKeyFile,
+# if _FFR_CLIENTCA
+ (CltCACertPath != NULL) ? CltCACertPath :
+# endif
+ CACertPath,
+# if _FFR_CLIENTCA
+ (CltCACertFile != NULL) ? CltCACertFile :
+# endif
+ CACertFile,
+ DHParams);
return tls_ok_clt;
}
@@ -6159,29 +6424,35 @@ initclttls(tls_ok)
*/
static int
-starttls(m, mci, e)
+starttls(m, mci, e
+# if DANE
+ , dane_vrfy_ctx
+# endif
+ )
MAILER *m;
MCI *mci;
ENVELOPE *e;
+# if DANE
+ dane_vrfy_ctx_P dane_vrfy_ctx;
+# endif
{
int smtpresult;
int result = 0;
int rfd, wfd;
SSL *clt_ssl = NULL;
time_t tlsstart;
+ extern int TLSsslidx;
if (clt_ctx == NULL && !initclttls(true))
return EX_TEMPFAIL;
-# if USE_OPENSSL_ENGINE
- if (!SSLEngineInitialized && !SSL_set_engine(NULL))
+ if (!TLS_set_engine(SSLEngine, false))
{
sm_syslog(LOG_ERR, NOQID,
- "STARTTLS=client, SSL_set_engine=failed");
+ "STARTTLS=client, engine=%s, TLS_set_engine=failed",
+ SSLEngine);
return EX_TEMPFAIL;
}
- SSLEngineInitialized = true;
-# endif /* USE_OPENSSL_ENGINE */
smtpmessage("STARTTLS", m, mci);
@@ -6213,19 +6484,60 @@ starttls(m, mci, e)
{
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=client, error: SSL_new failed");
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, "client");
+ tlslogerr(LOG_WARNING, 9, "client");
}
return EX_SOFTWARE;
}
/* SSL_clear(clt_ssl); ? */
- if (get_tls_se_options(e, clt_ssl, false) != 0)
+ if (get_tls_se_options(e, clt_ssl, &mci->mci_tlsi, false) != 0)
{
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=client, get_tls_se_options=fail");
return EX_SOFTWARE;
}
+ result = SSL_set_ex_data(clt_ssl, TLSsslidx, &mci->mci_tlsi);
+ if (0 == result)
+ {
+ if (LogLevel > 5)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=client, error: SSL_set_ex_data failed=%d, idx=%d",
+ result, TLSsslidx);
+ tlslogerr(LOG_WARNING, 9, "client");
+ }
+ return EX_SOFTWARE;
+ }
+# if DANE
+ if (SM_TLSI_IS(&(mci->mci_tlsi), TLSI_FL_NODANE))
+ dane_vrfy_ctx->dane_vrfy_chk = DANE_NEVER;
+ else
+ {
+ int r;
+
+# define SM_IS_EMPTY(s) (NULL == (s) || '\0' == *(s))
+
+ /* set SNI only if there is a TLSA RR */
+ if (dane_get_tlsa(dane_vrfy_ctx) != NULL &&
+ !(SM_IS_EMPTY(dane_vrfy_ctx->dane_vrfy_host) &&
+ SM_IS_EMPTY(dane_vrfy_ctx->dane_vrfy_sni)) &&
+ (r = SSL_set_tlsext_host_name(clt_ssl,
+ (!SM_IS_EMPTY(dane_vrfy_ctx->dane_vrfy_sni)
+ ? dane_vrfy_ctx->dane_vrfy_sni
+ : dane_vrfy_ctx->dane_vrfy_host))) <= 0)
+ {
+ if (LogLevel > 5)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=client, host=%s, SSL_set_tlsext_host_name=%d",
+ dane_vrfy_ctx->dane_vrfy_host, r);
+ }
+ tlslogerr(LOG_ERR, 5, "client");
+ /* return EX_SOFTWARE; */
+ }
+ }
+ memcpy(&mci->mci_tlsi.tlsi_dvc, dane_vrfy_ctx, sizeof(*dane_vrfy_ctx));
+# endif /* DANE */
rfd = sm_io_getinfo(mci->mci_in, SM_IO_WHAT_FD, NULL);
wfd = sm_io_getinfo(mci->mci_out, SM_IO_WHAT_FD, NULL);
@@ -6239,8 +6551,7 @@ starttls(m, mci, e)
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=client, error: SSL_set_xfd failed=%d",
result);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, "client");
+ tlslogerr(LOG_WARNING, 9, "client");
}
return EX_SOFTWARE;
}
@@ -6270,12 +6581,10 @@ ssl_retry:
"STARTTLS=client, error: connect failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d",
result, sr == NULL ? "unknown" : sr, ssl_err,
save_errno, i);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, "client");
+ tlslogerr(LOG_WARNING, 9, "client");
}
- SSL_free(clt_ssl);
- clt_ssl = NULL;
+ SM_SSL_FREE(clt_ssl);
return EX_SOFTWARE;
}
mci->mci_ssl = clt_ssl;
@@ -6287,8 +6596,7 @@ ssl_retry:
return EX_OK;
/* failure */
- SSL_free(clt_ssl);
- clt_ssl = NULL;
+ SM_SSL_FREE(clt_ssl);
return EX_SOFTWARE;
}
/*
@@ -6309,12 +6617,12 @@ endtlsclt(mci)
if (!bitset(MCIF_TLSACT, mci->mci_flags))
return EX_OK;
- r = endtls(mci->mci_ssl, "client");
+ r = endtls(&mci->mci_ssl, "client");
mci->mci_flags &= ~MCIF_TLSACT;
return r;
}
-# endif /* STARTTLS */
-# if STARTTLS || SASL
+#endif /* STARTTLS */
+#if STARTTLS || SASL
/*
** ISCLTFLGSET -- check whether client flag is set.
**
@@ -6344,4 +6652,4 @@ iscltflgset(e, flag)
}
return false;
}
-# endif /* STARTTLS || SASL */
+#endif /* STARTTLS || SASL */
diff --git a/contrib/sendmail/src/domain.c b/contrib/sendmail/src/domain.c
index 4d1b92d05c88..c45abf1acc09 100644
--- a/contrib/sendmail/src/domain.c
+++ b/contrib/sendmail/src/domain.c
@@ -13,54 +13,380 @@
#include <sendmail.h>
#include "map.h"
+#if _FFR_EAI
+#include <unicode/uidna.h>
+#endif
#if NAMED_BIND
SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (with name server)")
-#else /* NAMED_BIND */
+#else
SM_RCSID("@(#)$Id: domain.c,v 8.205 2013-11-22 20:51:55 ca Exp $ (without name server)")
-#endif /* NAMED_BIND */
+#endif
#if NAMED_BIND
# include <arpa/inet.h>
+# include <sm_resolve.h>
+# if DANE
+# include <tls.h>
+# ifndef SM_NEG_TTL
+# define SM_NEG_TTL 60 /* "negative" TTL */
+# endif
+# endif
# ifndef MXHOSTBUFSIZE
# define MXHOSTBUFSIZE (128 * MAXMXHOSTS)
-# endif /* ! MXHOSTBUFSIZE */
+# endif
static char MXHostBuf[MXHOSTBUFSIZE];
-#if (MXHOSTBUFSIZE < 2) || (MXHOSTBUFSIZE >= INT_MAX/2)
+# if (MXHOSTBUFSIZE < 2) || (MXHOSTBUFSIZE >= INT_MAX/2)
ERROR: _MXHOSTBUFSIZE is out of range
-#endif /* (MXHOSTBUFSIZE < 2) || (MXHOSTBUFSIZE >= INT_MAX/2) */
+# endif
# ifndef MAXDNSRCH
# define MAXDNSRCH 6 /* number of possible domains to search */
-# endif /* ! MAXDNSRCH */
+# endif
# ifndef RES_DNSRCH_VARIABLE
# define RES_DNSRCH_VARIABLE _res.dnsrch
-# endif /* ! RES_DNSRCH_VARIABLE */
+# endif
# ifndef NO_DATA
# define NO_DATA NO_ADDRESS
-# endif /* ! NO_DATA */
+# endif
# ifndef HFIXEDSZ
# define HFIXEDSZ 12 /* sizeof(HEADER) */
-# endif /* ! HFIXEDSZ */
+# endif
# define MAXCNAMEDEPTH 10 /* maximum depth of CNAME recursion */
# if defined(__RES) && (__RES >= 19940415)
# define RES_UNC_T char *
-# else /* defined(__RES) && (__RES >= 19940415) */
+# else
# define RES_UNC_T unsigned char *
-# endif /* defined(__RES) && (__RES >= 19940415) */
+# endif
static int mxrand __P((char *));
static int fallbackmxrr __P((int, unsigned short *, char **));
+# if DANE
+
+/*
+** TLSAADD -- add TLSA records to dane_tlsa entry
+**
+** Parameters:
+** name -- key for stab entry (for debugging output)
+** dr -- DNS reply
+** dane_tlsa -- dane_tlsa entry
+** dnsrc -- DNS lookup return code (h_errno)
+** n -- current number of TLSA records in dane_tlsa entry
+** pttl -- (pointer to) TTL (in/out)
+** level -- recursion level (CNAMEs)
+**
+** Returns:
+** new number of TLSA records
+*/
+
+static int tlsaadd __P((const char *, DNS_REPLY_T *, dane_tlsa_P, int, int,
+ unsigned int *, int));
+
+static int
+tlsaadd(name, dr, dane_tlsa, dnsrc, n, pttl, level)
+ const char *name;
+ DNS_REPLY_T *dr;
+ dane_tlsa_P dane_tlsa;
+ int dnsrc;
+ int n;
+ unsigned int *pttl;
+ int level;
+{
+ RESOURCE_RECORD_T *rr;
+ unsigned int ttl;
+ int nprev;
+
+ if (dnsrc != 0)
+ {
+ if (tTd(8, 2))
+ sm_dprintf("tlsaadd(%s), prev=%d, dnsrc=%d\n",
+ name, dane_tlsa->dane_tlsa_dnsrc, dnsrc);
+
+ /* check previous error and keep the "most important" one? */
+ dane_tlsa->dane_tlsa_dnsrc = dnsrc;
+# if DNSSEC_TEST
+ if (tTd(8, 110))
+ *pttl = tTdlevel(8)-110; /* how to make this an option? */
+ else
+# else
+ *pttl = SM_NEG_TTL;
+# endif
+
+ return n;
+ }
+ if (dr == NULL)
+ return n;
+ if (dr->dns_r_h.ad != 1 && Dane == DANE_SECURE) /* not secure? */
+ return n;
+ ttl = *pttl;
+
+ /* first: try to find TLSA records */
+ nprev = n;
+ for (rr = dr->dns_r_head; rr != NULL && n < MAX_TLSA_RR;
+ rr = rr->rr_next)
+ {
+ int tlsa_chk;
+
+ if (rr->rr_type != T_TLSA)
+ {
+ if (rr->rr_type != T_CNAME && tTd(8, 8))
+ sm_dprintf("tlsaadd(%s), type=%s\n", name,
+ dns_type_to_string(rr->rr_type));
+ continue;
+ }
+ tlsa_chk = dane_tlsa_chk(rr->rr_u.rr_data, rr->rr_size, name,
+ true);
+ if (!TLSA_IS_VALID(tlsa_chk))
+ continue;
+
+ /*
+ ** To do: the RRs should be sorted (by "complexity") --
+ ** when more than one type is supported.
+ */
+
+ dane_tlsa->dane_tlsa_rr[n] = rr->rr_u.rr_data;
+ dane_tlsa->dane_tlsa_len[n] = rr->rr_size;
+ if (tTd(8, 2))
+ {
+ unsigned char *p;
+
+ p = rr->rr_u.rr_data;
+ sm_dprintf("tlsaadd(%s), n=%d, %d-%d-%d:%02x\n", name,
+ n, (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
+ }
+
+ /* require some minimum TTL? */
+ if (ttl > rr->rr_ttl && rr->rr_ttl > 0)
+ ttl = rr->rr_ttl;
+
+ /* hack: instead of copying the data, just "take it over" */
+ rr->rr_u.rr_data = NULL;
+ ++n;
+ }
+
+ /* second: check for CNAME records, but only if no TLSA RR was added */
+ for (rr = dr->dns_r_head; rr != NULL && n < MAX_TLSA_RR && nprev == n;
+ rr = rr->rr_next)
+ {
+ DNS_REPLY_T *drc;
+ int err, herr;
+
+ if (rr->rr_type != T_CNAME)
+ continue;
+ if (level > 1)
+ {
+ if (tTd(8, 2))
+ sm_dprintf("tlsaadd(%s), CNAME=%s, level=%d\n",
+ name, rr->rr_u.rr_txt, level);
+ continue;
+ }
+
+ drc = dns_lookup_int(rr->rr_u.rr_txt, C_IN, T_TLSA, 0, 0,
+ (Dane == DANE_SECURE &&
+ !TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX))
+ ? SM_RES_DNSSEC : 0,
+ RR_RAW, &err, &herr);
+
+ if (tTd(8, 2))
+ sm_dprintf("tlsaadd(%s), CNAME=%s, level=%d, dr=%p, ad=%d, err=%d, herr=%d\n",
+ name, rr->rr_u.rr_txt, level,
+ (void *)drc, drc != NULL ? drc->dns_r_h.ad : -1,
+ err, herr);
+ nprev = n = tlsaadd(name, drc, dane_tlsa, herr, n, pttl,
+ level + 1);
+ dns_free_data(drc);
+ drc = NULL;
+ }
+
+ *pttl = ttl;
+ return n;
+}
+
+/*
+** GETTLSA -- get TLSA records for named host using DNS
+**
+** Parameters:
+** host -- host
+** name -- name for stab entry key (if NULL: host)
+** pste -- (pointer to) stab entry (output)
+** flags -- TLSAFL*
+** mxttl -- TTL of MX (or host)
+** port -- port
+**
+** Returns:
+** The number of TLSA records found.
+** <0 if there is an internal failure.
+**
+** Side effects:
+** Enters TLSA RRs into stab().
+** If the DNS lookup fails temporarily, an "empty" entry is
+** created with that DNS error code.
+*/
+
+int
+gettlsa(host, name, pste, flags, mxttl, port)
+ char *host;
+ char *name;
+ STAB **pste;
+ unsigned long flags;
+ unsigned int mxttl;
+ unsigned int port;
+{
+ DNS_REPLY_T *dr;
+ dane_tlsa_P dane_tlsa;
+ STAB *ste;
+ time_t now;
+ unsigned int ttl;
+ int n_rrs, len, err, herr;
+ bool isrname;
+ char nbuf[MAXDNAME];
+ char key[MAXDNAME];
+
+ SM_REQUIRE(host != NULL);
+ if (pste != NULL)
+ *pste = NULL;
+ if ('\0' == *host)
+ return 0;
+
+ isrname = NULL == name;
+ if (isrname)
+ name = host;
+ now = 0;
+ n_rrs = 0;
+ dr = NULL;
+ dane_tlsa = NULL;
+ len = strlen(name);
+ if (len > 1 && name[len - 1] == '.')
+ {
+ len--;
+ name[len] = '\0';
+ }
+ else
+ len = -1;
+ if (0 == port || tTd(66, 10))
+ port = 25;
+ (void) sm_snprintf(key, sizeof(key), "_%u..%s", port, name);
+ ste = stab(key, ST_TLSA_RR, ST_FIND);
+ if (tTd(8, 2))
+ sm_dprintf("gettlsa(%s, %s, ste=%p, pste=%p, flags=%lX, port=%d)\n",
+ host, isrname ? "" : name, (void *)ste, (void *)pste,
+ flags, port);
+
+ if (ste != NULL)
+ {
+ dane_tlsa = ste->s_tlsa;
+ if ((TLSAFLADMX & flags) != 0)
+ TLSA_CLR_FL(ste->s_tlsa, TLSAFLNOADMX);
+ }
+
+ /* Do not reload TLSA RRs if the MX RRs were not securely retrieved. */
+ if (pste != NULL
+ && dane_tlsa != NULL && TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX)
+ && DANE_SECURE == Dane)
+ goto end;
+
+ if (ste != NULL)
+ {
+ SM_ASSERT(dane_tlsa != NULL);
+ now = curtime();
+ if (dane_tlsa->dane_tlsa_exp <= now
+ && 0 == (TLSAFLNOEXP & flags))
+ dane_tlsa_clr(dane_tlsa);
+ else
+ {
+ n_rrs = dane_tlsa->dane_tlsa_n;
+ goto end;
+ }
+ }
+
+ if (dane_tlsa == NULL)
+ {
+ dane_tlsa = (dane_tlsa_P) sm_malloc(sizeof(*dane_tlsa));
+ if (dane_tlsa == NULL)
+ {
+ n_rrs = -ENOMEM;
+ goto end;
+ }
+ memset(dane_tlsa, '\0', sizeof(*dane_tlsa));
+ }
+
+ /* There are flags to store -- just set those, do nothing else. */
+ if (TLSA_STORE_FL(flags))
+ {
+ dane_tlsa->dane_tlsa_flags = flags;
+ ttl = mxttl > 0 ? mxttl: SM_DEFAULT_TTL;
+ goto done;
+ }
+
+ (void) sm_snprintf(nbuf, sizeof(nbuf), "_%u._tcp.%s", port, host);
+ dr = dns_lookup_int(nbuf, C_IN, T_TLSA, 0, 0,
+ TLSA_IS_FL(dane_tlsa, TLSAFLNOADMX) ? 0 : SM_RES_DNSSEC,
+ RR_RAW, &err, &herr);
+ if (tTd(8, 2))
+ sm_dprintf("gettlsa(%s), dr=%p, ad=%d, err=%d, herr=%d\n", host,
+ (void *)dr, dr != NULL ? dr->dns_r_h.ad : -1, err, herr);
+ ttl = UINT_MAX;
+ n_rrs = tlsaadd(key, dr, dane_tlsa, herr, n_rrs, &ttl, 0);
+
+ /* no valid entries found? */
+ if (n_rrs == 0 && !TLSA_RR_TEMPFAIL(dane_tlsa))
+ {
+ if (tTd(8, 2))
+ sm_dprintf("gettlsa(%s), n_rrs=%d, herr=%d, status=NOT_ADDED\n",
+ host, n_rrs, dane_tlsa->dane_tlsa_dnsrc);
+ goto cleanup;
+ }
+
+ done:
+ dane_tlsa->dane_tlsa_n = n_rrs;
+ if (!isrname)
+ {
+ SM_FREE(dane_tlsa->dane_tlsa_sni);
+ dane_tlsa->dane_tlsa_sni = sm_strdup(host);
+ }
+ if (NULL == ste)
+ {
+ ste = stab(key, ST_TLSA_RR, ST_ENTER);
+ if (NULL == ste)
+ goto error;
+ }
+ ste->s_tlsa = dane_tlsa;
+ if (now == 0)
+ now = curtime();
+ dane_tlsa->dane_tlsa_exp = now + SM_MIN(ttl, SM_DEFAULT_TTL);
+ dns_free_data(dr);
+ dr = NULL;
+ goto end;
+
+ error:
+ if (tTd(8, 2))
+ sm_dprintf("gettlsa(%s, %s), status=error\n", host, key);
+ n_rrs = -1;
+ cleanup:
+ if (NULL == ste)
+ dane_tlsa_free(dane_tlsa);
+ dns_free_data(dr);
+ dr = NULL;
+
+ end:
+ if (pste != NULL && ste != NULL)
+ *pste = ste;
+ if (len > 0)
+ host[len] = '.';
+ return n_rrs;
+}
+# endif /* DANE */
+
/*
** GETFALLBACKMXRR -- get MX resource records for fallback MX host.
**
@@ -99,24 +425,39 @@ getfallbackmxrr(host)
#endif /* 0 */
if (NumFallbackMXHosts > 0 && renew > curtime())
return NumFallbackMXHosts;
+
+ /* for DANE we need to invoke getmxrr() to get the TLSA RRs. */
+#if !DANE
if (host[0] == '[')
{
fbhosts[0] = host;
NumFallbackMXHosts = 1;
}
else
+#endif
{
/* free old data */
for (i = 0; i < NumFallbackMXHosts; i++)
sm_free(fbhosts[i]);
- /* get new data */
- NumFallbackMXHosts = getmxrr(host, fbhosts, NULL, false,
- &rcode, false, &ttl);
+ /*
+ ** Get new data.
+ ** Note: passing 0 as port is not correct but we cannot
+ ** determine the port number as there is no mailer.
+ */
+
+ NumFallbackMXHosts = getmxrr(host, fbhosts, NULL,
+#if DANE
+ (DANE_SECURE == Dane) ? ISAD :
+#endif
+ 0,
+ &rcode, &ttl, 0);
renew = curtime() + ttl;
for (i = 0; i < NumFallbackMXHosts; i++)
fbhosts[i] = newstr(fbhosts[i]);
}
+ if (NumFallbackMXHosts == NULLMX)
+ NumFallbackMXHosts = 0;
return NumFallbackMXHosts;
}
@@ -163,11 +504,13 @@ fallbackmxrr(nmx, prefs, mxhosts)
** mxhosts -- a pointer to a return buffer of MX records.
** mxprefs -- a pointer to a return buffer of MX preferences.
** If NULL, don't try to populate.
-** droplocalhost -- If true, all MX records less preferred
+** flags -- flags:
+** DROPLOCALHOSt -- If true, all MX records less preferred
** than the local host (as determined by $=w) will
** be discarded.
+** TRYFALLBACK -- add also fallback MX host?
+** ISAD -- host lookup was secure?
** rcode -- a pointer to an EX_ status code.
-** tryfallback -- add also fallback MX host?
** pttl -- pointer to return TTL (can be NULL).
**
** Returns:
@@ -183,14 +526,14 @@ fallbackmxrr(nmx, prefs, mxhosts)
*/
int
-getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
+getmxrr(host, mxhosts, mxprefs, flags, rcode, pttl, port)
char *host;
char **mxhosts;
unsigned short *mxprefs;
- bool droplocalhost;
+ unsigned int flags;
int *rcode;
- bool tryfallback;
int *pttl;
+ int port;
{
register unsigned char *eom, *cp;
register int i, j, n;
@@ -209,19 +552,34 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
unsigned short prefer[MAXMXHOSTS];
int weight[MAXMXHOSTS];
int ttl = 0;
+ bool ad;
+ bool seennullmx = false;
extern int res_query(), res_search();
+# if DANE
+ bool cname2mx;
+ char qname[MAXNAME];
+ unsigned long old_options = 0;
+# endif
if (tTd(8, 2))
- sm_dprintf("getmxrr(%s, droplocalhost=%d)\n",
- host, droplocalhost);
+ sm_dprintf("getmxrr(%s, droplocalhost=%d, flags=%X, port=%d)\n",
+ host, (flags & DROPLOCALHOST) != 0, flags, port);
+ ad = (flags & ISAD) != 0;
*rcode = EX_OK;
if (pttl != NULL)
*pttl = SM_DEFAULT_TTL;
if (*host == '\0')
return 0;
-
- if ((fallbackMX != NULL && droplocalhost &&
- wordinclass(fallbackMX, 'w')) || !tryfallback)
+# if DANE
+ cname2mx = false;
+ qname[0] = '\0';
+ old_options = _res.options;
+ if (ad)
+ _res.options |= SM_RES_DNSSEC;
+# endif
+
+ if ((fallbackMX != NULL && (flags & DROPLOCALHOST) != 0 &&
+ wordinclass(fallbackMX, 'w')) || (flags & TRYFALLBACK) == 0)
{
/* don't use fallback for this pass */
fallbackMX = NULL;
@@ -236,6 +594,34 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
if (host[0] == '[')
goto punt;
+# if DANE
+ /*
+ ** NOTE: This only works if nocanonify is used,
+ ** otherwise the name is already rewritten.
+ */
+
+ /* always or only when "needed"? */
+ if (DANE_ALWAYS == Dane || (ad && DANE_SECURE == Dane))
+ (void) sm_strlcpy(qname, host, sizeof(qname));
+# endif /* DANE */
+
+# if _FFR_EAI
+ if (!addr_is_ascii(host))
+ {
+ char buf[1024];
+ UErrorCode error = U_ZERO_ERROR;
+ UIDNAInfo info = UIDNA_INFO_INITIALIZER;
+ UIDNA *idna;
+
+ idna = uidna_openUTS46(UIDNA_NONTRANSITIONAL_TO_ASCII, &error);
+ (void) uidna_nameToASCII_UTF8(idna, host, strlen(host),
+ buf, sizeof(buf) - 1,
+ &info, &error);
+ uidna_close(idna);
+ host = sm_rpool_strdup_x(CurEnv->e_rpool, buf);
+ }
+# endif /* _FFR_EAI */
+
/*
** If we don't have MX records in our host switch, don't
** try for MX records. Note that this really isn't "right",
@@ -250,15 +636,26 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
resfunc = res_query;
else
resfunc = res_search;
+# if DNSSEC_TEST
+ if (tTd(8, 110))
+ resfunc = tstdns_search;
+# endif
errno = 0;
+ hp = (HEADER *)&answer;
n = (*resfunc)(host, C_IN, T_MX, (unsigned char *) &answer,
sizeof(answer));
if (n < 0)
{
if (tTd(8, 1))
- sm_dprintf("getmxrr: res_search(%s) failed (errno=%d, h_errno=%d)\n",
- host, errno, h_errno);
+# if DNSSEC_TEST
+ sm_dprintf("getmxrr: res_search(%s) failed (errno=%d (%s), h_errno=%d (%s))\n",
+ host, errno, strerror(errno),
+ h_errno, herrno2txt(h_errno));
+# else
+ sm_dprintf("getmxrr: res_search(%s) failed, h_errno=%d\n",
+ host, h_errno);
+# endif
switch (h_errno)
{
case NO_DATA:
@@ -271,8 +668,8 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
case HOST_NOT_FOUND:
# if BROKEN_RES_SEARCH
- case 0: /* Ultrix resolver retns failure w/ h_errno=0 */
-# endif /* BROKEN_RES_SEARCH */
+ case 0: /* Ultrix resolver returns failure w/ h_errno=0 */
+# endif
/* host doesn't exist in DNS; might be in /etc/hosts */
trycanon = true;
*rcode = EX_NOHOST;
@@ -284,7 +681,8 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
if (fallbackMX != NULL)
{
/* name server is hosed -- push to fallback */
- return fallbackmxrr(nmx, prefs, mxhosts);
+ nmx = fallbackmxrr(nmx, prefs, mxhosts);
+ goto done;
}
/* it might come up later; better queue it up */
*rcode = EX_TEMPFAIL;
@@ -298,17 +696,21 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
}
/* irreconcilable differences */
- return -1;
+ goto error;
}
+ ad = ad && hp->ad;
+ if (tTd(8, 2))
+ sm_dprintf("getmxrr(%s), hp=%p, ad=%d\n", host, (void*)hp, ad);
+
/* avoid problems after truncation in tcp packets */
if (n > sizeof(answer))
n = sizeof(answer);
/* find first satisfactory answer */
- hp = (HEADER *)&answer;
cp = (unsigned char *)&answer + HFIXEDSZ;
eom = (unsigned char *)&answer + n;
+
for (qdcount = ntohs((unsigned short) hp->qdcount);
qdcount--;
cp += n + QFIXEDSZ)
@@ -335,11 +737,19 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
cp += INT16SZ; /* skip over class */
GETLONG(ttl, cp);
GETSHORT(n, cp); /* rdlength */
+# if DANE
+ if (type == T_CNAME)
+ cname2mx = true;
+# endif
if (type != T_MX)
{
- if (tTd(8, 8) || _res.options & RES_DEBUG)
- sm_dprintf("unexpected answer type %d, size %d\n",
- type, n);
+ if ((tTd(8, 8) || _res.options & RES_DEBUG)
+# if DANE
+ && type != T_RRSIG
+# endif
+ )
+ sm_dprintf("unexpected answer type %s, size %d\n",
+ dns_type_to_string(type), n);
cp += n;
continue;
}
@@ -349,23 +759,17 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
break;
cp += n;
n = strlen(bp);
-# if 0
- /* Can this happen? */
- if (n == 0)
- {
- if (LogLevel > 4)
- sm_syslog(LOG_ERR, NOQID,
- "MX records for %s contain empty string",
- host);
- continue;
- }
-# endif /* 0 */
+
+ /* Support for RFC7505 "MX 0 ." */
+ if (pref == 0 && *bp == '\0')
+ seennullmx = true;
+
if (wordinclass(bp, 'w'))
{
if (tTd(8, 3))
sm_dprintf("found localhost (%s) in MX list, pref=%d\n",
bp, pref);
- if (droplocalhost)
+ if ((flags & DROPLOCALHOST) != 0)
{
if (!seenlocal || pref < localpref)
localpref = pref;
@@ -378,8 +782,31 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
weight[nmx] = mxrand(bp);
prefs[nmx] = pref;
mxhosts[nmx++] = bp;
+# if DANE
+ if (CHK_DANE(Dane) && port >= 0)
+ {
+ int nrr;
+ unsigned long flags;
+
+ flags = ad ? TLSAFLADMX : TLSAFLNOADMX;
+ nrr = gettlsa(bp, NULL, NULL, flags, ttl, port);
+
+ /* Only check qname if no TLSA RRs were found */
+ if (0 == nrr && cname2mx && '\0' != qname[0] &&
+ strcmp(qname, bp))
+ gettlsa(qname, bp, NULL, flags, ttl, port);
+ /* XXX is this the right ad flag? */
+ }
+# endif
+
+ /*
+ ** Note: n can be 0 for something like:
+ ** host MX 0 .
+ ** See RFC 7505
+ */
+
bp += n;
- if (bp[-1] != '.')
+ if (0 == n || bp[-1] != '.')
{
*bp++ = '.';
n++;
@@ -393,6 +820,15 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl)
buflen -= n + 1;
}
+ /* Support for RFC7505 "MX 0 ." */
+ if (seennullmx && nmx == 1)
+ {
+ if (tTd(8, 4))
+ sm_dprintf("getmxrr: Null MX record found, domain doesn't accept mail (RFC7505)\n");
+ *rcode = EX_UNAVAILABLE;
+ return NULLMX;
+ }
+
/* return only one TTL entry, that should be sufficient */
if (ttl > 0 && pttl != NULL)
*pttl = ttl;
@@ -475,7 +911,7 @@ punt:
UseNameServer))
{
*rcode = EX_TEMPFAIL;
- return -1;
+ goto error;
}
# if NETINET6
SM_SET_H_ERRNO(0);
@@ -488,7 +924,7 @@ punt:
UseNameServer)))
{
*rcode = EX_TEMPFAIL;
- return -1;
+ goto error;
}
# endif /* NETINET6 */
}
@@ -499,19 +935,19 @@ punt:
*rcode = EX_CONFIG;
syserr("MX list for %s points back to %s",
host, MyHostName);
- return -1;
+ goto error;
}
# if NETINET6
freehostent(h);
h = NULL;
-# endif /* NETINET6 */
+# endif
}
if (strlen(host) >= sizeof(MXHostBuf))
{
*rcode = EX_CONFIG;
syserr("Host name %s too long",
shortenstring(host, MAXSHORTSTR));
- return -1;
+ goto error;
}
(void) sm_strlcpy(MXHostBuf, host, sizeof(MXHostBuf));
mxhosts[0] = MXHostBuf;
@@ -521,7 +957,7 @@ punt:
register char *p;
# if NETINET6
struct sockaddr_in6 tmp6;
-# endif /* NETINET6 */
+# endif
/* this may be an MX suppression-style address */
p = strchr(MXHostBuf, ']');
@@ -550,7 +986,8 @@ punt:
}
}
if (trycanon &&
- getcanonname(mxhosts[0], sizeof(MXHostBuf) - 2, false, pttl))
+ (n = getcanonname(mxhosts[0], sizeof(MXHostBuf) - 2, false,
+ pttl)) != HOST_NOTFOUND)
{
/* XXX MXHostBuf == "" ? is that possible? */
bp = &MXHostBuf[strlen(MXHostBuf)];
@@ -560,16 +997,62 @@ punt:
*bp = '\0';
}
nmx = 1;
+# if DANE
+ if (tTd(8, 3))
+ sm_dprintf("getmxrr=%s, getcanonname=%d\n",
+ mxhosts[0], n);
+ if (CHK_DANE(Dane) && port >= 0)
+ {
+ int nrr;
+ unsigned long flags;
+ unsigned int cttl;
+
+ if (pttl != NULL)
+ cttl = *pttl;
+ else if (ttl > 0)
+ cttl = ttl;
+ else
+ cttl = SM_DEFAULT_TTL;
+
+ flags = (ad && n == HOST_SECURE)
+ ? TLSAFLADMX : TLSAFLNOADMX;
+ nrr = gettlsa(mxhosts[0], NULL, NULL, flags,
+ cttl, port);
+
+ /*
+ ** Only check qname if no TLSA RRs were found
+ ** XXX: what about (temp) DNS errors?
+ */
+
+ if (0 == nrr && '\0' != qname[0] &&
+ strcmp(qname, mxhosts[0]))
+ gettlsa(qname, mxhosts[0], NULL, flags,
+ cttl, port);
+ /* XXX is this the right ad flag? */
+ }
+# endif
}
}
/* if we have a default lowest preference, include that */
if (fallbackMX != NULL && !seenlocal)
{
+ /* TODO: DNSsec status of fallbacks */
nmx = fallbackmxrr(nmx, prefs, mxhosts);
}
+ done:
+# if DANE
+ _res.options = old_options;
+# endif
return nmx;
+
+ error:
+# if DANE
+ _res.options = old_options;
+# endif
+ return -1;
}
+
/*
** MXRAND -- create a randomizer for equal MX preferences
**
@@ -640,15 +1123,15 @@ bestmx_map_lookup(map, name, av, statp)
ssize_t len = 0;
char *result;
char *mxhosts[MAXMXHOSTS + 1];
-#if _FFR_BESTMX_BETTER_TRUNCATION
+# if _FFR_BESTMX_BETTER_TRUNCATION
char *buf;
-#else /* _FFR_BESTMX_BETTER_TRUNCATION */
+# else
char *p;
char buf[PSBUFSIZE / 2];
-#endif /* _FFR_BESTMX_BETTER_TRUNCATION */
+# endif
_res.options &= ~(RES_DNSRCH|RES_DEFNAMES);
- nmx = getmxrr(name, mxhosts, NULL, false, statp, false, NULL);
+ nmx = getmxrr(name, mxhosts, NULL, 0, statp, NULL, -1);
_res.options = saveopts;
if (nmx <= 0)
return NULL;
@@ -662,7 +1145,7 @@ bestmx_map_lookup(map, name, av, statp)
** ones. We need to build them all into a list.
*/
-#if _FFR_BESTMX_BETTER_TRUNCATION
+# if _FFR_BESTMX_BETTER_TRUNCATION
for (i = 0; i < nmx; i++)
{
if (strchr(mxhosts[i], map->map_coldelim) != NULL)
@@ -699,7 +1182,7 @@ bestmx_map_lookup(map, name, av, statp)
/* Cleanly truncate for rulesets */
truncate_at_delim(buf, PSBUFSIZE / 2, map->map_coldelim);
-#else /* _FFR_BESTMX_BETTER_TRUNCATION */
+# else /* _FFR_BESTMX_BETTER_TRUNCATION */
p = buf;
for (i = 0; i < nmx; i++)
{
@@ -723,12 +1206,12 @@ bestmx_map_lookup(map, name, av, statp)
p += slen;
len += slen;
}
-#endif /* _FFR_BESTMX_BETTER_TRUNCATION */
+# endif /* _FFR_BESTMX_BETTER_TRUNCATION */
result = map_rewrite(map, buf, len, av);
-#if _FFR_BESTMX_BETTER_TRUNCATION
+# if _FFR_BESTMX_BETTER_TRUNCATION
sm_free(buf);
-#endif /* _FFR_BESTMX_BETTER_TRUNCATION */
+# endif
return result;
}
/*
@@ -758,11 +1241,11 @@ bestmx_map_lookup(map, name, av, statp)
** pttl -- pointer to return TTL (can be NULL).
**
** Returns:
-** true -- if the host matched.
-** false -- otherwise.
+** >0 -- if the host was found.
+** 0 -- otherwise.
*/
-bool
+int
dns_getcanonname(host, hbsize, trymx, statp, pttl)
char *host;
int hbsize;
@@ -775,31 +1258,48 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl)
register int n;
HEADER *hp;
querybuf answer;
- int ancount, qdcount;
- int ret;
+ int ancount, qdcount, ret, type, qtype, initial, loopcnt, ttl, sli;
char **domain;
- int type;
- int ttl = 0;
- char **dp;
+ char *dp;
char *mxmatch;
- bool amatch;
- bool gotmx = false;
- int qtype;
- int initial;
- int loopcnt;
+ bool amatch, gotmx, ad;
char nbuf[SM_MAX(MAXPACKET, MAXDNAME*2+2)];
- char *searchlist[MAXDNSRCH + 2];
-
+# if DNSSEC_TEST
+# define ADDSL 1 /* NameSearchList may add another entry to searchlist! */
+# else
+# define ADDSL 0
+# endif
+ char *searchlist[MAXDNSRCH + 2 + ADDSL];
+# define SLSIZE SM_ARRAY_SIZE(searchlist)
+ int (*resqdomain) __P((const char *, const char *, int, int, unsigned char *, int));
+# if DANE
+ unsigned long old_options = 0;
+# endif
+
+ ttl = 0;
+ gotmx = false;
+ ad = true;
if (tTd(8, 2))
sm_dprintf("dns_getcanonname(%s, trymx=%d)\n", host, trymx);
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
{
*statp = EX_UNAVAILABLE;
- return false;
+ return HOST_NOTFOUND;
}
+# if DANE
+ old_options = _res.options;
+ if (DANE_SECURE == Dane)
+ _res.options |= SM_RES_DNSSEC;
+# endif
+
*statp = EX_OK;
+ resqdomain = res_querydomain;
+# if DNSSEC_TEST
+ if (tTd(8, 110))
+ resqdomain = tstdns_querydomain;
+# endif
/*
** Initialize domain search list. If there is at least one
@@ -831,26 +1331,35 @@ cnameloop:
** else if name ends in a dot, remove that dot.
*/
- dp = searchlist;
+ sli = 0;
if (n > 0)
- *dp++ = "";
+ searchlist[sli++] = "";
+# if DNSSEC_TEST
+ if (NameSearchList != NULL)
+ {
+ SM_ASSERT(sli < SLSIZE);
+ searchlist[sli++] = NameSearchList;
+ }
+# endif
if (n >= 0 && *--cp != '.' && bitset(RES_DNSRCH, _res.options))
{
/* make sure there are less than MAXDNSRCH domains */
for (domain = RES_DNSRCH_VARIABLE, ret = 0;
- *domain != NULL && ret < MAXDNSRCH;
+ *domain != NULL && ret < MAXDNSRCH && sli < SLSIZE;
ret++)
- *dp++ = *domain++;
+ searchlist[sli++] = *domain++;
}
else if (n == 0 && bitset(RES_DEFNAMES, _res.options))
{
- *dp++ = _res.defdname;
+ SM_ASSERT(sli < SLSIZE);
+ searchlist[sli++] = _res.defdname;
}
else if (*cp == '.')
{
*cp = '\0';
}
- *dp = NULL;
+ SM_ASSERT(sli < SLSIZE);
+ searchlist[sli] = NULL;
/*
** Now loop through the search list, appending each domain in turn
@@ -862,24 +1371,28 @@ cnameloop:
# if NETINET6
if (InetMode == AF_INET6)
initial = T_AAAA;
-# endif /* NETINET6 */
+# endif
qtype = initial;
- for (dp = searchlist; *dp != NULL; )
+ for (sli = 0; sli < SLSIZE; )
{
+ dp = searchlist[sli];
+ if (NULL == dp)
+ break;
if (qtype == initial)
gotmx = false;
if (tTd(8, 5))
sm_dprintf("dns_getcanonname: trying %s.%s (%s)\n",
- host, *dp,
+ host, dp,
# if NETINET6
qtype == T_AAAA ? "AAAA" :
-# endif /* NETINET6 */
+# endif
qtype == T_A ? "A" :
qtype == T_MX ? "MX" :
"???");
errno = 0;
- ret = res_querydomain(host, *dp, C_IN, qtype,
+ hp = (HEADER *) &answer;
+ ret = (*resqdomain)(host, dp, C_IN, qtype,
answer.qb2, sizeof(answer.qb2));
if (ret <= 0)
{
@@ -896,7 +1409,7 @@ cnameloop:
*/
SM_SET_H_ERRNO(TRY_AGAIN);
- if (**dp == '\0')
+ if (*dp == '\0')
{
if (*statp == EX_OK)
*statp = EX_TEMPFAIL;
@@ -917,10 +1430,10 @@ cnameloop:
*/
if (save_errno != ETIMEDOUT)
- return false;
+ goto error;
}
else
- return false;
+ goto error;
}
nexttype:
@@ -936,7 +1449,7 @@ nexttype:
else
# endif /* NETINET6 */
if (qtype == T_A && !gotmx &&
- (trymx || **dp == '\0'))
+ (trymx || *dp == '\0'))
{
qtype = T_MX;
continue;
@@ -944,7 +1457,7 @@ nexttype:
}
/* definite no -- try the next domain */
- dp++;
+ sli++;
qtype = initial;
continue;
}
@@ -962,10 +1475,12 @@ nexttype:
** wild card MX record, we will accept MX as well.
*/
- hp = (HEADER *) &answer;
ap = (unsigned char *) &answer + HFIXEDSZ;
eom = (unsigned char *) &answer + ret;
+ if (0 == hp->ad)
+ ad = false;
+
/* skip question part of response -- we know what we asked */
for (qdcount = ntohs((unsigned short) hp->qdcount);
qdcount--;
@@ -977,7 +1492,7 @@ nexttype:
sm_dprintf("qdcount failure (%d)\n",
ntohs((unsigned short) hp->qdcount));
*statp = EX_SOFTWARE;
- return false; /* ???XXX??? */
+ goto error;
}
}
@@ -999,7 +1514,7 @@ nexttype:
{
case T_MX:
gotmx = true;
- if (**dp != '\0' && HasWildcardMX)
+ if (*dp != '\0' && HasWildcardMX)
{
/*
** If we are using MX matches and have
@@ -1009,7 +1524,7 @@ nexttype:
*/
if (trymx && mxmatch == NULL)
- mxmatch = *dp;
+ mxmatch = dp;
continue;
}
@@ -1026,7 +1541,7 @@ nexttype:
# if NETINET6
case T_AAAA:
-# endif /* NETINET6 */
+# endif
case T_A:
/* Flag that a good match was found */
amatch = true;
@@ -1061,7 +1576,7 @@ nexttype:
}
SM_SET_H_ERRNO(NO_RECOVERY);
*statp = EX_CONFIG;
- return false;
+ goto error;
}
/* value points at name */
@@ -1092,7 +1607,7 @@ nexttype:
** exact MX record. Save it and get out of here.
*/
- mxmatch = *dp;
+ mxmatch = dp;
break;
}
@@ -1107,13 +1622,13 @@ nexttype:
if (qtype == T_AAAA)
qtype = T_A;
else
-# endif /* NETINET6 */
- if (qtype == T_A && !gotmx && (trymx || **dp == '\0'))
+# endif
+ if (qtype == T_A && !gotmx && (trymx || *dp == '\0'))
qtype = T_MX;
else
{
qtype = initial;
- dp++;
+ sli++;
}
}
@@ -1122,7 +1637,7 @@ nexttype:
{
if (*statp == EX_OK)
*statp = EX_NOHOST;
- return false;
+ goto error;
}
/*
@@ -1142,6 +1657,16 @@ nexttype:
/* return only one TTL entry, that should be sufficient */
if (ttl > 0 && pttl != NULL)
*pttl = ttl;
- return true;
+# if DANE
+ _res.options = old_options;
+# endif
+ return ad ? HOST_SECURE : HOST_OK;
+
+ error:
+# if DANE
+ _res.options = old_options;
+# endif
+ return HOST_NOTFOUND;
}
+
#endif /* NAMED_BIND */
diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c
index bae6b0010db7..08d48b171e6a 100644
--- a/contrib/sendmail/src/envelope.c
+++ b/contrib/sendmail/src/envelope.c
@@ -105,7 +105,7 @@ newenvelope(e, parent, rpool)
e->e_ctime = curtime();
#if _FFR_SESSID
e->e_sessid = e->e_id;
-#endif /* _FFR_SESSID */
+#endif
if (parent != NULL)
{
e->e_msgpriority = parent->e_msgsize;
@@ -113,7 +113,7 @@ newenvelope(e, parent, rpool)
if (parent->e_sessid != NULL)
e->e_sessid = sm_rpool_strdup_x(rpool,
parent->e_sessid);
-#endif /* _FFR_SESSID */
+#endif
if (parent->e_quarmsg == NULL)
{
@@ -189,7 +189,7 @@ dropenvelope(e, fulldrop, split)
if (tTd(50, 1))
{
- sm_dprintf("dropenvelope %p: id=", e);
+ sm_dprintf("dropenvelope %p: id=", (void *)e);
xputs(sm_debug_file(), e->e_id);
sm_dprintf(", flags=");
printenvflags(e);
@@ -264,7 +264,7 @@ dropenvelope(e, fulldrop, split)
#if _FFR_PROXY
if (queueit && e->e_sendmode == SM_PROXY)
queueit = false;
-#endif /* _FFR_PROXY */
+#endif
/* see if a notification is needed */
if (bitset(QPINGONFAILURE, q->q_flags) &&
@@ -323,7 +323,7 @@ dropenvelope(e, fulldrop, split)
/* don't free, allocated from e_rpool */
e->e_message = sm_rpool_strdup_x(e->e_rpool, buf);
- message(buf);
+ message("%s", buf);
e->e_flags |= EF_CLRQUEUE;
}
if (msg_timeout == MSG_NOT_BY)
@@ -380,7 +380,7 @@ dropenvelope(e, fulldrop, split)
#if _FFR_NODELAYDSN_ON_HOLD
&& !bitnset(M_HOLD,
q->q_mailer->m_flags)
-#endif /* _FFR_NODELAYDSN_ON_HOLD */
+#endif
)
{
if (msg_timeout ==
@@ -420,7 +420,7 @@ dropenvelope(e, fulldrop, split)
/* don't free, allocated from e_rpool */
e->e_message = sm_rpool_strdup_x(e->e_rpool,
buf);
- message(buf);
+ message("%s", buf);
e->e_flags |= EF_WARNING;
}
if (msg_timeout == MSG_WARN_BY)
@@ -446,8 +446,8 @@ dropenvelope(e, fulldrop, split)
failure_return, delay_return, success_return, queueit);
/*
- ** If we had some fatal error, but no addresses are marked as
- ** bad, mark them _all_ as bad.
+ ** If we had some fatal error, but no addresses are marked as bad,
+ ** mark all OK/VERIFIED addresses as bad (if QPINGONFAILURE).
*/
if (bitset(EF_FATALERRS, e->e_flags) && !failure_return)
@@ -455,8 +455,21 @@ dropenvelope(e, fulldrop, split)
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
if ((QS_IS_OK(q->q_state) ||
- QS_IS_VERIFIED(q->q_state)) &&
- bitset(QPINGONFAILURE, q->q_flags))
+ QS_IS_VERIFIED(q->q_state))
+ && bitset(QPINGONFAILURE, q->q_flags)
+
+ /*
+ ** do not mark an address as bad if
+ ** - the address itself is stored in the queue
+ ** - the DeliveryMode requires queueing
+ ** - the envelope is queued
+ */
+
+ && !(bitset(QQUEUED, q->q_flags)
+ && WILL_BE_QUEUED(e->e_sendmode)
+ && bitset(EF_INQUEUE, e->e_flags)
+ )
+ )
{
failure_return = true;
q->q_state = QS_BADADDR;
@@ -737,7 +750,7 @@ clearenvelope(e, fullclear, rpool)
}
#if _FFR_MILTER_ENHSC
e->e_enhsc[0] = '\0';
-#endif /* _FFR_MILTER_ENHSC */
+#endif
}
/*
** INITSYS -- initialize instantiation of system
@@ -878,7 +891,7 @@ settime(e)
#ifndef O_APPEND
# define O_APPEND 0
-#endif /* ! O_APPEND */
+#endif
void
openxscript(e)
@@ -892,7 +905,7 @@ openxscript(e)
#if 0
if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags))
syserr("openxscript: job not locked");
-#endif /* 0 */
+#endif
p = queuename(e, XSCRPT_LETTER);
e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize,
@@ -936,7 +949,7 @@ closexscript(e)
#if 0
if (e->e_lockfp == NULL)
syserr("closexscript: job not locked");
-#endif /* 0 */
+#endif
(void) sm_io_close(e->e_xfp, SM_TIME_DEFAULT);
e->e_xfp = NULL;
}
@@ -1271,8 +1284,6 @@ static struct eflags EnvelopeFlags[] =
{ "LOGSENDER", EF_LOGSENDER },
{ "NORECEIPT", EF_NORECEIPT },
{ "HAS8BIT", EF_HAS8BIT },
- { "NL_NOT_EOL", EF_NL_NOT_EOL },
- { "CRLF_NOT_EOL", EF_CRLF_NOT_EOL },
{ "RET_PARAM", EF_RET_PARAM },
{ "HAS_DF", EF_HAS_DF },
{ "IS_MIME", EF_IS_MIME },
@@ -1281,6 +1292,8 @@ static struct eflags EnvelopeFlags[] =
{ "TOOBIG", EF_TOOBIG },
{ "SPLIT", EF_SPLIT },
{ "UNSAFE", EF_UNSAFE },
+ { "TOODEEP", EF_TOODEEP },
+ { "SECURE", EF_SECURE },
{ NULL, 0 }
};
diff --git a/contrib/sendmail/src/err.c b/contrib/sendmail/src/err.c
index 0594eb9ba16c..8bd02669c5e0 100644
--- a/contrib/sendmail/src/err.c
+++ b/contrib/sendmail/src/err.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2003, 2010 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1998-2003, 2010, 2015 Proofpoint, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -18,7 +18,7 @@ SM_RCSID("@(#)$Id: err.c,v 8.206 2013-11-22 20:51:55 ca Exp $")
#if LDAPMAP
# include <lber.h>
# include <ldap.h> /* for LDAP error codes */
-#endif /* LDAPMAP */
+#endif
static void putoutmsg __P((char *, bool, bool));
static void puterrmsg __P((char *));
@@ -113,7 +113,7 @@ static char HeldMessageBuf[sizeof(MsgBuf)]; /* for held messages */
#if NAMED_BIND && !defined(NO_DATA)
# define NO_DATA NO_ADDRESS
-#endif /* NAMED_BIND && !defined(NO_DATA) */
+#endif
void
/*VARARGS1*/
@@ -224,19 +224,19 @@ syserr(fmt, va_alist)
case ENOTTY:
#ifdef EFBIG
case EFBIG:
-#endif /* EFBIG */
+#endif
#ifdef ESPIPE
case ESPIPE:
-#endif /* ESPIPE */
+#endif
#ifdef EPIPE
case EPIPE:
-#endif /* EPIPE */
+#endif
#ifdef ENOBUFS
case ENOBUFS:
-#endif /* ENOBUFS */
+#endif
#ifdef ESTALE
case ESTALE:
-#endif /* ESTALE */
+#endif
printopenfds(true);
mci_dump_all(smioout, true);
break;
@@ -245,7 +245,7 @@ syserr(fmt, va_alist)
{
#if XLA
xla_all_end();
-#endif /* XLA */
+#endif
sync_queue_time();
if (tTd(0, 1))
abort();
@@ -255,6 +255,7 @@ syserr(fmt, va_alist)
if (QuickAbort)
sm_exc_raisenew_x(&EtypeQuickAbort, 2);
}
+
/*
** USRERR -- Signal user error.
**
@@ -340,6 +341,7 @@ usrerr(fmt, va_alist)
if (QuickAbort)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
}
+
/*
** USRERRENH -- Signal user error.
**
@@ -438,9 +440,6 @@ usrerrenh(enhsc, fmt, va_alist)
**
** Returns:
** none
-**
-** Side Effects:
-** none.
*/
/*VARARGS1*/
@@ -493,9 +492,6 @@ message(msg, va_alist)
**
** Returns:
** none
-**
-** Side Effects:
-** none.
*/
/*VARARGS3*/
@@ -595,9 +591,6 @@ extsc(msg, delim, replycode, enhsc)
**
** Returns:
** none
-**
-** Side Effects:
-** none.
*/
/*VARARGS1*/
@@ -636,6 +629,7 @@ nmessage(msg, va_alist)
break;
}
}
+
/*
** PUTOUTMSG -- output error message to transcript and channel
**
@@ -761,6 +755,7 @@ putoutmsg(msg, holdmsg, heldmsg)
shortenstring(msg, MAXSHORTSTR), sm_errstring(errno));
#endif /* !PIPELINING */
}
+
/*
** PUTERRMSG -- like putoutmsg, but does special processing for error messages
**
@@ -804,6 +799,7 @@ puterrmsg(msg)
CurEnv->e_flags |= EF_FATALERRS;
}
}
+
/*
** ISENHSC -- check whether a string contains an enhanced status code
**
@@ -814,10 +810,8 @@ puterrmsg(msg)
** Returns:
** 0 -- no enhanced status code.
** >4 -- length of enhanced status code.
-**
-** Side Effects:
-** none.
*/
+
int
isenhsc(s, delim)
const char *s;
@@ -843,6 +837,7 @@ isenhsc(s, delim)
return 0;
return l + h;
}
+
/*
** EXTENHSC -- check and extract an enhanced status code
**
@@ -897,6 +892,7 @@ extenhsc(s, delim, e)
e[l + h] = '\0';
return l + h;
}
+
/*
** FMTMSG -- format a message into buffer.
**
@@ -906,14 +902,15 @@ extenhsc(s, delim, e)
** num -- default three digit SMTP reply code.
** enhsc -- enhanced status code.
** en -- the error number to display.
-** fmt -- format of string.
+** fmt -- format of string: See NOTE below.
** ap -- arguments for fmt.
**
** Returns:
** pointer to error text beyond status codes.
**
-** Side Effects:
-** none.
+** NOTE:
+** Do NOT use "%s" as fmt if the argument starts with an SMTP
+** reply code!
*/
static char *
@@ -1010,15 +1007,23 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap)
(void) sm_strlcpyn(eb, spaceleft, 2,
shortenstring(to, MAXSHORTSTR), "... ");
spaceleft -= strlen(eb);
+#if _FFR_EAI
+ eb += strlen(eb);
+#else
while (*eb != '\0')
*eb++ &= 0177;
+#endif
}
/* output the message */
(void) sm_vsnprintf(eb, spaceleft, fmt, ap);
spaceleft -= strlen(eb);
+#if _FFR_EAI
+ eb += strlen(eb);
+#else
while (*eb != '\0')
*eb++ &= 0177;
+#endif
/* output the error code, if any */
if (eno != 0)
@@ -1026,6 +1031,7 @@ fmtmsg(eb, to, num, enhsc, eno, fmt, ap)
return errtxt;
}
+
/*
** BUFFER_ERRORS -- arrange to buffer future error messages
**
@@ -1042,6 +1048,7 @@ buffer_errors()
HeldMessageBuf[0] = '\0';
HoldErrs = true;
}
+
/*
** FLUSH_ERRORS -- flush the held error message buffer
**
@@ -1070,9 +1077,6 @@ flush_errors(print)
**
** Returns:
** A string description of errnum.
-**
-** Side Effects:
-** none.
*/
const char *
@@ -1085,11 +1089,11 @@ sm_errstring(errnum)
#if HASSTRERROR
char *err;
char errbuf[30];
-#endif /* HASSTRERROR */
+#endif
#if !HASSTRERROR && !defined(ERRLIST_PREDEFINED)
extern char *sys_errlist[];
extern int sys_nerr;
-#endif /* !HASSTRERROR && !defined(ERRLIST_PREDEFINED) */
+#endif
/*
** Handle special network error codes.
@@ -1242,7 +1246,7 @@ sm_errstring(errnum)
#if LDAPMAP
if (errnum >= E_LDAPBASE - E_LDAP_SHIM)
return ldap_err2string(errnum - E_LDAPBASE);
-#endif /* LDAPMAP */
+#endif
#if HASSTRERROR
err = strerror(errnum);
diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c
index 0af72436f7f2..da84a8009328 100644
--- a/contrib/sendmail/src/headers.c
+++ b/contrib/sendmail/src/headers.c
@@ -174,7 +174,7 @@ dochompheader(line, pflag, hdrp, e)
while (isascii(*p) && isgraph(*p) && *p != ':')
p++;
fvalue = p;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p++ != ':' || fname == fvalue)
{
@@ -186,7 +186,7 @@ hse:
fvalue = p;
/* if the field is null, go ahead and use the default */
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
nullheader = true;
@@ -201,7 +201,7 @@ hse:
char hbuf[50];
(void) expand(fvalue, hbuf, sizeof(hbuf), e);
- for (p = hbuf; isascii(*p) && isspace(*p); )
+ for (p = hbuf; SM_ISSPACE(*p); )
p++;
if ((*p++ & 0377) == CALLSUBR)
{
@@ -735,7 +735,7 @@ hvalue(field, header)
s = h->h_value;
if (s == NULL)
return NULL;
- while (isascii(*s) && isspace(*s))
+ while (SM_ISSPACE(*s))
s++;
return s;
}
@@ -783,7 +783,7 @@ isheader(h)
return false;
/* following technically violates RFC822 */
- while (isascii(*s) && isspace(*s))
+ while (SM_ISSPACE(*s))
s++;
return (*s == ':');
@@ -900,7 +900,7 @@ eatheader(e, full, log)
{
#if 0
int saveflags = e->e_flags;
-#endif /* 0 */
+#endif
(void) sendtolist(denlstring(h->h_value, true, false),
NULLADDR, &e->e_sendqueue, 0, e);
@@ -1119,24 +1119,7 @@ logsender(e, msgid)
register char *sbp;
register char *p;
char hbuf[MAXNAME + 1];
- char sbuf[MAXLINE + 1];
- char mbuf[MAXNAME + 1];
-
- /* don't allow newlines in the message-id */
- /* XXX do we still need this? sm_syslog() replaces control chars */
- if (msgid != NULL)
- {
- size_t l;
-
- l = strlen(msgid);
- if (l > sizeof(mbuf) - 1)
- l = sizeof(mbuf) - 1;
- memmove(mbuf, msgid, l);
- mbuf[l] = '\0';
- p = mbuf;
- while ((p = strchr(p, '\n')) != NULL)
- *p++ = ' ';
- }
+ char sbuf[MAXLINE + 1]; /* XREF: see below MSGIDLOGLEN */
if (bitset(EF_RESPONSE, e->e_flags))
name = "[RESPONSE]";
@@ -1160,7 +1143,6 @@ logsender(e, msgid)
}
}
- /* some versions of syslog only take 5 printf args */
#if (SYSLOG_BUFSIZE) >= 256
sbp = sbuf;
(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
@@ -1170,8 +1152,29 @@ logsender(e, msgid)
sbp += strlen(sbp);
if (msgid != NULL)
{
+
+#ifndef MSGIDLOGLEN
+# define MSGIDLOGLEN 100
+# define FIRSTLOGLEN 850
+# else
+# if MSGIDLOGLEN < 100
+ ERROR MSGIDLOGLEN too short
+# endif
+/* XREF: this is "sizeof(sbuf)", see above */
+# if MSGIDLOGLEN >= MAXLINE / 2
+ ERROR MSGIDLOGLEN too long
+# endif
+
+/* 850 - 100 for original MSGIDLOGLEN */
+# define FIRSTLOGLEN (750 + MSGIDLOGLEN)
+
+/* check that total length is ok */
+# if FIRSTLOGLEN + 200 >= MAXLINE
+ ERROR MSGIDLOGLEN too long
+# endif
+#endif
(void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp),
- ", msgid=%.100s", mbuf);
+ ", msgid=%.*s", MSGIDLOGLEN, msgid);
sbp += strlen(sbp);
}
if (e->e_bodytype != NULL)
@@ -1195,13 +1198,7 @@ logsender(e, msgid)
sbp += strlen(sbp);
}
# if _FFR_LOG_MORE1
-# if STARTTLS
- p = macvalue(macid("{verify}"), e);
- if (p == NULL || *p == '\0')
- p = "NONE";
- (void) sm_snprintf(sbp, SPACELEFT(sbuf, sbp), ", tls_verify=%.20s", p);
- sbp += strlen(sbp);
-# endif /* STARTTLS */
+ LOG_MORE(sbuf, sbp);
# if SASL
p = macvalue(macid("{auth_type}"), e);
if (p == NULL || *p == '\0')
@@ -1210,7 +1207,7 @@ logsender(e, msgid)
sbp += strlen(sbp);
# endif /* SASL */
# endif /* _FFR_LOG_MORE1 */
- sm_syslog(LOG_INFO, e->e_id, "%.850s, relay=%s", sbuf, name);
+ sm_syslog(LOG_INFO, e->e_id, "%.*s, relay=%s", FIRSTLOGLEN, sbuf, name);
#else /* (SYSLOG_BUFSIZE) >= 256 */
@@ -1225,7 +1222,7 @@ logsender(e, msgid)
if (msgid != NULL)
sm_syslog(LOG_INFO, e->e_id,
"msgid=%s",
- shortenstring(mbuf, 83));
+ shortenstring(msgid, 83));
sbp = sbuf;
*sbp = '\0';
if (e->e_bodytype != NULL)
@@ -1326,7 +1323,7 @@ priencode(p)
#if MAXNAME < 10
ERROR MAXNAME must be at least 10
-#endif /* MAXNAME < 10 */
+#endif
char *
crackaddr(addr, e)
@@ -1361,7 +1358,7 @@ crackaddr(addr, e)
bp = bufhead = buf;
/* skip over leading spaces but preserve them */
- while (*addr != '\0' && isascii(*addr) && isspace(*addr))
+ while (*addr != '\0' && SM_ISSPACE(*addr))
{
SM_APPEND_CHAR(*addr);
addr++;
@@ -1527,7 +1524,7 @@ crackaddr(addr, e)
}
/* any trailing white space is part of group: */
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
{
SM_APPEND_CHAR(*p);
p++;
@@ -1879,7 +1876,7 @@ putheader(mci, hdr, e, flags)
}
}
- if (bitset(H_BCC, h->h_flags))
+ if (bitset(H_BCC, h->h_flags) && !KeepBcc)
{
/* Bcc: field -- either truncate or delete */
if (bitset(EF_DELETE_BCC, e->e_flags))
@@ -2067,7 +2064,7 @@ commaize(h, p, oldstyle, mci, e, putflags)
obp += opos;
spaces = 0;
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
{
++spaces;
++p;
@@ -2116,7 +2113,7 @@ commaize(h, p, oldstyle, mci, e, putflags)
*/
/* find end of name */
- while ((isascii(*p) && isspace(*p)) || *p == ',')
+ while ((SM_ISSPACE(*p)) || *p == ',')
p++;
name = p;
res = NULL;
@@ -2138,7 +2135,7 @@ commaize(h, p, oldstyle, mci, e, putflags)
#endif /* _FFR_IGNORE_BOGUS_ADDR */
/* look to see if we have an at sign */
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
if (*p != '@')
@@ -2147,14 +2144,14 @@ commaize(h, p, oldstyle, mci, e, putflags)
break;
}
++p;
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
}
/* at the end of one complete name */
/* strip off trailing white space */
while (p >= name &&
- ((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
+ ((SM_ISSPACE(*p)) || *p == ',' || *p == '\0'))
p--;
if (++p == name)
continue;
@@ -2165,7 +2162,7 @@ commaize(h, p, oldstyle, mci, e, putflags)
*/
if (res == NULL && p > name &&
- !((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0'))
+ !((SM_ISSPACE(*p)) || *p == ',' || *p == '\0'))
--p;
savechar = *p;
*p = '\0';
diff --git a/contrib/sendmail/src/macro.c b/contrib/sendmail/src/macro.c
index cb7daf8cf690..83438563151b 100644
--- a/contrib/sendmail/src/macro.c
+++ b/contrib/sendmail/src/macro.c
@@ -18,7 +18,7 @@ SM_RCSID("@(#)$Id: macro.c,v 8.108 2013-11-22 20:51:55 ca Exp $")
#include <sm/sendmail.h>
#if MAXMACROID != (BITMAPBITS - 1)
ERROR Read the comment in conf.h
-#endif /* MAXMACROID != (BITMAPBITS - 1) */
+#endif
static char *MacroName[MAXMACROID + 1]; /* macro id to name table */
@@ -362,6 +362,33 @@ expand(s, buf, bufsize, e)
}
/*
+** MACTABCLEAR -- clear entire macro table
+**
+** Parameters:
+** mac -- Macro table.
+**
+** Returns:
+** none.
+**
+** Side Effects:
+** clears entire mac structure including rpool pointer!
+*/
+
+void
+mactabclear(mac)
+ MACROS_T *mac;
+{
+ int i;
+
+ if (mac->mac_rpool == NULL)
+ {
+ for (i = 0; i < MAXMACROID; i++)
+ SM_FREE(mac->mac_table[i]);
+ }
+ memset((char *) mac, '\0', sizeof(*mac));
+}
+
+/*
** MACDEFINE -- bind a macro name to a value
**
** Set a macro to a value, with fancy storage management.
@@ -439,9 +466,9 @@ macdefine(mac, vclass, id, value)
{
#if SM_HEAP_CHECK
newvalue = sm_strdup_tagged_x(value, file, line, 0);
-#else /* SM_HEAP_CHECK */
+#else
newvalue = sm_strdup_x(value);
-#endif /* SM_HEAP_CHECK */
+#endif
setbitn(id, mac->mac_allocated);
}
mac->mac_table[id] = newvalue;
@@ -539,6 +566,15 @@ macvalue(n, e)
break;
e = e->e_parent;
}
+#if _FFR_BLANKENV_MACV
+ if (LOOKUP_MACRO_IN_BLANKENV && e != &BlankEnvelope)
+ {
+ char *p = BlankEnvelope.e_macro.mac_table[n];
+
+ if (p != NULL)
+ return p;
+ }
+#endif
return GlobalMacros.mac_table[n];
}
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c
index 38eebbfe2945..a79733448039 100644
--- a/contrib/sendmail/src/main.c
+++ b/contrib/sendmail/src/main.c
@@ -16,6 +16,7 @@
#include <sm/sendmail.h>
#include <sm/xtrap.h>
#include <sm/signal.h>
+#include <tls.h>
#ifndef lint
SM_UNUSED(static char copyright[]) =
@@ -31,10 +32,14 @@ SM_RCSID("@(#)$Id: main.c,v 8.988 2013-11-23 02:52:37 gshapiro Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+# if DANE
+# include "sm_resolve.h"
+# endif
+#endif
/* for getcfname() */
#include <sendmail/pathnames.h>
+#include <ratectrl.h>
static SM_DEBUG_T
DebugNoPRestart = SM_DEBUG_INITIALIZER("no_persistent_restart",
@@ -51,7 +56,7 @@ static SIGFUNC_DECL sigpipe __P((int));
static SIGFUNC_DECL sigterm __P((int));
#ifdef SIGUSR1
static SIGFUNC_DECL sigusr1 __P((int));
-#endif /* SIGUSR1 */
+#endif
/*
** SENDMAIL -- Post mail to a set of destinations.
@@ -104,7 +109,7 @@ char *Mbdb = "pw"; /* mailbox database defaults to /etc/passwd */
#ifdef NGROUPS_MAX
GIDSET_T InitialGidSet[NGROUPS_MAX];
-#endif /* NGROUPS_MAX */
+#endif
#define MAXCONFIGLEVEL 10 /* highest config version level known */
@@ -122,7 +127,7 @@ int SyslogPrefixLen; /* estimated length of syslog prefix */
#define PIDLEN 6 /* pid length for computing SyslogPrefixLen */
#ifndef SL_FUDGE
# define SL_FUDGE 10 /* fudge offset for SyslogPrefixLen */
-#endif /* ! SL_FUDGE */
+#endif
#define SLDLL 8 /* est. length of default syslog label */
@@ -194,7 +199,7 @@ main(argc, argv, envp)
char *emptyenviron[1];
#if STARTTLS
bool tls_ok;
-#endif /* STARTTLS */
+#endif
QUEUE_CHAR *new;
ENVELOPE *e;
extern int DtableSize;
@@ -204,11 +209,11 @@ main(argc, argv, envp)
extern char **environ;
#if SASL
extern void sm_sasl_init __P((void));
-#endif /* SASL */
+#endif
#if USE_ENVIRON
envp = environ;
-#endif /* USE_ENVIRON */
+#endif
/* turn off profiling */
SM_PROF(0);
@@ -277,12 +282,12 @@ main(argc, argv, envp)
#if LOG
# ifndef SM_LOG_STR
# define SM_LOG_STR "sendmail"
-# endif /* ! SM_LOG_STR */
-# ifdef LOG_MAIL
+# endif
+# ifdef LOG_MAIL
openlog(SM_LOG_STR, LOG_PID, LOG_MAIL);
-# else /* LOG_MAIL */
+# else
openlog(SM_LOG_STR, LOG_PID);
-# endif /* LOG_MAIL */
+# endif
#endif /* LOG */
/*
@@ -308,11 +313,11 @@ main(argc, argv, envp)
LocalDaemon = false;
# if NETINET6
V6LoopbackAddrFound = false;
-# endif /* NETINET6 */
-#endif /* _FFR_LOCAL_DAEMON */
+# endif
+#endif
#if XDEBUG
checkfd012("after openlog");
-#endif /* XDEBUG */
+#endif
tTsetup(tTdvect, sizeof(tTdvect), "0-99.1,*_trace_*.1");
@@ -382,7 +387,7 @@ main(argc, argv, envp)
#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 */
+#endif
/* Set to 0 to allow -b; need to check optarg before using it! */
opterr = 0;
@@ -507,11 +512,11 @@ main(argc, argv, envp)
*p = '*';
}
closelog();
-# ifdef LOG_MAIL
+# ifdef LOG_MAIL
openlog(sysloglabel, LOG_PID, LOG_MAIL);
-# else /* LOG_MAIL */
+# else
openlog(sysloglabel, LOG_PID);
-# endif /* LOG_MAIL */
+# endif
}
#endif /* LOG */
@@ -616,7 +621,7 @@ main(argc, argv, envp)
sm_printoptions(OsCompileOptions);
#ifdef _PATH_UNIX
sm_dprintf("Kernel symbols:\t%s\n", _PATH_UNIX);
-#endif /* _PATH_UNIX */
+#endif
sm_dprintf(" Conf file:\t%s (default for MSP)\n",
getcfname(OpMode, SubmitMode, SM_GET_SUBMIT_CF,
@@ -650,7 +655,7 @@ main(argc, argv, envp)
sm_dprintf(" OpenSSL: compiled 0x%08x\n",
(uint) OPENSSL_VERSION_NUMBER);
sm_dprintf(" OpenSSL: linked 0x%08x\n",
- (uint) SSLeay());
+ (uint) TLS_version_num());
}
#endif /* STARTTLS */
@@ -700,7 +705,7 @@ main(argc, argv, envp)
_res.options &= ~RES_DEBUG;
# ifdef RES_NOALIASES
_res.options |= RES_NOALIASES;
-# endif /* RES_NOALIASES */
+# endif
TimeOuts.res_retry[RES_TO_DEFAULT] = _res.retry;
TimeOuts.res_retry[RES_TO_FIRST] = _res.retry;
TimeOuts.res_retry[RES_TO_NORMAL] = _res.retry;
@@ -768,7 +773,7 @@ main(argc, argv, envp)
# endif /* NETINET6 */
# if NETINET
struct in_addr ia;
-# endif /* NETINET */
+# endif
char ipbuf[103];
ipbuf[0] = '\0';
@@ -809,7 +814,7 @@ main(argc, argv, envp)
#if NETINET6
freehostent(hp);
hp = NULL;
-#endif /* NETINET6 */
+#endif
}
/* current time */
@@ -1193,7 +1198,7 @@ main(argc, argv, envp)
#if defined(__osf__) || defined(_AIX3)
case 'x': /* random flag that OSF/1 & AIX mailx passes */
break;
-#endif /* defined(__osf__) || defined(_AIX3) */
+#endif
#if defined(sony_news)
case 'E':
case 'J': /* ignore flags for Japanese code conversion
@@ -1241,14 +1246,14 @@ main(argc, argv, envp)
#if XDEBUG
checkfd012("before readcf");
-#endif /* XDEBUG */
+#endif
vendor_pre_defaults(&BlankEnvelope);
readcf(getcfname(OpMode, SubmitMode, cftype, conffile),
safecf, &BlankEnvelope);
#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
ConfigFileRead = true;
-#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
+#endif
vendor_post_defaults(&BlankEnvelope);
/* now we can complain about missing fds */
@@ -1320,7 +1325,7 @@ main(argc, argv, envp)
#if NAMED_BIND
if (FallbackMX != NULL)
(void) getfallbackmxrr(FallbackMX);
-#endif /* NAMED_BIND */
+#endif
if (SuperSafe == SAFE_INTERACTIVE && !SM_IS_INTERACTIVE(CurEnv->e_sendmode))
{
@@ -1391,7 +1396,7 @@ main(argc, argv, envp)
#if NAMED_BIND
_res.retry = TimeOuts.res_retry[RES_TO_DEFAULT];
_res.retrans = TimeOuts.res_retrans[RES_TO_DEFAULT];
-#endif /* NAMED_BIND */
+#endif
/*
** Find our real host name for future logging.
@@ -1854,6 +1859,9 @@ main(argc, argv, envp)
/* MIME message/xxx subtypes that can be treated as messages */
setclass('s', "rfc822");
+#if _FFR_EAI
+ setclass('s', "global");
+#endif
/* MIME Content-Transfer-Encodings that can be encoded */
setclass('e', "7bit");
@@ -1964,11 +1972,11 @@ main(argc, argv, envp)
#if SASL
/* sendmail specific SASL initialization */
sm_sasl_init();
-#endif /* SASL */
+#endif
#if XDEBUG
checkfd012("before main() initmaps");
-#endif /* XDEBUG */
+#endif
/*
** Do operation-mode-dependent initialization.
@@ -1983,8 +1991,6 @@ main(argc, argv, envp)
(void) sm_signal(SIGPIPE, sigpipe);
if (qgrp != NOQGRP)
{
- int j;
-
/* Selecting a particular queue group to run */
for (j = 0; j < Queue[qgrp]->qg_numqueues; j++)
{
@@ -2164,13 +2170,15 @@ main(argc, argv, envp)
if (tls_ok)
{
/* basic TLS initialization */
- tls_ok = init_tls_library(FipsMode);
- if (!tls_ok && FipsMode)
+ j = init_tls_library(FipsMode);
+ if (j < 0)
{
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
- "ERROR: FIPSMode failed to initialize\n");
+ "ERROR: TLS failed to initialize\n");
exit(EX_USAGE);
}
+ if (j > 0)
+ tls_ok = false;
}
if (!tls_ok && (OpMode == MD_QUEUERUN || OpMode == MD_DELIVER))
@@ -2191,7 +2199,7 @@ main(argc, argv, envp)
#if STARTTLS
/* init TLS for client, ignore result for now */
(void) initclttls(tls_ok);
-#endif /* STARTTLS */
+#endif
/*
** The parent process of the caller of runqueue() needs
@@ -2295,7 +2303,7 @@ main(argc, argv, envp)
/* NOTREACHED */
}
-# if SASL
+#if SASL
if (OpMode == MD_SMTP || OpMode == MD_DAEMON)
{
/* check whether AUTH is turned off for the server */
@@ -2304,7 +2312,7 @@ main(argc, argv, envp)
syserr("!sasl_server_init failed! [%s]",
sasl_errstring(i, NULL, NULL));
}
-# endif /* SASL */
+#endif /* SASL */
if (OpMode == MD_SMTP)
{
@@ -2382,7 +2390,7 @@ main(argc, argv, envp)
"starting daemon (%s): %s", Version, dtype + 1);
#if XLA
xla_create_file();
-#endif /* XLA */
+#endif
/* save daemon type in a macro for possible PidFile use */
macdefine(&BlankEnvelope.e_macro, A_TEMP,
@@ -2562,7 +2570,7 @@ main(argc, argv, envp)
#if STARTTLS
/* init TLS for server, ignore result for now */
(void) initsrvtls(tls_ok);
-#endif /* STARTTLS */
+#endif
nextreq:
p_flags = getrequests(&MainEnvelope);
@@ -2623,8 +2631,19 @@ main(argc, argv, envp)
if (LogLevel > 9)
{
+ p = authinfo;
+ if (NULL == p)
+ {
+ if (NULL != RealHostName)
+ p = RealHostName;
+ else
+ p = anynet_ntoa(&RealHostAddr);
+ if (NULL == p)
+ p = "unknown";
+ }
+
/* log connection information */
- sm_syslog(LOG_INFO, NULL, "connect from %s", authinfo);
+ sm_syslog(LOG_INFO, NULL, "connect from %s", p);
}
/*
@@ -2704,7 +2723,7 @@ main(argc, argv, envp)
#if STARTTLS
if (OpMode == MD_SMTP)
(void) initsrvtls(tls_ok);
-#endif /* STARTTLS */
+#endif
/* turn off profiling */
SM_PROF(1);
@@ -2748,7 +2767,7 @@ main(argc, argv, envp)
RealUserName, from, warn_f_flag);
#if SASL
auth = false;
-#endif /* SASL */
+#endif
}
if (auth)
{
@@ -2927,7 +2946,7 @@ main(argc, argv, envp)
#if NAMED_BIND
_res.retry = TimeOuts.res_retry[RES_TO_FIRST];
_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
-#endif /* NAMED_BIND */
+#endif
next = e->e_sibling;
e->e_sibling = NULL;
@@ -2994,6 +3013,17 @@ finis(drop, cleanup, exitstat)
sm_clear_events();
(void) sm_releasesignal(SIGALRM);
+#if RATECTL_DEBUG || _FFR_OCC
+ /* do this only in "main" process */
+ if (DaemonPid == getpid())
+ {
+ SM_FILE_T *fp;
+
+ fp = sm_debug_file();
+ if (fp != NULL)
+ dump_ch(fp);
+ }
+#endif
if (tTd(2, 1))
{
sm_dprintf("\n====finis: stat %d e_id=%s e_flags=",
@@ -3046,16 +3076,16 @@ finis(drop, cleanup, exitstat)
#if USERDB
/* close UserDatabase */
_udbx_close();
-#endif /* USERDB */
+#endif
#if SASL
stop_sasl_client();
-#endif /* SASL */
+#endif
#if XLA
/* clean up extended load average stuff */
xla_all_end();
-#endif /* XLA */
+#endif
SM_FINALLY
/*
@@ -3074,7 +3104,7 @@ finis(drop, cleanup, exitstat)
pid = getpid();
#if SM_CONF_SHM
cleanup_shm(DaemonPid == pid);
-#endif /* SM_CONF_SHM */
+#endif
/* close locked pid file */
close_sendmail_pid();
@@ -3091,14 +3121,14 @@ finis(drop, cleanup, exitstat)
sm_mbdb_terminate();
#if _FFR_MEMSTAT
(void) sm_memstat_close();
-#endif /* _FFR_MEMSTAT */
+#endif
(void) setuid(RealUid);
#if SM_HEAP_CHECK
/* dump the heap, if we are checking for memory leaks */
if (sm_debug_active(&SmHeapCheck, 2))
sm_heap_report(smioout,
sm_debug_level(&SmHeapCheck) - 1);
-#endif /* SM_HEAP_CHECK */
+#endif
if (sm_debug_active(&SmXtrapReport, 1))
sm_dprintf("xtrap count = %d\n", SmXtrapCount);
if (cleanup)
@@ -3333,7 +3363,8 @@ disconnect(droplev, e)
if (tTd(52, 1))
sm_dprintf("disconnect: In %d Out %d, e=%p\n",
sm_io_getinfo(InChannel, SM_IO_WHAT_FD, NULL),
- sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL), e);
+ sm_io_getinfo(OutChannel, SM_IO_WHAT_FD, NULL),
+ (void *)e);
if (tTd(52, 100))
{
sm_dprintf("don't\n");
@@ -3422,7 +3453,7 @@ disconnect(droplev, e)
#if XDEBUG
checkfd012("disconnect");
-#endif /* XDEBUG */
+#endif
if (LogLevel > 71)
sm_syslog(LOG_DEBUG, e->e_id, "in background, pid=%d",
@@ -3460,7 +3491,7 @@ obsolete(argv)
ap[1] != 'd' &&
#if defined(sony_news)
ap[1] != 'E' && ap[1] != 'J' &&
-#endif /* defined(sony_news) */
+#endif
argv[1] != NULL && argv[1][0] != '-')
{
argv++;
@@ -3711,7 +3742,7 @@ sigusr1(sig)
dumpstate("user signal");
# if SM_HEAP_CHECK
dumpstab();
-# endif /* SM_HEAP_CHECK */
+# endif
errno = save_errno;
return SIGFUNC_RETURN;
}
@@ -4156,10 +4187,10 @@ testmodeline(line, e)
register char *wd;
char delim;
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
wd = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
delim = *p;
*p = '\0';
@@ -4286,12 +4317,12 @@ testmodeline(line, e)
case '/': /* miscellaneous commands */
p = &line[strlen(line)];
- while (--p >= line && isascii(*p) && isspace(*p))
+ while (--p >= line && SM_ISSPACE(*p))
*p = '\0';
p = strpbrk(line, " \t");
if (p != NULL)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
*p++ = '\0';
}
else
@@ -4322,11 +4353,16 @@ testmodeline(line, e)
"Usage: /mx address\n");
return;
}
- nmx = getmxrr(p, mxhosts, NULL, false, &rcode, true,
- NULL);
- (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
- "getmxrr(%s) returns %d value(s):\n",
- p, nmx);
+ nmx = getmxrr(p, mxhosts, NULL, TRYFALLBACK, &rcode,
+ NULL, -1);
+ if (nmx == NULLMX)
+ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "getmxrr(%s) returns null MX (See RFC7505)\n",
+ p);
+ else
+ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
+ "getmxrr(%s) returns %d value(s):\n",
+ p, nmx);
for (i = 0; i < nmx; i++)
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"\t%s\n", mxhosts[i]);
@@ -4368,7 +4404,7 @@ testmodeline(line, e)
"Usage: /map mapname key\n");
return;
}
- for (q = p; *q != '\0' && !(isascii(*q) && isspace(*q)); q++)
+ for (q = p; *q != '\0' && !(SM_ISSPACE(*q)); q++)
continue;
if (*q == '\0')
{
@@ -4415,7 +4451,7 @@ testmodeline(line, e)
q = strpbrk(p, " \t");
if (q != NULL)
{
- while (isascii(*q) && isspace(*q))
+ while (SM_ISSPACE(*q))
*q++ = '\0';
}
if (q == NULL || *q == '\0')
@@ -4535,7 +4571,7 @@ testmodeline(line, e)
q = strpbrk(p, " \t");
if (q != NULL)
{
- while (isascii(*q) && isspace(*q))
+ while (SM_ISSPACE(*q))
*q++ = '\0';
# if NETINET6
if (*q != '\0' && (strcmp(q, "inet6") == 0 ||
@@ -4546,6 +4582,58 @@ testmodeline(line, e)
(void) sm_gethostbyname(p, family);
}
#endif /* NETINET || NETINET6 */
+#if DANE
+ else if (sm_strcasecmp(&line[1], "dnslookup") == 0)
+ {
+ DNS_REPLY_T *r;
+ int rr_type, family;
+ unsigned int flags;
+
+ rr_type = T_A;
+ family = AF_INET;
+ flags = RR_AS_TEXT;
+ q = strpbrk(p, " \t");
+ if (q != NULL)
+ {
+ char *pflags;
+
+ while (SM_ISSPACE(*q))
+ *q++ = '\0';
+ pflags = strpbrk(q, " \t");
+ if (pflags != NULL)
+ {
+ while (SM_ISSPACE(*pflags))
+ *pflags++ = '\0';
+ }
+ rr_type = dns_string_to_type(q);
+ if (rr_type == T_A)
+ family = AF_INET;
+# if NETINET6
+ if (rr_type == T_AAAA)
+ family = AF_INET6;
+# endif
+ while (pflags != NULL && *pflags != '\0' &&
+ !SM_ISSPACE(*pflags))
+ {
+ if (*pflags == 'c')
+ flags |= RR_NO_CNAME;
+ else if (*pflags == 'o')
+ flags |= RR_ONLY_CNAME;
+ else if (*pflags == 'T')
+ flags &= ~RR_AS_TEXT;
+ ++pflags;
+ }
+ }
+ r = dns_lookup_int(p, C_IN, rr_type,
+ 0, 0, 0, flags, NULL, NULL);
+ if (r != NULL && family >= 0)
+ {
+ (void) dns2he(r, family);
+ dns_free_data(r);
+ r = NULL;
+ }
+ }
+#endif /* DANE */
else
{
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
@@ -4556,10 +4644,10 @@ testmodeline(line, e)
return;
}
- for (p = line; isascii(*p) && isspace(*p); p++)
+ for (p = line; SM_ISSPACE(*p); p++)
continue;
q = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p == '\0')
{
diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c
index 2cc283e5f52c..0931ea69235b 100644
--- a/contrib/sendmail/src/map.c
+++ b/contrib/sendmail/src/map.c
@@ -17,7 +17,7 @@ SM_RCSID("@(#)$Id: map.c,v 8.713 2013-11-22 20:51:55 ca Exp $")
#if LDAPMAP
# include <sm/ldap.h>
-#endif /* LDAPMAP */
+#endif
#if NDBM
# include <ndbm.h>
@@ -30,43 +30,46 @@ SM_RCSID("@(#)$Id: map.c,v 8.713 2013-11-22 20:51:55 ca Exp $")
#endif /* NDBM */
#if NEWDB
# include "sm/bdb.h"
-#endif /* NEWDB */
+#endif
#if NIS
struct dom_binding; /* forward reference needed on IRIX */
# include <rpcsvc/ypclnt.h>
# if NDBM
# define NDBM_YP_COMPAT /* create YP-compatible NDBM files */
-# endif /* NDBM */
+# endif
#endif /* NIS */
+#if CDB
+# include <cdb.h>
+#endif
#include "map.h"
#if NEWDB
# if DB_VERSION_MAJOR < 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, const void *));
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, DB_INFO *));
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
static bool db_map_open __P((MAP *, int, char *, DBTYPE, void **));
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
#endif /* NEWDB */
static bool extract_canonname __P((char *, char *, char *, char[], int));
static void map_close __P((STAB *, int));
static void map_init __P((STAB *, int));
#ifdef LDAPMAP
static STAB * ldapmap_findconn __P((SM_LDAP_STRUCT *));
-#endif /* LDAPMAP */
+#endif
#if NISPLUS
static bool nisplus_getcanonname __P((char *, int, int *));
-#endif /* NISPLUS */
+#endif
#if NIS
static bool nis_getcanonname __P((char *, int, int *));
-#endif /* NIS */
+#endif
#if NETINFO
static bool ni_getcanonname __P((char *, int, int *));
-#endif /* NETINFO */
+#endif
static bool text_getcanonname __P((char *, int, int *));
#if SOCKETMAP
static STAB *socket_map_findconn __P((const char*));
@@ -81,9 +84,9 @@ static STAB *socket_map_findconn __P((const char*));
#else /* ENOSYS */
# ifdef EFTYPE
# define SM_EMAPCANTWRITE EFTYPE
-# else /* EFTYPE */
+# else
# define SM_EMAPCANTWRITE ENXIO
-# endif /* EFTYPE */
+# endif
#endif /* ENOSYS */
/*
@@ -128,9 +131,9 @@ static STAB *socket_map_findconn __P((const char*));
#if O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL
# define LOCK_ON_OPEN 1 /* we can open/create a locked file */
-#else /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
+#else
# define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */
-#endif /* O_EXLOCK && HASFLOCK && !BOGUS_O_EXCL */
+#endif
/*
** MAP_PARSEARGS -- parse config line arguments for database lookup
@@ -165,45 +168,24 @@ map_parseargs(map, ap)
map->map_spacesub = SpaceSub; /* default value */
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
switch (*++p)
{
- case 'N':
- map->map_mflags |= MF_INCLNULL;
- map->map_mflags &= ~MF_TRY0NULL;
- break;
-
- case 'O':
- map->map_mflags &= ~MF_TRY1NULL;
- break;
-
- case 'o':
- map->map_mflags |= MF_OPTIONAL;
- break;
-
- case 'f':
- map->map_mflags |= MF_NOFOLDCASE;
- break;
-
- case 'm':
- map->map_mflags |= MF_MATCHONLY;
- break;
-
case 'A':
map->map_mflags |= MF_APPEND;
break;
- case 'q':
- map->map_mflags |= MF_KEEPQUOTES;
- break;
-
case 'a':
map->map_app = ++p;
break;
+ case 'D':
+ map->map_mflags |= MF_DEFER;
+ break;
+
case 'd':
{
char *h;
@@ -218,8 +200,8 @@ map_parseargs(map, ap)
}
break;
- case 'T':
- map->map_tapp = ++p;
+ case 'f':
+ map->map_mflags |= MF_NOFOLDCASE;
break;
case 'k':
@@ -228,6 +210,39 @@ map_parseargs(map, ap)
map->map_keycolnm = p;
break;
+ case 'm':
+ map->map_mflags |= MF_MATCHONLY;
+ break;
+
+ case 'N':
+ map->map_mflags |= MF_INCLNULL;
+ map->map_mflags &= ~MF_TRY0NULL;
+ break;
+
+ case 'O':
+ map->map_mflags &= ~MF_TRY1NULL;
+ break;
+
+ case 'o':
+ map->map_mflags |= MF_OPTIONAL;
+ break;
+
+ case 'q':
+ map->map_mflags |= MF_KEEPQUOTES;
+ break;
+
+ case 'S':
+ map->map_spacesub = *++p;
+ break;
+
+ case 'T':
+ map->map_tapp = ++p;
+ break;
+
+ case 't':
+ map->map_mflags |= MF_NODEFER;
+ break;
+
case 'v':
while (isascii(*++p) && isspace(*p))
continue;
@@ -255,24 +270,11 @@ map_parseargs(map, ap)
}
break;
- case 't':
- map->map_mflags |= MF_NODEFER;
- break;
-
-
- case 'S':
- map->map_spacesub = *++p;
- break;
-
- case 'D':
- map->map_mflags |= MF_DEFER;
- break;
-
default:
syserr("Illegal option %c map %s", *p, map->map_mname);
break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -289,14 +291,14 @@ map_parseargs(map, ap)
if (*p != '\0')
{
map->map_file = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
map->map_file = newstr(map->map_file);
}
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
if (*p != '\0')
map->map_rebuild = newstr(p);
@@ -454,11 +456,11 @@ initmaps()
{
#if XDEBUG
checkfd012("entering initmaps");
-#endif /* XDEBUG */
+#endif
stabapply(map_init, 0);
#if XDEBUG
checkfd012("exiting initmaps");
-#endif /* XDEBUG */
+#endif
}
/*
** MAP_INIT -- rebuild a map
@@ -629,7 +631,6 @@ closemaps(bogus)
** none.
*/
-/* ARGSUSED1 */
static void
map_close(s, bogus)
register STAB *s;
@@ -729,11 +730,11 @@ sun_init_domain()
** pttl -- pointer to return TTL (can be NULL).
**
** Returns:
-** true -- if the host was found.
-** false -- otherwise.
+** >0 -- if the host was found.
+** 0 -- otherwise.
*/
-bool
+int
getcanonname(host, hbsize, trymx, pttl)
char *host;
int hbsize;
@@ -751,9 +752,10 @@ getcanonname(host, hbsize, trymx, pttl)
bool should_try_nis_domain = false;
static char *nis_domain = NULL;
#endif
+ bool secure = true; /* consider all maps secure by default */
nmaps = switch_map_find("hosts", maptype, mapreturn);
- if (pttl != 0)
+ if (pttl != NULL)
*pttl = SM_DEFAULT_TTL;
for (mapno = 0; mapno < nmaps; mapno++)
{
@@ -773,7 +775,7 @@ getcanonname(host, hbsize, trymx, pttl)
# if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
if (nis_domain == NULL)
nis_domain = sun_init_domain();
-# endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
+# endif
}
#endif /* NIS */
#if NISPLUS
@@ -783,13 +785,18 @@ getcanonname(host, hbsize, trymx, pttl)
# if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
if (nis_domain == NULL)
nis_domain = sun_init_domain();
-# endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
+# endif
}
#endif /* NISPLUS */
#if NAMED_BIND
else if (strcmp("dns", maptype[mapno]) == 0)
{
- found = dns_getcanonname(host, hbsize, trymx, &status, pttl);
+ int r;
+
+ r = dns_getcanonname(host, hbsize, trymx, &status,
+ pttl);
+ secure = HOST_SECURE == r;
+ found = r > 0;
}
#endif /* NAMED_BIND */
#if NETINFO
@@ -841,7 +848,7 @@ getcanonname(host, hbsize, trymx, pttl)
char *d;
if (tTd(38, 20))
- sm_dprintf("getcanonname(%s), found\n", host);
+ sm_dprintf("getcanonname(%s), found, ad=%d\n", host, secure);
/*
** If returned name is still single token, compensate
@@ -870,10 +877,10 @@ getcanonname(host, hbsize, trymx, pttl)
goto try_nis_domain;
}
#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
- return false;
+ return HOST_NOTFOUND;
}
}
- return true;
+ return secure ? HOST_SECURE : HOST_OK;
}
#if defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN)
@@ -884,7 +891,7 @@ getcanonname(host, hbsize, trymx, pttl)
strlen(nis_domain) + strlen(host) + 1 < hbsize)
{
(void) sm_strlcat2(host, ".", nis_domain, hbsize);
- return true;
+ return HOST_OK;
}
}
#endif /* defined(SUN_EXTENSIONS) && defined(SUN_INIT_DOMAIN) */
@@ -898,7 +905,7 @@ getcanonname(host, hbsize, trymx, pttl)
else
SM_SET_H_ERRNO(HOST_NOT_FOUND);
- return false;
+ return HOST_NOTFOUND;
}
/*
** EXTRACT_CANONNAME -- extract canonical name from /etc/hosts entry
@@ -982,7 +989,7 @@ extract_canonname(name, dot, line, cbuf, cbuflen)
# include "sm_resolve.h"
# if NETINET || NETINET6
# include <arpa/inet.h>
-# endif /* NETINET || NETINET6 */
+# endif
/*
** DNS_MAP_OPEN -- stub to check proper value for dns map type
@@ -1023,6 +1030,7 @@ dns_map_open(map, mode)
struct dns_map
{
int dns_m_type;
+ unsigned int dns_m_options;
};
bool
@@ -1034,56 +1042,54 @@ dns_map_parseargs(map,args)
struct dns_map *map_p;
map_p = (struct dns_map *) xalloc(sizeof(*map_p));
+ memset(map_p, '\0', sizeof(*map_p));
map_p->dns_m_type = -1;
map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
switch (*++p)
{
- case 'N':
- map->map_mflags |= MF_INCLNULL;
- map->map_mflags &= ~MF_TRY0NULL;
- break;
-
- case 'O':
- map->map_mflags &= ~MF_TRY1NULL;
- break;
-
- case 'o':
- map->map_mflags |= MF_OPTIONAL;
- break;
-
- case 'f':
- map->map_mflags |= MF_NOFOLDCASE;
- break;
-
- case 'm':
- map->map_mflags |= MF_MATCHONLY;
+#if DNSSEC_TEST
+ case '@':
+ ++p;
+ if (nsportip(p) < 0)
+ syserr("dns map %s: nsportip(%s)=failed",
+ map->map_mname, p);
break;
+#endif /* DNSSEC_TEST */
case 'A':
map->map_mflags |= MF_APPEND;
break;
- case 'q':
- map->map_mflags |= MF_KEEPQUOTES;
- break;
-
- case 't':
- map->map_mflags |= MF_NODEFER;
- break;
-
case 'a':
map->map_app = ++p;
break;
- case 'T':
- map->map_tapp = ++p;
+ case 'B': /* base domain */
+ {
+ char *h;
+
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ h = strchr(p, ' ');
+ if (h != NULL)
+ *h = '\0';
+
+ /*
+ ** slight abuse of map->map_file; it isn't
+ ** used otherwise in this map type.
+ */
+
+ map->map_file = newstr(p);
+ if (h != NULL)
+ *h = ' ';
+ }
break;
case 'd':
@@ -1100,12 +1106,51 @@ dns_map_parseargs(map,args)
}
break;
+ case 'f':
+ map->map_mflags |= MF_NOFOLDCASE;
+ break;
+
+ case 'm':
+ map->map_mflags |= MF_MATCHONLY;
+ break;
+
+ case 'N':
+ map->map_mflags |= MF_INCLNULL;
+ map->map_mflags &= ~MF_TRY0NULL;
+ break;
+
+ case 'O':
+ map->map_mflags &= ~MF_TRY1NULL;
+ break;
+
+ case 'o':
+ map->map_mflags |= MF_OPTIONAL;
+ break;
+
+ case 'q':
+ map->map_mflags |= MF_KEEPQUOTES;
+ break;
+
+ case 'S':
+#if defined(RES_USE_EDNS0) && defined(RES_USE_DNSSEC)
+ map_p->dns_m_options |= SM_RES_DNSSEC;
+#endif
+ break;
+
case 'r':
while (isascii(*++p) && isspace(*p))
continue;
map->map_retry = atoi(p);
break;
+ case 't':
+ map->map_mflags |= MF_NODEFER;
+ break;
+
+ case 'T':
+ map->map_tapp = ++p;
+ break;
+
case 'z':
if (*++p != '\\')
map->map_coldelim = *p;
@@ -1152,28 +1197,8 @@ dns_map_parseargs(map,args)
}
break;
- case 'B': /* base domain */
- {
- char *h;
-
- while (isascii(*++p) && isspace(*p))
- continue;
- h = strchr(p, ' ');
- if (h != NULL)
- *h = '\0';
-
- /*
- ** slight abuse of map->map_file; it isn't
- ** used otherwise in this map type.
- */
-
- map->map_file = newstr(p);
- if (h != NULL)
- *h = ' ';
- }
- break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -1222,15 +1247,17 @@ dns_map_lookup(map, name, av, statp)
struct dns_map *map_p;
RESOURCE_RECORD_T *rr = NULL;
DNS_REPLY_T *r = NULL;
+ unsigned int options;
# if NETINET6
static char buf6[INET6_ADDRSTRLEN];
-# endif /* NETINET6 */
+# endif
if (tTd(38, 20))
sm_dprintf("dns_map_lookup(%s, %s)\n",
map->map_mname, name);
map_p = (struct dns_map *)(map->map_db1);
+ options = map_p->dns_m_options;
if (map->map_file != NULL && *map->map_file != '\0')
{
size_t len;
@@ -1244,14 +1271,14 @@ dns_map_lookup(map, name, av, statp)
return NULL;
}
(void) sm_strlcpyn(appdomain, len, 3, name, ".", map->map_file);
- r = dns_lookup_int(appdomain, C_IN, map_p->dns_m_type,
- map->map_timeout, map->map_retry);
+ r = dns_lookup_map(appdomain, C_IN, map_p->dns_m_type,
+ map->map_timeout, map->map_retry, options);
sm_free(appdomain);
}
else
{
- r = dns_lookup_int(name, C_IN, map_p->dns_m_type,
- map->map_timeout, map->map_retry);
+ r = dns_lookup_map(name, C_IN, map_p->dns_m_type,
+ map->map_timeout, map->map_retry, options);
}
if (r == NULL)
@@ -1312,6 +1339,12 @@ dns_map_lookup(map, name, av, statp)
sizeof(buf6));
break;
# endif /* NETINET6 */
+# ifdef T_TLSA
+ case T_TLSA:
+ type = "T_TLSA";
+ value = rr->rr_u.rr_txt;
+ break;
+# endif /* T_TLSA */
}
(void) strreplnonprt(value, 'X');
@@ -1396,8 +1429,7 @@ dns_map_lookup(map, name, av, statp)
cleanup:
if (vp != NULL)
sm_free(vp);
- if (r != NULL)
- dns_free_data(r);
+ dns_free_data(r);
return result;
}
# endif /* DNSMAP */
@@ -1582,7 +1614,7 @@ ndbm_map_open(map, mode)
# if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
+# endif
errno = save_errno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("Cannot open DBM database %s", map->map_file);
@@ -1597,7 +1629,7 @@ ndbm_map_open(map, mode)
# if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
+# endif
errno = 0;
syserr("dbm map \"%s\": cannot support GDBM",
map->map_mname);
@@ -1612,7 +1644,7 @@ ndbm_map_open(map, mode)
# if !LOCK_ON_OPEN && !NOFTRUNCATE
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN && !NOFTRUNCATE */
+# endif
errno = save_errno;
syserr("ndbm_map_open(%s): file changed after open",
map->map_file);
@@ -1840,7 +1872,7 @@ ndbm_map_store(map, lhs, rhs)
data.dptr = buf;
if (tTd(38, 9))
sm_dprintf("ndbm_map_store append=%s\n",
- (char *)data.dptr);
+ data.dptr);
}
}
status = dbm_store((DBM *) map->map_db1,
@@ -1900,7 +1932,7 @@ ndbm_map_close(map)
# if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN */
+# endif
}
#endif /* NDBM */
@@ -1928,10 +1960,10 @@ ndbm_map_close(map)
# define h_nelem nelem
# ifndef DB_CACHE_SIZE
# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */
-# endif /* ! DB_CACHE_SIZE */
+# endif
# ifndef DB_HASH_NELEM
# define DB_HASH_NELEM 4096 /* (starting) size of hash table */
-# endif /* ! DB_HASH_NELEM */
+# endif
# endif /* DB_VERSION_MAJOR < 2 */
bool
@@ -1941,13 +1973,13 @@ bt_map_open(map, mode)
{
# if DB_VERSION_MAJOR < 2
BTREEINFO btinfo;
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
DB_INFO btinfo;
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
void *btinfo = NULL;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
if (tTd(38, 2))
sm_dprintf("bt_map_open(%s, %s, %d)\n",
@@ -1957,7 +1989,7 @@ bt_map_open(map, mode)
memset(&btinfo, '\0', sizeof(btinfo));
# ifdef DB_CACHE_SIZE
btinfo.db_cachesize = DB_CACHE_SIZE;
-# endif /* DB_CACHE_SIZE */
+# endif
# endif /* DB_VERSION_MAJOR < 3 */
return db_map_open(map, mode, "btree", DB_BTREE, &btinfo);
@@ -1970,13 +2002,13 @@ hash_map_open(map, mode)
{
# if DB_VERSION_MAJOR < 2
HASHINFO hinfo;
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
DB_INFO hinfo;
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
void *hinfo = NULL;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
if (tTd(38, 2))
sm_dprintf("hash_map_open(%s, %s, %d)\n",
@@ -1986,10 +2018,10 @@ hash_map_open(map, mode)
memset(&hinfo, '\0', sizeof(hinfo));
# ifdef DB_HASH_NELEM
hinfo.h_nelem = DB_HASH_NELEM;
-# endif /* DB_HASH_NELEM */
+# endif
# ifdef DB_CACHE_SIZE
hinfo.db_cachesize = DB_CACHE_SIZE;
-# endif /* DB_CACHE_SIZE */
+# endif
# endif /* DB_VERSION_MAJOR < 3 */
return db_map_open(map, mode, "hash", DB_HASH, &hinfo);
@@ -2003,13 +2035,13 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
DBTYPE dbtype;
# if DB_VERSION_MAJOR < 2
const void *openinfo;
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
# if DB_VERSION_MAJOR == 2
DB_INFO *openinfo;
-# endif /* DB_VERSION_MAJOR == 2 */
+# endif
# if DB_VERSION_MAJOR > 2
void **openinfo;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
{
DB *db = NULL;
int i;
@@ -2143,7 +2175,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
int flags = 0;
# if DB_VERSION_MAJOR > 2
int ret;
-# endif /* DB_VERSION_MAJOR > 2 */
+# endif
if (mode == O_RDONLY)
flags |= DB_RDONLY;
@@ -2216,7 +2248,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
# if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN */
+# endif
errno = save_errno;
if (!bitset(MF_OPTIONAL, map->map_mflags))
syserr("Cannot open %s database %s",
@@ -2226,7 +2258,7 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
# if DB_VERSION_MAJOR < 2
fd = db->fd(db);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
fd = -1;
errno = db->fd(db, &fd);
# endif /* DB_VERSION_MAJOR < 2 */
@@ -2235,13 +2267,13 @@ db_map_open(map, mode, mapclassname, dbtype, openinfo)
save_errno = errno;
# if DB_VERSION_MAJOR < 2
(void) db->close(db);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
errno = db->close(db, 0);
# endif /* DB_VERSION_MAJOR < 2 */
# if !LOCK_ON_OPEN
if (map->map_lockfd >= 0)
(void) close(map->map_lockfd);
-# endif /* !LOCK_ON_OPEN */
+# endif
errno = save_errno;
syserr("db_map_open(%s): file changed after open", buf);
return false;
@@ -2352,7 +2384,7 @@ db_map_lookup(map, name, av, statp)
lockdb:
# if DB_VERSION_MAJOR < 2
fd = db->fd(db);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
fd = -1;
errno = db->fd(db, &fd);
# endif /* DB_VERSION_MAJOR < 2 */
@@ -2564,7 +2596,7 @@ db_map_store(map, lhs, rhs)
}
# if DB_VERSION_MAJOR < 2
status = db->put(db, &key, &data, 0);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
status = errno = db->put(db, NULL, &key, &data, 0);
# endif /* DB_VERSION_MAJOR < 2 */
}
@@ -2633,6 +2665,389 @@ db_map_close(map)
map->map_mname, map->map_file, map->map_mflags);
}
#endif /* NEWDB */
+
+#if CDB
+/*
+** CDB Modules
+*/
+
+static bool smdb_add_extension __P((char *, int, char *, char *));
+
+/*
+** SMDB_ADD_EXTENSION -- Adds an extension to a file name.
+**
+** Just adds a . followed by a string to a db_name if there
+** is room and the db_name does not already have that extension.
+**
+** Parameters:
+** full_name -- The final file name.
+** max_full_name_len -- The max length for full_name.
+** db_name -- The name of the db.
+** extension -- The extension to add.
+**
+** Returns:
+** SMDBE_OK -- Success.
+** Anything else is an error. Look up more info about the
+** error in the comments for the specific open() used.
+*/
+
+static bool
+smdb_add_extension(full_name, max_full_name_len, db_name, extension)
+ char *full_name;
+ int max_full_name_len;
+ char *db_name;
+ char *extension;
+{
+ int extension_len;
+ int db_name_len;
+
+ if (full_name == NULL || db_name == NULL || extension == NULL)
+ return false; /* SMDBE_INVALID_PARAMETER; */
+
+ extension_len = strlen(extension);
+ db_name_len = strlen(db_name);
+
+ if (extension_len + db_name_len + 2 > max_full_name_len)
+ return false; /* SMDBE_DB_NAME_TOO_LONG; */
+
+ if (db_name_len < extension_len + 1 ||
+ db_name[db_name_len - extension_len - 1] != '.' ||
+ strcmp(&db_name[db_name_len - extension_len], extension) != 0)
+ (void) sm_snprintf(full_name, max_full_name_len, "%s.%s",
+ db_name, extension);
+ else
+ (void) sm_strlcpy(full_name, db_name, max_full_name_len);
+
+ return true;
+}
+
+bool
+cdb_map_open(map, mode)
+ MAP *map;
+ int mode;
+{
+ int fd, status, omode, smode;
+ long sff;
+ struct stat st;
+ char buf[MAXPATHLEN];
+
+ if (tTd(38, 2))
+ sm_dprintf("cdb_map_open(%s, %s, %d)\n",
+ map->map_mname, map->map_file, mode);
+ map->map_db1 = (ARBPTR_T)NULL;
+ map->map_db2 = (ARBPTR_T)NULL;
+
+ mode &= O_ACCMODE;
+ omode = mode;
+
+ /*
+ ** Notes:
+ ** If a temporary file is used, then there must be some check
+ ** that the rename() is "safe" (i.e., does not overwrite some
+ ** "other" file created by an attacker).
+ **
+ ** The code to add the extension and to set up safefile()
+ ** and open() should be in a common function
+ ** (it would be nice to re-use libsmdb?)
+ */
+
+ if (!smdb_add_extension(buf, sizeof(buf), map->map_file, CDBext))
+ {
+ errno = 0;
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("cdb map \"%s\": map file %s name too long",
+ map->map_mname, map->map_file);
+ return false;
+ }
+
+ sff = SFF_ROOTOK|SFF_REGONLY;
+ if (mode == O_RDWR)
+ {
+ if (sm_strlcat(buf, ".tmp", sizeof buf) >= sizeof buf)
+ {
+ errno = 0;
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("cdb map \"%s\": map file %s name too long",
+ map->map_mname, map->map_file);
+ return false;
+ }
+ sff |= SFF_CREAT;
+ if (!bitnset(DBS_WRITEMAPTOSYMLINK, DontBlameSendmail))
+ sff |= SFF_NOSLINK;
+ if (!bitnset(DBS_WRITEMAPTOHARDLINK, DontBlameSendmail))
+ sff |= SFF_NOHLINK;
+ smode = S_IWRITE;
+ }
+ else
+ {
+ smode = S_IREAD;
+ if (!bitnset(DBS_LINKEDMAPINWRITABLEDIR, DontBlameSendmail))
+ sff |= SFF_NOWLINK;
+ }
+ if (!bitnset(DBS_MAPINUNSAFEDIRPATH, DontBlameSendmail))
+ sff |= SFF_SAFEDIRPATH;
+ status = safefile(buf, RunAsUid, RunAsGid, RunAsUserName, sff, smode, &st);
+ if (status != 0)
+ {
+ char *prob = "unsafe";
+
+ /* cannot open this map */
+ if (status == ENOENT)
+ prob = "missing";
+ errno = status;
+ if (tTd(38, 2))
+ sm_dprintf("\t%s map file: %s\n", prob, sm_errstring(status));
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("%s map \"%s\": %s map file %s",
+ map->map_mname, prob, buf, sm_errstring(status));
+ return false;
+ }
+
+ if (st.st_mode == ST_MODE_NOFILE)
+ omode |= O_CREAT|O_EXCL;
+# if LOCK_ON_OPEN
+ if (mode == O_RDWR)
+ omode |= O_TRUNC|O_EXLOCK;
+ else
+ omode |= O_SHLOCK;
+# else
+ if (mode == O_RDWR)
+ omode |= O_TRUNC;
+# endif /* LOCK_ON_OPEN */
+
+ fd = open(buf, omode, DBMMODE);
+ if (fd < 0)
+ {
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("cdb_map_open: cannot open database %s", buf);
+ return false;
+ }
+
+# if !LOCK_ON_OPEN
+ /* make sure no baddies slipped in just before the open... */
+ if (filechanged(buf, fd, &st))
+ {
+ int save_errno;
+
+ save_errno = errno;
+ (void) close(fd);
+ errno = save_errno;
+ syserr("cdb_map_open(%s): file changed after open", buf);
+ return false;
+ }
+
+ /* actually lock the opened file */
+ if (!lockfile(fd, buf, NULL, mode == O_RDONLY ? LOCK_SH : LOCK_EX))
+ syserr("cdb_map_open: cannot lock %s", buf);
+# endif /* !LOCK_ON_OPEN */
+
+ /* only for aliases! */
+ if (mode == O_RDWR)
+ {
+ struct cdb_make *cdbmp;
+
+ cdbmp = (struct cdb_make *) xalloc(sizeof(*cdbmp));
+ status = cdb_make_start(cdbmp, fd);
+ if (status != 0)
+ {
+ close(fd);
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("initialization of cdb map (make) failed");
+ return false;
+ }
+
+ map->map_db2 = (ARBPTR_T)cdbmp;
+ return true;
+ }
+ else
+ {
+ struct cdb *cdbp;
+
+ cdbp = (struct cdb *) xalloc(sizeof(*cdbp));
+ status = cdb_init(cdbp, fd);
+ if (status != 0)
+ {
+ close(fd);
+ if (!bitset(MF_OPTIONAL, map->map_mflags))
+ syserr("initialization of cdb map failed");
+ return false;
+ }
+ map->map_db1 = (ARBPTR_T)cdbp;
+ return true;
+ }
+
+ /* NOTREACHED */
+ return false;
+}
+
+char *
+cdb_map_lookup (map, name, av, statp)
+ MAP * map;
+ char *name;
+ char **av;
+ int *statp;
+{
+ char * data;
+ struct cdb *cdbmap;
+ unsigned int klen, dlen;
+ int st;
+ char key[MAXNAME+1];
+
+ data = NULL;
+ cdbmap = map->map_db1;
+ if (tTd(38, 20))
+ sm_dprintf("cdb_map_lookup(%s, %s)\n", map->map_mname, name);
+
+ klen = strlen(name);
+ if (klen > sizeof(key) - 1)
+ klen = sizeof(key) - 1;
+ memmove(key, name, klen);
+ key[klen] = '\0';
+
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ makelower(key);
+
+ st = 0;
+ if (bitset(MF_TRY0NULL, map->map_mflags))
+ {
+ st = cdb_find(cdbmap, key, klen);
+ if (st == 1)
+ map->map_mflags &= ~MF_TRY1NULL;
+ }
+ if (st != 1 && bitset(MF_TRY1NULL, map->map_mflags))
+ {
+ st = cdb_find(cdbmap, key, klen + 1);
+ if (st == 1)
+ map->map_mflags &= ~MF_TRY0NULL;
+ }
+ if (st != 1)
+ {
+ if (st < 0)
+ syserr("cdb_map_lookup: get (%s)", name);
+ return NULL;
+ }
+ else
+ {
+ dlen = cdb_datalen(cdbmap);
+ data = malloc(dlen + 1);
+ cdb_read(cdbmap, data, dlen, cdb_datapos(cdbmap));
+ data[dlen] = '\0';
+ }
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ return map_rewrite(map, name, strlen(name), NULL);
+ else
+ return map_rewrite(map, data, dlen, av);
+}
+
+/*
+** CDB_MAP_STORE -- store a datum in the CDB database
+*/
+
+void
+cdb_map_store(map, lhs, rhs)
+ MAP *map;
+ char *lhs;
+ char *rhs;
+{
+ struct cdb_make *cdbmp;
+ size_t klen;
+ size_t vlen;
+ int status;
+ char keybuf[MAXNAME + 1];
+
+ cdbmp = map->map_db2;
+ if (cdbmp == NULL)
+ return; /* XXX */
+
+ klen = strlen(lhs);
+ vlen = strlen(rhs);
+ if (!bitset(MF_NOFOLDCASE, map->map_mflags))
+ {
+ if (klen > sizeof(keybuf) - 1)
+ klen = sizeof(keybuf) - 1;
+ memmove(keybuf, lhs, klen);
+ keybuf[klen] = '\0';
+ makelower(keybuf);
+ lhs = keybuf;
+ }
+
+ if (bitset(MF_INCLNULL, map->map_mflags))
+ {
+ klen++;
+ vlen++;
+ }
+
+ /* flags? */
+ status = cdb_make_put(cdbmp, lhs, klen, rhs, vlen, 0);
+ /* and now? */
+}
+
+void
+cdb_map_close(map)
+ MAP * map;
+{
+ struct cdb *cdbp;
+ struct cdb_make *cdbmp;
+ int fd;
+
+ fd = -1;
+ cdbp = map->map_db1;
+ if (cdbp != NULL)
+ {
+ if (tTd(38, 20))
+ sm_dprintf("cdb_map_close(%p)\n", (void *)cdbp);
+ fd = cdb_fileno(cdbp);
+ cdb_free(cdbp);
+ sm_free(cdbp);
+ cdbp = NULL;
+ }
+ cdbmp = map->map_db2;
+ if (cdbmp != NULL)
+ {
+ char tmpfn[MAXPATHLEN], cdbfn[MAXPATHLEN];
+
+ if (tTd(38, 20))
+ sm_dprintf("cdb_map_close(%p)\n", (void *)cdbmp);
+ fd = cdb_fileno(cdbmp);
+
+ /* write out the distinguished alias */
+ /* XXX Why isn't this in a common place? */
+ cdb_map_store(map, "@", "@");
+
+ if (cdb_make_finish(cdbmp) != 0)
+ syserr("cdb: failed to write %s", map->map_file);
+ if (fd >=0)
+ {
+ if (fsync(fd) == -1)
+ syserr("cdb: fsync(%s) failed", map->map_file);
+ if (close(fd) == -1)
+ syserr("cdb: close(%s) failed", map->map_file);
+ }
+
+ if (!smdb_add_extension(cdbfn, sizeof(cdbfn), map->map_file,
+ CDBext))
+ {
+ syserr("cdb: add extension to %s failed",
+ map->map_file);
+ }
+ if (sm_strlcpy(tmpfn, cdbfn, sizeof tmpfn) >= sizeof tmpfn ||
+ sm_strlcat(tmpfn, ".tmp", sizeof tmpfn) >= sizeof tmpfn)
+ {
+ syserr("cdb: set temp filename for %s failed",
+ map->map_file);
+ }
+ if (tTd(38, 80))
+ sm_dprintf("rename(%s, %s)\n", tmpfn, cdbfn);
+ if (rename(tmpfn, cdbfn) == -1)
+ syserr("cdb: rename(%s, %s) failed", tmpfn, cdbfn);
+ sm_free(cdbmp);
+ cdbmp = NULL;
+ }
+ if (fd >=0)
+ close(fd);
+}
+#endif /* CDB */
+
/*
** NIS Modules
*/
@@ -2641,7 +3056,7 @@ db_map_close(map)
# ifndef YPERR_BUSY
# define YPERR_BUSY 16
-# endif /* ! YPERR_BUSY */
+# endif
/*
** NIS_MAP_OPEN -- open DBM map
@@ -2706,7 +3121,7 @@ nis_map_open(map, mode)
{
/*
** We ought to be calling aliaswait() here if this is an
- ** alias file, but powerful HP-UX NIS servers apparently
+ ** alias file, but powerful HP-UX NIS servers apparently
** don't insert the @:@ token into the alias map when it
** is rebuilt, so aliaswait() just hangs. I hate HP-UX.
*/
@@ -2714,7 +3129,7 @@ nis_map_open(map, mode)
# if 0
if (!bitset(MF_ALIAS, map->map_mflags) ||
aliaswait(map, NULL, true))
-# endif /* 0 */
+# endif
return true;
}
@@ -2769,7 +3184,7 @@ nis_map_lookup(map, name, av, statp)
}
if (yperr == YPERR_KEY && bitset(MF_TRY1NULL, map->map_mflags))
{
- SM_FREE_CLR(vp);
+ SM_FREE(vp);
buflen++;
yperr = yp_match(map->map_domain, map->map_file, keybuf, buflen,
&vp, &vsize);
@@ -2843,7 +3258,7 @@ nis_getcanonname(name, hbsize, statp)
}
if (yperr == YPERR_KEY && try1null)
{
- SM_FREE_CLR(vp);
+ SM_FREE(vp);
keylen++;
yperr = yp_match(yp_domain, "hosts.byname", nbuf, keylen,
&vp, &vsize);
@@ -2899,7 +3314,7 @@ nis_getcanonname(name, hbsize, statp)
# include <rpcsvc/nislib.h>
# ifndef NIS_TABLE_OBJ
# define NIS_TABLE_OBJ TABLE_OBJ
-# endif /* NIS_TABLE_OBJ */
+# endif
# define EN_col(col) zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val
# define COL_NAME(res,i) ((res->objects.objects_val)->TA_data.ta_cols.ta_cols_val)[i].tc_name
@@ -3331,7 +3746,7 @@ nisplus_default_domain()
# if PH_MAP
# define ph_map_dequote ldapmap_dequote
-# endif /* PH_MAP */
+# endif
static char *ldapmap_dequote __P((char *));
@@ -3462,9 +3877,9 @@ ldapmap_open(map, mode)
syserr("%s failed to %s in map %s",
# if USE_LDAP_INIT
"ldap_init/ldap_bind",
-# else /* USE_LDAP_INIT */
+# else
"ldap_open",
-# endif /* USE_LDAP_INIT */
+# endif
id, map->map_mname);
}
else
@@ -3472,9 +3887,9 @@ ldapmap_open(map, mode)
syserr("451 4.3.5 %s failed to %s in map %s",
# if USE_LDAP_INIT
"ldap_init/ldap_bind",
-# else /* USE_LDAP_INIT */
+# else
"ldap_open",
-# endif /* USE_LDAP_INIT */
+# endif
id, map->map_mname);
}
}
@@ -3589,7 +4004,7 @@ ldapmap_lookup(map, name, av, statp)
char keybuf[MAXKEY];
#if SM_LDAP_ARGS != MAX_MAP_ARGS
# ERROR _SM_LDAP_ARGS must be the same as _MAX_MAP_ARGS
-#endif /* SM_LDAP_ARGS != MAX_MAP_ARGS */
+#endif
#if defined(SUN_EXTENSIONS) && defined(SUN_SIMPLIFIED_LDAP) && \
HASLDAPGETALIASBYNAME
@@ -3717,7 +4132,7 @@ ldapmap_lookup(map, name, av, statp)
{
# ifdef LDAP_SERVER_DOWN
case LDAP_SERVER_DOWN:
-# endif /* LDAP_SERVER_DOWN */
+# endif
case LDAP_TIMEOUT:
case LDAP_UNAVAILABLE:
/* server disappeared, try reopen on next search */
@@ -3752,7 +4167,7 @@ ldapmap_lookup(map, name, av, statp)
# if _FFR_LDAP_SINGLEDN
if (bitset(MF_SINGLEDN, map->map_mflags))
flags |= SM_LDAP_SINGLEDN;
-# endif /* _FFR_LDAP_SINGLEDN */
+# endif
/* Create an rpool for search related memory usage */
rpool = sm_rpool_new_x(NULL);
@@ -3876,7 +4291,7 @@ static struct lamvalues LDAPAuthMethods[] =
{ "simple", LDAP_AUTH_SIMPLE },
# ifdef LDAP_AUTH_KRBV4
{ "krbv4", LDAP_AUTH_KRBV4 },
-# endif /* LDAP_AUTH_KRBV4 */
+# endif
{ NULL, 0 }
};
@@ -3996,13 +4411,15 @@ ldapmap_parseargs(map, args)
map->map_coldelim = ' ';
}
-# if _FFR_LDAP_NETWORK_TIMEOUT
- lmap->ldap_networktmo = 120;
-# endif /* _FFR_LDAP_NETWORK_TIMEOUT */
+# if LDAP_NETWORK_TIMEOUT
+ if (0 == lmap->ldap_networktmo)
+ lmap->ldap_networktmo = (LDAP_NETWORK_TIMEOUT > 1)
+ ? LDAP_NETWORK_TIMEOUT : 60;
+# endif
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -4095,13 +4512,13 @@ ldapmap_parseargs(map, args)
lmap->ldap_base = p;
break;
-# if _FFR_LDAP_NETWORK_TIMEOUT
+# if LDAP_NETWORK_TIMEOUT
case 'c': /* network (connect) timeout */
while (isascii(*++p) && isspace(*p))
continue;
lmap->ldap_networktmo = atoi(p);
break;
-# endif /* _FFR_LDAP_NETWORK_TIMEOUT */
+# endif /* LDAP_NETWORK_TIMEOUT */
case 'd': /* Dn to bind to server as */
while (isascii(*++p) && isspace(*p))
@@ -4217,7 +4634,7 @@ ldapmap_parseargs(map, args)
case 'R': /* don't auto chase referrals */
# ifdef LDAP_REFERRALS
lmap->ldap_options &= ~LDAP_OPT_REFERRALS;
-# else /* LDAP_REFERRALS */
+# else
syserr("compile with -DLDAP_REFERRALS for referral support");
# endif /* LDAP_REFERRALS */
break;
@@ -4345,6 +4762,14 @@ ldapmap_parseargs(map, args)
# endif /* LDAP_VERSION_MIN */
break;
+ case 'x':
+# if _FFR_SM_LDAP_DBG
+ while (isascii(*++p) && isspace(*p))
+ continue;
+ lmap->ldap_debug = atoi(p);
+# endif
+ break;
+
case 'Z':
while (isascii(*++p) && isspace(*p))
continue;
@@ -4357,7 +4782,7 @@ ldapmap_parseargs(map, args)
}
/* need to account for quoted strings here */
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
{
if (*p == '"')
{
@@ -4542,7 +4967,7 @@ ldapmap_parseargs(map, args)
{
char *v;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
break;
@@ -4719,8 +5144,8 @@ ldapmap_set_defaults(spec)
map.map_tapp != NULL)
{
syserr("readcf: option LDAPDefaultSpec: Do not set non-LDAP specific flags");
- SM_FREE_CLR(map.map_app);
- SM_FREE_CLR(map.map_tapp);
+ SM_FREE(map.map_app);
+ SM_FREE(map.map_tapp);
}
if (LDAPDefaults->ldap_filter != NULL)
@@ -4801,7 +5226,7 @@ ph_map_parseargs(map, args)
map->map_mflags |= MF_TRY0NULL|MF_TRY1NULL;
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -4879,7 +5304,7 @@ ph_map_parseargs(map, args)
}
/* try to account for quoted strings */
- done = isascii(*p) && isspace(*p);
+ done = SM_ISSPACE(*p);
while (*p != '\0' && !done)
{
if (*p == '"')
@@ -4891,7 +5316,7 @@ ph_map_parseargs(map, args)
}
else
p++;
- done = isascii(*p) && isspace(*p);
+ done = SM_ISSPACE(*p);
}
if (*p != '\0')
@@ -5196,7 +5621,7 @@ syslog_map_parseargs(map, args)
/* there is no check whether there is really an argument */
while (*p != '\0')
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -5214,12 +5639,12 @@ syslog_map_parseargs(map, args)
}
else if (*p == 'L')
{
- while (*++p != '\0' && isascii(*p) && isspace(*p))
+ while (*++p != '\0' && SM_ISSPACE(*p))
continue;
if (*p == '\0')
break;
priority = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -5335,7 +5760,7 @@ dprintf_map_parseargs(map, args)
/* there is no check whether there is really an argument */
while (*p != '\0')
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -5353,12 +5778,12 @@ dprintf_map_parseargs(map, args)
}
else if (*p == 'd')
{
- while (*++p != '\0' && isascii(*p) && isspace(*p))
+ while (*++p != '\0' && SM_ISSPACE(*p))
continue;
if (*p == '\0')
break;
dbg_level = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -5481,7 +5906,7 @@ hes_map_lookup(map, name, av, statp)
(void) sm_strlcpy(&np[1], name, (sizeof(nbuf)) - 1);
# ifdef HESIOD_INIT
hp = hesiod_resolve(HesiodContext, np, map->map_file);
-# else /* HESIOD_INIT */
+# else
hp = hes_resolve(np, map->map_file);
# endif /* HESIOD_INIT */
save_errno = errno;
@@ -5493,7 +5918,7 @@ hes_map_lookup(map, name, av, statp)
{
# ifdef HESIOD_INIT
hp = hesiod_resolve(HesiodContext, name, map->map_file);
-# else /* HESIOD_INIT */
+# else
hp = hes_resolve(name, map->map_file);
# endif /* HESIOD_INIT */
}
@@ -6069,11 +6494,15 @@ impl_map_lookup(map, name, av, pstat)
#if NEWDB
if (bitset(MF_IMPL_HASH, map->map_mflags))
return db_map_lookup(map, name, av, pstat);
-#endif /* NEWDB */
+#endif
#if NDBM
if (bitset(MF_IMPL_NDBM, map->map_mflags))
return ndbm_map_lookup(map, name, av, pstat);
-#endif /* NDBM */
+#endif
+#if CDB
+ if (bitset(MF_IMPL_CDB, map->map_mflags))
+ return cdb_map_lookup(map, name, av, pstat);
+#endif
return stab_map_lookup(map, name, av, pstat);
}
@@ -6093,11 +6522,15 @@ impl_map_store(map, lhs, rhs)
#if NEWDB
if (bitset(MF_IMPL_HASH, map->map_mflags))
db_map_store(map, lhs, rhs);
-#endif /* NEWDB */
+#endif
#if NDBM
if (bitset(MF_IMPL_NDBM, map->map_mflags))
ndbm_map_store(map, lhs, rhs);
-#endif /* NDBM */
+#endif
+#if CDB
+ if (bitset(MF_IMPL_CDB, map->map_mflags))
+ cdb_map_store(map, lhs, rhs);
+#endif
stab_map_store(map, lhs, rhs);
}
@@ -6110,19 +6543,25 @@ impl_map_open(map, mode)
MAP *map;
int mode;
{
+ bool wasopt;
+
if (tTd(38, 2))
sm_dprintf("impl_map_open(%s, %s, %d)\n",
map->map_mname, map->map_file, mode);
mode &= O_ACCMODE;
+ wasopt = bitset(MF_OPTIONAL, map->map_mflags);
+
+ /* suppress error msgs */
+ map->map_mflags |= MF_OPTIONAL;
#if NEWDB
map->map_mflags |= MF_IMPL_HASH;
if (hash_map_open(map, mode))
{
# ifdef NDBM_YP_COMPAT
if (mode == O_RDONLY || strstr(map->map_file, "/yp/") == NULL)
-# endif /* NDBM_YP_COMPAT */
- return true;
+# endif
+ goto ok;
}
else
map->map_mflags &= ~MF_IMPL_HASH;
@@ -6130,27 +6569,43 @@ impl_map_open(map, mode)
#if NDBM
map->map_mflags |= MF_IMPL_NDBM;
if (ndbm_map_open(map, mode))
- {
- return true;
- }
+ goto ok;
else
map->map_mflags &= ~MF_IMPL_NDBM;
#endif /* NDBM */
-#if defined(NEWDB) || defined(NDBM)
+#if CDB
+ map->map_mflags |= MF_IMPL_CDB;
+ if (cdb_map_open(map, mode))
+ goto ok;
+ else
+ map->map_mflags &= ~MF_IMPL_CDB;
+#endif /* CDB */
+
+ if (!bitset(MF_ALIAS, map->map_mflags))
+ goto fail;
+#if NEWDB || NDBM || CDB
if (Verbose)
message("WARNING: cannot open alias database %s%s",
map->map_file,
mode == O_RDONLY ? "; reading text version" : "");
-#else /* defined(NEWDB) || defined(NDBM) */
+#else
if (mode != O_RDONLY)
usrerr("Cannot rebuild aliases: no database format defined");
-#endif /* defined(NEWDB) || defined(NDBM) */
+#endif
- if (mode == O_RDONLY)
- return stab_map_open(map, mode);
- else
- return false;
+ if (mode == O_RDONLY && stab_map_open(map, mode))
+ goto ok;
+
+ fail:
+ if (!wasopt)
+ map->map_mflags &= ~MF_OPTIONAL;
+ return false;
+
+ ok:
+ if (!wasopt)
+ map->map_mflags &= ~MF_OPTIONAL;
+ return true;
}
@@ -6180,7 +6635,15 @@ impl_map_close(map)
map->map_mflags &= ~MF_IMPL_NDBM;
}
#endif /* NDBM */
+#if CDB
+ if (bitset(MF_IMPL_CDB, map->map_mflags))
+ {
+ cdb_map_close(map);
+ map->map_mflags &= ~MF_IMPL_CDB;
+ }
+#endif /* CDB */
}
+
/*
** User map class.
**
@@ -6468,7 +6931,7 @@ seq_map_parse(map, ap)
STAB *s;
/* find beginning of map name */
- while (isascii(*ap) && isspace(*ap))
+ while (SM_ISSPACE(*ap))
ap++;
for (p = ap;
(isascii(*p) && isalnum(*p)) || *p == '_' || *p == '.';
@@ -6880,7 +7343,7 @@ regex_map_init(map, ap)
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -6929,7 +7392,7 @@ regex_map_init(map, ap)
break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -7250,7 +7713,7 @@ nsd_map_lookup(map, name, av, statp)
if (r == NS_BADREQ
# ifdef NS_NOPERM
|| r == NS_NOPERM
-# endif /* NS_NOPERM */
+# endif
)
{
*statp = EX_CONFIG;
@@ -7459,11 +7922,88 @@ arpa_map_lookup(map, name, av, statp)
return rval;
}
+#if _FFR_SETDEBUG_MAP
+char *
+setdebug_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+
+ if (tTd(38, 2))
+ {
+ char **cpp;
+
+ sm_dprintf("setdebug_map_lookup: key '%s'\n", name);
+ for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
+ sm_dprintf("setdebug_map_lookup: arg '%s'\n", *cpp);
+ }
+ *statp = EX_OK;
+ tTflag(name);
+ return NULL;
+}
+#endif
+
+#if _FFR_SETOPT_MAP
+char *
+setopt_map_lookup(map, name, av, statp)
+ MAP *map;
+ char *name;
+ char **av;
+ int *statp;
+{
+# if !_FFR_SETANYOPT
+ int val;
+# endif
+ char **cpp;
+
+ if (tTd(38, 2))
+ {
+ sm_dprintf("setopt_map_lookup: key '%s'\n", name);
+ for (cpp = av; cpp != NULL && *cpp != NULL; cpp++)
+ sm_dprintf("setopt_map_lookup: arg '%s'\n", *cpp);
+ }
+# if _FFR_SETANYOPT
+ /*
+ ** API screwed up...
+ ** first arg is the "short" name and second is the entire string...
+ */
+
+ sm_dprintf("setoption: name=%s\n", name);
+ setoption(' ', name, true, false, CurEnv);
+ *statp = EX_OK;
+ return NULL;
+# else /* _FFR_SETANYOPT */
+ *statp = EX_CONFIG;
+
+ cpp = av;
+ if (cpp == NULL || ++cpp == NULL || *cpp == NULL)
+ return NULL;
+ *statp = EX_OK;
+ errno = 0;
+ val = strtol(*cpp, NULL, 0);
+ /* check for valid number? */
+
+ /* use a table? */
+ if (sm_strcasecmp(name, "LogLevel") == 0)
+ {
+ LogLevel = val;
+ sm_dprintf("LogLevel=%d\n", val);
+ return NULL;
+ }
+# endif /* _FFR_SETANYOPT */
+ *statp = EX_CONFIG;
+ return NULL;
+}
+#endif
+
+
#if SOCKETMAP
# if NETINET || NETINET6
# include <arpa/inet.h>
-# endif /* NETINET || NETINET6 */
+# endif
# define socket_map_next map_stack[0]
@@ -7577,7 +8117,7 @@ socket_map_open(map, mode)
{
# ifdef EPROTONOSUPPORT
errno = EPROTONOSUPPORT;
-# else /* EPROTONOSUPPORT */
+# else
errno = EINVAL;
# endif /* EPROTONOSUPPORT */
syserr("socket map \"%s\": unknown socket type %s",
@@ -7642,10 +8182,10 @@ socket_map_open(map, mode)
if (false
# if NETINET
|| addr.sa.sa_family == AF_INET
-# endif /* NETINET */
+# endif
# if NETINET6
|| addr.sa.sa_family == AF_INET6
-# endif /* NETINET6 */
+# endif
)
{
unsigned short port;
@@ -7691,10 +8231,10 @@ socket_map_open(map, mode)
bool found = false;
# if NETINET
unsigned long hid = INADDR_NONE;
-# endif /* NETINET */
+# endif
# if NETINET6
struct sockaddr_in6 hid6;
-# endif /* NETINET6 */
+# endif
*end = '\0';
# if NETINET
@@ -7769,7 +8309,7 @@ socket_map_open(map, mode)
map->map_mname, at, hp->h_addrtype);
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return false;
}
}
@@ -7841,7 +8381,7 @@ socket_map_open(map, mode)
hp->h_addrtype);
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return false;
}
continue;
@@ -7855,7 +8395,7 @@ socket_map_open(map, mode)
# if NETINET6
if (hp != NULL)
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return false;
}
# if NETINET6
@@ -7979,6 +8519,7 @@ socket_map_lookup(map, name, av, statp)
int *statp;
{
unsigned int nettolen, replylen, recvlen;
+ int ret;
char *replybuf, *rval, *value, *status, *key;
SM_FILE_T *f;
char keybuf[MAXNAME + 1];
@@ -8017,13 +8558,20 @@ socket_map_lookup(map, name, av, statp)
goto errcl;
}
- if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1)
+ if ((ret = sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen)) != 1)
{
if (errno == EAGAIN)
{
syserr("451 4.3.0 socket_map_lookup(%s): read timeout",
map->map_mname);
}
+ else if (SM_IO_EOF == ret)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_INFO, CurEnv->e_id,
+ "socket_map_lookup(%s): EOF",
+ map->map_mname);
+ }
else
{
syserr("451 4.3.0 socket_map_lookup(%s): failed to read length parameter of reply %d",
diff --git a/contrib/sendmail/src/map.h b/contrib/sendmail/src/map.h
index f20cf647706c..d93c971a7c03 100644
--- a/contrib/sendmail/src/map.h
+++ b/contrib/sendmail/src/map.h
@@ -14,16 +14,19 @@
extern char *arith_map_lookup __P((MAP *, char *, char **, int *));
+extern char *arpa_map_lookup __P((MAP *, char *, char **, int *));
+
extern char *bestmx_map_lookup __P((MAP *, char *, char **, int *));
extern char *bogus_map_lookup __P((MAP *, char *, char **, int *));
+#if NEWDB
extern bool bt_map_open __P((MAP *, int));
extern char *db_map_lookup __P((MAP *, char *, char **, int *));
-
extern void db_map_store __P((MAP *, char *, char *));
extern void db_map_close __P((MAP *));
+#endif /* NEWDB */
extern bool dequote_init __P((MAP *, char *));
extern char *dequote_map __P((MAP *, char *, char **, int *));
@@ -35,7 +38,9 @@ extern char *dns_map_lookup __P((MAP *, char *, char **, int *));
extern bool dprintf_map_parseargs __P((MAP *, char *));
extern char *dprintf_map_lookup __P((MAP *, char *, char **, int *));
+#if NEWDB
extern bool hash_map_open __P((MAP *, int));
+#endif
extern bool host_map_init __P((MAP *, char *));
extern char *host_map_lookup __P((MAP *, char *, char **, int *));
@@ -49,6 +54,12 @@ extern char *macro_map_lookup __P((MAP *, char *, char **, int *));
extern bool map_parseargs __P((MAP *, char *));
+#if NDBM
+extern char *ndbm_map_lookup __P((MAP *, char *, char **, int *));
+extern void ndbm_map_store __P((MAP *, char *, char *));
+extern void ndbm_map_close __P((MAP *));
+#endif /* NDBM */
+
extern bool nis_map_open __P((MAP *, int));
extern char *nis_map_lookup __P((MAP *, char *, char **, int *));
@@ -66,6 +77,19 @@ extern char *seq_map_lookup __P((MAP *, char *, char **, int *));
extern void seq_map_store __P((MAP *, char *, char *));
extern bool seq_map_parse __P((MAP *, char *));
+#if _FFR_SETDEBUG_MAP
+extern char *setdebug_map_lookup __P((MAP *, char *, char **, int *));
+#endif
+#if _FFR_SETOPT_MAP
+extern char *setopt_map_lookup __P((MAP *, char *, char **, int *));
+#endif
+
+#if SOCKETMAP
+extern bool socket_map_open __P((MAP *, int));
+extern void socket_map_close __P((MAP *));
+extern char *socket_map_lookup __P((MAP *, char *, char **, int *));
+#endif
+
extern char *stab_map_lookup __P((MAP *, char *, char **, int *));
extern void stab_map_store __P((MAP *, char *, char *));
extern bool stab_map_open __P((MAP *, int));
@@ -83,4 +107,11 @@ extern char *udb_map_lookup __P((MAP *, char *, char **, int *));
extern bool user_map_open __P((MAP *, int));
extern char *user_map_lookup __P((MAP *, char *, char **, int *));
+#if CDB
+extern bool cdb_map_open __P((MAP *, int));
+extern char *cdb_map_lookup __P((MAP *, char *, char **, int *));
+extern void cdb_map_store __P((MAP *, char *, char *));
+extern void cdb_map_close __P((MAP *));
+#endif /* CDB */
+
#endif /* ! _MAP_H */
diff --git a/contrib/sendmail/src/mci.c b/contrib/sendmail/src/mci.c
index c3f925f3cb25..a50fd8ed0fe2 100644
--- a/contrib/sendmail/src/mci.c
+++ b/contrib/sendmail/src/mci.c
@@ -17,14 +17,18 @@ SM_RCSID("@(#)$Id: mci.c,v 8.225 2013-11-22 20:51:56 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
#include <dirent.h>
+#if STARTTLS
+# include <tls.h>
+#endif
static int mci_generate_persistent_path __P((const char *, char *,
int, bool));
static bool mci_load_persistent __P((MCI *));
static void mci_uncache __P((MCI **, bool));
+static void mci_clear __P((MCI *));
static int mci_lock_host_statfile __P((MCI *));
static int mci_read_persistent __P((SM_FILE_T *, MCI *));
@@ -102,7 +106,7 @@ mci_cache(mci)
if (tTd(42, 5))
sm_dprintf("mci_cache: caching %p (%s) in slot %d\n",
- mci, mci->mci_host, (int) (mcislot - MciCache));
+ (void *)mci, mci->mci_host, (int) (mcislot - MciCache));
if (tTd(91, 100))
sm_syslog(LOG_DEBUG, CurEnv->e_id,
"mci_cache: caching %lx (%.100s) in slot %d",
@@ -209,7 +213,7 @@ mci_uncache(mcislot, doquit)
if (tTd(42, 5))
sm_dprintf("mci_uncache: uncaching %p (%s) from slot %d (%d)\n",
- mci, mci->mci_host, (int) (mcislot - MciCache),
+ (void *)mci, mci->mci_host, (int) (mcislot - MciCache),
doquit);
if (tTd(91, 100))
sm_syslog(LOG_DEBUG, CurEnv->e_id,
@@ -229,7 +233,7 @@ mci_uncache(mcislot, doquit)
smtpquit(mci->mci_mailer, mci, &BlankEnvelope);
#if XLA
xla_host_end(mci->mci_host);
-#endif /* XLA */
+#endif
}
else
{
@@ -247,12 +251,13 @@ mci_uncache(mcislot, doquit)
mci->mci_tolist = NULL;
#if PIPELINING
mci->mci_okrcpts = 0;
-#endif /* PIPELINING */
+#endif
}
- SM_FREE_CLR(mci->mci_status);
- SM_FREE_CLR(mci->mci_rstatus);
- SM_FREE_CLR(mci->mci_heloname);
+ SM_FREE(mci->mci_status);
+ SM_FREE(mci->mci_rstatus);
+ SM_FREE(mci->mci_heloname);
+ mci_clear(mci);
if (mci->mci_rpool != NULL)
{
sm_rpool_free(mci->mci_rpool);
@@ -311,10 +316,45 @@ mci_clr_extensions(mci)
mci->mci_min_by = 0;
#if SASL
mci->mci_saslcap = NULL;
-#endif /* SASL */
+#endif
}
/*
+** MCI_CLEAR -- clear mci
+**
+** Parameters:
+** mci -- the connection to clear.
+**
+** Returns:
+** none.
+*/
+
+static void
+mci_clear(mci)
+ MCI *mci;
+{
+ if (mci == NULL)
+ return;
+
+ mci->mci_maxsize = 0;
+ mci->mci_min_by = 0;
+ mci->mci_deliveries = 0;
+#if SASL
+ if (bitset(MCIF_AUTHACT, mci->mci_flags))
+ sasl_dispose(&mci->mci_conn);
+#endif
+#if STARTTLS
+ if (bitset(MCIF_TLSACT, mci->mci_flags) && mci->mci_ssl != NULL)
+ SM_SSL_FREE(mci->mci_ssl);
+#endif
+
+ /* which flags to preserve? */
+ mci->mci_flags &= MCIF_CACHED;
+ mactabclear(&mci->mci_macro);
+}
+
+
+/*
** MCI_GET -- get information about a particular host
**
** Parameters:
@@ -351,7 +391,7 @@ mci_get(host, m)
mci->mci_tolist = NULL;
#if PIPELINING
mci->mci_okrcpts = 0;
-#endif /* PIPELINING */
+#endif
mci->mci_flags &= ~MCIF_NOTSTICKY;
if (mci->mci_rpool == NULL)
@@ -419,6 +459,7 @@ mci_get(host, m)
mci->mci_errno = 0;
mci->mci_exitstat = EX_OK;
}
+ mci_clear(mci);
}
return mci;
@@ -551,11 +592,11 @@ mci_setstat(mci, xstat, dstat, rstat)
if (xstat != EX_NOTSTICKY && xstat != EX_PROTOCOL)
mci->mci_exitstat = xstat;
- SM_FREE_CLR(mci->mci_status);
+ SM_FREE(mci->mci_status);
if (dstat != NULL)
mci->mci_status = sm_strdup_x(dstat);
- SM_FREE_CLR(mci->mci_rstatus);
+ SM_FREE(mci->mci_rstatus);
if (rstat != NULL)
mci->mci_rstatus = sm_strdup_x(rstat);
}
@@ -580,7 +621,6 @@ struct mcifbits
};
static struct mcifbits MciFlags[] =
{
- { MCIF_VALID, "VALID" },
{ MCIF_CACHED, "CACHED" },
{ MCIF_ESMTP, "ESMTP" },
{ MCIF_EXPN, "EXPN" },
@@ -598,11 +638,14 @@ static struct mcifbits MciFlags[] =
{ MCIF_AUTHACT, "AUTHACT" },
{ MCIF_ENHSTAT, "ENHSTAT" },
{ MCIF_PIPELINED, "PIPELINED" },
+ { MCIF_VERB, "VERB" },
#if STARTTLS
{ MCIF_TLS, "TLS" },
{ MCIF_TLSACT, "TLSACT" },
-#endif /* STARTTLS */
+#endif
{ MCIF_DLVR_BY, "DLVR_BY" },
+ { MCIF_INLONGLINE, "INLONGLINE" },
+ { MCIF_NOTSTICKY, "NOTSTICKY" },
{ 0, NULL }
};
@@ -618,7 +661,7 @@ mci_dump(fp, mci, logit)
sep = logit ? " " : "\n\t";
p = buf;
- (void) sm_snprintf(p, SPACELEFT(buf, p), "MCI@%p: ", mci);
+ (void) sm_snprintf(p, SPACELEFT(buf, p), "MCI@%p: ", (void *)mci);
p += strlen(p);
if (mci == NULL)
{
@@ -967,8 +1010,8 @@ mci_read_persistent(fp, mci)
(unsigned long) fp);
}
- SM_FREE_CLR(mci->mci_status);
- SM_FREE_CLR(mci->mci_rstatus);
+ SM_FREE(mci->mci_status);
+ SM_FREE(mci->mci_rstatus);
sm_io_rewind(fp, SM_TIME_DEFAULT);
ver = -1;
@@ -1077,7 +1120,7 @@ mci_store_persistent(mci)
#if !NOFTRUNCATE
(void) ftruncate(sm_io_getinfo(mci->mci_statfile, SM_IO_WHAT_FD, NULL),
(off_t) 0);
-#endif /* !NOFTRUNCATE */
+#endif
(void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "V0\n");
(void) sm_io_fprintf(mci->mci_statfile, SM_TIME_DEFAULT, "E%d\n",
@@ -1162,7 +1205,7 @@ mci_traverse_persistent(action, pathname)
char newpath[MAXPATHLEN];
#if MAXPATHLEN <= MAXNAMLEN - 3
ERROR "MAXPATHLEN <= MAXNAMLEN - 3"
-#endif /* MAXPATHLEN <= MAXNAMLEN - 3 */
+#endif
if ((d = opendir(pathname)) == NULL)
{
@@ -1502,7 +1545,7 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
char t_host[MAXHOSTNAMELEN];
#if NETINET6
struct in6_addr in6_addr;
-#endif /* NETINET6 */
+#endif
/*
** Rationality check the arguments.
@@ -1550,11 +1593,11 @@ mci_generate_persistent_path(host, path, pathlen, createflag)
# if NETINET6
if (anynet_pton(AF_INET6, t_host, &in6_addr) == 1)
good = true;
-# endif /* NETINET6 */
+# endif
# if NETINET
if (inet_addr(t_host) != INADDR_NONE)
good = true;
-# endif /* NETINET */
+# endif
if (!good)
return -1;
}
diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c
index 9b3667dc573a..ba783c4c61db 100644
--- a/contrib/sendmail/src/milter.c
+++ b/contrib/sendmail/src/milter.c
@@ -25,7 +25,7 @@ SM_RCSID("@(#)$Id: milter.c,v 8.281 2013-11-22 20:51:56 ca Exp $")
# include <arpa/inet.h>
# if MILTER_NO_NAGLE
# include <netinet/tcp.h>
-# endif /* MILTER_NO_NAGLE */
+# endif
# endif /* NETINET || NETINET6 */
# include <sm/fdset.h>
@@ -61,11 +61,11 @@ static void milter_insheader __P((struct milter *, char *, ssize_t,
ENVELOPE *));
static void milter_changeheader __P((struct milter *, char *, ssize_t,
ENVELOPE *));
-static void milter_chgfrom __P((char *, ssize_t, ENVELOPE *));
-static void milter_addrcpt __P((char *, ssize_t, ENVELOPE *));
-static void milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *));
-static void milter_delrcpt __P((char *, ssize_t, ENVELOPE *));
-static int milter_replbody __P((char *, ssize_t, bool, ENVELOPE *));
+static void milter_chgfrom __P((char *, ssize_t, ENVELOPE *, const char *));
+static void milter_addrcpt __P((char *, ssize_t, ENVELOPE *, const char *));
+static void milter_addrcpt_par __P((char *, ssize_t, ENVELOPE *, const char *));
+static void milter_delrcpt __P((char *, ssize_t, ENVELOPE *, const char *));
+static int milter_replbody __P((char *, ssize_t, bool, ENVELOPE *, const char *));
static int milter_set_macros __P((char *, char **, char *, int));
@@ -397,7 +397,7 @@ milter_read(m, cmd, rlen, to, e, where)
mi_int32 i;
# if MILTER_NO_NAGLE && defined(TCP_CORK)
int cork = 0;
-# endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
+# endif
char *buf;
char data[MILTER_LEN_BYTES + 1];
@@ -420,7 +420,7 @@ milter_read(m, cmd, rlen, to, e, where)
# if MILTER_NO_NAGLE && defined(TCP_CORK)
setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
sizeof(cork));
-# endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
+# endif
if (milter_sysread(m, data, sizeof(data), to, e, where) == NULL)
return NULL;
@@ -429,7 +429,7 @@ milter_read(m, cmd, rlen, to, e, where)
cork = 1;
setsockopt(m->mf_sock, IPPROTO_TCP, TCP_CORK, (char *)&cork,
sizeof(cork));
-# endif /* MILTER_NO_NAGLE && defined(TCP_CORK) */
+# endif
/* reset timeout */
if (to > 0)
@@ -690,7 +690,7 @@ milter_open(m, parseonly, e)
# if NETUNIX
/* default to AF_UNIX */
addr.sa.sa_family = AF_UNIX;
-# else /* NETUNIX */
+# else
# if NETINET
/* default to AF_INET */
addr.sa.sa_family = AF_INET;
@@ -714,22 +714,22 @@ milter_open(m, parseonly, e)
else if (sm_strcasecmp(p, "unix") == 0 ||
sm_strcasecmp(p, "local") == 0)
addr.sa.sa_family = AF_UNIX;
-# endif /* NETUNIX */
+# endif
# if NETINET
else if (sm_strcasecmp(p, "inet") == 0)
addr.sa.sa_family = AF_INET;
-# endif /* NETINET */
+# endif
# if NETINET6
else if (sm_strcasecmp(p, "inet6") == 0)
addr.sa.sa_family = AF_INET6;
-# endif /* NETINET6 */
+# endif
else
{
# ifdef EPROTONOSUPPORT
errno = EPROTONOSUPPORT;
-# else /* EPROTONOSUPPORT */
+# else
errno = EINVAL;
-# endif /* EPROTONOSUPPORT */
+# endif
if (tTd(64, 5))
sm_dprintf("X%s: unknown socket type %s\n",
m->mf_name, p);
@@ -820,10 +820,10 @@ milter_open(m, parseonly, e)
if (false
# if NETINET
|| addr.sa.sa_family == AF_INET
-# endif /* NETINET */
+# endif
# if NETINET6
|| addr.sa.sa_family == AF_INET6
-# endif /* NETINET6 */
+# endif
)
{
unsigned short port;
@@ -898,10 +898,10 @@ milter_open(m, parseonly, e)
bool found = false;
# if NETINET
unsigned long hid = INADDR_NONE;
-# endif /* NETINET */
+# endif
# if NETINET6
struct sockaddr_in6 hid6;
-# endif /* NETINET6 */
+# endif
*end = '\0';
# if NETINET
@@ -1016,7 +1016,7 @@ milter_open(m, parseonly, e)
milter_error(m, e);
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return -1;
}
}
@@ -1044,7 +1044,7 @@ milter_open(m, parseonly, e)
# if NETINET6
if (hp != NULL)
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return 0;
}
@@ -1060,7 +1060,7 @@ milter_open(m, parseonly, e)
# if NETINET6
if (hp != NULL)
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return -1;
}
@@ -1083,7 +1083,7 @@ milter_open(m, parseonly, e)
# if NETINET6
if (hp != NULL)
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return -1;
}
@@ -1153,7 +1153,7 @@ milter_open(m, parseonly, e)
milter_error(m, e);
# if NETINET6
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return -1;
}
continue;
@@ -1172,7 +1172,7 @@ milter_open(m, parseonly, e)
# if NETINET6
if (hp != NULL)
freehostent(hp);
-# endif /* NETINET6 */
+# endif
return -1;
}
m->mf_state = SMFS_OPEN;
@@ -1230,7 +1230,7 @@ milter_setup(line)
/* collect the filter name */
for (p = line;
- *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
+ *p != '\0' && *p != ',' && !(SM_ISSPACE(*p));
p++)
continue;
if (*p != '\0')
@@ -1261,7 +1261,7 @@ milter_setup(line)
char *delimptr;
while (*p != '\0' &&
- (*p == ',' || (isascii(*p) && isspace(*p))))
+ (*p == ',' || (SM_ISSPACE(*p))))
p++;
/* p now points to field code */
@@ -1273,7 +1273,7 @@ milter_setup(line)
syserr("X%s: `=' expected", m->mf_name);
return;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* p now points to the field body */
@@ -1292,7 +1292,7 @@ milter_setup(line)
case 'F': /* Milter flags configured on MTA */
for (; *p != '\0'; p++)
{
- if (!(isascii(*p) && isspace(*p)))
+ if (!(SM_ISSPACE(*p)))
setbitn(bitidx(*p), m->mf_flags);
}
break;
@@ -1365,7 +1365,7 @@ milter_config(spec, list, max)
{
STAB *s;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
break;
@@ -1427,8 +1427,7 @@ milter_parse_timeouts(spec, m)
{
char *delimptr;
- while (*p != '\0' &&
- (*p == ';' || (isascii(*p) && isspace(*p))))
+ while (*p != '\0' && (*p == ';' || (SM_ISSPACE(*p))))
p++;
/* p now points to field code */
@@ -1440,7 +1439,7 @@ milter_parse_timeouts(spec, m)
syserr("X%s, T=: `:' expected", m->mf_name);
return;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* p now points to the field body */
@@ -1514,8 +1513,7 @@ milter_set_macros(name, macros, val, nummac)
char *macro;
/* Skip leading commas, spaces */
- while (*p != '\0' &&
- (*p == ',' || (isascii(*p) && isspace(*p))))
+ while (*p != '\0' && (*p == ',' || (SM_ISSPACE(*p))))
p++;
if (*p == '\0')
@@ -1577,7 +1575,7 @@ static struct milteropt
# if _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE
# define MO_MAXDATASIZE 0x08
{ "maxdatasize", MO_MAXDATASIZE },
-# endif /* _FFR_MAXDATASIZE || _FFR_MDS_NEGOTIATE */
+# endif
{ NULL, (unsigned char)-1 },
};
@@ -1686,7 +1684,7 @@ milter_set_option(name, val, sticky)
** e -- current envelope.
**
** Returns:
-** 0 if succesful, -1 otherwise
+** 0 if successful, -1 otherwise
*/
static int
@@ -1741,7 +1739,7 @@ milter_reopen_df(e)
** e -- current envelope.
**
** Returns:
-** 0 if succesful, -1 otherwise
+** 0 if successful, -1 otherwise
*/
static int
@@ -2332,18 +2330,14 @@ milter_getsymlist(m, buf, rlen, offset)
macros = MilterMacros[i][m->mf_idx];
m->mf_lflags |= MI_LFLAGS_SYM(i);
len = strlen(buf + offset);
- if (len >= 0)
- {
- r = milter_set_macros(m->mf_name, macros,
- buf + offset, nummac);
- if (r >= 0)
- nummac = r;
- if (tTd(64, 5))
- sm_dprintf("milter_getsymlist(%s, %s, \"%s\")=%d\n",
- m->mf_name,
- SM_M_MACRO_NAME(i),
- buf + offset, r);
- }
+ r = milter_set_macros(m->mf_name, macros, buf + offset,
+ nummac);
+ if (r >= 0)
+ nummac = r;
+ if (tTd(64, 5))
+ sm_dprintf("milter_getsymlist(%s, %s, \"%s\")=%d\n",
+ m->mf_name, SM_M_MACRO_NAME(i),
+ buf + offset, r);
break;
default:
@@ -2441,8 +2435,7 @@ milter_negotiate(m, e, milters)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): negotiate: returned %c instead of %c",
m->mf_name, rcmd, SMFIC_OPTNEG);
- if (response != NULL)
- sm_free(response); /* XXX */
+ SM_FREE(response);
milter_error(m, e);
return -1;
}
@@ -2457,8 +2450,7 @@ milter_negotiate(m, e, milters)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): negotiate: did not return valid info",
m->mf_name);
- if (response != NULL)
- sm_free(response); /* XXX */
+ SM_FREE(response);
milter_error(m, e);
return -1;
}
@@ -2476,8 +2468,7 @@ milter_negotiate(m, e, milters)
sm_syslog(LOG_ERR, e->e_id,
"Milter (%s): negotiate: did not return enough info",
m->mf_name);
- if (response != NULL)
- sm_free(response); /* XXX */
+ SM_FREE(response);
milter_error(m, e);
return -1;
}
@@ -2523,38 +2514,36 @@ milter_negotiate(m, e, milters)
}
#if _FFR_MDS_NEGOTIATE
+#define MDSWARNING(sz) \
+ do \
+ { \
+ sm_syslog(LOG_WARNING, NOQID, \
+ "WARNING: Milter.maxdatasize: configured=%lu, set by milter(%s)=%d", \
+ (unsigned long) MilterMaxDataSize, m->mf_name, sz); \
+ MilterMaxDataSize = sz; \
+ } while (0)
+
/* use a table instead of sequence? */
if (bitset(SMFIP_MDS_1M, m->mf_pflags))
{
if (MilterMaxDataSize != MILTER_MDS_1M)
- {
- /* this should not happen... */
- sm_syslog(LOG_WARNING, NOQID,
- "WARNING: Milter.maxdatasize: configured=%lu, set by libmilter=%d",
- (unsigned long) MilterMaxDataSize,
- MILTER_MDS_1M);
- MilterMaxDataSize = MILTER_MDS_1M;
- }
+ MDSWARNING(MILTER_MDS_1M);
}
else if (bitset(SMFIP_MDS_256K, m->mf_pflags))
{
if (MilterMaxDataSize != MILTER_MDS_256K)
- {
- sm_syslog(LOG_WARNING, NOQID,
- "WARNING: Milter.maxdatasize: configured=%lu, set by libmilter=%d",
- (unsigned long) MilterMaxDataSize,
- MILTER_MDS_256K);
- MilterMaxDataSize = MILTER_MDS_256K;
- }
+ MDSWARNING(MILTER_MDS_256K);
}
+
+ /*
+ ** Note: it is not possible to distinguish between
+ ** - milter requested 64K
+ ** - milter did not request anything
+ ** as there is no SMFIP_MDS_64K flag.
+ */
+
else if (MilterMaxDataSize != MILTER_MDS_64K)
- {
- sm_syslog(LOG_WARNING, NOQID,
- "WARNING: Milter.maxdatasize: configured=%lu, set by libmilter=%d",
- (unsigned long) MilterMaxDataSize,
- MILTER_MDS_64K);
- MilterMaxDataSize = MILTER_MDS_64K;
- }
+ MDSWARNING(MILTER_MDS_64K);
m->mf_pflags &= ~SMFI_INTERNAL;
#endif /* _FFR_MDS_NEGOTIATE */
@@ -2593,11 +2582,11 @@ milter_negotiate(m, e, milters)
if (tTd(64, 5))
sm_dprintf("milter_negotiate(%s): received: version %u, fflags 0x%x, pflags 0x%x\n",
m->mf_name, m->mf_fvers, m->mf_fflags, m->mf_pflags);
+ SM_FREE(response);
return 0;
error:
- if (response != NULL)
- sm_free(response); /* XXX */
+ SM_FREE(response);
return -1;
}
@@ -2799,7 +2788,7 @@ milter_body(m, e, state)
#if !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF
/* Not a CRLF already? */
if (prevchar != '\r')
-#endif /* !_FFR_MILTER_CONVERT_ALL_LF_TO_CRLF */
+#endif
{
/* Room for CR now? */
if (bp + 2 > &buf[sizeof(buf)])
@@ -3003,8 +2992,8 @@ milter_addheader(m, response, rlen, e)
h->h_field, mh_value);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
- "Milter change: default header %s value with %s",
- h->h_field, mh_value);
+ "Milter (%s) change: default header %s value with %s",
+ m->mf_name, h->h_field, mh_value);
if (bitset(SMFIP_HDR_LEADSPC, m->mf_pflags))
h->h_value = mh_value;
else
@@ -3020,8 +3009,8 @@ milter_addheader(m, response, rlen, e)
sm_dprintf("Add %s: %s\n", response, mh_value);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
- "Milter add: header: %s: %s",
- response, mh_value);
+ "Milter (%s) add: header: %s: %s",
+ m->mf_name, response, mh_value);
addheader(newstr(response), mh_value, H_USER, e,
!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
SM_FREE(mh_value);
@@ -3104,8 +3093,8 @@ milter_insheader(m, response, rlen, e)
sm_dprintf("Insert (%d) %s: %s\n", idx, field, val);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
- "Milter insert (%d): header: %s: %s",
- idx, field, val);
+ "Milter (%s) insert (%d): header: %s: %s",
+ m->mf_name, idx, field, val);
mh_v_len = 0;
mh_value = quote_internal_chars(val, NULL, &mh_v_len);
insheader(idx, newstr(field), mh_value, H_USER, e,
@@ -3195,8 +3184,9 @@ milter_changeheader(m, response, rlen, e)
!bitset(H_TRACE, h->h_flags))
{
/*
- ** DRUMS msg-fmt draft says can only have
- ** multiple occurences of trace fields,
+ ** RFC 2822:
+ ** 27. No multiple occurrences of fields
+ ** (except resent and received).*
** so make sure we replace any non-trace,
** non-user field.
*/
@@ -3218,8 +3208,8 @@ milter_changeheader(m, response, rlen, e)
sm_dprintf("Delete (noop) %s\n", field);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
- "Milter delete (noop): header: %s"
- , field);
+ "Milter (%s) delete (noop): header: %s"
+ , m->mf_name, field);
}
else
{
@@ -3228,11 +3218,12 @@ milter_changeheader(m, response, rlen, e)
sm_dprintf("Add %s: %s\n", field, mh_value);
if (MilterLogLevel > 8)
sm_syslog(LOG_INFO, e->e_id,
- "Milter change (add): header: %s: %s"
- , field, mh_value);
+ "Milter (%s) change (add): header: %s: %s"
+ , m->mf_name, field, mh_value);
addheader(newstr(field), mh_value, H_USER, e,
!bitset(SMFIP_HDR_LEADSPC, m->mf_pflags));
}
+ SM_FREE(mh_value);
return;
}
@@ -3260,7 +3251,8 @@ milter_changeheader(m, response, rlen, e)
if (*val == '\0')
{
sm_syslog(LOG_INFO, e->e_id,
- "Milter delete: header%s %s:%s",
+ "Milter (%s) delete: header%s %s:%s",
+ m->mf_name,
h == sysheader ? " (default header)" : "",
field,
h->h_value == NULL ? "<NULL>" : h->h_value);
@@ -3268,7 +3260,8 @@ milter_changeheader(m, response, rlen, e)
else
{
sm_syslog(LOG_INFO, e->e_id,
- "Milter change: header%s %s: from %s to %s",
+ "Milter (%s) change: header%s %s: from %s to %s",
+ m->mf_name,
h == sysheader ? " (default header)" : "",
field,
h->h_value == NULL ? "<NULL>" : h->h_value,
@@ -3398,16 +3391,18 @@ milter_split_response(response, rlen, pargc)
** response -- encoded form of recipient address.
** rlen -- length of response.
** e -- current envelope.
+** mname -- name of milter.
**
** Returns:
** none
*/
static void
-milter_chgfrom(response, rlen, e)
+milter_chgfrom(response, rlen, e, mname)
char *response;
ssize_t rlen;
ENVELOPE *e;
+ const char *mname;
{
int olderrors, argc;
char **argv;
@@ -3435,12 +3430,15 @@ milter_chgfrom(response, rlen, e)
if (tTd(64, 10))
sm_dprintf("%s\n", response);
if (MilterLogLevel > 8)
- sm_syslog(LOG_INFO, e->e_id, "Milter chgfrom: %s", response);
+ sm_syslog(LOG_INFO, e->e_id, "Milter (%s) chgfrom: %s",
+ mname, response);
argv = milter_split_response(response, rlen, &argc);
if (argc < 1 || argc > 2)
{
if (tTd(64, 10))
sm_dprintf("didn't follow protocol argc=%d\n", argc);
+ if (argv != NULL)
+ free(argv);
return;
}
@@ -3459,6 +3457,7 @@ milter_chgfrom(response, rlen, e)
mail_esmtp_args);
}
Errors = olderrors;
+ free(argv);
return;
}
@@ -3469,16 +3468,18 @@ milter_chgfrom(response, rlen, e)
** response -- encoded form of recipient address.
** rlen -- length of response.
** e -- current envelope.
+** mname -- name of milter.
**
** Returns:
** none
*/
static void
-milter_addrcpt_par(response, rlen, e)
+milter_addrcpt_par(response, rlen, e, mname)
char *response;
ssize_t rlen;
ENVELOPE *e;
+ const char *mname;
{
int olderrors, argc;
char *delimptr;
@@ -3499,13 +3500,16 @@ milter_addrcpt_par(response, rlen, e)
if (tTd(64, 10))
sm_dprintf("%s\n", response);
if (MilterLogLevel > 8)
- sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
+ sm_syslog(LOG_INFO, e->e_id, "Milter (%s) add: rcpt: %s",
+ mname, response);
argv = milter_split_response(response, rlen, &argc);
if (argc < 1 || argc > 2)
{
if (tTd(64, 10))
sm_dprintf("didn't follow protocol argc=%d\n", argc);
+ if (argv != NULL)
+ free(argv);
return;
}
olderrors = Errors;
@@ -3526,10 +3530,11 @@ milter_addrcpt_par(response, rlen, e)
else
{
sm_dprintf("a=%p, olderrors=%d, Errors=%d\n",
- a, olderrors, Errors);
+ (void *)a, olderrors, Errors);
}
Errors = olderrors;
+ free(argv);
return;
}
@@ -3540,16 +3545,18 @@ milter_addrcpt_par(response, rlen, e)
** response -- encoded form of recipient address.
** rlen -- length of response.
** e -- current envelope.
+** mname -- name of milter.
**
** Returns:
** none
*/
static void
-milter_addrcpt(response, rlen, e)
+milter_addrcpt(response, rlen, e, mname)
char *response;
ssize_t rlen;
ENVELOPE *e;
+ const char *mname;
{
int olderrors;
@@ -3576,7 +3583,8 @@ milter_addrcpt(response, rlen, e)
if (tTd(64, 10))
sm_dprintf("%s\n", response);
if (MilterLogLevel > 8)
- sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response);
+ sm_syslog(LOG_INFO, e->e_id, "Milter (%s) add: rcpt: %s",
+ mname, response);
olderrors = Errors;
(void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e);
Errors = olderrors;
@@ -3590,17 +3598,21 @@ milter_addrcpt(response, rlen, e)
** response -- encoded form of recipient address.
** rlen -- length of response.
** e -- current envelope.
+** mname -- name of milter.
**
** Returns:
** none
*/
static void
-milter_delrcpt(response, rlen, e)
+milter_delrcpt(response, rlen, e, mname)
char *response;
ssize_t rlen;
ENVELOPE *e;
+ const char *mname;
{
+ int r;
+
if (tTd(64, 10))
sm_dprintf("milter_delrcpt: ");
@@ -3623,10 +3635,10 @@ milter_delrcpt(response, rlen, e)
if (tTd(64, 10))
sm_dprintf("%s\n", response);
+ r = removefromlist(response, &e->e_sendqueue, e);
if (MilterLogLevel > 8)
- sm_syslog(LOG_INFO, e->e_id, "Milter delete: rcpt %s",
- response);
- (void) removefromlist(response, &e->e_sendqueue, e);
+ sm_syslog(LOG_INFO, e->e_id, "Milter (%s) delete: rcpt %s, naddrs=%d",
+ mname, response, r);
return;
}
@@ -3638,17 +3650,19 @@ milter_delrcpt(response, rlen, e)
** rlen -- length of response.
** newfilter -- if first time called by a new filter
** e -- current envelope.
+** mname -- name of milter.
**
** Returns:
** 0 upon success, -1 upon failure
*/
static int
-milter_replbody(response, rlen, newfilter, e)
+milter_replbody(response, rlen, newfilter, e, mname)
char *response;
ssize_t rlen;
bool newfilter;
ENVELOPE *e;
+ const char *mname;
{
static char prevchar;
int i;
@@ -3730,7 +3744,8 @@ milter_replbody(response, rlen, newfilter, e)
}
if (newfilter && MilterLogLevel > 8)
- sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced");
+ sm_syslog(LOG_INFO, e->e_id, "Milter (%s) message: body replaced",
+ mname);
if (response == NULL)
{
@@ -3898,7 +3913,7 @@ milter_connect(hostname, addr, e, state)
ssize_t s;
# if NETINET6
char buf6[INET6_ADDRSTRLEN];
-# endif /* NETINET6 */
+# endif
if (tTd(64, 10))
sm_dprintf("milter_connect(%s)\n", hostname);
@@ -4164,7 +4179,7 @@ milter_envfrom(args, e, state)
** MILTER_ENVRCPT -- send SMTP RCPT command info to milter filters
**
** Parameters:
-** args -- SMTP MAIL command args (args[0] == recipient).
+** args -- SMTP RCPT command args (args[0] == recipient).
** e -- current envelope.
** state -- return state from response.
** rcpt_error -- does RCPT have an error?
@@ -4553,7 +4568,7 @@ milter_data(e, state)
"milter_data(%s) lied about changing sender, honoring request anyway",
m->mf_name);
}
- milter_chgfrom(response, rlen, e);
+ milter_chgfrom(response, rlen, e, m->mf_name);
break;
case SMFIR_ADDRCPT:
@@ -4564,7 +4579,7 @@ milter_data(e, state)
"milter_data(%s) lied about adding recipients, honoring request anyway",
m->mf_name);
}
- milter_addrcpt(response, rlen, e);
+ milter_addrcpt(response, rlen, e, m->mf_name);
break;
case SMFIR_ADDRCPT_PAR:
@@ -4575,7 +4590,7 @@ milter_data(e, state)
"milter_data(%s) lied about adding recipients with parameters, honoring request anyway",
m->mf_name);
}
- milter_addrcpt_par(response, rlen, e);
+ milter_addrcpt_par(response, rlen, e, m->mf_name);
break;
case SMFIR_DELRCPT:
@@ -4586,7 +4601,7 @@ milter_data(e, state)
"milter_data(%s): lied about removing recipients, honoring request anyway",
m->mf_name);
}
- milter_delrcpt(response, rlen, e);
+ milter_delrcpt(response, rlen, e, m->mf_name);
break;
case SMFIR_REPLBODY:
@@ -4615,8 +4630,8 @@ milter_data(e, state)
rewind = true;
}
- if (milter_replbody(response, rlen,
- newfilter, e) < 0)
+ if (milter_replbody(response, rlen, newfilter,
+ e, m->mf_name) < 0)
replfailed = true;
newfilter = false;
replbody = true;
@@ -4644,7 +4659,7 @@ milter_data(e, state)
if (replbody && !replfailed)
{
/* flush possible buffered character */
- milter_replbody(NULL, 0, !replbody, e);
+ milter_replbody(NULL, 0, !replbody, e, m->mf_name);
replbody = false;
}
@@ -4663,7 +4678,7 @@ finishup:
*state == SMFIR_ACCEPT)
{
*state = SMFIR_TEMPFAIL;
- SM_FREE_CLR(response);
+ SM_FREE(response);
}
if (dfopen)
@@ -4687,11 +4702,10 @@ finishup:
** an error, we can't really keep it, tempfail it.
*/
- if (*state == SMFIR_CONTINUE ||
- *state == SMFIR_ACCEPT)
+ if (*state == SMFIR_CONTINUE || *state == SMFIR_ACCEPT)
{
*state = SMFIR_TEMPFAIL;
- SM_FREE_CLR(response);
+ SM_FREE(response);
}
errno = save_errno;
diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c
index ecfc761dd2e3..48849d6a48ea 100644
--- a/contrib/sendmail/src/mime.c
+++ b/contrib/sendmail/src/mime.c
@@ -36,7 +36,7 @@ SM_RCSID("@(#)$Id: mime.c,v 8.149 2013-11-22 20:51:56 ca Exp $")
/* use "old" mime 7 to 8 algorithm by default */
#ifndef MIME7TO8_OLD
# define MIME7TO8_OLD 1
-#endif /* ! MIME7TO8_OLD */
+#endif
#if MIME8TO7
static int isboundary __P((char *, char **));
@@ -246,7 +246,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
# ifdef USE_B_CLASS
if (wordinclass(buf, 'b') || wordinclass(type, 'b'))
MapNLtoCRLF = false;
-# endif /* USE_B_CLASS */
+# endif
if (wordinclass(buf, 'q') || wordinclass(type, 'q'))
use_qp = true;
@@ -282,7 +282,7 @@ mime8to7(mci, header, e, boundaries, flags, level)
else
{
p = argv[i].a_value;
- stripquotes(p);
+ unfoldstripquotes(p);
}
if (sm_strlcpy(bbuf, p, sizeof(bbuf)) >= sizeof(bbuf))
{
@@ -904,7 +904,7 @@ mimeboundary(line, boundaries)
while (i > 0 && (line[i - 1] == ' ' || line[i - 1] == '\t'
#if _FFR_MIME_CR_OK
|| line[i - 1] == '\r'
-#endif /* _FFR_MIME_CR_OK */
+#endif
))
i--;
savec = line[i];
@@ -1103,27 +1103,27 @@ mime7to8(mci, header, e)
while ((c1 = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT)) !=
SM_IO_EOF)
{
- if (isascii(c1) && isspace(c1))
+ if (SM_ISSPACE(c1))
continue;
do
{
c2 = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT);
- } while (isascii(c2) && isspace(c2));
+ } while (SM_ISSPACE(c2));
if (c2 == SM_IO_EOF)
break;
do
{
c3 = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT);
- } while (isascii(c3) && isspace(c3));
+ } while (SM_ISSPACE(c3));
if (c3 == SM_IO_EOF)
break;
do
{
c4 = sm_io_getc(e->e_dfp, SM_TIME_DEFAULT);
- } while (isascii(c4) && isspace(c4));
+ } while (SM_ISSPACE(c4));
if (c4 == SM_IO_EOF)
break;
diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c
index 2adb39caf0c4..58dde0f92465 100644
--- a/contrib/sendmail/src/parseaddr.c
+++ b/contrib/sendmail/src/parseaddr.c
@@ -134,6 +134,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
*/
qup = false;
+ e->e_flags |= EF_SECURE;
if (REWRITE(pvp, 3, e) == EX_TEMPFAIL)
qup = true;
if (REWRITE(pvp, 0, e) == EX_TEMPFAIL)
@@ -165,6 +166,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
*/
allocaddr(a, flags, addr, e);
+ e->e_flags &= ~EF_SECURE;
if (QS_IS_BADADDR(a->q_state))
{
/* weed out bad characters in the printable address too */
@@ -218,7 +220,7 @@ parseaddr(addr, a, flags, delim, delimptr, e, isrcpt)
msg = "Deferring message until queue run";
if (tTd(20, 1))
sm_dprintf("parseaddr: queueing message\n");
- message(msg);
+ message("%s", msg);
if (e->e_message == NULL && e->e_sendmode != SM_DEFER)
e->e_message = sm_rpool_strdup_x(e->e_rpool, msg);
a->q_state = QS_QUEUEUP;
@@ -273,12 +275,14 @@ invalidaddr(addr, delimptr, isrcpt)
}
for (; *addr != '\0'; addr++)
{
+#if !_FFR_EAI
if (!EightBitAddrOK && (*addr & 0340) == 0200)
{
setstat(EX_USAGE);
result = true;
*addr = BAD_CHAR_REPLACEMENT;
}
+#endif
if (++len > MAXNAME - 1)
{
char saved = *addr;
@@ -350,7 +354,7 @@ hasctrlchar(addr, isrcpt, complain)
}
result = "too long";
}
- if (!EightBitAddrOK && !quoted && (*addr < 32 || *addr == 127))
+ if (!quoted && ((unsigned char)*addr < 32 || *addr == 127))
{
result = "non-printable character";
*addr = BAD_CHAR_REPLACEMENT;
@@ -368,6 +372,7 @@ hasctrlchar(addr, isrcpt, complain)
break;
}
}
+#if !_FFR_EAI
if (!EightBitAddrOK && (*addr & 0340) == 0200)
{
setstat(EX_USAGE);
@@ -375,6 +380,7 @@ hasctrlchar(addr, isrcpt, complain)
*addr = BAD_CHAR_REPLACEMENT;
continue;
}
+#endif
}
if (quoted)
result = "unbalanced quote"; /* unbalanced quote */
@@ -416,7 +422,7 @@ allocaddr(a, flags, paddr, e)
ENVELOPE *e;
{
if (tTd(24, 4))
- sm_dprintf("allocaddr(flags=%x, paddr=%s)\n", flags, paddr);
+ sm_dprintf("allocaddr(flags=%x, paddr=%s, ad=%d)\n", flags, paddr, bitset(EF_SECURE, e->e_flags));
a->q_paddr = paddr;
@@ -425,6 +431,9 @@ allocaddr(a, flags, paddr, e)
if (a->q_host == NULL)
a->q_host = "";
+ if (bitset(EF_SECURE, e->e_flags))
+ a->q_flags |= QSECURE;
+
if (bitset(RF_COPYPARSE, flags))
{
a->q_host = sm_rpool_strdup_x(e->e_rpool, a->q_host);
@@ -869,7 +878,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab, ignore)
char *ptr = p;
anglecnt++;
- while (isascii(*ptr) && isspace(*ptr))
+ while (SM_ISSPACE(*ptr))
ptr++;
if (*ptr == '@')
route_syntax = true;
@@ -888,7 +897,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab, ignore)
anglecnt--;
route_syntax = false;
}
- else if (delim == ' ' && isascii(c) && isspace(c))
+ else if (delim == ' ' && SM_ISSPACE(c))
c = ' ';
if (c == NOCHAR)
@@ -1351,7 +1360,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom)
pp = m->match_first;
while (pp <= m->match_last)
{
- sm_dprintf(" %p=\"", *pp);
+ sm_dprintf(" %p=\"", (void *)*pp);
sm_dflush();
sm_dprintf("%s\"", *pp++);
}
@@ -1805,6 +1814,7 @@ map_lookup(smap, key, argvect, pstat, e)
map = &smap->s_map;
DYNOPENMAP(map);
+ map->map_mflags |= MF_SECURE; /* default: secure */
if (e->e_sendmode == SM_DEFER &&
bitset(MF_DEFER, map->map_mflags))
@@ -1834,10 +1844,15 @@ map_lookup(smap, key, argvect, pstat, e)
sm_dprintf(") => ");
}
replac = (*map->map_class->map_lookup)(map, key, argvect, &status);
+ if (bitset(MF_SECURE, map->map_mflags))
+ map->map_mflags &= ~MF_SECURE;
+ else
+ e->e_flags &= ~EF_SECURE;
+
if (tTd(60, 1))
- sm_dprintf("%s (%d)\n",
+ sm_dprintf("%s (%d), ad=%d\n",
replac != NULL ? replac : "NOT FOUND",
- status);
+ status, bitset(MF_SECURE, map->map_mflags));
/* should recover if status == EX_TEMPFAIL */
if (status == EX_TEMPFAIL && !bitset(MF_NODEFER, map->map_mflags))
@@ -2287,8 +2302,8 @@ cataddr(pvp, evp, buf, sz, spacesub, external)
** If the current character (c) is METAQUOTE and we
** want the "external" form and the next character
** is not NUL, then overwrite METAQUOTE with that
- ** character (i.e., METAQUOTE ch is changed to
- ** ch). p[-1] is used because p is advanced (above).
+ ** character (i.e., METAQUOTE ch is changed to ch).
+ ** p[-1] is used because p is advanced (above).
*/
if ((c & 0377) == METAQUOTE && external && *q != '\0')
@@ -2439,6 +2454,10 @@ static struct qflags AddressFlags[] =
{ "QINTBCC", QINTBCC },
{ "QDYNMAILER", QDYNMAILER },
{ "QRCPTOK", QRCPTOK },
+ { "QSECURE", QSECURE },
+ { "QTHISPASS", QTHISPASS },
+ { "QRCPTOK", QRCPTOK },
+ { "QQUEUED", QQUEUED },
{ NULL, 0 }
};
@@ -2461,7 +2480,7 @@ printaddr(fp, a, follow)
while (a != NULL)
{
- (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%p=", a);
+ (void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "%p=", (void *)a);
(void) sm_io_flush(fp, SM_TIME_DEFAULT);
/* find the mailer -- carefully */
@@ -2564,7 +2583,7 @@ printaddr(fp, a, follow)
}
(void) sm_io_fprintf(fp, SM_TIME_DEFAULT,
", next=%p, alias %p, uid %d, gid %d\n",
- a->q_next, a->q_alias,
+ (void *)a->q_next, (void *)a->q_alias,
(int) a->q_uid, (int) a->q_gid);
(void) sm_io_fprintf(fp, SM_TIME_DEFAULT, "\tflags=%lx<",
a->q_flags);
@@ -2931,7 +2950,7 @@ dequote_init(map, args)
map->map_mflags |= MF_KEEPQUOTES;
for (;;)
{
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '-')
break;
@@ -2950,7 +2969,7 @@ dequote_init(map, args)
map->map_spacesub = *++p;
break;
}
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p = '\0';
@@ -3064,7 +3083,7 @@ dequote_map(map, name, av, statp)
** Parameters:
** rwset -- the rewriting set to use.
** p1 -- the first string to check.
-** p2 -- the second string to check -- may be null.
+** p2 -- the second string to check -- may be NULL.
** e -- the current envelope.
** flags -- control some behavior, see RSF_ in sendmail.h
** logl -- logging level.
@@ -3083,13 +3102,13 @@ dequote_map(map, name, av, statp)
int
rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr, addrstr)
char *rwset;
- char *p1;
- char *p2;
+ const char *p1;
+ const char *p2;
ENVELOPE *e;
int flags;
int logl;
- char *host;
- char *logid;
+ const char *host;
+ const char *logid;
ADDRESS *addr;
char **addrstr;
{
@@ -3239,7 +3258,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr, addrstr)
if (LogLevel > logl)
{
- char *relay;
+ const char *relay;
char *p;
char lbuf[MAXLINE];
@@ -3296,13 +3315,14 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid, addr, addrstr)
sm_exc_raisenew_x(&EtypeQuickAbort, 2);
return rstat;
}
+
/*
** RSCAP -- call rewriting set to return capabilities
**
** Parameters:
** rwset -- the rewriting set to use.
** p1 -- the first string to check.
-** p2 -- the second string to check -- may be null.
+** p2 -- the second string to check -- may be NULL.
** e -- the current envelope.
** pvp -- pointer to token vector.
** pvpbuf -- buffer space.
diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c
index a323301fd62b..526b40469486 100644
--- a/contrib/sendmail/src/queue.c
+++ b/contrib/sendmail/src/queue.c
@@ -26,13 +26,13 @@ SM_RCSID("@(#)$Id: queue.c,v 8.1000 2013-11-22 20:51:56 ca Exp $")
# if HASFLOCK && defined(O_EXLOCK)
# define SM_OPEN_EXLOCK 1
# define TF_OPEN_FLAGS (O_CREAT|O_WRONLY|O_EXCL|O_EXLOCK)
-# else /* HASFLOCK && defined(O_EXLOCK) */
+# else
# define TF_OPEN_FLAGS (O_CREAT|O_WRONLY|O_EXCL)
-# endif /* HASFLOCK && defined(O_EXLOCK) */
+# endif
#ifndef SM_OPEN_EXLOCK
# define SM_OPEN_EXLOCK 0
-#endif /* ! SM_OPEN_EXLOCK */
+#endif
/*
** Historical notes:
@@ -123,7 +123,7 @@ static WORKGRP volatile WorkGrp[MAXWORKGROUPS + 1]; /* work groups */
#if SM_HEAP_CHECK
static SM_DEBUG_T DebugLeakQ = SM_DEBUG_INITIALIZER("leak_q",
"@(#)$Debug: leak_q - trace memory leaks during queue processing $");
-#endif /* SM_HEAP_CHECK */
+#endif
static void grow_wlist __P((int, int));
static int multiqueue_cache __P((char *, int, QUEUEGRP *, int, unsigned int *));
@@ -139,7 +139,7 @@ static ADDRESS *setctluser __P((char *, int, ENVELOPE *));
#if _FFR_RHS
static int sm_strshufflecmp __P((char *, char *));
static void init_shuffle_alphabet __P(());
-#endif /* _FFR_RHS */
+#endif
/*
** Note: workcmpf?() don't use a prototype because it will cause a conflict
@@ -157,13 +157,13 @@ static int workcmpf5();
static int workcmpf6();
#if _FFR_RHS
static int workcmpf7();
-#endif /* _FFR_RHS */
+#endif
#if RANDOMSHIFT
# define get_rand_mod(m) ((get_random() >> RANDOMSHIFT) % (m))
-#else /* RANDOMSHIFT */
+#else
# define get_rand_mod(m) (get_random() % (m))
-#endif /* RANDOMSHIFT */
+#endif
/*
** File system definition.
@@ -185,6 +185,7 @@ static FILESYS FileSys[MAXFILESYS]; /* queue file systems */
static const char *FSPath[MAXFILESYS]; /* pathnames for file systems */
#if SM_CONF_SHM
+# include <ratectrl.h>
/*
** Shared memory data
@@ -198,7 +199,9 @@ static const char *FSPath[MAXFILESYS]; /* pathnames for file systems */
** NumFileSys -- number of file systems.
** FileSys -- (array of) structure for used file systems.
** RSATmpCnt -- counter for number of uses of ephemeral RSA key.
+** [OCC -- ...]
** QShm -- (array of) structure for information about queue directories.
+** this must be last as the size is depending on the config.
*/
/*
@@ -236,13 +239,21 @@ static size_t shms;
# define OFF_RSA_TMP_CNT(p) (((char *) (p)) + SHM_OFF_HEAD + sizeof(FileSys) + sizeof(int))
int *PRSATmpCnt;
+# if _FFR_OCC
+# define OFF_OCC_SHM(p) (((char *) (p)) + SHM_OFF_HEAD + sizeof(FileSys) + sizeof(int) * 2)
+# define OCC_SIZE (sizeof(CHash_T) * CPMHSIZE)
+static CHash_T *occ = NULL;
+# else
+# define OCC_SIZE 0
+# endif
+
/* offset for queue_shm */
-# define OFF_QUEUE_SHM(p) (((char *) (p)) + SHM_OFF_HEAD + sizeof(FileSys) + sizeof(int) * 2)
+# define OFF_QUEUE_SHM(p) (((char *) (p)) + SHM_OFF_HEAD + sizeof(FileSys) + sizeof(int) * 2 + OCC_SIZE)
# define QSHM_ENTRIES(i) QShm[i].qs_entries
/* basic size of shared memory segment */
-# define SM_T_SIZE (SHM_OFF_HEAD + sizeof(FileSys) + sizeof(int) * 2)
+# define SM_T_SIZE (SHM_OFF_HEAD + sizeof(FileSys) + sizeof(int) * 2 + OCC_SIZE)
static unsigned int hash_q __P((char *, unsigned int));
@@ -275,7 +286,6 @@ hash_q(p, h)
return h;
}
-
#else /* SM_CONF_SHM */
# define FILE_SYS(i) FileSys[i]
#endif /* SM_CONF_SHM */
@@ -293,11 +303,10 @@ hash_q(p, h)
** A AUTH= parameter
** B body type
** C controlling user
-** D data file name
+** D data file name (obsolete)
** d data file directory name (added in 8.12)
** E error recipient
** F flag bits
-** G free
** H header
** I data file's inode number
** K time of last delivery attempt
@@ -313,7 +322,6 @@ hash_q(p, h)
** T init time
** V queue file version
** X free (was: character set if _FFR_SAVE_CHARSET)
-** Y free
** Z original envelope id from ESMTP
** ! deliver by (added in 8.12)
** $ define macro
@@ -388,7 +396,7 @@ queueup(e, announce, msync)
if (tfd < 0 ||
#if !SM_OPEN_EXLOCK
!lockfile(tfd, tf, NULL, LOCK_EX|LOCK_NB) ||
-#endif /* !SM_OPEN_EXLOCK */
+#endif
(tfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
(void *) &tfd, SM_IO_WRONLY,
NULL)) == NULL)
@@ -398,7 +406,7 @@ queueup(e, announce, msync)
printopenfds(true);
errno = save_errno;
syserr("!queueup: cannot create queue file %s, euid=%ld, fd=%d, fp=%p",
- tf, (long) geteuid(), tfd, tfp);
+ tf, (long) geteuid(), tfd, (void *)tfp);
/* NOTREACHED */
}
e->e_lockfp = tfp;
@@ -427,18 +435,18 @@ queueup(e, announce, msync)
#if SM_OPEN_EXLOCK
else
break;
-#endif /* SM_OPEN_EXLOCK */
+#endif
}
if (tfd >= 0)
{
#if SM_OPEN_EXLOCK
/* file is locked by open() */
break;
-#else /* SM_OPEN_EXLOCK */
+#else
if (lockfile(tfd, tf, NULL, LOCK_EX|LOCK_NB))
break;
else
-#endif /* SM_OPEN_EXLOCK */
+#endif
if (LogLevel > 0 && (i % 32) == 0)
sm_syslog(LOG_ALERT, e->e_id,
"queueup: cannot lock %s: %s",
@@ -665,6 +673,10 @@ queueup(e, announce, msync)
*p++ = 'n';
if (bitset(EF_SPLIT, e->e_flags))
*p++ = 's';
+#if _FFR_EAI
+ if (e->e_smtputf8)
+ *p++ = 'e';
+#endif
*p++ = '\0';
if (buf[0] != '\0')
(void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "F%s\n", buf);
@@ -697,6 +709,7 @@ queueup(e, announce, msync)
printctladdr(NULL, NULL);
for (q = e->e_sendqueue; q != NULL; q = q->q_next)
{
+ q->q_flags &= ~QQUEUED;
if (!QS_IS_UNDELIVERED(q->q_state))
continue;
@@ -752,6 +765,14 @@ queueup(e, announce, msync)
tag, NULL, (time_t) 0, e, q, EX_OK);
e->e_to = NULL;
}
+
+ /*
+ ** This is only "valid" when the msg is safely in the queue,
+ ** i.e., EF_INQUEUE needs to be set.
+ */
+
+ q->q_flags |= QQUEUED;
+
if (tTd(40, 1))
{
sm_dprintf("queueing ");
@@ -1288,7 +1309,7 @@ schedule_queue_runs(runall, wgrp, didit)
#if _FFR_QUEUE_SCHED_DBG
time_t lastsched;
bool sched;
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
time_t now;
time_t minqintvl;
@@ -1307,7 +1328,7 @@ schedule_queue_runs(runall, wgrp, didit)
#if _FFR_QUEUE_SCHED_DBG
lastsched = 0;
sched = false;
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
qgrp = WorkGrp[wgrp].wg_qgs[cgrp]->qg_index;
if (Queue[qgrp]->qg_queueintvl > 0)
qintvl = Queue[qgrp]->qg_queueintvl;
@@ -1317,12 +1338,12 @@ schedule_queue_runs(runall, wgrp, didit)
qintvl = (time_t) 0;
#if _FFR_QUEUE_SCHED_DBG
lastsched = Queue[qgrp]->qg_nextrun;
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
if ((runall || Queue[qgrp]->qg_nextrun <= now) && qintvl > 0)
{
#if _FFR_QUEUE_SCHED_DBG
sched = true;
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
if (minqintvl == 0 || qintvl < minqintvl)
minqintvl = qintvl;
@@ -1340,9 +1361,10 @@ schedule_queue_runs(runall, wgrp, didit)
if (tTd(69, 10))
sm_syslog(LOG_INFO, NOQID,
"sqr: wgrp=%d, cgrp=%d, qgrp=%d, intvl=%ld, QI=%ld, runall=%d, lastrun=%ld, nextrun=%ld, sched=%d",
- wgrp, cgrp, qgrp, Queue[qgrp]->qg_queueintvl,
- QueueIntvl, runall, lastsched,
- Queue[qgrp]->qg_nextrun, sched);
+ wgrp, cgrp, qgrp,
+ (long) Queue[qgrp]->qg_queueintvl,
+ (long) QueueIntvl, runall, (long) lastsched,
+ (long) Queue[qgrp]->qg_nextrun, sched);
#endif /* _FFR_QUEUE_SCHED_DBG */
INCR_MOD(cgrp, WorkGrp[wgrp].wg_numqgrp);
} while (endgrp != cgrp);
@@ -1394,7 +1416,7 @@ checkqueuerunner()
"checkqueuerunner: queue %d should have been run at %s, queue interval %ld",
qgrp,
arpadate(ctime(&Queue[qgrp]->qg_nextrun)),
- qintvl);
+ (long) qintvl);
}
}
if (minqintvl > 0)
@@ -1584,7 +1606,7 @@ runqueue(forkflag, verbose, persistent, runall)
#if SM_HEAP_CHECK
if (sm_debug_active(&DebugLeakQ, 1))
sm_heap_setgroup(oldgroup);
-#endif /* SM_HEAP_CHECK */
+#endif
return ret;
}
@@ -1722,7 +1744,7 @@ runner_work(e, sequenceno, didfork, skip, njobs)
#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 *
+#endif
*/
#if _FFR_SKIP_DOMAINS
@@ -1840,7 +1862,17 @@ runner_work(e, sequenceno, didfork, skip, njobs)
#if SM_HEAP_CHECK
if (sm_debug_active(&DebugLeakQ, 1))
sm_heap_setgroup(oldgroup);
-#endif /* SM_HEAP_CHECK */
+#endif
+#if _FFR_TESTS
+ if (tTd(76, 101))
+ {
+ int sl;
+
+ sl = tTdlevel(76) - 100;
+ sm_dprintf("run_work_group: sleep=%d\n", sl);
+ sleep(sl);
+ }
+#endif
}
BlockOldsh = false;
@@ -2095,7 +2127,7 @@ run_work_group(wgrp, flags)
/* tweak niceness of queue runs */
if (Queue[qgrp]->qg_nice > 0)
(void) nice(Queue[qgrp]->qg_nice);
-#endif /* HASNICE */
+#endif
/* XXX running queue group... */
sm_setproctitle(true, CurEnv, "running queue: %s",
@@ -2120,7 +2152,7 @@ run_work_group(wgrp, flags)
#if SM_CONF_SHM
if (ShmId != SM_SHM_NO_ID)
QSHM_ENTRIES(Queue[qgrp]->qg_qpaths[qdir].qp_idx) = h;
-#endif /* SM_CONF_SHM */
+#endif
/* If there are no more items in this queue advance */
if (!more)
{
@@ -2332,12 +2364,12 @@ run_work_group(wgrp, flags)
/* Update MX records for FallbackMX. */
if (FallbackMX != NULL)
(void) getfallbackmxrr(FallbackMX);
-#endif /* NAMED_BIND */
+#endif
#if USERDB
/* close UserDatabase */
_udbx_close();
-#endif /* USERDB */
+#endif
#if SM_HEAP_CHECK
if (sm_debug_active(&SmHeapCheck, 2)
@@ -2441,7 +2473,7 @@ runqueueevent(ignore)
#if _FFR_QUEUE_SCHED_DBG
if (tTd(69, 10))
sm_syslog(LOG_INFO, NOQID, "rqe: done");
-#endif /* _FFR_QUEUE_SCHED_DBG */
+#endif
errno = save_errno;
if (errno == EINTR)
@@ -2514,7 +2546,7 @@ gatherq(qgrp, qdir, doall, full, more, pnentries)
if (tTd(41, 1))
{
- sm_dprintf("gatherq:\n");
+ sm_dprintf("gatherq: %s\n", qd);
check = QueueLimitId;
while (check != NULL)
@@ -2729,7 +2761,7 @@ gatherq(qgrp, qdir, doall, full, more, pnentries)
if (QueueSortOrder == QSO_BYHOST
#if _FFR_RHS
|| QueueSortOrder == QSO_BYSHUFFLE
-#endif /* _FFR_RHS */
+#endif
)
{
/* need w_host set for host sort order */
@@ -2816,7 +2848,7 @@ gatherq(qgrp, qdir, doall, full, more, pnentries)
if (QueueSortOrder == QSO_BYSHUFFLE)
w->w_host = newstr(&p[1]);
else
-#endif /* _FFR_RHS */
+#endif
w->w_host = strrev(&p[1]);
makelower(w->w_host);
i &= ~NEED_H;
@@ -4020,7 +4052,7 @@ readqf(e, openonly)
ST_INODE(st) != ST_INODE(stf) ||
#if HAS_ST_GEN && 0 /* AFS returns garbage in st_gen */
st.st_gen != stf.st_gen ||
-#endif /* HAS_ST_GEN && 0 */
+#endif
st.st_uid != stf.st_uid ||
st.st_gid != stf.st_gid ||
st.st_size != stf.st_size)
@@ -4163,7 +4195,7 @@ readqf(e, openonly)
#if _FFR_QUEUE_MACRO
macdefine(&e->e_macro, A_TEMP, macid("{queue}"),
qid_printqueue(e->e_qgrp, e->e_qdir));
-#endif /* _FFR_QUEUE_MACRO */
+#endif
e->e_dfino = -1;
e->e_msgsize = -1;
while (bufsize = sizeof(buf),
@@ -4217,7 +4249,7 @@ readqf(e, openonly)
/* forbid queue groups in MSP? */
if (UseMSP)
goto hackattack;
-#endif /* _FFR_MSP_PARANOIA */
+#endif
for (qgrp = 0;
qgrp < NumQueue && Queue[qgrp] != NULL;
++qgrp)
@@ -4285,6 +4317,12 @@ readqf(e, openonly)
case 'w': /* warning sent */
e->e_flags |= EF_WARNING;
break;
+
+#if _FFR_EAI
+ case 'e': /* message requires EAI */
+ e->e_smtputf8 = true;
+ break;
+#endif /* _FFR_EAI */
}
}
break;
@@ -4493,14 +4531,11 @@ readqf(e, openonly)
case '$': /* define macro */
{
- char *p;
-
- /* XXX elimate p? */
r = macid_parse(&bp[1], &ep);
if (r == 0)
break;
- p = sm_rpool_strdup_x(e->e_rpool, ep);
- macdefine(&e->e_macro, A_PERM, r, p);
+ macdefine(&e->e_macro, A_PERM, r,
+ sm_rpool_strdup_x(e->e_rpool, ep));
}
break;
@@ -4550,6 +4585,26 @@ readqf(e, openonly)
/* other checks? */
#endif /* _FFR_QF_PARANOIA */
+#if _FFR_EAI
+ /*
+ ** If this message originates from something other than
+ ** srvrsmtp.c, then it might use UTF8 addresses but not be
+ ** marked. We'll just add the mark so we're sure that it
+ ** either can be delivered or will be returned.
+ */
+
+ if (!e->e_smtputf8)
+ {
+ ADDRESS *q;
+
+ for (q = e->e_sendqueue; q != NULL; q = q->q_next)
+ if (!addr_is_ascii(q->q_paddr) && !e->e_smtputf8)
+ e->e_smtputf8 = true;
+ if (!addr_is_ascii(e->e_from.q_paddr) && !e->e_smtputf8)
+ e->e_smtputf8 = true;
+ }
+#endif /* _FFR_EAI */
+
/* possibly set ${dsn_ret} macro */
if (bitset(EF_RET_PARAM, e->e_flags))
{
@@ -4626,11 +4681,13 @@ readqf(e, openonly)
static void prtstr __P((char *, int));
#if _FFR_BOUNCE_QUEUE
-# define SKIP_BOUNCE_QUEUE \
- if (i == BounceQueue) \
+# define IS_BOUNCE_QUEUE(i) ((i) == BounceQueue)
+# define SKIP_BOUNCE_QUEUE(i) \
+ if (IS_BOUNCE_QUEUE(i)) \
continue;
#else
-# define SKIP_BOUNCE_QUEUE
+# define IS_BOUNCE_QUEUE(i) false
+# define SKIP_BOUNCE_QUEUE(i)
#endif
static void
@@ -4696,7 +4753,7 @@ printnqe(out, prefix)
{
int j;
- SKIP_BOUNCE_QUEUE
+ SKIP_BOUNCE_QUEUE(i)
k++;
for (j = 0; j < Queue[i]->qg_numqueues; j++)
{
@@ -4837,7 +4894,7 @@ print_single_queue(qgrp, qdir)
#ifdef NGROUPS_MAX
int n;
extern GIDSET_T InitialGidSet[NGROUPS_MAX];
-#endif /* NGROUPS_MAX */
+#endif
if (stat(qd, &st) < 0)
{
@@ -5448,7 +5505,7 @@ assign_queueid(e)
if (tTd(7, 1))
sm_dprintf("assign_queueid: assigned id %s, e=%p\n",
- e->e_id, e);
+ e->e_id, (void *)e);
if (LogLevel > 93)
sm_syslog(LOG_DEBUG, e->e_id, "assigned id");
}
@@ -5787,7 +5844,7 @@ pickqdir(qg, fsize, e)
#if _FFR_TESTS
if (tTd(4, 101))
return NOQDIR;
-#endif /* _FFR_TESTS */
+#endif
if (MinBlocksFree <= 0 && fsize <= 0)
return qdir;
@@ -5963,9 +6020,9 @@ chkqdir(name, sff)
return false;
#if HASLSTAT
if (lstat(name, &statb) < 0)
-#else /* HASLSTAT */
+#else
if (stat(name, &statb) < 0)
-#endif /* HASLSTAT */
+#endif
{
if (tTd(41, 2))
sm_dprintf("chkqdir: stat(\"%s\"): %s\n",
@@ -6081,7 +6138,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
sff |= SFF_SAFEDIRPATH|SFF_NOWWFILES;
if (!UseMSP)
sff |= SFF_NOGWFILES;
-#endif /* _FFR_CHK_QUEUE */
+#endif
if (!SM_IS_DIR_START(qg->qg_qdir))
{
@@ -6288,7 +6345,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
#if SM_CONF_SHM
qg->qg_qpaths[qg->qg_numqueues].qp_idx = qn;
*phash = hash_q(relpath, *phash);
-#endif /* SM_CONF_SHM */
+#endif
qg->qg_numqueues++;
++qn;
slotsleft--;
@@ -6345,7 +6402,7 @@ multiqueue_cache(basedir, blen, qg, qn, phash)
#if SM_CONF_SHM
qg->qg_qpaths[0].qp_idx = qn;
*phash = hash_q(qg->qg_qpaths[0].qp_name, *phash);
-#endif /* SM_CONF_SHM */
+#endif
++qn;
}
return qn;
@@ -6625,12 +6682,25 @@ disk_status(out, prefix)
** none.
*/
-#if _FFR_USE_SEM_LOCKING
-#if SM_CONF_SEM
+#if _FFR_USE_SEM_LOCKING && SM_CONF_SEM
static int SemId = -1; /* Semaphore Id */
int SemKey = SM_SEM_KEY;
-#endif /* SM_CONF_SEM */
-#endif /* _FFR_USE_SEM_LOCKING */
+# define SEM_LOCK(r) \
+ do \
+ { \
+ if (SemId >= 0) \
+ r = sm_sem_acq(SemId, 0, 1); \
+ } while (0)
+# define SEM_UNLOCK(r) \
+ do \
+ { \
+ if (SemId >= 0 && r >= 0) \
+ r = sm_sem_rel(SemId, 0, 1); \
+ } while (0)
+#else /* _FFR_USE_SEM_LOCKING && SM_CONF_SEM */
+# define SEM_LOCK(r)
+# define SEM_UNLOCK(r)
+#endif /* _FFR_USE_SEM_LOCKING && SM_CONF_SEM */
static void init_sem __P((bool));
@@ -6683,11 +6753,118 @@ stop_sem(owner)
#if SM_CONF_SEM
if (owner && SemId >= 0)
sm_sem_stop(SemId);
-#endif /* SM_CONF_SEM */
+#endif
#endif /* _FFR_USE_SEM_LOCKING */
return;
}
+# if _FFR_OCC
+/*
+** Todo: call occ_close()
+** when closing a connection to decrease #open connections (and rate!)
+** (currently done as hack in deliver())
+** must also be done if connection couldn't be opened (see daemon.c: OCC_CLOSE)
+*/
+
+/*
+** OCC_EXCEEDED -- is an outgoing connection limit exceeded?
+**
+** Parameters:
+** e -- envelope
+** mci -- mail connection information
+** host -- name of host
+** addr -- address of host
+**
+** Returns:
+** true iff an outgoing connection limit is exceeded
+*/
+
+bool
+occ_exceeded(e, mci, host, addr)
+ ENVELOPE *e;
+ MCI *mci;
+ const char *host;
+ SOCKADDR *addr;
+{
+ time_t now;
+ bool exc;
+ int r, ratelimit, conclimit;
+ char *limit; /* allocated from e_rpool by rscheck(), no need to free() */
+
+/* if necessary, some error checking for a number could be done here */
+#define STR2INT(r, limit, val) \
+ do \
+ { \
+ if ((r) == EX_OK && (limit) != NULL) \
+ (val) = atoi((limit)); \
+ } while (0);
+
+ if (occ == NULL || e == NULL)
+ return false;
+ ratelimit = conclimit = 0;
+ limit = NULL;
+ r = rscheck("oc_rate", host, anynet_ntoa(addr), e, RSF_ADDR,
+ 12, NULL, NOQID, NULL, &limit);
+ STR2INT(r, limit, ratelimit);
+ limit = NULL;
+ r = rscheck("oc_conc", host, anynet_ntoa(addr), e, RSF_ADDR,
+ 12, NULL, NOQID, NULL, &limit);
+ STR2INT(r, limit, conclimit);
+ now = curtime();
+
+ /* lock occ: lock entire shared memory segment */
+ SEM_LOCK(r);
+ exc = (bool) conn_limits(e, now, addr, SM_CLFL_EXC, occ, ratelimit,
+ conclimit);
+ SEM_UNLOCK(r);
+ if (!exc && mci != NULL)
+ mci->mci_flags |= MCIF_OCC_INCR;
+ return exc;
+}
+
+/*
+** OCC_CLOSE -- "close" an outgoing connection: up connection status
+**
+** Parameters:
+** e -- envelope
+** mci -- mail connection information
+** host -- name of host
+** addr -- address of host
+**
+** Returns:
+** true after successful update
+*/
+
+bool
+occ_close(e, mci, host, addr)
+ ENVELOPE *e;
+ MCI *mci;
+ const char *host;
+ SOCKADDR *addr;
+{
+ time_t now;
+# if _FFR_USE_SEM_LOCKING && SM_CONF_SEM
+ int r;
+# endif
+
+ if (occ == NULL || e == NULL)
+ return false;
+ if (mci == NULL || mci->mci_state == MCIS_CLOSED ||
+ bitset(MCIF_CACHED, mci->mci_flags) ||
+ !bitset(MCIF_OCC_INCR, mci->mci_flags))
+ return false;
+ mci->mci_flags &= ~MCIF_OCC_INCR;
+
+ now = curtime();
+
+ /* lock occ: lock entire shared memory segment */
+ SEM_LOCK(r);
+ (void) conn_limits(e, now, addr, SM_CLFL_EXC, occ, -1, -1);
+ SEM_UNLOCK(r);
+ return true;
+}
+# endif /* _FFR_OCC */
+
/*
** UPD_QS -- update information about queue when adding/deleting an entry
**
@@ -6717,7 +6894,7 @@ upd_qs(e, count, space, where)
int idx;
# if _FFR_USE_SEM_LOCKING
int r;
-# endif /* _FFR_USE_SEM_LOCKING */
+# endif
long s;
if (ShmId == SM_SHM_NO_ID || e == NULL)
@@ -6732,15 +6909,9 @@ upd_qs(e, count, space, where)
/* XXX in theory this needs to be protected with a mutex */
if (QSHM_ENTRIES(idx) >= 0 && count != 0)
{
-# if _FFR_USE_SEM_LOCKING
- if (SemId >= 0)
- r = sm_sem_acq(SemId, 0, 1);
-# endif /* _FFR_USE_SEM_LOCKING */
+ SEM_LOCK(r);
QSHM_ENTRIES(idx) += count;
-# if _FFR_USE_SEM_LOCKING
- if (SemId >= 0 && r >= 0)
- r = sm_sem_rel(SemId, 0, 1);
-# endif /* _FFR_USE_SEM_LOCKING */
+ SEM_UNLOCK(r);
}
fidx = Queue[e->e_qgrp]->qg_qpaths[e->e_qdir].qp_fsysidx;
@@ -7007,12 +7178,18 @@ init_shm(qn, owner, hash)
QShm = (QUEUE_SHM_T *) OFF_QUEUE_SHM(Pshm);
PRSATmpCnt = (int *) OFF_RSA_TMP_CNT(Pshm);
*PRSATmpCnt = 0;
+# if _FFR_OCC
+ occ = (CHash_T *) OFF_OCC_SHM(Pshm);
+# endif
if (owner)
{
/* initialize values in shared memory */
NumFileSys = 0;
for (i = 0; i < qn; i++)
QShm[i].qs_entries = -1;
+# if _FFR_OCC
+ memset(occ, 0, OCC_SIZE);
+# endif
}
init_sem(owner);
return;
@@ -7120,7 +7297,7 @@ setup_queues(owner)
}
#if SM_CONF_SHM
hashval = hash_q(basedir, hashval);
-#endif /* SM_CONF_SHM */
+#endif
/* initialize for queue runs */
DoQueueRun = false;
@@ -7163,7 +7340,7 @@ setup_queues(owner)
#if _FFR_MSP_PARANOIA
syserr("dangerous permissions=%o on queue directory %s",
(unsigned int) st.st_mode, basedir);
-#else /* _FFR_MSP_PARANOIA */
+#else
if (LogLevel > 0)
sm_syslog(LOG_ERR, NOQID,
"dangerous permissions=%o on queue directory %s",
@@ -7173,7 +7350,7 @@ setup_queues(owner)
#if _FFR_MSP_PARANOIA
if (NumQueue > 1)
syserr("can not use multiple queues for MSP");
-#endif /* _FFR_MSP_PARANOIA */
+#endif
}
/* initial number of queue directories */
@@ -7279,7 +7456,7 @@ set_def_queueval(qg, all)
qg->qg_qdir = QueueDir;
#if _FFR_QUEUE_GROUP_SORTORDER
qg->qg_sortorder = QueueSortOrder;
-#endif /* _FFR_QUEUE_GROUP_SORTORDER */
+#endif
qg->qg_maxqrun = all ? MaxRunnersPerQueue : -1;
qg->qg_nice = NiceQueueRun;
}
@@ -7331,7 +7508,7 @@ makequeue(line, qdef)
/* collect the queue name */
for (p = line;
- *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
+ *p != '\0' && *p != ',' && !(SM_ISSPACE(*p));
p++)
continue;
if (*p != '\0')
@@ -7346,8 +7523,7 @@ makequeue(line, qdef)
{
auto char *delimptr;
- while (*p != '\0' &&
- (*p == ',' || (isascii(*p) && isspace(*p))))
+ while (*p != '\0' && (*p == ',' || (SM_ISSPACE(*p))))
p++;
/* p now points to field code */
@@ -7359,7 +7535,7 @@ makequeue(line, qdef)
syserr("queue %s: `=' expected", qg->qg_name);
return;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* p now points to the field body */
@@ -7378,7 +7554,7 @@ makequeue(line, qdef)
case 'F': /* flags */
for (; *p != '\0'; p++)
- if (!(isascii(*p) && isspace(*p)))
+ if (!(SM_ISSPACE(*p)))
setbitn(*p, qg->qg_flags);
break;
@@ -7685,13 +7861,17 @@ makeworkgroups()
{
si[i].sg_maxqrun = Queue[i]->qg_maxqrun;
si[i].sg_idx = i;
+
+ /* Hack to make sure BounceQueue ends up last */
+ if (IS_BOUNCE_QUEUE(i))
+ si[i].sg_maxqrun = INT_MIN;
}
qsort(si, NumQueue, sizeof(si[0]), cmpidx);
NumWorkGroups = 0;
for (i = 0; i < NumQueue; i++)
{
- SKIP_BOUNCE_QUEUE
+ SKIP_BOUNCE_QUEUE(i)
total_runners += si[i].sg_maxqrun;
if (MaxQueueChildren <= 0 || total_runners <= MaxQueueChildren)
NumWorkGroups++;
@@ -7717,7 +7897,11 @@ makeworkgroups()
dir = 1;
for (i = 0; i < NumQueue; i++)
{
- SKIP_BOUNCE_QUEUE
+ h = si[i].sg_idx;
+ if (tTd(41, 49))
+ sm_dprintf("sortqg: i=%d, j=%d, h=%d, skip=%d\n",
+ i, j, h, IS_BOUNCE_QUEUE(h));
+ SKIP_BOUNCE_QUEUE(h);
/* a to-and-fro packing scheme, continue from last position */
if (j >= NumWorkGroups)
@@ -7745,7 +7929,6 @@ makeworkgroups()
(WorkGrp[j].wg_numqgrp + 1)));
}
- h = si[i].sg_idx;
WorkGrp[j].wg_qgs[WorkGrp[j].wg_numqgrp] = Queue[h];
WorkGrp[j].wg_numqgrp++;
WorkGrp[j].wg_runners += Queue[h]->qg_maxqrun;
@@ -7782,6 +7965,9 @@ makeworkgroups()
sm_dprintf("%s, ",
WorkGrp[i].wg_qgs[j]->qg_name);
}
+ if (tTd(41, 12))
+ sm_dprintf("lowqintvl=%d",
+ (int) WorkGrp[i].wg_lowqintvl);
sm_dprintf("\n");
}
}
@@ -8143,7 +8329,7 @@ split_across_queue_groups(e)
es = splits[i];
#if 0
es->e_qdir = pickqdir(Queue[es->e_qgrp], es->e_msgsize, es);
-#endif /* 0 */
+#endif
if (!setnewqueue(es))
goto failure;
}
@@ -8433,6 +8619,7 @@ split_by_recipient(e)
if (split_within_queue(ee) == SM_SPLIT_FAIL)
{
e->e_sibling = firstsibling;
+ SM_FREE(lsplits);
return false;
}
ee->e_flags |= EF_SPLIT;
@@ -8447,8 +8634,7 @@ split_by_recipient(e)
if (p == NULL)
{
/* let's try to get this done */
- sm_free(lsplits);
- lsplits = NULL;
+ SM_FREE(lsplits);
}
else
lsplits = p;
@@ -8470,7 +8656,7 @@ split_by_recipient(e)
{
sm_syslog(LOG_NOTICE, e->e_id, "split: count=%d, id%s=%s",
n - 1, n > 2 ? "s" : "", lsplits);
- sm_free(lsplits);
+ SM_FREE(lsplits);
}
split = split_within_queue(e) != SM_SPLIT_FAIL;
if (split)
diff --git a/contrib/sendmail/src/ratectrl.c b/contrib/sendmail/src/ratectrl.c
index cb7dca58b539..6b9d5c4af3fa 100644
--- a/contrib/sendmail/src/ratectrl.c
+++ b/contrib/sendmail/src/ratectrl.c
@@ -44,57 +44,38 @@
* SUCH DAMAGE.
*/
-#include <sendmail.h>
+#include <ratectrl.h>
SM_RCSID("@(#)$Id: ratectrl.c,v 8.14 2013-11-22 20:51:56 ca Exp $")
-/*
-** stuff included - given some warnings (inet_ntoa)
-** - surely not everything is needed
-*/
-
-#if NETINET || NETINET6
-# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
-
-#include <sm/time.h>
-
-#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 client_rate __P((time_t, SOCKADDR *, int));
static int total_rate __P((time_t, bool));
+static unsigned int gen_hash __P((SOCKADDR *));
+static void rate_init __P((void));
/*
** 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)
+** Parameters:
+** hostaddr -- IP address of SMTP client
+** e -- envelope
**
-** Side Effects:
-** updates connection history
+** Returns:
+** none
**
-** 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.
+** 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
+void
connection_rate_check(hostaddr, e)
SOCKADDR *hostaddr;
ENVELOPE *e;
@@ -106,16 +87,16 @@ connection_rate_check(hostaddr, e)
now = time(NULL);
#if RATECTL_DEBUG
sm_syslog(LOG_INFO, NOQID, "connection_rate_check entering...");
-#endif /* RATECTL_DEBUG */
+#endif
/* update server connection rate */
totalrate = total_rate(now, e == NULL);
#if RATECTL_DEBUG
sm_syslog(LOG_INFO, NOQID, "global connection rate: %d", totalrate);
-#endif /* RATECTL_DEBUG */
+#endif
/* update client connection rate */
- clientrate = client_rate(now, hostaddr, e == NULL);
+ clientrate = client_rate(now, hostaddr, e == NULL ? SM_CLFL_UPDATE : SM_CLFL_NONE);
if (e == NULL)
clientconn = count_open_connections(hostaddr);
@@ -132,7 +113,7 @@ connection_rate_check(hostaddr, e)
macdefine(&e->e_macro, A_TEMP, macid("{client_connections}"),
s);
}
- return true;
+ return;
}
/*
@@ -141,17 +122,6 @@ connection_rate_check(hostaddr, e)
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
@@ -159,151 +129,165 @@ static int CollTime = 60;
*/
static int ChtGran = -1;
+static CHash_T CHashAry[CPMHSIZE];
+static CTime_T srv_Times[CHTSIZE];
-#define CHTSIZE 6
+#ifndef MAX_CT_STEPS
+# define MAX_CT_STEPS 10
+#endif
-/* Number of connections for a certain "tick" */
-typedef struct CTime
-{
- unsigned long ct_Ticks;
- int ct_Count;
-}
-CTime_T;
+/*
+** RATE_INIT - initialize local data
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+**
+** Side effects:
+** initializes static global data
+*/
-typedef struct CHash
+static void
+rate_init()
{
-#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];
+ if (ChtGran > 0)
+ return;
+ ChtGran = ConnectionRateWindowSize / CHTSIZE;
+ if (ChtGran <= 0)
+ ChtGran = 10;
+ memset(CHashAry, 0, sizeof(CHashAry));
+ memset(srv_Times, 0, sizeof(srv_Times));
+ return;
}
-CHash_T;
-
-static CHash_T CHashAry[CPMHSIZE];
-static bool CHashAryOK = false;
/*
-** CLIENT_RATE - Evaluate connection rate per smtp client
+** GEN_HASH - calculate a hash value
**
** 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
-**
+** hash value
*/
-static int
-client_rate(now, saddr, update)
- time_t now;
- SOCKADDR *saddr;
- bool update;
+static unsigned int
+gen_hash(saddr)
+ SOCKADDR *saddr;
{
unsigned int hv;
int i;
- int cnt;
- bool coll;
- CHash_T *chBest = NULL;
- unsigned int ticks;
+ int addrlen;
+ char *p;
+#if HASH_ALG != 1
+ int c, d;
+#endif
- cnt = 0;
hv = 0xABC3D20F;
- if (ChtGran < 0)
- ChtGran = ConnectionRateWindowSize / CHTSIZE;
- if (ChtGran <= 0)
- ChtGran = 10;
-
- ticks = now / ChtGran;
-
- if (!CHashAryOK)
+ switch (saddr->sa.sa_family)
{
- 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;
+ 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;
+ case AF_INET6:
+ p = (char *)&saddr->sin6.sin6_addr;
+ addrlen = sizeof(struct in6_addr);
+ break;
#endif /* NETINET6 */
- default:
- /* should not happen */
- return -1;
- }
+ default:
+ /* should not happen */
+ return -1;
+ }
- /* compute hash value */
- for (i = 0; i < addrlen; ++i, ++p)
+ /* compute hash value */
+ for (i = 0; i < addrlen; ++i, ++p)
#if HASH_ALG == 1
- hv = (hv << 5) ^ (hv >> 23) ^ *p;
- hv = (hv ^ (hv >> 16));
+ 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;
- }
+ {
+ 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 = (hv << 4) + *p;
- d = hv & 0xf0000000;
- if (d != 0)
- {
- hv ^= (d >> 24);
- hv ^= d;
- }
+ hv ^= (d >> 24);
+ hv ^= d;
}
+ }
#else /* HASH_ALG == 1 */
- hv = ((hv << 1) ^ (*p & 0377)) % cctx->cc_size;
+# ERROR: unsupported HASH_ALG
+ hv = ((hv << 1) ^ (*p & 0377)) % cctx->cc_size; ???
#endif /* HASH_ALG == 1 */
- }
+
+ return hv;
+}
+
+/*
+** CONN_LIMIT - Evaluate connection limits
+**
+** Parameters:
+** e -- envelope (_FFR_OCC, for logging only)
+** now - current time in secs
+** saddr - client address
+** clflags - update data / check only / ...
+** hashary - hash array
+** ratelimit - rate limit (_FFR_OCC only)
+** conclimit - concurrency limit (_FFR_OCC only)
+**
+** Returns:
+#if _FFR_OCC
+** outgoing: limit exceeded?
+#endif
+** incoming:
+** connection rate (connections / ConnectionRateWindowSize)
+*/
+
+int
+conn_limits(e, now, saddr, clflags, hashary, ratelimit, conclimit)
+ ENVELOPE *e;
+ time_t now;
+ SOCKADDR *saddr;
+ int clflags;
+ CHash_T hashary[];
+ int ratelimit;
+ int conclimit;
+{
+ int i;
+ int cnt;
+ bool coll;
+ CHash_T *chBest = NULL;
+ CTime_T *ct = NULL;
+ unsigned int ticks;
+ unsigned int hv;
+#if _FFR_OCC
+ bool exceeded = false;
+ int *prv, *pcv;
+#endif
+#if RATECTL_DEBUG || _FFR_OCC
+ bool logit = false;
+#endif
+
+ cnt = 0;
+ hv = gen_hash(saddr);
+ ticks = now / ChtGran;
coll = true;
for (i = 0; i < MAX_CT_STEPS; ++i)
{
- CHash_T *ch = &CHashAry[(hv + i) & CPMHMASK];
+ CHash_T *ch = &hashary[(hv + i) & CPMHMASK];
#if NETINET
if (saddr->sa.sa_family == AF_INET &&
@@ -334,7 +318,7 @@ client_rate(now, saddr, update)
}
/* Let's update data... */
- if (update)
+ if ((clflags & (SM_CLFL_UPDATE|SM_CLFL_EXC)) != 0)
{
if (coll && (now - chBest->ch_LTime < CollTime))
{
@@ -362,7 +346,7 @@ client_rate(now, saddr, update)
**
** Alternative approach: just use the old data, which may
** cause false positives however.
- ** To activate this, change deactivate following memset call.
+ ** To activate this, deactivate the memset() call.
*/
if (coll)
@@ -381,43 +365,127 @@ client_rate(now, saddr, update)
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];
+ ct = &chBest->ch_Times[ticks % CHTSIZE];
- if (ct->ct_Ticks != ticks)
- {
- ct->ct_Ticks = ticks;
- ct->ct_Count = 0;
- }
- ++ct->ct_Count;
+ if (ct->ct_Ticks != ticks)
+ {
+ ct->ct_Ticks = ticks;
+ ct->ct_Count = 0;
}
+ if ((clflags & SM_CLFL_UPDATE) != 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];
+ CTime_T *cth;
- if (ct->ct_Ticks <= ticks && ct->ct_Ticks >= ticks - CHTSIZE)
- cnt += ct->ct_Count;
+ cth = &chBest->ch_Times[i];
+ if (cth->ct_Ticks <= ticks && cth->ct_Ticks >= ticks - CHTSIZE)
+ cnt += cth->ct_Count;
+ }
+#if _FFR_OCC
+ prv = pcv = NULL;
+ if (ct != NULL && ((clflags & SM_CLFL_EXC) != 0))
+ {
+ if (ratelimit > 0)
+ {
+ if (cnt < ratelimit)
+ prv = &(ct->ct_Count);
+ else
+ exceeded = true;
+ }
+ else if (ratelimit < 0 && ct->ct_Count > 0)
+ --ct->ct_Count;
}
+ if (chBest != NULL && ((clflags & SM_CLFL_EXC) != 0))
+ {
+ if (conclimit > 0)
+ {
+ if (chBest->ch_oc < conclimit)
+ pcv = &(chBest->ch_oc);
+ else
+ exceeded = true;
+ }
+ else if (conclimit < 0 && chBest->ch_oc > 0)
+ --chBest->ch_oc;
+ }
+#endif
+
+
#if RATECTL_DEBUG
- sm_syslog(LOG_WARNING, NOQID,
- "cln: cnt=(%d), CHTSIZE=(%d), ChtGran=(%d)",
- cnt, CHTSIZE, ChtGran);
-#endif /* RATECTL_DEBUG */
+ logit = true;
+#endif
+#if RATECTL_DEBUG || _FFR_OCC
+#if _FFR_OCC
+ if (!exceeded)
+ {
+ if (prv != NULL)
+ ++*prv, ++cnt;
+ if (pcv != NULL)
+ ++*pcv;
+ }
+ logit = exceeded || LogLevel > 11;
+#endif
+ if (logit)
+ sm_syslog(LOG_DEBUG, e != NULL ? e->e_id : NOQID,
+ "conn_limits: addr=%s, flags=0x%x, rate=%d/%d, conc=%d/%d, exc=%d",
+ saddr->sa.sa_family == AF_INET
+ ? inet_ntoa(saddr->sin.sin_addr) : "???",
+ clflags, cnt, ratelimit,
+# if _FFR_OCC
+ chBest != NULL ? chBest->ch_oc : -1
+# else
+ -2
+# endif
+ , conclimit
+# if _FFR_OCC
+ , exceeded
+# else
+ , 0
+# endif
+ );
+#endif
+#if _FFR_OCC
+ if ((clflags & SM_CLFL_EXC) != 0)
+ return exceeded;
+#endif
return cnt;
}
/*
+** CLIENT_RATE - Evaluate connection rate per SMTP client
+**
+** Parameters:
+** now - current time in secs
+** saddr - client address
+** clflags - update data / check only
+**
+** Returns:
+** connection rate (connections / ConnectionRateWindowSize)
+**
+** Side effects:
+** update static global data
+*/
+
+static int
+client_rate(now, saddr, clflags)
+ time_t now;
+ SOCKADDR *saddr;
+ int clflags;
+{
+ rate_init();
+ return conn_limits(NULL, now, saddr, clflags, CHashAry, 0, 0);
+}
+
+/*
** TOTAL_RATE - Evaluate global connection rate
**
** Parameters:
@@ -428,29 +496,18 @@ client_rate(now, saddr, update)
** 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;
+ 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;
+ rate_init();
ticks = now / ChtGran;
- if (!srv_Times_OK)
- {
- memset(srv_Times, 0, sizeof(srv_Times));
- srv_Times_OK = true;
- }
/* Let's update data */
if (update)
@@ -476,9 +533,68 @@ total_rate(now, update)
#if RATECTL_DEBUG
sm_syslog(LOG_WARNING, NOQID,
- "srv: cnt=(%d), CHTSIZE=(%d), ChtGran=(%d)",
- cnt, CHTSIZE, ChtGran);
-#endif /* RATECTL_DEBUG */
+ "total: cnt=%d, CHTSIZE=%d, ChtGran=%d",
+ cnt, CHTSIZE, ChtGran);
+#endif
return cnt;
}
+
+#if RATECTL_DEBUG || _FFR_OCC
+void
+dump_ch(fp)
+ SM_FILE_T *fp;
+{
+ int i, j, cnt;
+ unsigned int ticks;
+
+ ticks = time(NULL) / ChtGran;
+ sm_io_fprintf(fp, SM_TIME_DEFAULT, "dump_ch\n");
+ for (i = 0; i < CPMHSIZE; i++)
+ {
+ CHash_T *ch = &CHashAry[i];
+ bool valid;
+
+ valid = false;
+#if NETINET
+ valid = (ch->ch_Family == AF_INET);
+ if (valid)
+ sm_io_fprintf(fp, SM_TIME_DEFAULT, "ip=%s ",
+ inet_ntoa(ch->ch_Addr4));
+#endif /* NETINET */
+#if NETINET6
+ if (ch->ch_Family == AF_INET6)
+ {
+ char buf[64], *str;
+
+ valid = true;
+ str = anynet_ntop(&ch->ch_Addr6, buf, sizeof(buf));
+ if (str != NULL)
+ sm_io_fprintf(fp, SM_TIME_DEFAULT, "ip=%s ",
+ str);
+ }
+#endif /* NETINET6 */
+ if (!valid)
+ continue;
+
+ cnt = 0;
+ for (j = 0; j < CHTSIZE; ++j)
+ {
+ CTime_T *cth;
+
+ cth = &ch->ch_Times[j];
+ if (cth->ct_Ticks <= ticks && cth->ct_Ticks >= ticks - CHTSIZE)
+ cnt += cth->ct_Count;
+ }
+
+ sm_io_fprintf(fp, SM_TIME_DEFAULT, "time=%ld cnt=%d ",
+ (long) ch->ch_LTime, cnt);
+#if _FFR_OCC
+ sm_io_fprintf(fp, SM_TIME_DEFAULT, "oc=%d", ch->ch_oc);
+#endif
+ sm_io_fprintf(fp, SM_TIME_DEFAULT, "\n");
+ }
+ sm_io_flush(fp, SM_TIME_DEFAULT);
+}
+
+#endif /* RATECTL_DEBUG || _FFR_OCC */
diff --git a/contrib/sendmail/src/ratectrl.h b/contrib/sendmail/src/ratectrl.h
new file mode 100644
index 000000000000..f1946c905603
--- /dev/null
+++ b/contrib/sendmail/src/ratectrl.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2003 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ * 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.
+ */
+
+#ifndef RATECTRL_H
+#define RATECTRL_H 1
+
+#include <sendmail.h>
+
+/*
+** stuff included - given some warnings (inet_ntoa)
+** - surely not everything is needed
+*/
+
+#if NETINET || NETINET6
+# include <arpa/inet.h>
+#endif
+
+#include <sm/time.h>
+
+#ifndef HASH_ALG
+# define HASH_ALG 2
+#endif
+
+#ifndef RATECTL_DEBUG
+# define RATECTL_DEBUG 0
+#endif
+
+/* this should be a power of 2, otherwise CPMHMASK doesn't work well */
+#ifndef CPMHSIZE
+# define CPMHSIZE 1024
+#endif
+
+#define CPMHMASK (CPMHSIZE-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];
+#if _FFR_OCC
+ int ch_oc; /* open connections */
+#endif
+}
+CHash_T;
+
+#define SM_CLFL_NONE 0x00
+#define SM_CLFL_UPDATE 0x01
+#define SM_CLFL_EXC 0x02 /* check if limit is exceeded */
+
+extern void connection_rate_check __P((SOCKADDR *, ENVELOPE *));
+extern int conn_limits __P((ENVELOPE *, time_t, SOCKADDR *, int, CHash_T *, int, int));
+extern bool occ_exceeded __P((ENVELOPE *, MCI *, const char *, SOCKADDR *));
+extern bool occ_close __P((ENVELOPE *, MCI *, const char *, SOCKADDR *));
+extern void dump_ch __P((SM_FILE_T *));
+#endif /* ! RATECTRL_H */
diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c
index 10eac0bc6724..e6f62961f220 100644
--- a/contrib/sendmail/src/readcf.c
+++ b/contrib/sendmail/src/readcf.c
@@ -13,12 +13,18 @@
#include <sendmail.h>
#include <sm/sendmail.h>
+#if STARTTLS
+# include <tls.h>
+#endif
+#if DNSSEC_TEST
+# include <sm_resolve.h>
+#endif
SM_RCSID("@(#)$Id: readcf.c,v 8.692 2013-11-22 20:51:56 ca Exp $")
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
#define SECONDS
@@ -194,7 +200,7 @@ readcf(cfname, safe, e)
#if XLA
xla_zero();
-#endif /* XLA */
+#endif
while (bufsize = sizeof(buf),
(bp = fgetfolded(buf, &bufsize, cf)) != NULL)
@@ -351,7 +357,7 @@ readcf(cfname, safe, e)
int args, endtoken;
#if _FFR_EXTRA_MAP_CHECK
int nexttoken;
-#endif /* _FFR_EXTRA_MAP_CHECK */
+#endif
bool inmap;
rwp->r_rhs = copyplist(rwp->r_rhs, true, NULL);
@@ -424,7 +430,7 @@ readcf(cfname, safe, e)
nexttoken = ap[1][0] & 0377;
if (nexttoken == CANONHOST ||
nexttoken == CANONUSER ||
- nexttoken == endtoken))
+ nexttoken == endtoken)
{
syserr("missing map name for lookup");
break;
@@ -434,7 +440,7 @@ readcf(cfname, safe, e)
syserr("syntax error in map lookup");
break;
}
- if (ap[0][0] == HOSTBEGIN)
+ if ((unsigned char) ap[0][0] == HOSTBEGIN)
break;
nexttoken = ap[2][0] & 0377;
if (nexttoken == CANONHOST ||
@@ -553,10 +559,10 @@ readcf(cfname, safe, e)
register char *wd;
char delim;
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
wd = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
delim = *p;
*p = '\0';
@@ -570,15 +576,15 @@ readcf(cfname, safe, e)
mid = macid_parse(&bp[1], &ep);
if (mid == 0)
break;
- for (p = ep; isascii(*p) && isspace(*p); )
+ for (p = ep; SM_ISSPACE(*p); )
p++;
if (p[0] == '-' && p[1] == 'o')
{
optional = true;
while (*p != '\0' &&
- !(isascii(*p) && isspace(*p)))
+ !(SM_ISSPACE(*p)))
p++;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
}
else
@@ -635,7 +641,7 @@ readcf(cfname, safe, e)
case 'L': /* extended load average description */
xla_init(&bp[1]);
break;
-#endif /* XLA */
+#endif
#if defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO)
case 'L': /* lookup macro */
@@ -676,7 +682,7 @@ readcf(cfname, safe, e)
break;
case 'V': /* configuration syntax version */
- for (p = &bp[1]; isascii(*p) && isspace(*p); p++)
+ for (p = &bp[1]; SM_ISSPACE(*p); p++)
continue;
if (!isascii(*p) || !isdigit(*p))
{
@@ -849,7 +855,7 @@ translate_dollars(ibp, obp, bsp)
default:
/* delete leading white space */
- while (isascii(*p) && isspace(*p) &&
+ while (SM_ISSPACE(*p) &&
*p != '\n' && p > bp)
{
p--;
@@ -887,7 +893,7 @@ translate_dollars(ibp, obp, bsp)
}
/* strip trailing white space from the line */
- while (--p > bp && isascii(*p) && isspace(*p))
+ while (--p > bp && SM_ISSPACE(*p))
*p = '\0';
if (tTd(37, 53))
@@ -954,14 +960,14 @@ parse_class_words(class, line)
register char *q;
/* strip leading spaces */
- while (isascii(*line) && isspace(*line))
+ while (SM_ISSPACE(*line))
line++;
if (*line == '\0')
break;
/* find the end of the word */
q = line;
- while (*line != '\0' && !(isascii(*line) && isspace(*line)))
+ while (*line != '\0' && !(SM_ISSPACE(*line)))
line++;
if (*line != '\0')
*line++ = '\0';
@@ -1184,7 +1190,7 @@ fileclass(class, filename, fmt, ismap, safe, optional)
{
#if SCANF
char wordbuf[MAXLINE + 1];
-#endif /* SCANF */
+#endif
if (buf[0] == '#')
continue;
@@ -1226,7 +1232,7 @@ static char frst[MAXMAILERS + 1];
**
** Returns:
** none
-**
+**
** Note: space is not valid in cf defined mailers hence the function
** will always find a char. It's not nice, but this is for
** internal names only.
@@ -1381,7 +1387,7 @@ makemailer(line)
/* collect the mailer name */
for (p = line;
- *p != '\0' && *p != ',' && !(isascii(*p) && isspace(*p));
+ *p != '\0' && *p != ',' && !(SM_ISSPACE(*p));
p++)
continue;
if (*p != '\0')
@@ -1405,7 +1411,7 @@ makemailer(line)
auto char *delimptr;
while (*p != '\0' &&
- (*p == ',' || (isascii(*p) && isspace(*p))))
+ (*p == ',' || (SM_ISSPACE(*p))))
p++;
/* p now points to field code */
@@ -1417,7 +1423,7 @@ makemailer(line)
syserr("mailer %s: `=' expected", m->m_name);
return;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* p now points to the field body */
@@ -1434,7 +1440,7 @@ makemailer(line)
case 'F': /* flags */
for (; *p != '\0'; p++)
{
- if (!(isascii(*p) && isspace(*p)))
+ if (!(SM_ISSPACE(*p)))
{
if (*p == M_INTERNAL)
sm_syslog(LOG_WARNING, NOQID,
@@ -1573,11 +1579,11 @@ makemailer(line)
while (*p != '\0' && isascii(*p) &&
# if _FFR_DOTTED_USERNAMES
(isalnum(*p) || strchr(SM_PWN_CHARS, *p) != NULL))
-# else /* _FFR_DOTTED_USERNAMES */
+# else
(isalnum(*p) || strchr("-_", *p) != NULL))
-# endif /* _FFR_DOTTED_USERNAMES */
+# endif
p++;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
*p++ = '\0';
if (*p != '\0')
*p++ = '\0';
@@ -1605,12 +1611,12 @@ makemailer(line)
m->m_uid = strtol(p, &q, 0);
p = q;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p != '\0')
p++;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (*p == '\0')
break;
@@ -1732,7 +1738,7 @@ makemailer(line)
if (strcmp(m->m_argv[0], "TCP") != 0
#if NETUNIX
&& strcmp(m->m_argv[0], "FILE") != 0
-#endif /* NETUNIX */
+#endif
)
{
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
@@ -1740,9 +1746,9 @@ makemailer(line)
m->m_name, m->m_mailer,
#if NETUNIX
"TCP or FILE"
-#else /* NETUNIX */
+#else
"TCP"
-#endif /* NETUNIX */
+#endif
);
}
if (m->m_mtatype == NULL)
@@ -1972,9 +1978,9 @@ makeargv(p)
while (*p != '\0' && i < MAXPV)
{
q = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
*p++ = '\0';
argv[i++] = newstr(q);
}
@@ -2189,6 +2195,9 @@ static struct ssl_options
#ifdef SSL_OP_NO_TLSv1
{ "SSL_OP_NO_TLSv1", SSL_OP_NO_TLSv1 },
#endif
+#ifdef SSL_OP_NO_TLSv1_3
+ { "SSL_OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3 },
+#endif
#ifdef SSL_OP_NO_TLSv1_2
{ "SSL_OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2 },
#endif
@@ -2213,6 +2222,24 @@ static struct ssl_options
#ifdef SSL_OP_TLSEXT_PADDING
{ "SSL_OP_TLSEXT_PADDING", SSL_OP_TLSEXT_PADDING },
#endif
+#ifdef SSL_OP_NO_RENEGOTIATION
+ { "SSL_OP_NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION },
+#endif
+#ifdef SSL_OP_NO_ANTI_REPLAY
+ { "SSL_OP_NO_ANTI_REPLAY", SSL_OP_NO_ANTI_REPLAY },
+#endif
+#ifdef SSL_OP_ALLOW_NO_DHE_KEX
+ { "SSL_OP_ALLOW_NO_DHE_KEX", SSL_OP_ALLOW_NO_DHE_KEX },
+#endif
+#ifdef SSL_OP_NO_ENCRYPT_THEN_MAC
+ { "SSL_OP_NO_ENCRYPT_THEN_MAC", SSL_OP_NO_ENCRYPT_THEN_MAC },
+#endif
+#ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT
+ { "SSL_OP_ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT },
+#endif
+#ifdef SSL_OP_PRIORITIZE_CHACHA
+ { "SSL_OP_PRIORITIZE_CHACHA", SSL_OP_PRIORITIZE_CHACHA },
+#endif
{ NULL, 0 }
};
@@ -2231,7 +2258,8 @@ static struct ssl_options
#define SSLOPERR_NAN 1
#define SSLOPERR_NOTFOUND 2
-#define SM_ISSPACE(c) (isascii(c) && isspace(c))
+
+static int readssloptions __P((char *, char *, unsigned long *, int ));
static int
readssloptions(opt, val, pssloptions, delim)
@@ -2312,13 +2340,13 @@ readssloptions(opt, val, pssloptions, delim)
return ret;
}
-# if _FFR_TLS_SE_OPTS
/*
** GET_TLS_SE_OPTIONS -- get TLS session options (from ruleset)
**
** Parameters:
** e -- envelope
** ssl -- TLS session context
+** tlsi_ctx -- TLS info context
** srv -- server?
**
** Returns:
@@ -2326,9 +2354,10 @@ readssloptions(opt, val, pssloptions, delim)
*/
int
-get_tls_se_options(e, ssl, srv)
+get_tls_se_options(e, ssl, tlsi_ctx, srv)
ENVELOPE *e;
SSL *ssl;
+ tlsi_ctx_T *tlsi_ctx;
bool srv;
{
bool saveQuickAbort, saveSuprErrs, ok;
@@ -2374,7 +2403,7 @@ get_tls_se_options(e, ssl, srv)
if (LogLevel > 9)
sm_syslog(LOG_INFO, NOQID,
"tls_%s_features=empty, relay=%s [%s]",
- WHICH, NAME_C_S, ADDR_C_S);
+ WHICH, NAME_C_S, ADDR_C_S);
return ok ? 0 : 1;
}
@@ -2389,7 +2418,7 @@ get_tls_se_options(e, ssl, srv)
if (LogLevel > 9 && len > 1)
sm_syslog(LOG_INFO, NOQID,
"tls_%s_features=too_short, relay=%s [%s]",
- WHICH, NAME_C_S, ADDR_C_S);
+ WHICH, NAME_C_S, ADDR_C_S);
/* this is not treated as error! */
return 0;
@@ -2402,7 +2431,7 @@ get_tls_se_options(e, ssl, srv)
if (LogLevel > 7) \
sm_syslog(LOG_INFO, NOQID, \
"tls_%s_features=invalid_syntax, opt=%s, relay=%s [%s]", \
- WHICH, opt, NAME_C_S, ADDR_C_S); \
+ WHICH, opt, NAME_C_S, ADDR_C_S); \
return -1; \
} while (0)
@@ -2483,11 +2512,20 @@ get_tls_se_options(e, ssl, srv)
"STARTTLS=%s, error: SSL_set_cipher_list(%s) failed",
who, val);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
}
}
+ else if (sm_strcasecmp(opt, "flags") == 0)
+ {
+ char *p;
+
+ for (p = val; *p != '\0'; p++)
+ {
+ if (isascii(*p) && isalnum(*p))
+ setbitn(bitidx(*p), tlsi_ctx->tlsi_flags);
+ }
+ }
else if (sm_strcasecmp(opt, "keyfile") == 0)
keyfile = val;
else if (sm_strcasecmp(opt, "certfile") == 0)
@@ -2499,7 +2537,7 @@ get_tls_se_options(e, ssl, srv)
{
sm_syslog(LOG_INFO, NOQID,
"tls_%s_features=unknown_option, opt=%s, relay=%s [%s]",
- WHICH, opt, NAME_C_S, ADDR_C_S);
+ WHICH, opt, NAME_C_S, ADDR_C_S);
}
}
@@ -2519,7 +2557,7 @@ get_tls_se_options(e, ssl, srv)
{
sm_syslog(LOG_INFO, NOQID,
"tls_%s_features=only_one_of_CertFile/KeyFile_specified, relay=%s [%s]",
- WHICH, NAME_C_S, ADDR_C_S);
+ WHICH, NAME_C_S, ADDR_C_S);
}
}
@@ -2529,7 +2567,6 @@ get_tls_se_options(e, ssl, srv)
# undef ADDR_C_S
# undef WHICH
}
-# endif /* _FFR_TLS_SE_OPTS */
#endif /* STARTTLS */
/*
@@ -2573,7 +2610,17 @@ static struct resolverflags
{ "dnsrch", RES_DNSRCH },
# ifdef RES_USE_INET6
{ "use_inet6", RES_USE_INET6 },
-# endif /* RES_USE_INET6 */
+# endif
+# ifdef RES_USE_EDNS0
+ { "use_edns0", RES_USE_EDNS0 },
+# endif
+# ifdef RES_USE_DNSSEC
+ { "use_dnssec", RES_USE_DNSSEC },
+# endif
+# if RES_TRUSTAD
+ { "trustad", RES_TRUSTAD },
+# endif
+ { "true", 0 }, /* avoid error on old syntax */
{ "true", 0 }, /* avoid error on old syntax */
{ NULL, 0 }
};
@@ -2593,7 +2640,7 @@ static struct optioninfo
{
#if defined(SUN_EXTENSIONS) && defined(REMOTE_MODE)
{ "RemoteMode", '>', OI_NONE },
-#endif /* defined(SUN_EXTENSIONS) && defined(REMOTE_MODE) */
+#endif
{ "SevenBitInput", '7', OI_SAFE },
{ "EightBitMode", '8', OI_SAFE },
{ "AliasFile", 'A', OI_NONE },
@@ -2716,7 +2763,7 @@ static struct optioninfo
#if _FFR_DONTLOCKFILESFORREAD_OPTION
# define O_DONTLOCK 0xa4
{ "DontLockFilesForRead", O_DONTLOCK, OI_NONE },
-#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
+#endif
#define O_MAXALIASRCSN 0xa5
{ "MaxAliasRecursion", O_MAXALIASRCSN, OI_NONE },
#define O_CNCTONLYTO 0xa6
@@ -2732,15 +2779,15 @@ static struct optioninfo
#if _FFR_MAX_FORWARD_ENTRIES
# define O_MAXFORWARD 0xab
{ "MaxForwardEntries", O_MAXFORWARD, OI_NONE },
-#endif /* _FFR_MAX_FORWARD_ENTRIES */
+#endif
#define O_PROCTITLEPREFIX 0xac
{ "ProcessTitlePrefix", O_PROCTITLEPREFIX, OI_NONE },
#define O_SASLINFO 0xad
#if _FFR_ALLOW_SASLINFO
{ "DefaultAuthInfo", O_SASLINFO, OI_SAFE },
-#else /* _FFR_ALLOW_SASLINFO */
+#else
{ "DefaultAuthInfo", O_SASLINFO, OI_NONE },
-#endif /* _FFR_ALLOW_SASLINFO */
+#endif
#define O_SASLMECH 0xae
{ "AuthMechanisms", O_SASLMECH, OI_NONE },
#define O_CLIENTPORT 0xaf
@@ -2821,10 +2868,8 @@ static struct optioninfo
{ "FallbackSmartHost", O_FALLBACKSMARTHOST, OI_NONE },
#define O_SASLREALM 0xd6
{ "AuthRealm", O_SASLREALM, OI_NONE },
-#if _FFR_CRLPATH
-# define O_CRLPATH 0xd7
+#define O_CRLPATH 0xd7
{ "CRLPath", O_CRLPATH, OI_NONE },
-#endif /* _FFR_CRLPATH */
#define O_HELONAME 0xd8
{ "HeloName", O_HELONAME, OI_NONE },
#if _FFR_MEMSTAT
@@ -2840,22 +2885,22 @@ static struct optioninfo
#if _FFR_MSG_ACCEPT
# define O_MSG_ACCEPT 0xdd
{ "MessageAccept", O_MSG_ACCEPT, OI_NONE },
-#endif /* _FFR_MSG_ACCEPT */
+#endif
#if _FFR_QUEUE_RUN_PARANOIA
# define O_CHK_Q_RUNNERS 0xde
{ "CheckQueueRunners", O_CHK_Q_RUNNERS, OI_NONE },
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#endif
#if _FFR_EIGHT_BIT_ADDR_OK
# if !ALLOW_255
# ERROR FFR_EIGHT_BIT_ADDR_OK requires _ALLOW_255
-# endif /* !ALLOW_255 */
+# endif
# define O_EIGHT_BIT_ADDR_OK 0xdf
{ "EightBitAddrOK", O_EIGHT_BIT_ADDR_OK, OI_NONE },
#endif /* _FFR_EIGHT_BIT_ADDR_OK */
#if _FFR_ADDR_TYPE_MODES
# define O_ADDR_TYPE_MODES 0xe0
{ "AddrTypeModes", O_ADDR_TYPE_MODES, OI_NONE },
-#endif /* _FFR_ADDR_TYPE_MODES */
+#endif
#if _FFR_BADRCPT_SHUTDOWN
# define O_RCPTSHUTD 0xe1
{ "BadRcptShutdown", O_RCPTSHUTD, OI_SAFE },
@@ -2871,7 +2916,7 @@ static struct optioninfo
#if _FFR_RCPTTHROTDELAY
# define O_RCPTTHROTDELAY 0xe6
{ "BadRcptThrottleDelay", O_RCPTTHROTDELAY, OI_SAFE },
-#endif /* _FFR_RCPTTHROTDELAY */
+#endif
#if 0 && _FFR_QOS && defined(SOL_IP) && defined(IP_TOS)
# define O_INETQOS 0xe7 /* reserved for FFR_QOS */
{ "InetQoS", O_INETQOS, OI_NONE },
@@ -2879,21 +2924,60 @@ static struct optioninfo
#if STARTTLS && _FFR_FIPSMODE
# define O_FIPSMODE 0xe8
{ "FIPSMode", O_FIPSMODE, OI_NONE },
-#endif /* STARTTLS && _FFR_FIPSMODE */
+#endif
#if _FFR_REJECT_NUL_BYTE
# define O_REJECTNUL 0xe9
{ "RejectNUL", O_REJECTNUL, OI_SAFE },
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
#if _FFR_BOUNCE_QUEUE
# define O_BOUNCEQUEUE 0xea
{ "BounceQueue", O_BOUNCEQUEUE, OI_NONE },
-#endif /* _FFR_BOUNCE_QUEUE */
+#endif
#if _FFR_ADD_BCC
# define O_ADDBCC 0xeb
{ "AddBcc", O_ADDBCC, OI_NONE },
#endif
#define O_USECOMPRESSEDIPV6ADDRESSES 0xec
{ "UseCompressedIPv6Addresses", O_USECOMPRESSEDIPV6ADDRESSES, OI_NONE },
+#if STARTTLS
+# define O_SSLENGINE 0xed
+ { "SSLEngine", O_SSLENGINE, OI_NONE },
+# define O_SSLENGINEPATH 0xee
+ { "SSLEnginePath", O_SSLENGINEPATH, OI_NONE },
+# define O_TLSFB2CLEAR 0xef
+ { "TLSFallbacktoClear", O_TLSFB2CLEAR, OI_NONE },
+#endif
+#if DNSSEC_TEST
+# define O_NSPORTIP 0xf0
+ { "NameServer", O_NSPORTIP, OI_NONE },
+#endif
+#if DANE
+# define O_DANE 0xf1
+ { "DANE", O_DANE, OI_NONE },
+#endif
+#if DNSSEC_TEST
+# define O_NSSRCHLIST 0xf2
+ { "NameSearchList", O_NSSRCHLIST, OI_NONE },
+#endif
+#if _FFR_BLANKENV_MACV
+# define O_HACKS 0xf4
+ { "Hacks", O_HACKS, OI_NONE },
+#endif
+#if _FFR_KEEPBCC
+# define O_KEEPBCC 0xf3
+ { "KeepBcc", O_KEEPBCC, OI_NONE },
+#endif
+
+#if _FFR_CLIENTCA
+#define O_CLTCACERTFILE 0xf5
+ { "ClientCACertFile", O_CLTCACERTFILE, OI_NONE },
+#define O_CLTCACERTPATH 0xf6
+ { "ClientCACertPath", O_CLTCACERTPATH, OI_NONE },
+#endif
+#if _FFR_TLS_ALTNAMES
+# define O_CHECKALTNAMES 0xf7
+ { "SetCertAltnames", O_CHECKALTNAMES, OI_NONE },
+#endif
{ NULL, '\0', OI_NONE }
};
@@ -2926,18 +3010,18 @@ setoption(opt, val, safe, sticky, e)
register char *p;
register struct optioninfo *o;
char *subopt;
- int mid;
+ int i;
bool can_setuid = RunAsUid == 0;
auto char *ep;
char buf[50];
extern bool Warn_Q_option;
#if _FFR_ALLOW_SASLINFO
extern unsigned int SubmitMode;
-#endif /* _FFR_ALLOW_SASLINFO */
+#endif
#if STARTTLS || SM_CONF_SHM
char *newval;
char exbuf[MAXLINE];
-#endif /* STARTTLS || SM_CONF_SHM */
+#endif
#if STARTTLS
unsigned long *pssloptions = NULL;
#endif
@@ -3181,7 +3265,7 @@ setoption(opt, val, safe, sticky, e)
#if _FFR_DM_ONE
/* deliver first TA in background, then queue */
case SM_DM_ONE:
-#endif /* _FFR_DM_ONE */
+#endif
set_delivery_mode(*val, e);
break;
@@ -3280,7 +3364,7 @@ setoption(opt, val, safe, sticky, e)
p--;
p++;
q = p;
- while (*p != '\0' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && !(SM_ISSPACE(*p)))
p++;
if (*p != '\0')
*p++ = '\0';
@@ -3348,13 +3432,13 @@ setoption(opt, val, safe, sticky, e)
case 'M': /* define macro */
sticky = false;
- mid = macid_parse(val, &ep);
- if (mid == 0)
+ i = macid_parse(val, &ep);
+ if (i == 0)
break;
p = newstr(ep);
if (!safe)
cleanstrcpy(p, p, strlen(p) + 1);
- macdefine(&CurEnv->e_macro, A_TEMP, mid, p);
+ macdefine(&CurEnv->e_macro, A_TEMP, i, p);
break;
case 'm': /* send to me too */
@@ -3490,9 +3574,9 @@ setoption(opt, val, safe, sticky, e)
{
# if _FFR_DOTTED_USERNAMES
if (*p == '/' || *p == ':')
-# else /* _FFR_DOTTED_USERNAMES */
+# else
if (*p == '.' || *p == '/' || *p == ':')
-# endif /* _FFR_DOTTED_USERNAMES */
+# endif
{
*p++ = '\0';
break;
@@ -3583,7 +3667,7 @@ setoption(opt, val, safe, sticky, e)
#if _FFR_QUEUE_GROUP_SORTORDER
/* coordinate this with makequeue() */
-#endif /* _FFR_QUEUE_GROUP_SORTORDER */
+#endif
case O_QUEUESORTORD: /* queue sorting order */
switch (*val)
{
@@ -3718,7 +3802,7 @@ setoption(opt, val, safe, sticky, e)
#if !HASNICE
(void) sm_io_fprintf(smioout, SM_TIME_DEFAULT,
"Warning: NiceQueueRun set on system that doesn't support nice()\n");
-#endif /* !HASNICE */
+#endif
/* XXX do we want to check the range? > 0 ? */
NiceQueueRun = atoi(val);
@@ -3748,7 +3832,7 @@ setoption(opt, val, safe, sticky, e)
case O_MAXFORWARD: /* max # of forward entries */
MaxForwardEntries = atoi(val);
break;
-#endif /* _FFR_MAX_FORWARD_ENTRIES */
+#endif
case O_KEEPCNAMES: /* don't expand CNAME records */
DontExpandCnames = atobool(val);
@@ -3826,9 +3910,9 @@ setoption(opt, val, safe, sticky, e)
{
# if _FFR_DOTTED_USERNAMES
if (*p == '/' || *p == ':')
-# else /* _FFR_DOTTED_USERNAMES */
+# else
if (*p == '.' || *p == '/' || *p == ':')
-# endif /* _FFR_DOTTED_USERNAMES */
+# endif
{
*p++ = '\0';
break;
@@ -3973,7 +4057,7 @@ setoption(opt, val, safe, sticky, e)
case O_RCPTTHROTDELAY:
BadRcptThrottleDelay = atoi(val);
break;
-#endif /* _FFR_RCPTTHROTDELAY */
+#endif
case O_DEADLETTER:
CANONIFY(val);
@@ -3984,7 +4068,7 @@ setoption(opt, val, safe, sticky, e)
case O_DONTLOCK:
DontLockReadFiles = atobool(val);
break;
-#endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */
+#endif
case O_MAXALIASRCSN:
MaxAliasRecursion = atoi(val);
@@ -3993,11 +4077,30 @@ setoption(opt, val, safe, sticky, e)
case O_CNCTONLYTO:
/* XXX should probably use gethostbyname */
#if NETINET || NETINET6
+ i = 0;
+ if ((subopt = strchr(val, '@')) != NULL)
+ {
+ *subopt = '\0';
+ i = (int) strtoul(val, NULL, 0);
+
+ /* stricter checks? probably not useful. */
+ if (i > USHRT_MAX)
+ {
+ syserr("readcf: option ConnectOnlyTo: invalid port %s",
+ val);
+ break;
+ }
+ val = subopt + 1;
+ }
ConnectOnlyTo.sa.sa_family = AF_UNSPEC;
# if NETINET6
if (anynet_pton(AF_INET6, val,
&ConnectOnlyTo.sin6.sin6_addr) == 1)
+ {
ConnectOnlyTo.sa.sa_family = AF_INET6;
+ if (i != 0)
+ ConnectOnlyTo.sin6.sin6_port = htons(i);
+ }
else
# endif /* NETINET6 */
# if NETINET
@@ -4005,6 +4108,8 @@ setoption(opt, val, safe, sticky, e)
ConnectOnlyTo.sin.sin_addr.s_addr = inet_addr(val);
if (ConnectOnlyTo.sin.sin_addr.s_addr != INADDR_NONE)
ConnectOnlyTo.sa.sa_family = AF_INET;
+ if (i != 0)
+ ConnectOnlyTo.sin.sin_port = htons(i);
}
# endif /* NETINET */
@@ -4217,6 +4322,9 @@ setoption(opt, val, safe, sticky, e)
#endif /* SASL */
#if STARTTLS
+ case O_TLSFB2CLEAR:
+ TLSFallbacktoClear = atobool(val);
+ break;
case O_SRVCERTFILE:
SET_STRING_EXP(SrvCertFile);
case O_SRVKEYFILE:
@@ -4229,12 +4337,34 @@ setoption(opt, val, safe, sticky, e)
SET_STRING_EXP(CACertFile);
case O_CACERTPATH:
SET_STRING_EXP(CACertPath);
+#if _FFR_CLIENTCA
+ case O_CLTCACERTFILE:
+ SET_STRING_EXP(CltCACertFile);
+ case O_CLTCACERTPATH:
+ SET_STRING_EXP(CltCACertPath);
+#endif
case O_DHPARAMS:
SET_STRING_EXP(DHParams);
case O_CIPHERLIST:
SET_STRING_EXP(CipherList);
case O_DIG_ALG:
SET_STRING_EXP(CertFingerprintAlgorithm);
+ case O_SSLENGINEPATH:
+ SET_STRING_EXP(SSLEnginePath);
+ case O_SSLENGINE:
+ newval = sm_pstrdup_x(val);
+ if (SSLEngine != NULL)
+ sm_free(SSLEngine);
+ SSLEngine = newval;
+
+ /*
+ ** Which engines need to be initialized before fork()?
+ ** XXX hack, should be an option?
+ */
+
+ if (strcmp(SSLEngine, "chil") == 0)
+ SSLEngineprefork = true;
+ break;
case O_SRV_SSL_OPTIONS:
pssloptions = &Srv_SSL_Options;
case O_CLT_SSL_OPTIONS:
@@ -4248,26 +4378,12 @@ setoption(opt, val, safe, sticky, e)
break;
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?
@@ -4329,14 +4445,17 @@ setoption(opt, val, safe, sticky, e)
case O_CLTKEYFILE:
case O_CACERTFILE:
case O_CACERTPATH:
+#if _FFR_CLIENTCA
+ case O_CLTCACERTFILE:
+ case O_CLTCACERTPATH:
+#endif
case O_DHPARAMS:
case O_SRV_SSL_OPTIONS:
case O_CLT_SSL_OPTIONS:
case O_CIPHERLIST:
+ case O_DIG_ALG:
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",
@@ -4348,7 +4467,7 @@ setoption(opt, val, safe, sticky, e)
case O_FIPSMODE:
FipsMode = atobool(val);
break;
-#endif /* STARTTLS && _FFR_FIPSMODE */
+#endif
case O_CLIENTPORT:
setclientoptions(val);
@@ -4435,9 +4554,9 @@ setoption(opt, val, safe, sticky, e)
case O_REQUIRES_DIR_FSYNC:
#if REQUIRES_DIR_FSYNC
RequiresDirfsync = atobool(val);
-#else /* REQUIRES_DIR_FSYNC */
+#else
/* silently ignored... required for cf file option */
-#endif /* REQUIRES_DIR_FSYNC */
+#endif
break;
case O_CONNECTION_RATE_WINDOW_SIZE:
@@ -4473,25 +4592,25 @@ setoption(opt, val, safe, sticky, e)
case O_MSG_ACCEPT:
MessageAccept = newstr(val);
break;
-#endif /* _FFR_MSG_ACCEPT */
+#endif
#if _FFR_QUEUE_RUN_PARANOIA
case O_CHK_Q_RUNNERS:
CheckQueueRunners = atoi(val);
break;
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#endif
#if _FFR_EIGHT_BIT_ADDR_OK
case O_EIGHT_BIT_ADDR_OK:
EightBitAddrOK = atobool(val);
break;
-#endif /* _FFR_EIGHT_BIT_ADDR_OK */
+#endif
#if _FFR_ADDR_TYPE_MODES
case O_ADDR_TYPE_MODES:
AddrTypeModes = atobool(val);
break;
-#endif /* _FFR_ADDR_TYPE_MODES */
+#endif
#if _FFR_BADRCPT_SHUTDOWN
case O_RCPTSHUTD:
@@ -4507,13 +4626,13 @@ setoption(opt, val, safe, sticky, e)
case O_REJECTNUL:
RejectNUL = atobool(val);
break;
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
#if _FFR_BOUNCE_QUEUE
case O_BOUNCEQUEUE:
bouncequeue = newstr(val);
break;
-#endif /* _FFR_BOUNCE_QUEUE */
+#endif
#if _FFR_ADD_BCC
case O_ADDBCC:
@@ -4524,6 +4643,42 @@ setoption(opt, val, safe, sticky, e)
UseCompressedIPv6Addresses = atobool(val);
break;
+#if DNSSEC_TEST
+ case O_NSPORTIP:
+ nsportip(val);
+ break;
+ case O_NSSRCHLIST:
+ NameSearchList = sm_strdup(val);
+ break;
+#endif
+
+#if DANE
+ case O_DANE:
+ if (sm_strcasecmp(val, "always") == 0)
+ Dane = DANE_ALWAYS;
+ else
+ Dane = atobool(val) ? DANE_SECURE : DANE_NEVER;
+ break;
+#endif
+
+#if _FFR_BLANKENV_MACV
+ case O_HACKS:
+ Hacks = (int) strtol(val, NULL, 0);
+ break;
+#endif
+
+#if _FFR_KEEPBCC
+ case O_KEEPBCC:
+ KeepBcc = atobool(val);
+ break;
+#endif
+
+# if _FFR_TLS_ALTNAMES
+ case O_CHECKALTNAMES:
+ SetCertAltnames = atobool(val);
+ break;
+# endif
+
default:
if (tTd(37, 1))
{
@@ -4614,7 +4769,7 @@ makemapentry(line)
register STAB *s;
STAB *class;
- for (p = line; isascii(*p) && isspace(*p); p++)
+ for (p = line; SM_ISSPACE(*p); p++)
continue;
if (!(isascii(*p) && isalnum(*p)))
{
@@ -4627,7 +4782,7 @@ makemapentry(line)
continue;
if (*p != '\0')
*p++ = '\0';
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (!(isascii(*p) && isalnum(*p)))
{
@@ -4639,7 +4794,7 @@ makemapentry(line)
continue;
if (*p != '\0')
*p++ = '\0';
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* look up the class */
@@ -4693,7 +4848,7 @@ strtorwset(p, endp, stabmode)
int ruleset;
static int nextruleset = MAXRWSETS;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
if (!isascii(*p))
{
@@ -4725,7 +4880,7 @@ strtorwset(p, endp, stabmode)
syserr("invalid ruleset name: \"%.20s\"", q);
return -1;
}
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
*p++ = '\0';
delim = *p;
if (delim != '\0')
@@ -5114,13 +5269,13 @@ settimeout(name, val, sticky)
case TO_AUTH:
TimeOuts.to_auth = toval;
break;
-#endif /* SASL */
+#endif
#if STARTTLS
case TO_STARTTLS:
TimeOuts.to_starttls = toval;
break;
-#endif /* STARTTLS */
+#endif
default:
syserr("settimeout: invalid timeout %s", name);
@@ -5176,18 +5331,18 @@ inittimeouts(val, sticky)
TimeOuts.to_miscshort = (time_t) 2 MINUTES;
#if IDENTPROTO
TimeOuts.to_ident = (time_t) 5 SECONDS;
-#else /* IDENTPROTO */
+#else
TimeOuts.to_ident = (time_t) 0 SECONDS;
-#endif /* IDENTPROTO */
+#endif
TimeOuts.to_fileopen = (time_t) 60 SECONDS;
TimeOuts.to_control = (time_t) 2 MINUTES;
TimeOuts.to_lhlo = (time_t) 2 MINUTES;
#if SASL
TimeOuts.to_auth = (time_t) 10 MINUTES;
-#endif /* SASL */
+#endif
#if STARTTLS
TimeOuts.to_starttls = (time_t) 1 HOUR;
-#endif /* STARTTLS */
+#endif
if (tTd(37, 5))
{
sm_dprintf("Timeouts:\n");
@@ -5225,7 +5380,7 @@ inittimeouts(val, sticky)
for (;; val = p)
{
- while (isascii(*val) && isspace(*val))
+ while (SM_ISSPACE(*val))
val++;
if (*val == '\0')
break;
diff --git a/contrib/sendmail/src/recipient.c b/contrib/sendmail/src/recipient.c
index 3fad95717d6b..eb325a6de385 100644
--- a/contrib/sendmail/src/recipient.c
+++ b/contrib/sendmail/src/recipient.c
@@ -44,9 +44,9 @@ sorthost(xx, yy)
#if _FFR_HOST_SORT_REVERSE
/* XXX maybe compare hostnames from the end? */
return sm_strrevcasecmp(xx->q_host, yy->q_host);
-#else /* _FFR_HOST_SORT_REVERSE */
+#else
return sm_strcasecmp(xx->q_host, yy->q_host);
-#endif /* _FFR_HOST_SORT_REVERSE */
+#endif
}
/*
@@ -82,9 +82,9 @@ sortexpensive(xx, yy)
#if _FFR_HOST_SORT_REVERSE
/* XXX maybe compare hostnames from the end? */
return sm_strrevcasecmp(xx->q_host, yy->q_host);
-#else /* _FFR_HOST_SORT_REVERSE */
+#else
return sm_strcasecmp(xx->q_host, yy->q_host);
-#endif /* _FFR_HOST_SORT_REVERSE */
+#endif
}
/*
@@ -112,9 +112,9 @@ sortbysignature(xx, yy)
/* Let's avoid redoing the signature over and over again */
if (xx->q_signature == NULL)
- xx->q_signature = hostsignature(xx->q_mailer, xx->q_host);
+ xx->q_signature = hostsignature(xx->q_mailer, xx->q_host, xx->q_flags & QSECURE);
if (yy->q_signature == NULL)
- yy->q_signature = hostsignature(yy->q_mailer, yy->q_host);
+ yy->q_signature = hostsignature(yy->q_mailer, yy->q_host, yy->q_flags & QSECURE);
ret = strcmp(xx->q_signature, yy->q_signature);
/*
@@ -222,7 +222,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e)
SM_ASSERT(p < endp);
/* parse the address */
- while ((isascii(*p) && isspace(*p)) || *p == ',')
+ while ((SM_ISSPACE(*p)) || *p == ',')
p++;
SM_ASSERT(p < endp);
a = parseaddr(p, NULLADDR, RF_COPYALL, delimiter,
@@ -392,7 +392,7 @@ removefromlist(list, sendq, e)
char *delimptr;
/* parse the address */
- while ((isascii(*p) && isspace(*p)) || *p == ',')
+ while ((SM_ISSPACE(*p)) || *p == ',')
p++;
if (parseaddr(p, &a, RF_COPYALL|RF_RM_ADDR,
delimiter, &delimptr, e, true) == NULL)
@@ -508,6 +508,11 @@ recipient(new, sendq, aliaslevel, e)
p = e->e_from.q_mailer->m_addrtype;
if (p == NULL)
p = "rfc822";
+#if _FFR_EAI
+ if (sm_strcasecmp(p, "rfc822") == 0 &&
+ !addr_is_ascii(q->q_user))
+ p = "utf-8";
+#endif
if (sm_strcasecmp(p, "rfc822") != 0)
{
(void) sm_snprintf(frbuf, sizeof(frbuf), "%s; %.800s",
@@ -949,7 +954,7 @@ recipient(new, sendq, aliaslevel, e)
if (tTd(29, 5))
{
sm_dprintf("recipient: testing local? cl=%d, rr5=%p\n\t",
- ConfigLevel, RewriteRules[5]);
+ ConfigLevel, (void *)RewriteRules[5]);
printaddr(sm_debug_file(), new, false);
}
if (ConfigLevel >= 2 && RewriteRules[5] != NULL &&
@@ -1164,7 +1169,7 @@ finduser(name, fuzzyp, user)
{
#if MATCHGECOS
register struct passwd *pw;
-#endif /* MATCHGECOS */
+#endif
register char *p;
bool tryagain;
int status;
@@ -1258,7 +1263,7 @@ finduser(name, fuzzyp, user)
sm_dprintf("no fuzzy match found\n");
# if DEC_OSF_BROKEN_GETPWENT /* DEC OSF/1 3.2 or earlier */
endpwent();
-# endif /* DEC_OSF_BROKEN_GETPWENT */
+# endif
if (pw == NULL)
return EX_NOUSER;
sm_mbdb_frompw(user, pw);
@@ -1838,7 +1843,7 @@ resetuid:
{
if (p[1] == '@' && p[2] == '#' &&
isascii(p[-1]) && isspace(p[-1]) &&
- (p[3] == '\0' || (isascii(p[3]) && isspace(p[3]))))
+ (p[3] == '\0' || (SM_ISSPACE(p[3]))))
{
--p;
while (p > buf && isascii(p[-1]) &&
diff --git a/contrib/sendmail/src/sasl.c b/contrib/sendmail/src/sasl.c
index bd2d908a11ad..71575f8dd1af 100644
--- a/contrib/sendmail/src/sasl.c
+++ b/contrib/sendmail/src/sasl.c
@@ -26,9 +26,9 @@ SM_RCSID("@(#)$Id: sasl.c,v 8.24 2013-11-22 20:51:56 ca Exp $")
# if defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a
# define SM_SASL_SIZE_T size_t
-# else /* defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a */
+# else
# define SM_SASL_SIZE_T unsigned long
-# endif /* defined(SASL_VERSION_FULL) && SASL_VERSION_FULL >= 0x02011a */
+# endif
void *sm_sasl_malloc __P((SM_SASL_SIZE_T));
static void *sm_sasl_calloc __P((SM_SASL_SIZE_T, SM_SASL_SIZE_T));
@@ -249,7 +249,7 @@ iptostring(addr, addrlen, out, outlen)
char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
# if NETINET6
int niflags;
-# endif /* NETINET6 */
+# endif
if (addr == NULL || out == NULL)
{
@@ -262,7 +262,7 @@ iptostring(addr, addrlen, out, outlen)
# ifdef NI_WITHSCOPEID
if (addr->sa.sa_family == AF_INET6)
niflags |= NI_WITHSCOPEID;
-# endif /* NI_WITHSCOPEID */
+# endif
if (getnameinfo((struct sockaddr *) addr, addrlen,
hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags) != 0)
return false;
diff --git a/contrib/sendmail/src/savemail.c b/contrib/sendmail/src/savemail.c
index 6de8f2f1957e..945bcd702e51 100644
--- a/contrib/sendmail/src/savemail.c
+++ b/contrib/sendmail/src/savemail.c
@@ -180,9 +180,9 @@ savemail(e, sendbody)
#if USE_TTYPATH
p = ttypath();
-#else /* USE_TTYPATH */
+#else
p = NULL;
-#endif /* USE_TTYPATH */
+#endif
if (p == NULL || sm_io_reopen(SmFtStdio,
SM_TIME_DEFAULT,
@@ -524,7 +524,7 @@ returntosender(msg, returnq, flags, e)
if (tTd(6, 1))
{
sm_dprintf("\n*** Return To Sender: msg=\"%s\", depth=%d, e=%p, returnq=",
- msg, returndepth, e);
+ msg, returndepth, (void *)e);
printaddr(sm_debug_file(), returnq, true);
if (tTd(6, 20))
{
@@ -584,7 +584,7 @@ returntosender(msg, returnq, flags, e)
#if _FFR_BOUNCE_QUEUE
if (BounceQueue != NOQGRP)
ee->e_qgrp = ee->e_dfqgrp = BounceQueue;
-#endif /* _FFR_BOUNCE_QUEUE */
+#endif
if (!setnewqueue(ee))
{
syserr("554 5.3.0 returntosender: cannot select queue for %s",
@@ -598,7 +598,7 @@ returntosender(msg, returnq, flags, e)
#if NAMED_BIND
_res.retry = TimeOuts.res_retry[RES_TO_FIRST];
_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
-#endif /* NAMED_BIND */
+#endif
for (q = returnq; q != NULL; q = q->q_next)
{
if (QS_IS_BADADDR(q->q_state))
@@ -637,9 +637,9 @@ returntosender(msg, returnq, flags, e)
(void) sm_snprintf(buf, sizeof(buf),
#if DSN
"multipart/report; report-type=delivery-status;\n\tboundary=\"%s\"",
-#else /* DSN */
+#else
"multipart/mixed; boundary=\"%s\"",
-#endif /* DSN */
+#endif
ee->e_msgboundary);
addheader("Content-Type", buf, 0, ee, true);
@@ -744,6 +744,44 @@ returntosender(msg, returnq, flags, e)
return ret;
}
+
+/*
+** DSNTYPENAME -- Returns the DSN name of the addrtype for this address
+**
+** Sendmail's addrtypes are largely in different universes, and
+** 'fred' may be a valid address in different addrtype
+** universes.
+**
+** EAI extends the rfc822 universe rather than introduce a new
+** universe. Because of that, sendmail uses the rfc822 addrtype,
+** but names it utf-8 when the EAI DSN extension requires that.
+**
+** Parameters:
+** addrtype -- address type
+** addr -- the address
+**
+** Returns:
+** type for DSN
+**
+*/
+
+static const char *dsntypename __P((const char *, const char *));
+
+static const char *
+dsntypename(addrtype, addr)
+ const char *addrtype;
+ const char *addr;
+{
+ if (sm_strcasecmp(addrtype, "rfc822") != 0)
+ return addrtype;
+#if _FFR_EAI
+ if (!addr_is_ascii(addr))
+ return "utf-8";
+#endif
+ return "rfc822";
+}
+
+
/*
** ERRBODY -- output the body of an error message.
**
@@ -1082,7 +1120,13 @@ errbody(mci, e, separator)
(void) sm_strlcpyn(buf, sizeof(buf), 2, "--", e->e_msgboundary);
if (!putline("", mci) ||
!putline(buf, mci) ||
+#if _FFR_EAI
+ !putline(e->e_parent->e_smtputf8
+ ? "Content-Type: message/global-delivery-status"
+ : "Content-Type: message/delivery-status", mci) ||
+#else
!putline("Content-Type: message/delivery-status", mci) ||
+#endif
!putline("", mci))
goto writeerr;
@@ -1223,7 +1267,8 @@ errbody(mci, e, separator)
(void) sm_snprintf(actual,
sizeof(actual),
"%s; %.700s@%.100s",
- p, q->q_user,
+ dsntypename(p, q->q_user),
+ q->q_user,
MyHostName);
}
else
@@ -1231,7 +1276,8 @@ errbody(mci, e, separator)
(void) sm_snprintf(actual,
sizeof(actual),
"%s; %.800s",
- p, q->q_user);
+ dsntypename(p, q->q_user),
+ q->q_user);
}
}
@@ -1248,6 +1294,23 @@ errbody(mci, e, separator)
actual);
}
+#if _FFR_EAI
+ if (sm_strncasecmp("rfc822;", q->q_finalrcpt, 7) == 0 &&
+ !addr_is_ascii(q->q_user))
+ {
+ char *a;
+ char utf8rcpt[1024];
+
+ a = strchr(q->q_finalrcpt, ';');
+ while(*a == ';' || *a == ' ')
+ a++;
+ sm_snprintf(utf8rcpt, sizeof(utf8rcpt),
+ "utf-8; %.800s", a);
+ q->q_finalrcpt = sm_rpool_strdup_x(e->e_rpool,
+ utf8rcpt);
+ }
+#endif
+
if (q->q_finalrcpt != NULL)
{
(void) sm_snprintf(buf, sizeof(buf),
@@ -1373,9 +1436,21 @@ errbody(mci, e, separator)
if (!putline(buf, mci))
goto writeerr;
+#if _FFR_EAI
+ if (e->e_parent->e_smtputf8)
+ (void) sm_strlcpyn(buf, sizeof(buf), 2,
+ "Content-Type: message/global",
+ sendbody ? "" : "-headers");
+ else
+ (void) sm_strlcpyn(buf, sizeof(buf), 2,
+ "Content-Type: ",
+ sendbody ? "message/rfc822"
+ : "text/rfc822-headers");
+#else /* _FFR_EAI */
(void) sm_strlcpyn(buf, sizeof(buf), 2, "Content-Type: ",
sendbody ? "message/rfc822"
: "text/rfc822-headers");
+#endif /* _FFR_EAI */
if (!putline(buf, mci))
goto writeerr;
@@ -1804,8 +1879,8 @@ pruneroute(addr)
while (start != NULL)
{
- if (getmxrr(hostbuf, mxhosts, NULL, false,
- &rcode, true, NULL) > 0)
+ if (getmxrr(hostbuf, mxhosts, NULL, TRYFALLBACK, &rcode, NULL, -1)
+ > 0)
{
(void) sm_strlcpy(addr + 1, start + 1,
strlen(addr) - 1);
diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h
index b2d0211ee0f5..e6cf45df0151 100644
--- a/contrib/sendmail/src/sendmail.h
+++ b/contrib/sendmail/src/sendmail.h
@@ -19,14 +19,13 @@
#ifndef MILTER
# define MILTER 1 /* turn on MILTER by default */
-#endif /* MILTER */
+#endif
#ifdef _DEFINE
# define EXTERN
-#else /* _DEFINE */
+#else
# define EXTERN extern
-#endif /* _DEFINE */
-
+#endif
#include <unistd.h>
@@ -37,24 +36,31 @@
#include <setjmp.h>
#include <string.h>
#include <time.h>
-# ifdef EX_OK
-# undef EX_OK /* for SVr4.2 SMP */
-# endif /* EX_OK */
+#ifdef EX_OK
+# undef EX_OK /* for SVr4.2 SMP */
+#endif
#include "sendmail/sendmail.h"
+#if STARTTLS
+# include <openssl/ssl.h>
+# if _FFR_TLSA_DANE && !defined(DANE)
+# define DANE _FFR_TLSA_DANE
+# endif
+#endif
+
/* profiling? */
#if MONCONTROL
# define SM_PROF(x) moncontrol(x)
-#else /* MONCONTROL */
+#else
# define SM_PROF(x)
-#endif /* MONCONTROL */
+#endif
#ifdef _DEFINE
# ifndef lint
SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:51:56 ca Exp $";
-# endif /* ! lint */
-#endif /* _DEFINE */
+# endif
+#endif
#include "bf.h"
#include "timers.h"
@@ -74,81 +80,139 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.1104 2013-11-22 20:5
#ifdef LOG
# include <syslog.h>
-#endif /* LOG */
-
-
+#endif
-# if NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25
-# include <sys/socket.h>
-# endif /* NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 */
-# if NETUNIX
-# include <sys/un.h>
-# endif /* NETUNIX */
-# if NETINET || NETINET6
-# include <netinet/in.h>
-# endif /* NETINET || NETINET6 */
-# if NETINET6
+#if NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25
+# include <sys/socket.h>
+#endif
+#if NETUNIX
+# include <sys/un.h>
+#endif
+#if NETINET || NETINET6
+# include <netinet/in.h>
+#endif
+#if NETINET6
/*
** There is no standard yet for IPv6 includes.
** Specify OS specific implementation in conf.h
*/
-# endif /* NETINET6 */
-# if NETISO
-# include <netiso/iso.h>
-# endif /* NETISO */
-# if NETNS
-# include <netns/ns.h>
-# endif /* NETNS */
-# if NETX25
-# include <netccitt/x25.h>
-# endif /* NETX25 */
-
-# if NAMED_BIND
-# include <arpa/nameser.h>
-# ifdef NOERROR
-# undef NOERROR /* avoid <sys/streams.h> conflict */
-# endif /* NOERROR */
-# include <resolv.h>
-# else /* NAMED_BIND */
-# undef SM_SET_H_ERRNO
-# define SM_SET_H_ERRNO(err)
-# endif /* NAMED_BIND */
-
-# if HESIOD
-# include <hesiod.h>
-# if !defined(HES_ER_OK) || defined(HESIOD_INTERFACES)
-# define HESIOD_INIT /* support for the new interface */
-# endif /* !defined(HES_ER_OK) || defined(HESIOD_INTERFACES) */
-# endif /* HESIOD */
+#endif /* NETINET6 */
+#if NETISO
+# include <netiso/iso.h>
+#endif
+#if NETNS
+# include <netns/ns.h>
+#endif
+#if NETX25
+# include <netccitt/x25.h>
+#endif
+
+#if NAMED_BIND
+# include <arpa/nameser.h>
+# ifdef NOERROR
+# undef NOERROR /* avoid <sys/streams.h> conflict */
+# endif
+# include <resolv.h>
+#else /* NAMED_BIND */
+# undef SM_SET_H_ERRNO
+# define SM_SET_H_ERRNO(err)
+#endif /* NAMED_BIND */
+
+#if HESIOD
+# include <hesiod.h>
+# if !defined(HES_ER_OK) || defined(HESIOD_INTERFACES)
+# define HESIOD_INIT /* support for the new interface */
+# endif
+#endif /* HESIOD */
+
+#if _FFR_EAI && !defined(ALLOW_255)
+# define ALLOW_255 1
+#endif
#if STARTTLS
-# include <openssl/ssl.h>
-# if !TLS_NO_RSA
-# if _FFR_FIPSMODE
-# define RSA_KEYLENGTH 1024
-# else /* _FFR_FIPSMODE */
-# define RSA_KEYLENGTH 512
-# endif /* _FFR_FIPSMODE */
-# endif /* !TLS_NO_RSA */
-#endif /* STARTTLS */
+# if DANE
+struct dane_vrfy_ctx_S
+{
+ int dane_vrfy_chk;
+ int dane_vrfy_res;
+ int dane_vrfy_port;
+
+ /* look up TLSA RRs, SNI unless dane_tlsa_sni is set. */
+ char *dane_vrfy_host;
+ char *dane_vrfy_sni; /* if not NULL: use for SNI */
+
+ /* full fingerprint in printable format */
+ char dane_vrfy_fp[1024];
+};
+
+typedef struct dane_tlsa_S dane_tlsa_T, *dane_tlsa_P;
+typedef struct dane_vrfy_ctx_S dane_vrfy_ctx_T, *dane_vrfy_ctx_P;
+# endif
+
+/* TLS information context */
+struct tlsi_ctx_S
+{
+ /* use unsigned long? */
+ BITMAP256 tlsi_flags;
+# if DANE
+ dane_vrfy_ctx_T tlsi_dvc;
+# endif
+};
+typedef struct tlsi_ctx_S tlsi_ctx_T, *tlsi_ctx_P;
+
+/* TLS information context flags */
+#define TLSI_FL_CRLREQ 'R' /* CRL required */
+#define TLSI_FL_FB2CLR 'C' /* fall back to clear text is ok */
+#define TLSI_FL_NOFB2CLR 'c' /* do not fall back to clear text */
+#define TLSI_FL_NODANE 'd' /* do not use/lookup DANE */
+#define SM_TLSI_IS(tlsi_ctx, flag) \
+ (((tlsi_ctx) != NULL) && bitnset((flag), (tlsi_ctx)->tlsi_flags))
+
+/* ugly hack, is it worth using different values? */
+# if _FFR_LOG_MORE1 > 1 || _FFR_LOG_MORE2 > 1
+# define LOG_MORE_2(buf, bp) \
+ p = macvalue(macid("{tls_version}"), e); \
+ if (p == NULL || *p == '\0') \
+ p = "NONE"; \
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", tls_version=%.10s", p); \
+ bp += strlen(bp); \
+ p = macvalue(macid("{cipher}"), e); \
+ if (p == NULL || *p == '\0') \
+ p = "NONE"; \
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", cipher=%.20s", p); \
+ bp += strlen(bp);
+# else
+# define LOG_MORE_2(buf, bp)
+# endif
-#if SASL /* include the sasl include files if we have them */
+# define LOG_MORE(buf, bp) \
+ p = macvalue(macid("{verify}"), e); \
+ if (p == NULL || *p == '\0') \
+ p = "NONE"; \
+ (void) sm_snprintf(bp, SPACELEFT(buf, bp), ", tls_verify=%.20s", p); \
+ bp += strlen(bp); \
+ LOG_MORE_2(buf, bp)
+#else
+# define LOG_MORE(buf, bp)
+#endif /* STARTTLS */
+#if SASL
+/* include the sasl include files if we have them */
# if SASL == 2 || SASL >= 20000
# include <sasl/sasl.h>
# include <sasl/saslplug.h>
# include <sasl/saslutil.h>
# if SASL_VERSION_FULL < 0x020119
typedef int (*sasl_callback_ft)(void);
-# endif /* SASL_VERSION_FULL < 0x020119 */
+# endif
# else /* SASL == 2 || SASL >= 20000 */
# include <sasl.h>
# include <saslutil.h>
typedef int (*sasl_callback_ft)(void);
# endif /* SASL == 2 || SASL >= 20000 */
# if defined(SASL_VERSION_MAJOR) && defined(SASL_VERSION_MINOR) && defined(SASL_VERSION_STEP)
-# define SASL_VERSION (SASL_VERSION_MAJOR * 10000) + (SASL_VERSION_MINOR * 100) + SASL_VERSION_STEP
+# define SASL_VERSION (SASL_VERSION_MAJOR * 10000) + (SASL_VERSION_MINOR * 100) + SASL_VERSION_STEP
# if SASL == 1 || SASL == 2
# undef SASL
# define SASL SASL_VERSION
@@ -177,19 +241,19 @@ typedef int (*sasl_callback_ft)(void);
#ifndef INADDRSZ
# define INADDRSZ 4 /* size of an IPv4 address in bytes */
-#endif /* ! INADDRSZ */
+#endif
#ifndef IN6ADDRSZ
# define IN6ADDRSZ 16 /* size of an IPv6 address in bytes */
-#endif /* ! IN6ADDRSZ */
+#endif
#ifndef INT16SZ
# define INT16SZ 2 /* size of a 16 bit integer in bytes */
-#endif /* ! INT16SZ */
+#endif
#ifndef INT32SZ
# define INT32SZ 4 /* size of a 32 bit integer in bytes */
-#endif /* ! INT32SZ */
+#endif
#ifndef INADDR_LOOPBACK
# define INADDR_LOOPBACK 0x7f000001 /* loopback address */
-#endif /* ! INADDR_LOOPBACK */
+#endif
/*
** Error return from inet_addr(3), in case not defined in /usr/include.
@@ -197,7 +261,7 @@ typedef int (*sasl_callback_ft)(void);
#ifndef INADDR_NONE
# define INADDR_NONE 0xffffffff
-#endif /* ! INADDR_NONE */
+#endif
/* By default use uncompressed IPv6 address format (no "::") */
#ifndef IPV6_FULL
@@ -207,11 +271,7 @@ typedef int (*sasl_callback_ft)(void);
/* (f)open() modes for queue files */
#define QF_O_EXTRA 0
-#if _FFR_PROXY || _FFR_LOGREPLY
-# define _FFR_ERRCODE 1
-#endif
-
-#define SM_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+#define SM_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
/*
** An 'argument class' describes the storage allocation status
@@ -245,6 +305,9 @@ struct address
char *q_user; /* user name */
char *q_ruser; /* real user name, or NULL if q_user */
char *q_host; /* host name */
+#if DANE
+ char *q_qname; /* original query (host) name */
+#endif
struct mailer *q_mailer; /* mailer to use */
unsigned long q_flags; /* status flags, see below */
uid_t q_uid; /* user-id of receiver (if known) */
@@ -257,7 +320,7 @@ struct address
struct address *q_tchain; /* temporary use chain */
#if PIPELINING
struct address *q_pchain; /* chain for pipelining */
-#endif /* PIPELINING */
+#endif
char *q_finalrcpt; /* Final-Recipient: DSN header */
char *q_orcpt; /* ORCPT parameter from RCPT TO: line */
char *q_status; /* status code for DSNs */
@@ -267,7 +330,6 @@ struct address
short q_state; /* address state, see below */
char *q_signature; /* MX-based sorting value */
int q_qgrp; /* index into queue groups */
- int q_qdir; /* queue directory inside group */
char *q_message; /* error message */
};
@@ -294,6 +356,8 @@ typedef struct address ADDRESS;
#define QBYNRELAY 0x00020000 /* DeliverBy: notify, relayed */
#define QINTBCC 0x00040000 /* internal Bcc */
#define QDYNMAILER 0x00080000 /* "dynamic mailer" */
+#define QSECURE 0x00100000 /* DNSSEC ok */
+#define QQUEUED 0x00200000 /* queued */
#define QTHISPASS 0x40000000 /* temp: address set this pass */
#define QRCPTOK 0x80000000 /* recipient() processed address */
@@ -384,7 +448,7 @@ extern bool sameaddr __P((ADDRESS *, ADDRESS *));
extern int sendtolist __P((char *, ADDRESS *, ADDRESS **, int, ENVELOPE *));
#if MILTER
extern int removefromlist __P((char *, ADDRESS **, ENVELOPE *));
-#endif /* MILTER */
+#endif
extern void setsender __P((char *, ENVELOPE *, char **, int, bool));
typedef void esmtp_args_F __P((ADDRESS *, char *, char *, ENVELOPE *));
extern void parse_esmtp_args __P((ENVELOPE *, ADDRESS *, char *, char *,
@@ -443,6 +507,12 @@ struct mailer
time_t m_wait; /* timeout to wait for end */
int m_maxrcpt; /* max recipients per envelope client-side */
short m_qgrp; /* queue group for this mailer */
+#if DANE
+ unsigned short m_port; /* port (if appropriate for mailer) */
+# define M_PORT(m) ((m)->m_port)
+#else
+# define M_PORT(m) (-1)
+#endif
};
/* bits for m_flags */
@@ -521,7 +591,7 @@ extern void makequeue __P((char *, bool));
extern void runqueueevent __P((int));
#if _FFR_QUEUE_RUN_PARANOIA
extern bool checkqueuerunner __P((void));
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#endif
EXTERN MAILER *FileMailer; /* ptr to *file* mailer */
EXTERN MAILER *InclMailer; /* ptr to *include* mailer */
@@ -545,9 +615,9 @@ struct qpaths_s
char *qp_name; /* name of queue dir, relative path */
short qp_subdirs; /* use subdirs? */
short qp_fsysidx; /* file system index of this directory */
-# if SM_CONF_SHM
+#if SM_CONF_SHM
int qp_idx; /* index into array for queue information */
-# endif /* SM_CONF_SHM */
+#endif
};
typedef struct qpaths_s QPATHS;
@@ -577,14 +647,14 @@ struct queuegrp
BITMAP256 qg_flags; /* status flags, see below */
short qg_nice; /* niceness for queue run */
int qg_wgrp; /* Assigned to this work group */
- int qg_maxlist; /* max items in work queue for this group */
- int qg_curnum; /* current number of queue for queue runs */
+ int qg_maxlist; /* max items in work queue for this group */
+ int qg_curnum; /* current number of queue for queue runs */
int qg_maxrcpt; /* max recipients per envelope, 0==no limit */
time_t qg_nextrun; /* time for next queue runs */
#if _FFR_QUEUE_GROUP_SORTORDER
short qg_sortorder; /* how do we sort this queuerun */
-#endif /* _FFR_QUEUE_GROUP_SORTORDER */
+#endif
#if 0
long qg_wkrcptfact; /* multiplier for # recipients -> priority */
long qg_qfactor; /* slope of queue function */
@@ -599,7 +669,7 @@ struct queuegrp
extern void filesys_update __P((void));
#if _FFR_ANY_FREE_FS
extern bool filesys_free __P((long));
-#endif /* _FFR_ANY_FREE_FS */
+#endif
#if SASL
/*
@@ -724,7 +794,7 @@ MCI
#if PIPELINING
int mci_okrcpts; /* number of valid recipients */
ADDRESS *mci_nextaddr; /* next address for pipelined status */
-#endif /* PIPELINING */
+#endif
#if SASL
SASL_AI_T mci_sai; /* authentication info */
bool mci_sasl_auth; /* authenticated? */
@@ -735,14 +805,16 @@ MCI
#endif /* SASL */
#if STARTTLS
SSL *mci_ssl; /* SSL connection */
-#endif /* STARTTLS */
+ tlsi_ctx_T mci_tlsi;
+#endif
MACROS_T mci_macro; /* macro definitions */
};
-/* flag bits */
-#define MCIF_VALID 0x00000001 /* this entry is valid */
-/* 0x00000002 unused, was MCIF_TEMP */
+/* MCI flag bits */
+/* XREF: mci.c: MciFlags[]: needs to be kept in sync! */
+/* 0x00000001 unused, was MCIF_VALID: this entry is valid */
+#define MCIF_OCC_INCR 0x00000002 /* occ values increased */
#define MCIF_CACHED 0x00000004 /* currently in open cache */
#define MCIF_ESMTP 0x00000008 /* this host speaks ESMTP */
#define MCIF_EXPN 0x00000010 /* EXPN command supported */
@@ -771,7 +843,7 @@ MCI
#define MCIF_DLVR_BY 0x00400000 /* DELIVERBY */
#if _FFR_IGNORE_EXT_ON_HELO
# define MCIF_HELO 0x00800000 /* we used HELO: ignore extensions */
-#endif /* _FFR_IGNORE_EXT_ON_HELO */
+#endif
#define MCIF_INLONGLINE 0x01000000 /* in the middle of a long line */
#define MCIF_AUTH2 0x02000000 /* got 2 AUTH lines */
#define MCIF_ONLY_EHLO 0x10000000 /* use only EHLO in smtpinit */
@@ -781,8 +853,13 @@ MCI
#else
# define MCIF_NOTSTICKY 0
#endif
+#if _FFR_EAI
+# define MCIF_EAI 0x40000000 /* SMTPUTF8 supported */
+#else
+# define MCIF_EAI 0x00000000 /* for MCIF_EXTENS */
+#endif
-#define MCIF_EXTENS (MCIF_EXPN | MCIF_SIZE | MCIF_8BITMIME | MCIF_DSN | MCIF_8BITOK | MCIF_AUTH | MCIF_ENHSTAT | MCIF_TLS | MCIF_AUTH2)
+#define MCIF_EXTENS (MCIF_EXPN|MCIF_SIZE|MCIF_8BITMIME|MCIF_DSN|MCIF_8BITOK|MCIF_AUTH|MCIF_ENHSTAT|MCIF_PIPELINED|MCIF_VERB|MCIF_TLS|MCIF_DLVR_BY|MCIF_AUTH2|MCIF_EAI)
/* states */
#define MCIS_CLOSED 0 /* no traffic on this connection */
@@ -921,6 +998,9 @@ struct envelope
ADDRESS e_from; /* the person it is from */
char *e_sender; /* e_from.q_paddr w comments stripped */
char **e_fromdomain; /* the domain part of the sender */
+#if _FFR_EAI
+ bool e_smtputf8; /* whether the sender demanded SMTPUTF8 */
+#endif
ADDRESS *e_sendqueue; /* list of message recipients */
ADDRESS *e_errorqueue; /* the queue for error responses */
@@ -951,7 +1031,7 @@ struct envelope
char *e_id; /* code for this entry in queue */
#if _FFR_SESSID
char *e_sessid; /* session ID for this envelope */
-#endif /* _FFR_SESSID */
+#endif
int e_qgrp; /* queue group (index into queues) */
int e_qdir; /* index into queue directories */
int e_dfqgrp; /* data file queue group index */
@@ -987,13 +1067,11 @@ struct envelope
#define ENHSC_LEN 11
#if _FFR_MILTER_ENHSC
char e_enhsc[ENHSC_LEN]; /* enhanced status code */
-#endif /* _FFR_MILTER_ENHSC */
-#if _FFR_ERRCODE
+#endif
/* smtp error codes during delivery */
int e_rcode; /* reply code */
char e_renhsc[ENHSC_LEN]; /* enhanced status code */
char *e_text; /* reply text */
-#endif /* _FFR_ERRCODE */
};
#define PRT_NONNEGL(v) ((v) < 0 ? LONG_MAX : (v))
@@ -1017,8 +1095,8 @@ struct envelope
#define EF_LOGSENDER 0x00008000L /* need to log the sender */
#define EF_NORECEIPT 0x00010000L /* suppress all return-receipts */
#define EF_HAS8BIT 0x00020000L /* at least one 8-bit char in body */
-#define EF_NL_NOT_EOL 0x00040000L /* don't accept raw NL as EOLine */
-#define EF_CRLF_NOT_EOL 0x00080000L /* don't accept CR-LF as EOLine */
+/* was: EF_NL_NOT_EOL 0x00040000L * don't accept raw NL as EOLine */
+/* was: EF_CRLF_NOT_EOL 0x00080000L * don't accept CR-LF as EOLine */
#define EF_RET_PARAM 0x00100000L /* RCPT command had RET argument */
#define EF_HAS_DF 0x00200000L /* set when data file is instantiated */
#define EF_IS_MIME 0x00400000L /* really is a MIME message */
@@ -1028,6 +1106,7 @@ struct envelope
#define EF_SPLIT 0x04000000L /* envelope has been split */
#define EF_UNSAFE 0x08000000L /* unsafe: read from untrusted source */
#define EF_TOODEEP 0x10000000L /* message is nested too deep */
+#define EF_SECURE 0x20000000L /* DNSSEC for currently parsed addr */
#define DLVR_NOTIFY 0x01
#define DLVR_RETURN 0x02
@@ -1183,10 +1262,11 @@ extern void macset __P((MACROS_T *, int, char *));
#define macget(mac, i) (mac)->mac_table[i]
extern void expand __P((char *, char *, size_t, ENVELOPE *));
extern int macid_parse __P((char *, char **));
-#define macid(name) macid_parse(name, NULL)
+#define macid(name) macid_parse(name, NULL)
extern char *macname __P((int));
extern char *macvalue __P((int, ENVELOPE *));
-extern int rscheck __P((char *, char *, char *, ENVELOPE *, int, int, char *, char *, ADDRESS *, char **));
+extern void mactabclear __P((MACROS_T *));
+extern int rscheck __P((char *, const char *, const char *, ENVELOPE *, int, int, const char *, const char *, ADDRESS *, char **));
extern int rscap __P((char *, char *, char *, ENVELOPE *, char ***, char *, int));
extern void setclass __P((int, char *));
extern int strtorwset __P((char *, char **, int));
@@ -1217,6 +1297,8 @@ NAMECANON
/* values for nc_flags */
#define NCF_VALID 0x0001 /* entry valid */
+#define NCF_VALID 0x0001 /* entry valid */
+#define NCF_SECURE 0x0002 /* entry secure (DNSSEC) */
/* hostsignature structure */
@@ -1237,9 +1319,9 @@ typedef struct hostsig_t HOSTSIG_T;
** it not big enough to accommodate the entire answer.
*/
-# ifndef MAXPACKET
-# define MAXPACKET 8192 /* max packet size used internally by BIND */
-# endif /* ! MAXPACKET */
+#ifndef MAXPACKET
+# define MAXPACKET 8192 /* max packet size used internally by BIND */
+#endif
/*
** The resolver functions res_{send,query,querydomain} expect the
@@ -1255,10 +1337,24 @@ typedef union
unsigned char qb2[MAXPACKET];
} querybuf;
+
+/* result values for getcanonname() etc */
+#define HOST_NOTFOUND 0
+#define HOST_OK 1
+#define HOST_SECURE 2
+
+/* flags for getmxrr() */
+#define DROPLOCALHOST 0x01
+#define TRYFALLBACK 0x02
+#define ISAD 0x04
+
+/* RFC7505: Null MX */
+#define NULLMX (-2)
+
/* functions */
-extern bool getcanonname __P((char *, int, bool, int *));
-extern int getmxrr __P((char *, char **, unsigned short *, bool, int *, bool, int *));
-extern char *hostsignature __P((MAILER *, char *));
+extern int getcanonname __P((char *, int, bool, int *));
+extern int getmxrr __P((char *, char **, unsigned short *, unsigned int, int *, int *, int));
+extern char *hostsignature __P((MAILER *, char *, bool));
extern int getfallbackmxrr __P((char *));
/*
@@ -1301,7 +1397,6 @@ MAP
int map_retry; /* # of retries for map accesses */
pid_t map_pid; /* PID of process which opened map */
int map_lockfd; /* auxiliary lock file descriptor */
- short map_specificity; /* specificity of aliases */
MAP *map_stack[MAXMAPSTACK]; /* list for stacked maps */
short map_return[MAXMAPACTIONS]; /* return bitmaps for stacked maps */
};
@@ -1322,7 +1417,7 @@ MAP
#define MF_ALIASWAIT 0x00000800 /* alias map in aliaswait state */
#define MF_IMPL_HASH 0x00001000 /* implicit: underlying hash database */
#define MF_IMPL_NDBM 0x00002000 /* implicit: underlying NDBM database */
-/* 0x00004000 */
+#define MF_IMPL_CDB 0x00004000 /* implicit: underlying CDB database */
#define MF_APPEND 0x00008000 /* append new entry on rebuild */
#define MF_KEEPQUOTES 0x00010000 /* don't dequote key before lookup */
#define MF_NODEFER 0x00020000 /* don't defer if map lookup fails */
@@ -1333,6 +1428,7 @@ MAP
#define MF_FILECLASS 0x00400000 /* this is a file class map */
#define MF_OPENBOGUS 0x00800000 /* open failed, don't call map_close */
#define MF_CLOSING 0x01000000 /* map is being closed */
+#define MF_SECURE 0x02000000 /* DNSSEC result is "secure" */
#define DYNOPENMAP(map) \
do \
@@ -1373,7 +1469,7 @@ MAPCLASS
/* bit values for map_cflags */
#define MCF_ALIASOK 0x0001 /* can be used for aliases */
-#define MCF_ALIASONLY 0x0002 /* usable only for aliases */
+/* #define MCF_ALIASONLY 0x0002 * usable only for aliases */
#define MCF_REBUILDABLE 0x0004 /* can rebuild alias files */
#define MCF_OPTFILE 0x0008 /* file name is optional */
#define MCF_NOTPERSIST 0x0010 /* don't keep map open all the time */
@@ -1387,13 +1483,13 @@ extern void maplocaluser __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
extern char *map_rewrite __P((MAP *, const char *, size_t, char **));
#if NETINFO
extern char *ni_propval __P((char *, char *, char *, char *, int));
-#endif /* NETINFO */
+#endif
extern bool openmap __P((MAP *));
extern int udbexpand __P((ADDRESS *, ADDRESS **, int, ENVELOPE *));
#if USERDB
extern void _udbx_close __P((void));
extern char *udbsender __P((char *, SM_RPOOL_T *));
-#endif /* USERDB */
+#endif
/*
** LDAP related items
@@ -1456,22 +1552,22 @@ union bigsockaddr
struct sockaddr sa; /* general version */
# if NETUNIX
struct sockaddr_un sunix; /* UNIX family */
-# endif /* NETUNIX */
+# endif
# if NETINET
struct sockaddr_in sin; /* INET family */
-# endif /* NETINET */
+# endif
# if NETINET6
struct sockaddr_in6 sin6; /* INET/IPv6 */
-# endif /* NETINET6 */
+# endif
# if NETISO
struct sockaddr_iso siso; /* ISO family */
-# endif /* NETISO */
+# endif
# if NETNS
struct sockaddr_ns sns; /* XNS family */
-# endif /* NETNS */
+# endif
# if NETX25
struct sockaddr_x25 sx25; /* X.25 family */
-# endif /* NETX25 */
+# endif
};
# define SOCKADDR union bigsockaddr
@@ -1481,12 +1577,12 @@ 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 */
+# endif
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
#endif /* NETINET || NETINET6 || NETUNIX || NETISO || NETNS || NETX25 */
@@ -1497,7 +1593,7 @@ extern bool iptostring __P((SOCKADDR *, SOCKADDR_LEN_T, char *, unsigned));
#define NO_PID ((pid_t) 0)
#ifndef PROC_LIST_SEG
# define PROC_LIST_SEG 32 /* number of pids to alloc at a time */
-#endif /* ! PROC_LIST_SEG */
+#endif
/* process types */
#define PROC_NONE 0
@@ -1542,14 +1638,17 @@ struct symtab
char *sv_service[MAXMAPSTACK]; /* service switch */
#if LDAPMAP
MAP *sv_lmap; /* Maps for LDAP connection */
-#endif /* LDAPMAP */
+#endif
#if SOCKETMAP
MAP *sv_socketmap; /* Maps for SOCKET connection */
-#endif /* SOCKETMAP */
+#endif
#if MILTER
struct milter *sv_milter; /* milter filter name */
-#endif /* MILTER */
+#endif
QUEUEGRP *sv_queue; /* pointer to queue */
+#if DANE
+ dane_tlsa_P sv_tlsa; /* pointer to TLSA RRs */
+#endif
} s_value;
};
@@ -1571,18 +1670,22 @@ typedef struct symtab STAB;
#define ST_HEADER 12 /* special header flags */
#if LDAPMAP
# define ST_LMAP 13 /* List head of maps for LDAP connection */
-#endif /* LDAPMAP */
+#endif
#if MILTER
# define ST_MILTER 14 /* milter filter */
-#endif /* MILTER */
+#endif
#define ST_QUEUE 15 /* a queue entry */
#if SOCKETMAP
-# define ST_SOCKETMAP 16 /* List head of maps for SOCKET connection */
-#endif /* SOCKETMAP */
+# define ST_SOCKETMAP 16 /* List head of maps for SOCKET connection */
+#endif
+
+#if DANE
+# define ST_TLSA_RR 17 /* cached TLSA RRs */
+#endif
/* This entry must be last */
-#define ST_MCI 17 /* mailer connection info (offset) */
+#define ST_MCI 18 /* mailer connection info (offset) */
#define s_class s_value.sv_class
#define s_mailer s_value.sv_mailer
@@ -1598,14 +1701,17 @@ typedef struct symtab STAB;
#define s_header s_value.sv_header
#if LDAPMAP
# define s_lmap s_value.sv_lmap
-#endif /* LDAPMAP */
+#endif
#if SOCKETMAP
-# define s_socketmap s_value.sv_socketmap
-#endif /* SOCKETMAP */
+# define s_socketmap s_value.sv_socketmap
+#endif
#if MILTER
# define s_milter s_value.sv_milter
-#endif /* MILTER */
+#endif
#define s_quegrp s_value.sv_queue
+#if DANE
+# define s_tlsa s_value.sv_tlsa
+#endif
/* opcodes to stab */
#define ST_FIND 0 /* find entry */
@@ -1672,20 +1778,20 @@ EXTERN bool V6LoopbackAddrFound; /* found an IPv6 loopback address */
#if _FFR_PROXY
#define SM_PROXY_REQ 's' /* synchronous mode requested */
#define SM_PROXY 'S' /* synchronous mode activated */
-#endif /* _FFR_PROXY */
+#endif
#define SM_FORK 'b' /* deliver in background */
#if _FFR_DM_ONE
#define SM_DM_ONE 'o' /* deliver first TA in background, then queue */
-#endif /* _FFR_DM_ONE */
+#endif
#define SM_QUEUE 'q' /* queue, don't deliver */
#define SM_DEFER 'd' /* defer map lookups as well as queue */
#define SM_VERIFY 'v' /* verify only (used internally) */
#define DM_NOTSET (-1) /* DeliveryMode (per daemon) option not set */
#if _FFR_PROXY
# define SM_IS_INTERACTIVE(m) ((m) == SM_DELIVER || (m) == SM_PROXY_REQ || (m) == SM_PROXY)
-#else /* _FFR_PROXY */
+#else
# define SM_IS_INTERACTIVE(m) ((m) == SM_DELIVER)
-#endif /* _FFR_PROXY */
+#endif
#define WILL_BE_QUEUED(m) ((m) == SM_QUEUE || (m) == SM_DEFER)
@@ -1839,16 +1945,16 @@ struct milter
char mf_lflags; /* "local" flags */
int mf_idx; /* milter number (index) */
time_t mf_timeout[SMFTO_NUM_TO]; /* timeouts */
-#if _FFR_MILTER_CHECK
+# if _FFR_MILTER_CHECK
/* for testing only */
mi_int32 mf_mta_prot_version;
mi_int32 mf_mta_prot_flags;
mi_int32 mf_mta_actions;
-#endif /* _FFR_MILTER_CHECK */
+# endif /* _FFR_MILTER_CHECK */
};
-#define MI_LFL_NONE 0x00000000
-#define MI_LFLAGS_SYM(st) (1 << (st)) /* has its own symlist for stage st */
+# define MI_LFL_NONE 0x00000000
+# define MI_LFLAGS_SYM(st) (1 << (st)) /* has its own symlist for stage st */
struct milters
{
@@ -1856,9 +1962,9 @@ struct milters
};
typedef struct milters milters_T;
-#define MIS_FL_NONE 0x00000000 /* no requirements... */
-#define MIS_FL_DEL_RCPT 0x00000001 /* can delete rcpt */
-#define MIS_FL_REJ_RCPT 0x00000002 /* can reject rcpt */
+# define MIS_FL_NONE 0x00000000 /* no requirements... */
+# define MIS_FL_DEL_RCPT 0x00000001 /* can delete rcpt */
+# define MIS_FL_REJ_RCPT 0x00000002 /* can reject rcpt */
/* MTA flags */
@@ -1885,8 +1991,9 @@ extern void setup_daemon_milters __P((void));
** -DVENDOR_DEFAULT=VENDOR_xxx
** in the Makefile.
**
-** Vendors should apply to sendmail@sendmail.org for
-** unique vendor codes.
+** Vendors should apply to sendmail-YYYY@support.sendmail.org
+** (replace YYYY with the current year)
+** for unique vendor codes.
*/
#define VENDOR_BERKELEY 1 /* Berkeley-native configuration file */
@@ -1928,6 +2035,9 @@ struct termescape
#define D_CANONREQ 'c' /* canonification required (cf) */
#define D_IFNHELO 'h' /* use if name for HELO */
#define D_FQMAIL 'f' /* fq sender address required (cf) */
+#if _FFR_EAI
+#define D_EAI 'I' /* EAI supported */
+#endif
#define D_FQRCPT 'r' /* fq recipient address required (cf) */
#define D_SMTPS 's' /* SMTP over SSL (smtps) */
#define D_UNQUALOK 'u' /* unqualified address is ok (cf) */
@@ -1942,88 +2052,8 @@ struct termescape
#if _FFR_XCNCT
#define D_XCNCT ((char)0x04) /* X-Connect was used */
#define D_XCNCT_M ((char)0x05) /* X-Connect was used + "forged" */
-#endif /* _FFR_XCNCT */
-
-#if STARTTLS
-/*
-** TLS
-*/
-
-/* what to do in the TLS initialization */
-#define TLS_I_NONE 0x00000000 /* no requirements... */
-#define TLS_I_CERT_EX 0x00000001 /* cert must exist */
-#define TLS_I_CERT_UNR 0x00000002 /* cert must be g/o unreadable */
-#define TLS_I_KEY_EX 0x00000004 /* key must exist */
-#define TLS_I_KEY_UNR 0x00000008 /* key must be g/o unreadable */
-#define TLS_I_CERTP_EX 0x00000010 /* CA cert path must exist */
-#define TLS_I_CERTP_UNR 0x00000020 /* CA cert path must be g/o unreadable */
-#define TLS_I_CERTF_EX 0x00000040 /* CA cert file must exist */
-#define TLS_I_CERTF_UNR 0x00000080 /* CA cert file must be g/o unreadable */
-#define TLS_I_RSA_TMP 0x00000100 /* RSA TMP must be generated */
-#define TLS_I_USE_KEY 0x00000200 /* private key must usable */
-#define TLS_I_USE_CERT 0x00000400 /* certificate must be usable */
-#define TLS_I_VRFY_PATH 0x00000800 /* load verify path must succeed */
-#define TLS_I_VRFY_LOC 0x00001000 /* load verify default must succeed */
-#define TLS_I_CACHE 0x00002000 /* require cache */
-#define TLS_I_TRY_DH 0x00004000 /* try DH certificate */
-#define TLS_I_REQ_DH 0x00008000 /* require DH certificate */
-#define TLS_I_DHPAR_EX 0x00010000 /* require DH parameters */
-#define TLS_I_DHPAR_UNR 0x00020000 /* DH param. must be g/o unreadable */
-#define TLS_I_DH512 0x00040000 /* generate 512bit DH param */
-#define TLS_I_DH1024 0x00080000 /* generate 1024bit DH param */
-#define TLS_I_DH2048 0x00100000 /* generate 2048bit DH param */
-#define TLS_I_NO_VRFY 0x00200000 /* do not require authentication */
-#define TLS_I_KEY_OUNR 0x00400000 /* Key must be 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 */
-#define TLS_I_DHFIXED 0x02000000 /* use fixed DH param */
-
-/* require server cert */
-#define TLS_I_SRV_CERT (TLS_I_CERT_EX | TLS_I_KEY_EX | \
- TLS_I_KEY_UNR | TLS_I_KEY_OUNR | \
- TLS_I_CERTP_EX | TLS_I_CERTF_EX | \
- TLS_I_USE_KEY | TLS_I_USE_CERT | TLS_I_CACHE)
-
-/* server requirements */
-#define TLS_I_SRV (TLS_I_SRV_CERT | TLS_I_RSA_TMP | TLS_I_VRFY_PATH | \
- TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_CACHE)
-
-/* client requirements */
-#define TLS_I_CLT (TLS_I_KEY_UNR | TLS_I_KEY_OUNR)
-
-#define TLS_AUTH_OK 0
-#define TLS_AUTH_NO 1
-#define TLS_AUTH_FAIL (-1)
+#endif
-/* functions */
-extern bool init_tls_library __P((bool _fipsmode));
-extern bool inittls __P((SSL_CTX **, unsigned long, unsigned long, bool, char *, char *, char *, char *, char *));
-extern bool initclttls __P((bool));
-extern void setclttls __P((bool));
-extern bool initsrvtls __P((bool));
-extern int tls_get_info __P((SSL *, bool, char *, MACROS_T *, bool));
-extern int endtls __P((SSL *, char *));
-extern void tlslogerr __P((int, const char *));
-
-
-EXTERN char *CACertPath; /* path to CA certificates (dir. with hashes) */
-EXTERN char *CACertFile; /* file with CA certificate */
-EXTERN char *CltCertFile; /* file with client certificate */
-EXTERN char *CltKeyFile; /* file with client private key */
-EXTERN char *CipherList; /* list of ciphers */
-EXTERN char *CertFingerprintAlgorithm; /* name of fingerprint alg */
-EXTERN const EVP_MD *EVP_digest; /* digest for cert fp */
-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 */
-EXTERN unsigned long Srv_SSL_Options, Clt_SSL_Options; /* SSL options */
-#endif /* STARTTLS */
/*
** Queue related items
@@ -2050,7 +2080,7 @@ EXTERN unsigned long Srv_SSL_Options, Clt_SSL_Options; /* SSL options */
#define QSO_NONE 6 /* do not sort */
#if _FFR_RHS
# define QSO_BYSHUFFLE 7 /* sort by shuffled host name */
-#endif /* _FFR_RHS */
+#endif
#define NOQGRP (-1) /* no queue group (yet) */
#define ENVQGRP (-2) /* use queue group of envelope */
@@ -2140,9 +2170,9 @@ extern int print_single_queue __P((int, int));
#if REQUIRES_DIR_FSYNC
# define SYNC_DIR(path, panic) sync_dir(path, panic)
extern void sync_dir __P((char *, bool));
-#else /* REQUIRES_DIR_FSYNC */
+#else
# define SYNC_DIR(path, panic) ((void) 0)
-#endif /* REQUIRES_DIR_FSYNC */
+#endif
/*
** Timeouts
@@ -2174,10 +2204,10 @@ EXTERN struct
time_t to_lhlo; /* LMTP: LHLO command */
#if SASL
time_t to_auth; /* AUTH dialogue [10m] */
-#endif /* SASL */
+#endif
#if STARTTLS
time_t to_starttls; /* STARTTLS dialogue [10m] */
-#endif /* STARTTLS */
+#endif
/* following are per message */
time_t to_q_return[MAXTOCLASS]; /* queue return timeouts */
time_t to_q_warning[MAXTOCLASS]; /* queue warning timeouts */
@@ -2249,17 +2279,6 @@ extern unsigned char tTdvect[100]; /* trace vector */
#define STRUCTCOPY(s, d) d = s
-/* free a pointer if it isn't NULL and set it to NULL */
-#define SM_FREE_CLR(p) \
- do \
- { \
- if ((p) != NULL) \
- { \
- sm_free(p); \
- (p) = NULL; \
- } \
- } while (0)
-
/*
** Update a permanent string variable with a new value.
** The old value is freed, the new value is strdup'ed.
@@ -2272,12 +2291,6 @@ extern unsigned char tTdvect[100]; /* trace vector */
** If an exception occurs while strdup'ing the new value,
** then the variable remains set to the old value.
** That's why the strdup must occur before we free the old value.
-**
-** The macro uses a do loop so that this idiom will work:
-** if (...)
-** PSTRSET(var, val1);
-** else
-** PSTRSET(var, val2);
*/
#define PSTRSET(var, val) \
do \
@@ -2336,16 +2349,16 @@ EXTERN bool AddBcc;
#endif
#if _FFR_ADDR_TYPE_MODES
EXTERN bool AddrTypeModes; /* addr_type: extra "mode" information */
-#endif /* _FFR_ADDR_TYPE_MODES */
+#endif
EXTERN bool AllowBogusHELO; /* allow syntax errors on HELO command */
EXTERN bool CheckAliases; /* parse addresses during newaliases */
#if _FFR_QUEUE_RUN_PARANOIA
EXTERN int CheckQueueRunners; /* check whether queue runners are OK */
-#endif /* _FFR_QUEUE_RUN_PARANOIA */
+#endif
EXTERN bool ColonOkInAddr; /* single colon legal in address */
#if !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_)
EXTERN bool ConfigFileRead; /* configuration file has been read */
-#endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */
+#endif
EXTERN bool DisConnected; /* running with OutChannel redirect to transcript file */
EXTERN bool DontExpandCnames; /* do not $[...$] expand CNAMEs */
EXTERN bool DontInitGroups; /* avoid initgroups() because of NIS cost */
@@ -2355,12 +2368,21 @@ EXTERN bool ForkQueueRuns; /* fork for each job when running the queue */
EXTERN bool FromFlag; /* if set, "From" person is explicit */
EXTERN bool FipsMode;
EXTERN bool GrabTo; /* if set, get recipients from msg */
+#if _FFR_EIGHT_BIT_ADDR_OK
EXTERN bool EightBitAddrOK; /* we'll let 8-bit addresses through */
+#else
+# define EightBitAddrOK false
+#endif
EXTERN bool HasEightBits; /* has at least one eight bit input byte */
EXTERN bool HasWildcardMX; /* don't use MX records when canonifying */
EXTERN bool HoldErrs; /* only output errors to transcript */
EXTERN bool IgnoreHostStatus; /* ignore long term host status files */
EXTERN bool IgnrDot; /* don't let dot end messages */
+#if _FFR_KEEPBCC
+EXTERN bool KeepBcc;
+#else
+# define KeepBcc false
+#endif
EXTERN bool LogUsrErrs; /* syslog user errors (e.g., SMTP RCPT cmd) */
EXTERN bool MatchGecos; /* look for user names in gecos field */
EXTERN bool MeToo; /* send to the sender also */
@@ -2370,10 +2392,10 @@ EXTERN bool OnlyOneError; /* .... or only want to give one SMTP reply */
EXTERN bool QuickAbort; /* .... but only if we want a quick abort */
#if _FFR_REJECT_NUL_BYTE
EXTERN bool RejectNUL; /* reject NUL input byte? */
-#endif /* _FFR_REJECT_NUL_BYTE */
+#endif
#if REQUIRES_DIR_FSYNC
EXTERN bool RequiresDirfsync; /* requires fsync() for directory */
-#endif /* REQUIRES_DIR_FSYNC */
+#endif
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 */
@@ -2396,18 +2418,24 @@ EXTERN char SpaceSub; /* substitution for <lwsp> */
#if _FFR_BADRCPT_SHUTDOWN
EXTERN int BadRcptShutdown; /* Shutdown connection for rejected RCPTs */
EXTERN int BadRcptShutdownGood; /* above even when there are good RCPTs */
-#endif /* _FFR_BADRCPT_SHUTDOWN */
+#endif
EXTERN int BadRcptThrottle; /* Throttle rejected RCPTs per SMTP message */
#if _FFR_RCPTTHROTDELAY
EXTERN unsigned int BadRcptThrottleDelay; /* delay for BadRcptThrottle */
#else
# define BadRcptThrottleDelay 1
-#endif /* _FFR_RCPTTHROTDELAY */
+#endif
+#if _FFR_TLS_ALTNAMES
+EXTERN bool SetCertAltnames;
+#endif
EXTERN int CheckpointInterval; /* queue file checkpoint interval */
EXTERN int ConfigLevel; /* config file level */
EXTERN int ConnRateThrottle; /* throttle for SMTP connection rate */
EXTERN int volatile CurChildren; /* current number of daemonic children */
EXTERN int CurrentLA; /* current load average */
+#if DANE
+EXTERN int Dane; /* DANE */
+#endif
EXTERN int DefaultNotify; /* default DSN notification flags */
EXTERN int DelayLA; /* load average to delay connections */
EXTERN int DontProbeInterfaces; /* don't probe interfaces for names */
@@ -2431,7 +2459,7 @@ EXTERN int MaxRcptPerMsg; /* max recipients per SMTP message */
EXTERN int MaxRuleRecursion; /* maximum depth of ruleset recursion */
#if _FFR_MSG_ACCEPT
EXTERN char *MessageAccept; /* "Message accepted for delivery" reply text */
-#endif /* _FFR_MSG_ACCEPT */
+#endif
EXTERN int MimeMode; /* MIME processing mode */
EXTERN int NoRecipientAction;
@@ -2440,9 +2468,9 @@ EXTERN int NoRecipientAction;
EXTERN int Numfilesys; /* number of queue file systems */
EXTERN int *PNumFileSys;
# define NumFileSys (*PNumFileSys)
-# else /* SM_CONF_SHM */
+#else /* SM_CONF_SHM */
EXTERN int NumFileSys; /* number of queue file systems */
-# endif /* SM_CONF_SHM */
+#endif /* SM_CONF_SHM */
EXTERN int QueueLA; /* load average starting forced queueing */
EXTERN int RefuseLA; /* load average refusing connections */
@@ -2462,7 +2490,7 @@ EXTERN gid_t EffGid; /* effective gid */
#if SM_CONF_SHM
EXTERN key_t ShmKey; /* shared memory key */
EXTERN char *ShmKeyFile; /* shared memory key file */
-#endif /* SM_CONF_SHM */
+#endif
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 */
@@ -2528,7 +2556,7 @@ EXTERN SM_FILE_T *OutChannel; /* output connection */
EXTERN SM_FILE_T *TrafficLogFile; /* file in which to log all traffic */
#if HESIOD
EXTERN void *HesiodContext;
-#endif /* HESIOD */
+#endif
EXTERN ENVELOPE *CurEnv; /* envelope currently being processed */
EXTERN char *RuleSetNames[MAXRWSETS]; /* ruleset number to name */
EXTERN char *UserEnviron[MAXUSERENVIRON + 1];
@@ -2538,11 +2566,15 @@ EXTERN SOCKADDR ConnectOnlyTo; /* override connection address (for testing) */
EXTERN SOCKADDR RealHostAddr; /* address of host we are talking to */
extern const SM_EXC_TYPE_T EtypeQuickAbort; /* type of a QuickAbort exception */
+#if _FFR_BLANKENV_MACV
+EXTERN int Hacks; /* bit field of run-time enabled "hacks" */
+# define H_LOOKUP_MACRO_IN_BLANKENV 0x0001
+# define LOOKUP_MACRO_IN_BLANKENV (Hacks & H_LOOKUP_MACRO_IN_BLANKENV)
+#else
+# define LOOKUP_MACRO_IN_BLANKENV false
+#endif
EXTERN int ConnectionRateWindowSize;
-#if STARTTLS && USE_OPENSSL_ENGINE
-EXTERN bool SSLEngineInitialized;
-#endif /* STARTTLS && USE_OPENSSL_ENGINE */
/*
** Declarations of useful functions
@@ -2552,18 +2584,24 @@ EXTERN bool SSLEngineInitialized;
extern void closexscript __P((ENVELOPE *));
extern void openxscript __P((ENVELOPE *));
+#if SM_DEVELOPER
+#define NR_PRINTFLIKE(a, b) PRINTFLIKE(a, b)
+#else
+#define NR_PRINTFLIKE(a, b)
+#endif
+
/* error related */
extern void buffer_errors __P((void));
extern void flush_errors __P((bool));
-extern void PRINTFLIKE(1, 2) message __P((const char *, ...));
-extern void PRINTFLIKE(1, 2) nmessage __P((const char *, ...));
+extern void NR_PRINTFLIKE(1, 2) message __P((const char *, ...));
+extern void NR_PRINTFLIKE(1, 2) nmessage __P((const char *, ...));
#if _FFR_PROXY
-extern void PRINTFLIKE(3, 4) emessage __P((const char *, const char *, const char *, ...));
+extern void NR_PRINTFLIKE(3, 4) emessage __P((const char *, const char *, const char *, ...));
extern int extsc __P((const char *, int, char *, char *));
-#endif /* _FFR_PROXY */
-extern void PRINTFLIKE(1, 2) syserr __P((const char *, ...));
-extern void PRINTFLIKE(2, 3) usrerrenh __P((char *, const char *, ...));
-extern void PRINTFLIKE(1, 2) usrerr __P((const char *, ...));
+#endif
+extern void NR_PRINTFLIKE(1, 2) syserr __P((const char *, ...));
+extern void NR_PRINTFLIKE(2, 3) usrerrenh __P((char *, const char *, ...));
+extern void NR_PRINTFLIKE(1, 2) usrerr __P((const char *, ...));
extern int isenhsc __P((const char *, int));
extern int extenhsc __P((const char *, int, char *));
@@ -2586,7 +2624,7 @@ extern int reply __P((MAILER *, MCI *, ENVELOPE *, time_t, void (*)__P((char *,
extern void smtp __P((char *volatile, BITMAP256, ENVELOPE *volatile));
#if SASL
extern int smtpauth __P((MAILER *, MCI *, ENVELOPE *));
-#endif /* SASL */
+#endif
extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *, ADDRESS *, time_t));
extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *));
extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *));
@@ -2602,10 +2640,11 @@ extern void smtprset __P((MAILER *, MCI *, ENVELOPE *));
#define REPLYCLASS(r) (((r) / 10) % 10) /* second digit of reply code */
#define REPLYMINOR(r) ((r) % 10) /* last digit of reply code */
#define ISSMTPCODE(c) (isascii(c[0]) && isdigit(c[0]) && \
- isascii(c[1]) && isdigit(c[1]) && \
- isascii(c[2]) && isdigit(c[2]))
+ isascii(c[1]) && isdigit(c[1]) && \
+ isascii(c[2]) && isdigit(c[2]))
#define ISSMTPREPLY(c) (ISSMTPCODE(c) && \
- (c[3] == ' ' || c[3] == '-' || c[3] == '\0'))
+ (c[3] == ' ' || c[3] == '-' || c[3] == '\0'))
+#define SM_ISSPACE(c) (isascii(c) && isspace(c))
/* delivery */
extern pid_t dowork __P((int, int, char *, bool, bool, ENVELOPE *));
@@ -2625,8 +2664,8 @@ extern void clearstats __P((void));
extern void poststats __P((char *));
/* control socket */
-extern void closecontrolsocket __P((bool));
-extern void clrcontrol __P((void));
+extern void closecontrolsocket __P((bool));
+extern void clrcontrol __P((void));
extern void control_command __P((int, ENVELOPE *));
extern int opencontrolsocket __P((void));
@@ -2663,17 +2702,16 @@ extern int checkcompat __P((ADDRESS *, ENVELOPE *));
#ifdef XDEBUG
extern void checkfd012 __P((char *));
extern void checkfdopen __P((int, char *));
-#endif /* XDEBUG */
+#endif
extern void checkfds __P((char *));
extern bool chownsafe __P((int, bool));
extern void cleanstrcpy __P((char *, char *, int));
#if SM_CONF_SHM
extern void cleanup_shm __P((bool));
-#endif /* SM_CONF_SHM */
+#endif
extern void close_sendmail_pid __P((void));
extern void clrdaemon __P((void));
extern void collect __P((SM_FILE_T *, bool, HDR **, ENVELOPE *, bool));
-extern 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));
@@ -2684,14 +2722,14 @@ extern char *denlstring __P((char *, bool, bool));
extern void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *));
extern void disconnect __P((int, ENVELOPE *));
extern void disk_status __P((SM_FILE_T *, char *));
-extern bool dns_getcanonname __P((char *, int, bool, int *, int *));
+extern int dns_getcanonname __P((char *, int, bool, int *, int *));
extern pid_t dofork __P((void));
extern int drop_privileges __P((bool));
extern int dsntoexitstat __P((char *));
extern void dumpfd __P((int, bool, bool));
#if SM_HEAP_CHECK
extern void dumpstab __P((void));
-#endif /* SM_HEAP_CHECK */
+#endif
extern void dumpstate __P((char *));
extern bool enoughdiskspace __P((long, ENVELOPE *));
extern char *exitstat __P((char *));
@@ -2705,7 +2743,7 @@ extern void fixcrlf __P((char *, bool));
extern long freediskspace __P((const char *, long *));
#if NETINET6 && NEEDSGETIPNODE
extern void freehostent __P((struct hostent *));
-#endif /* NETINET6 && NEEDSGETIPNODE */
+#endif
extern char *get_column __P((char *, int, int, char *, int));
extern char *getauthinfo __P((int, bool *));
extern int getdtsize __P((void));
@@ -2713,14 +2751,6 @@ extern int getla __P((void));
extern char *getmodifiers __P((char *, BITMAP256));
extern BITMAP256 *getrequests __P((ENVELOPE *));
extern char *getvendor __P((int));
-#if _FFR_TLS_SE_OPTS && STARTTLS
-# ifndef TLS_VRFY_PER_CTX
-# define TLS_VRFY_PER_CTX 1
-# endif
-extern int get_tls_se_options __P((ENVELOPE *, SSL *, bool));
-#else
-# define get_tls_se_options(e, s, w) 0
-#endif
extern void help __P((char *, ENVELOPE *));
extern void init_md __P((int, char **));
extern void initdaemon __P((void));
@@ -2731,9 +2761,6 @@ extern void init_vendor_macros __P((ENVELOPE *));
extern SIGFUNC_DECL intsig __P((int));
extern bool isatom __P((const char *));
extern bool isloopback __P((SOCKADDR sa));
-#if _FFR_TLS_SE_OPTS && STARTTLS
-extern bool load_certkey __P((SSL *, bool, char *, char *));
-#endif
extern void load_if_names __P((void));
extern bool lockfile __P((int, char *, char *, int));
extern void log_sendmail_pid __P((ENVELOPE *));
@@ -2741,7 +2768,11 @@ extern void logundelrcpts __P((ENVELOPE *, char *, int, bool));
extern char lower __P((int));
extern void makelower __P((char *));
extern int makeconnection_ds __P((char *, MCI *));
+#if DANE
+extern int makeconnection __P((char *, volatile unsigned int, MCI *, ENVELOPE *, time_t, unsigned long *));
+#else
extern int makeconnection __P((char *, volatile unsigned int, MCI *, ENVELOPE *, time_t));
+#endif
extern void makeworkgroups __P((void));
extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int, bool));
extern void mark_work_group_restart __P((int, int));
@@ -2751,7 +2782,7 @@ 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 */
+#endif
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));
@@ -2813,7 +2844,7 @@ extern bool strcontainedin __P((bool, char *, char *));
extern int switch_map_find __P((char *, char *[], short []));
#if STARTTLS
extern void tls_set_verify __P((SSL_CTX *, SSL *, bool));
-#endif /* STARTTLS */
+#endif
extern bool transienterror __P((int));
extern void truncate_at_delim __P((char *, size_t, int));
extern void tTflag __P((char *));
@@ -2823,7 +2854,7 @@ extern char *ttypath __P((void));
extern void unlockqueue __P((ENVELOPE *));
#if !HASUNSETENV
extern void unsetenv __P((char *));
-#endif /* !HASUNSETENV */
+#endif
/* update file system information: +/- some blocks */
#if SM_CONF_SHM
@@ -2843,18 +2874,22 @@ extern bool writable __P((char *, ADDRESS *, long));
#if SM_HEAP_CHECK
# define xalloc(size) xalloc_tagged(size, __FILE__, __LINE__)
extern char *xalloc_tagged __P((int, char *, int));
-#else /* SM_HEAP_CHECK */
+#else
extern char *xalloc __P((int));
#endif /* SM_HEAP_CHECK */
#if _FFR_XCNCT
extern int xconnect __P((SM_FILE_T *));
-#endif /* _FFR_XCNCT */
+#endif
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 *));
extern char *xuntextify __P((char *));
+#if _FFR_EAI
+extern bool addr_is_ascii __P((const char *));
+#endif
+
#if _FFR_RCPTFLAGS
extern bool newmodmailer __P((ADDRESS *, int));
#endif
diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c
index 5209dfa1c3b2..3335608e450c 100644
--- a/contrib/sendmail/src/sfsasl.c
+++ b/contrib/sendmail/src/sfsasl.c
@@ -19,7 +19,7 @@ SM_RCSID("@(#)$Id: sfsasl.c,v 8.121 2013-11-22 20:51:56 ca Exp $")
/* allow to disable error handling code just in case... */
#ifndef DEAL_WITH_ERROR_SSL
# define DEAL_WITH_ERROR_SSL 1
-#endif /* ! DEAL_WITH_ERROR_SSL */
+#endif
#if SASL
# include "sfsasl.h"
@@ -66,7 +66,7 @@ sasl_getinfo(fp, what, valp)
case SM_IO_WHAT_FD:
if (so->fp == NULL)
return -1;
- return so->fp->f_file; /* for stdio fileno() compatability */
+ return so->fp->f_file; /* for stdio fileno() compatibility */
case SM_IO_IS_READABLE:
if (so->fp == NULL)
@@ -193,9 +193,9 @@ sasl_read(fp, buf, size)
ssize_t len;
# if SASL >= 20000
static const char *outbuf = NULL;
-# else /* SASL >= 20000 */
+# else
static char *outbuf = NULL;
-# endif /* SASL >= 20000 */
+# endif
static unsigned int outlen = 0;
static unsigned int offset = 0;
struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
@@ -214,9 +214,9 @@ sasl_read(fp, buf, size)
# if SASL >= 20000
while (outlen == 0)
-# else /* SASL >= 20000 */
+# else
while (outbuf == NULL && outlen == 0)
-# endif /* SASL >= 20000 */
+# endif
{
len = sm_io_read(so->fp, SM_TIME_DEFAULT, buf, size);
if (len <= 0)
@@ -255,7 +255,7 @@ sasl_read(fp, buf, size)
(void) memcpy(buf, outbuf + offset, (size_t) len);
# if SASL < 20000
SASL_DEALLOC(outbuf);
-# endif /* SASL < 20000 */
+# endif
outbuf = NULL;
offset = 0;
outlen = 0;
@@ -287,9 +287,9 @@ sasl_write(fp, buf, size)
int result;
# if SASL >= 20000
const char *outbuf;
-# else /* SASL >= 20000 */
+# else
char *outbuf;
-# endif /* SASL >= 20000 */
+# endif
unsigned int outlen, *maxencode;
size_t ret = 0, total = 0;
struct sasl_obj *so = (struct sasl_obj *) fp->f_cookie;
@@ -299,7 +299,7 @@ sasl_write(fp, buf, size)
** This can be less than the size set in attemptauth()
** due to a negotiation with the other side, e.g.,
** Cyrus IMAP lmtp program sets maxbuf=4096,
- ** digestmd5 substracts 25 and hence we'll get 4071
+ ** digestmd5 subtracts 25 and hence we'll get 4071
** instead of 8192 (MAXOUTLEN).
** Hack (for now): simply reduce the size, callers are (must be)
** able to deal with that and invoke sasl_write() again with
@@ -339,7 +339,7 @@ sasl_write(fp, buf, size)
}
# if SASL < 20000
SASL_DEALLOC(outbuf);
-# endif /* SASL < 20000 */
+# endif
}
return size;
}
@@ -416,6 +416,7 @@ sfdcsasl(fin, fout, conn, tmo)
#if STARTTLS
# include "sfsasl.h"
+# include <tls.h>
# include <openssl/err.h>
/* Structure used by the "tls" file type */
@@ -461,7 +462,7 @@ tls_getinfo(fp, what, valp)
case SM_IO_WHAT_FD:
if (so->fp == NULL)
return -1;
- return so->fp->f_file; /* for stdio fileno() compatability */
+ return so->fp->f_file; /* for stdio fileno() compatibility */
case SM_IO_IS_READABLE:
return SSL_pending(so->con) > 0;
@@ -627,8 +628,7 @@ tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=%s, error: fd %d/%d too large",
where, rfd, wfd);
- if (LogLevel > 8)
- tlslogerr(LOG_WARNING, where);
+ tlslogerr(LOG_WARNING, 8, where);
}
errno = EINVAL;
}
@@ -674,9 +674,9 @@ tls_retry(ssl, rfd, wfd, tlsstart, timeout, err, where)
/* errno to force refill() etc to stop (see IS_IO_ERROR()) */
#ifdef ETIMEDOUT
# define SM_ERR_TIMEOUT ETIMEDOUT
-#else /* ETIMEDOUT */
+#else
# define SM_ERR_TIMEOUT EIO
-#endif /* ETIMEDOUT */
+#endif
/*
** SET_TLS_RD_TMO -- read secured information for the caller
@@ -768,15 +768,12 @@ tls_read(fp, buf, size)
if (r == 0 && errno == 0) /* out of protocol EOF found */
break;
err = "syscall error";
-/*
- get_last_socket_error());
-*/
break;
case SSL_ERROR_SSL:
#if DEAL_WITH_ERROR_SSL
if (r == 0 && errno == 0) /* out of protocol EOF found */
break;
-#endif /* DEAL_WITH_ERROR_SSL */
+#endif
err = "generic SSL error";
if (LogLevel > 9)
@@ -787,14 +784,14 @@ tls_read(fp, buf, size)
pri = LOG_DEBUG;
else
pri = LOG_WARNING;
- tlslogerr(pri, "read");
+ tlslogerr(pri, 9, "read");
}
#if DEAL_WITH_ERROR_SSL
/* avoid repeated calls? */
if (r == 0)
r = -1;
-#endif /* DEAL_WITH_ERROR_SSL */
+#endif
break;
}
if (err != NULL)
@@ -893,23 +890,19 @@ tls_write(fp, buf, size)
if (r == 0 && errno == 0) /* out of protocol EOF found */
break;
err = "syscall error";
-/*
- get_last_socket_error());
-*/
break;
case SSL_ERROR_SSL:
err = "generic SSL error";
/*
ERR_GET_REASON(ERR_peek_error()));
*/
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, "write");
+ tlslogerr(LOG_WARNING, 9, "write");
#if DEAL_WITH_ERROR_SSL
/* avoid repeated calls? */
if (r == 0)
r = -1;
-#endif /* DEAL_WITH_ERROR_SSL */
+#endif
break;
}
if (err != NULL)
diff --git a/contrib/sendmail/src/sfsasl.h b/contrib/sendmail/src/sfsasl.h
index a53ed9d69f38..51e59647b0b8 100644
--- a/contrib/sendmail/src/sfsasl.h
+++ b/contrib/sendmail/src/sfsasl.h
@@ -14,12 +14,12 @@
# if SASL
extern int sfdcsasl __P((SM_FILE_T **, SM_FILE_T **, sasl_conn_t *, int));
-# endif /* SASL */
+# endif
# if STARTTLS
extern int tls_retry __P((SSL *, int, int, time_t, int, int,
const char *));
extern int sfdctls __P((SM_FILE_T **, SM_FILE_T **, SSL *));
-# endif /* STARTTLS */
+# endif
#endif /* ! SFSASL_H */
diff --git a/contrib/sendmail/src/sm_resolve.c b/contrib/sendmail/src/sm_resolve.c
index 8ec2cb68e6bf..79e4168715a3 100644
--- a/contrib/sendmail/src/sm_resolve.c
+++ b/contrib/sendmail/src/sm_resolve.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2004, 2010 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 2000-2004, 2010, 2015, 2020 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -42,14 +42,17 @@
*/
#include <sendmail.h>
-#if DNSMAP
+#if DNSMAP || DANE
# if NAMED_BIND
# if NETINET
# include <netinet/in_systm.h>
# include <netinet/ip.h>
-# endif /* NETINET */
+# endif
+# define _DEFINE_SMR_GLOBALS 1
# include "sm_resolve.h"
+#include <arpa/inet.h>
+
SM_RCSID("$Id: sm_resolve.c,v 8.40 2013-11-22 20:51:56 ca Exp $")
static struct stot
@@ -60,10 +63,10 @@ static struct stot
{
# if NETINET
{ "A", T_A },
-# endif /* NETINET */
+# endif
# if NETINET6
{ "AAAA", T_AAAA },
-# endif /* NETINET6 */
+# endif
{ "NS", T_NS },
{ "CNAME", T_CNAME },
{ "PTR", T_PTR },
@@ -71,10 +74,24 @@ static struct stot
{ "TXT", T_TXT },
{ "AFSDB", T_AFSDB },
{ "SRV", T_SRV },
+# ifdef T_DS
+ { "DS", T_DS },
+# endif
+ { "RRSIG", T_RRSIG },
+# ifdef T_NSEC
+ { "NSEC", T_NSEC },
+# endif
+# ifdef T_DNSKEY
+ { "DNSKEY", T_DNSKEY },
+# endif
+ { "TLSA", T_TLSA },
{ NULL, 0 }
};
-static DNS_REPLY_T *parse_dns_reply __P((unsigned char *, int));
+static DNS_REPLY_T *parse_dns_reply __P((unsigned char *, int, unsigned int));
+# if DNSSEC_TEST && defined(T_TLSA)
+static char *hex2bin __P((const char *, int));
+# endif
/*
** DNS_STRING_TO_TYPE -- convert resource record name into type
@@ -126,21 +143,23 @@ dns_type_to_string(type)
** DNS_FREE_DATA -- free all components of a DNS_REPLY_T
**
** Parameters:
-** r -- pointer to DNS_REPLY_T
+** dr -- pointer to DNS_REPLY_T
**
** Returns:
** none.
*/
void
-dns_free_data(r)
- DNS_REPLY_T *r;
+dns_free_data(dr)
+ DNS_REPLY_T *dr;
{
RESOURCE_RECORD_T *rr;
- if (r->dns_r_q.dns_q_domain != NULL)
- sm_free(r->dns_r_q.dns_q_domain);
- for (rr = r->dns_r_head; rr != NULL; )
+ if (dr == NULL)
+ return;
+ if (dr->dns_r_q.dns_q_domain != NULL)
+ sm_free(dr->dns_r_q.dns_q_domain);
+ for (rr = dr->dns_r_head; rr != NULL; )
{
RESOURCE_RECORD_T *tmp = rr;
@@ -151,7 +170,59 @@ dns_free_data(r)
rr = rr->rr_next;
sm_free(tmp);
}
- sm_free(r);
+ sm_free(dr);
+}
+
+/*
+** BIN2HEX -- convert binary TLSA RR to hex string
+**
+** Parameters:
+** tlsa -- pointer to result (allocated here)
+** p -- binary data (TLSA RR)
+** size -- length of p
+** min_size -- minimum expected size
+**
+** Returns:
+** >0: length of string (*tlsa)
+** -1: error
+*/
+
+static int bin2hex __P((char **, unsigned char *, int, int));
+
+static int
+bin2hex(tlsa, p, size, min_size)
+ char **tlsa;
+ unsigned char *p;
+ int size;
+ int min_size;
+{
+ int i, pos, txtlen;
+
+ txtlen = size * 3;
+ if (txtlen <= size || size < min_size)
+ {
+ if (LogLevel > 5)
+ sm_syslog(LOG_WARNING, NOQID,
+ "ERROR: bin2hex: size %d wrong", size);
+ return -1;
+ }
+ *tlsa = (char *) sm_malloc(txtlen);
+ if (*tlsa == NULL)
+ {
+ if (tTd(8, 17))
+ sm_dprintf("len=%d, rr_data=NULL\n", txtlen);
+ return -1;
+ }
+ snprintf(*tlsa, txtlen,
+ "%02X %02X %02X", p[0], p[1], p[2]);
+ pos = strlen(*tlsa);
+
+ /* why isn't there a print function like strlcat? */
+ for (i = 3; i < size && pos < txtlen; i++, pos += 3)
+ snprintf(*tlsa + pos, txtlen - pos, "%c%02X",
+ (i == 3) ? ' ' : ':', p[i]);
+
+ return i;
}
/*
@@ -160,54 +231,72 @@ dns_free_data(r)
** Parameters:
** data -- pointer to dns data
** len -- len of data
+** flags -- flags (RR_*)
**
** Returns:
** pointer to DNS_REPLY_T if succeeded.
** NULL otherwise.
+**
+** Note:
+** use dns_free_data() to free() the result when no longer needed.
*/
static DNS_REPLY_T *
-parse_dns_reply(data, len)
+parse_dns_reply(data, len, flags)
unsigned char *data;
int len;
+ unsigned int flags;
{
unsigned char *p;
unsigned short ans_cnt, ui;
int status;
size_t l;
char host[MAXHOSTNAMELEN];
- DNS_REPLY_T *r;
+ DNS_REPLY_T *dr;
RESOURCE_RECORD_T **rr;
- r = (DNS_REPLY_T *) sm_malloc(sizeof(*r));
- if (r == NULL)
+ if (tTd(8, 90))
+ {
+ FILE *fp;
+
+ fp = fopen("dns.buffer", "w");
+ if (fp != NULL)
+ {
+ fwrite(data, 1, len, fp);
+ fclose(fp);
+ fp = NULL;
+ }
+ else
+ sm_dprintf("parse_dns_reply: fp=%p, e=%d\n",
+ (void *)fp, errno);
+ }
+
+ dr = (DNS_REPLY_T *) sm_malloc(sizeof(*dr));
+ if (dr == NULL)
return NULL;
- memset(r, 0, sizeof(*r));
+ memset(dr, 0, sizeof(*dr));
p = data;
/* doesn't work on Crays? */
- memcpy(&r->dns_r_h, p, sizeof(r->dns_r_h));
- p += sizeof(r->dns_r_h);
+ memcpy(&dr->dns_r_h, p, sizeof(dr->dns_r_h));
+ p += sizeof(dr->dns_r_h);
status = dn_expand(data, data + len, p, host, sizeof(host));
if (status < 0)
- {
- dns_free_data(r);
- return NULL;
- }
- r->dns_r_q.dns_q_domain = sm_strdup(host);
- if (r->dns_r_q.dns_q_domain == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
+ dr->dns_r_q.dns_q_domain = sm_strdup(host);
+ if (dr->dns_r_q.dns_q_domain == NULL)
+ goto error;
- ans_cnt = ntohs((unsigned short) r->dns_r_h.ancount);
+ ans_cnt = ntohs((unsigned short) dr->dns_r_h.ancount);
+ if (tTd(8, 17))
+ sm_dprintf("parse_dns_reply: ac=%d, ad=%d\n", ans_cnt,
+ dr->dns_r_h.ad);
p += status;
- GETSHORT(r->dns_r_q.dns_q_type, p);
- GETSHORT(r->dns_r_q.dns_q_class, p);
- rr = &r->dns_r_head;
+ GETSHORT(dr->dns_r_q.dns_q_type, p);
+ GETSHORT(dr->dns_r_q.dns_q_class, p);
+ rr = &dr->dns_r_head;
ui = 0;
while (p < data + len && ui < ans_cnt)
{
@@ -215,10 +304,7 @@ parse_dns_reply(data, len)
status = dn_expand(data, data + len, p, host, sizeof(host));
if (status < 0)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
++ui;
p += status;
GETSHORT(type, p);
@@ -236,22 +322,15 @@ parse_dns_reply(data, len)
sm_syslog(LOG_WARNING, NOQID,
"ERROR: DNS RDLENGTH=%d > data len=%d",
size, len - (int)(p - data));
- dns_free_data(r);
- return NULL;
+ goto error;
}
*rr = (RESOURCE_RECORD_T *) sm_malloc(sizeof(**rr));
if (*rr == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
memset(*rr, 0, sizeof(**rr));
(*rr)->rr_domain = sm_strdup(host);
if ((*rr)->rr_domain == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
(*rr)->rr_type = type;
(*rr)->rr_class = class;
(*rr)->rr_ttl = ttl;
@@ -264,16 +343,13 @@ parse_dns_reply(data, len)
status = dn_expand(data, data + len, p, host,
sizeof(host));
if (status < 0)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
+ if (tTd(8, 50))
+ sm_dprintf("parse_dns_reply: type=%s, host=%s\n",
+ dns_type_to_string(type), host);
(*rr)->rr_u.rr_txt = sm_strdup(host);
if ((*rr)->rr_u.rr_txt == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
break;
case T_MX:
@@ -281,39 +357,30 @@ parse_dns_reply(data, len)
status = dn_expand(data, data + len, p + 2, host,
sizeof(host));
if (status < 0)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
l = strlen(host) + 1;
(*rr)->rr_u.rr_mx = (MX_RECORD_T *)
sm_malloc(sizeof(*((*rr)->rr_u.rr_mx)) + l);
if ((*rr)->rr_u.rr_mx == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
(*rr)->rr_u.rr_mx->mx_r_preference = (p[0] << 8) | p[1];
(void) sm_strlcpy((*rr)->rr_u.rr_mx->mx_r_domain,
host, l);
+ if (tTd(8, 50))
+ sm_dprintf("mx=%s, pref=%d\n", host,
+ (*rr)->rr_u.rr_mx->mx_r_preference);
break;
case T_SRV:
status = dn_expand(data, data + len, p + 6, host,
sizeof(host));
if (status < 0)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
l = strlen(host) + 1;
(*rr)->rr_u.rr_srv = (SRV_RECORDT_T*)
sm_malloc(sizeof(*((*rr)->rr_u.rr_srv)) + l);
if ((*rr)->rr_u.rr_srv == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
(*rr)->rr_u.rr_srv->srv_r_priority = (p[0] << 8) | p[1];
(*rr)->rr_u.rr_srv->srv_r_weight = (p[2] << 8) | p[3];
(*rr)->rr_u.rr_srv->srv_r_port = (p[4] << 8) | p[5];
@@ -340,38 +407,850 @@ parse_dns_reply(data, len)
sm_syslog(LOG_WARNING, NOQID,
"ERROR: DNS TXT record size=%d <= text len=%d",
size, txtlen);
- dns_free_data(r);
- return NULL;
+ goto error;
}
(*rr)->rr_u.rr_txt = (char *) sm_malloc(txtlen + 1);
if ((*rr)->rr_u.rr_txt == NULL)
- {
- dns_free_data(r);
- return NULL;
- }
+ goto error;
(void) sm_strlcpy((*rr)->rr_u.rr_txt, (char*) p + 1,
txtlen + 1);
break;
+# ifdef T_TLSA
+ case T_TLSA:
+ if (tTd(8, 61))
+ sm_dprintf("parse_dns_reply: TLSA, size=%d, flags=%X\n",
+ size, flags);
+ if ((flags & RR_AS_TEXT) != 0)
+ {
+ txtlen = bin2hex((char **)&((*rr)->rr_u.rr_data),
+ p, size, 4);
+ if (txtlen <= 0)
+ goto error;
+ break;
+ }
+ /* FALLTHROUGH */
+ /* return "raw" data for caller to use as it pleases */
+# endif /* T_TLSA */
+
default:
(*rr)->rr_u.rr_data = (unsigned char*) sm_malloc(size);
if ((*rr)->rr_u.rr_data == NULL)
+ goto error;
+ (void) memcpy((*rr)->rr_u.rr_data, p, size);
+ if (tTd(8, 61) && type == T_A)
{
- dns_free_data(r);
- return NULL;
+ SOCKADDR addr;
+
+ (void) memcpy((void *)&addr.sin.sin_addr.s_addr, p, size);
+ sm_dprintf("parse_dns_reply: IPv4=%s\n",
+ inet_ntoa(addr.sin.sin_addr));
}
- (void) memcpy((*rr)->rr_u.rr_data, p, size);
break;
}
p += size;
rr = &(*rr)->rr_next;
}
*rr = NULL;
- return r;
+ return dr;
+
+ error:
+ dns_free_data(dr);
+ return NULL;
+}
+
+# if DNSSEC_TEST
+
+#include <arpa/nameser.h>
+
+static int gen_dns_reply __P((unsigned char *, int, unsigned char *,
+ const char *, int, const char *, int, int, int, int,
+ const char *, int, int, int));
+static int dnscrtrr __P((const char *, const char *, int, char *, int,
+ unsigned int, int *, int *, unsigned char *, int, unsigned char *));
+
+/*
+** HERRNO2TXT -- return error text for h_errno
+**
+** Parameters:
+** e -- h_errno
+**
+** Returns:
+** DNS error text if available
+*/
+
+const char *
+herrno2txt(e)
+ int e;
+{
+ switch (e)
+ {
+ case NETDB_INTERNAL:
+ return "see errno";
+ case NETDB_SUCCESS:
+ return "OK";
+ case HOST_NOT_FOUND:
+ return "HOST_NOT_FOUND";
+ case TRY_AGAIN:
+ return "TRY_AGAIN";
+ case NO_RECOVERY:
+ return "NO_RECOVERY";
+ case NO_DATA:
+ return "NO_DATA";
+ }
+ return "bogus h_errno";
}
/*
-** DNS_LOOKUP_INT -- perform dns map lookup (internal helper routine)
+** GEN_DNS_REPLY -- generate DNS reply data.
+**
+** Parameters:
+** buf -- buffer to which DNS data is written
+** buflen -- length of buffer
+** bufpos -- position in buffer where DNS RRs are appended
+** query -- name of query
+** qtype -- resource record type of query
+** domain -- name of domain which has been "found"
+** class -- resource record class
+** type -- resource record type
+** ttl -- TTL
+** size -- size of data
+** data -- data
+** txtlen -- length of text
+** pref -- MX preference
+** ad -- ad flag
+**
+** Returns:
+** >0 length of buffer that has been used.
+** <0 error
+*/
+
+static int
+gen_dns_reply(buf, buflen, bufpos, query, qtype, domain, class, type, ttl, size, data, txtlen, pref, ad)
+ unsigned char *buf;
+ int buflen;
+ unsigned char *bufpos;
+ const char *query;
+ int qtype;
+ const char *domain;
+ int class;
+ int type;
+ int ttl;
+ int size;
+ const char *data;
+ int txtlen;
+ int pref;
+ int ad;
+{
+ unsigned short ans_cnt;
+ HEADER *hp;
+ unsigned char *cp, *ep;
+ int n;
+ static unsigned char *dnptrs[20], **dpp, **lastdnptr;
+
+ SM_REQUIRE(NULL != buf);
+ SM_REQUIRE(buflen >= HFIXEDSZ);
+ SM_REQUIRE(query != NULL);
+ hp = (HEADER *) buf;
+ ep = buf + buflen;
+ cp = buf + HFIXEDSZ;
+
+ if (bufpos != NULL)
+ cp = bufpos;
+ else
+ {
+ sm_dprintf("gen_dns_reply: query=%s, domain=%s, type=%s, size=%d, ad=%d\n",
+ query, domain, dns_type_to_string(type), size, ad);
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
+
+ memset(buf, 0, HFIXEDSZ);
+ hp->id = 0xdead; /* HACK */
+ hp->qr = 1;
+ hp->opcode = QUERY;
+ hp->rd = 0; /* recursion desired? */
+ hp->rcode = 0; /* !!! */
+ /* hp->aa = ?; * !!! */
+ /* hp->tc = ?; * !!! */
+ /* hp->ra = ?; * !!! */
+ hp->qdcount = htons(1);
+ hp->ancount = 0;
+
+ n = dn_comp(query, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr);
+ if (n < 0)
+ return n;
+ cp += n;
+ PUTSHORT(qtype, cp);
+ PUTSHORT(class, cp);
+ }
+ hp->ad = ad;
+
+ if (ep - cp < QFIXEDSZ)
+ return (-1);
+ n = dn_comp(domain, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr);
+ if (n < 0)
+ return n;
+ cp += n;
+ PUTSHORT(type, cp);
+ PUTSHORT(class, cp);
+ PUTLONG(ttl, cp);
+
+ ans_cnt = ntohs((unsigned short) hp->ancount);
+ ++ans_cnt;
+ hp->ancount = htons((unsigned short) ans_cnt);
+
+ switch (type)
+ {
+ case T_MX:
+ n = dn_comp(data, cp + 4, ep - cp - QFIXEDSZ, dnptrs, lastdnptr);
+ if (n < 0)
+ return n;
+ PUTSHORT(n + 2, cp);
+ PUTSHORT(pref, cp);
+ cp += n;
+ break;
+
+ case T_TXT:
+ if (txtlen >= size)
+ return -1;
+ PUTSHORT(txtlen, cp);
+ (void) sm_strlcpy((char *)cp, data, txtlen + 1);
+ cp += txtlen;
+ break;
+
+ case T_CNAME:
+ n = dn_comp(data, cp + 2, ep - cp - QFIXEDSZ, dnptrs, lastdnptr);
+ if (n < 0)
+ return n;
+ PUTSHORT(n, cp);
+ cp += n;
+ break;
+
+# if defined(T_TLSA)
+ case T_TLSA:
+ {
+ char *tlsa;
+
+ tlsa = hex2bin(data, size);
+ if (tlsa == NULL)
+ return (-1);
+ n = size / 2;
+ PUTSHORT(n, cp);
+ (void) memcpy(cp, tlsa, n);
+ cp += n;
+ }
+ break;
+# endif /* T_TLSA */
+
+ default:
+ PUTSHORT(size, cp);
+ (void) memcpy(cp, data, size);
+ cp += size;
+ break;
+ }
+
+ return (cp - buf);
+}
+
+/*
+** SETHERRNOFROMSTRING -- set h_errno based on text
+**
+** Parameters:
+** str -- string which might contain h_errno text
+** prc -- pointer to rcode (EX_*)
+**
+** Returns:
+** h_errno if found
+** 0 otherwise
+*/
+
+int
+setherrnofromstring(str, prc)
+ const char *str;
+ int *prc;
+{
+ SM_SET_H_ERRNO(0);
+ if (str == NULL || *str == '\0')
+ return 0;
+ if (strstr(str, "herrno:") == NULL)
+ return 0;
+ if (prc != NULL)
+ *prc = EX_NOHOST;
+ if (strstr(str, "host_not_found"))
+ SM_SET_H_ERRNO(HOST_NOT_FOUND);
+ else if (strstr(str, "try_again"))
+ {
+ SM_SET_H_ERRNO(TRY_AGAIN);
+ if (prc != NULL)
+ *prc = EX_TEMPFAIL;
+ }
+ else if (strstr(str, "no_recovery"))
+ SM_SET_H_ERRNO(NO_RECOVERY);
+ else if (strstr(str, "no_data"))
+ SM_SET_H_ERRNO(NO_DATA);
+ else
+ SM_SET_H_ERRNO(NETDB_INTERNAL);
+ return h_errno;
+}
+
+/*
+** GETTTLFROMSTRING -- extract ttl from a string
+**
+** Parameters:
+** str -- string which might contain ttl
+**
+** Returns:
+** ttl if found
+** 0 otherwise
+*/
+
+int
+getttlfromstring(str)
+ const char *str;
+{
+ if (str == NULL || *str == '\0')
+ return 0;
+#define TTL_PRE "ttl="
+ if (strstr(str, TTL_PRE) == NULL)
+ return 0;
+ return strtoul(str + strlen(TTL_PRE), NULL, 10);
+}
+
+/*
+** NSPORTIP -- parse port@IPv4 and set NS accordingly
+**
+** Parameters:
+** p -- port@Ipv4
+**
+** Returns:
+** <0: error
+** >0: ok
+**
+** Side Effects:
+** sets NS for DNS lookups
+*/
+
+/*
+** There should be a generic function for this...
+** milter_open(), socket_map_open(), others?
+*/
+
+int
+nsportip(p)
+ char *p;
+{
+ char *h;
+ int r;
+ unsigned short port;
+ struct in_addr nsip;
+
+ if (p == NULL || *p == '\0')
+ return -1;
+
+ port = 0;
+ while (SM_ISSPACE(*p))
+ p++;
+ if (*p == '\0')
+ return -1;
+ h = strchr(p, '@');
+ if (h != NULL)
+ {
+ *h = '\0';
+ if (isascii(*p) && isdigit(*p))
+ port = atoi(p);
+ *h = '@';
+ p = h + 1;
+ }
+ h = strchr(p, ' ');
+ if (h != NULL)
+ *h = '\0';
+ r = inet_pton(AF_INET, p, &nsip);
+ if (r > 0)
+ {
+ if ((_res.options & RES_INIT) == 0)
+ (void) res_init();
+ dns_setns(&nsip, port);
+ }
+ if (h != NULL)
+ *h = ' ';
+ return r > 0 ? 0 : -1;
+}
+
+/*
+** DNS_SETNS -- set one NS in resolver context
+**
+** Parameters:
+** ns -- (IPv4 address of) nameserver
+** port -- nameserver port
+**
+** Returns:
+** None.
+*/
+
+void
+dns_setns(ns, port)
+ struct in_addr *ns;
+ unsigned int port;
+{
+ _res.nsaddr_list[0].sin_family = AF_INET;
+ _res.nsaddr_list[0].sin_addr = *ns;
+ if (port != 0)
+ _res.nsaddr_list[0].sin_port = htons(port);
+ _res.nscount = 1;
+ if (tTd(8, 61))
+ sm_dprintf("dns_setns(%s,%u)\n", inet_ntoa(*ns), port);
+}
+
+# if defined(T_TLSA)
+/*
+** HEX2BIN -- convert hex string to binary TLSA RR
+**
+** Parameters:
+** p -- hex representation of TLSA RR
+** size -- length of p
+**
+** Returns:
+** pointer to binary TLSA RR
+** NULL: error
+*/
+
+static char *
+hex2bin(p, size)
+ const char *p;
+ int size;
+{
+ int i, pos, txtlen;
+ char *tlsa;
+
+ txtlen = size / 2;
+ if (txtlen * 2 == size)
+ {
+ if (LogLevel > 5)
+ sm_syslog(LOG_WARNING, NOQID,
+ "ERROR: hex2bin: size %d wrong", size);
+ return NULL;
+ }
+ tlsa = sm_malloc(txtlen + 1);
+ if (tlsa == NULL)
+ {
+ if (tTd(8, 17))
+ sm_dprintf("len=%d, tlsa=NULL\n", txtlen);
+ return NULL;
+ }
+
+#define CHAR2INT(c) (((c) <= '9') ? ((c) - '0') : (toupper(c) - 'A' + 10))
+ for (i = 0, pos = 0; i + 1 < size && pos < txtlen; i += 2, pos++)
+ tlsa[pos] = CHAR2INT(p[i]) * 16 + CHAR2INT(p[i+1]);
+
+ return tlsa;
+}
+# endif /* T_TLSA */
+
+const char *
+rr_type2tag(rr_type)
+ int rr_type;
+{
+ switch (rr_type)
+ {
+ case T_A:
+ return "ipv4";
+# if NETINET6
+ case T_AAAA:
+ return "ipv6";
+# endif
+ case T_CNAME:
+ return "cname";
+ case T_MX:
+ return "mx";
+# ifdef T_TLSA
+ case T_TLSA:
+ return "tlsa";
+# endif
+ }
+ return NULL;
+}
+
+/*
+** DNSCRTRR -- create DNS RR
+**
+** Parameters:
+** domain -- original query domain
+** query -- name of query
+** qtype -- resource record type of query
+** value -- (list of) data to set
+** rr_type -- resource record type
+** flags -- flags how to handle various lookups
+** herr -- (pointer to) h_errno (output if non-NULL)
+** adp -- (pointer to) ad flag
+** answer -- buffer for RRs
+** anslen -- size of answer
+** anspos -- current position in answer
+**
+** Returns:
+** >0: length of data in answer
+** <0: error, check *herr
+*/
+
+static int
+dnscrtrr(domain, query, qtype, value, rr_type, flags, herr, adp, answer, anslen, anspos)
+ const char *domain;
+ const char *query;
+ int qtype;
+ char *value;
+ int rr_type;
+ unsigned int flags;
+ int *herr;
+ int *adp;
+ unsigned char *answer;
+ int anslen;
+ unsigned char *anspos;
+{
+ SOCKADDR addr;
+ int ttl, ad, rlen;
+ char *p, *token;
+ char data[IN6ADDRSZ];
+ char rhs[MAXLINE];
+
+ rlen = -1;
+ if (NULL == value || '\0' == *value)
+ return rlen;
+ SM_REQUIRE(adp != NULL);
+ (void) sm_strlcpy(rhs, value, sizeof(rhs));
+ p = rhs;
+ if (setherrnofromstring(p, NULL) != 0)
+ {
+ if (herr != NULL)
+ *herr = h_errno;
+ if (tTd(8, 16))
+ sm_dprintf("dnscrtrr rhs=%s h_errno=%d (%s)\n",
+ p, h_errno, herrno2txt(h_errno));
+ return rlen;
+ }
+
+ ttl = 0;
+ ad = 0;
+ for (token = p; token != NULL && *token != '\0'; token = p)
+ {
+ rlen = 0;
+ while (p != NULL && *p != '\0' && !SM_ISSPACE(*p))
+ ++p;
+ if (SM_ISSPACE(*p))
+ *p++ = '\0';
+ sm_dprintf("dnscrtrr: token=%s\n", token);
+ if (strcmp(token, "ad") == 0)
+ {
+ bool adflag;
+
+ adflag = (_res.options & RES_USE_DNSSEC) != 0;
+
+ /* maybe print this only for the final RR? */
+ if (tTd(8, 61))
+ sm_dprintf("dnscrtrr: ad=1, adp=%d, adflag=%d\n",
+ *adp, adflag);
+ if (*adp != 0 && adflag)
+ {
+ *adp = 1;
+ ad = 1;
+ }
+ continue;
+ }
+ if (ttl == 0 && (ttl = getttlfromstring(token)) > 0)
+ {
+ if (tTd(8, 61))
+ sm_dprintf("dnscrtrr: ttl=%d\n", ttl);
+ continue;
+ }
+
+ if (rr_type == T_A)
+ {
+ addr.sin.sin_addr.s_addr = inet_addr(token);
+ (void) memmove(data, (void *)&addr.sin.sin_addr.s_addr,
+ INADDRSZ);
+ rlen = gen_dns_reply(answer, anslen, anspos,
+ query, qtype, domain, C_IN, rr_type, ttl,
+ INADDRSZ, data, 0, 0, ad);
+ }
+
+# if NETINET6
+ if (rr_type == T_AAAA)
+ {
+ anynet_pton(AF_INET6, token, &addr.sin6.sin6_addr);
+ memmove(data, (void *)&addr.sin6.sin6_addr, IN6ADDRSZ);
+ rlen = gen_dns_reply(answer, anslen, anspos,
+ query, qtype, domain, C_IN, rr_type, ttl,
+ IN6ADDRSZ, data, 0, 0, ad);
+ }
+# endif /* NETINET6 */
+
+ if (rr_type == T_MX)
+ {
+ char *endptr;
+ int pref;
+
+ pref = (int) strtoul(token, &endptr, 10);
+ if (endptr == NULL || *endptr != ':')
+ goto error;
+ token = endptr + 1;
+ rlen = gen_dns_reply(answer, anslen, anspos,
+ query, qtype, domain, C_IN, rr_type, ttl,
+ strlen(token) + 1, token, 0, pref, ad);
+ if (tTd(8, 50))
+ sm_dprintf("dnscrtrr: mx=%s, pref=%d\n",
+ token, pref);
+ }
+
+# ifdef T_TLSA
+ if (rr_type == T_TLSA)
+ rlen = gen_dns_reply(answer, anslen, anspos,
+ query, qtype, domain, C_IN, rr_type, ttl,
+ strlen(token) + 1, token, 0, 0, ad);
+# endif
+
+ if (rr_type == T_CNAME)
+ rlen = gen_dns_reply(answer, anslen, anspos,
+ query, qtype, domain, C_IN, rr_type, ttl,
+ strlen(token), token, 0, 0, ad);
+ if (rlen < 0)
+ goto error;
+ if (rlen > 0)
+ anspos = answer + rlen;
+ }
+
+ if (ad != 1)
+ *adp = 0;
+
+ return rlen;
+
+ error:
+ if (herr != NULL && 0 == *herr)
+ *herr = NO_RECOVERY;
+ return -1;
+}
+
+/*
+** TSTDNS_SEARCH -- replacement for res_search() for testing
+**
+** Parameters:
+** domain -- query domain
+** class -- class
+** type -- resource record type
+** answer -- buffer for RRs
+** anslen -- size of answer
+**
+** Returns:
+** >0: length of data in answer
+** <0: error, check h_errno
+*/
+
+int
+tstdns_search(domain, class, type, answer, anslen)
+ const char *domain;
+ int class;
+ int type;
+ unsigned char *answer;
+ int anslen;
+{
+ int rlen, ad, maprcode, cnt, flags, herr;
+ bool found_cname;
+ const char *query;
+ char *p;
+ const char *tag;
+ char *av[2];
+ STAB *map;
+ char key[MAXNAME + 16];
+ char rhs[MAXLINE];
+ unsigned char *anspos;
+
+ rlen = -1;
+ herr = 0;
+ if (class != C_IN)
+ goto error;
+ if (NULL == domain || '\0' == *domain)
+ goto error;
+ tag = rr_type2tag(type);
+ if (tag == NULL)
+ goto error;
+ maprcode = EX_OK;
+ ad = -1;
+ flags = 0;
+ query = domain;
+ anspos = NULL;
+
+ map = stab("access", ST_MAP, ST_FIND);
+ if (NULL == map)
+ {
+ sm_dprintf("access map not found\n");
+ goto error;
+ }
+ if (!bitset(MF_OPEN, map->s_map.map_mflags) &&
+ !openmap(&(map->s_map)))
+ {
+ sm_dprintf("access map open failed\n");
+ goto error;
+ }
+
+/*
+** Look up tag:domain, if not found and domain does not end with a dot
+** (and the proper debug level is selected), also try with trailing dot.
+*/
+
+#define SM_LOOKUP2(tag) \
+ do { \
+ int len; \
+ \
+ len = strlen(domain); \
+ av[0] = key; \
+ av[1] = NULL; \
+ snprintf(key, sizeof(key), "%s:%s", tag, domain); \
+ p = (*map->s_map.map_class->map_lookup)(&map->s_map, key, av, \
+ &maprcode); \
+ if (p != NULL) \
+ break; \
+ if (!tTd(8, 112) || (len > 0 && '.' == domain[len - 1])) \
+ break; \
+ snprintf(key, sizeof(key), "%s:%s.", tag, domain); \
+ p = (*map->s_map.map_class->map_lookup)(&map->s_map, key, av, \
+ &maprcode); \
+ } while (0)
+
+ cnt = 0;
+ found_cname = false;
+ while (cnt < 6)
+ {
+ char *last;
+
+ /* Should this try with/without trailing dot? */
+ SM_LOOKUP2(tag);
+ if (p != NULL)
+ {
+ sm_dprintf("access map lookup key=%s, value=%s\n", key,
+ p);
+ break;
+ }
+ if (NULL == p && (flags & RR_NO_CNAME) == 0)
+ {
+ sm_dprintf("access map lookup failed key=%s, try cname\n",
+ key);
+ SM_LOOKUP2("cname");
+ if (p != NULL)
+ {
+ sm_dprintf("cname lookup key=%s, value=%s, ad=%d\n",
+ key, p, ad);
+ rlen = dnscrtrr(domain, query, type, p, T_CNAME,
+ flags, &herr, &ad, answer,
+ anslen, anspos);
+ if (rlen < 0)
+ goto error;
+ if (rlen > 0)
+ anspos = answer + rlen;
+ found_cname = true;
+ }
+ }
+ if (NULL == p)
+ break;
+
+ (void) sm_strlcpy(rhs, p, sizeof(rhs));
+ p = rhs;
+
+ /* skip (leading) ad/ttl: look for last ' ' */
+ if ((last = strrchr(p, ' ')) != NULL && last[1] != '\0')
+ domain = last + 1;
+ else
+ domain = p;
+ ++cnt;
+ }
+ if (NULL == p)
+ {
+ int t;
+ char *tags[] = { "ipv4", "mx", "tlsa",
+# if NETINET6
+ "ipv6",
+# endif
+ NULL
+ };
+
+ for (t = 0; tags[t] != NULL; t++)
+ {
+ if (strcmp(tag, tags[t]) == 0)
+ continue;
+ SM_LOOKUP2(tags[t]);
+ if (p != NULL)
+ {
+ sm_dprintf("access map lookup failed key=%s:%s, but found key=%s\n",
+ tag, domain, key);
+ herr = NO_DATA;
+ goto error;
+ }
+ }
+ sm_dprintf("access map lookup failed key=%s\n", key);
+ herr = HOST_NOT_FOUND;
+ goto error;
+ }
+ if (found_cname && (flags & RR_ONLY_CNAME) != 0)
+ return rlen;
+ rlen = dnscrtrr(domain, query, type, p, type, flags, &herr, &ad,
+ answer, anslen, anspos);
+ if (rlen < 0)
+ goto error;
+ return rlen;
+
+ error:
+ if (0 == herr)
+ herr = NO_RECOVERY;
+ SM_SET_H_ERRNO(herr);
+ sm_dprintf("rlen=%d, herr=%d\n", rlen, herr);
+ return -1;
+}
+
+/*
+** TSTDNS_QUERYDOMAIN -- replacement for res_querydomain() for testing
+**
+** Parameters:
+** name -- query name
+** domain -- query domain
+** class -- class
+** type -- resource record type
+** answer -- buffer for RRs
+** anslen -- size of answer
+**
+** Returns:
+** >0: length of data in answer
+** <0: error, check h_errno
+*/
+
+int
+tstdns_querydomain(name, domain, class, type, answer, anslen)
+ const char *name;
+ const char *domain;
+ int class;
+ int type;
+ unsigned char *answer;
+ int anslen;
+{
+ char query[MAXNAME];
+ int len;
+
+ if (NULL == name)
+ goto error;
+ if (NULL == domain || '\0' == *domain)
+ return tstdns_search(name, class, type, answer, anslen);
+
+ len = snprintf(query, sizeof(query), "%s.%s", name, domain);
+ if (len >= (int)sizeof(query))
+ goto error;
+ return tstdns_search(query, class, type, answer, anslen);
+
+ error:
+ SM_SET_H_ERRNO(NO_RECOVERY);
+ return -1;
+}
+
+# endif /* DNSSEC_TEST */
+
+/*
+** DNS_LOOKUP_INT -- perform DNS lookup
**
** Parameters:
** domain -- name to lookup
@@ -379,6 +1258,10 @@ parse_dns_reply(data, len)
** rr_type -- resource record type
** retrans -- retransmission timeout
** retry -- number of retries
+** options -- DNS resolver options
+** flags -- currently only passed to parse_dns_reply()
+** err -- (pointer to) errno (output if non-NULL)
+** herr -- (pointer to) h_errno (output if non-NULL)
**
** Returns:
** result of lookup if succeeded.
@@ -386,33 +1269,55 @@ parse_dns_reply(data, len)
*/
DNS_REPLY_T *
-dns_lookup_int(domain, rr_class, rr_type, retrans, retry)
+dns_lookup_int(domain, rr_class, rr_type, retrans, retry, options, flags, err, herr)
const char *domain;
int rr_class;
int rr_type;
time_t retrans;
int retry;
+ unsigned int options;
+ unsigned int flags;
+ int *err;
+ int *herr;
{
int len;
unsigned long old_options = 0;
time_t save_retrans = 0;
int save_retry = 0;
- DNS_REPLY_T *r = NULL;
+ DNS_REPLY_T *dr = NULL;
querybuf reply_buf;
unsigned char *reply;
+ int (*resfunc) __P((const char *, int, int, u_char *, int));
-#define SMRBSIZE sizeof(reply_buf)
-#ifndef IP_MAXPACKET
-# define IP_MAXPACKET 65535
-#endif
+# define SMRBSIZE ((int) sizeof(reply_buf))
+# ifndef IP_MAXPACKET
+# define IP_MAXPACKET 65535
+# endif
+ resfunc = res_search;
+# if DNSSEC_TEST
+ if (tTd(8, 110))
+ resfunc = tstdns_search;
+# endif
+
+ old_options = _res.options;
+ _res.options |= options;
+ if (err != NULL)
+ *err = 0;
+ if (herr != NULL)
+ *herr = 0;
if (tTd(8, 16))
{
- old_options = _res.options;
_res.options |= RES_DEBUG;
- sm_dprintf("dns_lookup(%s, %d, %s)\n", domain,
- rr_class, dns_type_to_string(rr_type));
+ sm_dprintf("dns_lookup_int(%s, %d, %s, %x)\n", domain,
+ rr_class, dns_type_to_string(rr_type), options);
}
+# if DNSSEC_TEST
+ if (tTd(8, 15))
+ sm_dprintf("NS=%s, port=%d\n",
+ inet_ntoa(_res.nsaddr_list[0].sin_addr),
+ ntohs(_res.nsaddr_list[0].sin_port));
+# endif
if (retrans > 0)
{
save_retrans = _res.retrans;
@@ -426,38 +1331,61 @@ dns_lookup_int(domain, rr_class, rr_type, retrans, retry)
errno = 0;
SM_SET_H_ERRNO(0);
reply = (unsigned char *)&reply_buf;
- len = res_search(domain, rr_class, rr_type, reply, SMRBSIZE);
+ len = (*resfunc)(domain, rr_class, rr_type, reply, SMRBSIZE);
if (len >= SMRBSIZE)
{
if (len >= IP_MAXPACKET)
{
if (tTd(8, 4))
sm_dprintf("dns_lookup: domain=%s, length=%d, default_size=%d, max=%d, status=response too long\n",
- domain, len, (int) SMRBSIZE,
- IP_MAXPACKET);
+ domain, len, SMRBSIZE, IP_MAXPACKET);
}
else
{
if (tTd(8, 6))
sm_dprintf("dns_lookup: domain=%s, length=%d, default_size=%d, max=%d, status=response longer than default size, resizing\n",
- domain, len, (int) SMRBSIZE,
- IP_MAXPACKET);
+ domain, len, SMRBSIZE, IP_MAXPACKET);
reply = (unsigned char *)sm_malloc(IP_MAXPACKET);
if (reply == NULL)
SM_SET_H_ERRNO(TRY_AGAIN);
else
- len = res_search(domain, rr_class, rr_type,
+ {
+ SM_SET_H_ERRNO(0);
+ len = (*resfunc)(domain, rr_class, rr_type,
reply, IP_MAXPACKET);
+ }
}
}
- if (tTd(8, 16))
+ _res.options = old_options;
+ if (len < 0)
+ {
+ if (err != NULL)
+ *err = errno;
+ if (herr != NULL)
+ *herr = h_errno;
+ if (tTd(8, 16))
+ {
+ sm_dprintf("dns_lookup_int(%s, %d, %s, %x)=%d, errno=%d, h_errno=%d"
+# if DNSSEC_TEST
+ " (%s)"
+# endif
+ "\n",
+ domain, rr_class, dns_type_to_string(rr_type),
+ options, len, errno, h_errno
+# if DNSSEC_TEST
+ , herrno2txt(h_errno)
+# endif
+ );
+ }
+ }
+ else if (tTd(8, 16))
{
- _res.options = old_options;
- sm_dprintf("dns_lookup(%s, %d, %s) --> %d\n",
- domain, rr_class, dns_type_to_string(rr_type), len);
+ sm_dprintf("dns_lookup_int(%s, %d, %s, %x)=%d\n",
+ domain, rr_class, dns_type_to_string(rr_type),
+ options, len);
}
if (len >= 0 && len < IP_MAXPACKET && reply != NULL)
- r = parse_dns_reply(reply, len);
+ dr = parse_dns_reply(reply, len, flags);
if (reply != (unsigned char *)&reply_buf && reply != NULL)
{
sm_free(reply);
@@ -467,29 +1395,209 @@ dns_lookup_int(domain, rr_class, rr_type, retrans, retry)
_res.retrans = save_retrans;
if (retry > 0)
_res.retry = save_retry;
- return r;
+ return dr;
}
-# if 0
+/*
+** DNS_LOOKUP_MAP -- perform DNS map lookup
+**
+** Parameters:
+** domain -- name to lookup
+** rr_class -- resource record class
+** rr_type -- resource record type
+** retrans -- retransmission timeout
+** retry -- number of retries
+** options -- DNS resolver options
+**
+** Returns:
+** result of lookup if succeeded.
+** NULL otherwise.
+*/
+
DNS_REPLY_T *
-dns_lookup(domain, type_name, retrans, retry)
+dns_lookup_map(domain, rr_class, rr_type, retrans, retry, options)
const char *domain;
- const char *type_name;
+ int rr_class;
+ int rr_type;
time_t retrans;
int retry;
+ unsigned int options;
{
- int type;
+ return dns_lookup_int(domain, rr_class, rr_type, retrans, retry,
+ options, RR_AS_TEXT, NULL, NULL);
+}
- type = dns_string_to_type(type_name);
- if (type == -1)
+# if DANE
+/*
+** DNS2HE -- convert DNS_REPLY_T list to hostent struct
+**
+** Parameters:
+** dr -- DNS lookup result
+** family -- address family
+**
+** Returns:
+** hostent struct if succeeded.
+** NULL otherwise.
+**
+** Note:
+** this returns a pointer to a static struct!
+*/
+
+struct hostent *
+dns2he(dr, family)
+ DNS_REPLY_T *dr;
+ int family;
+{
+# define SM_MAX_ADDRS 256
+ static struct hostent he;
+ static char *he_aliases[1];
+ static char *he_addr_list[SM_MAX_ADDRS];
+# ifdef IN6ADDRSZ
+# define IN_ADDRSZ IN6ADDRSZ
+# else
+# define IN_ADDRSZ INADDRSZ
+# endif
+ static char he_addrs[SM_MAX_ADDRS * IN_ADDRSZ];
+ static char he_name[MAXNAME];
+ static bool he_init = false;
+ struct hostent *h;
+ struct in_addr ia;
+ int i;
+ size_t sz;
+# if NETINET6 && DNSSEC_TEST
+ struct in6_addr ia6;
+ char buf6[INET6_ADDRSTRLEN];
+# endif
+ RESOURCE_RECORD_T *rr;
+
+ if (dr == NULL)
+ return NULL;
+
+ h = &he;
+ if (!he_init)
{
- if (tTd(8, 16))
- sm_dprintf("dns_lookup: unknown resource type: `%s'\n",
- type_name);
+ he_aliases[0] = NULL;
+ he.h_aliases = he_aliases;
+ he.h_addr_list = he_addr_list;
+ he.h_name = he_name;
+ he_init = true;
+ }
+ h->h_addrtype = family;
+
+ if (tTd(8, 17))
+ sm_dprintf("dns2he: ad=%d\n", dr->dns_r_h.ad);
+
+ /* do we want/need to copy the name? */
+ rr = dr->dns_r_head;
+ if (rr != NULL && rr->rr_domain != NULL)
+ sm_strlcpy(h->h_name, rr->rr_domain, sizeof(he_name));
+ else
+ h->h_name[0] = '\0';
+
+ sz = 0;
+# if NETINET
+ if (family == AF_INET)
+ sz = INADDRSZ;
+# endif
+# if NETINET6
+ if (family == AF_INET6)
+ sz = IN6ADDRSZ;
+# endif
+ if (sz == 0)
return NULL;
+ h->h_length = sz;
+
+ for (rr = dr->dns_r_head, i = 0; rr != NULL && i < SM_MAX_ADDRS - 1;
+ rr = rr->rr_next)
+ {
+ h->h_addr_list[i] = he_addrs + i * h->h_length;
+ switch (rr->rr_type)
+ {
+# if NETINET
+ case T_A:
+ if (family != AF_INET)
+ continue;
+ memmove(h->h_addr_list[i], rr->rr_u.rr_a, INADDRSZ);
+ ++i;
+ break;
+# endif /* NETINET */
+# if NETINET6
+ case T_AAAA:
+ if (family != AF_INET6)
+ continue;
+ memmove(h->h_addr_list[i], rr->rr_u.rr_aaaa, IN6ADDRSZ);
+ ++i;
+ break;
+# endif /* NETINET6 */
+ case T_CNAME:
+# if DNSSEC_TEST
+ if (tTd(8, 16))
+ sm_dprintf("dns2he: cname: %s ttl=%d\n",
+ rr->rr_u.rr_txt, rr->rr_ttl);
+# endif
+ break;
+ case T_MX:
+# if DNSSEC_TEST
+ if (tTd(8, 16))
+ sm_dprintf("dns2he: mx: %d %s ttl=%d\n",
+ rr->rr_u.rr_mx->mx_r_preference,
+ rr->rr_u.rr_mx->mx_r_domain,
+ rr->rr_ttl);
+# endif
+ break;
+
+# if defined(T_TLSA)
+ case T_TLSA:
+# if DNSSEC_TEST
+ if (tTd(8, 16))
+ {
+ char *tlsa;
+ int len;
+
+ len = bin2hex(&tlsa, rr->rr_u.rr_data,
+ rr->rr_size, 4);
+ if (len > 0)
+ sm_dprintf("dns2he: tlsa: %s ttl=%d\n",
+ tlsa, rr->rr_ttl);
+ }
+# endif
+ break;
+# endif /* T_TLSA */
+ }
+ }
+
+ /* complain if list is too long! */
+ SM_ASSERT(i < SM_MAX_ADDRS);
+ h->h_addr_list[i] = NULL;
+
+# if DNSSEC_TEST
+ if (tTd(8, 16))
+ {
+ for (i = 0; h->h_addr_list[i] != NULL && i < SM_MAX_ADDRS; i++)
+ {
+ char *addr;
+
+ addr = NULL;
+# if NETINET6
+ if (h->h_addrtype == AF_INET6)
+ {
+ memmove(&ia6, h->h_addr_list[i], IN6ADDRSZ);
+ addr = anynet_ntop(&ia6, buf6, sizeof(buf6));
+ }
+ else
+# endif /* NETINET6 */
+ /* "else" in #if code above */
+ {
+ memmove(&ia, h->h_addr_list[i], INADDRSZ);
+ addr = (char *) inet_ntoa(ia);
+ }
+ if (addr != NULL)
+ sm_dprintf("dns2he: addr[%d]: %s\n", i, addr);
+ }
}
- return dns_lookup_int(domain, C_IN, type, retrans, retry);
+# endif /* DNSSEC_TEST */
+ return h;
}
-# endif /* 0 */
+# endif /* DANE */
# endif /* NAMED_BIND */
-#endif /* DNSMAP */
+#endif /* DNSMAP || DANE */
diff --git a/contrib/sendmail/src/sm_resolve.h b/contrib/sendmail/src/sm_resolve.h
index 5f3fe21005b7..ffff41168944 100644
--- a/contrib/sendmail/src/sm_resolve.h
+++ b/contrib/sendmail/src/sm_resolve.h
@@ -43,7 +43,7 @@
/* $Id: sm_resolve.h,v 8.9 2013-11-22 20:51:56 ca Exp $ */
-#if DNSMAP
+#if DNSMAP || DANE
# ifndef __ROKEN_RESOLVE_H__
# define __ROKEN_RESOLVE_H__
@@ -51,16 +51,22 @@
# ifndef T_TXT
# define T_TXT 16
-# endif /* ! T_TXT */
+# endif
# ifndef T_AFSDB
# define T_AFSDB 18
-# endif /* ! T_AFSDB */
+# endif
# ifndef T_SRV
# define T_SRV 33
-# endif /* ! T_SRV */
+# endif
# ifndef T_NAPTR
# define T_NAPTR 35
-# endif /* ! T_NAPTR */
+# endif
+# ifndef T_RRSIG
+# define T_RRSIG 46
+# endif
+# ifndef T_TLSA
+# define T_TLSA 52
+# endif
typedef struct
{
@@ -101,10 +107,10 @@ struct resource_record
SRV_RECORDT_T *rr_srv;
# if NETINET
struct in_addr *rr_a;
-# endif /* NETINET */
+# endif
# if NETINET6
struct in6_addr *rr_aaaa;
-# endif /* NETINET6 */
+# endif
char *rr_txt;
} rr_u;
RESOURCE_RECORD_T *rr_next;
@@ -113,7 +119,7 @@ struct resource_record
# if !defined(T_A) && !defined(T_AAAA)
/* XXX if <arpa/nameser.h> isn't included */
typedef int HEADER; /* will never be used */
-# endif /* !defined(T_A) && !defined(T_AAAA) */
+# endif
typedef struct
{
@@ -122,15 +128,23 @@ typedef struct
RESOURCE_RECORD_T *dns_r_head;
} DNS_REPLY_T;
+#define SM_DNS_FL_EDNS0 0x01
+#define SM_DNS_FL_DNSSEC 0x02
+
+/* flags for parse_dns_reply() et.al. */
+#define RR_AS_TEXT 0x01 /* convert some RRs to text, e.g., TLSA */
+#define RR_RAW 0x02 /* return some RRs as "raw" data */
+ /* currently not used (set, but not read) */
+#define RR_NO_CNAME 0x04 /* do not try CNAME lookup */
+#define RR_ONLY_CNAME 0x08 /* if !RR_NO_CNAME" return only CNAME */
extern void dns_free_data __P((DNS_REPLY_T *));
extern int dns_string_to_type __P((const char *));
extern const char *dns_type_to_string __P((int));
-extern DNS_REPLY_T *dns_lookup_int __P((const char *,
- int,
- int,
- time_t,
- int));
+extern DNS_REPLY_T *dns_lookup_map __P((const char *, int, int, time_t,
+ int, unsigned int));
+extern DNS_REPLY_T *dns_lookup_int __P((const char *, int, int, time_t,
+ int, unsigned int, unsigned int, int *, int *));
# if 0
extern DNS_REPLY_T *dns_lookup __P((const char *domain,
const char *type_name,
@@ -138,5 +152,35 @@ extern DNS_REPLY_T *dns_lookup __P((const char *domain,
int retry));
# endif /* 0 */
+# if DANE
+struct hostent *dns2he __P((DNS_REPLY_T *, int));
+# endif
+
+/* what to do if family is not supported? add SM_ASSERT()? */
+#define FAM2T_(family) (((family) == AF_INET) ? T_A : T_AAAA)
+
+# if DNSSEC_TEST
+const char *herrno2txt __P((int));
+int setherrnofromstring __P((const char *, int *));
+int getttlfromstring __P((const char *));
+int tstdns_search __P((const char *, int, int, u_char *, int));
+int tstdns_querydomain __P((const char *, const char *, int, int, unsigned char *, int));
+
+# ifdef _DEFINE_SMR_GLOBALS
+# define SMR_EXTERN
+# else
+# define SMR_EXTERN extern
+# endif
+SMR_EXTERN char *NameSearchList;
+# undef SMR_EXTERN
+extern void dns_setns __P((struct in_addr *, unsigned int));
+extern int nsportip __P((char *));
+# endif /* DNSSEC_TEST*/
+
+#ifndef RES_TRUSTAD
+# define RES_TRUSTAD 0
+#endif
+#define SM_RES_DNSSEC (RES_USE_EDNS0|RES_USE_DNSSEC|RES_TRUSTAD)
+
# endif /* ! __ROKEN_RESOLVE_H__ */
-#endif /* DNSMAP */
+#endif /* DNSMAP || DANE */
diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c
index b05348d4b2e2..b6263079a90e 100644
--- a/contrib/sendmail/src/srvrsmtp.c
+++ b/contrib/sendmail/src/srvrsmtp.c
@@ -15,7 +15,7 @@
#if MILTER
# include <libmilter/mfapi.h>
# include <libmilter/mfdef.h>
-#endif /* MILTER */
+#endif
SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.1016 2013-11-22 20:51:56 ca Exp $")
@@ -23,18 +23,20 @@ SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.1016 2013-11-22 20:51:56 ca Exp $")
#include <sm/fdset.h>
#if SASL || STARTTLS
+# include <tls.h>
# include "sfsasl.h"
-#endif /* SASL || STARTTLS */
+#endif
#if SASL
# define ENC64LEN(l) (((l) + 2) * 4 / 3 + 1)
static int saslmechs __P((sasl_conn_t *, char **));
-#endif /* SASL */
+#endif
#if STARTTLS
# include <openssl/err.h>
# include <sysexits.h>
static SSL_CTX *srv_ctx = NULL; /* TLS server context */
static SSL *srv_ssl = NULL; /* per connection context */
+static tlsi_ctx_T tlsi_ctx; /* TLS information context */
static bool tls_ok_srv = false;
@@ -44,7 +46,7 @@ static bool tls_ok_srv = false;
#if _FFR_DM_ONE
static bool NotFirstDelivery = false;
-#endif /* _FFR_DM_ONE */
+#endif
/* server features */
#define SRV_NONE 0x0000 /* none... */
@@ -60,11 +62,14 @@ static bool NotFirstDelivery = false;
# define SRV_OFFER_PIPE 0x0100 /* offer PIPELINING */
# if _FFR_NO_PIPE
# define SRV_NO_PIPE 0x0200 /* disable PIPELINING, sleep if used */
-# endif /* _FFR_NO_PIPE */
+# endif
#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 */
+#if _FFR_EAI
+# define SRV_OFFER_EAI 0x2000 /* offer SMTPUTF* */
+#endif
static unsigned int srvfeatures __P((ENVELOPE *, char *, unsigned int));
@@ -76,6 +81,32 @@ static char *skipword __P((char *volatile, char *));
static void setup_smtpd_io __P((void));
#if SASL
+# ifndef MAX_AUTH_USER_LEN
+# define MAX_AUTH_USER_LEN 256
+# endif
+# ifndef MAX_AUTH_LOG_LEN
+# define MAX_AUTH_LOG_LEN 64
+# endif
+static void get_sasl_user __P((char *, unsigned int, const char *, char *out, size_t));
+# define RESET_AUTH_FAIL_LOG_USER \
+ do \
+ { \
+ (void) memset(auth_user, 0, sizeof(auth_user)); \
+ (void) memset(auth_user_tmp, 0, sizeof(auth_user_tmp)); \
+ auth_user_len = 0; \
+ } while (0)
+# define SET_AUTH_USER_TMP(s, len) \
+ do \
+ { \
+ auth_user_len = SM_MIN(len, MAX_AUTH_USER_LEN-1); \
+ (void) memcpy(auth_user_tmp, s, auth_user_len); \
+ } while (0)
+# define SET_AUTH_USER \
+ get_sasl_user(auth_user_tmp, auth_user_len, auth_type, auth_user, sizeof(auth_user))
+# define SET_AUTH_USER_CONDITIONALLY \
+ if ('\0' == auth_user[0]) \
+ SET_AUTH_USER;
+# define LOG_AUTH_FAIL_USER ", user=", (int)MAX_AUTH_LOG_LEN, auth_user
# if SASL >= 20000
static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
char *_remoteip, char *_localip,
@@ -84,6 +115,7 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
# define RESET_SASLCONN \
do \
{ \
+ RESET_AUTH_FAIL_LOG_USER; \
result = reset_saslconn(&conn, AuthRealm, remoteip, \
localip, auth_id, &ext_ssf); \
if (result != SASL_OK) \
@@ -98,6 +130,7 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
# define RESET_SASLCONN \
do \
{ \
+ RESET_AUTH_FAIL_LOG_USER; \
result = reset_saslconn(&conn, AuthRealm, &saddr_r, \
&saddr_l, &ext_ssf); \
if (result != SASL_OK) \
@@ -107,6 +140,10 @@ static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname,
# endif /* SASL >= 20000 */
#endif /* SASL */
+#if !defined(RESET_AUTH_FAIL_LOG_USER)
+# define RESET_AUTH_FAIL_LOG_USER
+#endif
+
extern ENVELOPE BlankEnvelope;
#define NBADRCPTS \
@@ -119,11 +156,34 @@ extern ENVELOPE BlankEnvelope;
macdefine(&e->e_macro, A_TEMP, macid("{nbadrcpts}"), buf); \
} while (0)
-#define SKIP_SPACE(s) while (isascii(*s) && isspace(*s)) \
+#define SKIP_SPACE(s) while (SM_ISSPACE(*s)) \
(s)++
+#if _FFR_EAI
+/*
+** ADDR_IS_ASCII -- check whether an address is 100% printable ASCII
+**
+** Parameters:
+** a -- an address (or other string)
+**
+** Returns:
+** TRUE if a is non-NULL and points to only printable ASCII
+** FALSE if a is NULL and points to printable ASCII
+** FALSE if a is non-NULL and points to something containing 8-bittery
+*/
+
+bool
+addr_is_ascii(a)
+ const char * a;
+{
+ while (a != NULL && *a != '\0' && *a >= ' ' && (unsigned char)*a < 127)
+ a++;
+ return (a != NULL && *a == '\0');
+}
+#endif
+
/*
-** PARSE_ESMTP_ARGS -- parse EMSTP arguments (for MAIL, RCPT)
+** PARSE_ESMTP_ARGS -- parse ESMTP arguments (for MAIL, RCPT)
**
** Parameters:
** e -- the envelope
@@ -417,10 +477,10 @@ struct cmd
#define CMDETRN 12 /* etrn -- flush queue */
#if SASL
# define CMDAUTH 13 /* auth -- SASL authenticate */
-#endif /* SASL */
+#endif
#if STARTTLS
# define CMDSTLS 14 /* STARTTLS -- start TLS session */
-#endif /* STARTTLS */
+#endif
/* non-standard commands */
#define CMDVERB 17 /* verb -- go into verbose mode */
/* unimplemented commands from RFC 821 */
@@ -456,10 +516,10 @@ static struct cmd CmdTab[] =
{ "turn", CMDUNIMPL },
#if SASL
{ "auth", CMDAUTH, },
-#endif /* SASL */
+#endif
#if STARTTLS
{ "starttls", CMDSTLS, },
-#endif /* STARTTLS */
+#endif
/* remaining commands are here only to trap and log attempts to use them */
{ "showq", CMDDBGQSHOW },
{ "debug", CMDDBGDEBUG },
@@ -472,19 +532,19 @@ static char *CurSmtpClient; /* who's at the other end of channel */
#ifndef MAXBADCOMMANDS
# define MAXBADCOMMANDS 25 /* maximum number of bad commands */
-#endif /* ! MAXBADCOMMANDS */
+#endif
#ifndef MAXHELOCOMMANDS
# define MAXHELOCOMMANDS 3 /* max HELO/EHLO commands before slowdown */
-#endif /* ! MAXHELOCOMMANDS */
+#endif
#ifndef MAXVRFYCOMMANDS
# define MAXVRFYCOMMANDS 6 /* max VRFY/EXPN commands before slowdown */
-#endif /* ! MAXVRFYCOMMANDS */
+#endif
#ifndef MAXETRNCOMMANDS
# define MAXETRNCOMMANDS 8 /* max ETRN commands before slowdown */
-#endif /* ! MAXETRNCOMMANDS */
+#endif
#ifndef MAXTIMEOUT
# define MAXTIMEOUT (4 * 60) /* max timeout for bad commands */
-#endif /* ! MAXTIMEOUT */
+#endif
/*
** Maximum shift value to compute timeout for bad commands.
@@ -493,10 +553,10 @@ static char *CurSmtpClient; /* who's at the other end of channel */
#ifndef MAXSHIFT
# define MAXSHIFT 8
-#endif /* ! MAXSHIFT */
+#endif
#if MAXSHIFT > 31
ERROR _MAXSHIFT > 31 is invalid
-#endif /* MAXSHIFT */
+#endif
#if MAXBADCOMMANDS > 0
@@ -514,7 +574,7 @@ static char *CurSmtpClient; /* who's at the other end of channel */
#if SM_HEAP_CHECK
static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp",
"@(#)$Debug: leak_smtp - trace memory leaks during SMTP processing $");
-#endif /* SM_HEAP_CHECK */
+#endif
typedef struct
{
@@ -722,10 +782,21 @@ do \
#else
# define auth_active false
#endif
+#if _FFR_EAI
+#define GET_PROTOCOL() \
+ (e->e_smtputf8 \
+ ? (auth_active \
+ ? (tls_active ? "UTF8SMTPSA" : "UTF8SMTPA") \
+ : (tls_active ? "UTF8SMTPS" : "UTF8SMTP")) \
+ : (auth_active \
+ ? (tls_active ? "ESMTPSA" : "ESMTPA") \
+ : (tls_active ? "ESMTPS" : "ESMTP")))
+#else /* _FFR_EAI */
#define GET_PROTOCOL() \
(auth_active \
? (tls_active ? "ESMTPSA" : "ESMTPA") \
: (tls_active ? "ESMTPS" : "ESMTP"))
+#endif /* _FFR_EAI */
static bool SevenBitInput_Saved; /* saved version of SevenBitInput */
@@ -770,7 +841,7 @@ smtp(nullserver, d_flags, e)
char inp[MAXINPLINE];
#if MAXINPLINE < MAXLINE
ERROR _MAXINPLINE must NOT be less than _MAXLINE: MAXINPLINE < MAXLINE
-#endif /* MAXINPLINE < MAXLINE */
+#endif
char cmdbuf[MAXLINE];
#if SASL
sasl_conn_t *conn;
@@ -781,6 +852,8 @@ smtp(nullserver, d_flags, e)
volatile int authenticating;
char *user;
char *in, *out2;
+ char auth_user[MAX_AUTH_USER_LEN], auth_user_tmp[MAX_AUTH_USER_LEN];
+ unsigned int auth_user_len;
# if SASL >= 20000
char *auth_id = NULL;
const char *out;
@@ -801,7 +874,6 @@ smtp(nullserver, d_flags, e)
char *mechlist;
volatile unsigned int n_mechs;
unsigned int len;
-#else /* SASL */
#endif /* SASL */
int r;
#if STARTTLS
@@ -811,12 +883,15 @@ smtp(nullserver, d_flags, e)
bool saveQuickAbort;
bool saveSuprErrs;
time_t tlsstart;
+ int ssl_err, tlsret;
+ int save_errno;
+ extern int TLSsslidx;
#endif /* STARTTLS */
volatile unsigned int features;
#if PIPELINING
# if _FFR_NO_PIPE
int np_log = 0;
-# endif /* _FFR_NO_PIPE */
+# endif
#endif /* PIPELINING */
volatile time_t log_delay = (time_t) 0;
#if MILTER
@@ -830,15 +905,16 @@ smtp(nullserver, d_flags, e)
size_t inplen;
#if _FFR_BADRCPT_SHUTDOWN
int n_badrcpts_adj;
-#endif /* _FFR_BADRCPT_SHUTDOWN */
+#endif
+ RESET_AUTH_FAIL_LOG_USER;
SevenBitInput_Saved = SevenBitInput;
smtp.sm_nrcpts = 0;
#if MILTER
smtp.sm_milterize = (nullserver == NULL);
smtp.sm_milterlist = false;
addr = NULL;
-#endif /* MILTER */
+#endif
/* setup I/O fd correctly for the SMTP server */
setup_smtpd_io();
@@ -892,12 +968,15 @@ smtp(nullserver, d_flags, e)
#endif /* SASL */
#if PIPELINING
| SRV_OFFER_PIPE
-#endif /* PIPELINING */
+#endif
#if STARTTLS
| (bitnset(D_NOTLS, d_flags) ? SRV_NONE : SRV_OFFER_TLS)
| (bitset(TLS_I_NO_VRFY, TLS_Srv_Opts) ? SRV_NONE
: SRV_VRFY_CLT)
-#endif /* STARTTLS */
+#endif
+#if _FFR_EAI
+ | SRV_OFFER_EAI
+#endif /* _FFR_EAI */
;
if (nullserver == NULL)
{
@@ -931,6 +1010,7 @@ smtp(nullserver, d_flags, e)
}
else if (strncmp(nullserver, "421 ", 4) == 0)
{
+ /* Can't use ("%s", ...) due to message() requirements */
message(nullserver);
goto doquit;
}
@@ -985,7 +1065,7 @@ smtp(nullserver, d_flags, e)
if (in != NULL && (
# if NETINET6
strcmp(in, "inet6") == 0 ||
-# endif /* NETINET6 */
+# endif
strcmp(in, "inet") == 0))
{
SOCKADDR_LEN_T addrsize;
@@ -1056,7 +1136,7 @@ smtp(nullserver, d_flags, e)
# if 0
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{auth_author}"), NULL);
-# endif /* 0 */
+# endif
/* set properties */
(void) memset(&ssp, '\0', sizeof(ssp));
@@ -1267,7 +1347,7 @@ smtp(nullserver, d_flags, e)
if (
#if STARTTLS
!smtps &&
-#endif /* STARTTLS */
+#endif
*greetcode == '2' && nullserver == NULL)
{
time_t msecs = 0;
@@ -1336,7 +1416,16 @@ smtp(nullserver, d_flags, e)
/* If this an smtps connection, start TLS now */
if (smtps)
{
+ if (!tls_ok_srv || srv_ctx == NULL)
+ {
+ sm_syslog(LOG_ERR, e->e_id,
+ "smtps: TLS not available, exiting");
+ exit(EX_CONFIG);
+ }
Errors = 0;
+ first = true;
+ gothello = false;
+ smtp.sm_gotmail = false;
goto starttls;
}
@@ -1369,14 +1458,14 @@ smtp(nullserver, d_flags, e)
while ((id = p) != NULL && (p = strchr(id, '\n')) != NULL)
{
*p++ = '\0';
- if (isascii(*id) && isspace(*id))
+ if (SM_ISSPACE(*id))
id++;
(void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, "-%s");
message(cmdbuf, id);
}
if (id != NULL)
{
- if (isascii(*id) && isspace(*id))
+ if (SM_ISSPACE(*id))
id++;
(void) sm_strlcpyn(cmdbuf, sizeof(cmdbuf), 2, greetcode, " %s");
message(cmdbuf, id);
@@ -1409,7 +1498,7 @@ smtp(nullserver, d_flags, e)
e->e_flags &= ~(EF_VRFYONLY|EF_GLOBALERRS);
#if MILTER
milter_cmd_fail = false;
-#endif /* MILTER */
+#endif
/* setup for the read */
e->e_to = NULL;
@@ -1437,7 +1526,7 @@ smtp(nullserver, d_flags, e)
#if MILTER
/* close out milter filters */
milter_quit(e);
-#endif /* MILTER */
+#endif
message("421 4.4.1 %s Lost input channel from %s",
MyHostName, CurSmtpClient);
@@ -1492,7 +1581,7 @@ smtp(nullserver, d_flags, e)
cmdlen = strlen(http_cmd);
if (cmdlen < inplen &&
sm_strncasecmp(inp, http_cmd, cmdlen) == 0 &&
- isascii(inp[cmdlen]) && isspace(inp[cmdlen]))
+ SM_ISSPACE(inp[cmdlen]))
{
/* Open proxy, drop it */
message("421 4.7.0 %s Rejecting open proxy %s",
@@ -1572,16 +1661,18 @@ smtp(nullserver, d_flags, e)
inp);
# if SASL >= 20000
sm_free(in);
-# endif /* SASL >= 20000 */
+# endif
RESET_SASLCONN;
continue;
}
# if SASL >= 20000
+ SET_AUTH_USER_TMP(in, inlen);
result = sasl_server_step(conn, in, inlen,
&out, &outlen);
sm_free(in);
# else /* SASL >= 20000 */
+ SET_AUTH_USER_TMP(out, outlen);
result = sasl_server_step(conn, out, outlen,
&out, &outlen, &errstr);
# endif /* SASL >= 20000 */
@@ -1622,7 +1713,7 @@ smtp(nullserver, d_flags, e)
# if 0
/* get realm? */
sasl_getprop(conn, SASL_REALM, (void **) &data);
-# endif /* 0 */
+# endif
/* get security strength (features) */
result = sasl_getprop(conn, SASL_SSF,
@@ -1691,6 +1782,8 @@ smtp(nullserver, d_flags, e)
}
else if (result == SASL_CONTINUE)
{
+ SET_AUTH_USER;
+
len = ENC64LEN(outlen);
out2 = xalloc(len);
result = sasl_encode64(out, outlen, out2, len,
@@ -1717,26 +1810,35 @@ smtp(nullserver, d_flags, e)
}
# if SASL >= 20000
sm_free(out2);
-# endif /* SASL >= 20000 */
+# endif
}
else
{
- /* not SASL_OK or SASL_CONT */
- message("535 5.7.0 authentication failed");
- if (LogLevel > 9)
- sm_syslog(LOG_WARNING, e->e_id,
- "AUTH failure (%s): %s (%d) %s, relay=%.100s",
- auth_type,
- sasl_errstring(result, NULL,
- NULL),
- result,
+
# if SASL >= 20000
- sasl_errdetail(conn),
-# else /* SASL >= 20000 */
- errstr == NULL ? "" : errstr,
-# endif /* SASL >= 20000 */
- CurSmtpClient);
- RESET_SASLCONN;
+# define SASLERR sasl_errdetail(conn)
+# else
+# define SASLERR errstr == NULL ? "" : errstr
+# endif
+#define LOGAUTHFAIL \
+ do \
+ { \
+ SET_AUTH_USER_CONDITIONALLY \
+ message("535 5.7.0 authentication failed"); \
+ if (LogLevel >= 9) \
+ sm_syslog(LOG_WARNING, e->e_id, \
+ "AUTH failure (%s): %s (%d) %s%s%.*s, relay=%.100s", \
+ (auth_type != NULL) ? auth_type : "unknown", \
+ sasl_errstring(result, NULL, NULL), \
+ result, \
+ SASLERR, \
+ LOG_AUTH_FAIL_USER, \
+ CurSmtpClient); \
+ RESET_SASLCONN; \
+ } while (0)
+
+
+ LOGAUTHFAIL;
authenticating = SASL_NOT_AUTH;
}
}
@@ -1754,11 +1856,11 @@ smtp(nullserver, d_flags, e)
sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp);
/* break off command */
- for (p = inp; isascii(*p) && isspace(*p); p++)
+ for (p = inp; SM_ISSPACE(*p); p++)
continue;
cmd = cmdbuf;
while (*p != '\0' &&
- !(isascii(*p) && isspace(*p)) &&
+ !(SM_ISSPACE(*p)) &&
cmd < &cmdbuf[sizeof(cmdbuf) - 2])
*cmd++ = *p++;
*cmd = '\0';
@@ -1849,10 +1951,15 @@ smtp(nullserver, d_flags, e)
if (nullserver != NULL)
{
if (ISSMTPREPLY(nullserver))
+ {
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(nullserver);
+ }
else
+ {
usrerr("550 5.0.0 %s",
nullserver);
+ }
}
else
usrerr("452 4.4.5 Insufficient disk space; try again later");
@@ -1902,8 +2009,7 @@ smtp(nullserver, d_flags, e)
if (isspace(*q))
{
*q = '\0';
- while (*++q != '\0' &&
- isascii(*q) && isspace(*q))
+ while (*++q != '\0' && SM_ISSPACE(*q))
continue;
*(q - 1) = '\0';
ismore = (*q != '\0');
@@ -1951,6 +2057,7 @@ smtp(nullserver, d_flags, e)
result = sasl_decode64(q, strlen(q), in,
&inlen);
# endif /* SASL >= 20000 */
+
if (result != SASL_OK)
{
message("501 5.5.4 cannot BASE64 decode '%s'",
@@ -1964,11 +2071,12 @@ smtp(nullserver, d_flags, e)
authenticating = SASL_NOT_AUTH;
# if SASL >= 20000
sm_free(in);
-# endif /* SASL >= 20000 */
+# endif
in = NULL;
inlen = 0;
break;
}
+ SET_AUTH_USER_TMP(in, inlen);
}
else
{
@@ -1980,33 +2088,19 @@ smtp(nullserver, d_flags, e)
# if SASL >= 20000
result = sasl_server_start(conn, p, in, inlen,
&out, &outlen);
- if (in != NULL)
- sm_free(in);
+ SM_FREE(in);
# else /* SASL >= 20000 */
result = sasl_server_start(conn, p, in, inlen,
&out, &outlen, &errstr);
# endif /* SASL >= 20000 */
+ if (p != NULL)
+ auth_type = newstr(p);
if (result != SASL_OK && result != SASL_CONTINUE)
{
- message("535 5.7.0 authentication failed");
- if (LogLevel > 9)
- sm_syslog(LOG_ERR, e->e_id,
- "AUTH failure (%s): %s (%d) %s, relay=%.100s",
- p,
- sasl_errstring(result, NULL,
- NULL),
- result,
-# if SASL >= 20000
- sasl_errdetail(conn),
-# else /* SASL >= 20000 */
- errstr,
-# endif /* SASL >= 20000 */
- CurSmtpClient);
- RESET_SASLCONN;
+ LOGAUTHFAIL;
break;
}
- auth_type = newstr(p);
if (result == SASL_OK)
{
@@ -2015,6 +2109,8 @@ smtp(nullserver, d_flags, e)
/* authenticated by the initial response */
}
+ SET_AUTH_USER;
+
/* len is at least 2 */
len = ENC64LEN(outlen);
out2 = xalloc(len);
@@ -2040,7 +2136,7 @@ smtp(nullserver, d_flags, e)
}
# if SASL >= 20000
sm_free(out2);
-# endif /* SASL >= 20000 */
+# endif
break;
#endif /* SASL */
@@ -2057,6 +2153,7 @@ smtp(nullserver, d_flags, e)
message("503 5.5.0 TLS not available");
break;
}
+ starttls:
if (!tls_ok_srv)
{
message("454 4.3.3 TLS not available after start");
@@ -2076,28 +2173,20 @@ smtp(nullserver, d_flags, e)
usrerr("454 4.7.0 Please try again later");
break;
}
- starttls:
-# if USE_OPENSSL_ENGINE
- if (!SSLEngineInitialized)
+ if (!TLS_set_engine(SSLEngine, false))
{
- if (!SSL_set_engine(NULL))
- {
- sm_syslog(LOG_ERR, NOQID,
- "STARTTLS=server, SSL_set_engine=failed");
- tls_ok_srv = false;
- message("454 4.3.3 TLS not available right now");
- break;
- }
- else
- SSLEngineInitialized = true;
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=server, engine=%s, TLS_set_engine=failed",
+ SSLEngine);
+ tls_ok_srv = false;
+ message("454 4.3.3 TLS not available right now");
+ break;
}
-# endif /* USE_OPENSSL_ENGINE */
# if TLS_NO_RSA
/*
** XXX do we need a temp key ?
*/
-# else /* TLS_NO_RSA */
-# endif /* TLS_NO_RSA */
+# endif
# if TLS_VRFY_PER_CTX
/*
@@ -2109,22 +2198,37 @@ smtp(nullserver, d_flags, e)
TLS_VERIFY_CLIENT();
# endif /* TLS_VRFY_PER_CTX */
+#define SMTLSFAILED \
+ do { \
+ SM_SSL_FREE(srv_ssl); \
+ goto tls_done; \
+ } while (0)
+
if (srv_ssl != NULL)
SSL_clear(srv_ssl);
else if ((srv_ssl = SSL_new(srv_ctx)) == NULL)
{
message("454 4.3.3 TLS not available: error generating SSL handle");
- if (LogLevel > 8)
- tlslogerr(LOG_WARNING, "server");
+ tlslogerr(LOG_WARNING, 8, "server");
goto tls_done;
}
-
- if (get_tls_se_options(e, srv_ssl, true) != 0)
+ if (get_tls_se_options(e, srv_ssl, &tlsi_ctx, true)
+ != 0)
{
message("454 4.3.3 TLS not available: error setting options");
- SSL_free(srv_ssl);
- srv_ssl = NULL;
- goto tls_done;
+ SMTLSFAILED;
+ }
+ r = SSL_set_ex_data(srv_ssl, TLSsslidx, &tlsi_ctx);
+ if (0 == r)
+ {
+ if (LogLevel > 5)
+ {
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=server, error: SSL_set_ex_data failed=%d",
+ r);
+ tlslogerr(LOG_WARNING, 9, "server");
+ }
+ SMTLSFAILED;
}
# if !TLS_VRFY_PER_CTX
@@ -2145,61 +2249,64 @@ smtp(nullserver, d_flags, e)
SSL_set_wfd(srv_ssl, wfd) <= 0)
{
message("454 4.3.3 TLS not available: error set fd");
- SSL_free(srv_ssl);
- srv_ssl = NULL;
- goto tls_done;
+ SMTLSFAILED;
}
if (!smtps)
message("220 2.0.0 Ready to start TLS");
# if PIPELINING
(void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
-# endif /* PIPELINING */
+# endif
SSL_set_accept_state(srv_ssl);
tlsstart = curtime();
- ssl_retry:
- if ((r = SSL_accept(srv_ssl)) <= 0)
- {
- int i, ssl_err;
- int save_errno = errno;
- ssl_err = SSL_get_error(srv_ssl, r);
- i = tls_retry(srv_ssl, rfd, wfd, tlsstart,
+ ssl_err = SSL_ERROR_WANT_READ;
+ save_errno = 0;
+ do
+ {
+ tlsret = tls_retry(srv_ssl, rfd, wfd, tlsstart,
TimeOuts.to_starttls, ssl_err,
"server");
- if (i > 0)
- goto ssl_retry;
-
- if (LogLevel > 5)
+ if (tlsret <= 0)
{
- unsigned long l;
- const char *sr;
-
- l = ERR_peek_error();
- sr = ERR_reason_error_string(l);
- sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=server, error: accept failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d, relay=%.100s",
- r, sr == NULL ? "unknown"
- : sr,
- ssl_err, save_errno, i,
- CurSmtpClient);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, "server");
- }
- tls_ok_srv = false;
- SSL_free(srv_ssl);
- srv_ssl = NULL;
+ if (LogLevel > 5)
+ {
+ unsigned long l;
+ const char *sr;
+
+ l = ERR_peek_error();
+ sr = ERR_reason_error_string(l);
+
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=server, error: accept failed=%d, reason=%s, SSL_error=%d, errno=%d, retry=%d, relay=%.100s",
+ r, sr == NULL ? "unknown"
+ : sr,
+ ssl_err, save_errno,
+ tlsret, CurSmtpClient);
+ tlslogerr(LOG_WARNING, 9, "server");
+ }
+ tls_ok_srv = false;
+ SM_SSL_FREE(srv_ssl);
- /*
- ** according to the next draft of
- ** RFC 2487 the connection should be dropped
- */
+ /*
+ ** according to the next draft of
+ ** RFC 2487 the connection should
+ ** be dropped
+ **
+ ** arrange to ignore any current
+ ** send list
+ */
- /* arrange to ignore any current send list */
- e->e_sendqueue = NULL;
- goto doquit;
- }
+ e->e_sendqueue = NULL;
+ goto doquit;
+ }
+
+ r = SSL_accept(srv_ssl);
+ save_errno = 0;
+ if (r <= 0)
+ ssl_err = SSL_get_error(srv_ssl, r);
+ } while (r <= 0);
/* ignore return code for now, it's in {verify} */
(void) tls_get_info(srv_ssl, true,
@@ -2278,7 +2385,7 @@ smtp(nullserver, d_flags, e)
tls_active = true;
# if PIPELINING
(void) sm_io_autoflush(InChannel, OutChannel);
-# endif /* PIPELINING */
+# endif
}
else
{
@@ -2452,10 +2559,15 @@ smtp(nullserver, d_flags, e)
tempfail = true;
smtp.sm_milterize = false;
if (response != NULL)
+ {
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(response);
+ }
else
+ {
message("421 4.7.0 %s closing connection",
MyHostName);
+ }
/* arrange to ignore send list */
e->e_sendqueue = NULL;
lognullconnection = false;
@@ -2505,7 +2617,7 @@ smtp(nullserver, d_flags, e)
#if PIPELINING
if (bitset(SRV_OFFER_PIPE, features))
message("250-PIPELINING");
-#endif /* PIPELINING */
+#endif
if (bitset(SRV_OFFER_EXPN, features))
{
message("250-EXPN");
@@ -2514,7 +2626,7 @@ smtp(nullserver, d_flags, e)
}
#if MIME8TO7
message("250-8BITMIME");
-#endif /* MIME8TO7 */
+#endif
if (MaxMessageSize > 0)
message("250-SIZE %ld", MaxMessageSize);
else
@@ -2522,17 +2634,21 @@ smtp(nullserver, d_flags, e)
#if DSN
if (SendMIMEErrors && bitset(SRV_OFFER_DSN, features))
message("250-DSN");
-#endif /* DSN */
+#endif
+#if _FFR_EAI
+ if (bitset(SRV_OFFER_EAI, features))
+ message("250-SMTPUTF8");
+#endif /* _FFR_EAI */
if (bitset(SRV_OFFER_ETRN, features))
message("250-ETRN");
#if SASL
if (sasl_ok && mechlist != NULL && *mechlist != '\0')
message("250-AUTH %s", mechlist);
-#endif /* SASL */
+#endif
#if STARTTLS
if (tls_ok_srv && bitset(SRV_OFFER_TLS, features))
message("250-STARTTLS");
-#endif /* STARTTLS */
+#endif
if (DeliverByMin > 0)
message("250-DELIVERBY %ld",
(long) DeliverByMin);
@@ -2577,6 +2693,7 @@ smtp(nullserver, d_flags, e)
sm_syslog(LOG_INFO, e->e_id,
"SMTP MAIL command (%.100s) from %s tempfailed (due to previous checks)",
p, CurSmtpClient);
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(MSG_TEMPFAIL);
break;
}
@@ -2636,7 +2753,7 @@ smtp(nullserver, d_flags, e)
extern char *FullName;
QuickAbort = true;
- SM_FREE_CLR(FullName);
+ SM_FREE(FullName);
/* must parse sender first */
delimptr = NULL;
@@ -2696,6 +2813,21 @@ smtp(nullserver, d_flags, e)
if (Errors > 0)
sm_exc_raisenew_x(&EtypeQuickAbort, 1);
+#if _FFR_EAI
+ if (e->e_smtputf8)
+ {
+ protocol = GET_PROTOCOL();
+ macdefine(&e->e_macro, A_PERM, 'r', protocol);
+ }
+
+ /* UTF8 addresses are only legal with SMTPUTF8 */
+ if (!e->e_smtputf8 && !addr_is_ascii(e->e_from.q_paddr))
+ {
+ usrerr("553 5.6.7 That address requires SMTPUTF8");
+ sm_exc_raisenew_x(&EtypeQuickAbort, 1);
+ }
+#endif
+
#if SASL
# if _FFR_AUTH_PASSING
/* set the default AUTH= if the sender didn't */
@@ -2723,7 +2855,7 @@ smtp(nullserver, d_flags, e)
/* make the "real" sender address available */
macdefine(&e->e_macro, A_TEMP, macid("{mail_from}"),
e->e_from.q_paddr);
-#endif /* _FFR_MAIL_MACRO */
+#endif
if (rscheck("check_mail", addr,
NULL, e, RSF_RMCOMM|RSF_COUNT, 3,
NULL, e->e_id, NULL, NULL) != EX_OK ||
@@ -2753,7 +2885,7 @@ smtp(nullserver, d_flags, e)
!enoughdiskspace(e->e_msgsize, e)
#if _FFR_ANY_FREE_FS
&& !filesys_free(e->e_msgsize)
-#endif /* _FFR_ANY_FREE_FS */
+#endif
)
{
/*
@@ -2894,7 +3026,7 @@ smtp(nullserver, d_flags, e)
if (!SM_IS_INTERACTIVE(e->e_sendmode)
#if _FFR_DM_ONE
&& (NotFirstDelivery || SM_DM_ONE != e->e_sendmode)
-#endif /* _FFR_DM_ONE */
+#endif
)
e->e_flags |= EF_VRFYONLY;
@@ -2908,8 +3040,8 @@ smtp(nullserver, d_flags, e)
** as QS_DONTSEND.
*/
- if (!(smtp.sm_milterlist && smtp.sm_milterize &&
- !bitset(EF_DISCARD, e->e_flags)) &&
+ if (smtp.sm_milterlist && smtp.sm_milterize &&
+ !bitset(EF_DISCARD, e->e_flags) &&
(smtp.sm_milters.mis_flags &
(MIS_FL_DEL_RCPT|MIS_FL_REJ_RCPT)) != 0)
e->e_flags |= EF_VRFYONLY;
@@ -2933,6 +3065,13 @@ smtp(nullserver, d_flags, e)
usrerr("501 5.0.0 Missing recipient");
goto rcpt_done;
}
+#if _FFR_EAI
+ if (!e->e_smtputf8 && !addr_is_ascii(a->q_paddr))
+ {
+ usrerr("553 5.6.7 Address requires SMTPUTF8");
+ goto rcpt_done;
+ }
+#endif
if (delimptr != NULL && *delimptr != '\0')
*delimptr++ = '\0';
@@ -3081,8 +3220,8 @@ smtp(nullserver, d_flags, e)
/* Is this needed? */
#if !MILTER
rcpt_done:
-#endif /* !MILTER */
-
+#endif
+
macdefine(&e->e_macro, A_PERM,
macid("{rcpt_mailer}"), NULL);
macdefine(&e->e_macro, A_PERM,
@@ -3226,7 +3365,7 @@ smtp(nullserver, d_flags, e)
vrfyqueue = NULL;
if (vrfy)
e->e_flags |= EF_VRFYONLY;
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
if (*p == '\0')
{
@@ -3308,6 +3447,7 @@ smtp(nullserver, d_flags, e)
sm_syslog(LOG_INFO, e->e_id,
"SMTP ETRN command (%.100s) from %s tempfailed (due to previous checks)",
p, CurSmtpClient);
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(MSG_TEMPFAIL);
break;
}
@@ -3404,7 +3544,7 @@ smtp(nullserver, d_flags, e)
message("221 2.0.0 %s closing connection", MyHostName);
#if PIPELINING
(void) sm_io_flush(OutChannel, SM_TIME_DEFAULT);
-#endif /* PIPELINING */
+#endif
if (smtp.sm_nrcpts > 0)
logundelrcpts(e, "aborted by sender", 9, false);
@@ -3416,7 +3556,7 @@ smtp(nullserver, d_flags, e)
/* shutdown TLS connection */
if (tls_active)
{
- (void) endtls(srv_ssl, "server");
+ (void) endtls(&srv_ssl, "server");
tls_active = false;
}
#endif /* STARTTLS */
@@ -3436,7 +3576,7 @@ doquit:
#if MILTER
/* close out milter filters */
milter_quit(e);
-#endif /* MILTER */
+#endif
if (tTd(92, 2))
sm_dprintf("QUIT: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",
@@ -3574,7 +3714,7 @@ doquit:
}
#if SASL
}
-#endif /* SASL */
+#endif
}
SM_EXCEPT(exc, "[!F]*")
{
@@ -3607,7 +3747,7 @@ smtp_data(smtp, e)
{
#if MILTER
bool milteraccept;
-#endif /* MILTER */
+#endif
bool aborting;
bool doublequeue;
bool rv = true;
@@ -3657,8 +3797,9 @@ smtp_data(smtp, e)
#if _FFR_MILTER_ENHSC
if (ISSMTPCODE(response))
(void) extenhsc(response + 4, ' ', e->e_enhsc);
-#endif /* _FFR_MILTER_ENHSC */
+#endif
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(response);
if (strncmp(response, "421 ", 4) == 0
|| strncmp(response, "421-", 4) == 0)
@@ -3678,7 +3819,7 @@ smtp_data(smtp, e)
#if _FFR_MILTER_ENHSC
(void) sm_strlcpy(e->e_enhsc, "5.7.1",
sizeof(e->e_enhsc));
-#endif /* _FFR_MILTER_ENHSC */
+#endif
usrerr("550 5.7.1 Command rejected");
return true;
@@ -3699,7 +3840,8 @@ smtp_data(smtp, e)
}
#if _FFR_MILTER_ENHSC
(void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc);
-#endif /* _FFR_MILTER_ENHSC */
+#endif
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(MSG_TEMPFAIL);
return true;
@@ -3778,7 +3920,8 @@ smtp_data(smtp, e)
#if _FFR_MILTER_ENHSC
if (ISSMTPCODE(response))
(void) extenhsc(response + 4, ' ', e->e_enhsc);
-#endif /* _FFR_MILTER_ENHSC */
+#endif
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(response);
if (strncmp(response, "421 ", 4) == 0
|| strncmp(response, "421-", 4) == 0)
@@ -3809,7 +3952,8 @@ smtp_data(smtp, e)
milteraccept = false;
#if _FFR_MILTER_ENHSC
(void) extenhsc(MSG_TEMPFAIL + 4, ' ', e->e_enhsc);
-#endif /* _FFR_MILTER_ENHSC */
+#endif
+ /* Can't use ("%s", ...) due to usrerr() requirements */
usrerr(MSG_TEMPFAIL);
break;
@@ -3994,7 +4138,7 @@ smtp_data(smtp, e)
#if NAMED_BIND
_res.retry = TimeOuts.res_retry[RES_TO_FIRST];
_res.retrans = TimeOuts.res_retrans[RES_TO_FIRST];
-#endif /* NAMED_BIND */
+#endif
#if _FFR_PROXY
if (SM_PROXY_REQ == e->e_sendmode)
@@ -4164,7 +4308,7 @@ smtp_data(smtp, e)
message("250 2.0.0 %s Message accepted for delivery", id);
#if _FFR_PROXY
}
-#endif /* _FFR_PROXY */
+#endif
CurEnv->e_id = oldid;
/* if we just queued, poke it */
@@ -4309,7 +4453,7 @@ logundelrcpts(e, msg, level, all)
#if _FFR_MILTER_ENHSC
(a->q_status == NULL && e->e_enhsc[0] != '\0')
? e->e_enhsc :
-#endif /* _FFR_MILTER_ENHSC */
+#endif
a->q_status,
msg, NULL, (time_t) 0, e, a, EX_OK /* ??? */);
}
@@ -4483,9 +4627,9 @@ skipword(p, w)
q = p;
/* find end of word */
- while (*p != '\0' && *p != ':' && !(isascii(*p) && isspace(*p)))
+ while (*p != '\0' && *p != ':' && !(SM_ISSPACE(*p)))
p++;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
*p++ = '\0';
if (*p != ':')
{
@@ -4542,7 +4686,7 @@ reset_mail_esmtp_args(e)
# if _FFR_AUTH_PASSING
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{auth_author}"), NULL);
-# endif /* _FFR_AUTH_PASSING */
+# endif
#endif /* SASL */
/* "by" */
@@ -4728,7 +4872,7 @@ mail_esmtp_args(a, kp, vp, e)
# if _FFR_AUTH_PASSING
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{auth_author}"), NULL);
-# endif /* _FFR_AUTH_PASSING */
+# endif
}
else
{
@@ -4820,6 +4964,17 @@ mail_esmtp_args(a, kp, vp, e)
/* XXX: check whether more characters follow? */
}
+#if _FFR_EAI
+ else if (sm_strcasecmp(kp, "smtputf8") == 0)
+ {
+ if (!bitset(SRV_OFFER_EAI, e->e_features))
+ {
+ usrerr("504 5.7.0 Sorry, SMTPUTF8 not supported/enabled");
+ /* NOTREACHED */
+ }
+ e->e_smtputf8 = true;
+ }
+#endif
else
{
usrerr("555 5.5.4 %s parameter unrecognized", kp);
@@ -5174,11 +5329,14 @@ static struct
{ 'C', SRV_REQ_SEC },
{ 'D', SRV_OFFER_DSN },
{ 'E', SRV_OFFER_ETRN },
+#if _FFR_EAI
+ { 'I', SRV_OFFER_EAI },
+#endif
{ 'L', SRV_REQ_AUTH },
#if PIPELINING
# if _FFR_NO_PIPE
{ 'N', SRV_NO_PIPE },
-# endif /* _FFR_NO_PIPE */
+# endif
{ 'P', SRV_OFFER_PIPE },
#endif /* PIPELINING */
{ 'R', SRV_VRFY_CLT }, /* same as V; not documented */
@@ -5453,4 +5611,140 @@ reset_saslconn(sasl_conn_t **conn, char *hostname,
# endif /* SASL >= 20000 */
return SASL_OK;
}
+
+/*
+** GET_SASL_USER -- extract user part from SASL reply
+**
+** Parameters:
+** val -- sasl reply (may contain NUL)
+** len -- length of val
+** auth_type -- auth_type (can be NULL)
+** user -- output buffer for extract user
+** user_len -- length of output buffer (user)
+**
+** Returns:
+** none.
+**
+** Note: val is supplied by the client and hence may contain "bad"
+** (non-printable) characters, but the returned value (user)
+** is only used for logging which converts those characters.
+*/
+
+static void
+get_sasl_user(val, len, auth_type, user, user_len)
+ char *val;
+ unsigned int len;
+ const char *auth_type;
+ char *user;
+ size_t user_len;
+{
+ unsigned int u;
+
+ SM_ASSERT(val != NULL);
+ SM_ASSERT(user != NULL);
+ SM_ASSERT(user_len > 0);
+
+ *user = '\0';
+ if (NULL == auth_type || '\0' == *auth_type)
+ return;
+ if (0 == len)
+ return;
+
+# define DIGMD5U "username=\""
+# define DIGMD5U_L (sizeof(DIGMD5U) - 1)
+ if (sm_strcasecmp(auth_type, "digest-md5") == 0 &&
+ strncmp(val, DIGMD5U, DIGMD5U_L) == 0)
+ {
+ char *s;
+
+ val += DIGMD5U_L;
+ if (len <= DIGMD5U_L)
+ return;
+ len -= DIGMD5U_L;
+
+ /* format? could there be a quoted '"'? */
+ for (s = val, u = 0; *s != '\0' && u < len; s++)
+ {
+ if ('"' == *s)
+ {
+ *s = '\0';
+ break;
+ }
+ if ('\\' == *s)
+ {
+ ++s;
+ if ('\0' == *s)
+ break;
+ }
+ }
+ }
+ else if (sm_strcasecmp(auth_type, "cram-md5") == 0)
+ {
+ char *s;
+
+ for (s = val, u = 0; *s != '\0' && u < len; s++)
+ {
+ if (' ' == *s)
+ {
+ *s = '\0';
+ break;
+ }
+ }
+ }
+
+ else if (sm_strcasecmp(auth_type, "plain") == 0 ||
+ sm_strcasecmp(auth_type, "login") == 0)
+ {
+ /*
+ ** RFC 4616: The PLAIN Simple Authentication and
+ ** Security Layer (SASL) Mechanism
+ ** message = [authzid] UTF8NUL authcid UTF8NUL passwd
+ ** each part: 1*SAFE ; MUST accept up to 255 octets
+ ** UTF8NUL = %x00 ; UTF-8 encoded NUL character
+ **
+ ** draft-murchison-sasl-login: it's just username by its own
+ */
+
+ for (u = 0; u < len; u++)
+ {
+ if (val[u] == '\0')
+ {
+ val[u] = '/';
+ (void) sm_strlcpy(user,
+ val + ((0 == u) ? 1 : 0),
+ user_len);
+ return;
+ }
+ }
+ }
+ else
+ {
+ /*
+ ** Extracting the "user" from other mechanisms
+ ** is currently not supported.
+ */
+
+ return;
+ }
+
+ /*
+ ** Does the input buffer has an NUL in it so it can be treated
+ ** as a C string?
+ */
+
+ /* SM_ASSERT(len > 0); see above */
+ u = len - 1;
+ if (val[u] != '\0')
+ {
+ for (u = 0; u < len; u++)
+ {
+ if (val[u] == '\0')
+ break;
+ }
+ }
+ if (val[u] != '\0')
+ user_len = SM_MIN(len, user_len);
+
+ (void) sm_strlcpy(user, val, user_len);
+}
#endif /* SASL */
diff --git a/contrib/sendmail/src/stab.c b/contrib/sendmail/src/stab.c
index bf8651113b73..6835662ae855 100644
--- a/contrib/sendmail/src/stab.c
+++ b/contrib/sendmail/src/stab.c
@@ -15,6 +15,10 @@
SM_RCSID("@(#)$Id: stab.c,v 8.92 2013-11-22 20:51:56 ca Exp $")
+#if DANE
+# include <tls.h>
+#endif
+
/*
** STAB -- manage the symbol table
**
@@ -157,13 +161,13 @@ stab(name, type, op)
case ST_LMAP:
len = sizeof(s->s_lmap);
break;
-#endif /* LDAPMAP */
+#endif
#if MILTER
case ST_MILTER:
len = sizeof(s->s_milter);
break;
-#endif /* MILTER */
+#endif
case ST_QUEUE:
len = sizeof(s->s_quegrp);
@@ -173,7 +177,13 @@ stab(name, type, op)
case ST_SOCKETMAP:
len = sizeof(s->s_socketmap);
break;
-#endif /* SOCKETMAP */
+#endif
+
+#if DANE
+ case ST_TLSA_RR:
+ len = sizeof(s->s_tlsa);
+ break;
+#endif
default:
/*
@@ -381,6 +391,15 @@ rmexpstab()
SM_STAB_FREE(s->s_namecanon.nc_cname); /* XXX */
break;
+#if DANE
+ case ST_TLSA_RR:
+ if (s->s_tlsa->dane_tlsa_exp >= now)
+ goto next; /* not expired */
+ (void) dane_tlsa_free(s->s_tlsa);
+ s->s_tlsa = NULL;
+ break;
+#endif /* DANE */
+
default:
if (s->s_symtype >= ST_MCI)
{
@@ -396,7 +415,7 @@ rmexpstab()
#if SASL
/* should always by NULL */
SM_STAB_FREE(s->s_mci.mci_sasl_string);
-#endif /* SASL */
+#endif
if (s->s_mci.mci_rpool != NULL)
{
sm_rpool_free(s->s_mci.mci_rpool);
diff --git a/contrib/sendmail/src/timers.c b/contrib/sendmail/src/timers.c
index 9ceb3a714f7b..5c7e2c7c71ab 100644
--- a/contrib/sendmail/src/timers.c
+++ b/contrib/sendmail/src/timers.c
@@ -38,7 +38,7 @@ warntimer(msg, va_alist)
# if 0
if (!tTd(98, 30))
return;
-# endif /* 0 */
+# endif
SM_VA_START(ap, msg);
(void) sm_vsnprintf(buf, sizeof(buf), msg, ap);
SM_VA_END(ap);
diff --git a/contrib/sendmail/src/tls.c b/contrib/sendmail/src/tls.c
index 40219da382b8..696d32fbb6df 100644
--- a/contrib/sendmail/src/tls.c
+++ b/contrib/sendmail/src/tls.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000-2006, 2008, 2009, 2011, 2013 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 2000-2006, 2008, 2009, 2011, 2013-2016 Proofpoint, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@@ -13,57 +13,53 @@
SM_RCSID("@(#)$Id: tls.c,v 8.127 2013-11-27 02:51:11 gshapiro Exp $")
#if STARTTLS
+# include <tls.h>
# include <openssl/err.h>
# include <openssl/bio.h>
# include <openssl/pem.h>
-# if !NO_DH
-# include <openssl/dh.h>
-# endif /* !NO_DH */
# ifndef HASURANDOMDEV
# include <openssl/rand.h>
-# endif /* ! HASURANDOMDEV */
-# if !TLS_NO_RSA
+# endif
+# include <openssl/engine.h>
+# if _FFR_TLS_ALTNAMES
+# include <openssl/x509v3.h>
+# endif
+
+# if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER <= 0x00907000L
+# ERROR: OpenSSL version OPENSSL_VERSION_NUMBER is unsupported.
+# endif
+
+# if OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x20000000L
+# define MTA_HAVE_DH_set0_pqg 1
+# define MTA_HAVE_DSA_GENERATE_EX 1
+
+# define MTA_HAVE_OPENSSL_init_ssl 1
+# define MTA_ASN1_STRING_data ASN1_STRING_get0_data
+# include <openssl/bn.h>
+# include <openssl/dsa.h>
+# else
+# define X509_STORE_CTX_get0_cert(ctx) (ctx)->cert
+# define MTA_RSA_TMP_CB 1
+# define MTA_ASN1_STRING_data ASN1_STRING_data
+# endif
+
+# if !TLS_NO_RSA && MTA_RSA_TMP_CB
static RSA *rsa_tmp = NULL; /* temporary RSA key */
static RSA *tmp_rsa_key __P((SSL *, int, int));
-# endif /* !TLS_NO_RSA */
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
-static int tls_verify_cb __P((X509_STORE_CTX *));
-# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+# endif
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 */
-# define CONST097 const
-# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
-static void apps_ssl_info_cb __P((CONST097 SSL *, int , int));
+
+static void apps_ssl_info_cb __P((const SSL *, int , int));
static bool tls_ok_f __P((char *, char *, int));
static bool tls_safe_f __P((char *, long, bool));
static int tls_verify_log __P((int, X509_STORE_CTX *, const char *));
-# if !NO_DH
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100001L || \
- (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
-static int
-DH_set0_pqg(dh, p, q, g)
- DH *dh;
- BIGNUM *p;
- BIGNUM *q;
- BIGNUM *g;
-{
- dh->p = p;
- if (q != NULL)
- dh->q = q;
- dh->g = g;
- return 1; /* success */
-}
-# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+int TLSsslidx = -1;
+# if !NO_DH
+# include <openssl/dh.h>
static DH *get_dh512 __P((void));
static unsigned char dh512_p[] =
@@ -83,25 +79,31 @@ static unsigned char dh512_g[] =
static DH *
get_dh512()
{
- DH *dh;
+ DH *dh = NULL;
+# if MTA_HAVE_DH_set0_pqg
BIGNUM *dhp_bn, *dhg_bn;
+# endif
if ((dh = DH_new()) == NULL)
return NULL;
- dhp_bn = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
- dhg_bn = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
- if ((dhp_bn == NULL) || (dhg_bn == NULL))
- {
+# if MTA_HAVE_DH_set0_pqg
+ dhp_bn = BN_bin2bn(dh512_p, sizeof (dh512_p), NULL);
+ dhg_bn = BN_bin2bn(dh512_g, sizeof (dh512_g), NULL);
+ if (dhp_bn == NULL || dhg_bn == NULL || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
DH_free(dh);
BN_free(dhp_bn);
BN_free(dhg_bn);
return NULL;
}
- if (!DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn))
+# else
+ dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
+ dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
{
DH_free(dh);
return NULL;
}
+# endif
return dh;
}
@@ -122,7 +124,7 @@ oK0jjSXgFyeU4/NfyA+zuNeWzUL6bHmigwIBAg==
static DH *
get_dh2048()
{
- static unsigned char dh2048_p[] = {
+ static unsigned char dh2048_p[]={
0xAC,0x37,0x20,0x70,0xBA,0x71,0x12,0x4B,0x10,0x1C,0xF9,0x68,
0x95,0x12,0x82,0x50,0x9D,0xAC,0xCC,0xA4,0x73,0x8A,0xC7,0x96,
0x57,0xD7,0x14,0x49,0x03,0x59,0x1B,0x1A,0x06,0xC3,0xB2,0xA4,
@@ -146,27 +148,33 @@ get_dh2048()
0xE3,0xF3,0x5F,0xC8,0x0F,0xB3,0xB8,0xD7,0x96,0xCD,0x42,0xFA,
0x6C,0x79,0xA2,0x83,
};
- static unsigned char dh2048_g[] = { 0x02, };
+ static unsigned char dh2048_g[]={ 0x02, };
DH *dh;
+# if MTA_HAVE_DH_set0_pqg
BIGNUM *dhp_bn, *dhg_bn;
-
- if ((dh = DH_new()) == NULL)
- return NULL;
- dhp_bn = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
- dhg_bn = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
- if ((dhp_bn == NULL) || (dhg_bn == NULL))
- {
+# endif
+
+ if ((dh=DH_new()) == NULL)
+ return(NULL);
+# if MTA_HAVE_DH_set0_pqg
+ dhp_bn = BN_bin2bn(dh2048_p, sizeof (dh2048_p), NULL);
+ dhg_bn = BN_bin2bn(dh2048_g, sizeof (dh2048_g), NULL);
+ if (dhp_bn == NULL || dhg_bn == NULL || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {
DH_free(dh);
BN_free(dhp_bn);
BN_free(dhg_bn);
return NULL;
}
- if (!DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn))
+# else
+ dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+ dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
{
DH_free(dh);
- return NULL;
+ return(NULL);
}
- return dh;
+# endif
+ return(dh);
}
# endif /* !NO_DH */
@@ -221,7 +229,7 @@ tls_rand_init(randfile, logl)
ok = false;
done = RI_FAIL;
randdef = (randfile == NULL || *randfile == '\0') ? RF_MISS : RF_OK;
-# if EGD
+# if EGD
if (randdef == RF_OK && sm_strncasecmp(randfile, "egd:", 4) == 0)
{
randfile += 4;
@@ -235,7 +243,7 @@ tls_rand_init(randfile, logl)
ok = true;
}
else
-# endif /* EGD */
+# endif /* EGD */
if (randdef == RF_OK && sm_strncasecmp(randfile, "file:", 5) == 0)
{
int fd;
@@ -365,25 +373,46 @@ tls_rand_init(randfile, logl)
** fipsmode -- use FIPS?
**
** Returns:
-** succeeded?
+** 0: OK
+** <0: perm.fail
+** >0: fail but can continue
*/
-bool
+int
init_tls_library(fipsmode)
bool fipsmode;
{
bool bv;
+ /*
+ ** OPENSSL_init_ssl(3): "As of version 1.1.0 OpenSSL will
+ ** automatically allocate all resources that it needs
+ ** so no explicit initialisation is required."
+ */
+
+# if !MTA_HAVE_OPENSSL_init_ssl
/* basic TLS initialization, ignore result for now */
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
-# if 0
- /* this is currently a macro for SSL_library_init */
- SSLeay_add_ssl_algorithms();
-# endif /* 0 */
+# endif
- bv = tls_rand_init(RandFile, 7);
+ bv = true;
+ if (TLSsslidx < 0)
+ {
+ TLSsslidx = SSL_get_ex_new_index(0, 0, 0, 0, 0);
+ if (TLSsslidx < 0)
+ {
+ if (LogLevel > 0)
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=init, SSL_get_ex_new_index=%d",
+ TLSsslidx);
+ bv = false;
+ }
+ }
+
+ if (bv)
+ bv = tls_rand_init(RandFile, 7);
# if _FFR_FIPSMODE
if (bv && fipsmode)
{
@@ -396,7 +425,7 @@ init_tls_library(fipsmode)
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=init, FIPSMode=%s",
ERR_error_string(err, NULL));
- return false;
+ return -1;
}
else
{
@@ -404,8 +433,20 @@ init_tls_library(fipsmode)
sm_syslog(LOG_INFO, NOQID,
"STARTTLS=init, FIPSMode=ok");
}
+ if (CertFingerprintAlgorithm == NULL)
+ CertFingerprintAlgorithm = "sha1";
}
-#endif /* _FFR_FIPSMODE */
+# endif /* _FFR_FIPSMODE */
+
+ if (!TLS_set_engine(SSLEngine, true))
+ {
+ if (LogLevel > 0)
+ sm_syslog(LOG_ERR, NOQID,
+ "STARTTLS=init, engine=%s, TLS_set_engine=failed",
+ SSLEngine);
+ return -1;
+ }
+
if (bv && CertFingerprintAlgorithm != NULL)
{
const EVP_MD *md;
@@ -422,7 +463,7 @@ init_tls_library(fipsmode)
else
EVP_digest = md;
}
- return bv;
+ return bv ? 0 : 1;
}
/*
@@ -430,7 +471,7 @@ init_tls_library(fipsmode)
**
** Parameters:
** ctx -- TLS context
-** ssl -- TLS structure
+** ssl -- TLS session context
** vrfy -- request certificate?
**
** Returns:
@@ -456,10 +497,10 @@ tls_set_verify(ctx, ssl, vrfy)
{
# if !TLS_VRFY_PER_CTX
SSL_set_verify(ssl, vrfy ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL);
-# else /* !TLS_VRFY_PER_CTX */
+# else
SSL_CTX_set_verify(ctx, vrfy ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
NULL);
-# endif /* !TLS_VRFY_PER_CTX */
+# endif
}
/*
@@ -585,6 +626,7 @@ tls_safe_f(var, sff, srv)
** Returns:
** 0/SFF_NORFILES
*/
+
# define TLS_UNR(bit, req) (bitset(bit, req) ? SFF_NORFILES : 0)
# define TLS_OUNR(bit, req) (bitset(bit, req) ? SFF_NOWRFILES : 0)
# define TLS_KEYSFF(req) \
@@ -617,12 +659,12 @@ tls_safe_f(var, sff, srv)
ok = false; \
}
-# if _FFR_TLS_SE_OPTS
/*
** LOAD_CERTKEY -- load cert/key for TLS session
**
** Parameters:
** ssl -- TLS session context
+** srv -- server side?
** certfile -- filename of certificate
** keyfile -- filename of private key
**
@@ -678,8 +720,7 @@ load_certkey(ssl, srv, certfile, keyfile)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: %s(%s) failed",
who, SSL_USE_CERT, certfile);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
if (bitset(TLS_I_USE_CERT, req))
return false;
@@ -692,8 +733,7 @@ load_certkey(ssl, srv, certfile, keyfile)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_use_PrivateKey_file(%s) failed",
who, keyfile);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
if (bitset(TLS_I_USE_KEY, req))
return false;
@@ -709,8 +749,7 @@ load_certkey(ssl, srv, certfile, keyfile)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_check_private_key failed(%s): %d",
who, keyfile, r);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
if (bitset(TLS_I_USE_KEY, req))
return false;
@@ -718,7 +757,143 @@ load_certkey(ssl, srv, certfile, keyfile)
return true;
}
-# endif /* _FFR_TLS_SE_OPTS */
+
+/*
+** LOAD_CRLFILE -- load a file holding a CRL into the TLS context
+**
+** Parameters:
+** ctx -- TLS context
+** srv -- server side?
+** filename -- filename of CRL
+**
+** Returns:
+** succeeded?
+*/
+
+static bool load_crlfile __P((SSL_CTX *, bool, char *));
+
+static bool
+load_crlfile(ctx, srv, filename)
+ SSL_CTX *ctx;
+ bool srv;
+ char *filename;
+{
+ char *who;
+ BIO *crl_file;
+ X509_CRL *crl;
+ X509_STORE *store;
+
+ who = srv ? "server" : "client";
+ crl_file = BIO_new(BIO_s_file());
+ if (crl_file == NULL)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: BIO_new=failed", who);
+ return false;
+ }
+
+ if (BIO_read_filename(crl_file, filename) < 0)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: BIO_read_filename(%s)=failed",
+ who, filename);
+
+ /* avoid memory leaks */
+ BIO_free(crl_file);
+ return false;
+ }
+
+ crl = PEM_read_bio_X509_CRL(crl_file, NULL, NULL, NULL);
+ if (crl == NULL)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: PEM_read_bio_X509_CRL(%s)=failed",
+ who, filename);
+ BIO_free(crl_file);
+ return true; /* XXX should probably be 'false' */
+ }
+
+ BIO_free(crl_file);
+
+ /* get a pointer to the current certificate validation store */
+ store = SSL_CTX_get_cert_store(ctx); /* does not fail */
+
+ if (X509_STORE_add_crl(store, crl) == 0)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: X509_STORE_add_crl=failed",
+ who);
+ X509_CRL_free(crl);
+ return false;
+ }
+
+ 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);
+
+ return true;
+}
+
+/*
+** LOAD_CRLPATH -- configure the TLS context to lookup CRLs in a directory
+**
+** Parameters:
+** ctx -- TLS context
+** srv -- server side?
+** path -- path of hashed directory of CRLs
+**
+** Returns:
+** succeeded?
+*/
+
+static bool load_crlpath __P((SSL_CTX *, bool, char *));
+
+static bool
+load_crlpath(ctx, srv, path)
+ SSL_CTX *ctx;
+ bool srv;
+ char *path;
+{
+ char *who;
+ X509_STORE *store;
+ X509_LOOKUP *lookup;
+
+ who = srv ? "server" : "client";
+
+ /* get a pointer to the current certificate validation store */
+ store = SSL_CTX_get_cert_store(ctx); /* does not fail */
+
+ 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);
+ return false;
+ }
+
+ if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) == 0)
+ {
+ if (LogLevel > 9)
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, error: X509_LOOKUP_add_dir(%s)=failed",
+ who, path);
+ return false;
+ }
+
+ 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);
+
+ return true;
+}
/*
** INITTLS -- initialize TLS
@@ -747,35 +922,12 @@ load_certkey(ssl, srv, certfile, keyfile)
static char server_session_id_context[] = "sendmail8";
-# if !TLS_NO_RSA
-static RSA *
-sm_RSA_generate_key(num, e)
- int num;
- unsigned long e;
-{
- RSA *rsa = NULL;
- BIGNUM *bn_rsa_r4;
-
- bn_rsa_r4 = BN_new();
- if ((bn_rsa_r4 != NULL) && BN_set_word(bn_rsa_r4, e) && (rsa = RSA_new()) != NULL)
- {
- if (!RSA_generate_key_ex(rsa, num, bn_rsa_r4, NULL))
- {
- RSA_free(rsa);
- rsa = NULL;
- }
- }
- BN_free(bn_rsa_r4);
- return rsa;
-}
-# endif /* !TLS_NO_RSA */
-
/* 0.9.8a and b have a problem with SSL_OP_TLS_BLOCK_PADDING_BUG */
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
-# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG 1
-#else
-# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG 0
-#endif
+# if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
+# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG 1
+# else
+# define SM_SSL_OP_TLS_BLOCK_PADDING_BUG 0
+# endif
bool
inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhparam)
@@ -787,24 +939,19 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
{
# if !NO_DH
static DH *dh = NULL;
-# endif /* !NO_DH */
+# endif
int r;
bool ok;
long sff, status;
char *who;
char *cf2, *kf2;
-# if SM_CONF_SHM
+# if SM_CONF_SHM && !TLS_NO_RSA && MTA_RSA_TMP_CB
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 */
-#if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
+# endif
+# if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
long rt_version;
STACK_OF(SSL_COMP) *comp_methods;
-#endif
+# endif
status = TLS_S_NONE;
who = srv ? "server" : "client";
@@ -852,10 +999,8 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
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 the second file is specified it must exist
@@ -883,7 +1028,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
** /file/name read parameters from /file/name
*/
-#define SET_DH_DFL \
+# define SET_DH_DFL \
do { \
dhparam = "I"; \
req |= TLS_I_DHFIXED; \
@@ -950,11 +1095,9 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if (!bitset(TLS_S_DHPAR_OK, status))
SET_DH_DFL;
}
-# 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 (cf2 != NULL)
@@ -978,82 +1121,57 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_CTX_new(SSLv23_%s_method()) failed",
who, who);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
return false;
}
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
- if (CRLFile != NULL)
+# if _FFR_VRFY_TRUSTED_FIRST
+ if (!tTd(88, 101))
{
+ X509_STORE *store;
+
/* 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());
- 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);
- }
+ SM_ASSERT(store != NULL);
+ X509_STORE_set_flags(store, X509_V_FLAG_TRUSTED_FIRST);
+ }
+# endif
- /* avoid memory leaks */
- BIO_free(crl_file);
- return false;
- }
+ if (CRLFile != NULL && !load_crlfile(*ctx, srv, CRLFile))
+ return false;
+ if (CRLPath != NULL && !load_crlpath(*ctx, srv, CRLPath))
+ return false;
- }
- else if (LogLevel > 9)
+# if defined(SSL_MODE_AUTO_RETRY) && OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x20000000L
+ /*
+ * Turn off blocking I/O handling in OpenSSL: someone turned
+ * this on by default in 1.1? should we check first?
+ */
+# if _FFR_TESTS
+ if (LogLevel > 9) {
+ sff = SSL_CTX_get_mode(*ctx);
+ if (sff & SSL_MODE_AUTO_RETRY)
sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, error: BIO_new=failed", who);
+ "STARTTLS=%s, SSL_MODE_AUTO_RETRY=set, mode=%#lx",
+ who, sff);
}
+
+ /* hack for testing! */
+ if (tTd(96, 101) || getenv("SSL_MODE_AUTO_RETRY") != NULL)
+ SSL_CTX_set_mode(*ctx, SSL_MODE_AUTO_RETRY);
else
- store = NULL;
-# if _FFR_CRLPATH
- if (CRLPath != NULL && store != NULL)
- {
- X509_LOOKUP *lookup;
+# endif
+ SSL_CTX_clear_mode(*ctx, SSL_MODE_AUTO_RETRY);
+# endif /* defined(SSL_MODE_AUTO_RETRY) && OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x20000000L */
- 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);
-# endif /* TLS_NO_RSA */
+# endif
-# if !TLS_NO_RSA
+# if !TLS_NO_RSA && MTA_RSA_TMP_CB
/*
** Create a temporary RSA key
** XXX Maybe we shouldn't create this always (even though it
@@ -1065,7 +1183,8 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if (bitset(TLS_I_RSA_TMP, req)
# if SM_CONF_SHM
&& ShmId != SM_SHM_NO_ID &&
- (rsa_tmp = sm_RSA_generate_key(RSA_KEYLENGTH, RSA_F4)) == NULL
+ (rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL,
+ NULL)) == NULL
# else /* SM_CONF_SHM */
&& 0 /* no shared memory: no need to generate key now */
# endif /* SM_CONF_SHM */
@@ -1076,12 +1195,11 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: RSA_generate_key failed",
who);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
return false;
}
-# endif /* !TLS_NO_RSA */
+# endif /* !TLS_NO_RSA && MTA_RSA_TMP_CB */
/*
** load private key
@@ -1097,22 +1215,21 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_CTX_use_PrivateKey_file(%s) failed",
who, keyfile);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
if (bitset(TLS_I_USE_KEY, req))
return false;
}
-#if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
-# define SSL_CTX_use_cert(ssl_ctx, certfile) \
+# if _FFR_TLS_USE_CERTIFICATE_CHAIN_FILE
+# define SSL_CTX_use_cert(ssl_ctx, certfile) \
SSL_CTX_use_certificate_chain_file(ssl_ctx, certfile)
-# define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_chain_file"
-#else
-# define SSL_CTX_use_cert(ssl_ctx, certfile) \
+# define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_chain_file"
+# else
+# define SSL_CTX_use_cert(ssl_ctx, certfile) \
SSL_CTX_use_certificate_file(ssl_ctx, certfile, SSL_FILETYPE_PEM)
-# define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_file"
-#endif
+# define SSL_CTX_USE_CERT "SSL_CTX_use_certificate_file"
+# endif
/* get the certificate file */
if (bitset(TLS_S_CERT_OK, status) &&
@@ -1123,8 +1240,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: %s(%s) failed",
who, SSL_CTX_USE_CERT, certfile);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
if (bitset(TLS_I_USE_CERT, req))
return false;
@@ -1140,8 +1256,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_CTX_check_private_key failed(%s): %d",
who, keyfile, r);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
if (bitset(TLS_I_USE_KEY, req))
return false;
@@ -1158,8 +1273,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_CTX_use_PrivateKey_file(%s) failed",
who, kf2);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
}
@@ -1172,8 +1286,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: %s(%s) failed",
who, SSL_CTX_USE_CERT, cf2);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
}
@@ -1187,14 +1300,13 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: SSL_CTX_check_private_key 2 failed: %d",
who, r);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
}
/* SSL_CTX_set_quiet_shutdown(*ctx, 1); violation of standard? */
-#if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
+# if SM_SSL_OP_TLS_BLOCK_PADDING_BUG
/*
** In OpenSSL 0.9.8[ab], enabling zlib compression breaks the
@@ -1206,23 +1318,23 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
** just the compile time version.
*/
- rt_version = SSLeay();
+ rt_version = TLS_version_num();
if (rt_version >= 0x00908000L && rt_version <= 0x0090802fL)
{
comp_methods = SSL_COMP_get_compression_methods();
if (comp_methods != NULL && sk_SSL_COMP_num(comp_methods) > 0)
options &= ~SSL_OP_TLS_BLOCK_PADDING_BUG;
}
-#endif
+# endif
SSL_CTX_set_options(*ctx, (long) options);
# if !NO_DH
/* Diffie-Hellman initialization */
if (bitset(TLS_I_TRY_DH, req))
{
-#if _FFR_TLS_EC
+# if TLS_EC == 1
EC_KEY *ecdh;
-#endif /* _FFR_TLS_EC */
+# endif
if (tTd(96, 8))
sm_dprintf("inittls: req=%#lx, status=%#lx\n",
@@ -1244,8 +1356,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
"STARTTLS=%s, error: cannot read DH parameters(%s): %s",
who, dhparam,
ERR_error_string(err, NULL));
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
SET_DH_DFL;
}
}
@@ -1256,8 +1367,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: BIO_new_file(%s) failed",
who, dhparam);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
}
}
@@ -1270,11 +1380,21 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if (tTd(96, 2))
sm_dprintf("inittls: Generating %d bit DH parameters\n", bits);
+# if MTA_HAVE_DSA_GENERATE_EX
dsa = DSA_new();
+ if (dsa != NULL)
+ {
+ r = DSA_generate_parameters_ex(dsa, bits, NULL,
+ 0, NULL, NULL, NULL);
+ if (r != 0)
+ dh = DSA_dup_DH(dsa);
+ }
+# else
/* this takes a while! */
- (void)DSA_generate_parameters_ex(dsa, bits, NULL, 0,
- NULL, NULL, NULL);
+ dsa = DSA_generate_parameters(bits, NULL, 0, NULL,
+ NULL, 0, NULL);
dh = DSA_dup_DH(dsa);
+# endif
DSA_free(dsa);
}
else if (dh == NULL && bitset(TLS_I_DHFIXED, req))
@@ -1318,7 +1438,10 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
DH_free(dh);
}
-#if _FFR_TLS_EC
+# if TLS_EC == 2
+ SSL_CTX_set_options(*ctx, SSL_OP_SINGLE_ECDH_USE);
+ SSL_CTX_set_ecdh_auto(*ctx, 1);
+# elif TLS_EC == 1
ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
if (ecdh != NULL)
{
@@ -1326,7 +1449,13 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
SSL_CTX_set_tmp_ecdh(*ctx, ecdh);
EC_KEY_free(ecdh);
}
-#endif /* _FFR_TLS_EC */
+ else if (LogLevel > 9)
+ {
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)=failed, error=%s",
+ who, ERR_error_string(ERR_get_error(), NULL));
+ }
+# endif /* TLS_EC */
}
# endif /* !NO_DH */
@@ -1355,10 +1484,10 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
if ((r = SSL_CTX_load_verify_locations(*ctx, cacertfile,
cacertpath)) == 1)
{
-# if !TLS_NO_RSA
+# if !TLS_NO_RSA && MTA_RSA_TMP_CB
if (bitset(TLS_I_RSA_TMP, req))
SSL_CTX_set_tmp_rsa_callback(*ctx, tmp_rsa_key);
-# endif /* !TLS_NO_RSA */
+# endif
/*
** We have to install our own verify callback:
@@ -1374,16 +1503,19 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
** but we hope that that function will later on
** only set the mode per connection.
*/
+
SSL_CTX_set_verify(*ctx,
bitset(TLS_I_NO_VRFY, req) ? SSL_VERIFY_NONE
: SSL_VERIFY_PEER,
NULL);
- /* install verify callback */
+ if (srv)
+ {
+ SSL_CTX_set_client_CA_list(*ctx,
+ SSL_load_client_CA_file(cacertfile));
+ }
SSL_CTX_set_cert_verify_callback(*ctx, tls_verify_cb,
- NULL);
- SSL_CTX_set_client_CA_list(*ctx,
- SSL_load_client_CA_file(cacertfile));
+ NULL);
}
else
{
@@ -1393,13 +1525,15 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
** which in turn would be necessary
** if we want to allow relaying based on it.
*/
+
if (LogLevel > 5)
{
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS=%s, error: load verify locs %s, %s failed: %d",
who, cacertpath, cacertfile, r);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING,
+ bitset(TLS_I_VRFY_LOC, req) ? 8 : 9,
+ who);
}
if (bitset(TLS_I_VRFY_LOC, req))
return false;
@@ -1421,8 +1555,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
"STARTTLS=%s, error: SSL_CTX_set_cipher_list(%s) failed, list ignored",
who, CipherList);
- if (LogLevel > 9)
- tlslogerr(LOG_WARNING, who);
+ tlslogerr(LOG_WARNING, 9, who);
}
/* failure if setting to this list is required? */
}
@@ -1454,6 +1587,7 @@ inittls(ctx, req, options, srv, certfile, keyfile, cacertpath, cacertfile, dhpar
**
** Parameters:
** cert -- TLS cert
+** evp_digest -- digest algorithm
** mac -- macro storage
** macro -- where to store cert fp
**
@@ -1494,12 +1628,117 @@ cert_fp(cert, evp_digest, mac, macro)
return 1;
}
+/* host for logging */
+#define whichhost host == NULL ? "local" : host
+
+# if _FFR_TLS_ALTNAMES
+
+/*
+** CLEARCLASS -- clear the specified class (called from stabapply)
+**
+** Parameters:
+** s -- STAB
+** id -- class id
+**
+** Returns:
+** none.
+*/
+
+static void
+clearclass(s, id)
+ STAB *s;
+ int id;
+{
+ if (s->s_symtype != ST_CLASS)
+ return;
+ if (bitnset(bitidx(id), s->s_class))
+ clrbitn(bitidx(id), s->s_class);
+}
+
+/*
+** GETALTNAMES -- set subject_alt_name
+**
+** Parameters:
+** cert -- cert
+** srv -- server side?
+** host -- hostname of other side
+**
+** Returns:
+** none.
+*/
+
+static void
+getaltnames(cert, srv, host)
+ X509 *cert;
+ bool srv;
+ const char *host;
+{
+ STACK_OF(GENERAL_NAME) *gens;
+ int i, j, len, r;
+ const GENERAL_NAME *gn;
+ char *dnsname, *who;
+
+ if (!SetCertAltnames)
+ return;
+ who = srv ? "server" : "client";
+ gens = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
+ if (gens == NULL)
+ return;
+
+ r = sk_GENERAL_NAME_num(gens);
+ for (i = 0; i < r; i++)
+ {
+ gn = sk_GENERAL_NAME_value(gens, i);
+ if (gn == NULL || gn->type != GEN_DNS)
+ continue;
+
+ /* Ensure data is IA5 */
+ if (ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING)
+ {
+ if (LogLevel > 6)
+ sm_syslog(LOG_INFO, NOQID,
+ "STARTTLS=%s, relay=%.100s, field=AltName, status=value contains non IA5",
+ who, whichhost);
+ continue;
+ }
+ dnsname = (char *) MTA_ASN1_STRING_data(gn->d.ia5);
+ if (dnsname == NULL)
+ continue;
+ len = ASN1_STRING_length(gn->d.ia5);
+
+ /*
+ ** "remove" trailing NULs (except for one of course),
+ ** those can happen and are OK (not a sign of an attack)
+ */
+
+ while (len > 0 && '\0' == dnsname[len - 1])
+ len--;
+
+#define ISPRINT(c) (isascii(c) && isprint(c))
+
+ /* just check for printable char for now */
+ for (j = 0; j < len && ISPRINT(dnsname[j]); j++)
+ ;
+ if (dnsname[j] != '\0' || len != j)
+ continue;
+
+ setclass(macid("{cert_altnames}"), xtextify(dnsname, "<>\")"));
+ if (LogLevel > 14)
+ sm_syslog(LOG_DEBUG, NOQID,
+ "STARTTLS=%s, relay=%.100s, AltName=%s",
+ who, whichhost, xtextify(dnsname, "<>\")"));
+ }
+}
+# else
+# define getaltnames(cert, srv, host)
+# endif /* _FFR_TLS_ALTNAMES */
+
/*
** TLS_GET_INFO -- get information about TLS connection
**
** Parameters:
-** ssl -- TLS connection structure
-** srv -- server or client
+** ssl -- TLS session context
+** srv -- server side?
** host -- hostname of other side
** mac -- macro storage
** certreq -- did we ask for a cert?
@@ -1525,6 +1764,9 @@ tls_get_info(ssl, srv, host, mac, certreq)
char *s, *who;
char bitstr[16];
X509 *cert;
+# if DANE
+ dane_vrfy_ctx_P dane_vrfy_ctx;
+# endif
c = SSL_get_current_cipher(ssl);
@@ -1548,6 +1790,9 @@ tls_get_info(ssl, srv, host, mac, certreq)
sm_syslog(LOG_INFO, NOQID,
"STARTTLS=%s, get_verify: %ld get_peer: 0x%lx",
who, verifyok, (unsigned long) cert);
+# if _FFR_TLS_ALTNAMES
+ stabapply(clearclass, macid("{cert_altnames}"));
+# endif
if (cert != NULL)
{
X509_NAME *subj, *issuer;
@@ -1562,7 +1807,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
macdefine(mac, A_TEMP, macid("{cert_issuer}"),
xtextify(buf, "<>\")"));
-# define LL_BADCERT 8
+# define LL_BADCERT 8
#define CERTFPMACRO (CertFingerprintAlgorithm != NULL ? "{cert_fp}" : "{cert_md5}")
@@ -1574,9 +1819,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
if (LogLevel > LL_BADCERT) \
sm_syslog(LOG_INFO, NOQID, \
"STARTTLS=%s, relay=%.100s, field=%s, status=failed to extract CN", \
- who, \
- host == NULL ? "local" : host, \
- which); \
+ who, whichhost, which); \
} \
else if ((size_t)r >= sizeof(buf) - 1) \
{ \
@@ -1584,9 +1827,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
if (LogLevel > 7) \
sm_syslog(LOG_INFO, NOQID, \
"STARTTLS=%s, relay=%.100s, field=%s, status=CN too long", \
- who, \
- host == NULL ? "local" : host, \
- which); \
+ who, whichhost, which); \
} \
else if ((size_t)r > strlen(buf)) \
{ \
@@ -1595,9 +1836,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
if (LogLevel > 7) \
sm_syslog(LOG_INFO, NOQID, \
"STARTTLS=%s, relay=%.100s, field=%s, status=CN contains NUL", \
- who, \
- host == NULL ? "local" : host, \
- which); \
+ who, whichhost, which); \
} \
} while (0)
@@ -1612,6 +1851,7 @@ tls_get_info(ssl, srv, host, mac, certreq)
macdefine(mac, A_TEMP, macid("{cn_issuer}"),
xtextify(buf, "<>\")"));
(void) cert_fp(cert, EVP_digest, mac, CERTFPMACRO);
+ getaltnames(cert, srv, host);
}
else
{
@@ -1621,6 +1861,30 @@ tls_get_info(ssl, srv, host, mac, certreq)
macdefine(mac, A_PERM, macid("{cn_issuer}"), "");
macdefine(mac, A_TEMP, macid(CERTFPMACRO), "");
}
+# if DANE
+ dane_vrfy_ctx = NULL;
+ if (TLSsslidx >= 0)
+ {
+ tlsi_ctx_T *tlsi_ctx;
+
+ tlsi_ctx = (tlsi_ctx_P) SSL_get_ex_data(ssl, TLSsslidx);
+ if (tlsi_ctx != NULL)
+ dane_vrfy_ctx = &(tlsi_ctx->tlsi_dvc);
+ }
+# define DANE_VRFY_RES_IS(r) \
+ ((dane_vrfy_ctx != NULL) && dane_vrfy_ctx->dane_vrfy_res == (r))
+ if (DANE_VRFY_RES_IS(DANE_VRFY_OK))
+ {
+ s = "TRUSTED";
+ r = TLS_AUTH_OK;
+ }
+ else if (DANE_VRFY_RES_IS(DANE_VRFY_FAIL))
+ {
+ s = "DANE_FAIL";
+ r = TLS_AUTH_FAIL;
+ }
+ else
+# endif /* if DANE */
switch (verifyok)
{
case X509_V_OK:
@@ -1655,14 +1919,25 @@ tls_get_info(ssl, srv, host, mac, certreq)
s1 = macget(mac, macid("{verify}"));
s2 = macget(mac, macid("{cipher}"));
+# if DANE
+# define LOG_DANE_FP \
+ ('\0' != dane_vrfy_ctx->dane_vrfy_fp[0] && DANE_VRFY_RES_IS(DANE_VRFY_FAIL))
+# endif
/* XXX: maybe cut off ident info? */
sm_syslog(LOG_INFO, NOQID,
- "STARTTLS=%s, relay=%.100s, version=%.16s, verify=%.16s, cipher=%.64s, bits=%.6s/%.6s",
+ "STARTTLS=%s, relay=%.100s, version=%.16s, verify=%.16s, cipher=%.64s, bits=%.6s/%.6s%s%s",
who,
host == NULL ? "local" : host,
vers, s1, s2, /* sm_snprintf() can deal with NULL */
algbits == NULL ? "0" : algbits,
- cbits == NULL ? "0" : cbits);
+ cbits == NULL ? "0" : cbits
+# if DANE
+ , LOG_DANE_FP ? ", pubkey_fp=" : ""
+ , LOG_DANE_FP ? dane_vrfy_ctx->dane_vrfy_fp : ""
+# else
+ , "", ""
+# endif
+ );
if (LogLevel > 11)
{
/*
@@ -1682,101 +1957,101 @@ tls_get_info(ssl, srv, host, mac, certreq)
}
return r;
}
+
/*
** ENDTLS -- shutdown secure connection
**
** Parameters:
-** ssl -- SSL connection information.
-** side -- server/client (for logging).
+** pssl -- pointer to TLS session context
+** who -- server/client (for logging).
**
** Returns:
** success? (EX_* code)
*/
int
-endtls(ssl, side)
- SSL *ssl;
- char *side;
+endtls(pssl, who)
+ SSL **pssl;
+ const char *who;
{
- int ret = EX_OK;
+ SSL *ssl;
+ int ret, r;
- if (ssl != NULL)
- {
- int r;
+ SM_REQUIRE(pssl != NULL);
+ ret = EX_OK;
+ ssl = *pssl;
+ if (ssl == NULL)
+ return ret;
- if ((r = SSL_shutdown(ssl)) < 0)
+ if ((r = SSL_shutdown(ssl)) < 0)
+ {
+ if (LogLevel > 11)
{
- if (LogLevel > 11)
- {
- sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, SSL_shutdown failed: %d",
- side, r);
- tlslogerr(LOG_WARNING, side);
- }
- ret = EX_SOFTWARE;
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, SSL_shutdown failed: %d",
+ who, r);
+ tlslogerr(LOG_WARNING, 11, who);
}
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL
+ ret = EX_SOFTWARE;
+ }
- /*
- ** Bug in OpenSSL (at least up to 0.9.6b):
- ** From: Lutz.Jaenicke@aet.TU-Cottbus.DE
- ** Message-ID: <20010723152244.A13122@serv01.aet.tu-cottbus.de>
- ** To: openssl-users@openssl.org
- ** Subject: Re: SSL_shutdown() woes (fwd)
- **
- ** The side sending the shutdown alert first will
- ** not care about the answer of the peer but will
- ** immediately return with a return value of "0"
- ** (ssl/s3_lib.c:ssl3_shutdown()). SSL_get_error will evaluate
- ** the value of "0" and as the shutdown alert of the peer was
- ** not received (actually, the program did not even wait for
- ** the answer), an SSL_ERROR_SYSCALL is flagged, because this
- ** is the default rule in case everything else does not apply.
- **
- ** For your server the problem is different, because it
- ** receives the shutdown first (setting SSL_RECEIVED_SHUTDOWN),
- ** then sends its response (SSL_SENT_SHUTDOWN), so for the
- ** server the shutdown was successfull.
- **
- ** As is by know, you would have to call SSL_shutdown() once
- ** and ignore an SSL_ERROR_SYSCALL returned. Then call
- ** SSL_shutdown() again to actually get the server's response.
- **
- ** In the last discussion, Bodo Moeller concluded that a
- ** rewrite of the shutdown code would be necessary, but
- ** probably with another API, as the change would not be
- ** compatible to the way it is now. Things do not become
- ** easier as other programs do not follow the shutdown
- ** guidelines anyway, so that a lot error conditions and
- ** compitibility issues would have to be caught.
- **
- ** For now the recommondation is to ignore the error message.
- */
+ /*
+ ** Bug in OpenSSL (at least up to 0.9.6b):
+ ** From: Lutz.Jaenicke@aet.TU-Cottbus.DE
+ ** Message-ID: <20010723152244.A13122@serv01.aet.tu-cottbus.de>
+ ** To: openssl-users@openssl.org
+ ** Subject: Re: SSL_shutdown() woes (fwd)
+ **
+ ** The side sending the shutdown alert first will
+ ** not care about the answer of the peer but will
+ ** immediately return with a return value of "0"
+ ** (ssl/s3_lib.c:ssl3_shutdown()). SSL_get_error will evaluate
+ ** the value of "0" and as the shutdown alert of the peer was
+ ** not received (actually, the program did not even wait for
+ ** the answer), an SSL_ERROR_SYSCALL is flagged, because this
+ ** is the default rule in case everything else does not apply.
+ **
+ ** For your server the problem is different, because it
+ ** receives the shutdown first (setting SSL_RECEIVED_SHUTDOWN),
+ ** then sends its response (SSL_SENT_SHUTDOWN), so for the
+ ** server the shutdown was successful.
+ **
+ ** As is by know, you would have to call SSL_shutdown() once
+ ** and ignore an SSL_ERROR_SYSCALL returned. Then call
+ ** SSL_shutdown() again to actually get the server's response.
+ **
+ ** In the last discussion, Bodo Moeller concluded that a
+ ** rewrite of the shutdown code would be necessary, but
+ ** probably with another API, as the change would not be
+ ** compatible to the way it is now. Things do not become
+ ** easier as other programs do not follow the shutdown
+ ** guidelines anyway, so that a lot error conditions and
+ ** compitibility issues would have to be caught.
+ **
+ ** For now the recommondation is to ignore the error message.
+ */
- else if (r == 0)
+ else if (r == 0)
+ {
+ if (LogLevel > 15)
{
- if (LogLevel > 15)
- {
- sm_syslog(LOG_WARNING, NOQID,
- "STARTTLS=%s, SSL_shutdown not done",
- side);
- tlslogerr(LOG_WARNING, side);
- }
- ret = EX_SOFTWARE;
+ sm_syslog(LOG_WARNING, NOQID,
+ "STARTTLS=%s, SSL_shutdown not done",
+ who);
+ tlslogerr(LOG_WARNING, 15, who);
}
-# endif /* !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER > 0x0090602fL */
- SSL_free(ssl);
- ssl = NULL;
+ ret = EX_SOFTWARE;
}
+ SM_SSL_FREE(*pssl);
return ret;
}
-# if !TLS_NO_RSA
+# if !TLS_NO_RSA && MTA_RSA_TMP_CB
/*
** TMP_RSA_KEY -- return temporary RSA key
**
** Parameters:
-** s -- TLS connection structure
+** ssl -- TLS session context
** export --
** keylength --
**
@@ -1784,9 +2059,9 @@ endtls(ssl, side)
** temporary RSA key.
*/
-# ifndef MAX_RSA_TMP_CNT
-# define MAX_RSA_TMP_CNT 1000 /* XXX better value? */
-# endif /* ! MAX_RSA_TMP_CNT */
+# ifndef MAX_RSA_TMP_CNT
+# define MAX_RSA_TMP_CNT 1000 /* XXX better value? */
+# endif
/* ARGUSED0 */
static RSA *
@@ -1795,18 +2070,18 @@ tmp_rsa_key(s, export, keylength)
int export;
int keylength;
{
-# if SM_CONF_SHM
+# if SM_CONF_SHM
extern int ShmId;
extern int *PRSATmpCnt;
if (ShmId != SM_SHM_NO_ID && rsa_tmp != NULL &&
++(*PRSATmpCnt) < MAX_RSA_TMP_CNT)
return rsa_tmp;
-# endif /* SM_CONF_SHM */
+# endif /* SM_CONF_SHM */
if (rsa_tmp != NULL)
RSA_free(rsa_tmp);
- rsa_tmp = sm_RSA_generate_key(RSA_KEYLENGTH, RSA_F4);
+ rsa_tmp = RSA_generate_key(RSA_KEYLENGTH, RSA_F4, NULL, NULL);
if (rsa_tmp == NULL)
{
if (LogLevel > 0)
@@ -1815,32 +2090,33 @@ tmp_rsa_key(s, export, keylength)
}
else
{
-# if SM_CONF_SHM
-# if 0
+# if SM_CONF_SHM
+# if 0
/*
** XXX we can't (yet) share the new key...
** The RSA structure contains pointers hence it can't be
** easily kept in shared memory. It must be transformed
- ** into a continous memory region first, then stored,
+ ** into a continuous memory region first, then stored,
** and later read out again (each time re-transformed).
*/
if (ShmId != SM_SHM_NO_ID)
*PRSATmpCnt = 0;
-# endif /* 0 */
-# endif /* SM_CONF_SHM */
+# endif /* 0 */
+# endif /* SM_CONF_SHM */
if (LogLevel > 9)
sm_syslog(LOG_ERR, NOQID,
"STARTTLS=server, tmp_rsa_key: new temp RSA key");
}
return rsa_tmp;
}
-# endif /* !TLS_NO_RSA */
+# endif /* !TLS_NO_RSA && MTA_RSA_TMP_CB */
+
/*
** APPS_SSL_INFO_CB -- info callback for TLS connections
**
** Parameters:
-** s -- TLS connection structure
+** ssl -- TLS session context
** where -- state in handshake
** ret -- return code of last operation
**
@@ -1849,8 +2125,8 @@ tmp_rsa_key(s, export, keylength)
*/
static void
-apps_ssl_info_cb(s, where, ret)
- CONST097 SSL *s;
+apps_ssl_info_cb(ssl, where, ret)
+ const SSL *ssl;
int where;
int ret;
{
@@ -1879,7 +2155,7 @@ apps_ssl_info_cb(s, where, ret)
if (LogLevel > 12)
sm_syslog(LOG_NOTICE, NOQID,
"STARTTLS: %s:%s",
- str, SSL_state_string_long(s));
+ str, SSL_state_string_long(ssl));
}
else if (bitset(SSL_CB_ALERT, where))
{
@@ -1897,23 +2173,24 @@ apps_ssl_info_cb(s, where, ret)
if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS: %s:failed in %s",
- str, SSL_state_string_long(s));
+ str, SSL_state_string_long(ssl));
}
else if (ret < 0)
{
if (LogLevel > 7)
sm_syslog(LOG_WARNING, NOQID,
"STARTTLS: %s:error in %s",
- str, SSL_state_string_long(s));
+ str, SSL_state_string_long(ssl));
}
}
}
+
/*
** TLS_VERIFY_LOG -- log verify error for TLS certificates
**
** Parameters:
** ok -- verify ok?
-** ctx -- x509 context
+** ctx -- X509 context
** name -- from where is this called?
**
** Returns:
@@ -1941,10 +2218,203 @@ tls_verify_log(ok, ctx, name)
}
/*
+** Declaration and access to tlsi_ctx in callbacks.
+** Currently only used in one of them.
+*/
+
+#define SM_DECTLSI \
+ tlsi_ctx_T *tlsi_ctx; \
+ SSL *ssl
+#define SM_GETTLSI \
+ do { \
+ tlsi_ctx = NULL; \
+ if (TLSsslidx >= 0) \
+ { \
+ ssl = (SSL *) X509_STORE_CTX_get_ex_data(ctx, \
+ SSL_get_ex_data_X509_STORE_CTX_idx()); \
+ if (ssl != NULL) \
+ tlsi_ctx = (tlsi_ctx_P) SSL_get_ex_data(ssl, TLSsslidx); \
+ } \
+ } \
+ while (0)
+
+
+# if DANE
+
+/*
+** DANE_GET_TLSA -- Retrieve TLSA RR for DANE
+**
+** Parameters:
+** dane -- dane verify context
+**
+** Returns:
+** dane_tlsa if TLSA RR is available
+** NULL otherwise
+*/
+
+dane_tlsa_P
+dane_get_tlsa(dane_vrfy_ctx)
+ dane_vrfy_ctx_P dane_vrfy_ctx;
+{
+ STAB *s;
+ dane_tlsa_P dane_tlsa;
+
+ dane_tlsa = NULL;
+ if (NULL == dane_vrfy_ctx)
+ return NULL;
+ if (dane_vrfy_ctx->dane_vrfy_chk == DANE_NEVER ||
+ dane_vrfy_ctx->dane_vrfy_host == NULL)
+ return NULL;
+
+ GETTLSANOX(dane_vrfy_ctx->dane_vrfy_host, &s,
+ dane_vrfy_ctx->dane_vrfy_port);
+ if (NULL == s)
+ goto notfound;
+ dane_tlsa = s->s_tlsa;
+ if (NULL == dane_tlsa)
+ goto notfound;
+ if (0 == dane_tlsa->dane_tlsa_n)
+ goto notfound;
+ if (tTd(96, 4))
+ sm_dprintf("dane_get_tlsa, chk=%d, host=%s, n=%d, stat=entry found\n",
+ dane_vrfy_ctx->dane_vrfy_chk,
+ dane_vrfy_ctx->dane_vrfy_host, dane_tlsa->dane_tlsa_n);
+ return dane_tlsa;
+
+ notfound:
+ if (tTd(96, 4))
+ sm_dprintf("dane_get_tlsa, chk=%d, host=%s, stat=no valid entry found\n",
+ dane_vrfy_ctx->dane_vrfy_chk,
+ dane_vrfy_ctx->dane_vrfy_host);
+ return NULL;
+}
+
+/*
+** DANE_VERIFY -- verify callback for TLS certificates
+**
+** Parameters:
+** ctx -- X509 context
+** dane_vrfy_ctx -- callback context
+**
+** Returns:
+** DANE_VRFY_{OK,NONE,FAIL}
+*/
+
+/* NOTE: this only works because the "matching type" is 0, 1, 2 for these! */
+static const char *dane_mdalgs[] = { "", "sha256", "sha512" };
+
+static int
+dane_verify(ctx, dane_vrfy_ctx)
+ X509_STORE_CTX *ctx;
+ dane_vrfy_ctx_P dane_vrfy_ctx;
+{
+ int r, i, ok, mdalg;
+ X509 *cert;
+ dane_tlsa_P dane_tlsa;
+ char *fp;
+
+ dane_tlsa = dane_get_tlsa(dane_vrfy_ctx);
+ if (dane_tlsa == NULL)
+ return DANE_VRFY_NONE;
+
+ dane_vrfy_ctx->dane_vrfy_fp[0] = '\0';
+ cert = X509_STORE_CTX_get0_cert(ctx);
+ if (tTd(96, 8))
+ sm_dprintf("dane_verify, cert=%p\n", (void *)cert);
+ if (cert == NULL)
+ return DANE_VRFY_FAIL;
+
+ ok = DANE_VRFY_NONE;
+ fp = NULL;
+
+ /*
+ ** If the TLSA RRs would be sorted the two loops below could
+ ** be merged into one and simply change mdalg when it changes
+ ** in dane_tlsa->dane_tlsa_rr.
+ */
+
+ /* use a different order? */
+ for (mdalg = 0; mdalg < SM_ARRAY_SIZE(dane_mdalgs); mdalg++)
+ {
+ SM_FREE(fp);
+ r = 0;
+ for (i = 0; i < dane_tlsa->dane_tlsa_n; i++)
+ {
+ char *p;
+ int alg;
+
+ p = dane_tlsa->dane_tlsa_rr[i];
+
+ /* ignore bogus/unsupported TLSA RRs */
+ alg = dane_tlsa_chk(p, dane_tlsa->dane_tlsa_len[i],
+ dane_vrfy_ctx->dane_vrfy_host, false);
+ if (tTd(96, 8))
+ sm_dprintf("dane_verify, alg=%d, mdalg=%d\n",
+ alg, mdalg);
+ if (alg != mdalg)
+ continue;
+
+ if (NULL == fp)
+ {
+ r = pubkey_fp(cert, dane_mdalgs[mdalg], &fp);
+ if (NULL == fp)
+ return DANE_VRFY_FAIL;
+ /* or continue? */
+ }
+
+ /* just for logging */
+ if (r > 0 && fp != NULL)
+ {
+ (void) data2hex((unsigned char *)fp, r,
+ (unsigned char *)dane_vrfy_ctx->dane_vrfy_fp,
+ sizeof(dane_vrfy_ctx->dane_vrfy_fp));
+ }
+
+ if (tTd(96, 4))
+ sm_dprintf("dane_verify, alg=%d, r=%d, len=%d\n",
+ alg, r, dane_tlsa->dane_tlsa_len[i]);
+ if (r != dane_tlsa->dane_tlsa_len[i] - 3)
+ continue;
+ ok = DANE_VRFY_FAIL;
+
+ /*
+ ** Note: Type is NOT checked because only 3-1-x
+ ** is supported.
+ */
+
+ if (memcmp(p + 3, fp, r) == 0)
+ {
+ if (tTd(96, 2))
+ sm_dprintf("dane_verify, status=match\n");
+ if (tTd(96, 8))
+ {
+ unsigned char hex[256];
+
+ data2hex((unsigned char *)p,
+ dane_tlsa->dane_tlsa_len[i],
+ hex, sizeof(hex));
+ sm_dprintf("dane_verify, pubkey_fp=%s\n"
+ , hex);
+ }
+ dane_vrfy_ctx->dane_vrfy_res = DANE_VRFY_OK;
+ SM_FREE(fp);
+ return DANE_VRFY_OK;
+ }
+ }
+ }
+
+ SM_FREE(fp);
+ dane_vrfy_ctx->dane_vrfy_res = ok;
+ return ok;
+}
+# endif /* DANE */
+
+/*
** TLS_VERIFY_CB -- verify callback for TLS certificates
**
** Parameters:
-** ctx -- x509 context
+** ctx -- X509 context
+** cb_ctx -- callback context
**
** Returns:
** accept connection?
@@ -1952,36 +2422,54 @@ tls_verify_log(ok, ctx, name)
*/
static int
-# if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x00907000L
-tls_verify_cb(ctx)
- X509_STORE_CTX *ctx;
-# else /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
-tls_verify_cb(ctx, unused)
+tls_verify_cb(ctx, cb_ctx)
X509_STORE_CTX *ctx;
- void *unused;
-# endif /* !defined() || OPENSSL_VERSION_NUMBER < 0x00907000L */
+ void *cb_ctx;
{
int ok;
+# if DANE
+ SM_DECTLSI;
+# endif
/*
- ** man SSL_CTX_set_cert_verify_callback():
+ ** SSL_CTX_set_cert_verify_callback(3):
** callback should return 1 to indicate verification success
** and 0 to indicate verification failure.
*/
+# if DANE
+ SM_GETTLSI;
+ if (tlsi_ctx != NULL)
+ {
+ dane_vrfy_ctx_P dane_vrfy_ctx;
+
+ dane_vrfy_ctx = &(tlsi_ctx->tlsi_dvc);
+ ok = dane_verify(ctx, dane_vrfy_ctx);
+ if (tTd(96, 2))
+ sm_dprintf("dane_verify=%d, res=%d\n", ok,
+ dane_vrfy_ctx->dane_vrfy_res);
+ if (ok != DANE_VRFY_NONE)
+ return 1;
+ }
+# endif /* DANE */
+
ok = X509_verify_cert(ctx);
if (ok <= 0)
{
if (LogLevel > 13)
return tls_verify_log(ok, ctx, "TLS");
}
+ else if (LogLevel > 14)
+ (void) tls_verify_log(ok, ctx, "TLS");
return 1;
}
+
/*
** TLSLOGERR -- log the errors from the TLS error stack
**
** Parameters:
-** level -- syslog level
+** priority -- syslog priority
+** ll -- loglevel
** who -- server/client (for logging).
**
** Returns:
@@ -1989,35 +2477,36 @@ tls_verify_cb(ctx, unused)
*/
void
-tlslogerr(level, who)
- int level;
+tlslogerr(priority, ll, who)
+ int priority;
+ int ll;
const char *who;
{
unsigned long l;
int line, flags;
- unsigned long es;
char *file, *data;
char buf[256];
- es = CRYPTO_thread_id();
+ if (LogLevel <= ll)
+ return;
while ((l = ERR_get_error_line_data((const char **) &file, &line,
(const char **) &data, &flags))
!= 0)
{
- sm_syslog(level, NOQID,
- "STARTTLS=%s: %lu:%s:%s:%d:%s", who, es,
+ sm_syslog(priority, NOQID,
+ "STARTTLS=%s: %s:%s:%d:%s", who,
ERR_error_string(l, buf),
file, line,
bitset(ERR_TXT_STRING, flags) ? data : "");
}
}
-# if OPENSSL_VERSION_NUMBER > 0x00907000L
/*
** X509_VERIFY_CB -- verify callback
**
** Parameters:
-** ctx -- x509 context
+** ok -- current result
+** ctx -- X509 context
**
** Returns:
** accept connection?
@@ -2029,17 +2518,141 @@ x509_verify_cb(ok, ctx)
int ok;
X509_STORE_CTX *ctx;
{
- if (ok == 0)
+ SM_DECTLSI;
+
+ if (ok != 0)
+ return ok;
+
+ SM_GETTLSI;
+ if (LogLevel > 13)
+ tls_verify_log(ok, ctx, "X509");
+ if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL &&
+ !SM_TLSI_IS(tlsi_ctx, TLSI_FL_CRLREQ))
{
- if (LogLevel > 13)
- tls_verify_log(ok, ctx, "x509");
- if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
+ X509_STORE_CTX_set_error(ctx, 0);
+ return 1; /* override it */
+ }
+ return ok;
+}
+
+# if !USE_OPENSSL_ENGINE
+/*
+** TLS_SET_ENGINE -- set up ENGINE if needed
+**
+** Parameters:
+** id -- id for ENGINE
+** isprefork -- called before fork()?
+**
+** Returns: (OpenSSL "semantics", reverse it to allow returning error codes)
+** 0: failure
+** !=0: ok
+*/
+
+int
+TLS_set_engine(id, isprefork)
+ const char *id;
+ bool isprefork;
+{
+ static bool TLSEngineInitialized = false;
+ ENGINE *e;
+ char enginepath[MAXPATHLEN];
+
+ /*
+ ** Todo: put error for logging into a string and log it in error:
+ */
+
+ if (LogLevel > 13)
+ sm_syslog(LOG_DEBUG, NOQID,
+ "engine=%s, path=%s, ispre=%d, pre=%d, initialized=%d",
+ id, SSLEnginePath, isprefork, SSLEngineprefork,
+ TLSEngineInitialized);
+ if (TLSEngineInitialized)
+ return 1;
+ if (id == NULL || *id == '\0')
+ return 1;
+
+ /* is this the "right time" to initialize the engine? */
+ if (isprefork != SSLEngineprefork)
+ return 1;
+
+ e = NULL;
+ ENGINE_load_builtin_engines();
+
+ if (SSLEnginePath != NULL && *SSLEnginePath != '\0')
+ {
+ if ((e = ENGINE_by_id("dynamic")) == NULL)
{
- X509_STORE_CTX_set_error(ctx, 0);
- return 1; /* override it */
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID,
+ "engine=%s, by_id=failed", "dynamic");
+ goto error;
+ }
+ (void) sm_snprintf(enginepath, sizeof(enginepath),
+ "%s/lib%s.so", SSLEnginePath, id);
+
+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", enginepath, 0))
+ {
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID,
+ "engine=%s, SO_PATH=%s, status=failed",
+ id, enginepath);
+ goto error;
+ }
+
+ if (!ENGINE_ctrl_cmd_string(e, "ID", id, 0))
+ {
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID,
+ "engine=%s, ID=failed", id);
+ goto error;
+ }
+
+ if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
+ {
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID,
+ "engine=%s, LOAD=failed", id);
+ goto error;
}
}
- return ok;
+ else if ((e = ENGINE_by_id(id)) == NULL)
+ {
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID, "engine=%s, by_id=failed",
+ id);
+ return 0;
+ }
+
+ if (!ENGINE_init(e))
+ {
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID, "engine=%s, init=failed", id);
+ goto error;
+ }
+ if (!ENGINE_set_default(e, ENGINE_METHOD_ALL))
+ {
+ if (LogLevel > 1)
+ sm_syslog(LOG_ERR, NOQID,
+ "engine=%s, set_default=failed", id);
+ goto error;
+ }
+# ifdef ENGINE_CTRL_CHIL_SET_FORKCHECK
+ if (strcmp(id, "chil") == 0)
+ ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
+# endif
+
+ /* Free our "structural" reference. */
+ ENGINE_free(e);
+ if (LogLevel > 10)
+ sm_syslog(LOG_INFO, NOQID, "engine=%s, loaded=ok", id);
+ TLSEngineInitialized = true;
+ return 1;
+
+ error:
+ tlslogerr(LOG_WARNING, 7, "init");
+ if (e != NULL)
+ ENGINE_free(e);
+ return 0;
}
-# endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */
+# endif /* !USE_OPENSSL_ENGINE */
#endif /* STARTTLS */
diff --git a/contrib/sendmail/src/tls.h b/contrib/sendmail/src/tls.h
new file mode 100644
index 000000000000..0e03b81933a9
--- /dev/null
+++ b/contrib/sendmail/src/tls.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2015 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ */
+
+
+#ifndef _TLS_H
+# define _TLS_H 1
+
+
+#if STARTTLS
+# include <openssl/ssl.h>
+# if !TLS_NO_RSA
+# if _FFR_FIPSMODE
+# define RSA_KEYLENGTH 1024
+# else
+# define RSA_KEYLENGTH 512
+# endif
+# endif /* !TLS_NO_RSA */
+
+# if OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x20000000L
+# define TLS_version_num OpenSSL_version_num
+# else
+# define TLS_version_num SSLeay
+# endif
+
+#ifdef _DEFINE
+# define EXTERN
+#else
+# define EXTERN extern
+#endif
+
+#if _FFR_TLS_EC && !defined(TLS_EC)
+# define TLS_EC _FFR_TLS_EC
+#endif
+
+#if DANE
+extern int gettlsa __P((char *, char *, STAB **, unsigned long, unsigned int, unsigned int));
+# define MAX_TLSA_RR 8
+
+# define DANE_VRFY_NONE 0 /* no TLSAs */
+# define DANE_VRFY_OK 1 /* TLSA check was ok */
+# define DANE_VRFY_FAIL (-1) /* TLSA check failed */
+
+/* return values for dane_tlsa_chk() */
+# define TLSA_BOGUS (-10)
+# define TLSA_UNSUPP (-1)
+/* note: anything >= 0 is ok and refers to the hash algorithm */
+# define TLSA_IS_KNOWN(r) ((r) >= 0)
+# define TLSA_IS_VALID(r) ((r) >= TLSA_UNSUPP)
+
+struct dane_tlsa_S
+{
+ time_t dane_tlsa_exp;
+ int dane_tlsa_n;
+ int dane_tlsa_dnsrc;
+ unsigned long dane_tlsa_flags;
+ unsigned char dane_tlsa_usage[MAX_TLSA_RR];
+ unsigned char dane_tlsa_selector[MAX_TLSA_RR];
+ unsigned char dane_tlsa_digest[MAX_TLSA_RR];
+ void *dane_tlsa_rr[MAX_TLSA_RR];
+ int dane_tlsa_len[MAX_TLSA_RR];
+ char *dane_tlsa_sni;
+};
+
+# define TLSAFLNONE 0x00000000 /* currently unused */
+/* Dane Mode */
+# define TLSAFLALWAYS 0x00000001
+# define TLSAFLSECURE 0x00000002
+# define DANEMODE(fl) ((fl) & 0x3)
+# define TLSAFLNOEXP 0x00000010 /* do not check expiration */
+
+# define TLSAFLADMX 0x00000100
+# define TLSAFLADTLSA 0x00000200 /* currently unused */
+
+/* could be used to replace DNSRC */
+# define TLSAFLTEMP 0x00001000
+/* no TLSA? -- _n == 0 */
+# define TLSAFLNOTLSA 0x00002000 /* currently unused */
+
+/*
+** Do not use this record, and do not look up new TLSA RRs because
+** the MX/host lookup was not secure.
+** XXX: to determine: interaction with DANE=always
+*/
+
+# define TLSAFLNOADMX 0x00010000
+# define TLSAFLNOADTLSA 0x00020000 /* TLSA: no AD - for DANE=always? */
+
+# define TLSA_SET_FL(dane_tlsa, fl) (dane_tlsa)->dane_tlsa_flags |= (fl)
+# define TLSA_CLR_FL(dane_tlsa, fl) (dane_tlsa)->dane_tlsa_flags &= ~(fl)
+# define TLSA_IS_FL(dane_tlsa, fl) ((dane_tlsa)->dane_tlsa_flags & (fl))
+# define TLSA_STORE_FL(fl) ((fl) >= TLSAFLTEMP)
+
+# define GETTLSA(host, pste, port) gettlsa(host, NULL, pste, TLSAFLNONE, 0, port)
+# define GETTLSANOX(host, pste, port) gettlsa(host, NULL, pste, TLSAFLNOEXP, 0, port)
+
+/* values for DANE option and dane_vrfy_chk */
+# define DANE_NEVER TLSAFLNONE
+# define DANE_ALWAYS TLSAFLALWAYS /* NOT documented, testing... */
+# define DANE_SECURE TLSAFLSECURE
+# define CHK_DANE(dane) ((dane) != DANE_NEVER)
+
+/* temp fails? others? */
+# define TLSA_RR_TEMPFAIL(dane_tlsa) (((dane_tlsa) != NULL) && (dane_tlsa)->dane_tlsa_dnsrc == TRY_AGAIN)
+
+#endif /* DANE */
+
+/*
+** TLS
+*/
+
+/* what to do in the TLS initialization */
+#define TLS_I_NONE 0x00000000 /* no requirements... */
+#define TLS_I_CERT_EX 0x00000001 /* cert must exist */
+#define TLS_I_CERT_UNR 0x00000002 /* cert must be g/o unreadable */
+#define TLS_I_KEY_EX 0x00000004 /* key must exist */
+#define TLS_I_KEY_UNR 0x00000008 /* key must be g/o unreadable */
+#define TLS_I_CERTP_EX 0x00000010 /* CA cert path must exist */
+#define TLS_I_CERTP_UNR 0x00000020 /* CA cert path must be g/o unreadable */
+#define TLS_I_CERTF_EX 0x00000040 /* CA cert file must exist */
+#define TLS_I_CERTF_UNR 0x00000080 /* CA cert file must be g/o unreadable */
+#define TLS_I_RSA_TMP 0x00000100 /* RSA TMP must be generated */
+#define TLS_I_USE_KEY 0x00000200 /* private key must usable */
+#define TLS_I_USE_CERT 0x00000400 /* certificate must be usable */
+#define TLS_I_VRFY_PATH 0x00000800 /* load verify path must succeed */
+#define TLS_I_VRFY_LOC 0x00001000 /* load verify default must succeed */
+#define TLS_I_CACHE 0x00002000 /* require cache */
+#define TLS_I_TRY_DH 0x00004000 /* try DH certificate */
+#define TLS_I_REQ_DH 0x00008000 /* require DH certificate */
+#define TLS_I_DHPAR_EX 0x00010000 /* require DH parameters */
+#define TLS_I_DHPAR_UNR 0x00020000 /* DH param. must be g/o unreadable */
+#define TLS_I_DH512 0x00040000 /* generate 512bit DH param */
+#define TLS_I_DH1024 0x00080000 /* generate 1024bit DH param */
+#define TLS_I_DH2048 0x00100000 /* generate 2048bit DH param */
+#define TLS_I_NO_VRFY 0x00200000 /* do not require authentication */
+#define TLS_I_KEY_OUNR 0x00400000 /* Key must be 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 */
+#define TLS_I_DHFIXED 0x02000000 /* use fixed DH param */
+
+/* require server cert */
+#define TLS_I_SRV_CERT (TLS_I_CERT_EX | TLS_I_KEY_EX | \
+ TLS_I_KEY_UNR | TLS_I_KEY_OUNR | \
+ TLS_I_CERTP_EX | TLS_I_CERTF_EX | \
+ TLS_I_USE_KEY | TLS_I_USE_CERT | TLS_I_CACHE)
+
+/* server requirements */
+#define TLS_I_SRV (TLS_I_SRV_CERT | TLS_I_RSA_TMP | TLS_I_VRFY_PATH | \
+ TLS_I_VRFY_LOC | TLS_I_TRY_DH | TLS_I_CACHE)
+
+/* client requirements */
+#define TLS_I_CLT (TLS_I_KEY_UNR | TLS_I_KEY_OUNR)
+
+#define TLS_AUTH_OK 0
+#define TLS_AUTH_NO 1
+#define TLS_AUTH_FAIL (-1)
+
+# ifndef TLS_VRFY_PER_CTX
+# define TLS_VRFY_PER_CTX 1
+# endif
+
+#define SM_SSL_FREE(ssl) \
+ do { \
+ if (ssl != NULL) \
+ { \
+ SSL_free(ssl); \
+ ssl = NULL; \
+ } \
+ } while (0)
+
+/* functions */
+extern int endtls __P((SSL **, const char *));
+extern int get_tls_se_options __P((ENVELOPE *, SSL *, tlsi_ctx_T *, bool));
+extern int init_tls_library __P((bool _fipsmode));
+extern bool inittls __P((SSL_CTX **, unsigned long, unsigned long, bool, char *, char *, char *, char *, char *));
+extern bool initclttls __P((bool));
+extern bool initsrvtls __P((bool));
+extern bool load_certkey __P((SSL *, bool, char *, char *));
+/* extern bool load_crlpath __P((SSL_CTX *, bool , char *)); */
+extern void setclttls __P((bool));
+extern int tls_get_info __P((SSL *, bool, char *, MACROS_T *, bool));
+extern void tlslogerr __P((int, int, const char *));
+extern void tls_set_verify __P((SSL_CTX *, SSL *, bool));
+# if DANE
+extern int dane_tlsa_chk __P((const char *, int, const char *, bool));
+extern int dane_tlsa_clr __P((dane_tlsa_P));
+extern int dane_tlsa_free __P((dane_tlsa_P));
+# endif
+
+EXTERN char *CACertPath; /* path to CA certificates (dir. with hashes) */
+EXTERN char *CACertFile; /* file with CA certificate */
+#if _FFR_CLIENTCA
+EXTERN char *CltCACertPath; /* path to CA certificates (dir. with hashes) */
+EXTERN char *CltCACertFile; /* file with CA certificate */
+#endif
+EXTERN char *CltCertFile; /* file with client certificate */
+EXTERN char *CltKeyFile; /* file with client private key */
+EXTERN char *CipherList; /* list of ciphers */
+EXTERN char *CertFingerprintAlgorithm; /* name of fingerprint alg */
+EXTERN const EVP_MD *EVP_digest; /* digest for cert fp */
+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 */
+EXTERN char *CRLPath; /* path to CRLs (dir. with hashes) */
+EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */
+EXTERN unsigned long Srv_SSL_Options, Clt_SSL_Options; /* SSL options */
+EXTERN bool TLSFallbacktoClear;
+
+EXTERN char *SSLEngine;
+EXTERN char *SSLEnginePath;
+EXTERN bool SSLEngineprefork;
+
+# if USE_OPENSSL_ENGINE
+#define TLS_set_engine(id, prefork) SSL_set_engine(id)
+# else
+int TLS_set_engine __P((const char *, bool));
+# endif
+
+extern int set_tls_rd_tmo __P((int));
+extern int data2hex __P((unsigned char *, int, unsigned char *, int));
+# if DANE
+extern int pubkey_fp __P((X509 *, const char*, char **));
+extern dane_tlsa_P dane_get_tlsa __P((dane_vrfy_ctx_P));
+# endif
+
+#else /* STARTTLS */
+# define set_tls_rd_tmo(rd_tmo) 0
+#endif /* STARTTLS */
+#undef EXTERN
+#endif /* ! _TLS_H */
diff --git a/contrib/sendmail/src/tlsh.c b/contrib/sendmail/src/tlsh.c
new file mode 100644
index 000000000000..4b968268cca0
--- /dev/null
+++ b/contrib/sendmail/src/tlsh.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2015 Proofpoint, Inc. and its suppliers.
+ * All rights reserved.
+ *
+ * By using this file, you agree to the terms and conditions set
+ * forth in the LICENSE file which can be found at the top level of
+ * the sendmail distribution.
+ *
+ */
+
+#include <sendmail.h>
+
+SM_RCSID("@(#)$Id: tls.c,v 8.127 2013-11-27 02:51:11 gshapiro Exp $")
+
+#if STARTTLS
+# include <tls.h>
+
+/*
+** DATA2HEX -- create a printable hex string from binary data ("%02X:")
+**
+** Parameters:
+** buf -- data
+** len -- length of data
+** hex -- output buffer
+** hlen -- length of output buffer
+**
+** Returns:
+** <0: errno
+** >0: length of data in hex
+*/
+
+int
+data2hex(buf, blen, hex, hlen)
+ unsigned char *buf;
+ int blen;
+ unsigned char *hex;
+ int hlen;
+{
+ int r, h;
+ static const char hexcodes[] = "0123456789ABCDEF";
+
+ SM_REQUIRE(buf != NULL);
+ SM_REQUIRE(hex != NULL);
+ if (blen * 3 + 2 > hlen)
+ return -ERANGE;
+
+ for (r = 0, h = 0; r < blen && h + 3 < hlen; r++)
+ {
+ hex[h++] = hexcodes[(buf[r] & 0xf0) >> 4];
+ hex[h++] = hexcodes[(buf[r] & 0x0f)];
+ if (r + 1 < blen)
+ hex[h++] = ':';
+ }
+ if (h >= hlen)
+ return -ERANGE;
+ hex[h] = '\0';
+ return h;
+}
+
+/*
+** TLS_DATA_MD -- calculate MD for data
+**
+** Parameters:
+** buf -- data (in and out!)
+** len -- length of data
+** md -- digest algorithm
+**
+** Returns:
+** <=0: cert fp calculation failed
+** >0: len of fp
+**
+** Side Effects:
+** writes digest to buf
+*/
+
+static int
+tls_data_md(buf, len, md)
+ unsigned char *buf;
+ int len;
+ const EVP_MD *md;
+{
+ unsigned int md_len;
+ EVP_MD_CTX *mdctx;
+ unsigned char md_buf[EVP_MAX_MD_SIZE];
+
+ SM_REQUIRE(buf != NULL);
+ SM_REQUIRE(md != NULL);
+ SM_REQUIRE(len >= EVP_MAX_MD_SIZE);
+
+ mdctx = EVP_MD_CTX_create();
+ if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
+ return -EINVAL;
+ if (EVP_DigestUpdate(mdctx, (void *)buf, len) != 1)
+ return -EINVAL;
+ if (EVP_DigestFinal_ex(mdctx, md_buf, &md_len) != 1)
+ return -EINVAL;
+ EVP_MD_CTX_destroy(mdctx);
+
+ if (md_len > len)
+ return -ERANGE;
+ (void) memcpy(buf, md_buf, md_len);
+ return (int)md_len;
+}
+
+#if DANE
+
+/*
+** PUBKEY_FP -- get public key fingerprint
+**
+** Parameters:
+** cert -- TLS cert
+** mdalg -- name of digest algorithm
+** fp -- (pointer to) fingerprint buffer
+**
+** Returns:
+** <=0: cert fp calculation failed
+** >0: len of fp
+*/
+
+int
+pubkey_fp(cert, mdalg, fp)
+ X509 *cert;
+ const char *mdalg;
+ char **fp;
+{
+ int len, r;
+ unsigned char *buf, *end;
+ const EVP_MD *md;
+
+ SM_ASSERT(cert != NULL);
+ SM_ASSERT(fp != NULL);
+ SM_ASSERT(mdalg != NULL);
+
+ len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), NULL);
+
+ /* what's an acceptable upper limit? */
+ if (len <= 0 || len >= 8192)
+ return -EINVAL;
+ if (len < EVP_MAX_MD_SIZE)
+ len = EVP_MAX_MD_SIZE;
+ end = buf = sm_malloc(len);
+ if (NULL == buf)
+ return -ENOMEM;
+
+ if ('\0' == mdalg[0])
+ {
+ r = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &end);
+ if (r <= 0 || r != len)
+ return -EINVAL;
+ *fp = (char *)buf;
+ return len;
+ }
+
+ md = EVP_get_digestbyname(mdalg);
+ if (NULL == md)
+ return DANE_VRFY_FAIL;
+ len = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(cert), &end);
+ r = tls_data_md(buf, len, md);
+ if (r < 0)
+ sm_free(buf);
+ else
+ *fp = (char *)buf;
+ return r;
+}
+
+/*
+** DANE_TLSA_CHK -- check whether a TLSA RR is ok to use
+**
+** Parameters:
+** rr -- RR
+** len -- length of RR
+** host -- name of host for RR (only for logging)
+** log -- whether to log problems
+**
+** Returns:
+** TLSA_*, see tls.h
+*/
+
+int
+dane_tlsa_chk(rr, len, host, log)
+ const char *rr;
+ int len;
+ const char *host;
+ bool log;
+{
+ int alg;
+
+ if (len < 4)
+ {
+ if (log && LogLevel > 8)
+ sm_syslog(LOG_WARNING, NOQID,
+ "TLSA=%s, len=%d, status=bogus",
+ host, len);
+ return TLSA_BOGUS;
+ }
+ SM_ASSERT(rr != NULL);
+
+ alg = (int)rr[2];
+ if ((int)rr[0] == 3 && (int)rr[1] == 1 && (alg >= 0 || alg <= 2))
+ return alg;
+ if (log && LogLevel > 9)
+ sm_syslog(LOG_NOTICE, NOQID,
+ "TLSA=%s, type=%d-%d-%d:%02x, status=unsupported",
+ host, (int)rr[0], (int)rr[1], (int)rr[2],
+ (int)rr[3]);
+ return TLSA_UNSUPP;
+}
+
+/*
+** DANE_TLSA_CLR -- clear data in a dane_tlsa structure (for use)
+**
+** Parameters:
+** dane_tlsa -- dane_tlsa to clear
+**
+** Returns:
+** 1 if NULL
+** 0 if ok
+*/
+
+int
+dane_tlsa_clr(dane_tlsa)
+ dane_tlsa_P dane_tlsa;
+{
+ int i;
+
+ if (dane_tlsa == NULL)
+ return 1;
+ for (i = 0; i < dane_tlsa->dane_tlsa_n; i++)
+ {
+ SM_FREE(dane_tlsa->dane_tlsa_rr[i]);
+ dane_tlsa->dane_tlsa_len[i] = 0;
+ }
+ SM_FREE(dane_tlsa->dane_tlsa_sni);
+ memset(dane_tlsa, '\0', sizeof(*dane_tlsa));
+ return 0;
+
+}
+
+/*
+** DANE_TLSA_FREE -- free a dane_tlsa structure
+**
+** Parameters:
+** dane_tlsa -- dane_tlsa to free
+**
+** Returns:
+** 0 if ok
+** 1 if NULL
+*/
+
+int
+dane_tlsa_free(dane_tlsa)
+ dane_tlsa_P dane_tlsa;
+{
+ if (dane_tlsa == NULL)
+ return 1;
+ dane_tlsa_clr(dane_tlsa);
+ SM_FREE(dane_tlsa);
+ return 0;
+
+}
+#endif /* DANE */
+
+#endif /* STARTTLS */
diff --git a/contrib/sendmail/src/udb.c b/contrib/sendmail/src/udb.c
index b2372b766169..00ee857ffe40 100644
--- a/contrib/sendmail/src/udb.c
+++ b/contrib/sendmail/src/udb.c
@@ -16,9 +16,9 @@
#if USERDB
SM_RCSID("@(#)$Id: udb.c,v 8.166 2013-11-22 20:51:57 ca Exp $ (with USERDB)")
-#else /* USERDB */
+#else
SM_RCSID("@(#)$Id: udb.c,v 8.166 2013-11-22 20:51:57 ca Exp $ (without USERDB)")
-#endif /* USERDB */
+#endif
#if USERDB
@@ -98,7 +98,7 @@ struct udb_option
# if HESIOD
static int hes_udb_get __P((DBT *, DBT *));
-# endif /* HESIOD */
+# endif
static char *udbmatch __P((char *, char *, SM_RPOOL_T *));
static int _udbx_init __P((ENVELOPE *));
static int _udb_parsespec __P((char *, struct udb_option [], int));
@@ -187,19 +187,23 @@ udbexpand(a, sendq, aliaslevel, e)
for (up = UdbEnts; !breakout; up++)
{
int usersize;
+# if NEWDB
int userleft;
+# endif
char userbuf[MEMCHUNKSIZE];
# if HESIOD && HES_GETMAILHOST
char pobuf[MAXNAME];
-# endif /* HESIOD && HES_GETMAILHOST */
+# endif
# if defined(NEWDB) && DB_VERSION_MAJOR > 1
DBC *dbc = NULL;
-# endif /* defined(NEWDB) && DB_VERSION_MAJOR > 1 */
+# endif
user = userbuf;
userbuf[0] = '\0';
usersize = sizeof(userbuf);
+# if NEWDB
userleft = sizeof(userbuf) - 1;
+# endif
/*
** Select action based on entry type.
@@ -362,10 +366,10 @@ udbexpand(a, sendq, aliaslevel, e)
# if DB_VERSION_MAJOR < 2
i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
i = errno = (*up->udb_dbp->get)(up->udb_dbp, NULL,
&key, &info, 0);
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
if (i != 0 || info.size <= 0)
break;
a->q_owner = sm_rpool_malloc_x(e->e_rpool,
@@ -404,7 +408,7 @@ udbexpand(a, sendq, aliaslevel, e)
{
# if HES_GETMAILHOST
struct hes_postoffice *hp;
-# endif /* HES_GETMAILHOST */
+# endif
if (tTd(28, 2))
sm_dprintf("udbexpand: no match on %s (%d)\n",
@@ -649,10 +653,10 @@ udbmatch(user, field, rpool)
key.size = keylen;
# if DB_VERSION_MAJOR < 2
i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
i = errno = (*up->udb_dbp->get)(up->udb_dbp, NULL,
&key, &info, 0);
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
if (i != 0 || info.size <= 0)
{
if (tTd(28, 2))
@@ -748,10 +752,10 @@ udbmatch(user, field, rpool)
key.size = keylen;
# if DB_VERSION_MAJOR < 2
i = (*up->udb_dbp->get)(up->udb_dbp, &key, &info, 0);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
i = errno = (*up->udb_dbp->get)(up->udb_dbp, NULL,
&key, &info, 0);
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
if (i != 0 || info.size <= 0)
{
/* nope -- no aliasing for this user */
@@ -906,14 +910,16 @@ _udbx_init(e)
# ifdef UDB_DEFAULT_SPEC
if (UdbSpec == NULL)
UdbSpec = UDB_DEFAULT_SPEC;
-# endif /* UDB_DEFAULT_SPEC */
+# endif
p = UdbSpec;
up = UdbEnts;
while (p != NULL)
{
char *spec;
+# if NEWDB
int l;
+# endif
struct udb_option opts[MAXUDBOPTS + 1];
while (*p == ' ' || *p == '\t' || *p == ',')
@@ -1019,7 +1025,7 @@ _udbx_init(e)
#ifdef DB_OLD_VERSION
if (ret == DB_OLD_VERSION)
ret = EINVAL;
-#endif /* DB_OLD_VERSION */
+#endif
(void) up->udb_dbp->close(up->udb_dbp, 0);
up->udb_dbp = NULL;
}
@@ -1086,7 +1092,7 @@ _udbx_init(e)
default:
# if HESIOD
badspec:
-# endif /* HESIOD */
+# endif
syserr("Unknown UDB spec %s", spec);
break;
}
@@ -1107,11 +1113,10 @@ badspec:
case UDB_DBFETCH:
# if NEWDB
- sm_dprintf("FETCH: file %s\n",
- up->udb_dbname);
-# else /* NEWDB */
+ sm_dprintf("FETCH: file %s\n", up->udb_dbname);
+# else
sm_dprintf("FETCH\n");
-# endif /* NEWDB */
+# endif
break;
case UDB_FORWARD:
@@ -1138,17 +1143,17 @@ badspec:
** On temporary failure, back out anything we've already done
*/
- tempfail:
# if NEWDB
+ tempfail:
for (up = UdbEnts; up->udb_type != UDB_EOLIST; up++)
{
if (up->udb_type == UDB_DBFETCH)
{
# if DB_VERSION_MAJOR < 2
(*up->udb_dbp->close)(up->udb_dbp);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
errno = (*up->udb_dbp->close)(up->udb_dbp, 0);
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
if (tTd(28, 1))
sm_dprintf("_udbx_init: db->close(%s)\n",
up->udb_dbname);
@@ -1173,7 +1178,7 @@ _udb_parsespec(udbspec, opt, maxopts)
{
register char *p;
- while (isascii(*spec) && isspace(*spec))
+ while (SM_ISSPACE(*spec))
spec++;
spec_end = strchr(spec, ':');
if (spec_end != NULL)
@@ -1214,9 +1219,9 @@ _udbx_close()
{
# if DB_VERSION_MAJOR < 2
(*up->udb_dbp->close)(up->udb_dbp);
-# else /* DB_VERSION_MAJOR < 2 */
+# else
errno = (*up->udb_dbp->close)(up->udb_dbp, 0);
-# endif /* DB_VERSION_MAJOR < 2 */
+# endif
}
if (tTd(28, 1))
sm_dprintf("_udbx_close: db->close(%s)\n",
@@ -1254,9 +1259,9 @@ hes_udb_get(key, info)
if (HesiodContext == NULL && hesiod_init(&HesiodContext) != 0)
return -1;
hp = hesiod_resolve(HesiodContext, name, type);
-# else /* HESIOD_INIT */
+# else
hp = hes_resolve(name, type);
-# endif /* HESIOD_INIT */
+# endif
*--type = ':';
# ifdef HESIOD_INIT
if (hp == NULL)
diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c
index 24d38ee4f945..b4ff5ccbc80a 100644
--- a/contrib/sendmail/src/usersmtp.c
+++ b/contrib/sendmail/src/usersmtp.c
@@ -25,7 +25,7 @@ static int smtprcptstat __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
#if SASL
extern void *sm_sasl_malloc __P((unsigned long));
extern void sm_sasl_free __P((void *));
-#endif /* SASL */
+#endif
/*
** USERSMTP -- run SMTP protocol from the user end.
@@ -72,6 +72,9 @@ smtpinit(m, mci, e, onlyhelo)
int state;
register char *p;
register char *hn;
+#if _FFR_EXPAND_HELONAME
+ char hnbuf[MAXNAME + 1];
+#endif
char *enhsc;
enhsc = NULL;
@@ -92,11 +95,9 @@ smtpinit(m, mci, e, onlyhelo)
CurHostName = MyHostName;
SmtpNeedIntro = true;
state = mci->mci_state;
-#if _FFR_ERRCODE
e->e_rcode = 0;
e->e_renhsc[0] = '\0';
e->e_text = NULL;
-#endif /* _FFR_ERRCODE */
switch (state)
{
case MCIS_MAIL:
@@ -156,12 +157,22 @@ smtpinit(m, mci, e, onlyhelo)
helo:
if (bitnset(M_ESMTP, m->m_flags) || bitnset(M_LMTP, m->m_flags))
mci->mci_flags |= MCIF_ESMTP;
- hn = mci->mci_heloname ? mci->mci_heloname : MyHostName;
+ if (mci->mci_heloname != NULL)
+ {
+#if _FFR_EXPAND_HELONAME
+ expand(mci->mci_heloname, hnbuf, sizeof(hnbuf), e);
+ hn = hnbuf;
+#else
+ hn = mci->mci_heloname;
+#endif
+ }
+ else
+ hn = MyHostName;
tryhelo:
#if _FFR_IGNORE_EXT_ON_HELO
mci->mci_flags &= ~MCIF_HELO;
-#endif /* _FFR_IGNORE_EXT_ON_HELO */
+#endif
if (bitnset(M_LMTP, m->m_flags))
{
smtpmessage("LHLO %s", m, mci, hn);
@@ -179,7 +190,7 @@ tryhelo:
SmtpPhase = mci->mci_phase = "client HELO";
#if _FFR_IGNORE_EXT_ON_HELO
mci->mci_flags |= MCIF_HELO;
-#endif /* _FFR_IGNORE_EXT_ON_HELO */
+#endif
}
sm_setproctitle(true, e, "%s %s: %s", qid_printname(e),
CurHostName, mci->mci_phase);
@@ -413,14 +424,14 @@ helo_options(line, firstline, m, mci, e)
register char *p;
#if _FFR_IGNORE_EXT_ON_HELO
static bool logged = false;
-#endif /* _FFR_IGNORE_EXT_ON_HELO */
+#endif
if (firstline)
{
mci_clr_extensions(mci);
#if _FFR_IGNORE_EXT_ON_HELO
logged = false;
-#endif /* _FFR_IGNORE_EXT_ON_HELO */
+#endif
return;
}
#if _FFR_IGNORE_EXT_ON_HELO
@@ -465,10 +476,14 @@ helo_options(line, firstline, m, mci, e)
mci->mci_flags |= MCIF_PIPELINED;
else if (sm_strcasecmp(line, "verb") == 0)
mci->mci_flags |= MCIF_VERB;
+#if _FFR_EAI
+ else if (sm_strcasecmp(line, "smtputf8") == 0)
+ mci->mci_flags |= MCIF_EAI;
+#endif /* _FFR_EAI */
#if STARTTLS
else if (sm_strcasecmp(line, "starttls") == 0)
mci->mci_flags |= MCIF_TLS;
-#endif /* STARTTLS */
+#endif
else if (sm_strcasecmp(line, "deliverby") == 0)
{
mci->mci_flags |= MCIF_DLVR_BY;
@@ -625,7 +640,7 @@ getsasldata(line, firstline, m, mci, e)
int result;
# if SASL < 20000
char *out;
-# endif /* SASL < 20000 */
+# endif
/* if not a continue we don't care about it */
len = strlen(line);
@@ -634,7 +649,7 @@ getsasldata(line, firstline, m, mci, e)
!isascii(line[1]) || !isdigit(line[1]) ||
!isascii(line[2]) || !isdigit(line[2]))
{
- SM_FREE_CLR(mci->mci_sasl_string);
+ SM_FREE(mci->mci_sasl_string);
return;
}
@@ -703,7 +718,7 @@ getsasldata(line, firstline, m, mci, e)
** rpool -- resource pool for sai.
**
** Returns:
-** EX_OK -- data succesfully read.
+** EX_OK -- data successfully read.
** EX_UNAVAILABLE -- no valid filename.
** EX_TEMPFAIL -- temporary failure.
*/
@@ -736,7 +751,7 @@ readauth(filename, safe, sai, rpool)
#if !_FFR_ALLOW_SASLINFO
/*
** make sure we don't use a program that is not
- ** accesible to the user who specified a different authinfo file.
+ ** accessible to the user who specified a different authinfo file.
** However, currently we don't pass this info (authinfo file
** specified by user) around, so we just turn off program access.
*/
@@ -778,7 +793,7 @@ readauth(filename, safe, sai, rpool)
#if _FFR_ALLOW_SASLINFO
/*
** XXX: make sure we don't read or open files that are not
- ** accesible to the user who specified a different authinfo
+ ** accessible to the user who specified a different authinfo
** file.
*/
@@ -837,7 +852,7 @@ readauth(filename, safe, sai, rpool)
** sai -- pointer to authinfo (result).
**
** Returns:
-** EX_OK -- ruleset was succesfully called, data may not
+** EX_OK -- ruleset was successfully called, data may not
** be available, sai must be checked.
** EX_UNAVAILABLE -- ruleset unavailable (or failed).
** EX_TEMPFAIL -- temporary failure (from ruleset).
@@ -1125,7 +1140,7 @@ getsimple(context, id, result, len)
char *h, *s;
# if SASL > 10509
bool addrealm;
-# endif /* SASL > 10509 */
+# endif
size_t l;
SASL_AI_T *sai;
char *authid = NULL;
@@ -1312,32 +1327,34 @@ getsecret(conn, context, id, psecret)
int
#if SASL > 10515
safesaslfile(context, file, type)
-#else /* SASL > 10515 */
+#else
safesaslfile(context, file)
-#endif /* SASL > 10515 */
+#endif
void *context;
# if SASL >= 20000
const char *file;
-# else /* SASL >= 20000 */
+# else
char *file;
-# endif /* SASL >= 20000 */
+# endif
#if SASL > 10515
# if SASL >= 20000
sasl_verify_type_t type;
-# else /* SASL >= 20000 */
+# else
int type;
-# endif /* SASL >= 20000 */
-#endif /* SASL > 10515 */
+# endif
+#endif
{
long sff;
int r;
#if SASL <= 10515
size_t len;
-#endif /* SASL <= 10515 */
+#endif
char *p;
if (file == NULL || *file == '\0')
return SASL_OK;
+ if (tTd(95, 16))
+ sm_dprintf("safesaslfile=%s\n", file);
sff = SFF_SAFEDIRPATH|SFF_NOWLINK|SFF_NOWWFILES|SFF_ROOTOK;
#if SASL <= 10515
if ((p = strrchr(file, '/')) == NULL)
@@ -1581,7 +1598,7 @@ attemptauth(m, mci, e, sai)
char in64[MAXOUTLEN + 1];
#if NETINET || (NETINET6 && SASL >= 20000)
extern SOCKADDR CurHostAddr;
-#endif /* NETINET || (NETINET6 && SASL >= 20000) */
+#endif
/* no mechanism selected (yet) */
(*sai)[SASL_MECH] = NULL;
@@ -1618,7 +1635,7 @@ attemptauth(m, mci, e, sai)
ssp.maxbufsize = MAXOUTLEN;
# if 0
ssp.security_flags = SASL_SEC_NOPLAINTEXT;
-# endif /* 0 */
+# endif
saslresult = sasl_setprop(mci->mci_conn, SASL_SEC_PROPS, &ssp);
if (saslresult != SASL_OK)
return EX_TEMPFAIL;
@@ -1647,7 +1664,7 @@ attemptauth(m, mci, e, sai)
if (mci->mci_out != NULL && (
# if NETINET6
CurHostAddr.sa.sa_family == AF_INET6 ||
-# endif /* NETINET6 */
+# endif
CurHostAddr.sa.sa_family == AF_INET))
{
SOCKADDR_LEN_T addrsize;
@@ -1663,7 +1680,7 @@ attemptauth(m, mci, e, sai)
case AF_INET6:
addrsize = sizeof(struct sockaddr_in6);
break;
-# endif /* NETINET6 */
+# endif
default:
break;
}
@@ -1747,7 +1764,7 @@ attemptauth(m, mci, e, sai)
if (saslresult == SASL_NOMECH && LogLevel > 8)
{
sm_syslog(LOG_NOTICE, e->e_id,
- "AUTH=client, available mechanisms do not fulfill requirements");
+ "AUTH=client, available mechanisms=%s do not fulfill requirements", mci->mci_saslcap);
}
return EX_TEMPFAIL;
}
@@ -1791,7 +1808,7 @@ attemptauth(m, mci, e, sai)
}
# if SASL < 20000
sm_sasl_free(out); /* XXX only if no rpool is used */
-# endif /* SASL < 20000 */
+# endif
/* get the reply */
smtpresult = reply(m, mci, e, TimeOuts.to_auth, getsasldata, NULL,
@@ -1858,7 +1875,7 @@ attemptauth(m, mci, e, sai)
in64[0] = '\0';
# if SASL < 20000
sm_sasl_free(out); /* XXX only if no rpool is used */
-# endif /* SASL < 20000 */
+# endif
smtpmessage("%s", m, mci, in64);
smtpresult = reply(m, mci, e, TimeOuts.to_auth,
getsasldata, NULL, XS_AUTH);
@@ -1939,15 +1956,15 @@ smtpauth(m, mci, e)
/* set the context for the callback function to sai */
# if SASL >= 20000
callbacks[CB_PASS_IDX].context = (void *) mci;
-# else /* SASL >= 20000 */
+# else
callbacks[CB_PASS_IDX].context = (void *) &mci->mci_sai;
-# endif /* SASL >= 20000 */
+# endif
callbacks[CB_USER_IDX].context = (void *) &mci->mci_sai;
callbacks[CB_AUTHNAME_IDX].context = (void *) &mci->mci_sai;
callbacks[CB_GETREALM_IDX].context = (void *) &mci->mci_sai;
#if 0
callbacks[CB_SAFESASL_IDX].context = (void *) &mci->mci_sai;
-#endif /* 0 */
+#endif
/* set default value for realm */
if ((mci->mci_sai)[SASL_DEFREALM] == NULL)
@@ -2027,6 +2044,19 @@ smtpmailfrom(m, mci, e)
return EX_TEMPFAIL;
}
+#if _FFR_EAI
+ /*
+ ** Abort right away if the message needs SMTPUTF8 and the
+ ** server does not advertise SMTPUTF8.
+ */
+
+ if (e->e_smtputf8 && !bitset(MCIF_EAI, mci->mci_flags)) {
+ usrerrenh("5.6.7", "%s does not support SMTPUTF8", CurHostName);
+ mci_setstat(mci, EX_NOTSTICKY, "5.6.7", NULL);
+ return EX_DATAERR;
+ }
+#endif /* _FFR_EAI */
+
/* set up appropriate options to include */
if (bitset(MCIF_SIZE, mci->mci_flags) && e->e_msgsize > 0)
{
@@ -2040,6 +2070,14 @@ smtpmailfrom(m, mci, e)
bufp = optbuf;
}
+#if _FFR_EAI
+ if (e->e_smtputf8) {
+ (void) sm_snprintf(bufp, SPACELEFT(optbuf, bufp),
+ " SMTPUTF8");
+ bufp += strlen(bufp);
+ }
+#endif /* _FFR_EAI */
+
bodytype = e->e_bodytype;
if (bitset(MCIF_8BITMIME, mci->mci_flags))
{
@@ -2110,7 +2148,7 @@ smtpmailfrom(m, mci, e)
SPACELEFT(optbuf, bufp) > strlen(e->e_auth_param) + 7
#if SASL
&& (!bitset(SASL_AUTH_AUTH, SASLOpts) || mci->mci_sasl_auth)
-#endif /* SASL */
+#endif
)
{
(void) sm_snprintf(bufp, SPACELEFT(optbuf, bufp),
@@ -2461,7 +2499,7 @@ smtprcptstat(to, m, mci, e)
}
#if PIPELINING
mci->mci_okrcpts++;
-#endif /* PIPELINING */
+#endif
return EX_OK;
}
else if (r == 550)
@@ -2555,8 +2593,6 @@ smtpdata(m, mci, e, ctladdr, xstart)
/* pick up any pending RCPT responses for SMTP pipelining */
while (mci->mci_nextaddr != NULL)
{
- int r;
-
e->e_to = mci->mci_nextaddr->q_paddr;
r = smtprcptstat(mci->mci_nextaddr, m, mci, e);
if (r != EX_OK)
@@ -2609,7 +2645,7 @@ smtpdata(m, mci, e, ctladdr, xstart)
if (mci->mci_okrcpts <= 0)
return mci->mci_retryrcpt ? EX_TEMPFAIL
: EX_UNAVAILABLE;
-#endif /* PIPELINING */
+#endif
return EX_UNAVAILABLE;
}
else if (REPLYTYPE(r) != 3)
@@ -2628,14 +2664,14 @@ smtpdata(m, mci, e, ctladdr, xstart)
if (mci->mci_okrcpts <= 0)
return mci->mci_retryrcpt ? EX_TEMPFAIL
: EX_PROTOCOL;
-#endif /* PIPELINING */
+#endif
return EX_PROTOCOL;
}
#if PIPELINING
if (mci->mci_okrcpts > 0)
{
-#endif /* PIPELINING */
+#endif
/*
** Set timeout around data writes. Make it at least large
@@ -2676,7 +2712,7 @@ smtpdata(m, mci, e, ctladdr, xstart)
#if PIPELINING
}
-#endif /* PIPELINING */
+#endif
#if _FFR_CATCH_BROKEN_MTAS
if (sm_io_getinfo(mci->mci_in, SM_IO_IS_READABLE, NULL) > 0)
@@ -2884,7 +2920,7 @@ smtpquit(m, mci, e)
#if PIPELINING
mci->mci_okrcpts = 0;
-#endif /* PIPELINING */
+#endif
/*
** Suppress errors here -- we may be processing a different
@@ -2961,7 +2997,7 @@ smtprset(m, mci, e)
#if PIPELINING
mci->mci_okrcpts = 0;
-#endif /* PIPELINING */
+#endif
/*
** Check if connection is gone, if so
@@ -3081,7 +3117,19 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
(void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT);
if (tTd(18, 1))
- sm_dprintf("reply\n");
+ {
+ char *what;
+
+ if (SmtpMsgBuffer[0] != '\0')
+ what = SmtpMsgBuffer;
+ else if (SmtpPhase != NULL && SmtpPhase[0] != '\0')
+ what = SmtpPhase;
+ else if (XS_GREET == rtype)
+ what = "greeting";
+ else
+ what = "unknown";
+ sm_dprintf("reply to %s\n", what);
+ }
/*
** Read the input line, being careful not to hang.
@@ -3150,9 +3198,9 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
CURHOSTNAME);
#ifdef ECONNRESET
errno = ECONNRESET;
-#else /* ECONNRESET */
+#else
errno = EPIPE;
-#endif /* ECONNRESET */
+#endif
}
mci->mci_errno = errno;
@@ -3250,14 +3298,15 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
firstline = false;
continue;
}
-#if _FFR_ERRCODE
+ if (REPLYTYPE(r) > 3 && firstline
# if _FFR_PROXY
- if ((e->e_rcode == 0 || REPLYTYPE(e->e_rcode) < 5)
- && REPLYTYPE(r) > 3 && firstline)
-# endif
-# if _FFR_LOGREPLY
- if (REPLYTYPE(r) > 3 && firstline)
+ &&
+ (e->e_sendmode != SM_PROXY
+ || (e->e_sendmode == SM_PROXY
+ && (e->e_rcode == 0 || REPLYTYPE(e->e_rcode) < 5))
+ )
# endif
+ )
{
int o = -1;
# if PIPELINING
@@ -3281,17 +3330,28 @@ reply(m, mci, e, timeout, pfunc, enhstat, rtype)
}
else
o = 4;
- e->e_rcode = r;
- e->e_text = sm_rpool_strdup_x(e->e_rpool,
- bufp + o);
+
+ /*
+ ** Don't use this for reply= logging
+ ** if it was for QUIT.
+ ** (Note: use the debug option to
+ ** reproduce the original error.)
+ */
+
+ if (rtype != XS_QUIT || tTd(87, 101))
+ {
+ e->e_rcode = r;
+ e->e_text = sm_rpool_strdup_x(
+ e->e_rpool, bufp + o);
+ }
}
if (tTd(87, 2))
{
- sm_dprintf("user: offset=%d, bufp=%s, rcode=%d, enhstat=%s, text=%s\n",
- o, bufp, r, e->e_renhsc, e->e_text);
+ sm_dprintf("user: e=%p, offset=%d, bufp=%s, rcode=%d, enhstat=%s, rtype=%d, text=%s\n"
+ , (void *)e, o, bufp, r, e->e_renhsc
+ , rtype, e->e_text);
}
}
-#endif /* _FFR_ERRCODE */
firstline = false;
diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c
index 9775915d6260..1cf6ddd811e7 100644
--- a/contrib/sendmail/src/util.c
+++ b/contrib/sendmail/src/util.c
@@ -1318,7 +1318,7 @@ sfgets(buf, siz, fp, timeout, during)
buf[0] = '\0';
#if XDEBUG
checkfd012(during);
-#endif /* XDEBUG */
+#endif
if (TrafficLogFile != NULL)
(void) sm_io_fprintf(TrafficLogFile,
SM_TIME_DEFAULT,
@@ -1386,6 +1386,7 @@ sfgets(buf, siz, fp, timeout, during)
** buf gets lines from f, with continuation lines (lines
** with leading white space) appended. CRLF's are mapped
** into single newlines. Any trailing NL is stripped.
+** Increases LineNumber for each line.
*/
char *
@@ -1752,7 +1753,7 @@ checkfds(where)
#if NETINET || NETINET6
# include <arpa/inet.h>
-#endif /* NETINET || NETINET6 */
+#endif
void
printopenfds(logit)
@@ -1788,14 +1789,14 @@ dumpfd(fd, printclosed, logit)
char *hp;
#ifdef S_IFSOCK
SOCKADDR sa;
-#endif /* S_IFSOCK */
+#endif
auto SOCKADDR_LEN_T slen;
int i;
#if STAT64 > 0
struct stat64 st;
-#else /* STAT64 > 0 */
+#else
struct stat st;
-#endif /* STAT64 > 0 */
+#endif
char buf[200];
p = buf;
@@ -1805,9 +1806,9 @@ dumpfd(fd, printclosed, logit)
if (
#if STAT64 > 0
fstat64(fd, &st)
-#else /* STAT64 > 0 */
+#else
fstat(fd, &st)
-#endif /* STAT64 > 0 */
+#endif
< 0)
{
if (errno != EBADF)
@@ -1858,12 +1859,12 @@ dumpfd(fd, printclosed, logit)
else if (sa.sa.sa_family == AF_INET)
(void) sm_snprintf(p, SPACELEFT(buf, p),
"%s/%d", hp, ntohs(sa.sin.sin_port));
-# endif /* NETINET */
+# endif
# if NETINET6
else if (sa.sa.sa_family == AF_INET6)
(void) sm_snprintf(p, SPACELEFT(buf, p),
"%s/%d", hp, ntohs(sa.sin6.sin6_port));
-# endif /* NETINET6 */
+# endif
else
(void) sm_snprintf(p, SPACELEFT(buf, p),
"%s", hp);
@@ -1887,12 +1888,12 @@ dumpfd(fd, printclosed, logit)
else if (sa.sa.sa_family == AF_INET)
(void) sm_snprintf(p, SPACELEFT(buf, p),
"%s/%d", hp, ntohs(sa.sin.sin_port));
-# endif /* NETINET */
+# endif
# if NETINET6
else if (sa.sa.sa_family == AF_INET6)
(void) sm_snprintf(p, SPACELEFT(buf, p),
"%s/%d", hp, ntohs(sa.sin6.sin6_port));
-# endif /* NETINET6 */
+# endif
else
(void) sm_snprintf(p, SPACELEFT(buf, p),
"%s", hp);
@@ -1910,28 +1911,28 @@ dumpfd(fd, printclosed, logit)
(void) sm_snprintf(p, SPACELEFT(buf, p), "BLK: ");
p += strlen(p);
goto defprint;
-#endif /* S_IFBLK */
+#endif
#if defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK)
case S_IFIFO:
(void) sm_snprintf(p, SPACELEFT(buf, p), "FIFO: ");
p += strlen(p);
goto defprint;
-#endif /* defined(S_IFIFO) && (!defined(S_IFSOCK) || S_IFIFO != S_IFSOCK) */
+#endif
#ifdef S_IFDIR
case S_IFDIR:
(void) sm_snprintf(p, SPACELEFT(buf, p), "DIR: ");
p += strlen(p);
goto defprint;
-#endif /* S_IFDIR */
+#endif
#ifdef S_IFLNK
case S_IFLNK:
(void) sm_snprintf(p, SPACELEFT(buf, p), "LNK: ");
p += strlen(p);
goto defprint;
-#endif /* S_IFLNK */
+#endif
default:
defprint:
@@ -2123,7 +2124,7 @@ prog_open(argv, pfd, e)
sm_mbdb_terminate();
#if _FFR_MEMSTAT
(void) sm_memstat_close();
-#endif /* _FFR_MEMSTAT */
+#endif
if (setgid(DefGid) < 0 && geteuid() == 0)
{
syserr("prog_open: setgid(%ld) failed", (long) DefGid);
@@ -2234,7 +2235,7 @@ get_column(line, col, delim, buf, buflen)
if (col == 0 && (char) delim == '\0')
{
- while (*begin != '\0' && isascii(*begin) && isspace(*begin))
+ while (*begin != '\0' && SM_ISSPACE(*begin))
begin++;
}
@@ -2245,7 +2246,7 @@ get_column(line, col, delim, buf, buflen)
begin++;
if ((char) delim == '\0')
{
- while (*begin != '\0' && isascii(*begin) && isspace(*begin))
+ while (*begin != '\0' && SM_ISSPACE(*begin))
begin++;
}
}
@@ -2414,9 +2415,9 @@ path_is_dir(pathname, createflag)
#if HASLSTAT
if (lstat(pathname, &statbuf) < 0)
-#else /* HASLSTAT */
+#else
if (stat(pathname, &statbuf) < 0)
-#endif /* HASLSTAT */
+#endif
{
if (errno != ENOENT || !createflag)
return false;
@@ -2706,7 +2707,7 @@ proc_list_probe()
"proc_list_probe: lost pid %d",
(int) ProcListVec[i].proc_pid);
ProcListVec[i].proc_pid = NO_PID;
- SM_FREE_CLR(ProcListVec[i].proc_task);
+ SM_FREE(ProcListVec[i].proc_task);
if (ProcListVec[i].proc_type == PROC_QUEUE)
{
@@ -2855,13 +2856,13 @@ count_open_connections(hostaddr)
(hostaddr->sin.sin_addr.s_addr ==
ProcListVec[i].proc_hostaddr.sin.sin_addr.s_addr))
n++;
-#endif /* NETINET */
+#endif
#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 */
+#endif
}
return n;
}
@@ -2920,13 +2921,28 @@ xconnect(inchannel)
return 0;
}
+# if _FFR_XCNCT > 1
+ if (pvp != NULL && pvp[0] != NULL &&
+ pvp[0][0] == '2' && pvp[0][1] == '2' && pvp[0][2] == '0')
+ {
+ char *hostname; /* my hostname ($j) */
+
+ hostname = macvalue('j', &BlankEnvelope);
+ if (tTd(75, 7))
+ sm_syslog(LOG_INFO, NOQID, "x-connect=%s", pvp[0]);
+ message("220-%s %s", hostname != NULL ? hostname : "xconnect",
+ pvp[1] != NULL ? pvp[1] : "waiting for xconnect");
+ sm_io_flush(OutChannel, SM_TIME_DEFAULT);
+ }
+# endif
+
p = sfgets(inp, sizeof(inp), InChannel, TimeOuts.to_nextcommand, "pre");
if (tTd(75, 6))
sm_syslog(LOG_INFO, NOQID, "x-connect: input=%s", p);
if (p == NULL || strncasecmp(p, XCONNECT, XCNNCTLEN) != 0)
return -1;
p += XCNNCTLEN;
- while (isascii(*p) && isspace(*p))
+ while (SM_ISSPACE(*p))
p++;
/* parameters: IPAddress [Hostname[ M]] */
@@ -2953,15 +2969,13 @@ xconnect(inchannel)
addr.sa.sa_family = AF_INET6;
memcpy(&RealHostAddr, &addr, sizeof(addr));
}
-# endif /* NETINET6 */
+# endif
else
return -1;
/* more parameters? */
if (delim != ' ')
return D_XCNCT;
- while (*p != '\0' && isascii(*p) && isspace(*p))
- p++;
for (b = ++p, i = 0;
*p != '\0' && isascii(*p) && (isalnum(*p) || *p == '.' || *p == '-');
@@ -2974,7 +2988,7 @@ xconnect(inchannel)
b[MAXNAME] = '\0';
else
b[i] = '\0';
- SM_FREE_CLR(RealHostName);
+ SM_FREE(RealHostName);
RealHostName = newstr(b);
if (tTd(75, 2))
sm_syslog(LOG_INFO, NOQID, "x-connect: host=%s", b);
@@ -2984,7 +2998,7 @@ xconnect(inchannel)
if (*p != ' ')
return D_XCNCT;
- while (*p != '\0' && isascii(*p) && isspace(*p))
+ while (*p != '\0' && SM_ISSPACE(*p))
p++;
if (tTd(75, 4))
diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c
index 7145ce219840..1cb5140b0521 100644
--- a/contrib/sendmail/src/version.c
+++ b/contrib/sendmail/src/version.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2015 Proofpoint, Inc. and its suppliers.
+ * Copyright (c) 1998-2016 Proofpoint, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -15,4 +15,4 @@
SM_RCSID("@(#)$Id: version.c,v 8.250 2014-01-27 12:55:16 ca Exp $")
-char Version[] = "8.15.2";
+char Version[] = "8.16.1";
diff --git a/contrib/sendmail/test/Results b/contrib/sendmail/test/Results
index 508427b3708c..b1ad0050a9c2 100644
--- a/contrib/sendmail/test/Results
+++ b/contrib/sendmail/test/Results
@@ -11,7 +11,7 @@ SunOS 4.1 OK 93.07.19 eric
SunOS 4.1.2 OK 93.07.19 eric
SunOS 4.1.3 OK 93.09.25 Robert Elz
-BSD 4.4 OK 93.07.19 eric (wierd results, but functional)
+BSD 4.4 OK 93.07.19 eric (weird results, but functional)
BSD 4.3Utah OK 93.07.19 eric
FreeBSD 2.1-sta OK 96.04.14 Jaye Mathisen <mrcpu@cdsnet.net>
diff --git a/contrib/sendmail/vacation/Makefile b/contrib/sendmail/vacation/Makefile
index 68f48c394f8b..b670f863b537 100644
--- a/contrib/sendmail/vacation/Makefile
+++ b/contrib/sendmail/vacation/Makefile
@@ -8,6 +8,8 @@ all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
+check: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
diff --git a/contrib/sendmail/vacation/vacation.c b/contrib/sendmail/vacation/vacation.c
index 1196464e72d2..72032748d624 100644
--- a/contrib/sendmail/vacation/vacation.c
+++ b/contrib/sendmail/vacation/vacation.c
@@ -30,7 +30,7 @@ SM_IDSTR(id, "@(#)$Id: vacation.c,v 8.148 2013-11-22 20:52:02 ca Exp $")
#include <unistd.h>
#ifdef EX_OK
# undef EX_OK /* unistd.h may have another use for this */
-#endif /* EX_OK */
+#endif
#include <sm/sysexits.h>
#include <sm/cf.h>
@@ -93,16 +93,16 @@ bool CloseMBDB = false;
#if defined(__hpux) || defined(__osf__)
# ifndef SM_CONF_SYSLOG_INT
# define SM_CONF_SYSLOG_INT 1
-# endif /* SM_CONF_SYSLOG_INT */
+# endif
#endif /* defined(__hpux) || defined(__osf__) */
#if SM_CONF_SYSLOG_INT
# define SYSLOG_RET_T int
# define SYSLOG_RET return 0
-#else /* SM_CONF_SYSLOG_INT */
+#else
# define SYSLOG_RET_T void
# define SYSLOG_RET
-#endif /* SM_CONF_SYSLOG_INT */
+#endif
typedef SYSLOG_RET_T SYSLOG_T __P((int, const char *, ...));
SYSLOG_T *msglog = syslog;
@@ -178,9 +178,9 @@ main(argc, argv)
# ifdef LOG_MAIL
openlog("vacation", LOG_PID, LOG_MAIL);
-# else /* LOG_MAIL */
+# else
openlog("vacation", LOG_PID);
-# endif /* LOG_MAIL */
+# endif
opterr = 0;
initdb = false;
@@ -767,7 +767,7 @@ junkmail(from)
#if 0
if (quot)
return false; /* syntax error... */
-#endif /* 0 */
+#endif
/* test prefixes */
for (cur = ignorepre; cur->name != NULL; ++cur)
@@ -1041,9 +1041,9 @@ sendmessage(myname, msgfn, sender)
#if _FFR_VAC_WAIT4SM
# ifdef WAITUNION
union wait st;
-# else /* WAITUNION */
+# else
auto int st;
-# endif /* WAITUNION */
+# endif
#endif /* _FFR_VAC_WAIT4SM */
(void) sm_io_fprintf(sfp, SM_TIME_DEFAULT, "To: %s\n", From);
@@ -1055,7 +1055,7 @@ sendmessage(myname, msgfn, sender)
(void) sm_io_close(sfp, SM_TIME_DEFAULT);
#if _FFR_VAC_WAIT4SM
(void) wait(&st);
-#endif /* _FFR_VAC_WAIT4SM */
+#endif
}
else
{