]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/dn2id.c
Fix previous commit
[openldap] / servers / slapd / back-bdb / 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 #include <ac/string.h>
12
13 #include "back-bdb.h"
14 #include "idl.h"
15
16 int
17 bdb_dn2id_add(
18         BackendDB       *be,
19         DB_TXN *txn,
20         const char      *pdn,
21         Entry           *e )
22 {
23         int             rc;
24         DBT             key, data;
25         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
26         DB *db = bdb->bi_dn2id->bdi_db;
27
28         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_add( \"%s\", 0x%08lx )\n",
29                 e->e_ndn, (long) e->e_id, 0 );
30         assert( e->e_id != NOID );
31
32         DBTzero( &key );
33         key.size = strlen( e->e_ndn ) + 2;
34         key.data = ch_malloc( key.size );
35         ((char *)key.data)[0] = DN_BASE_PREFIX;
36         AC_MEMCPY( &((char *)key.data)[1], e->e_ndn, key.size - 1 );
37
38         DBTzero( &data );
39         data.data = (char *) &e->e_id;
40         data.size = sizeof( e->e_id );
41
42         /* store it -- don't override */
43         rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
44         if( rc != 0 ) {
45                 Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_add: put failed: %s %d\n",
46                         db_strerror(rc), rc, 0 );
47                 goto done;
48         }
49
50         {
51                 ((char *)(key.data))[0] = DN_ONE_PREFIX;
52
53                 if( pdn != NULL ) {
54                         key.size = strlen( pdn ) + 2;
55                         AC_MEMCPY( &((char*)key.data)[1],
56                                 pdn, key.size - 1 );
57
58                         rc = bdb_idl_insert_key( be, db, txn, &key, e->e_id );
59
60                         if( rc != 0 ) {
61                                 Debug( LDAP_DEBUG_ANY,
62                                         "=> bdb_dn2id_add: parent (%s) insert failed: %d\n",
63                                         pdn, rc, 0 );
64                                 goto done;
65                         }
66                 }
67         }
68
69         {
70                 char **subtree = dn_subtree( be, e->e_ndn );
71
72                 if( subtree != NULL ) {
73                         int i;
74                         ((char *)key.data)[0] = DN_SUBTREE_PREFIX;
75                         for( i=0; subtree[i] != NULL; i++ ) {
76                                 key.size = strlen( subtree[i] ) + 2;
77                                 AC_MEMCPY( &((char *)key.data)[1],
78                                         subtree[i], key.size - 1 );
79
80                                 rc = bdb_idl_insert_key( be, db, txn, &key,
81                                         e->e_id );
82
83                                 if( rc != 0 ) {
84                                         Debug( LDAP_DEBUG_ANY,
85                                                 "=> bdb_dn2id_add: subtree (%s) insert failed: %d\n",
86                                                 subtree[i], rc, 0 );
87                                         break;
88                                 }
89                         }
90
91                         charray_free( subtree );
92                 }
93         }
94
95 done:
96         ch_free( key.data );
97         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add: %d\n", rc, 0, 0 );
98         return rc;
99 }
100
101 int
102 bdb_dn2id_delete(
103         BackendDB       *be,
104         DB_TXN *txn,
105         const char      *pdn,
106         const char      *dn,
107         ID              id )
108 {
109         int             rc;
110         DBT             key;
111         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
112         DB *db = bdb->bi_dn2id->bdi_db;
113
114         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete( \"%s\", 0x%08lx )\n",
115                 dn, id, 0 );
116
117         DBTzero( &key );
118         key.size = strlen( dn ) + 2;
119         key.data = ch_malloc( key.size );
120         ((char *)key.data)[0] = DN_BASE_PREFIX;
121         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
122
123         /* delete it */
124         rc = db->del( db, txn, &key, 0 );
125         if( rc != 0 ) {
126                 Debug( LDAP_DEBUG_ANY, "=> bdb_dn2id_delete: delete failed: %s %d\n",
127                         db_strerror(rc), rc, 0 );
128                 goto done;
129         }
130
131         {
132                 ((char *)(key.data))[0] = DN_ONE_PREFIX;
133
134                 if( pdn != NULL ) {
135                         key.size = strlen( pdn ) + 2;
136                         AC_MEMCPY( &((char*)key.data)[1],
137                                 pdn, key.size - 1 );
138
139                         rc = bdb_idl_delete_key( be, db, txn, &key, id );
140
141                         if( rc != 0 ) {
142                                 Debug( LDAP_DEBUG_ANY,
143                                         "=> bdb_dn2id_delete: parent (%s) delete failed: %d\n",
144                                         pdn, rc, 0 );
145                                 goto done;
146                         }
147                 }
148         }
149
150         {
151                 char **subtree = dn_subtree( be, dn );
152
153                 if( subtree != NULL ) {
154                         int i;
155                         ((char *)key.data)[0] = DN_SUBTREE_PREFIX;
156                         for( i=0; subtree[i] != NULL; i++ ) {
157                                 key.size = strlen( subtree[i] ) + 2;
158                                 AC_MEMCPY( &((char *)key.data)[1],
159                                         subtree[i], key.size - 1 );
160
161                                 rc = bdb_idl_delete_key( be, db, txn, &key, id );
162
163                                 if( rc != 0 ) {
164                                         Debug( LDAP_DEBUG_ANY,
165                                                 "=> bdb_dn2id_delete: subtree (%s) delete failed: %d\n",
166                                                 subtree[i], rc, 0 );
167                                         charray_free( subtree );
168                                         goto done;
169                                 }
170                         }
171
172                         charray_free( subtree );
173                 }
174         }
175
176 done:
177         ch_free( key.data );
178         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete %d\n", rc, 0, 0 );
179         return rc;
180 }
181
182 int
183 bdb_dn2id(
184         BackendDB       *be,
185         DB_TXN *txn,
186         const char      *dn,
187         ID *id )
188 {
189         int             rc;
190         DBT             key, data;
191         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
192         DB *db = bdb->bi_dn2id->bdi_db;
193
194         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id( \"%s\" )\n", dn, 0, 0 );
195
196         DBTzero( &key );
197         key.size = strlen( dn ) + 2;
198         key.data = ch_malloc( key.size );
199         ((char *)key.data)[0] = DN_BASE_PREFIX;
200         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
201
202         /* store the ID */
203         DBTzero( &data );
204         data.data = id;
205         data.ulen = sizeof(ID);
206         data.flags = DB_DBT_USERMEM;
207
208         /* fetch it */
209         rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
210
211         if( rc != 0 ) {
212                 Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: get failed: %s (%d)\n",
213                         db_strerror( rc ), rc, 0 );
214         } else {
215                 Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: got id=0x%08lx\n",
216                         *id, 0, 0 );
217         }
218
219         ch_free( key.data );
220         return rc;
221 }
222
223 int
224 bdb_dn2id_matched(
225         BackendDB       *be,
226         DB_TXN *txn,
227         const char      *in,
228         ID *id,
229         char **matchedDN )
230 {
231         int             rc;
232         DBT             key, data;
233         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
234         DB *db = bdb->bi_dn2id->bdi_db;
235         const char *dn = in;
236         char *tmp = NULL;
237
238         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_matched( \"%s\" )\n", dn, 0, 0 );
239
240         DBTzero( &key );
241         key.size = strlen( dn ) + 2;
242         key.data = ch_malloc( key.size );
243         ((char *)key.data)[0] = DN_BASE_PREFIX;
244
245         /* store the ID */
246         DBTzero( &data );
247         data.data = id;
248         data.ulen = sizeof(ID);
249         data.flags = DB_DBT_USERMEM;
250
251         *matchedDN = NULL;
252
253         while(1) {
254                 AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
255
256                 *id = NOID;
257
258                 /* fetch it */
259                 rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
260
261                 if( rc == DB_NOTFOUND ) {
262                         char *pdn = dn_parent( be, dn );
263                         ch_free( tmp );
264                         tmp = NULL;
265
266                         if( pdn == NULL || *pdn == '\0' ) {
267                                 Debug( LDAP_DEBUG_TRACE,
268                                         "<= bdb_dn2id_matched: no match\n",
269                                         0, 0, 0 );
270                                 ch_free( pdn );
271                                 break;
272                         }
273
274                         dn = pdn;
275                         tmp = pdn;
276                         key.size = strlen( dn ) + 2;
277
278                 } else if ( rc == 0 ) {
279                         if( data.size != sizeof( ID ) ) {
280                                 Debug( LDAP_DEBUG_ANY,
281                                         "<= bdb_dn2id_matched: get size mismatch: "
282                                         "expected %ld, got %ld\n",
283                                         (long) sizeof(ID), (long) data.size, 0 );
284                                 ch_free( tmp );
285                         }
286
287                         if( in != dn ) {
288                                 *matchedDN = (char *) dn;
289                         }
290
291                         Debug( LDAP_DEBUG_TRACE,
292                                 "<= bdb_dn2id_matched: id=0x%08lx: %s %s\n",
293                                 (long) *id, *matchedDN == NULL ? "entry" : "matched", dn );
294                         break;
295
296                 } else {
297                         Debug( LDAP_DEBUG_ANY,
298                                 "<= bdb_dn2id_matched: get failed: %s (%d)\n",
299                                 db_strerror(rc), rc, 0 );
300                         ch_free( tmp );
301                         break;
302                 }
303         }
304
305         ch_free( key.data );
306         return rc;
307 }
308
309 int
310 bdb_dn2id_children(
311         BackendDB       *be,
312         DB_TXN *txn,
313         const char *dn )
314 {
315         int             rc;
316         DBT             key, data;
317         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
318         DB *db = bdb->bi_dn2id->bdi_db;
319         ID              id;
320
321         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children( %s )\n",
322                 dn, 0, 0 );
323
324         DBTzero( &key );
325         key.size = strlen( dn ) + 2;
326         key.data = ch_malloc( key.size );
327         ((char *)key.data)[0] = DN_ONE_PREFIX;
328         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
329
330         /* we actually could do a empty get... */
331         DBTzero( &data );
332         data.data = &id;
333         data.ulen = sizeof(id);
334         data.flags = DB_DBT_USERMEM;
335         data.doff = 0;
336         data.dlen = sizeof(id);
337
338         rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
339
340         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %schildren (%d)\n",
341                 dn,
342                 rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
343                         db_strerror(rc) ), rc );
344
345         return rc;
346 }
347
348 int
349 bdb_dn2idl(
350         BackendDB       *be,
351         const char      *dn,
352         int prefix,
353         ID *ids )
354 {
355         int             rc;
356         DBT             key, data;
357         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
358         DB *db = bdb->bi_dn2id->bdi_db;
359
360         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2idl( \"%s\" )\n", dn, 0, 0 );
361
362         if (prefix == DN_SUBTREE_PREFIX && be_issuffix(be, dn))
363         {
364                 BDB_IDL_ALL(bdb, ids);
365                 return 0;
366         }
367
368         DBTzero( &key );
369         key.size = strlen( dn ) + 2;
370         key.data = ch_malloc( key.size );
371         ((char *)key.data)[0] = prefix;
372         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
373
374         /* store the ID */
375         DBTzero( &data );
376         data.data = ids;
377         data.ulen = BDB_IDL_UM_SIZEOF;  
378         data.flags = DB_DBT_USERMEM;
379
380         /* fetch it */
381         rc = db->get( db, NULL, &key, &data, bdb->bi_db_opflags );
382
383         if( rc != 0 ) {
384                 Debug( LDAP_DEBUG_TRACE,
385                         "<= bdb_dn2idl: get failed: %s (%d)\n",
386                         db_strerror( rc ), rc, 0 );
387
388         } else {
389                 Debug( LDAP_DEBUG_TRACE,
390                         "<= bdb_dn2idl: id=%ld first=%ld last=%ld\n",
391                         (long) ids[0],
392                         (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) );
393         }
394
395         ch_free( key.data );
396         return rc;
397 }