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;
}