Add overlay config stuff, handle overlay responses

This commit is contained in:
Howard Chu 2011-02-04 10:52:34 +00:00
parent 5d9baf3e85
commit 999b6407b0
3 changed files with 140 additions and 20 deletions

View File

@ -28,6 +28,8 @@ LDAP_BEGIN_DECL
struct sockinfo { struct sockinfo {
const char *si_sockpath; const char *si_sockpath;
slap_mask_t si_extensions; 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 #define SOCK_EXT_BINDDN 1

View File

@ -34,10 +34,26 @@ static int sock_over_setup();
static slap_response sock_over_response; static slap_response sock_over_response;
enum { 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[] = { 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, { "socketpath", "pathname", 2, 2, 0, ARG_STRING|ARG_OFFSET,
(void *)offsetof(struct sockinfo, si_sockpath), (void *)offsetof(struct sockinfo, si_sockpath),
"( OLcfgDbAt:7.1 NAME 'olcDbSocketPath' " "( OLcfgDbAt:7.1 NAME 'olcDbSocketPath' "
@ -59,7 +75,7 @@ static ConfigOCs bsocs[] = {
"SUP olcDatabaseConfig " "SUP olcDatabaseConfig "
"MUST olcDbSocketPath " "MUST olcDbSocketPath "
"MAY olcDbSocketExtensions )", "MAY olcDbSocketExtensions )",
Cft_Database, bscfg }, Cft_Database, bscfg+NUM_OV_ATTRS },
{ NULL, 0, NULL } { NULL, 0, NULL }
}; };
@ -69,11 +85,24 @@ static ConfigOCs osocs[] = {
"DESC 'Socket overlay configuration' " "DESC 'Socket overlay configuration' "
"SUP olcOverlayConfig " "SUP olcOverlayConfig "
"MUST olcDbSocketPath " "MUST olcDbSocketPath "
"MAY olcDbSocketExtensions )", "MAY ( olcDbSocketExtensions $ "
" olcOvSocketOps $ olcOvSocketResps ) )",
Cft_Overlay, bscfg }, Cft_Overlay, bscfg },
{ NULL, 0, NULL } { 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[] = { static slap_verbmasks bs_exts[] = {
{ BER_BVC("binddn"), SOCK_EXT_BINDDN }, { BER_BVC("binddn"), SOCK_EXT_BINDDN },
{ BER_BVC("peername"), SOCK_EXT_PEERNAME }, { BER_BVC("peername"), SOCK_EXT_PEERNAME },
@ -82,6 +111,24 @@ static slap_verbmasks bs_exts[] = {
{ BER_BVNULL, 0 } { 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 static int
bs_cf_gen( ConfigArgs *c ) bs_cf_gen( ConfigArgs *c )
{ {
@ -99,6 +146,10 @@ bs_cf_gen( ConfigArgs *c )
switch( c->type ) { switch( c->type ) {
case BS_EXT: case BS_EXT:
return mask_to_verbs( bs_exts, si->si_extensions, &c->rvalue_vals ); 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 ) { } else if ( c->op == LDAP_MOD_DELETE ) {
switch( c->type ) { switch( c->type ) {
@ -113,12 +164,38 @@ bs_cf_gen( ConfigArgs *c )
si->si_extensions ^= dels; si->si_extensions ^= dels;
} }
return rc; 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 { } else {
switch( c->type ) { switch( c->type ) {
case BS_EXT: case BS_EXT:
return verbs_to_mask( c->argc, c->argv, bs_exts, &si->si_extensions ); 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; return 1;
@ -153,6 +230,17 @@ static BI_op_bind *sockfuncs[] = {
sock_back_delete 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( static int sock_over_op(
Operation *op, Operation *op,
SlapReply *rs SlapReply *rs
@ -160,7 +248,8 @@ static int sock_over_op(
{ {
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
void *private = op->o_bd->be_private; 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; slap_operation_t which;
int rc; int rc;
@ -176,13 +265,17 @@ static int sock_over_op(
default: default:
return SLAP_CB_CONTINUE; return SLAP_CB_CONTINUE;
} }
op->o_bd->be_private = on->on_bi.bi_private; si = on->on_bi.bi_private;
cb.sc_next = op->o_callback; if ( !(si->si_ops & sockopflags[which]))
op->o_callback = &cb; return SLAP_CB_CONTINUE;
op->o_bd->be_private = si;
sc = op->o_callback;
op->o_callback = NULL;
rc = sockfuncs[which]( op, rs ); rc = sockfuncs[which]( op, rs );
op->o_bd->be_private = private; op->o_bd->be_private = private;
op->o_callback = cb.sc_next; op->o_callback = sc;
return SLAP_CB_CONTINUE; return rc;
} }
static int static int
@ -192,21 +285,38 @@ sock_over_response( Operation *op, SlapReply *rs )
struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private; struct sockinfo *si = (struct sockinfo *)on->on_bi.bi_private;
FILE *fp; 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; return SLAP_CB_CONTINUE;
if (( fp = opensock( si->si_sockpath )) == NULL ) if (( fp = opensock( si->si_sockpath )) == NULL )
return SLAP_CB_CONTINUE; return SLAP_CB_CONTINUE;
/* write out the result */ if ( rs->sr_type == REP_RESULT ) {
fprintf( fp, "RESULT\n" ); /* write out the result */
fprintf( fp, "msgid: %ld\n", (long) op->o_msgid ); fprintf( fp, "RESULT\n" );
sock_print_conn( fp, op->o_conn, si ); fprintf( fp, "msgid: %ld\n", (long) op->o_msgid );
fprintf( fp, "code: %d\n", rs->sr_err ); sock_print_conn( fp, op->o_conn, si );
if ( rs->sr_matched ) fprintf( fp, "code: %d\n", rs->sr_err );
fprintf( fp, "matched: %s\n", rs->sr_matched ); if ( rs->sr_matched )
if (rs->sr_text ) fprintf( fp, "matched: %s\n", rs->sr_matched );
fprintf( fp, "info: %s\n", rs->sr_text ); 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" ); fprintf( fp, "\n" );
fclose( fp ); fclose( fp );

View File

@ -91,6 +91,13 @@ sock_read_and_send_results(
if ( strncasecmp( buf, "RESULT", 6 ) == 0 ) { if ( strncasecmp( buf, "RESULT", 6 ) == 0 ) {
break; 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 ) { if ( (rs->sr_entry = str2entry( buf )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n", Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n",
@ -113,7 +120,8 @@ sock_read_and_send_results(
send_ldap_result( op, rs ); send_ldap_result( op, rs );
} }
free( buf ); skip:
ch_free( buf );
return( rs->sr_err ); return( rs->sr_err );
} }