Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to change user password on IBM System i (aka iSeries / AS400) using SQL?

I have a C#.NET application that must be able to change the user password on an IBM System i (iSeries / AS400) machine. I am currently using the following code to perform this operation using IBM's proprietary cwbx.dll.

using cwbx;

public void ChangePassword(string system, string user, string currentPassword, string newPassword)
{
    AS400System as400 = new AS400System();
    as400.Define(system);
    try
    {
        as400.ChangePassword(user, currentPassword, newPassword);
    }
    finally
    {
        as400.Disconnect(cwbcoServiceEnum.cwbcoServiceAll);
    }
}

This works well enough, but forces me (and all users of the application) to take a proprietary dependency on cwbx.dll. I would like to eliminate this dependency.

Is there any way to change the password using SQL similar to MS SQL Server's alter login mechanism?

I know I can accomplish this with the IBM.Data.DB2.iSeries .NET data provider by invoking programs from SQL using the following code from Integrating DB2 Universal Universal Database for iSeries with for iSeries with Microsoft ADO .NET.

/// <summary>
/// Call a program directly on the iSeries with parameters
/// </summary>
public string CallPgm(string cmdtext)
{
    string rc = " ";

    // Construct a string which contains the call to QCMDEXC.
    // Because QCMDEXC uses single quote characters, we must
    // delimit single quote characters in the command text
    // with an extra single quote.
    string pgmParm = "CALL QSYS/QCMDEXC('"
    + cmdtext.Replace("'", "''")
    + "', "
    + cmdtext.Length.ToString("0000000000.00000")
    + ")";

    // Create a command to execute the program or command.
    iDB2Command cmd = new iDB2Command(pgmParm, _connection);
    try
    {
        cmd.ExecuteNonQuery();
    }
    catch (iDB2Exception ex)
    {
        rc = ex.Message;
    }

    // Dispose the command since we're done with it.
    cmd.Dispose();

    // Return the success or failure of the call.
    return rc;
}

The problem with this technique is that I must have an existing connection before I can attempt to change a password. Unfortunately, if the user's password has expired they cannot connect to the database (iDB2CommErrorException) and as a result cannot change their password.

Is there any way accomplish this without the cwbx.dll?

like image 626
Timothy Schoonover Avatar asked Mar 29 '13 18:03

Timothy Schoonover


1 Answers

To programmatically change expired passwords on an IBM i (aka System i / iSeries / AS400) from a .NET application without taking a dependency on a local installation of IBM i Access for Windows (for cwbx.dll), consider one of the following options.

  • Programmatically establish a Telnet connection to the IBM i and transmit a sequence of characters that mimics the user input necessary to perform a change password operation. *Note that this is insecure without further configuration.

  • IBM Toolbox for Java includes an OS/400 or i5/OS Java class that can be used in Java programs to change passwords. The Java help for the class is available in iSeries Information Center a the following Web site: http://publib.boulder.ibm.com/pubs/html/as400/v5r1/ic2924/index.htm

    The following example demonstrates how to perform a change password operation on an expired password using the IBM Toolbox for Java. This can be invoked from a C# program using System.Diagnostics.Process.Start("java ChangeIBMiPassword hostname username oldpw newpw"); (assuming appropriate classpaths). Also note that it is possible to use Java API's directly from .NET with the IKVM.NET library.

import com.ibm.as400.access.AS400;

public class ChangeIBMiPassword {
    public static void main(String[] args) {
        if (args.length < 4)
            System.exit(-1);

        String host = args[0];
        String user = args[1];
        String oldpw = args[2];
        String newpw = args[3];

        AS400 sys = new AS400(host, user);  
        try {
            sys.changePassword(oldpw, newpw);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}
  • Write a secure web service that runs on the IBM i. This web service will accept parameters for username, current password and new password. When a user calls this web service, it will perform the change password operation on behalf of the calling program.

  • Write a secure web service that does not run on the IBM i. This web service will accept parameters for username, current password and new password. When a user calls this web service, it will use the cwbx library to perform the change password operation on behalf of the calling program. This does not totally eliminate the dependency on cwbx.dll, but it lowers it to a single system.

http://www-01.ibm.com/support/docview.wss?uid=nas10043a8b0e0544f1386256ba100659bcd

like image 118
Timothy Schoonover Avatar answered Oct 06 '22 18:10

Timothy Schoonover