group_input.subr revision 245437
133965Sjdpif [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1
2130561Sobrien#
3218822Sdim# Copyright (c) 2012 Ron McDowell
433965Sjdp# Copyright (c) 2012 Devin Teske
5218822Sdim# All rights reserved.
6218822Sdim#
7218822Sdim# Redistribution and use in source and binary forms, with or without
8218822Sdim# modification, are permitted provided that the following conditions
933965Sjdp# are met:
10218822Sdim# 1. Redistributions of source code must retain the above copyright
11218822Sdim#    notice, this list of conditions and the following disclaimer.
12218822Sdim# 2. Redistributions in binary form must reproduce the above copyright
13218822Sdim#    notice, this list of conditions and the following disclaimer in the
14218822Sdim#    documentation and/or other materials provided with the distribution.
15218822Sdim#
16218822Sdim# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17218822Sdim# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1833965Sjdp# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19218822Sdim# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20218822Sdim# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21218822Sdim# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22218822Sdim# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2333965Sjdp# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24218822Sdim# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25218822Sdim# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26218822Sdim# SUCH DAMAGE.
27218822Sdim#
2833965Sjdp# $FreeBSD: head/usr.sbin/bsdconfig/usermgmt/share/group_input.subr 245437 2013-01-14 21:03:34Z dteske $
29218822Sdim#
3033965Sjdp############################################################ INCLUDES
3133965Sjdp
3233965SjdpBSDCFG_SHARE="/usr/share/bsdconfig"
33130561Sobrien. $BSDCFG_SHARE/common.subr || exit 1
3433965Sjdpf_dprintf "%s: loading includes..." usermgmt/group_input.subr
35130561Sobrienf_include $BSDCFG_SHARE/dialog.subr
36130561Sobrienf_include $BSDCFG_SHARE/strings.subr
37130561Sobrien
38130561SobrienBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
3933965Sjdpf_include_lang $BSDCFG_LIBE/include/messages.subr
4033965Sjdpf_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
4168765Sobrien
4268765Sobrien############################################################ FUNCTIONS
4368765Sobrien
4468765Sobrien# f_input_group $group
4591041Sobrien#
4691041Sobrien# Given $group name or id, create the environment variables group_name,
47218822Sdim# group_gid, and group_members (and group_password is reset to NULL).
48218822Sdim#
4933965Sjdpf_input_group()
5068765Sobrien{
5168765Sobrien	eval $( pw groupshow "$1" | awk -F: '
5268765Sobrien	{
5368765Sobrien		printf "group_name='\'%s\''\n", $1
5468765Sobrien		printf "group_password=\n"
5568765Sobrien		printf "group_gid='\'%s\''\n", $3
5668765Sobrien		printf "group_members='\'%s\''\n", $4
5768765Sobrien		exit
5877298Sobrien	}' )
5977298Sobrien}
6060484Sobrien
6133965Sjdp# f_dialog_menu_group_list
6277298Sobrien#
6333965Sjdp# Allows the user to select a group from a list.
6433965Sjdp#
6533965Sjdpf_dialog_menu_group_list()
6633965Sjdp{
6733965Sjdp	local menu_list size
6833965Sjdp	local hline="$hline_alnum_punc_tab_enter"
6933965Sjdp
7033965Sjdp	menu_list="
7133965Sjdp		'X $msg_exit' ''
7233965Sjdp	" # END-QUOTE
7333965Sjdp
7489857Sobrien	# Add groups from group(5)
7533965Sjdp	menu_list="$menu_list $( pw groupshow -a | awk -F: '
7633965Sjdp		!/^[[:space:]]*(#|$)/ {
7733965Sjdp			printf "'\'%s\'\ \'%s\''\n", $1, $1
7833965Sjdp		}'
7960484Sobrien	)"
8060484Sobrien
8168765Sobrien	size=$( eval f_dialog_menu_size \
8277298Sobrien	        	\"\$DIALOG_TITLE\"     \
8377298Sobrien	        	\"\$DIALOG_BACKTITLE\" \
8477298Sobrien	        	\"\"                   \
8533965Sjdp	        	\"\$hline\"            \
8633965Sjdp	        	$menu_list             )
8733965Sjdp
8833965Sjdp	local dialog_menu
8989857Sobrien	dialog_menu=$( eval $DIALOG \
9068765Sobrien		--clear --title \"\$DIALOG_TITLE\" \
9168765Sobrien		--backtitle \"\$DIALOG_BACKTITLE\" \
9268765Sobrien		--hline \"\$hline\"                \
9368765Sobrien		--ok-label \"\$msg_ok\"            \
9468765Sobrien		--cancel-label \"\$msg_cancel\"    \
9568765Sobrien		--menu \"\" $size $menu_list       \
9677298Sobrien		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
9777298Sobrien	)
9877298Sobrien	local retval=$?
9933965Sjdp	setvar DIALOG_MENU_$$ "$dialog_menu"
10033965Sjdp	return $retval
10133965Sjdp}
10233965Sjdp
10333965Sjdp# f_dialog_input_group_name [$group_name]
10433965Sjdp#
10533965Sjdp# Allows the user to enter a new groupname for a given group. If the user does
10660484Sobrien# not cancel or press ESC, the $group_name variable will hold the
10760484Sobrien# newly-configured value upon return.
10860484Sobrien#
10977298Sobrien# If $cur_group_name is defined, the user can enter that and by-pass error-
11077298Sobrien# checking (allowing the user to "revert" to an old value without, for example,
11177298Sobrien# being told that the groupname already exists).
11233965Sjdp#
11368765Sobrienf_dialog_input_group_name()
11468765Sobrien{
11568765Sobrien	#
11689857Sobrien	# Loop until the user provides taint-free/valid input
11768765Sobrien	#
11889857Sobrien	local _name="$1" _input="$1"
11989857Sobrien	while :; do
12089857Sobrien
12168765Sobrien		# Return if user has either pressed ESC or chosen Cancel/No
12268765Sobrien		_input=$( f_dialog_input "$msg_group" "$_input" \
12333965Sjdp		                         "$hline_alnum_tab_enter"
124218822Sdim		        ) || return
12533965Sjdp
12633965Sjdp		# Check for no-change
127218822Sdim		[ "$_input" = "$_name" ] && return $SUCCESS
12833965Sjdp
12933965Sjdp		# Check for reversion
130218822Sdim		if [ "$_input" = "$cur_group_name" ]; then
13133965Sjdp			group_name="$cur_group_name"
13233965Sjdp			return $SUCCESS
13333965Sjdp		fi
13433965Sjdp
135218822Sdim		# Check for NULL entry
13633965Sjdp		if [ ! "$_input" ]; then
13768765Sobrien			f_dialog_msgbox "$msg_group_is_empty"
138218822Sdim			continue
13968765Sobrien		fi
14068765Sobrien
141218822Sdim		# Check for invalid entry
14268765Sobrien		if ! echo "$_input" | grep -q "^[[:alpha:]]"; then
143218822Sdim			f_dialog_msgbox "$msg_group_must_start_with_letter"
144218822Sdim			continue
145218822Sdim		fi
146218822Sdim
147218822Sdim		# Check for duplicate entry
148218822Sdim		if f_quietly pw groupshow -n "$_input"; then
149218822Sdim			f_show_msg "$msg_group_already_used" "$_input"
150218822Sdim			continue
151218822Sdim		fi
152218822Sdim
15368765Sobrien		group_name="$_input"
154218822Sdim		break
15568765Sobrien	done
156218822Sdim	save_flag=1
157218822Sdim
158218822Sdim	f_dprintf "group_name: [%s]->[%s]" "$cur_group_name" "$group_name"
159218822Sdim
16089857Sobrien	return $SUCCESS
161218822Sdim}
16289857Sobrien
16389857Sobrien# f_dialog_input_group_password
16489857Sobrien#
16589857Sobrien# Prompt the user to enter a password (twice).
16689857Sobrien#
16789857Sobrienf_dialog_input_group_password()
16889857Sobrien{
16989857Sobrien	local hline="$hline_alnum_punc_tab_enter"
17089857Sobrien	local msg size rmsg rsize
17189857Sobrien
17289857Sobrien	msg=$( printf "$msg_group_password" )
17389857Sobrien	size=$( f_dialog_inputbox_size \
174218822Sdim	        	"$DIALOG_TITLE"     \
17589857Sobrien	        	"$DIALOG_BACKTITLE" \
17689857Sobrien	        	"$msg"              \
17789857Sobrien	        	""                  \
17889857Sobrien	        	"$hline"            )
17989857Sobrien
18089857Sobrien	rmsg=$( printf "$msg_reenter_group_password" )
18189857Sobrien	rsize=$( f_dialog_inputbox_size \
18289857Sobrien	        	"$DIALOG_TITLE"     \
18389857Sobrien	        	"$DIALOG_BACKTITLE" \
18489857Sobrien	        	"$rmsg"             \
18589857Sobrien	        	""                  \
18689857Sobrien	        	"$hline"            )
18789857Sobrien
188218822Sdim	#
18989857Sobrien	# Loop until the user provides taint-free/valid input
190130561Sobrien	#
191130561Sobrien	local retval _password1 _password2
192130561Sobrien	while :; do
193130561Sobrien		local dialog_inputbox
194130561Sobrien		dialog_inputbox=$( eval $DIALOG \
195130561Sobrien			--title \"\$DIALOG_TITLE\"         \
196130561Sobrien			--backtitle \"\$DIALOG_BACKTITLE\" \
197130561Sobrien			--hline \"\$hline\"                \
198130561Sobrien			--ok-label \"\$msg_ok\"            \
199130561Sobrien			--cancel-label \"\$msg_cancel\"    \
200130561Sobrien			--insecure                         \
201130561Sobrien			--passwordbox \"\$msg\" $size      \
202130561Sobrien			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
203130561Sobrien		)
204130561Sobrien
205130561Sobrien		retval=$?
206130561Sobrien		setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
207130561Sobrien		_password1=$( f_dialog_inputstr )
208130561Sobrien
209130561Sobrien		# Return if user has either pressed ESC or chosen Cancel/No
210130561Sobrien		[ $retval -eq $SUCCESS ] || return $retval
211130561Sobrien
212130561Sobrien		dialog_inputbox=$( eval $DIALOG \
213130561Sobrien			--title \"\$DIALOG_TITLE\"         \
214130561Sobrien			--backtitle \"\$DIALOG_BACKTITLE\" \
215130561Sobrien			--hline \"\$hline\"                \
216130561Sobrien			--ok-label \"\$msg_ok\"            \
217130561Sobrien			--cancel-label \"\$msg_cancel\"    \
218130561Sobrien			--insecure                         \
219130561Sobrien			--passwordbox \"\$rmsg\" $rsize    \
220130561Sobrien			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
221130561Sobrien		)
222130561Sobrien
223130561Sobrien		retval=$?
224130561Sobrien		setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
225130561Sobrien		_password2=$( f_dialog_inputstr )
226130561Sobrien
227130561Sobrien		# Return if user has either pressed ESC or chosen Cancel/No
228130561Sobrien		[ $retval -eq $SUCCESS ] || return $retval
229130561Sobrien
230130561Sobrien		# Check for password mismatch
231130561Sobrien		if [ "$_password1" != "$_password2" ]; then
232130561Sobrien			f_dialog_msgbox "$msg_group_passwords_do_not_match"
233130561Sobrien			continue
234130561Sobrien		fi
235130561Sobrien
236130561Sobrien		# Check for NULL entry
237130561Sobrien		if [ ! "$_password1" ]; then
238130561Sobrien			f_dialog_yesno \
239130561Sobrien				"$msg_disable_password_auth_for_group" ||
240130561Sobrien				continue
241130561Sobrien			pw_group_password_disable=1
242130561Sobrien		else
243130561Sobrien			pw_group_password_disable=
244130561Sobrien		fi
245130561Sobrien
246130561Sobrien		group_password="$_password1"
247130561Sobrien		break
248130561Sobrien	done
249130561Sobrien	save_flag=1
250130561Sobrien
251130561Sobrien	f_dprintf "group_password: [%s]->[%s]" \
252130561Sobrien	          "$cur_group_password" "$group_password"
253130561Sobrien
254130561Sobrien	return $SUCCESS
255130561Sobrien}
256130561Sobrien
257130561Sobrien# f_dialog_input_group_gid [$group_gid]
258130561Sobrien#
259130561Sobrien# Allow the user to enter a new GID for a given group. If the user does not
260130561Sobrien# cancel or press ESC, the $group_gid variable will hold the newly-configured
261130561Sobrien# value upon return.
262130561Sobrien#
263130561Sobrienf_dialog_input_group_gid()
264130561Sobrien{
265218822Sdim	local _input="$1"
266218822Sdim
267218822Sdim	# Return if user has either pressed ESC or chosen Cancel/No
268130561Sobrien	_input=$( f_dialog_input "$msg_group_id_leave_empty_for_default" \
269130561Sobrien	                         "$_input" "$hline_num_tab_enter"
270130561Sobrien	        ) || return
271130561Sobrien
272130561Sobrien	group_gid="$_input"
273130561Sobrien	save_flag=1
274130561Sobrien
275130561Sobrien	f_dprintf "group_gid: [%s]->[%s]" "$cur_group_gid" "$group_gid"
276130561Sobrien
277130561Sobrien	return $SUCCESS
278130561Sobrien}
279130561Sobrien
280130561Sobrien# f_dialog_input_group_members [$group_members]
281130561Sobrien#
282130561Sobrien# Allow the user to modify a list of members for a given group. If the user does
283130561Sobrien# not cancel or press ESC, the $group_members variable will hold the newly-
284130561Sobrien# configured value upon return.
285130561Sobrien#
286130561Sobrienf_dialog_input_group_members()
287130561Sobrien{
288130561Sobrien	local menu_choice msg size retval _input="$1"
289130561Sobrien	local hline="$hline_num_arrows_tab_enter"
290130561Sobrien	local user 
291130561Sobrien	local menu_list
292130561Sobrien	local all_users_valid
293130561Sobrien	local _group_members
294130561Sobrien	local checklist_users
295130561Sobrien
296130561Sobrien	menu_list="
297130561Sobrien		'X' '$msg_continue'
298130561Sobrien		'1' '$msg_select_group_members_from_list'
299130561Sobrien		'2' '$msg_enter_group_members_manually'
300130561Sobrien	" # END-QUOTE
301130561Sobrien
302130561Sobrien	local dialog_menu
303130561Sobrien	while :; do
304130561Sobrien		msg="$msg_group_members:"
305130561Sobrien		menu_size=$( eval f_dialog_menu_size \
306130561Sobrien				\"\$DIALOG_TITLE\"     \
307130561Sobrien				\"\$DIALOG_BACKTITLE\" \
308130561Sobrien				\"\$msg\"              \
309130561Sobrien				\"\$hline\"            \
310130561Sobrien				$menu_list             )
311130561Sobrien		dialog_menu=$( eval $DIALOG \
312130561Sobrien			--title \"\$DIALOG_TITLE\"         \
313130561Sobrien			--backtitle \"\$DIALOG_BACKTITLE\" \
314130561Sobrien			--hline \"\$hline\"                \
315130561Sobrien			--ok-label \"\$msg_ok\"            \
316130561Sobrien			--cancel-label \"\$msg_cancel\"    \
317130561Sobrien			--menu \"\$msg\" $menu_size        \
318130561Sobrien			$menu_list                         \
319130561Sobrien			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
320130561Sobrien		)
321130561Sobrien		retval=$?
322130561Sobrien		setvar DIALOG_MENU_$$ "$dialog_menu"
323130561Sobrien		menu_choice=$( f_dialog_menutag )
324130561Sobrien		f_dprintf "retval=%u menu_choice=[%s]" $retval "$menu_choice"
325130561Sobrien
326130561Sobrien		# Return if user has either pressed ESC or chosen Cancel/No
327130561Sobrien		[ $retval -eq $SUCCESS ] || return $retval
328130561Sobrien
329130561Sobrien		case "$menu_choice" in
330130561Sobrien		X) # Exit
331130561Sobrien			break ;;
332130561Sobrien		1) # Select Group Members from a list
333130561Sobrien			user_list=$( pw usershow -a | awk -F: '
334130561Sobrien				!/^[[:space:]]*(#|$)/ { printf "%s\n", $1 }' )
335130561Sobrien			checklist_users=
336130561Sobrien			for user in $user_list; do
337130561Sobrien				checklist_users="$checklist_users $user \"\""
338130561Sobrien				if echo "$_input" | grep -q "\<$user\>"; then
339130561Sobrien					checklist_users="$checklist_users on"
340130561Sobrien				else
341130561Sobrien					checklist_users="$checklist_users off"
342130561Sobrien				fi
343130561Sobrien			done
344130561Sobrien
345130561Sobrien			size=$( eval f_dialog_radiolist_size \
346130561Sobrien			        	\"\$DIALOG_TITLE\"     \
347130561Sobrien			        	\"\$DIALOG_BACKTITLE\" \
348130561Sobrien			        	\"\"                   \
349130561Sobrien			        	\"\$hline\"            \
350130561Sobrien			        	$checklist_users       )
351130561Sobrien			local dialog_inputbox
352130561Sobrien			dialog_inputbox=$( eval $DIALOG \
353130561Sobrien				--title \"\$DIALOG_TITLE\"         \
354130561Sobrien				--backtitle \"\$DIALOG_BACKTITLE\" \
355130561Sobrien				--separate-output                  \
356130561Sobrien				--hline \"\$hline\"                \
357130561Sobrien				--ok-label \"\$msg_ok\"            \
358130561Sobrien				--cancel-label \"\$msg_cancel\"    \
359130561Sobrien				--checklist \"\$msg\" $size        \
360130561Sobrien				$checklist_users                   \
361130561Sobrien				2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
362130561Sobrien			)
363130561Sobrien			retval=$?
364130561Sobrien			setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox"
365130561Sobrien			_group_members=$( f_dialog_inputstr | tr '\n' ' ' |
366130561Sobrien				sed -e 's/[[:space:]]\{1,\}/,/g;s/^,//;s/,$//' )
367130561Sobrien
368130561Sobrien			# Return to previous menu if user has either
369130561Sobrien			#     pressed ESC or chosen Cancel/No
370130561Sobrien			[ $retval -eq $SUCCESS ] || continue
371130561Sobrien
372130561Sobrien			_input="$_group_members"
373130561Sobrien			;;
374130561Sobrien		2) # Enter Group Members manually
375130561Sobrien			msg="$msg_group_members ($msg_separated_by_commas)"
376130561Sobrien
377130561Sobrien			# Return to previous menu if user has either
378130561Sobrien			#     pressed ESC or chosen Cancel/No
379130561Sobrien			_group_members=$( f_dialog_input "$msg" "$_input" \
380130561Sobrien			                                 "$hline_num_tab_enter"
381130561Sobrien			                ) || continue
382130561Sobrien
383130561Sobrien			_input="$_group_members"
384130561Sobrien			;;
385130561Sobrien		esac
386130561Sobrien	done
387130561Sobrien
388130561Sobrien	group_members="$_input"
389130561Sobrien	save_flag=1
390130561Sobrien	f_dprintf "group_members: [%s]->[%s]" \
391130561Sobrien	          "$cur_group_members" "$group_members"
392130561Sobrien
393130561Sobrien	return $SUCCESS
394130561Sobrien}
395130561Sobrien
396130561Sobrien############################################################ MAIN
397130561Sobrien
398130561Sobrienf_dprintf "%s: Successfully loaded." usermgmt/group_input.subr
399130561Sobrien
400130561Sobrienfi # ! $_USERMGMT_GROUP_INPUT_SUBR
401130561Sobrien