Specifies the name of a function that converts a given value to uppercase.
This is used for CIS matching when the RDBMS is case sensitive.
.TP
-.B upper_needs_cast { yes | no }
+.B upper_needs_cast { NO | yes}
Set this directive to
.B yes
if
.B experimental
and may change in future releases.
.TP
-.B has_ldapinfo_dn_ru { yes | no }
+.B has_ldapinfo_dn_ru { NO | yes }
Explicitly inform the backend whether the SQL schema has dn_ru column
(dn in reverse uppercased form) or not.
Overrides automatic check (required by PostgreSQL/unixODBC).
and may change in future releases.
.TP
-.B fail_if_no_mapping { yes | no }
+.B fail_if_no_mapping { NO | yes }
When set to
.B yes
it forces
.B experimental
and may change in future releases.
+.TP
+.B allow_orphans { NO | yes }
+When set to
+.B yes
+orphaned entries (i.e. without the parent entry in the database)
+can be added. This option should be used with care, possibly
+in conjunction with some special rule on the RDBMS side that
+dynamically creates the missing parent.
+
+.TP
+.B baseObject [filename]
+Instructs the database to create and manage an in-memory baseObject
+entry instead of looking for one in the RDBMS.
+If the (optional)
+.B filename
+argument is given, the entry is read from file
+.B filename
+in
+.BR LDIF (5)
+form.
+This is particularly useful when
+.B ldap_entries
+information is stored in a view rather than in a table, and
+.B union
+is not supported for views, so that the view can only specify
+one rule to compute the entry structure for one objectClass.
+This topic is discussed further in section "METAINFORMATION USED".
+This is
+.B experimental
+and may change in future releases.
+
.SH METAINFORMATION USED
.LP
Almost everything mentioned later is illustrated in examples located
.LP
.nf
CREATE VIEW ldap_entries (id, dn, oc_map_id, parent, keyval)
- AS SELECT (1000000000+userid),
+ AS
+ SELECT 0, UPPER('o=MyCompany,c=NL'),
+ 3, 0, 'baseObject' FROM unixusers WHERE userid='root' UNION
+ SELECT (1000000000+userid),
UPPER(CONCAT(CONCAT('cn=',gecos),',o=MyCompany,c=NL')),
1, 0, userid FROM unixusers UNION
SELECT (2000000000+groupnummer),
UPPER(CONCAT(CONCAT('cn=',groupnaam),',o=MyCompany,c=NL')),
2, 0, groupnummer FROM groups;
.fi
+
+.LP
+If your RDBMS does not support
+.B unions
+in views, only one objectClass can be mapped in
+.BR ldap_entries ,
+and the baseObject cannot be created; in this case, see the
+.B baseObject
+directive for a possible workaround.
+
.LP
.SH Typical SQL backend operation
Having metainformation loaded, the SQL backend uses these tables to
(!BER_BVISNULL( &(si)->sql_upper_func ))
#define BACKSQL_ALLOW_ORPHANS(si) \
((si)->sql_flags & BSQLF_ALLOW_ORPHANS)
+
+ Entry *sql_baseObject;
+#ifdef BACKSQL_ARBITRARY_KEY
+#define BACKSQL_BASEOBJECT_IDSTR "baseObject"
+#define BACKSQL_BASEOBJECT_KEYVAL BACKSQL_BASEOBJECT_IDSTR
+#define BACKSQL_IS_BASEOBJECT_ID(id) (bvmatch((id), &backsql_baseObject_bv)
+#else /* ! BACKSQL_ARBITRARY_KEY */
+#define BACKSQL_BASEOBJECT_ID 0
+#define BACKSQL_BASEOBJECT_IDSTR "0"
+#define BACKSQL_BASEOBJECT_KEYVAL 0
+#define BACKSQL_IS_BASEOBJECT_ID(id) (*(id) == BACKSQL_BASEOBJECT_ID)
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+#define BACKSQL_BASEOBJECT_OC 0
Avlnode *sql_db_conns;
Avlnode *sql_oc_by_oc;
return 1;
}
- dn = op->o_req_dn;
+ dn = op->o_req_ndn;
if ( backsql_api_dn2odbc( op, rs, &dn ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"backsql_api_dn2odbc failed\n",
goto return_results;
}
- dn = op->o_req_dn;
+ dn = op->o_req_ndn;
if ( backsql_api_dn2odbc( op, rs, &dn ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"backsql_api_dn2odbc failed\n",
#include <sys/types.h>
#include "slap.h"
+#include "ldif.h"
#include "proto-sql.h"
+static int
+create_baseObject(
+ BackendDB *be,
+ const char *fname,
+ int lineno );
+
+static int
+read_baseObject(
+ BackendDB *be,
+ const char *fname );
+
int
backsql_db_config(
BackendDB *be,
"allow_orphans=%s\n",
BACKSQL_ALLOW_ORPHANS( bi ) ? "yes" : "no", 0, 0 );
+ } else if ( !strcasecmp( argv[ 0 ], "baseobject" ) ) {
+ if ( be->be_suffix == NULL ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): : "
+ "must be defined after \"suffix\"\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+
+ if ( bi->sql_baseObject ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): : "
+ "\"baseObject\" already provided (will be overwritten)\n",
+ fname, lineno, 0 );
+ entry_free( bi->sql_baseObject );
+ }
+
+ switch ( argc ) {
+ case 1:
+ return create_baseObject( be, fname, lineno );
+
+ case 2:
+ return read_baseObject( be, argv[ 1 ] );
+
+ default:
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): "
+ "trailing values "
+ "in \"baseObject\" directive?\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+
} else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) {
if ( backsql_api_config( bi, argv[ 1 ] ) ) {
Debug( LDAP_DEBUG_TRACE,
return 0;
}
+/*
+ * Read the entries specified in fname and merge the attributes
+ * to the user defined baseObject entry. Note that if we find any errors
+ * what so ever, we will discard the entire entries, print an
+ * error message and return.
+ */
+static int
+read_baseObject(
+ BackendDB *be,
+ const char *fname )
+{
+ backsql_info *bi = (backsql_info *)be->be_private;
+ FILE *fp;
+ int rc = 0, lineno = 0, lmax = 0;
+ char *buf = NULL;
+
+ assert( fname );
+
+ fp = fopen( fname, "r" );
+ if ( fp == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "could not open back-sql baseObject attr file \"%s\" - absolute path?\n",
+ fname, 0, 0 );
+ perror( fname );
+ return LDAP_OTHER;
+ }
+
+ bi->sql_baseObject = (Entry *) SLAP_CALLOC( 1, sizeof(Entry) );
+ if ( bi->sql_baseObject == NULL ) {
+ Debug( LDAP_DEBUG_ANY,
+ "read_baseObject_file: SLAP_CALLOC failed", 0, 0, 0 );
+ fclose( fp );
+ return LDAP_NO_MEMORY;
+ }
+ bi->sql_baseObject->e_name = be->be_suffix[0];
+ bi->sql_baseObject->e_nname = be->be_nsuffix[0];
+ bi->sql_baseObject->e_attrs = NULL;
+
+ while ( ldif_read_record( fp, &lineno, &buf, &lmax ) ) {
+ Entry *e = str2entry( buf );
+ Attribute *a;
+
+ if( e == NULL ) {
+ fprintf( stderr, "back-sql baseObject: could not parse entry (line=%d)\n",
+ lineno );
+ rc = LDAP_OTHER;
+ break;
+ }
+
+ /* make sure the DN is the database's suffix */
+ if ( !be_issuffix( be, &e->e_nname ) ) {
+ fprintf( stderr,
+ "back-sql: invalid baseObject - dn=\"%s\" (line=%d)\n",
+ e->e_dn, lineno );
+ entry_free( e );
+ rc = EXIT_FAILURE;
+ break;
+ }
+
+ /*
+ * we found a valid entry, so walk thru all the attributes in the
+ * entry, and add each attribute type and description to baseObject
+ */
+ for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+ if ( attr_merge( bi->sql_baseObject, a->a_desc, a->a_vals,
+ ( a->a_nvals == a->a_vals ) ? NULL : a->a_nvals ) )
+ {
+ rc = LDAP_OTHER;
+ break;
+ }
+ }
+
+ entry_free( e );
+ if ( rc ) {
+ break;
+ }
+ }
+
+ if ( rc ) {
+ entry_free( bi->sql_baseObject );
+ bi->sql_baseObject = NULL;
+ }
+
+ ch_free( buf );
+
+ fclose( fp );
+
+ Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 );
+
+ return rc;
+}
+
+static int
+create_baseObject(
+ BackendDB *be,
+ const char *fname,
+ int lineno )
+{
+ backsql_info *bi = (backsql_info *)be->be_private;
+ LDAPRDN rdn;
+ char *p;
+ int rc, iAVA;
+ char buf[1024];
+
+ snprintf( buf, sizeof(buf),
+ "dn: %s\n"
+ "objectClass: extensibleObject\n"
+ "description: builtin baseObject for back-sql\n"
+ "description: all entries mapped in the \"ldap_entries\" table\n"
+ "description: must have \"" BACKSQL_BASEOBJECT_IDSTR "\" "
+ "in the \"parent\" column",
+ be->be_suffix[0].bv_val );
+
+ bi->sql_baseObject = str2entry( buf );
+ if ( bi->sql_baseObject == NULL ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): "
+ "unable to parse baseObject entry\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+
+ if ( BER_BVISEMPTY( &be->be_suffix[ 0 ] ) ) {
+ return 0;
+ }
+
+ rc = ldap_bv2rdn( &be->be_suffix[ 0 ], &rdn, (char **) &p, LDAP_DN_FORMAT_LDAP );
+ if ( rc != LDAP_SUCCESS ) {
+ snprintf( buf, sizeof(buf),
+ "unable to extract RDN from baseObject DN \"%s\" (%d: %s)",
+ be->be_suffix[ 0 ].bv_val, rc, ldap_err2string( rc ) );
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): %s\n",
+ fname, lineno, buf );
+ return 1;
+ }
+
+ for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
+ LDAPAVA *ava = rdn[ iAVA ];
+ AttributeDescription *ad = NULL;
+ slap_syntax_transform_func *transf = NULL;
+ struct berval bv = BER_BVNULL;
+ const char *text = NULL;
+
+ assert( ava );
+
+ rc = slap_bv2ad( &ava->la_attr, &ad, &text );
+ if ( rc != LDAP_SUCCESS ) {
+ snprintf( buf, sizeof(buf),
+ "AttributeDescription of naming "
+ "attribute #%d from baseObject "
+ "DN \"%s\": %d: %s",
+ iAVA, be->be_suffix[ 0 ].bv_val,
+ rc, ldap_err2string( rc ) );
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): %s\n",
+ fname, lineno, buf );
+ return 1;
+ }
+
+ transf = ad->ad_type->sat_syntax->ssyn_pretty;
+ if ( transf ) {
+ /*
+ * transform value by pretty function
+ * if value is empty, use empty_bv
+ */
+ rc = ( *transf )( ad->ad_type->sat_syntax,
+ ava->la_value.bv_len
+ ? &ava->la_value
+ : (struct berval *) &slap_empty_bv,
+ &bv, NULL );
+
+ if ( rc != LDAP_SUCCESS ) {
+ snprintf( buf, sizeof(buf),
+ "prettying of attribute #%d from baseObject "
+ "DN \"%s\" failed: %d: %s",
+ iAVA, be->be_suffix[ 0 ].bv_val,
+ rc, ldap_err2string( rc ) );
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): %s\n",
+ fname, lineno, buf );
+ return 1;
+ }
+ }
+
+ if ( !BER_BVISNULL( &bv ) ) {
+ if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) {
+ ber_memfree( ava->la_value.bv_val );
+ }
+ ava->la_value = bv;
+ ava->la_flags |= LDAP_AVA_FREE_VALUE;
+ }
+
+ attr_merge_normalize_one( bi->sql_baseObject,
+ ad, &ava->la_value, NULL );
+ }
+
+ ldap_rdnfree( rdn );
+
+ return 0;
+}
+
#endif /* SLAPD_SQL */
#include "slap.h"
#include "proto-sql.h"
+#ifdef BACKSQL_ARBITRARY_KEY
+struct berval backsql_baseObject_bv = BER_BVC( BACKSQL_BASEOBJECT_IDSTR );
+#endif /* BACKSQL_ARBITRARY_KEY */
+
backsql_entryID *
backsql_free_entryID( backsql_entryID *id, int freeit )
{
if ( id->eid_dn.bv_val != NULL ) {
free( id->eid_dn.bv_val );
+ BER_BVZERO( &id->eid_dn );
}
#ifdef BACKSQL_ARBITRARY_KEY
if ( id->eid_id.bv_val ) {
free( id->eid_id.bv_val );
+ BER_BVZERO( &id->eid_id );
}
if ( id->eid_keyval.bv_val ) {
free( id->eid_keyval.bv_val );
+ BER_BVZERO( &id->eid_keyval );
}
#endif /* BACKSQL_ARBITRARY_KEY */
dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
return LDAP_OTHER;
}
+
+ /* return baseObject if available and matches */
+ if ( bi->sql_baseObject != NULL && bvmatch( dn, &bi->sql_baseObject->e_nname ) ) {
+ if ( id != NULL ) {
+#ifdef BACKSQL_ARBITRARY_KEY
+ ber_dupbv( &id->eid_id, &backsql_baseObject_bv );
+ ber_dupbv( &id->eid_keyval, &backsql_baseObject_bv );
+#else /* ! BACKSQL_ARBITRARY_KEY */
+ id->eid_id = BACKSQL_BASEOBJECT_ID;
+ id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+ id->eid_oc_id = BACKSQL_BASEOBJECT_OC;
+
+ ber_dupbv( &id->eid_dn, &bi->sql_baseObject->e_nname );
+
+ id->eid_next = NULL;
+ }
+
+ return LDAP_SUCCESS;
+ }
/* begin TimesTen */
- Debug(LDAP_DEBUG_TRACE, "id_query \"%s\"\n", bi->sql_id_query, 0, 0);
+ Debug( LDAP_DEBUG_TRACE, "id_query \"%s\"\n", bi->sql_id_query, 0, 0 );
assert( bi->sql_id_query );
rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 );
if ( rc != SQL_SUCCESS ) {
int
backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid )
{
+ backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
int i;
int rc;
AttributeDescription *ad_oc = slap_schema.si_ad_objectClass;
memset( bsi->bsi_e, 0, sizeof( Entry ) );
+ if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
+ Entry *e;
+
+ e = entry_dup( bi->sql_baseObject );
+ if ( e == NULL ) {
+ return LDAP_NO_MEMORY;
+ }
+
+ *bsi->bsi_e = *e;
+ free( e );
+ goto done;
+ }
+
rc = dnPrettyNormal( NULL, &eid->eid_dn,
&bsi->bsi_e->e_name, &bsi->bsi_e->e_nname,
bsi->bsi_op->o_tmpmemctx );
}
}
+done:;
Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
return LDAP_SUCCESS;
free( bi->sql_delentry_query );
free( bi->sql_delobjclasses_query );
free( bi->sql_delreferrals_query );
+
+ if ( bi->sql_baseObject ) {
+ entry_free( bi->sql_baseObject );
+ }
+
free( bi );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_destroy()\n", 0, 0, 0 );
/*
* entry-id.c
*/
+#ifdef BACKSQL_ARBITRARY_KEY
+extern struct berval backsql_baseObject_bv;
+#endif /* BACKSQL_ARBITRARY_KEY */
/* stores in *id the ID in table ldap_entries corresponding to DN, if any */
int backsql_dn2id( backsql_info *bi, backsql_entryID *id,
bsi->bsi_filter_oc = NULL;
if ( get_base_id ) {
+ assert( op->o_bd->be_private );
+
rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private,
&bsi->bsi_base_id, dbh, base );
}
backsql_BindRowAsStrings( sth, &row );
rc = SQLFetch( sth );
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
- struct berval dn;
+ struct berval dn, ndn;
backsql_entryID *c_id = NULL;
+ int ret;
ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
continue;
}
+ ret = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
+ if ( dn.bv_val != row.cols[ 3 ] ) {
+ free( dn.bv_val );
+ }
+
+ if ( ret != LDAP_SUCCESS ) {
+ continue;
+ }
+
+ if ( bi->sql_baseObject && bvmatch( &ndn, &bi->sql_baseObject->e_nname ) ) {
+ free( ndn.bv_val );
+ continue;
+ }
+
c_id = (backsql_entryID *)ch_calloc( 1,
sizeof( backsql_entryID ) );
#ifdef BACKSQL_ARBITRARY_KEY
#endif /* ! BACKSQL_ARBITRARY_KEY */
c_id->eid_oc_id = bsi->bsi_oc->bom_id;
- if ( dn.bv_val == row.cols[ 3 ] ) {
- ber_dupbv( &c_id->eid_dn, &dn );
+ if ( ndn.bv_val == row.cols[ 3 ] ) {
+ ber_dupbv( &c_id->eid_dn, &ndn );
} else {
- c_id->eid_dn = dn;
+ c_id->eid_dn = ndn;
}
/* append at end of list ... */
Entry user_entry = { 0 };
int manageDSAit;
time_t stoptime = 0;
- backsql_srch_info srch_info;
+ backsql_srch_info bsi;
backsql_entryID *eid = NULL;
struct berval base;
/* compute it anyway; root does not use it */
stoptime = op->o_time + op->ors_tlimit;
- base = op->o_req_dn;
+ base = op->o_req_ndn;
if ( backsql_api_dn2odbc( op, rs, &base ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"backsql_api_dn2odbc failed\n",
}
/* init search */
- rs->sr_err = backsql_init_search( &srch_info, &base,
+ rs->sr_err = backsql_init_search( &bsi, &base,
op->ors_scope,
op->ors_slimit, op->ors_tlimit,
stoptime, op->ors_filter,
goto done;
}
- /*
- * for each objectclass we try to construct query which gets IDs
- * of entries matching LDAP query filter and scope (or at least
- * candidates), and get the IDs
- */
- srch_info.bsi_n_candidates =
- ( op->ors_limit == NULL /* isroot == FALSE */ ? -2 :
+ bsi.bsi_n_candidates =
+ ( op->ors_limit == NULL /* isroot == TRUE */ ? -2 :
( op->ors_limit->lms_s_unchecked == -1 ? -2 :
( op->ors_limit->lms_s_unchecked ) ) );
- avl_apply( bi->sql_oc_by_oc, backsql_oc_get_candidates,
- &srch_info, BACKSQL_AVL_STOP, AVL_INORDER );
- if ( op->ors_limit != NULL /* isroot == TRUE */
+
+ switch ( bsi.bsi_scope ) {
+ case LDAP_SCOPE_BASE:
+ case BACKSQL_SCOPE_BASE_LIKE:
+ /*
+ * probably already found...
+ */
+ bsi.bsi_id_list = &bsi.bsi_base_id;
+ bsi.bsi_id_listtail = &bsi.bsi_base_id.eid_next;
+ break;
+
+ case LDAP_SCOPE_SUBTREE:
+ /*
+ * if baseObject is defined, and if it is the root
+ * of the search, add it to the candidate list
+ */
+ if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &bsi.bsi_base_id.eid_id ) )
+ {
+ bsi.bsi_id_list = &bsi.bsi_base_id;
+ bsi.bsi_id_listtail = &bsi.bsi_base_id.eid_next;
+ }
+
+ /* FALLTHRU */
+ default:
+
+ /*
+ * for each objectclass we try to construct query which gets IDs
+ * of entries matching LDAP query filter and scope (or at least
+ * candidates), and get the IDs
+ */
+ avl_apply( bi->sql_oc_by_oc, backsql_oc_get_candidates,
+ &bsi, BACKSQL_AVL_STOP, AVL_INORDER );
+ }
+
+ if ( op->ors_limit != NULL /* isroot == FALSE */
&& op->ors_limit->lms_s_unchecked != -1
- && srch_info.bsi_n_candidates == -1 )
+ && bsi.bsi_n_candidates == -1 )
{
rs->sr_err = LDAP_ADMINLIMIT_EXCEEDED;
send_ldap_result( op, rs );
/*
* now we load candidate entries (only those attributes
* mentioned in attrs and filter), test it against full filter
- * and then send to client
+ * and then send to client; don't free entry_id if baseObject...
*/
- for ( eid = srch_info.bsi_id_list;
+ for ( eid = bsi.bsi_id_list;
eid != NULL;
- eid = backsql_free_entryID( eid, 1 ) )
+ eid = backsql_free_entryID( eid, eid == &bsi.bsi_base_id ? 0 : 1 ) )
{
int rc;
Attribute *hasSubordinate = NULL,
*a = NULL;
+ Entry *e = NULL;
/* check for abandon */
if ( op->o_abandon ) {
eid->eid_id, eid->eid_oc_id, eid->eid_keyval );
#endif /* ! BACKSQL_ARBITRARY_KEY */
- srch_info.bsi_e = &user_entry;
- rc = backsql_id2entry( &srch_info, eid );
- if ( rc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
- "error %d in backsql_id2entry() "
- "- skipping\n", rc, 0, 0 );
- continue;
+ /* don't recollect baseObject ... */
+ if ( BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) {
+ e = bi->sql_baseObject;
+
+ } else {
+ bsi.bsi_e = &user_entry;
+ rc = backsql_id2entry( &bsi, eid );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
+ "error %d in backsql_id2entry() "
+ "- skipping\n", rc, 0, 0 );
+ continue;
+ }
+
+ e = &user_entry;
}
/* check scope */
switch ( op->ors_scope ) {
case LDAP_SCOPE_BASE:
case BACKSQL_SCOPE_BASE_LIKE:
- if ( !bvmatch( &user_entry.e_nname, &op->o_req_ndn ) ) {
+ if ( !bvmatch( &e->e_nname, &op->o_req_ndn ) ) {
goto next_entry;
}
break;
}
case LDAP_SCOPE_SUBTREE:
- if ( !dnIsSuffix( &user_entry.e_nname, &op->o_req_ndn ) ) {
+ if ( !dnIsSuffix( &e->e_nname, &op->o_req_ndn ) ) {
goto next_entry;
}
break;
if ( !manageDSAit &&
op->ors_scope != LDAP_SCOPE_BASE &&
op->ors_scope != BACKSQL_SCOPE_BASE_LIKE &&
- is_entry_referral( &user_entry ) )
+ is_entry_referral( e ) )
{
BerVarray refs;
- refs = get_entry_referrals( op, &user_entry );
+ refs = get_entry_referrals( op, e );
if ( !refs ) {
- backsql_srch_info srch_info2 = { 0 };
+ backsql_srch_info bsi2 = { 0 };
Entry user_entry2 = { 0 };
/* retry with the full entry... */
- (void)backsql_init_search( &srch_info2,
- &user_entry.e_name,
+ (void)backsql_init_search( &bsi2,
+ &e->e_nname,
LDAP_SCOPE_BASE,
-1, -1, -1, NULL,
dbh, op, rs, NULL, 0 );
- srch_info2.bsi_e = &user_entry2;
- rc = backsql_id2entry( &srch_info2, eid );
+ bsi2.bsi_e = &user_entry2;
+ rc = backsql_id2entry( &bsi2, eid );
if ( rc == LDAP_SUCCESS ) {
if ( is_entry_referral( &user_entry2 ) )
{
if ( refs ) {
rs->sr_ref = referral_rewrite( refs,
- &user_entry.e_name,
+ &e->e_name,
&op->o_req_dn,
op->ors_scope );
ber_bvarray_free( refs );
* anyway; we should have used the frontend API function
* filter_has_subordinates()
*/
- if ( srch_info.bsi_flags & BSQL_SF_FILTER_HASSUBORDINATE ) {
- rc = backsql_has_children( bi, dbh, &user_entry.e_nname );
+ if ( bsi.bsi_flags & BSQL_SF_FILTER_HASSUBORDINATE ) {
+ rc = backsql_has_children( bi, dbh, &e->e_nname );
switch ( rc ) {
case LDAP_COMPARE_TRUE:
}
}
- if ( test_filter( op, &user_entry, op->ors_filter )
+ if ( test_filter( op, e, op->ors_filter )
== LDAP_COMPARE_TRUE ) {
- if ( hasSubordinate && !( srch_info.bsi_flags & BSQL_SF_ALL_OPER )
+ 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 );
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
- rs->sr_entry = &user_entry;
- rs->sr_flags = REP_ENTRY_MODIFIABLE;
+ rs->sr_entry = e;
+ if ( e == &user_entry ) {
+ rs->sr_flags = REP_ENTRY_MODIFIABLE;
+ }
sres = send_search_entry( op, rs );
rs->sr_entry = NULL;
rs->sr_attrs = NULL;
: LDAP_REFERRAL;
} else {
- rs->sr_err = srch_info.bsi_status;
+ rs->sr_err = bsi.bsi_status;
}
send_ldap_result( op, rs );
}
done:;
- if ( !BER_BVISNULL( &srch_info.bsi_base_id.eid_dn ) ) {
- (void)backsql_free_entryID( &srch_info.bsi_base_id, 0 );
+ if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
}
- if ( srch_info.bsi_attrs ) {
- ch_free( srch_info.bsi_attrs );
+ if ( bsi.bsi_attrs ) {
+ ch_free( bsi.bsi_attrs );
}
if ( base.bv_val != op->o_req_ndn.bv_val ) {