1if [ ! "$_USERMGMT_GROUP_INPUT_SUBR" ]; then _USERMGMT_GROUP_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_include $BSDCFG_SHARE/dialog.subr 35f_include $BSDCFG_SHARE/strings.subr 36 37BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt" 38f_include_lang $BSDCFG_LIBE/include/messages.subr 39f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 40 41############################################################ FUNCTIONS 42 43# f_input_group $group 44# 45# Given $group name or id, create the environment variables group_name, 46# group_gid, and group_members (and group_password is reset to NULL). 47# 48f_input_group() 49{ 50 eval $( pw groupshow "$1" | awk -F: ' 51 { 52 printf "group_name='\'%s\''\n", $1 53 printf "group_password=\n" 54 printf "group_gid='\'%s\''\n", $3 55 printf "group_members='\'%s\''\n", $4 56 exit 57 }' ) 58} 59 60# f_dialog_menu_group_list 61# 62# Allows the user to select a group from a list. 63# 64f_dialog_menu_group_list() 65{ 66 local menu_list size 67 local hline="$hline_alnum_punc_tab_enter" 68 69 menu_list=" 70 'X $msg_exit' '' 71 " # END-QUOTE 72 73 # Add groups from group(5) 74 menu_list="$menu_list $( pw groupshow -a | awk -F: ' 75 !/^[[:space:]]*(#|$)/ { 76 printf "'\'%s\'\ \'%s\''\n", $1, $1 77 }' 78 )" 79 80 size=$( eval f_dialog_menu_size \ 81 \"\$DIALOG_TITLE\" \ 82 \"\$DIALOG_BACKTITLE\" \ 83 \"\" \ 84 \"\$hline\" \ 85 $menu_list ) 86 87 local dialog_menu 88 dialog_menu=$( eval $DIALOG \ 89 --clear --title \"\$DIALOG_TITLE\" \ 90 --backtitle \"\$DIALOG_BACKTITLE\" \ 91 --hline \"\$hline\" \ 92 --ok-label \"\$msg_ok\" \ 93 --cancel-label \"\$msg_cancel\" \ 94 --menu \"\" $size $menu_list \ 95 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 96 ) 97 local retval=$? 98 setvar DIALOG_MENU_$$ "$dialog_menu" 99 return $retval 100} 101 102# f_dialog_input_group_name [$group_name] 103# 104# Allows the user to enter a new groupname for a given group. If the user does 105# not cancel or press ESC, the $group_name variable will hold the 106# newly-configured value upon return. 107# 108# If $cur_group_name is defined, the user can enter that and by-pass error- 109# checking (allowing the user to "revert" to an old value without, for example, 110# being told that the groupname already exists). 111# 112f_dialog_input_group_name() 113{ 114 local msg="$( printf "$msg_group" )" 115 local hline="$hline_alnum_tab_enter" 116 117 # 118 # Loop until the user provides taint-free/valid input 119 # 120 local size retval _name="$1" _input="$1" 121 while :; do 122 size=$( f_dialog_inputbox_size \ 123 "$DIALOG_TITLE" \ 124 "$DIALOG_BACKTITLE" \ 125 "$msg" \ 126 "$_input" \ 127 "$hline" ) 128 129 local dialog_inputbox 130 dialog_inputbox=$( eval $DIALOG \ 131 --title \"\$DIALOG_TITLE\" \ 132 --backtitle \"\$DIALOG_BACKTITLE\" \ 133 --hline \"\$hline\" \ 134 --ok-label \"\$msg_ok\" \ 135 --cancel-label \"\$msg_cancel\" \ 136 --inputbox \"\$msg\" $size \ 137 \"\$_input\" \ 138 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 139 ) 140 141 retval=$? 142 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 143 _input=$( f_dialog_inputstr ) 144 145 # Return if user has either pressed ESC or chosen Cancel/No 146 [ $retval -eq $SUCCESS ] || return $retval 147 148 # Check for no-change 149 [ "$_input" = "$_name" ] && return $SUCCESS 150 151 # Check for reversion 152 if [ "$_input" = "$cur_group_name" ]; then 153 group_name="$cur_group_name" 154 return $SUCCESS 155 fi 156 157 # Check for NULL entry 158 if [ ! "$_input" ]; then 159 f_show_msg "$msg_group_is_empty" 160 continue 161 fi 162 163 # Check for invalid entry 164 if ! echo "$_input" | grep -q "^[[:alpha:]]"; then 165 f_show_msg "$msg_group_must_start_with_letter" 166 continue 167 fi 168 169 # Check for duplicate entry 170 if f_quietly pw groupshow -n "$_input"; then 171 f_show_msg "$msg_group_already_used" "$_input" 172 continue 173 fi 174 175 group_name="$_input" 176 break 177 done 178 save_flag=1 179 180 f_dprintf "group_name: [$cur_group_name]->[$group_name]" 181 182 return $SUCCESS 183} 184 185# f_dialog_input_group_password 186# 187# Prompt the user to enter a password (twice). 188# 189f_dialog_input_group_password() 190{ 191 local hline="$hline_alnum_punc_tab_enter" 192 local msg size rmsg rsize 193 194 msg=$( printf "$msg_group_password" ) 195 size=$( f_dialog_inputbox_size \ 196 "$DIALOG_TITLE" \ 197 "$DIALOG_BACKTITLE" \ 198 "$msg" \ 199 "" \ 200 "$hline" ) 201 202 rmsg=$( printf "$msg_reenter_group_password" ) 203 rsize=$( f_dialog_inputbox_size \ 204 "$DIALOG_TITLE" \ 205 "$DIALOG_BACKTITLE" \ 206 "$rmsg" \ 207 "" \ 208 "$hline" ) 209 210 # 211 # Loop until the user provides taint-free/valid input 212 # 213 local retval _password1 _password2 214 while :; do 215 local dialog_inputbox 216 dialog_inputbox=$( eval $DIALOG \ 217 --title \"\$DIALOG_TITLE\" \ 218 --backtitle \"\$DIALOG_BACKTITLE\" \ 219 --hline \"\$hline\" \ 220 --ok-label \"\$msg_ok\" \ 221 --cancel-label \"\$msg_cancel\" \ 222 --insecure \ 223 --passwordbox \"\$msg\" $size \ 224 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 225 ) 226 227 retval=$? 228 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 229 _password1=$( f_dialog_inputstr ) 230 231 # Return if user has either pressed ESC or chosen Cancel/No 232 [ $retval -eq $SUCCESS ] || return $retval 233 234 dialog_inputbox=$( eval $DIALOG \ 235 --title \"\$DIALOG_TITLE\" \ 236 --backtitle \"\$DIALOG_BACKTITLE\" \ 237 --hline \"\$hline\" \ 238 --ok-label \"\$msg_ok\" \ 239 --cancel-label \"\$msg_cancel\" \ 240 --insecure \ 241 --passwordbox \"\$rmsg\" $rsize \ 242 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 243 ) 244 245 retval=$? 246 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 247 _password2=$( f_dialog_inputstr ) 248 249 # Return if user has either pressed ESC or chosen Cancel/No 250 [ $retval -eq $SUCCESS ] || return $retval 251 252 # Check for password mismatch 253 if [ "$_password1" != "$_password2" ]; then 254 f_show_msg "$msg_group_passwords_do_not_match" 255 continue 256 fi 257 258 # Check for NULL entry 259 if [ ! "$_password1" ]; then 260 f_dialog_yesno \ 261 "$msg_disable_password_auth_for_group" || 262 continue 263 pw_group_password_disable=1 264 else 265 pw_group_password_disable= 266 fi 267 268 group_password="$_password1" 269 break 270 done 271 save_flag=1 272 273 f_dprintf "group_password: [$cur_group_password]->[$group_password]" 274 275 return $SUCCESS 276} 277 278# f_dialog_input_group_gid [$group_gid] 279# 280# Allow the user to enter a new GID for a given group. If the user does not 281# cancel or press ESC, the $group_gid variable will hold the newly-configured 282# value upon return. 283# 284f_dialog_input_group_gid() 285{ 286 local msg size retval _input="$1" 287 local hline="$hline_num_tab_enter" 288 289 msg=$( printf "$msg_group_id_leave_empty_for_default" ) 290 size=$( f_dialog_inputbox_size \ 291 "$DIALOG_TITLE" \ 292 "$DIALOG_BACKTITLE" \ 293 "$msg" \ 294 "$_input" \ 295 "$hline" ) 296 297 local dialog_inputbox 298 dialog_inputbox=$( eval $DIALOG \ 299 --title \"\$DIALOG_TITLE\" \ 300 --backtitle \"\$DIALOG_BACKTITLE\" \ 301 --hline \"\$hline\" \ 302 --ok-label \"\$msg_ok\" \ 303 --cancel-label \"\$msg_cancel\" \ 304 --inputbox \"\$msg\" $size \ 305 \"\$_input\" \ 306 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 307 ) 308 309 retval=$? 310 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 311 _input=$( f_dialog_inputstr ) 312 313 # Return if user has either pressed ESC or chosen Cancel/No 314 [ $retval -eq $SUCCESS ] || return $retval 315 316 group_gid="$_input" 317 save_flag=1 318 319 f_dprintf "group_gid: [$cur_group_gid]->[$group_gid]" 320 321 return $SUCCESS 322} 323 324# f_dialog_input_group_members [$group_members] 325# 326# Allow the user to modify a list of members for a given group. If the user does 327# not cancel or press ESC, the $group_members variable will hold the newly- 328# configured value upon return. 329# 330f_dialog_input_group_members() 331{ 332 local menu_choice msg size retval _input="$1" 333 local hline="$hline_num_arrows_tab_enter" 334 local user 335 local menu_list 336 local all_users_valid 337 local _group_members 338 local checklist_users 339 340 menu_list=" 341 'X' '$msg_continue' 342 '1' '$msg_select_group_members_from_list' 343 '2' '$msg_enter_group_members_manually' 344 " # END-QUOTE 345 346 local dialog_menu 347 while :; do 348 msg="$msg_group_members:" 349 menu_size=$( eval f_dialog_menu_size \ 350 \"\$DIALOG_TITLE\" \ 351 \"\$DIALOG_BACKTITLE\" \ 352 \"\$msg\" \ 353 \"\$hline\" \ 354 $menu_list ) 355 dialog_menu=$( eval $DIALOG \ 356 --title \"\$DIALOG_TITLE\" \ 357 --backtitle \"\$DIALOG_BACKTITLE\" \ 358 --hline \"\$hline\" \ 359 --ok-label \"\$msg_ok\" \ 360 --cancel-label \"\$msg_cancel\" \ 361 --menu \"\$msg\" $menu_size \ 362 $menu_list \ 363 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 364 ) 365 retval=$? 366 setvar DIALOG_MENU_$$ "$dialog_menu" 367 menu_choice=$( f_dialog_menutag ) 368 f_dprintf "retval=$retval menu_choice=[$menu_choice]" 369 370 # Return if user has either pressed ESC or chosen Cancel/No 371 [ $retval -eq $SUCCESS ] || return $retval 372 373 case "$menu_choice" in 374 X) # Exit 375 break ;; 376 1) # Select Group Members from a list 377 user_list=$( pw usershow -a | awk -F: ' 378 !/^[[:space:]]*(#|$)/ { printf "%s\n", $1 }' ) 379 checklist_users= 380 for user in $user_list; do 381 checklist_users="$checklist_users $user \"\"" 382 if echo "$_input" | grep -q "\<$user\>"; then 383 checklist_users="$checklist_users on" 384 else 385 checklist_users="$checklist_users off" 386 fi 387 done 388 389 size=$( eval f_dialog_radiolist_size \ 390 \"\$DIALOG_TITLE\" \ 391 \"\$DIALOG_BACKTITLE\" \ 392 \"\" \ 393 \"\$hline\" \ 394 $checklist_users ) 395 local dialog_inputbox 396 dialog_inputbox=$( eval $DIALOG \ 397 --title \"\$DIALOG_TITLE\" \ 398 --backtitle \"\$DIALOG_BACKTITLE\" \ 399 --separate-output \ 400 --hline \"\$hline\" \ 401 --ok-label \"\$msg_ok\" \ 402 --cancel-label \"\$msg_cancel\" \ 403 --checklist \"\$msg\" $size \ 404 $checklist_users \ 405 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 406 ) 407 retval=$? 408 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 409 _group_members=$( f_dialog_inputstr | tr '\n' ' ' | 410 sed -e 's/[[:space:]]\{1,\}/,/g;s/^,//;s/,$//' ) 411 412 # Return to previous menu if user has either 413 # pressed ESC or chosen Cancel/No 414 [ $retval -eq $SUCCESS ] || continue 415 416 _input="$_group_members" 417 ;; 418 2) # Enter Group Members manually 419 hline="$hline_num_tab_enter" 420 msg=$( 421 printf "$msg_group_members ($msg_separated_by_commas)" 422 ) 423 size=$( f_dialog_inputbox_size \ 424 "$DIALOG_TITLE" \ 425 "$DIALOG_BACKTITLE" \ 426 "$msg" \ 427 "$_input" \ 428 "$hline" ) 429 430 local dialog_inputbox 431 dialog_inputbox=$( eval $DIALOG \ 432 --title \"\$DIALOG_TITLE\" \ 433 --backtitle \"\$DIALOG_BACKTITLE\" \ 434 --hline \"\$hline\" \ 435 --ok-label \"\$msg_ok\" \ 436 --cancel-label \"\$msg_cancel\" \ 437 --inputbox \"\$msg\" $size \ 438 \"\$_input\" \ 439 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 440 ) 441 442 retval=$? 443 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 444 _group_members=$( f_dialog_inputstr ) 445 446 # Return to previous menu if user has either 447 # pressed ESC or chosen Cancel/No 448 [ $retval -eq $SUCCESS ] || continue 449 450 _input="$_group_members" 451 ;; 452 esac 453 done 454 455 group_members="$_input" 456 save_flag=1 457 f_dprintf "group_members: [$cur_group_members]->[$group_members]" 458 459 return $SUCCESS 460} 461 462fi # ! $_USERMGMT_GROUP_INPUT_SUBR 463