]> git.sur5r.net Git - openldap/commitdiff
return unsolicited responses
authorPierangelo Masarati <ando@openldap.org>
Thu, 4 Jan 2007 19:58:29 +0000 (19:58 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 4 Jan 2007 19:58:29 +0000 (19:58 +0000)
doc/man/man5/slapo-retcode.5
servers/slapd/overlays/retcode.c

index 5102c0383992bf9fdaed79fa9f468a9c1b4236b1..1de17fdefdfd840d27bc36cd34d548f5feee6139 100644 (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
index 8672c04d34951ab8ff1440989ee37879dcddd229..a92430a9045c07b52918c0643fbb430f59b6fc9e 100644 (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 "