]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/dn2id.c
Converted all use of dn_parent to the in-place version. (Fixed a pdn leak
[openldap] / servers / slapd / back-ldbm / dn2id.c
1 /* dn2id.c - routines to deal with the dn2id index */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 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     const char  *dn,
23     ID          id
24 )
25 {
26         int             rc, flags;
27         DBCache *db;
28         Datum           key, data;
29
30 #ifdef NEW_LOGGING
31         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
32                    "dn2id_add: (%s):%ld\n", dn, id ));
33 #else
34         Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
35 #endif
36
37         assert( id != NOID );
38
39         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
40             == NULL ) {
41 #ifdef NEW_LOGGING
42                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
43                            "dn2id_add: couldn't open/create dn2id%s\n", LDBM_SUFFIX ));
44 #else
45                 Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
46                     LDBM_SUFFIX, 0, 0 );
47 #endif
48
49                 return( -1 );
50         }
51
52         ldbm_datum_init( key );
53         key.dsize = strlen( dn ) + 2;
54         key.dptr = ch_malloc( key.dsize );
55         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
56
57         ldbm_datum_init( data );
58         data.dptr = (char *) &id;
59         data.dsize = sizeof(ID);
60
61         flags = LDBM_INSERT;
62         rc = ldbm_cache_store( db, key, data, flags );
63
64         free( key.dptr );
65
66         if ( rc != -1 ) {
67                 char *pdn = dn_parent( be, dn );
68
69                 if( pdn != NULL ) {
70                         ldbm_datum_init( key );
71                         key.dsize = strlen( pdn ) + 2;
72                         key.dptr = ch_malloc( key.dsize );
73                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
74                         ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
75                         rc = idl_insert_key( be, db, key, id );
76                         ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
77                         free( key.dptr );
78                 }
79         }
80
81         if ( rc != -1 ) {
82                 char **subtree = dn_subtree( be, dn );
83
84                 if( subtree != NULL ) {
85                         int i;
86                         for( i=0; subtree[i] != NULL; i++ ) {
87                                 ldbm_datum_init( key );
88                                 key.dsize = strlen( subtree[i] ) + 2;
89                                 key.dptr = ch_malloc( key.dsize );
90                                 sprintf( key.dptr, "%c%s",
91                                         DN_SUBTREE_PREFIX, subtree[i] );
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                                 free( key.dptr );
96
97                                 if(rc == -1) break;
98                         }
99
100                         charray_free( subtree );
101                 }
102         }
103
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     const char  *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 ));
130 #else
131         Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 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 = strlen( dn ) + 2;
169         key.dptr = ch_malloc( key.dsize );
170         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
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     const char  *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 ));
220 #else
221         Debug( LDAP_DEBUG_TRACE, "=> dn2idl( \"%c%s\" )\n", prefix, dn, 0 );
222 #endif
223
224         assert( idlp != NULL );
225         *idlp = NULL;
226
227         if ( prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn) ) {
228                 *idlp = ch_malloc( sizeof(ID) );
229                 **idlp = ID_BLOCK_ALLIDS_VALUE;
230                 return 0;
231         }
232
233         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
234                 == NULL ) {
235 #ifdef NEW_LOGGING
236                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
237                            "dn2idl: could not open dn2id%s\n", LDBM_SUFFIX ));
238 #else
239                 Debug( LDAP_DEBUG_ANY, "<= dn2idl could not open dn2id%s\n",
240                         LDBM_SUFFIX, 0, 0 );
241 #endif
242
243                 return -1;
244         }
245
246         ldbm_datum_init( key );
247
248         key.dsize = strlen( dn ) + 2;
249         key.dptr = ch_malloc( key.dsize );
250         sprintf( key.dptr, "%c%s", prefix, dn );
251
252         *idlp = idl_fetch( be, db, key );
253
254         ldbm_cache_close( be, db );
255
256         free( key.dptr );
257
258         return( 0 );
259 }
260
261
262 int
263 dn2id_delete(
264     Backend     *be,
265     const char  *dn,
266         ID id
267 )
268 {
269         DBCache *db;
270         Datum           key;
271         int             rc;
272
273 #ifdef NEW_LOGGING
274         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
275                    "dn2id_delete: (%s)%ld\n", dn, id ));
276 #else
277         Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
278 #endif
279
280
281         assert( id != NOID );
282
283         if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
284             == NULL ) {
285 #ifdef NEW_LOGGING
286                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
287                            "dn2id_delete: couldn't open db2id%s\n", LDBM_SUFFIX ));
288 #else
289                 Debug( LDAP_DEBUG_ANY,
290                     "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
291                     0, 0 );
292 #endif
293
294                 return( -1 );
295         }
296
297
298         {
299                 char *pdn = dn_parent( be, dn );
300
301                 if( pdn != NULL ) {
302                         ldbm_datum_init( key );
303                         key.dsize = strlen( pdn ) + 2;
304                         key.dptr = ch_malloc( key.dsize );
305                         sprintf( key.dptr, "%c%s", DN_ONE_PREFIX, pdn );
306
307                         ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
308                         (void) idl_delete_key( be, db, key, id );
309                         ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
310
311                         free( key.dptr );
312                 }
313         }
314
315         {
316                 char **subtree = dn_subtree( be, dn );
317
318                 if( subtree != NULL ) {
319                         int i;
320                         for( i=0; subtree[i] != NULL; i++ ) {
321                                 ldbm_datum_init( key );
322                                 key.dsize = strlen( subtree[i] ) + 2;
323                                 key.dptr = ch_malloc( key.dsize );
324                                 sprintf( key.dptr, "%c%s",
325                                         DN_SUBTREE_PREFIX, subtree[i] );
326
327                                 ldap_pvt_thread_mutex_lock( &db->dbc_write_mutex );
328                                 (void) idl_delete_key( be, db, key, id );
329                                 ldap_pvt_thread_mutex_unlock( &db->dbc_write_mutex );
330
331                                 free( key.dptr );
332                         }
333
334                         charray_free( subtree );
335                 }
336         }
337
338         ldbm_datum_init( key );
339
340         key.dsize = strlen( dn ) + 2;
341         key.dptr = ch_malloc( key.dsize );
342         sprintf( key.dptr, "%c%s", DN_BASE_PREFIX, dn );
343
344         rc = ldbm_cache_delete( db, key );
345
346         free( key.dptr );
347
348         ldbm_cache_close( be, db );
349
350 #ifdef NEW_LOGGING
351         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
352                    "dn2id_delete: return %d\n", rc ));
353 #else
354         Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
355 #endif
356
357         return( rc );
358 }
359
360 /*
361  * dn2entry - look up dn in the cache/indexes and return the corresponding
362  * entry.
363  */
364
365 Entry *
366 dn2entry_rw(
367     Backend     *be,
368     const char  *dn,
369     Entry       **matched,
370     int         rw
371 )
372 {
373         ID              id;
374         Entry           *e = NULL;
375         char            *pdn;
376
377 #ifdef NEW_LOGGING
378         LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
379                    "dn2entry_rw: %s entry %s\n", rw ? "w" : "r",
380                    dn ));
381 #else
382         Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
383                 rw ? "w" : "r", dn, 0);
384 #endif
385
386
387         if( matched != NULL ) {
388                 /* caller cares about match */
389                 *matched = NULL;
390         }
391
392         if ( dn2id( be, dn, &id ) ) {
393                 /* something bad happened to ldbm cache */
394                 return( NULL );
395
396         } else if ( id != NOID ) {
397                 /* try to return the entry */
398                 if ((e = id2entry_rw( be, id, rw )) != NULL ) {
399                         return( e );
400                 }
401
402 #ifdef NEW_LOGGING
403                 LDAP_LOG(( "backend", LDAP_LEVEL_ERR,
404                            "dn2entry_rw: no entry for valid id (%ld), dn (%s)\n",
405                            id, dn ));
406 #else
407                 Debug(LDAP_DEBUG_ANY,
408                         "dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
409                         rw ? "w" : "r", id, dn);
410 #endif
411
412                 /* must have been deleted from underneath us */
413                 /* treat as if NOID was found */
414         }
415
416         /* caller doesn't care about match */
417         if( matched == NULL ) return NULL;
418
419         /* entry does not exist - see how much of the dn does exist */
420         /* dn_parent checks returns NULL if dn is suffix */
421         if ( (pdn = dn_parent( be, dn )) != NULL ) {
422                 /* get entry with reader lock */
423                 if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
424                         *matched = e;
425                 }
426         }
427
428         return NULL;
429 }
430