Commit 999b6407 authored by Howard Chu's avatar Howard Chu
Browse files

Add overlay config stuff, handle overlay responses

parent 5d9baf3e
......@@ -28,6 +28,8 @@ LDAP_BEGIN_DECL
struct sockinfo {
const char *si_sockpath;
slap_mask_t si_extensions;
slap_mask_t si_ops; /* overlay: operations to act on */
slap_mask_t si_resps; /* overlay: responses to forward */
};
#define SOCK_EXT_BINDDN 1
......
......@@ -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, SlapReply *rs )
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 );
......
......@@ -91,6 +91,13 @@ sock_read_and_send_results(
if ( strncasecmp( buf, "RESULT", 6 ) == 0 ) {
break;
}
if ( strncasecmp( buf, "CONTINUE", 8 ) == 0 ) {
struct sockinfo *si = (struct sockinfo *) op->o_bd->be_private;
/* Only valid when operating as an overlay! */
assert( si->si_ops != 0 );
rs->sr_err = SLAP_CB_CONTINUE;
goto skip;
}
if ( (rs->sr_entry = str2entry( buf )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n",
......@@ -113,7 +120,8 @@ sock_read_and_send_results(
send_ldap_result( op, rs );
}
free( buf );
skip:
ch_free( buf );
return( rs->sr_err );
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment