/* $OpenLDAP$ */
-/*
- * Copyright 1999-2002 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * 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
+ * <http://www.OpenLDAP.org/license.html>.
*/
+
/*
* schema.c: parsing routines used by servers and clients to process
* schema definitions
#include <ldap_schema.h>
+static const char EndOfInput[] = "end of input";
+
static const char *
choose_name( char *names[], const char *fallback )
{
* 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;
**sp != ')' &&
**sp != '$' &&
**sp != '\'' &&
+ /* for suggested minimum upper bound on the number
+ * of characters (RFC 4517) */
+ **sp != '{' &&
**sp != '\0' )
(*sp)++;
q = *sp;
{
char ** res;
char ** res1;
- int kind;
+ tk_t kind;
char * sval;
int size;
int pos;
}
res = res1;
}
- res[pos] = sval;
- pos++;
+ res[pos++] = sval;
+ res[pos] = NULL;
parse_whsp(sp);
} else {
LDAP_VFREE(res);
return(NULL);
}
}
- res[pos] = NULL;
parse_whsp(sp);
return(res);
} else if ( kind == TK_QDESCR ) {
parse_woid(const char **sp, int *code)
{
char * sval;
- int kind;
+ tk_t kind;
parse_whsp(sp);
kind = get_token(sp, &sval);
/* 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) */
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)++;
{
char ** res;
char ** res1;
- int kind;
+ tk_t kind;
char * sval;
int size;
int pos;
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);
}
res = res1;
}
- res[pos] = sval;
- pos++;
+ res[pos++] = sval;
+ res[pos] = NULL;
} else {
*code = LDAP_SCHERR_UNEXPTOKEN;
LDAP_FREE(sval);
return NULL;
}
}
- res[pos] = NULL;
parse_whsp(sp);
return(res);
} else if ( kind == TK_BAREWORD ||
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;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
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;
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;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
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 {
switch (kind) {
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
- *errp = ss;
+ *errp = EndOfInput;
ldap_matchingrule_free(mr);
return NULL;
case TK_RIGHTPAREN:
}
return mr;
case TK_BAREWORD:
- if ( !strcmp(sval,"NAME") ) {
+ if ( !strcasecmp(sval,"NAME") ) {
LDAP_FREE(sval);
if ( seen_name ) {
*code = LDAP_SCHERR_DUPOPT;
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;
}
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;
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;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
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 {
switch (kind) {
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
- *errp = ss;
+ *errp = EndOfInput;
ldap_matchingruleuse_free(mru);
return NULL;
case TK_RIGHTPAREN:
}
return mru;
case TK_BAREWORD:
- if ( !strcmp(sval,"NAME") ) {
+ if ( !strcasecmp(sval,"NAME") ) {
LDAP_FREE(sval);
if ( seen_name ) {
*code = LDAP_SCHERR_DUPOPT;
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;
}
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;
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;
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;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
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);
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;
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;
}
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;
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;
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;
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;
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;
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;
}
}
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;
}
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;
}
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;
}
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;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
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 &
}
}
LDAP_FREE(sval);
+ *code = 0;
} else {
*errp = ss;
ldap_objectclass_free(oc);
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;
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;
}
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;
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;
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;
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;
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;
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;
}
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;
}
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);
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
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);
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;
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;
}
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;
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;
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;
}
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;
}
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;
}
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;
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;
switch (kind) {
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
- *errp = ss;
+ *errp = EndOfInput;
ldap_structurerule_free(sr);
return NULL;
case TK_RIGHTPAREN:
}
return sr;
case TK_BAREWORD:
- if ( !strcmp(sval,"NAME") ) {
+ if ( !strcasecmp(sval,"NAME") ) {
LDAP_FREE(sval);
if ( seen_name ) {
*code = LDAP_SCHERR_DUPOPT;
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;
}
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;
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;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
switch (kind) {
case TK_EOS:
*code = LDAP_SCHERR_NORIGHTPAREN;
- *errp = ss;
+ *errp = EndOfInput;
ldap_nameform_free(nf);
return NULL;
case TK_RIGHTPAREN:
}
return nf;
case TK_BAREWORD:
- if ( !strcmp(sval,"NAME") ) {
+ if ( !strcasecmp(sval,"NAME") ) {
LDAP_FREE(sval);
if ( seen_name ) {
*code = LDAP_SCHERR_DUPOPT;
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;
}
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;
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;
}
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;
}
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;
}
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]);
}
}