mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-17 14:00:30 +08:00
First step in new schema support.
This commit is contained in:
parent
8c954245fd
commit
7f357399cf
@ -22,6 +22,10 @@
|
||||
|
||||
#include "slap.h"
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
static void at_index_print( void );
|
||||
#endif
|
||||
|
||||
void
|
||||
attr_free( Attribute *a )
|
||||
{
|
||||
@ -174,11 +178,11 @@ attr_delete(
|
||||
|
||||
#define DEFAULT_SYNTAX SYNTAX_CIS
|
||||
|
||||
/* Force compilation errors by commenting out this
|
||||
struct asyntaxinfo {
|
||||
char **asi_names;
|
||||
int asi_syntax;
|
||||
};
|
||||
|
||||
static Avlnode *attr_syntaxes = NULL;
|
||||
|
||||
static int
|
||||
@ -228,6 +232,8 @@ attr_syntax_dup(
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* attr_syntax - return the syntax of attribute type
|
||||
*/
|
||||
@ -235,14 +241,11 @@ attr_syntax_dup(
|
||||
int
|
||||
attr_syntax( char *type )
|
||||
{
|
||||
struct asyntaxinfo *asi = NULL;
|
||||
AttributeType *sat;
|
||||
|
||||
if ( (asi = (struct asyntaxinfo *) avl_find( attr_syntaxes, type,
|
||||
(AVL_CMP) attr_syntax_name_cmp )) != NULL ||
|
||||
(asi = (struct asyntaxinfo *) avl_find_lin( attr_syntaxes, type,
|
||||
(AVL_CMP) attr_syntax_names_cmp )) != NULL )
|
||||
{
|
||||
return( asi->asi_syntax );
|
||||
sat = at_find(type);
|
||||
if ( sat ) {
|
||||
return( sat->sat_syntax_compat );
|
||||
}
|
||||
|
||||
return( DEFAULT_SYNTAX );
|
||||
@ -261,8 +264,10 @@ attr_syntax_config(
|
||||
)
|
||||
{
|
||||
char *save;
|
||||
struct asyntaxinfo *a;
|
||||
LDAP_ATTRIBUTE_TYPE *at;
|
||||
int lasti;
|
||||
int code;
|
||||
char *err;
|
||||
|
||||
if ( argc < 2 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
@ -271,23 +276,30 @@ attr_syntax_config(
|
||||
return;
|
||||
}
|
||||
|
||||
a = (struct asyntaxinfo *) ch_calloc( 1, sizeof(struct asyntaxinfo) );
|
||||
at = (LDAP_ATTRIBUTE_TYPE *)
|
||||
ch_calloc( 1, sizeof(LDAP_ATTRIBUTE_TYPE) );
|
||||
|
||||
lasti = argc - 1;
|
||||
if ( strcasecmp( argv[lasti], "caseignorestring" ) == 0 ||
|
||||
strcasecmp( argv[lasti], "cis" ) == 0 ) {
|
||||
a->asi_syntax = SYNTAX_CIS;
|
||||
at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
|
||||
at->at_equality_oid = "2.5.13.2";
|
||||
} else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
|
||||
strcasecmp( argv[lasti], "tel" ) == 0 ) {
|
||||
a->asi_syntax = (SYNTAX_CIS | SYNTAX_TEL);
|
||||
at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50";
|
||||
at->at_equality_oid = "2.5.13.20";
|
||||
} else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
|
||||
a->asi_syntax = (SYNTAX_CIS | SYNTAX_DN);
|
||||
at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12";
|
||||
at->at_equality_oid = "2.5.13.1";
|
||||
} else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
|
||||
strcasecmp( argv[lasti], "ces" ) == 0 ) {
|
||||
a->asi_syntax = SYNTAX_CES;
|
||||
at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
|
||||
/* notice: this is caseExactIA5Match */
|
||||
at->at_equality_oid = "1.3.6.1.4.1.1466.109.114.1";
|
||||
} else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
|
||||
strcasecmp( argv[lasti], "bin" ) == 0 ) {
|
||||
a->asi_syntax = SYNTAX_BIN;
|
||||
at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5";
|
||||
/* There is no match for binary syntax. Really */
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: unknown syntax \"%s\" in attribute line (ignored)\n",
|
||||
@ -295,50 +307,292 @@ attr_syntax_config(
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"possible syntaxes are \"cis\", \"ces\", \"tel\", \"dn\", or \"bin\"\n",
|
||||
0, 0, 0 );
|
||||
free( (char *) a );
|
||||
free( (AttributeType *) at );
|
||||
return;
|
||||
}
|
||||
|
||||
save = argv[lasti];
|
||||
argv[lasti] = NULL;
|
||||
a->asi_names = charray_dup( argv );
|
||||
at->at_names = charray_dup( argv );
|
||||
argv[lasti] = save;
|
||||
|
||||
switch ( avl_insert( &attr_syntaxes, (caddr_t) a,
|
||||
(AVL_CMP) attr_syntax_cmp,
|
||||
(AVL_DUP) attr_syntax_dup ) ) {
|
||||
case -1: /* duplicate - different syntaxes */
|
||||
Debug( LDAP_DEBUG_ARGS, "%s: line %d: duplicate attribute\n",
|
||||
fname, lineno, 0 );
|
||||
/* FALL */
|
||||
|
||||
case 1: /* duplicate - same syntaxes */
|
||||
charray_free( a->asi_names );
|
||||
free( (char *) a );
|
||||
break;
|
||||
|
||||
default: /* inserted */
|
||||
break;
|
||||
code = at_add( at, &err );
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s %s\n",
|
||||
fname, lineno, scherr2str(code), err);
|
||||
exit( 1 );
|
||||
}
|
||||
ldap_memfree(at);
|
||||
}
|
||||
|
||||
int
|
||||
at_fake_if_needed(
|
||||
char *name
|
||||
)
|
||||
{
|
||||
char *argv[3];
|
||||
|
||||
if ( at_find( name ) ) {
|
||||
return 0;
|
||||
} else {
|
||||
argv[0] = name;
|
||||
argv[1] = "cis";
|
||||
argv[2] = NULL;
|
||||
attr_syntax_config( "implicit", 0, 2, argv );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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(
|
||||
char *name
|
||||
)
|
||||
{
|
||||
struct aindexrec *air = NULL;
|
||||
|
||||
if ( (air = (struct aindexrec *) avl_find( attr_index, name,
|
||||
(AVL_CMP) attr_index_name_cmp )) != NULL ) {
|
||||
return( air->air_at );
|
||||
}
|
||||
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,
|
||||
char **err
|
||||
)
|
||||
{
|
||||
AttributeType **atp;
|
||||
struct aindexrec *air;
|
||||
char **names;
|
||||
|
||||
atp = &attr_list;
|
||||
while ( *atp != NULL ) {
|
||||
atp = &(*atp)->sat_next;
|
||||
}
|
||||
*atp = sat;
|
||||
|
||||
if ( sat->sat_atype.at_oid ) {
|
||||
air = (struct aindexrec *)
|
||||
ch_calloc( 1, sizeof(struct aindexrec) );
|
||||
air->air_name = sat->sat_atype.at_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_atype.at_oid;
|
||||
ldap_memfree(air);
|
||||
return SLAP_SCHERR_DUP_ATTR;
|
||||
}
|
||||
/* FIX: temporal consistency check */
|
||||
at_find(air->air_name);
|
||||
}
|
||||
if ( (names = sat->sat_atype.at_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);
|
||||
return SLAP_SCHERR_DUP_ATTR;
|
||||
}
|
||||
/* FIX: temporal consistency check */
|
||||
at_find(air->air_name);
|
||||
names++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
at_add(
|
||||
LDAP_ATTRIBUTE_TYPE *at,
|
||||
char **err
|
||||
)
|
||||
{
|
||||
AttributeType *sat;
|
||||
AttributeType *sat1;
|
||||
int code;
|
||||
char *errattr;
|
||||
|
||||
if ( at->at_names && at->at_names[0] ) {
|
||||
errattr = at->at_names[0];
|
||||
} else {
|
||||
errattr = at->at_oid;
|
||||
}
|
||||
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 = errattr;
|
||||
return SLAP_SCHERR_ATTR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.15") ) {
|
||||
if ( !strcmp(at->at_equality_oid,
|
||||
"1.3.6.1.4.1.1466.109.114.1") ) {
|
||||
sat->sat_syntax_compat = SYNTAX_CES;
|
||||
} else {
|
||||
sat->sat_syntax_compat = SYNTAX_CIS;
|
||||
}
|
||||
} else if ( !strcmp(at->at_syntax_oid,
|
||||
"1.3.6.1.4.1.1466.115.121.1.50") ) {
|
||||
sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
|
||||
} else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.12") ) {
|
||||
sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
|
||||
} else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
|
||||
sat->sat_syntax_compat = SYNTAX_BIN;
|
||||
} else {
|
||||
sat->sat_syntax_compat = DEFAULT_SYNTAX;
|
||||
}
|
||||
|
||||
code = at_insert(sat,err);
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
|
||||
static int
|
||||
attr_syntax_printnode( struct asyntaxinfo *a )
|
||||
at_index_printnode( struct aindexrec *air )
|
||||
{
|
||||
int i;
|
||||
|
||||
printf( "syntax: 0x%x\n", a->asi_syntax );
|
||||
for ( i = 0; a->asi_names[i] != NULL; i++ ) {
|
||||
printf( " name: %s\n", a->asi_names[i] );
|
||||
}
|
||||
printf( "%s = %s\n", air->air_name, ldap_attributetype2str(&air->air_at->sat_atype) );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static void
|
||||
attr_syntax_print( void )
|
||||
at_index_print( void )
|
||||
{
|
||||
(void) avl_apply( attr_syntaxes, (AVL_APPLY) attr_syntax_printnode,
|
||||
printf("Printing attribute type index:\n");
|
||||
(void) avl_apply( attr_index, (AVL_APPLY) at_index_printnode,
|
||||
0, -1, AVL_INORDER );
|
||||
}
|
||||
|
||||
|
@ -150,10 +150,12 @@ bdb2i_back_db_init_internal(
|
||||
li->li_directory = DEFAULT_DB_DIRECTORY;
|
||||
|
||||
/* always index dn, id2children, objectclass (used in some searches) */
|
||||
argv[ 0 ] = "dn";
|
||||
argv[ 1 ] = "dn";
|
||||
argv[ 2 ] = NULL;
|
||||
attr_syntax_config( "ldbm dn initialization", 0, 2, argv );
|
||||
if ( !at_find( "dn" ) ) {
|
||||
argv[ 0 ] = "dn";
|
||||
argv[ 1 ] = "dn";
|
||||
argv[ 2 ] = NULL;
|
||||
attr_syntax_config( "ldbm dn initialization", 0, 2, argv );
|
||||
}
|
||||
argv[ 0 ] = "dn";
|
||||
argv[ 1 ] = "sub";
|
||||
argv[ 2 ] = "eq";
|
||||
|
@ -110,10 +110,12 @@ ldbm_back_db_init(
|
||||
li->li_directory = ch_strdup( DEFAULT_DB_DIRECTORY );
|
||||
|
||||
/* always index dn, id2children, objectclass (used in some searches) */
|
||||
argv[ 0 ] = "dn";
|
||||
argv[ 1 ] = "dn";
|
||||
argv[ 2 ] = NULL;
|
||||
attr_syntax_config( "ldbm dn initialization", 0, 2, argv );
|
||||
if ( !at_find( "dn" ) ) {
|
||||
argv[ 0 ] = "dn";
|
||||
argv[ 1 ] = "dn";
|
||||
argv[ 2 ] = NULL;
|
||||
attr_syntax_config( "ldbm dn initialization", 0, 2, argv );
|
||||
}
|
||||
argv[ 0 ] = "dn";
|
||||
argv[ 1 ] = "sub";
|
||||
argv[ 2 ] = "eq";
|
||||
|
@ -346,12 +346,24 @@ read_config( char *fname )
|
||||
#endif
|
||||
/* specify an objectclass */
|
||||
} else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) {
|
||||
parse_oc( be, fname, lineno, cargc, cargv );
|
||||
if ( *cargv[1] == '(' ) {
|
||||
char * p;
|
||||
p = strchr(line,'(');
|
||||
parse_oc( fname, lineno, p );
|
||||
} else {
|
||||
parse_oc_old( be, fname, lineno, cargc, cargv );
|
||||
}
|
||||
|
||||
/* specify an attribute */
|
||||
} else if ( strcasecmp( cargv[0], "attribute" ) == 0 ) {
|
||||
attr_syntax_config( fname, lineno, cargc - 1,
|
||||
&cargv[1] );
|
||||
if ( *cargv[1] == '(' ) {
|
||||
char * p;
|
||||
p = strchr(line,'(');
|
||||
parse_at( fname, lineno, p );
|
||||
} else {
|
||||
attr_syntax_config( fname, lineno, cargc - 1,
|
||||
&cargv[1] );
|
||||
}
|
||||
|
||||
/* turn on/off schema checking */
|
||||
} else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) {
|
||||
|
@ -46,6 +46,11 @@ Attribute * attr_find LDAP_P(( Attribute *a, char *type ));
|
||||
int attr_delete LDAP_P(( Attribute **attrs, char *type ));
|
||||
int attr_syntax LDAP_P(( char *type ));
|
||||
void attr_syntax_config LDAP_P(( char *fname, int lineno, int argc, char **argv ));
|
||||
AttributeType * at_find LDAP_P(( char *name ));
|
||||
int at_find_in_list LDAP_P(( AttributeType *sat, AttributeType **list ));
|
||||
int at_append_to_list LDAP_P(( AttributeType *sat, AttributeType ***listp ));
|
||||
int at_delete_from_list LDAP_P(( int pos, AttributeType ***listp ));
|
||||
int at_fake_if_needed LDAP_P(( char *name ));
|
||||
|
||||
/*
|
||||
* ava.c
|
||||
@ -230,12 +235,17 @@ void send_ldap_search_result LDAP_P(( Connection *conn, Operation *op, int err,
|
||||
*/
|
||||
|
||||
int oc_schema_check LDAP_P(( Entry *e ));
|
||||
ObjectClass *oc_find LDAP_P((char *ocname));
|
||||
int oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, char **err));
|
||||
|
||||
|
||||
/*
|
||||
* schemaparse.c
|
||||
*/
|
||||
|
||||
void parse_oc LDAP_P(( Backend *be, char *fname, int lineno, int argc, char **argv ));
|
||||
void parse_oc_old LDAP_P(( Backend *be, char *fname, int lineno, int argc, char **argv ));
|
||||
void parse_oc LDAP_P(( char *fname, int lineno, char * line ));
|
||||
void parse_at LDAP_P(( char *fname, int lineno, char *line ));
|
||||
|
||||
/*
|
||||
* str2filter.c
|
||||
@ -311,8 +321,8 @@ extern ldap_pvt_thread_mutex_t crypt_mutex;
|
||||
#endif
|
||||
extern ldap_pvt_thread_mutex_t gmtime_mutex;
|
||||
|
||||
extern struct acl *global_acl;
|
||||
extern struct objclass *global_oc;
|
||||
extern struct acl *global_acl;
|
||||
extern ObjectClass *global_oc;
|
||||
|
||||
extern int slap_init LDAP_P((int mode, char* name));
|
||||
extern int slap_startup LDAP_P((int dbnum));
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "slap.h"
|
||||
|
||||
static struct objclass *oc_find(char *ocname);
|
||||
static char * oc_check_required(Entry *e, char *ocname);
|
||||
static int oc_check_allowed(char *type, struct berval **ocl);
|
||||
|
||||
@ -64,9 +63,15 @@ oc_schema_check( Entry *e )
|
||||
static char *
|
||||
oc_check_required( Entry *e, char *ocname )
|
||||
{
|
||||
struct objclass *oc;
|
||||
int i;
|
||||
ObjectClass *oc;
|
||||
AttributeType *at;
|
||||
int i, j;
|
||||
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 ) {
|
||||
@ -74,23 +79,43 @@ oc_check_required( Entry *e, char *ocname )
|
||||
}
|
||||
|
||||
/* check for empty oc_required */
|
||||
if(oc->oc_required == NULL) {
|
||||
if(oc->soc_required == NULL) {
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/* for each required attribute */
|
||||
for ( i = 0; oc->oc_required[i] != NULL; i++ ) {
|
||||
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 ( strcasecmp( a->a_type, oc->oc_required[i] )
|
||||
== 0 ) {
|
||||
if ( at->sat_atype.at_oid &&
|
||||
strcmp( a->a_type, at->sat_atype.at_oid ) == 0 ) {
|
||||
break;
|
||||
}
|
||||
pp = at->sat_atype.at_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 ) {
|
||||
return oc->oc_required[i];
|
||||
if ( at->sat_atype.at_names &&
|
||||
at->sat_atype.at_names[0] ) {
|
||||
return at->sat_atype.at_names[0];
|
||||
} else {
|
||||
return at->sat_atype.at_oid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -114,8 +139,13 @@ oc_check_operational( char *type )
|
||||
static int
|
||||
oc_check_allowed( char *type, struct berval **ocl )
|
||||
{
|
||||
struct objclass *oc;
|
||||
ObjectClass *oc;
|
||||
AttributeType *at;
|
||||
int i, j;
|
||||
char **pp;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"oc_check_allowed type \"%s\"\n", type, 0, 0 );
|
||||
|
||||
/* always allow objectclass attribute */
|
||||
if ( strcasecmp( type, "objectclass" ) == 0 ) {
|
||||
@ -131,22 +161,41 @@ oc_check_allowed( char *type, struct berval **ocl )
|
||||
/* if we know about the oc */
|
||||
if ( (oc = oc_find( ocl[i]->bv_val )) != NULL ) {
|
||||
/* does it require the type? */
|
||||
for ( j = 0; oc->oc_required != NULL &&
|
||||
oc->oc_required[j] != NULL; j++ ) {
|
||||
if ( strcasecmp( oc->oc_required[j], type )
|
||||
== 0 ) {
|
||||
for ( j = 0; oc->soc_required != NULL &&
|
||||
oc->soc_required[j] != NULL; j++ ) {
|
||||
at = oc->soc_required[j];
|
||||
if ( at->sat_atype.at_oid &&
|
||||
strcmp(at->sat_atype.at_oid, type ) == 0 ) {
|
||||
return( 0 );
|
||||
}
|
||||
pp = at->sat_atype.at_names;
|
||||
if ( pp == NULL )
|
||||
continue;
|
||||
while ( *pp ) {
|
||||
if ( strcasecmp( *pp, type ) == 0 ) {
|
||||
return( 0 );
|
||||
}
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
/* does it allow the type? */
|
||||
for ( j = 0; oc->oc_allowed != NULL &&
|
||||
oc->oc_allowed[j] != NULL; j++ ) {
|
||||
if ( strcasecmp( oc->oc_allowed[j], type )
|
||||
== 0 || strcmp( oc->oc_allowed[j], "*" )
|
||||
== 0 )
|
||||
{
|
||||
for ( j = 0; oc->soc_allowed != NULL &&
|
||||
oc->soc_allowed[j] != NULL; j++ ) {
|
||||
at = oc->soc_allowed[j];
|
||||
if ( at->sat_atype.at_oid &&
|
||||
strcmp(at->sat_atype.at_oid, type ) == 0 ) {
|
||||
return( 0 );
|
||||
}
|
||||
pp = at->sat_atype.at_names;
|
||||
if ( pp == NULL )
|
||||
continue;
|
||||
while ( *pp ) {
|
||||
if ( strcasecmp( *pp, type ) == 0 ||
|
||||
strcmp( *pp, "*" ) == 0 ) {
|
||||
return( 0 );
|
||||
}
|
||||
pp++;
|
||||
}
|
||||
}
|
||||
/* maybe the next oc allows it */
|
||||
|
||||
@ -160,39 +209,271 @@ oc_check_allowed( char *type, struct berval **ocl )
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
static struct objclass *
|
||||
struct oindexrec {
|
||||
char *oir_name;
|
||||
ObjectClass *oir_oc;
|
||||
};
|
||||
|
||||
static Avlnode *oc_index = NULL;
|
||||
static AttributeType *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 *type,
|
||||
struct oindexrec *oir
|
||||
)
|
||||
{
|
||||
return (strcasecmp( type, oir->oir_name ));
|
||||
}
|
||||
|
||||
ObjectClass *
|
||||
oc_find( char *ocname )
|
||||
{
|
||||
struct objclass *oc;
|
||||
struct oindexrec *oir = NULL;
|
||||
|
||||
for ( oc = global_oc; oc != NULL; oc = oc->oc_next ) {
|
||||
if ( strcasecmp( oc->oc_name, ocname ) == 0 ) {
|
||||
return( oc );
|
||||
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,
|
||||
char **err
|
||||
)
|
||||
{
|
||||
char **attrs1;
|
||||
int nattrs;
|
||||
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;
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
static int
|
||||
oc_create_allowed(
|
||||
ObjectClass *soc,
|
||||
char **attrs,
|
||||
char **err
|
||||
)
|
||||
{
|
||||
char **attrs1;
|
||||
int nattrs;
|
||||
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 &&
|
||||
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,
|
||||
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_oclass.oc_sup_oids,
|
||||
err);
|
||||
if ( code )
|
||||
return code;
|
||||
|
||||
if ( code = oc_create_required(soc,
|
||||
soc1->soc_oclass.oc_at_oids_must,err) )
|
||||
return code;
|
||||
if ( code = oc_create_allowed(soc,
|
||||
soc1->soc_oclass.oc_at_oids_may,err) )
|
||||
return code;
|
||||
nsups++;
|
||||
sups1++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
oc_insert(
|
||||
ObjectClass *soc,
|
||||
char **err
|
||||
)
|
||||
{
|
||||
ObjectClass **ocp;
|
||||
struct oindexrec *oir;
|
||||
char **names;
|
||||
|
||||
ocp = &global_oc;
|
||||
while ( *ocp != NULL ) {
|
||||
ocp = &(*ocp)->soc_next;
|
||||
}
|
||||
*ocp = soc;
|
||||
|
||||
if ( soc->soc_oclass.oc_oid ) {
|
||||
oir = (struct oindexrec *)
|
||||
ch_calloc( 1, sizeof(struct oindexrec) );
|
||||
oir->oir_name = soc->soc_oclass.oc_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_oclass.oc_oid;
|
||||
ldap_memfree(oir);
|
||||
return SLAP_SCHERR_DUP_CLASS;
|
||||
}
|
||||
/* FIX: temporal consistency check */
|
||||
oc_find(oir->oir_name);
|
||||
}
|
||||
if ( (names = soc->soc_oclass.oc_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,
|
||||
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_oclass.oc_sup_oids,err) )
|
||||
return code;
|
||||
if ( code = oc_create_required(soc,soc->soc_oclass.oc_at_oids_must,err) )
|
||||
return code;
|
||||
if ( code = oc_create_allowed(soc,soc->soc_oclass.oc_at_oids_may,err) )
|
||||
return code;
|
||||
code = oc_insert(soc,err);
|
||||
return code;
|
||||
}
|
||||
|
||||
#ifdef LDAP_DEBUG
|
||||
|
||||
static void
|
||||
oc_print( struct objclass *oc )
|
||||
oc_print( ObjectClass *oc )
|
||||
{
|
||||
int i;
|
||||
|
||||
printf( "objectclass %s\n", oc->oc_name );
|
||||
if ( oc->oc_required != NULL ) {
|
||||
printf( "\trequires %s", oc->oc_required[0] );
|
||||
for ( i = 1; oc->oc_required[i] != NULL; i++ ) {
|
||||
printf( ",%s", oc->oc_required[i] );
|
||||
if ( oc->soc_oclass.oc_names && oc->soc_oclass.oc_names[0] ) {
|
||||
printf( "objectclass %s\n", oc->soc_oclass.oc_names[0] );
|
||||
} else {
|
||||
printf( "objectclass %s\n", oc->soc_oclass.oc_oid );
|
||||
}
|
||||
if ( oc->soc_required != NULL ) {
|
||||
printf( "\trequires %s", oc->soc_required[0] );
|
||||
for ( i = 1; oc->soc_required[i] != NULL; i++ ) {
|
||||
printf( ",%s", oc->soc_required[i] );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
if ( oc->oc_allowed != NULL ) {
|
||||
printf( "\tallows %s", oc->oc_allowed[0] );
|
||||
for ( i = 1; oc->oc_allowed[i] != NULL; i++ ) {
|
||||
printf( ",%s", oc->oc_allowed[i] );
|
||||
if ( oc->soc_allowed != NULL ) {
|
||||
printf( "\tallows %s", oc->soc_allowed[0] );
|
||||
for ( i = 1; oc->soc_allowed[i] != NULL; i++ ) {
|
||||
printf( ",%s", oc->soc_allowed[i] );
|
||||
}
|
||||
printf( "\n" );
|
||||
}
|
||||
|
@ -8,14 +8,38 @@
|
||||
#include <ac/socket.h>
|
||||
|
||||
#include "slap.h"
|
||||
#include "ldap_schema.h"
|
||||
|
||||
struct objclass *global_oc;
|
||||
ObjectClass *global_oc;
|
||||
static Avlnode *object_classes = NULL;
|
||||
|
||||
AttributeType *global_at;
|
||||
int global_schemacheck = 1; /* schemacheck on is default */
|
||||
|
||||
static void oc_usage_old(void);
|
||||
static void oc_usage(void);
|
||||
|
||||
static char *err2text[] = {
|
||||
"",
|
||||
"Out of memory",
|
||||
"Objectclass not found",
|
||||
"Attribute type not found",
|
||||
"Duplicate objectclass",
|
||||
"Duplicate attributetype"
|
||||
};
|
||||
|
||||
char *
|
||||
scherr2str(int code)
|
||||
{
|
||||
if ( code < 1 || code >= (sizeof(err2text)/sizeof(char *)) ) {
|
||||
return "Unknown error";
|
||||
} else {
|
||||
return err2text[code];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parse_oc(
|
||||
parse_oc_old(
|
||||
Backend *be,
|
||||
char *fname,
|
||||
int lineno,
|
||||
@ -25,11 +49,15 @@ parse_oc(
|
||||
{
|
||||
int i;
|
||||
char last;
|
||||
struct objclass *oc;
|
||||
struct objclass **ocp;
|
||||
LDAP_OBJECT_CLASS *oc;
|
||||
int code;
|
||||
char *err;
|
||||
char **namep;
|
||||
|
||||
oc = (struct objclass *) ch_calloc( 1, sizeof(struct objclass) );
|
||||
oc->oc_name = ch_strdup( argv[1] );
|
||||
oc = (LDAP_OBJECT_CLASS *) ch_calloc( 1, sizeof(LDAP_OBJECT_CLASS) );
|
||||
oc->oc_names = ch_calloc( 2, sizeof(char *) );
|
||||
oc->oc_names[0] = ch_strdup( argv[1] );
|
||||
oc->oc_names[1] = NULL;
|
||||
for ( i = 2; i < argc; i++ ) {
|
||||
/* required attributes */
|
||||
if ( strcasecmp( argv[i], "requires" ) == 0 ) {
|
||||
@ -38,7 +66,7 @@ parse_oc(
|
||||
if ( i < argc ) {
|
||||
char **s = str2charray( argv[i], "," );
|
||||
last = argv[i][strlen( argv[i] ) - 1];
|
||||
charray_merge( &oc->oc_required, s );
|
||||
charray_merge( &oc->oc_at_oids_must, s );
|
||||
charray_free( s );
|
||||
}
|
||||
} while ( i < argc && last == ',' );
|
||||
@ -51,7 +79,7 @@ parse_oc(
|
||||
char **s = str2charray( argv[i], "," );
|
||||
last = argv[i][strlen( argv[i] ) - 1];
|
||||
|
||||
charray_merge( &oc->oc_allowed, s );
|
||||
charray_merge( &oc->oc_at_oids_may, s );
|
||||
charray_free( s );
|
||||
}
|
||||
} while ( i < argc && last == ',' );
|
||||
@ -60,19 +88,95 @@ parse_oc(
|
||||
fprintf( stderr,
|
||||
"%s: line %d: expecting \"requires\" or \"allows\" got \"%s\"\n",
|
||||
fname, lineno, argv[i] );
|
||||
oc_usage();
|
||||
oc_usage_old();
|
||||
}
|
||||
}
|
||||
|
||||
ocp = &global_oc;
|
||||
while ( *ocp != NULL ) {
|
||||
ocp = &(*ocp)->oc_next;
|
||||
/*
|
||||
* There was no requirement in the old schema that all attributes
|
||||
* types were defined before use and they would just default to
|
||||
* SYNTAX_CIS. To support this, we need to make attribute types
|
||||
* out of thin air.
|
||||
*/
|
||||
if ( oc->oc_at_oids_must ) {
|
||||
namep = oc->oc_at_oids_must;
|
||||
while ( *namep ) {
|
||||
code = at_fake_if_needed( *namep );
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s %s\n",
|
||||
fname, lineno, scherr2str(code), *namep);
|
||||
exit( 1 );
|
||||
}
|
||||
namep++;
|
||||
}
|
||||
}
|
||||
*ocp = oc;
|
||||
if ( oc->oc_at_oids_may ) {
|
||||
namep = oc->oc_at_oids_may;
|
||||
while ( *namep ) {
|
||||
code = at_fake_if_needed( *namep );
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s %s\n",
|
||||
fname, lineno, scherr2str(code), *namep);
|
||||
exit( 1 );
|
||||
}
|
||||
namep++;
|
||||
}
|
||||
}
|
||||
|
||||
code = oc_add(oc,&err);
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s %s\n",
|
||||
fname, lineno, scherr2str(code), err);
|
||||
exit( 1 );
|
||||
}
|
||||
ldap_memfree(oc);
|
||||
}
|
||||
|
||||
void
|
||||
parse_oc(
|
||||
char *fname,
|
||||
int lineno,
|
||||
char *line
|
||||
)
|
||||
{
|
||||
LDAP_OBJECT_CLASS *oc;
|
||||
int code;
|
||||
char *err;
|
||||
|
||||
oc = ldap_str2objectclass(line,&code,&err);
|
||||
if ( !oc ) {
|
||||
fprintf( stderr, "%s: line %d: %s before %s\n",
|
||||
fname, lineno, ldap_scherr2str(code), err );
|
||||
oc_usage();
|
||||
}
|
||||
code = oc_add(oc,&err);
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s %s\n",
|
||||
fname, lineno, scherr2str(code), err);
|
||||
exit( 1 );
|
||||
}
|
||||
ldap_memfree(oc);
|
||||
}
|
||||
|
||||
static void
|
||||
oc_usage( void )
|
||||
{
|
||||
fprintf( stderr, "ObjectClassDescription = \"(\" whsp\n");
|
||||
fprintf( stderr, " numericoid whsp ; ObjectClass identifier\n");
|
||||
fprintf( stderr, " [ \"NAME\" qdescrs ]\n");
|
||||
fprintf( stderr, " [ \"DESC\" qdstring ]\n");
|
||||
fprintf( stderr, " [ \"OBSOLETE\" whsp ]\n");
|
||||
fprintf( stderr, " [ \"SUP\" oids ] ; Superior ObjectClasses\n");
|
||||
fprintf( stderr, " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n");
|
||||
fprintf( stderr, " ; default structural\n");
|
||||
fprintf( stderr, " [ \"MUST\" oids ] ; AttributeTypes\n");
|
||||
fprintf( stderr, " [ \"MAY\" oids ] ; AttributeTypes\n");
|
||||
fprintf( stderr, "whsp \")\"\n");
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
static void
|
||||
oc_usage_old( void )
|
||||
{
|
||||
fprintf( stderr, "<oc clause> ::= objectclass <ocname>\n" );
|
||||
fprintf( stderr, " [ requires <attrlist> ]\n" );
|
||||
@ -80,3 +184,54 @@ oc_usage( void )
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
static void
|
||||
at_usage( void )
|
||||
{
|
||||
fprintf( stderr, "AttributeTypeDescription = \"(\" whsp\n");
|
||||
fprintf( stderr, " numericoid whsp ; AttributeType identifier\n");
|
||||
fprintf( stderr, " [ \"NAME\" qdescrs ] ; name used in AttributeType\n");
|
||||
fprintf( stderr, " [ \"DESC\" qdstring ] ; description\n");
|
||||
fprintf( stderr, " [ \"OBSOLETE\" whsp ]\n");
|
||||
fprintf( stderr, " [ \"SUP\" woid ] ; derived from this other\n");
|
||||
fprintf( stderr, " ; AttributeType\n");
|
||||
fprintf( stderr, " [ \"EQUALITY\" woid ] ; Matching Rule name\n");
|
||||
fprintf( stderr, " [ \"ORDERING\" woid ] ; Matching Rule name\n");
|
||||
fprintf( stderr, " [ \"SUBSTR\" woid ] ; Matching Rule name\n");
|
||||
fprintf( stderr, " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n");
|
||||
fprintf( stderr, " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n");
|
||||
fprintf( stderr, " [ \"COLLECTIVE\" whsp ] ; default not collective\n");
|
||||
fprintf( stderr, " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n");
|
||||
fprintf( stderr, " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n");
|
||||
fprintf( stderr, " ; userApplications\n");
|
||||
fprintf( stderr, " ; directoryOperation\n");
|
||||
fprintf( stderr, " ; distributedOperation\n");
|
||||
fprintf( stderr, " ; dSAOperation\n");
|
||||
fprintf( stderr, "whsp \")\"\n");
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
void
|
||||
parse_at(
|
||||
char *fname,
|
||||
int lineno,
|
||||
char *line
|
||||
)
|
||||
{
|
||||
LDAP_ATTRIBUTE_TYPE *at;
|
||||
int code;
|
||||
char *err;
|
||||
|
||||
at = ldap_str2attributetype(line,&code,&err);
|
||||
if ( !at ) {
|
||||
fprintf( stderr, "%s: line %d: %s before %s\n",
|
||||
fname, lineno, ldap_scherr2str(code), err );
|
||||
at_usage();
|
||||
}
|
||||
code = at_add(at,&err);
|
||||
if ( code ) {
|
||||
fprintf( stderr, "%s: line %d: %s %s\n",
|
||||
fname, lineno, scherr2str(code), err);
|
||||
exit( 1 );
|
||||
}
|
||||
ldap_memfree(at);
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <ac/syslog.h>
|
||||
#include <ac/regex.h>
|
||||
#include <ac/socket.h> /* needed by LDAP_CONNECTIONLESS */
|
||||
#include <ldap_schema.h>
|
||||
|
||||
#include "avl.h"
|
||||
|
||||
@ -51,6 +52,12 @@
|
||||
#define SPACE(c) ((c) == ' ' || (c) == '\n')
|
||||
#define NEEDSESCAPE(c) ((c) == '\\' || (c) == '"')
|
||||
|
||||
#define SLAP_SCHERR_OUTOFMEM 1
|
||||
#define SLAP_SCHERR_CLASS_NOT_FOUND 2
|
||||
#define SLAP_SCHERR_ATTR_NOT_FOUND 3
|
||||
#define SLAP_SCHERR_DUP_CLASS 4
|
||||
#define SLAP_SCHERR_DUP_ATTR 5
|
||||
|
||||
LDAP_BEGIN_DECL
|
||||
|
||||
extern int slap_debug;
|
||||
@ -209,12 +216,32 @@ typedef struct ldapmodlist {
|
||||
* represents schema information for a database
|
||||
*/
|
||||
|
||||
struct objclass {
|
||||
char *oc_name;
|
||||
char **oc_required;
|
||||
char **oc_allowed;
|
||||
struct objclass *oc_next;
|
||||
};
|
||||
typedef struct slap_matching_rule {
|
||||
int dummy;
|
||||
} MatchingRule;
|
||||
|
||||
typedef struct slap_attribute_type {
|
||||
LDAP_ATTRIBUTE_TYPE sat_atype;
|
||||
struct slap_attribute_type *sat_sup;
|
||||
struct slap_attribute_type **sat_subtypes;
|
||||
MatchingRule *sat_equality;
|
||||
MatchingRule *sat_ordering;
|
||||
MatchingRule *sat_substr;
|
||||
/*
|
||||
Syntax *sat_syntax;
|
||||
*/
|
||||
/* The next one is created to help in the transition */
|
||||
int sat_syntax_compat;
|
||||
struct slap_attribute_type *sat_next;
|
||||
} AttributeType;
|
||||
|
||||
typedef struct slap_object_class {
|
||||
LDAP_OBJECT_CLASS soc_oclass;
|
||||
struct slap_object_class **soc_sups;
|
||||
AttributeType **soc_required;
|
||||
AttributeType **soc_allowed;
|
||||
struct slap_object_class *soc_next;
|
||||
} ObjectClass;
|
||||
|
||||
/*
|
||||
* Backend-info
|
||||
|
Loading…
Reference in New Issue
Block a user