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