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) LDAP_GCCATTR((noreturn));
22 static void at_usage(void) LDAP_GCCATTR((noreturn));
24 static char *const err2text[] = {
27 "ObjectClass not found",
28 "AttributeType not found",
29 "Duplicate objectClass",
30 "Duplicate attributeType",
31 "Duplicate ldapSyntax",
32 "Duplicate matchingRule",
33 "OID or name required",
34 "SYNTAX or SUPerior required",
35 "MatchingRule not found",
43 if ( code < 0 || code >= (sizeof(err2text)/sizeof(char *)) ) {
44 return "Unknown error";
46 return err2text[code];
53 /* String compare with delimiter check. Return 0 if not
54 * matched, otherwise return length matched.
57 dscompare(const char *s1, const char *s2, char delim)
59 const char *orig = s1;
60 while (*s1++ == *s2++)
64 if (!*s1 && (!*s2 || *s2 == delim))
69 static OidMacro *om_list = NULL;
71 /* Replace an OID Macro invocation with its full numeric OID.
72 * If the macro is used with "macroname:suffix" append ".suffix"
80 /* OID macros must start alpha */
81 if ( OID_LEADCHAR( *oid ) ) {
85 for (om = om_list; om; om=om->som_next) {
86 char **names = om->som_names;
92 for( ; *names != NULL ; names++ ) {
93 int pos = dscompare(*names, oid, ':');
96 int suflen = strlen(oid + pos);
97 char *new = ch_calloc(1,
98 om->som_oid.bv_len + suflen + 1);
99 strcpy(new, om->som_oid.bv_val);
102 suflen = om->som_oid.bv_len;
104 strcpy(new+suflen, oid+pos+1);
125 fprintf( stderr, "%s: line %d: too many arguments\n",
127 usage: fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
128 exit( EXIT_FAILURE );
131 oid = find_oidm( argv[1] );
135 "ObjectIdentifier \"%s\" previously defined \"%s\"",
136 fname, lineno, argv[1], oid );
137 exit( EXIT_FAILURE );
140 om = (OidMacro *) ch_malloc( sizeof(OidMacro) );
142 om->som_names = NULL;
143 charray_add( &om->som_names, argv[1] );
144 om->som_oid.bv_val = find_oidm( argv[2] );
146 if (!om->som_oid.bv_val) {
147 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
148 fname, lineno, argv[2] );
152 if (om->som_oid.bv_val == argv[2]) {
153 om->som_oid.bv_val = ch_strdup( argv[2] );
156 om->som_oid.bv_len = strlen( om->som_oid.bv_val );
157 om->som_next = om_list;
169 LDAP_OBJECT_CLASS *oc;
174 oc = ldap_str2objectclass(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
176 fprintf( stderr, "%s: line %d: %s before %s\n",
177 fname, lineno, ldap_scherr2str(code), err );
181 if ( !OID_LEADCHAR( oc->oc_oid[0] )) {
182 /* Expand OID macros */
183 oid = find_oidm( oc->oc_oid );
186 "%s: line %d: OID %s not recognized\n",
187 fname, lineno, oc->oc_oid);
188 exit( EXIT_FAILURE );
190 if ( oid != oc->oc_oid ) {
191 ldap_memfree( oc->oc_oid );
196 /* oc->oc_oid == NULL will be an error someday */
197 code = oc_add(oc,&err);
199 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
200 fname, lineno, scherr2str(code), err);
201 exit( EXIT_FAILURE );
210 "ObjectClassDescription = \"(\" whsp\n"
211 " numericoid whsp ; ObjectClass identifier\n"
212 " [ \"NAME\" qdescrs ]\n"
213 " [ \"DESC\" qdstring ]\n"
214 " [ \"OBSOLETE\" whsp ]\n"
215 " [ \"SUP\" oids ] ; Superior ObjectClasses\n"
216 " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
217 " ; default structural\n"
218 " [ \"MUST\" oids ] ; AttributeTypes\n"
219 " [ \"MAY\" oids ] ; AttributeTypes\n"
221 exit( EXIT_FAILURE );
229 "AttributeTypeDescription = \"(\" whsp\n"
230 " numericoid whsp ; AttributeType identifier\n"
231 " [ \"NAME\" qdescrs ] ; name used in AttributeType\n"
232 " [ \"DESC\" qdstring ] ; description\n"
233 " [ \"OBSOLETE\" whsp ]\n"
234 " [ \"SUP\" woid ] ; derived from this other\n"
236 " [ \"EQUALITY\" woid ] ; Matching Rule name\n"
237 " [ \"ORDERING\" woid ] ; Matching Rule name\n"
238 " [ \"SUBSTR\" woid ] ; Matching Rule name\n"
239 " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
240 " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n"
241 " [ \"COLLECTIVE\" whsp ] ; default not collective\n"
242 " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
243 " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
244 " ; userApplications\n"
245 " ; directoryOperation\n"
246 " ; distributedOperation\n"
249 exit( EXIT_FAILURE );
260 LDAP_ATTRIBUTE_TYPE *at;
266 /* Kludge for OIDmacros for syntaxes. If the syntax field starts
267 * nonnumeric, look for and expand a macro. The macro's place in
268 * the input line will be replaced with a field of '0's to keep
269 * ldap_str2attributetype happy. The actual oid will be swapped
270 * into place afterwards.
272 for (; argv[3]; argv++)
274 if (!strcasecmp(argv[3], "syntax") &&
275 !OID_LEADCHAR(*argv[4]))
279 syn = syn_find_desc(argv[4], &slen);
282 fprintf(stderr, "%s: line %d: OID %s not found\n",
283 fname, lineno, argv[4]);
284 exit( EXIT_FAILURE );
286 memset(strstr(line, argv[4]), '0', slen);
287 soid = ch_strdup(syn->ssyn_syn.syn_oid );
291 at = ldap_str2attributetype(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
293 fprintf( stderr, "%s: line %d: %s before %s\n",
294 fname, lineno, ldap_scherr2str(code), err );
298 if ( !OID_LEADCHAR( at->at_oid[0] )) {
299 /* Expand OID macros */
300 oid = find_oidm( at->at_oid );
303 "%s: line %d: OID %s not recognized\n",
304 fname, lineno, at->at_oid);
305 exit( EXIT_FAILURE );
307 if ( oid != at->at_oid ) {
308 ldap_memfree( at->at_oid );
313 /* at->at_oid == NULL will be an error someday */
315 ldap_memfree(at->at_syntax_oid);
316 at->at_syntax_oid = soid;
318 code = at_add(at,&err);
320 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
321 fname, lineno, scherr2str(code), err);
322 exit( EXIT_FAILURE );