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