2013-04-23 10 views
8

私は、LDAPサーバー経由でユーザーが認証されるクライアントアプリケーション(OpenLDAPライブラリを使用)を作成しています。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 .: LDAPで作業しているのは初めてです。

答えて

7

これは実際にLDAPでパスワードチェックを実行する正しい方法ではなく、最初の検索で取得したdnとパスワードを使用してバインドを試みます。

つまり、パスワードを確認するために2番目のバインドを実行します。バインドに失敗した場合、パスワードは正しくありません。

何か似へ:

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

usernameが(すなわち、ユーザアカウントの検索に失敗した)一般的に、過剰な開示と考えられている間違っている、と避けるべきであることを示すセキュリティ上の理由から。

+0

あなたの答えをありがとう。 2度目のバインディングは完璧です。まったく異なる状況では、別の質問があります。クライアントの設計についてもっと学ぶための情報源はありますか?私は "暗号化"と "紹介"のための機能を持っていたい。ありがとう –

+0

暗号化のサポートは、接続にldapsを使用して行います。照会を追跡するために、 'LDAP_OPT_DEREF'を使用するモードに設定します。クライアントの設計...残念ながら、答えるには大きすぎる質問です。適切な唯一の答えは「それは依存する」です。 – Petesh

+0

多くの情報に感謝します!大変感謝しています。 :) –

関連する問題