X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fschema.c;h=72e4618876d365e19160171425cd64906a0003ee;hb=427f4ee0f66cac081a712e4ccc08609813b17fdc;hp=894b09de4a856304d072640cd1160c1e03300b96;hpb=256f5bbe57c7607f0d224adda2f175bffaed8eaf;p=openldap diff --git a/libraries/libldap/schema.c b/libraries/libldap/schema.c index 894b09de4a..72e4618876 100644 --- a/libraries/libldap/schema.c +++ b/libraries/libldap/schema.c @@ -1,8 +1,18 @@ /* $OpenLDAP$ */ -/* - * Copyright 1999-2002 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2010 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 + * . */ + /* * schema.c: parsing routines used by servers and clients to process * schema definitions @@ -20,6 +30,8 @@ #include +static const char EndOfInput[] = "end of input"; + static const char * choose_name( char *names[], const char *fallback ) { @@ -949,26 +961,23 @@ ldap_attributetype2bv( LDAPAttributeType * at, struct berval *bv ) * interpretation of the specs). */ -#define TK_NOENDQUOTE -2 -#define TK_OUTOFMEM -1 -#define TK_EOS 0 -#define TK_UNEXPCHAR 1 -#define TK_BAREWORD 2 -#define TK_QDSTRING 3 -#define TK_LEFTPAREN 4 -#define TK_RIGHTPAREN 5 -#define TK_DOLLAR 6 -#define TK_QDESCR TK_QDSTRING - -struct token { - int type; - char *sval; -}; - -static int +typedef enum tk_t { + TK_NOENDQUOTE = -2, + TK_OUTOFMEM = -1, + TK_EOS = 0, + TK_UNEXPCHAR = 1, + TK_BAREWORD = 2, + TK_QDSTRING = 3, + TK_LEFTPAREN = 4, + TK_RIGHTPAREN = 5, + TK_DOLLAR = 6, + TK_QDESCR = TK_QDSTRING +} tk_t; + +static tk_t get_token( const char ** sp, char ** token_val ) { - int kind; + tk_t kind; const char * p; const char * q; char * res; @@ -1020,6 +1029,9 @@ get_token( const char ** sp, char ** token_val ) **sp != ')' && **sp != '$' && **sp != '\'' && + /* for suggested minimum upper bound on the number + * of characters (RFC 4517) */ + **sp != '{' && **sp != '\0' ) (*sp)++; q = *sp; @@ -1140,7 +1152,7 @@ parse_qdescrs(const char **sp, int *code) { char ** res; char ** res1; - int kind; + tk_t kind; char * sval; int size; int pos; @@ -1173,8 +1185,8 @@ parse_qdescrs(const char **sp, int *code) } res = res1; } - res[pos] = sval; - pos++; + res[pos++] = sval; + res[pos] = NULL; parse_whsp(sp); } else { LDAP_VFREE(res); @@ -1183,7 +1195,6 @@ parse_qdescrs(const char **sp, int *code) return(NULL); } } - res[pos] = NULL; parse_whsp(sp); return(res); } else if ( kind == TK_QDESCR ) { @@ -1208,7 +1219,7 @@ static char * parse_woid(const char **sp, int *code) { char * sval; - int kind; + tk_t kind; parse_whsp(sp); kind = get_token(sp, &sval); @@ -1223,10 +1234,13 @@ parse_woid(const char **sp, int *code) /* Parse a noidlen */ static char * -parse_noidlen(const char **sp, int *code, int *len, int allow_quoted) +parse_noidlen(const char **sp, int *code, int *len, int flags) { char * sval; + const char *savepos; int quoted = 0; + int allow_quoted = ( flags & LDAP_SCHEMA_ALLOW_QUOTED ); + int allow_oidmacro = ( flags & LDAP_SCHEMA_ALLOW_OID_MACRO ); *len = 0; /* Netscape puts the SYNTAX value in quotes (incorrectly) */ @@ -1234,9 +1248,22 @@ parse_noidlen(const char **sp, int *code, int *len, int allow_quoted) quoted = 1; (*sp)++; } + savepos = *sp; sval = ldap_int_parse_numericoid(sp, code, 0); if ( !sval ) { - return NULL; + if ( allow_oidmacro + && *sp == savepos + && *code == LDAP_SCHERR_NODIGIT ) + { + if ( get_token(sp, &sval) != TK_BAREWORD ) { + if ( sval != NULL ) { + LDAP_FREE(sval); + } + return NULL; + } + } else { + return NULL; + } } if ( **sp == '{' /*}*/ ) { (*sp)++; @@ -1275,7 +1302,7 @@ parse_oids(const char **sp, int *code, const int allow_quoted) { char ** res; char ** res1; - int kind; + tk_t kind; char * sval; int size; int pos; @@ -1301,8 +1328,13 @@ parse_oids(const char **sp, int *code, const int allow_quoted) kind = get_token(sp,&sval); if ( kind == TK_BAREWORD || ( allow_quoted && kind == TK_QDSTRING ) ) { - res[pos] = sval; - pos++; + res[pos++] = sval; + res[pos] = NULL; + } else if ( kind == TK_RIGHTPAREN ) { + /* FIXME: be liberal in what we accept... */ + parse_whsp(sp); + LDAP_FREE(res); + return NULL; } else { *code = LDAP_SCHERR_UNEXPTOKEN; LDAP_FREE(sval); @@ -1331,8 +1363,8 @@ parse_oids(const char **sp, int *code, const int allow_quoted) } res = res1; } - res[pos] = sval; - pos++; + res[pos++] = sval; + res[pos] = NULL; } else { *code = LDAP_SCHERR_UNEXPTOKEN; LDAP_FREE(sval); @@ -1347,7 +1379,6 @@ parse_oids(const char **sp, int *code, const int allow_quoted) return NULL; } } - res[pos] = NULL; parse_whsp(sp); return(res); } else if ( kind == TK_BAREWORD || @@ -1385,16 +1416,20 @@ add_extension(LDAPSchemaExtensionItem ***extensions, if ( !*extensions ) { *extensions = LDAP_CALLOC(2, sizeof(LDAPSchemaExtensionItem *)); - if ( !*extensions ) - return 1; + if ( !*extensions ) { + LDAP_FREE( ext ); + return 1; + } n = 0; } else { for ( n=0; (*extensions)[n] != NULL; n++ ) ; tmp = LDAP_REALLOC(*extensions, (n+2)*sizeof(LDAPSchemaExtensionItem *)); - if ( !tmp ) + if ( !tmp ) { + LDAP_FREE( ext ); return 1; + } *extensions = tmp; } (*extensions)[n] = ext; @@ -1433,7 +1468,7 @@ ldap_str2syntax( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -1481,13 +1516,13 @@ ldap_str2syntax( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_syntax_free(syn); return NULL; case TK_RIGHTPAREN: return syn; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -1504,7 +1539,7 @@ ldap_str2syntax( LDAP_CONST char * s, ldap_syntax_free(syn); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -1575,7 +1610,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -1617,11 +1652,11 @@ ldap_str2matchingrule( LDAP_CONST char * s, ss = savepos; kind = get_token(&ss,&sval); if ( kind == TK_BAREWORD ) { - if ( !strcmp(sval, "NAME") || - !strcmp(sval, "DESC") || - !strcmp(sval, "OBSOLETE") || - !strcmp(sval, "SYNTAX") || - !strncmp(sval, "X-", 2) ) { + if ( !strcasecmp(sval, "NAME") || + !strcasecmp(sval, "DESC") || + !strcasecmp(sval, "OBSOLETE") || + !strcasecmp(sval, "SYNTAX") || + !strncasecmp(sval, "X-", 2) ) { /* Missing OID, backtrack */ ss = savepos; } else { @@ -1646,7 +1681,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_matchingrule_free(mr); return NULL; case TK_RIGHTPAREN: @@ -1657,7 +1692,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, } return mr; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -1674,7 +1709,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, ldap_matchingrule_free(mr); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -1694,7 +1729,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, } mr->mr_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -1705,7 +1740,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, seen_obsolete = 1; mr->mr_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"SYNTAX") ) { + } else if ( !strcasecmp(sval,"SYNTAX") ) { LDAP_FREE(sval); if ( seen_syntax ) { *code = LDAP_SCHERR_DUPOPT; @@ -1774,7 +1809,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -1816,11 +1851,11 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, ss = savepos; kind = get_token(&ss,&sval); if ( kind == TK_BAREWORD ) { - if ( !strcmp(sval, "NAME") || - !strcmp(sval, "DESC") || - !strcmp(sval, "OBSOLETE") || - !strcmp(sval, "APPLIES") || - !strncmp(sval, "X-", 2) ) { + if ( !strcasecmp(sval, "NAME") || + !strcasecmp(sval, "DESC") || + !strcasecmp(sval, "OBSOLETE") || + !strcasecmp(sval, "APPLIES") || + !strncasecmp(sval, "X-", 2) ) { /* Missing OID, backtrack */ ss = savepos; } else { @@ -1845,7 +1880,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_matchingruleuse_free(mru); return NULL; case TK_RIGHTPAREN: @@ -1856,7 +1891,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, } return mru; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -1873,7 +1908,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, ldap_matchingruleuse_free(mru); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -1893,7 +1928,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, } mru->mru_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -1904,7 +1939,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, seen_obsolete = 1; mru->mru_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"APPLIES") ) { + } else if ( !strcasecmp(sval,"APPLIES") ) { LDAP_FREE(sval); if ( seen_applies ) { *code = LDAP_SCHERR_DUPOPT; @@ -1916,7 +1951,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, mru->mru_applies_oids = parse_oids(&ss, code, flags); - if ( !mru->mru_applies_oids ) { + if ( !mru->mru_applies_oids && *code != LDAP_SUCCESS ) { *errp = ss; ldap_matchingruleuse_free(mru); return NULL; @@ -1976,7 +2011,7 @@ ldap_str2attributetype( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -2027,28 +2062,31 @@ ldap_str2attributetype( LDAP_CONST char * s, if ( !at->at_oid ) { if ( ( flags & ( LDAP_SCHEMA_ALLOW_NO_OID | LDAP_SCHEMA_ALLOW_OID_MACRO ) ) - && (ss == savepos) ) { + && (ss == savepos) ) + { /* Backtracking */ ss = savepos; kind = get_token(&ss,&sval); if ( kind == TK_BAREWORD ) { - if ( !strcmp(sval, "NAME") || - !strcmp(sval, "DESC") || - !strcmp(sval, "OBSOLETE") || - !strcmp(sval, "SUP") || - !strcmp(sval, "EQUALITY") || - !strcmp(sval, "ORDERING") || - !strcmp(sval, "SUBSTR") || - !strcmp(sval, "SYNTAX") || - !strcmp(sval, "SINGLE-VALUE") || - !strcmp(sval, "COLLECTIVE") || - !strcmp(sval, "NO-USER-MODIFICATION") || - !strcmp(sval, "USAGE") || - !strncmp(sval, "X-", 2) ) { + if ( !strcasecmp(sval, "NAME") || + !strcasecmp(sval, "DESC") || + !strcasecmp(sval, "OBSOLETE") || + !strcasecmp(sval, "SUP") || + !strcasecmp(sval, "EQUALITY") || + !strcasecmp(sval, "ORDERING") || + !strcasecmp(sval, "SUBSTR") || + !strcasecmp(sval, "SYNTAX") || + !strcasecmp(sval, "SINGLE-VALUE") || + !strcasecmp(sval, "COLLECTIVE") || + !strcasecmp(sval, "NO-USER-MODIFICATION") || + !strcasecmp(sval, "USAGE") || + !strncasecmp(sval, "X-", 2) ) + { /* Missing OID, backtrack */ ss = savepos; } else if ( flags - & LDAP_SCHEMA_ALLOW_OID_MACRO) { + & LDAP_SCHEMA_ALLOW_OID_MACRO) + { /* Non-numerical OID ... */ int len = ss-savepos; at->at_oid = LDAP_MALLOC(len+1); @@ -2074,13 +2112,13 @@ ldap_str2attributetype( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_attributetype_free(at); return NULL; case TK_RIGHTPAREN: return at; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -2097,7 +2135,7 @@ ldap_str2attributetype( LDAP_CONST char * s, ldap_attributetype_free(at); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -2117,7 +2155,7 @@ ldap_str2attributetype( LDAP_CONST char * s, } at->at_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -2128,7 +2166,7 @@ ldap_str2attributetype( LDAP_CONST char * s, seen_obsolete = 1; at->at_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"SUP") ) { + } else if ( !strcasecmp(sval,"SUP") ) { LDAP_FREE(sval); if ( seen_sup ) { *code = LDAP_SCHERR_DUPOPT; @@ -2143,7 +2181,7 @@ ldap_str2attributetype( LDAP_CONST char * s, ldap_attributetype_free(at); return NULL; } - } else if ( !strcmp(sval,"EQUALITY") ) { + } else if ( !strcasecmp(sval,"EQUALITY") ) { LDAP_FREE(sval); if ( seen_equality ) { *code = LDAP_SCHERR_DUPOPT; @@ -2158,7 +2196,7 @@ ldap_str2attributetype( LDAP_CONST char * s, ldap_attributetype_free(at); return NULL; } - } else if ( !strcmp(sval,"ORDERING") ) { + } else if ( !strcasecmp(sval,"ORDERING") ) { LDAP_FREE(sval); if ( seen_ordering ) { *code = LDAP_SCHERR_DUPOPT; @@ -2173,7 +2211,7 @@ ldap_str2attributetype( LDAP_CONST char * s, ldap_attributetype_free(at); return NULL; } - } else if ( !strcmp(sval,"SUBSTR") ) { + } else if ( !strcasecmp(sval,"SUBSTR") ) { LDAP_FREE(sval); if ( seen_substr ) { *code = LDAP_SCHERR_DUPOPT; @@ -2188,7 +2226,7 @@ ldap_str2attributetype( LDAP_CONST char * s, ldap_attributetype_free(at); return NULL; } - } else if ( !strcmp(sval,"SYNTAX") ) { + } else if ( !strcasecmp(sval,"SYNTAX") ) { LDAP_FREE(sval); if ( seen_syntax ) { *code = LDAP_SCHERR_DUPOPT; @@ -2232,7 +2270,7 @@ ldap_str2attributetype( LDAP_CONST char * s, } } parse_whsp(&ss); - } else if ( !strcmp(sval,"SINGLE-VALUE") ) { + } else if ( !strcasecmp(sval,"SINGLE-VALUE") ) { LDAP_FREE(sval); if ( at->at_single_value ) { *code = LDAP_SCHERR_DUPOPT; @@ -2242,7 +2280,7 @@ ldap_str2attributetype( LDAP_CONST char * s, } at->at_single_value = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"COLLECTIVE") ) { + } else if ( !strcasecmp(sval,"COLLECTIVE") ) { LDAP_FREE(sval); if ( at->at_collective ) { *code = LDAP_SCHERR_DUPOPT; @@ -2252,7 +2290,7 @@ ldap_str2attributetype( LDAP_CONST char * s, } at->at_collective = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"NO-USER-MODIFICATION") ) { + } else if ( !strcasecmp(sval,"NO-USER-MODIFICATION") ) { LDAP_FREE(sval); if ( at->at_no_user_mod ) { *code = LDAP_SCHERR_DUPOPT; @@ -2262,7 +2300,7 @@ ldap_str2attributetype( LDAP_CONST char * s, } at->at_no_user_mod = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"USAGE") ) { + } else if ( !strcasecmp(sval,"USAGE") ) { LDAP_FREE(sval); if ( seen_usage ) { *code = LDAP_SCHERR_DUPOPT; @@ -2354,7 +2392,7 @@ ldap_str2objectclass( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -2407,16 +2445,16 @@ ldap_str2objectclass( LDAP_CONST char * s, ss = savepos; kind = get_token(&ss,&sval); if ( kind == TK_BAREWORD ) { - if ( !strcmp(sval, "NAME") || - !strcmp(sval, "DESC") || - !strcmp(sval, "OBSOLETE") || - !strcmp(sval, "SUP") || - !strcmp(sval, "ABSTRACT") || - !strcmp(sval, "STRUCTURAL") || - !strcmp(sval, "AUXILIARY") || - !strcmp(sval, "MUST") || - !strcmp(sval, "MAY") || - !strncmp(sval, "X-", 2) ) { + if ( !strcasecmp(sval, "NAME") || + !strcasecmp(sval, "DESC") || + !strcasecmp(sval, "OBSOLETE") || + !strcasecmp(sval, "SUP") || + !strcasecmp(sval, "ABSTRACT") || + !strcasecmp(sval, "STRUCTURAL") || + !strcasecmp(sval, "AUXILIARY") || + !strcasecmp(sval, "MUST") || + !strcasecmp(sval, "MAY") || + !strncasecmp(sval, "X-", 2) ) { /* Missing OID, backtrack */ ss = savepos; } else if ( flags & @@ -2429,6 +2467,7 @@ ldap_str2objectclass( LDAP_CONST char * s, } } LDAP_FREE(sval); + *code = 0; } else { *errp = ss; ldap_objectclass_free(oc); @@ -2446,13 +2485,13 @@ ldap_str2objectclass( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_objectclass_free(oc); return NULL; case TK_RIGHTPAREN: return oc; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -2469,7 +2508,7 @@ ldap_str2objectclass( LDAP_CONST char * s, ldap_objectclass_free(oc); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -2489,7 +2528,7 @@ ldap_str2objectclass( LDAP_CONST char * s, } oc->oc_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -2500,7 +2539,7 @@ ldap_str2objectclass( LDAP_CONST char * s, seen_obsolete = 1; oc->oc_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"SUP") ) { + } else if ( !strcasecmp(sval,"SUP") ) { LDAP_FREE(sval); if ( seen_sup ) { *code = LDAP_SCHERR_DUPOPT; @@ -2512,12 +2551,13 @@ ldap_str2objectclass( LDAP_CONST char * s, oc->oc_sup_oids = parse_oids(&ss, code, flags); - if ( !oc->oc_sup_oids ) { + if ( !oc->oc_sup_oids && *code != LDAP_SUCCESS ) { *errp = ss; ldap_objectclass_free(oc); return NULL; } - } else if ( !strcmp(sval,"ABSTRACT") ) { + *code = 0; + } else if ( !strcasecmp(sval,"ABSTRACT") ) { LDAP_FREE(sval); if ( seen_kind ) { *code = LDAP_SCHERR_DUPOPT; @@ -2528,7 +2568,7 @@ ldap_str2objectclass( LDAP_CONST char * s, seen_kind = 1; oc->oc_kind = LDAP_SCHEMA_ABSTRACT; parse_whsp(&ss); - } else if ( !strcmp(sval,"STRUCTURAL") ) { + } else if ( !strcasecmp(sval,"STRUCTURAL") ) { LDAP_FREE(sval); if ( seen_kind ) { *code = LDAP_SCHERR_DUPOPT; @@ -2539,7 +2579,7 @@ ldap_str2objectclass( LDAP_CONST char * s, seen_kind = 1; oc->oc_kind = LDAP_SCHEMA_STRUCTURAL; parse_whsp(&ss); - } else if ( !strcmp(sval,"AUXILIARY") ) { + } else if ( !strcasecmp(sval,"AUXILIARY") ) { LDAP_FREE(sval); if ( seen_kind ) { *code = LDAP_SCHERR_DUPOPT; @@ -2550,7 +2590,7 @@ ldap_str2objectclass( LDAP_CONST char * s, seen_kind = 1; oc->oc_kind = LDAP_SCHEMA_AUXILIARY; parse_whsp(&ss); - } else if ( !strcmp(sval,"MUST") ) { + } else if ( !strcasecmp(sval,"MUST") ) { LDAP_FREE(sval); if ( seen_must ) { *code = LDAP_SCHERR_DUPOPT; @@ -2560,13 +2600,14 @@ ldap_str2objectclass( LDAP_CONST char * s, } seen_must = 1; oc->oc_at_oids_must = parse_oids(&ss,code,0); - if ( !oc->oc_at_oids_must ) { + if ( !oc->oc_at_oids_must && *code != LDAP_SUCCESS ) { *errp = ss; ldap_objectclass_free(oc); return NULL; } + *code = 0; parse_whsp(&ss); - } else if ( !strcmp(sval,"MAY") ) { + } else if ( !strcasecmp(sval,"MAY") ) { LDAP_FREE(sval); if ( seen_may ) { *code = LDAP_SCHERR_DUPOPT; @@ -2576,15 +2617,17 @@ ldap_str2objectclass( LDAP_CONST char * s, } seen_may = 1; oc->oc_at_oids_may = parse_oids(&ss,code,0); - if ( !oc->oc_at_oids_may ) { + if ( !oc->oc_at_oids_may && *code != LDAP_SUCCESS ) { *errp = ss; ldap_objectclass_free(oc); return NULL; } + *code = 0; parse_whsp(&ss); } else if ( sval[0] == 'X' && sval[1] == '-' ) { /* Should be parse_qdstrings */ ext_vals = parse_qdescrs(&ss, code); + *code = 0; if ( !ext_vals ) { *errp = ss; ldap_objectclass_free(oc); @@ -2636,7 +2679,7 @@ ldap_str2contentrule( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -2679,9 +2722,36 @@ ldap_str2contentrule( LDAP_CONST char * s, savepos = ss; cr->cr_oid = ldap_int_parse_numericoid(&ss,code,0); if ( !cr->cr_oid ) { - *errp = ss; - ldap_contentrule_free(cr); - return NULL; + if ( (flags & LDAP_SCHEMA_ALLOW_ALL) && (ss == savepos) ) { + /* Backtracking */ + ss = savepos; + kind = get_token(&ss,&sval); + if ( kind == TK_BAREWORD ) { + if ( !strcasecmp(sval, "NAME") || + !strcasecmp(sval, "DESC") || + !strcasecmp(sval, "OBSOLETE") || + !strcasecmp(sval, "AUX") || + !strcasecmp(sval, "MUST") || + !strcasecmp(sval, "MAY") || + !strcasecmp(sval, "NOT") || + !strncasecmp(sval, "X-", 2) ) { + /* Missing OID, backtrack */ + ss = savepos; + } else if ( flags & + LDAP_SCHEMA_ALLOW_OID_MACRO ) { + /* Non-numerical OID, ignore */ + int len = ss-savepos; + cr->cr_oid = LDAP_MALLOC(len+1); + strncpy(cr->cr_oid, savepos, len); + cr->cr_oid[len] = 0; + } + } + LDAP_FREE(sval); + } else { + *errp = ss; + ldap_contentrule_free(cr); + return NULL; + } } parse_whsp(&ss); @@ -2694,13 +2764,13 @@ ldap_str2contentrule( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_contentrule_free(cr); return NULL; case TK_RIGHTPAREN: return cr; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -2717,7 +2787,7 @@ ldap_str2contentrule( LDAP_CONST char * s, ldap_contentrule_free(cr); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -2737,7 +2807,7 @@ ldap_str2contentrule( LDAP_CONST char * s, } cr->cr_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -2748,7 +2818,7 @@ ldap_str2contentrule( LDAP_CONST char * s, seen_obsolete = 1; cr->cr_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"AUX") ) { + } else if ( !strcasecmp(sval,"AUX") ) { LDAP_FREE(sval); if ( seen_aux ) { *code = LDAP_SCHERR_DUPOPT; @@ -2764,7 +2834,7 @@ ldap_str2contentrule( LDAP_CONST char * s, return NULL; } parse_whsp(&ss); - } else if ( !strcmp(sval,"MUST") ) { + } else if ( !strcasecmp(sval,"MUST") ) { LDAP_FREE(sval); if ( seen_must ) { *code = LDAP_SCHERR_DUPOPT; @@ -2774,13 +2844,13 @@ ldap_str2contentrule( LDAP_CONST char * s, } seen_must = 1; cr->cr_at_oids_must = parse_oids(&ss,code,0); - if ( !cr->cr_at_oids_must ) { + if ( !cr->cr_at_oids_must && *code != LDAP_SUCCESS ) { *errp = ss; ldap_contentrule_free(cr); return NULL; } parse_whsp(&ss); - } else if ( !strcmp(sval,"MAY") ) { + } else if ( !strcasecmp(sval,"MAY") ) { LDAP_FREE(sval); if ( seen_may ) { *code = LDAP_SCHERR_DUPOPT; @@ -2790,13 +2860,13 @@ ldap_str2contentrule( LDAP_CONST char * s, } seen_may = 1; cr->cr_at_oids_may = parse_oids(&ss,code,0); - if ( !cr->cr_at_oids_may ) { + if ( !cr->cr_at_oids_may && *code != LDAP_SUCCESS ) { *errp = ss; ldap_contentrule_free(cr); return NULL; } parse_whsp(&ss); - } else if ( !strcmp(sval,"NOT") ) { + } else if ( !strcasecmp(sval,"NOT") ) { LDAP_FREE(sval); if ( seen_not ) { *code = LDAP_SCHERR_DUPOPT; @@ -2806,7 +2876,7 @@ ldap_str2contentrule( LDAP_CONST char * s, } seen_not = 1; cr->cr_at_oids_not = parse_oids(&ss,code,0); - if ( !cr->cr_at_oids_not ) { + if ( !cr->cr_at_oids_not && *code != LDAP_SUCCESS ) { *errp = ss; ldap_contentrule_free(cr); return NULL; @@ -2863,7 +2933,8 @@ ldap_str2structurerule( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind, ret; + tk_t kind; + int ret; const char * ss = s; char * sval; int seen_name = 0; @@ -2918,7 +2989,7 @@ ldap_str2structurerule( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_structurerule_free(sr); return NULL; case TK_RIGHTPAREN: @@ -2929,7 +3000,7 @@ ldap_str2structurerule( LDAP_CONST char * s, } return sr; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -2946,7 +3017,7 @@ ldap_str2structurerule( LDAP_CONST char * s, ldap_structurerule_free(sr); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -2966,7 +3037,7 @@ ldap_str2structurerule( LDAP_CONST char * s, } sr->sr_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -2977,7 +3048,7 @@ ldap_str2structurerule( LDAP_CONST char * s, seen_obsolete = 1; sr->sr_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"FORM") ) { + } else if ( !strcasecmp(sval,"FORM") ) { LDAP_FREE(sval); if ( seen_nameform ) { *code = LDAP_SCHERR_DUPOPT; @@ -3046,7 +3117,7 @@ ldap_str2nameform( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -3107,7 +3178,7 @@ ldap_str2nameform( LDAP_CONST char * s, switch (kind) { case TK_EOS: *code = LDAP_SCHERR_NORIGHTPAREN; - *errp = ss; + *errp = EndOfInput; ldap_nameform_free(nf); return NULL; case TK_RIGHTPAREN: @@ -3118,7 +3189,7 @@ ldap_str2nameform( LDAP_CONST char * s, } return nf; case TK_BAREWORD: - if ( !strcmp(sval,"NAME") ) { + if ( !strcasecmp(sval,"NAME") ) { LDAP_FREE(sval); if ( seen_name ) { *code = LDAP_SCHERR_DUPOPT; @@ -3135,7 +3206,7 @@ ldap_str2nameform( LDAP_CONST char * s, ldap_nameform_free(nf); return NULL; } - } else if ( !strcmp(sval,"DESC") ) { + } else if ( !strcasecmp(sval,"DESC") ) { LDAP_FREE(sval); if ( seen_desc ) { *code = LDAP_SCHERR_DUPOPT; @@ -3155,7 +3226,7 @@ ldap_str2nameform( LDAP_CONST char * s, } nf->nf_desc = sval; parse_whsp(&ss); - } else if ( !strcmp(sval,"OBSOLETE") ) { + } else if ( !strcasecmp(sval,"OBSOLETE") ) { LDAP_FREE(sval); if ( seen_obsolete ) { *code = LDAP_SCHERR_DUPOPT; @@ -3166,7 +3237,22 @@ ldap_str2nameform( LDAP_CONST char * s, seen_obsolete = 1; nf->nf_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); - } else if ( !strcmp(sval,"MUST") ) { + } else if ( !strcasecmp(sval,"OC") ) { + LDAP_FREE(sval); + if ( seen_class ) { + *code = LDAP_SCHERR_DUPOPT; + *errp = ss; + ldap_nameform_free(nf); + return(NULL); + } + seen_class = 1; + nf->nf_objectclass = parse_woid(&ss,code); + if ( !nf->nf_objectclass ) { + *errp = ss; + ldap_nameform_free(nf); + return NULL; + } + } else if ( !strcasecmp(sval,"MUST") ) { LDAP_FREE(sval); if ( seen_must ) { *code = LDAP_SCHERR_DUPOPT; @@ -3176,13 +3262,13 @@ ldap_str2nameform( LDAP_CONST char * s, } seen_must = 1; nf->nf_at_oids_must = parse_oids(&ss,code,0); - if ( !nf->nf_at_oids_must ) { + if ( !nf->nf_at_oids_must && *code != LDAP_SUCCESS ) { *errp = ss; ldap_nameform_free(nf); return NULL; } parse_whsp(&ss); - } else if ( !strcmp(sval,"MAY") ) { + } else if ( !strcasecmp(sval,"MAY") ) { LDAP_FREE(sval); if ( seen_may ) { *code = LDAP_SCHERR_DUPOPT; @@ -3192,7 +3278,7 @@ ldap_str2nameform( LDAP_CONST char * s, } seen_may = 1; nf->nf_at_oids_may = parse_oids(&ss,code,0); - if ( !nf->nf_at_oids_may ) { + if ( !nf->nf_at_oids_may && *code != LDAP_SUCCESS ) { *errp = ss; ldap_nameform_free(nf); return NULL; @@ -3233,27 +3319,27 @@ ldap_str2nameform( LDAP_CONST char * s, } static char *const err2text[] = { - "Success", - "Out of memory", - "Unexpected token", - "Missing opening parenthesis", - "Missing closing parenthesis", - "Expecting digit", - "Expecting a name", - "Bad description", - "Bad superiors", - "Duplicate option", - "Unexpected end of data", - "Missing required field", - "Out of order field" + N_("Success"), + N_("Out of memory"), + N_("Unexpected token"), + N_("Missing opening parenthesis"), + N_("Missing closing parenthesis"), + N_("Expecting digit"), + N_("Expecting a name"), + N_("Bad description"), + N_("Bad superiors"), + N_("Duplicate option"), + N_("Unexpected end of data"), + N_("Missing required field"), + N_("Out of order field") }; char * ldap_scherr2str(int code) { if ( code < 0 || code >= (int)(sizeof(err2text)/sizeof(char *)) ) { - return "Unknown error"; + return _("Unknown error"); } else { - return err2text[code]; + return _(err2text[code]); } }