OpenLDAP 2.0.22 Engineering
Fixed slapd passwd modify referral bug
+ Fixed back-ldbm index threading bug
Fixed back-ldbm ordering presense index bug
Fixed back-ldap modify bug (ITS#1547)
Fixed -lldap TLS errno bug
Updated ldaptcl API (contrib)
Updated -lldap SASL/TLS referral handling
Updated -lldap pthread code
+ Updated ldapmodify add/replace handling
Removed -lldap UFN search support
Build environment
Removed extraneous files
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
char *pdn;
Entry *p = NULL;
- int rootlock = 0;
int rc;
ID id = NOID;
const char *text = NULL;
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
-
- /* nobody else can add until we lock our parent */
- ldap_pvt_thread_mutex_lock(&li->li_add_mutex);
+ /* grab giant lock for writing */
+ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
if ( ( rc = dn2id( be, e->e_ndn, &id ) ) || id != NOID ) {
/* if (rc) something bad happened to ldbm cache */
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
send_ldap_result( conn, op,
rc ? LDAP_OPERATIONS_ERROR : LDAP_ALREADY_EXISTS,
NULL, NULL, NULL, NULL );
rc = entry_schema_check( e, NULL, &text, textbuf, textlen );
if ( rc != LDAP_SUCCESS ) {
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE, "entry failed schema check: %s\n",
text, 0, 0 );
char *matched_dn;
struct berval **refs;
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
-
if ( matched != NULL ) {
matched_dn = ch_strdup( matched->e_dn );
refs = is_entry_referral( matched )
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+
Debug( LDAP_DEBUG_TRACE, "parent does not exist\n",
0, 0, 0 );
return -1;
}
- /* don't need the add lock anymore */
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
-
free(pdn);
if ( ! access_allowed( be, conn, op, p,
{
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE, "no write access to parent\n", 0,
0, 0 );
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, "no write access to parent", NULL, NULL );
-
return -1;
}
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE, "parent is alias\n", 0,
0, 0 );
/* free parent and writer lock */
cache_return_entry_w( &li->li_cache, p );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE, "parent is referral\n", 0,
0, 0 );
p = NULL;
if ( ! rc ) {
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE,
"no write access to parent\n",
return -1;
}
} else {
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE, "%s add denied\n",
pdn == NULL ? "suffix"
return -1;
}
}
-
- /*
- * no parent, acquire the root write lock
- * and release the add lock.
- */
- ldap_pvt_thread_mutex_lock(&li->li_root_mutex);
- rootlock = 1;
- ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
}
if ( next_id( be, &e->e_id ) ) {
cache_return_entry_w( &li->li_cache, p );
}
- if ( rootlock ) {
- /* release root lock */
- ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
- }
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_ANY, "ldbm_add: next_id failed\n",
0, 0, 0 );
cache_return_entry_w( &li->li_cache, p );
}
- if ( rootlock ) {
- /* release root lock */
- ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
- }
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_ANY, "cache_add_entry_lock failed\n", 0, 0,
0 );
cache_return_entry_w( &li->li_cache, p );
}
- if ( rootlock ) {
- /* release root lock */
- ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
- }
-
if ( rc ) {
/* in case of error, writer lock is freed
* and entry's private data is destroyed */
cache_return_entry_w( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
}
return( rc );
#define MAXDBCACHE 128
struct ldbminfo {
+ ldap_pvt_thread_rdwr_t li_giant_rwlock;
ID li_nextid;
- ldap_pvt_thread_mutex_t li_nextid_mutex;
- ldap_pvt_thread_mutex_t li_root_mutex;
- ldap_pvt_thread_mutex_t li_add_mutex;
int li_mode;
slap_mask_t li_defaultmask;
char *li_directory;
*edn = NULL;
dn = ndn;
+ /* grab giant lock for reading */
+ ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);
+
/* get entry with reader lock */
if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
char *matched_dn = NULL;
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+
/* allow noauth binds */
rc = 1;
if ( method == LDAP_AUTH_SIMPLE ) {
return_results:;
/* free entry and reader lock */
cache_return_entry_r( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
/* front end with send result on success (rc==0) */
return( rc );
/* LDBM backend specific entry info -- visible only to the cache */
typedef struct ldbm_entry_info {
+#ifdef LDBM_ENTRY_RWLOCK
ldap_pvt_thread_rdwr_t lei_rdwr; /* reader/writer lock */
+#endif
/*
* remaining fields require backend cache lock to access
static void lru_print(Cache *cache);
#endif
+#ifdef LDBM_ENTRY_RWLOCK
static int
cache_entry_rdwr_lock(Entry *e, int rw)
{
{
return ldap_pvt_thread_rdwr_destroy( &LEI(e)->lei_rdwr );
}
+#endif
static int
cache_entry_private_init( Entry*e )
e->e_private = ch_calloc(1, sizeof(struct ldbm_entry_info));
+#ifdef LDBM_ENTRY_RWLOCK
if( cache_entry_rdwr_init( e ) != 0 ) {
free( LEI(e) );
e->e_private = NULL;
return 1;
}
+#endif
return 0;
}
{
assert( e->e_private );
+#ifdef LDBM_ENTRY_RWLOCK
cache_entry_rdwr_destroy( e );
+#endif
free( e->e_private );
e->e_private = NULL;
assert( e->e_private );
+#ifdef LDBM_ENTRY_RWLOCK
cache_entry_rdwr_unlock(e, rw);
+#endif
id = e->e_id;
refcnt = --LEI(e)->lei_refcnt;
return( -1 );
}
+#ifdef LDBM_ENTRY_RWLOCK
cache_entry_rdwr_lock( e, rw );
+#endif
/* put the entry into 'CREATING' state */
/* will be marked after when entry is returned */
goto try_again;
}
+#ifdef LDBM_ENTRY_RWLOCK
/* acquire reader lock */
if ( cache_entry_rdwr_trylock(ep, rw) == LDAP_PVT_THREAD_EBUSY ) {
/* could not acquire entry lock...
ldap_pvt_thread_yield();
goto try_again;
}
+#endif
/* lru */
LRU_DELETE( cache, ep );
int rc;
int manageDSAit = get_manageDSAit( op );
+ /* grab giant lock for reading */
+ ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);
+
/* get entry with reader lock */
if ( (e = dn2entry_r( be, ndn, &matched )) == NULL ) {
char *matched_dn = NULL;
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
return_results:;
cache_return_entry_r( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
return( rc );
}
Entry *matched;
char *pdn = NULL;
Entry *e, *p = NULL;
- int rootlock = 0;
int rc = -1;
int manageDSAit = get_manageDSAit( op );
AttributeDescription *children = slap_schema.si_ad_children;
Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_delete: %s\n", dn, 0, 0);
+ /* grab giant lock for writing */
+ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
+
/* get entry with writer lock */
if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
char *matched_dn = NULL;
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
goto return_results;
}
}
-
- ldap_pvt_thread_mutex_lock(&li->li_root_mutex);
- rootlock = 1;
}
/* delete from dn2id mapping */
cache_return_entry_w( &li->li_cache, p );
}
- if ( rootlock ) {
- /* release root lock */
- ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
- }
-
/* free entry and writer lock */
cache_return_entry_w( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+
return rc;
}
/* free entry and reader or writer lock */
cache_return_entry_rw( &li->li_cache, e, rw );
+ if(rw) {
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+ } else {
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+ }
+
return 0;
}
li->li_dbshutdown = 0;
/* initialize various mutex locks & condition variables */
- ldap_pvt_thread_mutex_init( &li->li_root_mutex );
- ldap_pvt_thread_mutex_init( &li->li_add_mutex );
+ ldap_pvt_thread_rdwr_init( &li->li_giant_rwlock );
ldap_pvt_thread_mutex_init( &li->li_cache.c_mutex );
- ldap_pvt_thread_mutex_init( &li->li_nextid_mutex );
ldap_pvt_thread_mutex_init( &li->li_dbcache_mutex );
ldap_pvt_thread_cond_init( &li->li_dbcache_cv );
free( li->li_directory );
attr_index_destroy( li->li_attrs );
- ldap_pvt_thread_mutex_destroy( &li->li_root_mutex );
- ldap_pvt_thread_mutex_destroy( &li->li_add_mutex );
+ ldap_pvt_thread_rdwr_destroy( &li->li_giant_rwlock );
ldap_pvt_thread_mutex_destroy( &li->li_cache.c_mutex );
- ldap_pvt_thread_mutex_destroy( &li->li_nextid_mutex );
ldap_pvt_thread_mutex_destroy( &li->li_dbcache_mutex );
ldap_pvt_thread_cond_destroy( &li->li_dbcache_cv );
Debug(LDAP_DEBUG_ARGS, "ldbm_back_modify:\n", 0, 0, 0);
+ /* grab giant lock for writing */
+ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
+
/* acquire and lock entry */
if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
char* matched_dn = NULL;
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
NULL, NULL, NULL, NULL );
cache_return_entry_w( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
return( 0 );
error_return:;
cache_return_entry_w( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
return( -1 );
}
(newSuperior ? newSuperior : "NULL"),
0, 0 );
+ /* grab giant lock for writing */
+ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
+
/* get entry with writer lock */
if ( (e = dn2entry_w( be, ndn, &matched )) == NULL ) {
char* matched_dn = NULL;
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+
send_ldap_result( conn, op, LDAP_REFERRAL,
matched_dn, NULL, refs, NULL );
}
}
- ldap_pvt_thread_mutex_lock(&li->li_root_mutex);
- rootlock = 1;
-
Debug( LDAP_DEBUG_TRACE,
"ldbm_back_modrdn: no parent, locked root\n",
0, 0, 0 );
cache_return_entry_w( &li->li_cache, p );
}
- if ( rootlock ) {
- /* release root writer lock */
- ldap_pvt_thread_mutex_unlock(&li->li_root_mutex);
- }
-
/* free entry and writer lock */
cache_return_entry_w( &li->li_cache, e );
if ( rc == MUST_DESTROY ) {
* the entry must be freed */
entry_free( e );
}
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
return( rc );
}
*idp = NOID;
- ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
-
if ( li->li_nextid == NOID ) {
if ( ( rc = next_id_read( be, idp ) ) ) {
- ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
li->li_nextid = *idp;
*idp = li->li_nextid;
- ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
int rc = 0;
- ldap_pvt_thread_mutex_lock( &li->li_nextid_mutex );
-
if ( li->li_nextid == NOID ) {
if ( ( rc = next_id_read( be, idp ) ) ) {
- ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
li->li_nextid = *idp;
rc = -1;
}
- ldap_pvt_thread_mutex_unlock( &li->li_nextid_mutex );
return( rc );
}
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- int rc;
+ int rc, locked=0;
Entry *e = NULL;
struct berval *hash = NULL;
goto done;
}
- e = dn2entry_w( be, dn, NULL );
+ /* grab giant lock for writing */
+ ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
+ e = dn2entry_w( be, dn, NULL );
if( e == NULL ) {
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
*text = "could not locate authorization entry";
rc = LDAP_NO_SUCH_OBJECT;
goto done;
done:
if( e != NULL ) {
cache_return_entry_w( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
}
if( id != NULL ) {
return rc;
}
+ /* grab giant lock for reading */
+ ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);
+
/* get entry with reader lock */
e = dn2entry_r( be, ndn, &matched );
if ( e == NULL ) {
cache_return_entry_r( &li->li_cache, matched );
}
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+
if( refs != NULL ) {
/* send referrals */
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
}
cache_return_entry_r( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+
return rc;
}
Debug(LDAP_DEBUG_TRACE, "=> ldbm_back_search\n", 0, 0, 0);
+ /* grab giant lock for reading */
+ ldap_pvt_thread_rdwr_rlock(&li->li_giant_rwlock);
+
if ( *nbase == '\0' ) {
/* DIT root special case */
static const Entry root = { NOID, "", "", NULL, NULL };
refs = default_referral;
}
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+
send_ldap_result( conn, op, err,
matched_dn, text, refs, NULL );
conn, op, e );
cache_return_entry_r( &li->li_cache, e );
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
Debug( LDAP_DEBUG_TRACE,
"ldbm_search: entry is referral\n",
rc = 0;
done:
+ ldap_pvt_thread_rdwr_runlock(&li->li_giant_rwlock);
+
if( candidates != NULL )
idl_free( candidates );