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