init.c revision 1.1.1.1
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 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_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 130relay_done:; 131 ch_free( c->value_dn.bv_val ); 132 ch_free( c->value_ndn.bv_val ); 133 } 134 135 return rc; 136} 137 138int 139relay_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 182int 183relay_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 205int 206relay_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 229int 230relay_back_db_close( Backend *be, ConfigReply *cr ) 231{ 232 return 0; 233} 234 235int 236relay_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 */ 253SLAP_BACKEND_INIT_MODULE( relay ) 254 255#endif /* SLAPD_RELAY == SLAPD_MOD_DYNAMIC */ 256 257