+
+ if ( entry_at == slap_schema.si_ad_entry || entry_at == slap_schema.si_ad_children )
+ {
+ if ( access_allowed_mask( op, e, entry_at,
+ NULL, access, NULL, mask ) == 0 )
+ {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+
+ } else {
+ rc = LDAP_SUCCESS;
+ }
+
+ } else {
+ a = attr_find( e->e_attrs, entry_at );
+ if ( a == NULL ) {
+ SlapReply rs = { 0 };
+ AttributeName anlist[ 2 ];
+
+ anlist[ 0 ].an_name = entry_at->ad_cname;
+ anlist[ 0 ].an_desc = entry_at;
+ BER_BVZERO( &anlist[ 1 ].an_name );
+ rs.sr_attrs = anlist;
+
+ rs.sr_attr_flags = slap_attr_flags( rs.sr_attrs );
+
+ /* NOTE: backend_operational() is also called
+ * when returning results, so it's supposed
+ * to do no harm to entries */
+ rs.sr_entry = e;
+ rc = backend_operational( op, &rs );
+ rs.sr_entry = NULL;
+
+ if ( rc == LDAP_SUCCESS ) {
+ if ( rs.sr_operational_attrs ) {
+ freeattr = 1;
+ a = rs.sr_operational_attrs;
+
+ } else {
+ rc = LDAP_NO_SUCH_OBJECT;
+ }
+ }
+ }
+
+ if ( a ) {
+ if ( access_allowed_mask( op, e, entry_at,
+ nval, access, NULL, mask ) == 0 )
+ {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+ goto freeit;
+ }
+ rc = LDAP_SUCCESS;
+ }
+#ifdef LDAP_SLAPI
+ else if ( op->o_pb ) {
+ /* try any computed attributes */
+ computed_attr_context ctx;
+
+ slapi_int_pblock_set_operation( op->o_pb, op );
+
+ ctx.cac_pb = op->o_pb;
+ ctx.cac_attrs = NULL;
+ ctx.cac_userattrs = 0;
+ ctx.cac_opattrs = 0;
+ ctx.cac_private = (void *)nval;
+
+ rc = compute_evaluator( &ctx, entry_at->ad_cname.bv_val, e, backend_compute_output_attr_access );
+ if ( rc == 1 ) {
+ rc = LDAP_INSUFFICIENT_ACCESS;
+
+ } else {
+ rc = LDAP_SUCCESS;
+ }
+ }