Commit b94d5e17 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

rework op/rs structures to deal with opeartional attributes

parent 448e2dca
......@@ -91,23 +91,26 @@ retry:
int
bdb_operational(
Operation *op,
SlapReply *rs,
int opattrs,
Attribute **a )
SlapReply *rs )
{
Attribute **aa = a;
Attribute **ap;
assert( rs->sr_entry );
if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) {
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( rs->sr_opattrs == SLAP_OPATTRS ||
ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
{
int hasSubordinates;
rs->sr_err = bdb_hasSubordinates( op, rs->sr_entry, &hasSubordinates );
if ( rs->sr_err == LDAP_SUCCESS ) {
*aa = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
if ( *aa != NULL ) {
aa = &(*aa)->a_next;
}
*ap = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
assert( *ap );
ap = &(*ap)->a_next;
}
}
......
......@@ -770,7 +770,7 @@ dn2entry_retry:
}
/* if not root and candidates exceed to-be-checked entries, abort */
if ( sop->ors_limit /* isroot == TRUE */ &&
if ( sop->ors_limit /* isroot == FALSE */ &&
sop->ors_limit->lms_s_unchecked != -1 &&
BDB_IDL_N(candidates) > (unsigned) sop->ors_limit->lms_s_unchecked )
{
......@@ -780,7 +780,7 @@ dn2entry_retry:
goto done;
}
if ( sop->ors_limit == NULL /* isroot == FALSE */ ||
if ( sop->ors_limit == NULL /* isroot == TRUE */ ||
!sop->ors_limit->lms_s_pr_hide )
{
tentries = BDB_IDL_N(candidates);
......@@ -1234,6 +1234,7 @@ id2entry_retry:
num_ctrls++, 1, &cookie );
if ( rs->sr_err != LDAP_SUCCESS ) goto done;
rs->sr_attrs = attrs;
rs->sr_operational_attrs = NULL;
rs->sr_ctrls = ctrls;
rs->sr_flags = 0;
result = send_search_entry( sop, rs );
......@@ -1276,6 +1277,7 @@ id2entry_retry:
if ( rs->sr_err != LDAP_SUCCESS ) goto done;
rs->sr_ctrls = ctrls;
rs->sr_attrs = sop->oq_search.rs_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_flags = 0;
result = send_search_entry( sop, rs );
slap_sl_free(
......@@ -1320,6 +1322,7 @@ id2entry_retry:
} else {
rs->sr_attrs = sop->oq_search.rs_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_ctrls = NULL;
rs->sr_flags = 0;
rs->sr_err = LDAP_SUCCESS;
......
......@@ -189,6 +189,7 @@ fail:;
if ( rc == LDAP_SUCCESS ) {
rs->sr_entry = &ent;
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_flags = 0;
abort = send_search_entry( op, rs );
while (ent.e_attrs) {
......
......@@ -51,24 +51,27 @@ ldbm_back_hasSubordinates(
int
ldbm_back_operational(
Operation *op,
SlapReply *rs,
int opattrs,
Attribute **a )
SlapReply *rs )
{
Attribute **aa = a;
Attribute **ap;
assert( rs->sr_entry );
if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) {
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( rs->sr_opattrs == SLAP_OPATTRS ||
ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
{
int hs;
hs = has_children( op->o_bd, rs->sr_entry );
*aa = slap_operational_hasSubordinate( hs );
if ( *aa != NULL ) {
aa = &(*aa)->a_next;
}
*ap = slap_operational_hasSubordinate( hs );
assert( *ap );
ap = &(*ap)->a_next;
}
return 0;
}
......@@ -205,7 +205,7 @@ searchit:
}
/* if candidates exceed to-be-checked entries, abort */
if ( op->ors_limit /* isroot == TRUE */
if ( op->ors_limit /* isroot == FALSE */
&& op->ors_limit->lms_s_unchecked != -1
&& ID_BLOCK_NIDS( candidates ) > (unsigned) op->ors_limit->lms_s_unchecked )
{
......
......@@ -37,16 +37,18 @@
int
monitor_back_operational(
Operation *op,
SlapReply *rs,
int opattrs,
Attribute **a )
SlapReply *rs )
{
Attribute **aa = a;
Attribute **ap;
assert( rs->sr_entry );
if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates,
rs->sr_attrs ) ) {
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( rs->sr_opattrs == SLAP_OPATTRS ||
ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
{
int hs;
struct monitorentrypriv *mp;
......@@ -55,10 +57,9 @@ monitor_back_operational(
assert( mp );
hs = MONITOR_HAS_CHILDREN( mp );
*aa = slap_operational_hasSubordinate( hs );
if ( *aa != NULL ) {
aa = &(*aa)->a_next;
}
*ap = slap_operational_hasSubordinate( hs );
assert( *ap );
ap = &(*ap)->a_next;
}
return 0;
......
......@@ -529,7 +529,7 @@ relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
int rc = 0;
bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
if ( bd == NULL ) {
if ( bd == NULL || bd == op->o_bd ) {
return 0;
}
......@@ -553,8 +553,7 @@ relay_back_chk_referrals( struct slap_op *op, struct slap_rep *rs )
}
int
relay_back_operational( struct slap_op *op, struct slap_rep *rs,
int opattrs, Attribute **ap )
relay_back_operational( struct slap_op *op, struct slap_rep *rs )
{
relay_back_info *ri = (relay_back_info *)op->o_bd->be_private;
BackendDB *bd;
......@@ -575,7 +574,7 @@ relay_back_operational( struct slap_op *op, struct slap_rep *rs,
relay_back_add_cb( &cb, op );
op->o_bd = bd;
rc = ( bd->be_operational )( op, rs, opattrs, ap );
rc = ( bd->be_operational )( op, rs );
op->o_bd = be;
if ( op->o_callback == &cb ) {
......
......@@ -35,7 +35,7 @@ backsql_compare( Operation *op, SlapReply *rs )
backsql_entryID user_id = BACKSQL_ENTRYID_INIT;
SQLHDBC dbh;
Entry *e = NULL, user_entry;
Attribute *a = NULL, *a_op = NULL;
Attribute *a = NULL;
backsql_srch_info bsi;
int rc;
AttributeName anlist[2];
......@@ -79,41 +79,31 @@ backsql_compare( Operation *op, SlapReply *rs )
goto return_results;
}
memset( &anlist[0], 0, 2 * sizeof( AttributeName ) );
anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc;
anlist[1].an_name.bv_val = NULL;
/*
* Try to get attr as dynamic operational
*/
if ( is_at_operational( op->oq_compare.rs_ava->aa_desc->ad_type ) ) {
AttributeName *an_old;
Entry *e_old;
SlapReply nrs = { 0 };
user_entry.e_attrs = NULL;
user_entry.e_name = op->o_req_dn;
user_entry.e_nname = op->o_req_ndn;
an_old = rs->sr_attrs;
e_old = rs->sr_entry;
rs->sr_attrs = anlist;
rs->sr_entry = &user_entry;
rs->sr_err = backsql_operational( op, rs, 0, &a_op );
rs->sr_attrs = an_old;
rs->sr_entry = e_old;
nrs.sr_attrs = anlist;
nrs.sr_entry = &user_entry;
nrs.sr_opattrs = SLAP_OPATTRS_NO;
nrs.sr_operational_attrs = NULL;
rs->sr_err = backsql_operational( op, &nrs );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto return_results;
}
}
/*
* attr was dynamic operational
*/
if ( a_op != NULL ) {
user_entry.e_attrs = a_op;
user_entry.e_attrs = nrs.sr_operational_attrs;
e = &user_entry;
} else {
......
......@@ -35,21 +35,21 @@
int
backsql_operational(
Operation *op,
SlapReply *rs,
int opattrs,
Attribute **a )
SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
SQLHDBC dbh = SQL_NULL_HDBC;
Attribute **aa = a;
int rc = 0;
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
SQLHDBC dbh = SQL_NULL_HDBC;
int rc = 0;
Attribute **ap;
Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n",
rs->sr_entry->e_nname.bv_val, 0, 0 );
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
if ( ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
if ( ( rs->sr_opattrs == SLAP_OPATTRS || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) {
rc = backsql_get_db_conn( op, &dbh );
......@@ -65,10 +65,9 @@ backsql_operational(
switch( rc ) {
case LDAP_COMPARE_TRUE:
case LDAP_COMPARE_FALSE:
*aa = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
if ( *aa != NULL ) {
aa = &(*aa)->a_next;
}
*ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
assert( *ap );
ap = &(*ap)->a_next;
rc = 0;
break;
......
......@@ -1577,11 +1577,13 @@ backsql_search( Operation *op, SlapReply *rs )
#endif
{
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_entry = entry;
rs->sr_flags = REP_ENTRY_MODIFIABLE;
sres = send_search_entry( op, rs );
rs->sr_entry = NULL;
rs->sr_attrs = NULL;
rs->sr_operational_attrs = NULL;
}
switch ( sres ) {
......
......@@ -770,7 +770,6 @@ int
be_isroot_pw( Operation *op )
{
int result;
char *errmsg;
if ( ! be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
return 0;
......@@ -1488,30 +1487,39 @@ freeit: if (e != target ) {
return rc;
}
Attribute *backend_operational(
int backend_operational(
Operation *op,
SlapReply *rs,
int opattrs )
SlapReply *rs )
{
Attribute *a = NULL, **ap = &a;
Attribute **ap;
int rc = 0;
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count them */ ;
/*
* If operational attributes (allegedly) are required,
* and the backend supports specific operational attributes,
* add them to the attribute list
*/
if ( opattrs || ( op->ors_attrs &&
if ( rs->sr_opattrs == SLAP_OPATTRS || ( op->ors_attrs &&
ad_inlist( slap_schema.si_ad_subschemaSubentry, op->ors_attrs )) ) {
*ap = slap_operational_subschemaSubentry( op->o_bd );
ap = &(*ap)->a_next;
}
if ( ( opattrs || op->ors_attrs ) && op->o_bd &&
if ( ( rs->sr_opattrs == SLAP_OPATTRS || op->ors_attrs ) && op->o_bd &&
op->o_bd->be_operational != NULL )
{
( void )op->o_bd->be_operational( op, rs, opattrs, ap );
rs->sr_operational_attrs = NULL;
rc = op->o_bd->be_operational( op, rs );
*ap = rs->sr_operational_attrs;
for ( ; *ap; ap = &(*ap)->a_next )
/* just count them */ ;
}
return a;
return rc;
}
......@@ -160,6 +160,7 @@ enum op_which {
op_abandon,
op_cancel,
op_extended,
op_aux_operational,
op_aux_chk_referrals,
op_last
};
......@@ -180,6 +181,7 @@ static int op_rc[] = {
LDAP_UNWILLING_TO_PERFORM, /* abandon */
LDAP_UNWILLING_TO_PERFORM, /* cancel */
LDAP_UNWILLING_TO_PERFORM, /* extended */
LDAP_SUCCESS, /* aux_operational */
LDAP_SUCCESS /* aux_chk_referrals */
};
......@@ -292,7 +294,13 @@ over_op_extended( Operation *op, SlapReply *rs )
}
static int
over_chk_referrals( Operation *op, SlapReply *rs )
over_aux_operational( Operation *op, SlapReply *rs )
{
return over_op_func( op, rs, op_aux_operational );
}
static int
over_aux_chk_referrals( Operation *op, SlapReply *rs )
{
return over_op_func( op, rs, op_aux_chk_referrals );
}
......@@ -325,7 +333,7 @@ static const char overtype[] = "over";
int
overlay_config( BackendDB *be, const char *ov )
{
slap_overinst *on = NULL, *on2 = NULL, *prev = NULL;
slap_overinst *on = NULL, *on2 = NULL;
slap_overinfo *oi = NULL;
BackendInfo *bi = NULL;
......@@ -380,7 +388,8 @@ overlay_config( BackendDB *be, const char *ov )
* all the hooks to share the same args
* of the operations...
*/
bi->bi_chk_referrals = over_chk_referrals;
bi->bi_operational = over_aux_operational;
bi->bi_chk_referrals = over_aux_chk_referrals;
be->bd_info = bi;
......
......@@ -450,7 +450,6 @@ refint_response(
BerValue ndn, moddn, pdn;
BerVarray b = NULL;
int rc, ac, i, j, ksize;
AttributeName an[2];
id->message = "_refint_response";
......@@ -556,10 +555,9 @@ refint_response(
nop.ors_tlimit = SLAP_NO_LIMIT;
/* no attrs! */
memset( &an[0], 0, sizeof( AttributeName ) );
BER_BVSTR( &an[0].an_name, LDAP_NO_ATTRS );
BER_BVZERO( &an[1].an_name );
nop.ors_attrs = an;
nop.ors_attrs = slap_anlist_no_attrs;
nop.ors_attrsonly = 1;
nop.o_sync_slog_size = -1;
nop.o_req_ndn = id->dn;
nop.o_req_dn = id->dn;
......
......@@ -274,7 +274,7 @@ rwm_delete( Operation *op, SlapReply *rs )
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "deleteDn massage error" );
return rc;
return -1;
}
return SLAP_CB_CONTINUE;
......@@ -300,7 +300,7 @@ rwm_modify( Operation *op, SlapReply *rs )
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "modifyDn massage error" );
return rc;
return -1;
}
isupdate = be_shadow_update( op );
......@@ -425,8 +425,43 @@ static int
rwm_modrdn( Operation *op, SlapReply *rs )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
struct ldaprwmap *rwmap =
(struct ldaprwmap *)on->on_bi.bi_private;
int rc;
if ( op->orr_newSup ) {
dncookie dc;
struct berval nnewSup = BER_BVNULL;
struct berval newSup = BER_BVNULL;
/*
* Rewrite the new superior, if defined and required
*/
dc.rwmap = rwmap;
#ifdef ENABLE_REWRITE
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "newSuperiorDN";
#else
dc.tofrom = 0;
dc.normalized = 0;
#endif
rc = rwm_dn_massage( &dc, op->orr_newSup, &newSup, &nnewSup );
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "newSuperiorDN massage error" );
return -1;
}
if ( op->orr_newSup->bv_val != newSup.bv_val ) {
op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
*op->orr_newSup = newSup;
*op->orr_nnewSup = nnewSup;
}
}
#ifdef ENABLE_REWRITE
rc = rwm_op_dn_massage( op, rs, "renameDn" );
#else
......@@ -436,7 +471,7 @@ rwm_modrdn( Operation *op, SlapReply *rs )
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "renameDn massage error" );
return rc;
return -1;
}
/* TODO: rewrite attribute types, values of DN-valued attributes ... */
......@@ -572,7 +607,7 @@ error_return:;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, text );
return 1;
return -1;
}
......@@ -591,7 +626,7 @@ rwm_extended( Operation *op, SlapReply *rs )
if ( rc != LDAP_SUCCESS ) {
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, "extendedDn massage error" );
return rc;
return -1;
}
/* TODO: rewrite/map extended data ? ... */
......@@ -644,21 +679,15 @@ rwm_matched( Operation *op, SlapReply *rs )
}
static int
rwm_send_entry( Operation *op, SlapReply *rs )
rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
{
slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
struct ldaprwmap *rwmap =
(struct ldaprwmap *)on->on_bi.bi_private;
Entry *e = NULL;
int flags;
struct berval dn = BER_BVNULL,
ndn = BER_BVNULL;
dncookie dc;
int rc;
Attribute **ap;
assert( rs->sr_entry );
dncookie dc;
int rc;
Attribute **ap;
/*
* Rewrite the dn of the result, if needed
......@@ -667,62 +696,35 @@ rwm_send_entry( Operation *op, SlapReply *rs )
#ifdef ENABLE_REWRITE
dc.conn = op->o_conn;
dc.rs = NULL;
dc.ctx = "searchResult";
dc.ctx = "searchAttrDN";
#else
dc.tofrom = 0;
dc.normalized = 0;
#endif
e = rs->sr_entry;
flags = rs->sr_flags;
if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
/* FIXME: all we need to duplicate are:
* - dn
* - ndn
* - attributes that are requested
* - no values if attrsonly is set
*/
e = entry_dup( e );
if ( e == NULL ) {
rc = LDAP_NO_MEMORY;
goto fail;
}
flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
}
/*
* Note: this may fail if the target host(s) schema differs
* from the one known to the meta, and a DN with unknown
* attributes is returned.
*/
rc = rwm_dn_massage( &dc, &e->e_name, &dn, &ndn );
if ( rc != LDAP_SUCCESS ) {
goto fail;
}
if ( e->e_name.bv_val != dn.bv_val ) {
free( e->e_name.bv_val );
free( e->e_nname.bv_val );