我正在尝试使用 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

称呼 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.

阶段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 );
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top