]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/dn2id.c
Add dn2entry.c
[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
15 int
16 bdb_dn2id_add(
17     Backend     *be,
18         DB_TXN *txn,
19     const char  *dn,
20     ID          id
21 )
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\", %ld )\n", dn, id, 0 );
29         assert( id != NOID );
30
31         DBTzero( &key );
32         key.size = strlen( dn ) + 2;
33         key.data = ch_malloc( key.size );
34         ((char *)key.data)[0] = DN_BASE_PREFIX;
35         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
36
37         DBTzero( &data );
38         data.data = (char *) &id;
39         data.size = sizeof( id );
40
41         /* store it -- don't override */
42         rc = db->put( db, txn, &key, &data, DB_NOOVERWRITE );
43         if( rc != 0 ) {
44                 goto done;
45         }
46
47         {
48                 char *pdn = dn_parent( NULL, dn );
49                 ((char *)(key.data))[0] = DN_ONE_PREFIX;
50
51                 if( pdn != NULL ) {
52                         key.size = strlen( pdn ) + 2;
53                         AC_MEMCPY( &((char*)key.data)[1],
54                                 pdn, key.size - 1 );
55
56                         rc = bdb_idl_insert_key( be, db, txn, &key, id );
57                         free( pdn );
58
59                         if( rc != 0 ) {
60                                 goto done;
61                         }
62                 }
63         }
64
65         {
66                 char **subtree = dn_subtree( NULL, dn );
67
68                 if( subtree != NULL ) {
69                         int i;
70                         ((char *)key.data)[0] = DN_SUBTREE_PREFIX;
71                         for( i=0; subtree[i] != NULL; i++ ) {
72                                 key.size = strlen( subtree[i] ) + 2;
73                                 AC_MEMCPY( &((char *)key.data)[1],
74                                         subtree[i], key.size - 1 );
75
76                                 rc = bdb_idl_insert_key( be, db, txn, &key, id );
77
78                                 if( rc != 0 ) {
79                                         goto done;
80                                 }
81                         }
82
83                         charray_free( subtree );
84                 }
85         }
86
87 done:
88         ch_free( key.data );
89         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_add %d\n", rc, 0, 0 );
90         return rc;
91 }
92
93 int
94 bdb_dn2id_delete(
95     Backend     *be,
96         DB_TXN *txn,
97     const char  *dn,
98     ID          id )
99 {
100         int             rc;
101         DBT             key;
102         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
103         DB *db = bdb->bi_dn2id->bdi_db;
104
105         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete( \"%s\", %ld )\n", dn, id, 0 );
106
107         DBTzero( &key );
108         key.size = strlen( dn ) + 2;
109         key.data = ch_malloc( key.size );
110         ((char *)key.data)[0] = DN_BASE_PREFIX;
111         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
112
113         /* store it -- don't override */
114         rc = db->del( db, txn, &key, 0 );
115         if( rc != 0 ) {
116                 goto done;
117         }
118
119         {
120                 char *pdn = dn_parent( NULL, dn );
121                 ((char *)(key.data))[0] = DN_ONE_PREFIX;
122
123                 if( pdn != NULL ) {
124                         key.size = strlen( pdn ) + 2;
125                         AC_MEMCPY( &((char*)key.data)[1],
126                                 pdn, key.size - 1 );
127
128                         rc = bdb_idl_delete_key( be, db, txn, &key, id );
129                         free( pdn );
130
131                         if( rc != 0 ) {
132                                 goto done;
133                         }
134                 }
135         }
136
137         {
138                 char **subtree = dn_subtree( NULL, dn );
139
140                 if( subtree != NULL ) {
141                         int i;
142                         ((char *)key.data)[0] = DN_SUBTREE_PREFIX;
143                         for( i=0; subtree[i] != NULL; i++ ) {
144                                 key.size = strlen( subtree[i] ) + 2;
145                                 AC_MEMCPY( &((char *)key.data)[1],
146                                         subtree[i], key.size - 1 );
147
148                                 rc = bdb_idl_delete_key( be, db, txn, &key, id );
149
150                                 if( rc != 0 ) {
151                                         goto done;
152                                 }
153                         }
154
155                         charray_free( subtree );
156                 }
157         }
158
159 done:
160         ch_free( key.data );
161         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_delete %d\n", rc, 0, 0 );
162         return rc;
163 }
164
165 int
166 bdb_dn2id(
167     Backend     *be,
168         DB_TXN *txn,
169     const char  *dn,
170         ID *id )
171 {
172         int             rc;
173         DBT             key, data;
174         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
175         DB *db = bdb->bi_dn2id->bdi_db;
176
177         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id( \"%s\" )\n", dn, 0, 0 );
178
179         DBTzero( &key );
180         key.size = strlen( dn ) + 2;
181         key.data = ch_malloc( key.size );
182         ((char *)key.data)[0] = DN_BASE_PREFIX;
183         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
184
185         /* store the ID */
186         DBTzero( &data );
187         data.data = id;
188         data.ulen = sizeof(ID);
189         data.flags = DB_DBT_USERMEM;
190
191         /* fetch it */
192         rc = db->get( db, txn, &key, &data, 0 );
193
194         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id: id=%ld: %s (%d)\n",
195                 id, db_strerror( rc ), rc );
196
197         ch_free( key.data );
198         return rc;
199 }
200
201 int
202 bdb_dn2id_matched(
203     Backend     *be,
204         DB_TXN *txn,
205     const char  *in,
206         ID *id,
207         char **matchedDN )
208 {
209         int             rc;
210         DBT             key, data;
211         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
212         DB *db = bdb->bi_dn2id->bdi_db;
213         const char *dn = in;
214         char *tmp = NULL;
215
216         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_matched( \"%s\" )\n", dn, 0, 0 );
217
218         DBTzero( &key );
219         key.size = strlen( dn ) + 2;
220         key.data = ch_malloc( key.size );
221         ((char *)key.data)[0] = DN_BASE_PREFIX;
222
223         /* store the ID */
224         DBTzero( &data );
225         data.data = id;
226         data.ulen = sizeof(ID);
227         data.flags = DB_DBT_USERMEM;
228
229         *matchedDN = NULL;
230
231         while(1) {
232                 AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
233
234                 /* fetch it */
235                 rc = db->get( db, txn, &key, &data, 0 );
236
237                 if( rc == DB_NOTFOUND ) {
238                         char *pdn = dn_parent( be, dn );
239                         ch_free( tmp );
240                         tmp = NULL;
241
242                         if( pdn == NULL || *pdn == '\0' ) {
243                                 ch_free( pdn );
244                                 break;
245                         }
246
247                         dn = pdn;
248                         tmp = pdn;
249                         key.size = strlen( dn ) + 2;
250
251                 } else if ( rc == 0 ) {
252                         if( in != dn ) {
253                                 *matchedDN = (char *) dn;
254                         }
255                         Debug( LDAP_DEBUG_TRACE,
256                                 "<= bdb_dn2id_matched: id=%ld: %s\n",
257                                 id, dn, 0 );
258                         break;
259
260                 } else {
261                         ch_free( tmp );
262                         break;
263                 }
264         }
265
266         ch_free( key.data );
267         return rc;
268 }
269
270 int
271 bdb_dn2id_children(
272     Backend     *be,
273         DB_TXN *txn,
274     const char *dn )
275 {
276         int             rc;
277         DBT             key, data;
278         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
279         DB *db = bdb->bi_dn2id->bdi_db;
280         ID              id;
281
282         Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_children( %s )\n",
283                 dn, 0, 0 );
284
285         DBTzero( &key );
286         key.size = strlen( dn ) + 2;
287         key.data = ch_malloc( key.size );
288         ((char *)key.data)[0] = DN_ONE_PREFIX;
289         AC_MEMCPY( &((char *)key.data)[1], dn, key.size - 1 );
290
291         /* we actually could do a empty get... */
292         DBTzero( &data );
293         data.data = &id;
294         data.ulen = sizeof(id);
295         data.flags = DB_DBT_USERMEM;
296         data.doff = 0;
297         data.dlen = sizeof(id);
298
299         rc = db->get( db, txn, &key, &data, 0 );
300
301         Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %s (%d)\n",
302                 dn,
303                 rc == 0 ? "yes" : ( rc == DB_NOTFOUND ? "no" :
304                         db_strerror(rc) ), rc );
305
306         return rc;
307 }