mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-22 23:59:34 -05:00
Final run of changes to back-sql; IBM db2 support has been tested.
Now related ITSes need be audited and possibly closed.
Enhancements:
- re-styled code for better readability
- upgraded backend API to reflect recent changes
- LDAP schema is checked when loading SQL/LDAP mapping
- AttributeDescription/ObjectClass pointers used for more efficient
mapping lookup
- bervals used where string length is required often
- atomized write operations by committing at the end of each operation
and defaulting connection closure to rollback
- added LDAP access control to write operations
- fully implemented modrdn (with rdn attrs change, deleteoldrdn,
access check, parent/children check and more)
- added parent access control, children control to delete operation
- added structuralObjectClass operational attribute check and
value return on search
- added hasSubordinate operational attribute on demand
- search limits are appropriately enforced
- function backsql_strcat() has been made more efficient
- concat function has been made configurable by means of a pattern
- added config switches:
- fail_if_no_mapping write operations fail if there is no mapping
- has_ldapinfo_dn_ru overrides autodetect
- concat_pattern a string containing two '?' is used
(note that "?||?" should be more portable
than builtin function "CONCAT(?,?)")
- strcast_func cast of string constants in "SELECT DISTINCT statements (needed by PostgreSQL)
- upper_needs_cast cast the argument of upper when required
(basically when building dn substring queries)
Todo:
- add security checks for SQL statements that can be injected (?)
- re-test with previously supported RDBMs
- replace dn_ru and so with normalized dn (no need for upper() and so
in dn match)
- implement a backsql_normalize() function to replace the upper()
conversion routines
- note that subtree deletion, subtree renaming and so could be easily
implemented (rollback and consistency checks are available :)
- implement "lastmod" and other operational stuff (ldap_entries table ?)
This commit is contained in:
parent
7b4b4b34c4
commit
f11c6b27e7
21 changed files with 1886 additions and 560 deletions
|
|
@ -63,7 +63,9 @@ These three options are generally unneeded, because this information is already
|
||||||
taken from the datasource.
|
taken from the datasource.
|
||||||
Use them if you need to override datasource settings.
|
Use them if you need to override datasource settings.
|
||||||
Also, several RDBMS' drivers tend to require explicit passing of user/password,
|
Also, several RDBMS' drivers tend to require explicit passing of user/password,
|
||||||
even if those are given in datasource.
|
even if those are given in datasource (Note:
|
||||||
|
.B dbhost
|
||||||
|
is currently ignored).
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
.B subtree_cond <SQL expression>
|
.B subtree_cond <SQL expression>
|
||||||
|
|
@ -92,18 +94,74 @@ adding and deleting entries to ldap_entries, etc.
|
||||||
All these and subtree_cond should have the given default values.
|
All these and subtree_cond should have the given default values.
|
||||||
For the current value it is recommended to look at the sources,
|
For the current value it is recommended to look at the sources,
|
||||||
or in the log output when slapd starts with "-d 5" or greater.
|
or in the log output when slapd starts with "-d 5" or greater.
|
||||||
|
Note that the parameter number and order must not be changed.
|
||||||
.TP
|
.TP
|
||||||
.B upper_func <SQL function name>
|
.B upper_func <SQL function name>
|
||||||
Specifies the name of a function that converts a given value to uppercase.
|
Specifies the name of a function that converts a given value to uppercase.
|
||||||
This is used for CIS matching when the RDBMS is case sensitive.
|
This is used for CIS matching when the RDBMS is case sensitive.
|
||||||
.TP
|
.TP
|
||||||
|
.B upper_needs_cast { yes | no }
|
||||||
|
Set this directive to
|
||||||
|
.B yes
|
||||||
|
if
|
||||||
|
.B upper_func
|
||||||
|
needs an explicit cast when applied to literal strings. The form
|
||||||
|
.B cast (<arg> as varchar(<max DN length>))
|
||||||
|
is used, where
|
||||||
|
.B <max DN length>
|
||||||
|
is builtin.
|
||||||
|
This is
|
||||||
|
.B experimental
|
||||||
|
and may change in future releases.
|
||||||
|
.TP
|
||||||
|
.B concat_pattern <pattern>
|
||||||
|
This statement defines the
|
||||||
|
.B pattern
|
||||||
|
to be used to concatenate strings. The
|
||||||
|
.B pattern
|
||||||
|
MUST contain two question marks, '?', that will be replaced
|
||||||
|
by the two strings that must be concatenated. The default value is
|
||||||
|
.BR "CONCAT(?,?)";
|
||||||
|
a form that is known to be highly portable is
|
||||||
|
.BR "?||?",
|
||||||
|
but an explicit cast may be required when operating on literal strings:
|
||||||
|
.BR "cast(?||? as varchar(<length>))".
|
||||||
|
On some RDBMSes the form
|
||||||
|
.B "?+?"
|
||||||
|
is known to work.
|
||||||
|
Carefully check the documentation of your RDBMS or stay with the examples
|
||||||
|
for supported ones.
|
||||||
|
This is
|
||||||
|
.B experimental
|
||||||
|
and may change in future releases.
|
||||||
|
.TP
|
||||||
.B strcast_func <SQL function name>
|
.B strcast_func <SQL function name>
|
||||||
Specifies the name of a function that converts a given value to a string
|
Specifies the name of a function that converts a given value to a string
|
||||||
for appropriate ordering. This is used when selecting distinct data.
|
for appropriate ordering. This is used in "SELECT DISTINCT" statements
|
||||||
|
for strongly typed RDBMSes with little implicit casting (like PostgreSQL),
|
||||||
|
when a literal string is specified.
|
||||||
|
This is
|
||||||
|
.B experimental
|
||||||
|
and may change in future releases.
|
||||||
.TP
|
.TP
|
||||||
.B has_ldapinfo_dn_ru { yes | no }
|
.B has_ldapinfo_dn_ru { yes | no }
|
||||||
Explicitly inform the backend whether the SQL schema has dn_ru or not.
|
Explicitly inform the backend whether the SQL schema has dn_ru column
|
||||||
Overrides automatic check (required by PostgreSQL).
|
(dn in reverse uppercased form) or not.
|
||||||
|
Overrides automatic check (required by PostgreSQL/unixODBC).
|
||||||
|
This is
|
||||||
|
.B experimental
|
||||||
|
and may change in future releases.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B fail_if_no_mapping { yes | no }
|
||||||
|
When set to
|
||||||
|
.B yes
|
||||||
|
it forces write operations to fail if no appropriate mapping between LDAP
|
||||||
|
attributes and SQL data is available. The default behavior is to ignore
|
||||||
|
those changes that cannot be mapped correctly.
|
||||||
|
This is
|
||||||
|
.B experimental
|
||||||
|
and may change in future releases.
|
||||||
|
|
||||||
.SH METAINFORMATION USED
|
.SH METAINFORMATION USED
|
||||||
.LP
|
.LP
|
||||||
|
|
@ -217,7 +275,7 @@ Keytbl and keycol thus contain "persons" (name of the table), and "id"
|
||||||
ldap_attr_mappings (some columns are not listed for clarity)
|
ldap_attr_mappings (some columns are not listed for clarity)
|
||||||
-----------
|
-----------
|
||||||
id=1
|
id=1
|
||||||
oc_id=1
|
oc_map_id=1
|
||||||
name="cn"
|
name="cn"
|
||||||
sel_expr="CONCAT(persons.first_name,' ',persons.last_name)"
|
sel_expr="CONCAT(persons.first_name,' ',persons.last_name)"
|
||||||
from_tbls="persons"
|
from_tbls="persons"
|
||||||
|
|
@ -356,7 +414,7 @@ information on this matter - they are self-explanatory for those familiar
|
||||||
with concept expressed above.
|
with concept expressed above.
|
||||||
.LP
|
.LP
|
||||||
.SH common techniques (referrals, multiclassing etc.)
|
.SH common techniques (referrals, multiclassing etc.)
|
||||||
First of all, lets remember that among other major differences to the
|
First of all, let's remember that among other major differences to the
|
||||||
complete LDAP data model, the concept above does not directly support
|
complete LDAP data model, the concept above does not directly support
|
||||||
such things as multiple objectclasses per entry, and referrals.
|
such things as multiple objectclasses per entry, and referrals.
|
||||||
Fortunately, they are easy to adopt in this scheme.
|
Fortunately, they are easy to adopt in this scheme.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
#ifndef __BACKSQL_H__
|
|
||||||
#define __BACKSQL_H__
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
|
* Copyright 1999, Dmitry Kovalev <mit@openldap.org>, All rights reserved.
|
||||||
*
|
*
|
||||||
|
|
@ -9,6 +6,66 @@
|
||||||
* license is available at http://www.OpenLDAP.org/license.html or
|
* license is available at http://www.OpenLDAP.org/license.html or
|
||||||
* in file LICENSE in the top-level directory of the distribution.
|
* in file LICENSE in the top-level directory of the distribution.
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright 2002, Pierangelo Masarati <ando@OpenLDAP.org>.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This is a modified version of back-sql; the same conditions
|
||||||
|
* of the above reported Copyright statement, and sigificantly
|
||||||
|
* the OpenLDAP Public License apply. Credits go to Dmitry
|
||||||
|
* Kovalev for the initial development of the backend.
|
||||||
|
*
|
||||||
|
* This copyright statement cannot be altered.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The following changes have been addressed:
|
||||||
|
*
|
||||||
|
* Enhancements:
|
||||||
|
* - re-styled code for better readability
|
||||||
|
* - upgraded backend API to reflect recent changes
|
||||||
|
* - LDAP schema is checked when loading SQL/LDAP mapping
|
||||||
|
* - AttributeDescription/ObjectClass pointers used for more efficient
|
||||||
|
* mapping lookup
|
||||||
|
* - bervals used where string length is required often
|
||||||
|
* - atomized write operations by committing at the end of each operation
|
||||||
|
* and defaulting connection closure to rollback
|
||||||
|
* - added LDAP access control to write operations
|
||||||
|
* - fully implemented modrdn (with rdn attrs change, deleteoldrdn,
|
||||||
|
* access check, parent/children check and more)
|
||||||
|
* - added parent access control, children control to delete operation
|
||||||
|
* - added structuralObjectClass operational attribute check and
|
||||||
|
* value return on search
|
||||||
|
* - added hasSubordinate operational attribute on demand
|
||||||
|
* - search limits are appropriately enforced
|
||||||
|
* - function backsql_strcat() has been made more efficient
|
||||||
|
* - concat function has been made configurable by means of a pattern
|
||||||
|
* - added config switches:
|
||||||
|
* - fail_if_no_mapping write operations fail if there is no mapping
|
||||||
|
* - has_ldapinfo_dn_ru overrides autodetect
|
||||||
|
* - concat_pattern a string containing two '?' is used
|
||||||
|
* (note that "?||?" should be more portable
|
||||||
|
* than builtin function "CONCAT(?,?)")
|
||||||
|
* - strcast_func cast of string constants in "SELECT DISTINCT
|
||||||
|
* statements (needed by PostgreSQL)
|
||||||
|
* - upper_needs_cast cast the argument of upper when required
|
||||||
|
* (basically when building dn substring queries)
|
||||||
|
*
|
||||||
|
* Todo:
|
||||||
|
* - add security checks for SQL statements that can be injected (?)
|
||||||
|
* - re-test with previously supported RDBMs
|
||||||
|
* - replace dn_ru and so with normalized dn (no need for upper() and so
|
||||||
|
* in dn match)
|
||||||
|
* - implement a backsql_normalize() function to replace the upper()
|
||||||
|
* conversion routines
|
||||||
|
* - note that subtree deletion, subtree renaming and so could be easily
|
||||||
|
* implemented (rollback and consistency checks are available :)
|
||||||
|
* - implement "lastmod" and other operational stuff (ldap_entries table ?)
|
||||||
|
* - check how to allow multiple operations with one statement, to remove
|
||||||
|
* BACKSQL_REALLOC_STMT from modify.c (a more recent unixODBC lib?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BACKSQL_H__
|
||||||
|
#define __BACKSQL_H__
|
||||||
|
|
||||||
#include "external.h"
|
#include "external.h"
|
||||||
#include "sql-types.h"
|
#include "sql-types.h"
|
||||||
|
|
@ -18,6 +75,12 @@
|
||||||
*/
|
*/
|
||||||
#define BACKSQL_MAX_DN_LEN 255
|
#define BACKSQL_MAX_DN_LEN 255
|
||||||
|
|
||||||
|
/*
|
||||||
|
* define to enable very extensive trace logging (debug only)
|
||||||
|
*/
|
||||||
|
#undef BACKSQL_TRACE
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *dbhost;
|
char *dbhost;
|
||||||
int dbport;
|
int dbport;
|
||||||
|
|
@ -26,27 +89,51 @@ typedef struct {
|
||||||
char *dbname;
|
char *dbname;
|
||||||
/*
|
/*
|
||||||
* SQL condition for subtree searches differs in syntax:
|
* SQL condition for subtree searches differs in syntax:
|
||||||
* "LIKE CONCAT('%',?)" or "LIKE '%'+?" or smth else
|
* "LIKE CONCAT('%',?)" or "LIKE '%'+?" or "LIKE '%'||?"
|
||||||
|
* or smth else
|
||||||
*/
|
*/
|
||||||
char *subtree_cond;
|
struct berval subtree_cond;
|
||||||
|
struct berval children_cond;
|
||||||
char *oc_query, *at_query;
|
char *oc_query, *at_query;
|
||||||
char *insentry_query,*delentry_query;
|
char *insentry_query,*delentry_query;
|
||||||
char *id_query;
|
char *id_query;
|
||||||
char *upper_func;
|
char *has_children_query;
|
||||||
char *strcast_func;
|
struct berval upper_func;
|
||||||
|
struct berval upper_func_open;
|
||||||
|
struct berval upper_func_close;
|
||||||
|
BerVarray concat_func;
|
||||||
|
|
||||||
|
unsigned int bsql_flags;
|
||||||
|
#define BSQLF_SCHEMA_LOADED 0x0001
|
||||||
|
#define BSQLF_UPPER_NEEDS_CAST 0x0002
|
||||||
|
#define BSQLF_CREATE_NEEDS_SELECT 0x0004
|
||||||
|
#define BSQLF_FAIL_IF_NO_MAPPING 0x0008
|
||||||
|
#define BSQLF_HAS_LDAPINFO_DN_RU 0x0010
|
||||||
|
#define BSQLF_DONTCHECK_LDAPINFO_DN_RU 0x0020
|
||||||
|
#define BSQLF_USE_REVERSE_DN 0x0040
|
||||||
|
|
||||||
|
#define BACKSQL_SCHEMA_LOADED(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_SCHEMA_LOADED)
|
||||||
|
#define BACKSQL_UPPER_NEEDS_CAST(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_UPPER_NEEDS_CAST)
|
||||||
|
#define BACKSQL_CREATE_NEEDS_SELECT(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_CREATE_NEEDS_SELECT)
|
||||||
|
#define BACKSQL_FAIL_IF_NO_MAPPING(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_FAIL_IF_NO_MAPPING)
|
||||||
|
#define BACKSQL_HAS_LDAPINFO_DN_RU(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_HAS_LDAPINFO_DN_RU)
|
||||||
|
#define BACKSQL_DONTCHECK_LDAPINFO_DN_RU(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_DONTCHECK_LDAPINFO_DN_RU)
|
||||||
|
#define BACKSQL_USE_REVERSE_DN(si) \
|
||||||
|
((si)->bsql_flags & BSQLF_USE_REVERSE_DN)
|
||||||
|
|
||||||
|
struct berval strcast_func;
|
||||||
Avlnode *db_conns;
|
Avlnode *db_conns;
|
||||||
Avlnode *oc_by_oc;
|
Avlnode *oc_by_oc;
|
||||||
Avlnode *oc_by_id;
|
Avlnode *oc_by_id;
|
||||||
int schema_loaded;
|
|
||||||
ldap_pvt_thread_mutex_t dbconn_mutex;
|
ldap_pvt_thread_mutex_t dbconn_mutex;
|
||||||
ldap_pvt_thread_mutex_t schema_mutex;
|
ldap_pvt_thread_mutex_t schema_mutex;
|
||||||
SQLHENV db_env;
|
SQLHENV db_env;
|
||||||
int isTimesTen;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Does ldapinfo.dn_ru exist in schema?
|
|
||||||
*/
|
|
||||||
int has_ldapinfo_dn_ru;
|
|
||||||
} backsql_info;
|
} backsql_info;
|
||||||
|
|
||||||
#define BACKSQL_SUCCESS( rc ) \
|
#define BACKSQL_SUCCESS( rc ) \
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
#include "slap.h"
|
#include "slap.h"
|
||||||
#include "back-sql.h"
|
#include "back-sql.h"
|
||||||
#include "sql-wrap.h"
|
#include "sql-wrap.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
backsql_db_config(
|
backsql_db_config(
|
||||||
|
|
@ -35,7 +36,7 @@ backsql_db_config(
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing hostname in dbhost directive\n",
|
"missing hostname in \"dbhost\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +49,7 @@ backsql_db_config(
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing username in dbuser directive\n",
|
"missing username in \"dbuser\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +61,7 @@ backsql_db_config(
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing password in dbpasswd directive\n",
|
"missing password in \"dbpasswd\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -72,33 +73,53 @@ backsql_db_config(
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing database name in dbname directive\n",
|
"missing database name in \"dbname\" "
|
||||||
fname, lineno, 0 );
|
"directive\n", fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
si->dbname = ch_strdup( argv[ 1 ] );
|
si->dbname = ch_strdup( argv[ 1 ] );
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n",
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): dbname=%s\n",
|
||||||
si->dbname, 0, 0 );
|
si->dbname, 0, 0 );
|
||||||
|
|
||||||
|
} else if ( !strcasecmp( argv[ 0 ], "concat_pattern" ) ) {
|
||||||
|
if ( argc < 2 ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"missing pattern"
|
||||||
|
"in \"concat_pattern\" directive\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if ( backsql_split_pattern( argv[ 1 ], &si->concat_func, 2 ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"unable to parse pattern \"%s\"\n"
|
||||||
|
"in \"concat_pattern\" directive\n",
|
||||||
|
fname, lineno, argv[ 1 ] );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
|
"concat_pattern=\"%s\"\n", argv[ 1 ], 0, 0 );
|
||||||
|
|
||||||
} else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
|
} else if ( !strcasecmp( argv[ 0 ], "subtree_cond" ) ) {
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing SQL condition "
|
"missing SQL condition "
|
||||||
"in subtree_cond directive\n",
|
"in \"subtree_cond\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
si->subtree_cond = ch_strdup( argv[ 1 ] );
|
ber_str2bv( argv[ 1 ], 0, 1, &si->subtree_cond );
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
"subtree_cond=%s\n", si->subtree_cond, 0, 0 );
|
"subtree_cond=%s\n", si->subtree_cond.bv_val, 0, 0 );
|
||||||
|
|
||||||
} else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
|
} else if ( !strcasecmp( argv[ 0 ], "oc_query" ) ) {
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing SQL statement "
|
"missing SQL statement "
|
||||||
"in oc_query directive\n",
|
"in \"oc_query\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +132,7 @@ backsql_db_config(
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing SQL statement "
|
"missing SQL statement "
|
||||||
"in at_query directive\n",
|
"in \"at_query\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +145,7 @@ backsql_db_config(
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing SQL statement "
|
"missing SQL statement "
|
||||||
"in insentry_query directive\n",
|
"in \"insentry_query\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -132,38 +153,97 @@ backsql_db_config(
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
"insentry_query=%s\n", si->insentry_query, 0, 0 );
|
"insentry_query=%s\n", si->insentry_query, 0, 0 );
|
||||||
|
|
||||||
|
} else if ( !strcasecmp( argv[ 0 ], "create_needs_select" ) ) {
|
||||||
|
if ( argc < 2 ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"missing { yes | no }"
|
||||||
|
"in \"create_needs_select\" directive\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
|
||||||
|
si->bsql_flags |= BSQLF_CREATE_NEEDS_SELECT;
|
||||||
|
|
||||||
|
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
|
||||||
|
si->bsql_flags &= ~BSQLF_CREATE_NEEDS_SELECT;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"\"create_needs_select\" directive arg "
|
||||||
|
"must be \"yes\" or \"no\"\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
|
"create_needs_select =%s\n",
|
||||||
|
BACKSQL_CREATE_NEEDS_SELECT( si ) ? "yes" : "no",
|
||||||
|
0, 0 );
|
||||||
|
|
||||||
} else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
|
} else if ( !strcasecmp( argv[ 0 ], "upper_func" ) ) {
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing function name "
|
"missing function name "
|
||||||
"in upper_func directive\n",
|
"in \"upper_func\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
si->upper_func = ch_strdup( argv[ 1 ] );
|
ber_str2bv( argv[ 1 ], 0, 1, &si->upper_func );
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
"upper_func=%s\n", si->upper_func, 0, 0 );
|
"upper_func=%s\n", si->upper_func.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
} else if ( !strcasecmp( argv[ 0 ], "upper_needs_cast" ) ) {
|
||||||
|
if ( argc < 2 ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"missing { yes | no }"
|
||||||
|
"in \"upper_needs_cast\" directive\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
|
||||||
|
si->bsql_flags |= BSQLF_UPPER_NEEDS_CAST;
|
||||||
|
|
||||||
|
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
|
||||||
|
si->bsql_flags &= ~BSQLF_UPPER_NEEDS_CAST;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"\"upper_needs_cast\" directive arg "
|
||||||
|
"must be \"yes\" or \"no\"\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
|
"upper_needs_cast =%s\n",
|
||||||
|
BACKSQL_UPPER_NEEDS_CAST( si ) ? "yes" : "no", 0, 0 );
|
||||||
|
|
||||||
} else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
|
} else if ( !strcasecmp( argv[ 0 ], "strcast_func" ) ) {
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing function name "
|
"missing function name "
|
||||||
"in strcast_func directive\n",
|
"in \"strcast_func\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
si->strcast_func = ch_strdup( argv[ 1 ] );
|
ber_str2bv( argv[ 1 ], 0, 1, &si->strcast_func );
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
"strcast_func=%s\n", si->strcast_func, 0, 0 );
|
"strcast_func=%s\n", si->strcast_func.bv_val, 0, 0 );
|
||||||
|
|
||||||
} else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
|
} else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
|
||||||
if ( argc < 2 ) {
|
if ( argc < 2 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing SQL statement "
|
"missing SQL statement "
|
||||||
"in delentry_query directive\n",
|
"in \"delentry_query\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -176,19 +256,23 @@ backsql_db_config(
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"missing { yes | no }"
|
"missing { yes | no }"
|
||||||
"in has_ldapinfo_dn_ru directive\n",
|
"in \"has_ldapinfo_dn_ru\" directive\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
|
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
|
||||||
si->has_ldapinfo_dn_ru = 1;
|
si->bsql_flags |= BSQLF_HAS_LDAPINFO_DN_RU;
|
||||||
|
si->bsql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
|
||||||
|
|
||||||
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
|
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
|
||||||
si->has_ldapinfo_dn_ru = 0;
|
si->bsql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU;
|
||||||
|
si->bsql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"<==backsql_db_config (%s line %d): "
|
"<==backsql_db_config (%s line %d): "
|
||||||
"has_ldapinfo_dn_ru directive arg "
|
"\"has_ldapinfo_dn_ru\" directive arg "
|
||||||
"must be \"yes\" or \"no\"\n",
|
"must be \"yes\" or \"no\"\n",
|
||||||
fname, lineno, 0 );
|
fname, lineno, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -196,11 +280,40 @@ backsql_db_config(
|
||||||
}
|
}
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
"has_ldapinfo_dn_ru=%s\n",
|
"has_ldapinfo_dn_ru=%s\n",
|
||||||
si->has_ldapinfo_dn_ru == 0 ? "no" : "yes", 0, 0 );
|
BACKSQL_HAS_LDAPINFO_DN_RU( si ) ? "yes" : "no", 0, 0 );
|
||||||
|
|
||||||
|
} else if ( !strcasecmp( argv[ 0 ], "fail_if_no_mapping") ) {
|
||||||
|
if ( argc < 2 ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"missing { yes | no }"
|
||||||
|
"in \"fail_if_no_mapping\" directive\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strcasecmp( argv[ 1 ], "yes" ) == 0 ) {
|
||||||
|
si->bsql_flags |= BSQLF_FAIL_IF_NO_MAPPING;
|
||||||
|
|
||||||
|
} else if ( strcasecmp( argv[ 1 ], "no" ) == 0 ) {
|
||||||
|
si->bsql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"<==backsql_db_config (%s line %d): "
|
||||||
|
"\"fail_if_no_mapping\" directive arg "
|
||||||
|
"must be \"yes\" or \"no\"\n",
|
||||||
|
fname, lineno, 0 );
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
|
||||||
|
"fail_if_no_mapping=%s\n",
|
||||||
|
BACKSQL_FAIL_IF_NO_MAPPING( si ) ? "yes" : "no", 0, 0 );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): "
|
||||||
"unknown directive '%s' (ignored)\n",
|
"unknown directive \"%s\" (ignored)\n",
|
||||||
fname, lineno, argv[ 0 ] );
|
fname, lineno, argv[ 0 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,11 +42,6 @@ backsql_free_entryID( backsql_entryID *id, int freeit )
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
int
|
||||||
backsql_dn2id(
|
backsql_dn2id(
|
||||||
backsql_info *bi,
|
backsql_info *bi,
|
||||||
|
|
@ -56,9 +51,6 @@ backsql_dn2id(
|
||||||
{
|
{
|
||||||
SQLHSTMT sth;
|
SQLHSTMT sth;
|
||||||
BACKSQL_ROW_NTS row;
|
BACKSQL_ROW_NTS row;
|
||||||
#if 0
|
|
||||||
SQLINTEGER nrows = 0;
|
|
||||||
#endif
|
|
||||||
RETCODE rc;
|
RETCODE rc;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
|
@ -93,7 +85,7 @@ backsql_dn2id(
|
||||||
return LDAP_OTHER;
|
return LDAP_OTHER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( bi->has_ldapinfo_dn_ru ) {
|
if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
|
||||||
/*
|
/*
|
||||||
* Prepare an upper cased, byte reversed version
|
* Prepare an upper cased, byte reversed version
|
||||||
* that can be searched using indexes
|
* that can be searched using indexes
|
||||||
|
|
@ -109,7 +101,7 @@ backsql_dn2id(
|
||||||
upperdn, 0, 0 );
|
upperdn, 0, 0 );
|
||||||
toBind = upperdn;
|
toBind = upperdn;
|
||||||
} else {
|
} else {
|
||||||
if ( bi->isTimesTen ) {
|
if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
|
||||||
AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 );
|
AC_MEMCPY( upperdn, dn->bv_val, dn->bv_len + 1 );
|
||||||
ldap_pvt_str2upper( upperdn );
|
ldap_pvt_str2upper( upperdn );
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
|
@ -126,7 +118,8 @@ backsql_dn2id(
|
||||||
if ( rc != SQL_SUCCESS) {
|
if ( rc != SQL_SUCCESS) {
|
||||||
/* end TimesTen */
|
/* end TimesTen */
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_dn2id(): "
|
||||||
"error binding dn=\"%s\" parameter:\n", toBind, 0, 0 );
|
"error binding dn=\"%s\" parameter:\n",
|
||||||
|
toBind, 0, 0 );
|
||||||
backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
|
backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
return LDAP_OTHER;
|
return LDAP_OTHER;
|
||||||
|
|
@ -145,9 +138,9 @@ backsql_dn2id(
|
||||||
backsql_BindRowAsStrings( sth, &row );
|
backsql_BindRowAsStrings( sth, &row );
|
||||||
rc = SQLFetch( sth );
|
rc = SQLFetch( sth );
|
||||||
if ( BACKSQL_SUCCESS( rc ) ) {
|
if ( BACKSQL_SUCCESS( rc ) ) {
|
||||||
id->id = atoi( row.cols[ 0 ] );
|
id->id = strtol( row.cols[ 0 ], NULL, 0 );
|
||||||
id->keyval = atoi( row.cols[ 1 ] );
|
id->keyval = strtol( row.cols[ 1 ], NULL, 0 );
|
||||||
id->oc_id = atoi( row.cols[ 2 ] );
|
id->oc_id = strtol( row.cols[ 2 ], NULL, 0 );
|
||||||
ber_dupbv( &id->dn, dn );
|
ber_dupbv( &id->dn, dn );
|
||||||
id->next = NULL;
|
id->next = NULL;
|
||||||
|
|
||||||
|
|
@ -169,6 +162,86 @@ backsql_dn2id(
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
backsql_has_children(
|
||||||
|
backsql_info *bi,
|
||||||
|
SQLHDBC dbh,
|
||||||
|
struct berval *dn )
|
||||||
|
{
|
||||||
|
SQLHSTMT sth;
|
||||||
|
BACKSQL_ROW_NTS row;
|
||||||
|
RETCODE rc;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_has_children(): dn='%s'\n",
|
||||||
|
dn->bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( dn->bv_len > BACKSQL_MAX_DN_LEN ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_has_children(): 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, "children id query '%s'\n",
|
||||||
|
bi->has_children_query, 0, 0);
|
||||||
|
assert( bi->has_children_query );
|
||||||
|
rc = backsql_Prepare( dbh, &sth, bi->has_children_query, 0 );
|
||||||
|
if ( rc != SQL_SUCCESS ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_has_children(): error preparing SQL:\n%s",
|
||||||
|
bi->has_children_query, 0, 0);
|
||||||
|
backsql_PrintErrors( SQL_NULL_HENV, dbh, sth, rc );
|
||||||
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
return LDAP_OTHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = backsql_BindParamStr( sth, 1, dn->bv_val, BACKSQL_MAX_DN_LEN );
|
||||||
|
if ( rc != SQL_SUCCESS) {
|
||||||
|
/* end TimesTen */
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_has_children(): "
|
||||||
|
"error binding dn=\"%s\" parameter:\n",
|
||||||
|
dn->bv_val, 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_has_children(): "
|
||||||
|
"error executing query (\"%s\", \"%s\"):\n",
|
||||||
|
bi->has_children_query, dn->bv_val, 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 ) ) {
|
||||||
|
if ( strtol( row.cols[ 0 ], NULL, 0 ) > 0 ) {
|
||||||
|
res = LDAP_COMPARE_TRUE;
|
||||||
|
} else {
|
||||||
|
res = LDAP_COMPARE_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
}
|
||||||
|
backsql_FreeRow( &row );
|
||||||
|
|
||||||
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_has_children(): %s\n",
|
||||||
|
res == LDAP_COMPARE_TRUE ? "yes" : "no", 0, 0 );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
|
backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
|
||||||
{
|
{
|
||||||
|
|
@ -182,7 +255,9 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
|
||||||
"oc='%s' attr='%s' keyval=%ld\n",
|
"oc='%s' attr='%s' keyval=%ld\n",
|
||||||
bsi->oc->name.bv_val, at->name.bv_val, bsi->c_eid->keyval );
|
// bsi->oc->name.bv_val, at->name.bv_val,
|
||||||
|
bsi->oc->oc->soc_names[0], at->ad->ad_cname.bv_val,
|
||||||
|
bsi->c_eid->keyval );
|
||||||
|
|
||||||
rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
|
rc = backsql_Prepare( bsi->dbh, &sth, at->query, 0 );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
|
|
@ -230,14 +305,14 @@ backsql_get_attr_vals( backsql_at_map_rec *at, backsql_srch_info *bsi )
|
||||||
backsql_entry_addattr( bsi->e,
|
backsql_entry_addattr( bsi->e,
|
||||||
&row.col_names[ i ], &bv );
|
&row.col_names[ i ], &bv );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
|
Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
|
||||||
(int)row.col_prec[ i ], 0, 0 );
|
(int)row.col_prec[ i ], 0, 0 );
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE, "NULL value "
|
Debug( LDAP_DEBUG_TRACE, "NULL value "
|
||||||
"in this row for attribute '%s'\n",
|
"in this row for attribute '%s'\n",
|
||||||
row.col_names[ i ].bv_val, 0, 0 );
|
row.col_names[ i ].bv_val, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -255,6 +330,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
||||||
int i;
|
int i;
|
||||||
backsql_at_map_rec *at;
|
backsql_at_map_rec *at;
|
||||||
int rc;
|
int rc;
|
||||||
|
AttributeDescription *ad_oc = slap_schema.si_ad_objectClass;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 );
|
||||||
|
|
||||||
|
|
@ -279,7 +355,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
||||||
for ( i = 0; bsi->attrs[ i ].an_name.bv_val; i++ ) {
|
for ( i = 0; bsi->attrs[ i ].an_name.bv_val; i++ ) {
|
||||||
AttributeName *attr = &bsi->attrs[ i ];
|
AttributeName *attr = &bsi->attrs[ i ];
|
||||||
|
|
||||||
if ( attr->an_desc == slap_schema.si_ad_objectClass
|
if ( attr->an_desc == ad_oc
|
||||||
#if 0 /* FIXME: what is 0.10 ? */
|
#if 0 /* FIXME: what is 0.10 ? */
|
||||||
|| !BACKSQL_NCMP( &attr->an_name, &bv_n_0_10 )
|
|| !BACKSQL_NCMP( &attr->an_name, &bv_n_0_10 )
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -303,6 +379,7 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
||||||
bsi->oc->name.bv_val, 0 );
|
bsi->oc->name.bv_val, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): "
|
||||||
"retrieving all attributes\n", 0, 0, 0 );
|
"retrieving all attributes\n", 0, 0, 0 );
|
||||||
|
|
@ -310,7 +387,35 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
|
||||||
bsi, 0, AVL_INORDER );
|
bsi, 0, AVL_INORDER );
|
||||||
}
|
}
|
||||||
|
|
||||||
backsql_entry_addattr( bsi->e, &bv_n_objectclass, &bsi->oc->name );
|
if ( attr_merge_one( bsi->e, ad_oc, &bsi->oc->name ) ) {
|
||||||
|
entry_free( e );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( global_schemacheck ) {
|
||||||
|
const char *text = NULL;
|
||||||
|
char textbuf[ 1024 ];
|
||||||
|
size_t textlen = sizeof( textbuf );
|
||||||
|
struct berval bv[ 2 ] = { bsi->oc->name, { 0, NULL } };
|
||||||
|
struct berval soc;
|
||||||
|
AttributeDescription *ad_soc
|
||||||
|
= slap_schema.si_ad_structuralObjectClass;
|
||||||
|
|
||||||
|
int rc = structural_class( bv, &soc, NULL,
|
||||||
|
&text, textbuf, textlen );
|
||||||
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
|
entry_free( e );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bsi->attr_flags | BSQL_SF_ALL_OPER
|
||||||
|
|| an_find( bsi->attrs, &AllOper ) ) {
|
||||||
|
if ( attr_merge_one( bsi->e, ad_soc, &soc ) ) {
|
||||||
|
entry_free( e );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ typedef struct backsql_entryID {
|
||||||
|
|
||||||
int backsql_dn2id( backsql_info *bi, backsql_entryID *id,
|
int backsql_dn2id( backsql_info *bi, backsql_entryID *id,
|
||||||
SQLHDBC dbh, struct berval *dn );
|
SQLHDBC dbh, struct berval *dn );
|
||||||
|
int backsql_has_children( backsql_info *bi, SQLHDBC dbh, struct berval *dn );
|
||||||
|
|
||||||
/* returns next */
|
/* returns next */
|
||||||
backsql_entryID *backsql_free_entryID( backsql_entryID *id, int freeit );
|
backsql_entryID *backsql_free_entryID( backsql_entryID *id, int freeit );
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@ extern BI_op_add backsql_add;
|
||||||
extern BI_op_delete backsql_delete;
|
extern BI_op_delete backsql_delete;
|
||||||
extern BI_op_abandon backsql_abandon;
|
extern BI_op_abandon backsql_abandon;
|
||||||
|
|
||||||
|
extern BI_operational backsql_operational;
|
||||||
|
|
||||||
extern BI_connection_destroy backsql_connection_destroy;
|
extern BI_connection_destroy backsql_connection_destroy;
|
||||||
|
|
||||||
LDAP_END_DECL
|
LDAP_END_DECL
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ sql_back_initialize(
|
||||||
bi->bi_acl_group = 0;
|
bi->bi_acl_group = 0;
|
||||||
bi->bi_acl_attribute = 0;
|
bi->bi_acl_attribute = 0;
|
||||||
bi->bi_chk_referrals = 0;
|
bi->bi_chk_referrals = 0;
|
||||||
|
bi->bi_operational = backsql_operational;
|
||||||
|
|
||||||
bi->bi_connection_init = 0;
|
bi->bi_connection_init = 0;
|
||||||
bi->bi_connection_destroy = backsql_connection_destroy;
|
bi->bi_connection_destroy = backsql_connection_destroy;
|
||||||
|
|
@ -100,10 +101,10 @@ backsql_db_init(
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 );
|
||||||
si = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) );
|
si = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) );
|
||||||
|
memset( si, '\0', sizeof( backsql_info ) );
|
||||||
ldap_pvt_thread_mutex_init( &si->dbconn_mutex );
|
ldap_pvt_thread_mutex_init( &si->dbconn_mutex );
|
||||||
ldap_pvt_thread_mutex_init( &si->schema_mutex );
|
ldap_pvt_thread_mutex_init( &si->schema_mutex );
|
||||||
backsql_init_db_env( si );
|
backsql_init_db_env( si );
|
||||||
si->has_ldapinfo_dn_ru = -1;
|
|
||||||
|
|
||||||
bd->be_private = si;
|
bd->be_private = si;
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 );
|
||||||
|
|
@ -120,11 +121,11 @@ backsql_db_destroy(
|
||||||
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
|
ldap_pvt_thread_mutex_lock( &si->dbconn_mutex );
|
||||||
backsql_free_db_env( si );
|
backsql_free_db_env( si );
|
||||||
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
|
ldap_pvt_thread_mutex_unlock( &si->dbconn_mutex );
|
||||||
|
ldap_pvt_thread_mutex_destroy( &si->dbconn_mutex );
|
||||||
ldap_pvt_thread_mutex_lock( &si->schema_mutex );
|
ldap_pvt_thread_mutex_lock( &si->schema_mutex );
|
||||||
backsql_destroy_schema_map( si );
|
backsql_destroy_schema_map( si );
|
||||||
ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
|
ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
|
||||||
ldap_pvt_thread_mutex_destroy( &si->schema_mutex );
|
ldap_pvt_thread_mutex_destroy( &si->schema_mutex );
|
||||||
ldap_pvt_thread_mutex_destroy( &si->dbconn_mutex );
|
|
||||||
free( si->dbname );
|
free( si->dbname );
|
||||||
free( si->dbuser );
|
free( si->dbuser );
|
||||||
if ( si->dbpasswd ) {
|
if ( si->dbpasswd ) {
|
||||||
|
|
@ -133,11 +134,13 @@ backsql_db_destroy(
|
||||||
if ( si->dbhost ) {
|
if ( si->dbhost ) {
|
||||||
free( si->dbhost );
|
free( si->dbhost );
|
||||||
}
|
}
|
||||||
if ( si->upper_func ) {
|
if ( si->upper_func.bv_val ) {
|
||||||
free( si->upper_func );
|
free( si->upper_func.bv_val );
|
||||||
|
free( si->upper_func_open.bv_val );
|
||||||
|
free( si->upper_func_close.bv_val );
|
||||||
}
|
}
|
||||||
|
|
||||||
free( si->subtree_cond );
|
free( si->subtree_cond.bv_val );
|
||||||
free( si->oc_query );
|
free( si->oc_query );
|
||||||
free( si->at_query );
|
free( si->at_query );
|
||||||
free( si->insentry_query );
|
free( si->insentry_query );
|
||||||
|
|
@ -155,7 +158,7 @@ backsql_db_open(
|
||||||
backsql_info *si = (backsql_info*)bd->be_private;
|
backsql_info *si = (backsql_info*)bd->be_private;
|
||||||
Connection tmp;
|
Connection tmp;
|
||||||
SQLHDBC dbh;
|
SQLHDBC dbh;
|
||||||
int idq_len;
|
ber_len_t idq_len;
|
||||||
struct berval bv;
|
struct berval bv;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
|
||||||
|
|
@ -163,52 +166,194 @@ backsql_db_open(
|
||||||
if ( si->dbname == NULL ) {
|
if ( si->dbname == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"datasource name not specified "
|
"datasource name not specified "
|
||||||
"(use dbname directive in slapd.conf)\n", 0, 0, 0 );
|
"(use \"dbname\" directive in slapd.conf)\n", 0, 0, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( si->concat_func == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
"concat func not specified (use \"concat_pattern\" "
|
||||||
|
"directive in slapd.conf)\n", 0, 0, 0 );
|
||||||
|
|
||||||
|
if ( backsql_split_pattern( backsql_def_concat_func,
|
||||||
|
&si->concat_func, 2 ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
"unable to parse pattern '%s'",
|
||||||
|
backsql_def_concat_func, 0, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare cast string as required
|
||||||
|
*/
|
||||||
|
if ( si->upper_func.bv_val ) {
|
||||||
|
char buf[1024];
|
||||||
|
|
||||||
|
if ( BACKSQL_UPPER_NEEDS_CAST( si ) ) {
|
||||||
|
snprintf( buf, sizeof( buf ),
|
||||||
|
"%s(cast (" /* ? as varchar(%d))) */ ,
|
||||||
|
si->upper_func.bv_val );
|
||||||
|
ber_str2bv( buf, 0, 1, &si->upper_func_open );
|
||||||
|
|
||||||
|
snprintf( buf, sizeof( buf ),
|
||||||
|
/* (cast(? */ " as varchar(%d)))",
|
||||||
|
BACKSQL_MAX_DN_LEN );
|
||||||
|
ber_str2bv( buf, 0, 1, &si->upper_func_close );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
snprintf( buf, sizeof( buf ), "%s(" /* ?) */ ,
|
||||||
|
si->upper_func.bv_val );
|
||||||
|
ber_str2bv( buf, 0, 1, &si->upper_func_open );
|
||||||
|
|
||||||
|
ber_str2bv( /* (? */ ")", 0, 1, &si->upper_func_close );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( si->dbuser == NULL ) {
|
if ( si->dbuser == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"user name not specified "
|
"user name not specified "
|
||||||
"(use dbuser directive in slapd.conf)\n", 0, 0, 0 );
|
"(use \"dbuser\" directive in slapd.conf)\n", 0, 0, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( si->subtree_cond.bv_val == NULL ) {
|
||||||
|
/*
|
||||||
|
* Prepare concat function for subtree search condition
|
||||||
|
*/
|
||||||
|
struct berval concat;
|
||||||
|
ber_len_t len = 0;
|
||||||
|
struct berval values[] = {
|
||||||
|
{ sizeof( "'%'" ) - 1, "'%'" },
|
||||||
|
{ sizeof( "?" ) - 1, "?" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( backsql_prepare_pattern( si->concat_func, values,
|
||||||
|
&concat ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
"unable to prepare CONCAT pattern", 0, 0, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( si->subtree_cond == NULL ) {
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"subtree search SQL condition not specified "
|
"subtree search SQL condition not specified "
|
||||||
"(use subtree_cond directive in slapd.conf)\n",
|
"(use \"subtree_cond\" directive in slapd.conf)\n",
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if ( si->upper_func ) {
|
|
||||||
struct berval bv = { 0, NULL };
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
backsql_strcat( &bv, &len, si->upper_func,
|
si->subtree_cond.bv_val = NULL;
|
||||||
backsql_def_upper_subtree_cond, NULL );
|
si->subtree_cond.bv_len = 0;
|
||||||
si->subtree_cond = bv.bv_val;
|
|
||||||
|
if ( si->upper_func.bv_val ) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?))
|
||||||
|
*/
|
||||||
|
|
||||||
|
backsql_strfcat( &si->subtree_cond, &len, "blbbb",
|
||||||
|
&si->upper_func,
|
||||||
|
(ber_len_t)sizeof( "(ldap_entries.dn) LIKE " ) - 1,
|
||||||
|
"(ldap_entries.dn) LIKE ",
|
||||||
|
&si->upper_func_open,
|
||||||
|
&concat,
|
||||||
|
&si->upper_func_close );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
si->subtree_cond = ch_strdup( backsql_def_subtree_cond );
|
|
||||||
|
/*
|
||||||
|
* ldap_entries.dn LIKE CONCAT('%',?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
backsql_strfcat( &si->subtree_cond, &len, "lb",
|
||||||
|
(ber_len_t)sizeof( "ldap_entries.dn LIKE " ) - 1,
|
||||||
|
"ldap_entries.dn LIKE ",
|
||||||
|
&concat );
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"setting '%s' as default\n",
|
"setting '%s' as default\n",
|
||||||
si->subtree_cond, 0, 0 );
|
si->subtree_cond.bv_val, 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( si->children_cond.bv_val == NULL ) {
|
||||||
|
/*
|
||||||
|
* Prepare concat function for children search condition
|
||||||
|
*/
|
||||||
|
struct berval concat;
|
||||||
|
ber_len_t len = 0;
|
||||||
|
struct berval values[] = {
|
||||||
|
{ sizeof( "'%,'" ) - 1, "'%,'" },
|
||||||
|
{ sizeof( "?" ) - 1, "?" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( backsql_prepare_pattern( si->concat_func, values,
|
||||||
|
&concat ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
"unable to prepare CONCAT pattern", 0, 0, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
"children search SQL condition not specified "
|
||||||
|
"(use \"children_cond\" directive in slapd.conf)\n",
|
||||||
|
0, 0, 0);
|
||||||
|
|
||||||
|
si->children_cond.bv_val = NULL;
|
||||||
|
si->children_cond.bv_len = 0;
|
||||||
|
|
||||||
|
if ( si->upper_func.bv_val ) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
|
||||||
|
*/
|
||||||
|
|
||||||
|
backsql_strfcat( &si->children_cond, &len, "blbbb",
|
||||||
|
&si->upper_func,
|
||||||
|
(ber_len_t)sizeof( "(ldap_entries.dn) LIKE " ) - 1,
|
||||||
|
"(ldap_entries.dn) LIKE ",
|
||||||
|
&si->upper_func_open,
|
||||||
|
&concat,
|
||||||
|
&si->upper_func_close );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ldap_entries.dn LIKE CONCAT('%,',?)
|
||||||
|
*/
|
||||||
|
|
||||||
|
backsql_strfcat( &si->children_cond, &len, "lb",
|
||||||
|
(ber_len_t)sizeof( "ldap_entries.dn LIKE " ) - 1,
|
||||||
|
"ldap_entries.dn LIKE ",
|
||||||
|
&concat );
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
"setting '%s' as default\n",
|
||||||
|
si->children_cond.bv_val, 0, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( si->oc_query == NULL ) {
|
if ( si->oc_query == NULL ) {
|
||||||
|
if ( BACKSQL_CREATE_NEEDS_SELECT( si ) ) {
|
||||||
|
si->oc_query =
|
||||||
|
ch_strdup( backsql_def_needs_select_oc_query );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
si->oc_query = ch_strdup( backsql_def_oc_query );
|
||||||
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"objectclass mapping SQL statement not specified "
|
"objectclass mapping SQL statement not specified "
|
||||||
"(use oc_query directive in slapd.conf)\n", 0, 0, 0 );
|
"(use \"oc_query\" directive in slapd.conf)\n",
|
||||||
|
0, 0, 0 );
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"setting '%s' by default\n",
|
"setting '%s' by default\n", si->oc_query, 0, 0 );
|
||||||
backsql_def_oc_query, 0, 0 );
|
|
||||||
si->oc_query = ch_strdup( backsql_def_oc_query );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( si->at_query == NULL ) {
|
if ( si->at_query == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"attribute mapping SQL statement not specified "
|
"attribute mapping SQL statement not specified "
|
||||||
"(use at_query directive in slapd.conf)\n",
|
"(use \"at_query\" directive in slapd.conf)\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"setting '%s' by default\n",
|
"setting '%s' by default\n",
|
||||||
|
|
@ -219,7 +364,7 @@ backsql_db_open(
|
||||||
if ( si->insentry_query == NULL ) {
|
if ( si->insentry_query == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"entry insertion SQL statement not specified "
|
"entry insertion SQL statement not specified "
|
||||||
"(use insentry_query directive in slapd.conf)\n",
|
"(use \"insentry_query\" directive in slapd.conf)\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"setting '%s' by default\n",
|
"setting '%s' by default\n",
|
||||||
|
|
@ -230,7 +375,7 @@ backsql_db_open(
|
||||||
if ( si->delentry_query == NULL ) {
|
if ( si->delentry_query == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"entry deletion SQL statement not specified "
|
"entry deletion SQL statement not specified "
|
||||||
"(use delentry_query directive in slapd.conf)\n",
|
"(use \"delentry_query\" directive in slapd.conf)\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"setting '%s' by default\n",
|
"setting '%s' by default\n",
|
||||||
|
|
@ -238,6 +383,7 @@ backsql_db_open(
|
||||||
si->delentry_query = ch_strdup( backsql_def_delentry_query );
|
si->delentry_query = ch_strdup( backsql_def_delentry_query );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tmp.c_connid =- 1;
|
tmp.c_connid =- 1;
|
||||||
if ( backsql_get_db_conn( bd, &tmp, &dbh ) != LDAP_SUCCESS ) {
|
if ( backsql_get_db_conn( bd, &tmp, &dbh ) != LDAP_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
|
|
@ -245,36 +391,55 @@ backsql_db_open(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare ID selection query
|
||||||
|
*/
|
||||||
si->id_query = NULL;
|
si->id_query = NULL;
|
||||||
idq_len = 0;
|
idq_len = 0;
|
||||||
|
|
||||||
bv.bv_val = NULL;
|
bv.bv_val = NULL;
|
||||||
bv.bv_len = 0;
|
bv.bv_len = 0;
|
||||||
if ( si->upper_func == NULL ) {
|
if ( si->upper_func.bv_val == NULL ) {
|
||||||
backsql_strcat( &bv, &idq_len, backsql_id_query,
|
backsql_strcat( &bv, &idq_len, backsql_id_query,
|
||||||
"dn=?", NULL );
|
"dn=?", NULL );
|
||||||
} else {
|
} else {
|
||||||
if ( si->has_ldapinfo_dn_ru ) {
|
if ( BACKSQL_HAS_LDAPINFO_DN_RU( si ) ) {
|
||||||
backsql_strcat( &bv, &idq_len, backsql_id_query,
|
backsql_strcat( &bv, &idq_len, backsql_id_query,
|
||||||
"dn_ru=?", NULL );
|
"dn_ru=?", NULL );
|
||||||
} else {
|
} else {
|
||||||
if ( si->isTimesTen ) {
|
if ( BACKSQL_USE_REVERSE_DN( si ) ) {
|
||||||
backsql_strcat( &bv, &idq_len,
|
backsql_strfcat( &bv, &idq_len, "sbl",
|
||||||
backsql_id_query,
|
backsql_id_query,
|
||||||
si->upper_func, "(dn)=?",
|
&si->upper_func,
|
||||||
NULL );
|
(ber_len_t)sizeof( "(dn)=?" ) - 1, "(dn)=?" );
|
||||||
} else {
|
} else {
|
||||||
backsql_strcat( &bv, &idq_len,
|
backsql_strfcat( &bv, &idq_len, "sblbcb",
|
||||||
backsql_id_query,
|
backsql_id_query,
|
||||||
si->upper_func, "(dn)=",
|
&si->upper_func,
|
||||||
si->upper_func, "(?)", NULL );
|
(ber_len_t)sizeof( "(dn)=" ) - 1, "(dn)=",
|
||||||
|
&si->upper_func_open,
|
||||||
|
'?',
|
||||||
|
&si->upper_func_close );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
si->id_query = bv.bv_val;
|
si->id_query = bv.bv_val;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prepare children ID selection query
|
||||||
|
*/
|
||||||
|
si->has_children_query = NULL;
|
||||||
|
idq_len = 0;
|
||||||
|
|
||||||
|
bv.bv_val = NULL;
|
||||||
|
bv.bv_len = 0;
|
||||||
|
backsql_strfcat( &bv, &idq_len, "sb",
|
||||||
|
"select count(*) from ldap_entries where ",
|
||||||
|
&si->children_cond );
|
||||||
|
si->has_children_query = bv.bv_val;
|
||||||
|
|
||||||
backsql_free_db_conn( bd, &tmp );
|
backsql_free_db_conn( bd, &tmp );
|
||||||
if ( !si->schema_loaded ) {
|
if ( !BACKSQL_SCHEMA_LOADED( si ) ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
|
||||||
"test failed, schema map not loaded - exiting\n",
|
"test failed, schema map not loaded - exiting\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
|
|
|
||||||
|
|
@ -23,27 +23,48 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PostgreSQL doesn't work without :(
|
* PostgreSQL 7.0 doesn't work without :(
|
||||||
*/
|
*/
|
||||||
#define BACKSQL_REALLOC_STMT
|
#define BACKSQL_REALLOC_STMT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip:
|
||||||
|
* - the first occurrence of objectClass, which is used
|
||||||
|
* to determine how to bulid the SQL entry (FIXME ?!?)
|
||||||
|
* - operational attributes
|
||||||
|
* empty attributes (FIXME ?!?)
|
||||||
|
*/
|
||||||
|
#define backsql_attr_skip(ad,vals) \
|
||||||
|
( \
|
||||||
|
( (ad) == slap_schema.si_ad_objectClass \
|
||||||
|
&& (vals)[ 1 ].bv_val == NULL ) \
|
||||||
|
|| is_at_operational( (ad)->ad_type ) \
|
||||||
|
|| ( (vals)[ 0 ].bv_val == NULL ) \
|
||||||
|
)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
backsql_modify_internal(
|
backsql_modify_internal(
|
||||||
backsql_info *bi,
|
backsql_info *bi,
|
||||||
SQLHDBC dbh,
|
SQLHDBC dbh,
|
||||||
backsql_oc_map_rec *oc,
|
backsql_oc_map_rec *oc,
|
||||||
backsql_entryID *e_id,
|
backsql_entryID *e_id,
|
||||||
Modifications *modlist )
|
Modifications *modlist,
|
||||||
|
const char **text )
|
||||||
{
|
{
|
||||||
RETCODE rc;
|
RETCODE rc;
|
||||||
SQLHSTMT sth;
|
SQLHSTMT sth;
|
||||||
Modifications *ml;
|
Modifications *ml;
|
||||||
|
int res = LDAP_SUCCESS;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_modify_internal(): "
|
||||||
"traversing modifications list\n", 0, 0, 0 );
|
"traversing modifications list\n", 0, 0, 0 );
|
||||||
|
|
||||||
|
*text = NULL;
|
||||||
|
|
||||||
#ifndef BACKSQL_REALLOC_STMT
|
#ifndef BACKSQL_REALLOC_STMT
|
||||||
SQLAllocStmt( dbh, &sth );
|
SQLAllocStmt( dbh, &sth );
|
||||||
#endif /* BACKSQL_REALLOC_STMT */
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
||||||
for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
|
for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
|
||||||
AttributeDescription *ad;
|
AttributeDescription *ad;
|
||||||
backsql_at_map_rec *at = NULL;
|
backsql_at_map_rec *at = NULL;
|
||||||
|
|
@ -60,16 +81,30 @@ backsql_modify_internal(
|
||||||
#endif /* BACKSQL_REALLOC_STMT */
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
||||||
c_mod = &ml->sml_mod;
|
c_mod = &ml->sml_mod;
|
||||||
|
|
||||||
ad = c_mod->sm_desc;
|
ad = c_mod->sm_desc;
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): attribute '%s'\n",
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_modify_internal(): "
|
||||||
|
"modifying attribute '%s'\n",
|
||||||
ad->ad_cname.bv_val, 0, 0 );
|
ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( backsql_attr_skip( ad, c_mod->sm_bvalues ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
at = backsql_ad2at( oc, ad );
|
at = backsql_ad2at( oc, ad );
|
||||||
if ( at == NULL ) {
|
if ( at == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_modify_internal(): "
|
||||||
"attribute provided is not registered "
|
"attribute provided is not registered "
|
||||||
"in objectclass '%s'\n",
|
"in objectClass '%s'\n",
|
||||||
ad->ad_cname.bv_val, 0, 0 );
|
ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
*text = "operation not permitted "
|
||||||
|
"within namingContext";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,57 +113,99 @@ backsql_modify_internal(
|
||||||
SQLHSTMT asth;
|
SQLHSTMT asth;
|
||||||
BACKSQL_ROW_NTS row;
|
BACKSQL_ROW_NTS row;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_modify_internal(): "
|
||||||
"replacing values for attribute '%s'\n",
|
"replacing values for attribute '%s'\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
if ( at->add_proc == NULL ) {
|
if ( at->add_proc == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"add procedure is not defined "
|
"add procedure is not defined "
|
||||||
"for attribute '%s' "
|
"for attribute '%s' "
|
||||||
"- unable to perform replacements\n",
|
"- unable to perform replacements\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
*text = "operation not permitted "
|
||||||
|
"within namingContext";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( at->delete_proc == NULL ) {
|
if ( at->delete_proc == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"delete procedure is not defined "
|
"delete procedure is not defined "
|
||||||
"for attribute '%s' "
|
"for attribute '%s' "
|
||||||
"- adding only\n",
|
"- adding only\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
*text = "operation not permitted "
|
||||||
|
"within namingContext";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
goto add_only;
|
goto add_only;
|
||||||
}
|
}
|
||||||
|
|
||||||
del_all:
|
del_all:
|
||||||
rc = backsql_Prepare( dbh, &asth, at->query, 0 );
|
rc = backsql_Prepare( dbh, &asth, at->query, 0 );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"error preparing query\n", 0, 0, 0 );
|
"error preparing query\n", 0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env, dbh,
|
backsql_PrintErrors( bi->db_env, dbh,
|
||||||
asth, rc );
|
asth, rc );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
*text = "SQL-backend error";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = backsql_BindParamID( asth, 1, &e_id->keyval );
|
rc = backsql_BindParamID( asth, 1, &e_id->keyval );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"error binding key value parameter\n",
|
"error binding key value parameter\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env, dbh,
|
backsql_PrintErrors( bi->db_env, dbh,
|
||||||
asth, rc );
|
asth, rc );
|
||||||
SQLFreeStmt( asth, SQL_DROP );
|
SQLFreeStmt( asth, SQL_DROP );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
*text = "SQL-backend error";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = SQLExecute( asth );
|
rc = SQLExecute( asth );
|
||||||
if ( !BACKSQL_SUCCESS( rc ) ) {
|
if ( !BACKSQL_SUCCESS( rc ) ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"error executing attribute query\n",
|
"error executing attribute query\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env, dbh,
|
backsql_PrintErrors( bi->db_env, dbh,
|
||||||
asth, rc );
|
asth, rc );
|
||||||
SQLFreeStmt( asth, SQL_DROP );
|
SQLFreeStmt( asth, SQL_DROP );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
*text = "SQL-backend error";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,19 +240,25 @@ del_all:
|
||||||
strlen( row.cols[ i ] ), 0 );
|
strlen( row.cols[ i ] ), 0 );
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"backsql_modify(): "
|
"backsql_modify_internal(): "
|
||||||
"executing '%s'\n",
|
"executing '%s'\n",
|
||||||
at->delete_proc, 0, 0 );
|
at->delete_proc, 0, 0 );
|
||||||
rc = SQLExecDirect( sth,
|
rc = SQLExecDirect( sth,
|
||||||
at->delete_proc, SQL_NTS );
|
at->delete_proc, SQL_NTS );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"backsql_modify(): "
|
"backsql_modify_internal(): "
|
||||||
"delete_proc "
|
"delete_proc "
|
||||||
"execution failed\n",
|
"execution failed\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env,
|
backsql_PrintErrors( bi->db_env,
|
||||||
dbh, sth, rc );
|
dbh, sth, rc );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
*text = "SQL-backend error";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef BACKSQL_REALLOC_STMT
|
#ifdef BACKSQL_REALLOC_STMT
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
|
@ -194,24 +277,25 @@ del_all:
|
||||||
case SLAP_MOD_SOFTADD:
|
case SLAP_MOD_SOFTADD:
|
||||||
add_only:;
|
add_only:;
|
||||||
if ( at->add_proc == NULL ) {
|
if ( at->add_proc == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"add procedure is not defined "
|
"add procedure is not defined "
|
||||||
"for attribute '%s'\n",
|
"for attribute '%s'\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
*text = "operation not permitted "
|
||||||
|
"within namingContext";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( c_mod->sm_bvalues == NULL ) {
|
Debug( LDAP_DEBUG_TRACE, "backsql_modify_internal(): "
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
|
||||||
"no values given to add "
|
|
||||||
"for attribute '%s'\n",
|
|
||||||
at->name.bv_val, 0, 0 );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
|
||||||
"adding new values for attribute '%s'\n",
|
"adding new values for attribute '%s'\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
for ( i = 0, at_val = c_mod->sm_bvalues;
|
for ( i = 0, at_val = c_mod->sm_bvalues;
|
||||||
at_val->bv_val != NULL;
|
at_val->bv_val != NULL;
|
||||||
i++, at_val++ ) {
|
i++, at_val++ ) {
|
||||||
|
|
@ -240,18 +324,25 @@ add_only:;
|
||||||
0, 0, at_val->bv_val,
|
0, 0, at_val->bv_val,
|
||||||
at_val->bv_len, 0 );
|
at_val->bv_len, 0 );
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"executing '%s'\n",
|
"executing '%s'\n",
|
||||||
at->add_proc, 0, 0 );
|
at->add_proc, 0, 0 );
|
||||||
rc = SQLExecDirect( sth, at->add_proc,
|
rc = SQLExecDirect( sth, at->add_proc,
|
||||||
SQL_NTS );
|
SQL_NTS );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"backsql_modify(): "
|
"backsql_modify_internal(): "
|
||||||
"add_proc execution failed\n",
|
"add_proc execution failed\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env,
|
backsql_PrintErrors( bi->db_env,
|
||||||
dbh, sth, rc );
|
dbh, sth, rc );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
*text = "SQL-backend error";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef BACKSQL_REALLOC_STMT
|
#ifdef BACKSQL_REALLOC_STMT
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
|
@ -262,25 +353,36 @@ add_only:;
|
||||||
|
|
||||||
case LDAP_MOD_DELETE:
|
case LDAP_MOD_DELETE:
|
||||||
if ( at->delete_proc == NULL ) {
|
if ( at->delete_proc == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"delete procedure is not defined "
|
"delete procedure is not defined "
|
||||||
"for attribute '%s'\n",
|
"for attribute '%s'\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_UNWILLING_TO_PERFORM;
|
||||||
|
*text = "operation not permitted "
|
||||||
|
"within namingContext";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( c_mod->sm_bvalues == NULL ) {
|
if ( c_mod->sm_bvalues == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"no values given to delete "
|
"no values given to delete "
|
||||||
"for attribute '%s' "
|
"for attribute '%s' "
|
||||||
"-- deleting all values\n",
|
"-- deleting all values\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
goto del_all;
|
goto del_all;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_modify_internal(): "
|
||||||
"deleting values for attribute '%s'\n",
|
"deleting values for attribute '%s'\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
for ( i = 0, at_val = c_mod->sm_bvalues;
|
for ( i = 0, at_val = c_mod->sm_bvalues;
|
||||||
at_val->bv_val != NULL;
|
at_val->bv_val != NULL;
|
||||||
i++, at_val++ ) {
|
i++, at_val++ ) {
|
||||||
|
|
@ -308,18 +410,25 @@ add_only:;
|
||||||
0, 0, at_val->bv_val,
|
0, 0, at_val->bv_val,
|
||||||
at_val->bv_len, 0 );
|
at_val->bv_len, 0 );
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modify(): "
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_modify_internal(): "
|
||||||
"executing '%s'\n",
|
"executing '%s'\n",
|
||||||
at->delete_proc, 0, 0 );
|
at->delete_proc, 0, 0 );
|
||||||
rc = SQLExecDirect( sth, at->delete_proc,
|
rc = SQLExecDirect( sth, at->delete_proc,
|
||||||
SQL_NTS );
|
SQL_NTS );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"backsql_modify(): "
|
"backsql_modify_internal(): "
|
||||||
"delete_proc execution "
|
"delete_proc execution "
|
||||||
"failed\n", 0, 0, 0 );
|
"failed\n", 0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env,
|
backsql_PrintErrors( bi->db_env,
|
||||||
dbh, sth, rc );
|
dbh, sth, rc );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
res = LDAP_OTHER;
|
||||||
|
*text = "SQL-backend error";
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef BACKSQL_REALLOC_STMT
|
#ifdef BACKSQL_REALLOC_STMT
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
|
@ -335,6 +444,8 @@ add_only:;
|
||||||
#endif /* BACKSQL_REALLOC_STMT */
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:;
|
||||||
|
|
||||||
#ifndef BACKSQL_REALLOC_STMT
|
#ifndef BACKSQL_REALLOC_STMT
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
#endif /* BACKSQL_REALLOC_STMT */
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
@ -342,7 +453,7 @@ add_only:;
|
||||||
/*
|
/*
|
||||||
* FIXME: should fail in case one change fails?
|
* FIXME: should fail in case one change fails?
|
||||||
*/
|
*/
|
||||||
return LDAP_SUCCESS;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
@ -358,7 +469,9 @@ backsql_modify(
|
||||||
SQLHDBC dbh;
|
SQLHDBC dbh;
|
||||||
backsql_oc_map_rec *oc = NULL;
|
backsql_oc_map_rec *oc = NULL;
|
||||||
backsql_entryID e_id;
|
backsql_entryID e_id;
|
||||||
|
Entry e;
|
||||||
int res;
|
int res;
|
||||||
|
const char *text = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: in case part of the operation cannot be performed
|
* FIXME: in case part of the operation cannot be performed
|
||||||
|
|
@ -415,7 +528,17 @@ backsql_modify(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = backsql_modify_internal( bi, dbh, oc, &e_id, modlist );
|
e.e_attrs = NULL;
|
||||||
|
e.e_name = *dn;
|
||||||
|
e.e_nname = *ndn;
|
||||||
|
if ( !acl_check_modlist( be, conn, op, &e, modlist )) {
|
||||||
|
res = LDAP_INSUFFICIENT_ACCESS;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
res = backsql_modify_internal( bi, dbh, oc, &e_id,
|
||||||
|
modlist, &text );
|
||||||
|
}
|
||||||
|
|
||||||
if ( res == LDAP_SUCCESS ) {
|
if ( res == LDAP_SUCCESS ) {
|
||||||
/*
|
/*
|
||||||
* Commit only if all operations succeed
|
* Commit only if all operations succeed
|
||||||
|
|
@ -428,7 +551,7 @@ backsql_modify(
|
||||||
*/
|
*/
|
||||||
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
||||||
}
|
}
|
||||||
send_ldap_result( conn, op, res, "", NULL, NULL, NULL );
|
send_ldap_result( conn, op, res, "", text, NULL, NULL );
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_modify()\n", 0, 0, 0 );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -460,6 +583,7 @@ backsql_modrdn(
|
||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
LDAPRDN *new_rdn = NULL;
|
LDAPRDN *new_rdn = NULL;
|
||||||
LDAPRDN *old_rdn = NULL;
|
LDAPRDN *old_rdn = NULL;
|
||||||
|
Entry e;
|
||||||
Modifications *mod;
|
Modifications *mod;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_modrdn() renaming entry '%s', "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_modrdn() renaming entry '%s', "
|
||||||
|
|
@ -494,9 +618,43 @@ backsql_modrdn(
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): entry id is %ld\n",
|
Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): entry id is %ld\n",
|
||||||
e_id.id, 0, 0 );
|
e_id.id, 0, 0 );
|
||||||
|
|
||||||
|
if ( backsql_has_children( bi, dbh, ndn ) == LDAP_COMPARE_TRUE ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
|
||||||
|
"entry \"%s\" has children\n", dn->bv_val, 0, 0 );
|
||||||
|
send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
|
||||||
|
NULL, "subtree delete not supported",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
dnParent( dn, &p_dn );
|
dnParent( dn, &p_dn );
|
||||||
dnParent( ndn, &p_ndn );
|
dnParent( ndn, &p_ndn );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* namingContext "" is not supported
|
||||||
|
*/
|
||||||
|
if ( p_dn.bv_len == 0 ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_modrdn(): "
|
||||||
|
"parent is \"\" - aborting\n", 0, 0, 0 );
|
||||||
|
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
|
||||||
|
"", "not allowed within namingContext",
|
||||||
|
NULL, NULL );
|
||||||
|
goto modrdn_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for children access to parent
|
||||||
|
*/
|
||||||
|
e.e_attrs = NULL;
|
||||||
|
e.e_name = p_dn;
|
||||||
|
e.e_nname = p_ndn;
|
||||||
|
if ( !access_allowed( be, conn, op, &e, slap_schema.si_ad_children,
|
||||||
|
NULL, ACL_WRITE, NULL ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0, 0, 0 );
|
||||||
|
res = LDAP_INSUFFICIENT_ACCESS;
|
||||||
|
goto modrdn_return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( newSuperior ) {
|
if ( newSuperior ) {
|
||||||
/*
|
/*
|
||||||
* namingContext "" is not supported
|
* namingContext "" is not supported
|
||||||
|
|
@ -513,6 +671,21 @@ backsql_modrdn(
|
||||||
new_pdn = newSuperior;
|
new_pdn = newSuperior;
|
||||||
new_npdn = nnewSuperior;
|
new_npdn = nnewSuperior;
|
||||||
|
|
||||||
|
e.e_name = *new_pdn;
|
||||||
|
e.e_nname = *new_npdn;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for children access to new parent
|
||||||
|
*/
|
||||||
|
if ( !access_allowed( be, conn, op, &e,
|
||||||
|
slap_schema.si_ad_children,
|
||||||
|
NULL, ACL_WRITE, NULL ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "no access to new parent\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
res = LDAP_INSUFFICIENT_ACCESS;
|
||||||
|
goto modrdn_return;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
new_pdn = &p_dn;
|
new_pdn = &p_dn;
|
||||||
new_npdn = &p_ndn;
|
new_npdn = &p_ndn;
|
||||||
|
|
@ -611,8 +784,9 @@ backsql_modrdn(
|
||||||
goto modrdn_return;
|
goto modrdn_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get attribute type and attribute value of our new rdn, we will
|
/*
|
||||||
* need to add that to our new entry
|
* Get attribute type and attribute value of our new rdn,
|
||||||
|
* we will need to add that to our new entry
|
||||||
*/
|
*/
|
||||||
if ( ldap_bv2rdn( newrdn, &new_rdn, (char **)&text,
|
if ( ldap_bv2rdn( newrdn, &new_rdn, (char **)&text,
|
||||||
LDAP_DN_FORMAT_LDAP ) ) {
|
LDAP_DN_FORMAT_LDAP ) ) {
|
||||||
|
|
@ -664,19 +838,24 @@ backsql_modrdn(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = slap_modrdn2mods( NULL, NULL, NULL, NULL, old_rdn, new_rdn,
|
e.e_name = new_dn;
|
||||||
|
e.e_nname = new_ndn;
|
||||||
|
res = slap_modrdn2mods( be, conn, op, &e, old_rdn, new_rdn,
|
||||||
deleteoldrdn, &mod );
|
deleteoldrdn, &mod );
|
||||||
if ( res != LDAP_SUCCESS ) {
|
if ( res != LDAP_SUCCESS ) {
|
||||||
goto modrdn_return;
|
goto modrdn_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
oc = backsql_id2oc( bi, e_id.oc_id );
|
if ( !acl_check_modlist( be, conn, op, &e, mod )) {
|
||||||
res = backsql_modify_internal( bi, dbh, oc, &e_id, mod );
|
res = LDAP_INSUFFICIENT_ACCESS;
|
||||||
|
|
||||||
if ( res != LDAP_SUCCESS ) {
|
|
||||||
goto modrdn_return;
|
goto modrdn_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oc = backsql_id2oc( bi, e_id.oc_id );
|
||||||
|
res = backsql_modify_internal( bi, dbh, oc, &e_id, mod, &text );
|
||||||
|
|
||||||
|
if ( res == LDAP_SUCCESS ) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Commit only if all operations succeed
|
* Commit only if all operations succeed
|
||||||
*
|
*
|
||||||
|
|
@ -687,6 +866,7 @@ backsql_modrdn(
|
||||||
* reason
|
* reason
|
||||||
*/
|
*/
|
||||||
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
SQLTransact( SQL_NULL_HENV, dbh, SQL_COMMIT );
|
||||||
|
}
|
||||||
|
|
||||||
modrdn_return:
|
modrdn_return:
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
|
@ -714,7 +894,7 @@ modrdn_return:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
send_ldap_result( conn, op, res, "", NULL, NULL, NULL );
|
send_ldap_result( conn, op, res, "", text, NULL, NULL );
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_modrdn()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_modrdn()\n", 0, 0, 0 );
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -736,25 +916,42 @@ backsql_add(
|
||||||
backsql_oc_map_rec *oc = NULL;
|
backsql_oc_map_rec *oc = NULL;
|
||||||
backsql_at_map_rec *at_rec = NULL;
|
backsql_at_map_rec *at_rec = NULL;
|
||||||
backsql_entryID e_id, parent_id;
|
backsql_entryID e_id, parent_id;
|
||||||
|
Entry p;
|
||||||
int res;
|
int res;
|
||||||
Attribute *at;
|
Attribute *at;
|
||||||
struct berval *at_val;
|
struct berval *at_val;
|
||||||
struct berval pdn;
|
struct berval pdn;
|
||||||
/* first parameter no, parameter order */
|
/* first parameter #, parameter order */
|
||||||
SQLUSMALLINT pno, po;
|
SQLUSMALLINT pno, po;
|
||||||
/* procedure return code */
|
/* procedure return code */
|
||||||
int prc;
|
int prc;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_add(): adding entry '%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_add(): adding entry '%s'\n",
|
||||||
e->e_dn, 0, 0 );
|
e->e_name.bv_val, 0, 0 );
|
||||||
|
|
||||||
for ( at = e->e_attrs; at != NULL; at = at->a_next ) {
|
for ( at = e->e_attrs; at != NULL; at = at->a_next ) {
|
||||||
if ( at->a_desc == slap_schema.si_ad_objectClass ) {
|
if ( at->a_desc == slap_schema.si_ad_objectClass ) {
|
||||||
|
if ( global_schemacheck ) {
|
||||||
|
const char *text = NULL;
|
||||||
|
char textbuf[ 1024 ];
|
||||||
|
size_t textlen = sizeof( textbuf );
|
||||||
|
struct berval soc;
|
||||||
|
|
||||||
|
int rc = structural_class( at->a_vals, &soc,
|
||||||
|
NULL, &text, textbuf, textlen );
|
||||||
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oc = backsql_name2oc( bi, &soc );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: only the objectClass provided first
|
* FIXME: only the objectClass provided first
|
||||||
* is considered when creating a new entry
|
* is considered when creating a new entry
|
||||||
*/
|
*/
|
||||||
oc = backsql_name2oc( bi, &at->a_vals[ 0 ] );
|
oc = backsql_name2oc( bi, &at->a_vals[ 0 ] );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -777,6 +974,16 @@ backsql_add(
|
||||||
"operation not permitted within namingContext",
|
"operation not permitted within namingContext",
|
||||||
NULL, NULL );
|
NULL, NULL );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
} else if ( BACKSQL_CREATE_NEEDS_SELECT( bi )
|
||||||
|
&& oc->create_keyval == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
|
||||||
|
"create procedure needs select, but none is defined"
|
||||||
|
"- aborting\n", 0, 0, 0 );
|
||||||
|
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, "",
|
||||||
|
"operation not permitted within namingContext",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
prc = backsql_get_db_conn( be, conn, &dbh );
|
prc = backsql_get_db_conn( be, conn, &dbh );
|
||||||
|
|
@ -862,6 +1069,16 @@ backsql_add(
|
||||||
* is expected to return the id as the first column of a select
|
* is expected to return the id as the first column of a select
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
p.e_attrs = NULL;
|
||||||
|
p.e_name = pdn;
|
||||||
|
dnParent( &e->e_nname, &p.e_nname );
|
||||||
|
if ( !access_allowed( be, conn, op, &p, slap_schema.si_ad_children,
|
||||||
|
NULL, ACL_WRITE, NULL ) ) {
|
||||||
|
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
||||||
|
NULL, NULL, NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef BACKSQL_REALLOC_STMT
|
#ifndef BACKSQL_REALLOC_STMT
|
||||||
rc = SQLAllocStmt( dbh, &sth );
|
rc = SQLAllocStmt( dbh, &sth );
|
||||||
#else /* BACKSQL_REALLOC_STMT */
|
#else /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
@ -899,6 +1116,27 @@ backsql_add(
|
||||||
SWORD ncols;
|
SWORD ncols;
|
||||||
SQLINTEGER is_null;
|
SQLINTEGER is_null;
|
||||||
|
|
||||||
|
if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
|
||||||
|
#ifndef BACKSQL_REALLOC_STMT
|
||||||
|
SQLFreeStmt( sth, SQL_RESET_PARAMS );
|
||||||
|
#else /* BACKSQL_REALLOC_STMT */
|
||||||
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
rc = SQLAllocStmt( dbh, &sth );
|
||||||
|
if ( rc != SQL_SUCCESS ) {
|
||||||
|
send_ldap_result( conn, op, LDAP_OTHER, "",
|
||||||
|
"SQL-backend error", NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
||||||
|
rc = SQLExecDirect( sth, oc->create_keyval, SQL_NTS );
|
||||||
|
if ( rc != SQL_SUCCESS ) {
|
||||||
|
send_ldap_result( conn, op, LDAP_OTHER, "",
|
||||||
|
"SQL-backend error", NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the query to know the id of the inserted entry
|
* the query to know the id of the inserted entry
|
||||||
* must be embedded in the create procedure
|
* must be embedded in the create procedure
|
||||||
|
|
@ -916,8 +1154,8 @@ backsql_add(
|
||||||
|
|
||||||
} else if ( ncols != 1 ) {
|
} else if ( ncols != 1 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
|
||||||
"create_proc result is bogus\n",
|
"create_proc result is bogus (ncols=%d)\n",
|
||||||
0, 0, 0 );
|
ncols, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env, dbh, sth, rc);
|
backsql_PrintErrors( bi->db_env, dbh, sth, rc);
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
send_ldap_result( conn, op, LDAP_OTHER, "",
|
send_ldap_result( conn, op, LDAP_OTHER, "",
|
||||||
|
|
@ -979,7 +1217,18 @@ backsql_add(
|
||||||
for ( at = e->e_attrs; at != NULL; at = at->a_next ) {
|
for ( at = e->e_attrs; at != NULL; at = at->a_next ) {
|
||||||
SQLUSMALLINT currpos;
|
SQLUSMALLINT currpos;
|
||||||
|
|
||||||
if ( at->a_vals[ 0 ].bv_val == NULL ) {
|
Debug( LDAP_DEBUG_TRACE, "backsql_add(): "
|
||||||
|
"adding attribute '%s'\n",
|
||||||
|
at->a_desc->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip:
|
||||||
|
* - the first occurrence of objectClass, which is used
|
||||||
|
* to determine how to bulid the SQL entry (FIXME ?!?)
|
||||||
|
* - operational attributes
|
||||||
|
* empty attributes (FIXME ?!?)
|
||||||
|
*/
|
||||||
|
if ( backsql_attr_skip( at->a_desc, at->a_vals ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -991,6 +1240,16 @@ backsql_add(
|
||||||
"in objectclass '%s'\n",
|
"in objectclass '%s'\n",
|
||||||
at->a_desc->ad_cname.bv_val,
|
at->a_desc->ad_cname.bv_val,
|
||||||
oc->name.bv_val, 0 );
|
oc->name.bv_val, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
send_ldap_result( conn, op,
|
||||||
|
LDAP_UNWILLING_TO_PERFORM, "",
|
||||||
|
"operation not permitted "
|
||||||
|
"within namingContext",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -999,12 +1258,31 @@ backsql_add(
|
||||||
"add procedure is not defined "
|
"add procedure is not defined "
|
||||||
"for attribute '%s'\n",
|
"for attribute '%s'\n",
|
||||||
at->a_desc->ad_cname.bv_val, 0, 0 );
|
at->a_desc->ad_cname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
send_ldap_result( conn, op,
|
||||||
|
LDAP_UNWILLING_TO_PERFORM, "",
|
||||||
|
"operation not permitted "
|
||||||
|
"within namingContext",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BACKSQL_REALLOC_STMT
|
#ifdef BACKSQL_REALLOC_STMT
|
||||||
rc = backsql_Prepare( dbh, &sth, at_rec->add_proc, 0 );
|
rc = backsql_Prepare( dbh, &sth, at_rec->add_proc, 0 );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
send_ldap_result( conn, op,
|
||||||
|
LDAP_OTHER, "",
|
||||||
|
"SQL-backend error",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif /* BACKSQL_REALLOC_STMT */
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
@ -1025,10 +1303,20 @@ backsql_add(
|
||||||
SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
|
SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
|
||||||
currpos = pno + 2 - po;
|
currpos = pno + 2 - po;
|
||||||
|
|
||||||
for ( i = 0, at_val = &at->a_vals[ 0 ];
|
for ( i = 0, at_val = &at->a_vals[ i ];
|
||||||
at_val->bv_val != NULL;
|
at_val->bv_val != NULL;
|
||||||
i++, at_val = &at->a_vals[ i ] ) {
|
i++, at_val = &at->a_vals[ i ] ) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do not deal with the objectClass that is used
|
||||||
|
* to build the entry
|
||||||
|
*/
|
||||||
|
if ( at->a_desc == slap_schema.si_ad_objectClass ) {
|
||||||
|
if ( ber_bvcmp( at_val, &oc->name ) == 0 ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* check for syntax needed here
|
* check for syntax needed here
|
||||||
* maybe need binary bind?
|
* maybe need binary bind?
|
||||||
|
|
@ -1055,6 +1343,14 @@ backsql_add(
|
||||||
"add_proc execution failed\n",
|
"add_proc execution failed\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
backsql_PrintErrors( bi->db_env, dbh, sth, rc );
|
backsql_PrintErrors( bi->db_env, dbh, sth, rc );
|
||||||
|
|
||||||
|
if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
|
||||||
|
send_ldap_result( conn, op,
|
||||||
|
LDAP_OTHER, "",
|
||||||
|
"SQL-backend error",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef BACKSQL_REALLOC_STMT
|
#ifndef BACKSQL_REALLOC_STMT
|
||||||
|
|
@ -1072,6 +1368,7 @@ backsql_add(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif /* BACKSQL_REALLOC_STMT */
|
#endif /* BACKSQL_REALLOC_STMT */
|
||||||
|
|
||||||
backsql_BindParamStr( sth, 1, e->e_name.bv_val, BACKSQL_MAX_DN_LEN );
|
backsql_BindParamStr( sth, 1, e->e_name.bv_val, BACKSQL_MAX_DN_LEN );
|
||||||
SQLBindParameter( sth, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,
|
SQLBindParameter( sth, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,
|
||||||
0, 0, &oc->id, 0, 0 );
|
0, 0, &oc->id, 0, 0 );
|
||||||
|
|
@ -1135,12 +1432,30 @@ backsql_delete(
|
||||||
RETCODE rc;
|
RETCODE rc;
|
||||||
backsql_oc_map_rec *oc = NULL;
|
backsql_oc_map_rec *oc = NULL;
|
||||||
backsql_entryID e_id;
|
backsql_entryID e_id;
|
||||||
|
Entry e;
|
||||||
int res;
|
int res;
|
||||||
/* first parameter no */
|
/* first parameter no */
|
||||||
SQLUSMALLINT pno;
|
SQLUSMALLINT pno;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry '%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_delete(): deleting entry '%s'\n",
|
||||||
ndn->bv_val, 0, 0 );
|
ndn->bv_val, 0, 0 );
|
||||||
|
|
||||||
|
dnParent( dn, &e.e_name );
|
||||||
|
dnParent( ndn, &e.e_nname );
|
||||||
|
e.e_attrs = NULL;
|
||||||
|
|
||||||
|
/* check parent for "children" acl */
|
||||||
|
if ( !access_allowed( be, conn, op, &e, slap_schema.si_ad_children,
|
||||||
|
NULL, ACL_WRITE, NULL ) ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
|
||||||
|
"no write access to parent\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
|
||||||
|
"", NULL, NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
res = backsql_get_db_conn( be, conn, &dbh );
|
res = backsql_get_db_conn( be, conn, &dbh );
|
||||||
if ( res != LDAP_SUCCESS ) {
|
if ( res != LDAP_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
|
||||||
|
|
@ -1160,13 +1475,32 @@ backsql_delete(
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
res = backsql_has_children( bi, dbh, ndn );
|
||||||
|
switch ( res ) {
|
||||||
|
case LDAP_COMPARE_TRUE:
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
|
||||||
|
"entry \"%s\" has children\n", dn->bv_val, 0, 0 );
|
||||||
|
send_ldap_result( conn, op, LDAP_NOT_ALLOWED_ON_NONLEAF,
|
||||||
|
NULL, "subtree delete not supported",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case LDAP_COMPARE_FALSE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
send_ldap_result( conn, op, res, NULL, NULL, NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
oc = backsql_id2oc( bi, e_id.oc_id );
|
oc = backsql_id2oc( bi, e_id.oc_id );
|
||||||
if ( oc == NULL ) {
|
if ( oc == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_delete(): "
|
||||||
"cannot determine objectclass of entry "
|
"cannot determine objectclass of entry "
|
||||||
"-- aborting\n", 0, 0, 0 );
|
"-- aborting\n", 0, 0, 0 );
|
||||||
send_ldap_result( conn, op, LDAP_OTHER, "",
|
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, "",
|
||||||
"SQL-backend error", NULL, NULL );
|
"operation not permitted within namingContext",
|
||||||
|
NULL, NULL );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1175,7 +1509,7 @@ backsql_delete(
|
||||||
"delete procedure is not defined "
|
"delete procedure is not defined "
|
||||||
"for this objectclass - aborting\n", 0, 0, 0 );
|
"for this objectclass - aborting\n", 0, 0, 0 );
|
||||||
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, "",
|
send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, "",
|
||||||
"operation not supported for required DN",
|
"operation not permitted within namingContext",
|
||||||
NULL, NULL );
|
NULL, NULL );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "slap.h"
|
#include "slap.h"
|
||||||
#include "back-sql.h"
|
#include "back-sql.h"
|
||||||
#include "sql-wrap.h"
|
#include "sql-wrap.h"
|
||||||
|
#include "entry-id.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
backsql_compare(
|
backsql_compare(
|
||||||
|
|
@ -43,5 +44,70 @@ backsql_abandon(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sets the supported operational attributes (if required)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
backsql_operational(
|
||||||
|
BackendDB *be,
|
||||||
|
Connection *conn,
|
||||||
|
Operation *op,
|
||||||
|
Entry *e,
|
||||||
|
AttributeName *attrs,
|
||||||
|
int opattrs,
|
||||||
|
Attribute **a )
|
||||||
|
{
|
||||||
|
|
||||||
|
backsql_info *bi = (backsql_info*)be->be_private;
|
||||||
|
SQLHDBC dbh = SQL_NULL_HDBC;
|
||||||
|
Attribute **aa = a;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry '%s'\n",
|
||||||
|
e->e_nname.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
|
||||||
|
if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
|
||||||
|
rc = backsql_get_db_conn( be, conn, &dbh );
|
||||||
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
|
goto no_connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = backsql_has_children( bi, dbh, &e->e_nname );
|
||||||
|
|
||||||
|
switch( rc ) {
|
||||||
|
case LDAP_COMPARE_TRUE:
|
||||||
|
case LDAP_COMPARE_FALSE:
|
||||||
|
*aa = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
|
||||||
|
if ( *aa != NULL ) {
|
||||||
|
aa = &(*aa)->a_next;
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Debug(LDAP_DEBUG_TRACE,
|
||||||
|
"backsql_operational(): "
|
||||||
|
"has_children failed( %d)\n",
|
||||||
|
rc, 0, 0 );
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
no_connection:;
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
|
||||||
|
"could not get connection handle - exiting\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
send_ldap_result( conn, op, rc, "",
|
||||||
|
rc == LDAP_OTHER ? "SQL-backend error" : "",
|
||||||
|
NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SLAPD_SQL */
|
#endif /* SLAPD_SQL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ create table ldap_oc_mappings
|
||||||
keytbl varchar(64) not null,
|
keytbl varchar(64) not null,
|
||||||
keycol varchar(64) not null,
|
keycol varchar(64) not null,
|
||||||
create_proc varchar(255),
|
create_proc varchar(255),
|
||||||
|
create_keyval varchar(255),
|
||||||
delete_proc varchar(255),
|
delete_proc varchar(255),
|
||||||
expect_return integer not null
|
expect_return integer not null
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,7 @@ dbpasswd ibmdb2
|
||||||
subtree_cond "upper(ldap_entries.dn) LIKE CONCAT('%',?)"
|
subtree_cond "upper(ldap_entries.dn) LIKE CONCAT('%',?)"
|
||||||
insentry_query "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
|
insentry_query "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
|
||||||
upper_func "upper"
|
upper_func "upper"
|
||||||
|
upper_needs_cast "yes"
|
||||||
|
create_needs_select "yes"
|
||||||
|
has_ldapinfo_dn_ru "no"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
drop table persons;
|
drop table persons;
|
||||||
CREATE TABLE persons (
|
CREATE TABLE persons (
|
||||||
id int NOT NULL,
|
id int NOT NULL,
|
||||||
name varchar(255) NOT NULL
|
name varchar(255) NOT NULL,
|
||||||
|
surname varchar(255) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
drop table institutes;
|
drop table institutes;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
insert into institutes (id,name) values (1,'sql');
|
insert into institutes (id,name) values (1,'sql');
|
||||||
|
|
||||||
insert into persons (id,name) values (1,'Mitya Kovalev');
|
insert into persons (id,name,surname) values (1,'Mitya','Kovalev');
|
||||||
insert into persons (id,name) values (2,'Torvlobnor Puzdoy');
|
insert into persons (id,name,surname) values (2,'Torvlobnor','Puzdoy');
|
||||||
insert into persons (id,name) values (3,'Akakiy Zinberstein');
|
insert into persons (id,name,surname) values (3,'Akakiy','Zinberstein');
|
||||||
|
|
||||||
insert into phones (id,phone,pers_id) values (1,'332-2334',1);
|
insert into phones (id,phone,pers_id) values (1,'332-2334',1);
|
||||||
insert into phones (id,phone,pers_id) values (2,'222-3234',1);
|
insert into phones (id,phone,pers_id) values (2,'222-3234',1);
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,27 @@
|
||||||
--mappings
|
--mappings
|
||||||
|
|
||||||
insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
|
insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,create_keyval,delete_proc,expect_return)
|
||||||
values (1,'inetOrgPerson','persons','id','insert into persons (name) values ('''');\n select last_insert_id();',NULL,0);
|
values (1,'inetOrgPerson','persons','id','insert into persons (id,name,surname) values ((select max(id)+1 from persons),'''','''')','select max(id) from persons',NULL,0);
|
||||||
|
|
||||||
insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
|
insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,create_keyval,delete_proc,expect_return)
|
||||||
values (2,'document','documents','id',NULL,NULL,0);
|
values (2,'document','documents','id',NULL,NULL,NULL,0);
|
||||||
|
|
||||||
insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
|
insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,create_keyval,delete_proc,expect_return)
|
||||||
values (3,'organization','institutes','id',NULL,NULL,0);
|
values (3,'organization','institutes','id',NULL,NULL,NULL,0);
|
||||||
|
|
||||||
|
|
||||||
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
||||||
values (1,1,'cn','persons.name','persons',NULL,NULL,NULL,3,0);
|
values (1,1,'cn','case when persons.name!='''' and persons.surname!='''' then persons.name||'' ''||persons.surname when persons.surname!='''' then persons.surname when persons.name!='''' then persons.name else '''' end','persons',NULL,NULL,NULL,3,0);
|
||||||
|
|
||||||
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
||||||
values (2,1,'telephoneNumber','phones.phone','persons,phones',
|
values (2,1,'telephoneNumber','phones.phone','persons,phones',
|
||||||
'phones.pers_id=persons.id',NULL,NULL,3,0);
|
'phones.pers_id=persons.id',NULL,NULL,3,0);
|
||||||
|
|
||||||
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
||||||
values (3,1,'sn','persons.name','persons',NULL,NULL,NULL,3,0);
|
values (3,1,'sn','persons.surname','persons',NULL,'update persons set surname=? where id=?',NULL,3,0);
|
||||||
|
|
||||||
|
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
||||||
|
values (6,1,'givenName','persons.name','persons',NULL,'update persons set name=? where id=?',NULL,3,0);
|
||||||
|
|
||||||
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
||||||
values (4,2,'description','documents.abstract','documents',NULL,NULL,NULL,3,0);
|
values (4,2,'description','documents.abstract','documents',NULL,NULL,NULL,3,0);
|
||||||
|
|
@ -35,7 +38,7 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,
|
||||||
values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
|
values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
|
||||||
|
|
||||||
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
|
||||||
values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
|
values (8,1,'documentAuthor','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
|
||||||
'ldap_entries.keyval=documents.id AND ldap_entries.oc_map_id=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
|
'ldap_entries.keyval=documents.id AND ldap_entries.oc_map_id=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
|
||||||
NULL,NULL,3,0);
|
NULL,NULL,3,0);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,9 @@ rootpw secret
|
||||||
dbname PostgreSQL
|
dbname PostgreSQL
|
||||||
dbuser postgres
|
dbuser postgres
|
||||||
dbpasswd postgres
|
dbpasswd postgres
|
||||||
subtree_cond "upper(ldap_entries.dn) LIKE '%'||?"
|
|
||||||
insentry_query "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
|
insentry_query "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
|
||||||
upper_func "upper"
|
upper_func "upper"
|
||||||
strcast_func "text"
|
strcast_func "text"
|
||||||
|
concat_pattern "?||?"
|
||||||
has_ldapinfo_dn_ru no
|
has_ldapinfo_dn_ru no
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,16 +73,25 @@ backsql_make_attr_query(
|
||||||
backsql_at_map_rec *at_map )
|
backsql_at_map_rec *at_map )
|
||||||
{
|
{
|
||||||
struct berval tmps = { 0, NULL };
|
struct berval tmps = { 0, NULL };
|
||||||
int tmpslen = 0;
|
ber_len_t tmpslen = 0;
|
||||||
|
|
||||||
backsql_strcat( &tmps, &tmpslen, "SELECT ", at_map->sel_expr,
|
backsql_strfcat( &tmps, &tmpslen, "lblblblbcbl",
|
||||||
" AS ", at_map->name.bv_val,
|
(ber_len_t)sizeof( "SELECT " ) - 1, "SELECT ",
|
||||||
" FROM ", at_map->from_tbls,
|
&at_map->sel_expr,
|
||||||
" WHERE ", oc_map->keytbl,".", oc_map->keycol,
|
(ber_len_t)sizeof( " AS " ) - 1, " AS ",
|
||||||
"=?", NULL );
|
&at_map->ad->ad_cname,
|
||||||
if ( at_map->join_where != NULL ) {
|
(ber_len_t)sizeof( " FROM " ) - 1, " FROM ",
|
||||||
backsql_strcat( &tmps, &tmpslen, " AND ",
|
&at_map->from_tbls,
|
||||||
at_map->join_where, NULL );
|
(ber_len_t)sizeof( " WHERE " ) - 1, " WHERE ",
|
||||||
|
&oc_map->keytbl,
|
||||||
|
'.',
|
||||||
|
&oc_map->keycol,
|
||||||
|
(ber_len_t)sizeof( "=?" ) - 1, "=?" );
|
||||||
|
|
||||||
|
if ( at_map->join_where.bv_val != NULL ) {
|
||||||
|
backsql_strfcat( &tmps, &tmpslen, "lb",
|
||||||
|
(ber_len_t)sizeof( " AND ") - 1, " AND ",
|
||||||
|
&at_map->join_where );
|
||||||
}
|
}
|
||||||
|
|
||||||
at_map->query = tmps.bv_val;
|
at_map->query = tmps.bv_val;
|
||||||
|
|
@ -94,30 +103,34 @@ static int
|
||||||
backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
|
backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
|
||||||
{
|
{
|
||||||
backsql_at_map_rec *at_map;
|
backsql_at_map_rec *at_map;
|
||||||
int len;
|
|
||||||
char s[ 30 ];
|
char s[ 30 ];
|
||||||
struct berval bv;
|
ber_len_t len, slen;
|
||||||
|
|
||||||
|
|
||||||
snprintf( s, sizeof( s ), "%ld", oc_map->id );
|
snprintf( s, sizeof( s ), "%ld", oc_map->id );
|
||||||
|
slen = strlen( s );
|
||||||
|
|
||||||
at_map = (backsql_at_map_rec *)ch_calloc(1,
|
at_map = (backsql_at_map_rec *)ch_calloc(1,
|
||||||
sizeof( backsql_at_map_rec ) );
|
sizeof( backsql_at_map_rec ) );
|
||||||
at_map->ad = slap_schema.si_ad_objectClass;
|
at_map->ad = slap_schema.si_ad_objectClass;
|
||||||
ber_dupbv( &at_map->name, &at_map->ad->ad_cname );
|
ber_str2bv( "ldap_entry_objclasses.oc_name", 0, 1, &at_map->sel_expr );
|
||||||
at_map->sel_expr = ch_strdup( "ldap_entry_objclasses.oc_name" );
|
ber_str2bv( "ldap_entry_objclasses,ldap_entries", 0, 1,
|
||||||
at_map->from_tbls = ch_strdup( "ldap_entry_objclasses,ldap_entries" );
|
&at_map->from_tbls );
|
||||||
len = strlen( at_map->from_tbls );
|
len = at_map->from_tbls.bv_len + 1;
|
||||||
backsql_merge_from_clause( &at_map->from_tbls, &len, oc_map->keytbl );
|
backsql_merge_from_clause( &at_map->from_tbls, &len, &oc_map->keytbl );
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
bv.bv_val = NULL;
|
at_map->join_where.bv_val = NULL;
|
||||||
bv.bv_len = 0;
|
at_map->join_where.bv_len = 0;
|
||||||
backsql_strcat( &bv, &len,
|
backsql_strfcat( &at_map->join_where, &len, "lbcbll",
|
||||||
"ldap_entries.id=ldap_entry_objclasses.entry_id "
|
(ber_len_t)sizeof( "ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=" ) - 1,
|
||||||
"and ldap_entries.keyval=",
|
"ldap_entries.id=ldap_entry_objclasses.entry_id and ldap_entries.keyval=",
|
||||||
oc_map->keytbl, ".", oc_map->keycol,
|
&oc_map->keytbl,
|
||||||
" and ldap_entries.oc_map_id=", s, NULL );
|
'.',
|
||||||
at_map->join_where = bv.bv_val;
|
&oc_map->keycol,
|
||||||
|
(ber_len_t)sizeof( " and ldap_entries.oc_map_id=" ) - 1,
|
||||||
|
" and ldap_entries.oc_map_id=",
|
||||||
|
slen, s );
|
||||||
|
|
||||||
at_map->add_proc = NULL;
|
at_map->add_proc = NULL;
|
||||||
at_map->delete_proc = NULL;
|
at_map->delete_proc = NULL;
|
||||||
|
|
@ -130,21 +143,23 @@ backsql_add_sysmaps( backsql_oc_map_rec *oc_map )
|
||||||
at_map = (backsql_at_map_rec *)ch_calloc( 1,
|
at_map = (backsql_at_map_rec *)ch_calloc( 1,
|
||||||
sizeof( backsql_at_map_rec ) );
|
sizeof( backsql_at_map_rec ) );
|
||||||
at_map->ad = slap_schema.si_ad_ref;
|
at_map->ad = slap_schema.si_ad_ref;
|
||||||
ber_dupbv( &at_map->name, &at_map->ad->ad_cname );
|
ber_str2bv( "ldap_referrals.url", 0, 1, &at_map->sel_expr );
|
||||||
at_map->sel_expr = ch_strdup( "ldap_referrals.url" );
|
ber_str2bv( "ldap_referrals,ldap_entries", 0, 1, &at_map->from_tbls );
|
||||||
at_map->from_tbls = ch_strdup( "ldap_referrals,ldap_entries" );
|
len = at_map->from_tbls.bv_len + 1;
|
||||||
len = strlen( at_map->from_tbls );
|
backsql_merge_from_clause( &at_map->from_tbls, &len, &oc_map->keytbl );
|
||||||
backsql_merge_from_clause( &at_map->from_tbls, &len,oc_map->keytbl );
|
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
bv.bv_val = NULL;
|
at_map->join_where.bv_val = NULL;
|
||||||
bv.bv_len = 0;
|
at_map->join_where.bv_len = 0;
|
||||||
backsql_strcat( &bv, &len,
|
backsql_strfcat( &at_map->join_where, &len, "lbcbll",
|
||||||
"ldap_entries.id=ldap_referrals.entry_id "
|
(ber_len_t)sizeof( "ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=" ) - 1,
|
||||||
"and ldap_entries.keyval=",
|
"ldap_entries.id=ldap_referrals.entry_id and ldap_entries.keyval=",
|
||||||
oc_map->keytbl, ".", oc_map->keycol,
|
&oc_map->keytbl,
|
||||||
" and ldap_entries.oc_map_id=", s, NULL );
|
'.',
|
||||||
at_map->join_where = bv.bv_val;
|
&oc_map->keycol,
|
||||||
|
(ber_len_t)sizeof( " and ldap_entries.oc_map_id=" ) - 1,
|
||||||
|
" and ldap_entries.oc_map_id=",
|
||||||
|
slen, s );
|
||||||
|
|
||||||
at_map->add_proc = NULL;
|
at_map->add_proc = NULL;
|
||||||
at_map->delete_proc = NULL;
|
at_map->delete_proc = NULL;
|
||||||
|
|
@ -166,23 +181,23 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
unsigned long oc_id;
|
unsigned long oc_id;
|
||||||
backsql_oc_map_rec *oc_map;
|
backsql_oc_map_rec *oc_map;
|
||||||
backsql_at_map_rec *at_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 ) {
|
if ( !BACKSQL_DONTCHECK_LDAPINFO_DN_RU( si ) ) {
|
||||||
rc = backsql_Prepare( dbh, &oc_sth,
|
rc = backsql_Prepare( dbh, &oc_sth,
|
||||||
backsql_check_dn_ru_query, 0 );
|
backsql_check_dn_ru_query, 0 );
|
||||||
if ( rc == SQL_SUCCESS ) {
|
if ( rc == SQL_SUCCESS ) {
|
||||||
si->has_ldapinfo_dn_ru = 1; /* Yes, the field exists */
|
/* Yes, the field exists */
|
||||||
|
si->bsql_flags |= BSQLF_HAS_LDAPINFO_DN_RU;
|
||||||
Debug( LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists "
|
Debug( LDAP_DEBUG_TRACE, "ldapinfo.dn_ru field exists "
|
||||||
"in the schema\n", 0, 0, 0 );
|
"in the schema\n", 0, 0, 0 );
|
||||||
} else {
|
} else {
|
||||||
si->has_ldapinfo_dn_ru = 0; /* No such field exists */
|
/* No such field exists */
|
||||||
|
si->bsql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLFreeStmt( oc_sth, SQL_DROP );
|
SQLFreeStmt( oc_sth, SQL_DROP );
|
||||||
|
|
@ -228,10 +243,12 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
backsql_BindRowAsStrings( oc_sth, &oc_row );
|
backsql_BindRowAsStrings( oc_sth, &oc_row );
|
||||||
rc = SQLFetch( oc_sth );
|
rc = SQLFetch( oc_sth );
|
||||||
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( oc_sth ) ) {
|
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( oc_sth ) ) {
|
||||||
|
int colnum;
|
||||||
|
|
||||||
oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
|
oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
|
||||||
sizeof( backsql_oc_map_rec ) );
|
sizeof( backsql_oc_map_rec ) );
|
||||||
|
|
||||||
oc_map->id = atoi( oc_row.cols[ 0 ] );
|
oc_map->id = strtol( oc_row.cols[ 0 ], NULL, 0 );
|
||||||
|
|
||||||
ber_str2bv( oc_row.cols[ 1 ], 0, 1, &oc_map->name );
|
ber_str2bv( oc_row.cols[ 1 ], 0, 1, &oc_map->name );
|
||||||
oc_map->oc = oc_bvfind( &oc_map->name );
|
oc_map->oc = oc_bvfind( &oc_map->name );
|
||||||
|
|
@ -242,13 +259,21 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
return LDAP_OTHER; /* undefined objectClass ? */
|
return LDAP_OTHER; /* undefined objectClass ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
oc_map->keytbl = ch_strdup( oc_row.cols[ 2 ] );
|
ber_str2bv( oc_row.cols[ 2 ], 0, 1, &oc_map->keytbl );
|
||||||
oc_map->keycol = ch_strdup( oc_row.cols[ 3 ] );
|
ber_str2bv( oc_row.cols[ 3 ], 0, 1, &oc_map->keycol );
|
||||||
oc_map->create_proc = ( oc_row.is_null[ 4 ] < 0 ) ? NULL
|
oc_map->create_proc = ( oc_row.is_null[ 4 ] < 0 ) ? NULL
|
||||||
: ch_strdup( oc_row.cols[ 4 ] );
|
: ch_strdup( oc_row.cols[ 4 ] );
|
||||||
oc_map->delete_proc = ( oc_row.is_null[ 5 ] < 0 ) ? NULL
|
|
||||||
: ch_strdup( oc_row.cols[ 5 ] );
|
colnum = 5;
|
||||||
oc_map->expect_return = atoi( oc_row.cols[ 6 ] );
|
if ( BACKSQL_CREATE_NEEDS_SELECT( si ) ) {
|
||||||
|
colnum = 6;
|
||||||
|
oc_map->create_keyval = ( oc_row.is_null[ 5 ] < 0 )
|
||||||
|
? NULL : ch_strdup( oc_row.cols[ 5 ] );
|
||||||
|
}
|
||||||
|
oc_map->delete_proc = ( oc_row.is_null[ colnum ] < 0 ) ? NULL
|
||||||
|
: ch_strdup( oc_row.cols[ colnum ] );
|
||||||
|
oc_map->expect_return = strtol( oc_row.cols[ colnum + 1 ],
|
||||||
|
NULL, 0 );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: first attempt to check for offending
|
* FIXME: first attempt to check for offending
|
||||||
|
|
@ -263,17 +288,22 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
oc_id = oc_map->id;
|
oc_id = oc_map->id;
|
||||||
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
||||||
"objectClass '%s': keytbl='%s' keycol='%s'\n",
|
"objectClass '%s': keytbl='%s' keycol='%s'\n",
|
||||||
oc_map->name.bv_val, oc_map->keytbl, oc_map->keycol );
|
oc_map->name.bv_val,
|
||||||
|
oc_map->keytbl.bv_val, oc_map->keycol.bv_val );
|
||||||
if ( oc_map->create_proc ) {
|
if ( oc_map->create_proc ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "create_proc='%s'\n",
|
||||||
oc_map->create_proc, 0, 0 );
|
oc_map->create_proc, 0, 0 );
|
||||||
}
|
}
|
||||||
|
if ( oc_map->create_keyval ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "create_keyval='%s'\n",
|
||||||
|
oc_map->create_keyval, 0, 0 );
|
||||||
|
}
|
||||||
if ( oc_map->delete_proc ) {
|
if ( oc_map->delete_proc ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "delete_proc='%s'\n",
|
||||||
oc_map->delete_proc, 0, 0 );
|
oc_map->delete_proc, 0, 0 );
|
||||||
}
|
}
|
||||||
Debug( LDAP_DEBUG_TRACE, "expect_return: "
|
Debug( LDAP_DEBUG_TRACE, "expect_return: "
|
||||||
"add=%s, del=%s; attributes:\n",
|
"add=%d, del=%d; attributes:\n",
|
||||||
BACKSQL_IS_ADD( oc_map->expect_return ),
|
BACKSQL_IS_ADD( oc_map->expect_return ),
|
||||||
BACKSQL_IS_DEL( oc_map->expect_return ), 0 );
|
BACKSQL_IS_DEL( oc_map->expect_return ), 0 );
|
||||||
|
|
||||||
|
|
@ -293,6 +323,8 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
rc = SQLFetch( at_sth );
|
rc = SQLFetch( at_sth );
|
||||||
for ( ; BACKSQL_SUCCESS(rc); rc = SQLFetch( at_sth ) ) {
|
for ( ; BACKSQL_SUCCESS(rc); rc = SQLFetch( at_sth ) ) {
|
||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
|
struct berval bv;
|
||||||
|
ber_len_t tmpslen;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "********'%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "********'%s'\n",
|
||||||
at_row.cols[ 0 ], 0, 0 );
|
at_row.cols[ 0 ], 0, 0 );
|
||||||
|
|
@ -310,33 +342,44 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
at_row.cols[ 8 ], 0, 0 );
|
at_row.cols[ 8 ], 0, 0 );
|
||||||
at_map = (backsql_at_map_rec *)ch_calloc( 1,
|
at_map = (backsql_at_map_rec *)ch_calloc( 1,
|
||||||
sizeof( backsql_at_map_rec ) );
|
sizeof( backsql_at_map_rec ) );
|
||||||
ber_str2bv( at_row.cols[ 0 ], 0, 1, &at_map->name );
|
rc = slap_str2ad( at_row.cols[ 0 ],
|
||||||
rc = slap_bv2ad( &at_map->name, &at_map->ad, &text );
|
&at_map->ad, &text );
|
||||||
if ( rc != LDAP_SUCCESS ) {
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
||||||
"attribute '%s' for objectClass '%s' "
|
"attribute '%s' for objectClass '%s' "
|
||||||
"is not defined in schema: %s\n",
|
"is not defined in schema: %s\n",
|
||||||
at_map->name.bv_val,
|
at_map->ad->ad_cname.bv_val,
|
||||||
oc_map->name.bv_val, text );
|
oc_map->name.bv_val, text );
|
||||||
return LDAP_CONSTRAINT_VIOLATION;
|
return LDAP_CONSTRAINT_VIOLATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
at_map->sel_expr = ch_strdup( at_row.cols[ 1 ] );
|
ber_str2bv( at_row.cols[ 1 ], 0, 1, &at_map->sel_expr );
|
||||||
at_map->sel_expr_u = ( at_row.is_null[ 8 ] < 0 ) ? NULL
|
if ( at_row.is_null[ 8 ] < 0 ) {
|
||||||
: ch_strdup( at_row.cols[ 8 ] );
|
at_map->sel_expr_u.bv_val = NULL;
|
||||||
tmps = NULL;
|
at_map->sel_expr_u.bv_len = 0;
|
||||||
|
} else {
|
||||||
|
ber_str2bv( at_row.cols[ 8 ], 0, 1,
|
||||||
|
&at_map->sel_expr_u );
|
||||||
|
}
|
||||||
tmpslen = 0;
|
tmpslen = 0;
|
||||||
backsql_merge_from_clause( &tmps, &tmpslen,
|
ber_str2bv( at_row.cols[ 2 ], 0, 0, &bv );
|
||||||
at_row.cols[ 2 ] );
|
backsql_merge_from_clause( &at_map->from_tbls,
|
||||||
at_map->from_tbls = tmps;
|
&tmpslen, &bv );
|
||||||
at_map->join_where = ( at_row.is_null[ 3 ] < 0 ) ? NULL
|
if ( at_row.is_null[ 3 ] < 0 ) {
|
||||||
: ch_strdup( at_row.cols[ 3 ] );
|
at_map->join_where.bv_val = NULL;
|
||||||
|
at_map->join_where.bv_len = 0;
|
||||||
|
} else {
|
||||||
|
ber_str2bv( at_row.cols[ 3 ], 0, 1,
|
||||||
|
&at_map->join_where );
|
||||||
|
}
|
||||||
at_map->add_proc = ( at_row.is_null[ 4 ] < 0 ) ? NULL
|
at_map->add_proc = ( at_row.is_null[ 4 ] < 0 ) ? NULL
|
||||||
: ch_strdup( at_row.cols[4] );
|
: ch_strdup( at_row.cols[4] );
|
||||||
at_map->delete_proc = ( at_row.is_null[ 5 ] < 0 ) ? NULL
|
at_map->delete_proc = ( at_row.is_null[ 5 ] < 0 ) ? NULL
|
||||||
: ch_strdup( at_row.cols[ 5 ] );
|
: ch_strdup( at_row.cols[ 5 ] );
|
||||||
at_map->param_order = atoi( at_row.cols[ 6 ] );
|
at_map->param_order = strtol( at_row.cols[ 6 ],
|
||||||
at_map->expect_return = atoi( at_row.cols[ 7 ] );
|
NULL, 0 );
|
||||||
|
at_map->expect_return = strtol( at_row.cols[ 7 ],
|
||||||
|
NULL, 0 );
|
||||||
backsql_make_attr_query( oc_map, at_map );
|
backsql_make_attr_query( oc_map, at_map );
|
||||||
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
Debug( LDAP_DEBUG_TRACE, "load_schema_map(): "
|
||||||
"preconstructed query '%s'\n",
|
"preconstructed query '%s'\n",
|
||||||
|
|
@ -350,7 +393,7 @@ backsql_load_schema_map( backsql_info *si, SQLHDBC dbh )
|
||||||
backsql_FreeRow( &oc_row );
|
backsql_FreeRow( &oc_row );
|
||||||
SQLFreeStmt( at_sth, SQL_DROP );
|
SQLFreeStmt( at_sth, SQL_DROP );
|
||||||
SQLFreeStmt( oc_sth, SQL_DROP );
|
SQLFreeStmt( oc_sth, SQL_DROP );
|
||||||
si->schema_loaded = 1;
|
si->bsql_flags |= BSQLF_SCHEMA_LOADED;
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==load_schema_map()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==load_schema_map()\n", 0, 0, 0 );
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -360,16 +403,16 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
|
||||||
{
|
{
|
||||||
backsql_oc_map_rec tmp, *res;
|
backsql_oc_map_rec tmp, *res;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_oc2oc(): "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_oc2oc(): "
|
||||||
"searching for objectclass with name='%s'\n",
|
"searching for objectclass with name='%s'\n",
|
||||||
objclass, 0, 0 );
|
objclass, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
tmp.oc = oc;
|
tmp.oc = oc;
|
||||||
res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
|
res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
|
||||||
(AVL_CMP)backsql_cmp_oc );
|
(AVL_CMP)backsql_cmp_oc );
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
if ( res != NULL ) {
|
if ( res != NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
|
||||||
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
||||||
|
|
@ -377,7 +420,7 @@ backsql_oc2oc( backsql_info *si, ObjectClass *oc )
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc2oc(): "
|
||||||
"not found\n", 0, 0, 0 );
|
"not found\n", 0, 0, 0 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -390,11 +433,11 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name )
|
||||||
{
|
{
|
||||||
backsql_oc_map_rec tmp, *res;
|
backsql_oc_map_rec tmp, *res;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): "
|
Debug( LDAP_DEBUG_TRACE, "==>oc_with_name(): "
|
||||||
"searching for objectclass with name='%s'\n",
|
"searching for objectclass with name='%s'\n",
|
||||||
objclass, 0, 0 );
|
objclass, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
tmp.oc = oc_bvfind( oc_name );
|
tmp.oc = oc_bvfind( oc_name );
|
||||||
if ( tmp.oc == NULL ) {
|
if ( tmp.oc == NULL ) {
|
||||||
|
|
@ -403,7 +446,7 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name )
|
||||||
|
|
||||||
res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
|
res = (backsql_oc_map_rec *)avl_find( si->oc_by_oc, &tmp,
|
||||||
(AVL_CMP)backsql_cmp_oc );
|
(AVL_CMP)backsql_cmp_oc );
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
if ( res != NULL ) {
|
if ( res != NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||||
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
||||||
|
|
@ -411,7 +454,7 @@ backsql_name2oc( backsql_info *si, struct berval *oc_name )
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||||
"not found\n", 0, 0, 0 );
|
"not found\n", 0, 0, 0 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -421,16 +464,16 @@ backsql_id2oc( backsql_info *si, unsigned long id )
|
||||||
{
|
{
|
||||||
backsql_oc_map_rec tmp, *res;
|
backsql_oc_map_rec tmp, *res;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>oc_with_id(): "
|
Debug( LDAP_DEBUG_TRACE, "==>oc_with_id(): "
|
||||||
"searching for objectclass with id='%d'\n", id, 0, 0 );
|
"searching for objectclass with id='%d'\n", id, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
tmp.id = id;
|
tmp.id = id;
|
||||||
res = (backsql_oc_map_rec *)avl_find( si->oc_by_id, &tmp,
|
res = (backsql_oc_map_rec *)avl_find( si->oc_by_id, &tmp,
|
||||||
(AVL_CMP)backsql_cmp_oc_id );
|
(AVL_CMP)backsql_cmp_oc_id );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
if ( res != NULL ) {
|
if ( res != NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||||
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
"found name='%s', id=%d\n", res->name, res->id, 0 );
|
||||||
|
|
@ -438,7 +481,7 @@ backsql_id2oc( backsql_info *si, unsigned long id )
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
Debug( LDAP_DEBUG_TRACE, "<==oc_with_name(): "
|
||||||
"not found\n", 0, 0, 0 );
|
"not found\n", 0, 0, 0 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -448,25 +491,26 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
|
||||||
{
|
{
|
||||||
backsql_at_map_rec tmp, *res;
|
backsql_at_map_rec tmp, *res;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_ad2at(): "
|
||||||
"searching for attribute '%s' for objectclass '%s'\n",
|
"searching for attribute '%s' for objectclass '%s'\n",
|
||||||
attr, objclass->name, 0 );
|
attr, objclass->name, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
tmp.ad = ad;
|
tmp.ad = ad;
|
||||||
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
|
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
|
||||||
(AVL_CMP)backsql_cmp_attr );
|
(AVL_CMP)backsql_cmp_attr );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
if ( res != NULL ) {
|
if ( res != NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
|
||||||
"found name='%s', sel_expr='%s'\n",
|
"found name='%s', sel_expr='%s'\n",
|
||||||
res->name, res->sel_expr, 0 );
|
res->name, res->sel_expr.bv_val, 0 );
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_ad2at(): "
|
||||||
"not found\n", 0, 0, 0 );
|
"not found\n", 0, 0, 0 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -480,11 +524,11 @@ backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
|
||||||
backsql_at_map_rec tmp, *res;
|
backsql_at_map_rec tmp, *res;
|
||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_name2at(): "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_name2at(): "
|
||||||
"searching for attribute '%s' for objectclass '%s'\n",
|
"searching for attribute '%s' for objectclass '%s'\n",
|
||||||
attr, objclass->name, 0 );
|
attr, objclass->name, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
if ( slap_bv2ad( attr, &tmp.ad, &text ) != LDAP_SUCCESS ) {
|
if ( slap_bv2ad( attr, &tmp.ad, &text ) != LDAP_SUCCESS ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -493,16 +537,16 @@ backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
|
||||||
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
|
res = (backsql_at_map_rec *)avl_find( objclass->attrs, &tmp,
|
||||||
(AVL_CMP)backsql_cmp_attr );
|
(AVL_CMP)backsql_cmp_attr );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
if ( res != NULL ) {
|
if ( res != NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_name2at(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_name2at(): "
|
||||||
"found name='%s', sel_expr='%s'\n",
|
"found name='%s', sel_expr='%s'\n",
|
||||||
res->name, res->sel_expr, 0 );
|
res->name, res->sel_expr.bv_val, 0 );
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_name2at(): "
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_name2at(): "
|
||||||
"not found\n", 0, 0, 0 );
|
"not found\n", 0, 0, 0 );
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
@ -511,14 +555,13 @@ static void
|
||||||
backsql_free_attr( backsql_at_map_rec *at )
|
backsql_free_attr( backsql_at_map_rec *at )
|
||||||
{
|
{
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "==>free_attr(): '%s'\n",
|
||||||
at->name.bv_val, 0, 0 );
|
at->ad->ad_cname.bv_val, 0, 0 );
|
||||||
ch_free( at->name.bv_val );
|
ch_free( at->sel_expr.bv_val );
|
||||||
ch_free( at->sel_expr );
|
if ( at->from_tbls.bv_val != NULL ) {
|
||||||
if ( at->from_tbls != NULL ) {
|
ch_free( at->from_tbls.bv_val );
|
||||||
ch_free( at->from_tbls );
|
|
||||||
}
|
}
|
||||||
if ( at->join_where != NULL ) {
|
if ( at->join_where.bv_val != NULL ) {
|
||||||
ch_free( at->join_where );
|
ch_free( at->join_where.bv_val );
|
||||||
}
|
}
|
||||||
if ( at->add_proc != NULL ) {
|
if ( at->add_proc != NULL ) {
|
||||||
ch_free( at->add_proc );
|
ch_free( at->add_proc );
|
||||||
|
|
@ -531,8 +574,8 @@ backsql_free_attr( backsql_at_map_rec *at )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TimesTen */
|
/* TimesTen */
|
||||||
if ( at->sel_expr_u ) {
|
if ( at->sel_expr_u.bv_val ) {
|
||||||
ch_free( at->sel_expr_u );
|
ch_free( at->sel_expr_u.bv_val );
|
||||||
}
|
}
|
||||||
|
|
||||||
ch_free( at );
|
ch_free( at );
|
||||||
|
|
@ -547,11 +590,14 @@ backsql_free_oc( backsql_oc_map_rec *oc )
|
||||||
oc->name.bv_val, 0, 0 );
|
oc->name.bv_val, 0, 0 );
|
||||||
avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
|
avl_free( oc->attrs, (AVL_FREE)backsql_free_attr );
|
||||||
ch_free( oc->name.bv_val );
|
ch_free( oc->name.bv_val );
|
||||||
ch_free( oc->keytbl );
|
ch_free( oc->keytbl.bv_val );
|
||||||
ch_free( oc->keycol );
|
ch_free( oc->keycol.bv_val );
|
||||||
if ( oc->create_proc != NULL ) {
|
if ( oc->create_proc != NULL ) {
|
||||||
ch_free( oc->create_proc );
|
ch_free( oc->create_proc );
|
||||||
}
|
}
|
||||||
|
if ( oc->create_keyval != NULL ) {
|
||||||
|
ch_free( oc->create_keyval );
|
||||||
|
}
|
||||||
if ( oc->delete_proc != NULL ) {
|
if ( oc->delete_proc != NULL ) {
|
||||||
ch_free( oc->delete_proc );
|
ch_free( oc->delete_proc );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,23 @@
|
||||||
* in file LICENSE in the top-level directory of the distribution.
|
* in file LICENSE in the top-level directory of the distribution.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/*
|
||||||
|
* FIXME: we explicitly keep the objectClass name because
|
||||||
|
* the ObjectClass structure does not use bervals (yet?)
|
||||||
|
*/
|
||||||
struct berval name;
|
struct berval name;
|
||||||
|
/*
|
||||||
|
* Structure of corresponding LDAP objectClass definition
|
||||||
|
*/
|
||||||
ObjectClass *oc;
|
ObjectClass *oc;
|
||||||
char *keytbl;
|
struct berval keytbl;
|
||||||
char *keycol;
|
struct berval keycol;
|
||||||
/* expected to return keyval of newly created entry */
|
/* expected to return keyval of newly created entry */
|
||||||
char *create_proc;
|
char *create_proc;
|
||||||
|
/* in case create_proc does not return the keyval of the newly
|
||||||
|
* created row */
|
||||||
|
char *create_keyval;
|
||||||
/* supposed to expect keyval as parameter and delete
|
/* supposed to expect keyval as parameter and delete
|
||||||
* all the attributes as well */
|
* all the attributes as well */
|
||||||
char *delete_proc;
|
char *delete_proc;
|
||||||
|
|
@ -29,12 +38,11 @@ typedef struct {
|
||||||
} backsql_oc_map_rec;
|
} backsql_oc_map_rec;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* literal name of corresponding LDAP attribute type */
|
/* Description of corresponding LDAP attribute type */
|
||||||
struct berval name;
|
|
||||||
AttributeDescription *ad;
|
AttributeDescription *ad;
|
||||||
char *from_tbls;
|
struct berval from_tbls;
|
||||||
char *join_where;
|
struct berval join_where;
|
||||||
char *sel_expr;
|
struct berval sel_expr;
|
||||||
/* supposed to expect 2 binded values: entry keyval
|
/* supposed to expect 2 binded values: entry keyval
|
||||||
* and attr. value to add, like "add_name(?,?,?)" */
|
* and attr. value to add, like "add_name(?,?,?)" */
|
||||||
char *add_proc;
|
char *add_proc;
|
||||||
|
|
@ -45,7 +53,7 @@ typedef struct {
|
||||||
* is preconstructed from parts on schemamap load time */
|
* is preconstructed from parts on schemamap load time */
|
||||||
char *query;
|
char *query;
|
||||||
/* following flags are bitmasks (first bit used for add_proc,
|
/* following flags are bitmasks (first bit used for add_proc,
|
||||||
* second - for modify, third - for delete_proc) */
|
* second - for delete_proc) */
|
||||||
/* order of parameters for procedures above;
|
/* order of parameters for procedures above;
|
||||||
* 1 means "data then keyval", 0 means "keyval then data" */
|
* 1 means "data then keyval", 0 means "keyval then data" */
|
||||||
int param_order;
|
int param_order;
|
||||||
|
|
@ -54,7 +62,7 @@ typedef struct {
|
||||||
* for return code) */
|
* for return code) */
|
||||||
int expect_return;
|
int expect_return;
|
||||||
/* TimesTen */
|
/* TimesTen */
|
||||||
char *sel_expr_u;
|
struct berval sel_expr_u;
|
||||||
} backsql_at_map_rec;
|
} backsql_at_map_rec;
|
||||||
|
|
||||||
/* defines to support bitmasks above */
|
/* defines to support bitmasks above */
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,6 @@
|
||||||
#include "entry-id.h"
|
#include "entry-id.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
static struct berval AllUser = BER_BVC( LDAP_ALL_USER_ATTRIBUTES );
|
|
||||||
static struct berval AllOper = BER_BVC( LDAP_ALL_OPERATIONAL_ATTRIBUTES );
|
|
||||||
static struct berval NoAttrs = BER_BVC( LDAP_NO_ATTRS );
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static struct berval NoAttrs = BER_BVC( LDAP_NO_ATTRS );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
|
backsql_attrlist_add( backsql_srch_info *bsi, AttributeDescription *ad )
|
||||||
{
|
{
|
||||||
|
|
@ -102,6 +94,7 @@ backsql_init_search(
|
||||||
bsi->be = be;
|
bsi->be = be;
|
||||||
bsi->conn = conn;
|
bsi->conn = conn;
|
||||||
bsi->op = op;
|
bsi->op = op;
|
||||||
|
bsi->attr_flags = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: need to discover how to deal with 1.1 (NoAttrs)
|
* FIXME: need to discover how to deal with 1.1 (NoAttrs)
|
||||||
|
|
@ -123,8 +116,11 @@ backsql_init_search(
|
||||||
/*
|
/*
|
||||||
* ignore "+"
|
* ignore "+"
|
||||||
*/
|
*/
|
||||||
if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0
|
if ( BACKSQL_NCMP( &p->an_name, &AllOper ) == 0 ) {
|
||||||
|| BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) {
|
continue;
|
||||||
|
|
||||||
|
} else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) {
|
||||||
|
bsi->attr_flags |= BSQL_SF_ALL_OPER;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,7 +158,7 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, "(", NULL );
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "c", '(' /* ) */ );
|
||||||
|
|
||||||
while ( 1 ) {
|
while ( 1 ) {
|
||||||
res = backsql_process_filter( bsi, f );
|
res = backsql_process_filter( bsi, f );
|
||||||
|
|
@ -181,18 +177,20 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
|
||||||
|
|
||||||
switch ( op ) {
|
switch ( op ) {
|
||||||
case LDAP_FILTER_AND:
|
case LDAP_FILTER_AND:
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||||
" AND ", NULL );
|
(ber_len_t)sizeof( " AND " ) - 1,
|
||||||
|
" AND " );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_FILTER_OR:
|
case LDAP_FILTER_OR:
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||||
" OR ", NULL );
|
(ber_len_t)sizeof( " OR " ) - 1,
|
||||||
|
" OR " );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, /* ( */ ")", NULL );
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "c", /* ( */ ')' );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -209,63 +207,75 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
|
|
||||||
at = backsql_ad2at( bsi->oc, f->f_sub_desc );
|
at = backsql_ad2at( bsi->oc, f->f_sub_desc );
|
||||||
|
|
||||||
|
assert( at );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* When dealing with case-sensitive strings
|
* When dealing with case-sensitive strings
|
||||||
* we may omit normalization; however, normalized
|
* we may omit normalization; however, normalized
|
||||||
* SQL filters are more liberal.
|
* SQL filters are more liberal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, "(" /* ) */ , NULL );
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "c", '(' /* ) */ );
|
||||||
|
|
||||||
/* TimesTen */
|
/* TimesTen */
|
||||||
Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->sel_expr,
|
Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->sel_expr.bv_val,
|
||||||
at->sel_expr_u ? at->sel_expr_u : "<NULL>", 0 );
|
at->sel_expr_u.bv_val ? at->sel_expr_u.bv_val : "<NULL>", 0 );
|
||||||
if ( bsi->bi->upper_func ) {
|
if ( bsi->bi->upper_func.bv_val ) {
|
||||||
/*
|
/*
|
||||||
* If a pre-upper-cased version of the column exists, use it
|
* If a pre-upper-cased version of the column exists, use it
|
||||||
*/
|
*/
|
||||||
if ( at->sel_expr_u ) {
|
if ( at->sel_expr_u.bv_val ) {
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len,
|
||||||
at->sel_expr_u, " LIKE '", NULL);
|
"bl",
|
||||||
|
&at->sel_expr_u,
|
||||||
|
(ber_len_t)sizeof( " LIKE '" ) - 1,
|
||||||
|
" LIKE '" );
|
||||||
} else {
|
} else {
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len,
|
||||||
bsi->bi->upper_func,
|
"bcbcl",
|
||||||
"(", at->sel_expr, ")",
|
&bsi->bi->upper_func,
|
||||||
" LIKE '", NULL );
|
'(',
|
||||||
|
&at->sel_expr,
|
||||||
|
')',
|
||||||
|
(ber_len_t)sizeof( " LIKE '" ) - 1,
|
||||||
|
" LIKE '" );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "bl",
|
||||||
at->sel_expr, " LIKE '", NULL );
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( " LIKE '" ) - 1, " LIKE '" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( f->f_sub_initial.bv_val != NULL ) {
|
if ( f->f_sub_initial.bv_val != NULL ) {
|
||||||
size_t start;
|
size_t start;
|
||||||
|
|
||||||
start = bsi->flt_where.bv_len;
|
start = bsi->flt_where.bv_len;
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "b",
|
||||||
f->f_sub_initial.bv_val, NULL );
|
&f->f_sub_initial );
|
||||||
if ( bsi->bi->upper_func ) {
|
if ( bsi->bi->upper_func.bv_val ) {
|
||||||
ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
|
ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, "%", NULL );
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "c", '%' );
|
||||||
|
|
||||||
if ( f->f_sub_any != NULL ) {
|
if ( f->f_sub_any != NULL ) {
|
||||||
for ( i = 0; f->f_sub_any[ i ].bv_val != NULL; i++ ) {
|
for ( i = 0; f->f_sub_any[ i ].bv_val != NULL; i++ ) {
|
||||||
size_t start;
|
size_t start;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE,
|
Debug( LDAP_DEBUG_TRACE,
|
||||||
"==>backsql_process_sub_filter(): "
|
"==>backsql_process_sub_filter(): "
|
||||||
"sub_any='%s'\n", f->f_sub_any[ i ].bv_val,
|
"sub_any='%s'\n", f->f_sub_any[ i ].bv_val,
|
||||||
0, 0 );
|
0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
start = bsi->flt_where.bv_len;
|
start = bsi->flt_where.bv_len;
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len,
|
||||||
f->f_sub_any[ i ].bv_val, "%", NULL );
|
"bc",
|
||||||
if ( bsi->bi->upper_func) {
|
&f->f_sub_any[ i ],
|
||||||
|
'%' );
|
||||||
|
if ( bsi->bi->upper_func.bv_val ) {
|
||||||
/*
|
/*
|
||||||
* Note: toupper('%') = '%'
|
* Note: toupper('%') = '%'
|
||||||
*/
|
*/
|
||||||
|
|
@ -277,15 +287,16 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
size_t start;
|
size_t start;
|
||||||
|
|
||||||
start = bsi->flt_where.bv_len;
|
start = bsi->flt_where.bv_len;
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "b",
|
||||||
f->f_sub_final.bv_val, NULL);
|
&f->f_sub_final );
|
||||||
if ( bsi->bi->upper_func ) {
|
if ( bsi->bi->upper_func.bv_val ) {
|
||||||
ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
|
ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, /* ( */ "')", NULL );
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||||
|
(ber_len_t)sizeof( /* (' */ "')" ) - 1, /* ( */ "')" );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -294,10 +305,12 @@ int
|
||||||
backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
{
|
{
|
||||||
backsql_at_map_rec *at;
|
backsql_at_map_rec *at;
|
||||||
backsql_at_map_rec oc_attr = { BER_BVC("objectClass"),
|
backsql_at_map_rec oc_attr = {
|
||||||
slap_schema.si_ad_objectClass, "", "", NULL, NULL, NULL, NULL };
|
slap_schema.si_ad_objectClass, BER_BVC(""), BER_BVC(""),
|
||||||
|
{ 0, NULL }, NULL, NULL, NULL };
|
||||||
AttributeDescription *ad = NULL;
|
AttributeDescription *ad = NULL;
|
||||||
int done = 0, len = 0;
|
int done = 0;
|
||||||
|
ber_len_t len = 0;
|
||||||
/* TimesTen */
|
/* TimesTen */
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
|
@ -320,10 +333,12 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_FILTER_NOT:
|
case LDAP_FILTER_NOT:
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||||
"NOT (", NULL );
|
(ber_len_t)sizeof( "NOT (" /* ) */ ) - 1,
|
||||||
|
"NOT (" /* ) */ );
|
||||||
rc = backsql_process_filter( bsi, f->f_not );
|
rc = backsql_process_filter( bsi, f->f_not );
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len, ")", NULL );
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "c",
|
||||||
|
/* ( */ ')' );
|
||||||
done = 1;
|
done = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -345,50 +360,52 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( strcasecmp( ad->ad_cname.bv_val, "objectclass" ) ) {
|
if ( ad != slap_schema.si_ad_objectClass ) {
|
||||||
at = backsql_ad2at( bsi->oc, ad );
|
at = backsql_ad2at( bsi->oc, ad );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
struct berval bv;
|
|
||||||
|
|
||||||
at = &oc_attr;
|
at = &oc_attr;
|
||||||
|
backsql_strfcat( &at->sel_expr, &len, "cbc",
|
||||||
/*
|
'\'',
|
||||||
* FIXME: use berval for at->sel_expr ?
|
&bsi->oc->name,
|
||||||
*/
|
'\'' );
|
||||||
bv.bv_val = at->sel_expr;
|
|
||||||
bv.bv_len = at->sel_expr ? strlen( at->sel_expr ) : 0;
|
|
||||||
backsql_strcat( &bv, &len, "'", bsi->oc->name.bv_val,
|
|
||||||
"'", NULL );
|
|
||||||
at->sel_expr = bv.bv_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( at == NULL ) {
|
if ( at == NULL ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
|
||||||
"attribute '%s' is not defined for objectclass '%s'\n",
|
"attribute '%s' is not defined for objectclass '%s'\n",
|
||||||
ad->ad_cname.bv_val, bsi->oc->name.bv_val, 0 );
|
ad->ad_cname.bv_val, bsi->oc->name.bv_val, 0 );
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "l",
|
||||||
" 1=0 ", NULL );
|
(ber_len_t)sizeof( " 1=0 " ) - 1, " 1=0 " );
|
||||||
goto impossible;
|
goto impossible;
|
||||||
}
|
}
|
||||||
|
|
||||||
backsql_merge_from_clause( &bsi->from.bv_val, &bsi->from_len,
|
backsql_merge_from_clause( &bsi->from, &bsi->from_len,
|
||||||
at->from_tbls );
|
&at->from_tbls );
|
||||||
/*
|
/*
|
||||||
* need to add this attribute to list of attrs to load,
|
* need to add this attribute to list of attrs to load,
|
||||||
* so that we could do test_filter() later
|
* so that we could do test_filter() later
|
||||||
*/
|
*/
|
||||||
backsql_attrlist_add( bsi, ad );
|
backsql_attrlist_add( bsi, ad );
|
||||||
|
|
||||||
if ( at->join_where != NULL && strstr( bsi->join_where.bv_val, at->join_where ) == NULL ) {
|
if ( at->join_where.bv_val != NULL
|
||||||
backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
|
&& strstr( bsi->join_where.bv_val, at->join_where.bv_val ) == NULL ) {
|
||||||
" AND ", at->join_where, NULL );
|
backsql_strfcat( &bsi->join_where, &bsi->jwhere_len, "lb",
|
||||||
|
(ber_len_t)sizeof( " AND " ) - 1, " AND ",
|
||||||
|
&at->join_where );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
/*
|
||||||
|
* FIXME: this is not required any more; however, note that
|
||||||
|
* attribute name syntax might collide with SQL legal aliases
|
||||||
|
*/
|
||||||
if ( at != &oc_attr ) {
|
if ( at != &oc_attr ) {
|
||||||
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
backsql_strfcat( &bsi->sel, &bsi->sel_len, "cblb",
|
||||||
",", at->sel_expr, " AS ",
|
',',
|
||||||
at->name.bv_val, NULL );
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( " AS " ) - 1, " AS ",
|
||||||
|
&at->name );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -400,49 +417,72 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
* upper_func stuff is made for Oracle, where UPPER is
|
* upper_func stuff is made for Oracle, where UPPER is
|
||||||
* safely applicable to NUMBER etc.
|
* safely applicable to NUMBER etc.
|
||||||
*/
|
*/
|
||||||
if ( bsi->bi->upper_func ) {
|
if ( bsi->bi->upper_func.bv_val ) {
|
||||||
size_t start;
|
size_t start;
|
||||||
|
|
||||||
if ( at->sel_expr_u ) {
|
if ( at->sel_expr_u.bv_val ) {
|
||||||
backsql_strcat( &bsi->flt_where,
|
backsql_strfcat( &bsi->flt_where,
|
||||||
&bsi->fwhere_len, "(",
|
&bsi->fwhere_len, "cbl",
|
||||||
at->sel_expr_u, "='", NULL );
|
'(',
|
||||||
|
&at->sel_expr_u,
|
||||||
|
(ber_len_t)sizeof( "='" ) - 1,
|
||||||
|
"='" );
|
||||||
} else {
|
} else {
|
||||||
backsql_strcat( &bsi->flt_where,
|
backsql_strfcat( &bsi->flt_where,
|
||||||
&bsi->fwhere_len, "(",
|
&bsi->fwhere_len, "cbcbl",
|
||||||
bsi->bi->upper_func, "(",
|
'(' /* ) */ ,
|
||||||
at->sel_expr, ")='", NULL );
|
&bsi->bi->upper_func,
|
||||||
|
'(' /* ) */ ,
|
||||||
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( /* ( */ ")='" ) - 1,
|
||||||
|
/* ( */ ")='" );
|
||||||
}
|
}
|
||||||
|
|
||||||
start = bsi->flt_where.bv_len;
|
start = bsi->flt_where.bv_len;
|
||||||
|
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len,
|
||||||
f->f_av_value.bv_val, "')", NULL );
|
"bl",
|
||||||
|
&f->f_av_value,
|
||||||
|
(ber_len_t)sizeof( /* (' */ "')" ) - 1,
|
||||||
|
/* (' */ "')" );
|
||||||
|
|
||||||
ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
|
ldap_pvt_str2upper( &bsi->flt_where.bv_val[ start ] );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len,
|
||||||
"(", at->sel_expr, "='",
|
"cblbl",
|
||||||
f->f_av_value.bv_val, "')", NULL );
|
'(',
|
||||||
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( "='" ) - 1, "='",
|
||||||
|
&f->f_av_value,
|
||||||
|
(ber_len_t)sizeof( /* (' */ "')" ) - 1,
|
||||||
|
/* (' */ "')" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_FILTER_GE:
|
case LDAP_FILTER_GE:
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
|
||||||
"(", at->sel_expr, ">=",
|
'(' /* ) */ ,
|
||||||
f->f_av_value.bv_val, ")", NULL );
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( ">=" ) - 1, ">=",
|
||||||
|
&f->f_av_value,
|
||||||
|
/* ( */ ')' );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_FILTER_LE:
|
case LDAP_FILTER_LE:
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "cblbc",
|
||||||
"(", at->sel_expr, "<=",
|
'(' /* ) */ ,
|
||||||
f->f_av_value.bv_val, ")", NULL );
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( "<=" ) - 1, "<=",
|
||||||
|
&f->f_av_value,
|
||||||
|
/* ( */ ')' );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_FILTER_PRESENT:
|
case LDAP_FILTER_PRESENT:
|
||||||
backsql_strcat( &bsi->flt_where, &bsi->fwhere_len,
|
backsql_strfcat( &bsi->flt_where, &bsi->fwhere_len, "lbl",
|
||||||
"NOT (", at->sel_expr, " IS NULL)", NULL );
|
(ber_len_t)sizeof( "NOT (" ) - 1, "NOT (",
|
||||||
|
&at->sel_expr,
|
||||||
|
(ber_len_t)sizeof( " IS NULL)" ) - 1, " IS NULL)" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_FILTER_SUBSTRINGS:
|
case LDAP_FILTER_SUBSTRINGS:
|
||||||
|
|
@ -451,16 +491,16 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if ( oc_attr.sel_expr != NULL ) {
|
if ( oc_attr.sel_expr.bv_val != NULL ) {
|
||||||
free( oc_attr.sel_expr );
|
free( oc_attr.sel_expr.bv_val );
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter()\n", 0, 0, 0 );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
impossible:
|
impossible:
|
||||||
if ( oc_attr.sel_expr != NULL ) {
|
if ( oc_attr.sel_expr.bv_val != NULL ) {
|
||||||
free( oc_attr.sel_expr );
|
free( oc_attr.sel_expr.bv_val );
|
||||||
}
|
}
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() returns -1\n",
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() returns -1\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
|
|
@ -471,7 +511,7 @@ static int
|
||||||
backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
|
backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
|
||||||
{
|
{
|
||||||
backsql_info *bi = (backsql_info *)bsi->be->be_private;
|
backsql_info *bi = (backsql_info *)bsi->be->be_private;
|
||||||
int q_len = 0;
|
ber_len_t q_len = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( query );
|
assert( query );
|
||||||
|
|
@ -491,55 +531,87 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
|
||||||
bsi->flt_where.bv_val = NULL;
|
bsi->flt_where.bv_val = NULL;
|
||||||
bsi->flt_where.bv_len = 0;
|
bsi->flt_where.bv_len = 0;
|
||||||
bsi->fwhere_len = 0;
|
bsi->fwhere_len = 0;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
/*
|
||||||
|
* FIXME: this query has been split in case a string cast function
|
||||||
|
* is defined; more sophisticated (pattern based) function should
|
||||||
|
* be used
|
||||||
|
*/
|
||||||
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
||||||
"SELECT DISTINCT ldap_entries.id,",
|
"SELECT DISTINCT ldap_entries.id,",
|
||||||
bsi->oc->keytbl, ".", bsi->oc->keycol,
|
bsi->oc->keytbl.bv_val, ".", bsi->oc->keycol.bv_val,
|
||||||
",'", bsi->oc->name.bv_val, "' AS objectClass",
|
",'", bsi->oc->name.bv_val, "' AS objectClass",
|
||||||
",ldap_entries.dn AS dn", NULL );
|
",ldap_entries.dn AS dn", NULL );
|
||||||
#endif
|
#endif
|
||||||
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
|
||||||
"SELECT DISTINCT ldap_entries.id,",
|
|
||||||
bsi->oc->keytbl, ".", bsi->oc->keycol, ",", NULL );
|
|
||||||
if ( bi->strcast_func ) {
|
|
||||||
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
|
||||||
bi->strcast_func,
|
|
||||||
"('", bsi->oc->name.bv_val, "')", NULL );
|
|
||||||
} else {
|
|
||||||
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
|
||||||
"'", bsi->oc->name.bv_val, "'", NULL );
|
|
||||||
}
|
|
||||||
backsql_strcat( &bsi->sel, &bsi->sel_len,
|
|
||||||
" AS objectClass,ldap_entries.dn AS dn", NULL );
|
|
||||||
|
|
||||||
backsql_strcat( &bsi->from, &bsi->from_len,
|
backsql_strfcat( &bsi->sel, &bsi->sel_len, "lbcbc",
|
||||||
" FROM ldap_entries,", bsi->oc->keytbl, NULL );
|
(ber_len_t)sizeof( "SELECT DISTINCT ldap_entries.id," ) - 1,
|
||||||
backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
|
"SELECT DISTINCT ldap_entries.id,",
|
||||||
" WHERE ", bsi->oc->keytbl, ".", bsi->oc->keycol,
|
&bsi->oc->keytbl,
|
||||||
"=ldap_entries.keyval AND ",
|
'.',
|
||||||
"ldap_entries.oc_map_id=? AND ", NULL );
|
&bsi->oc->keycol,
|
||||||
|
',' );
|
||||||
|
|
||||||
|
if ( bi->strcast_func.bv_val ) {
|
||||||
|
backsql_strfcat( &bsi->sel, &bsi->sel_len, "blbl",
|
||||||
|
&bi->strcast_func,
|
||||||
|
(ber_len_t)sizeof( "('" /* ') */ ) - 1,
|
||||||
|
"('" /* ') */ ,
|
||||||
|
&bsi->oc->name,
|
||||||
|
(ber_len_t)sizeof( /* (' */ "')" ) - 1,
|
||||||
|
/* (' */ "')" );
|
||||||
|
} else {
|
||||||
|
backsql_strfcat( &bsi->sel, &bsi->sel_len, "cbc",
|
||||||
|
'\'',
|
||||||
|
&bsi->oc->name,
|
||||||
|
'\'' );
|
||||||
|
}
|
||||||
|
backsql_strfcat( &bsi->sel, &bsi->sel_len, "l",
|
||||||
|
(ber_len_t)sizeof( " AS objectClass,ldap_entries.dn AS dn" ) - 1,
|
||||||
|
" AS objectClass,ldap_entries.dn AS dn" );
|
||||||
|
|
||||||
|
backsql_strfcat( &bsi->from, &bsi->from_len, "lb",
|
||||||
|
(ber_len_t)sizeof( " FROM ldap_entries," ) - 1,
|
||||||
|
" FROM ldap_entries,",
|
||||||
|
&bsi->oc->keytbl );
|
||||||
|
|
||||||
|
backsql_strfcat( &bsi->join_where, &bsi->jwhere_len, "lbcbl",
|
||||||
|
(ber_len_t)sizeof( " WHERE " ) - 1, " WHERE ",
|
||||||
|
&bsi->oc->keytbl,
|
||||||
|
'.',
|
||||||
|
&bsi->oc->keycol,
|
||||||
|
(ber_len_t)sizeof( "=ldap_entries.keyval AND ldap_entries.oc_map_id=? AND " ) - 1,
|
||||||
|
"=ldap_entries.keyval AND ldap_entries.oc_map_id=? AND " );
|
||||||
|
|
||||||
switch ( bsi->scope ) {
|
switch ( bsi->scope ) {
|
||||||
case LDAP_SCOPE_BASE:
|
case LDAP_SCOPE_BASE:
|
||||||
if ( bsi->bi->upper_func ) {
|
if ( bsi->bi->upper_func.bv_val ) {
|
||||||
backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
|
backsql_strfcat( &bsi->join_where, &bsi->jwhere_len,
|
||||||
bsi->bi->upper_func,
|
"blbcb",
|
||||||
"(","ldap_entries.dn)=",
|
&bsi->bi->upper_func,
|
||||||
bsi->bi->upper_func, "(?)", NULL );
|
(ber_len_t)sizeof( "(ldap_entries.dn)=" ) - 1,
|
||||||
|
"(ldap_entries.dn)=",
|
||||||
|
&bsi->bi->upper_func_open,
|
||||||
|
'?',
|
||||||
|
&bsi->bi->upper_func_close );
|
||||||
} else {
|
} else {
|
||||||
backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
|
backsql_strfcat( &bsi->join_where, &bsi->jwhere_len,
|
||||||
"ldap_entries.dn=?", NULL );
|
"l",
|
||||||
|
(ber_len_t)sizeof( "ldap_entries.dn=?" ) - 1,
|
||||||
|
"ldap_entries.dn=?" );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_SCOPE_ONELEVEL:
|
case LDAP_SCOPE_ONELEVEL:
|
||||||
backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
|
backsql_strfcat( &bsi->join_where, &bsi->jwhere_len, "l",
|
||||||
"ldap_entries.parent=?", NULL );
|
(ber_len_t)sizeof( "ldap_entries.parent=?" ) - 1,
|
||||||
|
"ldap_entries.parent=?" );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_SCOPE_SUBTREE:
|
case LDAP_SCOPE_SUBTREE:
|
||||||
backsql_strcat( &bsi->join_where, &bsi->jwhere_len,
|
backsql_strfcat( &bsi->join_where, &bsi->jwhere_len, "b",
|
||||||
bsi->bi->subtree_cond, NULL );
|
&bsi->bi->subtree_cond );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -548,10 +620,12 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
|
||||||
|
|
||||||
rc = backsql_process_filter( bsi, bsi->filter );
|
rc = backsql_process_filter( bsi, bsi->filter );
|
||||||
if ( rc > 0 ) {
|
if ( rc > 0 ) {
|
||||||
backsql_strcat( query, &q_len,
|
backsql_strfcat( query, &q_len, "bbblb",
|
||||||
bsi->sel.bv_val, bsi->from.bv_val,
|
&bsi->sel,
|
||||||
bsi->join_where.bv_val,
|
&bsi->from,
|
||||||
" AND ", bsi->flt_where.bv_val, NULL );
|
&bsi->join_where,
|
||||||
|
(ber_len_t)sizeof( " AND " ) - 1, " AND ",
|
||||||
|
&bsi->flt_where );
|
||||||
|
|
||||||
} else if ( rc < 0 ) {
|
} else if ( rc < 0 ) {
|
||||||
/*
|
/*
|
||||||
|
|
@ -590,17 +664,19 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
|
||||||
RETCODE rc;
|
RETCODE rc;
|
||||||
backsql_entryID base_id, *c_id;
|
backsql_entryID base_id, *c_id;
|
||||||
int res;
|
int res;
|
||||||
#if 0
|
|
||||||
Entry *e;
|
|
||||||
#endif
|
|
||||||
BACKSQL_ROW_NTS row;
|
BACKSQL_ROW_NTS row;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
/* TimesTen */
|
|
||||||
char temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 ];
|
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n",
|
||||||
oc->name.bv_val, 0, 0 );
|
oc->name.bv_val, 0, 0 );
|
||||||
|
|
||||||
|
if ( bsi->n_candidates == -1 ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
|
||||||
|
"unchecked limit has been overcome\n", 0, 0, 0 );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
bsi->oc = oc;
|
bsi->oc = oc;
|
||||||
if ( backsql_srch_query( bsi, &query ) ) {
|
if ( backsql_srch_query( bsi, &query ) ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
|
||||||
|
|
@ -640,7 +716,21 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LDAP_SCOPE_SUBTREE:
|
case LDAP_SCOPE_SUBTREE: {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* + 1 because we need room for '%'; this makes a subtree
|
||||||
|
* search for a DN BACKSQL_MAX_DN_LEN long legal
|
||||||
|
* if it returns that DN only
|
||||||
|
*/
|
||||||
|
char temp_base_dn[ BACKSQL_MAX_DN_LEN + 1 + 1 ];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not accept DNs longer than BACKSQL_MAX_DN_LEN;
|
||||||
|
* however this should be handled earlier
|
||||||
|
*/
|
||||||
|
assert( bsi->base_dn->bv_len <= BACKSQL_MAX_DN_LEN );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the parameters for the SQL built earlier
|
* Sets the parameters for the SQL built earlier
|
||||||
* NOTE that all the databases could actually use
|
* NOTE that all the databases could actually use
|
||||||
|
|
@ -654,7 +744,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
|
||||||
* If "dn" is being used, do a suffix search.
|
* If "dn" is being used, do a suffix search.
|
||||||
* If "dn_ru" is being used, do a prefix search.
|
* If "dn_ru" is being used, do a prefix search.
|
||||||
*/
|
*/
|
||||||
if ( bsi->bi->has_ldapinfo_dn_ru ) {
|
if ( BACKSQL_HAS_LDAPINFO_DN_RU( bsi->bi ) ) {
|
||||||
temp_base_dn[ 0 ] = '\0';
|
temp_base_dn[ 0 ] = '\0';
|
||||||
for ( i = 0, j = bsi->base_dn->bv_len - 1;
|
for ( i = 0, j = bsi->base_dn->bv_len - 1;
|
||||||
j >= 0; i++, j--) {
|
j >= 0; i++, j--) {
|
||||||
|
|
@ -684,6 +774,7 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case LDAP_SCOPE_ONELEVEL:
|
case LDAP_SCOPE_ONELEVEL:
|
||||||
res = backsql_dn2id( bsi->bi, &base_id,
|
res = backsql_dn2id( bsi->bi, &base_id,
|
||||||
|
|
@ -719,41 +810,23 @@ backsql_oc_get_candidates( backsql_oc_map_rec *oc, backsql_srch_info *bsi )
|
||||||
backsql_BindRowAsStrings( sth, &row );
|
backsql_BindRowAsStrings( sth, &row );
|
||||||
rc = SQLFetch( sth );
|
rc = SQLFetch( sth );
|
||||||
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
|
for ( ; BACKSQL_SUCCESS( rc ); rc = SQLFetch( sth ) ) {
|
||||||
#if 0
|
|
||||||
e = (Entry *)ch_calloc( 1, sizeof( Entry ) );
|
|
||||||
for ( i = 1; i < row.ncols; i++ ) {
|
|
||||||
if ( row.is_null[ i ] > 0 ) {
|
|
||||||
struct berval bv;
|
|
||||||
|
|
||||||
ber_str2bv( row.cols[ i ],
|
|
||||||
row.col_prec[ i ], 0, &bv );
|
|
||||||
|
|
||||||
backsql_entry_addattr( e,
|
|
||||||
&row.col_names[ i ], &bv );
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
c_id = (backsql_entryID *)ch_calloc( 1,
|
c_id = (backsql_entryID *)ch_calloc( 1,
|
||||||
sizeof( backsql_entryID ) );
|
sizeof( backsql_entryID ) );
|
||||||
c_id->id = atoi( row.cols[ 0 ] );
|
c_id->id = strtol( row.cols[ 0 ], NULL, 0 );
|
||||||
c_id->keyval = atoi( row.cols[ 1 ] );
|
c_id->keyval = strtol( row.cols[ 1 ], NULL, 0 );
|
||||||
c_id->oc_id = bsi->oc->id;
|
c_id->oc_id = bsi->oc->id;
|
||||||
ber_str2bv( row.cols[ 3 ], 0, 1, &c_id->dn );
|
ber_str2bv( row.cols[ 3 ], 0, 1, &c_id->dn );
|
||||||
c_id->next = bsi->id_list;
|
c_id->next = bsi->id_list;
|
||||||
bsi->id_list = c_id;
|
bsi->id_list = c_id;
|
||||||
bsi->n_candidates++;
|
bsi->n_candidates--;
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
|
||||||
"added entry id=%ld, keyval=%ld dn='%s'\n",
|
"added entry id=%ld, keyval=%ld dn='%s'\n",
|
||||||
c_id->id, c_id->keyval, row.cols[ 3 ] );
|
c_id->id, c_id->keyval, row.cols[ 3 ] );
|
||||||
|
|
||||||
|
if ( bsi->n_candidates == -1 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
backsql_FreeRow( &row );
|
backsql_FreeRow( &row );
|
||||||
SQLFreeStmt( sth, SQL_DROP );
|
SQLFreeStmt( sth, SQL_DROP );
|
||||||
|
|
@ -799,6 +872,20 @@ backsql_search(
|
||||||
"attributes to load: %s\n",
|
"attributes to load: %s\n",
|
||||||
deref, attrsonly, attrs == NULL ? "all" : "custom list" );
|
deref, attrsonly, attrs == NULL ? "all" : "custom list" );
|
||||||
|
|
||||||
|
if ( nbase->bv_len > BACKSQL_MAX_DN_LEN ) {
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
|
||||||
|
"search base length (%ld) exceeds max length (%ld)\n",
|
||||||
|
nbase->bv_len, BACKSQL_MAX_DN_LEN, 0 );
|
||||||
|
/*
|
||||||
|
* FIXME: a LDAP_NO_SUCH_OBJECT could be appropriate
|
||||||
|
* since it is impossible that such a long DN exists
|
||||||
|
* in the backend
|
||||||
|
*/
|
||||||
|
send_ldap_result( conn, op, LDAP_ADMINLIMIT_EXCEEDED,
|
||||||
|
"", NULL, NULL, NULL );
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
sres = backsql_get_db_conn( be, conn, &dbh );
|
sres = backsql_get_db_conn( be, conn, &dbh );
|
||||||
if ( sres != LDAP_SUCCESS ) {
|
if ( sres != LDAP_SUCCESS ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
|
||||||
|
|
@ -811,7 +898,7 @@ backsql_search(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TimesTen : Pass it along to the lower level routines */
|
/* TimesTen : Pass it along to the lower level routines */
|
||||||
srch_info.isTimesTen = bi->isTimesTen;
|
srch_info.use_reverse_dn = BACKSQL_USE_REVERSE_DN( bi );
|
||||||
|
|
||||||
/* if not root, get appropriate limits */
|
/* if not root, get appropriate limits */
|
||||||
if ( be_isroot( be, &op->o_ndn ) ) {
|
if ( be_isroot( be, &op->o_ndn ) ) {
|
||||||
|
|
@ -890,11 +977,12 @@ backsql_search(
|
||||||
* of entries matching LDAP query filter and scope (or at least
|
* of entries matching LDAP query filter and scope (or at least
|
||||||
* candidates), and get the IDs
|
* candidates), and get the IDs
|
||||||
*/
|
*/
|
||||||
|
srch_info.n_candidates = ( isroot ? -2 : limit->lms_s_unchecked == -1
|
||||||
|
? -2 : limit->lms_s_unchecked );
|
||||||
avl_apply( bi->oc_by_oc, (AVL_APPLY)backsql_oc_get_candidates,
|
avl_apply( bi->oc_by_oc, (AVL_APPLY)backsql_oc_get_candidates,
|
||||||
&srch_info, 0, AVL_INORDER );
|
&srch_info, 0, AVL_INORDER );
|
||||||
|
|
||||||
if ( !isroot && limit->lms_s_unchecked != -1 ) {
|
if ( !isroot && limit->lms_s_unchecked != -1 ) {
|
||||||
if ( srch_info.n_candidates > limit->lms_s_unchecked ) {
|
if ( srch_info.n_candidates == -1 ) {
|
||||||
send_search_result( conn, op,
|
send_search_result( conn, op,
|
||||||
LDAP_ADMINLIMIT_EXCEEDED,
|
LDAP_ADMINLIMIT_EXCEEDED,
|
||||||
NULL, NULL, NULL, NULL, 0 );
|
NULL, NULL, NULL, NULL, 0 );
|
||||||
|
|
@ -908,7 +996,8 @@ backsql_search(
|
||||||
* mentioned in attrs and filter), test it against full filter
|
* mentioned in attrs and filter), test it against full filter
|
||||||
* and then send to client
|
* and then send to client
|
||||||
*/
|
*/
|
||||||
for ( eid = srch_info.id_list; eid != NULL; eid = eid->next ) {
|
for ( eid = srch_info.id_list; eid != NULL;
|
||||||
|
eid = backsql_free_entryID( eid, 1 ) ) {
|
||||||
|
|
||||||
/* check for abandon */
|
/* check for abandon */
|
||||||
if ( op->o_abandon ) {
|
if ( op->o_abandon ) {
|
||||||
|
|
@ -919,7 +1008,7 @@ backsql_search(
|
||||||
if ( tlimit != -1 && slap_get_time() > stoptime ) {
|
if ( tlimit != -1 && slap_get_time() > stoptime ) {
|
||||||
send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
|
send_search_result( conn, op, LDAP_TIMELIMIT_EXCEEDED,
|
||||||
NULL, NULL, v2refs, NULL, nentries );
|
NULL, NULL, v2refs, NULL, nentries );
|
||||||
break;
|
goto end_of_search;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data "
|
Debug(LDAP_DEBUG_TRACE, "backsql_search(): loading data "
|
||||||
|
|
@ -950,22 +1039,34 @@ backsql_search(
|
||||||
== LDAP_COMPARE_TRUE ) {
|
== LDAP_COMPARE_TRUE ) {
|
||||||
sres = send_search_entry( be, conn, op, entry,
|
sres = send_search_entry( be, conn, op, entry,
|
||||||
attrs, attrsonly, NULL );
|
attrs, attrsonly, NULL );
|
||||||
if ( sres == -1 ) {
|
switch ( sres ) {
|
||||||
|
case 0:
|
||||||
|
nentries++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
|
||||||
"connection lost\n", 0, 0, 0 );
|
"connection lost\n", 0, 0, 0 );
|
||||||
|
goto end_of_search;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* FIXME: send_search_entry failed;
|
||||||
|
* better stop
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
nentries += !sres;
|
|
||||||
}
|
}
|
||||||
entry_free( entry );
|
entry_free( entry );
|
||||||
|
|
||||||
if ( slimit != -1 && nentries > slimit ) {
|
if ( slimit != -1 && nentries >= slimit ) {
|
||||||
send_search_result( conn, op, LDAP_SIZELIMIT_EXCEEDED,
|
send_search_result( conn, op, LDAP_SIZELIMIT_EXCEEDED,
|
||||||
NULL, NULL, v2refs, NULL, nentries );
|
NULL, NULL, v2refs, NULL, nentries );
|
||||||
break;
|
goto end_of_search;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
end_of_search:;
|
||||||
|
|
||||||
if ( nentries > 0 ) {
|
if ( nentries > 0 ) {
|
||||||
send_search_result( conn, op,
|
send_search_result( conn, op,
|
||||||
|
|
@ -977,9 +1078,6 @@ backsql_search(
|
||||||
}
|
}
|
||||||
|
|
||||||
done:;
|
done:;
|
||||||
for ( eid = srch_info.id_list; eid != NULL;
|
|
||||||
eid = backsql_free_entryID( eid, 1 ) );
|
|
||||||
|
|
||||||
ch_free( srch_info.attrs );
|
ch_free( srch_info.attrs );
|
||||||
|
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_search()\n", 0, 0, 0 );
|
||||||
|
|
|
||||||
|
|
@ -64,16 +64,16 @@ backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout )
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>_SQLPrepare()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "==>_SQLPrepare()\n", 0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
SQLGetInfo( dbh, SQL_DRIVER_NAME, drv_name, sizeof( drv_name ), &len );
|
SQLGetInfo( dbh, SQL_DRIVER_NAME, drv_name, sizeof( drv_name ), &len );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "_SQLPrepare(): driver name='%s'\n",
|
Debug( LDAP_DEBUG_TRACE, "_SQLPrepare(): driver name='%s'\n",
|
||||||
drv_name, 0, 0 );
|
drv_name, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
ldap_pvt_str2upper( drv_name );
|
ldap_pvt_str2upper( drv_name );
|
||||||
if ( !strncmp( drv_name, "SQLSRV32.DLL", sizeof( drv_name ) ) ) {
|
if ( !strncmp( drv_name, "SQLSRV32.DLL", sizeof( drv_name ) ) ) {
|
||||||
|
|
@ -107,10 +107,10 @@ backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==_SQLPrepare() calling SQLPrepare()\n",
|
Debug( LDAP_DEBUG_TRACE, "<==_SQLPrepare() calling SQLPrepare()\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return SQLPrepare( *sth, query, SQL_NTS );
|
return SQLPrepare( *sth, query, SQL_NTS );
|
||||||
}
|
}
|
||||||
|
|
@ -153,23 +153,23 @@ backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
|
||||||
return SQL_ERROR;
|
return SQL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==> backsql_BindRowAsStrings()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "==> backsql_BindRowAsStrings()\n", 0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
rc = SQLNumResultCols( sth, &row->ncols );
|
rc = SQLNumResultCols( sth, &row->ncols );
|
||||||
if ( rc != SQL_SUCCESS ) {
|
if ( rc != SQL_SUCCESS ) {
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "_SQLBindRowAsStrings(): "
|
Debug( LDAP_DEBUG_TRACE, "_SQLBindRowAsStrings(): "
|
||||||
"SQLNumResultCols() failed:\n", 0, 0, 0 );
|
"SQLNumResultCols() failed:\n", 0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );
|
backsql_PrintErrors( SQL_NULL_HENV, SQL_NULL_HDBC, sth, rc );
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
|
Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
|
||||||
"ncols=%d\n", (int)row->ncols, 0, 0 );
|
"ncols=%d\n", (int)row->ncols, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
row->col_names = (BerVarray)ch_calloc( row->ncols + 1,
|
row->col_names = (BerVarray)ch_calloc( row->ncols + 1,
|
||||||
sizeof( struct berval ) );
|
sizeof( struct berval ) );
|
||||||
|
|
@ -185,11 +185,11 @@ backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
|
||||||
&name_len, &col_type,
|
&name_len, &col_type,
|
||||||
&col_prec, &col_scale, &col_null );
|
&col_prec, &col_scale, &col_null );
|
||||||
ber_str2bv( colname, 0, 1, &row->col_names[ i - 1 ] );
|
ber_str2bv( colname, 0, 1, &row->col_names[ i - 1 ] );
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
|
Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
|
||||||
"col_name=%s, col_prec[%d]=%d\n",
|
"col_name=%s, col_prec[%d]=%d\n",
|
||||||
colname, (int)i, (int)col_prec );
|
colname, (int)i, (int)col_prec );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
if ( col_type == SQL_LONGVARCHAR
|
if ( col_type == SQL_LONGVARCHAR
|
||||||
|| col_type == SQL_LONGVARBINARY) {
|
|| col_type == SQL_LONGVARBINARY) {
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -229,9 +229,10 @@ backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
|
||||||
row->col_names[ i - 1 ].bv_len = 0;
|
row->col_names[ i - 1 ].bv_len = 0;
|
||||||
row->cols[ i - 1 ] = NULL;
|
row->cols[ i - 1 ] = NULL;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "<== backsql_BindRowAsStrings()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<== backsql_BindRowAsStrings()\n", 0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
@ -305,10 +306,11 @@ int
|
||||||
backsql_free_db_env( backsql_info *si )
|
backsql_free_db_env( backsql_info *si )
|
||||||
{
|
{
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_env()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_free_db_env()\n", 0, 0, 0 );
|
||||||
#if 0
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "free_db_env(): delete AVL tree here!!!\n",
|
Debug( LDAP_DEBUG_TRACE, "free_db_env(): delete AVL tree here!!!\n",
|
||||||
0, 0, 0 );
|
0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* stop, if frontend waits for all threads to shutdown
|
* stop, if frontend waits for all threads to shutdown
|
||||||
|
|
@ -366,7 +368,8 @@ backsql_open_db_conn( backsql_info *si, int ldap_cid, backsql_db_conn **pdbc )
|
||||||
* See if this connection is to TimesTen. If it is,
|
* See if this connection is to TimesTen. If it is,
|
||||||
* remember that fact for later use.
|
* remember that fact for later use.
|
||||||
*/
|
*/
|
||||||
si->isTimesTen = 0; /* Assume until proven otherwise */
|
/* Assume until proven otherwise */
|
||||||
|
si->bsql_flags &= ~BSQLF_USE_REVERSE_DN;
|
||||||
DBMSName[ 0 ] = '\0';
|
DBMSName[ 0 ] = '\0';
|
||||||
rc = SQLGetInfo( dbc->dbh, SQL_DBMS_NAME, (PTR)&DBMSName,
|
rc = SQLGetInfo( dbc->dbh, SQL_DBMS_NAME, (PTR)&DBMSName,
|
||||||
sizeof( DBMSName ), NULL );
|
sizeof( DBMSName ), NULL );
|
||||||
|
|
@ -375,7 +378,7 @@ backsql_open_db_conn( backsql_info *si, int ldap_cid, backsql_db_conn **pdbc )
|
||||||
strcmp( DBMSName, "Front-Tier" ) == 0 ) {
|
strcmp( DBMSName, "Front-Tier" ) == 0 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
|
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
|
||||||
"TimesTen database!\n", 0, 0, 0 );
|
"TimesTen database!\n", 0, 0, 0 );
|
||||||
si->isTimesTen = 1;
|
si->bsql_flags |= BSQLF_USE_REVERSE_DN;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
|
Debug( LDAP_DEBUG_TRACE, "backsql_open_db_conn: "
|
||||||
|
|
@ -454,11 +457,12 @@ backsql_get_db_conn( Backend *be, Connection *ldapc, SQLHDBC *dbh )
|
||||||
}
|
}
|
||||||
|
|
||||||
ldap_pvt_thread_mutex_lock( &si->schema_mutex );
|
ldap_pvt_thread_mutex_lock( &si->schema_mutex );
|
||||||
if ( !si->schema_loaded ) {
|
if ( !BACKSQL_SCHEMA_LOADED( si ) ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_get_db_conn(): "
|
||||||
"first call -- reading schema map\n", 0, 0, 0 );
|
"first call -- reading schema map\n", 0, 0, 0 );
|
||||||
rc = backsql_load_schema_map( si, dbc->dbh );
|
rc = backsql_load_schema_map( si, dbc->dbh );
|
||||||
if ( rc != LDAP_SUCCESS ) {
|
if ( rc != LDAP_SUCCESS ) {
|
||||||
|
ldap_pvt_thread_mutex_unlock( &si->schema_mutex );
|
||||||
backsql_free_db_conn( be, ldapc );
|
backsql_free_db_conn( be, ldapc );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,17 @@
|
||||||
#include "schema-map.h"
|
#include "schema-map.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#define BACKSQL_MAX(a,b) ((a)>(b)?(a):(b))
|
||||||
|
#define BACKSQL_MIN(a,b) ((a)<(b)?(a):(b))
|
||||||
|
|
||||||
|
#define BACKSQL_STR_GROW 256
|
||||||
|
|
||||||
char backsql_def_oc_query[] =
|
char backsql_def_oc_query[] =
|
||||||
"SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return "
|
"SELECT id,name,keytbl,keycol,create_proc,delete_proc,expect_return "
|
||||||
"FROM ldap_oc_mappings";
|
"FROM ldap_oc_mappings";
|
||||||
|
char backsql_def_needs_select_oc_query[] =
|
||||||
|
"SELECT id,name,keytbl,keycol,create_proc,create_keyval,delete_proc,"
|
||||||
|
"expect_return FROM ldap_oc_mappings";
|
||||||
char backsql_def_at_query[] =
|
char backsql_def_at_query[] =
|
||||||
"SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,"
|
"SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,"
|
||||||
"param_order,expect_return,sel_expr_u FROM ldap_attr_mappings "
|
"param_order,expect_return,sel_expr_u FROM ldap_attr_mappings "
|
||||||
|
|
@ -38,34 +45,29 @@ char backsql_def_insentry_query[] =
|
||||||
char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
|
char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
|
||||||
char backsql_def_upper_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 ";
|
char backsql_id_query[] = "SELECT id,keyval,oc_map_id FROM ldap_entries WHERE ";
|
||||||
|
/* better ?||? or cast(?||? as varchar) */
|
||||||
|
char backsql_def_concat_func[] = "CONCAT(?,?)";
|
||||||
|
|
||||||
/* TimesTen */
|
/* TimesTen */
|
||||||
char backsql_check_dn_ru_query[] = "SELECT dn_ru from ldap_entries";
|
char backsql_check_dn_ru_query[] = "SELECT dn_ru from ldap_entries";
|
||||||
|
|
||||||
/*
|
|
||||||
* Frequently used constants
|
|
||||||
*/
|
|
||||||
struct berval
|
|
||||||
bv_n_objectclass = BER_BVC("objectclass"),
|
|
||||||
bv_n_0_10 = BER_BVC("0.10");
|
|
||||||
|
|
||||||
struct berval *
|
struct berval *
|
||||||
backsql_strcat( struct berval *dest, int *buflen, ... )
|
backsql_strcat( struct berval *dest, ber_len_t *buflen, ... )
|
||||||
{
|
{
|
||||||
va_list strs;
|
va_list strs;
|
||||||
int cdlen, cslen, grow;
|
ber_len_t cdlen, cslen, grow;
|
||||||
char *cstr;
|
char *cstr;
|
||||||
|
|
||||||
assert( dest );
|
assert( dest );
|
||||||
assert( dest->bv_val == NULL
|
assert( dest->bv_val == NULL
|
||||||
|| dest->bv_len == strlen( dest->bv_val ) );
|
|| dest->bv_len == strlen( dest->bv_val ) );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" );
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_strcat()\n" );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
va_start( strs, buflen );
|
va_start( strs, buflen );
|
||||||
if ( dest->bv_val == NULL || *buflen <= 0 ) {
|
if ( dest->bv_val == NULL || *buflen == 0 ) {
|
||||||
dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
|
dest->bv_val = (char *)ch_calloc( BACKSQL_STR_GROW,
|
||||||
sizeof( char ) );
|
sizeof( char ) );
|
||||||
dest->bv_len = 0;
|
dest->bv_len = 0;
|
||||||
|
|
@ -78,12 +80,13 @@ backsql_strcat( struct berval *dest, int *buflen, ... )
|
||||||
if ( *buflen - cdlen <= cslen ) {
|
if ( *buflen - cdlen <= cslen ) {
|
||||||
char *tmp_dest;
|
char *tmp_dest;
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
|
||||||
"buflen=%d, cdlen=%d, cslen=%d "
|
"buflen=%d, cdlen=%d, cslen=%d "
|
||||||
"-- reallocating dest\n",
|
"-- reallocating dest\n",
|
||||||
*buflen, cdlen + 1, cslen );
|
*buflen, cdlen + 1, cslen );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
tmp_dest = (char *)ch_realloc( dest->bv_val,
|
tmp_dest = (char *)ch_realloc( dest->bv_val,
|
||||||
( *buflen ) + grow * sizeof( char ) );
|
( *buflen ) + grow * sizeof( char ) );
|
||||||
if ( tmp_dest == NULL ) {
|
if ( tmp_dest == NULL ) {
|
||||||
|
|
@ -94,20 +97,131 @@ backsql_strcat( struct berval *dest, int *buflen, ... )
|
||||||
}
|
}
|
||||||
dest->bv_val = tmp_dest;
|
dest->bv_val = tmp_dest;
|
||||||
*buflen += grow;
|
*buflen += grow;
|
||||||
#if 0
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_strcat(): "
|
||||||
"new buflen=%d, dest=%p\n", *buflen, dest, 0 );
|
"new buflen=%d, dest=%p\n", *buflen, dest, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
}
|
}
|
||||||
AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
|
AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
|
||||||
cdlen += cslen;
|
cdlen += cslen;
|
||||||
}
|
}
|
||||||
va_end( strs );
|
va_end( strs );
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest='%s')\n",
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_strcat() (dest='%s')\n",
|
||||||
dest, 0, 0 );
|
dest, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
|
dest->bv_len = cdlen;
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct berval *
|
||||||
|
backsql_strfcat( struct berval *dest, ber_len_t *buflen, const char *fmt, ... )
|
||||||
|
{
|
||||||
|
va_list strs;
|
||||||
|
ber_len_t cdlen;
|
||||||
|
|
||||||
|
assert( dest );
|
||||||
|
assert( buflen );
|
||||||
|
assert( fmt );
|
||||||
|
assert( *buflen == 0 || *buflen > dest->bv_len );
|
||||||
|
assert( dest->bv_val == NULL
|
||||||
|
|| dest->bv_len == strlen( dest->bv_val ) );
|
||||||
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_strfcat()\n" );
|
||||||
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
|
va_start( strs, fmt );
|
||||||
|
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;
|
||||||
|
for ( ; fmt[0]; fmt++ ) {
|
||||||
|
ber_len_t cslen, grow;
|
||||||
|
char *cstr, cc[ 2 ] = { '\0', '\0' };
|
||||||
|
struct berval *cbv;
|
||||||
|
|
||||||
|
switch ( fmt[ 0 ] ) {
|
||||||
|
|
||||||
|
/* berval */
|
||||||
|
case 'b':
|
||||||
|
cbv = va_arg( strs, struct berval * );
|
||||||
|
cstr = cbv->bv_val;
|
||||||
|
cslen = cbv->bv_len;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* length + string */
|
||||||
|
case 'l':
|
||||||
|
cslen = va_arg( strs, ber_len_t );
|
||||||
|
cstr = va_arg( strs, char * );
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* string */
|
||||||
|
case 's':
|
||||||
|
cstr = va_arg( strs, char * );
|
||||||
|
cslen = strlen( cstr );
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* char */
|
||||||
|
case 'c':
|
||||||
|
/*
|
||||||
|
* `char' is promoted to `int' when passed through `...'
|
||||||
|
*/
|
||||||
|
cc[0] = va_arg( strs, int );
|
||||||
|
cstr = cc;
|
||||||
|
cslen = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
grow = BACKSQL_MAX( BACKSQL_STR_GROW, cslen );
|
||||||
|
if ( *buflen - cdlen <= cslen ) {
|
||||||
|
char *tmp_dest;
|
||||||
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_strfcat(): "
|
||||||
|
"buflen=%d, cdlen=%d, cslen=%d "
|
||||||
|
"-- reallocating dest\n",
|
||||||
|
*buflen, cdlen + 1, cslen );
|
||||||
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
|
tmp_dest = (char *)ch_realloc( dest->bv_val,
|
||||||
|
( *buflen ) + grow * sizeof( char ) );
|
||||||
|
if ( tmp_dest == NULL ) {
|
||||||
|
Debug( LDAP_DEBUG_ANY, "backsql_strfcat(): "
|
||||||
|
"could not reallocate string buffer.\n",
|
||||||
|
0, 0, 0 );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dest->bv_val = tmp_dest;
|
||||||
|
*buflen += grow * sizeof( char );
|
||||||
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "backsql_strfcat(): "
|
||||||
|
"new buflen=%d, dest=%p\n", *buflen, dest, 0 );
|
||||||
|
#endif /* BACKSQL_TRACE */
|
||||||
|
}
|
||||||
|
|
||||||
|
AC_MEMCPY( dest->bv_val + cdlen, cstr, cslen + 1 );
|
||||||
|
cdlen += cslen;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end( strs );
|
||||||
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_strfcat() (dest='%s')\n",
|
||||||
|
dest, 0, 0 );
|
||||||
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
dest->bv_len = cdlen;
|
dest->bv_len = cdlen;
|
||||||
|
|
||||||
|
|
@ -120,17 +234,15 @@ backsql_entry_addattr(
|
||||||
struct berval *at_name,
|
struct berval *at_name,
|
||||||
struct berval *at_val )
|
struct berval *at_val )
|
||||||
{
|
{
|
||||||
struct berval add_val[ 2 ];
|
|
||||||
AttributeDescription *ad;
|
AttributeDescription *ad;
|
||||||
int rc;
|
int rc;
|
||||||
const char *text;
|
const char *text;
|
||||||
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
|
||||||
"at_name='%s', at_val='%s'\n",
|
"at_name='%s', at_val='%s'\n",
|
||||||
at_name->bv_val, at_val->bv_val, 0 );
|
at_name->bv_val, at_val->bv_val, 0 );
|
||||||
add_val[ 0 ] = *at_val;
|
#endif /* BACKSQL_TRACE */
|
||||||
add_val[ 1 ].bv_val = NULL;
|
|
||||||
add_val[ 1 ].bv_len = 0;
|
|
||||||
|
|
||||||
ad = NULL;
|
ad = NULL;
|
||||||
rc = slap_bv2ad( at_name, &ad, &text );
|
rc = slap_bv2ad( at_name, &ad, &text );
|
||||||
|
|
@ -141,7 +253,7 @@ backsql_entry_addattr(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = attr_merge( e, ad, add_val );
|
rc = attr_merge_one( e, ad, at_val );
|
||||||
|
|
||||||
if ( rc != 0 ) {
|
if ( rc != 0 ) {
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_entry_addattr(): "
|
||||||
|
|
@ -150,7 +262,10 @@ backsql_entry_addattr(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_query_addattr()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_query_addattr()\n", 0, 0, 0 );
|
||||||
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,7 +274,10 @@ backsql_get_table_spec( char **p )
|
||||||
{
|
{
|
||||||
char *s, *q;
|
char *s, *q;
|
||||||
struct berval res = { 0, NULL };
|
struct berval res = { 0, NULL };
|
||||||
int res_len = 0;
|
ber_len_t res_len = 0;
|
||||||
|
|
||||||
|
assert( p );
|
||||||
|
assert( *p );
|
||||||
|
|
||||||
s = *p;
|
s = *p;
|
||||||
while ( **p && **p != ',' ) {
|
while ( **p && **p != ',' ) {
|
||||||
|
|
@ -188,49 +306,57 @@ backsql_get_table_spec( char **p )
|
||||||
s = q;
|
s = q;
|
||||||
BACKSQL_NEXT_WORD;
|
BACKSQL_NEXT_WORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
backsql_strcat( &res, &res_len, " AS ", s, NULL );
|
backsql_strcat( &res, &res_len, " AS ", s, NULL );
|
||||||
/* oracle doesn't understand AS :( */
|
/* oracle doesn't understand AS :( */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* table alias */
|
/* table alias */
|
||||||
backsql_strcat( &res, &res_len, " ", s, NULL);
|
backsql_strfcat( &res, &res_len, "cs", ' ', s );
|
||||||
|
|
||||||
return res.bv_val;
|
return res.bv_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
backsql_merge_from_clause( char **dest_from, int *dest_len, char *src_from )
|
backsql_merge_from_clause(
|
||||||
|
struct berval *dest_from,
|
||||||
|
ber_len_t *dest_len,
|
||||||
|
struct berval *src_from )
|
||||||
{
|
{
|
||||||
char *s, *p, *srcc, *pos, e;
|
char *s, *p, *srcc, *pos, e;
|
||||||
struct berval res = { 0 , NULL };
|
struct berval res = { 0 , NULL };
|
||||||
|
|
||||||
#if 0
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): "
|
Debug( LDAP_DEBUG_TRACE, "==>backsql_merge_from_clause(): "
|
||||||
"dest_from='%s',src_from='%s'\n",
|
"dest_from='%s',src_from='%s'\n",
|
||||||
dest_from, src_from, 0 );
|
dest_from ? dest_from->bv_val : "<NULL>", src_from, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
srcc = ch_strdup( src_from );
|
|
||||||
|
srcc = ch_strdup( src_from->bv_val );
|
||||||
p = srcc;
|
p = srcc;
|
||||||
|
|
||||||
if ( *dest_from != NULL ) {
|
if ( dest_from != NULL ) {
|
||||||
res.bv_val = *dest_from;
|
res = *dest_from;
|
||||||
res.bv_len = strlen( *dest_from );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ( *p ) {
|
while ( *p ) {
|
||||||
s = backsql_get_table_spec( &p );
|
s = backsql_get_table_spec( &p );
|
||||||
#if 0
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "backsql_merge_from_clause(): "
|
Debug( LDAP_DEBUG_TRACE, "backsql_merge_from_clause(): "
|
||||||
"p='%s' s='%s'\n", p, s, 0 );
|
"p='%s' s='%s'\n", p, s, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
if ( res.bv_val == NULL ) {
|
if ( res.bv_val == NULL ) {
|
||||||
backsql_strcat( &res, dest_len, s, NULL );
|
backsql_strcat( &res, dest_len, s, NULL );
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
pos = strstr( res.bv_val, s );
|
pos = strstr( res.bv_val, s );
|
||||||
if ( pos == NULL ) {
|
if ( pos == NULL ) {
|
||||||
backsql_strcat( &res, dest_len, ",", s, NULL );
|
backsql_strfcat( &res, dest_len, "cs", ',', s );
|
||||||
} else if ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) {
|
} else if ( ( e = pos[ strlen( s ) ] ) != '\0' && e != ',' ) {
|
||||||
backsql_strcat( &res, dest_len, ",", s, NULL );
|
backsql_strfcat( &res, dest_len, "cs", ',', s );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -238,14 +364,115 @@ backsql_merge_from_clause( char **dest_from, int *dest_len, char *src_from )
|
||||||
ch_free( s );
|
ch_free( s );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
|
#ifdef BACKSQL_TRACE
|
||||||
Debug( LDAP_DEBUG_TRACE, "<==backsql_merge_from_clause()\n", 0, 0, 0 );
|
Debug( LDAP_DEBUG_TRACE, "<==backsql_merge_from_clause()\n", 0, 0, 0 );
|
||||||
#endif
|
#endif /* BACKSQL_TRACE */
|
||||||
|
|
||||||
free( srcc );
|
free( srcc );
|
||||||
*dest_from = res.bv_val;
|
*dest_from = res;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* splits a pattern in components separated by '?'
|
||||||
|
* (double ?? are turned into single ? and left in the string)
|
||||||
|
* expected contains the number of expected occurrences of '?'
|
||||||
|
* (a negative value means parse as many as possible)
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
backsql_split_pattern(
|
||||||
|
const char *_pattern,
|
||||||
|
BerVarray *split_pattern,
|
||||||
|
int expected )
|
||||||
|
{
|
||||||
|
char *pattern, *start, *end;
|
||||||
|
struct berval bv;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
#define SPLIT_CHAR '?'
|
||||||
|
|
||||||
|
assert( _pattern );
|
||||||
|
assert( split_pattern );
|
||||||
|
|
||||||
|
pattern = ch_strdup( _pattern );
|
||||||
|
|
||||||
|
start = pattern;
|
||||||
|
end = strchr( start, SPLIT_CHAR );
|
||||||
|
for ( ; start; expected-- ) {
|
||||||
|
char *real_end = end;
|
||||||
|
ber_len_t real_len;
|
||||||
|
|
||||||
|
if ( real_end == NULL ) {
|
||||||
|
real_end = start + strlen( start );
|
||||||
|
|
||||||
|
} else if ( real_end[ 1 ] == SPLIT_CHAR ) {
|
||||||
|
expected++;
|
||||||
|
AC_MEMCPY( real_end, real_end + 1, strlen( real_end ) );
|
||||||
|
end = strchr( real_end + 1, SPLIT_CHAR );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
real_len = real_end - start;
|
||||||
|
if ( real_len == 0 ) {
|
||||||
|
ber_str2bv( "", 0, 1, &bv );
|
||||||
|
} else {
|
||||||
|
ber_str2bv( start, real_len, 1, &bv );
|
||||||
|
}
|
||||||
|
|
||||||
|
ber_bvarray_add( split_pattern, &bv );
|
||||||
|
|
||||||
|
if ( expected == 0 ) {
|
||||||
|
if ( end != NULL ) {
|
||||||
|
rc = -1;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( end != NULL ) {
|
||||||
|
start = end + 1;
|
||||||
|
end = strchr( start, SPLIT_CHAR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:;
|
||||||
|
|
||||||
|
ch_free( pattern );
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
backsql_prepare_pattern(
|
||||||
|
BerVarray split_pattern,
|
||||||
|
BerVarray values,
|
||||||
|
struct berval *res )
|
||||||
|
{
|
||||||
|
ber_len_t len = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
res->bv_val = NULL;
|
||||||
|
res->bv_len = 0;
|
||||||
|
|
||||||
|
for ( i = 0; values[i].bv_val; i++ ) {
|
||||||
|
if ( split_pattern[i].bv_val == NULL ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
backsql_strfcat( res, &len, "b", &split_pattern[ i ] );
|
||||||
|
backsql_strfcat( res, &len, "b", &values[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( split_pattern[ i ].bv_val == NULL ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
backsql_strfcat( res, &len, "b", &split_pattern[ i ] );
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* SLAPD_SQL */
|
#endif /* SLAPD_SQL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,21 +14,16 @@
|
||||||
#include "entry-id.h"
|
#include "entry-id.h"
|
||||||
#include "schema-map.h"
|
#include "schema-map.h"
|
||||||
|
|
||||||
#define BACKSQL_MAX(a,b) ((a)>(b)?(a):(b))
|
#define BACKSQL_CONCAT
|
||||||
#define BACKSQL_MIN(a,b) ((a)<(b)?(a):(b))
|
|
||||||
|
|
||||||
#define BACKSQL_STR_GROW 64
|
struct berval * backsql_strcat( struct berval *dest, ber_len_t *buflen, ... );
|
||||||
|
struct berval * backsql_strfcat( struct berval *dest, ber_len_t *buflen,
|
||||||
extern struct berval
|
const char *fmt, ... );
|
||||||
bv_n_objectclass,
|
|
||||||
bv_n_0_10;
|
|
||||||
|
|
||||||
struct berval *backsql_strcat( struct berval *dest, int *buflen, ... );
|
|
||||||
|
|
||||||
int backsql_entry_addattr( Entry *e, struct berval *at_name,
|
int backsql_entry_addattr( Entry *e, struct berval *at_name,
|
||||||
struct berval *at_val );
|
struct berval *at_val );
|
||||||
|
|
||||||
typedef struct __backsql_srch_info {
|
typedef struct backsql_srch_info {
|
||||||
struct berval *base_dn;
|
struct berval *base_dn;
|
||||||
int scope;
|
int scope;
|
||||||
Filter *filter;
|
Filter *filter;
|
||||||
|
|
@ -40,16 +35,18 @@ typedef struct __backsql_srch_info {
|
||||||
backsql_info *bi;
|
backsql_info *bi;
|
||||||
backsql_oc_map_rec *oc;
|
backsql_oc_map_rec *oc;
|
||||||
struct berval sel, from, join_where, flt_where;
|
struct berval sel, from, join_where, flt_where;
|
||||||
int sel_len, from_len, jwhere_len, fwhere_len;
|
ber_len_t sel_len, from_len, jwhere_len, fwhere_len;
|
||||||
SQLHDBC dbh;
|
SQLHDBC dbh;
|
||||||
int status;
|
int status;
|
||||||
Backend *be;
|
Backend *be;
|
||||||
Connection *conn;
|
Connection *conn;
|
||||||
Operation *op;
|
Operation *op;
|
||||||
AttributeName *attrs;
|
AttributeName *attrs;
|
||||||
|
int attr_flags;
|
||||||
|
#define BSQL_SF_ALL_OPER 0x0001
|
||||||
Entry *e;
|
Entry *e;
|
||||||
/* 1 if the db is TimesTen; 0 if it's not */
|
/* 1 if the db is TimesTen; 0 if it's not */
|
||||||
int isTimesTen;
|
int use_reverse_dn;
|
||||||
} backsql_srch_info;
|
} backsql_srch_info;
|
||||||
|
|
||||||
int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
|
int backsql_process_filter( backsql_srch_info *bsi, Filter *f );
|
||||||
|
|
@ -63,18 +60,24 @@ Entry *backsql_id2entry( backsql_srch_info *bsi, Entry *e,
|
||||||
|
|
||||||
extern char
|
extern char
|
||||||
backsql_def_oc_query[],
|
backsql_def_oc_query[],
|
||||||
|
backsql_def_needs_select_oc_query[],
|
||||||
backsql_def_at_query[],
|
backsql_def_at_query[],
|
||||||
backsql_def_delentry_query[],
|
backsql_def_delentry_query[],
|
||||||
backsql_def_insentry_query[],
|
backsql_def_insentry_query[],
|
||||||
backsql_def_subtree_cond[],
|
backsql_def_subtree_cond[],
|
||||||
backsql_def_upper_subtree_cond[],
|
backsql_def_upper_subtree_cond[],
|
||||||
backsql_id_query[];
|
backsql_id_query[],
|
||||||
|
backsql_def_concat_func[];
|
||||||
extern char
|
extern char
|
||||||
backsql_check_dn_ru_query[];
|
backsql_check_dn_ru_query[];
|
||||||
|
|
||||||
int backsql_merge_from_clause( char **dest_from, int *dest_len,
|
int backsql_merge_from_clause( struct berval *dest_from, ber_len_t *dest_len,
|
||||||
char *src_from );
|
struct berval *src_from );
|
||||||
|
|
||||||
|
int backsql_split_pattern( const char *pattern, BerVarray *split_pattern,
|
||||||
|
int expected );
|
||||||
|
int backsql_prepare_pattern( BerVarray split_pattern, BerVarray values,
|
||||||
|
struct berval *res );
|
||||||
|
|
||||||
#endif /* __BACKSQL_UTIL_H__ */
|
#endif /* __BACKSQL_UTIL_H__ */
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue