1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1999-2011 The OpenLDAP Foundation. 5 * Portions Copyright 1999 Dmitry Kovalev. 6 * Portions Copyright 2002 Pierangelo Masarati. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17/* ACKNOWLEDGEMENTS: 18 * This work was initially developed by Dmitry Kovalev for inclusion 19 * by OpenLDAP Software. Additional significant contributors include 20 * Pierangelo Masarati. 21 */ 22 23#include "portable.h" 24 25#include <stdio.h> 26#include <sys/types.h> 27#include "ac/string.h" 28 29#include "slap.h" 30#include "config.h" 31#include "proto-sql.h" 32 33int 34sql_back_initialize( 35 BackendInfo *bi ) 36{ 37 static char *controls[] = { 38 LDAP_CONTROL_ASSERT, 39 LDAP_CONTROL_MANAGEDSAIT, 40 LDAP_CONTROL_NOOP, 41#ifdef SLAP_CONTROL_X_TREE_DELETE 42 SLAP_CONTROL_X_TREE_DELETE, 43#endif /* SLAP_CONTROL_X_TREE_DELETE */ 44#ifndef BACKSQL_ARBITRARY_KEY 45 LDAP_CONTROL_PAGEDRESULTS, 46#endif /* ! BACKSQL_ARBITRARY_KEY */ 47 NULL 48 }; 49 int rc; 50 51 bi->bi_controls = controls; 52 53 bi->bi_flags |= 54#if 0 55 SLAP_BFLAG_INCREMENT | 56#endif 57 SLAP_BFLAG_REFERRALS; 58 59 Debug( LDAP_DEBUG_TRACE,"==>sql_back_initialize()\n", 0, 0, 0 ); 60 61 bi->bi_db_init = backsql_db_init; 62 bi->bi_db_config = config_generic_wrapper; 63 bi->bi_db_open = backsql_db_open; 64 bi->bi_db_close = backsql_db_close; 65 bi->bi_db_destroy = backsql_db_destroy; 66 67 bi->bi_op_abandon = 0; 68 bi->bi_op_compare = backsql_compare; 69 bi->bi_op_bind = backsql_bind; 70 bi->bi_op_unbind = 0; 71 bi->bi_op_search = backsql_search; 72 bi->bi_op_modify = backsql_modify; 73 bi->bi_op_modrdn = backsql_modrdn; 74 bi->bi_op_add = backsql_add; 75 bi->bi_op_delete = backsql_delete; 76 77 bi->bi_chk_referrals = 0; 78 bi->bi_operational = backsql_operational; 79 bi->bi_entry_get_rw = backsql_entry_get; 80 bi->bi_entry_release_rw = backsql_entry_release; 81 82 bi->bi_connection_init = 0; 83 84 rc = backsql_init_cf( bi ); 85 Debug( LDAP_DEBUG_TRACE,"<==sql_back_initialize()\n", 0, 0, 0 ); 86 return rc; 87} 88 89int 90backsql_destroy( 91 BackendInfo *bi ) 92{ 93 Debug( LDAP_DEBUG_TRACE, "==>backsql_destroy()\n", 0, 0, 0 ); 94 Debug( LDAP_DEBUG_TRACE, "<==backsql_destroy()\n", 0, 0, 0 ); 95 return 0; 96} 97 98int 99backsql_db_init( 100 BackendDB *bd, 101 ConfigReply *cr ) 102{ 103 backsql_info *bi; 104 int rc = 0; 105 106 Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 ); 107 108 bi = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) ); 109 ldap_pvt_thread_mutex_init( &bi->sql_dbconn_mutex ); 110 ldap_pvt_thread_mutex_init( &bi->sql_schema_mutex ); 111 112 if ( backsql_init_db_env( bi ) != SQL_SUCCESS ) { 113 rc = -1; 114 } 115 116 bd->be_private = bi; 117 118 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 ); 119 120 return rc; 121} 122 123int 124backsql_db_destroy( 125 BackendDB *bd, 126 ConfigReply *cr ) 127{ 128 backsql_info *bi = (backsql_info*)bd->be_private; 129 130 Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 ); 131 132 backsql_free_db_env( bi ); 133 ldap_pvt_thread_mutex_destroy( &bi->sql_dbconn_mutex ); 134 backsql_destroy_schema_map( bi ); 135 ldap_pvt_thread_mutex_destroy( &bi->sql_schema_mutex ); 136 137 if ( bi->sql_dbname ) { 138 ch_free( bi->sql_dbname ); 139 } 140 if ( bi->sql_dbuser ) { 141 ch_free( bi->sql_dbuser ); 142 } 143 if ( bi->sql_dbpasswd ) { 144 ch_free( bi->sql_dbpasswd ); 145 } 146 if ( bi->sql_dbhost ) { 147 ch_free( bi->sql_dbhost ); 148 } 149 if ( bi->sql_upper_func.bv_val ) { 150 ch_free( bi->sql_upper_func.bv_val ); 151 ch_free( bi->sql_upper_func_open.bv_val ); 152 ch_free( bi->sql_upper_func_close.bv_val ); 153 } 154 if ( bi->sql_concat_func ) { 155 ber_bvarray_free( bi->sql_concat_func ); 156 } 157 if ( !BER_BVISNULL( &bi->sql_strcast_func ) ) { 158 ch_free( bi->sql_strcast_func.bv_val ); 159 } 160 if ( !BER_BVISNULL( &bi->sql_children_cond ) ) { 161 ch_free( bi->sql_children_cond.bv_val ); 162 } 163 if ( !BER_BVISNULL( &bi->sql_dn_match_cond ) ) { 164 ch_free( bi->sql_dn_match_cond.bv_val ); 165 } 166 if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) { 167 ch_free( bi->sql_subtree_cond.bv_val ); 168 } 169 if ( !BER_BVISNULL( &bi->sql_dn_oc_aliasing ) ) { 170 ch_free( bi->sql_dn_oc_aliasing.bv_val ); 171 } 172 if ( bi->sql_oc_query ) { 173 ch_free( bi->sql_oc_query ); 174 } 175 if ( bi->sql_at_query ) { 176 ch_free( bi->sql_at_query ); 177 } 178 if ( bi->sql_id_query ) { 179 ch_free( bi->sql_id_query ); 180 } 181 if ( bi->sql_has_children_query ) { 182 ch_free( bi->sql_has_children_query ); 183 } 184 if ( bi->sql_insentry_stmt ) { 185 ch_free( bi->sql_insentry_stmt ); 186 } 187 if ( bi->sql_delentry_stmt ) { 188 ch_free( bi->sql_delentry_stmt ); 189 } 190 if ( bi->sql_renentry_stmt ) { 191 ch_free( bi->sql_renentry_stmt ); 192 } 193 if ( bi->sql_delobjclasses_stmt ) { 194 ch_free( bi->sql_delobjclasses_stmt ); 195 } 196 if ( !BER_BVISNULL( &bi->sql_aliasing ) ) { 197 ch_free( bi->sql_aliasing.bv_val ); 198 } 199 if ( !BER_BVISNULL( &bi->sql_aliasing_quote ) ) { 200 ch_free( bi->sql_aliasing_quote.bv_val ); 201 } 202 203 if ( bi->sql_anlist ) { 204 int i; 205 206 for ( i = 0; !BER_BVISNULL( &bi->sql_anlist[ i ].an_name ); i++ ) 207 { 208 ch_free( bi->sql_anlist[ i ].an_name.bv_val ); 209 } 210 ch_free( bi->sql_anlist ); 211 } 212 213 if ( bi->sql_baseObject ) { 214 entry_free( bi->sql_baseObject ); 215 } 216 217 ch_free( bi ); 218 219 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_destroy()\n", 0, 0, 0 ); 220 return 0; 221} 222 223int 224backsql_db_open( 225 BackendDB *bd, 226 ConfigReply *cr ) 227{ 228 backsql_info *bi = (backsql_info*)bd->be_private; 229 struct berbuf bb = BB_NULL; 230 231 Connection conn = { 0 }; 232 OperationBuffer opbuf; 233 Operation* op; 234 SQLHDBC dbh = SQL_NULL_HDBC; 235 void *thrctx = ldap_pvt_thread_pool_context(); 236 237 Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): " 238 "testing RDBMS connection\n", 0, 0, 0 ); 239 if ( bi->sql_dbname == NULL ) { 240 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 241 "datasource name not specified " 242 "(use \"dbname\" directive in slapd.conf)\n", 0, 0, 0 ); 243 return 1; 244 } 245 246 if ( bi->sql_concat_func == NULL ) { 247 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 248 "concat func not specified (use \"concat_pattern\" " 249 "directive in slapd.conf)\n", 0, 0, 0 ); 250 251 if ( backsql_split_pattern( backsql_def_concat_func, 252 &bi->sql_concat_func, 2 ) ) { 253 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 254 "unable to parse pattern \"%s\"", 255 backsql_def_concat_func, 0, 0 ); 256 return 1; 257 } 258 } 259 260 /* 261 * see back-sql.h for default values 262 */ 263 if ( BER_BVISNULL( &bi->sql_aliasing ) ) { 264 ber_str2bv( BACKSQL_ALIASING, 265 STRLENOF( BACKSQL_ALIASING ), 266 1, &bi->sql_aliasing ); 267 } 268 269 if ( BER_BVISNULL( &bi->sql_aliasing_quote ) ) { 270 ber_str2bv( BACKSQL_ALIASING_QUOTE, 271 STRLENOF( BACKSQL_ALIASING_QUOTE ), 272 1, &bi->sql_aliasing_quote ); 273 } 274 275 /* 276 * Prepare cast string as required 277 */ 278 if ( bi->sql_upper_func.bv_val ) { 279 char buf[1024]; 280 281 if ( BACKSQL_UPPER_NEEDS_CAST( bi ) ) { 282 snprintf( buf, sizeof( buf ), 283 "%s(cast (" /* ? as varchar(%d))) */ , 284 bi->sql_upper_func.bv_val ); 285 ber_str2bv( buf, 0, 1, &bi->sql_upper_func_open ); 286 287 snprintf( buf, sizeof( buf ), 288 /* (cast(? */ " as varchar(%d)))", 289 BACKSQL_MAX_DN_LEN ); 290 ber_str2bv( buf, 0, 1, &bi->sql_upper_func_close ); 291 292 } else { 293 snprintf( buf, sizeof( buf ), "%s(" /* ?) */ , 294 bi->sql_upper_func.bv_val ); 295 ber_str2bv( buf, 0, 1, &bi->sql_upper_func_open ); 296 297 ber_str2bv( /* (? */ ")", 0, 1, &bi->sql_upper_func_close ); 298 } 299 } 300 301 /* normalize filter values only if necessary */ 302 bi->sql_caseIgnoreMatch = mr_find( "caseIgnoreMatch" ); 303 assert( bi->sql_caseIgnoreMatch != NULL ); 304 305 bi->sql_telephoneNumberMatch = mr_find( "telephoneNumberMatch" ); 306 assert( bi->sql_telephoneNumberMatch != NULL ); 307 308 if ( bi->sql_dbuser == NULL ) { 309 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 310 "user name not specified " 311 "(use \"dbuser\" directive in slapd.conf)\n", 0, 0, 0 ); 312 return 1; 313 } 314 315 if ( BER_BVISNULL( &bi->sql_subtree_cond ) ) { 316 /* 317 * Prepare concat function for subtree search condition 318 */ 319 struct berval concat; 320 struct berval values[] = { 321 BER_BVC( "'%'" ), 322 BER_BVC( "?" ), 323 BER_BVNULL 324 }; 325 struct berbuf bb = BB_NULL; 326 327 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 328 "subtree search SQL condition not specified " 329 "(use \"subtree_cond\" directive in slapd.conf); " 330 "preparing default\n", 331 0, 0, 0); 332 333 if ( backsql_prepare_pattern( bi->sql_concat_func, values, 334 &concat ) ) { 335 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 336 "unable to prepare CONCAT pattern for subtree search", 337 0, 0, 0 ); 338 return 1; 339 } 340 341 if ( bi->sql_upper_func.bv_val ) { 342 343 /* 344 * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?)) 345 */ 346 347 backsql_strfcat_x( &bb, NULL, "blbbb", 348 &bi->sql_upper_func, 349 (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ), 350 "(ldap_entries.dn) LIKE ", 351 &bi->sql_upper_func_open, 352 &concat, 353 &bi->sql_upper_func_close ); 354 355 } else { 356 357 /* 358 * ldap_entries.dn LIKE CONCAT('%',?) 359 */ 360 361 backsql_strfcat_x( &bb, NULL, "lb", 362 (ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ), 363 "ldap_entries.dn LIKE ", 364 &concat ); 365 } 366 367 ch_free( concat.bv_val ); 368 369 bi->sql_subtree_cond = bb.bb_val; 370 371 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 372 "setting \"%s\" as default \"subtree_cond\"\n", 373 bi->sql_subtree_cond.bv_val, 0, 0 ); 374 } 375 376 if ( bi->sql_children_cond.bv_val == NULL ) { 377 /* 378 * Prepare concat function for children search condition 379 */ 380 struct berval concat; 381 struct berval values[] = { 382 BER_BVC( "'%,'" ), 383 BER_BVC( "?" ), 384 BER_BVNULL 385 }; 386 struct berbuf bb = BB_NULL; 387 388 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 389 "children search SQL condition not specified " 390 "(use \"children_cond\" directive in slapd.conf); " 391 "preparing default\n", 392 0, 0, 0); 393 394 if ( backsql_prepare_pattern( bi->sql_concat_func, values, 395 &concat ) ) { 396 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 397 "unable to prepare CONCAT pattern for children search", 0, 0, 0 ); 398 return 1; 399 } 400 401 if ( bi->sql_upper_func.bv_val ) { 402 403 /* 404 * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?)) 405 */ 406 407 backsql_strfcat_x( &bb, NULL, "blbbb", 408 &bi->sql_upper_func, 409 (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ), 410 "(ldap_entries.dn) LIKE ", 411 &bi->sql_upper_func_open, 412 &concat, 413 &bi->sql_upper_func_close ); 414 415 } else { 416 417 /* 418 * ldap_entries.dn LIKE CONCAT('%,',?) 419 */ 420 421 backsql_strfcat_x( &bb, NULL, "lb", 422 (ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ), 423 "ldap_entries.dn LIKE ", 424 &concat ); 425 } 426 427 ch_free( concat.bv_val ); 428 429 bi->sql_children_cond = bb.bb_val; 430 431 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 432 "setting \"%s\" as default \"children_cond\"\n", 433 bi->sql_children_cond.bv_val, 0, 0 ); 434 } 435 436 if ( bi->sql_dn_match_cond.bv_val == NULL ) { 437 /* 438 * Prepare concat function for dn match search condition 439 */ 440 struct berbuf bb = BB_NULL; 441 442 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 443 "DN match search SQL condition not specified " 444 "(use \"dn_match_cond\" directive in slapd.conf); " 445 "preparing default\n", 446 0, 0, 0); 447 448 if ( bi->sql_upper_func.bv_val ) { 449 450 /* 451 * UPPER(ldap_entries.dn)=? 452 */ 453 454 backsql_strfcat_x( &bb, NULL, "blbcb", 455 &bi->sql_upper_func, 456 (ber_len_t)STRLENOF( "(ldap_entries.dn)=" ), 457 "(ldap_entries.dn)=", 458 &bi->sql_upper_func_open, 459 '?', 460 &bi->sql_upper_func_close ); 461 462 } else { 463 464 /* 465 * ldap_entries.dn=? 466 */ 467 468 backsql_strfcat_x( &bb, NULL, "l", 469 (ber_len_t)STRLENOF( "ldap_entries.dn=?" ), 470 "ldap_entries.dn=?" ); 471 } 472 473 bi->sql_dn_match_cond = bb.bb_val; 474 475 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 476 "setting \"%s\" as default \"dn_match_cond\"\n", 477 bi->sql_dn_match_cond.bv_val, 0, 0 ); 478 } 479 480 if ( bi->sql_oc_query == NULL ) { 481 if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) { 482 bi->sql_oc_query = 483 ch_strdup( backsql_def_needs_select_oc_query ); 484 485 } else { 486 bi->sql_oc_query = ch_strdup( backsql_def_oc_query ); 487 } 488 489 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 490 "objectclass mapping SQL statement not specified " 491 "(use \"oc_query\" directive in slapd.conf)\n", 492 0, 0, 0 ); 493 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 494 "setting \"%s\" by default\n", bi->sql_oc_query, 0, 0 ); 495 } 496 497 if ( bi->sql_at_query == NULL ) { 498 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 499 "attribute mapping SQL statement not specified " 500 "(use \"at_query\" directive in slapd.conf)\n", 501 0, 0, 0 ); 502 Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): " 503 "setting \"%s\" by default\n", 504 backsql_def_at_query, 0, 0 ); 505 bi->sql_at_query = ch_strdup( backsql_def_at_query ); 506 } 507 508 if ( bi->sql_insentry_stmt == NULL ) { 509 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 510 "entry insertion SQL statement not specified " 511 "(use \"insentry_stmt\" directive in slapd.conf)\n", 512 0, 0, 0 ); 513 Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): " 514 "setting \"%s\" by default\n", 515 backsql_def_insentry_stmt, 0, 0 ); 516 bi->sql_insentry_stmt = ch_strdup( backsql_def_insentry_stmt ); 517 } 518 519 if ( bi->sql_delentry_stmt == NULL ) { 520 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 521 "entry deletion SQL statement not specified " 522 "(use \"delentry_stmt\" directive in slapd.conf)\n", 523 0, 0, 0 ); 524 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 525 "setting \"%s\" by default\n", 526 backsql_def_delentry_stmt, 0, 0 ); 527 bi->sql_delentry_stmt = ch_strdup( backsql_def_delentry_stmt ); 528 } 529 530 if ( bi->sql_renentry_stmt == NULL ) { 531 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 532 "entry deletion SQL statement not specified " 533 "(use \"renentry_stmt\" directive in slapd.conf)\n", 534 0, 0, 0 ); 535 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 536 "setting \"%s\" by default\n", 537 backsql_def_renentry_stmt, 0, 0 ); 538 bi->sql_renentry_stmt = ch_strdup( backsql_def_renentry_stmt ); 539 } 540 541 if ( bi->sql_delobjclasses_stmt == NULL ) { 542 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 543 "objclasses deletion SQL statement not specified " 544 "(use \"delobjclasses_stmt\" directive in slapd.conf)\n", 545 0, 0, 0 ); 546 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 547 "setting \"%s\" by default\n", 548 backsql_def_delobjclasses_stmt, 0, 0 ); 549 bi->sql_delobjclasses_stmt = ch_strdup( backsql_def_delobjclasses_stmt ); 550 } 551 552 /* This should just be to force schema loading */ 553 connection_fake_init2( &conn, &opbuf, thrctx, 0 ); 554 op = &opbuf.ob_op; 555 op->o_bd = bd; 556 if ( backsql_get_db_conn( op, &dbh ) != LDAP_SUCCESS ) { 557 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 558 "connection failed, exiting\n", 0, 0, 0 ); 559 return 1; 560 } 561 if ( backsql_load_schema_map( bi, dbh ) != LDAP_SUCCESS ) { 562 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 563 "schema mapping failed, exiting\n", 0, 0, 0 ); 564 return 1; 565 } 566 if ( backsql_free_db_conn( op, dbh ) != SQL_SUCCESS ) { 567 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 568 "connection free failed\n", 0, 0, 0 ); 569 } 570 if ( !BACKSQL_SCHEMA_LOADED( bi ) ) { 571 Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): " 572 "test failed, schema map not loaded - exiting\n", 573 0, 0, 0 ); 574 return 1; 575 } 576 577 /* 578 * Prepare ID selection query 579 */ 580 if ( bi->sql_id_query == NULL ) { 581 /* no custom id_query provided */ 582 if ( bi->sql_upper_func.bv_val == NULL ) { 583 backsql_strcat_x( &bb, NULL, backsql_id_query, "dn=?", NULL ); 584 585 } else { 586 if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) { 587 backsql_strcat_x( &bb, NULL, backsql_id_query, 588 "dn_ru=?", NULL ); 589 } else { 590 if ( BACKSQL_USE_REVERSE_DN( bi ) ) { 591 backsql_strfcat_x( &bb, NULL, "sbl", 592 backsql_id_query, 593 &bi->sql_upper_func, 594 (ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" ); 595 } else { 596 backsql_strfcat_x( &bb, NULL, "sblbcb", 597 backsql_id_query, 598 &bi->sql_upper_func, 599 (ber_len_t)STRLENOF( "(dn)=" ), "(dn)=", 600 &bi->sql_upper_func_open, 601 '?', 602 &bi->sql_upper_func_close ); 603 } 604 } 605 } 606 bi->sql_id_query = bb.bb_val.bv_val; 607 } 608 609 /* 610 * Prepare children count query 611 */ 612 BER_BVZERO( &bb.bb_val ); 613 bb.bb_len = 0; 614 backsql_strfcat_x( &bb, NULL, "sbsb", 615 "SELECT COUNT(distinct subordinates.id) " 616 "FROM ldap_entries,ldap_entries ", 617 &bi->sql_aliasing, "subordinates " 618 "WHERE subordinates.parent=ldap_entries.id AND ", 619 &bi->sql_dn_match_cond ); 620 bi->sql_has_children_query = bb.bb_val.bv_val; 621 622 /* 623 * Prepare DN and objectClass aliasing bit of query 624 */ 625 BER_BVZERO( &bb.bb_val ); 626 bb.bb_len = 0; 627 backsql_strfcat_x( &bb, NULL, "sbbsbsbbsb", 628 " ", &bi->sql_aliasing, &bi->sql_aliasing_quote, 629 "objectClass", &bi->sql_aliasing_quote, 630 ",ldap_entries.dn ", &bi->sql_aliasing, 631 &bi->sql_aliasing_quote, "dn", &bi->sql_aliasing_quote ); 632 bi->sql_dn_oc_aliasing = bb.bb_val; 633 634 /* should never happen! */ 635 assert( bd->be_nsuffix != NULL ); 636 637 if ( BER_BVISNULL( &bd->be_nsuffix[ 1 ] ) ) { 638 /* enable if only one suffix is defined */ 639 bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT; 640 } 641 642 bi->sql_flags |= BSQLF_CHECK_SCHEMA; 643 644 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): " 645 "test succeeded, schema map loaded\n", 0, 0, 0 ); 646 return 0; 647} 648 649int 650backsql_db_close( 651 BackendDB *bd, 652 ConfigReply *cr ) 653{ 654 backsql_info *bi = (backsql_info*)bd->be_private; 655 656 Debug( LDAP_DEBUG_TRACE, "==>backsql_db_close()\n", 0, 0, 0 ); 657 658 backsql_conn_destroy( bi ); 659 660 Debug( LDAP_DEBUG_TRACE, "<==backsql_db_close()\n", 0, 0, 0 ); 661 662 return 0; 663} 664 665#if SLAPD_SQL == SLAPD_MOD_DYNAMIC 666 667/* conditionally define the init_module() function */ 668SLAP_BACKEND_INIT_MODULE( sql ) 669 670#endif /* SLAPD_SQL == SLAPD_MOD_DYNAMIC */ 671 672