diff options
Diffstat (limited to 'usr.sbin/bsdconfig/usermgmt/share/group_input.subr')
| -rw-r--r-- | usr.sbin/bsdconfig/usermgmt/share/group_input.subr | 595 | 
1 files changed, 595 insertions, 0 deletions
| diff --git a/usr.sbin/bsdconfig/usermgmt/share/group_input.subr b/usr.sbin/bsdconfig/usermgmt/share/group_input.subr new file mode 100644 index 000000000000..0af624249f7a --- /dev/null +++ b/usr.sbin/bsdconfig/usermgmt/share/group_input.subr @@ -0,0 +1,595 @@ +if [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1 +# +# Copyright (c) 2012 Ron McDowell +# Copyright (c) 2012-2014 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. +# +# +############################################################ INCLUDES + +BSDCFG_SHARE="/usr/share/bsdconfig" +. $BSDCFG_SHARE/common.subr || exit 1 +f_dprintf "%s: loading includes..." usermgmt/group_input.subr +f_include $BSDCFG_SHARE/dialog.subr +f_include $BSDCFG_SHARE/strings.subr + +BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" +f_include_lang $BSDCFG_LIBE/include/messages.subr +f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr + +############################################################ FUNCTIONS + +# f_input_group $group +# +# Given $group name or id, create the environment variables group_name, +# group_gid, and group_members (and group_password is reset to NULL). +# +f_input_group() +{ +	local funcname=f_input_group +	local group="$1" + +	f_dprintf "$funcname: Getting info for group \`%s'" "$group" +	eval "$( pw groupshow "$group" 2> /dev/null | awk -F: ' +	function set_value(var, value) { +		gsub(/'\''/, "'\''\\'\'\''", value) +		printf "group_%s='\'%s\''\n", var, value +	} +	{ +		found = $1 != "" +		set_value("name",     $1) +		set_value("password", "") +		set_value("gid",      $3) +		set_value("members",  $4) +		exit +	} +	END { if (!found) print "false" }' )" +} + +# f_dialog_menu_group_list [$default] +# +# Allows the user to select a group from a list. Optionally, if present and +# non-NULL, initially highlight $default group. +# +f_dialog_menu_group_list() +{ +	local prompt= +	local menu_list=" +		'X $msg_exit' '' +	" # END-QUOTE +	local defaultitem="$1" +	local hline="$hline_alnum_punc_tab_enter" + +	# Add groups from group(5) +	menu_list="$menu_list $( pw groupshow -a | awk -F: ' +		function mprint(tag, item) { +			gsub(/'\''/, "'\''\\'\'\''", tag) +			gsub(/'\''/, "'\''\\'\'\''", item) +			printf "'\'%s\'\ \'%s\''\n", tag, item +		} +		!/^[[:space:]]*(#|$)/ { mprint($1, $1) } +	' )" + +	local height width rows +	eval f_dialog_menu_size height width rows \ +	                        \"\$DIALOG_TITLE\"     \ +	                        \"\$DIALOG_BACKTITLE\" \ +	                        \"\$prompt\"           \ +	                        \"\$hline\"            \ +	                        $menu_list + +	local menu_choice +	menu_choice=$( eval $DIALOG \ +		--title \"\$DIALOG_TITLE\"         \ +		--backtitle \"\$DIALOG_BACKTITLE\" \ +		--hline \"\$hline\"                \ +		--ok-label \"\$msg_ok\"            \ +		--cancel-label \"\$msg_cancel\"    \ +		--default-item \"\$defaultitem\"   \ +		--menu \"\$prompt\"                \ +		$height $width $rows               \ +		$menu_list                         \ +		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +	) +	local retval=$? +	f_dialog_menutag_store -s "$menu_choice" +	return $retval +} + +# f_dialog_input_group_name $var_to_set [$group_name] +# +# Allows the user to enter a name for a new group. If the user does not cancel +# or press ESC, the $var_to_set variable will hold the newly-configured value +# upon return. +# +f_dialog_input_group_name() +{ +	local __var_to_set="$1" __name="$2" + +	# +	# Loop until the user provides taint-free/valid input +	# +	local __input="$__name" +	while :; do +		# Return if user has either pressed ESC or chosen Cancel/No +		f_dialog_input __input "$msg_group" "$__input" \ +		               "$hline_alnum_tab_enter" || return $? + +		# Check for no-change +		if [ "$__input" = "$__name" ]; then +			setvar "$__var_to_set" "$__input" +			return $DIALOG_OK +		fi + +		# Check for NULL entry +		if [ ! "$__input" ]; then +			f_show_msg "$msg_group_is_empty" +			continue +		fi + +		# Check for invalid entry +		case "$__input" in [!a-zA-Z]*) +			f_show_msg "$msg_group_must_start_with_letter" +			continue +		esac + +		# Check for duplicate entry +		if f_quietly pw groupshow -n "$__input"; then +			f_show_msg "$msg_group_already_used" "$__input" +			continue +		fi + +		setvar "$__var_to_set" "$__input" +		break +	done + +	return $DIALOG_OK +} + +# f_dialog_input_group_password $var_to_set $dvar_to_set +# +# Prompt the user to enter a password (twice). If the user does not cancel or +# press ESC, $var_to_set will hold the confirmed user entry. Otherwise, if the +# user cancels or enters a NULL password (twice), they are given the choice to +# disable password authentication for the given group, wherein $dvar_to_set has +# a value of 1 to indicate password authentication should be disabled. +# +f_dialog_input_group_password() +{ +	local __var_to_set="$1" __dvar_to_set="$2" +	local __prompt1="$msg_group_password" +	local __prompt2="$msg_reenter_group_password" +	local __hline="$hline_alnum_punc_tab_enter" + +	local __height1 __width1 +	f_dialog_inputbox_size __height1 __width1 \ +	        	"$DIALOG_TITLE"     \ +	        	"$DIALOG_BACKTITLE" \ +	        	"$__prompt1"        \ +	        	""                  \ +	        	"$__hline" + +	local __height2 __width2 +	f_dialog_inputbox_size __height2 __width2 \ +	        	"$DIALOG_TITLE"     \ +	        	"$DIALOG_BACKTITLE" \ +	        	"$__prompt2"        \ +	        	""                  \ +	        	"$__hline" + +	# +	# Loop until the user provides taint-free/valid input +	# +	local __retval __password1 __password2 +	while :; do +		__password1=$( $DIALOG \ +			--title "$DIALOG_TITLE"         \ +			--backtitle "$DIALOG_BACKTITLE" \ +			--hline "$__hline"              \ +			--ok-label "$msg_ok"            \ +			--cancel-label "$msg_cancel"    \ +			--insecure                      \ +			--passwordbox "$__prompt1"      \ +			$__height1 $__width1            \ +			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +		) +		__retval=$? +		debug= f_dialog_line_sanitize __password1 + +		# Return if user has either pressed ESC or chosen Cancel/No +		[ $__retval -eq $DIALOG_OK ] || return $__retval + +		__password2=$( $DIALOG \ +			--title "$DIALOG_TITLE"         \ +			--backtitle "$DIALOG_BACKTITLE" \ +			--hline "$__hline"              \ +			--ok-label "$msg_ok"            \ +			--cancel-label "$msg_cancel"    \ +			--insecure                      \ +			--passwordbox "$__prompt2"      \ +			$__height2 $__width2            \ +			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +		) +		__retval=$? +		debug= f_dialog_line_sanitize __password2 + +		# Return if user has either pressed ESC or chosen Cancel/No +		[ $__retval -eq $DIALOG_OK ] || return $__retval + +		# Check for password mismatch +		if [ "$__password1" != "$__password2" ]; then +			f_show_msg "$msg_group_passwords_do_not_match" +			continue +		fi + +		# Check for NULL entry +		if [ ! "$__password1" ]; then +			f_dialog_yesno "$msg_disable_password_auth_for_group" +			__retval=$? +			if [ $__retval -eq $DIALOG_ESC ]; then +				return $__retval +			elif [ $__retval -eq $DIALOG_OK ]; then +				setvar "$__dvar_to_set" 1 +			else +				continue # back to password prompt +			fi +		else +			setvar "$__dvar_to_set" "" +		fi + +		setvar "$__var_to_set" "$__password1" +		break +	done + +	return $DIALOG_OK +} + +# f_dialog_input_group_gid $var_to_set [$group_gid] +# +# Allow the user to enter a new GID for a given group. If the user does not +# cancel or press ESC, the $var_to_set variable will hold the newly-configured +# value upon return. +# +f_dialog_input_group_gid() +{ +	local __var_to_set="$1" __input="$2" + +	# Return if user has either pressed ESC or chosen Cancel/No +	f_dialog_input __input "$msg_group_id_leave_empty_for_default" \ +	               "$__input" "$hline_num_tab_enter" || return $? + +	setvar "$__var_to_set" "$__input" +	return $DIALOG_OK +} + +# f_dialog_input_group_members $var_to_set [$group_members] +# +# Allow the user to modify a list of members for a given group. If the user +# does not cancel or press ESC, the $var_to_set variable will hold the newly- +# configured value upon return. +# +f_dialog_input_group_members() +{ +	local __var_to_set="$1" __input="$2" +	local __prompt="$msg_group_members:" +	local __menu_list=" +		'X' '$msg_continue' +		'1' '$msg_select_group_members_from_list' +		'2' '$msg_enter_group_members_manually' +	" # END-QUOTE +	local __defaultitem= +	local __hline="$hline_num_arrows_tab_enter" + +	local __mheight __mwidth __mrows +	eval f_dialog_menu_size __mheight __mwidth __mrows \ +	                        \"\$DIALOG_TITLE\"     \ +	                        \"\$DIALOG_BACKTITLE\" \ +	                        \"\$__prompt\"         \ +	                        \"\$__hline\"          \ +	                        $__menu_list + +	local __menu_choice __retval +	while :; do +		__menu_choice=$( eval $DIALOG \ +			--title \"\$DIALOG_TITLE\"         \ +			--backtitle \"\$DIALOG_BACKTITLE\" \ +			--hline \"\$__hline\"              \ +			--ok-label \"\$msg_ok\"            \ +			--cancel-label \"\$msg_cancel\"    \ +			--default-item \"\$__defaultitem\" \ +			--menu \"\$__prompt\"              \ +			$__mheight $__mwidth $__mrows      \ +			$__menu_list                       \ +			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +		) +		__retval=$? +		f_dialog_data_sanitize __menu_choice +		__defaultitem="$__menu_choice" +		f_dprintf "retval=%u menu_choice=[%s]" \ +		          $__retval "$__menu_choice" + +		# Return if user has either pressed ESC or chosen Cancel/No +		[ $__retval -eq $DIALOG_OK ] || return $__retval + +		local __group_members +		case "$__menu_choice" in +		X) # Exit +			break ;; +		1) # Select Group Members from a list +			local __check_list= # Calculated below +			local __user_list __u __user __length=0 +			__user_list=$( pw usershow -a | +				awk -F: '!/^[[:space:]]*(#|$)/{print $1}' ) +			while [ $__length -ne ${#__user_list} ]; do +				__u="${__user_list%%$NL*}" # First line +				f_shell_escape "$__u" __user + +				# Format of a checklist entry: tag item status +				__check_list="$__check_list '$__user' ''" +				case "$__input" in +				"$__u"|"$__u",*|*,"$__u",*|*,"$__u") +					__check_list="$__check_list on" ;; +				*) +					__check_list="$__check_list off" +				esac + +				__length=${#__user_list} +				__user_list="${__user_list#*$NL}" # Kill line +			done + +			local __cheight __cwidth __crows +			eval f_dialog_checklist_size \ +				__cheight __cwidth __crows \ +				\"\$DIALOG_TITLE\"     \ +				\"\$DIALOG_BACKTITLE\" \ +				\"\$__prompt\"         \ +				\"\$__hline\"          \ +				$__check_list +			__group_members=$( eval $DIALOG \ +				--title \"\$DIALOG_TITLE\"         \ +				--backtitle \"\$DIALOG_BACKTITLE\" \ +				--separate-output                  \ +				--hline \"\$__hline\"              \ +				--ok-label \"\$msg_ok\"            \ +				--cancel-label \"\$msg_cancel\"    \ +				--checklist \"\$__prompt\"         \ +				$__cheight $__cwidth $__crows      \ +				$__check_list                      \ +				2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +			) || continue +				# Return to previous menu if user either +				# pressed ESC or chose Cancel/No +			f_dialog_data_sanitize __group_members + +			# +			# Convert the newline separated list into a comma- +			# separated one so that if the user switches over to +			# manual editing, list reflects checklist selections +			# +			f_replaceall "$__group_members" "[$NL]" "," __input +			;; +		2) # Enter Group Members manually +			local __prompt2="$msg_group_members" +			__prompt2="$__prompt2 ($msg_separated_by_commas)" + +			f_dialog_input __group_members \ +			               "$__prompt2" "$__input" \ +			               "$hline_num_tab_enter" || continue +				# Return to previous menu if user either +				# pressed ESC or chose Cancel/No + +			__input="$__group_members" +			;; +		esac +	done + +	setvar "$__var_to_set" "$__input" +	return $DIALOG_OK +} + +# f_dialog_menu_group_add [$defaultitem] +# +# Present a menu detailing the properties of a group that is about to be added. +# The user's menu choice is available using f_dialog_menutag_fetch(). Returns +# success unless the user chose Cancel or pressed ESC. Data to display is taken +# from environment variables group_name, group_gid, and group_members. If +# $defaultitem is present and non-NULL, initially highlight the item in the +# menu. +# +f_dialog_menu_group_add() +{ +	local prompt="$msg_save_exit_or_cancel" +	local menu_list # Calculated below +	local defaultitem="$1" +	local hline="$hline_arrows_tab_enter" + +	# Localize potentially hostile variables and escape their values +	# to the local variable (see f_shell_escape() of `strings.subr') +	local var +	for var in gid members name; do +		local _group_$var +		eval f_shell_escape \"\$group_$var\" _group_$var +	done + +	menu_list=" +		'X' '$msg_add/$msg_exit' +		'1' '$msg_group: $_group_name' +		'2' '$msg_password: -----' +		'3' '$msg_group_id: $_group_gid' +		'4' '$msg_group_members: $_group_members' +	" # END-QUOTE + +	local height width rows +	eval f_dialog_menu_size height width rows \ +	                        \"\$DIALOG_TITLE\"     \ +	                        \"\$DIALOG_BACKTITLE\" \ +	                        \"\$prompt\"           \ +	                        \"\$hline\"            \ +	                        $menu_list + +	local menu_choice +	menu_choice=$( eval $DIALOG \ +		--title \"\$DIALOG_TITLE\"         \ +		--backtitle \"\$DIALOG_BACKTITLE\" \ +		--hline \"\$hline\"                \ +		--ok-label \"\$msg_ok\"            \ +		--cancel-label \"\$msg_cancel\"    \ +		--default-item \"\$defaultitem\"   \ +		--menu \"\$prompt\"                \ +		$height $width $rows               \ +		$menu_list                         \ +		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +	) +	local retval=$? +	f_dialog_data_sanitize menu_choice +	f_dialog_menutag_store "$menu_choice" +	return $retval +} + +# f_dialog_menu_group_delete $group [$defaultitem] +# +# Present a menu detailing the properties of a group that is about to be +# deleted. The user's menu choice is available using f_dialog_menutag_fetch(). +# Returns success unless the user chose Cancel or pressed ESC. Data to display +# is populated automatically from the system accounting database for the given +# $group argument. If $defaultitem is present and non-NULL, initially highlight +# the item in the menu. +# +f_dialog_menu_group_delete() +{ +	local prompt="$msg_delete_exit_or_cancel" +	local menu_list # Calculated below +	local defaultitem="$2" +	local hline="$hline_arrows_tab_enter" + +	local group_name group_password group_gid group_members +	f_input_group "$1" + +	# Localize potentially hostile variables and escape their values +	# to the local variable (see f_shell_escape() of `strings.subr') +	local var +	for var in gid members name; do +		local _group_$var +		eval f_shell_escape \"\$group_$var\" _group_$var +	done + +	menu_list=" +		'X' '$msg_delete/$msg_exit' +		'1' '$msg_group: $_group_name' +		'-' '$msg_password: -----' +		'-' '$msg_group_id: $_group_gid' +		'-' '$msg_group_members: $_group_members' +	" # END-QUOTE + +	local height width rows +	eval f_dialog_menu_size height width rows \ +	                        \"\$DIALOG_TITLE\"     \ +	                        \"\$DIALOG_BACKTITLE\" \ +	                        \"\$prompt\"           \ +	                        \"\$hline\"            \ +	                        $menu_list + +	local menu_choice +	menu_choice=$( eval $DIALOG \ +		--title \"\$DIALOG_TITLE\"         \ +		--backtitle \"\$DIALOG_BACKTITLE\" \ +		--hline \"\$hline\"                \ +		--ok-label \"\$msg_ok\"            \ +		--cancel-label \"\$msg_cancel\"    \ +		--default-item \"\$defaultitem\"   \ +		--menu \"\$prompt\"                \ +		$height $width $rows               \ +		$menu_list                         \ +		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +	) +	local retval=$? +	f_dialog_data_sanitize menu_choice +	f_dialog_menutag_store "$menu_choice" +	return $retval +} + +# f_dialog_menu_group_edit [$defaultitem] +# +# Present a menu detailing the properties of a group that is about to be +# modified. The user's menu choice is available using f_dialog_menutag_fetch(). +# Returns success unless the user chose Cancel or pressed ESC. Data to display +# is taken from environment variables group_name, group_gid, and group_members. +# If $defaultitem is present and non-NULL, initially highlight the item in the +# menu. +# +f_dialog_menu_group_edit() +{ +	local prompt="$msg_save_exit_or_cancel" +	local menu_list # Calculated below +	local defaultitem="$1" +	local hline="$hline_arrows_tab_enter" + +	# Localize potentially hostile variables and escape their values +	# to the local variable (see f_shell_escape() of `strings.subr') +	local var +	for var in gid members name; do +		local _group_$var +		eval f_shell_escape \"\$group_$var\" _group_$var +	done + +	menu_list=" +		'X' '$msg_save/$msg_exit' +		'1' '$msg_group: $_group_name' +		'2' '$msg_password: -----' +		'3' '$msg_group_id: $_group_gid' +		'4' '$msg_group_members: $_group_members' +	" # END-QUOTE + +	local height width rows +	eval f_dialog_menu_size height width rows \ +	                        \"\$DIALOG_TITLE\"     \ +	                        \"\$DIALOG_BACKTITLE\" \ +	                        \"\$prompt\"           \ +	                        \"\$hline\"            \ +	                        $menu_list + +	local menu_choice +	menu_choice=$( eval $DIALOG \ +		--title \"\$DIALOG_TITLE\"         \ +		--backtitle \"\$DIALOG_BACKTITLE\" \ +		--hline \"\$hline\"                \ +		--ok-label \"\$msg_ok\"            \ +		--cancel-label \"\$msg_cancel\"    \ +		--default-item \"\$defaultitem\"   \ +		--menu \"\$prompt\"                \ +		$height $width $rows               \ +		$menu_list                         \ +		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD +	) +	local retval=$? +	f_dialog_data_sanitize menu_choice +	f_dialog_menutag_store "$menu_choice" +	return $retval +} + +############################################################ MAIN + +f_dprintf "%s: Successfully loaded." usermgmt/group_input.subr + +fi # ! $_USERMGMT_GROUP_INPUT_SUBR | 
