[exim-cvs] ldap lookups build as dynamic module

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Exim Git Commits Mailing List
Ημερομηνία:  
Προς: exim-cvs
Αντικείμενο: [exim-cvs] ldap lookups build as dynamic module
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/