.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
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
#include "slap.h"
#include "lutil.h"
+#include "ldif.h"
static slap_overinst retcode;
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;
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;
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;
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;
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;
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",
retcode_initialize( void )
{
int i, code;
- const char *err;
static struct {
char *desc;
"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 }
};
"$ errText "
"$ errSleepTime "
"$ errMatchedDN "
+ "$ errUnsolicitedOID "
+ "$ errUnsolicitedData "
") )",
&oc_errAbsObject },
{ "( 1.3.6.1.4.1.4203.666.11.4.3.1 "