1 /* schemaparse.c - routines to parse config file objectclass definitions */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
13 #include <ac/string.h>
14 #include <ac/socket.h>
17 #include "ldap_schema.h"
19 int global_schemacheck = 1; /* schemacheck on is default */
21 static void oc_usage(void);
22 static void at_usage(void);
24 static char *const err2text[] = {
27 "ObjectClass not found",
28 "ObjectClass inappropriate SUPerior",
29 "AttributeType not found",
30 "AttributeType inappropriate USAGE",
31 "Duplicate objectClass",
32 "Duplicate attributeType",
33 "Duplicate ldapSyntax",
34 "Duplicate matchingRule",
35 "OID or name required",
36 "SYNTAX or SUPerior required",
37 "MatchingRule not found",
40 "Qualifier not supported"
46 if ( code < 0 || code >= (sizeof(err2text)/sizeof(char *)) ) {
47 return "Unknown error";
49 return err2text[code];
56 /* String compare with delimiter check. Return 0 if not
57 * matched, otherwise return length matched.
60 dscompare(const char *s1, const char *s2, char delim)
62 const char *orig = s1;
63 while (*s1++ == *s2++)
67 if (!*s1 && (!*s2 || *s2 == delim))
72 static OidMacro *om_list = NULL;
74 /* Replace an OID Macro invocation with its full numeric OID.
75 * If the macro is used with "macroname:suffix" append ".suffix"
83 /* OID macros must start alpha */
84 if ( OID_LEADCHAR( *oid ) ) {
88 for (om = om_list; om; om=om->som_next) {
89 char **names = om->som_names;
95 for( ; *names != NULL ; names++ ) {
96 int pos = dscompare(*names, oid, ':');
99 int suflen = strlen(oid + pos);
100 char *new = ch_calloc(1,
101 om->som_oid.bv_len + suflen + 1);
102 strcpy(new, om->som_oid.bv_val);
105 suflen = om->som_oid.bv_len;
107 strcpy(new+suflen, oid+pos+1);
128 fprintf( stderr, "%s: line %d: too many arguments\n",
130 usage: fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
134 oid = find_oidm( argv[1] );
138 "ObjectIdentifier \"%s\" previously defined \"%s\"",
139 fname, lineno, argv[1], oid );
143 om = (OidMacro *) ch_malloc( sizeof(OidMacro) );
145 om->som_names = NULL;
146 charray_add( &om->som_names, argv[1] );
147 om->som_oid.bv_val = find_oidm( argv[2] );
149 if (!om->som_oid.bv_val) {
150 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
151 fname, lineno, argv[2] );
155 if (om->som_oid.bv_val == argv[2]) {
156 om->som_oid.bv_val = ch_strdup( argv[2] );
159 om->som_oid.bv_len = strlen( om->som_oid.bv_val );
160 om->som_next = om_list;
179 oc = ldap_str2objectclass(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
181 fprintf( stderr, "%s: line %d: %s before %s\n",
182 fname, lineno, ldap_scherr2str(code), err );
188 if ( !OID_LEADCHAR( oc->oc_oid[0] )) {
189 /* Expand OID macros */
190 oid = find_oidm( oc->oc_oid );
193 "%s: line %d: OID %s not recognized\n",
194 fname, lineno, oc->oc_oid);
197 if ( oid != oc->oc_oid ) {
198 ldap_memfree( oc->oc_oid );
204 /* oc->oc_oid == NULL will be an error someday */
205 code = oc_add(oc,&err);
207 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
208 fname, lineno, scherr2str(code), err);
220 "ObjectClassDescription = \"(\" whsp\n"
221 " numericoid whsp ; ObjectClass identifier\n"
222 " [ \"NAME\" qdescrs ]\n"
223 " [ \"DESC\" qdstring ]\n"
224 " [ \"OBSOLETE\" whsp ]\n"
225 " [ \"SUP\" oids ] ; Superior ObjectClasses\n"
226 " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
227 " ; default structural\n"
228 " [ \"MUST\" oids ] ; AttributeTypes\n"
229 " [ \"MAY\" oids ] ; AttributeTypes\n"
238 "AttributeTypeDescription = \"(\" whsp\n"
239 " numericoid whsp ; AttributeType identifier\n"
240 " [ \"NAME\" qdescrs ] ; name used in AttributeType\n"
241 " [ \"DESC\" qdstring ] ; description\n"
242 " [ \"OBSOLETE\" whsp ]\n"
243 " [ \"SUP\" woid ] ; derived from this other\n"
245 " [ \"EQUALITY\" woid ] ; Matching Rule name\n"
246 " [ \"ORDERING\" woid ] ; Matching Rule name\n"
247 " [ \"SUBSTR\" woid ] ; Matching Rule name\n"
248 " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
249 " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n"
250 " [ \"COLLECTIVE\" whsp ] ; default not collective\n"
251 " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
252 " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
253 " ; userApplications\n"
254 " ; directoryOperation\n"
255 " ; distributedOperation\n"
268 LDAPAttributeType *at;
274 /* Kludge for OIDmacros for syntaxes. If the syntax field starts
275 * nonnumeric, look for and expand a macro. The macro's place in
276 * the input line will be replaced with a field of '0's to keep
277 * ldap_str2attributetype happy. The actual oid will be swapped
278 * into place afterwards.
280 for (; argv[3]; argv++)
282 /* Allow numeric OIDs to be wrapped in single quotes */
283 if (!strcasecmp(argv[3], "syntax") && argv[4] != NULL &&
284 !OID_LEADCHAR(argv[4][argv[4][0] == '\'' ? 1 : 0]))
288 syn = syn_find_desc(argv[4], &slen);
291 fprintf(stderr, "%s: line %d: OID %s not found\n",
292 fname, lineno, argv[4]);
295 memset(strstr(line, argv[4]), '0', slen);
296 soid = ch_strdup(syn->ssyn_syn.syn_oid );
300 at = ldap_str2attributetype(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
302 fprintf( stderr, "%s: line %d: %s before %s\n",
303 fname, lineno, ldap_scherr2str(code), err );
308 if ( !OID_LEADCHAR( at->at_oid[0] )) {
309 /* Expand OID macros */
310 oid = find_oidm( at->at_oid );
313 "%s: line %d: OID %s not recognized\n",
314 fname, lineno, at->at_oid);
317 if ( oid != at->at_oid ) {
318 ldap_memfree( at->at_oid );
323 /* at->at_oid == NULL will be an error someday */
325 ldap_memfree(at->at_syntax_oid);
326 at->at_syntax_oid = soid;
328 code = at_add(at,&err);
330 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
331 fname, lineno, scherr2str(code), err);