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