Back to index

openldap  2.4.31
init.c
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 Masarati.
00007  * All rights reserved.
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted only as authorized by the OpenLDAP
00011  * Public License.
00012  *
00013  * A copy of this license is available in the file LICENSE in the
00014  * top-level directory of the distribution or, alternatively, at
00015  * <http://www.OpenLDAP.org/license.html>.
00016  */
00017 /* ACKNOWLEDGEMENTS:
00018  * This work was initially developed by Dmitry Kovalev for inclusion
00019  * by OpenLDAP Software.  Additional significant contributors include
00020  * Pierangelo Masarati.
00021  */
00022 
00023 #include "portable.h"
00024 
00025 #include <stdio.h>
00026 #include <sys/types.h>
00027 #include "ac/string.h"
00028 
00029 #include "slap.h"
00030 #include "config.h"
00031 #include "proto-sql.h"
00032 
00033 int
00034 sql_back_initialize(
00035        BackendInfo   *bi )
00036 { 
00037        static char *controls[] = {
00038               LDAP_CONTROL_ASSERT,
00039               LDAP_CONTROL_MANAGEDSAIT,
00040               LDAP_CONTROL_NOOP,
00041 #ifdef SLAP_CONTROL_X_TREE_DELETE
00042               SLAP_CONTROL_X_TREE_DELETE,
00043 #endif /* SLAP_CONTROL_X_TREE_DELETE */
00044 #ifndef BACKSQL_ARBITRARY_KEY
00045               LDAP_CONTROL_PAGEDRESULTS,
00046 #endif /* ! BACKSQL_ARBITRARY_KEY */
00047               NULL
00048        };
00049        int rc;
00050 
00051        bi->bi_controls = controls;
00052 
00053        bi->bi_flags |=
00054 #if 0
00055               SLAP_BFLAG_INCREMENT |
00056 #endif
00057               SLAP_BFLAG_REFERRALS;
00058 
00059        Debug( LDAP_DEBUG_TRACE,"==>sql_back_initialize()\n", 0, 0, 0 );
00060        
00061        bi->bi_db_init = backsql_db_init;
00062        bi->bi_db_config = config_generic_wrapper;
00063        bi->bi_db_open = backsql_db_open;
00064        bi->bi_db_close = backsql_db_close;
00065        bi->bi_db_destroy = backsql_db_destroy;
00066 
00067        bi->bi_op_abandon = 0;
00068        bi->bi_op_compare = backsql_compare;
00069        bi->bi_op_bind = backsql_bind;
00070        bi->bi_op_unbind = 0;
00071        bi->bi_op_search = backsql_search;
00072        bi->bi_op_modify = backsql_modify;
00073        bi->bi_op_modrdn = backsql_modrdn;
00074        bi->bi_op_add = backsql_add;
00075        bi->bi_op_delete = backsql_delete;
00076        
00077        bi->bi_chk_referrals = 0;
00078        bi->bi_operational = backsql_operational;
00079        bi->bi_entry_get_rw = backsql_entry_get;
00080        bi->bi_entry_release_rw = backsql_entry_release;
00081  
00082        bi->bi_connection_init = 0;
00083 
00084        rc = backsql_init_cf( bi );
00085        Debug( LDAP_DEBUG_TRACE,"<==sql_back_initialize()\n", 0, 0, 0 );
00086        return rc;
00087 }
00088 
00089 int
00090 backsql_destroy( 
00091        BackendInfo   *bi )
00092 {
00093        Debug( LDAP_DEBUG_TRACE, "==>backsql_destroy()\n", 0, 0, 0 );
00094        Debug( LDAP_DEBUG_TRACE, "<==backsql_destroy()\n", 0, 0, 0 );
00095        return 0;
00096 }
00097 
00098 int
00099 backsql_db_init(
00100        BackendDB     *bd,
00101        ConfigReply   *cr )
00102 {
00103        backsql_info  *bi;
00104        int           rc = 0;
00105  
00106        Debug( LDAP_DEBUG_TRACE, "==>backsql_db_init()\n", 0, 0, 0 );
00107 
00108        bi = (backsql_info *)ch_calloc( 1, sizeof( backsql_info ) );
00109        ldap_pvt_thread_mutex_init( &bi->sql_dbconn_mutex );
00110        ldap_pvt_thread_mutex_init( &bi->sql_schema_mutex );
00111 
00112        if ( backsql_init_db_env( bi ) != SQL_SUCCESS ) {
00113               rc = -1;
00114        }
00115 
00116        bd->be_private = bi;
00117        bd->be_cf_ocs = bd->bd_info->bi_cf_ocs;
00118 
00119        Debug( LDAP_DEBUG_TRACE, "<==backsql_db_init()\n", 0, 0, 0 );
00120 
00121        return rc;
00122 }
00123 
00124 int
00125 backsql_db_destroy(
00126        BackendDB     *bd,
00127        ConfigReply   *cr )
00128 {
00129        backsql_info  *bi = (backsql_info*)bd->be_private;
00130  
00131        Debug( LDAP_DEBUG_TRACE, "==>backsql_db_destroy()\n", 0, 0, 0 );
00132 
00133        backsql_free_db_env( bi );
00134        ldap_pvt_thread_mutex_destroy( &bi->sql_dbconn_mutex );
00135        backsql_destroy_schema_map( bi );
00136        ldap_pvt_thread_mutex_destroy( &bi->sql_schema_mutex );
00137 
00138        if ( bi->sql_dbname ) {
00139               ch_free( bi->sql_dbname );
00140        }
00141        if ( bi->sql_dbuser ) {
00142               ch_free( bi->sql_dbuser );
00143        }
00144        if ( bi->sql_dbpasswd ) {
00145               ch_free( bi->sql_dbpasswd );
00146        }
00147        if ( bi->sql_dbhost ) {
00148               ch_free( bi->sql_dbhost );
00149        }
00150        if ( bi->sql_upper_func.bv_val ) {
00151               ch_free( bi->sql_upper_func.bv_val );
00152               ch_free( bi->sql_upper_func_open.bv_val );
00153               ch_free( bi->sql_upper_func_close.bv_val );
00154        }
00155        if ( bi->sql_concat_func ) {
00156               ber_bvarray_free( bi->sql_concat_func );
00157        }
00158        if ( !BER_BVISNULL( &bi->sql_strcast_func ) ) {
00159               ch_free( bi->sql_strcast_func.bv_val );
00160        }
00161        if ( !BER_BVISNULL( &bi->sql_children_cond ) ) {
00162               ch_free( bi->sql_children_cond.bv_val );
00163        }
00164        if ( !BER_BVISNULL( &bi->sql_dn_match_cond ) ) {
00165               ch_free( bi->sql_dn_match_cond.bv_val );
00166        }
00167        if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) {
00168               ch_free( bi->sql_subtree_cond.bv_val );
00169        }
00170        if ( !BER_BVISNULL( &bi->sql_dn_oc_aliasing ) ) {
00171               ch_free( bi->sql_dn_oc_aliasing.bv_val );
00172        }
00173        if ( bi->sql_oc_query ) {
00174               ch_free( bi->sql_oc_query );
00175        }
00176        if ( bi->sql_at_query ) {
00177               ch_free( bi->sql_at_query );
00178        }
00179        if ( bi->sql_id_query ) {
00180               ch_free( bi->sql_id_query );
00181        }
00182        if ( bi->sql_has_children_query ) {
00183               ch_free( bi->sql_has_children_query );
00184        }
00185        if ( bi->sql_insentry_stmt ) {
00186               ch_free( bi->sql_insentry_stmt );
00187        }
00188        if ( bi->sql_delentry_stmt ) {
00189               ch_free( bi->sql_delentry_stmt );
00190        }
00191        if ( bi->sql_renentry_stmt ) {
00192               ch_free( bi->sql_renentry_stmt );
00193        }
00194        if ( bi->sql_delobjclasses_stmt ) {
00195               ch_free( bi->sql_delobjclasses_stmt );
00196        }
00197        if ( !BER_BVISNULL( &bi->sql_aliasing ) ) {
00198               ch_free( bi->sql_aliasing.bv_val );
00199        }
00200        if ( !BER_BVISNULL( &bi->sql_aliasing_quote ) ) {
00201               ch_free( bi->sql_aliasing_quote.bv_val );
00202        }
00203 
00204        if ( bi->sql_anlist ) {
00205               int    i;
00206 
00207               for ( i = 0; !BER_BVISNULL( &bi->sql_anlist[ i ].an_name ); i++ )
00208               {
00209                      ch_free( bi->sql_anlist[ i ].an_name.bv_val );
00210               }
00211               ch_free( bi->sql_anlist );
00212        }
00213 
00214        if ( bi->sql_baseObject ) {
00215               entry_free( bi->sql_baseObject );
00216        }
00217        
00218        ch_free( bi );
00219        
00220        Debug( LDAP_DEBUG_TRACE, "<==backsql_db_destroy()\n", 0, 0, 0 );
00221        return 0;
00222 }
00223 
00224 int
00225 backsql_db_open(
00226        BackendDB     *bd,
00227        ConfigReply   *cr )
00228 {
00229        backsql_info  *bi = (backsql_info*)bd->be_private;
00230        struct berbuf bb = BB_NULL;
00231 
00232        Connection    conn = { 0 };
00233        OperationBuffer opbuf;
00234        Operation*    op;
00235        SQLHDBC              dbh = SQL_NULL_HDBC;
00236        void          *thrctx = ldap_pvt_thread_pool_context();
00237 
00238        Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
00239               "testing RDBMS connection\n", 0, 0, 0 );
00240        if ( bi->sql_dbname == NULL ) {
00241               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00242                      "datasource name not specified "
00243                      "(use \"dbname\" directive in slapd.conf)\n", 0, 0, 0 );
00244               return 1;
00245        }
00246 
00247        if ( bi->sql_concat_func == NULL ) {
00248               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00249                      "concat func not specified (use \"concat_pattern\" "
00250                      "directive in slapd.conf)\n", 0, 0, 0 );
00251 
00252               if ( backsql_split_pattern( backsql_def_concat_func, 
00253                             &bi->sql_concat_func, 2 ) ) {
00254                      Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00255                             "unable to parse pattern \"%s\"",
00256                             backsql_def_concat_func, 0, 0 );
00257                      return 1;
00258               }
00259        }
00260 
00261        /*
00262         * see back-sql.h for default values
00263         */
00264        if ( BER_BVISNULL( &bi->sql_aliasing ) ) {
00265               ber_str2bv( BACKSQL_ALIASING,
00266                      STRLENOF( BACKSQL_ALIASING ),
00267                      1, &bi->sql_aliasing );
00268        }
00269 
00270        if ( BER_BVISNULL( &bi->sql_aliasing_quote ) ) {
00271               ber_str2bv( BACKSQL_ALIASING_QUOTE,
00272                      STRLENOF( BACKSQL_ALIASING_QUOTE ),
00273                      1, &bi->sql_aliasing_quote );
00274        }
00275 
00276        /*
00277         * Prepare cast string as required
00278         */
00279        if ( bi->sql_upper_func.bv_val ) {
00280               char buf[1024];
00281 
00282               if ( BACKSQL_UPPER_NEEDS_CAST( bi ) ) {
00283                      snprintf( buf, sizeof( buf ), 
00284                             "%s(cast (" /* ? as varchar(%d))) */ , 
00285                             bi->sql_upper_func.bv_val );
00286                      ber_str2bv( buf, 0, 1, &bi->sql_upper_func_open );
00287 
00288                      snprintf( buf, sizeof( buf ),
00289                             /* (cast(? */ " as varchar(%d)))",
00290                             BACKSQL_MAX_DN_LEN );
00291                      ber_str2bv( buf, 0, 1, &bi->sql_upper_func_close );
00292 
00293               } else {
00294                      snprintf( buf, sizeof( buf ), "%s(" /* ?) */ ,
00295                                    bi->sql_upper_func.bv_val );
00296                      ber_str2bv( buf, 0, 1, &bi->sql_upper_func_open );
00297 
00298                      ber_str2bv( /* (? */ ")", 0, 1, &bi->sql_upper_func_close );
00299               }
00300        }
00301 
00302        /* normalize filter values only if necessary */
00303        bi->sql_caseIgnoreMatch = mr_find( "caseIgnoreMatch" );
00304        assert( bi->sql_caseIgnoreMatch != NULL );
00305 
00306        bi->sql_telephoneNumberMatch = mr_find( "telephoneNumberMatch" );
00307        assert( bi->sql_telephoneNumberMatch != NULL );
00308 
00309        if ( bi->sql_dbuser == NULL ) {
00310               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00311                      "user name not specified "
00312                      "(use \"dbuser\" directive in slapd.conf)\n", 0, 0, 0 );
00313               return 1;
00314        }
00315        
00316        if ( BER_BVISNULL( &bi->sql_subtree_cond ) ) {
00317               /*
00318                * Prepare concat function for subtree search condition
00319                */
00320               struct berval concat;
00321               struct berval values[] = {
00322                      BER_BVC( "'%'" ),
00323                      BER_BVC( "?" ),
00324                      BER_BVNULL
00325               };
00326               struct berbuf bb = BB_NULL;
00327 
00328               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00329                      "subtree search SQL condition not specified "
00330                      "(use \"subtree_cond\" directive in slapd.conf); "
00331                      "preparing default\n", 
00332                      0, 0, 0);
00333 
00334               if ( backsql_prepare_pattern( bi->sql_concat_func, values, 
00335                             &concat ) ) {
00336                      Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00337                             "unable to prepare CONCAT pattern for subtree search",
00338                             0, 0, 0 );
00339                      return 1;
00340               }
00341                      
00342               if ( bi->sql_upper_func.bv_val ) {
00343 
00344                      /*
00345                       * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?))
00346                       */
00347 
00348                      backsql_strfcat_x( &bb, NULL, "blbbb",
00349                                    &bi->sql_upper_func,
00350                                    (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
00351                                           "(ldap_entries.dn) LIKE ",
00352                                    &bi->sql_upper_func_open,
00353                                    &concat,
00354                                    &bi->sql_upper_func_close );
00355 
00356               } else {
00357 
00358                      /*
00359                       * ldap_entries.dn LIKE CONCAT('%',?)
00360                       */
00361 
00362                      backsql_strfcat_x( &bb, NULL, "lb",
00363                                    (ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
00364                                           "ldap_entries.dn LIKE ",
00365                                    &concat );
00366               }
00367 
00368               ch_free( concat.bv_val );
00369 
00370               bi->sql_subtree_cond = bb.bb_val;
00371                      
00372               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00373                      "setting \"%s\" as default \"subtree_cond\"\n",
00374                      bi->sql_subtree_cond.bv_val, 0, 0 );
00375        }
00376 
00377        if ( bi->sql_children_cond.bv_val == NULL ) {
00378               /*
00379                * Prepare concat function for children search condition
00380                */
00381               struct berval concat;
00382               struct berval values[] = {
00383                      BER_BVC( "'%,'" ),
00384                      BER_BVC( "?" ),
00385                      BER_BVNULL
00386               };
00387               struct berbuf bb = BB_NULL;
00388 
00389               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00390                      "children search SQL condition not specified "
00391                      "(use \"children_cond\" directive in slapd.conf); "
00392                      "preparing default\n", 
00393                      0, 0, 0);
00394 
00395               if ( backsql_prepare_pattern( bi->sql_concat_func, values, 
00396                             &concat ) ) {
00397                      Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00398                             "unable to prepare CONCAT pattern for children search", 0, 0, 0 );
00399                      return 1;
00400               }
00401                      
00402               if ( bi->sql_upper_func.bv_val ) {
00403 
00404                      /*
00405                       * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
00406                       */
00407 
00408                      backsql_strfcat_x( &bb, NULL, "blbbb",
00409                                    &bi->sql_upper_func,
00410                                    (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
00411                                           "(ldap_entries.dn) LIKE ",
00412                                    &bi->sql_upper_func_open,
00413                                    &concat,
00414                                    &bi->sql_upper_func_close );
00415 
00416               } else {
00417 
00418                      /*
00419                       * ldap_entries.dn LIKE CONCAT('%,',?)
00420                       */
00421 
00422                      backsql_strfcat_x( &bb, NULL, "lb",
00423                                    (ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
00424                                           "ldap_entries.dn LIKE ",
00425                                    &concat );
00426               }
00427 
00428               ch_free( concat.bv_val );
00429 
00430               bi->sql_children_cond = bb.bb_val;
00431                      
00432               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00433                      "setting \"%s\" as default \"children_cond\"\n",
00434                      bi->sql_children_cond.bv_val, 0, 0 );
00435        }
00436 
00437        if ( bi->sql_dn_match_cond.bv_val == NULL ) {
00438               /*
00439                * Prepare concat function for dn match search condition
00440                */
00441               struct berbuf bb = BB_NULL;
00442 
00443               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00444                      "DN match search SQL condition not specified "
00445                      "(use \"dn_match_cond\" directive in slapd.conf); "
00446                      "preparing default\n", 
00447                      0, 0, 0);
00448 
00449               if ( bi->sql_upper_func.bv_val ) {
00450 
00451                      /*
00452                       * UPPER(ldap_entries.dn)=?
00453                       */
00454 
00455                      backsql_strfcat_x( &bb, NULL, "blbcb",
00456                                    &bi->sql_upper_func,
00457                                    (ber_len_t)STRLENOF( "(ldap_entries.dn)=" ),
00458                                           "(ldap_entries.dn)=",
00459                                    &bi->sql_upper_func_open,
00460                                    '?',
00461                                    &bi->sql_upper_func_close );
00462 
00463               } else {
00464 
00465                      /*
00466                       * ldap_entries.dn=?
00467                       */
00468 
00469                      backsql_strfcat_x( &bb, NULL, "l",
00470                                    (ber_len_t)STRLENOF( "ldap_entries.dn=?" ),
00471                                           "ldap_entries.dn=?" );
00472               }
00473 
00474               bi->sql_dn_match_cond = bb.bb_val;
00475                      
00476               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00477                      "setting \"%s\" as default \"dn_match_cond\"\n",
00478                      bi->sql_dn_match_cond.bv_val, 0, 0 );
00479        }
00480 
00481        if ( bi->sql_oc_query == NULL ) {
00482               if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
00483                      bi->sql_oc_query =
00484                             ch_strdup( backsql_def_needs_select_oc_query );
00485 
00486               } else {
00487                      bi->sql_oc_query = ch_strdup( backsql_def_oc_query );
00488               }
00489 
00490               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00491                      "objectclass mapping SQL statement not specified "
00492                      "(use \"oc_query\" directive in slapd.conf)\n", 
00493                      0, 0, 0 );
00494               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00495                      "setting \"%s\" by default\n", bi->sql_oc_query, 0, 0 );
00496        }
00497        
00498        if ( bi->sql_at_query == NULL ) {
00499               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00500                      "attribute mapping SQL statement not specified "
00501                      "(use \"at_query\" directive in slapd.conf)\n",
00502                      0, 0, 0 );
00503               Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
00504                      "setting \"%s\" by default\n",
00505                      backsql_def_at_query, 0, 0 );
00506               bi->sql_at_query = ch_strdup( backsql_def_at_query );
00507        }
00508        
00509        if ( bi->sql_insentry_stmt == NULL ) {
00510               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00511                      "entry insertion SQL statement not specified "
00512                      "(use \"insentry_stmt\" directive in slapd.conf)\n",
00513                      0, 0, 0 );
00514               Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
00515                      "setting \"%s\" by default\n",
00516                      backsql_def_insentry_stmt, 0, 0 );
00517               bi->sql_insentry_stmt = ch_strdup( backsql_def_insentry_stmt );
00518        }
00519        
00520        if ( bi->sql_delentry_stmt == NULL ) {
00521               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00522                      "entry deletion SQL statement not specified "
00523                      "(use \"delentry_stmt\" directive in slapd.conf)\n",
00524                      0, 0, 0 );
00525               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00526                      "setting \"%s\" by default\n",
00527                      backsql_def_delentry_stmt, 0, 0 );
00528               bi->sql_delentry_stmt = ch_strdup( backsql_def_delentry_stmt );
00529        }
00530 
00531        if ( bi->sql_renentry_stmt == NULL ) {
00532               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00533                      "entry deletion SQL statement not specified "
00534                      "(use \"renentry_stmt\" directive in slapd.conf)\n",
00535                      0, 0, 0 );
00536               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00537                      "setting \"%s\" by default\n",
00538                      backsql_def_renentry_stmt, 0, 0 );
00539               bi->sql_renentry_stmt = ch_strdup( backsql_def_renentry_stmt );
00540        }
00541 
00542        if ( bi->sql_delobjclasses_stmt == NULL ) {
00543               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00544                      "objclasses deletion SQL statement not specified "
00545                      "(use \"delobjclasses_stmt\" directive in slapd.conf)\n",
00546                      0, 0, 0 );
00547               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00548                      "setting \"%s\" by default\n",
00549                      backsql_def_delobjclasses_stmt, 0, 0 );
00550               bi->sql_delobjclasses_stmt = ch_strdup( backsql_def_delobjclasses_stmt );
00551        }
00552 
00553        /* This should just be to force schema loading */
00554        connection_fake_init2( &conn, &opbuf, thrctx, 0 );
00555        op = &opbuf.ob_op;
00556        op->o_bd = bd;
00557        if ( backsql_get_db_conn( op, &dbh ) != LDAP_SUCCESS ) {
00558               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00559                      "connection failed, exiting\n", 0, 0, 0 );
00560               return 1;
00561        }
00562        if ( backsql_load_schema_map( bi, dbh ) != LDAP_SUCCESS ) {
00563               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00564                      "schema mapping failed, exiting\n", 0, 0, 0 );
00565               return 1;
00566        }
00567        if ( backsql_free_db_conn( op, dbh ) != SQL_SUCCESS ) {
00568               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00569                      "connection free failed\n", 0, 0, 0 );
00570        }
00571        if ( !BACKSQL_SCHEMA_LOADED( bi ) ) {
00572               Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
00573                      "test failed, schema map not loaded - exiting\n",
00574                      0, 0, 0 );
00575               return 1;
00576        }
00577 
00578        /*
00579         * Prepare ID selection query
00580         */
00581        if ( bi->sql_id_query == NULL ) {
00582               /* no custom id_query provided */
00583               if ( bi->sql_upper_func.bv_val == NULL ) {
00584                      backsql_strcat_x( &bb, NULL, backsql_id_query, "dn=?", NULL );
00585 
00586               } else {
00587                      if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
00588                             backsql_strcat_x( &bb, NULL, backsql_id_query,
00589                                           "dn_ru=?", NULL );
00590                      } else {
00591                             if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
00592                                    backsql_strfcat_x( &bb, NULL, "sbl",
00593                                                  backsql_id_query,
00594                                                  &bi->sql_upper_func, 
00595                                                  (ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" );
00596                             } else {
00597                                    backsql_strfcat_x( &bb, NULL, "sblbcb",
00598                                                  backsql_id_query,
00599                                                  &bi->sql_upper_func, 
00600                                                  (ber_len_t)STRLENOF( "(dn)=" ), "(dn)=",
00601                                                  &bi->sql_upper_func_open, 
00602                                                  '?', 
00603                                                  &bi->sql_upper_func_close );
00604                             }
00605                      }
00606               }
00607               bi->sql_id_query = bb.bb_val.bv_val;
00608        }
00609 
00610        /*
00611         * Prepare children count query
00612         */
00613        BER_BVZERO( &bb.bb_val );
00614        bb.bb_len = 0;
00615        backsql_strfcat_x( &bb, NULL, "sbsb",
00616                      "SELECT COUNT(distinct subordinates.id) "
00617                      "FROM ldap_entries,ldap_entries ",
00618                      &bi->sql_aliasing, "subordinates "
00619                      "WHERE subordinates.parent=ldap_entries.id AND ",
00620                      &bi->sql_dn_match_cond );
00621        bi->sql_has_children_query = bb.bb_val.bv_val;
00622  
00623        /*
00624         * Prepare DN and objectClass aliasing bit of query
00625         */
00626        BER_BVZERO( &bb.bb_val );
00627        bb.bb_len = 0;
00628        backsql_strfcat_x( &bb, NULL, "sbbsbsbbsb",
00629                      " ", &bi->sql_aliasing, &bi->sql_aliasing_quote,
00630                      "objectClass", &bi->sql_aliasing_quote,
00631                      ",ldap_entries.dn ", &bi->sql_aliasing,
00632                      &bi->sql_aliasing_quote, "dn", &bi->sql_aliasing_quote );
00633        bi->sql_dn_oc_aliasing = bb.bb_val;
00634  
00635        /* should never happen! */
00636        assert( bd->be_nsuffix != NULL );
00637        
00638        if ( BER_BVISNULL( &bd->be_nsuffix[ 1 ] ) ) {
00639               /* enable if only one suffix is defined */
00640               bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT;
00641        }
00642 
00643        bi->sql_flags |= BSQLF_CHECK_SCHEMA;
00644        
00645        Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): "
00646               "test succeeded, schema map loaded\n", 0, 0, 0 );
00647        return 0;
00648 }
00649 
00650 int
00651 backsql_db_close(
00652        BackendDB     *bd,
00653        ConfigReply   *cr )
00654 {
00655        backsql_info  *bi = (backsql_info*)bd->be_private;
00656 
00657        Debug( LDAP_DEBUG_TRACE, "==>backsql_db_close()\n", 0, 0, 0 );
00658 
00659        backsql_conn_destroy( bi );
00660 
00661        Debug( LDAP_DEBUG_TRACE, "<==backsql_db_close()\n", 0, 0, 0 );
00662 
00663        return 0;
00664 }
00665 
00666 #if SLAPD_SQL == SLAPD_MOD_DYNAMIC
00667 
00668 /* conditionally define the init_module() function */
00669 SLAP_BACKEND_INIT_MODULE( sql )
00670 
00671 #endif /* SLAPD_SQL == SLAPD_MOD_DYNAMIC */
00672