LDAP_SASL_BIND_S(GSSAPI) - 凭证结构应提供的内容
题
我正在尝试使用 ldap_sasl_bind_s
Microsoft LDAP C SDK的方法, GSSAPI 作为身份验证机制。 ldap_sasl_bind_s
期望这些证书是 BERVAL
结构,不透明。
给定一个用户名(或DN)和密码, 我怎么到达 BERVAL
结构体 我应该传给 ldap_sasl_bind_s
?
到目前为止我发现的例子
- 来自其他LDAP C SDK-不是Microsoft的
- 采用
ldap_sasl_bind_s
当需要简单的身份验证时 - 但是我需要使用GSSAPI - 采用
ldap_sasl_interactive_bind_s
当需要其他SASL身份验证机制时。但是,没有ldap_sasl_interactive_bind_s
在Microsoft SDK中。
附带说明,目标是能够在SASL上绑定到各种LDAP服务器。目前:ActiveDirectory和OpenLDAP。
任何指针都将不胜感激。
解决方案
我设法使用GSSAPI执行LDAP SASL绑定 ldap_sasl_bind_s
. 。对于那些有兴趣的人来说,这里有一些指示。
有关客户端和服务器在GSSAPI SASL身份验证期间需要执行的操作的抽象描述, “ Kerberos V5(“ GSSAPI”)简单身份验证和安全层(SASL)机制” RFC应该阅读;具体而言,“身份验证协议交换的客户端”部分很有趣,因为它指示了我们需要执行的一系列操作,以便成功地绑定到Kerberos上的LDAP服务器。
凭证 ldap_sasl_bind_s
期望 - 它们的形式及其含义 - 取决于正在使用的实际身份验证机制,在我们的情况下是Kerberos。
在Microsoft SDK中,Kerberos可以通过SSPI获得 - 大约是GSSAPI的Microsoft实现;与我们特定情况相关的方法是: AcquireCredentialsHandle
, InitializeSecurityContext
, DecryptMessage
, EncryptMessage
LDAP SASL在Kerberos上结合具有3个阶段。
阶段1
称呼 AcquireCredentialsHandle
和 InitializeSecurityContext
.
这里的重要说明:
- 传递给
AcquireCredentialsHandle
指向一个指针SEC_WINNT_AUTH_IDENTITY
包含实际凭据(领域,用户名,密码)或NULL
如果要使用当前线程的凭据 - 目标名称应为映射到LDAP服务器的帐户的SPN
- 打电话时
InitializeSecurityContext
, ,必须请求相互认证。
如果所有重要参数都是正确的 - 有效的凭据,有效的SPN, NULL
输入令牌 - InitializeSecurityContext
通话应返回 SEC_I_CONTINUE_NEEDED
并正确填充输出令牌。此输出令牌的内容应进入 BERVAL
结构体 ldap_sasl_bind_s
期望作为客户凭证。
称呼 ldap_sasl_bind_s
来自输出令牌 InitializeSecurityContext
作为客户凭证。如果所有参数都是正确的 - 空的DN,GSSAPI作为机制名称 - 实际呼叫应返回 LDAP_SUCCESS
LDAP会话的最新LDAP错误应该是 LDAP_SASL_BIND_IN_PROGRESS
.
附带说明,可以通过致电发现LDAP会话的最新LDAP错误 ldap_get_option
在会议上, LDAP_OPT_ERROR_NUMBER
作为选项。
阶段2
成功打电话后 ldap_sasl_bind_s
, ,它的最后一个论点指向 BERVAL
包含服务器凭据的结构。内容的内容 BERVAL
现在应将结构用作第二个调用的输入令牌 InitializeSecurityContext
.
第二个电话给 InitializeSecurityContext
应该返回 SEC_OK
和一个空输出令牌。
此空输出令牌应用作另一个调用的客户凭据 ldap_sasl_bind_s
. 。第二个电话给 ldap_sasl_bind_s
应该返回 LDAP_SUCCESS
, ,由于LDAP会话的最新LDAP错误是 LDAP_SASL_BIND_IN_PROGRESS
.
阶段3
在第二次成功呼吁之后 ldap_sasl_bind_s
, ,它的最后一个论点指向 BERVAL
包含服务器数据的结构。该服务器数据应作为输入 DecryptMessage
. 。如前所述的RFC中指定,解密的数据必须长4个字节。
客户应根据同一RFC中的信息构建其答复。
笔记: :就我而言,我省略了RFC中提到的授权ID。据我了解,空的授权ID也会导致用于授权的身份验证ID。
然后,应将客户端构建的答复作为输入传递给 EncryptMessage
. 。输出 EncryptMessage
然后应通过第三个也是最后一个电话的客户凭据传递呼叫 ldap_sasl_bind_s
.
笔记: :用于使用的MSDN文档 EncryptMessage
在克伯罗斯的领导下,似乎并不完整。 Google的代码搜索应有助于一个工作示例。同样,对于上述流的工作示例,可以咨询桑巴河的源代码。
其他提示
我发现了这个问题。
根据这个线程( https://groups.google.com/group/microsoft.public.active.directory.interfaces/browse_thread/thread/thread/9c13fe85e520f0b4/820a136e136e032946e9?pli=1)有一个错误,其中ldap_sasl_bind_s在Windows XP中返回空服务器凭据。我已经在Windows 2008服务器下测试了我的应用程序,并正确返回了凭据。
来自 太阳 和 MSDN. 。大概,如果您可以尝试创建示例程序,则可能会得到答案
伪代码
struct berval cred;
char mechanism[BUFSIZ];
getline( mechanism, sizeof(mechanism), stdin, "mechanism? " );
getline( passwd, sizeof(passwd), stdin,"credentials? " );
cred.bv_val = passwd;
cred.bv_len = strlen( passwd );
rc = ldap_sasl_bind_s( ld, dn, mechanism, &cred, NULL, NULL, NULL );