group_input.subr revision 251547
1249259Sdimif [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1 2249259Sdim# 3249259Sdim# Copyright (c) 2012 Ron McDowell 4249259Sdim# Copyright (c) 2012-2013 Devin Teske 5249259Sdim# All rights reserved. 6249259Sdim# 7249259Sdim# Redistribution and use in source and binary forms, with or without 8249259Sdim# modification, are permitted provided that the following conditions 9249259Sdim# are met: 10249259Sdim# 1. Redistributions of source code must retain the above copyright 11249259Sdim# notice, this list of conditions and the following disclaimer. 12249259Sdim# 2. Redistributions in binary form must reproduce the above copyright 13249259Sdim# notice, this list of conditions and the following disclaimer in the 14249259Sdim# documentation and/or other materials provided with the distribution. 15249259Sdim# 16249259Sdim# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17249259Sdim# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18249259Sdim# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19249259Sdim# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20249259Sdim# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21249259Sdim# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22249259Sdim# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23249259Sdim# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24249259Sdim# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25249259Sdim# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26249259Sdim# SUCH DAMAGE. 27249259Sdim# 28249259Sdim# $FreeBSD: head/usr.sbin/bsdconfig/usermgmt/share/group_input.subr 251547 2013-06-08 18:23:41Z dteske $ 29249259Sdim# 30249259Sdim############################################################ INCLUDES 31249259Sdim 32249259SdimBSDCFG_SHARE="/usr/share/bsdconfig" 33249259Sdim. $BSDCFG_SHARE/common.subr || exit 1 34249259Sdimf_dprintf "%s: loading includes..." usermgmt/group_input.subr 35249259Sdimf_include $BSDCFG_SHARE/dialog.subr 36249259Sdimf_include $BSDCFG_SHARE/strings.subr 37249259Sdim 38249259SdimBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" 39249259Sdimf_include_lang $BSDCFG_LIBE/include/messages.subr 40249259Sdimf_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 41249259Sdim 42249259Sdim############################################################ FUNCTIONS 43249259Sdim 44249259Sdim# f_input_group $group 45249259Sdim# 46249259Sdim# Given $group name or id, create the environment variables group_name, 47249259Sdim# group_gid, and group_members (and group_password is reset to NULL). 48249259Sdim# 49249259Sdimf_input_group() 50249259Sdim{ 51249259Sdim eval $( pw groupshow "$1" | awk -F: ' 52249259Sdim { 53249259Sdim printf "group_name='\'%s\''\n", $1 54249259Sdim printf "group_password=\n" 55249259Sdim printf "group_gid='\'%s\''\n", $3 56249259Sdim printf "group_members='\'%s\''\n", $4 57249259Sdim exit 58249259Sdim }' ) 59249259Sdim} 60249259Sdim 61249259Sdim# f_dialog_menu_group_list [$default] 62249259Sdim# 63249259Sdim# Allows the user to select a group from a list. Optionally, if present and 64249259Sdim# non-NULL, initially highlight $default group. 65249259Sdim# 66249259Sdimf_dialog_menu_group_list() 67249259Sdim{ 68249259Sdim local prompt= 69249259Sdim local menu_list=" 70249259Sdim 'X $msg_exit' '' 71249259Sdim " # END-QUOTE 72249259Sdim local defaultitem="$1" 73249259Sdim local hline="$hline_alnum_punc_tab_enter" 74249259Sdim 75249259Sdim # Add groups from group(5) 76249259Sdim menu_list="$menu_list $( pw groupshow -a | awk -F: ' 77249259Sdim !/^[[:space:]]*(#|$)/ { 78249259Sdim printf "'\'%s\'\ \'%s\''\n", $1, $1 79249259Sdim }' 80249259Sdim )" 81249259Sdim 82249259Sdim local height width rows 83249259Sdim eval f_dialog_menu_size height width rows \ 84249259Sdim \"\$DIALOG_TITLE\" \ 85249259Sdim \"\$DIALOG_BACKTITLE\" \ 86249259Sdim \"\$prompt\" \ 87249259Sdim \"\$hline\" \ 88249259Sdim $menu_list 89249259Sdim 90249259Sdim local menu_choice 91249259Sdim menu_choice=$( eval $DIALOG \ 92249259Sdim --title \"\$DIALOG_TITLE\" \ 93249259Sdim --backtitle \"\$DIALOG_BACKTITLE\" \ 94249259Sdim --hline \"\$hline\" \ 95249259Sdim --ok-label \"\$msg_ok\" \ 96249259Sdim --cancel-label \"\$msg_cancel\" \ 97249259Sdim --default-item \"\$defaultitem\" \ 98249259Sdim --menu \"\$prompt\" \ 99249259Sdim $height $width $rows \ 100249259Sdim $menu_list \ 101249259Sdim 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 102249259Sdim ) 103249259Sdim local retval=$? 104249259Sdim f_dialog_menutag_store -s "$menu_choice" 105249259Sdim return $retval 106249259Sdim} 107249259Sdim 108249259Sdim# f_dialog_input_group_name [$group_name] 109249259Sdim# 110249259Sdim# Allows the user to enter a new groupname for a given group. If the user does 111249259Sdim# not cancel or press ESC, the $group_name variable will hold the 112249259Sdim# newly-configured value upon return. 113249259Sdim# 114249259Sdim# If $cur_group_name is defined, the user can enter that and by-pass error- 115249259Sdim# checking (allowing the user to "revert" to an old value without, for example, 116249259Sdim# being told that the groupname already exists). 117249259Sdim# 118249259Sdimf_dialog_input_group_name() 119249259Sdim{ 120249259Sdim # 121249259Sdim # Loop until the user provides taint-free/valid input 122249259Sdim # 123249259Sdim local _name="$1" _input="$1" 124249259Sdim while :; do 125249259Sdim 126249259Sdim # Return if user has either pressed ESC or chosen Cancel/No 127249259Sdim f_dialog_input _input "$msg_group" "$_input" \ 128249259Sdim "$hline_alnum_tab_enter" || return 129249259Sdim 130249259Sdim # Check for no-change 131249259Sdim [ "$_input" = "$_name" ] && return $SUCCESS 132249259Sdim 133249259Sdim # Check for reversion 134249259Sdim if [ "$_input" = "$cur_group_name" ]; then 135249259Sdim group_name="$cur_group_name" 136249259Sdim return $SUCCESS 137249259Sdim fi 138249259Sdim 139249259Sdim # Check for NULL entry 140249259Sdim if [ ! "$_input" ]; then 141249259Sdim f_dialog_msgbox "$msg_group_is_empty" 142249259Sdim continue 143249259Sdim fi 144249259Sdim 145249259Sdim # Check for invalid entry 146249259Sdim if ! echo "$_input" | grep -q "^[[:alpha:]]"; then 147249259Sdim f_dialog_msgbox "$msg_group_must_start_with_letter" 148249259Sdim continue 149249259Sdim fi 150249259Sdim 151249259Sdim # Check for duplicate entry 152249259Sdim if f_quietly pw groupshow -n "$_input"; then 153249259Sdim f_show_msg "$msg_group_already_used" "$_input" 154249259Sdim continue 155249259Sdim fi 156249259Sdim 157249259Sdim group_name="$_input" 158249259Sdim break 159249259Sdim done 160249259Sdim save_flag=1 161249259Sdim 162249259Sdim f_dprintf "group_name: [%s]->[%s]" "$cur_group_name" "$group_name" 163249259Sdim 164249259Sdim return $SUCCESS 165249259Sdim} 166249259Sdim 167249259Sdim# f_dialog_input_group_password 168249259Sdim# 169249259Sdim# Prompt the user to enter a password (twice). 170249259Sdim# 171249259Sdimf_dialog_input_group_password() 172249259Sdim{ 173249259Sdim local prompt1="$msg_group_password" 174249259Sdim local prompt2="$msg_reenter_group_password" 175249259Sdim local hline="$hline_alnum_punc_tab_enter" 176249259Sdim 177249259Sdim local height1 width1 178249259Sdim f_dialog_inputbox_size height1 width1 \ 179249259Sdim "$DIALOG_TITLE" \ 180249259Sdim "$DIALOG_BACKTITLE" \ 181249259Sdim "$prompt1" \ 182249259Sdim "" \ 183249259Sdim "$hline" 184249259Sdim 185249259Sdim local height2 width2 186249259Sdim f_dialog_inputbox_size height2 width2 \ 187249259Sdim "$DIALOG_TITLE" \ 188249259Sdim "$DIALOG_BACKTITLE" \ 189249259Sdim "$prompt2" \ 190249259Sdim "" \ 191249259Sdim "$hline" 192249259Sdim 193249259Sdim # 194249259Sdim # Loop until the user provides taint-free/valid input 195249259Sdim # 196249259Sdim local retval _password1 _password2 197249259Sdim while :; do 198249259Sdim _password1=$( $DIALOG \ 199249259Sdim --title "$DIALOG_TITLE" \ 200249259Sdim --backtitle "$DIALOG_BACKTITLE" \ 201249259Sdim --hline "$hline" \ 202249259Sdim --ok-label "$msg_ok" \ 203249259Sdim --cancel-label "$msg_cancel" \ 204249259Sdim --insecure \ 205249259Sdim --passwordbox "$prompt1" \ 206249259Sdim $height1 $width1 \ 207249259Sdim 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 208249259Sdim ) 209249259Sdim retval=$? 210249259Sdim debug= f_dialog_line_sanitize _password1 211249259Sdim 212249259Sdim # Return if user has either pressed ESC or chosen Cancel/No 213249259Sdim [ $retval -eq $SUCCESS ] || return $retval 214249259Sdim 215249259Sdim _password2=$( $DIALOG \ 216249259Sdim --title "$DIALOG_TITLE" \ 217249259Sdim --backtitle "$DIALOG_BACKTITLE" \ 218249259Sdim --hline "$hline" \ 219249259Sdim --ok-label "$msg_ok" \ 220249259Sdim --cancel-label "$msg_cancel" \ 221249259Sdim --insecure \ 222249259Sdim --passwordbox "$prompt2" \ 223249259Sdim $height2 $width2 \ 224249259Sdim 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 225249259Sdim ) 226249259Sdim retval=$? 227249259Sdim debug= f_dialog_line_sanitize _password2 228249259Sdim 229249259Sdim # Return if user has either pressed ESC or chosen Cancel/No 230249259Sdim [ $retval -eq $SUCCESS ] || return $retval 231249259Sdim 232249259Sdim # Check for password mismatch 233249259Sdim if [ "$_password1" != "$_password2" ]; then 234249259Sdim f_dialog_msgbox "$msg_group_passwords_do_not_match" 235249259Sdim continue 236249259Sdim fi 237249259Sdim 238249259Sdim # Check for NULL entry 239249259Sdim if [ ! "$_password1" ]; then 240249259Sdim f_dialog_yesno "$msg_disable_password_auth_for_group" 241249259Sdim local retval=$? 242249259Sdim if [ $retval -eq 255 ]; then # ESC was pressed 243249259Sdim return $retval 244249259Sdim elif [ $retval -eq $SUCCESS ]; then 245249259Sdim pw_group_password_disable=1 246249259Sdim else 247249259Sdim continue # back to password prompt 248249259Sdim fi 249249259Sdim else 250249259Sdim pw_group_password_disable= 251249259Sdim fi 252249259Sdim 253249259Sdim group_password="$_password1" 254249259Sdim break 255249259Sdim done 256249259Sdim save_flag=1 257249259Sdim 258249259Sdim f_dprintf "group_password: [%s]->[%s]" \ 259249259Sdim "$cur_group_password" "$group_password" 260249259Sdim 261249259Sdim return $SUCCESS 262249259Sdim} 263249259Sdim 264249259Sdim# f_dialog_input_group_gid [$group_gid] 265249259Sdim# 266249259Sdim# Allow the user to enter a new GID for a given group. If the user does not 267249259Sdim# cancel or press ESC, the $group_gid variable will hold the newly-configured 268249259Sdim# value upon return. 269249259Sdim# 270249259Sdimf_dialog_input_group_gid() 271249259Sdim{ 272249259Sdim local _input="$1" 273249259Sdim 274249259Sdim # Return if user has either pressed ESC or chosen Cancel/No 275249259Sdim f_dialog_input _input "$msg_group_id_leave_empty_for_default" \ 276249259Sdim "$_input" "$hline_num_tab_enter" || return 277249259Sdim 278249259Sdim group_gid="$_input" 279249259Sdim save_flag=1 280249259Sdim 281249259Sdim f_dprintf "group_gid: [%s]->[%s]" "$cur_group_gid" "$group_gid" 282249259Sdim 283249259Sdim return $SUCCESS 284249259Sdim} 285249259Sdim 286249259Sdim# f_dialog_input_group_members [$group_members] 287249259Sdim# 288249259Sdim# Allow the user to modify a list of members for a given group. If the user 289249259Sdim# does not cancel or press ESC, the $group_members variable will hold the 290249259Sdim# newly-configured value upon return. 291249259Sdim# 292249259Sdimf_dialog_input_group_members() 293249259Sdim{ 294249259Sdim local _input="$1" 295249259Sdim local prompt="$msg_group_members:" 296249259Sdim local menu_list=" 297249259Sdim 'X' '$msg_continue' 298249259Sdim '1' '$msg_select_group_members_from_list' 299249259Sdim '2' '$msg_enter_group_members_manually' 300249259Sdim " # END-QUOTE 301249259Sdim local defaultitem= 302249259Sdim local hline="$hline_num_arrows_tab_enter" 303249259Sdim 304249259Sdim local mheight mwidth mrows 305249259Sdim eval f_dialog_menu_size mheight mwidth mrows \ 306249259Sdim \"\$DIALOG_TITLE\" \ 307249259Sdim \"\$DIALOG_BACKTITLE\" \ 308249259Sdim \"\$prompt\" \ 309249259Sdim \"\$hline\" \ 310249259Sdim $menu_list 311249259Sdim 312249259Sdim local menu_choice retval 313249259Sdim while :; do 314249259Sdim menu_choice=$( eval $DIALOG \ 315249259Sdim --title \"\$DIALOG_TITLE\" \ 316249259Sdim --backtitle \"\$DIALOG_BACKTITLE\" \ 317249259Sdim --hline \"\$hline\" \ 318249259Sdim --ok-label \"\$msg_ok\" \ 319249259Sdim --cancel-label \"\$msg_cancel\" \ 320249259Sdim --default-item \"\$defaultitem\" \ 321249259Sdim --menu \"\$prompt\" \ 322249259Sdim $mheight $mwidth $mrows \ 323249259Sdim $menu_list \ 324249259Sdim 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 325249259Sdim ) 326249259Sdim retval=$? 327249259Sdim f_dialog_data_sanitize menu_choice 328249259Sdim defaultitem="$menu_choice" 329249259Sdim f_dprintf "retval=%u menu_choice=[%s]" $retval "$menu_choice" 330249259Sdim 331249259Sdim # Return if user has either pressed ESC or chosen Cancel/No 332249259Sdim [ $retval -eq $SUCCESS ] || return $retval 333249259Sdim 334249259Sdim local _group_members 335249259Sdim case "$menu_choice" in 336249259Sdim X) # Exit 337249259Sdim break ;; 338249259Sdim 1) # Select Group Members from a list 339249259Sdim local user check_list= 340249259Sdim for user in $( pw usershow -a | 341249259Sdim awk -F: '!/^[[:space:]]*(#|$)/{print $1}' 342249259Sdim ); do 343249259Sdim # Format of a checklist entry: tag item status 344249259Sdim if echo "$_input" | grep -q "\<$user\>"; then 345249259Sdim check_list="$check_list $user '' on" 346249259Sdim else 347249259Sdim check_list="$check_list $user '' off" 348249259Sdim fi 349249259Sdim done 350249259Sdim 351249259Sdim local cheight cwidth crows 352249259Sdim eval f_dialog_checklist_size cheight cwidth crows \ 353249259Sdim \"\$DIALOG_TITLE\" \ 354249259Sdim \"\$DIALOG_BACKTITLE\" \ 355249259Sdim \"\$prompt\" \ 356249259Sdim \"\$hline\" \ 357249259Sdim $check_list 358263508Sdim _group_members=$( eval $DIALOG \ 359263508Sdim --title \"\$DIALOG_TITLE\" \ 360263508Sdim --backtitle \"\$DIALOG_BACKTITLE\" \ 361263508Sdim --separate-output \ 362263508Sdim --hline \"\$hline\" \ 363249259Sdim --ok-label \"\$msg_ok\" \ 364249259Sdim --cancel-label \"\$msg_cancel\" \ 365249259Sdim --checklist \"\$prompt\" \ 366249259Sdim $cheight $cwidth $crows \ 367249259Sdim $check_list \ 368249259Sdim 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 369249259Sdim ) || continue 370249259Sdim # Return to previous menu if user either 371249259Sdim # pressed ESC or chose Cancel/No 372249259Sdim f_dialog_data_sanitize _group_members 373 374 # Convert the newline separated list into a comma- 375 # separated one so that if the user switches over to 376 # manual editing, list reflects checklist selections 377 _group_members=$( echo "$_group_members" | 378 tr '\n' ' ' | 379 sed -e 's/[[:space:]]\{1,\}/,/g;s/^,//;s/,$//' 380 ) 381 382 _input="$_group_members" 383 ;; 384 2) # Enter Group Members manually 385 local p="$msg_group_members ($msg_separated_by_commas)" 386 387 f_dialog_input _group_members "$p" "$_input" \ 388 "$hline_num_tab_enter" || continue 389 # Return to previous menu if user either 390 # pressed ESC or chose Cancel/No 391 392 _input="$_group_members" 393 ;; 394 esac 395 done 396 397 group_members="$_input" 398 save_flag=1 399 f_dprintf "group_members: [%s]->[%s]" \ 400 "$cur_group_members" "$group_members" 401 402 return $SUCCESS 403} 404 405############################################################ MAIN 406 407f_dprintf "%s: Successfully loaded." usermgmt/group_input.subr 408 409fi # ! $_USERMGMT_GROUP_INPUT_SUBR 410