1

我有一个问题,其中 ldap_sasl_bind_s 不起作用,但 ldap_simple_bind_s 有效。

奇怪的是,ldap_sasl_bind_s 即使在密码错误的情况下也能工作,并让用户感觉他输入了正确的密码。

问题的 PFA 代码片段,如果我的方法有任何问题,请建议我。

{
int rc, aReturnVal = 0;
NSString *aUserDN = [NSString stringWithFormat:@"uid=%s,cn=users,dc=example,dc=com", username];
char* userDN = (char*)[aUserDN UTF8String];
rc = ldap_simple_bind_s (
                       ld,
                       userDN,
                       password
                       );

    // TODO: ldap_simple_bind_s is a deprecated method and should not be used for long. ldap_sasl_bind_s is the right method, but is not working for now.
    // Find the reason and get this code up and running.
//  struct berval *servcred;
//  struct berval cred;
//  cred.bv_val = password; // my password
//  cred.bv_len = strlen(password);
//  rc = ldap_sasl_bind_s (
//               ld,
//               userDN,
//               "DIGEST-MD5",
//               &cred,
//               NULL,
//               NULL,
//               &servcred
//             );

if ( rc != LDAP_SUCCESS ) {
    fprintf( stderr, "ldap_sasl_bind: %s\n", ldap_err2string( rc ) );
} else {
    aReturnVal = 1;
}

return aReturnVal;
}

我已经使用以下代码 SNIP 初始化了 LDAP:

rc = ldap_initialize(&ld, HOSTNAME);
version = LDAP_VERSION3;
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
ldap_set_option( ld, LDAP_OPT_REFERRALS, 0 );

我需要能够使用正确的用户名登录,当用户尝试输入错误的用户名时,ldap 应该这样说。

我参考了以下链接及其相关链接来得出这个结论:

LDAP - 如何检查用户名/密码组合?

如何为使用 LDAP 的用户进行密码验证?

4

1 回答 1

1

Digest-MD5 身份验证比仅发送绑定 DN 和密码更复杂。您需要使用ldap_sasl_interactive_bind_s并提供回调,以便 SASL 库可以将您的凭据与服务器提供的 nonce 结合起来。

此代码(改编自此博客文章)适用于我的 Active Directory 服务器:

#include <stdio.h>
#include <stdlib.h>
#include <ldap.h>
#include <sasl/sasl.h>

typedef struct
{
  char *username;
  char *password;
} my_authdata;

int my_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *in)
{
  my_authdata *auth = (my_authdata *)defaults;
  sasl_interact_t *interact = (sasl_interact_t *)in;
  if(ld == NULL) return LDAP_PARAM_ERROR;

  while(interact->id != SASL_CB_LIST_END)
  {
    char *dflt = (char *)interact->defresult;

    switch(interact->id)
    {
      case SASL_CB_GETREALM:
        dflt = NULL;
        break;
      case SASL_CB_USER:
      case SASL_CB_AUTHNAME:
        dflt = auth->username;
        break;
      case SASL_CB_PASS:
        dflt = auth->password;
        break;
      default:
        printf("my_sasl_interact asked for unknown %ld\n",interact->id);
    }

    interact->result = (dflt && *dflt) ? dflt : (char *)"";
    interact->len = strlen((char *)interact->result);
    interact++;
  }

  return LDAP_SUCCESS;
}

int main(int argc, char *argv[])
{
  if(argc < 3)
  {
    fprintf(stderr, "Usage: dmd5-bind [username] [password]\n");
    return -1;
  }

  int rc;
  LDAP *ld = NULL;

  static my_authdata auth;
  auth.username = argv[1];
  auth.password = argv[2];

  char *sasl_mech = ber_strdup("DIGEST-MD5");
  char *ldapuri = ber_strdup("ldap://your.server.name.here");

  int protocol = LDAP_VERSION3;
  unsigned sasl_flags = LDAP_SASL_QUIET;
  char *binddn = NULL;

  rc = ldap_initialize(&ld, ldapuri);
  if(rc != LDAP_SUCCESS)
  {
    fprintf(stderr, "ldap_initialize: %s\n", ldap_err2string(rc));
    return rc;
  }


  if(ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &protocol) != LDAP_OPT_SUCCESS)
  {
    fprintf(stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", protocol);
    return -1;
  }

  rc = ldap_sasl_interactive_bind_s(ld,
                                    binddn,
                                    sasl_mech,
                                    NULL,
                                    NULL,
                                    sasl_flags,
                                    my_sasl_interact,
                                    &auth);

  if(rc != LDAP_SUCCESS)
  {
    ldap_perror(ld, "ldap_sasl_interactive_bind_s");
    ldap_unbind_ext_s(ld, NULL, NULL);
    return rc;
  }

  fprintf(stdout, "Authentication succeeded\n");

  rc = ldap_unbind_ext_s(ld, NULL, NULL);
  sasl_done();
  sasl_client_init(NULL);

  return rc;
}
于 2013-05-02T17:15:43.147 回答