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);
        }