1 /* backover.c - backend overlay routines */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
17 /* Functions to overlay other modules over a backend. */
23 #include <ac/string.h>
24 #include <ac/socket.h>
29 static slap_overinst *overlays;
31 enum db_which { db_open = 0, db_close, db_destroy };
39 slap_overinfo *oi = (slap_overinfo *) be->bd_info;
40 slap_overinst *on = oi->oi_list;
45 func = &oi->oi_bd.bd_info->bi_db_open;
47 rc = func[which]( &oi->oi_bd );
52 for (; on; on=on->on_next) {
53 bd.bd_info = &on->on_bi;
54 func = &on->on_bi.bi_db_open;
56 rc = func[which]( &bd );
72 slap_overinfo *oi = (slap_overinfo *) be->bd_info;
73 slap_overinst *on = oi->oi_list;
77 if ( oi->oi_bd.bd_info->bi_db_config ) {
78 rc = oi->oi_bd.bd_info->bi_db_config( &oi->oi_bd, fname, lineno,
80 if ( rc != SLAP_CONF_UNKNOWN ) return rc;
84 for (; on; on=on->on_next) {
85 bd.bd_info = &on->on_bi;
86 if (on->on_bi.bi_db_config) {
87 rc = on->on_bi.bi_db_config( &bd, fname, lineno,
89 if ( rc != SLAP_CONF_UNKNOWN ) break;
100 return over_db_func( be, db_open );
108 return over_db_func( be, db_close );
116 slap_overinfo *oi = (slap_overinfo *) be->bd_info;
117 slap_overinst *on = oi->oi_list, *next;
120 rc = over_db_func( be, db_destroy );
122 for (next = on->on_next; on; on=next) {
131 over_back_response ( Operation *op, SlapReply *rs )
133 slap_overinfo *oi = (slap_overinfo *) op->o_bd->bd_info;
134 slap_overinst *on = oi->oi_list;
135 int rc = SLAP_CB_CONTINUE;
136 BackendDB *be = op->o_bd, db = *op->o_bd;
139 for (; on; on=on->on_next ) {
140 if ( on->on_response ) {
141 db.bd_info = (BackendInfo *)on;
142 rc = on->on_response( op, rs );
143 if ( rc != SLAP_CB_CONTINUE ) break;
150 enum op_which { op_bind = 0, op_unbind, op_search, op_compare,
151 op_modify, op_modrdn, op_add, op_delete, op_abandon,
152 op_cancel, op_extended };
161 slap_overinfo *oi = (slap_overinfo *) op->o_bd->bd_info;
162 slap_overinst *on = oi->oi_list;
164 BackendDB *be = op->o_bd, db = *op->o_bd;
165 slap_callback cb = {NULL, over_back_response, NULL, NULL};
166 int rc = SLAP_CB_CONTINUE;
169 cb.sc_next = op->o_callback;
170 op->o_callback = &cb;
172 for (; on; on=on->on_next ) {
173 func = &on->on_bi.bi_op_bind;
175 db.bd_info = (BackendInfo *)on;
176 rc = func[which]( op, rs );
177 if ( rc != SLAP_CB_CONTINUE ) break;
182 func = &oi->oi_bd.bd_info->bi_op_bind;
183 if ( func[which] && rc == SLAP_CB_CONTINUE ) {
184 rc = func[which]( op, rs );
186 /* should not fall thru this far without anything happening... */
187 if ( rc == SLAP_CB_CONTINUE ) {
188 rc = LDAP_UNWILLING_TO_PERFORM;
190 op->o_callback = cb.sc_next;
195 over_op_bind( Operation *op, SlapReply *rs )
197 return over_op_func( op, rs, op_bind );
201 over_op_unbind( Operation *op, SlapReply *rs )
203 return over_op_func( op, rs, op_unbind );
207 over_op_search( Operation *op, SlapReply *rs )
209 return over_op_func( op, rs, op_search );
213 over_op_compare( Operation *op, SlapReply *rs )
215 return over_op_func( op, rs, op_compare );
219 over_op_modify( Operation *op, SlapReply *rs )
221 return over_op_func( op, rs, op_modify );
225 over_op_modrdn( Operation *op, SlapReply *rs )
227 return over_op_func( op, rs, op_modrdn );
231 over_op_add( Operation *op, SlapReply *rs )
233 return over_op_func( op, rs, op_add );
237 over_op_delete( Operation *op, SlapReply *rs )
239 return over_op_func( op, rs, op_delete );
243 over_op_abandon( Operation *op, SlapReply *rs )
245 return over_op_func( op, rs, op_abandon );
249 over_op_cancel( Operation *op, SlapReply *rs )
251 return over_op_func( op, rs, op_cancel );
255 over_op_extended( Operation *op, SlapReply *rs )
257 return over_op_func( op, rs, op_extended );
265 on->on_next = overlays;
270 static const char overtype[] = "over";
272 /* add an overlay to a particular backend. */
274 overlay_config( BackendDB *be, const char *ov )
276 slap_overinst *on, *on2, *prev;
280 for ( on = overlays; on; on=on->on_next ) {
281 if (!strcmp( ov, on->on_bi.bi_type ) )
285 Debug( LDAP_DEBUG_ANY, "overlay %s not found\n", ov, 0, 0 );
289 /* If this is the first overlay on this backend, set up the
290 * overlay info structure
292 if ( be->bd_info->bi_type != overtype ) {
293 oi = ch_malloc( sizeof(slap_overinfo) );
295 oi->oi_bi = *be->bd_info;
297 bi = (BackendInfo *)oi;
299 bi->bi_type = (char *)overtype;
301 bi->bi_db_config = over_db_config;
302 bi->bi_db_open = over_db_open;
303 bi->bi_db_close = over_db_close;
304 bi->bi_db_destroy = over_db_destroy;
306 bi->bi_op_bind = over_op_bind;
307 bi->bi_op_unbind = over_op_unbind;
308 bi->bi_op_search = over_op_search;
309 bi->bi_op_compare = over_op_compare;
310 bi->bi_op_modify = over_op_modify;
311 bi->bi_op_modrdn = over_op_modrdn;
312 bi->bi_op_add = over_op_add;
313 bi->bi_op_delete = over_op_delete;
314 bi->bi_op_abandon = over_op_abandon;
315 bi->bi_op_cancel = over_op_cancel;
316 bi->bi_extended = over_op_extended;
322 /* Walk to the end of the list of overlays, add the new
325 oi = (slap_overinfo *) be->bd_info;
326 for ( prev=NULL, on2 = oi->oi_list; on2; prev=on2, on2=on2->on_next );
327 on2 = ch_calloc( 1, sizeof(slap_overinst) );
337 /* Insert new overlay on head of list. Overlays are executed
338 * in reverse of config order...
340 on2 = ch_calloc( 1, sizeof(slap_overinst) );
343 on2->on_next = oi->oi_list;
347 /* Any initialization needed? */
348 if ( on->on_bi.bi_db_init ) {
349 be->bd_info = (BackendInfo *)on2;
350 on2->on_bi.bi_db_init( be );
351 be->bd_info = (BackendInfo *)oi;