send_ldapv3_referral(
    Slapi_PBlock *pb,
    struct berval **urls)
{
    Connection *conn = NULL;
    BerElement *ber;
    int i, rc, logit = 0;
    Slapi_Operation *operation;
    Slapi_Backend *pb_backend;

    slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
    slapi_pblock_get(pb, SLAPI_CONNECTION, &conn);
    slapi_pblock_get(pb, SLAPI_BACKEND, &pb_backend);

    slapi_log_err(SLAPI_LOG_TRACE, "send_ldapv3_referral", "=>\n");

    if (conn == NULL) {
        if (operation->o_search_referral_handler != NULL) {
            if ((rc = (*operation->o_search_referral_handler)(
                     pb_backend, conn, operation, urls)) == 0) {
                logit = 1;
            }
            goto log_and_return;
        }
        return (0);
    }
    if (urls == NULL) {
        return (0);
    }

    if ((ber = der_alloc()) == NULL) {
        slapi_log_err(SLAPI_LOG_ERR, "send_ldapv3_referral", "ber_alloc failed\n");
        send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
                         "ber_alloc", 0, NULL);
        return (-1);
    }

    /*
     * send the ldapv3 SearchResultReference. it looks like this:
     *
     *    SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
     *
     * all wrapped up in an LDAPMessage sequence which looks like this:
     *    LDAPMessage ::= SEQUENCE {
     *        messageID       MessageID,
     *        SearchResultReference
     *        controls        [0] Controls OPTIONAL
     *      }
     */

    for (i = 0, rc = ber_printf(ber, "{it{", operation->o_msgid,
                                LDAP_RES_SEARCH_REFERENCE);
         rc != LBER_ERROR && urls[i] != NULL; i++) {
        rc = ber_printf(ber, "s", urls[i]->bv_val);
    }
    if (rc == LBER_ERROR) {
        slapi_log_err(SLAPI_LOG_ERR, "send_ldapv3_referral", "ber_printf failed 2\n");
        send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
                         "ber_printf", 0, NULL);
        return (-1);
    }
    if (ber_printf(ber, "}}") == LBER_ERROR) {
        slapi_log_err(SLAPI_LOG_ERR, "send_ldapv3_referral", "ber_printf failed 3\n");
        send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
                         "ber_printf", 0, NULL);
        return (-1);
    }

    /* write only one pdu at a time - wait til it's our turn */
    if ((rc = flush_ber(pb, conn, operation, ber, _LDAP_SEND_REFERRAL)) == 0) {
        logit = 1;
    }

log_and_return:
    if (logit && operation_is_flag_set(operation,
                                       OP_FLAG_ACTION_LOG_ACCESS)) {
        log_referral(operation);
    }

    return (rc);
}
send_ldapv3_referral(
    Slapi_PBlock *pb,
    struct berval **urls)
{
    Connection *conn = NULL;
    BerElement *ber;
    int i, rc, logit = 0;
    Slapi_Operation *operation;
    Slapi_Backend *pb_backend;

    slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
    slapi_pblock_get(pb, SLAPI_CONNECTION, &conn);
    slapi_pblock_get(pb, SLAPI_BACKEND, &pb_backend);

    slapi_log_err(SLAPI_LOG_TRACE, "send_ldapv3_referral", "=>\n");

    if (conn == NULL) {
        if (operation->o_search_referral_handler != NULL) {
            if ((rc = (*operation->o_search_referral_handler)(
                     pb_backend, conn, operation, urls)) == 0) {
                logit = 1;
            }
            goto log_and_return;
        }
        return (0);
    }
    if (urls == NULL) {
        return (0);
    }

    if ((ber = der_alloc()) == NULL) {
        slapi_log_err(SLAPI_LOG_ERR, "send_ldapv3_referral", "ber_alloc failed\n");
        send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
                         "ber_alloc", 0, NULL);
        return (-1);
    }

     

    for (i = 0, rc = ber_printf(ber, "{it{", operation->o_msgid,
                                LDAP_RES_SEARCH_REFERENCE);
         rc != LBER_ERROR && urls[i] != NULL; i++) {
        rc = ber_printf(ber, "s", urls[i]->bv_val);
    }
    if (rc == LBER_ERROR) {
        slapi_log_err(SLAPI_LOG_ERR, "send_ldapv3_referral", "ber_printf failed 2\n");
        send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
                         "ber_printf", 0, NULL);
        return (-1);
    }
    if (ber_printf(ber, "}}") == LBER_ERROR) {
        slapi_log_err(SLAPI_LOG_ERR, "send_ldapv3_referral", "ber_printf failed 3\n");
        send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
                         "ber_printf", 0, NULL);
        return (-1);
    }

     
    if ((rc = flush_ber(pb, conn, operation, ber, _LDAP_SEND_REFERRAL)) == 0) {
        logit = 1;
    }

log_and_return:
    if (logit && operation_is_flag_set(operation,
                                       OP_FLAG_ACTION_LOG_ACCESS)) {
        log_referral(operation);
    }

    return (rc);
}