return unsolicited responses

This commit is contained in:
Pierangelo Masarati 2007-01-04 19:58:29 +00:00
parent 8cb4f6b348
commit 963eaf63b6
2 changed files with 155 additions and 12 deletions

View File

@ -58,16 +58,27 @@ If not defined, the suffix of the database is used.
.hy 0
.B retcode\-item <RDN> <errCode> [op=<oplist>] [text=<message>]
.B [ref=<referral>] [sleeptime=<sec>] [matched=<DN>]
.B [unsolicited=<OID>[:<data>]]
.RS
A dynamically generated entry, located below \fBretcode\-parent\fP.
The \fB<errCode>\fP is the number of the response code;
it can be in any format supported by strtol.
The optional \fB<oplist>\fP is a list of operations that cause
The \fBerrCode\fP is the number of the response code;
it can be in any format supported by
.BR strtol (3).
The optional \fBoplist\fP is a list of operations that cause
response code generation; if absent, all operations are affected.
The \fBmatched\fP field is the matched DN that is returned
along with the error.
along with the error, while the \fBtext\fP field is an optional
diagnostics message.
The \fBref\fP field is only allowed for the \fBreferral\fP
response code.
The \fBsleeptime\fP field causes
.BR slapd (8)
to sleep the specified number of seconds before proceeding
with the operation.
The \fBunsolicited\fP field can be used to cause the return
of an RFC 4511 unsolicited response message; if \fBOID\fP
is not "0", an extended response is generated, with the optional
\fBdata\fP appended.
.RE
.TP
.B retcode\-indir
@ -148,6 +159,28 @@ The matched DN returned to the client:
SINGLE-VALUE )
.RE
.LP
The OID to be returned as extended response OID
in RFC 4511 unsolicited responses
("0" generates a regular response with msgid set to 0):
.RS 4
( 1.3.6.1.4.1.4203.666.11.4.1.6
NAME ( 'errUnsolicitedOID' )
DESC 'OID to be returned within unsolicited response'
EQUALITY objectIdentifierMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.38
SINGLE-VALUE )
.RE
.LP
The octet string to be returned as extended response data
in RFC 4511 unsolicited response:
.RS 4
( 1.3.6.1.4.1.4203.666.11.4.1.7
NAME ( 'errUnsolicitedData' )
DESC 'Data to be returned within unsolicited response'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
SINGLE-VALUE )
.RE
.LP
The abstract class that triggers the overlay:
.RS 4
( 1.3.6.1.4.1.4203.666.11.4.3.0

View File

@ -32,6 +32,7 @@
#include "slap.h"
#include "lutil.h"
#include "ldif.h"
static slap_overinst retcode;
@ -40,6 +41,8 @@ static AttributeDescription *ad_errText;
static AttributeDescription *ad_errOp;
static AttributeDescription *ad_errSleepTime;
static AttributeDescription *ad_errMatchedDN;
static AttributeDescription *ad_errUnsolicitedOID;
static AttributeDescription *ad_errUnsolicitedData;
static ObjectClass *oc_errAbsObject;
static ObjectClass *oc_errObject;
static ObjectClass *oc_errAuxObject;
@ -70,6 +73,8 @@ typedef struct retcode_item_t {
int rdi_sleeptime;
Entry rdi_e;
slap_mask_t rdi_mask;
struct berval rdi_unsolicited_oid;
struct berval rdi_unsolicited_data;
struct retcode_item_t *rdi_next;
} retcode_item_t;
@ -143,11 +148,6 @@ retcode_send_onelevel( Operation *op, SlapReply *rs )
rs->sr_err = test_filter( op, &rdi->rdi_e, op->ors_filter );
if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
if ( op->ors_slimit == rs->sr_nentries ) {
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
goto done;
}
/* safe default */
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
@ -447,7 +447,35 @@ retcode_op_func( Operation *op, SlapReply *rs )
break;
default:
send_ldap_result( op, rs );
if ( rdi && !BER_BVISNULL( &rdi->rdi_unsolicited_oid ) ) {
ber_int_t msgid = op->o_msgid;
/* RFC 4511 unsolicited response */
op->o_msgid = 0;
if ( strcmp( rdi->rdi_unsolicited_oid.bv_val, "0" ) == 0 ) {
send_ldap_result( op, rs );
} else {
ber_tag_t tag = op->o_tag;
op->o_tag = LDAP_REQ_EXTENDED;
rs->sr_rspoid = rdi->rdi_unsolicited_oid.bv_val;
if ( !BER_BVISNULL( &rdi->rdi_unsolicited_data ) ) {
rs->sr_rspdata = &rdi->rdi_unsolicited_data;
}
send_ldap_extended( op, rs );
rs->sr_rspoid = NULL;
rs->sr_rspdata = NULL;
op->o_tag = tag;
}
op->o_msgid = msgid;
} else {
send_ldap_result( op, rs );
}
if ( rs->sr_ref != NULL ) {
ber_bvarray_free( rs->sr_ref );
rs->sr_ref = NULL;
@ -596,7 +624,44 @@ retcode_entry_response( Operation *op, SlapReply *rs, BackendInfo *bi, Entry *e
rs->sr_ref = NULL;
} else {
send_ldap_result( op, rs );
a = attr_find( e->e_attrs, ad_errUnsolicitedOID );
if ( a != NULL ) {
struct berval oid = BER_BVNULL,
data = BER_BVNULL;
ber_int_t msgid = op->o_msgid;
/* RFC 4511 unsolicited response */
op->o_msgid = 0;
oid = a->a_nvals[ 0 ];
a = attr_find( e->e_attrs, ad_errUnsolicitedData );
if ( a != NULL ) {
data = a->a_nvals[ 0 ];
}
if ( strcmp( oid.bv_val, "0" ) == 0 ) {
send_ldap_result( op, rs );
} else {
ber_tag_t tag = op->o_tag;
op->o_tag = LDAP_REQ_EXTENDED;
rs->sr_rspoid = oid.bv_val;
if ( !BER_BVISNULL( &data ) ) {
rs->sr_rspdata = &data;
}
send_ldap_extended( op, rs );
rs->sr_rspoid = NULL;
rs->sr_rspdata = NULL;
op->o_tag = tag;
}
op->o_msgid = msgid;
} else {
send_ldap_result( op, rs );
}
}
rs->sr_text = NULL;
@ -887,6 +952,37 @@ retcode_db_config(
return 1;
}
} else if ( strncasecmp( argv[ i ], "unsolicited=", STRLENOF( "unsolicited=" ) ) == 0 )
{
char *data;
if ( !BER_BVISNULL( &rdi.rdi_unsolicited_oid ) ) {
fprintf( stderr, "%s: line %d: retcode: "
"\"unsolicited\" already provided.\n",
fname, lineno );
return 1;
}
data = strchr( &argv[ i ][ STRLENOF( "unsolicited=" ) ], ':' );
if ( data != NULL ) {
struct berval oid;
if ( ldif_parse_line2( &argv[ i ][ STRLENOF( "unsolicited=" ) ],
&oid, &rdi.rdi_unsolicited_data, NULL ) )
{
fprintf( stderr, "%s: line %d: retcode: "
"unable to parse \"unsolicited\".\n",
fname, lineno );
return 1;
}
ber_dupbv( &rdi.rdi_unsolicited_oid, &oid );
} else {
ber_str2bv( &argv[ i ][ STRLENOF( "unsolicited=" ) ], 0, 1,
&rdi.rdi_unsolicited_oid );
}
} else {
fprintf( stderr, "%s: line %d: retcode: "
"unknown option \"%s\".\n",
@ -1118,7 +1214,6 @@ int
retcode_initialize( void )
{
int i, code;
const char *err;
static struct {
char *desc;
@ -1161,6 +1256,19 @@ retcode_initialize( void )
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
"SINGLE-VALUE )",
&ad_errMatchedDN },
{ "( 1.3.6.1.4.1.4203.666.11.4.1.6 "
"NAME ( 'errUnsolicitedOID' ) "
"DESC 'OID to be returned within unsolicited response' "
"EQUALITY objectIdentifierMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.38 "
"SINGLE-VALUE )",
&ad_errUnsolicitedOID },
{ "( 1.3.6.1.4.1.4203.666.11.4.1.7 "
"NAME ( 'errUnsolicitedData' ) "
"DESC 'Data to be returned within unsolicited response' "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 "
"SINGLE-VALUE )",
&ad_errUnsolicitedData },
{ NULL }
};
@ -1179,6 +1287,8 @@ retcode_initialize( void )
"$ errText "
"$ errSleepTime "
"$ errMatchedDN "
"$ errUnsolicitedOID "
"$ errUnsolicitedData "
") )",
&oc_errAbsObject },
{ "( 1.3.6.1.4.1.4203.666.11.4.3.1 "