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