Back to index

openldap  2.4.31
back-sql.h
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 1999-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 1999 Dmitry Kovalev.
00006  * Portions Copyright 2002 Pierangelo Mararati.
00007  * Portions Copyright 2004 Mark Adamson.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted only as authorized by the OpenLDAP
00012  * Public License.
00013  *
00014  * A copy of this license is available in the file LICENSE in the
00015  * top-level directory of the distribution or, alternatively, at
00016  * <http://www.OpenLDAP.org/license.html>.
00017  */
00018 /* ACKNOWLEDGEMENTS:
00019  * This work was initially developed by Dmitry Kovalev for inclusion
00020  * by OpenLDAP Software.  Additional significant contributors include
00021  * Pierangelo Masarati and Mark Adamson.
00022  */
00023 /*
00024  * The following changes have been addressed:
00025  *      
00026  * Enhancements:
00027  *   - re-styled code for better readability
00028  *   - upgraded backend API to reflect recent changes
00029  *   - LDAP schema is checked when loading SQL/LDAP mapping
00030  *   - AttributeDescription/ObjectClass pointers used for more efficient
00031  *     mapping lookup
00032  *   - bervals used where string length is required often
00033  *   - atomized write operations by committing at the end of each operation
00034  *     and defaulting connection closure to rollback
00035  *   - added LDAP access control to write operations
00036  *   - fully implemented modrdn (with rdn attrs change, deleteoldrdn,
00037  *     access check, parent/children check and more)
00038  *   - added parent access control, children control to delete operation
00039  *   - added structuralObjectClass operational attribute check and
00040  *     value return on search
00041  *   - added hasSubordinate operational attribute on demand
00042  *   - search limits are appropriately enforced
00043  *   - function backsql_strcat() has been made more efficient
00044  *   - concat function has been made configurable by means of a pattern
00045  *   - added config switches:
00046  *       - fail_if_no_mapping      write operations fail if there is no mapping
00047  *       - has_ldapinfo_dn_ru      overrides autodetect
00048  *       - concat_pattern   a string containing two '?' is used
00049  *                          (note that "?||?" should be more portable
00050  *                          than builtin function "CONCAT(?,?)")
00051  *       - strcast_func            cast of string constants in "SELECT DISTINCT
00052  *                          statements (needed by PostgreSQL)
00053  *       - upper_needs_cast cast the argument of upper when required
00054  *                          (basically when building dn substring queries)
00055  *   - added noop control
00056  *   - added values return filter control
00057  *   - hasSubordinate can be used in search filters (with limitations)
00058  *   - eliminated oc->name; use oc->oc->soc_cname instead
00059  * 
00060  * Todo:
00061  *   - add security checks for SQL statements that can be injected (?)
00062  *   - re-test with previously supported RDBMs
00063  *   - replace dn_ru and so with normalized dn (no need for upper() and so
00064  *     in dn match)
00065  *   - implement a backsql_normalize() function to replace the upper()
00066  *     conversion routines
00067  *   - note that subtree deletion, subtree renaming and so could be easily
00068  *     implemented (rollback and consistency checks are available :)
00069  *   - implement "lastmod" and other operational stuff (ldap_entries table ?)
00070  *   - check how to allow multiple operations with one statement, to remove
00071  *     BACKSQL_REALLOC_STMT from modify.c (a more recent unixODBC lib?)
00072  */
00073 /*
00074  * Improvements submitted by (ITS#3432)
00075  *
00076  * 1. id_query.patch        applied (with changes)
00077  * 2. shortcut.patch        applied (reworked)
00078  * 3. create_hint.patch            applied
00079  * 4. count_query.patch            applied (reworked)
00080  * 5. returncodes.patch            applied (with sanity checks)
00081  * 6. connpool.patch        under evaluation
00082  * 7. modoc.patch           under evaluation (requires
00083  *                          manageDSAit and "manage"
00084  *                          access privileges)
00085  * 8. miscfixes.patch              applied (reworked; other
00086  *                          operations need to load the
00087  *                          entire entry for ACL purposes;
00088  *                          see ITS#3480, now fixed)
00089  *
00090  * original description:
00091 
00092          Changes that were made to the SQL backend.
00093 
00094 The patches were made against 2.2.18 and can be applied individually,
00095 but would best be applied in the numerical order of the file names.
00096 A synopsis of each patch is given here:
00097 
00098 
00099 1. Added an option to set SQL query for the "id_query" operation.
00100 
00101 2. Added an option to the SQL backend called "use_subtree_shortcut".
00102 When a search is performed, the SQL query includes a WHERE clause
00103 which says the DN must be "LIKE %<searchbase>".  The LIKE operation
00104 can be slow in an RDBM. This shortcut option says that if the
00105 searchbase of the LDAP search is the root DN of the SQL backend,
00106 and thus all objects will match the LIKE operator, do not include
00107 the "LIKE %<searchbase>" clause in the SQL query (it is replaced
00108 instead by the always true "1=1" clause to keep the "AND"'s 
00109 working correctly).  This option is off by default, and should be
00110 turned on only if all objects to be found in the RDBM are under the
00111 same root DN. Multiple backends working within the same RDBM table
00112 space would encounter problems. LDAP searches whose searchbase are
00113 not at the root DN will bypass this shortcut and employ the LIKE 
00114 clause.
00115 
00116 3. Added a "create_hint" column to ldap_oc_mappings table. Allows
00117 taking the value of an attr named in "create_hint" and passing it to
00118 the create_proc procedure.  This is necessary for when an objectClass's
00119 table is partition indexed by some indexing column and thus the value
00120 in that indexing column cannot change after the row is created. The
00121 value for the indexed column is passed into the create_proc, which
00122 uses it to fill in the indexed column as the new row is created.
00123 
00124 4. When loading the values of an attribute, the count(*) of the number
00125 of values is fetched first and memory is allocated for the array of
00126 values and normalized values. The old system of loading the values one
00127 by one and running realloc() on the array of values and normalized
00128 values each time was badly fragmenting memory. The array of values and
00129 normalized values would be side by side in memory, and realloc()'ing
00130 them over and over would force them to leapfrog each other through all
00131 of available memory. Attrs with a large number of values could not be
00132 loaded without crashing the slapd daemon.
00133 
00134 5. Added code to interpret the value returned by stored procedures
00135 which have expect_return set. Returned value is interpreted as an LDAP
00136 return code. This allows the distinction between the SQL failing to
00137 execute and the SQL running to completion and returning an error code
00138 which can indicate a policy violation.
00139 
00140 6. Added RDBM connection pooling. Once an operation is finished the
00141 connection to the RDBM is returned to a pool rather than closing.
00142 Allows the next operation to skip the initialization and authentication
00143 phases of contacting the RDBM. Also, if licensing with ODBC places
00144 a limit on the number of connections, an LDAP thread can block waiting
00145 for another thread to finish, so that no LDAP errors are returned
00146 for having more LDAP connections than allowed RDBM connections. An
00147 RDBM connection which receives an SQL error is marked as "tainted"
00148 so that it will be closed rather than returned to the pool.
00149   Also, RDBM connections must be bound to a given LDAP connection AND
00150 operation number, and NOT just the connection number.  Asynchronous
00151 LDAP clients can have multiple simultaneous LDAP operations which
00152 should not share the same RDBM connection.  A given LDAP operation can
00153 even make multiple SQL operations (e.g. a BIND operation which
00154 requires SASL to perform an LDAP search to convert the SASL ID to an
00155 LDAP DN), so each RDBM connection now has a refcount that must reach
00156 zero before the connection is returned to the free pool.
00157 
00158 7. Added ability to change the objectClass of an object. Required 
00159 considerable work to copy all attributes out of old object and into
00160 new object.  Does a schema check before proceeding.  Creates a new
00161 object, fills it in, deletes the old object, then changes the 
00162 oc_map_id and keyval of the entry in the "ldap_entries" table.
00163 
00164 8.  Generic fixes. Includes initializing pointers before they
00165 get used in error branch cases, pointer checks before dereferencing,
00166 resetting a return code to success after a COMPARE op, sealing
00167 memory leaks, and in search.c, changing some of the "1=1" tests to
00168 "2=2", "3=3", etc so that when reading slapd trace output, the 
00169 location in the source code where the x=x test was added to the SQL
00170 can be easily distinguished.
00171  */
00172 
00173 #ifndef __BACKSQL_H__
00174 #define __BACKSQL_H__
00175 
00176 /* former sql-types.h */
00177 #include <sql.h>
00178 #include <sqlext.h>
00179 
00180 typedef struct {
00181        SWORD         ncols;
00182        BerVarray     col_names;
00183        UDWORD        *col_prec;
00184        SQLSMALLINT   *col_type;
00185        char          **cols;
00186        SQLLEN        *value_len;
00187 } BACKSQL_ROW_NTS;
00188 
00189 /*
00190  * Better use the standard length of 8192 (as of slap.h)?
00191  *
00192  * NOTE: must be consistent with definition in ldap_entries table
00193  */
00194 /* #define BACKSQL_MAX_DN_LEN      SLAP_LDAPDN_MAXLEN */
00195 #define BACKSQL_MAX_DN_LEN  255
00196 
00197 /*
00198  * define to enable very extensive trace logging (debug only)
00199  */
00200 #undef BACKSQL_TRACE
00201 
00202 /*
00203  * define if using MS SQL and workaround needed (see sql-wrap.c)
00204  */
00205 #undef BACKSQL_MSSQL_WORKAROUND
00206 
00207 /*
00208  * define to enable values counting for attributes
00209  */
00210 #define BACKSQL_COUNTQUERY
00211 
00212 /*
00213  * define to enable prettification/validation of values
00214  */
00215 #define BACKSQL_PRETTY_VALIDATE
00216 
00217 /*
00218  * define to enable varchars as unique keys in user tables
00219  *
00220  * by default integers are used (and recommended)
00221  * for performances.  Integers are used anyway in back-sql
00222  * related tables.
00223  */
00224 #undef BACKSQL_ARBITRARY_KEY
00225 
00226 /*
00227  * type used for keys
00228  */
00229 #if defined(HAVE_LONG_LONG) && defined(SQL_C_UBIGINT) && \
00230        ( defined(HAVE_STRTOULL) || defined(HAVE_STRTOUQ) )
00231 typedef unsigned long long backsql_key_t;
00232 #define BACKSQL_C_NUMID     SQL_C_UBIGINT
00233 #define BACKSQL_IDNUMFMT "%llu"
00234 #define BACKSQL_STR2ID lutil_atoullx
00235 #else /* ! HAVE_LONG_LONG || ! SQL_C_UBIGINT */
00236 typedef unsigned long backsql_key_t;
00237 #define BACKSQL_C_NUMID     SQL_C_ULONG
00238 #define BACKSQL_IDNUMFMT "%lu"
00239 #define BACKSQL_STR2ID lutil_atoulx
00240 #endif /* ! HAVE_LONG_LONG */
00241 
00242 /*
00243  * define to enable support for syncprov overlay
00244  */
00245 #define BACKSQL_SYNCPROV
00246 
00247 /*
00248  * define to the appropriate aliasing string
00249  *
00250  * some RDBMSes tolerate (or require) that " AS " is not used
00251  * when aliasing tables/columns
00252  */
00253 #define BACKSQL_ALIASING    "AS "
00254 /* #define    BACKSQL_ALIASING     "" */
00255 
00256 /*
00257  * define to the appropriate quoting char
00258  *
00259  * some RDBMSes tolerate/require that the aliases be enclosed
00260  * in quotes.  This is especially true for those that do not
00261  * allow keywords used as aliases.
00262  */
00263 #define BACKSQL_ALIASING_QUOTE     ""
00264 /* #define BACKSQL_ALIASING_QUOTE  "\"" */
00265 /* #define BACKSQL_ALIASING_QUOTE  "'" */
00266 
00267 /*
00268  * API
00269  *
00270  * a simple mechanism to allow DN mucking between the LDAP
00271  * and the stored string representation.
00272  */
00273 typedef struct backsql_api {
00274        char                 *ba_name;
00275        int                  (*ba_config)( struct backsql_api *self, int argc, char *argv[] );
00276        int                  (*ba_destroy)( struct backsql_api *self );
00277 
00278        int                  (*ba_dn2odbc)( Operation *op, SlapReply *rs, struct berval *dn );
00279        int                  (*ba_odbc2dn)( Operation *op, SlapReply *rs, struct berval *dn );
00280 
00281        void                 *ba_private;
00282        struct backsql_api   *ba_next;
00283        char **ba_argv;
00284        int    ba_argc;
00285 } backsql_api;
00286 
00287 /*
00288  * "structural" objectClass mapping structure
00289  */
00290 typedef struct backsql_oc_map_rec {
00291        /*
00292         * Structure of corresponding LDAP objectClass definition
00293         */
00294        ObjectClass          *bom_oc;
00295 #define BACKSQL_OC_NAME(ocmap)     ((ocmap)->bom_oc->soc_cname.bv_val)
00296        
00297        struct berval        bom_keytbl;
00298        struct berval        bom_keycol;
00299        /* expected to return keyval of newly created entry */
00300        char                 *bom_create_proc;
00301        /* in case create_proc does not return the keyval of the newly
00302         * created row */
00303        char                 *bom_create_keyval;
00304        /* supposed to expect keyval as parameter and delete 
00305         * all the attributes as well */
00306        char                 *bom_delete_proc;
00307        /* flags whether delete_proc is a function (whether back-sql 
00308         * should bind first parameter as output for return code) */
00309        int                  bom_expect_return;
00310        backsql_key_t        bom_id;
00311        Avlnode                     *bom_attrs;
00312        AttributeDescription *bom_create_hint;
00313 } backsql_oc_map_rec;
00314 
00315 /*
00316  * attributeType mapping structure
00317  */
00318 typedef struct backsql_at_map_rec {
00319        /* Description of corresponding LDAP attribute type */
00320        AttributeDescription *bam_ad;
00321        AttributeDescription *bam_true_ad;
00322        /* ObjectClass if bam_ad is objectClass */
00323        ObjectClass          *bam_oc;
00324 
00325        struct berval bam_from_tbls;
00326        struct berval bam_join_where;
00327        struct berval bam_sel_expr;
00328 
00329        /* TimesTen, or, if a uppercase function is defined,
00330         * an uppercased version of bam_sel_expr */
00331        struct berval bam_sel_expr_u;
00332 
00333        /* supposed to expect 2 binded values: entry keyval 
00334         * and attr. value to add, like "add_name(?,?,?)" */
00335        char          *bam_add_proc;
00336        /* supposed to expect 2 binded values: entry keyval 
00337         * and attr. value to delete */
00338        char          *bam_delete_proc;
00339        /* for optimization purposes attribute load query 
00340         * is preconstructed from parts on schemamap load time */
00341        char          *bam_query;
00342 #ifdef BACKSQL_COUNTQUERY
00343        char          *bam_countquery;
00344 #endif /* BACKSQL_COUNTQUERY */
00345        /* following flags are bitmasks (first bit used for add_proc, 
00346         * second - for delete_proc) */
00347        /* order of parameters for procedures above; 
00348         * 1 means "data then keyval", 0 means "keyval then data" */
00349        int           bam_param_order;
00350        /* flags whether one or more of procedures is a function 
00351         * (whether back-sql should bind first parameter as output 
00352         * for return code) */
00353        int           bam_expect_return;
00354 
00355        /* next mapping for attribute */
00356        struct backsql_at_map_rec   *bam_next;
00357 } backsql_at_map_rec;
00358 
00359 #define BACKSQL_AT_MAP_REC_INIT { NULL, NULL, BER_BVC(""), BER_BVC(""), BER_BVNULL, BER_BVNULL, NULL, NULL, NULL, 0, 0, NULL }
00360 
00361 /* define to uppercase filters only if the matching rule requires it
00362  * (currently broken) */
00363 /* #define    BACKSQL_UPPERCASE_FILTER */
00364 
00365 #define       BACKSQL_AT_CANUPPERCASE(at) ( !BER_BVISNULL( &(at)->bam_sel_expr_u ) )
00366 
00367 /* defines to support bitmasks above */
00368 #define BACKSQL_ADD  0x1
00369 #define BACKSQL_DEL  0x2
00370 
00371 #define BACKSQL_IS_ADD(x)   ( ( BACKSQL_ADD & (x) ) == BACKSQL_ADD )
00372 #define BACKSQL_IS_DEL(x)   ( ( BACKSQL_DEL & (x) ) == BACKSQL_DEL )
00373 
00374 #define BACKSQL_NCMP(v1,v2) ber_bvcmp((v1),(v2))
00375 
00376 #define BACKSQL_CONCAT
00377 /*
00378  * berbuf structure: a berval with a buffer size associated
00379  */
00380 typedef struct berbuf {
00381        struct berval bb_val;
00382        ber_len_t     bb_len;
00383 } BerBuffer;
00384 
00385 #define BB_NULL             { BER_BVNULL, 0 }
00386 
00387 /*
00388  * Entry ID structure
00389  */
00390 typedef struct backsql_entryID {
00391        /* #define BACKSQL_ARBITRARY_KEY to allow a non-numeric key.
00392         * It is required by some special applications that use
00393         * strings as keys for the main table.
00394         * In this case, #define BACKSQL_MAX_KEY_LEN consistently
00395         * with the key size definition */
00396 #ifdef BACKSQL_ARBITRARY_KEY
00397        struct berval        eid_id;
00398        struct berval        eid_keyval;
00399 #define BACKSQL_MAX_KEY_LEN 64
00400 #else /* ! BACKSQL_ARBITRARY_KEY */
00401        /* The original numeric key is maintained as default. */
00402        backsql_key_t        eid_id;
00403        backsql_key_t        eid_keyval;
00404 #endif /* ! BACKSQL_ARBITRARY_KEY */
00405 
00406        backsql_key_t        eid_oc_id;
00407        backsql_oc_map_rec   *eid_oc;
00408        struct berval        eid_dn;
00409        struct berval        eid_ndn;
00410        struct backsql_entryID      *eid_next;
00411 } backsql_entryID;
00412 
00413 #ifdef BACKSQL_ARBITRARY_KEY
00414 #define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, NULL, BER_BVNULL, BER_BVNULL, NULL }
00415 #else /* ! BACKSQL_ARBITRARY_KEY */
00416 #define BACKSQL_ENTRYID_INIT { 0, 0, 0, NULL, BER_BVNULL, BER_BVNULL, NULL }
00417 #endif /* BACKSQL_ARBITRARY_KEY */
00418 
00419 /* the function must collect the entry associated to nbase */
00420 #define BACKSQL_ISF_GET_ID  0x1U
00421 #define BACKSQL_ISF_GET_ENTRY      ( 0x2U | BACKSQL_ISF_GET_ID )
00422 #define BACKSQL_ISF_GET_OC  ( 0x4U | BACKSQL_ISF_GET_ID )
00423 #define BACKSQL_ISF_MATCHED 0x8U
00424 #define BACKSQL_IS_GET_ID(f) \
00425        ( ( (f) & BACKSQL_ISF_GET_ID ) == BACKSQL_ISF_GET_ID )
00426 #define BACKSQL_IS_GET_ENTRY(f) \
00427        ( ( (f) & BACKSQL_ISF_GET_ENTRY ) == BACKSQL_ISF_GET_ENTRY )
00428 #define BACKSQL_IS_GET_OC(f) \
00429        ( ( (f) & BACKSQL_ISF_GET_OC ) == BACKSQL_ISF_GET_OC )
00430 #define BACKSQL_IS_MATCHED(f) \
00431        ( ( (f) & BACKSQL_ISF_MATCHED ) == BACKSQL_ISF_MATCHED )
00432 typedef struct backsql_srch_info {
00433        Operation            *bsi_op;
00434        SlapReply            *bsi_rs;
00435 
00436        unsigned             bsi_flags;
00437 #define       BSQL_SF_NONE                0x0000U
00438 #define       BSQL_SF_ALL_USER            0x0001U
00439 #define       BSQL_SF_ALL_OPER            0x0002U
00440 #define       BSQL_SF_ALL_ATTRS           (BSQL_SF_ALL_USER|BSQL_SF_ALL_OPER)
00441 #define BSQL_SF_FILTER_HASSUBORDINATE     0x0010U
00442 #define BSQL_SF_FILTER_ENTRYUUID   0x0020U
00443 #define BSQL_SF_FILTER_ENTRYCSN           0x0040U
00444 #define BSQL_SF_RETURN_ENTRYUUID   (BSQL_SF_FILTER_ENTRYUUID << 8)
00445 #define       BSQL_ISF(bsi, f)            ( ( (bsi)->bsi_flags & f ) == f )
00446 #define       BSQL_ISF_ALL_USER(bsi)             BSQL_ISF(bsi, BSQL_SF_ALL_USER)
00447 #define       BSQL_ISF_ALL_OPER(bsi)             BSQL_ISF(bsi, BSQL_SF_ALL_OPER)
00448 #define       BSQL_ISF_ALL_ATTRS(bsi)            BSQL_ISF(bsi, BSQL_SF_ALL_ATTRS)
00449 
00450        struct berval        *bsi_base_ndn;
00451        int                  bsi_use_subtree_shortcut;
00452        backsql_entryID             bsi_base_id;
00453        int                  bsi_scope;
00454 /* BACKSQL_SCOPE_BASE_LIKE can be set by API in ors_scope
00455  * whenever the search base DN contains chars that cannot
00456  * be mapped into the charset used in the RDBMS; so they're
00457  * turned into '%' and an approximate ('LIKE') condition
00458  * is used */
00459 #define BACKSQL_SCOPE_BASE_LIKE           ( LDAP_SCOPE_BASE | 0x1000 )
00460        Filter               *bsi_filter;
00461        time_t               bsi_stoptime;
00462 
00463        backsql_entryID             *bsi_id_list,
00464                             **bsi_id_listtail,
00465                             *bsi_c_eid;
00466        int                  bsi_n_candidates;
00467        int                  bsi_status;
00468 
00469        backsql_oc_map_rec   *bsi_oc;
00470        struct berbuf        bsi_sel,
00471                             bsi_from,
00472                             bsi_join_where,
00473                             bsi_flt_where;
00474        ObjectClass          *bsi_filter_oc;
00475        SQLHDBC                     bsi_dbh;
00476        AttributeName        *bsi_attrs;
00477 
00478        Entry                *bsi_e;
00479 } backsql_srch_info;
00480 
00481 /*
00482  * Backend private data structure
00483  */
00484 typedef struct backsql_info {
00485        char          *sql_dbhost;
00486        int           sql_dbport;
00487        char          *sql_dbuser;
00488        char          *sql_dbpasswd;
00489        char          *sql_dbname;
00490 
00491        /*
00492         * SQL condition for subtree searches differs in syntax:
00493         * "LIKE CONCAT('%',?)" or "LIKE '%'+?" or "LIKE '%'||?"
00494         * or smtg else 
00495         */
00496        struct berval sql_subtree_cond;
00497        struct berval sql_children_cond;
00498        struct berval sql_dn_match_cond;
00499        char          *sql_oc_query;
00500        char          *sql_at_query;
00501        char          *sql_insentry_stmt;
00502        char          *sql_delentry_stmt;
00503        char          *sql_renentry_stmt;
00504        char          *sql_delobjclasses_stmt;
00505        char          *sql_id_query;
00506        char          *sql_has_children_query;
00507        char          *sql_list_children_query;
00508 
00509        MatchingRule  *sql_caseIgnoreMatch;
00510        MatchingRule  *sql_telephoneNumberMatch;
00511 
00512        struct berval sql_upper_func;
00513        struct berval sql_upper_func_open;
00514        struct berval sql_upper_func_close;
00515        struct berval sql_strcast_func;
00516        BerVarray     sql_concat_func;
00517        char          *sql_concat_patt;
00518 
00519        struct berval sql_aliasing;
00520        struct berval sql_aliasing_quote;
00521        struct berval sql_dn_oc_aliasing;
00522 
00523        AttributeName *sql_anlist;
00524 
00525        unsigned int  sql_flags;
00526 #define       BSQLF_SCHEMA_LOADED         0x0001
00527 #define       BSQLF_UPPER_NEEDS_CAST             0x0002
00528 #define       BSQLF_CREATE_NEEDS_SELECT   0x0004
00529 #define       BSQLF_FAIL_IF_NO_MAPPING    0x0008
00530 #define BSQLF_HAS_LDAPINFO_DN_RU   0x0010
00531 #define BSQLF_DONTCHECK_LDAPINFO_DN_RU    0x0020
00532 #define BSQLF_USE_REVERSE_DN              0x0040
00533 #define BSQLF_ALLOW_ORPHANS        0x0080
00534 #define BSQLF_USE_SUBTREE_SHORTCUT 0x0100
00535 #define BSQLF_FETCH_ALL_USERATTRS  0x0200
00536 #define BSQLF_FETCH_ALL_OPATTRS           0x0400
00537 #define       BSQLF_FETCH_ALL_ATTRS              (BSQLF_FETCH_ALL_USERATTRS|BSQLF_FETCH_ALL_OPATTRS)
00538 #define BSQLF_CHECK_SCHEMA         0x0800
00539 #define BSQLF_AUTOCOMMIT_ON        0x1000
00540 
00541 #define BACKSQL_ISF(si, f) \
00542        (((si)->sql_flags & f) == f)
00543 
00544 #define       BACKSQL_SCHEMA_LOADED(si) \
00545        BACKSQL_ISF(si, BSQLF_SCHEMA_LOADED)
00546 #define BACKSQL_UPPER_NEEDS_CAST(si) \
00547        BACKSQL_ISF(si, BSQLF_UPPER_NEEDS_CAST)
00548 #define BACKSQL_CREATE_NEEDS_SELECT(si) \
00549        BACKSQL_ISF(si, BSQLF_CREATE_NEEDS_SELECT)
00550 #define BACKSQL_FAIL_IF_NO_MAPPING(si) \
00551        BACKSQL_ISF(si, BSQLF_FAIL_IF_NO_MAPPING)
00552 #define BACKSQL_HAS_LDAPINFO_DN_RU(si) \
00553        BACKSQL_ISF(si, BSQLF_HAS_LDAPINFO_DN_RU)
00554 #define BACKSQL_DONTCHECK_LDAPINFO_DN_RU(si) \
00555        BACKSQL_ISF(si, BSQLF_DONTCHECK_LDAPINFO_DN_RU)
00556 #define BACKSQL_USE_REVERSE_DN(si) \
00557        BACKSQL_ISF(si, BSQLF_USE_REVERSE_DN)
00558 #define BACKSQL_CANUPPERCASE(si) \
00559        (!BER_BVISNULL( &(si)->sql_upper_func ))
00560 #define BACKSQL_ALLOW_ORPHANS(si) \
00561        BACKSQL_ISF(si, BSQLF_ALLOW_ORPHANS)
00562 #define BACKSQL_USE_SUBTREE_SHORTCUT(si) \
00563        BACKSQL_ISF(si, BSQLF_USE_SUBTREE_SHORTCUT)
00564 #define BACKSQL_FETCH_ALL_USERATTRS(si) \
00565        BACKSQL_ISF(si, BSQLF_FETCH_ALL_USERATTRS)
00566 #define BACKSQL_FETCH_ALL_OPATTRS(si) \
00567        BACKSQL_ISF(si, BSQLF_FETCH_ALL_OPATTRS)
00568 #define BACKSQL_FETCH_ALL_ATTRS(si) \
00569        BACKSQL_ISF(si, BSQLF_FETCH_ALL_ATTRS)
00570 #define BACKSQL_CHECK_SCHEMA(si) \
00571        BACKSQL_ISF(si, BSQLF_CHECK_SCHEMA)
00572 #define BACKSQL_AUTOCOMMIT_ON(si) \
00573        BACKSQL_ISF(si, BSQLF_AUTOCOMMIT_ON)
00574 
00575        Entry         *sql_baseObject;
00576        char          *sql_base_ob_file;
00577 #ifdef BACKSQL_ARBITRARY_KEY
00578 #define BACKSQL_BASEOBJECT_IDSTR   "baseObject"
00579 #define BACKSQL_BASEOBJECT_KEYVAL  BACKSQL_BASEOBJECT_IDSTR
00580 #define       BACKSQL_IS_BASEOBJECT_ID(id)       (bvmatch((id), &backsql_baseObject_bv))
00581 #else /* ! BACKSQL_ARBITRARY_KEY */
00582 #define BACKSQL_BASEOBJECT_ID             0
00583 #define BACKSQL_BASEOBJECT_IDSTR   LDAP_XSTRING(BACKSQL_BASEOBJECT_ID)
00584 #define BACKSQL_BASEOBJECT_KEYVAL  0
00585 #define       BACKSQL_IS_BASEOBJECT_ID(id)       (*(id) == BACKSQL_BASEOBJECT_ID)
00586 #endif /* ! BACKSQL_ARBITRARY_KEY */
00587 #define BACKSQL_BASEOBJECT_OC             0
00588        
00589        Avlnode              *sql_db_conns;
00590        SQLHDBC              sql_dbh;
00591        ldap_pvt_thread_mutex_t            sql_dbconn_mutex;
00592        Avlnode              *sql_oc_by_oc;
00593        Avlnode              *sql_oc_by_id;
00594        ldap_pvt_thread_mutex_t            sql_schema_mutex;
00595        SQLHENV              sql_db_env;
00596 
00597        backsql_api   *sql_api;
00598 } backsql_info;
00599 
00600 #define BACKSQL_SUCCESS( rc ) \
00601        ( (rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO )
00602 
00603 #define BACKSQL_AVL_STOP           0
00604 #define BACKSQL_AVL_CONTINUE              1
00605 
00606 /* see ldap.h for the meaning of the macros and of the values */
00607 #define BACKSQL_LEGAL_ERROR( rc ) \
00608        ( LDAP_RANGE( (rc), 0x00, 0x0e ) \
00609          || LDAP_ATTR_ERROR( (rc) ) \
00610          || LDAP_NAME_ERROR( (rc) ) \
00611          || LDAP_SECURITY_ERROR( (rc) ) \
00612          || LDAP_SERVICE_ERROR( (rc) ) \
00613          || LDAP_UPDATE_ERROR( (rc) ) )
00614 #define BACKSQL_SANITIZE_ERROR( rc ) \
00615        ( BACKSQL_LEGAL_ERROR( (rc) ) ? (rc) : LDAP_OTHER )
00616 
00617 #define BACKSQL_IS_BINARY(ct) \
00618        ( (ct) == SQL_BINARY \
00619          || (ct) == SQL_VARBINARY \
00620          || (ct) == SQL_LONGVARBINARY)
00621 
00622 #ifdef BACKSQL_ARBITRARY_KEY
00623 #define BACKSQL_IDFMT "%s"
00624 #define BACKSQL_IDARG(arg) ((arg).bv_val)
00625 #else /* ! BACKSQL_ARBITRARY_KEY */
00626 #define BACKSQL_IDFMT BACKSQL_IDNUMFMT
00627 #define BACKSQL_IDARG(arg) (arg)
00628 #endif /* ! BACKSQL_ARBITRARY_KEY */
00629 
00630 #endif /* __BACKSQL_H__ */
00631