]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slapi/slapi_utils.c
Fix slapi_str2entry()/slapi_entry2str() allocation
[openldap] / servers / slapd / slapi / slapi_utils.c
index 02020a176efef3b76583f8a91968b8edd2a741a8..ca370dd483d15fc19d045eff3816a268b9c1cfd5 100644 (file)
@@ -110,16 +110,7 @@ slapi_str2entry(
        char            *s, 
        int             flags )
 {
-       Slapi_Entry     *e = NULL;
-       char            *pTmpS;
-
-       pTmpS = slapi_ch_strdup( s );
-       if ( pTmpS != NULL ) {
-               e = str2entry( pTmpS ); 
-               slapi_ch_free( (void **)&pTmpS );
-       }
-
-       return e;
+       return str2entry( s );
 }
 
 char *
@@ -127,10 +118,13 @@ slapi_entry2str(
        Slapi_Entry     *e, 
        int             *len ) 
 {
-       char            *ret;
+       char            *ret = NULL;
+       char            *s;
 
        ldap_pvt_thread_mutex_lock( &entry2str_mutex );
-       ret = entry2str( e, len );
+       s = entry2str( e, len );
+       if ( s != NULL )
+               ret = slapi_ch_strdup( s );
        ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
 
        return ret;
@@ -148,6 +142,27 @@ slapi_x_entry_get_id( Slapi_Entry *e )
        return e->e_id;
 }
 
+static int
+slapi_int_dn_pretty( struct berval *in, struct berval *out )
+{
+       Syntax          *syntax = slap_schema.si_syn_distinguishedName;
+
+       assert( syntax != NULL );
+
+       return (syntax->ssyn_pretty)( syntax, in, out, NULL );
+}
+
+static int
+slapi_int_dn_normalize( struct berval *in, struct berval *out )
+{
+       MatchingRule    *mr = slap_schema.si_mr_distinguishedNameMatch;
+       Syntax          *syntax = slap_schema.si_syn_distinguishedName;
+
+       assert( mr != NULL );
+
+       return (mr->smr_normalize)( 0, syntax, mr, in, out, NULL );
+}
+
 void 
 slapi_entry_set_dn(
        Slapi_Entry     *e, 
@@ -158,7 +173,8 @@ slapi_entry_set_dn(
        dn.bv_val = ldn;
        dn.bv_len = strlen( ldn );
 
-       dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname, NULL );
+       slapi_int_dn_pretty( &dn, &e->e_name );
+       slapi_int_dn_normalize( &dn, &e->e_nname );
 }
 
 Slapi_Entry *
@@ -272,7 +288,7 @@ slapi_entry_attr_get_charptr( const Slapi_Entry *e, const char *type )
 
                p = slapi_value_get_string( &attr->a_vals[0] );
                if ( p != NULL ) {
-                       return slapi_ch_strdup( (char *)p );
+                       return slapi_ch_strdup( p );
                }
        }
 
@@ -462,9 +478,9 @@ slapi_entry_has_children( const Slapi_Entry *e )
 
        slapi_pblock_set( pb, SLAPI_TARGET_DN, slapi_entry_get_dn( (Entry *)e ) );
 
-       pb->pop->o_bd = select_backend( (struct berval *)&e->e_nname, 0, 0 );
-       if ( pb->pop->o_bd != NULL ) {
-               pb->pop->o_bd->be_has_subordinates( pb->pop, (Entry *)e, &hasSubordinates );
+       pb->pb_op->o_bd = select_backend( (struct berval *)&e->e_nname, 0, 0 );
+       if ( pb->pb_op->o_bd != NULL ) {
+               pb->pb_op->o_bd->be_has_subordinates( pb->pb_op, (Entry *)e, &hasSubordinates );
        }
 
        slapi_pblock_destroy( pb );
@@ -591,7 +607,7 @@ slapi_entry_delete_values( Slapi_Entry *e, const char *type, struct berval **val
        }
 
        if ( vals[0] == NULL ) {
-               /* SLAPI doco says LDAP_OPERATIONS_ERROR but LDAP_OTHER is better */
+               /* SLAPI doco says LDApb_opERATIONS_ERROR but LDAP_OTHER is better */
                return attr_delete( &e->e_attrs, mod.sm_desc ) ? LDAP_OTHER : LDAP_SUCCESS;
        }
 
@@ -770,7 +786,7 @@ slapi_dn_normalize( char *dn )
        bdn.bv_val = dn;
        bdn.bv_len = strlen( dn );
 
-       if ( dnPretty( NULL, &bdn, &pdn, NULL ) != LDAP_SUCCESS ) {
+       if ( slapi_int_dn_pretty( &bdn, &pdn ) != LDAP_SUCCESS ) {
                return NULL;
        }
 
@@ -788,7 +804,7 @@ slapi_dn_normalize_case( char *dn )
        bdn.bv_val = dn;
        bdn.bv_len = strlen( dn );
 
-       if ( dnNormalize( 0, NULL, NULL, &bdn, &ndn, NULL ) != LDAP_SUCCESS ) {
+       if ( slapi_int_dn_normalize( &bdn, &ndn ) != LDAP_SUCCESS ) {
                return NULL;
        }
 
@@ -914,43 +930,69 @@ slapi_dn_parent( const char *_dn )
        return slapi_ch_strdup( parentDN.bv_val );
 }
 
+int slapi_dn_isbesuffix( Slapi_PBlock *pb, char *ldn )
+{
+       struct berval   ndn;
+       Backend         *be;
+
+       if ( slapi_is_rootdse( ldn ) ) {
+               return 0;
+       }
+
+       /* according to spec should already be normalized */
+       ndn.bv_len = strlen( ldn );
+       ndn.bv_val = ldn;
+
+       be = select_backend( &pb->pb_op->o_req_ndn, 0, 0 );
+       if ( be == NULL ) {
+               return 0;
+       }
+
+       return be_issuffix( be, &ndn );
+}
+
 /*
  * Returns DN of the parent entry; or NULL if the DN is
  * an empty string, if the DN has no parent, or if the
  * DN is the suffix of the backend database
  */
-char *slapi_dn_beparent( Slapi_PBlock *pb, const char *_dn )
+char *slapi_dn_beparent( Slapi_PBlock *pb, const char *ldn )
 {
        Backend         *be;
        struct berval   dn, prettyDN;
        struct berval   normalizedDN, parentDN;
+       char            *parent = NULL;
 
-       if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void **)&be ) != 0 )
-               be = NULL;
+       if ( pb == NULL ) {
+               return NULL;
+       }
 
-       dn.bv_val = (char *)_dn;
-       dn.bv_len = strlen( _dn );
+       PBLOCK_ASSERT_OP( pb, 0 );
 
-       if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
+       if ( slapi_is_rootdse( ldn ) ) {
                return NULL;
        }
 
-       if ( be != NULL && be_issuffix( be, &normalizedDN ) ) {
-               slapi_ch_free( (void **)&prettyDN.bv_val );
-               slapi_ch_free( (void **)&normalizedDN.bv_val );
+       dn.bv_val = (char *)ldn;
+       dn.bv_len = strlen( ldn );
+
+       if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
                return NULL;
        }
 
-       dnParent( &prettyDN, &parentDN );
+       be = select_backend( &pb->pb_op->o_req_ndn, 0, 0 );
 
-       slapi_ch_free( (void **)&prettyDN.bv_val );
-       slapi_ch_free( (void **)&normalizedDN.bv_val );
+       if ( be == NULL || be_issuffix( be, &normalizedDN ) == 0 ) {
+               dnParent( &prettyDN, &parentDN );
 
-       if ( parentDN.bv_len == 0 ) {
-               return NULL;
+               if ( parentDN.bv_len != 0 )
+                       parent = slapi_ch_strdup( parentDN.bv_val );
        }
 
-       return slapi_ch_strdup( parentDN.bv_val );
+       slapi_ch_free_string( &prettyDN.bv_val );
+       slapi_ch_free_string( &normalizedDN.bv_val );
+
+       return parent;
 }
 
 char *
@@ -1046,15 +1088,15 @@ slapi_ch_realloc(
 }
 
 char *
-slapi_ch_strdup( char *s ) 
+slapi_ch_strdup( const char *s ) 
 {
-       return ch_strdup( (const char *)s );
+       return ch_strdup( s );
 }
 
 size_t
-slapi_ch_stlen( char *s ) 
+slapi_ch_stlen( const char *s ) 
 {
-       return strlen( (const char *)s );
+       return strlen( s );
 }
 
 int 
@@ -1295,9 +1337,9 @@ slapi_send_ldap_result(
 {
        SlapReply       *rs;
 
-       assert( pb->pop != NULL );
+       PBLOCK_ASSERT_OP( pb, 0 );
 
-       rs = &pb->rs;
+       rs = pb->pb_rs;
 
        rs->sr_err = err;
        rs->sr_matched = matched;
@@ -1305,14 +1347,14 @@ slapi_send_ldap_result(
        rs->sr_ref = NULL;
 
        if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
-               send_ldap_sasl( pb->pop, rs );
+               send_ldap_sasl( pb->pb_op, rs );
        } else if ( rs->sr_rspoid != NULL ) {
-               send_ldap_extended( pb->pop, rs );
+               send_ldap_extended( pb->pb_op, rs );
        } else {
-               if ( pb->pop->o_tag == LDAP_REQ_SEARCH )
+               if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
                        rs->sr_nentries = nentries;
 
-               send_ldap_result( pb->pop, rs );
+               send_ldap_result( pb->pb_op, rs );
        }
 }
 
@@ -1330,7 +1372,7 @@ slapi_send_ldap_search_entry(
        const char              *text;
        int                     rc;
 
-       assert( pb->pop != NULL );
+       assert( pb->pb_op != NULL );
 
        if ( attrs != NULL ) {
                for ( i = 0; attrs[ i ] != NULL; i++ ) {
@@ -1365,7 +1407,7 @@ slapi_send_ldap_search_entry(
        rs.sr_v2ref = NULL;
        rs.sr_flags = 0;
 
-       rc = send_search_entry( pb->pop, &rs );
+       rc = send_search_entry( pb->pb_op, &rs );
 
        slapi_ch_free( (void **)&an );
 
@@ -1408,7 +1450,7 @@ slapi_send_ldap_search_reference(
                rs.sr_v2ref = NULL;
        }
 
-       rc = send_search_reference( pb->pop, &rs );
+       rc = send_search_reference( pb->pb_op, &rs );
 
        slapi_ch_free( (void **)&rs.sr_ref );
        slapi_ch_free( (void **)&rs.sr_v2ref );
@@ -1760,13 +1802,13 @@ slapi_filter_test( Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Filter *f,
        }
 
        if ( verify_access ) {
-               rc = slapi_pblock_get(pb, SLAPI_OPERATION, (void *)&op);
-               if ( rc != 0 ) {
+               op = pb->pb_op;
+               if ( op == NULL )
                        return LDAP_PARAM_ERROR;
-               }
        } else {
                op = NULL;
        }
+
        /*
         * According to acl.c it is safe to call test_filter() with
         * NULL arguments...
@@ -2003,16 +2045,14 @@ slapi_free_search_results_internal( Slapi_PBlock *pb )
 
 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
 {
-       Connection *conn = NULL;
-       int rc;
+       if ( pb == NULL )
+               return LDAP_PARAM_ERROR;
 
-       rc = slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
-       if ( rc != PBLOCK_SUCCESS || conn == NULL ) {
-               return LDAP_OTHER;
-       }
+       if ( pb->pb_conn == NULL )
+               return LDAP_PARAM_ERROR;
 
 #ifdef HAVE_TLS
-       *isSSL = conn->c_is_tls;
+       *isSSL = pb->pb_conn->c_is_tls;
 #else
        *isSSL = 0;
 #endif
@@ -2242,7 +2282,7 @@ int slapi_attr_type_cmp( const char *t1, const char *t2, int opt )
 
 int slapi_attr_types_equivalent( const char *t1, const char *t2 )
 {
-       return slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT );
+       return ( slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT ) == 0 );
 }
 
 int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v )
@@ -2330,7 +2370,7 @@ Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
 
 Slapi_Value *slapi_value_init_string(Slapi_Value *v, const char *s)
 {
-       v->bv_val = slapi_ch_strdup( (char *)s );
+       v->bv_val = slapi_ch_strdup( s );
        v->bv_len = strlen( s );
 
        return v;
@@ -2618,9 +2658,9 @@ int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
                break;
        }
 
-       assert( pb->pop != NULL );
+       assert( pb->pb_op != NULL );
 
-       if ( access_allowed( pb->pop, e, ad, val, slap_access, NULL ) ) {
+       if ( access_allowed( pb->pb_op, e, ad, val, slap_access, NULL ) ) {
                return LDAP_SUCCESS;
        }
 
@@ -2629,25 +2669,22 @@ int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
 
 int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
 {
-       Operation *op;
        int rc = LDAP_SUCCESS;
        Modifications *ml;
 
-       if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
+       if ( pb == NULL || pb->pb_op == NULL )
                return LDAP_PARAM_ERROR;
-       }
 
-       ml = slapi_int_ldapmods2modifications( mods, NULL );
+       ml = slapi_int_ldapmods2modifications( mods );
        if ( ml == NULL ) {
                return LDAP_OTHER;
        }
 
        if ( rc == LDAP_SUCCESS ) {
-               rc = acl_check_modlist( op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
+               rc = acl_check_modlist( pb->pb_op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
        }
 
-       /* Careful when freeing the modlist because it has pointers into the mods array. */
-       slapi_int_mods_free( ml );
+       slap_mods_free( ml, 1 );
 
        return rc;
 }
@@ -2660,10 +2697,7 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
  * 
  * This function must also be called before slap_mods_check().
  */
-LDAPMod **slapi_int_modifications2ldapmods(
-       Modifications **pmodlist,
-       void *memctx
-)
+LDAPMod **slapi_int_modifications2ldapmods( Modifications **pmodlist )
 {
        Modifications *ml, *modlist;
        LDAPMod **mods, *modp;
@@ -2674,32 +2708,37 @@ LDAPMod **slapi_int_modifications2ldapmods(
        for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
                ;
 
-       mods = (LDAPMod **)slap_sl_malloc( (i + 1) * sizeof(LDAPMod *), memctx );
+       mods = (LDAPMod **)slapi_ch_malloc( (i + 1) * sizeof(LDAPMod *) );
 
        for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
-               mods[i] = (LDAPMod *)slap_sl_malloc( sizeof(LDAPMod), memctx );
+               mods[i] = (LDAPMod *)slapi_ch_malloc( sizeof(LDAPMod) );
                modp = mods[i];
                modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
-
-               /* Take ownership of original type. */
-               modp->mod_type = ml->sml_type.bv_val;
-               ml->sml_type.bv_val = NULL;
+               if ( BER_BVISNULL( &ml->sml_type ) ) {
+                       /* may happen for internally generated mods */
+                       assert( ml->sml_desc != NULL );
+                       modp->mod_type = slapi_ch_strdup( ml->sml_desc->ad_cname.bv_val );
+               } else {
+                       modp->mod_type = slapi_ch_strdup( ml->sml_type.bv_val );
+                       BER_BVZERO( &ml->sml_type );
+               }
 
                if ( ml->sml_values != NULL ) {
                        for( j = 0; ml->sml_values[j].bv_val != NULL; j++ )
                                ;
-                       modp->mod_bvalues = (struct berval **)slap_sl_malloc( (j + 1) *
-                               sizeof(struct berval *), memctx );
+                       modp->mod_bvalues = (struct berval **)slapi_ch_malloc( (j + 1) *
+                               sizeof(struct berval *) );
                        for( j = 0; ml->sml_values[j].bv_val != NULL; j++ ) {
+                               modp->mod_bvalues[j] = (struct berval *)slapi_ch_malloc(
+                                               sizeof(struct berval) );
                                /* Take ownership of original values. */
-                               modp->mod_bvalues[j] = (struct berval *)slap_sl_malloc(
-                                               sizeof(struct berval), memctx );
                                modp->mod_bvalues[j]->bv_len = ml->sml_values[j].bv_len;
                                modp->mod_bvalues[j]->bv_val = ml->sml_values[j].bv_val;
                                ml->sml_values[j].bv_len = 0;
                                ml->sml_values[j].bv_val = NULL;
                        }
                        modp->mod_bvalues[j] = NULL;
+                       slapi_ch_free( (void **)&ml->sml_values );
                } else {
                        modp->mod_bvalues = NULL;
                }
@@ -2708,7 +2747,7 @@ LDAPMod **slapi_int_modifications2ldapmods(
 
        mods[i] = NULL;
 
-       slap_mods_free( modlist );
+       slap_mods_free( modlist, 1 );
        *pmodlist = NULL;
 
        return mods;
@@ -2716,16 +2755,17 @@ LDAPMod **slapi_int_modifications2ldapmods(
 
 /*
  * Convert a potentially modified array of LDAPMods back to a
- * Modification list. 
- * 
- * The returned Modification list contains pointers into the
- * LDAPMods array; the latter MUST be freed with
- * slapi_int_free_ldapmods() (see below).
+ * Modification list. Unfortunately the values need to be
+ * duplicated because slap_mods_check() will try to free them
+ * before prettying (and we can't easily get out of calling
+ * slap_mods_check() because we need normalized values).
  */
-Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
+Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods )
 {
        Modifications *modlist = NULL, **modtail;
        LDAPMod **modp;
+       char textbuf[SLAP_TEXT_BUFLEN];
+       const char *text;
 
        if ( mods == NULL ) {
                return NULL;
@@ -2733,49 +2773,51 @@ Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
 
        modtail = &modlist;
 
-       for( modp = mods; *modp != NULL; modp++ ) {
+       for ( modp = mods; *modp != NULL; modp++ ) {
                Modifications *mod;
+               LDAPMod *lmod = *modp;
                int i;
-               char **p;
-               struct berval **bvp;
                const char *text;
                AttributeDescription *ad = NULL;
 
-               /* Don't initialize attribute type if mods_check() is going to be called */
-               if ( slap_str2ad( (*modp)->mod_type, &ad, &text ) != LDAP_SUCCESS )
+               if ( slap_str2ad( lmod->mod_type, &ad, &text ) != LDAP_SUCCESS ) {
                        continue;
+               }
 
-               mod = (Modifications *) slap_sl_malloc( sizeof(Modifications), memctx );
-               mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
+               mod = (Modifications *) slapi_ch_malloc( sizeof(Modifications) );
+               mod->sml_op = lmod->mod_op & ~(LDAP_MOD_BVALUES);
                mod->sml_flags = 0;
-               mod->sml_type.bv_val = (*modp)->mod_type;
-               mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
+               mod->sml_type = ad->ad_cname;
                mod->sml_desc = ad;
                mod->sml_next = NULL;
 
-               if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
-                       for( i = 0, bvp = (*modp)->mod_bvalues; bvp != NULL && *bvp != NULL; bvp++, i++ )
-                               ;
+               i = 0;
+               if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
+                       if ( lmod->mod_bvalues != NULL ) {
+                               while ( lmod->mod_bvalues[i] != NULL )
+                                       i++;
+                       }
                } else {
-                       for( i = 0, p = (*modp)->mod_values; p != NULL && *p != NULL; p++, i++ )
-                               ;
+                       if ( lmod->mod_values != NULL ) {
+                               while ( lmod->mod_values[i] != NULL )
+                                       i++;
+                       }
                }
 
                if ( i == 0 ) {
                        mod->sml_values = NULL;
                } else {
-                       mod->sml_values = (BerVarray) slap_sl_malloc( (i + 1) * sizeof(struct berval), memctx );
+                       mod->sml_values = (BerVarray) slapi_ch_malloc( (i + 1) * sizeof(struct berval) );
 
                        /* NB: This implicitly trusts a plugin to return valid modifications. */
-                       if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
-                               for( i = 0, bvp = (*modp)->mod_bvalues; bvp != NULL && *bvp != NULL; bvp++, i++ ) {
-                                       mod->sml_values[i].bv_val = (*bvp)->bv_val;
-                                       mod->sml_values[i].bv_len = (*bvp)->bv_len;
+                       if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
+                               for ( i = 0; lmod->mod_bvalues[i] != NULL; i++ ) {
+                                       ber_dupbv( &mod->sml_values[i], lmod->mod_bvalues[i] );
                                }
                        } else {
-                               for( i = 0, p = (*modp)->mod_values; p != NULL && *p != NULL; p++, i++ ) {
-                                       mod->sml_values[i].bv_val = *p;
-                                       mod->sml_values[i].bv_len = strlen( *p );
+                               for ( i = 0; lmod->mod_values[i] != NULL; i++ ) {
+                                       mod->sml_values[i].bv_val = slapi_ch_strdup( lmod->mod_values[i] );
+                                       mod->sml_values[i].bv_len = strlen( lmod->mod_values[i] );
                                }
                        }
                        mod->sml_values[i].bv_val = NULL;
@@ -2786,60 +2828,13 @@ Modifications *slapi_int_ldapmods2modifications ( LDAPMod **mods, void *memctx )
                *modtail = mod;
                modtail = &mod->sml_next;
        }
-       
-       return modlist;
-}
-
-void
-slapi_int_mods_free( Modifications *ml )
-{
-       Modifications           *next;
-
-       for ( ; ml != NULL; ml = next ) {
-               next = ml->sml_next;
 
-               /* Don't free unnormalized values */
-               if ( ml->sml_nvalues != NULL ) {
-                       ber_bvarray_free( ml->sml_nvalues );
-                       ml->sml_nvalues = NULL;
-               }
-               slapi_ch_free((void **)&ml->sml_values);
-               slapi_ch_free((void **)&ml);
+       if ( slap_mods_check( modlist, &text, textbuf, sizeof( textbuf ), NULL ) != LDAP_SUCCESS ) {
+               slap_mods_free( modlist, 1 );
+               modlist = NULL;
        }
-}
-
-/*
- * This function only frees the parts of the mods array that
- * are not shared with the Modification list that was created
- * by slapi_int_ldapmods2modifications(). 
- *
- */
-void
-slapi_int_free_ldapmods ( LDAPMod **mods )
-{
-       int i, j;
 
-       if (mods == NULL)
-               return;
-
-       for ( i = 0; mods[i] != NULL; i++ ) {
-               /*
-                * Don't free values themselves; they're owned by the
-                * Modification list. Do free the containing array.
-                */
-               if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
-                       if ( mods[i]->mod_bvalues != NULL ) {
-                               for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ )
-                                       slapi_ch_free( (void **)&mods[i]->mod_bvalues[j] );
-                               slapi_ch_free( (void **)&mods[i]->mod_bvalues );
-                       }
-               } else {
-                       slapi_ch_free( (void **)&mods[i]->mod_values );
-               }
-               /* Don't free type, for same reasons. */
-               slapi_ch_free( (void **)&mods[i] );
-       }
-       slapi_ch_free( (void **)&mods );
+       return modlist;
 }
 
 /*
@@ -2861,6 +2856,7 @@ int slapi_compute_add_evaluator(slapi_compute_callback_t function)
 {
        Slapi_PBlock *pPlugin = NULL;
        int rc;
+       int type = SLAPI_PLUGIN_OBJECT;
 
        pPlugin = slapi_pblock_new();
        if ( pPlugin == NULL ) {
@@ -2868,7 +2864,7 @@ int slapi_compute_add_evaluator(slapi_compute_callback_t function)
                goto done;
        }
 
-       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
        if ( rc != LDAP_SUCCESS ) {
                goto done;
        }
@@ -2902,6 +2898,7 @@ int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
 {
        Slapi_PBlock *pPlugin = NULL;
        int rc;
+       int type = SLAPI_PLUGIN_OBJECT;
 
        pPlugin = slapi_pblock_new();
        if ( pPlugin == NULL ) {
@@ -2909,7 +2906,7 @@ int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
                goto done;
        }
 
-       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
        if ( rc != LDAP_SUCCESS ) {
                goto done;
        }
@@ -2967,24 +2964,21 @@ int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slap
        return rc;
 }
 
-int compute_rewrite_search_filter(Slapi_PBlock *pb)
+int
+compute_rewrite_search_filter( Slapi_PBlock *pb )
 {
-       Backend *be;
-       int rc;
-
-       rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be );
-       if ( rc != 0 ) {
-               return rc;
-       }
+       if ( pb == NULL || pb->pb_op == NULL )
+               return LDAP_PARAM_ERROR;
 
-       return slapi_int_call_plugins( be, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
+       return slapi_int_call_plugins( pb->pb_op->o_bd, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
 }
 
 /*
  * New API to provide the plugin with access to the search
  * pblock. Have informed Sun DS team.
  */
-int slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
+int
+slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
 {
        if ( c == NULL )
                return -1;
@@ -3195,16 +3189,22 @@ char *slapi_dn_plus_rdn( const char *dn, const char *rdn )
 
 int slapi_entry_schema_check( Slapi_PBlock *pb, Slapi_Entry *e )
 {
-       Backend *be;
+       Backend *be_orig;
        const char *text;
        char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
        size_t textlen = sizeof textbuf;
        int rc = LDAP_SUCCESS;
 
-       be = select_backend( &e->e_nname, 0, 0 );
-       if ( be != NULL )
-               rc = entry_schema_check( be, e, NULL, 0,
+       PBLOCK_ASSERT_OP( pb, 0 );
+
+       be_orig = pb->pb_op->o_bd;
+
+       pb->pb_op->o_bd = select_backend( &e->e_nname, 0, 0 );
+       if ( pb->pb_op->o_bd != NULL ) {
+               rc = entry_schema_check( pb->pb_op, e, NULL, 0,
                        &text, textbuf, textlen );
+       }
+       pb->pb_op->o_bd = be_orig;
 
        return ( rc == LDAP_SUCCESS ) ? 0 : 1;
 }
@@ -3357,5 +3357,155 @@ slapi_int_count_controls( LDAPControl **ctrls )
        return i;
 }
 
+int
+slapi_op_abandoned( Slapi_PBlock *pb )
+{
+       if ( pb->pb_op == NULL )
+               return 0;
+
+       return ( pb->pb_op->o_abandon );
+}
+
+char *
+slapi_op_type_to_string(unsigned long type)
+{
+       char *str;
+
+       switch (type) {
+       case SLAPI_OPERATION_BIND:
+               str = "bind";
+               break;
+       case SLAPI_OPERATION_UNBIND:
+               str = "unbind";
+               break;
+       case SLAPI_OPERATION_SEARCH:
+               str = "search";
+               break;
+       case SLAPI_OPERATION_MODIFY:
+               str = "modify";
+               break;
+       case SLAPI_OPERATION_ADD:
+               str = "add";
+               break;
+       case SLAPI_OPERATION_DELETE:
+               str = "delete";
+               break;
+       case SLAPI_OPERATION_MODDN:
+               str = "modrdn";
+               break;
+       case SLAPI_OPERATION_COMPARE:
+               str = "compare";
+               break;
+       case SLAPI_OPERATION_ABANDON:
+               str = "abandon";
+               break;
+       case SLAPI_OPERATION_EXTENDED:
+               str = "extended";
+               break;
+       default:
+               str = "unknown operation type";
+               break;
+       }
+       return str;
+}
+
+unsigned long
+slapi_op_get_type(Slapi_Operation * op)
+{
+       unsigned long type;
+
+       switch ( op->o_tag ) {
+       case LDAP_REQ_BIND:
+               type = SLAPI_OPERATION_BIND;
+               break;
+       case LDAP_REQ_UNBIND:
+               type = SLAPI_OPERATION_UNBIND;
+               break;
+       case LDAP_REQ_SEARCH:
+               type = SLAPI_OPERATION_SEARCH;
+               break;
+       case LDAP_REQ_MODIFY:
+               type = SLAPI_OPERATION_MODIFY;
+               break;
+       case LDAP_REQ_ADD:
+               type = SLAPI_OPERATION_ADD;
+               break;
+       case LDAP_REQ_DELETE:
+               type = SLAPI_OPERATION_DELETE;
+               break;
+       case LDAP_REQ_MODRDN:
+               type = SLAPI_OPERATION_MODDN;
+               break;
+       case LDAP_REQ_COMPARE:
+               type = SLAPI_OPERATION_COMPARE;
+               break;
+       case LDAP_REQ_ABANDON:
+               type = SLAPI_OPERATION_ABANDON;
+               break;
+       case LDAP_REQ_EXTENDED:
+               type = SLAPI_OPERATION_EXTENDED;
+               break;
+       default:
+               type = SLAPI_OPERATION_NONE;
+               break;
+       }
+       return type;
+}
+
+void slapi_be_set_readonly( Slapi_Backend *be, int readonly )
+{
+       if ( be == NULL )
+               return;
+
+       if ( readonly )
+               be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
+       else
+               be->be_restrictops &= ~(SLAP_RESTRICT_OP_WRITES);
+}
+
+int slapi_be_get_readonly( Slapi_Backend *be )
+{
+       if ( be == NULL )
+               return 0;
+
+       return ( (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) == SLAP_RESTRICT_OP_WRITES );
+}
+
+const char *slapi_x_be_get_updatedn( Slapi_Backend *be )
+{
+       if ( be == NULL )
+               return NULL;
+
+       return be->be_update_ndn.bv_val;
+}
+
+Slapi_Backend *slapi_be_select( const Slapi_DN *sdn )
+{
+       Slapi_Backend *be;
+
+       slapi_sdn_get_ndn( sdn );
+
+       be = select_backend( (struct berval *)&sdn->ndn, 0, 0 );
+
+       return be;
+}
+
+#if 0
+void
+slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag)
+{
+}
+
+void
+slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag)
+{
+}
+
+int
+slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag)
+{
+}
+#endif
+
 #endif /* LDAP_SLAPI */