mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-29 13:18:12 +00:00
snapshot-19991122
This commit is contained in:
parent
37aa848072
commit
0504a0012e
@ -2,7 +2,7 @@ LINUX SYSLOGD PERFORMANCE
|
||||
=========================
|
||||
|
||||
LINUX syslogd uses synchronous writes by default, which is very
|
||||
expensive. For services such a mail it is recommended that you
|
||||
expensive. For services such as mail it is recommended that you
|
||||
disable synchronous logfile writes by prepending a - to the logfile
|
||||
name:
|
||||
|
||||
|
@ -3280,3 +3280,10 @@ Apologies for any names omitted.
|
||||
Robustness: INSTALL.sh no longer uses postmap for sanity checks.
|
||||
|
||||
Feature: INSTALL.sh now has an install_root option.
|
||||
|
||||
Bugfix: INSTALL.sh now installs manual pages with proper
|
||||
permissions and ownership.
|
||||
|
||||
Bugfix: the LDAP client did not properly escape special
|
||||
characters in lookup keys (patch by John Hensley).
|
||||
File: util/dict_ldap.c.
|
||||
|
@ -14,13 +14,13 @@ Make backups if you want to be able to recover.
|
||||
In addition to doing a fresh install, this script can change an
|
||||
existing installation from using a world-writable maildrop to a
|
||||
group-writable one. It cannot be used to change Postfix queue
|
||||
ownership.
|
||||
file/directory ownership.
|
||||
|
||||
Before installing files, this script prompts you for some definitions.
|
||||
You can either edit this script ahead of time, or you can specify
|
||||
your changes interactively.
|
||||
Most definitions will be remembered, so you have to specify them
|
||||
only once. All definitions have a reasonable default value.
|
||||
|
||||
install_root - prepend to installed file names (for package building)
|
||||
install_root - prefix for installed file names (for package building)
|
||||
|
||||
config_directory - directory with Postfix configuration files.
|
||||
daemon_directory - directory with Postfix daemon programs.
|
||||
@ -34,12 +34,15 @@ your changes interactively.
|
||||
mail_owner - owner of Postfix queue files.
|
||||
|
||||
setgid - groupname, e.g., postdrop (default: no). See INSTALL section 12.
|
||||
manpages - path to man tree (default: no). Example: /usr/local/man.
|
||||
manpages - "no" or path to man tree. Example: /usr/local/man.
|
||||
|
||||
EOF
|
||||
|
||||
# By now, shells must have functions. Ultrix users must use sh5 or lose.
|
||||
|
||||
# Apparently, some broken LINUX file utilities won't move symlinks across
|
||||
# file systems. Upgrade to a better system. Don't waste my time.
|
||||
|
||||
compare_or_replace() {
|
||||
cmp $2 $3 >/dev/null 2>&1 || {
|
||||
rm -f junk || exit 1
|
||||
@ -71,9 +74,9 @@ case `echo -n` in
|
||||
*) n=; c='\c';;
|
||||
esac
|
||||
|
||||
# Default settings, edit to taste or change interactively. Once this
|
||||
# script has run it saves settings to $config_directory/install.cf.
|
||||
# Default settings. These are clobbered by remembered settings.
|
||||
|
||||
install_root=/
|
||||
config_directory=/etc/postfix
|
||||
daemon_directory=/usr/libexec/postfix
|
||||
command_directory=/usr/sbin
|
||||
@ -83,19 +86,39 @@ newaliases_path=/usr/bin/newaliases
|
||||
mailq_path=/usr/bin/mailq
|
||||
mail_owner=postfix
|
||||
setgid=no
|
||||
manpages=no
|
||||
manpages=/usr/local/man
|
||||
|
||||
while :
|
||||
# Find out the location of configuration files.
|
||||
|
||||
for name in install_root config_directory
|
||||
do
|
||||
echo $n "install_root: [/] $c"
|
||||
read ans
|
||||
case $ans in
|
||||
""|/|no) install_root=; break;;
|
||||
/*) install_root=$ans; break;;
|
||||
*) echo "install_root should be an absolute path name" 1>&2; exit 1;;
|
||||
esac
|
||||
while :
|
||||
do
|
||||
eval echo \$n "$name: [\$$name]\ \$c"
|
||||
read ans
|
||||
case $ans in
|
||||
"") break;;
|
||||
*) eval $name=\$ans; break;;
|
||||
esac
|
||||
done
|
||||
done
|
||||
|
||||
# Sanity checks
|
||||
|
||||
for path in $install_root $config_directory
|
||||
do
|
||||
case $path in
|
||||
/*) ;;
|
||||
*) echo "$path should be an absolute path name" 1>&2; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
# In case some systems special-case pathnames beginning with //.
|
||||
|
||||
case $install_root in
|
||||
/) install_root=
|
||||
esac
|
||||
|
||||
# Load defaults from existing installation.
|
||||
|
||||
CONFIG_DIRECTORY=$install_root$config_directory
|
||||
@ -103,14 +126,16 @@ CONFIG_DIRECTORY=$install_root$config_directory
|
||||
test -f $CONFIG_DIRECTORY/main.cf && {
|
||||
for name in daemon_directory command_directory queue_directory mail_owner
|
||||
do
|
||||
eval "$name=\"\`bin/postconf -c $CONFIG_DIRECTORY -h $name || kill \$\$\`\""
|
||||
eval $name='"`bin/postconf -c $CONFIG_DIRECTORY -h $name`"' || kill $$
|
||||
done
|
||||
}
|
||||
|
||||
test -f $CONFIG_DIRECTORY/install.cf && . $CONFIG_DIRECTORY/install.cf
|
||||
|
||||
for name in config_directory daemon_directory command_directory \
|
||||
queue_directory sendmail_path newaliases_path mailq_path mail_owner \
|
||||
# Override default settings.
|
||||
|
||||
for name in daemon_directory command_directory \
|
||||
queue_directory sendmail_path newaliases_path mailq_path mail_owner\
|
||||
setgid manpages
|
||||
do
|
||||
while :
|
||||
@ -126,27 +151,7 @@ done
|
||||
|
||||
# Sanity checks
|
||||
|
||||
rm -f foobar-
|
||||
touch foobar-
|
||||
|
||||
chown $mail_owner foobar- >/dev/null 2>&1 || {
|
||||
echo "Error: $mail_owner needs an entry in the passwd file" 1>&2
|
||||
echo "Remember, $mail_owner must have a dedicated user id and group id." 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
case $setgid in
|
||||
no) ;;
|
||||
*) chgrp "$setgid" foobar- >/dev/null 2>&1 || {
|
||||
echo "Error: $setgid needs an entry in the group file" 1>&2
|
||||
echo "Remember, $setgid must have a dedicated group id." 1>&2
|
||||
exit 1
|
||||
}
|
||||
esac
|
||||
|
||||
rm -f foobar-
|
||||
|
||||
for path in $config_directory $daemon_directory $command_directory \
|
||||
for path in $daemon_directory $command_directory \
|
||||
$queue_directory $sendmail_path $newaliases_path $mailq_path $manpages
|
||||
do
|
||||
case $path in
|
||||
@ -156,9 +161,28 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
# Create any missing directories.
|
||||
rm -f junk || exit 1
|
||||
touch junk
|
||||
|
||||
chown "$mail_owner" junk >/dev/null 2>&1 || {
|
||||
echo "Error: $mail_owner needs an entry in the passwd file" 1>&2
|
||||
echo "Remember, $mail_owner must have a dedicated user id and group id." 1>&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
case $setgid in
|
||||
no) ;;
|
||||
*) chgrp "$setgid" junk >/dev/null 2>&1 || {
|
||||
echo "Error: $setgid needs an entry in the group file" 1>&2
|
||||
echo "Remember, $setgid must have a dedicated group id." 1>&2
|
||||
exit 1
|
||||
}
|
||||
esac
|
||||
|
||||
rm -f junk
|
||||
|
||||
# Avoid clumsiness.
|
||||
|
||||
CONFIG_DIRECTORY=$install_root$config_directory
|
||||
DAEMON_DIRECTORY=$install_root$daemon_directory
|
||||
COMMAND_DIRECTORY=$install_root$command_directory
|
||||
QUEUE_DIRECTORY=$install_root$queue_directory
|
||||
@ -167,9 +191,7 @@ NEWALIASES_PATH=$install_root$newaliases_path
|
||||
MAILQ_PATH=$install_root$mailq_path
|
||||
MANPAGES=$install_root$manpages
|
||||
|
||||
case $install_root in
|
||||
/?*) test -d $install_root || mkdir -p $install_root || exit 1
|
||||
esac
|
||||
# Create any missing directories.
|
||||
|
||||
test -d $CONFIG_DIRECTORY || mkdir -p $CONFIG_DIRECTORY || exit 1
|
||||
test -d $DAEMON_DIRECTORY || mkdir -p $DAEMON_DIRECTORY || exit 1
|
||||
@ -182,7 +204,7 @@ done
|
||||
|
||||
# Install files. Be careful to not copy over running programs.
|
||||
|
||||
for file in `ls libexec`
|
||||
for file in `ls libexec | grep -v '^\.'`
|
||||
do
|
||||
compare_or_replace a+x,go-w libexec/$file $DAEMON_DIRECTORY/$file || exit 1
|
||||
done
|
||||
@ -204,12 +226,14 @@ test -f $CONFIG_DIRECTORY/main.cf || {
|
||||
cp conf/* $CONFIG_DIRECTORY || exit 1
|
||||
chmod a+r,go-w $CONFIG_DIRECTORY/* || exit 1
|
||||
|
||||
echo "Warning: you still need to edit myorigin/mydestination in" 1>&2
|
||||
echo "$CONFIG_DIRECTORY/main.cf. See also html/faq.html for dialup" 1>&2
|
||||
echo "sites or for sites inside a firewalled network." 1>&2
|
||||
echo "" 1>&2
|
||||
echo "BTW, Edit your alias database and be sure to set up aliases" 1>&2
|
||||
echo "for root and postmaster, then run the newaliases command." 1>&2
|
||||
test -z "$install_root" && {
|
||||
echo "Warning: you still need to edit myorigin/mydestination in" 1>&2
|
||||
echo "$CONFIG_DIRECTORY/main.cf. See also html/faq.html for dialup" 1>&2
|
||||
echo "sites or for sites inside a firewalled network." 1>&2
|
||||
echo "" 1>&2
|
||||
echo "BTW: Edit your alias database and be sure to set up aliases" 1>&2
|
||||
echo "for root and postmaster, then run $NEWALIASES_PATH." 1>&2
|
||||
}
|
||||
}
|
||||
|
||||
# Save settings.
|
||||
@ -222,8 +246,7 @@ postconf -e \
|
||||
|| exit 1
|
||||
|
||||
(echo "# This file was generated by $0"
|
||||
for name in config_directory sendmail_path newaliases_path mailq_path \
|
||||
setgid manpages
|
||||
for name in sendmail_path newaliases_path mailq_path setgid manpages
|
||||
do
|
||||
eval echo $name=\$$name
|
||||
done) >junk || exit 1
|
||||
@ -255,7 +278,7 @@ esac
|
||||
compare_or_replace a+x,go-w $postfix_script $CONFIG_DIRECTORY/postfix-script ||
|
||||
exit 1
|
||||
|
||||
# Install manual pages (optional). We just clobber whatever is there.
|
||||
# Install manual pages (optional).
|
||||
|
||||
case $manpages in
|
||||
no) ;;
|
||||
@ -266,9 +289,11 @@ no) ;;
|
||||
done
|
||||
for file in man?/*
|
||||
do
|
||||
rm -f $MANPAGES/$file
|
||||
cp $file $MANPAGES/$file || exit 1
|
||||
chmod 644 $MANPAGES/$file || exit 1
|
||||
cmp -s $file $MANPAGES/$file || {
|
||||
rm -f $MANPAGES/$file
|
||||
cp $file $MANPAGES/$file || exit 1
|
||||
chmod 644 $MANPAGES/$file || exit 1
|
||||
}
|
||||
done
|
||||
)
|
||||
esac
|
||||
|
@ -67,13 +67,6 @@ Defaults are given in parentheses:
|
||||
substitute for the address Postfix is trying to resolve, e.g.
|
||||
ldapsource_query_filter = (&(mail=%s)(paid_up=true))
|
||||
|
||||
lookup_wildcards (no)
|
||||
Whether to search for addresses containing '*'. This has huge
|
||||
potential for spammers, so by default, any address containing
|
||||
'*' will cause the lookup to return nothing. Unless another
|
||||
dictionary returns a valid lookup for it, the mail will bounce
|
||||
with an 'unknown user' message.
|
||||
|
||||
result_attribute (maildrop)
|
||||
The attribute Postfix will read from any directory entries
|
||||
returned by the lookup, to be resolved to an email address.
|
||||
|
@ -1,4 +1,4 @@
|
||||
Incompatible changes with snapshot 19991120
|
||||
Incompatible changes with snapshot 19991122
|
||||
===========================================
|
||||
|
||||
- In an SMTPD access map, an all-numeric right-hand side now means
|
||||
@ -13,43 +13,51 @@ main.cf.
|
||||
SMTPD access control tables. Use the permit_recipient_map feature
|
||||
instead. The loss is compensated for (see below).
|
||||
|
||||
Major changes with snapshot 19991120
|
||||
Major changes with snapshot 19991122
|
||||
====================================
|
||||
|
||||
- It is now relatively safe to configure 550 status codes for the
|
||||
main.cf unknown_address_reject_code or unknown_client_reject_code
|
||||
parameters. The SMTP server now always sends a 450 (try again)
|
||||
reply code when an UCE restriction fails due to a soft DNS error,
|
||||
regardless of what main.cf specifies.
|
||||
|
||||
- The RBL checks now show the content of TXT records (Simon J Mudd).
|
||||
|
||||
- The Postfix SMTP server now understands a wider range of illegal
|
||||
address formats in MAIL FROM and RCPT TO commands. In order to
|
||||
disable those forms, specify "strict_rfc821_envelopes = yes".
|
||||
address forms in MAIL FROM and RCPT TO commands. In order to disable
|
||||
those forms, specify "strict_rfc821_envelopes = yes".
|
||||
|
||||
- Per-client/helo/sender/recipient UCE restrictions (fully-recursive
|
||||
UCE restriction parser). See the RESTRICTION_CLASS file for details.
|
||||
|
||||
- Block mail for non-existent users at the SMTP port. On a non-relay
|
||||
host, use the following to reject mail for non-existent users and
|
||||
for non-local destinations.
|
||||
- Block mail for most non-existent users at the SMTP port. Example:
|
||||
a non-relaying host could use the following to reject mail for
|
||||
non-existent local users and for all non-local destinations.
|
||||
|
||||
smtpd_recipient_restrictions =
|
||||
permit_recipient_map unix:passwd .byname
|
||||
reject_unknown_sender
|
||||
permit_recipient_map unix:passwd.byname
|
||||
permit_recipient_map hash:/etc/postfix/canonical
|
||||
permit_recipient_map hash:/etc/postfix/virtual
|
||||
permit_recipient_map hash:/etc/aliases
|
||||
reject
|
||||
|
||||
- "postconf -e name=value..." edits the main.cf file. This is
|
||||
I haven't figured out yet how to use this easily on hosts that must
|
||||
relay mail for other systems.
|
||||
|
||||
- Use "postmap -q key" or "postalias -q key" for testing Postfix
|
||||
lookup tables or alias files.
|
||||
|
||||
- Use "postconf -e name=value..." edits the main.cf file. This is
|
||||
easier and safer than editing the main.cf file by hand. The edits
|
||||
are done on a temporary copy that is renamed into place.
|
||||
|
||||
- "postconf -m" displays all supported lookup table types (Scott
|
||||
Cotton).
|
||||
|
||||
- It is now relatively safe to configure 550 status codes for the
|
||||
main.cf unknown_address_reject_code or unknown_client_reject_code
|
||||
parameters. The SMTP server now always sends a 450 (try again)
|
||||
reply code when an UCE restriction fails due to a soft DNS error.
|
||||
|
||||
- The RBL checks now show the content of TXT records (Simon J Mudd).
|
||||
- Use "postconf -m" to display all supported lookup table types
|
||||
(Scott Cotton).
|
||||
|
||||
- New "permit_auth_destination" UCE restriction for finer-grained
|
||||
control (Jesper Skriver).
|
||||
access control (Jesper Skriver).
|
||||
|
||||
Incompatible changes with postfix-19990906
|
||||
==========================================
|
||||
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Dummy UUCP rmail command for postfix/qmail systems
|
||||
|
||||
SENDMAIL="/usr/sbin/sendmail"
|
||||
IFS=" " read junk from junk
|
||||
|
||||
exec $SENDMAIL -f "$from" -- "$@"
|
@ -16,3 +16,11 @@
|
||||
# transport_maps = hash:/etc/postfix/transport, nis:transport
|
||||
# transport_maps = hash:/etc/postfix/transport, netinfo:/transport
|
||||
transport_maps =
|
||||
|
||||
# The local_transports parameter defines the name of the default
|
||||
# transport for local mail delivery, plus zero or more names of
|
||||
# additional transports that are known to deliver locally. The SMTP
|
||||
# server's UCE restrictions use this list to decide if an address
|
||||
# would be forwarded or not.
|
||||
#
|
||||
local_transports = local
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* SYNOPSIS
|
||||
/* #include <local_transport.h>
|
||||
/*
|
||||
/* const char *def_local_transport()
|
||||
/* const char *get_def_local_transport()
|
||||
/*
|
||||
/* int match_def_local_transport(transport)
|
||||
/* const char *transport;
|
||||
@ -19,7 +19,7 @@
|
||||
/* local transport, followed by the names of zero or more other
|
||||
/* transports that deliver locally.
|
||||
/*
|
||||
/* def_local_transport() returns the name of the default local
|
||||
/* get_def_local_transport() returns the name of the default local
|
||||
/* transport, that is, the first transport name specified with
|
||||
/* the "local_transports" configuration parameter.
|
||||
/*
|
||||
@ -29,7 +29,7 @@
|
||||
/* match_any_local_transport() determines if the named transport is
|
||||
/* listed in the "local_transports" configuration parameter.
|
||||
/* SEE ALSO
|
||||
/* resolve_local(3), see if address resolves locally.
|
||||
/* resolve_local(3), see if address resolves locally
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -84,13 +84,14 @@ static void local_transport_init(void)
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if (!match_any_local_transport(local_transport_name))
|
||||
if (!match_any_local_transport(local_transport_name)
|
||||
|| !match_def_local_transport(local_transport_name))
|
||||
msg_panic("%s: unable to intialize", myname);
|
||||
}
|
||||
|
||||
/* def_local_transport - determine default local transport */
|
||||
/* get_def_local_transport - determine default local transport */
|
||||
|
||||
const char *def_local_transport(void)
|
||||
const char *get_def_local_transport(void)
|
||||
{
|
||||
|
||||
/*
|
||||
|
@ -14,7 +14,7 @@
|
||||
/*
|
||||
* External interface.
|
||||
*/
|
||||
extern const char *def_local_transport(void);
|
||||
extern const char *get_def_local_transport(void);
|
||||
extern int match_def_local_transport(const char *);
|
||||
extern int match_any_local_transport(const char *);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Version of this program.
|
||||
*/
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "Snapshot-19991120"
|
||||
#define DEF_MAIL_VERSION "Snapshot-19991122"
|
||||
extern char *var_mail_version;
|
||||
|
||||
/* LICENSE
|
||||
|
@ -197,7 +197,7 @@ void resolve_addr(char *addr, VSTRING *channel, VSTRING *nexthop,
|
||||
* next-hop hostname (myself).
|
||||
*/
|
||||
else {
|
||||
vstring_strcpy(channel, def_local_transport());
|
||||
vstring_strcpy(channel, get_def_local_transport());
|
||||
vstring_strcpy(nexthop, var_myhostname);
|
||||
}
|
||||
|
||||
|
@ -36,10 +36,8 @@
|
||||
/* .IP \fIldapsource_\fRquery_filter
|
||||
/* The filter used to search for directory entries, for example
|
||||
/* \fI(mailacceptinggeneralid=%s)\fR.
|
||||
/* .IP \fIldapsource_\fRlookup_wildcards
|
||||
/* Whether to allow '*' in addresses to be looked up.
|
||||
/* .IP \fIldapsource_\fRresult_attribute
|
||||
/* The attribute returned by the search, in which we expect to find
|
||||
/* The attribute returned by the search, in which to find
|
||||
/* RFC822 addresses, for example \fImaildrop\fR.
|
||||
/* .IP \fIldapsource_\fRbind
|
||||
/* Whether or not to bind to the server -- LDAP v3 implementations don't
|
||||
@ -49,7 +47,7 @@
|
||||
/* .IP \fIldapsource_\fRbind_pw
|
||||
/* \&... and this password.
|
||||
/* BUGS
|
||||
/* Of course not! :)
|
||||
/* Thrice a year, needed or not.
|
||||
/* SEE ALSO
|
||||
/* dict(3) generic dictionary manager
|
||||
/* DIAGNOSTICS
|
||||
@ -65,8 +63,7 @@
|
||||
/* Yorktown Heights, NY 10532, USA
|
||||
/*
|
||||
/* John Hensley
|
||||
/* Merit Network, Inc.
|
||||
/* hensley@merit.edu
|
||||
/* stormroll@yahoo.com
|
||||
/*
|
||||
/*--*/
|
||||
|
||||
@ -78,6 +75,8 @@
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdlib.h>
|
||||
@ -92,12 +91,9 @@
|
||||
#include "dict.h"
|
||||
#include "dict_ldap.h"
|
||||
|
||||
/*
|
||||
* Grr.. this module should sit in the global library, because it interacts
|
||||
* with application-specific configuration parameters. I will have to
|
||||
* generalize the manner in which new dictionary types can register
|
||||
* themselves, including their configuration file parameters.
|
||||
*/
|
||||
/* Global library. */
|
||||
|
||||
#include "../global/mail_conf.h" /* XXX Fixme. */
|
||||
|
||||
/*
|
||||
* structure containing all the configuration parameters for a given
|
||||
@ -110,7 +106,6 @@ typedef struct {
|
||||
int server_port;
|
||||
char *search_base;
|
||||
char *query_filter;
|
||||
int lookup_wildcards;
|
||||
char *result_attribute;
|
||||
int bind;
|
||||
char *bind_dn;
|
||||
@ -139,7 +134,8 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
LDAPMessage *res = 0;
|
||||
LDAPMessage *entry = 0;
|
||||
struct timeval tv;
|
||||
VSTRING *filter_buf = 0;
|
||||
VSTRING *escaped_name = 0,
|
||||
*filter_buf = 0;
|
||||
char **attr_values;
|
||||
long i = 0;
|
||||
int rc = 0;
|
||||
@ -149,17 +145,6 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
|
||||
dict_errno = 0;
|
||||
|
||||
/*
|
||||
* Unless configured to allow them, refuse to search for a name
|
||||
* containing wildcards.
|
||||
*/
|
||||
if (!dict_ldap->lookup_wildcards) {
|
||||
if (strstr(name, "*") != NULL) {
|
||||
msg_warn("%s: Address (%s) contains a wildcard; refusing to search. See the lookup_wildcards attribute in LDAP_README for more information.", myname, name);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize.
|
||||
*/
|
||||
@ -171,35 +156,43 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
if (msg_verbose)
|
||||
msg_info("%s: In dict_ldap_lookup", myname);
|
||||
|
||||
if (dict_ldap->ld == 0) {
|
||||
msg_warn("%s: no existing connection for ldapsource %s, reopening",
|
||||
myname, dict_ldap->ldapsource);
|
||||
if (dict_ldap->ld == NULL) {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: no existing connection for ldapsource %s, reopening",
|
||||
myname, dict_ldap->ldapsource);
|
||||
|
||||
if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) {
|
||||
msg_warn("%s: error setting signal handler for open timeout: %m", myname);
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: connecting to server %s", myname,
|
||||
dict_ldap->server_host);
|
||||
|
||||
if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR)
|
||||
msg_fatal("%s: signal: %m", myname);
|
||||
|
||||
alarm(dict_ldap->timeout);
|
||||
if (setjmp(env) == 0)
|
||||
dict_ldap->ld = ldap_open(dict_ldap->server_host,
|
||||
(int) dict_ldap->server_port);
|
||||
alarm(0);
|
||||
|
||||
if (signal(SIGALRM, saved_alarm) == SIG_ERR)
|
||||
msg_fatal("%s: signal: %m", myname);
|
||||
|
||||
if (signal(SIGALRM, saved_alarm) == SIG_ERR) {
|
||||
msg_warn("%s: error resetting signal handler after open: %m", myname);
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: after ldap_open", myname);
|
||||
|
||||
if (dict_ldap->ld == 0) {
|
||||
msg_fatal("%s: Unable to contact LDAP server %s",
|
||||
myname, dict_ldap->server_host);
|
||||
if (dict_ldap->ld == NULL) {
|
||||
msg_warn("%s: Unable to contact LDAP server %s",
|
||||
myname, dict_ldap->server_host);
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If this server requires us to bind, do so.
|
||||
* If this server requires a bind, do so.
|
||||
*/
|
||||
if (dict_ldap->bind) {
|
||||
if (msg_verbose)
|
||||
@ -209,7 +202,9 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
rc = ldap_bind_s(dict_ldap->ld, dict_ldap->bind_dn,
|
||||
dict_ldap->bind_pw, LDAP_AUTH_SIMPLE);
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
msg_fatal("%s: Unable to bind to server %s as %s (%d -- %s): ", myname, dict_ldap->server_host, dict_ldap->bind_dn, rc, ldap_err2string(rc));
|
||||
msg_warn("%s: Unable to bind to server %s as %s (%d -- %s): ", myname, dict_ldap->server_host, dict_ldap->bind_dn, rc, ldap_err2string(rc));
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: Successful bind to server %s as %s (%d -- %s): ", myname, dict_ldap->server_host, dict_ldap->bind_dn, rc, ldap_err2string(rc));
|
||||
@ -220,37 +215,52 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
myname, dict_ldap->ldapsource);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for entries matching query_filter.
|
||||
* Prepare the query.
|
||||
*/
|
||||
tv.tv_sec = dict_ldap->timeout;
|
||||
tv.tv_usec = 0;
|
||||
escaped_name = vstring_alloc(20);
|
||||
filter_buf = vstring_alloc(30);
|
||||
|
||||
/* Any wildcards and escapes in the supplied address should be escaped. */
|
||||
if (strchr(name, '*') || strchr(name, '\\')) {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: found wildcard in %s", myname, name);
|
||||
for (sub = (char *) name; *sub != '\0'; sub++) {
|
||||
if (*sub == '*' || *sub == '\\') {
|
||||
vstring_strncat(escaped_name, "\\", 1);
|
||||
vstring_strncat(escaped_name, sub, 1);
|
||||
} else {
|
||||
vstring_strncat(escaped_name, sub, 1);
|
||||
}
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: with wildcards escaped, it's %s", myname, vstring_str(escaped_name));
|
||||
} else
|
||||
vstring_strcpy(escaped_name, (char *) name);
|
||||
|
||||
/* Does the supplied query_filter even include a substitution? */
|
||||
if (strstr(dict_ldap->query_filter, "%s") == NULL) {
|
||||
/* No, log the fact and continue. */
|
||||
msg_warn("%s: fixed query_filter %s is probably useless", myname,
|
||||
dict_ldap->query_filter);
|
||||
vstring_strcpy(filter_buf, dict_ldap->query_filter);
|
||||
} else {
|
||||
|
||||
/*
|
||||
* OK, let's replace all the instances of %s with the address to look
|
||||
* up.
|
||||
*/
|
||||
/* Yes, replace all instances of %s with the address to look up. */
|
||||
sub = dict_ldap->query_filter;
|
||||
end = sub + strlen(dict_ldap->query_filter);
|
||||
while (sub < end) {
|
||||
|
||||
/*
|
||||
* Make sure it's %s and not something else, though it wouldn't
|
||||
* really matter; we could skip any single character.
|
||||
* really matter; the token could be any single character.
|
||||
*/
|
||||
if (*(sub) == '%') {
|
||||
if ((sub + 1) != end && *(sub + 1) != 's')
|
||||
msg_fatal("%s: invalid lookup substitution format '%%%c'!", myname, *(sub + 1));
|
||||
vstring_strcat(filter_buf, name);
|
||||
msg_warn("%s: invalid lookup substitution format '%%%c'!", myname, *(sub + 1));
|
||||
vstring_strcat(filter_buf, vstring_str(escaped_name));
|
||||
sub++;
|
||||
} else
|
||||
vstring_strncat(filter_buf, sub, 1);
|
||||
@ -258,6 +268,7 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/* On to the search. */
|
||||
if (msg_verbose)
|
||||
msg_info("%s: searching with filter %s", myname,
|
||||
vstring_str(filter_buf));
|
||||
@ -265,33 +276,24 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
if ((rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
|
||||
LDAP_SCOPE_SUBTREE,
|
||||
vstring_str(filter_buf),
|
||||
0, 0, &tv, &res)) != LDAP_SUCCESS) {
|
||||
|
||||
ldap_unbind(dict_ldap->ld);
|
||||
dict_ldap->ld = 0;
|
||||
if (msg_verbose)
|
||||
msg_info("%s: freed connection handle for LDAP source %s", myname, dict_ldap->ldapsource);
|
||||
msg_fatal("%s: Unable to search base %s at server %s (%d -- %s): ",
|
||||
myname, dict_ldap->search_base, dict_ldap->server_host, rc,
|
||||
ldap_err2string(rc));
|
||||
|
||||
} else {
|
||||
|
||||
0, 0, &tv, &res)) == LDAP_SUCCESS) {
|
||||
/*
|
||||
* Extract the requested result_attribute.
|
||||
* Search worked; extract the requested result_attribute.
|
||||
*/
|
||||
if (msg_verbose)
|
||||
msg_info("%s: search found %d", myname,
|
||||
msg_info("%s: search found %d matches", myname,
|
||||
ldap_count_entries(dict_ldap->ld, res));
|
||||
|
||||
/* There could have been lots of hits. */
|
||||
for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL; entry = ldap_next_entry(dict_ldap->ld, entry)) {
|
||||
|
||||
/* And each entry could have multiple attributes. */
|
||||
attr_values = ldap_get_values(dict_ldap->ld, entry,
|
||||
dict_ldap->result_attribute);
|
||||
if (attr_values == NULL) {
|
||||
msg_warn("%s: entry doesn't have any values for %s", myname, dict_ldap->result_attribute);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append each returned address to the result list.
|
||||
*/
|
||||
@ -304,18 +306,28 @@ static const char *dict_ldap_lookup(DICT *dict, const char *name)
|
||||
}
|
||||
if (msg_verbose)
|
||||
msg_info("%s: search returned: %s", myname, vstring_str(result));
|
||||
} else {
|
||||
/* Rats. That didn't work. */
|
||||
msg_warn("%s: search error %d: %s ", myname, rc,
|
||||
ldap_err2string(rc));
|
||||
|
||||
/*
|
||||
* Tear down the connection so it gets set up from scratch on the
|
||||
* next lookup.
|
||||
*/
|
||||
ldap_unbind(dict_ldap->ld);
|
||||
dict_ldap->ld = NULL;
|
||||
|
||||
/* And tell the caller to try again later. */
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup. Always return with dict_errno set when we were unable to
|
||||
* perform the query.
|
||||
*/
|
||||
/* Cleanup. */
|
||||
if (res != 0)
|
||||
ldap_msgfree(res);
|
||||
else
|
||||
dict_errno = 1;
|
||||
if (filter_buf != 0)
|
||||
vstring_free(filter_buf);
|
||||
|
||||
return (VSTRING_LEN(result) > 0 ? vstring_str(result) : 0);
|
||||
}
|
||||
|
||||
@ -412,17 +424,6 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
|
||||
msg_info("%s: %s is %s", myname, vstring_str(config_param),
|
||||
dict_ldap->query_filter);
|
||||
|
||||
/*
|
||||
* get configured value of "ldapsource_lookup_wildcards"; default to
|
||||
* false
|
||||
*/
|
||||
vstring_sprintf(config_param, "%s_lookup_wildcards", ldapsource);
|
||||
dict_ldap->lookup_wildcards =
|
||||
get_mail_conf_bool(vstring_str(config_param), 0);
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s is %d", myname, vstring_str(config_param),
|
||||
dict_ldap->lookup_wildcards);
|
||||
|
||||
vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
|
||||
dict_ldap->result_attribute =
|
||||
mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
|
||||
@ -462,28 +463,33 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
|
||||
msg_info("%s: connecting to server %s", myname,
|
||||
dict_ldap->server_host);
|
||||
|
||||
if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR)
|
||||
msg_fatal("%s: signal: %m", myname);
|
||||
|
||||
if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) {
|
||||
msg_warn("%s: error setting signal handler for open timeout: %m", myname);
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
}
|
||||
alarm(dict_ldap->timeout);
|
||||
if (setjmp(env) == 0)
|
||||
dict_ldap->ld = ldap_open(dict_ldap->server_host,
|
||||
(int) dict_ldap->server_port);
|
||||
alarm(0);
|
||||
|
||||
if (signal(SIGALRM, saved_alarm) == SIG_ERR)
|
||||
msg_fatal("%s: signal: %m", myname);
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: after ldap_open", myname);
|
||||
|
||||
if (dict_ldap->ld == 0) {
|
||||
msg_fatal("%s: Unable to contact LDAP server %s",
|
||||
myname, dict_ldap->server_host);
|
||||
if (signal(SIGALRM, saved_alarm) == SIG_ERR) {
|
||||
msg_warn("%s: error resetting signal handler after open: %m", myname);
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
}
|
||||
if (dict_ldap->ld == NULL) {
|
||||
msg_warn("%s: Unable to contact LDAP server %s",
|
||||
myname, dict_ldap->server_host);
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
} else {
|
||||
|
||||
if (msg_verbose)
|
||||
msg_info("%s: after ldap_open", myname);
|
||||
/*
|
||||
* If this server requires us to bind, do so.
|
||||
* If this server requires a bind, do so.
|
||||
*/
|
||||
if (dict_ldap->bind) {
|
||||
if (msg_verbose)
|
||||
@ -493,7 +499,9 @@ DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
|
||||
rc = ldap_bind_s(dict_ldap->ld, dict_ldap->bind_dn,
|
||||
dict_ldap->bind_pw, LDAP_AUTH_SIMPLE);
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
msg_fatal("%s: Unable to bind to server %s as %s (%d -- %s): ", myname, dict_ldap->server_host, dict_ldap->bind_dn, rc, ldap_err2string(rc));
|
||||
msg_warn("%s: Unable to bind to server %s as %s (%d -- %s): ", myname, dict_ldap->server_host, dict_ldap->bind_dn, rc, ldap_err2string(rc));
|
||||
dict_errno = DICT_ERR_RETRY;
|
||||
return (0);
|
||||
} else {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: Successful bind to server %s as %s (%d -- %s): ", myname, dict_ldap->server_host, dict_ldap->bind_dn, rc, ldap_err2string(rc));
|
||||
|
Loading…
x
Reference in New Issue
Block a user