xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-relay/init.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: init.c,v 1.3 2021/08/14 16:15:01 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-2021 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.3 2021/08/14 16:15:01 christos Exp $");
26 
27 #include "portable.h"
28 
29 #include <stdio.h>
30 #include <ac/string.h>
31 
32 #include "slap.h"
33 #include "slap-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 			"EQUALITY distinguishedNameMatch "
45 			"SYNTAX OMsDN "
46 			"SINGLE-VALUE )",
47 		NULL, NULL },
48 	{ NULL }
49 };
50 
51 static ConfigOCs relayocs[] = {
52 	{ "( OLcfgDbOc:5.1 "
53 		"NAME 'olcRelayConfig' "
54 		"DESC 'Relay backend configuration' "
55 		"SUP olcDatabaseConfig "
56 		"MAY ( olcRelay "
57 		") )",
58 		 	Cft_Database, relaycfg},
59 	{ NULL, 0, NULL }
60 };
61 
62 static int
relay_back_cf(ConfigArgs * c)63 relay_back_cf( ConfigArgs *c )
64 {
65 	relay_back_info	*ri = ( relay_back_info * )c->be->be_private;
66 	int		rc = 0;
67 
68 	if ( c->op == SLAP_CONFIG_EMIT ) {
69 		if ( ri != NULL && !BER_BVISNULL( &ri->ri_realsuffix ) ) {
70 			value_add_one( &c->rvalue_vals, &ri->ri_realsuffix );
71 			return 0;
72 		}
73 		return 1;
74 
75 	} else if ( c->op == LDAP_MOD_DELETE ) {
76 		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
77 			ch_free( ri->ri_realsuffix.bv_val );
78 			BER_BVZERO( &ri->ri_realsuffix );
79 			ri->ri_bd = NULL;
80 			return 0;
81 		}
82 		return 1;
83 
84 	} else {
85 		BackendDB *bd;
86 
87 		assert( ri != NULL );
88 		assert( BER_BVISNULL( &ri->ri_realsuffix ) );
89 
90 		if ( c->be->be_nsuffix == NULL ) {
91 			snprintf( c->cr_msg, sizeof( c->cr_msg),
92 				"\"relay\" directive "
93 				"must appear after \"suffix\"" );
94 			Log( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
95 				"%s: %s.\n", c->log, c->cr_msg );
96 			rc = 1;
97 			goto relay_done;
98 		}
99 
100 		if ( !BER_BVISNULL( &c->be->be_nsuffix[ 1 ] ) ) {
101 			snprintf( c->cr_msg, sizeof( c->cr_msg),
102 				"relaying of multiple suffix "
103 				"database not supported" );
104 			Log( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
105 				"%s: %s.\n", c->log, c->cr_msg );
106 			rc = 1;
107 			goto relay_done;
108 		}
109 
110 		bd = select_backend( &c->value_ndn, 1 );
111 		if ( bd == NULL ) {
112 			snprintf( c->cr_msg, sizeof( c->cr_msg),
113 				"cannot find database "
114 				"of relay dn \"%s\" "
115 				"in \"olcRelay <dn>\"\n",
116 				c->value_dn.bv_val );
117 			Log( LDAP_DEBUG_CONFIG, LDAP_LEVEL_ERR,
118 				"%s: %s.\n", c->log, c->cr_msg );
119 
120 		} else if ( bd->be_private == c->be->be_private ) {
121 			snprintf( c->cr_msg, sizeof( c->cr_msg),
122 				"relay dn \"%s\" would call self "
123 				"in \"relay <dn>\" line\n",
124 				c->value_dn.bv_val );
125 			Log( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
126 				"%s: %s.\n", c->log, c->cr_msg );
127 			rc = 1;
128 			goto relay_done;
129 		}
130 
131 		ri->ri_realsuffix = c->value_ndn;
132 		BER_BVZERO( &c->value_ndn );
133 
134 relay_done:;
135 		ch_free( c->value_dn.bv_val );
136 		ch_free( c->value_ndn.bv_val );
137 	}
138 
139 	return rc;
140 }
141 
142 int
relay_back_initialize(BackendInfo * bi)143 relay_back_initialize( BackendInfo *bi )
144 {
145 	bi->bi_init = 0;
146 	bi->bi_open = 0;
147 	bi->bi_config = 0;
148 	bi->bi_close = 0;
149 	bi->bi_destroy = 0;
150 
151 	bi->bi_db_init = relay_back_db_init;
152 	bi->bi_db_config = config_generic_wrapper;
153 	bi->bi_db_open = relay_back_db_open;
154 #if 0
155 	bi->bi_db_close = relay_back_db_close;
156 #endif
157 	bi->bi_db_destroy = relay_back_db_destroy;
158 
159 	bi->bi_op_bind = relay_back_op_bind;
160 	bi->bi_op_search = relay_back_op_search;
161 	bi->bi_op_compare = relay_back_op_compare;
162 	bi->bi_op_modify = relay_back_op_modify;
163 	bi->bi_op_modrdn = relay_back_op_modrdn;
164 	bi->bi_op_add = relay_back_op_add;
165 	bi->bi_op_delete = relay_back_op_delete;
166 	bi->bi_extended = relay_back_op_extended;
167 	bi->bi_entry_release_rw = relay_back_entry_release_rw;
168 	bi->bi_entry_get_rw = relay_back_entry_get_rw;
169 	bi->bi_operational = relay_back_operational;
170 	bi->bi_has_subordinates = relay_back_has_subordinates;
171 
172 	bi->bi_cf_ocs = relayocs;
173 
174 	return config_register_schema( relaycfg, relayocs );
175 }
176 
177 int
relay_back_db_init(Backend * be,ConfigReply * cr)178 relay_back_db_init( Backend *be, ConfigReply *cr)
179 {
180 	relay_back_info		*ri;
181 
182 	be->be_private = NULL;
183 
184 	ri = (relay_back_info *) ch_calloc( 1, RELAY_INFO_SIZE );
185 	if ( ri == NULL ) {
186  		return -1;
187  	}
188 
189 	ri->ri_bd = NULL;
190 	BER_BVZERO( &ri->ri_realsuffix );
191 	ri->ri_massage = 0;
192 
193 	be->be_cf_ocs = be->bd_info->bi_cf_ocs;
194 
195 	be->be_private = (void *)ri;
196 
197 	return 0;
198 }
199 
200 int
relay_back_db_open(Backend * be,ConfigReply * cr)201 relay_back_db_open( Backend *be, ConfigReply *cr )
202 {
203 	relay_back_info		*ri = (relay_back_info *)be->be_private;
204 
205 	assert( ri != NULL );
206 
207 	if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
208 		ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 );
209 
210 		/* must be there: it was during config! */
211 		if ( ri->ri_bd == NULL ) {
212 			snprintf( cr->msg, sizeof( cr->msg),
213 				"cannot find database "
214 				"of relay dn \"%s\" "
215 				"in \"olcRelay <dn>\"\n",
216 				ri->ri_realsuffix.bv_val );
217 			Log( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
218 				"relay_back_db_open: %s.\n", cr->msg );
219 
220 			return 1;
221 		}
222 
223 		/* inherit controls */
224 		AC_MEMCPY( be->bd_self->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) );
225 
226 	} else {
227 		/* inherit all? */
228 		AC_MEMCPY( be->bd_self->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) );
229 	}
230 
231 	return 0;
232 }
233 
234 int
relay_back_db_close(Backend * be,ConfigReply * cr)235 relay_back_db_close( Backend *be, ConfigReply *cr )
236 {
237 	return 0;
238 }
239 
240 int
relay_back_db_destroy(Backend * be,ConfigReply * cr)241 relay_back_db_destroy( Backend *be, ConfigReply *cr)
242 {
243 	relay_back_info		*ri = (relay_back_info *)be->be_private;
244 
245 	if ( ri ) {
246 		if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) {
247 			ch_free( ri->ri_realsuffix.bv_val );
248 		}
249 		ch_free( ri );
250 	}
251 
252 	return 0;
253 }
254 
255 #if SLAPD_RELAY == SLAPD_MOD_DYNAMIC
256 
257 /* conditionally define the init_module() function */
258 SLAP_BACKEND_INIT_MODULE( relay )
259 
260 #endif /* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */
261