#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ldap.h>
#if defined(N_PLAT_NLM) && defined(LIBC)
#include <screen.h>
#endif
static char usage[] =
"\nUsage: checkBind <host name> <port number> <login dn> <password> <user DN>"
"\n <user password>"
"\nExample: checkBind Acme.com 389 cn=admin,o=Acme secret cn=test,o=Sales"
"\n userpwd\n";
int checkBindRestrictions( LDAP *, char *, char *, int * );
int getTimeRestriction( unsigned char *, char * );
int compareTime( char *, struct tm * );
void printUTC( char *);
#define LENGTH 42
int main( int argc, char **argv) {
int rc, ldapPort, version, cr = 0;
char *ldapHost, *loginDN, *password, *userDN, *userPWD;
LDAP *ld;
struct timeval timeOut = {10,0};
#if defined(N_PLAT_NLM) && defined(LIBC)
setscreenmode(SCR_NO_MODE);
#endif
if (argc != 7) {
printf("%s", usage);
return (1);
}
ldapHost = argv[1];
ldapPort = atoi(argv[2]);
loginDN = argv[3];
password = argv[4];
userDN = argv[5];
userPWD = argv[6];
version = LDAP_VERSION3;
ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version);
ldap_set_option( NULL, LDAP_OPT_NETWORK_TIMEOUT, &timeOut);
if (( ld = ldap_init( ldapHost, ldapPort )) == NULL) {
printf ( "\n LDAP session initialization failed.");
return( 1 );
}
printf ( "\n New LDAP session initialized.");
rc = ldap_simple_bind_s( ld, loginDN, password );
if ( rc == LDAP_SUCCESS )
printf("\n Bind successful.");
else {
printf("\n ldap_simple_bind_s: %s\n", ldap_err2string( rc ));
ldap_unbind_s ( ld );
return( 1 );
}
printf("\n\n Entry DN: %s", userDN );
printf("\n Checking bind restrictions...\n");
if ( (rc = checkBindRestrictions( ld, userDN, userPWD, &cr) )
== LDAP_SUCCESS ) {
if ( cr == 0 )
printf( "\n\n User can login now.\n\n" );
else
printf( "\n\n User cannot login now.\n\n" );
}
else {
printf( "\n\n Failed to check bind restrictions." );
printf( "\n Error: %s.\n", ldap_err2string( rc ));
}
ldap_unbind_s( ld );
return ( 0 );
}
int checkBindRestrictions( LDAP *ld, char *userDN, char *userPWD, int *cr) {
int rc;
ber_len_t len;
unsigned char *bv;
char **values, *attribute, *localTime, *currentUTC;
time_t ltime;
struct timeval timeOut;
struct tm *gmTime;
BerElement *ber;
BerValue **berValue = NULL;
LDAPMessage *searchResult, *entry;
char *attrs[] = { "LoginDisabled",
"loginExpirationTime",
"passwordExpirationTime",
"loginAllowedTimeMap",
"lockedByIntruder",
NULL };
timeOut.tv_sec = 10L;
timeOut.tv_usec = 0L;
time( <ime );
localTime = strdup( ctime( <ime ) );
localTime[strlen(localTime)-1] = '\0';
gmTime = gmtime( <ime );
currentUTC = strdup(asctime(gmTime));
currentUTC[strlen(currentUTC)-1] = '\0';
printf("\n check user's password: ");
rc = ldap_compare_s( ld,
userDN,
"userPassword",
userPWD);
if ( rc == LDAP_COMPARE_TRUE)
printf(" OK.\n");
else if ( rc == LDAP_COMPARE_FALSE ) {
printf(" User's password is not correct.\n");
*cr = -1;
}
else if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) {
printf(" User has no password.\n");
*cr = -1;
}
else if ( rc == LDAP_NO_SUCH_OBJECT ) {
printf(" User does not exist.\n");
*cr = -1;
}
else {
free( localTime );
free( currentUTC );
return rc;
}
rc = ldap_search_ext_s(
ld,
userDN,
LDAP_SCOPE_BASE,
"(objectclass=*)",
attrs,
0,
NULL,
NULL,
&timeOut,
LDAP_NO_LIMIT,
&searchResult );
if ( rc != LDAP_SUCCESS )
{
free( localTime );
free( currentUTC );
ldap_msgfree( searchResult );
return ( rc );
}
entry = ldap_first_entry( ld, searchResult );
for ( attribute = ldap_first_attribute( ld, entry, &ber );
attribute != NULL;
attribute = ldap_next_attribute( ld, entry, ber ) ) {
if ( strcmp( attribute, "loginAllowedTimeMap") == 0 ) {
berValue = ldap_get_values_len(ld, entry, attribute);
if ( berValue != NULL ) {
len = berValue[0]->bv_len;
printf("\n check 'LoginAllowedTimeMap': ");
if ( (len == LENGTH) &&
((bv = (unsigned char*)berValue[0]->bv_val) != NULL) ) {
if ( getTimeRestriction( bv, localTime) == 0)
printf(" OK.\n");
else {
printf(" has time restriction\n");
*cr = -1;
}
}
else
printf(" 'LoginAllowedTimeMap' not initialized\n");
}
}
else {
if ( ((values = ldap_get_values( ld, entry, attribute)) != NULL) ) {
if ( strcmp( attribute, "LoginDisabled") == 0 ) {
printf("\n check 'Logindisabled': ");
if ( strcmp( values[0], "FALSE" ) == 0 )
printf(" OK.\n");
else {
printf(" the user's account is disabled\n");
*cr = -1;
}
}
else if ( strcmp( attribute, "loginExpirationTime") == 0 ) {
printf("\n check 'loginExpirationTime': ");
if ( compareTime( values[0], gmTime)==0)
printf(" OK.\n");
else {
printf(" exceeded login expiration time.");
printf("\n loginExpirationTime:");
printf(" %s (UTC)", values[0]);
printf("\n ");
printUTC( values[0] );
printf("\n Current Time:");
printf(" %s (UTC)", currentUTC);
printf(" ");
printf(" %s (Local)\n", localTime);
*cr = -1;
}
}
else if ( strcmp( attribute, "passwordExpirationTime") == 0 ) {
printf("\n check 'passwordExpirationTime': ");
if ( compareTime( values[0], gmTime ) ==0)
printf(" OK.\n");
else {
printf("exceeded password expiration time");
printf("\n passwordExpirationTime:");
printf(" %s (UTC)", values[0]);
printf("\n ");
printUTC( values[0] );
printf("\n Current Time:");
printf(" %s (UTC)", currentUTC);
printf("\n ");
printf(" %s (Local)", localTime);
*cr = -1;
}
}
else if ( strcmp( attribute, "lockedByIntruder") == 0 ) {
printf("\n check 'lockedByIntruder': ");
if ( strcmp( values[0], "FALSE" ) == 0 )
printf(" OK.\n");
else {
printf(" intruder detection locked the account\n");
*cr = -1;
}
}
ldap_value_free( values );
}
}
ldap_memfree( attribute );
}
free( localTime );
free( currentUTC );
ber_free( ber, 0);
ldap_msgfree( searchResult );
return rc;
}
int getTimeRestriction( unsigned char *bytes, char *localTime ) {
int i, index, day, hour, minute;
char weekday[4];
unsigned char byte0, byte1, temp;
for ( i = 0, temp = 0; i < LENGTH; i ++, temp = 0 ) {
if ( bytes[i] & 0x80 )
temp |= 0x01;
if ( bytes[i] & 0x40 )
temp |= 0x02;
if ( bytes[i] & 0x20 )
temp |= 0x04;
if ( bytes[i] & 0x10 )
temp |= 0x08;
if ( bytes[i] & 0x08 )
temp |= 0x10;
if ( bytes[i] & 0x04 )
temp |= 0x20;
if ( bytes[i] & 0x02 )
temp |= 0x40;
if ( bytes[i] & 0x01 )
temp |= 0x80;
bytes[i] = temp;
}
byte0 = bytes[0];
byte1 = bytes[1];
for ( i = 2; i < LENGTH; i++ )
bytes[i-2] = bytes[i];
bytes[LENGTH-2] = byte0;
bytes[LENGTH-1] = byte1;
temp = bytes[LENGTH-1] & 0x03;
for ( i = LENGTH - 1; i > 0; i -- ) {
bytes[i] = bytes[i] >> 2;
if ( bytes[i-1] & 0x01 )
bytes[i] |= 0x40;
if ( bytes[i-1] & 0x02 )
bytes[i] |= 0x80;
}
bytes[0] = bytes[0] >> 2;
if ( temp & 0x01 )
bytes[0] |= 0x40;
if ( (temp & 0x02) != 0 )
bytes[0] |= 0x80;
sscanf( localTime + 0, "%s", weekday );
sscanf( localTime + 11, "%d", &hour );
sscanf( localTime + 14, "%d", &minute );
if ( strcmp( weekday, "Sun") == 0 )
day = 0;
else if ( strcmp( weekday, "Mon") == 0 )
day = 1;
else if ( strcmp( weekday, "Tue") == 0 )
day = 2;
else if ( strcmp( weekday, "Wed") == 0 )
day = 3;
else if ( strcmp( weekday, "Thu") == 0 )
day = 4;
else if ( strcmp( weekday, "Fri") == 0 )
day = 5;
else if ( strcmp( weekday, "Sat") == 0 )
day = 6;
index = ( day * 24 + hour ) * 2 + minute / 30;
if ( !(bytes[index / 8] & 1<<(7 - index % 8) ))
return -1;
return ( 0 );
}
int compareTime( char *utc1, struct tm *utc2 ) {
char currentTime[32];
sprintf( currentTime, "%4d%02d%02d%02d%02d%02d%c", utc2->tm_year+1900,
utc2->tm_mon+1, utc2->tm_mday, utc2->tm_hour, utc2->tm_min,
utc2->tm_sec, 'Z' );
if ( strcmp( utc1, currentTime) <= 0 )
return -1;
return ( 0 );
}
void printUTC( char *utc ) {
char *time;
struct tm UTC;
sscanf( utc, "%4d%02d%02d%02d%02d%02d", &UTC.tm_year, &UTC.tm_mon,
&UTC.tm_mday, &UTC.tm_hour, &UTC.tm_min, &UTC.tm_sec );
UTC.tm_year -= 1900;
UTC.tm_mon -= 1;
UTC.tm_isdst = 0;
if ( mktime(&UTC) != (time_t)-1 ) {
time = asctime(&UTC);
time[strlen(time)-1] = '\0';
printf( "%s (UTC)", time );
}
}