From 27c43fe1f3795622c5bd4bbfc465a29a800c0799 Mon Sep 17 00:00:00 2001 From: Devin Teske Date: Fri, 7 Mar 2014 20:44:19 +0000 Subject: [PATCH] Rewrite groupmgmt -- hooking it into the scripting system with dispatch commands groupAdd, groupDelete, and groupEdit. Getting rid of the awkward- to-use `groupinput' bolt-on which Ron and I talked about rewriting. --- usr.sbin/bsdconfig/share/script.subr | 6 + usr.sbin/bsdconfig/share/variable.subr | 6 +- usr.sbin/bsdconfig/usermgmt/Makefile | 4 +- usr.sbin/bsdconfig/usermgmt/groupadd | 19 +- usr.sbin/bsdconfig/usermgmt/groupdel | 8 +- usr.sbin/bsdconfig/usermgmt/groupedit | 18 +- usr.sbin/bsdconfig/usermgmt/groupinput | 293 ----------- .../bsdconfig/usermgmt/include/messages.subr | 4 +- usr.sbin/bsdconfig/usermgmt/share/Makefile | 2 +- usr.sbin/bsdconfig/usermgmt/share/group.subr | 484 ++++++++++++++++++ .../bsdconfig/usermgmt/share/group_input.subr | 423 ++++++++++----- 11 files changed, 827 insertions(+), 440 deletions(-) delete mode 100755 usr.sbin/bsdconfig/usermgmt/groupinput create mode 100644 usr.sbin/bsdconfig/usermgmt/share/group.subr diff --git a/usr.sbin/bsdconfig/share/script.subr b/usr.sbin/bsdconfig/share/script.subr index b947e47cff49..687991d17d5b 100644 --- a/usr.sbin/bsdconfig/share/script.subr +++ b/usr.sbin/bsdconfig/share/script.subr @@ -37,6 +37,7 @@ f_include $BSDCFG_SHARE/media/tcpip.subr f_include $BSDCFG_SHARE/mustberoot.subr f_include $BSDCFG_SHARE/networking/services.subr f_include $BSDCFG_SHARE/packages/packages.subr +f_include $BSDCFG_SHARE/usermgmt/group.subr f_include $BSDCFG_SHARE/variable.subr ############################################################ GLOBALS @@ -198,6 +199,11 @@ f_resword_new packageAdd f_package_add f_resword_new packageDelete f_package_delete f_resword_new packageReinstall f_package_reinstall +# usermgmt/group.subr +f_resword_new groupAdd f_group_add +f_resword_new groupDelete f_group_delete +f_resword_new groupEdit f_group_edit + # variable.subr f_resword_new installVarDefaults f_variable_set_defaults f_resword_new dumpVariables f_dump_variables diff --git a/usr.sbin/bsdconfig/share/variable.subr b/usr.sbin/bsdconfig/share/variable.subr index 55bc8506822e..98c525423cef 100644 --- a/usr.sbin/bsdconfig/share/variable.subr +++ b/usr.sbin/bsdconfig/share/variable.subr @@ -1,6 +1,6 @@ if [ ! "$_VARIABLE_SUBR" ]; then _VARIABLE_SUBR=1 # -# Copyright (c) 2012-2013 Devin Teske +# Copyright (c) 2012-2014 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -241,6 +241,10 @@ f_variable_new VAR_FTP_PORT ftpPort f_variable_new VAR_FTP_STATE ftpState f_variable_new VAR_FTP_USER ftpUser f_variable_new VAR_GATEWAY defaultrouter +f_variable_new VAR_GROUP group +f_variable_new VAR_GROUP_GID groupGid +f_variable_new VAR_GROUP_MEMBERS groupMembers +f_variable_new VAR_GROUP_PASSWORD groupPassword f_variable_new VAR_HOSTNAME hostname f_variable_new VAR_HTTP_DIR httpDirectory f_variable_new VAR_HTTP_FTP_MODE httpFtpMode diff --git a/usr.sbin/bsdconfig/usermgmt/Makefile b/usr.sbin/bsdconfig/usermgmt/Makefile index 910d380622d3..f4340eec806b 100644 --- a/usr.sbin/bsdconfig/usermgmt/Makefile +++ b/usr.sbin/bsdconfig/usermgmt/Makefile @@ -8,8 +8,8 @@ FILESDIR= ${LIBEXECDIR}/bsdconfig/070.usermgmt FILES= INDEX USAGE SCRIPTSDIR= ${FILESDIR} -SCRIPTS= groupadd groupdel groupedit groupinput \ - useradd userdel useredit userinput usermgmt +SCRIPTS= groupadd groupdel groupedit useradd userdel useredit \ + userinput usermgmt beforeinstall: mkdir -p ${DESTDIR}${FILESDIR} diff --git a/usr.sbin/bsdconfig/usermgmt/groupadd b/usr.sbin/bsdconfig/usermgmt/groupadd index 62f062d85ecf..e40085dc6771 100755 --- a/usr.sbin/bsdconfig/usermgmt/groupadd +++ b/usr.sbin/bsdconfig/usermgmt/groupadd @@ -1,7 +1,7 @@ #!/bin/sh #- # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2013 Devin Teske +# Copyright (c) 2012-2014 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,8 +33,11 @@ BSDCFG_SHARE="/usr/share/bsdconfig" . $BSDCFG_SHARE/common.subr || exit 1 f_dprintf "%s: loading includes..." "$0" f_include $BSDCFG_SHARE/dialog.subr +f_include $BSDCFG_SHARE/mustberoot.subr +f_include $BSDCFG_SHARE/usermgmt/group.subr BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" +f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && pgm="${ipgm:-$pgm}" @@ -55,9 +58,19 @@ done shift $(( $OPTIND - 1 )) # -# Chain-load to groupinput to centralize code and minimize duplication +# Initialize # -$BSDCFG_LIBE/$APP_DIR/groupinput ${USE_XDIALOG:+-X} mode="Add" +f_dialog_title "$msg_add $msg_group" +f_dialog_backtitle "${ipgm:+bsdconfig }$pgm" +f_mustberoot_init + +# +# Add a user +# +# NB: If given an argument on the command-line use it; otherwise fall-back to +# environment variable $group (handle $VAR_GROUP). +# +f_group_add ${1:+"$1"} ################################################################################ # END diff --git a/usr.sbin/bsdconfig/usermgmt/groupdel b/usr.sbin/bsdconfig/usermgmt/groupdel index aa1c305ad04d..a4a038247aa4 100755 --- a/usr.sbin/bsdconfig/usermgmt/groupdel +++ b/usr.sbin/bsdconfig/usermgmt/groupdel @@ -1,7 +1,7 @@ #!/bin/sh #- # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2013 Devin Teske +# Copyright (c) 2012-2014 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -34,6 +34,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig" f_dprintf "%s: loading includes..." "$0" f_include $BSDCFG_SHARE/dialog.subr f_include $BSDCFG_SHARE/mustberoot.subr +f_include $BSDCFG_SHARE/usermgmt/group.subr f_include $BSDCFG_SHARE/usermgmt/group_input.subr BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" @@ -67,7 +68,7 @@ f_mustberoot_init # # Loop until the user Exits, Cancels or presses ESC # -defaultitem="" +defaultitem= while :; do f_dialog_menu_group_list "$defaultitem" retval=$? @@ -81,8 +82,7 @@ while :; do # Anything else is a group name - $BSDCFG_LIBE/$APP_DIR/groupinput \ - ${USE_XDIALOG:+-X} mode="Delete" group="$mtag" + f_group_delete "$mtag" done exit $SUCCESS diff --git a/usr.sbin/bsdconfig/usermgmt/groupedit b/usr.sbin/bsdconfig/usermgmt/groupedit index 953f4f567487..2338d5732270 100755 --- a/usr.sbin/bsdconfig/usermgmt/groupedit +++ b/usr.sbin/bsdconfig/usermgmt/groupedit @@ -1,7 +1,7 @@ #!/bin/sh #- # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2013 Devin Teske +# Copyright (c) 2012-2014 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -34,6 +34,7 @@ BSDCFG_SHARE="/usr/share/bsdconfig" f_dprintf "%s: loading includes..." "$0" f_include $BSDCFG_SHARE/dialog.subr f_include $BSDCFG_SHARE/mustberoot.subr +f_include $BSDCFG_SHARE/usermgmt/group.subr f_include $BSDCFG_SHARE/usermgmt/group_input.subr BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" @@ -65,9 +66,17 @@ f_dialog_backtitle "${ipgm:+bsdconfig }$pgm" f_mustberoot_init # -# Loop until the user Exits, Cancels or presses ESC +# If given a group name, operate on it and exit # -defaultitem="" +if [ "$1" ]; then + f_group_edit "$1" + exit $SUCCESS +fi + +# +# Present a list of groups and loop until user Exits, Cancels or presses ESC +# +defaultitem= while :; do f_dialog_menu_group_list "$defaultitem" retval=$? @@ -81,8 +90,7 @@ while :; do # Anything else is a group name - $BSDCFG_LIBE/$APP_DIR/groupinput \ - ${USE_XDIALOG:+-X} mode="Edit/View" group="$mtag" + f_group_edit "$mtag" done exit $SUCCESS diff --git a/usr.sbin/bsdconfig/usermgmt/groupinput b/usr.sbin/bsdconfig/usermgmt/groupinput deleted file mode 100755 index f98e890b6035..000000000000 --- a/usr.sbin/bsdconfig/usermgmt/groupinput +++ /dev/null @@ -1,293 +0,0 @@ -#!/bin/sh -#- -# Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2013 Devin Teske -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ -# -############################################################ INCLUDES - -BSDCFG_SHARE="/usr/share/bsdconfig" -. $BSDCFG_SHARE/common.subr || exit 1 -f_dprintf "%s: loading includes..." "$0" -f_include $BSDCFG_SHARE/dialog.subr -f_include $BSDCFG_SHARE/mustberoot.subr -f_include $BSDCFG_SHARE/usermgmt/group_input.subr - -BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" -f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr - -f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && - pgm="${ipgm:-$pgm}" - -############################################################ CONFIGURATION - -# set some reasonable defaults if /etc/adduser.conf does not exist. -[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf -: ${passwdtype:="yes"} - -############################################################ FUNCTIONS - -# save_changes -# -# Save any/all settings (actions performed depend on $mode value). -# -save_changes() -{ - local funcname=save_changes - - case "$mode" in - Delete) - f_eval_catch $funcname pw 'pw groupdel "%s"' "$group_name" || - return $? - f_show_msg "$msg_group_deleted" - ;; - Add) - local cmd="pw groupadd -n '$group_name'" - [ "$group_gid" ] && cmd="$cmd -g '$group_gid'" - [ "$group_members" != "$cur_group_members" ] && - cmd="$cmd -M '$group_members'" - if [ "$pw_group_password_disable" ]; then - f_eval_catch $funcname pw '%s -h -' "$cmd" - elif [ "$group_password" ]; then - echo "$group_password" | - f_eval_catch $funcname pw '%s -h 0' "$cmd" - else - f_eval_catch $funcname pw '%s' "$cmd" - fi || return $? - f_show_msg "$msg_group_added" - ;; - Edit/View) - local cmd="pw groupmod -n '$group_name'" - [ "$group_gid" ] && cmd="$cmd -g '$group_gid'" - [ "$group_members" != "$cur_group_members" ] && - cmd="$cmd -M '$group_members'" - if [ "$pw_group_password_disable" ]; then - f_eval_catch $funcname pw '%s -h -' "$cmd" - elif [ "$group_password" ]; then - echo "$group_password" | - f_eval_catch $funcname pw '%s -h 0' "$cmd" - else - f_eval_catch $funcname pw '%s' "$cmd" - fi || return $? - f_show_msg "$msg_group_updated" - ;; - esac - - save_flag= - return $SUCCESS -} - -# dialog_title_update $mode -# -# Set the title based on the given $mode. -# -dialog_title_update() -{ - local mode="$1" - case "$mode" in - Add) f_dialog_title "$msg_add $msg_group" ;; - Edit/View) f_dialog_title "$msg_edit_view $msg_group: $group" ;; - Delete) f_dialog_title "$msg_delete $msg_group: $group" ;; - esac -} - -############################################################ MAIN - -# Incorporate rc-file if it exists -[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" - -# -# Process command-line arguments -# -while [ $# -gt 0 ]; do - key="${1%%=*}" - value="${1#*=}" - f_dprintf "key=[%s] value=[%s]" "$key" "$value" - case "$key" in - mode) mode="$value" ;; - group) group="$value" ;; - esac - shift -done -f_dprintf "mode=[%s] group=[%s]" "$mode" "$group" - -# -# Initialize -# -dialog_title_update "$mode" -f_dialog_backtitle "${ipgm:+bsdconfig }$pgm" -f_mustberoot_init -menu_text= -save_flag= -hline="$hline_arrows_tab_enter" - -if [ "$mode" = "Add" ]; then - f_dialog_input_group_name || exit 0 - - f_dialog_noyes "$msg_use_default_values_for_all_account_details" - retval=$? - - if [ $retval -eq $DIALOG_ESC ]; then - exit $SUCCESS - elif [ $retval -ne $DIALOG_OK ]; then - # - # Ask a series of questions to pre-fill the editor screen. - # - # The defaults used in each dialog should allow the user to - # simply hit ENTER to proceed, because cancelling a single - # dialog will cause them to be returned to the main groupmenu. - # - - [ "$passwdtype" = "yes" ] && - { f_dialog_input_group_password || exit $SUCCESS; } - f_dialog_input_group_gid || exit $SUCCESS - f_dialog_input_group_members || exit $SUCCESS - fi -fi - -if [ "$mode" = "Edit/View" -o "$mode" = "Delete" ]; then - f_input_group "$group" || f_die 1 "$msg_group_not_found" -fi - -cur_group_name="$group_name" -cur_group_password="$group_password" -cur_group_gid="$group_gid" -cur_group_members="$group_members" - -[ "$mode" = "Delete" ] && save_flag=1 - -# -# Loop until the user decides to Exit, Cancel, or presses ESC -# -while :; do - dialog_title_update "$mode" - - menu_text= - menu_exit="$msg_exit" - if [ "$save_flag" ]; then - if [ "$mode" = "Delete" ]; then - menu_exit="$msg_delete/$msg_exit" - menu_text="$msg_delete_exit_or_cancel" - else - menu_exit="$msg_save/$msg_exit" - menu_text="$msg_save_exit_or_cancel" - fi - fi - - case "$mode" in - Delete) - menu_items=" - 'X' '$menu_exit' - '1' '$msg_group: $group_name' - '-' '$msg_password: -----' - '-' '$msg_group_id: $group_gid' - '-' '$msg_group_members: $group_members' - " # END-QUOTE - ;; - *) - menu_items=" - 'X' '$menu_exit' - '1' '$msg_group: $group_name' - '2' '$msg_password: -----' - '3' '$msg_group_id: $group_gid' - '4' '$msg_group_members: $group_members' - " # END-QUOTE - esac - - eval f_dialog_menu_size height width rows \ - \"\$DIALOG_TITLE\" \ - \"\$DIALOG_BACKTITLE\" \ - \"\$menu_text\" \ - \"\$hline\" \ - $menu_items - - f_dialog_default_fetch defaultitem - mtag=$( eval $DIALOG \ - --title \"\$DIALOG_TITLE\" \ - --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ - --ok-label \"\$msg_ok\" \ - --cancel-label \"\$msg_cancel\" \ - --default-item \"\$defaultitem\" \ - --menu \"\$menu_text\" \ - $height $width $rows \ - $menu_items \ - 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD - ) - retval=$? - f_dialog_data_sanitize mtag - f_dialog_default_store "$mtag" - f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" - - # Exit if user has either pressed ESC or chosen Cancel/No - [ $retval -eq $DIALOG_OK ] || f_die - - case "$mtag" in - X) # Exit - [ "$save_flag" ] && { save_changes || continue; } - break - ;; - 1) # Group Name - case "$mode" in - Add) f_dialog_input_group_name "$group_name" ;; - Edit/View|Delete) - f_dialog_menu_group_list "$group_name" - retval=$? - f_dialog_menutag_fetch mtag - f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" - - # Loop if user has either pressed ESC or chosen Cancel/No - [ $retval -eq $DIALOG_OK ] || continue - - [ "$mtag" = "X $msg_exit" ] && continue - - group="$mtag" - f_input_group "$group" || f_die 1 "$msg_group_not_found" - cur_group_name="$group_name" - cur_group_password="$group_password" - cur_group_gid="$group_gid" - cur_group_members="$group_members" - [ "$mode" != "Delete" ] && save_flag= - esac - ;; - 2) # Password - f_dialog_input_group_password - ;; - 3) # GID - f_dialog_input_group_gid "$group_gid" - ;; - 4) # Users in Group - f_dialog_input_group_members "$group_members" - ;; - esac - -done - -exit $SUCCESS - -################################################################################ -# END -################################################################################ diff --git a/usr.sbin/bsdconfig/usermgmt/include/messages.subr b/usr.sbin/bsdconfig/usermgmt/include/messages.subr index e139f32b7109..97f899ba1f87 100644 --- a/usr.sbin/bsdconfig/usermgmt/include/messages.subr +++ b/usr.sbin/bsdconfig/usermgmt/include/messages.subr @@ -1,5 +1,5 @@ # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2013 Devin Teske +# Copyright (c) 2012-2014 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -90,6 +90,7 @@ msg_login_updated="Login Updated" msg_member_of_groups="Member of Groups" msg_n_a="N/A" msg_no="No" +msg_no_group_specified="No group specified!" msg_number_of_seconds_since_epoch="Number of seconds since the Epoch\n(1 = %s)\nNULL or zero to disable:" msg_ok="OK" msg_password="Password" @@ -97,6 +98,7 @@ msg_password_does_not_expire="Password does not expire" msg_password_expires_in_how_many_days="Password expires in how many days?" msg_password_expires_on="Password Expires on" msg_passwords_do_not_match="Passwords do not match." +msg_please_enter_a_group_name="Please enter a group name!" msg_reenter_group_password="Re-enter Group Password" msg_reenter_password="Re-enter Password" msg_save="Save" diff --git a/usr.sbin/bsdconfig/usermgmt/share/Makefile b/usr.sbin/bsdconfig/usermgmt/share/Makefile index d6b9e3a57746..f0fdcedf3212 100644 --- a/usr.sbin/bsdconfig/usermgmt/share/Makefile +++ b/usr.sbin/bsdconfig/usermgmt/share/Makefile @@ -3,7 +3,7 @@ NO_OBJ= FILESDIR= ${SHAREDIR}/bsdconfig/usermgmt -FILES= group_input.subr user_input.subr +FILES= group.subr group_input.subr user_input.subr beforeinstall: mkdir -p ${DESTDIR}${FILESDIR} diff --git a/usr.sbin/bsdconfig/usermgmt/share/group.subr b/usr.sbin/bsdconfig/usermgmt/share/group.subr new file mode 100644 index 000000000000..ee60f780eeca --- /dev/null +++ b/usr.sbin/bsdconfig/usermgmt/share/group.subr @@ -0,0 +1,484 @@ +if [ ! "$_USERMGMT_GROUP_SUBR" ]; then _USERMGMT_GROUP_SUBR=1 +# +# Copyright (c) 2012 Ron McDowell +# Copyright (c) 2012-2014 Devin Teske +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# +############################################################ INCLUDES + +BSDCFG_SHARE="/usr/share/bsdconfig" +. $BSDCFG_SHARE/common.subr || exit 1 +f_dprintf "%s: loading includes..." usermgmt/group.subr +f_include $BSDCFG_SHARE/dialog.subr +f_include $BSDCFG_SHARE/usermgmt/group_input.subr + +BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" +f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr + +############################################################ CONFIGURATION + +# set some reasonable defaults if /etc/adduser.conf does not exist. +[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf +: ${passwdtype:="yes"} + +############################################################ FUNCTIONS + +# f_group_add [$group] +# +# Add a group. If both $group (as a first argument) and $VAR_GROUP are unset +# or NULL and we are running interactively, prompt the user to enter the name +# of a new group and (if $VAR_NO_CONFIRM is unset or NULL) prompt the user to +# answer some questions about the new group. Variables that can be used to +# script user input: +# +# VAR_GROUP [Optional if running interactively] +# The group to add. Ignored if given non-NULL first-argument. +# VAR_GROUP_GID [Optional] +# Numerical group ID to use. If NULL or unset, the group ID is +# automatically chosen. +# VAR_GROUP_MEMBERS [Optional] +# Comma separated list of users that are a member of this group. +# VAR_GROUP_PASSWORD [Optional] +# newgrp(1) password to set for the group. Default if NULL or +# unset is to disable newgrp(1) password authentication. +# +# Returns success if the group was successfully added. +# +f_group_add() +{ + local funcname=f_group_add + local title # Calculated below + local alert=f_show_msg no_confirm= + + f_getvar $VAR_NO_CONFIRM no_confirm + [ "$no_confirm" ] && alert=f_show_info + + local input + f_getvar 3:-\$$VAR_GROUP input "$1" + + # + # NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID + # instead of name. Work-around is to also pass `-g GID' at the same + # time (any GID will do; but `-1' is appropriate for this context). + # + if [ "$input" ] && f_quietly pw groupshow -n "$input" -g -1; then + f_show_err "$msg_group_already_used" "$input" + return $FAILURE + fi + + local group_name="$input" + while f_interactive && [ ! "$group_name" ]; do + f_dialog_input_group_name group_name "$group_name" || + return $SUCCESS + [ "$group_name" ] || + f_show_err "$msg_please_enter_a_group_name" + done + + local group_password group_gid group_members + f_getvar $VAR_GROUP_PASSWORD group_password + f_getvar $VAR_GROUP_GID group_gid + f_getvar $VAR_GROUP_MEMBERS group_members + + local group_password_disable= + f_interactive || [ "$group_password" ] || group_password_disable=1 + + if f_interactive && [ ! "$no_confirm" ]; then + f_dialog_noyes \ + "$msg_use_default_values_for_all_account_details" + retval=$? + if [ $retval -eq $DIALOG_ESC ]; then + return $SUCCESS + elif [ $retval -ne $DIALOG_OK ]; then + # + # Ask series of questions to pre-fill the editor screen + # + # Defaults used in each dialog should allow the user to + # simply hit ENTER to proceed and cancelling a single + # dialog cause them to return to the previous menu. + # + + if [ "$passwdtype" = "yes" ]; then + f_dialog_input_group_password group_password \ + group_password_disable || + return $FAILURE + fi + f_dialog_input_group_gid group_gid "$group_gid" || + return $FAILURE + f_dialog_input_group_members group_members \ + "$group_members" || return $FAILURE + fi + fi + + # + # Loop until the user decides to Exit, Cancel, or presses ESC + # + title="$msg_add $msg_group: $group_name" + if f_interactive; then + local mtag retval defaultitem= + while :; do + f_dialog_title "$title" + f_dialog_menu_group_add "$defaultitem" + retval=$? + f_dialog_title_restore + f_dialog_menutag_fetch mtag + f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" + defaultitem="$mtag" + + # Return if user either pressed ESC or chose Cancel/No + [ $retval -eq $DIALOG_OK ] || return $FAILURE + + case "$mtag" in + X) # Add/Exit + local cmd="pw groupadd -n '$group_name'" + [ "$group_gid" ] && cmd="$cmd -g '$group_gid'" + [ "$group_members" ] && + cmd="$cmd -M '$group_members'" + + # Execute the command (break on success) + if [ "$group_password_disable" ]; then + f_eval_catch $funcname pw '%s -h -' "$cmd" + elif [ "$group_password" ]; then + echo "$group_password" | + f_eval_catch $funcname \ + pw '%s -h 0' "$cmd" + else + f_eval_catch $funcname pw '%s' "$cmd" + fi && break + ;; + 1) # Group Name (prompt for new group name) + f_dialog_input_group_name input "$group_name" || + continue + if f_quietly pw groupshow -n "$input" -g -1; then + f_show_err "$msg_group_already_used" "$input" + continue + fi + group_name="$input" + title="$msg_add $msg_group: $group_name" + ;; + 2) # Password + f_dialog_input_group_password group_password \ + group_password_disable + ;; + 3) # Group ID + f_dialog_input_group_gid group_gid "$group_gid" + ;; + 4) # Group Members + f_dialog_input_group_members group_members \ + "$group_members" + ;; + esac + done + else + # Form the command + local cmd="pw groupadd -n '$group_name'" + [ "$group_gid" ] && cmd="$cmd -g '$group_gid'" + [ "$group_members" ] && cmd="$cmd -M '$group_members'" + + # Execute the command + local retval err + if [ "$group_password_disable" ]; then + f_eval_catch -k err $funcname pw '%s -h -' "$cmd" + elif [ "$group_password" ]; then + echo "$group_password" | f_eval_catch -k err \ + $funcname pw '%s -h 0' "$cmd" + else + f_eval_catch -k err $funcname pw '%s' "$cmd" + fi + retval=$? + if [ $retval -ne $SUCCESS ]; then + f_show_err "%s" "$err" + return $retval + fi + fi + + f_dialog_title "$title" + $alert "$msg_group_added" + f_dialog_title_restore + [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2 + + return $SUCCESS +} + +# f_group_delete [$group] +# +# Delete a group. If both $group (as a first argument) and $VAR_GROUP are unset +# or NULL and we are running interactively, prompt the user to select a group +# from a list of available groups. Variables that can be used to script user +# input: +# +# VAR_GROUP [Optional if running interactively] +# The group to delete. Ignored if given non-NULL first-argument. +# +# Returns success if the group was successfully deleted. +# +f_group_delete() +{ + local funcname=f_group_delete + local title # Calculated below + local alert=f_show_msg no_confirm= + + f_getvar $VAR_NO_CONFIRM no_confirm + [ "$no_confirm" ] && alert=f_show_info + + local input + f_getvar 3:-\$$VAR_GROUP input "$1" + + local group_name group_password group_gid group_members + if [ "$input" ] && ! f_input_group "$input"; then + f_show_err "$msg_group_not_found" "$input" + return $FAILURE + fi + + # + # Loop until the user decides to Exit, Cancel, or presses ESC + # + title="$msg_delete $msg_group: $group_name" + if f_interactive; then + local mtag retval defaultitem= + while :; do + f_dialog_title "$title" + f_dialog_menu_group_delete "$group_name" "$defaultitem" + retval=$? + f_dialog_title_restore + f_dialog_menutag_fetch mtag + f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" + defaultitem="$mtag" + + # Return if user either pressed ESC or chose Cancel/No + [ $retval -eq $DIALOG_OK ] || return $FAILURE + + case "$mtag" in + X) # Delete/Exit + f_eval_catch $funcname pw 'pw groupdel "%s"' \ + "$group_name" && break + ;; + 1) # Group Name (select different group from list) + f_dialog_menu_group_list "$group_name" || continue + f_dialog_menutag_fetch mtag + + [ "$mtag" = "X $msg_exit" ] && continue + + if ! f_input_group "$mtag"; then + f_show_err "$msg_group_not_found" "$mtag" + # Attempt to fall back to previous selection + f_input_group "$input" || return $FAILURE + else + input="$mtag" + fi + ;; + esac + done + else + local retval err + f_eval_catch -k err $funcname pw \ + 'pw groupdel "%s"' "$group_name" + retval=$? + if [ $retval -ne $SUCCESS ]; then + f_show_err "%s" "$err" + return $retval + fi + fi + + f_dialog_title "$title" + $alert "$msg_group_deleted" + f_dialog_title_restore + [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2 + + return $SUCCESS +} + +# f_group_edit [$group] +# +# Modify a group. If both $group (as a first argument) and $VAR_GROUP are unset +# or NULL and we are running interactively, prompt the user to select a group +# from a list of available groups. Variables that can be used to script user +# input: +# +# VAR_GROUP [Optional if running interactively] +# The group to modify. Ignored if given non-NULL first-argument. +# VAR_GROUP_GID [Optional] +# Numerical group ID to set. If NULL or unset, the group ID is +# unchanged. +# VAR_GROUP_MEMBERS [Optional] +# Comma separated list of users that are a member of this group. +# If NULL or unset, group membership is unmodified. +# VAR_GROUP_PASSWORD [Optional] +# newgrp(1) password to set for the group. If unset, the password +# is unmodified. If NULL, the newgrp(1) password is disabled. +# +# Returns success if the group was successfully modified. +# +f_group_edit() +{ + local funcname=f_group_edit + local title # Calculated below + local alert=f_show_msg no_confirm= + + f_getvar $VAR_NO_CONFIRM no_confirm + [ "$no_confirm" ] && alert=f_show_info + + local input + f_getvar 3:-\$$VAR_GROUP input "$1" + + # + # NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID + # instead of name. Work-around is to also pass `-g GID' at the same + # time (any GID will do; but `-1' is appropriate for this context). + # + if [ "$input" ] && ! f_quietly pw groupshow -n "$input" -g -1; then + f_show_err "$msg_group_not_found" "$input" + return $FAILURE + fi + + if f_interactive && [ ! "$input" ]; then + f_dialog_menu_group_list || return $SUCCESS + f_dialog_menutag_fetch input + [ "$input" = "X $msg_exit" ] && return $SUCCESS + elif [ ! "$input" ]; then + f_show_err "$msg_no_group_specified" + return $FAILURE + fi + + local group_name group_password group_gid group_members + if ! f_input_group "$input"; then + f_show_err "$msg_group_not_found" "$input" + return $FAILURE + fi + + f_isset $VAR_GROUP_GID && f_getvar $VAR_GROUP_GID group_gid + local null_members= + if f_isset $VAR_GROUP_MEMBERS; then + f_getvar $VAR_GROUP_MEMBERS group_members + [ "$group_members" ] || null_members=1 + fi + local group_password_disable= + if f_isset $VAR_GROUP_PASSWORD; then + f_getvar $VAR_GROUP_PASSWORD group_password + [ "$group_password" ] || group_password_disable=1 + fi + + # + # Loop until the user decides to Exit, Cancel, or presses ESC + # + title="$msg_edit_view $msg_group: $group_name" + if f_interactive; then + local mtag retval defaultitem= + while :; do + f_dialog_title "$title" + f_dialog_menu_group_edit "$defaultitem" + retval=$? + f_dialog_title_restore + f_dialog_menutag_fetch mtag + f_dprintf "retval=%u mtag=[%s]" $retval "$mtag" + defaultitem="$mtag" + + # Return if user either pressed ESC or chose Cancel/No + [ $retval -eq $DIALOG_OK ] || return $FAILURE + + case "$mtag" in + X) # Save/Exit + local cmd="pw groupmod -n '$group_name'" + [ "$group_gid" ] && cmd="$cmd -g '$group_gid'" + [ "$group_members" -o "$null_members" ] && + cmd="$cmd -M '$group_members'" + + # Execute the command (break on success) + if [ "$group_password_disable" ]; then + f_eval_catch $funcname pw '%s -h -' "$cmd" + elif [ "$group_password" ]; then + echo "$group_password" | + f_eval_catch $funcname \ + pw '%s -h 0' "$cmd" + else + f_eval_catch $funcname pw '%s' "$cmd" + fi && break + ;; + 1) # Group Name (select different group from list) + f_dialog_menu_group_list "$group_name" || continue + f_dialog_menutag_fetch mtag + + [ "$mtag" = "X $msg_exit" ] && continue + + if ! f_input_group "$mtag"; then + f_show_err "$msg_group_not_found" "$mtag" + # Attempt to fall back to prevoius selection + f_input_group "$input" || return $FAILURE + else + input="$mtag" + fi + title="$msg_edit_view $msg_group: $group_name" + ;; + 2) # Password + f_dialog_input_group_password group_password \ + group_password_disable + ;; + 3) # Group ID + f_dialog_input_group_gid group_gid "$group_gid" + ;; + 4) # Group Members + f_dialog_input_group_members group_members \ + "$group_members" && [ ! "$group_members" ] && + null_members=1 + ;; + esac + done + else + # Form the command + local cmd="pw groupmod -n '$group_name'" + [ "$group_gid" ] && cmd="$cmd -g '$group_gid'" + [ "$group_members" -o "$null_members" ] && + cmd="$cmd -M '$group_members'" + + # Execute the command + local retval err + if [ "$group_password_disable" ]; then + f_eval_catch -k err $funcname pw '%s -h -' "$cmd" + elif [ "$group_password" -o "$null_password" ]; then + echo "$group_password" | f_eval_catch -k err \ + $funcname pw '%s -h 0' "$cmd" + else + f_eval_catch -k err $funcname pw '%s' "$cmd" + fi + retval=$? + if [ $retval -ne $SUCCESS ]; then + f_show_err "%s" "$err" + return $retval + fi + fi + + f_dialog_title "$title" + $alert "$msg_group_updated" + f_dialog_title_restore + [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2 + + return $SUCCESS +} + +############################################################ MAIN + +f_dprintf "%s: Successfully loaded." usermgmt/group.subr + +fi # ! $_USERMGMT_GROUP_SUBR diff --git a/usr.sbin/bsdconfig/usermgmt/share/group_input.subr b/usr.sbin/bsdconfig/usermgmt/share/group_input.subr index e0f47f75f506..cd0571ca89f5 100644 --- a/usr.sbin/bsdconfig/usermgmt/share/group_input.subr +++ b/usr.sbin/bsdconfig/usermgmt/share/group_input.subr @@ -1,7 +1,7 @@ if [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1 # # Copyright (c) 2012 Ron McDowell -# Copyright (c) 2012-2013 Devin Teske +# Copyright (c) 2012-2014 Devin Teske # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -48,14 +48,20 @@ f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr # f_input_group() { - eval $( pw groupshow "$1" | awk -F: ' + local funcname=f_input_group + local group="$1" + + f_dprintf "$funcname: Getting info for group \`%s'" "$group" + eval "$( pw groupshow "$group" 2> /dev/null | awk -F: ' { + found = $1 != "" printf "group_name='\'%s\''\n", $1 printf "group_password=\n" printf "group_gid='\'%s\''\n", $3 printf "group_members='\'%s\''\n", $4 exit - }' ) + } + END { if (!found) print "false" }' )" } # f_dialog_menu_group_list [$default] @@ -105,300 +111,457 @@ f_dialog_menu_group_list() return $retval } -# f_dialog_input_group_name [$group_name] +# f_dialog_input_group_name $var_to_set [$group_name] # -# Allows the user to enter a new groupname for a given group. If the user does -# not cancel or press ESC, the $group_name variable will hold the -# newly-configured value upon return. -# -# If $cur_group_name is defined, the user can enter that and by-pass error- -# checking (allowing the user to "revert" to an old value without, for example, -# being told that the groupname already exists). +# Allows the user to enter a name for a new group. If the user does not cancel +# or press ESC, the $var_to_set variable will hold the newly-configured value +# upon return. # f_dialog_input_group_name() { + local __var_to_set="$1" __name="$2" + # # Loop until the user provides taint-free/valid input # - local _name="$1" _input="$1" + local __input="$__name" while :; do - # Return if user has either pressed ESC or chosen Cancel/No - f_dialog_input _input "$msg_group" "$_input" \ + f_dialog_input __input "$msg_group" "$__input" \ "$hline_alnum_tab_enter" || return $? # Check for no-change - [ "$_input" = "$_name" ] && return $DIALOG_OK - - # Check for reversion - if [ "$_input" = "$cur_group_name" ]; then - group_name="$cur_group_name" + if [ "$__input" = "$__name" ]; then + setvar "$__var_to_set" "$__input" return $DIALOG_OK fi # Check for NULL entry - if [ ! "$_input" ]; then + if [ ! "$__input" ]; then f_show_msg "$msg_group_is_empty" continue fi # Check for invalid entry - if ! echo "$_input" | grep -q "^[[:alpha:]]"; then + case "$__input" in [!a-zA-Z]*) f_show_msg "$msg_group_must_start_with_letter" continue - fi + esac # Check for duplicate entry - if f_quietly pw groupshow -n "$_input"; then - f_show_msg "$msg_group_already_used" "$_input" + if f_quietly pw groupshow -n "$__input"; then + f_show_msg "$msg_group_already_used" "$__input" continue fi - group_name="$_input" + setvar "$__var_to_set" "$__input" break done save_flag=1 - f_dprintf "group_name: [%s]->[%s]" "$cur_group_name" "$group_name" - return $DIALOG_OK } -# f_dialog_input_group_password +# f_dialog_input_group_password $var_to_set $dvar_to_set # -# Prompt the user to enter a password (twice). +# Prompt the user to enter a password (twice). If the user does not cancel or +# press ESC, $var_to_set will hold the confirmed user entry. Otherwise, if the +# user cancels or enters a NULL password (twice), they are given the choice to +# disable password authentication for the given group, wherein $dvar_to_set has +# a value of 1 to indicate password authentication should be disabled. # f_dialog_input_group_password() { - local prompt1="$msg_group_password" - local prompt2="$msg_reenter_group_password" - local hline="$hline_alnum_punc_tab_enter" + local __var_to_set="$1" __dvar_to_set="$2" + local __prompt1="$msg_group_password" + local __prompt2="$msg_reenter_group_password" + local __hline="$hline_alnum_punc_tab_enter" - local height1 width1 - f_dialog_inputbox_size height1 width1 \ + local __height1 __width1 + f_dialog_inputbox_size __height1 __width1 \ "$DIALOG_TITLE" \ "$DIALOG_BACKTITLE" \ - "$prompt1" \ + "$__prompt1" \ "" \ - "$hline" + "$__hline" - local height2 width2 - f_dialog_inputbox_size height2 width2 \ + local __height2 __width2 + f_dialog_inputbox_size __height2 __width2 \ "$DIALOG_TITLE" \ "$DIALOG_BACKTITLE" \ - "$prompt2" \ + "$__prompt2" \ "" \ - "$hline" + "$__hline" # # Loop until the user provides taint-free/valid input # - local retval _password1 _password2 + local __retval __password1 __password2 while :; do - _password1=$( $DIALOG \ + __password1=$( $DIALOG \ --title "$DIALOG_TITLE" \ --backtitle "$DIALOG_BACKTITLE" \ - --hline "$hline" \ + --hline "$__hline" \ --ok-label "$msg_ok" \ --cancel-label "$msg_cancel" \ --insecure \ - --passwordbox "$prompt1" \ - $height1 $width1 \ + --passwordbox "$__prompt1" \ + $__height1 $__width1 \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) - retval=$? - debug= f_dialog_line_sanitize _password1 + __retval=$? + debug= f_dialog_line_sanitize __password1 # Return if user has either pressed ESC or chosen Cancel/No - [ $retval -eq $DIALOG_OK ] || return $retval + [ $__retval -eq $DIALOG_OK ] || return $__retval - _password2=$( $DIALOG \ + __password2=$( $DIALOG \ --title "$DIALOG_TITLE" \ --backtitle "$DIALOG_BACKTITLE" \ - --hline "$hline" \ + --hline "$__hline" \ --ok-label "$msg_ok" \ --cancel-label "$msg_cancel" \ --insecure \ - --passwordbox "$prompt2" \ - $height2 $width2 \ + --passwordbox "$__prompt2" \ + $__height2 $__width2 \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) - retval=$? - debug= f_dialog_line_sanitize _password2 + __retval=$? + debug= f_dialog_line_sanitize __password2 # Return if user has either pressed ESC or chosen Cancel/No - [ $retval -eq $DIALOG_OK ] || return $retval + [ $__retval -eq $DIALOG_OK ] || return $__retval # Check for password mismatch - if [ "$_password1" != "$_password2" ]; then + if [ "$__password1" != "$__password2" ]; then f_show_msg "$msg_group_passwords_do_not_match" continue fi # Check for NULL entry - if [ ! "$_password1" ]; then + if [ ! "$__password1" ]; then f_dialog_yesno "$msg_disable_password_auth_for_group" - local retval=$? - if [ $retval -eq $DIALOG_ESC ]; then - return $retval - elif [ $retval -eq $DIALOG_OK ]; then - pw_group_password_disable=1 + __retval=$? + if [ $__retval -eq $DIALOG_ESC ]; then + return $__retval + elif [ $__retval -eq $DIALOG_OK ]; then + setvar "$__dvar_to_set" 1 else continue # back to password prompt fi else - pw_group_password_disable= + setvar "$__dvar_to_set" "" fi - group_password="$_password1" + setvar "$__var_to_set" "$__password1" break done save_flag=1 - f_dprintf "group_password: [%s]->[%s]" \ - "$cur_group_password" "$group_password" - return $DIALOG_OK } -# f_dialog_input_group_gid [$group_gid] +# f_dialog_input_group_gid $var_to_set [$group_gid] # # Allow the user to enter a new GID for a given group. If the user does not -# cancel or press ESC, the $group_gid variable will hold the newly-configured +# cancel or press ESC, the $var_to_set variable will hold the newly-configured # value upon return. # f_dialog_input_group_gid() { - local _input="$1" + local __var_to_set="$1" __input="$2" # Return if user has either pressed ESC or chosen Cancel/No - f_dialog_input _input "$msg_group_id_leave_empty_for_default" \ - "$_input" "$hline_num_tab_enter" || return $? + f_dialog_input __input "$msg_group_id_leave_empty_for_default" \ + "$__input" "$hline_num_tab_enter" || return $? - group_gid="$_input" + setvar "$__var_to_set" "$__input" save_flag=1 - f_dprintf "group_gid: [%s]->[%s]" "$cur_group_gid" "$group_gid" - return $DIALOG_OK } -# f_dialog_input_group_members [$group_members] +# f_dialog_input_group_members $var_to_set [$group_members] # # Allow the user to modify a list of members for a given group. If the user -# does not cancel or press ESC, the $group_members variable will hold the -# newly-configured value upon return. +# does not cancel or press ESC, the $var_to_set variable will hold the newly- +# configured value upon return. # f_dialog_input_group_members() { - local _input="$1" - local prompt="$msg_group_members:" - local menu_list=" + local __var_to_set="$1" __input="$2" + local __prompt="$msg_group_members:" + local __menu_list=" 'X' '$msg_continue' '1' '$msg_select_group_members_from_list' '2' '$msg_enter_group_members_manually' " # END-QUOTE - local defaultitem= - local hline="$hline_num_arrows_tab_enter" + local __defaultitem= + local __hline="$hline_num_arrows_tab_enter" - local mheight mwidth mrows - eval f_dialog_menu_size mheight mwidth mrows \ + local __mheight __mwidth __mrows + eval f_dialog_menu_size __mheight __mwidth __mrows \ \"\$DIALOG_TITLE\" \ \"\$DIALOG_BACKTITLE\" \ - \"\$prompt\" \ - \"\$hline\" \ + \"\$__prompt\" \ + \"\$__hline\" \ $menu_list - local menu_choice retval + local __menu_choice __retval while :; do - menu_choice=$( eval $DIALOG \ + __menu_choice=$( eval $DIALOG \ --title \"\$DIALOG_TITLE\" \ --backtitle \"\$DIALOG_BACKTITLE\" \ - --hline \"\$hline\" \ + --hline \"\$__hline\" \ --ok-label \"\$msg_ok\" \ --cancel-label \"\$msg_cancel\" \ - --default-item \"\$defaultitem\" \ - --menu \"\$prompt\" \ - $mheight $mwidth $mrows \ - $menu_list \ + --default-item \"\$__defaultitem\" \ + --menu \"\$__prompt\" \ + $__mheight $__mwidth $__mrows \ + $__menu_list \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) - retval=$? - f_dialog_data_sanitize menu_choice - defaultitem="$menu_choice" - f_dprintf "retval=%u menu_choice=[%s]" $retval "$menu_choice" + __retval=$? + f_dialog_data_sanitize __menu_choice + __defaultitem="$__menu_choice" + f_dprintf "retval=%u menu_choice=[%s]" \ + $__retval "$__menu_choice" # Return if user has either pressed ESC or chosen Cancel/No - [ $retval -eq $DIALOG_OK ] || return $retval + [ $__retval -eq $DIALOG_OK ] || return $__retval - local _group_members - case "$menu_choice" in + local __group_members + case "$__menu_choice" in X) # Exit break ;; 1) # Select Group Members from a list - local user check_list= - for user in $( pw usershow -a | - awk -F: '!/^[[:space:]]*(#|$)/{print $1}' - ); do + local __user_list __length=0 __user __check_list= + __user_list=$( pw usershow -a | + awk -F: '!/^[[:space:]]*(#|$)/{print $1}' ) + while [ $__length -ne ${#__user_list} ]; do + __user="${__user_list%%$NL*}" # First line + # Format of a checklist entry: tag item status - if echo "$_input" | grep -q "\<$user\>"; then - check_list="$check_list $user '' on" - else - check_list="$check_list $user '' off" - fi + __check_list="$__check_list '$__user' ''" + case "$__input" in + "$__user"|"$__user",*|*,"$__user",*|*,"$__user") + __check_list="$__check_list on" ;; + *) + __check_list="$__check_list off" + esac + + __length=${#__user_list} + __user_list="${__user_list#*$NL}" # Kill line done - local cheight cwidth crows - eval f_dialog_checklist_size cheight cwidth crows \ - \"\$DIALOG_TITLE\" \ - \"\$DIALOG_BACKTITLE\" \ - \"\$prompt\" \ - \"\$hline\" \ - $check_list - _group_members=$( eval $DIALOG \ + local __cheight __cwidth __crows + eval f_dialog_checklist_size \ + __cheight __cwidth __crows \ + \"\$DIALOG_TITLE\" \ + \"\$DIALOG_BACKTITLE\" \ + \"\$__prompt\" \ + \"\$__hline\" \ + $__check_list + __group_members=$( eval $DIALOG \ --title \"\$DIALOG_TITLE\" \ --backtitle \"\$DIALOG_BACKTITLE\" \ --separate-output \ - --hline \"\$hline\" \ + --hline \"\$__hline\" \ --ok-label \"\$msg_ok\" \ --cancel-label \"\$msg_cancel\" \ - --checklist \"\$prompt\" \ - $cheight $cwidth $crows \ - $check_list \ + --checklist \"\$__prompt\" \ + $__cheight $__cwidth $__crows \ + $__check_list \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) || continue # Return to previous menu if user either # pressed ESC or chose Cancel/No - f_dialog_data_sanitize _group_members + f_dialog_data_sanitize __group_members # # Convert the newline separated list into a comma- # separated one so that if the user switches over to # manual editing, list reflects checklist selections # - f_replaceall "$_group_members" "[$IFS]" "," _input + f_replaceall "$__group_members" "[$NL]" "," __input ;; 2) # Enter Group Members manually - local p="$msg_group_members ($msg_separated_by_commas)" + local __prompt2="$msg_group_members" + __prompt2="$__prompt2 ($msg_separated_by_commas)" - f_dialog_input _group_members "$p" "$_input" \ + f_dialog_input __group_members \ + "$__prompt2" "$__input" \ "$hline_num_tab_enter" || continue # Return to previous menu if user either # pressed ESC or chose Cancel/No - _input="$_group_members" + __input="$__group_members" ;; esac done - group_members="$_input" + setvar "$__var_to_set" "$__input" save_flag=1 - f_dprintf "group_members: [%s]->[%s]" \ - "$cur_group_members" "$group_members" return $DIALOG_OK } +# f_dialog_menu_group_add [$defaultitem] +# +# Present a menu detailing the properties of a group that is about to be added. +# The user's menu choice is available using f_dialog_menutag_fetch(). Returns +# success unless the user chose Cancel or pressed ESC. Data to display is taken +# from environment variables group_name, group_gid, and group_members. If +# $defaultitem is present and non-NULL, initially highlight the item in the +# menu. +# +f_dialog_menu_group_add() +{ + local prompt="$msg_save_exit_or_cancel" + local menu_list # Calculated below + local defaultitem="$1" + local hline="$hline_arrows_tab_enter" + + menu_list=" + 'X' '$msg_add/$msg_exit' + '1' '$msg_group: $group_name' + '2' '$msg_password: -----' + '3' '$msg_group_id: $group_gid' + '4' '$msg_group_members: $group_members' + " # END-QUOTE + + local height width rows + eval f_dialog_menu_size height width rows \ + \"\$DIALOG_TITLE\" \ + \"\$DIALOG_BACKTITLE\" \ + \"\$prompt\" \ + \"\$hline\" \ + $menu_list + + local menu_choice + menu_choice=$( eval $DIALOG \ + --title \"\$DIALOG_TITLE\" \ + --backtitle \"\$DIALOG_BACKTITLE\" \ + --hline \"\$hline\" \ + --ok-label \"\$msg_ok\" \ + --cancel-label \"\$msg_cancel\" \ + --default-item \"\$defaultitem\" \ + --menu \"\$prompt\" \ + $height $width $rows \ + $menu_list \ + 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD + ) + local retval=$? + f_dialog_data_sanitize menu_choice + f_dialog_menutag_store "$menu_choice" + return $retval +} + +# f_dialog_menu_group_delete $group [$defaultitem] +# +# Present a menu detailing the properties of a group that is about to be +# deleted. The user's menu choice is available using f_dialog_menutag_fetch(). +# Returns success unless the user chose Cancel or pressed ESC. Data to display +# is populated automatically from the system accounting database for the given +# $group argument. If $defaultitem is present and non-NULL, initially highlight +# the item in the menu. +# +f_dialog_menu_group_delete() +{ + local prompt="$msg_delete_exit_or_cancel" + local menu_list # Calculated below + local defaultitem="$2" + local hline="$hline_arrows_tab_enter" + + local group_name group_password group_gid group_members + f_input_group "$1" + + menu_list=" + 'X' '$msg_delete/$msg_exit' + '1' '$msg_group: $group_name' + '-' '$msg_password: -----' + '-' '$msg_group_id: $group_gid' + '-' '$msg_group_members: $group_members' + " # END-QUOTE + + local height width rows + eval f_dialog_menu_size height width rows \ + \"\$DIALOG_TITLE\" \ + \"\$DIALOG_BACKTITLE\" \ + \"\$prompt\" \ + \"\$hline\" \ + $menu_list + + local menu_choice + menu_choice=$( eval $DIALOG \ + --title \"\$DIALOG_TITLE\" \ + --backtitle \"\$DIALOG_BACKTITLE\" \ + --hline \"\$hline\" \ + --ok-label \"\$msg_ok\" \ + --cancel-label \"\$msg_cancel\" \ + --default-item \"\$defaultitem\" \ + --menu \"\$prompt\" \ + $height $width $rows \ + $menu_list \ + 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD + ) + local retval=$? + f_dialog_data_sanitize menu_choice + f_dialog_menutag_store "$menu_choice" + return $retval +} + +# f_dialog_menu_group_edit [$defaultitem] +# +# Present a menu detailing the properties of a group that is about to be +# modified. The user's menu choice is available using f_dialog_menutag_fetch(). +# Returns success unless the user chose Cancel or pressed ESC. Data to display +# is taken from environment variables group_name, group_gid, and group_members. +# If $defaultitem is present and non-NULL, initially highlight the item in the +# menu. +# +f_dialog_menu_group_edit() +{ + local prompt="$msg_save_exit_or_cancel" + local menu_list # Calculated below + local defaultitem="$1" + local hline="$hline_arrows_tab_enter" + + menu_list=" + 'X' '$msg_save/$msg_exit' + '1' '$msg_group: $group_name' + '2' '$msg_password: -----' + '3' '$msg_group_id: $group_gid' + '4' '$msg_group_members: $group_members' + " # END-QUOTE + + local height width rows + eval f_dialog_menu_size height width rows \ + \"\$DIALOG_TITLE\" \ + \"\$DIALOG_BACKTITLE\" \ + \"\$prompt\" \ + \"\$hline\" \ + $menu_list + + local menu_choice + menu_choice=$( eval $DIALOG \ + --title \"\$DIALOG_TITLE\" \ + --backtitle \"\$DIALOG_BACKTITLE\" \ + --hline \"\$hline\" \ + --ok-label \"\$msg_ok\" \ + --cancel-label \"\$msg_cancel\" \ + --default-item \"\$defaultitem\" \ + --menu \"\$prompt\" \ + $height $width $rows \ + $menu_list \ + 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD + ) + local retval=$? + f_dialog_data_sanitize menu_choice + f_dialog_menutag_store "$menu_choice" + return $retval +} + ############################################################ MAIN f_dprintf "%s: Successfully loaded." usermgmt/group_input.subr