mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-09 02:52:04 +08:00
Add overlay config stuff, handle overlay responses
This commit is contained in:
parent
5d9baf3e85
commit
999b6407b0
@ -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 );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user