openldap/servers/slapd/back-bdb2/dn2id.c
Kurt Zeilenga 73276e84ae Import experimental referral implementation from OPENLDAP_DEVEL_REFERRALS.
Includes support for update referral for each replicated backend.
	Reworked replication test to use update referral.
Includes major rewrite of response encoding codes (result.c).
Includes reworked alias support and eliminates old suffix alias codes
(can be emulated using named alias).
Includes (untested) support for the Manage DSA IT control.
Works in LDAPv2 world.  Still testing in LDAPv3 world.
Added default referral (test009) test.
1999-07-16 02:45:46 +00:00

207 lines
4.1 KiB
C

/* dn2id.c - routines to deal with the dn2id index */
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include <ac/socket.h>
#include "slap.h"
#include "back-bdb2.h"
#include "proto-back-bdb2.h"
int
bdb2i_dn2id_add(
BackendDB *be,
char *dn,
ID id
)
{
int rc, flags;
struct dbcache *db;
Datum key, data;
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
ldbm_datum_init( key );
ldbm_datum_init( data );
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_add( \"%s\", %ld )\n", dn, id, 0 );
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
Debug( LDAP_DEBUG_ANY, "Could not open/create dn2id%s\n",
BDB2_SUFFIX, 0, 0 );
return( -1 );
}
dn = ch_strdup( dn );
dn_normalize_case( dn );
key.dptr = dn;
key.dsize = strlen( dn ) + 1;
data.dptr = (char *) &id;
data.dsize = sizeof(ID);
flags = LDBM_INSERT;
if ( li->li_dbcachewsync ) flags |= LDBM_SYNC;
rc = bdb2i_cache_store( db, key, data, flags );
free( dn );
bdb2i_cache_close( be, db );
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_add %d\n", rc, 0, 0 );
return( rc );
}
ID
bdb2i_dn2id(
BackendDB *be,
char *dn
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
struct dbcache *db;
ID id;
Datum key, data;
ldbm_datum_init( key );
ldbm_datum_init( data );
dn = ch_strdup( dn );
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id( \"%s\" )\n", dn, 0, 0 );
dn_normalize_case( dn );
/* first check the cache */
if ( (id = bdb2i_cache_find_entry_dn2id( be, &li->li_cache, dn )) != NOID ) {
free( dn );
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld (in cache)\n", id,
0, 0 );
return( id );
}
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
free( dn );
Debug( LDAP_DEBUG_ANY, "<= bdb2i_dn2id could not open dn2id%s\n",
BDB2_SUFFIX, 0, 0 );
return( NOID );
}
key.dptr = dn;
key.dsize = strlen( dn ) + 1;
data = bdb2i_cache_fetch( db, key );
bdb2i_cache_close( be, db );
free( dn );
if ( data.dptr == NULL ) {
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id NOID\n", 0, 0, 0 );
return( NOID );
}
(void) memcpy( (char *) &id, data.dptr, sizeof(ID) );
ldbm_datum_free( db->dbc_db, data );
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id %ld\n", id, 0, 0 );
return( id );
}
int
bdb2i_dn2id_delete(
BackendDB *be,
char *dn
)
{
struct dbcache *db;
Datum key;
int rc;
ldbm_datum_init( key );
Debug( LDAP_DEBUG_TRACE, "=> bdb2i_dn2id_delete( \"%s\" )\n", dn, 0, 0 );
if ( (db = bdb2i_cache_open( be, "dn2id", BDB2_SUFFIX, LDBM_WRCREAT ))
== NULL ) {
Debug( LDAP_DEBUG_ANY,
"<= bdb2i_dn2id_delete could not open dn2id%s\n", BDB2_SUFFIX,
0, 0 );
return( -1 );
}
dn = ch_strdup( dn );
dn_normalize_case( dn );
key.dptr = dn;
key.dsize = strlen( dn ) + 1;
rc = bdb2i_cache_delete( db, key );
free( dn );
bdb2i_cache_close( be, db );
Debug( LDAP_DEBUG_TRACE, "<= bdb2i_dn2id_delete %d\n", rc, 0, 0 );
return( rc );
}
/*
* dn2entry - look up dn in the cache/indexes and return the corresponding
* entry.
*/
Entry *
bdb2i_dn2entry_rw(
BackendDB *be,
char *dn,
Entry **matched,
int rw
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
ID id;
Entry *e = NULL;
char *pdn;
Debug(LDAP_DEBUG_TRACE, "dn2entry_%s: dn: \"%s\"\n",
rw ? "w" : "r", dn, 0);
if( matched != NULL ) {
/* caller cares about match */
*matched = NULL;
}
if ( (id = bdb2i_dn2id( be, dn )) != NOID &&
(e = bdb2i_id2entry_rw( be, id, rw )) != NULL )
{
return( e );
}
if ( id != NOID ) {
Debug(LDAP_DEBUG_ANY,
"dn2entry_%s: no entry for valid id (%ld), dn \"%s\"\n",
rw ? "w" : "r", id, dn);
/* must have been deleted from underneath us */
/* treat as if NOID was found */
}
/* caller doesn't care about match */
if( matched == NULL ) return NULL;
/* entry does not exist - see how much of the dn does exist */
/* dn_parent checks returns NULL if dn is suffix */
if ( (pdn = dn_parent( be, dn )) != NULL ) {
/* get entry with reader lock */
if ( (e = bdb2i_dn2entry_r( be, pdn, matched )) != NULL ) {
*matched = e;
}
free( pdn );
}
return( NULL );
}