import java.util.Hashtable;
import java.util.Date;
import java.util.TimeZone;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
public class CheckBind
{
public static final int LENGTH = 42;
public static final int BITS = 336;
public static final int BITSOFFSET = 14;
public static void main( String[] args )
{
if (args.length != 5) {
usage();
}
String hostURL = args[0];
String loginDN = args[1];
String password = args[2];
String userDN = args[3];
String userPWD = args[4];
try {
Hashtable env = new Hashtable(5, 0.75f);
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, hostURL);
env.put(Context.SECURITY_PRINCIPAL, loginDN );
env.put(Context.SECURITY_CREDENTIALS, password );
env.put("java.naming.ldap.attributes.binary","loginAllowedTimeMap");
DirContext ctx = new InitialDirContext(env);
System.out.println();
System.out.println(" User DN: " + userDN );
System.out.println(" Checking bind restrictions...\n");
if ( GetBindInfo( ctx, userDN, userPWD ) )
System.out.println("\n\n User can login now.\n");
else
System.out.println("\n\n User can not login now.\n");
ctx.close();
}
catch (NamingException e) {
System.err.println("CheckBind example failed.");
e.printStackTrace();
}
finally {
System.exit(0);
}
}
public static boolean GetBindInfo( DirContext ctx,
String userDN, String userPWD) {
byte byteValue[] = new byte [0];
Date date = new Date();
boolean cr = true;
String attrName, attrValue, login = null, loginExpTime = null;
String pwdExpTime = null, locked = null;
String locale = date.toString();
try {
System.out.print("\n user's password: ");
SearchControls ctls = new SearchControls();
ctls.setSearchScope( SearchControls.OBJECT_SCOPE );
ctls.setReturningAttributes( new String[0] );
NamingEnumeration sre = ctx.search( userDN, "userPassword="
+ userPWD, ctls );
if ( sre != null && sre.hasMoreElements())
System.out.println(" OK");
else
System.out.println(" password is incorrect");
String returnAttrs[] = {"LoginDisabled",
"loginExpirationTime",
"passwordExpirationTime",
"loginAllowedTimeMap",
"lockedByIntruder",
"title" };
Attributes attrs = ctx.getAttributes( userDN, returnAttrs );
NamingEnumeration enu = attrs.getAll();
while ( (enu != null) && enu.hasMore() ) {
Attribute attr = (Attribute)enu.next();
attrName = attr.getID();
NamingEnumeration attrValues = attr.getAll();
while ( attrValues.hasMore()) {
if ( attrName.equalsIgnoreCase( "loginAllowedTimeMap" ))
byteValue = (byte[])attrValues.next();
else {
attrValue = (String)attrValues.next();
if (attrName.equalsIgnoreCase( "LoginDisabled" ))
login = attrValue;
else if (attrName.equalsIgnoreCase(
"loginExpirationTime"))
loginExpTime = attrValue;
else if (attrName.equalsIgnoreCase(
"passwordExpirationTime"))
pwdExpTime = attrValue;
else if (attrName.equalsIgnoreCase("lockedByIntruder"))
locked = attrValue;
}
}
}
System.out.print("\n 'Logindisabled': ");
if ( (login != null) && (login.length() != 0) ) {
if ( login.equalsIgnoreCase( "FALSE" ) )
System.out.println( " OK." );
else {
System.out.println( " account is disabled." );
cr = false;
}
}
else
System.out.println(" not initialized.");
System.out.print("\n 'loginExpirationTime': ");
if ( (loginExpTime != null) && (loginExpTime.length() != 0) ) {
if ( CompareTime(loginExpTime) )
System.out.println( " OK." );
else {
System.out.println(" Exceeded expiration time." );
System.out.println(" LoninExpirationTime: "
+ loginExpTime + " (UTC)");
PrintLocalTime(loginExpTime);
System.out.println(" Current Locale Time: "
+ locale);
cr = false;
}
}
else
System.out.println(" not initialized.");
System.out.print("\n 'passwordExpirationTime': ");
if ( (pwdExpTime != null) && (pwdExpTime.length() != 0) ) {
if ( CompareTime( pwdExpTime) )
System.out.println( " OK." );
else {
System.out.println(" Exceeded expiration time.");
System.out.println(" passwordExpirationTime: "
+ pwdExpTime + " (UTC)");
PrintLocalTime( pwdExpTime );
System.out.println(" Current Locale Time: "
+ locale);
cr = false;
}
}
else
System.out.println(" not initialized.");
System.out.print("\n 'LoginAllowedTimeMap': ");
if ( (byteValue.length != 0) && (byteValue.length == LENGTH)) {
if ( getTimeRestriction( byteValue, locale) )
System.out.println( " Current time is restricted." );
else {
System.out.println( " OK." );
cr = false;
}
}
else
System.out.println(" not initialized.");
System.out.print("\n 'lockedByIntruder': ");
if ( (locked != null) && (locked.length() != 0) ) {
if ( locked.equalsIgnoreCase( "FALSE" ) )
System.out.println( " OK." );
else {
System.out.println( " lockedout.");
cr = false;
}
}
else
System.out.println(" not initialized.");
}
catch( NamingException e ) {
System.out.println( "\n Error: " + e.toString() );
System.exit(1);
}
return cr;
}
public static void PrintLocalTime( String UTCTime )
{
Date date = null;
DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
TimeZone tz = TimeZone.getTimeZone("UTC");
formatter.setTimeZone(tz);
try {
date = formatter.parse( UTCTime );
}
catch(ParseException pe) {
System.out.println( "\n Error: " + pe.toString() );
}
System.out.print(" ");
System.out.println(date);
}
public static boolean CompareTime( String UTCTime )
{
Date date = null, currentDate = new Date();
DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
TimeZone tz = TimeZone.getTimeZone("UTC");
formatter.setTimeZone(tz);
try {
date = formatter.parse( UTCTime );
}
catch(ParseException pe) {
System.out.println( "\n Error: " + pe.toString() );
}
return date.after(currentDate);
}
public static boolean getTimeRestriction( byte[] byteValues,
String localITime )
{
int i, index = 0;
boolean flags[] = new boolean[BITS], temp1[] = new boolean [BITSOFFSET];
for ( i = 0; i < LENGTH; i++ ) {
if ( (byteValues[i] & 0x01) != 0 )
flags[ i * 8 + 0 ]= true;
if ( (byteValues[i] & 0x02) != 0 )
flags[ i * 8 + 1 ]= true;
if ( (byteValues[i] & 0x04) != 0 )
flags[ i * 8 + 2 ]= true;
if ( (byteValues[i] & 0x08) != 0 )
flags[ i * 8 + 3 ]= true;
if ( (byteValues[i] & 0x10) != 0 )
flags[ i * 8 + 4 ]= true;
if ( (byteValues[i] & 0x20) != 0 )
flags[ i * 8 + 5 ]= true;
if ( (byteValues[i] & 0x40) != 0 )
flags[ i * 8 + 6 ]= true;
if ( (byteValues[i] & 0x80) != 0 )
flags[ i * 8 + 7 ]= true;
}
for ( i = 0; i < BITSOFFSET; i++ )
temp1[i] = flags[i];
for ( i = BITSOFFSET; i < BITS; i++ )
flags[i-BITSOFFSET] = flags[i];
for ( i = 0; i < BITSOFFSET; i++ )
flags[BITS-BITSOFFSET+i] = temp1[i];
String weekDay = localITime.substring( 0, 3 );
String clock = localITime.substring(
localITime.indexOf((int)':') - 2,
localITime.indexOf((int)':') + 3 );
int hour = Integer.parseInt( clock.substring( 0, 2 ));
int minute = Integer.parseInt( clock.substring( 3 ));
int clockIndex = hour * 2 + minute / 30;
if ( weekDay.equalsIgnoreCase( "Sun" ))
index = 0 * 48 + clockIndex;
else if ( weekDay.equalsIgnoreCase( "Mon" ))
index = 1 * 48 + clockIndex;
else if ( weekDay.equalsIgnoreCase( "Tue" ))
index = 2 * 48 + clockIndex;
else if ( weekDay.equalsIgnoreCase( "Wed" ))
index = 3 * 48 + clockIndex;
else if ( weekDay.equalsIgnoreCase( "Thu" ))
index = 4 * 48 + clockIndex;
else if ( weekDay.equalsIgnoreCase( "Fri" ))
index = 5 * 48 + clockIndex;
else if ( weekDay.equalsIgnoreCase( "Sat" ))
index = 6 * 48 + clockIndex;
return !flags[index];
}
public static void usage() {
System.err.println("\n Usage: java CheckBind <host URL> <login dn> "
+ "<password> <user dn>\n <user password>\n\n Example: java "
+ "CheckBind ldap://Acme.com:389 \"cn=Admin,o=Acme\" secret\n"
+ " \"cn=Jsmith,ou=Sales,o=Acme\" userPWD");
System.exit(1);
}
}