1f589320aSDevin Teskeif [ ! "$_USERMGMT_USER_SUBR" ]; then _USERMGMT_USER_SUBR=1 2f589320aSDevin Teske# 3f589320aSDevin Teske# Copyright (c) 2012 Ron McDowell 435994c42SDevin Teske# Copyright (c) 2012-2015 Devin Teske 5f589320aSDevin Teske# All rights reserved. 6f589320aSDevin Teske# 7f589320aSDevin Teske# Redistribution and use in source and binary forms, with or without 8f589320aSDevin Teske# modification, are permitted provided that the following conditions 9f589320aSDevin Teske# are met: 10f589320aSDevin Teske# 1. Redistributions of source code must retain the above copyright 11f589320aSDevin Teske# notice, this list of conditions and the following disclaimer. 12f589320aSDevin Teske# 2. Redistributions in binary form must reproduce the above copyright 13f589320aSDevin Teske# notice, this list of conditions and the following disclaimer in the 14f589320aSDevin Teske# documentation and/or other materials provided with the distribution. 15f589320aSDevin Teske# 16f589320aSDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17f589320aSDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18f589320aSDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19f589320aSDevin Teske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20f589320aSDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21f589320aSDevin Teske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22f589320aSDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23f589320aSDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24f589320aSDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25f589320aSDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26f589320aSDevin Teske# SUCH DAMAGE. 27f589320aSDevin Teske# 28f589320aSDevin Teske# 29f589320aSDevin Teske############################################################ INCLUDES 30f589320aSDevin Teske 31f589320aSDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig" 32f589320aSDevin Teske. $BSDCFG_SHARE/common.subr || exit 1 33f589320aSDevin Teskef_dprintf "%s: loading includes..." usermgmt/user.subr 34f589320aSDevin Teskef_include $BSDCFG_SHARE/dialog.subr 35f589320aSDevin Teskef_include $BSDCFG_SHARE/strings.subr 36f589320aSDevin Teskef_include $BSDCFG_SHARE/usermgmt/group_input.subr 37f589320aSDevin Teskef_include $BSDCFG_SHARE/usermgmt/user_input.subr 38f589320aSDevin Teske 39f589320aSDevin TeskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" 40f589320aSDevin Teskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 41f589320aSDevin Teske 42f589320aSDevin Teske############################################################ CONFIGURATION 43f589320aSDevin Teske 44f589320aSDevin Teske# set some reasonable defaults if /etc/adduser.conf does not exist. 45f589320aSDevin Teske[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf 46f589320aSDevin Teske: ${defaultclass:=""} 47f589320aSDevin Teske: ${defaultshell:="/bin/sh"} 48f589320aSDevin Teske: ${homeprefix:="/home"} 49f589320aSDevin Teske: ${passwdtype:="yes"} 50f589320aSDevin Teske: ${udotdir:="/usr/share/skel"} 51f589320aSDevin Teske: ${uexpire:=""} 52f589320aSDevin Teske # Default account expire time. Format is similar to upwexpire variable. 53f589320aSDevin Teske: ${ugecos:="User &"} 54f589320aSDevin Teske: ${upwexpire:=""} 55f589320aSDevin Teske # The default password expiration time. Format of the date is either a 56f589320aSDevin Teske # UNIX time in decimal, or a date in dd-mmm-yy[yy] format, where dd is 57f589320aSDevin Teske # the day, mmm is the month in either numeric or alphabetic format, and 58f589320aSDevin Teske # yy[yy] is either a two or four digit year. This variable also accepts 59f589320aSDevin Teske # a relative date in the form of n[mhdwoy] where n is a decimal, octal 60f589320aSDevin Teske # (leading 0) or hexadecimal (leading 0x) digit followed by the number 61f589320aSDevin Teske # of Minutes, Hours, Days, Weeks, Months or Years from the current date 62f589320aSDevin Teske # at which the expiration time is to be set. 63f589320aSDevin Teske 64f589320aSDevin Teske# 65f589320aSDevin Teske# uexpire and upwexpire from adduser.conf(5) differ only slightly from what 66f589320aSDevin Teske# pw(8) accepts as `date' argument(s); pw(8) requires a leading `+' for the 67f589320aSDevin Teske# relative date syntax (n[mhdwoy]). 68f589320aSDevin Teske# 69f589320aSDevin Teskecase "$uexpire" in *[mhdwoy]) 70f589320aSDevin Teske f_isinteger "${uexpire%[mhdwoy]}" && uexpire="+$uexpire" 71f589320aSDevin Teskeesac 72f589320aSDevin Teskecase "$upwexpire" in *[mhdwoy]) 73f589320aSDevin Teske f_isinteger "${upwexpire%[mhdwoy]}" && upwexpire="+$upwexpire" 74f589320aSDevin Teskeesac 75f589320aSDevin Teske 76f589320aSDevin Teske############################################################ FUNCTIONS 77f589320aSDevin Teske 78f589320aSDevin Teske# f_user_create_homedir $user 79f589320aSDevin Teske# 80f589320aSDevin Teske# Create home directory for $user. 81f589320aSDevin Teske# 82f589320aSDevin Teskef_user_create_homedir() 83f589320aSDevin Teske{ 84f589320aSDevin Teske local funcname=f_user_create_homedir 85f589320aSDevin Teske local user="$1" 86f589320aSDevin Teske 87f589320aSDevin Teske [ "$user" ] || return $FAILURE 88f589320aSDevin Teske 89f589320aSDevin Teske local user_account_expire user_class user_gecos user_gid user_home_dir 90f589320aSDevin Teske local user_member_groups user_name user_password user_password_expire 91f589320aSDevin Teske local user_shell user_uid # Variables created by f_input_user() below 92f589320aSDevin Teske f_input_user "$user" || return $FAILURE 93f589320aSDevin Teske 94f589320aSDevin Teske f_dprintf "Creating home directory \`%s' for user \`%s'" \ 95f589320aSDevin Teske "$user_home_dir" "$user" 96f589320aSDevin Teske 97f589320aSDevin Teske local _user_gid _user_home_dir _user_uid 98f589320aSDevin Teske f_shell_escape "$user_gid" _user_gid 99f589320aSDevin Teske f_shell_escape "$user_home_dir" _user_home_dir 100f589320aSDevin Teske f_shell_escape "$user_uid" _user_uid 101f589320aSDevin Teske f_eval_catch $funcname mkdir "mkdir -p '%s'" "$_user_home_dir" || 102f589320aSDevin Teske return $FAILURE 103f589320aSDevin Teske f_eval_catch $funcname chown "chown '%i:%i' '%s'" \ 104f589320aSDevin Teske "$_user_uid" "$_user_gid" "$_user_home_dir" || return $FAILURE 105f589320aSDevin Teske} 106f589320aSDevin Teske 107f589320aSDevin Teske# f_user_copy_dotfiles $user 108f589320aSDevin Teske# 109f589320aSDevin Teske# Copy `skel' dot-files from $udotdir (global inherited from /etc/adduser.conf) 110f589320aSDevin Teske# to the home-directory of $user. Attempts to create the home-directory first 111f589320aSDevin Teske# if it doesn't exist. 112f589320aSDevin Teske# 113f589320aSDevin Teskef_user_copy_dotfiles() 114f589320aSDevin Teske{ 115f589320aSDevin Teske local funcname=f_user_copy_dotfiles 116f589320aSDevin Teske local user="$1" 117f589320aSDevin Teske 118f589320aSDevin Teske [ "$udotdir" ] || return $FAILURE 119f589320aSDevin Teske [ "$user" ] || return $FAILURE 120f589320aSDevin Teske 121f589320aSDevin Teske local user_account_expire user_class user_gecos user_gid user_home_dir 122f589320aSDevin Teske local user_member_groups user_name user_password user_password_expire 123f589320aSDevin Teske local user_shell user_uid # Variables created by f_input_user() below 124f589320aSDevin Teske f_input_user "$user" || return $FAILURE 125f589320aSDevin Teske 126f589320aSDevin Teske f_dprintf "Copying dot-files from \`%s' to \`%s'" \ 127f589320aSDevin Teske "$udotdir" "$user_home_dir" 128f589320aSDevin Teske 129f589320aSDevin Teske # Attempt to create the home directory if it doesn't exist 130f589320aSDevin Teske [ -d "$user_home_dir" ] || 131f589320aSDevin Teske f_user_create_homedir "$user" || return $FAILURE 132f589320aSDevin Teske 133f589320aSDevin Teske local _user_gid _user_home_dir _user_uid 134f589320aSDevin Teske f_shell_escape "$user_gid" _user_gid 135f589320aSDevin Teske f_shell_escape "$user_home_dir" _user_home_dir 136f589320aSDevin Teske f_shell_escape "$user_uid" _user_uid 137f589320aSDevin Teske 138f589320aSDevin Teske local - # Localize `set' to this function 139f589320aSDevin Teske set +f # Enable glob pattern-matching for paths 140f589320aSDevin Teske cd "$udotdir" || return $FAILURE 141f589320aSDevin Teske 142f589320aSDevin Teske local _file file retval 143f589320aSDevin Teske for file in dot.*; do 144f589320aSDevin Teske [ -e "$file" ] || continue # no-match 145f589320aSDevin Teske 146f589320aSDevin Teske f_shell_escape "$file" "_file" 147f589320aSDevin Teske f_eval_catch $funcname cp "cp -n '%s' '%s'" \ 148f589320aSDevin Teske "$_file" "$_user_home_dir/${_file#dot}" 149f589320aSDevin Teske retval=$? 150f589320aSDevin Teske [ $retval -eq $SUCCESS ] || break 151f589320aSDevin Teske f_eval_catch $funcname chown \ 152f589320aSDevin Teske "chown -h '%i:%i' '%s'" \ 153f589320aSDevin Teske "$_user_uid" "$_user_gid" \ 154f589320aSDevin Teske "$_user_home_dir/${_file#dot}" 155f589320aSDevin Teske retval=$? 156f589320aSDevin Teske [ $retval -eq $SUCCESS ] || break 157f589320aSDevin Teske done 158f589320aSDevin Teske 159f589320aSDevin Teske cd - 160f589320aSDevin Teske return $retval 161f589320aSDevin Teske} 162f589320aSDevin Teske 163f589320aSDevin Teske# f_user_add [$user] 164f589320aSDevin Teske# 165f589320aSDevin Teske# Create a login account. If both $user (as a first argument) and $VAR_USER are 166f589320aSDevin Teske# unset or NULL and we are running interactively, prompt the end-user to enter 167f589320aSDevin Teske# the name of a new login account and (if $VAR_NO_CONFIRM is unset or NULL) 168f589320aSDevin Teske# prompt the end-user to answer some questions about the new account. Variables 169f589320aSDevin Teske# that can be used to script user input: 170f589320aSDevin Teske# 171f589320aSDevin Teske# VAR_USER [Optional if running interactively] 172f589320aSDevin Teske# The login to add. Ignored if given non-NULL first-argument. 173f589320aSDevin Teske# VAR_USER_ACCOUNT_EXPIRE [Optional] 174f589320aSDevin Teske# The account expiration time. Format is similar to 175f589320aSDevin Teske# VAR_USER_PASSWORD_EXPIRE variable below. Default is to never 176f589320aSDevin Teske# expire the account. 177f589320aSDevin Teske# VAR_USER_DOTFILES_CREATE [Optional] 178f589320aSDevin Teske# If non-NULL, populate the user's home directory with the 179f589320aSDevin Teske# template files found in $udotdir (`/usr/share/skel' default). 180f589320aSDevin Teske# VAR_USER_GECOS [Optional] 181f589320aSDevin Teske# Often the full name of the account holder. Default is NULL. 182f589320aSDevin Teske# VAR_USER_GID [Optional] 183f589320aSDevin Teske# Numerical primary-group ID to use. If NULL or unset, the group 184f589320aSDevin Teske# ID is automatically chosen. 185f589320aSDevin Teske# VAR_USER_GROUPS [Optional] 186f589320aSDevin Teske# Comma-separated list of additional groups to which the user is 187f589320aSDevin Teske# a member of. Default is NULL (no additional groups). 188f589320aSDevin Teske# VAR_USER_HOME [Optional] 189f589320aSDevin Teske# The home directory to set. If NULL or unset, the home directory 190f589320aSDevin Teske# is automatically calculated. 191f589320aSDevin Teske# VAR_USER_HOME_CREATE [Optional] 192f589320aSDevin Teske# If non-NULL, create the user's home directory if it doesn't 193f589320aSDevin Teske# already exist. 194f589320aSDevin Teske# VAR_USER_LOGIN_CLASS [Optional] 195f589320aSDevin Teske# Login class to use when creating the login. Default is NULL. 196f589320aSDevin Teske# VAR_USER_PASSWORD [Optional] 197f589320aSDevin Teske# Unencrypted password to use. If unset or NULL, password 198f589320aSDevin Teske# authentication for the login is disabled. 199f589320aSDevin Teske# VAR_USER_PASSWORD_EXPIRE [Optional] 200f589320aSDevin Teske# The password expiration time. Format of the date is either a 201f589320aSDevin Teske# UNIX time in decimal, or a date in dd-mmm-yy[yy] format, where 202f589320aSDevin Teske# dd is the day, mmm is the month in either numeric or alphabetic 203f589320aSDevin Teske# format, and yy[yy] is either a two or four digit year. This 204f589320aSDevin Teske# variable also accepts a relative date in the form of +n[mhdwoy] 205f589320aSDevin Teske# where n is a decimal, octal (leading 0) or hexadecimal (leading 206f589320aSDevin Teske# 0x) digit followed by the number of Minutes, Hours, Days, 207f589320aSDevin Teske# Weeks, Months or Years from the current date at which the 208f589320aSDevin Teske# expiration time is to be set. Default is to never expire the 209f589320aSDevin Teske# account password. 210f589320aSDevin Teske# VAR_USER_SHELL [Optional] 211f589320aSDevin Teske# Path to login shell to use. Default is `/bin/sh'. 212f589320aSDevin Teske# VAR_USER_UID [Optional] 213f589320aSDevin Teske# Numerical user ID to use. If NULL or unset, the user ID is 214f589320aSDevin Teske# automatically chosen. 215f589320aSDevin Teske# 216f589320aSDevin Teske# Returns success if the user account was successfully created. 217f589320aSDevin Teske# 218f589320aSDevin Teskef_user_add() 219f589320aSDevin Teske{ 220f589320aSDevin Teske local funcname=f_user_add 221f589320aSDevin Teske local title # Calculated below 222f589320aSDevin Teske local alert=f_show_msg no_confirm= 223f589320aSDevin Teske 224f589320aSDevin Teske f_getvar $VAR_NO_CONFIRM no_confirm 225f589320aSDevin Teske [ "$no_confirm" ] && alert=f_show_info 226f589320aSDevin Teske 227f589320aSDevin Teske local input 228f589320aSDevin Teske f_getvar 3:-\$$VAR_USER input "$1" 229f589320aSDevin Teske 230f589320aSDevin Teske # 231f589320aSDevin Teske # NB: pw(8) has a ``feature'' wherein `-n name' can be taken as UID 232f589320aSDevin Teske # instead of name. Work-around is to also pass `-u UID' at the same 233*e8e8c939SDevin Teske # time (the UID is ignored in this case, so any UID will do). 234f589320aSDevin Teske # 235*e8e8c939SDevin Teske if [ "$input" ] && f_quietly pw usershow -n "$input" -u 1337; then 236f589320aSDevin Teske f_show_err "$msg_login_already_used" "$input" 237f589320aSDevin Teske return $FAILURE 238f589320aSDevin Teske fi 239f589320aSDevin Teske 240f589320aSDevin Teske local user_name="$input" 241f589320aSDevin Teske while f_interactive && [ ! "$user_name" ]; do 242f589320aSDevin Teske f_dialog_input_name user_name "$user_name" || 243f589320aSDevin Teske return $SUCCESS 244f589320aSDevin Teske [ "$user_name" ] || 245f589320aSDevin Teske f_show_err "$msg_please_enter_a_user_name" 246f589320aSDevin Teske done 247f589320aSDevin Teske if [ ! "$user_name" ]; then 248f589320aSDevin Teske f_show_err "$msg_no_user_specified" 249f589320aSDevin Teske return $FAILURE 250f589320aSDevin Teske fi 251f589320aSDevin Teske 252f589320aSDevin Teske local user_account_expire user_class user_gecos user_gid user_home_dir 253f589320aSDevin Teske local user_member_groups user_password user_password_expire user_shell 254f589320aSDevin Teske local user_uid user_dotfiles_create= user_home_create= 255f589320aSDevin Teske f_getvar $VAR_USER_ACCOUNT_EXPIRE-\$uexpire user_account_expire 256f589320aSDevin Teske f_getvar $VAR_USER_DOTFILES_CREATE:+\$msg_yes user_dotfiles_create 257f589320aSDevin Teske f_getvar $VAR_USER_GECOS-\$ugecos user_gecos 258f589320aSDevin Teske f_getvar $VAR_USER_GID user_gid 259f589320aSDevin Teske f_getvar $VAR_USER_GROUPS user_member_groups 260f589320aSDevin Teske f_getvar $VAR_USER_HOME:-\${homeprefix%/}/\$user_name \ 261f589320aSDevin Teske user_home_dir 262f589320aSDevin Teske f_getvar $VAR_USER_HOME_CREATE:+\$msg_yes user_home_create 263f589320aSDevin Teske f_getvar $VAR_USER_LOGIN_CLASS-\$defaultclass user_class 264f589320aSDevin Teske f_getvar $VAR_USER_PASSWORD user_password 265f589320aSDevin Teske f_getvar $VAR_USER_PASSWORD_EXPIRE-\$upwexpire user_password_expire 266f589320aSDevin Teske f_getvar $VAR_USER_SHELL-\$defaultshell user_shell 267f589320aSDevin Teske f_getvar $VAR_USER_UID user_uid 268f589320aSDevin Teske 269f589320aSDevin Teske # Create home-dir if no script-override and does not exist 270f589320aSDevin Teske f_isset $VAR_USER_HOME_CREATE || [ -d "$user_home_dir" ] || 271f589320aSDevin Teske user_home_create="$msg_yes" 272f589320aSDevin Teske # Copy dotfiles if home-dir creation is desired, does not yet exist, 273f589320aSDevin Teske # and no script-override has been set 274f589320aSDevin Teske f_isset $VAR_USER_DOTFILES_CREATE || 275f589320aSDevin Teske [ "$user_home_create" != "$msg_yes" ] || 276f589320aSDevin Teske [ -d "$user_home_dir" ] || user_dotfiles_create="$msg_yes" 277f589320aSDevin Teske # Create home-dir if copying dotfiles but home-dir does not exist 278f589320aSDevin Teske [ "$user_dotfiles_create" -a ! -d "$user_home_dir" ] && 279f589320aSDevin Teske user_home_create="$msg_yes" 280f589320aSDevin Teske 281f589320aSDevin Teske # Set flags for meaningful NULL values if-provided 282f589320aSDevin Teske local no_account_expire= no_password_expire= null_gecos= null_members= 283f589320aSDevin Teske local user_password_disable= 284f589320aSDevin Teske f_isset $VAR_USER_ACCOUNT_EXPIRE && 285f589320aSDevin Teske [ ! "$user_account_expire" ] && no_account_expire=1 286f589320aSDevin Teske f_isset $VAR_USER_GECOS && 287f589320aSDevin Teske [ ! "$user_gecos" ] && null_gecos=1 288f589320aSDevin Teske f_isset $VAR_USER_GROUPS && 289f589320aSDevin Teske [ ! "$user_member_groups" ] && null_members=1 290f589320aSDevin Teske f_isset $VAR_USER_PASSWORD && 291f589320aSDevin Teske [ ! "$user_password" ] && user_password_disable=1 292f589320aSDevin Teske f_isset $VAR_USER_PASSWORD_EXPIRE && 293f589320aSDevin Teske [ ! "$user_password_expire" ] && no_password_expire=1 294f589320aSDevin Teske 295f589320aSDevin Teske if f_interactive && [ ! "$no_confirm" ]; then 296f589320aSDevin Teske f_dialog_noyes \ 297f589320aSDevin Teske "$msg_use_default_values_for_all_account_details" 298f589320aSDevin Teske retval=$? 299f589320aSDevin Teske if [ $retval -eq $DIALOG_ESC ]; then 300f589320aSDevin Teske return $SUCCESS 301f589320aSDevin Teske elif [ $retval -ne $DIALOG_OK ]; then 302f589320aSDevin Teske # 303f589320aSDevin Teske # Ask series of questions to pre-fill the editor screen 304f589320aSDevin Teske # 305f589320aSDevin Teske # Defaults used in each dialog should allow the user to 306f589320aSDevin Teske # simply hit ENTER to proceed, because cancelling any 307f589320aSDevin Teske # single dialog will cause them to be returned to the 308f589320aSDevin Teske # previous menu. 309f589320aSDevin Teske # 310f589320aSDevin Teske 311f589320aSDevin Teske f_dialog_input_gecos user_gecos "$user_gecos" || 312f589320aSDevin Teske return $FAILURE 313f589320aSDevin Teske if [ "$passwdtype" = "yes" ]; then 314f589320aSDevin Teske f_dialog_input_password user_password \ 315f589320aSDevin Teske user_password_disable || 316f589320aSDevin Teske return $FAILURE 317f589320aSDevin Teske fi 318f589320aSDevin Teske f_dialog_input_uid user_uid "$user_uid" || 319f589320aSDevin Teske return $FAILURE 320f589320aSDevin Teske f_dialog_input_gid user_gid "$user_gid" || 321f589320aSDevin Teske return $FAILURE 322f589320aSDevin Teske f_dialog_input_member_groups user_member_groups \ 323f589320aSDevin Teske "$user_member_groups" || return $FAILURE 324f589320aSDevin Teske f_dialog_input_class user_class "$user_class" || 325f589320aSDevin Teske return $FAILURE 326f589320aSDevin Teske f_dialog_input_expire_password user_password_expire \ 327f589320aSDevin Teske "$user_password_expire" || return $FAILURE 328f589320aSDevin Teske f_dialog_input_expire_account user_account_expire \ 329f589320aSDevin Teske "$user_account_expire" || return $FAILURE 330f589320aSDevin Teske f_dialog_input_home_dir user_home_dir \ 331f589320aSDevin Teske "$user_home_dir" || return $FAILURE 332f589320aSDevin Teske if [ ! -d "$user_home_dir" ]; then 333f589320aSDevin Teske f_dialog_input_home_create user_home_create || 334f589320aSDevin Teske return $FAILURE 335f589320aSDevin Teske if [ "$user_home_create" = "$msg_yes" ]; then 336f589320aSDevin Teske f_dialog_input_dotfiles_create \ 337f589320aSDevin Teske user_dotfiles_create || 338f589320aSDevin Teske return $FAILURE 339f589320aSDevin Teske fi 340f589320aSDevin Teske fi 341f589320aSDevin Teske f_dialog_input_shell user_shell "$user_shell" || 342f589320aSDevin Teske return $FAILURE 343f589320aSDevin Teske fi 344f589320aSDevin Teske fi 345f589320aSDevin Teske 346f589320aSDevin Teske # 347f589320aSDevin Teske # Loop until the user decides to Exit, Cancel, or presses ESC 348f589320aSDevin Teske # 349f589320aSDevin Teske title="$msg_add $msg_user: $user_name" 350f589320aSDevin Teske if f_interactive; then 351f589320aSDevin Teske local mtag retval defaultitem= 352f589320aSDevin Teske while :; do 353f589320aSDevin Teske f_dialog_title "$title" 354f589320aSDevin Teske f_dialog_menu_user_add "$defaultitem" 355f589320aSDevin Teske retval=$? 356f589320aSDevin Teske f_dialog_title_restore 357f589320aSDevin Teske f_dialog_menutag_fetch mtag 358f589320aSDevin Teske f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" 359f589320aSDevin Teske defaultitem="$mtag" 360f589320aSDevin Teske 361f589320aSDevin Teske # Return if user either pressed ESC or chose Cancel/No 362f589320aSDevin Teske [ $retval -eq $DIALOG_OK ] || return $FAILURE 363f589320aSDevin Teske 364f589320aSDevin Teske case "$mtag" in 365f589320aSDevin Teske X) # Add/Exit 366f589320aSDevin Teske local var 367f589320aSDevin Teske for var in account_expire class gecos gid home_dir \ 368f589320aSDevin Teske member_groups name password_expire shell uid \ 369f589320aSDevin Teske ; do 370f589320aSDevin Teske local _user_$var 371f589320aSDevin Teske eval f_shell_escape \"\$user_$var\" _user_$var 372f589320aSDevin Teske done 373f589320aSDevin Teske 374f589320aSDevin Teske local cmd="pw useradd -n '$_user_name'" 375f589320aSDevin Teske [ "$user_gid" ] && cmd="$cmd -g '$_user_gid'" 376f589320aSDevin Teske [ "$user_shell" ] && cmd="$cmd -s '$_user_shell'" 377f589320aSDevin Teske [ "$user_uid" ] && cmd="$cmd -u '$_user_uid'" 378f589320aSDevin Teske [ "$user_account_expire" -o \ 379f589320aSDevin Teske "$no_account_expire" ] && 380f589320aSDevin Teske cmd="$cmd -e '$_user_account_expire'" 381f589320aSDevin Teske [ "$user_class" -o "$null_class" ] && 382f589320aSDevin Teske cmd="$cmd -L '$_user_class'" 383f589320aSDevin Teske [ "$user_gecos" -o "$null_gecos" ] && 384f589320aSDevin Teske cmd="$cmd -c '$_user_gecos'" 385f589320aSDevin Teske [ "$user_home_dir" ] && 386f589320aSDevin Teske cmd="$cmd -d '$_user_home_dir'" 387f589320aSDevin Teske [ "$user_member_groups" ] && 388f589320aSDevin Teske cmd="$cmd -G '$_user_member_groups'" 389f589320aSDevin Teske [ "$user_password_expire" -o \ 390f589320aSDevin Teske "$no_password_expire" ] && 391f589320aSDevin Teske cmd="$cmd -p '$_user_password_expire'" 392f589320aSDevin Teske 393f589320aSDevin Teske # Execute the command 394f589320aSDevin Teske if [ "$user_password_disable" ]; then 395f589320aSDevin Teske f_eval_catch $funcname pw '%s -h -' "$cmd" 396f589320aSDevin Teske elif [ "$user_password" ]; then 397f589320aSDevin Teske echo "$user_password" | f_eval_catch \ 398f589320aSDevin Teske $funcname pw '%s -h 0' "$cmd" 399f589320aSDevin Teske else 400f589320aSDevin Teske f_eval_catch $funcname pw '%s' "$cmd" 401f589320aSDevin Teske fi || continue 402f589320aSDevin Teske 403f589320aSDevin Teske # Create home directory if desired 404f589320aSDevin Teske [ "${user_home_create:-$msg_no}" != "$msg_no" ] && 405f589320aSDevin Teske f_user_create_homedir "$user_name" 406f589320aSDevin Teske 407f589320aSDevin Teske # Copy dotfiles if desired 408f589320aSDevin Teske [ "${user_dotfiles_create:-$msg_no}" != \ 409f589320aSDevin Teske "$msg_no" ] && f_user_copy_dotfiles "$user_name" 410f589320aSDevin Teske 411f589320aSDevin Teske break # to success 412f589320aSDevin Teske ;; 413f589320aSDevin Teske 1) # Login (prompt for new login name) 414f589320aSDevin Teske f_dialog_input_name input "$user_name" || 415f589320aSDevin Teske continue 416*e8e8c939SDevin Teske if f_quietly pw usershow -n "$input" -u 1337; then 417f589320aSDevin Teske f_show_err "$msg_login_already_used" "$input" 418f589320aSDevin Teske continue 419f589320aSDevin Teske fi 420f589320aSDevin Teske user_name="$input" 421f589320aSDevin Teske title="$msg_add $msg_user: $user_name" 422f589320aSDevin Teske user_home_dir="${homeprefix%/}/$user_name" 423f589320aSDevin Teske ;; 424f589320aSDevin Teske 2) # Full Name 425f589320aSDevin Teske f_dialog_input_gecos user_gecos "$user_gecos" && 426f589320aSDevin Teske [ ! "$user_gecos" ] && null_gecos=1 ;; 427f589320aSDevin Teske 3) # Password 428f589320aSDevin Teske f_dialog_input_password \ 429f589320aSDevin Teske user_password user_password_disable ;; 430f589320aSDevin Teske 4) # User ID 431f589320aSDevin Teske f_dialog_input_uid user_uid "$user_uid" ;; 432f589320aSDevin Teske 5) # Group ID 433f589320aSDevin Teske f_dialog_input_gid user_gid "$user_gid" ;; 434f589320aSDevin Teske 6) # Member of Groups 435f589320aSDevin Teske f_dialog_input_member_groups \ 436f589320aSDevin Teske user_member_groups "$user_member_groups" && 437f589320aSDevin Teske [ ! "$user_member_groups" ] && 438f589320aSDevin Teske null_members=1 ;; 439f589320aSDevin Teske 7) # Login Class 440f589320aSDevin Teske f_dialog_input_class user_class "$user_class" && 441f589320aSDevin Teske [ ! "$user_class" ] && null_class=1 ;; 442f589320aSDevin Teske 8) # Password Expires On 443f589320aSDevin Teske f_dialog_input_expire_password \ 444f589320aSDevin Teske user_password_expire "$user_password_expire" && 445f589320aSDevin Teske [ ! "$user_password_expire" ] && 446f589320aSDevin Teske no_password_expire=1 ;; 447f589320aSDevin Teske 9) # Account Expires On 448f589320aSDevin Teske f_dialog_input_expire_account \ 449f589320aSDevin Teske user_account_expire "$user_account_expire" && 450f589320aSDevin Teske [ ! "$user_account_expire" ] && 451f589320aSDevin Teske no_account_expire=1 ;; 452f589320aSDevin Teske A) # Home Directory 453f589320aSDevin Teske f_dialog_input_home_dir \ 454f589320aSDevin Teske user_home_dir "$user_home_dir" ;; 455f589320aSDevin Teske B) # Shell 456f589320aSDevin Teske f_dialog_input_shell user_shell "$user_shell" ;; 457f589320aSDevin Teske C) # Create Home Directory? 458f589320aSDevin Teske if [ "${user_home_create:-$msg_no}" != "$msg_no" ] 459f589320aSDevin Teske then 460f589320aSDevin Teske user_home_create="$msg_no" 461f589320aSDevin Teske else 462f589320aSDevin Teske user_home_create="$msg_yes" 463f589320aSDevin Teske fi ;; 464f589320aSDevin Teske D) # Create Dotfiles? 465f589320aSDevin Teske if [ "${user_dotfiles_create:-$msg_no}" != \ 466f589320aSDevin Teske "$msg_no" ] 467f589320aSDevin Teske then 468f589320aSDevin Teske user_dotfiles_create="$msg_no" 469f589320aSDevin Teske else 470f589320aSDevin Teske user_dotfiles_create="$msg_yes" 471f589320aSDevin Teske fi ;; 472f589320aSDevin Teske esac 473f589320aSDevin Teske done 474f589320aSDevin Teske else 475f589320aSDevin Teske local var 476f589320aSDevin Teske for var in account_expire class gecos gid home_dir \ 477f589320aSDevin Teske member_groups name password_expire shell uid \ 478f589320aSDevin Teske ; do 479f589320aSDevin Teske local _user_$var 480f589320aSDevin Teske eval f_shell_escape \"\$user_$var\" _user_$var 481f589320aSDevin Teske done 482f589320aSDevin Teske 483f589320aSDevin Teske # Form the command 484f589320aSDevin Teske local cmd="pw useradd -n '$_user_name'" 485f589320aSDevin Teske [ "$user_gid" ] && cmd="$cmd -g '$_user_gid'" 486f589320aSDevin Teske [ "$user_home_dir" ] && cmd="$cmd -d '$_user_home_dir'" 487f589320aSDevin Teske [ "$user_shell" ] && cmd="$cmd -s '$_user_shell'" 488f589320aSDevin Teske [ "$user_uid" ] && cmd="$cmd -u '$_user_uid'" 489f589320aSDevin Teske [ "$user_account_expire" -o "$no_account_expire" ] && 490f589320aSDevin Teske cmd="$cmd -e '$_user_account_expire'" 491f589320aSDevin Teske [ "$user_class" -o "$null_class" ] && 492f589320aSDevin Teske cmd="$cmd -L '$_user_class'" 493f589320aSDevin Teske [ "$user_gecos" -o "$null_gecos" ] && 494f589320aSDevin Teske cmd="$cmd -c '$_user_gecos'" 495f589320aSDevin Teske [ "$user_member_groups" -o "$null_members" ] && 496f589320aSDevin Teske cmd="$cmd -G '$_user_member_groups'" 497f589320aSDevin Teske [ "$user_password_expire" -o "$no_password_expire" ] && 498f589320aSDevin Teske cmd="$cmd -p '$_user_password_expire'" 499f589320aSDevin Teske 500f589320aSDevin Teske # Execute the command 501f589320aSDevin Teske local retval err 502f589320aSDevin Teske if [ "$user_password_disable" ]; then 503f589320aSDevin Teske f_eval_catch -k err $funcname pw '%s -h -' "$cmd" 504f589320aSDevin Teske elif [ "$user_password" ]; then 505f589320aSDevin Teske err=$( echo "$user_password" | f_eval_catch -de \ 506f589320aSDevin Teske $funcname pw '%s -h 0' "$cmd" 2>&1 ) 507f589320aSDevin Teske else 508f589320aSDevin Teske f_eval_catch -k err $funcname pw '%s' "$cmd" 509f589320aSDevin Teske fi 510f589320aSDevin Teske retval=$? 511f589320aSDevin Teske if [ $retval -ne $SUCCESS ]; then 512f589320aSDevin Teske f_show_err "%s" "$err" 513f589320aSDevin Teske return $retval 514f589320aSDevin Teske fi 515f589320aSDevin Teske 516f589320aSDevin Teske # Create home directory if desired 517f589320aSDevin Teske [ "${user_home_create:-$msg_no}" != "$msg_no" ] && 518f589320aSDevin Teske f_user_create_homedir "$user_name" 519f589320aSDevin Teske 520f589320aSDevin Teske # Copy dotfiles if desired 521f589320aSDevin Teske [ "${user_dotfiles_create:-$msg_no}" != "$msg_no" ] && 522f589320aSDevin Teske f_user_copy_dotfiles "$user_name" 523f589320aSDevin Teske fi 524f589320aSDevin Teske 525f589320aSDevin Teske f_dialog_title "$title" 526f589320aSDevin Teske $alert "$msg_login_added" 527f589320aSDevin Teske f_dialog_title_restore 528f589320aSDevin Teske [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1 529f589320aSDevin Teske 530f589320aSDevin Teske return $SUCCESS 531f589320aSDevin Teske} 532f589320aSDevin Teske 533f589320aSDevin Teske# f_user_delete [$user] 534f589320aSDevin Teske# 535f589320aSDevin Teske# Delete a user. If both $user (as a first argument) and $VAR_USER are unset or 536f589320aSDevin Teske# NULL and we are running interactively, prompt the end-user to select a user 537f589320aSDevin Teske# account from a list of those available. Variables that can be used to script 538f589320aSDevin Teske# user input: 539f589320aSDevin Teske# 540f589320aSDevin Teske# VAR_USER [Optional if running interactively] 541f589320aSDevin Teske# The user to delete. Ignored if given non-NULL first-argument. 542f589320aSDevin Teske# 543f589320aSDevin Teske# Returns success if the user account was successfully deleted. 544f589320aSDevin Teske# 545f589320aSDevin Teskef_user_delete() 546f589320aSDevin Teske{ 547f589320aSDevin Teske local funcname=f_user_delete 548f589320aSDevin Teske local title # Calculated below 549f589320aSDevin Teske local alert=f_show_msg no_confirm= 550f589320aSDevin Teske 551f589320aSDevin Teske f_getvar $VAR_NO_CONFIRM no_confirm 552f589320aSDevin Teske [ "$no_confirm" ] && alert=f_show_info 553f589320aSDevin Teske 554f589320aSDevin Teske local input 555f589320aSDevin Teske f_getvar 3:-\$$VAR_USER input "$1" 556f589320aSDevin Teske 557f589320aSDevin Teske if f_interactive && [ ! "$input" ]; then 558f589320aSDevin Teske f_dialog_menu_user_list || return $SUCCESS 559f589320aSDevin Teske f_dialog_menutag_fetch input 560f589320aSDevin Teske [ "$input" = "X $msg_exit" ] && return $SUCCESS 561f589320aSDevin Teske elif [ ! "$input" ]; then 562f589320aSDevin Teske f_show_err "$msg_no_user_specified" 563f589320aSDevin Teske return $FAILURE 564f589320aSDevin Teske fi 565f589320aSDevin Teske 566f589320aSDevin Teske local user_account_expire user_class user_gecos user_gid user_home_dir 567f589320aSDevin Teske local user_member_groups user_name user_password user_password_expire 568f589320aSDevin Teske local user_shell user_uid # Variables created by f_input_user() below 569f589320aSDevin Teske if [ "$input" ] && ! f_input_user "$input"; then 570f589320aSDevin Teske f_show_err "$msg_login_not_found" "$input" 571f589320aSDevin Teske return $FAILURE 572f589320aSDevin Teske fi 573f589320aSDevin Teske 574f589320aSDevin Teske local user_group_delete= user_home_delete= 575f589320aSDevin Teske f_getvar $VAR_USER_GROUP_DELETE:-\$msg_no user_group_delete 576f589320aSDevin Teske f_getvar $VAR_USER_HOME_DELETE:-\$msg_no user_home_delete 577f589320aSDevin Teske 578f589320aSDevin Teske # Attempt to translate user GID into a group name 579f589320aSDevin Teske local user_group 580f589320aSDevin Teske if user_group=$( pw groupshow -g "$user_gid" 2> /dev/null ); then 581f589320aSDevin Teske user_group="${user_group%%:*}" 582f589320aSDevin Teske # Default to delete the primary group if no script-override and 583f589320aSDevin Teske # exists with same name as the user (same logic used by pw(8)) 584f589320aSDevin Teske f_isset $VAR_USER_GROUP_DELETE || 585f589320aSDevin Teske [ "$user_group" != "$user_name" ] || 586f589320aSDevin Teske user_group_delete="$msg_yes" 587f589320aSDevin Teske fi 588f589320aSDevin Teske 589f589320aSDevin Teske # 590f589320aSDevin Teske # Loop until the user decides to Exit, Cancel, or presses ESC 591f589320aSDevin Teske # 592f589320aSDevin Teske title="$msg_delete $msg_user: $user_name" 593f589320aSDevin Teske if f_interactive; then 594f589320aSDevin Teske local mtag retval defaultitem= 595f589320aSDevin Teske while :; do 596f589320aSDevin Teske f_dialog_title "$title" 597f589320aSDevin Teske f_dialog_menu_user_delete "$user_name" "$defaultitem" 598f589320aSDevin Teske retval=$? 599f589320aSDevin Teske f_dialog_title_restore 600f589320aSDevin Teske f_dialog_menutag_fetch mtag 601f589320aSDevin Teske f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" 602f589320aSDevin Teske defaultitem="$mtag" 603f589320aSDevin Teske 604f589320aSDevin Teske # Return if user either pressed ESC or chose Cancel/No 605f589320aSDevin Teske [ $retval -eq $DIALOG_OK ] || return $FAILURE 606f589320aSDevin Teske 607f589320aSDevin Teske case "$mtag" in 608f589320aSDevin Teske X) # Delete/Exit 609f589320aSDevin Teske f_shell_escape "$user_uid" _user_uid 610f589320aSDevin Teske 611f589320aSDevin Teske # Save group information in case pw(8) deletes it 612f589320aSDevin Teske # and we wanted to keep it (to be restored below) 613f589320aSDevin Teske if [ "${user_group_delete:-$msg_no}" = "$msg_no" ] 614f589320aSDevin Teske then 615f589320aSDevin Teske local v vars="gid members name password" 616f589320aSDevin Teske for v in $vars; do local group_$var; done 617f589320aSDevin Teske f_input_group "$user_group" 618f589320aSDevin Teske 619f589320aSDevin Teske # Remove user-to-delete from group members 620f589320aSDevin Teske # NB: Otherwise group restoration could fail 621f589320aSDevin Teske local name length=0 _members= 622f589320aSDevin Teske while [ $length -ne ${#group_members} ]; do 623f589320aSDevin Teske name="${group_members%%,*}" 624f589320aSDevin Teske [ "$name" != "$user_name" ] && 625f589320aSDevin Teske _members="$_members,$name" 626f589320aSDevin Teske length=${#group_members} 627f589320aSDevin Teske group_members="${group_members#*,}" 628f589320aSDevin Teske done 629f589320aSDevin Teske group_members="${_members#,}" 630f589320aSDevin Teske 631f589320aSDevin Teske # Create escaped variables for f_eval_catch() 632f589320aSDevin Teske for v in $vars; do 633f589320aSDevin Teske local _group_$v 634f589320aSDevin Teske eval f_shell_escape \ 635f589320aSDevin Teske \"\$group_$v\" _group_$v 636f589320aSDevin Teske done 637f589320aSDevin Teske fi 638f589320aSDevin Teske 639f589320aSDevin Teske # Delete the user (if asked to delete home directory 640f589320aSDevin Teske # display [X]dialog notification to show activity) 641f589320aSDevin Teske local cmd="pw userdel -u '$_user_uid'" 642f589320aSDevin Teske if [ "$user_home_delete" = "$msg_yes" -a \ 643f589320aSDevin Teske "$USE_XDIALOG" ] 644f589320aSDevin Teske then 645f589320aSDevin Teske local err 646f589320aSDevin Teske err=$( 647f589320aSDevin Teske exec 9>&1 648f589320aSDevin Teske f_eval_catch -e $funcname pw \ 649f589320aSDevin Teske "%s -r" "$cmd" \ 650f589320aSDevin Teske >&$DIALOG_TERMINAL_PASSTHRU_FD 2>&9 | 651f589320aSDevin Teske f_xdialog_info \ 652f589320aSDevin Teske "$msg_deleting_home_directory" 653f589320aSDevin Teske ) 654f589320aSDevin Teske [ ! "$err" ] 655f589320aSDevin Teske elif [ "$user_home_delete" = "$msg_yes" ]; then 656f589320aSDevin Teske f_dialog_info "$msg_deleting_home_directory" 657f589320aSDevin Teske f_eval_catch $funcname pw '%s -r' "$cmd" 658f589320aSDevin Teske else 659f589320aSDevin Teske f_eval_catch $funcname pw '%s' "$cmd" 660f589320aSDevin Teske fi || continue 661f589320aSDevin Teske 662f589320aSDevin Teske # 663f589320aSDevin Teske # pw(8) may conditionally delete the primary group, 664f589320aSDevin Teske # which may not be what is desired. 665f589320aSDevin Teske # 666f589320aSDevin Teske # If we've been asked to delete the group and pw(8) 667f589320aSDevin Teske # chose not to, delete it. Otherwise, if we're told 668f589320aSDevin Teske # to NOT delete the group, we may need to restore it 669f589320aSDevin Teske # since pw(8) doesn't have a flag to tell `userdel' 670f589320aSDevin Teske # to not delete the group. 671f589320aSDevin Teske # 672f589320aSDevin Teske # NB: If primary group and user have different names 673f589320aSDevin Teske # the group may not have been deleted (again, see PR 674f589320aSDevin Teske # 169471 and SVN r263114 for details). 675f589320aSDevin Teske # 676f589320aSDevin Teske if [ "${user_group_delete:-$msg_no}" != "$msg_no" ] 677f589320aSDevin Teske then 678f589320aSDevin Teske f_quietly pw groupshow -g "$user_gid" && 679f589320aSDevin Teske f_eval_catch $funcname pw \ 680f589320aSDevin Teske "pw groupdel -g '%s'" "$_user_gid" 681f589320aSDevin Teske elif ! f_quietly pw groupshow -g "$group_gid" && 682f589320aSDevin Teske [ "$group_name" -a "$group_gid" ] 683f589320aSDevin Teske then 684f589320aSDevin Teske # Group deleted by pw(8), so restore it 685f589320aSDevin Teske local cmd="pw groupadd -n '$_group_name'" 686f589320aSDevin Teske cmd="$cmd -g '$_group_gid'" 687f589320aSDevin Teske cmd="$cmd -M '$_group_members'" 688f589320aSDevin Teske 689f589320aSDevin Teske # Get the group password (pw(8) groupshow does 690f589320aSDevin Teske # NOT provide this (even if running privileged) 691f589320aSDevin Teske local group_password_enc 692f589320aSDevin Teske group_password_enc=$( getent group | awk -F: ' 693f589320aSDevin Teske !/^[[:space:]]*(#|$)/ && \ 694f589320aSDevin Teske $1 == ENVIRON["group_name"] && \ 695f589320aSDevin Teske $3 == ENVIRON["group_gid"] && \ 696f589320aSDevin Teske $4 == ENVIRON["group_members"] \ 697f589320aSDevin Teske { print $2; exit } 698f589320aSDevin Teske ' ) 699f589320aSDevin Teske if [ "$group_password_enc" ]; then 700f589320aSDevin Teske echo "$group_password_enc" | 701f589320aSDevin Teske f_eval_catch $funcname \ 702f589320aSDevin Teske pw '%s -H 0' "$cmd" 703f589320aSDevin Teske else 704f589320aSDevin Teske f_eval_catch $funcname \ 705f589320aSDevin Teske pw '%s -h -' "$cmd" 706f589320aSDevin Teske fi 707f589320aSDevin Teske fi 708f589320aSDevin Teske 709f589320aSDevin Teske break # to success 710f589320aSDevin Teske ;; 711f589320aSDevin Teske 1) # Login (select different login from list) 712f589320aSDevin Teske f_dialog_menu_user_list "$user_name" || continue 713f589320aSDevin Teske f_dialog_menutag_fetch mtag 714f589320aSDevin Teske 715f589320aSDevin Teske [ "$mtag" = "X $msg_exit" ] && continue 716f589320aSDevin Teske 717f589320aSDevin Teske if ! f_input_user "$mtag"; then 718f589320aSDevin Teske f_show_err "$msg_login_not_found" "$mtag" 719f589320aSDevin Teske # Attempt to fall back to previous selection 720f589320aSDevin Teske f_input_user "$input" || return $FAILURE 721f589320aSDevin Teske else 722f589320aSDevin Teske input="$mtag" 723f589320aSDevin Teske fi 724f589320aSDevin Teske title="$msg_delete $msg_user: $user_name" 725f589320aSDevin Teske ;; 726f589320aSDevin Teske C) # Delete Primary Group? 727f589320aSDevin Teske if [ "${user_group_delete:-$msg_no}" != "$msg_no" ] 728f589320aSDevin Teske then 729f589320aSDevin Teske user_group_delete="$msg_no" 730f589320aSDevin Teske else 731f589320aSDevin Teske user_group_delete="$msg_yes" 732f589320aSDevin Teske fi ;; 733f589320aSDevin Teske D) # Delete Home Directory? 734f589320aSDevin Teske if [ "${user_home_delete:-$msg_no}" != "$msg_no" ] 735f589320aSDevin Teske then 736f589320aSDevin Teske user_home_delete="$msg_no" 737f589320aSDevin Teske else 738f589320aSDevin Teske user_home_delete="$msg_yes" 739f589320aSDevin Teske fi ;; 740f589320aSDevin Teske esac 741f589320aSDevin Teske done 742f589320aSDevin Teske else 743f589320aSDevin Teske f_shell_escape "$user_uid" _user_uid 744f589320aSDevin Teske 745f589320aSDevin Teske # Save group information in case pw(8) deletes it 746f589320aSDevin Teske # and we wanted to keep it (to be restored below) 747f589320aSDevin Teske if [ "${user_group_delete:-$msg_no}" = "$msg_no" ]; then 748f589320aSDevin Teske local v vars="gid members name password" 749f589320aSDevin Teske for v in $vars; do local group_$v; done 750f589320aSDevin Teske f_input_group "$user_group" 751f589320aSDevin Teske 752f589320aSDevin Teske # Remove user we're about to delete from group members 753f589320aSDevin Teske # NB: Otherwise group restoration could fail 754f589320aSDevin Teske local name length=0 _members= 755f589320aSDevin Teske while [ $length -ne ${#group_members} ]; do 756f589320aSDevin Teske name="${group_members%%,*}" 757f589320aSDevin Teske [ "$name" != "$user_name" ] && 758f589320aSDevin Teske _members="$_members,$name" 759f589320aSDevin Teske length=${#group_members} 760f589320aSDevin Teske group_members="${group_members#*,}" 761f589320aSDevin Teske done 762f589320aSDevin Teske group_members="${_members#,}" 763f589320aSDevin Teske 764f589320aSDevin Teske # Create escaped variables for later f_eval_catch() 765f589320aSDevin Teske for v in $vars; do 766f589320aSDevin Teske local _group_$v 767f589320aSDevin Teske eval f_shell_escape \"\$group_$v\" _group_$v 768f589320aSDevin Teske done 769f589320aSDevin Teske fi 770f589320aSDevin Teske 771f589320aSDevin Teske # Delete the user (if asked to delete home directory 772f589320aSDevin Teske # display [X]dialog notification to show activity) 773f589320aSDevin Teske local err cmd="pw userdel -u '$_user_uid'" 774f589320aSDevin Teske if [ "$user_home_delete" = "$msg_yes" -a "$USE_XDIALOG" ]; then 775f589320aSDevin Teske err=$( 776f589320aSDevin Teske exec 9>&1 777f589320aSDevin Teske f_eval_catch -de $funcname pw \ 778f589320aSDevin Teske '%s -r' "$cmd" 2>&9 | f_xdialog_info \ 779f589320aSDevin Teske "$msg_deleting_home_directory" 780f589320aSDevin Teske ) 781f589320aSDevin Teske [ ! "$err" ] 782f589320aSDevin Teske elif [ "$user_home_delete" = "$msg_yes" ]; then 783f589320aSDevin Teske f_dialog_info "$msg_deleting_home_directory" 784f589320aSDevin Teske f_eval_catch -k err $funcname pw '%s -r' "$cmd" 785f589320aSDevin Teske else 786f589320aSDevin Teske f_eval_catch -k err $funcname pw '%s' "$cmd" 787f589320aSDevin Teske fi 788f589320aSDevin Teske local retval=$? 789f589320aSDevin Teske if [ $retval -ne $SUCCESS ]; then 790f589320aSDevin Teske f_show_err "%s" "$err" 791f589320aSDevin Teske return $retval 792f589320aSDevin Teske fi 793f589320aSDevin Teske 794f589320aSDevin Teske # 795f589320aSDevin Teske # pw(8) may conditionally delete the primary group, which may 796f589320aSDevin Teske # not be what is desired. 797f589320aSDevin Teske # 798f589320aSDevin Teske # If we've been asked to delete the group and pw(8) chose not 799f589320aSDevin Teske # to, delete it. Otherwise, if we're told to NOT delete the 800f589320aSDevin Teske # group, we may need to restore it since pw(8) doesn't have a 801f589320aSDevin Teske # flag to tell `userdel' to not delete the group. 802f589320aSDevin Teske # 803f589320aSDevin Teske # NB: If primary group and user have different names the group 804f589320aSDevin Teske # may not have been deleted (again, see PR 169471 and SVN 805f589320aSDevin Teske # r263114 for details). 806f589320aSDevin Teske # 807f589320aSDevin Teske if [ "${user_group_delete:-$msg_no}" != "$msg_no" ] 808f589320aSDevin Teske then 809f589320aSDevin Teske f_quietly pw groupshow -g "$user_gid" && 810f589320aSDevin Teske f_eval_catch $funcname pw \ 811f589320aSDevin Teske "pw groupdel -g '%s'" "$_user_gid" 812f589320aSDevin Teske elif ! f_quietly pw groupshow -g "$group_gid" && 813f589320aSDevin Teske [ "$group_name" -a "$group_gid" ] 814f589320aSDevin Teske then 815f589320aSDevin Teske # Group deleted by pw(8), so restore it 816f589320aSDevin Teske local cmd="pw groupadd -n '$_group_name'" 817f589320aSDevin Teske cmd="$cmd -g '$_group_gid'" 818f589320aSDevin Teske cmd="$cmd -M '$_group_members'" 819f589320aSDevin Teske local group_password_enc 820f589320aSDevin Teske group_password_enc=$( getent group | awk -F: ' 821f589320aSDevin Teske !/^[[:space:]]*(#|$)/ && \ 822f589320aSDevin Teske $1 == ENVIRON["group_name"] && \ 823f589320aSDevin Teske $3 == ENVIRON["group_gid"] && \ 824f589320aSDevin Teske $4 == ENVIRON["group_members"] \ 825f589320aSDevin Teske { print $2; exit } 826f589320aSDevin Teske ' ) 827f589320aSDevin Teske if [ "$group_password_enc" ]; then 828f589320aSDevin Teske echo "$group_password_enc" | 829f589320aSDevin Teske f_eval_catch $funcname \ 830f589320aSDevin Teske pw '%s -H 0' "$cmd" 831f589320aSDevin Teske else 832ad8d629aSDevin Teske f_eval_catch $funcname pw '%s -h -' "$cmd" 833f589320aSDevin Teske fi 834f589320aSDevin Teske fi 835f589320aSDevin Teske fi 836f589320aSDevin Teske 837f589320aSDevin Teske f_dialog_title "$title" 838f589320aSDevin Teske $alert "$msg_login_deleted" 839f589320aSDevin Teske f_dialog_title_restore 840f589320aSDevin Teske [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1 841f589320aSDevin Teske 842f589320aSDevin Teske return $SUCCESS 843f589320aSDevin Teske} 844f589320aSDevin Teske 845f589320aSDevin Teske# f_user_edit [$user] 846f589320aSDevin Teske# 847f589320aSDevin Teske# Modify a login account. If both $user (as a first argument) and $VAR_USER are 848f589320aSDevin Teske# unset or NULL and we are running interactively, prompt the end-user to select 849f589320aSDevin Teske# a login account from a list of those available. Variables that can be used to 850f589320aSDevin Teske# script user input: 851f589320aSDevin Teske# 852f589320aSDevin Teske# VAR_USER [Optional if running interactively] 853f589320aSDevin Teske# The login to modify. Ignored if given non-NULL first-argument. 854f589320aSDevin Teske# VAR_USER_ACCOUNT_EXPIRE [Optional] 855f589320aSDevin Teske# The account expiration time. Format is similar to 856f589320aSDevin Teske# VAR_USER_PASSWORD_EXPIRE variable below. If unset, account 857f589320aSDevin Teske# expiry is unchanged. If set but NULL, account expiration is 858f589320aSDevin Teske# disabled (same as setting a value of `0'). 859f589320aSDevin Teske# VAR_USER_DOTFILES_CREATE [Optional] 860f589320aSDevin Teske# If non-NULL, re-populate the user's home directory with the 861f589320aSDevin Teske# template files found in $udotdir (`/usr/share/skel' default). 862f589320aSDevin Teske# VAR_USER_GECOS [Optional] 863f589320aSDevin Teske# Often the full name of the account holder. If unset, the GECOS 864f589320aSDevin Teske# field is unmodified. If set but NULL, the field is blanked. 865f589320aSDevin Teske# VAR_USER_GID [Optional] 866f589320aSDevin Teske# Numerical primary-group ID to set. If NULL or unset, the group 867f589320aSDevin Teske# ID is unchanged. 868f589320aSDevin Teske# VAR_USER_GROUPS [Optional] 869f589320aSDevin Teske# Comma-separated list of additional groups to which the user is 870f589320aSDevin Teske# a member of. If set but NULL, group memberships are reset (this 871f589320aSDevin Teske# login will not be a member of any additional groups besides the 872f589320aSDevin Teske# primary group). If unset, group membership is unmodified. 873f589320aSDevin Teske# VAR_USER_HOME [Optional] 874f589320aSDevin Teske# The home directory to set. If NULL or unset, the home directory 875f589320aSDevin Teske# is unchanged. 876f589320aSDevin Teske# VAR_USER_HOME_CREATE [Optional] 877f589320aSDevin Teske# If non-NULL, create the user's home directory if it doesn't 878f589320aSDevin Teske# already exist. 879f589320aSDevin Teske# VAR_USER_LOGIN_CLASS [Optional] 880f589320aSDevin Teske# Login class to set. If unset, the login class is unchanged. If 881f589320aSDevin Teske# set but NULL, the field is blanked. 882f589320aSDevin Teske# VAR_USER_PASSWORD [Optional] 883f589320aSDevin Teske# Unencrypted password to set. If unset, the login password is 884f589320aSDevin Teske# unmodified. If set but NULL, password authentication for the 885f589320aSDevin Teske# login is disabled. 886f589320aSDevin Teske# VAR_USER_PASSWORD_EXPIRE [Optional] 887f589320aSDevin Teske# The password expiration time. Format of the date is either a 888f589320aSDevin Teske# UNIX time in decimal, or a date in dd-mmm-yy[yy] format, where 889f589320aSDevin Teske# dd is the day, mmm is the month in either numeric or alphabetic 890f589320aSDevin Teske# format, and yy[yy] is either a two or four digit year. This 891f589320aSDevin Teske# variable also accepts a relative date in the form of +n[mhdwoy] 892f589320aSDevin Teske# where n is a decimal, octal (leading 0) or hexadecimal (leading 893f589320aSDevin Teske# 0x) digit followed by the number of Minutes, Hours, Days, 894f589320aSDevin Teske# Weeks, Months or Years from the current date at which the 895f589320aSDevin Teske# expiration time is to be set. If unset, password expiry is 896f589320aSDevin Teske# unchanged. If set but NULL, password expiration is disabled 897f589320aSDevin Teske# (same as setting a value of `0'). 898f589320aSDevin Teske# VAR_USER_SHELL [Optional] 899f589320aSDevin Teske# Path to login shell to set. If NULL or unset, the shell is 900f589320aSDevin Teske# unchanged. 901f589320aSDevin Teske# VAR_USER_UID [Optional] 902f589320aSDevin Teske# Numerical user ID to set. If NULL or unset, the user ID is 903f589320aSDevin Teske# unchanged. 904f589320aSDevin Teske# 905f589320aSDevin Teske# Returns success if the user account was successfully modified. 906f589320aSDevin Teske# 907f589320aSDevin Teskef_user_edit() 908f589320aSDevin Teske{ 909f589320aSDevin Teske local funcname=f_user_edit 910f589320aSDevin Teske local title # Calculated below 911f589320aSDevin Teske local alert=f_show_msg no_confirm= 912f589320aSDevin Teske 913f589320aSDevin Teske f_getvar $VAR_NO_CONFIRM no_confirm 914f589320aSDevin Teske [ "$no_confirm" ] && alert=f_show_info 915f589320aSDevin Teske 916f589320aSDevin Teske local input 917f589320aSDevin Teske f_getvar 3:-\$$VAR_USER input "$1" 918f589320aSDevin Teske 919f589320aSDevin Teske # 920f589320aSDevin Teske # NB: pw(8) has a ``feature'' wherein `-n name' can be taken as UID 921f589320aSDevin Teske # instead of name. Work-around is to also pass `-u UID' at the same 922*e8e8c939SDevin Teske # time (the UID is ignored in this case, so any UID will do). 923f589320aSDevin Teske # 924*e8e8c939SDevin Teske if [ "$input" ] && ! f_quietly pw usershow -n "$input" -u 1337; then 925f589320aSDevin Teske f_show_err "$msg_login_not_found" "$input" 926f589320aSDevin Teske return $FAILURE 927f589320aSDevin Teske fi 928f589320aSDevin Teske 929f589320aSDevin Teske if f_interactive && [ ! "$input" ]; then 930f589320aSDevin Teske f_dialog_menu_user_list || return $SUCCESS 931f589320aSDevin Teske f_dialog_menutag_fetch input 932f589320aSDevin Teske [ "$input" = "X $msg_exit" ] && return $SUCCESS 933f589320aSDevin Teske elif [ ! "$input" ]; then 934f589320aSDevin Teske f_show_err "$msg_no_user_specified" 935f589320aSDevin Teske return $FAILURE 936f589320aSDevin Teske fi 937f589320aSDevin Teske 938f589320aSDevin Teske local user_account_expire user_class user_gecos user_gid user_home_dir 939f589320aSDevin Teske local user_member_groups user_name user_password user_password_expire 940f589320aSDevin Teske local user_shell user_uid # Variables created by f_input_user() below 941f589320aSDevin Teske if ! f_input_user "$input"; then 942f589320aSDevin Teske f_show_err "$msg_login_not_found" "$input" 943f589320aSDevin Teske return $FAILURE 944f589320aSDevin Teske fi 945f589320aSDevin Teske 946f589320aSDevin Teske # 947f589320aSDevin Teske # Override values probed by f_input_user() with desired values 948f589320aSDevin Teske # 949f589320aSDevin Teske f_isset $VAR_USER_GID && f_getvar $VAR_USER_GID user_gid 950f589320aSDevin Teske f_isset $VAR_USER_HOME && f_getvar $VAR_USER_HOME user_home_dir 951f589320aSDevin Teske f_isset $VAR_USER_SHELL && f_getvar $VAR_USER_SHELL user_shell 952f589320aSDevin Teske f_isset $VAR_USER_UID && f_getvar $VAR_USER_UID user_uid 953f589320aSDevin Teske local user_dotfiles_create= user_home_create= 954f589320aSDevin Teske f_getvar $VAR_USER_DOTFILES_CREATE:+\$msg_yes user_dotfiles_create 955f589320aSDevin Teske f_getvar $VAR_USER_HOME_CREATE:+\$msg_yes user_home_create 956f589320aSDevin Teske local no_account_expire= 957f589320aSDevin Teske if f_isset $VAR_USER_ACCOUNT_EXPIRE; then 958f589320aSDevin Teske f_getvar $VAR_USER_ACCOUNT_EXPIRE user_account_expire 959f589320aSDevin Teske [ "$user_account_expire" ] || no_account_expire=1 960f589320aSDevin Teske fi 961f589320aSDevin Teske local null_gecos= 962f589320aSDevin Teske if f_isset $VAR_USER_GECOS; then 963f589320aSDevin Teske f_getvar $VAR_USER_GECOS user_gecos 964f589320aSDevin Teske [ "$user_gecos" ] || null_gecos=1 965f589320aSDevin Teske fi 966f589320aSDevin Teske local null_members= 967f589320aSDevin Teske if f_isset $VAR_USER_GROUPS; then 968f589320aSDevin Teske f_getvar $VAR_USER_GROUPS user_member_groups 969f589320aSDevin Teske [ "$user_member_groups" ] || null_members=1 970f589320aSDevin Teske fi 971f589320aSDevin Teske local null_class= 972f589320aSDevin Teske if f_isset $VAR_USER_LOGIN_CLASS; then 973f589320aSDevin Teske f_getvar $VAR_USER_LOGIN_CLASS user_class 974f589320aSDevin Teske [ "$user_class" ] || null_class=1 975f589320aSDevin Teske fi 976f589320aSDevin Teske local user_password_disable= 977f589320aSDevin Teske if f_isset $VAR_USER_PASSWORD; then 978f589320aSDevin Teske f_getvar $VAR_USER_PASSWORD user_password 979f589320aSDevin Teske [ "$user_password" ] || user_password_disable=1 980f589320aSDevin Teske fi 981f589320aSDevin Teske local no_password_expire= 982f589320aSDevin Teske if f_isset $VAR_USER_PASSWORD_EXPIRE; then 983f589320aSDevin Teske f_getvar $VAR_USER_PASSWORD_EXPIRE user_password_expire 984f589320aSDevin Teske [ "$user_password_expire" ] || no_password_expire=1 985f589320aSDevin Teske fi 986f589320aSDevin Teske 987f589320aSDevin Teske # 988f589320aSDevin Teske # Loop until the user decides to Exit, Cancel, or presses ESC 989f589320aSDevin Teske # 990f589320aSDevin Teske title="$msg_edit_view $msg_user: $user_name" 991f589320aSDevin Teske if f_interactive; then 992f589320aSDevin Teske local mtag retval defaultitem= 993f589320aSDevin Teske while :; do 994f589320aSDevin Teske f_dialog_title "$title" 995f589320aSDevin Teske f_dialog_menu_user_edit "$defaultitem" 996f589320aSDevin Teske retval=$? 997f589320aSDevin Teske f_dialog_title_restore 998f589320aSDevin Teske f_dialog_menutag_fetch mtag 999f589320aSDevin Teske f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" 1000f589320aSDevin Teske defaultitem="$mtag" 1001f589320aSDevin Teske 1002f589320aSDevin Teske # Return if user either pressed ESC or chose Cancel/No 1003f589320aSDevin Teske [ $retval -eq $DIALOG_OK ] || return $FAILURE 1004f589320aSDevin Teske 1005f589320aSDevin Teske case "$mtag" in 1006f589320aSDevin Teske X) # Save/Exit 1007f589320aSDevin Teske local var 1008f589320aSDevin Teske for var in account_expire class gecos gid home_dir \ 1009f589320aSDevin Teske member_groups name password_expire shell uid \ 1010f589320aSDevin Teske ; do 1011f589320aSDevin Teske local _user_$var 1012f589320aSDevin Teske eval f_shell_escape \"\$user_$var\" _user_$var 1013f589320aSDevin Teske done 1014f589320aSDevin Teske 1015f589320aSDevin Teske local cmd="pw usermod -n '$_user_name'" 1016f589320aSDevin Teske [ "$user_gid" ] && cmd="$cmd -g '$_user_gid'" 1017f589320aSDevin Teske [ "$user_shell" ] && cmd="$cmd -s '$_user_shell'" 1018f589320aSDevin Teske [ "$user_uid" ] && cmd="$cmd -u '$_user_uid'" 1019f589320aSDevin Teske [ "$user_account_expire" -o \ 1020f589320aSDevin Teske "$no_account_expire" ] && 1021f589320aSDevin Teske cmd="$cmd -e '$_user_account_expire'" 1022f589320aSDevin Teske [ "$user_class" -o "$null_class" ] && 1023f589320aSDevin Teske cmd="$cmd -L '$_user_class'" 1024f589320aSDevin Teske [ "$user_gecos" -o "$null_gecos" ] && 1025f589320aSDevin Teske cmd="$cmd -c '$_user_gecos'" 1026f589320aSDevin Teske [ "$user_home_dir" ] && 1027f589320aSDevin Teske cmd="$cmd -d '$_user_home_dir'" 1028f589320aSDevin Teske [ "$user_member_groups" -o "$null_members" ] && 1029f589320aSDevin Teske cmd="$cmd -G '$_user_member_groups'" 1030f589320aSDevin Teske [ "$user_password_expire" -o \ 1031f589320aSDevin Teske "$no_password_expire" ] && 1032f589320aSDevin Teske cmd="$cmd -p '$_user_password_expire'" 1033f589320aSDevin Teske 1034f589320aSDevin Teske # Execute the command 1035f589320aSDevin Teske if [ "$user_password_disable" ]; then 1036f589320aSDevin Teske f_eval_catch $funcname pw '%s -h -' "$cmd" 1037f589320aSDevin Teske elif [ "$user_password" ]; then 1038f589320aSDevin Teske echo "$user_password" | f_eval_catch \ 1039f589320aSDevin Teske $funcname pw '%s -h 0' "$cmd" 1040f589320aSDevin Teske else 1041f589320aSDevin Teske f_eval_catch $funcname pw '%s' "$cmd" 1042f589320aSDevin Teske fi || continue 1043f589320aSDevin Teske 1044f589320aSDevin Teske # Create home directory if desired 1045f589320aSDevin Teske [ "${user_home_create:-$msg_no}" != "$msg_no" ] && 1046f589320aSDevin Teske f_user_create_homedir "$user_name" 1047f589320aSDevin Teske 1048f589320aSDevin Teske # Copy dotfiles if desired 1049f589320aSDevin Teske [ "${user_dotfiles_create:-$msg_no}" != \ 1050f589320aSDevin Teske "$msg_no" ] && f_user_copy_dotfiles "$user_name" 1051f589320aSDevin Teske 1052f589320aSDevin Teske break # to success 1053f589320aSDevin Teske ;; 1054f589320aSDevin Teske 1) # Login (select different login from list) 1055f589320aSDevin Teske f_dialog_menu_user_list "$user_name" || continue 1056f589320aSDevin Teske f_dialog_menutag_fetch mtag 1057f589320aSDevin Teske 1058f589320aSDevin Teske [ "$mtag" = "X $msg_exit" ] && continue 1059f589320aSDevin Teske 1060f589320aSDevin Teske if ! f_input_user "$mtag"; then 1061f589320aSDevin Teske f_show_err "$msg_login_not_found" "$mtag" 1062f589320aSDevin Teske # Attempt to fall back to previous selection 1063f589320aSDevin Teske f_input_user "$input" || return $FAILURE 1064f589320aSDevin Teske else 1065f589320aSDevin Teske input="$mtag" 1066f589320aSDevin Teske fi 1067f589320aSDevin Teske title="$msg_edit_view $msg_user: $user_name" 1068f589320aSDevin Teske ;; 1069f589320aSDevin Teske 2) # Full Name 1070f589320aSDevin Teske f_dialog_input_gecos user_gecos "$user_gecos" && 1071f589320aSDevin Teske [ ! "$user_gecos" ] && null_gecos=1 ;; 1072f589320aSDevin Teske 3) # Password 1073f589320aSDevin Teske f_dialog_input_password \ 1074f589320aSDevin Teske user_password user_password_disable ;; 1075f589320aSDevin Teske 4) # User ID 1076f589320aSDevin Teske f_dialog_input_uid user_uid "$user_uid" ;; 1077f589320aSDevin Teske 5) # Group ID 1078f589320aSDevin Teske f_dialog_input_gid user_gid "$user_gid" ;; 1079f589320aSDevin Teske 6) # Member of Groups 1080f589320aSDevin Teske f_dialog_input_member_groups \ 1081f589320aSDevin Teske user_member_groups "$user_member_groups" && 1082f589320aSDevin Teske [ ! "$user_member_groups" ] && 1083f589320aSDevin Teske null_members=1 ;; 1084f589320aSDevin Teske 7) # Login Class 1085f589320aSDevin Teske f_dialog_input_class user_class "$user_class" && 1086f589320aSDevin Teske [ ! "$user_class" ] && null_class=1 ;; 1087f589320aSDevin Teske 8) # Password Expires On 1088f589320aSDevin Teske f_dialog_input_expire_password \ 1089f589320aSDevin Teske user_password_expire "$user_password_expire" && 1090f589320aSDevin Teske [ ! "$user_password_expire" ] && 1091f589320aSDevin Teske no_password_expire=1 ;; 1092f589320aSDevin Teske 9) # Account Expires On 1093f589320aSDevin Teske f_dialog_input_expire_account \ 1094f589320aSDevin Teske user_account_expire "$user_account_expire" && 1095f589320aSDevin Teske [ ! "$user_account_expire" ] && 1096f589320aSDevin Teske no_account_expire=1 ;; 1097f589320aSDevin Teske A) # Home Directory 1098f589320aSDevin Teske f_dialog_input_home_dir \ 1099f589320aSDevin Teske user_home_dir "$user_home_dir" ;; 1100f589320aSDevin Teske B) # Shell 1101f589320aSDevin Teske f_dialog_input_shell user_shell "$user_shell" ;; 1102f589320aSDevin Teske C) # Create Home Directory? 1103f589320aSDevin Teske if [ "${user_home_create:-$msg_no}" != "$msg_no" ] 1104f589320aSDevin Teske then 1105f589320aSDevin Teske user_home_create="$msg_no" 1106f589320aSDevin Teske else 1107f589320aSDevin Teske user_home_create="$msg_yes" 1108f589320aSDevin Teske fi ;; 1109f589320aSDevin Teske D) # Create Dotfiles? 1110f589320aSDevin Teske if [ "${user_dotfiles_create:-$msg_no}" != \ 1111f589320aSDevin Teske "$msg_no" ] 1112f589320aSDevin Teske then 1113f589320aSDevin Teske user_dotfiles_create="$msg_no" 1114f589320aSDevin Teske else 1115f589320aSDevin Teske user_dotfiles_create="$msg_yes" 1116f589320aSDevin Teske fi ;; 1117f589320aSDevin Teske esac 1118f589320aSDevin Teske done 1119f589320aSDevin Teske else 1120f589320aSDevin Teske local var 1121f589320aSDevin Teske for var in account_expire class gecos gid home_dir \ 1122f589320aSDevin Teske member_groups name password_expire shell uid \ 1123f589320aSDevin Teske ; do 1124f589320aSDevin Teske local _user_$var 1125f589320aSDevin Teske eval f_shell_escape \"\$user_$var\" _user_$var 1126f589320aSDevin Teske done 1127f589320aSDevin Teske 1128f589320aSDevin Teske # Form the command 1129f589320aSDevin Teske local cmd="pw usermod -n '$_user_name'" 1130f589320aSDevin Teske [ "$user_gid" ] && cmd="$cmd -g '$_user_gid'" 1131f589320aSDevin Teske [ "$user_home_dir" ] && cmd="$cmd -d '$_user_home_dir'" 1132f589320aSDevin Teske [ "$user_shell" ] && cmd="$cmd -s '$_user_shell'" 1133f589320aSDevin Teske [ "$user_uid" ] && cmd="$cmd -u '$_user_uid'" 1134f589320aSDevin Teske [ "$user_account_expire" -o "$no_account_expire" ] && 1135f589320aSDevin Teske cmd="$cmd -e '$_user_account_expire'" 1136f589320aSDevin Teske [ "$user_class" -o "$null_class" ] && 1137f589320aSDevin Teske cmd="$cmd -L '$_user_class'" 1138f589320aSDevin Teske [ "$user_gecos" -o "$null_gecos" ] && 1139f589320aSDevin Teske cmd="$cmd -c '$_user_gecos'" 1140f589320aSDevin Teske [ "$user_member_groups" -o "$null_members" ] && 1141f589320aSDevin Teske cmd="$cmd -G '$_user_member_groups'" 1142f589320aSDevin Teske [ "$user_password_expire" -o "$no_password_expire" ] && 1143f589320aSDevin Teske cmd="$cmd -p '$_user_password_expire'" 1144f589320aSDevin Teske 1145f589320aSDevin Teske # Execute the command 1146f589320aSDevin Teske local retval err 1147f589320aSDevin Teske if [ "$user_password_disable" ]; then 1148f589320aSDevin Teske f_eval_catch -k err $funcname pw '%s -h -' "$cmd" 1149f589320aSDevin Teske elif [ "$user_password" ]; then 1150f589320aSDevin Teske err=$( echo "$user_password" | f_eval_catch -de \ 1151f589320aSDevin Teske $funcname pw '%s -h 0' "$cmd" 2>&1 ) 1152f589320aSDevin Teske else 1153f589320aSDevin Teske f_eval_catch -k err $funcname pw '%s' "$cmd" 1154f589320aSDevin Teske fi 1155f589320aSDevin Teske retval=$? 1156f589320aSDevin Teske if [ $retval -ne $SUCCESS ]; then 1157f589320aSDevin Teske f_show_err "%s" "$err" 1158f589320aSDevin Teske return $retval 1159f589320aSDevin Teske fi 1160f589320aSDevin Teske 1161f589320aSDevin Teske # Create home directory if desired 1162f589320aSDevin Teske [ "${user_home_create:-$msg_no}" != "$msg_no" ] && 1163f589320aSDevin Teske f_user_create_homedir "$user_name" 1164f589320aSDevin Teske 1165f589320aSDevin Teske # Copy dotfiles if desired 1166f589320aSDevin Teske [ "${user_dotfiles_create:-$msg_no}" != "$msg_no" ] && 1167f589320aSDevin Teske f_user_copy_dotfiles "$user_name" 1168f589320aSDevin Teske fi 1169f589320aSDevin Teske 1170f589320aSDevin Teske f_dialog_title "$title" 1171f589320aSDevin Teske $alert "$msg_login_updated" 1172f589320aSDevin Teske f_dialog_title_restore 1173f589320aSDevin Teske [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1 1174f589320aSDevin Teske 1175f589320aSDevin Teske return $SUCCESS 1176f589320aSDevin Teske} 1177f589320aSDevin Teske 1178f589320aSDevin Teske############################################################ MAIN 1179f589320aSDevin Teske 1180f589320aSDevin Teskef_dprintf "%s: Successfully loaded." usermgmt/user.subr 1181f589320aSDevin Teske 1182f589320aSDevin Teskefi # ! $_USERMGMT_USER_SUBR 1183