add support for entryUUID and entryCSN operational attributes (entryUUID is honored in filters as well)

This commit is contained in:
Pierangelo Masarati 2004-10-04 01:19:53 +00:00
parent e739f5a09a
commit e10186f1a5
8 changed files with 447 additions and 32 deletions

View File

@ -265,6 +265,7 @@ typedef struct backsql_srch_info {
int bsi_flags;
#define BSQL_SF_ALL_OPER 0x0001
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002
#define BSQL_SF_FILTER_ENTRYUUID 0x0004
struct berval *bsi_base_ndn;
backsql_entryID bsi_base_id;

View File

@ -62,7 +62,7 @@ backsql_bind( Operation *op, SlapReply *rs )
* method = LDAP_AUTH_SIMPLE
*/
rs->sr_err = backsql_get_db_conn( op, &dbh );
if (!dbh) {
if ( !dbh ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not get connection handle - exiting\n",
0, 0, 0 );

View File

@ -27,11 +27,72 @@
#include "slap.h"
#include "proto-sql.h"
#include "lutil.h"
/*
* sets the supported operational attributes (if required)
*/
Attribute *
backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
{
int rc;
struct berval val, nval;
AttributeDescription *desc = slap_schema.si_ad_entryUUID;
Attribute *a;
backsql_entryUUID( bi, id, &val, NULL );
rc = (*desc->ad_type->sat_equality->smr_normalize)(
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
desc->ad_type->sat_syntax,
desc->ad_type->sat_equality,
&val, &nval, NULL );
if ( rc != LDAP_SUCCESS ) {
ber_memfree( val.bv_val );
return NULL;
}
a = ch_malloc( sizeof( Attribute ) );
a->a_desc = desc;
a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
a->a_vals[ 0 ] = val;
BER_BVZERO( &a->a_vals[ 1 ] );
a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
a->a_nvals[ 0 ] = nval;
BER_BVZERO( &a->a_nvals[ 1 ] );
a->a_next = NULL;
a->a_flags = 0;
return a;
}
Attribute *
backsql_operational_entryCSN( Operation *op )
{
char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
struct berval entryCSN;
Attribute *a;
a = ch_malloc( sizeof( Attribute ) );
a->a_desc = slap_schema.si_ad_entryCSN;
a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
BER_BVZERO( &a->a_vals[ 1 ] );
slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
a->a_nvals = a->a_vals;
a->a_next = NULL;
a->a_flags = 0;
return a;
}
int
backsql_operational(
Operation *op,
@ -42,24 +103,50 @@ backsql_operational(
SQLHDBC dbh = SQL_NULL_HDBC;
int rc = 0;
Attribute **ap;
enum {
BACKSQL_OP_HASSUBORDINATES = 0,
BACKSQL_OP_ENTRYUUID,
BACKSQL_OP_ENTRYCSN,
BACKSQL_OP_LAST
};
int get_conn = BACKSQL_OP_LAST,
got[ BACKSQL_OP_LAST ] = { 0 };
Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n",
rs->sr_entry->e_nname.bv_val, 0, 0 );
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next )
/* just count */ ;
for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
get_conn--;
got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
} else if ( (*ap)->a_desc == slap_schema.si_ad_entryUUID ) {
get_conn--;
got[ BACKSQL_OP_ENTRYUUID ] = 1;
} else if ( (*ap)->a_desc == slap_schema.si_ad_entryCSN ) {
get_conn--;
got[ BACKSQL_OP_ENTRYCSN ] = 1;
}
}
if ( !get_conn ) {
return 0;
}
rc = backsql_get_db_conn( op, &dbh );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"could not get connection handle - exiting\n",
0, 0, 0 );
return 1;
}
if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) {
rc = backsql_get_db_conn( op, &dbh );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"could not get connection handle - exiting\n",
0, 0, 0 );
return 1;
}
&& !got[ BACKSQL_OP_HASSUBORDINATES ]
&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL )
{
rc = backsql_has_children( bi, dbh, &rs->sr_entry->e_nname );
switch( rc ) {
@ -74,12 +161,68 @@ backsql_operational(
default:
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"has_children failed( %d)\n", rc, 0, 0 );
rc = 1;
break;
return 1;
}
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_operational()\n", 0, 0, 0);
if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) )
&& !got[ BACKSQL_OP_ENTRYUUID ]
&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL )
{
struct berval ndn;
backsql_srch_info bsi;
ndn = rs->sr_entry->e_nname;
if ( backsql_api_dn2odbc( op, rs, &ndn ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"backsql_api_dn2odbc failed\n",
0, 0, 0 );
return 1;
}
rc = backsql_init_search( &bsi, &ndn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, NULL, 1 );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"could not retrieve entry ID - no such entry\n",
0, 0, 0 );
return 1;
}
*ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
if ( ndn.bv_val != rs->sr_entry->e_nname.bv_val ) {
free( ndn.bv_val );
}
if ( *ap == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"could not retrieve entryUUID\n",
0, 0, 0 );
return 1;
}
ap = &(*ap)->a_next;
}
if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryCSN, rs->sr_attrs ) )
&& !got[ BACKSQL_OP_ENTRYCSN ]
&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN ) == NULL )
{
*ap = backsql_operational_entryCSN( op );
if ( *ap == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"could not retrieve entryCSN\n",
0, 0, 0 );
return 1;
}
ap = &(*ap)->a_next;
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0);
return rc;
}

View File

@ -127,6 +127,14 @@ backsql_entryID *backsql_free_entryID( backsql_entryID *id, int freeit );
/* turns an ID into an entry */
int backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *id );
/*
* operational.c
*/
Attribute *backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id );
Attribute *backsql_operational_entryCSN( Operation *op );
/*
* schema-map.c
*/
@ -238,4 +246,14 @@ int backsql_split_pattern( const char *pattern, BerVarray *split_pattern,
int backsql_prepare_pattern( BerVarray split_pattern, BerVarray values,
struct berval *res );
int backsql_entryUUID( backsql_info *bi, backsql_entryID *id,
struct berval *entryUUID, void *memctx );
int backsql_entryUUID_decode( struct berval *entryUUID, unsigned long *oc_id,
#ifdef BACKSQL_ARBITRARY_KEY
struct berval *keyval
#else /* ! BACKSQL_ARBITRARY_KEY */
unsigned long *keyval
#endif /* ! BACKSQL_ARBITRARY_KEY */
);
#endif /* PROTO_SQL_H */

View File

@ -558,7 +558,8 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
* Turn structuralObjectClass into objectClass
*/
if ( ad == slap_schema.si_ad_objectClass
|| ad == slap_schema.si_ad_structuralObjectClass ) {
|| ad == slap_schema.si_ad_structuralObjectClass )
{
/*
* If the filter is LDAP_FILTER_PRESENT, then it's done;
* otherwise, let's see if we are lucky: filtering
@ -625,6 +626,53 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
goto done;
}
} else if ( ad == slap_schema.si_ad_entryUUID ) {
unsigned long oc_id;
#ifdef BACKSQL_ARBITRARY_KEY
struct berval keyval;
#else /* ! BACKSQL_ARBITRARY_KEY */
unsigned long keyval;
char keyvalbuf[] = "18446744073709551615";
#endif /* ! BACKSQL_ARBITRARY_KEY */
switch ( f->f_choice ) {
case LDAP_FILTER_EQUALITY:
backsql_entryUUID_decode( &f->f_av_value, &oc_id, &keyval );
if ( oc_id != bsi->bsi_oc->bom_id ) {
bsi->bsi_status = LDAP_SUCCESS;
rc = -1;
goto done;
}
#ifdef BACKSQL_ARBITRARY_KEY
backsql_strfcat( &bsi->bsi_flt_where, "bcblbc",
&bsi->bsi_oc->bom_keytbl, '.',
&bsi->bsi_oc->bom_keycol,
STRLENOF( " LIKE '" ), " LIKE '",
&keyval, '\'' );
#else /* ! BACKSQL_ARBITRARY_KEY */
snprintf( keyvalbuf, sizeof( keyvalbuf ), "%lu", keyval );
backsql_strfcat( &bsi->bsi_flt_where, "bcbcs",
&bsi->bsi_oc->bom_keytbl, '.',
&bsi->bsi_oc->bom_keycol, '=', keyvalbuf );
#endif /* ! BACKSQL_ARBITRARY_KEY */
break;
case LDAP_FILTER_PRESENT:
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
break;
default:
rc = -1;
goto done;
}
bsi->bsi_flags |= BSQL_SF_FILTER_ENTRYUUID;
rc = 1;
goto done;
} else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
/*
* FIXME: this is not robust; e.g. a filter
@ -1635,7 +1683,8 @@ backsql_search( Operation *op, SlapReply *rs )
eid = backsql_free_entryID( eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
{
int rc;
Attribute *hasSubordinate = NULL,
Attribute *a_hasSubordinate = NULL,
*a_entryUUID = NULL,
*a = NULL;
Entry *e = NULL;
@ -1786,13 +1835,13 @@ backsql_search( Operation *op, SlapReply *rs )
switch ( rc ) {
case LDAP_COMPARE_TRUE:
case LDAP_COMPARE_FALSE:
hasSubordinate = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
if ( hasSubordinate != NULL ) {
a_hasSubordinate = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
if ( a_hasSubordinate != NULL ) {
for ( a = user_entry.e_attrs;
a && a->a_next;
a = a->a_next );
a->a_next = hasSubordinate;
a->a_next = a_hasSubordinate;
}
rc = 0;
break;
@ -1807,14 +1856,36 @@ backsql_search( Operation *op, SlapReply *rs )
}
}
if ( test_filter( op, e, op->ors_filter )
== LDAP_COMPARE_TRUE ) {
if ( hasSubordinate && !( bsi.bsi_flags & BSQL_SF_ALL_OPER )
&& !ad_inlist( slap_schema.si_ad_hasSubordinates, op->ors_attrs ) ) {
a->a_next = NULL;
attr_free( hasSubordinate );
hasSubordinate = NULL;
if ( bsi.bsi_flags & BSQL_SF_FILTER_ENTRYUUID ) {
a_entryUUID = backsql_operational_entryUUID( bi, eid );
if ( a_entryUUID != NULL ) {
for ( a = user_entry.e_attrs;
a && a->a_next;
a = a->a_next );
a->a_next = a_entryUUID;
}
}
if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
{
#if 0
if ( a_hasSubordinate && !( bsi.bsi_flags & BSQL_SF_ALL_OPER )
&& !ad_inlist( slap_schema.si_ad_hasSubordinates, op->ors_attrs ) )
{
a->a_next = NULL;
attr_free( a_hasSubordinate );
a_hasSubordinate = NULL;
}
if ( a_entryUUID && !( bsi.bsi_flags & BSQL_SF_ALL_OPER )
&& !ad_inlist( slap_schema.si_ad_entryUUID, op->ors_attrs ) )
{
a->a_next = NULL;
attr_free( a_hasSubordinate );
a_hasSubordinate = NULL;
}
#endif
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;

View File

@ -30,6 +30,7 @@
#include "slap.h"
#include "proto-sql.h"
#include "lutil.h"
#define BACKSQL_MAX(a,b) ((a)>(b)?(a):(b))
#define BACKSQL_MIN(a,b) ((a)<(b)?(a):(b))
@ -489,5 +490,93 @@ backsql_prepare_pattern(
return 0;
}
int
backsql_entryUUID(
backsql_info *bi,
backsql_entryID *id,
struct berval *entryUUID,
void *memctx )
{
char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ];
struct berval uuid;
#ifdef BACKSQL_ARBITRARY_KEY
int i;
ber_len_t l, lmax;
#endif /* BACKSQL_ARBITRARY_KEY */
/* entryUUID is generated as "%08x-%04x-%04x-0000-eaddrXXX"
* with eid_oc_id as %08x and hi and lo eid_id as %04x-%04x */
assert( bi );
assert( id );
assert( entryUUID );
#ifdef BACKSQL_ARBITRARY_KEY
snprintf( uuidbuf, sizeof( uuidbuf ),
"%08x-0000-0000-0000-000000000000",
( id->eid_oc_id & 0xFFFFFFFF ) );
lmax = id->eid_keyval.bv_len < 12 ? id->eid_keyval.bv_len : 12;
for ( l = 0, i = 9; l < lmax; l++, i += 2 ) {
switch ( i ) {
case STRLENOF( "00000000-0000" ):
case STRLENOF( "00000000-0000-0000" ):
case STRLENOF( "00000000-0000-0000-0000" ):
uuidbuf[ i++ ] = '-';
/* FALLTHRU */
default:
snprintf( &uuidbuf[ i ], 3, "%2x", id->eid_keyval.bv_val[ l ] );
break;
}
}
#else /* ! BACKSQL_ARBITRARY_KEY */
/* note: works only with 32 bit architectures... */
snprintf( uuidbuf, sizeof( uuidbuf ),
"%08x-%04x-%04x-0000-000000000000",
( id->eid_oc_id & 0xFFFFFFFF ),
( ( id->eid_keyval & 0xFFFF0000 ) >> 16 ),
( id->eid_keyval & 0xFFFF ) );
#endif /* ! BACKSQL_ARBITRARY_KEY */
uuid.bv_val = uuidbuf;
uuid.bv_len = strlen( uuidbuf );
ber_dupbv_x( entryUUID, &uuid, memctx );
return 0;
}
int
backsql_entryUUID_decode(
struct berval *entryUUID,
unsigned long *oc_id,
#ifdef BACKSQL_ARBITRARY_KEY
struct berval *keyval
#else /* ! BACKSQL_ARBITRARY_KEY */
unsigned long *keyval
#endif /* ! BACKSQL_ARBITRARY_KEY */
)
{
fprintf( stderr, "==> backsql_entryUUID_decode()\n" );
*oc_id = ( entryUUID->bv_val[0] << 3 )
+ ( entryUUID->bv_val[1] << 2 )
+ ( entryUUID->bv_val[2] << 1 )
+ entryUUID->bv_val[3];
#ifdef BACKSQL_ARBITRARY_KEY
#else /* ! BACKSQL_ARBITRARY_KEY */
*keyval = ( entryUUID->bv_val[4] << 3 )
+ ( entryUUID->bv_val[5] << 2 )
+ ( entryUUID->bv_val[6] << 1 )
+ entryUUID->bv_val[7];
#endif /* ! BACKSQL_ARBITRARY_KEY */
fprintf( stderr, "<== backsql_entryUUID_decode(): oc=%lu id=%lu\n",
*oc_id, *keyval );
return LDAP_SUCCESS;
}
#endif /* SLAPD_SQL */

View File

@ -1,4 +1,47 @@
# Testing search...
# Testing baseobject search...
dn: dc=example,dc=com
objectClass: organization
objectClass: dcObject
o: Example
dc: example
# Testing onelevel search...
dn: documentTitle=book1,dc=example,dc=com
objectClass: document
description: abstract1
documentTitle: book1
documentAuthor: cn=Mitya Kovalev,dc=example,dc=com
documentAuthor: cn=Torvlobnor Puzdoy,dc=example,dc=com
documentIdentifier: document 1
dn: documentTitle=book2,dc=example,dc=com
objectClass: document
description: abstract2
documentTitle: book2
documentAuthor: cn=Mitya Kovalev,dc=example,dc=com
documentIdentifier: document 2
dn: cn=Mitya Kovalev,dc=example,dc=com
objectClass: inetOrgPerson
cn: Mitya Kovalev
sn: Kovalev
seeAlso: documentTitle=book1,dc=example,dc=com
seeAlso: documentTitle=book2,dc=example,dc=com
givenName: Mitya
telephoneNumber: 222-3234
telephoneNumber: 332-2334
dn: cn=Torvlobnor Puzdoy,dc=example,dc=com
objectClass: inetOrgPerson
cn: Torvlobnor Puzdoy
sn: Puzdoy
seeAlso: documentTitle=book1,dc=example,dc=com
givenName: Torvlobnor
telephoneNumber: 545-4563
# refldap://localhost/dc=example,dc=com??one
# Testing subtree search...
dn: documentTitle=book1,dc=example,dc=com
objectClass: document
description: abstract1
@ -282,6 +325,17 @@ dc: example
# refldap://localhost/dc=example,dc=com??sub
# Testing entryUUID in filter...
dn: cn=Mitya Kovalev,dc=example,dc=com
objectClass: inetOrgPerson
cn: Mitya Kovalev
sn: Kovalev
seeAlso: documentTitle=book1,dc=example,dc=com
seeAlso: documentTitle=book2,dc=example,dc=com
givenName: Mitya
telephoneNumber: 222-3234
telephoneNumber: 332-2334
# Testing attribute inheritance in requested attributes...
dn: cn=Mitya Kovalev,dc=example,dc=com
cn: Mitya Kovalev
@ -313,30 +367,35 @@ structuralObjectClass: document
entryDN: documentTitle=book1,dc=example,dc=com
subschemaSubentry: cn=Subschema
hasSubordinates: FALSE
entryUUID: 00000002-0000-0001-0000-000000000000
dn: documentTitle=book2,dc=example,dc=com
structuralObjectClass: document
entryDN: documentTitle=book2,dc=example,dc=com
subschemaSubentry: cn=Subschema
hasSubordinates: FALSE
entryUUID: 00000002-0000-0002-0000-000000000000
dn: dc=example,dc=com
structuralObjectClass: organization
entryDN: dc=example,dc=com
subschemaSubentry: cn=Subschema
hasSubordinates: TRUE
entryUUID: 00000003-0000-0001-0000-000000000000
dn: cn=Mitya Kovalev,dc=example,dc=com
structuralObjectClass: inetOrgPerson
entryDN: cn=Mitya Kovalev,dc=example,dc=com
subschemaSubentry: cn=Subschema
hasSubordinates: FALSE
entryUUID: 00000001-0000-0001-0000-000000000000
dn: cn=Torvlobnor Puzdoy,dc=example,dc=com
structuralObjectClass: inetOrgPerson
entryDN: cn=Torvlobnor Puzdoy,dc=example,dc=com
subschemaSubentry: cn=Subschema
hasSubordinates: FALSE
entryUUID: 00000001-0000-0002-0000-000000000000
# refldap://localhost/dc=example,dc=com??sub

View File

@ -77,8 +77,30 @@ if test $RC == 0 ; then
exit $RC
fi
echo "Testing search..."
echo "# Testing search..." > $SEARCHOUT
echo "Testing baseobject search..."
echo "# Testing baseobject search..." >> $SEARCHOUT
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -s base >> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "ldapsearch failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
echo "Testing onelevel search..."
echo "# Testing onelevel search..." >> $SEARCHOUT
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -s one >> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "ldapsearch failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
echo "Testing subtree search..."
echo "# Testing subtree search..." >> $SEARCHOUT
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" >> $SEARCHOUT 2>&1
RC=$?
@ -329,6 +351,18 @@ if test $RC != 0 ; then
exit $RC
fi
echo "Testing entryUUID in filter..."
echo "# Testing entryUUID in filter..." >> $SEARCHOUT
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" \
"(entryUUID=00000001-0000-0001-0000-000000000000)" >> $SEARCHOUT 2>&1
RC=$?
if test $RC != 0 ; then
echo "ldapsearch failed ($RC)!"
test $KILLSERVERS != no && kill -HUP $KILLPIDS
exit $RC
fi
echo "Testing attribute inheritance in requested attributes..."
echo "# Testing attribute inheritance in requested attributes..." >> $SEARCHOUT
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" \
@ -356,7 +390,7 @@ fi
echo "Testing operational attributes in request..."
echo "# Testing operational attributes in request..." >> $SEARCHOUT
$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" \
'+' >> $SEARCHOUT 2>&1
'+' 2>&1 | grep -v '^entryCSN:' >> $SEARCHOUT
RC=$?
if test $RC != 0 ; then