25 #if !defined(CURL_DISABLE_LDAP) && !defined(USE_OPENLDAP) 40 # ifndef LDAP_VENDOR_NAME 41 # error Your Platform SDK is NOT sufficient for LDAP support! \ 42 Update your Platform SDK, or disable LDAP support! 47 # define LDAP_DEPRECATED 1 52 # if (defined(HAVE_LDAP_SSL) && defined(HAVE_LDAP_SSL_H)) 53 # include <ldap_ssl.h> 62 # undef X509_CERT_PAIR 63 # undef X509_EXTENSIONS 83 #ifndef HAVE_LDAP_URL_PARSE 90 #if defined(USE_WIN32_LDAP) 98 #if defined(USE_WIN32_LDAP) 110 #define LDAPURLDesc CURL_LDAPURLDesc 116 #undef ldap_free_urldesc 117 #define ldap_free_urldesc _ldap_free_urldesc 121 #define LDAP_TRACE(x) do { \ 122 _ldap_trace("%u: ", __LINE__); \ 126 static void _ldap_trace(
const char *fmt, ...);
128 #define LDAP_TRACE(x) Curl_nop_stmt 186 #if defined(USE_WIN32_LDAP) 188 #if defined(USE_WINDOWS_SSPI) 189 static int ldap_win_bind_auth(LDAP *
server,
const char *user,
190 const char *passwd,
unsigned long authflags)
193 SEC_WINNT_AUTH_IDENTITY cred = { 0, };
194 int rc = LDAP_AUTH_METHOD_NOT_SUPPORTED;
196 #if defined(USE_SPNEGO) 198 method = LDAP_AUTH_NEGOTIATE;
202 #if defined(USE_NTLM) 204 method = LDAP_AUTH_NTLM;
208 #if !defined(CURL_DISABLE_CRYPTO_AUTH) 210 method = LDAP_AUTH_DIGEST;
218 if(method && user && passwd) {
219 rc = Curl_create_sspi_identity(user, passwd, &cred);
221 rc = ldap_bind_s(
server, NULL, (TCHAR *)&cred, method);
222 Curl_sspi_free_identity(&cred);
227 method = LDAP_AUTH_NEGOTIATE;
228 rc = ldap_bind_s(
server, NULL, NULL, method);
235 const char *user,
const char *passwd)
237 int rc = LDAP_INVALID_CREDENTIALS;
239 PTCHAR inuser = NULL;
240 PTCHAR inpass = NULL;
243 inuser = Curl_convert_UTF8_to_tchar((
char *) user);
244 inpass = Curl_convert_UTF8_to_tchar((
char *) passwd);
248 Curl_unicodefree(inuser);
249 Curl_unicodefree(inpass);
251 #if defined(USE_WINDOWS_SSPI) 267 LDAPMessage *ldapmsg = NULL;
268 LDAPMessage *entryIterator;
271 int ldap_proto = LDAP_VERSION3;
273 char *val_b64 = NULL;
274 size_t val_b64_sz = 0;
276 #ifdef LDAP_OPT_NETWORK_TIMEOUT 277 struct timeval ldap_timeout = {10, 0};
279 #if defined(USE_WIN32_LDAP) 288 infof(data,
"LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
289 LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
292 #ifdef HAVE_LDAP_URL_PARSE 306 infof(data,
"LDAP local: trying to establish %s connection\n",
307 ldap_ssl ?
"encrypted" :
"cleartext");
309 #if defined(USE_WIN32_LDAP) 310 host = Curl_convert_UTF8_to_tchar(conn->
host.
name);
325 #ifdef LDAP_OPT_NETWORK_TIMEOUT 326 ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
328 ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
332 #ifdef USE_WIN32_LDAP 334 server = ldap_sslinit(host, (
int)conn->
port, 1);
335 ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
339 #if defined(CURL_HAS_NOVELL_LDAPSDK) 340 rc = ldapssl_client_init(NULL, NULL);
341 if(rc != LDAP_SUCCESS) {
348 int cert_type = LDAPSSL_CERT_FILETYPE_B64;
351 cert_type = LDAPSSL_CERT_FILETYPE_DER;
353 failf(data,
"LDAP local: ERROR %s CA cert not set!",
354 (cert_type == LDAPSSL_CERT_FILETYPE_DER ?
"DER" :
"PEM"));
358 infof(data,
"LDAP local: using %s CA cert '%s'\n",
359 (cert_type == LDAPSSL_CERT_FILETYPE_DER ?
"DER" :
"PEM"),
361 rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
362 if(rc != LDAP_SUCCESS) {
363 failf(data,
"LDAP local: ERROR setting %s CA cert: %s",
364 (cert_type == LDAPSSL_CERT_FILETYPE_DER ?
"DER" :
"PEM"),
369 ldap_option = LDAPSSL_VERIFY_SERVER;
372 ldap_option = LDAPSSL_VERIFY_NONE;
373 rc = ldapssl_set_verify_mode(ldap_option);
374 if(rc != LDAP_SUCCESS) {
375 failf(data,
"LDAP local: ERROR setting cert verify mode: %s",
380 server = ldapssl_init(host, (
int)conn->
port, 1);
382 failf(data,
"LDAP local: Cannot connect to %s:%ld",
387 #elif defined(LDAP_OPT_X_TLS) 392 failf(data,
"LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
397 failf(data,
"LDAP local: ERROR PEM CA cert not set!");
401 infof(data,
"LDAP local: using PEM CA cert: %s\n", ldap_ca);
402 rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
403 if(rc != LDAP_SUCCESS) {
404 failf(data,
"LDAP local: ERROR setting PEM CA cert: %s",
409 ldap_option = LDAP_OPT_X_TLS_DEMAND;
412 ldap_option = LDAP_OPT_X_TLS_NEVER;
414 rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
415 if(rc != LDAP_SUCCESS) {
416 failf(data,
"LDAP local: ERROR setting cert verify mode: %s",
423 failf(data,
"LDAP local: Cannot connect to %s:%ld",
428 ldap_option = LDAP_OPT_X_TLS_HARD;
429 rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
430 if(rc != LDAP_SUCCESS) {
431 failf(data,
"LDAP local: ERROR setting SSL/TLS mode: %s",
448 failf(data,
"LDAP local: SSL/TLS not supported with this version " 449 "of the OpenLDAP toolkit\n");
459 failf(data,
"LDAP local: Cannot connect to %s:%ld",
465 #ifdef USE_WIN32_LDAP 466 ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
469 #ifdef USE_WIN32_LDAP 470 rc = ldap_win_bind(conn, server, user, passwd);
474 if(!ldap_ssl && rc != 0) {
475 ldap_proto = LDAP_VERSION2;
476 ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
477 #ifdef USE_WIN32_LDAP 478 rc = ldap_win_bind(conn, server, user, passwd);
490 ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);
492 if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
498 for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
500 entryIterator = ldap_next_entry(server, entryIterator), num++) {
501 BerElement *ber = NULL;
502 #if defined(USE_WIN32_LDAP) 513 #if defined(USE_WIN32_LDAP) 515 name = Curl_convert_tchar_to_UTF8(dn);
524 char *dn = name =
ldap_get_dn(server, entryIterator);
526 name_len = strlen(name);
530 #if defined(USE_WIN32_LDAP) 531 Curl_unicodefree(name);
541 #if defined(USE_WIN32_LDAP) 542 Curl_unicodefree(name);
551 #if defined(USE_WIN32_LDAP) 552 Curl_unicodefree(name);
559 dlsize += name_len + 5;
561 #if defined(USE_WIN32_LDAP) 562 Curl_unicodefree(name);
573 #if defined(USE_WIN32_LDAP) 574 char *attr = Curl_convert_tchar_to_UTF8(attribute);
584 char *attr = attribute;
586 attr_len = strlen(attr);
590 for(i = 0; (vals[
i] != NULL); i++) {
593 ldap_value_free_len(vals);
594 #if defined(USE_WIN32_LDAP) 595 Curl_unicodefree(attr);
597 ldap_memfree(attribute);
605 (
char *) attr, attr_len);
607 ldap_value_free_len(vals);
608 #if defined(USE_WIN32_LDAP) 609 Curl_unicodefree(attr);
611 ldap_memfree(attribute);
620 ldap_value_free_len(vals);
621 #if defined(USE_WIN32_LDAP) 622 Curl_unicodefree(attr);
624 ldap_memfree(attribute);
631 dlsize += attr_len + 3;
634 (strcmp(
";binary", (
char *) attr + (attr_len - 7)) == 0)) {
642 ldap_value_free_len(vals);
643 #if defined(USE_WIN32_LDAP) 644 Curl_unicodefree(attr);
646 ldap_memfree(attribute);
658 ldap_value_free_len(vals);
659 #if defined(USE_WIN32_LDAP) 660 Curl_unicodefree(attr);
662 ldap_memfree(attribute);
669 dlsize += val_b64_sz;
676 ldap_value_free_len(vals);
677 #if defined(USE_WIN32_LDAP) 678 Curl_unicodefree(attr);
680 ldap_memfree(attribute);
687 dlsize += vals[
i]->bv_len;
692 ldap_value_free_len(vals);
693 #if defined(USE_WIN32_LDAP) 694 Curl_unicodefree(attr);
696 ldap_memfree(attribute);
707 ldap_value_free_len(vals);
711 #if defined(USE_WIN32_LDAP) 712 Curl_unicodefree(attr);
714 ldap_memfree(attribute);
729 ldap_msgfree(ldapmsg);
732 if(rc == LDAP_SIZELIMIT_EXCEEDED)
733 infof(data,
"There are more than %d entries\n", num);
737 ldap_unbind_s(server);
738 #if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK) 740 ldapssl_client_deinit();
743 #if defined(USE_WIN32_LDAP) 744 Curl_unicodefree(host);
749 connclose(conn,
"LDAP connection always disable re-use");
755 static void _ldap_trace(
const char *fmt, ...)
757 static int do_trace = -1;
761 const char *env =
getenv(
"CURL_TRACE");
762 do_trace = (env && strtol(env, NULL, 10) > 0);
773 #ifndef HAVE_LDAP_URL_PARSE 781 return LDAP_SCOPE_ONELEVEL;
783 return LDAP_SCOPE_ONELEVEL;
785 return LDAP_SCOPE_BASE;
787 return LDAP_SCOPE_SUBTREE;
789 return LDAP_SCOPE_SUBTREE;
805 s = strchr(str,
',');
808 s = strchr(++s,
',');
811 res =
calloc(items,
sizeof(
char *));
815 for(i = 0, s =
strtok_r(str,
",", &lasts); s && i < items;
816 s =
strtok_r(NULL,
",", &lasts), i++)
841 int rc = LDAP_SUCCESS;
851 return LDAP_INVALID_SYNTAX;
853 ludp->lud_scope = LDAP_SCOPE_BASE;
860 return LDAP_NO_MEMORY;
882 #if defined(USE_WIN32_LDAP) 884 ludp->lud_dn = Curl_convert_UTF8_to_tchar(unescaped);
887 Curl_unicodefree(unescaped);
895 ludp->lud_dn = unescaped;
920 #if defined(USE_WIN32_LDAP) 921 ludp->lud_attrs =
calloc(count + 1,
sizeof(TCHAR *));
923 ludp->lud_attrs =
calloc(count + 1,
sizeof(
char *));
925 if(!ludp->lud_attrs) {
933 for(i = 0; i < count; i++) {
937 LDAP_TRACE((
"attr[%d] '%s'\n", i, attributes[i]));
950 #if defined(USE_WIN32_LDAP) 952 ludp->lud_attrs[
i] = Curl_convert_UTF8_to_tchar(unescaped);
955 Curl_unicodefree(unescaped);
957 if(!ludp->lud_attrs[i]) {
965 ludp->lud_attrs[
i] = unescaped;
968 ludp->lud_attrs_dups++;
985 if(ludp->lud_scope == -1) {
986 rc = LDAP_INVALID_SYNTAX;
1012 rc = LDAP_NO_MEMORY;
1017 #if defined(USE_WIN32_LDAP) 1019 ludp->lud_filter = Curl_convert_UTF8_to_tchar(unescaped);
1022 Curl_unicodefree(unescaped);
1024 if(!ludp->lud_filter) {
1025 rc = LDAP_NO_MEMORY;
1030 ludp->lud_filter = unescaped;
1036 rc = LDAP_INVALID_SYNTAX;
1055 return LDAP_NO_MEMORY;
1058 if(rc != LDAP_SUCCESS) {
1074 free(ludp->lud_filter);
1076 if(ludp->lud_attrs) {
1077 for(i = 0; i < ludp->lud_attrs_dups; i++)
1078 free(ludp->lud_attrs[i]);
1079 free(ludp->lud_attrs);
CURLcode Curl_urldecode(struct Curl_easy *data, const char *string, size_t length, char **ostring, size_t *olen, bool reject_ctrl)
#define ldap_simple_bind_s
static int _ldap_url_parse(const struct connectdata *conn, LDAPURLDesc **ludp)
static void _ldap_free_urldesc(LDAPURLDesc *ludp)
CURLcode Curl_base64_encode(struct Curl_easy *data, const char *inputbuff, size_t insize, char **outptr, size_t *outlen)
const struct Curl_handler Curl_handler_ldap
#define ldap_get_values_len
#define strcasecompare(a, b)
UNITTEST_START int result
struct ssl_config_data ssl
struct DynamicStatic change
#define CURLAUTH_NEGOTIATE
static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
void Curl_setup_transfer(struct connectdata *conn, int sockindex, curl_off_t size, bool getheader, curl_off_t *bytecountp, int writesockindex, curl_off_t *writecountp)
static bool split_str(char *str, char ***out, size_t *count)
static struct mg_server * server
CURL_TYPEOF_CURL_OFF_T curl_off_t
#define ldap_free_urldesc
const struct Curl_handler * given
CURLcode Curl_client_write(struct connectdata *conn, int type, char *ptr, size_t len)
void Curl_pgrsSetDownloadCounter(struct Curl_easy *data, curl_off_t size)
struct ssl_primary_config ssl_config
#define ldap_next_attribute
#define checkprefix(a, b)
#define ldap_first_attribute
static int str2scope(const char *p)
#define calloc(nbelem, size)
static CURLcode Curl_ldap(struct connectdata *conn, bool *done)