]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Move libldap init to global_lib framework (#4546)
authorNick Porter <nick@portercomputing.co.uk>
Fri, 3 Jun 2022 16:42:30 +0000 (17:42 +0100)
committerGitHub <noreply@github.com>
Fri, 3 Jun 2022 16:42:30 +0000 (12:42 -0400)
* Define libldap global config options and init / free callbacks

* Move libldap global options to global {} section

* Switch rlm_ldap to use autoinit of ldap library

* Clear old instance tracking from libldap

* Ensure global.d directory is handled correctly by packages

* Allow per module test global library settings

* Move global ldap library settings to correct location for tests

* Include global.d in list of raddb files to install

* WS

* Newline

Co-authored-by: Arran Cudbard-Bell <a.cudbardb@freeradius.org>
14 files changed:
debian/freeradius.postinst
debian/freeradius.prerm
raddb/all.mk
raddb/global.d/ldap [new file with mode: 0644]
raddb/mods-available/ldap
raddb/radiusd.conf.in
redhat/freeradius.spec
src/lib/ldap/base.c
src/lib/ldap/base.h
src/modules/rlm_ldap/rlm_ldap.c
src/modules/rlm_ldap/rlm_ldap.h
src/tests/modules/ldap/global.conf [new file with mode: 0644]
src/tests/modules/ldap/module.conf
src/tests/modules/unit_test_module.conf

index ce51a1d66c1d03f5ae3128032fdb25efb9bbcb2d..72be7109f0da380b48d53e527514bc815be64292 100644 (file)
@@ -47,6 +47,7 @@ case "$1" in
             /etc/freeradius/sites-available \
             /etc/freeradius/sites-enabled \
             /etc/freeradius/mods-config/attr_filter \
+            /etc/freeradius/global.d \
             /etc/freeradius/policy.d
           do
             if ! dpkg-statoverride --list | grep -qw $dir$; then
index d35359ff000b5bd192f1b29d06e7dca8efe8b77f..b1a242ca2ded84b44a3fa2b0b80cc091dc08f76c 100644 (file)
@@ -29,6 +29,7 @@ case "$1" in
           /etc/freeradius/mods-enabled \
           /etc/freeradius/mods-config/attr_filter \
           /etc/freeradius/mods-config \
+          /etc/freeradius/global.d \
           /etc/freeradius/policy.d \
           /var/run/freeradius \
           /var/log/freeradius
index c6ac401f263604ff21ecf28b8e2bb32642479df4..b281ffc7543e50603e8fc06305be8e0bb2633df9 100644 (file)
@@ -53,7 +53,7 @@ LEGACY_LINKS :=               $(addprefix $(R)$(raddbdir)/,users)
 
 BUILD_RADDB := $(strip $(foreach x,install clean,$(findstring $(x),$(MAKECMDGOALS))))
 ifneq "$(BUILD_RADDB)" ""
-RADDB_DIRS :=          certs mods-available mods-enabled policy.d template.d \
+RADDB_DIRS :=          certs mods-available mods-enabled global.d policy.d template.d \
                        sites-available sites-enabled \
                        $(patsubst raddb/%,%,$(call FIND_DIRS,raddb/mods-config))
 
@@ -65,6 +65,7 @@ INSTALL_FILES :=      $(wildcard raddb/sites-available/* raddb/mods-available/*) \
                        $(addprefix raddb/,$(LOCAL_FILES)) \
                        $(addprefix raddb/certs/,$(INSTALL_CERT_FILES)) \
                        $(call FIND_FILES,raddb/mods-config) \
+                       $(call FIND_FILES,raddb/global.d) \
                        $(call FIND_FILES,raddb/policy.d) \
                        $(call FIND_FILES,raddb/template.d)
 
diff --git a/raddb/global.d/ldap b/raddb/global.d/ldap
new file mode 100644 (file)
index 0000000..e4cb87d
--- /dev/null
@@ -0,0 +1,47 @@
+ldap {
+       #
+       #  random_file:: Provides random number generator.
+       #
+#      random_file = /dev/urandom
+
+       #
+       #  ldap_debug:: Debug flags for libldap (see OpenLDAP documentation).
+       #  Set this to enable debugging output from different code areas within libldap.
+       #
+       #  NOTE: These debugging options can produce significant amounts of logging output.
+       #
+       #  [options="header,autowidth"]
+       #  |===
+       #  | Option             | Value
+       #  | LDAP_DEBUG_TRACE   | 0x0001
+       #  | LDAP_DEBUG_PACKETS | 0x0002
+       #  | LDAP_DEBUG_ARGS    | 0x0004
+       #  | LDAP_DEBUG_CONNS   | 0x0008
+       #  | LDAP_DEBUG_BER     | 0x0010
+       #  | LDAP_DEBUG_FILTER  | 0x0020
+       #  | LDAP_DEBUG_CONFIG  | 0x0040
+       #  | LDAP_DEBUG_ACL     | 0x0080
+       #  | LDAP_DEBUG_STATS   | 0x0100
+       #  | LDAP_DEBUG_STATS2  | 0x0200
+       #  | LDAP_DEBUG_SHELL   | 0x0400
+       #  | LDAP_DEBUG_PARSE   | 0x0800
+       #  | LDAP_DEBUG_SYNC    | 0x4000
+       #  | LDAP_DEBUG_NONE    | 0x8000
+       #  | LDAP_DEBUG_ANY     | (-1)
+       #  |===
+       #
+       #  e.g:
+       #
+       #  If you want to see the LDAP logs only for `trace` and `parse`,
+       #  facilities you should use:
+       #
+       #    (LDAP_DEBUG_TRACE + LDAP_DEBUG_PARSE) = 0x0801
+       #
+       #  Setting the `ldap_debug` configuration item as follows:
+       #
+       #     ldap_debug = 0x0801
+       #
+       #  Default: 0x0000 (no debugging messages)
+       #
+       ldap_debug = 0x0000
+}
index d811482651d4559ba1fab7e61f7abdcfb4250122..eac37631a2b7a7eae05798c5b8e7610e9a5b4dd2 100644 (file)
@@ -149,57 +149,6 @@ ldap {
        #
 #      valuepair_attribute = 'radiusAttribute'
 
-       #
-       #  ### Global
-       #
-       global {
-               #
-               #  random_file:: Provides random number generator.
-               #
-#              random_file = /dev/urandom
-
-               #
-               #  ldap_debug:: Debug flags for libldap (see OpenLDAP documentation).
-               #  Set this to enable debugging output from different code areas within libldap.
-               #
-               #  NOTE: These debugging options can produce significant amounts of logging output.
-               #
-               #  [options="header,autowidth"]
-               #  |===
-               #  | Option             | Value
-               #  | LDAP_DEBUG_TRACE   | 0x0001
-               #  | LDAP_DEBUG_PACKETS | 0x0002
-               #  | LDAP_DEBUG_ARGS    | 0x0004
-               #  | LDAP_DEBUG_CONNS   | 0x0008
-               #  | LDAP_DEBUG_BER     | 0x0010
-               #  | LDAP_DEBUG_FILTER  | 0x0020
-               #  | LDAP_DEBUG_CONFIG  | 0x0040
-               #  | LDAP_DEBUG_ACL     | 0x0080
-               #  | LDAP_DEBUG_STATS   | 0x0100
-               #  | LDAP_DEBUG_STATS2  | 0x0200
-               #  | LDAP_DEBUG_SHELL   | 0x0400
-               #  | LDAP_DEBUG_PARSE   | 0x0800
-               #  | LDAP_DEBUG_SYNC    | 0x4000
-               #  | LDAP_DEBUG_NONE    | 0x8000
-               #  | LDAP_DEBUG_ANY     | (-1)
-               #  |===
-               #
-               #  e.g:
-               #
-               #  If you want to see the LDAP logs only for `trace` and `parse`,
-               #  facilities you should use:
-               #
-               #    (LDAP_DEBUG_TRACE + LDAP_DEBUG_PARSE) = 0x0801
-               #
-               #  Setting the `ldap_debug` configuration item as follows:
-               #
-               #     ldap_debug = 0x0801
-               #
-               #  Default: 0x0000 (no debugging messages)
-               #
-               ldap_debug = 0x0000
-       }
-
        #
        #  ### Mapping of LDAP directory attributes to RADIUS dictionary attributes.
        #
index 54b7b7461f5c9a85b9afb201ef133b011dadec6e..539832e46fbbe358d2ec1ccfb92973802c0d372b 100644 (file)
@@ -560,6 +560,16 @@ thread pool {
 #
 #$INCLUDE trigger.conf
 
+#
+#  .Global Library Settings
+#
+#  Each library which has global settings will have its own configuration
+#  file in global.d
+#
+global {
+       $INCLUDE global.d/
+}
+
 #
 #  .Module Configuration
 #
index 5a33ad459e9d9313aca0e326f3b0fe7cbde0ec21..ecf3c77c71ebebd258d8521ea7e6f690abe9b460 100644 (file)
@@ -776,6 +776,8 @@ fi
 %config(noreplace) %{_sysconfdir}/raddb/sites-enabled/*
 %dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/policy.d
 %attr(640,root,radiusd) %config(noreplace) %{_sysconfdir}/raddb/policy.d/*
+%dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/global.d
+%attr(640,root,radiusd) %config(noreplace) %{_sysconfdir}/raddb/global.d/*
 %dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/template.d
 %attr(640,root,radiusd) %config(noreplace) %{_sysconfdir}/raddb/template.d/*
 %dir %attr(750,root,radiusd) %{_sysconfdir}/raddb/mods-available
index 06440b0f5769a0fdc47af951c7d21dc32fe4fe50..9028c5ab6b2e512463aa6aca976ed65907dfa102 100644 (file)
@@ -41,8 +41,6 @@ LDAP *ldap_global_handle;                     //!< Hack for OpenLDAP libldap global initialisation
 static _Thread_local LDAP *ldap_thread_local_handle;   //!< Hack for functions which require an ldap handle
                                                ///< but don't actually use it for anything.
 
-static uint32_t instance_count = 0;
-
 /** Used to set the global log prefix for functions which don't operate on connections
  *
  */
@@ -93,6 +91,54 @@ fr_table_num_sorted_t const fr_ldap_dereference[] = {
 };
 size_t fr_ldap_dereference_len = NUM_ELEMENTS(fr_ldap_dereference);
 
+static fr_libldap_global_config_t libldap_global_config = {
+       .ldap_debug = 0x00,
+       .tls_random_file = ""
+};
+
+static CONF_PARSER const ldap_global_config[] = {
+       { FR_CONF_OFFSET("random_file", FR_TYPE_FILE_EXISTS, fr_libldap_global_config_t, tls_random_file) },
+       { FR_CONF_OFFSET("ldap_debug", FR_TYPE_UINT32, fr_libldap_global_config_t, ldap_debug), .dflt = "0x0000" },
+       CONF_PARSER_TERMINATOR
+};
+
+/** Initialise libldap library and set global options
+ *
+ * Used as a callback from global library initialisation.
+ */
+static int libldap_init(void)
+{
+       if (fr_ldap_init() < 0) return -1;
+
+       fr_ldap_global_config(libldap_global_config.ldap_debug, libldap_global_config.tls_random_file);
+
+       return 0;
+}
+
+/** Free any global libldap resources
+ *
+ */
+static void libldap_free(void)
+{
+       /*
+        *      Keeping the dummy ld around for the lifetime
+        *      of the module should always work,
+        *      irrespective of what changes happen in libldap.
+        */
+       ldap_unbind_ext_s(ldap_global_handle, NULL, NULL);
+}
+
+/*
+ *     Public symbol modules can reference to auto instantiate libldap
+ */
+global_lib_autoinst_t fr_libldap_global_config = {
+        .name = "ldap",
+        .config = (const CONF_PARSER *)ldap_global_config,
+        .inst = &libldap_global_config,
+        .init = libldap_init,
+        .free = libldap_free
+};
+
 typedef struct {
        fr_ldap_query_t *query;
        LDAPMessage     **result;
@@ -978,11 +1024,6 @@ int fr_ldap_init(void)
        static LDAPAPIInfo      info = { .ldapai_info_version = LDAP_API_INFO_VERSION };        /* static to quiet valgrind about this being uninitialised */
        fr_ldap_config_t        *handle_config = &ldap_global_handle_config;
 
-       if (instance_count > 0) {
-               instance_count++;
-               return 0;
-       }
-
        /*
         *      Only needs to be done once, prevents races in environment
         *      initialisation within libldap.
@@ -1039,22 +1080,5 @@ int fr_ldap_init(void)
                     LDAP_VENDOR_VERSION_MAJOR, LDAP_VENDOR_VERSION_MINOR, LDAP_VENDOR_VERSION_PATCH);
        }
 
-       instance_count++;
-
        return 0;
 }
-
-/** Free any global libldap resources
- *
- */
-void fr_ldap_free(void)
-{
-       if (--instance_count > 0) return;
-
-       /*
-        *      Keeping the dummy ld around for the lifetime
-        *      of the module should always work,
-        *      irrespective of what changes happen in libldap.
-        */
-       ldap_unbind_ext_s(ldap_global_handle, NULL, NULL);
-}
index e2a47d7764d437d50930f29d1ac55a23ee7519b9..6784e3b04da6d577358c06de85c932b4edb33927 100644 (file)
@@ -11,6 +11,7 @@
  */
 #include <freeradius-devel/server/base.h>
 #include <freeradius-devel/server/connection.h>
+#include <freeradius-devel/server/global_lib.h>
 #include <freeradius-devel/server/map.h>
 #include <freeradius-devel/server/trunk.h>
 
@@ -302,6 +303,17 @@ typedef struct {
        fr_time_delta_t         idle_timeout;           //!< How long to wait before closing unused connections.
 } fr_ldap_config_t;
 
+/** libldap global configuration data
+ *
+ */
+typedef struct {
+       uint32_t                ldap_debug;             //!< LDAP debug level
+       char const              *tls_random_file;       //!< Path to the ramdon file if /dev/random and /dev/urandom
+                                                       //!< are unavailable
+} fr_libldap_global_config_t;
+
+extern global_lib_autoinst_t fr_libldap_global_config;
+
 typedef struct fr_ldap_thread_trunk_s fr_ldap_thread_trunk_t;
 
 /** Tracks the state of a libldap connection handle
index 431b24ad4077344590f5539479dc5638e6477769..63da9c444fde8c6774823e0e1e2451a983c19ebc 100644 (file)
@@ -182,14 +182,6 @@ static CONF_PARSER option_config[] = {
        CONF_PARSER_TERMINATOR
 };
 
-static const CONF_PARSER global_config[] = {
-       { FR_CONF_OFFSET("random_file", FR_TYPE_FILE_EXISTS, rlm_ldap_t, tls_random_file) },
-
-       { FR_CONF_OFFSET("ldap_debug", FR_TYPE_UINT32, rlm_ldap_t, ldap_debug), .dflt = "0x0000" },             /* Debugging flags to the server */
-
-       CONF_PARSER_TERMINATOR
-};
-
 static const CONF_PARSER module_config[] = {
        /*
         *      Pool config items
@@ -228,8 +220,6 @@ static const CONF_PARSER module_config[] = {
 
        { FR_CONF_POINTER("options", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) option_config },
 
-       { FR_CONF_POINTER("global", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) global_config },
-
        { FR_CONF_OFFSET("tls", FR_TYPE_SUBSECTION, rlm_ldap_t, handle_config), .subcs = (void const *) tls_config },
 
        { FR_CONF_OFFSET("pool", FR_TYPE_SUBSECTION, rlm_ldap_t, trunk_conf), .subcs = (void const *) fr_trunk_config },
@@ -270,6 +260,12 @@ fr_dict_attr_autoload_t rlm_ldap_dict_attr[] = {
        { NULL }
 };
 
+extern global_lib_autoinst_t const *rlm_ldap_lib[];
+global_lib_autoinst_t const *rlm_ldap_lib[] = {
+       &fr_libldap_global_config,
+       GLOBAL_LIB_TERMINATOR
+};
+
 
 static xlat_arg_parser_t const ldap_escape_xlat_arg = { .required = true, .concat = true, .type = FR_TYPE_STRING };
 
@@ -2224,31 +2220,12 @@ static int mod_instantiate(module_inst_ctx_t const *mctx)
                }
        }
 
-       /*
-        *      Set global options
-        */
-       if (fr_ldap_init() < 0) goto error;
-
-       fr_ldap_global_config(inst->ldap_debug, inst->tls_random_file);
-
        return 0;
 
 error:
        return -1;
 }
 
-static int mod_load(void)
-{
-       fr_ldap_init();
-
-       return 0;
-}
-
-static void mod_unload(void)
-{
-       fr_ldap_free();
-}
-
 /* globally exported name */
 extern module_rlm_t rlm_ldap;
 module_rlm_t rlm_ldap = {
@@ -2258,8 +2235,6 @@ module_rlm_t rlm_ldap = {
                .type           = 0,
                .inst_size      = sizeof(rlm_ldap_t),
                .config         = module_config,
-               .onload         = mod_load,
-               .unload         = mod_unload,
                .bootstrap      = mod_bootstrap,
                .instantiate    = mod_instantiate,
                .detach         = mod_detach,
index 1a44f3cf1f2ef56d2f5c46867229f47d25a92be8..3d96db18df86dbfbc3f038e064b15cdf64ce4d3b 100644 (file)
@@ -136,14 +136,6 @@ typedef struct {
        fr_pool_t       *pool;                          //!< Connection pool instance.
        fr_ldap_config_t handle_config;                 //!< Connection configuration instance.
        fr_trunk_conf_t trunk_conf;                     //!< Trunk configuration
-
-       /*
-        *      Global config
-        */
-       char const      *tls_random_file;               //!< Path to the random file if /dev/random and /dev/urandom
-                                                       //!< are unavailable.
-
-       uint32_t        ldap_debug;                     //!< Debug flag for the SDK.
 } rlm_ldap_t;
 
 extern HIDDEN fr_dict_attr_t const *attr_cleartext_password;
diff --git a/src/tests/modules/ldap/global.conf b/src/tests/modules/ldap/global.conf
new file mode 100644 (file)
index 0000000..f3ffdd0
--- /dev/null
@@ -0,0 +1,12 @@
+global {
+       ldap {
+               #  ldap_debug: debug flag for LDAP SDK
+               #  (see OpenLDAP documentation).  Set this to enable
+               #  huge amounts of LDAP debugging on the screen.
+               #  You should only use this if you are an LDAP expert.
+               #
+               #       default: 0x0000 (no debugging messages)
+               #       Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)
+               ldap_debug = 0x0801
+       }
+}
index 20babda37f203312408cecc3aed6df8c2e378075..a15b17671d4125991f2bb550087e9e6e61f555a6 100644 (file)
@@ -53,17 +53,6 @@ ldap {
 #              realm = 'example.org'
        }
 
-       global {
-               #  ldap_debug: debug flag for LDAP SDK
-               #  (see OpenLDAP documentation).  Set this to enable
-               #  huge amounts of LDAP debugging on the screen.
-               #  You should only use this if you are an LDAP expert.
-               #
-               #       default: 0x0000 (no debugging messages)
-               #       Example:(LDAP_DEBUG_FILTER+LDAP_DEBUG_CONNS)
-               ldap_debug = 0x0801
-       }
-
        #
        #  Generic valuepair attribute
        #
index c0bea1417ec0ed41dc3e7693d8b5013a688ad8c2..7edba2b5f4b5d23c7561acc78f258139cef0e16d 100644 (file)
@@ -28,6 +28,8 @@ modules {
        $INCLUDE $ENV{MODULE_TEST_DIR}/module.conf
 }
 
+$-INCLUDE $ENV{MODULE_TEST_DIR}/global.conf
+
 $-INCLUDE $ENV{MODULE_TEST_DIR}/triggers.conf
 
 $-INCLUDE $ENV{MODULE_TEST_DIR}/clients.conf