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