1/*	$NetBSD: init.c,v 1.1.1.3 2010/12/12 15:22:31 adam Exp $	*/
2
3/* init.c - initialize various things */
4/* OpenLDAP: pkg/ldap/servers/slapd/init.c,v 1.97.2.13 2010/04/19 16:53:02 quanah Exp */
5/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
6 *
7 * Copyright 1998-2010 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 "portable.h"
30
31#include <stdio.h>
32
33#include <ac/socket.h>
34#include <ac/string.h>
35#include <ac/time.h>
36
37#include "slap.h"
38#include "lber_pvt.h"
39
40#include "ldap_rq.h"
41
42/*
43 * read-only global variables or variables only written by the listener
44 * thread (after they are initialized) - no need to protect them with a mutex.
45 */
46int		slap_debug = 0;
47
48#ifdef LDAP_DEBUG
49int		ldap_syslog = LDAP_DEBUG_STATS;
50#else
51int		ldap_syslog;
52#endif
53
54#ifdef LOG_DEBUG
55int		ldap_syslog_level = LOG_DEBUG;
56#endif
57
58BerVarray default_referral = NULL;
59
60/*
61 * global variables that need mutex protection
62 */
63ldap_pvt_thread_pool_t	connection_pool;
64int			connection_pool_max = SLAP_MAX_WORKER_THREADS;
65int		slap_tool_thread_max = 1;
66
67slap_counters_t			slap_counters, *slap_counters_list;
68
69static const char* slap_name = NULL;
70int slapMode = SLAP_UNDEFINED_MODE;
71
72int
73slap_init( int mode, const char *name )
74{
75	int rc;
76
77	assert( mode );
78
79	if ( slapMode != SLAP_UNDEFINED_MODE ) {
80		/* Make sure we write something to stderr */
81		slap_debug |= LDAP_DEBUG_NONE;
82		Debug( LDAP_DEBUG_ANY,
83		 "%s init: init called twice (old=%d, new=%d)\n",
84		 name, slapMode, mode );
85
86		return 1;
87	}
88
89	slapMode = mode;
90
91	slap_op_init();
92
93#ifdef SLAPD_MODULES
94	if ( module_init() != 0 ) {
95		slap_debug |= LDAP_DEBUG_NONE;
96		Debug( LDAP_DEBUG_ANY,
97		    "%s: module_init failed\n",
98			name, 0, 0 );
99		return 1;
100	}
101#endif
102
103	if ( slap_schema_init( ) != 0 ) {
104		slap_debug |= LDAP_DEBUG_NONE;
105		Debug( LDAP_DEBUG_ANY,
106		    "%s: slap_schema_init failed\n",
107		    name, 0, 0 );
108		return 1;
109	}
110
111	if ( filter_init() != 0 ) {
112		slap_debug |= LDAP_DEBUG_NONE;
113		Debug( LDAP_DEBUG_ANY,
114		    "%s: filter_init failed\n",
115		    name, 0, 0 );
116		return 1;
117	}
118
119	if ( entry_init() != 0 ) {
120		slap_debug |= LDAP_DEBUG_NONE;
121		Debug( LDAP_DEBUG_ANY,
122		    "%s: entry_init failed\n",
123		    name, 0, 0 );
124		return 1;
125	}
126
127	switch ( slapMode & SLAP_MODE ) {
128	case SLAP_SERVER_MODE:
129		root_dse_init();
130
131		/* FALLTHRU */
132	case SLAP_TOOL_MODE:
133		Debug( LDAP_DEBUG_TRACE,
134			"%s init: initiated %s.\n",	name,
135			(mode & SLAP_MODE) == SLAP_TOOL_MODE ? "tool" : "server",
136			0 );
137
138		slap_name = name;
139
140		ldap_pvt_thread_pool_init( &connection_pool,
141				connection_pool_max, 0);
142
143		slap_counters_init( &slap_counters );
144
145		ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
146		LDAP_STAILQ_INIT( &slapd_rq.task_list );
147		LDAP_STAILQ_INIT( &slapd_rq.run_list );
148
149		slap_passwd_init();
150
151		rc = slap_sasl_init();
152
153		if( rc == 0 ) {
154			rc = backend_init( );
155		}
156		if ( rc )
157			return rc;
158
159		break;
160
161	default:
162		slap_debug |= LDAP_DEBUG_NONE;
163		Debug( LDAP_DEBUG_ANY,
164			"%s init: undefined mode (%d).\n", name, mode, 0 );
165
166		rc = 1;
167		break;
168	}
169
170	if ( slap_controls_init( ) != 0 ) {
171		slap_debug |= LDAP_DEBUG_NONE;
172		Debug( LDAP_DEBUG_ANY,
173		    "%s: slap_controls_init failed\n",
174		    name, 0, 0 );
175		return 1;
176	}
177
178	if ( frontend_init() ) {
179		slap_debug |= LDAP_DEBUG_NONE;
180		Debug( LDAP_DEBUG_ANY,
181		    "%s: frontend_init failed\n",
182		    name, 0, 0 );
183		return 1;
184	}
185
186	if ( overlay_init() ) {
187		slap_debug |= LDAP_DEBUG_NONE;
188		Debug( LDAP_DEBUG_ANY,
189		    "%s: overlay_init failed\n",
190		    name, 0, 0 );
191		return 1;
192	}
193
194	if ( glue_sub_init() ) {
195		slap_debug |= LDAP_DEBUG_NONE;
196		Debug( LDAP_DEBUG_ANY,
197		    "%s: glue/subordinate init failed\n",
198		    name, 0, 0 );
199
200		return 1;
201	}
202
203	if ( acl_init() ) {
204		slap_debug |= LDAP_DEBUG_NONE;
205		Debug( LDAP_DEBUG_ANY,
206		    "%s: acl_init failed\n",
207		    name, 0, 0 );
208		return 1;
209	}
210
211	return rc;
212}
213
214int slap_startup( Backend *be )
215{
216	Debug( LDAP_DEBUG_TRACE,
217		"%s startup: initiated.\n",
218		slap_name, 0, 0 );
219
220
221	return backend_startup( be );
222}
223
224int slap_shutdown( Backend *be )
225{
226	Debug( LDAP_DEBUG_TRACE,
227		"%s shutdown: initiated\n",
228		slap_name, 0, 0 );
229
230	/* let backends do whatever cleanup they need to do */
231	return backend_shutdown( be );
232}
233
234int slap_destroy(void)
235{
236	int rc;
237
238	Debug( LDAP_DEBUG_TRACE,
239		"%s destroy: freeing system resources.\n",
240		slap_name, 0, 0 );
241
242	if ( default_referral ) {
243		ber_bvarray_free( default_referral );
244	}
245
246	/* clear out any thread-keys for the main thread */
247	ldap_pvt_thread_pool_context_reset( ldap_pvt_thread_pool_context());
248
249	rc = backend_destroy();
250
251	slap_sasl_destroy();
252
253	/* rootdse destroy goes before entry_destroy()
254	 * because it may use entry_free() */
255	root_dse_destroy();
256	entry_destroy();
257
258	switch ( slapMode & SLAP_MODE ) {
259	case SLAP_SERVER_MODE:
260	case SLAP_TOOL_MODE:
261		slap_counters_destroy( &slap_counters );
262		break;
263
264	default:
265		Debug( LDAP_DEBUG_ANY,
266			"slap_destroy(): undefined mode (%d).\n", slapMode, 0, 0 );
267
268		rc = 1;
269		break;
270
271	}
272
273	slap_op_destroy();
274
275	ldap_pvt_thread_destroy();
276
277	/* should destroy the above mutex */
278	return rc;
279}
280
281void slap_counters_init( slap_counters_t *sc )
282{
283	int i;
284
285	ldap_pvt_thread_mutex_init( &sc->sc_mutex );
286	ldap_pvt_mp_init( sc->sc_bytes );
287	ldap_pvt_mp_init( sc->sc_pdu );
288	ldap_pvt_mp_init( sc->sc_entries );
289	ldap_pvt_mp_init( sc->sc_refs );
290
291	ldap_pvt_mp_init( sc->sc_ops_initiated );
292	ldap_pvt_mp_init( sc->sc_ops_completed );
293
294#ifdef SLAPD_MONITOR
295	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
296		ldap_pvt_mp_init( sc->sc_ops_initiated_[ i ] );
297		ldap_pvt_mp_init( sc->sc_ops_completed_[ i ] );
298	}
299#endif /* SLAPD_MONITOR */
300}
301
302void slap_counters_destroy( slap_counters_t *sc )
303{
304	int i;
305
306	ldap_pvt_thread_mutex_destroy( &sc->sc_mutex );
307	ldap_pvt_mp_clear( sc->sc_bytes );
308	ldap_pvt_mp_clear( sc->sc_pdu );
309	ldap_pvt_mp_clear( sc->sc_entries );
310	ldap_pvt_mp_clear( sc->sc_refs );
311
312	ldap_pvt_mp_clear( sc->sc_ops_initiated );
313	ldap_pvt_mp_clear( sc->sc_ops_completed );
314
315#ifdef SLAPD_MONITOR
316	for ( i = 0; i < SLAP_OP_LAST; i++ ) {
317		ldap_pvt_mp_clear( sc->sc_ops_initiated_[ i ] );
318		ldap_pvt_mp_clear( sc->sc_ops_completed_[ i ] );
319	}
320#endif /* SLAPD_MONITOR */
321}
322
323