Hi All,
Recently, I tried to write a ldap client to do ldap search asynchronously, but failed to perform search operation after a successful async sasl (digest-md5) bind.
I’ve tried some code, but only succeeded in searching in synchronized sasl bind.
I compared the captured sync and async packets:
In sync bind, the search packets were encrypted.
In async bind, after sasl (digest-md5) binding to ldap server asynchronously (by calling ldap_sasl_interactive_bind() twice), ldap_search_ext() was called. But the search packet was in plain text. Then the ldap server reset the connection or just didn’t response (in the case of MSAD).
Did I use the ldap API incorrectly? Or async sasl bind doesn’t support search operation?
Any suggestion will be appreciated and sorry for my poor English.
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search asynchronously, but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it establishs a security context/association.
I compared the captured sync and async packets:
In sync bind, the search packets were encrypted.
In async bind, after sasl (digest-md5) binding to ldap server asynchronously (by calling ldap_sasl_interactive_bind() twice), ldap_search_ext() was called. But the search packet was in plain text. Then the ldap server reset the connection or just didn’t response (in the case of MSAD).
Note that SASL bind with DIGEST-MD5 does *not* give you any encryption of the transport channel. Working with MS AD are you looking for SASL/GSSAPI?
Ciao, Michael.
On Wed, Nov 26, 2014 at 5:30 PM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search
asynchronously,
but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it establishs a security context/association.
The ldap client is a daemon which accepts arbitrary request from outside and periodically retrieves all users/groups from ldap server. For sync bind, the client needs to wait for bind to complete, which could make outside request not be responded for a time . It would be better to support async bind in the client.
I compared the captured sync and async packets:
In sync bind, the search packets were encrypted.
In async bind, after sasl (digest-md5) binding to ldap server asynchronously (by calling ldap_sasl_interactive_bind() twice), ldap_search_ext() was called. But the search packet was in plain text.
Then
the ldap server reset the connection or just didn’t response (in the case of MSAD).
Note that SASL bind with DIGEST-MD5 does *not* give you any encryption of the transport channel. Working with MS AD are you looking for SASL/GSSAPI?
Thanks for your explanation.
From packet sniffer view, after sync SASL bind completed, the following
search packets are all encoded in to SASL buffer. Using SASL/DIGEST-MD5 is to protect the password of the bound user in contrast to simple bind. In addition, the client needs to support both openldap and MS AD, so maybe SASL/DIGEST-MD5 is a better choice.
Qian Li wrote:
On Wed, Nov 26, 2014 at 5:30 PM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search
asynchronously,
but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it establishs a security context/association.
The ldap client is a daemon which accepts arbitrary request from outside
What kind of requests?
and periodically retrieves all users/groups from ldap server.
A simple search? Security requirements regarding passwords?
For sync bind, the client needs to wait for bind to complete, which could make outside request not be responded for a time . It would be better to support async bind in the client.
That does not make sense.
Again: The bind operation is somewhat special because it establishs a security context/association. Note that the following LDAP requests are authorized based on the bound identity.
I don't know what's your exact use-case. But if you're cautious about performance you should open a connection pool of persistent connections and always bind *once* during connection lifetime.
Ciao, Michael.
On Thu, Nov 27, 2014 at 4:51 AM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
On Wed, Nov 26, 2014 at 5:30 PM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search
asynchronously,
but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it establishs a security context/association.
The ldap client is a daemon which accepts arbitrary request from outside
What kind of requests?
There are IPCs from other processes and the ldap client is only single thread.
and periodically retrieves all users/groups from ldap server.
A simple search? Security requirements regarding passwords?
Security requirements only regarding bound identity's password. If simple bind is used, the identity's password will be plain text in the search request.
For sync bind, the client needs to wait for bind to complete, which could make outside request not be responded for a time . It would be better to support async bind in the client.
That does not make sense.
Again: The bind operation is somewhat special because it establishs a security context/association. Note that the following LDAP requests are authorized based on the bound identity.
I don't know what's your exact use-case. But if you're cautious about performance you should open a connection pool of persistent connections and always bind *once* during connection lifetime.
Yes, persistent connections pool is another solution. The search operation works in both async simple bind and sync SASL/DIGEST-MD5 bind, but doesn't work in async SASL/DIGEST-MD5 bind. This confuses me...
Qian Li wrote:
On Thu, Nov 27, 2014 at 4:51 AM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
On Wed, Nov 26, 2014 at 5:30 PM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search
asynchronously,
but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it establishs a security context/association.
The ldap client is a daemon which accepts arbitrary request from outside
What kind of requests?
There are IPCs from other processes and the ldap client is only single thread.
I did something very similar recently.
I don't know what's your exact use-case. But if you're cautious about performance you should open a connection pool of persistent connections and always bind *once* during connection lifetime.
Yes, persistent connections pool is another solution. The search operation works in both async simple bind and sync SASL/DIGEST-MD5 bind, but doesn't work in async SASL/DIGEST-MD5 bind. This confuses me...
You have to wait for the SASL bind to complete *before* sending the subsequent search operation anyway => persistent connections are *the* solution.
In my case such a simple local demon served 300+ requests/second with the LDAP server with debug log and the demon running on the same old laptop. One request to the demon sends three synchronous LDAP requests.
Ciao, Michael.
On Thu, Nov 27, 2014 at 3:27 PM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
On Thu, Nov 27, 2014 at 4:51 AM, Michael Ströder michael@stroeder.com wrote:
Qian Li wrote:
On Wed, Nov 26, 2014 at 5:30 PM, Michael Ströder <michael@stroeder.com
wrote:
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search
asynchronously,
but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it
establishs a
security context/association.
The ldap client is a daemon which accepts arbitrary request from outside
What kind of requests?
There are IPCs from other processes and the ldap client is only single thread.
I did something very similar recently.
I don't know what's your exact use-case. But if you're cautious about performance you should open a connection pool of persistent connections
and
always bind *once* during connection lifetime.
Yes, persistent connections pool is another solution. The search operation works in both async simple bind and sync SASL/DIGEST-MD5 bind, but doesn't work in async SASL/DIGEST-MD5 bind.
This
confuses me...
You have to wait for the SASL bind to complete *before* sending the subsequent search operation anyway => persistent connections are *the* solution.
I did wait for the async SASL bind to complete. Unfortunately, the search operation still didn't work. I have to use sync SASL bind, like persistent connections pool.
In my case such a simple local demon served 300+ requests/second with the
LDAP server with debug log and the demon running on the same old laptop. One request to the demon sends three synchronous LDAP requests.
In my case, every response from LDAP server may include many entries. Async search will be more efficient.
Thanks -Qian
Michael Ströder wrote:
Qian Li wrote:
Recently, I tried to write a ldap client to do ldap search asynchronously, but failed to perform search operation after a successful async sasl (digest-md5) bind.
What's your use-case for having async bind operation?
Note that the bind operation is somewhat special because it establishs a security context/association.
I compared the captured sync and async packets:
In sync bind, the search packets were encrypted.
In async bind, after sasl (digest-md5) binding to ldap server asynchronously (by calling ldap_sasl_interactive_bind() twice), ldap_search_ext() was called. But the search packet was in plain text. Then the ldap server reset the connection or just didn’t response (in the case of MSAD).
Note that SASL bind with DIGEST-MD5 does *not* give you any encryption of the transport channel. Working with MS AD are you looking for SASL/GSSAPI?
That's false, the DIGEST-MD5 mech gives DES encryption. (Not that DES is worth much these days, but neither is MD5...)
Qian Li wrote:
Hi All,
Recently, I tried to write a ldap client to do ldap search asynchronously, but failed to perform search operation after a successful async sasl (digest-md5) bind.
I’ve tried some code, but only succeeded in searching in synchronized sasl bind.
I compared the captured sync and async packets:
In sync bind, the search packets were encrypted.
In async bind, after sasl (digest-md5) binding to ldap server asynchronously (by calling ldap_sasl_interactive_bind() twice), ldap_search_ext() was called. But the search packet was in plain text. Then the ldap server reset the connection or just didn’t response (in the case of MSAD).
Did I use the ldap API incorrectly?
No one can tell whether you did or not, without seeing your code.
Or async sasl bind doesn’t support search operation?
async or sync makes no difference when properly used.
Any suggestion will be appreciated and sorry for my poor English.
On Fri, Nov 28, 2014 at 9:43 PM, Howard Chu hyc@symas.com wrote:
Qian Li wrote:
Hi All,
Recently, I tried to write a ldap client to do ldap search asynchronously, but failed to perform search operation after a successful async sasl (digest-md5) bind.
I’ve tried some code, but only succeeded in searching in synchronized sasl bind.
I compared the captured sync and async packets:
In sync bind, the search packets were encrypted.
In async bind, after sasl (digest-md5) binding to ldap server asynchronously (by calling ldap_sasl_interactive_bind() twice), ldap_search_ext() was called. But the search packet was in plain text. Then the ldap server reset the connection or just didn’t response (in the case of MSAD).
Did I use the ldap API incorrectly?
No one can tell whether you did or not, without seeing your code.
Hi Howard,
Sorry for the late reply. The main part of my testing code is pasted below (some error handling is removed for simplicity). Would you please help review it. Thanks a lot.
ldap_initialize(&ld, ldapuri); ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol) != LDAP_OPT_SUCCESS); do { rc = ldap_sasl_interactive_bind(ld, NULL, sasl_mech, NULL, NULL, sasl_flags, my_sasl_interact, &auth, res, &rmech, &id); ldap_msgfree(res); if ((type = ldap_result(ld, LDAP_RES_ANY, 1, NULL, &res)) > 0) { parse_ret = ldap_parse_result(ld, res, &errno, NULL, NULL, NULL, NULL, 0); if (parse_ret != LDAP_SUCCESS) { printf("parse result error %d\n", parse_ret); break; } if (errno == LDAP_SUCCESS) { printf("sasl success\n"); break; } else if (errno == LDAP_SASL_BIND_IN_PROGRESS) { printf("sasl in progress\n"); } else { sasl_failed = 1; printf("sasl error\n"); break; } } } while (rc != -1);
ldap_msgfree(res);
if(sasl_failed) { ldap_perror(ld, "ldap_sasl_interactive_bind_s"); ldap_unbind_ext(ld, NULL, NULL); return -1; } printf("going to search\n"); rc = ldap_search_ext(ld, base_dn, LDAP_SCOPE_SUBTREE, "(ObjectClass=person)", NULL, 0, NULL, NULL, NULL, 0, &id); if ((type = ldap_result(ld, LDAP_RES_ANY, 1, NULL, &res)) > 0) { parse_ret = ldap_parse_result(ld, res, &errno, NULL, NULL, NULL, NULL, 0); if (parse_ret != LDAP_SUCCESS) { printf("parse result error %d\n", parse_ret); goto out; } for (e = ldap_first_entry(ld, res); e != NULL; e = ldap_next_entry(ld, e)) { if (ldap_msgtype(e) != LDAP_RES_SEARCH_ENTRY) { printf("non search entry\n"); break; } dn = ldap_get_dn(ld, e); printf("got dn=%s\n", dn); } ldap_msgfree(res); }
openldap-technical@openldap.org