+
+int slap_read_controls(
+ Operation *op,
+ SlapReply *rs,
+ Entry *e,
+ const struct berval *oid,
+ LDAPControl **ctrl )
+{
+ int rc;
+ struct berval bv;
+ BerElementBuffer berbuf;
+ BerElement *ber = (BerElement *) &berbuf;
+ LDAPControl c;
+ Operation myop;
+
+ Debug( LDAP_DEBUG_ANY, "slap_read_controls: (%s) %s\n",
+ oid->bv_val, e->e_dn, 0 );
+
+ rs->sr_entry = e;
+ rs->sr_attrs = ( oid == &slap_pre_read_bv ) ?
+ op->o_preread_attrs : op->o_postread_attrs;
+
+ bv.bv_len = entry_flatsize( rs->sr_entry, 0 );
+ bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx );
+
+ ber_init2( ber, &bv, LBER_USE_DER );
+ ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
+
+ /* create new operation */
+ myop = *op;
+ myop.o_bd = NULL;
+ myop.o_res_ber = ber;
+
+ rc = slap_send_search_entry( &myop, rs );
+ if( rc ) return rc;
+
+ rc = ber_flatten2( ber, &c.ldctl_value, 0 );
+
+ if( rc == LBER_ERROR ) return LDAP_OTHER;
+
+ c.ldctl_oid = oid->bv_val;
+ c.ldctl_iscritical = 0;
+
+ if ( ctrl == NULL ) {
+ /* first try */
+ *ctrl = (LDAPControl *) slap_sl_calloc( 1, sizeof(LDAPControl), NULL );
+ } else {
+ /* retry: free previous try */
+ slap_sl_free( (*ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
+ }
+
+ **ctrl = c;
+ return LDAP_SUCCESS;
+}
+
+/* Map API errors to protocol errors... */
+int
+slap_map_api2result( SlapReply *rs )
+{
+ switch(rs->sr_err) {
+ case LDAP_SERVER_DOWN:
+ return LDAP_UNAVAILABLE;
+ case LDAP_LOCAL_ERROR:
+ return LDAP_OTHER;
+ case LDAP_ENCODING_ERROR:
+ case LDAP_DECODING_ERROR:
+ return LDAP_PROTOCOL_ERROR;
+ case LDAP_TIMEOUT:
+ return LDAP_UNAVAILABLE;
+ case LDAP_AUTH_UNKNOWN:
+ return LDAP_AUTH_METHOD_NOT_SUPPORTED;
+ case LDAP_FILTER_ERROR:
+ rs->sr_text = "Filter error";
+ return LDAP_OTHER;
+ case LDAP_USER_CANCELLED:
+ rs->sr_text = "User cancelled";
+ return LDAP_OTHER;
+ case LDAP_PARAM_ERROR:
+ return LDAP_PROTOCOL_ERROR;
+ case LDAP_NO_MEMORY:
+ return LDAP_OTHER;
+ case LDAP_CONNECT_ERROR:
+ return LDAP_UNAVAILABLE;
+ case LDAP_NOT_SUPPORTED:
+ return LDAP_UNWILLING_TO_PERFORM;
+ case LDAP_CONTROL_NOT_FOUND:
+ return LDAP_PROTOCOL_ERROR;
+ case LDAP_NO_RESULTS_RETURNED:
+ return LDAP_NO_SUCH_OBJECT;
+ case LDAP_MORE_RESULTS_TO_RETURN:
+ rs->sr_text = "More results to return";
+ return LDAP_OTHER;
+ case LDAP_CLIENT_LOOP:
+ case LDAP_REFERRAL_LIMIT_EXCEEDED:
+ return LDAP_LOOP_DETECT;
+ default:
+ if ( LDAP_API_ERROR(rs->sr_err) ) return LDAP_OTHER;
+ return rs->sr_err;
+ }
+}
+
+
+slap_mask_t
+slap_attr_flags( AttributeName *an )
+{
+ slap_mask_t flags = SLAP_ATTRS_UNDEFINED;
+
+ if ( an == NULL ) {
+ flags |= ( SLAP_OPATTRS_NO | SLAP_USERATTRS_YES );
+
+ } else {
+ flags |= an_find( an, &AllOper )
+ ? SLAP_OPATTRS_YES : SLAP_OPATTRS_NO;
+ flags |= an_find( an, &AllUser )
+ ? SLAP_USERATTRS_YES : SLAP_USERATTRS_NO;
+ }
+
+ return flags;
+}
+