]> git.sur5r.net Git - openldap/blob - servers/slapd/schemaparse.c
Experimental code that uses one locker ID per thread. Seems to work OK,
[openldap] / servers / slapd / schemaparse.c
1 /* schemaparse.c - routines to parse config file objectclass definitions */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 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 has inappropriate SUPerior",
29         "user-defined ObjectClass includes operational attributes",
30         "Duplicate objectClass",
31         "AttributeType not found",
32         "AttributeType inappropriate USAGE",
33         "AttributeType inappropriate SUPerior",
34         "AttributeType SYNTAX or SUPerior required",
35         "Duplicate attributeType",
36         "MatchingRule not found",
37         "Duplicate matchingRule",
38         "Syntax not found",
39         "Syntax required",
40         "Duplicate ldapSyntax",
41         "OID or name required",
42         "Qualifier not supported",
43         "Invalid NAME",
44         "OID could not be expanded"
45 };
46
47 char *
48 scherr2str(int code)
49 {
50         if ( code < 0 || SLAP_SCHERR_LAST <= code ) {
51                 return "Unknown error";
52         } else {
53                 return err2text[code];
54         }
55 }
56
57 /* check schema descr validity */
58 int slap_valid_descr( const char *descr )
59 {
60         int i=0;
61
62         if( !DESC_LEADCHAR( descr[i] ) ) {
63                 return 0;
64         }
65
66         while( descr[++i] ) {
67                 if( !DESC_CHAR( descr[i] ) ) {
68                         return 0;
69                 }
70         }
71
72         return 1;
73 }
74
75
76 /* OID Macros */
77
78 /* String compare with delimiter check. Return 0 if not
79  * matched, otherwise return length matched.
80  */
81 int
82 dscompare(const char *s1, const char *s2, char delim)
83 {
84         const char *orig = s1;
85         while (*s1++ == *s2++)
86                 if (!s1[-1]) break;
87         --s1;
88         --s2;
89         if (!*s1 && (!*s2 || *s2 == delim))
90                 return s1 - orig;
91         return 0;
92 }
93
94
95 int
96 parse_oc(
97     const char  *fname,
98     int         lineno,
99     char        *line,
100     char        **argv
101 )
102 {
103         LDAPObjectClass *oc;
104         int             code;
105         const char      *err;
106
107         oc = ldap_str2objectclass(line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
108         if ( !oc ) {
109                 fprintf( stderr, "%s: line %d: %s before %s\n",
110                          fname, lineno, ldap_scherr2str(code), err );
111                 oc_usage();
112                 return 1;
113         }
114
115         if ( oc->oc_oid == NULL ) {
116                 fprintf( stderr,
117                         "%s: line %d: objectclass has no OID\n",
118                         fname, lineno );
119                 oc_usage();
120                 return 1;
121         }
122
123         code = oc_add(oc,1,&err);
124         if ( code ) {
125                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
126                          fname, lineno, scherr2str(code), err);
127                 return 1;
128         }
129
130         ldap_memfree(oc);
131         return 0;
132 }
133
134 static void
135 oc_usage( void )
136 {
137         fprintf( stderr,
138                 "ObjectClassDescription = \"(\" whsp\n"
139                 "  numericoid whsp                 ; ObjectClass identifier\n"
140                 "  [ \"NAME\" qdescrs ]\n"
141                 "  [ \"DESC\" qdstring ]\n"
142                 "  [ \"OBSOLETE\" whsp ]\n"
143                 "  [ \"SUP\" oids ]                ; Superior ObjectClasses\n"
144                 "  [ ( \"ABSTRACT\" / \"STRUCTURAL\" / \"AUXILIARY\" ) whsp ]\n"
145                 "                                  ; default structural\n"
146                 "  [ \"MUST\" oids ]               ; AttributeTypes\n"
147                 "  [ \"MAY\" oids ]                ; AttributeTypes\n"
148                 "  whsp \")\"\n" );
149 }
150
151
152 static void
153 at_usage( void )
154 {
155         fprintf( stderr,
156                 "AttributeTypeDescription = \"(\" whsp\n"
157                 "  numericoid whsp      ; AttributeType identifier\n"
158                 "  [ \"NAME\" qdescrs ]             ; name used in AttributeType\n"
159                 "  [ \"DESC\" qdstring ]            ; description\n"
160                 "  [ \"OBSOLETE\" whsp ]\n"
161                 "  [ \"SUP\" woid ]                 ; derived from this other\n"
162                 "                                   ; AttributeType\n"
163                 "  [ \"EQUALITY\" woid ]            ; Matching Rule name\n"
164                 "  [ \"ORDERING\" woid ]            ; Matching Rule name\n"
165                 "  [ \"SUBSTR\" woid ]              ; Matching Rule name\n"
166                 "  [ \"SYNTAX\" whsp noidlen whsp ] ; see section 4.3\n"
167                 "  [ \"SINGLE-VALUE\" whsp ]        ; default multi-valued\n"
168                 "  [ \"COLLECTIVE\" whsp ]          ; default not collective\n"
169                 "  [ \"NO-USER-MODIFICATION\" whsp ]; default user modifiable\n"
170                 "  [ \"USAGE\" whsp AttributeUsage ]; default userApplications\n"
171                 "                                   ; userApplications\n"
172                 "                                   ; directoryOperation\n"
173                 "                                   ; distributedOperation\n"
174                 "                                   ; dSAOperation\n"
175                 "  whsp \")\"\n");
176 }
177
178 int
179 parse_at(
180     const char  *fname,
181     int         lineno,
182     char        *line,
183     char        **argv
184 )
185 {
186         LDAPAttributeType *at;
187         int             code;
188         const char      *err;
189
190         at = ldap_str2attributetype( line, &code, &err, LDAP_SCHEMA_ALLOW_ALL );
191         if ( !at ) {
192                 fprintf( stderr, "%s: line %d: %s before %s\n",
193                          fname, lineno, ldap_scherr2str(code), err );
194                 at_usage();
195                 return 1;
196         }
197
198         if ( at->at_oid == NULL ) {
199                 fprintf( stderr,
200                         "%s: line %d: attributeType has no OID\n",
201                         fname, lineno );
202                 at_usage();
203                 return 1;
204         }
205
206         /* operational attributes should be defined internally */
207         if ( at->at_usage ) {
208                 fprintf( stderr, "%s: line %d: attribute type \"%s\" is operational\n",
209                          fname, lineno, at->at_oid );
210                 return 1;
211         }
212
213         code = at_add(at,&err);
214         if ( code ) {
215                 fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
216                          fname, lineno, scherr2str(code), err);
217                 return 1;
218         }
219         ldap_memfree(at);
220         return 0;
221 }