143412Snewton/* $NetBSD: init.c,v 1.3 2021/08/14 16:14:59 christos Exp $ */ 243412Snewton 343412Snewton/* init.c - initialize ldap backend */ 443412Snewton/* $OpenLDAP$ */ 543412Snewton/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 643412Snewton * 743412Snewton * Copyright 2003-2021 The OpenLDAP Foundation. 843412Snewton * Portions Copyright 1999-2003 Howard Chu. 943412Snewton * Portions Copyright 2000-2003 Pierangelo Masarati. 1043412Snewton * All rights reserved. 1143412Snewton * 1243412Snewton * Redistribution and use in source and binary forms, with or without 1343412Snewton * modification, are permitted only as authorized by the OpenLDAP 1443412Snewton * Public License. 1543412Snewton * 1643412Snewton * A copy of this license is available in the file LICENSE in the 1743412Snewton * top-level directory of the distribution or, alternatively, at 1843412Snewton * <http://www.OpenLDAP.org/license.html>. 1943412Snewton */ 2043412Snewton/* ACKNOWLEDGEMENTS: 2143412Snewton * This work was initially developed by the Howard Chu for inclusion 2243412Snewton * in OpenLDAP Software and subsequently enhanced by Pierangelo 2343412Snewton * Masarati. 2443412Snewton */ 2543412Snewton 2643412Snewton#include <sys/cdefs.h> 2743412Snewton__RCSID("$NetBSD: init.c,v 1.3 2021/08/14 16:14:59 christos Exp $"); 2843412Snewton 2949267Snewton#include "portable.h" 3050477Speter 3143412Snewton#include <stdio.h> 3243412Snewton 3343412Snewton#include <ac/string.h> 3443412Snewton#include <ac/socket.h> 3543412Snewton 3643412Snewton#include "slap.h" 3743412Snewton#include "slap-config.h" 3843412Snewton#include "back-ldap.h" 3943412Snewton#include "ldap_rq.h" 4043412Snewton 4143412Snewtonstatic const ldap_extra_t ldap_extra = { 4243412Snewton ldap_back_proxy_authz_ctrl, 4343412Snewton ldap_back_controls_free, 4443412Snewton slap_idassert_authzfrom_parse, 4543412Snewton slap_idassert_passthru_parse_cf, 4643412Snewton slap_idassert_parse, 4743412Snewton slap_retry_info_destroy, 4843412Snewton slap_retry_info_parse, 4943412Snewton slap_retry_info_unparse, 5043412Snewton ldap_back_connid2str 5143412Snewton}; 5243412Snewton 5343412Snewtonint 5443412Snewtonldap_back_open( BackendInfo *bi ) 5543412Snewton{ 5643412Snewton bi->bi_controls = slap_known_controls; 5743412Snewton return 0; 5843412Snewton} 5943412Snewton 6043412Snewtonint 6143412Snewtonldap_back_initialize( BackendInfo *bi ) 6243412Snewton{ 6343412Snewton int rc; 6443412Snewton 6543412Snewton bi->bi_flags = 6643412Snewton#ifdef LDAP_DYNAMIC_OBJECTS 6743412Snewton /* this is set because all the support a proxy has to provide 6843412Snewton * is the capability to forward the refresh exop, and to 6943412Snewton * pass thru entries that contain the dynamicObject class 7043412Snewton * and the entryTtl attribute */ 7143412Snewton SLAP_BFLAG_DYNAMIC | 7243412Snewton#endif /* LDAP_DYNAMIC_OBJECTS */ 7343412Snewton 7443412Snewton /* back-ldap recognizes RFC4525 increment; 7543412Snewton * let the remote server complain, if needed (ITS#5912) */ 7643412Snewton SLAP_BFLAG_INCREMENT; 7743412Snewton 7843412Snewton bi->bi_open = ldap_back_open; 7943412Snewton bi->bi_config = 0; 8043412Snewton bi->bi_close = 0; 8143412Snewton bi->bi_destroy = 0; 8243412Snewton 8343412Snewton bi->bi_db_init = ldap_back_db_init; 8443412Snewton bi->bi_db_config = config_generic_wrapper; 8543412Snewton bi->bi_db_open = ldap_back_db_open; 8643412Snewton bi->bi_db_close = ldap_back_db_close; 8743412Snewton bi->bi_db_destroy = ldap_back_db_destroy; 8843412Snewton 8943412Snewton bi->bi_op_bind = ldap_back_bind; 9043412Snewton bi->bi_op_unbind = 0; 9143412Snewton bi->bi_op_search = ldap_back_search; 9243412Snewton bi->bi_op_compare = ldap_back_compare; 9343412Snewton bi->bi_op_modify = ldap_back_modify; 9443412Snewton bi->bi_op_modrdn = ldap_back_modrdn; 9543412Snewton bi->bi_op_add = ldap_back_add; 9643412Snewton bi->bi_op_delete = ldap_back_delete; 9743412Snewton bi->bi_op_abandon = 0; 9843412Snewton 9943412Snewton bi->bi_extended = ldap_back_extended; 10043412Snewton 10143412Snewton bi->bi_chk_referrals = 0; 10243412Snewton bi->bi_entry_get_rw = ldap_back_entry_get; 10343412Snewton 10443412Snewton bi->bi_connection_init = 0; 10543412Snewton bi->bi_connection_destroy = ldap_back_conn_destroy; 10643412Snewton 10743412Snewton bi->bi_extra = (void *)&ldap_extra; 10843412Snewton 10943412Snewton rc = ldap_back_init_cf( bi ); 11043412Snewton if ( rc ) { 11143412Snewton return rc; 11243412Snewton } 11343412Snewton 11443412Snewton rc = chain_initialize(); 11543412Snewton if ( rc ) { 11643412Snewton return rc; 11743412Snewton } 11843412Snewton 11943412Snewton rc = pbind_initialize(); 12043412Snewton if ( rc ) { 12143412Snewton return rc; 12243412Snewton } 12343412Snewton 12443412Snewton#ifdef SLAP_DISTPROC 12543412Snewton rc = distproc_initialize(); 12643412Snewton if ( rc ) { 12743412Snewton return rc; 12843412Snewton } 12943412Snewton#endif 13043412Snewton return rc; 13143412Snewton} 13243412Snewton 13343412Snewtonint 13443412Snewtonldap_back_db_init( Backend *be, ConfigReply *cr ) 13543412Snewton{ 13643412Snewton ldapinfo_t *li; 13743412Snewton int rc; 13843412Snewton unsigned i; 13943412Snewton 14043412Snewton li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) ); 14143412Snewton if ( li == NULL ) { 14243412Snewton return -1; 14343412Snewton } 14443412Snewton 14543412Snewton li->li_rebind_f = ldap_back_default_rebind; 14643412Snewton li->li_urllist_f = ldap_back_default_urllist; 14743412Snewton li->li_urllist_p = li; 14843412Snewton ldap_pvt_thread_mutex_init( &li->li_uri_mutex ); 14943412Snewton 15043412Snewton BER_BVZERO( &li->li_acl_authcID ); 15143412Snewton BER_BVZERO( &li->li_acl_authcDN ); 15243412Snewton BER_BVZERO( &li->li_acl_passwd ); 15343412Snewton 15443412Snewton li->li_acl_authmethod = LDAP_AUTH_NONE; 15543412Snewton BER_BVZERO( &li->li_acl_sasl_mech ); 15643412Snewton li->li_acl.sb_tls = SB_TLS_DEFAULT; 15743412Snewton 15843412Snewton li->li_idassert_mode = LDAP_BACK_IDASSERT_LEGACY; 15943412Snewton 16043412Snewton BER_BVZERO( &li->li_idassert_authcID ); 16143412Snewton BER_BVZERO( &li->li_idassert_authcDN ); 16243412Snewton BER_BVZERO( &li->li_idassert_passwd ); 16343412Snewton 16443412Snewton BER_BVZERO( &li->li_idassert_authzID ); 16543412Snewton 16643412Snewton li->li_idassert_authmethod = LDAP_AUTH_NONE; 16743412Snewton BER_BVZERO( &li->li_idassert_sasl_mech ); 16843412Snewton li->li_idassert_tls = SB_TLS_DEFAULT; 16943412Snewton 17043412Snewton /* by default, use proxyAuthz control on each operation */ 17143412Snewton li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE; 17243412Snewton 17343412Snewton li->li_idassert_authz = NULL; 17443412Snewton 17543412Snewton /* initialize flags */ 17643412Snewton li->li_flags = LDAP_BACK_F_CHASE_REFERRALS; 17743412Snewton 17843412Snewton /* initialize version */ 17943412Snewton li->li_version = LDAP_VERSION3; 18043412Snewton 18143412Snewton ldap_pvt_thread_mutex_init( &li->li_conninfo.lai_mutex ); 18243412Snewton 18343412Snewton for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) { 18443412Snewton li->li_conn_priv[ i ].lic_num = 0; 18543412Snewton LDAP_TAILQ_INIT( &li->li_conn_priv[ i ].lic_priv ); 18643412Snewton } 18743412Snewton li->li_conn_priv_max = LDAP_BACK_CONN_PRIV_DEFAULT; 18843412Snewton 18943412Snewton ldap_pvt_thread_mutex_init( &li->li_counter_mutex ); 19043412Snewton for ( i = 0; i < SLAP_OP_LAST; i++ ) { 19143412Snewton ldap_pvt_mp_init( li->li_ops_completed[ i ] ); 19243412Snewton } 19343412Snewton 19443412Snewton li->li_conn_expire_task = NULL; 19543412Snewton 19643412Snewton be->be_private = li; 19743412Snewton SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD; 19843412Snewton 19943412Snewton be->be_cf_ocs = be->bd_info->bi_cf_ocs; 20043412Snewton 20143412Snewton rc = ldap_back_monitor_db_init( be ); 20243412Snewton if ( rc != 0 ) { 20343412Snewton /* ignore, by now */ 20443412Snewton rc = 0; 20543412Snewton } 20643412Snewton 20743412Snewton return rc; 20843412Snewton} 20943412Snewton 21043412Snewtonint 21143412Snewtonldap_back_db_open( BackendDB *be, ConfigReply *cr ) 21243412Snewton{ 21343412Snewton ldapinfo_t *li = (ldapinfo_t *)be->be_private; 21443412Snewton 21543412Snewton slap_bindconf sb = { BER_BVNULL }; 21643412Snewton int rc = 0; 21743412Snewton 21843412Snewton Debug( LDAP_DEBUG_TRACE, 21943412Snewton "ldap_back_db_open: URI=%s\n", 22043412Snewton li->li_uri != NULL ? li->li_uri : "" ); 22143412Snewton 22243412Snewton /* by default, use proxyAuthz control on each operation */ 22343412Snewton switch ( li->li_idassert_mode ) { 22443412Snewton case LDAP_BACK_IDASSERT_LEGACY: 22543412Snewton case LDAP_BACK_IDASSERT_SELF: 22643412Snewton /* however, since admin connections are pooled and shared, 22743412Snewton * only static authzIDs can be native */ 22843412Snewton li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; 22943412Snewton break; 23043412Snewton 23143412Snewton default: 23243412Snewton break; 23343412Snewton } 23443412Snewton 23543412Snewton ber_str2bv( li->li_uri, 0, 0, &sb.sb_uri ); 23643412Snewton sb.sb_version = li->li_version; 23743412Snewton sb.sb_method = LDAP_AUTH_SIMPLE; 23843412Snewton BER_BVSTR( &sb.sb_binddn, "" ); 23943412Snewton 24043412Snewton if ( LDAP_BACK_T_F_DISCOVER( li ) && !LDAP_BACK_T_F( li ) ) { 24143412Snewton rc = slap_discover_feature( &sb, 24243412Snewton slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, 24343412Snewton LDAP_FEATURE_ABSOLUTE_FILTERS ); 24443412Snewton if ( rc == LDAP_COMPARE_TRUE ) { 24543412Snewton li->li_flags |= LDAP_BACK_F_T_F; 24643412Snewton } 24743412Snewton } 24843412Snewton 24943412Snewton if ( LDAP_BACK_CANCEL_DISCOVER( li ) && !LDAP_BACK_CANCEL( li ) ) { 25043412Snewton rc = slap_discover_feature( &sb, 25143412Snewton slap_schema.si_ad_supportedExtension->ad_cname.bv_val, 25243412Snewton LDAP_EXOP_CANCEL ); 25343412Snewton if ( rc == LDAP_COMPARE_TRUE ) { 25443412Snewton li->li_flags |= LDAP_BACK_F_CANCEL_EXOP; 25543412Snewton } 25643412Snewton } 25743412Snewton 25843412Snewton /* monitor setup */ 25943412Snewton rc = ldap_back_monitor_db_open( be ); 26043412Snewton if ( rc != 0 ) { 26143412Snewton /* ignore by now */ 26243412Snewton rc = 0; 26343412Snewton } 26443412Snewton 26543412Snewton li->li_flags |= LDAP_BACK_F_ISOPEN; 26643412Snewton 26743412Snewton return rc; 26843412Snewton} 26943412Snewton 27043412Snewtonvoid 27143412Snewtonldap_back_conn_free( void *v_lc ) 27243412Snewton{ 27343412Snewton ldapconn_t *lc = v_lc; 27443412Snewton 27543412Snewton if ( lc->lc_ld != NULL ) { 27643412Snewton ldap_unbind_ext( lc->lc_ld, NULL, NULL ); 27743412Snewton } 27843412Snewton if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) { 27943412Snewton ch_free( lc->lc_bound_ndn.bv_val ); 28043412Snewton } 28143412Snewton if ( !BER_BVISNULL( &lc->lc_cred ) ) { 28243412Snewton memset( lc->lc_cred.bv_val, 0, lc->lc_cred.bv_len ); 28343412Snewton ch_free( lc->lc_cred.bv_val ); 28443412Snewton } 28543412Snewton if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) { 28643412Snewton ch_free( lc->lc_local_ndn.bv_val ); 28743412Snewton } 28843412Snewton lc->lc_q.tqe_prev = NULL; 28943412Snewton lc->lc_q.tqe_next = NULL; 29043412Snewton ch_free( lc ); 29143412Snewton} 29243412Snewton 29343412Snewtonint 29443412Snewtonldap_back_db_close( Backend *be, ConfigReply *cr ) 29543412Snewton{ 29643412Snewton int rc = 0; 29743412Snewton 29843412Snewton if ( be->be_private ) { 29943412Snewton rc = ldap_back_monitor_db_close( be ); 30043412Snewton } 30143412Snewton 30243412Snewton return rc; 30343412Snewton} 30443412Snewton 30543412Snewtonint 30643412Snewtonldap_back_db_destroy( Backend *be, ConfigReply *cr ) 30743412Snewton{ 30843412Snewton if ( be->be_private ) { 30943412Snewton ldapinfo_t *li = ( ldapinfo_t * )be->be_private; 31043412Snewton unsigned i; 31143412Snewton 31243412Snewton (void)ldap_back_monitor_db_destroy( be ); 31343412Snewton 31443412Snewton /* Stop and remove the task that prunes expired connections */ 31543412Snewton if ( li->li_conn_expire_task != NULL ) { 31643412Snewton ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); 31743412Snewton if ( ldap_pvt_runqueue_isrunning( &slapd_rq, li->li_conn_expire_task ) ) { 31843412Snewton ldap_pvt_runqueue_stoptask( &slapd_rq, li->li_conn_expire_task ); 31943412Snewton } 32043412Snewton ldap_pvt_runqueue_remove( &slapd_rq, li->li_conn_expire_task ); 32143412Snewton ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); 32243412Snewton } 32343412Snewton 32443412Snewton ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex ); 32543412Snewton 32643412Snewton if ( li->li_uri != NULL ) { 32743412Snewton ch_free( li->li_uri ); 32843412Snewton li->li_uri = NULL; 32943412Snewton 33043412Snewton assert( li->li_bvuri != NULL ); 33143412Snewton ber_bvarray_free( li->li_bvuri ); 33243412Snewton li->li_bvuri = NULL; 33343412Snewton } 33443412Snewton 33543412Snewton bindconf_free( &li->li_tls ); 33643412Snewton bindconf_free( &li->li_acl ); 33743412Snewton bindconf_free( &li->li_idassert.si_bc ); 33843412Snewton 33943412Snewton if ( li->li_idassert_authz != NULL ) { 34049267Snewton ber_bvarray_free( li->li_idassert_authz ); 34149267Snewton li->li_idassert_authz = NULL; 34243412Snewton } 34343412Snewton if ( li->li_conninfo.lai_tree ) { 34443412Snewton ldap_tavl_free( li->li_conninfo.lai_tree, ldap_back_conn_free ); 34543412Snewton } 34643412Snewton for ( i = LDAP_BACK_PCONN_FIRST; i < LDAP_BACK_PCONN_LAST; i++ ) { 34743412Snewton while ( !LDAP_TAILQ_EMPTY( &li->li_conn_priv[ i ].lic_priv ) ) { 34843412Snewton ldapconn_t *lc = LDAP_TAILQ_FIRST( &li->li_conn_priv[ i ].lic_priv ); 34943412Snewton 35043412Snewton LDAP_TAILQ_REMOVE( &li->li_conn_priv[ i ].lic_priv, lc, lc_q ); 35143412Snewton ldap_back_conn_free( lc ); 35243412Snewton } 35343412Snewton } 35443412Snewton if ( LDAP_BACK_QUARANTINE( li ) ) { 35543412Snewton slap_retry_info_destroy( &li->li_quarantine ); 35643412Snewton ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex ); 35743412Snewton } 35843412Snewton 35943412Snewton ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex ); 36043412Snewton ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex ); 36143412Snewton ldap_pvt_thread_mutex_destroy( &li->li_uri_mutex ); 36243412Snewton 36343412Snewton for ( i = 0; i < SLAP_OP_LAST; i++ ) { 36443412Snewton ldap_pvt_mp_clear( li->li_ops_completed[ i ] ); 36543412Snewton } 36643412Snewton ldap_pvt_thread_mutex_destroy( &li->li_counter_mutex ); 36743412Snewton } 36843412Snewton 36943412Snewton ch_free( be->be_private ); 37043412Snewton 37143412Snewton return 0; 37243412Snewton} 37343412Snewton 37443412Snewton#if SLAPD_LDAP == SLAPD_MOD_DYNAMIC 37543412Snewton 37643412Snewton/* conditionally define the init_module() function */ 37743412SnewtonSLAP_BACKEND_INIT_MODULE( ldap ) 37843412Snewton 37943412Snewton#endif /* SLAPD_LDAP == SLAPD_MOD_DYNAMIC */ 38043412Snewton