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