]> git.sur5r.net Git - openldap/blob - servers/slapd/schemaparse.c
6a621937f3eca4d02e3c977e255b190e0195bed4
[openldap] / servers / slapd / schemaparse.c
1 /* schemaparse.c - routines to parse config file objectclass definitions */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/ctype.h>
13 #include <ac/string.h>
14 #include <ac/socket.h>
15
16 #include "slap.h"
17 #include "ldap_schema.h"
18
19 int     global_schemacheck = 1; /* schemacheck ON is default */
20 int     global_add_rdn_values = 0; /* bail out if rdn values do not match entry values is default */
21
22 static void             oc_usage(void); 
23 static void             at_usage(void);
24
25 static char *const err2text[] = {
26         "Success",
27         "Out of memory",
28         "ObjectClass not found",
29         "user-defined ObjectClass includes operational attributes",
30         "user-defined ObjectClass has inappropriate SUPerior",
31         "Duplicate objectClass",
32         "AttributeType not found",
33         "AttributeType inappropriate matching rule",
34         "AttributeType inappropriate USAGE",
35         "AttributeType inappropriate SUPerior",
36         "AttributeType SYNTAX or SUPerior required",
37         "Duplicate attributeType",
38         "MatchingRule not found",
39         "MatchingRule incomplete",
40         "Duplicate matchingRule",
41         "Syntax not found",
42         "Duplicate ldapSyntax",
43         "OID or name required",
44         "Qualifier not supported",
45         "Invalid NAME",
46         "OID could not be expanded",
47         "Duplicate Content Rule",
48         "Content Rule not for STRUCTURAL object class",
49         "Content Rule AUX contains non-AUXILIARY object class"
50         "Content Rule attribute type list contains duplicate"
51 };
52
53 char *
54 scherr2str(int code)
55 {
56         if ( code < 0 || SLAP_SCHERR_LAST <= code ) {
57                 return "Unknown error";
58         } else {
59                 return err2text[code];
60         }
61 }
62
63 /* check schema descr validity */
64 int slap_valid_descr( const char *descr )
65 {
66         int i=0;
67
68         if( !DESC_LEADCHAR( descr[i] ) ) {
69                 return 0;
70         }
71
72         while( descr[++i] ) {
73                 if( !DESC_CHAR( descr[i] ) ) {
74                         return 0;
75                 }
76         }
77
78         return 1;
79 }
80
81
82 /* OID Macros */
83
84 /* String compare with delimiter check. Return 0 if not
85  * matched, otherwise return length matched.
86  */
87 int
88 dscompare(const char *s1, const char *s2, char delim)
89 {
90         const char *orig = s1;
91         while (*s1++ == *s2++)
92                 if (!s1[-1]) break;
93         --s1;
94         --s2;
95         if (!*s1 && (!*s2 || *s2 == delim))
96                 return s1 - orig;
97         return 0;
98 }
99
100 #ifdef SLAP_EXTENDED_SCHEMA
101
102 static void
103 cr_usage( void )
104 {
105         fprintf( stderr,
106                 "DITContentRuleDescription = \"(\" whsp\n"
107                 "  numericoid whsp       ; StructuralObjectClass identifier\n"
108                 "  [ \"NAME\" qdescrs ]\n"
109                 "  [ \"DESC\" qdstring ]\n"
110                 "  [ \"OBSOLETE\" whsp ]\n"
111                 "  [ \"AUX\" oids ]      ; Auxiliary ObjectClasses\n"
112                 "  [ \"MUST\" oids ]     ; AttributeTypes\n"
113                 "  [ \"MAY\" oids ]      ; AttributeTypes\n"
114                 "  [ \"NOT\" oids ]      ; AttributeTypes\n"
115                 "  whsp \")\"\n" );
116 }
117
118 int
119 parse_cr(
120     const char  *fname,
121     int         lineno,
122     char        *line,
123     char        **argv
124 )
125 {
126         LDAPContentRule *cr;
127         int             code;
128         const char      *err;
129
130         cr = ldap_str2contentrule(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
131         if ( !cr ) {
132                 fprintf( stderr, "%s: line %d: %s before %s\n",
133                          fname, lineno, ldap_scherr2str(code), err );
134                 cr_usage();
135                 return 1;
136         }
137
138         if ( cr->cr_oid == NULL ) {
139                 fprintf( stderr,
140                         "%s: line %d: Content rule has no OID\n",
141                         fname, lineno );
142                 cr_usage();
143                 return 1;
144         }
145
146         code = cr_add(cr,1,&err);
147         if ( code ) {
148                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
149                          fname, lineno, scherr2str(code), err);
150                 return 1;
151         }
152
153         ldap_memfree(cr);
154         return 0;
155 }
156
157 #endif
158
159 int
160 parse_oc(
161     const char  *fname,
162     int         lineno,
163     char        *line,
164     char        **argv
165 )
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,
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 {
249         LDAPAttributeType *at;
250         int             code;
251         const char      *err;
252
253         at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
254         if ( !at ) {
255                 fprintf( stderr, "%s: line %d: %s before %s\n",
256                          fname, lineno, ldap_scherr2str(code), err );
257                 at_usage();
258                 return 1;
259         }
260
261         if ( at->at_oid == NULL ) {
262                 fprintf( stderr,
263                         "%s: line %d: attributeType has no OID\n",
264                         fname, lineno );
265                 at_usage();
266                 return 1;
267         }
268
269         /* operational attributes should be defined internally */
270         if ( at->at_usage ) {
271                 fprintf( stderr, "%s: line %d: attribute type \"%s\" is operational\n",
272                          fname, lineno, at->at_oid );
273                 return 1;
274         }
275
276         code = at_add(at,&err);
277         if ( code ) {
278                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
279                          fname, lineno, scherr2str(code), err);
280                 return 1;
281         }
282         ldap_memfree(at);
283         return 0;
284 }