]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/mods.c
Silence a warning about ldap_debug
[openldap] / servers / slapd / mods.c
index 3f7772fdfe626ffab9eb59ed4fa60075b19e6197..203524666a12544afb03e8a4b1b4f603f2247833 100644 (file)
 
 #include "slap.h"
 
+int
+modify_add_values(
+       Entry   *e,
+       Modification    *mod,
+       const char      **text,
+       char *textbuf, size_t textlen
+)
+{
+       int             i, j;
+       Attribute       *a;
+       MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+       const char *op;
+
+       switch( mod->sm_op ) {
+       case LDAP_MOD_ADD:
+               op = "add";
+               break;
+       case LDAP_MOD_REPLACE:
+               op = "replace";
+               break;
+       default:
+               op = "?";
+               assert( 0 );
+       }
+
+       a = attr_find( e->e_attrs, mod->sm_desc );
+
+       /* check if the values we're adding already exist */
+       if( mr == NULL || !mr->smr_match ) {
+               if ( a != NULL ) {
+                       /* do not allow add of additional attribute
+                               if no equality rule exists */
+                       *text = textbuf;
+                       snprintf( textbuf, textlen,
+                               "modify/%s: %s: no equality matching rule",
+                               op, mod->sm_desc->ad_cname.bv_val );
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
+
+               for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
+                       /* test asserted values against existing values */
+                       if( a ) {
+                               for( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
+                                       int rc = ber_bvcmp( &mod->sm_bvalues[i],
+                                               &a->a_vals[j] );
+
+                                       if( rc == 0 ) {
+                                               /* value exists already */
+                                               *text = textbuf;
+                                               snprintf( textbuf, textlen,
+                                                       "modify/%s: %s: value #%i already exists",
+                                                       op, mod->sm_desc->ad_cname.bv_val );
+                                               return LDAP_TYPE_OR_VALUE_EXISTS;
+                                       }
+                               }
+                       }
+
+                       /* test asserted values against themselves */
+                       for( j = 0; j < i; j++ ) {
+                               int rc = ber_bvcmp( &mod->sm_bvalues[i],
+                                       &mod->sm_bvalues[j] );
+
+                               if( rc == 0 ) {
+                                       /* value exists already */
+                                       *text = textbuf;
+                                       snprintf( textbuf, textlen,
+                                               "modify/%s: %s: value #%i already exists",
+                                               op, mod->sm_desc->ad_cname.bv_val );
+                                       return LDAP_TYPE_OR_VALUE_EXISTS;
+                               }
+                       }
+               }
+
+       } else {
+               for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
+                       int rc, match;
+                       struct berval asserted;
+
+                       rc = value_normalize( mod->sm_desc,
+                               SLAP_MR_EQUALITY,
+                               &mod->sm_bvalues[i],
+                               &asserted,
+                               text );
+
+                       if( rc != LDAP_SUCCESS ) return rc;
+
+                       if( a ) {
+                               for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
+                                       int rc = value_match( &match, mod->sm_desc, mr,
+                                               SLAP_MR_VALUE_SYNTAX_MATCH,
+                                               &a->a_vals[j], &asserted, text );
+
+                                       if( rc == LDAP_SUCCESS && match == 0 ) {
+                                               free( asserted.bv_val );
+                                               return LDAP_TYPE_OR_VALUE_EXISTS;
+                                       }
+                               }
+                       }
+
+                       for ( j = 0; j < i; j++ ) {
+                               int rc = value_match( &match, mod->sm_desc, mr,
+                                       SLAP_MR_VALUE_SYNTAX_MATCH,
+                                       &mod->sm_bvalues[j], &asserted, text );
+
+                               if( rc == LDAP_SUCCESS && match == 0 ) {
+                                       free( asserted.bv_val );
+                                       return LDAP_TYPE_OR_VALUE_EXISTS;
+                               }
+                       }
+
+                       free( asserted.bv_val );
+               }
+       }
+
+       /* no - add them */
+       if( attr_merge( e, mod->sm_desc, mod->sm_bvalues ) != 0 ) {
+               /* this should return result of attr_merge */
+               *text = textbuf;
+               snprintf( textbuf, textlen,
+                       "modify/%s: %s: merge error",
+                       op, mod->sm_desc->ad_cname.bv_val );
+               return LDAP_OTHER;
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+modify_delete_values(
+       Entry   *e,
+       Modification    *mod,
+       const char      **text,
+       char *textbuf, size_t textlen
+)
+{
+       int             i, j, k, found;
+       Attribute       *a;
+       char *desc = mod->sm_desc->ad_cname.bv_val;
+       MatchingRule *mr = mod->sm_desc->ad_type->sat_equality;
+
+       /* delete the entire attribute */
+       if ( mod->sm_bvalues == NULL ) {
+               int rc = attr_delete( &e->e_attrs, mod->sm_desc );
+
+               if( rc != LDAP_SUCCESS ) {
+                       *text = textbuf;
+                       snprintf( textbuf, textlen,
+                               "modify/delete: %s: no such attribute",
+                               mod->sm_desc->ad_cname.bv_val );
+                       rc = LDAP_NO_SUCH_ATTRIBUTE;
+               }
+               return rc;
+       }
+
+       if( mr == NULL || !mr->smr_match ) {
+               /* disallow specific attributes from being deleted if
+                       no equality rule */
+               *text = textbuf;
+               snprintf( textbuf, textlen,
+                       "modify/delete: %s: no equality matching rule",
+                       mod->sm_desc->ad_cname.bv_val );
+               return LDAP_INAPPROPRIATE_MATCHING;
+       }
+
+       /* delete specific values - find the attribute first */
+       if ( (a = attr_find( e->e_attrs, mod->sm_desc )) == NULL ) {
+               *text = textbuf;
+               snprintf( textbuf, textlen,
+                       "modify/delete: %s: no such attribute",
+                       mod->sm_desc->ad_cname.bv_val );
+               return LDAP_NO_SUCH_ATTRIBUTE;
+       }
+
+       /* find each value to delete */
+       for ( i = 0; mod->sm_bvalues[i].bv_val != NULL; i++ ) {
+               int rc;
+               struct berval asserted;
+
+               rc = value_normalize( mod->sm_desc,
+                       SLAP_MR_EQUALITY,
+                       &mod->sm_bvalues[i],
+                       &asserted,
+                       text );
+
+               if( rc != LDAP_SUCCESS ) return rc;
+
+               found = 0;
+               for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) {
+                       int match;
+                       int rc = value_match( &match, mod->sm_desc, mr,
+                               SLAP_MR_VALUE_SYNTAX_MATCH,
+                               &a->a_vals[j], &asserted, text );
+
+                       if( rc == LDAP_SUCCESS && match != 0 ) {
+                               continue;
+                       }
+
+                       /* found a matching value */
+                       found = 1;
+
+                       /* delete it */
+                       free( a->a_vals[j].bv_val );
+                       for ( k = j + 1; a->a_vals[k].bv_val != NULL; k++ ) {
+                               a->a_vals[k - 1] = a->a_vals[k];
+                       }
+                       a->a_vals[k - 1].bv_val = NULL;
+                       a->a_vals[k - 1].bv_len = 0;
+
+                       break;
+               }
+
+               free( asserted.bv_val );
+
+               /* looked through them all w/o finding it */
+               if ( ! found ) {
+                       *text = textbuf;
+                       snprintf( textbuf, textlen,
+                               "modify/delete: %s: no such value",
+                               mod->sm_desc->ad_cname.bv_val );
+                       return LDAP_NO_SUCH_ATTRIBUTE;
+               }
+       }
+
+       /* if no values remain, delete the entire attribute */
+       if ( a->a_vals[0].bv_val == NULL ) {
+               if ( attr_delete( &e->e_attrs, mod->sm_desc ) ) {
+                       *text = textbuf;
+                       snprintf( textbuf, textlen,
+                               "modify/delete: %s: no such attribute",
+                               mod->sm_desc->ad_cname.bv_val );
+                       return LDAP_NO_SUCH_ATTRIBUTE;
+               }
+       }
+
+       return LDAP_SUCCESS;
+}
+
+int
+modify_replace_values(
+       Entry   *e,
+       Modification    *mod,
+       const char      **text,
+       char *textbuf, size_t textlen
+)
+{
+       (void) attr_delete( &e->e_attrs, mod->sm_desc );
+
+       if ( mod->sm_bvalues ) {
+               return modify_add_values( e, mod, text, textbuf, textlen );
+       }
+
+       return LDAP_SUCCESS;
+}
+
 void
 slap_mod_free(
        Modification    *mod,
        int                             freeit
 )
 {
+#if 0
        if ( mod->sm_type.bv_val)
                free( mod->sm_type.bv_val );
+#endif
        if ( mod->sm_bvalues != NULL )
-               bvarray_free( mod->sm_bvalues );
+               ber_bvarray_free( mod->sm_bvalues );
 
        if( freeit )
                free( mod );