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