* if not attempting to add entry at suffix or with parent ""
*/
if ( ( ( !be_isroot( op ) && !be_shadow_update( op ) )
- || !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e ) )
+ || !BER_BVISEMPTY( &pdn ) ) && !is_entry_glue( op->oq_add.rs_e )
+ && !BACKSQL_ALLOW_ORPHANS( bi ) )
{
Debug( LDAP_DEBUG_TRACE, " backsql_add: %s denied\n",
BER_BVISEMPTY( &pdn ) ? "suffix" : "entry at root",
ch_free( realpdn.bv_val );
}
if ( !BER_BVISNULL( &parent_id.eid_dn ) ) {
- backsql_free_entryID( &parent_id, 0 );
+ (void)backsql_free_entryID( &parent_id, 0 );
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n",
* define to enable very extensive trace logging (debug only)
*/
#undef BACKSQL_TRACE
+#define BACKSQL_TRACE
/*
* define to enable varchars as unique keys in user tables
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002
struct berval *bsi_base_dn;
+ backsql_entryID bsi_base_id;
int bsi_scope;
#define BACKSQL_SCOPE_BASE_LIKE ( LDAP_SCOPE_BASE | 0x1000 )
Filter *bsi_filter;
#define BSQLF_HAS_LDAPINFO_DN_RU 0x0010
#define BSQLF_DONTCHECK_LDAPINFO_DN_RU 0x0020
#define BSQLF_USE_REVERSE_DN 0x0040
+#define BSQLF_ALLOW_ORPHANS 0x0080
#define BACKSQL_SCHEMA_LOADED(si) \
((si)->bsql_flags & BSQLF_SCHEMA_LOADED)
((si)->bsql_flags & BSQLF_USE_REVERSE_DN)
#define BACKSQL_CANUPPERCASE(si) \
((si)->upper_func.bv_val)
+#define BACKSQL_ALLOW_ORPHANS(si) \
+ ((si)->bsql_flags & BSQLF_ALLOW_ORPHANS)
struct berval strcast_func;
Avlnode *db_conns;
int
backsql_bind( Operation *op, SlapReply *rs )
{
- backsql_info *bi = (backsql_info*)op->o_bd->be_private;
- backsql_entryID user_id = BACKSQL_ENTRYID_INIT;
SQLHDBC dbh;
AttributeDescription *password = slap_schema.si_ad_userPassword;
Entry *e, user_entry;
goto error_return;
}
- rc = backsql_dn2id( bi, &user_id, dbh, &dn );
+ anlist[0].an_name = password->ad_cname;
+ anlist[0].an_desc = password;
+ anlist[1].an_name.bv_val = NULL;
+
+ rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
+ -1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not retrieve bind dn id - no such entry\n",
return 1;
}
- anlist[0].an_name = password->ad_cname;
- anlist[0].an_desc = password;
- anlist[1].an_name.bv_val = NULL;
-
- backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
- -1, -1, -1, NULL, dbh, op, rs, anlist );
bsi.bsi_e = &user_entry;
- rc = backsql_id2entry( &bsi, &user_id );
+ rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"error %d in backsql_id2entry() "
}
error_return:;
+ if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+ }
+
if ( rs->sr_err ) {
send_ldap_result( op, rs );
return 1;
int
backsql_compare( Operation *op, SlapReply *rs )
{
- backsql_info *bi = (backsql_info*)op->o_bd->be_private;
- backsql_entryID user_id = BACKSQL_ENTRYID_INIT;
SQLHDBC dbh;
Entry *e = NULL, user_entry;
Attribute *a = NULL;
goto return_results;
}
- rc = backsql_dn2id( bi, &user_id, dbh, &dn );
- if ( rc != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
- "could not retrieve compare dn id - no such entry\n",
- 0, 0, 0 );
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
- goto return_results;
- }
-
memset( &anlist[0], 0, 2 * sizeof( AttributeName ) );
anlist[0].an_name = op->oq_compare.rs_ava->aa_desc->ad_cname;
anlist[0].an_desc = op->oq_compare.rs_ava->aa_desc;
user_entry.e_attrs = nrs.sr_operational_attrs;
} else {
- backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
- -1, -1, -1, NULL, dbh, op, rs, anlist );
+ rc = backsql_init_search( &bsi, &dn, LDAP_SCOPE_BASE,
+ -1, -1, -1, NULL, dbh, op, rs, anlist, 1 );
+ if ( rc != LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
+ "could not retrieve compare dn id - no such entry\n",
+ 0, 0, 0 );
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ goto return_results;
+ }
+
bsi.bsi_e = &user_entry;
- rc = backsql_id2entry( &bsi, &user_id );
+ rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"error %d in backsql_id2entry() "
return_results:;
send_ldap_result( op, rs );
+ if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_dn ) ) {
+ (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
+ }
+
if ( dn.bv_val != op->o_req_dn.bv_val ) {
ch_free( dn.bv_val );
}
"fail_if_no_mapping=%s\n",
BACKSQL_FAIL_IF_NO_MAPPING( si ) ? "yes" : "no", 0, 0 );
+ } else if ( !strcasecmp( argv[ 0 ], "allow_orphans") ) {
+ if ( argc < 2 ) {
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): "
+ "missing { yes | no }"
+ "in \"allow_orphans\" directive\n",
+ fname, lineno, 0 );
+ return 1;
+ }
+
+ if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
+ si->bsql_flags |= BSQLF_ALLOW_ORPHANS;
+
+ } else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
+ si->bsql_flags &= ~BSQLF_ALLOW_ORPHANS;
+
+ } else {
+ Debug( LDAP_DEBUG_TRACE,
+ "<==backsql_db_config (%s line %d): "
+ "\"allow_orphans\" directive arg "
+ "must be \"yes\" or \"no\"\n",
+ fname, lineno, 0 );
+ return 1;
+
+ }
+ Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
+ "allow_orphans=%s\n",
+ BACKSQL_ALLOW_ORPHANS( si ) ? "yes" : "no", 0, 0 );
+
} else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) {
if ( backsql_api_config( si, argv[ 1 ] ) ) {
Debug( LDAP_DEBUG_TRACE,
"old parent entry id is %ld\n", pe_id.eid_id, 0, 0 );
#endif /* ! BACKSQL_ARBITRARY_KEY */
- backsql_free_entryID( &pe_id, 0 );
+ (void)backsql_free_entryID( &pe_id, 0 );
rs->sr_err = backsql_dn2id( bi, &new_pe_id, dbh, new_npdn );
if ( rs->sr_err != LDAP_SUCCESS ) {
}
if ( new_pe_id.eid_dn.bv_val ) {
- backsql_free_entryID( &new_pe_id, 0 );
+ (void)backsql_free_entryID( &new_pe_id, 0 );
}
send_ldap_result( op, rs );
* search.c
*/
-void backsql_init_search( backsql_srch_info *bsi,
+int backsql_init_search( backsql_srch_info *bsi,
struct berval *nbase, int scope, int slimit, int tlimit,
time_t stoptime, Filter *filter, SQLHDBC dbh,
- Operation *op, SlapReply *rs, AttributeName *attrs );
+ Operation *op, SlapReply *rs, AttributeName *attrs,
+ int get_base_id );
/*
* sql-wrap.h
return 1;
}
-void
+/*
+ * Initializes the search structure.
+ *
+ * If get_base_id != 0, the field bsi_base_id is filled
+ * with the entryID of bsi_base_dn; it must be freed
+ * by backsql_free_entryID() when no longer required.
+ */
+int
backsql_init_search(
backsql_srch_info *bsi,
struct berval *base,
SQLHDBC dbh,
Operation *op,
SlapReply *rs,
- AttributeName *attrs )
+ AttributeName *attrs,
+ int get_base_id )
{
AttributeName *p;
+ int rc = LDAP_SUCCESS;
bsi->bsi_base_dn = base;
+ BER_BVZERO( &bsi->bsi_base_id.eid_dn );
bsi->bsi_scope = scope;
bsi->bsi_slimit = slimit;
bsi->bsi_tlimit = tlimit;
bsi->bsi_attrs = NULL;
} else {
- int is_oc = 0;
+ int got_oc = 0;
bsi->bsi_attrs = (AttributeName *)ch_calloc( 1,
sizeof( AttributeName ) );
continue;
} else if ( p->an_desc == slap_schema.si_ad_objectClass ) {
- is_oc = 1;
+ got_oc = 1;
}
backsql_attrlist_add( bsi, p->an_desc );
}
- if ( is_oc == 0 ) {
+ if ( got_oc == 0 ) {
/* add objectClass if not present,
* because it is required to understand
* if an entry is a referral, an alias
bsi->bsi_flt_where.bb_len = 0;
bsi->bsi_filter_oc = NULL;
- bsi->bsi_status = LDAP_SUCCESS;
+ if ( get_base_id ) {
+ rc = backsql_dn2id( (backsql_info *)op->o_bd->be_private,
+ &bsi->bsi_base_id, dbh, base );
+ }
+
+ return ( bsi->bsi_status = rc );
}
static int
struct berval query;
SQLHSTMT sth;
RETCODE rc;
- backsql_entryID base_id = BACKSQL_ENTRYID_INIT;
int res;
BACKSQL_ROW_NTS row;
int i;
}
case LDAP_SCOPE_ONELEVEL:
- res = backsql_dn2id( bi, &base_id,
- bsi->bsi_dbh, bsi->bsi_base_dn );
- if ( res != LDAP_SUCCESS ) {
- Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
- "could not retrieve base_dn id%s\n",
- res == LDAP_NO_SUCH_OBJECT ? ": no such entry"
- : "", 0, 0 );
- bsi->bsi_status = res;
- return BACKSQL_AVL_CONTINUE;
- }
+ assert( !BER_BVISNULL( &bsi->bsi_base_id.eid_dn ) );
#ifdef BACKSQL_ARBITRARY_KEY
Debug( LDAP_DEBUG_TRACE, "(one)id: \"%s\"\n",
- base_id.eid_id.bv_val, 0, 0 );
+ bsi->bsi_base_id.eid_id.bv_val, 0, 0 );
#else /* ! BACKSQL_ARBITRARY_KEY */
- Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n", base_id.eid_id,
- 0, 0 );
+ Debug( LDAP_DEBUG_TRACE, "(one)id: '%lu'\n",
+ bsi->bsi_base_id.eid_id, 0, 0 );
#endif /* ! BACKSQL_ARBITRARY_KEY */
rc = backsql_BindParamID( sth, 2, SQL_PARAM_INPUT,
- &base_id.eid_id );
- backsql_free_entryID( &base_id, 0 );
+ &bsi->bsi_base_id.eid_id );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
"error binding base id parameter\n", 0, 0, 0 );
return 1;
}
- backsql_init_search( &srch_info, &base,
+ /* init search */
+ rs->sr_err = backsql_init_search( &srch_info, &base,
op->ors_scope,
op->ors_slimit, op->ors_tlimit,
stoptime, op->ors_filter,
- dbh, op, rs, op->ors_attrs );
+ dbh, op, rs, op->ors_attrs, 1 );
+ if ( rs->sr_err != LDAP_SUCCESS ) {
+ send_ldap_result( op, rs );
+ goto done;
+ }
/*
* for each objectclass we try to construct query which gets IDs
send_ldap_result( op, rs );
goto done;
}
-
+
/*
* now we load candidate entries (only those attributes
* mentioned in attrs and filter), test it against full filter
is_entry_referral( &user_entry ) )
{
BerVarray refs;
- struct berval matched_dn;
- ber_dupbv( &matched_dn, &user_entry.e_name );
refs = get_entry_referrals( op, &user_entry );
if ( !refs ) {
backsql_srch_info srch_info2 = { 0 };
Entry user_entry2 = { 0 };
/* retry with the full entry... */
- backsql_init_search( &srch_info2,
+ (void)backsql_init_search( &srch_info2,
&user_entry.e_name,
LDAP_SCOPE_BASE,
-1, -1, -1, NULL,
- dbh, op, rs, NULL );
+ dbh, op, rs, NULL, 0 );
srch_info2.bsi_e = &user_entry2;
rc = backsql_id2entry( &srch_info2, eid );
if ( rc == LDAP_SUCCESS ) {
if ( refs ) {
rs->sr_ref = referral_rewrite( refs,
- &matched_dn, &op->o_req_dn,
+ &user_entry.e_name,
+ &op->o_req_dn,
op->ors_scope );
ber_bvarray_free( refs );
}
}
rs->sr_err = LDAP_REFERRAL;
- rs->sr_matched = matched_dn.bv_val;
+ rs->sr_matched = user_entry.e_name.bv_val;
send_search_reference( op, rs );
ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
- ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
goto next_entry;
}
done:;
- ch_free( srch_info.bsi_attrs );
+ if ( !BER_BVISNULL( &srch_info.bsi_base_id.eid_dn ) ) {
+ (void)backsql_free_entryID( &srch_info.bsi_base_id, 0 );
+ }
+
+ if ( srch_info.bsi_attrs ) {
+ ch_free( srch_info.bsi_attrs );
+ }
+
if ( base.bv_val != op->o_req_ndn.bv_val ) {
ch_free( base.bv_val );
}