dn2id.c 4.05 KB
Newer Older
Kurt Zeilenga's avatar
Kurt Zeilenga committed
1
2
/* dn2id.c - routines to deal with the dn2id index */

3
4
#include "portable.h"

Kurt Zeilenga's avatar
Kurt Zeilenga committed
5
#include <stdio.h>
6
7
8
9

#include <ac/string.h>
#include <ac/socket.h>

Kurt Zeilenga's avatar
Kurt Zeilenga committed
10
11
#include "slap.h"
#include "back-ldbm.h"
12
#include "proto-back-ldbm.h"
Kurt Zeilenga's avatar
Kurt Zeilenga committed
13
14
15
16
17
18
19
20

int
dn2id_add(
    Backend	*be,
    char	*dn,
    ID		id
)
{
21
	int		rc, flags;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
22
23
	struct dbcache	*db;
	Datum		key, data;
24
25
	struct ldbminfo *li = (struct ldbminfo *) be->be_private;

26
27
	ldbm_datum_init( key );
	ldbm_datum_init( data );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
28
29
30
31
32
33
34
35
36
37

	Debug( LDAP_DEBUG_TRACE, "=> dn2id_add( \"%s\", %ld )\n", dn, id, 0 );

	if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
	    == NULL ) {
		Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
		    LDBM_SUFFIX, 0, 0 );
		return( -1 );
	}

38
	dn = ch_strdup( dn );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
39
40
41
42
43
44
45
	dn_normalize_case( dn );

	key.dptr = dn;
	key.dsize = strlen( dn ) + 1;
	data.dptr = (char *) &id;
	data.dsize = sizeof(ID);

46
47
48
49
	flags = LDBM_INSERT;
	if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;

	rc = ldbm_cache_store( db, key, data, flags );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

	free( dn );
	ldbm_cache_close( be, db );

	Debug( LDAP_DEBUG_TRACE, "<= dn2id_add %d\n", rc, 0, 0 );
	return( rc );
}

ID
dn2id(
    Backend	*be,
    char	*dn
)
{
	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
	struct dbcache	*db;
	ID		id;
	Datum		key, data;

69
70
	ldbm_datum_init( key );
	ldbm_datum_init( data );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
71

72
	dn = ch_strdup( dn );
73
	Debug( LDAP_DEBUG_TRACE, "=> dn2id( \"%s\" )\n", dn, 0, 0 );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
74
75
76
	dn_normalize_case( dn );

	/* first check the cache */
77
	if ( (id = cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
78
		free( dn );
79
		Debug( LDAP_DEBUG_TRACE, "<= dn2id %lu (in cache)\n", id,
80
			0, 0 );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
81
82
83
84
		return( id );
	}

	if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
85
		== NULL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
86
87
		free( dn );
		Debug( LDAP_DEBUG_ANY, "<= dn2id could not open dn2id%s\n",
88
			LDBM_SUFFIX, 0, 0 );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
		return( NOID );
	}

	key.dptr = dn;
	key.dsize = strlen( dn ) + 1;

	data = ldbm_cache_fetch( db, key );

	ldbm_cache_close( be, db );
	free( dn );

	if ( data.dptr == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "<= dn2id NOID\n", 0, 0, 0 );
		return( NOID );
	}

	(void) memcpy( (char *) &id, data.dptr, sizeof(ID) );

	ldbm_datum_free( db->dbc_db, data );

109
	Debug( LDAP_DEBUG_TRACE, "<= dn2id %lu\n", id, 0, 0 );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
110
111
112
113
114
115
116
117
118
119
120
121
122
123
	return( id );
}

int
dn2id_delete(
    Backend	*be,
    char	*dn
)
{
	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
	struct dbcache	*db;
	Datum		key;
	int		rc;

124
	ldbm_datum_init( key );
125

Kurt Zeilenga's avatar
Kurt Zeilenga committed
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
	Debug( LDAP_DEBUG_TRACE, "=> dn2id_delete( \"%s\" )\n", dn, 0, 0 );

	if ( (db = ldbm_cache_open( be, "dn2id", LDBM_SUFFIX, LDBM_WRCREAT ))
	    == NULL ) {
		Debug( LDAP_DEBUG_ANY,
		    "<= dn2id_delete could not open dn2id%s\n", LDBM_SUFFIX,
		    0, 0 );
		return( -1 );
	}

	dn_normalize_case( dn );
	key.dptr = dn;
	key.dsize = strlen( dn ) + 1;

	rc = ldbm_cache_delete( db, key );

	ldbm_cache_close( be, db );

	Debug( LDAP_DEBUG_TRACE, "<= dn2id_delete %d\n", rc, 0, 0 );
	return( rc );
}

/*
 * dn2entry - look up dn in the cache/indexes and return the corresponding
 * entry.
 */

153
static Entry *
Kurt Zeilenga's avatar
Kurt Zeilenga committed
154
155
156
dn2entry(
    Backend	*be,
    char	*dn,
157
158
    char	**matched,
    int         rw
Kurt Zeilenga's avatar
Kurt Zeilenga committed
159
160
161
162
)
{
	struct ldbminfo *li = (struct ldbminfo *) be->be_private;
	ID		id;
163
	Entry		*e = NULL;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
164
165
	char		*pdn;

166
	Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
167
168
		rw ? "w" : "r", dn, 0);

169
170
	*matched = NULL;

171
172
173
	if ( (id = dn2id( be, dn )) != NOID &&
		(e = id2entry( be, id, rw )) != NULL )
	{
Kurt Zeilenga's avatar
Kurt Zeilenga committed
174
175
176
177
178
179
180
181
182
183
		return( e );
	}

	/* stop when we get to the suffix */
	if ( be_issuffix( be, dn ) ) {
		return( NULL );
	}

	/* entry does not exist - see how much of the dn does exist */
	if ( (pdn = dn_parent( be, dn )) != NULL ) {
184
185
		/* get entry with reader lock */
		if ( (e = dn2entry_r( be, pdn, matched )) != NULL ) {
Kurt Zeilenga's avatar
Kurt Zeilenga committed
186
187
188
			if(*matched != NULL) {
				free(*matched);
			}
Kurt Zeilenga's avatar
Kurt Zeilenga committed
189
			*matched = pdn;
190
191
			/* free entry with reader lock */
			cache_return_entry_r( &li->li_cache, e );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
192
193
194
195
196
197
198
		} else {
			free( pdn );
		}
	}

	return( NULL );
}
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

Entry *
dn2entry_r(
	Backend	*be,
	char	*dn,
	char	**matched
)
{
	return( dn2entry( be, dn, matched, 0 ) );
}

Entry *
dn2entry_w(
	Backend	*be,
	char	*dn,
	char	**matched
)
{
	return( dn2entry( be, dn, matched, 1 ) );
}