]> git.pld-linux.org Git - packages/exim.git/blame - localscan_dlopen_exim_4.20_or_better.patch
perl 5.36.0 rebuild; rel 5
[packages/exim.git] / localscan_dlopen_exim_4.20_or_better.patch
CommitLineData
b3e93248
AM
1Description: Allow one to use and switch between different local_scan functions
2 without recompiling exim.
3 http://marc.merlins.org/linux/exim/files/sa-exim-current/ Original patch from
4 David Woodhouse, modified first by Derrick 'dman' Hudson and then by Marc
5 MERLIN for SA-Exim and minor/major API version tracking
6Author: David Woodhouse, Derrick 'dman' Hudson, Marc MERLIN
7Origin: other, http://marc.merlins.org/linux/exim/files/sa-exim-current/
8Forwarded: https://bugs.exim.org/show_bug.cgi?id=2671
9Last-Update: 2021-07-28
10
11--- a/src/EDITME
12+++ b/src/EDITME
13@@ -881,10 +881,25 @@
14 # as the traditional crypt() function.
15 # *** WARNING *** WARNING *** WARNING *** WARNING *** WARNING ***
4d241ba7
AM
16
17
18 #------------------------------------------------------------------------------
19+# On systems which support dynamic loading of shared libraries, Exim can
20+# load a local_scan function specified in its config file instead of having
96e93d3d 21+# to be recompiled with the desired local_scan function. For a full
4d241ba7
AM
22+# description of the API to this function, see the Exim specification.
23+
24+DLOPEN_LOCAL_SCAN=yes
25+
26+# If you set DLOPEN_LOCAL_SCAN, then you need to include -rdynamic in the
27+# linker flags. Without it, the loaded .so won't be able to access any
28+# functions from exim.
29+
96e93d3d
AM
30+LDFLAGS += -rdynamic
31+CFLAGS += -fvisibility=hidden
4d241ba7
AM
32+
33+#------------------------------------------------------------------------------
34 # The default distribution of Exim contains only the plain text form of the
35 # documentation. Other forms are available separately. If you want to install
36 # the documentation in "info" format, first fetch the Texinfo documentation
b3e93248
AM
37 # sources from the ftp directory and unpack them, which should create files
38 # with the extension "texinfo" in the doc directory. You may find that the
39--- a/src/config.h.defaults
40+++ b/src/config.h.defaults
41@@ -33,10 +33,12 @@
42 #define AUTH_SPA
43 #define AUTH_TLS
44
45 #define AUTH_VARS 4
46
47+#define DLOPEN_LOCAL_SCAN
48+
49 #define BIN_DIRECTORY
50
51 #define CONFIGURE_FILE
52 #define CONFIGURE_FILE_USE_EUID
53 #define CONFIGURE_FILE_USE_NODE
54--- a/src/globals.c
55+++ b/src/globals.c
56@@ -119,10 +119,14 @@
57 uschar *dsn_envid = NULL;
58 int dsn_ret = 0;
96e93d3d
AM
59 const pcre *regex_DSN = NULL;
60 uschar *dsn_advertise_hosts = NULL;
4d241ba7
AM
61
62+#ifdef DLOPEN_LOCAL_SCAN
63+uschar *local_scan_path = NULL;
64+#endif
96e93d3d
AM
65+
66 #ifndef DISABLE_TLS
67 BOOL gnutls_compat_mode = FALSE;
68 BOOL gnutls_allow_auto_pkcs11 = FALSE;
b3e93248
AM
69 uschar *hosts_require_alpn = NULL;
70 uschar *openssl_options = NULL;
71--- a/src/globals.h
72+++ b/src/globals.h
73@@ -154,10 +154,13 @@
74 extern uschar *dsn_envid; /* DSN envid string */
75 extern int dsn_ret; /* DSN ret type*/
96e93d3d
AM
76 extern const pcre *regex_DSN; /* For recognizing DSN settings */
77 extern uschar *dsn_advertise_hosts; /* host for which TLS is advertised */
4d241ba7
AM
78
79+#ifdef DLOPEN_LOCAL_SCAN
80+extern uschar *local_scan_path; /* Path to local_scan() library */
81+#endif
4d241ba7
AM
82 /* Input-reading functions for messages, so we can use special ones for
83 incoming TCP/IP. */
96e93d3d 84
b3e93248
AM
85 extern int (*lwr_receive_getc)(unsigned);
86 extern uschar * (*lwr_receive_getbuf)(unsigned *);
87--- a/src/local_scan.c
88+++ b/src/local_scan.c
02ccdc95 89@@ -4,60 +4,136 @@
b3e93248
AM
90
91 /* Copyright (c) University of Cambridge 1995 - 2009 */
4d241ba7
AM
92 /* See the file NOTICE for conditions of use and distribution. */
93
4d241ba7
AM
94
95-/******************************************************************************
96-This file contains a template local_scan() function that just returns ACCEPT.
97-If you want to implement your own version, you should copy this file to, say
98-Local/local_scan.c, and edit the copy. To use your version instead of the
99-default, you must set
100-
048ec4ef 101-HAVE_LOCAL_SCAN=yes
4d241ba7
AM
102-LOCAL_SCAN_SOURCE=Local/local_scan.c
103-
104-in your Local/Makefile. This makes it easy to copy your version for use with
105-subsequent Exim releases.
106-
107-For a full description of the API to this function, see the Exim specification.
108-******************************************************************************/
109-
110-
96e93d3d
AM
111 /* This is the only Exim header that you should include. The effect of
112 including any other Exim header is not defined, and may change from release to
113 release. Use only the documented interface! */
96e93d3d 114
b3e93248 115 #include "local_scan.h"
96e93d3d 116
b3e93248 117-
4d241ba7
AM
118-/* This is a "do-nothing" version of a local_scan() function. The arguments
119-are:
120-
121- fd The file descriptor of the open -D file, which contains the
122- body of the message. The file is open for reading and
123- writing, but modifying it is dangerous and not recommended.
124-
125- return_text A pointer to an unsigned char* variable which you can set in
126- order to return a text string. It is initialized to NULL.
127-
128-The return values of this function are:
129-
130- LOCAL_SCAN_ACCEPT
131- The message is to be accepted. The return_text argument is
132- saved in $local_scan_data.
133-
134- LOCAL_SCAN_REJECT
135- The message is to be rejected. The returned text is used
136- in the rejection message.
137-
138- LOCAL_SCAN_TEMPREJECT
139- This specifies a temporary rejection. The returned text
140- is used in the rejection message.
141-*/
142+#ifdef DLOPEN_LOCAL_SCAN
143+#include <dlfcn.h>
02ccdc95 144+#include <stdlib.h>
4d241ba7
AM
145+static int (*local_scan_fn)(int fd, uschar **return_text) = NULL;
146+static int load_local_scan_library(void);
147+#endif
148
149 int
150 local_scan(int fd, uschar **return_text)
151 {
4d241ba7 152-return LOCAL_SCAN_ACCEPT;
b3e93248 153+
4d241ba7
AM
154+#ifdef DLOPEN_LOCAL_SCAN
155+/* local_scan_path is defined AND not the empty string */
156+if (local_scan_path && *local_scan_path)
157+ {
158+ if (!local_scan_fn)
159+ {
160+ if (!load_local_scan_library())
161+ {
162+ char *base_msg , *error_msg , *final_msg ;
163+ int final_length = -1 ;
164+
165+ base_msg=US"Local configuration error - local_scan() library failure\n";
166+ error_msg = dlerror() ;
167+
168+ final_length = strlen(base_msg) + strlen(error_msg) + 1 ;
169+ final_msg = (char*)malloc( final_length*sizeof(char) ) ;
170+ *final_msg = '\0' ;
171+
172+ strcat( final_msg , base_msg ) ;
173+ strcat( final_msg , error_msg ) ;
174+
175+ *return_text = final_msg ;
176+ return LOCAL_SCAN_TEMPREJECT;
177+ }
178+ }
179+ return local_scan_fn(fd, return_text);
180+ }
181+else
182+#endif
183+ return LOCAL_SCAN_ACCEPT;
b3e93248
AM
184+}
185+
4d241ba7
AM
186+#ifdef DLOPEN_LOCAL_SCAN
187+
188+static int load_local_scan_library(void)
189+{
190+/* No point in keeping local_scan_lib since we'll never dlclose() anyway */
191+void *local_scan_lib = NULL;
192+int (*local_scan_version_fn)(void);
193+int vers_maj;
194+int vers_min;
195+
196+local_scan_lib = dlopen(local_scan_path, RTLD_NOW);
197+if (!local_scan_lib)
198+ {
199+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library open failed - "
200+ "message temporarily rejected");
201+ return FALSE;
202+ }
203+
204+local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_major");
205+if (!local_scan_version_fn)
206+ {
207+ dlclose(local_scan_lib);
208+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
209+ "local_scan_version_major() function - message temporarily rejected");
210+ return FALSE;
211+ }
212+
213+/* The major number is increased when the ABI is changed in a non
214+ backward compatible way. */
215+vers_maj = local_scan_version_fn();
216+
217+local_scan_version_fn = dlsym(local_scan_lib, "local_scan_version_minor");
218+if (!local_scan_version_fn)
219+ {
220+ dlclose(local_scan_lib);
221+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
222+ "local_scan_version_minor() function - message temporarily rejected");
223+ return FALSE;
224+ }
225+
226+/* The minor number is increased each time a new feature is added (in a
227+ way that doesn't break backward compatibility) -- Marc */
228+vers_min = local_scan_version_fn();
229+
230+
231+if (vers_maj != LOCAL_SCAN_ABI_VERSION_MAJOR)
232+ {
233+ dlclose(local_scan_lib);
234+ local_scan_lib = NULL;
235+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible major"
236+ "version number, you need to recompile your module for this version"
237+ "of exim (The module was compiled for version %d.%d and this exim provides"
238+ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
239+ LOCAL_SCAN_ABI_VERSION_MINOR);
240+ return FALSE;
241+ }
242+else if (vers_min > LOCAL_SCAN_ABI_VERSION_MINOR)
243+ {
244+ dlclose(local_scan_lib);
245+ local_scan_lib = NULL;
246+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() has an incompatible minor"
247+ "version number, you need to recompile your module for this version"
248+ "of exim (The module was compiled for version %d.%d and this exim provides"
249+ "ABI version %d.%d)", vers_maj, vers_min, LOCAL_SCAN_ABI_VERSION_MAJOR,
250+ LOCAL_SCAN_ABI_VERSION_MINOR);
251+ return FALSE;
252+ }
253+
254+local_scan_fn = dlsym(local_scan_lib, "local_scan");
255+if (!local_scan_fn)
256+ {
257+ dlclose(local_scan_lib);
258+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() library doesn't contain "
96e93d3d 259+ "local_scan() function - message temporarily rejected");
4d241ba7
AM
260+ return FALSE;
261+ }
4d241ba7 262+return TRUE;
b3e93248
AM
263 }
264
4d241ba7 265+#endif /* DLOPEN_LOCAL_SCAN */
96e93d3d 266+
4d241ba7 267 /* End of local_scan.c */
b3e93248
AM
268--- a/src/local_scan.h
269+++ b/src/local_scan.h
270@@ -25,10 +25,11 @@
271 /* Some basic types that make some things easier, the Exim configuration
272 settings, and the store functions. */
96e93d3d
AM
273
274 #include <stdarg.h>
275 #include <sys/types.h>
276+#pragma GCC visibility push(default)
277 #include "config.h"
278 #include "mytypes.h"
279 #include "store.h"
b3e93248
AM
280
281
282@@ -164,10 +165,13 @@
283 extern header_line *header_last; /* Final header */
284 extern header_line *header_list; /* First header */
96e93d3d
AM
285 extern BOOL host_checking; /* Set when checking a host */
286 extern uschar *interface_address; /* Interface for incoming call */
287 extern int interface_port; /* Port number for incoming call */
288+#ifdef DLOPEN_LOCAL_SCAN
289+extern uschar *local_scan_path;
290+#endif
291 extern uschar *message_id; /* Internal id of message being handled */
292 extern uschar *received_protocol; /* Name of incoming protocol */
293 extern int recipients_count; /* Number of recipients */
b3e93248
AM
294 extern recipient_item *recipients_list;/* List of recipient addresses */
295 extern unsigned char *sender_address; /* Sender address */
296@@ -233,6 +237,8 @@
297 extern pid_t child_open_exim_function(int *, const uschar *);
298 extern pid_t child_open_exim2_function(int *, uschar *, uschar *, const uschar *);
0473fda3 299 extern pid_t child_open_function(uschar **, uschar **, int, int *, int *, BOOL, const uschar *);
96e93d3d
AM
300 #endif
301
302+#pragma GCC visibility pop
303+
304 /* End of local_scan.h */
b3e93248
AM
305--- a/src/readconf.c
306+++ b/src/readconf.c
307@@ -213,10 +213,13 @@
308 #endif
309 { "local_from_check", opt_bool, {&local_from_check} },
bc62d876
AM
310 { "local_from_prefix", opt_stringptr, {&local_from_prefix} },
311 { "local_from_suffix", opt_stringptr, {&local_from_suffix} },
312 { "local_interfaces", opt_stringptr, {&local_interfaces} },
4d241ba7 313+#ifdef DLOPEN_LOCAL_SCAN
b3e93248 314+ { "local_scan_path", opt_stringptr, &local_scan_path },
4d241ba7 315+#endif
906bd90b 316 #ifdef HAVE_LOCAL_SCAN
bc62d876 317 { "local_scan_timeout", opt_time, {&local_scan_timeout} },
906bd90b 318 #endif
b3e93248
AM
319 { "local_sender_retain", opt_bool, {&local_sender_retain} },
320 { "localhost_number", opt_stringptr, {&host_number_string} },
321--- a/src/string.c
322+++ b/src/string.c
323@@ -416,10 +416,11 @@
324
325
96e93d3d
AM
326
327 #if (defined(HAVE_LOCAL_SCAN) || defined(EXPAND_DLFUNC)) \
328 && !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
329+#pragma GCC visibility push(default)
330 /*************************************************
331 * Copy and save string *
332 *************************************************/
b3e93248
AM
333
334 /*
335@@ -468,10 +469,11 @@
336 uschar *ss = store_get(n + 1, is_tainted(s));
337 Ustrncpy(ss, s, n);
96e93d3d
AM
338 ss[n] = 0;
339 return ss;
340 }
341+#pragma GCC visibility pop
342 #endif
343
344
b3e93248
AM
345 /*************************************************
346 * Copy and save string in malloc'd store *
This page took 0.081459 seconds and 4 git commands to generate.