svn commit: r1924295 [2/3] - in /apr/apr/trunk: ./ build/ include/ include/private/ ldap/ misc/unix/ test/
[email protected] Tue, 11 Mar 2025 13:27:43 -0000
Newsgroups
gmane.comp.apache.apr.cvs
Message-ID
<[email protected] >
Modified: apr/apr/trunk/ldap/apr_ldap.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/ldap/apr_ldap.c?rev=1924295&r1=1924294&r2=1924295&view=diff
==============================================================================
--- apr/apr/trunk/ldap/apr_ldap.c (original)
+++ apr/apr/trunk/ldap/apr_ldap.c Tue Mar 11 13:27:42 2025
@@ -33,6 +33,7 @@
#include "apr_cstr.h"
#include "apr_strings.h"
#include "apr_escape.h"
+#include "apr_hash.h"
#define APR_WANT_MEMFUNC
#include "apr_want.h"
@@ -50,16 +51,142 @@
#include <assert.h>
+/* Older APIs don't define this from RFC4520 */
+#ifndef LDAP_MOD_INCREMENT
+#define LDAP_MOD_INCREMENT 3
+#endif
+
+/* Older APIs use LDAP_RES_MODRDN instead of LDAP_RES_RENAME */
+#ifndef LDAP_RES_RENAME
+#define LDAP_RES_RENAME LDAP_RES_MODRDN
+#endif
+
+/* Older APIs use LDAP_RES_REFERRAL instead of LDAP_RES_SEARCH_REFERENCE */
+#ifndef LDAP_RES_SEARCH_REFERENCE
+#define LDAP_RES_SEARCH_REFERENCE LDAP_RES_REFERRAL
+#endif
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+#define MSGID_T ULONG
+#define TO_BV_LEN(a) (ULONG)(a)
+#else
+#define MSGID_T int
+#define TO_BV_LEN(a) (a)
+#endif
+
+typedef struct apr_ldap_t {
+ apr_pool_t *pool;
+#if !APR_HAS_OPENLDAP_LDAPSDK
+ const char *uri;
+#endif
+ LDAP *ld;
+ apr_socket_t *socket;
+ apr_skiplist *results;
+ apr_array_header_t *abandons;
+ apr_array_header_t *prepares;
+ LDAPControl **serverctrls;
+ LDAPControl **clientctrls;
+ apu_err_t err;
+ apr_status_t status;
+} apr_ldap_t;
+
+
+typedef struct apr_ldap_prepare_t {
+ apr_pool_t *pool;
+ apr_ldap_prepare_cb cb;
+ void *ctx;
+} apr_ldap_prepare_t;
+
+
+typedef struct apr_ldap_result_t {
+ apr_pool_t *pool;
+ apr_ldap_t *ld;
+ const char *mech;
+ const char *rmech;
+ LDAPMessage *message;
+ MSGID_T msgid;
+ int msgtype;
+ union {
+ apr_ldap_bind_cb bind;
+ apr_ldap_compare_cb compare;
+ apr_ldap_search_result_cb search;
+ apr_ldap_add_cb add;
+ apr_ldap_modify_cb modify;
+ apr_ldap_rename_cb rename;
+ apr_ldap_delete_cb delete;
+ apr_ldap_extended_cb ext;
+ } cb;
+ union {
+ apr_ldap_search_entry_cb search;
+ } entry_cb;
+ void *ctx;
+ apr_size_t nentries;
+} apr_ldap_result_t;
+
-APU_DECLARE_LDAP(apr_status_t) apr_ldap_status(int rc, apr_status_t status)
+static apr_status_t apr_ldap_status(int rc)
{
+ if (LDAP_SUCCESS == rc) {
+ return APR_SUCCESS;
+ }
+
switch (rc) {
case LDAP_SUCCESS:
return APR_SUCCESS;
+ case LDAP_LOCAL_ERROR:
+ return APR_LOCAL_ERROR;
+
+ case LDAP_ENCODING_ERROR:
+ return APR_ENCODING_ERROR;
+
+ case LDAP_DECODING_ERROR:
+ return APR_DECODING_ERROR;
+
case LDAP_TIMEOUT:
- return APR_ETIMEDOUT;
+ return APR_TIMEOUT;
+
+ case LDAP_AUTH_UNKNOWN:
+ return APR_AUTH_UNKNOWN;
+
+ case LDAP_FILTER_ERROR:
+ return APR_FILTER_ERROR;
+
+ case LDAP_USER_CANCELLED:
+ return APR_USER_CANCELLED;
+
+ case LDAP_PARAM_ERROR:
+ return APR_PARAM_ERROR;
+
+ case LDAP_NO_MEMORY:
+ return APR_NO_MEMORY;
+
+ case LDAP_CONNECT_ERROR:
+ return APR_CONNECT_ERROR;
+
+ case LDAP_NOT_SUPPORTED:
+ return APR_NOT_SUPPORTED;
+
+ case LDAP_CONTROL_NOT_FOUND:
+ return APR_CONTROL_NOT_FOUND;
+
+ case LDAP_NO_RESULTS_RETURNED:
+ return APR_NO_RESULTS_RETURNED;
+
+ case LDAP_MORE_RESULTS_TO_RETURN:
+ return APR_MORE_RESULTS_TO_RETURN;
+
+ case LDAP_CLIENT_LOOP:
+ return APR_CLIENT_LOOP;
+
+ case LDAP_REFERRAL_LIMIT_EXCEEDED:
+ return APR_REFERRAL_LIMIT_EXCEEDED;
+
+#ifdef LDAP_X_CONNECTING
+ case LDAP_X_CONNECTING:
+ return APR_CONNECTING;
+#endif
#if defined(LDAP_SERVER_DOWN)
case LDAP_SERVER_DOWN:
@@ -68,29 +195,30 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
#if defined(LDAP_UNAVAILABLE)
case LDAP_UNAVAILABLE:
- return APR_SERVER_DOWN;
+ return APR_UNAVAILABLE;
#endif
- case LDAP_AUTH_UNKNOWN:
- return APR_AUTH_UNKNOWN;
-
#ifdef LDAP_X_PROXY_AUTHZ_FAILURE
case LDAP_X_PROXY_AUTHZ_FAILURE:
return APR_PROXY_AUTH;
-
#endif
+
case LDAP_INAPPROPRIATE_AUTH:
return APR_INAPPROPRIATE_AUTH;
case LDAP_INVALID_CREDENTIALS:
return APR_INVALID_CREDENTIALS;
+#ifdef LDAP_INSUFFICIENT_ACCESS
+ /* openldap */
case LDAP_INSUFFICIENT_ACCESS:
return APR_INSUFFICIENT_ACCESS;
+#endif
#ifdef LDAP_INSUFFICIENT_RIGHTS
+ /* microsoftsdk */
case LDAP_INSUFFICIENT_RIGHTS:
- return APR_INSUFFICIENT_RIGHTS;
+ return APR_INSUFFICIENT_ACCESS;
#endif
#ifdef LDAP_CONSTRAINT_VIOLATION
@@ -98,8 +226,10 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
return APR_CONSTRAINT_VIOLATION;
#endif
- case LDAP_NO_RESULTS_RETURNED:
- return APR_NO_RESULTS_RETURNED;
+#ifdef LDAP_OBJECT_CLASS_VIOLATION
+ case LDAP_OBJECT_CLASS_VIOLATION:
+ return APR_OBJECT_CLASS_VIOLATION;
+#endif
case LDAP_COMPARE_TRUE:
return APR_COMPARE_TRUE;
@@ -107,16 +237,29 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
case LDAP_COMPARE_FALSE:
return APR_COMPARE_FALSE;
+ case LDAP_NO_SUCH_OBJECT:
+ return APR_NO_SUCH_OBJECT;
+
+ case LDAP_NO_SUCH_ATTRIBUTE:
+ return APR_NO_SUCH_ATTRIBUTE;
+
+ case LDAP_ALREADY_EXISTS:
+ return APR_ALREADY_EXISTS;
+
case LDAP_OPERATIONS_ERROR:
+ return APR_OPERATIONS_ERROR;
+
case LDAP_PROTOCOL_ERROR:
+ return APR_PROTOCOL_ERROR;
+
case LDAP_TIMELIMIT_EXCEEDED:
- case LDAP_SIZELIMIT_EXCEEDED:
+ return APR_TIMELIMIT_EXCEEDED;
- case LDAP_OTHER:
- return APR_EGENERAL;
+ case LDAP_SIZELIMIT_EXCEEDED:
+ return APR_SIZELIMIT_EXCEEDED;
default:
- return status;
+ return APR_UTIL_START_STATUS + 200 + rc;
}
}
@@ -157,7 +300,7 @@ static apr_status_t prepare_cleanup(void
return APR_SUCCESS;
}
-static apr_status_t ldap_cleanup(void *dptr)
+static apr_status_t apr_ldap_cleanup(void *dptr)
{
if (dptr) {
@@ -193,8 +336,8 @@ static apr_status_t ldap_cleanup(void *d
static int result_comp(void *a, void *b)
{
- int m1 = ((apr_ldap_result_t *)a)->msgid;
- int m2 = ((apr_ldap_result_t *)b)->msgid;
+ MSGID_T m1 = ((apr_ldap_result_t *)a)->msgid;
+ MSGID_T m2 = ((apr_ldap_result_t *)b)->msgid;
return (m1 == m2) ? 0 : ((m1 < m2) ? -1 : 1);
}
@@ -215,10 +358,10 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
apr_skiplist_init(&(*ldap)->results, pool);
apr_skiplist_set_compare((*ldap)->results, result_comp, result_comp);
- (*ldap)->abandons = apr_array_make(pool, 1, sizeof(int));
+ (*ldap)->abandons = apr_array_make(pool, 1, sizeof(MSGID_T));
(*ldap)->prepares = apr_array_make(pool, 1, sizeof(apr_ldap_prepare_t));
- apr_pool_cleanup_register(pool, (*ldap), ldap_cleanup,
+ apr_pool_cleanup_register(pool, (*ldap), apr_ldap_cleanup,
apr_pool_cleanup_null);
return APR_SUCCESS;
@@ -244,6 +387,7 @@ static apr_status_t option_set_uri(apr_l
{
apr_ldap_url_desc_t *urld;
+ apu_err_t *result;
apr_status_t status;
int secure;
@@ -260,6 +404,8 @@ static apr_status_t option_set_uri(apr_l
ld = ldap_init((char *)urld->lud_host, urld->lud_port);
#endif
+ ldap->uri = apr_pstrdup(ldap->pool, uri);
+
}
#endif
@@ -677,13 +823,22 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
status = apr_os_sock_put(&ldap->socket, &sock, ldap->pool);
}
else {
- status = apr_ldap_status(rc, APR_EGENERAL);
+ status = apr_ldap_status(rc);
}
}
outvalue->socket = ldap->socket;
return status;
}
+ case APR_LDAP_OPT_URI: {
+#if APR_HAS_OPENLDAP_LDAPSDK
+ rc = ldap_get_option(ldap ? ldap->ld : NULL, option, &outvalue->opt);
+ break;
+#else
+ outvalue->uri = ldap->uri;
+ return APR_SUCCESS;
+#endif
+ }
case APR_LDAP_OPT_DEBUG_LEVEL: {
#if defined(LDAP_OPT_DEBUG_LEVEL)
@@ -852,11 +1007,11 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
/* windows allows the socket to be set here */
rc = LDAP_UNWILLING_TO_PERFORM;
- break;
+ goto end;
case APR_LDAP_OPT_URI:
rc = option_set_uri(ldap, invalue->uri, result);
- break;
+ goto end;
default:
break;
@@ -1025,7 +1180,13 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
rc = ldap_set_option(ldap ? ldap->ld : NULL, option, invalue->opt);
}
+end:
+
+#if defined (LDAP_OPT_SUCCESS)
if (rc != LDAP_OPT_SUCCESS) {
+#else
+ if (rc != LDAP_SUCCESS) {
+#endif
result->rc = rc;
if (!result->msg) {
@@ -1050,10 +1211,11 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
apr_interval_time_t timeout,
apu_err_t *err)
{
+#if APR_HAVE_LDAP_CONNECT
LDAP *ld = ldap->ld;
#if APR_HAS_MICROSOFT_LDAPSDK
- struct timeval tv, *tvptr;
+ LDAP_TIMEVAL tv, *tvptr;
if (timeout < 0) {
tvptr = NULL;
@@ -1097,13 +1259,16 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
if (err->rc != LDAP_SUCCESS) {
err->msg = ldap_err2string(err->rc);
err->reason = "LDAP: ldap_connect() failed";
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
else {
memset(err, 0, sizeof(*err));
}
return APR_SUCCESS;
+#else
+ return APR_ENOTIMPL;
+#endif
}
@@ -1134,6 +1299,392 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
+static apr_status_t ldap_control_cleanup(void *dptr)
+{
+ if (dptr) {
+
+ LDAPControl *ctl = dptr;
+
+ ldap_control_free(ctl);
+ }
+
+ return APR_SUCCESS;
+}
+
+#if APR_HAS_OPENLDAP_LDAPSDK
+static apr_status_t ldap_berval_cleanup(void *dptr)
+{
+ if (dptr) {
+
+ struct berval *val = dptr;
+
+ ber_bvfree(val);
+ }
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t ldap_memfree_cleanup(void *dptr)
+{
+ if (dptr) {
+ ldap_memfree(dptr);
+ }
+
+ return APR_SUCCESS;
+}
+#endif
+
+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;
+}
+
+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;
+}
+
+
/*
@@ -1192,10 +1743,10 @@ static apr_status_t results_cleanup(void
}
-APU_DECLARE_LDAP(void) apr_ldap_result_add(apr_pool_t *pool,
- apr_ldap_t *ldap,
- apr_ldap_result_t *res,
- int msgid)
+static void apr_ldap_result_add(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ apr_ldap_result_t *res,
+ MSGID_T msgid)
{
res->pool = pool;
res->ld = ldap;
@@ -1207,8 +1758,8 @@ APU_DECLARE_LDAP(void) apr_ldap_result_a
apr_skiplist_add(ldap->results, res);
}
-APU_DECLARE_LDAP(void) apr_ldap_result_remove(apr_ldap_t *ldap,
- apr_ldap_result_t *res)
+static void apr_ldap_result_remove(apr_ldap_t *ldap,
+ apr_ldap_result_t *res)
{
apr_pool_cleanup_run(res->pool, res, result_cleanup);
}
@@ -1225,7 +1776,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
apr_status_t status = APR_SUCCESS;
- int msgid = 0;
+ MSGID_T msgid = 0;
/* do we have a prepare callback outstanding? */
@@ -1247,7 +1798,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
if (ldap->abandons->nelts) {
- int *msgid = apr_array_pop(ldap->abandons);
+ MSGID_T *msgid = apr_array_pop(ldap->abandons);
#if APR_HAS_OPENLDAP_LDAPSDK
err->rc = ldap_abandon_ext(ldap->ld, *msgid, NULL, NULL);
@@ -1269,7 +1820,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
else {
err->reason = "LDAP: ldap_abandon_ext() failed";
err->msg = ldap_err2string(err->rc);
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
}
@@ -1289,6 +1840,8 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
switch(res->msgtype) {
case LDAP_RES_BIND: {
+#if APR_HAS_OPENLDAP_LDAPSDK && APR_HAVE_LDAP_SASL_INTERACTIVE_BIND
+
/* handle binding */
LDAPControl *sctrls[] = { 0 };
@@ -1319,17 +1872,29 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
/* we got a response, send the news, good or bad */
if (res->cb.bind) {
- status = res->cb.bind(ldap, apr_ldap_status(err->rc, APR_EGENERAL),
+ status = res->cb.bind(ldap, apr_ldap_status(err->rc),
NULL, NULL, res->ctx, err);
}
else {
- status = apr_ldap_status(err->rc, APR_EGENERAL);
+ status = apr_ldap_status(err->rc);
}
apr_ldap_result_remove(ldap, res);
}
break;
+#else
+
+ /*
+ * for platforms that do not support ldap_sasl_interactive_bind(), alternative
+ * implementations using ldap_sasl_bind() go here.
+ */
+
+ err->reason = "LDAP: SASL bind not yet supported by APR on this "
+ "LDAP SDK";
+ err->rc = LDAP_UNWILLING_TO_PERFORM;
+ return APR_ENOTIMPL;
+#endif
}
case LDAP_RES_COMPARE: {
@@ -1348,12 +1913,12 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
err->reason = "LDAP compare: ldap_parse_result()";
if (res->cb.compare) {
- status = res->cb.compare(ldap, apr_ldap_status(err->rc, APR_EGENERAL),
+ status = res->cb.compare(ldap, apr_ldap_status(err->rc),
matcheddn, (apr_ldap_control_t **)serverctrls,
res->ctx, err);
}
else {
- status = apr_ldap_status(err->rc, APR_EGENERAL);
+ status = apr_ldap_status(err->rc);
}
@@ -1380,24 +1945,195 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
char *matcheddn = NULL;
char *errmsg = NULL;
LDAPControl **serverctrls = NULL;
+ apr_hash_t *controls = NULL;
int rc;
err->rc = ldap_parse_result(ldap->ld, res->message, &rc, &matcheddn,
&errmsg, NULL, &serverctrls, 0);
+ status = apr_ldap_control_parse(res->pool, ldap, serverctrls, &controls, err);
+
+ if (APR_SUCCESS == status) {
+ err->rc = rc != LDAP_SUCCESS ? rc : err->rc;
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP search: ldap_parse_result()";
+ status = apr_ldap_status(err->rc);
+ }
+
+ if (res->cb.search) {
+ status = res->cb.search(ldap, status, 0,
+ matcheddn, controls,
+ res->ctx, err);
+ }
+
+ apr_ldap_result_remove(ldap, res);
+
+ if (matcheddn) {
+ ldap_memfree(matcheddn);
+ }
+
+ if (errmsg) {
+ ldap_memfree(errmsg);
+ }
+
+ if (serverctrls) {
+ ldap_controls_free(serverctrls);
+ }
+
+ break;
+ }
+ case LDAP_RES_ADD: {
+
+ /* handle adding */
+
+ char *matcheddn = NULL;
+ char *errmsg = NULL;
+ LDAPControl **serverctrls = NULL;
+ int rc;
+
+ err->rc = ldap_parse_result(ldap->ld, res->message, &rc, &matcheddn, &errmsg,
+ NULL, &serverctrls, 0);
+
err->rc = rc != LDAP_SUCCESS ? rc : err->rc;
err->msg = ldap_err2string(err->rc);
- err->reason = "LDAP search: ldap_parse_result()";
+ err->reason = "LDAP add: ldap_parse_result()";
- if (res->cb.search) {
- status = res->cb.search(ldap, apr_ldap_status(err->rc, APR_EGENERAL), 0,
+ if (res->cb.add) {
+ status = res->cb.add(ldap, apr_ldap_status(err->rc),
+ matcheddn, (apr_ldap_control_t **)serverctrls,
+ res->ctx, err);
+ }
+ else {
+ status = apr_ldap_status(err->rc);
+ }
+
+
+ apr_ldap_result_remove(ldap, res);
+
+ if (matcheddn) {
+ ldap_memfree(matcheddn);
+ }
+
+ if (errmsg) {
+ ldap_memfree(errmsg);
+ }
+
+ if (serverctrls) {
+ ldap_controls_free(serverctrls);
+ }
+
+ break;
+ }
+ case LDAP_RES_MODIFY: {
+
+ /* handle modification */
+
+ char *matcheddn = NULL;
+ char *errmsg = NULL;
+ LDAPControl **serverctrls = NULL;
+ int rc;
+
+ err->rc = ldap_parse_result(ldap->ld, res->message, &rc, &matcheddn, &errmsg,
+ NULL, &serverctrls, 0);
+
+ err->rc = rc != LDAP_SUCCESS ? rc : err->rc;
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP modify: ldap_parse_result()";
+
+ if (res->cb.modify) {
+ status = res->cb.modify(ldap, apr_ldap_status(err->rc),
+ matcheddn, (apr_ldap_control_t **)serverctrls,
+ res->ctx, err);
+ }
+ else {
+ status = apr_ldap_status(err->rc);
+ }
+
+
+ apr_ldap_result_remove(ldap, res);
+
+ if (matcheddn) {
+ ldap_memfree(matcheddn);
+ }
+
+ if (errmsg) {
+ ldap_memfree(errmsg);
+ }
+
+ if (serverctrls) {
+ ldap_controls_free(serverctrls);
+ }
+
+ break;
+ }
+ case LDAP_RES_RENAME: {
+
+ /* handle rename */
+
+ char *matcheddn = NULL;
+ char *errmsg = NULL;
+ LDAPControl **serverctrls = NULL;
+ int rc;
+
+ err->rc = ldap_parse_result(ldap->ld, res->message, &rc, &matcheddn, &errmsg,
+ NULL, &serverctrls, 0);
+
+ err->rc = rc != LDAP_SUCCESS ? rc : err->rc;
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP rename: ldap_parse_result()";
+
+ if (res->cb.rename) {
+ status = res->cb.rename(ldap, apr_ldap_status(err->rc),
+ matcheddn, (apr_ldap_control_t **)serverctrls,
+ res->ctx, err);
+ }
+ else {
+ status = apr_ldap_status(err->rc);
+ }
+
+
+ apr_ldap_result_remove(ldap, res);
+
+ if (matcheddn) {
+ ldap_memfree(matcheddn);
+ }
+
+ if (errmsg) {
+ ldap_memfree(errmsg);
+ }
+
+ if (serverctrls) {
+ ldap_controls_free(serverctrls);
+ }
+
+ break;
+ }
+ case LDAP_RES_DELETE: {
+
+ /* handle delete */
+
+ char *matcheddn = NULL;
+ char *errmsg = NULL;
+ LDAPControl **serverctrls = NULL;
+ int rc;
+
+ err->rc = ldap_parse_result(ldap->ld, res->message, &rc, &matcheddn, &errmsg,
+ NULL, &serverctrls, 0);
+
+ err->rc = rc != LDAP_SUCCESS ? rc : err->rc;
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP delete: ldap_parse_result()";
+
+ if (res->cb.delete) {
+ status = res->cb.delete(ldap, apr_ldap_status(err->rc),
matcheddn, (apr_ldap_control_t **)serverctrls,
res->ctx, err);
}
else {
- status = apr_ldap_status(err->rc, APR_EGENERAL);
+ status = apr_ldap_status(err->rc);
}
+
apr_ldap_result_remove(ldap, res);
if (matcheddn) {
@@ -1414,6 +2150,38 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
break;
}
+ case LDAP_RES_EXTENDED: {
+
+ /* handle extended operation */
+
+ char *roid = NULL;
+ struct berval *rd = NULL;
+ apr_buffer_t rdata;
+
+ err->rc = ldap_parse_extended_result(ldap->ld, res->message, &roid,
+ &rd, 0);
+
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP extended operation: ldap_parse_result()";
+
+ if (rd) {
+ apr_buffer_mem_set(&rdata, rd->bv_val, rd->bv_len);
+ }
+
+ if (res->cb.ext) {
+ status = res->cb.ext(ldap, apr_ldap_status(err->rc),
+ roid, &rdata,
+ res->ctx, err);
+ }
+ else {
+ status = apr_ldap_status(err->rc);
+ }
+
+
+ apr_ldap_result_remove(ldap, res);
+
+ break;
+ }
default:
break;
}
@@ -1444,7 +2212,11 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
apr_status_t status = APR_SUCCESS;
+#if APR_HAS_MICROSOFT_LDAPSDK
+ LDAP_TIMEVAL tv, *tvptr;
+#else
struct timeval tv, *tvptr;
+#endif
if (timeout < 0) {
tvptr = NULL;
@@ -1469,7 +2241,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
#endif
err->msg = ldap_err2string(err->rc);
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
else if (err->rc == 0) {
err->reason = "LDAP: ldap_result() timed out";
@@ -1519,23 +2291,6 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
return APR_WANT_WRITE;
}
- case LDAP_RES_COMPARE: {
-
- /*
- * Set the result aside for callbacks to be fired when our LDAP socket
- * is next writable. This means that we can safely write the next LDAP
- * request in the callback without messing about.
- */
-
- if (res->message) {
- /* two unprocessed bind messages would be weird, but don't leak */
- ldap_msgfree(res->message);
- }
-
- res->message = msg;
-
- return APR_WANT_WRITE;
- }
case LDAP_RES_SEARCH_ENTRY: {
/*
@@ -1550,7 +2305,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
char *attr;
BerElement *ber;
- int nattrs = 0, j = 0;
+ apr_ldap_search_entry_t e = { 0 };
entry = ldap_first_entry(ldap->ld, msg);
@@ -1559,7 +2314,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
for (attr = ldap_first_attribute(ldap->ld, entry, &ber);
attr != NULL;
attr = ldap_next_attribute(ldap->ld, entry, ber)) {
- nattrs++;
+ e.nattrs++;
}
for (attr = ldap_first_attribute(ldap->ld, entry, &ber);
@@ -1568,9 +2323,11 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
struct berval **vals = ldap_get_values_len(ldap->ld, entry, attr);
+ e.attr = attr;
+
if (vals) {
- int k, nvals, binary = 0;
+ int binary = 0;
char *sc = attr;
@@ -1582,27 +2339,28 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
}
}
- nvals = ldap_count_values_len(vals);
+ e.nvals = ldap_count_values_len(vals);
- for (k = 0; k < nvals; k++) {
+ for (e.vidx = 0; e.vidx < e.nvals; e.vidx++) {
- apr_buffer_t buf;
char *str = NULL;
if (binary) {
- apr_buffer_mem_set(&buf, vals[k]->bv_val, vals[k]->bv_len);
+ apr_buffer_mem_set(&e.val, vals[e.vidx]->bv_val, vals[e.vidx]->bv_len);
}
else {
- str = strndup(vals[k]->bv_val, vals[k]->bv_len);
- apr_buffer_str_set(&buf, str, vals[k]->bv_len);
+ str = malloc(vals[e.vidx]->bv_len + 1);
+ str[vals[e.vidx]->bv_len] = 0;
+ memcpy(str, vals[e.vidx]->bv_val, vals[e.vidx]->bv_len);
+ apr_buffer_str_set(&e.val, str, vals[e.vidx]->bv_len);
}
if (res->entry_cb.search) {
- status = res->entry_cb.search(ldap, dn, res->nentries, nattrs, j,
- attr, nvals, k, &buf, 0, res->ctx, err);
+ status = res->entry_cb.search(ldap, dn, res->nentries, &e,
+ res->ctx, err);
}
else {
- status = apr_ldap_status(err->rc, APR_EGENERAL);
+ status = apr_ldap_status(err->rc);
}
if (str) {
@@ -1613,11 +2371,11 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
}
else {
if (res->entry_cb.search) {
- status = res->entry_cb.search(ldap, dn, res->nentries, nattrs, j,
- attr, 0, 0, NULL, 0, res->ctx, err);
+ status = res->entry_cb.search(ldap, dn, res->nentries, &e,
+ res->ctx, err);
}
else {
- status = apr_ldap_status(err->rc, APR_EGENERAL);
+ status = apr_ldap_status(err->rc);
}
}
@@ -1628,17 +2386,16 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
break;
}
- j++;
+ e.aidx++;
}
res->nentries++;
if (res->entry_cb.search) {
- status = res->entry_cb.search(ldap, dn, res->nentries, 0, 0, NULL,
- 0, 0, NULL, 0, res->ctx, err);
+ status = res->entry_cb.search(ldap, dn, res->nentries, NULL, res->ctx, err);
}
else {
- status = apr_ldap_status(err->rc, APR_EGENERAL);
+ status = apr_ldap_status(err->rc);
}
ldap_memfree((void *)dn);
@@ -1649,7 +2406,13 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
break;
}
- case LDAP_RES_SEARCH_RESULT: {
+ case LDAP_RES_SEARCH_RESULT:
+ case LDAP_RES_COMPARE:
+ case LDAP_RES_ADD:
+ case LDAP_RES_MODIFY:
+ case LDAP_RES_RENAME:
+ case LDAP_RES_DELETE:
+ case LDAP_RES_EXTENDED: {
/*
* Set the result aside for callbacks to be fired when our LDAP socket
@@ -1658,7 +2421,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
*/
if (res->message) {
- /* two unprocessed bind messages would be weird, but don't leak */
+ /* two unprocessed messages would be weird, but don't leak */
ldap_msgfree(res->message);
}
@@ -1677,7 +2440,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
/* we are no longer interested in this message - a pool was cleaned up */
- int *msgid = apr_array_push(ldap->abandons);
+ MSGID_T *msgid = apr_array_push(ldap->abandons);
*msgid = find.msgid;
ldap_msgfree(msg);
@@ -1803,13 +2566,6 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
}
-
-#if APR_HAS_OPENLDAP_LDAPSDK && APR_HAVE_LDAP_SASL_INTERACTIVE_BIND
-
-#if !defined(HAVE_SASL_H) && !defined(HAVE_SASL_SASL_H)
-#error OpenLDAP was built with SASL support, but the SASL headers are not installed as required.
-#endif
-
typedef struct apr_ldap_bind_ctx_t {
apr_ldap_t *ld;
apr_ldap_bind_interact_cb *interact;
@@ -1817,6 +2573,12 @@ typedef struct apr_ldap_bind_ctx_t {
apr_status_t status;
} apr_ldap_bind_ctx_t;
+#if APR_HAS_OPENLDAP_LDAPSDK && APR_HAVE_LDAP_SASL_INTERACTIVE_BIND
+
+#if !defined(HAVE_SASL_H) && !defined(HAVE_SASL_SASL_H)
+#error OpenLDAP was built with SASL support, but the SASL headers are not installed as required.
+#endif
+
static int bind_sasl_interact(LDAP *ld, unsigned flags, void *ctx, void *in)
{
apr_ldap_bind_ctx_t *payload = ctx;
@@ -1888,8 +2650,6 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
LDAPControl *sctrls[] = { 0 };
LDAPControl *cctrls[] = { 0 };
- unsigned int flags = LDAP_SASL_QUIET;
-
apr_ldap_bind_ctx_t payload;
payload.ld = ldap;
@@ -1897,7 +2657,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
payload.ctx = interact_ctx;
payload.status = APR_SUCCESS;
- int msgid = 0;
+ MSGID_T msgid = 0;
#ifdef LDAP_OPT_NETWORK_TIMEOUT
{
@@ -1964,7 +2724,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
if (!apr_buffer_is_null(&interaction.result)) {
cred.bv_val = (char *)apr_buffer_mem(&interaction.result, NULL);
- cred.bv_len = apr_buffer_len(&interaction.result);
+ cred.bv_len = TO_BV_LEN(apr_buffer_len(&interaction.result));
} else {
cred.bv_val = "";
cred.bv_len = 0;
@@ -1976,13 +2736,18 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
* password is passed as a buffer to cred.
*/
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_sasl_bind(ldap->ld, (char *)dn, NULL, &cred,
+ NULL, NULL, &msgid);
+#else
err->rc = ldap_sasl_bind(ldap->ld, dn, LDAP_SASL_SIMPLE, &cred,
NULL, NULL, &msgid);
+#endif
if (err->rc != LDAP_SUCCESS) {
err->msg = ldap_err2string(err->rc);
err->reason = "LDAP: ldap_sasl_bind(SIMPLE) failed";
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
else {
memset(err, 0, sizeof(*err));
@@ -2009,6 +2774,8 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
const char *rmech;
+ unsigned int flags = LDAP_SASL_QUIET;
+
/* No distinguished name is a SASL bind */
memset(err, 0, sizeof(*err));
@@ -2046,7 +2813,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
else {
err->msg = ldap_err2string(err->rc);
err->reason = "LDAP: ldap_sasl_interactive_bind() failed";
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
#else
@@ -2066,49 +2833,43 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
}
-APU_DECLARE_LDAP(apr_ldap_control_t *) apr_ldap_control_make(apr_pool_t *pool,
- apr_ldap_t *ldap,
- const char *oid,
- apr_buffer_t *val,
- int iscritical)
-{
- apr_ldap_control_t *ctl;
- LDAPControl *c;
-
- ctl = apr_pcalloc(pool, sizeof(apr_ldap_result_t));
- c = (LDAPControl *)ctl;
-
- if (c) {
- apr_size_t size;
- c->ldctl_oid = (char *)oid;
- c->ldctl_value.bv_val = apr_buffer_mem(val, &size);
- c->ldctl_value.bv_len = size;
- c->ldctl_iscritical = iscritical ? 1 : 0;
- }
-
- return ctl;
-}
-
APU_DECLARE_LDAP(apr_status_t) apr_ldap_compare(apr_pool_t *pool,
apr_ldap_t *ldap,
const char *dn,
const char *attr,
const apr_buffer_t *val,
- apr_ldap_control_t **serverctrls,
- apr_ldap_control_t **clientctrls,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
apr_interval_time_t timeout,
apr_ldap_compare_cb compare_cb, void *compare_ctx,
apu_err_t *err)
{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
apr_ldap_result_t *res;
struct berval bval;
apr_size_t size;
- int msgid = 0;
+ MSGID_T msgid = 0;
+
+ apr_status_t status;
+
+ status = apr_ldap_control_create(pool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(pool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
bval.bv_val = apr_buffer_mem(val, &size);
- bval.bv_len = size;
+ bval.bv_len = TO_BV_LEN(size);
#ifdef LDAP_OPT_NETWORK_TIMEOUT
{
@@ -2122,7 +2883,7 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
tv.tv_usec = (long) apr_time_usec(timeout);
tvptr = &tv;
}
-
+
err->rc = ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, tvptr);
if (err->rc != LDAP_SUCCESS) {
err->msg = ldap_err2string(err->rc);
@@ -2132,13 +2893,18 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
}
#endif
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_compare_ext(ldap->ld, (char *)dn, (char *)attr, NULL, &bval,
+ sctrls, cctrls, &msgid);
+#else
err->rc = ldap_compare_ext(ldap->ld, dn, attr, &bval,
- (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, &msgid);
+ sctrls, cctrls, &msgid);
+#endif
if (err->rc != LDAP_SUCCESS) {
err->msg = ldap_err2string(err->rc);
err->reason = "LDAP: ldap_compare failed";
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
else {
memset(err, 0, sizeof(*err));
@@ -2168,8 +2934,8 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
const char *filter,
const char **attrs,
apr_ldap_switch_e attrsonly,
- apr_ldap_control_t **serverctrls,
- apr_ldap_control_t **clientctrls,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
apr_interval_time_t timeout,
apr_ssize_t sizelimit,
apr_ldap_search_result_cb search_result_cb,
@@ -2177,11 +2943,40 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
void *search_ctx,
apu_err_t *err)
{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
apr_ldap_result_t *res;
+#if APR_HAS_MICROSOFT_LDAPSDK
+ ULONG timelimit;
+#else
struct timeval tv, *tvptr;
+#endif
- int msgid = 0;
+ MSGID_T msgid = 0;
+
+ apr_status_t status;
+
+ status = apr_ldap_control_create(pool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(pool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+
+ timelimit = (ULONG)apr_time_sec(timeout);
+
+ err->rc = ldap_search_ext(ldap->ld, (char *)dn, scope, (char *)filter, (char **)attrs, attrsonly,
+ sctrls, cctrls, timelimit, (ULONG)sizelimit, &msgid);
+#else
if (timeout < 0) {
tvptr = NULL;
@@ -2193,12 +2988,13 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
}
err->rc = ldap_search_ext(ldap->ld, (char *)dn, scope, (char *)filter, (char **)attrs, attrsonly,
- (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, tvptr, sizelimit, &msgid);
+ sctrls, cctrls, tvptr, sizelimit, &msgid);
+#endif
if (err->rc != LDAP_SUCCESS) {
err->msg = ldap_err2string(err->rc);
err->reason = "LDAP: ldap_search failed";
- return apr_ldap_status(err->rc, APR_EGENERAL);
+ return apr_ldap_status(err->rc);
}
else {
memset(err, 0, sizeof(*err));
@@ -2220,16 +3016,627 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
return APR_WANT_READ;
}
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_add(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn,
+ apr_array_header_t *adds,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_add_cb add_cb, void *ctx,
+ apu_err_t *err)
+{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
+ apr_pool_t *tpool;
+
+ apr_ldap_result_t *res;
+
+ LDAPMod **mps, *ms;
+
+ MSGID_T msgid = 0;
+
+ int i, j;
+
+ apr_status_t status;
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ {
+ struct timeval tv, *tvptr;
+
+ if (timeout < 0) {
+ tvptr = NULL;
+ }
+ else {
+ tv.tv_sec = (long) apr_time_sec(timeout);
+ tv.tv_usec = (long) apr_time_usec(timeout);
+ tvptr = &tv;
+ }
+
+ err->rc = ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, tvptr);
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: Could not set network timeout";
+ return APR_EINVAL;
+ }
+ }
+#endif
+
+ /* sanity check - any binary inconsistency? */
+ for (i = 0; i < adds->nelts; ++i) {
+ apr_ldap_pair_t *pair = &APR_ARRAY_IDX(adds, i, apr_ldap_pair_t);
+
+ int is_str = 0;
+
+ /* no adding attributes with no values */
+ if (!pair->vals->nelts) {
+ return APR_EINVAL;
+ }
+
+ /* no adding mixed strings / binary */
+ for (j = 0; j < pair->vals->nelts; ++j) {
+ apr_buffer_t *buf = &APR_ARRAY_IDX(pair->vals, j, apr_buffer_t);
+
+ if (0 == j) {
+ is_str = apr_buffer_is_str(buf);
+ }
+ else if (apr_buffer_is_str(buf) != is_str) {
+ return APR_EINVAL;
+ }
+ }
+ }
+
+ /* all sane, let's translate into the LDAP world */
+ apr_pool_create(&tpool, pool);
+
+ status = apr_ldap_control_create(tpool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(tpool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ mps = apr_pcalloc(tpool, (adds->nelts + 1) * sizeof(LDAPMod *));
+ ms = apr_pcalloc(tpool, (adds->nelts) * sizeof(LDAPMod));
+
+ /* walk our attributes */
+ for (i = 0; i < adds->nelts; ++i) {
+ apr_ldap_pair_t *pair = &APR_ARRAY_IDX(adds, i, apr_ldap_pair_t);
+
+ ms->mod_op = 0; /* entry add, no operation on attributes */
+ ms->mod_type = (char *)pair->attr;
+
+ for (j = 0; j < pair->vals->nelts; ++j) {
+ apr_buffer_t *buf = &APR_ARRAY_IDX(pair->vals, j, apr_buffer_t);
+
+ if (apr_buffer_is_str(buf)) {
+ if (0 == j) {
+ ms->mod_vals.modv_strvals = apr_pcalloc(tpool, (pair->vals->nelts + 1) * sizeof(void *));
+ }
+ ms->mod_vals.modv_strvals[j] = apr_buffer_str(buf);
+ }
+ else {
+ if (0 == j) {
+ ms->mod_op |= LDAP_MOD_BVALUES;
+ ms->mod_vals.modv_bvals = apr_pcalloc(tpool, (pair->vals->nelts + 1) * sizeof(void *));
+ }
+ ms->mod_vals.modv_bvals[j]->bv_val = apr_buffer_mem(buf, NULL);
+ ms->mod_vals.modv_bvals[j]->bv_len = TO_BV_LEN(apr_buffer_len(buf));
+ }
+ }
+
+ mps[i] = ms++;
+ }
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_add_ext(ldap->ld, (char *)dn, mps,
+ sctrls, cctrls, &msgid);
+#else
+ err->rc = ldap_add_ext(ldap->ld, dn, mps,
+ sctrls, cctrls, &msgid);
+#endif
+
+ apr_pool_destroy(tpool);
+
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: ldap_add failed";
+ return apr_ldap_status(err->rc);
+ }
+ else {
+ memset(err, 0, sizeof(*err));
+ }
+
+ res = apr_pcalloc(pool, sizeof(apr_ldap_result_t));
+
+ if (!res) {
+ return APR_ENOMEM;
+ }
+
+ res->msgtype = LDAP_RES_ADD;
+ res->cb.add = add_cb;
+ res->ctx = ctx;
+
+ apr_ldap_result_add(pool, ldap, res, msgid);
+
+ return APR_WANT_READ;
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_modify(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn,
+ apr_array_header_t *mods,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_modify_cb modify_cb, void *ctx,
+ apu_err_t *err)
+{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
+ apr_pool_t *tpool;
+
+ apr_ldap_result_t *res;
+
+ LDAPMod **mps, *ms;
+
+ MSGID_T msgid = 0;
+
+ int i, j;
+
+ apr_status_t status;
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ {
+ struct timeval tv, *tvptr;
+
+ if (timeout < 0) {
+ tvptr = NULL;
+ }
+ else {
+ tv.tv_sec = (long) apr_time_sec(timeout);
+ tv.tv_usec = (long) apr_time_usec(timeout);
+ tvptr = &tv;
+ }
+
+ err->rc = ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, tvptr);
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: Could not set network timeout";
+ return APR_EINVAL;
+ }
+ }
+#endif
+
+ /* sanity check - any binary inconsistency? */
+ for (i = 0; i < mods->nelts; ++i) {
+ apr_ldap_modify_t *mod = &APR_ARRAY_IDX(mods, i, apr_ldap_modify_t);
+
+ int is_str = 0;
+
+ /* non recognised operations */
+ switch (mod->op) {
+ case APR_LDAP_MOD_ADD:
+ case APR_LDAP_MOD_DELETE:
+ case APR_LDAP_MOD_REPLACE:
+ case APR_LDAP_MOD_INCREMENT:
+ break;
+ default:
+ return APR_EINVAL;
+ }
+
+ /* no attribute */
+ if (!mod->pair.attr) {
+ return APR_EINVAL;
+ }
+
+ /* no adding attributes with no values */
+ if (mod->op == APR_LDAP_MOD_ADD && !mod->pair.vals->nelts) {
+ return APR_EINVAL;
+ }
+
+ /* no adding mixed strings / binary */
+ for (j = 0; j < mod->pair.vals->nelts; ++j) {
+ apr_buffer_t *buf = &APR_ARRAY_IDX(mod->pair.vals, j, apr_buffer_t);
+
+ if (0 == j) {
+ is_str = apr_buffer_is_str(buf);
+ }
+ else if (apr_buffer_is_str(buf) != is_str) {
+ return APR_EINVAL;
+ }
+ }
+ }
+
+ /* all sane, let's translate into the LDAP world */
+ apr_pool_create(&tpool, pool);
+
+ status = apr_ldap_control_create(tpool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(tpool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ mps = apr_pcalloc(tpool, (mods->nelts + 1) * sizeof(LDAPMod *));
+ ms = apr_pcalloc(tpool, (mods->nelts) * sizeof(LDAPMod));
+
+ /* walk our attributes */
+ for (i = 0; i < mods->nelts; ++i) {
+ apr_ldap_modify_t *mod = &APR_ARRAY_IDX(mods, i, apr_ldap_modify_t);
+
+ switch (mod->op) {
+ case APR_LDAP_MOD_ADD:
+ ms->mod_op = LDAP_MOD_ADD;
+ break;
+ case APR_LDAP_MOD_DELETE:
+ ms->mod_op = LDAP_MOD_DELETE;
+ break;
+ case APR_LDAP_MOD_REPLACE:
+ ms->mod_op = LDAP_MOD_REPLACE;
+ break;
+ case APR_LDAP_MOD_INCREMENT:
+ ms->mod_op = LDAP_MOD_INCREMENT;
+ break;
+ }
+
+ ms->mod_type = (char *)mod->pair.attr;
+
+ for (j = 0; j < mod->pair.vals->nelts; ++j) {
+ apr_buffer_t *buf = &APR_ARRAY_IDX(mod->pair.vals, j, apr_buffer_t);
+
+ if (apr_buffer_is_str(buf)) {
+ if (0 == j) {
+ ms->mod_vals.modv_strvals = apr_pcalloc(tpool, (mod->pair.vals->nelts + 1) * sizeof(void *));
+ }
+ ms->mod_vals.modv_strvals[j] = apr_buffer_str(buf);
+ }
+ else {
+ if (0 == j) {
+ ms->mod_op |= LDAP_MOD_BVALUES;
+ ms->mod_vals.modv_bvals = apr_pcalloc(tpool, (mod->pair.vals->nelts + 1) * sizeof(void *));
+ }
+ ms->mod_vals.modv_bvals[j]->bv_val = apr_buffer_mem(buf, NULL);
+ ms->mod_vals.modv_bvals[j]->bv_len = TO_BV_LEN(apr_buffer_len(buf));
+ }
+ }
+
+ mps[i] = ms++;
+ }
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_modify_ext(ldap->ld, (char *)dn, mps,
+ sctrls, cctrls, &msgid);
+#else
+ err->rc = ldap_modify_ext(ldap->ld, dn, mps,
+ sctrls, cctrls, &msgid);
+#endif
+
+ apr_pool_destroy(tpool);
+
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: ldap_modify failed";
+ return apr_ldap_status(err->rc);
+ }
+ else {
+ memset(err, 0, sizeof(*err));
+ }
+
+ res = apr_pcalloc(pool, sizeof(apr_ldap_result_t));
+
+ if (!res) {
+ return APR_ENOMEM;
+ }
+
+ res->msgtype = LDAP_RES_MODIFY;
+ res->cb.modify = modify_cb;
+ res->ctx = ctx;
+
+ apr_ldap_result_add(pool, ldap, res, msgid);
+
+ return APR_WANT_READ;
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_rename(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn, const char *newrdn, const char *newparent,
+ apr_ldap_rename_e flags,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_rename_cb rename_cb, void *ctx,
+ apu_err_t *err)
+{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
+ apr_ldap_result_t *res;
+
+ MSGID_T msgid = 0;
+
+ apr_status_t status;
+
+ status = apr_ldap_control_create(pool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(pool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ {
+ struct timeval tv, *tvptr;
+
+ if (timeout < 0) {
+ tvptr = NULL;
+ }
+ else {
+ tv.tv_sec = (long) apr_time_sec(timeout);
+ tv.tv_usec = (long) apr_time_usec(timeout);
+ tvptr = &tv;
+ }
+
+ err->rc = ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, tvptr);
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: Could not set network timeout";
+ return APR_EINVAL;
+ }
+ }
+#endif
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_rename_ext(ldap->ld, (char *)dn, (char *)newrdn, (char *)newparent, flags,
+ sctrls, cctrls, &msgid);
+#else
+ err->rc = ldap_rename(ldap->ld, dn, newrdn, newparent, flags,
+ sctrls, cctrls, &msgid);
+#endif
+
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: ldap_rename failed";
+ return apr_ldap_status(err->rc);
+ }
+ else {
+ memset(err, 0, sizeof(*err));
+ }
+
+ res = apr_pcalloc(pool, sizeof(apr_ldap_result_t));
+
+ if (!res) {
+ return APR_ENOMEM;
+ }
+
+ res->msgtype = LDAP_RES_RENAME;
+ res->cb.rename = rename_cb;
+ res->ctx = ctx;
+
+ apr_ldap_result_add(pool, ldap, res, msgid);
+
+ return APR_WANT_READ;
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_delete(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_delete_cb delete_cb, void *ctx,
+ apu_err_t *err)
+{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
+ apr_ldap_result_t *res;
+
+ MSGID_T msgid = 0;
+
+ apr_status_t status;
+
+ status = apr_ldap_control_create(pool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(pool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ {
+ struct timeval tv, *tvptr;
+
+ if (timeout < 0) {
+ tvptr = NULL;
+ }
+ else {
+ tv.tv_sec = (long) apr_time_sec(timeout);
+ tv.tv_usec = (long) apr_time_usec(timeout);
+ tvptr = &tv;
+ }
+
+ err->rc = ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, tvptr);
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: Could not set network timeout";
+ return APR_EINVAL;
+ }
+ }
+#endif
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_delete_ext(ldap->ld, (char *)dn,
+ sctrls, cctrls, &msgid);
+#else
+ err->rc = ldap_delete_ext(ldap->ld, dn,
+ sctrls, cctrls, &msgid);
+#endif
+
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: ldap_delete failed";
+ return apr_ldap_status(err->rc);
+ }
+ else {
+ memset(err, 0, sizeof(*err));
+ }
+
+ res = apr_pcalloc(pool, sizeof(apr_ldap_result_t));
+
+ if (!res) {
+ return APR_ENOMEM;
+ }
+
+ res->msgtype = LDAP_RES_DELETE;
+ res->cb.delete = delete_cb;
+ res->ctx = ctx;
+
+ apr_ldap_result_add(pool, ldap, res, msgid);
+
+ return APR_WANT_READ;
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_extended(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *oid,
+ apr_buffer_t *data,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_extended_cb ext_cb, void *ctx,
+ apu_err_t *err)
+{
+ LDAPControl **sctrls = NULL;
+ LDAPControl **cctrls = NULL;
+
+ apr_ldap_result_t *res;
+
+ struct berval reqdata;
+ struct berval *rd;
+
+ MSGID_T msgid = 0;
+
+ apr_status_t status;
+
+ status = apr_ldap_control_create(pool, ldap, &sctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(pool, ldap, &cctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+#ifdef LDAP_OPT_NETWORK_TIMEOUT
+ {
+ struct timeval tv, *tvptr;
+
+ if (timeout < 0) {
+ tvptr = NULL;
+ }
+ else {
+ tv.tv_sec = (long) apr_time_sec(timeout);
+ tv.tv_usec = (long) apr_time_usec(timeout);
+ tvptr = &tv;
+ }
+
+ err->rc = ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, tvptr);
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: Could not set network timeout";
+ return APR_EINVAL;
+ }
+ }
+#endif
+
+ if (!data || apr_buffer_is_null(data)) {
+ rd = NULL;
+ }
+ else {
+ reqdata.bv_val = apr_buffer_mem(data, NULL);
+ reqdata.bv_len = TO_BV_LEN(apr_buffer_len(data));
+ rd = &reqdata;
+ }
+
+#if APR_HAS_MICROSOFT_LDAPSDK
+ err->rc = ldap_extended_operation(ldap->ld, (char *)oid, rd,
+ sctrls, cctrls, &msgid);
+#else
+ err->rc = ldap_extended_operation(ldap->ld, oid, rd,
+ sctrls, cctrls, &msgid);
+#endif
+
+ if (err->rc != LDAP_SUCCESS) {
+ err->msg = ldap_err2string(err->rc);
+ err->reason = "LDAP: ldap_extended_operation failed";
+ return apr_ldap_status(err->rc);
+ }
+ else {
+ memset(err, 0, sizeof(*err));
+ }
+
+ res = apr_pcalloc(pool, sizeof(apr_ldap_result_t));
+
+ if (!res) {
+ return APR_ENOMEM;
+ }
+
+ res->msgtype = LDAP_RES_EXTENDED;
+ res->cb.ext = ext_cb;
+ res->ctx = ctx;
+
+ apr_ldap_result_add(pool, ldap, res, msgid);
+
+ return APR_WANT_READ;
+}
+
APU_DECLARE_LDAP(apr_status_t) apr_ldap_unbind(apr_ldap_t *ldap,
- apr_ldap_control_t **serverctrls,
- apr_ldap_control_t **clientctrls,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
apu_err_t *err)
{
- ldap->serverctrls = (LDAPControl **)serverctrls;
- ldap->clientctrls = (LDAPControl **)clientctrls;
+ apr_status_t status;
+
+ status = apr_ldap_control_create(ldap->pool, ldap, &ldap->serverctrls, serverctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
+
+ status = apr_ldap_control_create(ldap->pool, ldap, &ldap->clientctrls, clientctrls, err);
+
+ if (APR_SUCCESS != status) {
+ return status;
+ }
- apr_pool_cleanup_run(ldap->pool, ldap, ldap_cleanup);
+ apr_pool_cleanup_run(ldap->pool, ldap, apr_ldap_cleanup);
memcpy(err, &ldap->err, sizeof(apu_err_t));
@@ -2254,6 +3661,11 @@ APU_MODULE_DECLARE_DATA struct apr__ldap
apr_ldap_bind,
apr_ldap_compare,
apr_ldap_search,
+ apr_ldap_add,
+ apr_ldap_modify,
+ apr_ldap_rename,
+ apr_ldap_delete,
+ apr_ldap_extended,
apr_ldap_unbind
};
Modified: apr/apr/trunk/ldap/apr_ldap_stub.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/ldap/apr_ldap_stub.c?rev=1924295&r1=1924294&r2=1924295&view=diff
==============================================================================
--- apr/apr/trunk/ldap/apr_ldap_stub.c (original)
+++ apr/apr/trunk/ldap/apr_ldap_stub.c Tue Mar 11 13:27:42 2025
@@ -228,8 +228,8 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
const char *dn,
const char *attr,
const apr_buffer_t *bval,
- apr_ldap_control_t **serverctrls,
- apr_ldap_control_t **clientctrls,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
apr_interval_time_t timeout,
apr_ldap_compare_cb compare_cb, void *ctx,
apu_err_t *err)
@@ -245,8 +245,8 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
const char *filter,
const char **attrs,
apr_ldap_switch_e attrsonly,
- apr_ldap_control_t **serverctrls,
- apr_ldap_control_t **clientctrls,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
apr_interval_time_t timeout,
apr_ssize_t sizelimit,
apr_ldap_search_result_cb search_result_cb,
@@ -258,9 +258,78 @@ APU_DECLARE_LDAP(apr_status_t) apr_ldap_
return lfn->search(pool, ldap, dn, scope, filter, attrs, attrsonly, serverctrls, clientctrls, timeout, sizelimit, search_result_cb, search_entry_cb, search_ctx, err);
}
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_add(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn,
+ apr_array_header_t *adds,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_add_cb add_cb, void *ctx,
+ apu_err_t *err)
+{
+ CHECK_LDAP_STUB(APR_EINIT);
+ return lfn->add(pool, ldap, dn, adds, serverctrls, clientctrls, timeout, add_cb, ctx, err);
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_modify(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn,
+ apr_array_header_t *mods,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_modify_cb modify_cb, void *ctx,
+ apu_err_t *err)
+{
+ CHECK_LDAP_STUB(APR_EINIT);
+ return lfn->modify(pool, ldap, dn, mods, serverctrls, clientctrls, timeout, modify_cb, ctx, err);
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_rename(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn, const char *newrdn, const char *newparent,
+ apr_ldap_rename_e flags,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_rename_cb rename_cb, void *ctx,
+ apu_err_t *err)
+{
+ CHECK_LDAP_STUB(APR_EINIT);
+ return lfn->rename(pool, ldap, dn, newrdn, newparent, flags, serverctrls, clientctrls, timeout, rename_cb, ctx, err);
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_delete(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *dn,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_delete_cb delete_cb, void *ctx,
+ apu_err_t *err)
+{
+ CHECK_LDAP_STUB(APR_EINIT);
+ return lfn->delete(pool, ldap, dn, serverctrls, clientctrls, timeout, delete_cb, ctx, err);
+}
+
+APU_DECLARE_LDAP(apr_status_t) apr_ldap_extended(apr_pool_t *pool,
+ apr_ldap_t *ldap,
+ const char *oid,
+ apr_buffer_t *data,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
+ apr_interval_time_t timeout,
+ apr_ldap_extended_cb ext_cb, void *ctx,
+ apu_err_t *err)
+{
+ CHECK_LDAP_STUB(APR_EINIT);
+ return lfn->extended(pool, ldap, oid, data, serverctrls, clientctrls, timeout, ext_cb, ctx, err);
+}
+
APU_DECLARE_LDAP(apr_status_t) apr_ldap_unbind(apr_ldap_t *ldap,
- apr_ldap_control_t **serverctrls,
- apr_ldap_control_t **clientctrls,
+ apr_array_header_t *serverctrls,
+ apr_array_header_t *clientctrls,
apu_err_t *err)
{
CHECK_LDAP_STUB(APR_EINIT);
Modified: apr/apr/trunk/misc/unix/errorcodes.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/misc/unix/errorcodes.c?rev=1924295&r1=1924294&r2=1924295&view=diff
==============================================================================
--- apr/apr/trunk/misc/unix/errorcodes.c (original)
+++ apr/apr/trunk/misc/unix/errorcodes.c Tue Mar 11 13:27:42 2025
@@ -172,10 +172,55 @@ static char *apr_error_string(apr_status
return "Underlying crypto has already been initialised";
case APR_ENOVERIFY:
return "The signature verification failed";
+
+ case APR_WANT_READ:
+ return "Call me again when the socket is ready for reading";
+ case APR_WANT_WRITE:
+ return "Call me again when the socket is ready for writing";
+
+ case APR_OTHER:
+ return "An internal LDAP error has occurred";
case APR_SERVER_DOWN:
return "The server is down";
+ case APR_LOCAL_ERROR:
+ return "An error has occurred locally";
+ case APR_ENCODING_ERROR:
+ return "Encoding has failed";
+ case APR_DECODING_ERROR:
+ return "Decoding has failed";
case APR_AUTH_UNKNOWN:
return "Unknown SASL mechanism";
+ case APR_FILTER_ERROR:
+ return "The filter was malformed";
+ case APR_USER_CANCELLED:
+ return "User has cancelled the request";
+ case APR_PARAM_ERROR:
+ return "Parameter error";
+ case APR_CONNECT_ERROR:
+ return "Connect error";
+ case APR_NOT_SUPPORTED:
+ return "Not supported";
+ case APR_CONTROL_NOT_FOUND:
+ return "Control not found";
+ case APR_NO_RESULTS_RETURNED:
+ return "No results returned";
+ case APR_MORE_RESULTS_TO_RETURN:
+ return "More results to be returned";
+ case APR_CLIENT_LOOP:
+ return "Client loop has occurred";
+ case APR_REFERRAL_LIMIT_EXCEEDED:
+ return "Referral limit exceeded";
+ case APR_CONNECTING:
+ return "Connecting";
+
+ case APR_OPERATIONS_ERROR:
+ return "Operations error has occurred";
+ case APR_PROTOCOL_ERROR:
+ return "Protocol error has occurred";
+ case APR_TIMELIMIT_EXCEEDED:
+ return "Time limit has been exceeded";
+ case APR_SIZELIMIT_EXCEEDED:
+ return "Size limit has been exceeded";
case APR_PROXY_AUTH:
return "Proxy authorization has failed";
case APR_INAPPROPRIATE_AUTH:
@@ -184,26 +229,22 @@ static char *apr_error_string(apr_status
return "Invalid credentials were presented";
case APR_INSUFFICIENT_ACCESS:
return "The user has insufficient access";
- case APR_INSUFFICIENT_RIGHTS:
- return "The user has insufficient rights";
+ case APR_UNAVAILABLE:
+ return "Unavailable";
case APR_CONSTRAINT_VIOLATION:
return "A constraint was violated";
- case APR_FILTER_ERROR:
- return "The filter was malformed";
case APR_NO_SUCH_OBJECT:
return "No such object";
+ case APR_NO_SUCH_ATTRIBUTE:
+ return "No such attribute";
case APR_COMPARE_TRUE:
return "Comparison is true";
case APR_COMPARE_FALSE:
return "Comparison is false";
- case APR_NO_RESULTS_RETURNED:
- return "No results returned";
- case APR_WANT_READ:
- return "Call me again when the socket is ready for reading";
- case APR_WANT_WRITE:
- return "Call me again when the socket is ready for writing";
- case APR_USER_CANCELLED:
- return "User has cancelled the request";
+ case APR_ALREADY_EXISTS:
+ return "The object already exists";
+ case APR_OBJECT_CLASS_VIOLATION:
+ return "Add or modify results in an objectclass violation";
default:
return "Error string not specified yet";