send_ldap_referral(
    Slapi_PBlock *pb,
    Slapi_Entry *e,
    struct berval **refs,
    struct berval ***urls)
{
    char *refAttr = "ref";
    char *attrs[2] = {NULL, NULL};

    Connection *pb_conn;

    /* count the referral */
    slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsReferrals);

    attrs[0] = refAttr;
    if (e != NULL &&
        plugin_call_acl_plugin(pb, e, attrs, NULL,
                               SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL) != LDAP_SUCCESS) {
        return (0);
    }

    slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
    if (pb_conn && pb_conn->c_ldapversion > LDAP_VERSION2) {
        /*
         * v3 connection - send the referral(s) in a
         * SearchResultReference packet right now.
         */
        return (send_ldapv3_referral(pb, refs));
    } else {
        /*
         * v2 connection - add the referral(s) to the
         * list being maintained in urls. they will be
         * sent to the client later when send_ldap_result()
         * is called.
         */
        int i, need, have;

        if (refs == NULL && urls == NULL) {
            return (0);
        }

        for (have = 0; *urls != NULL && (*urls)[have] != NULL;
             have++) {
            ; /* NULL */
        }
        for (need = 0; refs != NULL && refs[need] != NULL; need++) {
            ; /* NULL */
        }

        *urls = (struct berval **)slapi_ch_realloc((char *)*urls,
                                                   (need + have + 1) * sizeof(struct berval *));
        for (i = have; i < have + need; i++) {
            (*urls)[i] = ber_bvdup(refs[i - have]);
        }
        (*urls)[i] = NULL;
    }

    return (0);
}
send_ldap_referral(
    Slapi_PBlock *pb,
    Slapi_Entry *e,
    struct berval **refs,
    struct berval ***urls)
{
    char *refAttr = "ref";
    char *attrs[2] = {NULL, NULL};

    Connection *pb_conn;

     
    slapi_counter_increment(g_get_global_snmp_vars()->ops_tbl.dsReferrals);

    attrs[0] = refAttr;
    if (e != NULL &&
        plugin_call_acl_plugin(pb, e, attrs, NULL,
                               SLAPI_ACL_READ, ACLPLUGIN_ACCESS_DEFAULT, NULL) != LDAP_SUCCESS) {
        return (0);
    }

    slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
    if (pb_conn && pb_conn->c_ldapversion > LDAP_VERSION2) {
         
        return (send_ldapv3_referral(pb, refs));
    } else {
         
        int i, need, have;

        if (refs == NULL && urls == NULL) {
            return (0);
        }

        for (have = 0; *urls != NULL && (*urls)[have] != NULL;
             have++) {
            ;  
        }
        for (need = 0; refs != NULL && refs[need] != NULL; need++) {
            ;  
        }

        *urls = (struct berval **)slapi_ch_realloc((char *)*urls,
                                                   (need + have + 1) * sizeof(struct berval *));
        for (i = have; i < have + need; i++) {
            (*urls)[i] = ber_bvdup(refs[i - have]);
        }
        (*urls)[i] = NULL;
    }

    return (0);
}