xref: /freebsd/usr.sbin/bsdconfig/usermgmt/share/group.subr (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
127c43fe1SDevin Teskeif [ ! "$_USERMGMT_GROUP_SUBR" ]; then _USERMGMT_GROUP_SUBR=1
227c43fe1SDevin Teske#
327c43fe1SDevin Teske# Copyright (c) 2012 Ron McDowell
427c43fe1SDevin Teske# Copyright (c) 2012-2014 Devin Teske
527c43fe1SDevin Teske# All rights reserved.
627c43fe1SDevin Teske#
727c43fe1SDevin Teske# Redistribution and use in source and binary forms, with or without
827c43fe1SDevin Teske# modification, are permitted provided that the following conditions
927c43fe1SDevin Teske# are met:
1027c43fe1SDevin Teske# 1. Redistributions of source code must retain the above copyright
1127c43fe1SDevin Teske#    notice, this list of conditions and the following disclaimer.
1227c43fe1SDevin Teske# 2. Redistributions in binary form must reproduce the above copyright
1327c43fe1SDevin Teske#    notice, this list of conditions and the following disclaimer in the
1427c43fe1SDevin Teske#    documentation and/or other materials provided with the distribution.
1527c43fe1SDevin Teske#
1627c43fe1SDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1727c43fe1SDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1827c43fe1SDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1927c43fe1SDevin Teske# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2027c43fe1SDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2127c43fe1SDevin Teske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2227c43fe1SDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2327c43fe1SDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2427c43fe1SDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2527c43fe1SDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2627c43fe1SDevin Teske# SUCH DAMAGE.
2727c43fe1SDevin Teske#
2827c43fe1SDevin Teske#
2927c43fe1SDevin Teske############################################################ INCLUDES
3027c43fe1SDevin Teske
3127c43fe1SDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig"
3227c43fe1SDevin Teske. $BSDCFG_SHARE/common.subr || exit 1
3327c43fe1SDevin Teskef_dprintf "%s: loading includes..." usermgmt/group.subr
3427c43fe1SDevin Teskef_include $BSDCFG_SHARE/dialog.subr
3527c43fe1SDevin Teskef_include $BSDCFG_SHARE/usermgmt/group_input.subr
3627c43fe1SDevin Teske
3727c43fe1SDevin TeskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
3827c43fe1SDevin Teskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
3927c43fe1SDevin Teske
4027c43fe1SDevin Teske############################################################ CONFIGURATION
4127c43fe1SDevin Teske
4227c43fe1SDevin Teske# set some reasonable defaults if /etc/adduser.conf does not exist.
4327c43fe1SDevin Teske[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf
4427c43fe1SDevin Teske: ${passwdtype:="yes"}
4527c43fe1SDevin Teske
4627c43fe1SDevin Teske############################################################ FUNCTIONS
4727c43fe1SDevin Teske
4827c43fe1SDevin Teske# f_group_add [$group]
4927c43fe1SDevin Teske#
5027c43fe1SDevin Teske# Add a group. If both $group (as a first argument) and $VAR_GROUP are unset
5127c43fe1SDevin Teske# or NULL and we are running interactively, prompt the user to enter the name
5227c43fe1SDevin Teske# of a new group and (if $VAR_NO_CONFIRM is unset or NULL) prompt the user to
5327c43fe1SDevin Teske# answer some questions about the new group. Variables that can be used to
5427c43fe1SDevin Teske# script user input:
5527c43fe1SDevin Teske#
5627c43fe1SDevin Teske# 	VAR_GROUP [Optional if running interactively]
5727c43fe1SDevin Teske# 		The group to add. Ignored if given non-NULL first-argument.
5827c43fe1SDevin Teske#	VAR_GROUP_GID [Optional]
5927c43fe1SDevin Teske# 		Numerical group ID to use. If NULL or unset, the group ID is
6027c43fe1SDevin Teske# 		automatically chosen.
6127c43fe1SDevin Teske# 	VAR_GROUP_MEMBERS [Optional]
6227c43fe1SDevin Teske# 		Comma separated list of users that are a member of this group.
6327c43fe1SDevin Teske# 	VAR_GROUP_PASSWORD [Optional]
6427c43fe1SDevin Teske# 		newgrp(1) password to set for the group. Default if NULL or
6527c43fe1SDevin Teske# 		unset is to disable newgrp(1) password authentication.
6627c43fe1SDevin Teske#
6727c43fe1SDevin Teske# Returns success if the group was successfully added.
6827c43fe1SDevin Teske#
6927c43fe1SDevin Teskef_group_add()
7027c43fe1SDevin Teske{
7127c43fe1SDevin Teske	local funcname=f_group_add
7227c43fe1SDevin Teske	local title # Calculated below
7327c43fe1SDevin Teske	local alert=f_show_msg no_confirm=
7427c43fe1SDevin Teske
7527c43fe1SDevin Teske	f_getvar $VAR_NO_CONFIRM no_confirm
7627c43fe1SDevin Teske	[ "$no_confirm" ] && alert=f_show_info
7727c43fe1SDevin Teske
7827c43fe1SDevin Teske	local input
7927c43fe1SDevin Teske	f_getvar 3:-\$$VAR_GROUP input "$1"
8027c43fe1SDevin Teske
8127c43fe1SDevin Teske	#
8227c43fe1SDevin Teske	# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
8327c43fe1SDevin Teske	# instead of name. Work-around is to also pass `-g GID' at the same
84*e8e8c939SDevin Teske	# time (the GID is ignored in this case, so any GID will do).
8527c43fe1SDevin Teske	#
86*e8e8c939SDevin Teske	if [ "$input" ] && f_quietly pw groupshow -n "$input" -g 1337; then
8727c43fe1SDevin Teske		f_show_err "$msg_group_already_used" "$input"
8827c43fe1SDevin Teske		return $FAILURE
8927c43fe1SDevin Teske	fi
9027c43fe1SDevin Teske
9127c43fe1SDevin Teske	local group_name="$input"
9227c43fe1SDevin Teske	while f_interactive && [ ! "$group_name" ]; do
9327c43fe1SDevin Teske		f_dialog_input_group_name group_name "$group_name" ||
9427c43fe1SDevin Teske			return $SUCCESS
9527c43fe1SDevin Teske		[ "$group_name" ] ||
9627c43fe1SDevin Teske			f_show_err "$msg_please_enter_a_group_name"
9727c43fe1SDevin Teske	done
98863bb164SDevin Teske	if [ ! "$group_name" ]; then
99863bb164SDevin Teske		f_show_err "$msg_no_group_specified"
100863bb164SDevin Teske		return $FAILURE
101863bb164SDevin Teske	fi
10227c43fe1SDevin Teske
10327c43fe1SDevin Teske	local group_password group_gid group_members
10427c43fe1SDevin Teske	f_getvar $VAR_GROUP_PASSWORD	group_password
10527c43fe1SDevin Teske	f_getvar $VAR_GROUP_GID		group_gid
10627c43fe1SDevin Teske	f_getvar $VAR_GROUP_MEMBERS	group_members
10727c43fe1SDevin Teske
10827c43fe1SDevin Teske	local group_password_disable=
10927c43fe1SDevin Teske	f_interactive || [ "$group_password" ] || group_password_disable=1
11027c43fe1SDevin Teske
11127c43fe1SDevin Teske	if f_interactive && [ ! "$no_confirm" ]; then
11227c43fe1SDevin Teske		f_dialog_noyes \
11327c43fe1SDevin Teske			"$msg_use_default_values_for_all_account_details"
11427c43fe1SDevin Teske		retval=$?
11527c43fe1SDevin Teske		if [ $retval -eq $DIALOG_ESC ]; then
11627c43fe1SDevin Teske			return $SUCCESS
11727c43fe1SDevin Teske		elif [ $retval -ne $DIALOG_OK ]; then
11827c43fe1SDevin Teske			#
11927c43fe1SDevin Teske			# Ask series of questions to pre-fill the editor screen
12027c43fe1SDevin Teske			#
12127c43fe1SDevin Teske			# Defaults used in each dialog should allow the user to
12227c43fe1SDevin Teske			# simply hit ENTER to proceed and cancelling a single
12327c43fe1SDevin Teske			# dialog cause them to return to the previous menu.
12427c43fe1SDevin Teske			#
12527c43fe1SDevin Teske
12627c43fe1SDevin Teske			if [ "$passwdtype" = "yes" ]; then
12727c43fe1SDevin Teske				f_dialog_input_group_password group_password \
12827c43fe1SDevin Teske					group_password_disable ||
12927c43fe1SDevin Teske					return $FAILURE
13027c43fe1SDevin Teske			fi
13127c43fe1SDevin Teske			f_dialog_input_group_gid group_gid "$group_gid" ||
13227c43fe1SDevin Teske				return $FAILURE
13327c43fe1SDevin Teske			f_dialog_input_group_members group_members \
13427c43fe1SDevin Teske				"$group_members" || return $FAILURE
13527c43fe1SDevin Teske		fi
13627c43fe1SDevin Teske	fi
13727c43fe1SDevin Teske
13827c43fe1SDevin Teske	#
13927c43fe1SDevin Teske	# Loop until the user decides to Exit, Cancel, or presses ESC
14027c43fe1SDevin Teske	#
14127c43fe1SDevin Teske	title="$msg_add $msg_group: $group_name"
14227c43fe1SDevin Teske	if f_interactive; then
14327c43fe1SDevin Teske		local mtag retval defaultitem=
14427c43fe1SDevin Teske		while :; do
14527c43fe1SDevin Teske			f_dialog_title "$title"
14627c43fe1SDevin Teske			f_dialog_menu_group_add "$defaultitem"
14727c43fe1SDevin Teske			retval=$?
14827c43fe1SDevin Teske			f_dialog_title_restore
14927c43fe1SDevin Teske			f_dialog_menutag_fetch mtag
15027c43fe1SDevin Teske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
15127c43fe1SDevin Teske			defaultitem="$mtag"
15227c43fe1SDevin Teske
15327c43fe1SDevin Teske			# Return if user either pressed ESC or chose Cancel/No
15427c43fe1SDevin Teske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
15527c43fe1SDevin Teske
15627c43fe1SDevin Teske			case "$mtag" in
15727c43fe1SDevin Teske			X) # Add/Exit
158b00c7d1aSDevin Teske			   local var
159b00c7d1aSDevin Teske			   for var in gid members name; do
160b00c7d1aSDevin Teske			   	local _group_$var
161b00c7d1aSDevin Teske			   	eval f_shell_escape \
162b00c7d1aSDevin Teske			   		\"\$group_$var\" _group_$var
163b00c7d1aSDevin Teske			   done
164b00c7d1aSDevin Teske
165b00c7d1aSDevin Teske			   local cmd="pw groupadd -n '$_group_name'"
166b00c7d1aSDevin Teske			   [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
16727c43fe1SDevin Teske			   [ "$group_members" ] &&
168b00c7d1aSDevin Teske			   	cmd="$cmd -M '$_group_members'"
16927c43fe1SDevin Teske
17027c43fe1SDevin Teske			   # Execute the command (break on success)
17127c43fe1SDevin Teske			   if [ "$group_password_disable" ]; then
17227c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s -h -' "$cmd"
17327c43fe1SDevin Teske			   elif [ "$group_password" ]; then
17427c43fe1SDevin Teske			   	echo "$group_password" |
17527c43fe1SDevin Teske			   		f_eval_catch $funcname \
17627c43fe1SDevin Teske			   			pw '%s -h 0' "$cmd"
17727c43fe1SDevin Teske			   else
17827c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s' "$cmd"
17927c43fe1SDevin Teske			   fi && break
18027c43fe1SDevin Teske			   ;;
18127c43fe1SDevin Teske			1) # Group Name (prompt for new group name)
18227c43fe1SDevin Teske			   f_dialog_input_group_name input "$group_name" ||
18327c43fe1SDevin Teske			   	continue
184*e8e8c939SDevin Teske			   if f_quietly pw groupshow -n "$input" -g 1337; then
18527c43fe1SDevin Teske			   	f_show_err "$msg_group_already_used" "$input"
18627c43fe1SDevin Teske			   	continue
18727c43fe1SDevin Teske			   fi
18827c43fe1SDevin Teske			   group_name="$input"
18927c43fe1SDevin Teske			   title="$msg_add $msg_group: $group_name"
19027c43fe1SDevin Teske			   ;;
19127c43fe1SDevin Teske			2) # Password
19227c43fe1SDevin Teske			   f_dialog_input_group_password group_password \
19327c43fe1SDevin Teske			   	group_password_disable
19427c43fe1SDevin Teske			   ;;
19527c43fe1SDevin Teske			3) # Group ID
19627c43fe1SDevin Teske			   f_dialog_input_group_gid group_gid "$group_gid"
19727c43fe1SDevin Teske			   ;;
19827c43fe1SDevin Teske			4) # Group Members
19927c43fe1SDevin Teske			   f_dialog_input_group_members group_members \
20027c43fe1SDevin Teske					"$group_members"
20127c43fe1SDevin Teske			   ;;
20227c43fe1SDevin Teske			esac
20327c43fe1SDevin Teske		done
20427c43fe1SDevin Teske	else
205b00c7d1aSDevin Teske		local var
206b00c7d1aSDevin Teske		for var in gid members name; do
207b00c7d1aSDevin Teske			local _group_$var
208b00c7d1aSDevin Teske			eval f_shell_escape \"\$group_$var\" _group_$var
209b00c7d1aSDevin Teske		done
210b00c7d1aSDevin Teske
21127c43fe1SDevin Teske		# Form the command
212b00c7d1aSDevin Teske		local cmd="pw groupadd -n '$_group_name'"
213b00c7d1aSDevin Teske		[ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
214b00c7d1aSDevin Teske		[ "$group_members" ] && cmd="$cmd -M '$_group_members'"
21527c43fe1SDevin Teske
21627c43fe1SDevin Teske		# Execute the command
21727c43fe1SDevin Teske		local retval err
21827c43fe1SDevin Teske		if [ "$group_password_disable" ]; then
21927c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
22027c43fe1SDevin Teske		elif [ "$group_password" ]; then
221faae0586SDevin Teske			err=$( echo "$group_password" | f_eval_catch -de \
222faae0586SDevin Teske				$funcname pw '%s -h 0' "$cmd" 2>&1 )
22327c43fe1SDevin Teske		else
22427c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s' "$cmd"
22527c43fe1SDevin Teske		fi
22627c43fe1SDevin Teske		retval=$?
22727c43fe1SDevin Teske		if [ $retval -ne $SUCCESS ]; then
22827c43fe1SDevin Teske			f_show_err "%s" "$err"
22927c43fe1SDevin Teske			return $retval
23027c43fe1SDevin Teske		fi
23127c43fe1SDevin Teske	fi
23227c43fe1SDevin Teske
23327c43fe1SDevin Teske	f_dialog_title "$title"
23427c43fe1SDevin Teske	$alert "$msg_group_added"
23527c43fe1SDevin Teske	f_dialog_title_restore
236160c4133SDevin Teske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
23727c43fe1SDevin Teske
23827c43fe1SDevin Teske	return $SUCCESS
23927c43fe1SDevin Teske}
24027c43fe1SDevin Teske
24127c43fe1SDevin Teske# f_group_delete [$group]
24227c43fe1SDevin Teske#
24327c43fe1SDevin Teske# Delete a group. If both $group (as a first argument) and $VAR_GROUP are unset
24427c43fe1SDevin Teske# or NULL and we are running interactively, prompt the user to select a group
24527c43fe1SDevin Teske# from a list of available groups. Variables that can be used to script user
24627c43fe1SDevin Teske# input:
24727c43fe1SDevin Teske#
24827c43fe1SDevin Teske# 	VAR_GROUP [Optional if running interactively]
24927c43fe1SDevin Teske# 		The group to delete. Ignored if given non-NULL first-argument.
25027c43fe1SDevin Teske#
25127c43fe1SDevin Teske# Returns success if the group was successfully deleted.
25227c43fe1SDevin Teske#
25327c43fe1SDevin Teskef_group_delete()
25427c43fe1SDevin Teske{
25527c43fe1SDevin Teske	local funcname=f_group_delete
25627c43fe1SDevin Teske	local title # Calculated below
25727c43fe1SDevin Teske	local alert=f_show_msg no_confirm=
25827c43fe1SDevin Teske
25927c43fe1SDevin Teske	f_getvar $VAR_NO_CONFIRM no_confirm
26027c43fe1SDevin Teske	[ "$no_confirm" ] && alert=f_show_info
26127c43fe1SDevin Teske
26227c43fe1SDevin Teske	local input
26327c43fe1SDevin Teske	f_getvar 3:-\$$VAR_GROUP input "$1"
26427c43fe1SDevin Teske
26527c43fe1SDevin Teske	local group_name group_password group_gid group_members
26627c43fe1SDevin Teske	if [ "$input" ] && ! f_input_group "$input"; then
26727c43fe1SDevin Teske		f_show_err "$msg_group_not_found" "$input"
26827c43fe1SDevin Teske		return $FAILURE
26927c43fe1SDevin Teske	fi
27027c43fe1SDevin Teske
27127c43fe1SDevin Teske	#
27227c43fe1SDevin Teske	# Loop until the user decides to Exit, Cancel, or presses ESC
27327c43fe1SDevin Teske	#
27427c43fe1SDevin Teske	title="$msg_delete $msg_group: $group_name"
27527c43fe1SDevin Teske	if f_interactive; then
27627c43fe1SDevin Teske		local mtag retval defaultitem=
27727c43fe1SDevin Teske		while :; do
27827c43fe1SDevin Teske        		f_dialog_title "$title"
27927c43fe1SDevin Teske			f_dialog_menu_group_delete "$group_name" "$defaultitem"
28027c43fe1SDevin Teske			retval=$?
28127c43fe1SDevin Teske			f_dialog_title_restore
28227c43fe1SDevin Teske			f_dialog_menutag_fetch mtag
28327c43fe1SDevin Teske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
28427c43fe1SDevin Teske			defaultitem="$mtag"
28527c43fe1SDevin Teske
28627c43fe1SDevin Teske			# Return if user either pressed ESC or chose Cancel/No
28727c43fe1SDevin Teske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
28827c43fe1SDevin Teske
28927c43fe1SDevin Teske			case "$mtag" in
29027c43fe1SDevin Teske			X) # Delete/Exit
291b00c7d1aSDevin Teske			   local _group_name
292b00c7d1aSDevin Teske			   f_shell_escape "$group_name" _group_name
29327c43fe1SDevin Teske			   f_eval_catch $funcname pw 'pw groupdel "%s"' \
294b00c7d1aSDevin Teske					"$_group_name" && break
29527c43fe1SDevin Teske			   ;;
29627c43fe1SDevin Teske			1) # Group Name (select different group from list)
29727c43fe1SDevin Teske			   f_dialog_menu_group_list "$group_name" || continue
29827c43fe1SDevin Teske			   f_dialog_menutag_fetch mtag
29927c43fe1SDevin Teske
30027c43fe1SDevin Teske			   [ "$mtag" = "X $msg_exit" ] && continue
30127c43fe1SDevin Teske
30227c43fe1SDevin Teske			   if ! f_input_group "$mtag"; then
30327c43fe1SDevin Teske				f_show_err "$msg_group_not_found" "$mtag"
30427c43fe1SDevin Teske				# Attempt to fall back to previous selection
30527c43fe1SDevin Teske				f_input_group "$input" || return $FAILURE
30627c43fe1SDevin Teske			   else
30727c43fe1SDevin Teske				input="$mtag"
30827c43fe1SDevin Teske			   fi
30927c43fe1SDevin Teske			   ;;
31027c43fe1SDevin Teske			esac
31127c43fe1SDevin Teske		done
31227c43fe1SDevin Teske	else
313b00c7d1aSDevin Teske		local retval err _group_name
314b00c7d1aSDevin Teske		f_shell_escape "$group_name" _group_name
31527c43fe1SDevin Teske		f_eval_catch -k err $funcname pw \
316b00c7d1aSDevin Teske			"pw groupdel '%s'" "$_group_name"
31727c43fe1SDevin Teske		retval=$?
31827c43fe1SDevin Teske		if [ $retval -ne $SUCCESS ]; then
31927c43fe1SDevin Teske			f_show_err "%s" "$err"
32027c43fe1SDevin Teske			return $retval
32127c43fe1SDevin Teske		fi
32227c43fe1SDevin Teske	fi
32327c43fe1SDevin Teske
32427c43fe1SDevin Teske        f_dialog_title "$title"
32527c43fe1SDevin Teske	$alert "$msg_group_deleted"
32627c43fe1SDevin Teske	f_dialog_title_restore
327160c4133SDevin Teske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
32827c43fe1SDevin Teske
32927c43fe1SDevin Teske	return $SUCCESS
33027c43fe1SDevin Teske}
33127c43fe1SDevin Teske
33227c43fe1SDevin Teske# f_group_edit [$group]
33327c43fe1SDevin Teske#
33427c43fe1SDevin Teske# Modify a group. If both $group (as a first argument) and $VAR_GROUP are unset
33527c43fe1SDevin Teske# or NULL and we are running interactively, prompt the user to select a group
33627c43fe1SDevin Teske# from a list of available groups. Variables that can be used to script user
33727c43fe1SDevin Teske# input:
33827c43fe1SDevin Teske#
33927c43fe1SDevin Teske# 	VAR_GROUP [Optional if running interactively]
34027c43fe1SDevin Teske# 		The group to modify. Ignored if given non-NULL first-argument.
34127c43fe1SDevin Teske#	VAR_GROUP_GID [Optional]
34227c43fe1SDevin Teske# 		Numerical group ID to set. If NULL or unset, the group ID is
34327c43fe1SDevin Teske# 		unchanged.
34427c43fe1SDevin Teske# 	VAR_GROUP_MEMBERS [Optional]
34527c43fe1SDevin Teske# 		Comma separated list of users that are a member of this group.
3467bac4bd2SDevin Teske# 		If set but NULL, group memberships are reset (no users will be
3477bac4bd2SDevin Teske# 		a member of this group). If unset, group membership is
3487bac4bd2SDevin Teske# 		unmodified.
34927c43fe1SDevin Teske# 	VAR_GROUP_PASSWORD [Optional]
35027c43fe1SDevin Teske# 		newgrp(1) password to set for the group. If unset, the password
35127c43fe1SDevin Teske# 		is unmodified. If NULL, the newgrp(1) password is disabled.
35227c43fe1SDevin Teske#
35327c43fe1SDevin Teske# Returns success if the group was successfully modified.
35427c43fe1SDevin Teske#
35527c43fe1SDevin Teskef_group_edit()
35627c43fe1SDevin Teske{
35727c43fe1SDevin Teske	local funcname=f_group_edit
35827c43fe1SDevin Teske	local title # Calculated below
35927c43fe1SDevin Teske	local alert=f_show_msg no_confirm=
36027c43fe1SDevin Teske
36127c43fe1SDevin Teske	f_getvar $VAR_NO_CONFIRM no_confirm
36227c43fe1SDevin Teske	[ "$no_confirm" ] && alert=f_show_info
36327c43fe1SDevin Teske
36427c43fe1SDevin Teske	local input
36527c43fe1SDevin Teske	f_getvar 3:-\$$VAR_GROUP input "$1"
36627c43fe1SDevin Teske
36727c43fe1SDevin Teske	#
36827c43fe1SDevin Teske	# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
36927c43fe1SDevin Teske	# instead of name. Work-around is to also pass `-g GID' at the same
370*e8e8c939SDevin Teske	# time (the GID is ignored in this case, so any GID will do).
37127c43fe1SDevin Teske	#
372*e8e8c939SDevin Teske	if [ "$input" ] && ! f_quietly pw groupshow -n "$input" -g 1337; then
37327c43fe1SDevin Teske		f_show_err "$msg_group_not_found" "$input"
37427c43fe1SDevin Teske		return $FAILURE
37527c43fe1SDevin Teske	fi
37627c43fe1SDevin Teske
37727c43fe1SDevin Teske	if f_interactive && [ ! "$input" ]; then
37827c43fe1SDevin Teske		f_dialog_menu_group_list || return $SUCCESS
37927c43fe1SDevin Teske		f_dialog_menutag_fetch input
38027c43fe1SDevin Teske		[ "$input" = "X $msg_exit" ] && return $SUCCESS
38127c43fe1SDevin Teske	elif [ ! "$input" ]; then
38227c43fe1SDevin Teske		f_show_err "$msg_no_group_specified"
38327c43fe1SDevin Teske		return $FAILURE
38427c43fe1SDevin Teske	fi
38527c43fe1SDevin Teske
38627c43fe1SDevin Teske	local group_name group_password group_gid group_members
38727c43fe1SDevin Teske	if ! f_input_group "$input"; then
38827c43fe1SDevin Teske		f_show_err "$msg_group_not_found" "$input"
38927c43fe1SDevin Teske		return $FAILURE
39027c43fe1SDevin Teske	fi
39127c43fe1SDevin Teske
39227c43fe1SDevin Teske	f_isset $VAR_GROUP_GID && f_getvar $VAR_GROUP_GID group_gid
39327c43fe1SDevin Teske	local null_members=
39427c43fe1SDevin Teske	if f_isset $VAR_GROUP_MEMBERS; then
39527c43fe1SDevin Teske		f_getvar $VAR_GROUP_MEMBERS group_members
39627c43fe1SDevin Teske		[ "$group_members" ] || null_members=1
39727c43fe1SDevin Teske	fi
39827c43fe1SDevin Teske	local group_password_disable=
39927c43fe1SDevin Teske	if f_isset $VAR_GROUP_PASSWORD; then
40027c43fe1SDevin Teske		f_getvar $VAR_GROUP_PASSWORD group_password
40127c43fe1SDevin Teske		[ "$group_password" ] || group_password_disable=1
40227c43fe1SDevin Teske	fi
40327c43fe1SDevin Teske
40427c43fe1SDevin Teske	#
40527c43fe1SDevin Teske	# Loop until the user decides to Exit, Cancel, or presses ESC
40627c43fe1SDevin Teske	#
40727c43fe1SDevin Teske	title="$msg_edit_view $msg_group: $group_name"
40827c43fe1SDevin Teske	if f_interactive; then
40927c43fe1SDevin Teske		local mtag retval defaultitem=
41027c43fe1SDevin Teske		while :; do
41127c43fe1SDevin Teske			f_dialog_title "$title"
41227c43fe1SDevin Teske			f_dialog_menu_group_edit "$defaultitem"
41327c43fe1SDevin Teske			retval=$?
41427c43fe1SDevin Teske			f_dialog_title_restore
41527c43fe1SDevin Teske			f_dialog_menutag_fetch mtag
41627c43fe1SDevin Teske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
41727c43fe1SDevin Teske			defaultitem="$mtag"
41827c43fe1SDevin Teske
41927c43fe1SDevin Teske			# Return if user either pressed ESC or chose Cancel/No
42027c43fe1SDevin Teske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
42127c43fe1SDevin Teske
42227c43fe1SDevin Teske			case "$mtag" in
42327c43fe1SDevin Teske			X) # Save/Exit
424b00c7d1aSDevin Teske			   local var
425b00c7d1aSDevin Teske			   for var in gid members name; do
426b00c7d1aSDevin Teske			   	local _group_$var
427b00c7d1aSDevin Teske			   	eval f_shell_escape \
428b00c7d1aSDevin Teske			   		\"\$group_$var\" _group_$var
429b00c7d1aSDevin Teske			   done
430b00c7d1aSDevin Teske
431b00c7d1aSDevin Teske			   local cmd="pw groupmod -n '$_group_name'"
432b00c7d1aSDevin Teske			   [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
43327c43fe1SDevin Teske			   [ "$group_members" -o "$null_members" ] &&
434b00c7d1aSDevin Teske			   	cmd="$cmd -M '$_group_members'"
43527c43fe1SDevin Teske
43627c43fe1SDevin Teske			   # Execute the command (break on success)
43727c43fe1SDevin Teske			   if [ "$group_password_disable" ]; then
43827c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s -h -' "$cmd"
43927c43fe1SDevin Teske			   elif [ "$group_password" ]; then
4407bac4bd2SDevin Teske			   	echo "$group_password" | f_eval_catch \
4417bac4bd2SDevin Teske			   		$funcname pw '%s -h 0' "$cmd"
44227c43fe1SDevin Teske			   else
44327c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s' "$cmd"
44427c43fe1SDevin Teske			   fi && break
44527c43fe1SDevin Teske			   ;;
44627c43fe1SDevin Teske			1) # Group Name (select different group from list)
44727c43fe1SDevin Teske			   f_dialog_menu_group_list "$group_name" || continue
44827c43fe1SDevin Teske			   f_dialog_menutag_fetch mtag
44927c43fe1SDevin Teske
45027c43fe1SDevin Teske			   [ "$mtag" = "X $msg_exit" ] && continue
45127c43fe1SDevin Teske
45227c43fe1SDevin Teske			   if ! f_input_group "$mtag"; then
45327c43fe1SDevin Teske			   	f_show_err "$msg_group_not_found" "$mtag"
4547bac4bd2SDevin Teske			   	# Attempt to fall back to previous selection
45527c43fe1SDevin Teske			   	f_input_group "$input" || return $FAILURE
45627c43fe1SDevin Teske			   else
45727c43fe1SDevin Teske			   	input="$mtag"
45827c43fe1SDevin Teske			   fi
45927c43fe1SDevin Teske			   title="$msg_edit_view $msg_group: $group_name"
46027c43fe1SDevin Teske			   ;;
46127c43fe1SDevin Teske			2) # Password
46227c43fe1SDevin Teske			   f_dialog_input_group_password group_password \
46327c43fe1SDevin Teske			   	group_password_disable
46427c43fe1SDevin Teske			   ;;
46527c43fe1SDevin Teske			3) # Group ID
46627c43fe1SDevin Teske			   f_dialog_input_group_gid group_gid "$group_gid"
46727c43fe1SDevin Teske			   ;;
46827c43fe1SDevin Teske			4) # Group Members
46927c43fe1SDevin Teske			   f_dialog_input_group_members group_members \
47027c43fe1SDevin Teske			   	"$group_members" && [ ! "$group_members" ] &&
47127c43fe1SDevin Teske			   	null_members=1
47227c43fe1SDevin Teske			   ;;
47327c43fe1SDevin Teske			esac
47427c43fe1SDevin Teske		done
47527c43fe1SDevin Teske	else
476b00c7d1aSDevin Teske		local var
477b00c7d1aSDevin Teske		for var in gid members name; do
478b00c7d1aSDevin Teske			local _group_$var
479b00c7d1aSDevin Teske			eval f_shell_escape \"\$group_$var\" _group_$var
480b00c7d1aSDevin Teske		done
481b00c7d1aSDevin Teske
48227c43fe1SDevin Teske		# Form the command
483b00c7d1aSDevin Teske		local cmd="pw groupmod -n '$_group_name'"
484b00c7d1aSDevin Teske		[ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
48527c43fe1SDevin Teske		[ "$group_members" -o "$null_members" ] &&
486b00c7d1aSDevin Teske			cmd="$cmd -M '$_group_members'"
48727c43fe1SDevin Teske
48827c43fe1SDevin Teske		# Execute the command
48927c43fe1SDevin Teske		local retval err
49027c43fe1SDevin Teske		if [ "$group_password_disable" ]; then
49127c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
49227c43fe1SDevin Teske		elif [ "$group_password" -o "$null_password" ]; then
493faae0586SDevin Teske			err=$( echo "$group_password" | f_eval_catch -de \
494faae0586SDevin Teske				$funcname pw '%s -h 0' "$cmd" 2>&1 )
49527c43fe1SDevin Teske		else
49627c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s' "$cmd"
49727c43fe1SDevin Teske		fi
49827c43fe1SDevin Teske		retval=$?
49927c43fe1SDevin Teske		if [ $retval -ne $SUCCESS ]; then
50027c43fe1SDevin Teske			f_show_err "%s" "$err"
50127c43fe1SDevin Teske			return $retval
50227c43fe1SDevin Teske		fi
50327c43fe1SDevin Teske	fi
50427c43fe1SDevin Teske
50527c43fe1SDevin Teske	f_dialog_title "$title"
50627c43fe1SDevin Teske	$alert "$msg_group_updated"
50727c43fe1SDevin Teske	f_dialog_title_restore
508160c4133SDevin Teske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
50927c43fe1SDevin Teske
51027c43fe1SDevin Teske	return $SUCCESS
51127c43fe1SDevin Teske}
51227c43fe1SDevin Teske
51327c43fe1SDevin Teske############################################################ MAIN
51427c43fe1SDevin Teske
51527c43fe1SDevin Teskef_dprintf "%s: Successfully loaded." usermgmt/group.subr
51627c43fe1SDevin Teske
51727c43fe1SDevin Teskefi # ! $_USERMGMT_GROUP_SUBR
518