]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/modify.c
ITS#2368 - fix deleting key from range IDL
[openldap] / servers / slapd / modify.c
index 42ccaeeaf6ea672bfba5180c15d3664ecf724650..1d3c7b325ff97b4b7e77bd46dcfd3a418d15838b 100644 (file)
 #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"
+
 
 int
 do_modify(
@@ -42,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 );
@@ -107,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,
@@ -121,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",
@@ -237,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 );
@@ -253,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;
@@ -296,6 +303,7 @@ do_modify(
                                op->o_connid, op->o_opid, abuf, 0, 0 );
                }
        }
+#endif /* LDAP_DEBUG */
 
        manageDSAit = get_manageDSAit( op );
 
@@ -329,9 +337,6 @@ 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 );
@@ -541,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,
@@ -557,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;
@@ -578,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 ) {
@@ -597,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;
                                }
                        }
 
@@ -606,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
                }
        }
 
@@ -630,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;
@@ -658,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
                }
        }
 
@@ -677,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;
                }
@@ -695,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;
 
@@ -706,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;
 
@@ -717,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;
                }
@@ -731,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;
 
@@ -742,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;
 
@@ -753,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;
        }