static apr_status_t apr_ldap_control_parse()

in ldap/apr_ldap.c [1334:1486]


static apr_status_t apr_ldap_control_parse(apr_pool_t *pool,
                                           apr_ldap_t *ldap,
                                           LDAPControl **ctls,
                                           apr_hash_t **controls,
                                           apu_err_t *err)
{
    apr_hash_t *cs;

    int i = 0;

    if (!ctls || !ctls[0]) {
        *controls = NULL;
        return APR_SUCCESS;
    }

    cs = apr_hash_make(pool);

    if (!cs) {
        return APR_ENOMEM;
    }

    for (i = 0; ctls[i]; i++) {

        LDAPControl *ctl = (LDAPControl *)ctls[i];

        apr_ldap_control_t *c = apr_pcalloc(pool, sizeof(apr_ldap_control_t));

        c->critical = ctl->ldctl_iscritical ? 1 : 0;

        /* what controls do we recognise? */

#if APR_HAS_OPENLDAP_LDAPSDK

        if (!strcmp(ctl->ldctl_oid, LDAP_CONTROL_SORTRESPONSE)) {

            ber_int_t result;
            char *attr;

            err->rc = ldap_parse_sortresponse_control(ldap->ld, ctl, &result, &attr);

            if (err->rc != LDAP_SUCCESS) {
                err->msg = ldap_err2string(err->rc);
                err->reason = "LDAP: ldap_parse_sortresponse_control failed";
                return apr_ldap_status(err->rc);
            }

            c->type = APR_LDAP_CONTROL_SORT_RESPONSE;

            if (attr) {

                apr_pool_cleanup_register(pool, attr, ldap_memfree_cleanup,
                                          apr_pool_cleanup_null);

            }

            c->c.sortrs.attribute = (const char *)attr;
            c->c.sortrs.result = apr_ldap_status(result);

            apr_hash_set(cs, ctl->ldctl_oid, APR_HASH_KEY_STRING, c);

            continue;
        }

        if (!strcmp(ctl->ldctl_oid, LDAP_CONTROL_PAGEDRESULTS)) {

            ber_int_t count;
            struct berval cookie;

            err->rc = ldap_parse_pageresponse_control(ldap->ld, ctl, &count, &cookie);

            if (err->rc != LDAP_SUCCESS) {
                err->msg = ldap_err2string(err->rc);
                err->reason = "LDAP: ldap_parse_pageresponse_control failed";
                return apr_ldap_status(err->rc);
            }

            c->type = APR_LDAP_CONTROL_PAGE_RESPONSE;

            if (cookie.bv_val) {
                apr_buffer_mem_set(&c->c.pagers.cookie, cookie.bv_val, cookie.bv_len);

                apr_pool_cleanup_register(pool, cookie.bv_val, ldap_memfree_cleanup,
                                          apr_pool_cleanup_null);

            }
            else {
                apr_buffer_mem_set(&c->c.pagers.cookie, NULL, 0);
            }

            c->c.pagers.count = (apr_size_t)count;

            apr_hash_set(cs, ctl->ldctl_oid, APR_HASH_KEY_STRING, c);

            continue;
        }

        if (!strcmp(ctl->ldctl_oid, LDAP_CONTROL_VLVRESPONSE)) {

            ber_int_t target_posp;
            ber_int_t list_countp;
            int result;

            struct berval *context = NULL;

            err->rc = ldap_parse_vlvresponse_control(ldap->ld, ctl, &target_posp, &list_countp, &context, &result);

            if (err->rc != LDAP_SUCCESS) {
                err->msg = ldap_err2string(err->rc);
                err->reason = "LDAP: ldap_parse_vlvresponse_control failed";
                return apr_ldap_status(err->rc);
            }

            c->type = APR_LDAP_CONTROL_VLV_RESPONSE;

            c->c.vlvrs.offset = (apr_size_t)target_posp;
            c->c.vlvrs.count = (apr_size_t)list_countp;

            if (context) {
                apr_buffer_mem_set(&c->c.vlvrs.context, context->bv_val, context->bv_len);

                apr_pool_cleanup_register(pool, context, ldap_berval_cleanup,
                                          apr_pool_cleanup_null);

            }
            else {
                apr_buffer_mem_set(&c->c.vlvrs.context, NULL, 0);
            }

            c->c.vlvrs.result = apr_ldap_status(result);

            apr_hash_set(cs, ctl->ldctl_oid, APR_HASH_KEY_STRING, c);

            continue;
        }

#endif

        /* not recognised, return raw value */
        c->type = APR_LDAP_CONTROL_OID;

        c->oid.oid = (const char *)ctl->ldctl_oid;

        apr_buffer_mem_set(&c->oid.val, ctl->ldctl_value.bv_val,
                           ctl->ldctl_value.bv_len);

        apr_hash_set(cs, ctl->ldctl_oid, APR_HASH_KEY_STRING, c);

    }

    *controls = cs;

    return APR_SUCCESS;
}