static int slap_mods2entry(
Modifications *mods,
Entry **e,
- const char **text );
+ int repl_user,
+ const char **text,
+ char *textbuf, size_t textlen );
int
do_add( Connection *conn, Operation *op )
}
e = (Entry *) ch_calloc( 1, sizeof(Entry) );
- e->e_name.bv_val = NULL;
- e->e_name.bv_len = 0;
- e->e_nname.bv_val = NULL;
- e->e_nname.bv_len = 0;
- e->e_attrs = NULL;
- e->e_private = NULL;
rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );
tag = ber_next_element( ber, &len, last ) )
{
Modifications *mod;
+ ber_tag_t rtag;
- rc = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_bvalues );
+ rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_bvalues );
- if ( rc == LBER_ERROR ) {
+ if ( rtag == LBER_ERROR ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "operation", LDAP_LEVEL_ERR,
"do_add: conn %d decoding error \n", conn->c_connid ));
#endif
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "no values for attribute type", NULL, NULL );
- free( tmp.sml_type.bv_val );
goto done;
}
mod = (Modifications *) ch_malloc( sizeof(Modifications) );
goto done;
}
- Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d ADD dn=\"%s\"\n",
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu ADD dn=\"%s\"\n",
op->o_connid, op->o_opid, e->e_dn, 0, 0 );
if( e->e_nname.bv_len == 0 ) {
}
}
- rc = slap_mods2entry( modlist, &e, &text );
+ rc = slap_mods2entry( modlist, &e, repl_user, &text,
+ textbuf, textlen );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
static int slap_mods2entry(
Modifications *mods,
Entry **e,
- const char **text )
+ int repl_user,
+ const char **text,
+ char *textbuf, size_t textlen )
{
Attribute **tail = &(*e)->e_attrs;
assert( *tail == NULL );
+ *text = textbuf;
+
for( ; mods != NULL; mods = mods->sml_next ) {
Attribute *attr;
#ifdef SLURPD_FRIENDLY
ber_len_t i,j;
+ if( !repl_user ) {
+ snprintf( textbuf, textlen,
+ "attribute '%s' provided more than once",
+ mods->sml_desc->ad_cname.bv_val );
+ return LDAP_TYPE_OR_VALUE_EXISTS;
+ }
+
for( i=0; attr->a_vals[i].bv_val; i++ ) {
/* count them */
}
sizeof( struct berval ) * (i+j) );
/* should check for duplicates */
+
AC_MEMCPY( &attr->a_vals[i], mods->sml_bvalues,
sizeof( struct berval ) * j );
continue;
#else
- *text = "attribute provided more than once";
+ snprintf( textbuf, textlen,
+ "attribute '%s' provided more than once",
+ mods->sml_desc->ad_cname.bv_val );
return LDAP_TYPE_OR_VALUE_EXISTS;
#endif
}
+ if( mods->sml_bvalues[1].bv_val != NULL ) {
+ /* check for duplicates */
+ int i, j;
+ MatchingRule *mr = mods->sml_desc->ad_type->sat_equality;
+
+ /* check if the values we're adding already exist */
+ if( mr == NULL || !mr->smr_match ) {
+ for ( i = 0; mods->sml_bvalues[i].bv_val != NULL; i++ ) {
+ /* test asserted values against themselves */
+ for( j = 0; j < i; j++ ) {
+ int rc = ber_bvcmp( &mods->sml_bvalues[i],
+ &mods->sml_bvalues[j] );
+
+ if( rc == 0 ) {
+ /* value exists already */
+ snprintf( textbuf, textlen,
+ "%s: value #%d provided more than once",
+ mods->sml_desc->ad_cname.bv_val, j );
+ return LDAP_TYPE_OR_VALUE_EXISTS;
+ }
+ }
+ }
+
+ } else {
+ for ( i = 0; mods->sml_bvalues[i].bv_val != NULL; i++ ) {
+ int rc, match;
+ const char *text = NULL;
+ struct berval asserted;
+
+ rc = value_normalize( mods->sml_desc,
+ SLAP_MR_EQUALITY,
+ &mods->sml_bvalues[i],
+ &asserted,
+ &text );
+
+ if( rc != LDAP_SUCCESS ) return rc;
+
+ for ( j = 0; j < i; j++ ) {
+ int rc = value_match( &match, mods->sml_desc, mr,
+ SLAP_MR_VALUE_SYNTAX_MATCH,
+ &mods->sml_bvalues[j], &asserted, &text );
+
+ if( rc == LDAP_SUCCESS && match == 0 ) {
+ free( asserted.bv_val );
+ snprintf( textbuf, textlen,
+ "%s: value #%d provided more than once",
+ mods->sml_desc->ad_cname.bv_val, j );
+ return LDAP_TYPE_OR_VALUE_EXISTS;
+ }
+ }
+
+ free( asserted.bv_val );
+ }
+ }
+ }
+
attr = ch_calloc( 1, sizeof(Attribute) );
/* move ad to attr structure */