if [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1 # # 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..." usermgmt/group_input.subr f_include $BSDCFG_SHARE/dialog.subr f_include $BSDCFG_SHARE/strings.subr BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" f_include_lang $BSDCFG_LIBE/include/messages.subr f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr ############################################################ FUNCTIONS # f_input_group $group # # Given $group name or id, create the environment variables group_name, # group_gid, and group_members (and group_password is reset to NULL). # f_input_group() { eval $( pw groupshow "$1" | awk -F: ' { printf "group_name='\'%s\''\n", $1 printf "group_password=\n" printf "group_gid='\'%s\''\n", $3 printf "group_members='\'%s\''\n", $4 exit }' ) } # f_dialog_menu_group_list [$default] # # Allows the user to select a group from a list. Optionally, if present and # non-NULL, initially highlight $default group. # f_dialog_menu_group_list() { local prompt= local menu_list=" 'X $msg_exit' '' " # END-QUOTE local defaultitem="$1" local hline="$hline_alnum_punc_tab_enter" # Add groups from group(5) menu_list="$menu_list $( pw groupshow -a | awk -F: ' !/^[[:space:]]*(#|$)/ { printf "'\'%s\'\ \'%s\''\n", $1, $1 }' )" 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_menutag_store -s "$menu_choice" return $retval } # f_dialog_input_group_name [$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). # f_dialog_input_group_name() { # # Loop until the user provides taint-free/valid input # local _name="$1" _input="$1" while :; do # Return if user has either pressed ESC or chosen Cancel/No 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" return $DIALOG_OK fi # Check for NULL entry if [ ! "$_input" ]; then f_show_msg "$msg_group_is_empty" continue fi # Check for invalid entry if ! echo "$_input" | grep -q "^[[:alpha:]]"; then f_show_msg "$msg_group_must_start_with_letter" continue fi # Check for duplicate entry if f_quietly pw groupshow -n "$_input"; then f_show_msg "$msg_group_already_used" "$_input" continue fi group_name="$_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 # # Prompt the user to enter a password (twice). # f_dialog_input_group_password() { 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 \ "$DIALOG_TITLE" \ "$DIALOG_BACKTITLE" \ "$prompt1" \ "" \ "$hline" local height2 width2 f_dialog_inputbox_size height2 width2 \ "$DIALOG_TITLE" \ "$DIALOG_BACKTITLE" \ "$prompt2" \ "" \ "$hline" # # Loop until the user provides taint-free/valid input # local retval _password1 _password2 while :; do _password1=$( $DIALOG \ --title "$DIALOG_TITLE" \ --backtitle "$DIALOG_BACKTITLE" \ --hline "$hline" \ --ok-label "$msg_ok" \ --cancel-label "$msg_cancel" \ --insecure \ --passwordbox "$prompt1" \ $height1 $width1 \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) retval=$? debug= f_dialog_line_sanitize _password1 # Return if user has either pressed ESC or chosen Cancel/No [ $retval -eq $DIALOG_OK ] || return $retval _password2=$( $DIALOG \ --title "$DIALOG_TITLE" \ --backtitle "$DIALOG_BACKTITLE" \ --hline "$hline" \ --ok-label "$msg_ok" \ --cancel-label "$msg_cancel" \ --insecure \ --passwordbox "$prompt2" \ $height2 $width2 \ 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD ) retval=$? debug= f_dialog_line_sanitize _password2 # Return if user has either pressed ESC or chosen Cancel/No [ $retval -eq $DIALOG_OK ] || return $retval # Check for password mismatch if [ "$_password1" != "$_password2" ]; then f_show_msg "$msg_group_passwords_do_not_match" continue fi # Check for NULL entry 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 else continue # back to password prompt fi else pw_group_password_disable= fi group_password="$_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] # # 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 # value upon return. # f_dialog_input_group_gid() { local _input="$1" # 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 $? group_gid="$_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] # # 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. # f_dialog_input_group_members() { local _input="$1" 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 mheight mwidth mrows eval f_dialog_menu_size mheight mwidth mrows \ \"\$DIALOG_TITLE\" \ \"\$DIALOG_BACKTITLE\" \ \"\$prompt\" \ \"\$hline\" \ $menu_list local menu_choice retval while :; do 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\" \ $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" # Return if user has either pressed ESC or chosen Cancel/No [ $retval -eq $DIALOG_OK ] || return $retval 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 # 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 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 \ --title \"\$DIALOG_TITLE\" \ --backtitle \"\$DIALOG_BACKTITLE\" \ --separate-output \ --hline \"\$hline\" \ --ok-label \"\$msg_ok\" \ --cancel-label \"\$msg_cancel\" \ --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 # Convert the newline separated list into a comma- # separated one so that if the user switches over to # manual editing, list reflects checklist selections _group_members=$( echo "$_group_members" | tr '\n' ' ' | sed -e 's/[[:space:]]\{1,\}/,/g;s/^,//;s/,$//' ) _input="$_group_members" ;; 2) # Enter Group Members manually local p="$msg_group_members ($msg_separated_by_commas)" f_dialog_input _group_members "$p" "$_input" \ "$hline_num_tab_enter" || continue # Return to previous menu if user either # pressed ESC or chose Cancel/No _input="$_group_members" ;; esac done group_members="$_input" save_flag=1 f_dprintf "group_members: [%s]->[%s]" \ "$cur_group_members" "$group_members" return $DIALOG_OK } ############################################################ MAIN f_dprintf "%s: Successfully loaded." usermgmt/group_input.subr fi # ! $_USERMGMT_GROUP_INPUT_SUBR