1if [ ! "$_USERMGMT_USER_INPUT_SUBR" ]; then _USERMGMT_USER_INPUT_SUBR=1 2# 3# Copyright (c) 2012 Ron McDowell 4# Copyright (c) 2012-2013 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/user_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############################################################ CONFIGURATION 43 44# 45# Default location of shells(5) 46# 47: ${ETC_SHELLS:=/etc/shells} 48 49############################################################ FUNCTIONS 50 51# f_get_member_groups $user 52# 53# Get a list of additional groups $user is a member of in group(5). 54# 55f_get_member_groups() 56{ 57 echo $( pw groupshow -a | awk -F: "/[:,]$1(,|\$)/{print \$1}" ) 58} 59 60# f_input_user $user 61# 62# Given $user name or id, create the environment variables pw_name, pw_uid, 63# pw_gid, pw_class, pw_password_expire, pw_account_expire, pw_gecos, 64# pw_home_dir, pw_shell, and pw_member_groups (and pw_password is reset to 65# NULL). 66# 67f_input_user() 68{ 69 local user="$1" 70 eval $( pw usershow "$user" | awk -F: ' 71 { 72 printf "pw_name='\'%s\''\n", $1 73 printf "pw_password=\n" 74 printf "pw_uid='\'%s\''\n", $3 75 printf "pw_gid='\'%s\''\n", $4 76 printf "pw_class='\'%s\''\n", $5 77 printf "pw_password_expire='\'%s\''\n", $6 78 printf "pw_account_expire='\'%s\''\n", $7 79 printf "pw_gecos='\'%s\''\n", $8 80 printf "pw_home_dir='\'%s\''\n", $9 81 printf "pw_shell='\'%s\''\n", $10 82 }' ) 83 pw_member_groups=$( f_get_member_groups "$user" ) 84} 85 86# f_dialog_menu_user_list [$default] 87# 88# Allows the user to select a login from a list. Optionally, if present and 89# non-NULL, initially highlight $default user. 90# 91f_dialog_menu_user_list() 92{ 93 local prompt= 94 local menu_list=" 95 'X $msg_exit' '' 96 " # END-QUOTE 97 local defaultitem="$1" 98 local hline="$hline_alnum_punc_tab_enter" 99 100 # Add users from passwd(5) 101 menu_list="$menu_list $( pw usershow -a | awk -F: ' 102 !/^[[:space:]]*(#|$)/ { 103 printf "'\'%s\'\ \'%s\''\n", $1, $8 104 }' 105 )" 106 107 local height width rows 108 eval f_dialog_menu_size height width rows \ 109 \"\$DIALOG_TITLE\" \ 110 \"\$DIALOG_BACKTITLE\" \ 111 \"\$prompt\" \ 112 \"\$hline\" \ 113 $menu_list 114 115 local menu_choice 116 menu_choice=$( eval $DIALOG \ 117 --title \"\$DIALOG_TITLE\" \ 118 --backtitle \"\$DIALOG_BACKTITLE\" \ 119 --hline \"\$hline\" \ 120 --ok-label \"\$msg_ok\" \ 121 --cancel-label \"\$msg_cancel\" \ 122 --default-item \"\$defaultitem\" \ 123 --menu \"\$prompt\" \ 124 $height $width $rows \ 125 $menu_list \ 126 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 127 ) 128 local retval=$? 129 f_dialog_menutag_store -s "$menu_choice" 130 return $retval 131} 132 133# f_dialog_input_member_groups [$member_groups] 134# 135# Allows the user to edit group memberships for a given user. If the user does 136# not cancel or press ESC, the $pw_member_groups variable will hold the newly- 137# configured value upon return. 138# 139f_dialog_input_member_groups() 140{ 141 local _member_groups="$1" 142 local prompt="$msg_member_of_groups" 143 local check_list= # Calculated below 144 local hline="$hline_alnum_space_tab_enter" 145 local group 146 147 # 148 # Generate the checklist menu 149 # 150 for group in $( 151 pw groupshow -a | awk -F: '!/^[[:space:]]*(#|$)/{print $1}' 152 ); do 153 # Format of a checklist menu entry is "tag item status" 154 # (setting both tag and item to the group name below). 155 if echo "$_member_groups" | grep -q "\<$group\>"; then 156 check_list="$check_list $group $group on" 157 else 158 check_list="$check_list $group $group off" 159 fi 160 done 161 162 # 163 # Loop until the user provides taint-free/valid input 164 # 165 local height width rows 166 while :; do 167 eval f_dialog_checklist_size height width rows \ 168 \"\$DIALOG_TITLE\" \ 169 \"\$DIALOG_BACKTITLE\" \ 170 \"\$prompt\" \ 171 \"\$hline\" \ 172 $check_list 173 _member_groups=$( eval $DIALOG \ 174 --title \"\$DIALOG_TITLE\" \ 175 --backtitle \"\$DIALOG_BACKTITLE\" \ 176 --separate-output \ 177 --hline \"\$hline\" \ 178 --ok-label \"\$msg_ok\" \ 179 --cancel-label \"\$msg_cancel\" \ 180 --checklist \"\$prompt\" \ 181 $height $width $rows \ 182 $check_list \ 183 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 184 ) || return $? 185 # Return if user either pressed ESC or chose Cancel/No 186 f_dialog_data_sanitize _member_groups 187 188 # 189 # Validate each of the groups the user has entered 190 # 191 local all_groups_valid=1 192 for group in $_member_groups; do 193 if ! f_quietly pw groupshow -n "$group"; then 194 f_show_msg "$msg_group_not_found" "$group" 195 all_groups_valid= 196 break 197 fi 198 done 199 [ "$all_groups_valid" ] || continue 200 201 pw_member_groups="$_member_groups" 202 break 203 done 204 save_flag=1 205 206 f_dprintf "pw_member_groups: [%s]->[%s]" \ 207 "$cur_pw_member_groups" "$pw_member_groups" 208 209 return $SUCCESS 210} 211 212# f_dialog_input_name [$name] 213# 214# Allows the user to enter a new username for a given user. If the user does 215# not cancel or press ESC, the $pw_name variable will hold the newly-configured 216# value upon return. 217# 218# If $cur_pw_name is defined, the user can enter that and by-pass error- 219# checking (allowing the user to "revert" to an old value without, for example, 220# being told that the username already exists). 221# 222f_dialog_input_name() 223{ 224 # 225 # Loop until the user provides taint-free/valid input 226 # 227 local _name="$1" _input="$1" 228 while :; do 229 230 # Return if user has either pressed ESC or chosen Cancel/No 231 f_dialog_input _input "$msg_login" "$_input" \ 232 "$hline_alnum_tab_enter" || return 233 234 # Check for no-change 235 [ "$_input" = "$_name" ] && return $SUCCESS 236 237 # Check for reversion 238 if [ "$_input" = "$cur_pw_name" ]; then 239 pw_name="$cur_pw_name" 240 return $SUCCESS 241 fi 242 243 # Check for NULL entry 244 if [ ! "$_input" ]; then 245 f_dialog_msgbox "$msg_login_is_empty" 246 continue 247 fi 248 249 # Check for invalid entry 250 if ! echo "$_input" | grep -q "^[[:alpha:]]"; then 251 f_dialog_msgbox "$msg_login_must_start_with_letter" 252 continue 253 fi 254 255 # Check for duplicate entry 256 if f_quietly pw usershow -n "$_input"; then 257 f_show_msg "$msg_login_already_used" "$_input" 258 continue 259 fi 260 261 pw_name="$_input" 262 break 263 done 264 save_flag=1 265 266 f_dprintf "pw_name: [%s]->[%s]" "$cur_pw_name" "$pw_name" 267 268 return $SUCCESS 269} 270 271# f_dialog_input_password 272# 273# Prompt the user to enter a password (twice). 274# 275f_dialog_input_password() 276{ 277 local prompt1="$msg_password" 278 local prompt2="$msg_reenter_password" 279 local hline="$hline_alnum_punc_tab_enter" 280 281 local height1 width1 282 f_dialog_inputbox_size height1 width1 \ 283 "$DIALOG_TITLE" \ 284 "$DIALOG_BACKTITLE" \ 285 "$prompt1" \ 286 "" \ 287 "$hline" 288 local height2 width2 289 f_dialog_inputbox_size height2 width2 \ 290 "$DIALOG_TITLE" \ 291 "$DIALOG_BACKTITLE" \ 292 "$prompt2" \ 293 "" \ 294 "$hline" 295 296 # 297 # Loop until the user provides taint-free/valid input 298 # 299 local _password1 _password2 300 while :; do 301 _password1=$( $DIALOG \ 302 --title "$DIALOG_TITLE" \ 303 --backtitle "$DIALOG_BACKTITLE" \ 304 --hline "$hline" \ 305 --ok-label "$msg_ok" \ 306 --cancel-label "$msg_cancel" \ 307 --insecure \ 308 --passwordbox "$prompt1" \ 309 $height1 $width1 \ 310 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 311 ) || return $? 312 # Return if user either pressed ESC or chose Cancel/No 313 debug= f_dialog_line_sanitize _password1 314 315 _password2=$( $DIALOG \ 316 --title "$DIALOG_TITLE" \ 317 --backtitle "$DIALOG_BACKTITLE" \ 318 --hline "$hline" \ 319 --ok-label "$msg_ok" \ 320 --cancel-label "$msg_cancel" \ 321 --insecure \ 322 --passwordbox "$prompt2" \ 323 $height2 $width2 \ 324 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 325 ) || return $? 326 # Return if user either pressed ESC or chose Cancel/No 327 debug= f_dialog_line_sanitize _password2 328 329 # Check for password mismatch 330 if [ "$_password1" != "$_password2" ]; then 331 f_dialog_msgbox "$msg_passwords_do_not_match" 332 continue 333 fi 334 335 # Check for NULL entry 336 if [ ! "$_password1" ]; then 337 f_dialog_yesno "$msg_disable_password_auth_for_account" 338 local retval=$? 339 if [ $retval -eq 255 ]; then # ESC was pressed 340 return $retval 341 elif [ $retval -eq $SUCCESS ]; then 342 pw_password_disable=1 343 else 344 continue # back to password prompt 345 fi 346 else 347 pw_password_disable= 348 fi 349 350 pw_password="$_password1" 351 break 352 done 353 save_flag=1 354 355 f_dprintf "pw_password: [%s]->[%s]" "$cur_pw_password" "$pw_password" 356 357 return $SUCCESS 358} 359 360# f_dialog_input_gecos [$gecos] 361# 362# Allow the user to enter new GECOS information for a given user. This 363# information is commonly used to store the ``Full Name'' of the user. If the 364# user does not cancel or press ESC, the $pw_gecos variable will hold the 365# newly-configured value upon return. 366# 367f_dialog_input_gecos() 368{ 369 local _input="$1" 370 371 # Return if user has either pressed ESC or chosen Cancel/No 372 f_dialog_input _input "$msg_full_name" "$_input" \ 373 "$hline_alnum_punc_tab_enter" || return 374 375 pw_gecos="$_input" 376 save_flag=1 377 378 f_dprintf "pw_gecos: [%s]->[%s]" "$cur_pw_gecos" "$pw_gecos" 379 380 return $SUCCESS 381} 382 383# f_dialog_input_uid [$uid] 384# 385# Allow the user to enter a new UID for a given user. If the user does not 386# cancel or press ESC, the $pw_uid variable will hold the newly-configured 387# value upon return. 388# 389f_dialog_input_uid() 390{ 391 local _input="$1" 392 393 # Return if user has either pressed ESC or chosen Cancel/No 394 f_dialog_input _input "$msg_user_id_leave_empty_for_default" \ 395 "$_input" "$hline_num_tab_enter" || return 396 397 pw_uid="$_input" 398 save_flag=1 399 400 f_dprintf "pw_uid: [%s]->[%s]" "$cur_pw_uid" "$pw_uid" 401 402 return $SUCCESS 403} 404 405# f_dialog_input_gid [$gid] 406# 407# Allow the user to enter a new primary GID for a given user. If the user does 408# not cancel or press ESC, the $pw_gid variable will hold the newly-configured 409# value upon return. 410# 411f_dialog_input_gid() 412{ 413 local _input="$1" 414 415 # Return if user has either pressed ESC or chosen Cancel/No 416 f_dialog_input _input "$msg_group_id_leave_empty_for_default" \ 417 "$_input" "$hline_num_tab_enter" || return 418 419 pw_gid="$_input" 420 save_flag=1 421 422 f_dprintf "pw_gid: [%s]->[%s]" "$cur_pw_gid" "$pw_gid" 423 424 return $SUCCESS 425} 426 427# f_dialog_input_class [$class] 428# 429# Allow the user to enter a new login class for a given user. If the user does 430# not cancel or press ESC, the $pw_class variable will hold the newly- 431# configured value upon return. 432# 433f_dialog_input_class() 434{ 435 local _input="$1" 436 437 # Return if user has either pressed ESC or chosen Cancel/No 438 f_dialog_input _input "$msg_login_class" "$_input" \ 439 "$hline_alnum_tab_enter" || return 440 441 pw_class="$_input" 442 save_flag=1 443 444 f_dprintf "pw_class: [%s]->[%s]" "$cur_pw_class" "$pw_class" 445 446 return $SUCCESS 447} 448 449# f_dialog_input_expire_password [$seconds] 450# 451# Allow the user to enter a date/time (in number-of-seconds since the `epoch') 452# for when a given user's password must be changed. If the user does not cancel 453# or press ESC, the $pw_password_expire variable will hold the newly- 454# configured value upon return. 455# 456f_dialog_input_expire_password() 457{ 458 local prompt="$msg_password_expires_on" 459 local menu_list=" 460 '1' '$msg_password_does_not_expire' 461 '2' '$msg_edit_date_time_with_a_calendar' 462 '3' '$msg_enter_number_of_days_into_the_future' 463 '4' '$msg_enter_value_manually' 464 " # END-QUOTE 465 local hline="$hline_num_arrows_tab_enter" 466 local retval _input="$1" 467 468 local mheight mwidth mrows 469 eval f_dialog_menu_size mheight mwidth mrows \ 470 \"\$DIALOG_TITLE\" \ 471 \"\$DIALOG_BACKTITLE\" \ 472 \"\$prompt\" \ 473 \"\$hline\" \ 474 $menu_list 475 local cheight cwidth 476 f_dialog_calendar_size cheight cwidth \ 477 "$DIALOG_TITLE" \ 478 "$DIALOG_BACKTITLE" \ 479 "$prompt" \ 480 "$hline" 481 local theight twidth 482 f_dialog_timebox_size theight twidth \ 483 "$DIALOG_TITLE" \ 484 "$DIALOG_BACKTITLE" \ 485 "$prompt" \ 486 "$hline" 487 488 # 489 # Loop until the user provides taint-free/cancellation-free input 490 # 491 local date_type defaultitem= 492 while :; do 493 date_type=$( eval $DIALOG \ 494 --title \"\$DIALOG_TITLE\" \ 495 --backtitle \"\$DIALOG_BACKTITLE\" \ 496 --hline \"\$hline\" \ 497 --default-item \"\$defaultitem\" \ 498 --ok-label \"\$msg_ok\" \ 499 --cancel-label \"\$msg_cancel\" \ 500 --menu \"\$prompt\" \ 501 $mheight $mwidth $mrows \ 502 $menu_list \ 503 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 504 ) 505 retval=$? 506 f_dialog_data_sanitize date_type 507 defaultitem="$date_type" 508 f_dprintf "retval=%u date_type=[%s]" $retval "$date_type" 509 510 # Return if user has either pressed ESC or chosen Cancel/No 511 [ $retval -eq $SUCCESS ] || return $retval 512 513 case "$date_type" in 514 1) # Password does not expire 515 _input="" 516 break ;; 517 518 2) # Edit date/time with a calendar 519 local _input_date _input_time ret_date ret_time 520 521 local secs="$_input" 522 { f_isinteger "$secs" && [ $secs -gt 0 ]; } || secs= 523 _input_date=$( date -j -f "%s" -- "$secs" \ 524 "+%d %m %Y" 2> /dev/null ) 525 ret_date=$( eval $DIALOG \ 526 --title \"\$DIALOG_TITLE\" \ 527 --backtitle \"\$DIALOG_BACKTITLE\" \ 528 --hline \"\$hline\" \ 529 --ok-label \"\$msg_ok\" \ 530 --cancel-label \"\$msg_cancel\" \ 531 --calendar \"\$prompt\" \ 532 $cheight $cwidth \ 533 $_input_date \ 534 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 535 ) 536 retval=$? 537 f_dialog_data_sanitize ret_date 538 f_dprintf "retval=%u ret_date=[%s]" $retval "$ret_date" 539 540 # Return to menu if either ESC or Cancel/No 541 [ $retval -eq $SUCCESS ] || continue 542 543 _input_time= 544 [ "$secs" ] && _input_time=$( date -j \ 545 -f %s -- "$_input" "+%H %M %S" 2> /dev/null ) 546 ret_time=$( eval $DIALOG \ 547 --title \"\$DIALOG_TITLE\" \ 548 --backtitle \"\$DIALOG_BACKTITLE\" \ 549 --hline \"\$hline\" \ 550 --ok-label \"\$msg_ok\" \ 551 --cancel-label \"\$msg_cancel\" \ 552 --timebox \"\$prompt\" \ 553 $theight $twidth \ 554 $_input_time \ 555 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 556 ) 557 retval=$? 558 f_dialog_data_sanitize ret_time 559 f_dprintf "retval=%u ret_time=[%s]" $retval "$ret_time" 560 561 # Return to menu if either ESC or Cancel/No 562 [ $retval -eq $SUCCESS ] || continue 563 564 _input=$( date \ 565 -j -f "%d/%m/%Y %T" \ 566 -- "$ret_date $ret_time" \ 567 +%s 2> /dev/null ) 568 f_dprintf "_input=[%s]" "$_input" 569 break ;; 570 571 3) # Enter number of days into the future 572 local ret_days seconds="$( date +%s )" 573 574 f_isinteger "$_input" || _input=0 575 [ $_input -gt 0 -a $_input -gt $seconds ] && 576 ret_days=$(( ( $_input - $seconds ) / 86400 )) 577 f_isinteger "$ret_days" && 578 ret_days=$(( $ret_days + 1 )) 579 580 # Return to menu if either ESC or Cancel/No 581 f_dialog_input ret_days \ 582 "$msg_password_expires_in_how_many_days" \ 583 "$ret_days" "$hline" || continue 584 585 # Taint-check the user's input 586 if ! f_isinteger "$ret_days"; then 587 f_dialog_msgbox "$msg_invalid_number_of_days" 588 continue 589 fi 590 591 f_dprintf "ret_days=[%s]" "$ret_days" 592 case "$ret_days" in 593 [-+]*) _input=$( date -v${ret_days}d +%s );; 594 0) _input=$( date +%s );; 595 *) _input=$( date -v+${ret_days}d +%s );; 596 esac 597 f_dprintf "_input=[%s]" "$_input" 598 break ;; 599 600 4) # Enter value manually 601 local msg ret_secs 602 msg=$( printf "$msg_number_of_seconds_since_epoch" \ 603 "$( date -r 1 "+%c %Z" )" ) 604 605 # Return to menu if either ESC or Cancel/No 606 f_dialog_input ret_secs \ 607 "$msg" "$_input" "$hline" || continue 608 609 _input="$ret_secs" 610 611 # Taint-check the user's input 612 if ! f_isinteger "${_input:-0}"; then 613 f_dialog_msgbox \ 614 "$msg_invalid_number_of_seconds" 615 continue 616 fi 617 618 f_dprintf "_input=[%s]" "$_input" 619 break ;; 620 621 esac 622 623 done # Loop forever 624 625 pw_password_expire="$_input" 626 save_flag=1 627 628 f_dprintf "pw_password_expire: [%s]->[%s]" \ 629 "$cur_pw_password_expire" "$pw_password_expire" 630 631 return $SUCCESS 632} 633 634# f_dialog_input_expire_account [$seconds] 635# 636# Allow the user to enter a date/time (in number-of-seconds since the `epoch') 637# for when a given user's account should become expired. If the user does not 638# cancel or press ESC, the $pw_account_expire variable will hold the newly- 639# configured value upon return. 640# 641f_dialog_input_expire_account() 642{ 643 local prompt="$msg_account_expires_on" 644 local menu_list=" 645 '1' '$msg_account_does_not_expire' 646 '2' '$msg_edit_date_time_with_a_calendar' 647 '3' '$msg_enter_number_of_days_into_the_future' 648 '4' '$msg_enter_value_manually' 649 " # END-QUOTE 650 local hline="$hline_num_arrows_tab_enter" 651 local retval _input="$1" 652 653 local mheight mwidth mrows 654 eval f_dialog_menu_size mheight mwidth mrows \ 655 \"\$DIALOG_TITLE\" \ 656 \"\$DIALOG_BACKTITLE\" \ 657 \"\$prompt\" \ 658 \"\$hline\" \ 659 $menu_list 660 local cheight cwidth 661 f_dialog_calendar_size cheight cwidth \ 662 "$DIALOG_TITLE" \ 663 "$DIALOG_BACKTITLE" \ 664 "$prompt" \ 665 "$hline" 666 local theight twidth 667 f_dialog_timebox_size theight twidth \ 668 "$DIALOG_TITLE" \ 669 "$DIALOG_BACKTITLE" \ 670 "$prompt" \ 671 "$hline" 672 673 # 674 # Loop until the user provides taint-free/cancellation-free input 675 # 676 local date_type defaultitem= 677 while :; do 678 date_type=$( eval $DIALOG \ 679 --title \"\$DIALOG_TITLE\" \ 680 --backtitle \"\$DIALOG_BACKTITLE\" \ 681 --hline \"\$hline\" \ 682 --default-item \"\$defaultitem\" \ 683 --ok-label \"\$msg_ok\" \ 684 --cancel-label \"\$msg_cancel\" \ 685 --menu \"\$prompt\" \ 686 $mheight $mwidth $mrows \ 687 $menu_list \ 688 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 689 ) 690 retval=$? 691 f_dialog_data_sanitize date_type 692 defaultitem="$date_type" 693 f_dprintf "retval=%u date_type=[%s]" $retval "$date_type" 694 695 # Return if user has either pressed ESC or chosen Cancel/No 696 [ $retval -eq $SUCCESS ] || return $retval 697 698 case "$date_type" in 699 1) # Account does not expire 700 _input="" 701 break ;; 702 703 2) # Edit date/time with a calendar 704 local _input_date _input_time ret_date ret_time 705 706 local secs="$_input" 707 { f_isinteger "$secs" && [ $secs -gt 0 ]; } || secs= 708 _input_date=$( date -j -f "%s" -- "$secs" \ 709 "+%d %m %Y" 2> /dev/null ) 710 ret_date=$( eval $DIALOG \ 711 --title \"\$DIALOG_TITLE\" \ 712 --backtitle \"\$DIALOG_BACKTITLE\" \ 713 --hline \"\$hline\" \ 714 --ok-label \"\$msg_ok\" \ 715 --cancel-label \"\$msg_cancel\" \ 716 --calendar \"\$prompt\" \ 717 $cheight $cwidth \ 718 $_input_date \ 719 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 720 ) 721 retval=$? 722 f_dialog_data_sanitize ret_date 723 f_dprintf "retval=%u ret_date=[%s]" $retval "$ret_date" 724 725 # Return to menu if either ESC or Cancel/No 726 [ $retval -eq $SUCCESS ] || continue 727 728 _input_time= 729 [ "$secs" ] && _input_time=$( date -j \ 730 -f %s -- "$_input" "+%H %M %S" 2> /dev/null ) 731 ret_time=$( eval $DIALOG \ 732 --title \"\$DIALOG_TITLE\" \ 733 --backtitle \"\$DIALOG_BACKTITLE\" \ 734 --hline \"\$hline\" \ 735 --ok-label \"\$msg_ok\" \ 736 --cancel-label \"\$msg_cancel\" \ 737 --timebox \"\$prompt\" \ 738 $theight $twidth \ 739 $_input_time \ 740 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 741 ) 742 retval=$? 743 f_dialog_data_sanitize ret_time 744 f_dprintf "retval=%u ret_time=[%s]" $retval "$ret_time" 745 746 # Return to menu if either ESC or Cancel/No 747 [ $retval -eq $SUCCESS ] || continue 748 749 _input=$( date \ 750 -j -f "%d/%m/%Y %T" \ 751 -- "$ret_date $ret_time" \ 752 +%s 2> /dev/null ) 753 f_dprintf "_input=[%s]" "$_input" 754 break ;; 755 756 3) # Enter number of days into the future 757 local ret_days seconds="$( date +%s )" 758 759 f_isinteger "$_input" || _input=0 760 [ $_input -gt 0 -a $_input -gt $seconds ] && 761 ret_days=$(( ( $_input - $seconds ) / 86400 )) 762 f_isinteger "$ret_days" && 763 ret_days=$(( $ret_days + 1 )) 764 765 # Return to menu if either ESC or Cancel/No 766 f_dialog_input ret_days \ 767 "$msg_account_expires_in_how_many_days" \ 768 "$ret_days" "$hline" || continue 769 770 # Taint-check the user's input 771 if ! f_isinteger "$ret_days"; then 772 f_dialog_msgbox "$msg_invalid_number_of_days" 773 continue 774 fi 775 776 f_dprintf "ret_days=[%s]" "$ret_days" 777 case "$ret_days" in 778 [-+]*) _input=$( date -v${ret_days}d +%s );; 779 0) _input=$( date +%s );; 780 *) _input=$( date -v+${ret_days}d +%s );; 781 esac 782 f_dprintf "_input=[%s]" "$_input" 783 break ;; 784 785 4) # Enter value manually 786 local msg ret_secs 787 msg=$( printf "$msg_number_of_seconds_since_epoch" \ 788 "$( date -r 1 "+%c %Z" )" ) 789 790 # Return to menu if either ESC or Cancel/No 791 f_dialog_input ret_secs "$msg" \ 792 "$_input" "$hline" || continue 793 794 _input="$ret_secs" 795 796 # Taint-check the user's input 797 if ! f_isinteger "${_input:-0}"; then 798 f_dialog_msgbox \ 799 "$msg_invalid_number_of_seconds" 800 continue 801 fi 802 803 f_dprintf "_input=[%s]" "$_input" 804 break ;; 805 806 esac 807 808 done # Loop forever 809 810 pw_account_expire="$_input" 811 save_flag=1 812 813 f_dprintf "pw_account_expire: [%s]->[%s]" \ 814 "$cur_pw_account_expire" "$pw_account_expire" 815 816 return $SUCCESS 817} 818 819# f_dialog_input_home_dir [$home_dir] 820# 821# Allow the user to enter a new home directory for a given user. If the user 822# does not cancel or press ESC, the $pw_home_dir variable will hold the newly- 823# configured value upon return. 824# 825f_dialog_input_home_dir() 826{ 827 local _input="$1" 828 829 # Return if user has either pressed ESC or chosen Cancel/No 830 f_dialog_input _input "$msg_home_directory" "$_input" \ 831 "$hline_alnum_punc_tab_enter" || return 832 833 pw_home_dir="$_input" 834 save_flag=1 835 836 f_dprintf "pw_home_dir: [%s]->[%s]" "$cur_pw_home_dir" "$pw_home_dir" 837 838 return $SUCCESS 839} 840 841# f_dialog_input_home_create 842# 843# Prompt the user to confirm creation of a given user's home directory. If the 844# user does not cancel (by choosing "No") or press ESC, the $pw_home_create 845# variable will hold $msg_yes upon return, otherwise $msg_no. Use these return 846# variables ($msg_yes and $msg_no) for comparisons to be i18n-compatible. 847# 848f_dialog_input_home_create() 849{ 850 local retval 851 852 f_dialog_yesno "$msg_create_home_directory" 853 retval=$? 854 855 if [ $retval -eq $SUCCESS ]; then 856 pw_home_create="$msg_yes" 857 else 858 pw_home_create="$msg_no" 859 fi 860 save_flag=1 861 862 f_dprintf "pw_home_create: [%s]->[%s]" \ 863 "$cur_pw_home_create" "$pw_home_create" 864 865 [ $retval -ne 255 ] # return failure if user pressed ESC 866} 867 868# f_dialog_input_group_delete 869# 870# Prompt the user to confirm deletion of a given user's primary group. If the 871# user does not cancel (by choosing "No") or press ESC, the $pw_group_delete 872# variable will hold $msg_yes upon return, otherwise $msg_no. Use these return 873# variables ($msg_yes and $msg_no) for comparisons to be i18n-compatible. 874# 875f_dialog_input_group_delete() 876{ 877 local retval 878 879 if f_isinteger "$pw_gid"; then 880 if [ $pw_gid -lt 1000 ]; then 881 f_dialog_noyes "$msg_delete_primary_group" 882 else 883 f_dialog_yesno "$msg_delete_primary_group" 884 fi 885 elif [ "$pw_gid" ]; then 886 local gid=0 887 gid=$( pw groupshow "$pw_gid" | awk -F: '{print $3}' ) 888 if f_isinteger "$gid" && [ $gid -lt 1000 ]; then 889 f_dialog_noyes "$msg_delete_primary_group" 890 else 891 f_dialog_yesno "$msg_delete_primary_group" 892 fi 893 else 894 f_dialog_yesno "$msg_delete_primary_group" 895 fi 896 retval=$? 897 898 if [ $retval -eq $SUCCESS ]; then 899 pw_group_delete="$msg_yes" 900 else 901 pw_group_delete="$msg_no" 902 fi 903 save_flag=1 904 905 f_dprintf "pw_group_delete: [%s]->[%s]" \ 906 "$cur_pw_group_delete" "$pw_group_delete" 907 908 [ $retval -ne 255 ] # return failure if user pressed ESC 909} 910 911# f_dialog_input_home_delete 912# 913# Prompt the user to confirm deletion of a given user's home directory. If the 914# user does not cancel (by choosing "No") or press ESC, the $pw_home_delete 915# variable will hold $msg_yes upon return, otherwise $msg_no. Use these return 916# variables ($msg_yes and $msg_no) for comparisons to be i18n-compatible. 917# 918f_dialog_input_home_delete() 919{ 920 local retval 921 922 f_dialog_yesno "$msg_delete_home_directory" 923 retval=$? 924 925 if [ $retval -eq $SUCCESS ]; then 926 pw_home_delete="$msg_yes" 927 else 928 pw_home_delete="$msg_no" 929 fi 930 save_flag=1 931 932 f_dprintf "pw_home_delete: [%s]->[%s]" \ 933 "$cur_pw_home_delete" "$pw_home_delete" 934 935 [ $retval -ne 255 ] # return failure if user pressed ESC 936} 937 938# f_dialog_input_dotfiles_create 939# 940# Prompt the user to confirm population of a given user's home directory with 941# sample dotfiles. If the user does not cancel (by choosing "No") or press ESC, 942# the $pw_dotfiles_create variable will hold $msg_yes upon return, otherwise 943# $msg_no. Use these return variables ($msg_yes and $msg_no) for comparison to 944# be i18n-compatible. 945# 946f_dialog_input_dotfiles_create() 947{ 948 local retval 949 950 f_dialog_yesno "$msg_create_dotfiles" 951 retval=$? 952 953 if [ $retval -eq $SUCCESS ]; then 954 pw_dotfiles_create="$msg_yes" 955 else 956 pw_dotfiles_create="$msg_no" 957 fi 958 save_flag=1 959 960 f_dprintf "pw_dotfiles_create: [%s]->[%s]" \ 961 "$cur_pw_dotfiles_create" "$pw_dotfiles_create" 962 963 [ $retval -ne 255 ] # return failure if user pressed ESC 964} 965 966# f_dialog_input_shell [$shell] 967# 968# Allow the user to select a new login shell for a given user. If the user does 969# not cancel or press ESC, the $pw_home_dir variable will hold the newly- 970# configured value upon return. 971# 972# 973f_dialog_input_shell() 974{ 975 local _input="$1" 976 local prompt="$msg_select_login_shell" 977 local radio_list= # Calculated below 978 local hline="$hline_arrows_space_tab_enter" 979 980 # 981 # Generate the radiolist of shells 982 # 983 local shell 984 for shell in $( awk '!/^[[:space:]]*(#|$)/{print}' "$ETC_SHELLS" ); do 985 # Format of a radiolist menu entry is "tag item status" 986 if [ "$shell" = "$_input" ]; then 987 radio_list="$radio_list '$shell' '' 'on'" 988 else 989 radio_list="$radio_list '$shell' '' 'off'" 990 fi 991 done 992 993 local height width rows 994 eval f_dialog_radiolist_size height width rows \ 995 \"\$DIALOG_TITLE\" \ 996 \"\$DIALOG_BACKTITLE\" \ 997 \"\$prompt\" \ 998 \"\$hline\" \ 999 $radio_list 1000 1001 _input=$( eval $DIALOG \ 1002 --title \"\$DIALOG_TITLE\" \ 1003 --backtitle \"\$DIALOG_BACKTITLE\" \ 1004 --hline \"\$hline\" \ 1005 --ok-label \"\$msg_ok\" \ 1006 --cancel-label \"\$msg_cancel\" \ 1007 --radiolist \"\$prompt\" \ 1008 $height $width $rows \ 1009 $radio_list \ 1010 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 1011 ) || return $? 1012 # Return if user either pressed ESC or chose Cancel/No 1013 f_dialog_data_sanitize _input 1014 1015 pw_shell="$_input" 1016 save_flag=1 1017 1018 f_dprintf "pw_shell: [%s]->[%s]" "$cur_pw_shell" "$pw_shell" 1019 1020 return $SUCCESS 1021} 1022 1023############################################################ MAIN 1024 1025f_dprintf "%s: Successfully loaded." usermgmt/user_input.subr 1026 1027fi # ! $_USERMGMT_USER_INPUT_SUBR 1028