From: Kurt Zeilenga Date: Fri, 28 Jul 2006 15:01:35 +0000 (+0000) Subject: Patches from Quanah X-Git-Tag: OPENLDAP_REL_ENG_2_3_25~26 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=62c3c31afd73fa44353d1200111904f24f6145e0;p=openldap Patches from Quanah + 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 CHANGES needs work --- diff --git a/CHANGES b/CHANGES index d02a133856..573075ef90 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,21 @@ 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) diff --git a/doc/man/man5/slapo-accesslog.5 b/doc/man/man5/slapo-accesslog.5 index 1c2d6cfe12..8e7b6342cc 100644 --- a/doc/man/man5/slapo-accesslog.5 +++ b/doc/man/man5/slapo-accesslog.5 @@ -26,9 +26,10 @@ directive. .B logdb 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 Specify which types of operations to log. The valid operation types are diff --git a/libraries/liblber/memory.c b/libraries/liblber/memory.c index f45ec52b68..ddd78622f2 100644 --- a/libraries/liblber/memory.c +++ b/libraries/liblber/memory.c @@ -700,8 +700,9 @@ struct berval * 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 ); } diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index 7bf45805c8..2d26d7b18d 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -105,6 +105,7 @@ static void tls_locking_cb( int mode, int type, const char *file, int line ) */ 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 ) { @@ -117,6 +118,7 @@ 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 */ @@ -855,7 +857,13 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg ) 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(); diff --git a/libraries/liblutil/passwd.c b/libraries/liblutil/passwd.c index 03024cb118..a14071da05 100644 --- a/libraries/liblutil/passwd.c +++ b/libraries/liblutil/passwd.c @@ -309,7 +309,7 @@ lutil_passwd( * 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; } diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index 4bff759a9e..cac4c4f6b1 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -146,7 +146,7 @@ bdb_cache_entry_db_unlock ( DB_ENV *env, DB_LOCK *lock ) #else int rc; - if ( !lock ) return 0; + if ( !lock || lock->mode == DB_LOCK_NG ) return 0; rc = LOCK_PUT ( env, lock ); return rc; @@ -556,7 +556,9 @@ bdb_cache_lru_add( 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 ) { @@ -568,7 +570,6 @@ bdb_cache_lru_add( 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. @@ -608,16 +609,12 @@ bdb_cache_lru_add( } 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; } } @@ -1019,6 +1016,10 @@ bdb_cache_modrdn( 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 ); @@ -1029,6 +1030,8 @@ bdb_cache_modrdn( 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) { @@ -1038,7 +1041,15 @@ bdb_cache_modrdn( 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 ); @@ -1046,6 +1057,8 @@ bdb_cache_modrdn( 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 ); diff --git a/servers/slapd/back-bdb/dn2entry.c b/servers/slapd/back-bdb/dn2entry.c index 1814cc22c7..1ba92956ce 100644 --- a/servers/slapd/back-bdb/dn2entry.c +++ b/servers/slapd/back-bdb/dn2entry.c @@ -56,8 +56,11 @@ bdb_dn2entry( 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 ); } diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 7d466b7fb6..06e53d6142 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -2458,6 +2458,8 @@ config_replica(ConfigArgs *c) { 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 ); @@ -2476,11 +2478,28 @@ config_replica(ConfigArgs *c) { 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; } diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index 8c261489e8..7be6f499ad 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -380,8 +380,7 @@ fe_op_bind( Operation *op, SlapReply *rs ) /* * 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 ) { diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c index 9d2e169048..de04c39352 100644 --- a/servers/slapd/ldapsync.c +++ b/servers/slapd/ldapsync.c @@ -38,24 +38,29 @@ slap_compose_sync_cookie( 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 ); } diff --git a/servers/slapd/overlays/accesslog.c b/servers/slapd/overlays/accesslog.c index c0454cf200..3e0295aa75 100644 --- a/servers/slapd/overlays/accesslog.c +++ b/servers/slapd/overlays/accesslog.c @@ -601,6 +601,10 @@ log_cf_gen(ConfigArgs *c) 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] = ' '; @@ -672,6 +676,13 @@ log_cf_gen(ConfigArgs *c) 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 ); @@ -683,11 +694,11 @@ log_cf_gen(ConfigArgs *c) 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; diff --git a/servers/slapd/overlays/auditlog.c b/servers/slapd/overlays/auditlog.c index dd338bbfa7..9d7942b3a2 100644 --- a/servers/slapd/overlays/auditlog.c +++ b/servers/slapd/overlays/auditlog.c @@ -160,7 +160,7 @@ auditlog_db_init( ) { 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 ); diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index 3d2e6227b6..2d140f53b8 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -435,9 +435,11 @@ password_scheme( struct berval *cred, struct berval *sch ) 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; } } @@ -1186,6 +1188,19 @@ ppolicy_add( 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 ) { @@ -1583,7 +1598,23 @@ do_modify: 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. diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index d5712363c8..9fcdc17112 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -797,11 +797,6 @@ do_syncrep2( &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 ); } @@ -813,12 +808,17 @@ do_syncrep2( 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; @@ -919,6 +919,7 @@ do_syncrep2( } slap_sl_free( syncUUIDs, op->o_tmpmemctx ); } + slap_sync_cookie_free( &syncCookie, 0 ); break; default: Debug( LDAP_DEBUG_ANY, @@ -941,15 +942,13 @@ do_syncrep2( &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); } } @@ -3161,8 +3160,14 @@ add_syncrepl( 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 ) );