Browse Source

Ticket 47601 - Plugin library path validation prevents intentional loading of out-of-tree modules

Bug Description:  The fix for ticket 47384 does not allow plugins to have their shared libs stored
                  anywhere else but in the default location.

Fix Description:  Allow plugin paths that are not in the default area if the absolute path has been
                  specified, and the library can be opened.

https://fedorahosted.org/389/ticket/47601

Reviewed by: rmeggins(Thanks!)
Mark Reynolds 12 years ago
parent
commit
d8e8a90fd1
4 changed files with 13 additions and 7 deletions
  1. 2 1
      Makefile.am
  2. 4 2
      Makefile.in
  3. 1 1
      ldap/servers/slapd/dynalib.c
  4. 6 3
      ldap/servers/slapd/fedse.c

+ 2 - 1
Makefile.am

@@ -65,6 +65,7 @@ PCRE_LINK = @pcre_lib@ -lpcre
 NETSNMP_LINK = @netsnmp_lib@ @netsnmp_link@
 PAM_LINK = -lpam
 KERBEROS_LINK = $(kerberos_lib)
+DLOPEN_LINK = -ldl
 
 LIBSOCKET=@LIBSOCKET@
 LIBNSL=@LIBNSL@
@@ -1462,7 +1463,7 @@ ns_slapd_SOURCES = ldap/servers/slapd/abandon.c \
 
 ns_slapd_CPPFLAGS = $(AM_CPPFLAGS) @sasl_inc@ @openldap_inc@ @ldapsdk_inc@ @nss_inc@ \
 	@nspr_inc@ @svrcore_inc@
-ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) \
+ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) $(DLOPEN_LINK) \
 	$(NSPR_LINK) $(SASL_LINK) $(SVRCORE_LINK) $(LIBNSL) $(LIBSOCKET) $(THREADLIB)
 # We need to link ns-slapd with the C++ compiler on HP-UX since we load
 # some C++ shared libraries (such as icu).

+ 4 - 2
Makefile.in

@@ -1063,7 +1063,8 @@ ns_slapd_DEPENDENCIES = libslapd.la libldaputil.a \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am_pwdhash_bin_OBJECTS =  \
 	ldap/servers/slapd/tools/pwdhash_bin-pwenc.$(OBJEXT)
 pwdhash_bin_OBJECTS = $(am_pwdhash_bin_OBJECTS)
@@ -1548,6 +1549,7 @@ PCRE_LINK = @pcre_lib@ -lpcre
 NETSNMP_LINK = @netsnmp_lib@ @netsnmp_link@
 PAM_LINK = -lpam
 KERBEROS_LINK = $(kerberos_lib)
+DLOPEN_LINK = -ldl
 
 #------------------------
 # Generated Sources
@@ -2783,7 +2785,7 @@ ns_slapd_SOURCES = ldap/servers/slapd/abandon.c \
 ns_slapd_CPPFLAGS = $(AM_CPPFLAGS) @sasl_inc@ @openldap_inc@ @ldapsdk_inc@ @nss_inc@ \
 	@nspr_inc@ @svrcore_inc@
 
-ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) \
+ns_slapd_LDADD = libslapd.la libldaputil.a $(LDAPSDK_LINK) $(NSS_LINK) $(DLOPEN_LINK) \
 	$(NSPR_LINK) $(SASL_LINK) $(SVRCORE_LINK) $(LIBNSL) $(LIBSOCKET) $(THREADLIB)
 
 @HPUX_FALSE@ns_slapd_LINK = $(LINK)

+ 1 - 1
ldap/servers/slapd/dynalib.c

@@ -107,7 +107,7 @@ sym_load_with_flags( char *libpath, char *symbol, char *plugin, int report_error
 	}
 
 	if (PR_SUCCESS != PR_Access(libpath, PR_ACCESS_READ_OK)) {
-		if (strncmp(libpath, PLUGINDIR, strlen(PLUGINDIR))) {
+		if (strncmp(libpath, PLUGINDIR, strlen(PLUGINDIR)) && libpath[0] != '/') {
 			libSpec.value.pathname = slapi_get_plugin_name(PLUGINDIR, libpath);
 		} else {
 			libSpec.value.pathname = slapi_get_plugin_name(NULL, libpath);

+ 6 - 3
ldap/servers/slapd/fedse.c

@@ -67,6 +67,7 @@
 #include <errno.h>
 #include <prio.h>
 #include <prcountr.h>
+#include <dlfcn.h>
 #include "slap.h"
 #include "fe.h"
 
@@ -1921,7 +1922,6 @@ check_plugin_path(Slapi_PBlock *pb,
 {
     /* check for invalid nsslapd-pluginPath */
     char **vals = slapi_entry_attr_get_charray (e, ATTR_PLUGIN_PATH);
-    int plugindir_len = sizeof(PLUGINDIR)-1;
     int j = 0;
     int rc = SLAPI_DSE_CALLBACK_OK;
 
@@ -1930,6 +1930,7 @@ check_plugin_path(Slapi_PBlock *pb,
         vals = slapi_entry_attr_get_charray (entryBefore, ATTR_PLUGIN_PATH);
     }
     for (j = 0; vals && vals[j]; j++) {
+        void *handle;
         char *full_path = NULL;
         char *resolved_path = NULL;
         char *res = NULL;
@@ -1942,10 +1943,12 @@ check_plugin_path(Slapi_PBlock *pb,
         resolved_path = slapi_ch_malloc(strlen(full_path) + 1);
         res = realpath( full_path, resolved_path );
         if (res) {
-            if (strncmp(PLUGINDIR, resolved_path, plugindir_len) != 0) {
+            if ((handle = dlopen(res, RTLD_NOW)) == NULL) {
                 *returncode = LDAP_UNWILLING_TO_PERFORM;
-                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Invalid plugin path");
+                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,"Invalid plugin path - failed to open library");
                 rc = SLAPI_DSE_CALLBACK_ERROR;
+            } else {
+                dlclose(handle);
             }
         } else {
             *returncode = LDAP_UNWILLING_TO_PERFORM;