]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb2/dn2id.c
dbf2ab4412752cf5cf88adca83f03dd05aec82bd
[openldap] / servers / slapd / back-bdb2 / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2
3 #include "portable.h"
4
5 #include <stdio.h>
6
7 #include <ac/string.h>
8 #include <ac/socket.h>
9
10 #include "slap.h"
11 #include "back-bdb2.h"
12 #include "proto-back-bdb2.h"
13
14 int
15 bdb2i_dn2id_add(
16     BackendDB   *be,
17     const char  *dn,
18     ID          id
19 )
20 {
21         int             rc, flags;
22         struct dbcache  *db;
23         Datum           key, data;
24         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
25
26         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
27
28         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
29             == NULL ) {
30                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
31                     BDB2_SUFFIX, 0, 0 );
32                 return( -1 );
33         }
34
35         ldbm_datum_init( key );
36         key.dsize = strlen( dn ) + 2;
37         key.dptr = ch_malloc( key.dsize );
38         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
39
40         ldbm_datum_init( data );
41         data.dptr = (char *) &id;
42         data.dsize = sizeof(ID);
43
44         flags = LDBM_INSERT;
45         if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
46
47         rc = bdb2i_cache_store( db, key, data, flags );
48
49         free( key.dptr );
50
51         if ( rc != -1 ) {
52                 char *pdn = dn_parent( NULL, dn );
53
54                 if( pdn != NULL ) {
55                         ldbm_datum_init( key );
56                         key.dsize = strlen( pdn ) + 2;
57                         key.dptr = ch_malloc( key.dsize );
58                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
59                         rc = bdb2i_idl_insert_key( be, db, key, id );
60                         free( key.dptr );
61                         free( pdn );
62                 }
63         }
64
65         if ( rc != -1 ) {
66                 char **subtree = dn_subtree( NULL, dn );
67
68                 if( subtree != NULL ) {
69                         int i;
70                         for( i=0; subtree[i] != NULL; i++ ) {
71                                 ldbm_datum_init( key );
72                                 key.dsize = strlen( subtree[i] ) + 2;
73                                 key.dptr = ch_malloc( key.dsize );
74                                 sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
75
76                                 rc = bdb2i_idl_insert_key( be, db, key, id );
77
78                                 free( key.dptr );
79                         }
80
81                         charray_free( subtree );
82                 }
83         }
84
85         bdb2i_cache_close( be, db );
86
87         Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_add %d\n", rc, 0, 0 );
88         return( rc );
89 }
90
91 ID
92 bdb2i_dn2id(
93     BackendDB   *be,
94     const char  *dn
95 )
96 {
97         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
98         struct dbcache  *db;
99         ID              id;
100         Datum           key, data;
101
102         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id( \"%s\" )\n", dn, 0, 0 );
103
104         /* first check the cache */
105         if ( (id = bdb2i_cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
106                 Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld (in cache)\n", id,
107                         0, 0 );
108                 return( id );
109         }
110
111         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
112                 == NULL ) {
113                 Debug( LDAP_DEBUG_ANY, "<= bdb2i_dn2id could not open dn2id%s\n",
114                         BDB2_SUFFIX, 0, 0 );
115                 return( NOID );
116         }
117
118         ldbm_datum_init( key );
119
120         key.dsize = strlen( dn ) + 2;
121         key.dptr = ch_malloc( key.dsize );
122         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
123
124         data = bdb2i_cache_fetch( db, key );
125
126         bdb2i_cache_close( be, db );
127
128         free( key.dptr );
129
130         if ( data.dptr == NULL ) {
131                 Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id NOID\n", 0, 0, 0 );
132                 return( NOID );
133         }
134
135         (void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
136
137         ldbm_datum_free( db->dbc_db, data );
138
139         Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld\n", id, 0, 0 );
140         return( id );
141 }
142
143 ID_BLOCK *
144 bdb2i_dn2idl(
145     BackendDB   *be,
146     const char  *dn,
147         int     prefix )
148 {
149         struct dbcache  *db;
150         Datum key;
151         ID_BLOCK *idl;
152
153         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
154
155         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
156             == NULL ) {
157                 Debug( LDAP_DEBUG_ANY,
158                     "<= bdb2i_dn2idl could not open dn2id%s\n", BDB2_SUFFIX,
159                     0, 0 );
160                 return( NULL );
161         }
162
163         ldbm_datum_init( key );
164
165         key.dsize = strlen( dn ) + 2;
166         key.dptr = ch_malloc( key.dsize );
167         sprintf( key.dptr, "%c%s", prefix, dn );
168
169         idl = bdb2i_idl_fetch( be, db, key );
170
171         free( key.dptr );
172
173         bdb2i_cache_close( be, db );
174
175         return( idl );
176 }
177
178 int
179 bdb2i_dn2id_delete(
180     BackendDB   *be,
181     const char  *dn,
182         ID id
183 )
184 {
185         struct dbcache  *db;
186         Datum           key;
187         int             rc;
188
189         Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_delete( \"%s\", %ld )\n",
190                 dn, id, 0 );
191
192         if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
193             == NULL ) {
194                 Debug( LDAP_DEBUG_ANY,
195                     "<= bdb2i_dn2id_delete could not open dn2id%s\n", BDB2_SUFFIX,
196                     0, 0 );
197                 return( -1 );
198         }
199
200         {
201                 char *pdn = dn_parent( NULL, dn );
202
203                 if( pdn != NULL ) {
204                         ldbm_datum_init( key );
205                         key.dsize = strlen( pdn ) + 2;
206                         key.dptr = ch_malloc( key.dsize );
207                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
208                         (void) bdb2i_idl_delete_key( be, db, key, id );
209                         free( key.dptr );
210                         free( pdn );
211                 }
212         }
213
214         {
215                 char **subtree = dn_subtree( NULL, dn );
216
217                 if( subtree != NULL ) {
218                         int i;
219                         for( i=0; subtree[i] != NULL; i++ ) {
220                                 ldbm_datum_init( key );
221                                 key.dsize = strlen( subtree[i] ) + 2;
222                                 key.dptr = ch_malloc( key.dsize );
223                                 sprintf( key.dptr, "%c%s", DN_SUBTREE_PREFIX, subtree[i] );
224
225                                 (void) bdb2i_idl_delete_key( be, db, key, id );
226
227                                 free( key.dptr );
228                         }
229
230                         charray_free( subtree );
231                 }
232         }
233
234         ldbm_datum_init( key );
235
236         key.dsize = strlen( dn ) + 2;
237         key.dptr = ch_malloc( key.dsize );
238         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
239
240         rc = bdb2i_cache_delete( db, key );
241
242         free( key.dptr );
243
244         bdb2i_cache_close( be, db );
245
246         Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_delete %d\n", rc, 0, 0 );
247         return( rc );
248 }
249
250 /*
251  * dn2entry - look up dn in the cache/indexes and return the corresponding
252  * entry.
253  */
254
255 Entry *
256 bdb2i_dn2entry_rw(
257     BackendDB   *be,
258     const char  *dn,
259     Entry       **matched,
260     int         rw
261 )
262 {
263         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
264         ID              id;
265         Entry           *e = NULL;
266         char            *pdn;
267
268         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
269                 rw ? "w" : "r", dn, 0);
270
271         if( matched != NULL ) {
272                 /* caller cares about match */
273                 *matched = NULL;
274         }
275
276         if ( (id = bdb2i_dn2id( be, dn )) != NOID &&
277                 (e = bdb2i_id2entry_rw( be, id, rw )) != NULL )
278         {
279                 return( e );
280         }
281
282         if ( id != NOID ) {
283                 Debug(LDAP_DEBUG_ANY,
284                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
285                         rw ? "w" : "r", id, dn);
286                 /* must have been deleted from underneath us */
287                 /* treat as if NOID was found */
288         }
289
290         /* caller doesn't care about match */
291         if( matched == NULL ) return NULL;
292
293         /* entry does not exist - see how much of the dn does exist */
294         /* dn_parent checks returns NULL if dn is suffix */
295         if ( (pdn = dn_parent( be, dn )) != NULL ) {
296                 /* get entry with reader lock */
297                 if ( (e = bdb2i_dn2entry_r( be, pdn, matched )) != NULL ) {
298                         *matched = e;
299                 }
300                 free( pdn );
301         }
302
303         return( NULL );
304 }
305
306