static AttributeName *slap_anlist_no_attrs = anlist_no_attrs;
#endif
-static AttributeDescription *ad_dgIdentity;
+static AttributeDescription *ad_dgIdentity, *ad_dgAuthz;
typedef struct dynlist_info_t {
ObjectClass *dli_oc;
}
for ( ; dli; dli = dli->dli_next ) {
- if ( value_find_ex( slap_schema.si_ad_objectClass,
+ if ( attr_valfind( a,
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
- a->a_nvals, &dli->dli_oc->soc_cname,
+ &dli->dli_oc->soc_cname, NULL,
op->o_tmpmemctx ) == 0 )
{
return dli;
mod.sm_type = dlc->dlc_dli->dli_member_ad->ad_cname;
mod.sm_values = vals;
mod.sm_nvalues = nvals;
+ mod.sm_numvals = 1;
(void)modify_add_values( e, &mod, /* permissive */ 1,
&text, textbuf, sizeof( textbuf ) );
}
/* test access to attribute */
- for ( i = 0; !BER_BVISNULL( &a->a_vals[i] ); i++ )
- /* just count */ ;
+ i = a->a_numvals;
vals = op->o_tmpalloc( ( i + 1 ) * sizeof( struct berval ), op->o_tmpmemctx );
if ( a->a_nvals != a->a_vals ) {
mod.sm_type = a->a_desc->ad_cname;
mod.sm_values = vals;
mod.sm_nvalues = nvals;
+ mod.sm_numvals = j;
(void)modify_add_values( e, &mod, /* permissive */ 1,
&text, textbuf, sizeof( textbuf ) );
return SLAP_CB_CONTINUE;
}
- if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
- e = entry_dup( rs->sr_entry );
- } else {
- e = rs->sr_entry;
+#ifndef SLAP_OPATTRS
+ opattrs = ( rs->sr_attrs == NULL ) ? 0 : an_find( rs->sr_attrs, &AllOper );
+ userattrs = ( rs->sr_attrs == NULL ) ? 1 : an_find( rs->sr_attrs, &AllUser );
+#else /* SLAP_OPATTRS */
+ opattrs = SLAP_OPATTRS( rs->sr_attr_flags );
+ userattrs = SLAP_USERATTRS( rs->sr_attr_flags );
+#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;
}
- e_flags = rs->sr_flags | ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
- if ( ad_dgIdentity && ( id = attrs_find( e->e_attrs, ad_dgIdentity ))) {
+ if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) {
+ Attribute *authz = NULL;
+
+ /* if not rootdn and dgAuthz is present,
+ * check if user can be authorized as dgIdentity */
+ if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op )
+ && ( authz = attrs_find( rs->sr_entry->e_attrs, ad_dgAuthz ) ) )
+ {
+ if ( slap_sasl_matches( op, authz->a_nvals,
+ &o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
+ {
+ return SLAP_CB_CONTINUE;
+ }
+ }
+
o.o_dn = id->a_vals[0];
o.o_ndn = id->a_nvals[0];
o.o_groups = NULL;
}
+ if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
+ e = entry_dup( rs->sr_entry );
+ } else {
+ e = rs->sr_entry;
+ }
+ e_flags = rs->sr_flags | ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
+
dlc.dlc_e = e;
dlc.dlc_dli = dli;
cb.sc_private = &dlc;
o.ors_tlimit = SLAP_NO_LIMIT;
o.ors_slimit = SLAP_NO_LIMIT;
-#ifndef SLAP_OPATTRS
- opattrs = ( rs->sr_attrs == NULL ) ? 0 : an_find( rs->sr_attrs, &AllOper );
- userattrs = ( rs->sr_attrs == NULL ) ? 1 : an_find( rs->sr_attrs, &AllUser );
-#else /* SLAP_OPATTRS */
- opattrs = SLAP_OPATTRS( rs->sr_attr_flags );
- userattrs = SLAP_USERATTRS( rs->sr_attr_flags );
-#endif /* SLAP_OPATTRS */
-
for ( url = a->a_nvals; !BER_BVISNULL( url ); url++ ) {
LDAPURLDesc *lud = NULL;
int i, j;
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private;
Operation o = *op;
- Entry *e;
+ Entry *e = NULL;
for ( ; dli != NULL; dli = dli->dli_next ) {
if ( op->oq_compare.rs_ava->aa_desc == dli->dli_member_ad ) {
* interested in. We'll use slapd's existing dyngroup
* evaluator to get the answer we want.
*/
- struct berval *id = NULL;
+ BerVarray id = NULL, authz = NULL;
o.o_do_not_cache = 1;
if ( ad_dgIdentity && backend_attribute( &o, NULL, &o.o_req_ndn,
- ad_dgIdentity, &id, ACL_READ ) == LDAP_SUCCESS ) {
+ ad_dgIdentity, &id, ACL_READ ) == LDAP_SUCCESS )
+ {
+ /* if not rootdn and dgAuthz is present,
+ * check if user can be authorized as dgIdentity */
+ if ( ad_dgAuthz && !BER_BVISEMPTY( id ) && !be_isroot( op )
+ && backend_attribute( &o, NULL, &o.o_req_ndn,
+ ad_dgAuthz, &authz, ACL_READ ) == LDAP_SUCCESS )
+ {
+
+ rs->sr_err = slap_sasl_matches( op, authz,
+ &o.o_ndn, &o.o_ndn );
+ ber_bvarray_free_x( authz, op->o_tmpmemctx );
+ if ( rs->sr_err != LDAP_SUCCESS ) {
+ goto done;
+ }
+ }
+
o.o_dn = *id;
o.o_ndn = *id;
o.o_groups = NULL; /* authz changed, invalidate cached groups */
}
+
rs->sr_err = backend_group( &o, NULL, &o.o_req_ndn,
&o.oq_compare.rs_ava->aa_value, dli->dli_oc, dli->dli_ad );
switch ( rs->sr_err ) {
break;
}
+done:;
if ( id ) ber_bvarray_free_x( id, o.o_tmpmemctx );
return SLAP_CB_CONTINUE;
}
if ( overlay_entry_get_ov( &o, &o.o_req_ndn, NULL, NULL, 0, &e, on ) !=
- LDAP_SUCCESS || e == NULL ) {
+ LDAP_SUCCESS || e == NULL )
+ {
return SLAP_CB_CONTINUE;
}
+
if ( ad_dgIdentity ) {
Attribute *id = attrs_find( e->e_attrs, ad_dgIdentity );
if ( id ) {
+ Attribute *authz;
+
+ /* if not rootdn and dgAuthz is present,
+ * check if user can be authorized as dgIdentity */
+ if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op )
+ && ( authz = attrs_find( e->e_attrs, ad_dgAuthz ) ) )
+ {
+ if ( slap_sasl_matches( op, authz->a_nvals,
+ &o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
+ {
+ goto release;
+ }
+ }
+
o.o_dn = id->a_vals[0];
o.o_ndn = id->a_nvals[0];
o.o_groups = NULL;
}
}
+
dli = (dynlist_info_t *)on->on_bi.bi_private;
for ( ; dli != NULL && rs->sr_err != LDAP_COMPARE_TRUE; dli = dli->dli_next ) {
Attribute *a;
o.o_bd = select_backend( &o.o_req_ndn, 1 );
if ( !o.o_bd || !o.o_bd->be_search ) {
- return SLAP_CB_CONTINUE;
+ goto release;
}
- BER_BVSTR( &o.ors_filterstr, "(objectClass=*)" );
- o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val );
- if ( o.ors_filter == NULL ) {
- /* FIXME: error? */
- return SLAP_CB_CONTINUE;
- }
+ o.ors_filterstr = *slap_filterstr_objectClass_pres;
+ o.ors_filter = (Filter *) slap_filter_objectClass_pres;
o.ors_scope = LDAP_SCOPE_BASE;
o.ors_deref = LDAP_DEREF_NEVER;
o.o_acl_priv = ACL_COMPARE;
rc = o.o_bd->be_search( &o, &r );
- filter_free_x( &o, o.ors_filter );
if ( o.o_dn.bv_val != op->o_dn.bv_val ) {
slap_op_groups_free( &o );
}
if ( rc != 0 ) {
- return rc;
+ goto release;
}
if ( dlc.dlc_e != NULL ) {
if ( r.sr_err != LDAP_SUCCESS || r.sr_entry == NULL ) {
/* error? */
- return SLAP_CB_CONTINUE;
+ goto release;
}
for ( a = attrs_find( r.sr_entry->e_attrs, op->orc_ava->aa_desc );
/* if we're here, we got a match... */
rs->sr_err = LDAP_COMPARE_FALSE;
- if ( value_find_ex( op->orc_ava->aa_desc,
+ if ( attr_valfind( a,
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
- a->a_nvals, &op->orc_ava->aa_value, op->o_tmpmemctx ) == 0 )
+ &op->orc_ava->aa_value, NULL, op->o_tmpmemctx ) == 0 )
{
rs->sr_err = LDAP_COMPARE_TRUE;
break;
}
}
+release:;
+ if ( e != NULL ) {
+ overlay_entry_release_ov( &o, e, 0, on );
+ }
+
return SLAP_CB_CONTINUE;
}
rc = slap_str2ad( "dgIdentity", &ad_dgIdentity, &text );
if ( rc != LDAP_SUCCESS ) {
- sprintf( cr->msg, "unable to fetch attributeDescription \"dgIdentity\": %d (%s)",
+ snprintf( cr->msg, sizeof( cr->msg),
+ "unable to fetch attributeDescription \"dgIdentity\": %d (%s)",
+ rc, text );
+ Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s\n", cr->msg, 0, 0 );
+ /* Just a warning */
+ }
+
+ rc = slap_str2ad( "dgAuthz", &ad_dgAuthz, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ snprintf( cr->msg, sizeof( cr->msg),
+ "unable to fetch attributeDescription \"dgAuthz\": %d (%s)",
rc, text );
Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s\n", cr->msg, 0, 0 );
/* Just a warning */