/*
* Strictly speaking, doing this here accepts whsp before the
- * ( at the begining of an oidlist, but his is harmless. Also,
+ * ( at the begining of an oidlist, but this is harmless. Also,
* we are very liberal in what we accept as an OID. Maybe
* refine later.
*/
}
}
-static void
-free_syn(LDAP_SYNTAX * syn)
+void
+ldap_syntax_free(LDAP_SYNTAX * syn)
{
LDAP_FREE(syn->syn_oid);
LDAP_FREE(syn->syn_desc);
kind = get_token(&ss,&sval);
if ( kind != TK_LEFTPAREN ) {
*code = LDAP_SCHERR_NOLEFTPAREN;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
}
syn->syn_oid = parse_numericoid(&ss,code);
if ( !syn->syn_oid ) {
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
}
parse_whsp(&ss);
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
case TK_RIGHTPAREN:
return syn;
if ( seen_desc ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return(NULL);
}
seen_desc = 1;
if ( kind != TK_QDSTRING ) {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
}
syn->syn_desc = sval;
ssdummy = parse_qdescrs(&ss, code);
if ( !ssdummy ) {
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
}
} else {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
}
break;
default:
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_syn(syn);
+ ldap_syntax_free(syn);
return NULL;
}
}
}
-static void
-free_at(LDAP_ATTRIBUTE_TYPE * at)
+void
+ldap_attributetype_free(LDAP_ATTRIBUTE_TYPE * at)
{
LDAP_FREE(at->at_oid);
LDAP_VFREE(at->at_names);
int kind;
char * ss = s;
char * sval;
+ int be_liberal = 1; /* Future additional argument */
int seen_name = 0;
int seen_desc = 0;
int seen_obsolete = 0;
int seen_may = 0;
LDAP_ATTRIBUTE_TYPE * at;
char ** ssdummy;
+ char * savepos;
if ( !s ) {
*code = LDAP_SCHERR_EMPTY;
kind = get_token(&ss,&sval);
if ( kind != TK_LEFTPAREN ) {
*code = LDAP_SCHERR_NOLEFTPAREN;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
+ /*
+ * Definitions MUST begin with an OID in the numericoid format.
+ * However, this routine is used by clients to parse the response
+ * from servers and very well known servers will provide an OID
+ * in the wrong format or even no OID at all. We do our best to
+ * extract info from those servers.
+ */
parse_whsp(&ss);
+ savepos = ss;
at->at_oid = parse_numericoid(&ss,code);
if ( !at->at_oid ) {
- *errp = ss;
- free_at(at);
- return NULL;
+ if ( be_liberal ) {
+ /* 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) ) {
+ /* Missing OID, backtrack */
+ ss = savepos;
+ } else {
+ /* Non-numerical OID, ignore */
+ }
+ }
+ } else {
+ *errp = ss;
+ ldap_attributetype_free(at);
+ return NULL;
+ }
}
parse_whsp(&ss);
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
case TK_RIGHTPAREN:
return at;
if ( seen_name ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_name = 1;
if ( *code != LDAP_SCHERR_OUTOFMEM )
*code = LDAP_SCHERR_BADNAME;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
} else if ( !strcmp(sval,"DESC") ) {
if ( seen_desc ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_desc = 1;
if ( kind != TK_QDSTRING ) {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
at->at_desc = sval;
if ( seen_obsolete ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_obsolete = 1;
if ( seen_sup ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_sup = 1;
at->at_sup_oid = parse_woid(&ss,code);
if ( !at->at_sup_oid ) {
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
} else if ( !strcmp(sval,"EQUALITY") ) {
if ( seen_equality ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_equality = 1;
at->at_equality_oid = parse_woid(&ss,code);
if ( !at->at_equality_oid ) {
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
} else if ( !strcmp(sval,"ORDERING") ) {
if ( seen_ordering ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_ordering = 1;
at->at_ordering_oid = parse_woid(&ss,code);
if ( !at->at_ordering_oid ) {
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
} else if ( !strcmp(sval,"SUBSTR") ) {
if ( seen_substr ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_substr = 1;
at->at_substr_oid = parse_woid(&ss,code);
if ( !at->at_substr_oid ) {
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
} else if ( !strcmp(sval,"SYNTAX") ) {
if ( seen_syntax ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_syntax = 1;
at->at_syntax_oid = parse_noidlen(&ss,code,&at->at_syntax_len);
if ( !at->at_syntax_oid ) {
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
parse_whsp(&ss);
if ( at->at_single_value ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
at->at_single_value = LDAP_SCHEMA_YES;
if ( at->at_collective ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
at->at_collective = LDAP_SCHEMA_YES;
if ( at->at_no_user_mod ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
at->at_no_user_mod = LDAP_SCHEMA_YES;
if ( seen_usage ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return(NULL);
}
seen_usage = 1;
if ( kind != TK_BAREWORD ) {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
if ( !strcasecmp(sval,"userApplications") )
else {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
parse_whsp(&ss);
ssdummy = parse_qdescrs(&ss, code);
if ( !ssdummy ) {
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
} else {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
break;
default:
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_at(at);
+ ldap_attributetype_free(at);
return NULL;
}
}
}
-static void
-free_oc(LDAP_OBJECT_CLASS * oc)
+void
+ldap_objectclass_free(LDAP_OBJECT_CLASS * oc)
{
LDAP_FREE(oc->oc_oid);
LDAP_VFREE(oc->oc_names);
int kind;
char * ss = s;
char * sval;
+ int be_liberal = 1; /* Future additional argument */
int seen_name = 0;
int seen_desc = 0;
int seen_obsolete = 0;
int seen_may = 0;
LDAP_OBJECT_CLASS * oc;
char ** ssdummy;
+ char * savepos;
if ( !s ) {
*code = LDAP_SCHERR_EMPTY;
kind = get_token(&ss,&sval);
if ( kind != TK_LEFTPAREN ) {
*code = LDAP_SCHERR_NOLEFTPAREN;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
+ /*
+ * Definitions MUST begin with an OID in the numericoid format.
+ * However, this routine is used by clients to parse the response
+ * from servers and very well known servers will provide an OID
+ * in the wrong format or even no OID at all. We do our best to
+ * extract info from those servers.
+ */
parse_whsp(&ss);
oc->oc_oid = parse_numericoid(&ss,code);
if ( !oc->oc_oid ) {
- *errp = ss;
- free_oc(oc);
- return NULL;
+ if ( be_liberal ) {
+ /* 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, "ABSTRACT") ||
+ !strcmp(sval, "STRUCTURAL") ||
+ !strcmp(sval, "AUXILIARY") ||
+ !strcmp(sval, "MUST") ||
+ !strncmp(sval, "X-", 2) ) {
+ /* Missing OID, backtrack */
+ ss = savepos;
+ } else {
+ /* Non-numerical OID, ignore */
+ }
+ }
+ } else {
+ *errp = ss;
+ ldap_objectclass_free(oc);
+ return NULL;
+ }
}
parse_whsp(&ss);
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
case TK_RIGHTPAREN:
return oc;
if ( seen_name ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_name = 1;
if ( *code != LDAP_SCHERR_OUTOFMEM )
*code = LDAP_SCHERR_BADNAME;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
} else if ( !strcmp(sval,"DESC") ) {
if ( seen_desc ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_desc = 1;
if ( kind != TK_QDSTRING ) {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
oc->oc_desc = sval;
if ( seen_obsolete ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_obsolete = 1;
if ( seen_sup ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_sup = 1;
oc->oc_sup_oids = parse_oids(&ss,code);
if ( !oc->oc_sup_oids ) {
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
} else if ( !strcmp(sval,"ABSTRACT") ) {
if ( seen_kind ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_kind = 1;
if ( seen_kind ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_kind = 1;
if ( seen_kind ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_kind = 1;
if ( seen_must ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_must = 1;
oc->oc_at_oids_must = parse_oids(&ss,code);
if ( !oc->oc_at_oids_must ) {
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
parse_whsp(&ss);
if ( seen_may ) {
*code = LDAP_SCHERR_DUPOPT;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return(NULL);
}
seen_may = 1;
oc->oc_at_oids_may = parse_oids(&ss,code);
if ( !oc->oc_at_oids_may ) {
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
parse_whsp(&ss);
ssdummy = parse_qdescrs(&ss, code);
if ( !ssdummy ) {
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
} else {
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
break;
default:
*code = LDAP_SCHERR_UNEXPTOKEN;
*errp = ss;
- free_oc(oc);
+ ldap_objectclass_free(oc);
return NULL;
}
}