[Date Prev][Date Next]
[Chronological]
[Thread]
[Top]
Re: ldap() in shared objects...
Jason Gerfen wrote:
I have compiled a shared object (PAM module to be exact) which
utilizes some ldap() API calls. I have noticed a discrepency in
making a call to ldap_simple_bind_s().
According to the man pages for ldap_simple_bind_s() I need to do a
check against LDAP_SUCCESS as a returned status message.
here is the code I am using for a regular binary:
/* open a connection & failover if necessary */
z = 0;
ld = ldap_init( servs[z], LDAP_PORT );
while( ldap_simple_bind_s( ld, "username", "password" ) !=
LDAP_SUCCESS ) {
rc = ldap_result( ld, msgid, z, &zerotime, &res );
where do you get the msgid? what's that call to ldap_result() for?
ldap_result() must be called only after an ASYNCHRONOUS call,
while ldap_simple_bind_s() is SYNCHRONOUS.
if( ( z < 5 ) || ( rc == -1 ) ) {
ld = ldap_init( servs[z], LDAP_PORT );
}
printf( "Bind failed on: %s\n", servs[z]);
z++;
}
ldap_perror( ld, "ldap_simple_bind_s");
This works fine,
I can hardly believe it.
now if I perform the same check as a shared object any attempt to
check against LDAP_SUCCESS fails, as of yet i have only been able to
do the following to get it to work:
/* open a connection & failover if necessary */
z = 0;
ld = ldap_init( servs[z], LDAP_PORT );
while( ! ldap_simple_bind_s( ld, "ldapaccess", "access6ldap" ) ) {
note that you can't bind with "username" or "ldapaccess"; you need to
turn that
into a valid DN, because ldap_*_bind_*() calls (and the LDAP BIND operation
they implement) require a DN as user identifier. Please read the API
documentation.
rc = ldap_result( ld, msgid, z, &zerotime, &res );
if( ( z < 5 ) || ( rc == -1 ) ) {
ld = ldap_init( servs[z], LDAP_PORT );
}
printf( "Bind failed on: %s\n", servs[z]);
z++;
}
ldap_perror( ld, "ldap_simple_bind_s");
has anyone else ran into this problem?
here are my compile commands if this is necessary:
binary: gcc -o search ldap.c -lldap
shared object: gcc -fPIC -o pam_ldap.o -c pam_ldap.c
ld -x --shared -o pam_ldap.so pam_ldap.o
-lpam -lldap
If what you intend to do is some sort of failover, in case one of the
hosts is down,
all you need to do is provide ldap_init() a space separated list of
hosts, like
"host1 host2 host#" (I suggest you also look at the ldap_initialize()
call, which
I note is currently undocumented).
Your code should look like
/*
* This code comes with no copyright nor WARRANTY
*/
#include <stdio.h>
#include <ldap.h>
extern char *username2dn( char * );
int
your_func(void)
{
LDAP *ld;
int rc;
char *hosts = "host1 host2 host#"; /* to be read from config */
int port = LDAP_PORT; /* to be read from config */
char *username, *credentials; /* you get these from PAM */
char *dn;
ld = ldap_init( hosts, port );
if ( ld == NULL ) {
/* error; handle it! */
}
/* you need a way to turn PAM's username into a valid DN by
implement this function */
dn = username2dn( username );
if ( dn == NULL ) {
/* error; handle it! */
}
rc = ldap_simple_bind_s( ld, dn, credentials );
/* do all cleanup here */
switch ( rc ) {
case LDAP_SUCCESS:
/* authenticated; take measures */
puts( "success\n" );
break;
case LDAP_INVALID_CREDENTIALS:
/* not authenticated; take measures */
puts( "invalid credentials\n" );
break;
default:
/* something happened; trap all protocol/API errors that may be
significant to you */
printf( "%s\n", ldap_str2error() );
break;
}
return 0;
}
SysNet - via Dossi,8 27100 Pavia Tel: +390382573859 Fax: +390382476497