]> git.sur5r.net Git - openldap/commitdiff
minor naming cleanup; improvements to DN mapping layer; major docs update
authorPierangelo Masarati <ando@openldap.org>
Wed, 5 Jan 2005 16:23:00 +0000 (16:23 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 5 Jan 2005 16:23:00 +0000 (16:23 +0000)
17 files changed:
doc/man/man5/slapd-sql.5
servers/slapd/back-sql/add.c
servers/slapd/back-sql/api.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/bind.c
servers/slapd/back-sql/config.c
servers/slapd/back-sql/delete.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/modrdn.c
servers/slapd/back-sql/proto-sql.h
servers/slapd/back-sql/rdbms_depend/ibmdb2/slapd.conf
servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf
servers/slapd/back-sql/rdbms_depend/oracle/slapd.conf
servers/slapd/back-sql/rdbms_depend/pgsql/slapd.conf
servers/slapd/back-sql/rdbms_depend/timesten/slapd.conf
servers/slapd/back-sql/search.c
servers/slapd/back-sql/util.c

index e49b7c75f90e14d15f55041374a21cb0edd01b3a..668eb13e883e29125e81de89048d10ac3c7a3b01 100644 (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).
+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 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
-.B "SELECT id, name, keytbl, keycol, create_proc, delete_proc, expect_return FROM ldap_oc_mappings"
+\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
-.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=?"
+\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 insentry_query <SQL expression>
+.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
-.B "INSERT INTO ldap_entries (dn, oc_map_id, parent, keyval) VALUES (?, ?, ?, ?)"
+\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 delentry_query <SQL expression>
+.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
-.B "DELETE FROM ldap_entries WHERE id=?"
+\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
 
-These four 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 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
index 55903e4047170930318f852e5dd5f9b2c97c5bff..c46dbba0a196e4ba3002da9cbe0c4cbd8b672027 100644 (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",
index 763956b0498450cf570848eee9e76c0e7f8b5bef..e4584c3ebfd655da2d22171cd4e3a7ff13d91f9a 100644 (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" );
index a949b8c0a24273c7991403dd245d5bd56059ad83..dd3a35edceae9c488f2436e259b9c18e7735b83f 100644 (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;
 
index ce4edaf83c74d4634ff99eaf5fdbf73068922319..45b60659f034758801a63131a95544c10877cbdd 100644 (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;
        }
index 965ba89180bd09b74566fdaa0eb9b61991858e55..413bdf5f9fef20a075d501a133c247fa014aec43 100644 (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",
index fb0538b09d13f62af5f507639090def974598a1a..366297c7915c2a9edf8a7bf1233d1859f11e09b4 100644 (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(): "
index 28d56e76d9b852be94d6646ac6a72f0e5d6ab969..11c45189707a3ecae8e6008438170e98553d6ca5 100644 (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 ];
index 847ae82d84d505721edc352448b79e4f78fdb904..c54d8833c9c9583b4962d26238ef94fb6b81d904 100644 (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 );
 
index b03f3ecbf5e92013644a9881f6b1c16601009fd9..1e019b587a10c351a83edd25281061e383a2543c 100644 (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[],
index 556470cb53cc6c4c7185896aae5e4b5856c81565..f6c16130099b26c13557d7735578b7157008b6c1 100644 (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"
index a780c83954d2dcb7b52786c111193ab01dc329c0..8f6e4e12f1ee1578b42084e5e212ded2e5c5e93e 100644 (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
index e94368237a49f658c23e14c0d0469010c09bc686..cc195d91e8c2cccebf9507b37afa7a97cfa81bbf 100644 (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
index aecc890597407c1941e14db58d88c6b27c739f39..70a8dee054679a4d2f96ea84fd49e4f73b313d88 100644 (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 "?||?"
index b0b15a386f7aea499b54ba7fccbe8ceeaf98a065..f93de8b402e3285eef91dafa9223457a0f8315a2 100644 (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 (?,?,?,?)"
index 3097e18fea810fef763ea6d3c75ab1f34b0d9b7c..cb4089b1925d76c6c382aa3d2fd2fa794b83bc9f 100644 (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 ) )
                {
index dcc30bf20e1f34acf40e81b16e75a0cfd2f9293a..d85058488b11e44654adabf9550b53c52c2ee21a 100644 (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('%',?)";