* \___|\___/|_| \_\_____|
*
* Copyright (C) 2010, Howard Chu, <hyc@openldap.org>
- * Copyright (C) 2011 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 2011 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
+ * are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
#include "curl_ldap.h"
#include "curl_base64.h"
#include "connect.h"
+/* The last 3 #include files should be in this order */
#include "curl_printf.h"
-
-/* The last #include files should be: */
#include "curl_memory.h"
#include "memdebug.h"
+/*
+ * Uncommenting this will enable the built-in debug logging of the openldap
+ * library. The debug log level can be set using the CURL_OPENLDAP_TRACE
+ * environment variable. The debug output is written to stderr.
+ *
+ * The library supports the following debug flags:
+ * LDAP_DEBUG_NONE 0x0000
+ * LDAP_DEBUG_TRACE 0x0001
+ * LDAP_DEBUG_CONSTRUCT 0x0002
+ * LDAP_DEBUG_DESTROY 0x0004
+ * LDAP_DEBUG_PARAMETER 0x0008
+ * LDAP_DEBUG_ANY 0xffff
+ *
+ * For example, use CURL_OPENLDAP_TRACE=0 for no debug,
+ * CURL_OPENLDAP_TRACE=2 for LDAP_DEBUG_CONSTRUCT messages only,
+ * CURL_OPENLDAP_TRACE=65535 for all debug message levels.
+ */
+/* #define CURL_OPENLDAP_DEBUG */
+
#ifndef _LDAP_PVT_H
extern int ldap_pvt_url_scheme2proto(const char *);
extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url,
ZERO_NULL, /* perform_getsock */
ldap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
PORT_LDAP, /* defport */
CURLPROTO_LDAP, /* protocol */
PROTOPT_NONE /* flags */
ZERO_NULL, /* perform_getsock */
ldap_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
+ ZERO_NULL, /* connection_check */
PORT_LDAPS, /* defport */
CURLPROTO_LDAP, /* protocol */
PROTOPT_SSL /* flags */
{
ldapconninfo *li;
LDAPURLDesc *lud;
- struct SessionHandle *data=conn->data;
+ struct Curl_easy *data = conn->data;
int rc, proto;
CURLcode status;
static CURLcode ldap_connect(struct connectdata *conn, bool *done)
{
ldapconninfo *li = conn->proto.generic;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
int rc, proto = LDAP_VERSION3;
char hosturl[1024];
char *ptr;
(void)done;
strcpy(hosturl, "ldap");
- ptr = hosturl+4;
+ ptr = hosturl + 4;
if(conn->handler->flags & PROTOPT_SSL)
*ptr++ = 's';
snprintf(ptr, sizeof(hosturl)-(ptr-hosturl), "://%s:%d",
- conn->host.name, conn->remote_port);
+ conn->host.name, conn->remote_port);
+
+#ifdef CURL_OPENLDAP_DEBUG
+ static int do_trace = 0;
+ const char *env = getenv("CURL_OPENLDAP_TRACE");
+ do_trace = (env && strtol(env, NULL, 10) > 0);
+ if(do_trace) {
+ ldap_set_option(li->ld, LDAP_OPT_DEBUG_LEVEL, &do_trace);
+ }
+#endif
rc = ldap_init_fd(conn->sock[FIRSTSOCKET], li->proto, hosturl, &li->ld);
if(rc) {
static CURLcode ldap_connecting(struct connectdata *conn, bool *done)
{
ldapconninfo *li = conn->proto.generic;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
LDAPMessage *msg = NULL;
struct timeval tv = {0, 1}, *tvp;
int rc, err;
tvp = &tv;
-retry:
+ retry:
if(!li->didbind) {
char *binddn;
struct berval passwd;
int rc = 0;
LDAPURLDesc *ludp = NULL;
int msgid;
- struct SessionHandle *data=conn->data;
+ struct Curl_easy *data = conn->data;
connkeep(conn, "OpenLDAP do");
size_t len, CURLcode *err)
{
ldapconninfo *li = conn->proto.generic;
- struct SessionHandle *data = conn->data;
+ struct Curl_easy *data = conn->data;
ldapreqinfo *lr = data->req.protop;
int rc, ret;
LDAPMessage *msg = NULL;
return ret;
for(ent = ldap_first_message(li->ld, msg); ent;
- ent = ldap_next_message(li->ld, ent)) {
- struct berval bv, *bvals, **bvp = &bvals;
+ ent = ldap_next_message(li->ld, ent)) {
+ struct berval bv, *bvals;
int binary = 0, msgtype;
+ CURLcode writeerr;
msgtype = ldap_msgtype(ent);
if(msgtype == LDAP_RES_SEARCH_RESULT) {
*err = CURLE_RECV_ERROR;
return -1;
}
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
- bv.bv_len);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ bv.bv_len);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount += bv.bv_len + 5;
- for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
- rc == LDAP_SUCCESS;
- rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
+ for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals);
+ (rc == LDAP_SUCCESS) && bvals;
+ rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) {
int i;
- if(bv.bv_val == NULL) break;
+ if(bv.bv_val == NULL)
+ break;
if(bv.bv_len > 7 && !strncmp(bv.bv_val + bv.bv_len - 7, ";binary", 7))
binary = 1;
else
binary = 0;
- for(i=0; bvals[i].bv_val != NULL; i++) {
+ for(i = 0; bvals[i].bv_val != NULL; i++) {
int binval = 0;
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
- bv.bv_len);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)bv.bv_val,
+ bv.bv_len);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)":", 1);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount += bv.bv_len + 2;
if(!binary) {
/* check for leading or trailing whitespace */
if(ISSPACE(bvals[i].bv_val[0]) ||
- ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
+ ISSPACE(bvals[i].bv_val[bvals[i].bv_len-1]))
binval = 1;
else {
/* check for unprintable characters */
unsigned int j;
- for(j=0; j<bvals[i].bv_len; j++)
+ for(j = 0; j<bvals[i].bv_len; j++)
if(!ISPRINT(bvals[i].bv_val[j])) {
binval = 1;
break;
*err = error;
return -1;
}
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY,
+ (char *)": ", 2);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount += 2;
if(val_b64_sz > 0) {
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
- val_b64_sz);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
+ val_b64_sz);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
free(val_b64);
data->req.bytecount += val_b64_sz;
}
}
else {
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)" ", 1);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
- bvals[i].bv_len);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, bvals[i].bv_val,
+ bvals[i].bv_len);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount += bvals[i].bv_len + 1;
}
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount++;
}
ber_memfree(bvals);
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount++;
}
- *err = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
- if(*err)
+ writeerr = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
+ if(writeerr) {
+ *err = writeerr;
return -1;
+ }
data->req.bytecount++;
ber_free(ber, 0);
}
ber_slen_t ret;
CURLcode err = CURLE_RECV_ERROR;
- ret = li->recv(conn, FIRSTSOCKET, buf, len, &err);
+ ret = (li->recv)(conn, FIRSTSOCKET, buf, len, &err);
if(ret < 0 && err == CURLE_AGAIN) {
SET_SOCKERRNO(EWOULDBLOCK);
}
ber_slen_t ret;
CURLcode err = CURLE_SEND_ERROR;
- ret = li->send(conn, FIRSTSOCKET, buf, len, &err);
+ ret = (li->send)(conn, FIRSTSOCKET, buf, len, &err);
if(ret < 0 && err == CURLE_AGAIN) {
SET_SOCKERRNO(EWOULDBLOCK);
}