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