More -DSLAPD_SCHEMA_NOT_COMPAT changes, including initial

impl of slap_modlist2mods() and is_at_subtype().
This commit is contained in:
Kurt Zeilenga 2000-02-25 19:36:07 +00:00
parent 2c16d08b7c
commit 76553ea53f
6 changed files with 329 additions and 66 deletions

View File

@ -19,6 +19,16 @@
#include "slap.h"
#ifdef SLAPD_SCHEMA_NOT_COMPAT
void
ad_free( AttributeDescription *ad, int freeit )
{
if( ad == NULL ) return;
ber_bvfree( ad->ad_cname );
free( ad->ad_lang );
if( freeit ) free( ad );
}
static int ad_keystring(
struct berval *bv )
@ -148,7 +158,10 @@ int slap_bv2ad(
strcat( desc.ad_cname->bv_val, desc.ad_lang );
}
*ad = ch_malloc( sizeof( AttributeDescription ) );
if( *ad == NULL ) {
*ad = ch_malloc( sizeof( AttributeDescription ) );
}
**ad = desc;
rtn = LDAP_SUCCESS;
@ -158,15 +171,42 @@ done:
return rtn;
}
void
ad_free( AttributeDescription *ad, int freeit )
int ad_inlist(
AttributeDescription *desc,
char **attrs )
{
if( ad == NULL ) return;
int i;
for( i=0; attrs[i] != NULL; i++ ) {
AttributeDescription *ad = NULL;
char *text;
int rc = slap_str2ad( attrs[i], &ad, &text );
ber_bvfree( ad->ad_cname );
free( ad->ad_lang );
if( rc != LDAP_SUCCESS ) {
goto cont;
}
if( freeit ) free( ad );
if( !is_at_subtype( desc->ad_type, ad->ad_type ) ) {
goto cont;
}
if( ad->ad_flags && ( ad->ad_flags == desc->ad_flags )) {
goto cont;
}
if( ad->ad_lang != NULL && ( desc->ad_lang == NULL
|| strcasecmp( ad->ad_lang, desc->ad_lang )))
{
goto cont;
}
ad_free( ad, 1 );
return 1;
cont:
ad_free( ad, 1 );
}
return 0;
}
#endif

View File

@ -26,7 +26,14 @@
#include "ldap_pvt.h"
#include "slap.h"
#ifdef SLAPD_SCHEMA_NOT_COMPAT
static int slap_mods2entry(
Modifications *mods,
Entry **e,
char **text );
#else
static int add_created_attrs(Operation *op, Entry *e);
#endif
int
do_add( Connection *conn, Operation *op )
@ -37,6 +44,12 @@ do_add( Connection *conn, Operation *op )
ber_tag_t tag;
Entry *e;
Backend *be;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
LDAPModList *modlist = NULL;
LDAPModList **modtail = &modlist;
Modifications *mods = NULL;
char *text;
#endif
int rc = LDAP_SUCCESS;
Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 );
@ -91,29 +104,48 @@ do_add( Connection *conn, Operation *op )
/* get the attrs */
for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) ) {
char *type;
struct berval **vals;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
LDAPModList *mod = (LDAPModList *) ch_malloc( sizeof(LDAPModList) );
#else
LDAPModList tmpmod;
LDAPModList *mod = &tmpmod;
#endif
mod->ml_op = LDAP_MOD_ADD;
mod->ml_next = NULL;
if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
rc = ber_scanf( ber, "{a{V}}", &mod->ml_type, &mod->ml_bvalues );
if ( rc == LBER_ERROR ) {
send_ldap_disconnect( conn, op,
LDAP_PROTOCOL_ERROR, "decoding error" );
rc = -1;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
free( mod );
#endif
goto done;
}
if ( vals == NULL ) {
Debug( LDAP_DEBUG_ANY, "no values for type %s\n", type,
0, 0 );
if ( mod->ml_bvalues == NULL ) {
Debug( LDAP_DEBUG_ANY, "no values for type %s\n",
mod->ml_type, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "no values for type", NULL, NULL );
free( type );
free( mod->ml_type );
#ifdef SLAPD_SCHEMA_NOT_COMPAT
free( mod );
#endif
goto done;
}
attr_merge( e, type, vals );
#ifdef SLAPD_SCHEMA_NOT_COMPAT
(*modtail)->ml_next = mod;
modtail = &mod->ml_next;
#else
attr_merge( e, mod->ml_type, mod->ml_bvalues );
free( type );
ber_bvecfree( vals );
free( mod->ml_type );
ber_bvecfree( mod->ml_bvalues );
#endif
}
if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
@ -129,6 +161,17 @@ do_add( Connection *conn, Operation *op )
goto done;
}
#ifdef SLAPD_SCHEMA_NOT_COMPAT
if ( modlist == NULL )
#else
if ( e->e_attrs == NULL )
#endif
{
send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
NULL, "No attributes provided", NULL, NULL );
goto done;
}
Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d ADD dn=\"%s\"\n",
op->o_connid, op->o_opid, e->e_ndn, 0, 0 );
@ -139,8 +182,8 @@ do_add( Connection *conn, Operation *op )
*/
be = select_backend( e->e_ndn );
if ( be == NULL ) {
send_ldap_result( conn, op, rc = LDAP_REFERRAL, NULL,
NULL, default_referral, NULL );
send_ldap_result( conn, op, rc = LDAP_REFERRAL,
NULL, NULL, default_referral, NULL );
goto done;
}
@ -157,7 +200,7 @@ do_add( Connection *conn, Operation *op )
Debug( LDAP_DEBUG_ANY, "do_add: database is read-only\n",
0, 0, 0 );
send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
NULL, "database is read-only", NULL, NULL );
NULL, "database is read-only", NULL, NULL );
goto done;
}
@ -178,21 +221,45 @@ do_add( Connection *conn, Operation *op )
strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
#endif
{
int update = be->be_update_ndn != NULL;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
rc = slap_modlist2mods( modlist, update, &mods, &text );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto done;
}
#endif
#ifndef SLAPD_MULTIMASTER
if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED &&
global_lastmod == ON)) && be->be_update_ndn == NULL )
global_lastmod == ON)) && !update )
#endif
{
#ifdef SLAPD_SCHEMA_NOT_COMPAT
rc = slap_mods_opattrs( op, &mods, &text );
#else
char *text = "no-user-modification attribute type";
rc = add_created_attrs( op, e );
#endif
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, "no-user-modification attribute type",
NULL, text,
NULL, NULL );
goto done;
}
}
#ifdef SLAPD_SCHEMA_NOT_COMPAT
rc = slap_mods2entry( mods, &e, &text );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, text, NULL, NULL );
goto done;
}
#endif
if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
#ifdef SLAPD_MULTIMASTER
if (be->be_update_ndn == NULL ||
@ -218,13 +285,32 @@ do_add( Connection *conn, Operation *op )
}
done:
if( e ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
if( modlist != NULL ) {
slap_modlist_free( modlist );
}
if( mods != NULL ) {
slap_mods_free( mods );
}
#endif
if( e != NULL ) {
entry_free( e );
}
return rc;
}
#ifdef SLAPD_SCHEMA_NOT_COMPAT
static int slap_mods2entry(
Modifications *mods,
Entry **e,
char **text )
{
*text = "Not yet implemented";
return LDAP_NOT_SUPPORTED;
}
#else
static int
add_created_attrs( Operation *op, Entry *e )
{
@ -276,3 +362,4 @@ add_created_attrs( Operation *op, Entry *e )
return LDAP_SUCCESS;
}
#endif

View File

@ -173,7 +173,16 @@ at_fake_if_needed(
#endif
int is_at_subtype(
AttributeType *sub,
AttributeType *sup )
{
for( ; sub != NULL; sub = sub->sat_sup ) {
if( sub == sup ) return 1;
}
return 0;
}
struct aindexrec {
char *air_name;

View File

@ -26,17 +26,10 @@
#include "ldap_pvt.h"
#include "slap.h"
static void modlist_free(LDAPModList *ml);
static void mods_free(Modifications *mods);
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* static */ int modlist2mods(
LDAPModList *ml,
Modifications **mods,
char **text );
#endif
#ifndef SLAPD_SCHEMA_NOT_COMPAT
static int add_modified_attrs( Operation *op, Modifications **modlist );
#endif
int
do_modify(
@ -177,7 +170,6 @@ do_modify(
#endif
Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MOD dn=\"%s\"\n",
op->o_connid, op->o_opid, dn, 0, 0 );
@ -228,9 +220,10 @@ do_modify(
strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
#endif
{
int update = be->be_update_ndn != NULL;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
char *text;
rc = modlist2mods( modlist, &mods, &text );
rc = slap_modlist2mods( modlist, update, &mods, &text );
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
@ -243,13 +236,18 @@ do_modify(
#endif
if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED &&
global_lastmod == ON)) && be->be_update_ndn == NULL )
global_lastmod == ON)) && !update )
{
#ifdef SLAPD_SCHEMA_NOT_COMPAT
rc = slap_mods_opattrs( op, &mods, &text );
#else
char *text = "no-user-modification attribute type";
rc = add_modified_attrs( op, &mods );
#endif
if( rc != LDAP_SUCCESS ) {
send_ldap_result( conn, op, rc,
NULL, "no-user-modification attribute type",
NULL, text,
NULL, NULL );
goto cleanup;
}
@ -282,18 +280,116 @@ cleanup:
free( dn );
free( ndn );
if ( modlist != NULL )
modlist_free( modlist );
slap_modlist_free( modlist );
if ( mods != NULL )
mods_free( mods );
slap_mods_free( mods );
return rc;
}
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/*
* convert a raw list of modifications to internal format
* Do basic attribute type checking and syntax validation.
*/
int slap_modlist2mods(
LDAPModList *ml,
int update,
Modifications **mods,
char **text )
{
int rc;
Modifications **modtail = mods;
for( ; ml != NULL; ml = ml->ml_next ) {
Modifications *mod;
AttributeDescription *ad;
mod = (Modifications *)
ch_calloc( 1, sizeof(Modifications) );
ad = &mod->sml_desc;
/* convert to attribute description */
rc = slap_str2ad( ml->ml_type, &ad, text );
if( rc != LDAP_SUCCESS ) {
slap_mods_free( mod );
return rc;
}
if((ad->ad_type->sat_syntax->ssyn_flags & SLAP_SYNTAX_BINARY)
&& !( ad->ad_flags & SLAP_DESC_BINARY ))
{
/* attribute requires binary transfer */
slap_mods_free( mod );
*text = "attribute requires ;binary transfer";
return LDAP_UNDEFINED_TYPE;
}
if (!update && is_at_no_user_mod( ad->ad_type )) {
/* user modification disallowed */
slap_mods_free( mod );
*text = "no user modification allowed";
return LDAP_CONSTRAINT_VIOLATION;
}
/*
* check values
*/
if( ml->ml_bvalues != NULL ) {
ber_len_t nvals;
slap_syntax_validate_func *validate =
ad->ad_type->sat_syntax->ssyn_validate;
/*
* check that each value is valid per syntax
*/
for( nvals = 0; ml->ml_bvalues[nvals]; nvals++ ) {
rc = validate( ad->ad_type->sat_syntax, ml->ml_bvalues[nvals] );
if( rc != 0 ) {
slap_mods_free( mod );
*text = "value contains invalid data";
return LDAP_INVALID_SYNTAX;
}
}
/*
* a rough single value check... an additional check is needed
* to catch add of single value to existing single valued attribute
*/
if( ( ml->ml_op == LDAP_MOD_ADD || ml->ml_op == LDAP_MOD_REPLACE )
&& nvals > 1 && is_at_single_value( ad->ad_type ))
{
slap_mods_free( mod );
*text = "multiple values provided";
return LDAP_INVALID_SYNTAX;
}
}
mod->sml_bvalues = ml->ml_bvalues;
ml->ml_values = NULL;
*modtail = mod;
modtail = &mod->sml_next;
}
return LDAP_SUCCESS;
}
int slap_mods_opattrs(
Operation *op,
Modifications **modlist,
char **text )
{
/* not yet implemented */
return LDAP_SUCCESS;
}
#else
static int
add_modified_attrs( Operation *op, Modifications **modlist )
{
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
char buf[22];
struct berval bv;
struct berval *bvals[2];
@ -341,13 +437,13 @@ add_modified_attrs( Operation *op, Modifications **modlist )
m->ml_bvalues[0] = ber_bvdup( &bv );
m->ml_next = *modlist;
*modlist = m;
#endif
return LDAP_SUCCESS;
}
#endif
static void
mod_free(
void
slap_mod_free(
Modification *mod,
int freeit
)
@ -367,8 +463,8 @@ mod_free(
free( mod );
}
static void
mods_free(
void
slap_mods_free(
Modifications *ml
)
{
@ -377,13 +473,13 @@ mods_free(
for ( ; ml != NULL; ml = next ) {
next = ml->sml_next;
mod_free( &ml->sml_mod, 0 );
slap_mod_free( &ml->sml_mod, 0 );
free( ml );
}
}
static void
modlist_free(
void
slap_modlist_free(
LDAPModList *ml
)
{

View File

@ -70,6 +70,30 @@ LIBSLAPD_F (slap_access_t) str2access LDAP_P(( const char *str ));
LIBSLAPD_F (char *) accessmask2str LDAP_P(( slap_access_mask_t mask, char* ));
LIBSLAPD_F (slap_access_mask_t) str2accessmask LDAP_P(( const char *str ));
/*
* at.c
*/
LIBSLAPD_F (void) at_config LDAP_P(( const char *fname, int lineno, int argc, char **argv ));
LIBSLAPD_F (AttributeType *) at_find LDAP_P(( const char *name ));
LIBSLAPD_F (int) at_find_in_list LDAP_P(( AttributeType *sat, AttributeType **list ));
LIBSLAPD_F (int) at_append_to_list LDAP_P(( AttributeType *sat, AttributeType ***listp ));
LIBSLAPD_F (int) at_delete_from_list LDAP_P(( int pos, AttributeType ***listp ));
LIBSLAPD_F (int) at_fake_if_needed LDAP_P(( const char *name ));
LIBSLAPD_F (int) at_schema_info LDAP_P(( Entry *e ));
LIBSLAPD_F (int) at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
#ifdef SLAPD_SCHEMA_NOT_COMPAT
LIBSLAPD_F (int) is_at_subtype LDAP_P((
AttributeType *sub,
AttributeType *super ));
# define at_canonical_name(at) ((at)->sat_cname)
#else
LIBSLAPD_F (char *) at_canonical_name LDAP_P(( const char * a_type ));
#endif
/*
* attr.c
*/
@ -92,25 +116,9 @@ LIBSLAPD_F (int) attr_delete LDAP_P(( Attribute **attrs, const char *type ));
LIBSLAPD_F (int) attr_syntax LDAP_P(( const char *type ));
#endif
LIBSLAPD_F (void) at_config LDAP_P(( const char *fname, int lineno, int argc, char **argv ));
LIBSLAPD_F (AttributeType *) at_find LDAP_P(( const char *name ));
LIBSLAPD_F (int) at_find_in_list LDAP_P(( AttributeType *sat, AttributeType **list ));
LIBSLAPD_F (int) at_append_to_list LDAP_P(( AttributeType *sat, AttributeType ***listp ));
LIBSLAPD_F (int) at_delete_from_list LDAP_P(( int pos, AttributeType ***listp ));
LIBSLAPD_F (int) at_fake_if_needed LDAP_P(( const char *name ));
LIBSLAPD_F (int) at_schema_info LDAP_P(( Entry *e ));
LIBSLAPD_F (int) at_add LDAP_P(( LDAP_ATTRIBUTE_TYPE *at, const char **err ));
LIBSLAPD_F (void) attrs_free LDAP_P(( Attribute *a ));
LIBSLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a ));
#ifdef SLAPD_SCHEMA_NOT_COMPAT
# define at_canonical_name(at) ((at)->sat_cname)
#else
LIBSLAPD_F (char *) at_canonical_name LDAP_P(( const char * a_type ));
#endif
/*
* ava.c
@ -358,6 +366,28 @@ LIBSLAPD_F (int) test_filter LDAP_P(( Backend *be, Connection *conn, Operation *
LIBSLAPD_F (FILE *) lock_fopen LDAP_P(( const char *fname, const char *type, FILE **lfp ));
LIBSLAPD_F (int) lock_fclose LDAP_P(( FILE *fp, FILE *lfp ));
/*
* modify.c
* should be relocated to separate file
*/
LIBSLAPD_F( void ) slap_mod_free LDAP_P(( Modification *mod, int freeit ));
LIBSLAPD_F( void ) slap_mods_free LDAP_P(( Modifications *mods ));
LIBSLAPD_F( void ) slap_modlist_free LDAP_P(( LDAPModList *ml ));
#ifdef SLAPD_SCHEMA_NOT_COMPAT
LIBSLAPD_F( int ) slap_modlist2mods(
LDAPModList *ml,
int update,
Modifications **mods,
char **text );
LIBSLAPD_F( int ) slap_mods_opattrs(
Operation *op,
Modifications **modlist,
char **text );
#endif
/*
* module.c
*/

View File

@ -190,6 +190,7 @@ typedef int slap_mr_indexer_func LDAP_P((
struct berval **keys ));
struct slap_filter; /* forward declaration */
/* Filter index function */
typedef int slap_mr_filter_func LDAP_P((
unsigned use,