]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.4.0-RC6 v2.4.0-RC6
authorWietse Venema <wietse@porcupine.org>
Sat, 17 Mar 2007 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 10 Feb 2018 20:04:30 +0000 (15:04 -0500)
94 files changed:
postfix/HISTORY
postfix/README_FILES/ADDRESS_VERIFICATION_README
postfix/README_FILES/LDAP_README
postfix/README_FILES/SASL_README
postfix/html/ADDRESS_VERIFICATION_README.html
postfix/html/LDAP_README.html
postfix/html/SASL_README.html
postfix/html/ldap_table.5.html
postfix/man/man5/ldap_table.5
postfix/proto/ADDRESS_VERIFICATION_README.html
postfix/proto/LDAP_README.html
postfix/proto/ldap_table
postfix/src/anvil/Makefile.in
postfix/src/anvil/anvil.c
postfix/src/bounce/Makefile.in
postfix/src/bounce/bounce.c
postfix/src/cleanup/Makefile.in
postfix/src/cleanup/cleanup.c
postfix/src/discard/Makefile.in
postfix/src/discard/discard.c
postfix/src/error/Makefile.in
postfix/src/error/error.c
postfix/src/flush/Makefile.in
postfix/src/flush/flush.c
postfix/src/fsstone/fsstone.c
postfix/src/global/Makefile.in
postfix/src/global/dict_ldap.c
postfix/src/global/mail_version.h
postfix/src/local/Makefile.in
postfix/src/local/local.c
postfix/src/master/Makefile.in
postfix/src/master/master.c
postfix/src/master/multi_server.c
postfix/src/master/single_server.c
postfix/src/master/trigger_server.c
postfix/src/milter/Makefile.in
postfix/src/oqmgr/Makefile.in
postfix/src/oqmgr/qmgr.c
postfix/src/pickup/Makefile.in
postfix/src/pickup/pickup.c
postfix/src/pipe/Makefile.in
postfix/src/pipe/pipe.c
postfix/src/postalias/Makefile.in
postfix/src/postalias/postalias.c
postfix/src/postcat/Makefile.in
postfix/src/postcat/postcat.c
postfix/src/postconf/extract.awk
postfix/src/postconf/postconf.c
postfix/src/postdrop/Makefile.in
postfix/src/postdrop/postdrop.c
postfix/src/postfix/Makefile.in
postfix/src/postfix/postfix.c
postfix/src/postkick/Makefile.in
postfix/src/postkick/postkick.c
postfix/src/postlock/Makefile.in
postfix/src/postlock/postlock.c
postfix/src/postlog/Makefile.in
postfix/src/postlog/postlog.c
postfix/src/postmap/Makefile.in
postfix/src/postmap/postmap.c
postfix/src/postqueue/Makefile.in
postfix/src/postqueue/postqueue.c
postfix/src/postsuper/Makefile.in
postfix/src/postsuper/postsuper.c
postfix/src/proxymap/Makefile.in
postfix/src/proxymap/proxymap.c
postfix/src/qmgr/Makefile.in
postfix/src/qmgr/qmgr.c
postfix/src/qmqpd/Makefile.in
postfix/src/qmqpd/qmqpd.c
postfix/src/scache/Makefile.in
postfix/src/scache/scache.c
postfix/src/sendmail/Makefile.in
postfix/src/sendmail/sendmail.c
postfix/src/showq/Makefile.in
postfix/src/showq/showq.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/smtp.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpstone/Makefile.in
postfix/src/smtpstone/qmqp-sink.c
postfix/src/smtpstone/qmqp-source.c
postfix/src/smtpstone/smtp-sink.c
postfix/src/smtpstone/smtp-source.c
postfix/src/spawn/Makefile.in
postfix/src/spawn/spawn.c
postfix/src/tlsmgr/Makefile.in
postfix/src/tlsmgr/tlsmgr.c
postfix/src/trivial-rewrite/Makefile.in
postfix/src/trivial-rewrite/trivial-rewrite.c
postfix/src/verify/Makefile.in
postfix/src/verify/verify.c
postfix/src/virtual/Makefile.in
postfix/src/virtual/virtual.c

index 0ed26a40675ccec5c7e1d2fedb179a9b719e322c..bd0bb978be45d3987c626a84ba640090569ce6e9 100644 (file)
@@ -13339,6 +13339,33 @@ Apologies for any names omitted.
        compatibility with Postfix versions that pre-date Milter
        support. File: cleanup/cleanup_out.c.
 
+20070314
+
+       Bitrot: move the "don't run this daemon by hand" message
+       before other tests. Files: master/*server.c.
+
+20070315
+
+       Bitrot: New OpenLDAP APIs deprecate simplified interfaces,
+       that are the only ones available in Sun's LDAP SDK. Define
+       suitable macros that work with new OpenLDAP and Sun's code.
+       Victor Duchovni, Morgan Stanley. File: src/global/dict_ldap.c
+
+       Cleanup: new "leaf" and "terminal" result attributes support
+       fine-tuning of LDAP group expansion, and provide a solution
+       for the problem case where DN recursion returns both the
+       group address and the addresses of the member objects.
+       Victor Duchovni, Morgan Stanley.  Files: src/global/dict_ldap.c,
+       proto/LDAP_README.html, proto/ldap_table
+
+20070317
+
+       Idioten Sicherheit: stamp every executable file and every
+       core dump file with "mail_version=xxxxx". Adding version
+       stamps and checks to every IPC message is too much change
+       after code freeze, and requires too much time for testing.
+       File: src/global/mail_version.h and every main program file.
+
 Wish list:
 
        Update message content length when adding/removing headers.
index 5db4991d14f2c4df805512752d095e9582c81a61..70948cde949b75aeeda4299ecddf900c70cad1dd 100644 (file)
@@ -5,9 +5,9 @@ P\bPo\bos\bst\btf\bfi\bix\bx A\bAd\bdd\bdr\bre\bes\bss\bs V\bVe\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn
 W\bWA\bAR\bRN\bNI\bIN\bNG\bG
 
 The sender/recipient address verification feature described in this document is
-suitable only for low-traffic sites. It performs poorly under high load and may
-cause your site to be blacklisted by some providers. See the "Limitations"
-section below for details.
+suitable only for low-traffic sites. It performs poorly under high load;
+excessive sender address verification activity may even cause your site to be
+blacklisted by some providers. See the "Limitations" section below for details.
 
 W\bWh\bha\bat\bt P\bPo\bos\bst\btf\bfi\bix\bx a\bad\bdd\bdr\bre\bes\bss\bs v\bve\ber\bri\bif\bfi\bic\bca\bat\bti\bio\bon\bn c\bca\ban\bn d\bdo\bo f\bfo\bor\br y\byo\bou\bu
 
index 12f31d1105efd33be6cbded0ea670d27f69219e6..dead251133420bc0b0c54fe0f47e260713a89c28 100644 (file)
@@ -18,6 +18,7 @@ Topics covered in this document:
   * Configuring LDAP lookups
   * Example: aliases
   * Example: virtual domains/addresses
+  * Example: expanding LDAP groups
   * Other uses of LDAP lookups
   * Notes and things to think about
   * Feedback
@@ -96,12 +97,12 @@ in main.cf, you have:
 
 and in ldap:/etc/postfix/ldap-aliases.cf you have:
 
-    server_host = ldap.my.com
-    search_base = dc=my, dc=com
+    server_host = ldap.example.com
+    search_base = dc=example, dc=com
 
 Upon receiving mail for a local address "ldapuser" that isn't found in the /
 etc/aliases database, Postfix will search the LDAP server listening at port 389
-on ldap.my.com. It will bind anonymously, search for any directory entries
+on ldap.example.com. It will bind anonymously, search for any directory entries
 whose mailacceptinggeneralid attribute is "ldapuser", read the "maildrop"
 attributes of those found, and build a list of their maildrops, which will be
 treated as RFC822 addresses to which the message will be delivered.
@@ -116,7 +117,7 @@ want to make sure all of your virtual recipient's mailacceptinggeneralid
 attributes are fully qualified with their virtual domains. Finally, if you want
 to designate a directory entry as the default user for a virtual domain, just
 give it an additional mailacceptinggeneralid (or the equivalent in your
-directory) of "@virtual.dom". That's right, no user part. If you don't want a
+directory) of "@fake.dom". That's right, no user part. If you don't want a
 catchall user, omit this step and mail to unknown users in the domain will
 simply bounce.
 
@@ -143,12 +144,183 @@ this:
 Normal users might simply have one mailacceptinggeneralid and maildrop, e.g.
 "normaluser@fake.dom" and "normaluser@real.dom".
 
+E\bEx\bxa\bam\bmp\bpl\ble\be:\b: e\bex\bxp\bpa\ban\bnd\bdi\bin\bng\bg L\bLD\bDA\bAP\bP g\bgr\bro\bou\bup\bps\bs
+
+LDAP is frequently used to store group member information, and Postfix supports
+expanding a group's email address to the list of email addresses of the group
+members. There are a number of ways of handling LDAP groups, which will be
+illustrated via the mock LDAP entries and implied schema below. This shows two
+group entries "agroup" and "bgroup" and four user entries "auser", "buser",
+"cuser" and "duser". The group "agroup" has the users "auser" (1) and "buser"
+(2) as members via DN references in the multi-valued attribute "memberdn", and
+direct email addresses of two external users "auser@example.org" (3) and
+"buser@example.org" (4) stored in the multi-valued attribute "memberaddr". The
+same is true of "bgroup" and "cuser"/"duser" (6)/(7)/(8)/(9), but "bgroup" also
+has a "maildrop" attribute of "bgroup@mlm.example.com" (5):
+
+         dn: cn=agroup, dc=example, dc=com
+         objectclass: top
+         objectclass: ldapgroup
+         cn: agroup
+         mail: agroup@example.com
+    1 -> memberdn: uid=auser, dc=example, dc=com
+    2 -> memberdn: uid=buser, dc=example, dc=com
+    3 -> memberaddr: auser@example.org
+    4 -> memberaddr: buser@example.org
+
+         dn: cn=bgroup, dc=example, dc=com
+         objectclass: top
+         objectclass: ldapgroup
+         cn: bgroup
+         mail: bgroup@example.com
+    5 -> maildrop: bgroup@mlm.example.com
+    6 -> memberdn: uid=cuser, dc=example, dc=com
+    7 -> memberdn: uid=duser, dc=example, dc=com
+    8 -> memberaddr: cuser@example.org
+    9 -> memberaddr: duser@example.org
+
+         dn: uid=auser, dc=example, dc=com
+         objectclass: top
+         objectclass: ldapuser
+         uid: auser
+    10 -> mail: auser@example.com
+    11 -> maildrop: auser@mailhub.example.com
+
+         dn: uid=buser, dc=example, dc=com
+         objectclass: top
+         objectclass: ldapuser
+         uid: buser
+    12 -> mail: buser@example.com
+    13 -> maildrop: buser@mailhub.example.com
+
+         dn: uid=cuser, dc=example, dc=com
+         objectclass: top
+         objectclass: ldapuser
+         uid: cuser
+    14 -> mail: cuser@example.com
+
+         dn: uid=duser, dc=example, dc=com
+         objectclass: top
+         objectclass: ldapuser
+         uid: duser
+    15 -> mail: duser@example.com
+
+Our first use case ignores the "memberdn" attributes, and assumes that groups
+hold only direct "memberaddr" strings as in (3), (4), (8) and (9). The goal is
+to map the group address to the list of constituent "memberaddr" values. This
+is simple, ignoring the various connection related settings (hosts, ports, bind
+settings, timeouts, ...) we have:
+
+        simple.cf:
+            ...
+            search_base = dc=example, dc=com
+            query_filter = mail=%s
+            result_attribute = memberaddr
+        $ postmap -q agroup@example.com ldap:simple.cf
+        auser@example.org,buser@example.org
+
+We search "dc=example, dc=com". The "mail" attribute is used in the
+query_filter to locate the right group, the "result_attribute" setting
+described in ldap_table(5) is used to specify that "memberaddr" values from the
+matching group are to be returned as a comma separated list. Always check
+tables using postmap(1) with the "-q" option, before deploying them into
+production use in main.cf.
+
+Our second use case also expands "memberdn" attributes (1), (2), (6) and (7),
+follows the DN references and returns the "maildrop" of the referenced user
+entries. Here we use the "special_result_attribute" setting from ldap_table(5)
+to designate the "memberdn" attribute as holding DNs of the desired member
+entries. The "result_attribute" setting selects which attributes are returned
+from the selected DNs. It is important to choose a result attribute that is not
+also present in the group object, because result attributes are collected from
+both the group and the member DNs. In this case we choose "maildrop" and assume
+for the moment that groups never have a "maildrop" (the "bgroup" "maildrop"
+attribute is for a different use case). The returned data for "auser" and
+"buser" is from items (11) and (13) in the mock data.
+
+        special.cf:
+            ...
+            search_base = dc=example, dc=com
+            query_filter = mail=%s
+            result_attribute = memberaddr, maildrop
+            special_result_attribute = memberdn
+        $ postmap -q agroup@example.com ldap:special.cf
+
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+
+Note: if the desired member object result attribute is always also present in
+the group, you get suprising results, the expansion also returns the address of
+the group. This is a known limitation of Postfix releases prior to 2.4, and is
+addressed in the new with Postfix 2.4 "leaf_result_attribute" feature described
+in ldap_table(5).
+
+Our third use case has some groups that are expanded immediately, and other
+groups that are forwarded to a dedicated mailing list manager host for delayed
+expansion. This uses two LDAP tables, one for users and forwarded groups and a
+second for groups that can be expanded immediately. It is assumed that groups
+that require forwarding are never nested members of groups that are directly
+expanded.
+
+        no_expand.cf:
+            ...
+            search_base = dc=example, dc=com
+            query_filter = mail=%s
+            result_attribute = maildrop
+        expand.cf
+            ...
+            search_base = dc=example, dc=com
+            query_filter = mail=%s
+            result_attribute = memberaddr, maildrop
+            special_result_attribute = memberdn
+        $ postmap -q auser@example.com ldap:no_expand.cf ldap:expand.cf
+        auser@mailhub.example.com
+        $ postmap -q agroup@example.com ldap:no_expand.cf ldap:expand.cf
+
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+        $ postmap -q bgroup@example.com ldap:no_expand.cf ldap:expand.cf
+        bgroup@mlm.example.com
+
+Non-group objects and groups with delayed expansion (those that have a maildrop
+attribute) are rewritten to a single maildrop value. Groups that don't have a
+maildrop are expanded as the second use case. This admits a more elegant
+solution with Postfix 2.4 and later.
+
+Our final use case is the same as the third, but this time uses new features in
+Postfix 2.4. We now are able to use just one LDAP table and no longer need to
+assume that forwarded groups are never nested inside expanded groups.
+
+        fancy.cf:
+            ...
+            search_base = dc=example, dc=com
+            query_filter = mail=%s
+            result_attribute = memberaddr
+            special_result_attribute = memberdn
+            terminal_result_attribute = maildrop
+            leaf_result_attribute = mail
+        $ postmap -q auser@example.com ldap:fancy.cf
+        auser@mailhub.example.com
+        $ postmap -q cuser@example.com ldap:fancy.cf
+        cuser@example.com
+        $ postmap -q agroup@example.com ldap:fancy.cf
+
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+        $ postmap -q bgroup@example.com ldap:fancy.cf
+        bgroup@mlm.example.com
+
+Above, delayed expansion is enabled via "terminal_result_attribute", which, if
+present, is used as the sole result and all other expansion is suppressed.
+Otherwise, the "leaf_result_attribute" is only returned for leaf objects that
+don't have a "special_result_attribute" (non-groups), while the
+"result_attribute" (direct member address of groups) is returned at every level
+of recursive expansion, not just the leaf nodes. This fancy example illustrates
+all the features of Postfix 2.4 group expansion.
+
 O\bOt\bth\bhe\ber\br u\bus\bse\bes\bs o\bof\bf L\bLD\bDA\bAP\bP l\blo\boo\bok\bku\bup\bps\bs
 
 Other common uses for LDAP lookups include rewriting senders and recipients
 with Postfix's canonical lookups, for example in order to make mail leaving
-your site appear to be coming from "First.Last@site.dom" instead of
-"userid@site.dom".
+your site appear to be coming from "First.Last@example.com" instead of
+"userid@example.com".
 
 N\bNo\bot\bte\bes\bs a\ban\bnd\bd t\bth\bhi\bin\bng\bgs\bs t\bto\bo t\bth\bhi\bin\bnk\bk a\bab\bbo\bou\but\bt
 
@@ -166,9 +338,9 @@ N\bNo\bot\bte\bes\bs a\ban\bnd\bd t\bth\bhi\bin\bng\bgs\bs t\bto\bo t\bth\bhi\bin\bnk\bk a\bab\bbo\bou\bu
     define an entry intended for use as a mailing list that looks like this
     (Warning! Schema made up just for this example):
 
-        dn: cn=Accounting Staff List, dc=my, dc=com
+        dn: cn=Accounting Staff List, dc=example, dc=com
         cn: Accounting Staff List
-        o: my.com
+        o: example.com
         objectclass: maillist
         mailacceptinggeneralid: accountingstaff
         mailacceptinggeneralid: accounting-staff
index efc0eebfe349370347a1c18593375a54308f34d0..ee39ad617eccc5e6859d9d67650c4688a7c7b895 100644 (file)
@@ -254,7 +254,7 @@ Note: some Cyrus SASL distributions look for the smtpd.conf file in /etc/sasl2.
     a pam".
 
     IMPORTANT: saslauthd usually establishes a UNIX domain socket in /var/run/
-    saslauthd and waits for authentication requests. postfix processes must
+    saslauthd and waits for authentication requests. Postfix processes must
     have read+execute permission to this directory or authentication attempts
     will fail.
 
index 7f6ab85ca3e73282e2121c6b4e89f6cf8f665beb..0f14fb03052809b4954690fd74aa8a473cf44c34 100644 (file)
@@ -21,7 +21,8 @@
 
 <p> The sender/recipient address verification feature described in this
 document is suitable only for low-traffic sites. It performs poorly
-under high load and may cause your site to be blacklisted by some
+under high load; excessive sender address verification activity may
+even cause your site to be blacklisted by some
 providers. See the "<a href="#limitations">Limitations</a>" section
 below for details. </p>
 
index e828b284814005958c28f9491372b53fa5b35625..6fe7ef71b66d9096772157355c4a0c1513fd5917 100644 (file)
@@ -41,6 +41,8 @@ it to each. </p>
 
 <li><a href="#example_virtual">Example: virtual domains/addresses</a>
 
+<li><a href="#example_group">Example: expanding LDAP groups</a>
+
 <li><a href="#other">Other uses of LDAP lookups</a>
 
 <li><a href="#hmmmm">Notes and things to think about</a>
@@ -124,7 +126,7 @@ option (e.g. '-R') so the executables can find it at runtime. </p>
 <h2><a name="config">Configuring LDAP lookups</a></h2>
 
 <p> In order to use LDAP lookups, define an LDAP source
-as a table lookup in main.cf, for example: </p>
+as a table lookup in <a href="postconf.5.html">main.cf</a>, for example: </p>
 
 <blockquote>
 <pre>
@@ -140,7 +142,7 @@ page. </p>
 <h2><a name="example_alias">Example: local(8) aliases</a></h2>
 
 <p> Here's a basic example for using LDAP to look up <a href="local.8.html">local(8)</a>
-aliases. Assume that in main.cf, you have: </p>
+aliases. Assume that in <a href="postconf.5.html">main.cf</a>, you have: </p>
 
 <blockquote> 
 <pre>
@@ -152,14 +154,14 @@ aliases. Assume that in main.cf, you have: </p>
 
 <blockquote> 
 <pre>
-server_host = ldap.my.com
-search_base = dc=my, dc=com
+server_host = ldap.example.com
+search_base = dc=example, dc=com
 </pre>
 </blockquote> 
 
 <p> Upon receiving mail for a local address "ldapuser" that isn't
 found in the /etc/aliases database, Postfix will search the LDAP
-server listening at port 389 on ldap.my.com. It will bind anonymously,
+server listening at port 389 on ldap.example.com. It will bind anonymously,
 search for any directory entries whose mailacceptinggeneralid
 attribute is "ldapuser", read the "maildrop" attributes of those
 found, and build a list of their maildrops, which will be treated
@@ -176,7 +178,7 @@ of your virtual recipient's mailacceptinggeneralid attributes are
 fully qualified with their virtual domains. Finally, if you want
 to designate a directory entry as the default user for a virtual
 domain, just give it an additional mailacceptinggeneralid (or the
-equivalent in your directory) of "@virtual.dom". That's right, no
+equivalent in your directory) of "@fake.dom". That's right, no
 user part. If you don't want a catchall user, omit this step and
 mail to unknown users in the domain will simply bounce. </p>
 
@@ -212,12 +214,221 @@ go to this entry ... </p>
 <a href="QSHAPE_README.html#maildrop_queue">maildrop</a>, e.g. "normaluser@fake.dom" and "normaluser@real.dom".
 </p>
 
+<h2><a name="example_group">Example: expanding LDAP groups</a></h2>
+
+<p> LDAP is frequently used to store group member information, and Postfix
+supports expanding a group's email address to the list of email addresses
+of the group members. There are a number of ways of handling LDAP groups,
+which will be illustrated via the mock LDAP entries and implied schema
+below.  This shows two group entries "agroup" and "bgroup" and four
+user entries "auser", "buser", "cuser" and "duser". The group "agroup"
+has the users "auser" (1) and "buser" (2) as members via DN references
+in the multi-valued attribute "memberdn", and direct email addresses of
+two external users "auser@example.org" (3) and "buser@example.org" (4)
+stored in the multi-valued attribute "memberaddr".  The same is true of
+"bgroup" and "cuser"/"duser" (6)/(7)/(8)/(9), but "bgroup" also has a
+"maildrop" attribute of "bgroup@mlm.example.com" (5): </p>
+
+<blockquote> 
+<pre>
+     dn: cn=agroup, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapgroup
+     cn: agroup
+     mail: agroup@example.com
+1 -&gt; memberdn: uid=auser, dc=example, dc=com
+2 -&gt; memberdn: uid=buser, dc=example, dc=com
+3 -&gt; memberaddr: auser@example.org
+4 -&gt; memberaddr: buser@example.org
+</pre>
+<br>
+
+<pre>
+     dn: cn=bgroup, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapgroup
+     cn: bgroup
+     mail: bgroup@example.com
+5 -&gt; maildrop: bgroup@mlm.example.com
+6 -&gt; memberdn: uid=cuser, dc=example, dc=com
+7 -&gt; memberdn: uid=duser, dc=example, dc=com
+8 -&gt; memberaddr: cuser@example.org
+9 -&gt; memberaddr: duser@example.org
+</pre>
+<br>
+
+<pre>
+     dn: uid=auser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: auser
+10 -&gt; mail: auser@example.com
+11 -&gt; maildrop: auser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+     dn: uid=buser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: buser
+12 -&gt; mail: buser@example.com
+13 -&gt; maildrop: buser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+     dn: uid=cuser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: cuser
+14 -&gt; mail: cuser@example.com
+</pre>
+<br>
+
+<pre>
+     dn: uid=duser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: duser
+15 -&gt; mail: duser@example.com
+</pre>
+<br>
+
+</blockquote> 
+
+<p> Our first use case ignores the "memberdn" attributes, and assumes
+that groups hold only direct "memberaddr" strings as in (3), (4), (8) and
+(9). The goal is to map the group address to the list of constituent
+"memberaddr" values. This is simple, ignoring the various connection
+related settings (hosts, ports, bind settings, timeouts, ...) we have:
+</p>
+
+<blockquote> 
+<pre>
+    simple.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr
+    $ postmap -q agroup@example.com <a href="ldap_table.5.html">ldap</a>:simple.cf
+    auser@example.org,buser@example.org
+</pre>
+</blockquote> 
+
+<p> We search "dc=example, dc=com". The "mail" attribute is used in the
+query_filter to locate the right group, the "result_attribute" setting
+described in <a href="ldap_table.5.html">ldap_table(5)</a> is used to specify that "memberaddr" values
+from the matching group are to be returned as a comma separated list.
+Always check tables using <a href="postmap.1.html">postmap(1)</a> with the "-q" option, before
+deploying them into production use in <a href="postconf.5.html">main.cf</a>. </p>
+
+<p> Our second use case also expands "memberdn" attributes (1), (2),
+(6) and (7), follows the DN references and returns the "maildrop" of the
+referenced user entries. Here we use the "special_result_attribute"
+setting from <a href="ldap_table.5.html">ldap_table(5)</a> to designate the "memberdn" attribute
+as holding DNs of the desired member entries. The "result_attribute"
+setting selects which attributes are returned from the selected DNs. It
+is important to choose a result attribute that is not also present in
+the group object, because result attributes are collected from both
+the group and the member DNs. In this case we choose "maildrop" and
+assume for the moment that groups never have a "maildrop" (the "bgroup"
+"maildrop" attribute is for a different use case). The returned data for
+"auser" and "buser" is from items (11) and (13) in the mock data. </p>
+
+<blockquote> 
+<pre>
+    special.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr, maildrop
+        special_result_attribute = memberdn
+    $ postmap -q agroup@example.com <a href="ldap_table.5.html">ldap</a>:special.cf
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+</pre>
+</blockquote> 
+
+<p> Note: if the desired member object result attribute is always also
+present in the group, you get suprising results, the expansion also
+returns the address of the group. This is a known limitation of Postfix
+releases prior to 2.4, and is addressed in the new with Postfix 2.4
+"leaf_result_attribute" feature described in <a href="ldap_table.5.html">ldap_table(5)</a>. </p>
+
+<p> Our third use case has some groups that are expanded immediately,
+and other groups that are forwarded to a dedicated mailing list manager
+host for delayed expansion. This uses two LDAP tables, one for users
+and forwarded groups and a second for groups that can be expanded
+immediately. It is assumed that groups that require forwarding are
+never nested members of groups that are directly expanded. </p>
+
+<blockquote> 
+<pre>
+    no_expand.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = maildrop
+    expand.cf
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr, maildrop
+        special_result_attribute = memberdn
+    $ postmap -q auser@example.com <a href="ldap_table.5.html">ldap</a>:no_expand.cf <a href="ldap_table.5.html">ldap</a>:expand.cf
+    auser@mailhub.example.com
+    $ postmap -q agroup@example.com <a href="ldap_table.5.html">ldap</a>:no_expand.cf <a href="ldap_table.5.html">ldap</a>:expand.cf
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+    $ postmap -q bgroup@example.com <a href="ldap_table.5.html">ldap</a>:no_expand.cf <a href="ldap_table.5.html">ldap</a>:expand.cf
+    bgroup@mlm.example.com
+</pre>
+</blockquote> 
+
+<p> Non-group objects and groups with delayed expansion (those that have a
+maildrop attribute) are rewritten to a single maildrop value. Groups that
+don't have a maildrop are expanded as the second use case. This admits
+a more elegant solution with Postfix 2.4 and later. </p>
+
+<p> Our final use case is the same as the third, but this time uses new
+features in Postfix 2.4. We now are able to use just one LDAP table and
+no longer need to assume that forwarded groups are never nested inside
+expanded groups. </p>
+
+<blockquote> 
+<pre>
+    fancy.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr
+        special_result_attribute = memberdn
+        terminal_result_attribute = maildrop
+        leaf_result_attribute = mail
+    $ postmap -q auser@example.com <a href="ldap_table.5.html">ldap</a>:fancy.cf
+    auser@mailhub.example.com
+    $ postmap -q cuser@example.com <a href="ldap_table.5.html">ldap</a>:fancy.cf
+    cuser@example.com
+    $ postmap -q agroup@example.com <a href="ldap_table.5.html">ldap</a>:fancy.cf
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+    $ postmap -q bgroup@example.com <a href="ldap_table.5.html">ldap</a>:fancy.cf
+    bgroup@mlm.example.com
+</pre>
+</blockquote> 
+
+<p> Above, delayed expansion is enabled via "terminal_result_attribute",
+which, if present, is used as the sole result and all other expansion is
+suppressed. Otherwise, the "leaf_result_attribute" is only returned for
+leaf objects that don't have a "special_result_attribute" (non-groups),
+while the "result_attribute" (direct member address of groups) is returned
+at every level of recursive expansion, not just the leaf nodes. This fancy
+example illustrates all the features of Postfix 2.4 group expansion. </p>
+
 <h2><a name="other">Other uses of LDAP lookups</a></h2>
 
 Other common uses for LDAP lookups include rewriting senders and
 recipients with Postfix's canonical lookups, for example in order
 to make mail leaving your site appear to be coming from
-"First.Last@site.dom" instead of "userid@site.dom".
+"First.Last@example.com" instead of "userid@example.com".
 
 <h2><a name="hmmmm">Notes and things to think about</a></h2>
 
@@ -240,9 +451,9 @@ to make mail leaving your site appear to be coming from
 
 <blockquote>
 <pre>
-dn: cn=Accounting Staff List, dc=my, dc=com
+dn: cn=Accounting Staff List, dc=example, dc=com
 cn: Accounting Staff List
-o: my.com
+o: example.com
 objectclass: maillist
 mailacceptinggeneralid: accountingstaff
 mailacceptinggeneralid: accounting-staff
@@ -341,7 +552,7 @@ contents, please include the applicable bits of some directory entries. </p>
             external files (<a href="ldap_table.5.html">ldap</a>:/path/ldap.cf) needed to securely store
             passwords for plain auth.
 
-<li>Liviu Daia revised the configuration interface and added the main.cf
+<li>Liviu Daia revised the configuration interface and added the <a href="postconf.5.html">main.cf</a>
     configuration feature.</li>
     
 <li>Liviu Daia with further refinements from Jose Luis Tallon and
index 5d172894711cbaad136da49f215f6cc30a40ec4d..3824e7de29ee8e45f6ad3152ea140ea597c15973 100644 (file)
@@ -391,7 +391,7 @@ can authenticate against PAM and various other sources. To use PAM,
 start saslauthd with "-a pam". </p>
 
 <p> IMPORTANT: saslauthd usually establishes a UNIX domain socket
-in /var/run/saslauthd and waits for authentication requests. postfix
+in /var/run/saslauthd and waits for authentication requests. Postfix
 processes must have read+execute permission to this directory or
 authentication attempts will fail. </p>
 
index ef9d1cf533298c692d175045f1d3a474338cbef7..238197abc41a6f23ecb0a544ee2bf2782a0d7f5c 100644 (file)
@@ -24,6 +24,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
        In order to use LDAP lookups, define an LDAP source  as  a
        lookup table in <a href="postconf.5.html">main.cf</a>, for example:
+
            <a href="postconf.5.html#alias_maps">alias_maps</a> = <a href="ldap_table.5.html">ldap</a>:/etc/postfix/ldap-aliases.cf
 
        The  file /etc/postfix/ldap-aliases.cf has the same format
@@ -87,10 +88,12 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
        For example, NEVER do this in a map  defining  $<a href="postconf.5.html#mydestination">mydestina</a>-
        <a href="postconf.5.html#mydestination">tion</a>:
+
            query_filter = domain=*
            result_attribute = domain
 
        Do this instead:
+
            query_filter = domain=%s
            result_attribute = domain
 
@@ -102,6 +105,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
        <b>server_host (default: localhost)</b>
               The name of the host running the LDAP server,  e.g.
+
                   server_host = ldap.example.com
 
               Depending  on the LDAP client library you're using,
@@ -110,10 +114,12 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               the first one fail. It should also be  possible  to
               give  each  server  in  the  list  a different port
               (overriding <b>server_port</b> below), by naming them like
+
                   server_host = ldap.example.com:1444
 
               With OpenLDAP, a (list of) LDAP URLs can be used to
               specify both the hostname(s) and the port(s):
+
                   server_host = <a href="ldap_table.5.html">ldap</a>://ldap.example.com:1444
                               <a href="ldap_table.5.html">ldap</a>://ldap2.example.com:1444
 
@@ -121,21 +127,25 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               supported,  including  connections over UNIX domain
               sockets, and LDAP SSL (the last one  provided  that
               OpenLDAP was compiled with support for SSL):
+
                   server_host = ldapi://%2Fsome%2Fpath
                               ldaps://ldap.example.com:636
 
        <b>server_port (default: 389)</b>
               The port the LDAP server listens on, e.g.
+
                   server_port = 778
 
        <b>timeout (default: 10 seconds)</b>
               The number of seconds a search can take before tim-
               ing out, e.g.
+
                   timeout = 5
 
        <b>search_base (No default; you must configure this)</b>
               The <a href="http://www.faqs.org/rfcs/rfc2253.html">RFC2253</a> base DN at which to conduct the search,
               e.g.
+
                   search_base = dc=your, dc=com
 
               With  Postfix 2.2 and later this parameter supports
@@ -184,6 +194,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               The  <a href="http://www.faqs.org/rfcs/rfc2254.html">RFC2254</a>  filter  used to search the directory,
               where <b>%s</b> is a substitute for the address Postfix is
               trying to resolve, e.g.
+
                   query_filter = (&amp;(mail=%s)(paid_up=true))
 
               This  parameter  supports  the following '%' expan-
@@ -315,6 +326,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               lookups,  bare domain lookups and "@domain" lookups
               are not performed. This  can  significantly  reduce
               the query load on the LDAP server.
+
                   domain = postfix.org, hash:/etc/postfix/search-
               domains
 
@@ -330,13 +342,15 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               The  attribute(s) Postfix will read from any direc-
               tory entries returned by the lookup, to be resolved
               to an email address.
+
                   result_attribute = mailbox, maildrop
 
-       <b>special_result_attribute (No default)</b>
+       <b>special_result_attribute (default: empty)</b>
               The attribute(s) of directory entries that can con-
               tain DNs or URLs. If found, a recursive  subsequent
               search is done using their values.
-                  special_result_attribute = member
+
+                  special_result_attribute = memberdn
 
               DN  recursion  retrieves the same result_attributes
               as the main query, including the special attributes
@@ -347,6 +361,51 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               map's  special  result  attributes,  these are also
               retrieved and used recursively.
 
+       <b>terminal_result_attribute (default: empty)</b>
+              When one or more  terminal  result  attributes  are
+              found in an LDAP entry, all other result attributes
+              are ignored and only the terminal result attributes
+              are  returned. This is useful for delegating expan-
+              sion of group members  to  a  particular  host,  by
+              using  an optional "maildrop" attribute on selected
+              groups to route the group to a specific host, where
+              the  group  is  expanded, possibly via mailing-list
+              manager or other special processing.
+
+                  terminal_result_attribute = maildrop
+
+              This feature is available with Postfix &gt;= 2.4.
+
+       <b>leaf_result_attribute (default: empty)</b>
+              When one or  more  special  result  attributes  are
+              found  in  a  non-terminal  (see above) LDAP entry,
+              leaf result attributes are excluded from the expan-
+              sion  of  that entry. This is useful when expanding
+              groups and the desired mail address attribute(s) of
+              the member objects obtained via DN or URI recursion
+              are also present  in  the  group  object.  To  only
+              return  the  attribute values from the leaf objects
+              and not the containing group, add the attribute  to
+              the   leaf_result_attribute   list,   and  not  the
+              result_attribute list, which  is  always  expanded.
+              Note,  the  default  value of "result_attribute" is
+              not empty, you may want to set it explicitly  empty
+              when  using  "leaf_result_attribute"  to expand the
+              group to a list of member DN addresses.  If  groups
+              have  both member DN references AND attributes that
+              hold multiple string valued rfc822 addresses,  then
+              the  string  attributes  go  in "result_attribute".
+              The attributes that represent the  email  addresses
+              of  objects referenced via a DN (or LDAP URI) go in
+              "leaf_result_attribute".
+
+                  result_attribute = memberaddr
+                  special_result_attribute = memberdn
+                  terminal_result_attribute = maildrop
+                  leaf_result_attribute = mail
+
+              This feature is available with Postfix &gt;= 2.4.
+
        <b>scope (default: sub)</b>
               The LDAP search scope: <b>sub</b>, <b>base</b>,  or  <b>one</b>.   These
               translate into LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE,
@@ -356,6 +415,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               Whether or not to bind to the  LDAP  server.  Newer
               LDAP implementations don't require clients to bind,
               which saves time. Example:
+
                   bind = no
 
               If you do need to bind, you might consider  config-
@@ -369,6 +429,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
        <b>bind_dn (default: empty)</b>
               If  you  do  have  to bind, do it with this distin-
               guished name. Example:
+
                   bind_dn = uid=postfix, dc=your, dc=com
 
        <b>bind_pw (default: empty)</b>
@@ -381,6 +442,7 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
               because <a href="postconf.5.html">main.cf</a> needs to be world readable to allow
               local accounts to submit mail via the sendmail com-
               mand. Example:
+
                   bind_pw = postfixpw
 
        <b>cache (IGNORED with a warning)</b>
@@ -459,13 +521,16 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 
        LDAP SSL service can be requested by using a LDAP SSL  URL
        in the server_host parameter:
+
            server_host = ldaps://ldap.example.com:636
 
        STARTTLS can be turned on with the start_tls parameter:
+
            start_tls = yes
 
        Both  forms  require LDAP protocol version 3, which has to
        be set explicitly with:
+
            version = 3
 
        If any of the Postfix programs querying the map is config-
@@ -530,22 +595,24 @@ LDAP_TABLE(5)                                                    LDAP_TABLE(5)
 <b>EXAMPLE</b>
        Here's  a basic example for using LDAP to look up <a href="local.8.html">local(8)</a>
        aliases.  Assume that in <a href="postconf.5.html">main.cf</a>, you have:
+
            <a href="postconf.5.html#alias_maps">alias_maps</a> = hash:/etc/aliases,
                <a href="ldap_table.5.html">ldap</a>:/etc/postfix/ldap-aliases.cf
 
        and in <a href="ldap_table.5.html">ldap</a>:/etc/postfix/ldap-aliases.cf you have:
-           server_host = ldap.my.com
-           search_base = dc=my, dc=com
+
+           server_host = ldap.example.com
+           search_base = dc=example, dc=com
 
        Upon receiving mail for a local  address  "ldapuser"  that
        isn't  found  in  the  /etc/aliases database, Postfix will
-       search  the  LDAP  server  listening  at   port   389   on
-       ldap.my.com.   It  will  bind  anonymously, search for any
-       directory entries whose  mailacceptinggeneralid  attribute
-       is  "ldapuser",  read  the  "maildrop" attributes of those
-       found, and build a list of their maildrops, which will  be
-       treated  as  <a href="http://www.faqs.org/rfcs/rfc822.html">RFC822</a> addresses to which the message will be
-       delivered.
+       search the LDAP server listening at port 389 on ldap.exam-
+       ple.com.   It will bind anonymously, search for any direc-
+       tory entries  whose  mailacceptinggeneralid  attribute  is
+       "ldapuser", read the "maildrop" attributes of those found,
+       and build a list of their maildrops, which will be treated
+       as  <a href="http://www.faqs.org/rfcs/rfc822.html">RFC822</a>  addresses  to which the message will be deliv-
+       ered.
 
 <b>SEE ALSO</b>
        <a href="postmap.1.html">postmap(1)</a>, Postfix lookup table manager
index 4e22f498781bda8600a48f2dc6215cf93a0b20a4..1cb4f49188e2ec5532a49937f55ebc7a76f1e539 100644 (file)
@@ -22,6 +22,7 @@ Alternatively, lookup tables can be specified as LDAP databases.
 
 In order to use LDAP lookups, define an LDAP source as a lookup
 table in main.cf, for example:
+
 .ti +4
 alias_maps = ldap:/etc/postfix/ldap-aliases.cf
 
@@ -87,6 +88,7 @@ an arbitrary value. With LDAP databases it is not uncommon to
 return the key itself.
 
 For example, NEVER do this in a map defining $mydestination:
+
 .in +4
 query_filter = domain=*
 .br
@@ -94,6 +96,7 @@ result_attribute = domain
 .in -4
 
 Do this instead:
+
 .in +4
 query_filter = domain=%s
 .br
@@ -110,6 +113,7 @@ Postfix configuration routines understand how to deal with quoted
 strings.
 .IP "\fBserver_host (default: localhost)\fR"
 The name of the host running the LDAP server, e.g.
+
 .ti +4
 server_host = ldap.example.com
 
@@ -118,11 +122,13 @@ be possible to specify multiple servers here, with the library
 trying them in order should the first one fail. It should also
 be possible to give each server in the list a different port
 (overriding \fBserver_port\fR below), by naming them like
+
 .ti +4
 server_host = ldap.example.com:1444
 
 With OpenLDAP, a (list of) LDAP URLs can be used to specify both
 the hostname(s) and the port(s):
+
 .ti +4
 server_host = ldap://ldap.example.com:1444
 .ti +8
@@ -132,20 +138,24 @@ All LDAP URLs accepted by the OpenLDAP library are supported,
 including connections over UNIX domain sockets, and LDAP SSL
 (the last one provided that OpenLDAP was compiled with support
 for SSL):
+
 .ti +4
 server_host = ldapi://%2Fsome%2Fpath
 .ti +8
         ldaps://ldap.example.com:636
 .IP "\fBserver_port (default: 389)\fR"
 The port the LDAP server listens on, e.g.
+
 .ti +4
 server_port = 778
 .IP "\fBtimeout (default: 10 seconds)\fR"
 The number of seconds a search can take before timing out, e.g.
+
 .ti +4
 timeout = 5
 .IP "\fBsearch_base (No default; you must configure this)\fR"
 The RFC2253 base DN at which to conduct the search, e.g.
+
 .ti +4
 search_base = dc=your, dc=com
 .IP
@@ -188,6 +198,7 @@ no results.
 The RFC2254 filter used to search the directory, where \fB%s\fR
 is a substitute for the address Postfix is trying to resolve,
 e.g.
+
 .ti +4
 query_filter = (&(mail=%s)(paid_up=true))
 
@@ -297,6 +308,7 @@ keys with a *non-empty* localpart and a matching domain
 are eligible for lookup: 'user' lookups, bare domain lookups
 and "@domain" lookups are not performed. This can significantly
 reduce the query load on the LDAP server.
+
 .ti +4
 domain = postfix.org, hash:/etc/postfix/searchdomains
 
@@ -310,14 +322,16 @@ This feature is available in Postfix 1.0 and later.
 The attribute(s) Postfix will read from any directory
 entries returned by the lookup, to be resolved to an email
 address.
+
 .ti +4
 result_attribute = mailbox, maildrop
-.IP "\fBspecial_result_attribute (No default)\fR"
+.IP "\fBspecial_result_attribute (default: empty)\fR"
 The attribute(s) of directory entries that can contain DNs
 or URLs. If found, a recursive subsequent search is done
 using their values.
+
 .ti +4
-special_result_attribute = member
+special_result_attribute = memberdn
 
 DN recursion retrieves the same result_attributes as the
 main query, including the special attributes for further
@@ -326,6 +340,47 @@ that are included in the URI definition and are *also*
 listed in "result_attribute". If the URI lists any of the
 map's special result attributes, these are also retrieved
 and used recursively.
+.IP "\fBterminal_result_attribute (default: empty)\fR"
+When one or more terminal result attributes are found in an LDAP
+entry, all other result attributes are ignored and only the terminal
+result attributes are returned. This is useful for delegating expansion
+of group members to a particular host, by using an optional "maildrop"
+attribute on selected groups to route the group to a specific host,
+where the group is expanded, possibly via mailing-list manager or
+other special processing.
+
+.ti +4
+terminal_result_attribute = maildrop
+
+This feature is available with Postfix >= 2.4.
+.IP "\fBleaf_result_attribute (default: empty)\fR"
+When one or more special result attributes are found in a non-terminal
+(see above) LDAP entry, leaf result attributes are excluded from the
+expansion of that entry. This is useful when expanding groups and the
+desired mail address attribute(s) of the member objects obtained via
+DN or URI recursion are also present in the group object. To only
+return the attribute values from the leaf objects and not the
+containing group, add the attribute to the leaf_result_attribute list,
+and not the result_attribute list, which is always expanded. Note,
+the default value of "result_attribute" is not empty, you may want to
+set it explicitly empty when using "leaf_result_attribute" to expand
+the group to a list of member DN addresses. If groups have both
+member DN references AND attributes that hold multiple string valued
+rfc822 addresses, then the string attributes go in "result_attribute".
+The attributes that represent the email addresses of objects
+referenced via a DN (or LDAP URI) go in "leaf_result_attribute".
+
+.in +4
+result_attribute = memberaddr
+.br
+special_result_attribute = memberdn
+.br
+terminal_result_attribute = maildrop
+.br
+leaf_result_attribute = mail
+.in -4
+
+This feature is available with Postfix >= 2.4.
 .IP "\fBscope (default: sub)\fR"
 The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR.
 These translate into LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE,
@@ -334,6 +389,7 @@ and LDAP_SCOPE_ONELEVEL.
 Whether or not to bind to the LDAP server. Newer LDAP
 implementations don't require clients to bind, which saves
 time. Example:
+
 .ti +4
 bind = no
 
@@ -346,6 +402,7 @@ should prevent the password from traversing the network in
 the clear.
 .IP "\fBbind_dn (default: empty)\fR"
 If you do have to bind, do it with this distinguished name. Example:
+
 .ti +4
 bind_dn = uid=postfix, dc=your, dc=com
 .IP "\fBbind_pw (default: empty)\fR"
@@ -357,6 +414,7 @@ main.cf, it is not possible to securely store the bind
 password. This is because main.cf needs to be world readable
 to allow local accounts to submit mail via the sendmail
 command. Example:
+
 .ti +4
 bind_pw = postfixpw
 .IP "\fBcache (IGNORED with a warning)\fR"
@@ -426,15 +484,18 @@ issue the STARTTLS command.
 
 LDAP SSL service can be requested by using a LDAP SSL URL
 in the server_host parameter:
+
 .ti +4
 server_host = ldaps://ldap.example.com:636
 
 STARTTLS can be turned on with the start_tls parameter:
+
 .ti +4
 start_tls = yes
 
 Both forms require LDAP protocol version 3, which has to be set
 explicitly with:
+
 .ti +4
 version = 3
 
@@ -488,21 +549,23 @@ Cipher suite to use in SSL/TLS negotiations.
 Here's a basic example for using LDAP to look up local(8)
 aliases.
 Assume that in main.cf, you have:
+
 .ti +4
 alias_maps = hash:/etc/aliases,
 .ti +8
 ldap:/etc/postfix/ldap-aliases.cf
 
 and in ldap:/etc/postfix/ldap-aliases.cf you have:
+
 .in +4
-server_host = ldap.my.com
+server_host = ldap.example.com
 .br
-search_base = dc=my, dc=com
+search_base = dc=example, dc=com
 .in -4
 
 Upon receiving mail for a local address "ldapuser" that
 isn't found in the /etc/aliases database, Postfix will
-search the LDAP server listening at port 389 on ldap.my.com.
+search the LDAP server listening at port 389 on ldap.example.com.
 It will bind anonymously, search for any directory entries
 whose mailacceptinggeneralid attribute is "ldapuser", read
 the "maildrop" attributes of those found, and build a list
index 1d66b4fe934ea230c14a2053e4e28abddb1b374e..d3ff04385c81eb3516fe724784a50cbedf7dba00 100644 (file)
@@ -21,7 +21,8 @@
 
 <p> The sender/recipient address verification feature described in this
 document is suitable only for low-traffic sites. It performs poorly
-under high load and may cause your site to be blacklisted by some
+under high load; excessive sender address verification activity may
+even cause your site to be blacklisted by some
 providers. See the "<a href="#limitations">Limitations</a>" section
 below for details. </p>
 
index f9573a897cad1c002e35bd96a0e5a1286e601cb5..7b8b6085706110088a4d8264a9b0aa4e22a229ba 100644 (file)
@@ -41,6 +41,8 @@ it to each. </p>
 
 <li><a href="#example_virtual">Example: virtual domains/addresses</a>
 
+<li><a href="#example_group">Example: expanding LDAP groups</a>
+
 <li><a href="#other">Other uses of LDAP lookups</a>
 
 <li><a href="#hmmmm">Notes and things to think about</a>
@@ -152,14 +154,14 @@ alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf
 
 <blockquote> 
 <pre>
-server_host = ldap.my.com
-search_base = dc=my, dc=com
+server_host = ldap.example.com
+search_base = dc=example, dc=com
 </pre>
 </blockquote> 
 
 <p> Upon receiving mail for a local address "ldapuser" that isn't
 found in the /etc/aliases database, Postfix will search the LDAP
-server listening at port 389 on ldap.my.com. It will bind anonymously,
+server listening at port 389 on ldap.example.com. It will bind anonymously,
 search for any directory entries whose mailacceptinggeneralid
 attribute is "ldapuser", read the "maildrop" attributes of those
 found, and build a list of their maildrops, which will be treated
@@ -176,7 +178,7 @@ of your virtual recipient's mailacceptinggeneralid attributes are
 fully qualified with their virtual domains. Finally, if you want
 to designate a directory entry as the default user for a virtual
 domain, just give it an additional mailacceptinggeneralid (or the
-equivalent in your directory) of "@virtual.dom". That's right, no
+equivalent in your directory) of "@fake.dom". That's right, no
 user part. If you don't want a catchall user, omit this step and
 mail to unknown users in the domain will simply bounce. </p>
 
@@ -212,12 +214,221 @@ go to this entry ... </p>
 maildrop, e.g. "normaluser@fake.dom" and "normaluser@real.dom".
 </p>
 
+<h2><a name="example_group">Example: expanding LDAP groups</a></h2>
+
+<p> LDAP is frequently used to store group member information, and Postfix
+supports expanding a group's email address to the list of email addresses
+of the group members. There are a number of ways of handling LDAP groups,
+which will be illustrated via the mock LDAP entries and implied schema
+below.  This shows two group entries "agroup" and "bgroup" and four
+user entries "auser", "buser", "cuser" and "duser". The group "agroup"
+has the users "auser" (1) and "buser" (2) as members via DN references
+in the multi-valued attribute "memberdn", and direct email addresses of
+two external users "auser@example.org" (3) and "buser@example.org" (4)
+stored in the multi-valued attribute "memberaddr".  The same is true of
+"bgroup" and "cuser"/"duser" (6)/(7)/(8)/(9), but "bgroup" also has a
+"maildrop" attribute of "bgroup@mlm.example.com" (5): </p>
+
+<blockquote> 
+<pre>
+     dn: cn=agroup, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapgroup
+     cn: agroup
+     mail: agroup@example.com
+1 -&gt; memberdn: uid=auser, dc=example, dc=com
+2 -&gt; memberdn: uid=buser, dc=example, dc=com
+3 -&gt; memberaddr: auser@example.org
+4 -&gt; memberaddr: buser@example.org
+</pre>
+<br>
+
+<pre>
+     dn: cn=bgroup, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapgroup
+     cn: bgroup
+     mail: bgroup@example.com
+5 -&gt; maildrop: bgroup@mlm.example.com
+6 -&gt; memberdn: uid=cuser, dc=example, dc=com
+7 -&gt; memberdn: uid=duser, dc=example, dc=com
+8 -&gt; memberaddr: cuser@example.org
+9 -&gt; memberaddr: duser@example.org
+</pre>
+<br>
+
+<pre>
+     dn: uid=auser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: auser
+10 -&gt; mail: auser@example.com
+11 -&gt; maildrop: auser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+     dn: uid=buser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: buser
+12 -&gt; mail: buser@example.com
+13 -&gt; maildrop: buser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+     dn: uid=cuser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: cuser
+14 -&gt; mail: cuser@example.com
+</pre>
+<br>
+
+<pre>
+     dn: uid=duser, dc=example, dc=com
+     objectclass: top
+     objectclass: ldapuser
+     uid: duser
+15 -&gt; mail: duser@example.com
+</pre>
+<br>
+
+</blockquote> 
+
+<p> Our first use case ignores the "memberdn" attributes, and assumes
+that groups hold only direct "memberaddr" strings as in (3), (4), (8) and
+(9). The goal is to map the group address to the list of constituent
+"memberaddr" values. This is simple, ignoring the various connection
+related settings (hosts, ports, bind settings, timeouts, ...) we have:
+</p>
+
+<blockquote> 
+<pre>
+    simple.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr
+    $ postmap -q agroup@example.com ldap:simple.cf
+    auser@example.org,buser@example.org
+</pre>
+</blockquote> 
+
+<p> We search "dc=example, dc=com". The "mail" attribute is used in the
+query_filter to locate the right group, the "result_attribute" setting
+described in ldap_table(5) is used to specify that "memberaddr" values
+from the matching group are to be returned as a comma separated list.
+Always check tables using postmap(1) with the "-q" option, before
+deploying them into production use in main.cf. </p>
+
+<p> Our second use case also expands "memberdn" attributes (1), (2),
+(6) and (7), follows the DN references and returns the "maildrop" of the
+referenced user entries. Here we use the "special_result_attribute"
+setting from ldap_table(5) to designate the "memberdn" attribute
+as holding DNs of the desired member entries. The "result_attribute"
+setting selects which attributes are returned from the selected DNs. It
+is important to choose a result attribute that is not also present in
+the group object, because result attributes are collected from both
+the group and the member DNs. In this case we choose "maildrop" and
+assume for the moment that groups never have a "maildrop" (the "bgroup"
+"maildrop" attribute is for a different use case). The returned data for
+"auser" and "buser" is from items (11) and (13) in the mock data. </p>
+
+<blockquote> 
+<pre>
+    special.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr, maildrop
+        special_result_attribute = memberdn
+    $ postmap -q agroup@example.com ldap:special.cf
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+</pre>
+</blockquote> 
+
+<p> Note: if the desired member object result attribute is always also
+present in the group, you get suprising results, the expansion also
+returns the address of the group. This is a known limitation of Postfix
+releases prior to 2.4, and is addressed in the new with Postfix 2.4
+"leaf_result_attribute" feature described in ldap_table(5). </p>
+
+<p> Our third use case has some groups that are expanded immediately,
+and other groups that are forwarded to a dedicated mailing list manager
+host for delayed expansion. This uses two LDAP tables, one for users
+and forwarded groups and a second for groups that can be expanded
+immediately. It is assumed that groups that require forwarding are
+never nested members of groups that are directly expanded. </p>
+
+<blockquote> 
+<pre>
+    no_expand.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = maildrop
+    expand.cf
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr, maildrop
+        special_result_attribute = memberdn
+    $ postmap -q auser@example.com ldap:no_expand.cf ldap:expand.cf
+    auser@mailhub.example.com
+    $ postmap -q agroup@example.com ldap:no_expand.cf ldap:expand.cf
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+    $ postmap -q bgroup@example.com ldap:no_expand.cf ldap:expand.cf
+    bgroup@mlm.example.com
+</pre>
+</blockquote> 
+
+<p> Non-group objects and groups with delayed expansion (those that have a
+maildrop attribute) are rewritten to a single maildrop value. Groups that
+don't have a maildrop are expanded as the second use case. This admits
+a more elegant solution with Postfix 2.4 and later. </p>
+
+<p> Our final use case is the same as the third, but this time uses new
+features in Postfix 2.4. We now are able to use just one LDAP table and
+no longer need to assume that forwarded groups are never nested inside
+expanded groups. </p>
+
+<blockquote> 
+<pre>
+    fancy.cf:
+        ...
+        search_base = dc=example, dc=com
+        query_filter = mail=%s
+        result_attribute = memberaddr
+        special_result_attribute = memberdn
+        terminal_result_attribute = maildrop
+        leaf_result_attribute = mail
+    $ postmap -q auser@example.com ldap:fancy.cf
+    auser@mailhub.example.com
+    $ postmap -q cuser@example.com ldap:fancy.cf
+    cuser@example.com
+    $ postmap -q agroup@example.com ldap:fancy.cf
+    auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+    $ postmap -q bgroup@example.com ldap:fancy.cf
+    bgroup@mlm.example.com
+</pre>
+</blockquote> 
+
+<p> Above, delayed expansion is enabled via "terminal_result_attribute",
+which, if present, is used as the sole result and all other expansion is
+suppressed. Otherwise, the "leaf_result_attribute" is only returned for
+leaf objects that don't have a "special_result_attribute" (non-groups),
+while the "result_attribute" (direct member address of groups) is returned
+at every level of recursive expansion, not just the leaf nodes. This fancy
+example illustrates all the features of Postfix 2.4 group expansion. </p>
+
 <h2><a name="other">Other uses of LDAP lookups</a></h2>
 
 Other common uses for LDAP lookups include rewriting senders and
 recipients with Postfix's canonical lookups, for example in order
 to make mail leaving your site appear to be coming from
-"First.Last@site.dom" instead of "userid@site.dom".
+"First.Last@example.com" instead of "userid@example.com".
 
 <h2><a name="hmmmm">Notes and things to think about</a></h2>
 
@@ -240,9 +451,9 @@ to make mail leaving your site appear to be coming from
 
 <blockquote>
 <pre>
-dn: cn=Accounting Staff List, dc=my, dc=com
+dn: cn=Accounting Staff List, dc=example, dc=com
 cn: Accounting Staff List
-o: my.com
+o: example.com
 objectclass: maillist
 mailacceptinggeneralid: accountingstaff
 mailacceptinggeneralid: accounting-staff
index d8d2d2ef0fd5591f4db169c677d12274b28a9a3f..8d11e7176ac93e45ef334ab50479d084efc5ff12 100644 (file)
@@ -16,6 +16,7 @@
 #
 #      In order to use LDAP lookups, define an LDAP source as a lookup
 #      table in main.cf, for example:
+#
 # .ti +4
 #      alias_maps = ldap:/etc/postfix/ldap-aliases.cf
 #
@@ -77,6 +78,7 @@
 #      return the key itself.
 #
 #      For example, NEVER do this in a map defining $mydestination:
+#
 # .in +4
 #      query_filter = domain=* 
 # .br
@@ -84,6 +86,7 @@
 # .in -4
 #
 #      Do this instead:
+#
 # .in +4
 #      query_filter = domain=%s 
 # .br
 #      strings.
 # .IP "\fBserver_host (default: localhost)\fR"
 #      The name of the host running the LDAP server, e.g.
+#
 # .ti +4
 #      server_host = ldap.example.com
 #
 #      trying them in order should the first one fail. It should also
 #      be possible to give each server in the list a different port
 #      (overriding \fBserver_port\fR below), by naming them like
+#
 # .ti +4
 #      server_host = ldap.example.com:1444
 #
 #      With OpenLDAP, a (list of) LDAP URLs can be used to specify both
 #      the hostname(s) and the port(s):
+#
 # .ti +4
 #      server_host = ldap://ldap.example.com:1444
 # .ti +8
 #      including connections over UNIX domain sockets, and LDAP SSL
 #      (the last one provided that OpenLDAP was compiled with support
 #      for SSL):
+#
 # .ti +4
 #      server_host = ldapi://%2Fsome%2Fpath
 # .ti +8
 #              ldaps://ldap.example.com:636
 # .IP "\fBserver_port (default: 389)\fR"
 #      The port the LDAP server listens on, e.g.
+#
 # .ti +4
 #      server_port = 778
 # .IP "\fBtimeout (default: 10 seconds)\fR"
 #      The number of seconds a search can take before timing out, e.g.
+#
 # .ti +4
 #      timeout = 5
 # .IP "\fBsearch_base (No default; you must configure this)\fR"
 #      The RFC2253 base DN at which to conduct the search, e.g.
+#
 # .ti +4
 #      search_base = dc=your, dc=com
 # .IP
 #      The RFC2254 filter used to search the directory, where \fB%s\fR
 #      is a substitute for the address Postfix is trying to resolve,
 #      e.g.
+#
 # .ti +4
 #      query_filter = (&(mail=%s)(paid_up=true))
 #
 #      are eligible for lookup: 'user' lookups, bare domain lookups
 #      and "@domain" lookups are not performed. This can significantly
 #      reduce the query load on the LDAP server.
+#
 # .ti +4
 #      domain = postfix.org, hash:/etc/postfix/searchdomains
 #
 #      The attribute(s) Postfix will read from any directory
 #      entries returned by the lookup, to be resolved to an email
 #      address.
+#
 # .ti +4
 #      result_attribute = mailbox, maildrop
-# .IP "\fBspecial_result_attribute (No default)\fR"
+# .IP "\fBspecial_result_attribute (default: empty)\fR"
 #      The attribute(s) of directory entries that can contain DNs
 #      or URLs. If found, a recursive subsequent search is done
 #      using their values.
+#
 # .ti +4
-#      special_result_attribute = member
+#      special_result_attribute = memberdn
 #
 #      DN recursion retrieves the same result_attributes as the
 #      main query, including the special attributes for further
 #      listed in "result_attribute". If the URI lists any of the
 #      map's special result attributes, these are also retrieved
 #      and used recursively.
+# .IP "\fBterminal_result_attribute (default: empty)\fR"
+#      When one or more terminal result attributes are found in an LDAP
+#      entry, all other result attributes are ignored and only the terminal
+#      result attributes are returned. This is useful for delegating expansion
+#      of group members to a particular host, by using an optional "maildrop"
+#      attribute on selected groups to route the group to a specific host,
+#      where the group is expanded, possibly via mailing-list manager or
+#      other special processing.
+#
+# .ti +4
+#      terminal_result_attribute = maildrop
+#
+#      This feature is available with Postfix >= 2.4.
+# .IP "\fBleaf_result_attribute (default: empty)\fR"
+#      When one or more special result attributes are found in a non-terminal
+#      (see above) LDAP entry, leaf result attributes are excluded from the
+#      expansion of that entry. This is useful when expanding groups and the
+#      desired mail address attribute(s) of the member objects obtained via
+#      DN or URI recursion are also present in the group object. To only
+#      return the attribute values from the leaf objects and not the
+#      containing group, add the attribute to the leaf_result_attribute list,
+#      and not the result_attribute list, which is always expanded. Note,
+#      the default value of "result_attribute" is not empty, you may want to
+#      set it explicitly empty when using "leaf_result_attribute" to expand
+#      the group to a list of member DN addresses. If groups have both
+#      member DN references AND attributes that hold multiple string valued
+#      rfc822 addresses, then the string attributes go in "result_attribute".
+#      The attributes that represent the email addresses of objects
+#      referenced via a DN (or LDAP URI) go in "leaf_result_attribute".
+#
+# .in +4
+#      result_attribute = memberaddr
+# .br
+#      special_result_attribute = memberdn
+# .br
+#      terminal_result_attribute = maildrop
+# .br
+#      leaf_result_attribute = mail
+# .in -4
+#
+#      This feature is available with Postfix >= 2.4.
 # .IP "\fBscope (default: sub)\fR"
 #      The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR.
 #      These translate into LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE,
 #      Whether or not to bind to the LDAP server. Newer LDAP
 #      implementations don't require clients to bind, which saves
 #      time. Example:
+#
 # .ti +4
 #      bind = no
 #
 #      the clear.
 # .IP "\fBbind_dn (default: empty)\fR"
 #      If you do have to bind, do it with this distinguished name. Example:
+#
 # .ti +4
 #      bind_dn = uid=postfix, dc=your, dc=com
 # .IP "\fBbind_pw (default: empty)\fR"
 #      password. This is because main.cf needs to be world readable
 #      to allow local accounts to submit mail via the sendmail
 #      command. Example:
+#
 # .ti +4
 #      bind_pw = postfixpw
 # .IP "\fBcache (IGNORED with a warning)\fR"
 #
 #      LDAP SSL service can be requested by using a LDAP SSL URL
 #      in the server_host parameter:
+#
 # .ti +4
 #      server_host = ldaps://ldap.example.com:636
 #
 #      STARTTLS can be turned on with the start_tls parameter:
+#
 # .ti +4
 #      start_tls = yes
 #
 #      Both forms require LDAP protocol version 3, which has to be set
 #      explicitly with:
+#
 # .ti +4
 #      version = 3
 #
 #      Here's a basic example for using LDAP to look up local(8)
 #      aliases.
 #      Assume that in main.cf, you have:
+#
 # .ti +4
 #      alias_maps = hash:/etc/aliases,
 # .ti +8
 #      ldap:/etc/postfix/ldap-aliases.cf
 #
 #      and in ldap:/etc/postfix/ldap-aliases.cf you have:
+#
 # .in +4
-#      server_host = ldap.my.com
+#      server_host = ldap.example.com
 # .br
-#      search_base = dc=my, dc=com
+#      search_base = dc=example, dc=com
 # .in -4
 #
 #      Upon receiving mail for a local address "ldapuser" that
 #      isn't found in the /etc/aliases database, Postfix will
-#      search the LDAP server listening at port 389 on ldap.my.com.
+#      search the LDAP server listening at port 389 on ldap.example.com.
 #      It will bind anonymously, search for any directory entries
 #      whose mailacceptinggeneralid attribute is "ldapuser", read
 #      the "maildrop" attributes of those found, and build a list
index 62946461e1392ddf838b0f114708d5ff79f68e9f..14772fa32222505f15e09eb9b9a72ac2b29bde74 100644 (file)
@@ -67,6 +67,7 @@ anvil.o: ../../include/mail_conf.h
 anvil.o: ../../include/mail_params.h
 anvil.o: ../../include/mail_proto.h
 anvil.o: ../../include/mail_server.h
+anvil.o: ../../include/mail_version.h
 anvil.o: ../../include/msg.h
 anvil.o: ../../include/mymalloc.h
 anvil.o: ../../include/stringops.h
index 0308f8d266b11f7288e08d5b4a3a6fafe9e88b92..ab42073a495eb4afb36639d05a663cb550eb151a 100644 (file)
 
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>
 #include <anvil_clnt.h>
 
@@ -945,6 +946,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
        var_idle_limit = var_anvil_time_unit;
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the multi-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -955,6 +958,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     multi_server_main(argc, argv, anvil_service,
                      MAIL_SERVER_TIME_TABLE, time_table,
                      MAIL_SERVER_POST_INIT, post_jail_init,
index ddfaaa2eb0a91aca5014e5df667efbf2df8b3a75..09de6e9d0ae5b258498f667a702f3837b4b81318 100644 (file)
@@ -107,6 +107,7 @@ bounce.o: ../../include/mail_params.h
 bounce.o: ../../include/mail_proto.h
 bounce.o: ../../include/mail_queue.h
 bounce.o: ../../include/mail_server.h
+bounce.o: ../../include/mail_version.h
 bounce.o: ../../include/msg.h
 bounce.o: ../../include/msg_stats.h
 bounce.o: ../../include/rcpt_buf.h
@@ -166,6 +167,7 @@ bounce_notify_service.o: ../../include/deliver_request.h
 bounce_notify_service.o: ../../include/dsn.h
 bounce_notify_service.o: ../../include/dsn_buf.h
 bounce_notify_service.o: ../../include/dsn_mask.h
+bounce_notify_service.o: ../../include/int_filt.h
 bounce_notify_service.o: ../../include/mail_addr.h
 bounce_notify_service.o: ../../include/mail_error.h
 bounce_notify_service.o: ../../include/mail_params.h
@@ -191,6 +193,7 @@ bounce_notify_util.o: ../../include/dsn.h
 bounce_notify_util.o: ../../include/dsn_buf.h
 bounce_notify_util.o: ../../include/dsn_mask.h
 bounce_notify_util.o: ../../include/events.h
+bounce_notify_util.o: ../../include/int_filt.h
 bounce_notify_util.o: ../../include/iostuff.h
 bounce_notify_util.o: ../../include/is_header.h
 bounce_notify_util.o: ../../include/lex_822.h
@@ -228,6 +231,7 @@ bounce_notify_verp.o: ../../include/deliver_request.h
 bounce_notify_verp.o: ../../include/dsn.h
 bounce_notify_verp.o: ../../include/dsn_buf.h
 bounce_notify_verp.o: ../../include/dsn_mask.h
+bounce_notify_verp.o: ../../include/int_filt.h
 bounce_notify_verp.o: ../../include/mail_addr.h
 bounce_notify_verp.o: ../../include/mail_error.h
 bounce_notify_verp.o: ../../include/mail_params.h
@@ -254,6 +258,7 @@ bounce_one_service.o: ../../include/deliver_request.h
 bounce_one_service.o: ../../include/dsn.h
 bounce_one_service.o: ../../include/dsn_buf.h
 bounce_one_service.o: ../../include/dsn_mask.h
+bounce_one_service.o: ../../include/int_filt.h
 bounce_one_service.o: ../../include/mail_addr.h
 bounce_one_service.o: ../../include/mail_error.h
 bounce_one_service.o: ../../include/mail_params.h
@@ -309,6 +314,7 @@ bounce_trace_service.o: ../../include/deliver_request.h
 bounce_trace_service.o: ../../include/dsn.h
 bounce_trace_service.o: ../../include/dsn_buf.h
 bounce_trace_service.o: ../../include/dsn_mask.h
+bounce_trace_service.o: ../../include/int_filt.h
 bounce_trace_service.o: ../../include/mail_addr.h
 bounce_trace_service.o: ../../include/mail_error.h
 bounce_trace_service.o: ../../include/mail_params.h
@@ -332,6 +338,7 @@ bounce_warn_service.o: ../../include/cleanup_user.h
 bounce_warn_service.o: ../../include/dsn.h
 bounce_warn_service.o: ../../include/dsn_buf.h
 bounce_warn_service.o: ../../include/dsn_mask.h
+bounce_warn_service.o: ../../include/int_filt.h
 bounce_warn_service.o: ../../include/mail_addr.h
 bounce_warn_service.o: ../../include/mail_error.h
 bounce_warn_service.o: ../../include/mail_params.h
index bef13b961619f9568bcca6edb1156d035654b4cd..483aa54c97afbba66374bee8283dfd9f8e758dc3 100644 (file)
 #include <mail_proto.h>
 #include <mail_queue.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <bounce.h>
 #include <mail_addr.h>
@@ -576,8 +577,8 @@ static void post_jail_init(char *service_name, char **unused_argv)
     /*
      * Special case: dump bounce templates. This is not part of the master(5)
      * public interface. This internal interface is used by the postconf
-     * command. It was implemented before bounce templates were isolated
-     * into modules that could have been called directly.
+     * command. It was implemented before bounce templates were isolated into
+     * modules that could have been called directly.
      */
     if (strcmp(service_name, "dump_templates") == 0) {
        bounce_templates_dump(VSTREAM_OUT, bounce_templates);
@@ -604,6 +605,8 @@ static void post_jail_init(char *service_name, char **unused_argv)
     dsn_buf = dsb_create();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -626,6 +629,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Pass control to the single-threaded service skeleton.
      */
index ecd317a6cd0d3cb6f1da01eb2987a15a0fd02960..fa98471aec0908003c7698eab1eb8587125c140b 100644 (file)
@@ -319,6 +319,7 @@ cleanup.o: ../../include/mail_params.h
 cleanup.o: ../../include/mail_proto.h
 cleanup.o: ../../include/mail_server.h
 cleanup.o: ../../include/mail_stream.h
+cleanup.o: ../../include/mail_version.h
 cleanup.o: ../../include/maps.h
 cleanup.o: ../../include/match_list.h
 cleanup.o: ../../include/match_ops.h
index 0f41b8a3b6f7770714ff3f8d058f0015b5df6191..5747f8c94bdff7c912b5241608cb3fb3198c29e8 100644 (file)
 #include <mail_params.h>
 #include <record.h>
 #include <rec_type.h>
+#include <mail_version.h>
 
 /* Single-threaded server skeleton. */
 
@@ -502,11 +503,18 @@ static void pre_accept(char *unused_name, char **unused_argv)
     }
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
 {
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Clean up an incomplete queue file in case of a fatal run-time error,
      * or after receiving SIGTERM from the master at shutdown time.
index e39100098059f4b4e75a101ca492a61e682a40e6..00a5d5c34a5d6eb336766b64621d5b598b076323 100644 (file)
@@ -67,6 +67,7 @@ discard.o: ../../include/dsn_util.h
 discard.o: ../../include/flush_clnt.h
 discard.o: ../../include/mail_queue.h
 discard.o: ../../include/mail_server.h
+discard.o: ../../include/mail_version.h
 discard.o: ../../include/msg.h
 discard.o: ../../include/msg_stats.h
 discard.o: ../../include/recipient_list.h
index 2e7b24b31f047f0a7152b360e84bd0882b56386d..17bdeceeed49f3fd69231daccd186fbec8d9b55d 100644 (file)
 #include <flush_clnt.h>
 #include <sent.h>
 #include <dsn_util.h>
+#include <mail_version.h>
 
 /* Single server skeleton. */
 
@@ -225,10 +226,18 @@ static void pre_init(char *unused_name, char **unused_argv)
     flush_init();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
 {
+
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, discard_service,
                       MAIL_SERVER_PRE_INIT, pre_init,
                       0);
index 8e1d097c5d51731331821f30772e64b5985de372..a9453126feca03e873dea5c430c222ab59f32905 100644 (file)
@@ -70,6 +70,7 @@ error.o: ../../include/iostuff.h
 error.o: ../../include/mail_proto.h
 error.o: ../../include/mail_queue.h
 error.o: ../../include/mail_server.h
+error.o: ../../include/mail_version.h
 error.o: ../../include/msg.h
 error.o: ../../include/msg_stats.h
 error.o: ../../include/recipient_list.h
index 6887ddd522534ac3fce29e6bb3d793f53958e96b..019900b2b957624099b05ce74812c45142446fe6 100644 (file)
 #include <dsn_util.h>
 #include <sys_exits.h>
 #include <mail_proto.h>
+#include <mail_version.h>
 
 /* Single server skeleton. */
 
@@ -237,10 +238,18 @@ static void pre_init(char *unused_name, char **unused_argv)
     flush_init();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
 {
+
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, error_service,
                       MAIL_SERVER_PRE_INIT, pre_init,
                       0);
index 8144eabbfd582cef1ebdc42ba25bcd9b5b94f038..7578940f561165e2320c9cf380c8d0a57d43210a 100644 (file)
@@ -72,6 +72,7 @@ flush.o: ../../include/mail_proto.h
 flush.o: ../../include/mail_queue.h
 flush.o: ../../include/mail_scan_dir.h
 flush.o: ../../include/mail_server.h
+flush.o: ../../include/mail_version.h
 flush.o: ../../include/maps.h
 flush.o: ../../include/match_list.h
 flush.o: ../../include/match_ops.h
index bfa4ca5744a4d8f0f20c5c1cd28a6251dc5175b2..41ffafa87f14719a43f3e184148cfb8b91dc335e 100644 (file)
 /* Global library. */
 
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_queue.h>
 #include <mail_proto.h>
 #include <mail_flush.h>
@@ -387,7 +388,7 @@ static int flush_send_service(const char *site, int how)
 /* flush_one_file - move one queue file to incoming queue */
 
 static int flush_one_file(const char *queue_id, VSTRING *queue_file,
-                                   struct utimbuf * tbuf, int how)
+                                 struct utimbuf * tbuf, int how)
 {
     const char *myname = "flush_one_file";
     const char *queue_name;
@@ -807,6 +808,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                                     var_fflush_domains);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -817,6 +820,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, flush_service,
                       MAIL_SERVER_TIME_TABLE, time_table,
                       MAIL_SERVER_PRE_INIT, pre_jail_init,
index 26ff50c1e3716bf7ea41764135772985102c5834..02674123162a6f1b5237ff76786c43a8993be219 100644 (file)
@@ -150,6 +150,8 @@ static void usage(char *myname)
     msg_fatal("usage: %s [-cr] [-s size] messages directory_entries", myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     int     op_count;
@@ -161,6 +163,11 @@ int     main(int argc, char **argv)
     int     ch;
     int     size = 2;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     msg_vstream_init(argv[0], VSTREAM_ERR);
     while ((ch = GETOPT(argc, argv, "crs:")) != EOF) {
        switch (ch) {
index 49e288d8916bfbfd70c3317c594391f6456633b5..b6c602f0b928f35849106b1239587e222f70b689 100644 (file)
@@ -890,10 +890,12 @@ input_transp.o: cleanup_user.h
 input_transp.o: input_transp.c
 input_transp.o: input_transp.h
 input_transp.o: mail_params.h
+int_filt.o: ../../include/msg.h
 int_filt.o: ../../include/name_mask.h
 int_filt.o: ../../include/sys_defs.h
 int_filt.o: ../../include/vbuf.h
 int_filt.o: ../../include/vstring.h
+int_filt.o: cleanup_user.h
 int_filt.o: int_filt.c
 int_filt.o: int_filt.h
 int_filt.o: mail_params.h
@@ -1462,6 +1464,7 @@ post_mail.o: ../../include/vbuf.h
 post_mail.o: ../../include/vstream.h
 post_mail.o: ../../include/vstring.h
 post_mail.o: cleanup_user.h
+post_mail.o: int_filt.h
 post_mail.o: mail_date.h
 post_mail.o: mail_params.h
 post_mail.o: mail_proto.h
index efd8c39271e794a5149018f6c8ef32298516d400..fd35579d26ed488e7b94283b6e23e93b79c425e0 100644 (file)
 /* .IP special_result_attribute
 /*     The attribute(s) of directory entries that can contain DNs or URLs.
 /*     If found, a recursive subsequent search is done using their values.
+/* .IP leaf_result_attribute
+/*     These are only returned for "leaf" LDAP entries, i.e. those that are
+/*     not "terminal" and have no values for any of the "special" result
+/*     attributes.
+/* .IP terminal_result_attribute
+/*     If found, the LDAP entry is considered a terminal LDAP object, not
+/*     subject to further direct or recursive expansion. Only the terminal
+/*     result attributes are returned.
 /* .IP scope
 /*     LDAP search scope: sub, base, or one.
 /* .IP bind
@@ -228,7 +236,9 @@ typedef struct {
     int     scope;
     char   *search_base;
     ARGV   *result_attributes;
-    int     num_attributes;            /* rest of list is DN's. */
+    int     num_terminal;              /* Number of terminal attributes. */
+    int     num_leaf;                  /* Number of leaf attributes */
+    int     num_attributes;            /* Combined # of non-special attrs */
     int     bind;
     char   *bind_dn;
     char   *bind_pw;
@@ -256,7 +266,16 @@ typedef struct {
 
 #define DICT_LDAP_CONN(d) ((LDAP_CONN *)((d)->ht->value))
 
-
+ /*
+  * Bitrot: LDAP_API 3000 and up (OpenLDAP 2.2.x) deprecated ldap_unbind()
+  */
+#if LDAP_API_VERSION >= 3000
+#define dict_ldap_unbind(ld)           ldap_unbind_ext((ld), 0, 0)
+#define dict_ldap_abandon(ld, msg)     ldap_abandon_ext((ld), (msg), 0, 0)
+#else
+#define dict_ldap_unbind(ld)           ldap_unbind(ld)
+#define dict_ldap_abandon(ld, msg)     ldap_abandon((ld), (msg))
+#endif
 
 /*
  * Quoting rules.
@@ -325,8 +344,7 @@ static void dict_ldap_timeout(int unused_sig)
 static void dict_ldap_logprint(LDAP_CONST char *data)
 {
     const char *myname = "dict_ldap_debug";
-    char   *buf,
-           *p;
+    char   *buf, *p;
 
     buf = mystrdup(data);
     if (*buf) {
@@ -338,7 +356,7 @@ static void dict_ldap_logprint(LDAP_CONST char *data)
     myfree(buf);
 }
 
-static int dict_ldap_get_errno(LDAP * ld)
+static int dict_ldap_get_errno(LDAP *ld)
 {
     int     rc;
 
@@ -347,7 +365,7 @@ static int dict_ldap_get_errno(LDAP * ld)
     return rc;
 }
 
-static int dict_ldap_set_errno(LDAP * ld, int rc)
+static int dict_ldap_set_errno(LDAP *ld, int rc)
 {
     (void) ldap_set_option(ld, LDAP_OPT_ERROR_NUMBER, &rc);
     return rc;
@@ -367,10 +385,9 @@ static int dict_ldap_result(LDAP *ld, int msgid, int timeout, LDAPMessage **res)
        return (dict_ldap_get_errno(ld));
 
     if (dict_ldap_get_errno(ld) == LDAP_TIMEOUT) {
-       (void) ldap_abandon_ext(ld, msgid, 0, 0);
+       (void) dict_ldap_abandon(ld, msgid);
        return (dict_ldap_set_errno(ld, LDAP_TIMEOUT));
     }
-
     return LDAP_SUCCESS;
 }
 
@@ -400,7 +417,7 @@ static int dict_ldap_bind_st(DICT_LDAP *dict_ldap)
 /* search_st - Synchronous search with timeout */
 
 static int search_st(LDAP *ld, char *base, int scope, char *query,
-                           char **attrs, int timeout, LDAPMessage **res)
+                            char **attrs, int timeout, LDAPMessage **res)
 {
     struct timeval mytimeval;
     int     msgid;
@@ -411,7 +428,7 @@ static int search_st(LDAP *ld, char *base, int scope, char *query,
     mytimeval.tv_usec = 0;
 
 #define WANTVALS 0
-#define USE_SIZE_LIM_OPT -1            /* Any negative value will do */
+#define USE_SIZE_LIM_OPT -1                    /* Any negative value will do */
 
     if ((rc = ldap_search_ext(ld, base, scope, query, attrs, WANTVALS, 0, 0,
                              &mytimeval, USE_SIZE_LIM_OPT,
@@ -506,7 +523,7 @@ static int dict_ldap_connect(DICT_LDAP *dict_ldap)
 #if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
     if (dict_ldap->debuglevel > 0 &&
        ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN,
-                    (LDAP_CONST void *) dict_ldap_logprint) != LBER_OPT_SUCCESS)
+               (LDAP_CONST void *) dict_ldap_logprint) != LBER_OPT_SUCCESS)
        msg_warn("%s: Unable to set ber logprint function.", myname);
 #if defined(LBER_OPT_DEBUG_LEVEL)
     if (ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL,
@@ -752,8 +769,8 @@ static void dict_ldap_conn_find(DICT_LDAP *dict_ldap)
  * This and the rest of the handling of multiple attributes, DNs and URLs
  * are thanks to LaMont Jones.
  */
-static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
-                                        VSTRING *result, const charname)
+static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
+                                        VSTRING *result, const char *name)
 {
     static int recursion = 0;
     static int expansion;
@@ -768,6 +785,8 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
     int     valcount;
     LDAPURLDesc *url;
     const char *myname = "dict_ldap_get_values";
+    int     is_leaf = 1;               /* No recursion via this entry */
+    int     is_terminal = 0;           /* No expansion via this entry */
 
     if (++recursion == 1)
        expansion = 0;
@@ -792,10 +811,45 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
                     dict_ldap->size_limit);
            dict_errno = DICT_ERR_RETRY;
        }
+
+       /*
+        * Check for terminal attributes, these preclude expansion of all
+        * other attributes, and DN/URI recursion. Any terminal attributes
+        * are listed first in the attribute array.
+        */
+       if (dict_ldap->num_terminal > 0) {
+           for (i = 0; i < dict_ldap->num_terminal; ++i) {
+               attr = dict_ldap->result_attributes->argv[i];
+               if (!(vals = ldap_get_values_len(dict_ldap->ld, entry, attr)))
+                   continue;
+               is_terminal = (ldap_count_values_len(vals) > 0);
+               ldap_value_free_len(vals);
+               if (is_terminal)
+                   break;
+           }
+       }
+
+       /*
+        * Check for special attributes, these preclude expansion of
+        * "leaf-only" attributes, and are at the end of the attribute array
+        * after the terminal, leaf and regular attributes.
+        */
+       if (is_terminal == 0 && dict_ldap->num_leaf > 0) {
+           for (i = dict_ldap->num_attributes;
+                dict_ldap->result_attributes->argv[i]; ++i) {
+               attr = dict_ldap->result_attributes->argv[i];
+               if (!(vals = ldap_get_values_len(dict_ldap->ld, entry, attr)))
+                   continue;
+               is_leaf = (ldap_count_values_len(vals) == 0);
+               ldap_value_free_len(vals);
+               if (!is_leaf)
+                   break;
+           }
+       }
        for (attr = ldap_first_attribute(dict_ldap->ld, entry, &ber);
-            attr != NULL;
-            ldap_memfree(attr), attr = ldap_next_attribute(dict_ldap->ld,
-                                                           entry, ber)) {
+            attr != NULL; ldap_memfree(attr),
+            attr = ldap_next_attribute(dict_ldap->ld, entry, ber)) {
+
            vals = ldap_get_values_len(dict_ldap->ld, entry, attr);
            if (vals == NULL) {
                if (msg_verbose)
@@ -803,7 +857,6 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
                             myname, recursion, attr);
                continue;
            }
-
            valcount = ldap_count_values_len(vals);
 
            /*
@@ -830,36 +883,47 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
             * We compute the attribute type (ordinary or special) from its
             * index on the "result_attributes" list.
             */
-           for (i = 0; dict_ldap->result_attributes->argv[i]; i++) {
-               if (strcasecmp(dict_ldap->result_attributes->argv[i], attr) == 0)
+           for (i = 0; dict_ldap->result_attributes->argv[i]; i++)
+               if (strcasecmp(dict_ldap->result_attributes->argv[i],
+                              attr) == 0)
                    break;
-           }
 
            /*
             * Append each returned address to the result list, possibly
-            * recursing (for dn or url attributes).
+            * recursing (for dn or url attributes of non-terminal entries)
             */
-           if (i < dict_ldap->num_attributes) {
-               /* Ordinary result attribute */
-               for (i = 0; i < valcount; i++) {
-                   if (db_common_expand(dict_ldap->ctx,
-                                        dict_ldap->result_format,
-                                        vals[i]->bv_val,
-                                        name, result, 0)
-                       && dict_ldap->expansion_limit > 0
-                       && ++expansion > dict_ldap->expansion_limit) {
-                       msg_warn("%s[%d]: %s: Expansion limit exceeded for key: '%s'",
-                                myname, recursion, dict_ldap->parser->name, name);
-                       dict_errno = DICT_ERR_RETRY;
-                       break;
+           if (i < dict_ldap->num_attributes || is_terminal) {
+               if (is_terminal && i >= dict_ldap->num_terminal
+                   || !is_leaf &&
+                   i < dict_ldap->num_terminal + dict_ldap->num_leaf) {
+                   if (msg_verbose)
+                       msg_info("%s[%d]: skipping %ld value(s) of %s "
+                                "attribute %s", myname, recursion, i,
+                                is_terminal ? "non-terminal" : "leaf-only",
+                                attr);
+               } else {
+                   /* Ordinary result attribute */
+                   for (i = 0; i < valcount; i++) {
+                       if (db_common_expand(dict_ldap->ctx,
+                                            dict_ldap->result_format,
+                                            vals[i]->bv_val,
+                                            name, result, 0)
+                           && dict_ldap->expansion_limit > 0
+                           && ++expansion > dict_ldap->expansion_limit) {
+                           msg_warn("%s[%d]: %s: Expansion limit exceeded "
+                                    "for key: '%s'", myname, recursion,
+                                    dict_ldap->parser->name, name);
+                           dict_errno = DICT_ERR_RETRY;
+                           break;
+                       }
                    }
+                   if (dict_errno != 0)
+                       continue;
+                   if (msg_verbose)
+                       msg_info("%s[%d]: search returned %ld value(s) for"
+                                " requested result attribute %s",
+                                myname, recursion, i, attr);
                }
-               if (dict_errno != 0)
-                   continue;
-               if (msg_verbose)
-                   msg_info("%s[%d]: search returned %ld value(s) for"
-                            " requested result attribute %s",
-                            myname, recursion, i, attr);
            } else if (recursion < dict_ldap->recursion_limit
                       && dict_ldap->result_attributes->argv[i]) {
                /* Special result attribute */
@@ -872,7 +936,7 @@ static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
                        if (rc == 0) {
                            rc = search_st(dict_ldap->ld, url->lud_dn,
                                           url->lud_scope, url->lud_filter,
-                                          url->lud_attrs, dict_ldap->timeout,
+                                        url->lud_attrs, dict_ldap->timeout,
                                           &resloop);
                            ldap_free_urldesc(url);
                        }
@@ -973,7 +1037,6 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
            msg_info("%s: Skipping lookup of '%s'", myname, name);
        return (0);
     }
-
 #define INIT_VSTR(buf, len) do { \
        if (buf == 0) \
            buf = vstring_alloc(len); \
@@ -1026,28 +1089,27 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
                 myname, dict_ldap->parser->name, dict_ldap->size_limit);
 
     /*
-     * Expand the search base and query. Skip lookup when the
-     * input key lacks sufficient domain components to satisfy
-     * all the requested %-substitutions.
-     *
-     * When the search base is not static, LDAP_NO_SUCH_OBJECT is
-     * expected and is therefore treated as a non-error: the lookup
-     * returns no results rather than a soft error.
+     * Expand the search base and query. Skip lookup when the input key lacks
+     * sufficient domain components to satisfy all the requested
+     * %-substitutions.
+     * 
+     * When the search base is not static, LDAP_NO_SUCH_OBJECT is expected and
+     * is therefore treated as a non-error: the lookup returns no results
+     * rather than a soft error.
      */
     if (!db_common_expand(dict_ldap->ctx, dict_ldap->search_base,
-                         name, 0, base, rfc2253_quote)) {
-        if (msg_verbose > 1)
+                         name, 0, base, rfc2253_quote)) {
+       if (msg_verbose > 1)
            msg_info("%s: %s: Empty expansion for %s", myname,
                     dict_ldap->parser->name, dict_ldap->search_base);
-        return (0);
+       return (0);
     }
-
     if (!db_common_expand(dict_ldap->ctx, dict_ldap->query,
                          name, 0, query, rfc2254_quote)) {
-        if (msg_verbose > 1)
+       if (msg_verbose > 1)
            msg_info("%s: %s: Empty expansion for %s", myname,
                     dict_ldap->parser->name, dict_ldap->query);
-        return (0);
+       return (0);
     }
 
     /*
@@ -1066,7 +1128,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
            msg_info("%s: Lost connection for LDAP source %s, reopening",
                     myname, dict_ldap->parser->name);
 
-       ldap_unbind_ext(dict_ldap->ld, 0, 0);
+       dict_ldap_unbind(dict_ldap->ld);
        dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld = 0;
        dict_ldap_connect(dict_ldap);
 
@@ -1077,14 +1139,14 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
            return (0);
 
        rc = search_st(dict_ldap->ld, vstring_str(base), dict_ldap->scope,
-                      vstring_str(query), dict_ldap->result_attributes->argv,
+                    vstring_str(query), dict_ldap->result_attributes->argv,
                       dict_ldap->timeout, &res);
 
     }
-
     switch (rc) {
 
     case LDAP_SUCCESS:
+
        /*
         * Search worked; extract the requested result_attribute.
         */
@@ -1109,12 +1171,13 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
        break;
 
     case LDAP_NO_SUCH_OBJECT:
-        /*
-        * If the search base is input key dependent, then not finding it,
-        * is equivalent to not finding the input key. Sadly, we cannot
-        * detect misconfiguration in this case.
+
+       /*
+        * If the search base is input key dependent, then not finding it, is
+        * equivalent to not finding the input key. Sadly, we cannot detect
+        * misconfiguration in this case.
         */
-       if (dict_ldap->dynamic_base)
+       if (dict_ldap->dynamic_base)
            break;
 
        msg_warn("%s: %s: Search base '%s' not found: %d: %s",
@@ -1124,6 +1187,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
        break;
 
     default:
+
        /*
         * Rats. The search didn't work.
         */
@@ -1134,7 +1198,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
         * Tear down the connection so it gets set up from scratch on the
         * next lookup.
         */
-       ldap_unbind_ext(dict_ldap->ld, 0, 0);
+       dict_ldap_unbind(dict_ldap->ld);
        dict_ldap->ld = DICT_LDAP_CONN(dict_ldap)->conn_ld = 0;
 
        /*
@@ -1171,7 +1235,7 @@ static void dict_ldap_close(DICT *dict)
            if (msg_verbose)
                msg_info("%s: Closed connection handle for LDAP source %s",
                         myname, dict_ldap->parser->name);
-           ldap_unbind_ext(conn->conn_ld, 0, 0);
+           dict_ldap_unbind(conn->conn_ld);
        }
        binhash_delete(conn_hash, ht->key, ht->key_len, myfree);
     }
@@ -1180,7 +1244,7 @@ static void dict_ldap_close(DICT *dict)
     myfree(dict_ldap->search_base);
     myfree(dict_ldap->query);
     if (dict_ldap->result_format)
-        myfree(dict_ldap->result_format);
+       myfree(dict_ldap->result_format);
     argv_free(dict_ldap->result_attributes);
     myfree(dict_ldap->bind_dn);
     myfree(dict_ldap->bind_pw);
@@ -1282,11 +1346,11 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
                dict_ldap->ldap_ssl = 1;
            ldap_free_urldesc(url_desc);
            if (VSTRING_LEN(url_list) > 0)
-               VSTRING_ADDCH(url_list, ' ');
+               VSTRING_ADDCH(url_list, ' ');
            vstring_strcat(url_list, h);
        } else {
            if (VSTRING_LEN(url_list) > 0)
-               VSTRING_ADDCH(url_list, ' ');
+               VSTRING_ADDCH(url_list, ' ');
            if (strrchr(h, ':'))
                vstring_sprintf_append(url_list, "ldap://%s", h);
            else
@@ -1344,24 +1408,26 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
      */
     dict_ldap->timeout = cfg_get_int(dict_ldap->parser, "timeout", 10, 0, 0);
 
-#if 0  /* No benefit from changing this to match the MySQL/PGSQL syntax */
+#if 0                                          /* No benefit from changing
+                                                * this to match the
+                                                * MySQL/PGSQL syntax */
     if ((dict_ldap->query =
-            cfg_get_str(dict_ldap->parser, "query", 0, 0, 0)) == 0)
+        cfg_get_str(dict_ldap->parser, "query", 0, 0, 0)) == 0)
 #endif
-        dict_ldap->query =
+       dict_ldap->query =
            cfg_get_str(dict_ldap->parser, "query_filter",
                        "(mailacceptinggeneralid=%s)", 0, 0);
 
     if ((dict_ldap->result_format =
-        cfg_get_str(dict_ldap->parser, "result_format", 0, 0, 0)) == 0)
-        dict_ldap->result_format =
-                cfg_get_str(dict_ldap->parser, "result_filter", "%s", 1, 0);
+        cfg_get_str(dict_ldap->parser, "result_format", 0, 0, 0)) == 0)
+       dict_ldap->result_format =
+           cfg_get_str(dict_ldap->parser, "result_filter", "%s", 1, 0);
 
     /*
-     * Must parse all templates before we can use db_common_expand()
-     * If data dependent substitutions are found in the search base,
-     * treat NO_SUCH_OBJECT search errors as a non-matching key, rather
-     * than a fatal run-time error.
+     * Must parse all templates before we can use db_common_expand() If data
+     * dependent substitutions are found in the search base, treat
+     * NO_SUCH_OBJECT search errors as a non-matching key, rather than a
+     * fatal run-time error.
      */
     dict_ldap->ctx = 0;
     dict_ldap->dynamic_base =
@@ -1375,8 +1441,8 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     db_common_parse_domain(dict_ldap->parser, dict_ldap->ctx);
 
     /*
-     * Maps that use substring keys should only be used with the full
-     * input key.
+     * Maps that use substring keys should only be used with the full input
+     * key.
      */
     if (db_common_dict_partial(dict_ldap->ctx))
        dict_ldap->dict.flags |= DICT_FLAG_PATTERN;
@@ -1385,14 +1451,29 @@ DICT   *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
     if (dict_flags & DICT_FLAG_FOLD_FIX)
        dict_ldap->dict.fold_buf = vstring_alloc(10);
 
-    attr = cfg_get_str(dict_ldap->parser, "result_attribute",
-                      "maildrop", 0, 0);
+    /* Order matters, first the terminal attributes: */
+    attr = cfg_get_str(dict_ldap->parser, "terminal_result_attribute", "", 0, 0);
     dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
+    dict_ldap->num_terminal = dict_ldap->result_attributes->argc;
+    myfree(attr);
+
+    /* Order matters, next the leaf-only attributes: */
+    attr = cfg_get_str(dict_ldap->parser, "leaf_result_attribute", "", 0, 0);
+    if (*attr)
+       argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
+    dict_ldap->num_leaf =
+       dict_ldap->result_attributes->argc - dict_ldap->num_terminal;
+    myfree(attr);
+
+    /* Order matters, next the regular attributes: */
+    attr = cfg_get_str(dict_ldap->parser, "result_attribute", "maildrop", 0, 0);
+    if (*attr)
+       argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
     dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
     myfree(attr);
 
-    attr = cfg_get_str(dict_ldap->parser, "special_result_attribute",
-                      "", 0, 0);
+    /* Order matters, finally the special attributes: */
+    attr = cfg_get_str(dict_ldap->parser, "special_result_attribute", "", 0, 0);
     if (*attr)
        argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
     myfree(attr);
index cc2666ba647c7d6b410612bd6a96001cb9916a55..652d504579c0722494048004ffb9cf9a00e90922 100644 (file)
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20070312"
-#define MAIL_VERSION_NUMBER    "2.4.0-RC5"
+#define MAIL_RELEASE_DATE      "20070317"
+#define MAIL_VERSION_NUMBER    "2.4.0-RC6"
 
 #ifdef SNAPSHOT
 # define MAIL_VERSION_DATE     "-" MAIL_RELEASE_DATE
@@ -47,6 +47,24 @@ extern char *var_mail_version;
 #define DEF_MAIL_RELEASE       MAIL_RELEASE_DATE
 extern char *var_mail_release;
 
+ /*
+  * The following macros stamp executable files as well as core dumps. This
+  * information helps to answer the following questions:
+  * 
+  * - What Postfix versions(s) are installed on this machine?
+  * 
+  * - Is this installation mixing multiple Postfix versions?
+  * 
+  * - What Postfix version generated this core dump?
+  */
+#include <string.h>
+
+#define MAIL_VERSION_STAMP_DECLARE \
+    char *mail_version_stamp
+
+#define MAIL_VERSION_STAMP_ALLOCATE \
+    mail_version_stamp = strdup(VAR_MAIL_VERSION "=" DEF_MAIL_VERSION)
+
 /* LICENSE
 /* .ad
 /* .fi
index bd9814b5f7d0a63b1a4322faa10bf67a20feffd2..f22a5646e0c3b72e8344063ebc8fb1812328d91e 100644 (file)
@@ -353,6 +353,7 @@ local.o: ../../include/mail_addr.h
 local.o: ../../include/mail_conf.h
 local.o: ../../include/mail_params.h
 local.o: ../../include/mail_server.h
+local.o: ../../include/mail_version.h
 local.o: ../../include/maps.h
 local.o: ../../include/mbox_conf.h
 local.o: ../../include/msg.h
index c24a55d55027097efad07853f29aca00e09688d2..557be6f4d0a5eae37c6a6b386b4f1813e487bfd4 100644 (file)
 #include <mail_conf.h>
 #include <been_here.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <ext_prop.h>
 #include <maps.h>
 #include <flush_clnt.h>
@@ -845,6 +846,8 @@ static void pre_init(char *unused_name, char **unused_argv)
     flush_init();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -896,6 +899,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, local_service,
                       MAIL_SERVER_INT_TABLE, int_table,
                       MAIL_SERVER_STR_TABLE, str_table,
index 2138f0a485822fe17c500ca7d59b52225739e95d..d8230c1b769b822fc38414cfe74d7c10d4d391ad 100644 (file)
@@ -180,6 +180,7 @@ master_service.o: master.h
 master_service.o: master_service.c
 master_sig.o: ../../include/events.h
 master_sig.o: ../../include/iostuff.h
+master_sig.o: ../../include/killme_after.h
 master_sig.o: ../../include/msg.h
 master_sig.o: ../../include/posix_signals.h
 master_sig.o: ../../include/sys_defs.h
index c8b1e693d8c8525f72cd937c9ec761919cfaf210..ed9f942771df7a5aa0505a469baf34b4138026fb 100644 (file)
@@ -209,6 +209,8 @@ static NORETURN usage(const char *me)
     msg_fatal("usage: %s [-c config_dir] [-D (debug)] [-d (don't detach from terminal)] [-e exit_time] [-t (test)] [-v]", me);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - main program */
 
 int     main(int argc, char **argv)
@@ -225,6 +227,11 @@ int     main(int argc, char **argv)
     WATCHDOG *watchdog;
     ARGV   *import_env;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Initialize.
      */
index b007986e6455a71855d2fd11adcc3e18d96ffb52..ede015d8b6c6eb15ddebc5b36224614ff7cb66e0 100644 (file)
@@ -626,6 +626,14 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     if (redo_syslog_init)
        msg_syslog_init(mail_task(var_procname), LOG_PID, LOG_FACILITY);
 
+    /*
+     * If not connected to stdin, stdin must not be a terminal.
+     */
+    if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
+       msg_vstream_init(var_procname, VSTREAM_ERR);
+       msg_fatal("do not run this command by hand");
+    }
+
     /*
      * Application-specific initialization.
      */
@@ -694,14 +702,6 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     if (user_name)
        user_name = var_mail_owner;
 
-    /*
-     * If not connected to stdin, stdin must not be a terminal.
-     */
-    if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
-       msg_vstream_init(var_procname, VSTREAM_ERR);
-       msg_fatal("do not run this command by hand");
-    }
-
     /*
      * Can options be required?
      */
index e22048f2bce00b837af00ad0d2ddf36a102057ee..244b6798fdcfe6b0798013a33562eb8398ea39cf 100644 (file)
@@ -519,6 +519,14 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     if (redo_syslog_init)
        msg_syslog_init(mail_task(var_procname), LOG_PID, LOG_FACILITY);
 
+    /*
+     * If not connected to stdin, stdin must not be a terminal.
+     */
+    if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
+       msg_vstream_init(var_procname, VSTREAM_ERR);
+       msg_fatal("do not run this command by hand");
+    }
+
     /*
      * Application-specific initialization.
      */
@@ -584,14 +592,6 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     if (user_name)
        user_name = var_mail_owner;
 
-    /*
-     * If not connected to stdin, stdin must not be a terminal.
-     */
-    if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
-       msg_vstream_init(var_procname, VSTREAM_ERR);
-       msg_fatal("do not run this command by hand");
-    }
-
     /*
      * Can options be required?
      */
index 5db0fb8ee6998f3f6c62c053f0ce0573b40f299f..e420d895e2c9d69e36f18a25cfa93af012f635d1 100644 (file)
@@ -526,6 +526,14 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
     if (redo_syslog_init)
        msg_syslog_init(mail_task(var_procname), LOG_PID, LOG_FACILITY);
 
+    /*
+     * If not connected to stdin, stdin must not be a terminal.
+     */
+    if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
+       msg_vstream_init(var_procname, VSTREAM_ERR);
+       msg_fatal("do not run this command by hand");
+    }
+
     /*
      * Application-specific initialization.
      */
@@ -591,14 +599,6 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
     if (user_name)
        user_name = var_mail_owner;
 
-    /*
-     * If not connected to stdin, stdin must not be a terminal.
-     */
-    if (daemon_mode && stream == 0 && isatty(STDIN_FILENO)) {
-       msg_vstream_init(var_procname, VSTREAM_ERR);
-       msg_fatal("do not run this command by hand");
-    }
-
     /*
      * Can options be required?
      * 
index 4b10cda9b947c57663bcace7af15571150246e06..ce66bd170376c91ce7cdff7e3756f7d421215505 100644 (file)
@@ -100,6 +100,7 @@ milter8.o: ../../include/connect.h
 milter8.o: ../../include/header_opts.h
 milter8.o: ../../include/iostuff.h
 milter8.o: ../../include/is_header.h
+milter8.o: ../../include/mail_params.h
 milter8.o: ../../include/mail_proto.h
 milter8.o: ../../include/mime_state.h
 milter8.o: ../../include/msg.h
index 136bd72e627e8d0109460f48c6c2e3d11c5c1600..7c6b21cce107dfa1cf3d4cc151057dcda68c09ca 100644 (file)
@@ -75,6 +75,7 @@ qmgr.o: ../../include/mail_params.h
 qmgr.o: ../../include/mail_proto.h
 qmgr.o: ../../include/mail_queue.h
 qmgr.o: ../../include/mail_server.h
+qmgr.o: ../../include/mail_version.h
 qmgr.o: ../../include/master_proto.h
 qmgr.o: ../../include/msg.h
 qmgr.o: ../../include/recipient_list.h
index 84baa7cac24812e5f86bc5088cc66ef0f6cd6451..6b7b037a380fd1253edeb94f581b5d1caf265c40 100644 (file)
 #include <recipient_list.h>
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>                        /* QMGR_SCAN constants */
 #include <mail_flow.h>
 #include <flush_clnt.h>
@@ -548,6 +549,8 @@ static void qmgr_post_init(char *unused_name, char **unused_argv)
     qmgr_deferred_run_event(0, (char *) 0);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -584,6 +587,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Use the trigger service skeleton, because no-one else should be
      * monitoring our service port while this process runs, and because we do
index f416e3cb14529481833438ac3f14a2f181f4f40f..07e39f2e13dfca9b4e11bd8455d6179a5fa14791 100644 (file)
@@ -69,6 +69,7 @@ pickup.o: ../../include/mail_params.h
 pickup.o: ../../include/mail_proto.h
 pickup.o: ../../include/mail_queue.h
 pickup.o: ../../include/mail_server.h
+pickup.o: ../../include/mail_version.h
 pickup.o: ../../include/msg.h
 pickup.o: ../../include/mymalloc.h
 pickup.o: ../../include/rec_attr_map.h
index ca3d97c8d221f5587b05edacca8e23d1532e79df..153f36326fdac97cec5ed3c8abd87c6613be5a3a 100644 (file)
 #include <lex_822.h>
 #include <input_transp.h>
 #include <rec_attr_map.h>
+#include <mail_version.h>
 
 /* Single-threaded server skeleton. */
 
@@ -570,6 +571,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
        input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the multi-threaded server skeleton */
 
 int     main(int argc, char **argv)
@@ -580,6 +583,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Use the multi-threaded skeleton, because no-one else should be
      * monitoring our service socket while this process runs.
index f4e28667034400ef07fa46dce735e04499d1c62f..c661d74201fa9f925e79cd7331b9c9691647fcb8 100644 (file)
@@ -77,6 +77,7 @@ pipe.o: ../../include/mail_conf.h
 pipe.o: ../../include/mail_copy.h
 pipe.o: ../../include/mail_params.h
 pipe.o: ../../include/mail_server.h
+pipe.o: ../../include/mail_version.h
 pipe.o: ../../include/msg.h
 pipe.o: ../../include/msg_stats.h
 pipe.o: ../../include/mymalloc.h
index bf9bbf1aaa87ba23f386f312817ead132dbd5746..164896ca681c35c0301528d7578b93b8cb8328d7 100644 (file)
 #include <recipient_list.h>
 #include <deliver_request.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <bounce.h>
 #include <defer.h>
@@ -1196,6 +1197,8 @@ static void pre_init(char *unused_name, char **unused_argv)
     flush_init();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -1205,6 +1208,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, pipe_service,
                       MAIL_SERVER_TIME_TABLE, time_table,
                       MAIL_SERVER_PRE_INIT, pre_init,
index 109dd6f7122f3814eedf5a01d30be0da42da1df1..2e748382ea90fa0c33eadf9f2befb03ec6a44822 100644 (file)
@@ -87,6 +87,7 @@ postalias.o: ../../include/mail_conf.h
 postalias.o: ../../include/mail_dict.h
 postalias.o: ../../include/mail_params.h
 postalias.o: ../../include/mail_task.h
+postalias.o: ../../include/mail_version.h
 postalias.o: ../../include/mkmap.h
 postalias.o: ../../include/msg.h
 postalias.o: ../../include/msg_syslog.h
index 3a6e5683a8ed5150b156905f1f70069753008de6..955116b995b4b2047abc434e07967d5ac9c02dec 100644 (file)
 #include <mail_conf.h>
 #include <mail_dict.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mkmap.h>
 #include <mail_task.h>
 
@@ -598,6 +599,8 @@ static NORETURN usage(char *myname)
              myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     char   *path_name;
@@ -613,6 +616,11 @@ int     main(int argc, char **argv)
     int     sequence = 0;
     int     found;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index e92b6b71fa7dcc2a597d376fe4be20627b50caa4..237bf60922f1df50e5e950303a47f9b148d26f1b 100644 (file)
@@ -63,6 +63,7 @@ postcat.o: ../../include/mail_conf.h
 postcat.o: ../../include/mail_params.h
 postcat.o: ../../include/mail_proto.h
 postcat.o: ../../include/mail_queue.h
+postcat.o: ../../include/mail_version.h
 postcat.o: ../../include/msg.h
 postcat.o: ../../include/msg_vstream.h
 postcat.o: ../../include/rec_type.h
index 7f043f4c31e475f9cd8717b1a6f9e8cd271afd7b..1db3d506b2eb321be4d69048ffadfa0d71bbb934 100644 (file)
@@ -88,6 +88,7 @@
 #include <mail_queue.h>
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>
 
 /* Application-specific. */
@@ -239,6 +240,8 @@ static NORETURN usage(char *myname)
              myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     VSTRING *buffer;
@@ -258,6 +261,11 @@ int     main(int argc, char **argv)
     char  **cpp;
     int     tries;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * To minimize confusion, make sure that the standard file descriptors
      * are open before opening anything else. XXX Work around for 44BSD where
index 25069f439c2eff6d9e17f4f075d07f15e0bd7ba9..77cd7440fcfda02e8c0d7e7fbae65e3dd57f5d23 100644 (file)
@@ -22,7 +22,7 @@
     }
 }
 /^(static| )*CONFIG_STR_TABLE .*\{/,/\};/ { 
-    if ($1 ~ /VAR/) {
+    if ($1 ~ /^VAR/) {
        print "char *" substr($3,2,length($3)-2) ";" > "str_vars.h"
        if (++stab[$1 $2 $4 $5 $6 $7 $8 $9] == 1) {
            print |"sed 's/[    ][      ]*/ /g' > str_table.h"
@@ -30,7 +30,7 @@
     }
 }
 /^(static| )*CONFIG_RAW_TABLE .*\{/,/\};/ { 
-    if ($1 ~ /VAR/) {
+    if ($1 ~ /^VAR/) {
        print "char *" substr($3,2,length($3)-2) ";" > "raw_vars.h"
        if (++rtab[$1 $2 $4 $5 $6 $7 $8 $9] == 1) {
            print |"sed 's/[    ][      ]*/ /g' > raw_table.h"
@@ -38,7 +38,7 @@
     }
 }
 /^(static| )*CONFIG_BOOL_TABLE .*\{/,/\};/ { 
-    if ($1 ~ /VAR/) {
+    if ($1 ~ /^VAR/) {
        print "int " substr($3,2,length($3)-2) ";" > "bool_vars.h"
        if (++btab[$1 $2 $4 $5 $6 $7 $8 $9] == 1) {
            print |"sed 's/[    ][      ]*/ /g' > bool_table.h"
@@ -46,7 +46,7 @@
     }
 }
 /^(static| )*CONFIG_TIME_TABLE .*\{/,/\};/ { 
-    if ($1 ~ /VAR/) {
+    if ($1 ~ /^VAR/) {
        print "int " substr($3,2,length($3)-2) ";" > "time_vars.h"
        if (++ttab[$1 $2 $4 $5 $6 $7 $8 $9] == 1) {
            print |"sed 's/[    ][      ]*/ /g' > time_table.h" 
index 376644fe9efc80d2fd1792f6b1cf6eb6af4da036..dfa03612da235fa80c1acea308c8a919c74a7523 100644 (file)
@@ -960,6 +960,8 @@ static void show_parameters(int mode, char **names)
     }
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main */
 
 int     main(int argc, char **argv)
@@ -970,6 +972,11 @@ int     main(int argc, char **argv)
     int     junk;
     ARGV   *ext_argv = 0;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index 178b14ba93eba9aace7911f4cfcc711d7ef6d355..06afb8492529940ab100d95bb8320ab7fbc59354 100644 (file)
@@ -68,6 +68,7 @@ postdrop.o: ../../include/mail_proto.h
 postdrop.o: ../../include/mail_queue.h
 postdrop.o: ../../include/mail_stream.h
 postdrop.o: ../../include/mail_task.h
+postdrop.o: ../../include/mail_version.h
 postdrop.o: ../../include/msg.h
 postdrop.o: ../../include/msg_syslog.h
 postdrop.o: ../../include/msg_vstream.h
index 537cdb260fc8debc307d42f323347a9bf387dacd..7668df8da803489e9585766a5b785cb73b94149d 100644 (file)
 #include <mail_proto.h>
 #include <mail_queue.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <mail_task.h>
 #include <clean_env.h>
@@ -206,6 +207,8 @@ static void postdrop_cleanup(void)
     postdrop_sig(0);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -231,6 +234,11 @@ int     main(int argc, char **argv)
     struct timeval start;
     int     saved_errno;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index f61f6703d87a4db4a1693be5fbbcdd7c6a7182a4..ef7c63cacd7a814ef0836a64adfee7563b43bd83 100644 (file)
@@ -65,6 +65,7 @@ postfix.o: ../../include/argv.h
 postfix.o: ../../include/clean_env.h
 postfix.o: ../../include/mail_conf.h
 postfix.o: ../../include/mail_params.h
+postfix.o: ../../include/mail_version.h
 postfix.o: ../../include/msg.h
 postfix.o: ../../include/msg_syslog.h
 postfix.o: ../../include/msg_vstream.h
index 784526c47173290a1f47b4fe46fc1c4ba5df6831..d2bb01284819a91c503209b0ac3ca8778294b043 100644 (file)
 
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 
 /* Additional installation parameters. */
 
@@ -311,6 +312,8 @@ static void check_setenv(char *name, char *value)
        msg_fatal("setenv: %m");
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - run administrative script from controlled environment */
 
 int     main(int argc, char **argv)
@@ -332,6 +335,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index 527598be8b773069cdb610d1fa21a6c42faaef53..7271ed1d09c97b2415e6c76d3091b3d65affa524 100644 (file)
@@ -63,6 +63,7 @@ postkick.o: ../../include/iostuff.h
 postkick.o: ../../include/mail_conf.h
 postkick.o: ../../include/mail_params.h
 postkick.o: ../../include/mail_proto.h
+postkick.o: ../../include/mail_version.h
 postkick.o: ../../include/msg.h
 postkick.o: ../../include/msg_vstream.h
 postkick.o: ../../include/mymalloc.h
index 8446f4069c284684b23a8efb360edfba4656229b..93df8d0e32da172503786568cfb4453bc4f70ace 100644 (file)
@@ -96,6 +96,7 @@
 
 #include <mail_proto.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 
 static NORETURN usage(char *myname)
@@ -103,6 +104,8 @@ static NORETURN usage(char *myname)
     msg_fatal("usage: %s [-c config_dir] [-v] class service request", myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     char   *class;
@@ -113,6 +116,11 @@ int     main(int argc, char **argv)
     char   *slash;
     int     c;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * To minimize confusion, make sure that the standard file descriptors
      * are open before opening anything else. XXX Work around for 44BSD where
index b97c2b9d40cf7d786cc3e629d5508f7e3619617e..7024d7139dffa66faa1c7d5215eef125c7a993fd 100644 (file)
@@ -66,6 +66,7 @@ postlock.o: ../../include/dsn_util.h
 postlock.o: ../../include/iostuff.h
 postlock.o: ../../include/mail_conf.h
 postlock.o: ../../include/mail_params.h
+postlock.o: ../../include/mail_version.h
 postlock.o: ../../include/mbox_conf.h
 postlock.o: ../../include/mbox_open.h
 postlock.o: ../../include/msg.h
index ab3a4ecf34ffcf0a0d1bcfc37559a17c24882e1c..e2814bce3bad4b8fdc43bb314dd02908f64e8896 100644 (file)
 /* Global library. */
 
 #include <mail_params.h>
+#include <mail_version.h>
 #include <dot_lockfile.h>
 #include <deliver_flock.h>
 #include <mail_conf.h>
@@ -136,6 +137,8 @@ static void fatal_exit(void)
     exit(EX_TEMPFAIL);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - go for it */
 
 int     main(int argc, char **argv)
@@ -153,6 +156,11 @@ int     main(int argc, char **argv)
     char   *lock_style = 0;
     MBOX   *mp;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index d0e135930f0e1fe70ab5801d85fd28ba3ae73984..5882fd33fa4f3cd16725121b06785c895c1f32f1 100644 (file)
@@ -64,6 +64,7 @@ depend: $(MAKES)
 postlog.o: ../../include/mail_conf.h
 postlog.o: ../../include/mail_params.h
 postlog.o: ../../include/mail_task.h
+postlog.o: ../../include/mail_version.h
 postlog.o: ../../include/msg.h
 postlog.o: ../../include/msg_output.h
 postlog.o: ../../include/msg_syslog.h
index ef6d37ea16c9ebdfad4e9f8614f70bd879f79f8f..5ed28a152c724f09aaa6986197f71ddf9b99f21f 100644 (file)
@@ -97,6 +97,7 @@
 /* Global library. */
 
 #include <mail_params.h>               /* XXX right place for LOG_FACILITY? */
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <mail_task.h>
 
@@ -160,6 +161,8 @@ static void log_stream(int level, VSTREAM *fp)
     vstring_free(buf);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - logger */
 
 int     main(int argc, char **argv)
@@ -172,6 +175,11 @@ int     main(int argc, char **argv)
     int     log_flags = 0;
     int     level = MSG_INFO;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index a71a34f848c412a38270c21f1b3d7d902db50bb3..508fae4eca670b75af9e8dd74e1099029d040bde 100644 (file)
@@ -87,6 +87,7 @@ postmap.o: ../../include/mail_conf.h
 postmap.o: ../../include/mail_dict.h
 postmap.o: ../../include/mail_params.h
 postmap.o: ../../include/mail_task.h
+postmap.o: ../../include/mail_version.h
 postmap.o: ../../include/mkmap.h
 postmap.o: ../../include/msg.h
 postmap.o: ../../include/msg_syslog.h
index d2f15684ad36191e3a0788e5f893dbed51f4843b..5befc3e695ac0c1a4afac75c684f3c0aa5309cee 100644 (file)
@@ -42,7 +42,7 @@
 /*     The \fIkey\fR and \fIvalue\fR are processed as is, except that
 /*     surrounding white space is stripped off. Unlike with Postfix alias
 /*     databases, quotes cannot be used to protect lookup keys that contain
-/*     special characters such as `#' or whitespace. 
+/*     special characters such as `#' or whitespace.
 /*
 /*     By default the lookup key is mapped to lowercase to make
 /*     the lookups case insensitive; as of Postfix 2.3 this case
 #include <mail_conf.h>
 #include <mail_dict.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mkmap.h>
 #include <mail_task.h>
 
@@ -427,7 +428,7 @@ static int postmap_queries(VSTREAM *in, char **maps, const int map_count,
 /* postmap_query - query a map and print the result to stdout */
 
 static int postmap_query(const char *map_type, const char *map_name,
-                                  const char *key, int dict_flags)
+                                const char *key, int dict_flags)
 {
     DICT   *dict;
     const char *value;
@@ -450,7 +451,7 @@ static int postmap_query(const char *map_type, const char *map_name,
 /* postmap_deletes - apply multiple requests from stdin */
 
 static int postmap_deletes(VSTREAM *in, char **maps, const int map_count,
-                                    int dict_flags)
+                                  int dict_flags)
 {
     int     found = 0;
     VSTRING *keybuf = vstring_alloc(100);
@@ -495,7 +496,7 @@ static int postmap_deletes(VSTREAM *in, char **maps, const int map_count,
 /* postmap_delete - delete a (key, value) pair from a map */
 
 static int postmap_delete(const char *map_type, const char *map_name,
-                                   const char *key, int dict_flags)
+                                 const char *key, int dict_flags)
 {
     DICT   *dict;
     int     status;
@@ -509,7 +510,7 @@ static int postmap_delete(const char *map_type, const char *map_name,
 /* postmap_seq - print all map entries to stdout */
 
 static void postmap_seq(const char *map_type, const char *map_name,
-                                 int dict_flags)
+                               int dict_flags)
 {
     DICT   *dict;
     const char *key;
@@ -543,6 +544,8 @@ static NORETURN usage(char *myname)
              myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     char   *path_name;
@@ -558,6 +561,11 @@ int     main(int argc, char **argv)
     int     sequence = 0;
     int     found;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
@@ -663,15 +671,15 @@ int     main(int argc, char **argv)
            usage(argv[0]);
        if (strcmp(delkey, "-") == 0)
            exit(postmap_deletes(VSTREAM_IN, argv + optind, argc - optind,
-                                  dict_flags | DICT_FLAG_LOCK) == 0);
+                                dict_flags | DICT_FLAG_LOCK) == 0);
        found = 0;
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
                found |= postmap_delete(argv[optind], path_name, delkey,
-                                         dict_flags | DICT_FLAG_LOCK);
+                                       dict_flags | DICT_FLAG_LOCK);
            } else {
                found |= postmap_delete(var_db_type, argv[optind], delkey,
-                                         dict_flags | DICT_FLAG_LOCK);
+                                       dict_flags | DICT_FLAG_LOCK);
            }
            optind++;
        }
@@ -681,14 +689,14 @@ int     main(int argc, char **argv)
            usage(argv[0]);
        if (strcmp(query, "-") == 0)
            exit(postmap_queries(VSTREAM_IN, argv + optind, argc - optind,
-                                  dict_flags | DICT_FLAG_LOCK) == 0);
+                                dict_flags | DICT_FLAG_LOCK) == 0);
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
                found = postmap_query(argv[optind], path_name, query,
-                                       dict_flags | DICT_FLAG_LOCK);
+                                     dict_flags | DICT_FLAG_LOCK);
            } else {
                found = postmap_query(var_db_type, argv[optind], query,
-                                       dict_flags | DICT_FLAG_LOCK);
+                                     dict_flags | DICT_FLAG_LOCK);
            }
            if (found)
                exit(0);
@@ -699,10 +707,10 @@ int     main(int argc, char **argv)
        while (optind < argc) {
            if ((path_name = split_at(argv[optind], ':')) != 0) {
                postmap_seq(argv[optind], path_name,
-                             dict_flags | DICT_FLAG_LOCK);
+                           dict_flags | DICT_FLAG_LOCK);
            } else {
                postmap_seq(var_db_type, argv[optind],
-                             dict_flags | DICT_FLAG_LOCK);
+                           dict_flags | DICT_FLAG_LOCK);
            }
            exit(0);
        }
index 7a0a39ca9f4c66508b2eabe7a41ced7a9b130690..4e80a3c811f70a8f82032cb48cefce178e64ef02 100644 (file)
@@ -71,6 +71,7 @@ postqueue.o: ../../include/mail_proto.h
 postqueue.o: ../../include/mail_queue.h
 postqueue.o: ../../include/mail_run.h
 postqueue.o: ../../include/mail_task.h
+postqueue.o: ../../include/mail_version.h
 postqueue.o: ../../include/msg.h
 postqueue.o: ../../include/msg_syslog.h
 postqueue.o: ../../include/msg_vstream.h
index 8013277bef4465b2dfdc09c36874d6f6a0f15107..dad7b592be6827425c17c504e4569c7b694cf8f6 100644 (file)
 
 #include <mail_proto.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <mail_task.h>
 #include <mail_run.h>
   * establish frequent proof of client liveliness with challenge/response, or
   * the client needs to restrict expensive requests to privileged users only.
   * 
-  * We don't have this problem with queue listings. The showq server detects
-  * an EPIPE error after reporting a few queue entries.
+  * We don't have this problem with queue listings. The showq server detects an
+  * EPIPE error after reporting a few queue entries.
   */
 #define PQ_MODE_DEFAULT                0       /* noop */
 #define PQ_MODE_MAILQ_LIST     1       /* list mail queue */
@@ -429,6 +430,8 @@ static NORETURN usage(void)
     msg_fatal_status(EX_USAGE, "usage: postqueue -f | postqueue -i queueid | postqueue -p | postqueue -s site");
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -443,6 +446,11 @@ int     main(int argc, char **argv)
     ARGV   *import_env;
     int     bad_site;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index b131fe88bd13c789bf29c4aaf1d2aa645e5fd07d..0df70b1ad20b5026c1823515c5a532d1da5665ab 100644 (file)
@@ -63,6 +63,7 @@ postsuper.o: ../../include/mail_open_ok.h
 postsuper.o: ../../include/mail_params.h
 postsuper.o: ../../include/mail_queue.h
 postsuper.o: ../../include/mail_task.h
+postsuper.o: ../../include/mail_version.h
 postsuper.o: ../../include/msg.h
 postsuper.o: ../../include/msg_syslog.h
 postsuper.o: ../../include/msg_vstream.h
index a8bcedde824f058e36b7bd9401f287130680ea96..47f67485c84dac7741413f90232e6821aac3d292 100644 (file)
 #include <mail_task.h>
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_queue.h>
 #include <mail_open_ok.h>
 
@@ -988,6 +989,8 @@ static void fatal_warning(void)
     interrupted(0);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     int     fd;
@@ -1031,6 +1034,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
index 565afbf6d4c73b920874425919966c524f8e976c..c4ccf673de8fecde899ec42201fab701efb31771 100644 (file)
@@ -67,6 +67,7 @@ proxymap.o: ../../include/mail_conf.h
 proxymap.o: ../../include/mail_params.h
 proxymap.o: ../../include/mail_proto.h
 proxymap.o: ../../include/mail_server.h
+proxymap.o: ../../include/mail_version.h
 proxymap.o: ../../include/msg.h
 proxymap.o: ../../include/mymalloc.h
 proxymap.o: ../../include/stringops.h
index 1e143d2dd065ee32b3655af545a1ddc8ee66ed48..a9eb0c06b6c1dc8dbbedcbfaf66d7a133fcbbf49 100644 (file)
 
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>
 #include <dict_proxy.h>
 
@@ -429,6 +430,8 @@ static void pre_accept(char *unused_name, char **unused_argv)
     }
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the multi-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -450,6 +453,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     multi_server_main(argc, argv, proxymap_service,
                      MAIL_SERVER_STR_TABLE, str_table,
                      MAIL_SERVER_POST_INIT, post_jail_init,
index 75b86bf911558928e4c5314d6ae50cb400a59d3c..d7db1a073e2e3b360ad41abce5d1d4b2a6b2f270 100644 (file)
@@ -77,6 +77,7 @@ qmgr.o: ../../include/mail_params.h
 qmgr.o: ../../include/mail_proto.h
 qmgr.o: ../../include/mail_queue.h
 qmgr.o: ../../include/mail_server.h
+qmgr.o: ../../include/mail_version.h
 qmgr.o: ../../include/master_proto.h
 qmgr.o: ../../include/msg.h
 qmgr.o: ../../include/recipient_list.h
index 4ab22b02d8f1172287150e2bff1b843d0d37a6c0..4cc999671e27ffcdce6610e0ad84b4fea919862f 100644 (file)
 #include <recipient_list.h>
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>                        /* QMGR_SCAN constants */
 #include <mail_flow.h>
 #include <flush_clnt.h>
@@ -615,6 +616,8 @@ static void qmgr_post_init(char *name, char **unused_argv)
     qmgr_deferred_run_event(0, (char *) 0);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -659,6 +662,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Use the trigger service skeleton, because no-one else should be
      * monitoring our service port while this process runs, and because we do
index 84c5523b8ad53cb0602dcfa9c0ef61aef1e9d6f8..ef50fda86dbe3a1fc5d6b05aded7163171a5e97e 100644 (file)
@@ -72,6 +72,7 @@ qmqpd.o: ../../include/mail_params.h
 qmqpd.o: ../../include/mail_proto.h
 qmqpd.o: ../../include/mail_server.h
 qmqpd.o: ../../include/mail_stream.h
+qmqpd.o: ../../include/mail_version.h
 qmqpd.o: ../../include/match_list.h
 qmqpd.o: ../../include/match_ops.h
 qmqpd.o: ../../include/match_parent_style.h
index 19d804697425ba794211a78d9f597e7f942c98da..171ecae6328d7c4b1738e1faecae281f017c4681 100644 (file)
 /* Global library. */
 
 #include <mail_params.h>
+#include <mail_version.h>
 #include <record.h>
 #include <rec_type.h>
 #include <mail_proto.h>
@@ -759,6 +760,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
     input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -775,6 +778,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Pass control to the single-threaded service skeleton.
      */
index e5282e84fbfcba7ce0b640a72216595cd96621ce..c6ab06562e31d48fd20a9df0d6a1dd5fc9abe88c 100644 (file)
@@ -65,6 +65,7 @@ scache.o: ../../include/mail_conf.h
 scache.o: ../../include/mail_params.h
 scache.o: ../../include/mail_proto.h
 scache.o: ../../include/mail_server.h
+scache.o: ../../include/mail_version.h
 scache.o: ../../include/msg.h
 scache.o: ../../include/ring.h
 scache.o: ../../include/scache.h
index 28de18c34f0a2bb8cdac2b8f3906aaf07512af58..f75ec306a374120140231016fae3c16fc8edb17d 100644 (file)
 /* Global library. */
 
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>
 #include <scache.h>
 
@@ -532,6 +533,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
     scache_start_time = event_time();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the multi-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -542,6 +545,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     multi_server_main(argc, argv, scache_service,
                      MAIL_SERVER_TIME_TABLE, time_table,
                      MAIL_SERVER_POST_INIT, post_jail_init,
index cf9dbeeaa8561de5286a491c539749a2ca7662d4..262b9b8f850c2a7f2e1b867dd578e1cf2dc251b0 100644 (file)
@@ -76,6 +76,7 @@ sendmail.o: ../../include/mail_queue.h
 sendmail.o: ../../include/mail_run.h
 sendmail.o: ../../include/mail_stream.h
 sendmail.o: ../../include/mail_task.h
+sendmail.o: ../../include/mail_version.h
 sendmail.o: ../../include/mime_state.h
 sendmail.o: ../../include/msg.h
 sendmail.o: ../../include/msg_stats.h
index 08cf0209c850250acbabb6e970240d9e7b0fc673..30fef831e35f691eb1e0c7ed9403f3014a2a9dc3 100644 (file)
 #include <mail_queue.h>
 #include <mail_proto.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <record.h>
 #include <rec_type.h>
 #include <rec_streamlf.h>
@@ -897,6 +898,8 @@ static void tempfail(void)
     exit(EX_TEMPFAIL);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -924,6 +927,11 @@ int     main(int argc, char **argv)
     const char *dsn_envid = 0;
     int     saved_optind;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Be consistent with file permissions.
      */
@@ -1009,7 +1017,7 @@ int     main(int argc, char **argv)
     optind = saved_optind;
     mail_conf_read();
     if (strcmp(var_syslog_name, DEF_SYSLOG_NAME) != 0)
-        msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
+       msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
     get_mail_conf_str_table(str_table);
 
     if (chdir(var_queue_dir))
index 2783e970089275f8ac9a7f3b6b391da6ccf34153..d4cd349cba04f3e3296bdf304b73faa53bea6982 100644 (file)
@@ -72,6 +72,7 @@ showq.o: ../../include/mail_proto.h
 showq.o: ../../include/mail_queue.h
 showq.o: ../../include/mail_scan_dir.h
 showq.o: ../../include/mail_server.h
+showq.o: ../../include/mail_version.h
 showq.o: ../../include/msg.h
 showq.o: ../../include/mymalloc.h
 showq.o: ../../include/quote_822_local.h
index 30ed5f9bb8093236cfd43dc40b92c65bcaf6bec8..8e1cc2d04931463fba142cd6eef6cfab6714deb4 100644 (file)
 #include <mail_proto.h>
 #include <mail_date.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_scan_dir.h>
 #include <mail_conf.h>
 #include <record.h>
@@ -143,8 +144,8 @@ char   *var_empty_addr;
 #define SENDER_FORMAT  "%-11s %7ld %20.20s %s\n"
 #define DROP_FORMAT    "%-10s%c %7ld %20.20s (maildrop queue, sender UID %u)\n"
 
-static void showq_reasons(VSTREAM *, BOUNCE_LOG *, RCPT_BUF *, DSN_BUF *, 
-HTABLE *);
+static void showq_reasons(VSTREAM *, BOUNCE_LOG *, RCPT_BUF *, DSN_BUF *,
+                                 HTABLE *);
 
 #define STR(x) vstring_str(x)
 
@@ -260,8 +261,8 @@ static void showq_report(VSTREAM *client, char *queue, char *id,
 
 /* showq_reasons - show deferral reasons */
 
-static void showq_reasons(VSTREAM *client, BOUNCE_LOG *bp, RCPT_BUF *rcpt_buf, 
-DSN_BUF *dsn_buf, HTABLE *dup_filter)
+static void showq_reasons(VSTREAM *client, BOUNCE_LOG *bp, RCPT_BUF *rcpt_buf,
+                                 DSN_BUF *dsn_buf, HTABLE *dup_filter)
 {
     char   *saved_reason = 0;
     int     padding;
@@ -395,6 +396,8 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv)
     }
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded server skeleton */
 
 int     main(int argc, char **argv)
@@ -408,6 +411,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, showq_service,
                       MAIL_SERVER_INT_TABLE, int_table,
                       MAIL_SERVER_STR_TABLE, str_table,
index 94ef9d3c718fc64c7bcfceda45f7ae48ee1d2939..8e578347da12741be5ec36165206c6905d4a1c63 100644 (file)
@@ -99,6 +99,7 @@ smtp.o: ../../include/htable.h
 smtp.o: ../../include/mail_conf.h
 smtp.o: ../../include/mail_params.h
 smtp.o: ../../include/mail_server.h
+smtp.o: ../../include/mail_version.h
 smtp.o: ../../include/maps.h
 smtp.o: ../../include/match_list.h
 smtp.o: ../../include/match_ops.h
@@ -168,6 +169,7 @@ smtp_chat.o: ../../include/dsn.h
 smtp_chat.o: ../../include/dsn_buf.h
 smtp_chat.o: ../../include/dsn_util.h
 smtp_chat.o: ../../include/htable.h
+smtp_chat.o: ../../include/int_filt.h
 smtp_chat.o: ../../include/line_wrap.h
 smtp_chat.o: ../../include/mail_addr.h
 smtp_chat.o: ../../include/mail_error.h
index 363b8132ba80c63fc89af01021c2899664d6989e..29c91d5865a548580bdfdccdfc8d3850b1d4623e 100644 (file)
 
 #include <deliver_request.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <debug_peer.h>
 #include <flush_clnt.h>
@@ -947,6 +948,8 @@ static void pre_accept(char *unused_name, char **unused_argv)
     }
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -955,6 +958,11 @@ int     main(int argc, char **argv)
 #include "lmtp_params.c"
     int     smtp_mode;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * XXX At this point, var_procname etc. are not initialized.
      */
index 96d09ef94b7f94789e258bf3ab9db902c1938444..601a1f53887f1c13af026783d26b6cbfcc098f77 100644 (file)
@@ -4401,6 +4401,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
        anvil_clnt = anvil_clnt_create();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -4572,6 +4574,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Pass control to the single-threaded service skeleton.
      */
index 6de57d175930f5dda9777c98bf4b37500b4980d7..3c0316e735d8517a0f79f3dbede3b97a0fac1aa8 100644 (file)
@@ -82,6 +82,7 @@ qmqp-sink.o: ../../include/events.h
 qmqp-sink.o: ../../include/inet_proto.h
 qmqp-sink.o: ../../include/iostuff.h
 qmqp-sink.o: ../../include/listen.h
+qmqp-sink.o: ../../include/mail_version.h
 qmqp-sink.o: ../../include/msg.h
 qmqp-sink.o: ../../include/msg_vstream.h
 qmqp-sink.o: ../../include/mymalloc.h
@@ -99,6 +100,7 @@ qmqp-source.o: ../../include/host_port.h
 qmqp-source.o: ../../include/inet_proto.h
 qmqp-source.o: ../../include/iostuff.h
 qmqp-source.o: ../../include/mail_date.h
+qmqp-source.o: ../../include/mail_version.h
 qmqp-source.o: ../../include/msg.h
 qmqp-source.o: ../../include/msg_vstream.h
 qmqp-source.o: ../../include/myaddrinfo.h
@@ -114,14 +116,20 @@ qmqp-source.o: ../../include/vbuf.h
 qmqp-source.o: ../../include/vstream.h
 qmqp-source.o: ../../include/vstring.h
 qmqp-source.o: qmqp-source.c
+smtp-sink.o: ../../include/chroot_uid.h
 smtp-sink.o: ../../include/events.h
 smtp-sink.o: ../../include/get_hostname.h
 smtp-sink.o: ../../include/inet_proto.h
 smtp-sink.o: ../../include/iostuff.h
 smtp-sink.o: ../../include/listen.h
+smtp-sink.o: ../../include/mail_date.h
+smtp-sink.o: ../../include/mail_version.h
+smtp-sink.o: ../../include/make_dirs.h
 smtp-sink.o: ../../include/msg.h
 smtp-sink.o: ../../include/msg_vstream.h
+smtp-sink.o: ../../include/myaddrinfo.h
 smtp-sink.o: ../../include/mymalloc.h
+smtp-sink.o: ../../include/myrand.h
 smtp-sink.o: ../../include/sane_accept.h
 smtp-sink.o: ../../include/smtp_stream.h
 smtp-sink.o: ../../include/stringops.h
@@ -138,6 +146,7 @@ smtp-source.o: ../../include/host_port.h
 smtp-source.o: ../../include/inet_proto.h
 smtp-source.o: ../../include/iostuff.h
 smtp-source.o: ../../include/mail_date.h
+smtp-source.o: ../../include/mail_version.h
 smtp-source.o: ../../include/msg.h
 smtp-source.o: ../../include/msg_vstream.h
 smtp-source.o: ../../include/myaddrinfo.h
index 30390e6275b3712598fdf1897a555f739706a487..f89cd194f8e52890ca9f6b02f3b8b262c830e812 100644 (file)
@@ -79,6 +79,7 @@
 /* Global library. */
 
 #include <qmqp_proto.h>
+#include <mail_version.h>
 
 /* Application-specific. */
 
@@ -239,6 +240,8 @@ static void usage(char *myname)
     msg_fatal("usage: %s [-cv] [-x time] [host]:port backlog", myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     int     sock;
@@ -248,6 +251,11 @@ int     main(int argc, char **argv)
     const char *protocols = INET_PROTO_NAME_ALL;
     INET_PROTO_INFO *proto_info;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Fix 20051207.
      */
index 2606e6e118bfa4c07bbf5584e3ea6614df0589a5..33282ac40a5e72aed3cea212f1e62bf3777e63bb 100644 (file)
 
 #include <mail_date.h>
 #include <qmqp_proto.h>
+#include <mail_version.h>
 
 /* Application-specific. */
 
@@ -442,6 +443,8 @@ static void usage(char *myname)
     msg_fatal("usage: %s -cv -s sess -l msglen -m msgs -C count -M myhostname -f from -t to -R delay -w delay host[:port]", myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - parse JCL and start the machine */
 
 int     main(int argc, char **argv)
@@ -463,6 +466,11 @@ int     main(int argc, char **argv)
     const char *protocols = INET_PROTO_NAME_ALL;
     INET_PROTO_INFO *proto_info;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     signal(SIGPIPE, SIG_IGN);
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
index b18278fa91cfcf3e0ab7f6ded12f497f3cdafca8..d5b0bcd7e4ce6af146d41021a2c684d6360fa9fa 100644 (file)
 
 #include <smtp_stream.h>
 #include <mail_date.h>
+#include <mail_version.h>
 
 /* Application-specific. */
 
@@ -1249,6 +1250,8 @@ static void usage(char *myname)
     msg_fatal("usage: %s [-468acCeEFLpPv] [-A abort_delay] [-f commands] [-h hostname] [-m max_concurrency] [-n quit_count] [-q commands] [-r commands] [-s commands] [-w delay] [-d dump-template] [-D dump-template] [-R root-dir] [-S start-string] [-u user_privs] [host]:port backlog", myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 int     main(int argc, char **argv)
 {
     int     backlog;
@@ -1258,6 +1261,11 @@ int     main(int argc, char **argv)
     const char *root_dir = 0;
     const char *user_privs = 0;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Fix 20051207.
      */
index 9a736e14a311ed3613f9b6199974f1a8db8c5d45..52306cf8c9017ed946119e05587365ef250f2305 100644 (file)
 
 #include <smtp_stream.h>
 #include <mail_date.h>
+#include <mail_version.h>
 
 /* Application-specific. */
 
@@ -794,6 +795,8 @@ static void usage(char *myname)
     msg_fatal("usage: %s -cdLNov -s sess -l msglen -m msgs -C count -M myhostname -f from -t to -r rcptcount -R delay -w delay host[:port]", myname);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - parse JCL and start the machine */
 
 int     main(int argc, char **argv)
@@ -813,6 +816,11 @@ int     main(int argc, char **argv)
     const char *protocols = INET_PROTO_NAME_ALL;
     INET_PROTO_INFO *proto_info;
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     signal(SIGPIPE, SIG_IGN);
     msg_vstream_init(argv[0], VSTREAM_ERR);
 
index 24d2cc2fea08676d7470ff433a9a1bb8031a7471..1a89937db7d9460fae40ae1e7cb7e442add46d43 100644 (file)
@@ -62,6 +62,7 @@ spawn.o: ../../include/dict.h
 spawn.o: ../../include/mail_conf.h
 spawn.o: ../../include/mail_params.h
 spawn.o: ../../include/mail_server.h
+spawn.o: ../../include/mail_version.h
 spawn.o: ../../include/msg.h
 spawn.o: ../../include/mymalloc.h
 spawn.o: ../../include/set_eugid.h
index 9fa0eb9ecc39da3f23953ca690efa02635be282f..90fe7987b8c8b8efaaf5aca46b92b10b03d009dd 100644 (file)
@@ -70,7 +70,7 @@
 /*     The amount of time the command is allowed to run before it is
 /*     terminated.
 /*
-/*     Postfix 2.4 and later support a suffix that specifies the 
+/*     Postfix 2.4 and later support a suffix that specifies the
 /*     time unit: s (seconds), m (minutes), h (hours), d (days),
 /*     w (weeks). The default time unit is seconds.
 /* MISCELLANEOUS
 #include <timed_wait.h>
 #include <set_eugid.h>
 
+/* Global library. */
+
+#include <mail_version.h>
+
 /* Single server skeleton. */
 
 #include <mail_params.h>
@@ -322,7 +326,7 @@ static void spawn_service(VSTREAM *client_stream, char *service, char **argv)
 static void pre_accept(char *unused_name, char **unused_argv)
 {
     const char *table;
+
     if ((table = dict_changed_name()) != 0) {
        msg_info("table %s has changed -- restarting", table);
        exit(0);
@@ -336,6 +340,8 @@ static void drop_privileges(char *unused_name, char **unused_argv)
     set_eugid(var_owner_uid, var_owner_gid);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -345,6 +351,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, spawn_service,
                       MAIL_SERVER_TIME_TABLE, time_table,
                       MAIL_SERVER_POST_INIT, drop_privileges,
index 05301e47b7ce6a21acc5a6f9e9dc98f2b7795365..a2520842757948877b7da825d03c497810126a73 100644 (file)
@@ -68,6 +68,7 @@ tlsmgr.o: ../../include/mail_conf.h
 tlsmgr.o: ../../include/mail_params.h
 tlsmgr.o: ../../include/mail_proto.h
 tlsmgr.o: ../../include/mail_server.h
+tlsmgr.o: ../../include/mail_version.h
 tlsmgr.o: ../../include/master_proto.h
 tlsmgr.o: ../../include/msg.h
 tlsmgr.o: ../../include/mymalloc.h
index ed1018ec11d959bbac3083ed9b18fedad082d342..e4630193d453dbb2f3947279123fc0c0fe70122f 100644 (file)
 
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <tls_mgr.h>
 #include <mail_proto.h>
 
@@ -876,6 +877,8 @@ static void tlsmgr_before_exit(char *unused_service_name, char **unused_argv)
        tls_prng_exch_update(rand_exch);
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - the main program */
 
 int     main(int argc, char **argv)
@@ -904,6 +907,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     /*
      * Use the multi service skeleton, and require that no-one else is
      * monitoring our service port while this process runs.
index eadb385c01bb3f7810120de94ad3322239eca269..6b3ae51a31d2d6c1654ef6bbe7df77516b559f97 100644 (file)
@@ -146,6 +146,7 @@ trivial-rewrite.o: ../../include/mail_conf.h
 trivial-rewrite.o: ../../include/mail_params.h
 trivial-rewrite.o: ../../include/mail_proto.h
 trivial-rewrite.o: ../../include/mail_server.h
+trivial-rewrite.o: ../../include/mail_version.h
 trivial-rewrite.o: ../../include/maps.h
 trivial-rewrite.o: ../../include/msg.h
 trivial-rewrite.o: ../../include/resolve_clnt.h
index 233d740a49f14243749709978df2a7c23fea3040..d539a5d2a5de66c7927297d0ff91a01ed45e2a8e 100644 (file)
 /* Global library. */
 
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>
 #include <resolve_local.h>
 #include <mail_conf.h>
@@ -530,6 +531,8 @@ static void post_jail_init(char *unused_name, char **unused_argv)
     var_idle_limit = 1;
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the multi-threaded skeleton code */
 
 int     main(int argc, char **argv)
@@ -569,6 +572,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     multi_server_main(argc, argv, rewrite_service,
                      MAIL_SERVER_STR_TABLE, str_table,
                      MAIL_SERVER_BOOL_TABLE, bool_table,
index f9671f8dab363fd2bfb216b03cc583c67b9b71b7..0bb5c159d0a55828023e5c722c53a79ac592e7e2 100644 (file)
@@ -65,11 +65,13 @@ verify.o: ../../include/dict.h
 verify.o: ../../include/dict_ht.h
 verify.o: ../../include/dsn.h
 verify.o: ../../include/htable.h
+verify.o: ../../include/int_filt.h
 verify.o: ../../include/iostuff.h
 verify.o: ../../include/mail_conf.h
 verify.o: ../../include/mail_params.h
 verify.o: ../../include/mail_proto.h
 verify.o: ../../include/mail_server.h
+verify.o: ../../include/mail_version.h
 verify.o: ../../include/msg.h
 verify.o: ../../include/msg_stats.h
 verify.o: ../../include/mymalloc.h
index c1771fa564a89a9e6ee910b8f0ee6144f9ae60ff..13db73fd883c4a80e4645b06d79f2b012edadd8d 100644 (file)
 
 #include <mail_conf.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_proto.h>
 #include <post_mail.h>
 #include <verify_clnt.h>
@@ -562,6 +563,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
     setsid();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the multi-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -579,6 +582,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     multi_server_main(argc, argv, verify_service,
                      MAIL_SERVER_STR_TABLE, str_table,
                      MAIL_SERVER_TIME_TABLE, time_table,
index 51360fe43bcb7656e078568a118f043a4119f69d..9aed39f412a8061188c3edc1cc4b0cdea2dcdebd 100644 (file)
@@ -187,6 +187,7 @@ virtual.o: ../../include/mail_conf.h
 virtual.o: ../../include/mail_params.h
 virtual.o: ../../include/mail_queue.h
 virtual.o: ../../include/mail_server.h
+virtual.o: ../../include/mail_version.h
 virtual.o: ../../include/maps.h
 virtual.o: ../../include/mbox_conf.h
 virtual.o: ../../include/msg.h
index 1ccbcc67da8d08f8d99cda43aee0e54b981d7888..c522278746f28d120c221c693a89be3035ada4d8 100644 (file)
 #include <deliver_request.h>
 #include <deliver_completed.h>
 #include <mail_params.h>
+#include <mail_version.h>
 #include <mail_conf.h>
 #include <mail_params.h>
 #include <mail_addr_find.h>
@@ -482,6 +483,8 @@ static void pre_init(char *unused_name, char **unused_argv)
     flush_init();
 }
 
+MAIL_VERSION_STAMP_DECLARE;
+
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -501,6 +504,11 @@ int     main(int argc, char **argv)
        0,
     };
 
+    /*
+     * Fingerprint executables and core dumps.
+     */
+    MAIL_VERSION_STAMP_ALLOCATE;
+
     single_server_main(argc, argv, local_service,
                       MAIL_SERVER_INT_TABLE, int_table,
                       MAIL_SERVER_STR_TABLE, str_table,