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