LDAP身份validation,ldap_sasl_bind_s无效,但ldap_simple_bind_s有效

我有一个问题,在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对用户进行密码validation?

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

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

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