]> git.sur5r.net Git - openldap/blob - servers/slapd/schemaparse.c
coverity scan, fix typo
[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-2007 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 #include "config.h"
28
29 static void             oc_usage(void); 
30 static void             at_usage(void);
31
32 static char *const err2text[] = {
33         "Success",
34         "Out of memory",
35         "ObjectClass not found",
36         "user-defined ObjectClass includes operational attributes",
37         "user-defined ObjectClass has inappropriate SUPerior",
38         "Duplicate objectClass",
39         "Inconsistent 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         "Inconsistent duplicate attributeType",
47         "MatchingRule not found",
48         "MatchingRule incomplete",
49         "Duplicate matchingRule",
50         "Syntax not found",
51         "Duplicate ldapSyntax",
52         "OID or name required",
53         "Qualifier not supported",
54         "Invalid NAME",
55         "OID could not be expanded",
56         "Duplicate Content Rule",
57         "Content Rule not for STRUCTURAL object class",
58         "Content Rule AUX contains inappropriate object class",
59         "Content Rule attribute type list contains duplicate",
60         NULL
61 };
62
63 char *
64 scherr2str(int code)
65 {
66         if ( code < 0 || SLAP_SCHERR_LAST <= code ) {
67                 return "Unknown error";
68         } else {
69                 return err2text[code];
70         }
71 }
72
73 /* check schema descr validity */
74 int slap_valid_descr( const char *descr )
75 {
76         int i=0;
77
78         if( !DESC_LEADCHAR( descr[i] ) ) {
79                 return 0;
80         }
81
82         while( descr[++i] ) {
83                 if( !DESC_CHAR( descr[i] ) ) {
84                         return 0;
85                 }
86         }
87
88         return 1;
89 }
90
91
92 /* OID Macros */
93
94 /* String compare with delimiter check. Return 0 if not
95  * matched, otherwise return length matched.
96  */
97 int
98 dscompare(const char *s1, const char *s2, char delim)
99 {
100         const char *orig = s1;
101         while (*s1++ == *s2++)
102                 if (!s1[-1]) break;
103         --s1;
104         --s2;
105         if (!*s1 && (!*s2 || *s2 == delim))
106                 return s1 - orig;
107         return 0;
108 }
109
110 static void
111 cr_usage( void )
112 {
113         fprintf( stderr,
114                 "DITContentRuleDescription = \"(\" whsp\n"
115                 "  numericoid whsp       ; StructuralObjectClass identifier\n"
116                 "  [ \"NAME\" qdescrs ]\n"
117                 "  [ \"DESC\" qdstring ]\n"
118                 "  [ \"OBSOLETE\" whsp ]\n"
119                 "  [ \"AUX\" oids ]      ; Auxiliary ObjectClasses\n"
120                 "  [ \"MUST\" oids ]     ; AttributeTypes\n"
121                 "  [ \"MAY\" oids ]      ; AttributeTypes\n"
122                 "  [ \"NOT\" oids ]      ; AttributeTypes\n"
123                 "  whsp \")\"\n" );
124 }
125
126 int
127 parse_cr(
128         struct config_args_s *c,
129         ContentRule     **scr )
130 {
131         LDAPContentRule *cr;
132         int             code;
133         const char      *err;
134         char *line = strchr( c->line, '(' );
135
136         cr = ldap_str2contentrule( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
137         if ( !cr ) {
138                 snprintf( c->msg, sizeof( c->msg ), "%s: %s before %s",
139                         c->argv[0], ldap_scherr2str( code ), err );
140                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
141                         "%s %s\n", c->log, c->msg, 0 );
142                 cr_usage();
143                 return 1;
144         }
145
146         if ( cr->cr_oid == NULL ) {
147                 snprintf( c->msg, sizeof( c->msg ), "%s: OID is missing",
148                         c->argv[0] );
149                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
150                         "%s %s\n", c->log, c->msg, 0 );
151                 cr_usage();
152                 code = 1;
153                 goto done;
154         }
155
156         code = cr_add( cr, 1, scr, &err );
157         if ( code ) {
158                 snprintf( c->msg, sizeof( c->msg ), "%s: %s: \"%s\"",
159                         c->argv[0], scherr2str(code), err);
160                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
161                         "%s %s\n", c->log, c->msg, 0 );
162                 code = 1;
163                 goto done;
164         }
165
166 done:;
167         if ( code ) {
168                 ldap_contentrule_free( cr );
169
170         } else {
171                 ldap_memfree( cr );
172         }
173
174         return code;
175 }
176
177 int
178 parse_oc(
179         struct config_args_s *c,
180         ObjectClass     **soc,
181         ObjectClass *prev )
182 {
183         LDAPObjectClass *oc;
184         int             code;
185         const char      *err;
186         char *line = strchr( c->line, '(' );
187
188         oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
189         if ( !oc ) {
190                 snprintf( c->msg, sizeof( c->msg ), "%s: %s before %s",
191                         c->argv[0], ldap_scherr2str( code ), err );
192                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
193                         "%s %s\n", c->log, c->msg, 0 );
194                 oc_usage();
195                 return 1;
196         }
197
198         if ( oc->oc_oid == NULL ) {
199                 snprintf( c->msg, sizeof( c->msg ), "%s: OID is missing",
200                         c->argv[0] );
201                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
202                         "%s %s\n", c->log, c->msg, 0 );
203                 oc_usage();
204                 code = 1;
205                 goto done;
206         }
207
208         code = oc_add( oc, 1, soc, prev, &err );
209         if ( code ) {
210                 snprintf( c->msg, sizeof( c->msg ), "%s: %s: \"%s\"",
211                         c->argv[0], scherr2str(code), err);
212                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
213                         "%s %s\n", c->log, c->msg, 0 );
214                 code = 1;
215                 goto done;
216         }
217
218 done:;
219         if ( code ) {
220                 ldap_objectclass_free( oc );
221
222         } else {
223                 ldap_memfree( oc );
224         }
225
226         return code;
227 }
228
229 static void
230 oc_usage( void )
231 {
232         fprintf( stderr,
233                 "ObjectClassDescription = \"(\" whsp\n"
234                 "  numericoid whsp                 ; ObjectClass identifier\n"
235                 "  [ \"NAME\" qdescrs ]\n"
236                 "  [ \"DESC\" qdstring ]\n"
237                 "  [ \"OBSOLETE\" whsp ]\n"
238                 "  [ \"SUP\" oids ]                ; Superior ObjectClasses\n"
239                 "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
240                 "                                  ; default structural\n"
241                 "  [ \"MUST\" oids ]               ; AttributeTypes\n"
242                 "  [ \"MAY\" oids ]                ; AttributeTypes\n"
243                 "  whsp \")\"\n" );
244 }
245
246 static void
247 at_usage( void )
248 {
249         fprintf( stderr, "%s%s%s",
250                 "AttributeTypeDescription = \"(\" whsp\n"
251                 "  numericoid whsp      ; AttributeType identifier\n"
252                 "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n"
253                 "  [ \"DESC\" qdstring ]            ; description\n"
254                 "  [ \"OBSOLETE\" whsp ]\n"
255                 "  [ \"SUP\" woid ]                 ; derived from this other\n"
256                 "                                   ; AttributeType\n",
257                 "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n"
258                 "  [ \"ORDERING\" woid ]            ; Matching Rule name\n"
259                 "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n"
260                 "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
261                 "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n"
262                 "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n",
263                 "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
264                 "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
265                 "                                   ; userApplications\n"
266                 "                                   ; directoryOperation\n"
267                 "                                   ; distributedOperation\n"
268                 "                                   ; dSAOperation\n"
269                 "  whsp \")\"\n");
270 }
271
272 int
273 parse_at(
274         struct config_args_s *c,
275         AttributeType   **sat,
276         AttributeType   *prev )
277 {
278         LDAPAttributeType *at;
279         int             code;
280         const char      *err;
281         char *line = strchr( c->line, '(' );
282
283         at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
284         if ( !at ) {
285                 snprintf( c->msg, sizeof( c->msg ), "%s: %s before %s",
286                         c->argv[0], ldap_scherr2str(code), err );
287                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
288                         "%s %s\n", c->log, c->msg, 0 );
289                 at_usage();
290                 return 1;
291         }
292
293         if ( at->at_oid == NULL ) {
294                 snprintf( c->msg, sizeof( c->msg ), "%s: OID is missing",
295                         c->argv[0] );
296                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
297                         "%s %s\n", c->log, c->msg, 0 );
298                 at_usage();
299                 code = 1;
300                 goto done;
301         }
302
303         /* operational attributes should be defined internally */
304         if ( at->at_usage ) {
305                 snprintf( c->msg, sizeof( c->msg ), "%s: \"%s\" is operational",
306                         c->argv[0], at->at_oid );
307                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
308                         "%s %s\n", c->log, c->msg, 0 );
309                 code = 1;
310                 goto done;
311         }
312
313         code = at_add( at, 1, sat, prev, &err);
314         if ( code ) {
315                 snprintf( c->msg, sizeof( c->msg ), "%s: %s: \"%s\"",
316                         c->argv[0], scherr2str(code), err);
317                 Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
318                         "%s %s\n", c->log, c->msg, 0 );
319                 code = 1;
320                 goto done;
321         }
322
323 done:;
324         if ( code ) {
325                 ldap_attributetype_free( at );
326
327         } else {
328                 ldap_memfree( at );
329         }
330
331         return code;
332 }