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