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