]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/modify.c
ITS#2368 - fix deleting key from range IDL
[openldap] / servers / slapd / modify.c
index f6dbac13fe11fe0fcc92ab65c15425ae9d094850..1d3c7b325ff97b4b7e77bd46dcfd3a418d15838b 100644 (file)
@@ -16,7 +16,6 @@
  */
 
 #include "portable.h"
-#include "slapi_common.h"
 
 #include <stdio.h>
 
 #include <ac/string.h>
 #include <ac/time.h>
 
-#include "lutil.h"
-
 #include "ldap_pvt.h"
 #include "slap.h"
+#ifdef LDAP_SLAPI
 #include "slapi.h"
+#endif
+#include "lutil.h"
 
-#ifdef LDAP_SLAPI
-static LDAPMod **Modifications2LDAPMods (Modifications **modlist);
-static Modifications *LDAPMods2Modifications (LDAPMod **mods);
-static void FreeLDAPMods (LDAPMod **mods);
-#endif /* LDAP_SLAPI */
 
 int
 do_modify(
@@ -49,17 +44,17 @@ do_modify(
        ber_len_t       len;
        Modifications   *modlist = NULL;
        Modifications   **modtail = &modlist;
-#ifdef LDAP_SLAPI
-       LDAPMod         **modv = NULL;
-#endif
 #ifdef LDAP_DEBUG
        Modifications *tmp;
+#endif
+#ifdef LDAP_SLAPI
+       LDAPMod         **modv = NULL;
+       Slapi_PBlock *pb = op->o_pb;
 #endif
        Backend         *be;
        int rc;
        const char      *text;
        int manageDSAit;
-       Slapi_PBlock *pb = op->o_pb;
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, "do_modify: enter\n", 0, 0, 0 );
@@ -114,9 +109,12 @@ do_modify(
                ber_int_t mop;
                Modifications tmp, *mod;
 
+#ifdef SLAP_NVALUES
+               tmp.sml_nvalues = NULL;
+#endif
 
                if ( ber_scanf( op->o_ber, "{i{m[W]}}", &mop,
-                   &tmp.sml_type, &tmp.sml_bvalues )
+                   &tmp.sml_type, &tmp.sml_values )
                    == LBER_ERROR )
                {
                        send_ldap_disconnect( conn, op,
@@ -128,14 +126,17 @@ do_modify(
                mod = (Modifications *) ch_malloc( sizeof(Modifications) );
                mod->sml_op = mop;
                mod->sml_type = tmp.sml_type;
-               mod->sml_bvalues = tmp.sml_bvalues;
+               mod->sml_values = tmp.sml_values;
+#ifdef SLAP_NVALUES
+               mod->sml_nvalues = NULL;
+#endif
                mod->sml_desc = NULL;
                mod->sml_next = NULL;
                *modtail = mod;
 
                switch( mop ) {
                case LDAP_MOD_ADD:
-                       if ( mod->sml_bvalues == NULL ) {
+                       if ( mod->sml_values == NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( OPERATION, ERR, 
                                        "do_modify: modify/add operation (%ld) requires values\n",
@@ -244,11 +245,11 @@ do_modify(
                        "add" : (tmp->sml_op == LDAP_MOD_DELETE ?
                        "delete" : "replace"), tmp->sml_type.bv_val, 0 );
 
-               if ( tmp->sml_bvalues == NULL ) {
+               if ( tmp->sml_values == NULL ) {
                        LDAP_LOG( OPERATION, DETAIL1, "\t\tno values", 0, 0, 0 );
-               } else if ( tmp->sml_bvalues[0].bv_val == NULL ) {
+               } else if ( tmp->sml_values[0].bv_val == NULL ) {
                        LDAP_LOG( OPERATION, DETAIL1, "\t\tzero values", 0, 0, 0 );
-               } else if ( tmp->sml_bvalues[1].bv_val == NULL ) {
+               } else if ( tmp->sml_values[1].bv_val == NULL ) {
                        LDAP_LOG( OPERATION, DETAIL1, "\t\tone value", 0, 0, 0 );
                } else {
                        LDAP_LOG( OPERATION, DETAIL1, "\t\tmultiple values", 0, 0, 0 );
@@ -260,22 +261,21 @@ do_modify(
                                ? "add" : (tmp->sml_op == LDAP_MOD_DELETE
                                        ? "delete" : "replace"), tmp->sml_type.bv_val, 0 );
 
-               if ( tmp->sml_bvalues == NULL ) {
+               if ( tmp->sml_values == NULL ) {
                        Debug( LDAP_DEBUG_ARGS, "%s\n",
                           "\t\tno values", NULL, NULL );
-               } else if ( tmp->sml_bvalues[0].bv_val == NULL ) {
+               } else if ( tmp->sml_values[0].bv_val == NULL ) {
                        Debug( LDAP_DEBUG_ARGS, "%s\n",
                           "\t\tzero values", NULL, NULL );
-               } else if ( tmp->sml_bvalues[1].bv_val == NULL ) {
+               } else if ( tmp->sml_values[1].bv_val == NULL ) {
                        Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n",
-                          "\t\tone value", (long) tmp->sml_bvalues[0].bv_len, NULL );
+                          "\t\tone value", (long) tmp->sml_values[0].bv_len, NULL );
                } else {
                        Debug( LDAP_DEBUG_ARGS, "%s\n",
                           "\t\tmultiple values", NULL, NULL );
                }
 #endif
        }
-#endif
 
        if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
                char abuf[BUFSIZ/2], *ptr = abuf;
@@ -303,6 +303,7 @@ do_modify(
                                op->o_connid, op->o_opid, abuf, 0, 0 );
                }
        }
+#endif /* LDAP_DEBUG */
 
        manageDSAit = get_manageDSAit( op );
 
@@ -336,16 +337,13 @@ do_modify(
                goto cleanup;
        }
 
-       /* deref suffix alias if appropriate */
-       suffix_alias( be, &ndn );
-
 #if defined( LDAP_SLAPI )
        slapi_x_backend_set_pb( pb, be );
        slapi_x_connection_set_pb( pb, conn );
        slapi_x_operation_set_pb( pb, op );
        slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val );
-       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(1) );
-       modv = Modifications2LDAPMods( &modlist );
+       slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit );
+       modv = slapi_x_modifications2ldapmods( &modlist );
        slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv );
 
        rc = doPluginFNs( be, SLAPI_PLUGIN_PRE_MODIFY_FN, pb );
@@ -362,7 +360,7 @@ do_modify(
                                0, 0, 0);
 #endif
                if ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rc ) != 0) {
-                       rc = LDAP_OPERATIONS_ERROR;
+                       rc = LDAP_OTHER;
                }
                ldap_mods_free( modv, 1 );
                modv = NULL;
@@ -374,11 +372,11 @@ do_modify(
         * modification array, so we need to convert it back to
         * a Modification list.
         *
-        * Calling Modifications2LDAPMods() destroyed modlist so
+        * Calling slapi_x_modifications2ldapmods() destroyed modlist so
         * we don't need to free it.
         */
        slapi_pblock_get( pb, SLAPI_MODIFY_MODS, (void **)&modv );
-       modlist = LDAPMods2Modifications( modv );
+       modlist = slapi_x_ldapmods2modifications( modv );
 #endif /* defined( LDAP_SLAPI ) */
 
        /*
@@ -475,7 +473,7 @@ cleanup:
        free( ndn.bv_val );
        if ( modlist != NULL ) slap_mods_free( modlist );
 #if defined( LDAP_SLAPI )
-       if ( modv != NULL ) FreeLDAPMods( modv );
+       if ( modv != NULL ) slapi_x_free_ldapmods( modv );
 #endif
        return rc;
 }
@@ -548,7 +546,7 @@ int slap_mods_check(
                }
 
                if ( is_at_obsolete( ad->ad_type ) &&
-                       ( ml->sml_op == LDAP_MOD_ADD || ml->sml_bvalues != NULL ) )
+                       ( ml->sml_op == LDAP_MOD_ADD || ml->sml_values != NULL ) )
                {
                        /*
                         * attribute is obsolete,
@@ -564,7 +562,7 @@ int slap_mods_check(
                /*
                 * check values
                 */
-               if( ml->sml_bvalues != NULL ) {
+               if( ml->sml_values != NULL ) {
                        ber_len_t nvals;
                        slap_syntax_validate_func *validate =
                                ad->ad_type->sat_syntax->ssyn_validate;
@@ -585,14 +583,14 @@ int slap_mods_check(
                         * check that each value is valid per syntax
                         *      and pretty if appropriate
                         */
-                       for( nvals = 0; ml->sml_bvalues[nvals].bv_val; nvals++ ) {
+                       for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) {
                                struct berval pval;
                                if( pretty ) {
                                        rc = pretty( ad->ad_type->sat_syntax,
-                                               &ml->sml_bvalues[nvals], &pval );
+                                               &ml->sml_values[nvals], &pval );
                                } else {
                                        rc = validate( ad->ad_type->sat_syntax,
-                                               &ml->sml_bvalues[nvals] );
+                                               &ml->sml_values[nvals] );
                                }
 
                                if( rc != 0 ) {
@@ -604,8 +602,8 @@ int slap_mods_check(
                                }
 
                                if( pretty ) {
-                                       ber_memfree( ml->sml_bvalues[nvals].bv_val );
-                                       ml->sml_bvalues[nvals] = pval;
+                                       ber_memfree( ml->sml_values[nvals].bv_val );
+                                       ml->sml_values[nvals] = pval;
                                }
                        }
 
@@ -613,15 +611,48 @@ int slap_mods_check(
                         * a rough single value check... an additional check is needed
                         * to catch add of single value to existing single valued attribute
                         */
-                       if( ( ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE )
+                       if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
                                && nvals > 1 && is_at_single_value( ad->ad_type ))
                        {
                                snprintf( textbuf, textlen,
-                                       "%s: multiple value provided",
+                                       "%s: multiple values provided",
                                        ml->sml_type.bv_val );
                                *text = textbuf;
                                return LDAP_CONSTRAINT_VIOLATION;
                        }
+
+#ifdef SLAP_NVALUES
+                       if( nvals && ad->ad_type->sat_equality &&
+                               ad->ad_type->sat_equality->smr_normalize )
+                       {
+                               ml->sml_nvalues = ch_malloc( (nvals+1)*sizeof(struct berval) );
+                               for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) {
+                                       rc = ad->ad_type->sat_equality->smr_normalize(
+                                               0,
+                                               ad->ad_type->sat_syntax,
+                                               ad->ad_type->sat_equality,
+                                               &ml->sml_values[nvals], &ml->sml_nvalues[nvals] );
+                                       if( rc ) {
+#ifdef NEW_LOGGING
+                                               LDAP_LOG( OPERATION, DETAIL1,
+                                                       "str2entry:  NULL (ssyn_normalize %d)\n",
+                                                       rc, 0, 0 );
+#else
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "<= str2entry NULL (ssyn_normalize %d)\n",
+                                                       rc, 0, 0 );
+#endif
+                                               snprintf( textbuf, textlen,
+                                                       "%s: value #%ld normalization failed",
+                                                       ml->sml_type.bv_val, (long) nvals );
+                                               *text = textbuf;
+                                               return rc;
+                                       }
+                               }
+                               ml->sml_nvalues[nvals].bv_val = NULL;
+                               ml->sml_nvalues[nvals].bv_len = 0;
+                       }
+#endif
                }
        }
 
@@ -637,6 +668,9 @@ int slap_mods_opattrs(
        char *textbuf, size_t textlen )
 {
        struct berval name, timestamp, csn;
+#ifdef SLAP_NVALUES
+       struct berval nname;
+#endif
        char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
        char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
        Modifications *mod;
@@ -665,8 +699,14 @@ int slap_mods_opattrs(
                if( op->o_dn.bv_len == 0 ) {
                        name.bv_val = SLAPD_ANONYMOUS;
                        name.bv_len = sizeof(SLAPD_ANONYMOUS)-1;
+#ifdef SLAP_NVALUES
+                       nname = name;
+#endif
                } else {
                        name = op->o_dn;
+#ifdef SLAP_NVALUES
+                       nname = op->o_ndn;
+#endif
                }
        }
 
@@ -684,10 +724,20 @@ int slap_mods_opattrs(
                        mod->sml_op = mop;
                        mod->sml_type.bv_val = NULL;
                        mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
-                       mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod->sml_bvalues[0], &tmpval );
-                       mod->sml_bvalues[1].bv_val = NULL;
-                       assert( mod->sml_bvalues[0].bv_val );
+                       mod->sml_values =
+                               (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+                       ber_dupbv( &mod->sml_values[0], &tmpval );
+                       mod->sml_values[1].bv_len = 0;
+                       mod->sml_values[1].bv_val = NULL;
+                       assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+                       mod->sml_nvalues =
+                               (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+                       ber_dupbv( &mod->sml_nvalues[0], &tmpval );
+                       mod->sml_nvalues[1].bv_len = 0;
+                       mod->sml_nvalues[1].bv_val = NULL;
+                       assert( mod->sml_nvalues[0].bv_val );
+#endif
                        *modtail = mod;
                        modtail = &mod->sml_next;
                }
@@ -702,10 +752,15 @@ int slap_mods_opattrs(
                        mod->sml_op = mop;
                        mod->sml_type.bv_val = NULL;
                        mod->sml_desc = slap_schema.si_ad_entryUUID;
-                       mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod->sml_bvalues[0], &tmpval );
-                       mod->sml_bvalues[1].bv_val = NULL;
-                       assert( mod->sml_bvalues[0].bv_val );
+                       mod->sml_values =
+                               (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+                       ber_dupbv( &mod->sml_values[0], &tmpval );
+                       mod->sml_values[1].bv_len = 0;
+                       mod->sml_values[1].bv_val = NULL;
+                       assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+                       mod->sml_nvalues = NULL;
+#endif
                        *modtail = mod;
                        modtail = &mod->sml_next;
 
@@ -713,10 +768,19 @@ int slap_mods_opattrs(
                        mod->sml_op = mop;
                        mod->sml_type.bv_val = NULL;
                        mod->sml_desc = slap_schema.si_ad_creatorsName;
-                       mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod->sml_bvalues[0], &name );
-                       mod->sml_bvalues[1].bv_val = NULL;
-                       assert( mod->sml_bvalues[0].bv_val );
+                       mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+                       ber_dupbv( &mod->sml_values[0], &name );
+                       mod->sml_values[1].bv_len = 0;
+                       mod->sml_values[1].bv_val = NULL;
+                       assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+                       mod->sml_nvalues =
+                               (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+                       ber_dupbv( &mod->sml_nvalues[0], &nname );
+                       mod->sml_nvalues[1].bv_len = 0;
+                       mod->sml_nvalues[1].bv_val = NULL;
+                       assert( mod->sml_nvalues[0].bv_val );
+#endif
                        *modtail = mod;
                        modtail = &mod->sml_next;
 
@@ -724,10 +788,14 @@ int slap_mods_opattrs(
                        mod->sml_op = mop;
                        mod->sml_type.bv_val = NULL;
                        mod->sml_desc = slap_schema.si_ad_createTimestamp;
-                       mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-                       ber_dupbv( &mod->sml_bvalues[0], &timestamp );
-                       mod->sml_bvalues[1].bv_val = NULL;
-                       assert( mod->sml_bvalues[0].bv_val );
+                       mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+                       ber_dupbv( &mod->sml_values[0], &timestamp );
+                       mod->sml_values[1].bv_len = 0;
+                       mod->sml_values[1].bv_val = NULL;
+                       assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+                       mod->sml_nvalues = NULL;
+#endif
                        *modtail = mod;
                        modtail = &mod->sml_next;
                }
@@ -738,10 +806,14 @@ int slap_mods_opattrs(
                mod->sml_op = mop;
                mod->sml_type.bv_val = NULL;
                mod->sml_desc = slap_schema.si_ad_entryCSN;
-               mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-               ber_dupbv( &mod->sml_bvalues[0], &csn );
-               mod->sml_bvalues[1].bv_val = NULL;
-               assert( mod->sml_bvalues[0].bv_val );
+               mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+               ber_dupbv( &mod->sml_values[0], &csn );
+               mod->sml_values[1].bv_len = 0;
+               mod->sml_values[1].bv_val = NULL;
+               assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+               mod->sml_nvalues = NULL;
+#endif
                *modtail = mod;
                modtail = &mod->sml_next;
 
@@ -749,10 +821,19 @@ int slap_mods_opattrs(
                mod->sml_op = mop;
                mod->sml_type.bv_val = NULL;
                mod->sml_desc = slap_schema.si_ad_modifiersName;
-               mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-               ber_dupbv( &mod->sml_bvalues[0], &name );
-               mod->sml_bvalues[1].bv_val = NULL;
-               assert( mod->sml_bvalues[0].bv_val );
+               mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+               ber_dupbv( &mod->sml_values[0], &name );
+               mod->sml_values[1].bv_len = 0;
+               mod->sml_values[1].bv_val = NULL;
+               assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+               mod->sml_nvalues =
+                       (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+               ber_dupbv( &mod->sml_nvalues[0], &nname );
+               mod->sml_nvalues[1].bv_len = 0;
+               mod->sml_nvalues[1].bv_val = NULL;
+               assert( mod->sml_nvalues[0].bv_val );
+#endif
                *modtail = mod;
                modtail = &mod->sml_next;
 
@@ -760,10 +841,14 @@ int slap_mods_opattrs(
                mod->sml_op = mop;
                mod->sml_type.bv_val = NULL;
                mod->sml_desc = slap_schema.si_ad_modifyTimestamp;
-               mod->sml_bvalues = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
-               ber_dupbv( &mod->sml_bvalues[0], &timestamp );
-               mod->sml_bvalues[1].bv_val = NULL;
-               assert( mod->sml_bvalues[0].bv_val );
+               mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
+               ber_dupbv( &mod->sml_values[0], &timestamp );
+               mod->sml_values[1].bv_len = 0;
+               mod->sml_values[1].bv_val = NULL;
+               assert( mod->sml_values[0].bv_val );
+#ifdef SLAP_NVALUES
+               mod->sml_nvalues = NULL;
+#endif
                *modtail = mod;
                modtail = &mod->sml_next;
        }
@@ -772,154 +857,3 @@ int slap_mods_opattrs(
        return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_SLAPI
-/*
- * Synthesise an LDAPMod array from a Modifications list to pass
- * to SLAPI. This synthesis is destructive and as such the 
- * Modifications list may not be used after calling this 
- * function.
- * 
- * This function must also be called before slap_mods_check().
- */
-static LDAPMod **Modifications2LDAPMods(Modifications **pmodlist)
-{
-       Modifications *ml, *modlist;
-       LDAPMod **mods, *modp;
-       int i, j;
-
-       modlist = *pmodlist;
-
-       for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
-               ;
-
-       mods = (LDAPMod **)ch_malloc( (i + 1) * sizeof(LDAPMod *) );
-
-       for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
-               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 ( ml->sml_bvalues != NULL ) {
-                       for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ )
-                               ;
-                       modp->mod_bvalues = (struct berval **)ch_malloc( (j + 1) *
-                               sizeof(struct berval *) );
-                       for( j = 0; ml->sml_bvalues[j].bv_val != NULL; j++ ) {
-                               /* Take ownership of original values. */
-                               modp->mod_bvalues[j] = (struct berval *)ch_malloc( sizeof(struct berval) );
-                               modp->mod_bvalues[j]->bv_len = ml->sml_bvalues[j].bv_len;
-                               modp->mod_bvalues[j]->bv_val = ml->sml_bvalues[j].bv_val;
-                               ml->sml_bvalues[j].bv_len = 0;
-                               ml->sml_bvalues[j].bv_val = NULL;
-                       }
-                       modp->mod_bvalues[j] = NULL;
-               } else {
-                       modp->mod_bvalues = NULL;
-               }
-               i++;
-       }
-
-       mods[i] = NULL;
-
-       slap_mods_free( modlist );
-       *pmodlist = NULL;
-
-       return mods;
-}
-
-/*
- * 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 FreeLDAPMods()
- * (see below).
- */
-static Modifications *LDAPMods2Modifications (LDAPMod **mods)
-{
-       Modifications *modlist, **modtail;
-       LDAPMod **modp;
-
-       modtail = &modlist;
-
-       for( modp = mods; *modp != NULL; modp++ ) {
-               Modifications *mod;
-               int i;
-               char **p;
-               struct berval **bvp;
-
-               mod = (Modifications *) ch_malloc( sizeof(Modifications) );
-               mod->sml_op = (*modp)->mod_op & (~LDAP_MOD_BVALUES);
-               mod->sml_type.bv_val = (*modp)->mod_type;
-               mod->sml_type.bv_len = strlen( mod->sml_type.bv_val );
-               mod->sml_desc = NULL;
-               mod->sml_next = NULL;
-
-               if ( (*modp)->mod_op & LDAP_MOD_BVALUES ) {
-                       for( i = 0, bvp = (*modp)->mod_bvalues; *bvp != NULL; bvp++, i++ )
-                               ;
-               } else {
-                       for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ )
-                               ;
-               }
-
-               mod->sml_bvalues = (BerVarray) 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++, i++ ) {
-                               mod->sml_bvalues[i].bv_val = (*bvp)->bv_val;
-                               mod->sml_bvalues[i].bv_len = (*bvp)->bv_len;
-                       }
-               } else {
-                       for( i = 0, p = (*modp)->mod_values; *p != NULL; p++, i++ ) {
-                               mod->sml_bvalues[i].bv_val = *p;
-                               mod->sml_bvalues[i].bv_len = strlen( *p );
-                       }
-               }
-               mod->sml_bvalues[i].bv_val = NULL;
-
-               *modtail = mod;
-               modtail = &mod->sml_next;
-       }
-       
-       return modlist;
-}
-
-/*
- * This function only frees the parts of the mods array that
- * are not shared with the Modification list that was created
- * by LDAPMods2Modifications. 
- *
- */
-static void FreeLDAPMods (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 ) {
-                       for ( j = 0; mods[i]->mod_bvalues[j] != NULL; j++ ) {
-                               ch_free( mods[i]->mod_bvalues[j] );
-                       }
-                       ch_free( mods[i]->mod_bvalues );
-               } else {
-                       ch_free( mods[i]->mod_values );
-               }
-               /* Don't free type, for same reasons. */
-               ch_free( mods[i] );
-       }
-       ch_free( mods );
-}
-
-#endif /* LDAP_SLAPI */
-