xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-relay/init.c (revision 274254cdae52594c1aa480a736aef78313d15c9c)
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 
31 static ConfigDriver relay_back_cf;
32 
33 static 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 
45 static 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 
56 static int
57 relay_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 
130 relay_done:;
131 		ch_free( c->value_dn.bv_val );
132 		ch_free( c->value_ndn.bv_val );
133 	}
134 
135 	return rc;
136 }
137 
138 int
139 relay_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 
182 int
183 relay_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 
205 int
206 relay_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 
229 int
230 relay_back_db_close( Backend *be, ConfigReply *cr )
231 {
232 	return 0;
233 }
234 
235 int
236 relay_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 */
253 SLAP_BACKEND_INIT_MODULE( relay )
254 
255 #endif /* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */
256 
257