cURL / Mailing Lists / curl-library / Single Mail

curl-library

Win32 LDAP and Unicode

From: Steve Holme <steve_holme_at_hotmail.com>
Date: Sun, 4 Jan 2015 17:46:00 +0000

Dear friends,

Back in August Gisle raised an issue that our ldap module (ldap.c) when
compiled under Windows with Unicode had compilation warnings:

http://curl.haxx.se/mail/lib-2014-08/0066.html

At the time I proposed a fix, which fixed the warnings, but we weren't sure
if this patch was needed or whether we could simply cast the offending
pointers, or even if ldap would work properly with my proposed fix.

Anyway, the bottom line was that it wasn't that simple, unfortunately, and
I've spent quite a bit of time during December working on an appropriate
fix, coming up with some live test cases and testing it over and over again
- ideally trying to find the simplest fix (which wasn't to be!). Last night
I finished off my testing and prepared my fixes for pushing into the repo.

If you compile the curl source code, prior to the changes I started to push
yesterday, with UNICODE defined on Win32 or Win64 then you'll get a bunch of
warnings about wchar * conversion to char * and via versa.

Option 1: The simply solution

If the warnings are silenced or ignored then the output shown in [1] is
typical of a connection to an LDAP server.

Basically, the call to ldap_simple_bind_s() fails.

Option 2: The more involved approach

This can be broken down into three parts:

A) The broken connection as discussed above.

The changes I pushed yesterday fix the connection initialisation and bind by
using a Unicode based host name, user name and password in the ldap_init()
and ldap_simple_bind_s() calls.

B) Do something useful via curl (ie set a base DN, search for specific
attributes or apply a filter)

Basically, the call to ldap_search_s() fails as can be seen in [2].

The changes I've pushing today fix this by using Unicode based DN, attribute
and filters in the CURL_LDAPURLDesc structure.

C) curl outputs the resulting data incorrectly

This can be seen in [3].

I'm not sure what the best fix here is - and depending on what we should do,
may be outside the scope of fixing for 7.40.0 :(

In summary, some of the data being passed to Curl_client_write() is stored
as wide characters and the length being passed may not be correct (as it was
being obtained using strlen() - which could find a potential zero in the
second byte of the first character). I am now using _tcslen() under Windows
but this will report the characters not the bytes and modifies the output as
seen in [4].

So my question is... Should we be passing the wide characters, as is, from
libcurl to the client application or should we be converting it to UTF-8
first?

If we send the data as is, how would a client know that the data being
received is wide - it can check the UNICODE pre-processor directive but not
all the data will be in Unicode. For example the DN and attribute names seem
to be Unicode but the actual data seems to be ASCII or binary. If it is
binary, we already attempt to detect this and convert the data to base64 -
this brings other problems and I'm not convinced it is work 100% at the
moment but that is another issue for another day!!

Additionally, in order for the curl command line tool to then correctly
display that data - it would have to have access to the multibyte routines
used in libcurl.

I have also included what the output looks like for an ASCII build [5].

Many thanks

Steve

[1] - Connection a Windows Active Directory Domain Controller (Code prior to
commit f460f12c9d)

* Rebuilt URL to: ldap://dc0.example.com/
* Hostname was NOT found in DNS cache
* Trying 192.168.0.1...
* Connected to dc0.example.com (192.168.0.1) port 389 (#0)
* LDAP local: LDAP Vendor = Microsoft Corporation. ; LDAP Version = 510
* LDAP local: ldap://dc0.example.com/
* LDAP local: trying to establish cleartext connection
* LDAP local: ldap_simple_bind_s U
* Closing connection 0
curl: (38) LDAP local: ldap_simple_bind_s U

[2] - Fixed connection (Code with commits f460f12c9d, 0f26148423 and
6416dc998b)

* Rebuilt URL to: ldap://dc0.example.com/
* Hostname was NOT found in DNS cache
* Trying 192.168.0.1...
* Connected to dc0.example.com (192.168.0.1) port 389 (#0)
* LDAP local: LDAP Vendor = Microsoft Corporation. ; LDAP Version = 510
* LDAP local: ldap://dc0.example.com/???(objectClass=*)
* LDAP local: trying to establish cleartext connection
* LDAP remote: F
* Closing connection 0
curl: (39) LDAP remote: F

[3] - An extract of Unicode data after fixing the connection

* Rebuilt URL to: ldap://dc0.example.com/
* Hostname was NOT found in DNS cache
* Trying 192.168.0.1...
* Connected to dc0.example.com (192.168.0.1) port 389 (#0)
* LDAP local: LDAP Vendor = Microsoft Corporation. ; LDAP Version = 510
* LDAP local: ldap://dc0.example.com/???(objectClass=*)
* LDAP local: trying to establish cleartext connection
DN:

        c: 20150103192654.0Z
        s: 3
        s: 2
        s: GSSAPI
        s: GSS-SPNEGO
        s: EXTERNAL
        s: DIGEST-MD5
        d: dc0.example.com
        l: example.com:dc0$@EXAMPLE.COM
        i: TRUE
        i: TRUE
        d: 4
        f: 4
        d: 6

[4] - The same data after commit c37dcf0edb

* Rebuilt URL to: ldap://dc0.example.com/
* Hostname was NOT found in DNS cache
* Trying 192.168.0.1...
* Connected to dc0.example.com (192.168.0.1) port 389 (#0)
* LDAP local: LDAP Vendor = Microsoft Corporation. ; LDAP Version = 510
* LDAP local: ldap://dc0.example.com/???(objectClass=*)
* LDAP local: trying to establish cleartext connection
DN:

        c u r r e n: 20150104170738.0Z
        s u p p o r t e d L : 3
        s u p p o r t e d L : 2
        s u p p o r t e d S A S: GSSAPI
        s u p p o r t e d S A S: GSS-SPNEGO
        s u p p o r t e d S A S: EXTERNAL
        s u p p o r t e d S A S: DIGEST-MD5
        d n s H o s: dc0.example.com
        l d a p S e r v: example.com:dc0$@EXAMPLE.COM
        i s S y n c h : TRUE
        i s G l o b a l C a : TRUE
        d o m a i n F u n c: 4
        f o r e s t F u n c: 4
        d o m a i n C o n t r o l l e: 6

[5] - The same data with an ASCII build of curl

* Rebuilt URL to: ldap://dc0.example.com/
* Hostname was NOT found in DNS cache
* Trying 192.168.0.1...
* Connected to dc0.example.com (192.168.0.1) port 389 (#0)
* LDAP local: LDAP Vendor = Microsoft Corporation. ; LDAP Version = 510
* LDAP local: ldap://dc0.example.com/???(objectClass=*)
* LDAP local: trying to establish cleartext connection
DN:

        currentTime: 20150103191155.0Z
        supportedLDAPVersion: 3
        supportedLDAPVersion: 2
        supportedSASLMechanisms: GSSAPI
        supportedSASLMechanisms: GSS-SPNEGO
        supportedSASLMechanisms: EXTERNAL
        supportedSASLMechanisms: DIGEST-MD5
        dnsHostName: dc0.example.com
        ldapServiceName: example.com:dc0$@EXAMPLE.COM
        isSynchronized: TRUE
        isGlobalCatalogReady: TRUE
        domainFunctionality: 4
        forestFunctionality: 4
        domainControllerFunctionality: 6

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-01-04