static apr_status_t apr_ldap_control_create()

in ldap/apr_ldap.c [1488:1682]


static apr_status_t apr_ldap_control_create(apr_pool_t *pool,
                                            apr_ldap_t *ldap,
                                            LDAPControl ***ctrls,
                                            apr_array_header_t *controls,
                                            apu_err_t *err)
{
    LDAPControl **cs;

    int i, count;

    if (!controls || !(count = controls->nelts)) {
        *ctrls = NULL;
        return APR_SUCCESS;
    }

    cs = apr_pcalloc(pool, (count + 1) * sizeof(LDAPControl *));

    for (i = 0; i < count; ++i) {

        apr_ldap_control_t *control = &APR_ARRAY_IDX(controls, i, apr_ldap_control_t);

        /* what controls do we recognise? */
        switch (control->type) {

        /* page control */
        case APR_LDAP_CONTROL_PAGE_REQUEST: {
#if APR_HAS_OPENLDAP_LDAPSDK

            LDAPControl *c;

            ber_int_t pagesize = control->c.pagerq.size;
            struct berval cookie;

            cookie.bv_val = apr_buffer_str(&control->c.pagerq.cookie);
            cookie.bv_len = TO_BV_LEN(apr_buffer_len(&control->c.pagerq.cookie));

            err->rc = ldap_create_page_control(ldap->ld, pagesize, &cookie, control->critical ? 1 : 0, &c);

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

            apr_pool_cleanup_register(pool, c, ldap_control_cleanup,
                                      apr_pool_cleanup_null);

            cs[i] = c;

            break;
#else
            err->reason = "LDAP: page control not supported";
            return APR_ENOTIMPL;
#endif
        }

        /* sort control */
        case APR_LDAP_CONTROL_SORT_REQUEST: {
#if APR_HAS_OPENLDAP_LDAPSDK

            LDAPControl *c;
            LDAPSortKey **sks;

            apr_array_header_t *keys = control->c.sortrq.keys;

            int j;

            if (!keys || !keys->nelts) {
                err->reason = "LDAP: no sort control keys specified";
                return APR_EINVAL;
            }

            sks = apr_pcalloc(pool, (keys->nelts + 1) * sizeof(LDAPSortKey *));

            for (j = 0; j < keys->nelts; ++j) {

                apr_ldap_control_sortkey_t *sortkey = &APR_ARRAY_IDX(keys, j, apr_ldap_control_sortkey_t);

                LDAPSortKey *sk = apr_pcalloc(pool, sizeof(LDAPSortKey));

                sk->attributeType = (char *)sortkey->attribute;
                sk->orderingRule = (char *)sortkey->order;
                sk->reverseOrder = sortkey->direction == APR_LDAP_CONTROL_SORT_REVERSE ? 1 : 0;

                sks[j] = sk;
            }

            err->rc = ldap_create_sort_control(ldap->ld, sks, control->critical ? 1 : 0, &c);

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

            apr_pool_cleanup_register(pool, c, ldap_control_cleanup,
                                      apr_pool_cleanup_null);

            cs[i] = c;

            break;
#else
            err->reason = "LDAP: sort control not supported";
            return APR_ENOTIMPL;
#endif
        }

        /* vlv control */
        case APR_LDAP_CONTROL_VLV_REQUEST: {
#if APR_HAS_OPENLDAP_LDAPSDK

            LDAPControl *c;
            LDAPVLVInfo vlvInfo;
            struct berval attrvalue;
            struct berval context;

            vlvInfo.ldvlv_before_count = control->c.vlvrq.before;
            vlvInfo.ldvlv_after_count = control->c.vlvrq.after;
            vlvInfo.ldvlv_offset = control->c.vlvrq.offset;
            vlvInfo.ldvlv_count = control->c.vlvrq.count;

            if (apr_buffer_is_null(&control->c.vlvrq.attrvalue)) {
                vlvInfo.ldvlv_attrvalue = NULL;
            }
            else {
                attrvalue.bv_val = (char *)apr_buffer_mem(&control->c.vlvrq.attrvalue, NULL);
                attrvalue.bv_len = TO_BV_LEN(apr_buffer_len(&control->c.vlvrq.attrvalue));
                vlvInfo.ldvlv_attrvalue = &attrvalue;
            }

            if (apr_buffer_is_null(&control->c.vlvrq.context)) {
                vlvInfo.ldvlv_context = NULL;
            }
            else {
                context.bv_val = (char *)apr_buffer_mem(&control->c.vlvrq.context, NULL);
                context.bv_len = TO_BV_LEN(apr_buffer_len(&control->c.vlvrq.context));
                vlvInfo.ldvlv_context = &context;
            }

            vlvInfo.ldvlv_extradata = NULL;
            vlvInfo.ldvlv_version = 1;

            err->rc = ldap_create_vlv_control(ldap->ld, &vlvInfo, &c);

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

            apr_pool_cleanup_register(pool, c, ldap_control_cleanup,
                                      apr_pool_cleanup_null);

            cs[i] = c;

            break;
#else
            err->reason = "LDAP: vlv control not supported";
            return APR_ENOTIMPL;
#endif
        }

        /* not recognised, return raw value */
        case APR_LDAP_CONTROL_OID: {

            apr_size_t size;

            LDAPControl *c = apr_pcalloc(pool, count * sizeof(LDAPControl));

            if (!control->oid.oid) {
                err->msg = NULL;
                err->reason = "LDAP: control oid missing";
                return APR_EINVAL;
            }

            c->ldctl_oid = (char *)control->oid.oid;
            c->ldctl_value.bv_val = apr_buffer_mem(&control->oid.val, &size);
            c->ldctl_value.bv_len = TO_BV_LEN(size);
            c->ldctl_iscritical = control->critical ? 1 : 0;

            cs[i] = c;

            break;
        }
        default:
            err->reason = "LDAP: control not recognised";
            return APR_EINVAL;
        }

    }

    *ctrls = (LDAPControl **)cs;

    return APR_SUCCESS;
}