--- servers/slapd/back-sock/config.c 2011/02/03 20:54:11 1.13 +++ servers/slapd/back-sock/config.c 2011/02/04 09:52:34 1.14 @@ -1,5 +1,5 @@ /* config.c - sock backend configuration file routine */ -/* $OpenLDAP: pkg/ldap/servers/slapd/back-sock/config.c,v 1.12 2011/02/03 20:34:45 hyc Exp $ */ +/* $OpenLDAP: pkg/ldap/servers/slapd/back-sock/config.c,v 1.13 2011/02/03 20:54:11 hyc Exp $ */ /* This work is part of OpenLDAP Software . * * Copyright 2007-2011 The OpenLDAP Foundation. @@ -34,10 +34,26 @@ static int sock_over_setup(); static slap_response sock_over_response; enum { - BS_EXT = 1 + BS_EXT = 1, + BS_OPS, + BS_RESP }; +/* The number of overlay-only config attrs */ +#define NUM_OV_ATTRS 2 + static ConfigTable bscfg[] = { + { "sockops", "ops", 2, 0, 0, ARG_MAGIC|BS_OPS, + bs_cf_gen, "( OLcfgDbAt:7.3 NAME 'olcOvSocketOps' " + "DESC 'Operation types to forward' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { "sockresps", "resps", 2, 0, 0, ARG_MAGIC|BS_RESP, + bs_cf_gen, "( OLcfgDbAt:7.4 NAME 'olcOvSocketResps' " + "DESC 'Response types to forward' " + "EQUALITY caseIgnoreMatch " + "SYNTAX OMsDirectoryString )", NULL, NULL }, + { "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET, (void *)offsetof(struct sockinfo, si_sockpath), "( OLcfgDbAt:7.1 NAME 'olcDbSocketPath' " @@ -59,7 +75,7 @@ static ConfigOCs bsocs[] = { "SUP olcDatabaseConfig " "MUST olcDbSocketPath " "MAY olcDbSocketExtensions )", - Cft_Database, bscfg }, + Cft_Database, bscfg+NUM_OV_ATTRS }, { NULL, 0, NULL } }; @@ -69,11 +85,24 @@ static ConfigOCs osocs[] = { "DESC 'Socket overlay configuration' " "SUP olcOverlayConfig " "MUST olcDbSocketPath " - "MAY olcDbSocketExtensions )", + "MAY ( olcDbSocketExtensions $ " + " olcOvSocketOps $ olcOvSocketResps ) )", Cft_Overlay, bscfg }, { NULL, 0, NULL } }; +#define SOCK_OP_BIND 0x001 +#define SOCK_OP_UNBIND 0x002 +#define SOCK_OP_SEARCH 0x004 +#define SOCK_OP_COMPARE 0x008 +#define SOCK_OP_MODIFY 0x010 +#define SOCK_OP_MODRDN 0x020 +#define SOCK_OP_ADD 0x040 +#define SOCK_OP_DELETE 0x080 + +#define SOCK_REP_RESULT 0x001 +#define SOCK_REP_SEARCH 0x002 + static slap_verbmasks bs_exts[] = { { BER_BVC("binddn"), SOCK_EXT_BINDDN }, { BER_BVC("peername"), SOCK_EXT_PEERNAME }, @@ -82,6 +111,24 @@ static slap_verbmasks bs_exts[] = { { BER_BVNULL, 0 } }; +static slap_verbmasks ov_ops[] = { + { BER_BVC("bind"), SOCK_OP_BIND }, + { BER_BVC("unbind"), SOCK_OP_UNBIND }, + { BER_BVC("search"), SOCK_OP_SEARCH }, + { BER_BVC("compare"), SOCK_OP_COMPARE }, + { BER_BVC("modify"), SOCK_OP_MODIFY }, + { BER_BVC("modrdn"), SOCK_OP_MODRDN }, + { BER_BVC("add"), SOCK_OP_ADD }, + { BER_BVC("delete"), SOCK_OP_DELETE }, + { BER_BVNULL, 0 } +}; + +static slap_verbmasks ov_resps[] = { + { BER_BVC("result"), SOCK_REP_RESULT }, + { BER_BVC("search"), SOCK_REP_SEARCH }, + { BER_BVNULL, 0 } +}; + static int bs_cf_gen( ConfigArgs *c ) { @@ -99,6 +146,10 @@ bs_cf_gen( ConfigArgs *c ) switch( c->type ) { case BS_EXT: return mask_to_verbs( bs_exts, si->si_extensions, &c->rvalue_vals ); + case BS_OPS: + return mask_to_verbs( ov_ops, si->si_ops, &c->rvalue_vals ); + case BS_RESP: + return mask_to_verbs( ov_resps, si->si_resps, &c->rvalue_vals ); } } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { @@ -113,12 +164,38 @@ bs_cf_gen( ConfigArgs *c ) si->si_extensions ^= dels; } return rc; + case BS_OPS: + if ( c->valx < 0 ) { + si->si_ops = 0; + rc = 0; + } else { + slap_mask_t dels = 0; + rc = verbs_to_mask( c->argc, c->argv, ov_ops, &dels ); + if ( rc == 0 ) + si->si_ops ^= dels; + } + return rc; + case BS_RESP: + if ( c->valx < 0 ) { + si->si_resps = 0; + rc = 0; + } else { + slap_mask_t dels = 0; + rc = verbs_to_mask( c->argc, c->argv, ov_resps, &dels ); + if ( rc == 0 ) + si->si_resps ^= dels; + } + return rc; } } else { switch( c->type ) { case BS_EXT: return verbs_to_mask( c->argc, c->argv, bs_exts, &si->si_extensions ); + case BS_OPS: + return verbs_to_mask( c->argc, c->argv, ov_ops, &si->si_ops ); + case BS_RESP: + return verbs_to_mask( c->argc, c->argv, ov_resps, &si->si_resps ); } } return 1; @@ -153,6 +230,17 @@ static BI_op_bind *sockfuncs[] = { sock_back_delete }; +static const int sockopflags[] = { + SOCK_OP_BIND, + SOCK_OP_UNBIND, + SOCK_OP_SEARCH, + SOCK_OP_COMPARE, + SOCK_OP_MODIFY, + SOCK_OP_MODRDN, + SOCK_OP_ADD, + SOCK_OP_DELETE +}; + static int sock_over_op( Operation *op, SlapReply *rs @@ -160,7 +248,8 @@ static int sock_over_op( { 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_callback *sc; + struct sockinfo *si; slap_operation_t which; int rc; @@ -176,13 +265,17 @@ static int sock_over_op( 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; + si = on->on_bi.bi_private; + if ( !(si->si_ops & sockopflags[which])) + return SLAP_CB_CONTINUE; + + op->o_bd->be_private = si; + sc = op->o_callback; + op->o_callback = NULL; rc = sockfuncs[which]( op, rs ); op->o_bd->be_private = private; - op->o_callback = cb.sc_next; - return SLAP_CB_CONTINUE; + op->o_callback = sc; + return rc; } static int @@ -192,21 +285,38 @@ sock_over_response( Operation *op, SlapR struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private; FILE *fp; - if ( rs->sr_type != REP_RESULT ) + if ( rs->sr_type == REP_RESULT ) { + if ( !( si->si_resps & SOCK_REP_RESULT )) + return SLAP_CB_CONTINUE; + } else if ( rs->sr_type == REP_SEARCH ) { + if ( !( si->si_resps & SOCK_REP_SEARCH )) + return SLAP_CB_CONTINUE; + } else 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 ); + if ( rs->sr_type == REP_RESULT ) { + /* 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 ); + } else { + /* write out the search entry */ + int len; + fprintf( fp, "ENTRY\n" ); + fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); + sock_print_conn( fp, op->o_conn, si ); + ldap_pvt_thread_mutex_lock( &entry2str_mutex ); + fprintf( fp, "%s", entry2str( rs->sr_entry, &len ) ); + ldap_pvt_thread_mutex_unlock( &entry2str_mutex ); + } fprintf( fp, "\n" ); fclose( fp );