1 /* $NetBSD: back-sql.h,v 1.3 2021/08/14 16:15:01 christos Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1999-2021 The OpenLDAP Foundation. 7 * Portions Copyright 1999 Dmitry Kovalev. 8 * Portions Copyright 2002 Pierangelo Mararati. 9 * Portions Copyright 2004 Mark Adamson. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted only as authorized by the OpenLDAP 14 * Public License. 15 * 16 * A copy of this license is available in the file LICENSE in the 17 * top-level directory of the distribution or, alternatively, at 18 * <http://www.OpenLDAP.org/license.html>. 19 */ 20 /* ACKNOWLEDGEMENTS: 21 * This work was initially developed by Dmitry Kovalev for inclusion 22 * by OpenLDAP Software. Additional significant contributors include 23 * Pierangelo Masarati and Mark Adamson. 24 */ 25 /* 26 * The following changes have been addressed: 27 * 28 * Enhancements: 29 * - re-styled code for better readability 30 * - upgraded backend API to reflect recent changes 31 * - LDAP schema is checked when loading SQL/LDAP mapping 32 * - AttributeDescription/ObjectClass pointers used for more efficient 33 * mapping lookup 34 * - bervals used where string length is required often 35 * - atomized write operations by committing at the end of each operation 36 * and defaulting connection closure to rollback 37 * - added LDAP access control to write operations 38 * - fully implemented modrdn (with rdn attrs change, deleteoldrdn, 39 * access check, parent/children check and more) 40 * - added parent access control, children control to delete operation 41 * - added structuralObjectClass operational attribute check and 42 * value return on search 43 * - added hasSubordinate operational attribute on demand 44 * - search limits are appropriately enforced 45 * - function backsql_strcat() has been made more efficient 46 * - concat function has been made configurable by means of a pattern 47 * - added config switches: 48 * - fail_if_no_mapping write operations fail if there is no mapping 49 * - has_ldapinfo_dn_ru overrides autodetect 50 * - concat_pattern a string containing two '?' is used 51 * (note that "?||?" should be more portable 52 * than builtin function "CONCAT(?,?)") 53 * - strcast_func cast of string constants in "SELECT DISTINCT 54 * statements (needed by PostgreSQL) 55 * - upper_needs_cast cast the argument of upper when required 56 * (basically when building dn substring queries) 57 * - added noop control 58 * - added values return filter control 59 * - hasSubordinate can be used in search filters (with limitations) 60 * - eliminated oc->name; use oc->oc->soc_cname instead 61 * 62 * Todo: 63 * - add security checks for SQL statements that can be injected (?) 64 * - re-test with previously supported RDBMs 65 * - replace dn_ru and so with normalized dn (no need for upper() and so 66 * in dn match) 67 * - implement a backsql_normalize() function to replace the upper() 68 * conversion routines 69 * - note that subtree deletion, subtree renaming and so could be easily 70 * implemented (rollback and consistency checks are available :) 71 * - implement "lastmod" and other operational stuff (ldap_entries table ?) 72 * - check how to allow multiple operations with one statement, to remove 73 * BACKSQL_REALLOC_STMT from modify.c (a more recent unixODBC lib?) 74 */ 75 /* 76 * Improvements submitted by (ITS#3432) 77 * 78 * 1. id_query.patch applied (with changes) 79 * 2. shortcut.patch applied (reworked) 80 * 3. create_hint.patch applied 81 * 4. count_query.patch applied (reworked) 82 * 5. returncodes.patch applied (with sanity checks) 83 * 6. connpool.patch under evaluation 84 * 7. modoc.patch under evaluation (requires 85 * manageDSAit and "manage" 86 * access privileges) 87 * 8. miscfixes.patch applied (reworked; other 88 * operations need to load the 89 * entire entry for ACL purposes; 90 * see ITS#3480, now fixed) 91 * 92 * original description: 93 94 Changes that were made to the SQL backend. 95 96 The patches were made against 2.2.18 and can be applied individually, 97 but would best be applied in the numerical order of the file names. 98 A synopsis of each patch is given here: 99 100 101 1. Added an option to set SQL query for the "id_query" operation. 102 103 2. Added an option to the SQL backend called "use_subtree_shortcut". 104 When a search is performed, the SQL query includes a WHERE clause 105 which says the DN must be "LIKE %<searchbase>". The LIKE operation 106 can be slow in an RDBM. This shortcut option says that if the 107 searchbase of the LDAP search is the root DN of the SQL backend, 108 and thus all objects will match the LIKE operator, do not include 109 the "LIKE %<searchbase>" clause in the SQL query (it is replaced 110 instead by the always true "1=1" clause to keep the "AND"'s 111 working correctly). This option is off by default, and should be 112 turned on only if all objects to be found in the RDBM are under the 113 same root DN. Multiple backends working within the same RDBM table 114 space would encounter problems. LDAP searches whose searchbase are 115 not at the root DN will bypass this shortcut and employ the LIKE 116 clause. 117 118 3. Added a "create_hint" column to ldap_oc_mappings table. Allows 119 taking the value of an attr named in "create_hint" and passing it to 120 the create_proc procedure. This is necessary for when an objectClass's 121 table is partition indexed by some indexing column and thus the value 122 in that indexing column cannot change after the row is created. The 123 value for the indexed column is passed into the create_proc, which 124 uses it to fill in the indexed column as the new row is created. 125 126 4. When loading the values of an attribute, the count(*) of the number 127 of values is fetched first and memory is allocated for the array of 128 values and normalized values. The old system of loading the values one 129 by one and running realloc() on the array of values and normalized 130 values each time was badly fragmenting memory. The array of values and 131 normalized values would be side by side in memory, and realloc()'ing 132 them over and over would force them to leapfrog each other through all 133 of available memory. Attrs with a large number of values could not be 134 loaded without crashing the slapd daemon. 135 136 5. Added code to interpret the value returned by stored procedures 137 which have expect_return set. Returned value is interpreted as an LDAP 138 return code. This allows the distinction between the SQL failing to 139 execute and the SQL running to completion and returning an error code 140 which can indicate a policy violation. 141 142 6. Added RDBM connection pooling. Once an operation is finished the 143 connection to the RDBM is returned to a pool rather than closing. 144 Allows the next operation to skip the initialization and authentication 145 phases of contacting the RDBM. Also, if licensing with ODBC places 146 a limit on the number of connections, an LDAP thread can block waiting 147 for another thread to finish, so that no LDAP errors are returned 148 for having more LDAP connections than allowed RDBM connections. An 149 RDBM connection which receives an SQL error is marked as "tainted" 150 so that it will be closed rather than returned to the pool. 151 Also, RDBM connections must be bound to a given LDAP connection AND 152 operation number, and NOT just the connection number. Asynchronous 153 LDAP clients can have multiple simultaneous LDAP operations which 154 should not share the same RDBM connection. A given LDAP operation can 155 even make multiple SQL operations (e.g. a BIND operation which 156 requires SASL to perform an LDAP search to convert the SASL ID to an 157 LDAP DN), so each RDBM connection now has a refcount that must reach 158 zero before the connection is returned to the free pool. 159 160 7. Added ability to change the objectClass of an object. Required 161 considerable work to copy all attributes out of old object and into 162 new object. Does a schema check before proceeding. Creates a new 163 object, fills it in, deletes the old object, then changes the 164 oc_map_id and keyval of the entry in the "ldap_entries" table. 165 166 8. Generic fixes. Includes initializing pointers before they 167 get used in error branch cases, pointer checks before dereferencing, 168 resetting a return code to success after a COMPARE op, sealing 169 memory leaks, and in search.c, changing some of the "1=1" tests to 170 "2=2", "3=3", etc so that when reading slapd trace output, the 171 location in the source code where the x=x test was added to the SQL 172 can be easily distinguished. 173 */ 174 175 #ifndef __BACKSQL_H__ 176 #define __BACKSQL_H__ 177 178 /* former sql-types.h */ 179 #include <sql.h> 180 #include <sqlext.h> 181 182 typedef struct { 183 SWORD ncols; 184 BerVarray col_names; 185 UDWORD *col_prec; 186 SQLSMALLINT *col_type; 187 char **cols; 188 SQLLEN *value_len; 189 } BACKSQL_ROW_NTS; 190 191 /* 192 * Better use the standard length of 8192 (as of slap.h)? 193 * 194 * NOTE: must be consistent with definition in ldap_entries table 195 */ 196 /* #define BACKSQL_MAX_DN_LEN SLAP_LDAPDN_MAXLEN */ 197 #define BACKSQL_MAX_DN_LEN 255 198 199 /* 200 * define to enable very extensive trace logging (debug only) 201 */ 202 #undef BACKSQL_TRACE 203 204 /* 205 * define if using MS SQL and workaround needed (see sql-wrap.c) 206 */ 207 #undef BACKSQL_MSSQL_WORKAROUND 208 209 /* 210 * define to enable values counting for attributes 211 */ 212 #define BACKSQL_COUNTQUERY 213 214 /* 215 * define to enable prettification/validation of values 216 */ 217 #define BACKSQL_PRETTY_VALIDATE 218 219 /* 220 * define to enable varchars as unique keys in user tables 221 * 222 * by default integers are used (and recommended) 223 * for performances. Integers are used anyway in back-sql 224 * related tables. 225 */ 226 #undef BACKSQL_ARBITRARY_KEY 227 228 /* 229 * type used for keys 230 */ 231 #if defined(HAVE_LONG_LONG) && defined(SQL_C_UBIGINT) && \ 232 ( defined(HAVE_STRTOULL) || defined(HAVE_STRTOUQ) ) 233 typedef unsigned long long backsql_key_t; 234 #define BACKSQL_C_NUMID SQL_C_UBIGINT 235 #define BACKSQL_IDNUMFMT "%llu" 236 #define BACKSQL_STR2ID lutil_atoullx 237 #else /* ! HAVE_LONG_LONG || ! SQL_C_UBIGINT */ 238 typedef unsigned long backsql_key_t; 239 #define BACKSQL_C_NUMID SQL_C_ULONG 240 #define BACKSQL_IDNUMFMT "%lu" 241 #define BACKSQL_STR2ID lutil_atoulx 242 #endif /* ! HAVE_LONG_LONG */ 243 244 /* 245 * define to enable support for syncprov overlay 246 */ 247 #define BACKSQL_SYNCPROV 248 249 /* 250 * define to the appropriate aliasing string 251 * 252 * some RDBMSes tolerate (or require) that " AS " is not used 253 * when aliasing tables/columns 254 */ 255 #define BACKSQL_ALIASING "AS " 256 /* #define BACKSQL_ALIASING "" */ 257 258 /* 259 * define to the appropriate quoting char 260 * 261 * some RDBMSes tolerate/require that the aliases be enclosed 262 * in quotes. This is especially true for those that do not 263 * allow keywords used as aliases. 264 */ 265 #define BACKSQL_ALIASING_QUOTE "" 266 /* #define BACKSQL_ALIASING_QUOTE "\"" */ 267 /* #define BACKSQL_ALIASING_QUOTE "'" */ 268 269 /* 270 * API 271 * 272 * a simple mechanism to allow DN mucking between the LDAP 273 * and the stored string representation. 274 */ 275 typedef struct backsql_api { 276 char *ba_name; 277 int (*ba_config)( struct backsql_api *self, int argc, char *argv[] ); 278 int (*ba_destroy)( struct backsql_api *self ); 279 280 int (*ba_dn2odbc)( Operation *op, SlapReply *rs, struct berval *dn ); 281 int (*ba_odbc2dn)( Operation *op, SlapReply *rs, struct berval *dn ); 282 283 void *ba_private; 284 struct backsql_api *ba_next; 285 char **ba_argv; 286 int ba_argc; 287 } backsql_api; 288 289 /* 290 * "structural" objectClass mapping structure 291 */ 292 typedef struct backsql_oc_map_rec { 293 /* 294 * Structure of corresponding LDAP objectClass definition 295 */ 296 ObjectClass *bom_oc; 297 #define BACKSQL_OC_NAME(ocmap) ((ocmap)->bom_oc->soc_cname.bv_val) 298 299 struct berval bom_keytbl; 300 struct berval bom_keycol; 301 /* expected to return keyval of newly created entry */ 302 char *bom_create_proc; 303 /* in case create_proc does not return the keyval of the newly 304 * created row */ 305 char *bom_create_keyval; 306 /* supposed to expect keyval as parameter and delete 307 * all the attributes as well */ 308 char *bom_delete_proc; 309 /* flags whether delete_proc is a function (whether back-sql 310 * should bind first parameter as output for return code) */ 311 int bom_expect_return; 312 backsql_key_t bom_id; 313 Avlnode *bom_attrs; 314 AttributeDescription *bom_create_hint; 315 } backsql_oc_map_rec; 316 317 /* 318 * attributeType mapping structure 319 */ 320 typedef struct backsql_at_map_rec { 321 /* Description of corresponding LDAP attribute type */ 322 AttributeDescription *bam_ad; 323 AttributeDescription *bam_true_ad; 324 /* ObjectClass if bam_ad is objectClass */ 325 ObjectClass *bam_oc; 326 327 struct berval bam_from_tbls; 328 struct berval bam_join_where; 329 struct berval bam_sel_expr; 330 331 /* TimesTen, or, if a uppercase function is defined, 332 * an uppercased version of bam_sel_expr */ 333 struct berval bam_sel_expr_u; 334 335 /* supposed to expect 2 binded values: entry keyval 336 * and attr. value to add, like "add_name(?,?,?)" */ 337 char *bam_add_proc; 338 /* supposed to expect 2 binded values: entry keyval 339 * and attr. value to delete */ 340 char *bam_delete_proc; 341 /* for optimization purposes attribute load query 342 * is preconstructed from parts on schemamap load time */ 343 char *bam_query; 344 #ifdef BACKSQL_COUNTQUERY 345 char *bam_countquery; 346 #endif /* BACKSQL_COUNTQUERY */ 347 /* following flags are bitmasks (first bit used for add_proc, 348 * second - for delete_proc) */ 349 /* order of parameters for procedures above; 350 * 1 means "data then keyval", 0 means "keyval then data" */ 351 int bam_param_order; 352 /* flags whether one or more of procedures is a function 353 * (whether back-sql should bind first parameter as output 354 * for return code) */ 355 int bam_expect_return; 356 357 /* next mapping for attribute */ 358 struct backsql_at_map_rec *bam_next; 359 } backsql_at_map_rec; 360 361 #define BACKSQL_AT_MAP_REC_INIT { NULL, NULL, BER_BVC(""), BER_BVC(""), BER_BVNULL, BER_BVNULL, NULL, NULL, NULL, 0, 0, NULL } 362 363 /* define to uppercase filters only if the matching rule requires it 364 * (currently broken) */ 365 /* #define BACKSQL_UPPERCASE_FILTER */ 366 367 #define BACKSQL_AT_CANUPPERCASE(at) ( !BER_BVISNULL( &(at)->bam_sel_expr_u ) ) 368 369 /* defines to support bitmasks above */ 370 #define BACKSQL_ADD 0x1 371 #define BACKSQL_DEL 0x2 372 373 #define BACKSQL_IS_ADD(x) ( ( BACKSQL_ADD & (x) ) == BACKSQL_ADD ) 374 #define BACKSQL_IS_DEL(x) ( ( BACKSQL_DEL & (x) ) == BACKSQL_DEL ) 375 376 #define BACKSQL_NCMP(v1,v2) ber_bvcmp((v1),(v2)) 377 378 #define BACKSQL_CONCAT 379 /* 380 * berbuf structure: a berval with a buffer size associated 381 */ 382 typedef struct berbuf { 383 struct berval bb_val; 384 ber_len_t bb_len; 385 } BerBuffer; 386 387 #define BB_NULL { BER_BVNULL, 0 } 388 389 /* 390 * Entry ID structure 391 */ 392 typedef struct backsql_entryID { 393 /* #define BACKSQL_ARBITRARY_KEY to allow a non-numeric key. 394 * It is required by some special applications that use 395 * strings as keys for the main table. 396 * In this case, #define BACKSQL_MAX_KEY_LEN consistently 397 * with the key size definition */ 398 #ifdef BACKSQL_ARBITRARY_KEY 399 struct berval eid_id; 400 struct berval eid_keyval; 401 #define BACKSQL_MAX_KEY_LEN 64 402 #else /* ! BACKSQL_ARBITRARY_KEY */ 403 /* The original numeric key is maintained as default. */ 404 backsql_key_t eid_id; 405 backsql_key_t eid_keyval; 406 #endif /* ! BACKSQL_ARBITRARY_KEY */ 407 408 backsql_key_t eid_oc_id; 409 backsql_oc_map_rec *eid_oc; 410 struct berval eid_dn; 411 struct berval eid_ndn; 412 struct backsql_entryID *eid_next; 413 } backsql_entryID; 414 415 #ifdef BACKSQL_ARBITRARY_KEY 416 #define BACKSQL_ENTRYID_INIT { BER_BVNULL, BER_BVNULL, 0, NULL, BER_BVNULL, BER_BVNULL, NULL } 417 #else /* ! BACKSQL_ARBITRARY_KEY */ 418 #define BACKSQL_ENTRYID_INIT { 0, 0, 0, NULL, BER_BVNULL, BER_BVNULL, NULL } 419 #endif /* BACKSQL_ARBITRARY_KEY */ 420 421 /* the function must collect the entry associated to nbase */ 422 #define BACKSQL_ISF_GET_ID 0x1U 423 #define BACKSQL_ISF_GET_ENTRY ( 0x2U | BACKSQL_ISF_GET_ID ) 424 #define BACKSQL_ISF_GET_OC ( 0x4U | BACKSQL_ISF_GET_ID ) 425 #define BACKSQL_ISF_MATCHED 0x8U 426 #define BACKSQL_IS_GET_ID(f) \ 427 ( ( (f) & BACKSQL_ISF_GET_ID ) == BACKSQL_ISF_GET_ID ) 428 #define BACKSQL_IS_GET_ENTRY(f) \ 429 ( ( (f) & BACKSQL_ISF_GET_ENTRY ) == BACKSQL_ISF_GET_ENTRY ) 430 #define BACKSQL_IS_GET_OC(f) \ 431 ( ( (f) & BACKSQL_ISF_GET_OC ) == BACKSQL_ISF_GET_OC ) 432 #define BACKSQL_IS_MATCHED(f) \ 433 ( ( (f) & BACKSQL_ISF_MATCHED ) == BACKSQL_ISF_MATCHED ) 434 typedef struct backsql_srch_info { 435 Operation *bsi_op; 436 SlapReply *bsi_rs; 437 438 unsigned bsi_flags; 439 #define BSQL_SF_NONE 0x0000U 440 #define BSQL_SF_ALL_USER 0x0001U 441 #define BSQL_SF_ALL_OPER 0x0002U 442 #define BSQL_SF_ALL_ATTRS (BSQL_SF_ALL_USER|BSQL_SF_ALL_OPER) 443 #define BSQL_SF_FILTER_HASSUBORDINATE 0x0010U 444 #define BSQL_SF_FILTER_ENTRYUUID 0x0020U 445 #define BSQL_SF_FILTER_ENTRYCSN 0x0040U 446 #define BSQL_SF_RETURN_ENTRYUUID (BSQL_SF_FILTER_ENTRYUUID << 8) 447 #define BSQL_ISF(bsi, f) ( ( (bsi)->bsi_flags & f ) == f ) 448 #define BSQL_ISF_ALL_USER(bsi) BSQL_ISF(bsi, BSQL_SF_ALL_USER) 449 #define BSQL_ISF_ALL_OPER(bsi) BSQL_ISF(bsi, BSQL_SF_ALL_OPER) 450 #define BSQL_ISF_ALL_ATTRS(bsi) BSQL_ISF(bsi, BSQL_SF_ALL_ATTRS) 451 452 struct berval *bsi_base_ndn; 453 int bsi_use_subtree_shortcut; 454 backsql_entryID bsi_base_id; 455 int bsi_scope; 456 /* BACKSQL_SCOPE_BASE_LIKE can be set by API in ors_scope 457 * whenever the search base DN contains chars that cannot 458 * be mapped into the charset used in the RDBMS; so they're 459 * turned into '%' and an approximate ('LIKE') condition 460 * is used */ 461 #define BACKSQL_SCOPE_BASE_LIKE ( LDAP_SCOPE_BASE | 0x1000 ) 462 Filter *bsi_filter; 463 time_t bsi_stoptime; 464 465 backsql_entryID *bsi_id_list, 466 **bsi_id_listtail, 467 *bsi_c_eid; 468 int bsi_n_candidates; 469 int bsi_status; 470 471 backsql_oc_map_rec *bsi_oc; 472 struct berbuf bsi_sel, 473 bsi_from, 474 bsi_join_where, 475 bsi_flt_where; 476 ObjectClass *bsi_filter_oc; 477 SQLHDBC bsi_dbh; 478 AttributeName *bsi_attrs; 479 480 Entry *bsi_e; 481 } backsql_srch_info; 482 483 /* 484 * Backend private data structure 485 */ 486 typedef struct backsql_info { 487 char *sql_dbhost; 488 int sql_dbport; 489 char *sql_dbuser; 490 char *sql_dbpasswd; 491 char *sql_dbname; 492 493 /* 494 * SQL condition for subtree searches differs in syntax: 495 * "LIKE CONCAT('%',?)" or "LIKE '%'+?" or "LIKE '%'||?" 496 * or smtg else 497 */ 498 struct berval sql_subtree_cond; 499 struct berval sql_children_cond; 500 struct berval sql_dn_match_cond; 501 char *sql_oc_query; 502 char *sql_at_query; 503 char *sql_insentry_stmt; 504 char *sql_delentry_stmt; 505 char *sql_renentry_stmt; 506 char *sql_delobjclasses_stmt; 507 char *sql_id_query; 508 char *sql_has_children_query; 509 char *sql_list_children_query; 510 511 MatchingRule *sql_caseIgnoreMatch; 512 MatchingRule *sql_telephoneNumberMatch; 513 514 struct berval sql_upper_func; 515 struct berval sql_upper_func_open; 516 struct berval sql_upper_func_close; 517 struct berval sql_strcast_func; 518 BerVarray sql_concat_func; 519 char *sql_concat_patt; 520 521 struct berval sql_aliasing; 522 struct berval sql_aliasing_quote; 523 struct berval sql_dn_oc_aliasing; 524 525 AttributeName *sql_anlist; 526 527 unsigned int sql_flags; 528 #define BSQLF_SCHEMA_LOADED 0x0001 529 #define BSQLF_UPPER_NEEDS_CAST 0x0002 530 #define BSQLF_CREATE_NEEDS_SELECT 0x0004 531 #define BSQLF_FAIL_IF_NO_MAPPING 0x0008 532 #define BSQLF_HAS_LDAPINFO_DN_RU 0x0010 533 #define BSQLF_DONTCHECK_LDAPINFO_DN_RU 0x0020 534 #define BSQLF_USE_REVERSE_DN 0x0040 535 #define BSQLF_ALLOW_ORPHANS 0x0080 536 #define BSQLF_USE_SUBTREE_SHORTCUT 0x0100 537 #define BSQLF_FETCH_ALL_USERATTRS 0x0200 538 #define BSQLF_FETCH_ALL_OPATTRS 0x0400 539 #define BSQLF_FETCH_ALL_ATTRS (BSQLF_FETCH_ALL_USERATTRS|BSQLF_FETCH_ALL_OPATTRS) 540 #define BSQLF_CHECK_SCHEMA 0x0800 541 #define BSQLF_AUTOCOMMIT_ON 0x1000 542 543 #define BACKSQL_ISF(si, f) \ 544 (((si)->sql_flags & f) == f) 545 546 #define BACKSQL_SCHEMA_LOADED(si) \ 547 BACKSQL_ISF(si, BSQLF_SCHEMA_LOADED) 548 #define BACKSQL_UPPER_NEEDS_CAST(si) \ 549 BACKSQL_ISF(si, BSQLF_UPPER_NEEDS_CAST) 550 #define BACKSQL_CREATE_NEEDS_SELECT(si) \ 551 BACKSQL_ISF(si, BSQLF_CREATE_NEEDS_SELECT) 552 #define BACKSQL_FAIL_IF_NO_MAPPING(si) \ 553 BACKSQL_ISF(si, BSQLF_FAIL_IF_NO_MAPPING) 554 #define BACKSQL_HAS_LDAPINFO_DN_RU(si) \ 555 BACKSQL_ISF(si, BSQLF_HAS_LDAPINFO_DN_RU) 556 #define BACKSQL_DONTCHECK_LDAPINFO_DN_RU(si) \ 557 BACKSQL_ISF(si, BSQLF_DONTCHECK_LDAPINFO_DN_RU) 558 #define BACKSQL_USE_REVERSE_DN(si) \ 559 BACKSQL_ISF(si, BSQLF_USE_REVERSE_DN) 560 #define BACKSQL_CANUPPERCASE(si) \ 561 (!BER_BVISNULL( &(si)->sql_upper_func )) 562 #define BACKSQL_ALLOW_ORPHANS(si) \ 563 BACKSQL_ISF(si, BSQLF_ALLOW_ORPHANS) 564 #define BACKSQL_USE_SUBTREE_SHORTCUT(si) \ 565 BACKSQL_ISF(si, BSQLF_USE_SUBTREE_SHORTCUT) 566 #define BACKSQL_FETCH_ALL_USERATTRS(si) \ 567 BACKSQL_ISF(si, BSQLF_FETCH_ALL_USERATTRS) 568 #define BACKSQL_FETCH_ALL_OPATTRS(si) \ 569 BACKSQL_ISF(si, BSQLF_FETCH_ALL_OPATTRS) 570 #define BACKSQL_FETCH_ALL_ATTRS(si) \ 571 BACKSQL_ISF(si, BSQLF_FETCH_ALL_ATTRS) 572 #define BACKSQL_CHECK_SCHEMA(si) \ 573 BACKSQL_ISF(si, BSQLF_CHECK_SCHEMA) 574 #define BACKSQL_AUTOCOMMIT_ON(si) \ 575 BACKSQL_ISF(si, BSQLF_AUTOCOMMIT_ON) 576 577 Entry *sql_baseObject; 578 char *sql_base_ob_file; 579 #ifdef BACKSQL_ARBITRARY_KEY 580 #define BACKSQL_BASEOBJECT_IDSTR "baseObject" 581 #define BACKSQL_BASEOBJECT_KEYVAL BACKSQL_BASEOBJECT_IDSTR 582 #define BACKSQL_IS_BASEOBJECT_ID(id) (bvmatch((id), &backsql_baseObject_bv)) 583 #else /* ! BACKSQL_ARBITRARY_KEY */ 584 #define BACKSQL_BASEOBJECT_ID 0 585 #define BACKSQL_BASEOBJECT_IDSTR LDAP_XSTRING(BACKSQL_BASEOBJECT_ID) 586 #define BACKSQL_BASEOBJECT_KEYVAL 0 587 #define BACKSQL_IS_BASEOBJECT_ID(id) (*(id) == BACKSQL_BASEOBJECT_ID) 588 #endif /* ! BACKSQL_ARBITRARY_KEY */ 589 #define BACKSQL_BASEOBJECT_OC 0 590 591 Avlnode *sql_db_conns; 592 SQLHDBC sql_dbh; 593 ldap_pvt_thread_mutex_t sql_dbconn_mutex; 594 Avlnode *sql_oc_by_oc; 595 Avlnode *sql_oc_by_id; 596 ldap_pvt_thread_mutex_t sql_schema_mutex; 597 SQLHENV sql_db_env; 598 599 backsql_api *sql_api; 600 } backsql_info; 601 602 #define BACKSQL_SUCCESS( rc ) \ 603 ( (rc) == SQL_SUCCESS || (rc) == SQL_SUCCESS_WITH_INFO ) 604 605 #define BACKSQL_AVL_STOP 0 606 #define BACKSQL_AVL_CONTINUE 1 607 608 /* see ldap.h for the meaning of the macros and of the values */ 609 #define BACKSQL_LEGAL_ERROR( rc ) \ 610 ( LDAP_RANGE( (rc), 0x00, 0x0e ) \ 611 || LDAP_ATTR_ERROR( (rc) ) \ 612 || LDAP_NAME_ERROR( (rc) ) \ 613 || LDAP_SECURITY_ERROR( (rc) ) \ 614 || LDAP_SERVICE_ERROR( (rc) ) \ 615 || LDAP_UPDATE_ERROR( (rc) ) ) 616 #define BACKSQL_SANITIZE_ERROR( rc ) \ 617 ( BACKSQL_LEGAL_ERROR( (rc) ) ? (rc) : LDAP_OTHER ) 618 619 #define BACKSQL_IS_BINARY(ct) \ 620 ( (ct) == SQL_BINARY \ 621 || (ct) == SQL_VARBINARY \ 622 || (ct) == SQL_LONGVARBINARY) 623 624 #ifdef BACKSQL_ARBITRARY_KEY 625 #define BACKSQL_IDFMT "%s" 626 #define BACKSQL_IDARG(arg) ((arg).bv_val) 627 #else /* ! BACKSQL_ARBITRARY_KEY */ 628 #define BACKSQL_IDFMT BACKSQL_IDNUMFMT 629 #define BACKSQL_IDARG(arg) (arg) 630 #endif /* ! BACKSQL_ARBITRARY_KEY */ 631 632 #endif /* __BACKSQL_H__ */ 633 634