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