]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.2-20041215
authorWietse Venema <wietse@porcupine.org>
Wed, 15 Dec 2004 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:30:17 +0000 (06:30 +0000)
18 files changed:
postfix/HISTORY
postfix/examples/chroot-setup/Solaris10 [new file with mode: 0644]
postfix/html/postconf.1.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/man/man1/postconf.1
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/mail_version.h
postfix/src/global/mkmap.h
postfix/src/global/mkmap_open.c
postfix/src/postconf/postconf.c
postfix/src/smtp/smtp.c
postfix/src/util/dict_dbm.c
postfix/src/util/dict_open.c
postfix/src/util/dict_sdbm.c

index ac72609b5dc555e39875292d191af3c255d3667e..67a0f671c0f7c2a7e0c5f06f2a316d7888e2959d 100644 (file)
@@ -9926,6 +9926,39 @@ Apologies for any names omitted.
        Hexadecimal encode/decode routines, from the TLS-enabled
        version. Files:  util/hext_code.[hc].
 
+20041212
+
+       Solaris 10/ix86 chroot setup script update by J.D. Bronson.
+
+20041213
+
+       Updated the SDBM dictionary interface. It had fallen behind
+       with the Postfix dictionary interfaces that were already
+       bundled with Postfix. Files: util/dict_sdbm.[hc].
+
+       Cleanup: "postconf -m" (show all available map types) now
+       produces sorted output.  File: util/dict_open.c.
+
+20041215
+
+       No bugfix: tests with the new "postmap -s" feature show
+       that SDBM first/next operations never worked with Postfix/TLS
+       patch 20040829 (verified with the 20040829 dict_sdbm.c
+       module on Linux and FreeBSD).  The code stops after finding
+       one database element.  Other SDBM versions found on the
+       Internet will find all database entries, but report an I/O
+       error after the last database element is found. All this
+       would be easy enough to fix, but the SDBM library is not
+       part of Postfix, and never will be.
+
+       Bugfix: the sequence operator in the DBM and SDBM clients
+       released the shared lock after reading the next key but
+       before reading the corresponding value. This was never a
+       problem, because the sequence operator was used only in
+       the Postfix/TLS patch. This used the SDBM sequence operator
+       which didn't work as discussed above. Files:  util/dict_dbm.c,
+       util/dict_sdbm.c.
+
 Open problems:
 
        Med: implement ${name[?:]value} in main.cf or update the
@@ -10024,9 +10057,6 @@ Open problems:
        servers seem to need this in particular. Need a way to
        expire cached results that are too old.
 
-       Medium: make address rewriting on/off configurable for
-       envelopes and/or headers.
-
        Low: generic showq protocol, to allow for more intelligent
        processing than just mailq. Maybe marry this with postsuper.
 
diff --git a/postfix/examples/chroot-setup/Solaris10 b/postfix/examples/chroot-setup/Solaris10
new file mode 100644 (file)
index 0000000..a815218
--- /dev/null
@@ -0,0 +1,110 @@
+#!/bin/sh
+# From original Solaris 8 version by Matthew X. Economou
+# Solaris 10 version updated by JD Bronson. Caution: this copies
+# too many files. There is no need to copy libc.so and other files
+# that are already linked in before a Postfix daemon chroots itself.
+
+COMMAND_DIRECTORY="/usr/sbin"
+DAEMON_DIRECTORY="/usr/libexec/postfix"
+QUEUE_DIRECTORY="/var/spool/postfix"
+
+## Copy any shared libraries, device entries, or configuration files
+## needed by Postfix into the jail.
+binlist="
+$DAEMON_DIRECTORY/virtual
+$DAEMON_DIRECTORY/trivial-rewrite
+$DAEMON_DIRECTORY/spawn
+$DAEMON_DIRECTORY/smtpd
+$DAEMON_DIRECTORY/smtp
+$DAEMON_DIRECTORY/showq
+$DAEMON_DIRECTORY/qmqpd
+$DAEMON_DIRECTORY/qmgr
+$DAEMON_DIRECTORY/proxymap
+$DAEMON_DIRECTORY/pipe
+$DAEMON_DIRECTORY/pickup
+$DAEMON_DIRECTORY/nqmgr
+$DAEMON_DIRECTORY/master
+$DAEMON_DIRECTORY/local
+$DAEMON_DIRECTORY/lmtp
+$DAEMON_DIRECTORY/flush
+$DAEMON_DIRECTORY/error
+$DAEMON_DIRECTORY/cleanup
+$DAEMON_DIRECTORY/bounce
+/usr/lib/sendmail
+$COMMAND_DIRECTORY/postsuper
+$COMMAND_DIRECTORY/postqueue
+$COMMAND_DIRECTORY/postmap
+$COMMAND_DIRECTORY/postlog
+$COMMAND_DIRECTORY/postlock
+$COMMAND_DIRECTORY/postkick
+$COMMAND_DIRECTORY/postfix
+$COMMAND_DIRECTORY/postdrop
+$COMMAND_DIRECTORY/postconf
+$COMMAND_DIRECTORY/postcat
+$COMMAND_DIRECTORY/postalias
+"
+ldd $binlist | awk '/[=]>/ { print $3 }' | sort -u | while read i
+do
+    mkdir -p $QUEUE_DIRECTORY`dirname $i`
+    ## Sun's version of tar sucks.  We'll have to remove the leading
+    ## slashes from file names ourself, otherwise the copy doesn't
+    ## work.
+    (cd / && tar cphf - `echo $i | sed -e 's/^\///'`) | (cd $QUEUE_DIRECTORY && tar xpf -)
+done
+
+## More stuff for the jail, mostly discovered by inspection
+## (e.g. strings, lsof).
+more="
+/dev/zero
+/dev/null
+/dev/udp6
+/dev/tcp6
+/dev/udp
+/dev/tcp
+/dev/rawip
+/dev/ticlts
+/dev/ticotsord
+/dev/ticots
+/devices/pseudo/mm@0:zero
+/devices/pseudo/mm@0:null
+/devices/pseudo/udp6@0:udp6
+/devices/pseudo/tcp6@0:tcp6
+/devices/pseudo/udp@0:udp
+/devices/pseudo/tcp@0:tcp
+/devices/pseudo/icmp@0:icmp
+/devices/pseudo/tl@0:ticlts
+/devices/pseudo/tl@0:ticotsord
+/devices/pseudo/tl@0:ticots
+/etc/hosts
+/etc/nsswitch.conf
+/etc/netconfig
+/etc/passwd
+/etc/resolv.conf
+/etc/default/init
+/etc/default/nss
+/etc/inet/services
+/etc/inet/hosts
+/etc/services
+/lib/ld.so
+/lib/ld.so.1
+/usr/lib/nss_dns.so.1
+/usr/lib/sparcv9/straddr.so
+/usr/lib/straddr.so
+/usr/lib/straddr.so.2
+/lib/libintl.so
+/lib/libintl.so.1
+/lib/libw.so
+/lib/libw.so.1
+/lib/nss_nis.so.1
+/lib/nss_nisplus.so.1
+/lib/nss_dns.so.1
+/lib/nss_files.so.1
+/usr/share/lib/zoneinfo
+/var/ld/ld.config
+"
+for i in $more; do
+    mkdir -p $QUEUE_DIRECTORY`dirname $i`
+    (cd / && tar cpf - `echo $i | sed -e 's/^\///'`) | (cd $QUEUE_DIRECTORY && tar xpf -)
+done
+
+exit 0
index 0398b2c0b2aa4143061ffccf23852cc33e67a16b..0150a6bb4fc601dc2e63d5f6a6a7a5425d54a916 100644 (file)
@@ -112,6 +112,10 @@ POSTCONF(1)                                           POSTCONF(1)
                      The  file  format  is  described   in   <a href="regexp_table.5.html"><b>reg-</b></a>
                      <a href="regexp_table.5.html"><b>exp_table</b>(5)</a>.
 
+              <b>sdbm</b>   An indexed file type based on hashing.  This
+                     is available only on  systems  with  support
+                     for SDBM databases.
+
               <b>static</b> (read-only)
                      A  table  that  always  returns  its name as
                      lookup result.  For  example,  <b>static:foobar</b>
index 3b5f2f4b210397a26afc60c4287889ce292c244f..f36e3b6c8e79c138a116f3d466f9b9e2cfb27a06 100644 (file)
@@ -5948,11 +5948,12 @@ Example:
 (default: empty)</b></DT><DD>
 
 <p>
-If non-empty, filters the SMTP server's list of offered SASL mechanisms.
-Different client and server implementations may support different
-mechanism lists. By default, the client will use the intersection of the
-two. <a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> further restricts what server mechanisms
-the client will take into consideration.  </p>
+If non-empty, a Postfix SMTP client filter for the remote SMTP
+server's list of offered SASL mechanisms.  Different client and
+server implementations may support different mechanism lists. By
+default, the Postfix SMTP client will use the intersection of the
+two. <a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> further restricts what server
+mechanisms the client will take into consideration.  </p>
 
 <p> Specify mechanism names, "/file/name" patterns or "<a href="DATABASE_README.html">type:table</a>"
 lookup tables. The right-hand side result from "<a href="DATABASE_README.html">type:table</a>" lookups
index 28fc4b42bcc9147d5a62828924a9128ec8150d8c..46f3659cb7343bca836abca1252f2962e927849e 100644 (file)
@@ -173,29 +173,30 @@ SMTP(8)                                                   SMTP(8)
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> (empty)</b>
-              If  non-empty,  filters  the  SMTP server's list of
-              offered SASL mechanisms.
+              If  non-empty, a Postfix SMTP client filter for the
+              remote SMTP server's list of  offered  SASL  mecha-
+              nisms.
 
 <b>RESOURCE AND RATE CONTROLS</b>
        <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a>      ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destina</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">tion_concurrency_limit</a>)</b>
-              The maximal number of parallel  deliveries  to  the
-              same  destination  via  the  smtp  message delivery
+              The  maximal  number  of parallel deliveries to the
+              same destination  via  the  smtp  message  delivery
               transport.
 
        <b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a>        ($<a href="postconf.5.html#default_destination_recipient_limit">default_destina</a>-</b>
        <b><a href="postconf.5.html#default_destination_recipient_limit">tion_recipient_limit</a>)</b>
-              The maximal number of recipients per  delivery  via
+              The  maximal  number of recipients per delivery via
               the smtp message delivery transport.
 
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The  SMTP  client  time  limit for completing a TCP
+              The SMTP client time limit  for  completing  a  TCP
               connection,  or  zero  (use  the  operating  system
               built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The  SMTP client time limit for sending the HELO or
-              EHLO command, and for receiving the initial  server
+              The SMTP client time limit for sending the HELO  or
+              EHLO  command, and for receiving the initial server
               response.
 
        <b><a href="postconf.5.html#smtp_xforward_timeout">smtp_xforward_timeout</a> (300s)</b>
@@ -203,30 +204,30 @@ SMTP(8)                                                   SMTP(8)
               command, and for receiving the server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The SMTP client time limit  for  sending  the  MAIL
-              FROM   command,   and   for  receiving  the  server
+              The  SMTP  client  time  limit for sending the MAIL
+              FROM  command,  and  for   receiving   the   server
               response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The SMTP client time limit  for  sending  the  SMTP
-              RCPT  TO  command,  and  for  receiving  the server
+              The  SMTP  client  time  limit for sending the SMTP
+              RCPT TO  command,  and  for  receiving  the  server
               response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The SMTP client time limit  for  sending  the  SMTP
-              DATA   command,   and   for  receiving  the  server
+              The  SMTP  client  time  limit for sending the SMTP
+              DATA  command,  and  for   receiving   the   server
               response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The SMTP client time limit  for  sending  the  SMTP
+              The  SMTP  client  time  limit for sending the SMTP
               message content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
-              The  SMTP  client  time  limit for sending the SMTP
+              The SMTP client time limit  for  sending  the  SMTP
               ".", and for receiving the server response.
 
        <b><a href="postconf.5.html#smtp_quit_timeout">smtp_quit_timeout</a> (300s)</b>
-              The SMTP client time limit  for  sending  the  QUIT
+              The  SMTP  client  time  limit for sending the QUIT
               command, and for receiving the server response.
 
        Available in Postfix version 2.1 and later:
@@ -237,77 +238,77 @@ SMTP(8)                                                   SMTP(8)
               lookups, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The  maximal  number  of SMTP sessions per delivery
-              request before giving up or delivering to  a  fall-
+              The maximal number of SMTP  sessions  per  delivery
+              request  before  giving up or delivering to a fall-
               back relay host, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
-              The  SMTP  client  time  limit for sending the RSET
+              The SMTP client time limit  for  sending  the  RSET
               command, and for receiving the server response.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently enable SMTP connection caching for  the
+              Permanently  enable SMTP connection caching for the
               specified destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily  enable SMTP connection caching while a
+              Temporarily enable SMTP connection caching while  a
               destination has a high volume of mail in the active
               queue.
 
        <b><a href="postconf.5.html#smtp_connection_cache_reuse_limit">smtp_connection_cache_reuse_limit</a> (10)</b>
               When SMTP connection caching is enabled, the number
-              of times that an SMTP session is reused  before  it
+              of  times  that an SMTP session is reused before it
               is closed.
 
        <b><a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> (2s)</b>
               When SMTP connection caching is enabled, the amount
-              of time that an unused SMTP client socket  is  kept
+              of  time  that an unused SMTP client socket is kept
               open before it is closed.
 
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The  increment  in  verbose  logging  level  when a
-              remote client or server matches a  pattern  in  the
+              The increment  in  verbose  logging  level  when  a
+              remote  client  or  server matches a pattern in the
               <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of remote client or server hostname
-              or network address patterns that cause the  verbose
-              logging  level  to increase by the amount specified
+              Optional list of remote client or  server  hostname
+              or  network address patterns that cause the verbose
+              logging level to increase by the  amount  specified
               in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The recipient  of  postmaster  notifications  about
-              mail  delivery  problems that are caused by policy,
+              The  recipient  of  postmaster  notifications about
+              mail delivery problems that are caused  by  policy,
               resource, software or protocol errors.
 
        <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
-              The list of error classes that are reported to  the
+              The  list of error classes that are reported to the
               postmaster.
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where  the  Postfix SMTP client should deliver mail
+              Where the Postfix SMTP client should  deliver  mail
               when it detects a "mail loops back to myself" error
               condition.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix main.cf and
+              The default location of  the  Postfix  main.cf  and
               master.cf configuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process may take  to
-              handle  a  request  before  it  is  terminated by a
+              How  much time a Postfix daemon process may take to
+              handle a request  before  it  is  terminated  by  a
               built-in watchdog timer.
 
        <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
-              Disable DNS lookups in the Postfix  SMTP  and  LMTP
+              Disable  DNS  lookups  in the Postfix SMTP and LMTP
               clients.
 
        <b><a href="postconf.5.html#fallback_relay">fallback_relay</a> (empty)</b>
-              Optional  list of relay hosts for SMTP destinations
+              Optional list of relay hosts for SMTP  destinations
               that can't be found or that are unreachable.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
@@ -319,25 +320,25 @@ SMTP(8)                                                   SMTP(8)
               over an internal communication channel.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The maximum amount of time  that  an  idle  Postfix
-              daemon  process  waits for the next service request
+              The  maximum  amount  of  time that an idle Postfix
+              daemon process waits for the next  service  request
               before exiting.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
-              The maximal number of connection requests before  a
+              The  maximal number of connection requests before a
               Postfix daemon process terminates.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The  process ID of a Postfix command or daemon pro-
+              The process ID of a Postfix command or daemon  pro-
               cess.
 
        <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The process name of a  Postfix  command  or  daemon
+              The  process  name  of  a Postfix command or daemon
               process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
               The network interface addresses that this mail sys-
-              tem receives mail on by way of a proxy  or  network
+              tem  receives  mail on by way of a proxy or network
               address translation unit.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
@@ -345,22 +346,22 @@ SMTP(8)                                                   SMTP(8)
               client should bind to when making a connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The hostname to send in the SMTP EHLO or HELO  com-
+              The  hostname to send in the SMTP EHLO or HELO com-
               mand.
 
        <b><a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a> (dns)</b>
-              What  mechanisms  when the SMTP client uses to look
+              What mechanisms when the SMTP client uses  to  look
               up a host's IP address.
 
        <b><a href="postconf.5.html#smtp_randomize_addresses">smtp_randomize_addresses</a> (yes)</b>
-              Randomize the order  of  equal-preference  MX  host
+              Randomize  the  order  of  equal-preference MX host
               addresses.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
-              The  mail system name that is prepended to the pro-
+              The mail system name that is prepended to the  pro-
               cess  name  in  syslog  records,  so  that  "smtpd"
               becomes, for example, "postfix/smtpd".
 
@@ -377,7 +378,7 @@ SMTP(8)                                                   SMTP(8)
        <a href="SASL_README.html">SASL_README</a>, Postfix SASL howto
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index b2a24623d7b0d7b2a7de84c44ddb206827329e58..24d2114b5cb805ae6f6f0983b936b705b3e0be91 100644 (file)
@@ -95,6 +95,9 @@ A lookup table that is implemented via the Postfix
 .IP "\fBregexp\fR (read-only)"
 A lookup table based on regular expressions. The file format is
 described in \fBregexp_table\fR(5).
+.IP \fBsdbm\fR
+An indexed file type based on hashing.
+This is available only on systems with support for SDBM databases.
 .IP "\fBstatic\fR (read-only)"
 A table that always returns its name as lookup result. For example,
 \fBstatic:foobar\fR always returns the string \fBfoobar\fR as lookup
index accb79de3fa48156a6c9b8bae53bf56330e36d2b..5bf87ce68408c86d54b48eb79bfbb9cc442ffc56 100644 (file)
@@ -3174,11 +3174,12 @@ smtp_sasl_auth_enable = yes
 .ad
 .ft R
 .SH smtp_sasl_mechanism_filter (default: empty)
-If non-empty, filters the SMTP server's list of offered SASL mechanisms.
-Different client and server implementations may support different
-mechanism lists. By default, the client will use the intersection of the
-two. smtp_sasl_mechanism_filter further restricts what server mechanisms
-the client will take into consideration.
+If non-empty, a Postfix SMTP client filter for the remote SMTP
+server's list of offered SASL mechanisms.  Different client and
+server implementations may support different mechanism lists. By
+default, the Postfix SMTP client will use the intersection of the
+two. smtp_sasl_mechanism_filter further restricts what server
+mechanisms the client will take into consideration.
 .PP
 Specify mechanism names, "/file/name" patterns or "type:table"
 lookup tables. The right-hand side result from "type:table" lookups
index 83bb849e149fc1e1927d0a59cea4f9d848142c9c..d14b61a700f91bcb6b66c2ced941c50b7b95a0bd 100644 (file)
@@ -165,7 +165,8 @@ to use.
 .PP
 Available in Postfix version 2.2 and later:
 .IP "\fBsmtp_sasl_mechanism_filter (empty)\fR"
-If non-empty, filters the SMTP server's list of offered SASL mechanisms.
+If non-empty, a Postfix SMTP client filter for the remote SMTP
+server's list of offered SASL mechanisms.
 .SH "RESOURCE AND RATE CONTROLS"
 .na
 .nf
index 1ced6c0599be7914d960d2a98c878b052f056e4e..433b64bcc8626fba993a29ded34a00e7ff975c4f 100644 (file)
@@ -3730,11 +3730,12 @@ smtp_sasl_security_options = noplaintext
 %PARAM smtp_sasl_mechanism_filter
 
 <p>
-If non-empty, filters the SMTP server's list of offered SASL mechanisms.
-Different client and server implementations may support different
-mechanism lists. By default, the client will use the intersection of the
-two. smtp_sasl_mechanism_filter further restricts what server mechanisms
-the client will take into consideration.  </p>
+If non-empty, a Postfix SMTP client filter for the remote SMTP
+server's list of offered SASL mechanisms.  Different client and
+server implementations may support different mechanism lists. By
+default, the Postfix SMTP client will use the intersection of the
+two. smtp_sasl_mechanism_filter further restricts what server
+mechanisms the client will take into consideration.  </p>
 
 <p> Specify mechanism names, "/file/name" patterns or "type:table"
 lookup tables. The right-hand side result from "type:table" lookups
index 4adf152e87a45e8c4a6e1d4d66629310d59e4003..0f23fb9402eaa8c2ff69025f1e2cc0982025e745 100644 (file)
@@ -1070,6 +1070,7 @@ mkmap_open.o: ../../include/argv.h
 mkmap_open.o: ../../include/dict_db.h
 mkmap_open.o: ../../include/dict_cdb.h
 mkmap_open.o: ../../include/dict_dbm.h
+mkmap_open.o: ../../include/dict_sdbm.h
 mkmap_open.o: ../../include/sigdelay.h
 mkmap_open.o: ../../include/mymalloc.h
 mkmap_open.o: mkmap.h
index 2361aaba180818bfdf9bbf0663c1538620b7ad6c..bf355f8ed8f591e3a0ae0c5f835e9c310c8def29 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change the patchlevel and the release date. Snapshots change the
   * release date only.
   */
-#define MAIL_RELEASE_DATE      "20041211"
+#define MAIL_RELEASE_DATE      "20041215"
 #define MAIL_VERSION_NUMBER    "2.2"
 
 #define VAR_MAIL_VERSION       "mail_version"
index 848dbc003fdedd0ec9ebbfd8bd0eff29a7f63da2..45e32c69c2837d9c7150d3681778ba6d9f3a7650 100644 (file)
@@ -39,6 +39,7 @@ extern MKMAP *mkmap_dbm_open(const char *);
 extern MKMAP *mkmap_cdb_open(const char *);
 extern MKMAP *mkmap_hash_open(const char *);
 extern MKMAP *mkmap_btree_open(const char *);
+extern MKMAP *mkmap_sdbm_open(const char *);
 
 /* LICENSE
 /* .ad
index 92ed0f96c8eb04b5919ad4e08d53cfaf0836b67c..a3caf952fdc19f725bdeb6e57376c9f65ad8bfce 100644 (file)
@@ -65,6 +65,7 @@
 #include <dict_db.h>
 #include <dict_cdb.h>
 #include <dict_dbm.h>
+#include <dict_sdbm.h>
 #include <sigdelay.h>
 #include <mymalloc.h>
 
index 07567361d769a075fcf309e3dd33ada32e111804..8da57e1e23f3afd740a2ca18d9746370098f24d8 100644 (file)
@@ -89,6 +89,9 @@
 /* .IP "\fBregexp\fR (read-only)"
 /*     A lookup table based on regular expressions. The file format is
 /*     described in \fBregexp_table\fR(5).
+/* .IP \fBsdbm\fR
+/*     An indexed file type based on hashing.
+/*     This is available only on systems with support for SDBM databases.
 /* .IP "\fBstatic\fR (read-only)"
 /*     A table that always returns its name as lookup result. For example,
 /*     \fBstatic:foobar\fR always returns the string \fBfoobar\fR as lookup
index 0ecc7140e3bccc94dba216f683834e0ab28f278e..9ffad1b5c440b3c01b4839ab63bac479c2a8657b 100644 (file)
 /* .PP
 /*     Available in Postfix version 2.2 and later:
 /* .IP "\fBsmtp_sasl_mechanism_filter (empty)\fR"
-/*     If non-empty, filters the SMTP server's list of offered SASL mechanisms.
+/*     If non-empty, a Postfix SMTP client filter for the remote SMTP
+/*     server's list of offered SASL mechanisms.
 /* RESOURCE AND RATE CONTROLS
 /* .ad
 /* .fi
index fa58ad004316417d01d86d61a1c211a856b9bed7..87e527694368394a87f29d268168eaebc990334d 100644 (file)
@@ -213,7 +213,6 @@ static int dict_dbm_delete(DICT *dict, const char *name)
     DICT_DBM *dict_dbm = (DICT_DBM *) dict;
     datum   dbm_key;
     int     status = 1;
-    int     flags = 0;
 
     /*
      * Sanity check.
@@ -281,7 +280,6 @@ static int dict_dbm_sequence(DICT *dict, int function,
     DICT_DBM *dict_dbm = (DICT_DBM *) dict;
     datum   dbm_key;
     datum   dbm_value;
-    int     status = 0;
 
     /*
      * Acquire a shared lock.
@@ -304,13 +302,6 @@ static int dict_dbm_sequence(DICT *dict, int function,
        msg_panic("%s: invalid function: %d", myname, function);
     }
 
-    /*
-     * Release the shared lock.
-     */
-    if ((dict->flags & DICT_FLAG_LOCK)
-       && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
-
     if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
 
        /*
@@ -349,6 +340,14 @@ static int dict_dbm_sequence(DICT *dict, int function,
            msg_fatal("error seeking %s: %m", dict_dbm->dict.name);
        return (1);                             /* no error: eof/not found */
     }
+
+    /*
+     * Release the shared lock.
+     */
+    if ((dict->flags & DICT_FLAG_LOCK)
+       && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+       msg_fatal("%s: unlock dictionary: %m", dict_dbm->dict.name);
+
     return (0);
 }
 
index 008d3becbbf8ec0a16a2cb6b90d122edf681b2c3..0a1ff93ab2613370d27f616995c7ec010ecf0a1d 100644 (file)
@@ -42,6 +42,8 @@
 /*     dict_open_register(type, open)
 /*     char    *type;
 /*     DICT    *(*open) (const char *, int, int);
+/*
+/*     ARGV    *dict_mapnames()
 /* DESCRIPTION
 /*     This module implements a low-level interface to multiple
 /*     physical dictionary types.
 /*     associated data structures.
 /*
 /*     dict_open_register() adds support for a new dictionary type.
+/*
+/*     dict_mapnames() returns a sorted list with the names of all available 
+/*     dictionary types.
 /* DIAGNOSTICS
 /*     Fatal error: open error, unsupported dictionary type, attempt to
 /*     update non-writable dictionary.
 
 #include <sys_defs.h>
 #include <string.h>
+#include <stdlib.h>
 
 #ifdef STRCASECMP_IN_STRINGS_H
 #include <strings.h>
@@ -302,6 +308,13 @@ void    dict_open_register(const char *type,
     htable_enter(dict_open_hash, dp->type, (char *) dp);
 }
 
+/* dict_sort_alpha_cpp - qsort() callback */
+
+static int dict_sort_alpha_cpp(const void *a, const void *b)
+{
+    return (strcmp(((char **) a)[0], ((char **) b)[0]));
+}
+
 /* dict_mapnames - return an ARGV of available map_names */
 
 ARGV   *dict_mapnames()
@@ -318,6 +331,8 @@ ARGV   *dict_mapnames()
        dp = (DICT_OPEN_INFO *) ht[0]->value;
        argv_add(mapnames, dp->type, ARGV_END);
     }
+    qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]),
+         dict_sort_alpha_cpp);
     myfree((char *) ht_info);
     argv_terminate(mapnames);
     return mapnames;
index d123fcf8db27c5098a115552714f8ba791ad8cfc..35ee7782ec9bd0138a46c49766958c4dd2365d52 100644 (file)
 typedef struct {
     DICT    dict;                      /* generic members */
     SDBM   *dbm;                       /* open database */
-    char   *path;                      /* pathname */
+    VSTRING *key_buf;                  /* key buffer */
+    VSTRING *val_buf;                  /* result buffer */
 } DICT_SDBM;
 
+#define SCOPY(buf, data, size) \
+    vstring_str(vstring_strncpy(buf ? buf : (buf = vstring_alloc(10)), data, size))
+
 /* dict_sdbm_lookup - find database entry */
 
 static const char *dict_sdbm_lookup(DICT *dict, const char *name)
@@ -70,9 +74,14 @@ static const char *dict_sdbm_lookup(DICT *dict, const char *name)
     DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
     datum   dbm_key;
     datum   dbm_value;
-    static VSTRING *buf;
     const char *result = 0;
 
+    /*
+     * Sanity check.
+     */
+    if ((dict->flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
+       msg_panic("dict_sdbm_lookup: no DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL flag");
+
     dict_errno = 0;
 
     /*
@@ -80,7 +89,7 @@ static const char *dict_sdbm_lookup(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_sdbm->dict.name);
 
     /*
      * See if this DBM file was written with one null byte appended to key
@@ -92,7 +101,7 @@ static const char *dict_sdbm_lookup(DICT *dict, const char *name)
        dbm_value = sdbm_fetch(dict_sdbm->dbm, dbm_key);
        if (dbm_value.dptr != 0) {
            dict->flags &= ~DICT_FLAG_TRY0NULL;
-           result = dbm_value.dptr;
+           result = SCOPY(dict_sdbm->val_buf, dbm_value.dptr, dbm_value.dsize);
        }
     }
 
@@ -105,11 +114,8 @@ static const char *dict_sdbm_lookup(DICT *dict, const char *name)
        dbm_key.dsize = strlen(name);
        dbm_value = sdbm_fetch(dict_sdbm->dbm, dbm_key);
        if (dbm_value.dptr != 0) {
-           if (buf == 0)
-               buf = vstring_alloc(10);
-           vstring_strncpy(buf, dbm_value.dptr, dbm_value.dsize);
            dict->flags &= ~DICT_FLAG_TRY1NULL;
-           result = vstring_str(buf);
+           result = SCOPY(dict_sdbm->val_buf, dbm_value.dptr, dbm_value.dsize);
        }
     }
 
@@ -118,7 +124,7 @@ static const char *dict_sdbm_lookup(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->dict.name);
 
     return (result);
 }
@@ -132,6 +138,12 @@ static void dict_sdbm_update(DICT *dict, const char *name, const char *value)
     datum   dbm_value;
     int     status;
 
+    /*
+     * Sanity check.
+     */
+    if ((dict->flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
+       msg_panic("dict_sdbm_update: no DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL flag");
+
     dbm_key.dptr = (void *) name;
     dbm_value.dptr = (void *) value;
     dbm_key.dsize = strlen(name);
@@ -163,21 +175,21 @@ static void dict_sdbm_update(DICT *dict, const char *name, const char *value)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_sdbm->dict.name);
 
     /*
      * Do the update.
      */
     if ((status = sdbm_store(dict_sdbm->dbm, dbm_key, dbm_value,
      (dict->flags & DICT_FLAG_DUP_REPLACE) ? DBM_REPLACE : DBM_INSERT)) < 0)
-       msg_fatal("error writing SDBM database %s: %m", dict_sdbm->path);
+       msg_fatal("error writing SDBM database %s: %m", dict_sdbm->dict.name);
     if (status) {
        if (dict->flags & DICT_FLAG_DUP_IGNORE)
             /* void */ ;
        else if (dict->flags & DICT_FLAG_DUP_WARN)
-           msg_warn("%s: duplicate entry: \"%s\"", dict_sdbm->path, name);
+           msg_warn("%s: duplicate entry: \"%s\"", dict_sdbm->dict.name, name);
        else
-           msg_fatal("%s: duplicate entry: \"%s\"", dict_sdbm->path, name);
+           msg_fatal("%s: duplicate entry: \"%s\"", dict_sdbm->dict.name, name);
     }
 
     /*
@@ -185,10 +197,9 @@ static void dict_sdbm_update(DICT *dict, const char *name, const char *value)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->dict.name);
 }
 
-
 /* dict_sdbm_delete - delete one entry from the dictionary */
 
 static int dict_sdbm_delete(DICT *dict, const char *name)
@@ -196,14 +207,19 @@ static int dict_sdbm_delete(DICT *dict, const char *name)
     DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
     datum   dbm_key;
     int     status = 1;
-    int     flags = 0;
+
+    /*
+     * Sanity check.
+     */
+    if ((dict->flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
+       msg_panic("dict_sdbm_delete: no DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL flag");
 
     /*
      * Acquire an exclusive lock.
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_sdbm->dict.name);
 
     /*
      * See if this DBM file was written with one null byte appended to key
@@ -214,8 +230,8 @@ static int dict_sdbm_delete(DICT *dict, const char *name)
        dbm_key.dsize = strlen(name) + 1;
        sdbm_clearerr(dict_sdbm->dbm);
        if ((status = sdbm_delete(dict_sdbm->dbm, dbm_key)) < 0) {
-           if (sdbm_error(dict_sdbm->dbm) != 0)        /* fatal error */
-               msg_fatal("error deleting from %s: %m", dict_sdbm->path);
+           if (sdbm_error(dict_sdbm->dbm) != 0)/* fatal error */
+               msg_fatal("error deleting from %s: %m", dict_sdbm->dict.name);
            status = 1;                         /* not found */
        } else {
            dict->flags &= ~DICT_FLAG_TRY0NULL; /* found */
@@ -231,8 +247,8 @@ static int dict_sdbm_delete(DICT *dict, const char *name)
        dbm_key.dsize = strlen(name);
        sdbm_clearerr(dict_sdbm->dbm);
        if ((status = sdbm_delete(dict_sdbm->dbm, dbm_key)) < 0) {
-           if (sdbm_error(dict_sdbm->dbm) != 0)        /* fatal error */
-               msg_fatal("error deleting from %s: %m", dict_sdbm->path);
+           if (sdbm_error(dict_sdbm->dbm) != 0)/* fatal error */
+               msg_fatal("error deleting from %s: %m", dict_sdbm->dict.name);
            status = 1;                         /* not found */
        } else {
            dict->flags &= ~DICT_FLAG_TRY1NULL; /* found */
@@ -244,7 +260,7 @@ static int dict_sdbm_delete(DICT *dict, const char *name)
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->dict.name);
 
     return (status);
 }
@@ -252,26 +268,24 @@ static int dict_sdbm_delete(DICT *dict, const char *name)
 /* traverse the dictionary */
 
 static int dict_sdbm_sequence(DICT *dict, const int function,
-                                    const char **key, const char **value)
+                                     const char **key, const char **value)
 {
     char   *myname = "dict_sdbm_sequence";
     DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
     datum   dbm_key;
     datum   dbm_value;
-    int     status = 0;
-    static VSTRING *key_buf;
-    static VSTRING *value_buf;
 
     /*
      * Acquire a shared lock.
      */
     if ((dict->flags & DICT_FLAG_LOCK)
        && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
-       msg_fatal("%s: lock dictionary: %m", dict_sdbm->path);
+       msg_fatal("%s: lock dictionary: %m", dict_sdbm->dict.name);
 
     /*
      * Determine and execute the seek function. It returns the key.
      */
+    sdbm_clearerr(dict_sdbm->dbm);
     switch (function) {
     case DICT_SEQ_FUN_FIRST:
        dbm_key = sdbm_firstkey(dict_sdbm->dbm);
@@ -283,27 +297,12 @@ static int dict_sdbm_sequence(DICT *dict, const int function,
        msg_panic("%s: invalid function: %d", myname, function);
     }
 
-    /*
-     * Release the shared lock.
-     */
-    if ((dict->flags & DICT_FLAG_LOCK)
-       && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
-       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->path);
-
     if (dbm_key.dptr != 0 && dbm_key.dsize > 0) {
 
        /*
-        * See if this DB file was written with one null byte appended to key
-        * and value or not. If necessary, copy the key.
+        * Copy the key so that it is guaranteed null terminated.
         */
-       if (((char *) dbm_key.dptr)[dbm_key.dsize - 1] == 0) {
-           *key = dbm_key.dptr;
-       } else {
-           if (key_buf == 0)
-               key_buf = vstring_alloc(10);
-           vstring_strncpy(key_buf, dbm_key.dptr, dbm_key.dsize);
-           *key = vstring_str(key_buf);
-       }
+       *key = SCOPY(dict_sdbm->key_buf, dbm_key.dptr, dbm_key.dsize);
 
        /*
         * Fetch the corresponding value.
@@ -313,17 +312,9 @@ static int dict_sdbm_sequence(DICT *dict, const int function,
        if (dbm_value.dptr != 0 && dbm_value.dsize > 0) {
 
            /*
-            * See if this DB file was written with one null byte appended to
-            * key and value or not. If necessary, copy the key.
+            * Copy the value so that it is guaranteed null terminated.
             */
-           if (((char *) dbm_value.dptr)[dbm_value.dsize - 1] == 0) {
-               *value = dbm_value.dptr;
-           } else {
-               if (value_buf == 0)
-                   value_buf = vstring_alloc(10);
-               vstring_strncpy(value_buf, dbm_value.dptr, dbm_value.dsize);
-               *value = vstring_str(value_buf);
-           }
+           *value = SCOPY(dict_sdbm->val_buf, dbm_value.dptr, dbm_value.dsize);
        } else {
 
            /*
@@ -331,7 +322,7 @@ static int dict_sdbm_sequence(DICT *dict, const int function,
             * condition.
             */
            if (sdbm_error(dict_sdbm->dbm))
-               msg_fatal("error seeking %s: %m", dict_sdbm->path);
+               msg_fatal("error seeking %s: %m", dict_sdbm->dict.name);
            return (1);                         /* no error: eof/not found
                                                 * (should not happen!) */
        }
@@ -341,9 +332,17 @@ static int dict_sdbm_sequence(DICT *dict, const int function,
         * Determine if we have hit the last record or an error condition.
         */
        if (sdbm_error(dict_sdbm->dbm))
-           msg_fatal("error seeking %s: %m", dict_sdbm->path);
+           msg_fatal("error seeking %s: %m", dict_sdbm->dict.name);
        return (1);                             /* no error: eof/not found */
     }
+
+    /*
+     * Release the shared lock.
+     */
+    if ((dict->flags & DICT_FLAG_LOCK)
+       && myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
+       msg_fatal("%s: unlock dictionary: %m", dict_sdbm->dict.name);
+
     return (0);
 }
 
@@ -354,8 +353,11 @@ static void dict_sdbm_close(DICT *dict)
     DICT_SDBM *dict_sdbm = (DICT_SDBM *) dict;
 
     sdbm_close(dict_sdbm->dbm);
-    myfree(dict_sdbm->path);
-    myfree((char *) dict_sdbm);
+    if (dict_sdbm->key_buf)
+       vstring_free(dict_sdbm->key_buf);
+    if (dict_sdbm->val_buf)
+       vstring_free(dict_sdbm->val_buf);
+    dict_free(dict);
 }
 
 /* dict_sdbm_open - open SDBM data base */
@@ -368,8 +370,15 @@ DICT   *dict_sdbm_open(const char *path, int open_flags, int dict_flags)
     char   *dbm_path;
     int     lock_fd;
 
+    /*
+     * Note: DICT_FLAG_LOCK is used only by programs that do fine-grained (in
+     * the time domain) locking while accessing individual database records.
+     * 
+     * Programs such as postmap/postalias use their own large-grained (in the
+     * time domain) locks while rewriting the entire file.
+     */
     if (dict_flags & DICT_FLAG_LOCK) {
-       dbm_path = concatenate(path, ".pag", (char *) 0);
+       dbm_path = concatenate(path, ".dir", (char *) 0);
        if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0)
            msg_fatal("open database %s: %m", dbm_path);
        if (myflock(lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
@@ -387,9 +396,8 @@ DICT   *dict_sdbm_open(const char *path, int open_flags, int dict_flags)
            msg_fatal("unlock database %s for open: %m", dbm_path);
        if (close(lock_fd) < 0)
            msg_fatal("close database %s: %m", dbm_path);
-       myfree(dbm_path);
     }
-    dict_sdbm = (DICT_SDBM *) mymalloc(sizeof(*dict_sdbm));
+    dict_sdbm = (DICT_SDBM *) dict_alloc(DICT_TYPE_SDBM, path, sizeof(*dict_sdbm));
     dict_sdbm->dict.lookup = dict_sdbm_lookup;
     dict_sdbm->dict.update = dict_sdbm_update;
     dict_sdbm->dict.delete = dict_sdbm_delete;
@@ -400,15 +408,30 @@ DICT   *dict_sdbm_open(const char *path, int open_flags, int dict_flags)
     if (fstat(dict_sdbm->dict.stat_fd, &st) < 0)
        msg_fatal("dict_sdbm_open: fstat: %m");
     dict_sdbm->dict.mtime = st.st_mtime;
+
+    /*
+     * Warn if the source file is newer than the indexed file, except when
+     * the source file changed only seconds ago.
+     */
+    if ((dict_flags & DICT_FLAG_LOCK) != 0
+       && stat(path, &st) == 0
+       && st.st_mtime > dict_sdbm->dict.mtime
+       && st.st_mtime < time((time_t *) 0) - 100)
+       msg_warn("database %s is older than source file %s", dbm_path, path);
+
     close_on_exec(sdbm_pagfno(dbm), CLOSE_ON_EXEC);
     close_on_exec(sdbm_dirfno(dbm), CLOSE_ON_EXEC);
     dict_sdbm->dict.flags = dict_flags | DICT_FLAG_FIXED;
     if ((dict_flags & (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL)) == 0)
        dict_sdbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL);
     dict_sdbm->dbm = dbm;
-    dict_sdbm->path = mystrdup(path);
+    dict_sdbm->key_buf = 0;
+    dict_sdbm->val_buf = 0;
+
+    if ((dict_flags & DICT_FLAG_LOCK))
+       myfree(dbm_path);
 
-    return (&dict_sdbm->dict);
+    return (DICT_DEBUG (&dict_sdbm->dict));
 }
 
 #endif