]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/schema.c
rename ldap_pvt_init_utils() to ldap_int_utils_init() and provide
[openldap] / libraries / libldap / schema.c
index 83c333db02b1b95b13323156d6a3cdfea6fc9b54..e404a32724717ae0b9290723c49588d3f56ad420 100644 (file)
@@ -64,6 +64,7 @@ safe_string_free(safe_string * ss)
 static char *
 safe_string_val(safe_string * ss)
 {
+       ss->val[ss->pos] = '\0';
        return(ss->val);
 }
 
@@ -119,7 +120,8 @@ print_whsp(safe_string *ss)
 static int
 print_numericoid(safe_string *ss, char *s)
 {
-       return(append_to_safe_string(ss,s));
+       if ( s )
+               return(append_to_safe_string(ss,s));
 }
 
 /* This one is identical to print_qdescr */
@@ -250,7 +252,7 @@ ldap_objectclass2str( LDAP_OBJECT_CLASS * oc )
                print_qdstring(ss,oc->oc_desc);
        }
 
-       if ( oc->oc_obsolete ) {
+       if ( oc->oc_obsolete == LDAP_SCHEMA_YES ) {
                print_literal(ss, "OBSOLETE");
                print_whsp(ss);
        }
@@ -261,13 +263,13 @@ ldap_objectclass2str( LDAP_OBJECT_CLASS * oc )
        }
 
        switch (oc->oc_kind) {
-       case 0:
+       case LDAP_SCHEMA_ABSTRACT:
                print_literal(ss,"ABSTRACT");
                break;
-       case 1:
+       case LDAP_SCHEMA_STRUCTURAL:
                print_literal(ss,"STRUCTURAL");
                break;
-       case 2:
+       case LDAP_SCHEMA_AUXILIARY:
                print_literal(ss,"AUXILIARY");
                break;
        default:
@@ -324,7 +326,7 @@ ldap_attributetype2str( LDAP_ATTRIBUTE_TYPE * at )
                print_qdstring(ss,at->at_desc);
        }
 
-       if ( at->at_obsolete ) {
+       if ( at->at_obsolete == LDAP_SCHEMA_YES ) {
                print_literal(ss, "OBSOLETE");
                print_whsp(ss);
        }
@@ -351,35 +353,36 @@ ldap_attributetype2str( LDAP_ATTRIBUTE_TYPE * at )
 
        if ( at->at_syntax_oid ) {
                print_literal(ss,"SYNTAX");
+               print_whsp(ss);
                print_noidlen(ss,at->at_syntax_oid,at->at_syntax_len);
        }
 
-       if ( at->at_single_value ) {
+       if ( at->at_single_value == LDAP_SCHEMA_YES ) {
                print_literal(ss,"SINGLE-VALUE");
                print_whsp(ss);
        }
 
-       if ( at->at_collective ) {
+       if ( at->at_collective == LDAP_SCHEMA_YES ) {
                print_literal(ss,"COLLECTIVE");
                print_whsp(ss);
        }
 
-       if ( at->at_no_user_mod ) {
+       if ( at->at_no_user_mod == LDAP_SCHEMA_YES ) {
                print_literal(ss,"NO-USER-MODIFICATION");
                print_whsp(ss);
        }
 
-       if ( at->at_usage ) {
+       if ( at->at_usage != LDAP_SCHEMA_USER_APPLICATIONS ) {
                print_literal(ss,"USAGE");
                print_whsp(ss);
                switch (at->at_usage) {
-               case 1:
+               case LDAP_SCHEMA_DIRECTORY_OPERATION:
                        print_literal(ss,"directoryOperation");
                        break;
-               case 2:
+               case LDAP_SCHEMA_DISTRIBUTED_OPERATION:
                        print_literal(ss,"distributedOperation");
                        break;
-               case 3:
+               case LDAP_SCHEMA_DSA_OPERATION:
                        print_literal(ss,"dSAOperation");
                        break;
                default:
@@ -417,6 +420,28 @@ charray_free( char **array )
        free( (char *) array );
 }
 
+/*
+ * Now come the parsers.  There is one parser for each entity type:
+ * objectclasses, attributetypes, etc.
+ *
+ * Each of them is written as a recursive-descent parser, except that
+ * none of them is really recursive.  But the idea is kept: there
+ * is one routine per non-terminal that eithers gobbles lexical tokens
+ * or calls lower-level routines, etc.
+ *
+ * The scanner is implemented in the routine get_token.  Actually,
+ * get_token is more than a scanner and will return tokens that are
+ * in fact non-terminals in the grammar.  So you can see the whole
+ * approach as the combination of a low-level bottom-up recognizer
+ * combined with a scanner and a number of top-down parsers.  Or just
+ * consider that the real grammars recognized by the parsers are not
+ * those of the standards.  As a matter of fact, our parsers are more
+ * liberal than the spec when there is no ambiguity.
+ *
+ * The difference is pretty academic (modulo bugs or incorrect
+ * interpretation of the specs).
+ */
+
 #define TK_NOENDQUOTE  -2
 #define TK_OUTOFMEM    -1
 #define TK_EOS         0
@@ -529,7 +554,7 @@ parse_numericoid(char **sp, int *code)
        while (**sp) {
                if ( !isdigit(**sp) ) {
                        /* Initial char is not a digit or char after dot is not a digit */
-                       *code = SCHEMA_ERR_NODIGIT;
+                       *code = LDAP_SCHERR_NODIGIT;
                        return NULL;
                }
                (*sp)++;
@@ -544,7 +569,7 @@ parse_numericoid(char **sp, int *code)
        len = *sp - start;
        res = malloc(len+1);
        if (!res) {
-         *code = SCHEMA_ERR_OUTOFMEM;
+         *code = LDAP_SCHERR_OUTOFMEM;
          return(NULL);
        }
        strncpy(res,start,len);
@@ -570,7 +595,7 @@ parse_qdescrs(char **sp, int *code)
                size = 3;
                res = calloc(3,sizeof(char *));
                if ( !res ) {
-                       *code = SCHEMA_ERR_OUTOFMEM;
+                       *code = LDAP_SCHERR_OUTOFMEM;
                        return NULL;
                }
                pos = 0;
@@ -585,7 +610,7 @@ parse_qdescrs(char **sp, int *code)
                                        res1 = realloc(res,size*sizeof(char *));
                                        if ( !res1 ) {
                                                charray_free(res);
-                                               *code = SCHEMA_ERR_OUTOFMEM;
+                                               *code = LDAP_SCHERR_OUTOFMEM;
                                                return(NULL);
                                        }
                                        res = res1;
@@ -595,7 +620,7 @@ parse_qdescrs(char **sp, int *code)
                                parse_whsp(sp);
                        } else {
                                charray_free(res);
-                               *code = SCHEMA_ERR_UNEXPTOKEN;
+                               *code = LDAP_SCHERR_UNEXPTOKEN;
                                return(NULL);
                        }
                }
@@ -605,7 +630,7 @@ parse_qdescrs(char **sp, int *code)
        } else if ( kind == TK_QDESCR ) {
                res = calloc(2,sizeof(char *));
                if ( !res ) {
-                       *code = SCHEMA_ERR_OUTOFMEM;
+                       *code = LDAP_SCHERR_OUTOFMEM;
                        return NULL;
                }
                res[0] = sval;
@@ -613,7 +638,7 @@ parse_qdescrs(char **sp, int *code)
                parse_whsp(sp);
                return res;
        } else {
-               *code = SCHEMA_ERR_BADNAME;
+               *code = LDAP_SCHERR_BADNAME;
                return NULL;
        }
 }
@@ -628,7 +653,7 @@ parse_woid(char **sp, int *code)
        parse_whsp(sp);
        kind = get_token(sp, &sval);
        if ( kind != TK_BAREWORD ) {
-               *code = SCHEMA_ERR_UNEXPTOKEN;
+               *code = LDAP_SCHERR_UNEXPTOKEN;
                return NULL;
        }
        parse_whsp(sp);
@@ -645,7 +670,7 @@ parse_noidlen(char **sp, int *code, int *len)
        *len = 0;
        kind = get_token(sp, &sval);
        if ( kind != TK_BAREWORD ) {
-               *code = SCHEMA_ERR_UNEXPTOKEN;
+               *code = LDAP_SCHERR_UNEXPTOKEN;
                return NULL;
        }
        if ( **sp == '{' ) {
@@ -655,7 +680,7 @@ parse_noidlen(char **sp, int *code, int *len)
                        (*sp)++;
                (*sp)++;
                if ( **sp != '}' ) {
-                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                       *code = LDAP_SCHERR_UNEXPTOKEN;
                        ldap_memfree(sval);
                        return NULL;
                }
@@ -688,7 +713,7 @@ parse_oids(char **sp, int *code)
                size = 3;
                res = calloc(3,sizeof(char *));
                if ( !res ) {
-                       *code = SCHEMA_ERR_OUTOFMEM;
+                       *code = LDAP_SCHERR_OUTOFMEM;
                        return NULL;
                }
                pos = 0;
@@ -698,7 +723,7 @@ parse_oids(char **sp, int *code)
                        res[pos] = sval;
                        pos++;
                } else {
-                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                       *code = LDAP_SCHERR_UNEXPTOKEN;
                        charray_free(res);
                        return NULL;
                }
@@ -716,7 +741,7 @@ parse_oids(char **sp, int *code)
                                                res1 = realloc(res,size*sizeof(char *));
                                                if ( !res1 ) {
                                                  charray_free(res);
-                                                 *code = SCHEMA_ERR_OUTOFMEM;
+                                                 *code = LDAP_SCHERR_OUTOFMEM;
                                                  return(NULL);
                                                }
                                                res = res1;
@@ -724,13 +749,13 @@ parse_oids(char **sp, int *code)
                                        res[pos] = sval;
                                        pos++;
                                } else {
-                                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                                       *code = LDAP_SCHERR_UNEXPTOKEN;
                                        charray_free(res);
                                        return NULL;
                                }
                                parse_whsp(sp);
                        } else {
-                               *code = SCHEMA_ERR_UNEXPTOKEN;
+                               *code = LDAP_SCHERR_UNEXPTOKEN;
                                charray_free(res);
                                return NULL;
                        }
@@ -741,7 +766,7 @@ parse_oids(char **sp, int *code)
        } else if ( kind == TK_BAREWORD ) {
                res = calloc(2,sizeof(char *));
                if ( !res ) {
-                       *code = SCHEMA_ERR_OUTOFMEM;
+                       *code = LDAP_SCHERR_OUTOFMEM;
                        return NULL;
                }
                res[0] = sval;
@@ -749,7 +774,7 @@ parse_oids(char **sp, int *code)
                parse_whsp(sp);
                return res;
        } else {
-               *code = SCHEMA_ERR_BADNAME;
+               *code = LDAP_SCHERR_BADNAME;
                return NULL;
        }
 }
@@ -792,13 +817,13 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
        at = calloc(1,sizeof(LDAP_ATTRIBUTE_TYPE));
 
        if ( !at ) {
-               *code = SCHEMA_ERR_OUTOFMEM;
+               *code = LDAP_SCHERR_OUTOFMEM;
                return NULL;
        }
 
        kind = get_token(&ss,&sval);
        if ( kind != TK_LEFTPAREN ) {
-               *code = SCHEMA_ERR_NOLEFTPAREN;
+               *code = LDAP_SCHERR_NOLEFTPAREN;
                free_at(at);
                return NULL;
        }
@@ -820,7 +845,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                kind = get_token(&ss,&sval);
                switch (kind) {
                case TK_EOS:
-                       *code = SCHEMA_ERR_NORIGHTPAREN;
+                       *code = LDAP_SCHERR_NORIGHTPAREN;
                        *errp = ss;
                        free_at(at);
                        return NULL;
@@ -829,7 +854,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                case TK_BAREWORD:
                        if ( !strcmp(sval,"NAME") ) {
                                if ( seen_name ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -837,15 +862,15 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                seen_name = 1;
                                at->at_names = parse_qdescrs(&ss,code);
                                if ( !at->at_names ) {
-                                       if ( *code != SCHEMA_ERR_OUTOFMEM )
-                                               *code = SCHEMA_ERR_BADNAME;
+                                       if ( *code != LDAP_SCHERR_OUTOFMEM )
+                                               *code = LDAP_SCHERR_BADNAME;
                                        *errp = ss;
                                        free_at(at);
                                        return NULL;
                                }
                        } else if ( !strcmp(sval,"DESC") ) {
                                if ( seen_desc ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -854,7 +879,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                parse_whsp(&ss);
                                kind = get_token(&ss,&sval);
                                if ( kind != TK_QDSTRING ) {
-                                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                                       *code = LDAP_SCHERR_UNEXPTOKEN;
                                        *errp = ss;
                                        free_at(at);
                                        return NULL;
@@ -863,17 +888,17 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"OBSOLETE") ) {
                                if ( seen_obsolete ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
                                }
                                seen_obsolete = 1;
-                               at->at_obsolete = 1;
+                               at->at_obsolete = LDAP_SCHEMA_YES;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"SUP") ) {
                                if ( seen_sup ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -887,7 +912,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                }
                        } else if ( !strcmp(sval,"EQUALITY") ) {
                                if ( seen_equality ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -901,7 +926,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                }
                        } else if ( !strcmp(sval,"ORDERING") ) {
                                if ( seen_ordering ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -915,7 +940,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                }
                        } else if ( !strcmp(sval,"SUBSTR") ) {
                                if ( seen_substr ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -929,7 +954,7 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                }
                        } else if ( !strcmp(sval,"SYNTAX") ) {
                                if ( seen_syntax ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -944,34 +969,34 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                }
                        } else if ( !strcmp(sval,"SINGLE-VALUE") ) {
                                if ( at->at_single_value ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
                                }
-                               at->at_single_value = 1;
+                               at->at_single_value = LDAP_SCHEMA_YES;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"COLLECTIVE") ) {
                                if ( at->at_collective ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
                                }
-                               at->at_collective = 1;
+                               at->at_collective = LDAP_SCHEMA_YES;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"NO-USER-MODIFICATION") ) {
                                if ( at->at_no_user_mod ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
                                }
-                               at->at_no_user_mod = 1;
+                               at->at_no_user_mod = LDAP_SCHEMA_YES;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"USAGE") ) {
                                if ( seen_usage ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_at(at);
                                        return(NULL);
@@ -980,34 +1005,34 @@ ldap_str2attributetype( char * s, int * code, char ** errp )
                                parse_whsp(&ss);
                                kind = get_token(&ss,&sval);
                                if ( kind != TK_BAREWORD ) {
-                                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                                       *code = LDAP_SCHERR_UNEXPTOKEN;
                                        *errp = ss;
                                        free_at(at);
                                        return NULL;
                                }
                                if ( !strcasecmp(sval,"userApplications") )
-                                       at->at_usage = 0;
+                                       at->at_usage = LDAP_SCHEMA_USER_APPLICATIONS;
                                else if ( !strcasecmp(sval,"directoryOperation") )
-                                       at->at_usage = 1;
+                                       at->at_usage = LDAP_SCHEMA_DIRECTORY_OPERATION;
                                else if ( !strcasecmp(sval,"distributedOperation") )
-                                       at->at_usage = 2;
+                                       at->at_usage = LDAP_SCHEMA_DISTRIBUTED_OPERATION;
                                else if ( !strcasecmp(sval,"dSAOperation") )
-                                       at->at_usage = 3;
+                                       at->at_usage = LDAP_SCHEMA_DSA_OPERATION;
                                else {
-                                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                                       *code = LDAP_SCHERR_UNEXPTOKEN;
                                        *errp = ss;
                                        free_at(at);
                                        return NULL;
                                }
                        } else {
-                               *code = SCHEMA_ERR_UNEXPTOKEN;
+                               *code = LDAP_SCHERR_UNEXPTOKEN;
                                *errp = ss;
                                free_at(at);
                                return NULL;
                        }
                        break;
                default:
-                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                       *code = LDAP_SCHERR_UNEXPTOKEN;
                        *errp = ss;
                        free_at(at);
                        return NULL;
@@ -1046,13 +1071,13 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
        oc = calloc(1,sizeof(LDAP_OBJECT_CLASS));
 
        if ( !oc ) {
-               *code = SCHEMA_ERR_OUTOFMEM;
+               *code = LDAP_SCHERR_OUTOFMEM;
                return NULL;
        }
 
        kind = get_token(&ss,&sval);
        if ( kind != TK_LEFTPAREN ) {
-               *code = SCHEMA_ERR_NOLEFTPAREN;
+               *code = LDAP_SCHERR_NOLEFTPAREN;
                free_oc(oc);
                return NULL;
        }
@@ -1074,7 +1099,7 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                kind = get_token(&ss,&sval);
                switch (kind) {
                case TK_EOS:
-                       *code = SCHEMA_ERR_NORIGHTPAREN;
+                       *code = LDAP_SCHERR_NORIGHTPAREN;
                        *errp = ss;
                        free_oc(oc);
                        return NULL;
@@ -1083,7 +1108,7 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                case TK_BAREWORD:
                        if ( !strcmp(sval,"NAME") ) {
                                if ( seen_name ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
@@ -1091,15 +1116,15 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                                seen_name = 1;
                                oc->oc_names = parse_qdescrs(&ss,code);
                                if ( !oc->oc_names ) {
-                                       if ( *code != SCHEMA_ERR_OUTOFMEM )
-                                               *code = SCHEMA_ERR_BADNAME;
+                                       if ( *code != LDAP_SCHERR_OUTOFMEM )
+                                               *code = LDAP_SCHERR_BADNAME;
                                        *errp = ss;
                                        free_oc(oc);
                                        return NULL;
                                }
                        } else if ( !strcmp(sval,"DESC") ) {
                                if ( seen_desc ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
@@ -1108,7 +1133,7 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                                parse_whsp(&ss);
                                kind = get_token(&ss,&sval);
                                if ( kind != TK_QDSTRING ) {
-                                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                                       *code = LDAP_SCHERR_UNEXPTOKEN;
                                        *errp = ss;
                                        free_oc(oc);
                                        return NULL;
@@ -1117,17 +1142,17 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"OBSOLETE") ) {
                                if ( seen_obsolete ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
                                }
                                seen_obsolete = 1;
-                               oc->oc_obsolete = 1;
+                               oc->oc_obsolete = LDAP_SCHEMA_YES;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"SUP") ) {
                                if ( seen_sup ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
@@ -1144,37 +1169,37 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                                }
                        } else if ( !strcmp(sval,"ABSTRACT") ) {
                                if ( seen_kind ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
                                }
                                seen_kind = 1;
-                               oc->oc_kind = 0;
+                               oc->oc_kind = LDAP_SCHEMA_ABSTRACT;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"STRUCTURAL") ) {
                                if ( seen_kind ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
                                }
                                seen_kind = 1;
-                               oc->oc_kind = 1;
+                               oc->oc_kind = LDAP_SCHEMA_STRUCTURAL;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"AUXILIARY") ) {
                                if ( seen_kind ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
                                }
                                seen_kind = 1;
-                               oc->oc_kind = 2;
+                               oc->oc_kind = LDAP_SCHEMA_AUXILIARY;
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"MUST") ) {
                                if ( seen_must ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
@@ -1189,7 +1214,7 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                                parse_whsp(&ss);
                        } else if ( !strcmp(sval,"MAY") ) {
                                if ( seen_may ) {
-                                       *code = SCHEMA_ERR_DUPOPT;
+                                       *code = LDAP_SCHERR_DUPOPT;
                                        *errp = ss;
                                        free_oc(oc);
                                        return(NULL);
@@ -1203,14 +1228,14 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
                                }
                                parse_whsp(&ss);
                        } else {
-                               *code = SCHEMA_ERR_UNEXPTOKEN;
+                               *code = LDAP_SCHERR_UNEXPTOKEN;
                                *errp = ss;
                                free_oc(oc);
                                return NULL;
                        }
                        break;
                default:
-                       *code = SCHEMA_ERR_UNEXPTOKEN;
+                       *code = LDAP_SCHERR_UNEXPTOKEN;
                        *errp = ss;
                        free_oc(oc);
                        return NULL;
@@ -1218,4 +1243,25 @@ ldap_str2objectclass( char * s, int * code, char ** errp )
        }
 }
 
+static char *err2text[] = {
+       "",
+       "Out of memory",
+       "Unexpected token",
+       "Missing opening parenthesis",
+       "Missing closing parenthesis",
+       "Expecting digit",
+       "Expecting a name",
+       "Bad description",
+       "Bad superiors",
+       "Duplicate option"
+};
 
+char *
+ldap_scherr2str(int code)
+{
+       if ( code < 1 || code >= (sizeof(err2text)/sizeof(char *)) ) {
+               return "Unknown error";
+       } else {
+               return err2text[code];
+       }
+}