1262904Sdteskeif [ ! "$_USERMGMT_GROUP_SUBR" ]; then _USERMGMT_GROUP_SUBR=1
2262904Sdteske#
3262904Sdteske# Copyright (c) 2012 Ron McDowell
4262904Sdteske# Copyright (c) 2012-2014 Devin Teske
5262904Sdteske# All rights reserved.
6262904Sdteske#
7262904Sdteske# Redistribution and use in source and binary forms, with or without
8262904Sdteske# modification, are permitted provided that the following conditions
9262904Sdteske# are met:
10262904Sdteske# 1. Redistributions of source code must retain the above copyright
11262904Sdteske#    notice, this list of conditions and the following disclaimer.
12262904Sdteske# 2. Redistributions in binary form must reproduce the above copyright
13262904Sdteske#    notice, this list of conditions and the following disclaimer in the
14262904Sdteske#    documentation and/or other materials provided with the distribution.
15262904Sdteske#
16262904Sdteske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17262904Sdteske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18262904Sdteske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19262904Sdteske# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20262904Sdteske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21262904Sdteske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22262904Sdteske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23262904Sdteske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24262904Sdteske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25262904Sdteske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26262904Sdteske# SUCH DAMAGE.
27262904Sdteske#
28262904Sdteske# $FreeBSD$
29262904Sdteske#
30262904Sdteske############################################################ INCLUDES
31262904Sdteske
32262904SdteskeBSDCFG_SHARE="/usr/share/bsdconfig"
33262904Sdteske. $BSDCFG_SHARE/common.subr || exit 1
34262904Sdteskef_dprintf "%s: loading includes..." usermgmt/group.subr
35262904Sdteskef_include $BSDCFG_SHARE/dialog.subr
36262904Sdteskef_include $BSDCFG_SHARE/usermgmt/group_input.subr
37262904Sdteske
38262904SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
39262904Sdteskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
40262904Sdteske
41262904Sdteske############################################################ CONFIGURATION
42262904Sdteske
43262904Sdteske# set some reasonable defaults if /etc/adduser.conf does not exist.
44262904Sdteske[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf
45262904Sdteske: ${passwdtype:="yes"}
46262904Sdteske
47262904Sdteske############################################################ FUNCTIONS
48262904Sdteske
49262904Sdteske# f_group_add [$group]
50262904Sdteske#
51262904Sdteske# Add a group. If both $group (as a first argument) and $VAR_GROUP are unset
52262904Sdteske# or NULL and we are running interactively, prompt the user to enter the name
53262904Sdteske# of a new group and (if $VAR_NO_CONFIRM is unset or NULL) prompt the user to
54262904Sdteske# answer some questions about the new group. Variables that can be used to
55262904Sdteske# script user input:
56262904Sdteske#
57262904Sdteske# 	VAR_GROUP [Optional if running interactively]
58262904Sdteske# 		The group to add. Ignored if given non-NULL first-argument.
59262904Sdteske#	VAR_GROUP_GID [Optional]
60262904Sdteske# 		Numerical group ID to use. If NULL or unset, the group ID is
61262904Sdteske# 		automatically chosen.
62262904Sdteske# 	VAR_GROUP_MEMBERS [Optional]
63262904Sdteske# 		Comma separated list of users that are a member of this group.
64262904Sdteske# 	VAR_GROUP_PASSWORD [Optional]
65262904Sdteske# 		newgrp(1) password to set for the group. Default if NULL or
66262904Sdteske# 		unset is to disable newgrp(1) password authentication.
67262904Sdteske#
68262904Sdteske# Returns success if the group was successfully added.
69262904Sdteske#
70262904Sdteskef_group_add()
71262904Sdteske{
72262904Sdteske	local funcname=f_group_add
73262904Sdteske	local title # Calculated below
74262904Sdteske	local alert=f_show_msg no_confirm=
75262904Sdteske
76262904Sdteske	f_getvar $VAR_NO_CONFIRM no_confirm
77262904Sdteske	[ "$no_confirm" ] && alert=f_show_info
78262904Sdteske
79262904Sdteske	local input
80262904Sdteske	f_getvar 3:-\$$VAR_GROUP input "$1"
81262904Sdteske
82262904Sdteske	#
83262904Sdteske	# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
84262904Sdteske	# instead of name. Work-around is to also pass `-g GID' at the same
85262904Sdteske	# time (any GID will do; but `-1' is appropriate for this context).
86262904Sdteske	#
87262904Sdteske	if [ "$input" ] && f_quietly pw groupshow -n "$input" -g -1; then
88262904Sdteske		f_show_err "$msg_group_already_used" "$input"
89262904Sdteske		return $FAILURE
90262904Sdteske	fi
91262904Sdteske
92262904Sdteske	local group_name="$input"
93262904Sdteske	while f_interactive && [ ! "$group_name" ]; do
94262904Sdteske		f_dialog_input_group_name group_name "$group_name" ||
95262904Sdteske			return $SUCCESS
96262904Sdteske		[ "$group_name" ] ||
97262904Sdteske			f_show_err "$msg_please_enter_a_group_name"
98262904Sdteske	done
99263980Sdteske	if [ ! "$group_name" ]; then
100263980Sdteske		f_show_err "$msg_no_group_specified"
101263980Sdteske		return $FAILURE
102263980Sdteske	fi
103262904Sdteske
104262904Sdteske	local group_password group_gid group_members
105262904Sdteske	f_getvar $VAR_GROUP_PASSWORD	group_password
106262904Sdteske	f_getvar $VAR_GROUP_GID		group_gid
107262904Sdteske	f_getvar $VAR_GROUP_MEMBERS	group_members
108262904Sdteske
109262904Sdteske	local group_password_disable=
110262904Sdteske	f_interactive || [ "$group_password" ] || group_password_disable=1
111262904Sdteske
112262904Sdteske	if f_interactive && [ ! "$no_confirm" ]; then
113262904Sdteske		f_dialog_noyes \
114262904Sdteske			"$msg_use_default_values_for_all_account_details"
115262904Sdteske		retval=$?
116262904Sdteske		if [ $retval -eq $DIALOG_ESC ]; then
117262904Sdteske			return $SUCCESS
118262904Sdteske		elif [ $retval -ne $DIALOG_OK ]; then
119262904Sdteske			#
120262904Sdteske			# Ask series of questions to pre-fill the editor screen
121262904Sdteske			#
122262904Sdteske			# Defaults used in each dialog should allow the user to
123262904Sdteske			# simply hit ENTER to proceed and cancelling a single
124262904Sdteske			# dialog cause them to return to the previous menu.
125262904Sdteske			#
126262904Sdteske	
127262904Sdteske			if [ "$passwdtype" = "yes" ]; then
128262904Sdteske				f_dialog_input_group_password group_password \
129262904Sdteske					group_password_disable ||
130262904Sdteske					return $FAILURE
131262904Sdteske			fi
132262904Sdteske			f_dialog_input_group_gid group_gid "$group_gid" ||
133262904Sdteske				return $FAILURE
134262904Sdteske			f_dialog_input_group_members group_members \
135262904Sdteske				"$group_members" || return $FAILURE
136262904Sdteske		fi
137262904Sdteske	fi
138262904Sdteske
139262904Sdteske	#
140262904Sdteske	# Loop until the user decides to Exit, Cancel, or presses ESC
141262904Sdteske	#
142262904Sdteske	title="$msg_add $msg_group: $group_name"
143262904Sdteske	if f_interactive; then
144262904Sdteske		local mtag retval defaultitem=
145262904Sdteske		while :; do
146262904Sdteske			f_dialog_title "$title"
147262904Sdteske			f_dialog_menu_group_add "$defaultitem"
148262904Sdteske			retval=$?
149262904Sdteske			f_dialog_title_restore
150262904Sdteske			f_dialog_menutag_fetch mtag
151262904Sdteske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
152262904Sdteske			defaultitem="$mtag"
153262904Sdteske
154262904Sdteske			# Return if user either pressed ESC or chose Cancel/No
155262904Sdteske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
156262904Sdteske
157262904Sdteske			case "$mtag" in
158262904Sdteske			X) # Add/Exit
159263980Sdteske			   local var
160263980Sdteske			   for var in gid members name; do
161263980Sdteske			   	local _group_$var
162263980Sdteske			   	eval f_shell_escape \
163263980Sdteske			   		\"\$group_$var\" _group_$var
164263980Sdteske			   done
165263980Sdteske
166263980Sdteske			   local cmd="pw groupadd -n '$_group_name'"
167263980Sdteske			   [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
168262904Sdteske			   [ "$group_members" ] &&
169263980Sdteske			   	cmd="$cmd -M '$_group_members'"
170262904Sdteske
171262904Sdteske			   # Execute the command (break on success)
172262904Sdteske			   if [ "$group_password_disable" ]; then
173262904Sdteske			   	f_eval_catch $funcname pw '%s -h -' "$cmd"
174262904Sdteske			   elif [ "$group_password" ]; then
175262904Sdteske			   	echo "$group_password" |
176262904Sdteske			   		f_eval_catch $funcname \
177263980Sdteske			   			pw '%s -h 0' "$cmd"
178262904Sdteske			   else
179262904Sdteske			   	f_eval_catch $funcname pw '%s' "$cmd"
180262904Sdteske			   fi && break
181262904Sdteske			   ;;
182262904Sdteske			1) # Group Name (prompt for new group name)
183262904Sdteske			   f_dialog_input_group_name input "$group_name" ||
184262904Sdteske			   	continue
185262904Sdteske			   if f_quietly pw groupshow -n "$input" -g -1; then
186262904Sdteske			   	f_show_err "$msg_group_already_used" "$input"
187262904Sdteske			   	continue
188262904Sdteske			   fi
189262904Sdteske			   group_name="$input"
190262904Sdteske			   title="$msg_add $msg_group: $group_name"
191262904Sdteske			   ;;
192262904Sdteske			2) # Password
193262904Sdteske			   f_dialog_input_group_password group_password \
194262904Sdteske			   	group_password_disable
195262904Sdteske			   ;;
196262904Sdteske			3) # Group ID
197262904Sdteske			   f_dialog_input_group_gid group_gid "$group_gid"
198262904Sdteske			   ;;
199262904Sdteske			4) # Group Members
200262904Sdteske			   f_dialog_input_group_members group_members \
201262904Sdteske					"$group_members"
202262904Sdteske			   ;;
203262904Sdteske			esac
204262904Sdteske		done
205262904Sdteske	else
206263980Sdteske		local var
207263980Sdteske		for var in gid members name; do
208263980Sdteske			local _group_$var
209263980Sdteske			eval f_shell_escape \"\$group_$var\" _group_$var
210263980Sdteske		done
211263980Sdteske
212262904Sdteske		# Form the command
213263980Sdteske		local cmd="pw groupadd -n '$_group_name'"
214263980Sdteske		[ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
215263980Sdteske		[ "$group_members" ] && cmd="$cmd -M '$_group_members'"
216262904Sdteske
217262904Sdteske		# Execute the command
218262904Sdteske		local retval err
219262904Sdteske		if [ "$group_password_disable" ]; then
220262904Sdteske			f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
221262904Sdteske		elif [ "$group_password" ]; then
222263980Sdteske			err=$( echo "$group_password" | f_eval_catch -de \
223263980Sdteske				$funcname pw '%s -h 0' "$cmd" 2>&1 )
224262904Sdteske		else
225262904Sdteske			f_eval_catch -k err $funcname pw '%s' "$cmd"
226262904Sdteske		fi
227262904Sdteske		retval=$?
228262904Sdteske		if [ $retval -ne $SUCCESS ]; then
229262904Sdteske			f_show_err "%s" "$err"
230262904Sdteske			return $retval
231262904Sdteske		fi
232262904Sdteske	fi
233262904Sdteske
234262904Sdteske	f_dialog_title "$title"
235262904Sdteske	$alert "$msg_group_added"
236262904Sdteske	f_dialog_title_restore
237263980Sdteske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
238262904Sdteske
239262904Sdteske	return $SUCCESS
240262904Sdteske}
241262904Sdteske
242262904Sdteske# f_group_delete [$group]
243262904Sdteske#
244262904Sdteske# Delete a group. If both $group (as a first argument) and $VAR_GROUP are unset
245262904Sdteske# or NULL and we are running interactively, prompt the user to select a group
246262904Sdteske# from a list of available groups. Variables that can be used to script user
247262904Sdteske# input:
248262904Sdteske#
249262904Sdteske# 	VAR_GROUP [Optional if running interactively]
250262904Sdteske# 		The group to delete. Ignored if given non-NULL first-argument.
251262904Sdteske#
252262904Sdteske# Returns success if the group was successfully deleted.
253262904Sdteske#
254262904Sdteskef_group_delete()
255262904Sdteske{
256262904Sdteske	local funcname=f_group_delete
257262904Sdteske	local title # Calculated below
258262904Sdteske	local alert=f_show_msg no_confirm=
259262904Sdteske
260262904Sdteske	f_getvar $VAR_NO_CONFIRM no_confirm
261262904Sdteske	[ "$no_confirm" ] && alert=f_show_info
262262904Sdteske
263262904Sdteske	local input
264262904Sdteske	f_getvar 3:-\$$VAR_GROUP input "$1"
265262904Sdteske
266262904Sdteske	local group_name group_password group_gid group_members
267262904Sdteske	if [ "$input" ] && ! f_input_group "$input"; then
268262904Sdteske		f_show_err "$msg_group_not_found" "$input"
269262904Sdteske		return $FAILURE
270262904Sdteske	fi
271262904Sdteske
272262904Sdteske	#
273262904Sdteske	# Loop until the user decides to Exit, Cancel, or presses ESC
274262904Sdteske	#
275262904Sdteske	title="$msg_delete $msg_group: $group_name"
276262904Sdteske	if f_interactive; then
277262904Sdteske		local mtag retval defaultitem=
278262904Sdteske		while :; do
279262904Sdteske        		f_dialog_title "$title"
280262904Sdteske			f_dialog_menu_group_delete "$group_name" "$defaultitem"
281262904Sdteske			retval=$?
282262904Sdteske			f_dialog_title_restore
283262904Sdteske			f_dialog_menutag_fetch mtag
284262904Sdteske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
285262904Sdteske			defaultitem="$mtag"
286262904Sdteske
287262904Sdteske			# Return if user either pressed ESC or chose Cancel/No
288262904Sdteske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
289262904Sdteske
290262904Sdteske			case "$mtag" in
291262904Sdteske			X) # Delete/Exit
292263980Sdteske			   local _group_name
293263980Sdteske			   f_shell_escape "$group_name" _group_name
294262904Sdteske			   f_eval_catch $funcname pw 'pw groupdel "%s"' \
295263980Sdteske					"$_group_name" && break
296262904Sdteske			   ;;
297262904Sdteske			1) # Group Name (select different group from list)
298262904Sdteske			   f_dialog_menu_group_list "$group_name" || continue
299262904Sdteske			   f_dialog_menutag_fetch mtag
300262904Sdteske
301262904Sdteske			   [ "$mtag" = "X $msg_exit" ] && continue
302262904Sdteske
303262904Sdteske			   if ! f_input_group "$mtag"; then
304262904Sdteske				f_show_err "$msg_group_not_found" "$mtag"
305262904Sdteske				# Attempt to fall back to previous selection
306262904Sdteske				f_input_group "$input" || return $FAILURE
307262904Sdteske			   else
308262904Sdteske				input="$mtag"
309262904Sdteske			   fi
310262904Sdteske			   ;;
311262904Sdteske			esac
312262904Sdteske		done
313262904Sdteske	else
314263980Sdteske		local retval err _group_name
315263980Sdteske		f_shell_escape "$group_name" _group_name
316262904Sdteske		f_eval_catch -k err $funcname pw \
317263980Sdteske			"pw groupdel '%s'" "$_group_name"
318262904Sdteske		retval=$?
319262904Sdteske		if [ $retval -ne $SUCCESS ]; then
320262904Sdteske			f_show_err "%s" "$err"
321262904Sdteske			return $retval
322262904Sdteske		fi
323262904Sdteske	fi
324262904Sdteske
325262904Sdteske        f_dialog_title "$title"
326262904Sdteske	$alert "$msg_group_deleted"
327262904Sdteske	f_dialog_title_restore
328263980Sdteske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
329262904Sdteske
330262904Sdteske	return $SUCCESS
331262904Sdteske}
332262904Sdteske
333262904Sdteske# f_group_edit [$group]
334262904Sdteske#
335262904Sdteske# Modify a group. If both $group (as a first argument) and $VAR_GROUP are unset
336262904Sdteske# or NULL and we are running interactively, prompt the user to select a group
337262904Sdteske# from a list of available groups. Variables that can be used to script user
338262904Sdteske# input:
339262904Sdteske#
340262904Sdteske# 	VAR_GROUP [Optional if running interactively]
341262904Sdteske# 		The group to modify. Ignored if given non-NULL first-argument.
342262904Sdteske#	VAR_GROUP_GID [Optional]
343262904Sdteske# 		Numerical group ID to set. If NULL or unset, the group ID is
344262904Sdteske# 		unchanged.
345262904Sdteske# 	VAR_GROUP_MEMBERS [Optional]
346262904Sdteske# 		Comma separated list of users that are a member of this group.
347263980Sdteske# 		If set but NULL, group memberships are reset (no users will be
348263980Sdteske# 		a member of this group). If unset, group membership is
349263980Sdteske# 		unmodified.
350262904Sdteske# 	VAR_GROUP_PASSWORD [Optional]
351262904Sdteske# 		newgrp(1) password to set for the group. If unset, the password
352262904Sdteske# 		is unmodified. If NULL, the newgrp(1) password is disabled.
353262904Sdteske#
354262904Sdteske# Returns success if the group was successfully modified.
355262904Sdteske#
356262904Sdteskef_group_edit()
357262904Sdteske{
358262904Sdteske	local funcname=f_group_edit
359262904Sdteske	local title # Calculated below
360262904Sdteske	local alert=f_show_msg no_confirm=
361262904Sdteske
362262904Sdteske	f_getvar $VAR_NO_CONFIRM no_confirm
363262904Sdteske	[ "$no_confirm" ] && alert=f_show_info
364262904Sdteske
365262904Sdteske	local input
366262904Sdteske	f_getvar 3:-\$$VAR_GROUP input "$1"
367262904Sdteske
368262904Sdteske	#
369262904Sdteske	# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
370262904Sdteske	# instead of name. Work-around is to also pass `-g GID' at the same
371262904Sdteske	# time (any GID will do; but `-1' is appropriate for this context).
372262904Sdteske	#
373262904Sdteske	if [ "$input" ] && ! f_quietly pw groupshow -n "$input" -g -1; then
374262904Sdteske		f_show_err "$msg_group_not_found" "$input"
375262904Sdteske		return $FAILURE
376262904Sdteske	fi
377262904Sdteske
378262904Sdteske	if f_interactive && [ ! "$input" ]; then
379262904Sdteske		f_dialog_menu_group_list || return $SUCCESS
380262904Sdteske		f_dialog_menutag_fetch input
381262904Sdteske		[ "$input" = "X $msg_exit" ] && return $SUCCESS
382262904Sdteske	elif [ ! "$input" ]; then
383262904Sdteske		f_show_err "$msg_no_group_specified"
384262904Sdteske		return $FAILURE
385262904Sdteske	fi
386262904Sdteske
387262904Sdteske	local group_name group_password group_gid group_members
388262904Sdteske	if ! f_input_group "$input"; then
389262904Sdteske		f_show_err "$msg_group_not_found" "$input"
390262904Sdteske		return $FAILURE
391262904Sdteske	fi
392262904Sdteske
393262904Sdteske	f_isset $VAR_GROUP_GID && f_getvar $VAR_GROUP_GID group_gid
394262904Sdteske	local null_members=
395262904Sdteske	if f_isset $VAR_GROUP_MEMBERS; then
396262904Sdteske		f_getvar $VAR_GROUP_MEMBERS group_members
397262904Sdteske		[ "$group_members" ] || null_members=1
398262904Sdteske	fi
399262904Sdteske	local group_password_disable=
400262904Sdteske	if f_isset $VAR_GROUP_PASSWORD; then
401262904Sdteske		f_getvar $VAR_GROUP_PASSWORD group_password
402262904Sdteske		[ "$group_password" ] || group_password_disable=1
403262904Sdteske	fi
404262904Sdteske
405262904Sdteske	#
406262904Sdteske	# Loop until the user decides to Exit, Cancel, or presses ESC
407262904Sdteske	#
408262904Sdteske	title="$msg_edit_view $msg_group: $group_name"
409262904Sdteske	if f_interactive; then
410262904Sdteske		local mtag retval defaultitem=
411262904Sdteske		while :; do
412262904Sdteske			f_dialog_title "$title"
413262904Sdteske			f_dialog_menu_group_edit "$defaultitem"
414262904Sdteske			retval=$?
415262904Sdteske			f_dialog_title_restore
416262904Sdteske			f_dialog_menutag_fetch mtag
417262904Sdteske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
418262904Sdteske			defaultitem="$mtag"
419262904Sdteske
420262904Sdteske			# Return if user either pressed ESC or chose Cancel/No
421262904Sdteske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
422262904Sdteske
423262904Sdteske			case "$mtag" in
424262904Sdteske			X) # Save/Exit
425263980Sdteske			   local var
426263980Sdteske			   for var in gid members name; do
427263980Sdteske			   	local _group_$var
428263980Sdteske			   	eval f_shell_escape \
429263980Sdteske			   		\"\$group_$var\" _group_$var
430263980Sdteske			   done
431263980Sdteske
432263980Sdteske			   local cmd="pw groupmod -n '$_group_name'"
433263980Sdteske			   [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
434262904Sdteske			   [ "$group_members" -o "$null_members" ] &&
435263980Sdteske			   	cmd="$cmd -M '$_group_members'"
436262904Sdteske
437262904Sdteske			   # Execute the command (break on success)
438262904Sdteske			   if [ "$group_password_disable" ]; then
439262904Sdteske			   	f_eval_catch $funcname pw '%s -h -' "$cmd"
440262904Sdteske			   elif [ "$group_password" ]; then
441263980Sdteske			   	echo "$group_password" | f_eval_catch \
442263980Sdteske			   		$funcname pw '%s -h 0' "$cmd"
443262904Sdteske			   else
444262904Sdteske			   	f_eval_catch $funcname pw '%s' "$cmd"
445262904Sdteske			   fi && break
446262904Sdteske			   ;;
447262904Sdteske			1) # Group Name (select different group from list)
448262904Sdteske			   f_dialog_menu_group_list "$group_name" || continue
449262904Sdteske			   f_dialog_menutag_fetch mtag
450262904Sdteske
451262904Sdteske			   [ "$mtag" = "X $msg_exit" ] && continue
452262904Sdteske
453262904Sdteske			   if ! f_input_group "$mtag"; then
454262904Sdteske			   	f_show_err "$msg_group_not_found" "$mtag"
455263980Sdteske			   	# Attempt to fall back to previous selection
456262904Sdteske			   	f_input_group "$input" || return $FAILURE
457262904Sdteske			   else
458262904Sdteske			   	input="$mtag"
459262904Sdteske			   fi
460262904Sdteske			   title="$msg_edit_view $msg_group: $group_name"
461262904Sdteske			   ;;
462262904Sdteske			2) # Password
463262904Sdteske			   f_dialog_input_group_password group_password \
464262904Sdteske			   	group_password_disable
465262904Sdteske			   ;;
466262904Sdteske			3) # Group ID
467262904Sdteske			   f_dialog_input_group_gid group_gid "$group_gid"
468262904Sdteske			   ;;
469262904Sdteske			4) # Group Members
470262904Sdteske			   f_dialog_input_group_members group_members \
471262904Sdteske			   	"$group_members" && [ ! "$group_members" ] &&
472262904Sdteske			   	null_members=1
473262904Sdteske			   ;;
474262904Sdteske			esac
475262904Sdteske		done
476262904Sdteske	else
477263980Sdteske		local var
478263980Sdteske		for var in gid members name; do
479263980Sdteske			local _group_$var
480263980Sdteske			eval f_shell_escape \"\$group_$var\" _group_$var
481263980Sdteske		done
482263980Sdteske
483262904Sdteske		# Form the command
484263980Sdteske		local cmd="pw groupmod -n '$_group_name'"
485263980Sdteske		[ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
486262904Sdteske		[ "$group_members" -o "$null_members" ] &&
487263980Sdteske			cmd="$cmd -M '$_group_members'"
488262904Sdteske
489262904Sdteske		# Execute the command
490262904Sdteske		local retval err
491262904Sdteske		if [ "$group_password_disable" ]; then
492262904Sdteske			f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
493262904Sdteske		elif [ "$group_password" -o "$null_password" ]; then
494263980Sdteske			err=$( echo "$group_password" | f_eval_catch -de \
495263980Sdteske				$funcname pw '%s -h 0' "$cmd" 2>&1 )
496262904Sdteske		else
497262904Sdteske			f_eval_catch -k err $funcname pw '%s' "$cmd"
498262904Sdteske		fi
499262904Sdteske		retval=$?
500262904Sdteske		if [ $retval -ne $SUCCESS ]; then
501262904Sdteske			f_show_err "%s" "$err"
502262904Sdteske			return $retval
503262904Sdteske		fi
504262904Sdteske	fi
505262904Sdteske
506262904Sdteske	f_dialog_title "$title"
507262904Sdteske	$alert "$msg_group_updated"
508262904Sdteske	f_dialog_title_restore
509263980Sdteske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
510262904Sdteske
511262904Sdteske	return $SUCCESS
512262904Sdteske}
513262904Sdteske
514262904Sdteske############################################################ MAIN
515262904Sdteske
516262904Sdteskef_dprintf "%s: Successfully loaded." usermgmt/group.subr
517262904Sdteske
518262904Sdteskefi # ! $_USERMGMT_GROUP_SUBR
519