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)
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)
/* 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;
}
}
--- /dev/null
+/* $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
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 );
}
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;
return tmp;
}
+#ifndef SLAPD_SCHEMA_NOT_COMPAT
/*
* attr_normalize - normalize an attribute name (make it all lowercase)
*/
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
{
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;
return( value_add_fast( &(**a)->a_vals, vals, nvals, naddvals,
maxvals ) );
}
+#endif
/*
* attr_merge - merge the given type and value with the list of
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;
}
}
/*
- * 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 );
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 ) {
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
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 );
}
/* 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 );
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",
#include "slap.h"
#include "back-ldbm.h"
+
static int change_value(Backend *be,
DBCache *db,
char *type,
/* 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 );
}
/* 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,
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 );
}
#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
/* 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 );
}
}
# End Source File
# Begin Source File
+SOURCE=.\at.c
+# End Source File
+# Begin Source File
+
SOURCE=.\attr.c
# End Source File
# Begin Source File
# 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
# 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
# End Source File
# Begin Source File
+SOURCE=.\syntax.c
+# End Source File
+# Begin Source File
+
SOURCE=.\unbind.c
# End Source File
# Begin Source File
--- /dev/null
+/* 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
--- /dev/null
+/* 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
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
));
#endif
-#ifdef SLAPD_SCHEMA_DN
-/* temporary extern for temporary routine*/
-LIBSLAPD_F (Attribute *) backend_subschemasubentry( Backend * );
-#endif
+LIBSLAPD_F (Attribute *) backend_operational( Backend *, Entry * );
+
/*
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 ));
#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
)
{
BerElement *ber;
- Attribute *a;
+ Attribute *a, *aa;
int i, rc=-1, bytes;
char *edn;
int userattrs;
: 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,
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;
}
}
}
-#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,
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;
}
NULL, "encode end error", NULL, NULL );
goto error_return;
}
- } while (0);
-#endif
+ }
+
+ attrs_free( aa );
rc = ber_printf( ber, /*{{{*/ "}}}" );
-/* schema.c - routines to enforce schema definitions */
+/* schema.c - routines to manage schema definitions */
/* $OpenLDAP$ */
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
#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);
-
-/*
- * oc_check - check that entry e conforms to the schema required by
- * its object class(es). returns 0 if so, non-zero otherwise.
- */
-
-int
-oc_schema_check( Entry *e )
-{
- Attribute *a, *aoc;
- ObjectClass *oc;
- int i;
- int ret = 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 ) {
- 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;
- }
- }
-
- return( ret );
-}
-
-static char *
-oc_check_required( Entry *e, char *ocname )
-{
- ObjectClass *oc;
- AttributeType *at;
- int i;
- Attribute *a;
- char **pp;
-
- 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 ) {
- 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;
- }
- }
- /* 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 );
-}
-
-
-#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;
-}
-
-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;
-}
-
-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_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 );
-}
-
-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 )
-static 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;
-}
-
-static 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;
-}
-
-static 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;
-}
-
void
schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
{
free( rdn );
}
- if ( syn_schema_info( e ) ) {
- /* Out of memory, do something about it */
- entry_free( e );
- return;
- }
- if ( mr_schema_info( e ) ) {
- /* Out of memory, do something about it */
- entry_free( e );
- return;
- }
- if ( at_schema_info( e ) ) {
- /* Out of memory, do something about it */
- entry_free( e );
- return;
- }
- if ( oc_schema_info( e ) ) {
+ if ( syn_schema_info( e )
+ || mr_schema_info( e )
+ || at_schema_info( e )
+ || oc_schema_info( e ) )
+ {
/* Out of memory, do something about it */
entry_free( e );
+ send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
+ NULL, NULL, NULL, NULL );
return;
}
}
#endif
-#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
-
-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;
-}
--- /dev/null
+/* 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 );
+}
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;
} 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;
#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;
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
*/
} 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;
--- /dev/null
+/* 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
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 \
}
/* 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;