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