]> git.sur5r.net Git - openldap/blob - servers/slapd/schema.c
#unifdef -DSLAP_NVALUES_ON_DISK
[openldap] / servers / slapd / schema.c
1 /* schema.c - routines to manage schema definitions */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 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_pvt.h"
18 #include "lutil.h"
19
20
21 int
22 schema_info( Entry **entry, const char **text )
23 {
24         AttributeDescription *ad_structuralObjectClass
25                 = slap_schema.si_ad_structuralObjectClass;
26         AttributeDescription *ad_objectClass
27                 = slap_schema.si_ad_objectClass;
28         AttributeDescription *ad_createTimestamp
29                 = slap_schema.si_ad_createTimestamp;
30         AttributeDescription *ad_modifyTimestamp
31                 = slap_schema.si_ad_modifyTimestamp;
32
33         Entry           *e;
34         struct berval   vals[5];
35 #ifdef SLAP_NVALUES
36         struct berval   nvals[5];
37 #endif
38
39         e = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
40         if( e == NULL ) {
41                 /* Out of memory, do something about it */
42 #ifdef NEW_LOGGING
43                 LDAP_LOG( OPERATION, ERR, 
44                         "schema_info: SLAP_CALLOC failed - out of memory.\n", 0, 0,0 );
45 #else
46                 Debug( LDAP_DEBUG_ANY, 
47                         "schema_info: SLAP_CALLOC failed - out of memory.\n", 0, 0, 0 );
48 #endif
49                 *text = "out of memory";
50                 return LDAP_OTHER;
51         }
52
53         e->e_attrs = NULL;
54         /* backend-specific schema info should be created by the
55          * backend itself
56          */
57         ber_dupbv( &e->e_name, &global_schemadn );
58         ber_dupbv( &e->e_nname, &global_schemandn );
59         e->e_private = NULL;
60
61         vals[0].bv_val = "subentry";
62         vals[0].bv_len = sizeof("subentry")-1;
63 #ifdef SLAP_NVALUES
64         if( attr_merge_one( e, ad_structuralObjectClass, vals, vals ) )
65 #else
66         if( attr_merge_one( e, ad_structuralObjectClass, vals ) )
67 #endif
68         {
69                 /* Out of memory, do something about it */
70                 entry_free( e );
71                 *text = "out of memory";
72                 return LDAP_OTHER;
73         }
74
75         vals[0].bv_val = "top";
76         vals[0].bv_len = sizeof("top")-1;
77         vals[1].bv_val = "subentry";
78         vals[1].bv_len = sizeof("subentry")-1;
79         vals[2].bv_val = "subschema";
80         vals[2].bv_len = sizeof("subschema")-1;
81         vals[3].bv_val = "extensibleObject";
82         vals[3].bv_len = sizeof("extensibleObject")-1;
83         vals[4].bv_val = NULL;
84 #ifdef SLAP_NVALUES
85         if( attr_merge( e, ad_objectClass, vals, vals ) )
86 #else
87         if( attr_merge( e, ad_objectClass, vals ) )
88 #endif
89         {
90                 /* Out of memory, do something about it */
91                 entry_free( e );
92                 *text = "out of memory";
93                 return LDAP_OTHER;
94         }
95
96         {
97                 int rc;
98                 AttributeDescription *desc = NULL;
99                 struct berval rdn = global_schemadn;
100                 vals[0].bv_val = strchr( rdn.bv_val, '=' );
101
102                 if( vals[0].bv_val == NULL ) {
103                         *text = "improperly configured subschema subentry";
104                         return LDAP_OTHER;
105                 }
106
107                 vals[0].bv_val++;
108                 vals[0].bv_len = rdn.bv_len - (vals[0].bv_val - rdn.bv_val);
109                 rdn.bv_len -= vals[0].bv_len + 1;
110
111                 rc = slap_bv2ad( &rdn, &desc, text );
112
113                 if( rc != LDAP_SUCCESS ) {
114                         entry_free( e );
115                         *text = "improperly configured subschema subentry";
116                         return LDAP_OTHER;
117                 }
118
119 #ifdef SLAP_NVALUES
120                 nvals[0].bv_val = strchr( global_schemandn.bv_val, '=' );
121                 assert( nvals[0].bv_val );
122                 nvals[0].bv_val++;
123                 nvals[0].bv_len = global_schemandn.bv_len -
124                         (nvals[0].bv_val - global_schemandn.bv_val);
125
126                 if( attr_merge_one( e, desc, vals, nvals ) )
127 #else
128                 if( attr_merge_one( e, desc, vals ) )
129 #endif
130                 {
131                         /* Out of memory, do something about it */
132                         entry_free( e );
133                         *text = "out of memory";
134                         return LDAP_OTHER;
135                 }
136         }
137
138         {
139                 struct          tm *ltm;
140                 char            timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
141
142                 /*
143                  * According to RFC 2251:
144
145    Servers SHOULD provide the attributes createTimestamp and
146    modifyTimestamp in subschema entries, in order to allow clients to
147    maintain their caches of schema information.
148
149                  * to be conservative, we declare schema created 
150                  * AND modified at server startup time ...
151                  */
152
153                 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
154                 ltm = gmtime( &starttime );
155                 lutil_gentime( timebuf, sizeof(timebuf), ltm );
156                 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
157
158                 vals[0].bv_val = timebuf;
159                 vals[0].bv_len = strlen( timebuf );
160
161 #ifdef SLAP_NVALUES
162                 if( attr_merge_one( e, ad_createTimestamp, vals, vals ) )
163 #else
164                 if( attr_merge_one( e, ad_createTimestamp, vals ) )
165 #endif
166                 {
167                         /* Out of memory, do something about it */
168                         entry_free( e );
169                         *text = "out of memory";
170                         return LDAP_OTHER;
171                 }
172 #ifdef SLAP_NVALUES
173                 if( attr_merge_one( e, ad_modifyTimestamp, vals, vals ) )
174 #else
175                 if( attr_merge_one( e, ad_modifyTimestamp, vals ) )
176 #endif
177                 {
178                         /* Out of memory, do something about it */
179                         entry_free( e );
180                         *text = "out of memory";
181                         return LDAP_OTHER;
182                 }
183         }
184
185         if ( syn_schema_info( e ) 
186                 || mr_schema_info( e )
187                 || mru_schema_info( e )
188                 || at_schema_info( e )
189                 || oc_schema_info( e )
190                 || cr_schema_info( e ) )
191         {
192                 /* Out of memory, do something about it */
193                 entry_free( e );
194                 *text = "out of memory";
195                 return LDAP_OTHER;
196         }
197         
198         *entry = e;
199         return LDAP_SUCCESS;
200 }