- re-style according to the style giudelines for better readability
- updated to recent frontend/backend API changes
- fixed a few quirks about normalization
- "optimized" a few memory allocation/string handling functions
- fixed a few quirks about add/modify (still have to look ad modrdn)

todo:
- there is still something broken (at least with PostgreSQL and IBM db2,
  the two RDBMS O have at hand) when adding
- move everything to struct bervals and try to save a few strlen
- try some LDAP/SQL syntax relation to use appropriate value bind if possible
- ...
This commit is contained in:
Pierangelo Masarati 2002-08-13 17:12:27 +00:00
parent 7c2de5721a
commit 115408986c
17 changed files with 3673 additions and 2442 deletions

View File

@ -10,35 +10,47 @@
* in file LICENSE in the top-level directory of the distribution.
*/
#include "external.h"
#include "sql-types.h"
#define BACKSQL_MAX_DN_LEN 255
typedef struct
{
char *dbhost;
int dbport;
char *dbuser;
char *dbpasswd;
char *dbname;
/*SQL condition for subtree searches differs in syntax:
*"LIKE CONCAT('%',?)" or "LIKE '%'+?" or smth else */
char *subtree_cond;
char *oc_query,*at_query;
char *insentry_query,*delentry_query;
char *id_query;
char *upper_func;
Avlnode *db_conns;
Avlnode *oc_by_name;
Avlnode *oc_by_id;
int schema_loaded;
ldap_pvt_thread_mutex_t dbconn_mutex;
ldap_pvt_thread_mutex_t schema_mutex;
SQLHENV db_env;
int isTimesTen; /* TimesTen */
int has_ldapinfo_dn_ru; /* Does ldapinfo.dn_ru exist in schema? */
}backsql_info;
/*
* Better use the standard length of 8192 (as of servers/slapd/dn.c) ?
*/
#define BACKSQL_MAX_DN_LEN 255
#endif
typedef struct {
char *dbhost;
int dbport;
char *dbuser;
char *dbpasswd;
char *dbname;
/*
* SQL condition for subtree searches differs in syntax:
* "LIKE CONCAT('%',?)" or "LIKE '%'+?" or smth else
*/
char *subtree_cond;
char *oc_query,*at_query;
char *insentry_query,*delentry_query;
char *id_query;
char *upper_func;
char *strcast_func;
Avlnode *db_conns;
Avlnode *oc_by_name;
Avlnode *oc_by_id;
int schema_loaded;
ldap_pvt_thread_mutex_t dbconn_mutex;
ldap_pvt_thread_mutex_t schema_mutex;
SQLHENV db_env;
int isTimesTen;
/*
* Does ldapinfo.dn_ru exist in schema?
*/
int has_ldapinfo_dn_ru;
} backsql_info;
#define BACKSQL_SUCCESS( rc ) \
( (rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO )
#endif /* __BACKSQL_H__ */

View File

@ -19,91 +19,111 @@
#include "util.h"
#include "entry-id.h"
int backsql_bind(BackendDB *be,Connection *conn,Operation *op,
struct berval *dn,struct berval *ndn,int method,struct berval *cred,struct berval *edn)
int
backsql_bind(
BackendDB *be,
Connection *conn,
Operation *op,
struct berval *dn,
struct berval *ndn,
int method,
struct berval *cred,
struct berval *edn )
{
backsql_info *bi=(backsql_info*)be->be_private;
backsql_entryID user_id,*res;
SQLHDBC dbh;
AttributeDescription *password = slap_schema.si_ad_userPassword;
Entry *e,user_entry;
Attribute *a;
backsql_srch_info bsi;
backsql_info *bi = (backsql_info*)be->be_private;
backsql_entryID user_id;
SQLHDBC dbh;
AttributeDescription *password = slap_schema.si_ad_userPassword;
Entry *e, user_entry;
Attribute *a;
backsql_srch_info bsi;
Debug(LDAP_DEBUG_TRACE,"==>backsql_bind()\n",0,0,0);
if ( be_isroot_pw( be, conn, ndn, cred ) )
{
ber_dupbv(edn, be_root_dn(be));
Debug(LDAP_DEBUG_TRACE,"<==backsql_bind() root bind\n",0,0,0);
return LDAP_SUCCESS;
}
ber_dupbv(edn, ndn);
if (method == LDAP_AUTH_SIMPLE)
{
dbh=backsql_get_db_conn(be,conn);
Debug( LDAP_DEBUG_TRACE, "==>backsql_bind()\n", 0, 0, 0 );
if (!dbh)
{
Debug(LDAP_DEBUG_TRACE,"backsql_bind(): could not get connection handle - exiting\n",0,0,0);
send_ldap_result(conn,op,LDAP_OTHER,"","SQL-backend error",NULL,NULL);
return 1;
}
res=backsql_dn2id(bi,&user_id,dbh,ndn->bv_val);
if (res==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_bind(): could not retrieve bind dn id - no such entry\n",0,0,0);
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,NULL, NULL, NULL, NULL );
return 1;
}
backsql_init_search(&bsi,bi,(char*)ndn->bv_val,LDAP_SCOPE_BASE,-1,-1,-1,NULL,dbh,
be,conn,op,NULL);
e=backsql_id2entry(&bsi,&user_entry,&user_id);
if (e==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_bind(): error in backsql_id2entry() - auth failed\n",0,0,0);
send_ldap_result( conn, op, LDAP_OTHER,NULL, NULL, NULL, NULL );
return 1;
}
if ( ! access_allowed( be, conn, op, e, password, NULL, ACL_AUTH, NULL ) )
{
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, NULL, NULL, NULL, NULL );
return 1;
}
if ( be_isroot_pw( be, conn, ndn, cred ) ) {
ber_dupbv( edn, be_root_dn( be ) );
Debug( LDAP_DEBUG_TRACE, "<==backsql_bind() root bind\n",
0, 0, 0 );
return LDAP_SUCCESS;
}
if ( (a = attr_find( e->e_attrs, password )) == NULL )
{
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH, NULL, NULL, NULL, NULL );
return 1;
}
ber_dupbv( edn, ndn );
if ( slap_passwd_check( conn, a, cred ) != 0 )
{
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,NULL, NULL, NULL, NULL );
return 1;
}
}
else /*method != SIMPLE */
{
send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
NULL, "authentication method not supported", NULL, NULL );
return 1;
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);
return 0;
if ( method != LDAP_AUTH_SIMPLE ) {
send_ldap_result( conn, op, LDAP_STRONG_AUTH_NOT_SUPPORTED,
NULL, "authentication method not supported",
NULL, NULL );
return 1;
}
/*
* method = LDAP_AUTH_SIMPLE
*/
dbh = backsql_get_db_conn( be, conn );
if (!dbh) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not get connection handle - exiting\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OTHER, "",
"SQL-backend error", NULL, NULL );
return 1;
}
if ( backsql_dn2id( bi, &user_id, dbh, ndn ) != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"could not retrieve bind dn id - no such entry\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
NULL, NULL, NULL, NULL );
return 1;
}
backsql_init_search( &bsi, bi, ndn, LDAP_SCOPE_BASE, -1, -1, -1,
NULL, dbh, be, conn, op, NULL );
e = backsql_id2entry( &bsi, &user_entry, &user_id );
if ( e == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_bind(): "
"error in backsql_id2entry() - auth failed\n",
0, 0, 0 );
send_ldap_result( conn, op, LDAP_OTHER,
NULL, NULL, NULL, NULL );
return 1;
}
if ( ! access_allowed( be, conn, op, e, password, NULL,
ACL_AUTH, NULL ) ) {
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
NULL, NULL, NULL, NULL );
return 1;
}
if ( ( a = attr_find( e->e_attrs, password ) ) == NULL ) {
send_ldap_result( conn, op, LDAP_INAPPROPRIATE_AUTH,
NULL, NULL, NULL, NULL );
return 1;
}
if ( slap_passwd_check( conn, a, cred ) != 0 ) {
send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
NULL, NULL, NULL, NULL );
return 1;
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_bind()\n",0,0,0);
return 0;
}
int backsql_unbind(BackendDB *be,Connection *conn,Operation *op)
int
backsql_unbind(
BackendDB *be,
Connection *conn,
Operation *op )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_unbind()\n",0,0,0);
send_ldap_result(conn,op,LDAP_SUCCESS,NULL,NULL,NULL,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_unbind()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_unbind()\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, 0 );
Debug( LDAP_DEBUG_TRACE, "<==backsql_unbind()\n", 0, 0, 0 );
return 0;
}
#endif /* SLAPD_SQL */

View File

@ -18,170 +18,194 @@
#include "back-sql.h"
#include "sql-wrap.h"
int backsql_db_config(BackendDB *be,const char *fname,int lineno,int argc,char **argv)
int
backsql_db_config(
BackendDB *be,
const char *fname,
int lineno,
int argc,
char **argv )
{
backsql_info *si=(backsql_info*) be->be_private;
backsql_info *si = (backsql_info *)be->be_private;
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_config()\n",0,0,0);
if (!si)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_config: be_private is NULL!!!\n",0,0,0);
exit(1);
}
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_config()\n", 0, 0, 0 );
assert( si );
if (!strcasecmp(argv[0],"dbhost"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing hostname in dbhost directive\n",
fname,lineno,0);
}
else
{
si->dbhost=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): hostname=%s\n",si->dbhost,0,0);
}
return(0);
}
if (!strcasecmp(argv[0],"dbuser"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing username in dbuser directive\n",
fname,lineno,0);
}
else
{
si->dbuser=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbuser=%s\n",argv[1],0,0);
}
return(0);
}
if (!strcasecmp(argv[0],"dbpasswd"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing password in dbpasswd directive\n",
fname,lineno,0);
}
else
{
si->dbpasswd=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbpasswd=%s\n",si->dbpasswd,0,0);
}
return(0);
}
if (!strcasecmp(argv[0],"dbname"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing database name in dbname directive\n",
fname,lineno,0);
}
else
{
si->dbname=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): dbname=%s\n",si->dbname,0,0);
}
return(0);
}
if ( !strcasecmp( argv[ 0 ], "dbhost" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing hostname in dbhost directive\n",
fname, lineno, 0 );
return 1;
}
si->dbhost = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config(): hostname=%s\n",
si->dbhost, 0, 0 );
if (!strcasecmp(argv[0],"subtree_cond"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL condition in subtree_cond directive\n",
fname,lineno,0);
}
else
{
si->subtree_cond=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): subtree_cond=%s\n",si->subtree_cond,0,0);
}
return(0);
}
} else if ( !strcasecmp( argv[ 0 ], "dbuser" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing username in dbuser directive\n",
fname, lineno, 0 );
return 1;
}
si->dbuser = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbuser=%s\n",
si->dbuser, 0, 0 );
if (!strcasecmp(argv[0],"oc_query"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in oc_query directive\n",
fname,lineno,0);
}
else
{
si->oc_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): oc_query=%s\n",si->oc_query,0,0);
}
return(0);
}
} else if ( !strcasecmp( argv[ 0 ], "dbpasswd" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing password in dbpasswd directive\n",
fname, lineno, 0 );
return 1;
}
si->dbpasswd = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"dbpasswd=%s\n", /* si->dbpasswd */ "xxxx", 0, 0 );
if (!strcasecmp(argv[0],"at_query"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in at_query directive\n",
fname,lineno,0);
}
else
{
si->at_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): at_query=%s\n",si->at_query,0,0);
}
return(0);
}
} else if ( !strcasecmp( argv[ 0 ], "dbname" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing database name in dbname directive\n",
fname, lineno, 0 );
return 1;
}
si->dbname = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n",
si->dbname, 0, 0 );
if (!strcasecmp(argv[0],"insentry_query"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in insentry_query directive\n",
fname,lineno,0);
}
else
{
si->insentry_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): insentry_query=%s\n",si->insentry_query,0,0);
}
return(0);
}
} else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL condition "
"in subtree_cond directive\n",
fname, lineno, 0 );
return 1;
}
si->subtree_cond = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"subtree_cond=%s\n", si->subtree_cond, 0, 0 );
if (!strcasecmp(argv[0],"upper_func"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing function name in upper_func directive\n",
fname,lineno,0);
}
else
{
si->upper_func=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): upper_func=%s\n",si->upper_func,0,0);
}
return(0);
}
} else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in oc_query directive\n",
fname, lineno, 0 );
return 1;
}
si->oc_query = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"oc_query=%s\n", si->oc_query, 0, 0 );
if (!strcasecmp(argv[0],"delentry_query"))
{
if (argc<2)
{
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): missing SQL statement in delentry_query directive\n",
fname,lineno,0);
}
else
{
si->delentry_query=ch_strdup(argv[1]);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config(): delentry_query=%s\n",si->delentry_query,0,0);
}
return(0);
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_config (%s line %d): unknown directive '%s' (ignored)\n",
fname,lineno,argv[0]);
return 0;
} else if ( !strcasecmp( argv[ 0 ], "at_query" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in at_query directive\n",
fname, lineno, 0 );
return 1;
}
si->at_query = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"at_query=%s\n", si->at_query, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "insentry_query" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in insentry_query directive\n",
fname, lineno, 0 );
return 1;
}
si->insentry_query = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"insentry_query=%s\n", si->insentry_query, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing function name "
"in upper_func directive\n",
fname, lineno, 0 );
return 1;
}
si->upper_func = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"upper_func=%s\n", si->upper_func, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing function name "
"in strcast_func directive\n",
fname, lineno, 0 );
return 1;
}
si->strcast_func = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"strcast_func=%s\n", si->strcast_func, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in delentry_query directive\n",
fname, lineno, 0 );
return 1;
}
si->delentry_query = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"delentry_query=%s\n", si->delentry_query, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru") ) {
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing { yes | no }"
"in has_ldapinfo_dn_ru directive\n",
fname, lineno, 0 );
return 1;
}
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
si->has_ldapinfo_dn_ru = 1;
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
si->has_ldapinfo_dn_ru = 0;
} else {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"has_ldapinfo_dn_ru directive arg "
"must be \"yes\" or \"no\"\n",
fname, lineno, 0 );
return 1;
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"has_ldapinfo_dn_ru=%s\n",
si->has_ldapinfo_dn_ru == 0 ? "no" : "yes", 0, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): "
"unknown directive '%s' (ignored)\n",
fname, lineno, argv[ 0 ] );
}
return 0;
}
#endif /* SLAPD_SQL */

View File

@ -10,7 +10,7 @@ Then, at top of OpenLDAP source tree, run
this should build back-sql-enabled slapd, provided that you have iODBC/unixODBC
libraries and include files in include/library paths, "make install"...
In other words, follow installation procedure described in OpenLDAP
Administrators Guide, adding --enbale-sql option to configure, and
Administrators Guide, adding --enable-sql option to configure, and
having iODBC/unixODBC libraries installed an accessible by compiler.
Under Win32/MSVC++, I modified the workspace so that back-sql is built into
@ -41,7 +41,7 @@ Several things worth noting about ODBC:
Also worth noting are: ODBC-ODBC bridge by EasySoft (which was claimed
by several people to be far more effective and stable than OpenLink),
OpenRDA package etc.
- be carefull defining RDBMS connection parameters, you'll probably need only
- be careful defining RDBMS connection parameters, you'll probably need only
"dbname" directive - all the rest can be defined in datasource. Every other
directive is used to override value stored in datasource definition.
Maybe you will want to use dbuser/dbpasswd to override credentials defined in datasource

View File

@ -13,7 +13,8 @@
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "ac/string.h"
#include "ldap_pvt.h"
#include "slap.h"
#include "back-sql.h"
#include "sql-wrap.h"
@ -21,208 +22,292 @@
#include "entry-id.h"
#include "util.h"
backsql_entryID* backsql_free_entryID(backsql_entryID* id)
backsql_entryID *
backsql_free_entryID( backsql_entryID *id, int freeit )
{
backsql_entryID* next=id->next;
if (id->dn!=NULL)
free(id->dn);
free(id);
return next;
backsql_entryID *next;
assert( id );
next = id->next;
if ( id->dn.bv_val != NULL ) {
free( id->dn.bv_val );
}
if ( freeit ) {
free( id );
}
return next;
}
backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID *id,SQLHDBC dbh,char *dn)
/*
* FIXME: need to change API to pass backsql_entryID **id
* and return an error code, to distinguish LDAP_OTHER from
* LDAP_NO_SUCH_OBJECT
*/
int
backsql_dn2id(
backsql_info *bi,
backsql_entryID *id,
SQLHDBC dbh,
struct berval *dn )
{
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
/*SQLINTEGER nrows=0;*/
RETCODE rc;
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
#if 0
SQLINTEGER nrows = 0;
#endif
RETCODE rc;
int res;
/* TimesTen */
char upperdn[BACKSQL_MAX_DN_LEN+1];
char* toBind;
int i, j, k;
/* TimesTen */
char upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
char *toBind;
int i, j;
Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): dn='%s'\n",dn,0,0);
/* begin TimesTen */
Debug(LDAP_DEBUG_TRACE, "id_query '%s'\n", bi->id_query, 0, 0);
rc = backsql_Prepare(dbh,&sth,bi->id_query,0);
if (rc != SQL_SUCCESS) {
Debug(LDAP_DEBUG_TRACE, "backsql_dn2id(): error preparing SQL:\n", 0, 0, 0);
Debug(LDAP_DEBUG_TRACE, "%s\n", bi->id_query, 0, 0);
backsql_PrintErrors(SQL_NULL_HENV, dbh, sth, rc);
SQLFreeStmt(sth, SQL_DROP);
return NULL;
}
Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): dn='%s'\n",
dn->bv_val, 0, 0 );
if (bi->has_ldapinfo_dn_ru) {
/* Prepare an upper cased, byte reversed version that can be
searched using indexes */
assert( id );
for ((i=0, j=strlen(dn)-1); *(dn+i); (i++, j--)) {
*(upperdn+i) = toupper(*(dn+j));
}
*(upperdn+i) = '\0';
Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): upperdn='%s'\n",upperdn,0,0);
toBind = upperdn;
}
else {
if (bi->isTimesTen) {
for (i = 0; *(dn+i); i++) {
*(upperdn+i) = toupper(*(dn+i)); /* Copy while upper casing */
}
*(upperdn+i) = '\0';
Debug(LDAP_DEBUG_TRACE,"==>backsql_dn2id(): upperdn='%s'\n",upperdn,0,0);
toBind = upperdn;
}
else
toBind = dn;
}
if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
Debug( LDAP_DEBUG_TRACE,
"backsql_dn2id(): DN \"%s\" (%ld bytes) "
"exceeds max DN length (%d):\n",
dn->bv_val, dn->bv_len, BACKSQL_MAX_DN_LEN );
return LDAP_OTHER;
}
/* begin TimesTen */
Debug(LDAP_DEBUG_TRACE, "id_query '%s'\n", bi->id_query, 0, 0);
assert( bi->id_query );
rc = backsql_Prepare( dbh, &sth, bi->id_query, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
"backsql_dn2id(): error preparing SQL:\n%s",
bi->id_query, 0, 0);
backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
SQLFreeStmt( sth, SQL_DROP );
return LDAP_OTHER;
}
if ((rc=backsql_BindParamStr(sth,1,toBind,
BACKSQL_MAX_DN_LEN)) != SQL_SUCCESS)
/* end TimesTen*/
{
Debug(LDAP_DEBUG_TRACE,"backsql_dn2id(): error binding dn parameter:\n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
SQLFreeStmt(sth,SQL_DROP);
return NULL;
}
if ((rc=SQLExecute(sth)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_dn2id(): error executing query:\n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
SQLFreeStmt(sth,SQL_DROP);
return NULL;
}
backsql_BindRowAsStrings(sth,&row);
if ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
if (id==NULL)
{
id=(backsql_entryID*)ch_calloc(1,sizeof(backsql_entryID));
}
id->id=atoi(row.cols[0]);
id->keyval=atoi(row.cols[1]);
id->oc_id=atoi(row.cols[2]);
id->dn=ch_strdup(dn);
id->next=NULL;
}
else
id=NULL;
backsql_FreeRow(&row);
SQLFreeStmt(sth, SQL_DROP);
if (id!=NULL)
Debug(LDAP_DEBUG_TRACE,"<==backsql_dn2id(): id=%d\n",(int)id->id,0,0);
else
Debug(LDAP_DEBUG_TRACE,"<==backsql_dn2id(): no match\n",0,0,0);
return id;
if ( bi->has_ldapinfo_dn_ru ) {
/*
* Prepare an upper cased, byte reversed version
* that can be searched using indexes
*/
for ( i = 0, j = dn->bv_len - 1; dn->bv_val[ i ]; i++, j--) {
upperdn[ i ] = dn->bv_val[ j ];
}
upperdn[ i ] = '\0';
ldap_pvt_str2upper( upperdn );
Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(): upperdn='%s'\n",
upperdn, 0, 0 );
toBind = upperdn;
} else {
if ( bi->isTimesTen ) {
AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 );
ldap_pvt_str2upper( upperdn );
Debug( LDAP_DEBUG_TRACE,
"==>backsql_dn2id(): upperdn='%s'\n",
upperdn, 0, 0 );
toBind = upperdn;
} else {
toBind = dn->bv_val;
}
}
rc = backsql_BindParamStr( sth, 1, toBind, BACKSQL_MAX_DN_LEN );
if ( rc != SQL_SUCCESS) {
/* end TimesTen */
Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
"error binding dn=\"%s\" parameter:\n", toBind, 0, 0 );
backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
SQLFreeStmt( sth, SQL_DROP );
return LDAP_OTHER;
}
rc = SQLExecute( sth );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
"error executing query (\"%s\", \"%s\"):\n",
bi->id_query, toBind, 0 );
backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
SQLFreeStmt( sth, SQL_DROP );
return LDAP_OTHER;
}
backsql_BindRowAsStrings( sth, &row );
rc = SQLFetch( sth );
if ( BACKSQL_SUCCESS( rc ) ) {
id->id = atoi( row.cols[ 0 ] );
id->keyval = atoi( row.cols[ 1 ] );
id->oc_id = atoi( row.cols[ 2 ] );
ber_dupbv( &id->dn, dn );
id->next = NULL;
res = LDAP_SUCCESS;
} else {
res = LDAP_NO_SUCH_OBJECT;
}
backsql_FreeRow( &row );
SQLFreeStmt( sth, SQL_DROP );
if ( res == LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): id=%ld\n",
id->id, 0, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "<==backsql_dn2id(): no match\n",
0, 0, 0 );
}
return res;
}
int backsql_get_attr_vals(backsql_at_map_rec *at,backsql_srch_info *bsi)
int
backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
{
RETCODE rc;
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
int i;
RETCODE rc;
SQLHSTMT sth;
BACKSQL_ROW_NTS row;
int i;
assert( at );
assert( bsi );
Debug(LDAP_DEBUG_TRACE,"==>backsql_get_attr_vals(): oc='%s' attr='%s' keyval=%d\n",
bsi->oc->name,at->name,bsi->c_eid->keyval);
Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
"oc='%s' attr='%s' keyval=%ld\n",
bsi->oc->name, at->name, bsi->c_eid->keyval );
if ((rc=backsql_Prepare(bsi->dbh,&sth,at->query,0)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error preparing query: %s\n",at->query,0,0);
backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
return 1;
}
rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
"error preparing query: %s\n", at->query, 0, 0 );
backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
return 1;
}
if (backsql_BindParamID(sth,1,&(bsi->c_eid->keyval)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error binding key value parameter\n",0,0,0);
return 1;
}
rc = backsql_BindParamID( sth, 1, &bsi->c_eid->keyval );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
"error binding key value parameter\n", 0, 0, 0 );
return 1;
}
if ((rc=SQLExecute(sth)) != SQL_SUCCESS && rc!= SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_attr_values(): error executing attribute query '%s'\n",at->query,0,0);
backsql_PrintErrors(bsi->bi->db_env,bsi->dbh,sth,rc);
SQLFreeStmt(sth,SQL_DROP);
return 1;
}
rc = SQLExecute( sth );
if ( ! BACKSQL_SUCCESS( rc ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_values(): "
"error executing attribute query '%s'\n",
at->query, 0, 0 );
backsql_PrintErrors( bsi->bi->db_env, bsi->dbh, sth, rc );
SQLFreeStmt( sth, SQL_DROP );
return 1;
}
backsql_BindRowAsStrings(sth,&row);
while ((rc=SQLFetch(sth)) == SQL_SUCCESS || rc==SQL_SUCCESS_WITH_INFO)
{
for (i=0;i<row.ncols;i++)
{
if (row.is_null[i]>0)
{
backsql_entry_addattr(bsi->e,row.col_names[i],row.cols[i],/*row.col_prec[i]*/
strlen(row.cols[i]));
/* Debug(LDAP_DEBUG_TRACE,"prec=%d\n",(int)row.col_prec[i],0,0);*/
}
/* else
Debug(LDAP_DEBUG_TRACE,"NULL value in this row for attribute '%s'\n",row.col_names[i],0,0);
*/
}
}
backsql_FreeRow(&row);
SQLFreeStmt(sth,SQL_DROP);
Debug(LDAP_DEBUG_TRACE,"<==backsql_get_attr_vals()\n",0,0,0);
return 1;
backsql_BindRowAsStrings( sth, &row );
rc = SQLFetch( sth );
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
for ( i = 0; i < row.ncols; i++ ) {
if ( row.is_null[ i ] > 0 ) {
backsql_entry_addattr( bsi->e,
row.col_names[ i ],
row.cols[ i ],
#if 0
row.col_prec[ i ]
#else
/*
* FIXME: what if a binary
* is fetched?
*/
strlen( row.cols[ i ] )
#endif
);
#if 0
Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
(int)row.col_prec[ i ], 0, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "NULL value "
"in this row for attribute '%s'\n",
row.col_names[ i ], 0, 0 );
#endif
}
}
}
backsql_FreeRow( &row );
SQLFreeStmt( sth, SQL_DROP );
Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );
return 1;
}
Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* eid)
Entry *
backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
{
char **c_at_name;
backsql_at_map_rec *at;
char **c_at_name;
backsql_at_map_rec *at;
int rc;
Debug(LDAP_DEBUG_TRACE,"==>backsql_id2entry()\n",0,0,0);
Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
bsi->oc=backsql_oc_with_id(bsi->bi,eid->oc_id);
bsi->e=e;
bsi->c_eid=eid;
e->e_attrs=NULL;
e->e_private=NULL;
rc = dnPrettyNormal( NULL, &eid->dn, &e->e_name, &e->e_nname );
if ( rc != LDAP_SUCCESS ) {
return NULL;
}
bsi->oc = backsql_oc_with_id( bsi->bi, eid->oc_id );
bsi->e = e;
bsi->c_eid = eid;
e->e_attrs = NULL;
e->e_private = NULL;
/* if (bsi->base_dn != NULL)???*/
e->e_id=eid->id;
e->e_dn=ch_strdup(bsi->c_eid->dn);
e->e_ndn=dn_normalize(ch_strdup(bsi->c_eid->dn));
/* if ( bsi->base_dn != NULL)??? */
e->e_id = eid->id;
if (bsi->attrs!=NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_id2entry(): custom attribute list\n",0,0,0);
for(c_at_name=bsi->attrs;*c_at_name!=NULL;c_at_name++)
{
if (!strcasecmp(*c_at_name,"objectclass") || !strcasecmp(*c_at_name,"0.10"))
{
/*backsql_entry_addattr(bsi->e,"objectclass",bsi->oc->name,strlen(bsi->oc->name));*/
continue;
}
at=backsql_at_with_name(bsi->oc,*c_at_name);
if (at!=NULL)
backsql_get_attr_vals(at,bsi);
else
Debug(LDAP_DEBUG_TRACE,"backsql_id2entry(): attribute '%s' is not defined for objectlass '%s'\n",
*c_at_name,bsi->oc->name,0);
if ( bsi->attrs != NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
"custom attribute list\n", 0, 0, 0 );
for ( c_at_name = bsi->attrs; *c_at_name != NULL; c_at_name++ ) {
if ( !strcasecmp( *c_at_name, "objectclass" )
|| !strcasecmp( *c_at_name, "0.10" ) ) {
#if 0
backsql_entry_addattr( bsi->e, "objectclass",
bsi->oc->name,
strlen( bsi->oc->name ) );
#endif
continue;
}
at = backsql_at_with_name( bsi->oc, *c_at_name );
if ( at != NULL ) {
backsql_get_attr_vals( at, bsi );
} else {
Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
"attribute '%s' is not defined "
"for objectlass '%s'\n",
*c_at_name, bsi->oc->name, 0 );
}
}
} else {
Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
"retrieving all attributes\n", 0, 0, 0 );
avl_apply( bsi->oc->attrs, (AVL_APPLY)backsql_get_attr_vals,
bsi, 0, AVL_INORDER );
}
}
}
else
{
Debug(LDAP_DEBUG_TRACE,"backsql_id2entry(): retrieving all attributes\n",0,0,0);
avl_apply(bsi->oc->attrs,(AVL_APPLY)backsql_get_attr_vals,bsi,0,AVL_INORDER);
}
backsql_entry_addattr(bsi->e,"objectclass",bsi->oc->name,strlen(bsi->oc->name));
backsql_entry_addattr( bsi->e, "objectclass", bsi->oc->name,
strlen( bsi->oc->name ) );
Debug(LDAP_DEBUG_TRACE,"<==backsql_id2entry()\n",0,0,0);
return e;
Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
return e;
}
#endif /* SLAPD_SQL */

View File

@ -11,17 +11,18 @@
*/
typedef struct __backsql_entryID
{
unsigned long id;
unsigned long keyval;
unsigned long oc_id;
char *dn;
struct __backsql_entryID *next;
}backsql_entryID;
typedef struct backsql_entryID {
unsigned long id;
unsigned long keyval;
unsigned long oc_id;
struct berval dn;
struct backsql_entryID *next;
} backsql_entryID;
backsql_entryID* backsql_dn2id(backsql_info *bi,backsql_entryID* id,SQLHDBC dbh,char *dn);
backsql_entryID* backsql_free_entryID(backsql_entryID* id);/*returns next*/
int backsql_dn2id( backsql_info *bi, backsql_entryID *id,
SQLHDBC dbh, struct berval *dn );
/* returns next */
backsql_entryID *backsql_free_entryID( backsql_entryID *id, int freeit );
#endif
#endif /* __BACKSQL_ENTRYID_H__ */

View File

@ -21,24 +21,29 @@
#ifdef SLAPD_SQL_DYNAMIC
int backsql_LTX_init_module(int argc, char *argv[]) {
BackendInfo bi;
int
backsql_LTX_init_module(
int argc,
char *argv[] )
{
BackendInfo bi;
memset( &bi, '\0', sizeof(bi) );
bi.bi_type = "sql";
bi.bi_init = backbacksql_initialize;
memset( &bi, '\0', sizeof( bi ) );
bi.bi_type = "sql";
bi.bi_init = backbacksql_initialize;
backend_add(&bi);
return 0;
backend_add( &bi );
return 0;
}
#endif /* SLAPD_SHELL_DYNAMIC */
int sql_back_initialize(
BackendInfo *bi
)
int
sql_back_initialize(
BackendInfo *bi )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_initialize()\n",0,0,0);
Debug( LDAP_DEBUG_TRACE,"==>backsql_initialize()\n", 0, 0, 0 );
bi->bi_open = 0;
bi->bi_config = 0;
bi->bi_close = 0;
@ -72,165 +77,234 @@ int sql_back_initialize(
bi->bi_connection_init = 0;
bi->bi_connection_destroy = backsql_connection_destroy;
Debug(LDAP_DEBUG_TRACE,"<==backsql_initialize()\n",0,0,0);
Debug( LDAP_DEBUG_TRACE,"<==backsql_initialize()\n", 0, 0, 0 );
return 0;
}
int backsql_destroy ( BackendInfo *bi )
int
backsql_destroy(
BackendInfo *bi )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_destroy()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_destroy()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_destroy()\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<==backsql_destroy()\n", 0, 0, 0 );
return 0;
}
int backsql_db_init(BackendDB *bd)
int
backsql_db_init(
BackendDB *bd )
{
backsql_info *si;
backsql_info *si;
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_init()\n",0,0,0);
si = (backsql_info *) ch_calloc( 1, sizeof(backsql_info) );
ldap_pvt_thread_mutex_init(&si->dbconn_mutex);
ldap_pvt_thread_mutex_init(&si->schema_mutex);
backsql_init_db_env(si);
bd->be_private=si;
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_init()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 );
si = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) );
ldap_pvt_thread_mutex_init( &si->dbconn_mutex );
ldap_pvt_thread_mutex_init( &si->schema_mutex );
backsql_init_db_env( si );
si->has_ldapinfo_dn_ru = -1;
bd->be_private = si;
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 );
return 0;
}
int backsql_db_destroy(BackendDB *bd)
int
backsql_db_destroy(
BackendDB *bd )
{
backsql_info *si=(backsql_info*)bd->be_private;
backsql_info *si = (backsql_info*)bd->be_private;
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_destroy()\n",0,0,0);
ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
backsql_free_db_env(si);
ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
ldap_pvt_thread_mutex_lock(&si->schema_mutex);
backsql_destroy_schema_map(si);
ldap_pvt_thread_mutex_unlock(&si->schema_mutex);
ldap_pvt_thread_mutex_destroy(&si->schema_mutex);
ldap_pvt_thread_mutex_destroy(&si->dbconn_mutex);
free(si->dbname);
free(si->dbuser);
if (si->dbpasswd)
free(si->dbpasswd);
if (si->dbhost)
free(si->dbhost);
if (si->upper_func)
free(si->upper_func);
free(si->subtree_cond);
free(si->oc_query);
free(si->at_query);
free(si->insentry_query);
free(si->delentry_query);
free(si);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_destroy()\n",0,0,0);
return 0;
}
int backsql_db_open (BackendDB *bd)
{
backsql_info *si=(backsql_info*)bd->be_private;
Connection tmp;
SQLHDBC dbh;
int idq_len;
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_open(): testing RDBMS connection\n",0,0,0);
if (si->dbname==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): datasource name not specified (use dbname directive in slapd.conf)\n",0,0,0);
return 1;
}
if (si->dbuser==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): user name not specified (use dbuser directive in slapd.conf)\n",0,0,0);
return 1;
}
if (si->subtree_cond==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): subtree search SQL condition not specified (use subtree_cond directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' as default\n",backsql_def_subtree_cond,0,0);
si->subtree_cond=ch_strdup(backsql_def_subtree_cond);
}
if (si->oc_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): objectclass mapping SQL statement not specified (use oc_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_oc_query,0,0);
si->oc_query=ch_strdup(backsql_def_oc_query);
}
if (si->at_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): attribute mapping SQL statement not specified (use at_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_at_query,0,0);
si->at_query=ch_strdup(backsql_def_at_query);
}
if (si->insentry_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry insertion SQL statement not specified (use insentry_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_insentry_query,0,0);
si->insentry_query=ch_strdup(backsql_def_insentry_query);
}
if (si->delentry_query==NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): entry deletion SQL statement not specified (use delentry_query directive in slapd.conf)\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): setting '%s' by default\n",backsql_def_delentry_query,0,0);
si->delentry_query=ch_strdup(backsql_def_delentry_query);
}
tmp.c_connid=-1;
dbh=backsql_get_db_conn(bd,&tmp);
if (!dbh)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): connection failed, exiting\n",0,0,0
);
return 1;
}
si->id_query=NULL;
idq_len=0;
if (si->upper_func==NULL)
{
si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,"dn=?",NULL);
}
else
{
if (si->has_ldapinfo_dn_ru) {
si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,"dn_ru=?",NULL);
}
else {
if (si->isTimesTen) {
si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,si->upper_func,"(dn)=?",NULL);
}
else {
si->id_query=backsql_strcat(si->id_query,&idq_len,backsql_id_query,si->upper_func,"(dn)=",si->upper_func,"(?)",NULL);
}
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 );
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
backsql_free_db_env( si );
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
ldap_pvt_thread_mutex_lock( &si->schema_mutex );
backsql_destroy_schema_map( si );
ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
ldap_pvt_thread_mutex_destroy( &si->schema_mutex );
ldap_pvt_thread_mutex_destroy( &si->dbconn_mutex );
free( si->dbname );
free( si->dbuser );
if ( si->dbpasswd ) {
free( si->dbpasswd );
}
}
if ( si->dbhost ) {
free( si->dbhost );
}
if ( si->upper_func ) {
free( si->upper_func );
}
free( si->subtree_cond );
free( si->oc_query );
free( si->at_query );
free( si->insentry_query );
free( si->delentry_query );
free( si );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_destroy()\n", 0, 0, 0 );
return 0;
}
int
backsql_db_open(
BackendDB *bd )
{
backsql_info *si = (backsql_info*)bd->be_private;
Connection tmp;
SQLHDBC dbh;
int idq_len;
struct berval bv;
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
"testing RDBMS connection\n", 0, 0, 0 );
if ( si->dbname == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"datasource name not specified "
"(use dbname directive in slapd.conf)\n", 0, 0, 0 );
return 1;
}
if ( si->dbuser == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"user name not specified "
"(use dbuser directive in slapd.conf)\n", 0, 0, 0 );
return 1;
}
if ( si->subtree_cond == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"subtree search SQL condition not specified "
"(use subtree_cond directive in slapd.conf)\n",
0, 0, 0);
if ( si->upper_func ) {
struct berval bv = { 0, NULL };
int len = 0;
backsql_strcat( &bv, &len, si->upper_func,
backsql_def_upper_subtree_cond, NULL );
si->subtree_cond = bv.bv_val;
} else {
si->subtree_cond = ch_strdup( backsql_def_subtree_cond );
}
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' as default\n",
si->subtree_cond, 0, 0 );
}
if ( si->oc_query == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"objectclass mapping SQL statement not specified "
"(use oc_query directive in slapd.conf)\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' by default\n",
backsql_def_oc_query, 0, 0 );
si->oc_query = ch_strdup( backsql_def_oc_query );
}
if ( si->at_query == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"attribute mapping SQL statement not specified "
"(use at_query directive in slapd.conf)\n",
0, 0, 0 );
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' by default\n",
backsql_def_at_query, 0, 0 );
si->at_query = ch_strdup( backsql_def_at_query );
}
if ( si->insentry_query == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"entry insertion SQL statement not specified "
"(use insentry_query directive in slapd.conf)\n",
0, 0, 0 );
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' by default\n",
backsql_def_insentry_query, 0, 0 );
si->insentry_query = ch_strdup( backsql_def_insentry_query );
}
if ( si->delentry_query == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"entry deletion SQL statement not specified "
"(use delentry_query directive in slapd.conf)\n",
0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting '%s' by default\n",
backsql_def_delentry_query, 0, 0 );
si->delentry_query = ch_strdup( backsql_def_delentry_query );
}
tmp.c_connid =- 1;
dbh = backsql_get_db_conn( bd, &tmp );
if ( !dbh ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"connection failed, exiting\n", 0, 0, 0 );
return 1;
}
si->id_query = NULL;
idq_len = 0;
bv.bv_val = NULL;
bv.bv_len = 0;
if ( si->upper_func == NULL ) {
backsql_strcat( &bv, &idq_len, backsql_id_query,
"dn=?", NULL );
} else {
if ( si->has_ldapinfo_dn_ru ) {
backsql_strcat( &bv, &idq_len, backsql_id_query,
"dn_ru=?", NULL );
} else {
if ( si->isTimesTen ) {
backsql_strcat( &bv, &idq_len,
backsql_id_query,
si->upper_func, "(dn)=?",
NULL );
} else {
backsql_strcat( &bv, &idq_len,
backsql_id_query,
si->upper_func, "(dn)=",
si->upper_func, "(?)", NULL );
}
}
}
si->id_query = bv.bv_val;
backsql_free_db_conn(bd,&tmp);
if (!si->schema_loaded)
{
Debug(LDAP_DEBUG_TRACE,"backsql_db_open(): test failed, schema map not loaded - exiting\n",0,0,0);
return 1;
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_open(): test succeeded, schema map loaded\n",0,0,0);
return 0;
backsql_free_db_conn( bd, &tmp );
if ( !si->schema_loaded ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"test failed, schema map not loaded - exiting\n",
0, 0, 0 );
return 1;
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): "
"test succeeded, schema map loaded\n", 0, 0, 0 );
return 0;
}
int backsql_db_close(BackendDB *bd)
int
backsql_db_close(
BackendDB *bd )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_db_close()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_db_close()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_close()\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_close()\n", 0, 0, 0 );
return 0;
}
int backsql_connection_destroy(BackendDB *be,Connection *conn)
int
backsql_connection_destroy(
BackendDB *be,
Connection *conn )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_connection_destroy()\n",0,0,0);
backsql_free_db_conn(be,conn);
Debug(LDAP_DEBUG_TRACE,"<==backsql_connection_destroy()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_connection_destroy()\n", 0, 0, 0 );
backsql_free_db_conn( be, conn );
Debug( LDAP_DEBUG_TRACE, "<==backsql_connection_destroy()\n", 0, 0, 0 );
return 0;
}
#endif /* SLAPD_SQL */

File diff suppressed because it is too large Load Diff

View File

@ -17,26 +17,37 @@
#include "back-sql.h"
#include "sql-wrap.h"
int backsql_dummy()
int
backsql_dummy( void )
{
return 0;
return 0;
}
int backsql_compare(BackendDB *bd,
Connection *conn, Operation *op,
const char *dn, const char *ndn,
int
backsql_compare(
BackendDB *bd,
Connection *conn,
Operation *op,
struct berval *dn,
struct berval *ndn,
AttributeAssertion *ava )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_compare() - not implemented\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_compare() - not implemented\n",
0, 0, 0 );
return 1;
}
int backsql_abandon( BackendDB *be,
Connection *conn, Operation *op, int msgid )
int
backsql_abandon(
BackendDB *be,
Connection *conn,
Operation *op,
int msgid )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_abandon()\n",0,0,0);
Debug(LDAP_DEBUG_TRACE,"<==backsql_abandon()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_abandon()\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<==backsql_abandon()\n", 0, 0, 0 );
return 0;
}
#endif /* SLAPD_SQL */

View File

@ -20,309 +20,440 @@
#include "schema-map.h"
#include "util.h"
int backsql_dummy(void *,void *);
int backsql_dummy( void *, void * );
int backsql_cmp_oc_name(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
int
backsql_cmp_oc_name( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
{
return strcasecmp(m1->name,m2->name);
return strcasecmp( m1->name, m2->name );
}
int backsql_cmp_oc_id(backsql_oc_map_rec *m1,backsql_oc_map_rec *m2)
int
backsql_cmp_oc_id( backsql_oc_map_rec *m1, backsql_oc_map_rec *m2 )
{
if (m1->id < m2->id)
return -1;
if (m1->id > m2->id)
return 1;
return 0;
if ( m1->id < m2->id ) {
return -1;
}
if ( m1->id > m2->id ) {
return 1;
}
return 0;
}
int backsql_cmp_attr(backsql_at_map_rec *m1,backsql_at_map_rec *m2)
int
backsql_cmp_attr(
backsql_at_map_rec *m1,
backsql_at_map_rec *m2 )
{
return strcasecmp(m1->name,m2->name);
return strcasecmp( m1->name, m2->name );
}
char* backsql_make_attr_query(backsql_oc_map_rec *oc_map,backsql_at_map_rec *at_map)
char *
backsql_make_attr_query(
backsql_oc_map_rec *oc_map,
backsql_at_map_rec *at_map )
{
char *tmps;
int tmpslen;
struct berval tmps = { 0, NULL };
int tmpslen = 0;
tmps=NULL;tmpslen=0;
tmps=backsql_strcat(tmps,&tmpslen,"SELECT ",at_map->sel_expr," AS ",at_map->name,
" FROM ",at_map->from_tbls,
" WHERE ",oc_map->keytbl,".",oc_map->keycol,"=?",NULL);
if (at_map->join_where!=NULL && at_map->join_where[0]!='\0')
tmps=backsql_strcat(tmps,&tmpslen," AND ",at_map->join_where,NULL);
at_map->query=ch_strdup(tmps);
ch_free(tmps);
return at_map->query;
backsql_strcat( &tmps, &tmpslen, "SELECT ", at_map->sel_expr,
" AS ", at_map->name, " FROM ", at_map->from_tbls,
" WHERE ", oc_map->keytbl,".", oc_map->keycol,
"=?", NULL );
if ( at_map->join_where != NULL ) {
backsql_strcat( &tmps, &tmpslen, " AND ",
at_map->join_where, NULL );
}
at_map->query = tmps.bv_val;
return at_map->query;
}
int backsql_add_sysmaps(backsql_oc_map_rec *oc_map)
int
backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
{
backsql_at_map_rec *at_map;
int len;
char s[30];
backsql_at_map_rec *at_map;
int len;
char s[ 30 ];
struct berval bv;
sprintf(s,"%d",oc_map->id);
at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
at_map->name=ch_strdup("objectClass");
at_map->sel_expr=ch_strdup("ldap_entry_objclasses.oc_name");
at_map->from_tbls=ch_strdup("ldap_entry_objclasses,ldap_entries");
len=strlen(at_map->from_tbls);
backsql_merge_from_clause(&at_map->from_tbls,&len,oc_map->keytbl);
at_map->join_where=NULL; len=0;
at_map->join_where=backsql_strcat(at_map->join_where,&len,
"ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=",
oc_map->keytbl,".",oc_map->keycol," and ldap_entries.oc_map_id=",s,NULL);
at_map->add_proc=NULL;
at_map->delete_proc=NULL;
at_map->param_order=0;
at_map->expect_return=0;
backsql_make_attr_query(oc_map,at_map);
avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
snprintf( s, sizeof( s ), "%ld", oc_map->id );
at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
at_map->name=ch_strdup("ref");
at_map->sel_expr=ch_strdup("ldap_referrals.url");
at_map->from_tbls=ch_strdup("ldap_referrals,ldap_entries");
len=strlen(at_map->from_tbls);
backsql_merge_from_clause(&at_map->from_tbls,&len,oc_map->keytbl);
at_map->join_where=NULL; len=0;
at_map->join_where=backsql_strcat(at_map->join_where,&len,
"ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=",
oc_map->keytbl,".",oc_map->keycol," and ldap_entries.oc_map_id=",s,NULL);
at_map->add_proc=NULL;
at_map->delete_proc=NULL;
at_map->param_order=0;
at_map->expect_return=0;
backsql_make_attr_query(oc_map,at_map);
avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
at_map = (backsql_at_map_rec *)ch_calloc(1,
sizeof( backsql_at_map_rec ) );
at_map->name = ch_strdup( "objectClass" );
at_map->sel_expr = ch_strdup( "ldap_entry_objclasses.oc_name" );
at_map->from_tbls = ch_strdup( "ldap_entry_objclasses,ldap_entries" );
len = strlen( at_map->from_tbls );
backsql_merge_from_clause( &at_map->from_tbls, &len, oc_map->keytbl );
len = 0;
bv.bv_val = NULL;
bv.bv_len = 0;
backsql_strcat( &bv, &len,
"ldap_entries.id=ldap_entry_objclasses.entry_id "
"and ldap_entries.keyval=",
oc_map->keytbl, ".", oc_map->keycol,
" and ldap_entries.oc_map_id=", s, NULL );
at_map->join_where = bv.bv_val;
at_map->add_proc = NULL;
at_map->delete_proc = NULL;
at_map->param_order = 0;
at_map->expect_return = 0;
backsql_make_attr_query( oc_map, at_map );
avl_insert( &oc_map->attrs, at_map,
(AVL_CMP)backsql_cmp_attr, backsql_dummy );
return 1;
at_map = (backsql_at_map_rec *)ch_calloc( 1,
sizeof( backsql_at_map_rec ) );
at_map->name = ch_strdup( "ref" );
at_map->sel_expr = ch_strdup( "ldap_referrals.url" );
at_map->from_tbls = ch_strdup( "ldap_referrals,ldap_entries" );
len = strlen( at_map->from_tbls );
backsql_merge_from_clause( &at_map->from_tbls, &len,oc_map->keytbl );
/* FIXME: no free? */
at_map->join_where = NULL;
len = 0;
bv.bv_val = NULL;
bv.bv_len = 0;
backsql_strcat( &bv, &len,
"ldap_entries.id=ldap_referrals.entry_id "
"and ldap_entries.keyval=",
oc_map->keytbl, ".", oc_map->keycol,
" and ldap_entries.oc_map_id=", s, NULL );
at_map->join_where = bv.bv_val;
at_map->add_proc = NULL;
at_map->delete_proc = NULL;
at_map->param_order = 0;
at_map->expect_return = 0;
backsql_make_attr_query( oc_map, at_map );
avl_insert( &oc_map->attrs, at_map,
(AVL_CMP)backsql_cmp_attr, backsql_dummy );
return 1;
}
int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh)
int
backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
{
SQLHSTMT oc_sth,at_sth;
RETCODE rc;
BACKSQL_ROW_NTS oc_row,at_row;
unsigned long oc_id;
backsql_oc_map_rec *oc_map;
backsql_at_map_rec *at_map;
char *tmps;
int tmpslen;
SQLHSTMT oc_sth, at_sth;
RETCODE rc;
BACKSQL_ROW_NTS oc_row, at_row;
unsigned long oc_id;
backsql_oc_map_rec *oc_map;
backsql_at_map_rec *at_map;
char *tmps;
int tmpslen;
Debug(LDAP_DEBUG_TRACE,"==>load_schema_map()\n",0,0,0);
Debug( LDAP_DEBUG_TRACE, "==>load_schema_map()\n", 0, 0, 0 );
/* TimesTen : See if the ldap_entries.dn_ru field exists in the schema. */
/*
* TimesTen : See if the ldap_entries.dn_ru field exists in the schema
*/
if ( si->has_ldapinfo_dn_ru == -1 ) {
rc = backsql_Prepare( dbh, &oc_sth,
backsql_check_dn_ru_query, 0 );
if ( rc == SQL_SUCCESS ) {
si->has_ldapinfo_dn_ru = 1; /* Yes, the field exists */
Debug( LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists "
"in the schema\n", 0, 0, 0 );
} else {
si->has_ldapinfo_dn_ru = 0; /* No such field exists */
}
rc = backsql_Prepare(dbh, &oc_sth, backsql_check_dn_ru_query, 0);
if (rc == SQL_SUCCESS) {
si->has_ldapinfo_dn_ru = 1; /* Yes, the field exists */
Debug(LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists in the schema\n", 0, 0,0);
}
else {
si->has_ldapinfo_dn_ru = 0; /* No such field exists */
}
SQLFreeStmt( oc_sth, SQL_DROP );
}
SQLFreeStmt(oc_sth, SQL_DROP);
rc=backsql_Prepare(dbh,&oc_sth,si->oc_query,0);
if (rc != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing oc_query: '%s'\n",si->oc_query,0,0);
backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
return -1;
}
Debug(LDAP_DEBUG_TRACE, "load_schema_map(): at_query '%s'\n", si->at_query,0,0);
rc = backsql_Prepare( dbh, &oc_sth, si->oc_query, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"error preparing oc_query: '%s'\n",
si->oc_query, 0, 0 );
backsql_PrintErrors( si->db_env, dbh, oc_sth, rc );
return -1;
}
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): at_query '%s'\n",
si->at_query, 0, 0 );
rc=backsql_Prepare(dbh,&at_sth,si->at_query,0);
if (rc != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error preparing at_query: '%s'\n",si->at_query,0,0);
backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
return -1;
}
if ((rc=backsql_BindParamID(at_sth,1,&oc_id)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error binding param for at_query: \n",0,0,0);
backsql_PrintErrors(si->db_env,dbh,at_sth,rc);
return -1;
}
if ((rc=SQLExecute(oc_sth)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing oc_query: \n",0,0,0);
backsql_PrintErrors(si->db_env,dbh,oc_sth,rc);
return -1;
}
backsql_BindRowAsStrings(oc_sth,&oc_row);
while ((rc=SQLFetch(oc_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
oc_map=(backsql_oc_map_rec*)ch_calloc(1,sizeof(backsql_oc_map_rec));
oc_map->id=atoi(oc_row.cols[0]);
oc_map->name=ch_strdup(oc_row.cols[1]);
oc_map->keytbl=ch_strdup(oc_row.cols[2]);
oc_map->keycol=ch_strdup(oc_row.cols[3]);
oc_map->create_proc=(oc_row.is_null[4]<0)?NULL:ch_strdup(oc_row.cols[4]);
oc_map->delete_proc=(oc_row.is_null[5]<0)?NULL:ch_strdup(oc_row.cols[5]);
oc_map->expect_return=atoi(oc_row.cols[6]);
rc = backsql_Prepare( dbh, &at_sth, si->at_query, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"error preparing at_query: '%s'\n",
si->at_query, 0, 0 );
backsql_PrintErrors( si->db_env, dbh, at_sth, rc );
return -1;
}
oc_map->attrs=NULL;
avl_insert(&si->oc_by_name,oc_map,(AVL_CMP)backsql_cmp_oc_name,backsql_dummy);
avl_insert(&si->oc_by_id,oc_map,(AVL_CMP)backsql_cmp_oc_id,backsql_dummy);
oc_id=oc_map->id;
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): objectclass '%s': keytbl='%s' keycol='%s' ",
oc_map->name,oc_map->keytbl,oc_map->keycol);
if (oc_map->delete_proc) {
Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n", oc_map->delete_proc, 0, 0);
}
if (oc_map->create_proc) {
Debug(LDAP_DEBUG_TRACE,"create_proc='%s'\n", oc_map->create_proc, 0, 0);
}
Debug(LDAP_DEBUG_TRACE,"expect_return=%d; attributes:\n",
oc_map->expect_return, 0, 0);
rc = backsql_BindParamID( at_sth, 1, &oc_id );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"error binding param for at_query: \n", 0, 0, 0 );
backsql_PrintErrors( si->db_env, dbh, at_sth, rc );
return -1;
}
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): autoadding 'objectClass' and 'ref' mappings\n",0,0,0);
backsql_add_sysmaps(oc_map);
if ((rc=SQLExecute(at_sth)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): error executing at_query: \n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,dbh,at_sth,rc);
return -1;
}
backsql_BindRowAsStrings(at_sth,&at_row);
while ((rc=SQLFetch(at_sth)) == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"********'%s'\n",at_row.cols[0],0,0);
Debug(LDAP_DEBUG_TRACE,"name='%s',sel_expr='%s' from='%s' ",at_row.cols[0],
at_row.cols[1],at_row.cols[2]);
Debug(LDAP_DEBUG_TRACE,"join_where='%s',add_proc='%s' ",at_row.cols[3],
at_row.cols[4],0);
Debug(LDAP_DEBUG_TRACE,"delete_proc='%s'\n",at_row.cols[5],0,0);
Debug(LDAP_DEBUG_TRACE,"sel_expr_u='%s'\n", at_row.cols[8],0,0); /* TimesTen*/
at_map=(backsql_at_map_rec*)ch_calloc(1,sizeof(backsql_at_map_rec));
at_map->name=ch_strdup(at_row.cols[0]);
at_map->sel_expr=ch_strdup(at_row.cols[1]);
at_map->sel_expr_u = (at_row.is_null[8]<0)?NULL:ch_strdup(at_row.cols[8
]);
tmps=NULL;tmpslen=0;
backsql_merge_from_clause(&tmps,&tmpslen,at_row.cols[2]);
at_map->from_tbls=ch_strdup(tmps);
ch_free(tmps);
at_map->join_where=ch_strdup((at_row.is_null[3]<0)?"":at_row.cols[3]);
at_map->add_proc=(at_row.is_null[4]<0)?NULL:ch_strdup(at_row.cols[4]);
at_map->delete_proc=(at_row.is_null[5]<0)?NULL:ch_strdup(at_row.cols[5]);
at_map->param_order=atoi(at_row.cols[6]);
at_map->expect_return=atoi(at_row.cols[7]);
backsql_make_attr_query(oc_map,at_map);
Debug(LDAP_DEBUG_TRACE,"load_schema_map(): preconstructed query '%s'\n",at_map->query,0,0);
avl_insert(&oc_map->attrs,at_map,(AVL_CMP)backsql_cmp_attr,backsql_dummy);
}
backsql_FreeRow(&at_row);
SQLFreeStmt(at_sth,SQL_CLOSE);
}
backsql_FreeRow(&oc_row);
SQLFreeStmt(at_sth,SQL_DROP);
SQLFreeStmt(oc_sth,SQL_DROP);
si->schema_loaded=1;
Debug(LDAP_DEBUG_TRACE,"<==load_schema_map()\n",0,0,0);
return 1;
rc = SQLExecute( oc_sth );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"error executing oc_query: \n", 0, 0, 0 );
backsql_PrintErrors( si->db_env, dbh, oc_sth, rc );
return -1;
}
backsql_BindRowAsStrings( oc_sth, &oc_row );
rc = SQLFetch( oc_sth );
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( oc_sth ) ) {
oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
sizeof( backsql_oc_map_rec ) );
oc_map->id = atoi( oc_row.cols[ 0 ] );
oc_map->name = ch_strdup( oc_row.cols[ 1 ] );
oc_map->keytbl = ch_strdup( oc_row.cols[ 2 ] );
oc_map->keycol = ch_strdup( oc_row.cols[ 3 ] );
oc_map->create_proc = ( oc_row.is_null[ 4 ] < 0 ) ? NULL
: ch_strdup( oc_row.cols[ 4 ] );
oc_map->delete_proc = ( oc_row.is_null[ 5 ] < 0 ) ? NULL
: ch_strdup( oc_row.cols[ 5 ] );
oc_map->expect_return = atoi( oc_row.cols[ 6 ] );
/*
* FIXME: first attempt to check for offending
* instructions in {create|delete}_proc
*/
oc_map->attrs = NULL;
avl_insert( &si->oc_by_name, oc_map,
(AVL_CMP)backsql_cmp_oc_name, backsql_dummy );
avl_insert( &si->oc_by_id, oc_map,
(AVL_CMP)backsql_cmp_oc_id, backsql_dummy );
oc_id = oc_map->id;
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"objectClass '%s': keytbl='%s' keycol='%s'\n",
oc_map->name, oc_map->keytbl, oc_map->keycol );
if ( oc_map->delete_proc ) {
Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n",
oc_map->delete_proc, 0, 0 );
}
if ( oc_map->create_proc ) {
Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n",
oc_map->create_proc, 0, 0 );
}
Debug( LDAP_DEBUG_TRACE, "expect_return=%d; attributes:\n",
oc_map->expect_return, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"autoadding 'objectClass' and 'ref' mappings\n",
0, 0, 0 );
backsql_add_sysmaps( oc_map );
rc = SQLExecute( at_sth );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"error executing at_query: \n", 0, 0, 0 );
backsql_PrintErrors( SQL_NULL_HENV, dbh, at_sth, rc );
return -1;
}
backsql_BindRowAsStrings( at_sth, &at_row );
rc = SQLFetch( at_sth );
for ( ; BACKSQL_SUCCESS(rc); rc = SQLFetch( at_sth ) ) {
Debug( LDAP_DEBUG_TRACE, "********'%s'\n",
at_row.cols[ 0 ], 0, 0 );
Debug( LDAP_DEBUG_TRACE,
"name='%s',sel_expr='%s' from='%s'",
at_row.cols[ 0 ], at_row.cols[ 1 ],
at_row.cols[ 2 ] );
Debug( LDAP_DEBUG_TRACE,
"join_where='%s',add_proc='%s'",
at_row.cols[ 3 ], at_row.cols[ 4 ], 0 );
Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n",
at_row.cols[ 5 ], 0, 0 );
/* TimesTen */
Debug( LDAP_DEBUG_TRACE, "sel_expr_u='%s'\n",
at_row.cols[ 8 ], 0, 0 );
at_map = (backsql_at_map_rec *)ch_calloc( 1,
sizeof( backsql_at_map_rec ) );
at_map->name = ch_strdup( at_row.cols[ 0 ] );
at_map->sel_expr = ch_strdup( at_row.cols[ 1 ] );
at_map->sel_expr_u = ( at_row.is_null[ 8 ] < 0 ) ? NULL
: ch_strdup( at_row.cols[ 8 ] );
tmps = NULL;
tmpslen = 0;
backsql_merge_from_clause( &tmps, &tmpslen,
at_row.cols[ 2 ] );
at_map->from_tbls = tmps;
at_map->join_where = ( at_row.is_null[ 3 ] < 0 ) ? NULL
: ch_strdup( at_row.cols[ 3 ] );
at_map->add_proc = ( at_row.is_null[ 4 ] < 0 ) ? NULL
: ch_strdup( at_row.cols[4] );
at_map->delete_proc = ( at_row.is_null[ 5 ] < 0 ) ? NULL
: ch_strdup( at_row.cols[ 5 ] );
at_map->param_order = atoi( at_row.cols[ 6 ] );
at_map->expect_return = atoi( at_row.cols[ 7 ] );
backsql_make_attr_query( oc_map, at_map );
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
"preconstructed query '%s'\n",
at_map->query, 0, 0 );
avl_insert( &oc_map->attrs, at_map,
(AVL_CMP)backsql_cmp_attr,
backsql_dummy );
}
backsql_FreeRow( &at_row );
SQLFreeStmt( at_sth, SQL_CLOSE );
}
backsql_FreeRow( &oc_row );
SQLFreeStmt( at_sth, SQL_DROP );
SQLFreeStmt( oc_sth, SQL_DROP );
si->schema_loaded = 1;
Debug( LDAP_DEBUG_TRACE, "<==load_schema_map()\n", 0, 0, 0 );
return 1;
}
backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass)
backsql_oc_map_rec *
backsql_oc_with_name( backsql_info *si, char *objclass )
{
backsql_oc_map_rec tmp,*res;
backsql_oc_map_rec tmp, *res;
#if 0
Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): "
"searching for objectclass with name='%s'\n",
objclass, 0, 0 );
#endif
tmp.name = objclass;
res = (backsql_oc_map_rec *)avl_find( si->oc_by_name, &tmp,
(AVL_CMP)backsql_cmp_oc_name );
#if 0
if ( res != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
"found name='%s', id=%d\n", res->name, res->id, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
"not found\n", 0, 0, 0 );
}
#endif
/* Debug(LDAP_DEBUG_TRACE,"==>oc_with_name(): searching for objectclass with name='%s'\n",objclass,0,0);*/
tmp.name=objclass;
res=(backsql_oc_map_rec*)avl_find(si->oc_by_name,&tmp,(AVL_CMP)backsql_cmp_oc_name);
/* if (res!=NULL)
Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
else
Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
*/
return res;
return res;
}
backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id)
backsql_oc_map_rec *
backsql_oc_with_id( backsql_info *si, unsigned long id )
{
backsql_oc_map_rec tmp,*res;
backsql_oc_map_rec tmp, *res;
/* Debug(LDAP_DEBUG_TRACE,"==>oc_with_id(): searching for objectclass with id='%d'\n",id,0,0);*/
tmp.id=id;
res=(backsql_oc_map_rec*)avl_find(si->oc_by_id,&tmp,(AVL_CMP)backsql_cmp_oc_id);
/* if (res!=NULL)
Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): found name='%s', id=%d\n",res->name,res->id,0);
else
Debug(LDAP_DEBUG_TRACE,"<==oc_with_name(): not found\n",0,0,0);
*/
return res;
#if 0
Debug( LDAP_DEBUG_TRACE, "==>oc_with_id(): "
"searching for objectclass with id='%d'\n", id, 0, 0 );
#endif
tmp.id = id;
res = (backsql_oc_map_rec *)avl_find( si->oc_by_id, &tmp,
(AVL_CMP)backsql_cmp_oc_id );
#if 0
if ( res != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
"found name='%s', id=%d\n", res->name, res->id, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
"not found\n", 0, 0, 0 );
}
#endif
return res;
}
backsql_at_map_rec* backsql_at_with_name(backsql_oc_map_rec* objclass,char* attr)
backsql_at_map_rec *
backsql_at_with_name( backsql_oc_map_rec* objclass, char *attr )
{
backsql_at_map_rec tmp,*res;
backsql_at_map_rec tmp, *res;
/*Debug(LDAP_DEBUG_TRACE,"==>at_with_name(): searching for attribute with name='%s' (for objectclass '%s')\n",
attr,objclass->name,0);
*/
tmp.name=attr;
res=(backsql_at_map_rec*)avl_find(objclass->attrs,&tmp,(AVL_CMP)backsql_cmp_attr);
/*if (res!=NULL)
Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): found name='%s', sel_expr='%s'\n",
res->name,res->sel_expr,0);
else
Debug(LDAP_DEBUG_TRACE,"<==at_with_name(): not found\n",0,0,0);
*/
return res;
#if 0
Debug( LDAP_DEBUG_TRACE, "==>at_with_name(): "
"searching for attribute '%s' for objectclass '%s'\n",
attr, objclass->name, 0 );
#endif
tmp.name = attr;
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
(AVL_CMP)backsql_cmp_attr );
#if 0
if ( res != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<==at_with_name(): "
"found name='%s', sel_expr='%s'\n",
res->name, res->sel_expr, 0 );
} else {
Debug( LDAP_DEBUG_TRACE, "<==at_with_name(): "
"not found\n", 0, 0, 0 );
}
#endif
return res;
}
int backsql_free_attr(backsql_at_map_rec *at)
int
backsql_free_attr( backsql_at_map_rec *at )
{
Debug(LDAP_DEBUG_TRACE,"==>free_attr(): '%s'\n",at->name,0,0);
ch_free(at->name);
ch_free(at->sel_expr);
if (at->from_tbls!=NULL)
ch_free(at->from_tbls);
if (at->join_where!=NULL)
ch_free(at->join_where);
if (at->add_proc!=NULL)
ch_free(at->add_proc);
if (at->delete_proc!=NULL)
ch_free(at->delete_proc);
if (at->query)
ch_free(at->query);
ch_free(at);
if (at->sel_expr_u)
ch_free(at->sel_expr_u); /* TimesTen */
Debug(LDAP_DEBUG_TRACE,"<==free_attr()\n",0,0,0);
return 1;
Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n", at->name, 0, 0 );
ch_free( at->name );
ch_free( at->sel_expr );
if ( at->from_tbls != NULL ) {
ch_free( at->from_tbls );
}
if ( at->join_where != NULL ) {
ch_free( at->join_where );
}
if ( at->add_proc != NULL ) {
ch_free( at->add_proc );
}
if ( at->delete_proc != NULL ) {
ch_free( at->delete_proc );
}
if ( at->query ) {
ch_free( at->query );
}
ch_free( at );
/* TimesTen */
if ( at->sel_expr_u ) {
ch_free( at->sel_expr_u );
}
Debug( LDAP_DEBUG_TRACE, "<==free_attr()\n", 0, 0, 0 );
return 1;
}
int backsql_free_oc(backsql_oc_map_rec *oc)
int
backsql_free_oc( backsql_oc_map_rec *oc )
{
Debug(LDAP_DEBUG_TRACE,"==>free_oc(): '%s'\n",oc->name,0,0);
avl_free(oc->attrs,(AVL_FREE)backsql_free_attr);
ch_free(oc->name);
ch_free(oc->keytbl);
ch_free(oc->keycol);
if (oc->create_proc!=NULL)
ch_free(oc->create_proc);
if (oc->delete_proc!=NULL)
ch_free(oc->delete_proc);
ch_free(oc);
Debug(LDAP_DEBUG_TRACE,"<==free_oc()\n",0,0,0);
return 1;
Debug( LDAP_DEBUG_TRACE, "==>free_oc(): '%s'\n", oc->name, 0, 0 );
avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
ch_free( oc->name );
ch_free( oc->keytbl );
ch_free( oc->keycol );
if ( oc->create_proc != NULL ) {
ch_free( oc->create_proc );
}
if ( oc->delete_proc != NULL ) {
ch_free( oc->delete_proc );
}
ch_free( oc );
Debug( LDAP_DEBUG_TRACE, "<==free_oc()\n", 0, 0, 0 );
return 1;
}
int backsql_destroy_schema_map(backsql_info *si)
int
backsql_destroy_schema_map( backsql_info *si )
{
Debug(LDAP_DEBUG_TRACE,"==>destroy_schema_map()\n",0,0,0);
avl_free(si->oc_by_id,(AVL_FREE)backsql_free_oc);
avl_free(si->oc_by_name,(AVL_FREE)backsql_dummy);
Debug(LDAP_DEBUG_TRACE,"<==destroy_schema_map()\n",0,0,0);
return 0;
Debug( LDAP_DEBUG_TRACE, "==>destroy_schema_map()\n", 0, 0, 0 );
avl_free( si->oc_by_id, (AVL_FREE)backsql_free_oc );
avl_free( si->oc_by_name, (AVL_FREE)backsql_dummy );
Debug( LDAP_DEBUG_TRACE, "<==destroy_schema_map()\n", 0, 0, 0 );
return 0;
}
#endif /* SLAPD_SQL */

View File

@ -11,42 +11,60 @@
*/
typedef struct
{
char *name;
char *keytbl;
char *keycol;
char *create_proc; /*expected to return keyval of newly created entry*/
char *delete_proc;/*supposed to expect keyval as parameter and delete all the attributes as well*/
int expect_return; /*flags whether delete_proc is a function (whether back-sql should bind first parameter as output for return code)*/
unsigned long id;
Avlnode *attrs;
}backsql_oc_map_rec;
typedef struct {
char *name;
char *keytbl;
char *keycol;
/* expected to return keyval of newly created entry */
char *create_proc;
/* supposed to expect keyval as parameter and delete
* all the attributes as well */
char *delete_proc;
/* flags whether delete_proc is a function (whether back-sql
* should bind first parameter as output for return code) */
int expect_return;
unsigned long id;
Avlnode *attrs;
} backsql_oc_map_rec;
typedef struct
{
char *name;/*literal name of corresponding LDAP attribute type*/
char *from_tbls;
char *join_where;
char *sel_expr;
char *add_proc; /*supposed to expect 2 binded values: entry keyval and attr. value to add, like "add_name(?,?,?)"*/
char *delete_proc; /*supposed to expect 2 binded values: entry keyval and attr. value to delete*/
char *query; /*for optimization purposes attribute load query is preconstructed from parts on schemamap load time*/
/*following flags are bitmasks (first bit used for add_proc, second - for modify, third - for delete_proc)*/
int param_order; /*order of parameters for procedures above; 1 means "data then keyval", 0 means "keyval then data"*/
int expect_return; /*flags whether one or more of procedures is a function (whether back-sql should bind first parameter as output for return code)*/
char *sel_expr_u; /* TimesTen */
}backsql_at_map_rec;
typedef struct {
/* literal name of corresponding LDAP attribute type */
char *name;
char *from_tbls;
char *join_where;
char *sel_expr;
/* supposed to expect 2 binded values: entry keyval
* and attr. value to add, like "add_name(?,?,?)" */
char *add_proc;
/* supposed to expect 2 binded values: entry keyval
* and attr. value to delete */
char *delete_proc;
/* for optimization purposes attribute load query
* is preconstructed from parts on schemamap load time */
char *query;
/* following flags are bitmasks (first bit used for add_proc,
* second - for modify, third - for delete_proc) */
/* order of parameters for procedures above;
* 1 means "data then keyval", 0 means "keyval then data" */
int param_order;
/* flags whether one or more of procedures is a function
* (whether back-sql should bind first parameter as output
* for return code) */
int expect_return;
/* TimesTen */
char *sel_expr_u;
} backsql_at_map_rec;
/*defines to support bitmasks above*/
/* defines to support bitmasks above */
#define BACKSQL_ADD 1
#define BACKSQL_DEL 2
int backsql_load_schema_map(backsql_info *si,SQLHDBC dbh);
backsql_oc_map_rec* backsql_oc_with_name(backsql_info *si,char* objclass);
backsql_oc_map_rec* backsql_oc_with_id(backsql_info *si,unsigned long id);
backsql_at_map_rec* backsql_at_with_name(backsql_oc_map_rec* objclass,char* attr);
int backsql_destroy_schema_map(backsql_info *si);
int backsql_load_schema_map( backsql_info *si, SQLHDBC dbh );
backsql_oc_map_rec *backsql_oc_with_name( backsql_info *si, char *objclass );
backsql_oc_map_rec *backsql_oc_with_id( backsql_info *si, unsigned long id );
backsql_at_map_rec *backsql_at_with_name( backsql_oc_map_rec *objclass,
char *attr );
int backsql_destroy_schema_map( backsql_info *si );
#endif
#endif /* __BACKSQL_SCHEMA_MAP_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -13,14 +13,13 @@
#include <sql.h>
#include <sqlext.h>
typedef struct
{
SWORD ncols;
char** col_names;
UDWORD *col_prec;
char** cols;
SQLINTEGER* is_null;
}BACKSQL_ROW_NTS;
typedef struct {
SWORD ncols;
char **col_names;
UDWORD *col_prec;
char **cols;
SQLINTEGER *is_null;
} BACKSQL_ROW_NTS;
#endif
#endif /* __BACKSQL_SQL_TYPES_H__ */

View File

@ -12,8 +12,9 @@
#ifdef SLAPD_SQL
#include <stdio.h>
#include <string.h>
#include "ac/string.h"
#include <sys/types.h>
#include "ldap_pvt.h"
#include "slap.h"
#include "back-sql.h"
#include "sql-types.h"
@ -22,326 +23,433 @@
#define MAX_ATTR_LEN 16384
typedef struct backsql_conn
typedef struct backsql_conn {
int ldap_cid;
SQLHDBC dbh;
} backsql_db_conn;
int backsql_dummy( void *, void * );
void
backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc )
{
int ldap_cid;
SQLHDBC dbh;
}backsql_db_conn;
SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH]; /* msg. buffer */
SQLCHAR state[SQL_SQLSTATE_SIZE]; /* statement buf. */
SDWORD iSqlCode; /* return code */
SWORD len = SQL_MAX_MESSAGE_LENGTH - 1; /* return length */
int backsql_dummy(void *,void *);
Debug( LDAP_DEBUG_TRACE, "Return code: %d\n", rc, 0, 0 );
void backsql_PrintErrors(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth,int rc)
{
SQLCHAR msg[SQL_MAX_MESSAGE_LENGTH]; /* msg. buffer */
SQLCHAR state[SQL_SQLSTATE_SIZE]; /* statement buf. */
SDWORD iSqlCode; /* return code */
SWORD len=SQL_MAX_MESSAGE_LENGTH-1; /* return length */
Debug(LDAP_DEBUG_TRACE,"Return code: %d\n", rc,0,0);
while((rc=SQLError(henv,hdbc,sth,state,&iSqlCode,msg,
SQL_MAX_MESSAGE_LENGTH - 1, &len)) == SQL_SUCCESS
|| rc == SQL_SUCCESS_WITH_INFO
)
{
Debug(LDAP_DEBUG_TRACE,"Native error code: %d\n",(int) iSqlCode,0,0);
Debug(LDAP_DEBUG_TRACE,"SQL engine state: %s\n", state,0,0);
Debug(LDAP_DEBUG_TRACE,"Message: %s\n",msg,0,0);
}
rc = SQLError( henv, hdbc, sth, state, &iSqlCode, msg,
SQL_MAX_MESSAGE_LENGTH - 1, &len );
for ( ; BACKSQL_SUCCESS( rc ); ) {
Debug( LDAP_DEBUG_TRACE, "Native error code: %d\n",
(int)iSqlCode, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "SQL engine state: %s\n",
state, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "Message: %s\n", msg, 0, 0 );
rc = SQLError( henv, hdbc, sth, state, &iSqlCode, msg,
SQL_MAX_MESSAGE_LENGTH - 1, &len );
}
}
RETCODE backsql_Prepare(SQLHDBC dbh,SQLHSTMT *sth,char* query,int timeout)
RETCODE
backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout )
{
RETCODE rc;
char drv_name[30];
SWORD len;
int i;
rc=SQLAllocStmt(dbh,sth);
if (rc != SQL_SUCCESS)
return rc;
/*Debug(LDAP_DEBUG_TRACE,"==>_SQLPrepare()\n", 0,0,0);*/
SQLGetInfo(dbh,SQL_DRIVER_NAME,drv_name,30,&len);
/*Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): driver name='%s'\n", drv_name,0,0);*/
if (!strncmp(ldap_pvt_str2upper(drv_name),"SQLSRV32.DLL",30))
{
/*stupid default result set in MS SQL Server does not support multiple active statements
*on the same connection -- so we are trying to make it not to use default result set...
*/
Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): enabling MS SQL Server default result set workaround\n", 0,0,0);
rc=SQLSetStmtOption(*sth,SQL_CONCURRENCY,SQL_CONCUR_ROWVER);
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"_SQLPrepare(): SQLSetStmtOption(SQL_CONCURRENCY,SQL_CONCUR_ROWVER) failed:\n", 0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
}
}
if (timeout>0)
{
Debug(LDAP_DEBUG_TRACE,"_SQLprepare(): setting query timeout to %d sec.\n", timeout,0,0);
if ((rc=SQLSetStmtOption(*sth,SQL_QUERY_TIMEOUT,timeout)) != SQL_SUCCESS)
{
backsql_PrintErrors(SQL_NULL_HENV,dbh,sth,rc);
}
}
/*Debug(LDAP_DEBUG_TRACE,"<==_SQLPrepare() calling SQLPrepare()\n", 0,0,0);*/
return SQLPrepare(*sth,query,SQL_NTS);
RETCODE rc;
char drv_name[ 30 ];
SWORD len;
rc = SQLAllocStmt( dbh, sth );
if ( rc != SQL_SUCCESS ) {
return rc;
}
#if 0
Debug( LDAP_DEBUG_TRACE, "==>_SQLPrepare()\n", 0, 0, 0 );
#endif
SQLGetInfo( dbh, SQL_DRIVER_NAME, drv_name, 30, &len );
#if 0
Debug( LDAP_DEBUG_TRACE, "_SQLPrepare(): driver name='%s'\n",
drv_name, 0, 0 );
#endif
if ( !strncmp( ldap_pvt_str2upper( drv_name ), "SQLSRV32.DLL", 30 ) ) {
/*
* stupid default result set in MS SQL Server
* does not support multiple active statements
* on the same connection -- so we are trying
* to make it not to use default result set...
*/
Debug( LDAP_DEBUG_TRACE, "_SQLprepare(): "
"enabling MS SQL Server default result "
"set workaround\n", 0, 0, 0 );
rc = SQLSetStmtOption( *sth, SQL_CONCURRENCY,
SQL_CONCUR_ROWVER );
if ( rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO ) {
Debug( LDAP_DEBUG_TRACE, "_SQLPrepare(): "
"SQLSetStmtOption(SQL_CONCURRENCY,SQL_CONCUR_ROWVER) failed:\n",
0, 0, 0 );
backsql_PrintErrors( SQL_NULL_HENV, dbh, *sth, rc );
}
}
if ( timeout > 0 ) {
Debug( LDAP_DEBUG_TRACE, "_SQLprepare(): "
"setting query timeout to %d sec.\n",
timeout, 0, 0 );
rc = SQLSetStmtOption( *sth, SQL_QUERY_TIMEOUT, timeout );
if ( rc != SQL_SUCCESS ) {
backsql_PrintErrors( SQL_NULL_HENV, dbh, *sth, rc );
}
}
#if 0
Debug( LDAP_DEBUG_TRACE, "<==_SQLPrepare() calling SQLPrepare()\n",
0, 0, 0 );
#endif
return SQLPrepare( *sth, query, SQL_NTS );
}
RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen)
#if 0
RETCODE
backsql_BindParamStr( SQLHSTMT sth, int par_ind, char *str, int maxlen )
{
RETCODE rc;
SQLINTEGER len=SQL_NTS;
rc=SQLBindParameter(sth,(SQLUSMALLINT)par_ind,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_VARCHAR,
(SQLUINTEGER)maxlen,0,(SQLPOINTER)str,(SQLUINTEGER)maxlen,NULL);
return rc;
RETCODE rc;
rc = SQLBindParameter( sth, (SQLUSMALLINT)par_ind, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_VARCHAR,
(SQLUINTEGER)maxlen, 0, (SQLPOINTER)str,
(SQLUINTEGER)maxlen, NULL );
return rc;
}
RETCODE backsql_BindParamID(SQLHSTMT sth,int par_ind,unsigned long *id)
RETCODE
backsql_BindParamID( SQLHSTMT sth, int par_ind, unsigned long *id )
{
return SQLBindParameter(sth,(SQLUSMALLINT)par_ind,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,
0,0,(SQLPOINTER)id,0,(SQLINTEGER*)NULL);
return SQLBindParameter( sth, (SQLUSMALLINT)par_ind,
SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER,
0, 0, (SQLPOINTER)id, 0, (SQLINTEGER*)NULL );
}
#endif
RETCODE
backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
{
RETCODE rc;
SQLCHAR colname[ 64 ];
SQLSMALLINT name_len, col_type, col_scale, col_null;
UDWORD col_prec;
int i;
if ( row == NULL ) {
return SQL_ERROR;
}
#if 0
Debug( LDAP_DEBUG_TRACE, "==> backsql_BindRowAsStrings()\n", 0, 0, 0 );
#endif
rc = SQLNumResultCols( sth, &row->ncols );
if ( rc != SQL_SUCCESS ) {
#if 0
Debug( LDAP_DEBUG_TRACE, "_SQLBindRowAsStrings(): "
"SQLNumResultCols() failed:\n", 0, 0, 0 );
#endif
backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );
} else {
#if 0
Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
"ncols=%d\n", (int)row->ncols, 0, 0 );
#endif
row->col_names = (char **)ch_calloc( row->ncols,
sizeof( char * ) );
row->cols = (char **)ch_calloc( row->ncols, sizeof( char * ) );
row->col_prec = (UDWORD *)ch_calloc( row->ncols,
sizeof( UDWORD ) );
row->is_null = (SQLINTEGER *)ch_calloc( row->ncols,
sizeof( SQLINTEGER ) );
for ( i = 1; i <= row->ncols; i++ ) {
rc = SQLDescribeCol( sth, (SQLSMALLINT)i, &colname[ 0 ],
(SQLUINTEGER)sizeof( colname ) - 1,
&name_len, &col_type,
&col_prec, &col_scale, &col_null );
row->col_names[ i - 1 ] = ch_strdup( colname );
#if 0
Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
"col_name=%s, col_prec[%d]=%d\n",
colname, (int)i, (int)col_prec );
#endif
if ( col_type == SQL_LONGVARCHAR
|| col_type == SQL_LONGVARBINARY) {
#if 0
row->cols[ i - 1 ] = NULL;
row->col_prec[ i - 1 ] = -1;
/*
* such fields must be handled
* in some other way since they return 2G
* as their precision (at least it does so
* with MS SQL Server w/native driver)
* for now, we just set fixed precision
* for such fields - dirty hack, but...
* no time to deal with SQLGetData()
*/
#endif
col_prec = MAX_ATTR_LEN;
row->cols[ i - 1 ] = (char *)ch_calloc( col_prec + 1, sizeof( char ) );
row->col_prec[ i - 1 ] = col_prec;
rc = SQLBindCol( sth, (SQLUSMALLINT)i,
SQL_C_CHAR,
(SQLPOINTER)row->cols[ i - 1 ],
col_prec + 1,
&row->is_null[ i - 1 ] );
} else {
row->cols[ i - 1 ] = (char *)ch_calloc( col_prec + 1, sizeof( char ) );
row->col_prec[ i - 1 ] = col_prec;
rc = SQLBindCol( sth, (SQLUSMALLINT)i,
SQL_C_CHAR,
(SQLPOINTER)row->cols[ i - 1 ],
col_prec + 1,
&row->is_null[ i - 1 ] );
}
}
}
#if 0
Debug( LDAP_DEBUG_TRACE, "<== backsql_BindRowAsStrings()\n", 0, 0, 0 );
#endif
return rc;
}
RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row)
RETCODE
backsql_FreeRow( BACKSQL_ROW_NTS *row )
{
RETCODE rc;
SQLCHAR colname[64];
SQLSMALLINT name_len,col_type,col_scale,col_null;
UDWORD col_prec;
int i;
if (row == NULL)
return SQL_ERROR;
/*Debug(LDAP_DEBUG_TRACE,"==> backsql_BindRowAsStrings()\n",0,0,0);*/
rc=SQLNumResultCols(sth,&row->ncols);
if (rc != SQL_SUCCESS)
{
/*Debug(LDAP_DEBUG_TRACE,"_SQLBindRowAsStrings(): SQLNumResultCols() failed:\n",0,0,0);*/
backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,sth,rc);
}
else
{
/*Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: ncols=%d\n",(int)row->ncols,0,0);*/
row->col_names=(char**)ch_calloc(row->ncols,sizeof(char*));
row->cols=(char**)ch_calloc(row->ncols,sizeof(char*));
row->col_prec=(UDWORD*)ch_calloc(row->ncols,sizeof(UDWORD));
row->is_null=(SQLINTEGER*)ch_calloc(row->ncols,sizeof(SQLINTEGER));
for (i=1;i<=row->ncols;i++)
{
rc=SQLDescribeCol(sth,(SQLSMALLINT)i,&colname[0],(SQLUINTEGER)sizeof(colname)-1,&name_len,&col_type,
(UDWORD*) &col_prec,&col_scale,&col_null);
row->col_names[i-1]=ch_strdup(colname);
/*Debug(LDAP_DEBUG_TRACE,"backsql_BindRowAsStrings: col_name=%s, col_prec[%d]=%d\n",colname,(int)i,(int)col_prec);*/
if (col_type == SQL_LONGVARCHAR || col_type== SQL_LONGVARBINARY)
{
/*row->cols[i-1]=NULL;
*row->col_prec[i-1]=-1;
*such fields must be handled in some other way since they return 2G
*as their precision (at least it does so with MS SQL Server w/native driver)
*for now, we just set fixed precision for such fields - dirty hack, but...
*no time to deal with SQLGetData()
*/
col_prec=MAX_ATTR_LEN;
row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
row->col_prec[i-1]=col_prec;
rc=SQLBindCol(sth,(SQLUSMALLINT)i,SQL_C_CHAR,(SQLPOINTER)row->cols[i-1],col_prec+1,
&row->is_null[i-1]);
}
else
{
row->cols[i-1]=(char*)ch_calloc((col_prec+1),sizeof(char));
row->col_prec[i-1]=col_prec;
rc=SQLBindCol(sth,(SQLUSMALLINT)i,SQL_C_CHAR,(SQLPOINTER)row->cols[i-1],col_prec+1,
&row->is_null[i-1]);
}
}
}
/*Debug(LDAP_DEBUG_TRACE,"<== backsql_BindRowAsStrings()\n",0,0,0);*/
return rc;
int i;
if ( row->cols == NULL ) {
return SQL_ERROR;
}
for ( i = 0; i < row->ncols; i++ ) {
/*
* FIXME: we need to free the col_names as well, don't we?
*/
free( row->cols[ i ] );
}
free( row->col_names );
free( row->col_prec );
free( row->cols );
free( row->is_null );
return SQL_SUCCESS;
}
RETCODE backsql_FreeRow(BACKSQL_ROW_NTS *row)
int
backsql_cmp_connid( backsql_db_conn *c1, backsql_db_conn *c2 )
{
int i;
if (row->cols == NULL)
return SQL_ERROR;
for(i=0;i<row->ncols;i++)
{
free(row->cols[i]);
}
free(row->col_names);
free(row->col_prec);
free(row->cols);
free(row->is_null);
return SQL_SUCCESS;
if ( c1->ldap_cid > c2->ldap_cid ) {
return 1;
}
if ( c1->ldap_cid < c2->ldap_cid ) {
return -1;
}
return 0;
}
int backsql_cmp_connid(backsql_db_conn *c1,backsql_db_conn *c2)
int
backsql_close_db_conn( backsql_db_conn *conn )
{
if (c1->ldap_cid > c2->ldap_cid)
return 1;
if (c1->ldap_cid < c2->ldap_cid)
return -1;
return 0;
Debug( LDAP_DEBUG_TRACE, "==>backsql_close_db_conn()\n", 0, 0, 0 );
/* TimesTen */
SQLTransact( SQL_NULL_HENV, conn->dbh, SQL_COMMIT );
SQLDisconnect( conn->dbh );
SQLFreeConnect( conn->dbh );
Debug( LDAP_DEBUG_TRACE, "<==backsql_close_db_conn()\n", 0, 0, 0 );
return 1;
}
int backsql_close_db_conn(backsql_db_conn *conn)
int
backsql_init_db_env( backsql_info *si )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_close_db_conn()\n",0,0,0);
SQLTransact(NULL, conn->dbh, SQL_COMMIT); /* TimesTen */
SQLDisconnect(conn->dbh);
SQLFreeConnect(conn->dbh);
Debug(LDAP_DEBUG_TRACE,"<==backsql_close_db_conn()\n",0,0,0);
return 1;
RETCODE rc;
Debug( LDAP_DEBUG_TRACE, "==>backsql_init_db_env()\n", 0, 0, 0 );
rc = SQLAllocEnv( &si->db_env );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "init_db_env: SQLAllocEnv failed:\n",
0, 0, 0 );
backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC,
SQL_NULL_HENV, rc );
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_init_db_env()\n", 0, 0, 0 );
return SQL_SUCCESS;
}
int backsql_init_db_env(backsql_info *si)
int
backsql_free_db_env( backsql_info *si )
{
RETCODE rc;
Debug(LDAP_DEBUG_TRACE,"==>backsql_init_db_env()\n",0,0,0);
if ((rc=SQLAllocEnv(&si->db_env)) != SQL_SUCCESS)
{
Debug(LDAP_DEBUG_TRACE,"init_db_env: SQLAllocEnv failed:\n",0,0,0);
backsql_PrintErrors(SQL_NULL_HENV,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_init_db_env()\n",0,0,0);
return SQL_SUCCESS;
Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_env()\n", 0, 0, 0 );
#if 0
Debug( LDAP_DEBUG_TRACE, "free_db_env(): delete AVL tree here!!!\n",
0, 0, 0 );
#endif
/*
* stop, if frontend waits for all threads to shutdown
* before calling this -- then what are we going to delete??
* everything is already deleted...
*/
Debug( LDAP_DEBUG_TRACE, "<==backsql_free_db_env()\n", 0, 0, 0 );
return SQL_SUCCESS;
}
int backsql_free_db_env(backsql_info *si)
backsql_db_conn *
backsql_open_db_conn( backsql_info *si, int ldap_cid )
{
Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_env()\n",0,0,0);
/*Debug(LDAP_DEBUG_TRACE,"free_db_env(): delete AVL tree here!!!\n",0,0,0);*/
/* TimesTen */
char DBMSName[ 32 ];
backsql_db_conn *dbc;
int rc;
/*stop, if frontend waits for all threads to shutdown before calling this --
*then what we are going to delete?? everything is deleted already...
*/
Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_env()\n",0,0,0);
return SQL_SUCCESS;
Debug( LDAP_DEBUG_TRACE, "==>backsql_open_db_conn()\n", 0, 0, 0 );
dbc = (backsql_db_conn *)ch_calloc( 1, sizeof( backsql_db_conn ) );
dbc->ldap_cid = ldap_cid;
rc = SQLAllocConnect( si->db_env, &dbc->dbh );
if (!BACKSQL_SUCCESS( rc ) ) {
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
"SQLAllocConnect() failed:\n", 0, 0, 0 );
backsql_PrintErrors( si->db_env, SQL_NULL_HDBC,
SQL_NULL_HENV, rc );
return NULL;
}
rc = SQLConnect( dbc->dbh, si->dbname, SQL_NTS, si->dbuser,
SQL_NTS, si->dbpasswd, SQL_NTS );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
"SQLConnect() to database '%s' as user '%s' "
"%s:\n", si->dbname, si->dbuser,
rc == SQL_SUCCESS_WITH_INFO ?
"succeeded with info" : "failed" );
backsql_PrintErrors( si->db_env, dbc->dbh, SQL_NULL_HENV, rc );
if ( rc != SQL_SUCCESS_WITH_INFO ) {
return NULL;
}
}
/*
* TimesTen : Turn off autocommit. We must explicitly
* commit any transactions.
*/
SQLSetConnectOption( dbc->dbh, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF );
/*
* See if this connection is to TimesTen. If it is,
* remember that fact for later use.
*/
si->isTimesTen = 0; /* Assume until proven otherwise */
DBMSName[ 0 ] = '\0';
rc = SQLGetInfo( dbc->dbh, SQL_DBMS_NAME, (PTR)&DBMSName,
sizeof( DBMSName ), NULL );
if ( rc == SQL_SUCCESS ) {
if ( strcmp( DBMSName, "TimesTen" ) == 0 ||
strcmp( DBMSName, "Front-Tier" ) == 0 ) {
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
"TimesTen database!\n", 0, 0, 0 );
si->isTimesTen = 1;
}
} else {
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
"SQLGetInfo() failed:\n", 0, 0, 0 );
backsql_PrintErrors( si->db_env, dbc->dbh, SQL_NULL_HENV, rc );
}
/* end TimesTen */
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn(): "
"connected, adding to tree\n", 0, 0, 0 );
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
avl_insert( &si->db_conns, dbc, (AVL_CMP)backsql_cmp_connid,
backsql_dummy );
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
Debug( LDAP_DEBUG_TRACE, "<==backsql_open_db_conn()\n", 0, 0, 0 );
return dbc;
}
backsql_db_conn* backsql_open_db_conn(backsql_info *si,int ldap_cid)
int
backsql_free_db_conn( Backend *be, Connection *ldapc )
{
char DBMSName[32]; /* TimesTen*/
backsql_info *si = (backsql_info *)be->be_private;
backsql_db_conn tmp, *conn;
backsql_db_conn *dbc=(backsql_db_conn*)ch_calloc(1,sizeof(backsql_db_conn));
int rc;
Debug(LDAP_DEBUG_TRACE,"==>backsql_open_db_conn()\n",0,0,0);
dbc->ldap_cid=ldap_cid;
if ((rc=SQLAllocConnect(si->db_env,&dbc->dbh)) != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
{
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLAllocConnect() failed:\n",0,0,0);
backsql_PrintErrors(si->db_env,SQL_NULL_HDBC,SQL_NULL_HENV,rc);
return NULL;
}
if ((rc=SQLConnect(dbc->dbh,si->dbname,SQL_NTS,si->dbuser,SQL_NTS,
si->dbpasswd,SQL_NTS) != SQL_SUCCESS))
{
if (rc != SQL_SUCCESS_WITH_INFO)
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() failed:\n",0,0,0);
else
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLConnect() succeeded with info:\n",0,0,0);
backsql_PrintErrors(si->db_env,dbc->dbh,SQL_NULL_HENV,rc);
if (rc != SQL_SUCCESS_WITH_INFO)
return NULL;
}
Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_conn()\n", 0, 0, 0 );
tmp.ldap_cid = ldapc->c_connid;
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
conn = (backsql_db_conn *)avl_delete( &si->db_conns, &tmp,
(AVL_CMP)backsql_cmp_connid );
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
/* TimesTen : Turn off autocommit. We must explicitly commit any transactions. */
SQLSetConnectOption(dbc->dbh, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF);
/* See if this connection is to TimesTen. If it is,
remember that fact for later use. */
si->isTimesTen = 0; /* Assume until proven otherwise */
DBMSName[0] = '\0';
rc = SQLGetInfo(dbc->dbh, SQL_DBMS_NAME, (PTR) &DBMSName,
sizeof(DBMSName), NULL);
if (rc == SQL_SUCCESS) {
if (strcmp(DBMSName, "TimesTen") == 0 ||
strcmp(DBMSName, "Front-Tier") == 0) {
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: TimesTen database!\n",0,0,0);
si->isTimesTen = 1;
}
}
else {
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn: SQLGetInfo() failed:\n",0,0,0);
backsql_PrintErrors(si->db_env,dbc->dbh,SQL_NULL_HENV,rc);
}
/* end TimesTen */
Debug(LDAP_DEBUG_TRACE,"backsql_open_db_conn(): connected, adding to tree\n",0,0,0);
ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
avl_insert(&si->db_conns,dbc,(AVL_CMP)backsql_cmp_connid,backsql_dummy);
ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
Debug(LDAP_DEBUG_TRACE,"<==backsql_open_db_conn()\n",0,0,0);
return dbc;
/*
* we have one thread per connection, as I understand -- so we can
* get this out of critical section
*/
if ( conn != NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_free_db_conn(): "
"closing db connection\n", 0, 0, 0 );
backsql_close_db_conn( conn );
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_free_db_conn()\n", 0, 0, 0 );
return SQL_SUCCESS;
}
int backsql_free_db_conn(Backend *be,Connection *ldapc)
SQLHDBC
backsql_get_db_conn( Backend *be, Connection *ldapc )
{
backsql_info *si=(backsql_info*)be->be_private;
backsql_db_conn tmp,*conn;
Debug(LDAP_DEBUG_TRACE,"==>backsql_free_db_conn()\n",0,0,0);
tmp.ldap_cid=ldapc->c_connid;
ldap_pvt_thread_mutex_lock(&si->dbconn_mutex);
conn=(backsql_db_conn*)avl_delete(&si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
ldap_pvt_thread_mutex_unlock(&si->dbconn_mutex);
/*we have one thread per connection, as I understand -- so we can
*get this out of critical section
*/
if (conn!=NULL)
{
Debug(LDAP_DEBUG_TRACE,"backsql_free_db_conn(): closing db connection\n",0,0,0);
backsql_close_db_conn(conn);
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_free_db_conn()\n",0,0,0);
return SQL_SUCCESS;
}
backsql_info *si = (backsql_info *)be->be_private;
backsql_db_conn *dbc;
backsql_db_conn tmp;
SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc)
{
backsql_info *si=(backsql_info*)be->be_private;
backsql_db_conn *dbc;
backsql_db_conn tmp;
Debug( LDAP_DEBUG_TRACE, "==>backsql_get_db_conn()\n", 0, 0, 0 );
tmp.ldap_cid = ldapc->c_connid;
/*
* we have one thread per connection, as I understand --
* so we do not need locking here
*/
dbc = (backsql_db_conn *)avl_find( si->db_conns, &tmp,
(AVL_CMP)backsql_cmp_connid );
if ( !dbc ) {
dbc = backsql_open_db_conn( si, ldapc->c_connid );
}
Debug(LDAP_DEBUG_TRACE,"==>backsql_get_db_conn()\n",0,0,0);
tmp.ldap_cid=ldapc->c_connid;
/*we have one thread per connection, as I understand -- so we do not need
* locking here
*/
dbc=(backsql_db_conn*)avl_find(si->db_conns,&tmp,(AVL_CMP)backsql_cmp_connid);
if (!dbc)
dbc=backsql_open_db_conn(si,ldapc->c_connid);
if (!dbc)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_db_conn(): could not get connection handle -- returning NULL\n",0,0,0);
return NULL;
}
ldap_pvt_thread_mutex_lock(&si->schema_mutex);
if (!si->schema_loaded)
{
Debug(LDAP_DEBUG_TRACE,"backsql_get_db_conn(): first call -- reading schema map\n",0,0,0);
backsql_load_schema_map(si,dbc->dbh);
}
ldap_pvt_thread_mutex_unlock(&si->schema_mutex);
Debug(LDAP_DEBUG_TRACE,"<==backsql_get_db_conn()\n",0,0,0);
return dbc->dbh;
if ( !dbc ) {
Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
"could not get connection handle -- returning NULL\n",
0, 0, 0 );
return SQL_NULL_HDBC;
}
ldap_pvt_thread_mutex_lock( &si->schema_mutex );
if ( !si->schema_loaded ) {
Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
"first call -- reading schema map\n", 0, 0, 0 );
backsql_load_schema_map( si, dbc->dbh );
}
ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
Debug( LDAP_DEBUG_TRACE, "<==backsql_get_db_conn()\n", 0, 0, 0 );
return dbc->dbh;
}
#endif /* SLAPD_SQL */

View File

@ -13,17 +13,28 @@
#include "back-sql.h"
#include "sql-types.h"
RETCODE backsql_Prepare(SQLHDBC dbh,SQLHSTMT *sth,char* query,int timeout);
RETCODE backsql_BindParamStr(SQLHSTMT sth,int par_ind,char *str,int maxlen);
RETCODE backsql_BindParamID(SQLHSTMT sth,int par_ind,unsigned long *id);
RETCODE backsql_BindRowAsStrings(SQLHSTMT sth,BACKSQL_ROW_NTS *row);
RETCODE backsql_FreeRow(BACKSQL_ROW_NTS *row);
void backsql_PrintErrors(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth,int rc);
RETCODE backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char* query, int timeout );
int backsql_init_db_env(backsql_info *si);
int backsql_free_db_env(backsql_info *si);
SQLHDBC backsql_get_db_conn(Backend *be,Connection *ldapc);
int backsql_free_db_conn(Backend *be,Connection *ldapc);
#define backsql_BindParamStr( sth, par_ind, str, maxlen ) \
SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind), \
SQL_PARAM_INPUT, \
SQL_C_CHAR, SQL_VARCHAR, \
(SQLUINTEGER)(maxlen), 0, (SQLPOINTER)(str), \
(SQLUINTEGER)(maxlen), NULL )
#endif
#define backsql_BindParamID( sth, par_ind, id ) \
SQLBindParameter( (sth), (SQLUSMALLINT)(par_ind), \
SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, \
0, 0, (SQLPOINTER)(id), 0, (SQLINTEGER*)NULL )
RETCODE backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row );
RETCODE backsql_FreeRow( BACKSQL_ROW_NTS *row );
void backsql_PrintErrors( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT sth, int rc );
int backsql_init_db_env( backsql_info *si );
int backsql_free_db_env( backsql_info *si );
SQLHDBC backsql_get_db_conn( Backend *be, Connection *ldapc );
int backsql_free_db_conn( Backend *be, Connection *ldapc );
#endif /* __BACKSQL_SQL_WRAP_H__ */

View File

@ -13,158 +13,231 @@
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <stdarg.h>
#include "ac/string.h"
#include "ac/ctype.h"
#include "ac/stdarg.h"
#include "slap.h"
#include "back-sql.h"
#include "schema-map.h"
#include "util.h"
char backsql_def_oc_query[]="SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return FROM ldap_oc_mappings";
char backsql_def_at_query[]="SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return,sel_expr_u FROM ldap_attr_mappings WHERE oc_map_id=?";
char backsql_def_delentry_query[]="DELETE FROM ldap_entries WHERE id=?";
char backsql_def_insentry_query[]="INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)";
char backsql_def_subtree_cond[]="ldap_entries.dn LIKE CONCAT('%',?)";
char backsql_id_query[]="SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
char backsql_def_oc_query[] =
"SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return "
"FROM ldap_oc_mappings";
char backsql_def_at_query[] =
"SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,"
"param_order,expect_return,sel_expr_u FROM ldap_attr_mappings "
"WHERE oc_map_id=?";
char backsql_def_delentry_query[] = "DELETE FROM ldap_entries WHERE id=?";
char backsql_def_insentry_query[] =
"INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) "
"VALUES (?,?,?,?)";
char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)";
char backsql_id_query[] = "SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
/* TimesTen*/
/* TimesTen */
char backsql_check_dn_ru_query[] = "SELECT dn_ru from ldap_entries";
char* backsql_strcat(char* dest,int *buflen, ...)
struct berval *
backsql_strcat( struct berval *dest, int *buflen, ... )
{
va_list strs;
int cdlen,cslen,grow;
char *cstr;
va_list strs;
int cdlen, cslen, grow;
char *cstr;
assert( dest );
assert( dest->bv_val == NULL
|| dest->bv_len == strlen( dest->bv_val ) );
/*Debug(LDAP_DEBUG_TRACE,"==>my_strcat()\n");*/
va_start(strs,buflen);
if (dest==NULL || *buflen<=0)
{
dest=(char*)ch_calloc(BACKSQL_STR_GROW,sizeof(char));
*buflen=BACKSQL_STR_GROW;
}
cdlen=strlen(dest)+1;
while ((cstr=va_arg(strs,char*)) != NULL)
{
cslen=strlen(cstr);
grow=BACKSQL_MAX(BACKSQL_STR_GROW,cslen);
if (*buflen-cdlen < cslen)
{
/*Debug(LDAP_DEBUG_TRACE,"my_strcat(): buflen=%d, cdlen=%d, cslen=%d -- reallocating dest\n",
*buflen,cdlen,cslen); */
dest=(char*)ch_realloc(dest,(*buflen)+grow*sizeof(char));
if (dest == NULL)
{
Debug(LDAP_DEBUG_ANY,"my_strcat(): could not reallocate string buffer.\n",0,0,0);
}
*buflen+=grow;
/*Debug(LDAP_DEBUG_TRACE,"my_strcat(): new buflen=%d, dest=%p\n",*buflen,dest,0);*/
}
strcat(dest,cstr);
cdlen+=cslen;
}
va_end(strs);
/*Debug(LDAP_DEBUG_TRACE,"<==my_strcat() (dest='%s')\n",dest,0,0);*/
return dest;
#if 0
Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" );
#endif
va_start( strs, buflen );
if ( dest->bv_val == NULL || *buflen <= 0 ) {
dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
sizeof( char ) );
dest->bv_len = 0;
*buflen = BACKSQL_STR_GROW;
}
cdlen = dest->bv_len;
while ( ( cstr = va_arg( strs, char * ) ) != NULL ) {
cslen = strlen( cstr );
grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen );
if ( *buflen - cdlen <= cslen ) {
char *tmp_dest;
#if 0
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
"buflen=%d, cdlen=%d, cslen=%d "
"-- reallocating dest\n",
*buflen, cdlen + 1, cslen );
#endif
tmp_dest = (char *)ch_realloc( dest->bv_val,
( *buflen ) + grow * sizeof( char ) );
if ( tmp_dest == NULL ) {
Debug( LDAP_DEBUG_ANY, "backsql_strcat(): "
"could not reallocate string buffer.\n",
0, 0, 0 );
return NULL;
}
dest->bv_val = tmp_dest;
*buflen += grow;
#if 0
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
"new buflen=%d, dest=%p\n", *buflen, dest, 0 );
#endif
}
AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
cdlen += cslen;
}
va_end( strs );
#if 0
Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest='%s')\n",
dest, 0, 0 );
#endif
dest->bv_len = cdlen;
return dest;
}
int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_val_len)
int
backsql_entry_addattr(
Entry *e,
char *at_name,
char *at_val,
unsigned int at_val_len )
{
Attribute *c_at=e->e_attrs;
struct berval* add_val[2];
struct berval cval;
AttributeDescription *ad;
int rc;
const char *text;
Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): at_name='%s', at_val='%s'\n",at_name,at_val,0);
cval.bv_val=at_val;
cval.bv_len=at_val_len;
add_val[0]=&cval;
add_val[1]=NULL;
ad=NULL;
rc = slap_str2ad( at_name, &ad, &text );
if( rc != LDAP_SUCCESS )
{
Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): failed to find AttributeDescription for '%s'\n",at_name,0,0);
return 0;
}
rc = attr_merge(e,ad,add_val);
struct berval add_val[ 2 ];
AttributeDescription *ad;
int rc;
const char *text;
if( rc != 0 )
{
Debug(LDAP_DEBUG_TRACE,"backsql_entry_addattr(): failed to merge value '%s' for attribute '%s'\n",at_val,at_name,0);
return 0;
}
Debug(LDAP_DEBUG_TRACE,"<==backsql_query_addattr()\n",0,0,0);
return 1;
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
"at_name='%s', at_val='%s'\n", at_name, at_val, 0 );
add_val[ 0 ].bv_val = at_val;
add_val[ 0 ].bv_len = at_val_len;
add_val[ 1 ].bv_val = NULL;
add_val[ 1 ].bv_len = 0;
ad = NULL;
rc = slap_str2ad( at_name, &ad, &text );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
"failed to find AttributeDescription for '%s'\n",
at_name, 0, 0 );
return 0;
}
rc = attr_merge( e, ad, add_val );
if ( rc != 0 ) {
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
"failed to merge value '%s' for attribute '%s'\n",
at_val, at_name, 0 );
return 0;
}
Debug( LDAP_DEBUG_TRACE, "<==backsql_query_addattr()\n", 0, 0, 0 );
return 1;
}
char* backsql_get_table_spec(char **p)
char *
backsql_get_table_spec( char **p )
{
char *s,*q;
char *res=NULL;
int res_len=0;
char *s, *q;
struct berval res = { 0, NULL };
int res_len = 0;
s=*p;
while(**p && **p!=',') (*p)++;
if (**p)
*(*p)++='\0';
s = *p;
while ( **p && **p != ',' ) {
(*p)++;
}
if ( **p ) {
*(*p)++ = '\0';
}
#define BACKSQL_NEXT_WORD { \
while (*s && isspace((unsigned char)*s)) s++; \
if (!*s) return res; \
q=s; \
while (*q && !isspace((unsigned char)*q)) q++; \
if (*q) *q++='\0'; \
}
while ( *s && isspace( (unsigned char)*s ) ) s++; \
if ( !*s ) return res.bv_val; \
q = s; \
while ( *q && !isspace( (unsigned char)*q ) ) q++; \
if ( *q ) *q++='\0'; \
}
BACKSQL_NEXT_WORD;
res=backsql_strcat(res,&res_len,s,NULL);/*table name*/
s=q;
BACKSQL_NEXT_WORD;
/* table name */
backsql_strcat( &res, &res_len, s, NULL );
s = q;
BACKSQL_NEXT_WORD;
if (!strcasecmp(s,"as"))
{
s=q;
BACKSQL_NEXT_WORD;
}
/*res=backsql_strcat(res,&res_len," AS ",s,NULL);
*oracle doesn't understand AS :(
*/
res=backsql_strcat(res,&res_len," ",s,NULL);/*table alias*/
return res;
BACKSQL_NEXT_WORD;
if ( !strcasecmp( s, "as" ) ) {
s = q;
BACKSQL_NEXT_WORD;
}
#if 0
backsql_strcat( &res, &res_len, " AS ", s, NULL );
/* oracle doesn't understand AS :( */
#endif
/* table alias */
backsql_strcat( &res, &res_len, " ", s, NULL);
return res.bv_val;
}
int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from)
int
backsql_merge_from_clause( char **dest_from, int *dest_len, char *src_from )
{
char *s,*p,*srcc,*pos,e;
char *s, *p, *srcc, *pos, e;
struct berval res = { 0 , NULL };
/*Debug(LDAP_DEBUG_TRACE,"==>backsql_merge_from_clause(): dest_from='%s',src_from='%s'\n",
dest_from,src_from,0); */
srcc=ch_strdup(src_from);
p=srcc;
while(*p)
{
s=backsql_get_table_spec(&p);
/* Debug(LDAP_DEBUG_TRACE,"backsql_merge_from_clause(): p='%s' s='%s'\n",p,s,0); */
if (*dest_from==NULL)
*dest_from=backsql_strcat(*dest_from,dest_len,s,NULL);
else
if((pos=strstr(*dest_from,s))==NULL)
*dest_from=backsql_strcat(*dest_from,dest_len,",",s,NULL);
else if((e=pos[strlen(s)])!='\0' && e!=',')
*dest_from=backsql_strcat(*dest_from,dest_len,",",s,NULL);
if (s)
ch_free(s);
}
/* Debug(LDAP_DEBUG_TRACE,"<==backsql_merge_from_clause()\n",0,0,0);*/
free(srcc);
return 1;
#if 0
Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): "
"dest_from='%s',src_from='%s'\n",
dest_from, src_from, 0 );
#endif
srcc = ch_strdup( src_from );
p = srcc;
if ( *dest_from != NULL ) {
res.bv_val = *dest_from;
res.bv_len = strlen( *dest_from );
}
while ( *p ) {
s = backsql_get_table_spec( &p );
#if 0
Debug( LDAP_DEBUG_TRACE, "backsql_merge_from_clause(): "
"p='%s' s='%s'\n", p, s, 0 );
#endif
if ( res.bv_val == NULL ) {
backsql_strcat( &res, dest_len, s, NULL );
} else {
pos = strstr( res.bv_val, s );
if ( pos == NULL ) {
backsql_strcat( &res, dest_len, ",", s, NULL );
} else if ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) {
backsql_strcat( &res, dest_len, ",", s, NULL );
}
}
if ( s ) {
ch_free( s );
}
}
#if 0
Debug( LDAP_DEBUG_TRACE, "<==backsql_merge_from_clause()\n", 0, 0, 0 );
#endif
free( srcc );
*dest_from = res.bv_val;
return 1;
}
#endif /* SLAPD_SQL */

View File

@ -19,46 +19,58 @@
#define BACKSQL_STR_GROW 64
char* backsql_strcat(char* dest,int *buflen, ...);
struct berval *backsql_strcat( struct berval *dest, int *buflen, ... );
int backsql_entry_addattr(Entry *e,char *at_name,char *at_val,unsigned int at_val_len);
int backsql_entry_addattr( Entry *e, char *at_name, char *at_val,
unsigned int at_val_len );
typedef struct __backsql_srch_info
{
char *base_dn;
int scope;
Filter *filter;
int slimit,tlimit;
time_t stoptime;
backsql_entryID *id_list,*c_eid;
int abandon;
backsql_info *bi;
backsql_oc_map_rec *oc;
char *sel,*from,*join_where,*flt_where;
int sel_len,from_len,jwhere_len,fwhere_len;
SQLHDBC dbh;
int status;
Backend *be;
Connection *conn;
Operation *op;
char **attrs;
Entry *e;
int isTimesTen; /* 1 if the db is TimesTen; 0 if it's not */
}backsql_srch_info;
typedef struct __backsql_srch_info {
struct berval *base_dn;
int scope;
Filter *filter;
int slimit, tlimit;
time_t stoptime;
backsql_entryID *id_list, *c_eid;
int n_candidates;
int abandon;
backsql_info *bi;
backsql_oc_map_rec *oc;
struct berval sel, from, join_where, flt_where;
int sel_len, from_len, jwhere_len, fwhere_len;
SQLHDBC dbh;
int status;
Backend *be;
Connection *conn;
Operation *op;
char **attrs;
Entry *e;
/* 1 if the db is TimesTen; 0 if it's not */
int isTimesTen;
} backsql_srch_info;
int backsql_process_filter(backsql_srch_info *bsi,Filter *f);
void backsql_init_search(backsql_srch_info *bsi,backsql_info *bi,char *nbase,int scope,
int slimit,int tlimit,time_t stoptime,Filter *filter,
SQLHDBC dbh,Backend *be,Connection *conn,Operation *op,struct berval **attrs);
Entry* backsql_id2entry(backsql_srch_info *bsi,Entry* e,backsql_entryID* id);
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,
BackendDB *be, Connection *conn, Operation *op,
AttributeName *attrs );
Entry *backsql_id2entry( backsql_srch_info *bsi, Entry *e,
backsql_entryID *id );
extern char backsql_def_oc_query[],backsql_def_at_query[],
backsql_def_delentry_query[],backsql_def_insentry_query[],
backsql_def_subtree_cond[],backsql_id_query[];
extern char backsql_check_dn_ru_query[];
extern char
backsql_def_oc_query[],
backsql_def_at_query[],
backsql_def_delentry_query[],
backsql_def_insentry_query[],
backsql_def_subtree_cond[],
backsql_def_upper_subtree_cond[],
backsql_id_query[];
extern char
backsql_check_dn_ru_query[];
int backsql_merge_from_clause(char **dest_from,int *dest_len,char *src_from);
int backsql_merge_from_clause( char **dest_from, int *dest_len,
char *src_from );
#endif
#endif /* __BACKSQL_UTIL_H__ */