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 2001-2003 Pierangelo Masarati.
00006  * Portions Copyright 1999-2003 Howard Chu.
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 
00018 #include "portable.h"
00019 
00020 #include <stdio.h>
00021 
00022 #include <ac/string.h>
00023 #include <ac/socket.h>
00024 
00025 #include "slap.h"
00026 #include "config.h"
00027 #include "../back-ldap/back-ldap.h"
00028 #include "back-meta.h"
00029 
00030 int
00031 meta_back_open(
00032        BackendInfo   *bi )
00033 {
00034        /* FIXME: need to remove the pagedResults, and likely more... */
00035        bi->bi_controls = slap_known_controls;
00036 
00037        return 0;
00038 }
00039 
00040 int
00041 meta_back_initialize(
00042        BackendInfo   *bi )
00043 {
00044        bi->bi_flags =
00045 #if 0
00046        /* this is not (yet) set essentially because back-meta does not
00047         * directly support extended operations... */
00048 #ifdef LDAP_DYNAMIC_OBJECTS
00049               /* this is set because all the support a proxy has to provide
00050                * is the capability to forward the refresh exop, and to
00051                * pass thru entries that contain the dynamicObject class
00052                * and the entryTtl attribute */
00053               SLAP_BFLAG_DYNAMIC |
00054 #endif /* LDAP_DYNAMIC_OBJECTS */
00055 #endif
00056 
00057               /* back-meta recognizes RFC4525 increment;
00058                * let the remote server complain, if needed (ITS#5912) */
00059               SLAP_BFLAG_INCREMENT;
00060 
00061        bi->bi_open = meta_back_open;
00062        bi->bi_config = 0;
00063        bi->bi_close = 0;
00064        bi->bi_destroy = 0;
00065 
00066        bi->bi_db_init = meta_back_db_init;
00067        bi->bi_db_config = meta_back_db_config;
00068        bi->bi_db_open = meta_back_db_open;
00069        bi->bi_db_close = 0;
00070        bi->bi_db_destroy = meta_back_db_destroy;
00071 
00072        bi->bi_op_bind = meta_back_bind;
00073        bi->bi_op_unbind = 0;
00074        bi->bi_op_search = meta_back_search;
00075        bi->bi_op_compare = meta_back_compare;
00076        bi->bi_op_modify = meta_back_modify;
00077        bi->bi_op_modrdn = meta_back_modrdn;
00078        bi->bi_op_add = meta_back_add;
00079        bi->bi_op_delete = meta_back_delete;
00080        bi->bi_op_abandon = 0;
00081 
00082        bi->bi_extended = 0;
00083 
00084        bi->bi_chk_referrals = 0;
00085 
00086        bi->bi_connection_init = 0;
00087        bi->bi_connection_destroy = meta_back_conn_destroy;
00088 
00089        return 0;
00090 }
00091 
00092 int
00093 meta_back_db_init(
00094        Backend              *be,
00095        ConfigReply   *cr)
00096 {
00097        metainfo_t    *mi;
00098        int           i;
00099        BackendInfo   *bi;
00100 
00101        bi = backend_info( "ldap" );
00102        if ( !bi || !bi->bi_extra ) {
00103               Debug( LDAP_DEBUG_ANY,
00104                      "meta_back_db_init: needs back-ldap\n",
00105                      0, 0, 0 );
00106               return 1;
00107        }
00108 
00109        mi = ch_calloc( 1, sizeof( metainfo_t ) );
00110        if ( mi == NULL ) {
00111               return -1;
00112        }
00113 
00114        /* set default flags */
00115        mi->mi_flags =
00116               META_BACK_F_DEFER_ROOTDN_BIND;
00117 
00118        /*
00119         * At present the default is no default target;
00120         * this may change
00121         */
00122        mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
00123        mi->mi_bind_timeout.tv_sec = 0;
00124        mi->mi_bind_timeout.tv_usec = META_BIND_TIMEOUT;
00125 
00126        mi->mi_rebind_f = meta_back_default_rebind;
00127        mi->mi_urllist_f = meta_back_default_urllist;
00128 
00129        ldap_pvt_thread_mutex_init( &mi->mi_conninfo.lai_mutex );
00130        ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex );
00131 
00132        /* safe default */
00133        mi->mi_nretries = META_RETRY_DEFAULT;
00134        mi->mi_version = LDAP_VERSION3;
00135 
00136        for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
00137               mi->mi_conn_priv[ i ].mic_num = 0;
00138               LDAP_TAILQ_INIT( &mi->mi_conn_priv[ i ].mic_priv );
00139        }
00140        mi->mi_conn_priv_max = LDAP_BACK_CONN_PRIV_DEFAULT;
00141        
00142        mi->mi_ldap_extra = (ldap_extra_t *)bi->bi_extra;
00143 
00144        be->be_private = mi;
00145 
00146        return 0;
00147 }
00148 
00149 int
00150 meta_back_db_open(
00151        Backend              *be,
00152        ConfigReply   *cr )
00153 {
00154        metainfo_t    *mi = (metainfo_t *)be->be_private;
00155 
00156        int           i,
00157                      not_always = 0,
00158                      not_always_anon_proxyauthz = 0,
00159                      not_always_anon_non_prescriptive = 0,
00160                      rc;
00161 
00162        if ( mi->mi_ntargets == 0 ) {
00163               Debug( LDAP_DEBUG_ANY,
00164                      "meta_back_db_open: no targets defined\n",
00165                      0, 0, 0 );
00166               return 1;
00167        }
00168 
00169        for ( i = 0; i < mi->mi_ntargets; i++ ) {
00170               slap_bindconf sb = { BER_BVNULL };
00171               metatarget_t  *mt = mi->mi_targets[ i ];
00172 
00173               struct berval mapped;
00174 
00175               ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
00176               sb.sb_version = mt->mt_version;
00177               sb.sb_method = LDAP_AUTH_SIMPLE;
00178               BER_BVSTR( &sb.sb_binddn, "" );
00179 
00180               if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
00181                      rc = slap_discover_feature( &sb,
00182                                    slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
00183                                    LDAP_FEATURE_ABSOLUTE_FILTERS );
00184                      if ( rc == LDAP_COMPARE_TRUE ) {
00185                             mt->mt_flags |= LDAP_BACK_F_T_F;
00186                      }
00187               }
00188 
00189               if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
00190                      rc = slap_discover_feature( &sb,
00191                                    slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
00192                                    LDAP_EXOP_CANCEL );
00193                      if ( rc == LDAP_COMPARE_TRUE ) {
00194                             mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
00195                      }
00196               }
00197 
00198               if ( not_always == 0 ) {
00199                      if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
00200                             || mt->mt_idassert_authz != NULL )
00201                      {
00202                             not_always = 1;
00203                      }
00204               }
00205 
00206               if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
00207                      && !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
00208               {
00209                      Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
00210                             "target #%d inconsistent idassert configuration "
00211                             "(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
00212                             be->be_suffix[ 0 ].bv_val, i, 0 );
00213                      return 1;
00214               }
00215 
00216               if ( not_always_anon_proxyauthz == 0 ) {
00217                      if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
00218                      {
00219                             not_always_anon_proxyauthz = 1;
00220                      }
00221               }
00222 
00223               if ( not_always_anon_non_prescriptive == 0 ) {
00224                      if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
00225                      {
00226                             not_always_anon_non_prescriptive = 1;
00227                      }
00228               }
00229 
00230               BER_BVZERO( &mapped );
00231               ldap_back_map( &mt->mt_rwmap.rwm_at, 
00232                      &slap_schema.si_ad_entryDN->ad_cname, &mapped,
00233                      BACKLDAP_REMAP );
00234               if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
00235                      mt->mt_rep_flags |= REP_NO_ENTRYDN;
00236               }
00237 
00238               BER_BVZERO( &mapped );
00239               ldap_back_map( &mt->mt_rwmap.rwm_at, 
00240                      &slap_schema.si_ad_subschemaSubentry->ad_cname, &mapped,
00241                      BACKLDAP_REMAP );
00242               if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
00243                      mt->mt_rep_flags |= REP_NO_SUBSCHEMA;
00244               }
00245        }
00246 
00247        if ( not_always == 0 ) {
00248               mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
00249        }
00250 
00251        if ( not_always_anon_proxyauthz == 0 ) {
00252               mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;
00253 
00254        } else if ( not_always_anon_non_prescriptive == 0 ) {
00255               mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
00256        }
00257 
00258        return 0;
00259 }
00260 
00261 /*
00262  * meta_back_conn_free()
00263  *
00264  * actually frees a connection; the reference count must be 0,
00265  * and it must not (or no longer) be in the cache.
00266  */
00267 void
00268 meta_back_conn_free( 
00269        void          *v_mc )
00270 {
00271        metaconn_t           *mc = v_mc;
00272        int                  ntargets;
00273 
00274        assert( mc != NULL );
00275        assert( mc->mc_refcnt == 0 );
00276 
00277        /* at least one must be present... */
00278        ntargets = mc->mc_info->mi_ntargets;
00279        assert( ntargets > 0 );
00280 
00281        for ( ; ntargets--; ) {
00282               (void)meta_clear_one_candidate( NULL, mc, ntargets );
00283        }
00284 
00285        if ( !BER_BVISNULL( &mc->mc_local_ndn ) ) {
00286               free( mc->mc_local_ndn.bv_val );
00287        }
00288 
00289        free( mc );
00290 }
00291 
00292 static void
00293 mapping_free(
00294        void          *v_mapping )
00295 {
00296        struct ldapmapping *mapping = v_mapping;
00297        ch_free( mapping->src.bv_val );
00298        ch_free( mapping->dst.bv_val );
00299        ch_free( mapping );
00300 }
00301 
00302 static void
00303 mapping_dst_free(
00304        void          *v_mapping )
00305 {
00306        struct ldapmapping *mapping = v_mapping;
00307 
00308        if ( BER_BVISEMPTY( &mapping->dst ) ) {
00309               mapping_free( &mapping[ -1 ] );
00310        }
00311 }
00312 
00313 static void
00314 target_free(
00315        metatarget_t  *mt )
00316 {
00317        if ( mt->mt_uri ) {
00318               free( mt->mt_uri );
00319               ldap_pvt_thread_mutex_destroy( &mt->mt_uri_mutex );
00320        }
00321        if ( mt->mt_subtree ) {
00322               meta_subtree_destroy( mt->mt_subtree );
00323               mt->mt_subtree = NULL;
00324        }
00325        if ( !BER_BVISNULL( &mt->mt_psuffix ) ) {
00326               free( mt->mt_psuffix.bv_val );
00327        }
00328        if ( !BER_BVISNULL( &mt->mt_nsuffix ) ) {
00329               free( mt->mt_nsuffix.bv_val );
00330        }
00331        if ( !BER_BVISNULL( &mt->mt_binddn ) ) {
00332               free( mt->mt_binddn.bv_val );
00333        }
00334        if ( !BER_BVISNULL( &mt->mt_bindpw ) ) {
00335               free( mt->mt_bindpw.bv_val );
00336        }
00337        if ( !BER_BVISNULL( &mt->mt_idassert_authcID ) ) {
00338               ch_free( mt->mt_idassert_authcID.bv_val );
00339        }
00340        if ( !BER_BVISNULL( &mt->mt_idassert_authcDN ) ) {
00341               ch_free( mt->mt_idassert_authcDN.bv_val );
00342        }
00343        if ( !BER_BVISNULL( &mt->mt_idassert_passwd ) ) {
00344               ch_free( mt->mt_idassert_passwd.bv_val );
00345        }
00346        if ( !BER_BVISNULL( &mt->mt_idassert_authzID ) ) {
00347               ch_free( mt->mt_idassert_authzID.bv_val );
00348        }
00349        if ( !BER_BVISNULL( &mt->mt_idassert_sasl_mech ) ) {
00350               ch_free( mt->mt_idassert_sasl_mech.bv_val );
00351        }
00352        if ( !BER_BVISNULL( &mt->mt_idassert_sasl_realm ) ) {
00353               ch_free( mt->mt_idassert_sasl_realm.bv_val );
00354        }
00355        if ( mt->mt_idassert_authz != NULL ) {
00356               ber_bvarray_free( mt->mt_idassert_authz );
00357        }
00358        if ( mt->mt_rwmap.rwm_rw ) {
00359               rewrite_info_delete( &mt->mt_rwmap.rwm_rw );
00360        }
00361        avl_free( mt->mt_rwmap.rwm_oc.remap, mapping_dst_free );
00362        avl_free( mt->mt_rwmap.rwm_oc.map, mapping_free );
00363        avl_free( mt->mt_rwmap.rwm_at.remap, mapping_dst_free );
00364        avl_free( mt->mt_rwmap.rwm_at.map, mapping_free );
00365 
00366        free( mt );
00367 }
00368 
00369 int
00370 meta_back_db_destroy(
00371        Backend              *be,
00372        ConfigReply   *cr )
00373 {
00374        metainfo_t    *mi;
00375 
00376        if ( be->be_private ) {
00377               int i;
00378 
00379               mi = ( metainfo_t * )be->be_private;
00380 
00381               /*
00382                * Destroy the connection tree
00383                */
00384               ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
00385 
00386               if ( mi->mi_conninfo.lai_tree ) {
00387                      avl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free );
00388               }
00389               for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) {
00390                      while ( !LDAP_TAILQ_EMPTY( &mi->mi_conn_priv[ i ].mic_priv ) ) {
00391                             metaconn_t    *mc = LDAP_TAILQ_FIRST( &mi->mi_conn_priv[ i ].mic_priv );
00392 
00393                             LDAP_TAILQ_REMOVE( &mi->mi_conn_priv[ i ].mic_priv, mc, mc_q );
00394                             meta_back_conn_free( mc );
00395                      }
00396               }
00397 
00398               /*
00399                * Destroy the per-target stuff (assuming there's at
00400                * least one ...)
00401                */
00402               if ( mi->mi_targets != NULL ) {
00403                      for ( i = 0; i < mi->mi_ntargets; i++ ) {
00404                             metatarget_t  *mt = mi->mi_targets[ i ];
00405 
00406                             if ( META_BACK_TGT_QUARANTINE( mt ) ) {
00407                                    if ( mt->mt_quarantine.ri_num != mi->mi_quarantine.ri_num )
00408                                    {
00409                                           mi->mi_ldap_extra->retry_info_destroy( &mt->mt_quarantine );
00410                                    }
00411 
00412                                    ldap_pvt_thread_mutex_destroy( &mt->mt_quarantine_mutex );
00413                             }
00414 
00415                             target_free( mt );
00416                      }
00417 
00418                      free( mi->mi_targets );
00419               }
00420 
00421               ldap_pvt_thread_mutex_lock( &mi->mi_cache.mutex );
00422               if ( mi->mi_cache.tree ) {
00423                      avl_free( mi->mi_cache.tree, meta_dncache_free );
00424               }
00425               
00426               ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex );
00427               ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex );
00428 
00429               ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
00430               ldap_pvt_thread_mutex_destroy( &mi->mi_conninfo.lai_mutex );
00431 
00432               if ( mi->mi_candidates != NULL ) {
00433                      ber_memfree_x( mi->mi_candidates, NULL );
00434               }
00435 
00436               if ( META_BACK_QUARANTINE( mi ) ) {
00437                      mi->mi_ldap_extra->retry_info_destroy( &mi->mi_quarantine );
00438               }
00439        }
00440 
00441        free( be->be_private );
00442        return 0;
00443 }
00444 
00445 #if SLAPD_META == SLAPD_MOD_DYNAMIC
00446 
00447 /* conditionally define the init_module() function */
00448 SLAP_BACKEND_INIT_MODULE( meta )
00449 
00450 #endif /* SLAPD_META == SLAPD_MOD_DYNAMIC */
00451 
00452