--- servers/slapd/back-sock/config.c 2007/12/24 04:32:13 1.4 +++ servers/slapd/back-sock/config.c 2011/02/03 20:54:11 1.13 @@ -1,8 +1,8 @@ /* config.c - sock backend configuration file routine */ -/* $OpenLDAP: pkg/ldap/servers/slapd/back-sock/config.c,v 1.3 2007/12/24 04:18:26 hyc Exp $ */ +/* $OpenLDAP: pkg/ldap/servers/slapd/back-sock/config.c,v 1.12 2011/02/03 20:34:45 hyc Exp $ */ /* This work is part of OpenLDAP Software . * - * Copyright 2007 The OpenLDAP Foundation. + * Copyright 2007-2011 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,8 @@ #include "back-sock.h" static ConfigDriver bs_cf_gen; +static int sock_over_setup(); +static slap_response sock_over_response; enum { BS_EXT = 1 @@ -61,19 +63,38 @@ static ConfigOCs bsocs[] = { { NULL, 0, NULL } }; +static ConfigOCs osocs[] = { + { "( OLcfgDbOc:7.2 " + "NAME 'olcOvSocketConfig' " + "DESC 'Socket overlay configuration' " + "SUP olcOverlayConfig " + "MUST olcDbSocketPath " + "MAY olcDbSocketExtensions )", + Cft_Overlay, bscfg }, + { NULL, 0, NULL } +}; + static slap_verbmasks bs_exts[] = { { BER_BVC("binddn"), SOCK_EXT_BINDDN }, { BER_BVC("peername"), SOCK_EXT_PEERNAME }, { BER_BVC("ssf"), SOCK_EXT_SSF }, + { BER_BVC("connid"), SOCK_EXT_CONNID }, { BER_BVNULL, 0 } }; static int bs_cf_gen( ConfigArgs *c ) { - struct sockinfo *si = c->be->be_private; + struct sockinfo *si; int rc; + if ( c->be && c->table == Cft_Database ) + si = c->be->be_private; + else if ( c->bi ) + si = c->bi->bi_private; + else + return ARG_BAD_CONF; + if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case BS_EXT: @@ -106,7 +127,149 @@ bs_cf_gen( ConfigArgs *c ) int sock_back_init_cf( BackendInfo *bi ) { + int rc; bi->bi_cf_ocs = bsocs; - return config_register_schema( bscfg, bsocs ); + rc = config_register_schema( bscfg, bsocs ); + if ( !rc ) + rc = sock_over_setup(); + return rc; +} + +/* sock overlay wrapper */ +static slap_overinst sockover; + +static int sock_over_db_init( Backend *be, struct config_reply_s *cr ); +static int sock_over_db_destroy( Backend *be, struct config_reply_s *cr ); + +static BI_op_bind *sockfuncs[] = { + sock_back_bind, + sock_back_unbind, + sock_back_search, + sock_back_compare, + sock_back_modify, + sock_back_modrdn, + sock_back_add, + sock_back_delete +}; + +static int sock_over_op( + Operation *op, + SlapReply *rs +) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + void *private = op->o_bd->be_private; + slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; + slap_operation_t which; + int rc; + + switch (op->o_tag) { + case LDAP_REQ_BIND: which = op_bind; break; + case LDAP_REQ_UNBIND: which = op_unbind; break; + case LDAP_REQ_SEARCH: which = op_search; break; + case LDAP_REQ_COMPARE: which = op_compare; break; + case LDAP_REQ_MODIFY: which = op_modify; break; + case LDAP_REQ_MODRDN: which = op_modrdn; break; + case LDAP_REQ_ADD: which = op_add; break; + case LDAP_REQ_DELETE: which = op_delete; break; + default: + return SLAP_CB_CONTINUE; + } + op->o_bd->be_private = on->on_bi.bi_private; + cb.sc_next = op->o_callback; + op->o_callback = &cb; + rc = sockfuncs[which]( op, rs ); + op->o_bd->be_private = private; + op->o_callback = cb.sc_next; + return SLAP_CB_CONTINUE; +} + +static int +sock_over_response( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private; + FILE *fp; + + if ( rs->sr_type != REP_RESULT ) + return SLAP_CB_CONTINUE; + + if (( fp = opensock( si->si_sockpath )) == NULL ) + return SLAP_CB_CONTINUE; + + /* write out the result */ + fprintf( fp, "RESULT\n" ); + fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); + sock_print_conn( fp, op->o_conn, si ); + fprintf( fp, "code: %d\n", rs->sr_err ); + if ( rs->sr_matched ) + fprintf( fp, "matched: %s\n", rs->sr_matched ); + if (rs->sr_text ) + fprintf( fp, "info: %s\n", rs->sr_text ); + fprintf( fp, "\n" ); + fclose( fp ); + + return SLAP_CB_CONTINUE; +} + +static int +sock_over_setup() +{ + int rc; + + sockover.on_bi.bi_type = "sock"; + sockover.on_bi.bi_db_init = sock_over_db_init; + sockover.on_bi.bi_db_destroy = sock_over_db_destroy; + + sockover.on_bi.bi_op_bind = sock_over_op; + sockover.on_bi.bi_op_unbind = sock_over_op; + sockover.on_bi.bi_op_search = sock_over_op; + sockover.on_bi.bi_op_compare = sock_over_op; + sockover.on_bi.bi_op_modify = sock_over_op; + sockover.on_bi.bi_op_modrdn = sock_over_op; + sockover.on_bi.bi_op_add = sock_over_op; + sockover.on_bi.bi_op_delete = sock_over_op; + sockover.on_response = sock_over_response; + + sockover.on_bi.bi_cf_ocs = osocs; + + rc = config_register_schema( bscfg, osocs ); + if ( rc ) return rc; + + return overlay_register( &sockover ); +} + +static int +sock_over_db_init( + Backend *be, + struct config_reply_s *cr +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + void *private = be->be_private; + int rc; + + be->be_private = NULL; + rc = sock_back_db_init( be, cr ); + on->on_bi.bi_private = be->be_private; + be->be_private = private; + return rc; +} + +static int +sock_over_db_destroy( + Backend *be, + struct config_reply_s *cr +) +{ + slap_overinst *on = (slap_overinst *)be->bd_info; + void *private = be->be_private; + int rc; + + be->be_private = on->on_bi.bi_private; + rc = sock_back_db_destroy( be, cr ); + on->on_bi.bi_private = be->be_private; + be->be_private = private; + return rc; }