mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-25 00:59:45 -05:00
- added the capability to filter based on hasSubordinate attribute
to back-bdb, back-ldbm and back-sql (the latter with limitations); - added handling of ":dn" attributes to extended rfc2254 filters and to matched value filter - altered the behavior of get_mra() when a matching rule is given: now it checks whether it is compatible with the attribute syntax and, in case it is, the given mr is used. In case of no type, the check is delayed when filtering
This commit is contained in:
parent
f4c5362955
commit
fbc11bd16a
20 changed files with 831 additions and 149 deletions
|
|
@ -59,6 +59,10 @@ bdb_search(
|
|||
struct slap_limits_set *limit = NULL;
|
||||
int isroot = 0;
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
int filter_hasSubordinates = 0;
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
u_int32_t locker;
|
||||
DB_LOCK lock;
|
||||
|
||||
|
|
@ -322,11 +326,22 @@ dn2entry_retry:
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
/*
|
||||
* is hasSubordinates used in the filter ?
|
||||
* FIXME: we may compute this directly when parsing the filter
|
||||
*/
|
||||
filter_hasSubordinates = filter_has_subordinates( filter );
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
for ( id = bdb_idl_first( candidates, &cursor );
|
||||
id != NOID;
|
||||
id = bdb_idl_next( candidates, &cursor ) )
|
||||
{
|
||||
int scopeok = 0;
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
Attribute *hasSubordinates = NULL;
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
/* check for abandon */
|
||||
if ( op->o_abandon ) {
|
||||
|
|
@ -490,8 +505,47 @@ id2entry_retry:
|
|||
goto loop_continue;
|
||||
}
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
/*
|
||||
* if hasSubordinates is used in the filter,
|
||||
* append it to the entry's attributes
|
||||
*/
|
||||
if ( filter_hasSubordinates ) {
|
||||
int hs;
|
||||
|
||||
rc = bdb_hasSubordinates( be, conn, op, e, &hs);
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
hasSubordinates = slap_operational_hasSubordinate( hs == LDAP_COMPARE_TRUE );
|
||||
if ( hasSubordinates == NULL ) {
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
hasSubordinates->a_next = e->e_attrs;
|
||||
e->e_attrs = hasSubordinates;
|
||||
}
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
/* if it matches the filter and scope, send it */
|
||||
rc = test_filter( be, conn, op, e, filter );
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
if ( hasSubordinates ) {
|
||||
/*
|
||||
* FIXME: this is fairly inefficient, because
|
||||
* if hasSubordinates is among the required
|
||||
* attrs, it will be added again later;
|
||||
* maybe we should leave it and check
|
||||
* check later if it's already present,
|
||||
* if required
|
||||
*/
|
||||
e->e_attrs = e->e_attrs->a_next;
|
||||
attr_free( hasSubordinates );
|
||||
}
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
if ( rc == LDAP_COMPARE_TRUE ) {
|
||||
struct berval dn;
|
||||
|
||||
|
|
@ -557,8 +611,8 @@ id2entry_retry:
|
|||
}
|
||||
} else {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: %ld does match filter\n", (long) id, 0, 0);
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
"bdb_search: %ld does match filter\n", (long) id, 0, 0);
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_search: %ld does match filter\n",
|
||||
|
|
@ -774,3 +828,4 @@ static int search_candidates(
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ ldbm_back_search(
|
|||
struct slap_limits_set *limit = NULL;
|
||||
int isroot = 0;
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
int filter_hasSubordinates = 0;
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_search: enter\n", 0, 0, 0 );
|
||||
#else
|
||||
|
|
@ -288,10 +292,22 @@ searchit:
|
|||
/* compute it anyway; root does not use it */
|
||||
stoptime = op->o_time + tlimit;
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
/*
|
||||
* is hasSubordinates used in the filter ?
|
||||
* FIXME: we may compute this directly when parsing the filter
|
||||
*/
|
||||
filter_hasSubordinates = filter_has_subordinates( filter );
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
for ( id = idl_firstid( candidates, &cursor ); id != NOID;
|
||||
id = idl_nextid( candidates, &cursor ) )
|
||||
{
|
||||
int scopeok = 0;
|
||||
int result = 0;
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
Attribute *hasSubordinates = NULL;
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
/* check for abandon */
|
||||
if ( op->o_abandon ) {
|
||||
|
|
@ -420,8 +436,44 @@ searchit:
|
|||
goto loop_continue;
|
||||
}
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
/*
|
||||
* if hasSubordinates is used in the filter,
|
||||
* append it to the entry's attributes
|
||||
*/
|
||||
if ( filter_hasSubordinates ) {
|
||||
int hs;
|
||||
|
||||
hs = has_children( be, e );
|
||||
hasSubordinates = slap_operational_hasSubordinate( hs );
|
||||
if ( hasSubordinates == NULL ) {
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
hasSubordinates->a_next = e->e_attrs;
|
||||
e->e_attrs = hasSubordinates;
|
||||
}
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
/* if it matches the filter and scope, send it */
|
||||
if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
|
||||
result = test_filter( be, conn, op, e, filter );
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
if ( hasSubordinates ) {
|
||||
/*
|
||||
* FIXME: this is fairly inefficient, because
|
||||
* if hasSubordinates is among the required
|
||||
* attrs, it will be added again later;
|
||||
* maybe we should leave it and check
|
||||
* check later if it's already present,
|
||||
* if required
|
||||
*/
|
||||
e->e_attrs = e->e_attrs->a_next;
|
||||
attr_free( hasSubordinates );
|
||||
}
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
if ( result == LDAP_COMPARE_TRUE ) {
|
||||
struct berval dn;
|
||||
|
||||
/* check scope */
|
||||
|
|
@ -452,7 +504,7 @@ searchit:
|
|||
}
|
||||
|
||||
if (e) {
|
||||
int result = send_search_entry(be, conn, op,
|
||||
result = send_search_entry(be, conn, op,
|
||||
e, attrs, attrsonly, NULL);
|
||||
|
||||
switch (result) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,10 @@
|
|||
* statements (needed by PostgreSQL)
|
||||
* - upper_needs_cast cast the argument of upper when required
|
||||
* (basically when building dn substring queries)
|
||||
* - added noop control
|
||||
* - added values return filter control
|
||||
* - hasSubordinate can be used in search filters (with limitations)
|
||||
* - eliminated oc->name; use oc->oc->soc_cname instead
|
||||
*
|
||||
* Todo:
|
||||
* - add security checks for SQL statements that can be injected (?)
|
||||
|
|
@ -80,7 +84,6 @@
|
|||
*/
|
||||
#undef BACKSQL_TRACE
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *dbhost;
|
||||
int dbport;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "ac/string.h"
|
||||
#include "lber_pvt.h"
|
||||
#include "ldap_pvt.h"
|
||||
#include "slap.h"
|
||||
#include "back-sql.h"
|
||||
|
|
@ -255,8 +256,7 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
|
|||
|
||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
|
||||
"oc='%s' attr='%s' keyval=%ld\n",
|
||||
// bsi->oc->name.bv_val, at->name.bv_val,
|
||||
bsi->oc->oc->soc_names[0], at->ad->ad_cname.bv_val,
|
||||
BACKSQL_OC_NAME( bsi->oc ), at->ad->ad_cname.bv_val,
|
||||
bsi->c_eid->keyval );
|
||||
|
||||
rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
|
||||
|
|
@ -363,7 +363,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
|||
#if 0
|
||||
backsql_entry_addattr( bsi->e,
|
||||
&bv_n_objectclass,
|
||||
&bsi->oc->name );
|
||||
BACKSQL_OC_NAME( bsi->oc ) );
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
|
@ -376,7 +376,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
|||
"attribute '%s' is not defined "
|
||||
"for objectlass '%s'\n",
|
||||
attr->an_name.bv_val,
|
||||
bsi->oc->name.bv_val, 0 );
|
||||
BACKSQL_OC_NAME( bsi->oc ), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +387,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
|||
bsi, 0, AVL_INORDER );
|
||||
}
|
||||
|
||||
if ( attr_merge_one( bsi->e, ad_oc, &bsi->oc->name ) ) {
|
||||
if ( attr_merge_one( bsi->e, ad_oc, &bsi->oc->oc->soc_cname ) ) {
|
||||
entry_free( e );
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -396,7 +396,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
|||
const char *text = NULL;
|
||||
char textbuf[ 1024 ];
|
||||
size_t textlen = sizeof( textbuf );
|
||||
struct berval bv[ 2 ] = { bsi->oc->name, { 0, NULL } };
|
||||
struct berval bv[ 2 ] = { bsi->oc->oc->soc_cname, BER_BVNULL };
|
||||
struct berval soc;
|
||||
AttributeDescription *ad_soc
|
||||
= slap_schema.si_ad_structuralObjectClass;
|
||||
|
|
@ -408,7 +408,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if ( bsi->attr_flags | BSQL_SF_ALL_OPER
|
||||
if ( bsi->bsi_flags | BSQL_SF_ALL_OPER
|
||||
|| an_find( bsi->attrs, &AllOper ) ) {
|
||||
if ( attr_merge_one( bsi->e, ad_soc, &soc ) ) {
|
||||
entry_free( e );
|
||||
|
|
|
|||
|
|
@ -43,6 +43,18 @@ int
|
|||
sql_back_initialize(
|
||||
BackendInfo *bi )
|
||||
{
|
||||
static char *controls[] = {
|
||||
#ifdef LDAP_CONTROL_NOOP
|
||||
LDAP_CONTROL_NOOP,
|
||||
#endif
|
||||
#ifdef LDAP_CONTROL_VALUESRETURNFILTER
|
||||
LDAP_CONTROL_VALUESRETURNFILTER,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
bi->bi_controls = controls;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,"==>backsql_initialize()\n", 0, 0, 0 );
|
||||
|
||||
bi->bi_open = 0;
|
||||
|
|
|
|||
|
|
@ -549,9 +549,10 @@ backsql_modify(
|
|||
* or if a single operation on an attribute fails
|
||||
* for any reason
|
||||
*/
|
||||
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
||||
SQLTransact( SQL_NULL_HENV, dbh,
|
||||
op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
|
||||
}
|
||||
send_ldap_result( conn, op, res, "", text, NULL, NULL );
|
||||
send_ldap_result( conn, op, res, NULL, text, NULL, NULL );
|
||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
|
||||
|
||||
return 0;
|
||||
|
|
@ -865,7 +866,8 @@ backsql_modrdn(
|
|||
* or if a single operation on an attribute fails for any
|
||||
* reason
|
||||
*/
|
||||
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
||||
SQLTransact( SQL_NULL_HENV, dbh,
|
||||
op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
|
||||
}
|
||||
|
||||
modrdn_return:
|
||||
|
|
@ -1239,7 +1241,7 @@ backsql_add(
|
|||
"attribute '%s' is not registered "
|
||||
"in objectclass '%s'\n",
|
||||
at->a_desc->ad_cname.bv_val,
|
||||
oc->name.bv_val, 0 );
|
||||
BACKSQL_OC_NAME( oc ), 0 );
|
||||
|
||||
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||
send_ldap_result( conn, op,
|
||||
|
|
@ -1312,7 +1314,7 @@ backsql_add(
|
|||
* to build the entry
|
||||
*/
|
||||
if ( at->a_desc == slap_schema.si_ad_objectClass ) {
|
||||
if ( ber_bvcmp( at_val, &oc->name ) == 0 ) {
|
||||
if ( bvmatch( at_val, &oc->oc->soc_cname ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -1411,7 +1413,8 @@ backsql_add(
|
|||
* or if a single operation on an attribute fails
|
||||
* for any reason
|
||||
*/
|
||||
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
||||
SQLTransact( SQL_NULL_HENV, dbh,
|
||||
op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
|
||||
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS, "",
|
||||
NULL, NULL, NULL );
|
||||
|
|
@ -1570,7 +1573,8 @@ backsql_delete(
|
|||
* or if a single operation on an attribute fails
|
||||
* for any reason
|
||||
*/
|
||||
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
||||
SQLTransact( SQL_NULL_HENV, dbh,
|
||||
op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
|
||||
|
||||
send_ldap_result( conn, op, LDAP_SUCCESS, "", NULL, NULL, NULL );
|
||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );
|
||||
|
|
|
|||
|
|
@ -63,13 +63,18 @@ backsql_operational(
|
|||
backsql_info *bi = (backsql_info*)be->be_private;
|
||||
SQLHDBC dbh = SQL_NULL_HDBC;
|
||||
Attribute **aa = a;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry '%s'\n",
|
||||
e->e_nname.bv_val, 0, 0 );
|
||||
|
||||
|
||||
if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
|
||||
if ( ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) )
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
&& attr_find( e->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
) {
|
||||
|
||||
rc = backsql_get_db_conn( be, conn, &dbh );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
goto no_connection;
|
||||
|
|
|
|||
|
|
@ -15,23 +15,13 @@
|
|||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include "slap.h"
|
||||
#include "lber_pvt.h"
|
||||
#include "ldap_pvt.h"
|
||||
#include "back-sql.h"
|
||||
#include "sql-wrap.h"
|
||||
#include "schema-map.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* Deprecated
|
||||
*/
|
||||
#if 0
|
||||
static int
|
||||
backsql_cmp_oc_name( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
|
||||
{
|
||||
return BACKSQL_NCMP( &m1->name, &m2->name );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Uses the pointer to the ObjectClass structure
|
||||
*/
|
||||
|
|
@ -47,17 +37,6 @@ backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
|
|||
return ( m1->id < m2->id ? -1 : ( m1->id > m2->id ? 1 : 0 ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecated
|
||||
*/
|
||||
#if 0
|
||||
static int
|
||||
backsql_cmp_attr_name( backsql_at_map_rec *m1, backsql_at_map_rec *m2 )
|
||||
{
|
||||
return BACKSQL_NCMP( &m1->name, &m2->name );
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Uses the pointer to the AttributeDescription structure
|
||||
*/
|
||||
|
|
@ -72,7 +51,7 @@ backsql_make_attr_query(
|
|||
backsql_oc_map_rec *oc_map,
|
||||
backsql_at_map_rec *at_map )
|
||||
{
|
||||
struct berval tmps = { 0, NULL };
|
||||
struct berval tmps = BER_BVNULL;
|
||||
ber_len_t tmpslen = 0;
|
||||
|
||||
backsql_strfcat( &tmps, &tmpslen, "lblblblbcbl",
|
||||
|
|
@ -250,12 +229,11 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
|||
|
||||
oc_map->id = strtol( oc_row.cols[ 0 ], NULL, 0 );
|
||||
|
||||
ber_str2bv( oc_row.cols[ 1 ], 0, 1, &oc_map->name );
|
||||
oc_map->oc = oc_bvfind( &oc_map->name );
|
||||
oc_map->oc = oc_find( oc_row.cols[ 1 ] );
|
||||
if ( oc_map->oc == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
||||
"objectClass '%s' is not defined in schema\n",
|
||||
oc_map->name.bv_val, 0, 0 );
|
||||
oc_row.cols[ 1 ], 0, 0 );
|
||||
return LDAP_OTHER; /* undefined objectClass ? */
|
||||
}
|
||||
|
||||
|
|
@ -288,7 +266,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
|||
oc_id = oc_map->id;
|
||||
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
||||
"objectClass '%s': keytbl='%s' keycol='%s'\n",
|
||||
oc_map->name.bv_val,
|
||||
BACKSQL_OC_NAME( oc_map ),
|
||||
oc_map->keytbl.bv_val, oc_map->keycol.bv_val );
|
||||
if ( oc_map->create_proc ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n",
|
||||
|
|
@ -349,7 +327,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
|||
"attribute '%s' for objectClass '%s' "
|
||||
"is not defined in schema: %s\n",
|
||||
at_map->ad->ad_cname.bv_val,
|
||||
oc_map->name.bv_val, text );
|
||||
BACKSQL_OC_NAME( oc_map ), text );
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
|
||||
|
|
@ -415,7 +393,8 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
|
|||
#ifdef BACKSQL_TRACE
|
||||
if ( res != NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
|
||||
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
||||
"found name='%s', id=%d\n",
|
||||
BACKSQL_OC_NAME( res ), res->id, 0 );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
|
||||
"not found\n", 0, 0, 0 );
|
||||
|
|
@ -425,9 +404,6 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
|
|||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecated
|
||||
*/
|
||||
backsql_oc_map_rec *
|
||||
backsql_name2oc( backsql_info *si, struct berval *oc_name )
|
||||
{
|
||||
|
|
@ -449,7 +425,8 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name )
|
|||
#ifdef BACKSQL_TRACE
|
||||
if ( res != NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
||||
"found name='%s', id=%d\n",
|
||||
BACKSQL_OC_NAME( res ), res->id, 0 );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||
"not found\n", 0, 0, 0 );
|
||||
|
|
@ -476,7 +453,8 @@ backsql_id2oc( backsql_info *si, unsigned long id )
|
|||
#ifdef BACKSQL_TRACE
|
||||
if ( res != NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
||||
"found name='%s', id=%d\n",
|
||||
BACKSQL_OC_NAME( res ), res->id, 0 );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||
"not found\n", 0, 0, 0 );
|
||||
|
|
@ -494,7 +472,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
|
|||
#ifdef BACKSQL_TRACE
|
||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): "
|
||||
"searching for attribute '%s' for objectclass '%s'\n",
|
||||
attr, objclass->name, 0 );
|
||||
attr, BACKSQL_OC_NAME( objclass ), 0 );
|
||||
#endif /* BACKSQL_TRACE */
|
||||
|
||||
tmp.ad = ad;
|
||||
|
|
@ -505,7 +483,7 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
|
|||
if ( res != NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
|
||||
"found name='%s', sel_expr='%s'\n",
|
||||
res->name, res->sel_expr.bv_val, 0 );
|
||||
res->ad->ad_cname.bv_val, res->sel_expr.bv_val, 0 );
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
|
||||
"not found\n", 0, 0, 0 );
|
||||
|
|
@ -527,7 +505,7 @@ backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
|
|||
#ifdef BACKSQL_TRACE
|
||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_name2at(): "
|
||||
"searching for attribute '%s' for objectclass '%s'\n",
|
||||
attr, objclass->name, 0 );
|
||||
attr, BACKSQL_OC_NAME( objclass ), 0 );
|
||||
#endif /* BACKSQL_TRACE */
|
||||
|
||||
if ( slap_bv2ad( attr, &tmp.ad, &text ) != LDAP_SUCCESS ) {
|
||||
|
|
@ -587,9 +565,8 @@ static void
|
|||
backsql_free_oc( backsql_oc_map_rec *oc )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n",
|
||||
oc->name.bv_val, 0, 0 );
|
||||
BACKSQL_OC_NAME( oc ), 0, 0 );
|
||||
avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
|
||||
ch_free( oc->name.bv_val );
|
||||
ch_free( oc->keytbl.bv_val );
|
||||
ch_free( oc->keycol.bv_val );
|
||||
if ( oc->create_proc != NULL ) {
|
||||
|
|
|
|||
|
|
@ -11,15 +11,12 @@
|
|||
*/
|
||||
|
||||
typedef struct {
|
||||
/*
|
||||
* FIXME: we explicitly keep the objectClass name because
|
||||
* the ObjectClass structure does not use bervals (yet?)
|
||||
*/
|
||||
struct berval name;
|
||||
/*
|
||||
* Structure of corresponding LDAP objectClass definition
|
||||
*/
|
||||
ObjectClass *oc;
|
||||
#define BACKSQL_OC_NAME(ocmap) ((ocmap)->oc->soc_cname.bv_val)
|
||||
|
||||
struct berval keytbl;
|
||||
struct berval keycol;
|
||||
/* expected to return keyval of newly created entry */
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "entry-id.h"
|
||||
#include "util.h"
|
||||
|
||||
static int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
|
||||
|
||||
static int
|
||||
backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
|
||||
{
|
||||
|
|
@ -33,6 +35,15 @@ backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* clear the list (retrieve all attrs)
|
||||
*/
|
||||
if ( ad == NULL ) {
|
||||
ch_free( bsi->attrs );
|
||||
bsi->attrs = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
for ( ; bsi->attrs[ n_attrs ].an_name.bv_val; n_attrs++ ) {
|
||||
an = &bsi->attrs[ n_attrs ];
|
||||
|
||||
|
|
@ -94,12 +105,8 @@ backsql_init_search(
|
|||
bsi->be = be;
|
||||
bsi->conn = conn;
|
||||
bsi->op = op;
|
||||
bsi->attr_flags = 0;
|
||||
bsi->bsi_flags = 0;
|
||||
|
||||
/*
|
||||
* FIXME: need to discover how to deal with 1.1 (NoAttrs)
|
||||
*/
|
||||
|
||||
/*
|
||||
* handle "*"
|
||||
*/
|
||||
|
|
@ -114,13 +121,13 @@ backsql_init_search(
|
|||
|
||||
for ( p = attrs; p->an_name.bv_val; p++ ) {
|
||||
/*
|
||||
* ignore "+"
|
||||
* ignore "1.1"; handle "+"
|
||||
*/
|
||||
if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0 ) {
|
||||
bsi->bsi_flags |= BSQL_SF_ALL_OPER;
|
||||
continue;
|
||||
|
||||
} else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) {
|
||||
bsi->attr_flags |= BSQL_SF_ALL_OPER;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +156,7 @@ backsql_init_search(
|
|||
bsi->status = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
|
||||
{
|
||||
int res;
|
||||
|
|
@ -195,7 +202,7 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
|
||||
{
|
||||
int i;
|
||||
|
|
@ -301,13 +308,13 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
||||
{
|
||||
backsql_at_map_rec *at;
|
||||
backsql_at_map_rec oc_attr = {
|
||||
slap_schema.si_ad_objectClass, BER_BVC(""), BER_BVC(""),
|
||||
{ 0, NULL }, NULL, NULL, NULL };
|
||||
BER_BVNULL, NULL, NULL, NULL };
|
||||
AttributeDescription *ad = NULL;
|
||||
int done = 0;
|
||||
ber_len_t len = 0;
|
||||
|
|
@ -328,7 +335,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
|||
|
||||
case LDAP_FILTER_AND:
|
||||
rc = backsql_process_filter_list( bsi, f->f_and,
|
||||
LDAP_FILTER_AND);
|
||||
LDAP_FILTER_AND );
|
||||
done = 1;
|
||||
break;
|
||||
|
||||
|
|
@ -346,6 +353,10 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
|||
ad = f->f_desc;
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_EXT:
|
||||
ad = f->f_mra->ma_desc;
|
||||
break;
|
||||
|
||||
default:
|
||||
ad = f->f_av_desc;
|
||||
break;
|
||||
|
|
@ -360,23 +371,58 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
|||
goto done;
|
||||
}
|
||||
|
||||
if ( ad != slap_schema.si_ad_objectClass ) {
|
||||
at = backsql_ad2at( bsi->oc, ad );
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Turn structuralObjectClass into objectClass
|
||||
*/
|
||||
if ( ad == slap_schema.si_ad_objectClass
|
||||
|| ad == slap_schema.si_ad_structuralObjectClass ) {
|
||||
at = &oc_attr;
|
||||
backsql_strfcat( &at->sel_expr, &len, "cbc",
|
||||
'\'',
|
||||
&bsi->oc->name,
|
||||
&bsi->oc->oc->soc_cname,
|
||||
'\'' );
|
||||
|
||||
#if defined(SLAP_X_FILTER_HASSUBORDINATES) || defined(SLAP_X_MRA_MATCH_DNATTRS)
|
||||
} else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
|
||||
/*
|
||||
* FIXME: this is not robust; e.g. a filter
|
||||
* '(!(hasSubordinates=TRUE))' fails because
|
||||
* in SQL it would read 'NOT (1=1)' instead
|
||||
* of no condition.
|
||||
* Note however that hasSubordinates is boolean,
|
||||
* so a more appropriate filter would be
|
||||
* '(hasSubordinates=FALSE)'
|
||||
*/
|
||||
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||
(ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
|
||||
if ( ad != NULL ) {
|
||||
/*
|
||||
* We use this flag since we need to parse
|
||||
* the filter anyway; we should have used
|
||||
* the frontend API function
|
||||
* filter_has_subordinates()
|
||||
*/
|
||||
bsi->bsi_flags |= BSQL_SF_FILTER_HASSUBORDINATE;
|
||||
} else {
|
||||
/*
|
||||
* clear attributes to fetch, to require ALL
|
||||
* and try extended match on all attributes
|
||||
*/
|
||||
backsql_attrlist_add( bsi, NULL );
|
||||
}
|
||||
goto done;
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES || SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
} else {
|
||||
at = backsql_ad2at( bsi->oc, ad );
|
||||
}
|
||||
|
||||
if ( at == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
|
||||
"attribute '%s' is not defined for objectclass '%s'\n",
|
||||
ad->ad_cname.bv_val, bsi->oc->name.bv_val, 0 );
|
||||
ad->ad_cname.bv_val, BACKSQL_OC_NAME( bsi->oc ), 0 );
|
||||
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||
(ber_len_t)sizeof( " 1=0 " ) - 1, " 1=0 " );
|
||||
(ber_len_t)sizeof( "1=0" ) - 1, "1=0" );
|
||||
goto impossible;
|
||||
}
|
||||
|
||||
|
|
@ -461,6 +507,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
|||
break;
|
||||
|
||||
case LDAP_FILTER_GE:
|
||||
/*
|
||||
* FIXME: should we uppercase the operands?
|
||||
*/
|
||||
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
|
||||
'(' /* ) */ ,
|
||||
&at->sel_expr,
|
||||
|
|
@ -470,6 +519,9 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
|||
break;
|
||||
|
||||
case LDAP_FILTER_LE:
|
||||
/*
|
||||
* FIXME: should we uppercase the operands?
|
||||
*/
|
||||
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
|
||||
'(' /* ) */ ,
|
||||
&at->sel_expr,
|
||||
|
|
@ -558,13 +610,13 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
|
|||
&bi->strcast_func,
|
||||
(ber_len_t)sizeof( "('" /* ') */ ) - 1,
|
||||
"('" /* ') */ ,
|
||||
&bsi->oc->name,
|
||||
&bsi->oc->oc->soc_cname,
|
||||
(ber_len_t)sizeof( /* (' */ "')" ) - 1,
|
||||
/* (' */ "')" );
|
||||
} else {
|
||||
backsql_strfcat( &bsi->sel, &bsi->sel_len, "cbc",
|
||||
'\'',
|
||||
&bsi->oc->name,
|
||||
&bsi->oc->oc->soc_cname,
|
||||
'\'' );
|
||||
}
|
||||
backsql_strfcat( &bsi->sel, &bsi->sel_len, "l",
|
||||
|
|
@ -669,7 +721,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
|
|||
int j;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n",
|
||||
oc->name.bv_val, 0, 0 );
|
||||
BACKSQL_OC_NAME( oc ), 0, 0 );
|
||||
|
||||
if ( bsi->n_candidates == -1 ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
|
||||
|
|
@ -998,6 +1050,10 @@ backsql_search(
|
|||
*/
|
||||
for ( eid = srch_info.id_list; eid != NULL;
|
||||
eid = backsql_free_entryID( eid, 1 ) ) {
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
Attribute *hasSubordinate = NULL,
|
||||
*a = NULL;
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
/* check for abandon */
|
||||
if ( op->o_abandon ) {
|
||||
|
|
@ -1035,10 +1091,68 @@ backsql_search(
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
/*
|
||||
* We use this flag since we need to parse the filter
|
||||
* anyway; we should have used the frontend API function
|
||||
* filter_has_subordinates()
|
||||
*/
|
||||
if ( srch_info.bsi_flags & BSQL_SF_FILTER_HASSUBORDINATE ) {
|
||||
int rc;
|
||||
|
||||
rc = backsql_has_children( bi, dbh, &entry->e_nname );
|
||||
|
||||
switch( rc ) {
|
||||
case LDAP_COMPARE_TRUE:
|
||||
case LDAP_COMPARE_FALSE:
|
||||
hasSubordinate = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
|
||||
if ( hasSubordinate != NULL ) {
|
||||
for ( a = entry->e_attrs;
|
||||
a && a->a_next;
|
||||
a = a->a_next );
|
||||
|
||||
a->a_next = hasSubordinate;
|
||||
}
|
||||
rc = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"backsql_search(): "
|
||||
"has_children failed( %d)\n",
|
||||
rc, 0, 0 );
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rc ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
if ( test_filter( be, conn, op, entry, filter )
|
||||
== LDAP_COMPARE_TRUE ) {
|
||||
sres = send_search_entry( be, conn, op, entry,
|
||||
attrs, attrsonly, NULL );
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
if ( hasSubordinate && !( srch_info.bsi_flags & BSQL_SF_ALL_OPER )
|
||||
&& !ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
|
||||
a->a_next = NULL;
|
||||
attr_free( hasSubordinate );
|
||||
hasSubordinate = NULL;
|
||||
}
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
#if 0 /* noop is masked SLAP_CTRL_UPDATE */
|
||||
if ( op->o_noop ) {
|
||||
sres = 0;
|
||||
} else {
|
||||
#endif
|
||||
sres = send_search_entry( be, conn, op, entry,
|
||||
attrs, attrsonly, NULL );
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
switch ( sres ) {
|
||||
case 0:
|
||||
nentries++;
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ char *
|
|||
backsql_get_table_spec( char **p )
|
||||
{
|
||||
char *s, *q;
|
||||
struct berval res = { 0, NULL };
|
||||
struct berval res = BER_BVNULL;
|
||||
ber_len_t res_len = 0;
|
||||
|
||||
assert( p );
|
||||
|
|
|
|||
|
|
@ -42,14 +42,14 @@ typedef struct backsql_srch_info {
|
|||
Connection *conn;
|
||||
Operation *op;
|
||||
AttributeName *attrs;
|
||||
int attr_flags;
|
||||
#define BSQL_SF_ALL_OPER 0x0001
|
||||
int bsi_flags;
|
||||
#define BSQL_SF_ALL_OPER 0x0001
|
||||
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002
|
||||
Entry *e;
|
||||
/* 1 if the db is TimesTen; 0 if it's not */
|
||||
int use_reverse_dn;
|
||||
} backsql_srch_info;
|
||||
|
||||
int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
|
||||
void backsql_init_search( backsql_srch_info *bsi, backsql_info *bi,
|
||||
struct berval *nbase, int scope, int slimit, int tlimit,
|
||||
time_t stoptime, Filter *filter, SQLHDBC dbh,
|
||||
|
|
|
|||
|
|
@ -22,10 +22,6 @@
|
|||
|
||||
const struct berval slap_empty_bv = { 0, "" };
|
||||
|
||||
#define SLAP_LDAPDN_PRETTY 0x1
|
||||
|
||||
#define SLAP_LDAPDN_MAXLEN 8192
|
||||
|
||||
/*
|
||||
* The DN syntax-related functions take advantage of the dn representation
|
||||
* handling functions ldap_str2dn/ldap_dn2str. The latter are not schema-
|
||||
|
|
@ -493,6 +489,60 @@ dnPretty2(
|
|||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
dnPrettyNormalDN(
|
||||
Syntax *syntax,
|
||||
struct berval *val,
|
||||
LDAPDN **dn,
|
||||
int flags )
|
||||
{
|
||||
assert( val );
|
||||
assert( dn );
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( OPERATION, ARGS, ">>> dn%sDN: <%s>\n",
|
||||
flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal",
|
||||
val->bv_val, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, ">>> dn%sDN: <%s>\n",
|
||||
flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal",
|
||||
val->bv_val, 0 );
|
||||
#endif
|
||||
|
||||
if ( val->bv_len == 0 ) {
|
||||
return LDAP_SUCCESS;
|
||||
|
||||
} else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
|
||||
} else {
|
||||
int rc;
|
||||
|
||||
/* FIXME: should be liberal in what we accept */
|
||||
rc = ldap_bv2dn( val, dn, LDAP_DN_FORMAT_LDAP );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
assert( strlen( val->bv_val ) == val->bv_len );
|
||||
|
||||
/*
|
||||
* Schema-aware rewrite
|
||||
*/
|
||||
if ( LDAPDN_rewrite( *dn, flags ) != LDAP_SUCCESS ) {
|
||||
ldap_dnfree( *dn );
|
||||
*dn = NULL;
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "<<< dn%sDN\n",
|
||||
flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal",
|
||||
0, 0 );
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Combination of both dnPretty and dnNormalize
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -744,7 +744,7 @@ filter2bv( Filter *f, struct berval *fstr )
|
|||
|
||||
case LDAP_FILTER_EXT:
|
||||
filter_escape_value( &f->f_mr_value, &tmp );
|
||||
|
||||
#ifndef SLAP_X_MRA_MATCH_DNATTRS
|
||||
fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
|
||||
( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
|
||||
( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
|
||||
|
|
@ -757,6 +757,31 @@ filter2bv( Filter *f, struct berval *fstr )
|
|||
f->f_mr_rule_text.bv_len ? ":" : "",
|
||||
f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
|
||||
tmp.bv_val );
|
||||
#else /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
{
|
||||
struct berval ad;
|
||||
|
||||
if ( f->f_mr_desc ) {
|
||||
ad = f->f_mr_desc->ad_cname;
|
||||
} else {
|
||||
ad.bv_len = 0;
|
||||
ad.bv_val = "";
|
||||
}
|
||||
|
||||
fstr->bv_len = ad.bv_len +
|
||||
( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
|
||||
( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
|
||||
tmp.bv_len + ( sizeof("(:=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
|
||||
ad.bv_val,
|
||||
f->f_mr_dnattrs ? ":dn" : "",
|
||||
f->f_mr_rule_text.bv_len ? ":" : "",
|
||||
f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
|
||||
tmp.bv_val );
|
||||
}
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
ber_memfree( tmp.bv_val );
|
||||
break;
|
||||
|
||||
|
|
@ -1286,6 +1311,7 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
|
|||
case LDAP_FILTER_EXT:
|
||||
filter_escape_value( &f->f_mr_value, &tmp );
|
||||
|
||||
#ifndef SLAP_X_MRA_MATCH_DNATTRS
|
||||
fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
|
||||
( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
|
||||
( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
|
||||
|
|
@ -1298,6 +1324,32 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
|
|||
f->f_mr_rule_text.bv_len ? ":" : "",
|
||||
f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
|
||||
tmp.bv_val );
|
||||
#else /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
{
|
||||
struct berval ad;
|
||||
|
||||
if ( f->f_mr_desc ) {
|
||||
ad = f->f_mr_desc->ad_cname;
|
||||
} else {
|
||||
ad.bv_len = 0;
|
||||
ad.bv_val = "";
|
||||
}
|
||||
|
||||
fstr->bv_len = ad.bv_len +
|
||||
( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
|
||||
( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
|
||||
tmp.bv_len + ( sizeof("(:=)") - 1 );
|
||||
fstr->bv_val = malloc( fstr->bv_len + 1 );
|
||||
|
||||
snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
|
||||
ad.bv_val,
|
||||
f->f_mr_dnattrs ? ":dn" : "",
|
||||
f->f_mr_rule_text.bv_len ? ":" : "",
|
||||
f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
|
||||
tmp.bv_val );
|
||||
}
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
ber_memfree( tmp.bv_val );
|
||||
break;
|
||||
|
||||
|
|
@ -1514,3 +1566,92 @@ return_error:
|
|||
return( LDAP_SUCCESS );
|
||||
}
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
static int filter_has_subordinates_list(
|
||||
Filter *filter );
|
||||
|
||||
/*
|
||||
* FIXME: we could detect the need to filter
|
||||
* for hasSubordinates when parsing the filter ...
|
||||
*/
|
||||
|
||||
static int
|
||||
filter_has_subordinates_list(
|
||||
Filter *fl )
|
||||
{
|
||||
Filter *f;
|
||||
|
||||
for ( f = fl; f != NULL; f = f->f_next ) {
|
||||
int rc;
|
||||
|
||||
rc = filter_has_subordinates( f );
|
||||
|
||||
if ( rc ) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
filter_has_subordinates(
|
||||
Filter *f )
|
||||
{
|
||||
AttributeDescription *ad = NULL;
|
||||
|
||||
switch ( f->f_choice ) {
|
||||
case LDAP_FILTER_PRESENT:
|
||||
ad = f->f_desc;
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_EQUALITY:
|
||||
case LDAP_FILTER_APPROX:
|
||||
case LDAP_FILTER_GE:
|
||||
case LDAP_FILTER_LE:
|
||||
ad = f->f_ava->aa_desc;
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_SUBSTRINGS:
|
||||
ad = f->f_sub_desc;
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_EXT:
|
||||
/* could be null; however here it is harmless */
|
||||
ad = f->f_mra->ma_desc;
|
||||
break;
|
||||
|
||||
case LDAP_FILTER_NOT:
|
||||
return filter_has_subordinates( f->f_not );
|
||||
|
||||
case LDAP_FILTER_AND:
|
||||
return filter_has_subordinates_list( f->f_and );
|
||||
|
||||
case LDAP_FILTER_OR:
|
||||
return filter_has_subordinates_list( f->f_or );
|
||||
|
||||
case SLAPD_FILTER_COMPUTED:
|
||||
/*
|
||||
* something wrong?
|
||||
*/
|
||||
return 0;
|
||||
|
||||
default:
|
||||
/*
|
||||
* this means a new type of filter has been implemented,
|
||||
* which is not handled yet in this function; we should
|
||||
* issue a developer's warning, e.g. an assertion
|
||||
*/
|
||||
assert( 0 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( ad == slap_schema.si_ad_hasSubordinates ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
|
|
|
|||
|
|
@ -215,37 +215,175 @@ static int test_mra_filter(
|
|||
{
|
||||
Attribute *a;
|
||||
|
||||
#ifndef SLAP_X_MRA_MATCH_DNATTRS
|
||||
if( !access_allowed( be, conn, op, e,
|
||||
mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
#else /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
if ( mra->ma_desc ) {
|
||||
/*
|
||||
* if ma_desc is available, then we're filtering for
|
||||
* one attribute, and SEARCH permissions can be checked
|
||||
* directly.
|
||||
*/
|
||||
if( !access_allowed( be, conn, op, e,
|
||||
mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
|
||||
{
|
||||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
for(a = attrs_find( e->e_attrs, mra->ma_desc );
|
||||
a != NULL;
|
||||
a = attrs_find( a->a_next, mra->ma_desc ) )
|
||||
{
|
||||
struct berval *bv;
|
||||
for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
|
||||
int ret;
|
||||
int rc;
|
||||
const char *text;
|
||||
for(a = attrs_find( e->e_attrs, mra->ma_desc );
|
||||
a != NULL;
|
||||
a = attrs_find( a->a_next, mra->ma_desc ) )
|
||||
{
|
||||
struct berval *bv;
|
||||
for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
|
||||
int ret;
|
||||
int rc;
|
||||
const char *text;
|
||||
|
||||
rc = value_match( &ret, a->a_desc, mra->ma_rule,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
bv, &mra->ma_value, &text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ( ret == 0 ) {
|
||||
return LDAP_COMPARE_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef SLAP_X_MRA_MATCH_DNATTRS
|
||||
} else {
|
||||
|
||||
rc = value_match( &ret, a->a_desc, mra->ma_rule,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
bv, &mra->ma_value,
|
||||
&text );
|
||||
/*
|
||||
* No attribute description: test all
|
||||
*/
|
||||
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
|
||||
struct berval *bv, value;
|
||||
const char *text = NULL;
|
||||
int rc;
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
/* check if matching is appropriate */
|
||||
if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
|
||||
a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ret == 0 ) {
|
||||
return LDAP_COMPARE_TRUE;
|
||||
/* normalize for equality */
|
||||
rc = value_validate_normalize( a->a_desc,
|
||||
SLAP_MR_EQUALITY,
|
||||
&mra->ma_value, &value, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check search access */
|
||||
if ( !access_allowed( be, conn, op, e,
|
||||
a->a_desc, &value, ACL_SEARCH, NULL ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check match */
|
||||
for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
|
||||
int ret;
|
||||
int rc;
|
||||
|
||||
rc = value_match( &ret, a->a_desc, mra->ma_rule,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
bv, &value, &text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ( ret == 0 ) {
|
||||
return LDAP_COMPARE_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check attrs in DN AVAs if required */
|
||||
if ( mra->ma_dnattrs ) {
|
||||
LDAPDN *dn = NULL;
|
||||
int iRDN, iAVA;
|
||||
int rc;
|
||||
|
||||
/* parse and pretty the dn */
|
||||
rc = dnPrettyDN( NULL, &e->e_name, &dn );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
return LDAP_INVALID_SYNTAX;
|
||||
}
|
||||
|
||||
/* for each AVA of each RDN ... */
|
||||
for ( iRDN = 0; dn[ 0 ][ iRDN ]; iRDN++ ) {
|
||||
LDAPRDN *rdn = dn[ 0 ][ iRDN ];
|
||||
|
||||
for ( iAVA = 0; rdn[ 0 ][ iAVA ]; iAVA++ ) {
|
||||
LDAPAVA *ava = rdn[ 0 ][ iAVA ];
|
||||
struct berval *bv = &ava->la_value, value;
|
||||
AttributeDescription *ad = (AttributeDescription *)ava->la_private;
|
||||
int ret;
|
||||
int rc;
|
||||
const char *text;
|
||||
|
||||
assert( ad );
|
||||
|
||||
if ( mra->ma_desc ) {
|
||||
/* have a mra type? check for subtype */
|
||||
if ( !is_ad_subtype( ad, mra->ma_desc ) ) {
|
||||
continue;
|
||||
}
|
||||
value = mra->ma_value;
|
||||
|
||||
} else {
|
||||
const char *text = NULL;
|
||||
|
||||
/* check if matching is appropriate */
|
||||
if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
|
||||
ad->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* normalize for equality */
|
||||
rc = value_validate_normalize( ad, SLAP_MR_EQUALITY,
|
||||
&mra->ma_value, &value, &text );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check search access */
|
||||
if ( !access_allowed( be, conn, op, e,
|
||||
ad, &value, ACL_SEARCH, NULL ) ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* check match */
|
||||
rc = value_match( &ret, ad, mra->ma_rule,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
bv, &value, &text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
ldap_dnfree( dn );
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ( ret == 0 ) {
|
||||
ldap_dnfree( dn );
|
||||
return LDAP_COMPARE_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
return LDAP_COMPARE_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
#include "../../libraries/liblber/lber-int.h"
|
||||
|
||||
static int test_mra_vrFilter(
|
||||
static int
|
||||
test_mra_vrFilter(
|
||||
Backend *be,
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
|
|
@ -342,7 +343,8 @@ test_substrings_vrFilter(
|
|||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
static int test_mra_vrFilter(
|
||||
static int
|
||||
test_mra_vrFilter(
|
||||
Backend *be,
|
||||
Connection *conn,
|
||||
Operation *op,
|
||||
|
|
@ -354,11 +356,40 @@ static int test_mra_vrFilter(
|
|||
int i, j;
|
||||
|
||||
for ( i=0; a != NULL; a = a->a_next, i++ ) {
|
||||
struct berval *bv;
|
||||
|
||||
struct berval *bv, value;
|
||||
|
||||
#ifndef SLAP_X_MRA_MATCH_DNATTRS
|
||||
if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
|
||||
return( LDAP_SUCCESS );
|
||||
}
|
||||
value = mra->ma_value;
|
||||
|
||||
#else /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
if ( mra->ma_desc ) {
|
||||
if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
|
||||
return( LDAP_SUCCESS );
|
||||
}
|
||||
value = mra->ma_value;
|
||||
|
||||
} else {
|
||||
const char *text = NULL;
|
||||
|
||||
/* check if matching is appropriate */
|
||||
if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
|
||||
a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* normalize for equality */
|
||||
if ( value_validate_normalize( a->a_desc,
|
||||
SLAP_MR_EQUALITY,
|
||||
&mra->ma_value, &value,
|
||||
&text ) != LDAP_SUCCESS ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
|
||||
int ret;
|
||||
|
|
@ -367,7 +398,7 @@ static int test_mra_vrFilter(
|
|||
|
||||
rc = value_match( &ret, a->a_desc, mra->ma_rule,
|
||||
SLAP_MR_ASSERTION_SYNTAX_MATCH,
|
||||
bv, &mra->ma_value,
|
||||
bv, &value,
|
||||
&text );
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
|
|
|
|||
|
|
@ -170,10 +170,15 @@ get_mra(
|
|||
return SLAPD_DISCONNECT;
|
||||
}
|
||||
|
||||
#ifndef SLAP_X_MRA_MATCH_DNATTRS
|
||||
/*
|
||||
* Let's try to implement it
|
||||
*/
|
||||
if( ma->ma_dnattrs ) {
|
||||
*text = "matching with \":dn\" not supported";
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
#endif /* !SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
if( type.bv_val != NULL ) {
|
||||
rc = slap_bv2ad( &type, &ma->ma_desc, text );
|
||||
|
|
@ -182,9 +187,11 @@ get_mra(
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifndef SLAP_X_MRA_MATCH_DNATTRS
|
||||
} else {
|
||||
*text = "matching without attribute description rule not supported";
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
#endif /* !SLAP_X_MRA_MATCH_DNATTRS */
|
||||
}
|
||||
|
||||
if( ma->ma_rule_text.bv_val != NULL ) {
|
||||
|
|
@ -196,6 +203,40 @@ get_mra(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: is it correct that ma->ma_rule_text, if present,
|
||||
* is looked-up, checked, and then replaced by the sat_equality
|
||||
* of the given attribute? I'd rather do smtg like use
|
||||
* the attribute's equality rule only if no matching rule
|
||||
* was given, otherwise I don't see any extension ...
|
||||
*/
|
||||
|
||||
#if 1
|
||||
if ( ma->ma_rule == NULL ) {
|
||||
#ifdef SLAP_X_MRA_MATCH_DNATTRS
|
||||
/*
|
||||
* Need either type or rule ...
|
||||
*/
|
||||
if ( ma->ma_desc == NULL ) {
|
||||
mra_free( ma, 1 );
|
||||
*text = "matching rule not recognized";
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
#endif /* !SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
if ( ma->ma_desc->ad_type->sat_equality != NULL &&
|
||||
ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
|
||||
{
|
||||
/* no matching rule was provided, use the attribute's
|
||||
equality rule if it supports extensible matching. */
|
||||
ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
|
||||
|
||||
} else {
|
||||
mra_free( ma, 1 );
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if( ma->ma_desc != NULL &&
|
||||
ma->ma_desc->ad_type->sat_equality != NULL &&
|
||||
ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
|
||||
|
|
@ -208,24 +249,38 @@ get_mra(
|
|||
mra_free( ma, 1 );
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SLAP_X_MRA_MATCH_DNATTRS
|
||||
if ( ma->ma_desc != NULL ) {
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
/* check to see if the matching rule is appropriate for
|
||||
the syntax of the attribute. This check will need
|
||||
to be extended to support other kinds of extensible
|
||||
matching rules */
|
||||
if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
|
||||
ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
|
||||
{
|
||||
mra_free( ma, 1 );
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, if no matching rule, normalize for equality, otherwise
|
||||
* normalize for the matching rule.
|
||||
*/
|
||||
rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
|
||||
&value, &ma->ma_value, text );
|
||||
#ifdef SLAP_X_MRA_MATCH_DNATTRS
|
||||
} else {
|
||||
/*
|
||||
* Need to normalize, but how?
|
||||
*/
|
||||
ma->ma_value = value;
|
||||
rc = value_validate( ma->ma_rule, &ma->ma_value, text );
|
||||
|
||||
/* check to see if the matching rule is appropriate for
|
||||
the syntax of the attribute. This check will need
|
||||
to be extended to support other kinds of extensible
|
||||
matching rules */
|
||||
if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
|
||||
ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
|
||||
{
|
||||
mra_free( ma, 1 );
|
||||
return LDAP_INAPPROPRIATE_MATCHING;
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, if no matching rule, normalize for equality, otherwise
|
||||
* normalize for the matching rule.
|
||||
*/
|
||||
rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
|
||||
&value, &ma->ma_value, text );
|
||||
#endif /* SLAP_X_MRA_MATCH_DNATTRS */
|
||||
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
mra_free( ma, 1 );
|
||||
|
|
|
|||
|
|
@ -395,6 +395,13 @@ LDAP_SLAPD_F (int) dnX509normalize LDAP_P(( void *x509_name, struct berval *out
|
|||
|
||||
LDAP_SLAPD_F (int) dnX509peerNormalize LDAP_P(( void *ssl, struct berval *dn ));
|
||||
|
||||
LDAP_SLAPD_F (int) dnPrettyNormalDN LDAP_P(( Syntax *syntax, struct berval *val, LDAPDN **dn, int flags ));
|
||||
#define dnPrettyDN(syntax, val, dn) \
|
||||
dnPrettyNormalDN((syntax),(val),(dn), SLAP_LDAPDN_PRETTY)
|
||||
#define dnNormalDN(syntax, val, dn) \
|
||||
dnPrettyNormalDN((syntax),(val),(dn), 0)
|
||||
|
||||
|
||||
/*
|
||||
* entry.c
|
||||
*/
|
||||
|
|
@ -451,17 +458,31 @@ LDAP_SLAPD_F (int) get_filter LDAP_P((
|
|||
LDAP_SLAPD_F (void) filter_free LDAP_P(( Filter *f ));
|
||||
LDAP_SLAPD_F (void) filter2bv LDAP_P(( Filter *f, struct berval *bv ));
|
||||
|
||||
LDAP_SLAPD_F (int) get_vrFilter( Connection *conn, BerElement *ber,
|
||||
LDAP_SLAPD_F (int) get_vrFilter LDAP_P(( Connection *conn, BerElement *ber,
|
||||
ValuesReturnFilter **f,
|
||||
const char **text );
|
||||
const char **text ));
|
||||
|
||||
LDAP_SLAPD_F (void) vrFilter_free( ValuesReturnFilter *f );
|
||||
LDAP_SLAPD_F (void) vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr );
|
||||
LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
|
||||
LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
|
||||
|
||||
/*
|
||||
* define to honor hasSubordinates operational attribute in search filters
|
||||
*/
|
||||
#define SLAP_X_FILTER_HASSUBORDINATES
|
||||
|
||||
#ifdef SLAP_X_FILTER_HASSUBORDINATES
|
||||
LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
|
||||
#endif /* SLAP_X_FILTER_HASSUBORDINATES */
|
||||
|
||||
/*
|
||||
* filterentry.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* define to enable dn components match in extended filter matching
|
||||
*/
|
||||
#define SLAP_X_MRA_MATCH_DNATTRS
|
||||
|
||||
LDAP_SLAPD_F (int) test_filter LDAP_P((
|
||||
Backend *be, Connection *conn, Operation *op,
|
||||
Entry *e, Filter *f ));
|
||||
|
|
|
|||
|
|
@ -770,6 +770,7 @@ send_search_entry(
|
|||
}
|
||||
e_flags = ch_calloc ( 1, i * sizeof(char *) + k );
|
||||
a_flags = (char *)(e_flags + i);
|
||||
memset( a_flags, 0, k );
|
||||
for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
|
||||
for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
|
||||
e_flags[i] = a_flags;
|
||||
|
|
@ -909,25 +910,45 @@ send_search_entry(
|
|||
}
|
||||
}
|
||||
|
||||
/* free e_flags */
|
||||
if ( e_flags ) {
|
||||
free( e_flags );
|
||||
e_flags = NULL;
|
||||
}
|
||||
|
||||
/* eventually will loop through generated operational attributes */
|
||||
/* only have subschemaSubentry implemented */
|
||||
aa = backend_operational( be, conn, op, e, attrs, opattrs );
|
||||
|
||||
if ( aa != NULL && op->vrFilter != NULL ) {
|
||||
int k = 0;
|
||||
char *a_flags;
|
||||
char *a_flags, **tmp;
|
||||
|
||||
for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
|
||||
for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) k++;
|
||||
}
|
||||
e_flags = ch_calloc ( 1, i * sizeof(char *) + k );
|
||||
/*
|
||||
* Reuse previous memory - we likely need less space
|
||||
* for operational attributes
|
||||
*/
|
||||
tmp = ch_realloc ( e_flags, i * sizeof(char *) + k );
|
||||
if ( tmp == NULL ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( OPERATION, ERR,
|
||||
"send_search_entry: conn %lu "
|
||||
"not enough memory "
|
||||
"for matched values filtering\n",
|
||||
conn ? conn->c_connid : 0, 0, 0);
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"send_search_entry: conn %lu "
|
||||
"not enough memory "
|
||||
"for matched values filtering\n",
|
||||
conn ? conn->c_connid : 0, 0, 0 );
|
||||
#endif
|
||||
ber_free( ber, 1 );
|
||||
|
||||
send_ldap_result( conn, op, LDAP_NO_MEMORY,
|
||||
NULL, NULL, NULL, NULL );
|
||||
goto error_return;
|
||||
}
|
||||
e_flags = tmp;
|
||||
a_flags = (char *)(e_flags + i);
|
||||
memset( a_flags, 0, k );
|
||||
for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
|
||||
for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
|
||||
e_flags[i] = a_flags;
|
||||
|
|
@ -942,7 +963,7 @@ send_search_entry(
|
|||
"matched values filtering failed\n",
|
||||
conn ? conn->c_connid : 0, 0, 0);
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"matched values filtering failed\n", 0, 0, 0 );
|
||||
#endif
|
||||
ber_free( ber, 1 );
|
||||
|
|
|
|||
|
|
@ -1683,6 +1683,12 @@ enum {
|
|||
};
|
||||
#endif /* SLAPD_MONITOR */
|
||||
|
||||
/*
|
||||
* Better know these all around slapd
|
||||
*/
|
||||
#define SLAP_LDAPDN_PRETTY 0x1
|
||||
#define SLAP_LDAPDN_MAXLEN 8192
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
#include "proto-slap.h"
|
||||
|
|
|
|||
Loading…
Reference in a new issue