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",
47 if ( code < 0 || code >= (sizeof(err2text)/sizeof(char *)) ) {
48 return "Unknown error";
50 return err2text[code];
54 /* check schema descr validity */
55 int slap_valid_descr( const char *descr )
59 if( !DESC_LEADCHAR( descr[i] ) ) {
64 if( !DESC_CHAR( descr[i] ) ) {
75 /* String compare with delimiter check. Return 0 if not
76 * matched, otherwise return length matched.
79 dscompare(const char *s1, const char *s2, char delim)
81 const char *orig = s1;
82 while (*s1++ == *s2++)
86 if (!*s1 && (!*s2 || *s2 == delim))
91 static OidMacro *om_list = NULL;
93 /* Replace an OID Macro invocation with its full numeric OID.
94 * If the macro is used with "macroname:suffix" append ".suffix"
102 /* OID macros must start alpha */
103 if ( OID_LEADCHAR( *oid ) ) {
107 for (om = om_list; om; om=om->som_next) {
108 char **names = om->som_names;
110 if( names == NULL ) {
114 for( ; *names != NULL ; names++ ) {
115 int pos = dscompare(*names, oid, ':');
118 int suflen = strlen(oid + pos);
119 char *new = ch_calloc(1,
120 om->som_oid.bv_len + suflen + 1);
121 strcpy(new, om->som_oid.bv_val);
124 suflen = om->som_oid.bv_len;
126 strcpy(new+suflen, oid+pos+1);
147 fprintf( stderr, "%s: line %d: too many arguments\n",
149 usage: fprintf( stderr, "\tObjectIdentifier <name> <oid>\n");
153 oid = find_oidm( argv[1] );
157 "ObjectIdentifier \"%s\" previously defined \"%s\"",
158 fname, lineno, argv[1], oid );
162 om = (OidMacro *) ch_malloc( sizeof(OidMacro) );
164 om->som_names = NULL;
165 charray_add( &om->som_names, argv[1] );
166 om->som_oid.bv_val = find_oidm( argv[2] );
168 if (!om->som_oid.bv_val) {
169 fprintf( stderr, "%s: line %d: OID %s not recognized\n",
170 fname, lineno, argv[2] );
174 if (om->som_oid.bv_val == argv[2]) {
175 om->som_oid.bv_val = ch_strdup( argv[2] );
178 om->som_oid.bv_len = strlen( om->som_oid.bv_val );
179 om->som_next = om_list;
198 oc = ldap_str2objectclass(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
200 fprintf( stderr, "%s: line %d: %s before %s\n",
201 fname, lineno, ldap_scherr2str(code), err );
207 if ( !OID_LEADCHAR( oc->oc_oid[0] )) {
208 /* Expand OID macros */
209 oid = find_oidm( oc->oc_oid );
212 "%s: line %d: OID %s not recognized\n",
213 fname, lineno, oc->oc_oid);
216 if ( oid != oc->oc_oid ) {
217 ldap_memfree( oc->oc_oid );
223 /* oc->oc_oid == NULL will be an error someday */
224 code = oc_add(oc,&err);
226 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
227 fname, lineno, scherr2str(code), err);
239 "ObjectClassDescription = \"(\" whsp\n"
240 " numericoid whsp ; ObjectClass identifier\n"
241 " [ \"NAME\" qdescrs ]\n"
242 " [ \"DESC\" qdstring ]\n"
243 " [ \"OBSOLETE\" whsp ]\n"
244 " [ \"SUP\" oids ] ; Superior ObjectClasses\n"
245 " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
246 " ; default structural\n"
247 " [ \"MUST\" oids ] ; AttributeTypes\n"
248 " [ \"MAY\" oids ] ; AttributeTypes\n"
257 "AttributeTypeDescription = \"(\" whsp\n"
258 " numericoid whsp ; AttributeType identifier\n"
259 " [ \"NAME\" qdescrs ] ; name used in AttributeType\n"
260 " [ \"DESC\" qdstring ] ; description\n"
261 " [ \"OBSOLETE\" whsp ]\n"
262 " [ \"SUP\" woid ] ; derived from this other\n"
264 " [ \"EQUALITY\" woid ] ; Matching Rule name\n"
265 " [ \"ORDERING\" woid ] ; Matching Rule name\n"
266 " [ \"SUBSTR\" woid ] ; Matching Rule name\n"
267 " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
268 " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n"
269 " [ \"COLLECTIVE\" whsp ] ; default not collective\n"
270 " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
271 " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
272 " ; userApplications\n"
273 " ; directoryOperation\n"
274 " ; distributedOperation\n"
287 LDAPAttributeType *at;
293 /* Kludge for OIDmacros for syntaxes. If the syntax field starts
294 * nonnumeric, look for and expand a macro. The macro's place in
295 * the input line will be replaced with a field of '0's to keep
296 * ldap_str2attributetype happy. The actual oid will be swapped
297 * into place afterwards.
299 for (; argv[3]; argv++)
301 /* Allow numeric OIDs to be wrapped in single quotes */
302 if (!strcasecmp(argv[3], "syntax") && argv[4] != NULL &&
303 !OID_LEADCHAR(argv[4][argv[4][0] == '\'' ? 1 : 0]))
307 syn = syn_find_desc(argv[4], &slen);
310 fprintf(stderr, "%s: line %d: OID %s not found\n",
311 fname, lineno, argv[4]);
314 memset(strstr(line, argv[4]), '0', slen);
315 soid = ch_strdup(syn->ssyn_syn.syn_oid );
319 at = ldap_str2attributetype(line,&code,&err,LDAP_SCHEMA_ALLOW_ALL);
321 fprintf( stderr, "%s: line %d: %s before %s\n",
322 fname, lineno, ldap_scherr2str(code), err );
327 if ( !OID_LEADCHAR( at->at_oid[0] )) {
328 /* Expand OID macros */
329 oid = find_oidm( at->at_oid );
332 "%s: line %d: OID %s not recognized\n",
333 fname, lineno, at->at_oid);
336 if ( oid != at->at_oid ) {
337 ldap_memfree( at->at_oid );
342 /* at->at_oid == NULL will be an error someday */
344 ldap_memfree(at->at_syntax_oid);
345 at->at_syntax_oid = soid;
347 code = at_add(at,&err);
349 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
350 fname, lineno, scherr2str(code), err);