From e92c6c92c5d69d2dc2a3eede2a00431b940e7bc2 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Mon, 10 Oct 2005 19:35:25 +0000 Subject: [PATCH] Sync with HEAD Ready for release? --- CHANGES | 10 ++++ build/version.var | 2 +- include/ldap.h | 2 +- libraries/libldap/error.c | 48 ++-------------- libraries/libldap/ldap-int.h | 1 + libraries/libldap/request.c | 95 ++++++++++++++++++++++++++++---- libraries/libldap/result.c | 91 ++++++++---------------------- libraries/libldap/tls.c | 10 ++-- servers/slapd/back-meta/config.c | 82 +++++++++++++++++++++++---- servers/slapd/back-meta/conn.c | 2 +- servers/slapd/bconfig.c | 9 +++ servers/slapd/daemon.c | 7 +++ servers/slapd/extended.c | 3 - servers/slapd/main.c | 11 ++-- servers/slapd/overlays/rwmconf.c | 44 ++++++++++++--- servers/slurpd/main.c | 18 ++++-- 16 files changed, 277 insertions(+), 158 deletions(-) diff --git a/CHANGES b/CHANGES index dd0a01c85a..c020c3bef5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,15 @@ OpenLDAP 2.3 Change Log +OpenLDAP 2.3.10 Engineering + Fixed libldap ndelay without timeout + Fixed libldap chasing of chased referrals (ITS#2942) + Added libldap LDAP_NO_SUPPORT for TLS (ITS#4072) + Added libldap LDAP_MSG_RECEIVED support + Dropped libldap LDAP_MORE_RESULTS_TO_RETURN use + Fixed slapd cn=config undated rootdn issue (ITS#4035) + Fixed slapd-meta bus error (ITS#4073) + Fixed slapd-meta/ldap/rwm empty naming context issue (ITS#4071) + OpenLDAP 2.3.9 Release Fixed slapd req_pwdexop bug Fixed slapo-syncprov queued UUIDs bug (ITS#4068) diff --git a/build/version.var b/build/version.var index 37283f1cc3..cdf9c127c7 100644 --- a/build/version.var +++ b/build/version.var @@ -15,7 +15,7 @@ ol_package=OpenLDAP ol_major=2 ol_minor=3 -ol_patch=9 +ol_patch=X ol_api_inc=20309 ol_api_current=1 ol_api_revision=4 diff --git a/include/ldap.h b/include/ldap.h index 05eb052df4..201db1e836 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -610,7 +610,7 @@ typedef struct ldapcontrol { #define LDAP_NOT_SUPPORTED (-12) #define LDAP_CONTROL_NOT_FOUND (-13) #define LDAP_NO_RESULTS_RETURNED (-14) -#define LDAP_MORE_RESULTS_TO_RETURN (-15) +#define LDAP_MORE_RESULTS_TO_RETURN (-15) /* Obsolete */ #define LDAP_CLIENT_LOOP (-16) #define LDAP_REFERRAL_LIMIT_EXCEEDED (-17) diff --git a/libraries/libldap/error.c b/libraries/libldap/error.c index 3cb13f70e7..db26ae97ce 100644 --- a/libraries/libldap/error.c +++ b/libraries/libldap/error.c @@ -273,26 +273,12 @@ ldap_parse_result( #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex ); #endif - /* Find the next result... */ - if ( r->lm_chain == NULL ) { - if ((r->lm_msgtype == LDAP_RES_SEARCH_ENTRY) || - (r->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) || - (r->lm_msgtype == LDAP_RES_INTERMEDIATE)) { - lm = NULL; - } else { - lm = r; - } - } else { - if ((r->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_SEARCH_ENTRY) || - (r->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_SEARCH_REFERENCE) || - (r->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_INTERMEDIATE)) { - lm = NULL; - } else { - lm = r->lm_chain_tail->lm_chain; - } + /* Find the result, last msg in chain... */ + lm = r->lm_chain_tail; + if ((lm->lm_msgtype == LDAP_RES_SEARCH_ENTRY) || + (lm->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) || + (lm->lm_msgtype == LDAP_RES_INTERMEDIATE)) { + lm = NULL; } if( lm == NULL ) { @@ -396,28 +382,6 @@ ldap_parse_result( if( referralsp != NULL) { *referralsp = ldap_value_dup( ld->ld_referrals ); } - - /* Find the next result... */ - lm = lm->lm_chain; - if ( lm ) { - if ( lm->lm_chain == NULL ) { - if ((lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY) && - (lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE) && - (lm->lm_msgtype != LDAP_RES_INTERMEDIATE)) { - /* more results to return */ - errcode = LDAP_MORE_RESULTS_TO_RETURN; - } - } else { - if ((lm->lm_chain_tail->lm_chain->lm_msgtype - != LDAP_RES_SEARCH_ENTRY) && - (lm->lm_chain_tail->lm_chain->lm_msgtype - != LDAP_RES_SEARCH_REFERENCE) && - (lm->lm_chain_tail->lm_chain->lm_msgtype - != LDAP_RES_INTERMEDIATE)) { - errcode = LDAP_MORE_RESULTS_TO_RETURN; - } - } - } } if ( freeit ) { diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 11100f21f7..d50da9370d 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -256,6 +256,7 @@ typedef struct ldapreq { char *lr_res_matched;/* result matched DN string */ BerElement *lr_ber; /* ber encoded request contents */ LDAPConn *lr_conn; /* connection used to send request */ + struct berval lr_dn; /* DN of request, in lr_ber */ struct ldapreq *lr_parent; /* request that spawned this referral */ struct ldapreq *lr_child; /* first child request */ struct ldapreq *lr_refnext; /* next referral spawned */ diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 02515ff880..184d37d7a3 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -271,6 +271,31 @@ ldap_send_server_request( lr->lr_origid = lr->lr_msgid; } + /* Extract requestDN for future reference */ + { + BerElement tmpber = *ber; + ber_int_t bint; + ber_tag_t tag, rtag; + + ber_reset( &tmpber, 1 ); + rtag = ber_scanf( &tmpber, "{it", /*}*/ &bint, &tag ); + switch ( tag ) { + case LDAP_REQ_BIND: + rtag = ber_scanf( &tmpber, "{i" /*}*/, &bint ); + break; + case LDAP_REQ_DELETE: + break; + default: + rtag = ber_scanf( &tmpber, "{" /*}*/ ); + case LDAP_REQ_ABANDON: + break; + } + if ( tag != LDAP_REQ_ABANDON ) { + ber_skip_tag( &tmpber, &lr->lr_dn.bv_len ); + lr->lr_dn.bv_val = tmpber.ber_ptr; + } + } + lr->lr_prev = NULL; if (( lr->lr_next = ld->ld_requests ) != NULL ) { lr->lr_next->lr_prev = lr; @@ -820,6 +845,33 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * /* check connection for re-bind in progress */ if (( lc = find_connection( ld, srv, 1 )) != NULL ) { + /* See if we've already requested this DN with this conn */ + LDAPRequest *lp; + int looped = 0; + int len = srv->lud_dn ? strlen( srv->lud_dn ) : 0; + for (lp = origreq; lp; ) { + if ( lp->lr_conn == lc ) { + if ( len == lp->lr_dn.bv_len ) { + if ( len && strncmp( srv->lud_dn, lp->lr_dn.bv_val, + len )) + continue; + looped = 1; + break; + } + } + if ( lp == origreq ) + lp = lp->lr_child; + else + lp = lr->lr_refnext; + } + if ( looped ) { + ldap_free_urllist( srv ); + srv = NULL; + ld->ld_errno = LDAP_CLIENT_LOOP; + rc = -1; + continue; + } + if( lc->lconn_rebind_inprogress) { /* We are already chasing a referral or search reference and a * bind on that connection is in progress. We must queue @@ -904,7 +956,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); #endif rc = ldap_send_server_request( ld, ber, id, - origreq, srv, NULL, &rinfo ); + origreq, srv, NULL, &rinfo ); #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); #endif @@ -915,6 +967,7 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * unfollowedcnt += ldap_append_referral( ld, &unfollowed, refarray[i] ); ldap_free_urllist( srv ); srv = NULL; + ld->ld_errno = LDAP_REFERRAL; } else { /* Success, no need to try this referral list further */ rc = 0; @@ -965,7 +1018,6 @@ done: LDAP_FREE( unfollowed ); return count; } else { - ld->ld_errno = LDAP_REFERRAL; *errstrp = unfollowed; return rc; } @@ -988,6 +1040,7 @@ ldap_chase_referrals( LDAP *ld, LDAPURLDesc *srv; BerElement *ber; LDAPreqinfo rinfo; + LDAPConn *lc; Debug( LDAP_DEBUG_TRACE, "ldap_chase_referrals\n", 0, 0, 0 ); @@ -1055,6 +1108,30 @@ ldap_chase_referrals( LDAP *ld, *hadrefp = 1; + /* See if we've already been here */ + if (( lc = find_connection( ld, srv, 1 )) != NULL ) { + LDAPRequest *lp; + int looped = 0; + int len = srv->lud_dn ? strlen( srv->lud_dn ) : 0; + for (lp = lr; lp; lp = lp->lr_parent ) { + if ( lp->lr_conn == lc ) { + if ( len == lp->lr_dn.bv_len ) { + if ( len && strncmp( srv->lud_dn, lp->lr_dn.bv_val, + len )) + continue; + looped = 1; + break; + } + } + } + if ( looped ) { + ldap_free_urllist(srv); + ld->ld_errno = LDAP_CLIENT_LOOP; + rc = -1; + continue; + } + } + LDAP_NEXT_MSGID( ld, id ); ber = re_encode_request( ld, origreq->lr_ber, id, sref, srv, &rinfo.ri_request ); @@ -1148,7 +1225,7 @@ re_encode_request( LDAP *ld, ber_int_t scope; int rc; BerElement tmpber, *ber; - char *orig_dn; + struct berval orig_dn; char *dn; Debug( LDAP_DEBUG_TRACE, @@ -1174,15 +1251,15 @@ re_encode_request( LDAP *ld, assert( tag != 0); if ( tag == LDAP_REQ_BIND ) { /* bind requests have a version number before the DN & other stuff */ - rtag = ber_scanf( &tmpber, "{ia" /*}*/, &ver, &orig_dn ); + rtag = ber_scanf( &tmpber, "{im" /*}*/, &ver, &orig_dn ); } else if ( tag == LDAP_REQ_DELETE ) { /* delete requests don't have a DN wrapping sequence */ - rtag = ber_scanf( &tmpber, "a", &orig_dn ); + rtag = ber_scanf( &tmpber, "m", &orig_dn ); } else if ( tag == LDAP_REQ_SEARCH ) { /* search requests need to be re-scope-ed */ - rtag = ber_scanf( &tmpber, "{ae" /*"}"*/, &orig_dn, &scope ); + rtag = ber_scanf( &tmpber, "{me" /*"}"*/, &orig_dn, &scope ); if( srv->lud_scope != LDAP_SCOPE_DEFAULT ) { /* use the scope provided in reference */ @@ -1211,7 +1288,7 @@ re_encode_request( LDAP *ld, } } else { - rtag = ber_scanf( &tmpber, "{a" /*}*/, &orig_dn ); + rtag = ber_scanf( &tmpber, "{m" /*}*/, &orig_dn ); } if( rtag == LBER_ERROR ) { @@ -1224,7 +1301,7 @@ re_encode_request( LDAP *ld, } if ( srv->lud_dn == NULL ) { - dn = orig_dn; + dn = orig_dn.bv_val; } else { dn = srv->lud_dn; } @@ -1239,8 +1316,6 @@ re_encode_request( LDAP *ld, rc = ber_printf( ber, "{it{s" /*}}*/, msgid, tag, dn ); } - LDAP_FREE( orig_dn ); - if ( rc == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index 6891e6f915..fa36b83651 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -137,7 +137,7 @@ chkResponseList( int msgid, int all) { - LDAPMessage *lm, *lastlm, *nextlm; + LDAPMessage *lm, **lastlm, *nextlm; /* * Look through the list of responses we have received on * this association and see if the response we're interested in @@ -148,7 +148,7 @@ chkResponseList( Debug( LDAP_DEBUG_TRACE, "ldap_chkResponseList for msgid=%d, all=%d\n", msgid, all, 0 ); - lastlm = NULL; + lastlm = &ld->ld_responses; for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) { nextlm = lm->lm_next; @@ -158,12 +158,8 @@ chkResponseList( msgid, 0, 0 ); ldap_mark_abandoned( ld, lm->lm_msgid ); - if ( lastlm == NULL ) { - /* Remove first entry in list */ - ld->ld_responses = lm->lm_next; - } else { - lastlm->lm_next = nextlm; - } + /* Remove this entry from list */ + *lastlm = nextlm; ldap_msgfree( lm ); @@ -173,32 +169,16 @@ chkResponseList( if ( msgid == LDAP_RES_ANY || lm->lm_msgid == msgid ) { LDAPMessage *tmp; - if ( all == LDAP_MSG_ONE || msgid == LDAP_RES_UNSOLICITED ) { + if ( all == LDAP_MSG_ONE || all == LDAP_MSG_RECEIVED || + msgid == LDAP_RES_UNSOLICITED ) { break; } - if ( lm->lm_chain == NULL ) { - assert(lm->lm_chain_tail == lm); - if ((lm->lm_msgtype == LDAP_RES_SEARCH_ENTRY) || - (lm->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) || - (lm->lm_msgtype == LDAP_RES_INTERMEDIATE)) { - tmp = NULL; - } else { - tmp = lm; - } - } else { - assert(lm->lm_chain_tail != NULL); - assert(lm->lm_chain_tail->lm_chain != NULL); - if ((lm->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_SEARCH_ENTRY) || - (lm->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_SEARCH_REFERENCE) || - (lm->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_INTERMEDIATE)) { - tmp = NULL; - } else { - tmp = lm->lm_chain_tail->lm_chain; - } + tmp = lm->lm_chain_tail; + if ((tmp->lm_msgtype == LDAP_RES_SEARCH_ENTRY) || + (tmp->lm_msgtype == LDAP_RES_SEARCH_REFERENCE) || + (tmp->lm_msgtype == LDAP_RES_INTERMEDIATE)) { + tmp = NULL; } if ( tmp == NULL ) { @@ -207,25 +187,20 @@ chkResponseList( break; } - lastlm = lm; + lastlm = &lm->lm_next; } if ( lm != NULL ) { /* Found an entry, remove it from the list */ - if ( lastlm == NULL ) { - ld->ld_responses = (all == LDAP_MSG_ONE && lm->lm_chain != NULL - ? lm->lm_chain : lm->lm_next); - } else { - lastlm->lm_next = (all == LDAP_MSG_ONE && lm->lm_chain != NULL - ? lm->lm_chain : lm->lm_next); - } if ( all == LDAP_MSG_ONE && lm->lm_chain != NULL ) { + *lastlm = lm->lm_chain; lm->lm_chain->lm_next = lm->lm_next; lm->lm_chain->lm_chain_tail = ( lm->lm_chain_tail != lm ) ? lm->lm_chain_tail : lm->lm_chain; - assert(lm->lm_chain->lm_chain_tail != NULL); lm->lm_chain = NULL; lm->lm_chain_tail = NULL; - } + } else { + *lastlm = lm->lm_next; + } lm->lm_next = NULL; } @@ -403,7 +378,7 @@ try_read1msg( #ifdef LDAP_CONNECTIONLESS LDAPMessage *tmp = NULL, *chain_head = NULL; - int firstmsg = 1, moremsgs = 0, isv2 = 0; + int moremsgs = 0, isv2 = 0; #endif /* @@ -806,6 +781,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" ); newmsg->lm_msgid = (int)id; newmsg->lm_msgtype = tag; newmsg->lm_ber = ber; + newmsg->lm_chain_tail = newmsg; #ifdef LDAP_CONNECTIONLESS /* CLDAP replies all fit in a single datagram. In LDAPv2 RFC1798 @@ -852,17 +828,14 @@ lr->lr_res_matched ? lr->lr_res_matched : "" ); if (ber_sockbuf_ctrl(sb, LBER_SB_OPT_DATA_READY, NULL)) ok=1; } /* set up response chain */ - if ( firstmsg ) { - firstmsg = 0; + if ( tmp == NULL ) { newmsg->lm_next = ld->ld_responses; ld->ld_responses = newmsg; - newmsg->lm_chain_tail = newmsg; chain_head = newmsg; } else { - assert( tmp != NULL ); tmp->lm_chain = newmsg; - chain_head->lm_chain_tail = tmp; } + chain_head->lm_chain_tail = newmsg; tmp = newmsg; /* "ok" means there's more to parse */ if (ok) { @@ -883,7 +856,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" ); * first response off the head of the chain. */ tmp->lm_chain = newmsg; - chain_head->lm_chain_tail = tmp; + chain_head->lm_chain_tail = newmsg; *result = chkResponseList( ld, msgid, all ); ld->ld_errno = LDAP_SUCCESS; return( (*result)->lm_msgtype ); @@ -927,7 +900,6 @@ lr->lr_res_matched ? lr->lr_res_matched : "" ); newmsg->lm_next = ld->ld_responses; ld->ld_responses = newmsg; - newmsg->lm_chain_tail = newmsg; goto exit; } @@ -935,25 +907,8 @@ lr->lr_res_matched ? lr->lr_res_matched : "" ); (long) newmsg->lm_msgid, (long) newmsg->lm_msgtype, 0 ); /* part of a search response - add to end of list of entries */ - if (l->lm_chain == NULL) { - assert(l->lm_chain_tail == l); - l->lm_chain = newmsg; - } else { - assert(l->lm_chain_tail != NULL); - assert(l->lm_chain_tail->lm_chain != NULL); - if ((l->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_SEARCH_ENTRY) || - (l->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_SEARCH_REFERENCE) || - (l->lm_chain_tail->lm_chain->lm_msgtype - == LDAP_RES_INTERMEDIATE)) { - l->lm_chain_tail->lm_chain->lm_chain = newmsg; - l->lm_chain_tail = l->lm_chain_tail->lm_chain; - } else { - /*FIXME: ldap_msgfree( l->lm_chain_tail->lm_chain );*/ - l->lm_chain_tail->lm_chain = newmsg; - } - } + l->lm_chain_tail->lm_chain = newmsg; + l->lm_chain_tail = newmsg; /* return the whole chain if that's what we were looking for */ if ( foundit ) { diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index 71a5e33d20..6c73eff5b4 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -199,6 +199,12 @@ ldap_pvt_tls_init_def_ctx( void ) char *certfile = tls_opt_certfile; char *keyfile = tls_opt_keyfile; +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex ); +#endif + if (( !cacertfile && !cacertdir ) || !certfile || !keyfile ) + return LDAP_NOT_SUPPORTED; + #ifdef HAVE_EBCDIC /* This ASCII/EBCDIC handling is a real pain! */ if ( ciphersuite ) { @@ -222,10 +228,6 @@ ldap_pvt_tls_init_def_ctx( void ) __atoe( keyfile ); } #endif - -#ifdef LDAP_R_COMPILE - ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex ); -#endif if ( tls_def_ctx == NULL ) { int i; tls_def_ctx = SSL_CTX_new( SSLv23_method() ); diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 1c596de133..aeba81e1db 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -120,6 +120,13 @@ meta_back_db_config( fname, lineno ); return 1; } + + if ( be->be_nsuffix == NULL ) { + fprintf( stderr, + "%s: line %d: the suffix must be defined before any target.\n", + fname, lineno ); + return 1; + } ++mi->mi_ntargets; @@ -163,12 +170,29 @@ meta_back_db_config( /* * uri MUST have the part! */ - if ( ludp->lud_dn == NULL || ludp->lud_dn[ 0 ] == '\0' ) { + if ( ludp->lud_dn == NULL ) { fprintf( stderr, "%s: line %d: missing " " in \"uri ://[:port]/\" line\n", fname, lineno ); return 1; + + } else if ( ludp->lud_dn[ 0 ] == '\0' ) { + int j = -1; + + for ( j = 0; !BER_BVISNULL( &be->be_nsuffix[ j ] ); j++ ) { + if ( BER_BVISEMPTY( &be->be_nsuffix[ j ] ) ) { + break; + } + } + + if ( BER_BVISNULL( &be->be_nsuffix[ j ] ) ) { + fprintf( stderr, + "%s: line %d: missing " + " in \"uri ://[:port]/\" line\n", + fname, lineno ); + return 1; + } } /* @@ -1029,6 +1053,10 @@ suffix_massage_regexize( const char *s ) const char *p, *r; int i; + if ( s[ 0 ] == '\0' ) { + return ch_strdup( "^(.+)$" ); + } + for ( i = 0, p = s; ( r = strchr( p, ',' ) ) != NULL; p = r + 1, i++ ) @@ -1036,10 +1064,11 @@ suffix_massage_regexize( const char *s ) res = ch_calloc( sizeof( char ), strlen( s ) - + STRLENOF( "(.+,)?" ) - + STRLENOF( "[ ]?" ) * i + 1 ); + + STRLENOF( "((.+),)?" ) + + STRLENOF( "[ ]?" ) * i + + STRLENOF( "$" ) + 1 ); - ptr = lutil_strcopy( res, "(.+,)?" ); + ptr = lutil_strcopy( res, "((.+),)?" ); for ( i = 0, p = s; ( r = strchr( p, ',' ) ) != NULL; p = r + 1 , i++ ) { @@ -1050,26 +1079,37 @@ suffix_massage_regexize( const char *s ) r++; } } - lutil_strcopy( ptr, p ); + ptr = lutil_strcopy( ptr, p ); + ptr[ 0 ] = '$'; + ptr++; + ptr[ 0 ] = '\0'; return res; } static char * -suffix_massage_patternize( const char *s ) +suffix_massage_patternize( const char *s, const char *p ) { ber_len_t len; - char *res; + char *res, *ptr; + + len = strlen( p ); - len = strlen( s ); + if ( s[ 0 ] == '\0' ) { + len++; + } res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 ); if ( res == NULL ) { return NULL; } - strcpy( res, "%1" ); - strcpy( &res[ STRLENOF( "%1" ) ], s ); + ptr = lutil_strcopy( res, ( p[ 0 ] == '\0' ? "%2" : "%1" ) ); + if ( s[ 0 ] == '\0' ) { + ptr[ 0 ] = ','; + ptr++; + } + lutil_strcopy( ptr, p ); return res; } @@ -1098,12 +1138,21 @@ suffix_massage_config( rargv[ 0 ] = "rewriteRule"; rargv[ 1 ] = suffix_massage_regexize( pvnc->bv_val ); - rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val ); + rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val, prnc->bv_val ); rargv[ 3 ] = ":"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); ch_free( rargv[ 1 ] ); ch_free( rargv[ 2 ] ); + + if ( BER_BVISEMPTY( pvnc ) ) { + rargv[ 0 ] = "rewriteRule"; + rargv[ 1 ] = "^$"; + rargv[ 2 ] = prnc->bv_val; + rargv[ 3 ] = ":"; + rargv[ 4 ] = NULL; + rewrite_parse( info, "", ++line, 4, rargv ); + } rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "searchEntryDN"; @@ -1112,13 +1161,22 @@ suffix_massage_config( rargv[ 0 ] = "rewriteRule"; rargv[ 1 ] = suffix_massage_regexize( prnc->bv_val ); - rargv[ 2 ] = suffix_massage_patternize( pvnc->bv_val ); + rargv[ 2 ] = suffix_massage_patternize( prnc->bv_val, pvnc->bv_val ); rargv[ 3 ] = ":"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); ch_free( rargv[ 1 ] ); ch_free( rargv[ 2 ] ); + if ( BER_BVISEMPTY( prnc ) ) { + rargv[ 0 ] = "rewriteRule"; + rargv[ 1 ] = "^$"; + rargv[ 2 ] = pvnc->bv_val; + rargv[ 3 ] = ":"; + rargv[ 4 ] = NULL; + rewrite_parse( info, "", ++line, 4, rargv ); + } + /* backward compatibility */ rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "searchResult"; diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 1d0a548958..9254407e45 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -503,7 +503,7 @@ meta_back_get_candidate( struct berval *ndn ) { metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; - int candidate; + long candidate; /* * tries to get a unique candidate diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index be9de3f5ea..86c9daf8fb 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -3427,6 +3427,11 @@ config_back_add( Operation *op, SlapReply *rs ) BackendDB *be = op->o_bd; slap_callback sc = { NULL, slap_null_cb, NULL, NULL }; op->o_bd = &cfb->cb_db; + /* FIXME: there must be a better way. */ + if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) { + op->o_bd->be_rootdn = be->be_rootdn; + op->o_bd->be_rootndn= be->be_rootndn; + } sc.sc_next = op->o_callback; op->o_callback = ≻ op->o_bd->be_add( op, rs ); @@ -3751,6 +3756,10 @@ config_back_modify( Operation *op, SlapReply *rs ) BackendDB *be = op->o_bd; slap_callback sc = { NULL, slap_null_cb, NULL, NULL }; op->o_bd = &cfb->cb_db; + if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) { + op->o_bd->be_rootdn = be->be_rootdn; + op->o_bd->be_rootndn= be->be_rootndn; + } sc.sc_next = op->o_callback; op->o_callback = ≻ op->o_bd->be_modify( op, rs ); diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 098bce5242..f7e8a7f9b4 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -836,6 +836,13 @@ static int slap_open_listener( #else l.sl_is_tls = ldap_pvt_url_scheme2tls( lud->lud_scheme ); + if ( l.sl_is_tls && !slap_tls_ctx ) { + Debug( LDAP_DEBUG_ANY, + "daemon: TLS not configured (%s)\n", + url, 0, 0 ); + ldap_free_urldesc( lud ); + return -1; + } if(! lud->lud_port ) { lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT; } diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c index 33a8a11807..bef3b96560 100644 --- a/servers/slapd/extended.c +++ b/servers/slapd/extended.c @@ -69,9 +69,6 @@ static struct { { &slap_EXOP_CANCEL, SLAP_EXOP_HIDE, cancel_extop }, { &slap_EXOP_WHOAMI, 0, whoami_extop }, { &slap_EXOP_MODIFY_PASSWD, SLAP_EXOP_WRITES, passwd_extop }, -#ifdef HAVE_TLS - { &slap_EXOP_START_TLS, 0, starttls_extop }, -#endif { NULL, 0, NULL } }; diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 6a7ebec0ff..7de2855ba4 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -669,7 +669,12 @@ unhandled_option:; ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, NULL ); rc = ldap_pvt_tls_init_def_ctx(); - if( rc != 0) { + if( rc == 0) { + ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx ); + /* Restore previous ctx */ + ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, def_ctx ); + load_extop( &slap_EXOP_START_TLS, 0, starttls_extop ); + } else if ( rc != LDAP_NOT_SUPPORTED ) { Debug( LDAP_DEBUG_ANY, "main: TLS init def ctx failed: %d\n", rc, 0, 0 ); @@ -677,10 +682,6 @@ unhandled_option:; SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); goto destroy; } - /* Retrieve slapd's own ctx */ - ldap_pvt_tls_get_option( NULL, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx ); - /* Restore previous ctx */ - ldap_pvt_tls_set_option( NULL, LDAP_OPT_X_TLS_CTX, def_ctx ); } #endif diff --git a/servers/slapd/overlays/rwmconf.c b/servers/slapd/overlays/rwmconf.c index 077f6f8f87..7a87ccff00 100644 --- a/servers/slapd/overlays/rwmconf.c +++ b/servers/slapd/overlays/rwmconf.c @@ -248,6 +248,10 @@ rwm_suffix_massage_regexize( const char *s ) const char *p, *r; int i; + if ( s[0] == '\0' ) { + return ch_strdup( "^(.+)$" ); + } + for ( i = 0, p = s; ( r = strchr( p, ',' ) ) != NULL; p = r + 1, i++ ) @@ -277,20 +281,28 @@ rwm_suffix_massage_regexize( const char *s ) } static char * -rwm_suffix_massage_patternize( const char *s ) +rwm_suffix_massage_patternize( const char *s, const char *p ) { ber_len_t len; - char *res; + char *res, *ptr; - len = strlen( s ); + len = strlen( p ); + + if ( s[ 0 ] == '\0' ) { + len++; + } res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 ); if ( res == NULL ) { return NULL; } - strcpy( res, "%1" ); - strcpy( res + STRLENOF( "%1" ), s ); + ptr = lutil_strcopy( res, ( p[0] == '\0' ? "%2" : "%1" ) ); + if ( s[ 0 ] == '\0' ) { + ptr[ 0 ] = ','; + ptr++; + } + lutil_strcopy( ptr, p ); return res; } @@ -319,13 +331,22 @@ rwm_suffix_massage_config( rargv[ 0 ] = "rewriteRule"; rargv[ 1 ] = rwm_suffix_massage_regexize( pvnc->bv_val ); - rargv[ 2 ] = rwm_suffix_massage_patternize( prnc->bv_val ); + rargv[ 2 ] = rwm_suffix_massage_patternize( pvnc->bv_val, prnc->bv_val ); rargv[ 3 ] = ":"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); ch_free( rargv[ 1 ] ); ch_free( rargv[ 2 ] ); + if ( BER_BVISEMPTY( pvnc ) ) { + rargv[ 0 ] = "rewriteRule"; + rargv[ 1 ] = "^$"; + rargv[ 2 ] = prnc->bv_val; + rargv[ 3 ] = ":"; + rargv[ 4 ] = NULL; + rewrite_parse( info, "", ++line, 4, rargv ); + } + rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "searchEntryDN"; rargv[ 2 ] = NULL; @@ -333,13 +354,22 @@ rwm_suffix_massage_config( rargv[ 0 ] = "rewriteRule"; rargv[ 1 ] = rwm_suffix_massage_regexize( prnc->bv_val ); - rargv[ 2 ] = rwm_suffix_massage_patternize( pvnc->bv_val ); + rargv[ 2 ] = rwm_suffix_massage_patternize( prnc->bv_val, pvnc->bv_val ); rargv[ 3 ] = ":"; rargv[ 4 ] = NULL; rewrite_parse( info, "", ++line, 4, rargv ); ch_free( rargv[ 1 ] ); ch_free( rargv[ 2 ] ); + if ( BER_BVISEMPTY( prnc ) ) { + rargv[ 0 ] = "rewriteRule"; + rargv[ 1 ] = "^$"; + rargv[ 2 ] = pvnc->bv_val; + rargv[ 3 ] = ":"; + rargv[ 4 ] = NULL; + rewrite_parse( info, "", ++line, 4, rargv ); + } + rargv[ 0 ] = "rewriteContext"; rargv[ 1 ] = "matchedDN"; rargv[ 2 ] = "alias"; diff --git a/servers/slurpd/main.c b/servers/slurpd/main.c index 4984a6a50f..ccd75e7ed0 100644 --- a/servers/slurpd/main.c +++ b/servers/slurpd/main.c @@ -156,10 +156,20 @@ int main( int argc, char **argv ) #ifdef HAVE_TLS if( ldap_pvt_tls_init() || ldap_pvt_tls_init_def_ctx() ) { - fprintf( stderr, "TLS Initialization failed.\n" ); - SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); - rc = 1; - goto stop; + rc = 0; + /* See if we actually need TLS */ + for ( i=0; i < sglob->num_replicas; i++ ) { + if ( sglob->replicas[i]->ri_tls || ( sglob->replicas[i]->ri_uri && + !strncmp( sglob->replicas[i]->ri_uri, "ldaps:", 6 ))) { + rc = 1; + break; + } + } + if ( rc ) { + fprintf( stderr, "TLS Initialization failed.\n" ); + SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 ); + goto stop; + } } #endif -- 2.39.5