OpenLDAP 2.3 Change Log
OpenLDAP 2.3.25 Engineering
+ Patch to fix ITS4572
+ Patch to fix ITS4575
+ Patch to fix ITS4576
+ Patch to fix ITS4580
+ Patch to fix ITS4582
+ Patch to fix ITS4583
+ Patch to fix ITS4589
+ Patch to fix ITS4595
+ Patch to fix ITS4616
+ Patch to fix ITS4534/ITS4622
+ Fixes auditlog DB initialization
+ Fix for back-bdb and back-hdb cache job
+ liblber fix
+ Password length bug fix
+ Fixes return code bug
OpenLDAP 2.3.24 Release
Fixed slapd syncrepl timestamp bug (delta-sync/cascade) (ITS#4567)
.B logdb <suffix>
Specify the suffix of a database to be used for storing the log records.
The specified database must have already been configured in a prior section
-of the config file. The suffix entry of the log database will be created
-automatically by this overlay. The log entries will be generated as the
-immediate children of the suffix entry.
+of the config file, and it must have a rootDN configured. The access controls
+on the log database should prevent general write access. The suffix entry
+of the log database will be created automatically by this overlay. The log
+entries will be generated as the immediate children of the suffix entry.
.TP
.B logops <operations>
Specify which types of operations to log. The valid operation types are
ber_bvreplace_x( struct berval *dst, LDAP_CONST struct berval *src, void *ctx )
{
assert( dst != NULL );
+ assert( !BER_BVISNULL( src ) );
- if ( dst->bv_len < src->bv_len ) {
+ if ( BER_BVISNULL( dst ) || dst->bv_len < src->bv_len ) {
dst->bv_val = ber_memrealloc_x( dst->bv_val, src->bv_len + 1, ctx );
}
*/
static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
+static ldap_pvt_thread_mutex_t tls_connect_mutex;
static void tls_init_threads( void )
{
/* FIXME: the thread id should be added somehow... */
ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
+ ldap_pvt_thread_mutex_init( &tls_connect_mutex );
}
#endif /* LDAP_R_COMPILE */
LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
}
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_lock( &tls_connect_mutex );
+#endif
err = SSL_accept( ssl );
+#ifdef LDAP_R_COMPILE
+ ldap_pvt_thread_mutex_unlock( &tls_connect_mutex );
+#endif
#ifdef HAVE_WINSOCK
errno = WSAGetLastError();
* didn't recognize? Assume a scheme name is at least 1 character.
*/
if (( passwd->bv_val[0] == '{' ) &&
- ( strchr( passwd->bv_val, '}' ) > passwd->bv_val+1 ))
+ ( ber_bvchr( passwd, '}' ) > passwd->bv_val+1 ))
{
return 1;
}
#else
int rc;
- if ( !lock ) return 0;
+ if ( !lock || lock->mode == DB_LOCK_NG ) return 0;
rc = LOCK_PUT ( env, lock );
return rc;
lockp = NULL;
}
- ldap_pvt_thread_mutex_lock( &bdb->bi_cache.lru_tail_mutex );
+ /* Don't bother if we can't get the lock */
+ if ( ldap_pvt_thread_mutex_trylock( &bdb->bi_cache.lru_tail_mutex ) )
+ return;
/* Look for an unused entry to remove */
for (elru = bdb->bi_cache.c_lrutail; elru; elru = elprev ) {
if ( bdb_cache_entry_db_lock( bdb->bi_dbenv,
bdb->bi_cache.c_locker, elru, 1, 1, lockp ) == 0 ) {
- int stop = 0;
/* If this node is in the process of linking into the cache,
* or this node is being deleted, skip it.
}
bdb_cache_entry_db_unlock( bdb->bi_dbenv, lockp );
- if ( count == bdb->bi_cache.c_minfree ) {
+ if ( count >= bdb->bi_cache.c_minfree ) {
ldap_pvt_thread_rdwr_wlock( &bdb->bi_cache.c_rwlock );
- bdb->bi_cache.c_cursize -= bdb->bi_cache.c_minfree;
- if ( bdb->bi_cache.c_maxsize - bdb->bi_cache.c_cursize >=
- bdb->bi_cache.c_minfree )
- stop = 1;
- count = 0;
+ bdb->bi_cache.c_cursize -= count;
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
+ break;
}
- if (stop) break;
}
}
avl_delete( &pei->bei_kids, (caddr_t) ei, bdb_rdn_cmp );
free( ei->bei_nrdn.bv_val );
ber_dupbv( &ei->bei_nrdn, nrdn );
+
+ if ( !pei->bei_kids )
+ pei->bei_state |= CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS;
+
#ifdef BDB_HIER
free( ei->bei_rdn.bv_val );
rdn.bv_len = ptr - rdn.bv_val;
}
ber_dupbv( &ei->bei_rdn, &rdn );
+ pei->bei_ckids--;
+ if ( pei->bei_dkids ) pei->bei_dkids--;
#endif
if (!ein) {
bdb_cache_entryinfo_unlock( pei );
bdb_cache_entryinfo_lock( ein );
}
+ /* parent now has kids */
+ if ( ein->bei_state & CACHE_ENTRY_NO_KIDS )
+ ein->bei_state ^= CACHE_ENTRY_NO_KIDS;
#ifdef BDB_HIER
+ /* parent might now have grandkids */
+ if ( ein->bei_state & CACHE_ENTRY_NO_GRANDKIDS &&
+ !(ei->bei_state & (CACHE_ENTRY_NO_KIDS)))
+ ein->bei_state ^= CACHE_ENTRY_NO_GRANDKIDS;
+
{
/* Record the generation number of this change */
ldap_pvt_thread_mutex_lock( &bdb->bi_modrdns_mutex );
ei->bei_modrdns = bdb->bi_modrdns;
ldap_pvt_thread_mutex_unlock( &bdb->bi_modrdns_mutex );
}
+ ein->bei_ckids++;
+ if ( ein->bei_dkids ) ein->bei_dkids++;
#endif
avl_insert( &ein->bei_kids, ei, bdb_rdn_cmp, avl_dup_error );
bdb_cache_entryinfo_unlock( ein );
rc2 = bdb_cache_find_id( op, tid, ei->bei_id,
&ei, 1, locker, lock );
if ( rc2 ) rc = rc2;
- } else if ( ei )
+ } else if ( ei ) {
bdb_cache_entryinfo_unlock( ei );
+ memset( lock, 0, sizeof( *lock ));
+ lock->mode = DB_LOCK_NG;
+ }
} else if ( ei ) {
bdb_cache_entryinfo_unlock( ei );
}
nr = add_replica_info(c->be, replicauri, replicahost);
break;
} else if(!strncasecmp(c->argv[i], "uri=", STRLENOF("uri="))) {
+ ber_len_t len;
+
if ( replicauri ) {
snprintf( c->msg, sizeof( c->msg ), "<%s> replica host/URI already specified", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", c->log, c->msg, replicauri );
Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return(1);
}
+
+ len = strlen(ludp->lud_scheme) + strlen(ludp->lud_host) +
+ STRLENOF("://") + 1;
+ if (ludp->lud_port != LDAP_PORT) {
+ if (ludp->lud_port < 1 || ludp->lud_port > 65535) {
+ ldap_free_urldesc(ludp);
+ snprintf( c->msg, sizeof( c->msg ), "<%s> invalid port",
+ c->argv[0] );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+ return(1);
+ }
+ len += STRLENOF(":65535");
+ }
+ replicauri = ch_malloc( len );
+ replicahost = lutil_strcopy( replicauri, ludp->lud_scheme );
+ replicahost = lutil_strcopy( replicauri, "://" );
+ if (ludp->lud_port == LDAP_PORT) {
+ strcpy( replicahost, ludp->lud_host );
+ } else {
+ sprintf( replicahost, "%s:%d",ludp->lud_host,ludp->lud_port );
+ }
ldap_free_urldesc(ludp);
- replicauri = c->argv[i] + STRLENOF("uri=");
- replicauri = ch_strdup( replicauri );
- replicahost = strchr( replicauri, '/' );
- replicahost += 2;
nr = add_replica_info(c->be, replicauri, replicahost);
break;
}
/*
* We could be serving multiple database backends. Select the
- * appropriate one, or send a referral to our "referral server"
- * if we don't hold it.
+ * appropriate one. If none, return invalid cred, not a referral.
*/
if ( (op->o_bd = select_backend( &op->o_req_ndn, 0, 0 )) == NULL ) {
int rid )
{
char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 20 ];
+ int len;
if ( BER_BVISNULL( csn )) {
if ( rid == -1 ) {
cookiestr[0] = '\0';
+ len = 0;
} else {
- snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
+ len = snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
"rid=%03d", rid );
}
} else {
- if ( rid == -1 ) {
- snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
- "csn=%s", csn->bv_val );
- } else {
- snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 20,
- "csn=%s,rid=%03d", csn->bv_val, rid );
+ char *end = cookiestr + sizeof(cookiestr);
+ char *ptr = lutil_strcopy( cookiestr, "csn=" );
+ len = csn->bv_len;
+ if ( ptr + len >= end )
+ len = end - ptr;
+ ptr = lutil_strncopy( ptr, csn->bv_val, len );
+ if ( rid != -1 && ptr < end - STRLENOF(",rid=xxx") ) {
+ ptr += sprintf( ptr, ",rid=%03d", rid );
}
+ len = ptr - cookiestr;
}
- ber_str2bv_x( cookiestr, strlen(cookiestr), 1, cookie,
+ ber_str2bv_x( cookiestr, len, 1, cookie,
op ? op->o_tmpmemctx : NULL );
}
rc = mask_to_verbs( logops, li->li_ops, &c->rvalue_vals );
break;
case LOG_PURGE:
+ if ( !li->li_age ) {
+ rc = 1;
+ break;
+ }
agebv.bv_val = agebuf;
log_age_unparse( li->li_age, &agebv );
agebv.bv_val[agebv.bv_len] = ' ';
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->value_dn.bv_val );
rc = 1;
+ } else if ( BER_BVISEMPTY( &li->li_db->be_rootdn )) {
+ snprintf( c->msg, sizeof( c->msg ),
+ "<%s> no rootDN was configured for suffix",
+ c->argv[0] );
+ Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
+ c->log, c->msg, c->value_dn.bv_val );
+ rc = 1;
}
ch_free( c->value_dn.bv_val );
ch_free( c->value_ndn.bv_val );
break;
case LOG_PURGE:
li->li_age = log_age_parse( c->argv[1] );
- if ( li->li_age == -1 ) {
+ if ( li->li_age < 1 ) {
rc = 1;
} else {
li->li_cycle = log_age_parse( c->argv[2] );
- if ( li->li_cycle == -1 ) {
+ if ( li->li_cycle < 1 ) {
rc = 1;
} else if ( slapMode & SLAP_SERVER_MODE ) {
struct re_s *re = li->li_task;
)
{
slap_overinst *on = (slap_overinst *)be->bd_info;
- auditlog_data *ad = ch_malloc(sizeof(auditlog_data));
+ auditlog_data *ad = ch_calloc(1, sizeof(auditlog_data));
on->on_bi.bi_private = ad;
ldap_pvt_thread_mutex_init( &ad->ad_mutex );
if (cred->bv_val[e]) {
int rc;
rc = lutil_passwd_scheme( cred->bv_val );
- if (rc && sch) {
- sch->bv_val = cred->bv_val;
- sch->bv_len = e;
+ if (rc) {
+ if (sch) {
+ sch->bv_val = cred->bv_val;
+ sch->bv_len = e;
+ }
return LDAP_SUCCESS;
}
}
return SLAP_CB_CONTINUE;
}
+static int
+ppolicy_mod_cb( Operation *op, SlapReply *rs )
+{
+ slap_callback *sc = op->o_callback;
+ op->o_callback = sc->sc_next;
+ if ( rs->sr_err == LDAP_SUCCESS ) {
+ ch_free( pwcons[op->o_conn->c_conn_idx].dn.bv_val );
+ BER_BVZERO( &pwcons[op->o_conn->c_conn_idx].dn );
+ }
+ op->o_tmpfree( sc, op->o_tmpmemctx );
+ return SLAP_CB_CONTINUE;
+}
+
static int
ppolicy_modify( Operation *op, SlapReply *rs )
{
struct berval timestamp;
char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
time_t now = slap_get_time();
-
+
+ /* If the conn is restricted, set a callback to clear it
+ * if the pwmod succeeds
+ */
+ if (!BER_BVISEMPTY( &pwcons[op->o_conn->c_conn_idx].dn )) {
+ slap_callback *sc = op->o_tmpcalloc( 1, sizeof( slap_callback ),
+ op->o_tmpmemctx );
+ sc->sc_next = op->o_callback;
+ /* Must use sc_response to insure we reset on success, before
+ * the client sees the response. Must use sc_cleanup to insure
+ * that it gets cleaned up if sc_response is not called.
+ */
+ sc->sc_response = ppolicy_mod_cb;
+ sc->sc_cleanup = ppolicy_mod_cb;
+ op->o_callback = sc;
+ }
+
/*
* keep the necessary pwd.. operational attributes
* up to date.
&syncCookie_req.ctxcsn, &syncCookie.ctxcsn,
&text );
}
- if ( !BER_BVISNULL( &syncCookie.ctxcsn ) &&
- match < 0 && err == LDAP_SUCCESS )
- {
- syncrepl_updateCookie( si, op, psub, &syncCookie );
- }
if ( rctrls ) {
ldap_controls_free( rctrls );
}
if ( refreshDeletes == 0 && match < 0 &&
err == LDAP_SUCCESS )
{
- syncrepl_del_nonpresent( op, si, NULL, NULL );
+ syncrepl_del_nonpresent( op, si, NULL, &syncCookie.ctxcsn );
} else {
avl_free( si->si_presentlist, avl_ber_bvfree );
si->si_presentlist = NULL;
}
}
+ if ( !BER_BVISNULL( &syncCookie.ctxcsn ) &&
+ match < 0 && err == LDAP_SUCCESS )
+ {
+ syncrepl_updateCookie( si, op, psub, &syncCookie );
+ }
if ( err == LDAP_SUCCESS
&& si->si_logstate == SYNCLOG_FALLBACK ) {
si->si_logstate = SYNCLOG_LOGGING;
}
slap_sl_free( syncUUIDs, op->o_tmpmemctx );
}
+ slap_sync_cookie_free( &syncCookie, 0 );
break;
default:
Debug( LDAP_DEBUG_ANY,
&syncCookie.ctxcsn, &text );
}
- if ( !BER_BVISNULL( &syncCookie.ctxcsn ) &&
- match < 0 )
- {
- syncrepl_updateCookie( si, op, psub, &syncCookie);
- }
-
- if ( si->si_refreshPresent == 1 ) {
- if ( match < 0 ) {
- syncrepl_del_nonpresent( op, si, NULL, NULL );
+ if ( match < 0 ) {
+ if ( si->si_refreshPresent == 1 ) {
+ syncrepl_del_nonpresent( op, si, NULL, &syncCookie.ctxcsn );
+ }
+ if ( !BER_BVISNULL( &syncCookie.ctxcsn ))
+ {
+ syncrepl_updateCookie( si, op, psub, &syncCookie);
}
}
int rc = 0;
if ( !( c->be->be_search && c->be->be_add && c->be->be_modify && c->be->be_delete ) ) {
- Debug( LDAP_DEBUG_ANY, "%s: database %s does not support operations "
- "required for syncrepl\n", c->log, c->be->be_type, 0 );
+ snprintf( c->msg, sizeof(c->msg), "database %s does not support "
+ "operations required for syncrepl", c->be->be_type );
+ Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
+ return 1;
+ }
+ if ( BER_BVISEMPTY( &c->be->be_rootdn )) {
+ strcpy( c->msg, "rootDN must be defined before syncrepl may be used" );
+ Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return 1;
}
si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );