#include "sys_defs.h"
#ifdef HAS_LDAP
#include <sys/time.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <lber.h>
#include <ldap.h>
#include <string.h>
#if !defined(LDAP_API_VERSION) || (LDAP_API_VERSION < 2000)
#error "Your LDAP version is too old"
#endif
#ifndef LDAP_CONST
#define LDAP_CONST const
#endif
#ifndef LDAP_OPT_SUCCESS
#define LDAP_OPT_SUCCESS 0
#endif
#include "match_list.h"
#include "match_ops.h"
#include "msg.h"
#include "mymalloc.h"
#include "vstring.h"
#include "dict.h"
#include "dict_ldap.h"
#include "../global/mail_conf.h"
typedef struct {
DICT dict;
char *ldapsource;
char *server_host;
int server_port;
int scope;
char *search_base;
MATCH_LIST *domain;
char *query_filter;
char *result_filter;
ARGV *result_attributes;
int num_attributes;
int bind;
char *bind_dn;
char *bind_pw;
int timeout;
int cache;
long cache_expiry;
long cache_size;
int dereference;
int chase_referrals;
int debuglevel;
int version;
LDAP *ld;
} DICT_LDAP;
#ifndef LDAP_OPT_NETWORK_TIMEOUT
static jmp_buf env;
static void dict_ldap_timeout(int unused_sig)
{
longjmp(env, 1);
}
#endif
static void dict_ldap_logprint(LDAP_CONST char *data)
{
char *myname = "dict_ldap_debug";
msg_info("%s: %s", myname, data);
}
static int dict_ldap_get_errno(LDAP * ld)
{
int rc;
if (ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_OPT_SUCCESS)
rc = LDAP_OTHER;
return rc;
}
static int dict_ldap_set_errno(LDAP * ld, int rc)
{
(void) ldap_set_option(ld, LDAP_OPT_ERROR_NUMBER, &rc);
return rc;
}
static int dict_ldap_bind_st(DICT_LDAP *dict_ldap)
{
int msgid;
LDAPMessage *res;
struct timeval mytimeval;
if ((msgid = ldap_bind(dict_ldap->ld, dict_ldap->bind_dn,
dict_ldap->bind_pw, LDAP_AUTH_SIMPLE)) == -1)
return (dict_ldap_get_errno(dict_ldap->ld));
mytimeval.tv_sec = dict_ldap->timeout;
mytimeval.tv_usec = 0;
if (ldap_result(dict_ldap->ld, msgid, 1, &mytimeval, &res) == -1)
return (dict_ldap_get_errno(dict_ldap->ld));
if (dict_ldap_get_errno(dict_ldap->ld) == LDAP_TIMEOUT) {
(void) ldap_abandon(dict_ldap->ld, msgid);
return (dict_ldap_set_errno(dict_ldap->ld, LDAP_TIMEOUT));
}
return (ldap_result2error(dict_ldap->ld, res, 1));
}
static int dict_ldap_connect(DICT_LDAP *dict_ldap)
{
char *myname = "dict_ldap_connect";
int rc = 0;
#ifdef LDAP_API_FEATURE_X_MEMCACHE
LDAPMemCache *dircache;
#endif
#ifdef LDAP_OPT_NETWORK_TIMEOUT
struct timeval mytimeval;
#else
void (*saved_alarm) (int);
#endif
dict_errno = 0;
if (msg_verbose)
msg_info("%s: Connecting to server %s", myname,
dict_ldap->server_host);
#ifdef LDAP_OPT_NETWORK_TIMEOUT
dict_ldap->ld = ldap_init(dict_ldap->server_host,
(int) dict_ldap->server_port);
if (dict_ldap->ld == NULL) {
msg_warn("%s: Unable to init LDAP server %s",
myname, dict_ldap->server_host);
dict_errno = DICT_ERR_RETRY;
return (-1);
}
mytimeval.tv_sec = dict_ldap->timeout;
mytimeval.tv_usec = 0;
if (ldap_set_option(dict_ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &mytimeval) !=
LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to set network timeout.", myname);
#else
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 (-1);
}
alarm(dict_ldap->timeout);
if (setjmp(env) == 0)
dict_ldap->ld = ldap_open(dict_ldap->server_host,
(int) dict_ldap->server_port);
else
dict_ldap->ld = 0;
alarm(0);
if (signal(SIGALRM, saved_alarm) == SIG_ERR) {
msg_warn("%s: Error resetting signal handler after open: %m",
myname);
dict_errno = DICT_ERR_RETRY;
return (-1);
}
if (dict_ldap->ld == NULL) {
msg_warn("%s: Unable to connect to LDAP server %s",
myname, dict_ldap->server_host);
dict_errno = DICT_ERR_RETRY;
return (-1);
}
#endif
#ifdef LDAP_OPT_PROTOCOL_VERSION
if (ldap_set_option(dict_ldap->ld, LDAP_OPT_PROTOCOL_VERSION,
&dict_ldap->version) != LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to set LDAP protocol version", myname);
if (msg_verbose) {
if (ldap_get_option(dict_ldap->ld,
LDAP_OPT_PROTOCOL_VERSION,
&dict_ldap->version) != LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to get LDAP protocol version", myname);
else
msg_warn("%s: Actual Protocol version used is %d.",
myname, dict_ldap->version);
}
#endif
if (ldap_set_option(dict_ldap->ld, LDAP_OPT_DEREF,
&(dict_ldap->dereference)) != LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to set dereference option.", myname);
#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 *) dict_ldap_logprint) != LBER_OPT_SUCCESS)
msg_warn("%s: Unable to set ber logprint function.", myname);
if (ldap_set_option(dict_ldap->ld, LDAP_OPT_DEBUG_LEVEL,
&(dict_ldap->debuglevel)) != LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to set LDAP debug level.", myname);
#endif
#ifdef LDAP_OPT_REFERRALS
if (ldap_set_option(dict_ldap->ld, LDAP_OPT_REFERRALS,
dict_ldap->chase_referrals ? LDAP_OPT_ON : LDAP_OPT_OFF)
!= LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to set Referral chasing.", myname);
#else
if (dict_ldap->chase_referrals) {
msg_warn("%s: Unable to set Referral chasing.", myname);
}
#endif
if (dict_ldap->bind) {
if (msg_verbose)
msg_info("%s: Binding to server %s as dn %s",
myname, dict_ldap->server_host, dict_ldap->bind_dn);
rc = dict_ldap_bind_st(dict_ldap);
if (rc != LDAP_SUCCESS) {
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 (-1);
}
if (msg_verbose)
msg_info("%s: Successful bind to server %s as %s ",
myname, dict_ldap->server_host, dict_ldap->bind_dn);
}
if (dict_ldap->cache) {
if (msg_verbose)
msg_info
("%s: Enabling %ld-byte cache for %s with %ld-second expiry",
myname, dict_ldap->cache_size, dict_ldap->ldapsource,
dict_ldap->cache_expiry);
#ifdef LDAP_API_FEATURE_X_MEMCACHE
rc = ldap_memcache_init(dict_ldap->cache_expiry, dict_ldap->cache_size,
NULL, NULL, &dircache);
if (rc != LDAP_SUCCESS) {
msg_warn
("%s: Unable to configure cache for %s: %d (%s) -- continuing",
myname, dict_ldap->ldapsource, rc, ldap_err2string(rc));
} else {
rc = ldap_memcache_set(dict_ldap->ld, dircache);
if (rc != LDAP_SUCCESS) {
msg_warn
("%s: Unable to configure cache for %s: %d (%s) -- continuing",
myname, dict_ldap->ldapsource, rc, ldap_err2string(rc));
} else {
if (msg_verbose)
msg_info("%s: Caching enabled for %s",
myname, dict_ldap->ldapsource);
}
}
#else
rc = ldap_enable_cache(dict_ldap->ld, dict_ldap->cache_expiry,
dict_ldap->cache_size);
if (rc != LDAP_SUCCESS) {
msg_warn
("%s: Unable to configure cache for %s: %d (%s) -- continuing",
myname, dict_ldap->ldapsource, rc, ldap_err2string(rc));
} else {
if (msg_verbose)
msg_info("%s: Caching enabled for %s",
myname, dict_ldap->ldapsource);
}
#endif
}
if (msg_verbose)
msg_info("%s: Cached connection handle for LDAP source %s",
myname, dict_ldap->ldapsource);
return (0);
}
static void dict_ldap_expand_filter(char *filter, char *value, VSTRING *out)
{
char *myname = "dict_ldap_expand_filter";
char *sub,
*end;
sub = filter;
end = sub + strlen(filter);
while (sub < end) {
if (*(sub) == '%') {
char *u = value;
char *p = strrchr(u, '@');
switch (*(sub + 1)) {
case 'd':
if (p)
vstring_strcat(out, p + 1);
break;
case 'u':
if (p)
vstring_strncat(out, u, p - u);
else
vstring_strcat(out, u);
break;
default:
msg_warn
("%s: Invalid filter substitution format '%%%c'!",
myname, *(sub + 1));
case 's':
vstring_strcat(out, u);
break;
}
sub++;
} else
vstring_strncat(out, sub, 1);
sub++;
}
}
static void dict_ldap_get_values(DICT_LDAP *dict_ldap, LDAPMessage * res,
VSTRING *result)
{
long i = 0;
int rc = 0;
LDAPMessage *resloop = 0;
LDAPMessage *entry = 0;
BerElement *ber;
char **vals;
char *attr;
char *myname = "dict_ldap_get_values";
struct timeval tv;
LDAPURLDesc *url;
tv.tv_sec = dict_ldap->timeout;
tv.tv_usec = 0;
if (msg_verbose)
msg_info("%s: Search found %d match(es)", myname,
ldap_count_entries(dict_ldap->ld, res));
for (entry = ldap_first_entry(dict_ldap->ld, res); entry != NULL;
entry = ldap_next_entry(dict_ldap->ld, entry)) {
ber = NULL;
for (attr = ldap_first_attribute(dict_ldap->ld, entry, &ber);
attr != NULL;
ldap_memfree(attr), attr = ldap_next_attribute(dict_ldap->ld,
entry, ber)) {
vals = ldap_get_values(dict_ldap->ld, entry, attr);
if (vals == NULL) {
if (msg_verbose)
msg_info("%s: Entry doesn't have any values for %s",
myname, attr);
continue;
}
for (i = 0; dict_ldap->result_attributes->argv[i]; i++) {
if (strcasecmp(dict_ldap->result_attributes->argv[i],
attr) == 0) {
if (msg_verbose)
msg_info("%s: search returned %ld value(s) for requested result attribute %s", myname, i, attr);
break;
}
}
if (i < dict_ldap->num_attributes) {
for (i = 0; vals[i] != NULL; i++) {
if (VSTRING_LEN(result) > 0)
vstring_strcat(result, ",");
if (dict_ldap->result_filter == NULL)
vstring_strcat(result, vals[i]);
else
dict_ldap_expand_filter(dict_ldap->result_filter,
vals[i], result);
}
} else if (dict_ldap->result_attributes->argv[i]) {
for (i = 0; vals[i] != NULL; i++) {
if (ldap_is_ldap_url(vals[i])) {
if (msg_verbose)
msg_info("%s: looking up URL %s", myname,
vals[i]);
rc = ldap_url_parse(vals[i], &url);
if (rc == 0) {
rc = ldap_search_st(dict_ldap->ld, url->lud_dn,
url->lud_scope, url->lud_filter,
url->lud_attrs, 0, &tv,
&resloop);
ldap_free_urldesc(url);
}
} else {
if (msg_verbose)
msg_info("%s: looking up DN %s", myname, vals[i]);
rc = ldap_search_st(dict_ldap->ld, vals[i],
LDAP_SCOPE_BASE, "objectclass=*",
dict_ldap->result_attributes->argv,
0, &tv, &resloop);
}
switch (rc) {
case LDAP_SUCCESS:
dict_ldap_get_values(dict_ldap, resloop, result);
break;
case LDAP_NO_SUCH_OBJECT:
msg_warn("%s: DN %s not found, skipping ", myname,
vals[i]);
break;
default:
msg_warn("%s: search error %d: %s ", myname, rc,
ldap_err2string(rc));
dict_errno = DICT_ERR_RETRY;
break;
}
if (resloop != 0)
ldap_msgfree(resloop);
}
}
ldap_value_free(vals);
}
if (ber)
ber_free(ber, 0);
}
if (msg_verbose)
msg_info("%s: Leaving %s", myname, myname);
}
static const char *dict_ldap_lookup(DICT *dict, const char *name)
{
char *myname = "dict_ldap_lookup";
DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
LDAPMessage *res = 0;
static VSTRING *result;
struct timeval tv;
VSTRING *escaped_name = 0,
*filter_buf = 0;
int rc = 0;
char *sub,
*end;
dict_errno = 0;
if (msg_verbose)
msg_info("%s: In dict_ldap_lookup", myname);
if (dict_ldap->domain) {
const char *p = strrchr(name, '@');
if (p != 0)
p = p + 1;
else
p = name;
if (match_list_match(dict_ldap->domain, p) == 0) {
if (msg_verbose)
msg_info("%s: domain of %s not found in domain list", myname,
name);
return (0);
}
}
if (result == 0)
result = vstring_alloc(2);
vstring_strcpy(result, "");
if (dict_ldap->ld == NULL) {
if (msg_verbose)
msg_info
("%s: No existing connection for LDAP source %s, reopening",
myname, dict_ldap->ldapsource);
dict_ldap_connect(dict_ldap);
if (dict_errno)
return (0);
} else if (msg_verbose)
msg_info("%s: Using existing connection for LDAP source %s",
myname, dict_ldap->ldapsource);
tv.tv_sec = dict_ldap->timeout;
tv.tv_usec = 0;
escaped_name = vstring_alloc(20);
filter_buf = vstring_alloc(30);
end = (char *) name + strlen((char *) name);
sub = (char *) strpbrk((char *) name, "*()\\\0");
if (sub && sub != end) {
if (msg_verbose)
msg_info("%s: Found character(s) in %s that must be escaped",
myname, name);
for (sub = (char *) name; sub != end; sub++) {
switch (*sub) {
case '*':
vstring_strcat(escaped_name, "\\2a");
break;
case '(':
vstring_strcat(escaped_name, "\\28");
break;
case ')':
vstring_strcat(escaped_name, "\\29");
break;
case '\\':
vstring_strcat(escaped_name, "\\5c");
break;
case '\0':
vstring_strcat(escaped_name, "\\00");
break;
default:
vstring_strncat(escaped_name, sub, 1);
}
}
if (msg_verbose)
msg_info("%s: After escaping, it's %s", myname,
vstring_str(escaped_name));
} else
vstring_strcpy(escaped_name, (char *) name);
if ((char *) strchr(dict_ldap->query_filter, '%') == NULL) {
msg_warn("%s: Fixed query_filter %s is probably useless", myname,
dict_ldap->query_filter);
vstring_strcpy(filter_buf, dict_ldap->query_filter);
} else {
dict_ldap_expand_filter(dict_ldap->query_filter,
vstring_str(escaped_name), filter_buf);
}
if (msg_verbose)
msg_info("%s: Searching with filter %s", myname,
vstring_str(filter_buf));
rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
dict_ldap->scope,
vstring_str(filter_buf),
dict_ldap->result_attributes->argv,
0, &tv, &res);
if (rc == LDAP_SERVER_DOWN) {
if (msg_verbose)
msg_info("%s: Lost connection for LDAP source %s, reopening",
myname, dict_ldap->ldapsource);
ldap_unbind(dict_ldap->ld);
dict_ldap->ld = NULL;
dict_ldap_connect(dict_ldap);
if (dict_errno)
return (0);
rc = ldap_search_st(dict_ldap->ld, dict_ldap->search_base,
dict_ldap->scope,
vstring_str(filter_buf),
dict_ldap->result_attributes->argv,
0, &tv, &res);
}
if (rc == LDAP_SUCCESS) {
dict_ldap_get_values(dict_ldap, res, result);
rc = dict_ldap_get_errno(dict_ldap->ld);
if (rc != LDAP_SUCCESS && rc != LDAP_DECODING_ERROR)
msg_warn
("%s: Had some trouble with entries returned by search: %s",
myname, ldap_err2string(rc));
if (msg_verbose)
msg_info("%s: Search returned %s", myname,
VSTRING_LEN(result) >
0 ? vstring_str(result) : "nothing");
} else {
msg_warn("%s: Search error %d: %s ", myname, rc,
ldap_err2string(rc));
ldap_unbind(dict_ldap->ld);
dict_ldap->ld = NULL;
dict_errno = DICT_ERR_RETRY;
}
if (res != 0)
ldap_msgfree(res);
if (filter_buf != 0)
vstring_free(filter_buf);
if (escaped_name != 0)
vstring_free(escaped_name);
return (VSTRING_LEN(result) > 0 && !dict_errno ? vstring_str(result) : 0);
}
static void dict_ldap_close(DICT *dict)
{
char *myname = "dict_ldap_close";
DICT_LDAP *dict_ldap = (DICT_LDAP *) dict;
if (dict_ldap->ld)
ldap_unbind(dict_ldap->ld);
myfree(dict_ldap->ldapsource);
myfree(dict_ldap->server_host);
myfree(dict_ldap->search_base);
if (dict_ldap->domain)
match_list_free(dict_ldap->domain);
myfree(dict_ldap->query_filter);
if (dict_ldap->result_filter)
myfree(dict_ldap->result_filter);
argv_free(dict_ldap->result_attributes);
myfree(dict_ldap->bind_dn);
myfree(dict_ldap->bind_pw);
dict_free(dict);
}
DICT *dict_ldap_open(const char *ldapsource, int dummy, int dict_flags)
{
char *myname = "dict_ldap_open";
DICT_LDAP *dict_ldap;
VSTRING *config_param;
char *domainlist;
char *scope;
char *attr;
if (msg_verbose)
msg_info("%s: Using LDAP source %s", myname, ldapsource);
dict_ldap = (DICT_LDAP *) dict_alloc(DICT_TYPE_LDAP, ldapsource,
sizeof(*dict_ldap));
dict_ldap->dict.lookup = dict_ldap_lookup;
dict_ldap->dict.close = dict_ldap_close;
dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
dict_ldap->ldapsource = mystrdup(ldapsource);
config_param = vstring_alloc(15);
vstring_sprintf(config_param, "%s_server_host", ldapsource);
dict_ldap->server_host =
mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
"localhost", 0, 0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->server_host);
vstring_sprintf(config_param, "%s_server_port", ldapsource);
dict_ldap->server_port =
get_mail_conf_int(vstring_str(config_param), LDAP_PORT, 0, 0);
if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->server_port);
vstring_sprintf(config_param, "%s_scope", ldapsource);
scope =
(char *) get_mail_conf_str(vstring_str(config_param), "sub", 0, 0);
if (strcasecmp(scope, "one") == 0) {
dict_ldap->scope = LDAP_SCOPE_ONELEVEL;
if (msg_verbose)
msg_info("%s: %s is LDAP_SCOPE_ONELEVEL", myname,
vstring_str(config_param));
} else if (strcasecmp(scope, "base") == 0) {
dict_ldap->scope = LDAP_SCOPE_BASE;
if (msg_verbose)
msg_info("%s: %s is LDAP_SCOPE_BASE", myname,
vstring_str(config_param));
} else {
dict_ldap->scope = LDAP_SCOPE_SUBTREE;
if (msg_verbose)
msg_info("%s: %s is LDAP_SCOPE_SUBTREE", myname,
vstring_str(config_param));
}
myfree(scope);
vstring_sprintf(config_param, "%s_search_base", ldapsource);
dict_ldap->search_base = mystrdup((char *)
get_mail_conf_str(vstring_str
(config_param), "",
0, 0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->search_base);
vstring_sprintf(config_param, "%s_domain", ldapsource);
domainlist =
mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
"", 0, 0));
if (*domainlist) {
#ifdef MATCH_FLAG_NONE
dict_ldap->domain = match_list_init(MATCH_FLAG_NONE,
domainlist, 1, match_string);
#else
dict_ldap->domain = match_list_init(domainlist, 1, match_string);
#endif
if (dict_ldap->domain == NULL)
msg_warn("%s: domain match list creation using \"%s\" failed, will continue without it", myname, domainlist);
if (msg_verbose)
msg_info("%s: domain list created using \"%s\"", myname,
domainlist);
} else {
dict_ldap->domain = NULL;
}
myfree(domainlist);
vstring_sprintf(config_param, "%s_timeout", ldapsource);
dict_ldap->timeout =
get_mail_conf_int(vstring_str(config_param), 10, 0, 0);
if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->timeout);
vstring_sprintf(config_param, "%s_query_filter", ldapsource);
dict_ldap->query_filter =
mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
"(mailacceptinggeneralid=%s)",
0, 0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->query_filter);
vstring_sprintf(config_param, "%s_result_filter", ldapsource);
dict_ldap->result_filter =
mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
"%s",
0, 0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->result_filter);
if (strcmp(dict_ldap->result_filter, "%s") == 0) {
myfree(dict_ldap->result_filter);
dict_ldap->result_filter = NULL;
}
vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
"maildrop", 0, 0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);;
dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
vstring_sprintf(config_param, "%s_special_result_attribute", ldapsource);
attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
"", 0, 0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);
if (*attr) {
argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
}
vstring_sprintf(config_param, "%s_bind", ldapsource);
dict_ldap->bind = get_mail_conf_bool(vstring_str(config_param), 1);
if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->bind);
vstring_sprintf(config_param, "%s_bind_dn", ldapsource);
dict_ldap->bind_dn = mystrdup((char *)
get_mail_conf_str(vstring_str
(config_param), "", 0,
0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->bind_dn);
vstring_sprintf(config_param, "%s_bind_pw", ldapsource);
dict_ldap->bind_pw = mystrdup((char *)
get_mail_conf_str(vstring_str
(config_param), "", 0,
0));
if (msg_verbose)
msg_info("%s: %s is %s", myname, vstring_str(config_param),
dict_ldap->bind_pw);
vstring_sprintf(config_param, "%s_cache", ldapsource);
dict_ldap->cache = 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->cache);
vstring_sprintf(config_param, "%s_cache_expiry", ldapsource);
dict_ldap->cache_expiry = get_mail_conf_int(vstring_str(config_param),
30, 0, 0);
if (msg_verbose)
msg_info("%s: %s is %ld", myname, vstring_str(config_param),
dict_ldap->cache_expiry);
vstring_sprintf(config_param, "%s_cache_size", ldapsource);
dict_ldap->cache_size = get_mail_conf_int(vstring_str(config_param),
32768, 0, 0);
if (msg_verbose)
msg_info("%s: %s is %ld", myname, vstring_str(config_param),
dict_ldap->cache_size);
vstring_sprintf(config_param, "%s_dereference", ldapsource);
dict_ldap->dereference = get_mail_conf_int(vstring_str(config_param), 0, 0,
0);
vstring_sprintf(config_param, "%s_version", ldapsource);
dict_ldap->version = get_mail_conf_int(vstring_str(config_param), 2, 0,
0);
switch (dict_ldap->version) {
case 2:
dict_ldap->version = LDAP_VERSION2;
break;
case 3:
dict_ldap->version = LDAP_VERSION3;
break;
default:
msg_warn("%s: Unknown version %d.", myname, dict_ldap->version);
dict_ldap->version = LDAP_VERSION2;
}
if (dict_ldap->dereference < 0 || dict_ldap->dereference > 3) {
msg_warn("%s: Unrecognized value %d specified for %s; using 0",
myname, dict_ldap->dereference, vstring_str(config_param));
dict_ldap->dereference = 0;
}
if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->dereference);
vstring_sprintf(config_param, "%s_chase_referrals", ldapsource);
dict_ldap->chase_referrals = 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->chase_referrals);
#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
vstring_sprintf(config_param, "%s_debuglevel", ldapsource);
dict_ldap->debuglevel = get_mail_conf_int(vstring_str(config_param), 0, 0,
0);
if (msg_verbose)
msg_info("%s: %s is %d", myname, vstring_str(config_param),
dict_ldap->debuglevel);
#endif
dict_ldap_connect(dict_ldap);
if (dict_errno) {
if (dict_ldap->ld)
ldap_unbind(dict_ldap->ld);
myfree((char *) dict_ldap);
return (0);
}
return (DICT_DEBUG (&dict_ldap->dict));
}
#endif