11

我正在尝试使用ldap_sasl_bind_sMicrosoft 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_sMicrosoft SDK 中没有。

附带说明一下,目标是能够通过 SASL 绑定到各种 LDAP 服务器;现在:ActiveDirectory 和 OpenLDAP。

任何指针将不胜感激。

4

3 回答 3

16

我设法通过 GSSAPI 执行 LDAP SASL 绑定,使用ldap_sasl_bind_s. 对于那些感兴趣的人,这里有一些指示。

对于客户端和服务器在 GSSAPI SASL 身份验证期间需要执行的操作的抽象描述,应阅读“Kerberos V5(“GSSAPI”)简单身份验证和安全层(SASL)机制” RFC;具体来说,“身份验证协议交换的客户端”部分很有趣,因为它指示了我们需要执行的操作序列,以通过 Kerberos 成功绑定到 LDAP 服务器。

凭证的ldap_sasl_bind_s期望——它们的形式和意义——取决于所使用的实际身份验证机制,在我们的例子中是 Kerberos。

在微软 SDK 中,Kerberos 是通过 SSPI 提供的——大致是微软对 GSSAPI 的实现;与我们的特定案例相关的方法是:AcquireCredentialsHandle, InitializeSecurityContext, DecryptMessage,EncryptMessage

基于 Kerberos 的 LDAP SASL 绑定有 3 个阶段。

阶段1

呼叫AcquireCredentialsHandleInitializeSecurityContext
这里的重要说明:

  • 传递到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

第三阶段

在第二次成功调用 之后ldap_sasl_bind_s,它的最后一个参数指向一个BERVAL包含服务器数据的结构。该服务器数据应作为输入提供给DecryptMessage. 正如前面提到的 RFC 中所规定的,解密后的数据必须是 4 个字节长。

客户端应根据同一 RFC 中的信息构建其回复。
注意:就我而言,我省略了 RFC 中提到的授权 ID。据我了解,一个空的授权 id 会导致身份验证 id 也被用于授权。

然后,客户端构建的回复应作为输入传递给EncryptMessage. EncryptMessage然后应将调用的输出作为第三次也是最后一次调用的客户端凭据传递给ldap_sasl_bind_s.

注意:在 Kerberos 下使用的 MSDN 文档EncryptMessage似乎不完整。谷歌的代码搜索应该有助于提供一个工作示例。此外,对于上述流程的工作示例,可以查阅 Samba 的源代码。

于 2010-08-08T08:05:38.707 回答
2

我发现了问题。

根据这个线程(https://groups.google.com/group/microsoft.public.active.directory.interfaces/browse_thread/thread/9c13fe85e520f0b4/820a136e032946e9?pli=1)有一个错误 ldap_sasl_bind_s 返回空服务器凭据视窗XP。我已经在 Windows 2008 Server 下测试了我的应用程序,并且正确返回了凭据。

于 2011-01-31T13:33:32.207 回答
0

来自SunMSDN的文章。如果您可以尝试创建一个示例程序,您可能会得到答案

另一个

伪代码

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 );
于 2010-08-07T21:29:55.987 回答