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 "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",
45 if ( code < 0 || code >= (sizeof(err2text)/sizeof(char *)) ) {
46 return "Unknown error";
48 return err2text[code];
55 /* String compare with delimiter check. Return 0 if not
56 * matched, otherwise return length matched.
59 dscompare(const char *s1, const char *s2, char delim)
61 const char *orig = s1;
62 while (*s1++ == *s2++)
66 if (!*s1 && (!*s2 || *s2 == delim))
71 static OidMacro *om_list = NULL;
73 /* Replace an OID Macro invocation with its full numeric OID.
74 * If the macro is used with "macroname:suffix" append ".suffix"
82 /* OID macros must start alpha */
83 if ( OID_LEADCHAR( *oid ) ) {
87 for (om = om_list; om; om=om->som_next) {
88 char **names = om->som_names;
94 for( ; *names != NULL ; names++ ) {
95 int pos = dscompare(*names, oid, ':');
98 int suflen = strlen(oid + pos);
99 char *new = ch_calloc(1,
100 om->som_oid.bv_len + suflen + 1);
101 strcpy(new, om->som_oid.bv_val);
104 suflen = om->som_oid.bv_len;
106 strcpy(new+suflen, oid+pos+1);
127 fprintf( stderr, "%s: line %d: too many arguments\n",
129 usage: fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
130 exit( EXIT_FAILURE );
133 oid = find_oidm( argv[1] );
137 "ObjectIdentifier \"%s\" previously defined \"%s\"",
138 fname, lineno, argv[1], oid );
139 exit( EXIT_FAILURE );
142 om = (OidMacro *) ch_malloc( sizeof(OidMacro) );
144 om->som_names = NULL;
145 charray_add( &om->som_names, argv[1] );
146 om->som_oid.bv_val = find_oidm( argv[2] );
148 if (!om->som_oid.bv_val) {
149 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
150 fname, lineno, argv[2] );
154 if (om->som_oid.bv_val == argv[2]) {
155 om->som_oid.bv_val = ch_strdup( argv[2] );
158 om->som_oid.bv_len = strlen( om->som_oid.bv_val );
159 om->som_next = om_list;
176 oc = ldap_str2objectclass(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
178 fprintf( stderr, "%s: line %d: %s before %s\n",
179 fname, lineno, ldap_scherr2str(code), err );
183 if ( !OID_LEADCHAR( oc->oc_oid[0] )) {
184 /* Expand OID macros */
185 oid = find_oidm( oc->oc_oid );
188 "%s: line %d: OID %s not recognized\n",
189 fname, lineno, oc->oc_oid);
190 exit( EXIT_FAILURE );
192 if ( oid != oc->oc_oid ) {
193 ldap_memfree( oc->oc_oid );
198 /* oc->oc_oid == NULL will be an error someday */
199 code = oc_add(oc,&err);
201 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
202 fname, lineno, scherr2str(code), err);
203 exit( EXIT_FAILURE );
212 "ObjectClassDescription = \"(\" whsp\n"
213 " numericoid whsp ; ObjectClass identifier\n"
214 " [ \"NAME\" qdescrs ]\n"
215 " [ \"DESC\" qdstring ]\n"
216 " [ \"OBSOLETE\" whsp ]\n"
217 " [ \"SUP\" oids ] ; Superior ObjectClasses\n"
218 " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
219 " ; default structural\n"
220 " [ \"MUST\" oids ] ; AttributeTypes\n"
221 " [ \"MAY\" oids ] ; AttributeTypes\n"
223 exit( EXIT_FAILURE );
231 "AttributeTypeDescription = \"(\" whsp\n"
232 " numericoid whsp ; AttributeType identifier\n"
233 " [ \"NAME\" qdescrs ] ; name used in AttributeType\n"
234 " [ \"DESC\" qdstring ] ; description\n"
235 " [ \"OBSOLETE\" whsp ]\n"
236 " [ \"SUP\" woid ] ; derived from this other\n"
238 " [ \"EQUALITY\" woid ] ; Matching Rule name\n"
239 " [ \"ORDERING\" woid ] ; Matching Rule name\n"
240 " [ \"SUBSTR\" woid ] ; Matching Rule name\n"
241 " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
242 " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n"
243 " [ \"COLLECTIVE\" whsp ] ; default not collective\n"
244 " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
245 " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
246 " ; userApplications\n"
247 " ; directoryOperation\n"
248 " ; distributedOperation\n"
251 exit( EXIT_FAILURE );
262 LDAPAttributeType *at;
268 /* Kludge for OIDmacros for syntaxes. If the syntax field starts
269 * nonnumeric, look for and expand a macro. The macro's place in
270 * the input line will be replaced with a field of '0's to keep
271 * ldap_str2attributetype happy. The actual oid will be swapped
272 * into place afterwards.
274 for (; argv[3]; argv++)
276 /* Allow numeric OIDs to be wrapped in single quotes */
277 if (!strcasecmp(argv[3], "syntax") && argv[4] != NULL &&
278 !OID_LEADCHAR(argv[4][argv[4][0] == '\'' ? 1 : 0]))
282 syn = syn_find_desc(argv[4], &slen);
285 fprintf(stderr, "%s: line %d: OID %s not found\n",
286 fname, lineno, argv[4]);
287 exit( EXIT_FAILURE );
289 memset(strstr(line, argv[4]), '0', slen);
290 soid = ch_strdup(syn->ssyn_syn.syn_oid );
294 at = ldap_str2attributetype(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
296 fprintf( stderr, "%s: line %d: %s before %s\n",
297 fname, lineno, ldap_scherr2str(code), err );
301 if ( !OID_LEADCHAR( at->at_oid[0] )) {
302 /* Expand OID macros */
303 oid = find_oidm( at->at_oid );
306 "%s: line %d: OID %s not recognized\n",
307 fname, lineno, at->at_oid);
308 exit( EXIT_FAILURE );
310 if ( oid != at->at_oid ) {
311 ldap_memfree( at->at_oid );
316 /* at->at_oid == NULL will be an error someday */
318 ldap_memfree(at->at_syntax_oid);
319 at->at_syntax_oid = soid;
321 code = at_add(at,&err);
323 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
324 fname, lineno, scherr2str(code), err);
325 exit( EXIT_FAILURE );