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;
}
}
}
/* 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 )
{
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);
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 );
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(
} 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;
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) {
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;
}
}
/* 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 )
{
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;
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;
int rc = 0;
bd = relay_back_select_backend( op, rs, LDAP_SUCCESS );
- if ( bd == NULL ) {
+ if ( bd == NULL || bd == op->o_bd ) {
return 0;
}
}
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;
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 ) {
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];
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 {
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 );
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;
#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 ) {
be_isroot_pw( Operation *op )
{
int result;
- char *errmsg;
if ( ! be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
return 0;
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;
}
op_abandon,
op_cancel,
op_extended,
+ op_aux_operational,
op_aux_chk_referrals,
op_last
};
LDAP_UNWILLING_TO_PERFORM, /* abandon */
LDAP_UNWILLING_TO_PERFORM, /* cancel */
LDAP_UNWILLING_TO_PERFORM, /* extended */
+ LDAP_SUCCESS, /* aux_operational */
LDAP_SUCCESS /* aux_chk_referrals */
};
}
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 );
}
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;
* 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;
BerValue ndn, moddn, pdn;
BerVarray b = NULL;
int rc, ac, i, j, ksize;
- AttributeName an[2];
id->message = "_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;
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;
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 );
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
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 ... */
op->o_bd->bd_info = (BackendInfo *)on->on_info;
send_ldap_error( op, rs, rc, text );
- return 1;
+ return -1;
}
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 ? ... */
}
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
#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 );
-
- e->e_name = dn;
- e->e_nname = ndn;
- }
-
- /* TODO: map entry attribute types, objectclasses
- * and dn-valued attribute values */
-
/* FIXME: the entries are in the remote mapping form;
* so we need to select those attributes we are willing
* to return, and remap them accordingly */
- for ( ap = &e->e_attrs; *ap; ) {
+ /* FIXME: in principle, one could map an attribute
+ * on top of another, which already exists.
+ * As such, in the end there might exist more than
+ * one instance of an attribute.
+ * We should at least check if this occurs, and issue
+ * an error (because multiple instances of attrs in
+ * response are not valid), or merge the values (what
+ * about duplicate values?) */
+ for ( ap = a_first; *ap; ) {
struct ldapmapping *m;
int drop_missing;
int last;
- if ( op->ors_attrs != NULL && !ad_inlist( (*ap)->a_desc, op->ors_attrs ) ) {
+ if ( rs->sr_opattrs == SLAP_OPATTRS && is_at_operational( (*ap)->a_desc->ad_type ) )
+ {
+ /* go on */ ;
+
+ } else if ( op->ors_attrs != NULL && !ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
+ {
Attribute *a;
a = *ap;
ap = &(*ap)->a_next;
}
+ return 0;
+}
+
+static int
+rwm_send_entry( Operation *op, SlapReply *rs )
+{
+ 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;
+
+ assert( rs->sr_entry );
+
+ /*
+ * Rewrite the dn of the result, if needed
+ */
+ dc.rwmap = rwmap;
+#ifdef ENABLE_REWRITE
+ dc.conn = op->o_conn;
+ dc.rs = NULL;
+ dc.ctx = "searchResult";
+#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 );
+
+ e->e_name = dn;
+ e->e_nname = ndn;
+ }
+
+ /* TODO: map entry attribute types, objectclasses
+ * and dn-valued attribute values */
+
+ /* FIXME: the entries are in the remote mapping form;
+ * so we need to select those attributes we are willing
+ * to return, and remap them accordingly */
+ rwm_attrs( op, rs, &e->e_attrs );
rs->sr_entry = e;
rs->sr_flags = flags;
return rc;
}
+static int
+rwm_operational( Operation *op, SlapReply *rs )
+{
+ /* FIXME: the entries are in the remote mapping form;
+ * so we need to select those attributes we are willing
+ * to return, and remap them accordingly */
+ if ( rs->sr_operational_attrs ) {
+ rwm_attrs( op, rs, &rs->sr_operational_attrs );
+ }
+
+ return SLAP_CB_CONTINUE;
+}
+
static int
rwm_rw_config(
BackendDB *be,
rwm.on_bi.bi_op_delete = rwm_delete;
rwm.on_bi.bi_op_unbind = rwm_unbind;
rwm.on_bi.bi_extended = rwm_extended;
+ rwm.on_bi.bi_operational = rwm_operational;
rwm.on_response = rwm_response;
if(!up) continue;
}
if((b = a->a_vals) && b[0].bv_val) for(i = 0; b[i].bv_val; i++)
- ks += b[i].bv_len + a->a_desc->ad_cname.bv_len + 3;
+ ks += b[i].bv_len + a->a_desc->ad_cname.bv_len + STRLENOF( "(=)" );
else if(ud->strict)
- ks += a->a_desc->ad_cname.bv_len + 4; /* (attr=*) */
+ ks += a->a_desc->ad_cname.bv_len + STRLENOF( "(=*)" );
}
key = ch_malloc(ks);
nop.ors_deref = LDAP_DEREF_NEVER;
nop.ors_slimit = SLAP_NO_LIMIT;
nop.ors_tlimit = SLAP_NO_LIMIT;
+ /* no attrs! */
+ nop.ors_attrs = slap_anlist_no_attrs;
+ nop.ors_attrsonly = 1;
+ nop.o_sync_slog_size = -1;
+
nop.o_req_ndn = ud->dn;
nop.o_ndn = op->o_bd->be_rootndn;
AttributeDescription *ad,
unsigned usage );
+LDAP_SLAPD_V( AttributeName * ) slap_anlist_no_attrs;
+LDAP_SLAPD_V( AttributeName * ) slap_anlist_all_user_attributes;
+LDAP_SLAPD_V( AttributeName * ) slap_anlist_all_operational_attributes;
+LDAP_SLAPD_V( AttributeName * ) slap_anlist_all_attributes;
+
/*
* add.c
*/
BerVarray *vals
));
-LDAP_SLAPD_F (Attribute *) backend_operational(
+LDAP_SLAPD_F (int) backend_operational LDAP_P((
Operation *op,
- SlapReply *rs,
- int opattrs );
+ SlapReply *rs
+));
/*
* backglue.c
{
BerElementBuffer berbuf;
BerElement *ber = (BerElement *) &berbuf;
- Attribute *a, *aa = NULL;
+ Attribute *a;
int i, j, rc=-1, bytes;
char *edn;
int userattrs;
- int opattrs;
AccessControlState acl_state = ACL_STATE_INIT;
#ifdef LDAP_SLAPI
/* Support for computed attribute plugins */
*/
char **e_flags = NULL;
+ rs->sr_type = REP_SEARCH;
+
/* eventually will loop through generated operational attributes */
/* only subschemaSubentry and numSubordinates are implemented */
/* NOTE: moved before overlays callback circling because
* they may modify entry and other stuff in rs */
/* check for special all operational attributes ("+") type */
- opattrs = ( rs->sr_attrs == NULL ) ? 0
- : an_find( rs->sr_attrs, &AllOper );
-
- aa = backend_operational( op, rs, opattrs );
+ /* FIXME: maybe we could se this flag at the operation level;
+ * however, in principle the caller of send_search_entry() may
+ * change the attribute list at each call */
+ rs->sr_opattrs = ( rs->sr_attrs == NULL ) ? SLAP_OPATTRS_NO
+ : ( an_find( rs->sr_attrs, &AllOper ) ? SLAP_OPATTRS : SLAP_OPATTRS_NO );
+
+ rc = backend_operational( op, rs );
+ if ( rc ) {
+ goto error_return;
+ }
- rs->sr_type = REP_SEARCH;
if ( op->o_callback ) {
int first = 1;
slap_callback *sc = op->o_callback,
} else {
/* specific attrs requested */
if ( is_at_operational( desc->ad_type ) ) {
- if( !opattrs && !ad_inlist( desc, rs->sr_attrs ) ) {
+ if ( rs->sr_opattrs != SLAP_OPATTRS &&
+ !ad_inlist( desc, rs->sr_attrs ) )
+ {
continue;
}
} else {
- if (!userattrs && !ad_inlist( desc, rs->sr_attrs ) ) {
+ if ( !userattrs && !ad_inlist( desc, rs->sr_attrs ) )
+ {
continue;
}
}
/* NOTE: moved before overlays callback circling because
* they may modify entry and other stuff in rs */
- if ( aa != NULL && op->o_vrFilter != NULL ) {
+ if ( rs->sr_operational_attrs != NULL && op->o_vrFilter != NULL ) {
int k = 0;
size_t size;
- for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
+ for ( a = rs->sr_operational_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) k++;
}
e_flags = tmp;
a_flags = (char *)(e_flags + i);
memset( a_flags, 0, k );
- for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
+ for ( a = rs->sr_operational_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
e_flags[i] = a_flags;
a_flags += j;
}
- rc = filter_matched_values(op, aa, &e_flags) ;
+ rc = filter_matched_values(op, rs->sr_operational_attrs, &e_flags) ;
if ( rc == -1 ) {
#ifdef NEW_LOGGING
}
}
- for (a = aa, j=0; a != NULL; a = a->a_next, j++ ) {
+ for (a = rs->sr_operational_attrs, j=0; a != NULL; a = a->a_next, j++ ) {
AttributeDescription *desc = a->a_desc;
if ( rs->sr_attrs == NULL ) {
} else {
/* specific attrs requested */
if( is_at_operational( desc->ad_type ) ) {
- if( !opattrs && !ad_inlist( desc, rs->sr_attrs ) ) {
+ if ( rs->sr_opattrs != SLAP_OPATTRS &&
+ !ad_inlist( desc, rs->sr_attrs ) )
+ {
continue;
}
} else {
- if (!userattrs && !ad_inlist( desc, rs->sr_attrs ) ) {
+ if ( !userattrs && !ad_inlist( desc, rs->sr_attrs ) ) {
continue;
}
}
ctx.cac_attrs = rs->sr_attrs;
ctx.cac_attrsonly = op->ors_attrsonly;
ctx.cac_userattrs = userattrs;
- ctx.cac_opattrs = opattrs;
+ ctx.cac_opattrs = rs->sr_opattrs;
ctx.cac_acl_state = acl_state;
ctx.cac_private = (void *)ber;
rc = 0;
error_return:;
- if ( e_flags ) {
- slap_sl_free( e_flags, op->o_tmpmemctx );
- }
-
- if ( aa ) {
- attrs_free( aa );
- }
-
if ( op->o_callback ) {
int first = 1;
slap_callback *sc = op->o_callback,
op->o_callback = sc;
}
+ if ( e_flags ) {
+ slap_sl_free( e_flags, op->o_tmpmemctx );
+ }
+
+ if ( rs->sr_operational_attrs ) {
+ attrs_free( rs->sr_operational_attrs );
+ rs->sr_operational_attrs = NULL;
+ }
+ rs->sr_opattrs = SLAP_OPATTRS_UNDEFINED;
+
/* FIXME: I think rs->sr_type should be explicitly set to
* REP_SEARCH here. That's what it was when we entered this
* function. send_ldap_error may have changed it, but we
op.ors_slimit = 1;
op.ors_filter = &generic_filter;
op.ors_filterstr = generic_filterstr;
+ /* FIXME: we want all attributes, right? */
+ op.ors_attrs = NULL;
op.o_bd->be_search( &op, &rs );
}
#endif
rc = slap_parseURI( opx, rule, &op.o_req_dn,
- &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter,
+ &op.o_req_ndn, &op.ors_scope, &op.ors_filter,
&op.ors_filterstr );
if( rc != LDAP_SUCCESS ) goto CONCLUDED;
- switch ( op.oq_search.rs_scope ) {
+ switch ( op.ors_scope ) {
case LDAP_X_SCOPE_EXACT:
exact_match:
if ( dn_match( &op.o_req_ndn, assertDN ) ) {
rc = LDAP_INAPPROPRIATE_AUTH;
- if ( d == 0 && op.oq_search.rs_scope == LDAP_X_SCOPE_SUBTREE ) {
+ if ( d == 0 && op.ors_scope == LDAP_X_SCOPE_SUBTREE ) {
goto exact_match;
} else if ( d > 0 ) {
bv.bv_val = assertDN->bv_val + d;
if ( bv.bv_val[ -1 ] == ',' && dn_match( &op.o_req_ndn, &bv ) ) {
- switch ( op.oq_search.rs_scope ) {
+ switch ( op.ors_scope ) {
case LDAP_X_SCOPE_SUBTREE:
case LDAP_X_SCOPE_CHILDREN:
rc = LDAP_SUCCESS;
}
/* Must run an internal search. */
- if ( op.oq_search.rs_filter == NULL ) {
+ if ( op.ors_filter == NULL ) {
rc = LDAP_FILTER_ERROR;
goto CONCLUDED;
}
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, DETAIL1,
"slap_sasl_match: performing internal search (base=%s, scope=%d)\n",
- op.o_req_ndn.bv_val, op.oq_search.rs_scope, 0 );
+ op.o_req_ndn.bv_val, op.ors_scope, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"slap_sasl_match: performing internal search (base=%s, scope=%d)\n",
- op.o_req_ndn.bv_val, op.oq_search.rs_scope, 0 );
+ op.o_req_ndn.bv_val, op.ors_scope, 0 );
#endif
op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
/* use req_ndn as req_dn instead of non-pretty base of uri */
if( !BER_BVISNULL( &op.o_req_dn ) ) ch_free( op.o_req_dn.bv_val );
ber_dupbv_x( &op.o_req_dn, &op.o_req_ndn, op.o_tmpmemctx );
- op.oq_search.rs_slimit = 1;
- op.oq_search.rs_tlimit = SLAP_NO_LIMIT;
+ op.ors_slimit = 1;
+ op.ors_tlimit = SLAP_NO_LIMIT;
+ op.ors_attrs = slap_anlist_no_attrs;
+ op.ors_attrsonly = 1;
op.o_sync_slog_size = -1;
op.o_bd->be_search( &op, &rs );
CONCLUDED:
if( !BER_BVISNULL( &op.o_req_dn ) ) slap_sl_free( op.o_req_dn.bv_val, opx->o_tmpmemctx );
if( !BER_BVISNULL( &op.o_req_ndn ) ) slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
- if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter );
+ if( op.ors_filter ) filter_free_x( opx, op.ors_filter );
if( !BER_BVISNULL( &op.ors_filterstr ) ) ch_free( op.ors_filterstr.bv_val );
#ifdef NEW_LOGGING
}
rc = slap_parseURI( opx, ®out, &op.o_req_dn,
- &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter,
+ &op.o_req_ndn, &op.ors_scope, &op.ors_filter,
&op.ors_filterstr );
if ( !BER_BVISNULL( ®out ) ) slap_sl_free( regout.bv_val, opx->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
/* Must do an internal search */
op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
- switch ( op.oq_search.rs_scope ) {
+ switch ( op.ors_scope ) {
case LDAP_X_SCOPE_EXACT:
*sasldn = op.o_req_ndn;
BER_BVZERO( &op.o_req_ndn );
#ifdef NEW_LOGGING
LDAP_LOG( TRANSPORT, DETAIL1,
"slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
- op.o_req_ndn.bv_val, op.oq_search.rs_scope, 0 );
+ op.o_req_ndn.bv_val, op.ors_scope, 0 );
#else
Debug( LDAP_DEBUG_TRACE,
"slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
- op.o_req_ndn.bv_val, op.oq_search.rs_scope, 0 );
+ op.o_req_ndn.bv_val, op.ors_scope, 0 );
#endif
if(( op.o_bd == NULL ) || ( op.o_bd->be_search == NULL)) {
#ifdef LDAP_SLAPI
op.o_pb = opx->o_pb;
#endif
- op.oq_search.rs_deref = LDAP_DEREF_NEVER;
- op.oq_search.rs_slimit = 1;
- op.oq_search.rs_tlimit = SLAP_NO_LIMIT;
- op.oq_search.rs_attrsonly = 1;
+ op.ors_deref = LDAP_DEREF_NEVER;
+ op.ors_slimit = 1;
+ op.ors_tlimit = SLAP_NO_LIMIT;
+ op.ors_attrs = slap_anlist_no_attrs;
+ op.ors_attrsonly = 1;
+ op.o_sync_slog_size = -1;
/* use req_ndn as req_dn instead of non-pretty base of uri */
if( !BER_BVISNULL( &op.o_req_dn ) ) ch_free( op.o_req_dn.bv_val );
ber_dupbv_x( &op.o_req_dn, &op.o_req_ndn, op.o_tmpmemctx );
if( !BER_BVISNULL( &op.o_req_ndn ) ) {
slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx );
}
- if( op.oq_search.rs_filter ) {
- filter_free_x( opx, op.oq_search.rs_filter );
+ if( op.ors_filter ) {
+ filter_free_x( opx, op.ors_filter );
}
if( !BER_BVISNULL( &op.ors_filterstr ) ) {
ch_free( op.ors_filterstr.bv_val );
if( rs->sr_err == LDAP_COMPARE_TRUE ) {
rs->sr_entry = entry;
rs->sr_attrs = op->ors_attrs;
+ rs->sr_operational_attrs = NULL;
send_search_entry( op, rs );
rs->sr_entry = NULL;
+ rs->sr_operational_attrs = NULL;
}
entry_free( entry );
typedef struct rep_search_s {
Entry *r_entry;
+ int r_opattrs;
+#define SLAP_OPATTRS_UNDEFINED (0)
+#define SLAP_OPATTRS_NO (-1)
+#define SLAP_OPATTRS (1)
+ Attribute *r_operational_attrs;
AttributeName *r_attrs;
int r_nentries;
BerVarray r_v2ref;
/* short hands for response members */
#define sr_attrs sr_un.sru_search.r_attrs
#define sr_entry sr_un.sru_search.r_entry
+#define sr_operational_attrs sr_un.sru_search.r_operational_attrs
+#define sr_opattrs sr_un.sru_search.r_opattrs
#define sr_v2ref sr_un.sru_search.r_v2ref
#define sr_nentries sr_un.sru_search.r_nentries
#define sr_rspoid sr_un.sru_extended.r_rspoid
LDAP_P(( struct slap_op *op, Entry *e, int rw ));
typedef int (BI_entry_get_rw) LDAP_P(( struct slap_op *op, struct berval *ndn,
ObjectClass *oc, AttributeDescription *at, int rw, Entry **e ));
-typedef int (BI_operational) LDAP_P(( struct slap_op *op, struct slap_rep *rs,
- int opattrs, Attribute **ap ));
+typedef int (BI_operational) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
typedef int (BI_has_subordinates) LDAP_P(( struct slap_op *op,
Entry *e, int *hasSubs ));
BI_op_extended *bi_extended;
/* Auxilary Functions */
+ BI_operational *bi_operational;
BI_chk_referrals *bi_chk_referrals;
BI_entry_get_rw *bi_entry_get_rw;
BI_entry_release_rw *bi_entry_release_rw;
- BI_operational *bi_operational;
BI_has_subordinates *bi_has_subordinates;
BI_connection_init *bi_connection_init;
BI_connection_destroy *bi_connection_destroy;
/* hooks for slap tools */
- BI_tool_entry_open *bi_tool_entry_open;
- BI_tool_entry_close *bi_tool_entry_close;
- BI_tool_entry_first *bi_tool_entry_first;
- BI_tool_entry_next *bi_tool_entry_next;
- BI_tool_entry_get *bi_tool_entry_get;
- BI_tool_entry_put *bi_tool_entry_put;
+ BI_tool_entry_open *bi_tool_entry_open;
+ BI_tool_entry_close *bi_tool_entry_close;
+ BI_tool_entry_first *bi_tool_entry_first;
+ BI_tool_entry_next *bi_tool_entry_next;
+ BI_tool_entry_get *bi_tool_entry_get;
+ BI_tool_entry_put *bi_tool_entry_put;
BI_tool_entry_reindex *bi_tool_entry_reindex;
- BI_tool_sync *bi_tool_sync;
- BI_tool_dn2id_get *bi_tool_dn2id_get;
+ BI_tool_sync *bi_tool_sync;
+ BI_tool_dn2id_get *bi_tool_dn2id_get;
BI_tool_id2entry_get *bi_tool_id2entry_get;
BI_tool_entry_modify *bi_tool_entry_modify;
rs.sr_type = REP_SEARCH;
rs.sr_err = LDAP_SUCCESS;
rs.sr_attrs = an;
+ rs.sr_operational_attrs = NULL;
rs.sr_flags = REP_ENTRY_MODIFIABLE;
send_search_entry( op, &rs );
rs.sr_ref = NULL;
rs.sr_ctrls = ectrls;
rs.sr_attrs = an;
+ rs.sr_operational_attrs = NULL;
rs.sr_entry = e;
rs.sr_v2ref = NULL;
rs.sr_flags = 0;
rs.sr_ctrls = ectrls;
rs.sr_attrs = NULL;
+ rs.sr_operational_attrs = NULL;
rs.sr_entry = e;
if ( v2refs != NULL ) {
op->ors_tlimit = SLAP_NO_LIMIT;
op->ors_slimit = 1;
+ op->ors_attrs = slap_anlist_no_attrs;
+ op->ors_attrsonly = 1;
+
/* set callback function */
op->o_callback = &cb;
cb.sc_response = dn_callback;
Modifications *modlist = NULL;
Modifications **modtail = &modlist;
Attribute *attr;
+ AttributeName an[2];
struct berval pdn = BER_BVNULL;
struct berval org_req_dn = BER_BVNULL;
op->o_time = slap_get_time();
op->ors_tlimit = SLAP_NO_LIMIT;
op->ors_slimit = SLAP_NO_LIMIT;
+
+ 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;
+ op->ors_attrs = an;
+
op->ors_attrsonly = 0;
- op->ors_attrs = NULL;
op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val );
op->ors_filterstr = si->si_filterstr;