简体   繁体   中英

How to do password authentication for a user using LDAP?

I am writing a client app (using OpenLDAP libraries) for which the users gets authenticated via LDAP server.

Here is the sample, hard coded, program that fails to compare userPassword for a user.

#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 if it is plain in LDAP server, it works. the same password if it is MD5 encrypted, ldap_compare_s fails. And that's because I am passing the cleartext password to compare.

How do I get this sample program working?

Am I doing this right? Is it correct to use ldap_compare_s to authenticate user via LDAP?

PS: This is the first time I am working on LDAP.

This is not really the right way to perform a password check on LDAP, what you should do is attempt to bind using the dn obtained from the first search and the password supplied.

ie you perform a second bind to verify the password. If the bind fails then the password is incorrect.

Something akin to:

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

For security reasons indicating that the username is incorrect (ie the search for the user account fails) is generally considered excessive disclosure, and should be avoided.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM