ldap_sasl_bind_s(GSSAPI) - 在凭证BERVAL结构中应该提供什么

时间:2010-06-29 21:30:54

标签: ldap sasl gssapi

我正在尝试使用Microsoft LDAP C SDK中的ldap_sasl_bind_s方法,并使用 GSSAPI 作为身份验证机制。 ldap_sasl_bind_s期望凭据为BERVAL结构,这是不透明的。

鉴于用户名(或DN)和密码,如何进入我应该传递给BERVAL的{​​{1}}结构

到目前为止我找到的例子

  • 来自其他LDAP C SDK - 而不是来自Microsoft的
  • 在需要SIMPLE身份验证时使用ldap_sasl_bind_s - 但我需要使用GSSAPI
  • 在需要其他SASL身份验证机制时使用ldap_sasl_bind_s。但是,Microsoft SDK中没有ldap_sasl_interactive_bind_s

作为旁注,目标是能够通过SASL绑定到各种LDAP服务器;目前:ActiveDirectory和OpenLDAP。

任何指针都将非常感激。

3 个答案:

答案 0 :(得分:14)

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

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

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

在Microsoft SDK中,Kerberos可通过SSPI获得 - 这大致是Microsoft的GSSAPI实现;与我们的具体案例相关的方法有:AcquireCredentialsHandleInitializeSecurityContextDecryptMessageEncryptMessage

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

第1阶段

致电AcquireCredentialsHandleInitializeSecurityContext 重要说明:

  • 传递给AcquireCredentialsHandle指向包含实际凭据(领域,用户名,密码)的SEC_WINNT_AUTH_IDENTITY结构的指针,或NULL如果要使用当前线程的凭据< / LI>
  • 目标名称应该是映射到运行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_get_option来发现LDAP会话的最新LDAP错误,并选择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

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

答案 1 :(得分:2)

我发现了问题。

根据此主题(https://groups.google.com/group/microsoft.public.active.directory.interfaces/browse_thread/thread/9c13fe85e520f0b4/820a136e032946e9?pli=1),ldap_sasl_bind_s在Windows XP中返回空服务器凭据时出现错误。我已在Windows 2008 Server下测试了我的应用程序,并且正确返回了凭据。

答案 2 :(得分:0)

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

Another One

伪代码

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 );