1/* init.c - initialize relay backend */ 2/* $OpenLDAP$ */ 3/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2004-2011 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_CONFIG, LDAP_LEVEL_ERR, 112 "%s: %s.\n", c->log, c->cr_msg ); 113 114 } else if ( bd->be_private == c->be->be_private ) { 115 snprintf( c->cr_msg, sizeof( c->cr_msg), 116 "relay dn \"%s\" would call self " 117 "in \"relay <dn>\" line\n", 118 c->value_dn.bv_val ); 119 Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, 120 "%s: %s.\n", c->log, c->cr_msg ); 121 rc = 1; 122 goto relay_done; 123 } 124 125 ri->ri_realsuffix = c->value_ndn; 126 BER_BVZERO( &c->value_ndn ); 127 128relay_done:; 129 ch_free( c->value_dn.bv_val ); 130 ch_free( c->value_ndn.bv_val ); 131 } 132 133 return rc; 134} 135 136int 137relay_back_initialize( BackendInfo *bi ) 138{ 139 bi->bi_init = 0; 140 bi->bi_open = 0; 141 bi->bi_config = 0; 142 bi->bi_close = 0; 143 bi->bi_destroy = 0; 144 145 bi->bi_db_init = relay_back_db_init; 146 bi->bi_db_config = config_generic_wrapper; 147 bi->bi_db_open = relay_back_db_open; 148#if 0 149 bi->bi_db_close = relay_back_db_close; 150#endif 151 bi->bi_db_destroy = relay_back_db_destroy; 152 153 bi->bi_op_bind = relay_back_op_bind; 154 bi->bi_op_search = relay_back_op_search; 155 bi->bi_op_compare = relay_back_op_compare; 156 bi->bi_op_modify = relay_back_op_modify; 157 bi->bi_op_modrdn = relay_back_op_modrdn; 158 bi->bi_op_add = relay_back_op_add; 159 bi->bi_op_delete = relay_back_op_delete; 160 bi->bi_extended = relay_back_op_extended; 161 bi->bi_entry_release_rw = relay_back_entry_release_rw; 162 bi->bi_entry_get_rw = relay_back_entry_get_rw; 163 bi->bi_operational = relay_back_operational; 164 bi->bi_has_subordinates = relay_back_has_subordinates; 165 166 bi->bi_cf_ocs = relayocs; 167 168 return config_register_schema( relaycfg, relayocs ); 169} 170 171int 172relay_back_db_init( Backend *be, ConfigReply *cr) 173{ 174 relay_back_info *ri; 175 176 be->be_private = NULL; 177 178 ri = (relay_back_info *) ch_calloc( 1, RELAY_INFO_SIZE ); 179 if ( ri == NULL ) { 180 return -1; 181 } 182 183 ri->ri_bd = NULL; 184 BER_BVZERO( &ri->ri_realsuffix ); 185 ri->ri_massage = 0; 186 187 be->be_cf_ocs = be->bd_info->bi_cf_ocs; 188 189 be->be_private = (void *)ri; 190 191 return 0; 192} 193 194int 195relay_back_db_open( Backend *be, ConfigReply *cr ) 196{ 197 relay_back_info *ri = (relay_back_info *)be->be_private; 198 199 assert( ri != NULL ); 200 201 if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { 202 ri->ri_bd = select_backend( &ri->ri_realsuffix, 1 ); 203 204 /* must be there: it was during config! */ 205 if ( ri->ri_bd == NULL ) { 206 snprintf( cr->msg, sizeof( cr->msg), 207 "cannot find database " 208 "of relay dn \"%s\" " 209 "in \"olcRelay <dn>\"\n", 210 ri->ri_realsuffix.bv_val ); 211 Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR, 212 "relay_back_db_open: %s.\n", cr->msg ); 213 214 return 1; 215 } 216 217 /* inherit controls */ 218 AC_MEMCPY( be->bd_self->be_ctrls, ri->ri_bd->be_ctrls, sizeof( be->be_ctrls ) ); 219 220 } else { 221 /* inherit all? */ 222 AC_MEMCPY( be->bd_self->be_ctrls, frontendDB->be_ctrls, sizeof( be->be_ctrls ) ); 223 } 224 225 return 0; 226} 227 228int 229relay_back_db_close( Backend *be, ConfigReply *cr ) 230{ 231 return 0; 232} 233 234int 235relay_back_db_destroy( Backend *be, ConfigReply *cr) 236{ 237 relay_back_info *ri = (relay_back_info *)be->be_private; 238 239 if ( ri ) { 240 if ( !BER_BVISNULL( &ri->ri_realsuffix ) ) { 241 ch_free( ri->ri_realsuffix.bv_val ); 242 } 243 ch_free( ri ); 244 } 245 246 return 0; 247} 248 249#if SLAPD_RELAY == SLAPD_MOD_DYNAMIC 250 251/* conditionally define the init_module() function */ 252SLAP_BACKEND_INIT_MODULE( relay ) 253 254#endif /* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */ 255