#!/bin/ksh93 # IBM_PROLOG_BEGIN_TAG # This is an automatically generated prolog. # # 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_user.sh 1.8.1.1 # # 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 # @(#)77 1.8.1.1 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_user.sh, hacmp.assist, 61haes_r721, 1610A_hacmp721 3/8/16 12:45:30 #============================================================================ # # Name: KLIB_HACMP_add_user # # Description: This is the main, FPATH function that is invoked by clmgr # to add a new user to the cluster. The primary utility used # for this operation is "cl_mkuser". # # Inputs: See the "devDoc()" function, below. # # Outputs: The properties hash is populated. The only other outputs are # any error messages that might be needed. # # Returns: Zero if no errors are detected. Otherwise, an appropriate # non-zero value is returned. Refer to the "RETURN" section # of the "devDoc()" function, below, for the standard return # code values/meanings for clmgr. # #============================================================================ function KLIB_HACMP_add_user { LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL" : version=1.8.1.1, src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_user.sh, hacmp.assist, 61haes_r721, 1610A_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 -l 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 -u registryUC=$registry typeset existing CL=$LINENO KLIB_HACMP_list_users existing 2>>$CLMGR_TMPLOG case $registryUC in LD*) registry="LDAP" ;; LO*) registry="files" ;; F*) registry="files" ;; *) if [[ $registry != *([[:space:]]) ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' REGISTRY "$registry" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 'Valid values: %1$s\n\n' "files, LDAP" 1>&2 rc=$RC_INCORRECT_INPUT fi ;; esac #================= : Validate input #================= if [[ -z $user ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2 rc=$RC_MISSING_INPUT elif [[ " ${existing[*]} " == *\ $user\ * ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 229 '\nERROR: the specified object already exists: "%1$s"\n\n' "$user" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ -n $user && $user == [\-\+\~\@]* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 103 '\nERROR: one or more invalid characters were detected in "%1$s": "%2$s".\n\n' NAME "[-+~@]" 1>&2 rc=$RC_INCORRECT_INPUT fi if [[ $rg != *([[:space:]]) ]]; then CL=$LINENO KLIB_HACMP_is_known_rg $rg if (( $? != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$rg" 1>&2 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 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 CL=$LINENO KLIB_HACMP_is_known_efs >>$CLMGR_TMPLOG 2>&1 typeset -i EFS_ENABLED=$? #============================== : 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 [[ $ATTR == "ALLOW_MODE_CHANGE" ]] && \ (( EFS_ENABLED != RC_SUCCESS )) then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1122 '\nERROR: EFS is not enabled on this system, so no attributes related to EFS may be used: %1$s\n\n' "$ATTR" 1>&2 rc=$RC_INCORRECT_INPUT continue fi if [[ $VALUE != @(y|t|n|f)* ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 110 '\nERROR: invalid value specified for "%1$s": "%2$s".\n' "$ATTR" "$VALUE" 1>&2 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 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 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 #================================== typeset KS_VALS="file,none" typeset AKS_VALS="file,none" if [[ $registryUC == "LDAP" ]]; then KS_VALS="LDAP" AKS_VALS="file" fi for PAIR in "KEYSTORE_ACCESS|$keystore_access|$KS_VALS" \ "ADMIN_KEYSTORE_ACCESS|$admin_keystore_access|$AKS_VALS" \ "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|$(lsrole ALL | 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 if [[ $ATTR == *@(KEYSTORE|ENC)* ]] && \ (( EFS_ENABLED != RC_SUCCESS )) then cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1122 '\nERROR: EFS is not enabled on this system, so no attributes related to EFS may be used: %1$s\n\n' "$ATTR" 1>&2 rc=$RC_INCORRECT_INPUT continue fi ACCEPTED=${ACCEPTED//$NL/,} ACCEPTED_LC=$ACCEPTED typeset -i INVALID=0 for VALUE in ${VALUE//,/ }; do VALUE_LC=$VALUE if [[ ",$ACCEPTED_LC," != *,$VALUE_LC,* ]]; then 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 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 'Valid values: %1$s\n\n' "${ACCEPTED//,/, }" 1>&2 rc=$RC_INCORRECT_INPUT fi done #============================================================== : Perform a few LDAP-only validations and default assignments #============================================================== if [[ $registryUC == "LDAP" ]]; then if [[ $roles == *([[:space:]]) ]]; then dspmsg -s $CLMGR_SET $CLMGR_MSGS 200 '\nERROR: missing required argument: %1$s\n' "ROLES" 1>&2 dspmsg -s $CLMGR_SET $CLMGR_MSGS 3 'Valid values: %1$s\n\n' "ha_admin, ha_op, ha_mon, ha_view, ..." 1>&2 rc=$RC_MISSING_INPUT fi if [[ $authentication != *([[:space:]]) ]]; then typeset -u authUC=$authentication if [[ $authUC == LD* ]]; then authentication="LDAP" else cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 36 '\nERROR: conflicting options were provided, "%1$s" versus "%2$s".\n\n' "REGISTRY=$registry" AUTHENTICATION=$authentication 1>&2 rc=$RC_INCORRECT_INPUT fi else authentication="LDAP" fi fi #======================================================== : Create the user if no input errors have been detected #======================================================== if (( $rc == RC_UNKNOWN )); then typeset rgOpt= idOpt= kaOpt= akaOpt= kmOpt= amcOpt= keOpt= feOpt= rOpt= 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" [[ $registry != *([[:space:]]) ]] && rOpt=" registry=$registry" [[ $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 [[ $registryUC == "LDAP" ]]; then print -- "$0()[$LINENO]($SECONDS): mode=LDAP $HACSPOC/fix_args nop cl_mkuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$rOpt$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_mkuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$rOpt$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_mkuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$rOpt$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_mkuser$rgOpt$idOpt$kaOpt$akaOpt$kmOpt$amcOpt$keOpt$feOpt$rOpt$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_mkuser RC: $rc" >>$CLMGR_TMPLOG if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 201 '\nERROR: failed to create "%1$s".\n\n' "$user" 1>&2 rc=$RC_ERROR #==================================================== : If a password was specified, set the new password #==================================================== elif [[ " ${!_ENV_ARGS[*]} " == *\ PASSWORD\ * ]] then 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 $HASBIN/cl_chpasswd$cspocOpt$kOpt $user $password rc=$? if [[ $CLMGR_LOGGING == 'high' ]]; then print -u2 "$PS4: typeset -i rc=$rc" set -x fi if (( $rc != RC_SUCCESS )); then dspmsg -s $CLMGR_SET $CLMGR_MSGS 400 '\nERROR: failed to modify "%1$s".\n\n' "$user" 1>&2 rc=$RC_ERROR fi fi #====================================================== : Add the user to the allow list, if it was requested #====================================================== if (( $rc == RC_SUCCESS )) && [[ $allow_password_change == @(Y|T|1)* ]]; then 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 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_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_add_user()" #============================================================================ # # Name: devDoc # # Description: This is a never-to-be-called, wrapper function that all the # clmgr FPATH functions implement in order to hide embedded # syntax from trace logging. This information is implemented # in POD format, and can be viewed in a number of ways using # POD tools. Some viewing suggestions for this function's POD- # formatted information are: # # perldoc # pod2text -c # pod2text -c --code # pod2html # # However, the more important use for this information is that # it is parsed by clmgr to display the syntax for this file's # operation. The information in the "SYNOPSIS" section is used # for this purpose. This feature was originally implemented # using the man page information. However, in a code review it # was pointed out that this approach had to be changed because # customers do not have to install the man pages! Therefore, a # built-in dependency on man page information would break the # automatic help feature of clmgr. So the SYNPOSIS section must # be used instead. # # IMPORTANT: As a result of this, it is imperative that the # information in this SYNOPSIS be kept in sync # with the man page information, which is owned # by the IDD team. # # Inputs: None. # # Outputs: None. # # Returns: n/a (not intended to be invoked) # #============================================================================ function devDoc { : <<'=cut' >/dev/null 2>&1 =head1 NAME KLIB_HACMP_add_user =head1 VERSION Version Number: 1.8.1.1 Last Extracted: 3/9/16 04:24:49 Last Changed: 3/8/16 12:45:30 Path, Component, Release(, Level): src/43haes/lib/ksh93/hacmp/KLIB_HACMP_add_user.sh, hacmp.assist, 61haes_r721, 1610A_hacmp721 =head1 SYNOPSIS clmgr add user \ RESOURCE_GROUP= \ [ ID=### ] \ [ ADMINISTRATIVE={false|true} ] \ [ PASSWORD="{|}" ] \ [ CHANGE_ON_NEXT_LOGIN={true|false} ] \ [ PRIMARY= ] \ [ GROUPS=[,,...] ] \ [ ADMIN_GROUPS=[,,...] ] \ [ ROLES=[,,...] ] \ [ SWITCH_USER={true|false} ] \ [ SU_GROUPS={ALL|[,,...]} ] \ [ HOME= ] \ [ SHELL= ] \ [ INFO= ] \ [ EXPIRATION= ] \ [ LOCKED={false|true} ] \ [ LOGIN={true|false} ] \ [ REMOTE_LOGIN={true|false} ] \ [ SCHEDULE=[,,...>] ] \ [ MAX_FAILED_LOGINS={#|0} ] \ [ AUTHENTICATION={compat|files|DCE|ldap} ] \ [ ALLOWED_TTYS=[,,...] ] \ [ DAYS_TO_WARN={#|0} ] \ [ PASSWORD_VALIDATION_METHODS=[,,...]]\ [ PASSWORD_FILTERS=[,,...] ] \ [ MIN_PASSWORDS= ] \ [ REUSE_TIME= ] \ [ LOCKOUT_DELAY= ] \ [ 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=[,,...] ] \ [ TRUSTED_PATH={nosak|on|notsh|always} ] \ [ PRIMARY_AUTH={SYSTEM|.} ] \ [ SECONDARY_AUTH={NONE|SYSTEM|;} ] \ [ PROJECTS=[,,...] ] \ [ 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} ] \ [ ALLOW_PASSWORD_CHANGE={no|yes} ] 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. 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 new user's information is to be stored. If the user is being defined locally, within AIX, than the value "LOCAL" should be used. If the user is being 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. 2011,2016 All Rights Reserved =cut } # End of "devDoc()" #============================================================================== # The following, comment block attempts to enforce coding standards when this # file is edited via emacs or vim. This block _must_ appear at the very end # of the file, or the editor will not find it, and it will be ignored. #============================================================================== # Local Variables: # indent-tabs-mode: nil # tab-width: 4 # End: #============================================================================== # vim: tabstop=4 shiftwidth=4 expandtab #==============================================================================