apply patches 1,2,3,5,8 (with changes) from ITS#3432)

This commit is contained in:
Pierangelo Masarati 2005-01-01 16:21:55 +00:00
parent 8ec78171d3
commit 642f7aed50
14 changed files with 524 additions and 158 deletions

View File

@ -57,7 +57,7 @@ backsql_modify_delete_all_values(
{
backsql_info *bi = (backsql_info *)op->o_bd->be_private;
RETCODE rc;
SQLHSTMT asth;
SQLHSTMT asth = SQL_NULL_HSTMT;
BACKSQL_ROW_NTS row;
assert( at );
@ -138,10 +138,10 @@ backsql_modify_delete_all_values(
/* first parameter no, parameter order */
SQLUSMALLINT pno, po;
/* procedure return code */
int prc;
int prc = LDAP_SUCCESS;
for ( i = 0; i < row.ncols; i++ ) {
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
ber_len_t col_len;
rc = backsql_Prepare( dbh, &sth, at->bam_delete_proc, 0 );
@ -248,19 +248,33 @@ backsql_modify_delete_all_values(
pno + 2 - po, row.cols[ i ],
at->bam_delete_proc );
rc = SQLExecute( sth );
if ( rc != SQL_SUCCESS ) {
if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
rs->sr_err = LDAP_SUCCESS;
} else {
Debug( LDAP_DEBUG_TRACE,
" backsql_modify_delete_all_values(): "
"delete_proc "
"execution failed\n",
0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env,
dbh, sth, rc );
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
"execution failed (rc=%d, prc=%d)\n",
rc, prc, 0 );
if ( prc != LDAP_SUCCESS ) {
/* SQL procedure executed fine
* but returned an error */
rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
SQLFreeStmt( sth, SQL_DROP );
rs->sr_text = "SQL-backend error";
return rs->sr_err = LDAP_OTHER;
return rs->sr_err;
} else {
backsql_PrintErrors( bi->sql_db_env, dbh,
sth, rc );
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) )
{
rs->sr_err = LDAP_OTHER;
rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
SQLFreeStmt( sth, SQL_DROP );
return rs->sr_err;
}
}
}
SQLFreeStmt( sth, SQL_DROP );
@ -283,7 +297,7 @@ backsql_modify_internal(
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
RETCODE rc;
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
Modifications *ml;
Debug( LDAP_DEBUG_TRACE, "==>backsql_modify_internal(): "
@ -306,7 +320,7 @@ backsql_modify_internal(
/* first parameter position, parameter order */
SQLUSMALLINT pno, po;
/* procedure return code */
int prc;
int prc = LDAP_SUCCESS;
ad = ml->sml_mod.sm_desc;
sm_op = ( ml->sml_mod.sm_op & LDAP_MOD_OP );
@ -578,6 +592,7 @@ add_only:;
!BER_BVISNULL( at_val );
i++, at_val++ )
{
prc = LDAP_SUCCESS;
rc = backsql_Prepare( dbh, &sth, at->bam_delete_proc, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
@ -667,19 +682,34 @@ add_only:;
"executing \"%s\"\n",
at->bam_delete_proc, 0, 0 );
rc = SQLExecute( sth );
if ( rc != SQL_SUCCESS ) {
if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS )
{
rs->sr_err = LDAP_SUCCESS;
} else {
Debug( LDAP_DEBUG_TRACE,
" backsql_modify_internal(): "
"delete_proc execution "
"failed\n", 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env,
dbh, sth, rc );
"failed (rc=%d, prc=%d)\n",
rc, prc, 0 );
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
SQLFreeStmt( sth, SQL_DROP );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error";
if ( prc != LDAP_SUCCESS ) {
/* SQL procedure executed fine
* but returned an error */
rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
rs->sr_text = at->bam_ad->ad_cname.bv_val;
goto done;
} else {
backsql_PrintErrors( bi->sql_db_env,
dbh, sth, rc );
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) )
{
SQLFreeStmt( sth, SQL_DROP );
rs->sr_err = LDAP_OTHER;
rs->sr_text = at->bam_ad->ad_cname.bv_val;
goto done;
}
}
}
SQLFreeStmt( sth, SQL_DROP );
@ -724,12 +754,8 @@ backsql_add_attr(
struct berval *at_val;
unsigned long i;
RETCODE rc;
/* first parameter #, parameter order */
SQLUSMALLINT pno, po;
/* procedure return code */
int prc;
SQLUSMALLINT currpos;
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
at_rec = backsql_ad2at( oc, at->a_desc );
@ -772,7 +798,11 @@ backsql_add_attr(
!BER_BVISNULL( at_val );
i++, at_val = &at->a_vals[ i ] )
{
char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
/* procedure return code */
int prc = LDAP_SUCCESS;
/* first parameter #, parameter order */
SQLUSMALLINT pno, po;
char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
/*
* Do not deal with the objectClass that is used
@ -875,17 +905,31 @@ backsql_add_attr(
at_rec->bam_add_proc, logbuf );
#endif
rc = SQLExecute( sth );
if ( rc != SQL_SUCCESS ) {
if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
rs->sr_err = LDAP_SUCCESS;
} else {
Debug( LDAP_DEBUG_TRACE,
" backsql_add_attr(\"%s\"): "
"add_proc execution failed\n",
op->oq_add.rs_e->e_name.bv_val, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
"add_proc execution failed (rc=%d, prc=%d)\n",
op->oq_add.rs_e->e_name.bv_val, rc, prc );
if ( prc != LDAP_SUCCESS ) {
/* SQL procedure executed fine
* but returned an error */
rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
SQLFreeStmt( sth, SQL_DROP );
rs->sr_text = "SQL-backend error";
return rs->sr_err = LDAP_OTHER;
return rs->sr_err;
} else {
backsql_PrintErrors( bi->sql_db_env, dbh,
sth, rc );
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = op->oq_add.rs_e->e_name.bv_val;
SQLFreeStmt( sth, SQL_DROP );
return rs->sr_err;
}
}
}
SQLFreeStmt( sth, SQL_DROP );
@ -898,8 +942,8 @@ int
backsql_add( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
SQLHDBC dbh;
SQLHSTMT sth;
SQLHDBC dbh = SQL_NULL_HDBC;
SQLHSTMT sth = SQL_NULL_HSTMT;
unsigned long new_keyval = 0;
RETCODE rc;
backsql_oc_map_rec *oc = NULL;
@ -909,6 +953,7 @@ backsql_add( Operation *op, SlapReply *rs )
*at_objectClass = NULL;
struct berval pdn;
struct berval realdn = BER_BVNULL;
int colnum;
#ifdef BACKSQL_SYNCPROV
/*
@ -1005,6 +1050,9 @@ backsql_add( Operation *op, SlapReply *rs )
/*
* Check if entry exists
*
* NOTE: backsql_api_dn2odbc() is called explicitly because
* we need the mucked DN to pass it to the create procedure.
*/
realdn = op->oq_add.rs_e->e_name;
if ( backsql_api_dn2odbc( op, rs, &realdn ) ) {
@ -1122,6 +1170,7 @@ backsql_add( Operation *op, SlapReply *rs )
goto done;
}
colnum = 1;
if ( BACKSQL_IS_ADD( oc->bom_expect_return ) ) {
rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &new_keyval );
if ( rc != SQL_SUCCESS ) {
@ -1137,6 +1186,27 @@ backsql_add( Operation *op, SlapReply *rs )
rs->sr_err = LDAP_OTHER;
goto done;
}
colnum++;
}
if ( oc->bom_create_hint ) {
at = attr_find( op->oq_add.rs_e->e_attrs, oc->bom_create_hint );
if ( at && at->a_vals ) {
backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
at->a_vals[0].bv_val,
at->a_vals[0].bv_len );
Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
"create_proc hint: param = '%s'\n",
at->a_vals[0].bv_val, 0, 0 );
} else {
backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT,
"", 0 );
Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
"create_proc hint (%s) not avalable\n",
oc->bom_create_hint->ad_cname.bv_val,
0, 0 );
}
}
Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): executing \"%s\"\n",

View File

@ -17,9 +17,25 @@
/* ACKNOWLEDGEMENTS:
* This work was initially developed by Dmitry Kovalev for inclusion
* by OpenLDAP Software. Additional significant contributors include
* Pierangelo Mararati
* Pierangelo Mararati
*/
/*
* Original copyright notice by Mark Adamson (applies to portions
* of code submitted as ITS#3432, and reworked by Pierangelo Masarati):
*
* The patch files are derived from OpenLDAP Software. All of the
* modifications to OpenLDAP Software represented in the following
* patches were developed by Mark Adamson (adamson@cmu.edu). These
* modifications are not subject to any license of Carnegie Mellon.
*
* The attached modifications to OpenLDAP Software are subject to the
* following notice:
*
* Copyright 2004 Mark Adamson
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP Public
* License.
*/
/*
* The following changes have been addressed:
*
@ -70,6 +86,102 @@
* - check how to allow multiple operations with one statement, to remove
* BACKSQL_REALLOC_STMT from modify.c (a more recent unixODBC lib?)
*/
/*
* Improvements submitted by (ITS#)
*
* 1. id_query.patch applied (with changes)
* 2. shortcut.patch applied (reworked)
* 3. create_hint.patch applied
* 4. count_query.patch rejected (conflicts with other features)
* 5. returncodes.patch applied (with sanity checks)
* 6. connpool.patch under evaluation
* 7. modoc.patch under evaluation
* 8. miscfixes.patch applied (reworked; FIXME: other
* operations may need to load the
* entire entry for ACL purposes)
*
* original description:
Changes that were made to the SQL backend.
The patches were made against 2.2.18 and can be applied individually,
but would best be applied in the numerical order of the file names.
A synopsis of each patch is given here:
1. Added an option to set SQL query for the "id_query" operation.
2. Added an option to the SQL backend called "use_subtree_shortcut".
When a search is performed, the SQL query includes a WHERE clause
which says the DN must be "LIKE %<searchbase>". The LIKE operation
can be slow in an RDBM. This shortcut option says that if the
searchbase of the LDAP search is the root DN of the SQL backend,
and thus all objects will match the LIKE operator, do not include
the "LIKE %<searchbase>" clause in the SQL query (it is replaced
instead by the always true "1=1" clause to keep the "AND"'s
working correctly). This option is off by default, and should be
turned on only if all objects to be found in the RDBM are under the
same root DN. Multiple backends working within the same RDBM table
space would encounter problems. LDAP searches whose searchbase are
not at the root DN will bypass this shortcut and employ the LIKE
clause.
3. Added a "create_hint" column to ldap_oc_mappings table. Allows
taking the value of an attr named in "create_hint" and passing it to
the create_proc procedure. This is necessary for when an objectClass's
table is partition indexed by some indexing column and thus the value
in that indexing column cannot change after the row is created. The
value for the indexed column is passed into the create_proc, which
uses it to fill in the indexed column as the new row is created.
4. When loading the values of an attribute, the count(*) of the number
of values is fetched first and memory is allocated for the array of
values and normalized values. The old system of loading the values one
by one and running realloc() on the array of values and normalized
values each time was badly fragmenting memory. The array of values and
normalized values would be side by side in memory, and realloc()'ing
them over and over would force them to leapfrog each other through all
of available memory. Attrs with a large number of values could not be
loaded without crashing the slapd daemon.
5. Added code to interpret the value returned by stored procedures
which have expect_return set. Returned value is interpreted as an LDAP
return code. This allows the distinction between the SQL failing to
execute and the SQL running to completion and returning an error code
which can indicate a policy violation.
6. Added RDBM connection pooling. Once an operation is finished the
connection to the RDBM is returned to a pool rather than closing.
Allows the next operation to skip the initialization and authentication
phases of contacting the RDBM. Also, if licensing with ODBC places
a limit on the number of connections, an LDAP thread can block waiting
for another thread to finish, so that no LDAP errors are returned
for having more LDAP connections than allowed RDBM connections. An
RDBM connection which receives an SQL error is marked as "tainted"
so that it will be closed rather than returned to the pool.
Also, RDBM connections must be bound to a given LDAP connection AND
operation number, and NOT just the connection number. Asynchronous
LDAP clients can have multiple simultaneous LDAP operations which
should not share the same RDBM connection. A given LDAP operation can
even make multiple SQL operations (e.g. a BIND operation which
requires SASL to perform an LDAP search to convert the SASL ID to an
LDAP DN), so each RDBM connection now has a refcount that must reach
zero before the connection is returned to the free pool.
7. Added ability to change the objectClass of an object. Required
considerable work to copy all attributes out of old object and into
new object. Does a schema check before proceeding. Creates a new
object, fills it in, deletes the old object, then changes the
oc_map_id and keyval of the entry in the "ldap_entries" table.
8. Generic fixes. Includes initializing pointers before they
get used in error branch cases, pointer checks before dereferencing,
resetting a return code to success after a COMPARE op, sealing
memory leaks, and in search.c, changing some of the "1=1" tests to
"2=2", "3=3", etc so that when reading slapd trace output, the
location in the source code where the x=x test was added to the SQL
can be easily distinguished.
*/
#ifndef __BACKSQL_H__
#define __BACKSQL_H__
@ -175,24 +287,25 @@ typedef struct backsql_oc_map_rec {
/*
* Structure of corresponding LDAP objectClass definition
*/
ObjectClass *bom_oc;
ObjectClass *bom_oc;
#define BACKSQL_OC_NAME(ocmap) ((ocmap)->bom_oc->soc_cname.bv_val)
struct berval bom_keytbl;
struct berval bom_keycol;
struct berval bom_keytbl;
struct berval bom_keycol;
/* expected to return keyval of newly created entry */
char *bom_create_proc;
char *bom_create_proc;
/* in case create_proc does not return the keyval of the newly
* created row */
char *bom_create_keyval;
char *bom_create_keyval;
/* supposed to expect keyval as parameter and delete
* all the attributes as well */
char *bom_delete_proc;
char *bom_delete_proc;
/* flags whether delete_proc is a function (whether back-sql
* should bind first parameter as output for return code) */
int bom_expect_return;
unsigned long bom_id;
Avlnode *bom_attrs;
int bom_expect_return;
unsigned long bom_id;
Avlnode *bom_attrs;
AttributeDescription *bom_create_hint;
} backsql_oc_map_rec;
/*
@ -278,6 +391,7 @@ typedef struct backsql_srch_info {
#define BSQL_SF_RETURN_ENTRYUUID (BSQL_SF_FILTER_ENTRYUUID << 8)
struct berval *bsi_base_ndn;
int bsi_use_subtree_shortcut;
backsql_entryID bsi_base_id;
int bsi_scope;
/* BACKSQL_SCOPE_BASE_LIKE can be set by API in ors_scope
@ -355,6 +469,7 @@ typedef struct {
#define BSQLF_DONTCHECK_LDAPINFO_DN_RU 0x0020
#define BSQLF_USE_REVERSE_DN 0x0040
#define BSQLF_ALLOW_ORPHANS 0x0080
#define BSQLF_USE_SUBTREE_SHORTCUT 0x0100
#define BACKSQL_SCHEMA_LOADED(si) \
((si)->sql_flags & BSQLF_SCHEMA_LOADED)
@ -374,6 +489,8 @@ typedef struct {
(!BER_BVISNULL( &(si)->sql_upper_func ))
#define BACKSQL_ALLOW_ORPHANS(si) \
((si)->sql_flags & BSQLF_ALLOW_ORPHANS)
#define BACKSQL_USE_SUBTREE_SHORTCUT(si) \
((si)->sql_flags & BSQLF_USE_SUBTREE_SHORTCUT)
Entry *sql_baseObject;
#ifdef BACKSQL_ARBITRARY_KEY
@ -404,7 +521,16 @@ typedef struct {
#define BACKSQL_AVL_STOP 0
#define BACKSQL_AVL_CONTINUE 1
/* see ldap.h for the meaning of the macros and of the values */
#define BACKSQL_LEGAL_ERROR( rc ) \
( LDAP_RANGE( (rc), 0x00, 0x0e ) \
|| LDAP_ATTR_ERROR( (rc) ) \
|| LDAP_NAME_ERROR( (rc) ) \
|| LDAP_SECURITY_ERROR( (rc) ) \
|| LDAP_SERVICE_ERROR( (rc) ) \
|| LDAP_UPDATE_ERROR( (rc) ) )
#define BACKSQL_SANITIZE_ERROR( rc ) \
( BACKSQL_LEGAL_ERROR( (rc) ) ? (rc) : LDAP_OTHER )
#endif /* __BACKSQL_H__ */

View File

@ -29,7 +29,7 @@
int
backsql_bind( Operation *op, SlapReply *rs )
{
SQLHDBC dbh;
SQLHDBC dbh = SQL_NULL_HDBC;
AttributeDescription *password = slap_schema.si_ad_userPassword;
Entry *e, user_entry;
Attribute *a;
@ -75,8 +75,9 @@ backsql_bind( Operation *op, SlapReply *rs )
anlist[1].an_name.bv_val = NULL;
rc = backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist,
( BACKSQL_ISF_GET_ID | BACKSQL_ISF_MUCK ) );
SLAP_NO_LIMIT, SLAP_NO_LIMIT,
(time_t)(-1), NULL, dbh, op, rs, anlist,
BACKSQL_ISF_GET_ID );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not retrieve bindDN ID - no such entry\n",

View File

@ -29,7 +29,7 @@
int
backsql_compare( Operation *op, SlapReply *rs )
{
SQLHDBC dbh;
SQLHDBC dbh = SQL_NULL_HDBC;
Entry *e = NULL, user_entry;
Attribute *a = NULL;
backsql_srch_info bsi;
@ -82,9 +82,11 @@ backsql_compare( Operation *op, SlapReply *rs )
user_entry.e_attrs = nrs.sr_operational_attrs;
} else {
rc = backsql_init_search( &bsi, &op->o_req_ndn, LDAP_SCOPE_BASE,
-1, -1, -1, NULL, dbh, op, rs, anlist,
( BACKSQL_ISF_GET_ID | BACKSQL_ISF_MUCK ) );
rc = backsql_init_search( &bsi, &op->o_req_ndn,
LDAP_SCOPE_BASE,
SLAP_NO_LIMIT, SLAP_NO_LIMIT,
(time_t)(-1), NULL, dbh, op, rs, anlist,
BACKSQL_ISF_GET_ID );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_compare(): "
"could not retrieve compareDN ID - no such entry\n",

View File

@ -441,6 +441,48 @@ backsql_db_config(
return 1;
}
} else if ( !strcasecmp( argv[ 0 ], "id_query" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL condition "
"in \"id_query\" directive\n",
fname, lineno, 0 );
return 1;
}
bi->sql_id_query = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"id_query=%s\n", bi->sql_id_query, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "use_subtree_shortcut") ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing { yes | no }"
"in \"use_subtree_shortcut\" directive\n",
fname, lineno, 0 );
return 1;
}
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT;
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
bi->sql_flags &= ~BSQLF_USE_SUBTREE_SHORTCUT;
} else {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"\"use_subtree_shortcut\" directive arg "
"must be \"yes\" or \"no\"\n",
fname, lineno, 0 );
return 1;
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"use_subtree_shortcut=%s\n",
BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ? "yes" : "no", 0, 0 );
} else {
return SLAP_CONF_UNKNOWN;
}

View File

@ -80,15 +80,16 @@ int
backsql_delete( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
SQLHDBC dbh;
SQLHSTMT sth;
SQLHDBC dbh = SQL_NULL_HDBC;
SQLHSTMT sth = SQL_NULL_HSTMT;
RETCODE rc;
int retval;
int prc = LDAP_SUCCESS;
backsql_oc_map_rec *oc = NULL;
backsql_entryID e_id = BACKSQL_ENTRYID_INIT;
Entry e;
/* first parameter no */
SQLUSMALLINT pno;
SQLUSMALLINT CompletionType = SQL_ROLLBACK;
Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry \"%s\"\n",
op->o_req_ndn.bv_val, 0, 0 );
@ -127,16 +128,17 @@ backsql_delete( Operation *op, SlapReply *rs )
rs->sr_err = backsql_has_children( bi, dbh, &op->o_req_ndn );
switch ( rs->sr_err ) {
case LDAP_COMPARE_FALSE:
rs->sr_err = LDAP_SUCCESS;
break;
case LDAP_COMPARE_TRUE:
Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "
"entry \"%s\" has children\n",
op->o_req_dn.bv_val, 0, 0 );
rs->sr_err = LDAP_NOT_ALLOWED_ON_NONLEAF;
rs->sr_text = "subtree delete not supported";
goto done;
case LDAP_COMPARE_FALSE:
break;
/* fallthru */
default:
goto done;
@ -182,7 +184,7 @@ backsql_delete( Operation *op, SlapReply *rs )
if ( BACKSQL_IS_DEL( oc->bom_expect_return ) ) {
pno = 1;
rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &retval );
rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &prc );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_delete(): "
@ -217,13 +219,26 @@ backsql_delete( Operation *op, SlapReply *rs )
}
rc = SQLExecute( sth );
if ( rc != SQL_SUCCESS ) {
if ( rc == SQL_SUCCESS && prc == LDAP_SUCCESS ) {
rs->sr_err = LDAP_SUCCESS;
} else {
Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "
"delete_proc execution failed\n", 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
"delete_proc execution failed (rc=%d, prc=%d)\n",
rc, prc, 0 );
if ( prc != LDAP_SUCCESS ) {
/* SQL procedure executed fine
* but returned an error */
rs->sr_err = BACKSQL_SANITIZE_ERROR( prc );
} else {
backsql_PrintErrors( bi->sql_db_env, dbh,
sth, rc );
rs->sr_err = LDAP_OTHER;
}
SQLFreeStmt( sth, SQL_DROP );
rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error";
goto done;
}
SQLFreeStmt( sth, SQL_DROP );
@ -371,6 +386,10 @@ backsql_delete( Operation *op, SlapReply *rs )
}
SQLFreeStmt( sth, SQL_DROP );
rs->sr_err = LDAP_SUCCESS;
done:;
/*
* Commit only if all operations succeed
*
@ -380,12 +399,11 @@ backsql_delete( Operation *op, SlapReply *rs )
* or if a single operation on an attribute fails
* for any reason
*/
SQLTransact( SQL_NULL_HENV, dbh,
op->o_noop ? SQL_ROLLBACK : SQL_COMMIT );
if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) {
CompletionType = SQL_COMMIT;
}
SQLTransact( SQL_NULL_HENV, dbh, CompletionType );
rs->sr_err = LDAP_SUCCESS;
done:;
send_ldap_result( op, rs );
Debug( LDAP_DEBUG_TRACE, "<==backsql_delete()\n", 0, 0, 0 );

View File

@ -114,7 +114,10 @@ backsql_dn2id(
}
/* return baseObject if available and matches */
if ( bi->sql_baseObject != NULL && dn_match( ndn, &bi->sql_baseObject->e_nname ) ) {
/* FIXME: if ndn is already mucked, we cannot check this */
if ( bi->sql_baseObject != NULL &&
dn_match( ndn, &bi->sql_baseObject->e_nname ) )
{
if ( id != NULL ) {
#ifdef BACKSQL_ARBITRARY_KEY
ber_dupbv( &id->eid_id, &backsql_baseObject_bv );
@ -164,7 +167,8 @@ backsql_dn2id(
* that can be searched using indexes
*/
for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--) {
for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--)
{
upperdn[ i ] = realndn.bv_val[ j ];
}
upperdn[ i ] = '\0';
@ -288,7 +292,7 @@ backsql_count_children(
struct berval *dn,
unsigned long *nchildren )
{
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
BACKSQL_ROW_NTS row;
RETCODE rc;
int res = LDAP_SUCCESS;
@ -391,7 +395,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
backsql_srch_info *bsi = v_bsi;
backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
RETCODE rc;
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
BACKSQL_ROW_NTS row;
int i;
@ -466,7 +470,7 @@ backsql_get_attr_vals( void *v_at, void *v_bsi )
*/
bv.bv_len = strlen( row.cols[ i ] );
#endif
backsql_entry_addattr( bsi->bsi_e,
backsql_entry_addattr( bsi->bsi_e,
&row.col_names[ i ], &bv,
bsi->bsi_op->o_tmpmemctx );

View File

@ -153,8 +153,7 @@ backsql_db_open(
BackendDB *bd )
{
backsql_info *bi = (backsql_info*)bd->be_private;
SQLHDBC dbh;
ber_len_t idq_len;
SQLHDBC dbh = SQL_NULL_HDBC;
struct berbuf bb = BB_NULL;
char opbuf[ OPERATION_BUFFER_SIZE ];
@ -398,34 +397,34 @@ backsql_db_open(
/*
* Prepare ID selection query
*/
bi->sql_id_query = NULL;
idq_len = 0;
if ( bi->sql_id_query == NULL ) {
/* no custom id_query provided */
if ( bi->sql_upper_func.bv_val == NULL ) {
backsql_strcat( &bb, backsql_id_query, "dn=?", NULL );
if ( bi->sql_upper_func.bv_val == NULL ) {
backsql_strcat( &bb, backsql_id_query, "dn=?", NULL );
} else {
if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
backsql_strcat( &bb, backsql_id_query,
"dn_ru=?", NULL );
} else {
if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
backsql_strfcat( &bb, "sbl",
backsql_id_query,
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" );
if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
backsql_strcat( &bb, backsql_id_query,
"dn_ru=?", NULL );
} else {
backsql_strfcat( &bb, "sblbcb",
backsql_id_query,
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(dn)=" ), "(dn)=",
&bi->sql_upper_func_open,
'?',
&bi->sql_upper_func_close );
if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
backsql_strfcat( &bb, "sbl",
backsql_id_query,
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" );
} else {
backsql_strfcat( &bb, "sblbcb",
backsql_id_query,
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(dn)=" ), "(dn)=",
&bi->sql_upper_func_open,
'?',
&bi->sql_upper_func_close );
}
}
}
bi->sql_id_query = bb.bb_val.bv_val;
}
bi->sql_id_query = bb.bb_val.bv_val;
/*
* Prepare children ID selection query

View File

@ -31,10 +31,10 @@ int
backsql_modify( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
SQLHDBC dbh;
SQLHDBC dbh = SQL_NULL_HDBC;
backsql_oc_map_rec *oc = NULL;
backsql_entryID e_id = BACKSQL_ENTRYID_INIT;
Entry e;
backsql_srch_info bsi = { 0 };
Entry e = { 0 };
/*
* FIXME: in case part of the operation cannot be performed
@ -58,26 +58,42 @@ backsql_modify( Operation *op, SlapReply *rs )
goto done;
}
rs->sr_err = backsql_dn2id( op, rs, &e_id, dbh, &op->o_req_ndn, 1 );
/* FIXME: using all attributes because of access control later ... */
rs->sr_err = backsql_init_search( &bsi, &op->o_req_ndn,
LDAP_SCOPE_BASE,
SLAP_NO_LIMIT, SLAP_NO_LIMIT,
(time_t)(-1), NULL, dbh, op, rs,
slap_anlist_all_attributes,
BACKSQL_ISF_GET_ID );
if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, " backsql_modify(): "
"could not lookup entry id\n", 0, 0, 0 );
rs->sr_text = ( rs->sr_err == LDAP_OTHER )
? "SQL-backend error" : NULL;
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
"could not retrieve modifyDN ID - no such entry\n",
0, 0, 0 );
rs->sr_err = LDAP_NO_SUCH_OBJECT;
goto done;
}
bsi.bsi_e = &e;
rs->sr_err = backsql_id2entry( &bsi, &bsi.bsi_base_id );
if ( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
"error %d in backsql_id2entry()\n",
rs->sr_err, 0, 0 );
goto done;
}
#ifdef BACKSQL_ARBITRARY_KEY
Debug( LDAP_DEBUG_TRACE, " backsql_modify(): "
"modifying entry \"%s\" (id=%s)\n",
e_id.eid_dn.bv_val, e_id.eid_id.bv_val, 0 );
bsi.bsi_base_id.eid_dn.bv_val,
bsi.bsi_base_id.eid_id.bv_val, 0 );
#else /* ! BACKSQL_ARBITRARY_KEY */
Debug( LDAP_DEBUG_TRACE, " backsql_modify(): "
"modifying entry \"%s\" (id=%ld)\n",
e_id.eid_dn.bv_val, e_id.eid_id, 0 );
bsi.bsi_base_id.eid_dn.bv_val, bsi.bsi_base_id.eid_id, 0 );
#endif /* ! BACKSQL_ARBITRARY_KEY */
oc = backsql_id2oc( bi, e_id.eid_oc_id );
oc = backsql_id2oc( bi, bsi.bsi_base_id.eid_oc_id );
if ( oc == NULL ) {
Debug( LDAP_DEBUG_TRACE, " backsql_modify(): "
"cannot determine objectclass of entry -- aborting\n",
@ -102,7 +118,8 @@ backsql_modify( Operation *op, SlapReply *rs )
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
} else {
rs->sr_err = backsql_modify_internal( op, rs, dbh, oc, &e_id,
rs->sr_err = backsql_modify_internal( op, rs, dbh, oc,
&bsi.bsi_base_id,
op->oq_modify.rs_modlist );
}
@ -116,6 +133,15 @@ backsql_modify( Operation *op, SlapReply *rs )
done:;
send_ldap_result( op, rs );
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
}
if ( bsi.bsi_e != NULL ) {
entry_clean( bsi.bsi_e );
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
return rs->sr_err != LDAP_SUCCESS ? rs->sr_err : op->o_noop;

View File

@ -31,8 +31,8 @@ int
backsql_modrdn( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info*)op->o_bd->be_private;
SQLHDBC dbh;
SQLHSTMT sth;
SQLHDBC dbh = SQL_NULL_HDBC;
SQLHSTMT sth = SQL_NULL_HSTMT;
RETCODE rc;
backsql_entryID e_id = BACKSQL_ENTRYID_INIT,
pe_id = BACKSQL_ENTRYID_INIT,

View File

@ -181,9 +181,10 @@ backsql_operational(
backsql_srch_info bsi;
rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname,
LDAP_SCOPE_BASE, -1, -1, -1, NULL,
dbh, op, rs, NULL,
( BACKSQL_ISF_GET_ID | BACKSQL_ISF_MUCK ) );
LDAP_SCOPE_BASE,
SLAP_NO_LIMIT, SLAP_NO_LIMIT,
(time_t)(-1), NULL, dbh, op, rs, NULL,
BACKSQL_ISF_GET_ID );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
"could not retrieve entry ID - no such entry\n",

View File

@ -160,8 +160,8 @@ int backsql_destroy_schema_map( backsql_info *si );
* search.c
*/
/* the function must collect the entry associated to nbase */
#define BACKSQL_ISF_GET_ID 0x1U
#define BACKSQL_ISF_MUCK 0x2U
int backsql_init_search( backsql_srch_info *bsi,
struct berval *nbase, int scope, int slimit, int tlimit,
time_t stoptime, Filter *filter, SQLHDBC dbh,

View File

@ -385,6 +385,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
backsql_BindRowAsStrings( bas->bas_sth, &at_row );
for ( ; rc = SQLFetch( bas->bas_sth ), BACKSQL_SUCCESS( rc ); ) {
const char *text = NULL;
char *next = NULL;
struct berval bv;
struct berbuf bb = BB_NULL;
@ -446,9 +447,15 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
at_map->bam_delete_proc = ch_strdup( at_row.cols[ 5 ] );
}
at_map->bam_param_order = strtol( at_row.cols[ 6 ],
NULL, 0 );
&next, 0 );
if ( next == at_row.cols[ 6 ] || next[0] != '\0' ) {
/* error */
}
at_map->bam_expect_return = strtol( at_row.cols[ 7 ],
NULL, 0 );
&next, 0 );
if ( next == at_row.cols[ 7 ] || next[0] != '\0' ) {
/* error */
}
backsql_make_attr_query( oc_map, at_map );
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_attr_mapping(): "
"preconstructed query \"%s\"\n",
@ -491,7 +498,7 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
int
backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
{
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
RETCODE rc;
BACKSQL_ROW_NTS oc_row;
unsigned long oc_id;
@ -573,6 +580,28 @@ backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
oc_map->bom_expect_return = strtol( oc_row.cols[ colnum + 1 ],
NULL, 0 );
colnum += 2;
if ( ( oc_row.ncols > colnum ) &&
( oc_row.value_len[ colnum ] > 0 ) )
{
const char *text;
oc_map->bom_create_hint = NULL;
rc = slap_str2ad( oc_row.cols[ colnum ],
&oc_map->bom_create_hint, &text );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"error matching "
"AttributeDescription %s "
"in create_hint: %s (%d)\n",
oc_row.cols[ colnum ],
text, rc );
backsql_PrintErrors( bi->sql_db_env, dbh,
sth, rc );
return LDAP_OTHER;
}
}
/*
* FIXME: first attempt to check for offending
* instructions in {create|delete}_proc
@ -593,22 +622,27 @@ backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
}
oc_id = oc_map->bom_id;
Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
"objectClass \"%s\": keytbl=\"%s\" keycol=\"%s\"\n",
"objectClass \"%s\":\n keytbl=\"%s\" keycol=\"%s\"\n",
BACKSQL_OC_NAME( oc_map ),
oc_map->bom_keytbl.bv_val, oc_map->bom_keycol.bv_val );
if ( oc_map->bom_create_proc ) {
Debug( LDAP_DEBUG_TRACE, "create_proc=\"%s\"\n",
Debug( LDAP_DEBUG_TRACE, " create_proc=\"%s\"\n",
oc_map->bom_create_proc, 0, 0 );
}
if ( oc_map->bom_create_keyval ) {
Debug( LDAP_DEBUG_TRACE, "create_keyval=\"%s\"\n",
Debug( LDAP_DEBUG_TRACE, " create_keyval=\"%s\"\n",
oc_map->bom_create_keyval, 0, 0 );
}
if ( oc_map->bom_create_hint ) {
Debug( LDAP_DEBUG_TRACE, " create_hint=\"%s\"\n",
oc_map->bom_create_hint->ad_cname.bv_val,
0, 0 );
}
if ( oc_map->bom_delete_proc ) {
Debug( LDAP_DEBUG_TRACE, "delete_proc=\"%s\"\n",
Debug( LDAP_DEBUG_TRACE, " delete_proc=\"%s\"\n",
oc_map->bom_delete_proc, 0, 0 );
}
Debug( LDAP_DEBUG_TRACE, "expect_return: "
Debug( LDAP_DEBUG_TRACE, " expect_return: "
"add=%d, del=%d; attributes:\n",
BACKSQL_IS_ADD( oc_map->bom_expect_return ),
BACKSQL_IS_DEL( oc_map->bom_expect_return ), 0 );

View File

@ -119,6 +119,7 @@ backsql_init_search(
int rc = LDAP_SUCCESS;
bsi->bsi_base_ndn = nbase;
bsi->bsi_use_subtree_shortcut = 0;
BER_BVZERO( &bsi->bsi_base_id.eid_dn );
BER_BVZERO( &bsi->bsi_base_id.eid_ndn );
bsi->bsi_scope = scope;
@ -194,8 +195,7 @@ backsql_init_search(
if ( flags & BACKSQL_ISF_GET_ID ) {
assert( op->o_bd->be_private );
rc = backsql_dn2id( op, rs, &bsi->bsi_base_id, dbh, nbase,
( flags & BACKSQL_ISF_MUCK ) );
rc = backsql_dn2id( op, rs, &bsi->bsi_base_id, dbh, nbase, 1 );
}
return ( bsi->bsi_status = rc );
@ -261,15 +261,17 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f,
/* always uppercase strings by now */
#ifdef BACKSQL_UPPERCASE_FILTER
if ( SLAP_MR_ASSOCIATED( f->f_sub_desc->ad_type->sat_substr,
bi->sql_caseIgnoreMatch ) )
if ( f->f_sub_desc->ad_type->sat_substr &&
SLAP_MR_ASSOCIATED( f->f_sub_desc->ad_type->sat_substr,
bi->sql_caseIgnoreMatch ) )
#endif /* BACKSQL_UPPERCASE_FILTER */
{
casefold = 1;
}
if ( SLAP_MR_ASSOCIATED( f->f_sub_desc->ad_type->sat_substr,
bi->sql_telephoneNumberMatch ) )
if ( f->f_sub_desc->ad_type->sat_substr &&
SLAP_MR_ASSOCIATED( f->f_sub_desc->ad_type->sat_substr,
bi->sql_telephoneNumberMatch ) )
{
struct berval bv;
@ -598,8 +600,8 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
backsql_merge_from_tbls( bsi, &ldap_entry_objclasses );
backsql_strfcat( &bsi->bsi_flt_where, "lbl",
(ber_len_t)STRLENOF( "1=1 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */ ),
"1=1 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */,
(ber_len_t)STRLENOF( "2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */ ),
"2=2 OR (ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */,
&bsi->bsi_oc->bom_oc->soc_cname,
(ber_len_t)STRLENOF( /* (' */ "')" ),
/* (' */ "')" );
@ -613,7 +615,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
case LDAP_FILTER_PRESENT:
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
(ber_len_t)STRLENOF( "3=3" ), "3=3" );
bsi->bsi_status = LDAP_SUCCESS;
rc = 1;
goto done;
@ -666,7 +668,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
case LDAP_FILTER_PRESENT:
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
(ber_len_t)STRLENOF( "4=4" ), "4=4" );
break;
default:
@ -696,7 +698,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
/* if doing a syncrepl, try to return as much as possible,
* and always match the filter */
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
(ber_len_t)STRLENOF( "5=5" ), "5=5" );
/* save for later use in operational attributes */
/* FIXME: saves only the first occurrence, because
@ -730,7 +732,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
* candidate.
*/
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
(ber_len_t)STRLENOF( "6=6" ), "6=6" );
if ( ad == slap_schema.si_ad_hasSubordinates ) {
/*
* instruct candidate selection algorithm
@ -763,7 +765,7 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
/* search anyway; other parts of the filter
* may succeeed */
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
(ber_len_t)STRLENOF( "7=7" ), "7=7" );
bsi->bsi_status = LDAP_SUCCESS;
rc = 1;
goto done;
@ -1015,10 +1017,13 @@ equality_match:;
/* fall thru to next case */
case LDAP_FILTER_LE:
filter_value = &f->f_av_value;
/* always uppercase strings by now */
#ifdef BACKSQL_UPPERCASE_FILTER
if ( SLAP_MR_ASSOCIATED( at->bam_ad->ad_type->sat_ordering,
bi->sql_caseIgnoreMatch ) )
if ( at->bam_ad->ad_type->sat_ordering &&
SLAP_MR_ASSOCIATED( at->bam_ad->ad_type->sat_ordering,
bi->sql_caseIgnoreMatch ) )
#endif /* BACKSQL_UPPERCASE_FILTER */
{
casefold = 1;
@ -1086,7 +1091,7 @@ equality_match:;
/* unhandled filter type; should not happen */
assert( 0 );
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
(ber_len_t)STRLENOF( "8=8" ), "8=8" );
break;
}
@ -1106,6 +1111,8 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
assert( query );
BER_BVZERO( query );
bsi->bsi_use_subtree_shortcut = 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_srch_query()\n", 0, 0, 0 );
BER_BVZERO( &bsi->bsi_sel.bb_val );
BER_BVZERO( &bsi->bsi_sel.bb_val );
@ -1205,11 +1212,40 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE:
if ( BACKSQL_CANUPPERCASE( bi ) ) {
if ( BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ) {
int i;
BackendDB *bd = bsi->bsi_op->o_bd;
assert( bd->be_nsuffix );
for ( i = 0; !BER_BVISNULL( &bd->be_nsuffix[ i ] ); i++ )
{
if ( dn_match( &bd->be_nsuffix[ i ],
bsi->bsi_base_ndn ) )
{
/* pass this to the candidate selection
* routine so that the DN is not bound
* to the select statement */
bsi->bsi_use_subtree_shortcut = 1;
break;
}
}
}
if ( bsi->bsi_use_subtree_shortcut ) {
/* Skip the base DN filter, as every entry will match it */
backsql_strfcat( &bsi->bsi_join_where, "l",
(ber_len_t)STRLENOF( "9=9"), "9=9");
} else if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
backsql_strfcat( &bsi->bsi_join_where, "b", &bi->sql_subtree_cond );
} else if ( BACKSQL_CANUPPERCASE( bi ) ) {
backsql_strfcat( &bsi->bsi_join_where, "bl",
&bi->sql_upper_func,
(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ),
"(ldap_entries.dn) LIKE ?" );
} else {
backsql_strfcat( &bsi->bsi_join_where, "l",
(ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ),
@ -1270,7 +1306,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
backsql_srch_info *bsi = v_bsi;
backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
struct berval query;
SQLHSTMT sth;
SQLHSTMT sth = SQL_NULL_HSTMT;
RETCODE rc;
int res;
BACKSQL_ROW_NTS row;
@ -1402,6 +1438,12 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE:
{
/* if short-cutting the search base,
* don't bind any parameter */
if ( bsi->bsi_use_subtree_shortcut ) {
break;
}
/*
* We do not accept DNs longer than BACKSQL_MAX_DN_LEN;
* however this should be handled earlier
@ -1595,7 +1637,7 @@ int
backsql_search( Operation *op, SlapReply *rs )
{
backsql_info *bi = (backsql_info *)op->o_bd->be_private;
SQLHDBC dbh;
SQLHDBC dbh = SQL_NULL_HDBC;
int sres;
Entry user_entry = { 0 };
int manageDSAit;
@ -1610,7 +1652,7 @@ backsql_search( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): "
"base=\"%s\", filter=\"%s\", scope=%d,",
op->o_req_ndn.bv_val,
op->ors_filterstr.bv_val,
op->ors_filterstr.bv_val ? op->ors_filterstr.bv_val : "(no filter)",
op->ors_scope );
Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, "
"attributes to load: %s\n",
@ -1663,7 +1705,7 @@ backsql_search( Operation *op, SlapReply *rs )
op->ors_slimit, op->ors_tlimit,
stoptime, op->ors_filter,
dbh, op, rs, op->ors_attrs,
( BACKSQL_ISF_GET_ID | BACKSQL_ISF_MUCK ) );
BACKSQL_ISF_GET_ID );
if ( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
goto done;
@ -1831,9 +1873,9 @@ backsql_search( Operation *op, SlapReply *rs )
(void)backsql_init_search( &bsi2,
&e->e_nname,
LDAP_SCOPE_BASE,
-1, -1, -1, NULL,
dbh, op, rs, NULL,
BACKSQL_ISF_MUCK );
SLAP_NO_LIMIT, SLAP_NO_LIMIT,
(time_t)(-1), NULL,
dbh, op, rs, NULL, 0 );
bsi2.bsi_e = &user_entry2;
rc = backsql_id2entry( &bsi2, eid );
if ( rc == LDAP_SUCCESS ) {
@ -2054,7 +2096,7 @@ backsql_entry_get(
Entry **ent )
{
backsql_srch_info bsi;
SQLHDBC dbh;
SQLHDBC dbh = SQL_NULL_HDBC;
int rc;
SlapReply rs = { 0 };
AttributeName anlist[ 2 ];
@ -2073,9 +2115,10 @@ backsql_entry_get(
rc = backsql_init_search( &bsi,
ndn,
LDAP_SCOPE_BASE,
SLAP_NO_LIMIT, SLAP_NO_LIMIT, -1, NULL,
SLAP_NO_LIMIT, SLAP_NO_LIMIT,
(time_t)(-1), NULL,
dbh, op, &rs, at ? anlist : NULL,
( BACKSQL_ISF_GET_ID | BACKSQL_ISF_MUCK ) );
BACKSQL_ISF_GET_ID );
if ( rc != LDAP_SUCCESS ) {
return rc;
}