]> git.sur5r.net Git - openldap/blob - servers/slapd/schemaparse.c
ITS#5489
[openldap] / servers / slapd / schemaparse.c
1 /* schemaparse.c - routines to parse config file objectclass definitions */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2008 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
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.
11  *
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>.
15  */
16
17 #include "portable.h"
18
19 #include <stdio.h>
20
21 #include <ac/ctype.h>
22 #include <ac/string.h>
23 #include <ac/socket.h>
24
25 #include "slap.h"
26 #include "ldap_schema.h"
27
28 static void             oc_usage(void); 
29 static void             at_usage(void);
30
31 static char *const err2text[] = {
32         "Success",
33         "Out of memory",
34         "ObjectClass not found",
35         "user-defined ObjectClass includes operational attributes",
36         "user-defined ObjectClass has inappropriate SUPerior",
37         "Duplicate objectClass",
38         "Inconsistent duplicate objectClass",
39         "AttributeType not found",
40         "AttributeType inappropriate matching rule",
41         "AttributeType inappropriate USAGE",
42         "AttributeType inappropriate SUPerior",
43         "AttributeType SYNTAX or SUPerior required",
44         "Duplicate attributeType",
45         "Inconsistent duplicate attributeType",
46         "MatchingRule not found",
47         "MatchingRule incomplete",
48         "Duplicate matchingRule",
49         "Syntax not found",
50         "Duplicate ldapSyntax",
51         "OID or name required",
52         "Qualifier not supported",
53         "Invalid NAME",
54         "OID could not be expanded",
55         "Duplicate Content Rule",
56         "Content Rule not for STRUCTURAL object class",
57         "Content Rule AUX contains inappropriate object class",
58         "Content Rule attribute type list contains duplicate",
59         NULL
60 };
61
62 char *
63 scherr2str(int code)
64 {
65         if ( code < 0 || SLAP_SCHERR_LAST <= code ) {
66                 return "Unknown error";
67         } else {
68                 return err2text[code];
69         }
70 }
71
72 /* check schema descr validity */
73 int slap_valid_descr( const char *descr )
74 {
75         int i=0;
76
77         if( !DESC_LEADCHAR( descr[i] ) ) {
78                 return 0;
79         }
80
81         while( descr[++i] ) {
82                 if( !DESC_CHAR( descr[i] ) ) {
83                         return 0;
84                 }
85         }
86
87         return 1;
88 }
89
90
91 /* OID Macros */
92
93 /* String compare with delimiter check. Return 0 if not
94  * matched, otherwise return length matched.
95  */
96 int
97 dscompare(const char *s1, const char *s2, char delim)
98 {
99         const char *orig = s1;
100         while (*s1++ == *s2++)
101                 if (!s1[-1]) break;
102         --s1;
103         --s2;
104         if (!*s1 && (!*s2 || *s2 == delim))
105                 return s1 - orig;
106         return 0;
107 }
108
109 static void
110 cr_usage( void )
111 {
112         fprintf( stderr,
113                 "DITContentRuleDescription = \"(\" whsp\n"
114                 "  numericoid whsp       ; StructuralObjectClass identifier\n"
115                 "  [ \"NAME\" qdescrs ]\n"
116                 "  [ \"DESC\" qdstring ]\n"
117                 "  [ \"OBSOLETE\" whsp ]\n"
118                 "  [ \"AUX\" oids ]      ; Auxiliary ObjectClasses\n"
119                 "  [ \"MUST\" oids ]     ; AttributeTypes\n"
120                 "  [ \"MAY\" oids ]      ; AttributeTypes\n"
121                 "  [ \"NOT\" oids ]      ; AttributeTypes\n"
122                 "  whsp \")\"\n" );
123 }
124
125 int
126 parse_cr(
127         const char      *fname,
128         int             lineno,
129         char            *line,
130         char            **argv,
131         ContentRule     **scr )
132 {
133         LDAPContentRule *cr;
134         int             code;
135         const char      *err;
136
137         cr = ldap_str2contentrule( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
138         if ( !cr ) {
139                 fprintf( stderr, "%s: line %d: %s before %s\n",
140                          fname, lineno, ldap_scherr2str(code), err );
141                 cr_usage();
142                 return 1;
143         }
144
145         if ( cr->cr_oid == NULL ) {
146                 fprintf( stderr,
147                         "%s: line %d: Content rule has no OID\n",
148                         fname, lineno );
149                 cr_usage();
150                 code = 1;
151                 goto done;
152         }
153
154         code = cr_add( cr, 1, scr, &err );
155         if ( code ) {
156                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
157                          fname, lineno, scherr2str( code ), err );
158                 code = 1;
159                 goto done;
160         }
161
162 done:;
163         if ( code ) {
164                 ldap_contentrule_free( cr );
165
166         } else {
167                 ldap_memfree( cr );
168         }
169
170         return code;
171 }
172
173 int
174 parse_oc(
175         const char      *fname,
176         int             lineno,
177         char            *line,
178         char            **argv,
179         ObjectClass     **soc )
180 {
181         LDAPObjectClass *oc;
182         int             code;
183         const char      *err;
184
185         oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
186         if ( !oc ) {
187                 fprintf( stderr, "%s: line %d: %s before %s\n",
188                          fname, lineno, ldap_scherr2str( code ), err );
189                 oc_usage();
190                 return 1;
191         }
192
193         if ( oc->oc_oid == NULL ) {
194                 fprintf( stderr,
195                         "%s: line %d: objectclass has no OID\n",
196                         fname, lineno );
197                 oc_usage();
198                 code = 1;
199                 goto done;
200         }
201
202         code = oc_add( oc, 1, soc, &err );
203         if ( code ) {
204                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
205                          fname, lineno, scherr2str( code ), err );
206                 code = 1;
207                 goto done;
208         }
209
210 done:;
211         if ( code ) {
212                 ldap_objectclass_free( oc );
213
214         } else {
215                 ldap_memfree( oc );
216         }
217
218         return code;
219 }
220
221 static void
222 oc_usage( void )
223 {
224         fprintf( stderr,
225                 "ObjectClassDescription = \"(\" whsp\n"
226                 "  numericoid whsp                 ; ObjectClass identifier\n"
227                 "  [ \"NAME\" qdescrs ]\n"
228                 "  [ \"DESC\" qdstring ]\n"
229                 "  [ \"OBSOLETE\" whsp ]\n"
230                 "  [ \"SUP\" oids ]                ; Superior ObjectClasses\n"
231                 "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
232                 "                                  ; default structural\n"
233                 "  [ \"MUST\" oids ]               ; AttributeTypes\n"
234                 "  [ \"MAY\" oids ]                ; AttributeTypes\n"
235                 "  whsp \")\"\n" );
236 }
237
238 static void
239 at_usage( void )
240 {
241         fprintf( stderr, "%s%s%s",
242                 "AttributeTypeDescription = \"(\" whsp\n"
243                 "  numericoid whsp      ; AttributeType identifier\n"
244                 "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n"
245                 "  [ \"DESC\" qdstring ]            ; description\n"
246                 "  [ \"OBSOLETE\" whsp ]\n"
247                 "  [ \"SUP\" woid ]                 ; derived from this other\n"
248                 "                                   ; AttributeType\n",
249                 "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n"
250                 "  [ \"ORDERING\" woid ]            ; Matching Rule name\n"
251                 "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n"
252                 "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
253                 "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n"
254                 "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n",
255                 "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
256                 "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
257                 "                                   ; userApplications\n"
258                 "                                   ; directoryOperation\n"
259                 "                                   ; distributedOperation\n"
260                 "                                   ; dSAOperation\n"
261                 "  whsp \")\"\n");
262 }
263
264 int
265 parse_at(
266         const char      *fname,
267         int             lineno,
268         char            *line,
269         char            **argv,
270         AttributeType   **sat )
271 {
272         LDAPAttributeType *at;
273         int             code;
274         const char      *err;
275
276         at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
277         if ( !at ) {
278                 fprintf( stderr, "%s: line %d: %s before %s\n",
279                          fname, lineno, ldap_scherr2str(code), err );
280                 at_usage();
281                 return 1;
282         }
283
284         if ( at->at_oid == NULL ) {
285                 fprintf( stderr,
286                         "%s: line %d: attributeType has no OID\n",
287                         fname, lineno );
288                 at_usage();
289                 code = 1;
290                 goto done;
291         }
292
293         /* operational attributes should be defined internally */
294         if ( at->at_usage ) {
295                 fprintf( stderr, "%s: line %d: attribute type \"%s\" is operational\n",
296                          fname, lineno, at->at_oid );
297                 code = 1;
298                 goto done;
299         }
300
301         code = at_add( at, 1, sat, &err);
302         if ( code ) {
303                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
304                          fname, lineno, scherr2str(code), err);
305                 code = 1;
306                 goto done;
307         }
308
309 done:;
310         if ( code ) {
311                 ldap_attributetype_free( at );
312
313         } else {
314                 ldap_memfree( at );
315         }
316
317         return code;
318 }