X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fschemaparse.c;h=f802f1ad59a541ee2cc774fb9746ca62aa435911;hb=f96e6378d6cd06c744a47af5e5e551cbb494826a;hp=385f8f6ab1b1f51592bec436d912954de5b3db81;hpb=ae4c85b84f5537194f3fb4dbf11776043df203fc;p=openldap diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c index 385f8f6ab1..f802f1ad59 100644 --- a/servers/slapd/schemaparse.c +++ b/servers/slapd/schemaparse.c @@ -1,238 +1,318 @@ /* schemaparse.c - routines to parse config file objectclass definitions */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2006 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ #include "portable.h" #include +#include #include #include #include "slap.h" #include "ldap_schema.h" -static Avlnode *object_classes = NULL; +static void oc_usage(void); +static void at_usage(void); -int global_schemacheck = 1; /* schemacheck on is default */ - -static void oc_usage_old(void); -static void oc_usage(void); - -static char *err2text[] = { - "", +static char *const err2text[] = { + "Success", "Out of memory", - "Objectclass not found", - "Attribute type not found", - "Duplicate objectclass", - "Duplicate attributetype" + "ObjectClass not found", + "user-defined ObjectClass includes operational attributes", + "user-defined ObjectClass has inappropriate SUPerior", + "Duplicate objectClass", + "Inconsistent duplicate objectClass", + "AttributeType not found", + "AttributeType inappropriate matching rule", + "AttributeType inappropriate USAGE", + "AttributeType inappropriate SUPerior", + "AttributeType SYNTAX or SUPerior required", + "Duplicate attributeType", + "Inconsistent duplicate attributeType", + "MatchingRule not found", + "MatchingRule incomplete", + "Duplicate matchingRule", + "Syntax not found", + "Duplicate ldapSyntax", + "OID or name required", + "Qualifier not supported", + "Invalid NAME", + "OID could not be expanded", + "Duplicate Content Rule", + "Content Rule not for STRUCTURAL object class", + "Content Rule AUX contains inappropriate object class", + "Content Rule attribute type list contains duplicate", + NULL }; char * scherr2str(int code) { - if ( code < 1 || code >= (sizeof(err2text)/sizeof(char *)) ) { + if ( code < 0 || SLAP_SCHERR_LAST <= code ) { return "Unknown error"; } else { return err2text[code]; } } -void -parse_oc_old( - Backend *be, - char *fname, - int lineno, - int argc, - char **argv -) +/* check schema descr validity */ +int slap_valid_descr( const char *descr ) { - int i; - char last; - LDAP_OBJECT_CLASS *oc; - int code; - char *err; - char **namep; - - 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; - if ( strcasecmp( oc->oc_names[0], "top" ) ) { - oc->oc_kind = LDAP_SCHEMA_STRUCTURAL; - } - for ( i = 2; i < argc; i++ ) { - /* required attributes */ - if ( strcasecmp( argv[i], "requires" ) == 0 ) { - do { - i++; - if ( i < argc ) { - char **s = str2charray( argv[i], "," ); - last = argv[i][strlen( argv[i] ) - 1]; - charray_merge( &oc->oc_at_oids_must, s ); - charray_free( s ); - } - } while ( i < argc && last == ',' ); - - /* optional attributes */ - } else if ( strcasecmp( argv[i], "allows" ) == 0 ) { - do { - i++; - if ( i < argc ) { - char **s = str2charray( argv[i], "," ); - last = argv[i][strlen( argv[i] ) - 1]; - - charray_merge( &oc->oc_at_oids_may, s ); - charray_free( s ); - } - } while ( i < argc && last == ',' ); - - } else { - fprintf( stderr, - "%s: line %d: expecting \"requires\" or \"allows\" got \"%s\"\n", - fname, lineno, argv[i] ); - oc_usage_old(); - } + int i=0; + + if( !DESC_LEADCHAR( descr[i] ) ) { + return 0; } - /* - * 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++; + while( descr[++i] ) { + if( !DESC_CHAR( descr[i] ) ) { + return 0; } } - 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++; - } + + return 1; +} + + +/* OID Macros */ + +/* String compare with delimiter check. Return 0 if not + * matched, otherwise return length matched. + */ +int +dscompare(const char *s1, const char *s2, char delim) +{ + const char *orig = s1; + while (*s1++ == *s2++) + if (!s1[-1]) break; + --s1; + --s2; + if (!*s1 && (!*s2 || *s2 == delim)) + return s1 - orig; + return 0; +} + +static void +cr_usage( void ) +{ + fprintf( stderr, + "DITContentRuleDescription = \"(\" whsp\n" + " numericoid whsp ; StructuralObjectClass identifier\n" + " [ \"NAME\" qdescrs ]\n" + " [ \"DESC\" qdstring ]\n" + " [ \"OBSOLETE\" whsp ]\n" + " [ \"AUX\" oids ] ; Auxiliary ObjectClasses\n" + " [ \"MUST\" oids ] ; AttributeTypes\n" + " [ \"MAY\" oids ] ; AttributeTypes\n" + " [ \"NOT\" oids ] ; AttributeTypes\n" + " whsp \")\"\n" ); +} + +int +parse_cr( + const char *fname, + int lineno, + char *line, + char **argv, + ContentRule **scr ) +{ + LDAPContentRule *cr; + int code; + const char *err; + + cr = ldap_str2contentrule( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); + if ( !cr ) { + fprintf( stderr, "%s: line %d: %s before %s\n", + fname, lineno, ldap_scherr2str(code), err ); + cr_usage(); + return 1; } - - code = oc_add(oc,&err); + + if ( cr->cr_oid == NULL ) { + fprintf( stderr, + "%s: line %d: Content rule has no OID\n", + fname, lineno ); + cr_usage(); + code = 1; + goto done; + } + + code = cr_add( cr, 1, scr, &err ); if ( code ) { - fprintf( stderr, "%s: line %d: %s %s\n", - fname, lineno, scherr2str(code), err); - exit( 1 ); + fprintf( stderr, "%s: line %d: %s: \"%s\"\n", + fname, lineno, scherr2str( code ), err ); + code = 1; + goto done; } - ldap_memfree(oc); + +done:; + if ( code ) { + ldap_contentrule_free( cr ); + + } else { + ldap_memfree( cr ); + } + + return code; } -void +int parse_oc( - char *fname, - int lineno, - char *line -) + const char *fname, + int lineno, + char *line, + char **argv, + ObjectClass **soc ) { - LDAP_OBJECT_CLASS *oc; + LDAPObjectClass *oc; int code; - char *err; + const char *err; - oc = ldap_str2objectclass(line,&code,&err); + oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); if ( !oc ) { fprintf( stderr, "%s: line %d: %s before %s\n", - fname, lineno, ldap_scherr2str(code), err ); + fname, lineno, ldap_scherr2str( code ), err ); + oc_usage(); + return 1; + } + + if ( oc->oc_oid == NULL ) { + fprintf( stderr, + "%s: line %d: objectclass has no OID\n", + fname, lineno ); oc_usage(); + code = 1; + goto done; } - code = oc_add(oc,&err); + + code = oc_add( oc, 1, soc, &err ); if ( code ) { - fprintf( stderr, "%s: line %d: %s %s\n", - fname, lineno, scherr2str(code), err); - exit( 1 ); + fprintf( stderr, "%s: line %d: %s: \"%s\"\n", + fname, lineno, scherr2str( code ), err ); + code = 1; + goto done; } - 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 ); +done:; + if ( code ) { + ldap_objectclass_free( oc ); + + } else { + ldap_memfree( oc ); + } + + return code; } static void -oc_usage_old( void ) +oc_usage( void ) { - fprintf( stderr, " ::= objectclass \n" ); - fprintf( stderr, " [ requires ]\n" ); - fprintf( stderr, " [ allows ]\n" ); - exit( 1 ); + fprintf( stderr, + "ObjectClassDescription = \"(\" whsp\n" + " numericoid whsp ; ObjectClass identifier\n" + " [ \"NAME\" qdescrs ]\n" + " [ \"DESC\" qdstring ]\n" + " [ \"OBSOLETE\" whsp ]\n" + " [ \"SUP\" oids ] ; Superior ObjectClasses\n" + " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n" + " ; default structural\n" + " [ \"MUST\" oids ] ; AttributeTypes\n" + " [ \"MAY\" oids ] ; AttributeTypes\n" + " whsp \")\"\n" ); } 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 ); + fprintf( stderr, "%s%s%s", + "AttributeTypeDescription = \"(\" whsp\n" + " numericoid whsp ; AttributeType identifier\n" + " [ \"NAME\" qdescrs ] ; name used in AttributeType\n" + " [ \"DESC\" qdstring ] ; description\n" + " [ \"OBSOLETE\" whsp ]\n" + " [ \"SUP\" woid ] ; derived from this other\n" + " ; AttributeType\n", + " [ \"EQUALITY\" woid ] ; Matching Rule name\n" + " [ \"ORDERING\" woid ] ; Matching Rule name\n" + " [ \"SUBSTR\" woid ] ; Matching Rule name\n" + " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n" + " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n" + " [ \"COLLECTIVE\" whsp ] ; default not collective\n", + " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n" + " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n" + " ; userApplications\n" + " ; directoryOperation\n" + " ; distributedOperation\n" + " ; dSAOperation\n" + " whsp \")\"\n"); } -void +int parse_at( - char *fname, - int lineno, - char *line -) + const char *fname, + int lineno, + char *line, + char **argv, + AttributeType **sat ) { - LDAP_ATTRIBUTE_TYPE *at; + LDAPAttributeType *at; int code; - char *err; + const char *err; - at = ldap_str2attributetype(line,&code,&err); + at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL ); if ( !at ) { fprintf( stderr, "%s: line %d: %s before %s\n", fname, lineno, ldap_scherr2str(code), err ); at_usage(); + return 1; + } + + if ( at->at_oid == NULL ) { + fprintf( stderr, + "%s: line %d: attributeType has no OID\n", + fname, lineno ); + at_usage(); + code = 1; + goto done; + } + + /* operational attributes should be defined internally */ + if ( at->at_usage ) { + fprintf( stderr, "%s: line %d: attribute type \"%s\" is operational\n", + fname, lineno, at->at_oid ); + code = 1; + goto done; } - code = at_add(at,&err); + + code = at_add( at, 1, sat, &err); if ( code ) { - fprintf( stderr, "%s: line %d: %s %s\n", + fprintf( stderr, "%s: line %d: %s: \"%s\"\n", fname, lineno, scherr2str(code), err); - exit( 1 ); + code = 1; + goto done; } - ldap_memfree(at); + +done:; + if ( code ) { + ldap_attributetype_free( at ); + + } else { + ldap_memfree( at ); + } + + return code; }