X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fschema.c;h=ffa37332025211ac40b18ea3e2a012698fbe36e9;hb=2e4580beaa358299ecb6bc8b920e40dfc373e969;hp=4639b4510520425b654205641064776db02f9b1d;hpb=5e41701ca208a5a58837f306108937a1350fde10;p=openldap diff --git a/libraries/libldap/schema.c b/libraries/libldap/schema.c index 4639b45105..ffa3733202 100644 --- a/libraries/libldap/schema.c +++ b/libraries/libldap/schema.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2004 The OpenLDAP Foundation. + * Copyright 1998-2012 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,8 @@ #include +static const char EndOfInput[] = "end of input"; + static const char * choose_name( char *names[], const char *fallback ) { @@ -39,48 +41,56 @@ choose_name( char *names[], const char *fallback ) LDAP_CONST char * ldap_syntax2name( LDAPSyntax * syn ) { + if (!syn) return NULL; return( syn->syn_oid ); } LDAP_CONST char * ldap_matchingrule2name( LDAPMatchingRule * mr ) { + if (!mr) return NULL; return( choose_name( mr->mr_names, mr->mr_oid ) ); } LDAP_CONST char * ldap_matchingruleuse2name( LDAPMatchingRuleUse * mru ) { + if (!mru) return NULL; return( choose_name( mru->mru_names, mru->mru_oid ) ); } LDAP_CONST char * ldap_attributetype2name( LDAPAttributeType * at ) { + if (!at) return NULL; return( choose_name( at->at_names, at->at_oid ) ); } LDAP_CONST char * ldap_objectclass2name( LDAPObjectClass * oc ) { + if (!oc) return NULL; return( choose_name( oc->oc_names, oc->oc_oid ) ); } LDAP_CONST char * ldap_contentrule2name( LDAPContentRule * cr ) { + if (!cr) return NULL; return( choose_name( cr->cr_names, cr->cr_oid ) ); } LDAP_CONST char * ldap_nameform2name( LDAPNameForm * nf ) { + if (!nf) return NULL; return( choose_name( nf->nf_names, nf->nf_oid ) ); } LDAP_CONST char * ldap_structurerule2name( LDAPStructureRule * sr ) { + if (!sr) return NULL; return( choose_name( sr->sr_names, NULL ) ); } @@ -377,7 +387,10 @@ struct berval * ldap_syntax2bv( LDAPSyntax * syn, struct berval *bv ) { safe_string * ss; - + + if ( !syn || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -419,7 +432,10 @@ struct berval * ldap_matchingrule2bv( LDAPMatchingRule * mr, struct berval *bv ) { safe_string * ss; - + + if ( !mr || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -478,7 +494,10 @@ struct berval * ldap_matchingruleuse2bv( LDAPMatchingRuleUse * mru, struct berval *bv ) { safe_string * ss; - + + if ( !mru || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -537,7 +556,10 @@ struct berval * ldap_objectclass2bv( LDAPObjectClass * oc, struct berval *bv ) { safe_string * ss; - + + if ( !oc || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -626,7 +648,10 @@ struct berval * ldap_contentrule2bv( LDAPContentRule * cr, struct berval *bv ) { safe_string * ss; - + + if ( !cr || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -705,7 +730,10 @@ struct berval * ldap_structurerule2bv( LDAPStructureRule * sr, struct berval *bv ) { safe_string * ss; - + + if ( !sr || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -769,7 +797,10 @@ struct berval * ldap_nameform2bv( LDAPNameForm * nf, struct berval *bv ) { safe_string * ss; - + + if ( !nf || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -838,7 +869,10 @@ struct berval * ldap_attributetype2bv( LDAPAttributeType * at, struct berval *bv ) { safe_string * ss; - + + if ( !at || !bv ) + return NULL; + ss = new_safe_string(256); if ( !ss ) return NULL; @@ -959,26 +993,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; @@ -1030,6 +1061,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; @@ -1150,7 +1184,7 @@ parse_qdescrs(const char **sp, int *code) { char ** res; char ** res1; - int kind; + tk_t kind; char * sval; int size; int pos; @@ -1217,7 +1251,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); @@ -1232,10 +1266,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) */ @@ -1243,9 +1280,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)++; @@ -1284,7 +1334,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; @@ -1312,6 +1362,11 @@ parse_oids(const char **sp, int *code, const int allow_quoted) ( allow_quoted && kind == TK_QDSTRING ) ) { 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); @@ -1393,16 +1448,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; @@ -1428,6 +1487,7 @@ free_extensions(LDAPSchemaExtensionItem **extensions) void ldap_syntax_free( LDAPSyntax * syn ) { + if ( !syn ) return; LDAP_FREE(syn->syn_oid); if (syn->syn_names) LDAP_VFREE(syn->syn_names); if (syn->syn_desc) LDAP_FREE(syn->syn_desc); @@ -1441,7 +1501,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; @@ -1489,7 +1549,7 @@ 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: @@ -1569,6 +1629,7 @@ ldap_str2syntax( LDAP_CONST char * s, void ldap_matchingrule_free( LDAPMatchingRule * mr ) { + if (!mr) return; LDAP_FREE(mr->mr_oid); if (mr->mr_names) LDAP_VFREE(mr->mr_names); if (mr->mr_desc) LDAP_FREE(mr->mr_desc); @@ -1583,7 +1644,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; @@ -1654,7 +1715,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: @@ -1768,6 +1829,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, void ldap_matchingruleuse_free( LDAPMatchingRuleUse * mru ) { + if (!mru) return; LDAP_FREE(mru->mru_oid); if (mru->mru_names) LDAP_VFREE(mru->mru_names); if (mru->mru_desc) LDAP_FREE(mru->mru_desc); @@ -1782,7 +1844,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; @@ -1853,7 +1915,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: @@ -1924,7 +1986,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; @@ -1966,6 +2028,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, void ldap_attributetype_free(LDAPAttributeType * at) { + if (!at) return; LDAP_FREE(at->at_oid); if (at->at_names) LDAP_VFREE(at->at_names); if (at->at_desc) LDAP_FREE(at->at_desc); @@ -1984,7 +2047,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; @@ -2035,7 +2098,8 @@ 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); @@ -2052,11 +2116,13 @@ ldap_str2attributetype( LDAP_CONST char * s, !strcasecmp(sval, "COLLECTIVE") || !strcasecmp(sval, "NO-USER-MODIFICATION") || !strcasecmp(sval, "USAGE") || - !strncasecmp(sval, "X-", 2) ) { + !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); @@ -2082,7 +2148,7 @@ 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: @@ -2346,6 +2412,7 @@ ldap_str2attributetype( LDAP_CONST char * s, void ldap_objectclass_free(LDAPObjectClass * oc) { + if (!oc) return; LDAP_FREE(oc->oc_oid); if (oc->oc_names) LDAP_VFREE(oc->oc_names); if (oc->oc_desc) LDAP_FREE(oc->oc_desc); @@ -2362,7 +2429,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; @@ -2437,6 +2504,7 @@ ldap_str2objectclass( LDAP_CONST char * s, } } LDAP_FREE(sval); + *code = 0; } else { *errp = ss; ldap_objectclass_free(oc); @@ -2454,7 +2522,7 @@ 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: @@ -2520,11 +2588,12 @@ 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; } + *code = 0; } else if ( !strcasecmp(sval,"ABSTRACT") ) { LDAP_FREE(sval); if ( seen_kind ) { @@ -2568,11 +2637,12 @@ 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 ( !strcasecmp(sval,"MAY") ) { LDAP_FREE(sval); @@ -2584,15 +2654,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); @@ -2627,6 +2699,7 @@ ldap_str2objectclass( LDAP_CONST char * s, void ldap_contentrule_free(LDAPContentRule * cr) { + if (!cr) return; LDAP_FREE(cr->cr_oid); if (cr->cr_names) LDAP_VFREE(cr->cr_names); if (cr->cr_desc) LDAP_FREE(cr->cr_desc); @@ -2644,7 +2717,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; @@ -2729,7 +2802,7 @@ 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: @@ -2809,7 +2882,7 @@ 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; @@ -2825,7 +2898,7 @@ 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; @@ -2841,7 +2914,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; @@ -2884,6 +2957,7 @@ ldap_str2contentrule( LDAP_CONST char * s, void ldap_structurerule_free(LDAPStructureRule * sr) { + if (!sr) return; if (sr->sr_names) LDAP_VFREE(sr->sr_names); if (sr->sr_desc) LDAP_FREE(sr->sr_desc); if (sr->sr_nameform) LDAP_FREE(sr->sr_nameform); @@ -2898,7 +2972,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; @@ -2953,7 +3028,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: @@ -3065,6 +3140,7 @@ ldap_str2structurerule( LDAP_CONST char * s, void ldap_nameform_free(LDAPNameForm * nf) { + if (!nf) return; LDAP_FREE(nf->nf_oid); if (nf->nf_names) LDAP_VFREE(nf->nf_names); if (nf->nf_desc) LDAP_FREE(nf->nf_desc); @@ -3081,7 +3157,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; @@ -3142,7 +3218,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: @@ -3201,6 +3277,21 @@ ldap_str2nameform( LDAP_CONST char * s, seen_obsolete = 1; nf->nf_obsolete = LDAP_SCHEMA_YES; parse_whsp(&ss); + } 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 ) { @@ -3211,7 +3302,7 @@ 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; @@ -3227,7 +3318,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;