Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • openldap/openldap
  • hyc/openldap
  • ryan/openldap
  • iboukris/openldap
  • ondra/openldap
  • sshanks-kx/openldap
  • blaggacao/openldap
  • pbrezina/openldap
  • quanah/openldap
  • dragos_h/openldap
  • lorenz/openldap
  • tsaarni/openldap
  • fei.ding/openldap
  • orent/openldap
  • arrowplum/openldap
  • barchiesi/openldap
  • jotik/openldap
  • hamano/openldap
  • ingovoss/openldap
  • henson/openldap
  • jlrine2/openldap
  • howeverAT/openldap
  • nivanova/openldap
  • orbea/openldap
  • rdubner/openldap
  • smckinney/openldap
  • jklowden/openldap
  • dpa-openldap/openldap
  • rouzier/openldap
  • orgads/openldap
  • ffontaine/openldap
  • jiaqingz/openldap
  • dcoutadeur/openldap
  • begeragus/openldap
  • pubellit/openldap
  • glandium/openldap
  • facboy/openldap
  • thesamesam/openldap
  • Johan/openldap
  • fkooman/openldap
  • gburd/openldap
  • h-homma/openldap
  • sgallagher/openldap
  • ahmed_zaki/openldap
  • gnoe/openldap
  • mid/openldap
  • clan/openldap
47 results
Show changes
Showing with 404 additions and 467 deletions
......@@ -267,7 +267,7 @@ struct bdb_lock_info {
};
struct bdb_op_info {
BackendDB* boi_bdb;
OpExtra boi_oe;
DB_TXN* boi_txn;
u_int32_t boi_err;
int boi_acl_cache;
......
......@@ -925,7 +925,7 @@ load1:
if (( flag & ID_NOCACHE ) &&
( bdb_cache_entryinfo_trylock( *eip ) == 0 )) {
/* Set the cached state only if no other thread
* found the info while we was loading the entry.
* found the info while we were loading the entry.
*/
if ( (*eip)->bei_finders == 1 )
(*eip)->bei_state |= CACHE_ENTRY_NOT_CACHED;
......@@ -1257,18 +1257,19 @@ bdb_cache_delete(
assert( e->e_private != NULL );
/* Lock the entry's info */
bdb_cache_entryinfo_lock( ei );
/* Set this early, warn off any queriers */
ei->bei_state |= CACHE_ENTRY_DELETED;
/* Lock the entry's info */
bdb_cache_entryinfo_lock( ei );
bdb_cache_entryinfo_unlock( ei );
/* Get write lock on the data */
rc = bdb_cache_entry_db_relock( bdb, locker, ei, 1, 0, lock );
if ( rc ) {
/* couldn't lock, undo and give up */
ei->bei_state ^= CACHE_ENTRY_DELETED;
bdb_cache_entryinfo_unlock( ei );
return rc;
}
......@@ -1283,8 +1284,6 @@ bdb_cache_delete(
/* free lru mutex */
ldap_pvt_thread_mutex_unlock( &bdb->bi_cache.c_lru_mutex );
/* Leave entry info locked */
return( rc );
}
......@@ -1293,6 +1292,8 @@ bdb_cache_delete_cleanup(
Cache *cache,
EntryInfo *ei )
{
/* Enter with ei locked */
if ( ei->bei_e ) {
ei->bei_e->e_private = NULL;
#ifdef SLAP_ZONE_ALLOC
......
......@@ -124,7 +124,8 @@ retry: /* transaction retry */
0, 0, 0 );
rs->sr_err = TXN_ABORT( ltid );
ltid = NULL;
op->o_private = NULL;
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
opinfo.boi_oe.oe_key = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
......@@ -155,11 +156,11 @@ retry: /* transaction retry */
locker = TXN_ID ( ltid );
opinfo.boi_bdb = op->o_bd;
opinfo.boi_oe.oe_key = bdb;
opinfo.boi_txn = ltid;
opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo;
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
dnParent( &op->o_req_ndn, &pdn );
......@@ -536,7 +537,8 @@ retry: /* transaction retry */
rs->sr_err = TXN_COMMIT( ltid, 0 );
}
ltid = NULL;
op->o_private = NULL;
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
opinfo.boi_oe.oe_key = NULL;
BDB_LOG_PRINTF( bdb->bi_dbenv, NULL, "slapd Committed delete %s(%d)",
e->e_nname.bv_val, e->e_id );
......@@ -572,6 +574,7 @@ return_results:
if( e != NULL ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
/* Free the EntryInfo and the Entry */
bdb_cache_entryinfo_lock( BEI(e) );
bdb_cache_delete_cleanup( &bdb->bi_cache, BEI(e) );
} else {
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
......@@ -581,7 +584,9 @@ return_results:
if( ltid != NULL ) {
TXN_ABORT( ltid );
}
op->o_private = NULL;
if ( opinfo.boi_oe.oe_key ) {
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
}
send_ldap_result( op, rs );
slap_graduate_commit_csn( op );
......
......@@ -242,7 +242,8 @@ int bdb_entry_release(
int rw )
{
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
struct bdb_op_info *boi = NULL;
struct bdb_op_info *boi;
OpExtra *oex;
/* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE,
SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */
......@@ -257,7 +258,10 @@ int bdb_entry_release(
#endif
}
/* free entry and reader or writer lock */
boi = (struct bdb_op_info *)op->o_private;
LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
if ( oex->oe_key == bdb ) break;
}
boi = (struct bdb_op_info *)oex;
/* lock is freed with txn */
if ( !boi || boi->boi_txn ) {
......@@ -274,8 +278,8 @@ int bdb_entry_release(
}
}
if ( !boi->boi_locks ) {
LDAP_SLIST_REMOVE( &op->o_extra, &boi->boi_oe, OpExtra, oe_next );
op->o_tmpfree( boi, op->o_tmpmemctx );
op->o_private = NULL;
}
}
} else {
......@@ -328,9 +332,14 @@ int bdb_entry_get(
"=> bdb_entry_get: oc: \"%s\", at: \"%s\"\n",
oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
if( op ) boi = (struct bdb_op_info *) op->o_private;
if( boi != NULL && op->o_bd->be_private == boi->boi_bdb->be_private ) {
txn = boi->boi_txn;
if( op ) {
OpExtra *oex;
LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
if ( oex->oe_key == bdb ) break;
}
boi = (struct bdb_op_info *)oex;
if ( boi )
txn = boi->boi_txn;
}
if ( txn != NULL ) {
......@@ -407,8 +416,8 @@ return_results:
if ( op ) {
if ( !boi ) {
boi = op->o_tmpcalloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx);
boi->boi_bdb = op->o_bd;
op->o_private = boi;
boi->boi_oe.oe_key = bdb;
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &boi->boi_oe, oe_next );
}
if ( !boi->boi_txn ) {
struct bdb_lock_info *bli;
......
......@@ -410,7 +410,8 @@ retry: /* transaction retry */
rs->sr_err = TXN_ABORT( ltid );
ltid = NULL;
op->o_private = NULL;
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
opinfo.boi_oe.oe_key = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
......@@ -439,11 +440,11 @@ retry: /* transaction retry */
locker = TXN_ID ( ltid );
opinfo.boi_bdb = op->o_bd;
opinfo.boi_oe.oe_key = bdb;
opinfo.boi_txn = ltid;
opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo;
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
/* get entry or ancestor */
rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,
......@@ -666,7 +667,8 @@ retry: /* transaction retry */
rs->sr_err = TXN_COMMIT( ltid, 0 );
}
ltid = NULL;
op->o_private = NULL;
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
opinfo.boi_oe.oe_key = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
......@@ -705,7 +707,9 @@ done:
if( ltid != NULL ) {
TXN_ABORT( ltid );
}
op->o_private = NULL;
if ( opinfo.boi_oe.oe_key ) {
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
}
if( e != NULL ) {
bdb_unlocked_cache_return_entry_w (&bdb->bi_cache, e);
......
......@@ -134,7 +134,8 @@ retry: /* transaction retry */
rs->sr_err = TXN_ABORT( ltid );
ltid = NULL;
op->o_private = NULL;
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
opinfo.boi_oe.oe_key = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rs->sr_err != 0 ) {
rs->sr_err = LDAP_OTHER;
......@@ -165,11 +166,11 @@ retry: /* transaction retry */
locker = TXN_ID ( ltid );
opinfo.boi_bdb = op->o_bd;
opinfo.boi_oe.oe_key = bdb;
opinfo.boi_txn = ltid;
opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo;
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next );
/* get entry */
rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1,
......@@ -764,7 +765,8 @@ retry: /* transaction retry */
}
ltid = NULL;
op->o_private = NULL;
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
opinfo.boi_oe.oe_key = NULL;
if( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
......@@ -823,7 +825,9 @@ done:
if( ltid != NULL ) {
TXN_ABORT( ltid );
}
op->o_private = NULL;
if ( opinfo.boi_oe.oe_key ) {
LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next );
}
if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
......
......@@ -322,11 +322,16 @@ bdb_search( Operation *op, SlapReply *rs )
DB_LOCK lock;
struct bdb_op_info *opinfo = NULL;
DB_TXN *ltid = NULL;
OpExtra *oex;
Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_search) "\n", 0, 0, 0);
attrs = op->oq_search.rs_attrs;
opinfo = (struct bdb_op_info *) op->o_private;
LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
if ( oex->oe_key == bdb )
break;
}
opinfo = (struct bdb_op_info *) oex;
manageDSAit = get_manageDSAit( op );
......
......@@ -773,8 +773,9 @@ ldap_back_entry_get(
ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
ldapconn_t *lc = NULL;
int rc = 1,
int rc,
do_not_cache;
ber_tag_t tag;
struct berval bdn;
LDAPMessage *result = NULL,
*e = NULL;
......@@ -788,12 +789,18 @@ ldap_back_entry_get(
/* Tell getconn this is a privileged op */
do_not_cache = op->o_do_not_cache;
tag = op->o_tag;
/* do not cache */
op->o_do_not_cache = 1;
if ( !ldap_back_dobind( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
op->o_do_not_cache = do_not_cache;
/* ldap_back_entry_get() is an entry lookup, so it does not need
* to know what the entry is being looked up for */
op->o_tag = LDAP_REQ_SEARCH;
rc = ldap_back_dobind( &lc, op, &rs, LDAP_BACK_DONTSEND );
op->o_do_not_cache = do_not_cache;
op->o_tag = tag;
if ( !rc ) {
return rs.sr_err;
}
op->o_do_not_cache = do_not_cache;
if ( at ) {
attrp = attr;
......
......@@ -154,13 +154,18 @@ monitor_cache_get(
*ep = NULL;
tmp_mc.mc_ndn = *ndn;
retry:;
ldap_pvt_thread_mutex_lock( &mi->mi_cache_mutex );
mc = ( monitor_cache_t * )avl_find( mi->mi_cache,
( caddr_t )&tmp_mc, monitor_cache_cmp );
if ( mc != NULL ) {
/* entry is returned with mutex locked */
monitor_cache_lock( mc->mc_e );
if ( monitor_cache_trylock( mc->mc_e ) ) {
ldap_pvt_thread_mutex_unlock( &mi->mi_cache_mutex );
ldap_pvt_thread_yield();
goto retry;
}
*ep = mc->mc_e;
}
......
......@@ -1348,7 +1348,7 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
old = li->li_old;
li->li_old = NULL;
/* Disarm mod_cleanup */
for ( cb = op->o_callback->sc_next; cb; cb = cb->sc_next ) {
for ( cb = op->o_callback; cb; cb = cb->sc_next ) {
if ( cb->sc_private == (void *)on ) {
cb->sc_private = NULL;
break;
......
......@@ -4,6 +4,7 @@
*
* Copyright 2003-2008 The OpenLDAP Foundation.
* Portions Copyright 2004-2005 Pierangelo Masarati.
* Portions Copyright 2008 Emmanuel Dreyfus.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -60,14 +61,23 @@ static AttributeName *slap_anlist_no_attrs = anlist_no_attrs;
static AttributeDescription *ad_dgIdentity, *ad_dgAuthz;
typedef struct dynlist_map_t {
AttributeDescription *dlm_member_ad;
AttributeDescription *dlm_mapped_ad;
struct dynlist_map_t *dlm_next;
} dynlist_map_t;
typedef struct dynlist_info_t {
ObjectClass *dli_oc;
AttributeDescription *dli_ad;
AttributeDescription *dli_member_ad;
struct dynlist_map_t *dli_dlm;
struct berval dli_default_filter;
struct dynlist_info_t *dli_next;
} dynlist_info_t;
#define DYNLIST_USAGE \
"\"dynlist-attrset <oc> <URL-ad> [[<mapped-ad>:]<member-ad> ...]\": "
static dynlist_info_t *
dynlist_is_dynlist_next( Operation *op, SlapReply *rs, dynlist_info_t *old_dli )
{
......@@ -149,6 +159,7 @@ dynlist_sc_update( Operation *op, SlapReply *rs )
AccessControlState acl_state = ACL_STATE_INIT;
dynlist_sc_t *dlc;
dynlist_map_t *dlm;
if ( rs->sr_type != REP_SEARCH ) {
return 0;
......@@ -167,7 +178,9 @@ dynlist_sc_update( Operation *op, SlapReply *rs )
goto done;
}
if ( dlc->dlc_dli->dli_member_ad ) {
for ( dlm = dlc->dlc_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
if (dlm->dlm_mapped_ad != NULL)
continue;
/* if access allowed, try to add values, emulating permissive
* control to silently ignore duplicates */
......@@ -185,8 +198,8 @@ dynlist_sc_update( Operation *op, SlapReply *rs )
BER_BVZERO( &nvals[ 1 ] );
mod.sm_op = LDAP_MOD_ADD;
mod.sm_desc = dlc->dlc_dli->dli_member_ad;
mod.sm_type = dlc->dlc_dli->dli_member_ad->ad_cname;
mod.sm_desc = dlm->dlm_member_ad;
mod.sm_type = dlm->dlm_member_ad->ad_cname;
mod.sm_values = vals;
mod.sm_nvalues = nvals;
mod.sm_numvals = 1;
......@@ -282,15 +295,25 @@ dynlist_sc_update( Operation *op, SlapReply *rs )
Modification mod;
const char *text = NULL;
char textbuf[1024];
dynlist_map_t *dlm;
AttributeDescription *ad;
BER_BVZERO( &vals[j] );
if ( nvals ) {
BER_BVZERO( &nvals[j] );
}
ad = a->a_desc;
for ( dlm = dlc->dlc_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
if ( dlm->dlm_member_ad == a->a_desc ) {
ad = dlm->dlm_mapped_ad;
break;
}
}
mod.sm_op = LDAP_MOD_ADD;
mod.sm_desc = a->a_desc;
mod.sm_type = a->a_desc->ad_cname;
mod.sm_desc = ad;
mod.sm_type = ad->ad_cname;
mod.sm_values = vals;
mod.sm_nvalues = nvals;
mod.sm_numvals = j;
......@@ -328,6 +351,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
int opattrs,
userattrs;
dynlist_sc_t dlc = { 0 };
dynlist_map_t *dlm;
a = attrs_find( rs->sr_entry->e_attrs, dli->dli_ad );
if ( a == NULL ) {
......@@ -344,9 +368,13 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
#endif /* SLAP_OPATTRS */
/* Don't generate member list if it wasn't requested */
if ( dli->dli_member_ad && !userattrs && !ad_inlist( dli->dli_member_ad, rs->sr_attrs ) ) {
return SLAP_CB_CONTINUE;
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
if ( userattrs ||
ad_inlist( dlm->dlm_member_ad, rs->sr_attrs ) )
break;
}
if ( dli->dli_dlm && !dlm )
return SLAP_CB_CONTINUE;
if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) {
Attribute *authz = NULL;
......@@ -393,6 +421,7 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
int i, j;
struct berval dn;
int rc;
dynlist_map_t *dlm;
BER_BVZERO( &o.o_req_dn );
BER_BVZERO( &o.o_req_ndn );
......@@ -431,7 +460,13 @@ dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
}
o.ors_scope = lud->lud_scope;
if ( dli->dli_member_ad != NULL ) {
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
if ( dlm->dlm_mapped_ad != NULL ) {
break;
}
}
if ( dli->dli_dlm && !dlm ) {
/* if ( lud->lud_attrs != NULL ),
* the URL should be ignored */
o.ors_attrs = slap_anlist_no_attrs;
......@@ -564,9 +599,14 @@ dynlist_compare( Operation *op, SlapReply *rs )
dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private;
Operation o = *op;
Entry *e = NULL;
dynlist_map_t *dlm;
for ( ; dli != NULL; dli = dli->dli_next ) {
if ( op->oq_compare.rs_ava->aa_desc == dli->dli_member_ad ) {
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next )
if ( op->oq_compare.rs_ava->aa_desc == dlm->dlm_member_ad )
break;
if ( dli->dli_dlm && dlm ) {
/* This compare is for one of the attributes we're
* interested in. We'll use slapd's existing dyngroup
* evaluator to get the answer we want.
......@@ -834,11 +874,11 @@ dynlist_db_config(
ObjectClass *oc;
AttributeDescription *ad = NULL,
*member_ad = NULL;
dynlist_map_t *dlm = NULL;
const char *text;
if ( argc < 3 || argc > 4 ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
if ( argc < 3 ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
"invalid arg number #%d.\n",
fname, lineno, argc );
return 1;
......@@ -846,8 +886,7 @@ dynlist_db_config(
oc = oc_find( argv[1] );
if ( oc == NULL ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
"unable to find ObjectClass \"%s\"\n",
fname, lineno, argv[ 1 ] );
return 1;
......@@ -855,41 +894,90 @@ dynlist_db_config(
rc = slap_str2ad( argv[2], &ad, &text );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
"unable to find AttributeDescription \"%s\"\n",
fname, lineno, argv[2] );
return 1;
}
if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
"AttributeDescription \"%s\" "
"must be a subtype of \"labeledURI\"\n",
fname, lineno, argv[2] );
return 1;
}
if ( argc == 4 ) {
rc = slap_str2ad( argv[3], &member_ad, &text );
for ( i = 3; i < argc; i++ ) {
char *arg;
char *cp;
AttributeDescription *member_ad = NULL;
AttributeDescription *mapped_ad = NULL;
dynlist_map_t *dlmp;
dynlist_map_t *dlml;
/*
* If no mapped attribute is given, dn is used
* for backward compatibility.
*/
arg = argv[i];
if ( cp = strchr( arg, (int)':' ) != NULL ) {
struct berval bv;
ber_str2bv( arg, cp - arg, 0, &bv );
rc = slap_bv2ad( &bv, &mapped_ad, &text );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
DYNLIST_USAGE
"unable to find mapped AttributeDescription \"%s\"\n",
fname, lineno, arg );
return 1;
}
arg = cp + 1;
}
rc = slap_str2ad( arg, &member_ad, &text );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
DYNLIST_USAGE
"unable to find AttributeDescription \"%s\"\n",
fname, lineno, argv[3] );
fname, lineno, arg );
return 1;
}
dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) );
if ( dlm == NULL ) {
dlm = dlmp;
dlml = NULL;
}
dlmp->dlm_member_ad = member_ad;
dlmp->dlm_mapped_ad = mapped_ad;
dlmp->dlm_next = NULL;
if ( dlml != NULL )
dlml->dlm_next = dlmp;
dlml = dlmp;
}
for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private;
*dlip; dlip = &(*dlip)->dli_next )
{
/* The same URL attribute / member attribute pair
* cannot be repeated */
if ( (*dlip)->dli_ad == ad && (*dlip)->dli_member_ad == member_ad ) {
/*
* The same URL attribute / member attribute pair
* cannot be repeated, but we enforce this only
* when the member attribute is unique. Performing
* the check for multiple values would require
* sorting and comparing the lists, which is left
* as a future improvement
*/
if ( (*dlip)->dli_ad == ad &&
(*dlip)->dli_dlm->dlm_next == NULL &&
dlm->dlm_next == NULL &&
dlm->dlm_member_ad == (*dlip)->dli_dlm->dlm_member_ad &&
dlm->dlm_mapped_ad == (*dlip)->dli_dlm->dlm_mapped_ad ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
DYNLIST_USAGE
"URL attributeDescription \"%s\" already mapped.\n",
fname, lineno, ad->ad_cname.bv_val );
#if 0
......@@ -902,9 +990,18 @@ dynlist_db_config(
*dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) );
(*dlip)->dli_oc = oc;
(*dlip)->dli_ad = ad;
(*dlip)->dli_member_ad = member_ad;
(*dlip)->dli_dlm = dlm;
if ( dynlist_build_def_filter( *dlip ) ) {
dynlist_map_t *dlm = (*dlip)->ldi_dlm;
dynlist_map_t *dlm_next;
while ( dlm != NULL ) {
dlm_next = dlm->dlm_next;
ch_free( dlm );
dlm = dlm_next;
}
ch_free( *dlip );
*dlip = NULL;
return 1;
......@@ -965,9 +1062,17 @@ dynlist_db_config(
for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private;
*dlip; dlip = &(*dlip)->dli_next )
{
/* The same URL attribute / member attribute pair
* cannot be repeated */
if ( (*dlip)->dli_ad == ad && (*dlip)->dli_member_ad == member_ad ) {
/*
* The same URL attribute / member attribute pair
* cannot be repeated, but we enforce this only
* when the member attribute is unique. Performing
* the check for multiple values would require
* sorting and comparing the lists, which is left
* as a future improvement
*/
if ( (*dlip)->dli_ad == ad &&
(*dlip)->dli_dlm->dlm_next == NULL &&
member_ad == (*dlip)->dli_dlm->dlm_member_ad ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"dynlist-attrpair <member-ad> <URL-ad>\": "
"URL attributeDescription \"%s\" already mapped.\n",
......@@ -982,9 +1087,12 @@ dynlist_db_config(
*dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) );
(*dlip)->dli_oc = oc;
(*dlip)->dli_ad = ad;
(*dlip)->dli_member_ad = member_ad;
(*dlip)->dli_dlm = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) );
(*dlip)->dli_dlm->dlm_member_ad = member_ad;
(*dlip)->dli_dlm->dlm_mapped_ad = NULL;
if ( dynlist_build_def_filter( *dlip ) ) {
ch_free( (*dlip)->dli_dlm );
ch_free( *dlip );
*dlip = NULL;
return 1;
......@@ -1007,9 +1115,10 @@ enum {
static ConfigDriver dl_cfgen;
/* XXXmanu 255 is the maximum arguments we allow. Can we go beyond? */
static ConfigTable dlcfg[] = {
{ "dynlist-attrset", "group-oc> <URL-ad> <member-ad",
3, 4, 0, ARG_MAGIC|DL_ATTRSET, dl_cfgen,
3, 255, 0, ARG_MAGIC|DL_ATTRSET, dl_cfgen,
"( OLcfgOvAt:8.1 NAME 'olcDLattrSet' "
"DESC 'Dynamic list: <group objectClass>, <URL attributeDescription>, <member attributeDescription>' "
"EQUALITY caseIgnoreMatch "
......@@ -1051,6 +1160,7 @@ dl_cfgen( ConfigArgs *c )
for ( i = 0; dli; i++, dli = dli->dli_next ) {
struct berval bv;
char *ptr = c->cr_msg;
dynlist_map_t *dlm;
assert( dli->dli_oc != NULL );
assert( dli->dli_ad != NULL );
......@@ -1060,10 +1170,16 @@ dl_cfgen( ConfigArgs *c )
dli->dli_oc->soc_cname.bv_val,
dli->dli_ad->ad_cname.bv_val );
if ( dli->dli_member_ad != NULL ) {
for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
ptr[ 0 ] = ' ';
ptr++;
ptr = lutil_strcopy( ptr, dli->dli_member_ad->ad_cname.bv_val );
if ( dlm->dlm_mapped_ad ) {
ptr = lutil_strcopy( ptr, dlm->dlm_mapped_ad->ad_cname.bv_val );
ptr[ 0 ] = ':';
ptr++;
}
ptr = lutil_strcopy( ptr, dlm->dlm_member_ad->ad_cname.bv_val );
}
bv.bv_val = c->cr_msg;
......@@ -1091,9 +1207,18 @@ dl_cfgen( ConfigArgs *c )
dynlist_info_t *dli_next;
for ( dli_next = dli; dli_next; dli = dli_next ) {
dynlist_map_t *dlm = dli->dli_dlm;
dynlist_map_t *dlm_next;
dli_next = dli->dli_next;
ch_free( dli->dli_default_filter.bv_val );
while ( dlm != NULL ) {
dlm_next = dlm->dlm_next;
ch_free( dlm );
dlm = dlm_next;
}
ch_free( dli );
}
......@@ -1101,6 +1226,8 @@ dl_cfgen( ConfigArgs *c )
} else {
dynlist_info_t **dlip;
dynlist_map_t *dlm;
dynlist_map_t *dlm_next;
for ( i = 0, dlip = (dynlist_info_t **)&on->on_bi.bi_private;
i < c->valx; i++ )
......@@ -1114,6 +1241,13 @@ dl_cfgen( ConfigArgs *c )
dli = *dlip;
*dlip = dli->dli_next;
ch_free( dli->dli_default_filter.bv_val );
dlm = dli->dli_dlm;
while ( dlm != NULL ) {
dlm_next = dlm->dlm_next;
ch_free( dlm );
dlm = dlm_next;
}
ch_free( dli );
dli = (dynlist_info_t *)on->on_bi.bi_private;
......@@ -1138,14 +1272,13 @@ dl_cfgen( ConfigArgs *c )
dynlist_info_t **dlip,
*dli_next = NULL;
ObjectClass *oc = NULL;
AttributeDescription *ad = NULL,
*member_ad = NULL;
AttributeDescription *ad = NULL;
dynlist_map_t *dlm = NULL;
const char *text;
oc = oc_find( c->argv[ 1 ] );
if ( oc == NULL ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE
"unable to find ObjectClass \"%s\"",
c->argv[ 1 ] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
......@@ -1155,8 +1288,7 @@ dl_cfgen( ConfigArgs *c )
rc = slap_str2ad( c->argv[ 2 ], &ad, &text );
if ( rc != LDAP_SUCCESS ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE
"unable to find AttributeDescription \"%s\"",
c->argv[ 2 ] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
......@@ -1165,8 +1297,7 @@ dl_cfgen( ConfigArgs *c )
}
if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE
"AttributeDescription \"%s\" "
"must be a subtype of \"labeledURI\"",
c->argv[ 2 ] );
......@@ -1175,36 +1306,59 @@ dl_cfgen( ConfigArgs *c )
return 1;
}
if ( c->argc == 4 ) {
rc = slap_str2ad( c->argv[ 3 ], &member_ad, &text );
for ( i = 3; i < c->argc; i++ ) {
char *arg;
char *cp;
AttributeDescription *member_ad = NULL;
AttributeDescription *mapped_ad = NULL;
dynlist_map_t *dlmp;
dynlist_map_t *dlml;
/*
* If no mapped attribute is given, dn is used
* for backward compatibility.
*/
arg = c->argv[i];
if ( ( cp = strchr( arg, ':' ) ) != NULL ) {
struct berval bv;
ber_str2bv( arg, cp - arg, 0, &bv );
rc = slap_bv2ad( &bv, &mapped_ad, &text );
if ( rc != LDAP_SUCCESS ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
DYNLIST_USAGE
"unable to find mapped AttributeDescription #%d \"%s\"\n",
i - 3, c->argv[ i ] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
c->log, c->cr_msg, 0 );
return 1;
}
arg = cp + 1;
}
rc = slap_str2ad( arg, &member_ad, &text );
if ( rc != LDAP_SUCCESS ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
"unable to find AttributeDescription \"%s\"\n",
c->argv[ 3 ] );
DYNLIST_USAGE
"unable to find AttributeDescription #%d \"%s\"\n",
i - 3, c->argv[ i ] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
c->log, c->cr_msg, 0 );
return 1;
}
}
for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private;
*dlip; dlip = &(*dlip)->dli_next )
{
/* The same URL attribute / member attribute pair
* cannot be repeated */
if ( (*dlip)->dli_ad == ad && (*dlip)->dli_member_ad == member_ad ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
"URL attributeDescription \"%s\" already mapped.\n",
ad->ad_cname.bv_val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
c->log, c->cr_msg, 0 );
#if 0
/* make it a warning... */
return 1;
#endif
dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) );
if ( dlm == NULL ) {
dlm = dlmp;
dlml = NULL;
}
dlmp->dlm_member_ad = member_ad;
dlmp->dlm_mapped_ad = mapped_ad;
dlmp->dlm_next = NULL;
if ( dlml != NULL )
dlml->dlm_next = dlmp;
dlml = dlmp;
}
if ( c->valx > 0 ) {
......@@ -1215,7 +1369,7 @@ dl_cfgen( ConfigArgs *c )
{
if ( *dlip == NULL ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
DYNLIST_USAGE
"invalid index {%d}\n",
c->valx );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
......@@ -1236,7 +1390,7 @@ dl_cfgen( ConfigArgs *c )
(*dlip)->dli_oc = oc;
(*dlip)->dli_ad = ad;
(*dlip)->dli_member_ad = member_ad;
(*dlip)->dli_dlm = dlm;
(*dlip)->dli_next = dli_next;
rc = dynlist_build_def_filter( *dlip );
......@@ -1291,7 +1445,7 @@ dl_cfgen( ConfigArgs *c )
if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrset <oc> <URL-ad> [<member-ad>]\": "
DYNLIST_USAGE
"AttributeDescription \"%s\" "
"must be a subtype of \"labeledURI\"",
c->argv[ 2 ] );
......@@ -1303,9 +1457,17 @@ dl_cfgen( ConfigArgs *c )
for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private;
*dlip; dlip = &(*dlip)->dli_next )
{
/* The same URL attribute / member attribute pair
* cannot be repeated */
if ( (*dlip)->dli_ad == ad && (*dlip)->dli_member_ad == member_ad ) {
/*
* The same URL attribute / member attribute pair
* cannot be repeated, but we enforce this only
* when the member attribute is unique. Performing
* the check for multiple values would require
* sorting and comparing the lists, which is left
* as a future improvement
*/
if ( (*dlip)->dli_ad == ad &&
(*dlip)->dli_dlm->dlm_next == NULL &&
member_ad == (*dlip)->dli_dlm->dlm_member_ad ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"\"dynlist-attrpair <member-ad> <URL-ad>\": "
"URL attributeDescription \"%s\" already mapped.\n",
......@@ -1323,7 +1485,9 @@ dl_cfgen( ConfigArgs *c )
(*dlip)->dli_oc = oc;
(*dlip)->dli_ad = ad;
(*dlip)->dli_member_ad = member_ad;
(*dlip)->dli_dlm = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) );
(*dlip)->dli_dlm->dlm_member_ad = member_ad;
(*dlip)->dli_dlm->dlm_mapped_ad = NULL;
rc = dynlist_build_def_filter( *dlip );
......@@ -1426,9 +1590,18 @@ dynlist_db_destroy(
*dli_next;
for ( dli_next = dli; dli_next; dli = dli_next ) {
dynlist_map_t *dlm;
dynlist_map_t *dlm_next;
dli_next = dli->dli_next;
ch_free( dli->dli_default_filter.bv_val );
dlm = dli->dli_dlm;
while ( dlm != NULL ) {
dlm_next = dlm->dlm_next;
ch_free( dlm );
dlm = dlm_next;
}
ch_free( dli );
}
}
......
......@@ -737,6 +737,13 @@ syncprov_free_syncop( syncops *so )
ldap_pvt_thread_mutex_unlock( &so->s_mutex );
return;
}
if ( so->s_qtask ) {
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, so->s_qtask ) )
ldap_pvt_runqueue_stoptask( &slapd_rq, so->s_qtask );
ldap_pvt_runqueue_remove( &slapd_rq, so->s_qtask );
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
}
ldap_pvt_thread_mutex_unlock( &so->s_mutex );
if ( so->s_flags & PS_IS_DETACHED ) {
filter_free( so->s_op->ors_filter );
......@@ -1169,10 +1176,14 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss;
sprev = ss, ss=snext)
{
Operation op2;
syncmatches *sm;
int found = 0;
snext = ss->s_next;
if ( ss->s_op->o_abandon )
continue;
/* validate base */
fc.fss = ss;
fc.fbase = 0;
......@@ -1213,8 +1224,11 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
}
}
if ( fc.fscope )
op2 = *ss->s_op;
/* check if current o_req_dn is in scope and matches filter */
if ( fc.fscope && test_filter( ss->s_op, e, ss->s_op->ors_filter ) ==
if ( fc.fscope && test_filter( &op2, e, ss->s_op->ors_filter ) ==
LDAP_COMPARE_TRUE ) {
if ( saveit ) {
sm = op->o_tmpalloc( sizeof(syncmatches), op->o_tmpmemctx );
......@@ -2389,7 +2403,14 @@ syncprov_operational(
if ( !ap ) {
if ( !(rs->sr_flags & REP_ENTRY_MODIFIABLE) ) {
rs->sr_entry = entry_dup( rs->sr_entry );
Entry *e = entry_dup( rs->sr_entry );
if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) {
overlay_entry_release_ov( op, rs->sr_entry, 0, on );
rs->sr_flags ^= REP_ENTRY_MUSTRELEASE;
} else if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) {
entry_free( rs->sr_entry );
}
rs->sr_entry = e;
rs->sr_flags |=
REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED;
a = attr_find( rs->sr_entry->e_attrs,
......
......@@ -106,7 +106,7 @@ typedef struct syncinfo_s {
static int syncuuid_cmp( const void *, const void * );
static int avl_presentlist_insert( syncinfo_t* si, struct berval *syncUUID );
static void syncrepl_del_nonpresent( Operation *, syncinfo_t *, BerVarray, struct berval * );
static void syncrepl_del_nonpresent( Operation *, syncinfo_t *, BerVarray, struct sync_cookie *, int );
static int syncrepl_message_to_op(
syncinfo_t *, Operation *, LDAPMessage * );
static int syncrepl_message_to_entry(
......@@ -683,7 +683,7 @@ compare_csns( struct sync_cookie *sc1, struct sync_cookie *sc2, int *which )
}
for (i=0; i<sc1->numcsns; i++) {
for (j=0; i<sc2->numcsns; j++) {
for (j=0; j<sc2->numcsns; j++) {
if ( sc1->sids[i] != sc2->sids[j] )
continue;
value_match( &match, slap_schema.si_ad_entryCSN,
......@@ -950,7 +950,7 @@ do_syncrep2(
syncCookie_req.numcsns == syncCookie.numcsns )
{
syncrepl_del_nonpresent( op, si, NULL,
&syncCookie.ctxcsn[m] );
&syncCookie, m );
} else {
avl_free( si->si_presentlist, ch_free );
si->si_presentlist = NULL;
......@@ -1061,7 +1061,7 @@ do_syncrep2(
ber_scanf( ber, /*"{"*/ "}" );
if ( refreshDeletes ) {
syncrepl_del_nonpresent( op, si, syncUUIDs,
&syncCookie.ctxcsn[m] );
&syncCookie, m );
ber_bvarray_free_x( syncUUIDs, op->o_tmpmemctx );
} else {
int i;
......@@ -1099,7 +1099,7 @@ do_syncrep2(
if ( si->si_refreshPresent == 1 &&
syncCookie_req.numcsns == syncCookie.numcsns ) {
syncrepl_del_nonpresent( op, si, NULL,
&syncCookie.ctxcsn[m] );
&syncCookie, m );
}
if ( syncCookie.ctxcsn )
......@@ -2352,7 +2352,8 @@ syncrepl_del_nonpresent(
Operation *op,
syncinfo_t *si,
BerVarray uuids,
struct berval *cookiecsn )
struct sync_cookie *sc,
int m )
{
Backend* be = op->o_bd;
slap_callback cb = { NULL };
......@@ -2405,6 +2406,8 @@ syncrepl_del_nonpresent(
}
si->si_refreshDelete ^= NP_DELETE_ONE;
} else {
Filter *cf, *of;
memset( &an[0], 0, 2 * sizeof( AttributeName ) );
an[0].an_name = slap_schema.si_ad_entryUUID->ad_cname;
an[0].an_desc = slap_schema.si_ad_entryUUID;
......@@ -2412,21 +2415,56 @@ syncrepl_del_nonpresent(
op->ors_slimit = SLAP_NO_LIMIT;
op->ors_attrsonly = 0;
op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val );
op->ors_filterstr = si->si_filterstr;
/* In multimaster, updates can continue to arrive while
* we're searching. Limit the search result to entries
* older than all of our cookie CSNs.
*/
if ( SLAP_MULTIMASTER( op->o_bd )) {
Filter *f;
int i;
cf = op->o_tmpalloc( (sc->numcsns+1) * sizeof(Filter) +
sc->numcsns * sizeof(AttributeAssertion), op->o_tmpmemctx );
f = cf;
f->f_choice = LDAP_FILTER_AND;
f->f_next = NULL;
f->f_and = f+1;
of = f->f_and;
for ( i=0; i<sc->numcsns; i++ ) {
f = of;
f->f_choice = LDAP_FILTER_LE;
f->f_ava = (AttributeAssertion *)(f+1);
f->f_av_desc = slap_schema.si_ad_entryCSN;
f->f_av_value = sc->ctxcsn[i];
f->f_next = (Filter *)(f->f_ava+1);
of = f->f_next;
}
f->f_next = op->ors_filter;
of = op->ors_filter;
op->ors_filter = cf;
filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
} else {
cf = NULL;
op->ors_filterstr = si->si_filterstr;
}
op->o_nocaching = 1;
if ( limits_check( op, &rs_search ) == 0 ) {
rc = be->be_search( op, &rs_search );
}
if ( SLAP_MULTIMASTER( op->o_bd )) {
op->o_tmpfree( cf, op->o_tmpmemctx );
op->ors_filter = of;
}
if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
}
op->o_nocaching = 0;
if ( !LDAP_LIST_EMPTY( &si->si_nonpresentlist ) ) {
if ( cookiecsn && !BER_BVISNULL( cookiecsn ) ) {
csn = *cookiecsn;
if ( sc->ctxcsn && !BER_BVISNULL( &sc->ctxcsn[m] ) ) {
csn = sc->ctxcsn[m];
} else {
csn = si->si_syncCookie.ctxcsn[0];
}
......
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2006-2008 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
* This work was initially developed by Howard Chu for inclusion
* in OpenLDAP Software.
*/
#include "portable.h"
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/ctype.h>
#include <ac/param.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/unistd.h>
#include <ac/wait.h>
#include <ac/time.h>
#include <ac/signal.h>
#include <ldap.h>
#include <ldap_pvt_thread.h>
#include <lutil.h>
static int
do_time( );
/* This program is a simplified version of SLAMD's WeightedAuthRate jobclass.
* It doesn't offer as much configurability, but it's a good starting point.
* When run without the -R option it will behave as a Standard AuthRate job.
* Eventually this will grow into a set of C-based load generators for the SLAMD
* framework. This code is anywhere from 2 to 10 times more efficient than the
* original Java code, allowing servers to be fully loaded without requiring
* anywhere near as much load-generation hardware.
*/
static void
usage( char *name )
{
fprintf( stderr, "usage: %s -H <uri> -b <baseDN> -w <passwd> -t <seconds> -r lo:hi\n\t"
"[-R %:lo:hi] [-f <filter-template>] [-n <threads>] [-D <bindDN>] [-i <seconds>]\n",
name );
exit( EXIT_FAILURE );
}
static char *filter = "(uid=user.%d)";
static char hname[1024];
static char *uri = "ldap:///";
static char *base;
static char *pass;
static char *binder;
static int tdur, r1per, r1lo, r1hi, r2per, r2lo, r2hi;
static int threads = 1;
static int interval = 30;
static volatile int *r1binds, *r2binds;
static int *r1old, *r2old;
static volatile int finish;
int
main( int argc, char **argv )
{
int i;
while ( (i = getopt( argc, argv, "b:D:H:w:f:n:i:t:r:R:" )) != EOF ) {
switch( i ) {
case 'b': /* base DN of a tree of user DNs */
base = strdup( optarg );
break;
case 'D':
binder = strdup( optarg );
break;
case 'H': /* the server uri */
uri = strdup( optarg );
break;
case 'w':
pass = strdup( optarg );
break;
case 't': /* the duration to run */
if ( lutil_atoi( &tdur, optarg ) != 0 ) {
usage( argv[0] );
}
break;
case 'i': /* the time interval */
if ( lutil_atoi( &interval, optarg ) != 0 ) {
usage( argv[0] );
}
break;
case 'r': /* the uid range */
if ( sscanf(optarg, "%d:%d", &r1lo, &r1hi) != 2 ) {
usage( argv[0] );
}
break;
case 'R': /* percentage:2nd uid range */
if ( sscanf(optarg, "%d:%d:%d", &r2per, &r2lo, &r2hi) != 3 ) {
usage( argv[0] );
}
break;
case 'f':
filter = optarg;
break;
case 'n':
if ( lutil_atoi( &threads, optarg ) != 0 || threads < 1 ) {
usage( argv[0] );
}
break;
default:
usage( argv[0] );
break;
}
}
if ( tdur == 0 || r1hi <= r1lo )
usage( argv[0] );
r1per = 100 - r2per;
if ( r1per < 1 )
usage( argv[0] );
r1binds = calloc( threads*4, sizeof( int ));
r2binds = r1binds + threads;
r1old = (int *)r2binds + threads;
r2old = r1old + threads;
do_time( );
exit( EXIT_SUCCESS );
}
static void *
my_task( void *my_num )
{
LDAP *ld = NULL, *sld = NULL;
ber_int_t msgid;
LDAPMessage *res, *msg;
char *attrs[] = { "1.1", NULL };
int rc = LDAP_SUCCESS;
int tid = *(int *)my_num;
ldap_initialize( &ld, uri );
if ( ld == NULL ) {
perror( "ldap_initialize" );
return NULL;
}
{
int version = LDAP_VERSION3;
(void) ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
&version );
}
(void) ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
ldap_initialize( &sld, uri );
if ( sld == NULL ) {
perror( "ldap_initialize" );
return NULL;
}
{
int version = LDAP_VERSION3;
(void) ldap_set_option( sld, LDAP_OPT_PROTOCOL_VERSION,
&version );
}
(void) ldap_set_option( sld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
if ( binder ) {
rc = ldap_bind_s( sld, binder, pass, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( sld, "ldap_bind" );
}
}
r1binds[tid] = 0;
for (;;) {
char dn[BUFSIZ], *ptr, fstr[256];
int j, isr1;
if ( finish )
break;
j = rand() % 100;
if ( j < r1per ) {
j = rand() % r1hi;
isr1 = 1;
} else {
j = rand() % (r2hi - r2lo + 1 );
j += r2lo;
isr1 = 0;
}
sprintf(fstr, filter, j);
rc = ldap_search_ext( sld, base, LDAP_SCOPE_SUB,
fstr, attrs, 0, NULL, NULL, 0, 0, &msgid );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( sld, "ldap_search_ex" );
return NULL;
}
while (( rc=ldap_result( sld, LDAP_RES_ANY, LDAP_MSG_ONE, NULL, &res )) >0){
BerElement *ber;
struct berval bv;
char *ptr;
int done = 0;
for (msg = ldap_first_message( sld, res ); msg;
msg = ldap_next_message( sld, msg )) {
switch ( ldap_msgtype( msg )) {
case LDAP_RES_SEARCH_ENTRY:
rc = ldap_get_dn_ber( sld, msg, &ber, &bv );
strcpy(dn, bv.bv_val );
ber_free( ber, 0 );
break;
case LDAP_RES_SEARCH_RESULT:
done = 1;
break;
}
if ( done )
break;
}
ldap_msgfree( res );
if ( done ) break;
}
rc = ldap_bind_s( ld, dn, pass, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_bind" );
}
if ( isr1 )
r1binds[tid]++;
else
r2binds[tid]++;
}
ldap_unbind( sld );
ldap_unbind( ld );
return NULL;
}
static int
do_time( )
{
struct timeval tv;
time_t now, prevt, start;
int r1new, r2new;
int dt, dr1, dr2, rr1, rr2;
int dr10, dr20;
int i;
gethostname(hname, sizeof(hname));
printf("%s(tid)\tdeltaT\tauth1\tauth2\trate1\trate2\tRate1+2\n", hname);
srand(getpid());
prevt = start = time(0L);
for ( i = 0; i<threads; i++ ) {
ldap_pvt_thread_t thr;
r1binds[i] = i;
ldap_pvt_thread_create( &thr, 1, my_task, (void *)&r1binds[i] );
}
for (;;) {
tv.tv_sec = interval;
tv.tv_usec = 0;
select(0, NULL, NULL, NULL, &tv);
now = time(0L);
dt = now - prevt;
prevt = now;
dr10 = 0;
dr20 = 0;
for ( i = 0; i < threads; i++ ) {
r1new = r1binds[i];
r2new = r2binds[i];
dr1 = r1new - r1old[i];
dr2 = r2new - r2old[i];
rr1 = dr1 / dt;
rr2 = dr2 / dt;
printf("%s(%d)\t%d\t%d\t%d\t%d\t%d\t%d\n",
hname, i, dt, dr1, dr2, rr1, rr2, rr1 + rr2);
dr10 += dr1;
dr20 += dr2;
r1old[i] = r1new;
r2old[i] = r2new;
}
if ( i > 1 ) {
rr1 = dr10 / dt;
rr2 = dr20 / dt;
printf("%s(sum)\t%d\t%d\t%d\t%d\t%d\t%d\n",
hname, 0, dr10, dr20, rr1, rr2, rr1 + rr2);
}
if ( now - start >= tdur ) {
finish = 1;
break;
}
}
return 0;
}
......@@ -157,13 +157,13 @@ changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=$URI1 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
olcSyncRepl: rid=002 provider=$URI2 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
olcSyncRepl: rid=003 provider=$URI3 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
......@@ -213,13 +213,13 @@ changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=$URI1 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
olcSyncRepl: rid=002 provider=$URI2 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
olcSyncRepl: rid=003 provider=$URI3 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
......@@ -263,13 +263,13 @@ changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=$URI1 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
olcSyncRepl: rid=002 provider=$URI2 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
olcSyncRepl: rid=003 provider=$URI3 binddn="cn=config" bindmethod=simple
credentials=$CONFIGPW searchbase="cn=config" type=refreshAndPersist
retry="5 5 300 5" timeout=1
retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
......@@ -321,13 +321,13 @@ olcRootDN: $MANAGERDN
olcRootPW: $PASSWD
olcSyncRepl: rid=004 provider=$URI1 binddn="$MANAGERDN" bindmethod=simple
credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly
interval=00:00:00:10 retry="5 5 300 5" timeout=1
interval=00:00:00:10 retry="5 5 300 5" timeout=3
olcSyncRepl: rid=005 provider=$URI2 binddn="$MANAGERDN" bindmethod=simple
credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly
interval=00:00:00:10 retry="5 5 300 5" timeout=1
interval=00:00:00:10 retry="5 5 300 5" timeout=3
olcSyncRepl: rid=006 provider=$URI3 binddn="$MANAGERDN" bindmethod=simple
credentials=$PASSWD searchbase="$BASEDN" type=refreshOnly
interval=00:00:00:10 retry="5 5 300 5" timeout=1
interval=00:00:00:10 retry="5 5 300 5" timeout=3
olcMirrorMode: TRUE
dn: olcOverlay=syncprov,olcDatabase={1}${BACKEND},cn=config
......