2013-04-23 118 views
8

我正在編寫一個客戶端應用程序(使用OpenLDAP庫),用戶通過LDAP服務器進行身份驗證。如何爲使用LDAP的用戶進行密碼驗證?

下面是示例,硬編碼的程序,無法比較用戶的userPassword。

#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如果是在LDAP服務器平原,它的工作原理。 相同的密碼,如果它是MD5加密,ldap_compare_s失敗。這是因爲我傳遞了明文密碼進行比較。

如何獲得此示例程序的工作?

我正在做這個對嗎?使用ldap_compare_s通過LDAP對用戶進行身份驗證是否正確?

P.S:這是我第一次使用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

感謝您的回答。第二次裝訂完美。在完全不同的背景下,我還有另外一個問題:您是否有更多關於設計客戶的信息?我想擁有「加密」和「推介」的功能。謝謝 – 2013-04-23 13:35:17

+0

加密支持是通過使用ldaps進行連接來完成的。爲了追逐引薦,您將「LDAP_OPT_DEREF」設置爲您想要使用的模式。設計客戶......不幸的是,這個問題太大而無法回答。唯一合適的答案是'它取決於'。 – Petesh 2013-04-23 14:05:07

+0

非常感謝您的信息!非常感謝。 :) – 2013-04-23 14:37:45