int dnExtractRdn( struct berval *dn, struct berval *rdn, void *ctx ) { LDAPRDN tmpRDN; const char *p; int rc; assert( dn != NULL ); assert( rdn != NULL ); if( dn->bv_len == 0 ) { return LDAP_OTHER; } rc = ldap_bv2rdn_x( dn, &tmpRDN, (char **)&p, LDAP_DN_FORMAT_LDAP, ctx ); if ( rc != LDAP_SUCCESS ) { return rc; } rc = ldap_rdn2bv_x( tmpRDN, rdn, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY, ctx ); ldap_rdnfree_x( tmpRDN, ctx ); return rc; }
int rdnPretty( Syntax *syntax, struct berval *val, struct berval *out, void *ctx) { assert( val != NULL ); assert( out != NULL ); Debug( LDAP_DEBUG_TRACE, ">>> rdnPretty: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); if ( val->bv_len == 0 ) { ber_dupbv_x( out, val, ctx ); } else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) { return LDAP_INVALID_SYNTAX; } else { LDAPRDN rdn = NULL; int rc; char* p; /* FIXME: should be liberal in what we accept */ rc = ldap_bv2rdn_x( val , &rdn, (char **) &p, LDAP_DN_FORMAT_LDAP, ctx); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( val->bv_val ) == val->bv_len ); /* * Schema-aware rewrite */ if ( LDAPRDN_rewrite( rdn, SLAP_LDAPDN_PRETTY, ctx ) != LDAP_SUCCESS ) { ldap_rdnfree_x( rdn, ctx ); return LDAP_INVALID_SYNTAX; } /* FIXME: not sure why the default isn't pretty */ /* RE: the default is the form that is used as * an internal representation; the pretty form * is a variant */ rc = ldap_rdn2bv_x( rdn, out, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY, ctx ); ldap_rdnfree_x( rdn, ctx ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } } Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val ? out->bv_val : "", 0, 0 ); return LDAP_SUCCESS; }
int rdnNormalize( slap_mask_t use, Syntax *syntax, MatchingRule *mr, struct berval *val, struct berval *out, void *ctx) { assert( val != NULL ); assert( out != NULL ); Debug( LDAP_DEBUG_TRACE, ">>> dnNormalize: <%s>\n", val->bv_val ? val->bv_val : "", 0, 0 ); if ( val->bv_len != 0 ) { LDAPRDN rdn = NULL; int rc; char* p; /* * Go to structural representation */ rc = ldap_bv2rdn_x( val , &rdn, (char **) &p, LDAP_DN_FORMAT_LDAP, ctx); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( val->bv_val ) == val->bv_len ); /* * Schema-aware rewrite */ if ( LDAPRDN_rewrite( rdn, 0, ctx ) != LDAP_SUCCESS ) { ldap_rdnfree_x( rdn, ctx ); return LDAP_INVALID_SYNTAX; } /* * Back to string representation */ rc = ldap_rdn2bv_x( rdn, out, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY, ctx ); ldap_rdnfree_x( rdn, ctx ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } } else { ber_dupbv_x( out, val, ctx ); } Debug( LDAP_DEBUG_TRACE, "<<< dnNormalize: <%s>\n", out->bv_val ? out->bv_val : "", 0, 0 ); return LDAP_SUCCESS; }
int rdnValidate( Syntax *syntax, struct berval *in ) { int rc; LDAPRDN rdn; char* p; assert( in != NULL ); if ( in->bv_len == 0 ) { return LDAP_SUCCESS; } else if ( in->bv_len > SLAP_LDAPDN_MAXLEN ) { return LDAP_INVALID_SYNTAX; } rc = ldap_bv2rdn_x( in , &rdn, (char **) &p, LDAP_DN_FORMAT_LDAP, NULL); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } assert( strlen( in->bv_val ) == in->bv_len ); /* * Schema-aware validate */ rc = LDAPRDN_validate( rdn ); ldap_rdnfree( rdn ); if ( rc != LDAP_SUCCESS ) { return LDAP_INVALID_SYNTAX; } return LDAP_SUCCESS; }
int slap_modrdn2mods( Operation *op, SlapReply *rs ) { int a_cnt, d_cnt; LDAPRDN old_rdn = NULL; LDAPRDN new_rdn = NULL; assert( !BER_BVISEMPTY( &op->oq_modrdn.rs_newrdn ) ); /* if requestDN is empty, silently reset deleteOldRDN */ if ( BER_BVISEMPTY( &op->o_req_dn ) ) op->orr_deleteoldrdn = 0; if ( ldap_bv2rdn_x( &op->oq_modrdn.rs_newrdn, &new_rdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { Debug( LDAP_DEBUG_TRACE, "%s slap_modrdn2mods: can't figure out " "type(s)/value(s) of newrdn\n", op->o_log_prefix, 0, 0 ); rs->sr_err = LDAP_INVALID_DN_SYNTAX; rs->sr_text = "unknown type(s)/value(s) used in RDN"; goto done; } if ( op->oq_modrdn.rs_deleteoldrdn ) { if ( ldap_bv2rdn_x( &op->o_req_dn, &old_rdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { Debug( LDAP_DEBUG_TRACE, "%s slap_modrdn2mods: can't figure out " "type(s)/value(s) of oldrdn\n", op->o_log_prefix, 0, 0 ); rs->sr_err = LDAP_OTHER; rs->sr_text = "cannot parse RDN from old DN"; goto done; } } rs->sr_text = NULL; /* Add new attribute values to the entry */ for ( a_cnt = 0; new_rdn[a_cnt]; a_cnt++ ) { AttributeDescription *desc = NULL; Modifications *mod_tmp; rs->sr_err = slap_bv2ad( &new_rdn[a_cnt]->la_attr, &desc, &rs->sr_text ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s slap_modrdn2mods: %s: %s (new)\n", op->o_log_prefix, rs->sr_text, new_rdn[ a_cnt ]->la_attr.bv_val ); goto done; } if ( !desc->ad_type->sat_equality ) { Debug( LDAP_DEBUG_TRACE, "%s slap_modrdn2mods: %s: %s (new)\n", op->o_log_prefix, rs->sr_text, new_rdn[ a_cnt ]->la_attr.bv_val ); rs->sr_text = "naming attribute has no equality matching rule"; rs->sr_err = LDAP_NAMING_VIOLATION; goto done; } /* Apply modification */ mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) ); mod_tmp->sml_desc = desc; BER_BVZERO( &mod_tmp->sml_type ); mod_tmp->sml_numvals = 1; mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &mod_tmp->sml_values[0], &new_rdn[a_cnt]->la_value ); mod_tmp->sml_values[1].bv_val = NULL; if( desc->ad_type->sat_equality->smr_normalize) { mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) ); rs->sr_err = desc->ad_type->sat_equality->smr_normalize( SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &mod_tmp->sml_values[0], &mod_tmp->sml_nvalues[0], NULL ); if (rs->sr_err != LDAP_SUCCESS) { ch_free(mod_tmp->sml_nvalues); ch_free(mod_tmp->sml_values[0].bv_val); ch_free(mod_tmp->sml_values); ch_free(mod_tmp); goto done; } mod_tmp->sml_nvalues[1].bv_val = NULL; } else { mod_tmp->sml_nvalues = NULL; } mod_tmp->sml_op = SLAP_MOD_SOFTADD; mod_tmp->sml_flags = 0; mod_tmp->sml_next = op->orr_modlist; op->orr_modlist = mod_tmp; } /* Remove old rdn value if required */ if ( op->orr_deleteoldrdn ) { for ( d_cnt = 0; old_rdn[d_cnt]; d_cnt++ ) { AttributeDescription *desc = NULL; Modifications *mod_tmp; rs->sr_err = slap_bv2ad( &old_rdn[d_cnt]->la_attr, &desc, &rs->sr_text ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s slap_modrdn2mods: %s: %s (old)\n", op->o_log_prefix, rs->sr_text, old_rdn[d_cnt]->la_attr.bv_val ); goto done; } /* Apply modification */ mod_tmp = ( Modifications * )ch_malloc( sizeof( Modifications ) ); mod_tmp->sml_desc = desc; BER_BVZERO( &mod_tmp->sml_type ); mod_tmp->sml_numvals = 1; mod_tmp->sml_values = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &mod_tmp->sml_values[0], &old_rdn[d_cnt]->la_value ); mod_tmp->sml_values[1].bv_val = NULL; if( desc->ad_type->sat_equality->smr_normalize) { mod_tmp->sml_nvalues = ( BerVarray )ch_malloc( 2 * sizeof( struct berval ) ); (void) (*desc->ad_type->sat_equality->smr_normalize)( SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &mod_tmp->sml_values[0], &mod_tmp->sml_nvalues[0], NULL ); mod_tmp->sml_nvalues[1].bv_val = NULL; } else { mod_tmp->sml_nvalues = NULL; } mod_tmp->sml_op = LDAP_MOD_DELETE; mod_tmp->sml_flags = 0; mod_tmp->sml_next = op->orr_modlist; op->orr_modlist = mod_tmp; } } done: /* LDAP v2 supporting correct attribute handling. */ if ( rs->sr_err != LDAP_SUCCESS && op->orr_modlist != NULL ) { Modifications *tmp; for ( ; op->orr_modlist != NULL; op->orr_modlist = tmp ) { tmp = op->orr_modlist->sml_next; ch_free( op->orr_modlist ); } } if ( new_rdn != NULL ) { ldap_rdnfree_x( new_rdn, op->o_tmpmemctx ); } if ( old_rdn != NULL ) { ldap_rdnfree_x( old_rdn, op->o_tmpmemctx ); } return rs->sr_err; }
static int rdnval_rdn2vals( Operation *op, SlapReply *rs, struct berval *dn, struct berval *ndn, BerVarray *valsp, BerVarray *nvalsp, int *numvalsp ) { LDAPRDN rdn = NULL, nrdn = NULL; int nAVA, i; assert( *valsp == NULL ); assert( *nvalsp == NULL ); *numvalsp = 0; if ( ldap_bv2rdn_x( dn, &rdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: can't figure out " "type(s)/value(s) of rdn DN=\"%s\"\n", op->o_log_prefix, dn->bv_val, 0 ); rs->sr_err = LDAP_INVALID_DN_SYNTAX; rs->sr_text = "unknown type(s) used in RDN"; goto done; } if ( ldap_bv2rdn_x( ndn, &nrdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP, op->o_tmpmemctx ) ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: can't figure out " "type(s)/value(s) of normalized rdn DN=\"%s\"\n", op->o_log_prefix, ndn->bv_val, 0 ); rs->sr_err = LDAP_INVALID_DN_SYNTAX; rs->sr_text = "unknown type(s) used in RDN"; goto done; } for ( nAVA = 0; rdn[ nAVA ]; nAVA++ ) /* count'em */ ; /* NOTE: we assume rdn and nrdn contain the same AVAs! */ *valsp = SLAP_CALLOC( sizeof( struct berval ), nAVA + 1 ); *nvalsp = SLAP_CALLOC( sizeof( struct berval ), nAVA + 1 ); /* Add new attribute values to the entry */ for ( i = 0; rdn[ i ]; i++ ) { AttributeDescription *desc = NULL; rs->sr_err = slap_bv2ad( &rdn[ i ]->la_attr, &desc, &rs->sr_text ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: %s: %s\n", op->o_log_prefix, rs->sr_text, rdn[ i ]->la_attr.bv_val ); goto done; } if ( !rdnval_is_valid( desc, &rdn[ i ]->la_value ) ) { Debug( LDAP_DEBUG_TRACE, "%s rdnval: syntax of naming attribute '%s' " "not compatible with directoryString", op->o_log_prefix, rdn[ i ]->la_attr.bv_val, 0 ); continue; } if ( value_find_ex( desc, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, *nvalsp, &nrdn[ i ]->la_value, op->o_tmpmemctx ) == LDAP_NO_SUCH_ATTRIBUTE ) { ber_dupbv( &(*valsp)[ *numvalsp ], &rdn[ i ]->la_value ); ber_dupbv( &(*nvalsp)[ *numvalsp ], &nrdn[ i ]->la_value ); (*numvalsp)++; } } if ( rdnval_unique_check( op, *valsp ) != LDAP_SUCCESS ) { rs->sr_err = LDAP_CONSTRAINT_VIOLATION; rs->sr_text = "rdnValue not unique within siblings"; goto done; } done:; if ( rdn != NULL ) { ldap_rdnfree_x( rdn, op->o_tmpmemctx ); } if ( nrdn != NULL ) { ldap_rdnfree_x( nrdn, op->o_tmpmemctx ); } if ( rs->sr_err != LDAP_SUCCESS ) { if ( *valsp != NULL ) { ber_bvarray_free( *valsp ); ber_bvarray_free( *nvalsp ); *valsp = NULL; *nvalsp = NULL; *numvalsp = 0; } } return rs->sr_err; }