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.
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
* 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
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.
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.
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
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
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.
<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>
<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>
<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>
<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>
<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
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>
<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 -> 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
+</pre>
+<br>
+
+<pre>
+ 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
+</pre>
+<br>
+
+<pre>
+ dn: uid=auser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: auser
+10 -> mail: auser@example.com
+11 -> maildrop: auser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=buser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: buser
+12 -> mail: buser@example.com
+13 -> maildrop: buser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=cuser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: cuser
+14 -> mail: cuser@example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=duser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: duser
+15 -> 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>
<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
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
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>
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
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
<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,
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
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
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 = (&(mail=%s)(paid_up=true))
This parameter supports the following '%' expan-
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
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
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 >= 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 >= 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,
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-
<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>
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>
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-
<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
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
return the key itself.
For example, NEVER do this in a map defining $mydestination:
+
.in +4
query_filter = domain=*
.br
.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
<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>
<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>
<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
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>
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 -> 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
+</pre>
+<br>
+
+<pre>
+ 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
+</pre>
+<br>
+
+<pre>
+ dn: uid=auser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: auser
+10 -> mail: auser@example.com
+11 -> maildrop: auser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=buser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: buser
+12 -> mail: buser@example.com
+13 -> maildrop: buser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=cuser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: cuser
+14 -> mail: cuser@example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=duser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: duser
+15 -> 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>
<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
#
# 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
#
# return the key itself.
#
# For example, NEVER do this in a map defining $mydestination:
+#
# .in +4
# query_filter = domain=*
# .br
# .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
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
#include <mail_conf.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_proto.h>
#include <anvil_clnt.h>
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)
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,
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
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
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
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
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
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
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
#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>
/*
* 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);
dsn_buf = dsb_create();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
int main(int argc, char **argv)
0,
};
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Pass control to the single-threaded service skeleton.
*/
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
#include <mail_params.h>
#include <record.h>
#include <rec_type.h>
+#include <mail_version.h>
/* Single-threaded server skeleton. */
}
}
+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.
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
#include <flush_clnt.h>
#include <sent.h>
#include <dsn_util.h>
+#include <mail_version.h>
/* Single server skeleton. */
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);
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
#include <dsn_util.h>
#include <sys_exits.h>
#include <mail_proto.h>
+#include <mail_version.h>
/* Single server skeleton. */
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);
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
/* Global library. */
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_queue.h>
#include <mail_proto.h>
#include <mail_flush.h>
/* 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;
var_fflush_domains);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the single-threaded skeleton */
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,
msg_fatal("usage: %s [-cr] [-s size] messages directory_entries", myname);
}
+MAIL_VERSION_STAMP_DECLARE;
+
int main(int argc, char **argv)
{
int op_count;
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) {
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
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
/* .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
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;
#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.
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) {
myfree(buf);
}
-static int dict_ldap_get_errno(LDAP * ld)
+static int dict_ldap_get_errno(LDAP *ld)
{
int rc;
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;
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;
}
/* 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;
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,
#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,
* 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 char* name)
+static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage *res,
+ VSTRING *result, const char *name)
{
static int recursion = 0;
static int expansion;
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;
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)
myname, recursion, attr);
continue;
}
-
valcount = ldap_count_values_len(vals);
/*
* 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 */
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);
}
msg_info("%s: Skipping lookup of '%s'", myname, name);
return (0);
}
-
#define INIT_VSTR(buf, len) do { \
if (buf == 0) \
buf = vstring_alloc(len); \
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);
}
/*
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);
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.
*/
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",
break;
default:
+
/*
* Rats. The search didn't work.
*/
* 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;
/*
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);
}
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);
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
*/
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 =
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;
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);
* 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
#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
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
#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>
flush_init();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the single-threaded skeleton */
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,
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
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)
WATCHDOG *watchdog;
ARGV *import_env;
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Initialize.
*/
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.
*/
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?
*/
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.
*/
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?
*/
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.
*/
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?
*
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
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
#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>
qmgr_deferred_run_event(0, (char *) 0);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
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
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
#include <lex_822.h>
#include <input_transp.h>
#include <rec_attr_map.h>
+#include <mail_version.h>
/* Single-threaded server skeleton. */
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)
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.
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
#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>
flush_init();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the single-threaded skeleton */
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,
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
#include <mail_conf.h>
#include <mail_dict.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mkmap.h>
#include <mail_task.h>
myname);
}
+MAIL_VERSION_STAMP_DECLARE;
+
int main(int argc, char **argv)
{
char *path_name;
int sequence = 0;
int found;
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Be consistent with file permissions.
*/
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
#include <mail_queue.h>
#include <mail_conf.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_proto.h>
/* Application-specific. */
myname);
}
+MAIL_VERSION_STAMP_DECLARE;
+
int main(int argc, char **argv)
{
VSTRING *buffer;
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
}
}
/^(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"
}
}
/^(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"
}
}
/^(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"
}
}
/^(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"
}
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main */
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.
*/
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
#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>
postdrop_sig(0);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
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.
*/
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
#include <mail_conf.h>
#include <mail_params.h>
+#include <mail_version.h>
/* Additional installation parameters. */
msg_fatal("setenv: %m");
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - run administrative script from controlled environment */
int main(int argc, char **argv)
0,
};
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Be consistent with file permissions.
*/
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
#include <mail_proto.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_conf.h>
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;
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
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
/* Global library. */
#include <mail_params.h>
+#include <mail_version.h>
#include <dot_lockfile.h>
#include <deliver_flock.h>
#include <mail_conf.h>
exit(EX_TEMPFAIL);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - go for it */
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.
*/
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
/* Global library. */
#include <mail_params.h> /* XXX right place for LOG_FACILITY? */
+#include <mail_version.h>
#include <mail_conf.h>
#include <mail_task.h>
vstring_free(buf);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - logger */
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.
*/
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
/* 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>
/* 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;
/* 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);
/* 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;
/* 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;
myname);
}
+MAIL_VERSION_STAMP_DECLARE;
+
int main(int argc, char **argv)
{
char *path_name;
int sequence = 0;
int found;
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Be consistent with file permissions.
*/
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++;
}
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);
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);
}
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
#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 */
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)
ARGV *import_env;
int bad_site;
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Be consistent with file permissions.
*/
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
#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>
interrupted(0);
}
+MAIL_VERSION_STAMP_DECLARE;
+
int main(int argc, char **argv)
{
int fd;
0,
};
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Be consistent with file permissions.
*/
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
#include <mail_conf.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_proto.h>
#include <dict_proxy.h>
}
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the multi-threaded skeleton */
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,
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
#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>
qmgr_deferred_run_event(0, (char *) 0);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
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
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
/* Global library. */
#include <mail_params.h>
+#include <mail_version.h>
#include <record.h>
#include <rec_type.h>
#include <mail_proto.h>
input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
int main(int argc, char **argv)
0,
};
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Pass control to the single-threaded service skeleton.
*/
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
/* Global library. */
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_proto.h>
#include <scache.h>
scache_start_time = event_time();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the multi-threaded skeleton */
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,
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
#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>
exit(EX_TEMPFAIL);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
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.
*/
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))
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
#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>
#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)
/* 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;
}
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the single-threaded server skeleton */
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,
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
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
#include <deliver_request.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_conf.h>
#include <debug_peer.h>
#include <flush_clnt.h>
}
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the single-threaded skeleton */
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.
*/
anvil_clnt = anvil_clnt_create();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
int main(int argc, char **argv)
0,
};
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Pass control to the single-threaded service skeleton.
*/
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
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
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
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
/* Global library. */
#include <qmqp_proto.h>
+#include <mail_version.h>
/* Application-specific. */
msg_fatal("usage: %s [-cv] [-x time] [host]:port backlog", myname);
}
+MAIL_VERSION_STAMP_DECLARE;
+
int main(int argc, char **argv)
{
int sock;
const char *protocols = INET_PROTO_NAME_ALL;
INET_PROTO_INFO *proto_info;
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Fix 20051207.
*/
#include <mail_date.h>
#include <qmqp_proto.h>
+#include <mail_version.h>
/* Application-specific. */
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)
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);
#include <smtp_stream.h>
#include <mail_date.h>
+#include <mail_version.h>
/* Application-specific. */
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;
const char *root_dir = 0;
const char *user_privs = 0;
+ /*
+ * Fingerprint executables and core dumps.
+ */
+ MAIL_VERSION_STAMP_ALLOCATE;
+
/*
* Fix 20051207.
*/
#include <smtp_stream.h>
#include <mail_date.h>
+#include <mail_version.h>
/* Application-specific. */
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)
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);
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
/* 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>
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);
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)
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,
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
#include <mail_conf.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <tls_mgr.h>
#include <mail_proto.h>
tls_prng_exch_update(rand_exch);
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - the main program */
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.
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
/* Global library. */
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_proto.h>
#include <resolve_local.h>
#include <mail_conf.h>
var_idle_limit = 1;
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the multi-threaded skeleton code */
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,
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
#include <mail_conf.h>
#include <mail_params.h>
+#include <mail_version.h>
#include <mail_proto.h>
#include <post_mail.h>
#include <verify_clnt.h>
setsid();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the multi-threaded skeleton */
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,
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
#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>
flush_init();
}
+MAIL_VERSION_STAMP_DECLARE;
+
/* main - pass control to the single-threaded skeleton */
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,