diff options
author | Rich Megginson <rmeggins@redhat.com> | 2005-01-25 22:38:13 +0000 |
---|---|---|
committer | Rich Megginson <rmeggins@redhat.com> | 2005-01-25 22:38:13 +0000 |
commit | e64a91376288adece5d9578a93ede1bc15db1b5d (patch) | |
tree | 3d693bb559c91e2e1c606064e4b9504000126a53 | |
parent | 9c26d438cf54749a9803ca8d9305e4a085dd2f75 (diff) | |
download | ds-e64a91376288adece5d9578a93ede1bc15db1b5d.tar.gz ds-e64a91376288adece5d9578a93ede1bc15db1b5d.tar.xz ds-e64a91376288adece5d9578a93ede1bc15db1b5d.zip |
Bug(s) fixed: 145179
Bug Description: The auth specific PAM libraries do not have a run time
dependency on libpam, but they do use symbols
in libpam - they expect the executable has already loaded libpam and
made its symbols visible to all other
dynamically loaded libraries. This breaks with DS when loading the PAM
plugin since we just use the default
dlopen arguments, which make the symbols private. We need a way to tell
the plugin loader to treat certain
plugins differently without changing the behavior for all plugins.
Reviewed by: dboreham, nkinder (Thanks!)
Fix Description: Added two new plugin configuration options:
nsslapd-pluginLoadNow and nsslapd-pluginLoadGlobal. These are boolean
valued and false by default (also false if absent). LoadNow causes all
symbols in the plugin and all of its dependents to be loaded
immediately, as opposed to load lazy which only loads the symbol when
used the first time (we probably don't ever want to do this, but it's
there if we need it). LoadGlobal makes all loaded symbols visible to
the executable and all other dynamically loaded libraries, which solves
the PAM problem.
Platforms tested: RHEL3
Flag Day: no
Doc impact: Yes. Need to document the two new plugin config attributes
and their behavior, and document slapi_entry_get_bool().
QA impact: should be covered by regular nightly and manual testing
New Tests integrated into TET: none
-rw-r--r-- | ldap/servers/slapd/dynalib.c | 20 | ||||
-rw-r--r-- | ldap/servers/slapd/entry.c | 30 | ||||
-rw-r--r-- | ldap/servers/slapd/plugin.c | 12 | ||||
-rw-r--r-- | ldap/servers/slapd/proto-slap.h | 8 | ||||
-rw-r--r-- | ldap/servers/slapd/slap.h | 2 | ||||
-rw-r--r-- | ldap/servers/slapd/slapi-plugin.h | 2 |
6 files changed, 70 insertions, 4 deletions
diff --git a/ldap/servers/slapd/dynalib.c b/ldap/servers/slapd/dynalib.c index 4839a17b..aeb12a1f 100644 --- a/ldap/servers/slapd/dynalib.c +++ b/ldap/servers/slapd/dynalib.c @@ -24,8 +24,19 @@ static void symload_report_error( char *libpath, char *symbol, char *plugin, void * sym_load( char *libpath, char *symbol, char *plugin, int report_errors ) { + return sym_load_with_flags(libpath, symbol, plugin, report_errors, PR_FALSE, PR_FALSE); +} + +void * +sym_load_with_flags( char *libpath, char *symbol, char *plugin, int report_errors, PRBool load_now, PRBool load_global ) +{ int i; void *handle; + PRLibSpec libSpec; + unsigned int flags = PR_LD_LAZY; /* default PR_LoadLibrary flag */ + + libSpec.type = PR_LibSpec_Pathname; + libSpec.value.pathname = libpath; for ( i = 0; libs != NULL && libs[i] != NULL; i++ ) { if ( strcasecmp( libs[i]->dl_name, libpath ) == 0 ) { @@ -37,7 +48,14 @@ sym_load( char *libpath, char *symbol, char *plugin, int report_errors ) } } - if ( (handle = PR_LoadLibrary( libpath )) == NULL ) { + if (load_now) { + flags = PR_LD_NOW; + } + if (load_global) { + flags |= PR_LD_GLOBAL; + } + + if ( (handle = PR_LoadLibraryWithFlags( libSpec, flags )) == NULL ) { if ( report_errors ) { symload_report_error( libpath, symbol, plugin, 0 /* lib not open */ ); } diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c index 0d315053..dc232db2 100644 --- a/ldap/servers/slapd/entry.c +++ b/ldap/servers/slapd/entry.c @@ -2180,6 +2180,36 @@ slapi_entry_attr_get_ulong( const Slapi_Entry* e, const char *type) return r; } +PRBool +slapi_entry_attr_get_bool( const Slapi_Entry* e, const char *type) +{ + PRBool r = PR_FALSE; /* default if no attr */ + Slapi_Attr* attr; + slapi_entry_attr_find(e, type, &attr); + if (attr!=NULL) + { + Slapi_Value *v; + const struct berval *bvp; + + slapi_valueset_first_value( &attr->a_present_values, &v); + bvp = slapi_value_get_berval(v); + if ((bvp == NULL) || (bvp->bv_len == 0)) { /* none or empty == false */ + r = PR_FALSE; + } else if (!PL_strncasecmp(bvp->bv_val, "true", bvp->bv_len)) { + r = PR_TRUE; + } else if (!PL_strncasecmp(bvp->bv_val, "false", bvp->bv_len)) { + r = PR_FALSE; + } else if (!PL_strncasecmp(bvp->bv_val, "yes", bvp->bv_len)) { + r = PR_TRUE; + } else if (!PL_strncasecmp(bvp->bv_val, "no", bvp->bv_len)) { + r = PR_FALSE; + } else { /* assume numeric: 0 - false: non-zero - true */ + r = (PRBool)slapi_value_get_ulong(v); + } + } + return r; +} + void slapi_entry_attr_set_charptr( Slapi_Entry* e, const char *type, const char *value) { diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index 5477f3e2..825fb21b 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -2064,6 +2064,9 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group, if (!initfunc) { + PRBool loadNow = PR_FALSE; + PRBool loadGlobal = PR_FALSE; + if (!(value = slapi_entry_attr_get_charptr(plugin_entry, ATTR_PLUGIN_PATH))) { @@ -2079,12 +2082,15 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group, plugin->plg_libpath = value; /* plugin owns value's memory now, don't free */ } + loadNow = slapi_entry_attr_get_bool(plugin_entry, ATTR_PLUGIN_LOAD_NOW); + loadGlobal = slapi_entry_attr_get_bool(plugin_entry, ATTR_PLUGIN_LOAD_GLOBAL); + /* * load the plugin's init function */ - if ((initfunc = (slapi_plugin_init_fnptr)sym_load(plugin->plg_libpath, - plugin->plg_initfunc, plugin->plg_name, 1 /* report errors */ - )) == NULL) + if ((initfunc = (slapi_plugin_init_fnptr)sym_load_with_flags(plugin->plg_libpath, + plugin->plg_initfunc, plugin->plg_name, 1 /* report errors */, + loadNow, loadGlobal)) == NULL) { status = -1; goto PLUGIN_CLEANUP; diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h index 06d718eb..96a60a01 100644 --- a/ldap/servers/slapd/proto-slap.h +++ b/ldap/servers/slapd/proto-slap.h @@ -406,6 +406,14 @@ int hexchar2int( char c ); * dynalib.c */ void *sym_load( char *libpath, char *symbol, char *plugin, int report_errors ); +/* same as above but + * load_now - use PR_LD_NOW so that all referenced symbols are loaded immediately + * default is PR_LD_LAZY which only loads symbols as they are referenced + * load_global - use PR_LD_GLOBAL so that all loaded symbols are made available globally + * to all other dynamically loaded libraries - default is PR_LD_LOCAL + * which only makes symbols visible to the executable + */ +void *sym_load_with_flags( char *libpath, char *symbol, char *plugin, int report_errors, PRBool load_now, PRBool load_global ); /* diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index ad1ccdda..28663b6d 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -632,6 +632,8 @@ struct matchingRuleList { #define ATTR_PLUGIN_TARGET_SUBTREE "nsslapd-targetSubtree" #define ATTR_PLUGIN_BIND_SUBTREE "nsslapd-bindSubtree" #define ATTR_PLUGIN_INVOKE_FOR_REPLOP "nsslapd-invokeForReplOp" +#define ATTR_PLUGIN_LOAD_NOW "nsslapd-pluginLoadNow" +#define ATTR_PLUGIN_LOAD_GLOBAL "nsslapd-pluginLoadGlobal" /* plugin action states */ enum diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index 52c437aa..c7263b4d 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -13,6 +13,7 @@ extern "C" { #endif +#include "prtypes.h" #include "ldap.h" /* @@ -211,6 +212,7 @@ int slapi_entry_attr_get_int(const Slapi_Entry* e, const char *type); unsigned int slapi_entry_attr_get_uint(const Slapi_Entry* e, const char *type); long slapi_entry_attr_get_long( const Slapi_Entry* e, const char *type); unsigned long slapi_entry_attr_get_ulong( const Slapi_Entry* e, const char *type); +PRBool slapi_entry_attr_get_bool( const Slapi_Entry* e, const char *type); void slapi_entry_attr_set_charptr(Slapi_Entry* e, const char *type, const char *value); void slapi_entry_attr_set_int( Slapi_Entry* e, const char *type, int l); void slapi_entry_attr_set_uint( Slapi_Entry* e, const char *type, unsigned int l); |