]> git.sur5r.net Git - openldap/blob - servers/slapd/schema.c
Round one of SLAP_NVALUES code
[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                 nvals[0].bv_val++;
122                 nvals[0].bv_len = global_schemandn.bv_len -
123                         (nvals[0].bv_val - global_schemandn.bv_val);
124
125                 if( attr_merge_one( e, desc, vals, nvals ) )
126 #else
127                 if( attr_merge_one( e, desc, vals ) )
128 #endif
129                 {
130                         /* Out of memory, do something about it */
131                         entry_free( e );
132                         *text = "out of memory";
133                         return LDAP_OTHER;
134                 }
135         }
136
137         {
138                 struct          tm *ltm;
139                 char            timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
140
141                 /*
142                  * According to RFC 2251:
143
144    Servers SHOULD provide the attributes createTimestamp and
145    modifyTimestamp in subschema entries, in order to allow clients to
146    maintain their caches of schema information.
147
148                  * to be conservative, we declare schema created 
149                  * AND modified at server startup time ...
150                  */
151
152                 ldap_pvt_thread_mutex_lock( &gmtime_mutex );
153                 ltm = gmtime( &starttime );
154                 lutil_gentime( timebuf, sizeof(timebuf), ltm );
155                 ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
156
157                 vals[0].bv_val = timebuf;
158                 vals[0].bv_len = strlen( timebuf );
159
160 #ifdef SLAP_NVALUES
161                 if( attr_merge_one( e, ad_createTimestamp, vals, vals ) )
162 #else
163                 if( attr_merge_one( e, ad_createTimestamp, vals ) )
164 #endif
165                 {
166                         /* Out of memory, do something about it */
167                         entry_free( e );
168                         *text = "out of memory";
169                         return LDAP_OTHER;
170                 }
171 #ifdef SLAP_NVALUES
172                 if( attr_merge_one( e, ad_modifyTimestamp, vals, vals ) )
173 #else
174                 if( attr_merge_one( e, ad_modifyTimestamp, vals ) )
175 #endif
176                 {
177                         /* Out of memory, do something about it */
178                         entry_free( e );
179                         *text = "out of memory";
180                         return LDAP_OTHER;
181                 }
182         }
183
184         if ( syn_schema_info( e ) 
185                 || mr_schema_info( e )
186                 || mru_schema_info( e )
187                 || at_schema_info( e )
188                 || oc_schema_info( e )
189                 || cr_schema_info( e ) )
190         {
191                 /* Out of memory, do something about it */
192                 entry_free( e );
193                 *text = "out of memory";
194                 return LDAP_OTHER;
195         }
196         
197         *entry = e;
198         return LDAP_SUCCESS;
199 }