#!/bin/ksh93
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_user.sh 1.10 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2011 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)27	1.10  src/43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_user.sh, hacmp.assist, 61haes_r721, 1607A_hacmp721 1/5/16 07:00:23

#================================================
# The following, commented line enforces coding
# standards when this file is edited via vim.
#================================================
# vim:tabstop=4:shiftwidth=4:expandtab:smarttab
#================================================

# Start of POD-formatted documentation. Viewing suggestions:
#      perldoc <FILENAME>
#      pod2text -c <FILENAME>
#      pod2text -c --code <FILENAME>
#      pod2html <FILENAME>
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_modify_user

=head1 VERSION

 Version Number:  1.10
 Last Extracted:  2/17/16 10:37:20
 Last Changed:    1/5/16 07:00:23

 Path, Component, Release(, Level):
 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_user.sh, hacmp.assist, 61haes_r721, 1607A_hacmp721

=head1 SYNOPSIS

 clmgr modify user <user_name> \
             RESOURCE_GROUP=<resource_group> \
             [ ID=### ] \
             [ ADMINISTRATIVE={false|true} ] \
             [ PRIMARY=<group> ] \
             [ PASSWORD="{<password>|}" ] \
                 [ CHANGE_ON_NEXT_LOGIN={true|false} ] \
             [ GROUPS=<group#1>[,<group#2>,...] ] \
             [ ADMIN_GROUPS=<group#1>[,<group#2>,...] ] \
             [ ROLES=<role#1>[,<role#2>,...] ] \
             [ SWITCH_USER={true|false} ] \
             [ SU_GROUPS={ALL|<group#1>[,<group#2>,...]} ] \
             [ HOME=<full_directory_path> ] \
             [ SHELL=<defined_in_/etc/shells> ] \
             [ INFO=<user_information> ] \
             [ EXPIRATION=<MMDDhhmmyy> ] \
             [ LOCKED={false|true} ] \
             [ LOGIN={true|false} ] \
             [ REMOTE_LOGIN={true|false} ] \
             [ SCHEDULE=<range#1>[,<range#2>,...>] ] \
             [ MAX_FAILED_LOGINS={#|0} ] \
             [ AUTHENTICATION={compat|files|DCE|ldap} ] \
             [ ALLOWED_TTYS=<tty#1>[,<tty#2>,...] ] \
             [ DAYS_TO_WARN={#|0} ] \
             [ PASSWORD_VALIDATION_METHODS=<meth#1>[,<meth#2>,...]]\
             [ PASSWORD_FILTERS=<filter#1>[,<filter#2>,...] ] \
             [ MIN_PASSWORDS=<number_of_passwords_before_reuse> ] \
             [ REUSE_TIME=<weeks_before_password_reuse> ] \
             [ LOCKOUT_DELAY=<weeks_btwn_expiration_and_lockout> ] \
             [ MAX_PASSWORD_AGE={0..52} ] \
             [ MIN_PASSWORD_AGE={0..52} ] \
             [ MIN_PASSWORD_LENGTH={0..8} ] \
             [ MIN_PASSWORD_ALPHAS={0..8} ] \
             [ MIN_PASSWORD_OTHERS={0..8} ] \
             [ MAX_PASSWORD_REPEATED_CHARS={0..52} ] \
             [ MIN_PASSWORD_DIFFERENT={0..8} ] \
             [ REGISTRY={local|ldap} ] \
             [ UMASK=#### ] \
             [ AUDIT_CLASSES=<class#1>[,<class#2>,...] ] \
             [ TRUSTED_PATH={nosak|on|notsh|always} ] \
             [ PRIMARY_AUTH={SYSTEM|.} ] \
             [ SECONDARY_AUTH={NONE|SYSTEM|<token>;<user>} ] \
             [ PROJECTS=<project#1>[,<project#2>,...] ] \
             [ KEYSTORE_ACCESS={file|none} ] \
                 [ ADMIN_KEYSTORE_ACCESS={file|none} ] \
                 [ KEYSTORE_MODE={admin|guard} ] \
                 [ ALLOW_MODE_CHANGE={false|true} ] \
             [ KEYSTORE_ENCRYPTION={RSA_1024|RSA_2048|RSA_4096} ] \
                 [ FILE_ENCRYPTION={AES_128_CBC|AES_128_EBC| \
                                    AES_192_CBC|AES_192_ECB| \
                                    AES_256_CBC|AES_256_ECB} ]

  NOTE: "SCHEDULE" defines the times when the user is allowed to
        login to this system. The value is a comma separated list
        of items as follows:
            * [!][MMdd[-MMdd]]:hhmm-hhmm
            * [!]MMdd[-MMdd][:hhmm-hhmm]
            * [!][w[-w]]:hhmm-hhmm
            * [!]w[-w][:hhmm-hhmm]
        where MM is a month number (00=January, 11=December), dd is
        the day of the month, hh is the hour of the day (00 - 23), mm
        is the minute of the hour, and w is a weekday (0=Sunday, 6=
        Saturday). An exclamation point may be used to indicate that
        the access during the specified time range is disallowed.
 NOTE: "MAX_FAILED_LOGINS", "DAYS_TO_WARN", "MIN_PASSWORDS",
       "REUSE_TIME" may be set to zero to disable these features.
 NOTE: "LOCKOUT_DELAY" may be set to -1 to disable these features.

 clmgr modify user {<user_name> | ALL_USERS} \
             ALLOW_PASSWORD_CHANGE={no|yes}

 NOTE: "ALLOW_PASSWORD_CHANGE" indicates if the user is allowed to
       change their password across the entire cluster using C-SPOC.

 NOTE: the alias for "user" is "ur".

=head1 DESCRIPTION

Attempts to add a new AIX user to either all the nodes in the cluster,
or to just those nodes within the specified resource group.

=head1 ARGUMENTS

 1. properties [REQUIRED] [hash ref]
    An associative array within which data about the
    created object can be returned to the caller.

 2. user [REQUIRED] [string]
    A login name that identifies this user account on the system.
    The system uses the user name to set the correct environment
    and access privileges for the user during login.

    A user name is specified as a string.  The maximum length
    depends on the configuration of the individual nodes, and can
    be queried using the lsattr command to view the max_logname
    attribute of the sys0 device, but all AIX systems will accept
    a length of up to 8 characters.  See the documentation on the
    AIX mkuser command for more information.

    You can use letters, numbers, and some special characters in
    the name. The string cannot start with a hyphen (-), plus (+),
    tilde (~), or at sign (@). The string cannot contain any spaces
    or any of the following characters: colon (:), double quote ("),
    pound sign, comma (,), asterisk (*), single quote ('), equal
    sign (=), newline (\n), tab (\t), backslash (\), forward slash
    (/), question mark (?), back quote (`), or the key words "ALL"
    or "default".

 3. rg [OPTIONAL] [string]
    A resource group within the cluster. If specified, the new user
    will only be added to the nodes that this resource group is able
    to run on. If no resource group is specified, the new users will
    be added to all nodes within the cluster.

 4. id [OPTIONAL] [posint]
    Defines a unique decimal integer string to associate with this
    user account on the system.

    It is strongly recommended to let the system generate the user's
    ID to incorporate all the security restrictions and conventions
    that may apply to your system. To have the system generate the
    ID, leave this option blank.

 5. keystore_access [OPTIONAL] [set]
    The key store will allow the user to utilize files in Encrypted    
    File System. The selection of file will create a key store file
    associated with this user. It is recommended that file is
    selected.  Select none for no key store to be created. All
    other EFS (efs_*) attributes will not have any effect.

    Allowed values: file, none

 6. admin_keystore_access [OPTIONAL] [set]
    Indicates where the efs_admin key store can be found when
    user opens its key store. This can be file, to indicate
    /etc/security/efs/efs_admin/key store.

    Allowed values: file, none

 7. keystore_mode [OPTIONAL] [set]
    The efs_initalks_mode of admin allows for root or other security
    privileged system users to reset the user's key store password.
    Otherwise, if the user forgets their key store password, they
    will not be able to access their Encrypted File System files.

    If the guard mode is selected, then root cannot reset the user's
    key store password.

    Allowed values: admin, guard

 8. allow_mode_change [OPTIONAL] [boolean]
    Indicates if this user is allowed to change the keystore mode.

 9. keystore_encryption [OPTIONAL] [set]
    This option specifies the algorithm for the user's key within
    the key store. This key will protect the encrypting key of files
    the user creates within the Encrypted File System.

    Allowed values: RSA_1024, RSA_2048, RSA_4096

    RSA_1024 = 1024bit RSA key
    RSA_2048 = 2048bit RSA key
    RSA_4096 = 4096bit RSA key

 10. file_encryption [OPTIONAL] [set]
    When an encrypted file is created in an Encrypted File System,
    this option specifies the algorithm and mode in which the file
    will be encrypted.

    Allowed values: AES_128_CBC, AES_128_EBC, AES_192_CBC,
                    AES_192_ECB, AES_256_CBC, AES_256_ECB

    AES_128_CBC = Advanced Encryption Standard with 128 bit key
                  length, in Cipher Block Chaining mode.

    AES_128_EBC = Advanced Encryption Standard with 128 bit key
                  length, in Electronic Code Book mode.

    AES_192_CBC = Advanced Encryption Standard with 192 bit key
                  length, in Cipher Block Chaining mode.

    AES_192_ECB = Advanced Encryption Standard with 192 bit key
                  length, in Electronic Code Book mode.

    AES_256_CBC = Advanced Encryption Standard with 256 bit key
                  length, in Cipher Block Chaining mode.

    AES_256_ECB = Advanced Encryption Standard with 256 bit key
                  length, in Electronic Code Book mode.

 11. registry [OPTIONAL] [set]
    Indicates where the user's information is currently stored,
    so the modification(s) can be made in the correct place.
    If the user is defined locally, within AIX, than the value
    "files" should be used. If the user is defined remotely, on
    the LDAP server, then "LDAP" should be used.

 12. authentication [OPTIONAL] [set]
    Specifies the methods through which the user must
    authenticate successfully before gaining access to the
    system. The default word compat indicates that normal login
    procedures will be followed. Therefore, compat allows local
    and NIS users access to the system.

 13. groups [OPTIONAL] [string]
    The groups in which the user is a member. Groups are
    collections of users that can share access authority to
    protected resources. Groups can be formed for users who
    access the same applications or hardware resources, perform
    similar tasks, or have similar needs for information. A user
    can be a member in up to 64 groups. The groups must already
    exist on the system.

    To specify the user's group set, type a string containing
    the group names (each group name can contain one to eight
    bytes. Separate the names with commas), or use the List box
    and select the names from the choices displayed (as you
    select, the string of names is displayed in the field in the
    correct format). If you do not specify any groups, the system
    assigns the user to the default groups specified in the
    /usr/lib/security/mkuser.default file.

 14. primary [OPTIONAL] [string]
    The group name the user will have when the user logs in for
    the first time. Groups are collections of users that can share
    access authority to protected resources. Groups can be formed
    for users who access the same applications or hardware
    resources, perform similar tasks, or have similar needs for
    information. A user can be a member in up to 64 groups.
    However, you can specify only one primary group for a user.

    To specify the primary group name, type the name of an existing
    group, or use the List box and select the group from the choices
    displayed. If you do not specify or list any groups, the system
    assigns the user to the primary default group specified in the
    usr/lib/security/mkuser.default file.

 15. admin_groups [OPTIONAL] [string]
    Specifies the non-administrative groups for which the user is an
    administrator.

    The attributes of a non-administrative group can be modified by
    its administrators and the root user. This is different than the
    attributes of an administrative group which can be modified by
    only the root user.

    A user can be the administrator of more than one group. The
    groups must already exist on the system.

    To enter the groups, type in a string containing the group names
    each group name can contain one to eight bytes; separate the
    names with commas), or use the List box and select the names
    from the choices displayed (as you select, the string of names
    is displayed in the field in the correct format).
                                                                       
    If you do not enter or list any groups, the system checks the
    defaults in the /etc/security/user file for default
    administrator definitions. It is possible that the user may not
    be made an administrator of any groups.

 16. roles [OPTIONAL] [set]
    One or more roles that this user operates within. Each role
    serves to restrict the operations that the user is allowed
    to perform.

    Allowed values: ha_admin, ha_op, ha_mon, ha_view

 17. switch_user [OPTIONAL] [boolean]
    Specifies the users ability to su to another user's account.

    Select "true" if the user should be authorized to switch, or
    "su", to another user's account. Select "false" if the user is
    not authorized to swith to another user's account.

 18. su_groups [OPTIONAL] [set]
    Specifies the groups that can su (switch user) to this user's
    account. You may want groups, such as a group with administrative
    privileges, to be able to access this user's account to update
    the user's system configuration or change some attribute values,
    such as print queues or host names.

    More than one group can su to a user account. The groups must
    already exist on the system.

    To enter su groups, type in a string containing the group names
    each group name can contain one to eight bytes; separate the
    names with commas), or use the List box and select the names
    from the choices displayed (as you select, the string of names
    is displayed in the field in the correct format).

    You can specify the keyword ALL to indicate all groups or place
    an exclamation point) in front of a group name listed in the
    field to exclude a specific group.

    If you do not enter or list any groups, the system allows the
    groups listed as default su groups in the /etc/security/user
    file to switch to this user account with the su command.

    Allow values: any defined group, or the special value "ALL".

 19. home [OPTIONAL] [fullpath]
    The absolute path to the new user's home directory.

 20. shell [OPTIONAL] [string]
    Specify the initial program to execute when the user performs
    a login. This is typically a shell program, such as /bin/ksh.

 21. info [OPTIONAL] [string]
    Specify descriptive information about the user.

 22. expiration [OPTIONAL] ["MMDDhhmmyy"]
    Specifies an expiration date for the user's password using the
    format "MMDDhhmmyy" (i.e. month, day, hour, minute, year).
    When the expiration date expires, the user will be required
    to change their the password.

 23. locked [OPTIONAL] [boolean]
    Indicates whether the user's account is locked, which prevents
    the user from logging in. True indicates the account is locked
    and the user cannot login. False indicates the account is not
    locked and the user can login.

    This option will not unlock a user's account that was locked
    as a result of too many failed login attempts.

    Note: To unlock a user's account that was locked because of
          too many failed logins, the system administrator can
          use the Reset User's Failed Login Count menu item under
          the Users menu item of the Security & Users menu.

 24. login [OPTIONAL] [boolean]
    Indicates whether the user can log into the system with the
    "login" command.

 25. remote_login [OPTIONAL] [boolean]
    Indicates whether the user can log into the system from a
    remote system.

 26. schedule [OPTIONAL] ["MMDDhhmmyy"]
    Specifies the time of day and days of the week the user is
    allowed to login to the system. Any attempt to access the
    system outside of these times is not allowed. The value is
    a comma-separated list of day and time periods. An exclamation
    point("!") in front of the time indicates the user is not
    allowed to log in during that time. If this attribute is not
    specified, the user can log in at all times. Refer to the
    chuser command documentation for details.             

    NOTE: the ranges are a comma separated list of items as follows:
              * [!][MMdd[-MMdd]]:hhmm-hhmm
              * [!]MMdd[-MMdd][:hhmm-hhmm]
              * [!][w[-w]]:hhmm-hhmm
              * [!]w[-w][:hhmm-hhmm]
          where MM is a month number (00=January, 11=December), dd
          is the day of the month, hh is the hour of the day (00 -
          23), mm is the minute of the hour, and w is a weekday
          (0=Sunday, 6=Saturday). An exclamation point may be used
          to indicate that the access during the specified time
          range is disallowed.

 27. max_failed_logins [OPTIONAL] [int]
    The number of consecutive unsuccessful login attempts the user
    is allowed. If this number is exceeded, the account is locked
    and the user cannot login. If 0 is specified this feature is
    disabled.

    Note: To unlock a user's account that was locked because of too
          many failed logins, the system administrator can use the
          Reset User's Failed Login Count menu item under the Users
          menu item of the Security & Users menu.

 28. allowed_ttys [OPTIONAL] [string]
    Specifies the list of terminals that can access this user
    account. When a user tries to access the account, the system
    attempts to match the terminal from which the access request
    is made with a terminal listed in this field. The system works
    through the list of TTYs in the order specified in this field
    and grants access to the account to the first TTY that it
    matches. If the system cannot find a match, the user cannot
    log in to the account from the terminal.

    To enter a list of valid TTYs for this user account, type in
    the full path names to each terminal (separating each path name
    with a comma).

    Note: As shortcuts, type in the keyword ALL to indicate that
          all TTYs known to the system are valid for the account,
          or prefix a TTY's path with an ! (exclamation point) to
          exclude it from a list of entries. You can even combine
          the two shortcuts. For example, dev/tty0,ALL means that
          all TTYs available to the system can access this user
          account except for tty0.

    If you do not enter a list of valid TTYs, the system uses the
    defaults from the /etc/security/user file.

 29. days_to_warn [OPTIONAL] [int]
    Specifies the number of days prior to the expiration of the
    user's password when a warning message is issued. The value
    is a decimal integer string. The message appears each time
    the user logs in during this warning period, and gives the
    date when the user's password expires.

 30. password_validation_methods [OPTIONAL] [string]
    List of administrator-supplied methods for checking the user's
    new password during a password change. The value is a comma-
    separated list of program names, which must be specified using
    absolute pathnames or a path relative to /usr/lib. If the
    password does not meet the requirements of all the methods
    specified, the password change will not be allowed.

 31. password_filters [OPTIONAL] [fullpath]
    List of dictionary files containing words that cannot be used
    as passwords. The value is a comma-separated list of files,
    which must be specified using absolute pathnames.

 32. min_passwords [OPTIONAL] [int]
    The number of previous passwords that the user will not be
    able to reuse. The value is a decimal integer string. The
    interpretation of this value may depend on the value of the
    "REUSE_TIME" attribute. If 0 is specified, any previous
    password can be reused as long as the "REUSE_TIME" has
    elapsed.

 33. reuse_time [OPTIONAL] [int]
    The number of weeks that must pass before a user is able to
    reuse a password after it has been selected as the user's
    current password. The value is a decimal integer string,
    and the recommended number of weeks is 26 (six months). The
    interpretation of this value may depend on the value of the
    NUMBER OF PASSWORDS before reuse attribute. If 0 is
    specified, any previous password can be reused as long as
    the NUMBER OF PASSWORDS before reuse attribute has been
    satisfied.

 34. lockout_delay [OPTIONAL] [int]
    The number of weeks after the user's password expires
    (reaches its maximum age) during which the user can still
    change the password. If this time period passes without a
    password change, the user account no longer allows logins
    until an administrator resets the password. The value is a
    decimal integer string. If 0 is specified, logins will be
    prevented at the time the password expires. If -1 is
    specified, this feature is disabled. If "MAX_PASSWORD_AGE"
    is 0, any value entered here is ignored.

 35. max_password_age [OPTIONAL] [int]
    Defines the maximum age (in weeks) for the user's password.
    When the password reaches this age, the system requires it
    to be changed before the user can login again. The value is
    a decimal integer string. If you specify "0", this feature
    is disabled. You can specify a number from 0 to 52.

 36. min_password_age [OPTIONAL] [int]
    Defines the minimum age (in weeks) for the user's password
    before it can be changed. The value is a decimal integer
    string. If you specify "0", the password can be changed at
    any time. You can specify a number from 0 to 52.

 37. min_password_length [OPTIONAL] [int]
    The minimum number of characters that the user's password
    must contain. The value is a decimal integer string. If you
    select "0" there is no minimum length. You can select a
    number from 0 to 8. 

 38. min_password_alphas [OPTIONAL] [int]
    The minimum number of alphabetic characters that must be
    included in the user's password. The value is a decimal
    integer string. If you select "0", no minimum number of
    alphabetic characters is required. You can select a number
    from 0 to 8.

 39. min_password_others [OPTIONAL] [int]
    The minimum number of characters other than alpha characters
    that must be included in the user's password. The value is a
    decimal integer string. If you specify "0", no minimum number
    of other characters is required. You can select a number from
    0 to 8.

 40. max_password_repeated_chars [OPTIONAL] [int]
    The maximum number of times that a character can be repeated
    within the user's password. The value is a decimal integer
    string. If you specify "8", any number of characters can be
    repeated. You can select a number from 0 to 8.

 41. min_password_different [OPTIONAL] [int]
    The minimum number of characters required in the user's new
    password that were not in the old password. The value is a
    decimal integer string. If you specify "0", no minimum
    number of different characters is required. You can select
    a number from 0 to 8.

 42. umask [OPTIONAL] [string]
    Defines the UMASK to use when creating files.

 43. audit_classes [OPTIONAL] [set]

 44. trusted_path [OPTIONAL] [set]
    Specifies a variable that defines the user's access to the
    trusted path. The system uses this variable when the user
    tries to invoke the trusted shell or a trusted process, or
    enters the secure attention key (SAK) sequence.

    Allowed values: nosak, on, notsh, always

        nosak - SAK is disabled for all processes run by the
                user. Select this option if this user transfers
                binary data that may contain the SAK sequence.

        notsh - User cannot invoke the trusted shell on a
                trusted path and is logged off if the user
                enters the SAK during the current session.

        always - User can only execute trusted processes (and
                 implies the user's initial program is the
                 trusted shell or another trusted process).

        on - User has standard trusted path characteristics
             and can invoke the trusted shell with the SAK.

    Default value: nosak

 45. primary_auth [OPTIONAL] [string]

 46. secondary_auth [OPTIONAL] [string]

 47. projects [OPTIONAL] [string]

 48. administrative [OPTIONAL] [boolean]
    Indicates if the user is an administrative user.

 49. password [OPTIONAL] [string]
    A new password to apply to the specified user.

 50. change_on_next_login [OPTIONAL] [boolean]
    Indicates if this user will be required to change their password on their
    next login.

 51. allow_password_change [OPTIONAL] [boolean]
    Indicates if this user is allowed to change their password on
    all the nodes in the cluster.

=head1 RETURN

 0: no errors were detected; the operation appears to have been successful
 1: a general error has occurred
 2: a specified resource does not exist, or could not be found
 3: some required input was missing
 4: some detected input was incorrect in some way
 5: a required dependency does not exist
 6: a specified search failed to match any data

=head1 COPYRIGHT

COPYRIGHT International Business Machines Corp. 2005,2010
All Rights Reserved

=cut
} # End of POD-formatted documentation.


function KLIB_HACMP_modify_user {
    LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL"
    : version=1.10, src/43haes/lib/ksh93/hacmp/KLIB_HACMP_modify_user.sh, hacmp.assist, 61haes_r721, 1607A_hacmp721
    : INPUTS: $*

    typeset -n properties=$1
    typeset user=${2//\"/}
    typeset rg=${3//\"/}
    typeset id=${4//\"/}
    typeset keystore_access=${5//\"/}
    typeset admin_keystore_access=${6//\"/}
    typeset keystore_mode=${7//\"/}
    typeset -l allow_mode_change=${8//\"/}
    typeset -u keystore_encryption=${9//\"/}
    typeset -u file_encryption=${10//\"/}
    typeset registry=${11//\"/}
    typeset authentication=${12//\"/}
    typeset groups=${13//\"/}
            groups=${groups//,/ }
    typeset primary=${14//\"/}
    typeset admin_groups=${15//\"/}
            admin_groups=${admin_groups//,/ }
    typeset roles=${16//\"/}
            roles=${roles//,/ }
    typeset switch_user=${17//\"/}
    typeset su_groups=${18//\"/}
            su_groups=${su_groups//,/ }
    typeset home=${19//\"/}
    typeset shell=${20//\"/}
    typeset info=${21//\"/}
    typeset expiration=${22//\"/}
    typeset -l locked=${23//\"/}
    typeset -l login=${24//\"/}
    typeset -l remote_login=${25//\"/}
    typeset schedule=${26//\"/}
    typeset max_failed_logins=${27//\"/}
    typeset allowed_ttys=${28//\"/}
    typeset days_to_warn=${29//\"/}
    typeset password_validation_methods=${30//\"/}
    typeset password_filters=${31//\"/}
    typeset min_passwords=${32//\"/}
    typeset reuse_time=${33//\"/}
    typeset lockout_delay=${34//\"/}
    typeset max_password_age=${35//\"/}
    typeset min_password_age=${36//\"/}
    typeset min_password_length=${37//\"/}
    typeset min_password_alphas=${38//\"/}
    typeset min_password_others=${39//\"/}
    typeset max_password_repeated_chars=${40//\"/}
    typeset min_password_different=${41//\"/}
    typeset umask=${42//\"/}
    typeset audit_classes=${43//\"/}
    typeset trusted_path=${44//\"/}
    typeset primary_auth=${45//\"/}
    typeset secondary_auth=${46//\"/}
    typeset projects=${47//\"/}
    typeset administrative=${48//\"/}
    if [[ $CLMGR_LOGGING == @(m|h)* ]]; then
        set +x  # Try not to log the customer's password!
        print -u2 "$PS4: typeset password=########"
    fi
    typeset password=${49//\"/}
    [[ $CLMGR_LOGGING == @(m|h)* ]] && set +x
    typeset -l change_on_next_login=${50//\"/}
    typeset -u allow_password_change=${51//\"/}

    [[ $CLMGR_LOGGING == 'med' ]] && set +x  # Only trace param values

    #===================================
    : Declare and initialize variables
    #===================================
    typeset -i rc=$RC_UNKNOWN
    typeset PAIR=
    typeset OPTIONS=" ${!_ENV_ARGS[*]} "
            OPTIONS=${OPTIONS/ RESOURCE_NAME / }
            OPTIONS=${OPTIONS/ RESOURCE_CLASS / }
    if [[ $OPTIONS == *([[:space:]]) ]]; then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 401 "\nERROR: no valid modifications were specified for \"%1\$s\".\n\n" "$tape" 1>&2
        rc=$RC_MISSING_INPUT
    fi

    [[ $registry == "local" || $registry == "LOCAL" ]] && registry="files"

    #=================
    : Validate input
    #=================
    if [[ -z $user ]]; then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2
        rc=$RC_MISSING_INPUT

    else
        if [[ $user != "ALL_USERS" ]]; then
            CL=$LINENO KLIB_HACMP_is_known_user $user
            if (( $? != RC_SUCCESS )); then
                /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$user" 1>&2
                /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 162 "Available Users:\n\n" 1>&2

                typeset available
                CL=$LINENO KLIB_HACMP_list_users available
                for (( i=0; i<${#available[*]}; i++ )); do
                    if [[ ${available[$i]} != *([[:space:]]) ]]; then
                        print -u2 "\t${available[$i]}"
                    fi
                done
                print -u2 ""

                rc=$RC_NOT_FOUND
            fi
        fi
    fi

    if [[ $rg != *([[:space:]]) ]]; then
        CL=$LINENO KLIB_HACMP_is_known_rg $rg
        if (( $? != RC_SUCCESS )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$rg" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 154 "Available Resource Groups:\n\n" 1>&2

            typeset available
            CL=$LINENO KLIB_HACMP_list_resourceusers available
            for (( i=0; i<${#available[*]}; i++ )); do
                if [[ ${available[$i]} != *([[:space:]]) ]]; then
                    print -u2 "\t${available[$i]}"
                fi
            done
            print -u2 ""

            rc=$RC_NOT_FOUND
        fi
    fi

    #==============================
    : Validate all numeric values
    #==============================
    for PAIR in "ID|$id" \
                "MAX_FAILED_LOGINS|$max_failed_logins" \
                "DAYS_TO_WARN|$days_to_warn" \
                "MIN_PASSWORDS|$min_passwords" \
                "REUSE_TIME|$reuse_time" \
                "LOCKOUT_DELAY|$lockout_delay" \
                "MAX_PASSWORD_AGE|$max_password_age" \
                "MIN_PASSWORD_AGE|$min_password_age" \
                "MIN_PASSWORD_LENGTH|$min_password_length" \
                "MIN_PASSWORD_ALPHAS|$min_password_alphas" \
                "MIN_PASSWORD_OTHERS|$min_password_others" \
                "MAX_PASSWORD_REPEATED_CHARS|$max_password_repeated_chars" \
                "MIN_PASSWORD_DIFFERENT|$min_password_different"
    do
        typeset ATTR=${PAIR%%\|*}
        typeset VALUE=${PAIR##*\|}
        [[ $VALUE == *([[:space:]]) ]] && continue

        if [[ $VALUE != ?(-)+([[:digit:]]) ]]; then 
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 111 "\nERROR: \"%1\$s\" requires a positive, integer value.\n\n" "$ATTR" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    done

    #==============================
    : Validate all boolean values
    #==============================
    for PAIR in "ALLOW_MODE_CHANGE|$allow_mode_change" \
                "SWITCH_USER|$switch_user" \
                "LOCKED|$locked" \
                "LOGIN|$login" \
                "REMOTE_LOGIN|$remote_login" \
                "ADMINISTRATIVE|$administrative" \
                "ALLOW_PASSWORD_CHANGE|$allow_password_change"
    do
        typeset ATTR=${PAIR%%\|*}
        typeset -l VALUE=${PAIR##*\|}
        [[ $VALUE == *([[:space:]]) ]] && continue

        if [[ $VALUE != @(y|t|n|f)* ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" "$ATTR" "$VALUE" 1>&2
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "true, false" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    done

    #====================================
    : Validate all group specifications
    #====================================
    typeset -i MISSING_GROUP=0
    for PAIR in "GROUPS|$groups" \
                "PRIMARY|$primary" \
                "ADMIN_GROUPS|$admin_groups" \
                "SU_GROUPS|$su_groups"
    do
        typeset ATTR=${PAIR%%\|*}
        typeset VALUE=${PAIR##*\|}
        [[ $VALUE == *([[:space:]]) ]] && continue

        typeset group=
        for group in $VALUE; do
            CL=$LINENO KLIB_HACMP_is_known_group $group
            if (( $? != RC_SUCCESS )); then
                /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$group" 1>&2
            fi
        done
    done
    if (( MISSING_GROUP )); then
        /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 161 "Available Groups:\n\n" 1>&2

        typeset available
        CL=$LINENO KLIB_HACMP_list_groups available
        for (( i=0; i<${#available[*]}; i++ )); do
            if [[ ${available[$i]} != *([[:space:]]) ]]; then
                print -u2 "\t${available[$i]}"
            fi
        done
        print -u2 ""

        rc=$RC_NOT_FOUND
    fi

    #==================================
    : Validate all set specifications
    #==================================
    for PAIR in "KEYSTORE_ACCESS|$keystore_access|file,none" \
                "ADMIN_KEYSTORE_ACCESS|$admin_keystore_access|file,none" \
                "KEYSTORE_MODE|$keystore_mode|admin,guard" \
                "KEYSTORE_ENCRYPTION|$keystore_encryption|RSA_1024,RSA_2048,RSA_4096" \
                "FILE_ENCRYPTION|$file_encryption|AES_128_CBC,AES_128_EBC,AES_192_CBC,AES_192_ECB,AES_256_CBC,AES_256_ECB" \
                "ROLES|$roles|$(/usr/sbin/lsrole ALL | /usr/bin/cut -f1 -d' ')" \
                "TRUSTED_PATH|$trusted_path|nosak,on,notsh,always"
    do
        typeset ATTR= VALUE= ACCEPTED=
        typeset -l VALUE_LC= ACCEPTED_LC=

        ATTR=${PAIR%%\|*};   PAIR=${PAIR#*\|}
        VALUE=${PAIR%%\|*};  PAIR=${PAIR#*\|}
        ACCEPTED=$PAIR
        [[ $VALUE == *([[:space:]]) ]] && continue
        [[ $ACCEPTED == *([[:space:]]) ]] && continue

        ACCEPTED=${ACCEPTED//$NL/,}
        ACCEPTED_LC=$ACCEPTED

        typeset -i INVALID=0
        for VALUE in ${VALUE//,/ }; do
            VALUE_LC=$VALUE
            if [[ ",$ACCEPTED_LC," != *,$VALUE_LC,* ]]; then
                /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 "\nERROR: invalid value specified for \"%1\$s\":  \"%2\$s\".\n" "$ATTR" "$VALUE" 1>&2
                INVALID=1
            fi
        done

        if (( INVALID )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "${ACCEPTED//,/, }" 1>&2
            rc=$RC_INCORRECT_INPUT
        fi
    done

    if (( $rc == RC_UNKNOWN )) && [[ $allow_password_change != *([[:space:]]) ]]; then
        OPTIONS=${OPTIONS/ ALLOW_PASSWORD_CHANGE / }
        if [[ $allow_password_change == @(Y|T|1)* ]]; then
            #===================================
            : Add user $user to the allow list
            #===================================
            print -- "$0()[$LINENO]($SECONDS): $HAUTILS/cl_manageallowpasswd -a $user" >>$CLMGR_TMPLOG
            $HAUTILS/cl_manageallowpasswd -a $user
            rc=$?
            print -- "$0()[$LINENO]($SECONDS): cl_manageallowpasswd RC: $rc" >>$CLMGR_TMPLOG
        else
            #========================================
            : Remove user $user from the allow list
            #========================================
            print -- "$0()[$LINENO]($SECONDS): $HAUTILS/cl_manageallowpasswd -r $user" >>$CLMGR_TMPLOG
            $HAUTILS/cl_manageallowpasswd -r $user
            rc=$?
            print -- "$0()[$LINENO]($SECONDS): cl_manageallowpasswd RC: $rc" >>$CLMGR_TMPLOG
        fi
    fi

    #===============================================================
    : Attempt to determine where the specified user is registered,
    : so that the modifications can be made in the right place.
    #===============================================================
    typeset -u source= user_source=
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
        if [[ $registry != *([[:space:]]) ]]; then
            typeset -u registryUC=$registry
            case $registryUC in
                LD*) registry="LDAP" ;;
                LO*) registry="files"  ;;
                 F*) registry="files" ;;
                  *) /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s":  "%2$s".\n' REGISTRY "$registry" 1>&2
                     /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "files, LDAP" 1>&2
                     rc=$RC_INCORRECT_INPUT
                  ;;
            esac
            (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && user_source=$registry
        fi 

        if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )); then
            print -- "$0()[$LINENO]($SECONDS): /usr/sbin/lsuser -a registry ALL | grep \"^$user \" | grep registry=files" >>$CLMGR_TMPLOG
            typeset LOCAL=$(/usr/sbin/lsuser -a registry ALL | grep "^$user " | grep registry=files 2>>$CLMGR_TMPLOG)
            print "$0()[$LINENO]($SECONDS): lsuser (files) RC: $?" >>$CLMGR_TMPLOG

            print -- "$0()[$LINENO]($SECONDS): /usr/sbin/lsuser -a registry ALL | grep \"^$user \" | grep registry=LDAP" >>$CLMGR_TMPLOG
            typeset REMOTE=$(/usr/sbin/lsuser -a registry ALL | grep "^$user " | grep registry=LDAP 2>>$CLMGR_TMPLOG)
            print "$0()[$LINENO]($SECONDS): lsuser (LDAP) RC: $?" >>$CLMGR_TMPLOG

            if [[ -n $LOCAL && -n $REMOTE ]]; then
                if [[ -z $user_source ]]; then
                    CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 9999 '\nERROR: "%1$s" is registered both locally and remotely. Please use the "REGISTRY" option to indicate which definition of "%1$s" you want to modify.\n' "$user" 1>&2
                    /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 "Valid values: %1\$s\n\n" "files, LDAP" 1>&2
                    rc=$RC_MISSING_INPUT
                else
                    source=$user_source
                fi
            elif [[ -n $LOCAL ]]; then
                source=${LOCAL##*=}
                if [[ -n $user_source && $user_source != $source ]]; then
                    CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 9999 '\nERROR: "%1$s" is not registered remotely, so the specified REGISTRY setting, "%2$s", will not work.\n\n' "$user" "$registry" 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
            elif [[ -n $REMOTE ]]; then
                source=${REMOTE##*=}
                if [[ -n $user_source && $user_source != $source ]]; then
                    CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 9999 '\nERROR: "%1$s" is not registered locally, so the specified REGISTRY setting, "%2$s", will not work.\n\n' "$user" "$registry" 1>&2
                    rc=$RC_INCORRECT_INPUT
                fi
            fi
        fi
    fi

    #====================================================
    : If a password was specified, set the new password
    #====================================================
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       [[ $OPTIONS == *\ PASSWORD\ * ]]
    then
        OPTIONS=${OPTIONS/ PASSWORD / }

        typeset cspocOpt= kOpt=
        if [[ -n $rg ]]; then
             cspocOpt=" -cspoc "
             (( CLMGR_FORCE )) && cspocOpt="$cspocOpt -f"
             [[ $CLMGR_LOGGING == "high" ]] && cspocOpt="$cspocOpt -d9"
             cspocOpt="$cspocOpt -g $rg"
        fi
        if [[ $change_on_next_login == @(f|n)* ]]; then
            kOpt=" -k"
        fi
        if [[ $CLMGR_LOGGING == 'high' ]]; then
            set +x  # Try not to log the customer's password!

            if [[ $password != *([[:space:]]) ]]; then
                print -u2 "$PS4: $HASBIN/cl_chpasswd$cspocOpt$kOpt $user ########"
            else
                print -u2 "$PS4: $HASBIN/cl_chpasswd$cspocOpt$kOpt $user"
            fi
        else
            if [[ $password != *([[:space:]]) ]]; then
                print "$HASBIN/cl_chpasswd$cspocOpt$kOpt $user ########" >>$CLMGR_TMPLOG
            else
                print "$HASBIN/cl_chpasswd$cspocOpt$kOpt $user" >>$CLMGR_TMPLOG
            fi
        fi
        if [[ $source == "LDAP" ]]; then
            mode=LDAP $HASBIN/cl_chpasswd$cspocOpt$kOpt $user $password
        else
            $HASBIN/cl_chpasswd$cspocOpt$kOpt $user $password
        fi
        rc=$?
        if [[ $CLMGR_LOGGING == 'high' ]]; then
            print -u2 "$PS4: typeset -i rc=$rc"
            set -x
        fi
        if (( $rc != RC_SUCCESS )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 400 '\nERROR: failed to modify "%1$s".\n\n' "$user" 1>&2
            rc=$RC_ERROR
        fi
    fi

    #========================================================
    : Modify the user if no input errors have been detected
    #========================================================
    typeset -i HAVE_CHANGES=0
    typeset VARNAME=
    for VARNAME in ${!_ENV_ARGS[*]}; do
        [[ $VARNAME == RESOURCE_@(CLASS|NAME) ]] && continue   # Internal only
        [[ $VARNAME == PASSWORD ]] && continue             # Already processed
        [[ $VARNAME == CHANGE_ON_NEXT_LOGIN ]] && continue # Already processed
        if [[ $VARNAME != *([[:space:]]) ]]; then
            HAVE_CHANGES=1
            break
        fi
    done
    if (( $rc == RC_UNKNOWN || $rc == RC_SUCCESS )) && \
       (( HAVE_CHANGES )) && [[ $OPTIONS != *([[:space:]]) ]]
    then
        typeset rgOpt= idOpt= kaOpt= akaOpt= kmOpt= amcOpt= keOpt= feOpt=
        typeset authOpt= gOpt= pOpt= agOpt= rlOpt= suOpt= sugOpt= homeOpt=
        typeset shellOpt= infoOpt= expOpt= lckOpt= logOpt= rlogOpt= schOpt=
        typeset mflOpt= ttyOpt= dtwOpt= pvmOpt= pfOpt= minPwOpt= ruOpt=
        typeset delayOpt= maxAgeOpt= minAgeOpt= minLenOpt= minAlphasOpt=
        typeset minOthersOpt= maxRptOpt= minDiffOpt= uOpt= acOpt= tOpt= paOpt=
        typeset saOpt= projOpt= adminOpt

        [[ $rg != *([[:space:]]) ]] && rgOpt=" -cspoc-g $rg"
        [[ $id != *([[:space:]]) ]] && idOpt=" id=$id"
        [[ $keystore_access != *([[:space:]]) ]] && kaOpt=" efs_keystore_access=$keystore_access"
        [[ $admin_keystore_access != *([[:space:]]) ]] && akaOpt=" efs_adminks_access=$admin_keystore_access"
        [[ $keystore_mode != *([[:space:]]) ]] && kmOpt=" efs_initialks_mode=$keystore_mode"
        if [[ $allow_mode_change != *([[:space:]]) ]]; then
            if [[ $allow_mode_change == @(y|t)* ]]; then
                amcOpt=" efs_allowksmodechangebyuser=true"
            else
                amcOpt=" efs_allowksmodechangebyuser=false"
            fi
        fi
        [[ $keystore_encryption != *([[:space:]]) ]] && keOpt=" efs_keystore_algo=$keystore_encryption"
        [[ $file_encryption != *([[:space:]]) ]] && feOpt=" efs_file_algo=$file_encryption"
        [[ $authentication != *([[:space:]]) ]] && authOpt=" SYSTEM=$authentication"
        [[ $groups != *([[:space:]]) ]] && gOpt=" groups=${groups//+([[:space:]])/,}"
        [[ $primary != *([[:space:]]) ]] && pOpt=" pgrp=$primary"
        [[ $admin_groups != *([[:space:]]) ]] && agOpt=" admgroups=${admin_groups//+([[:space:]])/,}"
        [[ $roles != *([[:space:]]) ]] && rlOpt=" roles=${roles//+([[:space:]])/,}"
        if [[ $switch_user != *([[:space:]]) ]]; then
            if [[ $switch_user == @(y|t)* ]]; then
                suOpt=" su=true"
            else
                suOpt=" su=false"
            fi
        fi
        [[ $su_groups != *([[:space:]]) ]] && sugOpt=" sugroups=${su_groups//+([[:space:]])/,}"
        [[ $home != *([[:space:]]) ]] && homeOpt=" home=$home"
        [[ $shell != *([[:space:]]) ]] && shellOpt=" shell=$shell"
        [[ $info != *([[:space:]]) ]] && infoOpt=" gecos=\"$info\""
        [[ $expiration != *([[:space:]]) ]] && expOpt=" expires=$expiration"
        if [[ $locked != *([[:space:]]) ]]; then
            if [[ $locked == @(y|t)* ]]; then
                lckOpt=" account_locked=true"
            else
                lckOpt=" account_locked=false"
            fi
        fi
        if [[ $login != *([[:space:]]) ]]; then
            if [[ $login == @(y|t)* ]]; then
                logOpt=" login=true"
            else
                logOpt=" login=false"
            fi
        fi
        if [[ $remote_login != *([[:space:]]) ]]; then
            if [[ $remote_login == @(y|t)* ]]; then
                rlogOpt=" rlogin=true"
            else
                rlogOpt=" rlogin=false"
            fi
        fi
        [[ $schedule != *([[:space:]]) ]] && schOpt=" logintimes=$schedule"
        [[ $max_failed_logins != *([[:space:]]) ]] && mflOpt=" loginretries=$max_failed_logins"
        [[ $allowed_ttys != *([[:space:]]) ]] && ttyOpt=" ttys=$allowed_ttys"
        [[ $days_to_warn != *([[:space:]]) ]] && dtwOpt=" pwdwarntime=$days_to_warn"
        [[ $password_validation_methods != *([[:space:]]) ]] && pvmOpt=" pwdchecks=$password_validation_methods"
        [[ $password_filters != *([[:space:]]) ]] && pfOpt=" dictionlist=$password_filters"
        [[ $min_passwords != *([[:space:]]) ]] && minPwOpt=" histsize=$min_passwords"
        [[ $reuse_time != *([[:space:]]) ]] && ruOpt=" histexpire=$reuse_time"
        [[ $lockout_delay != *([[:space:]]) ]] && delayOpt=" maxexpired=$lockout_delay"
        [[ $min_password_age != *([[:space:]]) ]] && minAgeOpt=" minage=$min_password_age"
        [[ $min_password_length != *([[:space:]]) ]] && minLenOpt=" minlen=$min_password_length"
        [[ $min_password_alphas != *([[:space:]]) ]] && minAlphasOpt=" minalpha=$min_password_alphas"
        [[ $min_password_others != *([[:space:]]) ]] && minOthersOpt=" minother=$min_password_others"
        [[ $max_password_repeated_chars != *([[:space:]]) ]] && maxRptOpt=" maxrepeats=$max_password_repeated_chars"
        [[ $min_password_different != *([[:space:]]) ]] && minDiffOpt=" mindiff=$min_password_different"
        [[ $umask != *([[:space:]]) ]] && uOpt=" umask=$umask"
        [[ $audit_classes != *([[:space:]]) ]] && acOpt=" auditclasses=$audit_classes"
        [[ $trusted_path != *([[:space:]]) ]] && tOpt=" tpath=$trusted_path"
        [[ $primary_auth != *([[:space:]]) ]] && paOpt=" auth1=$primary_auth"
        [[ $secondary_auth != *([[:space:]]) ]] && saOpt=" auth2=$secondary_auth"
        [[ $projects != *([[:space:]]) ]] && projOpt=" projects=$projects"
        if [[ -n $administrative ]]; then
            case $administrative in
                @(y|t)*) adminOpt=" admin=true";;
                @(n|f)*) adminOpt=" admin=false";;
            esac
        fi

        if [[ $source == "LDAP" ]]; then
            print -- "$0()[$LINENO]($SECONDS): mode=LDAP $HACSPOC/fix_args nop cl_chuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$authOpt$gOpt$pOpt$agOpt$rlOpt$suOpt$sugOpt$homeOpt$shellOpt$infoOpt$expOpt$lckOpt$logOpt$rlogOpt$schOpt$mflOpt$ttyOpt$dtwOpt$pvmOpt$pfOpt$minPwOpt$ruOpt$delayOpt$maxAgeOpt$minAgeOpt$minLenOpt$minAlphasOpt$minOthersOpt$maxRptOpt$minDiffOpt$uOpt$acOpt$tOpt$paOpt$saOpt$projOpt$adminOpt $user" >>$CLMGR_TMPLOG
            mode=LDAP $HACSPOC/fix_args nop "cl_chuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$authOpt$gOpt$pOpt$agOpt$rlOpt$suOpt$sugOpt$homeOpt$shellOpt$infoOpt$expOpt$lckOpt$logOpt$rlogOpt$schOpt$mflOpt$ttyOpt$dtwOpt$pvmOpt$pfOpt$minPwOpt$ruOpt$delayOpt$maxAgeOpt$minAgeOpt$minLenOpt$minAlphasOpt$minOthersOpt$maxRptOpt$minDiffOpt$uOpt$acOpt$tOpt$paOpt$saOpt$projOpt$adminOpt" $user
        else
            print -- "$0()[$LINENO]($SECONDS): $HACSPOC/fix_args nop cl_chuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$authOpt$gOpt$pOpt$agOpt$rlOpt$suOpt$sugOpt$homeOpt$shellOpt$infoOpt$expOpt$lckOpt$logOpt$rlogOpt$schOpt$mflOpt$ttyOpt$dtwOpt$pvmOpt$pfOpt$minPwOpt$ruOpt$delayOpt$maxAgeOpt$minAgeOpt$minLenOpt$minAlphasOpt$minOthersOpt$maxRptOpt$minDiffOpt$uOpt$acOpt$tOpt$paOpt$saOpt$projOpt$adminOpt $user" >>$CLMGR_TMPLOG
            $HACSPOC/fix_args nop "cl_chuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$authOpt$gOpt$pOpt$agOpt$rlOpt$suOpt$sugOpt$homeOpt$shellOpt$infoOpt$expOpt$lckOpt$logOpt$rlogOpt$schOpt$mflOpt$ttyOpt$dtwOpt$pvmOpt$pfOpt$minPwOpt$ruOpt$delayOpt$maxAgeOpt$minAgeOpt$minLenOpt$minAlphasOpt$minOthersOpt$maxRptOpt$minDiffOpt$uOpt$acOpt$tOpt$paOpt$saOpt$projOpt$adminOpt" $user
        fi
        rc=$?
        print "$0()[$LINENO]($SECONDS): cl_chuser RC: $rc" >>$CLMGR_TMPLOG

        if (( $rc != RC_SUCCESS )); then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 400 '\nERROR: failed to modify "%1$s".\n\n' "$user" 1>&2
            rc=$RC_ERROR
        fi

        #===========================================================
        : If output from this operation was requested, retrieve it
        #===========================================================
        if (( $rc == RC_SUCCESS )); then
            if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then
                CL=$LINENO KLIB_HACMP_get_user_attributes "$user" properties
            fi
        fi
    fi

    #=======================================================================
    : If a user input error was detected, provide some helpful suggestions
    #=======================================================================
    if (( $rc == RC_MISSING_INPUT || $rc == RC_INCORRECT_INPUT )) && \
       [[ $CLMGR_GUI == *([[:space:]]) ]]
    then
        CL=$LINENO cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 104 "For more information about available options and syntax, try\n\"$HAUTILS/clmgr %1\$s\". As an\nalternative, if the PowerHA SystemMirror man pages have been installed, invoke\n\"$HAUTILS/clmgr -hv\" (or \"/usr/bin/man clmgr\"),\nsearching for \"%2\$s\" in the displayed text.\n\n" \
        "add user -h" "USER:" "$CLMGR_PROGNAME" 1>&2
    fi

    log_return_msg "$rc" "$0()" "$LINENO"
    return $?
} # End of "KLIB_HACMP_modify_user()"
