SLAP_ACI_SCOPE_SUBTREE = ( SLAP_ACI_SCOPE_ENTRY | SLAP_ACI_SCOPE_CHILDREN )
} slap_aci_scope_t;
-static AccessControl * acl_get(
+static AccessControl * slap_acl_get(
AccessControl *ac, int *count,
Operation *op, Entry *e,
AttributeDescription *desc,
int nmatch, regmatch_t *matches,
AccessControlState *state );
-static slap_control_t acl_mask(
+static slap_control_t slap_acl_mask(
AccessControl *ac, slap_mask_t *mask,
Operation *op, Entry *e,
AttributeDescription *desc,
* the whole attribute is assumed (all values).
*
* This routine loops through all access controls and calls
- * acl_mask() on each applicable access control.
+ * slap_acl_mask() on each applicable access control.
* The loop exits when a definitive answer is reached or
* or no more controls remain.
*
memset( matches, '\0', sizeof( matches ) );
}
- while ( ( a = acl_get( a, &count, op, e, desc, val,
+ while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
MAXREMATCHES, matches, state ) ) != NULL )
{
int i;
}
vd_access:
- control = acl_mask( a, &mask, op,
+ control = slap_acl_mask( a, &mask, op,
e, desc, val, MAXREMATCHES, matches, count, state );
if ( control != ACL_BREAK ) {
memset( matches, '\0', sizeof(matches) );
}
- while ( ( a = acl_get( a, &count, op, e, desc, val,
+ while ( ( a = slap_acl_get( a, &count, op, e, desc, val,
MAXREMATCHES, matches, state ) ) != NULL )
{
int i;
}
vd_access:
- control = acl_mask( a, &mask, op,
+ control = slap_acl_mask( a, &mask, op,
e, desc, val, MAXREMATCHES, matches, count, state );
if ( control != ACL_BREAK ) {
#endif /* SLAP_OVERLAY_ACCESS */
/*
- * acl_get - return the acl applicable to entry e, attribute
+ * slap_acl_get - return the acl applicable to entry e, attribute
* attr. the acl returned is suitable for use in subsequent calls to
* acl_access_allowed().
*/
static AccessControl *
-acl_get(
+slap_acl_get(
AccessControl *a,
int *count,
Operation *op,
if( state && !( state->as_recorded & ACL_STATE_RECORDED_VD )) {
state->as_recorded |= ACL_STATE_RECORDED_VD;
- state->as_vd_acl = prev;
+ state->as_vd_acl = a;
state->as_vd_acl_count = *count;
state->as_vd_access = a->acl_access;
state->as_vd_access_count = 1;
if ( a->acl_attrs[0].an_desc->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName ) {
if (value_match( &match, desc,
- desc->ad_type->sat_equality, 0,
+ /* desc->ad_type->sat_equality */ a->acl_attrval_mr, 0,
val, &a->acl_attrval, &text ) != LDAP_SUCCESS ||
match )
continue;
/*
- * acl_mask - modifies mask based upon the given acl and the
+ * slap_acl_mask - modifies mask based upon the given acl and the
* requested access to entry e, attribute attr, value val. if val
* is null, access to the whole attribute is assumed (all values).
*
*/
static slap_control_t
-acl_mask(
+slap_acl_mask(
AccessControl *a,
slap_mask_t *mask,
Operation *op,
continue;
}
- /* this could be improved by changing acl_mask so that it can deal with
+ /* this could be improved by changing slap_acl_mask so that it can deal with
* by clauses that return grant/deny pairs. Right now, it does either
* additive or subtractive rights, but not both at the same time. So,
* we need to combine the grant/deny pair into a single rights mask in
continue;
}
- /* this could be improved by changing acl_mask so that it can deal with
+ /* this could be improved by changing slap_acl_mask so that it can deal with
* by clauses that return grant/deny pairs. Right now, it does either
* additive or subtractive rights, but not both at the same time. So,
* we need to combine the grant/deny pair into a single rights mask in
if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
fprintf( stderr, "%s: line %d: "
"inappropriate style \"%s\" in \"aci\" by clause\n",
- fname, lineno, sty );
+ fname, lineno, style_strings[sty] );
return -1;
}
#include "lutil.h"
static const char style_base[] = "base";
-static char *style_strings[] = {
+char *style_strings[] = {
"regex",
"expand",
"exact",
}
} else if ( strncasecmp( left, "val", 3 ) == 0 ) {
+ char *mr;
+
if ( !BER_BVISEMPTY( &a->acl_attrval ) ) {
fprintf( stderr,
"%s: line %d: attr val already specified in to clause.\n",
fname, lineno );
acl_usage();
}
+
ber_str2bv( right, 0, 1, &a->acl_attrval );
a->acl_attrval_style = ACL_STYLE_BASE;
+
+ mr = strchr( left, '/' );
+ if ( mr != NULL ) {
+ mr[ 0 ] = '\0';
+ mr++;
+
+ a->acl_attrval_mr = mr_find( mr );
+ if ( a->acl_attrval_mr == NULL ) {
+ fprintf( stderr, "%s: line %d: "
+ "invalid matching rule \"%s\".\n",
+ fname, lineno, mr );
+ acl_usage();
+ }
+
+ if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )
+ {
+ fprintf( stderr, "%s: line %d: "
+ "matching rule \"%s\" use "
+ "with attr \"%s\" not appropriate.\n",
+ fname, lineno, mr,
+ a->acl_attrs[ 0 ].an_name.bv_val );
+ acl_usage();
+ }
+ }
+
if ( style != NULL ) {
if ( strcasecmp( style, "regex" ) == 0 ) {
int e = regcomp( &a->acl_attrval_re, a->acl_attrval.bv_val,
} else if ( a->acl_attrs[0].an_desc->ad_type->
sat_syntax == slap_schema.si_syn_distinguishedName )
{
+ struct berval bv;
+
if ( !strcasecmp( style, "baseObject" ) ||
!strcasecmp( style, "base" ) )
{
a->acl_attrval_style = ACL_STYLE_BASE;
}
+ bv = a->acl_attrval;
+ rc = dnNormalize( 0, NULL, NULL, &bv, &a->acl_attrval, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "%s: line %d: unable to normalize DN \"%s\" "
+ "for attributeType \"%s\" (%d).\n",
+ fname, lineno, bv.bv_val,
+ a->acl_attrs[0].an_desc->ad_cname.bv_val, rc );
+ acl_usage();
+ }
+ ber_memfree( bv.bv_val );
+
} else {
fprintf( stderr,
"%s: line %d: unknown val.<style> \"%s\" "
}
}
}
-
+
+ /* Check for appropriate matching rule */
+ if ( a->acl_attrval_style != ACL_STYLE_REGEX ) {
+ if ( a->acl_attrval_mr == NULL ) {
+ a->acl_attrval_mr = a->acl_attrs[ 0 ].an_desc->ad_type->sat_equality;
+ }
+
+ if ( a->acl_attrval_mr == NULL ) {
+ fprintf( stderr, "%s: line %d: "
+ "attr \"%s\" must have an EQUALITY matching rule.\n",
+ fname, lineno, a->acl_attrs[ 0 ].an_name.bv_val );
+ acl_usage();
+ }
+ }
+
} else {
fprintf( stderr,
"%s: line %d: expecting <what> got \"%s\"\n",
"<access clause> ::= access to <what> "
"[ by <who> <access> [ <control> ] ]+ \n"
"<what> ::= * | [dn[.<dnstyle>]=<DN>] [filter=<filter>] [attrs=<attrlist>]\n"
- "<attrlist> ::= <attr> [val[.<attrstyle>]=<value>] | <attr> , <attrlist>\n"
+ "<attrlist> ::= <attr> [val[/matchingRule][.<attrstyle>]=<value>] | <attr> , <attrlist>\n"
"<attr> ::= <attrname> | entry | children\n",
"<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<DN> ]\n"
"\t[ realanonymous | realusers | realself | realdn[.<dnstyle>]=<DN> ]\n"
bv.bv_val = ptr;
ber_bvarray_add( bva, &bv );
}
+ return 0;
}
static AttributeDescription addef = { NULL, NULL, BER_BVC("default") };
#include "portable.h"
#include <stdio.h>
+#include <ac/ctype.h>
#include <ac/string.h>
#include "back-bdb.h"
{ "dbconfig", "DB_CONFIG setting", 1, 0, 0, ARG_MAGIC|BDB_CONFIG,
bdb_cf_gen, "( OLcfgDbAt:1.3 NAME 'olcDbConfig' "
"DESC 'BerkeleyDB DB_CONFIG configuration directives' "
- "SYNTAX OMsDirectoryString )",NULL, NULL },
+ "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )",NULL, NULL },
{ "dbnosync", NULL, 1, 2, 0, ARG_ON_OFF|ARG_MAGIC|BDB_NOSYNC,
bdb_cf_gen, "( OLcfgDbAt:1.4 NAME 'olcDbNoSync' "
"DESC 'Disable synchronous database writes' "
};
static ConfigOCs bdbocs[] = {
- { "( OLcfgDbOc:1.1 "
+ {
+#ifdef BDB_HIER
+ "( OLcfgDbOc:1.2 "
+ "NAME 'olcHdbConfig' "
+ "DESC 'HDB backend configuration' "
+#else
+ "( OLcfgDbOc:1.1 "
"NAME 'olcBdbConfig' "
"DESC 'BDB backend configuration' "
+#endif
"SUP olcDatabaseConfig "
"MUST olcDbDirectory "
"MAY ( olcDbCacheSize $ olcDbCheckpoint $ olcDbConfig $ "
*/
if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) {
struct re_s *re = bdb->bi_txn_cp_task;
- if ( re )
+ if ( re ) {
re->interval.tv_sec = bdb->bi_txn_cp_min * 60;
- else
+ } else {
+ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {
+ fprintf( stderr, "%s: "
+ "\"checkpoint\" must occur after \"suffix\".\n",
+ c->log );
+ return 1;
+ }
bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq,
bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb,
LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );
+ }
}
break;
case BDB_CONFIG: {
- char *ptr = c->line + STRLENOF("dbconfig");
+ char *ptr = c->line;
struct berval bv;
- while (!isspace(*ptr)) ptr++;
- while (isspace(*ptr)) ptr++;
-
+
+ if ( c->op == SLAP_CONFIG_ADD ) {
+ ptr += STRLENOF("dbconfig");
+ while (!isspace(*ptr)) ptr++;
+ while (isspace(*ptr)) ptr++;
+ }
+
if ( bdb->bi_flags & BDB_IS_OPEN ) {
bdb->bi_flags |= BDB_UPD_CONFIG;
c->cleanup = bdb_cf_cleanup;
/* Start the task as soon as we finish here. Set a long
* interval (10 hours) so that it only gets scheduled once.
*/
+ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) {
+ fprintf( stderr, "%s: "
+ "\"index\" must occur after \"suffix\".\n",
+ c->log );
+ return 1;
+ }
bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000,
bdb_online_index, c->be,
LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val );
rc = DB_NOTFOUND;
}
if ( rc == 0 ) {
- ptr = data.data + data.size - sizeof(ID);
+ ptr = (char *) data.data + data.size - sizeof(ID);
BDB_DISK2ID( ptr, &ei->bei_id );
ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen;
ptr = d->nrdn + nrlen + 1;
rc = LDAP_OTHER;
} else {
db_recno_t dkids;
- ptr = data.data + data.size - sizeof(ID);
+ ptr = (char *) data.data + data.size - sizeof(ID);
BDB_DISK2ID( ptr, idp );
ei->bei_nrdn.bv_len = (d->nrdnlen[0] << 8) | d->nrdnlen[1];
ber_str2bv( d->nrdn, ei->bei_nrdn.bv_len, 1, &ei->bei_nrdn );
if ( oc && !is_entry_objectclass( e, oc, 0 )) {
Debug( LDAP_DEBUG_ACL,
"<= bdb_entry_get: failed to find objectClass %s\n",
- oc->soc_cname, 0, 0 );
+ oc->soc_cname.bv_val, 0, 0 );
rc = LDAP_NO_SUCH_ATTRIBUTE;
goto return_results;
}
ldap_pvt_thread_mutex_init( &bdb->bi_cache.lru_mutex );
ldap_pvt_thread_mutex_init( &bdb->bi_cache.c_dntree.bei_kids_mutex );
ldap_pvt_thread_rdwr_init ( &bdb->bi_cache.c_rwlock );
+ ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
+ ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock );
be->be_private = bdb;
be->be_cf_ocs = be->bd_info->bi_cf_ocs;
#endif
if( rc == ENOENT ) {
- goto re_exit;
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_db_recover: DB environment files are missing, assuming it was "
+ "manually recovered\n", 0, 0, 0 );
+ return 0;
}
else if( rc != 0 ) {
Debug( LDAP_DEBUG_ANY,
if ( bdb->bi_idl_cache_max_size ) {
bdb->bi_idl_tree = NULL;
- ldap_pvt_thread_rdwr_init( &bdb->bi_idl_tree_rwlock );
- ldap_pvt_thread_mutex_init( &bdb->bi_idl_tree_lrulock );
bdb->bi_idl_cache_size = 0;
}
ldap_pvt_thread_mutex_destroy( &bdb->bi_cache.c_dntree.bei_kids_mutex );
ldap_pvt_thread_mutex_destroy( &bdb->bi_lastid_mutex );
ldap_pvt_thread_mutex_destroy( &bdb->bi_database_mutex );
- if ( bdb->bi_idl_cache_max_size ) {
- ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
- ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
- }
+ ldap_pvt_thread_rdwr_destroy( &bdb->bi_idl_tree_rwlock );
+ ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
ch_free( bdb );
be->be_private = NULL;
for ( id = bdb_idl_first( candidates, &cursor );
id != NOID ; id = bdb_idl_next( candidates, &cursor ) )
{
- int scopeok = 0;
+ int scopeok;
loop_begin:
* scope while we are looking at it, and unless we're using
* BDB_HIER, its parents cannot be moved either.
*/
+ scopeok = 0;
switch( op->ors_scope ) {
case LDAP_SCOPE_BASE:
/* This is always true, yes? */
static unsigned nhmax = HOLE_SIZE;
static unsigned nholes;
-Avlnode *index_attrs, index_dummy;
+static Avlnode *index_attrs, index_dummy;
int bdb_tool_entry_open(
BackendDB *be, int mode )
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+ lc = NULL;
goto cleanup;
}
ch_free( attrs );
}
+ if ( lc ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
Debug( LDAP_DEBUG_ARGS, "<== ldap_back_add(\"%s\"): %d\n",
op->o_req_dn.bv_val, rs->sr_err, 0 );
int lc_bound;
int lc_ispriv;
ldap_pvt_thread_mutex_t lc_mutex;
+ unsigned lc_refcnt;
};
/*
#define LDAP_BACK_AUTH_NONE 0x00U
#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U
#define LDAP_BACK_AUTH_OVERRIDE 0x02U
+#define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U
BerVarray idassert_authz;
/* end of ID assert stuff */
#include <stdio.h>
+#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
/* must re-insert if local DN changed as result of bind */
if ( lc->lc_bound && !dn_match( &op->o_req_ndn, &lc->lc_local_ndn ) ) {
- int lerr;
+ int lerr;
- ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+ /* wait for all other ops to release the connection */
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ if ( lc->lc_refcnt > 1 ) {
+ ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+ }
+ break;
+ }
+
+ assert( lc->lc_refcnt == 1 );
lc = avl_delete( &li->conntree, (caddr_t)lc,
ldap_back_conn_cmp );
+ assert( lc != NULL );
+
if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) {
ch_free( lc->lc_local_ndn.bv_val );
}
ldap_back_conn_cmp, ldap_back_conn_dup );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
if ( lerr == -1 ) {
+ /* handle this! (e.g. wait until refcnt goes to 1...) */
ldap_back_conn_free( lc );
+ lc = NULL;
}
}
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return( rc );
}
ldap_back_freeconn( Operation *op, struct ldapconn *lc )
{
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
+ int rc = 0;
- ldap_pvt_thread_mutex_lock( &li->conn_mutex );
- lc = avl_delete( &li->conntree, (caddr_t)lc,
- ldap_back_conn_cmp );
- ldap_back_conn_free( (void *)lc );
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
+ assert( lc->lc_refcnt > 0 );
+ if ( --lc->lc_refcnt == 0 ) {
+ lc = avl_delete( &li->conntree, (caddr_t)lc,
+ ldap_back_conn_cmp );
+ assert( lc != NULL );
+
+ ldap_back_conn_free( (void *)lc );
+ }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
- return 0;
+ return rc;
}
static int
ldap_unbind_ext_s( ld, NULL, NULL );
goto error_return;
}
+
+ /* in case Start TLS is not critical */
+ rs->sr_err = LDAP_SUCCESS;
}
#endif /* HAVE_TLS */
memset( *lcp, 0, sizeof( struct ldapconn ) );
}
(*lcp)->lc_ld = ld;
+ (*lcp)->lc_refcnt = 1;
error_return:;
if ( rs->sr_err != LDAP_SUCCESS ) {
lc_curr.lc_local_ndn = op->o_ndn;
}
- ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
lc = (struct ldapconn *)avl_find( li->conntree,
(caddr_t)&lc_curr, ldap_back_conn_cmp );
+ if ( lc != NULL ) {
+ lc->lc_refcnt++;
+ }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
/* Looks like we didn't get a bind. Open a new session... */
- if ( !lc ) {
+ if ( lc == NULL ) {
/* lc here must be NULL */
if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
return NULL;
lc->lc_bound = 0;
/* Inserts the newly created ldapconn in the avl tree */
- ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+retry_lock2:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock2;
+
+ case 0:
+ break;
+ }
+
+ assert( lc->lc_refcnt == 1 );
rs->sr_err = avl_insert( &li->conntree, (caddr_t)lc,
ldap_back_conn_cmp, ldap_back_conn_dup );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
Debug( LDAP_DEBUG_TRACE,
- "=>ldap_back_getconn: conn %p inserted\n", (void *) lc, 0, 0 );
+ "=>ldap_back_getconn: conn %p inserted (refcnt=%u)\n",
+ (void *)lc, lc->lc_refcnt, 0 );
/* Err could be -1 in case a duplicate ldapconn is inserted */
if ( rs->sr_err != 0 ) {
ldap_back_conn_free( lc );
+ rs->sr_err = LDAP_OTHER;
if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {
send_ldap_error( op, rs, LDAP_OTHER,
- "internal server error" );
+ "internal server error" );
}
return NULL;
}
+
} else {
Debug( LDAP_DEBUG_TRACE,
- "=>ldap_back_getconn: conn %p fetched\n", (void *) lc, 0, 0 );
+ "=>ldap_back_getconn: conn %p fetched (refcnt=%u)\n",
+ (void *)lc, lc->lc_refcnt, 0 );
}
return lc;
}
+void
+ldap_back_release_conn(
+ Operation *op,
+ SlapReply *rs,
+ struct ldapconn *lc )
+{
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
+ assert( lc->lc_refcnt > 0 );
+ lc->lc_refcnt--;
+ ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+}
+
/*
* ldap_back_dobind
*
Operation *op,
SlapReply *rs,
ldap_back_send_t sendok,
- int retries )
+ int retries,
+ int dolock )
{
int rc;
ber_int_t msgid;
*/
if ( op->o_conn != NULL &&
!op->o_do_not_cache &&
- !be_isroot( op ) &&
( BER_BVISNULL( &lc->lc_bound_ndn ) ||
( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
{
if ( rs->sr_err == LDAP_SERVER_DOWN ) {
if ( retries > 0 ) {
- ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
- lc->lc_ld = NULL;
-
- /* lc here must be the regular lc, reset and ready for init */
- if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
- return 0;
+ if ( dolock ) {
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
}
- retries--;
- goto retry;
+ assert( lc->lc_refcnt > 0 );
+ if ( lc->lc_refcnt == 1 ) {
+ ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
+ lc->lc_ld = NULL;
+
+ /* lc here must be the regular lc, reset and ready for init */
+ rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok );
+ }
+ if ( dolock ) {
+ ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
+ }
+ if ( rs->sr_err == LDAP_SUCCESS ) {
+ retries--;
+ goto retry;
+ }
}
ldap_back_freeconn( op, lc );
int rc;
ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
- rc = ldap_back_dobind_int( lc, op, rs, sendok, 1 );
+ rc = ldap_back_dobind_int( lc, op, rs, sendok, 1, 1 );
ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
return rc;
int
ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{
- int rc;
+ int rc = 0;
+ struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
- ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
- ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
- lc->lc_ld = NULL;
- lc->lc_bound = 0;
+ case 0:
+ break;
+ }
- /* lc here must be the regular lc, reset and ready for init */
- rc = ldap_back_prepare_conn( &lc, op, rs, sendok );
- if ( rc == LDAP_SUCCESS ) {
- rc = ldap_back_dobind_int( lc, op, rs, sendok, 0 );
+ if ( lc->lc_refcnt == 1 ) {
+ ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
+ ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
+ lc->lc_ld = NULL;
+ lc->lc_bound = 0;
+
+ /* lc here must be the regular lc, reset and ready for init */
+ rc = ldap_back_prepare_conn( &lc, op, rs, sendok );
+ if ( rc == LDAP_SUCCESS ) {
+ rc = ldap_back_dobind_int( lc, op, rs, sendok, 0, 0 );
+ }
+ ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
}
- ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
+
+ ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
return rc;
}
break;
default:
- if ( li->idassert_authz ) {
+ /* NOTE: rootdn can always idassert */
+ if ( li->idassert_authz && !be_isroot( op ) ) {
struct berval authcDN;
if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
authcDN = slap_empty_bv;
+
} else {
authcDN = op->o_conn->c_ndn;
}
rs->sr_err = slap_sasl_matches( op, li->idassert_authz,
&authcDN, &authcDN );
if ( rs->sr_err != LDAP_SUCCESS ) {
- send_ldap_result( op, rs );
- lc->lc_bound = 0;
+ if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
+ send_ldap_result( op, rs );
+ lc->lc_bound = 0;
+
+ } else {
+ rs->sr_err = LDAP_SUCCESS;
+ binddn = slap_empty_bv;
+ bindcred = slap_empty_bv;
+ break;
+ }
+
goto done;
}
}
goto done;
}
- } else if ( li->idassert_authz ) {
+ } else if ( li->idassert_authz && !be_isroot( op ) ) {
int rc;
struct berval authcDN;
rc = slap_sasl_matches( op, li->idassert_authz,
&authcDN, & authcDN );
if ( rc != LDAP_SUCCESS ) {
- /* op->o_conn->c_ndn is not authorized
- * to use idassert */
- return rc;
+ if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
+ /* op->o_conn->c_ndn is not authorized
+ * to use idassert */
+ return rc;
+ }
+ return rs->sr_err;
}
}
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+ lc = NULL;
goto cleanup;
}
cleanup:
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rs->sr_err;
}
char *ptr;
if ( li->idassert_authmethod != LDAP_AUTH_NONE ) {
+ ber_len_t len = bv.bv_len
+ + STRLENOF( "flags=override,non-prescriptive" );
+
switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
(void)lutil_strcopy( ptr, "authz=native" );
}
- if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
- ber_len_t len = bv.bv_len + STRLENOF( "flags=override" );
+ /* flags */
+ if ( !BER_BVISEMPTY( &bv ) ) {
+ len += STRLENOF( " " );
+ }
- if ( !BER_BVISEMPTY( &bv ) ) {
- len += STRLENOF( " " );
- }
+ bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
- bv.bv_val = ch_realloc( bv.bv_val, len + 1 );
+ ptr = &bv.bv_val[ bv.bv_len ];
- ptr = bv.bv_val + bv.bv_len;
+ if ( !BER_BVISEMPTY( &bv ) ) {
+ ptr = lutil_strcopy( ptr, " " );
+ }
- if ( !BER_BVISEMPTY( &bv ) ) {
- ptr = lutil_strcopy( ptr, " " );
- }
+ ptr = lutil_strcopy( ptr, "flags=" );
- (void)lutil_strcopy( ptr, "flags=override" );
+ if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
+ ptr = lutil_strcopy( ptr, "prescriptive" );
+ } else {
+ ptr = lutil_strcopy( ptr, "non-prescriptive" );
}
- }
+ if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
+ ptr = lutil_strcopy( ptr, ",override" );
+ }
+ bv.bv_len = ( ptr - bv.bv_val );
+ /* end-of-flags */
+ }
bindconf_unparse( &li->idassert_sb, &bc );
if ( strcasecmp( c->argv[ i ], "override" ) == 0 ) {
li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
+ } else if ( strcasecmp( c->argv[ i ], "prescriptive" ) == 0 ) {
+ li->idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
+
+ } else if ( strcasecmp( c->argv[ i ], "non-prescriptive" ) == 0 ) {
+ li->idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
+
} else {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unknown flag #%d "
if ( strcasecmp( flags[ j ], "override" ) == 0 ) {
li->idassert_flags |= LDAP_BACK_AUTH_OVERRIDE;
+ } else if ( strcasecmp( flags[ j ], "prescriptive" ) == 0 ) {
+ li->idassert_flags |= LDAP_BACK_AUTH_PRESCRIPTIVE;
+
+ } else if ( strcasecmp( flags[ j ], "non-prescriptive" ) == 0 ) {
+ li->idassert_flags &= ( ~LDAP_BACK_AUTH_PRESCRIPTIVE );
+
} else {
fprintf( stderr, "%s: %d: "
"\"idassert-bind <args>\": "
if (rs->sr_err != LDAP_SUCCESS) {
rs->sr_err = slap_map_api2result( rs );
}
+
+ if ( lc != NULL ) {
+ ldap_back_release_conn( &op2, rs, lc );
+ }
+
} else {
/* else just do the same as before */
bv = (struct berval *) ch_malloc( sizeof(struct berval) );
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
- rc = -1;
- goto cleanup;
+ return -1;
}
ctrls = op->o_ctrls;
cleanup:
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rc;
}
op->o_ctrls = oldctrls;
send_ldap_result( op, rs );
rs->sr_text = NULL;
- return rs->sr_err;
+ rc = rs->sr_err;
+ goto done;
}
rc = ( *exop_table[i].extended )( op, rs );
}
op->o_ctrls = oldctrls;
+done:;
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rc;
}
}
rc = -1;
}
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rc;
}
li->idassert_sb.sb_tls = SB_TLS_DEFAULT;
/* by default, use proxyAuthz control on each operation */
- li->idassert_flags = LDAP_BACK_AUTH_NONE;
+ li->idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
li->idassert_authz = NULL;
ldap_back_conn_free( void *v_lc )
{
struct ldapconn *lc = v_lc;
-
- ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
+
+ if ( lc->lc_ld != NULL ) {
+ ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
+ }
if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) {
ch_free( lc->lc_bound_ndn.bv_val );
}
}
ch_free( modv );
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rc;
}
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
- return( -1 );
+ return -1;
}
if ( op->orr_newSup ) {
cleanup:
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rc;
}
int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs, ldap_back_send_t sendok);
+void ldap_back_release_conn( struct slap_op *op, struct slap_rep *rs, struct ldapconn *lc );
int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
int ldap_back_map_result(SlapReply *rs);
static struct berval
bv_true = BER_BVC( "(?=true)" ),
bv_false = BER_BVC( "(?=false)" ),
+ bv_undefined = BER_BVC( "(?=undefined)" ),
bv_t = BER_BVC( "(&)" ),
bv_f = BER_BVC( "(|)" ),
bv_T = BER_BVC( "(objectClass=*)" ),
newbv = &bv_F;
}
+ } else if ( strncmp( ptr, bv_undefined.bv_val, bv_undefined.bv_len ) == 0 )
+ {
+ oldbv = &bv_undefined;
+ newbv = &bv_F;
+
} else {
gotit = 0;
goto done;
}
oldfilter = *filter;
- if ( !( li->flags & LDAP_BACK_F_SUPPORT_T_F ) ) {
+ if ( newbv->bv_len > oldbv->bv_len ) {
filter->bv_len += newbv->bv_len - oldbv->bv_len;
if ( filter->bv_val == op->ors_filterstr.bv_val ) {
filter->bv_val = op->o_tmpalloc( filter->bv_len + 1,
LDAPControl **ctrls = NULL;
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
- if ( !lc ) {
+ if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
* FIXME: in case of values return filter, we might want
* to map attrs and maybe rewrite value
*/
- if ( !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
- return rs->sr_err;
- }
/* should we check return values? */
if ( op->ors_deref != -1 ) {
e = ldap_first_entry( lc->lc_ld, res );
rc = ldap_build_entry( op, e, &ent, &bdn );
- if ( rc == LDAP_SUCCESS ) {
+ if ( rc == LDAP_SUCCESS ) {
rs->sr_entry = &ent;
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
ch_free( attrs );
}
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, rs, lc );
+ }
+
return rc;
}
ch_free( filter );
}
+ if ( lc != NULL ) {
+ ldap_back_release_conn( op, &rs, lc );
+ }
+
return rc;
}
#include <stdio.h>
+#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
lc_curr.lc_conn = conn;
lc_curr.lc_local_ndn = conn->c_ndn;
- ldap_pvt_thread_mutex_lock( &li->conn_mutex );
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &li->conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
lc = avl_delete( &li->conntree, (caddr_t)&lc_curr, ldap_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
if ( lc ) {
Debug( LDAP_DEBUG_TRACE,
- "=>ldap_back_conn_destroy: destroying conn %ld\n",
- lc->lc_conn->c_connid, 0, 0 );
+ "=>ldap_back_conn_destroy: destroying conn %ld (refcnt=%u)\n",
+ lc->lc_conn->c_connid, lc->lc_refcnt, 0 );
+
+ assert( lc->lc_refcnt == 0 );
/*
* Needs a test because the handler may be corrupted,
if ( oc && !is_entry_objectclass( e, oc, 0 )) {
Debug( LDAP_DEBUG_ACL,
"<= ldbm_back_entry_get: failed to find objectClass %s\n",
- oc->soc_cname, 0, 0 );
+ oc->soc_cname.bv_val, 0, 0 );
rc = LDAP_NO_SUCH_ATTRIBUTE;
goto return_results;
}
return entry;
}
-static int spew_file(int fd, char * spew) {
- int written = 0;
+static int spew_file(int fd, char * spew, int len) {
int writeres = 0;
- int len = strlen(spew);
- char * spewptr = spew;
- while(written < len) {
- writeres = write(fd, spewptr, len - written);
+ while(len > 0) {
+ writeres = write(fd, spew, len);
if(writeres == -1) {
perror("could not spew write");
return -1;
}
else {
- spewptr += writeres;
- written += writeres;
+ spew += writeres;
+ len -= writeres;
}
}
return writeres;
int entry_length;
char * entry_as_string;
- openres = open(path->bv_val, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ openres = open(path->bv_val, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR | S_IWUSR);
if(openres == -1) {
if(errno == ENOENT)
rs = LDAP_NO_SUCH_OBJECT;
close(openres);
}
else {
- spew_res = spew_file(openres, entry_as_string);
+ spew_res = spew_file(openres, entry_as_string, entry_length);
close(openres);
if(spew_res == -1)
rs = LDAP_UNWILLING_TO_PERFORM;
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
send_ldap_result( op, rs );
- return rs->sr_err;
+ goto done;
}
/* Count number of attributes in entry ( +1 ) */
BER_BVZERO( &mdn );
}
- return meta_back_op_result( mc, op, rs, candidate );
+ (void)meta_back_op_result( mc, op, rs, candidate );
+
+done:;
+ meta_back_release_conn( op, mc );
+
+ return rs->sr_err;
}
typedef struct metaconn_t {
struct slap_conn *mc_conn;
ldap_pvt_thread_mutex_t mc_mutex;
+ unsigned mc_refcnt;
/*
* means that the connection is bound;
#define META_BOUND_NONE (-1)
#define META_BOUND_ALL (-2)
/* supersedes the connection stuff */
- metasingleconn_t *mc_conns;
+ metasingleconn_t mc_conns[ 1 ];
+ /* NOTE: mc_conns must be last, because
+ * the required number of conns is malloc'ed
+ * in one block with the metaconn_t structure */
} metaconn_t;
typedef struct metatarget_t {
long int ttl; /* seconds; 0: no cache, -1: no expiry */
} metadncache_t;
+typedef struct metacandidates_t {
+ int mc_ntargets;
+ SlapReply *mc_candidates;
+} metacandidates_t;
+
typedef struct metainfo_t {
int mi_ntargets;
int mi_defaulttarget;
int mi_nretries;
metatarget_t *mi_targets;
- SlapReply *mi_candidates;
+ metacandidates_t *mi_candidates;
metadncache_t mi_cache;
Avlnode *mi_conntree;
unsigned flags;
-#if 0
-/* defined in <back-ldap/back-ldap.h> */
-#define LDAP_BACK_F_NONE 0x00U
-#define LDAP_BACK_F_SAVECRED 0x01U
-#define LDAP_BACK_F_USE_TLS 0x02U
-#define LDAP_BACK_F_PROPAGATE_TLS 0x04U
-#define LDAP_BACK_F_TLS_CRITICAL 0x08U
-#define LDAP_BACK_F_TLS_MASK (LDAP_BACK_F_USE_TLS|LDAP_BACK_F_PROPAGATE_TLS|LDAP_BACK_F_TLS_CRITICAL)
-#define LDAP_BACK_F_CHASE_REFERRALS 0x10U
-#endif
+/* uses flags as defined in <back-ldap/back-ldap.h> */
+#define META_BACK_F_ONERR_STOP 0x00010000U
+#define META_BACK_ONERR_STOP(mi) ( (mi)->flags & META_BACK_F_ONERR_STOP )
+#define META_BACK_ONERR_CONTINUE(mi) ( !META_BACK_ONERR_CONTINUE( (mi) ) )
int mi_version;
} metainfo_t;
int *candidate,
ldap_back_send_t sendok );
+extern void
+meta_back_release_conn(
+ Operation *op,
+ metaconn_t *mc );
+
extern int
meta_back_retry(
Operation *op,
ldap_back_send_t sendok );
extern void
-meta_back_conn_free( metaconn_t *mc );
+meta_back_conn_free(
+ metaconn_t *mc );
extern int
meta_back_init_one_conn(
metaconn_t *msc,
int candidate,
ldap_back_send_t sendok,
- int retries );
+ int retries,
+ int dolock );
extern int
meta_back_op_result(
#include <stdio.h>
+#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
meta_back_bind( Operation *op, SlapReply *rs )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metaconn_t *mc;
+ metaconn_t *mc = NULL;
int rc = LDAP_OTHER,
i, gotit = 0, isroot = 0;
mc->mc_auth_target = META_BOUND_ALL;
}
+ meta_back_release_conn( op, mc );
+
/*
* rc is LDAP_SUCCESS if at least one bind succeeded,
* err is the last error that occurred during a bind;
rc = slap_map_api2result( rs );
if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
- msc->msc_bound = 0;
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
+ if ( mc->mc_refcnt == 1 ) {
+ ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
+ msc->msc_ld = NULL;
+ msc->msc_bound = 0;
+
+ /* mc here must be the regular mc, reset and ready for init */
+ rc = meta_back_init_one_conn( op, rs, mt, msc,
+ LDAP_BACK_DONTSEND );
+
+ } else {
+ /* can't do anything about it */
+ rc = 0;
+ }
+
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
- /* mc here must be the regular mc, reset and ready for init */
- rc = meta_back_init_one_conn( op, rs, mt, msc,
- LDAP_BACK_DONTSEND );
if ( rc ) {
if ( nretries > 0 ) {
nretries--;
metaconn_t *mc,
int candidate,
ldap_back_send_t sendok,
- int nretries )
+ int nretries,
+ int dolock )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = &mi->mi_targets[ candidate ];
rc = slap_map_api2result( rs );
if ( rc == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
- msc->msc_bound = 0;
+ if ( dolock ) {
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+ }
+
+ if ( mc->mc_refcnt == 1 ) {
+ ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
+ msc->msc_ld = NULL;
+ msc->msc_bound = 0;
- /* mc here must be the regular mc, reset and ready for init */
- rc = meta_back_init_one_conn( op, rs, mt, msc, LDAP_BACK_DONTSEND );
+ /* mc here must be the regular mc, reset and ready for init */
+ rc = meta_back_init_one_conn( op, rs, mt, msc, LDAP_BACK_DONTSEND );
+
+
+ } else {
+ /* can't do anything about it */
+ rc = LDAP_UNAVAILABLE;
+ }
+
+ if ( dolock ) {
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+ }
if ( rc == LDAP_SUCCESS ) {
ldap_pvt_thread_yield();
}
rc = meta_back_single_dobind( op, rs, mc, i,
- LDAP_BACK_DONTSEND, mt->mt_nretries );
+ LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
if ( rc != LDAP_SUCCESS ) {
rs->sr_err = slap_map_api2result( rs );
"%s meta_back_dobind: conn=%ld bound=%d\n",
op->o_log_prefix, mc->mc_conn->c_connid, bound );
- if ( bound == 0 && ( sendok & LDAP_BACK_SENDERR ) ) {
- if ( rs->sr_err == LDAP_SUCCESS ) {
- rs->sr_err = LDAP_BUSY;
+ if ( bound == 0 ) {
+ meta_back_release_conn( op, mc );
+
+ if ( sendok & LDAP_BACK_SENDERR ) {
+ if ( rs->sr_err == LDAP_SUCCESS ) {
+ rs->sr_err = LDAP_BUSY;
+ }
+ send_ldap_result( op, rs );
}
- send_ldap_result( op, rs );
}
return( bound > 0 );
/*
* meta_back_select_unique_candidate
*
- * returns the index of the candidate in case it is unique, otherwise -1
- * Note: dn MUST be normalized.
- * Note: if defined, the default candidate is returned in case of no match.
+ * returns the index of the candidate in case it is unique, otherwise
+ * META_TARGET_NONE if none matches, or
+ * META_TARGET_MULTIPLE if more than one matches
+ * Note: ndn MUST be normalized.
*/
int
meta_back_select_unique_candidate(
meta_back_compare( Operation *op, SlapReply *rs )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metaconn_t *mc;
+ metaconn_t *mc = NULL;
char *match = NULL,
*err = NULL;
struct berval mmatch = BER_BVNULL;
msgid = ch_calloc( sizeof( int ), mi->mi_ntargets );
if ( msgid == NULL ) {
- return -1;
+ send_ldap_error( op, rs, LDAP_OTHER, NULL );
+ rc = LDAP_OTHER;
+ goto done;
}
/*
if ( msgid ) {
free( msgid );
}
-
+
+done:;
+ meta_back_release_conn( op, mc );
+
return rc;
}
/* save bind creds for referral rebinds? */
} else if ( strcasecmp( argv[ 0 ], "rebind-as-user" ) == 0 ) {
- if (argc != 1) {
+ if ( argc > 2 ) {
fprintf( stderr,
- "%s: line %d: rebind-as-user takes no arguments\n",
+ "%s: line %d: \"rebind-as-user {NO|yes}\" takes 1 argument.\n",
fname, lineno );
return( 1 );
}
- mi->flags |= LDAP_BACK_F_SAVECRED;
+ if ( argc == 1 ) {
+ fprintf( stderr,
+ "%s: line %d: deprecated use of \"rebind-as-user {NO|yes}\" with no arguments.\n",
+ fname, lineno );
+ mi->flags |= LDAP_BACK_F_SAVECRED;
+
+ } else {
+ if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+ mi->flags &= ~LDAP_BACK_F_SAVECRED;
+
+ } else if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+ mi->flags |= LDAP_BACK_F_SAVECRED;
+
+ } else {
+ fprintf( stderr,
+ "%s: line %d: \"rebind-as-user {NO|yes}\" unknown argument \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+ }
} else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ?
} else {
fprintf( stderr,
- "%s: line %d: \"chase-referrals {yes|no}\": unknown argument \"%s\".\n",
+ "%s: line %d: \"chase-referrals {YES|no}\": unknown argument \"%s\".\n",
fname, lineno, argv[ 1 ] );
return( 1 );
}
if ( argc != 2 ) {
fprintf( stderr,
- "%s: line %d: \"t-f-support {no|yes|discover}\" needs 1 argument.\n",
+ "%s: line %d: \"t-f-support {NO|yes|discover}\" needs 1 argument.\n",
fname, lineno );
return( 1 );
}
return 1;
}
+ /* onerr? */
+ } else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) {
+ if ( argc != 2 ) {
+ fprintf( stderr,
+ "%s: line %d: \"onerr {CONTINUE|stop}\" takes 1 argument\n",
+ fname, lineno );
+ return( 1 );
+ }
+
+ if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) {
+ mi->flags &= ~META_BACK_F_ONERR_STOP;
+
+ } else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) {
+ mi->flags |= META_BACK_F_ONERR_STOP;
+
+ } else {
+ fprintf( stderr,
+ "%s: line %d: \"onerr {CONTINUE|stop}\": invalid arg \"%s\".\n",
+ fname, lineno, argv[ 1 ] );
+ return 1;
+ }
+
/* name to use as pseudo-root dn */
} else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
int i = mi->mi_ntargets - 1;
#include <stdio.h>
+#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
assert( ntargets > 0 );
- /* malloc once only; leave an extra one for one-past-end */
+ /* malloc all in one */
mc = ( metaconn_t * )ch_malloc( sizeof( metaconn_t )
+ sizeof( metasingleconn_t ) * ntargets );
if ( mc == NULL ) {
return NULL;
}
- mc->mc_conns = ( metasingleconn_t * )&mc[ 1 ];
-
for ( i = 0; i < ntargets; i++ ) {
mc->mc_conns[ i ].msc_ld = NULL;
BER_BVZERO( &mc->mc_conns[ i ].msc_bound_ndn );
mc->mc_auth_target = META_BOUND_NONE;
ldap_pvt_thread_mutex_init( &mc->mc_mutex );
+ mc->mc_refcnt = 1;
return mc;
}
*
* clears a metaconn
*/
+
void
meta_back_conn_free(
metaconn_t *mc )
{
- if ( mc == NULL ) {
- return;
- }
+ assert( mc != NULL );
+ assert( mc->mc_refcnt == 0 );
ldap_pvt_thread_mutex_destroy( &mc->mc_mutex );
-
free( mc );
}
+static void
+meta_back_freeconn(
+ Operation *op,
+ metaconn_t *mc )
+{
+ metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
+
+ assert( mc != NULL );
+
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
+ if ( --mc->mc_refcnt == 0 ) {
+ meta_back_conn_free( mc );
+ }
+
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+}
+
/*
* meta_back_init_one_conn
*
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = &mi->mi_targets[ candidate ];
- int rc;
+ int rc = LDAP_UNAVAILABLE;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
- ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
- msc->msc_bound = 0;
+ assert( mc->mc_refcnt > 0 );
- /* mc here must be the regular mc, reset and ready for init */
- rc = meta_back_init_one_conn( op, rs, mt, msc, sendok );
+ if ( mc->mc_refcnt == 1 ) {
+ ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
- if ( rc == LDAP_SUCCESS ) {
- rc = meta_back_single_dobind( op, rs, mc, candidate,
- sendok, mt->mt_nretries );
- }
+ ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
+ msc->msc_ld = NULL;
+ msc->msc_bound = 0;
- ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
+ /* mc here must be the regular mc, reset and ready for init */
+ rc = meta_back_init_one_conn( op, rs, mt, msc, sendok );
+
+ if ( rc == LDAP_SUCCESS ) {
+ rc = meta_back_single_dobind( op, rs, mc, candidate,
+ sendok, mt->mt_nretries, 0 );
+ }
+
+ ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
+ }
+
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
return rc == LDAP_SUCCESS ? 1 : 0;
}
}
static void
-meta_back_candidate_keyfree(
+meta_back_candidates_keyfree(
void *key,
void *data )
{
+ metacandidates_t *mc = (metacandidates_t *)data;
+
+ ber_memfree_x( mc->mc_candidates, NULL );
ber_memfree_x( data, NULL );
}
SlapReply *
meta_back_candidates_get( Operation *op )
{
- metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- void *data = NULL;
+ metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
+ metacandidates_t *mc;
+ SlapReply *rs;
if ( op->o_threadctx ) {
+ void *data = NULL;
+
ldap_pvt_thread_pool_getkey( op->o_threadctx,
- meta_back_candidate_keyfree, &data, NULL );
+ meta_back_candidates_keyfree, &data, NULL );
+ mc = (metacandidates_t *)data;
+
} else {
- data = (void *)mi->mi_candidates;
+ mc = mi->mi_candidates;
}
- if ( data == NULL ) {
- data = ber_memalloc( sizeof( SlapReply ) * mi->mi_ntargets );
+ if ( mc == NULL ) {
+ mc = ch_calloc( sizeof( metacandidates_t ), 1 );
+ mc->mc_ntargets = mi->mi_ntargets;
+ mc->mc_candidates = ch_calloc( sizeof( SlapReply ), mc->mc_ntargets );
if ( op->o_threadctx ) {
+ void *data = NULL;
+
+ data = (void *)mc;
ldap_pvt_thread_pool_setkey( op->o_threadctx,
- meta_back_candidate_keyfree, data,
- meta_back_candidate_keyfree );
+ meta_back_candidates_keyfree, data,
+ meta_back_candidates_keyfree );
} else {
- mi->mi_candidates = (SlapReply *)data;
+ mi->mi_candidates = mc;
}
+
+ } else if ( mc->mc_ntargets < mi->mi_ntargets ) {
+ /* NOTE: in the future, may want to allow back-config
+ * to add/remove targets from back-meta... */
+ mc->mc_ntargets = mi->mi_ntargets;
+ mc->mc_candidates = ch_realloc( mc->mc_candidates,
+ sizeof( SlapReply ) * mc->mc_ntargets );
}
- return (SlapReply *)data;
+ return mc->mc_candidates;
}
/*
ldap_back_send_t sendok )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metaconn_t *mc, mc_curr;
+ metaconn_t *mc = NULL,
+ mc_curr = { 0 };
int cached = META_TARGET_NONE,
i = META_TARGET_NONE,
err = LDAP_SUCCESS,
/* Searches for a metaconn in the avl tree */
mc_curr.mc_conn = op->o_conn;
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
mc = (metaconn_t *)avl_find( mi->mi_conntree,
(caddr_t)&mc_curr, meta_back_conn_cmp );
+ if ( mc ) {
+ mc->mc_refcnt++;
+ }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
switch ( op->o_tag ) {
if ( op_type == META_OP_REQUIRE_ALL ) {
/* Looks like we didn't get a bind. Open a new session... */
- if ( !mc ) {
+ if ( mc == NULL ) {
mc = metaconn_alloc( op );
mc->mc_conn = op->o_conn;
new_conn = 1;
continue;
}
}
+
+ if ( ncandidates == 0 ) {
+ if ( new_conn ) {
+ meta_back_freeconn( op, mc );
+
+ } else {
+ meta_back_release_conn( op, mc );
+ }
+
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_text = "Unable to select valid candidates";
+
+ if ( sendok & LDAP_BACK_SENDERR ) {
+ if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
+ rs->sr_matched = op->o_bd->be_suffix[ 0 ].bv_val;
+ }
+ send_ldap_result( op, rs );
+ rs->sr_text = NULL;
+ rs->sr_matched = NULL;
+ }
+
+ return NULL;
+ }
+
goto done;
}
if ( rs->sr_err != LDAP_SUCCESS ) {
if ( sendok & LDAP_BACK_SENDERR ) {
+ if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
+ rs->sr_matched = op->o_bd->be_suffix[ 0 ].bv_val;
+ }
send_ldap_result( op, rs );
rs->sr_text = NULL;
+ rs->sr_matched = NULL;
}
return NULL;
}
"==>meta_back_getconn: got target %d for ndn=\"%s\" from cache\n",
i, op->o_req_ndn.bv_val, 0 );
- /* Retries searching for a metaconn in the avl tree */
- mc_curr.mc_conn = op->o_conn;
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
- mc = (metaconn_t *)avl_find( mi->mi_conntree,
- (caddr_t)&mc_curr, meta_back_conn_cmp );
- ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+ if ( mc == NULL ) {
+ /* Retries searching for a metaconn in the avl tree
+ * the reason is that the connection might have been
+ * created by meta_back_get_candidate() */
+ mc_curr.mc_conn = op->o_conn;
+retry_lock2:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock2;
+
+ case 0:
+ break;
+ }
+ mc = (metaconn_t *)avl_find( mi->mi_conntree,
+ (caddr_t)&mc_curr, meta_back_conn_cmp );
+ if ( mc != NULL ) {
+ mc->mc_refcnt++;
+ }
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
- /* Looks like we didn't get a bind. Open a new session... */
- if ( !mc ) {
- mc = metaconn_alloc( op );
- mc->mc_conn = op->o_conn;
- new_conn = 1;
+ /* Looks like we didn't get a bind. Open a new session... */
+ if ( mc == NULL ) {
+ mc = metaconn_alloc( op );
+ mc->mc_conn = op->o_conn;
+ new_conn = 1;
+ }
}
/*
*/
err = meta_back_init_one_conn( op, rs, &mi->mi_targets[ i ],
&mc->mc_conns[ i ], sendok );
- if ( err == LDAP_SUCCESS ) {
- candidates[ i ].sr_tag = META_CANDIDATE;
- ncandidates++;
-
- } else {
-
+ if ( err != LDAP_SUCCESS ) {
/*
* FIXME: in case one target cannot
* be init'd, should the other ones
*/
candidates[ i ].sr_tag = META_NOT_CANDIDATE;
if ( new_conn ) {
- ( void )meta_clear_one_candidate( &mc->mc_conns[ i ] );
- meta_back_conn_free( mc );
+ (void)meta_clear_one_candidate( &mc->mc_conns[ i ] );
+ meta_back_freeconn( op, mc );
+
+ } else {
+ meta_back_release_conn( op, mc );
}
return NULL;
}
+ candidates[ i ].sr_tag = META_CANDIDATE;
+ ncandidates++;
+
if ( candidate ) {
*candidate = i;
}
} else {
/* Looks like we didn't get a bind. Open a new session... */
- if ( !mc ) {
+ if ( mc == NULL ) {
mc = metaconn_alloc( op );
mc->mc_conn = op->o_conn;
new_conn = 1;
if ( ncandidates == 0 ) {
if ( new_conn ) {
- meta_back_conn_free( mc );
+ meta_back_freeconn( op, mc );
+
+ } else {
+ meta_back_release_conn( op, mc );
}
rs->sr_err = LDAP_NO_SUCH_OBJECT;
rs->sr_text = "Unable to select valid candidates";
if ( sendok & LDAP_BACK_SENDERR ) {
+ if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
+ rs->sr_matched = op->o_bd->be_suffix[ 0 ].bv_val;
+ }
send_ldap_result( op, rs );
rs->sr_text = NULL;
+ rs->sr_matched = NULL;
}
return NULL;
/*
* Inserts the newly created metaconn in the avl tree
*/
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+retry_lock3:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock3;
+
+ case 0:
+ break;
+ }
err = avl_insert( &mi->mi_conntree, ( caddr_t )mc,
meta_back_conn_cmp, meta_back_conn_dup );
/*
* Err could be -1 in case a duplicate metaconn is inserted
+ *
+ * FIXME: what if the same client issues more than one
+ * asynchronous operations?
*/
- if ( err == 0 ) {
- Debug( LDAP_DEBUG_TRACE,
- "%s meta_back_getconn: candidates=%d conn=%ld inserted\n",
- op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
-
- } else {
+ if ( err != 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s meta_back_getconn: candidates=%d conn=%ld insert failed\n",
op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "Internal server error";
- meta_back_conn_free( mc );
+ meta_back_freeconn( op, mc );
if ( sendok & LDAP_BACK_SENDERR ) {
send_ldap_result( op, rs );
rs->sr_text = NULL;
return NULL;
}
+ Debug( LDAP_DEBUG_TRACE,
+ "%s meta_back_getconn: candidates=%d conn=%ld inserted\n",
+ op->o_log_prefix, ncandidates, mc->mc_conn->c_connid );
+
} else {
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_getconn: candidates=%d conn=%ld fetched\n",
return mc;
}
+void
+meta_back_release_conn(
+ Operation *op,
+ metaconn_t *mc )
+{
+ metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
+
+ assert( mc != NULL );
+
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
+ assert( mc->mc_refcnt > 0 );
+ mc->mc_refcnt--;
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+}
meta_back_delete( Operation *op, SlapReply *rs )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
- metaconn_t *mc;
+ metaconn_t *mc = NULL;
int candidate = -1;
struct berval mdn = BER_BVNULL;
dncookie dc;
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
send_ldap_result( op, rs );
- return -1;
+ goto done;
}
retry:;
BER_BVZERO( &mdn );
}
- return meta_back_op_result( mc, op, rs, candidate );
+ rs->sr_err = meta_back_op_result( mc, op, rs, candidate );
+
+done:;
+ meta_back_release_conn( op, mc );
+
+ return rs->sr_err;
}
int i, rc;
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- if ( mi->mi_targets[ i ].mt_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) {
+ if ( mi->mi_targets[ i ].mt_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER )
+ {
mi->mi_targets[ i ].mt_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
rc = slap_discover_feature( mi->mi_targets[ i ].mt_uri,
mi->mi_targets[ i ].mt_version,
ber_memfree( vtmp.bv_val );
break;
- case SLAPD_FILTER_COMPUTED:
+ case SLAPD_FILTER_COMPUTED: {
+ struct berval bv;
+
switch ( f->f_result ) {
case LDAP_COMPARE_FALSE:
if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) {
- ber_str2bv( "(|)", STRLENOF( "(|)" ), 1, fstr );
-
- } else {
-#if 0
- ber_str2bv( "(?=false)", STRLENOF( "(?=false)" ), 1, fstr );
-#endif
- /* better than nothing... */
- ber_str2bv( "(!(objectClass=*))", STRLENOF( "(!(objectClass=*))" ), 1, fstr );
+ BER_BVSTR( &bv, "(|)" );
+ break;
}
+ /* fallthru */
+
+ /* FIXME: treat UNDEFINED as FALSE */
+ case SLAPD_COMPARE_UNDEFINED:
+ /* better than nothing... */
+ BER_BVSTR( &bv, "(!(objectClass=*))" );
break;
case LDAP_COMPARE_TRUE:
if ( dc->target->mt_flags & LDAP_BACK_F_SUPPORT_T_F ) {
- ber_str2bv( "(&)", STRLENOF( "(&)" ), 1, fstr );
-
- } else {
-#if 0
- ber_str2bv( "(?=true)", STRLENOF( "(?=true)" ), 1, fstr );
-#endif
- /* better than nothing... */
- ber_str2bv( "(objectClass=*)", STRLENOF( "(objectClass=*)" ), 1, fstr );
+ BER_BVSTR( &bv, "(&)" );
+ break;
}
- break;
- case SLAPD_COMPARE_UNDEFINED:
- ber_str2bv( "(?=undefined)", STRLENOF( "(?=undefined)" ), 1, fstr );
+ /* better than nothing... */
+ BER_BVSTR( &bv, "(objectClass=*)" );
break;
default:
- ber_str2bv( "(?=error)", STRLENOF( "(?=error)" ), 1, fstr );
+ BER_BVSTR( &bv, "(?=error)" );
break;
}
- break;
+
+ ber_dupbv( fstr, &bv );
+ } break;
default:
ber_str2bv( "(?=unknown)", STRLENOF( "(?=unknown)" ), 1, fstr );
free( modv );
if ( rc != -1 ) {
- return meta_back_op_result( mc, op, rs, candidate );
+ rc = meta_back_op_result( mc, op, rs, candidate );
+
+ } else {
+ send_ldap_result( op, rs );
+ rc = 0;
}
-
- send_ldap_result( op, rs );
- return rs->sr_err;
+ meta_back_release_conn( op, mc );
+
+ return rc;
}
send_ldap_result( op, rs );
+ meta_back_release_conn( op, mc );
+
return rs->sr_err;
}
if ( candidates[ i ].sr_tag != META_CANDIDATE ) {
continue;
}
+
candidates[ i ].sr_err = LDAP_SUCCESS;
candidates[ i ].sr_matched = NULL;
candidates[ i ].sr_text = NULL;
0, &tv, &res );
if ( rc == 0 ) {
- /* timeout exceeded */
-
/* FIXME: res should not need to be freed */
assert( res == NULL );
(char **)&candidates[ i ].sr_matched,
NULL /* (char **)&candidates[ i ].sr_text */ ,
&references,
- &candidates[ i ].sr_ctrls, 1 ) )
+ &candidates[ i ].sr_ctrls, 1 ) != LDAP_SUCCESS )
{
res = NULL;
ldap_get_option( msc->msc_ld,
sres = slap_map_api2result( rs );
goto really_bad;
}
+
rs->sr_err = candidates[ i ].sr_err;
sres = slap_map_api2result( rs );
res = NULL;
rs->sr_err = candidates[ i ].sr_err;
sres = slap_map_api2result( rs );
+
+ snprintf( buf, sizeof( buf ),
+ "%s meta_back_search[%d] "
+ "match=\"%s\" err=%d\n",
+ op->o_log_prefix, i,
+ candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
+ candidates[ i ].sr_err );
+ Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
+
switch ( sres ) {
case LDAP_NO_SUCH_OBJECT:
/* is_ok is touched any time a valid
case LDAP_REFERRAL:
is_ok++;
break;
- }
- snprintf( buf, sizeof( buf ),
- "%s meta_back_search[%d] "
- "match=\"%s\" err=%d\n",
- op->o_log_prefix, i,
- candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
- candidates[ i ].sr_err );
- Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
+ default:
+ if ( META_BACK_ONERR_STOP( mi ) ) {
+ savepriv = op->o_private;
+ op->o_private = (void *)i;
+ send_ldap_result( op, rs );
+ op->o_private = savepriv;
+ goto finish;
+ }
+ break;
+ }
last = i;
rc = 0;
}
}
+ meta_back_release_conn( op, mc );
+
return rc;
}
#include <stdio.h>
+#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
-#include <ac/errno.h>
#include "slap.h"
#include "../back-ldap/back-ldap.h"
Connection *conn )
{
metainfo_t *mi = ( metainfo_t * )be->be_private;
- metaconn_t *mc,
+ metaconn_t *mc,
mc_curr = { 0 };
Debug( LDAP_DEBUG_TRACE,
mc_curr.mc_conn = conn;
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+retry_lock:;
+ switch ( ldap_pvt_thread_mutex_trylock( &mi->mi_conn_mutex ) ) {
+ case LDAP_PVT_THREAD_EBUSY:
+ default:
+ ldap_pvt_thread_yield();
+ goto retry_lock;
+
+ case 0:
+ break;
+ }
+
mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
meta_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
"=>meta_back_conn_destroy: destroying conn %ld\n",
mc->mc_conn->c_connid, 0, 0 );
+ assert( mc->mc_refcnt == 0 );
+
/*
* Cleanup rewrite session
*/
for ( i = 0; i < mi->mi_ntargets; ++i ) {
- if ( mc->mc_conns[ i ].msc_ld == NULL ) {
- continue;
- }
-
rewrite_session_delete( mi->mi_targets[ i ].mt_rwmap.rwm_rw, conn );
- meta_clear_one_candidate( &mc->mc_conns[ i ] );
+
+ if ( mc->mc_conns[ i ].msc_ld != NULL ) {
+ meta_clear_one_candidate( &mc->mc_conns[ i ] );
+ }
}
meta_back_conn_free( mc );
}
#if 0 /* needs improvements */
LDAP_CONTROL_NOOP,
#endif
-#ifdef LDAP_CONTROL_X_TREE_DELETE
- LDAP_CONTROL_X_TREE_DELETE,
-#endif /* LDAP_CONTROL_X_TREE_DELETE */
+#ifdef SLAP_CONTROL_X_TREE_DELETE
+ SLAP_CONTROL_X_TREE_DELETE,
+#endif /* SLAP_CONTROL_X_TREE_DELETE */
NULL
};
LDAP_STAILQ_FOREACH( be, &backendDB, be_next ) {
if ( be->be_connection_init ) {
- be->be_connection_init( be, conn);
+ be->be_connection_init( be, conn );
}
}
return rc;
}
-enum op_which {
- op_bind = 0,
- op_unbind,
- op_search,
- op_compare,
- op_modify,
- op_modrdn,
- op_add,
- op_delete,
- op_abandon,
- op_cancel,
- op_extended,
- op_aux_operational,
- op_aux_chk_referrals,
- op_aux_chk_controls,
- op_last
-};
-
-/*
- * default return code in case of missing backend function
- * and overlay stack returning SLAP_CB_CONTINUE
- */
-static int op_rc[] = {
- LDAP_UNWILLING_TO_PERFORM, /* bind */
- LDAP_UNWILLING_TO_PERFORM, /* unbind */
- LDAP_UNWILLING_TO_PERFORM, /* search */
- SLAP_CB_CONTINUE, /* compare; pass to frontend */
- LDAP_UNWILLING_TO_PERFORM, /* modify */
- LDAP_UNWILLING_TO_PERFORM, /* modrdn */
- LDAP_UNWILLING_TO_PERFORM, /* add */
- LDAP_UNWILLING_TO_PERFORM, /* delete */
- LDAP_UNWILLING_TO_PERFORM, /* abandon */
- LDAP_UNWILLING_TO_PERFORM, /* cancel */
- LDAP_UNWILLING_TO_PERFORM, /* extended */
- LDAP_SUCCESS, /* aux_operational */
- LDAP_SUCCESS, /* aux_chk_referrals */
- SLAP_CB_CONTINUE /* aux_chk_controls; pass to frontend */
-};
-
#ifdef SLAP_OVERLAY_ACCESS
static int
over_access_allowed(
}
#endif /* SLAP_OVERLAY_ACCESS */
+enum op_which {
+ op_bind = 0,
+ op_unbind,
+ op_search,
+ op_compare,
+ op_modify,
+ op_modrdn,
+ op_add,
+ op_delete,
+ op_abandon,
+ op_cancel,
+ op_extended,
+ op_aux_operational,
+ op_aux_chk_referrals,
+ op_aux_chk_controls,
+ op_last
+};
+
+/*
+ * default return code in case of missing backend function
+ * and overlay stack returning SLAP_CB_CONTINUE
+ */
+static int op_rc[] = {
+ LDAP_UNWILLING_TO_PERFORM, /* bind */
+ LDAP_UNWILLING_TO_PERFORM, /* unbind */
+ LDAP_UNWILLING_TO_PERFORM, /* search */
+ SLAP_CB_CONTINUE, /* compare; pass to frontend */
+ LDAP_UNWILLING_TO_PERFORM, /* modify */
+ LDAP_UNWILLING_TO_PERFORM, /* modrdn */
+ LDAP_UNWILLING_TO_PERFORM, /* add */
+ LDAP_UNWILLING_TO_PERFORM, /* delete */
+ LDAP_UNWILLING_TO_PERFORM, /* abandon */
+ LDAP_UNWILLING_TO_PERFORM, /* cancel */
+ LDAP_UNWILLING_TO_PERFORM, /* extended */
+ LDAP_SUCCESS, /* aux_operational */
+ LDAP_SUCCESS, /* aux_chk_referrals */
+ SLAP_CB_CONTINUE /* aux_chk_controls; pass to frontend */
+};
+
static int
over_op_func(
Operation *op,
return over_op_func( op, rs, op_aux_chk_controls );
}
+enum conn_which {
+ conn_init = 0,
+ conn_destroy
+};
+
static int
-over_connection_destroy(
+over_connection_func(
BackendDB *bd,
- Connection *conn
+ Connection *conn,
+ enum conn_which which
)
{
- slap_overinfo *oi;
- slap_overinst *on;
- BackendDB db;
- int rc = SLAP_CB_CONTINUE;
+ slap_overinfo *oi;
+ slap_overinst *on;
+ BackendDB db;
+ int rc = SLAP_CB_CONTINUE;
+ BI_connection_init **func;
/* FIXME: used to happen for instance during abandon
* when global overlays are used... */
oi = bd->bd_info->bi_private;
on = oi->oi_list;
- if ( !SLAP_ISOVERLAY( bd )) {
+ if ( !SLAP_ISOVERLAY( bd ) ) {
db = *bd;
db.be_flags |= SLAP_DBFLAG_OVERLAY;
bd = &db;
}
- for (; on; on=on->on_next ) {
- if ( on->on_bi.bi_connection_destroy ) {
+ for ( ; on; on = on->on_next ) {
+ func = &on->on_bi.bi_connection_init;
+ if ( func[ which ] ) {
bd->bd_info = (BackendInfo *)on;
- rc = on->on_bi.bi_connection_destroy( bd, conn );
+ rc = func[ which ]( bd, conn );
if ( rc != SLAP_CB_CONTINUE ) break;
}
}
- if ( oi->oi_orig->bi_connection_destroy && rc == SLAP_CB_CONTINUE ) {
+ func = &oi->oi_orig->bi_connection_init;
+ if ( func[ which ] && rc == SLAP_CB_CONTINUE ) {
bd->bd_info = oi->oi_orig;
- rc = oi->oi_orig->bi_connection_destroy( bd, conn );
+ rc = func[ which ]( bd, conn );
}
/* should not fall thru this far without anything happening... */
if ( rc == SLAP_CB_CONTINUE ) {
return rc;
}
+static int
+over_connection_init(
+ BackendDB *bd,
+ Connection *conn
+)
+{
+ return over_connection_func( bd, conn, conn_init );
+}
+
+static int
+over_connection_destroy(
+ BackendDB *bd,
+ Connection *conn
+)
+{
+ return over_connection_func( bd, conn, conn_destroy );
+}
+
int
overlay_register(
slap_overinst *on
bi->bi_access_allowed = over_access_allowed;
#endif /* SLAP_OVERLAY_ACCESS */
+ bi->bi_connection_init = over_connection_init;
bi->bi_connection_destroy = over_connection_destroy;
be->bd_info = bi;
CFG_SASLSECP,
CFG_SSTR_IF_MAX,
CFG_SSTR_IF_MIN,
+
+ CFG_LAST
};
typedef struct {
"DESC 'File for slapd command line options' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "attributeoptions", NULL, 0, 0, 0, ARG_MAGIC|CFG_ATOPT,
+ &config_generic, "( OLcfgGlAt:5 NAME 'olcAttributeOptions' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
{ "attribute", "attribute", 2, 0, 9,
ARG_PAREN|ARG_MAGIC|CFG_ATTR|ARG_NO_DELETE|ARG_NO_INSERT,
&config_generic, "( OLcfgGlAt:4 NAME 'olcAttributeTypes' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )",
NULL, NULL },
- { "attributeoptions", NULL, 0, 0, 0, ARG_MAGIC|CFG_ATOPT,
- &config_generic, "( OLcfgGlAt:5 NAME 'olcAttributeOptions' "
- "EQUALITY caseIgnoreMatch "
- "SYNTAX OMsDirectoryString )", NULL, NULL },
{ "authid-rewrite", NULL, 2, 0, STRLENOF( "authid-rewrite" ),
#ifdef SLAP_AUTH_REWRITE
ARG_MAGIC|CFG_REWRITE|ARG_NO_INSERT, &config_generic,
&config_generic, "( OLcfgGlAt:13 NAME 'olcDatabase' "
"DESC 'The backend type for a database instance' "
"SUP olcBackend SINGLE-VALUE X-ORDERED 'SIBLINGS' )", NULL, NULL },
- { "defaultSearchBase", "dn", 2, 2, 0, ARG_PRE_BI|ARG_PRE_DB|ARG_DN|ARG_MAGIC,
+ { "defaultSearchBase", "dn", 2, 2, 0, ARG_PRE_BI|ARG_PRE_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_search_base, "( OLcfgGlAt:14 NAME 'olcDefaultSearchBase' "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
{ "disallows", "features", 2, 0, 8, ARG_PRE_DB|ARG_MAGIC,
{ "index_substr_any_len", "len", 2, 2, 0, ARG_INT|ARG_NONZERO,
&index_substr_any_len, "( OLcfgGlAt:22 NAME 'olcIndexSubstrAnyLen' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
- { "index_substr_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO,
+ { "index_substr_any_step", "step", 2, 2, 0, ARG_INT|ARG_NONZERO,
&index_substr_any_step, "( OLcfgGlAt:23 NAME 'olcIndexSubstrAnyStep' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
{ "lastmod", "on|off", 2, 2, 0, ARG_DB|ARG_ON_OFF|ARG_MAGIC|CFG_LASTMOD,
#endif
"( OLcfgGlAt:49 NAME 'olcReverseLookup' "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
- { "rootdn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_MAGIC,
+ { "rootdn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_rootdn, "( OLcfgDbAt:0.8 NAME 'olcRootDN' "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
{ "rootDSE", "file", 2, 2, 0, ARG_MAGIC|CFG_ROOTDSE,
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "saslRegexp", NULL, 3, 3, 0, ARG_MAGIC|CFG_AZREGEXP,
&config_generic, NULL, NULL, NULL },
- { "schemadn", "dn", 2, 2, 0, ARG_MAY_DB|ARG_DN|ARG_MAGIC,
+ { "schemadn", "dn", 2, 2, 0, ARG_MAY_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_schema_dn, "( OLcfgGlAt:58 NAME 'olcSchemaDN' "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
{ "security", "factors", 2, 0, 0, ARG_MAY_DB|ARG_MAGIC,
#endif
"( OLcfgGlAt:63 NAME 'olcSrvtab' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
- { "suffix", "suffix", 2, 2, 0, ARG_DB|ARG_DN|ARG_MAGIC,
+ { "suffix", "suffix", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_suffix, "( OLcfgDbAt:0.10 NAME 'olcSuffix' "
"SYNTAX OMsDN )", NULL, NULL },
{ "syncrepl", NULL, 0, 0, 0, ARG_DB|ARG_MAGIC,
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "ucdata-path", "path", 2, 2, 0, ARG_IGNORED,
NULL, NULL, NULL, NULL },
- { "updatedn", "dn", 2, 2, 0, ARG_DB|ARG_MAGIC,
+ { "updatedn", "dn", 2, 2, 0, ARG_DB|ARG_DN|ARG_QUOTE|ARG_MAGIC,
&config_updatedn, "( OLcfgDbAt:0.12 NAME 'olcUpdateDN' "
"SYNTAX OMsDN SINGLE-VALUE )", NULL, NULL },
{ "updateref", "url", 2, 2, 0, ARG_DB|ARG_MAGIC,
if ( !c->rvalue_vals ) rc = 1;
break;
case CFG_RO:
- c->value_int = (c->be->be_restrictops & SLAP_RESTRICT_OP_WRITES) != 0;
+ c->value_int = (c->be->be_restrictops & SLAP_RESTRICT_OP_WRITES) ==
+ SLAP_RESTRICT_OP_WRITES;
break;
case CFG_AZPOLICY:
c->value_string = ch_strdup( slap_sasl_getpolicy());
if ( idx ) ca->line = idx+1;
}
rc = config_parse_vals( ct, ca, i );
- if ( rc )
+ if ( rc ) {
break;
+ }
}
return rc;
}
Debug(LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
ca->log, ca->msg, ca->argv[1] );
rc = LDAP_OTHER;
- if ( colst[0]->co_type == Cft_Database )
- backend_destroy_one( ca->be );
- else
- overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
goto leave;
}
}
}
leave:
+ if ( rc ) {
+ if ( (colst[0]->co_type == Cft_Database) && ca->be ) {
+ backend_destroy_one( ca->be );
+ } else if ( (colst[0]->co_type == Cft_Overlay) && ca->bi ) {
+ overlay_destroy_one( ca->be, (slap_overinst *)ca->bi );
+ }
+ }
+
ch_free( ca->argv );
if ( colst ) ch_free( colst );
return rc;
bi->bi_tool_entry_get = config_tool_entry_get;
bi->bi_tool_entry_put = config_tool_entry_put;
+ /* Make sure we don't exceed the bits reserved for userland */
+ assert( ( ( CFG_LAST - 1 ) & ARGS_USERLAND ) == ( CFG_LAST - 1 ) );
+
argv[3] = NULL;
for (i=0; OidMacros[i].name; i++ ) {
argv[1] = OidMacros[i].name;
send_ldap_result( op, rs );
Debug( LDAP_DEBUG_TRACE,
- "do_bind: v%d unknown authentication method (%ld)\n",
+ "do_bind: v%d unknown authentication method (%d)\n",
op->o_protocol, op->orb_method, 0 );
goto cleanup;
}
type = peek_componentId_type( cav );
- Debug( LDAP_DEBUG_FILTER, "get_compId [%d]\n", type, 0, 0 );
+ Debug( LDAP_DEBUG_FILTER, "get_compId [%lu]\n",
+ (unsigned long) type, 0, 0 );
len = 0;
_cid.ci_type = type;
_cid.ci_next = NULL;
c->argc = argc;
c->argv = argv;
c->lineno = lineno;
- snprintf( c->log, sizeof( c->log ), "%s: line %lu", fname, lineno );
+ snprintf( c->log, sizeof( c->log ), "%s: line %d", fname, lineno );
return(c);
}
int
config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx)
{
- int rc = 0;
+ int rc = 0;
+ char *saveline = NULL;
snprintf( c->log, sizeof( c->log ), "%s: value #%d",
ct->ad->ad_cname.bv_val, valx );
c->argc = 1;
c->argv[0] = ct->ad->ad_cname.bv_val;
+
+ if ( ( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) {
+ ber_len_t len;
+
+ saveline = c->line;
+ len = strlen( c->line );
+ c->line = ch_malloc( len + STRLENOF( "\"\"" ) + 1 );
+ sprintf( c->line, "\"%s\"", saveline );
+ }
+
if ( fp_parse_line( c ) ) {
rc = 1;
} else {
rc = config_check_vals( ct, c, 1 );
}
+
+ if ( saveline ) {
+ ch_free( c->line );
+ c->line = saveline;
+ }
+
if ( rc )
rc = LDAP_CONSTRAINT_VIOLATION;
int
config_parse_add(ConfigTable *ct, ConfigArgs *c)
{
- int rc = 0;
+ int rc = 0;
+ char *saveline = NULL;
snprintf( c->log, sizeof( c->log ), "%s: value #%d",
ct->ad->ad_cname.bv_val, c->valx );
c->argc = 1;
c->argv[0] = ct->ad->ad_cname.bv_val;
+
+ if ( ( ct->arg_type & ARG_QUOTE ) && c->line[ 0 ] != '"' ) {
+ ber_len_t len;
+
+ saveline = c->line;
+ len = strlen( c->line );
+
+ c->line = ch_malloc( len + STRLENOF( "\"\"" ) + 1 );
+ sprintf( c->line, "\"%s\"", saveline );
+ }
+
if ( fp_parse_line( c ) ) {
rc = 1;
} else {
rc = config_add_vals( ct, c );
}
+ if ( saveline ) {
+ ch_free( c->line );
+ c->line = saveline;
+ }
+
ch_free( c->tline );
return rc;
}
c.argc = argc;
c.argv = argv;
c.valx = -1;
- sprintf( c.log, "%s: line %lu", fname, lineno );
+ sprintf( c.log, "%s: line %d", fname, lineno );
rc = SLAP_CONF_UNKNOWN;
ct = config_find_keyword( be->be_cf_ocs->co_table, &c );
#define ARG_NO_INSERT 0x04000000 /* no arbitrary inserting */
#define ARG_NO_DELETE 0x08000000 /* no runtime deletes */
#define ARG_UNIQUE 0x10000000
+#define ARG_QUOTE 0x20000000 /* wrap with quotes before parsing */
#define ARG_OFFSET 0x40000000
#define ARG_MAGIC 0x80000000
* already pending ops, let them go first. Abandon operations
* get exceptions to some, but not all, cases.
*/
- if (tag != LDAP_REQ_ABANDON && conn->c_conn_state == SLAP_C_CLOSING) {
- defer = "closing";
- } else if (tag != LDAP_REQ_ABANDON && conn->c_writewaiter) {
- defer = "awaiting write";
- } else if (conn->c_n_ops_executing >= connection_pool_max/2) {
- defer = "too many executing";
- } else if (conn->c_conn_state == SLAP_C_BINDING) {
- defer = "binding";
- } else if (tag != LDAP_REQ_ABANDON && conn->c_n_ops_pending) {
- defer = "pending operations";
+ switch( tag ){
+ default:
+ /* Abandon and Unbind are exempt from these checks */
+ if (conn->c_conn_state == SLAP_C_CLOSING) {
+ defer = "closing";
+ break;
+ } else if (conn->c_writewaiter) {
+ defer = "awaiting write";
+ break;
+ } else if (conn->c_n_ops_pending) {
+ defer = "pending operations";
+ break;
+ }
+ /* FALLTHRU */
+ case LDAP_REQ_ABANDON:
+ /* Unbind is exempt from these checks */
+ if (conn->c_n_ops_executing >= connection_pool_max/2) {
+ defer = "too many executing";
+ break;
+ } else if (conn->c_conn_state == SLAP_C_BINDING) {
+ defer = "binding";
+ break;
+ }
+ /* FALLTHRU */
+ case LDAP_REQ_UNBIND:
+ break;
}
if( defer ) {
static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
static SLAP_CTRL_PARSE_FN parsePermissiveModify;
static SLAP_CTRL_PARSE_FN parseDomainScope;
+#ifdef SLAP_CONTROL_X_TREE_DELETE
static SLAP_CTRL_PARSE_FN parseTreeDelete;
+#endif
static SLAP_CTRL_PARSE_FN parseSearchOptions;
static SLAP_CTRL_PARSE_FN parseSubentries;
}
#endif
-#ifdef LDAP_CONTROL_X_TREE_DELETE
+#ifdef SLAP_CONTROL_X_TREE_DELETE
static int parseTreeDelete (
Operation *op,
SlapReply *rs,
if( getpeereid( s, &uid, &gid ) == 0 ) {
authid.bv_val = ch_malloc(
- sizeof("uidnumber=4294967295+gidnumber=4294967295,"
- "cn=peercred,cn=external,cn=auth"));
+ STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
+ "cn=peercred,cn=external,cn=auth" ) + 1 );
authid.bv_len = sprintf( authid.bv_val,
- "uidnumber=%d+gidnumber=%d,"
+ "gidNumber=%d+uidNumber=%d,"
"cn=peercred,cn=external,cn=auth",
- (int) uid, (int) gid);
+ (int) gid, (int) uid );
+ assert( authid.bv_len <=
+ STRLENOF( "gidNumber=4294967295+uidNumber=4294967295,"
+ "cn=peercred,cn=external,cn=auth" ) );
}
}
dnsname = "local";
close_listeners ( 0 );
}
- free ( slap_listeners );
- slap_listeners = NULL;
-
if( !slapd_gentle_shutdown ) {
slapd_abrupt_shutdown = 1;
connections_shutdown();
ldap_pvt_thread_pool_backload(&connection_pool), 0, 0 );
ldap_pvt_thread_pool_destroy(&connection_pool, 1);
+ free ( slap_listeners );
+ slap_listeners = NULL;
+
return NULL;
}
if( err != LDAP_SUCCESS ) {
/* unrecognized attribute description or other error */
Debug( LDAP_DEBUG_ANY,
- "get_filter: conn %d unknown attribute "
+ "get_filter: conn %lu unknown attribute "
"type=%s (%d)\n",
op->o_connid, type.bv_val, err );
if( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
- "get_ssa: conn %d unknown attribute type=%s (%d)\n",
- op->o_connid, desc.bv_val, rc );
+ "get_ssa: conn %lu unknown attribute type=%s (%ld)\n",
+ op->o_connid, desc.bv_val, (long) rc );
/* skip over the rest of this filter */
for ( tag = ber_first_element( ber, &len, &last );
switch ( tag ) {
case LDAP_SUBSTRING_INITIAL:
+ if ( ssa.sa_initial.bv_val != NULL
+ || ssa.sa_any != NULL
+ || ssa.sa_final.bv_val != NULL )
+ {
+ rc = LDAP_PROTOCOL_ERROR;
+ goto return_error;
+ }
usage = SLAP_MR_SUBSTR_INITIAL;
break;
case LDAP_SUBSTRING_ANY:
+ if ( ssa.sa_final.bv_val != NULL ) {
+ rc = LDAP_PROTOCOL_ERROR;
+ goto return_error;
+ }
usage = SLAP_MR_SUBSTR_ANY;
break;
case LDAP_SUBSTRING_FINAL:
+ if ( ssa.sa_final.bv_val != NULL ) {
+ rc = LDAP_PROTOCOL_ERROR;
+ goto return_error;
+ }
+
usage = SLAP_MR_SUBSTR_FINAL;
break;
default:
- rc = LDAP_PROTOCOL_ERROR;
-
Debug( LDAP_DEBUG_FILTER,
" unknown substring choice=%ld\n",
(long) tag, 0, 0 );
+ rc = LDAP_PROTOCOL_ERROR;
goto return_error;
}
rc = asserted_value_validate_normalize(
ssa.sa_desc, ssa.sa_desc->ad_type->sat_equality,
usage, &value, &nvalue, text, op->o_tmpmemctx );
-
- if( rc != LDAP_SUCCESS ) {
- goto return_error;
- }
-
- rc = LDAP_PROTOCOL_ERROR;
+ if( rc != LDAP_SUCCESS ) goto return_error;
switch ( tag ) {
case LDAP_SUBSTRING_INITIAL:
Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 );
-
- if ( ssa.sa_initial.bv_val != NULL
- || ssa.sa_any != NULL
- || ssa.sa_final.bv_val != NULL )
- {
- slap_sl_free( nvalue.bv_val, op->o_tmpmemctx );
- goto return_error;
- }
-
ssa.sa_initial = nvalue;
break;
case LDAP_SUBSTRING_ANY:
Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 );
-
- if ( ssa.sa_final.bv_val != NULL ) {
- slap_sl_free( nvalue.bv_val, op->o_tmpmemctx );
- goto return_error;
- }
-
ber_bvarray_add_x( &ssa.sa_any, &nvalue, op->o_tmpmemctx );
break;
case LDAP_SUBSTRING_FINAL:
Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 );
-
- if ( ssa.sa_final.bv_val != NULL ) {
- slap_sl_free( nvalue.bv_val, op->o_tmpmemctx );
- goto return_error;
- }
-
ssa.sa_final = nvalue;
break;
default:
- Debug( LDAP_DEBUG_FILTER,
- " unknown substring type=%ld\n",
- (long) tag, 0, 0 );
-
assert( 0 );
slap_sl_free( nvalue.bv_val, op->o_tmpmemctx );
+ rc = LDAP_PROTOCOL_ERROR;
return_error:
Debug( LDAP_DEBUG_FILTER, " error=%ld\n",
}
Debug( LDAP_DEBUG_FILTER, "end get_ssa\n", 0, 0, 0 );
-
return rc /* LDAP_SUCCESS */ ;
}
if( err != LDAP_SUCCESS ) {
/* unrecognized attribute description or other error */
Debug( LDAP_DEBUG_ANY,
- "get_simple_vrFilter: conn %d unknown "
+ "get_simple_vrFilter: conn %lu unknown "
"attribute type=%s (%d)\n",
op->o_connid, type.bv_val, err );
/* info */
frontendDB->bd_info = &slap_frontendInfo;
+ SLAP_BFLAGS(frontendDB) |= SLAP_BFLAG_FRONTEND;
+
/* name */
frontendDB->bd_info->bi_type = "frontend";
switch ( slapMode & SLAP_MODE ) {
case SLAP_SERVER_MODE:
+ ldap_pvt_thread_pool_init( &connection_pool,
+ connection_pool_max, 0);
+
+ /* FALLTHRU */
case SLAP_TOOL_MODE:
Debug( LDAP_DEBUG_TRACE,
"%s init: initiated %s.\n", name,
(mode & SLAP_MODE) == SLAP_TOOL_MODE ? "tool" : "server",
0 );
-
slap_name = name;
- ldap_pvt_thread_pool_init( &connection_pool,
- connection_pool_max, 0);
-
ldap_pvt_thread_mutex_init( &entry2str_mutex );
ldap_pvt_thread_mutex_init( &replog_mutex );
Attribute *a;
/* The backend wants to take care of it */
- if ( be && be!= frontendDB && be->be_schemadn.bv_val ) return NULL;
+ if ( be && !SLAP_FRONTEND(be) && be->be_schemadn.bv_val ) return NULL;
a = ch_malloc( sizeof( Attribute ) );
a->a_desc = slap_schema.si_ad_subschemaSubentry;
pcache.c \
ppolicy.c \
refint.c \
+ retcode.c \
rwm.c rwmconf.c rwmdn.c rwmmap.c \
syncprov.c \
translucent.c \
refint.la : refint.lo
$(LTLINK_MOD) -module -o $@ refint.lo version.lo $(LINK_LIBS)
+retcode.la : retcode.lo
+ $(LTLINK_MOD) -module -o $@ retcode.lo version.lo $(LINK_LIBS)
+
rwm_x.o: rwm.o rwmconf.o rwmdn.o rwmmap.o
$(LD) -r -o $@ rwm.o rwmconf.o rwmdn.o rwmmap.o
attr_merge_one( e, ad_reqType, &lo->word, NULL );
}
- rdn.bv_len = sprintf( rdn.bv_val, "%d", op->o_connid );
+ rdn.bv_len = sprintf( rdn.bv_val, "%lu", op->o_connid );
attr_merge_one( e, ad_reqSession, &rdn, NULL );
if ( BER_BVISNULL( &op->o_dn ))
log_info *li = on->on_bi.bi_private;
free( li );
+ return LDAP_SUCCESS;
}
int accesslog_init()
)
{
BackendDB *b0, b2;
- int rc;
+ int rc = -1;
b0 = op->o_bd;
b2 = *op->o_bd;
b2.bd_info = (BackendInfo *)glue_tool_inst( op->o_bd->bd_info );
op->o_bd = glue_back_select (&b2, &e->e_nname);
- rc = op->o_bd->be_release( op, e, rw );
+ if ( op->o_bd->be_release ) {
+ rc = op->o_bd->be_release( op, e, rw );
+
+ } else {
+ /* FIXME: mimic be_entry_release_rw
+ * when no be_release() available */
+ /* free entry */
+ entry_free( e );
+ rc = 0;
+ }
op->o_bd = b0;
return rc;
}
)
{
BackendDB *be, b2;
- int rc;
+ int rc = NOID;
b2 = *b0;
b2.bd_info = (BackendInfo *)glue_tool_inst( b0->bd_info );
return NOID;
if (!glueBack) {
- rc = be->be_entry_open (be, glueMode);
- if (rc != 0)
+ if ( be->be_entry_open ) {
+ rc = be->be_entry_open (be, glueMode);
+ }
+ if (rc != 0) {
return NOID;
+ }
} else if (be != glueBack) {
/* If this entry belongs in a different branch than the
* previous one, close the current database and open the
* new one.
*/
- glueBack->be_entry_close (glueBack);
- rc = be->be_entry_open (be, glueMode);
- if (rc != 0)
+ if ( glueBack->be_entry_close ) {
+ glueBack->be_entry_close (glueBack);
+ }
+ if ( be->be_entry_open ) {
+ rc = be->be_entry_open (be, glueMode);
+ }
+ if (rc != 0) {
return NOID;
+ }
}
glueBack = be;
return be->be_entry_put (be, e, text);
glue.on_bi.bi_op_search = glue_op_search;
glue.on_bi.bi_op_modify = glue_op_func;
glue.on_bi.bi_op_modrdn = glue_op_func;
- glue.on_bi.bi_op_add = glue_op_func;
+ glue.on_bi.bi_op_add = glue_op_func;
glue.on_bi.bi_op_delete = glue_op_func;
glue.on_bi.bi_chk_referrals = glue_chk_referrals;
#if SLAPD_OVER_REFINT == SLAPD_MOD_STATIC
extern int refint_init();
#endif
+#if SLAPD_OVER_RETCODE == SLAPD_MOD_STATIC
+extern int retcode_init();
+#endif
#if SLAPD_OVER_RWM == SLAPD_MOD_STATIC
extern int rwm_init();
#endif
#if SLAPD_OVER_REFINT == SLAPD_MOD_STATIC
{ "Referential Integrity", refint_init },
#endif
+#if SLAPD_OVER_RETCODE == SLAPD_MOD_STATIC
+ { "Return Code", retcode_init },
+#endif
#if SLAPD_OVER_RWM == SLAPD_MOD_STATIC
{ "Rewrite/Remap", rwm_init },
#endif
break;
case PC_TEMP:
for (i=0; i<cm->numtemplates; i++) {
- bv.bv_len = sprintf( c->msg, " %d %d",
+ bv.bv_len = sprintf( c->msg, " %d %ld",
qm->templates[i].attr_set_index,
qm->templates[i].ttl );
bv.bv_len += qm->templates[i].querystr.bv_len + 2;
struct berval bv;
Modifications *m;
+ if (!pp->pwdLockoutDuration)
+ return 1;
+
if ((then = parse_time( vals[0].bv_val )) == (time_t)0)
return 1;
for(e = 1; cred->bv_val[e] && cred->bv_val[e] != '}'; e++);
if (cred->bv_val[e]) {
- char *sc = ch_calloc( sizeof(char), e + 2);
- sc[e + 1] = '\0'; /* terminate string */
- strncpy( sc, cred->bv_val, e + 1);
- e = lutil_passwd_scheme( sc );
- free( sc );
- if (e && sch) {
+ int rc;
+ rc = lutil_passwd_scheme( cred->bv_val );
+ if (rc && sch) {
sch->bv_val = cred->bv_val;
sch->bv_len = e;
return LDAP_SUCCESS;
int nlen;
snprintf( str, MAX_PWD_HISTORY_SZ,
- "%s#%s#%d#", timebuf,
+ "%s#%s#%lu#", timebuf,
pa->a_desc->ad_type->sat_syntax->ssyn_oid,
- pa->a_nvals[0].bv_len );
+ (unsigned long) pa->a_nvals[0].bv_len );
str[MAX_PWD_HISTORY_SZ-1] = 0;
nlen = strlen(str);
return SLAP_CB_CONTINUE;
}
+#ifdef ENABLE_REWRITE
+static int
+rwm_conn_init( BackendDB *be, Connection *conn )
+{
+ slap_overinst *on = (slap_overinst *) be->bd_info;
+ struct ldaprwmap *rwmap =
+ (struct ldaprwmap *)on->on_bi.bi_private;
+
+ ( void )rewrite_session_init( rwmap->rwm_rw, conn );
+
+ return SLAP_CB_CONTINUE;
+}
+
+static int
+rwm_conn_destroy( BackendDB *be, Connection *conn )
+{
+ slap_overinst *on = (slap_overinst *) be->bd_info;
+ struct ldaprwmap *rwmap =
+ (struct ldaprwmap *)on->on_bi.bi_private;
+
+ ( void )rewrite_session_delete( rwmap->rwm_rw, conn );
+
+ return SLAP_CB_CONTINUE;
+}
+#endif /* ENABLE_REWRITE */
+
static int
rwm_op_bind( Operation *op, SlapReply *rs )
{
int rc;
#ifdef ENABLE_REWRITE
- ( void )rewrite_session_delete( rwmap->rwm_rw, op->o_conn );
- ( void )rewrite_session_init( rwmap->rwm_rw, op->o_conn );
-
rc = rwm_op_dn_massage( op, rs, "bindDN" );
#else /* ! ENABLE_REWRITE */
rc = 1;
return SLAP_CB_CONTINUE;
}
+static slap_callback rwm_cb;
+
+static void
+rwm_keyfree(
+ void *key,
+ void *data )
+{
+ ber_memfree_x( data, NULL );
+}
+
+static slap_callback *
+rwm_callback_get( Operation *op )
+{
+ void *data = NULL;
+
+ if ( op->o_threadctx == NULL ) {
+ return &rwm_cb;
+ }
+
+ ldap_pvt_thread_pool_getkey( op->o_threadctx,
+ rwm_keyfree, &data, NULL );
+ if ( data == NULL ) {
+ data = ch_calloc( sizeof( slap_callback ), 1 );
+ ldap_pvt_thread_pool_setkey( op->o_threadctx,
+ rwm_keyfree, data, rwm_keyfree );
+ }
+
+ return (slap_callback *)data;
+}
+
static int
rwm_swap_attrs( Operation *op, SlapReply *rs )
{
return SLAP_CB_CONTINUE;
}
-static int rwm_freeself( Operation *op, SlapReply *rs )
-{
- if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_RESULT ) {
- assert( op->o_callback );
-
- op->o_tmpfree( op->o_callback, op->o_tmpmemctx );
- op->o_callback = NULL;
- }
-
- return SLAP_CB_CONTINUE;
-}
-
static int
rwm_op_search( Operation *op, SlapReply *rs )
{
struct berval fstr = BER_BVNULL;
Filter *f = NULL;
- slap_callback *cb;
+ slap_callback *cb = NULL;
AttributeName *an = NULL;
char *text = NULL;
goto error_return;
}
- cb = (slap_callback *) op->o_tmpcalloc( sizeof( slap_callback ),
- 1, op->o_tmpmemctx );
- if ( cb == NULL ) {
- rc = LDAP_NO_MEMORY;
- goto error_return;
- }
+ cb = rwm_callback_get( op );
cb->sc_response = rwm_swap_attrs;
- cb->sc_cleanup = rwm_freeself;
+ cb->sc_cleanup = NULL;
cb->sc_private = (void *)op->ors_attrs;
cb->sc_next = op->o_callback;
rwm.on_bi.bi_operational = rwm_operational;
rwm.on_bi.bi_chk_referrals = 0 /* rwm_chk_referrals */ ;
+#ifdef ENABLE_REWRITE
+ rwm.on_bi.bi_connection_init = rwm_conn_init;
+ rwm.on_bi.bi_connection_destroy = rwm_conn_destroy;
+#endif /* ENABLE_REWRITE */
+
rwm.on_response = rwm_response;
return overlay_register( &rwm );
vtmp,
tmp;
static struct berval
-#if 0
- ber_bvfalse = BER_BVC( "(?=false)" ),
-#endif
/* better than nothing... */
ber_bvfalse = BER_BVC( "(!(objectClass=*))" ),
ber_bvtf_false = BER_BVC( "(|)" ),
-#if 0
- ber_bvtrue = BER_BVC( "(?=true)" ),
-#endif
/* better than nothing... */
ber_bvtrue = BER_BVC( "(objectClass=*)" ),
ber_bvtf_true = BER_BVC( "(&)" ),
case LDAP_COMPARE_FALSE:
if ( dc->rwmap->rwm_flags & RWM_F_SUPPORT_T_F ) {
tmp = ber_bvtf_false;
- } else {
- tmp = ber_bvfalse;
+ break;
}
+ /* fallthru */
+
+ case SLAPD_COMPARE_UNDEFINED:
+ tmp = ber_bvfalse;
break;
case LDAP_COMPARE_TRUE:
}
break;
- case SLAPD_COMPARE_UNDEFINED:
- tmp = ber_bvundefined;
- break;
-
default:
tmp = ber_bverror;
break;
SlapReply frs = { REP_RESULT };
char buf[LDAP_LUTIL_CSNSTR_BUFSIZE + STRLENOF("(entryCSN<=)")];
char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
- struct berval fbuf, maxcsn;
+ struct berval maxcsn;
Filter cf, af;
#ifdef LDAP_COMP_MATCH
AttributeAssertion eq = { NULL, BER_BVNULL, NULL };
/* We want pure entries, not referrals */
fop.o_managedsait = SLAP_CONTROL_CRITICAL;
- fbuf.bv_val = buf;
cf.f_ava = &eq;
cf.f_av_desc = slap_schema.si_ad_entryCSN;
cf.f_next = NULL;
fop.ors_limit = NULL;
fop.ors_tlimit = SLAP_NO_LIMIT;
fop.ors_filter = &cf;
- fop.ors_filterstr = fbuf;
+ fop.ors_filterstr.bv_val = buf;
switch( mode ) {
case FIND_MAXCSN:
cf.f_choice = LDAP_FILTER_GE;
cf.f_av_value = si->si_ctxcsn;
- fbuf.bv_len = sprintf( buf, "(entryCSN>=%s)",
+ fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN>=%s)",
cf.f_av_value.bv_val );
fop.ors_attrsonly = 0;
fop.ors_attrs = csn_anlist;
case FIND_CSN:
cf.f_choice = LDAP_FILTER_LE;
cf.f_av_value = srs->sr_state.ctxcsn;
- fbuf.bv_len = sprintf( buf, "(entryCSN<=%s)",
+ fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
cf.f_av_value.bv_val );
fop.ors_attrsonly = 1;
fop.ors_attrs = slap_anlist_no_attrs;
}
}
ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
-done:
+
if ( op->o_tag != LDAP_REQ_ADD && e ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
be_entry_release_rw( op, e, 0 );
/* A fake thread context */
static thread_keys thrctx[MAXKEYS];
+/* ITS#3456 we cannot run this search on the main thread, must use a
+ * child thread in order to insure we have a big enough stack.
+ */
+static void *
+syncprov_db_otask(
+ void *ptr
+)
+{
+ syncprov_findcsn( ptr, FIND_MAXCSN );
+ return NULL;
+}
+
/* Read any existing contextCSN from the underlying db.
* Then search for any entries newer than that. If no value exists,
* just generate it. Cache whatever result.
slap_schema.si_ad_contextCSN, 0, &e );
if ( e ) {
+ ldap_pvt_thread_t tid;
+
a = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN );
if ( a ) {
si->si_ctxcsn.bv_len = a->a_nvals[0].bv_len;
op->o_req_dn = be->be_suffix[0];
op->o_req_ndn = be->be_nsuffix[0];
op->ors_scope = LDAP_SCOPE_SUBTREE;
- syncprov_findcsn( op, FIND_MAXCSN );
+ ldap_pvt_thread_create( &tid, 0, syncprov_db_otask, op );
+ ldap_pvt_thread_join( tid, NULL );
} else if ( SLAP_SYNC_SHADOW( op->o_bd )) {
/* If we're also a consumer, and we didn't find the context entry,
* then don't generate anything, wait for our provider to send it
}
/* If our ctxcsn is different from what was read from the root
- * entry, write the new value out.
+ * entry, make sure we do a checkpoint on close
*/
if ( strcmp( si->si_ctxcsnbuf, ctxcsnbuf )) {
- SlapReply rs = {REP_RESULT};
- syncprov_checkpoint( op, &rs, on );
+ si->si_numops++;
}
out:
if ( hash ) {
*hash = ber_strdup( cr );
rc = LUTIL_PASSWD_OK;
+
+ } else {
+ rc = strcmp( salt, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
}
- rc = strcmp( salt, cr ) ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;
}
ldap_pvt_thread_mutex_unlock( &passwd_mutex );
/*
* aclparse.c
*/
+LDAP_SLAPD_V (char *) style_strings[];
+
LDAP_SLAPD_F (void) parse_acl LDAP_P(( Backend *be,
const char *fname, int lineno,
int argc, char **argv, int pos ));
char *attrs[ 2 ] = { NULL, NULL };
ber_str2bv( val, 0, 0, &bv_val );
- attrs[ 0 ] = attr;
+ attrs[ 0 ] = (char *) attr;
rc = ldap_initialize( &ld, uri );
if ( rc != LDAP_SUCCESS ) {
static slap_response sasl_ap_lookup;
+static struct berval sc_cleartext = BER_BVC("{CLEARTEXT}");
+
static int
sasl_ap_lookup( Operation *op, SlapReply *rs )
{
sl->list[i].name );
}
for ( bv = a->a_vals; bv->bv_val; bv++ ) {
+ /* ITS#3846 don't give hashed passwords to SASL */
+ if ( ad == slap_schema.si_ad_userPassword &&
+ bv->bv_val[0] == '{' ) {
+ rc = lutil_passwd_scheme( bv->bv_val );
+ if ( rc ) {
+ /* If it's not a recognized scheme, just assume it's
+ * a cleartext password that happened to include brackets.
+ *
+ * If it's a recognized scheme, skip this value, unless the
+ * scheme is {CLEARTEXT}. In that case, skip over the
+ * scheme name and use the remainder. If there is nothing
+ * past the scheme name, skip this value.
+ */
+#ifdef SLAPD_CLEARTEXT
+ if ( !strncasecmp( bv->bv_val, sc_cleartext.bv_val,
+ sc_cleartext.bv_len )) {
+ struct berval cbv;
+ cbv.bv_len = bv->bv_len - sc_cleartext.bv_len;
+ if ( cbv.bv_len ) {
+ cbv.bv_val = bv->bv_val + sc_cleartext.bv_len;
+ sl->sparams->utils->prop_set( sl->sparams->propctx,
+ sl->list[i].name, cbv.bv_val, cbv.bv_len );
+ }
+ }
+#endif
+ continue;
+ }
+ }
sl->sparams->utils->prop_set( sl->sparams->propctx,
sl->list[i].name, bv->bv_val, bv->bv_len );
}
assert( conn );
assert( id );
- Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: conn %d id=%s [len=%d]\n",
+ Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: conn %lu id=%s [len=%lu]\n",
conn->c_connid,
BER_BVISNULL( id ) ? "NULL" : ( BER_BVISEMPTY( id ) ? "<empty>" : id->bv_val ),
- BER_BVISNULL( id ) ? 0 : ( BER_BVISEMPTY( id ) ? 0 : id->bv_len ) );
+ BER_BVISNULL( id ) ? 0 : ( BER_BVISEMPTY( id ) ? 0 :
+ (unsigned long) id->bv_len ) );
if ( !op ) {
op = conn->c_sasl_bindop;
return LDAP_CONSTRAINT_VIOLATION;
}
- *matchp = (lValue & lAssertedValue) ? 0 : 1;
+ *matchp = ((lValue & lAssertedValue) == lAssertedValue) ? 0 : 1;
return LDAP_SUCCESS;
}
return LDAP_CONSTRAINT_VIOLATION;
}
- *matchp = (lValue | lAssertedValue) ? 0 : -1;
+ *matchp = ((lValue & lAssertedValue) != 0) ? 0 : -1;
return LDAP_SUCCESS;
}
Debug(level, "free list:\n", 0, 0, 0);
so = LDAP_LIST_FIRST(&sh->sh_free[i-order_start]);
while (so) {
- Debug(level, "%x\n",so->so_ptr, 0, 0);
+ Debug(level, "%lx\n", (unsigned long) so->so_ptr, 0, 0);
so = LDAP_LIST_NEXT(so, so_link);
}
}
regex_t acl_dn_re;
struct berval acl_dn_pat;
AttributeName *acl_attrs;
+ MatchingRule *acl_attrval_mr;
slap_style_t acl_attrval_style;
regex_t acl_attrval_re;
struct berval acl_attrval;
slap_mask_t bi_flags; /* backend flags */
#define SLAP_BFLAG_MONITOR 0x0001U /* a monitor backend */
#define SLAP_BFLAG_CONFIG 0x0002U /* a config backend */
+#define SLAP_BFLAG_FRONTEND 0x0004U /* the frontendDB */
#define SLAP_BFLAG_NOLASTMODCMD 0x0010U
#define SLAP_BFLAG_INCREMENT 0x0100U
#define SLAP_BFLAG_ALIASES 0x1000U
#define SLAP_BFLAGS(be) ((be)->bd_info->bi_flags)
#define SLAP_MONITOR(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_MONITOR)
#define SLAP_CONFIG(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_CONFIG)
+#define SLAP_FRONTEND(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_FRONTEND)
#define SLAP_INCREMENT(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_INCREMENT)
#define SLAP_ALIASES(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_ALIASES)
#define SLAP_REFERRALS(be) (SLAP_BFLAGS(be) & SLAP_BFLAG_REFERRALS)
#define get_domainScope(op) (0)
#endif
-#ifdef LDAP_CONTROL_X_TREE_DELETE
+#ifdef SLAP_CONTROL_X_TREE_DELETE
#define o_tree_delete o_ctrlflag[slap_cids.sc_treeDelete]
#define get_treeDelete(op) ((int)(op)->o_tree_delete)
#else
{
#ifdef LDAP_SLAPI
unsigned long start = slapi_timer_current_time();
- printf("%10ld %10ld usec %s\n", start, 0, label);
+ printf("%10ld %10d usec %s\n", start, 0, label);
return start;
#else /* LDAP_SLAPI */
return 0;
/* NOTE: used & documented in slapd.conf(5) */
#define IDSTR "rid"
#define PROVIDERSTR "provider"
-#define TYPESTR "type"
-#define INTERVALSTR "interval"
-#define SEARCHBASESTR "searchbase"
+#define SCHEMASTR "schemachecking"
#define FILTERSTR "filter"
+#define SEARCHBASESTR "searchbase"
#define SCOPESTR "scope"
-#define ATTRSSTR "attrs"
#define ATTRSONLYSTR "attrsonly"
+#define ATTRSSTR "attrs"
+#define TYPESTR "type"
+#define INTERVALSTR "interval"
+#define RETRYSTR "retry"
#define SLIMITSTR "sizelimit"
#define TLIMITSTR "timelimit"
-#define SCHEMASTR "schemachecking"
/* FIXME: undocumented */
#define OLDAUTHCSTR "bindprincipal"
#define EXATTRSSTR "exattrs"
-#define RETRYSTR "retry"
+#define MANAGEDSAITSTR "manageDSAit"
/* FIXME: unused */
#define LASTMODSTR "lastmod"
#define LMREQSTR "req"
#define SRVTABSTR "srvtab"
#define SUFFIXSTR "suffix"
-#define MANAGEDSAITSTR "manageDSAit"
/* mandatory */
#define GOT_ID 0x0001
} scopes[] = {
{ BER_BVC("base"), LDAP_SCOPE_BASE },
{ BER_BVC("one"), LDAP_SCOPE_ONELEVEL },
+ { BER_BVC("onelevel"), LDAP_SCOPE_ONELEVEL }, /* OpenLDAP extension */
#ifdef LDAP_SCOPE_SUBORDINATE
{ BER_BVC("children"), LDAP_SCOPE_SUBORDINATE },
- { BER_BVC("subordinate"), 0 },
+ { BER_BVC("subordinate"), LDAP_SCOPE_SUBORDINATE },
#endif
{ BER_BVC("sub"), LDAP_SCOPE_SUBTREE },
+ { BER_BVC("subtree"), LDAP_SCOPE_SUBTREE }, /* OpenLDAP extension */
{ BER_BVNULL, 0 }
};
int j;
val = cargv[ i ] + STRLENOF( SCOPESTR "=" );
for ( j=0; !BER_BVISNULL(&scopes[j].key); j++ ) {
- if (!strncasecmp( val, scopes[j].key.bv_val,
- scopes[j].key.bv_len )) {
- while (!scopes[j].val) j--;
+ if (!strcasecmp( val, scopes[j].key.bv_val )) {
si->si_scope = scopes[j].val;
break;
}
bindconf_unparse( &si->si_bindconf, &bc );
ptr = buf;
- ptr += sprintf( ptr, IDSTR "=%03d " PROVIDERSTR "=%s",
+ ptr += sprintf( ptr, IDSTR "=%03ld " PROVIDERSTR "=%s",
si->si_rid, si->si_provideruri.bv_val );
if ( !BER_BVISNULL( &bc )) {
ptr = lutil_strcopy( ptr, bc.bv_val );
for (i=0; si->si_retryinterval[i]; i++) {
if ( space ) *ptr++ = ' ';
space = 1;
- ptr += sprintf( ptr, "%d ", si->si_retryinterval[i] );
+ ptr += sprintf( ptr, "%ld ", (long) si->si_retryinterval[i] );
if ( si->si_retrynum_init[i] == -1 )
*ptr++ = '+';
else
- ptr += sprintf( ptr, "%d", si->si_retrynum_init );
+ ptr += sprintf( ptr, "%d", si->si_retrynum_init[i] );
}
*ptr++ = '"';
}