X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fschema.c;h=dac2eb267ba43d5bad32fe35a07dd0747db48398;hb=25b5aaf262b108908499b6bf4cf13cc7bff41038;hp=a8f85951baf67c7647756cd37bfdc2625cc829ac;hpb=49d73e12a720cfe052a335d82e67994ff261d21c;p=openldap diff --git a/libraries/libldap/schema.c b/libraries/libldap/schema.c index a8f85951ba..dac2eb267b 100644 --- a/libraries/libldap/schema.c +++ b/libraries/libldap/schema.c @@ -20,32 +20,38 @@ #include -static LDAP_CONST char * -choose_name( char *names[], LDAP_CONST char *fallback ) +static const char * +choose_name( char *names[], const char *fallback ) { return( (names != NULL && names[0] != NULL) ? names[0] : fallback ); } LDAP_CONST char * -ldap_syntax2name( LDAP_SYNTAX * syn ) +ldap_syntax2name( LDAPSyntax * syn ) { return( syn->syn_oid ); } LDAP_CONST char * -ldap_matchingrule2name( LDAP_MATCHING_RULE * mr ) +ldap_matchingrule2name( LDAPMatchingRule * mr ) { return( choose_name( mr->mr_names, mr->mr_oid ) ); } LDAP_CONST char * -ldap_attributetype2name( LDAP_ATTRIBUTE_TYPE * at ) +ldap_matchingruleuse2name( LDAPMatchingRuleUse * mru ) +{ + return( choose_name( mru->mru_names, mru->mru_oid ) ); +} + +LDAP_CONST char * +ldap_attributetype2name( LDAPAttributeType * at ) { return( choose_name( at->at_names, at->at_oid ) ); } LDAP_CONST char * -ldap_objectclass2name( LDAP_OBJECT_CLASS * oc ) +ldap_objectclass2name( LDAPObjectClass * oc ) { return( choose_name( oc->oc_names, oc->oc_oid ) ); } @@ -120,6 +126,10 @@ append_to_safe_string(safe_string * ss, char * s) /* We always make sure there is at least one position available */ if ( ss->pos + l >= ss->size-1 ) { ss->size *= 2; + if ( ss->pos + l >= ss->size-1 ) { + ss->size = ss->pos + l + 1; + } + temp = LDAP_REALLOC(ss->val, ss->size); if ( !temp ) { /* Trouble, out of memory */ @@ -267,9 +277,9 @@ print_noidlen(safe_string *ss, char *s, int l) } static int -print_extensions(safe_string *ss, LDAP_SCHEMA_EXTENSION_ITEM **extensions) +print_extensions(safe_string *ss, LDAPSchemaExtensionItem **extensions) { - LDAP_SCHEMA_EXTENSION_ITEM **ext; + LDAPSchemaExtensionItem **ext; if ( extensions ) { print_whsp(ss); @@ -286,7 +296,7 @@ print_extensions(safe_string *ss, LDAP_SCHEMA_EXTENSION_ITEM **extensions) } char * -ldap_syntax2str( const LDAP_SYNTAX * syn ) +ldap_syntax2str( LDAPSyntax * syn ) { safe_string * ss; char * retstring; @@ -318,7 +328,7 @@ ldap_syntax2str( const LDAP_SYNTAX * syn ) } char * -ldap_matchingrule2str( const LDAP_MATCHING_RULE * mr ) +ldap_matchingrule2str( LDAPMatchingRule * mr ) { safe_string * ss; char * retstring; @@ -367,7 +377,56 @@ ldap_matchingrule2str( const LDAP_MATCHING_RULE * mr ) } char * -ldap_objectclass2str( const LDAP_OBJECT_CLASS * oc ) +ldap_matchingruleuse2str( LDAPMatchingRuleUse * mru ) +{ + safe_string * ss; + char * retstring; + + ss = new_safe_string(256); + if ( !ss ) + return NULL; + + print_literal(ss,"(" /*)*/); + print_whsp(ss); + + print_numericoid(ss, mru->mru_oid); + print_whsp(ss); + + if ( mru->mru_names ) { + print_literal(ss,"NAME"); + print_qdescrs(ss,mru->mru_names); + } + + if ( mru->mru_desc ) { + print_literal(ss,"DESC"); + print_qdstring(ss,mru->mru_desc); + } + + if ( mru->mru_obsolete == LDAP_SCHEMA_YES ) { + print_literal(ss, "OBSOLETE"); + print_whsp(ss); + } + + if ( mru->mru_applies_oids ) { + print_literal(ss,"APPLIES"); + print_whsp(ss); + print_oids(ss, mru->mru_applies_oids); + print_whsp(ss); + } + + print_whsp(ss); + + print_extensions(ss, mru->mru_extensions); + + print_literal(ss,/*(*/")"); + + retstring = LDAP_STRDUP(safe_string_val(ss)); + safe_string_free(ss); + return(retstring); +} + +char * +ldap_objectclass2str( LDAPObjectClass * oc ) { safe_string * ss; char * retstring; @@ -446,7 +505,7 @@ ldap_objectclass2str( const LDAP_OBJECT_CLASS * oc ) } char * -ldap_attributetype2str( const LDAP_ATTRIBUTE_TYPE * at ) +ldap_attributetype2str( LDAPAttributeType * at ) { safe_string * ss; char * retstring; @@ -587,7 +646,7 @@ struct token { }; static int -get_token(const char ** sp, char ** token_val) +get_token( const char ** sp, char ** token_val ) { int kind; const char * p; @@ -677,7 +736,7 @@ parse_whsp(const char **sp) */ /* Parse a sequence of dot-separated decimal strings */ -static char * +char * parse_numericoid(const char **sp, int *code, const int flags) { char * res; @@ -966,13 +1025,13 @@ parse_oids(const char **sp, int *code, const int allow_quoted) } static int -add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions, +add_extension(LDAPSchemaExtensionItem ***extensions, char * name, char ** values) { int n; - LDAP_SCHEMA_EXTENSION_ITEM **tmp, *ext; + LDAPSchemaExtensionItem **tmp, *ext; - ext = LDAP_CALLOC(1, sizeof(LDAP_SCHEMA_EXTENSION_ITEM)); + ext = LDAP_CALLOC(1, sizeof(LDAPSchemaExtensionItem)); if ( !ext ) return 1; ext->lsei_name = name; @@ -980,7 +1039,7 @@ add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions, if ( !*extensions ) { *extensions = - LDAP_CALLOC(2, sizeof(LDAP_SCHEMA_EXTENSION_ITEM *)); + LDAP_CALLOC(2, sizeof(LDAPSchemaExtensionItem *)); if ( !*extensions ) return 1; n = 0; @@ -988,7 +1047,7 @@ add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions, for ( n=0; (*extensions)[n] != NULL; n++ ) ; tmp = LDAP_REALLOC(*extensions, - (n+2)*sizeof(LDAP_SCHEMA_EXTENSION_ITEM *)); + (n+2)*sizeof(LDAPSchemaExtensionItem *)); if ( !tmp ) return 1; *extensions = tmp; @@ -999,9 +1058,9 @@ add_extension(LDAP_SCHEMA_EXTENSION_ITEM ***extensions, } static void -free_extensions(LDAP_SCHEMA_EXTENSION_ITEM **extensions) +free_extensions(LDAPSchemaExtensionItem **extensions) { - LDAP_SCHEMA_EXTENSION_ITEM **ext; + LDAPSchemaExtensionItem **ext; if ( extensions ) { for ( ext = extensions; *ext != NULL; ext++ ) { @@ -1014,23 +1073,27 @@ free_extensions(LDAP_SCHEMA_EXTENSION_ITEM **extensions) } void -ldap_syntax_free( LDAP_SYNTAX * syn ) +ldap_syntax_free( LDAPSyntax * syn ) { LDAP_FREE(syn->syn_oid); + LDAP_VFREE(syn->syn_names); LDAP_FREE(syn->syn_desc); free_extensions(syn->syn_extensions); LDAP_FREE(syn); } -LDAP_SYNTAX * -ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags ) +LDAPSyntax * +ldap_str2syntax( LDAP_CONST char * s, + int * code, + LDAP_CONST char ** errp, + LDAP_CONST int flags ) { int kind; const char * ss = s; char * sval; int seen_name = 0; int seen_desc = 0; - LDAP_SYNTAX * syn; + LDAPSyntax * syn; char ** ext_vals; if ( !s ) { @@ -1040,7 +1103,7 @@ ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags } *errp = s; - syn = LDAP_CALLOC(1,sizeof(LDAP_SYNTAX)); + syn = LDAP_CALLOC(1,sizeof(LDAPSyntax)); if ( !syn ) { *code = LDAP_SCHERR_OUTOFMEM; @@ -1151,7 +1214,7 @@ ldap_str2syntax( const char * s, int * code, const char ** errp, const int flags } void -ldap_matchingrule_free( LDAP_MATCHING_RULE * mr ) +ldap_matchingrule_free( LDAPMatchingRule * mr ) { LDAP_FREE(mr->mr_oid); LDAP_VFREE(mr->mr_names); @@ -1161,8 +1224,11 @@ ldap_matchingrule_free( LDAP_MATCHING_RULE * mr ) LDAP_FREE(mr); } -LDAP_MATCHING_RULE * -ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int flags ) +LDAPMatchingRule * +ldap_str2matchingrule( LDAP_CONST char * s, + int * code, + LDAP_CONST char ** errp, + LDAP_CONST int flags ) { int kind; const char * ss = s; @@ -1171,7 +1237,7 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int int seen_desc = 0; int seen_obsolete = 0; int seen_syntax = 0; - LDAP_MATCHING_RULE * mr; + LDAPMatchingRule * mr; char ** ext_vals; const char * savepos; @@ -1182,7 +1248,7 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int } *errp = s; - mr = LDAP_CALLOC(1,sizeof(LDAP_MATCHING_RULE)); + mr = LDAP_CALLOC(1,sizeof(LDAPMatchingRule)); if ( !mr ) { *code = LDAP_SCHERR_OUTOFMEM; @@ -1342,7 +1408,200 @@ ldap_str2matchingrule( const char * s, int * code, const char ** errp, const int } void -ldap_attributetype_free(LDAP_ATTRIBUTE_TYPE * at) +ldap_matchingruleuse_free( LDAPMatchingRuleUse * mru ) +{ + LDAP_FREE(mru->mru_oid); + LDAP_VFREE(mru->mru_names); + LDAP_FREE(mru->mru_desc); + LDAP_VFREE(mru->mru_applies_oids); + free_extensions(mru->mru_extensions); + LDAP_FREE(mru); +} + +LDAPMatchingRuleUse * +ldap_str2matchingruleuse( LDAP_CONST char * s, + int * code, + LDAP_CONST char ** errp, + LDAP_CONST int flags ) +{ + int kind; + const char * ss = s; + char * sval; + int seen_name = 0; + int seen_desc = 0; + int seen_obsolete = 0; + int seen_applies = 0; + LDAPMatchingRuleUse * mru; + char ** ext_vals; + const char * savepos; + + if ( !s ) { + *code = LDAP_SCHERR_EMPTY; + *errp = ""; + return NULL; + } + + *errp = s; + mru = LDAP_CALLOC(1,sizeof(LDAPMatchingRuleUse)); + + if ( !mru ) { + *code = LDAP_SCHERR_OUTOFMEM; + return NULL; + } + + kind = get_token(&ss,&sval); + if ( kind != TK_LEFTPAREN ) { + *code = LDAP_SCHERR_NOLEFTPAREN; + LDAP_FREE(sval); + ldap_matchingruleuse_free(mru); + return NULL; + } + + parse_whsp(&ss); + savepos = ss; + mru->mru_oid = parse_numericoid(&ss,code,flags); + if ( !mru->mru_oid ) { + if ( flags & LDAP_SCHEMA_ALLOW_NO_OID ) { + /* Backtracking */ + 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) ) { + /* Missing OID, backtrack */ + ss = savepos; + } else { + /* Non-numerical OID, ignore */ + } + } + LDAP_FREE(sval); + } else { + *errp = ss; + ldap_matchingruleuse_free(mru); + return NULL; + } + } + parse_whsp(&ss); + + /* + * Beyond this point we will be liberal and accept the items + * in any order. + */ + while (1) { + kind = get_token(&ss,&sval); + switch (kind) { + case TK_EOS: + *code = LDAP_SCHERR_NORIGHTPAREN; + *errp = ss; + ldap_matchingruleuse_free(mru); + return NULL; + case TK_RIGHTPAREN: + return mru; + case TK_BAREWORD: + if ( !strcmp(sval,"NAME") ) { + LDAP_FREE(sval); + if ( seen_name ) { + *code = LDAP_SCHERR_DUPOPT; + *errp = ss; + ldap_matchingruleuse_free(mru); + return(NULL); + } + seen_name = 1; + mru->mru_names = parse_qdescrs(&ss,code); + if ( !mru->mru_names ) { + if ( *code != LDAP_SCHERR_OUTOFMEM ) + *code = LDAP_SCHERR_BADNAME; + *errp = ss; + ldap_matchingruleuse_free(mru); + return NULL; + } + } else if ( !strcmp(sval,"DESC") ) { + LDAP_FREE(sval); + if ( seen_desc ) { + *code = LDAP_SCHERR_DUPOPT; + *errp = ss; + ldap_matchingruleuse_free(mru); + return(NULL); + } + seen_desc = 1; + parse_whsp(&ss); + kind = get_token(&ss,&sval); + if ( kind != TK_QDSTRING ) { + *code = LDAP_SCHERR_UNEXPTOKEN; + *errp = ss; + LDAP_FREE(sval); + ldap_matchingruleuse_free(mru); + return NULL; + } + mru->mru_desc = sval; + parse_whsp(&ss); + } else if ( !strcmp(sval,"OBSOLETE") ) { + LDAP_FREE(sval); + if ( seen_obsolete ) { + *code = LDAP_SCHERR_DUPOPT; + *errp = ss; + ldap_matchingruleuse_free(mru); + return(NULL); + } + seen_obsolete = 1; + mru->mru_obsolete = LDAP_SCHEMA_YES; + parse_whsp(&ss); + } else if ( !strcmp(sval,"APPLIES") ) { + LDAP_FREE(sval); + if ( seen_applies ) { + *code = LDAP_SCHERR_DUPOPT; + *errp = ss; + ldap_matchingruleuse_free(mru); + return(NULL); + } + seen_applies = 1; + mru->mru_applies_oids = parse_oids(&ss, + code, + flags); + if ( !mru->mru_applies_oids ) { + *errp = ss; + ldap_matchingruleuse_free(mru); + return NULL; + } + } else if ( sval[0] == 'X' && sval[1] == '-' ) { + /* Should be parse_qdstrings */ + ext_vals = parse_qdescrs(&ss, code); + if ( !ext_vals ) { + *errp = ss; + ldap_matchingruleuse_free(mru); + return NULL; + } + if ( add_extension(&mru->mru_extensions, + sval, ext_vals) ) { + *code = LDAP_SCHERR_OUTOFMEM; + *errp = ss; + LDAP_FREE(sval); + ldap_matchingruleuse_free(mru); + return NULL; + } + } else { + *code = LDAP_SCHERR_UNEXPTOKEN; + *errp = ss; + LDAP_FREE(sval); + ldap_matchingruleuse_free(mru); + return NULL; + } + break; + default: + *code = LDAP_SCHERR_UNEXPTOKEN; + *errp = ss; + LDAP_FREE(sval); + ldap_matchingruleuse_free(mru); + return NULL; + } + } +} + +void +ldap_attributetype_free(LDAPAttributeType * at) { LDAP_FREE(at->at_oid); LDAP_VFREE(at->at_names); @@ -1356,8 +1615,11 @@ ldap_attributetype_free(LDAP_ATTRIBUTE_TYPE * at) LDAP_FREE(at); } -LDAP_ATTRIBUTE_TYPE * -ldap_str2attributetype( const char * s, int * code, const char ** errp, const int flags ) +LDAPAttributeType * +ldap_str2attributetype( LDAP_CONST char * s, + int * code, + LDAP_CONST char ** errp, + LDAP_CONST int flags ) { int kind; const char * ss = s; @@ -1371,7 +1633,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in int seen_substr = 0; int seen_syntax = 0; int seen_usage = 0; - LDAP_ATTRIBUTE_TYPE * at; + LDAPAttributeType * at; char ** ext_vals; const char * savepos; @@ -1382,7 +1644,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in } *errp = s; - at = LDAP_CALLOC(1,sizeof(LDAP_ATTRIBUTE_TYPE)); + at = LDAP_CALLOC(1,sizeof(LDAPAttributeType)); if ( !at ) { *code = LDAP_SCHERR_OUTOFMEM; @@ -1408,7 +1670,9 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in savepos = ss; at->at_oid = parse_numericoid(&ss,code,0); if ( !at->at_oid ) { - if ( flags & LDAP_SCHEMA_ALLOW_NO_OID ) { + if ( ( flags & ( LDAP_SCHEMA_ALLOW_NO_OID + | LDAP_SCHEMA_ALLOW_OID_MACRO ) ) + && (ss == savepos) ) { /* Backtracking */ ss = savepos; kind = get_token(&ss,&sval); @@ -1428,8 +1692,13 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in !strncmp(sval, "X-", 2) ) { /* Missing OID, backtrack */ ss = savepos; - } else { - /* Non-numerical OID, ignore */ + } else if ( flags + & LDAP_SCHEMA_ALLOW_OID_MACRO) { + /* Non-numerical OID ... */ + int len = ss-savepos; + at->at_oid = LDAP_MALLOC(len+1); + strncpy(at->at_oid, savepos, len); + at->at_oid[len] = 0; } } LDAP_FREE(sval); @@ -1574,15 +1843,38 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in } seen_syntax = 1; parse_whsp(&ss); + savepos = ss; at->at_syntax_oid = parse_noidlen(&ss, code, &at->at_syntax_len, flags); if ( !at->at_syntax_oid ) { + if ( flags & LDAP_SCHEMA_ALLOW_OID_MACRO ) { + kind = get_token(&ss,&sval); + if (kind == TK_BAREWORD) + { + char *sp = strchr(sval, '{'); + at->at_syntax_oid = sval; + if (sp) + { + *sp++ = 0; + at->at_syntax_len = atoi(sp); + while ( LDAP_DIGIT(*sp) ) + sp++; + if ( *sp != '}' ) { + *code = LDAP_SCHERR_UNEXPTOKEN; + *errp = ss; + ldap_attributetype_free(at); + return NULL; + } + } + } + } else { *errp = ss; ldap_attributetype_free(at); return NULL; + } } parse_whsp(&ss); } else if ( !strcmp(sval,"SINGLE-VALUE") ) { @@ -1689,7 +1981,7 @@ ldap_str2attributetype( const char * s, int * code, const char ** errp, const in } void -ldap_objectclass_free(LDAP_OBJECT_CLASS * oc) +ldap_objectclass_free(LDAPObjectClass * oc) { LDAP_FREE(oc->oc_oid); LDAP_VFREE(oc->oc_names); @@ -1701,8 +1993,11 @@ ldap_objectclass_free(LDAP_OBJECT_CLASS * oc) LDAP_FREE(oc); } -LDAP_OBJECT_CLASS * -ldap_str2objectclass( const char * s, int * code, const char ** errp, const int flags ) +LDAPObjectClass * +ldap_str2objectclass( LDAP_CONST char * s, + int * code, + LDAP_CONST char ** errp, + LDAP_CONST int flags ) { int kind; const char * ss = s; @@ -1714,7 +2009,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp, const int int seen_kind = 0; int seen_must = 0; int seen_may = 0; - LDAP_OBJECT_CLASS * oc; + LDAPObjectClass * oc; char ** ext_vals; const char * savepos; @@ -1725,12 +2020,13 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp, const int } *errp = s; - oc = LDAP_CALLOC(1,sizeof(LDAP_OBJECT_CLASS)); + oc = LDAP_CALLOC(1,sizeof(LDAPObjectClass)); if ( !oc ) { *code = LDAP_SCHERR_OUTOFMEM; return NULL; } + oc->oc_kind = LDAP_SCHEMA_STRUCTURAL; kind = get_token(&ss,&sval); if ( kind != TK_LEFTPAREN ) { @@ -1751,7 +2047,7 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp, const int savepos = ss; oc->oc_oid = parse_numericoid(&ss,code,0); if ( !oc->oc_oid ) { - if ( flags & LDAP_SCHEMA_ALLOW_ALL ) { + if ( (flags & LDAP_SCHEMA_ALLOW_ALL) && (ss == savepos) ) { /* Backtracking */ ss = savepos; kind = get_token(&ss,&sval); @@ -1767,8 +2063,13 @@ ldap_str2objectclass( const char * s, int * code, const char ** errp, const int !strncmp(sval, "X-", 2) ) { /* Missing OID, backtrack */ ss = savepos; - } else { + } else if ( flags & + LDAP_SCHEMA_ALLOW_OID_MACRO ) { /* Non-numerical OID, ignore */ + int len = ss-savepos; + oc->oc_oid = LDAP_MALLOC(len+1); + strncpy(oc->oc_oid, savepos, len); + oc->oc_oid[len] = 0; } } LDAP_FREE(sval);