Commit 7d101bcd authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Sync with HEAD

ready for 1alpha release
parent 512f9e9c
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
ol_package=OpenLDAP ol_package=OpenLDAP
ol_major=2 ol_major=2
ol_minor=3 ol_minor=3
ol_patch=X ol_patch=1alpha
ol_api_inc=20300 ol_api_inc=20301
ol_api_current=0 ol_api_current=0
ol_api_revision=0 ol_api_revision=1
ol_api_age=0 ol_api_age=0
ol_release_date="2004/12/31" ol_release_date="2005/02/02"
...@@ -47,7 +47,7 @@ Other database options are described in the ...@@ -47,7 +47,7 @@ Other database options are described in the
.BR slapd.conf (5) .BR slapd.conf (5)
manual page. manual page.
.LP .LP
Note: It is strongly recommended to set Note: In early versions of back-ldap it was recommended to always set
.LP .LP
.RS .RS
.nf .nf
...@@ -63,6 +63,8 @@ database. ...@@ -63,6 +63,8 @@ database.
This is because operational attributes related to entry creation and This is because operational attributes related to entry creation and
modification should not be used, as they could be passed to the target modification should not be used, as they could be passed to the target
servers, generating an error. servers, generating an error.
The current implementation automatically sets ldapmod to off, so its use
is redundant and can be safely omitted.
.TP .TP
.B uri <ldapurl> .B uri <ldapurl>
LDAP server to use. Multiple URIs can be set in in a single LDAP server to use. Multiple URIs can be set in in a single
...@@ -234,7 +236,30 @@ in conjunction with Proxy Authorization. ...@@ -234,7 +236,30 @@ in conjunction with Proxy Authorization.
.TP .TP
.B rebind-as-user .B rebind-as-user
If this option is given, the client's bind credentials are remembered If this option is given, the client's bind credentials are remembered
for rebinds when chasing referrals. for rebinds when chasing referrals. Useful in conjunction with
\fBchase-referrals\fP, useless if \fBdont-chase-referrals\fP is set.
.LP
.B chase-referrals
.br
.B dont-chase-referrals
.RS
enable/disable automatic referral chasing, which is delegated to the
underlying libldap, with rebinding eventually performed if the
\fBrebind-as-user\fP directive is used. The default is to chase referrals.
.RE
.LP
.B start-tls
.br
.B try-start-tls
.RS
execute the start TLS extended operation when the connection is initialized.
\fBtry-start-tls\fP continues operations if start TLS fails.
.RE
.TP .TP
.\".B suffixmassage <suffix> <massaged (remote) suffix> .\".B suffixmassage <suffix> <massaged (remote) suffix>
.\"DNs ending with <suffix> in a request are changed to end with <remote .\"DNs ending with <suffix> in a request are changed to end with <remote
......
...@@ -30,11 +30,13 @@ directive and before any subsequent ...@@ -30,11 +30,13 @@ directive and before any subsequent
.B database .B database
directive. directive.
.TP .TP
.B glue-sub <suffix-DN> [async] .B glue-sub <suffix-DN> [async] [advertise]
Specify the suffix of a database to attach as a subordinate to the root Specify the suffix of a database to attach as a subordinate to the root
database. The specified database must have already been configured. If the database. The specified database must have already been configured. If the
optional "async" keyword is supplied, searches against this database may optional \fBasync\fP keyword is supplied, searches against this database may
be spawned in a separate thread to run concurrently with other operations. be spawned in a separate thread to run concurrently with other operations
(currently not implemented). If the optional \fBadvertise\fI flag
is supplied, the naming context is advertised in the rootDSE.
.SH FILES .SH FILES
.TP .TP
ETCDIR/slapd.conf ETCDIR/slapd.conf
......
...@@ -291,15 +291,16 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, ...@@ -291,15 +291,16 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
return rc; return rc;
} }
#endif #endif
FD_ZERO(&wfds);
FD_SET(s, &wfds ); do {
FD_ZERO(&wfds);
FD_SET(s, &wfds );
#ifdef HAVE_WINSOCK #ifdef HAVE_WINSOCK
FD_ZERO(&efds); FD_ZERO(&efds);
FD_SET(s, &efds ); FD_SET(s, &efds );
#endif #endif
do {
rc = select(ldap_int_tblsize, z, &wfds, rc = select(ldap_int_tblsize, z, &wfds,
#ifdef HAVE_WINSOCK #ifdef HAVE_WINSOCK
&efds, &efds,
......
...@@ -292,6 +292,7 @@ bdb_idl_cache_get( ...@@ -292,6 +292,7 @@ bdb_idl_cache_get(
{ {
bdb_idl_cache_entry_t idl_tmp; bdb_idl_cache_entry_t idl_tmp;
bdb_idl_cache_entry_t *matched_idl_entry; bdb_idl_cache_entry_t *matched_idl_entry;
int rc = LDAP_NO_SUCH_OBJECT;
DBT2bv( key, &idl_tmp.kstr ); DBT2bv( key, &idl_tmp.kstr );
idl_tmp.db = db; idl_tmp.db = db;
...@@ -301,19 +302,18 @@ bdb_idl_cache_get( ...@@ -301,19 +302,18 @@ bdb_idl_cache_get(
if ( matched_idl_entry != NULL ) { if ( matched_idl_entry != NULL ) {
if ( matched_idl_entry->idl && ids ) if ( matched_idl_entry->idl && ids )
BDB_IDL_CPY( ids, matched_idl_entry->idl ); BDB_IDL_CPY( ids, matched_idl_entry->idl );
ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock ); ldap_pvt_thread_mutex_lock( &bdb->bi_idl_tree_lrulock );
IDL_LRU_DELETE( bdb, matched_idl_entry ); IDL_LRU_DELETE( bdb, matched_idl_entry );
IDL_LRU_ADD( bdb, matched_idl_entry ); IDL_LRU_ADD( bdb, matched_idl_entry );
ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock ); ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
if ( matched_idl_entry->idl ) if ( matched_idl_entry->idl )
return LDAP_SUCCESS; rc = LDAP_SUCCESS;
else else
return DB_NOTFOUND; rc = DB_NOTFOUND;
} }
ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock ); ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
return LDAP_NO_SUCH_OBJECT; return rc;
} }
void void
......
...@@ -472,7 +472,6 @@ bdb_back_initialize( ...@@ -472,7 +472,6 @@ bdb_back_initialize(
#ifdef LDAP_CONTROL_SUBENTRIES #ifdef LDAP_CONTROL_SUBENTRIES
LDAP_CONTROL_SUBENTRIES, LDAP_CONTROL_SUBENTRIES,
#endif #endif
LDAP_CONTROL_VALUESRETURNFILTER,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY #ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY, LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif #endif
......
...@@ -34,13 +34,12 @@ dnssrv_back_initialize( ...@@ -34,13 +34,12 @@ dnssrv_back_initialize(
{ {
static char *controls[] = { static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT, LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_VALUESRETURNFILTER,
NULL NULL
}; };
bi->bi_controls = controls; bi->bi_controls = controls;
bi->bi_open = 0; bi->bi_open = dnssrv_back_open;
bi->bi_config = 0; bi->bi_config = 0;
bi->bi_close = 0; bi->bi_close = 0;
bi->bi_destroy = 0; bi->bi_destroy = 0;
...@@ -71,6 +70,21 @@ dnssrv_back_initialize( ...@@ -71,6 +70,21 @@ dnssrv_back_initialize(
return 0; return 0;
} }
AttributeDescription *ad_dc;
AttributeDescription *ad_associatedDomain;
int
dnssrv_back_open(
BackendInfo *bi )
{
const char *text;
(void)slap_str2ad( "dc", &ad_dc, &text );
(void)slap_str2ad( "associatedDomain", &ad_associatedDomain, &text );
return 0;
}
int int
dnssrv_back_db_init( dnssrv_back_db_init(
Backend *be ) Backend *be )
......
...@@ -41,7 +41,15 @@ dnssrv_back_referrals( ...@@ -41,7 +41,15 @@ dnssrv_back_referrals(
char **hosts = NULL; char **hosts = NULL;
BerVarray urls = NULL; BerVarray urls = NULL;
if( op->o_req_dn.bv_len == 0 ) { if ( BER_BVISEMPTY( &op->o_req_dn ) ) {
#ifdef LDAP_DEVEL
/* FIXME: need some means to determine whether the database
* is a glue instance */
if ( SLAP_GLUE_INSTANCE( op->o_bd ) ) {
return LDAP_SUCCESS;
}
#endif /* LDAP_DEVEL */
rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed";
return LDAP_UNWILLING_TO_PERFORM; return LDAP_UNWILLING_TO_PERFORM;
} }
......
...@@ -47,11 +47,27 @@ dnssrv_back_search( ...@@ -47,11 +47,27 @@ dnssrv_back_search(
rs->sr_ref = NULL; rs->sr_ref = NULL;
if ( BER_BVISEMPTY( &op->o_req_ndn ) ) {
#ifdef LDAP_DEVEL
/* FIXME: need some means to determine whether the database
* is a glue instance; if we got here with empty DN, then
* we passed this same test in dnssrv_back_referrals() */
if ( !SLAP_GLUE_INSTANCE( op->o_bd ) ) {
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed";
} else {
rs->sr_err = LDAP_SUCCESS;
}
goto done;
#endif /* LDAP_DEVEL */
}
manageDSAit = get_manageDSAit( op ); manageDSAit = get_manageDSAit( op );
/* /*
* FIXME: we may return a referral if manageDSAit is not set * FIXME: we may return a referral if manageDSAit is not set
*/ */
if ( ! manageDSAit ) { if ( !manageDSAit ) {
send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
"manageDSAit must be set" ); "manageDSAit must be set" );
goto done; goto done;
...@@ -151,7 +167,6 @@ dnssrv_back_search( ...@@ -151,7 +167,6 @@ dnssrv_back_search(
send_ldap_error( op, rs, LDAP_SUCCESS, NULL ); send_ldap_error( op, rs, LDAP_SUCCESS, NULL );
} else { } else {
struct berval vals[2];
Entry *e = ch_calloc( 1, sizeof(Entry) ); Entry *e = ch_calloc( 1, sizeof(Entry) );
AttributeDescription *ad_objectClass AttributeDescription *ad_objectClass
= slap_schema.si_ad_objectClass; = slap_schema.si_ad_objectClass;
...@@ -164,54 +179,36 @@ dnssrv_back_search( ...@@ -164,54 +179,36 @@ dnssrv_back_search(
e->e_attrs = NULL; e->e_attrs = NULL;
e->e_private = NULL; e->e_private = NULL;
vals[1].bv_val = NULL; attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_top->soc_cname );
attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_referral->soc_cname );
vals[0].bv_val = "top"; attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname );
vals[0].bv_len = sizeof("top")-1;
attr_mergeit( e, ad_objectClass, vals );
vals[0].bv_val = "referral";
vals[0].bv_len = sizeof("referral")-1;
attr_mergeit( e, ad_objectClass, vals );
vals[0].bv_val = "extensibleObject"; if ( ad_dc ) {
vals[0].bv_len = sizeof("extensibleObject")-1; char *p;
attr_mergeit( e, ad_objectClass, vals ); struct berval bv;
{ bv.bv_val = domain;
AttributeDescription *ad = NULL;
const char *text;
rc = slap_str2ad( "dc", &ad, &text ); p = strchr( bv.bv_val, '.' );
if ( p == bv.bv_val ) {
bv.bv_len = 1;
if( rc == LDAP_SUCCESS ) { } else if ( p != NULL ) {
char *p; bv.bv_len = p - bv.bv_val;
vals[0].bv_val = ch_strdup( domain );
p = strchr( vals[0].bv_val, '.' ); } else {
bv.bv_len = strlen( bv.bv_val );
if( p == vals[0].bv_val ) {
vals[0].bv_val[1] = '\0';
} else if ( p != NULL ) {
*p = '\0';
}
vals[0].bv_len = strlen(vals[0].bv_val);
attr_mergeit( e, ad, vals );
} }
}
{ attr_mergeit_one( e, ad_dc, &bv );
AttributeDescription *ad = NULL; }
const char *text;
rc = slap_str2ad( "associatedDomain", &ad, &text ); if ( ad_associatedDomain ) {
struct berval bv;
if( rc == LDAP_SUCCESS ) { ber_str2bv( domain, 0, 0, &bv );
vals[0].bv_val = domain; attr_mergeit_one( e, ad_associatedDomain, &bv );
vals[0].bv_len = strlen(domain);
attr_mergeit( e, ad, vals );
}
} }
attr_mergeit( e, ad_ref, urls ); attr_mergeit( e, ad_ref, urls );
......
...@@ -95,6 +95,7 @@ struct ldapinfo { ...@@ -95,6 +95,7 @@ struct ldapinfo {
#define LDAP_BACK_F_SAVECRED 0x01U #define LDAP_BACK_F_SAVECRED 0x01U
#define LDAP_BACK_F_USE_TLS 0x02U #define LDAP_BACK_F_USE_TLS 0x02U
#define LDAP_BACK_F_TLS_CRITICAL ( 0x04U | LDAP_BACK_F_USE_TLS ) #define LDAP_BACK_F_TLS_CRITICAL ( 0x04U | LDAP_BACK_F_USE_TLS )
#define LDAP_BACK_F_CHASE_REFERRALS 0x8U
Avlnode *conntree; Avlnode *conntree;
int rwm_started; int rwm_started;
......
...@@ -68,7 +68,7 @@ ldap_back_bind( Operation *op, SlapReply *rs ) ...@@ -68,7 +68,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val, rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
LDAP_SASL_SIMPLE, LDAP_SASL_SIMPLE,
&op->orb_cred, op->o_ctrls, NULL, &msgid ); &op->orb_cred, op->o_ctrls, NULL, &msgid );
rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT ); rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {
/* If defined, proxyAuthz will be used also when /* If defined, proxyAuthz will be used also when
...@@ -241,15 +241,12 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda ...@@ -241,15 +241,12 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
*/ */
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers ); ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers );
/* Set LDAP version. This will always succeed: If the client /* automatically chase referrals ("chase-referrals"/"dont-chase-referrals" statement) */
* bound with a particular version, then so can we. if ( li->flags & LDAP_BACK_F_CHASE_REFERRALS ) {
*/ ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, }
(const void *)&vers );
/* FIXME: configurable? */
ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
/* start TLS ("start-tls"/"try-start-tls" statements) */
if ( ( li->flags & LDAP_BACK_F_USE_TLS ) if ( ( li->flags & LDAP_BACK_F_USE_TLS )
&& !ldap_is_ldaps_url( li->url ) && !ldap_is_ldaps_url( li->url )
&& ( rs->sr_err = ldap_start_tls_s( ld, NULL, NULL ) ) != LDAP_SUCCESS ) && ( rs->sr_err = ldap_start_tls_s( ld, NULL, NULL ) ) != LDAP_SUCCESS )
......
...@@ -614,6 +614,23 @@ ldap_chain_db_destroy( ...@@ -614,6 +614,23 @@ ldap_chain_db_destroy(
return rc; return rc;
} }
static int
ldap_chain_connection_destroy(
BackendDB *be,
Connection *conn
)
{
slap_overinst *on = (slap_overinst *) be->bd_info;
void *private = be->be_private;
int rc;
be->be_private = on->on_bi.bi_private;
rc = lback->bi_connection_destroy( be, conn );
on->on_bi.bi_private = be->be_private;
be->be_private = private;
return rc;
}
#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR #ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
static int static int
ldap_chain_parse_ctrl( ldap_chain_parse_ctrl(
...@@ -766,18 +783,20 @@ chain_init( void ) ...@@ -766,18 +783,20 @@ chain_init( void )
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */ #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
ldapchain.on_bi.bi_db_config = ldap_chain_db_config; ldapchain.on_bi.bi_db_config = ldap_chain_db_config;
ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy; ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy;
/* ... otherwise the underlying backend's function would be called, /* ... otherwise the underlying backend's function would be called,
* likely passing an invalid entry; on the contrary, the requested * likely passing an invalid entry; on the contrary, the requested
* operational attributes should have been returned while chasing * operational attributes should have been returned while chasing
* the referrals. This all in all is a bit messy, because part * the referrals. This all in all is a bit messy, because part
* of the operational attributes are generated by they backend; * of the operational attributes are generated by the backend;
* part by the frontend; back-ldap should receive all the available * part by the frontend; back-ldap should receive all the available
* ones from the remote server, but then, on it own, it strips those * ones from the remote server, but then, on its own, it strips those
* it assumes will be (re)generated by the frontend (e.g. * it assumes will be (re)generated by the frontend (e.g.
* subschemaSubentry.) */ * subschemaSubentry.) */
ldapchain.on_bi.bi_operational = ldap_chain_operational; ldapchain.on_bi.bi_operational = ldap_chain_operational;
ldapchain.on_bi.bi_connection_destroy = ldap_chain_connection_destroy;
ldapchain.on_response = ldap_chain_response; ldapchain.on_response = ldap_chain_response;
return overlay_register( &ldapchain ); return overlay_register( &ldapchain );
......
...@@ -289,12 +289,32 @@ ldap_back_db_config( ...@@ -289,12 +289,32 @@ ldap_back_db_config(
} else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) { } else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
if ( argc != 1 ) { if ( argc != 1 ) {
fprintf( stderr, fprintf( stderr,
"%s: line %d: rebind-as-user takes no arguments\n", "%s: line %d: \"rebind-as-user\" takes no arguments\n",
fname, lineno ); fname, lineno );
return( 1 ); return( 1 );
} }
li->flags |= LDAP_BACK_F_SAVECRED; li->flags |= LDAP_BACK_F_SAVECRED;
} else if ( strcasecmp( argv[0], "chase-referrals" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: \"chase-referrals\" takes no arguments\n",
fname, lineno );
return( 1 );
}
li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
} else if ( strcasecmp( argv[0], "dont-chase-referrals" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: \"dont-chase-referrals\" takes no arguments\n",
fname, lineno );
return( 1 );
}
li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
/* intercept exop_who_am_i? */ /* intercept exop_who_am_i? */
} else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) { } else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
if ( argc != 1 ) { if ( argc != 1 ) {
......
...@@ -109,6 +109,9 @@ ldap_back_db_init( Backend *be ) ...@@ -109,6 +109,9 @@ ldap_back_db_init( Backend *be )
/* by default, use proxyAuthz control on each operation */ /* by default, use proxyAuthz control on each operation */
li->idassert_flags = LDAP_BACK_AUTH_NONE; li->idassert_flags = LDAP_BACK_AUTH_NONE;
/* initialize flags */
li->flags = LDAP_BACK_F_CHASE_REFERRALS;
ldap_pvt_thread_mutex_init( &li->conn_mutex ); ldap_pvt_thread_mutex_init( &li->conn_mutex );
be->be_private = li; be->be_private = li;
......
...@@ -573,8 +573,8 @@ ldap_back_entry_get( ...@@ -573,8 +573,8 @@ ldap_back_entry_get(
retry: retry:
rc = ldap_search_ext_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter, rc = ldap_search_ext_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
at ? gattr : NULL, 0, ctrls, NULL, LDAP_NO_LIMIT, at ? gattr : NULL, 0, ctrls, NULL,
LDAP_NO_LIMIT, &result ); LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
if ( rc == LDAP_SERVER_DOWN && do_retry ) { if ( rc == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0; do_retry = 0;
......
...@@ -31,7 +31,6 @@ ldbm_back_initialize( ...@@ -31,7 +31,6 @@ ldbm_back_initialize(
{ {
static char *controls[] = { static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT, LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_VALUESRETURNFILTER,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY #ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY, LDAP_CONTROL_X_PERMISSIVE_MODIFY