]> git.sur5r.net Git - openldap/blob - servers/slapd/schemaparse.c
49d95281f86ff551ff89c55e143a6ab7abc491f2
[openldap] / servers / slapd / schemaparse.c
1 /* schemaparse.c - routines to parse config file objectclass definitions */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/string.h>
8 #include <ac/socket.h>
9
10 #include "slap.h"
11 #include "ldap_schema.h"
12
13 static Avlnode          *object_classes = NULL;
14
15 int     global_schemacheck = 1; /* schemacheck on is default */
16
17 static void             oc_usage_old(void);
18 static void             oc_usage(void);
19
20 static char *err2text[] = {
21         "",
22         "Out of memory",
23         "Objectclass not found",
24         "Attribute type not found",
25         "Duplicate objectclass",
26         "Duplicate attributetype",
27         "Duplicate syntax",
28         "Duplicate matchingrule",
29         "OID or name required",
30         "Syntax or superior required",
31         "Matchingrule not found",
32         "Syntax not found"
33 };
34
35 char *
36 scherr2str(int code)
37 {
38         if ( code < 1 || code >= (sizeof(err2text)/sizeof(char *)) ) {
39                 return "Unknown error";
40         } else {
41                 return err2text[code];
42         }
43 }
44
45 void
46 parse_oc_old(
47     Backend     *be,
48     char        *fname,
49     int         lineno,
50     int         argc,
51     char        **argv
52 )
53 {
54         int             i;
55         char            last;
56         LDAP_OBJECT_CLASS       *oc;
57         int             code;
58         const char      *err;
59         char            **namep;
60
61         oc = (LDAP_OBJECT_CLASS *) ch_calloc( 1, sizeof(LDAP_OBJECT_CLASS) );
62         oc->oc_names = ch_calloc( 2, sizeof(char *) );
63         oc->oc_names[0] = ch_strdup( argv[1] );
64         oc->oc_names[1] = NULL;
65         if ( strcasecmp( oc->oc_names[0], "top" ) ) {
66                 oc->oc_kind = LDAP_SCHEMA_STRUCTURAL;
67         }
68         for ( i = 2; i < argc; i++ ) {
69                 /* required attributes */
70                 if ( strcasecmp( argv[i], "requires" ) == 0 ) {
71                         do {
72                                 i++;
73                                 if ( i < argc ) {
74                                         char **s = str2charray( argv[i], "," );
75                                         last = argv[i][strlen( argv[i] ) - 1];
76                                         charray_merge( &oc->oc_at_oids_must, s );
77                                         charray_free( s );
78                                 }
79                         } while ( i < argc && last == ',' );
80
81                 /* optional attributes */
82                 } else if ( strcasecmp( argv[i], "allows" ) == 0 ) {
83                         do {
84                                 i++;
85                                 if ( i < argc ) {
86                                         char **s = str2charray( argv[i], "," );
87                                         last = argv[i][strlen( argv[i] ) - 1];
88                                         
89                                         charray_merge( &oc->oc_at_oids_may, s );
90                                         charray_free( s );
91                                 }
92                         } while ( i < argc && last == ',' );
93
94                 } else {
95                         fprintf( stderr,
96             "%s: line %d: expecting \"requires\" or \"allows\" got \"%s\"\n",
97                             fname, lineno, argv[i] );
98                         oc_usage_old();
99                 }
100         }
101
102         /*
103          * There was no requirement in the old schema that all attributes
104          * types were defined before use and they would just default to
105          * SYNTAX_CIS.  To support this, we need to make attribute types
106          * out of thin air.
107          */
108         if ( oc->oc_at_oids_must ) {
109                 namep = oc->oc_at_oids_must;
110                 while ( *namep ) {
111                         code = at_fake_if_needed( *namep );
112                         if ( code ) {
113                                 fprintf( stderr, "%s: line %d: %s %s\n",
114                                          fname, lineno, scherr2str(code), *namep);
115                                 exit( 1 );
116                         }
117                         namep++;
118                 }
119         }
120         if ( oc->oc_at_oids_may ) {
121                 namep = oc->oc_at_oids_may;
122                 while ( *namep ) {
123                         code = at_fake_if_needed( *namep );
124                         if ( code ) {
125                                 fprintf( stderr, "%s: line %d: %s %s\n",
126                                          fname, lineno, scherr2str(code), *namep);
127                                 exit( 1 );
128                         }
129                         namep++;
130                 }
131         }
132         
133         code = oc_add(oc,&err);
134         if ( code ) {
135                 fprintf( stderr, "%s: line %d: %s %s\n",
136                          fname, lineno, scherr2str(code), err);
137                 exit( 1 );
138         }
139         ldap_memfree(oc);
140 }
141
142 void
143 parse_oc(
144     char        *fname,
145     int         lineno,
146     char        *line
147 )
148 {
149         LDAP_OBJECT_CLASS *oc;
150         int             code;
151         const char      *err;
152
153         oc = ldap_str2objectclass(line,&code,&err);
154         if ( !oc ) {
155                 fprintf( stderr, "%s: line %d: %s before %s\n",
156                          fname, lineno, ldap_scherr2str(code), err );
157                 oc_usage();
158         }
159         code = oc_add(oc,&err);
160         if ( code ) {
161                 fprintf( stderr, "%s: line %d: %s %s\n",
162                          fname, lineno, scherr2str(code), err);
163                 exit( 1 );
164         }
165         ldap_memfree(oc);
166 }
167
168 static void
169 oc_usage( void )
170 {
171         fprintf( stderr, "ObjectClassDescription = \"(\" whsp\n");
172         fprintf( stderr, "  numericoid whsp      ; ObjectClass identifier\n");
173         fprintf( stderr, "  [ \"NAME\" qdescrs ]\n");
174         fprintf( stderr, "  [ \"DESC\" qdstring ]\n");
175         fprintf( stderr, "  [ \"OBSOLETE\" whsp ]\n");
176         fprintf( stderr, "  [ \"SUP\" oids ]       ; Superior ObjectClasses\n");
177         fprintf( stderr, "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n");
178         fprintf( stderr, "                       ; default structural\n");
179         fprintf( stderr, "  [ \"MUST\" oids ]      ; AttributeTypes\n");
180         fprintf( stderr, "  [ \"MAY\" oids ]       ; AttributeTypes\n");
181         fprintf( stderr, "whsp \")\"\n");
182         exit( 1 );
183 }
184
185 static void
186 oc_usage_old( void )
187 {
188         fprintf( stderr, "<oc clause> ::= objectclass <ocname>\n" );
189         fprintf( stderr, "                [ requires <attrlist> ]\n" );
190         fprintf( stderr, "                [ allows <attrlist> ]\n" );
191         exit( 1 );
192 }
193
194 static void
195 at_usage( void )
196 {
197         fprintf( stderr, "AttributeTypeDescription = \"(\" whsp\n");
198         fprintf( stderr, "  numericoid whsp      ; AttributeType identifier\n");
199         fprintf( stderr, "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n");
200         fprintf( stderr, "  [ \"DESC\" qdstring ]            ; description\n");
201         fprintf( stderr, "  [ \"OBSOLETE\" whsp ]\n");
202         fprintf( stderr, "  [ \"SUP\" woid ]                 ; derived from this other\n");
203         fprintf( stderr, "                                 ; AttributeType\n");
204         fprintf( stderr, "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n");
205         fprintf( stderr, "  [ \"ORDERING\" woid ]            ; Matching Rule name\n");
206         fprintf( stderr, "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n");
207         fprintf( stderr, "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n");
208         fprintf( stderr, "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n");
209         fprintf( stderr, "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n");
210         fprintf( stderr, "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n");
211         fprintf( stderr, "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n");
212         fprintf( stderr, "                                 ; userApplications\n");
213         fprintf( stderr, "                                 ; directoryOperation\n");
214         fprintf( stderr, "                                 ; distributedOperation\n");
215         fprintf( stderr, "                                 ; dSAOperation\n");
216         fprintf( stderr, "whsp \")\"\n");
217         exit( 1 );
218 }
219
220 void
221 parse_at(
222     char        *fname,
223     int         lineno,
224     char        *line
225 )
226 {
227         LDAP_ATTRIBUTE_TYPE *at;
228         int             code;
229         const char      *err;
230
231         at = ldap_str2attributetype(line,&code,&err);
232         if ( !at ) {
233                 fprintf( stderr, "%s: line %d: %s before %s\n",
234                          fname, lineno, ldap_scherr2str(code), err );
235                 at_usage();
236         }
237         code = at_add(at,&err);
238         if ( code ) {
239                 fprintf( stderr, "%s: line %d: %s %s\n",
240                          fname, lineno, scherr2str(code), err);
241                 exit( 1 );
242         }
243         ldap_memfree(at);
244 }