2013-04-23 10 views
8

Sto scrivendo un'app client (utilizzando le librerie OpenLDAP) per cui gli utenti vengono autenticati tramite il server LDAP.Come eseguire l'autenticazione della password per un utente che utilizza LDAP?

Ecco il programma di esempio, codificato, che non riesce a confrontare userPassword per un utente.

#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 se è chiaro a server LDAP, funziona. la stessa password se è crittografata con MD5, ldap_compare_s non riesce. E questo perché sto passando la password in chiaro per confrontare.

Come si ottiene il funzionamento di questo programma di esempio?

Sto facendo bene? È corretto utilizzare ldap_compare_s per autenticare l'utente tramite LDAP?

P.S: Questa è la prima volta che lavoro su LDAP.

risposta

7

Questo non è davvero il modo giusto per eseguire un controllo password su LDAP, cosa si dovrebbe fare è il tentativo di legare con il dn ottenuto dalla prima ricerca e la password fornita.

Ad esempio, si esegue una seconda associazione per verificare la password. Se il bind fallisce, la password non è corretta.

qualcosa di simile a:

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

Per ragioni di sicurezza che indicano che il nome utente non è corretto (vale a dire la ricerca per l'account utente non riesce) è generalmente considerata eccessiva divulgazione, e deve essere evitato.

+0

Grazie per la risposta. La seconda volta vincolante funziona perfettamente. In un contesto totalmente diverso, ho un'altra domanda: hai qualche fonte per saperne di più sulla progettazione di un cliente? Voglio avere la funzionalità per "crittografia" e "referral". Grazie –

+0

Il supporto per la crittografia si ottiene utilizzando ldaps per le connessioni. per inseguire i referral, si imposta 'LDAP_OPT_DEREF' su quale modalità si desidera utilizzare. Progettare i clienti ... Questa, purtroppo, è una domanda troppo grande per rispondere. L'unica risposta appropriata è "dipende". – Petesh

+0

Mille grazie per le informazioni! È molto apprezzato :) –

Problemi correlati