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