Winldap,Qt,ldap_search_ext_s在ldap_sasl_bind_s后返回"Operations Error"

winldap, Qt, ldap_search_ext_s returns "Operations Error" after ldap_sasl_bind_s

本文关键字:ldap 返回 Operations Error bind sasl search ext Winldap Qt      更新时间:2023-10-16

我正在尝试使用Windows上Qt中的winldap库在openldap服务器上进行搜索。我得到的响应是(将值替换为"some*"):

"LDAP using normal connection to ldap://someip:someport" [10:37:30][Debug]"Connected to LDAP successfully" [10:37:30][Debug]"base:ou=someou,dc=somedc,dc=someotherdc, scope:1, filter:(objectClass=*)" [10:37:30][Warning]"Failed to search entries in LDAP server: Operations Error"

服务器出现以下错误:

Jan 21 05:38:35 someservername slapd[2348]: connection_operation: error: SASL bind in progress (tag=99).
Jan 21 05:38:35 someservername slapd[2348]: connection_operation: error: SASL bind in progress (tag=66).

负责连接的代码是:

int LdapInstance::connectToServer()
{
int ret = -1;
int ldapVersion = LDAP_VERSION3;
if(!access.isValid())
{
    qWarning() << QString("Failed to bind LDAP server. Access information invalid");
    lastErrorString = QString("Access information invalid");
    return -4;
}
QString uri;
if(access.useSsl())
{
    uri = QString("ldaps://%1:%2").arg(access.getServer()).arg(access.getPort());
    qDebug() << QString("LDAP using TLS connection to %1").arg(uri);
}
else
{
    uri = QString("ldap://%1:%2").arg(access.getServer()).arg(access.getPort());
    qDebug() << QString("LDAP using normal connection to %1").arg(uri);
}
ld = ldap_init((const PWCHAR)access.getServer().utf16(), access.getPort());
if(ld == NULL)
{
    qWarning() << QString("Failed to init LDAP instance: %1").arg(QString::fromWCharArray(ldap_err2string(ret)));
    lastErrorString = QString::fromWCharArray(ldap_err2string(ret));
    return -1;
}
if((ret = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldapVersion)) != LDAP_SUCCESS)
{
    qWarning() << QString("Failed to set LDAP option: %1").arg(QString::fromWCharArray(ldap_err2string(ret)));
    lastErrorString = QString::fromWCharArray(ldap_err2string(ret));
    return -2;
}
if((ret = ldap_connect(ld, NULL)) != LDAP_SUCCESS)
{
    qWarning() << QString("Failed to connect to LDAP instance: %1").arg(QString::fromWCharArray(ldap_err2string(ret)));
    lastErrorString = QString::fromWCharArray(ldap_err2string(ret));
    return -1;
}
struct berval cred;
cred.bv_len = access.getPasswd().length();
cred.bv_val = (const PCHAR)access.getPasswd().utf16();
if(( ret = ldap_sasl_bind_s(ld,
                            (const PWCHAR)access.getLoginDn().utf16(),
                            L"DIGEST-MD5",
                            &cred,
                            NULL,
                            NULL,
                            NULL)) != LDAP_SUCCESS)
{
    qWarning() << QString("Failed to bind LDAP server %1: %2").arg(access.getLoginDn()).arg(QString::fromWCharArray(ldap_err2string(ret)));
    lastErrorString = QString::fromWCharArray(ldap_err2string(ret));
    return -3;
}
qDebug() << QString("Connected to LDAP successfully");
return 0;
}

搜索功能是:

QList<SimpleFriend *> LdapInstance::getSimpleFriendsByGroup(const QString &group, int *response)
{
Q_ASSERT(!group.isEmpty() && response);
LDAPMessage *message = NULL;
PWCHAR attrList[] = {
    L"displayName",
    L"givenName",
    L"sn",
    L"o",
    L"telephoneNumber",
    L"homePhone",
    L"mobile",
    NULL
};
QList<SimpleFriend *> simpleFrList;
int ret = connectToServer();
if(ret != 0)
{
    qWarning() << QString("Failed to get simple friend list from LDAP server. Connection failed.");
    *response = ret;
    return simpleFrList;
}
QString base = QString("%1,%2").arg(group).arg(access.getBaseDc());
qDebug() << QString("base:%1, scope:%2, filter:%3")
            .arg(base)
            .arg(LDAP_SCOPE_ONELEVEL)
            .arg(access.getSearchFilter());
// HERE BE DRAGONS =(
if((ret = ldap_search_ext_s(ld,
                            (const PWCHAR)base.utf16(),
                            LDAP_SCOPE_ONELEVEL,
                            (const PWCHAR)access.getSearchFilter().utf16(),
                            NULL,//attrList,
                            0,
                            NULL,
                            NULL,
                            NULL,
                            0,
                            &message)) != LDAP_SUCCESS)
{
    qWarning() << QString("Failed to search entries in LDAP server: %1").arg(QString::fromWCharArray(ldap_err2string(ret)));
    lastErrorString = QString::fromWCharArray(ldap_err2string(ret));
    *response = ret;
    closeConnection();
    return simpleFrList;
}
//... some processing
ldap_msgfree(message);
closeConnection();
*response = 0;
return simpleFrList;
}

我不知道我做错了什么。我正在将所有内容转换为 PCHAR 和 PWCHAR,然后再将其传递给 winldap 函数。

我使用 openldap 库将其从我的 Linux 实现移植到 Windows(那里一切正常......自然=))

可能是服务器需要一些额外的信息才能完全绑定吗?但是什么?

请帮帮我...会拯救我的一天。

来自 winldap 的错误消息不是很好。事实证明,您需要在LDAP服务器上共享sasl=)。此外,winldap 需要您自己实现 sasl 握手。