xref: /freebsd/usr.sbin/bsdconfig/usermgmt/share/group.subr (revision b00c7d1aa222b2376aed2d7762e9f2d18b02b7fb)
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# $FreeBSD$
2927c43fe1SDevin Teske#
3027c43fe1SDevin Teske############################################################ INCLUDES
3127c43fe1SDevin Teske
3227c43fe1SDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig"
3327c43fe1SDevin Teske. $BSDCFG_SHARE/common.subr || exit 1
3427c43fe1SDevin Teskef_dprintf "%s: loading includes..." usermgmt/group.subr
3527c43fe1SDevin Teskef_include $BSDCFG_SHARE/dialog.subr
3627c43fe1SDevin Teskef_include $BSDCFG_SHARE/usermgmt/group_input.subr
3727c43fe1SDevin Teske
3827c43fe1SDevin TeskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
3927c43fe1SDevin Teskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
4027c43fe1SDevin Teske
4127c43fe1SDevin Teske############################################################ CONFIGURATION
4227c43fe1SDevin Teske
4327c43fe1SDevin Teske# set some reasonable defaults if /etc/adduser.conf does not exist.
4427c43fe1SDevin Teske[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf
4527c43fe1SDevin Teske: ${passwdtype:="yes"}
4627c43fe1SDevin Teske
4727c43fe1SDevin Teske############################################################ FUNCTIONS
4827c43fe1SDevin Teske
4927c43fe1SDevin Teske# f_group_add [$group]
5027c43fe1SDevin Teske#
5127c43fe1SDevin Teske# Add a group. If both $group (as a first argument) and $VAR_GROUP are unset
5227c43fe1SDevin Teske# or NULL and we are running interactively, prompt the user to enter the name
5327c43fe1SDevin Teske# of a new group and (if $VAR_NO_CONFIRM is unset or NULL) prompt the user to
5427c43fe1SDevin Teske# answer some questions about the new group. Variables that can be used to
5527c43fe1SDevin Teske# script user input:
5627c43fe1SDevin Teske#
5727c43fe1SDevin Teske# 	VAR_GROUP [Optional if running interactively]
5827c43fe1SDevin Teske# 		The group to add. Ignored if given non-NULL first-argument.
5927c43fe1SDevin Teske#	VAR_GROUP_GID [Optional]
6027c43fe1SDevin Teske# 		Numerical group ID to use. If NULL or unset, the group ID is
6127c43fe1SDevin Teske# 		automatically chosen.
6227c43fe1SDevin Teske# 	VAR_GROUP_MEMBERS [Optional]
6327c43fe1SDevin Teske# 		Comma separated list of users that are a member of this group.
6427c43fe1SDevin Teske# 	VAR_GROUP_PASSWORD [Optional]
6527c43fe1SDevin Teske# 		newgrp(1) password to set for the group. Default if NULL or
6627c43fe1SDevin Teske# 		unset is to disable newgrp(1) password authentication.
6727c43fe1SDevin Teske#
6827c43fe1SDevin Teske# Returns success if the group was successfully added.
6927c43fe1SDevin Teske#
7027c43fe1SDevin Teskef_group_add()
7127c43fe1SDevin Teske{
7227c43fe1SDevin Teske	local funcname=f_group_add
7327c43fe1SDevin Teske	local title # Calculated below
7427c43fe1SDevin Teske	local alert=f_show_msg no_confirm=
7527c43fe1SDevin Teske
7627c43fe1SDevin Teske	f_getvar $VAR_NO_CONFIRM no_confirm
7727c43fe1SDevin Teske	[ "$no_confirm" ] && alert=f_show_info
7827c43fe1SDevin Teske
7927c43fe1SDevin Teske	local input
8027c43fe1SDevin Teske	f_getvar 3:-\$$VAR_GROUP input "$1"
8127c43fe1SDevin Teske
8227c43fe1SDevin Teske	#
8327c43fe1SDevin Teske	# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
8427c43fe1SDevin Teske	# instead of name. Work-around is to also pass `-g GID' at the same
8527c43fe1SDevin Teske	# time (any GID will do; but `-1' is appropriate for this context).
8627c43fe1SDevin Teske	#
8727c43fe1SDevin Teske	if [ "$input" ] && f_quietly pw groupshow -n "$input" -g -1; then
8827c43fe1SDevin Teske		f_show_err "$msg_group_already_used" "$input"
8927c43fe1SDevin Teske		return $FAILURE
9027c43fe1SDevin Teske	fi
9127c43fe1SDevin Teske
9227c43fe1SDevin Teske	local group_name="$input"
9327c43fe1SDevin Teske	while f_interactive && [ ! "$group_name" ]; do
9427c43fe1SDevin Teske		f_dialog_input_group_name group_name "$group_name" ||
9527c43fe1SDevin Teske			return $SUCCESS
9627c43fe1SDevin Teske		[ "$group_name" ] ||
9727c43fe1SDevin Teske			f_show_err "$msg_please_enter_a_group_name"
9827c43fe1SDevin Teske	done
99863bb164SDevin Teske	if [ ! "$group_name" ]; then
100863bb164SDevin Teske		f_show_err "$msg_no_group_specified"
101863bb164SDevin Teske		return $FAILURE
102863bb164SDevin Teske	fi
10327c43fe1SDevin Teske
10427c43fe1SDevin Teske	local group_password group_gid group_members
10527c43fe1SDevin Teske	f_getvar $VAR_GROUP_PASSWORD	group_password
10627c43fe1SDevin Teske	f_getvar $VAR_GROUP_GID		group_gid
10727c43fe1SDevin Teske	f_getvar $VAR_GROUP_MEMBERS	group_members
10827c43fe1SDevin Teske
10927c43fe1SDevin Teske	local group_password_disable=
11027c43fe1SDevin Teske	f_interactive || [ "$group_password" ] || group_password_disable=1
11127c43fe1SDevin Teske
11227c43fe1SDevin Teske	if f_interactive && [ ! "$no_confirm" ]; then
11327c43fe1SDevin Teske		f_dialog_noyes \
11427c43fe1SDevin Teske			"$msg_use_default_values_for_all_account_details"
11527c43fe1SDevin Teske		retval=$?
11627c43fe1SDevin Teske		if [ $retval -eq $DIALOG_ESC ]; then
11727c43fe1SDevin Teske			return $SUCCESS
11827c43fe1SDevin Teske		elif [ $retval -ne $DIALOG_OK ]; then
11927c43fe1SDevin Teske			#
12027c43fe1SDevin Teske			# Ask series of questions to pre-fill the editor screen
12127c43fe1SDevin Teske			#
12227c43fe1SDevin Teske			# Defaults used in each dialog should allow the user to
12327c43fe1SDevin Teske			# simply hit ENTER to proceed and cancelling a single
12427c43fe1SDevin Teske			# dialog cause them to return to the previous menu.
12527c43fe1SDevin Teske			#
12627c43fe1SDevin Teske
12727c43fe1SDevin Teske			if [ "$passwdtype" = "yes" ]; then
12827c43fe1SDevin Teske				f_dialog_input_group_password group_password \
12927c43fe1SDevin Teske					group_password_disable ||
13027c43fe1SDevin Teske					return $FAILURE
13127c43fe1SDevin Teske			fi
13227c43fe1SDevin Teske			f_dialog_input_group_gid group_gid "$group_gid" ||
13327c43fe1SDevin Teske				return $FAILURE
13427c43fe1SDevin Teske			f_dialog_input_group_members group_members \
13527c43fe1SDevin Teske				"$group_members" || return $FAILURE
13627c43fe1SDevin Teske		fi
13727c43fe1SDevin Teske	fi
13827c43fe1SDevin Teske
13927c43fe1SDevin Teske	#
14027c43fe1SDevin Teske	# Loop until the user decides to Exit, Cancel, or presses ESC
14127c43fe1SDevin Teske	#
14227c43fe1SDevin Teske	title="$msg_add $msg_group: $group_name"
14327c43fe1SDevin Teske	if f_interactive; then
14427c43fe1SDevin Teske		local mtag retval defaultitem=
14527c43fe1SDevin Teske		while :; do
14627c43fe1SDevin Teske			f_dialog_title "$title"
14727c43fe1SDevin Teske			f_dialog_menu_group_add "$defaultitem"
14827c43fe1SDevin Teske			retval=$?
14927c43fe1SDevin Teske			f_dialog_title_restore
15027c43fe1SDevin Teske			f_dialog_menutag_fetch mtag
15127c43fe1SDevin Teske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
15227c43fe1SDevin Teske			defaultitem="$mtag"
15327c43fe1SDevin Teske
15427c43fe1SDevin Teske			# Return if user either pressed ESC or chose Cancel/No
15527c43fe1SDevin Teske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
15627c43fe1SDevin Teske
15727c43fe1SDevin Teske			case "$mtag" in
15827c43fe1SDevin Teske			X) # Add/Exit
159*b00c7d1aSDevin Teske			   local var
160*b00c7d1aSDevin Teske			   for var in gid members name; do
161*b00c7d1aSDevin Teske			   	local _group_$var
162*b00c7d1aSDevin Teske			   	eval f_shell_escape \
163*b00c7d1aSDevin Teske			   		\"\$group_$var\" _group_$var
164*b00c7d1aSDevin Teske			   done
165*b00c7d1aSDevin Teske
166*b00c7d1aSDevin Teske			   local cmd="pw groupadd -n '$_group_name'"
167*b00c7d1aSDevin Teske			   [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
16827c43fe1SDevin Teske			   [ "$group_members" ] &&
169*b00c7d1aSDevin Teske			   	cmd="$cmd -M '$_group_members'"
17027c43fe1SDevin Teske
17127c43fe1SDevin Teske			   # Execute the command (break on success)
17227c43fe1SDevin Teske			   if [ "$group_password_disable" ]; then
17327c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s -h -' "$cmd"
17427c43fe1SDevin Teske			   elif [ "$group_password" ]; then
17527c43fe1SDevin Teske			   	echo "$group_password" |
17627c43fe1SDevin Teske			   		f_eval_catch $funcname \
17727c43fe1SDevin Teske			   			pw '%s -h 0' "$cmd"
17827c43fe1SDevin Teske			   else
17927c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s' "$cmd"
18027c43fe1SDevin Teske			   fi && break
18127c43fe1SDevin Teske			   ;;
18227c43fe1SDevin Teske			1) # Group Name (prompt for new group name)
18327c43fe1SDevin Teske			   f_dialog_input_group_name input "$group_name" ||
18427c43fe1SDevin Teske			   	continue
18527c43fe1SDevin Teske			   if f_quietly pw groupshow -n "$input" -g -1; then
18627c43fe1SDevin Teske			   	f_show_err "$msg_group_already_used" "$input"
18727c43fe1SDevin Teske			   	continue
18827c43fe1SDevin Teske			   fi
18927c43fe1SDevin Teske			   group_name="$input"
19027c43fe1SDevin Teske			   title="$msg_add $msg_group: $group_name"
19127c43fe1SDevin Teske			   ;;
19227c43fe1SDevin Teske			2) # Password
19327c43fe1SDevin Teske			   f_dialog_input_group_password group_password \
19427c43fe1SDevin Teske			   	group_password_disable
19527c43fe1SDevin Teske			   ;;
19627c43fe1SDevin Teske			3) # Group ID
19727c43fe1SDevin Teske			   f_dialog_input_group_gid group_gid "$group_gid"
19827c43fe1SDevin Teske			   ;;
19927c43fe1SDevin Teske			4) # Group Members
20027c43fe1SDevin Teske			   f_dialog_input_group_members group_members \
20127c43fe1SDevin Teske					"$group_members"
20227c43fe1SDevin Teske			   ;;
20327c43fe1SDevin Teske			esac
20427c43fe1SDevin Teske		done
20527c43fe1SDevin Teske	else
206*b00c7d1aSDevin Teske		local var
207*b00c7d1aSDevin Teske		for var in gid members name; do
208*b00c7d1aSDevin Teske			local _group_$var
209*b00c7d1aSDevin Teske			eval f_shell_escape \"\$group_$var\" _group_$var
210*b00c7d1aSDevin Teske		done
211*b00c7d1aSDevin Teske
21227c43fe1SDevin Teske		# Form the command
213*b00c7d1aSDevin Teske		local cmd="pw groupadd -n '$_group_name'"
214*b00c7d1aSDevin Teske		[ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
215*b00c7d1aSDevin Teske		[ "$group_members" ] && cmd="$cmd -M '$_group_members'"
21627c43fe1SDevin Teske
21727c43fe1SDevin Teske		# Execute the command
21827c43fe1SDevin Teske		local retval err
21927c43fe1SDevin Teske		if [ "$group_password_disable" ]; then
22027c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
22127c43fe1SDevin Teske		elif [ "$group_password" ]; then
222faae0586SDevin Teske			err=$( echo "$group_password" | f_eval_catch -de \
223faae0586SDevin Teske				$funcname pw '%s -h 0' "$cmd" 2>&1 )
22427c43fe1SDevin Teske		else
22527c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s' "$cmd"
22627c43fe1SDevin Teske		fi
22727c43fe1SDevin Teske		retval=$?
22827c43fe1SDevin Teske		if [ $retval -ne $SUCCESS ]; then
22927c43fe1SDevin Teske			f_show_err "%s" "$err"
23027c43fe1SDevin Teske			return $retval
23127c43fe1SDevin Teske		fi
23227c43fe1SDevin Teske	fi
23327c43fe1SDevin Teske
23427c43fe1SDevin Teske	f_dialog_title "$title"
23527c43fe1SDevin Teske	$alert "$msg_group_added"
23627c43fe1SDevin Teske	f_dialog_title_restore
237160c4133SDevin Teske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
23827c43fe1SDevin Teske
23927c43fe1SDevin Teske	return $SUCCESS
24027c43fe1SDevin Teske}
24127c43fe1SDevin Teske
24227c43fe1SDevin Teske# f_group_delete [$group]
24327c43fe1SDevin Teske#
24427c43fe1SDevin Teske# Delete a group. If both $group (as a first argument) and $VAR_GROUP are unset
24527c43fe1SDevin Teske# or NULL and we are running interactively, prompt the user to select a group
24627c43fe1SDevin Teske# from a list of available groups. Variables that can be used to script user
24727c43fe1SDevin Teske# input:
24827c43fe1SDevin Teske#
24927c43fe1SDevin Teske# 	VAR_GROUP [Optional if running interactively]
25027c43fe1SDevin Teske# 		The group to delete. Ignored if given non-NULL first-argument.
25127c43fe1SDevin Teske#
25227c43fe1SDevin Teske# Returns success if the group was successfully deleted.
25327c43fe1SDevin Teske#
25427c43fe1SDevin Teskef_group_delete()
25527c43fe1SDevin Teske{
25627c43fe1SDevin Teske	local funcname=f_group_delete
25727c43fe1SDevin Teske	local title # Calculated below
25827c43fe1SDevin Teske	local alert=f_show_msg no_confirm=
25927c43fe1SDevin Teske
26027c43fe1SDevin Teske	f_getvar $VAR_NO_CONFIRM no_confirm
26127c43fe1SDevin Teske	[ "$no_confirm" ] && alert=f_show_info
26227c43fe1SDevin Teske
26327c43fe1SDevin Teske	local input
26427c43fe1SDevin Teske	f_getvar 3:-\$$VAR_GROUP input "$1"
26527c43fe1SDevin Teske
26627c43fe1SDevin Teske	local group_name group_password group_gid group_members
26727c43fe1SDevin Teske	if [ "$input" ] && ! f_input_group "$input"; then
26827c43fe1SDevin Teske		f_show_err "$msg_group_not_found" "$input"
26927c43fe1SDevin Teske		return $FAILURE
27027c43fe1SDevin Teske	fi
27127c43fe1SDevin Teske
27227c43fe1SDevin Teske	#
27327c43fe1SDevin Teske	# Loop until the user decides to Exit, Cancel, or presses ESC
27427c43fe1SDevin Teske	#
27527c43fe1SDevin Teske	title="$msg_delete $msg_group: $group_name"
27627c43fe1SDevin Teske	if f_interactive; then
27727c43fe1SDevin Teske		local mtag retval defaultitem=
27827c43fe1SDevin Teske		while :; do
27927c43fe1SDevin Teske        		f_dialog_title "$title"
28027c43fe1SDevin Teske			f_dialog_menu_group_delete "$group_name" "$defaultitem"
28127c43fe1SDevin Teske			retval=$?
28227c43fe1SDevin Teske			f_dialog_title_restore
28327c43fe1SDevin Teske			f_dialog_menutag_fetch mtag
28427c43fe1SDevin Teske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
28527c43fe1SDevin Teske			defaultitem="$mtag"
28627c43fe1SDevin Teske
28727c43fe1SDevin Teske			# Return if user either pressed ESC or chose Cancel/No
28827c43fe1SDevin Teske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
28927c43fe1SDevin Teske
29027c43fe1SDevin Teske			case "$mtag" in
29127c43fe1SDevin Teske			X) # Delete/Exit
292*b00c7d1aSDevin Teske			   local _group_name
293*b00c7d1aSDevin Teske			   f_shell_escape "$group_name" _group_name
29427c43fe1SDevin Teske			   f_eval_catch $funcname pw 'pw groupdel "%s"' \
295*b00c7d1aSDevin Teske					"$_group_name" && break
29627c43fe1SDevin Teske			   ;;
29727c43fe1SDevin Teske			1) # Group Name (select different group from list)
29827c43fe1SDevin Teske			   f_dialog_menu_group_list "$group_name" || continue
29927c43fe1SDevin Teske			   f_dialog_menutag_fetch mtag
30027c43fe1SDevin Teske
30127c43fe1SDevin Teske			   [ "$mtag" = "X $msg_exit" ] && continue
30227c43fe1SDevin Teske
30327c43fe1SDevin Teske			   if ! f_input_group "$mtag"; then
30427c43fe1SDevin Teske				f_show_err "$msg_group_not_found" "$mtag"
30527c43fe1SDevin Teske				# Attempt to fall back to previous selection
30627c43fe1SDevin Teske				f_input_group "$input" || return $FAILURE
30727c43fe1SDevin Teske			   else
30827c43fe1SDevin Teske				input="$mtag"
30927c43fe1SDevin Teske			   fi
31027c43fe1SDevin Teske			   ;;
31127c43fe1SDevin Teske			esac
31227c43fe1SDevin Teske		done
31327c43fe1SDevin Teske	else
314*b00c7d1aSDevin Teske		local retval err _group_name
315*b00c7d1aSDevin Teske		f_shell_escape "$group_name" _group_name
31627c43fe1SDevin Teske		f_eval_catch -k err $funcname pw \
317*b00c7d1aSDevin Teske			"pw groupdel '%s'" "$_group_name"
31827c43fe1SDevin Teske		retval=$?
31927c43fe1SDevin Teske		if [ $retval -ne $SUCCESS ]; then
32027c43fe1SDevin Teske			f_show_err "%s" "$err"
32127c43fe1SDevin Teske			return $retval
32227c43fe1SDevin Teske		fi
32327c43fe1SDevin Teske	fi
32427c43fe1SDevin Teske
32527c43fe1SDevin Teske        f_dialog_title "$title"
32627c43fe1SDevin Teske	$alert "$msg_group_deleted"
32727c43fe1SDevin Teske	f_dialog_title_restore
328160c4133SDevin Teske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
32927c43fe1SDevin Teske
33027c43fe1SDevin Teske	return $SUCCESS
33127c43fe1SDevin Teske}
33227c43fe1SDevin Teske
33327c43fe1SDevin Teske# f_group_edit [$group]
33427c43fe1SDevin Teske#
33527c43fe1SDevin Teske# Modify a group. If both $group (as a first argument) and $VAR_GROUP are unset
33627c43fe1SDevin Teske# or NULL and we are running interactively, prompt the user to select a group
33727c43fe1SDevin Teske# from a list of available groups. Variables that can be used to script user
33827c43fe1SDevin Teske# input:
33927c43fe1SDevin Teske#
34027c43fe1SDevin Teske# 	VAR_GROUP [Optional if running interactively]
34127c43fe1SDevin Teske# 		The group to modify. Ignored if given non-NULL first-argument.
34227c43fe1SDevin Teske#	VAR_GROUP_GID [Optional]
34327c43fe1SDevin Teske# 		Numerical group ID to set. If NULL or unset, the group ID is
34427c43fe1SDevin Teske# 		unchanged.
34527c43fe1SDevin Teske# 	VAR_GROUP_MEMBERS [Optional]
34627c43fe1SDevin Teske# 		Comma separated list of users that are a member of this group.
3477bac4bd2SDevin Teske# 		If set but NULL, group memberships are reset (no users will be
3487bac4bd2SDevin Teske# 		a member of this group). If unset, group membership is
3497bac4bd2SDevin Teske# 		unmodified.
35027c43fe1SDevin Teske# 	VAR_GROUP_PASSWORD [Optional]
35127c43fe1SDevin Teske# 		newgrp(1) password to set for the group. If unset, the password
35227c43fe1SDevin Teske# 		is unmodified. If NULL, the newgrp(1) password is disabled.
35327c43fe1SDevin Teske#
35427c43fe1SDevin Teske# Returns success if the group was successfully modified.
35527c43fe1SDevin Teske#
35627c43fe1SDevin Teskef_group_edit()
35727c43fe1SDevin Teske{
35827c43fe1SDevin Teske	local funcname=f_group_edit
35927c43fe1SDevin Teske	local title # Calculated below
36027c43fe1SDevin Teske	local alert=f_show_msg no_confirm=
36127c43fe1SDevin Teske
36227c43fe1SDevin Teske	f_getvar $VAR_NO_CONFIRM no_confirm
36327c43fe1SDevin Teske	[ "$no_confirm" ] && alert=f_show_info
36427c43fe1SDevin Teske
36527c43fe1SDevin Teske	local input
36627c43fe1SDevin Teske	f_getvar 3:-\$$VAR_GROUP input "$1"
36727c43fe1SDevin Teske
36827c43fe1SDevin Teske	#
36927c43fe1SDevin Teske	# NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
37027c43fe1SDevin Teske	# instead of name. Work-around is to also pass `-g GID' at the same
37127c43fe1SDevin Teske	# time (any GID will do; but `-1' is appropriate for this context).
37227c43fe1SDevin Teske	#
37327c43fe1SDevin Teske	if [ "$input" ] && ! f_quietly pw groupshow -n "$input" -g -1; then
37427c43fe1SDevin Teske		f_show_err "$msg_group_not_found" "$input"
37527c43fe1SDevin Teske		return $FAILURE
37627c43fe1SDevin Teske	fi
37727c43fe1SDevin Teske
37827c43fe1SDevin Teske	if f_interactive && [ ! "$input" ]; then
37927c43fe1SDevin Teske		f_dialog_menu_group_list || return $SUCCESS
38027c43fe1SDevin Teske		f_dialog_menutag_fetch input
38127c43fe1SDevin Teske		[ "$input" = "X $msg_exit" ] && return $SUCCESS
38227c43fe1SDevin Teske	elif [ ! "$input" ]; then
38327c43fe1SDevin Teske		f_show_err "$msg_no_group_specified"
38427c43fe1SDevin Teske		return $FAILURE
38527c43fe1SDevin Teske	fi
38627c43fe1SDevin Teske
38727c43fe1SDevin Teske	local group_name group_password group_gid group_members
38827c43fe1SDevin Teske	if ! f_input_group "$input"; then
38927c43fe1SDevin Teske		f_show_err "$msg_group_not_found" "$input"
39027c43fe1SDevin Teske		return $FAILURE
39127c43fe1SDevin Teske	fi
39227c43fe1SDevin Teske
39327c43fe1SDevin Teske	f_isset $VAR_GROUP_GID && f_getvar $VAR_GROUP_GID group_gid
39427c43fe1SDevin Teske	local null_members=
39527c43fe1SDevin Teske	if f_isset $VAR_GROUP_MEMBERS; then
39627c43fe1SDevin Teske		f_getvar $VAR_GROUP_MEMBERS group_members
39727c43fe1SDevin Teske		[ "$group_members" ] || null_members=1
39827c43fe1SDevin Teske	fi
39927c43fe1SDevin Teske	local group_password_disable=
40027c43fe1SDevin Teske	if f_isset $VAR_GROUP_PASSWORD; then
40127c43fe1SDevin Teske		f_getvar $VAR_GROUP_PASSWORD group_password
40227c43fe1SDevin Teske		[ "$group_password" ] || group_password_disable=1
40327c43fe1SDevin Teske	fi
40427c43fe1SDevin Teske
40527c43fe1SDevin Teske	#
40627c43fe1SDevin Teske	# Loop until the user decides to Exit, Cancel, or presses ESC
40727c43fe1SDevin Teske	#
40827c43fe1SDevin Teske	title="$msg_edit_view $msg_group: $group_name"
40927c43fe1SDevin Teske	if f_interactive; then
41027c43fe1SDevin Teske		local mtag retval defaultitem=
41127c43fe1SDevin Teske		while :; do
41227c43fe1SDevin Teske			f_dialog_title "$title"
41327c43fe1SDevin Teske			f_dialog_menu_group_edit "$defaultitem"
41427c43fe1SDevin Teske			retval=$?
41527c43fe1SDevin Teske			f_dialog_title_restore
41627c43fe1SDevin Teske			f_dialog_menutag_fetch mtag
41727c43fe1SDevin Teske			f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
41827c43fe1SDevin Teske			defaultitem="$mtag"
41927c43fe1SDevin Teske
42027c43fe1SDevin Teske			# Return if user either pressed ESC or chose Cancel/No
42127c43fe1SDevin Teske			[ $retval -eq $DIALOG_OK ] || return $FAILURE
42227c43fe1SDevin Teske
42327c43fe1SDevin Teske			case "$mtag" in
42427c43fe1SDevin Teske			X) # Save/Exit
425*b00c7d1aSDevin Teske			   local var
426*b00c7d1aSDevin Teske			   for var in gid members name; do
427*b00c7d1aSDevin Teske			   	local _group_$var
428*b00c7d1aSDevin Teske			   	eval f_shell_escape \
429*b00c7d1aSDevin Teske			   		\"\$group_$var\" _group_$var
430*b00c7d1aSDevin Teske			   done
431*b00c7d1aSDevin Teske
432*b00c7d1aSDevin Teske			   local cmd="pw groupmod -n '$_group_name'"
433*b00c7d1aSDevin Teske			   [ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
43427c43fe1SDevin Teske			   [ "$group_members" -o "$null_members" ] &&
435*b00c7d1aSDevin Teske			   	cmd="$cmd -M '$_group_members'"
43627c43fe1SDevin Teske
43727c43fe1SDevin Teske			   # Execute the command (break on success)
43827c43fe1SDevin Teske			   if [ "$group_password_disable" ]; then
43927c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s -h -' "$cmd"
44027c43fe1SDevin Teske			   elif [ "$group_password" ]; then
4417bac4bd2SDevin Teske			   	echo "$group_password" | f_eval_catch \
4427bac4bd2SDevin Teske			   		$funcname pw '%s -h 0' "$cmd"
44327c43fe1SDevin Teske			   else
44427c43fe1SDevin Teske			   	f_eval_catch $funcname pw '%s' "$cmd"
44527c43fe1SDevin Teske			   fi && break
44627c43fe1SDevin Teske			   ;;
44727c43fe1SDevin Teske			1) # Group Name (select different group from list)
44827c43fe1SDevin Teske			   f_dialog_menu_group_list "$group_name" || continue
44927c43fe1SDevin Teske			   f_dialog_menutag_fetch mtag
45027c43fe1SDevin Teske
45127c43fe1SDevin Teske			   [ "$mtag" = "X $msg_exit" ] && continue
45227c43fe1SDevin Teske
45327c43fe1SDevin Teske			   if ! f_input_group "$mtag"; then
45427c43fe1SDevin Teske			   	f_show_err "$msg_group_not_found" "$mtag"
4557bac4bd2SDevin Teske			   	# Attempt to fall back to previous selection
45627c43fe1SDevin Teske			   	f_input_group "$input" || return $FAILURE
45727c43fe1SDevin Teske			   else
45827c43fe1SDevin Teske			   	input="$mtag"
45927c43fe1SDevin Teske			   fi
46027c43fe1SDevin Teske			   title="$msg_edit_view $msg_group: $group_name"
46127c43fe1SDevin Teske			   ;;
46227c43fe1SDevin Teske			2) # Password
46327c43fe1SDevin Teske			   f_dialog_input_group_password group_password \
46427c43fe1SDevin Teske			   	group_password_disable
46527c43fe1SDevin Teske			   ;;
46627c43fe1SDevin Teske			3) # Group ID
46727c43fe1SDevin Teske			   f_dialog_input_group_gid group_gid "$group_gid"
46827c43fe1SDevin Teske			   ;;
46927c43fe1SDevin Teske			4) # Group Members
47027c43fe1SDevin Teske			   f_dialog_input_group_members group_members \
47127c43fe1SDevin Teske			   	"$group_members" && [ ! "$group_members" ] &&
47227c43fe1SDevin Teske			   	null_members=1
47327c43fe1SDevin Teske			   ;;
47427c43fe1SDevin Teske			esac
47527c43fe1SDevin Teske		done
47627c43fe1SDevin Teske	else
477*b00c7d1aSDevin Teske		local var
478*b00c7d1aSDevin Teske		for var in gid members name; do
479*b00c7d1aSDevin Teske			local _group_$var
480*b00c7d1aSDevin Teske			eval f_shell_escape \"\$group_$var\" _group_$var
481*b00c7d1aSDevin Teske		done
482*b00c7d1aSDevin Teske
48327c43fe1SDevin Teske		# Form the command
484*b00c7d1aSDevin Teske		local cmd="pw groupmod -n '$_group_name'"
485*b00c7d1aSDevin Teske		[ "$group_gid" ] && cmd="$cmd -g '$_group_gid'"
48627c43fe1SDevin Teske		[ "$group_members" -o "$null_members" ] &&
487*b00c7d1aSDevin Teske			cmd="$cmd -M '$_group_members'"
48827c43fe1SDevin Teske
48927c43fe1SDevin Teske		# Execute the command
49027c43fe1SDevin Teske		local retval err
49127c43fe1SDevin Teske		if [ "$group_password_disable" ]; then
49227c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
49327c43fe1SDevin Teske		elif [ "$group_password" -o "$null_password" ]; then
494faae0586SDevin Teske			err=$( echo "$group_password" | f_eval_catch -de \
495faae0586SDevin Teske				$funcname pw '%s -h 0' "$cmd" 2>&1 )
49627c43fe1SDevin Teske		else
49727c43fe1SDevin Teske			f_eval_catch -k err $funcname pw '%s' "$cmd"
49827c43fe1SDevin Teske		fi
49927c43fe1SDevin Teske		retval=$?
50027c43fe1SDevin Teske		if [ $retval -ne $SUCCESS ]; then
50127c43fe1SDevin Teske			f_show_err "%s" "$err"
50227c43fe1SDevin Teske			return $retval
50327c43fe1SDevin Teske		fi
50427c43fe1SDevin Teske	fi
50527c43fe1SDevin Teske
50627c43fe1SDevin Teske	f_dialog_title "$title"
50727c43fe1SDevin Teske	$alert "$msg_group_updated"
50827c43fe1SDevin Teske	f_dialog_title_restore
509160c4133SDevin Teske	[ "$no_confirm" -a "$USE_DIALOG" ] && sleep 1
51027c43fe1SDevin Teske
51127c43fe1SDevin Teske	return $SUCCESS
51227c43fe1SDevin Teske}
51327c43fe1SDevin Teske
51427c43fe1SDevin Teske############################################################ MAIN
51527c43fe1SDevin Teske
51627c43fe1SDevin Teskef_dprintf "%s: Successfully loaded." usermgmt/group.subr
51727c43fe1SDevin Teske
51827c43fe1SDevin Teskefi # ! $_USERMGMT_GROUP_SUBR
519