diff options
| author | perry <perry@NetBSD.org> | 2002-02-02 23:54:35 +0000 |
|---|---|---|
| committer | perry <perry@NetBSD.org> | 2002-02-02 23:54:35 +0000 |
| commit | 00f7fe97b451ad732deadff4dbb7475ee126e9ed (patch) | |
| tree | f21fc4189931957cb7a4e66369aeae91f9090209 /gnu | |
| parent | 5cf194aa6d2ac7c4abbed5161e5485e691b13df2 (diff) | |
resolve conflicts
Diffstat (limited to 'gnu')
| -rw-r--r-- | gnu/dist/postfix/makedefs | 32 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/global/Makefile.in | 129 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/global/resolve_local.c | 13 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/global/tok822_parse.c | 67 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/master/master.h | 6 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/master/master_ent.c | 4 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/master/master_listen.c | 5 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/qmgr/qmgr_message.c | 14 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtp/smtp_addr.c | 57 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtpd/smtpd.c | 349 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtpd/smtpd_check.c | 600 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/smtpd/smtpd_peer.c | 1 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/Makefile.in | 322 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/match_list.c | 29 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/match_ops.c | 47 | ||||
| -rw-r--r-- | gnu/dist/postfix/src/util/sys_defs.h | 103 |
16 files changed, 1322 insertions, 456 deletions
diff --git a/gnu/dist/postfix/makedefs b/gnu/dist/postfix/makedefs index 2f110f03fdb..139ae070841 100644 --- a/gnu/dist/postfix/makedefs +++ b/gnu/dist/postfix/makedefs @@ -93,6 +93,8 @@ case "$SYSTEM.$RELEASE" in ;; OpenBSD.2*) SYSTYPE=OPENBSD2 ;; + OpenBSD.3*) SYSTYPE=OPENBSD3 + ;; NetBSD.1*) SYSTYPE=NETBSD1 ;; BSD/OS.2*) SYSTYPE=BSDI2 @@ -142,6 +144,12 @@ case "$SYSTEM.$RELEASE" in done ;; AIX.*) case "`uname -v`" in + 5) SYSTYPE=AIX4 + case "$CC" in + cc|*/cc|xlc|*/xlc) CCARGS="$CCARGS -w -blibpath:/usr/lib:/lib:/usr/local/lib";; + esac + CCARGS="$CCARGS -D_ALL_SOURCE -DHAS_POSIX_REGEXP" + ;; 4) SYSTYPE=AIX4 # How embarrassing... case "$CC" in @@ -175,10 +183,22 @@ case "$SYSTEM.$RELEASE" in echo "See the RELEASE_NOTES file for more information." 1>&2 exit 1 fi + # See where GDBM's ndbm.h include file sits. + if [ -f /usr/include/gdbm-ndbm.h ] + then + CCARGS="$CCARGS -DHAS_DBM -DPATH_NDBM_H='<gdbm-ndbm.h>'" + GDBM_LIBS=gdbm + elif [ -f /usr/include/gdbm/ndbm.h ] + then + CCARGS="$CCARGS -DHAS_DBM -DPATH_NDBM_H='<gdbm/ndbm.h>'" + GDBM_LIBS=gdbm + fi SYSLIBS="-ldb" - for name in nsl resolv + for name in nsl resolv $GDBM_LIBS do - test -f /usr/lib/lib$name.a && SYSLIBS="$SYSLIBS -l$name" + test -e /usr/lib/lib$name.a -o -e /usr/lib/lib$name.so \ + -o -e /lib/lib$name.a -o -e /lib/lib$name.so \ + && SYSLIBS="$SYSLIBS -l$name" done ;; IRIX*.5.*) SYSTYPE=IRIX5 @@ -218,11 +238,17 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 RANLIB=echo SYSLIBS="-lresolv -lsocket -lnsl" ;; -Rhapsody.5*|Darwin.1.*) +Rhapsody.5*|Darwin.*) SYSTYPE=RHAPSODY5 # Use the native compiler by default : ${CC=cc} AWK=gawk + case $RELEASE in + 1.[0-3]) ;; + *) AWK=awk + SYSLIBS=-flat_namespace + ;; + esac ;; "Mac OS".10*) SYSTYPE=MACOSX # Use the native compiler by default diff --git a/gnu/dist/postfix/src/global/Makefile.in b/gnu/dist/postfix/src/global/Makefile.in index 43d75aed068..6083e1107b1 100644 --- a/gnu/dist/postfix/src/global/Makefile.in +++ b/gnu/dist/postfix/src/global/Makefile.in @@ -4,41 +4,43 @@ SRCS = been_here.c bounce.c canon_addr.c cleanup_strerror.c clnt_stream.c \ deliver_flock.c deliver_pass.c deliver_request.c domain_list.c \ dot_lockfile.c dot_lockfile_as.c ext_prop.c file_id.c \ header_opts.c is_header.c mail_addr.c mail_addr_crunch.c \ - mail_addr_find.c mail_addr_map.c mail_command_read.c \ - mail_command_write.c mail_conf.c mail_conf_bool.c mail_conf_int.c \ + mail_addr_find.c mail_addr_map.c mail_command_server.c \ + mail_command_client.c mail_conf.c mail_conf_bool.c mail_conf_int.c \ mail_conf_raw.c mail_conf_str.c mail_connect.c mail_copy.c \ mail_date.c mail_error.c mail_flush.c mail_open_ok.c mail_params.c \ - mail_pathname.c mail_print.c mail_queue.c mail_run.c mail_scan.c \ + mail_pathname.c mail_queue.c mail_run.c \ mail_scan_dir.c mail_stream.c mail_task.c mail_trigger.c maps.c \ mark_corrupt.c mkmap_db.c mkmap_dbm.c mkmap_open.c mynetworks.c \ mypwd.c namadr_list.c off_cvt.c opened.c own_inet_addr.c \ - peer_name.c pipe_command.c post_mail.c quote_821_local.c \ + pipe_command.c post_mail.c quote_821_local.c \ quote_822_local.c rec_streamlf.c rec_type.c recipient_list.c \ record.c remove.c resolve_clnt.c resolve_local.c rewrite_clnt.c \ sent.c smtp_stream.c split_addr.c string_list.c sys_exits.c \ timed_ipc.c tok822_find.c tok822_node.c tok822_parse.c \ tok822_resolve.c tok822_rewrite.c tok822_tree.c xtext.c bounce_log.c \ - flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c + flush_clnt.c mail_conf_time.c mbox_conf.c mbox_open.c abounce.c \ + verp_sender.c match_parent_style.c OBJS = been_here.o bounce.o canon_addr.o cleanup_strerror.o clnt_stream.o \ debug_peer.o debug_process.o defer.o deliver_completed.o \ deliver_flock.o deliver_pass.o deliver_request.o domain_list.o \ dot_lockfile.o dot_lockfile_as.o ext_prop.o file_id.o \ header_opts.o is_header.o mail_addr.o mail_addr_crunch.o \ - mail_addr_find.o mail_addr_map.o mail_command_read.o \ - mail_command_write.o mail_conf.o mail_conf_bool.o mail_conf_int.o \ + mail_addr_find.o mail_addr_map.o mail_command_server.o \ + mail_command_client.o mail_conf.o mail_conf_bool.o mail_conf_int.o \ mail_conf_raw.o mail_conf_str.o mail_connect.o mail_copy.o \ mail_date.o mail_error.o mail_flush.o mail_open_ok.o mail_params.o \ - mail_pathname.o mail_print.o mail_queue.o mail_run.o mail_scan.o \ + mail_pathname.o mail_queue.o mail_run.o \ mail_scan_dir.o mail_stream.o mail_task.o mail_trigger.o maps.o \ mark_corrupt.o mkmap_db.o mkmap_dbm.o mkmap_open.o mynetworks.o \ mypwd.o namadr_list.o off_cvt.o opened.o own_inet_addr.o \ - peer_name.o pipe_command.o post_mail.o quote_821_local.o \ + pipe_command.o post_mail.o quote_821_local.o \ quote_822_local.o rec_streamlf.o rec_type.o recipient_list.o \ record.o remove.o resolve_clnt.o resolve_local.o rewrite_clnt.o \ sent.o smtp_stream.o split_addr.o string_list.o sys_exits.o \ timed_ipc.o tok822_find.o tok822_node.o tok822_parse.o \ tok822_resolve.o tok822_rewrite.o tok822_tree.o xtext.o bounce_log.o \ - flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o + flush_clnt.o mail_conf_time.o mbox_conf.o mbox_open.o abounce.o \ + verp_sender.o match_parent_style.o HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \ config.h debug_peer.h debug_process.h defer.h deliver_completed.h \ deliver_flock.h deliver_pass.h deliver_request.h domain_list.h \ @@ -49,12 +51,13 @@ HDRS = been_here.h bounce.h canon_addr.h cleanup_user.h clnt_stream.h \ mail_proto.h mail_queue.h mail_run.h mail_scan_dir.h mail_stream.h \ mail_task.h mail_version.h maps.h mark_corrupt.h mkmap.h \ mynetworks.h mypwd.h namadr_list.h off_cvt.h opened.h \ - own_inet_addr.h peer_name.h pipe_command.h post_mail.h \ + own_inet_addr.h pipe_command.h post_mail.h \ quote_821_local.h quote_822_local.h rec_streamlf.h rec_type.h \ recipient_list.h record.h resolve_clnt.h resolve_local.h \ rewrite_clnt.h sent.h smtp_stream.h split_addr.h string_list.h \ sys_exits.h timed_ipc.h tok822.h xtext.h bounce_log.h flush_clnt.h \ - mbox_conf.h mbox_open.h abounce.h + mbox_conf.h mbox_open.h abounce.h qmqp_proto.h verp_sender.h \ + match_parent_style.h TESTSRC = rec2stream.c stream2rec.c recdump.c WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ @@ -65,7 +68,7 @@ INCL = LIB = libglobal.a TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \ mail_addr_map mail_date maps mynetworks mypwd namadr_list \ - off_cvt peer_name quote_822_local rec2stream recdump resolve_clnt \ + off_cvt quote_822_local rec2stream recdump resolve_clnt \ resolve_local rewrite_clnt stream2rec string_list tok822_parse \ quote_821_local mail_conf_time @@ -252,6 +255,7 @@ abounce.o: ../../include/vstream.h abounce.o: ../../include/vbuf.h abounce.o: mail_proto.h abounce.o: ../../include/iostuff.h +abounce.o: ../../include/attr.h abounce.o: abounce.h abounce.o: bounce.h been_here.o: been_here.c @@ -272,6 +276,7 @@ bounce.o: mail_params.h bounce.o: mail_proto.h bounce.o: ../../include/vstream.h bounce.o: ../../include/iostuff.h +bounce.o: ../../include/attr.h bounce.o: defer.h bounce.o: bounce.h bounce_log.o: bounce_log.c @@ -306,6 +311,7 @@ clnt_stream.o: ../../include/vbuf.h clnt_stream.o: ../../include/events.h clnt_stream.o: ../../include/iostuff.h clnt_stream.o: mail_proto.h +clnt_stream.o: ../../include/attr.h clnt_stream.o: mail_params.h clnt_stream.o: clnt_stream.h debug_peer.o: debug_peer.c @@ -313,7 +319,10 @@ debug_peer.o: ../../include/sys_defs.h debug_peer.o: ../../include/msg.h debug_peer.o: mail_params.h debug_peer.o: namadr_list.h +debug_peer.o: ../../include/match_list.h +debug_peer.o: ../../include/match_ops.h debug_peer.o: debug_peer.h +debug_peer.o: match_parent_style.h debug_process.o: debug_process.c debug_process.o: ../../include/sys_defs.h debug_process.o: ../../include/msg.h @@ -329,6 +338,7 @@ defer.o: mail_queue.h defer.o: ../../include/vstream.h defer.o: mail_proto.h defer.o: ../../include/iostuff.h +defer.o: ../../include/attr.h defer.o: flush_clnt.h defer.o: bounce.h defer.o: defer.h @@ -363,6 +373,7 @@ deliver_pass.o: deliver_request.h deliver_pass.o: recipient_list.h deliver_pass.o: mail_proto.h deliver_pass.o: ../../include/iostuff.h +deliver_pass.o: ../../include/attr.h deliver_request.o: deliver_request.c deliver_request.o: ../../include/sys_defs.h deliver_request.o: ../../include/msg.h @@ -374,14 +385,15 @@ deliver_request.o: ../../include/iostuff.h deliver_request.o: ../../include/myflock.h deliver_request.o: mail_queue.h deliver_request.o: mail_proto.h +deliver_request.o: ../../include/attr.h deliver_request.o: mail_open_ok.h deliver_request.o: recipient_list.h deliver_request.o: deliver_request.h domain_list.o: domain_list.c domain_list.o: ../../include/sys_defs.h domain_list.o: ../../include/match_list.h -domain_list.o: ../../include/match_ops.h domain_list.o: domain_list.h +domain_list.o: ../../include/match_ops.h dot_lockfile.o: dot_lockfile.c dot_lockfile.o: ../../include/sys_defs.h dot_lockfile.o: ../../include/vstring.h @@ -417,6 +429,7 @@ flush_clnt.o: ../../include/vstream.h flush_clnt.o: ../../include/vbuf.h flush_clnt.o: mail_proto.h flush_clnt.o: ../../include/iostuff.h +flush_clnt.o: ../../include/attr.h flush_clnt.o: mail_flush.h flush_clnt.o: flush_clnt.h flush_clnt.o: mail_params.h @@ -475,19 +488,20 @@ mail_addr_map.o: mail_addr_find.h mail_addr_map.o: maps.h mail_addr_map.o: mail_addr_crunch.h mail_addr_map.o: mail_addr_map.h -mail_command_read.o: mail_command_read.c -mail_command_read.o: ../../include/sys_defs.h -mail_command_read.o: ../../include/vstring.h -mail_command_read.o: ../../include/vbuf.h -mail_command_read.o: ../../include/vstream.h -mail_command_read.o: mail_proto.h -mail_command_read.o: ../../include/iostuff.h -mail_command_write.o: mail_command_write.c -mail_command_write.o: ../../include/sys_defs.h -mail_command_write.o: ../../include/vstream.h -mail_command_write.o: ../../include/vbuf.h -mail_command_write.o: mail_proto.h -mail_command_write.o: ../../include/iostuff.h +mail_command_client.o: mail_command_client.c +mail_command_client.o: ../../include/sys_defs.h +mail_command_client.o: ../../include/vstream.h +mail_command_client.o: ../../include/vbuf.h +mail_command_client.o: mail_proto.h +mail_command_client.o: ../../include/iostuff.h +mail_command_client.o: ../../include/attr.h +mail_command_server.o: mail_command_server.c +mail_command_server.o: ../../include/sys_defs.h +mail_command_server.o: ../../include/vstream.h +mail_command_server.o: ../../include/vbuf.h +mail_command_server.o: mail_proto.h +mail_command_server.o: ../../include/iostuff.h +mail_command_server.o: ../../include/attr.h mail_conf.o: mail_conf.c mail_conf.o: ../../include/sys_defs.h mail_conf.o: ../../include/msg.h @@ -499,6 +513,7 @@ mail_conf.o: ../../include/dict.h mail_conf.o: ../../include/argv.h mail_conf.o: ../../include/safe.h mail_conf.o: ../../include/stringops.h +mail_conf.o: ../../include/readlline.h mail_conf.o: mail_params.h mail_conf.o: mail_conf.h mail_conf_bool.o: mail_conf_bool.c @@ -549,8 +564,11 @@ mail_connect.o: ../../include/vbuf.h mail_connect.o: ../../include/connect.h mail_connect.o: ../../include/iostuff.h mail_connect.o: ../../include/mymalloc.h +mail_connect.o: ../../include/stringops.h +mail_connect.o: ../../include/vstring.h mail_connect.o: timed_ipc.h mail_connect.o: mail_proto.h +mail_connect.o: ../../include/attr.h mail_copy.o: mail_copy.c mail_copy.o: ../../include/sys_defs.h mail_copy.o: ../../include/msg.h @@ -565,8 +583,9 @@ mail_copy.o: record.h mail_copy.o: rec_type.h mail_copy.o: mail_queue.h mail_copy.o: mail_addr.h -mail_copy.o: mail_copy.h mail_copy.o: mark_corrupt.h +mail_copy.o: mail_params.h +mail_copy.o: mail_copy.h mail_date.o: mail_date.c mail_date.o: ../../include/sys_defs.h mail_date.o: ../../include/msg.h @@ -583,6 +602,7 @@ mail_flush.o: mail_proto.h mail_flush.o: ../../include/vstream.h mail_flush.o: ../../include/vbuf.h mail_flush.o: ../../include/iostuff.h +mail_flush.o: ../../include/attr.h mail_flush.o: mail_flush.h mail_open_ok.o: mail_open_ok.c mail_open_ok.o: ../../include/sys_defs.h @@ -601,12 +621,15 @@ mail_params.o: ../../include/valid_hostname.h mail_params.o: ../../include/stringops.h mail_params.o: ../../include/vstring.h mail_params.o: ../../include/vbuf.h +mail_params.o: ../../include/safe.h mail_params.o: mynetworks.h mail_params.o: mail_conf.h mail_params.o: mail_version.h mail_params.o: mail_proto.h mail_params.o: ../../include/vstream.h mail_params.o: ../../include/iostuff.h +mail_params.o: ../../include/attr.h +mail_params.o: verp_sender.h mail_params.o: mail_params.h mail_pathname.o: mail_pathname.c mail_pathname.o: ../../include/sys_defs.h @@ -616,14 +639,7 @@ mail_pathname.o: ../../include/vbuf.h mail_pathname.o: mail_proto.h mail_pathname.o: ../../include/vstream.h mail_pathname.o: ../../include/iostuff.h -mail_print.o: mail_print.c -mail_print.o: ../../include/sys_defs.h -mail_print.o: ../../include/msg.h -mail_print.o: ../../include/mymalloc.h -mail_print.o: ../../include/vstream.h -mail_print.o: ../../include/vbuf.h -mail_print.o: mail_proto.h -mail_print.o: ../../include/iostuff.h +mail_pathname.o: ../../include/attr.h mail_queue.o: mail_queue.c mail_queue.o: ../../include/sys_defs.h mail_queue.o: ../../include/msg.h @@ -649,16 +665,6 @@ mail_run.o: ../../include/vbuf.h mail_run.o: ../../include/mymalloc.h mail_run.o: mail_params.h mail_run.o: mail_run.h -mail_scan.o: mail_scan.c -mail_scan.o: ../../include/sys_defs.h -mail_scan.o: ../../include/msg.h -mail_scan.o: ../../include/vstring.h -mail_scan.o: ../../include/vbuf.h -mail_scan.o: ../../include/vstream.h -mail_scan.o: ../../include/vstring_vstream.h -mail_scan.o: ../../include/mymalloc.h -mail_scan.o: mail_proto.h -mail_scan.o: ../../include/iostuff.h mail_scan_dir.o: mail_scan_dir.c mail_scan_dir.o: ../../include/sys_defs.h mail_scan_dir.o: ../../include/scan_dir.h @@ -675,6 +681,7 @@ mail_stream.o: ../../include/argv.h mail_stream.o: cleanup_user.h mail_stream.o: mail_proto.h mail_stream.o: ../../include/iostuff.h +mail_stream.o: ../../include/attr.h mail_stream.o: mail_queue.h mail_stream.o: opened.h mail_stream.o: mail_params.h @@ -683,7 +690,9 @@ mail_task.o: mail_task.c mail_task.o: ../../include/sys_defs.h mail_task.o: ../../include/vstring.h mail_task.o: ../../include/vbuf.h +mail_task.o: ../../include/safe.h mail_task.o: mail_params.h +mail_task.o: mail_conf.h mail_task.o: mail_task.h mail_trigger.o: mail_trigger.c mail_trigger.o: ../../include/sys_defs.h @@ -695,6 +704,7 @@ mail_trigger.o: mail_params.h mail_trigger.o: mail_proto.h mail_trigger.o: ../../include/vstream.h mail_trigger.o: ../../include/vbuf.h +mail_trigger.o: ../../include/attr.h mail_version.o: mail_version.c maps.o: maps.c maps.o: ../../include/sys_defs.h @@ -714,9 +724,20 @@ mark_corrupt.o: ../../include/sys_defs.h mark_corrupt.o: ../../include/msg.h mark_corrupt.o: ../../include/vstream.h mark_corrupt.o: ../../include/vbuf.h +mark_corrupt.o: ../../include/set_eugid.h mark_corrupt.o: mail_queue.h mark_corrupt.o: ../../include/vstring.h +mark_corrupt.o: mail_params.h +mark_corrupt.o: deliver_request.h +mark_corrupt.o: recipient_list.h mark_corrupt.o: mark_corrupt.h +match_parent_style.o: match_parent_style.c +match_parent_style.o: ../../include/sys_defs.h +match_parent_style.o: string_list.h +match_parent_style.o: ../../include/match_list.h +match_parent_style.o: ../../include/match_ops.h +match_parent_style.o: mail_params.h +match_parent_style.o: match_parent_style.h mbox_conf.o: mbox_conf.c mbox_conf.o: ../../include/sys_defs.h mbox_conf.o: ../../include/name_mask.h @@ -795,8 +816,8 @@ mypwd.o: mypwd.h namadr_list.o: namadr_list.c namadr_list.o: ../../include/sys_defs.h namadr_list.o: ../../include/match_list.h -namadr_list.o: ../../include/match_ops.h namadr_list.o: namadr_list.h +namadr_list.o: ../../include/match_ops.h off_cvt.o: off_cvt.c off_cvt.o: ../../include/sys_defs.h off_cvt.o: ../../include/msg.h @@ -854,6 +875,7 @@ post_mail.o: record.h post_mail.o: rec_type.h post_mail.o: mail_proto.h post_mail.o: ../../include/iostuff.h +post_mail.o: ../../include/attr.h post_mail.o: cleanup_user.h post_mail.o: post_mail.h post_mail.o: mail_date.h @@ -921,6 +943,7 @@ resolve_clnt.o: ../../include/vstring_vstream.h resolve_clnt.o: ../../include/events.h resolve_clnt.o: ../../include/iostuff.h resolve_clnt.o: mail_proto.h +resolve_clnt.o: ../../include/attr.h resolve_clnt.o: mail_params.h resolve_clnt.o: clnt_stream.h resolve_clnt.o: resolve_clnt.h @@ -929,9 +952,12 @@ resolve_local.o: ../../include/sys_defs.h resolve_local.o: ../../include/msg.h resolve_local.o: ../../include/mymalloc.h resolve_local.o: string_list.h +resolve_local.o: ../../include/match_list.h +resolve_local.o: ../../include/match_ops.h resolve_local.o: mail_params.h resolve_local.o: own_inet_addr.h resolve_local.o: resolve_local.h +resolve_local.o: match_parent_style.h rewrite_clnt.o: rewrite_clnt.c rewrite_clnt.o: ../../include/sys_defs.h rewrite_clnt.o: ../../include/msg.h @@ -943,6 +969,7 @@ rewrite_clnt.o: ../../include/events.h rewrite_clnt.o: ../../include/iostuff.h rewrite_clnt.o: quote_822_local.h rewrite_clnt.o: mail_proto.h +rewrite_clnt.o: ../../include/attr.h rewrite_clnt.o: mail_params.h rewrite_clnt.o: clnt_stream.h rewrite_clnt.o: rewrite_clnt.h @@ -978,8 +1005,8 @@ stream2rec.o: rec_type.h string_list.o: string_list.c string_list.o: ../../include/sys_defs.h string_list.o: ../../include/match_list.h -string_list.o: ../../include/match_ops.h string_list.o: string_list.h +string_list.o: ../../include/match_ops.h sys_exits.o: sys_exits.c sys_exits.o: ../../include/sys_defs.h sys_exits.o: ../../include/msg.h @@ -1033,6 +1060,12 @@ tok822_tree.o: ../../include/vstring.h tok822_tree.o: ../../include/vbuf.h tok822_tree.o: tok822.h tok822_tree.o: resolve_clnt.h +verp_sender.o: verp_sender.c +verp_sender.o: ../../include/sys_defs.h +verp_sender.o: ../../include/vstring.h +verp_sender.o: ../../include/vbuf.h +verp_sender.o: mail_params.h +verp_sender.o: verp_sender.h xtext.o: xtext.c xtext.o: ../../include/sys_defs.h xtext.o: ../../include/vstream.h diff --git a/gnu/dist/postfix/src/global/resolve_local.c b/gnu/dist/postfix/src/global/resolve_local.c index 42fbae7b3fe..f9ff2d203f6 100644 --- a/gnu/dist/postfix/src/global/resolve_local.c +++ b/gnu/dist/postfix/src/global/resolve_local.c @@ -2,14 +2,14 @@ /* NAME /* resolve_local 3 /* SUMMARY -/* determine if address resolves to local mail system +/* determine if domain resolves to local mail system /* SYNOPSIS /* #include <resolve_local.h> /* /* void resolve_local_init() /* -/* int resolve_local(host) -/* const char *host; +/* int resolve_local(domain) +/* const char *domain; /* DESCRIPTION /* resolve_local() determines if the named domain resolves to the /* local mail system, either by case-insensitive exact match @@ -58,6 +58,7 @@ #include <mail_params.h> #include <own_inet_addr.h> #include <resolve_local.h> +#include <match_parent_style.h> /* Application-specific */ @@ -69,10 +70,10 @@ void resolve_local_init(void) { if (resolve_local_list) msg_panic("resolve_local_init: duplicate initialization"); - resolve_local_list = string_list_init(var_mydest); + resolve_local_list = string_list_init(MATCH_FLAG_NONE, var_mydest); } -/* resolve_local - match address against list of local destinations */ +/* resolve_local - match domain against list of local destinations */ int resolve_local(const char *addr) { @@ -90,6 +91,8 @@ int resolve_local(const char *addr) * Strip one trailing dot. */ len = strlen(saved_addr); + if (len == 0) + msg_panic("resolve_local: null domain"); if (saved_addr[len - 1] == '.') saved_addr[--len] = 0; diff --git a/gnu/dist/postfix/src/global/tok822_parse.c b/gnu/dist/postfix/src/global/tok822_parse.c index 7fd66830adc..997a0355425 100644 --- a/gnu/dist/postfix/src/global/tok822_parse.c +++ b/gnu/dist/postfix/src/global/tok822_parse.c @@ -192,12 +192,7 @@ VSTRING *tok822_internalize(VSTRING *vp, TOK822 *tree, int flags) tok822_internalize(vp, tp->head, TOK822_STR_NONE); break; case TOK822_COMMENT: - VSTRING_ADDCH(vp, '('); - tok822_internalize(vp, tp->head, TOK822_STR_NONE); - VSTRING_ADDCH(vp, ')'); - break; case TOK822_ATOM: - case TOK822_COMMENT_TEXT: case TOK822_QSTRING: vstring_strcat(vp, vstring_str(tp->vstr)); break; @@ -244,15 +239,8 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags) tok822_externalize(vp, tp->head, TOK822_STR_NONE); break; case TOK822_ATOM: - vstring_strcat(vp, vstring_str(tp->vstr)); - break; case TOK822_COMMENT: - VSTRING_ADDCH(vp, '('); - tok822_externalize(vp, tp->head, TOK822_STR_NONE); - VSTRING_ADDCH(vp, ')'); - break; - case TOK822_COMMENT_TEXT: - tok822_copy_quoted(vp, vstring_str(tp->vstr), "()\\"); + vstring_strcat(vp, vstring_str(tp->vstr)); break; case TOK822_QSTRING: VSTRING_ADDCH(vp, '"'); @@ -321,6 +309,13 @@ TOK822 *tok822_scan(const char *str, TOK822 **tailp) TOK822 *tp; int ch; + /* + * XXX 2822 new feature: Section 4.1 allows "." to appear in a phrase (to + * allow for forms such as: Johnny B. Goode <johhny@domain.org>. I cannot + * handle that at the tokenizer level - it is not context sensitive. And + * to fix this at the parser level requires radical changes to preserve + * white space as part of the token stream. Thanks a lot, people. + */ while ((ch = *(unsigned char *) str++) != 0) { if (ISSPACE(ch)) continue; @@ -466,36 +461,33 @@ static void tok822_quote_atom(TOK822 *tp) static const char *tok822_comment(TOK822 *tp, const char *str) { - TOK822 *tc = 0; + int level = 1; int ch; -#define COMMENT_TEXT_TOKEN(t) ((t) && (t)->type == TOK822_COMMENT_TEXT) - -#define APPEND_NEW_TOKEN(tp, type, strval) \ - tok822_sub_append(tp, tok822_alloc(type, strval)) + /* + * XXX We cheat by storing comments in their external form. Otherwise it + * would be a royal pain to preserve \ before (. That would require a + * recursive parser; the easy to implement stack-based recursion would be + * too expensive. + */ + VSTRING_ADDCH(tp->vstr, '('); while ((ch = *(unsigned char *) str) != 0) { + VSTRING_ADDCH(tp->vstr, ch); str++; if (ch == '(') { /* comments can nest! */ - if (COMMENT_TEXT_TOKEN(tc)) - VSTRING_TERMINATE(tc->vstr); - tc = APPEND_NEW_TOKEN(tp, TOK822_COMMENT, (char *) 0); - str = tok822_comment(tc, str); + level++; } else if (ch == ')') { - break; - } else { - if (ch == '\\') { - if ((ch = *(unsigned char *) str) == 0) - break; - str++; - } - if (!COMMENT_TEXT_TOKEN(tc)) - tc = APPEND_NEW_TOKEN(tp, TOK822_COMMENT_TEXT, (char *) 0); - VSTRING_ADDCH(tc->vstr, ch); + if (--level == 0) + break; + } else if (ch == '\\') { + if ((ch = *(unsigned char *) str) == 0) + break; + VSTRING_ADDCH(tp->vstr, ch); + str++; } } - if (COMMENT_TEXT_TOKEN(tc)) - VSTRING_TERMINATE(tc->vstr); + VSTRING_TERMINATE(tp->vstr); return (str); } @@ -554,14 +546,11 @@ static void tok822_print(TOK822 *list, int indent) } else if (tp->type == TOK822_ADDR) { vstream_printf("%*s %s\n", indent, "", "address"); tok822_print(tp->head, indent + 2); - } else if (tp->type == TOK822_COMMENT) { - vstream_printf("%*s %s\n", indent, "", "comment"); - tok822_print(tp->head, indent + 2); } else if (tp->type == TOK822_STARTGRP) { vstream_printf("%*s %s\n", indent, "", "group \":\""); } else { vstream_printf("%*s %s \"%s\"\n", indent, "", - tp->type == TOK822_COMMENT_TEXT ? "text" : + tp->type == TOK822_COMMENT ? "comment" : tp->type == TOK822_ATOM ? "atom" : tp->type == TOK822_QSTRING ? "quoted string" : tp->type == TOK822_DOMLIT ? "domain literal" : @@ -577,7 +566,7 @@ int main(int unused_argc, char **unused_argv) TOK822 *list; VSTRING *buf = vstring_alloc(100); - while (readlline(buf, VSTREAM_IN, (int *) 0, READLL_KEEPNL)) { + while (readlline(buf, VSTREAM_IN, (int *) 0)) { while (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\n') { vstring_end(buf)[-1] = 0; vstring_truncate(buf, VSTRING_LEN(buf) - 1); diff --git a/gnu/dist/postfix/src/master/master.h b/gnu/dist/postfix/src/master/master.h index abdfecc720f..d2e4728615e 100644 --- a/gnu/dist/postfix/src/master/master.h +++ b/gnu/dist/postfix/src/master/master.h @@ -162,6 +162,12 @@ extern void master_spawn(MASTER_SERV *); extern void master_reap_child(void); extern void master_delete_children(MASTER_SERV *); + /* + * master_flow.c + */ +void master_flow_init(void); +int master_flow_pipe[2]; + /* DIAGNOSTICS /* BUGS /* SEE ALSO diff --git a/gnu/dist/postfix/src/master/master_ent.c b/gnu/dist/postfix/src/master/master_ent.c index 3eb824c9751..89aac56abfa 100644 --- a/gnu/dist/postfix/src/master/master_ent.c +++ b/gnu/dist/postfix/src/master/master_ent.c @@ -242,13 +242,13 @@ MASTER_SERV *get_master_ent() * Skip blank lines and comment lines. */ do { - if (readlline(buf, master_fp, &master_line, READLL_STRIPNL) == 0) { + if (readlline(buf, master_fp, &master_line) == 0) { vstring_free(buf); vstring_free(junk); return (0); } bufp = vstring_str(buf); - } while ((cp = mystrtok(&bufp, master_blanks)) == 0 || *cp == '#'); + } while ((cp = mystrtok(&bufp, master_blanks)) == 0); /* * Parse one logical line from the configuration file. Initialize service diff --git a/gnu/dist/postfix/src/master/master_listen.c b/gnu/dist/postfix/src/master/master_listen.c index c126e357fd6..9ff3056d1eb 100644 --- a/gnu/dist/postfix/src/master/master_listen.c +++ b/gnu/dist/postfix/src/master/master_listen.c @@ -53,6 +53,7 @@ #include <stringops.h> #include <inet_addr_list.h> #include <set_eugid.h> +#include <set_ugid.h> #include <iostuff.h> /* Global library. */ @@ -88,7 +89,7 @@ void master_listen_init(MASTER_SERV *serv) LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ? serv->max_proc : var_proc_limit, NON_BLOCKING); close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC); - set_eugid(getuid(), getgid()); + set_ugid(getuid(), getgid()); break; /* @@ -98,7 +99,7 @@ void master_listen_init(MASTER_SERV *serv) set_eugid(var_owner_uid, var_owner_gid); serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING); close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC); - set_eugid(getuid(), getgid()); + set_ugid(getuid(), getgid()); break; /* diff --git a/gnu/dist/postfix/src/qmgr/qmgr_message.c b/gnu/dist/postfix/src/qmgr/qmgr_message.c index e696fb4a768..561a73cec45 100644 --- a/gnu/dist/postfix/src/qmgr/qmgr_message.c +++ b/gnu/dist/postfix/src/qmgr/qmgr_message.c @@ -112,6 +112,7 @@ #include <mail_addr_find.h> #include <opened.h> #include <resolve_local.h> +#include <verp_sender.h> /* Client stubs. */ @@ -151,6 +152,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name, message->warn_offset = 0; message->warn_time = 0; message->rcpt_offset = 0; + message->verp_delims = 0; qmgr_rcpt_list_init(&message->rcpt_list); return (message); } @@ -303,6 +305,16 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->warn_offset = curr_offset; message->warn_time = atol(start); } + } else if (rec_type == REC_TYPE_VERP) { + if (message->verp_delims == 0) { + if (verp_delims_verify(start) != 0) { + msg_warn("%s: bad VERP record content: \"%s\"", + message->queue_id, start); + } else { + message->single_rcpt = 1; + message->verp_delims = mystrdup(start); + } + } } } while (rec_type > 0 && rec_type != REC_TYPE_END); @@ -737,6 +749,8 @@ void qmgr_message_free(QMGR_MESSAGE *message) myfree(message->queue_name); if (message->sender) myfree(message->sender); + if (message->verp_delims) + myfree(message->verp_delims); if (message->errors_to) myfree(message->errors_to); if (message->return_receipt) diff --git a/gnu/dist/postfix/src/smtp/smtp_addr.c b/gnu/dist/postfix/src/smtp/smtp_addr.c index 2a6a9d12ab2..9be6cd8b9d2 100644 --- a/gnu/dist/postfix/src/smtp/smtp_addr.c +++ b/gnu/dist/postfix/src/smtp/smtp_addr.c @@ -79,11 +79,33 @@ #include <ctype.h> #include <string.h> #include <unistd.h> +#include <errno.h> #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif + /* + * Older systems don't have h_errno. Even modern systems don't have + * hstrerror(). + */ +#ifdef NO_HERRNO + +static int h_errno = TRY_AGAIN; + +#define HSTRERROR(err) "Host not found" + +#else + +#define HSTRERROR(err) (\ + err == TRY_AGAIN ? "Host not found, try again" : \ + err == HOST_NOT_FOUND ? "Host not found" : \ + err == NO_DATA ? "Host name has no address" : \ + err == NO_RECOVERY ? "Name server failure" : \ + strerror(errno) \ + ) +#endif + /* Utility library. */ #include <msg.h> @@ -91,6 +113,7 @@ #include <mymalloc.h> #include <inet_addr_list.h> #include <stringops.h> +#include <myrand.h> /* Global library. */ @@ -157,8 +180,8 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI if (var_disable_dns) { memset((char *) &fixed, 0, sizeof(fixed)); if ((hp = gethostbyname(host)) == 0) { - vstring_sprintf(why, "%s: host not found", host); - smtp_errno = SMTP_FAIL; + vstring_sprintf(why, "%s: %s", host, HSTRERROR(h_errno)); + smtp_errno = (h_errno == TRY_AGAIN ? SMTP_RETRY : SMTP_FAIL); } else if (hp->h_addrtype != AF_INET) { vstring_sprintf(why, "%s: host not found", host); msg_warn("%s: unknown address family %d for %s", @@ -206,6 +229,11 @@ static DNS_RR *smtp_addr_list(DNS_RR *mx_names, VSTRING *why) /* * As long as we are able to look up any host address, we ignore problems * with DNS lookups. + * + * XXX 2821: update smtp_errno (0->FAIL upon unrecoverable lookup error, + * any->RETRY upon temporary lookup error) so that we can correctly + * handle the case of no resolvable MX host. Currently this is always + * treated as a soft error. RFC 2821 wants a more precise response. */ for (rr = mx_names; rr; rr = rr->next) { if (rr->type != T_MX) @@ -271,9 +299,9 @@ static DNS_RR *smtp_truncate_self(DNS_RR *addr_list, unsigned pref) return (addr_list); } -/* smtp_compare_mx - compare resource records by preference */ +/* smtp_compare_pref - compare resource records by preference */ -static int smtp_compare_mx(DNS_RR *a, DNS_RR *b) +static int smtp_compare_pref(DNS_RR *a, DNS_RR *b) { return (a->pref - b->pref); } @@ -319,6 +347,19 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself) * as we're looking up all the hosts, it would be better to look up the * least preferred host first, so that DNS lookup error messages make * more sense. + * + * XXX 2821: RFC 2821 says that the sender must shuffle equal-preference MX + * hosts, whereas multiple A records per hostname must be used in the + * order as received. They make the bogus assumption that a hostname with + * multiple A records corresponds to one machine with multiple network + * interfaces. + * + * XXX 2821: Postfix recognizes the local machine by looking for its own IP + * address in the list of mail exchangers. RFC 2821 says one has to look + * at the mail exchanger hostname as well, making the bogus assumption + * that an IP address is listed only under one hostname. However, looking + * at hostnames provides a partial solution for MX hosts behind a NAT + * gateway. */ switch (dns_lookup(name, T_MX, 0, &mx_names, (VSTRING *) 0, why)) { default: @@ -332,7 +373,7 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself) addr_list = smtp_host_addr(name, why); break; case DNS_OK: - mx_names = dns_rr_sort(mx_names, smtp_compare_mx); + mx_names = dns_rr_sort(mx_names, smtp_compare_pref); best_pref = (mx_names ? mx_names->pref : IMPOSSIBLE_PREFERENCE); addr_list = smtp_addr_list(mx_names, why); dns_rr_free(mx_names); @@ -362,6 +403,10 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why, int *found_myself) } } } + if (addr_list && addr_list->next && var_smtp_rand_addr) { + addr_list = dns_rr_shuffle(addr_list); + addr_list = dns_rr_sort(addr_list, smtp_compare_pref); + } break; case DNS_NOTFOUND: addr_list = smtp_host_addr(name, why); @@ -387,6 +432,8 @@ DNS_RR *smtp_host_addr(char *host, VSTRING *why) */ #define PREF0 0 addr_list = smtp_addr_one((DNS_RR *) 0, host, PREF0, why); + if (addr_list && addr_list->next && var_smtp_rand_addr) + addr_list = dns_rr_shuffle(addr_list); if (msg_verbose) smtp_print_addr(host, addr_list); return (addr_list); diff --git a/gnu/dist/postfix/src/smtpd/smtpd.c b/gnu/dist/postfix/src/smtpd/smtpd.c index 3389835858b..9e4f4fc2b25 100644 --- a/gnu/dist/postfix/src/smtpd/smtpd.c +++ b/gnu/dist/postfix/src/smtpd/smtpd.c @@ -32,12 +32,13 @@ /* STANDARDS /* RFC 821 (SMTP protocol) /* RFC 1123 (Host requirements) -/* RFC 1651 (SMTP service extensions) /* RFC 1652 (8bit-MIME transport) +/* RFC 1869 (SMTP service extensions) /* RFC 1854 (SMTP Pipelining) /* RFC 1870 (Message Size Declaration) /* RFC 1985 (ETRN command) /* RFC 2554 (AUTH command) +/* RFC 2821 (SMTP protocol) /* DIAGNOSTICS /* Problems and transactions are logged to \fBsyslogd\fR(8). /* @@ -55,12 +56,16 @@ /* .ad /* .fi /* .IP \fBstrict_rfc821_envelopes\fR -/* Disallow non-RFC 821 style addresses in envelopes. For example, -/* allow RFC822-style address forms with comments, like Sendmail does. +/* Disallow non-RFC 821 style addresses in SMTP commands. For example, +/* the RFC822-style address forms with comments that Sendmail allows. /* .IP \fBbroken_sasl_auth_clients\fR /* Support older Microsoft clients that mis-implement the AUTH /* protocol, and that expect an EHLO response of "250 AUTH=list" /* instead of "250 AUTH list". +/* .IP \fBsmtpd_noop_commands\fR +/* List of commands that are treated as NOOP (no operation) commands, +/* without any parameter syntax checking and without any state change. +/* This list overrides built-in command definitions. /* .SH "Content inspection controls" /* .IP \fBcontent_filter\fR /* The name of a mail delivery transport that filters mail and that @@ -88,6 +93,10 @@ /* .IP \fBnoanonymous\fR /* Disallow anonymous logins. /* .RE +/* .IP \fBsmtpd_sender_login_maps\fR +/* Maps that specify the SASL login name that owns a MAIL FROM sender +/* address. Used by the \fBreject_sender_login_mismatch\fR sender +/* anti-spoofing restriction. /* .SH Miscellaneous /* .ad /* .fi @@ -103,6 +112,9 @@ /* List of domain or network patterns. When a remote host matches /* a pattern, increase the verbose logging level by the amount /* specified in the \fBdebug_peer_level\fR parameter. +/* .IP \fBdefault_verp_delimiters\fR +/* The default VERP delimiter characters that are used when the +/* XVERP command is specified without explicit delimiters. /* .IP \fBerror_notice_recipient\fR /* Recipient of protocol/policy/resource/software error notices. /* .IP \fBhopcount_limit\fR @@ -133,6 +145,8 @@ /* .IP \fBsoft_bounce\fR /* Change hard (5xx) reject responses into soft (4xx) reject responses. /* This can be useful for testing purposes. +/* .IP \fBverp_delimiter_filter\fR +/* The characters that Postfix accepts as VERP delimiter characters. /* .SH "Resource controls" /* .ad /* .fi @@ -145,6 +159,9 @@ /* .IP \fBqueue_minfree\fR /* Minimal amount of free space in bytes in the queue file system /* for the SMTP server to accept any mail at all. +/* .IP \fBsmtpd_history_flush_threshold\fR +/* Flush the command history to postmaster after receipt of RSET etc. +/* only if the number of history lines exceeds the given threshold. /* .SH Tarpitting /* .ad /* .fi @@ -163,6 +180,10 @@ /* .SH "UCE control restrictions" /* .ad /* .fi +/* .IP \fBparent_domain_matches_subdomains\fR +/* List of Postfix features that use \fIdomain.name\fR patterns +/* to match \fIsub.domain.name\fR (as opposed to +/* requiring \fI.domain.name\fR patterns). /* .IP \fBsmtpd_client_restrictions\fR /* Restrict what clients may connect to this mail system. /* .IP \fBsmtpd_helo_required\fR @@ -186,9 +207,15 @@ /* Declares the name of zero or more parameters that contain a /* list of UCE restrictions. The names of these parameters can /* then be used instead of the restriction lists that they represent. +/* .IP \fBsmtpd_null_access_lookup_key\fR +/* The lookup key to be used in SMTPD access tables instead of the +/* null sender address. A null sender address cannot be looked up. /* .IP \fBmaps_rbl_domains\fR /* List of DNS domains that publish the addresses of blacklisted /* hosts. +/* .IP \fBpermit_mx_backup_networks\fR +/* Only domains whose primary MX hosts match the listed networks +/* are eligible for the \fBpermit_mx_backup\fR feature. /* .IP \fBrelay_domains\fR /* Restrict what domains or networks this mail system will relay /* mail from or to. @@ -283,6 +310,8 @@ #include <mail_stream.h> #include <mail_queue.h> #include <tok822.h> +#include <verp_sender.h> +#include <string_list.h> /* Single-threaded server skeleton. */ @@ -311,8 +340,6 @@ int var_smtpd_soft_erlim; int var_smtpd_hard_erlim; int var_queue_minfree; /* XXX use off_t */ char *var_smtpd_banner; -char *var_debug_peer_list; -int var_debug_peer_level; char *var_notify_classes; char *var_client_checks; char *var_helo_checks; @@ -340,6 +367,7 @@ bool var_disable_vrfy_cmd; char *var_canonical_maps; char *var_rcpt_canon_maps; char *var_virtual_maps; +char *var_virt_mailbox_maps; char *var_relocated_maps; char *var_alias_maps; char *var_local_rcpt_maps; @@ -350,12 +378,11 @@ char *var_smtpd_sasl_opts; char *var_smtpd_sasl_realm; char *var_filter_xport; bool var_broken_auth_clients; - - /* - * Global state, for stand-alone mode queue file cleanup. When this is - * non-null at cleanup time, the named file is removed. - */ -char *smtpd_path; +char *var_perm_mx_networks; +char *var_smtpd_snd_auth_maps; +char *var_smtpd_noop_cmds; +char *var_smtpd_null_key; +int var_smtpd_hist_thrsh; /* * Silly little macros. @@ -364,11 +391,18 @@ char *smtpd_path; #define LEN(x) VSTRING_LEN(x) /* + * VERP command name. + */ +#define VERP_CMD "XVERP" +#define VERP_CMD_LEN 5 + + /* * Forward declarations. */ static void helo_reset(SMTPD_STATE *); static void mail_reset(SMTPD_STATE *); static void rcpt_reset(SMTPD_STATE *); +static void chat_reset(SMTPD_STATE *, int); /* collapse_args - put arguments together again */ @@ -416,6 +450,11 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) { char *err; + /* + * XXX 2821 new feature: Section 4.1.4 specifies that a server must clear + * all buffers and reset the state exactly as if a RSET command had been + * issued. + */ if (argc < 2) { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "501 Syntax: EHLO hostname"); @@ -423,7 +462,8 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) } if (state->helo_name != 0) helo_reset(state); -#if 0 +#ifndef RFC821_SYNTAX + chat_reset(state, var_smtpd_hist_thrsh); mail_reset(state); rcpt_reset(state); #endif @@ -444,6 +484,8 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) (unsigned long) var_message_limit); /* XXX */ else smtpd_chat_reply(state, "250-SIZE"); + if (var_disable_vrfy_cmd == 0) + smtpd_chat_reply(state, "250-VRFY"); smtpd_chat_reply(state, "250-ETRN"); #ifdef USE_SASL_AUTH if (var_smtpd_sasl_enable) { @@ -452,6 +494,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "250-AUTH=%s", state->sasl_mechanism_list); } #endif + smtpd_chat_reply(state, "250-%s", VERP_CMD); smtpd_chat_reply(state, "250 8BITMIME"); return (0); } @@ -472,27 +515,30 @@ static void mail_open_stream(SMTPD_STATE *state) char *postdrop_command; /* + * XXX 2821: An SMTP server is not allowed to "clean up" mail except in + * the case of original submissions. Presently, Postfix always runs all + * mail through the cleanup server. + * + * We could approximate the RFC as follows: Postfix rewrites mail if it + * comes from a source that we are willing to relay for. This way, we + * avoid rewriting most mail that comes from elsewhere. However, that + * requires moving functionality away from the cleanup daemon elsewhere, + * such as virtual address expansion, and header/body pattern matching. + */ + + /* * If running from the master or from inetd, connect to the cleanup * service. */ if (SMTPD_STAND_ALONE(state) == 0) { - state->dest = mail_stream_service(MAIL_CLASS_PRIVATE, + state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, MAIL_SERVICE_CLEANUP); if (state->dest == 0 - || mail_print(state->dest->stream, "%d", CLEANUP_FLAG_FILTER) != 0) + || attr_print(state->dest->stream, ATTR_FLAG_NONE, + ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_FILTER, + ATTR_TYPE_END) != 0) msg_fatal("unable to connect to the %s %s service", - MAIL_CLASS_PRIVATE, MAIL_SERVICE_CLEANUP); - } - - /* - * Otherwise, if the maildrop is writable, create a maildrop file. - * Arrange for pickup service notification. Make a copy of the pathname - * so that the file can be deleted in case of a fatal run-time error. - */ - else if (access(MAIL_QUEUE_MAILDROP, W_OK) == 0) { - state->dest = mail_stream_file(MAIL_QUEUE_MAILDROP, - MAIL_CLASS_PUBLIC, MAIL_SERVICE_PICKUP); - smtpd_path = mystrdup(VSTREAM_PATH(state->dest->stream)); + MAIL_CLASS_PUBLIC, MAIL_SERVICE_CLEANUP); } /* @@ -607,12 +653,18 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) char *err; int narg; char *arg; + char *verp_delims = 0; state->msg_size = 0; /* - * Sanity checks. XXX Ignore bad SIZE= values until we can reliably and - * portably detect overflows while converting from string to off_t. + * Sanity checks. + * + * XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a + * command in which invalid character codes have been employed, and for + * which there are no other reasons for rejection, MUST reject that + * command with a 501 response. So much for the principle of "be liberal + * in what you accept, be strict in what you send". */ if (var_helo_required && state->helo_name == 0) { state->error_mask |= MAIL_ERROR_POLICY; @@ -646,8 +698,18 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) || strcasecmp(arg, "BODY=7BIT") == 0) { /* void */ ; } else if (strncasecmp(arg, "SIZE=", 5) == 0) { - if ((state->msg_size = off_cvt_string(arg + 5)) < 0) - state->msg_size = 0; + /* Reject non-numeric size. */ + if (!alldig(arg + 5)) { + state->error_mask |= MAIL_ERROR_PROTOCOL; + smtpd_chat_reply(state, "501 Bad message size syntax"); + return (-1); + } + /* Reject size overflow. */ + if ((state->msg_size = off_cvt_string(arg + 5)) < 0) { + smtpd_chat_reply(state, "552 Message size exceeds file system imposed limit"); + state->error_mask |= MAIL_ERROR_POLICY; + return (-1); + } #ifdef USE_SASL_AUTH } else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) { if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) { @@ -655,12 +717,27 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) return (-1); } #endif + } else if (strcasecmp(arg, VERP_CMD) == 0) { + verp_delims = var_verp_delims; + } else if (strncasecmp(arg, VERP_CMD, VERP_CMD_LEN) == 0 + && arg[VERP_CMD_LEN] == '=') { + verp_delims = arg + VERP_CMD_LEN + 1; + if (verp_delims_verify(verp_delims) != 0) { + state->error_mask |= MAIL_ERROR_PROTOCOL; + smtpd_chat_reply(state, "501 %s needs two characters from %s", + VERP_CMD, var_verp_filter); + return (-1); + } } else { state->error_mask |= MAIL_ERROR_PROTOCOL; smtpd_chat_reply(state, "555 Unsupported option: %s", arg); return (-1); } } + if (verp_delims && argv[2].strval[0] == 0) { + smtpd_chat_reply(state, "503 Error: XVERP requires non-null sender"); + return (-1); + } state->time = time((time_t *) 0); if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_delay_reject == 0 @@ -693,6 +770,8 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) if (*var_filter_xport) rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport); rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval); + if (verp_delims) + rec_fputs(state->cleanup, REC_TYPE_VERP, verp_delims); state->sender = mystrdup(argv[2].strval); smtpd_chat_reply(state, "250 Ok"); return (0); @@ -718,14 +797,6 @@ static void mail_reset(SMTPD_STATE *state) myfree(state->queue_id); state->queue_id = 0; } - if (smtpd_path) { - if (remove(smtpd_path)) - msg_warn("remove %s: %m", smtpd_path); - else if (msg_verbose) - msg_info("remove %s", smtpd_path); - myfree(smtpd_path); - smtpd_path = 0; - } if (state->sender) { myfree(state->sender); state->sender = 0; @@ -746,6 +817,12 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) /* * Sanity checks. + * + * XXX 2821 pedantism: Section 4.1.2 says that SMTP servers that receive a + * command in which invalid character codes have been employed, and for + * which there are no other reasons for rejection, MUST reject that + * command with a 501 response. So much for the principle of "be liberal + * in what you accept, be strict in what you send". */ if (state->cleanup == 0) { state->error_mask |= MAIL_ERROR_PROTOCOL; @@ -823,6 +900,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) int curr_rec_type; int prev_rec_type; int first = 1; + VSTRING *why = 0; /* * Sanity checks. With ESMTP command pipelining the client can send DATA @@ -861,6 +939,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) "\tby %s (%s) with %s id %s", var_myhostname, var_mail_name, state->protocol, state->queue_id); + /* XXX Should RFC 822 externalize recipient address */ rec_fprintf(state->cleanup, REC_TYPE_NORM, "\tfor <%s>; %s", state->recipient, mail_date(state->time)); } else { @@ -871,6 +950,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) "\tid %s; %s", state->queue_id, mail_date(state->time)); } #ifdef RECEIVED_ENVELOPE_FROM + /* XXX Should RFC 822 externalize sender address */ rec_fprintf(state->cleanup, REC_TYPE_NORM, "\t(envelope-from %s)", state->sender); #endif @@ -929,30 +1009,18 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) * Finish the queue file or finish the cleanup conversation. */ if (state->err == 0) - state->err |= mail_stream_finish(state->dest); + state->err = mail_stream_finish(state->dest, why = vstring_alloc(10)); else mail_stream_cleanup(state->dest); state->dest = 0; state->cleanup = 0; /* - * Delete the queue file or disable delete on fatal error or interrupt. - */ - if (smtpd_path) { - if (state->err != 0) { - if (remove(smtpd_path)) - msg_warn("remove %s: %m", smtpd_path); - else if (msg_verbose) - msg_info("remove %s", smtpd_path); - } - myfree(smtpd_path); - smtpd_path = 0; - } - - /* * Handle any errors. One message may suffer from multiple errors, so * complain only about the most severe error. Forgive any previous client * errors when a message was received successfully. + * + * See also: qmqpd.c */ if (state->err == CLEANUP_STAT_OK) { state->error_count = 0; @@ -970,15 +1038,14 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) smtpd_chat_reply(state, "554 Error: too many hops"); } else if ((state->err & CLEANUP_STAT_CONT) != 0) { state->error_mask |= MAIL_ERROR_POLICY; - smtpd_chat_reply(state, "552 Error: content rejected"); + smtpd_chat_reply(state, "552 Error: %s", LEN(why) ? + STR(why) : "content rejected"); } else if ((state->err & CLEANUP_STAT_WRITE) != 0) { state->error_mask |= MAIL_ERROR_RESOURCE; smtpd_chat_reply(state, "451 Error: queue file write error"); - } else if ((state->err & CLEANUP_STAT_RCPT) != 0) { + } else { state->error_mask |= MAIL_ERROR_SOFTWARE; smtpd_chat_reply(state, "451 Error: internal error %d", state->err); - } else { - msg_panic("data_cmd: unknown status %d", state->err); } /* @@ -988,23 +1055,13 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) state->where = SMTPD_AFTER_DOT; /* - * Notify the postmaster if there were errors. This usually indicates a - * client configuration problem, or that someone is trying nasty things. - * Either is significant enough to bother the postmaster. XXX Can't - * report problems when running in stand-alone mode: postmaster notices - * require availability of the cleanup service. - */ - if (state->history != 0 && state->client != VSTREAM_IN - && (state->error_mask & state->notify_mask)) - smtpd_chat_notify(state); - state->error_mask = 0; - smtpd_chat_reset(state); - - /* * Cleanup. The client may send another MAIL command. */ + chat_reset(state, var_smtpd_hist_thrsh); mail_reset(state); rcpt_reset(state); + if (why) + vstring_free(why); return (state->err); } @@ -1023,21 +1080,9 @@ static int rset_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) } /* - * Notify the postmaster if there were errors. This usually indicates a - * client configuration problem, or that someone is trying nasty things. - * Either is significant enough to bother the postmaster. XXX Can't - * report problems when running in stand-alone mode: postmaster notices - * require availability of the cleanup service. - */ - if (state->history != 0 && state->client != VSTREAM_IN - && (state->error_mask & state->notify_mask)) - smtpd_chat_notify(state); - state->error_mask = 0; - smtpd_chat_reset(state); - - /* * Restore state to right after HELO/EHLO command. */ + chat_reset(state, var_smtpd_hist_thrsh); mail_reset(state); rcpt_reset(state); smtpd_chat_reply(state, "250 Ok"); @@ -1050,6 +1095,15 @@ static int noop_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) { /* + * XXX 2821 incompatibility: Section 4.1.1.9 says that NOOP can have a + * parameter string which is to be ignored. NOOP instructions with + * parameters? Go figure. + * + * RFC 2821 violates RFC 821, which says that NOOP takes no parameters. + */ +#ifdef RFC821_SYNTAX + + /* * Sanity checks. */ if (argc != 1) { @@ -1057,6 +1111,7 @@ static int noop_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv) smtpd_chat_reply(state, "501 Syntax: NOOP"); return (-1); } +#endif smtpd_chat_reply(state, "250 Ok"); return (0); } @@ -1077,6 +1132,17 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) * address forms. Therefore we must parse out the address, or we must * stop doing recipient restriction checks and lose the opportunity to * say "user unknown" at the SMTP port. + * + * XXX 2821 incompatibility and brain damage: Section 4.5.1 requires that + * VRFY is implemented. RFC 821 specifies that VRFY is optional. It gets + * even worse: section 3.5.3 says that a 502 (command recognized but not + * implemented) reply is not fully compliant. + * + * Thus, an RFC 2821 compliant implementation cannot refuse to supply + * information in reply to VRFY queries. That is simply bogus. The only + * reply we could supply is a generic 252 reply. This causes spammers to + * add tons of bogus addresses to their mailing lists (spam harvesting by + * trying out large lists of potential recipient names with VRFY). */ #define SLOPPY 0 @@ -1102,7 +1168,17 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) smtpd_chat_reply(state, "%s", err); return (-1); } - smtpd_chat_reply(state, "252 <%s>", argv[1].strval); + + /* + * XXX 2821 new feature: Section 3.5.1 requires that the VRFY response is + * either "full name <user@domain>" or "user@domain". Postfix replies + * with the address that was provided by the client, whether or not it is + * in fully qualified domain form or not. + * + * Reply code 250 is reserved for the case where the address is verified; + * reply code 252 should be used when no definitive certainty exists. + */ + smtpd_chat_reply(state, "252 %s", argv[1].strval); return (0); } @@ -1157,6 +1233,12 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) case FLUSH_STAT_OK: smtpd_chat_reply(state, "250 Queuing started"); return (0); + case FLUSH_STAT_DENY: + msg_warn("reject: ETRN %.100s... from %s", + argv[1].strval, state->namaddr); + smtpd_chat_reply(state, "459 <%s>: service unavailable", + argv[1].strval); + return (-1); case FLUSH_STAT_BAD: msg_warn("bad ETRN %.100s... from %s", argv[1].strval, state->namaddr); smtpd_chat_reply(state, "458 Unable to queue messages"); @@ -1180,6 +1262,27 @@ static int quit_cmd(SMTPD_STATE *state, int unused_argc, SMTPD_TOKEN *unused_arg return (0); } +/* chat_reset - notify postmaster and reset conversation log */ + +static void chat_reset(SMTPD_STATE *state, int threshold) +{ + + /* + * Notify the postmaster if there were errors. This usually indicates a + * client configuration problem, or that someone is trying nasty things. + * Either is significant enough to bother the postmaster. XXX Can't + * report problems when running in stand-alone mode: postmaster notices + * require availability of the cleanup service. + */ + if (state->history != 0 && state->history->argc > threshold) { + if (SMTPD_STAND_ALONE(state) == 0 + && (state->error_mask & state->notify_mask)) + smtpd_chat_notify(state); + state->error_mask = 0; + smtpd_chat_reset(state); + } +} + /* * The table of all SMTP commands that we know. Set the junk limit flag on * any command that can be repeated an arbitrary number of times without @@ -1212,6 +1315,8 @@ static SMTPD_CMD smtpd_cmd_table[] = { 0, }; +static STRING_LIST *smtpd_noop_cmds; + /* smtpd_proto - talk the SMTP protocol */ static void smtpd_proto(SMTPD_STATE *state) @@ -1272,6 +1377,13 @@ static void smtpd_proto(SMTPD_STATE *state) state->error_count++; continue; } + if (*var_smtpd_noop_cmds + && string_list_match(smtpd_noop_cmds, argv[0].strval)) { + smtpd_chat_reply(state, "250 Ok"); + if (state->junk_cmds++ > var_smtpd_junk_cmd_limit) + state->error_count++; + continue; + } for (cmdp = smtpd_cmd_table; cmdp->name != 0; cmdp++) if (strcasecmp(argv[0].strval, cmdp->name) == 0) break; @@ -1282,7 +1394,8 @@ static void smtpd_proto(SMTPD_STATE *state) continue; } if (state->access_denied && cmdp->action != quit_cmd) { - smtpd_chat_reply(state, "%s", state->access_denied); + smtpd_chat_reply(state, "503 Error: access denied for %s", + state->namaddr); /* RFC 2821 Sec 3.1 */ state->error_count++; continue; } @@ -1310,18 +1423,6 @@ static void smtpd_proto(SMTPD_STATE *state) state->reason, state->where, state->name, state->addr); /* - * Notify the postmaster if there were errors but no message was - * collected. This usually indicates a client configuration problem, or - * that someone is trying nasty things. Either is significant enough to - * bother the postmaster. XXX Can't report problems when running in - * stand-alone mode: postmaster notices require availability of the - * cleanup service. - */ - if (state->history != 0 && state->client != VSTREAM_IN - && (state->error_mask & state->notify_mask)) - smtpd_chat_notify(state); - - /* * Cleanup whatever information the client gave us during the SMTP * dialog. */ @@ -1330,9 +1431,9 @@ static void smtpd_proto(SMTPD_STATE *state) if (var_smtpd_sasl_enable) smtpd_sasl_auth_reset(state); #endif + chat_reset(state, 0); mail_reset(state); rcpt_reset(state); - smtpd_chat_reset(state); } /* smtpd_service - service one client */ @@ -1389,33 +1490,6 @@ static void smtpd_service(VSTREAM *stream, char *unused_service, char **argv) debug_peer_restore(); } -/* smtpd_cleanup - stand-alone mode queue file cleanup */ - -static void smtpd_cleanup(void) -{ - char *myname = "smtpd_cleanup"; - - /* - * This routine is called by the run-time error handler, right before - * program exit. - */ - if (smtpd_path) { - if (remove(smtpd_path)) - msg_warn("%s: remove %s: %m", myname, smtpd_path); - else if (msg_verbose) - msg_info("%s: remove %s", myname, smtpd_path); - smtpd_path = 0; - } -} - -/* smtpd_sig - signal handler */ - -static void smtpd_sig(int sig) -{ - smtpd_cleanup(); - exit(sig); -} - /* pre_accept - see if tables have changed */ static void pre_accept(char *unused_name, char **unused_argv) @@ -1426,20 +1500,6 @@ static void pre_accept(char *unused_name, char **unused_argv) } } -/* post_jail_init - post-jail initialization */ - -static void post_jail_init(char *unused_name, char **unused_argv) -{ - - /* - * Set up signal handlers so that we clean up in stand-alone mode. - */ - signal(SIGHUP, smtpd_sig); - signal(SIGINT, smtpd_sig); - signal(SIGQUIT, smtpd_sig); - signal(SIGTERM, smtpd_sig); -} - /* pre_jail_init - pre-jail initialization */ static void pre_jail_init(char *unused_name, char **unused_argv) @@ -1449,9 +1509,9 @@ static void pre_jail_init(char *unused_name, char **unused_argv) * Initialize blacklist/etc. patterns before entering the chroot jail, in * case they specify a filename pattern. */ + smtpd_noop_cmds = string_list_init(MATCH_FLAG_NONE, var_smtpd_noop_cmds); smtpd_check_init(); debug_peer_init(); - msg_cleanup(smtpd_cleanup); if (var_smtpd_sasl_enable) #ifdef USE_SASL_AUTH @@ -1471,7 +1531,6 @@ int main(int argc, char **argv) VAR_SMTPD_SOFT_ERLIM, DEF_SMTPD_SOFT_ERLIM, &var_smtpd_soft_erlim, 1, 0, VAR_SMTPD_HARD_ERLIM, DEF_SMTPD_HARD_ERLIM, &var_smtpd_hard_erlim, 1, 0, VAR_QUEUE_MINFREE, DEF_QUEUE_MINFREE, &var_queue_minfree, 0, 0, - VAR_DEBUG_PEER_LEVEL, DEF_DEBUG_PEER_LEVEL, &var_debug_peer_level, 1, 0, VAR_UNK_CLIENT_CODE, DEF_UNK_CLIENT_CODE, &var_unk_client_code, 0, 0, VAR_BAD_NAME_CODE, DEF_BAD_NAME_CODE, &var_bad_name_code, 0, 0, VAR_UNK_NAME_CODE, DEF_UNK_NAME_CODE, &var_unk_name_code, 0, 0, @@ -1482,6 +1541,7 @@ int main(int argc, char **argv) VAR_REJECT_CODE, DEF_REJECT_CODE, &var_reject_code, 0, 0, VAR_NON_FQDN_CODE, DEF_NON_FQDN_CODE, &var_non_fqdn_code, 0, 0, VAR_SMTPD_JUNK_CMD, DEF_SMTPD_JUNK_CMD, &var_smtpd_junk_cmd_limit, 1, 0, + VAR_SMTPD_HIST_THRSH, DEF_SMTPD_HIST_THRSH, &var_smtpd_hist_thrsh, 1, 0, 0, }; static CONFIG_TIME_TABLE time_table[] = { @@ -1501,7 +1561,6 @@ int main(int argc, char **argv) }; static CONFIG_STR_TABLE str_table[] = { VAR_SMTPD_BANNER, DEF_SMTPD_BANNER, &var_smtpd_banner, 1, 0, - VAR_DEBUG_PEER_LIST, DEF_DEBUG_PEER_LIST, &var_debug_peer_list, 0, 0, VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0, VAR_CLIENT_CHECKS, DEF_CLIENT_CHECKS, &var_client_checks, 0, 0, VAR_HELO_CHECKS, DEF_HELO_CHECKS, &var_helo_checks, 0, 0, @@ -1515,12 +1574,17 @@ int main(int argc, char **argv) VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, 0, 0, VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, 0, 0, VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, 0, 0, + VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, 0, 0, VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, 0, 0, VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0, VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0, VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0, VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 1, 0, VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0, + VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0, + VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, 0, 0, + VAR_SMTPD_NOOP_CMDS, DEF_SMTPD_NOOP_CMDS, &var_smtpd_noop_cmds, 0, 0, + VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key, 0, 0, 0, }; @@ -1533,7 +1597,6 @@ int main(int argc, char **argv) MAIL_SERVER_BOOL_TABLE, bool_table, MAIL_SERVER_TIME_TABLE, time_table, MAIL_SERVER_PRE_INIT, pre_jail_init, - MAIL_SERVER_POST_INIT, post_jail_init, MAIL_SERVER_PRE_ACCEPT, pre_accept, 0); } diff --git a/gnu/dist/postfix/src/smtpd/smtpd_check.c b/gnu/dist/postfix/src/smtpd/smtpd_check.c index a8ed776f6ea..3d51395c1ea 100644 --- a/gnu/dist/postfix/src/smtpd/smtpd_check.c +++ b/gnu/dist/postfix/src/smtpd/smtpd_check.c @@ -145,9 +145,10 @@ /* Reject the request when the client has already sent the next request /* without being told that the server implements SMTP command pipelining. /* .IP permit_mx_backup -/* Allow the request when the local mail system is mail exchanger -/* for the recipient domain (this includes the case where the local -/* system is the final destination). +/* Allow the request when all primary MX hosts for the recipient +/* are in the networks specified with the $permit_mx_backup_networks +/* configuration parameter, or when the local system is the final +/* destination. /* .IP restriction_classes /* Defines a list of parameter names, each parameter being a list /* of restrictions that can be used anywhere a restriction is legal. @@ -288,6 +289,8 @@ #include <mail_conf.h> #include <maps.h> #include <mail_addr_find.h> +#include <match_parent_style.h> +#include <split_addr.h> /* Application-specific. */ @@ -308,6 +311,11 @@ static jmp_buf smtpd_check_buf; #define SMTPD_CHECK_REJECT 2 /* explicitly reject */ /* + * XXX For now define SMTPD_CHECK_TRYAGAIN as SMTPD_CHECK_OK. + */ +#define SMTPD_CHECK_TRYAGAIN 1 /* return 4xx try again */ + + /* * Intermediate results. These are static to avoid unnecessary stress on the * memory manager routines. */ @@ -323,13 +331,25 @@ static MAPS *local_rcpt_maps; static MAPS *rcpt_canon_maps; static MAPS *canonical_maps; static MAPS *virtual_maps; +static MAPS *virt_mailbox_maps; static MAPS *relocated_maps; /* + * Pre-opened sender to login name mapping. + */ +static MAPS *smtpd_sender_login_maps; + + /* * Pre-opened access control lists. */ static DOMAIN_LIST *relay_domains; static NAMADR_LIST *mynetworks; +static NAMADR_LIST *perm_mx_networks; + + /* + * How to do parent domain wildcard matching, if any. + */ +static int access_parent_style; /* * Pre-parsed restriction lists. @@ -444,6 +464,10 @@ static int has_required(ARGV *restrictions, char **required) * Recursively check list membership. */ for (rest = restrictions->argv; *rest; rest++) { + if (strcmp(*rest, WARN_IF_REJECT) == 0 && rest[1] != 0) { + rest += 1; + continue; + } for (reqd = required; *reqd; reqd++) if (strcmp(*rest, *reqd) == 0) return (1); @@ -473,8 +497,9 @@ static void fail_required(char *name, char **required) */ example = vstring_alloc(10); for (reqd = required; *reqd; reqd++) - vstring_sprintf_append(example, "%s ", *reqd); - msg_fatal("parameter \"%s\": specify at least one explicit instance of: %s", + vstring_sprintf_append(example, "%s%s", *reqd, + reqd[1] == 0 ? "" : reqd[2] == 0 ? " or " : ", "); + msg_fatal("parameter \"%s\": specify at least one working instance of: %s", name, STR(example)); } @@ -496,8 +521,15 @@ void smtpd_check_init(void) /* * Pre-open access control lists before going to jail. */ - mynetworks = namadr_list_init(var_mynetworks); - relay_domains = domain_list_init(var_relay_domains); + mynetworks = + namadr_list_init(match_parent_style(VAR_MYNETWORKS), + var_mynetworks); + relay_domains = + domain_list_init(match_parent_style(VAR_RELAY_DOMAINS), + var_relay_domains); + perm_mx_networks = + namadr_list_init(match_parent_style(VAR_PERM_MX_NETWORKS), + var_perm_mx_networks); /* * Pre-parse and pre-open the recipient maps. @@ -510,9 +542,20 @@ void smtpd_check_init(void) DICT_FLAG_LOCK); virtual_maps = maps_create(VAR_VIRTUAL_MAPS, var_virtual_maps, DICT_FLAG_LOCK); + virt_mailbox_maps = maps_create(VAR_VIRT_MAILBOX_MAPS, var_virt_mailbox_maps, + DICT_FLAG_LOCK); relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps, DICT_FLAG_LOCK); + access_parent_style = match_parent_style(SMTPD_ACCESS_MAPS); + + /* + * Sender to login name mapping. + */ + smtpd_sender_login_maps = maps_create(VAR_SMTPD_SND_AUTH_MAPS, + var_smtpd_snd_auth_maps, + DICT_FLAG_LOCK); + /* * error_text is used for returning error responses. */ @@ -574,6 +617,20 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, char *format,...) { va_list ap; + int warn_if_reject; + const char *whatsup; + + /* + * Do not reject mail if we were asked to warn only. However, + * configuration errors cannot be converted into warnings. + */ + if (state->warn_if_reject && error_class != MAIL_ERROR_SOFTWARE) { + warn_if_reject = 1; + whatsup = "reject_warning"; + } else { + warn_if_reject = 0; + whatsup = "reject"; + } /* * Update the error class mask, and format the response. XXX What about @@ -611,7 +668,7 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, * * We could eliminate the code duplication and implement the soft_bounce * safety net only in the code below. But then the safety net would cover - * the UCE restrictions only. This would be at odds with the documentation + * the UCE restrictions only. This would be at odds with documentation * which says soft_bounce changes all 5xx replies into 4xx ones. */ if (var_soft_bounce && STR(error_text)[0] == '5') @@ -623,22 +680,22 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, * rejected. Print the request, client name/address, and response. */ if (state->recipient && state->sender) { - msg_info("reject: %s from %s: %s; from=<%s> to=<%s>", - state->where, state->namaddr, STR(error_text), + msg_info("%s: %s from %s: %s; from=<%s> to=<%s>", + whatsup, state->where, state->namaddr, STR(error_text), state->sender, state->recipient); } else if (state->recipient) { - msg_info("reject: %s from %s: %s; to=<%s>", - state->where, state->namaddr, STR(error_text), + msg_info("%s: %s from %s: %s; to=<%s>", + whatsup, state->where, state->namaddr, STR(error_text), state->recipient); } else if (state->sender) { - msg_info("reject: %s from %s: %s; from=<%s>", - state->where, state->namaddr, STR(error_text), + msg_info("%s: %s from %s: %s; from=<%s>", + whatsup, state->where, state->namaddr, STR(error_text), state->sender); } else { - msg_info("reject: %s from %s: %s", - state->where, state->namaddr, STR(error_text)); + msg_info("%s: %s from %s: %s", + whatsup, state->where, state->namaddr, STR(error_text)); } - return (SMTPD_CHECK_REJECT); + return (warn_if_reject ? 0 : SMTPD_CHECK_REJECT); } /* reject_dict_retry - reject with temporary failure if dict lookup fails */ @@ -680,6 +737,29 @@ static const char *check_mail_addr_find(SMTPD_STATE *state, return (result); } +/* resolve_final - do we do final delivery for the domain? */ + +static int resolve_final(SMTPD_STATE *state, const char *reply_name, +const char *domain) +{ + + /* If matches $mydestination or $inet_interfaces. */ + if (resolve_local(domain)) + return (1); + + /* If Postfix-style virtual domain. */ + if (*var_virtual_maps + && check_maps_find(state, reply_name, virtual_maps, domain, 0)) + return (1); + + /* If virtual mailbox domain. */ + if (*var_virt_mailbox_maps + && check_maps_find(state, reply_name, virt_mailbox_maps, domain, 0)) + return (1); + + return (0); +} + /* reject_unknown_client - fail if client hostname is unknown */ static int reject_unknown_client(SMTPD_STATE *state) @@ -941,12 +1021,10 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient) domain += 1; /* - * Permit final delivery: the destination matches mydestination or - * virtual_maps. + * Permit final delivery: the destination matches mydestination, + * virtual_maps, or virtual_mailbox_maps. */ - if (resolve_local(domain) - || (*var_virtual_maps - && check_maps_find(state, recipient, virtual_maps, domain, 0))) + if (resolve_final(state, recipient, domain)) return (SMTPD_CHECK_OK); /* @@ -1009,6 +1087,60 @@ static int reject_unauth_pipelining(SMTPD_STATE *state) return (SMTPD_CHECK_DUNNO); } +/* all_auth_mx_addr - match host addresses against permit_mx_backup_networks */ + +static int all_auth_mx_addr(char *host) +{ + char *myname = "all_auth_mx_addr"; + struct in_addr addr; + DNS_RR *rr; + DNS_RR *addr_list; + int dns_status; + + if (msg_verbose) + msg_info("%s: host %s", myname, host); + + /* + * If we can't lookup the host, try again. + */ +#define NOPE 0 +#define YUP 1 +#define TRYAGAIN 2 + + /* + * Verify that all host addresses are within permit_mx_backup_networks. + */ + dns_status = dns_lookup(host, T_A, 0, &addr_list, (VSTRING *) 0, (VSTRING *) 0); + if (dns_status != DNS_OK) + return (TRYAGAIN); + + for (rr = addr_list; rr != 0; rr = rr->next) { + if (rr->data_len > sizeof(addr)) { + msg_warn("skipping address length %d for host %s", + rr->data_len, host); + continue; + } + memcpy((char *) &addr, rr->data, sizeof(addr)); + if (msg_verbose) + msg_info("%s: checking: %s", myname, inet_ntoa(addr)); + + if (!namadr_list_match(perm_mx_networks, host, inet_ntoa(addr))) { + + /* + * Reject: at least one IP address is not listed in + * permit_mx_backup_networks. + */ + if (msg_verbose) + msg_info("%s: address %s for %s does not match %s", + myname, inet_ntoa(addr), host, VAR_PERM_MX_NETWORKS); + dns_rr_free(addr_list); + return (NOPE); + } + } + dns_rr_free(addr_list); + return (YUP); +} + /* has_my_addr - see if this host name lists one of my network addresses */ static int has_my_addr(const char *host) @@ -1050,6 +1182,78 @@ static int has_my_addr(const char *host) return (NOPE); } +/* i_am_mx - is this machine listed as MX relay */ + +static int i_am_mx(DNS_RR *mx_list) +{ + const char *myname = "permit_mx_backup"; + DNS_RR *mx; + + /* + * Compare hostnames first. Only if no name match is found, go through + * the trouble of host address lookups. + */ + for (mx = mx_list; mx != 0; mx = mx->next) { + if (msg_verbose) + msg_info("%s: resolve hostname: %s", myname, (char *) mx->data); + if (resolve_local((char *) mx->data)) + return (YUP); + } + + /* + * Argh. Do further DNS lookups and match interface addresses. + */ + for (mx = mx_list; mx != 0; mx = mx->next) { + if (msg_verbose) + msg_info("%s: address lookup: %s", myname, (char *) mx->data); + if (has_my_addr((char *) mx->data)) + return (YUP); + } + + /* + * This machine is not listed as MX relay. + */ + if (msg_verbose) + msg_info("%s: I am not listed as MX relay", myname); + return (NOPE); +} + +/* permit_mx_primary - authorize primary MX relays */ + +static int permit_mx_primary(DNS_RR *mx_list) +{ + DNS_RR *mx; + unsigned int best_pref; + int status; + + /* + * Find the preference of the primary MX hosts. + */ + for (best_pref = 0xffff, mx = mx_list; mx != 0; mx = mx->next) + if (mx->pref < best_pref) + best_pref = mx->pref; + + /* + * See if each best MX host has all IP addresses in + * permit_mx_backup_networks. + */ + for (mx = mx_list; mx != 0; mx = mx->next) { + if (mx->pref != best_pref) + continue; + switch (status = all_auth_mx_addr((char *) mx->data)) { + case TRYAGAIN: + case NOPE: + return (status); + } + } + + /* + * All IP addresses of the best MX hosts are within + * permit_mx_backup_networks. + */ + return (YUP); +} + /* permit_mx_backup - permit use of me as MX backup for recipient domain */ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient) @@ -1059,7 +1263,6 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient) const char *domain; DNS_RR *mx_list; - DNS_RR *mx; int dns_status; if (msg_verbose) @@ -1078,9 +1281,7 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient) if ((domain = strrchr(CONST_STR(reply->recipient), '@')) == 0) return (SMTPD_CHECK_OK); domain += 1; - if (resolve_local(domain) - || (*var_virtual_maps - && check_maps_find(state, recipient, virtual_maps, domain, 0))) + if (resolve_final(state, recipient, domain)) return (SMTPD_CHECK_OK); if (msg_verbose) @@ -1110,37 +1311,30 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient) if (dns_status == DNS_NOTFOUND) return (has_my_addr(domain) ? SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO); if (dns_status != DNS_OK) - return (SMTPD_CHECK_OK); + return (SMTPD_CHECK_TRYAGAIN); /* - * First, see if we match any of the MX host names listed. Only if no - * name match is found, go through the trouble of host address lookups. + * First, see if we match any of the MX host names listed. */ - for (mx = mx_list; mx != 0; mx = mx->next) { - if (msg_verbose) - msg_info("%s: resolve hostname: %s", myname, (char *) mx->data); - if (resolve_local((char *) mx->data)) { - dns_rr_free(mx_list); - return (SMTPD_CHECK_OK); - } + if (!i_am_mx(mx_list)) { + dns_rr_free(mx_list); + return (SMTPD_CHECK_DUNNO); } /* - * Argh. Do further DNS lookups and match interface addresses. + * Optionally, see if the primary MX hosts are in a restricted list of + * networks. */ - for (mx = mx_list; mx != 0; mx = mx->next) { - if (msg_verbose) - msg_info("%s: address lookup: %s", myname, (char *) mx->data); - if (has_my_addr((char *) mx->data)) { - dns_rr_free(mx_list); - return (SMTPD_CHECK_OK); - } + if (*var_perm_mx_networks && !permit_mx_primary(mx_list)) { + dns_rr_free(mx_list); + return (SMTPD_CHECK_DUNNO); } - if (msg_verbose) - msg_info("%s: no match", myname); + /* + * The destination passed all requirements. + */ dns_rr_free(mx_list); - return (SMTPD_CHECK_DUNNO); + return (SMTPD_CHECK_OK); } /* reject_non_fqdn_address - fail if address is not in fqdn form */ @@ -1219,9 +1413,7 @@ static int reject_unknown_address(SMTPD_STATE *state, const char *addr, if ((domain = strrchr(CONST_STR(reply->recipient), '@')) == 0) return (SMTPD_CHECK_DUNNO); domain += 1; - if (resolve_local(domain) - || (*var_virtual_maps - && check_maps_find(state, reply_name, virtual_maps, domain, 0))) + if (resolve_final(state, reply_name, domain)) return (SMTPD_CHECK_DUNNO); if (domain[0] == '#') return (SMTPD_CHECK_DUNNO); @@ -1245,6 +1437,7 @@ static int check_table_result(SMTPD_STATE *state, const char *table, char *myname = "check_table_result"; int code; ARGV *restrictions; + jmp_buf savebuf; int status; if (msg_verbose) @@ -1268,7 +1461,7 @@ static int check_table_result(SMTPD_STATE *state, const char *table, * All-numeric result probably means OK - some out-of-band authentication * mechanism uses this as time stamp. */ - if (*value && value[strspn(value, "0123456789")] == 0) + if (alldig(value)) return (SMTPD_CHECK_OK); /* @@ -1303,7 +1496,8 @@ static int check_table_result(SMTPD_STATE *state, const char *table, table, value); msg_warn("do not specify lookup tables inside SMTPD access maps"); msg_warn("define a restriction class and specify its name instead"); - longjmp(smtpd_check_buf, -1); + longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE, + "451 Server configuration error")); } /* @@ -1312,15 +1506,29 @@ static int check_table_result(SMTPD_STATE *state, const char *table, if (state->recursion++ > 100) { msg_warn("SMTPD access map %s entry %s causes unreasonable recursion", table, value); - longjmp(smtpd_check_buf, -1); + longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE, + "451 Server configuration error")); } /* * Recursively evaluate the restrictions given in the right-hand side. In * the dark ages, an empty right-hand side meant OK. Make some * discouraging comments. + * + * XXX Jump some hoops to avoid a minute memory leak in case of a file + * configuration error. */ +#define ADDROF(x) ((char *) &(x)) + restrictions = argv_split(value, " \t\r\n,"); + memcpy(ADDROF(savebuf), ADDROF(smtpd_check_buf), sizeof(savebuf)); + status = setjmp(smtpd_check_buf); + if (status != 0) { + argv_free(restrictions); + memcpy(ADDROF(smtpd_check_buf), ADDROF(savebuf), + sizeof(smtpd_check_buf)); + longjmp(smtpd_check_buf, status); + } if (restrictions->argc == 0) { msg_warn("SMTPD access map %s entry %s has empty value", table, value); @@ -1391,7 +1599,7 @@ static int check_domain_access(SMTPD_STATE *state, const char *table, if ((dict = dict_handle(table)) == 0) msg_panic("%s: dictionary not found: %s", myname, table); - for (name = low_domain; /* void */ ; name = next + 1) { + for (name = low_domain; /* void */ ; name = next) { if (flags == 0 || (flags & dict->flags) != 0) { if ((value = dict_get(dict, name)) != 0) CHK_DOMAIN_RETURN(check_table_result(state, table, value, @@ -1400,8 +1608,10 @@ static int check_domain_access(SMTPD_STATE *state, const char *table, if (dict_errno != 0) msg_fatal("%s: table lookup problem", table); } - if ((next = strchr(name, '.')) == 0) + if ((next = strchr(name + 1, '.')) == 0) break; + if (access_parent_style == MATCH_FLAG_PARENT) + next += 1; flags = PARTIAL; } CHK_DOMAIN_RETURN(SMTPD_CHECK_DUNNO, MISSED); @@ -1495,9 +1705,12 @@ static int check_mail_access(SMTPD_STATE *state, const char *table, { char *myname = "check_mail_access"; const RESOLVE_REPLY *reply; - const char *ratsign; + const char *domain; int status; char *local_at; + char *bare_addr; + char *bare_ext; + char *bare_at; if (msg_verbose) msg_info("%s: %s", myname, addr); @@ -1511,42 +1724,114 @@ static int check_mail_access(SMTPD_STATE *state, const char *table, * Garbage in, garbage out. Every address from canon_addr_internal() and * from resolve_clnt_query() must be fully qualified. */ - if ((ratsign = strrchr(CONST_STR(reply->recipient), '@')) == 0) { - msg_warn("%s: no @domain in address: %s", myname, CONST_STR(reply->recipient)); + if ((domain = strrchr(CONST_STR(reply->recipient), '@')) == 0) { + msg_warn("%s: no @domain in address: %s", myname, + CONST_STR(reply->recipient)); return (0); } + domain += 1; + + /* + * In case of address extensions. + */ + if (*var_rcpt_delim == 0) { + bare_addr = 0; + } else { + bare_addr = mystrdup(addr); + if ((bare_at = strrchr(bare_addr, '@')) != 0) + *bare_at = 0; + if ((bare_ext = split_addr(bare_addr, *var_rcpt_delim)) != 0) { + if (bare_at != 0) { + *bare_at = '@'; + memmove(bare_ext - 1, bare_at, strlen(bare_at) + 1); + bare_at = bare_ext - 1; + } + } else { + myfree(bare_addr); + bare_addr = 0; + } + } + +#define CHECK_MAIL_ACCESS_RETURN(x) \ + { if (bare_addr) myfree(bare_addr); return(x); } + + /* + * Source-routed, non-local, recipient addresses are too suspicious for + * returning an "OK" result. The complicated expression below was brought + * to you by the keyboard of Victor Duchovni, Morgan Stanley and hacked + * up a bit by Wietse. + */ +#define SUSPICIOUS(domain, reply, state, reply_name, reply_class) \ + (var_allow_untrust_route == 0 \ + && (reply->flags & RESOLVE_FLAG_ROUTED) \ + && strcmp(reply_class, SMTPD_NAME_RECIPIENT) == 0 \ + && !resolve_final(state, reply_name, domain)) /* - * Look up the full address. + * Look up user+foo@domain if the address has an extension, user@domain + * otherwise. */ if ((status = check_access(state, table, CONST_STR(reply->recipient), FULL, found, reply_name, reply_class, def_acl)) != 0 || *found) - return (status); + CHECK_MAIL_ACCESS_RETURN(status == SMTPD_CHECK_OK + && SUSPICIOUS(domain, reply, state, reply_name, reply_class) ? + SMTPD_CHECK_DUNNO : status); + + /* + * Try user@domain if the address has an extension. + */ + if (bare_addr) + if ((status = check_access(state, table, bare_addr, PARTIAL, + found, reply_name, reply_class, def_acl)) != 0 + || *found) + CHECK_MAIL_ACCESS_RETURN(status == SMTPD_CHECK_OK + && SUSPICIOUS(domain, reply, state, reply_name, reply_class) ? + SMTPD_CHECK_DUNNO : status); /* * Look up the domain name, or parent domains thereof. */ - if ((status = check_domain_access(state, table, ratsign + 1, PARTIAL, + if ((status = check_domain_access(state, table, domain, PARTIAL, found, reply_name, reply_class, def_acl)) != 0 || *found) - return (status); + CHECK_MAIL_ACCESS_RETURN(status == SMTPD_CHECK_OK + && SUSPICIOUS(domain, reply, state, reply_name, reply_class) ? + SMTPD_CHECK_DUNNO : status); /* - * Look up localpart@ + * Look up user+foo@ if the address has an extension, user@ otherwise. + * XXX This leaks a little memory if map lookup is aborted. */ local_at = mystrndup(CONST_STR(reply->recipient), - ratsign - CONST_STR(reply->recipient) + 1); + domain - CONST_STR(reply->recipient)); status = check_access(state, table, local_at, PARTIAL, found, reply_name, reply_class, def_acl); myfree(local_at); if (status != 0 || *found) - return (status); + CHECK_MAIL_ACCESS_RETURN(status == SMTPD_CHECK_OK + && SUSPICIOUS(domain, reply, state, reply_name, reply_class) ? + SMTPD_CHECK_DUNNO : status); + + /* + * Look up user@ if the address has an extension. XXX Same problem here. + */ + if (bare_addr) { + local_at = (bare_at ? mystrndup(bare_addr, bare_at + 1 - bare_addr) : + mystrdup(bare_addr)); + status = check_access(state, table, local_at, PARTIAL, found, + reply_name, reply_class, def_acl); + myfree(local_at); + if (status != 0 || *found) + CHECK_MAIL_ACCESS_RETURN(status == SMTPD_CHECK_OK + && SUSPICIOUS(domain, reply, state, reply_name, reply_class) ? + SMTPD_CHECK_DUNNO : status); + } /* * Undecided when no match found. */ - return (SMTPD_CHECK_DUNNO); + CHECK_MAIL_ACCESS_RETURN(SMTPD_CHECK_DUNNO); } /* reject_maps_rbl - reject if client address in real-time blackhole list */ @@ -1566,6 +1851,7 @@ static int reject_maps_rbl(SMTPD_STATE *state) int dns_status = DNS_FAIL; int i; int result; + VSTRING *why; if (msg_verbose) msg_info("%s: %s", myname, state->addr); @@ -1591,14 +1877,18 @@ static int reject_maps_rbl(SMTPD_STATE *state) * Tack on each RBL domain name and query the DNS for an A record. If the * record exists, the client address is blacklisted. */ + why = vstring_alloc(10); while ((rbl_domain = mystrtok(&bp, " \t\r\n,")) != 0) { vstring_truncate(query, reverse_len); vstring_strcat(query, rbl_domain); dns_status = dns_lookup(STR(query), T_A, 0, (DNS_RR **) 0, - (VSTRING *) 0, (VSTRING *) 0); + (VSTRING *) 0, why); if (dns_status == DNS_OK) break; + if (dns_status != DNS_NOTFOUND) + msg_warn("%s: RBL lookup error: %s", STR(query), STR(why)); } + vstring_free(why); /* * Report the result. @@ -1631,9 +1921,44 @@ static int reject_maps_rbl(SMTPD_STATE *state) return (result); } +/* reject_sender_login_mismatch - reject login/sender ownership mismatch */ + +static int reject_sender_login_mismatch(SMTPD_STATE *state, const char *sender) +{ + const RESOLVE_REPLY *reply; + const char *login = 0; + const char *owner = 0; + + /* + * If the sender address is owned by a login name, or if the client has + * logged in, then require that the client is logged in as the owner of + * the sender address. + */ + reply = (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, sender); + owner = check_maps_find(state, sender, smtpd_sender_login_maps, + STR(reply->recipient), 0); +#ifdef USE_SASL_AUTH + if (var_smtpd_sasl_enable && state->sasl_username != 0) + login = state->sasl_username; +#endif + if (login) { + if (owner == 0 || strcasecmp(login, owner) != 0) + return (smtpd_check_reject(state, MAIL_ERROR_POLICY, + "553 <%s>: Sender address rejected: not owned by user %s", + sender, login)); + } else { + if (owner) + return (smtpd_check_reject(state, MAIL_ERROR_POLICY, + "553 <%s>: Sender address rejected: not logged in as owner", + sender)); + } + return (SMTPD_CHECK_DUNNO); +} + /* is_map_command - restriction has form: check_xxx_access type:name */ -static int is_map_command(const char *name, const char *command, char ***argp) +static int is_map_command(SMTPD_STATE *state, const char *name, + const char *command, char ***argp) { /* @@ -1647,7 +1972,8 @@ static int is_map_command(const char *name, const char *command, char ***argp) return (0); } else if (*(*argp + 1) == 0 || strchr(*(*argp += 1), ':') == 0) { msg_warn("restriction %s requires maptype:mapname", command); - longjmp(smtpd_check_buf, -1); + longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE, + "451 Server configuration error")); } else { return (1); } @@ -1666,6 +1992,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, int status = 0; ARGV *list; int found; + int saved_recursion = state->recursion; if (msg_verbose) msg_info("%s: START", myname); @@ -1676,6 +2003,15 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, msg_info("%s: name=%s", myname, name); /* + * Pseudo restrictions. + */ + if (strcasecmp(name, WARN_IF_REJECT) == 0) { + if (state->warn_if_reject == 0) + state->warn_if_reject = state->recursion; + continue; + } + + /* * Spoof the is_map_command() routine, so that we do not have to make * special cases for the implicit short-hand access map notation. */ @@ -1689,14 +2025,14 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, */ if (strcasecmp(name, PERMIT_ALL) == 0) { status = SMTPD_CHECK_OK; - if (cpp[1] != 0) + if (cpp[1] != 0 && state->warn_if_reject == 0) msg_warn("restriction `%s' after `%s' is ignored", cpp[1], PERMIT_ALL); } else if (strcasecmp(name, REJECT_ALL) == 0) { status = smtpd_check_reject(state, MAIL_ERROR_POLICY, "%d <%s>: %s rejected: Access denied", var_reject_code, reply_name, reply_class); - if (cpp[1] != 0) + if (cpp[1] != 0 && state->warn_if_reject == 0) msg_warn("restriction `%s' after `%s' is ignored", cpp[1], REJECT_ALL); } else if (strcasecmp(name, REJECT_UNAUTH_PIPE) == 0) { @@ -1710,7 +2046,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, status = reject_unknown_client(state); } else if (strcasecmp(name, PERMIT_MYNETWORKS) == 0) { status = permit_mynetworks(state); - } else if (is_map_command(name, CHECK_CLIENT_ACL, &cpp)) { + } else if (is_map_command(state, name, CHECK_CLIENT_ACL, &cpp)) { status = check_namadr_access(state, *cpp, state->name, state->addr, FULL, &found, state->namaddr, SMTPD_NAME_CLIENT, def_acl); @@ -1721,7 +2057,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, /* * HELO/EHLO parameter restrictions. */ - else if (is_map_command(name, CHECK_HELO_ACL, &cpp)) { + else if (is_map_command(state, name, CHECK_HELO_ACL, &cpp)) { if (state->helo_name) status = check_domain_access(state, *cpp, state->helo_name, FULL, &found, state->helo_name, @@ -1765,11 +2101,15 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, /* * Sender mail address restrictions. */ - else if (is_map_command(name, CHECK_SENDER_ACL, &cpp)) { + else if (is_map_command(state, name, CHECK_SENDER_ACL, &cpp)) { if (state->sender && *state->sender) status = check_mail_access(state, *cpp, state->sender, &found, state->sender, SMTPD_NAME_SENDER, def_acl); + if (state->sender && !*state->sender) + status = check_access(state, *cpp, var_smtpd_null_key, FULL, + &found, state->sender, + SMTPD_NAME_SENDER, def_acl); } else if (strcasecmp(name, REJECT_UNKNOWN_ADDRESS) == 0) { if (state->sender && *state->sender) status = reject_unknown_address(state, state->sender, @@ -1782,12 +2122,15 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, if (state->sender && *state->sender) status = reject_non_fqdn_address(state, state->sender, state->sender, SMTPD_NAME_SENDER); + } else if (strcasecmp(name, REJECT_SENDER_LOGIN_MISMATCH) == 0) { + if (state->sender && *state->sender) + status = reject_sender_login_mismatch(state, state->sender); } /* * Recipient mail address restrictions. */ - else if (is_map_command(name, CHECK_RECIP_ACL, &cpp)) { + else if (is_map_command(state, name, CHECK_RECIP_ACL, &cpp)) { if (state->recipient) status = check_mail_access(state, *cpp, state->recipient, &found, state->recipient, @@ -1805,14 +2148,16 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, if (state->recipient) status = check_relay_domains(state, state->recipient, state->recipient, SMTPD_NAME_RECIPIENT); - if (cpp[1] != 0) + if (cpp[1] != 0 && state->warn_if_reject == 0) msg_warn("restriction `%s' after `%s' is ignored", cpp[1], CHECK_RELAY_DOMAINS); -#ifdef USE_SASL_AUTH } else if (strcasecmp(name, PERMIT_SASL_AUTH) == 0) { if (var_smtpd_sasl_enable) +#ifdef USE_SASL_AUTH status = permit_sasl_auth(state, SMTPD_CHECK_OK, SMTPD_CHECK_DUNNO); +#else + msg_warn("restriction `%s' ignored: no SASL support", name); #endif } else if (strcasecmp(name, REJECT_UNKNOWN_RCPTDOM) == 0) { if (state->recipient) @@ -1827,7 +2172,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, /* * ETRN domain name restrictions. */ - else if (is_map_command(name, CHECK_ETRN_ACL, &cpp)) { + else if (is_map_command(state, name, CHECK_ETRN_ACL, &cpp)) { if (state->etrn_name) status = check_domain_access(state, *cpp, state->etrn_name, FULL, &found, state->etrn_name, @@ -1847,17 +2192,23 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, */ else { msg_warn("unknown smtpd restriction: \"%s\"", name); - break; + longjmp(smtpd_check_buf, smtpd_check_reject(state, + MAIL_ERROR_SOFTWARE, "451 Server configuration error")); } if (msg_verbose) msg_info("%s: name=%s status=%d", myname, name, status); + if (state->warn_if_reject >= state->recursion) + state->warn_if_reject = 0; + if (status != 0) break; } if (msg_verbose && name == 0) msg_info("%s: END", myname); + state->recursion = saved_recursion; + return (status); } @@ -1876,7 +2227,7 @@ char *smtpd_check_client(SMTPD_STATE *state) /* * Apply restrictions in the order as specified. */ - state->recursion = 0; + state->recursion = 1; status = setjmp(smtpd_check_buf); if (status == 0 && client_restrctions->argc) status = generic_checks(state, client_restrctions, state->namaddr, @@ -1922,7 +2273,7 @@ char *smtpd_check_helo(SMTPD_STATE *state, char *helohost) /* * Apply restrictions in the order as specified. */ - state->recursion = 0; + state->recursion = 1; status = setjmp(smtpd_check_buf); if (status == 0 && helo_restrctions->argc) status = generic_checks(state, helo_restrctions, state->helo_name, @@ -1958,7 +2309,7 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender) /* * Apply restrictions in the order as specified. */ - state->recursion = 0; + state->recursion = 1; status = setjmp(smtpd_check_buf); if (status == 0 && mail_restrctions->argc) status = generic_checks(state, mail_restrctions, sender, @@ -1982,6 +2333,13 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) return (0); /* + * XXX 2821: Section 3.6 requires that "postmaster" be accepted even when + * specified without a fully qualified domain name. + */ + if (strcasecmp(recipient, "postmaster") == 0) + return (0); + + /* * Minor kluge so that we can delegate work to the generic routine and so * that we can syslog the recipient with the reject messages. */ @@ -2005,7 +2363,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) /* * Apply restrictions in the order as specified. */ - state->recursion = 0; + state->recursion = 1; status = setjmp(smtpd_check_buf); if (status == 0 && rcpt_restrctions->argc) status = generic_checks(state, rcpt_restrctions, @@ -2050,7 +2408,7 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain) /* * Apply restrictions in the order as specified. */ - state->recursion = 0; + state->recursion = 1; status = setjmp(smtpd_check_buf); if (status == 0 && etrn_restrctions->argc) status = generic_checks(state, etrn_restrctions, domain, @@ -2117,6 +2475,23 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient) if (NOMATCH(rcpt_canon_maps, CONST_STR(reply->recipient)) && NOMATCH(canonical_maps, CONST_STR(reply->recipient)) && NOMATCH(relocated_maps, CONST_STR(reply->recipient)) + && NOMATCH(virt_mailbox_maps, CONST_STR(reply->recipient)) + && NOMATCH(virtual_maps, CONST_STR(reply->recipient))) { + (void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE, + "%d <%s>: User unknown", 550, recipient); + SMTPD_CHECK_RCPT_RETURN(STR(error_text)); + } + } + + /* + * Reject mail to unknown addresses in Postfix-style virtual domains. + */ + if (*var_virt_mailbox_maps + && (check_maps_find(state, recipient, virt_mailbox_maps, domain, 0))) { + if (NOMATCH(rcpt_canon_maps, CONST_STR(reply->recipient)) + && NOMATCH(canonical_maps, CONST_STR(reply->recipient)) + && NOMATCH(relocated_maps, CONST_STR(reply->recipient)) + && NOMATCH(virt_mailbox_maps, CONST_STR(reply->recipient)) && NOMATCH(virtual_maps, CONST_STR(reply->recipient))) { (void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE, "%d <%s>: User unknown", 550, recipient); @@ -2133,6 +2508,7 @@ char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient) if (NOMATCH(rcpt_canon_maps, CONST_STR(reply->recipient)) && NOMATCH(canonical_maps, CONST_STR(reply->recipient)) && NOMATCH(relocated_maps, CONST_STR(reply->recipient)) + && NOMATCH(virt_mailbox_maps, CONST_STR(reply->recipient)) && NOMATCH(virtual_maps, CONST_STR(reply->recipient)) && NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient))) { (void) smtpd_check_reject(state, MAIL_ERROR_BOUNCE, @@ -2154,6 +2530,13 @@ char *smtpd_check_size(SMTPD_STATE *state, off_t size) { char *myname = "smtpd_check_size"; struct fsspace fsbuf; + int status; + + /* + * Return here in case of serious trouble. + */ + if ((status = setjmp(smtpd_check_buf)) != 0) + return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); /* * Avoid overflow/underflow when comparing message size against available @@ -2226,8 +2609,13 @@ char *var_alias_maps; char *var_rcpt_canon_maps; char *var_canonical_maps; char *var_virtual_maps; +char *var_virt_mailbox_maps; char *var_relocated_maps; char *var_local_rcpt_maps; +char *var_perm_mx_networks; +char *var_par_dom_match; +char *var_smtpd_null_key; +char *var_smtpd_snd_auth_maps; typedef struct { char *name; @@ -2246,8 +2634,13 @@ static STRING_TABLE string_table[] = { VAR_RCPT_CANON_MAPS, DEF_RCPT_CANON_MAPS, &var_rcpt_canon_maps, VAR_CANONICAL_MAPS, DEF_CANONICAL_MAPS, &var_canonical_maps, VAR_VIRTUAL_MAPS, DEF_VIRTUAL_MAPS, &var_virtual_maps, + VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, + VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, + VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, + VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, + VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key, 0, }; @@ -2348,7 +2741,7 @@ static int int_update(char **argv) typedef struct { char *name; ARGV **target; -} REST_TABLE; +} REST_TABLE; static REST_TABLE rest_table[] = { "client_restrictions", &client_restrctions, @@ -2445,7 +2838,7 @@ VSTRING *canon_addr_internal(VSTRING *result, const char *addr) { if (addr == STR(result)) msg_panic("canon_addr_internal: result clobbers input"); - if (strchr(addr, '@') == 0) + if (*addr && strchr(addr, '@') == 0) msg_fatal("%s: address rewriting is disabled", addr); vstring_strcpy(result, addr); } @@ -2483,6 +2876,7 @@ int main(int argc, char **argv) ARGV *args; char *bp; char *resp; + char *addr; /* * Initialization. Use dummies for client information. @@ -2562,6 +2956,13 @@ int main(int argc, char **argv) resp = 0; break; } + if (strcasecmp(args->argv[0], VAR_VIRT_MAILBOX_MAPS) == 0) { + UPDATE_STRING(var_virt_mailbox_maps, args->argv[1]); + UPDATE_MAPS(virt_mailbox_maps, VAR_VIRT_MAILBOX_MAPS, + var_virt_mailbox_maps, DICT_FLAG_LOCK); + resp = 0; + break; + } if (strcasecmp(args->argv[0], "local_recipient_maps") == 0) { UPDATE_STRING(var_local_rcpt_maps, args->argv[1]); UPDATE_MAPS(local_rcpt_maps, VAR_LOCAL_RCPT_MAPS, @@ -2578,13 +2979,17 @@ int main(int argc, char **argv) } if (strcasecmp(args->argv[0], "mynetworks") == 0) { namadr_list_free(mynetworks); - mynetworks = namadr_list_init(args->argv[1]); + mynetworks = + namadr_list_init(match_parent_style(VAR_MYNETWORKS), + args->argv[1]); resp = 0; break; } if (strcasecmp(args->argv[0], "relay_domains") == 0) { domain_list_free(relay_domains); - relay_domains = domain_list_init(args->argv[1]); + relay_domains = + domain_list_init(match_parent_style(VAR_RELAY_DOMAINS), + args->argv[1]); resp = 0; break; } @@ -2603,18 +3008,29 @@ int main(int argc, char **argv) /* * Try restrictions. */ +#define TRIM_ADDR(src, res) { \ + if (*(res = src) == '<') { \ + res += strlen(res) - 1; \ + if (*res == '>') \ + *res = 0; \ + res = src + 1; \ + } \ + } + if (strcasecmp(args->argv[0], "helo") == 0) { state.where = "HELO"; resp = smtpd_check_helo(&state, args->argv[1]); UPDATE_STRING(state.helo_name, args->argv[1]); } else if (strcasecmp(args->argv[0], "mail") == 0) { state.where = "MAIL"; - resp = smtpd_check_mail(&state, args->argv[1]); - UPDATE_STRING(state.sender, args->argv[1]); + TRIM_ADDR(args->argv[1], addr); + UPDATE_STRING(state.sender, addr); + resp = smtpd_check_mail(&state, addr); } else if (strcasecmp(args->argv[0], "rcpt") == 0) { state.where = "RCPT"; - (resp = smtpd_check_rcpt(&state, args->argv[1])) - || (resp = smtpd_check_rcptmap(&state, args->argv[1])); + TRIM_ADDR(args->argv[1], addr); + (resp = smtpd_check_rcpt(&state, addr)) + || (resp = smtpd_check_rcptmap(&state, addr)); } break; diff --git a/gnu/dist/postfix/src/smtpd/smtpd_peer.c b/gnu/dist/postfix/src/smtpd/smtpd_peer.c index e6ef0ab3518..81f88431a09 100644 --- a/gnu/dist/postfix/src/smtpd/smtpd_peer.c +++ b/gnu/dist/postfix/src/smtpd/smtpd_peer.c @@ -119,7 +119,6 @@ void smtpd_peer_init(SMTPD_STATE *state) * If peer went away, give up. */ if (errno == ECONNRESET || errno == ECONNABORTED) { - msg_info("errno %d %m", errno); state->name = mystrdup("unknown"); state->addr = mystrdup("unknown"); state->peer_code = 5; diff --git a/gnu/dist/postfix/src/util/Makefile.in b/gnu/dist/postfix/src/util/Makefile.in index 0f9afce80b1..e483e6c761f 100644 --- a/gnu/dist/postfix/src/util/Makefile.in +++ b/gnu/dist/postfix/src/util/Makefile.in @@ -1,75 +1,82 @@ SHELL = /bin/sh -SRCS = argv.c argv_split.c attr.c basename.c binhash.c chroot_uid.c \ - close_on_exec.c concatenate.c dict.c dict_db.c dict_dbm.c \ - dict_env.c dict_ht.c dict_ldap.c dict_mysql.c dict_ni.c dict_nis.c \ - dict_nisplus.c dict_open.c dir_forest.c doze.c environ.c \ - events.c exec_command.c fifo_listen.c fifo_trigger.c file_limit.c \ - find_inet.c fsspace.c fullname.c get_domainname.c get_hostname.c \ - htable.c inet_addr_host.c inet_addr_list.c inet_addr_local.c \ - inet_connect.c inet_listen.c inet_trigger.c inet_util.c \ - line_wrap.c lowercase.c lstat_as.c mac_parse.c make_dirs.c \ - match_list.c match_ops.c msg.c msg_output.c msg_syslog.c \ - msg_vstream.c mvect.c myflock.c mymalloc.c mystrtok.c name_mask.c \ - non_blocking.c open_as.c open_limit.c open_lock.c peekfd.c \ - percentm.c posix_signals.c printable.c read_wait.c readable.c \ - readlline.c ring.c safe_getenv.c safe_open.c sane_accept.c \ - scan_dir.c set_eugid.c set_ugid.c sigdelay.c skipblanks.c \ - split_at.c stat_as.c sys_compat.c timed_connect.c timed_wait.c \ - translit.c trimblanks.c unix_connect.c unix_listen.c unix_trigger.c \ - unsafe.c username.c valid_hostname.c vbuf.c vbuf_print.c \ - vstream.c vstream_popen.c vstring.c vstring_vstream.c writable.c \ - write_buf.c write_wait.c dict_unix.c dict_pcre.c stream_listen.c \ - stream_connect.c stream_trigger.c dict_regexp.c mac_expand.c \ - clean_env.c watchdog.c spawn_command.c duplex_pipe.c sane_rename.c \ - sane_link.c unescape.c timed_read.c timed_write.c dict_tcp.c \ - hex_quote.c dict_alloc.c rand_sleep.c sane_time.c dict_debug.c \ - sane_socketpair.c ctable.c -OBJS = argv.o argv_split.o attr.o basename.o binhash.o chroot_uid.o \ - close_on_exec.o concatenate.o dict.o dict_db.o dict_dbm.o \ - dict_env.o dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \ - dict_nisplus.o dict_open.o dir_forest.o doze.o environ.o \ - events.o exec_command.o fifo_listen.o fifo_trigger.o file_limit.o \ - find_inet.o fsspace.o fullname.o get_domainname.o get_hostname.o \ - htable.o inet_addr_host.o inet_addr_list.o inet_addr_local.o \ - inet_connect.o inet_listen.o inet_trigger.o inet_util.o \ - line_wrap.o lowercase.o lstat_as.o mac_parse.o make_dirs.o \ - match_list.o match_ops.o msg.o msg_output.o msg_syslog.o \ - msg_vstream.o mvect.o myflock.o mymalloc.o mystrtok.o name_mask.o \ - non_blocking.o open_as.o open_limit.o open_lock.o peekfd.o \ - percentm.o posix_signals.o printable.o read_wait.o readable.o \ - readlline.o ring.o safe_getenv.o safe_open.o sane_accept.o \ - scan_dir.o set_eugid.o set_ugid.o sigdelay.o skipblanks.o \ - split_at.o stat_as.o sys_compat.o timed_connect.o timed_wait.o \ - translit.o trimblanks.o unix_connect.o unix_listen.o unix_trigger.o \ - unsafe.o username.o valid_hostname.o vbuf.o vbuf_print.o \ - vstream.o vstream_popen.o vstring.o vstring_vstream.o writable.o \ - write_buf.o write_wait.o dict_unix.o dict_pcre.o stream_listen.o \ - stream_connect.o stream_trigger.o dict_regexp.o mac_expand.o \ - clean_env.o watchdog.o spawn_command.o duplex_pipe.o sane_rename.o \ - sane_link.o unescape.o timed_read.o timed_write.o dict_tcp.o \ - hex_quote.o dict_alloc.o rand_sleep.o sane_time.o dict_debug.o \ - sane_socketpair.o ctable.o -HDRS = argv.h attr.h binhash.h chroot_uid.h connect.h dict.h dict_db.h \ - dict_dbm.h dict_env.h dict_ht.h dict_ldap.h dict_mysql.h \ - dict_ni.h dict_nis.h dict_nisplus.h dir_forest.h events.h \ - exec_command.h find_inet.h fsspace.h fullname.h get_domainname.h \ - get_hostname.h htable.h inet_addr_host.h inet_addr_list.h \ - inet_addr_local.h inet_util.h iostuff.h line_wrap.h listen.h lstat_as.h \ - mac_parse.h make_dirs.h match_list.h match_ops.h msg.h msg_output.h \ - msg_syslog.h msg_vstream.h mvect.h myflock.h mymalloc.h name_mask.h \ - open_as.h open_lock.h percentm.h posix_signals.h readlline.h ring.h \ - safe.h safe_open.h sane_accept.h scan_dir.h set_eugid.h set_ugid.h \ - sigdelay.h split_at.h stat_as.h stringops.h sys_defs.h \ - timed_connect.h timed_wait.h trigger.h username.h valid_hostname.h \ - vbuf.h vbuf_print.h vstream.h vstring.h vstring_vstream.h \ - dict_unix.h dict_pcre.h dict_regexp.h mac_expand.h clean_env.h \ - watchdog.h spawn_command.h sane_fsops.h dict_tcp.h hex_quote.h \ - sane_time.h sane_socketpair.h ctable.h +SRCS = alldig.c argv.c argv_split.c attr_print0.c attr_print64.c \ + attr_scan0.c attr_scan64.c base64_code.c basename.c binhash.c \ + chroot_uid.c clean_env.c close_on_exec.c concatenate.c ctable.c \ + dict.c dict_alloc.c dict_db.c dict_dbm.c dict_debug.c dict_env.c \ + dict_ht.c dict_ldap.c dict_mysql.c dict_ni.c dict_nis.c \ + dict_nisplus.c dict_open.c dict_pcre.c dict_regexp.c dict_static.c \ + dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \ + environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \ + file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \ + get_hostname.c hex_quote.c htable.c inet_addr_host.c \ + inet_addr_list.c inet_addr_local.c inet_connect.c inet_listen.c \ + inet_trigger.c inet_util.c intv.c line_wrap.c lowercase.c \ + lstat_as.c mac_expand.c mac_parse.c make_dirs.c match_list.c \ + match_ops.c msg.c msg_output.c msg_syslog.c msg_vstream.c \ + mvect.c myflock.c mymalloc.c myrand.c mystrtok.c name_mask.c \ + netstring.c non_blocking.c open_as.c open_limit.c open_lock.c \ + peekfd.c percentm.c posix_signals.c printable.c rand_sleep.c \ + read_wait.c readable.c readlline.c ring.c safe_getenv.c \ + safe_open.c sane_accept.c sane_link.c sane_rename.c \ + sane_socketpair.c sane_time.c scan_dir.c set_eugid.c set_ugid.c \ + sigdelay.c skipblanks.c spawn_command.c split_at.c \ + split_nameval.c stat_as.c stream_connect.c stream_listen.c \ + stream_trigger.c sys_compat.c timed_connect.c timed_read.c \ + timed_wait.c timed_write.c translit.c trimblanks.c unescape.c \ + unix_connect.c unix_listen.c unix_trigger.c unsafe.c username.c \ + valid_hostname.c vbuf.c vbuf_print.c vstream.c vstream_popen.c \ + vstring.c vstring_vstream.c watchdog.c writable.c write_buf.c \ + write_wait.c +OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \ + attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \ + chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \ + dict.o dict_alloc.o dict_db.o dict_dbm.o dict_debug.o dict_env.o \ + dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \ + dict_nisplus.o dict_open.o dict_pcre.o dict_regexp.o dict_static.o \ + dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \ + environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \ + file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \ + get_hostname.o hex_quote.o htable.o inet_addr_host.o \ + inet_addr_list.o inet_addr_local.o inet_connect.o inet_listen.o \ + inet_trigger.o inet_util.o intv.o line_wrap.o lowercase.o \ + lstat_as.o mac_expand.o mac_parse.o make_dirs.o match_list.o \ + match_ops.o msg.o msg_output.o msg_syslog.o msg_vstream.o \ + mvect.o myflock.o mymalloc.o myrand.o mystrtok.o name_mask.o \ + netstring.o non_blocking.o open_as.o open_limit.o open_lock.o \ + peekfd.o percentm.o posix_signals.o printable.o rand_sleep.o \ + read_wait.o readable.o readlline.o ring.o safe_getenv.o \ + safe_open.o sane_accept.o sane_link.o sane_rename.o \ + sane_socketpair.o sane_time.o scan_dir.o set_eugid.o set_ugid.o \ + sigdelay.o skipblanks.o spawn_command.o split_at.o \ + split_nameval.o stat_as.o stream_connect.o stream_listen.o \ + stream_trigger.o sys_compat.o timed_connect.o timed_read.o \ + timed_wait.o timed_write.o translit.o trimblanks.o unescape.o \ + unix_connect.o unix_listen.o unix_trigger.o unsafe.o username.o \ + valid_hostname.o vbuf.o vbuf_print.o vstream.o vstream_popen.o \ + vstring.o vstring_vstream.o watchdog.o writable.o write_buf.o \ + write_wait.o +HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \ + connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \ + dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \ + dict_nisplus.h dict_pcre.h dict_regexp.h dict_static.h dict_tcp.h \ + dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \ + fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \ + htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \ + inet_util.h intv.h iostuff.h line_wrap.h listen.h lstat_as.h \ + mac_expand.h mac_parse.h make_dirs.h match_list.h match_ops.h \ + msg.h msg_output.h msg_syslog.h msg_vstream.h mvect.h myflock.h \ + mymalloc.h myrand.h name_mask.h netstring.h open_as.h open_lock.h \ + percentm.h posix_signals.h readlline.h ring.h safe.h safe_open.h \ + sane_accept.h sane_fsops.h sane_socketpair.h sane_time.h \ + scan_dir.h set_eugid.h set_ugid.h sigdelay.h spawn_command.h \ + split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \ + timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \ + vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ stream_test.c dup2_pass_on_exec.c WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ -Wparentheses -Wstrict-prototypes -Wswitch -Wuninitialized \ - -Wunused + -Wunused DEFS = -I. -D$(SYSTYPE) CFLAGS = $(DEBUG) $(OPT) $(DEFS) FILES = Makefile $(SRCS) $(HDRS) @@ -81,7 +88,8 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \ mystrtok sigdelay translit valid_hostname vstream_popen \ vstring vstring_vstream doze select_bug stream_test mac_expand \ watchdog unescape hex_quote name_mask rand_sleep sane_time ctable \ - inet_addr_list + inet_addr_list attr_print64 attr_scan64 base64_code attr_print0 \ + attr_scan0 LIB_DIR = ../../lib INC_DIR = ../../include @@ -200,87 +208,112 @@ fifo_rdonly_bug: fifo_rdonly_bug.c $(LIB) select_bug: select_bug.c $(LIB) $(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS) -translit: $(LIB) +translit: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -fsspace: $(LIB) +fsspace: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -exec_command: $(LIB) +exec_command: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -make_dirs: $(LIB) +make_dirs: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -mac_parse: $(LIB) +mac_parse: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -vstream_popen: $(LIB) +vstream_popen: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -fifo_trigger: $(LIB) +fifo_trigger: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -doze: $(LIB) +doze: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -mac_expand: $(LIB) +mac_expand: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -watchdog: $(LIB) +watchdog: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -unescape: $(LIB) +unescape: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -hex_quote: $(LIB) +hex_quote: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -name_mask: $(LIB) +name_mask: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -rand_sleep: $(LIB) +rand_sleep: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -sane_time: $(LIB) +sane_time: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -ctable: $(LIB) +ctable: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o -inet_addr_list: $(LIB) +inet_addr_list: $(LIB) $@.o + mv $@.o junk + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) + mv junk $@.o + +attr_print64: $(LIB) $@.o + mv $@.o junk + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) + mv junk $@.o + +attr_scan64: $(LIB) $@.o + mv $@.o junk + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) + mv junk $@.o + +base64_code: $(LIB) $@.o + mv $@.o junk + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) + mv junk $@.o + +attr_print0: $(LIB) $@.o + mv $@.o junk + $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) + mv junk $@.o + +attr_scan0: $(LIB) $@.o mv $@.o junk $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) mv junk $@.o @@ -297,7 +330,8 @@ stream_test: stream_test.c $(LIB) $(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS) tests: valid_hostname_test mac_expand_test dict_test unescape_test \ - hex_quote_test ctable_test inet_addr_list_test + hex_quote_test ctable_test inet_addr_list_test base64_code_test \ + attr_scan64_test attr_scan0_test valid_hostname_test: valid_hostname valid_hostname.in valid_hostname.ref ./valid_hostname <valid_hostname.in 2>valid_hostname.tmp @@ -330,6 +364,19 @@ inet_addr_list_test: inet_addr_list diff inet_addr_list.ref inet_addr_list.tmp rm -f inet_addr_list.tmp +base64_code_test: base64_code + ./base64_code + +attr_scan64_test: attr_print64 attr_scan64 attr_scan64.ref + (./attr_print64 2>&3 | (sleep 1; ./attr_scan64)) >attr_scan64.tmp 2>&1 3>&1 + diff attr_scan64.ref attr_scan64.tmp + rm -f attr_scan64.tmp + +attr_scan0_test: attr_print0 attr_scan0 attr_scan0.ref + (./attr_print0 2>&3 | (sleep 1; ./attr_scan0)) >attr_scan0.tmp 2>&1 3>&1 + diff attr_scan0.ref attr_scan0.tmp + rm -f attr_scan0.tmp + DB_TYPE = `../postconf/postconf -h default_database_type` dict_test: dict_open testdb dict_test.in dict_test.ref @@ -340,9 +387,14 @@ dict_test: dict_open testdb dict_test.in dict_test.ref ../postmap/postmap -n testdb ./dict_open $(DB_TYPE):testdb write < dict_test.in > dict_test.tmp 2>&1 diff dict_test.ref dict_test.tmp - rm -f testdb.db testdb.dir testdb.pag + rm -f testdb.db testdb.dir testdb.pag dict_test.tmp # do not edit below this line - it is generated by 'make depend' +alldig.o: alldig.c +alldig.o: sys_defs.h +alldig.o: stringops.h +alldig.o: vstring.h +alldig.o: vbuf.h argv.o: argv.c argv.o: sys_defs.h argv.o: mymalloc.h @@ -354,11 +406,51 @@ argv_split.o: stringops.h argv_split.o: vstring.h argv_split.o: vbuf.h argv_split.o: argv.h -attr.o: attr.c -attr.o: sys_defs.h -attr.o: mymalloc.h -attr.o: htable.h -attr.o: attr.h +attr_print0.o: attr_print0.c +attr_print0.o: sys_defs.h +attr_print0.o: msg.h +attr_print0.o: mymalloc.h +attr_print0.o: vstream.h +attr_print0.o: vbuf.h +attr_print0.o: htable.h +attr_print0.o: attr.h +attr_print64.o: attr_print64.c +attr_print64.o: sys_defs.h +attr_print64.o: msg.h +attr_print64.o: mymalloc.h +attr_print64.o: vstream.h +attr_print64.o: vbuf.h +attr_print64.o: htable.h +attr_print64.o: base64_code.h +attr_print64.o: vstring.h +attr_print64.o: attr.h +attr_scan0.o: attr_scan0.c +attr_scan0.o: sys_defs.h +attr_scan0.o: msg.h +attr_scan0.o: mymalloc.h +attr_scan0.o: vstream.h +attr_scan0.o: vbuf.h +attr_scan0.o: vstring.h +attr_scan0.o: vstring_vstream.h +attr_scan0.o: htable.h +attr_scan0.o: attr.h +attr_scan64.o: attr_scan64.c +attr_scan64.o: sys_defs.h +attr_scan64.o: msg.h +attr_scan64.o: mymalloc.h +attr_scan64.o: vstream.h +attr_scan64.o: vbuf.h +attr_scan64.o: vstring.h +attr_scan64.o: htable.h +attr_scan64.o: base64_code.h +attr_scan64.o: attr.h +base64_code.o: base64_code.c +base64_code.o: sys_defs.h +base64_code.o: msg.h +base64_code.o: mymalloc.h +base64_code.o: vstring.h +base64_code.o: vbuf.h +base64_code.o: base64_code.h basename.o: basename.c basename.o: sys_defs.h basename.o: stringops.h @@ -406,6 +498,7 @@ dict.o: vbuf.h dict.o: vstring.h dict.o: readlline.h dict.o: mac_parse.h +dict.o: stringops.h dict.o: dict.h dict.o: argv.h dict.o: dict_ht.h @@ -505,6 +598,7 @@ dict_open.o: dict_ldap.h dict_open.o: dict_mysql.h dict_open.o: dict_pcre.h dict_open.o: dict_regexp.h +dict_open.o: dict_static.h dict_open.o: stringops.h dict_open.o: vstring.h dict_open.o: split_at.h @@ -525,6 +619,15 @@ dict_regexp.o: dict.h dict_regexp.o: argv.h dict_regexp.o: dict_regexp.h dict_regexp.o: mac_parse.h +dict_static.o: dict_static.c +dict_static.o: sys_defs.h +dict_static.o: mymalloc.h +dict_static.o: msg.h +dict_static.o: dict.h +dict_static.o: vstream.h +dict_static.o: vbuf.h +dict_static.o: argv.h +dict_static.o: dict_static.h dict_tcp.o: dict_tcp.c dict_tcp.o: sys_defs.h dict_tcp.o: msg.h @@ -593,6 +696,10 @@ fifo_trigger.o: fifo_trigger.c fifo_trigger.o: sys_defs.h fifo_trigger.o: msg.h fifo_trigger.o: iostuff.h +fifo_trigger.o: safe_open.h +fifo_trigger.o: vstream.h +fifo_trigger.o: vbuf.h +fifo_trigger.o: vstring.h fifo_trigger.o: trigger.h file_limit.o: file_limit.c file_limit.o: sys_defs.h @@ -674,12 +781,19 @@ inet_trigger.o: sys_defs.h inet_trigger.o: msg.h inet_trigger.o: connect.h inet_trigger.o: iostuff.h +inet_trigger.o: mymalloc.h +inet_trigger.o: events.h inet_trigger.o: trigger.h inet_util.o: inet_util.c inet_util.o: sys_defs.h inet_util.o: mymalloc.h inet_util.o: split_at.h inet_util.o: inet_util.h +intv.o: intv.c +intv.o: sys_defs.h +intv.o: mymalloc.h +intv.o: msg.h +intv.o: intv.h line_wrap.o: line_wrap.c line_wrap.o: sys_defs.h line_wrap.o: line_wrap.h @@ -726,6 +840,7 @@ match_list.o: vstring_vstream.h match_list.o: stringops.h match_list.o: argv.h match_list.o: dict.h +match_list.o: match_ops.h match_list.o: match_list.h match_ops.o: match_ops.c match_ops.o: sys_defs.h @@ -780,6 +895,9 @@ mymalloc.o: mymalloc.c mymalloc.o: sys_defs.h mymalloc.o: msg.h mymalloc.o: mymalloc.h +myrand.o: myrand.c +myrand.o: sys_defs.h +myrand.o: myrand.h mystrtok.o: mystrtok.c mystrtok.o: sys_defs.h mystrtok.o: stringops.h @@ -793,6 +911,13 @@ name_mask.o: stringops.h name_mask.o: vstring.h name_mask.o: vbuf.h name_mask.o: name_mask.h +netstring.o: netstring.c +netstring.o: sys_defs.h +netstring.o: msg.h +netstring.o: vstream.h +netstring.o: vbuf.h +netstring.o: vstring.h +netstring.o: netstring.h non_blocking.o: non_blocking.c non_blocking.o: sys_defs.h non_blocking.o: msg.h @@ -833,6 +958,7 @@ printable.o: vbuf.h rand_sleep.o: rand_sleep.c rand_sleep.o: sys_defs.h rand_sleep.o: msg.h +rand_sleep.o: myrand.h rand_sleep.o: iostuff.h read_wait.o: read_wait.c read_wait.o: sys_defs.h @@ -844,6 +970,7 @@ readable.o: msg.h readable.o: iostuff.h readlline.o: readlline.c readlline.o: sys_defs.h +readlline.o: msg.h readlline.o: vstream.h readlline.o: vbuf.h readlline.o: vstring.h @@ -862,6 +989,7 @@ safe_open.o: vstring.h safe_open.o: safe_open.h sane_accept.o: sane_accept.c sane_accept.o: sys_defs.h +sane_accept.o: msg.h sane_accept.o: sane_accept.h sane_link.o: sane_link.c sane_link.o: sys_defs.h @@ -923,6 +1051,12 @@ spawn_command.o: clean_env.h split_at.o: split_at.c split_at.o: sys_defs.h split_at.o: split_at.h +split_nameval.o: split_nameval.c +split_nameval.o: sys_defs.h +split_nameval.o: msg.h +split_nameval.o: stringops.h +split_nameval.o: vstring.h +split_nameval.o: vbuf.h stat_as.o: stat_as.c stat_as.o: sys_defs.h stat_as.o: msg.h @@ -953,6 +1087,8 @@ stream_trigger.o: sys_defs.h stream_trigger.o: msg.h stream_trigger.o: connect.h stream_trigger.o: iostuff.h +stream_trigger.o: mymalloc.h +stream_trigger.o: events.h stream_trigger.o: trigger.h sys_compat.o: sys_compat.c sys_compat.o: sys_defs.h @@ -1004,6 +1140,8 @@ unix_trigger.o: sys_defs.h unix_trigger.o: msg.h unix_trigger.o: connect.h unix_trigger.o: iostuff.h +unix_trigger.o: mymalloc.h +unix_trigger.o: events.h unix_trigger.o: trigger.h unsafe.o: unsafe.c unsafe.o: sys_defs.h diff --git a/gnu/dist/postfix/src/util/match_list.c b/gnu/dist/postfix/src/util/match_list.c index 7ae42d6d503..3d9e71c3f00 100644 --- a/gnu/dist/postfix/src/util/match_list.c +++ b/gnu/dist/postfix/src/util/match_list.c @@ -6,10 +6,11 @@ /* SYNOPSIS /* #include <match_list.h> /* -/* MATCH_LIST *match_list_init(pattern_list, count, func,...) +/* MATCH_LIST *match_list_init(flags, pattern_list, count, func,...) +/* int flags; /* const char *pattern_list; /* int count; -/* int (*func)(const char *string, const char *pattern); +/* int (*func)(int flags, const char *string, const char *pattern); /* /* int match_list_match(list, string,...) /* MATCH_LIST *list; @@ -28,9 +29,17 @@ /* a pattern match, precede a non-file name pattern with an /* exclamation point (!). /* -/* match_list_init() performs initializations. The first argument is -/* a list of patterns. The second argument specifies how many match -/* functions follow. +/* match_list_init() performs initializations. The flags argument +/* specifies the bit-wise OR of zero or more of the following: +/* .RS +/* .IP MATCH_FLAG_PARENT +/* The hostname pattern foo.com matches any name within the domain +/* foo.com. If this flag is cleared, foo.com matches itself +/* only, and .foo.com matches any name below the domain foo.com. +/* .RE +/* Specify MATCH_FLAG_NONE to request none of the above. +/* The pattern_list argument specifies a list of patterns. The third +/* argument specifies how many match functions follow. /* /* match_list_match() matches strings against the specified pattern /* list, passing the first string to the first function given to @@ -73,11 +82,13 @@ #include <stringops.h> #include <argv.h> #include <dict.h> +#include <match_ops.h> #include <match_list.h> /* Application-specific */ struct MATCH_LIST { + int flags; /* processing options */ ARGV *patterns; /* one pattern each */ int match_count; /* match function/argument count */ MATCH_LIST_FN *match_func; /* match functions */ @@ -125,14 +136,18 @@ static ARGV *match_list_parse(ARGV *list, char *string) /* match_list_init - initialize pattern list */ -MATCH_LIST *match_list_init(const char *patterns, int match_count,...) +MATCH_LIST *match_list_init(int flags, const char *patterns, int match_count,...) { MATCH_LIST *list; char *saved_patterns; va_list ap; int i; + if (flags & ~MATCH_FLAG_ALL) + msg_panic("match_list_init: bad flags 0x%x", flags); + list = (MATCH_LIST *) mymalloc(sizeof(*list)); + list->flags = flags; list->match_count = match_count; list->match_func = (MATCH_LIST_FN *) mymalloc(match_count * sizeof(MATCH_LIST_FN)); @@ -173,7 +188,7 @@ int match_list_match(MATCH_LIST * list,...) for (match = 1; *pat == '!'; pat++) match = !match; for (i = 0; i < list->match_count; i++) - if (list->match_func[i] (list->match_args[i], pat) != 0) + if (list->match_func[i] (list->flags, list->match_args[i], pat)) return (match); } if (msg_verbose) diff --git a/gnu/dist/postfix/src/util/match_ops.c b/gnu/dist/postfix/src/util/match_ops.c index 764866bbc1c..1bde84abdfa 100644 --- a/gnu/dist/postfix/src/util/match_ops.c +++ b/gnu/dist/postfix/src/util/match_ops.c @@ -6,15 +6,18 @@ /* SYNOPSIS /* #include <match_ops.h> /* -/* int match_string(string, pattern) +/* int match_string(flags, string, pattern) +/* int flags; /* const char *string; /* const char *pattern; /* -/* int match_hostname(name, pattern) +/* int match_hostname(flags, name, pattern) +/* int flags; /* const char *name; /* const char *pattern; /* -/* int match_hostaddr(addr, pattern) +/* int match_hostaddr(flags, addr, pattern) +/* int flags; /* const char *addr; /* const char *pattern; /* DESCRIPTION @@ -24,16 +27,24 @@ /* or address comparison. /* /* match_string() matches the string against the pattern, requiring -/* an exact (case-insensitive) match. +/* an exact (case-insensitive) match. The flags argument is not used. /* /* match_hostname() matches the host name when the hostname matches /* the pattern exactly, or when the pattern matches a parent domain -/* of the named host. +/* of the named host. The flags argument specifies the bit-wise OR +/* of zero or more of the following: +/* .IP MATCH_FLAG_PARENT +/* The hostname pattern foo.com matches itself and any name below +/* the domain foo.com. If this flag is cleared, foo.com matches itself +/* only, and .foo.com matches any name below the domain foo.com. +/* .RE +/* Specify MATCH_FLAG_NONE to request none of the above. /* /* match_hostaddr() matches a host address when the pattern is /* identical to the host address, or when the pattern is a net/mask /* that contains the address. The mask specifies the number of -/* bits in the network part of the pattern. +/* bits in the network part of the pattern. The flags argument is +/* not used. /* LICENSE /* .ad /* .fi @@ -72,7 +83,7 @@ /* match_string - match a string literal */ -int match_string(const char *string, const char *pattern) +int match_string(int unused_flags, const char *string, const char *pattern) { char *myname = "match_string"; int match; @@ -110,7 +121,7 @@ int match_string(const char *string, const char *pattern) /* match_hostname - match a host by name */ -int match_hostname(const char *name, const char *pattern) +int match_hostname(int flags, const char *name, const char *pattern) { char *myname = "match_hostname"; const char *pd; @@ -128,13 +139,15 @@ int match_hostname(const char *name, const char *pattern) if (strchr(pattern, ':') != 0) { temp = lowercase(mystrdup(name)); match = 0; - for (entry = temp; /* void */ ; entry = next + 1) { + for (entry = temp; /* void */ ; entry = next) { if ((match = (dict_lookup(pattern, entry) != 0)) != 0) break; if (dict_errno != 0) msg_fatal("%s: table lookup problem", pattern); - if ((next = strchr(entry, '.')) == 0) + if ((next = strchr(entry + 1, '.')) == 0) break; + if (flags & MATCH_FLAG_PARENT) + next += 1; } myfree(temp); return (match); @@ -151,9 +164,15 @@ int match_hostname(const char *name, const char *pattern) * See if the pattern is a parent domain of the hostname. */ else { - pd = name + strlen(name) - strlen(pattern); - if (pd > name && pd[-1] == '.' && strcasecmp(pd, pattern) == 0) - return (1); + if (flags & MATCH_FLAG_PARENT) { + pd = name + strlen(name) - strlen(pattern); + if (pd > name && pd[-1] == '.' && strcasecmp(pd, pattern) == 0) + return (1); + } else if (pattern[0] == '.') { + pd = name + strlen(name) - strlen(pattern); + if (pd > name && strcasecmp(pd, pattern) == 0) + return (1); + } } return (0); } @@ -181,7 +200,7 @@ static int match_parse_mask(const char *pattern, unsigned long *net_bits, /* match_hostaddr - match host by address */ -int match_hostaddr(const char *addr, const char *pattern) +int match_hostaddr(int unused_flags, const char *addr, const char *pattern) { char *myname = "match_hostaddr"; int mask_shift; diff --git a/gnu/dist/postfix/src/util/sys_defs.h b/gnu/dist/postfix/src/util/sys_defs.h index 664b32938d7..5a6cd3296e5 100644 --- a/gnu/dist/postfix/src/util/sys_defs.h +++ b/gnu/dist/postfix/src/util/sys_defs.h @@ -26,7 +26,7 @@ #if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) \ || defined(FREEBSD5) \ || defined(BSDI2) || defined(BSDI3) || defined(BSDI4) \ - || defined(OPENBSD2) || defined(NETBSD1) + || defined(OPENBSD2) || defined(OPENBSD3) || defined(NETBSD1) #define SUPPORTED #include <sys/types.h> #include <sys/param.h> @@ -52,13 +52,19 @@ #define STATFS_IN_SYS_MOUNT_H #define HAS_POSIX_REGEXP #define HAS_ST_GEN /* struct stat contains inode generation number */ +#define DEF_SENDMAIL_PATH "/usr/sbin/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif #if defined(FREEBSD2) || defined(FREEBSD3) || defined(FREEBSD4) #define HAS_DUPLEX_PIPE #endif -#if defined(OPENBSD2) || defined(FREEBSD3) || defined(FREEBSD4) +#if defined(OPENBSD2) || defined(OPENBSD3) \ + || defined(FREEBSD3) || defined(FREEBSD4) #define HAS_ISSETUGID #endif @@ -93,6 +99,11 @@ #define PRINTFLIKE(x,y) #define SCANFLIKE(x,y) #define HAS_NETINFO +#define DEF_SENDMAIL_PATH "/usr/sbin/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif /* @@ -141,6 +152,9 @@ extern int h_errno; #define DUP2_DUPS_CLOSE_ON_EXEC #define MISSING_USLEEP #define NO_HERRNO +#define DEF_SENDMAIL_PATH "/usr/lib/sendmail" +#define DEF_COMMAND_DIR "/usr/etc" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif /* @@ -207,6 +221,11 @@ extern int opterr; #define STATFS_IN_SYS_VFS_H #define memmove(d,s,l) bcopy(s,d,l) #define NO_HERRNO +#define DEF_SENDMAIL_PATH "/usr/lib/sendmail" +#define DEF_MAILQ_PATH "/usr/ucb/mailq" +#define DEF_NEWALIAS_PATH "/usr/ucb/newaliases" +#define DEF_COMMAND_DIR "/usr/etc" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif /* @@ -241,6 +260,11 @@ extern int opterr; #define LOCAL_CONNECT stream_connect #define LOCAL_TRIGGER stream_trigger #define HAS_VOLATILE_LOCKS +#define DEF_SENDMAIL_PATH "/usr/lib/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif /* @@ -303,6 +327,39 @@ extern int opterr; * AIX: a SYSV-flavored hybrid. NB: fcntl() and flock() access the same * underlying locking primitives. */ +#ifdef AIX5 +#define SUPPORTED +#include <sys/types.h> +#define MISSING_SETENV +#define _PATH_BSHELL "/bin/sh" +#define _PATH_MAILDIR "/var/spool/mail" /* paths.h lies */ +#define _PATH_DEFPATH "/usr/bin:/usr/ucb" +#define _PATH_STDPATH "/usr/bin:/usr/sbin:/usr/ucb" +#define HAS_FCNTL_LOCK +#define INTERNAL_LOCK MYFLOCK_STYLE_FCNTL +#define DEF_MAILBOX_LOCK "fcntl, dotlock" +#define USE_SYS_SELECT_H +#define HAS_FSYNC +#define HAS_DBM +#define DEF_DB_TYPE "dbm" +#define ALIAS_DB_MAP "dbm:/etc/aliases" +#define HAS_NIS +#define HAS_SA_LEN +#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0) +#define RESOLVE_H_NEEDS_STDIO_H +#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb" +#define SOCKADDR_SIZE size_t +#define SOCKOPT_SIZE size_t +#define USE_STATVFS +#define STATVFS_IN_SYS_STATVFS_H +#define STRCASECMP_IN_STRINGS_H +#define DEF_SENDMAIL_PATH "/usr/lib/sendmail" +#define DEF_MAILQ_PATH "/usr/sbin/mailq" +#define DEF_NEWALIAS_PATH "/usr/sbin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" +#endif + #ifdef AIX4 #define SUPPORTED #include <sys/types.h> @@ -335,6 +392,11 @@ extern int seteuid(uid_t); extern int setegid(gid_t); extern int initgroups(const char *, int); #endif +#define DEF_SENDMAIL_PATH "/usr/lib/sendmail" +#define DEF_MAILQ_PATH "/usr/sbin/mailq" +#define DEF_NEWALIAS_PATH "/usr/sbin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif @@ -368,6 +430,7 @@ extern time_t time(time_t *); extern int seteuid(uid_t); extern int setegid(gid_t); extern int initgroups(const char *, int); +#define DEF_SENDMAIL_PATH "/usr/lib/sendmail" #endif @@ -431,6 +494,11 @@ extern int initgroups(const char *, int); #define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT #define PREPEND_PLUS_TO_OPTSTRING #define HAS_POSIX_REGEXP +#define DEF_SENDMAIL_PATH "/usr/sbin/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif /* @@ -464,6 +532,11 @@ extern int h_errno; /* <netdb.h> imports too much stuff */ #define USE_STATFS #define STATFS_IN_SYS_VFS_H #define HAS_POSIX_REGEXP +#define DEF_SENDMAIL_PATH "/usr/sbin/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif #ifdef HPUX10 @@ -494,6 +567,11 @@ extern int h_errno; /* <netdb.h> imports too much stuff */ #define USE_STATFS #define STATFS_IN_SYS_VFS_H #define HAS_POSIX_REGEXP +#define DEF_SENDMAIL_PATH "/usr/sbin/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_COMMAND_DIR "/usr/sbin" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif #ifdef HPUX9 @@ -526,6 +604,10 @@ extern int h_errno; #define USE_STATFS #define STATFS_IN_SYS_VFS_H #define HAS_POSIX_REGEXP +#define DEF_SENDMAIL_PATH "/usr/bin/sendmail" +#define DEF_MAILQ_PATH "/usr/bin/mailq" +#define DEF_NEWALIAS_PATH "/usr/bin/newaliases" +#define DEF_DAEMON_DIR "/usr/libexec/postfix" #endif /* @@ -876,13 +958,28 @@ typedef int pid_t; #endif /* + * Memory alignment of memory allocator results. By default we align for + * doubles. + */ +#ifndef ALIGN_TYPE +# ifdef __ia64__ +# define ALIGN_TYPE long double +# else +# define ALIGN_TYPE double +# endif +#endif + + /* * Need to specify what functions never return, so that the compiler can * warn for missing initializations and other trouble. However, OPENSTEP4 * gcc 2.7.x cannot handle this so we define this only if NORETURN isn't * already defined above. + * + * Data point: gcc 2.7.2 has __attribute__ (Wietse Venema) but gcc 2.6.3 does + * not (Clive Jones). So we'll set the threshold at 2.7. */ #ifndef NORETURN -#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 || __GNUC__ >= 3 +#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7 || __GNUC__ >= 3 #define NORETURN void __attribute__((__noreturn__)) #endif #endif |
