Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / openldap / dist / servers / slapd / schemaparse.c
blobd0fd60a4033ee664022e1d224848c2ebc989ae71
1 /* schemaparse.c - routines to parse config file objectclass definitions */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/schemaparse.c,v 1.80.2.4 2008/02/11 23:26:44 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 #include "portable.h"
19 #include <stdio.h>
21 #include <ac/ctype.h>
22 #include <ac/string.h>
23 #include <ac/socket.h>
25 #include "slap.h"
26 #include "ldap_schema.h"
27 #include "config.h"
29 static void oc_usage(void);
30 static void at_usage(void);
32 static char *const err2text[] = {
33 "Success",
34 "Out of memory",
35 "ObjectClass not found",
36 "user-defined ObjectClass includes operational attributes",
37 "user-defined ObjectClass has inappropriate SUPerior",
38 "Duplicate objectClass",
39 "Inconsistent duplicate objectClass",
40 "AttributeType not found",
41 "AttributeType inappropriate matching rule",
42 "AttributeType inappropriate USAGE",
43 "AttributeType inappropriate SUPerior",
44 "AttributeType SYNTAX or SUPerior required",
45 "Duplicate attributeType",
46 "Inconsistent duplicate attributeType",
47 "MatchingRule not found",
48 "MatchingRule incomplete",
49 "Duplicate matchingRule",
50 "Syntax not found",
51 "Duplicate ldapSyntax",
52 "Superior syntax not found",
53 "OID or name required",
54 "Qualifier not supported",
55 "Invalid NAME",
56 "OID could not be expanded",
57 "Duplicate Content Rule",
58 "Content Rule not for STRUCTURAL object class",
59 "Content Rule AUX contains inappropriate object class",
60 "Content Rule attribute type list contains duplicate",
61 NULL
64 char *
65 scherr2str(int code)
67 if ( code < 0 || SLAP_SCHERR_LAST <= code ) {
68 return "Unknown error";
69 } else {
70 return err2text[code];
74 /* check schema descr validity */
75 int slap_valid_descr( const char *descr )
77 int i=0;
79 if( !DESC_LEADCHAR( descr[i] ) ) {
80 return 0;
83 while( descr[++i] ) {
84 if( !DESC_CHAR( descr[i] ) ) {
85 return 0;
89 return 1;
93 /* OID Macros */
95 /* String compare with delimiter check. Return 0 if not
96 * matched, otherwise return length matched.
98 int
99 dscompare(const char *s1, const char *s2, char delim)
101 const char *orig = s1;
102 while (*s1++ == *s2++)
103 if (!s1[-1]) break;
104 --s1;
105 --s2;
106 if (!*s1 && (!*s2 || *s2 == delim))
107 return s1 - orig;
108 return 0;
111 static void
112 cr_usage( void )
114 fprintf( stderr,
115 "DITContentRuleDescription = \"(\" whsp\n"
116 " numericoid whsp ; StructuralObjectClass identifier\n"
117 " [ \"NAME\" qdescrs ]\n"
118 " [ \"DESC\" qdstring ]\n"
119 " [ \"OBSOLETE\" whsp ]\n"
120 " [ \"AUX\" oids ] ; Auxiliary ObjectClasses\n"
121 " [ \"MUST\" oids ] ; AttributeTypes\n"
122 " [ \"MAY\" oids ] ; AttributeTypes\n"
123 " [ \"NOT\" oids ] ; AttributeTypes\n"
124 " whsp \")\"\n" );
128 parse_cr(
129 struct config_args_s *c,
130 ContentRule **scr )
132 LDAPContentRule *cr;
133 int code;
134 const char *err;
135 char *line = strchr( c->line, '(' );
137 cr = ldap_str2contentrule( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
138 if ( !cr ) {
139 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
140 c->argv[0], ldap_scherr2str( code ), err );
141 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
142 "%s %s\n", c->log, c->cr_msg, 0 );
143 cr_usage();
144 return 1;
147 if ( cr->cr_oid == NULL ) {
148 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
149 c->argv[0] );
150 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
151 "%s %s\n", c->log, c->cr_msg, 0 );
152 cr_usage();
153 code = 1;
154 goto done;
157 code = cr_add( cr, 1, scr, &err );
158 if ( code ) {
159 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
160 c->argv[0], scherr2str(code), err);
161 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
162 "%s %s\n", c->log, c->cr_msg, 0 );
163 code = 1;
164 goto done;
167 done:;
168 if ( code ) {
169 ldap_contentrule_free( cr );
171 } else {
172 ldap_memfree( cr );
175 return code;
179 parse_oc(
180 struct config_args_s *c,
181 ObjectClass **soc,
182 ObjectClass *prev )
184 LDAPObjectClass *oc;
185 int code;
186 const char *err;
187 char *line = strchr( c->line, '(' );
189 oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
190 if ( !oc ) {
191 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
192 c->argv[0], ldap_scherr2str( code ), err );
193 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
194 "%s %s\n", c->log, c->cr_msg, 0 );
195 oc_usage();
196 return 1;
199 if ( oc->oc_oid == NULL ) {
200 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
201 c->argv[0] );
202 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
203 "%s %s\n", c->log, c->cr_msg, 0 );
204 oc_usage();
205 code = 1;
206 goto done;
209 code = oc_add( oc, 1, soc, prev, &err );
210 if ( code ) {
211 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
212 c->argv[0], scherr2str(code), err);
213 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
214 "%s %s\n", c->log, c->cr_msg, 0 );
215 code = 1;
216 goto done;
219 done:;
220 if ( code ) {
221 ldap_objectclass_free( oc );
223 } else {
224 ldap_memfree( oc );
227 return code;
230 static void
231 oc_usage( void )
233 fprintf( stderr,
234 "ObjectClassDescription = \"(\" whsp\n"
235 " numericoid whsp ; ObjectClass identifier\n"
236 " [ \"NAME\" qdescrs ]\n"
237 " [ \"DESC\" qdstring ]\n"
238 " [ \"OBSOLETE\" whsp ]\n"
239 " [ \"SUP\" oids ] ; Superior ObjectClasses\n"
240 " [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
241 " ; default structural\n"
242 " [ \"MUST\" oids ] ; AttributeTypes\n"
243 " [ \"MAY\" oids ] ; AttributeTypes\n"
244 " whsp \")\"\n" );
247 static void
248 at_usage( void )
250 fprintf( stderr, "%s%s%s",
251 "AttributeTypeDescription = \"(\" whsp\n"
252 " numericoid whsp ; AttributeType identifier\n"
253 " [ \"NAME\" qdescrs ] ; name used in AttributeType\n"
254 " [ \"DESC\" qdstring ] ; description\n"
255 " [ \"OBSOLETE\" whsp ]\n"
256 " [ \"SUP\" woid ] ; derived from this other\n"
257 " ; AttributeType\n",
258 " [ \"EQUALITY\" woid ] ; Matching Rule name\n"
259 " [ \"ORDERING\" woid ] ; Matching Rule name\n"
260 " [ \"SUBSTR\" woid ] ; Matching Rule name\n"
261 " [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
262 " [ \"SINGLE-VALUE\" whsp ] ; default multi-valued\n"
263 " [ \"COLLECTIVE\" whsp ] ; default not collective\n",
264 " [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
265 " [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
266 " ; userApplications\n"
267 " ; directoryOperation\n"
268 " ; distributedOperation\n"
269 " ; dSAOperation\n"
270 " whsp \")\"\n");
274 parse_at(
275 struct config_args_s *c,
276 AttributeType **sat,
277 AttributeType *prev )
279 LDAPAttributeType *at;
280 int code;
281 const char *err;
282 char *line = strchr( c->line, '(' );
284 at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
285 if ( !at ) {
286 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s before %s",
287 c->argv[0], ldap_scherr2str(code), err );
288 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
289 "%s %s\n", c->log, c->cr_msg, 0 );
290 at_usage();
291 return 1;
294 if ( at->at_oid == NULL ) {
295 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: OID is missing",
296 c->argv[0] );
297 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
298 "%s %s\n", c->log, c->cr_msg, 0 );
299 at_usage();
300 code = 1;
301 goto done;
304 /* operational attributes should be defined internally */
305 if ( at->at_usage ) {
306 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: \"%s\" is operational",
307 c->argv[0], at->at_oid );
308 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
309 "%s %s\n", c->log, c->cr_msg, 0 );
310 code = 1;
311 goto done;
314 code = at_add( at, 1, sat, prev, &err);
315 if ( code ) {
316 snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: %s: \"%s\"",
317 c->argv[0], scherr2str(code), err);
318 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
319 "%s %s\n", c->log, c->cr_msg, 0 );
320 code = 1;
321 goto done;
324 done:;
325 if ( code ) {
326 ldap_attributetype_free( at );
328 } else {
329 ldap_memfree( at );
332 return code;