]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.9-20111217
authorWietse Venema <wietse@porcupine.org>
Sat, 17 Dec 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:37:46 +0000 (06:37 +0000)
36 files changed:
postfix/HISTORY
postfix/README_FILES/MEMCACHE_README
postfix/README_FILES/POSTSCREEN_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/conf/master.cf
postfix/html/MEMCACHE_README.html
postfix/html/POSTSCREEN_README.html
postfix/html/memcache_table.5.html
postfix/html/postconf.5.html
postfix/html/postscreen.8.html
postfix/man/man5/memcache_table.5
postfix/man/man5/postconf.5
postfix/man/man8/postscreen.8
postfix/proto/MEMCACHE_README.html
postfix/proto/POSTSCREEN_README.html
postfix/proto/memcache_table
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/dict_memcache.c
postfix/src/global/dict_proxy.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/server_acl.c [new file with mode: 0644]
postfix/src/global/server_acl.h [new file with mode: 0644]
postfix/src/postconf/Makefile.in
postfix/src/postconf/postconf_builtin.c
postfix/src/postscreen/Makefile.in
postfix/src/postscreen/postscreen.c
postfix/src/postscreen/postscreen.h
postfix/src/postscreen/postscreen_access.c [deleted file]
postfix/src/proxymap/proxymap.c
postfix/src/util/dict.c
postfix/src/util/dict.h
postfix/src/util/dict_cache.c
postfix/src/util/dict_test.c

index 20a72296ce6affb09a6b8bb2d94b60483eb7c46a..7ee65cf81333b0760da5d2d3d6e7a6cc93ef9527 100644 (file)
@@ -17274,10 +17274,12 @@ Apologies for any names omitted.
        LDAP, *SQL, and memcache. Files: util/dict_test.c, util/dict.c,
        global/mail_dict.c.
 
-       Workaround: apparently, some distributions don't use proper
-       so-number versioning, causing programs to fail erratically
-       after an update replaces the Postfix library but not the
-       program.  Files: global/mail_version.[hc], master/*server.c,
+       Workaround: apparently, some distributions use Postfix
+       shared libraries without proper so-number versioning. This
+       causes programs to fail mysteriously, after an update
+       replaces the Postfix library but not the program (someone
+       experienced this with an extra copy of the Postfix SMTP
+       server).  Files: global/mail_version.[hc], master/*server.c,
        master/master.c, src/postalias/postalias.c,
        src/postdrop/postdrop.c, src/postfix/postfix.c,
        src/postlog/postlog.c, src/postmap/postmap.c,
@@ -17295,6 +17297,13 @@ Apologies for any names omitted.
        dependencies. Files: global/memcache_proto.[hc],
        global/dict_memcache.c.
 
+       Bugfix: missing lookup table entry and terminator, causing
+       proxymap(8) server segfault when postscreen(8) or verify(8)
+       attempted to access their cache via the proxymap(8) server.
+       This could never have worked anyway, because the Postfix
+       proxymap protocol did not support cache cleanup.  File
+       util/dict.c.
+
        Feature: support for persistent backup database in the
        memcache client. The database can be shared with the proxymap
        service, but it needs to be listed as "proxy:maptype:mapname"
@@ -17302,3 +17311,45 @@ Apologies for any names omitted.
        (depending on whether the access is read-only or read-write).
        Support for proxymap-over-tcp (proxy:maptype:mapname@host:port)
        is under development.  File: global/dict_memcache.c.
+
+20111214
+
+       Documentation: updated the submission and smtps examples
+       in the sample master.cf file, so that their logging is
+       easier to recognize.  File: conf/master.cf.
+
+20111215
+
+       Documentation: use different hosts to separate MUA "port
+       25" traffic from the "port 25" MX service. Files:
+       postscreen/postscreen.c, proto/POSTSCREEN_README.html.
+
+20111216
+
+       Cleanup: the proxymap client did not correctly propagate
+       the "open_lock" flag, causing the proxymap service to open
+       postscreen(8) and verify(8) caches twice, instead of once.
+       File: global/dict_proxy.c.
+
+       Cleanup: the verify and postscreen caches were not listed
+       as "authorized" for access via the proxywrite service. File:
+       global/mail_params.h.
+
+       Refactoring: the postscreen permanent access list code is
+       now a library module, so that it can be also used for remote
+       access to the proxymap server.  Files: global/server_acl.[hc].
+
+       Hardening: read/write deadlines, to make the proxymap server
+       suitable for remote access. File: proxymap/proxymap.c.
+
+20111217
+
+       Cleanup: more orthogonal definition of when the proxymap
+       server can/cannot share a single map instance among multiple
+       requestors, and corresponding code cleanup in the proxymap
+       client and server. Files: util/dict.h, util/dict_test.c,
+       global/dict_proxy.c, proxymap/proxymap.c.
+
+       Human factors: the postscreen/verify cache manager now logs
+       the full database name including the proxy: prefix, to avoid
+       WTF surprises. File: util/dict_cache.c.
index 4685f4c514fdac5b6317d7bef7684bcf51b4d019..56b31cd4c0ce3f7e74869c04653bea5a8bb14821 100644 (file)
@@ -13,7 +13,7 @@ supports this operation.
 
 Typically, the Postfix memcache client is used to reduce query load on a
 persistent database, but it may also be used to query a memory-only database
-for low-value, easy-to-create, information such as a reputation cache for
+for low-value, easy-to-recreate, information such as a reputation cache for
 postscreen(8), verify(8) or greylisting.
 
 L\bLi\bim\bmi\bit\bta\bat\bti\bio\bon\bns\bs
index 99977285865f8ff7fb94d1cc5904d2377c302da3..a8189e27e728e8daecec0ea4e4e44aaae6fe6365 100644 (file)
@@ -16,7 +16,9 @@ impact on legitimate email traffic.
 postscreen(8) should not be used on SMTP ports that receive mail from end-user
 clients (MUAs). In a typical deployment, postscreen(8) is used on the "port 25"
 service, while MUA clients submit mail via the submission service (port 587)
-which normally requires client authentication.
+which normally requires client authentication, or via a "port 25" server that
+provides no MX service (i.e. a dedicated server that provides submission
+service on port 25).
 
 postscreen(8) is part of a multi-layer defense.
 
@@ -159,6 +161,12 @@ postscreen_cache_map parameter specifies the location of the temporary
 whitelist. The temporary whitelist is not used for SMTP client addresses that
 appear on the permanent access list.
 
+    NOTE: To share a postscreen(8) cache between multiple postscreen(8)
+    instances, use "postscreen_cache_map = proxy:btree:/path/to/file". This
+    requires Postfix 2.9 or later; earlier proxymap(8) implementations don't
+    support cache cleanup. For an alternative approach see the memcache_table
+    (5) manpage.
+
 When the SMTP client address appears on the temporary whitelist, postscreen(8)
 logs this with the client address and port number as:
 
index c375bb3efc57ff1ef5a3f34d32a5af753a1aa4b9..5bc1f69da2ce47ba7a21bee3b514b94ea1f3bd40 100644 (file)
@@ -21,11 +21,6 @@ Support for a persistent backup database in the memcache client.
 The memcache client updates the memcache whenever it looks up or
 modifies information in the persistent database.
 
-The persistent database can be shared with the proxymap service,
-but it needs to be listed as "proxy:maptype:mapname" in the
-proxy_read_maps or proxy_write_maps parameter value (depending on
-whether the access is read-only or read-write).
-
 Support for proxymap-over-tcp (proxy:maptype:mapname@host:port) is
 under development.
 
index dd11556ff0bff7a1a6bb6bb6f813832cf5f44eb5..0daf6339904dcbfcde51696f397f8c6ab1ab9e72 100644 (file)
@@ -6,8 +6,20 @@ Wish list:
        or require that they reset dict_errno on entry, either exit
        with a fatal error or set dict_errno on error.
 
+       multi_connect() function that takes a list of inet:host:port
+       and/or unix:pathname specs, with an explicit "inet" prefix
+       argument to handle applications that use host:port only.
+       This will simplify multi-host implementation for memcache
+       client, dovecot client, and other.
+
        dict_memcache: treat "bad" key as cache miss, i.e.  read/write
-       the database as if the cache did not exist.
+       the database as if the cache did not exist. This does not
+       work because most Postfix maps (virtual, canonical, access,
+       transport, ...) also don't support spaces in keys.
+
+       postscreen: keep the cache open after "postfix reload" when
+       it is remote (type memcache: or proxy:). This does not work
+       because memcache can use a non-proxied file as backup).
 
        Is it possible to replace msg_fatal calls in match_ops.c
        by msg_warn and longjmp? The callers will have to specify
index e71ac17eed5aa741f23757797604b85ad3951cbf..dfc3eb002890482f9aa093a00c2569935755d108 100644 (file)
@@ -14,11 +14,13 @@ smtp      inet  n       -       n       -       -       smtpd
 #dnsblog   unix  -       -       n       -       0       dnsblog
 #tlsproxy  unix  -       -       n       -       0       tlsproxy
 #submission inet n       -       n       -       -       smtpd
+#  -o syslog_name=postfix/submission
 #  -o smtpd_tls_security_level=encrypt
 #  -o smtpd_sasl_auth_enable=yes
 #  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
 #  -o milter_macro_daemon_name=ORIGINATING
 #smtps     inet  n       -       n       -       -       smtpd
+#  -o syslog_name=postfix/smtps
 #  -o smtpd_tls_wrappermode=yes
 #  -o smtpd_sasl_auth_enable=yes
 #  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
index 5f3226cc6c1ecd74457ba2ee57157acf5afe047b..5ee1d554c0c64250b0651b483e2d7b55fab136f1 100644 (file)
@@ -29,7 +29,7 @@ this operation. </p>
 
 <p> Typically, the Postfix memcache client is used to reduce query
 load on a persistent database, but it may also be used to query a
-memory-only database for low-value, easy-to-create, information
+memory-only database for low-value, easy-to-recreate, information
 such as a reputation cache for <a href="postscreen.8.html">postscreen(8)</a>, <a href="verify.8.html">verify(8)</a> or greylisting.
 </p>
 
index bd4e666777d254679f9f0c82e3f4f5b2625cc09f..9e717aa73ad46ce4e5bb624d6592fc22ed853f1b 100644 (file)
@@ -32,7 +32,9 @@ pass its tests; by allowing whitelisted clients to skip tests,
 mail from end-user clients (MUAs). In a typical deployment,
 <a href="postscreen.8.html">postscreen(8)</a> is used on the "port 25" service, while MUA clients
 submit mail via the submission service (port 587) which normally
-requires client authentication. </p>
+requires client authentication, or via a "port 25" server that
+provides no MX service (i.e. a dedicated server that provides
+submission service on port 25). </p>
 
 <p> <a href="postscreen.8.html">postscreen(8)</a> is part of a multi-layer defense. <p>
 
@@ -216,6 +218,13 @@ specifies the location of the temporary whitelist.  The
 temporary whitelist is not used for SMTP client addresses
 that appear on the <i>permanent</i> access list. </p>
 
+<blockquote> <p> NOTE: To share a <a href="postscreen.8.html">postscreen(8)</a> cache between
+multiple <a href="postscreen.8.html">postscreen(8)</a> instances, use "<tt><a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> =
+<a href="proxymap.8.html">proxy</a>:btree:/path/to/file</tt>".  This requires Postfix 2.9 or
+later; earlier <a href="proxymap.8.html">proxymap(8)</a> implementations don't support cache
+cleanup.  For an alternative approach see the <a href="memcache_table.5.html">memcache_table(5)</a>
+manpage.  </p> </blockquote>
+
 <p> When the SMTP client address appears on the temporary
 whitelist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port
 number as: </p>
index 85610f977c0b8a9354fcd78f48ea260890642596..a2042e7c2786a03946b12f28b28c973a17142a18 100644 (file)
@@ -40,10 +40,14 @@ MEMCACHE_TABLE(5)                                            MEMCACHE_TABLE(5)
               memcache client will update the  memcache  database
               whenever  it looks up or changes information in the
               persistent database. Specify a Postfix "<a href="DATABASE_README.html">type:table</a>"
-              database. Example:
+              database. Examples:
 
+                  # Non-shared postscreen cache.
                   backup = btree:/var/lib/postfix/<a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a>
 
+                  # Shared postscreen cache for processes on the same host.
+                  backup = <a href="proxymap.8.html">proxy</a>:btree:/var/lib/postfix/<a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a>
+
               Access to remote proxymap servers is under develop-
               ment.
 
index ccc07e9de9a2fca17cbbaff358e937fe8e87d247..5ef3c7bd0e41e4db3c252ca3de5c1f428bdf7968 100644 (file)
@@ -7000,6 +7000,12 @@ seconds. </p>
 
 <p> Persistent storage for the <a href="postscreen.8.html">postscreen(8)</a> server decisions. </p>
 
+<p> To share a <a href="postscreen.8.html">postscreen(8)</a> cache between multiple <a href="postscreen.8.html">postscreen(8)</a>
+instances, use "<a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> = <a href="proxymap.8.html">proxy</a>:btree:/path/to/file".
+This requires Postfix version 2.9 or later; earlier <a href="proxymap.8.html">proxymap(8)</a>
+implementations don't support cache cleanup. For an alternative
+approach see the <a href="memcache_table.5.html">memcache_table(5)</a> manpage. </p>
+
 <p> This feature is available in Postfix 2.8. </p>
 
 
index 6e74138f43b3e2d8636aaf7f78cf46c04e3b3c10..d3636546c35f95373eaa09429ec18539b81785d7 100644 (file)
@@ -22,7 +22,10 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
        This program should not be used on SMTP ports that receive
        mail from end-user clients (MUAs). In  a  typical  deploy-
        ment,  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  is  used  on  the "port 25" service,
-       while MUA clients submit mail via the <b>submission</b>  service.
+       while MUA clients submit mail via the <b>submission</b>  service,
+       or  via  a  "port  25"  server that provides no MX service
+       (i.e.  a dedicated server that provides <b>submission</b> service
+       on port 25).
 
        <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  maintains a temporary whitelist for clients
        that have passed a number of tests.  When an  SMTP  client
index 4d8a48dbaf124e0562618fc46b043357c8adcb24..87de7eccd69ce4763feca0265c2c826e35cba97e 100644 (file)
@@ -44,10 +44,14 @@ An optional Postfix database that provides persistent backup
 for the memcache database. The Postfix memcache client will
 update the memcache database whenever it looks up or changes
 information in the persistent database. Specify a Postfix
-"type:table" database. Example:
+"type:table" database. Examples:
 
 .nf
+    # Non-shared postscreen cache.
     backup = btree:/var/lib/postfix/postscreen_cache_map
+
+    # Shared postscreen cache for processes on the same host.
+    backup = proxy:btree:/var/lib/postfix/postscreen_cache_map
 .fi
 
 Access to remote proxymap servers is under development.
index dd4c9464ea20a477ab0b7d4a7c3d2e207e8d3024..d5b5e17f172f567eb5a52d3ecc76ce625a646dfb 100644 (file)
@@ -4015,6 +4015,12 @@ This feature is available in Postfix 2.8.
 .SH postscreen_cache_map (default: btree:$data_directory/postscreen_cache)
 Persistent storage for the \fBpostscreen\fR(8) server decisions.
 .PP
+To share a \fBpostscreen\fR(8) cache between multiple \fBpostscreen\fR(8)
+instances, use "postscreen_cache_map = proxy:btree:/path/to/file".
+This requires Postfix version 2.9 or later; earlier \fBproxymap\fR(8)
+implementations don't support cache cleanup. For an alternative
+approach see the \fBmemcache_table\fR(5) manpage.
+.PP
 This feature is available in Postfix 2.8.
 .SH postscreen_cache_retention_time (default: 7d)
 The amount of time that \fBpostscreen\fR(8) will cache an expired
index 2147fb9c20155c327411c711f8bde6ebbbd23c04..5a9b275aa6bc49e7d7caf577ac0bdbc73c4c4c27 100644 (file)
@@ -21,7 +21,10 @@ processes remain available for legitimate clients.
 This program should not be used on SMTP ports that receive
 mail from end-user clients (MUAs). In a typical deployment,
 \fBpostscreen\fR(8) is used on the "port 25" service, while
-MUA clients submit mail via the \fBsubmission\fR service.
+MUA clients submit mail via the \fBsubmission\fR service,
+or via a "port 25" server that provides no MX service (i.e.
+a dedicated server that provides \fBsubmission\fR service
+on port 25).
 
 \fBpostscreen\fR(8) maintains a temporary whitelist for
 clients that have passed a number of tests.  When an SMTP
index 62825d6a37f45a55c1072879fd42dc553c1d0f8c..3f2c3e09b7ab35dae626fd31f3e4b4f563b62bec 100644 (file)
@@ -29,7 +29,7 @@ this operation. </p>
 
 <p> Typically, the Postfix memcache client is used to reduce query
 load on a persistent database, but it may also be used to query a
-memory-only database for low-value, easy-to-create, information
+memory-only database for low-value, easy-to-recreate, information
 such as a reputation cache for postscreen(8), verify(8) or greylisting.
 </p>
 
index 6de1e7286544268191d34fddeb78809d977d8157..44a8b785b4a724a6a4a7816a0ce002a9ebfc7ec0 100644 (file)
@@ -32,7 +32,9 @@ postscreen(8) minimizes its impact on legitimate email traffic.
 mail from end-user clients (MUAs). In a typical deployment,
 postscreen(8) is used on the "port 25" service, while MUA clients
 submit mail via the submission service (port 587) which normally
-requires client authentication. </p>
+requires client authentication, or via a "port 25" server that
+provides no MX service (i.e. a dedicated server that provides
+submission service on port 25). </p>
 
 <p> postscreen(8) is part of a multi-layer defense. <p>
 
@@ -216,6 +218,13 @@ specifies the location of the temporary whitelist.  The
 temporary whitelist is not used for SMTP client addresses
 that appear on the <i>permanent</i> access list. </p>
 
+<blockquote> <p> NOTE: To share a postscreen(8) cache between
+multiple postscreen(8) instances, use "<tt>postscreen_cache_map =
+proxy:btree:/path/to/file</tt>".  This requires Postfix 2.9 or
+later; earlier proxymap(8) implementations don't support cache
+cleanup.  For an alternative approach see the memcache_table(5)
+manpage.  </p> </blockquote>
+
 <p> When the SMTP client address appears on the temporary
 whitelist, postscreen(8) logs this with the client address and port
 number as: </p>
index f2beacd7c747caae3d7066ba738005ad2ed6ee72..129e7d4382e19c855afb5d6efe91e453006f8073 100644 (file)
 #      for the memcache database. The Postfix memcache client will
 #      update the memcache database whenever it looks up or changes
 #      information in the persistent database. Specify a Postfix
-#      "type:table" database. Example:
+#      "type:table" database. Examples:
 #
 # .nf
+#          # Non-shared postscreen cache.
 #          backup = btree:/var/lib/postfix/postscreen_cache_map
+#
+#          # Shared postscreen cache for processes on the same host.
+#          backup = proxy:btree:/var/lib/postfix/postscreen_cache_map
 # .fi
 #
 #      Access to remote proxymap servers is under development.
index b34499579cf058ecf725789d5005e1aa8ac0296f..638e81205a0433a820703491577b589cf7a26e43 100644 (file)
@@ -12796,6 +12796,12 @@ patch for Postfix 2.6. </p>
 
 <p> Persistent storage for the postscreen(8) server decisions. </p>
 
+<p> To share a postscreen(8) cache between multiple postscreen(8)
+instances, use "postscreen_cache_map = proxy:btree:/path/to/file".
+This requires Postfix version 2.9 or later; earlier proxymap(8)
+implementations don't support cache cleanup. For an alternative
+approach see the memcache_table(5) manpage. </p>
+
 <p> This feature is available in Postfix 2.8. </p>
 
 %PARAM smtpd_service_name smtpd
index e771052cd98b356dd04b4c11916da6b601b5c02c..586d056460d759486e40a2b8dccd3e8f43f0c4ff 100644 (file)
@@ -31,7 +31,7 @@ SRCS  = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
        fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \
        match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
        smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \
-       dict_memcache.c mail_version.c memcache_proto.c
+       dict_memcache.c mail_version.c memcache_proto.c server_acl.c
 OBJS   = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
        clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
@@ -64,7 +64,7 @@ OBJS  = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \
        match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
        smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \
-       dict_memcache.o mail_version.o memcache_proto.o
+       dict_memcache.o mail_version.o memcache_proto.o server_acl.o
 HDRS   = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
        conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
@@ -90,7 +90,7 @@ HDRS  = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        verp_sender.h wildcard_inet_addr.h xtext.h delivered_hdr.h \
        fold_addr.h header_body_checks.h data_redirect.h match_service.h \
        addr_match_list.h smtp_reply_footer.h safe_ultostr.h \
-       verify_sender_addr.h dict_memcache.h memcache_proto.h
+       verify_sender_addr.h dict_memcache.h memcache_proto.h server_acl.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -104,7 +104,7 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
        verify_clnt xtext anvil_clnt scache ehlo_mask \
        valid_mailhost_addr own_inet_addr header_body_checks \
        data_redirect addr_match_list safe_ultostr verify_sender_addr \
-       mail_version mail_dict
+       mail_version mail_dict server_acl
 
 LIBS   = ../../lib/libutil.a
 LIB_DIR        = ../../lib
@@ -302,6 +302,9 @@ mail_version: mail_version.c $(LIB) $(LIBS)
 mail_dict: mail_dict.c $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
+server_acl: server_acl.c $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
 tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
        xtext_test scache_multi_test ehlo_mask_test \
        namadr_list_test mail_conf_time_test header_body_checks_tests \
@@ -1570,7 +1573,15 @@ mime_state.o: mail_params.h
 mime_state.o: mime_state.c
 mime_state.o: mime_state.h
 mime_state.o: rec_type.h
+mkmap_cdb.o: ../../include/argv.h
+mkmap_cdb.o: ../../include/dict.h
+mkmap_cdb.o: ../../include/dict_cdb.h
+mkmap_cdb.o: ../../include/mymalloc.h
 mkmap_cdb.o: ../../include/sys_defs.h
+mkmap_cdb.o: ../../include/vbuf.h
+mkmap_cdb.o: ../../include/vstream.h
+mkmap_cdb.o: ../../include/vstring.h
+mkmap_cdb.o: mkmap.h
 mkmap_cdb.o: mkmap_cdb.c
 mkmap_db.o: ../../include/argv.h
 mkmap_db.o: ../../include/dict.h
@@ -1954,6 +1965,18 @@ sent.o: sent.c
 sent.o: sent.h
 sent.o: trace.h
 sent.o: verify.h
+server_acl.o: ../../include/match_list.h
+server_acl.o: ../../include/match_ops.h
+server_acl.o: ../../include/msg.h
+server_acl.o: ../../include/mymalloc.h
+server_acl.o: ../../include/stringops.h
+server_acl.o: ../../include/sys_defs.h
+server_acl.o: ../../include/vbuf.h
+server_acl.o: ../../include/vstring.h
+server_acl.o: addr_match_list.h
+server_acl.o: mail_params.h
+server_acl.o: match_parent_style.h
+server_acl.o: server_acl.c
 smtp_reply_footer.o: ../../include/mac_expand.h
 smtp_reply_footer.o: ../../include/mac_parse.h
 smtp_reply_footer.o: ../../include/msg.h
index 8f635f71792a18056b924ae96c51963596839500..f140ee7df20ddca36edfd072c1b498e836d88670 100644 (file)
@@ -109,7 +109,7 @@ typedef struct {
 #define STR(x) vstring_str(x)
 #define LEN(x) VSTRING_LEN(x)
 
-#define msg_verbose 1
+/*#define msg_verbose 1*/
 
 /* dict_memcache_set - set memcache key/value */
 
index e09399cabbb63b6a266ae9ecbb90eb3a9660a19d..a4d7a902d40c41afabd63ca95e26b344daa677a2 100644 (file)
@@ -72,7 +72,7 @@ typedef struct {
     DICT    dict;                      /* generic members */
     CLNT_STREAM *clnt;                 /* client handle (shared) */
     const char *service;               /* service name */
-    int     in_flags;                  /* caller-specified flags */
+    int     inst_flags;                        /* saved dict flags */
     VSTRING *reskey;                   /* result key storage */
     VSTRING *result;                   /* storage */
 } DICT_PROXY;
@@ -112,7 +112,7 @@ static int dict_proxy_sequence(DICT *dict, int function,
     VSTRING_TERMINATE(dict_proxy->reskey);
     VSTRING_RESET(dict_proxy->result);
     VSTRING_TERMINATE(dict_proxy->result);
-    request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK)
+    request_flags = dict_proxy->inst_flags
        | (dict->flags & DICT_FLAG_RQST_MASK);
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
@@ -189,7 +189,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
      */
     VSTRING_RESET(dict_proxy->result);
     VSTRING_TERMINATE(dict_proxy->result);
-    request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK)
+    request_flags = dict_proxy->inst_flags
        | (dict->flags & DICT_FLAG_RQST_MASK);
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
@@ -259,7 +259,7 @@ static void dict_proxy_update(DICT *dict, const char *key, const char *value)
      * associated with a specific connection. Each lookup needs to specify
      * the table and the flags that were specified to dict_proxy_open().
      */
-    request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK)
+    request_flags = dict_proxy->inst_flags
        | (dict->flags & DICT_FLAG_RQST_MASK);
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
@@ -325,7 +325,7 @@ static int dict_proxy_delete(DICT *dict, const char *key)
      * associated with a specific connection. Each lookup needs to specify
      * the table and the flags that were specified to dict_proxy_open().
      */
-    request_flags = (dict_proxy->in_flags & DICT_FLAG_RQST_MASK)
+    request_flags = dict_proxy->inst_flags
        | (dict->flags & DICT_FLAG_RQST_MASK);
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
@@ -455,7 +455,7 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
     dict_proxy->dict.delete = dict_proxy_delete;
     dict_proxy->dict.sequence = dict_proxy_sequence;
     dict_proxy->dict.close = dict_proxy_close;
-    dict_proxy->in_flags = dict_flags;
+    dict_proxy->inst_flags = (dict_flags & DICT_FLAG_INST_MASK);
     dict_proxy->reskey = vstring_alloc(10);
     dict_proxy->result = vstring_alloc(10);
     dict_proxy->clnt = *pstream;
@@ -472,7 +472,7 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
        if (attr_print(stream, ATTR_FLAG_NONE,
                       ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_OPEN,
                       ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict_proxy->dict.name,
-                      ATTR_TYPE_INT, MAIL_ATTR_FLAGS, dict_proxy->in_flags,
+                    ATTR_TYPE_INT, MAIL_ATTR_FLAGS, dict_proxy->inst_flags,
                       ATTR_TYPE_END) != 0
            || vstream_fflush(stream)
            || attr_scan(stream, ATTR_FLAG_STRICT,
@@ -494,7 +494,7 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
                msg_fatal("%s service is not configured for table \"%s\"",
                          dict_proxy->service, dict_proxy->dict.name);
            case PROXY_STAT_OK:
-               dict_proxy->dict.flags = dict_proxy->in_flags
+               dict_proxy->dict.flags = (dict_flags & ~DICT_FLAG_IMPL_MASK)
                    | (server_flags & DICT_FLAG_IMPL_MASK);
                return (DICT_DEBUG (&dict_proxy->dict));
            default:
index 32b59c5acfd280fe3c00afe2a8d573316242ad7d..936835e7013012606ab2c88a7cd68078647a04a8 100644 (file)
@@ -2235,14 +2235,25 @@ extern int var_local_rcpt_code;
                                " $" VAR_SEND_BCC_MAPS \
                                " $" VAR_RCPT_BCC_MAPS \
                                " $" VAR_SMTP_GENERIC_MAPS \
-                               " $" VAR_LMTP_GENERIC_MAPS
+                               " $" VAR_LMTP_GENERIC_MAPS \
+                               " $" VAR_ALIAS_MAPS
 extern char *var_proxy_read_maps;
 
 #define VAR_PROXY_WRITE_MAPS   "proxy_write_maps"
 #define DEF_PROXY_WRITE_MAPS   "$" VAR_SMTP_SASL_AUTH_CACHE_NAME \
-                               " $" VAR_LMTP_SASL_AUTH_CACHE_NAME
+                               " $" VAR_LMTP_SASL_AUTH_CACHE_NAME \
+                               " $" VAR_VERIFY_MAP \
+                               " $" VAR_PSC_CACHE_MAP
 extern char *var_proxy_write_maps;
 
+#define VAR_PROXY_READ_ACL     "proxy_read_access_list"
+#define DEF_PROXY_READ_ACL     "reject"
+extern char *var_proxy_read_acl;
+
+#define VAR_PROXY_WRITE_ACL    "proxy_write_access_list"
+#define DEF_PROXY_WRITE_ACL    "reject"
+extern char *var_proxy_write_acl;
+
  /*
   * Other.
   */
@@ -3438,14 +3449,8 @@ extern char *var_psc_exp_filter;
 #define DEF_PSC_CMD_FILTER     ""
 extern char *var_psc_cmd_filter;
 
-#define PSC_ACL_NAME_WL_MYNETWORKS "permit_mynetworks"
-#define PSC_ACL_NAME_WHITELIST "permit"
-#define PSC_ACL_NAME_BLACKLIST "reject"
-#define PSC_ACL_NAME_DUNNO     "dunno"
-#define PSC_ACL_NAME_ERROR     "error"
-
 #define VAR_PSC_ACL            "postscreen_access_list"
-#define DEF_PSC_ACL            PSC_ACL_NAME_WL_MYNETWORKS
+#define DEF_PSC_ACL            SERVER_ACL_NAME_WL_MYNETWORKS
 extern char *var_psc_acl;
 
 #define VAR_PSC_WLIST_IF       "postscreen_whitelist_interfaces"
index f35591f459641793f70208db3ff41f93c24e7e37..032b403aa5506cd8b47c2e34215803190fea94b3 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20111213"
+#define MAIL_RELEASE_DATE      "20111217"
 #define MAIL_VERSION_NUMBER    "2.9"
 
 #ifdef SNAPSHOT
diff --git a/postfix/src/global/server_acl.c b/postfix/src/global/server_acl.c
new file mode 100644 (file)
index 0000000..f4a78fb
--- /dev/null
@@ -0,0 +1,278 @@
+/*++
+/* NAME
+/*     server_acl 3
+/* SUMMARY
+/*     server access list
+/* SYNOPSIS
+/*     #include <server_acl.h>
+/*
+/*     void    server_acl_pre_jail_init(mynetworks, param_name)
+/*     const char *mynetworks;
+/*     const char *param_name;
+/*
+/*     SERVER_ACL *server_acl_parse(extern_acl, param_name)
+/*     const char *extern_acl;
+/*     const char *param_name;
+/*
+/*     int     server_acl_eval(client_addr, intern_acl, param_name)
+/*     const char *client_addr;
+/*     SERVER_ACL *intern_acl;
+/*     const char *param_name;
+/* DESCRIPTION
+/*     This module implements a permanent black/whitelist that
+/*     is meant to be evaluated immediately after a client connects
+/*     to a server.
+/*
+/*     server_acl_pre_jail_init() does before-chroot initialization
+/*     for the permit_mynetworks setting.
+/*
+/*     server_acl_parse() converts an access list from raw string
+/*     form to binary form. It should also be called as part of
+/*     before-chroot initialization.
+/*
+/*     server_acl_eval() evaluates an access list for the specified
+/*     client address.  The result is SERVER_ACL_ACT_PERMIT (permit),
+/*     SERVER_ACL_ACT_REJECT (reject), SERVER_ACL_ACT_DUNNO (no
+/*     decision), or SERVER_ACL_ACT_ERROR (error, unknown command
+/*     or database access error).
+/*
+/*     Arguments:
+/* .IP mynetworks
+/*     Network addresses that match "permit_mynetworks".
+/* .IP param_name
+/*     The configuration parameter name for the access list from
+/*     main.cf.  The information is used for error reporting (nested
+/*     table, unknown keyword) and to select the appropriate
+/*     behavior from parent_domain_matches_subdomains.
+/* .IP extern_acl
+/*     External access list representation.
+/* .IP intern_acl
+/*     Internal access list representation.
+/* .IP client_addr
+/*     The client IP address as printable string (without []).
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <dict.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <addr_match_list.h>
+#include <match_parent_style.h>
+#include <server_acl.h>
+
+/* Application-specific. */
+
+#define SERVER_ACL_SEPARATORS  ", \t\r\n"
+
+static ADDR_MATCH_LIST *server_acl_mynetworks;
+
+#define STR vstring_str
+
+/* server_acl_pre_jail_init - initialize */
+
+void    server_acl_pre_jail_init(const char *mynetworks, const char *origin)
+{
+    if (server_acl_mynetworks)
+       addr_match_list_free(server_acl_mynetworks);
+    server_acl_mynetworks = addr_match_list_init(match_parent_style(origin),
+                                                mynetworks);
+}
+
+/* server_acl_parse - parse access list */
+
+SERVER_ACL *server_acl_parse(const char *extern_acl, const char *origin)
+{
+    char   *saved_acl = mystrdup(extern_acl);
+    SERVER_ACL *intern_acl = argv_alloc(1);
+    char   *bp = saved_acl;
+    char   *acl;
+
+#define STREQ(x,y) ((*x) == (*y) && strcasecmp((x), (y)) == 0)
+#define STRNE(x,y) ((*x) != (*y) || strcasecmp((x), (y)) != 0)
+
+    /*
+     * Nested tables are not allowed. Tables are opened before entering the
+     * chroot jail, while access lists are evaluated after entering the
+     * chroot jail.
+     */
+    while ((acl = mystrtok(&bp, SERVER_ACL_SEPARATORS)) != 0) {
+       if (strchr(acl, ':') != 0) {
+           if (strchr(origin, ':') != 0) {
+               msg_warn("table %s: lookup result \"%s\" is not allowed"
+                        " -- ignoring remainder of access list",
+                        origin, acl);
+               argv_add(intern_acl, SERVER_ACL_NAME_DUNNO, (char *) 0);
+               break;
+           } else {
+               if (dict_handle(acl) == 0)
+                   dict_register(acl, dict_open(acl, O_RDONLY, DICT_FLAG_LOCK
+                                                 | DICT_FLAG_FOLD_FIX));
+           }
+       }
+       argv_add(intern_acl, acl, (char *) 0);
+    }
+    argv_terminate(intern_acl);
+
+    /*
+     * Cleanup.
+     */
+    myfree(saved_acl);
+    return (intern_acl);
+}
+
+/* server_acl_eval - evaluate access list */
+
+int     server_acl_eval(const char *client_addr, SERVER_ACL * intern_acl,
+                               const char *origin)
+{
+    const char *myname = "server_acl_eval";
+    char  **cpp;
+    DICT   *dict;
+    SERVER_ACL *argv;
+    const char *acl;
+    const char *dict_val;
+    int     ret;
+    ARGV    fake_argv;
+    const char *fake_args[2];
+
+    for (cpp = intern_acl->argv; (acl = *cpp) != 0; cpp++) {
+       if (msg_verbose)
+           msg_info("source=%s address=%s acl=%s",
+                    origin, client_addr, acl);
+       if (STREQ(acl, SERVER_ACL_NAME_REJECT)) {
+           return (SERVER_ACL_ACT_REJECT);
+       } else if (STREQ(acl, SERVER_ACL_NAME_PERMIT)) {
+           return (SERVER_ACL_ACT_PERMIT);
+       } else if (STREQ(acl, SERVER_ACL_NAME_WL_MYNETWORKS)) {
+           if (addr_match_list_match(server_acl_mynetworks, client_addr))
+               return (SERVER_ACL_ACT_PERMIT);
+       } else if (strchr(acl, ':') != 0) {
+           if ((dict = dict_handle(acl)) == 0)
+               msg_panic("%s: unexpected dictionary: %s", myname, acl);
+           if ((dict_val = dict_get(dict, client_addr)) != 0) {
+               /* Fake up an ARGV to avoid lots of mallocs and frees. */
+               if (dict_val[strcspn(dict_val, ":" SERVER_ACL_SEPARATORS)] == 0) {
+                   fake_args[0] = dict_val;
+                   fake_args[1] = 0;
+                   fake_argv.argv = (char **) fake_args;
+                   fake_argv.argc = fake_argv.len = 1;
+                   ret = server_acl_eval(client_addr, &fake_argv, acl);
+               } else {
+                   argv = server_acl_parse(dict_val, acl);
+                   ret = server_acl_eval(client_addr, argv, acl);
+                   argv_free(argv);
+               }
+               if (ret != SERVER_ACL_ACT_DUNNO)
+                   return (ret);
+           } else if (dict_errno != 0) {
+               msg_warn("%s: table lookup error -- ignoring the remainder "
+                        "of this access list", acl);
+               return (SERVER_ACL_ACT_ERROR);
+           }
+       } else if (STREQ(acl, SERVER_ACL_NAME_DUNNO)) {
+           return (SERVER_ACL_ACT_DUNNO);
+       } else {
+           msg_warn("%s: unknown command: %s -- ignoring the remainder "
+                    "of this access list", origin, acl);
+           return (SERVER_ACL_ACT_ERROR);
+       }
+    }
+    if (msg_verbose)
+       msg_info("source=%s address=%s - no match",
+                origin, client_addr);
+    return (SERVER_ACL_ACT_DUNNO);
+}
+
+ /*
+  * Access lists need testing. Not only with good inputs; error cases must
+  * also be handled appropriately.
+  */
+#ifdef TEST
+#include <unistd.h>
+#include <stdlib.h>
+#include <vstring_vstream.h>
+#include <name_code.h>
+#include <split_at.h>
+
+char   *var_par_dom_match = DEF_PAR_DOM_MATCH;
+char   *var_mynetworks = "";
+char   *var_server_acl = "";
+
+#define UPDATE_VAR(s,v) do { if (*(s)) myfree(s); (s) = mystrdup(v); } while (0)
+
+int     main(void)
+{
+    VSTRING *buf = vstring_alloc(100);
+    SERVER_ACL *argv;
+    int     ret;
+    int     have_tty = isatty(0);
+    char   *bufp;
+    char   *cmd;
+    char   *value;
+    const NAME_CODE acl_map[] = {
+       SERVER_ACL_NAME_ERROR, SERVER_ACL_ACT_ERROR,
+       SERVER_ACL_NAME_PERMIT, SERVER_ACL_ACT_PERMIT,
+       SERVER_ACL_NAME_REJECT, SERVER_ACL_ACT_REJECT,
+       SERVER_ACL_NAME_DUNNO, SERVER_ACL_ACT_DUNNO,
+       0,
+    };
+
+#define VAR_SERVER_ACL "server_acl"
+
+    while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
+       bufp = STR(buf);
+       if (have_tty == 0) {
+           vstream_printf("> %s\n", bufp);
+           vstream_fflush(VSTREAM_OUT);
+       }
+       if (*bufp == '#')
+           continue;
+       if ((cmd = mystrtok(&bufp, " =")) == 0 || STREQ(cmd, "?")) {
+           vstream_printf("usage: %s=value|%s=value|address=value\n",
+                          VAR_MYNETWORKS, VAR_SERVER_ACL);
+       } else if ((value = mystrtok(&bufp, " =")) == 0) {
+           vstream_printf("missing value\n");
+       } else if (STREQ(cmd, VAR_MYNETWORKS)) {
+           UPDATE_VAR(var_mynetworks, value);
+       } else if (STREQ(cmd, VAR_SERVER_ACL)) {
+           UPDATE_VAR(var_server_acl, value);
+       } else if (STREQ(cmd, "address")) {
+           server_acl_pre_jail_init(var_mynetworks, VAR_SERVER_ACL);
+           argv = server_acl_parse(var_server_acl, VAR_SERVER_ACL);
+           ret = server_acl_eval(value, argv, VAR_SERVER_ACL);
+           argv_free(argv);
+           vstream_printf("%s: %s\n", value, str_name_code(acl_map, ret));
+       } else {
+           vstream_printf("unknown command: \"%s\"\n", cmd);
+       }
+       vstream_fflush(VSTREAM_OUT);
+    }
+    vstring_free(buf);
+    exit(0);
+}
+
+#endif
diff --git a/postfix/src/global/server_acl.h b/postfix/src/global/server_acl.h
new file mode 100644 (file)
index 0000000..4951f8f
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef _SERVER_ACL_INCLUDED_
+#define _SERVER_ACL_INCLUDED_
+
+/*++
+/* NAME
+/*     dict_memcache 3h
+/* SUMMARY
+/*     dictionary interface to memcache databases
+/* SYNOPSIS
+/*     #include <dict_memcache.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <argv.h>
+
+ /*
+  * External interface.
+  */
+typedef ARGV SERVER_ACL;
+extern void server_acl_pre_jail_init(const char *, const char *);
+extern SERVER_ACL *server_acl_parse(const char *, const char *);
+extern int server_acl_eval(const char *, SERVER_ACL *, const char *);
+
+#define SERVER_ACL_NAME_WL_MYNETWORKS "permit_mynetworks"
+#define SERVER_ACL_NAME_PERMIT "permit"
+#define SERVER_ACL_NAME_DUNNO  "dunno"
+#define SERVER_ACL_NAME_REJECT "reject"
+#define SERVER_ACL_NAME_ERROR  "error"
+
+#define SERVER_ACL_ACT_PERMIT  1
+#define SERVER_ACL_ACT_DUNNO   0
+#define SERVER_ACL_ACT_REJECT  (-1)
+#define SERVER_ACL_ACT_ERROR   (-2)
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
index abb6e3bb02680bbd27aed4849dce2fe5ec852bfe..c4e6d86a6372b4d10b2a4c1e4e535f491538a107 100644 (file)
@@ -415,6 +415,7 @@ postconf_builtin.o: ../../include/mail_version.h
 postconf_builtin.o: ../../include/msg.h
 postconf_builtin.o: ../../include/mymalloc.h
 postconf_builtin.o: ../../include/mynetworks.h
+postconf_builtin.o: ../../include/server_acl.h
 postconf_builtin.o: ../../include/stringops.h
 postconf_builtin.o: ../../include/sys_defs.h
 postconf_builtin.o: ../../include/vbuf.h
index b915ad84a57db88df97c2a8968312d425b9fef21..8833dc80b6f57d034be3805e64ded51eca5ddc95 100644 (file)
@@ -50,6 +50,7 @@
 #include <mail_proto.h>
 #include <mail_addr.h>
 #include <inet_proto.h>
+#include <server_acl.h>
 
 /* Application-specific. */
 
index 0eead33d391ff11b60788d3d544aebc02d8ab668..bf6a735b72ea76cd0ec1a8beaf6bb3ab716a912f 100644 (file)
@@ -2,16 +2,16 @@ SHELL = /bin/sh
 SRCS   = postscreen.c postscreen_dict.c postscreen_dnsbl.c \
        postscreen_early.c postscreen_smtpd.c postscreen_misc.c \
        postscreen_state.c postscreen_tests.c postscreen_send.c \
-       postscreen_starttls.c postscreen_expand.c postscreen_access.c
+       postscreen_starttls.c postscreen_expand.c
 OBJS   = postscreen.o postscreen_dict.o postscreen_dnsbl.o \
        postscreen_early.o postscreen_smtpd.o postscreen_misc.o \
        postscreen_state.o postscreen_tests.o postscreen_send.o \
-       postscreen_starttls.o postscreen_expand.o postscreen_access.o
+       postscreen_starttls.o postscreen_expand.o
 HDRS   = 
 TESTSRC        =
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= postscreen_access
+TESTPROG=
 PROG   = postscreen
 INC_DIR = ../../include
 LIBS   = ../../lib/libmaster.a ../../lib/libtls.a ../../lib/libglobal.a \
@@ -38,11 +38,6 @@ update: ../../libexec/$(PROG)
 ../../libexec/$(PROG): $(PROG)
        cp $(PROG) ../../libexec
 
-postscreen_access: $(PROG) $(LIBS)
-       mv $@.o junk
-       $(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIBS) $(SYSLIBS)
-       mv junk $@.o
-
 printfck: $(OBJS) $(PROG)
        rm -rf printfck
        mkdir printfck
@@ -90,6 +85,7 @@ postscreen.o: ../../include/msg.h
 postscreen.o: ../../include/myaddrinfo.h
 postscreen.o: ../../include/mymalloc.h
 postscreen.o: ../../include/name_code.h
+postscreen.o: ../../include/server_acl.h
 postscreen.o: ../../include/set_eugid.h
 postscreen.o: ../../include/string_list.h
 postscreen.o: ../../include/sys_defs.h
@@ -98,27 +94,6 @@ postscreen.o: ../../include/vstream.h
 postscreen.o: ../../include/vstring.h
 postscreen.o: postscreen.c
 postscreen.o: postscreen.h
-postscreen_access.o: ../../include/addr_match_list.h
-postscreen_access.o: ../../include/argv.h
-postscreen_access.o: ../../include/dict.h
-postscreen_access.o: ../../include/dict_cache.h
-postscreen_access.o: ../../include/events.h
-postscreen_access.o: ../../include/htable.h
-postscreen_access.o: ../../include/mail_params.h
-postscreen_access.o: ../../include/maps.h
-postscreen_access.o: ../../include/match_list.h
-postscreen_access.o: ../../include/match_ops.h
-postscreen_access.o: ../../include/match_parent_style.h
-postscreen_access.o: ../../include/msg.h
-postscreen_access.o: ../../include/mymalloc.h
-postscreen_access.o: ../../include/string_list.h
-postscreen_access.o: ../../include/stringops.h
-postscreen_access.o: ../../include/sys_defs.h
-postscreen_access.o: ../../include/vbuf.h
-postscreen_access.o: ../../include/vstream.h
-postscreen_access.o: ../../include/vstring.h
-postscreen_access.o: postscreen.h
-postscreen_access.o: postscreen_access.c
 postscreen_dict.o: ../../include/addr_match_list.h
 postscreen_dict.o: ../../include/argv.h
 postscreen_dict.o: ../../include/dict.h
@@ -129,6 +104,7 @@ postscreen_dict.o: ../../include/maps.h
 postscreen_dict.o: ../../include/match_list.h
 postscreen_dict.o: ../../include/match_ops.h
 postscreen_dict.o: ../../include/msg.h
+postscreen_dict.o: ../../include/server_acl.h
 postscreen_dict.o: ../../include/string_list.h
 postscreen_dict.o: ../../include/sys_defs.h
 postscreen_dict.o: ../../include/vbuf.h
@@ -154,6 +130,7 @@ postscreen_dnsbl.o: ../../include/match_ops.h
 postscreen_dnsbl.o: ../../include/msg.h
 postscreen_dnsbl.o: ../../include/myaddrinfo.h
 postscreen_dnsbl.o: ../../include/mymalloc.h
+postscreen_dnsbl.o: ../../include/server_acl.h
 postscreen_dnsbl.o: ../../include/split_at.h
 postscreen_dnsbl.o: ../../include/string_list.h
 postscreen_dnsbl.o: ../../include/stringops.h
@@ -176,6 +153,7 @@ postscreen_early.o: ../../include/match_list.h
 postscreen_early.o: ../../include/match_ops.h
 postscreen_early.o: ../../include/msg.h
 postscreen_early.o: ../../include/mymalloc.h
+postscreen_early.o: ../../include/server_acl.h
 postscreen_early.o: ../../include/string_list.h
 postscreen_early.o: ../../include/stringops.h
 postscreen_early.o: ../../include/sys_defs.h
@@ -198,6 +176,7 @@ postscreen_expand.o: ../../include/maps.h
 postscreen_expand.o: ../../include/match_list.h
 postscreen_expand.o: ../../include/match_ops.h
 postscreen_expand.o: ../../include/msg.h
+postscreen_expand.o: ../../include/server_acl.h
 postscreen_expand.o: ../../include/string_list.h
 postscreen_expand.o: ../../include/stringops.h
 postscreen_expand.o: ../../include/sys_defs.h
@@ -219,6 +198,7 @@ postscreen_misc.o: ../../include/maps.h
 postscreen_misc.o: ../../include/match_list.h
 postscreen_misc.o: ../../include/match_ops.h
 postscreen_misc.o: ../../include/msg.h
+postscreen_misc.o: ../../include/server_acl.h
 postscreen_misc.o: ../../include/string_list.h
 postscreen_misc.o: ../../include/sys_defs.h
 postscreen_misc.o: ../../include/vbuf.h
@@ -241,6 +221,7 @@ postscreen_send.o: ../../include/maps.h
 postscreen_send.o: ../../include/match_list.h
 postscreen_send.o: ../../include/match_ops.h
 postscreen_send.o: ../../include/msg.h
+postscreen_send.o: ../../include/server_acl.h
 postscreen_send.o: ../../include/smtp_reply_footer.h
 postscreen_send.o: ../../include/string_list.h
 postscreen_send.o: ../../include/sys_defs.h
@@ -269,6 +250,7 @@ postscreen_smtpd.o: ../../include/msg.h
 postscreen_smtpd.o: ../../include/mymalloc.h
 postscreen_smtpd.o: ../../include/name_code.h
 postscreen_smtpd.o: ../../include/name_mask.h
+postscreen_smtpd.o: ../../include/server_acl.h
 postscreen_smtpd.o: ../../include/string_list.h
 postscreen_smtpd.o: ../../include/stringops.h
 postscreen_smtpd.o: ../../include/sys_defs.h
@@ -296,6 +278,7 @@ postscreen_starttls.o: ../../include/msg.h
 postscreen_starttls.o: ../../include/mymalloc.h
 postscreen_starttls.o: ../../include/name_code.h
 postscreen_starttls.o: ../../include/name_mask.h
+postscreen_starttls.o: ../../include/server_acl.h
 postscreen_starttls.o: ../../include/string_list.h
 postscreen_starttls.o: ../../include/stringops.h
 postscreen_starttls.o: ../../include/sys_defs.h
@@ -322,6 +305,7 @@ postscreen_state.o: ../../include/match_ops.h
 postscreen_state.o: ../../include/msg.h
 postscreen_state.o: ../../include/mymalloc.h
 postscreen_state.o: ../../include/name_mask.h
+postscreen_state.o: ../../include/server_acl.h
 postscreen_state.o: ../../include/string_list.h
 postscreen_state.o: ../../include/sys_defs.h
 postscreen_state.o: ../../include/vbuf.h
@@ -340,6 +324,7 @@ postscreen_tests.o: ../../include/maps.h
 postscreen_tests.o: ../../include/match_list.h
 postscreen_tests.o: ../../include/match_ops.h
 postscreen_tests.o: ../../include/msg.h
+postscreen_tests.o: ../../include/server_acl.h
 postscreen_tests.o: ../../include/string_list.h
 postscreen_tests.o: ../../include/sys_defs.h
 postscreen_tests.o: ../../include/vbuf.h
index 3b79900b8ceaad7e266a534fa2f686d95bb739cd..6f2ae065e74de3161b35c123e7ab5017b6b35e5b 100644 (file)
 /*     This program should not be used on SMTP ports that receive
 /*     mail from end-user clients (MUAs). In a typical deployment,
 /*     \fBpostscreen\fR(8) is used on the "port 25" service, while
-/*     MUA clients submit mail via the \fBsubmission\fR service.
+/*     MUA clients submit mail via the \fBsubmission\fR service,
+/*     or via a "port 25" server that provides no MX service (i.e.
+/*     a dedicated server that provides \fBsubmission\fR service
+/*     on port 25).
 /*
 /*     \fBpostscreen\fR(8) maintains a temporary whitelist for
 /*     clients that have passed a number of tests.  When an SMTP
@@ -846,7 +849,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
      * Open read-only maps before dropping privilege, for consistency with
      * other Postfix daemons.
      */
-    psc_acl_pre_jail_init();
+    psc_acl_pre_jail_init(var_mynetworks, VAR_PSC_ACL);
     if (*var_psc_acl)
        psc_acl = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
     if (*var_psc_forbid_cmds)
index dda8f354423909859e916420dee016a43f6ec226..87cc2c13022e4525273ec39872c3a31103f3ea1a 100644 (file)
@@ -27,6 +27,7 @@
 #include <addr_match_list.h>
 #include <string_list.h>
 #include <maps.h>
+#include <server_acl.h>
 
  /*
   * Preliminary stuff, to be fixed.
@@ -468,16 +469,16 @@ extern void psc_expand_init(void);
 extern const char *psc_expand_lookup(const char *, int, char *);
 
  /*
-  * postscreen_access.c
+  * postscreen_access emulation.
   */
-#define PSC_ACL_ACT_WHITELIST  1
-#define PSC_ACL_ACT_DUNNO      0
-#define PSC_ACL_ACT_BLACKLIST  (-1)
-#define PSC_ACL_ACT_ERROR      (-2)
-
-extern void psc_acl_pre_jail_init(void);
-extern ARGV *psc_acl_parse(const char *, const char *);
-extern int psc_acl_eval(PSC_STATE *, ARGV *, const char *);
+#define PSC_ACL_ACT_WHITELIST  SERVER_ACL_ACT_PERMIT
+#define PSC_ACL_ACT_DUNNO      SERVER_ACL_ACT_DUNNO
+#define PSC_ACL_ACT_BLACKLIST  SERVER_ACL_ACT_REJECT
+#define PSC_ACL_ACT_ERROR      SERVER_ACL_ACT_ERROR
+
+#define psc_acl_pre_jail_init  server_acl_pre_jail_init
+#define psc_acl_parse          server_acl_parse
+#define psc_acl_eval(s,a,p)    server_acl_eval((s)->smtp_client_addr, (a), (p))
 
 /* LICENSE
 /* .ad
diff --git a/postfix/src/postscreen/postscreen_access.c b/postfix/src/postscreen/postscreen_access.c
deleted file mode 100644 (file)
index ba386a5..0000000
+++ /dev/null
@@ -1,254 +0,0 @@
-/*++
-/* NAME
-/*     postscreen_access 3
-/* SUMMARY
-/*     postscreen access list support
-/* SYNOPSIS
-/*     #include <postscreen.h>
-/*
-/*     void    psc_acl_pre_jail_init()
-/*
-/*     ARGV    *psc_acl_parse(raw_acl, origin)
-/*     const char *raw_acl;
-/*     const char *origin;
-/*
-/*     int     psc_acl_eval(state, cooked_acl, origin)
-/*     PSC_STATE *state;
-/*     ARGV    *cooked_acl;
-/*     const char *origin;
-/* DESCRIPTION
-/*     This module implements the permanent black/whitelist that
-/*     is evaluated immediately after a client connects to postscreen.
-/*
-/*     psc_acl_pre_jail_init() does before-chroot initialization.
-/*
-/*     psc_acl_parse() converts an access list from raw string
-/*     form to binary form.
-/*
-/*     psc_acl_eval() evaluates an access list for the specified
-/*     SMTP session.
-/*
-/*     Arguments:
-/* .IP raw_acl
-/*     String with space/comma separated commands.
-/* .IP cooked_acl
-/*     The parsed access list.
-/* .IP origin
-/*     This should be "postscreen_access_list" for an access list
-/*     from main.cf, and the type:name of a lookup table otherwise.
-/*     The information is used for error reporting (nested table,
-/*     unknown keyword).
-/* .IP state
-/*     Connection state.
-/* LICENSE
-/* .ad
-/* .fi
-/*     The Secure Mailer license must be distributed with this software.
-/* AUTHOR(S)
-/*     Wietse Venema
-/*     IBM T.J. Watson Research
-/*     P.O. Box 704
-/*     Yorktown Heights, NY 10598, USA
-/*--*/
-
-/* System library. */
-
-#include <sys_defs.h>
-#include <string.h>
-
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
-/* Utility library. */
-
-#include <msg.h>
-#include <mymalloc.h>
-#include <stringops.h>
-
-/* Global library. */
-
-#include <mail_params.h>
-#include <addr_match_list.h>
-#include <match_parent_style.h>
-
-/* Application-specific. */
-
-#include <postscreen.h>
-
-#define PSC_ACL_SEPARATORS     ", \t\r"
-
-static ADDR_MATCH_LIST *psc_mynetworks;
-
-/* psc_acl_pre_jail_init - initialize */
-
-void    psc_acl_pre_jail_init(void)
-{
-    if (psc_mynetworks)
-       addr_match_list_free(psc_mynetworks);
-    psc_mynetworks = addr_match_list_init(match_parent_style(VAR_MYNETWORKS),
-                                         var_mynetworks);
-}
-
-/* psc_acl_parse - parse access list */
-
-ARGV   *psc_acl_parse(const char *acl, const char *origin)
-{
-    char   *saved_checks = mystrdup(acl);
-    ARGV   *argv = argv_alloc(1);
-    char   *bp = saved_checks;
-    char   *name;
-
-#define STREQ(x,y) ((*x) == (*y) && strcasecmp((x), (y)) == 0)
-#define STRNE(x,y) ((*x) != (*y) || strcasecmp((x), (y)) != 0)
-
-    /*
-     * Nested tables are not allowed. Tables are opened before entering the
-     * chroot jail, while access lists are evaluated after entering the
-     * chroot jail.
-     */
-    while ((name = mystrtok(&bp, PSC_ACL_SEPARATORS)) != 0) {
-       if (strchr(name, ':') != 0) {
-           if (STRNE(origin, VAR_PSC_ACL)) {
-               msg_warn("table %s: lookup result \"%s\" is not allowed"
-                        " -- ignoring remainder of access list",
-                        origin, name);
-               argv_add(argv, PSC_ACL_NAME_DUNNO, (char *) 0);
-               break;
-           } else {
-               if (dict_handle(name) == 0)
-                   dict_register(name, dict_open(name, O_RDONLY, DICT_FLAG_LOCK
-                                                 | DICT_FLAG_FOLD_FIX));
-           }
-       }
-       argv_add(argv, name, (char *) 0);
-    }
-    argv_terminate(argv);
-
-    /*
-     * Cleanup.
-     */
-    myfree(saved_checks);
-    return (argv);
-}
-
-/* psc_acl_eval - evaluate access list */
-
-int     psc_acl_eval(PSC_STATE *state, ARGV *acl, const char *origin)
-{
-    const char *myname = "psc_acl_eval";
-    char  **cpp;
-    DICT   *dict;
-    ARGV   *argv;
-    const char *name;
-    const char *dict_val;
-    int     ret;
-
-    for (cpp = acl->argv; (name = *cpp) != 0; cpp++) {
-       if (msg_verbose)
-           msg_info("source=%s address=%s acl=%s",
-                    origin, state->smtp_client_addr, name);
-       if (STREQ(name, PSC_ACL_NAME_BLACKLIST)) {
-           return (PSC_ACL_ACT_BLACKLIST);
-       } else if (STREQ(name, PSC_ACL_NAME_WHITELIST)) {
-           return (PSC_ACL_ACT_WHITELIST);
-       } else if (STREQ(name, PSC_ACL_NAME_WL_MYNETWORKS)) {
-           if (addr_match_list_match(psc_mynetworks, state->smtp_client_addr))
-               return (PSC_ACL_ACT_WHITELIST);
-       } else if (strchr(name, ':') != 0) {
-           if ((dict = dict_handle(name)) == 0)
-               msg_panic("%s: unexpected dictionary: %s", myname, name);
-           if ((dict_val = dict_get(dict, state->smtp_client_addr)) != 0) {
-               argv = psc_acl_parse(dict_val, name);
-               ret = psc_acl_eval(state, argv, name);
-               argv_free(argv);
-               if (ret != PSC_ACL_ACT_DUNNO)
-                   return (ret);
-           } else if (dict_errno != 0) {
-               msg_warn("%s: table lookup error -- ignoring the remainder "
-                        "of this access list", name);
-               return (PSC_ACL_ACT_ERROR);
-           }
-       } else if (STREQ(name, PSC_ACL_NAME_DUNNO)) {
-           return (PSC_ACL_ACT_DUNNO);
-       } else {
-           msg_warn("%s: unknown command: %s -- ignoring the remainder "
-                    "of this access list", origin, name);
-           return (PSC_ACL_ACT_ERROR);
-       }
-    }
-    if (msg_verbose)
-       msg_info("source=%s address=%s - no match",
-                origin, state->smtp_client_addr);
-    return (PSC_ACL_ACT_DUNNO);
-}
-
- /*
-  * Access lists need testing. Not only with good inputs; error cases must
-  * also be handled appropriately.
-  */
-#ifdef TEST
-#include <unistd.h>
-#include <stdlib.h>
-#include <vstring_vstream.h>
-#include <name_code.h>
-#include <split_at.h>
-
-char   *var_par_dom_match = DEF_PAR_DOM_MATCH;
-char   *var_mynetworks = "";
-char   *var_psc_acl = "";
-
-#define UPDATE_VAR(s,v) do { if (*(s)) myfree(s); (s) = mystrdup(v); } while (0)
-
-int     main(void)
-{
-    VSTRING *buf = vstring_alloc(100);
-    PSC_STATE state;
-    ARGV   *argv;
-    int     ret;
-    int     have_tty = isatty(0);
-    char   *bufp;
-    char   *cmd;
-    char   *value;
-    const NAME_CODE acl_map[] = {
-       PSC_ACL_NAME_ERROR, PSC_ACL_ACT_ERROR,
-       PSC_ACL_NAME_WHITELIST, PSC_ACL_ACT_WHITELIST,
-       PSC_ACL_NAME_BLACKLIST, PSC_ACL_ACT_BLACKLIST,
-       PSC_ACL_NAME_DUNNO, PSC_ACL_ACT_DUNNO,
-       0,
-    };
-
-    while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
-       bufp = STR(buf);
-       if (have_tty == 0) {
-           vstream_printf("> %s\n", bufp);
-           vstream_fflush(VSTREAM_OUT);
-       }
-       if (*bufp == '#')
-           continue;
-       if ((cmd = mystrtok(&bufp, " =")) == 0 || STREQ(cmd, "?")) {
-           vstream_printf("usage: %s=value|%s=value|address=value\n",
-                          VAR_MYNETWORKS, VAR_PSC_ACL);
-       } else if ((value = mystrtok(&bufp, " =")) == 0) {
-           vstream_printf("missing value\n");
-       } else if (STREQ(cmd, VAR_MYNETWORKS)) {
-           UPDATE_VAR(var_mynetworks, value);
-       } else if (STREQ(cmd, VAR_PSC_ACL)) {
-           UPDATE_VAR(var_psc_acl, value);
-       } else if (STREQ(cmd, "address")) {
-           psc_acl_pre_jail_init();
-           argv = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
-           state.smtp_client_addr = value;
-           ret = psc_acl_eval(&state, argv, VAR_PSC_ACL);
-           argv_free(argv);
-           vstream_printf("%s: %s\n", value, str_name_code(acl_map, ret));
-       } else {
-           vstream_printf("unknown command: \"%s\"\n", cmd);
-       }
-       vstream_fflush(VSTREAM_OUT);
-    }
-    vstring_free(buf);
-    exit(0);
-}
-
-#endif
index 9caea93508b7682dba57497dfc0ce37b737dfefe..73741096e09590d06692cb88eb399508b93fa6c1 100644 (file)
@@ -255,6 +255,8 @@ char   *var_send_canon_maps;
 char   *var_rcpt_canon_maps;
 char   *var_relocated_maps;
 char   *var_transport_maps;
+char   *var_verify_map;
+char   *var_psc_cache_map;
 char   *var_proxy_read_maps;
 char   *var_proxy_write_maps;
 
@@ -326,7 +328,9 @@ static DICT *proxy_map_find(const char *map_type_name, int request_flags,
      * of open() flags should be received directly from the client.
      */
     vstring_sprintf(map_type_name_flags, "%s:%s", map_type_name,
-                   dict_flags_str(request_flags & DICT_FLAG_NP_INST_MASK));
+                   dict_flags_str(request_flags & DICT_FLAG_INST_MASK));
+    if (msg_verbose)
+       msg_info("proxy_map_find: %s", STR(map_type_name_flags));
     if ((dict = dict_handle(STR(map_type_name_flags))) == 0)
        dict = dict_open(map_type_name, proxy_writer ?
                         WRITE_OPEN_FLAGS : READ_OPEN_FLAGS,
@@ -570,11 +574,22 @@ static void proxymap_service(VSTREAM *client_stream, char *unused_service,
     if (argv[0])
        msg_fatal("unexpected command-line argument: %s", argv[0]);
 
+    /*
+     * Deadline enforcement.
+     */
+    if (vstream_fstat(client_stream, VSTREAM_FLAG_DEADLINE) == 0)
+       vstream_control(client_stream,
+                       VSTREAM_CTL_TIMEOUT, 1,
+                       VSTREAM_CTL_END);
+
     /*
      * This routine runs whenever a client connects to the socket dedicated
      * to the proxymap service. All connection-management stuff is handled by
      * the common code in multi_server.c.
      */
+    vstream_control(client_stream,
+                   VSTREAM_CTL_START_DEADLINE,
+                   VSTREAM_CTL_END);
     if (attr_scan(client_stream,
                  ATTR_FLAG_MORE | ATTR_FLAG_STRICT,
                  ATTR_TYPE_STR, MAIL_ATTR_REQ, request,
@@ -596,6 +611,9 @@ static void proxymap_service(VSTREAM *client_stream, char *unused_service,
                       ATTR_TYPE_END);
        }
     }
+    vstream_control(client_stream,
+                   VSTREAM_CTL_START_DEADLINE,
+                   VSTREAM_CTL_END);
     vstream_fflush(client_stream);
 }
 
@@ -698,6 +716,8 @@ int     main(int argc, char **argv)
        VAR_TRANSPORT_MAPS, DEF_TRANSPORT_MAPS, &var_transport_maps, 0, 0,
        VAR_PROXY_READ_MAPS, DEF_PROXY_READ_MAPS, &var_proxy_read_maps, 0, 0,
        VAR_PROXY_WRITE_MAPS, DEF_PROXY_WRITE_MAPS, &var_proxy_write_maps, 0, 0,
+       VAR_VERIFY_MAP, DEF_VERIFY_MAP, &var_verify_map, 0, 0,
+       VAR_PSC_CACHE_MAP, DEF_PSC_CACHE_MAP, &var_psc_cache_map, 0, 0,
        0,
     };
 
index 8e170e62f9fbf7cbd961ba921144ddf86ee5eadf..30a51b9f22cde663fc683caa69ffaa53bbd5e422 100644 (file)
@@ -544,21 +544,23 @@ int     dict_changed(void)
   * Mapping between flag names and flag values.
   */
 static const NAME_MASK dict_mask[] = {
-    "warn_dup", (1 << 0),              /* if file, warn about dups */
-    "ignore_dup", (1 << 1),            /* if file, ignore dups */
-    "try0null", (1 << 2),              /* do not append 0 to key/value */
-    "try1null", (1 << 3),              /* append 0 to key/value */
-    "fixed", (1 << 4),                 /* fixed key map */
-    "pattern", (1 << 5),               /* keys are patterns */
-    "lock", (1 << 6),                  /* lock before access */
-    "replace", (1 << 7),               /* if file, replace dups */
-    "sync_update", (1 << 8),           /* if file, sync updates */
-    "debug", (1 << 9),                 /* log access */
-    "no_regsub", (1 << 11),            /* disallow regexp substitution */
-    "no_proxy", (1 << 12),             /* disallow proxy mapping */
-    "no_unauth", (1 << 13),            /* disallow unauthenticated data */
-    "fold_fix", (1 << 14),             /* case-fold with fixed-case key map */
-    "fold_mul", (1 << 15),             /* case-fold with multi-case key map */
+    "warn_dup", DICT_FLAG_DUP_WARN,    /* if file, warn about dups */
+    "ignore_dup", DICT_FLAG_DUP_IGNORE,        /* if file, ignore dups */
+    "try0null", DICT_FLAG_TRY0NULL,    /* do not append 0 to key/value */
+    "try1null", DICT_FLAG_TRY1NULL,    /* append 0 to key/value */
+    "fixed", DICT_FLAG_FIXED,          /* fixed key map */
+    "pattern", DICT_FLAG_PATTERN,      /* keys are patterns */
+    "lock", DICT_FLAG_LOCK,            /* lock before access */
+    "replace", DICT_FLAG_DUP_REPLACE,  /* if file, replace dups */
+    "sync_update", DICT_FLAG_SYNC_UPDATE,      /* if file, sync updates */
+    "debug", DICT_FLAG_DEBUG,          /* log access */
+    "no_regsub", DICT_FLAG_NO_REGSUB,  /* disallow regexp substitution */
+    "no_proxy", DICT_FLAG_NO_PROXY,    /* disallow proxy mapping */
+    "no_unauth", DICT_FLAG_NO_UNAUTH,  /* disallow unauthenticated data */
+    "fold_fix", DICT_FLAG_FOLD_FIX,    /* case-fold with fixed-case key map */
+    "fold_mul", DICT_FLAG_FOLD_MUL,    /* case-fold with multi-case key map */
+    "open_lock", DICT_FLAG_OPEN_LOCK,  /* permanent lock upon open */
+    0,
 };
 
 /* dict_flags_str - convert mask to string for debugging purposes */
@@ -571,5 +573,5 @@ const char *dict_flags_str(int dict_flags)
        buf = vstring_alloc(1);
 
     return (str_name_mask_opt(buf, "dictionary flags", dict_mask, dict_flags,
-                             NAME_MASK_RETURN | NAME_MASK_PIPE));
+                             NAME_MASK_NUMBER | NAME_MASK_PIPE));
 }
index 36d49c89fc48c0e8b2994bfa28cb4486ef8a587b..ed08a9a3c650672d8cd54d95e81e2abbddeb5a66 100644 (file)
@@ -88,32 +88,30 @@ extern DICT *dict_debug(DICT *);
   * The subsets of flags that control how a map is used. These are relevant
   * mainly for proxymap support. Note: some categories overlap.
   * 
-  * DICT_FLAG_PARANOID - flags that forbid the use of insecure map types for
-  * security-sensitive operations. These flags are specified by the caller,
-  * and are checked by the map implementation itself upon open, lookup etc.
-  * requests.
+  * DICT_FLAG_IMPL_MASK - flags that are set by the map implementation itself.
   * 
-  * DICT_FLAG_IMPL_MASK - flags that specify properties of the lookup table
-  * implementation. These flags are set by the map implementation itself.
+  * DICT_FLAG_PARANOID - requestor flags that forbid the use of insecure map
+  * types for security-sensitive operations. These flags are checked by the
+  * map implementation itself upon open, lookup etc. requests.
   * 
-  * DICT_FLAG_INST_MASK - flags that control how a specific table instance is
-  * opened or used. The caller specifies these flags, and the caller may not
-  * change them between open, lookup, etc. requests (although the map itself
-  * may make changes to some of these flags).
+  * DICT_FLAG_RQST_MASK - all requestor flags, including paranoid flags, that
+  * the requestor may change between open, lookup etc. requests.
   * 
-  * DICT_FLAG_NP_INST_MASK - ditto, but without the paranoia flags.
-  * 
-  * DICT_FLAG_RQST_MASK - flags that the caller specifies, and that the caller
-  * may change between open, lookup etc. requests.
+  * DICT_FLAG_INST_MASK - none of the above flags. The requestor may not change
+  * these flags between open, lookup, etc. requests (although a map may make
+  * changes to its copy of some of these flags). The proxymap server opens
+  * only one map instance for all client requests with the same values of
+  * these flags, and the proxymap client uses its own saved copy of these
+  * flags.
   */
 #define DICT_FLAG_PARANOID \
        (DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH)
 #define DICT_FLAG_IMPL_MASK    (DICT_FLAG_FIXED | DICT_FLAG_PATTERN)
 #define DICT_FLAG_RQST_MASK    (DICT_FLAG_FOLD_ANY | DICT_FLAG_LOCK | \
                                DICT_FLAG_DUP_REPLACE | DICT_FLAG_DUP_WARN | \
-                               DICT_FLAG_SYNC_UPDATE)
-#define DICT_FLAG_NP_INST_MASK ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK)
-#define DICT_FLAG_INST_MASK    (DICT_FLAG_NP_INST_MASK | DICT_FLAG_PARANOID)
+                               DICT_FLAG_DUP_IGNORE | DICT_FLAG_SYNC_UPDATE | \
+                               DICT_FLAG_PARANOID)
+#define DICT_FLAG_INST_MASK    ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK)
 
 extern int dict_unknown_allowed;
 extern int dict_errno;
index e079dcbc08d5199a4b4b018f24ad42408c8195c8..a4ab0615147c38acd1c45c35f77ee5de4ef0f1b4 100644 (file)
   * underlying database.
   */
 struct DICT_CACHE {
+    char   *name;                      /* full name including proxy: */
     int     cache_flags;               /* see below */
     int     user_flags;                        /* logging */
     DICT   *db;                                /* database handle */
@@ -366,7 +367,7 @@ int     dict_cache_sequence(DICT_CACHE *cp, int first_next,
                     myname, previous_curr_key, previous_curr_val);
        if (dict_del(cp->db, previous_curr_key) != 0)
            msg_warn("database %s: could not delete entry for %s",
-                    cp->db->name, previous_curr_key);
+                    cp->name, previous_curr_key);
     }
 
     /*
@@ -403,7 +404,7 @@ static void dict_cache_clean_stat_log_reset(DICT_CACHE *cp,
 {
     if (cp->user_flags & DICT_CACHE_FLAG_STATISTICS)
        msg_info("cache %s %s cleanup: retained=%d dropped=%d entries",
-                cp->db->name, full_partial, cp->retained, cp->dropped);
+                cp->name, full_partial, cp->retained, cp->dropped);
     cp->retained = cp->dropped = 0;
 }
 
@@ -432,7 +433,7 @@ static void dict_cache_clean_event(int unused_event, char *cache_context)
        cp->retained = cp->dropped = 0;
        first_next = DICT_SEQ_FUN_FIRST;
        if (cp->user_flags & DICT_CACHE_FLAG_VERBOSE)
-           msg_info("%s: start %s cache cleanup", myname, cp->db->name);
+           msg_info("%s: start %s cache cleanup", myname, cp->name);
     }
 
     /*
@@ -451,12 +452,12 @@ static void dict_cache_clean_event(int unused_event, char *cache_context)
            cp->dropped++;
            if (cp->user_flags & DICT_CACHE_FLAG_VERBOSE)
                msg_info("%s: drop %s cache entry for %s",
-                        myname, cp->db->name, cache_key);
+                        myname, cp->name, cache_key);
        } else {
            cp->retained++;
            if (cp->user_flags & DICT_CACHE_FLAG_VERBOSE)
                msg_info("%s: keep %s cache entry for %s",
-                        myname, cp->db->name, cache_key);
+                        myname, cp->name, cache_key);
        }
        next_interval = 0;
     }
@@ -466,7 +467,7 @@ static void dict_cache_clean_event(int unused_event, char *cache_context)
      */
     else {
        if (cp->user_flags & DICT_CACHE_FLAG_VERBOSE)
-           msg_info("%s: done %s cache cleanup scan", myname, cp->db->name);
+           msg_info("%s: done %s cache cleanup scan", myname, cp->name);
        dict_cache_clean_stat_log_reset(cp, "full");
        stamp_buf = vstring_alloc(100);
        vstring_sprintf(stamp_buf, "%ld", (long) event_time());
@@ -504,7 +505,7 @@ void    dict_cache_control(DICT_CACHE *cp,...)
            cp->exp_interval = va_arg(ap, int);
            if (cp->exp_interval < 0)
                msg_panic("%s: bad %s cache cleanup interval %d",
-                         myname, cp->db->name, cp->exp_interval);
+                         myname, cp->name, cp->exp_interval);
            break;
        case DICT_CACHE_CTL_VALIDATOR:
            cp->exp_validator = va_arg(ap, DICT_CACHE_VALIDATOR_FN);
@@ -528,7 +529,7 @@ void    dict_cache_control(DICT_CACHE *cp,...)
         */
        if (cache_cleanup_is_active)
            msg_panic("%s: %s cache cleanup is already scheduled",
-                     myname, cp->db->name);
+                     myname, cp->name);
 
        /*
         * The next start time depends on the last completion time.
@@ -543,7 +544,7 @@ void    dict_cache_control(DICT_CACHE *cp,...)
            next_interval = cp->exp_interval;
        if ((cp->user_flags & DICT_CACHE_FLAG_VERBOSE) && next_interval > 0)
            msg_info("%s cache cleanup will start after %ds",
-                    cp->db->name, (int) next_interval);
+                    cp->name, (int) next_interval);
        event_request_timer(dict_cache_clean_event, (char *) cp,
                            (int) next_interval);
     }
@@ -576,6 +577,7 @@ DICT_CACHE *dict_cache_open(const char *dbname, int open_flags, int dict_flags)
      * Create the DICT_CACHE object.
      */
     cp = (DICT_CACHE *) mymalloc(sizeof(*cp));
+    cp->name = mystrdup(dbname);
     cp->cache_flags = 0;
     cp->user_flags = 0;
     cp->db = dict;
@@ -598,6 +600,7 @@ void    dict_cache_close(DICT_CACHE *cp)
     /*
      * Destroy the DICT_CACHE object.
      */
+    myfree(cp->name);
     dict_cache_control(cp, DICT_CACHE_CTL_INTERVAL, 0, DICT_CACHE_CTL_END);
     dict_close(cp->db);
     if (cp->saved_curr_key)
@@ -618,5 +621,5 @@ const char *dict_cache_name(DICT_CACHE *cp)
      * execute still presents overhead for the processor pipeline, processor
      * cache, etc).
      */
-    return (cp->db->name);
+    return (cp->name);
 }
index afd41b790839162874cb658164ac8acc5082120a..eb8d2cb59814901fd0c363601b3c8132226e0890 100644 (file)
@@ -87,7 +87,7 @@ void    dict_test(int argc, char **argv)
        if (*bufp == '#')
            continue;
        if ((cmd = mystrtok(&bufp, " ")) == 0) {
-           vstream_printf("usage: verbose|del key|get key|put key=value|first|next\n");
+           vstream_printf("usage: verbose|del key|get key|put key=value|first|next|masks|flags\n");
            vstream_fflush(VSTREAM_OUT);
            continue;
        }
@@ -132,8 +132,20 @@ void    dict_test(int argc, char **argv)
                vstream_printf("%s\n",
                               dict_errno == DICT_ERR_RETRY ?
                               "soft error" : "not found");
+       } else if (strcmp(cmd, "flags") == 0 && !key && !value) {
+           vstream_printf("dict flags %s\n",
+                          dict_flags_str(dict->flags));
+       } else if (strcmp(cmd, "masks") == 0 && !key && !value) {
+           vstream_printf("DICT_FLAG_IMPL_MASK %s\n",
+                          dict_flags_str(DICT_FLAG_IMPL_MASK));
+           vstream_printf("DICT_FLAG_PARANOID %s\n",
+                          dict_flags_str(DICT_FLAG_PARANOID));
+           vstream_printf("DICT_FLAG_RQST_MASK %s\n",
+                          dict_flags_str(DICT_FLAG_RQST_MASK));
+           vstream_printf("DICT_FLAG_INST_MASK %s\n",
+                          dict_flags_str(DICT_FLAG_INST_MASK));
        } else {
-           vstream_printf("usage: del key|get key|put key=value|first|next\n");
+           vstream_printf("usage: del key|get key|put key=value|first|next|masks|flags\n");
        }
        vstream_fflush(VSTREAM_OUT);
     }