3. Events smtp:fail:protocol and smtp:fail:syntax
- 4. JSON lookup support, all the router and authenticator drivers, and all the
- transport drivers except smtp, can now be built as loadable modules
+ 4. JSON and LDAP lookup support, all the router and authenticator drivers,
+ and all the transport drivers except smtp, can now be built as loadable
+ modules
Version 4.98
------------
sed -n "1,/$tag_marker/p" < "$input"
for name_mod in \
- CDB DBM:dbmdb DNSDB DSEARCH IBASE JSON LMDB LSEARCH MYSQL NIS NISPLUS ORACLE \
- PASSWD PGSQL REDIS SQLITE TESTDB WHOSON
+ CDB DBM:dbmdb DNSDB DSEARCH IBASE JSON LMDB LDAP LSEARCH MYSQL NIS NISPLUS \
+ ORACLE PASSWD PGSQL REDIS SQLITE TESTDB WHOSON
do
emit_module_rule $name_mod
done
-if want_at_all LDAP
-then
- OBJ="${OBJ} ldap.o"
-fi
-
# Because the variable is EXPERIMENTAL_SPF and not LOOKUP_SPF we
# always include spf.o and compile a dummy if EXPERIMENTAL_SPF is not
# defined.
# the dynamic library and not the exim binary will be linked against the
# library.
#
-# NOTE: LDAP cannot be built as a module!
-# JSON cannot (yet).
-# Also, PASSWD, DBM and DNSDB can but there is little point since the accesses
-# are always needed by the Exim core.
+# PASSWD, DBM and DNSDB can be build as modules but there is little point since
+# the accesses are always needed by the Exim core.
#
# For Redis you need to have hiredis installed on your system
# (https://github.com/redis/hiredis).
# If you don't set any of these, Exim assumes the original University of
# Michigan (OpenLDAP 1) library.
+# For building as a modules, set LOOKUP_LDAP_INCLUDE and LOOKUP_LDAP_LIBS
#------------------------------------------------------------------------------
# The PCRE2 library is required for Exim. There is no longer an embedded
#
# LOOKUP_INCLUDE += -I/usr/local/include
# LOOKUP_LIBS += -llmdb
+# For dynamic-modules builds, use instead LOOKUP_LMDB_INCLUDE & LOOKUP_LMDB_LIBS
#------------------------------------------------------------------------------
#if defined(LOOKUP_JSON) && LOOKUP_JSON!=2
extern lookup_module_info json_lookup_module_info;
#endif
-#if defined(LOOKUP_LDAP)
+#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
extern lookup_module_info ldap_lookup_module_info;
#endif
#if defined(LOOKUP_LSEARCH) && LOOKUP_LSEARCH!=2
#if defined(LOOKUP_REDIS) && LOOKUP_REDIS!=2
extern lookup_module_info redis_lookup_module_info;
#endif
-#if defined(LOOKUP_LMDB)
+#if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
extern lookup_module_info lmdb_lookup_module_info;
#endif
#if defined(SUPPORT_SPF)
addlookupmodule(NULL, &ibase_lookup_module_info);
#endif
-#ifdef LOOKUP_LDAP
+#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
addlookupmodule(NULL, &ldap_lookup_module_info);
#endif
addlookupmodule(NULL, &redis_lookup_module_info);
#endif
-#ifdef LOOKUP_LMDB
+#if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
addlookupmodule(NULL, &lmdb_lookup_module_info);
#endif
{
gstring * b = NULL, * d = NULL;
-#if defined(LOOKUP_LSEARCH)
+#ifdef LOOKUP_LSEARCH
# if LOOKUP_LSEARCH!=2
b = string_cat(b, US" lsearch wildlsearch nwildlsearch iplsearch");
# else
d = string_cat(d, US" lsearch wildlsearch nwildlsearch iplsearch");
# endif
#endif
-#if defined(LOOKUP_CDB)
+#ifdef LOOKUP_CDB
# if LOOKUP_CDB!=2
b = string_cat(b, US" cdb");
# else
d = string_cat(d, US" cdb");
# endif
#endif
-#if defined(LOOKUP_DBM)
+#ifdef LOOKUP_DBM
# if LOOKUP_DBM!=2
b = string_cat(b, US" dbm dbmjz dbmnz");
# else
d = string_cat(d, US" dbm dbmjz dbmnz");
# endif
#endif
-#if defined(LOOKUP_DNSDB)
+#ifdef LOOKUP_DNSDB
# if LOOKUP_DNSDB!=2
b = string_cat(b, US" dnsdb");
# else
d = string_cat(d, US" dnsdb");
# endif
#endif
-#if defined(LOOKUP_DSEARCH)
+#ifdef LOOKUP_DSEARCH
# if LOOKUP_DSEARCH!=2
b = string_cat(b, US" dsearch");
# else
d = string_cat(d, US" dsearch");
# endif
#endif
-#if defined(LOOKUP_IBASE)
+#ifdef LOOKUP_IBASE
# if LOOKUP_IBASE!=2
b = string_cat(b, US" ibase");
# else
d = string_cat(d, US" ibase");
# endif
#endif
-#if defined(LOOKUP_JSON)
+#ifdef LOOKUP_JSON
# if LOOKUP_JSON!=2
b = string_cat(b, US" json");
# else
d = string_cat(d, US" json");
# endif
#endif
-#if defined(LOOKUP_LDAP)
+#ifdef LOOKUP_LDAP
# if LOOKUP_LDAP!=2
b = string_cat(b, US" ldap ldapdn ldapm");
# else
# endif
#endif
#ifdef LOOKUP_LMDB
+# if LOOKUP_LMDB!=2
b = string_cat(b, US" lmdb");
+# else
+ d = string_cat(d, US" lmdb");
+# endif
#endif
-#if defined(LOOKUP_MYSQL)
+#ifdef LOOKUP_MYSQL
# if LOOKUP_MYSQL!=2
b = string_cat(b, US" mysql");
# else
d = string_cat(d, US" mysql");
# endif
#endif
-#if defined(LOOKUP_NIS)
+#ifdef LOOKUP_NIS
# if LOOKUP_NIS!=2
b = string_cat(b, US" nis nis0");
# else
d = string_cat(d, US" nis nis0");
# endif
#endif
-#if defined(LOOKUP_NISPLUS)
+#ifdef LOOKUP_NISPLUS
# if LOOKUP_NISPLUS!=2
b = string_cat(b, US" nisplus");
# else
d = string_cat(d, US" nisplus");
# endif
#endif
-#if defined(LOOKUP_ORACLE)
+#ifdef LOOKUP_ORACLE
# if LOOKUP_ORACLE!=2
b = string_cat(b, US" oracle");
# else
d = string_cat(d, US" oracle");
# endif
#endif
-#if defined(LOOKUP_PASSWD)
+#ifdef LOOKUP_PASSWD
# if LOOKUP_PASSWD!=2
b = string_cat(b, US" passwd");
# else
d = string_cat(d, US" passwd");
# endif
#endif
-#if defined(LOOKUP_PGSQL)
+#ifdef LOOKUP_PGSQL
# if LOOKUP_PGSQL!=2
b = string_cat(b, US" pgsql");
# else
d = string_cat(d, US" pgsql");
# endif
#endif
-#if defined(LOOKUP_REDIS)
+#ifdef LOOKUP_REDIS
# if LOOKUP_REDIS!=2
b = string_cat(b, US" redis");
# else
d = string_cat(d, US" redis");
# endif
#endif
-#if defined(LOOKUP_SQLITE)
+#ifdef LOOKUP_SQLITE
# if LOOKUP_SQLITE!=2
b = string_cat(b, US" sqlite");
# else
d = string_cat(d, US" sqlite");
# endif
#endif
-#if defined(LOOKUP_TESTDB)
+#ifdef LOOKUP_TESTDB
# if LOOKUP_TESTDB!=2
b = string_cat(b, US" testdb");
# else
d = string_cat(d, US" testdb");
# endif
#endif
-#if defined(LOOKUP_WHOSON)
+#ifdef LOOKUP_WHOSON
# if LOOKUP_WHOSON!=2
b = string_cat(b, US" whoson");
# else
# endif
#endif /*!STAND_ALONE*/
-#ifdef LOOKUP_LDAP
-# include "lookups/ldap.h"
-#endif
-
#ifdef SUPPORT_CRYPTEQ
# ifdef CRYPT_H
# include <crypt.h>
case ECOND_LDAPAUTH:
#ifdef LOOKUP_LDAP
{
- /* Just to keep the interface the same */
- BOOL do_cache;
- int old_pool = store_pool;
- store_pool = POOL_SEARCH;
- rc = eldapauth_find((void *)(-1), NULL, sub[0], Ustrlen(sub[0]), NULL,
- &expand_string_message, &do_cache);
- store_pool = old_pool;
+ int stype = search_findtype(US"ldapauth", 8), expand_setup = -1;
+ void * handle = search_open(NULL, stype, 0, NULL, NULL);
+ if (handle)
+ rc= search_find(handle, NULL, sub[0],
+ -1, NULL, 0, 0, &expand_setup, NULL)
+ ? OK : f.search_find_defer ? DEFER : FAIL;
+ else
+ { expand_string_message = search_error_message; rc = FAIL; }
}
goto END_AUTH;
#else
extern uschar *router_current_name(void);
extern uschar *search_args(int, uschar *, uschar *, uschar **, const uschar *);
-extern uschar *search_find(void *, const uschar *, uschar *, int,
+extern uschar *search_find(void *, const uschar *, const uschar *, int,
const uschar *, int, int, int *, const uschar *);
extern int search_findtype(const uschar *, int);
extern int search_findtype_partial(const uschar *, int *, const uschar **, int *,
The case of eldapauth_find() is special in that all it does is do
authentication, returning OK or FAIL as appropriate. This isn't used as a
-lookup. Instead, it is called from expand.c as an expansion condition test.
+lookup. Instead, it is called via the generic search interface from expand.c
+as an expansion condition test. We take a non/NULL return string as OK/FAIL.
+We do not advertise or document it as a general search method,
+but probably could.
The DN from a successful lookup is placed in $ldap_dn. This feature postdates
the provision of the SEARCH_LDAP_DN facility for returning just the DN as the
int
eldapauth_find(void * handle, const uschar * filename, const uschar * ldap_url,
- int length, uschar ** result, uschar ** errmsg, uint * do_cache)
+ int length, uschar ** result, uschar ** errmsg, uint * do_cache,
+ const uschar * opts)
{
return(control_ldap_search(ldap_url, SEARCH_LDAP_AUTH, result, errmsg));
}
ldap_version_report(gstring * g)
{
#ifdef DYNLOOKUP
+/*XXX it would be nice to haul a version string for the underlying ldap library */
g = string_fmt_append(g, "Library version: LDAP: Exim version %s\n", EXIM_VERSION_STR);
#endif
return g;
.version_report = NULL /* no version reporting (redundant) */
};
+static lookup_info ldapauth_lookup_info = {
+ .name = US"ldapauth", /* lookup name */
+ .type = lookup_querystyle, /* query-style lookup */
+ .open = eldap_open, /* sic */ /* open function */
+ .check = NULL, /* check function */
+ .find = eldapauth_find, /* find function */
+ .close = NULL, /* no close function */
+ .tidy = eldap_tidy, /* sic */ /* tidy function */
+ .quote = eldap_quote, /* sic */ /* quoting function */
+ .version_report = NULL /* no version reporting (redundant) */
+};
+
#ifdef DYNLOOKUP
#define ldap_lookup_module_info _lookup_module_info
#endif
-static lookup_info *_lookup_list[] = { &ldap_lookup_info, &ldapdn_lookup_info, &ldapm_lookup_info };
-lookup_module_info ldap_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 3 };
+static lookup_info *_lookup_list[] = {
+ &ldap_lookup_info,
+ &ldapdn_lookup_info,
+ &ldapm_lookup_info,
+ &ldapauth_lookup_info,
+ };
+lookup_module_info ldap_lookup_module_info = { LOOKUP_MODULE_INFO_MAGIC, _lookup_list, 4 };
/* End of lookups/ldap.c */
+++ /dev/null
-/*************************************************
-* Exim - an Internet mail transport agent *
-*************************************************/
-
-/* Copyright (c) University of Cambridge 1995 - 2015 */
-/* See the file NOTICE for conditions of use and distribution. */
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-/* Header for eldapauth_find */
-
-extern int eldapauth_find(void *, uschar *, const uschar *, int, uschar **,
- uschar **, BOOL *);
-
-/* End of lookups/ldap.h */
*/
static uschar *
-internal_search_find(void * handle, const uschar * filename, uschar * keystring,
- BOOL cache_rd, const uschar * opts)
+internal_search_find(void * handle, const uschar * filename,
+ const uschar * keystring, BOOL cache_rd, const uschar * opts)
{
tree_node * t = (tree_node *)handle;
search_cache * c = (search_cache *)(t->data.ptr);
*/
uschar *
-search_find(void * handle, const uschar * filename, uschar * keystring,
+search_find(void * handle, const uschar * filename, const uschar * keystring,
int partial, const uschar * affix, int affixlen, int starflags,
int * expand_setup, const uschar * opts)
{
/* Try with the affix on the front, except for a zero-length affix */
- if (affixlen == 0) keystring2 = keystring; else
+ if (affixlen == 0)
+ keystring2 = string_copy(keystring);
+ else
{
keystring2 = store_get(len + affixlen + 1,
is_tainted(keystring) || is_tainted(affix) ? GET_TAINTED : GET_UNTAINTED);
Ustrncpy(keystring2, affix, affixlen);
Ustrcpy(keystring2 + affixlen, keystring);
DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring2);
- yield = internal_search_find(handle, filename, keystring2, cache_rd, opts);
+ yield = internal_search_find(handle, filename, CUS keystring2, cache_rd, opts);
if (f.search_find_defer) return NULL;
}
}
DEBUG(D_lookup) debug_printf_indent("trying partial match %s\n", keystring3);
- yield = internal_search_find(handle, filename, keystring3,
+ yield = internal_search_find(handle, filename, CUS keystring3,
cache_rd, opts);
if (f.search_find_defer) return NULL;
if (yield)