ldap/admin/src/scripts/DSCreate.pm.in | 1
ldap/servers/plugins/usn/usn.c | 8 --
ldap/servers/slapd/entry.c | 11 ++
ldap/servers/slapd/libglobs.c | 88 +++++++++++++++++++++-
ldap/servers/slapd/mapping_tree.c | 131 +++++++++++++++++++++++++++++++---
ldap/servers/slapd/plugin.c | 2
ldap/servers/slapd/proto-slap.h | 3
ldap/servers/slapd/rdn.c | 12 +++
ldap/servers/slapd/rootdse.c | 8 +-
ldap/servers/slapd/slap.h | 2
ldap/servers/slapd/slapi-plugin.h | 14 +++
11 files changed, 253 insertions(+), 27 deletions(-)
New commits:
commit a8bacbae7878728573fb4b02a2afe24985d8b0ee
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Jan 16 17:29:49 2012 -0800
Trac Ticket 75 - Unconfigure plugin opperations are being called.
https://fedorahosted.org/389/ticket/75
Fix descriptions:
When plugin is not enabled, the start function is not called,
but the initialization is made and the plugins are registered.
This patch calls the initialization/plugin registration only
when the plugin is enabled.
diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c
index b211019..f5579c9 100644
--- a/ldap/servers/plugins/usn/usn.c
+++ b/ldap/servers/plugins/usn/usn.c
@@ -77,18 +77,10 @@ usn_init(Slapi_PBlock *pb)
{
int rc = 0;
void *identity = NULL;
- int enabled = 0;
slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
"--> usn_init\n");
- slapi_pblock_get(pb, SLAPI_PLUGIN_ENABLED, &enabled);
-
- if (!enabled) {
- /* not enabled */
- goto bail;
- }
-
slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &identity);
/* slapi_register_plugin always returns SUCCESS (0) */
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 52b560f..8179352 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -2293,7 +2293,7 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid
*group,
slapi_pblock_set(&pb, SLAPI_PLUGIN_ENABLED, &enabled);
slapi_pblock_set(&pb, SLAPI_PLUGIN_CONFIG_ENTRY, plugin_entry);
- if ((*initfunc)(&pb) != 0)
+ if (enabled && (*initfunc)(&pb) != 0)
{
LDAPDebug(LDAP_DEBUG_ANY, "Init function \"%s\" for
\"%s\" plugin"
" in library \"%s\" failed\n",
commit 50ed1b2498b9441be34be9c68070835787677b07
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Jan 16 17:25:07 2012 -0800
Trac Ticket 26 - Please support setting
defaultNamingContext in the rootdse.
https://fedorahosted.org/389/ticket/26
Fix descriptions:
1) Introducing an attribute defaultNamingContext to rootdse.
2) To support it, a config parameter nsslapd-defaultnamingcontext
is added.
. Suffix created in setup is set to nsslapd-defaultnamingcontext
in createConfigFile (DSCreate.pm).
. If the default naming context is deleted from mapping tree,
the config parameter nsslapd-defaultnamingcontext as well as
the attribute defaultNamingContext in rootdse are removed.
. When nsslapd-defaultnamingcontext does not exist, there are
3 ways to set it.
a) Next added suffix is automatically set.
b) Add nsslapd-defaultnamingcontext value to cn=config
using ldap client.
c) Shutdown the server and add nsslapd-defaultnamingcontext
value to cn=config
. nsslapd-defaultnamingcontext value could be replaced with
other existing suffix with ldap modify operation.
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in
b/ldap/admin/src/scripts/DSCreate.pm.in
index c60ca89..00d290c 100644
--- a/ldap/admin/src/scripts/DSCreate.pm.in
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
@@ -418,6 +418,7 @@ sub createConfigFile {
$ent->setValues("nsslapd-ldapiautodnsuffix",
"cn=peercred,cn=external,cn=auth");
}
}
+ $ent->setValues("nsslapd-defaultNamingContext",
$inf->{slapd}->{Suffix});
if (!$conn->update($ent)) {
$conn->close();
return ("error_enabling_feature", "ldapi",
$conn->getErrorString());
diff --git a/ldap/servers/slapd/entry.c b/ldap/servers/slapd/entry.c
index bf7b4bf..cac7b85 100644
--- a/ldap/servers/slapd/entry.c
+++ b/ldap/servers/slapd/entry.c
@@ -2185,7 +2185,16 @@ slapi_entry_get_rdn_const( const Slapi_Entry *e )
const char *
slapi_entry_get_nrdn_const( const Slapi_Entry *e )
{
- return (slapi_rdn_get_nrdn(slapi_entry_get_srdn((Slapi_Entry *)e)));
+ const char *nrdn =
+ slapi_rdn_get_nrdn(slapi_entry_get_srdn((Slapi_Entry *)e));
+ if (NULL == nrdn) {
+ const char *dn = slapi_entry_get_dn_const(e);
+ if (dn) {
+ slapi_rdn_init_all_dn(&e->e_srdn, dn);
+ nrdn = slapi_rdn_get_nrdn(slapi_entry_get_srdn((Slapi_Entry *)e));
+ }
+ }
+ return nrdn;
}
/*
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index b9beafb..2177934 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -643,12 +643,17 @@ static struct config_get_and_set {
(void**)&global_slapdFrontendConfig.allowed_to_delete_attrs,
CONFIG_STRING, (ConfigGetFunc)config_get_allowed_to_delete_attrs},
{CONFIG_VALIDATE_CERT_ATTRIBUTE, config_set_validate_cert_switch,
- NULL, 0,
- (void**)&global_slapdFrontendConfig.validate_cert,
CONFIG_SPECIAL_VALIDATE_CERT_SWITCH,
- (ConfigGetFunc)config_get_validate_cert_switch},
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.validate_cert,
+ CONFIG_SPECIAL_VALIDATE_CERT_SWITCH,
+ (ConfigGetFunc)config_get_validate_cert_switch},
{CONFIG_PAGEDSIZELIMIT_ATTRIBUTE, config_set_pagedsizelimit,
NULL, 0,
(void**)&global_slapdFrontendConfig.pagedsizelimit, CONFIG_INT, NULL},
+ {CONFIG_DEFAULT_NAMING_CONTEXT, config_set_default_naming_context,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.default_naming_context,
+ CONFIG_STRING, (ConfigGetFunc)config_get_default_naming_context},
#ifdef MEMPOOL_EXPERIMENTAL
,{CONFIG_MEMPOOL_SWITCH_ATTRIBUTE, config_set_mempool_switch,
NULL, 0,
@@ -1031,7 +1036,8 @@ FrontendConfig_init () {
cfg->entryusn_global = LDAP_OFF;
cfg->entryusn_import_init = slapi_ch_strdup("0");
- cfg->allowed_to_delete_attrs = slapi_ch_strdup("nsslapd-listenhost
nsslapd-securelistenhost");
+ cfg->allowed_to_delete_attrs = slapi_ch_strdup("nsslapd-listenhost
nsslapd-securelistenhost nsslapd-defaultnamingcontext");
+ cfg->default_naming_context = NULL; /* store normalized dn */
#ifdef MEMPOOL_EXPERIMENTAL
cfg->mempool_switch = LDAP_ON;
@@ -5801,6 +5807,80 @@ config_set_allowed_to_delete_attrs( const char *attrname, char
*value,
return retVal;
}
+char *
+config_get_default_naming_context(void)
+{
+ char *retVal;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ CFG_LOCK_READ(slapdFrontendConfig);
+ retVal = slapdFrontendConfig->default_naming_context;
+ CFG_UNLOCK_READ(slapdFrontendConfig);
+
+ return retVal;
+}
+
+int
+config_set_default_naming_context(const char *attrname,
+ char *value, char *errorbuf, int apply)
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ void *node;
+ Slapi_DN *sdn;
+ char *suffix = NULL;
+
+ if (value && *value) {
+ int in_init = 0;
+ suffix = slapi_create_dn_string("%s", value);
+ if (NULL == suffix) {
+ if (errorbuf) {
+ PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+ "%s is not a valid suffix.", value);
+ }
+ return LDAP_INVALID_DN_SYNTAX;
+ }
+ sdn = slapi_get_first_suffix(&node, 0);
+ if (NULL == sdn) {
+ in_init = 1; /* at the startup time, no suffix is set yet */
+ }
+ while (sdn) {
+ if (0 == strcasecmp(suffix, slapi_sdn_get_dn(sdn))) {
+ /* matched */
+ break;
+ }
+ sdn = slapi_get_next_suffix(&node, 0);
+ }
+ if (!in_init && (NULL == sdn)) { /* not in startup && no match
*/
+ if (errorbuf) {
+ PR_snprintf (errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+ "%s is not an existing suffix.", value);
+ }
+ slapi_ch_free_string(&suffix);
+ return LDAP_NO_SUCH_OBJECT;
+ }
+ } else {
+ /* reset */
+ suffix = NULL;
+ }
+
+ if (!apply) {
+ return LDAP_SUCCESS;
+ }
+
+ if (errorbuf) {
+ *errorbuf = '\0';
+ }
+
+ if (apply) {
+ CFG_LOCK_WRITE(slapdFrontendConfig);
+ slapi_ch_free_string(&slapdFrontendConfig->default_naming_context);
+ /* normalized suffix*/
+ slapdFrontendConfig->default_naming_context = suffix;
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
+ }
+ return LDAP_SUCCESS;
+}
+
/*
* This function is intended to be used from the dse code modify callback. It
* is "optimized" for that case because it takes a berval** of values, which
is
diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
index 935e34a..3aa3bec 100644
--- a/ldap/servers/slapd/mapping_tree.c
+++ b/ldap/servers/slapd/mapping_tree.c
@@ -155,6 +155,7 @@ static mapping_tree_node * mtn_get_first_node(mapping_tree_node *
node,
int scope);
static mapping_tree_node *
get_mapping_tree_node_by_name(mapping_tree_node * node, char * be_name);
+static int _mtn_update_config_param(int op, char *type, char *strvalue);
#ifdef DEBUG
static void dump_mapping_tree(mapping_tree_node *parent, int depth);
@@ -1419,6 +1420,32 @@ int mapping_tree_entry_add_callback(Slapi_PBlock *pb, Slapi_Entry*
entryBefore,
node->mtn_extension = factory_create_extension(mapping_tree_get_extension_type(),
node, NULL);
+ /*
+ * Check defaultNamingContext is set.
+ * If it is not set, set the to-be-added suffix to the config param.
+ */
+ if (NULL == config_get_default_naming_context()) {
+ char *suffix =
+ slapi_rdn_get_value(slapi_entry_get_nrdn_const(entryBefore));
+ char *escaped = slapi_ch_strdup(suffix);
+ if (suffix && escaped) {
+ strcpy_unescape_value(escaped, suffix);
+ }
+ if (escaped) {
+ int rc = _mtn_update_config_param(LDAP_MOD_REPLACE,
+ CONFIG_DEFAULT_NAMING_CONTEXT,
+ escaped);
+ if (rc) {
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "mapping_tree_entry_add_callback: "
+ "setting %s to %s failed: RC=%d\n",
+ escaped, CONFIG_DEFAULT_NAMING_CONTEXT, rc);
+ }
+ }
+ slapi_ch_free_string(&suffix);
+ slapi_ch_free_string(&escaped);
+ }
+
return SLAPI_DSE_CALLBACK_OK;
}
@@ -1443,7 +1470,7 @@ static void mtn_remove_node(mapping_tree_node * node)
int mapping_tree_entry_delete_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore,
Slapi_Entry* e, int *returncode, char *returntext, void *arg)
{
- int result;
+ int result = SLAPI_DSE_CALLBACK_OK;
mapping_tree_node *node = NULL;
Slapi_DN * subtree;
int i;
@@ -1499,9 +1526,51 @@ int mapping_tree_entry_delete_callback(Slapi_PBlock *pb,
Slapi_Entry* entryBefor
result = SLAPI_DSE_CALLBACK_OK;
removed = 1;
-
+
done:
mtn_unlock();
+
+ /* Remove defaultNamingContext if it is the to-be-deleted suffix.
+ * It should be done outside of mtn lock. */
+ if (SLAPI_DSE_CALLBACK_OK == result) {
+ char *default_naming_context = config_get_default_naming_context();
+ char *suffix, *escaped;
+ if (default_naming_context) {
+ suffix =
+ slapi_rdn_get_value(slapi_entry_get_nrdn_const(entryBefore));
+ escaped = slapi_ch_strdup(suffix);
+ if (suffix && escaped) {
+ strcpy_unescape_value(escaped, suffix);
+ }
+ if (escaped && (0 == strcasecmp(escaped, default_naming_context))) {
+ int rc = _mtn_update_config_param(LDAP_MOD_DELETE,
+ CONFIG_DEFAULT_NAMING_CONTEXT,
+ NULL);
+ if (rc) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "mapping_tree_entry_delete_callback: "
+ "deleting config param %s failed: RC=%d\n",
+ CONFIG_DEFAULT_NAMING_CONTEXT, rc);
+ }
+ if (LDAP_SUCCESS == rc) {
+ char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE];
+ /* Removing defaultNamingContext from cn=config entry
+ * was successful. The remove does not reset the
+ * global parameter. We need to reset it separately. */
+ if (config_set_default_naming_context(
+ CONFIG_DEFAULT_NAMING_CONTEXT,
+ NULL, errorbuf, CONFIG_APPLY)) {
+ LDAPDebug2Args(LDAP_DEBUG_ANY,
+ "mapping_tree_entry_delete_callback: "
+ "setting NULL to %s failed. %s\n",
+ CONFIG_DEFAULT_NAMING_CONTEXT, errorbuf);
+ }
+ }
+ }
+ slapi_ch_free_string(&suffix);
+ slapi_ch_free_string(&escaped);
+ }
+ }
slapi_sdn_free(&subtree);
if (SLAPI_DSE_CALLBACK_OK == result && removed)
{
@@ -2506,11 +2575,11 @@ static int mtn_get_be(mapping_tree_node *target_node, Slapi_PBlock
*pb,
target_sdn = operation_get_target_spec (op);
if (target_node->mtn_state == MTN_DISABLED) {
- if (errorbuf) {
- PR_snprintf(errorbuf, BUFSIZ,
+ if (errorbuf) {
+ PR_snprintf(errorbuf, BUFSIZ,
"Warning: Operation attempted on a disabled node : %s\n",
- slapi_sdn_get_dn(target_node->mtn_subtree));
- }
+ slapi_sdn_get_dn(target_node->mtn_subtree));
+ }
result = LDAP_OPERATIONS_ERROR;
return result;
}
@@ -3047,10 +3116,12 @@ slapi_be_exist(const Slapi_DN *sdn) /* JCM - The name of this
should change??? *
Slapi_DN *
slapi_get_first_suffix(void ** node, int show_private)
{
- mapping_tree_node * first_node = mapping_tree_root->mtn_children;
- if (NULL == node) {
+ mapping_tree_node *first_node;
+
+ if ((NULL == node) || (NULL == mapping_tree_root)) {
return NULL;
}
+ first_node = mapping_tree_root->mtn_children;
*node = (void * ) first_node ;
while (first_node && (first_node->mtn_private && (show_private ==
0)))
first_node = first_node->mtn_brother;
@@ -3060,9 +3131,9 @@ slapi_get_first_suffix(void ** node, int show_private)
Slapi_DN *
slapi_get_next_suffix(void ** node, int show_private)
{
- mapping_tree_node * next_node = NULL;
+ mapping_tree_node *next_node;
- if (NULL == node) {
+ if ((NULL == node) || (NULL == mapping_tree_root)) {
return NULL;
}
next_node = *node;
@@ -3681,3 +3752,43 @@ static void dump_mapping_tree(mapping_tree_node *parent, int
depth)
return;
}
#endif
+
+/* helper function to set/remove the config param in cn=config */
+static int
+_mtn_update_config_param(int op, char *type, char *strvalue)
+{
+ Slapi_PBlock confpb;
+ Slapi_DN sdn;
+ Slapi_Mods smods;
+ LDAPMod **mods;
+ int rc = LDAP_PARAM_ERROR;
+
+ pblock_init (&confpb);
+ slapi_mods_init (&smods, 0);
+ switch (op) {
+ case LDAP_MOD_DELETE:
+ slapi_mods_add(&smods, op, type, 0, NULL);
+ break;
+ case LDAP_MOD_ADD:
+ case LDAP_MOD_REPLACE:
+ slapi_mods_add_string(&smods, op, type, strvalue);
+ break;
+ default:
+ return rc;
+ }
+ slapi_sdn_init_ndn_byref(&sdn, SLAPD_CONFIG_DN);
+ slapi_modify_internal_set_pb_ext(&confpb, &sdn,
+ slapi_mods_get_ldapmods_byref(&smods),
+ NULL, NULL,
+ (void *)plugin_get_default_component_id(), 0);
+ slapi_modify_internal_pb(&confpb);
+ slapi_pblock_get (&confpb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+ slapi_sdn_done(&sdn);
+ /* need to free passed out mods
+ * since the internal modify could realloced mods. */
+ slapi_pblock_get(&confpb, SLAPI_MODIFY_MODS, &mods);
+ ldap_mods_free (mods, 1 /* Free the Array and the Elements */);
+ pblock_done(&confpb);
+
+ return rc;
+}
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 9714871..a3fcc5f 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -377,7 +377,7 @@ int config_set_force_sasl_external(const char *attrname, char *value,
char *erro
int config_set_entryusn_global( const char *attrname, char *value, char *errorbuf, int
apply );
int config_set_allowed_to_delete_attrs( const char *attrname, char *value, char
*errorbuf, int apply );
int config_set_entryusn_import_init( const char *attrname, char *value, char *errorbuf,
int apply );
-
+int config_set_default_naming_context( const char *attrname, char *value, char *errorbuf,
int apply );
#if !defined(_WIN32) && !defined(AIX)
int config_set_maxdescriptors( const char *attrname, char *value, char *errorbuf, int
apply );
@@ -522,6 +522,7 @@ int config_get_force_sasl_external();
int config_get_entryusn_global(void);
char *config_get_allowed_to_delete_attrs(void);
char *config_get_entryusn_import_init(void);
+char *config_get_default_naming_context(void);
int is_abspath(const char *);
char* rel2abspath( char * );
diff --git a/ldap/servers/slapd/rdn.c b/ldap/servers/slapd/rdn.c
index c9f6386..d408f0e 100644
--- a/ldap/servers/slapd/rdn.c
+++ b/ldap/servers/slapd/rdn.c
@@ -1092,3 +1092,15 @@ bail:
return sz;
}
+char *
+slapi_rdn_get_value(const char *rdn)
+{
+ char *p = PL_strchr(rdn, '=');
+ if (p) {
+ p++;
+ while (isspace(*p)) p++;
+ p = slapi_ch_strdup(p);
+ }
+ return p;
+}
+
diff --git a/ldap/servers/slapd/rootdse.c b/ldap/servers/slapd/rootdse.c
index 2368a3d..e9e903d 100644
--- a/ldap/servers/slapd/rootdse.c
+++ b/ldap/servers/slapd/rootdse.c
@@ -161,8 +161,14 @@ read_root_dse( Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*entryAfter, int *r
sdn = slapi_get_next_suffix(&node, 0);
}
+ val.bv_val = config_get_default_naming_context();
+ if (val.bv_val) {
+ val.bv_len = strlen(val.bv_val);
+ attrlist_replace( &e->e_attrs, "defaultnamingcontext", vals );
+ }
+
attrlist_delete( &e->e_attrs, "nsBackendSuffix");
- for (be = slapi_get_first_backend(&cookie); be != NULL;
+ for (be = slapi_get_first_backend(&cookie); be != NULL;
be = slapi_get_next_backend(cookie)) {
char * base;
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 4acf375..b59299c 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -1969,6 +1969,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_ENTRYUSN_GLOBAL "nsslapd-entryusn-global"
#define CONFIG_ENTRYUSN_IMPORT_INITVAL "nsslapd-entryusn-import-initval"
#define CONFIG_ALLOWED_TO_DELETE_ATTRIBUTE "nsslapd-allowed-to-delete-attrs"
+#define CONFIG_DEFAULT_NAMING_CONTEXT "nsslapd-defaultnamingcontext"
#ifdef MEMPOOL_EXPERIMENTAL
#define CONFIG_MEMPOOL_SWITCH_ATTRIBUTE "nsslapd-mempool"
@@ -2191,6 +2192,7 @@ typedef struct _slapdFrontendConfig {
char *allowed_to_delete_attrs;/* list of config attrs allowed to delete */
char *entryusn_import_init; /* Entry USN: determine the initital value of import */
int pagedsizelimit;
+ char *default_naming_context; /* Default naming context (normalized) */
} slapdFrontendConfig_t;
/* possible values for slapdFrontendConfig_t.schemareplace */
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index a92cc5b..2296351 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3279,6 +3279,14 @@ int slapi_rdn_partial_dup(Slapi_RDN *from, Slapi_RDN **to, int
idx);
*/
size_t slapi_rdn_get_size(Slapi_RDN *srdn);
+/**
+ * Return the value of the RDN
+ *
+ * \param rdn A pointer to rdn to get the value.
+ * \return The value of the given RDN.
+ */
+char * slapi_rdn_get_value(const char *rdn);
+
/*
* utility routines for dealing with DNs
*/
@@ -3334,7 +3342,7 @@ int slapi_dn_normalize_case_ext(char *src, size_t src_len, char
**dest, size_t *
*
* \param fmt The format used to generate a DN string.
* \param ... The arguments to generate a DN string.
- * \return A pointer to the generated DN. The
+ * \return A pointer to the generated DN.
* \return NULL if failed.
* \note When a DN needs to be internally created, this function is supposed to be
called. This function allocates the enough memory for the normalized DN and returns it
filled with the normalized DN.
*/
@@ -5466,7 +5474,11 @@ int slapi_is_loglevel_set( const int loglevel );
*/
typedef struct slapi_mutex Slapi_Mutex;
typedef struct slapi_condvar Slapi_CondVar;
+#ifdef USE_POSIX_RWLOCKS
+typedef pthread_rwlock_t Slapi_RWLock;
+#else
typedef struct slapi_rwlock Slapi_RWLock;
+#endif
Slapi_Mutex *slapi_new_mutex( void );
void slapi_destroy_mutex( Slapi_Mutex *mutex );
void slapi_lock_mutex( Slapi_Mutex *mutex );