//Sample code file: var/ndk/webBuildengine/tmp/viewable_samples/f91a68eb-ad37-4526-92b1-b1938f37b871/GraceLogin.java //Warning: This code has been marked up for HTML

/*******************************************************************************

 * $Novell: GraceLogin.java,v 1.7 2002/07/29 21:17:42 $

 * Copyright (c) 2001 Novell, Inc. All Rights Reserved.

 *

 * THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND

 * TREATIES. USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE

 * AGREEMENT ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS

 * THIS WORK. PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO

 * DEVELOPER A ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE

 * CODE IN ITS PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS

 * TO MARKET, DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF

 * DEVELOPER'S PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR

 * DEVELOPER'S CUSTOMERS WITH RESPECT TO THIS CODE.

 *

 * $name:         GraceLogin.java

 * $description:  If a password has expired and grace logins are enabled, the

 *                bind operation succeeds but uses one grace login. An

 *                application may want to detect this situation and display

 *                a warning message to the user to change his or her password.

 *

 *                In eDirectory 8.5 an interim solution was provided to detect

 *                expired passwords. When a password is expired, a message is

 *                returned in the bind response of the form:

 *                    "NDS error -223"

 *

 *                It is expected that a control will be added in a future

 *                release to allow detection of expired passwords.

 *

 *                If desired, the application can read the user object to obtain

 *                the total and remaining grace logins.

 ******************************************************************************/

import com.novell.ldap.*;

import java.util.Enumeration;

import java.util.Iterator;

import java.io.UnsupportedEncodingException;



public class GraceLogin

{

    public static void main( String[] args )

    {

        if (args.length != 3) {

            System.err.println(

                "Usage:   java GraceLogin <host Name> <login dn> <password>");

            System.err.println(

                "Example: java GraceLogin Acme.com \"cn=Admin,o=Acme\" secret");

            System.exit(1);

        }



        int rc;

        int ldapVersion   = LDAPConnection.LDAP_V3;

        int ldapPort      = LDAPConnection.DEFAULT_PORT;

        String msg;

        String ldapHost   = args[0];;

        String loginDN    = args[1];

        String password   = args[2];

        LDAPConnection conn = new LDAPConnection();



        LDAPResponseQueue queue = null;

        try {

           // Encode the password to UTF-8


            byte[] pw = null;

            try {

                pw = password.getBytes("UTF8");

            } catch( UnsupportedEncodingException ex) {

                System.out.println("Error encoding password: " + ex.toString());

                System.exit(1);

            }

           // connect to the server


            conn.connect( ldapHost, ldapPort );

           // bind to the server. Asynchronous bind is used to


           // get the response and the message from the response


            queue = conn.bind( ldapVersion,

                             loginDN,

                             pw,

                             (LDAPResponseQueue)null );

           // get the bind response


            LDAPResponse rsp = (LDAPResponse)queue.getResponse();

           // get the return code and the message from the response


            rc = rsp.getResultCode();

            msg = rsp.getErrorMessage();



           // is bind successful ?


            if ( rc == LDAPException.SUCCESS )

                System.out.println("Bind is successful.");

            else {

                System.out.println("Bind failed.");

                throw new LDAPException( msg, rc, (String)null );

            }



           // is grace login used? get the message ID from the message


           // and then compare the message ID with "-223"


            if ( msg != null && msg.length() != 0) {

               // message ID starts with '-'


                String messageID = msg.substring(msg.indexOf((int)'-'));

                int lastIndex = messageID.length()-1;



               // strip off the trailing non numeric character(s)


                while ( true ) {

                    int charAscii = (int)messageID.charAt(lastIndex);

                    if ( charAscii >= 48 && charAscii <= 57 )

                        break;

                    int len = lastIndex;

                    lastIndex = lastIndex - 1;

                    messageID = messageID.substring(0, len);

                }



                if ( messageID.compareTo( "-223" ) == 0 ) {

                    System.out.println(

                        "Password is expired for loginDN: " + loginDN);

                    System.out.println("Grace login used:");

                    getGraceLoginInfo(conn, loginDN);

                }

            }



           // do some LDAP operations here then exit


            conn.disconnect();

        }

        catch( LDAPException e ) {

            System.out.println( "Error: " + e.toString() );

            System.exit(1);

        }

        System.exit(0);

    }



   // getGraceLoginInfo() uses read() to get grace login info. The read()


   // returns the entry specified by dn. The entry only contains the


   // attributes specified by returnAttrs


    public static void getGraceLoginInfo( LDAPConnection conn, String dn )

        throws LDAPException

    {

        String attributeName;

        String returnAttrs[] = { "loginGraceRemaining", "loginGraceLimit" };

        Enumeration allValues;

        LDAPAttribute attribute;

        LDAPAttributeSet attributeSet;



        try {

           // read login object and return grace login attrs


            LDAPEntry graceLogin = conn.read( dn, returnAttrs );



           // printout the grace login attrs and values


            attributeSet = graceLogin.getAttributeSet();

            Iterator allAttributes = attributeSet.iterator();



            while(allAttributes.hasNext()) {

                attribute = (LDAPAttribute)allAttributes.next();

                attributeName = attribute.getName();

                allValues = attribute.getStringValues();

                String attrValue = (String) allValues.nextElement();

                System.out.println("  " + attributeName + ": "+ attrValue);

            }

        }

        catch( LDAPException e ) {

            System.err.println( "getGraceLoginInfo() Failed.");

            System.err.println( "Error: " + e.toString() );

            System.exit(1);

        }

    }

}