group_input.subr revision 251190
1139749Simpif [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1
272016Scg#
372016Scg# Copyright (c) 2012 Ron McDowell
472016Scg# Copyright (c) 2012-2013 Devin Teske
572016Scg# All rights reserved.
672016Scg#
772016Scg# Redistribution and use in source and binary forms, with or without
872016Scg# modification, are permitted provided that the following conditions
972016Scg# are met:
1072016Scg# 1. Redistributions of source code must retain the above copyright
1172016Scg#    notice, this list of conditions and the following disclaimer.
1272016Scg# 2. Redistributions in binary form must reproduce the above copyright
1372016Scg#    notice, this list of conditions and the following disclaimer in the
1472016Scg#    documentation and/or other materials provided with the distribution.
1572016Scg#
1672016Scg# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1772016Scg# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1872016Scg# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1972016Scg# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2072016Scg# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2172016Scg# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2272016Scg# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2372016Scg# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2472016Scg# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2572016Scg# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2672016Scg# SUCH DAMAGE.
2772016Scg#
2872016Scg# $FreeBSD: head/usr.sbin/bsdconfig/usermgmt/share/group_input.subr 251190 2013-05-31 19:07:17Z dteske $
2972016Scg#
30108533Sschweikh############################################################ INCLUDES
3172016Scg
3273772ScgBSDCFG_SHARE="/usr/share/bsdconfig"
3378362Scg. $BSDCFG_SHARE/common.subr || exit 1
3472016Scgf_dprintf "%s: loading includes..." usermgmt/group_input.subr
3572016Scgf_include $BSDCFG_SHARE/dialog.subr
3672016Scgf_include $BSDCFG_SHARE/strings.subr
3774994Sorion
3874994SorionBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
3974994Sorionf_include_lang $BSDCFG_LIBE/include/messages.subr
4074994Sorionf_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
4172016Scg
4272016Scg############################################################ FUNCTIONS
4372016Scg
4472016Scg# f_input_group $group
4572016Scg#
4672016Scg# Given $group name or id, create the environment variables group_name,
47119287Simp# group_gid, and group_members (and group_password is reset to NULL).
48119287Simp#
4972016Scgf_input_group()
5074994Sorion{
5174994Sorion	eval $( pw groupshow "$1" | awk -F: '
5272016Scg	{
5372016Scg		printf "group_name='\'%s\''\n", $1
5482180Scg		printf "group_password=\n"
5582180Scg		printf "group_gid='\'%s\''\n", $3
5672016Scg		printf "group_members='\'%s\''\n", $4
5772016Scg		exit
5872016Scg	}' )
5972016Scg}
6072016Scg
6172016Scg# f_dialog_menu_group_list [$default]
6272016Scg#
6384771Sorion# Allows the user to select a group from a list. Optionally, if present and
6472016Scg# non-NULL, initially highlight $default group.
6572016Scg#
6672016Scgf_dialog_menu_group_list()
6772016Scg{
6872016Scg	local defaultitem="$1"
6972016Scg	local menu_list
7072016Scg	local hline="$hline_alnum_punc_tab_enter"
7172016Scg
7272016Scg	menu_list="
7372016Scg		'X $msg_exit' ''
7472016Scg	" # END-QUOTE
7572016Scg
7672016Scg	# Add groups from group(5)
7772016Scg	menu_list="$menu_list $( pw groupshow -a | awk -F: '
7874994Sorion		!/^[[:space:]]*(#|$)/ {
7972016Scg			printf "'\'%s\'\ \'%s\''\n", $1, $1
8072016Scg		}'
8172016Scg	)"
8272016Scg
8372016Scg	local height width rows
8472016Scg	eval f_dialog_menu_size height width rows \
8572016Scg	                        \"\$DIALOG_TITLE\"     \
8672016Scg	                        \"\$DIALOG_BACKTITLE\" \
8772016Scg	                        \"\"                   \
8872016Scg	                        \"\$hline\"            \
8972016Scg	                        $menu_list
9074994Sorion
9172016Scg	local dialog_menu
9274994Sorion	dialog_menu=$( eval $DIALOG \
9374994Sorion		--title \"\$DIALOG_TITLE\"         \
9474994Sorion		--backtitle \"\$DIALOG_BACKTITLE\" \
9574994Sorion		--hline \"\$hline\"                \
9674994Sorion		--ok-label \"\$msg_ok\"            \
9774994Sorion		--cancel-label \"\$msg_cancel\"    \
9874994Sorion		--default-item \"\$defaultitem\"   \
9972016Scg		--menu \"\"                        \
10072016Scg		$height $width $rows               \
10174994Sorion		$menu_list                         \
10274994Sorion		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
10373772Scg	)
10474994Sorion	local retval=$?
10574994Sorion	setvar DIALOG_MENU_$$ "$dialog_menu"
10674994Sorion	return $retval
10775174Sorion}
10874994Sorion
10974994Sorion# f_dialog_input_group_name [$group_name]
110107285Scg#
11172016Scg# Allows the user to enter a new groupname for a given group. If the user does
11288032Sorion# not cancel or press ESC, the $group_name variable will hold the
11384771Sorion# newly-configured value upon return.
11474994Sorion#
11572016Scg# If $cur_group_name is defined, the user can enter that and by-pass error-
11672016Scg# checking (allowing the user to "revert" to an old value without, for example,
11772016Scg# being told that the groupname already exists).
11872016Scg#
11972016Scgf_dialog_input_group_name()
12072016Scg{
12172016Scg	#
12272016Scg	# Loop until the user provides taint-free/valid input
12372016Scg	#
12472016Scg	local _name="$1" _input="$1"
12572016Scg	while :; do
12672016Scg
12774763Scg		# Return if user has either pressed ESC or chosen Cancel/No
12872016Scg		_input=$( f_dialog_input "$msg_group" "$_input" \
12972016Scg		                         "$hline_alnum_tab_enter"
13072016Scg		        ) || return
13172016Scg
13272016Scg		# Check for no-change
13374994Sorion		[ "$_input" = "$_name" ] && return $SUCCESS
13472016Scg
13572016Scg		# Check for reversion
13672016Scg		if [ "$_input" = "$cur_group_name" ]; then
13774994Sorion			group_name="$cur_group_name"
13872016Scg			return $SUCCESS
13974994Sorion		fi
14072016Scg
14174994Sorion		# Check for NULL entry
14272016Scg		if [ ! "$_input" ]; then
14372016Scg			f_dialog_msgbox "$msg_group_is_empty"
14472016Scg			continue
14572016Scg		fi
14672016Scg
14772016Scg		# Check for invalid entry
14872016Scg		if ! echo "$_input" | grep -q "^[[:alpha:]]"; then
14974994Sorion			f_dialog_msgbox "$msg_group_must_start_with_letter"
15072016Scg			continue
15172016Scg		fi
15272016Scg
15374994Sorion		# Check for duplicate entry
15472016Scg		if f_quietly pw groupshow -n "$_input"; then
15572016Scg			f_show_msg "$msg_group_already_used" "$_input"
15674994Sorion			continue
15772016Scg		fi
15872016Scg
15974994Sorion		group_name="$_input"
16072016Scg		break
16172016Scg	done
16272016Scg	save_flag=1
16372016Scg
16472016Scg	f_dprintf "group_name: [%s]->[%s]" "$cur_group_name" "$group_name"
16578362Scg
16672016Scg	return $SUCCESS
16772016Scg}
16872016Scg
16972016Scg# f_dialog_input_group_password
17074994Sorion#
17172016Scg# Prompt the user to enter a password (twice).
17272016Scg#
17374994Sorionf_dialog_input_group_password()
17472016Scg{
17572016Scg	local hline="$hline_alnum_punc_tab_enter"
17672016Scg	local msg rmsg
17774994Sorion
17872016Scg	msg=$( printf "$msg_group_password" )
17972016Scg	local height1 width1
18073772Scg	f_dialog_inputbox_size height1 width1 \
18174994Sorion	        	"$DIALOG_TITLE"     \
18272016Scg	        	"$DIALOG_BACKTITLE" \
18374994Sorion	        	"$msg"              \
18472016Scg	        	""                  \
18572016Scg	        	"$hline"
18672016Scg
18774994Sorion	rmsg=$( printf "$msg_reenter_group_password" )
18872016Scg	local height2 width2
18972016Scg	f_dialog_inputbox_size height2 width2 \
19072016Scg	        	"$DIALOG_TITLE"     \
19174994Sorion	        	"$DIALOG_BACKTITLE" \
19272016Scg	        	"$rmsg"             \
19374994Sorion	        	""                  \
19472016Scg	        	"$hline"
19572016Scg
19672016Scg	#
19772016Scg	# Loop until the user provides taint-free/valid input
19872016Scg	#
19973772Scg	local retval _password1 _password2
20072016Scg	while :; do
20172016Scg		local dialog_inputbox
20272016Scg		dialog_inputbox=$( $DIALOG \
20372016Scg			--title "$DIALOG_TITLE"         \
20472016Scg			--backtitle "$DIALOG_BACKTITLE" \
20572016Scg			--hline "$hline"                \
20673772Scg			--ok-label "$msg_ok"            \
20772016Scg			--cancel-label "$msg_cancel"    \
20872016Scg			--insecure                      \
20972016Scg			--passwordbox "$msg"            \
21073772Scg			$height1 $width1                \
21172016Scg			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
21272016Scg		)
21372016Scg
21472016Scg		retval=$?
21572016Scg		setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
21672016Scg		_password1=$( f_dialog_inputstr )
21772016Scg
21872016Scg		# Return if user has either pressed ESC or chosen Cancel/No
21972016Scg		[ $retval -eq $SUCCESS ] || return $retval
22072016Scg
22172016Scg		dialog_inputbox=$( $DIALOG \
22272016Scg			--title "$DIALOG_TITLE"         \
22373772Scg			--backtitle "$DIALOG_BACKTITLE" \
22473772Scg			--hline "$hline"                \
22572016Scg			--ok-label "$msg_ok"            \
22672016Scg			--cancel-label "$msg_cancel"    \
22772016Scg			--insecure                      \
22872016Scg			--passwordbox "$rmsg"           \
22972016Scg			$height2 $width2                \
23072016Scg			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
23172016Scg		)
23272016Scg
23372016Scg		retval=$?
23474994Sorion		setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
23574994Sorion		_password2=$( f_dialog_inputstr )
23672016Scg
23772016Scg		# Return if user has either pressed ESC or chosen Cancel/No
23878362Scg		[ $retval -eq $SUCCESS ] || return $retval
23972016Scg
240102328Sorion		# Check for password mismatch
24174994Sorion		if [ "$_password1" != "$_password2" ]; then
242111183Scognet			f_dialog_msgbox "$msg_group_passwords_do_not_match"
24374994Sorion			continue
244102328Sorion		fi
24574994Sorion
24674994Sorion		# Check for NULL entry
24774994Sorion		if [ ! "$_password1" ]; then
24875174Sorion			f_dialog_yesno \
24974994Sorion				"$msg_disable_password_auth_for_group" ||
25074994Sorion				continue
25175174Sorion			pw_group_password_disable=1
25278362Scg		else
25374994Sorion			pw_group_password_disable=
25475174Sorion		fi
25575174Sorion
25675174Sorion		group_password="$_password1"
25775174Sorion		break
25875174Sorion	done
25975174Sorion	save_flag=1
26078362Scg
26178362Scg	f_dprintf "group_password: [%s]->[%s]" \
26275174Sorion	          "$cur_group_password" "$group_password"
26375174Sorion
26474994Sorion	return $SUCCESS
26572016Scg}
26672016Scg
26774994Sorion# f_dialog_input_group_gid [$group_gid]
26874994Sorion#
26972016Scg# Allow the user to enter a new GID for a given group. If the user does not
27074994Sorion# cancel or press ESC, the $group_gid variable will hold the newly-configured
27172016Scg# value upon return.
27275174Sorion#
27378362Scgf_dialog_input_group_gid()
27478362Scg{
27575290Sorion	local _input="$1"
27674994Sorion
27774994Sorion	# Return if user has either pressed ESC or chosen Cancel/No
27872016Scg	_input=$( f_dialog_input "$msg_group_id_leave_empty_for_default" \
27972016Scg	                         "$_input" "$hline_num_tab_enter"
28072016Scg	        ) || return
28174994Sorion
28272016Scg	group_gid="$_input"
28375174Sorion	save_flag=1
28478362Scg
28575174Sorion	f_dprintf "group_gid: [%s]->[%s]" "$cur_group_gid" "$group_gid"
28678362Scg
28775174Sorion	return $SUCCESS
28874994Sorion}
28974994Sorion
29072016Scg# f_dialog_input_group_members [$group_members]
29172016Scg#
29274994Sorion# Allow the user to modify a list of members for a given group. If the user does
29374994Sorion# not cancel or press ESC, the $group_members variable will hold the newly-
29472016Scg# configured value upon return.
29574994Sorion#
29672016Scgf_dialog_input_group_members()
29775174Sorion{
29878362Scg	local menu_choice retval _input="$1"
29978362Scg	local msg="$msg_group_members:"
30075290Sorion	local hline="$hline_num_arrows_tab_enter"
30174994Sorion	local user 
30274994Sorion	local menu_list
30372016Scg	local all_users_valid
30472016Scg	local _group_members
30572016Scg	local checklist_users
30674994Sorion
30772016Scg	menu_list="
30872016Scg		'X' '$msg_continue'
30972016Scg		'1' '$msg_select_group_members_from_list'
31072016Scg		'2' '$msg_enter_group_members_manually'
31172016Scg	" # END-QUOTE
31273772Scg
31372016Scg	local dialog_menu defaultitem=
31472016Scg	local mheight mwidth mrows
31572016Scg	eval f_dialog_menu_size mheight mwidth mrows \
31672016Scg	                        \"\$DIALOG_TITLE\"     \
31772016Scg	                        \"\$DIALOG_BACKTITLE\" \
31874994Sorion	                        \"\$msg\"              \
31972016Scg	                        \"\$hline\"            \
32074994Sorion	                        $menu_list
32174994Sorion
32274994Sorion	while :; do
32372016Scg		dialog_menu=$( eval $DIALOG \
32472016Scg			--title \"\$DIALOG_TITLE\"         \
32572016Scg			--backtitle \"\$DIALOG_BACKTITLE\" \
32672016Scg			--hline \"\$hline\"                \
32772016Scg			--ok-label \"\$msg_ok\"            \
32872016Scg			--cancel-label \"\$msg_cancel\"    \
32972016Scg			--default-item \"\$defaultitem\"   \
33078362Scg			--menu \"\$msg\"                   \
33174994Sorion			$mheight $mwidth $mrows            \
33272016Scg			$menu_list                         \
33374994Sorion			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
33474994Sorion		)
33572016Scg		retval=$?
33674994Sorion		setvar DIALOG_MENU_$$ "$dialog_menu"
33774994Sorion		defaultitem="$dialog_menu"
33874994Sorion		menu_choice=$( f_dialog_menutag )
33974994Sorion		f_dprintf "retval=%u menu_choice=[%s]" $retval "$menu_choice"
34074994Sorion
34174994Sorion		# Return if user has either pressed ESC or chosen Cancel/No
34274994Sorion		[ $retval -eq $SUCCESS ] || return $retval
34384771Sorion
34472016Scg		case "$menu_choice" in
34572016Scg		X) # Exit
34672016Scg			break ;;
34772016Scg		1) # Select Group Members from a list
34872016Scg			user_list=$( pw usershow -a | awk -F: '
34983214Sgreen				!/^[[:space:]]*(#|$)/ { printf "%s\n", $1 }' )
35075174Sorion			checklist_users=
35175174Sorion			for user in $user_list; do
35272016Scg				checklist_users="$checklist_users $user \"\""
35375174Sorion				if echo "$_input" | grep -q "\<$user\>"; then
35472016Scg					checklist_users="$checklist_users on"
35583214Sgreen				else
35672016Scg					checklist_users="$checklist_users off"
35772016Scg				fi
35872016Scg			done
35972016Scg
36073772Scg			local cheight cwidth crows
36173772Scg			eval f_dialog_checklist_size cheight cwidth crows \
36272016Scg			                             \"\$DIALOG_TITLE\"     \
36374994Sorion			                             \"\$DIALOG_BACKTITLE\" \
36483214Sgreen			                             \"\"                   \
36572016Scg			                             \"\$hline\"            \
36672016Scg			                             $checklist_users
36772016Scg			local dialog_inputbox
36872016Scg			dialog_inputbox=$( eval $DIALOG \
36972016Scg				--title \"\$DIALOG_TITLE\"         \
37072016Scg				--backtitle \"\$DIALOG_BACKTITLE\" \
37172016Scg				--separate-output                  \
37272016Scg				--hline \"\$hline\"                \
37372016Scg				--ok-label \"\$msg_ok\"            \
37472016Scg				--cancel-label \"\$msg_cancel\"    \
37572016Scg				--checklist \"\$msg\"              \
37672016Scg				$cheight $cwidth $crows            \
37772016Scg				$checklist_users                   \
37872016Scg				2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
37972016Scg			)
38072016Scg			retval=$?
38172016Scg			setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
38283214Sgreen			_group_members=$( f_dialog_inputstr | tr '\n' ' ' |
38372016Scg				sed -e 's/[[:space:]]\{1,\}/,/g;s/^,//;s/,$//' )
38472016Scg
38572016Scg			# Return to previous menu if user has either
38672016Scg			#     pressed ESC or chosen Cancel/No
38772016Scg			[ $retval -eq $SUCCESS ] || continue
38872016Scg
38972016Scg			_input="$_group_members"
39072016Scg			;;
39172016Scg		2) # Enter Group Members manually
39272016Scg			msg="$msg_group_members ($msg_separated_by_commas)"
39372016Scg
39472016Scg			# Return to previous menu if user has either
39572016Scg			#     pressed ESC or chosen Cancel/No
39683214Sgreen			_group_members=$( f_dialog_input "$msg" "$_input" \
39773772Scg			                                 "$hline_num_tab_enter"
39872016Scg			                ) || continue
39972016Scg
40072016Scg			_input="$_group_members"
40172016Scg			;;
40273772Scg		esac
40372016Scg	done
40473772Scg
40574994Sorion	group_members="$_input"
40683214Sgreen	save_flag=1
40772016Scg	f_dprintf "group_members: [%s]->[%s]" \
40872016Scg	          "$cur_group_members" "$group_members"
40972016Scg
41083214Sgreen	return $SUCCESS
41172016Scg}
41288032Sorion
41388032Sorion############################################################ MAIN
41472016Scg
41588032Sorionf_dprintf "%s: Successfully loaded." usermgmt/group_input.subr
41672016Scg
41772016Scgfi # ! $_USERMGMT_GROUP_INPUT_SUBR
41872016Scg