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 $DIALOG_OK 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 $DIALOG_OK 236 237 # Check for reversion 238 if [ "$_input" = "$cur_pw_name" ]; then 239 pw_name="$cur_pw_name" 240 return $DIALOG_OK 241 fi 242 243 # Check for NULL entry 244 if [ ! "$_input" ]; then 245 f_show_msg "$msg_login_is_empty" 246 continue 247 fi 248 249 # Check for invalid entry 250 if ! echo "$_input" | grep -q "^[[:alpha:]]"; then 251 f_show_msg "$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 $DIALOG_OK 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_show_msg "$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 $DIALOG_ESC ]; then 340 return $retval 341 elif [ $retval -eq $DIALOG_OK ]; 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 $DIALOG_OK 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 $DIALOG_OK 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 $DIALOG_OK 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 $DIALOG_OK 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 $DIALOG_OK 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 $DIALOG_OK ] || 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 $DIALOG_OK ] || 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 $DIALOG_OK ] || 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_show_msg "$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 f_sprintf msg "$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_show_msg "$msg_invalid_number_of_seconds" 614 continue 615 fi 616 617 f_dprintf "_input=[%s]" "$_input" 618 break ;; 619 620 esac 621 622 done # Loop forever 623 624 pw_password_expire="$_input" 625 save_flag=1 626 627 f_dprintf "pw_password_expire: [%s]->[%s]" \ 628 "$cur_pw_password_expire" "$pw_password_expire" 629 630 return $DIALOG_OK 631} 632 633# f_dialog_input_expire_account [$seconds] 634# 635# Allow the user to enter a date/time (in number-of-seconds since the `epoch') 636# for when a given user's account should become expired. If the user does not 637# cancel or press ESC, the $pw_account_expire variable will hold the newly- 638# configured value upon return. 639# 640f_dialog_input_expire_account() 641{ 642 local prompt="$msg_account_expires_on" 643 local menu_list=" 644 '1' '$msg_account_does_not_expire' 645 '2' '$msg_edit_date_time_with_a_calendar' 646 '3' '$msg_enter_number_of_days_into_the_future' 647 '4' '$msg_enter_value_manually' 648 " # END-QUOTE 649 local hline="$hline_num_arrows_tab_enter" 650 local retval _input="$1" 651 652 local mheight mwidth mrows 653 eval f_dialog_menu_size mheight mwidth mrows \ 654 \"\$DIALOG_TITLE\" \ 655 \"\$DIALOG_BACKTITLE\" \ 656 \"\$prompt\" \ 657 \"\$hline\" \ 658 $menu_list 659 local cheight cwidth 660 f_dialog_calendar_size cheight cwidth \ 661 "$DIALOG_TITLE" \ 662 "$DIALOG_BACKTITLE" \ 663 "$prompt" \ 664 "$hline" 665 local theight twidth 666 f_dialog_timebox_size theight twidth \ 667 "$DIALOG_TITLE" \ 668 "$DIALOG_BACKTITLE" \ 669 "$prompt" \ 670 "$hline" 671 672 # 673 # Loop until the user provides taint-free/cancellation-free input 674 # 675 local date_type defaultitem= 676 while :; do 677 date_type=$( eval $DIALOG \ 678 --title \"\$DIALOG_TITLE\" \ 679 --backtitle \"\$DIALOG_BACKTITLE\" \ 680 --hline \"\$hline\" \ 681 --default-item \"\$defaultitem\" \ 682 --ok-label \"\$msg_ok\" \ 683 --cancel-label \"\$msg_cancel\" \ 684 --menu \"\$prompt\" \ 685 $mheight $mwidth $mrows \ 686 $menu_list \ 687 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 688 ) 689 retval=$? 690 f_dialog_data_sanitize date_type 691 defaultitem="$date_type" 692 f_dprintf "retval=%u date_type=[%s]" $retval "$date_type" 693 694 # Return if user has either pressed ESC or chosen Cancel/No 695 [ $retval -eq $DIALOG_OK ] || return $retval 696 697 case "$date_type" in 698 1) # Account does not expire 699 _input="" 700 break ;; 701 702 2) # Edit date/time with a calendar 703 local _input_date _input_time ret_date ret_time 704 705 local secs="$_input" 706 { f_isinteger "$secs" && [ $secs -gt 0 ]; } || secs= 707 _input_date=$( date -j -f "%s" -- "$secs" \ 708 "+%d %m %Y" 2> /dev/null ) 709 ret_date=$( 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 \"\$prompt\" \ 716 $cheight $cwidth \ 717 $_input_date \ 718 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 719 ) 720 retval=$? 721 f_dialog_data_sanitize ret_date 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 $DIALOG_OK ] || continue 726 727 _input_time= 728 [ "$secs" ] && _input_time=$( date -j \ 729 -f %s -- "$_input" "+%H %M %S" 2> /dev/null ) 730 ret_time=$( eval $DIALOG \ 731 --title \"\$DIALOG_TITLE\" \ 732 --backtitle \"\$DIALOG_BACKTITLE\" \ 733 --hline \"\$hline\" \ 734 --ok-label \"\$msg_ok\" \ 735 --cancel-label \"\$msg_cancel\" \ 736 --timebox \"\$prompt\" \ 737 $theight $twidth \ 738 $_input_time \ 739 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 740 ) 741 retval=$? 742 f_dialog_data_sanitize ret_time 743 f_dprintf "retval=%u ret_time=[%s]" $retval "$ret_time" 744 745 # Return to menu if either ESC or Cancel/No 746 [ $retval -eq $DIALOG_OK ] || continue 747 748 _input=$( date \ 749 -j -f "%d/%m/%Y %T" \ 750 -- "$ret_date $ret_time" \ 751 +%s 2> /dev/null ) 752 f_dprintf "_input=[%s]" "$_input" 753 break ;; 754 755 3) # Enter number of days into the future 756 local ret_days seconds="$( date +%s )" 757 758 f_isinteger "$_input" || _input=0 759 [ $_input -gt 0 -a $_input -gt $seconds ] && 760 ret_days=$(( ( $_input - $seconds ) / 86400 )) 761 f_isinteger "$ret_days" && 762 ret_days=$(( $ret_days + 1 )) 763 764 # Return to menu if either ESC or Cancel/No 765 f_dialog_input ret_days \ 766 "$msg_account_expires_in_how_many_days" \ 767 "$ret_days" "$hline" || continue 768 769 # Taint-check the user's input 770 if ! f_isinteger "$ret_days"; then 771 f_show_msg "$msg_invalid_number_of_days" 772 continue 773 fi 774 775 f_dprintf "ret_days=[%s]" "$ret_days" 776 case "$ret_days" in 777 [-+]*) _input=$( date -v${ret_days}d +%s ) ;; 778 0) _input=$( date +%s ) ;; 779 *) _input=$( date -v+${ret_days}d +%s ) ;; 780 esac 781 f_dprintf "_input=[%s]" "$_input" 782 break ;; 783 784 4) # Enter value manually 785 local msg ret_secs 786 f_sprintf msg "$msg_number_of_seconds_since_epoch" \ 787 "$( date -r 1 "+%c %Z" )" 788 789 # Return to menu if either ESC or Cancel/No 790 f_dialog_input ret_secs "$msg" \ 791 "$_input" "$hline" || continue 792 793 _input="$ret_secs" 794 795 # Taint-check the user's input 796 if ! f_isinteger "${_input:-0}"; then 797 f_show_msg "$msg_invalid_number_of_seconds" 798 continue 799 fi 800 801 f_dprintf "_input=[%s]" "$_input" 802 break ;; 803 804 esac 805 806 done # Loop forever 807 808 pw_account_expire="$_input" 809 save_flag=1 810 811 f_dprintf "pw_account_expire: [%s]->[%s]" \ 812 "$cur_pw_account_expire" "$pw_account_expire" 813 814 return $DIALOG_OK 815} 816 817# f_dialog_input_home_dir [$home_dir] 818# 819# Allow the user to enter a new home directory for a given user. If the user 820# does not cancel or press ESC, the $pw_home_dir variable will hold the newly- 821# configured value upon return. 822# 823f_dialog_input_home_dir() 824{ 825 local _input="$1" 826 827 # Return if user has either pressed ESC or chosen Cancel/No 828 f_dialog_input _input "$msg_home_directory" "$_input" \ 829 "$hline_alnum_punc_tab_enter" || return $? 830 831 pw_home_dir="$_input" 832 save_flag=1 833 834 f_dprintf "pw_home_dir: [%s]->[%s]" "$cur_pw_home_dir" "$pw_home_dir" 835 836 return $DIALOG_OK 837} 838 839# f_dialog_input_home_create 840# 841# Prompt the user to confirm creation of a given user's home directory. If the 842# user does not cancel (by choosing "No") or press ESC, the $pw_home_create 843# variable will hold $msg_yes upon return, otherwise $msg_no. Use these return 844# variables ($msg_yes and $msg_no) for comparisons to be i18n-compatible. 845# 846f_dialog_input_home_create() 847{ 848 local retval 849 850 f_dialog_yesno "$msg_create_home_directory" 851 retval=$? 852 853 if [ $retval -eq $DIALOG_OK ]; then 854 pw_home_create="$msg_yes" 855 else 856 pw_home_create="$msg_no" 857 fi 858 save_flag=1 859 860 f_dprintf "pw_home_create: [%s]->[%s]" \ 861 "$cur_pw_home_create" "$pw_home_create" 862 863 [ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC 864} 865 866# f_dialog_input_group_delete 867# 868# Prompt the user to confirm deletion of a given user's primary group. If the 869# user does not cancel (by choosing "No") or press ESC, the $pw_group_delete 870# variable will hold $msg_yes upon return, otherwise $msg_no. Use these return 871# variables ($msg_yes and $msg_no) for comparisons to be i18n-compatible. 872# 873f_dialog_input_group_delete() 874{ 875 local retval 876 877 if f_isinteger "$pw_gid"; then 878 if [ $pw_gid -lt 1000 ]; then 879 f_dialog_noyes "$msg_delete_primary_group" 880 else 881 f_dialog_yesno "$msg_delete_primary_group" 882 fi 883 elif [ "$pw_gid" ]; then 884 local gid=0 885 gid=$( pw groupshow "$pw_gid" | awk -F: '{print $3}' ) 886 if f_isinteger "$gid" && [ $gid -lt 1000 ]; then 887 f_dialog_noyes "$msg_delete_primary_group" 888 else 889 f_dialog_yesno "$msg_delete_primary_group" 890 fi 891 else 892 f_dialog_yesno "$msg_delete_primary_group" 893 fi 894 retval=$? 895 896 if [ $retval -eq $DIALOG_OK ]; then 897 pw_group_delete="$msg_yes" 898 else 899 pw_group_delete="$msg_no" 900 fi 901 save_flag=1 902 903 f_dprintf "pw_group_delete: [%s]->[%s]" \ 904 "$cur_pw_group_delete" "$pw_group_delete" 905 906 [ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC 907} 908 909# f_dialog_input_home_delete 910# 911# Prompt the user to confirm deletion of a given user's home directory. If the 912# user does not cancel (by choosing "No") or press ESC, the $pw_home_delete 913# variable will hold $msg_yes upon return, otherwise $msg_no. Use these return 914# variables ($msg_yes and $msg_no) for comparisons to be i18n-compatible. 915# 916f_dialog_input_home_delete() 917{ 918 local retval 919 920 f_dialog_yesno "$msg_delete_home_directory" 921 retval=$? 922 923 if [ $retval -eq $DIALOG_OK ]; then 924 pw_home_delete="$msg_yes" 925 else 926 pw_home_delete="$msg_no" 927 fi 928 save_flag=1 929 930 f_dprintf "pw_home_delete: [%s]->[%s]" \ 931 "$cur_pw_home_delete" "$pw_home_delete" 932 933 [ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC 934} 935 936# f_dialog_input_dotfiles_create 937# 938# Prompt the user to confirm population of a given user's home directory with 939# sample dotfiles. If the user does not cancel (by choosing "No") or press ESC, 940# the $pw_dotfiles_create variable will hold $msg_yes upon return, otherwise 941# $msg_no. Use these return variables ($msg_yes and $msg_no) for comparison to 942# be i18n-compatible. 943# 944f_dialog_input_dotfiles_create() 945{ 946 local retval 947 948 f_dialog_yesno "$msg_create_dotfiles" 949 retval=$? 950 951 if [ $retval -eq $DIALOG_OK ]; then 952 pw_dotfiles_create="$msg_yes" 953 else 954 pw_dotfiles_create="$msg_no" 955 fi 956 save_flag=1 957 958 f_dprintf "pw_dotfiles_create: [%s]->[%s]" \ 959 "$cur_pw_dotfiles_create" "$pw_dotfiles_create" 960 961 [ $retval -ne $DIALOG_ESC ] # return failure if user pressed ESC 962} 963 964# f_dialog_input_shell [$shell] 965# 966# Allow the user to select a new login shell for a given user. If the user does 967# not cancel or press ESC, the $pw_home_dir variable will hold the newly- 968# configured value upon return. 969# 970# 971f_dialog_input_shell() 972{ 973 local _input="$1" 974 local prompt="$msg_select_login_shell" 975 local radio_list= # Calculated below 976 local hline="$hline_arrows_space_tab_enter" 977 978 # 979 # Generate the radiolist of shells 980 # 981 local shell 982 for shell in $( awk '!/^[[:space:]]*(#|$)/{print}' "$ETC_SHELLS" ); do 983 # Format of a radiolist menu entry is "tag item status" 984 if [ "$shell" = "$_input" ]; then 985 radio_list="$radio_list '$shell' '' 'on'" 986 else 987 radio_list="$radio_list '$shell' '' 'off'" 988 fi 989 done 990 991 local height width rows 992 eval f_dialog_radiolist_size height width rows \ 993 \"\$DIALOG_TITLE\" \ 994 \"\$DIALOG_BACKTITLE\" \ 995 \"\$prompt\" \ 996 \"\$hline\" \ 997 $radio_list 998 999 _input=$( eval $DIALOG \ 1000 --title \"\$DIALOG_TITLE\" \ 1001 --backtitle \"\$DIALOG_BACKTITLE\" \ 1002 --hline \"\$hline\" \ 1003 --ok-label \"\$msg_ok\" \ 1004 --cancel-label \"\$msg_cancel\" \ 1005 --radiolist \"\$prompt\" \ 1006 $height $width $rows \ 1007 $radio_list \ 1008 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 1009 ) || return $? 1010 # Return if user either pressed ESC or chose Cancel/No 1011 f_dialog_data_sanitize _input 1012 1013 pw_shell="$_input" 1014 save_flag=1 1015 1016 f_dprintf "pw_shell: [%s]->[%s]" "$cur_pw_shell" "$pw_shell" 1017 1018 return $DIALOG_OK 1019} 1020 1021############################################################ MAIN 1022 1023f_dprintf "%s: Successfully loaded." usermgmt/user_input.subr 1024 1025fi # ! $_USERMGMT_USER_INPUT_SUBR 1026