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

 * $Novell: SimplePassword.java,v 1.1 2003/09/17 06:35:55 $

 * Copyright (C) 1999, 2000, 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:          SimplePassword.java

 * $description:   Shows how to set the simple password of an entry.  

 *               

 *               The simple password is set by modifying the 'userpassword'

 *               attribute and attaching the Simple Password control to

 *               the LDAP add or modify operation.

 *               

 *               The purpose of the Simple Password is to allow migration 

 *               of an object with a hashed password into eDirectory.

 *               The object may then be accessed using the same password as 

 *               in the orginal system.

 *               

 *               Simple Passwords are also used when binding with the

 *               DIGEST-MD5 SASL mechanism.

 *               

 *               The simple password value may be specified as the original 

 *               clear text password, or as the result of hashing the password

 *               with the Secure Hash (SHA), Salted Secure Hash (SSHA), 

 *               digest-md5 (MD5) or Unix Crypt (CRYPT) algorithm.  

 *               A hashed password is represented as a text string consisting

 *               of a prefix indicating the hashing algorithm used, followed

 *               by the base-64 encoding the the binary hash result.

 *               

 *               Valid prefixes are  {SHA}, {SSHA}, {MD5}, or {CYRPT}. 

 *               Example:  "{SHA}qUqP5cyxm6YcTAhz05Hph5gvu9M="

 *               

 *               Note:  For simplicity this sample uses a clear text connection 

 *               to the server.  Real applications should use a TLS/SSL 

 *               (encrypted) connection when setting a password, so that

 *               the password or its hash value is not sent on the wire

 *               as clear text.

 *               

 *               If the DIGEST-MDG SASL mechanism is to be used to authenticate

 *               users, the simple password must be stored as clear text (not

 *               hashed.)

 *               

 *

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

import com.novell.ldap.*;

import java.io.UnsupportedEncodingException;



public class SimplePassword 

{



    private static String  simplePassOID="2.16.840.1.113719.1.27.101.5";

  

    public static void main( String[] args )

    {

        if (args.length != 6) {

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

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

                    + " <new user password>");

            System.err.println("\n Example: java SimplePassword Acme.com 389"

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

                       + "         \"cn=JSmith,ou=sales,o=Acme\" userPWD");

            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];

        String userPWD     = args[5];





    /* Simple Password control.  There is no value  associated with this control,

     * just an OID and criticality. Setting the criticality to TRUE means the

     * server will return an error if it does not recognize or is unable to

     * perform the control. 

     */



        LDAPControl cont = new LDAPControl(simplePassOID,

                                           true,

                                           null);  

        LDAPConstraints lcons = new LDAPConstraints();

        lcons.setControls(cont);

        

        LDAPConnection lc  = new LDAPConnection();



        try {

            // connect to the server

            lc.connect( ldapHost, ldapPort );

            // bind to the server

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



            //  Modify the 'userpassword' attribute, with the Simple

            // Password control.

            LDAPModification[] modifications = new LDAPModification[1];             

            LDAPAttribute sPassword = new LDAPAttribute( "userPassword",userPWD);

            modifications[0] =

                new LDAPModification( LDAPModification.REPLACE, sPassword);



            lc.modify( userDN, modifications,lcons);



            System.out.println("Your Simple password has been modified.");



            lc.disconnect();

        }

        catch( LDAPException e ) {

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

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

            System.exit(1);

        }

        catch( UnsupportedEncodingException e ) {

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

        }

        System.exit(0);

    }

}            

