1/* $NetBSD: init.c,v 1.3 2021/08/14 16:14:58 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-2021 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.3 2021/08/14 16:14:58 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 */ 49int slap_debug = 0; 50 51#ifdef LDAP_DEBUG 52int ldap_syslog = LDAP_DEBUG_STATS; 53#else 54int ldap_syslog; 55#endif 56 57#ifdef LOG_DEBUG 58int ldap_syslog_level = LOG_DEBUG; 59#endif 60 61BerVarray default_referral = NULL; 62 63/* 64 * global variables that need mutex protection 65 */ 66ldap_pvt_thread_pool_t connection_pool; 67int connection_pool_max = SLAP_MAX_WORKER_THREADS; 68int connection_pool_queues = 1; 69int slap_tool_thread_max = 1; 70 71slap_counters_t slap_counters, *slap_counters_list; 72 73static const char* slap_name = NULL; 74int slapMode = SLAP_UNDEFINED_MODE; 75 76int 77slap_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 220int 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 233int 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 246int 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 298void 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 317void 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