version 1.103, 2006/01/03 22:12:15
|
version 1.103.2.13, 2011/01/04 23:50:23
|
Line 1
|
Line 1
|
/* schema_check.c - routines to enforce schema definitions */ |
/* schema_check.c - routines to enforce schema definitions */ |
/* $OpenLDAP: pkg/ldap/servers/slapd/schema_check.c,v 1.102 2005/08/01 13:26:13 lukeh Exp $ */ |
/* $OpenLDAP: pkg/ldap/servers/slapd/schema_check.c,v 1.103.2.12 2010/04/13 20:23:19 kurt Exp $ */ |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
/* This work is part of OpenLDAP Software <http://www.openldap.org/>. |
* |
* |
* Copyright 1998-2006 The OpenLDAP Foundation. |
* Copyright 1998-2011 The OpenLDAP Foundation. |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
Line 32 static char * oc_check_required(
|
Line 32 static char * oc_check_required(
|
static int entry_naming_check( |
static int entry_naming_check( |
Entry *e, |
Entry *e, |
int manage, |
int manage, |
|
int add_naming, |
const char** text, |
const char** text, |
char *textbuf, size_t textlen ); |
char *textbuf, size_t textlen ); |
/* |
/* |
Line 47 entry_schema_check(
|
Line 48 entry_schema_check(
|
Entry *e, |
Entry *e, |
Attribute *oldattrs, |
Attribute *oldattrs, |
int manage, |
int manage, |
|
int add, |
|
Attribute **socp, |
const char** text, |
const char** text, |
char *textbuf, size_t textlen ) |
char *textbuf, size_t textlen ) |
{ |
{ |
Attribute *a, *asc, *aoc; |
Attribute *a, *asc = NULL, *aoc = NULL; |
ObjectClass *sc, *oc; |
ObjectClass *sc, *oc, **socs = NULL; |
AttributeType *at; |
AttributeType *at; |
ContentRule *cr; |
ContentRule *cr; |
int rc, i; |
int rc, i; |
struct berval nsc; |
|
AttributeDescription *ad_structuralObjectClass |
AttributeDescription *ad_structuralObjectClass |
= slap_schema.si_ad_structuralObjectClass; |
= slap_schema.si_ad_structuralObjectClass; |
AttributeDescription *ad_objectClass |
AttributeDescription *ad_objectClass |
Line 87 entry_schema_check(
|
Line 89 entry_schema_check(
|
assert( a->a_vals[0].bv_val != NULL ); |
assert( a->a_vals[0].bv_val != NULL ); |
|
|
if( a->a_desc->ad_type->sat_check ) { |
if( a->a_desc->ad_type->sat_check ) { |
int rc = (a->a_desc->ad_type->sat_check)( |
rc = (a->a_desc->ad_type->sat_check)( |
op->o_bd, e, a, text, textbuf, textlen ); |
op->o_bd, e, a, text, textbuf, textlen ); |
if( rc != LDAP_SUCCESS ) { |
if( rc != LDAP_SUCCESS ) { |
return rc; |
return rc; |
} |
} |
} |
} |
|
|
|
if( a->a_desc == ad_structuralObjectClass ) |
|
asc = a; |
|
else if ( a->a_desc == ad_objectClass ) |
|
aoc = a; |
|
|
if( !collectiveSubentry && is_at_collective( a->a_desc->ad_type ) ) { |
if( !collectiveSubentry && is_at_collective( a->a_desc->ad_type ) ) { |
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
"'%s' can only appear in collectiveAttributeSubentry", |
"'%s' can only appear in collectiveAttributeSubentry", |
Line 117 entry_schema_check(
|
Line 124 entry_schema_check(
|
} |
} |
} |
} |
|
|
/* find the structural object class attribute */ |
/* check the object class attribute */ |
asc = attr_find( e->e_attrs, ad_structuralObjectClass ); |
if ( aoc == NULL ) { |
if ( asc == NULL ) { |
Debug( LDAP_DEBUG_ANY, "No objectClass for entry (%s)\n", |
|
e->e_dn, 0, 0 ); |
|
|
|
*text = "no objectClass attribute"; |
|
return LDAP_OBJECT_CLASS_VIOLATION; |
|
} |
|
|
|
assert( aoc->a_vals != NULL ); |
|
assert( aoc->a_vals[0].bv_val != NULL ); |
|
|
|
/* check the structural object class attribute */ |
|
if ( asc == NULL && !add ) { |
Debug( LDAP_DEBUG_ANY, |
Debug( LDAP_DEBUG_ANY, |
"No structuralObjectClass for entry (%s)\n", |
"No structuralObjectClass for entry (%s)\n", |
e->e_dn, 0, 0 ); |
e->e_dn, 0, 0 ); |
Line 128 entry_schema_check(
|
Line 146 entry_schema_check(
|
return LDAP_OTHER; |
return LDAP_OTHER; |
} |
} |
|
|
|
rc = structural_class( aoc->a_vals, &oc, &socs, text, textbuf, textlen, |
|
op->o_tmpmemctx ); |
|
if( rc != LDAP_SUCCESS ) { |
|
return rc; |
|
} |
|
|
|
if ( asc == NULL && add ) { |
|
attr_merge_one( e, ad_structuralObjectClass, &oc->soc_cname, NULL ); |
|
asc = attr_find( e->e_attrs, ad_structuralObjectClass ); |
|
sc = oc; |
|
goto got_soc; |
|
} |
|
|
assert( asc->a_vals != NULL ); |
assert( asc->a_vals != NULL ); |
assert( asc->a_vals[0].bv_val != NULL ); |
assert( asc->a_vals[0].bv_val != NULL ); |
assert( asc->a_vals[1].bv_val == NULL ); |
assert( asc->a_vals[1].bv_val == NULL ); |
Line 142 entry_schema_check(
|
Line 173 entry_schema_check(
|
"entry_check_schema(%s): %s\n", |
"entry_check_schema(%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
|
|
if( sc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) { |
if( sc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) { |
Line 154 entry_schema_check(
|
Line 186 entry_schema_check(
|
"entry_check_schema(%s): %s\n", |
"entry_check_schema(%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OTHER; |
rc = LDAP_OTHER; |
|
goto done; |
} |
} |
|
|
|
got_soc: |
if( !manage && sc->soc_obsolete ) { |
if( !manage && sc->soc_obsolete ) { |
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
"structuralObjectClass '%s' is OBSOLETE", |
"structuralObjectClass '%s' is OBSOLETE", |
Line 166 entry_schema_check(
|
Line 200 entry_schema_check(
|
"entry_check_schema(%s): %s\n", |
"entry_check_schema(%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
} |
goto done; |
|
|
/* find the object class attribute */ |
|
aoc = attr_find( e->e_attrs, ad_objectClass ); |
|
if ( aoc == NULL ) { |
|
Debug( LDAP_DEBUG_ANY, "No objectClass for entry (%s)\n", |
|
e->e_dn, 0, 0 ); |
|
|
|
*text = "no objectClass attribute"; |
|
return LDAP_OBJECT_CLASS_VIOLATION; |
|
} |
|
|
|
assert( aoc->a_vals != NULL ); |
|
assert( aoc->a_vals[0].bv_val != NULL ); |
|
|
|
rc = structural_class( aoc->a_vals, &nsc, &oc, text, textbuf, textlen ); |
|
if( rc != LDAP_SUCCESS ) { |
|
return rc; |
|
} |
} |
|
|
*text = textbuf; |
*text = textbuf; |
Line 193 entry_schema_check(
|
Line 210 entry_schema_check(
|
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
"unrecognized objectClass '%s'", |
"unrecognized objectClass '%s'", |
aoc->a_vals[0].bv_val ); |
aoc->a_vals[0].bv_val ); |
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
|
|
} else if ( sc != slap_schema.si_oc_glue && sc != oc ) { |
} else if ( sc != oc ) { |
snprintf( textbuf, textlen, |
if ( !manage && sc != slap_schema.si_oc_glue ) { |
"structural object class modification " |
snprintf( textbuf, textlen, |
"from '%s' to '%s' not allowed", |
"structural object class modification " |
asc->a_vals[0].bv_val, nsc.bv_val ); |
"from '%s' to '%s' not allowed", |
return LDAP_NO_OBJECT_CLASS_MODS; |
asc->a_vals[0].bv_val, oc->soc_cname.bv_val ); |
} else if ( sc == slap_schema.si_oc_glue ) { |
rc = LDAP_NO_OBJECT_CLASS_MODS; |
|
goto done; |
|
} |
|
|
|
assert( asc->a_vals != NULL ); |
|
assert( !BER_BVISNULL( &asc->a_vals[0] ) ); |
|
assert( BER_BVISNULL( &asc->a_vals[1] ) ); |
|
assert( asc->a_nvals == asc->a_vals ); |
|
|
|
/* draft-zeilenga-ldap-relax: automatically modify |
|
* structuralObjectClass if changed with relax */ |
sc = oc; |
sc = oc; |
|
ber_bvreplace( &asc->a_vals[ 0 ], &sc->soc_cname ); |
|
if ( socp ) { |
|
*socp = asc; |
|
} |
} |
} |
|
|
/* naming check */ |
/* naming check */ |
if ( !is_entry_objectclass ( e, slap_schema.si_oc_glue, 0 ) ) { |
if ( !is_entry_glue ( e ) ) { |
rc = entry_naming_check( e, manage, text, textbuf, textlen ); |
rc = entry_naming_check( e, manage, add, text, textbuf, textlen ); |
if( rc != LDAP_SUCCESS ) { |
if( rc != LDAP_SUCCESS ) { |
return rc; |
goto done; |
} |
} |
} else { |
} else { |
/* Glue Entry */ |
/* Glue Entry */ |
Line 232 entry_schema_check(
|
Line 264 entry_schema_check(
|
"Entry (%s): %s\n", |
"Entry (%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
|
|
if( cr->scr_required ) for( i=0; cr->scr_required[i]; i++ ) { |
if( cr->scr_required ) for( i=0; cr->scr_required[i]; i++ ) { |
Line 255 entry_schema_check(
|
Line 288 entry_schema_check(
|
"Entry (%s): %s\n", |
"Entry (%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
} |
} |
|
|
Line 279 entry_schema_check(
|
Line 313 entry_schema_check(
|
"Entry (%s): %s\n", |
"Entry (%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
} |
} |
} |
} |
|
|
/* check that the entry has required attrs for each oc */ |
/* check that the entry has required attrs for each oc */ |
for ( i = 0; aoc->a_vals[i].bv_val != NULL; i++ ) { |
for ( i = 0; socs[i]; i++ ) { |
if ( (oc = oc_bvfind( &aoc->a_vals[i] )) == NULL ) { |
oc = socs[i]; |
snprintf( textbuf, textlen, |
|
"unrecognized objectClass '%s'", |
|
aoc->a_vals[i].bv_val ); |
|
|
|
Debug( LDAP_DEBUG_ANY, |
|
"entry_check_schema(%s): %s\n", |
|
e->e_dn, textbuf, 0 ); |
|
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
|
} |
|
|
|
if ( !manage && oc->soc_obsolete ) { |
if ( !manage && oc->soc_obsolete ) { |
/* disallow obsolete classes */ |
/* disallow obsolete classes */ |
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
Line 308 entry_schema_check(
|
Line 332 entry_schema_check(
|
"entry_check_schema(%s): %s\n", |
"entry_check_schema(%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
|
|
if ( oc->soc_check ) { |
if ( oc->soc_check ) { |
int rc = (oc->soc_check)( op->o_bd, e, oc, |
rc = (oc->soc_check)( op->o_bd, e, oc, |
text, textbuf, textlen ); |
text, textbuf, textlen ); |
if( rc != LDAP_SUCCESS ) { |
if( rc != LDAP_SUCCESS ) { |
return rc; |
goto done; |
} |
} |
} |
} |
|
|
Line 326 entry_schema_check(
|
Line 351 entry_schema_check(
|
{ |
{ |
int j; |
int j; |
ObjectClass *xc = NULL; |
ObjectClass *xc = NULL; |
for( j=0; aoc->a_vals[j].bv_val; j++ ) { |
for( j=0; socs[j]; j++ ) { |
if( i != j ) { |
if( i != j ) { |
xc = oc_bvfind( &aoc->a_vals[i] ); |
xc = socs[j]; |
if( xc == NULL ) { |
|
snprintf( textbuf, textlen, |
|
"unrecognized objectClass '%s'", |
|
aoc->a_vals[i].bv_val ); |
|
|
|
Debug( LDAP_DEBUG_ANY, |
|
"entry_check_schema(%s): %s\n", |
|
e->e_dn, textbuf, 0 ); |
|
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
|
} |
|
|
|
/* since we previous check against the |
/* since we previous check against the |
* structural object of this entry, the |
* structural object of this entry, the |
Line 356 entry_schema_check(
|
Line 370 entry_schema_check(
|
} |
} |
} |
} |
|
|
if( xc == NULL ) { |
if( xc != NULL ) { |
snprintf( textbuf, textlen, "instanstantiation of " |
snprintf( textbuf, textlen, "instantiation of " |
"abstract objectClass '%s' not allowed", |
"abstract objectClass '%s' not allowed", |
aoc->a_vals[i].bv_val ); |
aoc->a_vals[i].bv_val ); |
|
|
Line 365 entry_schema_check(
|
Line 379 entry_schema_check(
|
"entry_check_schema(%s): %s\n", |
"entry_check_schema(%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
} |
} |
|
|
Line 387 entry_schema_check(
|
Line 402 entry_schema_check(
|
} |
} |
} |
} |
} |
} |
|
if ( k ) { |
|
snprintf( textbuf, textlen, |
|
"class '%s' not allowed by content rule '%s'", |
|
oc->soc_cname.bv_val, |
|
ldap_contentrule2name( &cr->scr_crule ) ); |
|
} |
} else if ( global_disallows & SLAP_DISALLOW_AUX_WO_CR ) { |
} else if ( global_disallows & SLAP_DISALLOW_AUX_WO_CR ) { |
k = -1; |
k = -1; |
|
snprintf( textbuf, textlen, |
|
"class '%s' not allowed by any content rule", |
|
oc->soc_cname.bv_val ); |
} else { |
} else { |
k = 0; |
k = 0; |
} |
} |
|
|
if( k == -1 ) { |
if( k == -1 ) { |
snprintf( textbuf, textlen, |
|
"content rule '%s' does not allow class '%s'", |
|
ldap_contentrule2name( &cr->scr_crule ), |
|
oc->soc_cname.bv_val ); |
|
|
|
Debug( LDAP_DEBUG_ANY, |
Debug( LDAP_DEBUG_ANY, |
"Entry (%s): %s\n", |
"Entry (%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
} |
} |
|
|
Line 417 entry_schema_check(
|
Line 437 entry_schema_check(
|
"Entry (%s): %s\n", |
"Entry (%s): %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return LDAP_OBJECT_CLASS_VIOLATION; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
goto done; |
} |
} |
|
|
if( oc == slap_schema.si_oc_extensibleObject ) { |
if( oc == slap_schema.si_oc_extensibleObject ) { |
Line 428 entry_schema_check(
|
Line 449 entry_schema_check(
|
|
|
if( extensible ) { |
if( extensible ) { |
*text = NULL; |
*text = NULL; |
return LDAP_SUCCESS; |
rc = LDAP_SUCCESS; |
|
goto done; |
} |
} |
|
|
/* check that each attr in the entry is allowed by some oc */ |
/* check that each attr in the entry is allowed by some oc */ |
for ( a = e->e_attrs; a != NULL; a = a->a_next ) { |
for ( a = e->e_attrs; a != NULL; a = a->a_next ) { |
int ret; |
rc = LDAP_OBJECT_CLASS_VIOLATION; |
|
|
ret = LDAP_OBJECT_CLASS_VIOLATION; |
|
|
|
if( cr && cr->scr_required ) { |
if( cr && cr->scr_required ) { |
for( i=0; cr->scr_required[i]; i++ ) { |
for( i=0; cr->scr_required[i]; i++ ) { |
if( cr->scr_required[i] == a->a_desc->ad_type ) { |
if( cr->scr_required[i] == a->a_desc->ad_type ) { |
ret = LDAP_SUCCESS; |
rc = LDAP_SUCCESS; |
break; |
break; |
} |
} |
} |
} |
} |
} |
|
|
if( ret != LDAP_SUCCESS && cr && cr->scr_allowed ) { |
if( rc != LDAP_SUCCESS && cr && cr->scr_allowed ) { |
for( i=0; cr->scr_allowed[i]; i++ ) { |
for( i=0; cr->scr_allowed[i]; i++ ) { |
if( cr->scr_allowed[i] == a->a_desc->ad_type ) { |
if( cr->scr_allowed[i] == a->a_desc->ad_type ) { |
ret = LDAP_SUCCESS; |
rc = LDAP_SUCCESS; |
break; |
break; |
} |
} |
} |
} |
} |
} |
|
|
if( ret != LDAP_SUCCESS ) |
if( rc != LDAP_SUCCESS ) |
{ |
{ |
ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc ); |
rc = oc_check_allowed( a->a_desc->ad_type, socs, sc ); |
} |
} |
|
|
if ( ret != LDAP_SUCCESS ) { |
if ( rc != LDAP_SUCCESS ) { |
char *type = a->a_desc->ad_cname.bv_val; |
char *type = a->a_desc->ad_cname.bv_val; |
|
|
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
Line 471 entry_schema_check(
|
Line 491 entry_schema_check(
|
"Entry (%s), %s\n", |
"Entry (%s), %s\n", |
e->e_dn, textbuf, 0 ); |
e->e_dn, textbuf, 0 ); |
|
|
return ret; |
goto done; |
} |
} |
} |
} |
|
|
*text = NULL; |
*text = NULL; |
return LDAP_SUCCESS; |
done: |
|
slap_sl_free( socs, op->o_tmpmemctx ); |
|
return rc; |
} |
} |
|
|
static char * |
static char * |
Line 519 oc_check_required(
|
Line 541 oc_check_required(
|
|
|
int oc_check_allowed( |
int oc_check_allowed( |
AttributeType *at, |
AttributeType *at, |
BerVarray ocl, |
ObjectClass **socs, |
ObjectClass *sc ) |
ObjectClass *sc ) |
{ |
{ |
int i, j; |
int i, j; |
Line 562 int oc_check_allowed(
|
Line 584 int oc_check_allowed(
|
} |
} |
|
|
/* check that the type appears as req or opt in at least one oc */ |
/* check that the type appears as req or opt in at least one oc */ |
for ( i = 0; ocl[i].bv_val != NULL; i++ ) { |
for ( i = 0; socs[i]; i++ ) { |
/* if we know about the oc */ |
/* if we know about the oc */ |
ObjectClass *oc = oc_bvfind( &ocl[i] ); |
ObjectClass *oc = socs[i]; |
|
/* extensibleObject allows all */ |
|
if ( oc == slap_schema.si_oc_extensibleObject ) { |
|
return LDAP_SUCCESS; |
|
} |
if ( oc != NULL && oc->soc_kind != LDAP_SCHEMA_ABSTRACT && |
if ( oc != NULL && oc->soc_kind != LDAP_SCHEMA_ABSTRACT && |
( sc == NULL || oc->soc_kind == LDAP_SCHEMA_AUXILIARY )) |
( sc == NULL || oc->soc_kind == LDAP_SCHEMA_AUXILIARY )) |
{ |
{ |
Line 596 int oc_check_allowed(
|
Line 622 int oc_check_allowed(
|
*/ |
*/ |
int structural_class( |
int structural_class( |
BerVarray ocs, |
BerVarray ocs, |
struct berval *scbv, |
|
ObjectClass **scp, |
ObjectClass **scp, |
|
ObjectClass ***socsp, |
const char **text, |
const char **text, |
char *textbuf, size_t textlen ) |
char *textbuf, size_t textlen, |
|
void *ctx ) |
{ |
{ |
int i; |
int i, nocs; |
ObjectClass *oc; |
ObjectClass *oc, **socs; |
ObjectClass *sc = NULL; |
ObjectClass *sc = NULL; |
int scn = -1; |
int scn = -1; |
|
|
*text = "structural_class: internal error"; |
*text = "structural_class: internal error"; |
scbv->bv_len = 0; |
|
|
/* count them */ |
|
for( i=0; ocs[i].bv_val; i++ ) ; |
|
nocs = i; |
|
|
|
socs = slap_sl_malloc( (nocs+1) * sizeof(ObjectClass *), ctx ); |
|
|
for( i=0; ocs[i].bv_val; i++ ) { |
for( i=0; ocs[i].bv_val; i++ ) { |
oc = oc_bvfind( &ocs[i] ); |
socs[i] = oc_bvfind( &ocs[i] ); |
|
|
if( oc == NULL ) { |
if( socs[i] == NULL ) { |
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
"unrecognized objectClass '%s'", |
"unrecognized objectClass '%s'", |
ocs[i].bv_val ); |
ocs[i].bv_val ); |
*text = textbuf; |
*text = textbuf; |
return LDAP_OBJECT_CLASS_VIOLATION; |
goto fail; |
} |
} |
|
} |
|
socs[i] = NULL; |
|
|
|
for( i=0; ocs[i].bv_val; i++ ) { |
|
oc = socs[i]; |
if( oc->soc_kind == LDAP_SCHEMA_STRUCTURAL ) { |
if( oc->soc_kind == LDAP_SCHEMA_STRUCTURAL ) { |
if( sc == NULL || is_object_subclass( sc, oc ) ) { |
if( sc == NULL || is_object_subclass( sc, oc ) ) { |
sc = oc; |
sc = oc; |
Line 631 int structural_class(
|
Line 667 int structural_class(
|
|
|
/* find common superior */ |
/* find common superior */ |
for( j=i+1; ocs[j].bv_val; j++ ) { |
for( j=i+1; ocs[j].bv_val; j++ ) { |
xc = oc_bvfind( &ocs[j] ); |
xc = socs[j]; |
|
|
if( xc == NULL ) { |
if( xc == NULL ) { |
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
"unrecognized objectClass '%s'", |
"unrecognized objectClass '%s'", |
ocs[j].bv_val ); |
ocs[j].bv_val ); |
*text = textbuf; |
*text = textbuf; |
return LDAP_OBJECT_CLASS_VIOLATION; |
goto fail; |
} |
} |
|
|
if( xc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) { |
if( xc->soc_kind != LDAP_SCHEMA_STRUCTURAL ) { |
Line 662 int structural_class(
|
Line 698 int structural_class(
|
"invalid structural object class chain (%s/%s)", |
"invalid structural object class chain (%s/%s)", |
ocs[scn].bv_val, ocs[i].bv_val ); |
ocs[scn].bv_val, ocs[i].bv_val ); |
*text = textbuf; |
*text = textbuf; |
return LDAP_OBJECT_CLASS_VIOLATION; |
goto fail; |
} |
} |
} |
} |
} |
} |
Line 674 int structural_class(
|
Line 710 int structural_class(
|
|
|
if( sc == NULL ) { |
if( sc == NULL ) { |
*text = "no structural object class provided"; |
*text = "no structural object class provided"; |
return LDAP_OBJECT_CLASS_VIOLATION; |
goto fail; |
} |
} |
|
|
if( scn < 0 ) { |
if( scn < 0 ) { |
*text = "invalid structural object class"; |
*text = "invalid structural object class"; |
return LDAP_OBJECT_CLASS_VIOLATION; |
goto fail; |
} |
} |
|
|
*scbv = ocs[scn]; |
if ( socsp ) { |
|
*socsp = socs; |
if( scbv->bv_len == 0 ) { |
} else { |
*text = "invalid structural object class"; |
slap_sl_free( socs, ctx ); |
return LDAP_OBJECT_CLASS_VIOLATION; |
|
} |
} |
|
|
*text = NULL; |
*text = NULL; |
|
|
return LDAP_SUCCESS; |
return LDAP_SUCCESS; |
|
|
|
fail: |
|
slap_sl_free( socs, ctx ); |
|
return LDAP_OBJECT_CLASS_VIOLATION; |
} |
} |
|
|
/* |
/* |
Line 701 int mods_structural_class(
|
Line 739 int mods_structural_class(
|
Modifications *mods, |
Modifications *mods, |
struct berval *sc, |
struct berval *sc, |
const char **text, |
const char **text, |
char *textbuf, size_t textlen ) |
char *textbuf, size_t textlen, void *ctx ) |
{ |
{ |
Modifications *ocmod = NULL; |
Modifications *ocmod = NULL; |
|
ObjectClass *ssc; |
|
int rc; |
|
|
for( ; mods != NULL; mods = mods->sml_next ) { |
for( ; mods != NULL; mods = mods->sml_next ) { |
if( mods->sml_desc == slap_schema.si_ad_objectClass ) { |
if( mods->sml_desc == slap_schema.si_ad_objectClass ) { |
Line 725 int mods_structural_class(
|
Line 765 int mods_structural_class(
|
return LDAP_OBJECT_CLASS_VIOLATION; |
return LDAP_OBJECT_CLASS_VIOLATION; |
} |
} |
|
|
return structural_class( ocmod->sml_values, sc, NULL, |
rc = structural_class( ocmod->sml_values, &ssc, NULL, |
text, textbuf, textlen ); |
text, textbuf, textlen, ctx ); |
|
if ( rc == LDAP_SUCCESS ) |
|
*sc = ssc->soc_cname; |
|
return rc; |
} |
} |
|
|
|
|
Line 734 static int
|
Line 777 static int
|
entry_naming_check( |
entry_naming_check( |
Entry *e, |
Entry *e, |
int manage, |
int manage, |
|
int add_naming, |
const char** text, |
const char** text, |
char *textbuf, size_t textlen ) |
char *textbuf, size_t textlen ) |
{ |
{ |
Line 753 entry_naming_check(
|
Line 797 entry_naming_check(
|
if ( ldap_bv2rdn( &e->e_name, &rdn, (char **)&p, |
if ( ldap_bv2rdn( &e->e_name, &rdn, (char **)&p, |
LDAP_DN_FORMAT_LDAP ) ) |
LDAP_DN_FORMAT_LDAP ) ) |
{ |
{ |
*text = "unrecongized attribute type(s) in RDN"; |
*text = "unrecognized attribute type(s) in RDN"; |
return LDAP_INVALID_DN_SYNTAX; |
return LDAP_INVALID_DN_SYNTAX; |
} |
} |
|
|
Line 764 entry_naming_check(
|
Line 808 entry_naming_check(
|
AttributeDescription *desc = NULL; |
AttributeDescription *desc = NULL; |
Attribute *attr; |
Attribute *attr; |
const char *errtext; |
const char *errtext; |
|
int add = 0; |
|
|
if( ava->la_flags & LDAP_AVA_BINARY ) { |
if( ava->la_flags & LDAP_AVA_BINARY ) { |
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
Line 824 entry_naming_check(
|
Line 869 entry_naming_check(
|
snprintf( textbuf, textlen, |
snprintf( textbuf, textlen, |
"naming attribute '%s' is not present in entry", |
"naming attribute '%s' is not present in entry", |
ava->la_attr.bv_val ); |
ava->la_attr.bv_val ); |
rc = LDAP_NAMING_VIOLATION; |
if ( add_naming ) { |
break; |
add = 1; |
} |
|
|
|
rc = value_find_ex( desc, SLAP_MR_VALUE_OF_ASSERTION_SYNTAX| |
} else { |
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, |
rc = LDAP_NAMING_VIOLATION; |
attr->a_nvals, &ava->la_value, NULL ); |
|
|
|
if( rc != 0 ) { |
|
switch( rc ) { |
|
case LDAP_INAPPROPRIATE_MATCHING: |
|
snprintf( textbuf, textlen, |
|
"inappropriate matching for naming attribute '%s'", |
|
ava->la_attr.bv_val ); |
|
break; |
|
case LDAP_INVALID_SYNTAX: |
|
snprintf( textbuf, textlen, |
|
"value of naming attribute '%s' is invalid", |
|
ava->la_attr.bv_val ); |
|
break; |
|
case LDAP_NO_SUCH_ATTRIBUTE: |
|
snprintf( textbuf, textlen, |
|
"value of naming attribute '%s' is not present in entry", |
|
ava->la_attr.bv_val ); |
|
break; |
|
default: |
|
snprintf( textbuf, textlen, |
|
"naming attribute '%s' is inappropriate", |
|
ava->la_attr.bv_val ); |
|
} |
} |
rc = LDAP_NAMING_VIOLATION; |
|
|
} else { |
|
rc = attr_valfind( attr, SLAP_MR_VALUE_OF_ASSERTION_SYNTAX| |
|
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, |
|
&ava->la_value, NULL, NULL ); |
|
|
|
if ( rc != 0 ) { |
|
switch( rc ) { |
|
case LDAP_INAPPROPRIATE_MATCHING: |
|
snprintf( textbuf, textlen, |
|
"inappropriate matching for naming attribute '%s'", |
|
ava->la_attr.bv_val ); |
|
break; |
|
case LDAP_INVALID_SYNTAX: |
|
snprintf( textbuf, textlen, |
|
"value of naming attribute '%s' is invalid", |
|
ava->la_attr.bv_val ); |
|
break; |
|
case LDAP_NO_SUCH_ATTRIBUTE: |
|
if ( add_naming ) { |
|
if ( is_at_single_value( desc->ad_type ) ) { |
|
snprintf( textbuf, textlen, |
|
"value of single-valued naming attribute '%s' conflicts with value present in entry", |
|
ava->la_attr.bv_val ); |
|
|
|
} else { |
|
add = 1; |
|
rc = LDAP_SUCCESS; |
|
} |
|
|
|
} else { |
|
snprintf( textbuf, textlen, |
|
"value of naming attribute '%s' is not present in entry", |
|
ava->la_attr.bv_val ); |
|
} |
|
break; |
|
default: |
|
snprintf( textbuf, textlen, |
|
"naming attribute '%s' is inappropriate", |
|
ava->la_attr.bv_val ); |
|
} |
|
|
|
if ( !add ) { |
|
rc = LDAP_NAMING_VIOLATION; |
|
} |
|
} |
|
} |
|
|
|
if ( add ) { |
|
attr_merge_normalize_one( e, desc, &ava->la_value, NULL ); |
|
|
|
} else if ( rc != LDAP_SUCCESS ) { |
break; |
break; |
} |
} |
} |
} |