2013-04-23 1 views
8

사용자가 LDAP 서버를 통해 인증받는 클라이언트 응용 프로그램 (OpenLDAP 라이브러리 사용)을 작성 중입니다.LDAP를 사용하는 사용자의 비밀번호 인증을 수행하는 방법은 무엇입니까?

다음은 사용자의 userPassword를 비교하지 못하는 하드 코딩 된 프로그램의 샘플입니다. 이 LDAP 서버에 일반의 경우

#include <stdio.h> 
#include <ldap.h> 
#define LDAP_SERVER "ldap://192.168.1.95:389" 

int main(int argc, char **argv){ 
    LDAP  *ld; 
    int   rc; 
    char  bind_dn[100]; 
    LDAPMessage *result, *e; 
    char *dn; 
    int has_value; 

    sprintf(bind_dn, "cn=%s,dc=ashwin,dc=com", "manager"); 
    printf("Connecting as %s...\n", bind_dn); 

    if(ldap_initialize(&ld, LDAP_SERVER)) 
    { 
     perror("ldap_initialize"); 
     return(1); 
    } 

    rc = ldap_simple_bind_s(ld, bind_dn, "ashwin"); 
    if(rc != LDAP_SUCCESS) 
    { 
     fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc)); 
     return(1); 
    } 

    printf("Successful authentication\n"); 

    rc = ldap_search_ext_s(ld, "dc=ashwin,dc=com", LDAP_SCOPE_SUBTREE, "sn=ashwin kumar", NULL, 0, NULL, NULL, NULL, 0, &result); 
    if (rc != LDAP_SUCCESS) { 
     fprintf(stderr, "ldap_search_ext_s: %s\n", ldap_err2string(rc)); 
    } 

    for (e = ldap_first_entry(ld, result); e != NULL; e = ldap_next_entry(ld, e)) { 
     if ((dn = ldap_get_dn(ld, e)) != NULL) { 
      printf("dn: %s\n", dn); 
      has_value = ldap_compare_s(ld, dn, "userPassword", "secret"); 
      switch (has_value) { 
       case LDAP_COMPARE_TRUE: 
        printf("Works.\n"); 
        break; 
       case LDAP_COMPARE_FALSE: 
        printf("Failed.\n"); 
        break; 
       default: 
        ldap_perror(ld, "ldap_compare_s"); 
        return(1); 
      } 
      ldap_memfree(dn); 
     } 
    } 

    ldap_msgfree(result); 
    ldap_unbind(ld); 
    return(0); 
} 

userPassword에, 그것을 작동합니다. MD5로 암호화 된 경우 동일한 암호 인 ldap_compare_s이 실패합니다. 비교하기 위해 일반 텍스트 암호를 전달하기 때문입니다.

이 샘플 프로그램은 어떻게 작동합니까?

내가이 일을 제대로하고 있습니까? ldap_compare_s을 사용하여 LDAP를 통해 사용자를 인증하는 것이 맞습니까?

P .: LDAP를 처음으로 작업합니다.

답변

7

이것은 실제로 LDAP에서 비밀번호 검사를 수행하는 올바른 방법이 아니며, 첫 번째 검색에서 얻은 dn 및 제공된 비밀번호를 사용하여 바인드를 시도해야합니다.

즉 두 번째 바인딩을 수행하여 비밀번호를 확인합니다. 바인드가 실패하면 암호가 올바르지 않습니다.

뭔가 유사로 :

if ((dn = ldap_get_dn(ld, e)) != NULL) { 
     printf("dn: %s\n", dn); 
     /* rebind */ 
     ldap_initialize(&ld2, LDAP_SERVER); 
     rc = ldap_simple_bind_s(ld2, dn, "secret"); 
     printf("%d\n", rc); 
     if (rc != 0) { 
      printf("Failed.\n"); 
     } else { 
      printf("Works.\n"); 
      ldap_unbind(ld2); 
     } 
     ldap_memfree(dn); 
    } 

사용자 이름이 (즉, 사용자 계정에 대한 검색이 실패) 일반적으로 과도한 노출로 간주됩니다 올바르지 피해야한다 나타내는 보안상의 이유로.

+0

답변 해 주셔서 감사합니다. 바인딩 두 번째 완벽하게 작동합니다. 전혀 다른 맥락에서 나는 또 다른 질문을 가지고있다 : 당신은 클라이언트 설계에 대해 더 많은 것을 배우는 것에 관한 어떤 정보원이 있는가? 나는 "암호화"와 "소개"기능을 원합니다. 감사합니다 –

+0

암호화 지원은 연결에 ldaps를 사용하여 수행됩니다. 추천을 추적하기 위해'LDAP_OPT_DEREF'를 사용할 모드로 설정합니다. 클라이언트 설계 ... 불행히도, 대답하기에는 너무 큰 질문입니다. 유일하게 적절한 답변은 '의존적'입니다. – Petesh

+0

많은 정보를 제공해 주셔서 감사합니다! 크게 감사드립니다. :) –

관련 문제