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