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 @@
ol_package=OpenLDAP
ol_major=2
ol_minor=3
ol_patch=X
ol_api_inc=20300
ol_patch=1alpha
ol_api_inc=20301
ol_api_current=0
ol_api_revision=0
ol_api_revision=1
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
.BR slapd.conf (5)
manual page.
.LP
Note: It is strongly recommended to set
Note: In early versions of back-ldap it was recommended to always set
.LP
.RS
.nf
......@@ -63,6 +63,8 @@ database.
This is because operational attributes related to entry creation and
modification should not be used, as they could be passed to the target
servers, generating an error.
The current implementation automatically sets ldapmod to off, so its use
is redundant and can be safely omitted.
.TP
.B uri <ldapurl>
LDAP server to use. Multiple URIs can be set in in a single
......@@ -234,7 +236,30 @@ in conjunction with Proxy Authorization.
.TP
.B rebind-as-user
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
.\".B suffixmassage <suffix> <massaged (remote) suffix>
.\"DNs ending with <suffix> in a request are changed to end with <remote
......
......@@ -30,11 +30,13 @@ directive and before any subsequent
.B database
directive.
.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
database. The specified database must have already been configured. If the
optional "async" keyword is supplied, searches against this database may
be spawned in a separate thread to run concurrently with other operations.
optional \fBasync\fP keyword is supplied, searches against this database may
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
.TP
ETCDIR/slapd.conf
......
......@@ -291,15 +291,16 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
return rc;
}
#endif
FD_ZERO(&wfds);
FD_SET(s, &wfds );
do {
FD_ZERO(&wfds);
FD_SET(s, &wfds );
#ifdef HAVE_WINSOCK
FD_ZERO(&efds);
FD_SET(s, &efds );
FD_ZERO(&efds);
FD_SET(s, &efds );
#endif
do {
rc = select(ldap_int_tblsize, z, &wfds,
#ifdef HAVE_WINSOCK
&efds,
......
......@@ -292,6 +292,7 @@ bdb_idl_cache_get(
{
bdb_idl_cache_entry_t idl_tmp;
bdb_idl_cache_entry_t *matched_idl_entry;
int rc = LDAP_NO_SUCH_OBJECT;
DBT2bv( key, &idl_tmp.kstr );
idl_tmp.db = db;
......@@ -301,19 +302,18 @@ bdb_idl_cache_get(
if ( matched_idl_entry != NULL ) {
if ( matched_idl_entry->idl && ids )
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 );
IDL_LRU_DELETE( bdb, matched_idl_entry );
IDL_LRU_ADD( bdb, matched_idl_entry );
ldap_pvt_thread_mutex_unlock( &bdb->bi_idl_tree_lrulock );
if ( matched_idl_entry->idl )
return LDAP_SUCCESS;
rc = LDAP_SUCCESS;
else
return DB_NOTFOUND;
rc = DB_NOTFOUND;
}
ldap_pvt_thread_rdwr_runlock( &bdb->bi_idl_tree_rwlock );
return LDAP_NO_SUCH_OBJECT;
return rc;
}
void
......
......@@ -472,7 +472,6 @@ bdb_back_initialize(
#ifdef LDAP_CONTROL_SUBENTRIES
LDAP_CONTROL_SUBENTRIES,
#endif
LDAP_CONTROL_VALUESRETURNFILTER,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif
......
......@@ -34,13 +34,12 @@ dnssrv_back_initialize(
{
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_VALUESRETURNFILTER,
NULL
};
bi->bi_controls = controls;
bi->bi_open = 0;
bi->bi_open = dnssrv_back_open;
bi->bi_config = 0;
bi->bi_close = 0;
bi->bi_destroy = 0;
......@@ -71,6 +70,21 @@ dnssrv_back_initialize(
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
dnssrv_back_db_init(
Backend *be )
......
......@@ -41,7 +41,15 @@ dnssrv_back_referrals(
char **hosts = 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";
return LDAP_UNWILLING_TO_PERFORM;
}
......
......@@ -47,11 +47,27 @@ dnssrv_back_search(
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 );
/*
* FIXME: we may return a referral if manageDSAit is not set
*/
if ( ! manageDSAit ) {
if ( !manageDSAit ) {
send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
"manageDSAit must be set" );
goto done;
......@@ -151,7 +167,6 @@ dnssrv_back_search(
send_ldap_error( op, rs, LDAP_SUCCESS, NULL );
} else {
struct berval vals[2];
Entry *e = ch_calloc( 1, sizeof(Entry) );
AttributeDescription *ad_objectClass
= slap_schema.si_ad_objectClass;
......@@ -164,54 +179,36 @@ dnssrv_back_search(
e->e_attrs = NULL;
e->e_private = NULL;
vals[1].bv_val = NULL;
vals[0].bv_val = "top";
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 );
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 );
attr_mergeit_one( e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname );
vals[0].bv_val = "extensibleObject";
vals[0].bv_len = sizeof("extensibleObject")-1;
attr_mergeit( e, ad_objectClass, vals );
if ( ad_dc ) {
char *p;
struct berval bv;
{
AttributeDescription *ad = NULL;
const char *text;
bv.bv_val = domain;
rc = slap_str2ad( "dc", &ad, &text );
p = strchr( bv.bv_val, '.' );
if ( p == bv.bv_val ) {
bv.bv_len = 1;
if( rc == LDAP_SUCCESS ) {
char *p;
vals[0].bv_val = ch_strdup( domain );
} else if ( p != NULL ) {
bv.bv_len = p - bv.bv_val;
p = strchr( vals[0].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 );
} else {
bv.bv_len = strlen( bv.bv_val );
}
}
{
AttributeDescription *ad = NULL;
const char *text;
attr_mergeit_one( e, ad_dc, &bv );
}
rc = slap_str2ad( "associatedDomain", &ad, &text );
if ( ad_associatedDomain ) {
struct berval bv;
if( rc == LDAP_SUCCESS ) {
vals[0].bv_val = domain;
vals[0].bv_len = strlen(domain);
attr_mergeit( e, ad, vals );
}
ber_str2bv( domain, 0, 0, &bv );
attr_mergeit_one( e, ad_associatedDomain, &bv );
}
attr_mergeit( e, ad_ref, urls );
......
......@@ -95,6 +95,7 @@ struct ldapinfo {
#define LDAP_BACK_F_SAVECRED 0x01U
#define LDAP_BACK_F_USE_TLS 0x02U
#define LDAP_BACK_F_TLS_CRITICAL ( 0x04U | LDAP_BACK_F_USE_TLS )
#define LDAP_BACK_F_CHASE_REFERRALS 0x8U
Avlnode *conntree;
int rwm_started;
......
......@@ -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,
LDAP_SASL_SIMPLE,
&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 defined, proxyAuthz will be used also when
......@@ -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 );
/* Set LDAP version. This will always succeed: If the client
* bound with a particular version, then so can we.
*/
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
(const void *)&vers );
/* FIXME: configurable? */
ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
/* automatically chase referrals ("chase-referrals"/"dont-chase-referrals" statement) */
if ( li->flags & LDAP_BACK_F_CHASE_REFERRALS ) {
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 )
&& !ldap_is_ldaps_url( li->url )
&& ( rs->sr_err = ldap_start_tls_s( ld, NULL, NULL ) ) != LDAP_SUCCESS )
......
......@@ -614,6 +614,23 @@ ldap_chain_db_destroy(
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
static int
ldap_chain_parse_ctrl(
......@@ -766,18 +783,20 @@ chain_init( void )
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
ldapchain.on_bi.bi_db_config = ldap_chain_db_config;
ldapchain.on_bi.bi_db_destroy = ldap_chain_db_destroy;
/* ... otherwise the underlying backend's function would be called,
* likely passing an invalid entry; on the contrary, the requested
* operational attributes should have been returned while chasing
* 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
* 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.
* subschemaSubentry.) */
ldapchain.on_bi.bi_operational = ldap_chain_operational;
ldapchain.on_bi.bi_connection_destroy = ldap_chain_connection_destroy;
ldapchain.on_response = ldap_chain_response;
return overlay_register( &ldapchain );
......
......@@ -289,12 +289,32 @@ ldap_back_db_config(
} else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
if ( argc != 1 ) {
fprintf( stderr,
"%s: line %d: rebind-as-user takes no arguments\n",
"%s: line %d: \"rebind-as-user\" takes no arguments\n",
fname, lineno );
return( 1 );
}
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? */
} else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
if ( argc != 1 ) {
......
......@@ -109,6 +109,9 @@ ldap_back_db_init( Backend *be )
/* by default, use proxyAuthz control on each operation */
li->idassert_flags = LDAP_BACK_AUTH_NONE;
/* initialize flags */
li->flags = LDAP_BACK_F_CHASE_REFERRALS;
ldap_pvt_thread_mutex_init( &li->conn_mutex );
be->be_private = li;
......
......@@ -573,8 +573,8 @@ ldap_back_entry_get(
retry:
rc = ldap_search_ext_s( lc->lc_ld, ndn->bv_val, LDAP_SCOPE_BASE, filter,
at ? gattr : NULL, 0, ctrls, NULL, LDAP_NO_LIMIT,
LDAP_NO_LIMIT, &result );
at ? gattr : NULL, 0, ctrls, NULL,
LDAP_NO_LIMIT, LDAP_NO_LIMIT, &result );
if ( rc != LDAP_SUCCESS ) {
if ( rc == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0;
......
......@@ -31,7 +31,6 @@ ldbm_back_initialize(
{
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_VALUESRETURNFILTER,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif
......
......@@ -671,7 +671,6 @@ monitor_back_initialize(
monitor_subsys_t *ms;
static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_VALUESRETURNFILTER,
NULL
};
......
......@@ -21,6 +21,7 @@
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "slap.h"
#include "back-relay.h"
......@@ -102,15 +103,11 @@ relay_back_db_open( Backend *be )
assert( ri->ri_bd );
/* inherit controls */
if ( ri->ri_bd->be_controls ) {
be->be_controls = ldap_charray_dup( ri->ri_bd->be_controls );
}
AC_MEMCPY( be->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) );
} else {
/* inherit all? */
if ( frontendDB->be_controls ) {
be->be_controls = ldap_charray_dup( frontendDB->be_controls );
}
AC_MEMCPY( be->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) );
}
return 0;
......
......@@ -42,9 +42,6 @@ sql_back_initialize(
#ifdef LDAP_CONTROL_X_TREE_DELETE
LDAP_CONTROL_X_TREE_DELETE,
#endif /* LDAP_CONTROL_X_TREE_DELETE */
#ifdef LDAP_CONTROL_VALUESRETURNFILTER
LDAP_CONTROL_VALUESRETURNFILTER,
#endif /* LDAP_CONTROL_VALUESRETURNFILTER */
NULL
};
......
......@@ -65,6 +65,32 @@ BackendDB *backendDB = NULL;
ldap_pvt_thread_pool_t syncrepl_pool;
int syncrepl_pool_max = SLAP_MAX_SYNCREPL_THREADS;
static int
backend_init_controls( BackendInfo *bi )
{
if ( bi->bi_controls ) {
int i;
for ( i = 0; bi->bi_controls[ i ]; i++ ) {
int cid;
if ( slap_find_control_id( bi->bi_controls[ i ], &cid )
== LDAP_CONTROL_NOT_FOUND )
{
if ( !( slapMode & SLAP_TOOL_MODE ) ) {
assert( 0 );
}
return -1;
}
bi->bi_ctrls[ cid ] = 1;
}
}
return 0;
}
int backend_init(void)
{
int rc = -1;
......@@ -132,12 +158,15 @@ int backend_add(BackendInfo *aBackendInfo)
return -1;
}
if ((rc = aBackendInfo->bi_init(aBackendInfo)) != 0) {
rc = aBackendInfo->bi_init(aBackendInfo);
if ( rc != 0) {
Debug( LDAP_DEBUG_ANY,
"backend_add: initialization for type \"%s\" failed\n",
aBackendInfo->bi_type, 0, 0 );
return rc;
}
}
(void)backend_init_controls( aBackendInfo );
/* now add the backend type to the Backend Info List */
{
......@@ -161,65 +190,66 @@ int backend_add(BackendInfo *aBackendInfo)
}
}
static int
backend_set_controls( BackendDB *be )
{
BackendInfo *bi = be->bd_info;
/* back-relay takes care of itself; so may do other */
if ( overlay_is_over( be ) ) {
bi = ((slap_overinfo *)be->bd_info->bi_private)->oi_orig;
}
if ( bi->bi_controls ) {
if ( be->be_ctrls[ SLAP_MAX_CIDS ] == 0 ) {
AC_MEMCPY( be->be_ctrls, bi->bi_ctrls,
sizeof( be->be_ctrls ) );
be->be_ctrls[ SLAP_MAX_CIDS ] = 1;
} else {
int i;
for ( i = 0; i < SLAP_MAX_CIDS; i++ ) {
if ( bi->bi_ctrls[ i ] ) {
be->be_ctrls[ i ] = bi->bi_ctrls[ i ];
}
}
}
}
return 0;
}
/* startup a specific backend database */
int backend_startup_one(Backend *be)
{
int rc = 0;
BackendInfo *bi = be->bd_info;
assert(be);
assert( be );
be->be_pending_csn_list = (struct be_pcl *)
ch_calloc( 1, sizeof( struct be_pcl ));
LDAP_TAILQ_INIT( be->be_pending_csn_list );
/* back-relay takes care of itself; so may do other */
if ( be->be_controls == NULL ) {