1if [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_INPUT_SUBR=1 2# 3# Copyright (c) 2012 Ron McDowell 4# Copyright (c) 2012-2014 Devin Teske 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28# $FreeBSD$ 29# 30############################################################ INCLUDES 31 32BSDCFG_SHARE="/usr/share/bsdconfig" 33. $BSDCFG_SHARE/common.subr || exit 1 34f_dprintf "%s: loading includes..." usermgmt/group_input.subr 35f_include $BSDCFG_SHARE/dialog.subr 36f_include $BSDCFG_SHARE/strings.subr 37 38BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" 39f_include_lang $BSDCFG_LIBE/include/messages.subr 40f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 41 42############################################################ FUNCTIONS 43 44# f_input_group $group 45# 46# Given $group name or id, create the environment variables group_name, 47# group_gid, and group_members (and group_password is reset to NULL). 48# 49f_input_group() 50{ 51 local funcname=f_input_group 52 local group="$1" 53 54 f_dprintf "$funcname: Getting info for group \`%s'" "$group" 55 eval "$( pw groupshow "$group" 2> /dev/null | awk -F: ' 56 { 57 found = $1 != "" 58 printf "group_name='\'%s\''\n", $1 59 printf "group_password=\n" 60 printf "group_gid='\'%s\''\n", $3 61 printf "group_members='\'%s\''\n", $4 62 exit 63 } 64 END { if (!found) print "false" }' )" 65} 66 67# f_dialog_menu_group_list [$default] 68# 69# Allows the user to select a group from a list. Optionally, if present and 70# non-NULL, initially highlight $default group. 71# 72f_dialog_menu_group_list() 73{ 74 local prompt= 75 local menu_list=" 76 'X $msg_exit' '' 77 " # END-QUOTE 78 local defaultitem="$1" 79 local hline="$hline_alnum_punc_tab_enter" 80 81 # Add groups from group(5) 82 menu_list="$menu_list $( pw groupshow -a | awk -F: ' 83 !/^[[:space:]]*(#|$)/ { 84 printf "'\'%s\'\ \'%s\''\n", $1, $1 85 }' 86 )" 87 88 local height width rows 89 eval f_dialog_menu_size height width rows \ 90 \"\$DIALOG_TITLE\" \ 91 \"\$DIALOG_BACKTITLE\" \ 92 \"\$prompt\" \ 93 \"\$hline\" \ 94 $menu_list 95 96 local menu_choice 97 menu_choice=$( eval $DIALOG \ 98 --title \"\$DIALOG_TITLE\" \ 99 --backtitle \"\$DIALOG_BACKTITLE\" \ 100 --hline \"\$hline\" \ 101 --ok-label \"\$msg_ok\" \ 102 --cancel-label \"\$msg_cancel\" \ 103 --default-item \"\$defaultitem\" \ 104 --menu \"\$prompt\" \ 105 $height $width $rows \ 106 $menu_list \ 107 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 108 ) 109 local retval=$? 110 f_dialog_menutag_store -s "$menu_choice" 111 return $retval 112} 113 114# f_dialog_input_group_name $var_to_set [$group_name] 115# 116# Allows the user to enter a name for a new group. If the user does not cancel 117# or press ESC, the $var_to_set variable will hold the newly-configured value 118# upon return. 119# 120f_dialog_input_group_name() 121{ 122 local __var_to_set="$1" __name="$2" 123 124 # 125 # Loop until the user provides taint-free/valid input 126 # 127 local __input="$__name" 128 while :; do 129 # Return if user has either pressed ESC or chosen Cancel/No 130 f_dialog_input __input "$msg_group" "$__input" \ 131 "$hline_alnum_tab_enter" || return $? 132 133 # Check for no-change 134 if [ "$__input" = "$__name" ]; then 135 setvar "$__var_to_set" "$__input" 136 return $DIALOG_OK 137 fi 138 139 # Check for NULL entry 140 if [ ! "$__input" ]; then 141 f_show_msg "$msg_group_is_empty" 142 continue 143 fi 144 145 # Check for invalid entry 146 case "$__input" in [!a-zA-Z]*) 147 f_show_msg "$msg_group_must_start_with_letter" 148 continue 149 esac 150 151 # Check for duplicate entry 152 if f_quietly pw groupshow -n "$__input"; then 153 f_show_msg "$msg_group_already_used" "$__input" 154 continue 155 fi 156 157 setvar "$__var_to_set" "$__input" 158 break 159 done 160 161 return $DIALOG_OK 162} 163 164# f_dialog_input_group_password $var_to_set $dvar_to_set 165# 166# Prompt the user to enter a password (twice). If the user does not cancel or 167# press ESC, $var_to_set will hold the confirmed user entry. Otherwise, if the 168# user cancels or enters a NULL password (twice), they are given the choice to 169# disable password authentication for the given group, wherein $dvar_to_set has 170# a value of 1 to indicate password authentication should be disabled. 171# 172f_dialog_input_group_password() 173{ 174 local __var_to_set="$1" __dvar_to_set="$2" 175 local __prompt1="$msg_group_password" 176 local __prompt2="$msg_reenter_group_password" 177 local __hline="$hline_alnum_punc_tab_enter" 178 179 local __height1 __width1 180 f_dialog_inputbox_size __height1 __width1 \ 181 "$DIALOG_TITLE" \ 182 "$DIALOG_BACKTITLE" \ 183 "$__prompt1" \ 184 "" \ 185 "$__hline" 186 187 local __height2 __width2 188 f_dialog_inputbox_size __height2 __width2 \ 189 "$DIALOG_TITLE" \ 190 "$DIALOG_BACKTITLE" \ 191 "$__prompt2" \ 192 "" \ 193 "$__hline" 194 195 # 196 # Loop until the user provides taint-free/valid input 197 # 198 local __retval __password1 __password2 199 while :; do 200 __password1=$( $DIALOG \ 201 --title "$DIALOG_TITLE" \ 202 --backtitle "$DIALOG_BACKTITLE" \ 203 --hline "$__hline" \ 204 --ok-label "$msg_ok" \ 205 --cancel-label "$msg_cancel" \ 206 --insecure \ 207 --passwordbox "$__prompt1" \ 208 $__height1 $__width1 \ 209 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 210 ) 211 __retval=$? 212 debug= f_dialog_line_sanitize __password1 213 214 # Return if user has either pressed ESC or chosen Cancel/No 215 [ $__retval -eq $DIALOG_OK ] || return $__retval 216 217 __password2=$( $DIALOG \ 218 --title "$DIALOG_TITLE" \ 219 --backtitle "$DIALOG_BACKTITLE" \ 220 --hline "$__hline" \ 221 --ok-label "$msg_ok" \ 222 --cancel-label "$msg_cancel" \ 223 --insecure \ 224 --passwordbox "$__prompt2" \ 225 $__height2 $__width2 \ 226 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 227 ) 228 __retval=$? 229 debug= f_dialog_line_sanitize __password2 230 231 # Return if user has either pressed ESC or chosen Cancel/No 232 [ $__retval -eq $DIALOG_OK ] || return $__retval 233 234 # Check for password mismatch 235 if [ "$__password1" != "$__password2" ]; then 236 f_show_msg "$msg_group_passwords_do_not_match" 237 continue 238 fi 239 240 # Check for NULL entry 241 if [ ! "$__password1" ]; then 242 f_dialog_yesno "$msg_disable_password_auth_for_group" 243 __retval=$? 244 if [ $__retval -eq $DIALOG_ESC ]; then 245 return $__retval 246 elif [ $__retval -eq $DIALOG_OK ]; then 247 setvar "$__dvar_to_set" 1 248 else 249 continue # back to password prompt 250 fi 251 else 252 setvar "$__dvar_to_set" "" 253 fi 254 255 setvar "$__var_to_set" "$__password1" 256 break 257 done 258 259 return $DIALOG_OK 260} 261 262# f_dialog_input_group_gid $var_to_set [$group_gid] 263# 264# Allow the user to enter a new GID for a given group. If the user does not 265# cancel or press ESC, the $var_to_set variable will hold the newly-configured 266# value upon return. 267# 268f_dialog_input_group_gid() 269{ 270 local __var_to_set="$1" __input="$2" 271 272 # Return if user has either pressed ESC or chosen Cancel/No 273 f_dialog_input __input "$msg_group_id_leave_empty_for_default" \ 274 "$__input" "$hline_num_tab_enter" || return $? 275 276 setvar "$__var_to_set" "$__input" 277 return $DIALOG_OK 278} 279 280# f_dialog_input_group_members $var_to_set [$group_members] 281# 282# Allow the user to modify a list of members for a given group. If the user 283# does not cancel or press ESC, the $var_to_set variable will hold the newly- 284# configured value upon return. 285# 286f_dialog_input_group_members() 287{ 288 local __var_to_set="$1" __input="$2" 289 local __prompt="$msg_group_members:" 290 local __menu_list=" 291 'X' '$msg_continue' 292 '1' '$msg_select_group_members_from_list' 293 '2' '$msg_enter_group_members_manually' 294 " # END-QUOTE 295 local __defaultitem= 296 local __hline="$hline_num_arrows_tab_enter" 297 298 local __mheight __mwidth __mrows 299 eval f_dialog_menu_size __mheight __mwidth __mrows \ 300 \"\$DIALOG_TITLE\" \ 301 \"\$DIALOG_BACKTITLE\" \ 302 \"\$__prompt\" \ 303 \"\$__hline\" \ 304 $menu_list 305 306 local __menu_choice __retval 307 while :; do 308 __menu_choice=$( eval $DIALOG \ 309 --title \"\$DIALOG_TITLE\" \ 310 --backtitle \"\$DIALOG_BACKTITLE\" \ 311 --hline \"\$__hline\" \ 312 --ok-label \"\$msg_ok\" \ 313 --cancel-label \"\$msg_cancel\" \ 314 --default-item \"\$__defaultitem\" \ 315 --menu \"\$__prompt\" \ 316 $__mheight $__mwidth $__mrows \ 317 $__menu_list \ 318 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 319 ) 320 __retval=$? 321 f_dialog_data_sanitize __menu_choice 322 __defaultitem="$__menu_choice" 323 f_dprintf "retval=%u menu_choice=[%s]" \ 324 $__retval "$__menu_choice" 325 326 # Return if user has either pressed ESC or chosen Cancel/No 327 [ $__retval -eq $DIALOG_OK ] || return $__retval 328 329 local __group_members 330 case "$__menu_choice" in 331 X) # Exit 332 break ;; 333 1) # Select Group Members from a list 334 local __user_list __length=0 __user __check_list= 335 __user_list=$( pw usershow -a | 336 awk -F: '!/^[[:space:]]*(#|$)/{print $1}' ) 337 while [ $__length -ne ${#__user_list} ]; do 338 __user="${__user_list%%$NL*}" # First line 339 340 # Format of a checklist entry: tag item status 341 __check_list="$__check_list '$__user' ''" 342 case "$__input" in 343 "$__user"|"$__user",*|*,"$__user",*|*,"$__user") 344 __check_list="$__check_list on" ;; 345 *) 346 __check_list="$__check_list off" 347 esac 348 349 __length=${#__user_list} 350 __user_list="${__user_list#*$NL}" # Kill line 351 done 352 353 local __cheight __cwidth __crows 354 eval f_dialog_checklist_size \ 355 __cheight __cwidth __crows \ 356 \"\$DIALOG_TITLE\" \ 357 \"\$DIALOG_BACKTITLE\" \ 358 \"\$__prompt\" \ 359 \"\$__hline\" \ 360 $__check_list 361 __group_members=$( eval $DIALOG \ 362 --title \"\$DIALOG_TITLE\" \ 363 --backtitle \"\$DIALOG_BACKTITLE\" \ 364 --separate-output \ 365 --hline \"\$__hline\" \ 366 --ok-label \"\$msg_ok\" \ 367 --cancel-label \"\$msg_cancel\" \ 368 --checklist \"\$__prompt\" \ 369 $__cheight $__cwidth $__crows \ 370 $__check_list \ 371 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 372 ) || continue 373 # Return to previous menu if user either 374 # pressed ESC or chose Cancel/No 375 f_dialog_data_sanitize __group_members 376 377 # 378 # Convert the newline separated list into a comma- 379 # separated one so that if the user switches over to 380 # manual editing, list reflects checklist selections 381 # 382 f_replaceall "$__group_members" "[$NL]" "," __input 383 ;; 384 2) # Enter Group Members manually 385 local __prompt2="$msg_group_members" 386 __prompt2="$__prompt2 ($msg_separated_by_commas)" 387 388 f_dialog_input __group_members \ 389 "$__prompt2" "$__input" \ 390 "$hline_num_tab_enter" || continue 391 # Return to previous menu if user either 392 # pressed ESC or chose Cancel/No 393 394 __input="$__group_members" 395 ;; 396 esac 397 done 398 399 setvar "$__var_to_set" "$__input" 400 return $DIALOG_OK 401} 402 403# f_dialog_menu_group_add [$defaultitem] 404# 405# Present a menu detailing the properties of a group that is about to be added. 406# The user's menu choice is available using f_dialog_menutag_fetch(). Returns 407# success unless the user chose Cancel or pressed ESC. Data to display is taken 408# from environment variables group_name, group_gid, and group_members. If 409# $defaultitem is present and non-NULL, initially highlight the item in the 410# menu. 411# 412f_dialog_menu_group_add() 413{ 414 local prompt="$msg_save_exit_or_cancel" 415 local menu_list # Calculated below 416 local defaultitem="$1" 417 local hline="$hline_arrows_tab_enter" 418 419 menu_list=" 420 'X' '$msg_add/$msg_exit' 421 '1' '$msg_group: $group_name' 422 '2' '$msg_password: -----' 423 '3' '$msg_group_id: $group_gid' 424 '4' '$msg_group_members: $group_members' 425 " # END-QUOTE 426 427 local height width rows 428 eval f_dialog_menu_size height width rows \ 429 \"\$DIALOG_TITLE\" \ 430 \"\$DIALOG_BACKTITLE\" \ 431 \"\$prompt\" \ 432 \"\$hline\" \ 433 $menu_list 434 435 local menu_choice 436 menu_choice=$( eval $DIALOG \ 437 --title \"\$DIALOG_TITLE\" \ 438 --backtitle \"\$DIALOG_BACKTITLE\" \ 439 --hline \"\$hline\" \ 440 --ok-label \"\$msg_ok\" \ 441 --cancel-label \"\$msg_cancel\" \ 442 --default-item \"\$defaultitem\" \ 443 --menu \"\$prompt\" \ 444 $height $width $rows \ 445 $menu_list \ 446 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 447 ) 448 local retval=$? 449 f_dialog_data_sanitize menu_choice 450 f_dialog_menutag_store "$menu_choice" 451 return $retval 452} 453 454# f_dialog_menu_group_delete $group [$defaultitem] 455# 456# Present a menu detailing the properties of a group that is about to be 457# deleted. The user's menu choice is available using f_dialog_menutag_fetch(). 458# Returns success unless the user chose Cancel or pressed ESC. Data to display 459# is populated automatically from the system accounting database for the given 460# $group argument. If $defaultitem is present and non-NULL, initially highlight 461# the item in the menu. 462# 463f_dialog_menu_group_delete() 464{ 465 local prompt="$msg_delete_exit_or_cancel" 466 local menu_list # Calculated below 467 local defaultitem="$2" 468 local hline="$hline_arrows_tab_enter" 469 470 local group_name group_password group_gid group_members 471 f_input_group "$1" 472 473 menu_list=" 474 'X' '$msg_delete/$msg_exit' 475 '1' '$msg_group: $group_name' 476 '-' '$msg_password: -----' 477 '-' '$msg_group_id: $group_gid' 478 '-' '$msg_group_members: $group_members' 479 " # END-QUOTE 480 481 local height width rows 482 eval f_dialog_menu_size height width rows \ 483 \"\$DIALOG_TITLE\" \ 484 \"\$DIALOG_BACKTITLE\" \ 485 \"\$prompt\" \ 486 \"\$hline\" \ 487 $menu_list 488 489 local menu_choice 490 menu_choice=$( eval $DIALOG \ 491 --title \"\$DIALOG_TITLE\" \ 492 --backtitle \"\$DIALOG_BACKTITLE\" \ 493 --hline \"\$hline\" \ 494 --ok-label \"\$msg_ok\" \ 495 --cancel-label \"\$msg_cancel\" \ 496 --default-item \"\$defaultitem\" \ 497 --menu \"\$prompt\" \ 498 $height $width $rows \ 499 $menu_list \ 500 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 501 ) 502 local retval=$? 503 f_dialog_data_sanitize menu_choice 504 f_dialog_menutag_store "$menu_choice" 505 return $retval 506} 507 508# f_dialog_menu_group_edit [$defaultitem] 509# 510# Present a menu detailing the properties of a group that is about to be 511# modified. The user's menu choice is available using f_dialog_menutag_fetch(). 512# Returns success unless the user chose Cancel or pressed ESC. Data to display 513# is taken from environment variables group_name, group_gid, and group_members. 514# If $defaultitem is present and non-NULL, initially highlight the item in the 515# menu. 516# 517f_dialog_menu_group_edit() 518{ 519 local prompt="$msg_save_exit_or_cancel" 520 local menu_list # Calculated below 521 local defaultitem="$1" 522 local hline="$hline_arrows_tab_enter" 523 524 menu_list=" 525 'X' '$msg_save/$msg_exit' 526 '1' '$msg_group: $group_name' 527 '2' '$msg_password: -----' 528 '3' '$msg_group_id: $group_gid' 529 '4' '$msg_group_members: $group_members' 530 " # END-QUOTE 531 532 local height width rows 533 eval f_dialog_menu_size height width rows \ 534 \"\$DIALOG_TITLE\" \ 535 \"\$DIALOG_BACKTITLE\" \ 536 \"\$prompt\" \ 537 \"\$hline\" \ 538 $menu_list 539 540 local menu_choice 541 menu_choice=$( eval $DIALOG \ 542 --title \"\$DIALOG_TITLE\" \ 543 --backtitle \"\$DIALOG_BACKTITLE\" \ 544 --hline \"\$hline\" \ 545 --ok-label \"\$msg_ok\" \ 546 --cancel-label \"\$msg_cancel\" \ 547 --default-item \"\$defaultitem\" \ 548 --menu \"\$prompt\" \ 549 $height $width $rows \ 550 $menu_list \ 551 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 552 ) 553 local retval=$? 554 f_dialog_data_sanitize menu_choice 555 f_dialog_menutag_store "$menu_choice" 556 return $retval 557} 558 559############################################################ MAIN 560 561f_dprintf "%s: Successfully loaded." usermgmt/group_input.subr 562 563fi # ! $_USERMGMT_GROUP_INPUT_SUBR 564