]> git.sur5r.net Git - openldap/commitdiff
Intermediate Response
authorJong Hyuk Choi <jongchoi@openldap.org>
Mon, 3 Feb 2003 17:28:19 +0000 (17:28 +0000)
committerJong Hyuk Choi <jongchoi@openldap.org>
Mon, 3 Feb 2003 17:28:19 +0000 (17:28 +0000)
include/ldap.h
libraries/libldap/extended.c
libraries/libldap/result.c
servers/slapd/connection.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/slap.h
servers/slapd/tools/mimic.c

index b746ad773f3bd7721e7df993c318f7532854d489..361a8244399478e64853ad48d4286f9c553c3ed3 100644 (file)
@@ -322,6 +322,7 @@ typedef struct ldapcontrol {
 #define LDAP_RES_COMPARE               ((ber_tag_t) 0x6fU)     /* application + constructed */
 #define LDAP_RES_EXTENDED              ((ber_tag_t) 0x78U)     /* V3: application + constructed */
 #define LDAP_RES_EXTENDED_PARTIAL      ((ber_tag_t) 0x79U)     /* V3+: application + constructed */
+#define LDAP_RES_INTERMEDIATE_RESP     ((ber_tag_t) 0x7aU)
 
 #define LDAP_RES_ANY                   (-1)
 #define LDAP_RES_UNSOLICITED   (0)
@@ -683,6 +684,14 @@ ldap_parse_extended_partial LDAP_P((
        LDAPControl             ***serverctrls,
        int                             freeit ));
 
+LDAP_F( int )
+ldap_parse_intermediate_resp_result LDAP_P((
+       LDAP                    *ld,
+       LDAPMessage             *res,
+       char                    **retoidp,
+       struct berval   **retdatap,
+       int                             freeit ));
+
 /*
  * in abandon.c:
  */
index 18281bb23ec6054712554053d76be642ac3d59d7..5a6508f9b8c8420ec819b95c2fe1a51ac5e6fbb5 100644 (file)
@@ -393,3 +393,118 @@ free_and_return:
 
        return LDAP_SUCCESS;
 }
+
+/* Parse an intermediate response result */
+int
+ldap_parse_intermediate_resp_result (
+       LDAP                    *ld,
+       LDAPMessage             *res,
+       char                    **retoidp,
+       struct berval           **retdatap,
+       int                     freeit )
+{
+       BerElement *ber;
+       ber_tag_t rc;
+       ber_tag_t tag;
+       ber_len_t len;
+       struct berval *resdata;
+       ber_int_t errcode;
+       char *resoid;
+
+       assert( ld != NULL );
+       assert( LDAP_VALID( ld ) );
+       assert( res != NULL );
+
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, ENTRY, "ldap_parse_intermediate_resp_result\n", 0,0,0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "ldap_parse_intermediate_resp_result\n", 0, 0, 0 );
+#endif
+
+       if( ld->ld_version < LDAP_VERSION3 ) {
+               ld->ld_errno = LDAP_NOT_SUPPORTED;
+               return ld->ld_errno;
+       }
+
+       if( res->lm_msgtype != LDAP_RES_INTERMEDIATE_RESP ) {
+               ld->ld_errno = LDAP_PARAM_ERROR;
+               return ld->ld_errno;
+       }
+
+       if( retoidp != NULL ) *retoidp = NULL;
+       if( retdatap != NULL ) *retdatap = NULL;
+
+       if ( ld->ld_error ) {
+               LDAP_FREE( ld->ld_error );
+               ld->ld_error = NULL;
+       }
+
+       if ( ld->ld_matched ) {
+               LDAP_FREE( ld->ld_matched );
+               ld->ld_matched = NULL;
+       }
+
+       ber = ber_dup( res->lm_ber );
+
+       if ( ber == NULL ) {
+               ld->ld_errno = LDAP_NO_MEMORY;
+               return ld->ld_errno;
+       }
+
+       rc = ber_scanf( ber, "{iaa" /*}*/, &errcode,
+               &ld->ld_matched, &ld->ld_error );
+
+       if( rc == LBER_ERROR ) {
+               ld->ld_errno = LDAP_DECODING_ERROR;
+               ber_free( ber, 0 );
+               return ld->ld_errno;
+       }
+
+       resoid = NULL;
+       resdata = NULL;
+
+       tag = ber_peek_tag( ber, &len );
+
+       if( tag == LDAP_TAG_EXOP_RES_OID ) {
+               /* we have a resoid */
+               if( ber_scanf( ber, "a", &resoid ) == LBER_ERROR ) {
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       ber_free( ber, 0 );
+                       return ld->ld_errno;
+               }
+
+               tag = ber_peek_tag( ber, &len );
+       }
+
+       if( tag == LDAP_TAG_EXOP_RES_VALUE ) {
+               /* we have a resdata */
+               if( ber_scanf( ber, "O", &resdata ) == LBER_ERROR ) {
+                       ld->ld_errno = LDAP_DECODING_ERROR;
+                       ber_free( ber, 0 );
+                       if( resoid != NULL ) LDAP_FREE( resoid );
+                       return ld->ld_errno;
+               }
+       }
+
+       ber_free( ber, 0 );
+
+       if( retoidp != NULL ) {
+               *retoidp = resoid;
+       } else {
+               LDAP_FREE( resoid );
+       }
+
+       if( retdatap != NULL ) {
+               *retdatap = resdata;
+       } else {
+               ber_bvfree( resdata );
+       }
+
+       ld->ld_errno = errcode;
+
+       if( freeit ) {
+               ldap_msgfree( res );
+       }
+
+       return LDAP_SUCCESS;
+}
index ab9a075b4745570d9b6ead40a34c748dfcfbca35..f6d62b64ef56ddafa071b24798d8ba516c446c04 100644 (file)
@@ -645,7 +645,8 @@ retry_ber:
         * go through the following code.  This code also chases V2 referrals
         * and checks if all referrals have been chased.
         */
-       if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1) ) {
+       if ( (tag != LDAP_RES_SEARCH_ENTRY) && (v3ref > -1) &&
+            (tag != LDAP_RES_INTERMEDIATE_RESP ) ) {
                /* For a v3 search referral/reference, only come here if already chased it */
                if ( ld->ld_version >= LDAP_VERSION2 &&
                        ( lr->lr_parent != NULL ||
index 13bdbe36fcb11cd604d411ae1b0503b147fecf03..0f54d412ebe25e5f83f2bd3b420f13a79397c8cf 100644 (file)
@@ -416,6 +416,7 @@ long connection_init(
                c->c_send_search_result = slap_send_search_result;
                c->c_send_search_reference = slap_send_search_reference;
                c->c_send_ldap_extended = slap_send_ldap_extended;
+               c->c_send_ldap_intermediate_resp = slap_send_ldap_intermediate_resp;
 
                c->c_authmech.bv_val = NULL;
                c->c_authmech.bv_len = 0;
index de11528d19406a89b6931559bbfe618efa171c53..4b26475dfc5f3655f659b80c992a35a0c13dee93 100644 (file)
@@ -821,6 +821,13 @@ LDAP_SLAPD_F (void) slap_send_ldap_extended LDAP_P((
        const char *rspoid, struct berval *rspdata,
        LDAPControl **ctrls ));
 
+LDAP_SLAPD_F (void) slap_send_ldap_intermediate_resp LDAP_P((
+       Connection *conn, Operation *op,
+       ber_int_t err, const char *matched,
+       const char *text, BerVarray refs,
+       const char *rspoid, struct berval *rspdata,
+       LDAPControl **ctrls ));
+
 LDAP_SLAPD_F (void) send_ldap_partial LDAP_P((
        Connection *conn, Operation *op,
        const char *rspoid, struct berval *rspdata,
index fcae73adf050c51f35d01e87643a6458f16ff932..23c4099df7ff1a43e040773e20d0b3de9688859a 100644 (file)
@@ -582,6 +582,38 @@ slap_send_ldap_extended(
                rspoid, rspdata, NULL, ctrls );
 }
 
+void
+slap_send_ldap_intermediate_resp(
+       Connection  *conn,
+       Operation   *op,
+       ber_int_t   err,
+       const char  *matched,
+       const char  *text,
+       BerVarray   refs,
+       const char  *rspoid,
+       struct berval *rspdata,
+       LDAPControl **ctrls )
+{
+       ber_tag_t tag;
+       ber_int_t msgid;
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ENTRY,
+               "send_ldap_intermediate: err=%d oid=%s len=%ld\n",
+               err, rspoid ? rspoid : "",
+               rspdata != NULL ? rspdata->bv_len : 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "send_ldap_intermediate: err=%d oid=%s len=%ld\n",
+               err,
+               rspoid ? rspoid : "",
+               rspdata != NULL ? rspdata->bv_len : 0 );
+#endif
+       tag = LDAP_RES_INTERMEDIATE_RESP;
+       msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
+       send_ldap_response( conn, op, tag, msgid,
+               err, matched, text, refs,
+               rspoid, rspdata, NULL, ctrls );
+}
 
 void
 slap_send_search_result(
index a0a1b920d6dc434df82f8f0d9ef55902c9f8a08e..152f971462fd3774a753250608d3f99c7e9b45b8 100644 (file)
@@ -1800,6 +1800,22 @@ typedef void (*SEND_LDAP_EXTENDED)(
 #define send_ldap_extended( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls) \
 (*conn->c_send_ldap_extended)( conn, op, err, matched, text, refs, rspoid, rspdata, ctrls )
 
+typedef void (*SEND_LDAP_INTERMEDIATE_RESP)(
+                               struct slap_conn *conn,
+                               struct slap_op *op,
+                               ber_int_t   err,
+                               const char  *matched,
+                               const char  *text,
+                               BerVarray   refs,
+                               const char      *rspoid,
+                               struct berval *rspdata,
+                               LDAPControl **ctrls
+                               );
+
+#define send_ldap_intermediate_resp( conn, op, err, matched, text, refs, \
+                                    rspoid, rspdata, ctrls) \
+       (*conn->c_send_ldap_intermediate_resp)( conn, op, err, matched, text, \
+                                               refs, rspoid, rspdata, ctrls )
 
 /*
  * Caches the result of a backend_group check for ACL evaluation
@@ -1894,6 +1910,7 @@ typedef struct slap_conn {
        SEND_SEARCH_RESULT c_send_search_result;
        SEND_SEARCH_REFERENCE c_send_search_reference;
        SEND_LDAP_EXTENDED c_send_ldap_extended;
+       SEND_LDAP_INTERMEDIATE_RESP c_send_ldap_intermediate_resp;
        
 } Connection;
 
index 53131be6d6f7b876d13275a421e57a5c7fafc9b8..dd5dc46eafad0abf695c7859a43c28f109dc8eb2 100644 (file)
@@ -57,6 +57,22 @@ slap_send_ldap_extended(
        assert(0);
 }
 
+void
+slap_send_ldap_intermediate_resp(
+       Connection  *conn,
+       Operation   *op,
+       ber_int_t   err,
+       const char  *matched,
+       const char  *text,
+       BerVarray refs,
+       const char  *rspoid,
+       struct berval *rspdata,
+       LDAPControl **ctrls
+)
+{
+       assert(0);
+}
+
 void
 send_ldap_sasl(
     Connection *conn,