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

Cat*_*cob 9 ldap sasl gssapi

我正在尝试使用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在需要SIMPLE身份验证时使用- 但我需要使用GSSAPI
  • ldap_sasl_interactive_bind_s在需要其他SASL身份验证机制时使用.但是,ldap_sasl_interactive_bind_sMicrosoft SDK中没有.

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

任何指针将不胜感激.

Cat*_*cob 15

我设法使用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获得 - 这大致是Microsoft的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_SUCCESSLDAP会话的最新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用于授权.

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

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