init.c revision 1.1.1.1
1/* init.c - initialize relay backend */
2/* $OpenLDAP: pkg/ldap/servers/slapd/back-relay/init.c,v 1.19.2.4 2008/02/12 01:03:16 quanah Exp $ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 2004-2008 The OpenLDAP Foundation.
6 * Portions Copyright 2004 Pierangelo Masarati.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17/* ACKNOWLEDGEMENTS:
18 * This work was initially developed by Pierangelo Masarati for inclusion
19 * in OpenLDAP Software.
20 */
21
22#include "portable.h"
23
24#include <stdio.h>
25#include <ac/string.h>
26
27#include "slap.h"
28#include "config.h"
29#include "back-relay.h"
30
31static ConfigDriver relay_back_cf;
32
33static ConfigTable relaycfg[] = {
34	{ "relay", "relay", 2, 2, 0,
35		ARG_MAGIC|ARG_DN,
36		relay_back_cf, "( OLcfgDbAt:5.1 "
37			"NAME 'olcRelay' "
38			"DESC 'Relay DN' "
39			"SYNTAX OMsDN "
40			"SINGLE-VALUE )",
41		NULL, NULL },
42	{ NULL }
43};
44
45static ConfigOCs relayocs[] = {
46	{ "( OLcfgDbOc:5.1 "
47		"NAME 'olcRelayConfig' "
48		"DESC 'Relay backend configuration' "
49		"SUP olcDatabaseConfig "
50		"MAY ( olcRelay "
51		") )",
52		 	Cft_Database, relaycfg},
53	{ NULL, 0, NULL }
54};
55
56static int
57relay_back_cf( ConfigArgs *c )
58{
59	relay_back_info	*ri = ( relay_back_info * )c->be->be_private;
60	int		rc = 0;
61
62	if ( c->op == SLAP_CONFIG_EMIT ) {
63		if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) {
64			value_add_one( &c->rvalue_vals, &ri->ri_realsuffix );
65			return 0;
66		}
67		return 1;
68
69	} else if ( c->op == LDAP_MOD_DELETE ) {
70		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
71			ch_free( ri->ri_realsuffix.bv_val );
72			BER_BVZERO( &ri->ri_realsuffix );
73			ri->ri_bd = NULL;
74			return 0;
75		}
76		return 1;
77
78	} else {
79		BackendDB *bd;
80
81		assert( ri != NULL );
82		assert( BER_BVISNULL( &ri->ri_realsuffix ) );
83
84		if ( c->be->be_nsuffix == NULL ) {
85			snprintf( c->cr_msg, sizeof( c->cr_msg),
86				"\"relay\" directive "
87				"must appear after \"suffix\"" );
88			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
89				"%s: %s.\n", c->log, c->cr_msg );
90			rc = 1;
91			goto relay_done;
92		}
93
94		if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) {
95			snprintf( c->cr_msg, sizeof( c->cr_msg),
96				"relaying of multiple suffix "
97				"database not supported" );
98			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
99				"%s: %s.\n", c->log, c->cr_msg );
100			rc = 1;
101			goto relay_done;
102		}
103
104		bd = select_backend( &c->value_ndn, 1 );
105		if ( bd == NULL ) {
106			snprintf( c->cr_msg, sizeof( c->cr_msg),
107				"cannot find database "
108				"of relay dn \"%s\" "
109				"in \"olcRelay <dn>\"\n",
110				c->value_dn.bv_val );
111			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
112				"%s: %s.\n", c->log, c->cr_msg );
113			rc = 1;
114			goto relay_done;
115
116		} else if ( bd->be_private == c->be->be_private ) {
117			snprintf( c->cr_msg, sizeof( c->cr_msg),
118				"relay dn \"%s\" would call self "
119				"in \"relay <dn>\" line\n",
120				c->value_dn.bv_val );
121			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
122				"%s: %s.\n", c->log, c->cr_msg );
123			rc = 1;
124			goto relay_done;
125		}
126
127		ri->ri_realsuffix = c->value_ndn;
128		BER_BVZERO( &c->value_ndn );
129
130relay_done:;
131		ch_free( c->value_dn.bv_val );
132		ch_free( c->value_ndn.bv_val );
133	}
134
135	return rc;
136}
137
138int
139relay_back_initialize( BackendInfo *bi )
140{
141	bi->bi_init = 0;
142	bi->bi_open = 0;
143	bi->bi_config = 0;
144	bi->bi_close = 0;
145	bi->bi_destroy = 0;
146
147	bi->bi_db_init = relay_back_db_init;
148	bi->bi_db_config = config_generic_wrapper;
149	bi->bi_db_open = relay_back_db_open;
150#if 0
151	bi->bi_db_close = relay_back_db_close;
152#endif
153	bi->bi_db_destroy = relay_back_db_destroy;
154
155	bi->bi_op_bind = relay_back_op_bind;
156	bi->bi_op_unbind = relay_back_op_unbind;
157	bi->bi_op_search = relay_back_op_search;
158	bi->bi_op_compare = relay_back_op_compare;
159	bi->bi_op_modify = relay_back_op_modify;
160	bi->bi_op_modrdn = relay_back_op_modrdn;
161	bi->bi_op_add = relay_back_op_add;
162	bi->bi_op_delete = relay_back_op_delete;
163	bi->bi_op_abandon = relay_back_op_abandon;
164	bi->bi_op_cancel = relay_back_op_cancel;
165	bi->bi_extended = relay_back_op_extended;
166	bi->bi_entry_release_rw = relay_back_entry_release_rw;
167	bi->bi_entry_get_rw = relay_back_entry_get_rw;
168#if 0	/* see comment in op.c */
169	bi->bi_chk_referrals = relay_back_chk_referrals;
170#endif
171	bi->bi_operational = relay_back_operational;
172	bi->bi_has_subordinates = relay_back_has_subordinates;
173
174	bi->bi_connection_init = relay_back_connection_init;
175	bi->bi_connection_destroy = relay_back_connection_destroy;
176
177	bi->bi_cf_ocs = relayocs;
178
179	return config_register_schema( relaycfg, relayocs );
180}
181
182int
183relay_back_db_init( Backend *be, ConfigReply *cr)
184{
185	relay_back_info		*ri;
186
187	be->be_private = NULL;
188
189	ri = (relay_back_info *)ch_calloc( 1, sizeof( relay_back_info ) );
190	if ( ri == NULL ) {
191 		return -1;
192 	}
193
194	ri->ri_bd = NULL;
195	BER_BVZERO( &ri->ri_realsuffix );
196	ri->ri_massage = 0;
197
198	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
199
200	be->be_private = (void *)ri;
201
202	return 0;
203}
204
205int
206relay_back_db_open( Backend *be, ConfigReply *cr )
207{
208	relay_back_info		*ri = (relay_back_info *)be->be_private;
209
210	assert( ri != NULL );
211
212	if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
213		ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 );
214
215		/* must be there: it was during config! */
216		assert( ri->ri_bd != NULL );
217
218		/* inherit controls */
219		AC_MEMCPY( be->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) );
220
221	} else {
222		/* inherit all? */
223		AC_MEMCPY( be->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) );
224	}
225
226	return 0;
227}
228
229int
230relay_back_db_close( Backend *be, ConfigReply *cr )
231{
232	return 0;
233}
234
235int
236relay_back_db_destroy( Backend *be, ConfigReply *cr)
237{
238	relay_back_info		*ri = (relay_back_info *)be->be_private;
239
240	if ( ri ) {
241		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
242			ch_free( ri->ri_realsuffix.bv_val );
243		}
244		ch_free( ri );
245	}
246
247	return 0;
248}
249
250#if SLAPD_RELAY == SLAPD_MOD_DYNAMIC
251
252/* conditionally define the init_module() function */
253SLAP_BACKEND_INIT_MODULE( relay )
254
255#endif /* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */
256
257