Home | History | Annotate | Line # | Download | only in slapd
      1 /*	$NetBSD: init.c,v 1.4 2025/09/05 21:16:25 christos Exp $	*/
      2 
      3 /* init.c - initialize various things */
      4 /* $OpenLDAP$ */
      5 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6  *
      7  * Copyright 1998-2024 The OpenLDAP Foundation.
      8  * All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted only as authorized by the OpenLDAP
     12  * Public License.
     13  *
     14  * A copy of this license is available in the file LICENSE in the
     15  * top-level directory of the distribution or, alternatively, at
     16  * <http://www.OpenLDAP.org/license.html>.
     17  */
     18 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
     19  * All rights reserved.
     20  *
     21  * Redistribution and use in source and binary forms are permitted
     22  * provided that this notice is preserved and that due credit is given
     23  * to the University of Michigan at Ann Arbor. The name of the University
     24  * may not be used to endorse or promote products derived from this
     25  * software without specific prior written permission. This software
     26  * is provided ``as is'' without express or implied warranty.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __RCSID("$NetBSD: init.c,v 1.4 2025/09/05 21:16:25 christos Exp $");
     31 
     32 #include "portable.h"
     33 
     34 #include <stdio.h>
     35 
     36 #include <ac/socket.h>
     37 #include <ac/string.h>
     38 #include <ac/time.h>
     39 
     40 #include "slap.h"
     41 #include "lber_pvt.h"
     42 
     43 #include "ldap_rq.h"
     44 
     45 /*
     46  * read-only global variables or variables only written by the listener
     47  * thread (after they are initialized) - no need to protect them with a mutex.
     48  */
     49 int		slap_debug = 0;
     50 
     51 #ifdef LDAP_DEBUG
     52 int		ldap_syslog = LDAP_DEBUG_STATS;
     53 #else
     54 int		ldap_syslog;
     55 #endif
     56 
     57 #ifdef LOG_DEBUG
     58 int		ldap_syslog_level = LOG_DEBUG;
     59 #endif
     60 
     61 BerVarray default_referral = NULL;
     62 
     63 /*
     64  * global variables that need mutex protection
     65  */
     66 ldap_pvt_thread_pool_t	connection_pool;
     67 int		connection_pool_max = SLAP_MAX_WORKER_THREADS;
     68 int		connection_pool_queues = 1;
     69 int		slap_tool_thread_max = 1;
     70 
     71 slap_counters_t			slap_counters, *slap_counters_list;
     72 
     73 static const char* slap_name = NULL;
     74 int slapMode = SLAP_UNDEFINED_MODE;
     75 
     76 int
     77 slap_init( int mode, const char *name )
     78 {
     79 	int rc;
     80 
     81 	assert( mode );
     82 
     83 	if ( slapMode != SLAP_UNDEFINED_MODE ) {
     84 		/* Make sure we write something to stderr */
     85 		slap_debug |= LDAP_DEBUG_NONE;
     86 		Debug( LDAP_DEBUG_ANY,
     87 		 "%s init: init called twice (old=%d, new=%d)\n",
     88 		 name, slapMode, mode );
     89 
     90 		return 1;
     91 	}
     92 
     93 	slapMode = mode;
     94 
     95 	slap_op_init();
     96 
     97 	ldap_pvt_thread_mutex_init( &slapd_init_mutex );
     98 	ldap_pvt_thread_cond_init( &slapd_init_cond );
     99 
    100 #ifdef SLAPD_MODULES
    101 	if ( module_init() != 0 ) {
    102 		slap_debug |= LDAP_DEBUG_NONE;
    103 		Debug( LDAP_DEBUG_ANY,
    104 		    "%s: module_init failed\n",
    105 			name );
    106 		return 1;
    107 	}
    108 #endif
    109 
    110 	if ( slap_schema_init( ) != 0 ) {
    111 		slap_debug |= LDAP_DEBUG_NONE;
    112 		Debug( LDAP_DEBUG_ANY,
    113 		    "%s: slap_schema_init failed\n",
    114 		    name );
    115 		return 1;
    116 	}
    117 
    118 	if ( filter_init() != 0 ) {
    119 		slap_debug |= LDAP_DEBUG_NONE;
    120 		Debug( LDAP_DEBUG_ANY,
    121 		    "%s: filter_init failed\n",
    122 		    name );
    123 		return 1;
    124 	}
    125 
    126 	if ( entry_init() != 0 ) {
    127 		slap_debug |= LDAP_DEBUG_NONE;
    128 		Debug( LDAP_DEBUG_ANY,
    129 		    "%s: entry_init failed\n",
    130 		    name );
    131 		return 1;
    132 	}
    133 
    134 	switch ( slapMode & SLAP_MODE ) {
    135 	case SLAP_SERVER_MODE:
    136 		root_dse_init();
    137 
    138 		/* FALLTHRU */
    139 	case SLAP_TOOL_MODE:
    140 		Debug( LDAP_DEBUG_TRACE,
    141 			"%s init: initiated %s.\n",	name,
    142 			(mode & SLAP_MODE) == SLAP_TOOL_MODE ? "tool" : "server" );
    143 
    144 		slap_name = name;
    145 
    146 		ldap_pvt_thread_pool_init_q( &connection_pool,
    147 				connection_pool_max, 0, connection_pool_queues);
    148 
    149 		slap_counters_init( &slap_counters );
    150 
    151 		ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
    152 		LDAP_STAILQ_INIT( &slapd_rq.task_list );
    153 		LDAP_STAILQ_INIT( &slapd_rq.run_list );
    154 
    155 		slap_passwd_init();
    156 
    157 		rc = slap_sasl_init();
    158 
    159 		if( rc == 0 ) {
    160 			rc = backend_init( );
    161 		}
    162 		if ( rc )
    163 			return rc;
    164 
    165 		break;
    166 
    167 	default:
    168 		slap_debug |= LDAP_DEBUG_NONE;
    169 		Debug( LDAP_DEBUG_ANY,
    170 			"%s init: undefined mode (%d).\n", name, mode );
    171 
    172 		rc = 1;
    173 		break;
    174 	}
    175 
    176 	if ( slap_controls_init( ) != 0 ) {
    177 		slap_debug |= LDAP_DEBUG_NONE;
    178 		Debug( LDAP_DEBUG_ANY,
    179 		    "%s: slap_controls_init failed\n",
    180 		    name );
    181 		return 1;
    182 	}
    183 
    184 	if ( frontend_init() ) {
    185 		slap_debug |= LDAP_DEBUG_NONE;
    186 		Debug( LDAP_DEBUG_ANY,
    187 		    "%s: frontend_init failed\n",
    188 		    name );
    189 		return 1;
    190 	}
    191 
    192 	if ( overlay_init() ) {
    193 		slap_debug |= LDAP_DEBUG_NONE;
    194 		Debug( LDAP_DEBUG_ANY,
    195 		    "%s: overlay_init failed\n",
    196 		    name );
    197 		return 1;
    198 	}
    199 
    200 	if ( glue_sub_init() ) {
    201 		slap_debug |= LDAP_DEBUG_NONE;
    202 		Debug( LDAP_DEBUG_ANY,
    203 		    "%s: glue/subordinate init failed\n",
    204 		    name );
    205 
    206 		return 1;
    207 	}
    208 
    209 	if ( acl_init() ) {
    210 		slap_debug |= LDAP_DEBUG_NONE;
    211 		Debug( LDAP_DEBUG_ANY,
    212 		    "%s: acl_init failed\n",
    213 		    name );
    214 		return 1;
    215 	}
    216 
    217 	return rc;
    218 }
    219 
    220 int slap_startup( Backend *be )
    221 {
    222 	int rc;
    223 	Debug( LDAP_DEBUG_TRACE,
    224 		"%s startup: initiated.\n",
    225 		slap_name );
    226 
    227 	rc = backend_startup( be );
    228 	if ( !rc && ( slapMode & SLAP_SERVER_MODE ))
    229 		slapMode |= SLAP_SERVER_RUNNING;
    230 	return rc;
    231 }
    232 
    233 int slap_shutdown( Backend *be )
    234 {
    235 	Debug( LDAP_DEBUG_TRACE,
    236 		"%s shutdown: initiated\n",
    237 		slap_name );
    238 
    239 	/* Make sure the pool stops now even if we did not start up fully */
    240 	ldap_pvt_thread_pool_close( &connection_pool, 1 );
    241 
    242 	/* let backends do whatever cleanup they need to do */
    243 	return backend_shutdown( be );
    244 }
    245 
    246 int slap_destroy(void)
    247 {
    248 	int rc;
    249 
    250 	Debug( LDAP_DEBUG_TRACE,
    251 		"%s destroy: freeing system resources.\n",
    252 		slap_name );
    253 
    254 	if ( default_referral ) {
    255 		ber_bvarray_free( default_referral );
    256 	}
    257 
    258 	ldap_pvt_thread_pool_free( &connection_pool );
    259 
    260 	/* clear out any thread-keys for the main thread */
    261 	ldap_pvt_thread_pool_context_reset( ldap_pvt_thread_pool_context());
    262 
    263 	rc = backend_destroy();
    264 
    265 	slap_sasl_destroy();
    266 
    267 	/* rootdse destroy goes before entry_destroy()
    268 	 * because it may use entry_free() */
    269 	root_dse_destroy();
    270 	entry_destroy();
    271 
    272 	switch ( slapMode & SLAP_MODE ) {
    273 	case SLAP_SERVER_MODE:
    274 	case SLAP_TOOL_MODE:
    275 		slap_counters_destroy( &slap_counters );
    276 		break;
    277 
    278 	default:
    279 		Debug( LDAP_DEBUG_ANY,
    280 			"slap_destroy(): undefined mode (%d).\n", slapMode );
    281 
    282 		rc = 1;
    283 		break;
    284 
    285 	}
    286 
    287 	ldap_pvt_thread_mutex_destroy( &slapd_init_mutex );
    288 	ldap_pvt_thread_cond_destroy( &slapd_init_cond );
    289 
    290 	slap_op_destroy();
    291 
    292 	ldap_pvt_thread_destroy();
    293 
    294 	/* should destroy the above mutex */
    295 	return rc;
    296 }
    297 
    298 void slap_counters_init( slap_counters_t *sc )
    299 {
    300 	int i;
    301 
    302 	ldap_pvt_thread_mutex_init( &sc->sc_mutex );
    303 	ldap_pvt_mp_init( sc->sc_bytes );
    304 	ldap_pvt_mp_init( sc->sc_pdu );
    305 	ldap_pvt_mp_init( sc->sc_entries );
    306 	ldap_pvt_mp_init( sc->sc_refs );
    307 
    308 	ldap_pvt_mp_init( sc->sc_ops_initiated );
    309 	ldap_pvt_mp_init( sc->sc_ops_completed );
    310 
    311 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
    312 		ldap_pvt_mp_init( sc->sc_ops_initiated_[ i ] );
    313 		ldap_pvt_mp_init( sc->sc_ops_completed_[ i ] );
    314 	}
    315 }
    316 
    317 void slap_counters_destroy( slap_counters_t *sc )
    318 {
    319 	int i;
    320 
    321 	ldap_pvt_thread_mutex_destroy( &sc->sc_mutex );
    322 	ldap_pvt_mp_clear( sc->sc_bytes );
    323 	ldap_pvt_mp_clear( sc->sc_pdu );
    324 	ldap_pvt_mp_clear( sc->sc_entries );
    325 	ldap_pvt_mp_clear( sc->sc_refs );
    326 
    327 	ldap_pvt_mp_clear( sc->sc_ops_initiated );
    328 	ldap_pvt_mp_clear( sc->sc_ops_completed );
    329 
    330 	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
    331 		ldap_pvt_mp_clear( sc->sc_ops_initiated_[ i ] );
    332 		ldap_pvt_mp_clear( sc->sc_ops_completed_[ i ] );
    333 	}
    334 }
    335 
    336