Back to index

openldap  2.4.31
init.c
Go to the documentation of this file.
00001 /* init.c - initialize ldap backend */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2003-2012 The OpenLDAP Foundation.
00006  * Portions Copyright 1999-2003 Howard Chu.
00007  * Portions Copyright 2000-2003 Pierangelo Masarati.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted only as authorized by the OpenLDAP
00012  * Public License.
00013  *
00014  * A copy of this license is available in the file LICENSE in the
00015  * top-level directory of the distribution or, alternatively, at
00016  * <http://www.OpenLDAP.org/license.html>.
00017  */
00018 /* ACKNOWLEDGEMENTS:
00019  * This work was initially developed by the Howard Chu for inclusion
00020  * in OpenLDAP Software and subsequently enhanced by Pierangelo
00021  * Masarati.
00022  */
00023 
00024 #include "portable.h"
00025 
00026 #include <stdio.h>
00027 
00028 #include <ac/string.h>
00029 #include <ac/socket.h>
00030 
00031 #include "slap.h"
00032 #include "config.h"
00033 #include "back-ldap.h"
00034 
00035 static const ldap_extra_t ldap_extra = {
00036        ldap_back_proxy_authz_ctrl,
00037        ldap_back_controls_free,
00038        slap_idassert_authzfrom_parse_cf,
00039        slap_idassert_passthru_parse_cf,
00040        slap_idassert_parse_cf,
00041        slap_retry_info_destroy,
00042        slap_retry_info_parse,
00043        slap_retry_info_unparse,
00044        ldap_back_connid2str
00045 };
00046 
00047 int
00048 ldap_back_open( BackendInfo *bi )
00049 {
00050        bi->bi_controls = slap_known_controls;
00051        return 0;
00052 }
00053 
00054 int
00055 ldap_back_initialize( BackendInfo *bi )
00056 {
00057        int           rc;
00058 
00059        bi->bi_flags =
00060 #ifdef LDAP_DYNAMIC_OBJECTS
00061               /* this is set because all the support a proxy has to provide
00062                * is the capability to forward the refresh exop, and to
00063                * pass thru entries that contain the dynamicObject class
00064                * and the entryTtl attribute */
00065               SLAP_BFLAG_DYNAMIC |
00066 #endif /* LDAP_DYNAMIC_OBJECTS */
00067 
00068               /* back-ldap recognizes RFC4525 increment;
00069                * let the remote server complain, if needed (ITS#5912) */
00070               SLAP_BFLAG_INCREMENT;
00071 
00072        bi->bi_open = ldap_back_open;
00073        bi->bi_config = 0;
00074        bi->bi_close = 0;
00075        bi->bi_destroy = 0;
00076 
00077        bi->bi_db_init = ldap_back_db_init;
00078        bi->bi_db_config = config_generic_wrapper;
00079        bi->bi_db_open = ldap_back_db_open;
00080        bi->bi_db_close = ldap_back_db_close;
00081        bi->bi_db_destroy = ldap_back_db_destroy;
00082 
00083        bi->bi_op_bind = ldap_back_bind;
00084        bi->bi_op_unbind = 0;
00085        bi->bi_op_search = ldap_back_search;
00086        bi->bi_op_compare = ldap_back_compare;
00087        bi->bi_op_modify = ldap_back_modify;
00088        bi->bi_op_modrdn = ldap_back_modrdn;
00089        bi->bi_op_add = ldap_back_add;
00090        bi->bi_op_delete = ldap_back_delete;
00091        bi->bi_op_abandon = 0;
00092 
00093        bi->bi_extended = ldap_back_extended;
00094 
00095        bi->bi_chk_referrals = 0;
00096        bi->bi_entry_get_rw = ldap_back_entry_get;
00097 
00098        bi->bi_connection_init = 0;
00099        bi->bi_connection_destroy = ldap_back_conn_destroy;
00100 
00101        bi->bi_extra = (void *)&ldap_extra;
00102 
00103        rc =  ldap_back_init_cf( bi );
00104        if ( rc ) {
00105               return rc;
00106        }
00107 
00108        rc = chain_initialize();
00109        if ( rc ) {
00110               return rc;
00111        }
00112 
00113        rc = pbind_initialize();
00114        if ( rc ) {
00115               return rc;
00116        }
00117 
00118 #ifdef SLAP_DISTPROC
00119        rc = distproc_initialize();
00120        if ( rc ) {
00121               return rc;
00122        }
00123 #endif
00124        return rc;
00125 }
00126 
00127 int
00128 ldap_back_db_init( Backend *be, ConfigReply *cr )
00129 {
00130        ldapinfo_t    *li;
00131        int           rc;
00132        unsigned      i;
00133 
00134        li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) );
00135        if ( li == NULL ) {
00136               return -1;
00137        }
00138 
00139        li->li_rebind_f = ldap_back_default_rebind;
00140        li->li_urllist_f = ldap_back_default_urllist;
00141        li->li_urllist_p = li;
00142        ldap_pvt_thread_mutex_init( &li->li_uri_mutex );
00143 
00144        BER_BVZERO( &li->li_acl_authcID );
00145        BER_BVZERO( &li->li_acl_authcDN );
00146        BER_BVZERO( &li->li_acl_passwd );
00147 
00148        li->li_acl_authmethod = LDAP_AUTH_NONE;
00149        BER_BVZERO( &li->li_acl_sasl_mech );
00150        li->li_acl.sb_tls = SB_TLS_DEFAULT;
00151 
00152        li->li_idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
00153 
00154        BER_BVZERO( &li->li_idassert_authcID );
00155        BER_BVZERO( &li->li_idassert_authcDN );
00156        BER_BVZERO( &li->li_idassert_passwd );
00157 
00158        BER_BVZERO( &li->li_idassert_authzID );
00159 
00160        li->li_idassert_authmethod = LDAP_AUTH_NONE;
00161        BER_BVZERO( &li->li_idassert_sasl_mech );
00162        li->li_idassert_tls = SB_TLS_DEFAULT;
00163 
00164        /* by default, use proxyAuthz control on each operation */
00165        li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
00166 
00167        li->li_idassert_authz = NULL;
00168 
00169        /* initialize flags */
00170        li->li_flags = LDAP_BACK_F_CHASE_REFERRALS;
00171 
00172        /* initialize version */
00173        li->li_version = LDAP_VERSION3;
00174 
00175        ldap_pvt_thread_mutex_init( &li->li_conninfo.lai_mutex );
00176 
00177        for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
00178               li->li_conn_priv[ i ].lic_num = 0;
00179               LDAP_TAILQ_INIT( &li->li_conn_priv[ i ].lic_priv );
00180        }
00181        li->li_conn_priv_max = LDAP_BACK_CONN_PRIV_DEFAULT;
00182 
00183        be->be_private = li;
00184        SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD;
00185 
00186        be->be_cf_ocs = be->bd_info->bi_cf_ocs;
00187 
00188        rc = ldap_back_monitor_db_init( be );
00189        if ( rc != 0 ) {
00190               /* ignore, by now */
00191               rc = 0;
00192        }
00193 
00194        return rc;
00195 }
00196 
00197 int
00198 ldap_back_db_open( BackendDB *be, ConfigReply *cr )
00199 {
00200        ldapinfo_t    *li = (ldapinfo_t *)be->be_private;
00201 
00202        slap_bindconf sb = { BER_BVNULL };
00203        int           rc = 0;
00204 
00205        Debug( LDAP_DEBUG_TRACE,
00206               "ldap_back_db_open: URI=%s\n",
00207               li->li_uri != NULL ? li->li_uri : "", 0, 0 );
00208 
00209        /* by default, use proxyAuthz control on each operation */
00210        switch ( li->li_idassert_mode ) {
00211        case LDAP_BACK_IDASSERT_LEGACY:
00212        case LDAP_BACK_IDASSERT_SELF:
00213               /* however, since admin connections are pooled and shared,
00214                * only static authzIDs can be native */
00215               li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
00216               break;
00217 
00218        default:
00219               break;
00220        }
00221 
00222        ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri );
00223        sb.sb_version = li->li_version;
00224        sb.sb_method = LDAP_AUTH_SIMPLE;
00225        BER_BVSTR( &sb.sb_binddn, "" );
00226 
00227        if ( LDAP_BACK_T_F_DISCOVER( li ) && !LDAP_BACK_T_F( li ) ) {
00228               rc = slap_discover_feature( &sb,
00229                             slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
00230                             LDAP_FEATURE_ABSOLUTE_FILTERS );
00231               if ( rc == LDAP_COMPARE_TRUE ) {
00232                      li->li_flags |= LDAP_BACK_F_T_F;
00233               }
00234        }
00235 
00236        if ( LDAP_BACK_CANCEL_DISCOVER( li ) && !LDAP_BACK_CANCEL( li ) ) {
00237               rc = slap_discover_feature( &sb,
00238                             slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
00239                             LDAP_EXOP_CANCEL );
00240               if ( rc == LDAP_COMPARE_TRUE ) {
00241                      li->li_flags |= LDAP_BACK_F_CANCEL_EXOP;
00242               }
00243        }
00244 
00245        /* monitor setup */
00246        rc = ldap_back_monitor_db_open( be );
00247        if ( rc != 0 ) {
00248               /* ignore by now */
00249               rc = 0;
00250        }
00251 
00252        li->li_flags |= LDAP_BACK_F_ISOPEN;
00253 
00254        return rc;
00255 }
00256 
00257 void
00258 ldap_back_conn_free( void *v_lc )
00259 {
00260        ldapconn_t    *lc = v_lc;
00261 
00262        if ( lc->lc_ld != NULL ) {  
00263               ldap_unbind_ext( lc->lc_ld, NULL, NULL );
00264        }
00265        if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) {
00266               ch_free( lc->lc_bound_ndn.bv_val );
00267        }
00268        if ( !BER_BVISNULL( &lc->lc_cred ) ) {
00269               memset( lc->lc_cred.bv_val, 0, lc->lc_cred.bv_len );
00270               ch_free( lc->lc_cred.bv_val );
00271        }
00272        if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) {
00273               ch_free( lc->lc_local_ndn.bv_val );
00274        }
00275        lc->lc_q.tqe_prev = NULL;
00276        lc->lc_q.tqe_next = NULL;
00277        ch_free( lc );
00278 }
00279 
00280 int
00281 ldap_back_db_close( Backend *be, ConfigReply *cr )
00282 {
00283        int           rc = 0;
00284 
00285        if ( be->be_private ) {
00286               rc = ldap_back_monitor_db_close( be );
00287        }
00288 
00289        return rc;
00290 }
00291 
00292 int
00293 ldap_back_db_destroy( Backend *be, ConfigReply *cr )
00294 {
00295        if ( be->be_private ) {
00296               ldapinfo_t    *li = ( ldapinfo_t * )be->be_private;
00297               unsigned      i;
00298 
00299               (void)ldap_back_monitor_db_destroy( be );
00300 
00301               ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
00302 
00303               if ( li->li_uri != NULL ) {
00304                      ch_free( li->li_uri );
00305                      li->li_uri = NULL;
00306 
00307                      assert( li->li_bvuri != NULL );
00308                      ber_bvarray_free( li->li_bvuri );
00309                      li->li_bvuri = NULL;
00310               }
00311 
00312               bindconf_free( &li->li_tls );
00313               bindconf_free( &li->li_acl );
00314               bindconf_free( &li->li_idassert.si_bc );
00315 
00316               if ( li->li_idassert_authz != NULL ) {
00317                      ber_bvarray_free( li->li_idassert_authz );
00318                      li->li_idassert_authz = NULL;
00319               }
00320                      if ( li->li_conninfo.lai_tree ) {
00321                      avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
00322               }
00323               for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
00324                      while ( !LDAP_TAILQ_EMPTY( &li->li_conn_priv[ i ].lic_priv ) ) {
00325                             ldapconn_t    *lc = LDAP_TAILQ_FIRST( &li->li_conn_priv[ i ].lic_priv );
00326 
00327                             LDAP_TAILQ_REMOVE( &li->li_conn_priv[ i ].lic_priv, lc, lc_q );
00328                             ldap_back_conn_free( lc );
00329                      }
00330               }
00331               if ( LDAP_BACK_QUARANTINE( li ) ) {
00332                      slap_retry_info_destroy( &li->li_quarantine );
00333                      ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex );
00334               }
00335 
00336               ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
00337               ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex );
00338               ldap_pvt_thread_mutex_destroy( &li->li_uri_mutex );
00339        }
00340 
00341        ch_free( be->be_private );
00342 
00343        return 0;
00344 }
00345 
00346 #if SLAPD_LDAP == SLAPD_MOD_DYNAMIC
00347 
00348 /* conditionally define the init_module() function */
00349 SLAP_BACKEND_INIT_MODULE( ldap )
00350 
00351 #endif /* SLAPD_LDAP == SLAPD_MOD_DYNAMIC */
00352