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)
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
#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)
#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 ) {
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 ) {
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 */
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;
/* 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
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
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;
LDAP_FREE( unfollowed );
return count;
} else {
- ld->ld_errno = LDAP_REFERRAL;
*errstrp = unfollowed;
return rc;
}
LDAPURLDesc *srv;
BerElement *ber;
LDAPreqinfo rinfo;
+ LDAPConn *lc;
Debug( LDAP_DEBUG_TRACE, "ldap_chase_referrals\n", 0, 0, 0 );
*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 );
ber_int_t scope;
int rc;
BerElement tmpber, *ber;
- char *orig_dn;
+ struct berval orig_dn;
char *dn;
Debug( LDAP_DEBUG_TRACE,
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 */
}
} else {
- rtag = ber_scanf( &tmpber, "{a" /*}*/, &orig_dn );
+ rtag = ber_scanf( &tmpber, "{m" /*}*/, &orig_dn );
}
if( rtag == LBER_ERROR ) {
}
if ( srv->lud_dn == NULL ) {
- dn = orig_dn;
+ dn = orig_dn.bv_val;
} else {
dn = srv->lud_dn;
}
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 );
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
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;
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 );
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 ) {
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;
}
#ifdef LDAP_CONNECTIONLESS
LDAPMessage *tmp = NULL, *chain_head = NULL;
- int firstmsg = 1, moremsgs = 0, isv2 = 0;
+ int moremsgs = 0, isv2 = 0;
#endif
/*
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
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) {
* 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 );
newmsg->lm_next = ld->ld_responses;
ld->ld_responses = newmsg;
- newmsg->lm_chain_tail = newmsg;
goto exit;
}
(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 ) {
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 ) {
__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() );
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;
/*
* uri MUST have the <dn> part!
*/
- if ( ludp->lud_dn == NULL || ludp->lud_dn[ 0 ] == '\0' ) {
+ if ( ludp->lud_dn == NULL ) {
fprintf( stderr,
"%s: line %d: missing <naming context> "
" in \"uri <protocol>://<server>[:port]/<naming context>\" 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 <naming context> "
+ " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
+ fname, lineno );
+ return 1;
+ }
}
/*
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++ )
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++ ) {
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;
}
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, "<suffix massage>", ++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, "<suffix massage>", ++line, 4, rargv );
+ }
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "searchEntryDN";
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, "<suffix massage>", ++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, "<suffix massage>", ++line, 4, rargv );
+ }
+
/* backward compatibility */
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "searchResult";
struct berval *ndn )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- int candidate;
+ long candidate;
/*
* tries to get a unique candidate
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 );
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 );
#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;
}
{ &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 }
};
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 );
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
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++ )
}
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;
}
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, "<suffix massage>", ++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, "<suffix massage>", ++line, 4, rargv );
+ }
+
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "searchEntryDN";
rargv[ 2 ] = NULL;
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, "<suffix massage>", ++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, "<suffix massage>", ++line, 4, rargv );
+ }
+
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "matchedDN";
rargv[ 2 ] = "alias";
#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