mirror of
https://github.com/opnsense/src.git
synced 2026-04-04 08:55:18 -04:00
1183 lines
40 KiB
Text
1183 lines
40 KiB
Text
if [ ! "$_USERMGMT_USER_SUBR" ]; then _USERMGMT_USER_SUBR=1
|
|
#
|
|
# Copyright (c) 2012 Ron McDowell
|
|
# Copyright (c) 2012-2015 Devin Teske
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
# SUCH DAMAGE.
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
############################################################ INCLUDES
|
|
|
|
BSDCFG_SHARE="/usr/share/bsdconfig"
|
|
. $BSDCFG_SHARE/common.subr || exit 1
|
|
f_dprintf "%s: loading includes..." usermgmt/user.subr
|
|
f_include $BSDCFG_SHARE/dialog.subr
|
|
f_include $BSDCFG_SHARE/strings.subr
|
|
f_include $BSDCFG_SHARE/usermgmt/group_input.subr
|
|
f_include $BSDCFG_SHARE/usermgmt/user_input.subr
|
|
|
|
BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
|
|
f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
|
|
|
|
############################################################ CONFIGURATION
|
|
|
|
# set some reasonable defaults if /etc/adduser.conf does not exist.
|
|
[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf
|
|
: ${defaultclass:=""}
|
|
: ${defaultshell:="/bin/sh"}
|
|
: ${homeprefix:="/home"}
|
|
: ${passwdtype:="yes"}
|
|
: ${udotdir:="/usr/share/skel"}
|
|
: ${uexpire:=""}
|
|
# Default account expire time. Format is similar to upwexpire variable.
|
|
: ${ugecos:="User &"}
|
|
: ${upwexpire:=""}
|
|
# The default password expiration time. Format of the date is either a
|
|
# UNIX time in decimal, or a date in dd-mmm-yy[yy] format, where dd is
|
|
# the day, mmm is the month in either numeric or alphabetic format, and
|
|
# yy[yy] is either a two or four digit year. This variable also accepts
|
|
# a relative date in the form of n[mhdwoy] where n is a decimal, octal
|
|
# (leading 0) or hexadecimal (leading 0x) digit followed by the number
|
|
# of Minutes, Hours, Days, Weeks, Months or Years from the current date
|
|
# at which the expiration time is to be set.
|
|
|
|
#
|
|
# uexpire and upwexpire from adduser.conf(5) differ only slightly from what
|
|
# pw(8) accepts as `date' argument(s); pw(8) requires a leading `+' for the
|
|
# relative date syntax (n[mhdwoy]).
|
|
#
|
|
case "$uexpire" in *[mhdwoy])
|
|
f_isinteger "${uexpire%[mhdwoy]}" && uexpire="+$uexpire"
|
|
esac
|
|
case "$upwexpire" in *[mhdwoy])
|
|
f_isinteger "${upwexpire%[mhdwoy]}" && upwexpire="+$upwexpire"
|
|
esac
|
|
|
|
############################################################ FUNCTIONS
|
|
|
|
# f_user_create_homedir $user
|
|
#
|
|
# Create home directory for $user.
|
|
#
|
|
f_user_create_homedir()
|
|
{
|
|
local funcname=f_user_create_homedir
|
|
local user="$1"
|
|
|
|
[ "$user" ] || return $FAILURE
|
|
|
|
local user_account_expire user_class user_gecos user_gid user_home_dir
|
|
local user_member_groups user_name user_password user_password_expire
|
|
local user_shell user_uid # Variables created by f_input_user() below
|
|
f_input_user "$user" || return $FAILURE
|
|
|
|
f_dprintf "Creating home directory \`%s' for user \`%s'" \
|
|
"$user_home_dir" "$user"
|
|
|
|
local _user_gid _user_home_dir _user_uid
|
|
f_shell_escape "$user_gid" _user_gid
|
|
f_shell_escape "$user_home_dir" _user_home_dir
|
|
f_shell_escape "$user_uid" _user_uid
|
|
f_eval_catch $funcname mkdir "mkdir -p '%s'" "$_user_home_dir" ||
|
|
return $FAILURE
|
|
f_eval_catch $funcname chown "chown '%i:%i' '%s'" \
|
|
"$_user_uid" "$_user_gid" "$_user_home_dir" || return $FAILURE
|
|
}
|
|
|
|
# f_user_copy_dotfiles $user
|
|
#
|
|
# Copy `skel' dot-files from $udotdir (global inherited from /etc/adduser.conf)
|
|
# to the home-directory of $user. Attempts to create the home-directory first
|
|
# if it doesn't exist.
|
|
#
|
|
f_user_copy_dotfiles()
|
|
{
|
|
local funcname=f_user_copy_dotfiles
|
|
local user="$1"
|
|
|
|
[ "$udotdir" ] || return $FAILURE
|
|
[ "$user" ] || return $FAILURE
|
|
|
|
local user_account_expire user_class user_gecos user_gid user_home_dir
|
|
local user_member_groups user_name user_password user_password_expire
|
|
local user_shell user_uid # Variables created by f_input_user() below
|
|
f_input_user "$user" || return $FAILURE
|
|
|
|
f_dprintf "Copying dot-files from \`%s' to \`%s'" \
|
|
"$udotdir" "$user_home_dir"
|
|
|
|
# Attempt to create the home directory if it doesn't exist
|
|
[ -d "$user_home_dir" ] ||
|
|
f_user_create_homedir "$user" || return $FAILURE
|
|
|
|
local _user_gid _user_home_dir _user_uid
|
|
f_shell_escape "$user_gid" _user_gid
|
|
f_shell_escape "$user_home_dir" _user_home_dir
|
|
f_shell_escape "$user_uid" _user_uid
|
|
|
|
local - # Localize `set' to this function
|
|
set +f # Enable glob pattern-matching for paths
|
|
cd "$udotdir" || return $FAILURE
|
|
|
|
local _file file retval
|
|
for file in dot.*; do
|
|
[ -e "$file" ] || continue # no-match
|
|
|
|
f_shell_escape "$file" "_file"
|
|
f_eval_catch $funcname cp "cp -n '%s' '%s'" \
|
|
"$_file" "$_user_home_dir/${_file#dot}"
|
|
retval=$?
|
|
[ $retval -eq $SUCCESS ] || break
|
|
f_eval_catch $funcname chown \
|
|
"chown -h '%i:%i' '%s'" \
|
|
"$_user_uid" "$_user_gid" \
|
|
"$_user_home_dir/${_file#dot}"
|
|
retval=$?
|
|
[ $retval -eq $SUCCESS ] || break
|
|
done
|
|
|
|
cd -
|
|
return $retval
|
|
}
|
|
|
|
# f_user_add [$user]
|
|
#
|
|
# Create a login account. If both $user (as a first argument) and $VAR_USER are
|
|
# unset or NULL and we are running interactively, prompt the end-user to enter
|
|
# the name of a new login account and (if $VAR_NO_CONFIRM is unset or NULL)
|
|
# prompt the end-user to answer some questions about the new account. Variables
|
|
# that can be used to script user input:
|
|
#
|
|
# VAR_USER [Optional if running interactively]
|
|
# The login to add. Ignored if given non-NULL first-argument.
|
|
# VAR_USER_ACCOUNT_EXPIRE [Optional]
|
|
# The account expiration time. Format is similar to
|
|
# VAR_USER_PASSWORD_EXPIRE variable below. Default is to never
|
|
# expire the account.
|
|
# VAR_USER_DOTFILES_CREATE [Optional]
|
|
# If non-NULL, populate the user's home directory with the
|
|
# template files found in $udotdir (`/usr/share/skel' default).
|
|
# VAR_USER_GECOS [Optional]
|
|
# Often the full name of the account holder. Default is NULL.
|
|
# VAR_USER_GID [Optional]
|
|
# Numerical primary-group ID to use. If NULL or unset, the group
|
|
# ID is automatically chosen.
|
|
# VAR_USER_GROUPS [Optional]
|
|
# Comma-separated list of additional groups to which the user is
|
|
# a member of. Default is NULL (no additional groups).
|
|
# VAR_USER_HOME [Optional]
|
|
# The home directory to set. If NULL or unset, the home directory
|
|
# is automatically calculated.
|
|
# VAR_USER_HOME_CREATE [Optional]
|
|
# If non-NULL, create the user's home directory if it doesn't
|
|
# already exist.
|
|
# VAR_USER_LOGIN_CLASS [Optional]
|
|
# Login class to use when creating the login. Default is NULL.
|
|
# VAR_USER_PASSWORD [Optional]
|
|
# Unencrypted password to use. If unset or NULL, password
|
|
# authentication for the login is disabled.
|
|
# VAR_USER_PASSWORD_EXPIRE [Optional]
|
|
# The password expiration time. Format of the date is either a
|
|
# UNIX time in decimal, or a date in dd-mmm-yy[yy] format, where
|
|
# dd is the day, mmm is the month in either numeric or alphabetic
|
|
# format, and yy[yy] is either a two or four digit year. This
|
|
# variable also accepts a relative date in the form of +n[mhdwoy]
|
|
# where n is a decimal, octal (leading 0) or hexadecimal (leading
|
|
# 0x) digit followed by the number of Minutes, Hours, Days,
|
|
# Weeks, Months or Years from the current date at which the
|
|
# expiration time is to be set. Default is to never expire the
|
|
# account password.
|
|
# VAR_USER_SHELL [Optional]
|
|
# Path to login shell to use. Default is `/bin/sh'.
|
|
# VAR_USER_UID [Optional]
|
|
# Numerical user ID to use. If NULL or unset, the user ID is
|
|
# automatically chosen.
|
|
#
|
|
# Returns success if the user account was successfully created.
|
|
#
|
|
f_user_add()
|
|
{
|
|
local funcname=f_user_add
|
|
local title # Calculated below
|
|
local alert=f_show_msg no_confirm=
|
|
|
|
f_getvar $VAR_NO_CONFIRM no_confirm
|
|
[ "$no_confirm" ] && alert=f_show_info
|
|
|
|
local input
|
|
f_getvar 3:-\$$VAR_USER input "$1"
|
|
|
|
#
|
|
# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as UID
|
|
# instead of name. Work-around is to also pass `-u UID' at the same
|
|
# time (the UID is ignored in this case, so any UID will do).
|
|
#
|
|
if [ "$input" ] && f_quietly pw usershow -n "$input" -u 1337; then
|
|
f_show_err "$msg_login_already_used" "$input"
|
|
return $FAILURE
|
|
fi
|
|
|
|
local user_name="$input"
|
|
while f_interactive && [ ! "$user_name" ]; do
|
|
f_dialog_input_name user_name "$user_name" ||
|
|
return $SUCCESS
|
|
[ "$user_name" ] ||
|
|
f_show_err "$msg_please_enter_a_user_name"
|
|
done
|
|
if [ ! "$user_name" ]; then
|
|
f_show_err "$msg_no_user_specified"
|
|
return $FAILURE
|
|
fi
|
|
|
|
local user_account_expire user_class user_gecos user_gid user_home_dir
|
|
local user_member_groups user_password user_password_expire user_shell
|
|
local user_uid user_dotfiles_create= user_home_create=
|
|
f_getvar $VAR_USER_ACCOUNT_EXPIRE-\$uexpire user_account_expire
|
|
f_getvar $VAR_USER_DOTFILES_CREATE:+\$msg_yes user_dotfiles_create
|
|
f_getvar $VAR_USER_GECOS-\$ugecos user_gecos
|
|
f_getvar $VAR_USER_GID user_gid
|
|
f_getvar $VAR_USER_GROUPS user_member_groups
|
|
f_getvar $VAR_USER_HOME:-\${homeprefix%/}/\$user_name \
|
|
user_home_dir
|
|
f_getvar $VAR_USER_HOME_CREATE:+\$msg_yes user_home_create
|
|
f_getvar $VAR_USER_LOGIN_CLASS-\$defaultclass user_class
|
|
f_getvar $VAR_USER_PASSWORD user_password
|
|
f_getvar $VAR_USER_PASSWORD_EXPIRE-\$upwexpire user_password_expire
|
|
f_getvar $VAR_USER_SHELL-\$defaultshell user_shell
|
|
f_getvar $VAR_USER_UID user_uid
|
|
|
|
# Create home-dir if no script-override and does not exist
|
|
f_isset $VAR_USER_HOME_CREATE || [ -d "$user_home_dir" ] ||
|
|
user_home_create="$msg_yes"
|
|
# Copy dotfiles if home-dir creation is desired, does not yet exist,
|
|
# and no script-override has been set
|
|
f_isset $VAR_USER_DOTFILES_CREATE ||
|
|
[ "$user_home_create" != "$msg_yes" ] ||
|
|
[ -d "$user_home_dir" ] || user_dotfiles_create="$msg_yes"
|
|
# Create home-dir if copying dotfiles but home-dir does not exist
|
|
[ "$user_dotfiles_create" -a ! -d "$user_home_dir" ] &&
|
|
user_home_create="$msg_yes"
|
|
|
|
# Set flags for meaningful NULL values if-provided
|
|
local no_account_expire= no_password_expire= null_gecos= null_members=
|
|
local user_password_disable=
|
|
f_isset $VAR_USER_ACCOUNT_EXPIRE &&
|
|
[ ! "$user_account_expire" ] && no_account_expire=1
|
|
f_isset $VAR_USER_GECOS &&
|
|
[ ! "$user_gecos" ] && null_gecos=1
|
|
f_isset $VAR_USER_GROUPS &&
|
|
[ ! "$user_member_groups" ] && null_members=1
|
|
f_isset $VAR_USER_PASSWORD &&
|
|
[ ! "$user_password" ] && user_password_disable=1
|
|
f_isset $VAR_USER_PASSWORD_EXPIRE &&
|
|
[ ! "$user_password_expire" ] && no_password_expire=1
|
|
|
|
if f_interactive && [ ! "$no_confirm" ]; then
|
|
f_dialog_noyes \
|
|
"$msg_use_default_values_for_all_account_details"
|
|
retval=$?
|
|
if [ $retval -eq $DIALOG_ESC ]; then
|
|
return $SUCCESS
|
|
elif [ $retval -ne $DIALOG_OK ]; then
|
|
#
|
|
# Ask series of questions to pre-fill the editor screen
|
|
#
|
|
# Defaults used in each dialog should allow the user to
|
|
# simply hit ENTER to proceed, because cancelling any
|
|
# single dialog will cause them to be returned to the
|
|
# previous menu.
|
|
#
|
|
|
|
f_dialog_input_gecos user_gecos "$user_gecos" ||
|
|
return $FAILURE
|
|
if [ "$passwdtype" = "yes" ]; then
|
|
f_dialog_input_password user_password \
|
|
user_password_disable ||
|
|
return $FAILURE
|
|
fi
|
|
f_dialog_input_uid user_uid "$user_uid" ||
|
|
return $FAILURE
|
|
f_dialog_input_gid user_gid "$user_gid" ||
|
|
return $FAILURE
|
|
f_dialog_input_member_groups user_member_groups \
|
|
"$user_member_groups" || return $FAILURE
|
|
f_dialog_input_class user_class "$user_class" ||
|
|
return $FAILURE
|
|
f_dialog_input_expire_password user_password_expire \
|
|
"$user_password_expire" || return $FAILURE
|
|
f_dialog_input_expire_account user_account_expire \
|
|
"$user_account_expire" || return $FAILURE
|
|
f_dialog_input_home_dir user_home_dir \
|
|
"$user_home_dir" || return $FAILURE
|
|
if [ ! -d "$user_home_dir" ]; then
|
|
f_dialog_input_home_create user_home_create ||
|
|
return $FAILURE
|
|
if [ "$user_home_create" = "$msg_yes" ]; then
|
|
f_dialog_input_dotfiles_create \
|
|
user_dotfiles_create ||
|
|
return $FAILURE
|
|
fi
|
|
fi
|
|
f_dialog_input_shell user_shell "$user_shell" ||
|
|
return $FAILURE
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Loop until the user decides to Exit, Cancel, or presses ESC
|
|
#
|
|
title="$msg_add $msg_user: $user_name"
|
|
if f_interactive; then
|
|
local mtag retval defaultitem=
|
|
while :; do
|
|
f_dialog_title "$title"
|
|
f_dialog_menu_user_add "$defaultitem"
|
|
retval=$?
|
|
f_dialog_title_restore
|
|
f_dialog_menutag_fetch mtag
|
|
f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
|
|
defaultitem="$mtag"
|
|
|
|
# Return if user either pressed ESC or chose Cancel/No
|
|
[ $retval -eq $DIALOG_OK ] || return $FAILURE
|
|
|
|
case "$mtag" in
|
|
X) # Add/Exit
|
|
local var
|
|
for var in account_expire class gecos gid home_dir \
|
|
member_groups name password_expire shell uid \
|
|
; do
|
|
local _user_$var
|
|
eval f_shell_escape \"\$user_$var\" _user_$var
|
|
done
|
|
|
|
local cmd="pw useradd -n '$_user_name'"
|
|
[ "$user_gid" ] && cmd="$cmd -g '$_user_gid'"
|
|
[ "$user_shell" ] && cmd="$cmd -s '$_user_shell'"
|
|
[ "$user_uid" ] && cmd="$cmd -u '$_user_uid'"
|
|
[ "$user_account_expire" -o \
|
|
"$no_account_expire" ] &&
|
|
cmd="$cmd -e '$_user_account_expire'"
|
|
[ "$user_class" -o "$null_class" ] &&
|
|
cmd="$cmd -L '$_user_class'"
|
|
[ "$user_gecos" -o "$null_gecos" ] &&
|
|
cmd="$cmd -c '$_user_gecos'"
|
|
[ "$user_home_dir" ] &&
|
|
cmd="$cmd -d '$_user_home_dir'"
|
|
[ "$user_member_groups" ] &&
|
|
cmd="$cmd -G '$_user_member_groups'"
|
|
[ "$user_password_expire" -o \
|
|
"$no_password_expire" ] &&
|
|
cmd="$cmd -p '$_user_password_expire'"
|
|
|
|
# Execute the command
|
|
if [ "$user_password_disable" ]; then
|
|
f_eval_catch $funcname pw '%s -h -' "$cmd"
|
|
elif [ "$user_password" ]; then
|
|
echo "$user_password" | f_eval_catch \
|
|
$funcname pw '%s -h 0' "$cmd"
|
|
else
|
|
f_eval_catch $funcname pw '%s' "$cmd"
|
|
fi || continue
|
|
|
|
# Create home directory if desired
|
|
[ "${user_home_create:-$msg_no}" != "$msg_no" ] &&
|
|
f_user_create_homedir "$user_name"
|
|
|
|
# Copy dotfiles if desired
|
|
[ "${user_dotfiles_create:-$msg_no}" != \
|
|
"$msg_no" ] && f_user_copy_dotfiles "$user_name"
|
|
|
|
break # to success
|
|
;;
|
|
1) # Login (prompt for new login name)
|
|
f_dialog_input_name input "$user_name" ||
|
|
continue
|
|
if f_quietly pw usershow -n "$input" -u 1337; then
|
|
f_show_err "$msg_login_already_used" "$input"
|
|
continue
|
|
fi
|
|
user_name="$input"
|
|
title="$msg_add $msg_user: $user_name"
|
|
user_home_dir="${homeprefix%/}/$user_name"
|
|
;;
|
|
2) # Full Name
|
|
f_dialog_input_gecos user_gecos "$user_gecos" &&
|
|
[ ! "$user_gecos" ] && null_gecos=1 ;;
|
|
3) # Password
|
|
f_dialog_input_password \
|
|
user_password user_password_disable ;;
|
|
4) # User ID
|
|
f_dialog_input_uid user_uid "$user_uid" ;;
|
|
5) # Group ID
|
|
f_dialog_input_gid user_gid "$user_gid" ;;
|
|
6) # Member of Groups
|
|
f_dialog_input_member_groups \
|
|
user_member_groups "$user_member_groups" &&
|
|
[ ! "$user_member_groups" ] &&
|
|
null_members=1 ;;
|
|
7) # Login Class
|
|
f_dialog_input_class user_class "$user_class" &&
|
|
[ ! "$user_class" ] && null_class=1 ;;
|
|
8) # Password Expires On
|
|
f_dialog_input_expire_password \
|
|
user_password_expire "$user_password_expire" &&
|
|
[ ! "$user_password_expire" ] &&
|
|
no_password_expire=1 ;;
|
|
9) # Account Expires On
|
|
f_dialog_input_expire_account \
|
|
user_account_expire "$user_account_expire" &&
|
|
[ ! "$user_account_expire" ] &&
|
|
no_account_expire=1 ;;
|
|
A) # Home Directory
|
|
f_dialog_input_home_dir \
|
|
user_home_dir "$user_home_dir" ;;
|
|
B) # Shell
|
|
f_dialog_input_shell user_shell "$user_shell" ;;
|
|
C) # Create Home Directory?
|
|
if [ "${user_home_create:-$msg_no}" != "$msg_no" ]
|
|
then
|
|
user_home_create="$msg_no"
|
|
else
|
|
user_home_create="$msg_yes"
|
|
fi ;;
|
|
D) # Create Dotfiles?
|
|
if [ "${user_dotfiles_create:-$msg_no}" != \
|
|
"$msg_no" ]
|
|
then
|
|
user_dotfiles_create="$msg_no"
|
|
else
|
|
user_dotfiles_create="$msg_yes"
|
|
fi ;;
|
|
esac
|
|
done
|
|
else
|
|
local var
|
|
for var in account_expire class gecos gid home_dir \
|
|
member_groups name password_expire shell uid \
|
|
; do
|
|
local _user_$var
|
|
eval f_shell_escape \"\$user_$var\" _user_$var
|
|
done
|
|
|
|
# Form the command
|
|
local cmd="pw useradd -n '$_user_name'"
|
|
[ "$user_gid" ] && cmd="$cmd -g '$_user_gid'"
|
|
[ "$user_home_dir" ] && cmd="$cmd -d '$_user_home_dir'"
|
|
[ "$user_shell" ] && cmd="$cmd -s '$_user_shell'"
|
|
[ "$user_uid" ] && cmd="$cmd -u '$_user_uid'"
|
|
[ "$user_account_expire" -o "$no_account_expire" ] &&
|
|
cmd="$cmd -e '$_user_account_expire'"
|
|
[ "$user_class" -o "$null_class" ] &&
|
|
cmd="$cmd -L '$_user_class'"
|
|
[ "$user_gecos" -o "$null_gecos" ] &&
|
|
cmd="$cmd -c '$_user_gecos'"
|
|
[ "$user_member_groups" -o "$null_members" ] &&
|
|
cmd="$cmd -G '$_user_member_groups'"
|
|
[ "$user_password_expire" -o "$no_password_expire" ] &&
|
|
cmd="$cmd -p '$_user_password_expire'"
|
|
|
|
# Execute the command
|
|
local retval err
|
|
if [ "$user_password_disable" ]; then
|
|
f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
|
|
elif [ "$user_password" ]; then
|
|
err=$( echo "$user_password" | f_eval_catch -de \
|
|
$funcname pw '%s -h 0' "$cmd" 2>&1 )
|
|
else
|
|
f_eval_catch -k err $funcname pw '%s' "$cmd"
|
|
fi
|
|
retval=$?
|
|
if [ $retval -ne $SUCCESS ]; then
|
|
f_show_err "%s" "$err"
|
|
return $retval
|
|
fi
|
|
|
|
# Create home directory if desired
|
|
[ "${user_home_create:-$msg_no}" != "$msg_no" ] &&
|
|
f_user_create_homedir "$user_name"
|
|
|
|
# Copy dotfiles if desired
|
|
[ "${user_dotfiles_create:-$msg_no}" != "$msg_no" ] &&
|
|
f_user_copy_dotfiles "$user_name"
|
|
fi
|
|
|
|
f_dialog_title "$title"
|
|
$alert "$msg_login_added"
|
|
f_dialog_title_restore
|
|
[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
|
|
|
|
return $SUCCESS
|
|
}
|
|
|
|
# f_user_delete [$user]
|
|
#
|
|
# Delete a user. If both $user (as a first argument) and $VAR_USER are unset or
|
|
# NULL and we are running interactively, prompt the end-user to select a user
|
|
# account from a list of those available. Variables that can be used to script
|
|
# user input:
|
|
#
|
|
# VAR_USER [Optional if running interactively]
|
|
# The user to delete. Ignored if given non-NULL first-argument.
|
|
#
|
|
# Returns success if the user account was successfully deleted.
|
|
#
|
|
f_user_delete()
|
|
{
|
|
local funcname=f_user_delete
|
|
local title # Calculated below
|
|
local alert=f_show_msg no_confirm=
|
|
|
|
f_getvar $VAR_NO_CONFIRM no_confirm
|
|
[ "$no_confirm" ] && alert=f_show_info
|
|
|
|
local input
|
|
f_getvar 3:-\$$VAR_USER input "$1"
|
|
|
|
if f_interactive && [ ! "$input" ]; then
|
|
f_dialog_menu_user_list || return $SUCCESS
|
|
f_dialog_menutag_fetch input
|
|
[ "$input" = "X $msg_exit" ] && return $SUCCESS
|
|
elif [ ! "$input" ]; then
|
|
f_show_err "$msg_no_user_specified"
|
|
return $FAILURE
|
|
fi
|
|
|
|
local user_account_expire user_class user_gecos user_gid user_home_dir
|
|
local user_member_groups user_name user_password user_password_expire
|
|
local user_shell user_uid # Variables created by f_input_user() below
|
|
if [ "$input" ] && ! f_input_user "$input"; then
|
|
f_show_err "$msg_login_not_found" "$input"
|
|
return $FAILURE
|
|
fi
|
|
|
|
local user_group_delete= user_home_delete=
|
|
f_getvar $VAR_USER_GROUP_DELETE:-\$msg_no user_group_delete
|
|
f_getvar $VAR_USER_HOME_DELETE:-\$msg_no user_home_delete
|
|
|
|
# Attempt to translate user GID into a group name
|
|
local user_group
|
|
if user_group=$( pw groupshow -g "$user_gid" 2> /dev/null ); then
|
|
user_group="${user_group%%:*}"
|
|
# Default to delete the primary group if no script-override and
|
|
# exists with same name as the user (same logic used by pw(8))
|
|
f_isset $VAR_USER_GROUP_DELETE ||
|
|
[ "$user_group" != "$user_name" ] ||
|
|
user_group_delete="$msg_yes"
|
|
fi
|
|
|
|
#
|
|
# Loop until the user decides to Exit, Cancel, or presses ESC
|
|
#
|
|
title="$msg_delete $msg_user: $user_name"
|
|
if f_interactive; then
|
|
local mtag retval defaultitem=
|
|
while :; do
|
|
f_dialog_title "$title"
|
|
f_dialog_menu_user_delete "$user_name" "$defaultitem"
|
|
retval=$?
|
|
f_dialog_title_restore
|
|
f_dialog_menutag_fetch mtag
|
|
f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
|
|
defaultitem="$mtag"
|
|
|
|
# Return if user either pressed ESC or chose Cancel/No
|
|
[ $retval -eq $DIALOG_OK ] || return $FAILURE
|
|
|
|
case "$mtag" in
|
|
X) # Delete/Exit
|
|
f_shell_escape "$user_uid" _user_uid
|
|
|
|
# Save group information in case pw(8) deletes it
|
|
# and we wanted to keep it (to be restored below)
|
|
if [ "${user_group_delete:-$msg_no}" = "$msg_no" ]
|
|
then
|
|
local v vars="gid members name password"
|
|
for v in $vars; do local group_$var; done
|
|
f_input_group "$user_group"
|
|
|
|
# Remove user-to-delete from group members
|
|
# NB: Otherwise group restoration could fail
|
|
local name length=0 _members=
|
|
while [ $length -ne ${#group_members} ]; do
|
|
name="${group_members%%,*}"
|
|
[ "$name" != "$user_name" ] &&
|
|
_members="$_members,$name"
|
|
length=${#group_members}
|
|
group_members="${group_members#*,}"
|
|
done
|
|
group_members="${_members#,}"
|
|
|
|
# Create escaped variables for f_eval_catch()
|
|
for v in $vars; do
|
|
local _group_$v
|
|
eval f_shell_escape \
|
|
\"\$group_$v\" _group_$v
|
|
done
|
|
fi
|
|
|
|
# Delete the user (if asked to delete home directory
|
|
# display [X]dialog notification to show activity)
|
|
local cmd="pw userdel -u '$_user_uid'"
|
|
if [ "$user_home_delete" = "$msg_yes" -a \
|
|
"$USE_XDIALOG" ]
|
|
then
|
|
local err
|
|
err=$(
|
|
exec 9>&1
|
|
f_eval_catch -e $funcname pw \
|
|
"%s -r" "$cmd" \
|
|
>&$DIALOG_TERMINAL_PASSTHRU_FD 2>&9 |
|
|
f_xdialog_info \
|
|
"$msg_deleting_home_directory"
|
|
)
|
|
[ ! "$err" ]
|
|
elif [ "$user_home_delete" = "$msg_yes" ]; then
|
|
f_dialog_info "$msg_deleting_home_directory"
|
|
f_eval_catch $funcname pw '%s -r' "$cmd"
|
|
else
|
|
f_eval_catch $funcname pw '%s' "$cmd"
|
|
fi || continue
|
|
|
|
#
|
|
# pw(8) may conditionally delete the primary group,
|
|
# which may not be what is desired.
|
|
#
|
|
# If we've been asked to delete the group and pw(8)
|
|
# chose not to, delete it. Otherwise, if we're told
|
|
# to NOT delete the group, we may need to restore it
|
|
# since pw(8) doesn't have a flag to tell `userdel'
|
|
# to not delete the group.
|
|
#
|
|
# NB: If primary group and user have different names
|
|
# the group may not have been deleted (again, see PR
|
|
# 169471 and SVN r263114 for details).
|
|
#
|
|
if [ "${user_group_delete:-$msg_no}" != "$msg_no" ]
|
|
then
|
|
f_quietly pw groupshow -g "$user_gid" &&
|
|
f_eval_catch $funcname pw \
|
|
"pw groupdel -g '%s'" "$_user_gid"
|
|
elif ! f_quietly pw groupshow -g "$group_gid" &&
|
|
[ "$group_name" -a "$group_gid" ]
|
|
then
|
|
# Group deleted by pw(8), so restore it
|
|
local cmd="pw groupadd -n '$_group_name'"
|
|
cmd="$cmd -g '$_group_gid'"
|
|
cmd="$cmd -M '$_group_members'"
|
|
|
|
# Get the group password (pw(8) groupshow does
|
|
# NOT provide this (even if running privileged)
|
|
local group_password_enc
|
|
group_password_enc=$( getent group | awk -F: '
|
|
!/^[[:space:]]*(#|$)/ && \
|
|
$1 == ENVIRON["group_name"] && \
|
|
$3 == ENVIRON["group_gid"] && \
|
|
$4 == ENVIRON["group_members"] \
|
|
{ print $2; exit }
|
|
' )
|
|
if [ "$group_password_enc" ]; then
|
|
echo "$group_password_enc" |
|
|
f_eval_catch $funcname \
|
|
pw '%s -H 0' "$cmd"
|
|
else
|
|
f_eval_catch $funcname \
|
|
pw '%s -h -' "$cmd"
|
|
fi
|
|
fi
|
|
|
|
break # to success
|
|
;;
|
|
1) # Login (select different login from list)
|
|
f_dialog_menu_user_list "$user_name" || continue
|
|
f_dialog_menutag_fetch mtag
|
|
|
|
[ "$mtag" = "X $msg_exit" ] && continue
|
|
|
|
if ! f_input_user "$mtag"; then
|
|
f_show_err "$msg_login_not_found" "$mtag"
|
|
# Attempt to fall back to previous selection
|
|
f_input_user "$input" || return $FAILURE
|
|
else
|
|
input="$mtag"
|
|
fi
|
|
title="$msg_delete $msg_user: $user_name"
|
|
;;
|
|
C) # Delete Primary Group?
|
|
if [ "${user_group_delete:-$msg_no}" != "$msg_no" ]
|
|
then
|
|
user_group_delete="$msg_no"
|
|
else
|
|
user_group_delete="$msg_yes"
|
|
fi ;;
|
|
D) # Delete Home Directory?
|
|
if [ "${user_home_delete:-$msg_no}" != "$msg_no" ]
|
|
then
|
|
user_home_delete="$msg_no"
|
|
else
|
|
user_home_delete="$msg_yes"
|
|
fi ;;
|
|
esac
|
|
done
|
|
else
|
|
f_shell_escape "$user_uid" _user_uid
|
|
|
|
# Save group information in case pw(8) deletes it
|
|
# and we wanted to keep it (to be restored below)
|
|
if [ "${user_group_delete:-$msg_no}" = "$msg_no" ]; then
|
|
local v vars="gid members name password"
|
|
for v in $vars; do local group_$v; done
|
|
f_input_group "$user_group"
|
|
|
|
# Remove user we're about to delete from group members
|
|
# NB: Otherwise group restoration could fail
|
|
local name length=0 _members=
|
|
while [ $length -ne ${#group_members} ]; do
|
|
name="${group_members%%,*}"
|
|
[ "$name" != "$user_name" ] &&
|
|
_members="$_members,$name"
|
|
length=${#group_members}
|
|
group_members="${group_members#*,}"
|
|
done
|
|
group_members="${_members#,}"
|
|
|
|
# Create escaped variables for later f_eval_catch()
|
|
for v in $vars; do
|
|
local _group_$v
|
|
eval f_shell_escape \"\$group_$v\" _group_$v
|
|
done
|
|
fi
|
|
|
|
# Delete the user (if asked to delete home directory
|
|
# display [X]dialog notification to show activity)
|
|
local err cmd="pw userdel -u '$_user_uid'"
|
|
if [ "$user_home_delete" = "$msg_yes" -a "$USE_XDIALOG" ]; then
|
|
err=$(
|
|
exec 9>&1
|
|
f_eval_catch -de $funcname pw \
|
|
'%s -r' "$cmd" 2>&9 | f_xdialog_info \
|
|
"$msg_deleting_home_directory"
|
|
)
|
|
[ ! "$err" ]
|
|
elif [ "$user_home_delete" = "$msg_yes" ]; then
|
|
f_dialog_info "$msg_deleting_home_directory"
|
|
f_eval_catch -k err $funcname pw '%s -r' "$cmd"
|
|
else
|
|
f_eval_catch -k err $funcname pw '%s' "$cmd"
|
|
fi
|
|
local retval=$?
|
|
if [ $retval -ne $SUCCESS ]; then
|
|
f_show_err "%s" "$err"
|
|
return $retval
|
|
fi
|
|
|
|
#
|
|
# pw(8) may conditionally delete the primary group, which may
|
|
# not be what is desired.
|
|
#
|
|
# If we've been asked to delete the group and pw(8) chose not
|
|
# to, delete it. Otherwise, if we're told to NOT delete the
|
|
# group, we may need to restore it since pw(8) doesn't have a
|
|
# flag to tell `userdel' to not delete the group.
|
|
#
|
|
# NB: If primary group and user have different names the group
|
|
# may not have been deleted (again, see PR 169471 and SVN
|
|
# r263114 for details).
|
|
#
|
|
if [ "${user_group_delete:-$msg_no}" != "$msg_no" ]
|
|
then
|
|
f_quietly pw groupshow -g "$user_gid" &&
|
|
f_eval_catch $funcname pw \
|
|
"pw groupdel -g '%s'" "$_user_gid"
|
|
elif ! f_quietly pw groupshow -g "$group_gid" &&
|
|
[ "$group_name" -a "$group_gid" ]
|
|
then
|
|
# Group deleted by pw(8), so restore it
|
|
local cmd="pw groupadd -n '$_group_name'"
|
|
cmd="$cmd -g '$_group_gid'"
|
|
cmd="$cmd -M '$_group_members'"
|
|
local group_password_enc
|
|
group_password_enc=$( getent group | awk -F: '
|
|
!/^[[:space:]]*(#|$)/ && \
|
|
$1 == ENVIRON["group_name"] && \
|
|
$3 == ENVIRON["group_gid"] && \
|
|
$4 == ENVIRON["group_members"] \
|
|
{ print $2; exit }
|
|
' )
|
|
if [ "$group_password_enc" ]; then
|
|
echo "$group_password_enc" |
|
|
f_eval_catch $funcname \
|
|
pw '%s -H 0' "$cmd"
|
|
else
|
|
f_eval_catch $funcname pw '%s -h -' "$cmd"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
f_dialog_title "$title"
|
|
$alert "$msg_login_deleted"
|
|
f_dialog_title_restore
|
|
[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
|
|
|
|
return $SUCCESS
|
|
}
|
|
|
|
# f_user_edit [$user]
|
|
#
|
|
# Modify a login account. If both $user (as a first argument) and $VAR_USER are
|
|
# unset or NULL and we are running interactively, prompt the end-user to select
|
|
# a login account from a list of those available. Variables that can be used to
|
|
# script user input:
|
|
#
|
|
# VAR_USER [Optional if running interactively]
|
|
# The login to modify. Ignored if given non-NULL first-argument.
|
|
# VAR_USER_ACCOUNT_EXPIRE [Optional]
|
|
# The account expiration time. Format is similar to
|
|
# VAR_USER_PASSWORD_EXPIRE variable below. If unset, account
|
|
# expiry is unchanged. If set but NULL, account expiration is
|
|
# disabled (same as setting a value of `0').
|
|
# VAR_USER_DOTFILES_CREATE [Optional]
|
|
# If non-NULL, re-populate the user's home directory with the
|
|
# template files found in $udotdir (`/usr/share/skel' default).
|
|
# VAR_USER_GECOS [Optional]
|
|
# Often the full name of the account holder. If unset, the GECOS
|
|
# field is unmodified. If set but NULL, the field is blanked.
|
|
# VAR_USER_GID [Optional]
|
|
# Numerical primary-group ID to set. If NULL or unset, the group
|
|
# ID is unchanged.
|
|
# VAR_USER_GROUPS [Optional]
|
|
# Comma-separated list of additional groups to which the user is
|
|
# a member of. If set but NULL, group memberships are reset (this
|
|
# login will not be a member of any additional groups besides the
|
|
# primary group). If unset, group membership is unmodified.
|
|
# VAR_USER_HOME [Optional]
|
|
# The home directory to set. If NULL or unset, the home directory
|
|
# is unchanged.
|
|
# VAR_USER_HOME_CREATE [Optional]
|
|
# If non-NULL, create the user's home directory if it doesn't
|
|
# already exist.
|
|
# VAR_USER_LOGIN_CLASS [Optional]
|
|
# Login class to set. If unset, the login class is unchanged. If
|
|
# set but NULL, the field is blanked.
|
|
# VAR_USER_PASSWORD [Optional]
|
|
# Unencrypted password to set. If unset, the login password is
|
|
# unmodified. If set but NULL, password authentication for the
|
|
# login is disabled.
|
|
# VAR_USER_PASSWORD_EXPIRE [Optional]
|
|
# The password expiration time. Format of the date is either a
|
|
# UNIX time in decimal, or a date in dd-mmm-yy[yy] format, where
|
|
# dd is the day, mmm is the month in either numeric or alphabetic
|
|
# format, and yy[yy] is either a two or four digit year. This
|
|
# variable also accepts a relative date in the form of +n[mhdwoy]
|
|
# where n is a decimal, octal (leading 0) or hexadecimal (leading
|
|
# 0x) digit followed by the number of Minutes, Hours, Days,
|
|
# Weeks, Months or Years from the current date at which the
|
|
# expiration time is to be set. If unset, password expiry is
|
|
# unchanged. If set but NULL, password expiration is disabled
|
|
# (same as setting a value of `0').
|
|
# VAR_USER_SHELL [Optional]
|
|
# Path to login shell to set. If NULL or unset, the shell is
|
|
# unchanged.
|
|
# VAR_USER_UID [Optional]
|
|
# Numerical user ID to set. If NULL or unset, the user ID is
|
|
# unchanged.
|
|
#
|
|
# Returns success if the user account was successfully modified.
|
|
#
|
|
f_user_edit()
|
|
{
|
|
local funcname=f_user_edit
|
|
local title # Calculated below
|
|
local alert=f_show_msg no_confirm=
|
|
|
|
f_getvar $VAR_NO_CONFIRM no_confirm
|
|
[ "$no_confirm" ] && alert=f_show_info
|
|
|
|
local input
|
|
f_getvar 3:-\$$VAR_USER input "$1"
|
|
|
|
#
|
|
# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as UID
|
|
# instead of name. Work-around is to also pass `-u UID' at the same
|
|
# time (the UID is ignored in this case, so any UID will do).
|
|
#
|
|
if [ "$input" ] && ! f_quietly pw usershow -n "$input" -u 1337; then
|
|
f_show_err "$msg_login_not_found" "$input"
|
|
return $FAILURE
|
|
fi
|
|
|
|
if f_interactive && [ ! "$input" ]; then
|
|
f_dialog_menu_user_list || return $SUCCESS
|
|
f_dialog_menutag_fetch input
|
|
[ "$input" = "X $msg_exit" ] && return $SUCCESS
|
|
elif [ ! "$input" ]; then
|
|
f_show_err "$msg_no_user_specified"
|
|
return $FAILURE
|
|
fi
|
|
|
|
local user_account_expire user_class user_gecos user_gid user_home_dir
|
|
local user_member_groups user_name user_password user_password_expire
|
|
local user_shell user_uid # Variables created by f_input_user() below
|
|
if ! f_input_user "$input"; then
|
|
f_show_err "$msg_login_not_found" "$input"
|
|
return $FAILURE
|
|
fi
|
|
|
|
#
|
|
# Override values probed by f_input_user() with desired values
|
|
#
|
|
f_isset $VAR_USER_GID && f_getvar $VAR_USER_GID user_gid
|
|
f_isset $VAR_USER_HOME && f_getvar $VAR_USER_HOME user_home_dir
|
|
f_isset $VAR_USER_SHELL && f_getvar $VAR_USER_SHELL user_shell
|
|
f_isset $VAR_USER_UID && f_getvar $VAR_USER_UID user_uid
|
|
local user_dotfiles_create= user_home_create=
|
|
f_getvar $VAR_USER_DOTFILES_CREATE:+\$msg_yes user_dotfiles_create
|
|
f_getvar $VAR_USER_HOME_CREATE:+\$msg_yes user_home_create
|
|
local no_account_expire=
|
|
if f_isset $VAR_USER_ACCOUNT_EXPIRE; then
|
|
f_getvar $VAR_USER_ACCOUNT_EXPIRE user_account_expire
|
|
[ "$user_account_expire" ] || no_account_expire=1
|
|
fi
|
|
local null_gecos=
|
|
if f_isset $VAR_USER_GECOS; then
|
|
f_getvar $VAR_USER_GECOS user_gecos
|
|
[ "$user_gecos" ] || null_gecos=1
|
|
fi
|
|
local null_members=
|
|
if f_isset $VAR_USER_GROUPS; then
|
|
f_getvar $VAR_USER_GROUPS user_member_groups
|
|
[ "$user_member_groups" ] || null_members=1
|
|
fi
|
|
local null_class=
|
|
if f_isset $VAR_USER_LOGIN_CLASS; then
|
|
f_getvar $VAR_USER_LOGIN_CLASS user_class
|
|
[ "$user_class" ] || null_class=1
|
|
fi
|
|
local user_password_disable=
|
|
if f_isset $VAR_USER_PASSWORD; then
|
|
f_getvar $VAR_USER_PASSWORD user_password
|
|
[ "$user_password" ] || user_password_disable=1
|
|
fi
|
|
local no_password_expire=
|
|
if f_isset $VAR_USER_PASSWORD_EXPIRE; then
|
|
f_getvar $VAR_USER_PASSWORD_EXPIRE user_password_expire
|
|
[ "$user_password_expire" ] || no_password_expire=1
|
|
fi
|
|
|
|
#
|
|
# Loop until the user decides to Exit, Cancel, or presses ESC
|
|
#
|
|
title="$msg_edit_view $msg_user: $user_name"
|
|
if f_interactive; then
|
|
local mtag retval defaultitem=
|
|
while :; do
|
|
f_dialog_title "$title"
|
|
f_dialog_menu_user_edit "$defaultitem"
|
|
retval=$?
|
|
f_dialog_title_restore
|
|
f_dialog_menutag_fetch mtag
|
|
f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
|
|
defaultitem="$mtag"
|
|
|
|
# Return if user either pressed ESC or chose Cancel/No
|
|
[ $retval -eq $DIALOG_OK ] || return $FAILURE
|
|
|
|
case "$mtag" in
|
|
X) # Save/Exit
|
|
local var
|
|
for var in account_expire class gecos gid home_dir \
|
|
member_groups name password_expire shell uid \
|
|
; do
|
|
local _user_$var
|
|
eval f_shell_escape \"\$user_$var\" _user_$var
|
|
done
|
|
|
|
local cmd="pw usermod -n '$_user_name'"
|
|
[ "$user_gid" ] && cmd="$cmd -g '$_user_gid'"
|
|
[ "$user_shell" ] && cmd="$cmd -s '$_user_shell'"
|
|
[ "$user_uid" ] && cmd="$cmd -u '$_user_uid'"
|
|
[ "$user_account_expire" -o \
|
|
"$no_account_expire" ] &&
|
|
cmd="$cmd -e '$_user_account_expire'"
|
|
[ "$user_class" -o "$null_class" ] &&
|
|
cmd="$cmd -L '$_user_class'"
|
|
[ "$user_gecos" -o "$null_gecos" ] &&
|
|
cmd="$cmd -c '$_user_gecos'"
|
|
[ "$user_home_dir" ] &&
|
|
cmd="$cmd -d '$_user_home_dir'"
|
|
[ "$user_member_groups" -o "$null_members" ] &&
|
|
cmd="$cmd -G '$_user_member_groups'"
|
|
[ "$user_password_expire" -o \
|
|
"$no_password_expire" ] &&
|
|
cmd="$cmd -p '$_user_password_expire'"
|
|
|
|
# Execute the command
|
|
if [ "$user_password_disable" ]; then
|
|
f_eval_catch $funcname pw '%s -h -' "$cmd"
|
|
elif [ "$user_password" ]; then
|
|
echo "$user_password" | f_eval_catch \
|
|
$funcname pw '%s -h 0' "$cmd"
|
|
else
|
|
f_eval_catch $funcname pw '%s' "$cmd"
|
|
fi || continue
|
|
|
|
# Create home directory if desired
|
|
[ "${user_home_create:-$msg_no}" != "$msg_no" ] &&
|
|
f_user_create_homedir "$user_name"
|
|
|
|
# Copy dotfiles if desired
|
|
[ "${user_dotfiles_create:-$msg_no}" != \
|
|
"$msg_no" ] && f_user_copy_dotfiles "$user_name"
|
|
|
|
break # to success
|
|
;;
|
|
1) # Login (select different login from list)
|
|
f_dialog_menu_user_list "$user_name" || continue
|
|
f_dialog_menutag_fetch mtag
|
|
|
|
[ "$mtag" = "X $msg_exit" ] && continue
|
|
|
|
if ! f_input_user "$mtag"; then
|
|
f_show_err "$msg_login_not_found" "$mtag"
|
|
# Attempt to fall back to previous selection
|
|
f_input_user "$input" || return $FAILURE
|
|
else
|
|
input="$mtag"
|
|
fi
|
|
title="$msg_edit_view $msg_user: $user_name"
|
|
;;
|
|
2) # Full Name
|
|
f_dialog_input_gecos user_gecos "$user_gecos" &&
|
|
[ ! "$user_gecos" ] && null_gecos=1 ;;
|
|
3) # Password
|
|
f_dialog_input_password \
|
|
user_password user_password_disable ;;
|
|
4) # User ID
|
|
f_dialog_input_uid user_uid "$user_uid" ;;
|
|
5) # Group ID
|
|
f_dialog_input_gid user_gid "$user_gid" ;;
|
|
6) # Member of Groups
|
|
f_dialog_input_member_groups \
|
|
user_member_groups "$user_member_groups" &&
|
|
[ ! "$user_member_groups" ] &&
|
|
null_members=1 ;;
|
|
7) # Login Class
|
|
f_dialog_input_class user_class "$user_class" &&
|
|
[ ! "$user_class" ] && null_class=1 ;;
|
|
8) # Password Expires On
|
|
f_dialog_input_expire_password \
|
|
user_password_expire "$user_password_expire" &&
|
|
[ ! "$user_password_expire" ] &&
|
|
no_password_expire=1 ;;
|
|
9) # Account Expires On
|
|
f_dialog_input_expire_account \
|
|
user_account_expire "$user_account_expire" &&
|
|
[ ! "$user_account_expire" ] &&
|
|
no_account_expire=1 ;;
|
|
A) # Home Directory
|
|
f_dialog_input_home_dir \
|
|
user_home_dir "$user_home_dir" ;;
|
|
B) # Shell
|
|
f_dialog_input_shell user_shell "$user_shell" ;;
|
|
C) # Create Home Directory?
|
|
if [ "${user_home_create:-$msg_no}" != "$msg_no" ]
|
|
then
|
|
user_home_create="$msg_no"
|
|
else
|
|
user_home_create="$msg_yes"
|
|
fi ;;
|
|
D) # Create Dotfiles?
|
|
if [ "${user_dotfiles_create:-$msg_no}" != \
|
|
"$msg_no" ]
|
|
then
|
|
user_dotfiles_create="$msg_no"
|
|
else
|
|
user_dotfiles_create="$msg_yes"
|
|
fi ;;
|
|
esac
|
|
done
|
|
else
|
|
local var
|
|
for var in account_expire class gecos gid home_dir \
|
|
member_groups name password_expire shell uid \
|
|
; do
|
|
local _user_$var
|
|
eval f_shell_escape \"\$user_$var\" _user_$var
|
|
done
|
|
|
|
# Form the command
|
|
local cmd="pw usermod -n '$_user_name'"
|
|
[ "$user_gid" ] && cmd="$cmd -g '$_user_gid'"
|
|
[ "$user_home_dir" ] && cmd="$cmd -d '$_user_home_dir'"
|
|
[ "$user_shell" ] && cmd="$cmd -s '$_user_shell'"
|
|
[ "$user_uid" ] && cmd="$cmd -u '$_user_uid'"
|
|
[ "$user_account_expire" -o "$no_account_expire" ] &&
|
|
cmd="$cmd -e '$_user_account_expire'"
|
|
[ "$user_class" -o "$null_class" ] &&
|
|
cmd="$cmd -L '$_user_class'"
|
|
[ "$user_gecos" -o "$null_gecos" ] &&
|
|
cmd="$cmd -c '$_user_gecos'"
|
|
[ "$user_member_groups" -o "$null_members" ] &&
|
|
cmd="$cmd -G '$_user_member_groups'"
|
|
[ "$user_password_expire" -o "$no_password_expire" ] &&
|
|
cmd="$cmd -p '$_user_password_expire'"
|
|
|
|
# Execute the command
|
|
local retval err
|
|
if [ "$user_password_disable" ]; then
|
|
f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
|
|
elif [ "$user_password" ]; then
|
|
err=$( echo "$user_password" | f_eval_catch -de \
|
|
$funcname pw '%s -h 0' "$cmd" 2>&1 )
|
|
else
|
|
f_eval_catch -k err $funcname pw '%s' "$cmd"
|
|
fi
|
|
retval=$?
|
|
if [ $retval -ne $SUCCESS ]; then
|
|
f_show_err "%s" "$err"
|
|
return $retval
|
|
fi
|
|
|
|
# Create home directory if desired
|
|
[ "${user_home_create:-$msg_no}" != "$msg_no" ] &&
|
|
f_user_create_homedir "$user_name"
|
|
|
|
# Copy dotfiles if desired
|
|
[ "${user_dotfiles_create:-$msg_no}" != "$msg_no" ] &&
|
|
f_user_copy_dotfiles "$user_name"
|
|
fi
|
|
|
|
f_dialog_title "$title"
|
|
$alert "$msg_login_updated"
|
|
f_dialog_title_restore
|
|
[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
|
|
|
|
return $SUCCESS
|
|
}
|
|
|
|
############################################################ MAIN
|
|
|
|
f_dprintf "%s: Successfully loaded." usermgmt/user.subr
|
|
|
|
fi # ! $_USERMGMT_USER_SUBR
|