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

 * $Novell: ModifyTimeStamp.java,v 1.8 2003/08/21 11:36:58 $

 * 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:         ModifyTimeStamp.java

 * $description:  ModifyTimeStamp.java shows how to modify an

 *                attribute's value in LDAP Timestamp format.

 *

 *                LDAP Timestamp is in the form of "yyyymmddhhmmssZ". The

 *                date and time specified in LDAP Timestamp is based on the

 *                Coordinated Universal Time (UTC). The date and time

 *                "Mon Jul 30 17:42:00 2001"  is represented in LDAP Time-

 *                stamp as "20010730174200Z".

 *

 *                ModifyTimeStamp.java modifies a user's passwordExpira-

 *                tionTime attribute for example. It first displays the user's

 *                passwordExpirationTime, then modifys user's passwordExpira-

 *                tionTime attribute, and finally displays newly modified

 *                passwordExpirationTime.

 *

 *                Before running this sample, the passwordExpirationTime

 *                attribute should be initialized.

 *

 *                The last parameter to this sample is an integer representing

 *                the number of days to extend the user's passwordExpiration-

 *                Time. It can be a positive, a zero, or a negative value.

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

import com.novell.ldap.LDAPConnection;

import com.novell.ldap.LDAPAttribute;

import com.novell.ldap.LDAPAttributeSet;

import com.novell.ldap.LDAPEntry;

import com.novell.ldap.LDAPModification;

import com.novell.ldap.LDAPException;

import java.util.Date;

import java.util.Calendar;

import java.util.Enumeration;

import java.util.Iterator;

import java.util.TimeZone;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.text.ParsePosition;

import java.text.ParseException;

import java.io.UnsupportedEncodingException;



public class ModifyTimeStamp

{

    public static void main( String[] args )

    {

        if (args.length != 6) {

            System.err.println("Usage:   java ModifyTimeStamp <host Name>"

                        + " <port number> <login dn> <password>"

                        + "\n         <user dn> <day extension>");

            System.err.println("Example: java ModifyTimeStamp Acme.com 389"

                               + " \"cn=Admin,o=Acme\" secret\n"

                               + "         \"cn=JSmith,ou=sales,o=Acme\""

                               + " 90");

            System.exit(1);

        }



        int    ldapVersion = LDAPConnection.LDAP_V3;

        String ldapHost    = args[0];

        int    ldapPort    = Integer.parseInt(args[1]);

        String loginDN     = args[2];

        String password    = args[3];

        String userDN      = args[4];

        int    days        = Integer.parseInt( args[5]);

        String expTime     = null;

        LDAPConnection lc  = new LDAPConnection();



        try {

            // connect to the server

            lc.connect( ldapHost, ldapPort );

            // bind to the server

            lc.bind( ldapVersion, loginDN, password.getBytes("UTF8") );



            System.out.println( "\n    Entry DN: " + userDN );

            System.out.println( "    Day Extension: " + days + "\n" );

            // get user's passwordExpirationTime value

            if ( (expTime = GetTime( lc, userDN )) == null )

                System.out.println("\n    passwordExpirationTime was not"

                                                           + " initialized.");

            else {

                System.out.println( "        Current passwordExpirationTime: "

                                                        + expTime + " (UTC)");

                printTime(expTime);



                // update passwordExpirationTime value

                String newExpTime = extendTime( expTime, days );



                // prepare to modify the user's passwordExpirationtime

                LDAPAttribute pwdExpTime = new LDAPAttribute(

                                         "passwordExpirationTime", newExpTime );



                // modify the user's passwordExpirationTime attribute

                System.out.println( "\n        Modifying"

                                          + " passwordExpirationTime ...");

                lc.modify( userDN,

                   new LDAPModification( LDAPModification.REPLACE, pwdExpTime));

                System.out.println( "        Successfully modified "

                                              + " passwordExpiratioTime.");



                // display user's new passwordExpirationTime value

                if ( (newExpTime = GetTime( lc, userDN )) == null )

                    System.out.println("\n    Failed to get"

                                           + " passwordExpirationTime value.");

                else {

                    System.out.println( "\n        New    "

                        + " passwordExpirationTime: " + newExpTime + " (UTC)");

                    printTime(newExpTime);

                }

            }



            lc.disconnect();

        }

        catch( LDAPException e ) {

            System.err.println( "ModifyTimeStamp example failed");

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

            System.exit(1);

        }

        catch( UnsupportedEncodingException e ) {

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

        }



        System.exit(0);

    }



    // getTime() search the directory and returns the

    // passwordExpirationTime value in LDAP Timestamp format.

    public static String GetTime(LDAPConnection lc, String userDN)

    {

        Enumeration allValues;

        LDAPAttribute attribute;

        LDAPAttributeSet attributeSet;

        String attrValue = null, attributeName;

        String returnAttr[] = { "passwordExpirationTime" };



        try {

            // read the entry

            LDAPEntry entry = lc.read( userDN, returnAttr );



            // find passwordExpirationTime value

            attributeSet = entry.getAttributeSet();

            Iterator allAttributes = attributeSet.iterator();

            while(allAttributes.hasNext()) {

                attribute = (LDAPAttribute)allAttributes.next();

                attributeName = attribute.getName();

                allValues = attribute.getStringValues();

                attrValue = (String) allValues.nextElement();

            }

        }

        catch( LDAPException e ) {

            System.out.println( "Failed to read: " + userDN );

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

            return null;

        }

        return attrValue;

    }



    // printTime() takes utc as input and prints it in text format

    public static void printTime( String utc )

    {

        // setup x.208 generalized time formatter

        DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss'Z'");



        try {

            // parse utc into Date

            Date date = formatter.parse( utc );

            System.out.print( "                                        ");

            System.out.println( date + " (UTC)");

        }

        catch(ParseException pe) {

            System.out.println( "\nError: " + pe.toString() );

        }

    }



    // extendTime() takes utc and days as input and returns updated utc

    public static String extendTime( String utc, int days )

    {

        // utc is in the form of "20010706080000Z". get year,

        // month, day, hour, minute, and second from the utc

        int year   = Integer.parseInt( utc.substring(  0, 4  ));

        int mon    = Integer.parseInt( utc.substring(  4, 6  ));

        int day    = Integer.parseInt( utc.substring(  6, 8  ));

        int hour   = Integer.parseInt( utc.substring(  8, 10 ));

        int minute = Integer.parseInt( utc.substring( 10, 12 ));

        int second = Integer.parseInt( utc.substring( 12, 14 ));



        Calendar utcTime = Calendar.getInstance();

        // set calendar to the time

        utcTime.set( year, mon-1 , day, hour, minute, second );

        // add days to the expiration Time

        utcTime.add(Calendar.DAY_OF_MONTH, days );

        Date date = utcTime.getTime();

        DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss'Z'");

        // format date into LDAP Timestamp

        return formatter.format( date );

    }

}

