Back to index

openldap  2.4.31
schemaparse.c
Go to the documentation of this file.
00001 /* schemaparse.c - routines to parse config file objectclass definitions */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 1998-2012 The OpenLDAP Foundation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 
00017 #include "portable.h"
00018 
00019 #include <stdio.h>
00020 
00021 #include <ac/ctype.h>
00022 #include <ac/string.h>
00023 #include <ac/socket.h>
00024 
00025 #include "slap.h"
00026 #include "ldap_schema.h"
00027 #include "config.h"
00028 
00029 static void          oc_usage(void); 
00030 static void          at_usage(void);
00031 
00032 static char *const err2text[] = {
00033        "Success",
00034        "Out of memory",
00035        "ObjectClass not found",
00036        "user-defined ObjectClass includes operational attributes",
00037        "user-defined ObjectClass has inappropriate SUPerior",
00038        "Duplicate objectClass",
00039        "Inconsistent duplicate objectClass",
00040        "AttributeType not found",
00041        "AttributeType inappropriate matching rule",
00042        "AttributeType inappropriate USAGE",
00043        "AttributeType inappropriate SUPerior",
00044        "AttributeType SYNTAX or SUPerior required",
00045        "Duplicate attributeType",
00046        "Inconsistent duplicate attributeType",
00047        "MatchingRule not found",
00048        "MatchingRule incomplete",
00049        "Duplicate matchingRule",
00050        "Syntax not found",
00051        "Duplicate ldapSyntax",
00052        "Superior syntax not found",
00053        "Substitute syntax not specified",
00054        "Substitute syntax not found",
00055        "OID or name required",
00056        "Qualifier not supported",
00057        "Invalid NAME",
00058        "OID could not be expanded",
00059        "Duplicate Content Rule",
00060        "Content Rule not for STRUCTURAL object class",
00061        "Content Rule AUX contains inappropriate object class",
00062        "Content Rule attribute type list contains duplicate",
00063        NULL
00064 };
00065 
00066 char *
00067 scherr2str(int code)
00068 {
00069        if ( code < 0 || SLAP_SCHERR_LAST <= code ) {
00070               return "Unknown error";
00071        } else {
00072               return err2text[code];
00073        }
00074 }
00075 
00076 /* check schema descr validity */
00077 int slap_valid_descr( const char *descr )
00078 {
00079        int i=0;
00080 
00081        if( !DESC_LEADCHAR( descr[i] ) ) {
00082               return 0;
00083        }
00084 
00085        while( descr[++i] ) {
00086               if( !DESC_CHAR( descr[i] ) ) {
00087                      return 0;
00088               }
00089        }
00090 
00091        return 1;
00092 }
00093 
00094 
00095 /* OID Macros */
00096 
00097 /* String compare with delimiter check. Return 0 if not
00098  * matched, otherwise return length matched.
00099  */
00100 int
00101 dscompare(const char *s1, const char *s2, char delim)
00102 {
00103        const char *orig = s1;
00104        while (*s1++ == *s2++)
00105               if (!s1[-1]) break;
00106        --s1;
00107        --s2;
00108        if (!*s1 && (!*s2 || *s2 == delim))
00109               return s1 - orig;
00110        return 0;
00111 }
00112 
00113 static void
00114 cr_usage( void )
00115 {
00116        fprintf( stderr,
00117               "DITContentRuleDescription = \"(\" whsp\n"
00118               "  numericoid whsp       ; StructuralObjectClass identifier\n"
00119               "  [ \"NAME\" qdescrs ]\n"
00120               "  [ \"DESC\" qdstring ]\n"
00121               "  [ \"OBSOLETE\" whsp ]\n"
00122               "  [ \"AUX\" oids ]      ; Auxiliary ObjectClasses\n"
00123               "  [ \"MUST\" oids ]     ; AttributeTypes\n"
00124               "  [ \"MAY\" oids ]      ; AttributeTypes\n"
00125               "  [ \"NOT\" oids ]      ; AttributeTypes\n"
00126               "  whsp \")\"\n" );
00127 }
00128 
00129 int
00130 parse_cr(
00131        struct config_args_s *c,
00132        ContentRule   **scr )
00133 {
00134        LDAPContentRule *cr;
00135        int           code;
00136        const char    *err;
00137        char *line = strchr( c->line, '(' );
00138 
00139        cr = ldap_str2contentrule( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
00140        if ( !cr ) {
00141               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
00142                      c->argv[0], ldap_scherr2str( code ), err );
00143               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00144                      "%s %s\n", c->log, c->cr_msg, 0 );
00145               cr_usage();
00146               return 1;
00147        }
00148 
00149        if ( cr->cr_oid == NULL ) {
00150               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
00151                      c->argv[0] );
00152               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00153                      "%s %s\n", c->log, c->cr_msg, 0 );
00154               cr_usage();
00155               code = 1;
00156               goto done;
00157        }
00158 
00159        code = cr_add( cr, 1, scr, &err );
00160        if ( code ) {
00161               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
00162                      c->argv[0], scherr2str(code), err);
00163               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00164                      "%s %s\n", c->log, c->cr_msg, 0 );
00165               code = 1;
00166               goto done;
00167        }
00168 
00169 done:;
00170        if ( code ) {
00171               ldap_contentrule_free( cr );
00172 
00173        } else {
00174               ldap_memfree( cr );
00175        }
00176 
00177        return code;
00178 }
00179 
00180 int
00181 parse_oc(
00182        struct config_args_s *c,
00183        ObjectClass   **soc,
00184        ObjectClass *prev )
00185 {
00186        LDAPObjectClass *oc;
00187        int           code;
00188        const char    *err;
00189        char *line = strchr( c->line, '(' );
00190 
00191        oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
00192        if ( !oc ) {
00193               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
00194                      c->argv[0], ldap_scherr2str( code ), err );
00195               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00196                      "%s %s\n", c->log, c->cr_msg, 0 );
00197               oc_usage();
00198               return 1;
00199        }
00200 
00201        if ( oc->oc_oid == NULL ) {
00202               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
00203                      c->argv[0] );
00204               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00205                      "%s %s\n", c->log, c->cr_msg, 0 );
00206               oc_usage();
00207               code = 1;
00208               goto done;
00209        }
00210 
00211        code = oc_add( oc, 1, soc, prev, &err );
00212        if ( code ) {
00213               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
00214                      c->argv[0], scherr2str(code), err);
00215               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00216                      "%s %s\n", c->log, c->cr_msg, 0 );
00217               code = 1;
00218               goto done;
00219        }
00220 
00221 done:;
00222        if ( code ) {
00223               ldap_objectclass_free( oc );
00224 
00225        } else {
00226               ldap_memfree( oc );
00227        }
00228 
00229        return code;
00230 }
00231 
00232 static void
00233 oc_usage( void )
00234 {
00235        fprintf( stderr,
00236               "ObjectClassDescription = \"(\" whsp\n"
00237               "  numericoid whsp                 ; ObjectClass identifier\n"
00238               "  [ \"NAME\" qdescrs ]\n"
00239               "  [ \"DESC\" qdstring ]\n"
00240               "  [ \"OBSOLETE\" whsp ]\n"
00241               "  [ \"SUP\" oids ]                ; Superior ObjectClasses\n"
00242               "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
00243               "                                  ; default structural\n"
00244               "  [ \"MUST\" oids ]               ; AttributeTypes\n"
00245               "  [ \"MAY\" oids ]                ; AttributeTypes\n"
00246               "  whsp \")\"\n" );
00247 }
00248 
00249 static void
00250 at_usage( void )
00251 {
00252        fprintf( stderr, "%s%s%s",
00253               "AttributeTypeDescription = \"(\" whsp\n"
00254               "  numericoid whsp      ; AttributeType identifier\n"
00255               "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n"
00256               "  [ \"DESC\" qdstring ]            ; description\n"
00257               "  [ \"OBSOLETE\" whsp ]\n"
00258               "  [ \"SUP\" woid ]                 ; derived from this other\n"
00259               "                                   ; AttributeType\n",
00260               "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n"
00261               "  [ \"ORDERING\" woid ]            ; Matching Rule name\n"
00262               "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n"
00263               "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
00264               "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n"
00265               "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n",
00266               "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
00267               "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
00268               "                                   ; userApplications\n"
00269               "                                   ; directoryOperation\n"
00270               "                                   ; distributedOperation\n"
00271               "                                   ; dSAOperation\n"
00272               "  whsp \")\"\n");
00273 }
00274 
00275 int
00276 parse_at(
00277        struct config_args_s *c,
00278        AttributeType **sat,
00279        AttributeType *prev )
00280 {
00281        LDAPAttributeType *at;
00282        int           code;
00283        const char    *err;
00284        char *line = strchr( c->line, '(' );
00285 
00286        at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
00287        if ( !at ) {
00288               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
00289                      c->argv[0], ldap_scherr2str(code), err );
00290               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00291                      "%s %s\n", c->log, c->cr_msg, 0 );
00292               at_usage();
00293               return 1;
00294        }
00295 
00296        if ( at->at_oid == NULL ) {
00297               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
00298                      c->argv[0] );
00299               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00300                      "%s %s\n", c->log, c->cr_msg, 0 );
00301               at_usage();
00302               code = 1;
00303               goto done;
00304        }
00305 
00306        /* operational attributes should be defined internally */
00307        if ( at->at_usage ) {
00308               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: \"%s\" is operational",
00309                      c->argv[0], at->at_oid );
00310               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00311                      "%s %s\n", c->log, c->cr_msg, 0 );
00312               code = 1;
00313               goto done;
00314        }
00315 
00316        code = at_add( at, 1, sat, prev, &err);
00317        if ( code ) {
00318               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
00319                      c->argv[0], scherr2str(code), err);
00320               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00321                      "%s %s\n", c->log, c->cr_msg, 0 );
00322               code = 1;
00323               goto done;
00324        }
00325 
00326 done:;
00327        if ( code ) {
00328               ldap_attributetype_free( at );
00329 
00330        } else {
00331               ldap_memfree( at );
00332        }
00333 
00334        return code;
00335 }
00336 
00337 static void
00338 syn_usage( void )
00339 {
00340        fprintf( stderr, "%s",
00341               "SyntaxDescription = \"(\" whsp\n"
00342               "  numericoid whsp                  ; object identifier\n"
00343               "  [ whsp \"DESC\" whsp qdstring ]  ; description\n"
00344               "  extensions whsp \")\"            ; extensions\n"
00345               "  whsp \")\"\n");
00346 }
00347 
00348 int
00349 parse_syn(
00350        struct config_args_s *c,
00351        Syntax **ssyn,
00352        Syntax *prev )
00353 {
00354        LDAPSyntax           *syn;
00355        slap_syntax_defs_rec def = { 0 };
00356        int                  code;
00357        const char           *err;
00358        char                 *line = strchr( c->line, '(' );
00359 
00360        syn = ldap_str2syntax( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
00361        if ( !syn ) {
00362               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
00363                      c->argv[0], ldap_scherr2str(code), err );
00364               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00365                      "%s %s\n", c->log, c->cr_msg, 0 );
00366               syn_usage();
00367               return 1;
00368        }
00369 
00370        if ( syn->syn_oid == NULL ) {
00371               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
00372                      c->argv[0] );
00373               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00374                      "%s %s\n", c->log, c->cr_msg, 0 );
00375               syn_usage();
00376               code = 1;
00377               goto done;
00378        }
00379 
00380        code = syn_add( syn, 1, &def, ssyn, prev, &err );
00381        if ( code ) {
00382               snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
00383                      c->argv[0], scherr2str(code), err);
00384               Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
00385                      "%s %s\n", c->log, c->cr_msg, 0 );
00386               code = 1;
00387               goto done;
00388        }
00389 
00390 done:;
00391        if ( code ) {
00392               ldap_syntax_free( syn );
00393 
00394        } else {
00395               ldap_memfree( syn );
00396        }
00397 
00398        return code;
00399 }
00400