LDAP验证,ldap_sasl_bind_s不工作,但ldap_simple_bind_s作品 [英] LDAP Authentication, ldap_sasl_bind_s not working but ldap_simple_bind_s works

查看:3451
本文介绍了LDAP验证,ldap_sasl_bind_s不工作,但ldap_simple_bind_s作品的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,即在ldap_sasl_bind_s不起作用,但ldap_simple_bind_s的作品。

I have a problem where in ldap_sasl_bind_s does not work, but ldap_simple_bind_s works.

但奇怪的是,与ldap_sasl_bind_s密码错误,甚至工作,给用户的感觉,他已经进入了正确的密码。

The strange thing is, ldap_sasl_bind_s works even with wrong passwords and gives user the feeling that he has entered a correct password.

PFA code段,并建议我如果有什么不对我的做法。

PFA code snippet of the problem and suggest me if anything is wrong with my approach.

{
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;
}

我已经初始化使用以下code SNIP的LDAP:

I have initialized the LDAP using following code SNIP:

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应该这么说来登录。

I need to be able to login with correct user name and when user tries to enter wrong user name, ldap should say so.

我已经提到以下链接及其相关链接得到这样的结论:

I have referred to following links and their related links to get to this conclusion:

<一个href=\"http://stackoverflow.com/questions/4066265/ldap-how-to-check-a-username-password-combination/4076733#4076733\">LDAP - ?如何检查用户名/密码组合

<一个href=\"http://stackoverflow.com/questions/16168293/how-to-do-password-authentication-for-a-user-using-ldap\">How到使用LDAP用户做密码验证?

推荐答案

DIGEST-MD5 AUTH 不仅仅是发送一个绑定DN和密码更复杂。你需要使用 ldap_sasl_interactive_bind_s ,并提供一个回调使SASL库可以与服务器提供的现时结合您的凭据。

Digest-MD5 auth is more complicated than just sending a bind DN and password. You'll need to use ldap_sasl_interactive_bind_s and provide a callback so the SASL library can combine your credentials with the server-provided nonce.

这code(改编自这篇博客文章)对我的作品针对Active Directory服务器:

This code (adapted from this blog post) works for me against an Active Directory server:

#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;
}

这篇关于LDAP验证,ldap_sasl_bind_s不工作,但ldap_simple_bind_s作品的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆