diff -p -up postfix-2.7.0/conf/dynamicmaps.cf.dynamic postfix-2.7.0/conf/dynamicmaps.cf --- postfix-2.7.0/conf/dynamicmaps.cf.dynamic 2010-02-20 18:36:31.580501570 +0100 +++ postfix-2.7.0/conf/dynamicmaps.cf 2010-02-20 18:36:31.580501570 +0100 @@ -0,0 +1,7 @@ +# Postfix dynamic maps configuration file. +# +# The first match found is the one that is used. Wildcards are not +# supported. +# +#type location of .so file name of open function name of mkmap function +#==== ============================= ===================== ====================== diff -p -up postfix-2.7.0/conf/postfix-files.dynamic postfix-2.7.0/conf/postfix-files --- postfix-2.7.0/conf/postfix-files.dynamic 2010-02-03 22:05:49.000000000 +0100 +++ postfix-2.7.0/conf/postfix-files 2010-02-20 18:36:31.580501570 +0100 @@ -65,6 +65,11 @@ $queue_directory/saved:d:$mail_owner:-:7 $queue_directory/trace:d:$mail_owner:-:700:ucr $daemon_directory/anvil:f:root:-:755 $daemon_directory/bounce:f:root:-:755 +$daemon_directory/dict_ldap.so:f:root:-:755 +$daemon_directory/dict_pcre.so:f:root:-:755 +$daemon_directory/dict_mysql.so:f:root:-:755 +$daemon_directory/dict_pgsql.so:f:root:-:755 +$daemon_directory/dict_cdb.so:f:root:-:755 $daemon_directory/cleanup:f:root:-:755 $daemon_directory/discard:f:root:-:755 $daemon_directory/error:f:root:-:755 @@ -94,6 +99,11 @@ $daemon_directory/tlsmgr:f:root:-:755 $daemon_directory/trivial-rewrite:f:root:-:755 $daemon_directory/verify:f:root:-:755 $daemon_directory/virtual:f:root:-:755 +/usr/lib/libpostfix-dns.so.1:f:root:-:755 +/usr/lib/libpostfix-global.so.1:f:root:-:755 +/usr/lib/libpostfix-tls.so.1:f:root:-:755 +/usr/lib/libpostfix-master.so.1:f:root:-:755 +/usr/lib/libpostfix-util.so.1:f:root:-:755 $daemon_directory/nqmgr:h:$daemon_directory/qmgr $daemon_directory/lmtp:h:$daemon_directory/smtp $command_directory/postalias:f:root:-:755 @@ -117,6 +127,7 @@ $config_directory/access:f:root:-:644:p1 $config_directory/aliases:f:root:-:644:p1 $config_directory/bounce.cf.default:f:root:-:644:1 $config_directory/canonical:f:root:-:644:p1 +$config_directory/dynamicmaps.cf:f:root:-:644:p1 $config_directory/cidr_table:f:root:-:644:o $config_directory/generic:f:root:-:644:p1 $config_directory/generics:f:root:-:644:o diff -p -up postfix-2.7.0/src/dns/Makefile.in.dynamic postfix-2.7.0/src/dns/Makefile.in --- postfix-2.7.0/src/dns/Makefile.in.dynamic 2009-01-15 22:36:39.000000000 +0100 +++ postfix-2.7.0/src/dns/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -14,7 +14,7 @@ LIBS = ../../lib/libutil.a LIB_DIR = ../../lib INC_DIR = ../../include -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c all: $(LIB) @@ -31,12 +31,10 @@ tests: test dns_rr_to_pa_test dns_rr_to_ root_tests: $(LIB): $(OBJS) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-dns.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS) $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR) - $(RANLIB) $(LIB_DIR)/$(LIB) update: $(LIB_DIR)/$(LIB) $(HDRS) -for i in $(HDRS); \ diff -p -up postfix-2.7.0/src/global/mail_conf.c.dynamic postfix-2.7.0/src/global/mail_conf.c --- postfix-2.7.0/src/global/mail_conf.c.dynamic 2009-01-20 02:50:44.000000000 +0100 +++ postfix-2.7.0/src/global/mail_conf.c 2010-02-20 18:36:31.580501570 +0100 @@ -182,6 +182,13 @@ void mail_conf_suck(void) path = concatenate(var_config_dir, "/", "main.cf", (char *) 0); dict_load_file(CONFIG_DICT, path); myfree(path); + +#ifndef NO_DYNAMIC_MAPS + path = concatenate(DEF_CONFIG_DIR, "/", "dynamicmaps.cf", (char *) 0); + dict_open_dlinfo(path); + myfree(path); +#endif + } /* mail_conf_flush - discard configuration dictionary */ diff -p -up postfix-2.7.0/src/global/mail_dict.c.dynamic postfix-2.7.0/src/global/mail_dict.c --- postfix-2.7.0/src/global/mail_dict.c.dynamic 2008-01-08 22:07:47.000000000 +0100 +++ postfix-2.7.0/src/global/mail_dict.c 2010-02-20 18:36:31.580501570 +0100 @@ -45,6 +45,7 @@ typedef struct { static const DICT_OPEN_INFO dict_open_info[] = { DICT_TYPE_PROXY, dict_proxy_open, +#ifdef NO_DYNAMIC_MAPS #ifdef HAS_LDAP DICT_TYPE_LDAP, dict_ldap_open, #endif @@ -54,6 +55,7 @@ static const DICT_OPEN_INFO dict_open_in #ifdef HAS_PGSQL DICT_TYPE_PGSQL, dict_pgsql_open, #endif +#endif /* NO_DYNAMIC_MAPS */ 0, }; diff -p -up postfix-2.7.0/src/global/mail_params.c.dynamic postfix-2.7.0/src/global/mail_params.c --- postfix-2.7.0/src/global/mail_params.c.dynamic 2009-12-25 23:29:15.000000000 +0100 +++ postfix-2.7.0/src/global/mail_params.c 2010-02-20 18:36:31.580501570 +0100 @@ -79,6 +79,7 @@ /* char *var_export_environ; /* char *var_debug_peer_list; /* int var_debug_peer_level; +/* int var_command_maxtime; /* int var_in_flow_delay; /* int var_fault_inj_code; /* char *var_bounce_service; @@ -91,6 +92,7 @@ /* char *var_error_service; /* char *var_flush_service; /* char *var_verify_service; +/* char *var_scache_service; /* char *var_trace_service; /* char *var_proxymap_service; /* char *var_proxywrite_service; @@ -265,6 +267,7 @@ char *var_import_environ; char *var_export_environ; char *var_debug_peer_list; int var_debug_peer_level; +int var_command_maxtime; int var_fault_inj_code; char *var_bounce_service; char *var_cleanup_service; @@ -276,6 +279,7 @@ char *var_showq_service; char *var_error_service; char *var_flush_service; char *var_verify_service; +char *var_scache_service; char *var_trace_service; char *var_proxymap_service; char *var_proxywrite_service; diff -p -up postfix-2.7.0/src/global/Makefile.in.dynamic postfix-2.7.0/src/global/Makefile.in --- postfix-2.7.0/src/global/Makefile.in.dynamic 2009-10-07 02:09:52.000000000 +0200 +++ postfix-2.7.0/src/global/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -34,7 +34,7 @@ OBJS = abounce.o anvil_clnt.o been_here. canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \ clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \ defer.o deliver_completed.o deliver_flock.o deliver_pass.o \ - deliver_request.o dict_ldap.o dict_mysql.o dict_pgsql.o \ + deliver_request.o \ dict_proxy.o domain_list.o dot_lockfile.o dot_lockfile_as.o \ dsb_scan.o dsn.o dsn_buf.o dsn_mask.o dsn_print.o dsn_util.o \ ehlo_mask.o ext_prop.o file_id.o flush_clnt.o header_opts.o \ @@ -47,7 +47,7 @@ OBJS = abounce.o anvil_clnt.o been_here. mail_params.o mail_pathname.o mail_queue.o mail_run.o \ mail_scan_dir.o mail_stream.o mail_task.o mail_trigger.o maps.o \ mark_corrupt.o match_parent_style.o mbox_conf.o mbox_open.o \ - mime_state.o mkmap_cdb.o mkmap_db.o mkmap_dbm.o mkmap_open.o \ + mime_state.o mkmap_db.o mkmap_dbm.o mkmap_open.o \ mkmap_sdbm.o msg_stats_print.o msg_stats_scan.o mynetworks.o \ mypwd.o namadr_list.o off_cvt.o opened.o own_inet_addr.o \ pipe_command.o post_mail.o quote_821_local.o quote_822_local.o \ @@ -104,10 +104,14 @@ LIBS = ../../lib/libutil.a LIB_DIR = ../../lib INC_DIR = ../../include MAKES = +LDAPSO = dict_ldap.so +MYSQLSO = dict_mysql.so +PGSQLSO = dict_pgsql.so +CDBSO = dict_cdb.so -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c -all: $(LIB) +all: $(LIB) $(LDAPSO) $(MYSQLSO) $(PGSQLSO) $(CDBSO) $(OBJS): ../../conf/makedefs.out @@ -117,14 +121,36 @@ Makefile: Makefile.in test: $(TESTPROG) $(LIB): $(OBJS) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-global.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS) + +$(LDAPSO): dict_ldap.o + gcc -shared -Wl,-soname,dict_ldap.so -o $@ $? -lldap -llber -L../../lib -lutil -L. -lglobal + +$(MYSQLSO): dict_mysql.o + gcc -shared -Wl,-soname,dict_mysql.so -o $@ $? -lmysqlclient -L../../lib -lutil -L. -lglobal + +$(PGSQLSO): dict_pgsql.o + gcc -shared -Wl,-soname,dict_pgsql.so -o $@ $? -lpq -L../../lib -lutil -L. -lglobal + +$(CDBSO): ../util/dict_cdb.o mkmap_cdb.o + gcc -shared -Wl,-soname,dict_cdb.so -o $@ $? -lcdb -L../../lib -lutil -L. -lglobal $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR) - $(RANLIB) $(LIB_DIR)/$(LIB) -update: $(LIB_DIR)/$(LIB) $(HDRS) +../../libexec/$(LDAPSO): $(LDAPSO) + cp $(LDAPSO) ../../libexec + +../../libexec/$(MYSQLSO): $(MYSQLSO) + cp $(MYSQLSO) ../../libexec + +../../libexec/$(PGSQLSO): $(PGSQLSO) + cp $(PGSQLSO) ../../libexec + +../../libexec/$(CDBSO): $(CDBSO) + cp $(CDBSO) ../../libexec + +update: $(LIB_DIR)/$(LIB) ../../libexec/$(LDAPSO) ../../libexec/$(MYSQLSO) ../../libexec/$(PGSQLSO) ../../libexec/$(CDBSO) $(HDRS) -for i in $(HDRS); \ do \ cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \ @@ -492,7 +518,7 @@ lint: lint $(DEFS) $(SRCS) $(LINTFIX) clean: - rm -f *.o $(LIB) *core $(TESTPROG) junk + rm -f *.o $(LIB) $(LDAPSO) $(MYSQLSO) $(PGSQLSO) $(CDBSO) *core $(TESTPROG) junk rm -rf printfck tidy: clean diff -p -up postfix-2.7.0/src/global/mkmap_open.c.dynamic postfix-2.7.0/src/global/mkmap_open.c --- postfix-2.7.0/src/global/mkmap_open.c.dynamic 2008-01-08 23:08:45.000000000 +0100 +++ postfix-2.7.0/src/global/mkmap_open.c 2010-02-20 18:36:31.580501570 +0100 @@ -81,15 +81,17 @@ * We use a different table (in dict_open.c) when querying maps. */ typedef struct { - char *type; + const char *type; MKMAP *(*before_open) (const char *); } MKMAP_OPEN_INFO; static const MKMAP_OPEN_INFO mkmap_types[] = { DICT_TYPE_PROXY, mkmap_proxy_open, +#ifdef NO_DYNAMIC_MAPS #ifdef HAS_CDB DICT_TYPE_CDB, mkmap_cdb_open, #endif +#endif /* NO_DYNAMIC_MAPS */ #ifdef HAS_SDBM DICT_TYPE_SDBM, mkmap_sdbm_open, #endif @@ -156,7 +158,16 @@ MKMAP *mkmap_open(const char *type, con */ for (mp = mkmap_types; /* void */ ; mp++) { if (mp->type == 0) +#ifndef NO_DYNAMIC_MAPS + { + static MKMAP_OPEN_INFO oi; + oi.before_open=(MKMAP*(*)(const char*))dict_mkmap_func(type); + oi.type=type; + mp=&oi; + } +#else msg_fatal("unsupported map type: %s", type); +#endif if (strcmp(type, mp->type) == 0) break; } diff -p -up postfix-2.7.0/src/master/Makefile.in.dynamic postfix-2.7.0/src/master/Makefile.in --- postfix-2.7.0/src/master/Makefile.in.dynamic 2009-07-12 00:56:43.000000000 +0200 +++ postfix-2.7.0/src/master/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -20,7 +20,7 @@ LIB_DIR = ../../lib INC_DIR = ../../include BIN_DIR = ../../libexec -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) `for i in $(LIB_OBJ); do [ $$i = $@ ] && echo -fPIC; done` $(CFLAGS) -c $*.c all: $(PROG) $(LIB) @@ -39,12 +39,10 @@ tests: root_tests: $(LIB): $(LIB_OBJ) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-master.so.1 -o $(LIB) $(LIB_OBJ) $(LIBS) $(SYSLIBS) $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR)/$(LIB) - $(RANLIB) $(LIB_DIR)/$(LIB) $(BIN_DIR)/$(PROG): $(PROG) cp $(PROG) $(BIN_DIR) diff -p -up postfix-2.7.0/src/milter/Makefile.in.dynamic postfix-2.7.0/src/milter/Makefile.in --- postfix-2.7.0/src/milter/Makefile.in.dynamic 2009-01-15 22:36:39.000000000 +0100 +++ postfix-2.7.0/src/milter/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -14,7 +14,7 @@ LIB_DIR = ../../lib INC_DIR = ../../include MAKES = -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c all: $(LIB) @@ -30,12 +30,10 @@ tests: root_tests: $(LIB): $(OBJS) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-milter.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS) $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR) - $(RANLIB) $(LIB_DIR)/$(LIB) update: $(LIB_DIR)/$(LIB) $(HDRS) -for i in $(HDRS); \ diff -p -up postfix-2.7.0/src/postconf/postconf.c.dynamic postfix-2.7.0/src/postconf/postconf.c --- postfix-2.7.0/src/postconf/postconf.c.dynamic 2009-12-31 20:02:14.000000000 +0100 +++ postfix-2.7.0/src/postconf/postconf.c 2010-02-20 18:36:31.580501570 +0100 @@ -965,6 +965,16 @@ static void show_maps(void) { ARGV *maps_argv; int i; +#ifndef NO_DYNAMIC_MAPS + char *path; + char *config_dir; + + var_config_dir = mystrdup((config_dir = safe_getenv(CONF_ENV_PATH)) != 0 ? + config_dir : DEF_CONFIG_DIR); /* XXX */ + path = concatenate(var_config_dir, "/", "dynamicmaps.cf", (char *) 0); + dict_open_dlinfo(path); + myfree(path); +#endif maps_argv = dict_mapnames(); for (i = 0; i < maps_argv->argc; i++) diff -p -up postfix-2.7.0/src/tls/Makefile.in.dynamic postfix-2.7.0/src/tls/Makefile.in --- postfix-2.7.0/src/tls/Makefile.in.dynamic 2009-01-15 22:36:39.000000000 +0100 +++ postfix-2.7.0/src/tls/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -22,7 +22,7 @@ LIB_DIR = ../../lib INC_DIR = ../../include MAKES = -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c all: $(LIB) @@ -38,12 +38,10 @@ tests: root_tests: $(LIB): $(OBJS) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-tls.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS) $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR) - $(RANLIB) $(LIB_DIR)/$(LIB) update: $(LIB_DIR)/$(LIB) $(HDRS) -for i in $(HDRS); \ diff -p -up postfix-2.7.0/src/util/dict.h.dynamic postfix-2.7.0/src/util/dict.h --- postfix-2.7.0/src/util/dict.h.dynamic 2007-12-03 20:42:26.000000000 +0100 +++ postfix-2.7.0/src/util/dict.h 2010-02-20 18:36:31.580501570 +0100 @@ -138,6 +138,11 @@ extern const char *dict_eval(const char extern DICT *dict_open(const char *, int, int); extern DICT *dict_open3(const char *, const char *, int, int); extern void dict_open_register(const char *, DICT *(*) (const char *, int, int)); +#ifndef NO_DYNAMIC_MAPS +extern void dict_open_dlinfo(const char *path); +typedef void* (*dict_mkmap_func_t)(const char *); +dict_mkmap_func_t dict_mkmap_func(const char *dict_type); +#endif #define dict_get(dp, key) ((const char *) (dp)->lookup((dp), (key))) #define dict_put(dp, key, val) (dp)->update((dp), (key), (val)) diff -p -up postfix-2.7.0/src/util/dict_open.c.dynamic postfix-2.7.0/src/util/dict_open.c --- postfix-2.7.0/src/util/dict_open.c.dynamic 2010-02-10 01:21:30.000000000 +0100 +++ postfix-2.7.0/src/util/dict_open.c 2010-02-20 18:36:31.580501570 +0100 @@ -44,6 +44,8 @@ /* DICT *(*open) (const char *, int, int); /* /* ARGV *dict_mapnames() +/* +/* void (*)() dict_mkmap_func(const char *dict_type) /* DESCRIPTION /* This module implements a low-level interface to multiple /* physical dictionary types. @@ -159,6 +161,9 @@ /* /* dict_mapnames() returns a sorted list with the names of all available /* dictionary types. +/* +/* dict_mkmap_func() returns a pointer to the mkmap setup function +/* for the given map type, as given in /etc/dynamicmaps.cf /* DIAGNOSTICS /* Fatal error: open error, unsupported dictionary type, attempt to /* update non-writable dictionary. @@ -183,6 +188,9 @@ #include <strings.h> #endif +#include <sys/stat.h> +#include <unistd.h> + /* Utility library. */ #include <argv.h> @@ -208,6 +216,27 @@ #include <split_at.h> #include <htable.h> +#ifndef NO_DYNAMIC_MAPS +#include <load_lib.h> +#include <vstring.h> +#include <vstream.h> +#include <vstring_vstream.h> +#include <mvect.h> + + /* + * Interface for dynamic map loading. + */ +typedef struct { + const char *pattern; + const char *soname; + const char *openfunc; + const char *mkmapfunc; +} DLINFO; + +static DLINFO *dict_dlinfo; +static DLINFO *dict_open_dlfind(const char *type); +#endif + /* * lookup table for available map types. */ @@ -217,9 +246,11 @@ typedef struct { } DICT_OPEN_INFO; static const DICT_OPEN_INFO dict_open_info[] = { +#ifdef NO_DYNAMIC_MAPS #ifdef HAS_CDB DICT_TYPE_CDB, dict_cdb_open, #endif +#endif /* NO_DYNAMIC_MAPS */ DICT_TYPE_ENVIRON, dict_env_open, DICT_TYPE_HT, dict_ht_open, DICT_TYPE_UNIX, dict_unix_open, @@ -243,9 +274,11 @@ static const DICT_OPEN_INFO dict_open_in #ifdef HAS_NETINFO DICT_TYPE_NETINFO, dict_ni_open, #endif +#ifdef NO_DYNAMIC_MAPS #ifdef HAS_PCRE DICT_TYPE_PCRE, dict_pcre_open, #endif +#endif /* NO_DYNAMIC_MAPS */ #ifdef HAS_POSIX_REGEXP DICT_TYPE_REGEXP, dict_regexp_open, #endif @@ -303,8 +336,31 @@ DICT *dict_open3(const char *dict_type dict_type, dict_name); if (dict_open_hash == 0) dict_open_init(); - if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) - msg_fatal("unsupported dictionary type: %s", dict_type); + if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) { +#ifdef NO_DYNAMIC_MAPS + msg_fatal("%s: unsupported dictionary type: %s", myname, dict_type); +#else + struct stat st; + LIB_FN fn[2]; + DICT *(*open) (const char *, int, int); + DLINFO *dl=dict_open_dlfind(dict_type); + if (!dl) + msg_fatal("%s: unsupported dictionary type: %s: Is the postfix-%s package installed?", myname, dict_type, dict_type); + if (stat(dl->soname,&st) < 0) { + msg_fatal("%s: unsupported dictionary type: %s (%s not found. Is the postfix-%s package installed?)", + myname, dict_type, dl->soname, dict_type); + } + fn[0].name = dl->openfunc; + fn[0].ptr = (void**)&open; + fn[1].name = NULL; + load_library_symbols(dl->soname, fn, NULL); + dict_open_register(dict_type, open); + dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type); +#endif + } + if (msg_verbose>1) { + msg_info("%s: calling %s open routine",myname,dict_type); + } if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0) msg_fatal("opening %s:%s %m", dict_type, dict_name); if (msg_verbose) @@ -312,6 +368,36 @@ DICT *dict_open3(const char *dict_type return (dict); } +dict_mkmap_func_t dict_mkmap_func(const char *dict_type) +{ + char *myname="dict_mkmap_func"; + struct stat st; + LIB_FN fn[2]; + dict_mkmap_func_t mkmap; + DLINFO *dl; +#ifndef NO_DYNAMIC_MAPS + if (!dict_dlinfo) + msg_fatal("dlinfo==NULL"); + dl=dict_open_dlfind(dict_type); + if (!dl) + msg_fatal("%s: unsupported dictionary type: %s: Is the postfix-%s package installed?", myname, dict_type, dict_type); + if (stat(dl->soname,&st) < 0) { + msg_fatal("%s: unsupported dictionary type: %s (%s not found. Is the postfix-%s package installed?)", + myname, dict_type, dl->soname, dict_type); + } + if (!dl->mkmapfunc) + msg_fatal("%s: unsupported dictionary type: %s does not allow map creation.", myname, dict_type); + + fn[0].name = dl->mkmapfunc; + fn[0].ptr = (void**)&mkmap; + fn[1].name = NULL; + load_library_symbols(dl->soname, fn, NULL); + return mkmap; +#else + return (void(*)())NULL; +#endif +} + /* dict_open_register - register dictionary type */ void dict_open_register(const char *type, @@ -345,6 +431,9 @@ ARGV *dict_mapnames() HTABLE_INFO **ht; DICT_OPEN_INFO *dp; ARGV *mapnames; +#ifndef NO_DYNAMIC_MAPS + DLINFO *dlp; +#endif if (dict_open_hash == 0) dict_open_init(); @@ -353,6 +442,13 @@ ARGV *dict_mapnames() dp = (DICT_OPEN_INFO *) ht[0]->value; argv_add(mapnames, dp->type, ARGV_END); } +#ifndef NO_DYNAMIC_MAPS + if (!dict_dlinfo) + msg_fatal("dlinfo==NULL"); + for (dlp=dict_dlinfo; dlp->pattern; dlp++) { + argv_add(mapnames, dlp->pattern, ARGV_END); + } +#endif qsort((void *) mapnames->argv, mapnames->argc, sizeof(mapnames->argv[0]), dict_sort_alpha_cpp); myfree((char *) ht_info); @@ -360,6 +456,87 @@ ARGV *dict_mapnames() return mapnames; } +#ifndef NO_DYNAMIC_MAPS +#define STREQ(x,y) (x == y || (x[0] == y[0] && strcmp(x,y) == 0)) + +void dict_open_dlinfo(const char *path) +{ + char *myname="dict_open_dlinfo"; + VSTREAM *conf_fp=vstream_fopen(path,O_RDONLY,0); + VSTRING *buf = vstring_alloc(100); + char *cp; + ARGV *argv; + MVECT vector; + int nelm=0; + int linenum=0; + + dict_dlinfo=(DLINFO*)mvect_alloc(&vector,sizeof(DLINFO),3,NULL,NULL); + + if (!conf_fp) { + msg_warn("%s: cannot open %s. No dynamic maps will be allowed.", + myname, path); + } else { + while (vstring_get_nonl(buf,conf_fp) != VSTREAM_EOF) { + cp = vstring_str(buf); + linenum++; + if (*cp == '#' || *cp == '\0') + continue; + argv = argv_split(cp, " \t"); + if (argv->argc != 3 && argv->argc != 4) { + msg_fatal("%s: Expected \"pattern .so-name open-function [mkmap-function]\" at line %d", + myname, linenum); + } + if (STREQ(argv->argv[0],"*")) { + msg_warn("%s: wildcard dynamic map entry no longer supported.", + myname); + continue; + } + if (argv->argv[1][0] != '/') { + msg_fatal("%s: .so name must begin with a \"/\" at line %d", + myname, linenum); + } + if (nelm >= vector.nelm) { + dict_dlinfo=(DLINFO*)mvect_realloc(&vector,vector.nelm+3); + } + dict_dlinfo[nelm].pattern = mystrdup(argv->argv[0]); + dict_dlinfo[nelm].soname = mystrdup(argv->argv[1]); + dict_dlinfo[nelm].openfunc = mystrdup(argv->argv[2]); + if (argv->argc==4) + dict_dlinfo[nelm].mkmapfunc = mystrdup(argv->argv[3]); + else + dict_dlinfo[nelm].mkmapfunc = NULL; + nelm++; + argv_free(argv); + } + } + if (nelm >= vector.nelm) { + dict_dlinfo=(DLINFO*)mvect_realloc(&vector,vector.nelm+1); + } + dict_dlinfo[nelm].pattern = NULL; + dict_dlinfo[nelm].soname = NULL; + dict_dlinfo[nelm].openfunc = NULL; + dict_dlinfo[nelm].mkmapfunc = NULL; + if (conf_fp) + vstream_fclose(conf_fp); + vstring_free(buf); +} + +static DLINFO *dict_open_dlfind(const char *type) +{ + DLINFO *dp; + + if (!dict_dlinfo) + return NULL; + + for (dp=dict_dlinfo; dp->pattern; dp++) { + if (STREQ(dp->pattern,type)) + return dp; + } + return NULL; +} + +#endif /* !NO_DYNAMIC_MAPS */ + #ifdef TEST /* diff -p -up postfix-2.7.0/src/util/load_lib.c.dynamic postfix-2.7.0/src/util/load_lib.c --- postfix-2.7.0/src/util/load_lib.c.dynamic 2010-02-20 18:36:31.580501570 +0100 +++ postfix-2.7.0/src/util/load_lib.c 2010-02-20 18:36:31.580501570 +0100 @@ -0,0 +1,135 @@ +/*++ +/* NAME +/* load_lib 3 +/* SUMMARY +/* library loading wrappers +/* SYNOPSIS +/* #include <load_lib.h> +/* +/* extern int load_library_symbols(const char *, LIB_FN *, LIB_FN *); +/* const char *libname; +/* LIB_FN *libfuncs; +/* LIB_FN *libdata; +/* +/* DESCRIPTION +/* This module loads functions from libraries, returnine pointers +/* to the named functions. +/* +/* load_library_symbols() loads all of the desired functions, and +/* returns zero for success, or exits via msg_fatal(). +/* +/* SEE ALSO +/* msg(3) diagnostics interface +/* DIAGNOSTICS +/* Problems are reported via the msg(3) diagnostics routines: +/* library not found, symbols not found, other fatal errors. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* LaMont Jones +/* Hewlett-Packard Company +/* 3404 Harmony Road +/* Fort Collins, CO 80528, USA +/* +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System libraries. */ + +#include "sys_defs.h" +#include <stdlib.h> +#include <stddef.h> +#include <string.h> +#if defined(HAS_DLOPEN) +#include <dlfcn.h> +#elif defined(HAS_SHL_LOAD) +#include <dl.h> +#endif + +/* Application-specific. */ + +#include "msg.h" +#include "load_lib.h" + +extern int load_library_symbols(const char * libname, LIB_FN * libfuncs, LIB_FN * libdata) +{ + char *myname = "load_library_symbols"; + LIB_FN *fn; + +#if defined(HAS_DLOPEN) + void *handle; + char *emsg; + + handle=dlopen(libname,RTLD_NOW); + emsg=dlerror(); + if (emsg) { + msg_fatal("%s: dlopen failure loading %s: %s", myname, libname, emsg); + } + + if (libfuncs) { + for (fn=libfuncs; fn->name; fn++) { + *(fn->ptr) = dlsym(handle,fn->name); + emsg=dlerror(); + if (emsg) { + msg_fatal("%s: dlsym failure looking up %s in %s: %s", myname, + fn->name, libname, emsg); + } + if (msg_verbose>1) { + msg_info("loaded %s = %lx",fn->name, *((long*)(fn->ptr))); + } + } + } + + if (libdata) { + for (fn=libdata; fn->name; fn++) { + *(fn->ptr) = dlsym(handle,fn->name); + emsg=dlerror(); + if (emsg) { + msg_fatal("%s: dlsym failure looking up %s in %s: %s", myname, + fn->name, libname, emsg); + } + if (msg_verbose>1) { + msg_info("loaded %s = %lx",fn->name, *((long*)(fn->ptr))); + } + } + } +#elif defined(HAS_SHL_LOAD) + shl_t handle; + + handle = shl_load(libname,BIND_IMMEDIATE,0); + + if (libfuncs) { + for (fn=libfuncs; fn->name; fn++) { + if (shl_findsym(&handle,fn->name,TYPE_PROCEDURE,fn->ptr) != 0) { + msg_fatal("%s: shl_findsym failure looking up %s in %s: %m", + myname, fn->name, libname); + } + if (msg_verbose>1) { + msg_info("loaded %s = %x",fn->name, *((long*)(fn->ptr))); + } + } + } + + if (libdata) { + for (fn=libdata; fn->name; fn++) { + if (shl_findsym(&handle,fn->name,TYPE_DATA,fn->ptr) != 0) { + msg_fatal("%s: shl_findsym failure looking up %s in %s: %m", + myname, fn->name, libname); + } + if (msg_verbose>1) { + msg_info("loaded %s = %x",fn->name, *((long*)(fn->ptr))); + } + } + } + +#else + msg_fatal("%s: need dlopen or shl_load support for dynamic libraries", + myname); +#endif + return 0; +} diff -p -up postfix-2.7.0/src/util/load_lib.h.dynamic postfix-2.7.0/src/util/load_lib.h --- postfix-2.7.0/src/util/load_lib.h.dynamic 2010-02-20 18:36:31.580501570 +0100 +++ postfix-2.7.0/src/util/load_lib.h 2010-02-20 18:36:31.580501570 +0100 @@ -0,0 +1,41 @@ +#ifndef _LOAD_LIB_H_INCLUDED_ +#define _LOAD_LIB_H_INCLUDED_ + +/*++ +/* NAME +/* load_lib 3h +/* SUMMARY +/* library loading wrappers +/* SYNOPSIS +/* #include "load_lib.h" +/* DESCRIPTION +/* .nf + + /* + * External interface. + */ +/* NULL name terminates list */ +typedef struct LIB_FN { + const char *name; + void **ptr; +} LIB_FN; + +extern int load_library_symbols(const char *, LIB_FN *, LIB_FN *); + +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* LaMont Jones +/* Hewlett-Packard Company +/* 3404 Harmony Road +/* Fort Collins, CO 80528, USA +/* +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +#endif diff -p -up postfix-2.7.0/src/util/Makefile.in.dynamic postfix-2.7.0/src/util/Makefile.in --- postfix-2.7.0/src/util/Makefile.in.dynamic 2010-02-20 18:36:31.570723986 +0100 +++ postfix-2.7.0/src/util/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -32,14 +32,14 @@ SRCS = alldig.c allprint.c argv.c argv_s write_buf.c write_wait.c sane_basename.c format_tv.c allspace.c \ allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \ upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \ - unix_pass_fd_fix.c dict_cache.c + unix_pass_fd_fix.c dict_cache.c load_lib.c OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \ attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \ attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \ chroot_uid.o cidr_match.o clean_env.o close_on_exec.o concatenate.o \ - ctable.o dict.o dict_alloc.o dict_cdb.o dict_cidr.o dict_db.o \ + ctable.o dict.o dict_alloc.o dict_cidr.o dict_db.o \ dict_dbm.o dict_debug.o dict_env.o dict_ht.o dict_ni.o dict_nis.o \ - dict_nisplus.o dict_open.o dict_pcre.o dict_regexp.o dict_sdbm.o \ + dict_nisplus.o dict_open.o dict_regexp.o dict_sdbm.o \ dict_static.o dict_tcp.o dict_unix.o dir_forest.o doze.o dummy_read.o \ dummy_write.o duplex_pipe.o environ.o events.o exec_command.o \ fifo_listen.o fifo_trigger.o file_limit.o find_inet.o fsspace.o \ @@ -66,7 +66,7 @@ OBJS = alldig.o allprint.o argv.o argv_s write_buf.o write_wait.o sane_basename.o format_tv.o allspace.o \ allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \ upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \ - unix_pass_fd_fix.o dict_cache.o + unix_pass_fd_fix.o dict_cache.o load_lib.o HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \ chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \ dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \ @@ -86,13 +86,14 @@ HDRS = argv.h attr.h attr_clnt.h auto_cl stringops.h sys_defs.h timed_connect.h timed_wait.h trigger.h \ username.h valid_hostname.h vbuf.h vbuf_print.h vstream.h vstring.h \ vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \ - edit_file.h dict_cache.h + edit_file.h dict_cache.h load_lib.h TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ stream_test.c dup2_pass_on_exec.c test_send_fd test_recv_fd DEFS = -I. -D$(SYSTYPE) CFLAGS = $(DEBUG) $(OPT) $(DEFS) FILES = Makefile $(SRCS) $(HDRS) INCL = +PCRESO = dict_pcre.so LIB = libutil.a TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \ fifo_rdonly_bug fifo_rdwr_bug fifo_trigger fsspace fullname \ @@ -108,10 +109,11 @@ TESTPROG= dict_open dup2_pass_on_exec ev LIB_DIR = ../../lib INC_DIR = ../../include +LIBS = $(LIB_DIR)/$(LIB) $(PCRESO) dict_cdb.o -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c -all: $(LIB) +all: $(LIB) $(PCRESO) $(OBJS): ../../conf/makedefs.out @@ -120,15 +122,19 @@ Makefile: Makefile.in test: $(TESTPROG) +$(PCRESO): dict_pcre.o + gcc -shared -Wl,-soname,dict_pcre.so -o $@ $? -lpcre -L. -lutil + $(LIB): $(OBJS) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-util.so.1 -o $(LIB) $(OBJS) -ldl $(SYSLIBS) $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR) - $(RANLIB) $(LIB_DIR)/$(LIB) -update: $(LIB_DIR)/$(LIB) $(HDRS) +../../libexec/$(PCRESO): $(PCRESO) + cp $(PCRESO) ../../libexec + +update: $(LIBS) ../../libexec/$(PCRESO) $(HDRS) -for i in $(HDRS); \ do \ cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \ @@ -150,7 +156,8 @@ lint: lint $(SRCS) clean: - rm -f *.o $(LIB) *core $(TESTPROG) junk $(MAKES) *.tmp + rm -f *.o $(LIB) $(PCRESO) *core $(TESTPROG) \ + junk $(MAKES) *.tmp rm -rf printfck tidy: clean diff -p -up postfix-2.7.0/src/xsasl/Makefile.in.dynamic postfix-2.7.0/src/xsasl/Makefile.in --- postfix-2.7.0/src/xsasl/Makefile.in.dynamic 2009-01-15 22:36:39.000000000 +0100 +++ postfix-2.7.0/src/xsasl/Makefile.in 2010-02-20 18:36:31.580501570 +0100 @@ -18,7 +18,7 @@ LIB_DIR = ../../lib INC_DIR = ../../include MAKES = -.c.o:; $(CC) $(CFLAGS) -c $*.c +.c.o:; $(CC) -fPIC $(CFLAGS) -c $*.c all: $(LIB) @@ -34,12 +34,10 @@ tests: root_tests: $(LIB): $(OBJS) - $(AR) $(ARFL) $(LIB) $? - $(RANLIB) $(LIB) + gcc -shared -Wl,-soname,libpostfix-xsasl.so.1 -o $(LIB) $(OBJS) $(LIBS) $(SYSLIBS) $(LIB_DIR)/$(LIB): $(LIB) cp $(LIB) $(LIB_DIR) - $(RANLIB) $(LIB_DIR)/$(LIB) update: $(LIB_DIR)/$(LIB) $(HDRS) -for i in $(HDRS); \