Gitweb:
https://git.exim.org/exim.git/commitdiff/419d8549aad98eb3438593873332661e6fb1845e
Commit: 419d8549aad98eb3438593873332661e6fb1845e
Parent: 747736dc83324875bd6339f97f492747a3ad7fe5
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Aug 18 18:46:44 2024 +0100
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Sun Aug 18 20:17:45 2024 +0100
ldap lookups build as dynamic module
---
doc/doc-txt/NewStuff | 5 +++--
src/scripts/lookups-Makefile | 9 ++-------
src/src/EDITME | 8 ++++----
src/src/drtables.c | 8 ++++----
src/src/exim.c | 40 ++++++++++++++++++++++------------------
src/src/expand.c | 19 ++++++++-----------
src/src/functions.h | 2 +-
src/src/lookups/ldap.c | 30 ++++++++++++++++++++++++++----
src/src/lookups/ldap.h | 14 --------------
src/src/search.c | 14 ++++++++------
10 files changed, 78 insertions(+), 71 deletions(-)
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index a5a8bd5f3..9a34f8ac2 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -14,8 +14,9 @@ Version 4.98
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
------------
diff --git a/src/scripts/lookups-Makefile b/src/scripts/lookups-Makefile
index 8dcac585b..40cca603f 100755
--- a/src/scripts/lookups-Makefile
+++ b/src/scripts/lookups-Makefile
@@ -163,17 +163,12 @@ exec > "$target"
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.
diff --git a/src/src/EDITME b/src/src/EDITME
index 3353a4239..aeba7704a 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -416,10 +416,8 @@ TRANSPORT_SMTP=yes
# 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).
@@ -479,6 +477,7 @@ LOOKUP_DNSDB=yes
# 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
@@ -538,6 +537,7 @@ SUPPORT_DANE=yes
#
# LOOKUP_INCLUDE += -I/usr/local/include
# LOOKUP_LIBS += -llmdb
+# For dynamic-modules builds, use instead LOOKUP_LMDB_INCLUDE & LOOKUP_LMDB_LIBS
#------------------------------------------------------------------------------
diff --git a/src/src/drtables.c b/src/src/drtables.c
index c490e7f86..1d8e222e2 100644
--- a/src/src/drtables.c
+++ b/src/src/drtables.c
@@ -295,7 +295,7 @@ extern lookup_module_info ibase_lookup_module_info;
#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
@@ -322,7 +322,7 @@ extern lookup_module_info pgsql_lookup_module_info;
#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)
@@ -378,7 +378,7 @@ addlookupmodule(NULL, &dsearch_lookup_module_info);
addlookupmodule(NULL, &ibase_lookup_module_info);
#endif
-#ifdef LOOKUP_LDAP
+#if defined(LOOKUP_LDAP) && LOOKUP_LDAP!=2
addlookupmodule(NULL, &ldap_lookup_module_info);
#endif
@@ -418,7 +418,7 @@ addlookupmodule(NULL, &pgsql_lookup_module_info);
addlookupmodule(NULL, &redis_lookup_module_info);
#endif
-#ifdef LOOKUP_LMDB
+#if defined(LOOKUP_LMDB) && LOOKUP_LMDB!=2
addlookupmodule(NULL, &lmdb_lookup_module_info);
#endif
diff --git a/src/src/exim.c b/src/src/exim.c
index 66746e6bb..3d0929592 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -1043,56 +1043,56 @@ lookup_show_supported(gstring * g)
{
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
@@ -1100,72 +1100,76 @@ gstring * b = NULL, * d = NULL;
# 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
diff --git a/src/src/expand.c b/src/src/expand.c
index 2ed802fd4..d7b55831f 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -30,10 +30,6 @@ typedef unsigned esi_flags;
# endif
#endif /*!STAND_ALONE*/
-#ifdef LOOKUP_LDAP
-# include "lookups/ldap.h"
-#endif
-
#ifdef SUPPORT_CRYPTEQ
# ifdef CRYPT_H
# include <crypt.h>
@@ -2808,13 +2804,14 @@ switch(cond_type = identify_operator(&s, &opname))
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
diff --git a/src/src/functions.h b/src/src/functions.h
index 3253043ae..9ae51d05b 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -491,7 +491,7 @@ extern void route_tidyup(void);
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 *,
diff --git a/src/src/lookups/ldap.c b/src/src/lookups/ldap.c
index 0c29b6c9a..8a142398e 100644
--- a/src/src/lookups/ldap.c
+++ b/src/src/lookups/ldap.c
@@ -101,7 +101,10 @@ and eldapm_find(), with a difference in the "search_type" argument.
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
@@ -1305,7 +1308,8 @@ return(control_ldap_search(ldap_url, SEARCH_LDAP_DN, result, errmsg));
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));
}
@@ -1559,6 +1563,7 @@ gstring *
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;
@@ -1601,11 +1606,28 @@ static lookup_info ldapm_lookup_info = {
.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 */
diff --git a/src/src/lookups/ldap.h b/src/src/lookups/ldap.h
deleted file mode 100644
index 2ce62fc05..000000000
--- a/src/src/lookups/ldap.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*************************************************
-* 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 */
diff --git a/src/src/search.c b/src/src/search.c
index 6c28b390e..1c501455e 100644
--- a/src/src/search.c
+++ b/src/src/search.c
@@ -520,8 +520,8 @@ Returns: a pointer to a dynamic string containing the answer,
*/
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);
@@ -729,7 +729,7 @@ Returns: a pointer to a dynamic string containing the answer,
*/
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)
{
@@ -830,14 +830,16 @@ else if (partial >= 0)
/* 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;
}
@@ -875,7 +877,7 @@ else if (partial >= 0)
}
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)
--
## subscription configuration (requires account):
##
https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at
http://www.exim.org/
## Please use the Wiki with this list -
http://wiki.exim.org/