init.c 6.99 KB
Newer Older
Kurt Zeilenga's avatar
Kurt Zeilenga committed
1
/* init.c - initialize various things */
2
/* $OpenLDAP$ */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
3
4
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
5
 * Copyright 1998-2021 The OpenLDAP Foundation.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */
/* Portions Copyright (c) 1995 Regents of the University of Michigan.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of Michigan at Ann Arbor. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific prior written permission. This software
 * is provided ``as is'' without express or implied warranty.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
25
 */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
26

Kurt Zeilenga's avatar
Kurt Zeilenga committed
27
28
#include "portable.h"

Kurt Zeilenga's avatar
Kurt Zeilenga committed
29
#include <stdio.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
30
31
32
33
34

#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>

Kurt Zeilenga's avatar
Kurt Zeilenga committed
35
#include "slap.h"
36
#include "lber_pvt.h"
Kurt Zeilenga's avatar
Kurt Zeilenga committed
37

38
39
#include "ldap_rq.h"

40
41
42
43
44
45
/*
 * read-only global variables or variables only written by the listener
 * thread (after they are initialized) - no need to protect them with a mutex.
 */
int		slap_debug = 0;

46
47
48
49
50
51
52
53
54
55
56
57
#ifdef LDAP_DEBUG
int		ldap_syslog = LDAP_DEBUG_STATS;
#else
int		ldap_syslog;
#endif

#ifdef LOG_DEBUG
int		ldap_syslog_level = LOG_DEBUG;
#endif

BerVarray default_referral = NULL;

58
59
60
/*
 * global variables that need mutex protection
 */
61
ldap_pvt_thread_pool_t	connection_pool;
Howard Chu's avatar
Howard Chu committed
62
63
int		connection_pool_max = SLAP_MAX_WORKER_THREADS;
int		connection_pool_queues = 1;
64
int		slap_tool_thread_max = 1;
65

66
slap_counters_t			slap_counters, *slap_counters_list;
67

Kurt Zeilenga's avatar
Kurt Zeilenga committed
68
static const char* slap_name = NULL;
69
int slapMode = SLAP_UNDEFINED_MODE;
70
71

int
Kurt Zeilenga's avatar
Kurt Zeilenga committed
72
slap_init( int mode, const char *name )
Kurt Zeilenga's avatar
Kurt Zeilenga committed
73
{
74
75
	int rc;

76
77
	assert( mode );

78
	if ( slapMode != SLAP_UNDEFINED_MODE ) {
79
		/* Make sure we write something to stderr */
80
		slap_debug |= LDAP_DEBUG_NONE;
81
		Debug( LDAP_DEBUG_ANY,
Gary Williams's avatar
Gary Williams committed
82
83
		 "%s init: init called twice (old=%d, new=%d)\n",
		 name, slapMode, mode );
84

85
86
87
88
89
		return 1;
	}

	slapMode = mode;

90
91
	slap_op_init();

92
	ldap_pvt_thread_mutex_init( &slapd_init_mutex );
93
94
	ldap_pvt_thread_cond_init( &slapd_init_cond );

95
96
#ifdef SLAPD_MODULES
	if ( module_init() != 0 ) {
97
		slap_debug |= LDAP_DEBUG_NONE;
98
99
		Debug( LDAP_DEBUG_ANY,
		    "%s: module_init failed\n",
100
			name );
101
102
103
104
105
		return 1;
	}
#endif

	if ( slap_schema_init( ) != 0 ) {
106
		slap_debug |= LDAP_DEBUG_NONE;
107
108
		Debug( LDAP_DEBUG_ANY,
		    "%s: slap_schema_init failed\n",
109
		    name );
110
111
112
		return 1;
	}

113
114
115
116
	if ( filter_init() != 0 ) {
		slap_debug |= LDAP_DEBUG_NONE;
		Debug( LDAP_DEBUG_ANY,
		    "%s: filter_init failed\n",
117
		    name );
118
119
120
		return 1;
	}

121
122
123
124
	if ( entry_init() != 0 ) {
		slap_debug |= LDAP_DEBUG_NONE;
		Debug( LDAP_DEBUG_ANY,
		    "%s: entry_init failed\n",
125
		    name );
126
127
		return 1;
	}
128

129
	switch ( slapMode & SLAP_MODE ) {
130
	case SLAP_SERVER_MODE:
131
		root_dse_init();
132
133

		/* FALLTHRU */
134
135
136
	case SLAP_TOOL_MODE:
		Debug( LDAP_DEBUG_TRACE,
			"%s init: initiated %s.\n",	name,
137
			(mode & SLAP_MODE) == SLAP_TOOL_MODE ? "tool" : "server" );
138
139

		slap_name = name;
140

Howard Chu's avatar
Howard Chu committed
141
		ldap_pvt_thread_pool_init_q( &connection_pool,
Howard Chu's avatar
Howard Chu committed
142
				connection_pool_max, 0, connection_pool_queues);
143

144
		slap_counters_init( &slap_counters );
145

146
147
148
149
		ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
		LDAP_STAILQ_INIT( &slapd_rq.task_list );
		LDAP_STAILQ_INIT( &slapd_rq.run_list );

150
		slap_passwd_init();
151

152
		rc = slap_sasl_init();
153

154
155
156
		if( rc == 0 ) {
			rc = backend_init( );
		}
157
158
		if ( rc )
			return rc;
159

160
		break;
161

162
	default:
163
		slap_debug |= LDAP_DEBUG_NONE;
164
		Debug( LDAP_DEBUG_ANY,
165
			"%s init: undefined mode (%d).\n", name, mode );
166

167
168
		rc = 1;
		break;
169
	}
170

171
	if ( slap_controls_init( ) != 0 ) {
172
		slap_debug |= LDAP_DEBUG_NONE;
173
174
		Debug( LDAP_DEBUG_ANY,
		    "%s: slap_controls_init failed\n",
175
		    name );
176
177
178
179
		return 1;
	}

	if ( frontend_init() ) {
180
		slap_debug |= LDAP_DEBUG_NONE;
181
182
		Debug( LDAP_DEBUG_ANY,
		    "%s: frontend_init failed\n",
183
		    name );
184
185
186
187
		return 1;
	}

	if ( overlay_init() ) {
188
		slap_debug |= LDAP_DEBUG_NONE;
189
190
		Debug( LDAP_DEBUG_ANY,
		    "%s: overlay_init failed\n",
191
		    name );
192
193
194
		return 1;
	}

195
	if ( glue_sub_init() ) {
196
		slap_debug |= LDAP_DEBUG_NONE;
197
198
		Debug( LDAP_DEBUG_ANY,
		    "%s: glue/subordinate init failed\n",
199
		    name );
200
201
202
203

		return 1;
	}

204
	if ( acl_init() ) {
205
		slap_debug |= LDAP_DEBUG_NONE;
206
207
		Debug( LDAP_DEBUG_ANY,
		    "%s: acl_init failed\n",
208
		    name );
209
210
		return 1;
	}
Pierangelo Masarati's avatar
Pierangelo Masarati committed
211

212
213
214
	return rc;
}

215
int slap_startup( Backend *be )
216
{
217
	int rc;
218
219
	Debug( LDAP_DEBUG_TRACE,
		"%s startup: initiated.\n",
220
		slap_name );
221

222
223
224
225
	rc = backend_startup( be );
	if ( !rc && ( slapMode & SLAP_SERVER_MODE ))
		slapMode |= SLAP_SERVER_RUNNING;
	return rc;
226
227
}

228
int slap_shutdown( Backend *be )
229
230
231
{
	Debug( LDAP_DEBUG_TRACE,
		"%s shutdown: initiated\n",
232
		slap_name );
233

234
235
236
	/* Make sure the pool stops now even if we did not start up fully */
	ldap_pvt_thread_pool_close( &connection_pool, 1 );

237
	/* let backends do whatever cleanup they need to do */
238
	return backend_shutdown( be ); 
Kurt Zeilenga's avatar
Kurt Zeilenga committed
239
}
240
241
242
243
244
245

int slap_destroy(void)
{
	int rc;

	Debug( LDAP_DEBUG_TRACE,
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
246
		"%s destroy: freeing system resources.\n",
247
		slap_name );
248

249
250
	if ( default_referral ) {
		ber_bvarray_free( default_referral );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
251
	}
252

253
254
	ldap_pvt_thread_pool_free( &connection_pool );

255
256
257
	/* clear out any thread-keys for the main thread */
	ldap_pvt_thread_pool_context_reset( ldap_pvt_thread_pool_context());

258
259
	rc = backend_destroy();

Pierangelo Masarati's avatar
Pierangelo Masarati committed
260
261
	slap_sasl_destroy();

262
263
264
	/* rootdse destroy goes before entry_destroy()
	 * because it may use entry_free() */
	root_dse_destroy();
265
266
	entry_destroy();

267
268
269
	switch ( slapMode & SLAP_MODE ) {
	case SLAP_SERVER_MODE:
	case SLAP_TOOL_MODE:
270
		slap_counters_destroy( &slap_counters );
271
272
273
274
		break;

	default:
		Debug( LDAP_DEBUG_ANY,
275
			"slap_destroy(): undefined mode (%d).\n", slapMode );
276
277
278
279
280
281

		rc = 1;
		break;

	}

282
	ldap_pvt_thread_mutex_destroy( &slapd_init_mutex );
283
284
	ldap_pvt_thread_cond_destroy( &slapd_init_cond );

285
286
	slap_op_destroy();

287
288
	ldap_pvt_thread_destroy();

289
	/* should destroy the above mutex */
290
291
	return rc;
}
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330

void slap_counters_init( slap_counters_t *sc )
{
	int i;

	ldap_pvt_thread_mutex_init( &sc->sc_mutex );
	ldap_pvt_mp_init( sc->sc_bytes );
	ldap_pvt_mp_init( sc->sc_pdu );
	ldap_pvt_mp_init( sc->sc_entries );
	ldap_pvt_mp_init( sc->sc_refs );

	ldap_pvt_mp_init( sc->sc_ops_initiated );
	ldap_pvt_mp_init( sc->sc_ops_completed );

	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
		ldap_pvt_mp_init( sc->sc_ops_initiated_[ i ] );
		ldap_pvt_mp_init( sc->sc_ops_completed_[ i ] );
	}
}

void slap_counters_destroy( slap_counters_t *sc )
{
	int i;

	ldap_pvt_thread_mutex_destroy( &sc->sc_mutex );
	ldap_pvt_mp_clear( sc->sc_bytes );
	ldap_pvt_mp_clear( sc->sc_pdu );
	ldap_pvt_mp_clear( sc->sc_entries );
	ldap_pvt_mp_clear( sc->sc_refs );

	ldap_pvt_mp_clear( sc->sc_ops_initiated );
	ldap_pvt_mp_clear( sc->sc_ops_completed );

	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
		ldap_pvt_mp_clear( sc->sc_ops_initiated_[ i ] );
		ldap_pvt_mp_clear( sc->sc_ops_completed_[ i ] );
	}
}