Another round of SLAPD_SCHEMA_NOT_COMPAT changes including

basic structures for handing language tags and binary option
(but less actual code to actually support them).  Provided
for reference only.  Will not even compile.
This commit is contained in:
Kurt Zeilenga 2000-02-05 05:01:41 +00:00
parent 86cedc6ac7
commit f9195f9b6f
22 changed files with 1913 additions and 1655 deletions

View File

@ -15,7 +15,8 @@ SRCS = main.c daemon.c connection.c search.c filter.c add.c charray.c \
value.c ava.c bind.c unbind.c abandon.c filterentry.c \
phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
repl.c lock.c controls.c extended.c kerberos.c passwd.c \
schema.c schema_init.c schemaparse.c \
schema.c schema_check.c schema_init.c schemaparse.c \
at.c mr.c syntax.c oc.c \
monitor.c configinfo.c starttls.c \
root_dse.c sasl.c module.c suffixalias.c $(@PLAT@_SRCS)
@ -25,7 +26,8 @@ OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
value.o ava.o bind.o unbind.o abandon.o filterentry.o \
phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
repl.o lock.o controls.o extended.o kerberos.o passwd.o \
schema.o schema_init.o schemaparse.o \
schema.o schema_check.o schema_init.o schemaparse.o \
at.o mr.o syntax.o oc.o \
monitor.o configinfo.o starttls.o \
root_dse.o sasl.o module.o suffixalias.o $(@PLAT@_OBJS)

View File

@ -244,7 +244,12 @@ add_created_attrs( Operation *op, Entry *e )
/* return error on any attempts by the user to add these attrs */
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
if ( oc_check_op_no_usermod_attr( a->a_type ) ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
if ( is_at_no_user_mod( a->a_desc.ad_type ))
#else
if ( oc_check_op_no_usermod_attr( a->a_type ) )
#endif
{
return LDAP_CONSTRAINT_VIOLATION;
}
}

563
servers/slapd/at.c Normal file
View File

@ -0,0 +1,563 @@
/* $OpenLDAP$ */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* at.c - routines for dealing with attributes */
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/errno.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
#include "ldap_pvt.h"
#include "slap.h"
#ifndef SLAPD_SCHEMA_NOT_COMPAT
char *
at_canonical_name( const char * a_type )
{
AttributeType *atp;
atp=at_find(a_type);
if ( atp == NULL ) {
return (char *) a_type;
} else if ( atp->sat_names
&& atp->sat_names[0] && (*(atp->sat_names[0]) != '\0') )
{
return atp->sat_names[0];
} else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
return atp->sat_oid;
}
return (char *) a_type;
}
#define DEFAULT_SYNTAX SYNTAX_CIS
/*
* attr_syntax - return the syntax of attribute type
*/
int
attr_syntax( const char *type )
{
AttributeType *sat;
sat = at_find(type);
if ( sat ) {
return( sat->sat_syntax_compat );
}
return( DEFAULT_SYNTAX );
}
/*
* attr_syntax_config - process an attribute syntax config line
*/
void
attr_syntax_config(
const char *fname,
int lineno,
int argc,
char **argv
)
{
char *save;
LDAP_ATTRIBUTE_TYPE *at;
int lasti;
int code;
const char *err;
if ( argc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
fname, lineno, 0 );
return;
}
at = (LDAP_ATTRIBUTE_TYPE *)
ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
#define SYNTAX_DS_OID "1.3.6.1.4.1.1466.115.121.1.15"
#define SYNTAX_DSCE_OID "2.5.13.5"
#define SYNTAX_IA5_OID "1.3.6.1.4.1.1466.115.121.1.26"
#define SYNTAX_IA5CE_OID "1.3.6.1.4.1.1466.109.114.1"
#define SYNTAX_DN_OID SLAPD_OID_DN_SYNTAX
#define SYNTAX_TEL_OID "1.3.6.1.4.1.1466.115.121.1.50"
#define SYNTAX_BIN_OID "1.3.6.1.4.1.1466.115.121.1.40" /* octetString */
lasti = argc - 1;
if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
strcasecmp( argv[lasti], "cis" ) == 0 ) {
at->at_syntax_oid = SYNTAX_DS_OID;
at->at_equality_oid = "2.5.13.2";
at->at_ordering_oid = "2.5.13.3";
at->at_substr_oid = "2.5.13.4";
} else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
strcasecmp( argv[lasti], "tel" ) == 0 ) {
at->at_syntax_oid = SYNTAX_TEL_OID;
at->at_equality_oid = "2.5.13.20";
at->at_substr_oid = "2.5.13.21";
} else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
at->at_syntax_oid = SYNTAX_DN_OID;
at->at_equality_oid = "2.5.13.1";
} else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
strcasecmp( argv[lasti], "ces" ) == 0 ) {
at->at_syntax_oid = SYNTAX_DS_OID;
at->at_equality_oid = SYNTAX_DSCE_OID;
at->at_ordering_oid = "2.5.13.6";
at->at_substr_oid = "2.5.13.7";
} else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
strcasecmp( argv[lasti], "bin" ) == 0 ) {
/* bin -> octetString, not binary! */
at->at_syntax_oid = SYNTAX_BIN_OID;
at->at_equality_oid = "2.5.13.17";
} else {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
fname, lineno, argv[lasti] );
Debug( LDAP_DEBUG_ANY,
"possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
0, 0, 0 );
free( (AttributeType *) at );
return;
}
save = argv[lasti];
argv[lasti] = NULL;
at->at_names = charray_dup( argv );
argv[lasti] = save;
code = at_add( at, &err );
if ( code ) {
fprintf( stderr, "%s: line %d: %s %s\n",
fname, lineno, scherr2str(code), err);
exit( EXIT_FAILURE );
}
ldap_memfree(at);
}
int
at_fake_if_needed(
const char *name
)
{
char *argv[3];
if ( at_find( name ) ) {
return 0;
} else {
argv[0] = (char*) name;
argv[1] = "cis";
argv[2] = NULL;
attr_syntax_config( "implicit", 0, 2, argv );
return 0;
}
}
#endif
struct aindexrec {
char *air_name;
AttributeType *air_at;
};
static Avlnode *attr_index = NULL;
static AttributeType *attr_list = NULL;
static int
attr_index_cmp(
struct aindexrec *air1,
struct aindexrec *air2
)
{
return (strcasecmp( air1->air_name, air2->air_name ));
}
static int
attr_index_name_cmp(
char *type,
struct aindexrec *air
)
{
return (strcasecmp( type, air->air_name ));
}
AttributeType *
at_find(
const char *name
)
{
struct aindexrec *air;
char *tmpname;
#ifndef SLAPD_SCHEMA_NOT_COMPAT
/*
* The name may actually be an AttributeDescription, i.e. it may
* contain options.
*/
/* Treat any attribute type with option as an unknown attribute type */
char *p = strchr( name, ';' );
if ( p ) {
tmpname = ch_malloc( p-name+1 );
strncpy( tmpname, name, p-name );
tmpname[p-name] = '\0';
} else
#endif
{
tmpname = (char *)name;
}
if ( (air = (struct aindexrec *) avl_find( attr_index, tmpname,
(AVL_CMP) attr_index_name_cmp )) != NULL ) {
if ( tmpname != name )
ldap_memfree( tmpname );
return( air->air_at );
}
if ( tmpname != name )
ldap_memfree( tmpname );
return( NULL );
}
int
at_append_to_list(
AttributeType *sat,
AttributeType ***listp
)
{
AttributeType **list;
AttributeType **list1;
int size;
list = *listp;
if ( !list ) {
size = 2;
list = calloc(size, sizeof(AttributeType *));
if ( !list ) {
return -1;
}
} else {
size = 0;
list1 = *listp;
while ( *list1 ) {
size++;
list1++;
}
size += 2;
list1 = realloc(list, size*sizeof(AttributeType *));
if ( !list1 ) {
return -1;
}
list = list1;
}
list[size-2] = sat;
list[size-1] = NULL;
*listp = list;
return 0;
}
int
at_delete_from_list(
int pos,
AttributeType ***listp
)
{
AttributeType **list;
AttributeType **list1;
int i;
int j;
if ( pos < 0 ) {
return -2;
}
list = *listp;
for ( i=0; list[i]; i++ )
;
if ( pos >= i ) {
return -2;
}
for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
list[i] = list[j];
}
list[i] = NULL;
/* Tell the runtime this can be shrinked */
list1 = realloc(list, (i+1)*sizeof(AttributeType **));
if ( !list1 ) {
return -1;
}
*listp = list1;
return 0;
}
int
at_find_in_list(
AttributeType *sat,
AttributeType **list
)
{
int i;
if ( !list ) {
return -1;
}
for ( i=0; list[i]; i++ ) {
if ( sat == list[i] ) {
return i;
}
}
return -1;
}
static int
at_insert(
AttributeType *sat,
const char **err
)
{
AttributeType **atp;
struct aindexrec *air;
char **names;
atp = &attr_list;
while ( *atp != NULL ) {
atp = &(*atp)->sat_next;
}
*atp = sat;
if ( sat->sat_oid ) {
air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name = sat->sat_oid;
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
(AVL_CMP) attr_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = sat->sat_oid;
ldap_memfree(air);
return SLAP_SCHERR_DUP_ATTR;
}
/* FIX: temporal consistency check */
at_find(air->air_name);
}
if ( (names = sat->sat_names) ) {
while ( *names ) {
air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name = ch_strdup(*names);
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
(AVL_CMP) attr_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = *names;
ldap_memfree(air->air_name);
ldap_memfree(air);
return SLAP_SCHERR_DUP_ATTR;
}
/* FIX: temporal consistency check */
at_find(air->air_name);
names++;
}
}
return 0;
}
int
at_add(
LDAP_ATTRIBUTE_TYPE *at,
const char **err
)
{
AttributeType *sat;
MatchingRule *mr;
Syntax *syn;
int code;
char *cname;
if ( at->at_names && at->at_names[0] ) {
cname = at->at_names[0];
} else if ( at->at_oid ) {
cname = at->at_oid;
} else {
cname = "";
return SLAP_SCHERR_ATTR_INCOMPLETE;
}
sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
#ifdef SLAPD_SCHEMA_NOT_COMPAT
sat->sat_cname = cname;
#endif
if ( at->at_sup_oid ) {
AttributeType *supsat = at_find(at->at_sup_oid);
if ( (supsat == NULL ) ) {
*err = at->at_sup_oid;
return SLAP_SCHERR_ATTR_NOT_FOUND;
}
sat->sat_sup = supsat;
if ( at_append_to_list(sat, &supsat->sat_subtypes) ) {
*err = cname;
return SLAP_SCHERR_OUTOFMEM;
}
}
/*
* Inherit definitions from superiors. We only check the
* direct superior since that one has already inherited from
* its own superiorss
*/
if ( sat->sat_sup ) {
sat->sat_syntax = sat->sat_sup->sat_syntax;
sat->sat_equality = sat->sat_sup->sat_equality;
sat->sat_ordering = sat->sat_sup->sat_ordering;
sat->sat_substr = sat->sat_sup->sat_substr;
}
if ( at->at_syntax_oid ) {
if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
sat->sat_syntax = syn;
} else {
*err = sat->sat_syntax_oid;
return SLAP_SCHERR_SYN_NOT_FOUND;
}
#ifndef SLAPD_SCHEMA_NOT_COMPAT
if ( !strcmp(at->at_syntax_oid, SYNTAX_DS_OID) ) {
if ( at->at_equality_oid && (
!strcmp(at->at_equality_oid, SYNTAX_DSCE_OID) ) )
{
sat->sat_syntax_compat = SYNTAX_CES;
} else {
sat->sat_syntax_compat = SYNTAX_CIS;
}
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_IA5_OID) ) {
if ( at->at_equality_oid && (
!strcmp(at->at_equality_oid, SYNTAX_IA5CE_OID) ) )
{
sat->sat_syntax_compat = SYNTAX_CES;
} else {
sat->sat_syntax_compat = SYNTAX_CIS;
}
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_DN_OID ) ) {
sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_TEL_OID ) ) {
sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_BIN_OID ) ) {
sat->sat_syntax_compat = SYNTAX_BIN;
} else {
sat->sat_syntax_compat = DEFAULT_SYNTAX;
}
#endif
} else if ( sat->sat_syntax == NULL ) {
return SLAP_SCHERR_ATTR_INCOMPLETE;
}
if ( sat->sat_equality_oid ) {
if ( (mr = mr_find(sat->sat_equality_oid)) ) {
sat->sat_equality = mr;
} else {
*err = sat->sat_equality_oid;
return SLAP_SCHERR_MR_NOT_FOUND;
}
}
if ( sat->sat_ordering_oid ) {
if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
sat->sat_ordering = mr;
} else {
*err = sat->sat_ordering_oid;
return SLAP_SCHERR_MR_NOT_FOUND;
}
}
if ( sat->sat_substr_oid ) {
if ( (mr = mr_find(sat->sat_substr_oid)) ) {
sat->sat_substr = mr;
} else {
*err = sat->sat_substr_oid;
return SLAP_SCHERR_MR_NOT_FOUND;
}
}
code = at_insert(sat,err);
return code;
}
#ifdef LDAP_DEBUG
static int
at_index_printnode( struct aindexrec *air )
{
printf("%s = %s\n",
air->air_name,
ldap_attributetype2str(&air->air_at->sat_atype) );
return( 0 );
}
static void
at_index_print( void )
{
printf("Printing attribute type index:\n");
(void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
0, -1, AVL_INORDER );
}
#endif
#if defined( SLAPD_SCHEMA_DN )
int
at_schema_info( Entry *e )
{
struct berval val;
struct berval *vals[2];
AttributeType *at;
vals[0] = &val;
vals[1] = NULL;
for ( at = attr_list; at; at = at->sat_next ) {
val.bv_val = ldap_attributetype2str( &at->sat_atype );
if ( val.bv_val ) {
val.bv_len = strlen( val.bv_val );
Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
(long) val.bv_len, val.bv_val, 0 );
attr_merge( e, "attributeTypes", vals );
ldap_memfree( val.bv_val );
} else {
return -1;
}
}
return 0;
}
#endif

View File

@ -26,10 +26,28 @@
static void at_index_print( void );
#endif
#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 );
}
#endif
void
attr_free( Attribute *a )
{
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
ad_free( &a->a_desc, 0 );
#else
free( a->a_type );
#endif
ber_bvecfree( a->a_vals );
free( a );
}
@ -74,8 +92,13 @@ Attribute *attr_dup( Attribute *a )
tmp->a_vals = NULL;
}
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
tmp->a_desc = a->a_desc;
tmp->a_desc.ad_cname = ber_bvdup( a->a_desc.ad_cname );
tmp->a_desc.ad_lang = ch_strdup( a->a_desc.ad_lang );
#else
tmp->a_type = ch_strdup( a->a_type );
#ifndef SLAPD_SCHEMA_NOT_COMPAT
tmp->a_syntax = a->a_syntax;
#endif
tmp->a_next = NULL;
@ -101,6 +124,7 @@ Attribute *attrs_dup( Attribute *a )
return tmp;
}
#ifndef SLAPD_SCHEMA_NOT_COMPAT
/*
* attr_normalize - normalize an attribute name (make it all lowercase)
*/
@ -112,7 +136,9 @@ attr_normalize( char *s )
return( ldap_pvt_str2lower( s ) );
}
#endif
#ifndef SLAPD_SCHEMA_NOT_COMPAT
/*
* attr_merge_fast - merge the given type and value with the list of
* attributes in attrs. called from str2entry(), where we can make some
@ -134,17 +160,21 @@ attr_merge_fast(
{
if ( *a == NULL ) {
for ( *a = &e->e_attrs; **a != NULL; *a = &(**a)->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
if ( strcasecmp( (**a)->a_type, type ) == 0 ) {
break;
}
#endif
}
}
if ( **a == NULL ) {
**a = (Attribute *) ch_malloc( sizeof(Attribute) );
(**a)->a_type = attr_normalize( ch_strdup( type ) );
(**a)->a_vals = NULL;
#ifndef SLAPD_SCHEMA_NOT_COMPAT
(**a)->a_type = attr_normalize( ch_strdup( type ) );
(**a)->a_syntax = attr_syntax( type );
#endif
(**a)->a_next = NULL;
@ -153,6 +183,7 @@ attr_merge_fast(
return( value_add_fast( &(**a)->a_vals, vals, nvals, naddvals,
maxvals ) );
}
#endif
/*
* attr_merge - merge the given type and value with the list of
@ -171,18 +202,24 @@ attr_merge(
Attribute **a;
for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
break;
}
#endif
}
if ( *a == NULL ) {
*a = (Attribute *) ch_malloc( sizeof(Attribute) );
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
(*a)->a_type = attr_normalize( ch_strdup( type ) );
(*a)->a_vals = NULL;
#ifndef SLAPD_SCHEMA_NOT_COMPAT
(*a)->a_syntax = attr_syntax( type );
#endif
(*a)->a_vals = NULL;
(*a)->a_next = NULL;
}
@ -190,19 +227,23 @@ attr_merge(
}
/*
* attr_find - find and return attribute type in list a
* attr_find - find attribute by type
*/
Attribute *
attr_find(
Attribute *a,
const char *type
const char *type
)
{
for ( ; a != NULL; a = a->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
if ( strcasecmp( a->a_type, type ) == 0 ) {
return( a );
}
#endif
}
return( NULL );
@ -225,9 +266,13 @@ attr_delete(
Attribute *save;
for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
if ( strcasecmp( (*a)->a_type, type ) == 0 ) {
break;
}
#endif
}
if ( *a == NULL ) {
@ -241,552 +286,3 @@ attr_delete(
return( 0 );
}
#ifndef SLAPD_SCHEMA_NOT_COMPAT
#define DEFAULT_SYNTAX SYNTAX_CIS
/*
* attr_syntax - return the syntax of attribute type
*/
int
attr_syntax( const char *type )
{
AttributeType *sat;
sat = at_find(type);
if ( sat ) {
return( sat->sat_syntax_compat );
}
return( DEFAULT_SYNTAX );
}
/*
* attr_syntax_config - process an attribute syntax config line
*/
void
attr_syntax_config(
const char *fname,
int lineno,
int argc,
char **argv
)
{
char *save;
LDAP_ATTRIBUTE_TYPE *at;
int lasti;
int code;
const char *err;
if ( argc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing name in \"attribute <name>+ <syntax>\" (ignored)\n",
fname, lineno, 0 );
return;
}
at = (LDAP_ATTRIBUTE_TYPE *)
ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
#define SYNTAX_DS_OID "1.3.6.1.4.1.1466.115.121.1.15"
#define SYNTAX_DSCE_OID "2.5.13.5"
#define SYNTAX_IA5_OID "1.3.6.1.4.1.1466.115.121.1.26"
#define SYNTAX_IA5CE_OID "1.3.6.1.4.1.1466.109.114.1"
#define SYNTAX_DN_OID SLAPD_OID_DN_SYNTAX
#define SYNTAX_TEL_OID "1.3.6.1.4.1.1466.115.121.1.50"
#define SYNTAX_BIN_OID "1.3.6.1.4.1.1466.115.121.1.40" /* octetString */
lasti = argc - 1;
if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
strcasecmp( argv[lasti], "cis" ) == 0 ) {
at->at_syntax_oid = SYNTAX_DS_OID;
at->at_equality_oid = "2.5.13.2";
at->at_ordering_oid = "2.5.13.3";
at->at_substr_oid = "2.5.13.4";
} else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
strcasecmp( argv[lasti], "tel" ) == 0 ) {
at->at_syntax_oid = SYNTAX_TEL_OID;
at->at_equality_oid = "2.5.13.20";
at->at_substr_oid = "2.5.13.21";
} else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
at->at_syntax_oid = SYNTAX_DN_OID;
at->at_equality_oid = "2.5.13.1";
} else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
strcasecmp( argv[lasti], "ces" ) == 0 ) {
at->at_syntax_oid = SYNTAX_DS_OID;
at->at_equality_oid = SYNTAX_DSCE_OID;
at->at_ordering_oid = "2.5.13.6";
at->at_substr_oid = "2.5.13.7";
} else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
strcasecmp( argv[lasti], "bin" ) == 0 ) {
/* bin -> octetString, not binary! */
at->at_syntax_oid = SYNTAX_BIN_OID;
at->at_equality_oid = "2.5.13.17";
} else {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
fname, lineno, argv[lasti] );
Debug( LDAP_DEBUG_ANY,
"possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
0, 0, 0 );
free( (AttributeType *) at );
return;
}
save = argv[lasti];
argv[lasti] = NULL;
at->at_names = charray_dup( argv );
argv[lasti] = save;
code = at_add( at, &err );
if ( code ) {
fprintf( stderr, "%s: line %d: %s %s\n",
fname, lineno, scherr2str(code), err);
exit( EXIT_FAILURE );
}
ldap_memfree(at);
}
int
at_fake_if_needed(
const char *name
)
{
char *argv[3];
if ( at_find( name ) ) {
return 0;
} else {
argv[0] = (char*) name;
argv[1] = "cis";
argv[2] = NULL;
attr_syntax_config( "implicit", 0, 2, argv );
return 0;
}
}
#endif
struct aindexrec {
char *air_name;
AttributeType *air_at;
};
static Avlnode *attr_index = NULL;
static AttributeType *attr_list = NULL;
static int
attr_index_cmp(
struct aindexrec *air1,
struct aindexrec *air2
)
{
return (strcasecmp( air1->air_name, air2->air_name ));
}
static int
attr_index_name_cmp(
char *type,
struct aindexrec *air
)
{
return (strcasecmp( type, air->air_name ));
}
AttributeType *
at_find(
const char *name
)
{
struct aindexrec *air;
char *tmpname;
#ifndef SLAPD_SCHEMA_NOT_COMPAT
/*
* The name may actually be an AttributeDescription, i.e. it may
* contain options.
*/
/* Treat any attribute type with option as an unknown attribute type */
char *p = strchr( name, ';' );
if ( p ) {
tmpname = ch_malloc( p-name+1 );
strncpy( tmpname, name, p-name );
tmpname[p-name] = '\0';
} else
#endif
{
tmpname = (char *)name;
}
if ( (air = (struct aindexrec *) avl_find( attr_index, tmpname,
(AVL_CMP) attr_index_name_cmp )) != NULL ) {
if ( tmpname != name )
ldap_memfree( tmpname );
return( air->air_at );
}
if ( tmpname != name )
ldap_memfree( tmpname );
return( NULL );
}
int
at_append_to_list(
AttributeType *sat,
AttributeType ***listp
)
{
AttributeType **list;
AttributeType **list1;
int size;
list = *listp;
if ( !list ) {
size = 2;
list = calloc(size, sizeof(AttributeType *));
if ( !list ) {
return -1;
}
} else {
size = 0;
list1 = *listp;
while ( *list1 ) {
size++;
list1++;
}
size += 2;
list1 = realloc(list, size*sizeof(AttributeType *));
if ( !list1 ) {
return -1;
}
list = list1;
}
list[size-2] = sat;
list[size-1] = NULL;
*listp = list;
return 0;
}
int
at_delete_from_list(
int pos,
AttributeType ***listp
)
{
AttributeType **list;
AttributeType **list1;
int i;
int j;
if ( pos < 0 ) {
return -2;
}
list = *listp;
for ( i=0; list[i]; i++ )
;
if ( pos >= i ) {
return -2;
}
for ( i=pos, j=pos+1; list[j]; i++, j++ ) {
list[i] = list[j];
}
list[i] = NULL;
/* Tell the runtime this can be shrinked */
list1 = realloc(list, (i+1)*sizeof(AttributeType **));
if ( !list1 ) {
return -1;
}
*listp = list1;
return 0;
}
int
at_find_in_list(
AttributeType *sat,
AttributeType **list
)
{
int i;
if ( !list ) {
return -1;
}
for ( i=0; list[i]; i++ ) {
if ( sat == list[i] ) {
return i;
}
}
return -1;
}
static int
at_insert(
AttributeType *sat,
const char **err
)
{
AttributeType **atp;
struct aindexrec *air;
char **names;
atp = &attr_list;
while ( *atp != NULL ) {
atp = &(*atp)->sat_next;
}
*atp = sat;
if ( sat->sat_oid ) {
air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name = sat->sat_oid;
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
(AVL_CMP) attr_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = sat->sat_oid;
ldap_memfree(air);
return SLAP_SCHERR_DUP_ATTR;
}
/* FIX: temporal consistency check */
at_find(air->air_name);
}
if ( (names = sat->sat_names) ) {
while ( *names ) {
air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name = ch_strdup(*names);
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
(AVL_CMP) attr_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = *names;
ldap_memfree(air->air_name);
ldap_memfree(air);
return SLAP_SCHERR_DUP_ATTR;
}
/* FIX: temporal consistency check */
at_find(air->air_name);
names++;
}
}
return 0;
}
int
at_add(
LDAP_ATTRIBUTE_TYPE *at,
const char **err
)
{
AttributeType *sat;
AttributeType *sat1;
MatchingRule *mr;
Syntax *syn;
int code;
char *errattr;
if ( at->at_names && at->at_names[0] ) {
errattr = at->at_names[0];
} else if ( at->at_oid ) {
errattr = at->at_oid;
} else {
errattr = "";
return SLAP_SCHERR_ATTR_INCOMPLETE;
}
sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
if ( at->at_sup_oid ) {
if ( (sat1 = at_find(at->at_sup_oid)) ) {
sat->sat_sup = sat1;
if ( at_append_to_list(sat, &sat1->sat_subtypes) ) {
*err = errattr;
return SLAP_SCHERR_OUTOFMEM;
}
} else {
*err = at->at_sup_oid;
return SLAP_SCHERR_ATTR_NOT_FOUND;
}
}
/*
* Inherit definitions from superiors. We only check the
* direct superior since that one has already inherited from
* its own superiorss
*/
if ( sat->sat_sup ) {
sat->sat_syntax = sat->sat_sup->sat_syntax;
sat->sat_equality = sat->sat_sup->sat_equality;
sat->sat_ordering = sat->sat_sup->sat_ordering;
sat->sat_substr = sat->sat_sup->sat_substr;
}
if ( at->at_syntax_oid ) {
if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
sat->sat_syntax = syn;
} else {
*err = sat->sat_syntax_oid;
return SLAP_SCHERR_SYN_NOT_FOUND;
}
#ifndef SLAPD_SCHEMA_NOT_COMPAT
if ( !strcmp(at->at_syntax_oid, SYNTAX_DS_OID) ) {
if ( at->at_equality_oid && (
!strcmp(at->at_equality_oid, SYNTAX_DSCE_OID) ) )
{
sat->sat_syntax_compat = SYNTAX_CES;
} else {
sat->sat_syntax_compat = SYNTAX_CIS;
}
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_IA5_OID) ) {
if ( at->at_equality_oid && (
!strcmp(at->at_equality_oid, SYNTAX_IA5CE_OID) ) )
{
sat->sat_syntax_compat = SYNTAX_CES;
} else {
sat->sat_syntax_compat = SYNTAX_CIS;
}
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_DN_OID ) ) {
sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_TEL_OID ) ) {
sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
} else if ( !strcmp(at->at_syntax_oid, SYNTAX_BIN_OID ) ) {
sat->sat_syntax_compat = SYNTAX_BIN;
} else {
sat->sat_syntax_compat = DEFAULT_SYNTAX;
}
#endif
} else if ( sat->sat_syntax == NULL ) {
return SLAP_SCHERR_ATTR_INCOMPLETE;
}
if ( sat->sat_equality_oid ) {
if ( (mr = mr_find(sat->sat_equality_oid)) ) {
sat->sat_equality = mr;
} else {
*err = sat->sat_equality_oid;
return SLAP_SCHERR_MR_NOT_FOUND;
}
}
if ( sat->sat_ordering_oid ) {
if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
sat->sat_ordering = mr;
} else {
*err = sat->sat_ordering_oid;
return SLAP_SCHERR_MR_NOT_FOUND;
}
}
if ( sat->sat_substr_oid ) {
if ( (mr = mr_find(sat->sat_substr_oid)) ) {
sat->sat_substr = mr;
} else {
*err = sat->sat_substr_oid;
return SLAP_SCHERR_MR_NOT_FOUND;
}
}
code = at_insert(sat,err);
return code;
}
char *
#ifdef SLAPD_SCHEMA_NOT_COMPAT
at_canonical_name( AttributeType * atp )
#else
at_canonical_name( const char * a_type )
#endif
{
#ifndef SLAPD_SCHEMA_NOT_COMPAT
AttributeType *atp;
atp=at_find(a_type);
#endif
if ( atp == NULL ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
return NULL;
#else
return (char *) a_type;
#endif
} else if ( atp->sat_names
&& atp->sat_names[0] && (*(atp->sat_names[0]) != '\0') )
{
return atp->sat_names[0];
} else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
return atp->sat_oid;
}
#ifdef SLAPD_SCHEMA_NOT_COMPAT
return NULL;
#else
return (char *) a_type;
#endif
}
#if defined( SLAPD_SCHEMA_DN )
int
at_schema_info( Entry *e )
{
struct berval val;
struct berval *vals[2];
AttributeType *at;
vals[0] = &val;
vals[1] = NULL;
for ( at = attr_list; at; at = at->sat_next ) {
val.bv_val = ldap_attributetype2str( &at->sat_atype );
if ( val.bv_val ) {
val.bv_len = strlen( val.bv_val );
Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
(long) val.bv_len, val.bv_val, 0 );
attr_merge( e, "attributeTypes", vals );
ldap_memfree( val.bv_val );
} else {
return -1;
}
}
return 0;
}
#endif
#ifdef LDAP_DEBUG
static int
at_index_printnode( struct aindexrec *air )
{
printf("%s = %s\n",
air->air_name,
ldap_attributetype2str(&air->air_at->sat_atype) );
return( 0 );
}
static void
at_index_print( void )
{
printf("Printing attribute type index:\n");
(void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
0, -1, AVL_INORDER );
}
#endif

View File

@ -38,7 +38,7 @@ bdb2i_back_add_internal(
return( -1 );
}
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
if ( schema_check_entry( e ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",
0, 0, 0 );

View File

@ -74,7 +74,7 @@ bdb2i_back_modify_internal(
}
/* check that the entry still obeys the schema */
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
if ( schema_check_entry( e ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OBJECT_CLASS_VIOLATION,
NULL, NULL, NULL, NULL );

View File

@ -43,7 +43,7 @@ ldbm_back_add(
return( -1 );
}
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
if ( schema_check_entry( e ) != 0 ) {
ldap_pvt_thread_mutex_unlock(&li->li_add_mutex);
Debug( LDAP_DEBUG_TRACE, "entry failed schema check\n",

View File

@ -15,6 +15,7 @@
#include "slap.h"
#include "back-ldbm.h"
static int change_value(Backend *be,
DBCache *db,
char *type,
@ -51,7 +52,11 @@ index_add_entry(
/* add the dn to the indexes */
{
char *dn = ch_strdup("dn");
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
index_change_values( be, dn, bvals, e->e_id, SLAP_INDEX_ADD_OP );
#endif
free( dn );
}
@ -59,8 +64,12 @@ index_add_entry(
/* add each attribute to the indexes */
for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* index_change_values( be, SLAP_INDEX_ADD_OP, e->e_id, ap ); */
#else
index_change_values( be, ap->a_type, ap->a_vals, e->e_id,
SLAP_INDEX_ADD_OP );
#endif
}
Debug( LDAP_DEBUG_TRACE, "<= index_add( %ld, \"%s\" ) 0\n", e->e_id,

View File

@ -95,7 +95,7 @@ int ldbm_modify_internal(
ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
/* check that the entry still obeys the schema */
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
if ( schema_check_entry( e ) != 0 ) {
attrs_free( e->e_attrs );
e->e_attrs = save_attrs;
Debug( LDAP_DEBUG_ANY, "entry failed schema check\n", 0, 0, 0 );

View File

@ -633,26 +633,27 @@ backend_group(
}
#ifdef SLAPD_SCHEMA_DN
Attribute *backend_subschemasubentry( Backend *be )
Attribute *backend_operational(
Backend *be,
Entry *e )
{
/*
* This routine returns points to STATIC data!!!
*/
/* and should be backend specific */
static struct berval ss_val = {
sizeof(SLAPD_SCHEMA_DN)-1,
SLAPD_SCHEMA_DN };
static struct berval *ss_vals[2] = { &ss_val, NULL };
static Attribute ss_attr = {
"subschemasubentry",
ss_vals,
#ifndef SLAPD_SCHEMA_NOT_COMPAT
SYNTAX_DN | SYNTAX_CIS,
Attribute *a = ch_malloc( sizeof( Attribute ) );
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
a->a_type = "subschemasubentry";
a->a_syntax = SYNTAX_DN | SYNTAX_CIS;
#endif
NULL
};
return &ss_attr;
/* Should be backend specific */
a->a_vals = ch_malloc( 2 * sizeof( struct berval * ) );
a->a_vals[0] = ch_malloc( sizeof( struct berval ) );
a->a_vals[0]->bv_val = strdup( SLAPD_SCHEMA_DN );
a->a_vals[0]->bv_len = sizeof( SLAPD_SCHEMA_DN ) - 1;
a->a_vals[1] = NULL;
a->a_next = NULL;
return a;
}
#endif

View File

@ -197,9 +197,18 @@ entry2str(
/* put "<type>:[:] <value>" line for each value */
for ( i = 0; a->a_vals[i] != NULL; i++ ) {
bv = a->a_vals[i];
#ifdef SLAPD_SCHEMA_NOT_COMPAT
tmplen = a->a_desc.ad_cname->bv_len;
#else
tmplen = strlen( a->a_type );
#endif
MAKE_SPACE( LDIF_SIZE_NEEDED( tmplen, bv->bv_len ));
ldif_sput( (char **) &ecur, LDIF_PUT_VALUE, a->a_type,
ldif_sput( (char **) &ecur, LDIF_PUT_VALUE,
#ifdef SLAPD_SCHEMA_NOT_COMPAT
a->a_desc.ad_cname->bv_val,
#else
a->a_type,
#endif
bv->bv_val, bv->bv_len );
}
}

View File

@ -140,6 +140,10 @@ SOURCE=.\add.c
# End Source File
# Begin Source File
SOURCE=.\at.c
# End Source File
# Begin Source File
SOURCE=.\attr.c
# End Source File
# Begin Source File
@ -236,6 +240,14 @@ SOURCE=.\monitor.c
# End Source File
# Begin Source File
SOURCE=.\mr.c
# End Source File
# Begin Source File
SOURCE=.\oc.c
# End Source File
# Begin Source File
SOURCE=.\operation.c
# End Source File
# Begin Source File
@ -268,6 +280,10 @@ SOURCE=.\schema.c
# End Source File
# Begin Source File
SOURCE=.\schema_check.c
# End Source File
# Begin Source File
SOURCE=.\schema_init.c
# End Source File
# Begin Source File
@ -292,6 +308,10 @@ SOURCE=.\suffixalias.c
# End Source File
# Begin Source File
SOURCE=.\syntax.c
# End Source File
# Begin Source File
SOURCE=.\unbind.c
# End Source File
# Begin Source File

206
servers/slapd/mr.c Normal file
View File

@ -0,0 +1,206 @@
/* mr.c - routines to manage matching rule definitions */
/* $OpenLDAP$ */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "ldap_pvt.h"
struct mindexrec {
char *mir_name;
MatchingRule *mir_mr;
};
static Avlnode *mr_index = NULL;
static MatchingRule *mr_list = NULL;
static int
mr_index_cmp(
struct mindexrec *mir1,
struct mindexrec *mir2
)
{
return (strcmp( mir1->mir_name, mir2->mir_name ));
}
static int
mr_index_name_cmp(
char *name,
struct mindexrec *mir
)
{
return (strcmp( name, mir->mir_name ));
}
MatchingRule *
mr_find( const char *mrname )
{
struct mindexrec *mir = NULL;
if ( (mir = (struct mindexrec *) avl_find( mr_index, mrname,
(AVL_CMP) mr_index_name_cmp )) != NULL ) {
return( mir->mir_mr );
}
return( NULL );
}
static int
mr_insert(
MatchingRule *smr,
const char **err
)
{
MatchingRule **mrp;
struct mindexrec *mir;
char **names;
mrp = &mr_list;
while ( *mrp != NULL ) {
mrp = &(*mrp)->smr_next;
}
*mrp = smr;
if ( smr->smr_oid ) {
mir = (struct mindexrec *)
ch_calloc( 1, sizeof(struct mindexrec) );
mir->mir_name = smr->smr_oid;
mir->mir_mr = smr;
if ( avl_insert( &mr_index, (caddr_t) mir,
(AVL_CMP) mr_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = smr->smr_oid;
ldap_memfree(mir);
return SLAP_SCHERR_DUP_RULE;
}
/* FIX: temporal consistency check */
mr_find(mir->mir_name);
}
if ( (names = smr->smr_names) ) {
while ( *names ) {
mir = (struct mindexrec *)
ch_calloc( 1, sizeof(struct mindexrec) );
mir->mir_name = ch_strdup(*names);
mir->mir_mr = smr;
if ( avl_insert( &mr_index, (caddr_t) mir,
(AVL_CMP) mr_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = *names;
ldap_memfree(mir);
return SLAP_SCHERR_DUP_RULE;
}
/* FIX: temporal consistency check */
mr_find(mir->mir_name);
names++;
}
}
return 0;
}
int
mr_add(
LDAP_MATCHING_RULE *mr,
slap_mr_convert_func *convert,
slap_mr_normalize_func *normalize,
slap_mr_match_func *match,
slap_mr_indexer_func *indexer,
slap_mr_filter_func *filter,
const char **err
)
{
MatchingRule *smr;
Syntax *syn;
int code;
smr = (MatchingRule *) ch_calloc( 1, sizeof(MatchingRule) );
memcpy( &smr->smr_mrule, mr, sizeof(LDAP_MATCHING_RULE));
smr->smr_convert = convert;
smr->smr_normalize = normalize;
smr->smr_match = match;
smr->smr_indexer = indexer;
smr->smr_filter = filter;
if ( smr->smr_syntax_oid ) {
if ( (syn = syn_find(smr->smr_syntax_oid)) ) {
smr->smr_syntax = syn;
} else {
*err = smr->smr_syntax_oid;
return SLAP_SCHERR_SYN_NOT_FOUND;
}
} else {
*err = "";
return SLAP_SCHERR_MR_INCOMPLETE;
}
code = mr_insert(smr,err);
return code;
}
int
register_matching_rule(
char * desc,
slap_mr_convert_func *convert,
slap_mr_normalize_func *normalize,
slap_mr_match_func *match,
slap_mr_indexer_func *indexer,
slap_mr_filter_func *filter )
{
LDAP_MATCHING_RULE *mr;
int code;
const char *err;
mr = ldap_str2matchingrule( desc, &code, &err);
if ( !mr ) {
Debug( LDAP_DEBUG_ANY, "Error in register_matching_rule: %s before %s in %s\n",
ldap_scherr2str(code), err, desc );
return( -1 );
}
code = mr_add( mr, convert, normalize, match, indexer, filter, &err );
if ( code ) {
Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s for %s in %s\n",
scherr2str(code), err, desc );
return( -1 );
}
return( 0 );
}
#if defined( SLAPD_SCHEMA_DN )
int mr_schema_info( Entry *e )
{
struct berval val;
struct berval *vals[2];
MatchingRule *mr;
vals[0] = &val;
vals[1] = NULL;
for ( mr = mr_list; mr; mr = mr->smr_next ) {
val.bv_val = ldap_matchingrule2str( &mr->smr_mrule );
if ( val.bv_val ) {
val.bv_len = strlen( val.bv_val );
Debug( LDAP_DEBUG_TRACE, "Merging mr [%ld] %s\n",
(long) val.bv_len, val.bv_val, 0 );
attr_merge( e, "matchingRules", vals );
ldap_memfree( val.bv_val );
} else {
return -1;
}
}
return 0;
}
#endif

456
servers/slapd/oc.c Normal file
View File

@ -0,0 +1,456 @@
/* oc.c - object class routines */
/* $OpenLDAP$ */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "ldap_pvt.h"
int is_entry_objectclass(
Entry* e,
const char* oc)
{
Attribute *attr;
struct berval bv;
if( e == NULL || oc == NULL || *oc == '\0' )
return 0;
/*
* find objectClass attribute
*/
attr = attr_find(e->e_attrs, "objectclass");
if( attr == NULL ) {
/* no objectClass attribute */
return 0;
}
bv.bv_val = (char *) oc;
bv.bv_len = strlen( bv.bv_val );
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/* not yet implemented */
#else
if( value_find(attr->a_vals, &bv, attr->a_syntax, 1) != 0) {
/* entry is not of this objectclass */
return 0;
}
#endif
return 1;
}
#ifndef SLAPD_SCHEMA_NOT_COMPAT
/* these shouldn't be hardcoded */
static char *oc_op_usermod_attrs[] = {
/*
* these are operational attributes which are
* not defined as NO-USER_MODIFICATION and
* which slapd supports modification of.
*
* Currently none.
* Likely candidate, "aci"
*/
NULL
};
static char *oc_op_attrs[] = {
/*
* these are operational attributes
* most could be user modifiable
*/
"objectClasses",
"attributeTypes",
"matchingRules",
"matchingRuleUse",
"dITStructureRules",
"dITContentRules",
"nameForms",
"ldapSyntaxes",
"namingContexts",
"supportedExtension",
"supportedControl",
"supportedSASLMechanisms",
"supportedLDAPversion",
"supportedACIMechanisms",
"subschemaSubentry", /* NO USER MOD */
NULL
};
/* this list should be extensible */
static char *oc_op_no_usermod_attrs[] = {
/*
* Operational and 'no user modification' attributes
* which are STORED in the directory server.
*/
/* RFC2252, 3.2.1 */
"creatorsName",
"createTimestamp",
"modifiersName",
"modifyTimestamp",
NULL
};
#endif
/*
* check to see if attribute is 'operational' or not.
*/
int
oc_check_op_attr( const char *type )
{
#ifndef SLAPD_SCHEMA_NOT_COMPAT
return charray_inlist( oc_op_attrs, type )
|| charray_inlist( oc_op_usermod_attrs, type )
|| charray_inlist( oc_op_no_usermod_attrs, type );
#else
AttributeType *at = at_find( type );
if( at == NULL ) return 0;
return at->sat_usage != LDAP_SCHEMA_USER_APPLICATIONS;
#endif
}
/*
* check to see if attribute can be user modified or not.
*/
int
oc_check_op_usermod_attr( const char *type )
{
#ifndef SLAPD_SCHEMA_NOT_COMPAT
return charray_inlist( oc_op_usermod_attrs, type );
#else
/* not (yet) in schema */
return 0;
#endif
}
/*
* check to see if attribute is 'no user modification' or not.
*/
int
oc_check_op_no_usermod_attr( const char *type )
{
#ifndef SLAPD_SCHEMA_NOT_COMPAT
return charray_inlist( oc_op_no_usermod_attrs, type );
#else
AttributeType *at = at_find( type );
if( at == NULL ) return 0;
return at->sat_no_user_mod;
#endif
}
struct oindexrec {
char *oir_name;
ObjectClass *oir_oc;
};
static Avlnode *oc_index = NULL;
static ObjectClass *oc_list = NULL;
static int
oc_index_cmp(
struct oindexrec *oir1,
struct oindexrec *oir2
)
{
return (strcasecmp( oir1->oir_name, oir2->oir_name ));
}
static int
oc_index_name_cmp(
char *name,
struct oindexrec *oir
)
{
return (strcasecmp( name, oir->oir_name ));
}
ObjectClass *
oc_find( const char *ocname )
{
struct oindexrec *oir = NULL;
if ( (oir = (struct oindexrec *) avl_find( oc_index, ocname,
(AVL_CMP) oc_index_name_cmp )) != NULL ) {
return( oir->oir_oc );
}
return( NULL );
}
static int
oc_create_required(
ObjectClass *soc,
char **attrs,
const char **err
)
{
char **attrs1;
AttributeType *sat;
AttributeType **satp;
int i;
if ( attrs ) {
attrs1 = attrs;
while ( *attrs1 ) {
sat = at_find(*attrs1);
if ( !sat ) {
*err = *attrs1;
return SLAP_SCHERR_ATTR_NOT_FOUND;
}
if ( at_find_in_list(sat, soc->soc_required) < 0) {
if ( at_append_to_list(sat, &soc->soc_required) ) {
*err = *attrs1;
return SLAP_SCHERR_OUTOFMEM;
}
}
attrs1++;
}
/* Now delete duplicates from the allowed list */
for ( satp = soc->soc_required; *satp; satp++ ) {
i = at_find_in_list(*satp,soc->soc_allowed);
if ( i >= 0 ) {
at_delete_from_list(i, &soc->soc_allowed);
}
}
}
return 0;
}
static int
oc_create_allowed(
ObjectClass *soc,
char **attrs,
const char **err
)
{
char **attrs1;
AttributeType *sat;
if ( attrs ) {
attrs1 = attrs;
while ( *attrs1 ) {
sat = at_find(*attrs1);
if ( !sat ) {
*err = *attrs1;
return SLAP_SCHERR_ATTR_NOT_FOUND;
}
if ( at_find_in_list(sat, soc->soc_required) < 0 &&
at_find_in_list(sat, soc->soc_allowed) < 0 ) {
if ( at_append_to_list(sat, &soc->soc_allowed) ) {
*err = *attrs1;
return SLAP_SCHERR_OUTOFMEM;
}
}
attrs1++;
}
}
return 0;
}
static int
oc_add_sups(
ObjectClass *soc,
char **sups,
const char **err
)
{
int code;
ObjectClass *soc1;
int nsups;
char **sups1;
int add_sups = 0;
if ( sups ) {
if ( !soc->soc_sups ) {
/* We are at the first recursive level */
add_sups = 1;
nsups = 0;
sups1 = sups;
while ( *sups1 ) {
nsups++;
sups1++;
}
nsups++;
soc->soc_sups = (ObjectClass **)ch_calloc(1,
nsups*sizeof(ObjectClass *));
}
nsups = 0;
sups1 = sups;
while ( *sups1 ) {
soc1 = oc_find(*sups1);
if ( !soc1 ) {
*err = *sups1;
return SLAP_SCHERR_CLASS_NOT_FOUND;
}
if ( add_sups )
soc->soc_sups[nsups] = soc1;
code = oc_add_sups(soc,soc1->soc_sup_oids, err);
if ( code )
return code;
code = oc_create_required(soc,soc1->soc_at_oids_must,err);
if ( code )
return code;
code = oc_create_allowed(soc,soc1->soc_at_oids_may,err);
if ( code )
return code;
nsups++;
sups1++;
}
}
return 0;
}
static int
oc_insert(
ObjectClass *soc,
const char **err
)
{
ObjectClass **ocp;
struct oindexrec *oir;
char **names;
ocp = &oc_list;
while ( *ocp != NULL ) {
ocp = &(*ocp)->soc_next;
}
*ocp = soc;
if ( soc->soc_oid ) {
oir = (struct oindexrec *)
ch_calloc( 1, sizeof(struct oindexrec) );
oir->oir_name = soc->soc_oid;
oir->oir_oc = soc;
if ( avl_insert( &oc_index, (caddr_t) oir,
(AVL_CMP) oc_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = soc->soc_oid;
ldap_memfree(oir);
return SLAP_SCHERR_DUP_CLASS;
}
/* FIX: temporal consistency check */
oc_find(oir->oir_name);
}
if ( (names = soc->soc_names) ) {
while ( *names ) {
oir = (struct oindexrec *)
ch_calloc( 1, sizeof(struct oindexrec) );
oir->oir_name = ch_strdup(*names);
oir->oir_oc = soc;
if ( avl_insert( &oc_index, (caddr_t) oir,
(AVL_CMP) oc_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = *names;
ldap_memfree(oir);
return SLAP_SCHERR_DUP_CLASS;
}
/* FIX: temporal consistency check */
oc_find(oir->oir_name);
names++;
}
}
return 0;
}
int
oc_add(
LDAP_OBJECT_CLASS *oc,
const char **err
)
{
ObjectClass *soc;
int code;
soc = (ObjectClass *) ch_calloc( 1, sizeof(ObjectClass) );
memcpy( &soc->soc_oclass, oc, sizeof(LDAP_OBJECT_CLASS));
if ( (code = oc_add_sups(soc,soc->soc_sup_oids,err)) != 0 )
return code;
if ( (code = oc_create_required(soc,soc->soc_at_oids_must,err)) != 0 )
return code;
if ( (code = oc_create_allowed(soc,soc->soc_at_oids_may,err)) != 0 )
return code;
code = oc_insert(soc,err);
return code;
}
#ifdef LDAP_DEBUG
static void
oc_print( ObjectClass *oc )
{
int i;
const char *mid;
printf( "objectclass %s\n", ldap_objectclass2name( &oc->soc_oclass ) );
if ( oc->soc_required != NULL ) {
mid = "\trequires ";
for ( i = 0; oc->soc_required[i] != NULL; i++, mid = "," )
printf( "%s%s", mid,
ldap_attributetype2name( &oc->soc_required[i]->sat_atype ) );
printf( "\n" );
}
if ( oc->soc_allowed != NULL ) {
mid = "\tallows ";
for ( i = 0; oc->soc_allowed[i] != NULL; i++, mid = "," )
printf( "%s%s", mid,
ldap_attributetype2name( &oc->soc_allowed[i]->sat_atype ) );
printf( "\n" );
}
}
#endif
#if defined( SLAPD_SCHEMA_DN )
int
oc_schema_info( Entry *e )
{
struct berval val;
struct berval *vals[2];
ObjectClass *oc;
vals[0] = &val;
vals[1] = NULL;
for ( oc = oc_list; oc; oc = oc->soc_next ) {
val.bv_val = ldap_objectclass2str( &oc->soc_oclass );
if ( val.bv_val ) {
val.bv_len = strlen( val.bv_val );
Debug( LDAP_DEBUG_TRACE, "Merging oc [%ld] %s\n",
(long) val.bv_len, val.bv_val, 0 );
attr_merge( e, "objectClasses", vals );
ldap_memfree( val.bv_val );
} else {
return -1;
}
}
return 0;
}
#endif

View File

@ -70,14 +70,15 @@ 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
LIBSLAPD_F (char *) at_canonical_name LDAP_P(( AttributeType *a_type ));
# define at_canonical_name(at) ((at)->sat_cname)
#else
LIBSLAPD_F (char *) at_canonical_name LDAP_P(( const char * a_type ));
#endif
LIBSLAPD_F (void) attrs_free LDAP_P(( Attribute *a ));
LIBSLAPD_F (Attribute *) attrs_dup LDAP_P(( Attribute *a ));
/*
* ava.c
@ -138,10 +139,8 @@ LIBSLAPD_F (int) backend_group LDAP_P((Backend *be,
));
#endif
#ifdef SLAPD_SCHEMA_DN
/* temporary extern for temporary routine*/
LIBSLAPD_F (Attribute *) backend_subschemasubentry( Backend * );
#endif
LIBSLAPD_F (Attribute *) backend_operational( Backend *, Entry * );
/*
@ -455,11 +454,19 @@ LIBSLAPD_F (int) sasl_bind LDAP_P((Backend *,
char *, char *, char *, struct berval *, char **));
#endif
/* oc.c */
LIBSLAPD_F (int) oc_schema_info( Entry *e );
/* mr.c */
LIBSLAPD_F (int) mr_schema_info( Entry *e );
/* syntax.c */
LIBSLAPD_F (int) syn_schema_info( Entry *e );
/*
* schema.c
*/
LIBSLAPD_F (int) oc_schema_check LDAP_P(( Entry *e ));
LIBSLAPD_F (int) oc_check_op_attr LDAP_P(( const char *type ));
LIBSLAPD_F (int) oc_check_op_usermod_attr LDAP_P(( const char *type ));
LIBSLAPD_F (int) oc_check_op_no_usermod_attr LDAP_P(( const char *type ));
@ -503,6 +510,11 @@ LIBSLAPD_F (int) is_entry_objectclass LDAP_P((
#define is_entry_alias(e) is_entry_objectclass((e), "ALIAS")
#define is_entry_referral(e) is_entry_objectclass((e), "REFERRAL")
/*
* schema_check.c
*/
LIBSLAPD_F (int) schema_check_entry LDAP_P(( Entry *e ));
/*
* schema_init.c

View File

@ -612,7 +612,7 @@ send_search_entry(
)
{
BerElement *ber;
Attribute *a;
Attribute *a, *aa;
int i, rc=-1, bytes;
char *edn;
int userattrs;
@ -659,36 +659,40 @@ send_search_entry(
: charray_inlist( attrs, LDAP_ALL_OPERATIONAL_ATTRIBUTES );
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
char *desc;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
desc = a->a_desc.ad_type->sat_cname;
#else
desc = a->a_type;
#endif
if ( attrs == NULL ) {
/* all addrs request, skip operational attributes */
if( !opattrs && oc_check_op_attr( a->a_type ) ) {
if( !opattrs && oc_check_op_attr( desc ) ) {
continue;
}
} else {
/* specific addrs requested */
if ( oc_check_op_attr( a->a_type ) ) {
if( !opattrs && !charray_inlist( attrs, a->a_type ) )
{
if ( oc_check_op_attr( desc ) )
{
if( !opattrs && !charray_inlist( attrs, desc ) ) {
continue;
}
} else {
if (!userattrs && !charray_inlist( attrs, a->a_type ) )
{
if (!userattrs && !charray_inlist( attrs, desc ) ) {
continue;
}
}
}
if ( ! access_allowed( be, conn, op, e,
a->a_type, NULL, ACL_READ ) )
{
if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
a->a_type, 0, 0 );
desc, 0, 0 );
continue;
}
if (( rc = ber_printf( ber, "{s[" /*]}*/ , a->a_type )) == -1 ) {
if (( rc = ber_printf( ber, "{s[" /*]}*/ , desc )) == -1 ) {
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@ -699,11 +703,11 @@ send_search_entry(
if ( ! attrsonly ) {
for ( i = 0; a->a_vals[i] != NULL; i++ ) {
if ( ! access_allowed( be, conn, op, e,
a->a_type, a->a_vals[i], ACL_READ ) )
desc, a->a_vals[i], ACL_READ ) )
{
Debug( LDAP_DEBUG_ACL,
"acl: access to attribute %s, value %d not allowed\n",
a->a_type, i, 0 );
desc, i, 0 );
continue;
}
@ -727,42 +731,46 @@ send_search_entry(
}
}
#ifdef SLAPD_SCHEMA_DN
/* eventually will loop through generated operational attributes */
/* only have subschemaSubentry implemented */
a = backend_subschemasubentry( be );
aa = backend_operational( be, e );
do {
for (a = aa ; a == NULL; a = a->a_next ) {
char *desc;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
desc = a->a_desc.ad_type->sat_cname;
#else
desc = a->a_type;
#endif
if ( attrs == NULL ) {
/* all addrs request, skip operational attributes */
if( !opattrs && oc_check_op_attr( a->a_type ) ) {
if( !opattrs && oc_check_op_attr( desc ) ) {
continue;
}
} else {
/* specific addrs requested */
if ( oc_check_op_attr( a->a_type ) ) {
if( !opattrs && !charray_inlist( attrs, a->a_type ) )
if ( oc_check_op_attr( desc ) ) {
if( !opattrs && !charray_inlist( attrs, desc ) )
{
continue;
}
} else {
if (!userattrs && !charray_inlist( attrs, a->a_type ) )
if (!userattrs && !charray_inlist( attrs, desc ) )
{
continue;
}
}
}
if ( ! access_allowed( be, conn, op, e,
a->a_type, NULL, ACL_READ ) )
{
if ( ! access_allowed( be, conn, op, e, desc, NULL, ACL_READ ) ) {
Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s not allowed\n",
a->a_type, 0, 0 );
desc, 0, 0 );
continue;
}
if (( rc = ber_printf( ber, "{s[" /*]}*/ , a->a_type )) == -1 ) {
if (( rc = ber_printf( ber, "{s[" /*]}*/ , desc )) == -1 ) {
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@ -773,11 +781,11 @@ send_search_entry(
if ( ! attrsonly ) {
for ( i = 0; a->a_vals[i] != NULL; i++ ) {
if ( ! access_allowed( be, conn, op, e,
a->a_type, a->a_vals[i], ACL_READ ) )
desc, a->a_vals[i], ACL_READ ) )
{
Debug( LDAP_DEBUG_ACL,
"acl: access to attribute %s, value %d not allowed\n",
a->a_type, i, 0 );
desc, i, 0 );
continue;
}
@ -800,8 +808,9 @@ send_search_entry(
NULL, "encode end error", NULL, NULL );
goto error_return;
}
} while (0);
#endif
}
attrs_free( aa );
rc = ber_printf( ber, /*{{{*/ "}}}" );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,271 @@
/* schema_check.c - routines to enforce schema definitions */
/* $OpenLDAP$ */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "ldap_pvt.h"
static char * oc_check_required(Entry *e, char *ocname);
static int oc_check_allowed(char *type, struct berval **ocl);
/*
* entry_schema_check - check that entry e conforms to the schema required
* by its object class(es).
*
* returns 0 if so, non-zero otherwise.
*/
int
schema_check_entry( Entry *e )
{
Attribute *a, *aoc;
ObjectClass *oc;
int i;
int ret = 0;
if( !global_schemacheck ) return 0;
/* find the object class attribute - could error out here */
if ( (aoc = attr_find( e->e_attrs, "objectclass" )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "No object class for entry (%s)\n",
e->e_dn, 0, 0 );
return( 1 );
}
/* check that the entry has required attrs for each oc */
for ( i = 0; aoc->a_vals[i] != NULL; i++ ) {
if ( (oc = oc_find( aoc->a_vals[i]->bv_val )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"Objectclass \"%s\" not defined\n",
aoc->a_vals[i]->bv_val, 0, 0 );
}
else
{
char *s = oc_check_required( e, aoc->a_vals[i]->bv_val );
if (s != NULL) {
Debug( LDAP_DEBUG_ANY,
"Entry (%s), oc \"%s\" requires attr \"%s\"\n",
e->e_dn, aoc->a_vals[i]->bv_val, s );
ret = 1;
}
}
}
if ( ret != 0 ) {
return( ret );
}
/* check that each attr in the entry is allowed by some oc */
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
if ( oc_check_allowed( a->a_desc.ad_type, aoc->a_vals ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"Entry (%s), attr \"%s\" not allowed\n",
e->e_dn, a->a_desc.ad_cname->bv_val, 0 );
ret = 1;
}
#else
if ( oc_check_allowed( a->a_type, aoc->a_vals ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"Entry (%s), attr \"%s\" not allowed\n",
e->e_dn, a->a_type, 0 );
ret = 1;
}
#endif
}
return( ret );
}
static char *
oc_check_required( Entry *e, char *ocname )
{
ObjectClass *oc;
AttributeType *at;
int i;
Attribute *a;
Debug( LDAP_DEBUG_TRACE,
"oc_check_required entry (%s), objectclass \"%s\"\n",
e->e_dn, ocname, 0 );
/* find global oc defn. it we don't know about it assume it's ok */
if ( (oc = oc_find( ocname )) == NULL ) {
return( 0 );
}
/* check for empty oc_required */
if(oc->soc_required == NULL) {
return( 0 );
}
/* for each required attribute */
for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
at = oc->soc_required[i];
/* see if it's in the entry */
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
if( a->a_desc.ad_type == at ) {
break;
}
#else
char **pp;
if ( at->sat_oid &&
strcmp( a->a_type, at->sat_oid ) == 0 ) {
break;
}
pp = at->sat_names;
if ( pp == NULL ) {
/* Empty name list => not found */
a = NULL;
break;
}
while ( *pp ) {
if ( strcasecmp( a->a_type, *pp ) == 0 ) {
break;
}
pp++;
}
if ( *pp ) {
break;
}
#endif
}
/* not there => schema violation */
if ( a == NULL ) {
if ( at->sat_names && at->sat_names[0] ) {
return at->sat_names[0];
} else {
return at->sat_oid;
}
}
}
return( NULL );
}
static int
oc_check_allowed( char *type, struct berval **ocl )
{
ObjectClass *oc;
AttributeType *at;
int i, j;
char **pp;
char *p, *t;
Debug( LDAP_DEBUG_TRACE,
"oc_check_allowed type \"%s\"\n", type, 0, 0 );
/* always allow objectclass attribute */
if ( strcasecmp( type, "objectclass" ) == 0 ) {
return( 0 );
}
#ifndef SLAPD_SCHEMA_NOT_COMPAT
/* Treat any attribute type with option as an unknown attribute type */
/*
* The "type" we have received is actually an AttributeDescription.
* Let's find out the corresponding type.
*/
p = strchr( type, ';' );
if ( p ) {
t = ch_malloc( p-type+1 );
strncpy( t, type, p-type );
t[p-type] = '\0';
Debug( LDAP_DEBUG_TRACE,
"oc_check_allowed type \"%s\" from \"%s\"\n",
t, type, 0 );
} else
#endif
{
t = type;
}
/*
* All operational attributions are allowed by schema rules.
*/
if ( oc_check_op_attr( t ) ) {
return( 0 );
}
/* check that the type appears as req or opt in at least one oc */
for ( i = 0; ocl[i] != NULL; i++ ) {
/* if we know about the oc */
if ( (oc = oc_find( ocl[i]->bv_val )) != NULL ) {
/* does it require the type? */
for ( j = 0; oc->soc_required != NULL &&
oc->soc_required[j] != NULL; j++ ) {
at = oc->soc_required[j];
if ( at->sat_oid &&
strcmp(at->sat_oid, t ) == 0 ) {
if ( t != type )
ldap_memfree( t );
return( 0 );
}
pp = at->sat_names;
if ( pp == NULL )
continue;
while ( *pp ) {
if ( strcasecmp( *pp, t ) == 0 ) {
if ( t != type )
ldap_memfree( t );
return( 0 );
}
pp++;
}
}
/* does it allow the type? */
for ( j = 0; oc->soc_allowed != NULL &&
oc->soc_allowed[j] != NULL; j++ ) {
at = oc->soc_allowed[j];
if ( at->sat_oid &&
strcmp( at->sat_oid, t ) == 0 ) {
if ( t != type )
ldap_memfree( t );
return( 0 );
}
pp = at->sat_names;
if ( pp == NULL )
continue;
while ( *pp ) {
if ( strcasecmp( *pp, t ) == 0 ||
strcmp( *pp, "*" ) == 0 ) {
if ( t != type )
ldap_memfree( t );
return( 0 );
}
pp++;
}
}
/* maybe the next oc allows it */
#ifdef OC_UNDEFINED_IMPLES_EXTENSIBLE
/* we don't know about the oc. assume it allows it */
} else {
if ( t != type )
ldap_memfree( t );
return( 0 );
#endif
}
}
if ( t != type )
ldap_memfree( t );
/* not allowed by any oc */
return( 1 );
}

View File

@ -143,10 +143,10 @@ typedef int slap_syntax_transform_func LDAP_P((
typedef struct slap_syntax {
LDAP_SYNTAX ssyn_syn;
int ssyn_flags;
unsigned ssyn_flags;
#define SLAP_SYNTAX_NONE 0
#define SLAP_SYNTAX_BINARY 1
#define SLAP_SYNTAX_NONE 0x0U
#define SLAP_SYNTAX_BINARY 0x1U
slap_syntax_validate_func *ssyn_validate;
@ -210,6 +210,9 @@ typedef struct slap_matching_rule {
} MatchingRule;
typedef struct slap_attribute_type {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
char *sat_cname;
#endif
LDAP_ATTRIBUTE_TYPE sat_atype;
struct slap_attribute_type *sat_sup;
struct slap_attribute_type **sat_subtypes;
@ -235,6 +238,11 @@ typedef struct slap_attribute_type {
#define sat_usage sat_atype.at_usage
} AttributeType;
#define is_at_operational(at) ((at)->sat_usage)
#define is_at_single_value(at) ((at)->sat_single_value)
#define is_at_collective(at) ((at)->sat_collective)
#define is_at_no_user_mod(at) ((at)->sat_no_user_mod)
typedef struct slap_object_class {
LDAP_OBJECT_CLASS soc_oclass;
struct slap_object_class **soc_sups;
@ -279,6 +287,32 @@ typedef struct slap_mra {
struct berval *mra_value;
} Mra;
#ifdef SLAPD_SCHEMA_NOT_COMPAT
/*
* represents a recognized attribute description ( type + options )
*/
typedef struct slap_attr_desc {
struct berval *ad_cname; /* canonical name */
AttributeType *ad_type; /* NULL if unknown */
char *ad_lang; /* NULL if no language tags */
unsigned ad_flags;
#define SLAP_DESC_NONE 0x0U
#define SLAP_DESC_BINARY 0x1U
} AttributeDescription;
typedef struct slap_attr_assertion {
AttributeDescription aa_desc;
struct berval *aa_value;
} AttributeAssertion;
typedef struct slap_mr_assertion {
char *ma_rule; /* optional */
AttributeDescription *ma_desc; /* optional */
int ma_dnattrs; /* boolean */
struct berval *ma_value; /* required */
} MatchingRuleAssertion;
#endif
/*
* represents a search filter
*/
@ -331,14 +365,16 @@ typedef struct slap_filter {
} Filter;
/*
* represents an attribute (type + values + syntax)
* represents an attribute (description + values)
*/
typedef struct slap_attr {
#ifdef SLAPD_SCHEMA_NOT_COMPAT
AttributeDescription a_desc;
#else
char *a_type; /* description */
struct berval **a_vals;
#ifndef SLAPD_SCHEMA_NOT_COMPAT
int a_syntax;
#endif
struct berval **a_vals;
struct slap_attr *a_next;
} Attribute;

182
servers/slapd/syntax.c Normal file
View File

@ -0,0 +1,182 @@
/* syntax.c - routines to manage syntax definitions */
/* $OpenLDAP$ */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include "portable.h"
#include <stdio.h>
#include <ac/ctype.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "ldap_pvt.h"
struct sindexrec {
char *sir_name;
Syntax *sir_syn;
};
static Avlnode *syn_index = NULL;
static Syntax *syn_list = NULL;
static int
syn_index_cmp(
struct sindexrec *sir1,
struct sindexrec *sir2
)
{
return (strcmp( sir1->sir_name, sir2->sir_name ));
}
static int
syn_index_name_cmp(
char *name,
struct sindexrec *sir
)
{
return (strcmp( name, sir->sir_name ));
}
Syntax *
syn_find( const char *synname )
{
struct sindexrec *sir = NULL;
if ( (sir = (struct sindexrec *) avl_find( syn_index, synname,
(AVL_CMP) syn_index_name_cmp )) != NULL ) {
return( sir->sir_syn );
}
return( NULL );
}
Syntax *
syn_find_desc( const char *syndesc, int *len )
{
Syntax *synp;
for (synp = syn_list; synp; synp = synp->ssyn_next)
if ((*len = dscompare( synp->ssyn_syn.syn_desc, syndesc, '{')))
return synp;
return( NULL );
}
static int
syn_insert(
Syntax *ssyn,
const char **err
)
{
Syntax **synp;
struct sindexrec *sir;
synp = &syn_list;
while ( *synp != NULL ) {
synp = &(*synp)->ssyn_next;
}
*synp = ssyn;
if ( ssyn->ssyn_oid ) {
sir = (struct sindexrec *)
ch_calloc( 1, sizeof(struct sindexrec) );
sir->sir_name = ssyn->ssyn_oid;
sir->sir_syn = ssyn;
if ( avl_insert( &syn_index, (caddr_t) sir,
(AVL_CMP) syn_index_cmp,
(AVL_DUP) avl_dup_error ) ) {
*err = ssyn->ssyn_oid;
ldap_memfree(sir);
return SLAP_SCHERR_DUP_SYNTAX;
}
/* FIX: temporal consistency check */
syn_find(sir->sir_name);
}
return 0;
}
int
syn_add(
LDAP_SYNTAX *syn,
int flags,
slap_syntax_validate_func *validate,
slap_syntax_transform_func *ber2str,
slap_syntax_transform_func *str2ber,
const char **err
)
{
Syntax *ssyn;
int code;
ssyn = (Syntax *) ch_calloc( 1, sizeof(Syntax) );
memcpy( &ssyn->ssyn_syn, syn, sizeof(LDAP_SYNTAX));
ssyn->ssyn_flags = flags;
ssyn->ssyn_validate = validate;
ssyn->ssyn_ber2str = ber2str;
ssyn->ssyn_str2ber = str2ber;
code = syn_insert(ssyn,err);
return code;
}
int
register_syntax(
char * desc, int flags,
slap_syntax_validate_func *validate,
slap_syntax_transform_func *ber2str,
slap_syntax_transform_func *str2ber )
{
LDAP_SYNTAX *syn;
int code;
const char *err;
syn = ldap_str2syntax( desc, &code, &err);
if ( !syn ) {
Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s before %s in %s\n",
ldap_scherr2str(code), err, desc );
return( -1 );
}
code = syn_add( syn, flags, validate, ber2str, str2ber, &err );
if ( code ) {
Debug( LDAP_DEBUG_ANY, "Error in register_syntax: %s %s in %s\n",
scherr2str(code), err, desc );
return( -1 );
}
return( 0 );
}
#if defined( SLAPD_SCHEMA_DN )
int
syn_schema_info( Entry *e )
{
struct berval val;
struct berval *vals[2];
Syntax *syn;
vals[0] = &val;
vals[1] = NULL;
for ( syn = syn_list; syn; syn = syn->ssyn_next ) {
val.bv_val = ldap_syntax2str( &syn->ssyn_syn );
if ( val.bv_val ) {
val.bv_len = strlen( val.bv_val );
Debug( LDAP_DEBUG_TRACE, "Merging syn [%ld] %s\n",
(long) val.bv_len, val.bv_val, 0 );
attr_merge( e, "ldapSyntaxes", vals );
ldap_memfree( val.bv_val );
} else {
return -1;
}
}
return 0;
}
#endif

View File

@ -51,7 +51,8 @@ BDB2SRCS =
QUIPUSRCS = edb2ldif.c ldapsyntax.c chlog2replog.c
SLAPD_OBJS = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
../module.o ../aclparse.o ../filterentry.o \
../schema.o ../schema_init.o ../schemaparse.o \
../schema.o ../schema_check.o ../schema_init.o ../schemaparse.o \
../at.o ../mr.o ../oc.o ../syntax.o \
../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
../controls.o ../kerberos.o ../passwd.o \

View File

@ -69,7 +69,7 @@ main( int argc, char **argv )
}
/* check schema */
if ( global_schemacheck && oc_schema_check( e ) != 0 ) {
if ( schema_check_entry( e ) != 0 ) {
fprintf( stderr, "%s: schema violation in entry dn=\"%s\" (line=%d)\n",
progname, e->e_dn, lineno );
rc = EXIT_FAILURE;