winldap,Qt,ldap_search_ext_s在ldap_sasl_bind_s之后返回“操作错误”

时间:2015-01-21 10:20:30

标签: c++ windows qt ldap

我正在尝试使用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(有一切工作正常......自然=))

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

请帮帮我......会救我的。

1 个答案:

答案 0 :(得分:0)

来自winldap的错误消息不是很好。 事实证明,你需要在LDAP服务器上激活sasl =)。 另外winldap需要你自己实施sasl握手。