init.c 6.79 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-2020 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
93
#ifdef SLAPD_MODULES
	if ( module_init() != 0 ) {
94
		slap_debug |= LDAP_DEBUG_NONE;
95
96
		Debug( LDAP_DEBUG_ANY,
		    "%s: module_init failed\n",
97
			name );
98
99
100
101
102
		return 1;
	}
#endif

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

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

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

126
	switch ( slapMode & SLAP_MODE ) {
127
	case SLAP_SERVER_MODE:
128
		root_dse_init();
129
130

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

		slap_name = name;
137

Howard Chu's avatar
Howard Chu committed
138
		ldap_pvt_thread_pool_init_q( &connection_pool,
Howard Chu's avatar
Howard Chu committed
139
				connection_pool_max, 0, connection_pool_queues);
140

141
		slap_counters_init( &slap_counters );
142

143
144
145
146
		ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
		LDAP_STAILQ_INIT( &slapd_rq.task_list );
		LDAP_STAILQ_INIT( &slapd_rq.run_list );

147
		slap_passwd_init();
148

149
		rc = slap_sasl_init();
150

151
152
153
		if( rc == 0 ) {
			rc = backend_init( );
		}
154
155
		if ( rc )
			return rc;
156

157
		break;
158

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

164
165
		rc = 1;
		break;
166
	}
167

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

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

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

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

		return 1;
	}

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

209
210
211
	return rc;
}

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

219
220
221
222
	rc = backend_startup( be );
	if ( !rc && ( slapMode & SLAP_SERVER_MODE ))
		slapMode |= SLAP_SERVER_RUNNING;
	return rc;
223
224
}

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

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

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

int slap_destroy(void)
{
	int rc;

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

246
247
	if ( default_referral ) {
		ber_bvarray_free( default_referral );
Jong Hyuk Choi's avatar
Jong Hyuk Choi committed
248
	}
249

250
251
	ldap_pvt_thread_pool_free( &connection_pool );

252
253
254
	/* clear out any thread-keys for the main thread */
	ldap_pvt_thread_pool_context_reset( ldap_pvt_thread_pool_context());

255
256
	rc = backend_destroy();

Pierangelo Masarati's avatar
Pierangelo Masarati committed
257
258
	slap_sasl_destroy();

259
260
261
	/* rootdse destroy goes before entry_destroy()
	 * because it may use entry_free() */
	root_dse_destroy();
262
263
	entry_destroy();

264
265
266
	switch ( slapMode & SLAP_MODE ) {
	case SLAP_SERVER_MODE:
	case SLAP_TOOL_MODE:
267
		slap_counters_destroy( &slap_counters );
268
269
270
271
		break;

	default:
		Debug( LDAP_DEBUG_ANY,
272
			"slap_destroy(): undefined mode (%d).\n", slapMode );
273
274
275
276
277
278

		rc = 1;
		break;

	}

279
280
	slap_op_destroy();

281
282
	ldap_pvt_thread_destroy();

283
	/* should destroy the above mutex */
284
285
	return rc;
}
286
287
288
289
290
291
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

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 ] );
	}
}