]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
Changed be_issuffix and dnParent to struct bervals
[openldap] / servers / slapd / back-ldbm / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
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/string.h>
13 #include <ac/socket.h>
14
15 #include "slap.h"
16 #include "back-ldbm.h"
17 #include "proto-back-ldbm.h"
18
19 int
20 dn2id_add(
21     Backend     *be,
22     struct berval *dn,
23     ID          id
24 )
25 {
26         int             rc, flags;
27         DBCache *db;
28         Datum           key, data;
29         char            *buf;
30         struct berval   ptr, pdn;
31
32 #ifdef NEW_LOGGING
33         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
34                    "dn2id_add: (%s):%ld\n", dn->bv_val, id ));
35 #else
36         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn->bv_val, id, 0 );
37 #endif
38
39         assert( id != NOID );
40
41         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
42             == NULL ) {
43 #ifdef NEW_LOGGING
44                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
45                            "dn2id_add: couldn't open/create dn2id%s\n", LDBM_SUFFIX ));
46 #else
47                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
48                     LDBM_SUFFIX, 0, 0 );
49 #endif
50
51                 return( -1 );
52         }
53
54         ldbm_datum_init( key );
55         key.dsize = dn->bv_len + 2;
56         buf = ch_malloc( key.dsize );
57         key.dptr = buf;
58         buf[0] = DN_BASE_PREFIX;
59         ptr.bv_val = buf + 1;
60         ptr.bv_len = dn->bv_len;
61         strcpy( ptr.bv_val, dn->bv_val );
62
63         ldbm_datum_init( data );
64         data.dptr = (char *) &id;
65         data.dsize = sizeof(ID);
66
67         flags = LDBM_INSERT;
68         rc = ldbm_cache_store( db, key, data, flags );
69
70         if ( rc != -1 && !be_issuffix( be, &ptr )) {
71                 buf[0] = DN_SUBTREE_PREFIX;
72                 ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
73                 rc = idl_insert_key( be, db, key, id );
74                 ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
75
76                 if ( rc != -1 ) {
77                         rc = dnParent( &ptr, &pdn );
78
79                         if( rc == LDAP_SUCCESS ) {
80                                 pdn.bv_val[-1] = DN_ONE_PREFIX;
81                                 key.dsize = pdn.bv_len + 2;
82                                 key.dptr = pdn.bv_val - 1;
83                                 ptr = pdn;
84                                 ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
85                                 rc = idl_insert_key( be, db, key, id );
86                                 ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
87                         }
88                 }
89         }
90
91         while ( rc != -1 && !be_issuffix( be, &ptr )) {
92                 ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
93
94                 ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
95                 rc = idl_insert_key( be, db, key, id );
96                 ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
97
98                 if( rc != 0 ) break;
99                 rc = dnParent( &ptr, &pdn );
100                 key.dsize = pdn.bv_len + 2;
101                 key.dptr = pdn.bv_val - 1;
102                 ptr = pdn;
103         }
104
105         free( buf );
106         ldbm_cache_close( be, db );
107
108 #ifdef NEW_LOGGING
109         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
110                    "dn2id_add: return %d\n", rc ));
111 #else
112         Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
113 #endif
114
115         return( rc );
116 }
117
118 int
119 dn2id(
120     Backend     *be,
121     struct berval *dn,
122     ID          *idp
123 )
124 {
125         struct ldbminfo *li = (struct ldbminfo *) be->be_private;
126         DBCache *db;
127         Datum           key, data;
128
129 #ifdef NEW_LOGGING
130         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
131                    "dn2id: (%s)\n", dn->bv_val ));
132 #else
133         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn->bv_val, 0, 0 );
134 #endif
135
136         assert( idp );
137
138         /* first check the cache */
139         if ( (*idp = cache_find_entry_ndn2id( be, &li->li_cache, dn )) != NOID ) {
140 #ifdef NEW_LOGGING
141                 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
142                            "dn2id: (%s)%ld in cache.\n", dn, *idp ));
143 #else
144                 Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld (in cache)\n", *idp,
145                         0, 0 );
146 #endif
147
148                 return( 0 );
149         }
150
151         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
152                 == NULL ) {
153 #ifdef NEW_LOGGING
154                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
155                            "dn2id: couldn't open dn2id%s\n", LDBM_SUFFIX ));
156 #else
157                 Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
158                         LDBM_SUFFIX, 0, 0 );
159 #endif
160                 /*
161                  * return code !0 if ldbm cache open failed;
162                  * callers should handle this
163                  */
164                 *idp = NOID;
165                 return( -1 );
166         }
167
168         ldbm_datum_init( key );
169
170         key.dsize = dn->bv_len + 2;
171         key.dptr = ch_malloc( key.dsize );
172         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn->bv_val );
173
174         data = ldbm_cache_fetch( db, key );
175
176         ldbm_cache_close( be, db );
177
178         free( key.dptr );
179
180         if ( data.dptr == NULL ) {
181 #ifdef NEW_LOGGING
182                 LDAP_LOG(( "backend", LDAP_LEVEL_INFO,
183                            "dn2id: (%s) NOID\n", dn ));
184 #else
185                 Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
186 #endif
187
188                 *idp = NOID;
189                 return( 0 );
190         }
191
192         AC_MEMCPY( (char *) idp, data.dptr, sizeof(ID) );
193
194         assert( *idp != NOID );
195
196         ldbm_datum_free( db->dbc_db, data );
197
198 #ifdef NEW_LOGGING
199         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
200                    "dn2id: %ld\n", *idp ));
201 #else
202         Debug( LDAP_DEBUG_TRACE, "<= dn2id %ld\n", *idp, 0, 0 );
203 #endif
204
205         return( 0 );
206 }
207
208 int
209 dn2idl(
210     Backend     *be,
211     struct berval       *dn,
212     int         prefix,
213     ID_BLOCK    **idlp
214 )
215 {
216         DBCache *db;
217         Datum           key;
218
219 #ifdef NEW_LOGGING
220         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
221                    "dn2idl: \"%c%s\"\n", prefix, dn->bv_val ));
222 #else
223         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn->bv_val, 0 );
224 #endif
225
226         assert( idlp != NULL );
227         *idlp = NULL;
228
229         if ( prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn) ) {
230                 *idlp = idl_allids( be );
231                 return 0;
232         }
233
234         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
235                 == NULL ) {
236 #ifdef NEW_LOGGING
237                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
238                            "dn2idl: could not open dn2id%s\n", LDBM_SUFFIX ));
239 #else
240                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
241                         LDBM_SUFFIX, 0, 0 );
242 #endif
243
244                 return -1;
245         }
246
247         ldbm_datum_init( key );
248
249         key.dsize = dn->bv_len + 2;
250         key.dptr = ch_malloc( key.dsize );
251         sprintf( key.dptr, "%c%s", prefix, dn->bv_val );
252
253         *idlp = idl_fetch( be, db, key );
254
255         ldbm_cache_close( be, db );
256
257         free( key.dptr );
258
259         return( 0 );
260 }
261
262
263 int
264 dn2id_delete(
265     Backend     *be,
266     struct berval *dn,
267         ID id
268 )
269 {
270         DBCache *db;
271         Datum           key;
272         int             rc;
273         char            *buf;
274         struct berval   ptr, pdn;
275
276 #ifdef NEW_LOGGING
277         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
278                    "dn2id_delete: (%s)%ld\n", dn->bv_val, id ));
279 #else
280         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn->bv_val, id, 0 );
281 #endif
282
283
284         assert( id != NOID );
285
286         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
287             == NULL ) {
288 #ifdef NEW_LOGGING
289                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
290                            "dn2id_delete: couldn't open db2id%s\n", LDBM_SUFFIX ));
291 #else
292                 Debug( LDAP_DEBUG_ANY,
293                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
294                     0, 0 );
295 #endif
296
297                 return( -1 );
298         }
299
300         ldbm_datum_init( key );
301         key.dsize = dn->bv_len + 2;
302         buf = ch_malloc( key.dsize );
303         key.dptr = buf;
304         buf[0] = DN_BASE_PREFIX;
305         ptr.bv_val = buf + 1;
306         ptr.bv_len = dn->bv_len;
307         strcpy( ptr.bv_val, dn->bv_val );
308
309         rc = ldbm_cache_delete( db, key );
310         
311         if( !be_issuffix( be, &ptr )) {
312                 buf[0] = DN_SUBTREE_PREFIX;
313                 ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
314                 (void) idl_delete_key( be, db, key, id );
315                 ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
316
317                 rc = dnParent( &ptr, &pdn );
318
319                 if( rc == LDAP_SUCCESS ) {
320                         pdn.bv_val[-1] = DN_ONE_PREFIX;
321                         key.dsize = pdn.bv_len + 2;
322                         key.dptr = pdn.bv_val - 1;
323                         ptr = pdn;
324
325                         ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
326                         (void) idl_delete_key( be, db, key, id );
327                         ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
328                 }
329         }
330
331         while ( rc != -1 && !be_issuffix( be, &ptr )) {
332                 ptr.bv_val[-1] = DN_SUBTREE_PREFIX;
333
334                 ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
335                 (void) idl_delete_key( be, db, key, id );
336                 ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
337
338                 rc = dnParent( &ptr, &pdn );
339                 key.dsize = pdn.bv_len + 2;
340                 key.dptr = pdn.bv_val - 1;
341                 ptr = pdn;
342         }
343
344         free( buf );
345
346         ldbm_cache_close( be, db );
347
348 #ifdef NEW_LOGGING
349         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
350                    "dn2id_delete: return %d\n", rc ));
351 #else
352         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
353 #endif
354
355         return( rc );
356 }
357
358 /*
359  * dn2entry - look up dn in the cache/indexes and return the corresponding
360  * entry.
361  */
362
363 Entry *
364 dn2entry_rw(
365     Backend     *be,
366     struct berval *dn,
367     Entry       **matched,
368     int         rw
369 )
370 {
371         ID              id;
372         Entry           *e = NULL;
373         struct berval   pdn;
374
375 #ifdef NEW_LOGGING
376         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
377                    "dn2entry_rw: %s entry %s\n", rw ? "w" : "r",
378                    dn->bv_val ));
379 #else
380         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
381                 rw ? "w" : "r", dn->bv_val, 0);
382 #endif
383
384
385         if( matched != NULL ) {
386                 /* caller cares about match */
387                 *matched = NULL;
388         }
389
390         if ( dn2id( be, dn, &id ) ) {
391                 /* something bad happened to ldbm cache */
392                 return( NULL );
393
394         } else if ( id != NOID ) {
395                 /* try to return the entry */
396                 if ((e = id2entry_rw( be, id, rw )) != NULL ) {
397                         return( e );
398                 }
399
400 #ifdef NEW_LOGGING
401                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
402                            "dn2entry_rw: no entry for valid id (%ld), dn (%s)\n",
403                            id, dn->bv_val ));
404 #else
405                 Debug(LDAP_DEBUG_ANY,
406                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
407                         rw ? "w" : "r", id, dn->bv_val);
408 #endif
409
410                 /* must have been deleted from underneath us */
411                 /* treat as if NOID was found */
412         }
413
414         /* caller doesn't care about match */
415         if( matched == NULL ) return NULL;
416
417         /* entry does not exist - see how much of the dn does exist */
418         if ( !be_issuffix( be, dn ) && dnParent( dn, &pdn ) == LDAP_SUCCESS
419                 && pdn.bv_len ) {
420                 /* get entry with reader lock */
421                 if ( (e = dn2entry_r( be, &pdn, matched )) != NULL ) {
422                         *matched = e;
423                 }
424         }
425
426         return NULL;
427 }
428