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