]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Add function for set global library directory
authorJorge Pereira <jpereiran@gmail.com>
Wed, 11 Jan 2023 22:37:24 +0000 (19:37 -0300)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 13 Jan 2023 23:24:15 +0000 (17:24 -0600)
src/lib/util/dl.c
src/lib/util/dl.h

index 5a94f826e0566f26b916e95150a943b6e54bd454..890f80d787e7ca44397669b1f811b8b2621dda86 100644 (file)
@@ -27,6 +27,7 @@ RCSID("$Id$")
 
 #include <freeradius-devel/server/dl_module.h>
 #include <freeradius-devel/server/log.h>
+#include <freeradius-devel/util/atexit.h>
 #include <freeradius-devel/util/debug.h>
 
 #include <freeradius-devel/util/paths.h>
@@ -111,6 +112,12 @@ struct dl_loader_s {
        bool                    defer_symbol_init;      //!< Do not call dl_symbol_init in dl_loader_init.
 };
 
+/**
+ *
+ * Global library directory set.
+ */
+static char *dl_global_libdir = NULL;
+
 static int8_t dl_symbol_init_cmp(void const *one, void const *two)
 {
        dl_symbol_init_t const *a = one, *b = two;
@@ -713,19 +720,55 @@ finish:
 char const *dl_search_path(dl_loader_t *dl_loader)
 {
        char            *env;
-       char const      *search_path;
+       fr_sbuff_t      *search_path = NULL;
+
+       /*
+        * The search path in this order [env:][global:]dl_loader->lib_dir
+        */
 
        /*
-        *      Apple removed support for DYLD_LIBRARY_PATH in rootless mode.
+        *      Create a thread-local extensible buffer to
+        *      store library search_path data.
+        *
+        *      This is created once per-thread (the first time
+        *      this function is called), and freed when the
+        *      thread exits.
+        */
+       FR_SBUFF_TALLOC_THREAD_LOCAL(&search_path, 16, PATH_MAX);
+
+       /*
+        * Apple removed support for DYLD_LIBRARY_PATH in rootless mode.
         */
        env = getenv("FR_LIBRARY_PATH");
-       if (env) {
-               search_path = env;
-       } else {
-               search_path = dl_loader->lib_dir;
+       if (env && fr_sbuff_in_sprintf(search_path, "%s:", env) < 0) return NULL;
+
+       if (dl_global_libdir && fr_sbuff_in_sprintf(search_path, "%s:", dl_global_libdir) < 0) return NULL;
+
+       if (fr_sbuff_in_strcpy(search_path, dl_loader->lib_dir) < 0) return NULL;
+
+       return fr_sbuff_start(search_path);
+}
+
+/** Set the global library path
+ *
+ * @param[in] lib_dir          ":" separated list of paths to search for libraries in.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int dl_search_global_path_set(char const *lib_dir)
+{
+       if (dl_global_libdir) TALLOC_FREE(dl_global_libdir);
+
+       dl_global_libdir = talloc_typed_strdup(NULL, lib_dir);
+       if (!dl_global_libdir) {
+               fr_strerror_const("Failed allocating memory for global dl search path");
+               return -1;
        }
 
-       return search_path;
+       fr_atexit_global_once(NULL, fr_atexit_talloc_free, dl_global_libdir);
+
+       return 0;
 }
 
 /** Set the current library path
index fdf74f3e355d2264d3a35364c01deb6f422beb71..7ab8dc5798d5af68d350a761ceea9882bcd3e355 100644 (file)
@@ -115,6 +115,8 @@ int                 dl_free(dl_t const *dl);
 
 char const             *dl_search_path(dl_loader_t *dl_loader) CC_HINT(nonnull);
 
+int                     dl_search_global_path_set(char const *lib_dir) CC_HINT(nonnull);
+
 int                    dl_search_path_set(dl_loader_t *dl_loader, char const *lib_dir) CC_HINT(nonnull);
 
 int                    dl_search_path_prepend(dl_loader_t *dl_loader, char const *lib_dir) CC_HINT(nonnull);