minor naming cleanup; improvements to DN mapping layer; major docs update

This commit is contained in:
Pierangelo Masarati 2005-01-05 16:23:00 +00:00
parent c1e4eeb23b
commit f5936eb7fc
17 changed files with 296 additions and 166 deletions

View file

@ -41,90 +41,163 @@ for SQL dialects RDBMSes may use, so it may be used for integration
and distribution of data on different RDBMSes, OSes, hosts etc., in
other words, in highly heterogeneous environment.
.LP
This backend is experimental.
This backend is \fIexperimental\fP.
.SH CONFIGURATION
These
.B slapd.conf
options apply to the SQL backend database.
That is, they must follow a "database sql" line and come before any
options apply to the SQL backend database, which means that
they must follow a "database sql" line and come before any
subsequent "backend" or "database" lines.
Other database options are described in the
Other database options not specific to this backend are described
in the
.BR slapd.conf (5)
manual page.
.SH DATA SOURCE CONFIGURATION
.TP
.B dbname <datasource name>
The name of the ODBC datasource to use.
.LP
.B dbhost <hostname>
.br
.B dbuser <username>
.br
.B dbpasswd <password>
.br
.B dbuser <username>
.RS
These three options are generally unneeded, because this information is already
taken from the datasource.
Use them if you need to override datasource settings.
The three above options are generally unneeded, because this information
is taken from the datasource specified by the
.B dbname
directive.
They allow to override datasource settings.
Also, several RDBMS' drivers tend to require explicit passing of user/password,
even if those are given in datasource (Note:
.B dbhost
is currently ignored).
.RE
.SH SCOPING CONFIGURATION
These options specify SQL query templates for scoping searches.
.TP
.B subtree_cond <SQL expression>
Specifies a where-clause template used to form a subtree search condition
(dn=".*<dn>").
(dn="(.+,)?<dn>$").
It may differ from one SQL dialect to another (see samples).
By default, it is constructed based on the knowledge about
how to normalize DN values (e.g.
\fB"<upper_func>(ldap_entries.dn) LIKE CONCAT('%',?)"\fP).
.TP
.B children_cond <SQL expression>
Specifies a where-clause template used to form a children search condition
(dn="\.+,<dn>").
(dn=".+,<dn>$").
It may differ from one SQL dialect to another (see samples).
.TP
.B oc_query <SQL expression>
The default is
.B "SELECT id, name, keytbl, keycol, create_proc, delete_proc, expect_return FROM ldap_oc_mappings"
.TP
.B at_query <SQL expression>
The default is
.B "SELECT name, sel_expr, from_tbls, join_where, add_proc, delete_proc, param_order, expect_return FROM ldap_attr_mappings WHERE oc_map_id=?"
.TP
.B insentry_query <SQL expression>
The default is
.B "INSERT INTO ldap_entries (dn, oc_map_id, parent, keyval) VALUES (?, ?, ?, ?)"
.TP
.B delentry_query <SQL expression>
The default is
.B "DELETE FROM ldap_entries WHERE id=?"
By default, it is constructed based on the knowledge about
how to normalize DN values (e.g.
\fB"<upper_func>(ldap_entries.dn) LIKE CONCAT('%,',?)"\fP).
These four options specify SQL query templates for loading schema mapping
.TP
.B use_subtree_shortcut { NO | yes }
Do not use the subtree condition when the searchBase is the database
suffix, and the scope is subtree; rather collect all entries.
.RE
.SH STAMEMENT CONFIGURATION
These options specify SQL query templates for loading schema mapping
metainformation, adding and deleting entries to ldap_entries, etc.
All these and subtree_cond should have the given default values.
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.
Note that the parameter number and order must not be changed.
.TP
.B oc_query <SQL expression>
The query that is used to collect the objectClass mapping data
from table \fIldap_oc_mappings\fP; see "METAINFORMATION USED" for details.
The default is
\fB"SELECT id, name, keytbl, keycol, create_proc, delete_proc, expect_return
FROM ldap_oc_mappings"\fP.
.TP
.B at_query <SQL expression>
The query that is used to collect the attributeType mapping data
from table \fIldap_attr_mappings\fP; see "METAINFORMATION USED" for details.
The default is
\fB"SELECT name, sel_expr, from_tbls, join_where, add_proc, delete_proc,
param_order, expect_return FROM ldap_attr_mappings WHERE oc_map_id=?"\fP.
.TP
.B id_query <SQL expression>
The query that is used to map a DN to an entry
in table \fIldap_entries\fP; see "METAINFORMATION USED" for details.
The default is
\fB"SELECT id,keyval,oc_map_id,dn FROM ldap_entries WHERE <DN match expr>"\fP,
where \fB<DN match expr>\fP is constructed based on the knowledge about
how to normalize DN values (e.g. \fB"dn=?"\fP if no means to uppercase
strings are available; typically, \fB"<upper_func>(dn)=?"\fP
is used).
.TP
.B insentry_stmt <SQL expression>
The statement that is used to insert a new entry
in table \fIldap_entries\fP; see "METAINFORMATION USED" for details.
The default is
\fB"INSERT INTO ldap_entries (dn, oc_map_id, parent, keyval) VALUES
(?, ?, ?, ?)"\fP.
.TP
.B delentry_stmt <SQL expression>
The statement that is used to delete an existing entry
from table \fIldap_entries\fP; see "METAINFORMATION USED" for details.
The default is
\fB"DELETE FROM ldap_entries WHERE id=?"\fP.
.TP
.B delobjclasses_stmt <SQL expression>
The statement that is used to delete an existing entry's ID
from table \fIldap_objclasses\fP; see "METAINFORMATION USED" for details.
The default is
\fB""DELETE FROM ldap_entry_objclasses WHERE entry_id=?"\fP.
.TP
.B delreferrals_stmt <SQL expression>
The statement that is used to delete an existing entry's ID
from table \fIldap_referrals\fP; see "METAINFORMATION USED" for details.
The default is
\fB""DELETE FROM ldap_referrals WHERE entry_id=?"\fP.
.RE
.SH HELPER CONFIGURATION
.TP
.B upper_func <SQL function name>
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 case insensitive matching when the RDBMS is case sensitive.
It may differ from one SQL dialect to another (e.g. \fBUCASE\fP, \fBUPPER\fP
or whatever; see samples). By default, none is used, i.e. strings are not
uppercased, so matches may be case sensitive.
.TP
.B upper_needs_cast { NO | yes}
.B upper_needs_cast { NO | yes }
Set this directive to
.B yes
if
.B upper_func
needs an explicit cast when applied to literal strings. The form
needs an explicit cast when applied to literal strings.
A cast in 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.
is builtin in back-sql; see macro
.B BACKSQL_MAX_DN_LEN
(currently 255; note that slapd's builtin limit, in macro
.BR SLAP_LDAPDN_MAXLEN ,
is set to 8192).
This is \fIexperimental\fP and may change in future releases.
.TP
.B concat_pattern <pattern>
This statement defines the
.B pattern
to be used to concatenate strings. The
that is 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
@ -135,40 +208,34 @@ but an explicit cast may be required when operating on literal strings:
.BR "CAST(?||? AS VARCHAR(<length>))".
On some RDBMSes (IBM db2, MSSQL) the form
.B "?+?"
is known to work.
is known to work as well.
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.
This is \fIexperimental\fP and may change in future releases.
.TP
.B strcast_func <SQL function name>
Specifies the name of a function that converts a given value to a string
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.
This is \fIexperimental\fP and may change in future releases.
.TP
.B has_ldapinfo_dn_ru { NO | yes }
Explicitly inform the backend whether the SQL schema has dn_ru column
(dn in reverse uppercased form) or not.
Overrides automatic check (required by PostgreSQL/unixODBC).
This is
.B experimental
and may change in future releases.
Explicitly inform the backend whether the dn_ru column
(DN in reverse uppercased form) is present in table \fIldap_entries\fP.
Overrides automatic check (this is required, ofr instance,
by PostgreSQL/unixODBC).
This is \fIexperimental\fP and may change in future releases.
.TP
.B fail_if_no_mapping { NO | yes }
When set to
.B yes
it forces
.I attribute
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.
it forces \fIattribute\fP 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.
It has no impact on objectClass mapping, i.e. if the
.I structuralObjectClass
of an entry cannot be mapped to SQL by looking up its name
@ -177,9 +244,7 @@ in ldap_oc_mappings, an
operation will fail regardless of the
.B fail_if_no_mapping
switch; see section "METAINFORMATION USED" for details.
This is
.B experimental
and may change in future releases.
This is \fIexperimental\fP and may change in future releases.
.TP
.B allow_orphans { NO | yes }
@ -196,21 +261,31 @@ Instructs the database to create and manage an in-memory baseObject
entry instead of looking for one in the RDBMS.
If the (optional)
.B filename
argument is given, the entry is read from file
.B filename
in
argument is given, the entry is read from that file in
.BR LDIF (5)
form.
This is particularly useful when
.B ldap_entries
form; otherwise, an entry with objectClass \fBextensibleObject\fP
is created based on the contents of the RDN of the \fIbaseObject\fP.
This is particularly useful when \fIldap_entries\fP
information is stored in a view rather than in a table, and
.B union
is not supported for views, so that the view can only specify
one rule to compute the entry structure for one objectClass.
This topic is discussed further in section "METAINFORMATION USED".
This is
.B experimental
and may change in future releases.
This is \fIexperimental\fP and may change in future releases.
.TP
.B create_needs_select { NO | yes }
Instructs the database whether entry creation in table \fIldap_entries\fP
needs a subsequent select to collect the automatically assigned ID,
instead of being returned by a stored procedure.
.TP
.B sqllayer <name> [...]
Loads the layer \fB<name>\fP onto a stack of helpers that are used
to map DNs from LDAP to SQL representation and vice-versa.
Subsequent args are passed to the layer configuration routine.
This is \fIhighly experimental\fP and should be used with extreme care.
The API of the layers is not frozen yet, so it is unpublished.
.SH METAINFORMATION USED
.LP
@ -280,7 +355,7 @@ for telephoneNumber we can use:
.LP
.nf
SELECT phones.phone AS telephoneNumber FROM persons,phones
WHERE persons.id=phones.pers_id AND persons.id=?
WHERE persons.id=phones.pers_id AND persons.id=?
.fi
.LP
If we wanted to service LDAP requests with filters like
@ -288,11 +363,15 @@ If we wanted to service LDAP requests with filters like
.LP
.nf
SELECT ... FROM persons,phones
WHERE persons.id=phones.pers_id
AND persons.id=?
AND phones.phone like '123%'
WHERE persons.id=phones.pers_id
AND persons.id=?
AND phones.phone like '%1%2%3%'
.fi
.LP
(note how the telephoneNumber match is expanded in multiple wildcards
to account for interspersed ininfluential chars like spaces, dashes
and so; this occurs by design because telephoneNumber is defined after
a specially recognized syntax).
So, if we had information about what tables contain values for each
attribute, how to join these tables and arrange these values, we could
try to automatically generate such statements, and translate search
@ -402,13 +481,15 @@ like this (by Robin Elfrink):
CREATE VIEW ldap_entries (id, dn, oc_map_id, parent, keyval)
AS
SELECT 0, UPPER('o=MyCompany,c=NL'),
3, 0, 'baseObject' FROM unixusers WHERE userid='root' UNION
3, 0, 'baseObject' FROM unixusers WHERE userid='root'
UNION
SELECT (1000000000+userid),
UPPER(CONCAT(CONCAT('cn=',gecos),',o=MyCompany,c=NL')),
1, 0, userid FROM unixusers UNION
UPPER(CONCAT(CONCAT('cn=',gecos),',o=MyCompany,c=NL')),
1, 0, userid FROM unixusers
UNION
SELECT (2000000000+groupnummer),
UPPER(CONCAT(CONCAT('cn=',groupnaam),',o=MyCompany,c=NL')),
2, 0, groupnummer FROM groups;
UPPER(CONCAT(CONCAT('cn=',groupnaam),',o=MyCompany,c=NL')),
2, 0, groupnummer FROM groups;
.fi
.LP
@ -439,7 +520,7 @@ query generated (which loads candidate IDs)
AND ldap_entries.objclass=?
AND ldap_entries.parent=?
AND phones.pers_id=persons.id
AND (phones.phone LIKE '123%')
AND (phones.phone LIKE '%1%2%3%')
.fi
.LP
(for ONELEVEL search)
@ -465,15 +546,15 @@ ADD, DELETE, MODIFY and MODRDN operations are also performed on per-attribute
metainformation (add_proc etc.).
In those fields one can specify an SQL statement or stored procedure
call which can add, or delete given values of a given attribute, using
the given entry keyval (see examples -- mostly ORACLE and MSSQL - since
there're no stored procs in mySQL).
the given entry keyval (see examples -- mostly PostgreSQL, ORACLE and MSSQL
- since as of this writing there are no stored procs in MySQL).
.LP
We just add more columns to oc_mappings and attr_mappings, holding
We just add more columns to ldap_oc_mappings and ldap_attr_mappings, holding
statements to execute (like create_proc, add_proc, del_proc etc.), and
flags governing the order of parameters passed to those statements.
Please see samples to find out what are the parameters passed, and other
information on this matter - they are self-explanatory for those familiar
with concept expressed above.
with the concepts expressed above.
.LP
.SH Common techniques (referrals, multiclassing etc.)
First of all, let's remember that among other major differences to the
@ -505,16 +586,24 @@ As previously stated, this backend should not be considered
a replacement of other data storage backends, but rather a gateway
to existing RDBMS storages that need to be published in LDAP form.
.LP
The hasSubordintes operational attribute is honored by back-sql
The \fBhasSubordintes\fP operational attribute is honored by back-sql
in search results and in compare operations; it is partially honored
also in filtering. Owing to design limitations, a (braindead) filter
also in filtering. Owing to design limitations, a (braindead?) filter
of the form
\fB(!(hasSubordinates=TRUE))\fP
will give no results instead of returning all the leaf entries.
will give no results instead of returning all the leaf entries, because
it actually expands into \fB... AND NOT (1=1)\fP.
If you need to find all the leaf entries, please use
\fB(hasSubordinates=FALSE)\fP
instead.
.LP
A directoryString value of the form "__First___Last_"
(where underscores should be replaced by spaces) corresponds
to its prettified counterpart "First_Last"; this is not currently
honored by back-sql if non-prettified data is written via RDBMS;
when non-prettified data is written thru back-sql, the prettified
values are actually used instead.
.LP
.SH PROXY CACHE OVERLAY
The proxy cache overlay
allows caching of LDAP search requests (queries) in a local database.
@ -525,6 +614,7 @@ for details.
There are example SQL modules in the slapd/back-sql/rdbms_depend/
directory in the OpenLDAP source tree.
.SH FILES
.TP
ETCDIR/slapd.conf
default slapd configuration file

View file

@ -1348,7 +1348,7 @@ backsql_add( Operation *op, SlapReply *rs )
}
}
rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_query, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_stmt, 0 );
if ( rc != SQL_SUCCESS ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = "SQL-backend error";
@ -1416,7 +1416,7 @@ backsql_add( Operation *op, SlapReply *rs )
}
Debug( LDAP_DEBUG_TRACE, " backsql_add(): executing \"%s\" for dn \"%s\"\n",
bi->sql_insentry_query, op->oq_add.rs_e->e_name.bv_val, 0 );
bi->sql_insentry_stmt, op->oq_add.rs_e->e_name.bv_val, 0 );
#ifdef BACKSQL_ARBITRARY_KEY
Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, "
"parent_id=%s, keyval=%ld\n",

View file

@ -31,7 +31,7 @@
static backsql_api *backsqlapi;
int
backsql_api_config( backsql_info *bi, const char *name )
backsql_api_config( backsql_info *bi, const char *name, int argc, char *argv[] )
{
backsql_api *ba;
@ -44,6 +44,14 @@ backsql_api_config( backsql_info *bi, const char *name )
ba2 = ch_malloc( sizeof( backsql_api ) );
*ba2 = *ba;
if ( ba2->ba_config ) {
if ( ( *ba2->ba_config )( ba2, argc, argv ) ) {
ch_free( ba2 );
return 1;
}
}
ba2->ba_next = bi->sql_api;
bi->sql_api = ba2;
return 0;
@ -53,12 +61,35 @@ backsql_api_config( backsql_info *bi, const char *name )
return 1;
}
int
backsql_api_destroy( backsql_info *bi )
{
backsql_api *ba;
assert( bi );
ba = bi->sql_api;
if ( ba == NULL ) {
return 0;
}
for ( ; ba; ba = ba->ba_next ) {
if ( ba->ba_destroy ) {
(void)( *ba->ba_destroy )( ba );
}
}
return 0;
}
int
backsql_api_register( backsql_api *ba )
{
backsql_api *ba2;
assert( ba );
assert( ba->ba_private == NULL );
if ( ba->ba_name == NULL ) {
fprintf( stderr, "API module has no name\n" );

View file

@ -238,9 +238,14 @@ typedef struct {
*/
typedef struct backsql_api {
char *ba_name;
int (*ba_config)( struct backsql_api *self, int argc, char *argv[] );
int (*ba_destroy)( struct backsql_api *self );
int (*ba_dn2odbc)( Operation *op, SlapReply *rs, struct berval *dn );
int (*ba_odbc2dn)( Operation *op, SlapReply *rs, struct berval *dn );
struct backsql_api *ba_next;
void *ba_private;
struct backsql_api *ba_next;
} backsql_api;
/*
@ -437,10 +442,10 @@ typedef struct {
struct berval sql_children_cond;
char *sql_oc_query,
*sql_at_query;
char *sql_insentry_query,
*sql_delentry_query,
*sql_delobjclasses_query,
*sql_delreferrals_query;
char *sql_insentry_stmt,
*sql_delentry_stmt,
*sql_delobjclasses_stmt,
*sql_delreferrals_stmt;
char *sql_id_query;
char *sql_has_children_query;

View file

@ -100,26 +100,15 @@ backsql_bind( Operation *op, SlapReply *rs )
}
e = &user_entry;
if ( ! access_allowed( op, e, password, NULL, ACL_AUTH, NULL ) ) {
#if 1
rs->sr_err = LDAP_INVALID_CREDENTIALS;
#else
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
#endif
goto error_return;
}
a = attr_find( e->e_attrs, password );
if ( a == NULL ) {
#if 1
rs->sr_err = LDAP_INVALID_CREDENTIALS;
#else
rs->sr_err = LDAP_INAPPROPRIATE_AUTH;
#endif
goto error_return;
}
if ( slap_passwd_check( op->o_conn, a, &op->oq_bind.rb_cred, &rs->sr_text ) != 0 ) {
if ( slap_passwd_check( op, e, a, &op->oq_bind.rb_cred,
&rs->sr_text ) != 0 )
{
rs->sr_err = LDAP_INVALID_CREDENTIALS;
goto error_return;
}

View file

@ -176,18 +176,20 @@ backsql_db_config(
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"at_query=%s\n", bi->sql_at_query, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "insentry_query" ) ) {
} else if ( !strcasecmp( argv[ 0 ], "insentry_stmt" ) ||
!strcasecmp( argv[ 0 ], "insentry_query" ) )
{
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in \"insentry_query\" directive\n",
"in \"insentry_stmt\" directive\n",
fname, lineno, 0 );
return 1;
}
bi->sql_insentry_query = ch_strdup( argv[ 1 ] );
bi->sql_insentry_stmt = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"insentry_query=%s\n", bi->sql_insentry_query, 0, 0 );
"insentry_stmt=%s\n", bi->sql_insentry_stmt, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "create_needs_select" ) ) {
if ( argc < 2 ) {
@ -274,44 +276,50 @@ backsql_db_config(
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"strcast_func=%s\n", bi->sql_strcast_func.bv_val, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "delentry_query" ) ) {
} else if ( !strcasecmp( argv[ 0 ], "delentry_stmt" ) ||
!strcasecmp( argv[ 0 ], "delentry_query" ) )
{
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in \"delentry_query\" directive\n",
"in \"delentry_stmt\" directive\n",
fname, lineno, 0 );
return 1;
}
bi->sql_delentry_query = ch_strdup( argv[ 1 ] );
bi->sql_delentry_stmt = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"delentry_query=%s\n", bi->sql_delentry_query, 0, 0 );
"delentry_stmt=%s\n", bi->sql_delentry_stmt, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "delobjclasses_query" ) ) {
} else if ( !strcasecmp( argv[ 0 ], "delobjclasses_stmt" ) ||
!strcasecmp( argv[ 0 ], "delobjclasses_query" ) )
{
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in \"delobjclasses_query\" directive\n",
"in \"delobjclasses_stmt\" directive\n",
fname, lineno, 0 );
return 1;
}
bi->sql_delobjclasses_query = ch_strdup( argv[ 1 ] );
bi->sql_delobjclasses_stmt = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"delobjclasses_query=%s\n", bi->sql_delobjclasses_query, 0, 0 );
"delobjclasses_stmt=%s\n", bi->sql_delobjclasses_stmt, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "delreferrals_query" ) ) {
} else if ( !strcasecmp( argv[ 0 ], "delreferrals_stmt" ) ||
!strcasecmp( argv[ 0 ], "delreferrals_query" ) )
{
if ( argc < 2 ) {
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"missing SQL statement "
"in \"delreferrals_query\" directive\n",
"in \"delreferrals_stmt\" directive\n",
fname, lineno, 0 );
return 1;
}
bi->sql_delreferrals_query = ch_strdup( argv[ 1 ] );
bi->sql_delreferrals_stmt = ch_strdup( argv[ 1 ] );
Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config(): "
"delreferrals_query=%s\n", bi->sql_delreferrals_query, 0, 0 );
"delreferrals_stmt=%s\n", bi->sql_delreferrals_stmt, 0, 0 );
} else if ( !strcasecmp( argv[ 0 ], "has_ldapinfo_dn_ru") ) {
if ( argc < 2 ) {
@ -436,7 +444,8 @@ backsql_db_config(
}
} else if ( !strcasecmp( argv[ 0 ], "sqllayer") ) {
if ( backsql_api_config( bi, argv[ 1 ] ) ) {
if ( backsql_api_config( bi, argv[ 1 ], argc - 2, &argv[ 2 ] ) )
{
Debug( LDAP_DEBUG_TRACE,
"<==backsql_db_config (%s line %d): "
"unable to load sqllayer \"%s\"\n",

View file

@ -246,7 +246,7 @@ backsql_delete( Operation *op, SlapReply *rs )
SQLFreeStmt( sth, SQL_DROP );
/* delete "auxiliary" objectClasses, if any... */
rc = backsql_Prepare( dbh, &sth, bi->sql_delobjclasses_query, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_delobjclasses_stmt, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_delete(): "
@ -296,7 +296,7 @@ backsql_delete( Operation *op, SlapReply *rs )
SQLFreeStmt( sth, SQL_DROP );
/* delete referrals, if any... */
rc = backsql_Prepare( dbh, &sth, bi->sql_delreferrals_query, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_delreferrals_stmt, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_delete(): "
@ -346,7 +346,7 @@ backsql_delete( Operation *op, SlapReply *rs )
SQLFreeStmt( sth, SQL_DROP );
/* delete entry... */
rc = backsql_Prepare( dbh, &sth, bi->sql_delentry_query, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_delentry_stmt, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_delete(): "

View file

@ -135,10 +135,10 @@ backsql_db_destroy(
free( bi->sql_subtree_cond.bv_val );
free( bi->sql_oc_query );
free( bi->sql_at_query );
free( bi->sql_insentry_query );
free( bi->sql_delentry_query );
free( bi->sql_delobjclasses_query );
free( bi->sql_delreferrals_query );
free( bi->sql_insentry_stmt );
free( bi->sql_delentry_stmt );
free( bi->sql_delobjclasses_stmt );
free( bi->sql_delreferrals_stmt );
if ( bi->sql_baseObject ) {
entry_free( bi->sql_baseObject );
@ -343,48 +343,48 @@ backsql_db_open(
bi->sql_at_query = ch_strdup( backsql_def_at_query );
}
if ( bi->sql_insentry_query == NULL ) {
if ( bi->sql_insentry_stmt == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"entry insertion SQL statement not specified "
"(use \"insentry_query\" directive in slapd.conf)\n",
"(use \"insentry_stmt\" directive in slapd.conf)\n",
0, 0, 0 );
Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting \"%s\" by default\n",
backsql_def_insentry_query, 0, 0 );
bi->sql_insentry_query = ch_strdup( backsql_def_insentry_query );
backsql_def_insentry_stmt, 0, 0 );
bi->sql_insentry_stmt = ch_strdup( backsql_def_insentry_stmt );
}
if ( bi->sql_delentry_query == NULL ) {
if ( bi->sql_delentry_stmt == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"entry deletion SQL statement not specified "
"(use \"delentry_query\" directive in slapd.conf)\n",
"(use \"delentry_stmt\" directive in slapd.conf)\n",
0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting \"%s\" by default\n",
backsql_def_delentry_query, 0, 0 );
bi->sql_delentry_query = ch_strdup( backsql_def_delentry_query );
backsql_def_delentry_stmt, 0, 0 );
bi->sql_delentry_stmt = ch_strdup( backsql_def_delentry_stmt );
}
if ( bi->sql_delobjclasses_query == NULL ) {
if ( bi->sql_delobjclasses_stmt == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"objclasses deletion SQL statement not specified "
"(use \"delobjclasses_query\" directive in slapd.conf)\n",
"(use \"delobjclasses_stmt\" directive in slapd.conf)\n",
0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting \"%s\" by default\n",
backsql_def_delobjclasses_query, 0, 0 );
bi->sql_delobjclasses_query = ch_strdup( backsql_def_delobjclasses_query );
backsql_def_delobjclasses_stmt, 0, 0 );
bi->sql_delobjclasses_stmt = ch_strdup( backsql_def_delobjclasses_stmt );
}
if ( bi->sql_delreferrals_query == NULL ) {
if ( bi->sql_delreferrals_stmt == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"referrals deletion SQL statement not specified "
"(use \"delreferrals_query\" directive in slapd.conf)\n",
"(use \"delreferrals_stmt\" directive in slapd.conf)\n",
0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"setting \"%s\" by default\n",
backsql_def_delreferrals_query, 0, 0 );
bi->sql_delreferrals_query = ch_strdup( backsql_def_delreferrals_query );
backsql_def_delreferrals_stmt, 0, 0 );
bi->sql_delreferrals_stmt = ch_strdup( backsql_def_delreferrals_stmt );
}
op->o_hdr = (Opheader *)&op[ 1 ];

View file

@ -232,13 +232,13 @@ backsql_modrdn( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): "
"executing delentry_query\n", 0, 0, 0 );
"executing delentry_stmt\n", 0, 0, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_delentry_query, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_delentry_stmt, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_modrdn(): "
"error preparing delentry_query\n", 0, 0, 0 );
"error preparing delentry_stmt\n", 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, dbh,
sth, rc );
@ -279,13 +279,13 @@ backsql_modrdn( Operation *op, SlapReply *rs )
SQLFreeStmt( sth, SQL_DROP );
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): "
"executing insentry_query\n", 0, 0, 0 );
"executing insentry_stmt\n", 0, 0, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_query, 0 );
rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_stmt, 0 );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_modrdn(): "
"error preparing insentry_query\n", 0, 0, 0 );
"error preparing insentry_stmt\n", 0, 0, 0 );
backsql_PrintErrors( bi->sql_db_env, dbh,
sth, rc );

View file

@ -96,7 +96,9 @@ int backsql_modify_internal(
/*
* api.c
*/
int backsql_api_config( backsql_info *si, const char *name );
int backsql_api_config( backsql_info *bi, const char *name,
int argc, char *argv[] );
int backsql_api_destroy( backsql_info *bi );
int backsql_api_register( backsql_api *ba );
int backsql_api_dn2odbc( Operation *op, SlapReply *rs, struct berval *dn );
int backsql_api_odbc2dn( Operation *op, SlapReply *rs, struct berval *dn );
@ -221,10 +223,10 @@ extern char
backsql_def_oc_query[],
backsql_def_needs_select_oc_query[],
backsql_def_at_query[],
backsql_def_delentry_query[],
backsql_def_insentry_query[],
backsql_def_delobjclasses_query[],
backsql_def_delreferrals_query[],
backsql_def_delentry_stmt[],
backsql_def_insentry_stmt[],
backsql_def_delobjclasses_stmt[],
backsql_def_delreferrals_stmt[],
backsql_def_subtree_cond[],
backsql_def_upper_subtree_cond[],
backsql_id_query[],

View file

@ -28,7 +28,7 @@ dbname ldap_db2
dbuser db2inst1
dbpasswd ibmdb2
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_stmt "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
upper_func "upper"
upper_needs_cast "yes"
create_needs_select "yes"

View file

@ -28,5 +28,5 @@ dbname ldap_mysql
dbuser root
dbpasswd
subtree_cond "ldap_entries.dn LIKE CONCAT('%',?)"
insentry_query "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)"
insentry_stmt "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)"
has_ldapinfo_dn_ru no

View file

@ -28,5 +28,5 @@ dbname ldap_ora8
dbuser ldap
dbpasswd ldap
subtree_cond "UPPER(ldap_entries.dn) LIKE CONCAT('%',UPPER(?))"
insentry_query "INSERT INTO ldap_entries (id,dn,oc_map_id,parent,keyval) VALUES (ldap_entry_ids.nextval,?,?,?,?)"
insentry_stmt "INSERT INTO ldap_entries (id,dn,oc_map_id,parent,keyval) VALUES (ldap_entry_ids.nextval,?,?,?,?)"
upper_func UPPER

View file

@ -27,7 +27,7 @@ rootpw secret
dbname PostgreSQL
dbuser postgres
dbpasswd postgres
insentry_query "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
insentry_stmt "insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values ((select max(id)+1 from ldap_entries),?,?,?,?)"
upper_func "upper"
strcast_func "text"
concat_pattern "?||?"

View file

@ -28,4 +28,4 @@ dbname ldap_tt
dbuser root
dbpasswd
subtree_cond "ldap_entries.dn LIKE ?"
insentry_query "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)"
insentry_stmt "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)"

View file

@ -958,6 +958,10 @@ equality_match:;
casefold = 1;
}
/* FIXME: directoryString filtering should use a similar
* approach to deal with non-prettified values like
* " A non prettified value ", by using a LIKE
* filter with all whitespaces collapsed to a single '%' */
if ( SLAP_MR_ASSOCIATED( matching_rule,
bi->sql_telephoneNumberMatch ) )
{

View file

@ -47,13 +47,13 @@ char backsql_def_at_query[] =
"SELECT name,sel_expr,from_tbls,join_where,add_proc,delete_proc,"
"param_order,expect_return,sel_expr_u FROM ldap_attr_mappings "
"WHERE oc_map_id=?";
char backsql_def_delentry_query[] = "DELETE FROM ldap_entries WHERE id=?";
char backsql_def_insentry_query[] =
char backsql_def_delentry_stmt[] = "DELETE FROM ldap_entries WHERE id=?";
char backsql_def_insentry_stmt[] =
"INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) "
"VALUES (?,?,?,?)";
char backsql_def_delobjclasses_query[] = "DELETE FROM ldap_entry_objclasses "
char backsql_def_delobjclasses_stmt[] = "DELETE FROM ldap_entry_objclasses "
"WHERE entry_id=?";
char backsql_def_delreferrals_query[] = "DELETE FROM ldap_referrals "
char backsql_def_delreferrals_stmt[] = "DELETE FROM ldap_referrals "
"WHERE entry_id=?";
char backsql_def_subtree_cond[] = "ldap_entries.dn LIKE CONCAT('%',?)";
char backsql_def_upper_subtree_cond[] = "(ldap_entries.dn) LIKE CONCAT('%',?)";