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 */ 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