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