group_input.subr revision 260678
1238438Sdteskeif [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1
2238438Sdteske#
3238438Sdteske# Copyright (c) 2012 Ron McDowell
4249751Sdteske# Copyright (c) 2012-2013 Devin Teske
5238438Sdteske# All rights reserved.
6238438Sdteske#
7238438Sdteske# Redistribution and use in source and binary forms, with or without
8238438Sdteske# modification, are permitted provided that the following conditions
9238438Sdteske# are met:
10238438Sdteske# 1. Redistributions of source code must retain the above copyright
11238438Sdteske#    notice, this list of conditions and the following disclaimer.
12238438Sdteske# 2. Redistributions in binary form must reproduce the above copyright
13238438Sdteske#    notice, this list of conditions and the following disclaimer in the
14238438Sdteske#    documentation and/or other materials provided with the distribution.
15238438Sdteske#
16238438Sdteske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17238438Sdteske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18238438Sdteske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19238438Sdteske# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20238438Sdteske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21238438Sdteske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22238438Sdteske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23238438Sdteske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24238438Sdteske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25238438Sdteske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26238438Sdteske# SUCH DAMAGE.
27238438Sdteske#
28238438Sdteske# $FreeBSD: stable/10/usr.sbin/bsdconfig/usermgmt/share/group_input.subr 260678 2014-01-15 07:49:17Z dteske $
29238438Sdteske#
30238438Sdteske############################################################ INCLUDES
31238438Sdteske
32240684SdteskeBSDCFG_SHARE="/usr/share/bsdconfig"
33240684Sdteske. $BSDCFG_SHARE/common.subr || exit 1
34244675Sdteskef_dprintf "%s: loading includes..." usermgmt/group_input.subr
35240684Sdteskef_include $BSDCFG_SHARE/dialog.subr
36240684Sdteskef_include $BSDCFG_SHARE/strings.subr
37240684Sdteske
38240684SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
39238438Sdteskef_include_lang $BSDCFG_LIBE/include/messages.subr
40238438Sdteskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
41238438Sdteske
42238438Sdteske############################################################ FUNCTIONS
43238438Sdteske
44238438Sdteske# f_input_group $group
45238438Sdteske#
46238438Sdteske# Given $group name or id, create the environment variables group_name,
47238438Sdteske# group_gid, and group_members (and group_password is reset to NULL).
48238438Sdteske#
49238438Sdteskef_input_group()
50238438Sdteske{
51238438Sdteske	eval $( pw groupshow "$1" | awk -F: '
52238438Sdteske	{
53238438Sdteske		printf "group_name='\'%s\''\n", $1
54238438Sdteske		printf "group_password=\n"
55238438Sdteske		printf "group_gid='\'%s\''\n", $3
56238438Sdteske		printf "group_members='\'%s\''\n", $4
57238438Sdteske		exit
58238438Sdteske	}' )
59238438Sdteske}
60238438Sdteske
61249751Sdteske# f_dialog_menu_group_list [$default]
62238438Sdteske#
63249751Sdteske# Allows the user to select a group from a list. Optionally, if present and
64249751Sdteske# non-NULL, initially highlight $default group.
65238438Sdteske#
66238438Sdteskef_dialog_menu_group_list()
67238438Sdteske{
68251264Sdteske	local prompt=
69251264Sdteske	local menu_list="
70251264Sdteske		'X $msg_exit' ''
71251264Sdteske	" # END-QUOTE
72249751Sdteske	local defaultitem="$1"
73238438Sdteske	local hline="$hline_alnum_punc_tab_enter"
74238438Sdteske
75238438Sdteske	# Add groups from group(5)
76238438Sdteske	menu_list="$menu_list $( pw groupshow -a | awk -F: '
77238438Sdteske		!/^[[:space:]]*(#|$)/ {
78238438Sdteske			printf "'\'%s\'\ \'%s\''\n", $1, $1
79238438Sdteske		}'
80238438Sdteske	)"
81238438Sdteske
82251190Sdteske	local height width rows
83251190Sdteske	eval f_dialog_menu_size height width rows \
84251190Sdteske	                        \"\$DIALOG_TITLE\"     \
85251190Sdteske	                        \"\$DIALOG_BACKTITLE\" \
86251264Sdteske	                        \"\$prompt\"           \
87251190Sdteske	                        \"\$hline\"            \
88251190Sdteske	                        $menu_list
89238438Sdteske
90251236Sdteske	local menu_choice
91251236Sdteske	menu_choice=$( eval $DIALOG \
92249751Sdteske		--title \"\$DIALOG_TITLE\"         \
93238438Sdteske		--backtitle \"\$DIALOG_BACKTITLE\" \
94238438Sdteske		--hline \"\$hline\"                \
95238438Sdteske		--ok-label \"\$msg_ok\"            \
96238438Sdteske		--cancel-label \"\$msg_cancel\"    \
97249751Sdteske		--default-item \"\$defaultitem\"   \
98251264Sdteske		--menu \"\$prompt\"                \
99251190Sdteske		$height $width $rows               \
100251190Sdteske		$menu_list                         \
101240768Sdteske		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
102240768Sdteske	)
103240768Sdteske	local retval=$?
104251236Sdteske	f_dialog_menutag_store -s "$menu_choice"
105240768Sdteske	return $retval
106238438Sdteske}
107238438Sdteske
108238438Sdteske# f_dialog_input_group_name [$group_name]
109238438Sdteske#
110238438Sdteske# Allows the user to enter a new groupname for a given group. If the user does
111238438Sdteske# not cancel or press ESC, the $group_name variable will hold the
112238438Sdteske# newly-configured value upon return.
113238438Sdteske#
114238438Sdteske# If $cur_group_name is defined, the user can enter that and by-pass error-
115238438Sdteske# checking (allowing the user to "revert" to an old value without, for example,
116238438Sdteske# being told that the groupname already exists).
117238438Sdteske#
118238438Sdteskef_dialog_input_group_name()
119238438Sdteske{
120238438Sdteske	#
121238438Sdteske	# Loop until the user provides taint-free/valid input
122238438Sdteske	#
123244548Sdteske	local _name="$1" _input="$1"
124238438Sdteske	while :; do
125238438Sdteske
126238438Sdteske		# Return if user has either pressed ESC or chosen Cancel/No
127251242Sdteske		f_dialog_input _input "$msg_group" "$_input" \
128256181Sdteske		               "$hline_alnum_tab_enter" || return $?
129238438Sdteske
130238438Sdteske		# Check for no-change
131256181Sdteske		[ "$_input" = "$_name" ] && return $DIALOG_OK
132238438Sdteske
133238438Sdteske		# Check for reversion
134238438Sdteske		if [ "$_input" = "$cur_group_name" ]; then
135238438Sdteske			group_name="$cur_group_name"
136256181Sdteske			return $DIALOG_OK
137238438Sdteske		fi
138238438Sdteske
139238438Sdteske		# Check for NULL entry
140238438Sdteske		if [ ! "$_input" ]; then
141252795Sdteske			f_show_msg "$msg_group_is_empty"
142238438Sdteske			continue
143238438Sdteske		fi
144238438Sdteske
145238438Sdteske		# Check for invalid entry
146238438Sdteske		if ! echo "$_input" | grep -q "^[[:alpha:]]"; then
147252795Sdteske			f_show_msg "$msg_group_must_start_with_letter"
148238438Sdteske			continue
149238438Sdteske		fi
150238438Sdteske
151238438Sdteske		# Check for duplicate entry
152238438Sdteske		if f_quietly pw groupshow -n "$_input"; then
153238438Sdteske			f_show_msg "$msg_group_already_used" "$_input"
154238438Sdteske			continue
155238438Sdteske		fi
156238438Sdteske
157238438Sdteske		group_name="$_input"
158238438Sdteske		break
159238438Sdteske	done
160238438Sdteske	save_flag=1
161238438Sdteske
162244550Sdteske	f_dprintf "group_name: [%s]->[%s]" "$cur_group_name" "$group_name"
163238438Sdteske
164256181Sdteske	return $DIALOG_OK
165238438Sdteske}
166238438Sdteske
167238438Sdteske# f_dialog_input_group_password
168238438Sdteske#
169238438Sdteske# Prompt the user to enter a password (twice).
170238438Sdteske#
171238438Sdteskef_dialog_input_group_password()
172238438Sdteske{
173251264Sdteske	local prompt1="$msg_group_password"
174251264Sdteske	local prompt2="$msg_reenter_group_password"
175238438Sdteske	local hline="$hline_alnum_punc_tab_enter"
176238438Sdteske
177251190Sdteske	local height1 width1
178251190Sdteske	f_dialog_inputbox_size height1 width1 \
179238438Sdteske	        	"$DIALOG_TITLE"     \
180238438Sdteske	        	"$DIALOG_BACKTITLE" \
181251264Sdteske	        	"$prompt1"          \
182238438Sdteske	        	""                  \
183251190Sdteske	        	"$hline"
184238438Sdteske
185251190Sdteske	local height2 width2
186251190Sdteske	f_dialog_inputbox_size height2 width2 \
187238438Sdteske	        	"$DIALOG_TITLE"     \
188238438Sdteske	        	"$DIALOG_BACKTITLE" \
189251264Sdteske	        	"$prompt2"          \
190238438Sdteske	        	""                  \
191251190Sdteske	        	"$hline"
192238438Sdteske
193238438Sdteske	#
194238438Sdteske	# Loop until the user provides taint-free/valid input
195238438Sdteske	#
196238438Sdteske	local retval _password1 _password2
197238438Sdteske	while :; do
198251242Sdteske		_password1=$( $DIALOG \
199251190Sdteske			--title "$DIALOG_TITLE"         \
200251190Sdteske			--backtitle "$DIALOG_BACKTITLE" \
201251190Sdteske			--hline "$hline"                \
202251190Sdteske			--ok-label "$msg_ok"            \
203251190Sdteske			--cancel-label "$msg_cancel"    \
204251190Sdteske			--insecure                      \
205251264Sdteske			--passwordbox "$prompt1"        \
206251190Sdteske			$height1 $width1                \
207240768Sdteske			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
208240768Sdteske		)
209238438Sdteske		retval=$?
210251242Sdteske		debug= f_dialog_line_sanitize _password1
211238438Sdteske
212238438Sdteske		# Return if user has either pressed ESC or chosen Cancel/No
213256181Sdteske		[ $retval -eq $DIALOG_OK ] || return $retval
214238438Sdteske
215251242Sdteske		_password2=$( $DIALOG \
216251190Sdteske			--title "$DIALOG_TITLE"         \
217251190Sdteske			--backtitle "$DIALOG_BACKTITLE" \
218251190Sdteske			--hline "$hline"                \
219251190Sdteske			--ok-label "$msg_ok"            \
220251190Sdteske			--cancel-label "$msg_cancel"    \
221251190Sdteske			--insecure                      \
222251264Sdteske			--passwordbox "$prompt2"        \
223251190Sdteske			$height2 $width2                \
224240768Sdteske			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
225240768Sdteske		)
226238438Sdteske		retval=$?
227251242Sdteske		debug= f_dialog_line_sanitize _password2
228238438Sdteske
229238438Sdteske		# Return if user has either pressed ESC or chosen Cancel/No
230256181Sdteske		[ $retval -eq $DIALOG_OK ] || return $retval
231238438Sdteske
232238438Sdteske		# Check for password mismatch
233238438Sdteske		if [ "$_password1" != "$_password2" ]; then
234252795Sdteske			f_show_msg "$msg_group_passwords_do_not_match"
235238438Sdteske			continue
236238438Sdteske		fi
237238438Sdteske
238238438Sdteske		# Check for NULL entry
239238438Sdteske		if [ ! "$_password1" ]; then
240251544Sdteske			f_dialog_yesno "$msg_disable_password_auth_for_group"
241251544Sdteske			local retval=$?
242256181Sdteske			if [ $retval -eq $DIALOG_ESC ]; then
243251547Sdteske				return $retval
244256181Sdteske			elif [ $retval -eq $DIALOG_OK ]; then
245251547Sdteske				pw_group_password_disable=1
246251547Sdteske			else
247251547Sdteske				continue # back to password prompt
248251547Sdteske			fi
249238438Sdteske		else
250238438Sdteske			pw_group_password_disable=
251238438Sdteske		fi
252238438Sdteske
253238438Sdteske		group_password="$_password1"
254238438Sdteske		break
255238438Sdteske	done
256238438Sdteske	save_flag=1
257238438Sdteske
258244550Sdteske	f_dprintf "group_password: [%s]->[%s]" \
259244550Sdteske	          "$cur_group_password" "$group_password"
260238438Sdteske
261256181Sdteske	return $DIALOG_OK
262238438Sdteske}
263238438Sdteske
264238438Sdteske# f_dialog_input_group_gid [$group_gid]
265238438Sdteske#
266238438Sdteske# Allow the user to enter a new GID for a given group. If the user does not
267238438Sdteske# cancel or press ESC, the $group_gid variable will hold the newly-configured
268238438Sdteske# value upon return.
269238438Sdteske#
270238438Sdteskef_dialog_input_group_gid()
271238438Sdteske{
272244548Sdteske	local _input="$1"
273238438Sdteske
274238438Sdteske	# Return if user has either pressed ESC or chosen Cancel/No
275251242Sdteske	f_dialog_input _input "$msg_group_id_leave_empty_for_default" \
276256181Sdteske	               "$_input" "$hline_num_tab_enter" || return $?
277238438Sdteske
278238438Sdteske	group_gid="$_input"
279238438Sdteske	save_flag=1
280238438Sdteske
281244550Sdteske	f_dprintf "group_gid: [%s]->[%s]" "$cur_group_gid" "$group_gid"
282238438Sdteske
283256181Sdteske	return $DIALOG_OK
284238438Sdteske}
285238438Sdteske
286238438Sdteske# f_dialog_input_group_members [$group_members]
287238438Sdteske#
288251266Sdteske# Allow the user to modify a list of members for a given group. If the user
289251266Sdteske# does not cancel or press ESC, the $group_members variable will hold the
290251266Sdteske# newly-configured value upon return.
291238438Sdteske#
292238438Sdteskef_dialog_input_group_members()
293238438Sdteske{
294251264Sdteske	local _input="$1"
295251264Sdteske	local prompt="$msg_group_members:"
296251264Sdteske	local menu_list="
297238438Sdteske		'X' '$msg_continue'
298238438Sdteske		'1' '$msg_select_group_members_from_list'
299238438Sdteske		'2' '$msg_enter_group_members_manually'
300238438Sdteske	" # END-QUOTE
301251264Sdteske	local defaultitem=
302251264Sdteske	local hline="$hline_num_arrows_tab_enter"
303238438Sdteske
304251190Sdteske	local mheight mwidth mrows
305251190Sdteske	eval f_dialog_menu_size mheight mwidth mrows \
306251190Sdteske	                        \"\$DIALOG_TITLE\"     \
307251190Sdteske	                        \"\$DIALOG_BACKTITLE\" \
308251264Sdteske	                        \"\$prompt\"           \
309251190Sdteske	                        \"\$hline\"            \
310251190Sdteske	                        $menu_list
311251190Sdteske
312251264Sdteske	local menu_choice retval
313238438Sdteske	while :; do
314251236Sdteske		menu_choice=$( eval $DIALOG \
315238438Sdteske			--title \"\$DIALOG_TITLE\"         \
316238438Sdteske			--backtitle \"\$DIALOG_BACKTITLE\" \
317238438Sdteske			--hline \"\$hline\"                \
318238438Sdteske			--ok-label \"\$msg_ok\"            \
319238438Sdteske			--cancel-label \"\$msg_cancel\"    \
320249751Sdteske			--default-item \"\$defaultitem\"   \
321251264Sdteske			--menu \"\$prompt\"                \
322251190Sdteske			$mheight $mwidth $mrows            \
323238438Sdteske			$menu_list                         \
324240768Sdteske			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
325240768Sdteske		)
326238438Sdteske		retval=$?
327251236Sdteske		f_dialog_data_sanitize menu_choice
328251236Sdteske		defaultitem="$menu_choice"
329244550Sdteske		f_dprintf "retval=%u menu_choice=[%s]" $retval "$menu_choice"
330238438Sdteske
331238438Sdteske		# Return if user has either pressed ESC or chosen Cancel/No
332256181Sdteske		[ $retval -eq $DIALOG_OK ] || return $retval
333238438Sdteske
334251264Sdteske		local _group_members
335238438Sdteske		case "$menu_choice" in
336238438Sdteske		X) # Exit
337238438Sdteske			break ;;
338238438Sdteske		1) # Select Group Members from a list
339251264Sdteske			local user check_list=
340251264Sdteske			for user in $( pw usershow -a |
341251264Sdteske				awk -F: '!/^[[:space:]]*(#|$)/{print $1}'
342251264Sdteske			); do
343251264Sdteske				# Format of a checklist entry: tag item status
344238438Sdteske				if echo "$_input" | grep -q "\<$user\>"; then
345251264Sdteske					check_list="$check_list $user '' on"
346238438Sdteske				else
347251264Sdteske					check_list="$check_list $user '' off"
348238438Sdteske				fi
349238438Sdteske			done
350238438Sdteske
351251190Sdteske			local cheight cwidth crows
352251190Sdteske			eval f_dialog_checklist_size cheight cwidth crows \
353251190Sdteske			                             \"\$DIALOG_TITLE\"     \
354251190Sdteske			                             \"\$DIALOG_BACKTITLE\" \
355251264Sdteske			                             \"\$prompt\"           \
356251190Sdteske			                             \"\$hline\"            \
357251264Sdteske			                             $check_list
358251236Sdteske			_group_members=$( eval $DIALOG \
359238438Sdteske				--title \"\$DIALOG_TITLE\"         \
360238438Sdteske				--backtitle \"\$DIALOG_BACKTITLE\" \
361238438Sdteske				--separate-output                  \
362238438Sdteske				--hline \"\$hline\"                \
363238438Sdteske				--ok-label \"\$msg_ok\"            \
364238438Sdteske				--cancel-label \"\$msg_cancel\"    \
365251264Sdteske				--checklist \"\$prompt\"           \
366251190Sdteske				$cheight $cwidth $crows            \
367251264Sdteske				$check_list                        \
368240768Sdteske				2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
369251236Sdteske			) || continue
370251236Sdteske				# Return to previous menu if user either
371251236Sdteske				# pressed ESC or chose Cancel/No
372251236Sdteske			f_dialog_data_sanitize _group_members
373251236Sdteske
374260678Sdteske			#
375251236Sdteske			# Convert the newline separated list into a comma-
376251236Sdteske			# separated one so that if the user switches over to
377251236Sdteske			# manual editing, list reflects checklist selections
378260678Sdteske			#
379260678Sdteske			f_replaceall "$_group_members" "[$IFS]" "," _input
380238438Sdteske			;;
381238438Sdteske		2) # Enter Group Members manually
382251264Sdteske			local p="$msg_group_members ($msg_separated_by_commas)"
383238438Sdteske
384251264Sdteske			f_dialog_input _group_members "$p" "$_input" \
385251242Sdteske			               "$hline_num_tab_enter" || continue
386251242Sdteske				# Return to previous menu if user either
387251242Sdteske				# pressed ESC or chose Cancel/No
388238438Sdteske
389238438Sdteske			_input="$_group_members"
390238438Sdteske			;;
391238438Sdteske		esac
392238438Sdteske	done
393238438Sdteske
394238438Sdteske	group_members="$_input"
395238438Sdteske	save_flag=1
396244550Sdteske	f_dprintf "group_members: [%s]->[%s]" \
397244550Sdteske	          "$cur_group_members" "$group_members"
398238438Sdteske
399256181Sdteske	return $DIALOG_OK
400238438Sdteske}
401238438Sdteske
402244675Sdteske############################################################ MAIN
403244675Sdteske
404244675Sdteskef_dprintf "%s: Successfully loaded." usermgmt/group_input.subr
405244675Sdteske
406238438Sdteskefi # ! $_USERMGMT_GROUP_INPUT_SUBR
407