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 # 115 # Loop until the user provides taint-free/valid input 116 # 117 local _name="$1" _input="$1" 118 while :; do 119 120 # Return if user has either pressed ESC or chosen Cancel/No 121 _input=$( f_dialog_input "$msg_group" "$_input" \ 122 "$hline_alnum_tab_enter" 123 ) || return 124 125 # Check for no-change 126 [ "$_input" = "$_name" ] && return $SUCCESS 127 128 # Check for reversion 129 if [ "$_input" = "$cur_group_name" ]; then 130 group_name="$cur_group_name" 131 return $SUCCESS 132 fi 133 134 # Check for NULL entry 135 if [ ! "$_input" ]; then 136 f_show_msg "$msg_group_is_empty" 137 continue 138 fi 139 140 # Check for invalid entry 141 if ! echo "$_input" | grep -q "^[[:alpha:]]"; then 142 f_show_msg "$msg_group_must_start_with_letter" 143 continue 144 fi 145 146 # Check for duplicate entry 147 if f_quietly pw groupshow -n "$_input"; then 148 f_show_msg "$msg_group_already_used" "$_input" 149 continue 150 fi 151 152 group_name="$_input" 153 break 154 done 155 save_flag=1 156 157 f_dprintf "group_name: [$cur_group_name]->[$group_name]" 158 159 return $SUCCESS 160} 161 162# f_dialog_input_group_password 163# 164# Prompt the user to enter a password (twice). 165# 166f_dialog_input_group_password() 167{ 168 local hline="$hline_alnum_punc_tab_enter" 169 local msg size rmsg rsize 170 171 msg=$( printf "$msg_group_password" ) 172 size=$( f_dialog_inputbox_size \ 173 "$DIALOG_TITLE" \ 174 "$DIALOG_BACKTITLE" \ 175 "$msg" \ 176 "" \ 177 "$hline" ) 178 179 rmsg=$( printf "$msg_reenter_group_password" ) 180 rsize=$( f_dialog_inputbox_size \ 181 "$DIALOG_TITLE" \ 182 "$DIALOG_BACKTITLE" \ 183 "$rmsg" \ 184 "" \ 185 "$hline" ) 186 187 # 188 # Loop until the user provides taint-free/valid input 189 # 190 local retval _password1 _password2 191 while :; do 192 local dialog_inputbox 193 dialog_inputbox=$( eval $DIALOG \ 194 --title \"\$DIALOG_TITLE\" \ 195 --backtitle \"\$DIALOG_BACKTITLE\" \ 196 --hline \"\$hline\" \ 197 --ok-label \"\$msg_ok\" \ 198 --cancel-label \"\$msg_cancel\" \ 199 --insecure \ 200 --passwordbox \"\$msg\" $size \ 201 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 202 ) 203 204 retval=$? 205 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 206 _password1=$( f_dialog_inputstr ) 207 208 # Return if user has either pressed ESC or chosen Cancel/No 209 [ $retval -eq $SUCCESS ] || return $retval 210 211 dialog_inputbox=$( eval $DIALOG \ 212 --title \"\$DIALOG_TITLE\" \ 213 --backtitle \"\$DIALOG_BACKTITLE\" \ 214 --hline \"\$hline\" \ 215 --ok-label \"\$msg_ok\" \ 216 --cancel-label \"\$msg_cancel\" \ 217 --insecure \ 218 --passwordbox \"\$rmsg\" $rsize \ 219 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 220 ) 221 222 retval=$? 223 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 224 _password2=$( f_dialog_inputstr ) 225 226 # Return if user has either pressed ESC or chosen Cancel/No 227 [ $retval -eq $SUCCESS ] || return $retval 228 229 # Check for password mismatch 230 if [ "$_password1" != "$_password2" ]; then 231 f_show_msg "$msg_group_passwords_do_not_match" 232 continue 233 fi 234 235 # Check for NULL entry 236 if [ ! "$_password1" ]; then 237 f_dialog_yesno \ 238 "$msg_disable_password_auth_for_group" || 239 continue 240 pw_group_password_disable=1 241 else 242 pw_group_password_disable= 243 fi 244 245 group_password="$_password1" 246 break 247 done 248 save_flag=1 249 250 f_dprintf "group_password: [$cur_group_password]->[$group_password]" 251 252 return $SUCCESS 253} 254 255# f_dialog_input_group_gid [$group_gid] 256# 257# Allow the user to enter a new GID for a given group. If the user does not 258# cancel or press ESC, the $group_gid variable will hold the newly-configured 259# value upon return. 260# 261f_dialog_input_group_gid() 262{ 263 local _input="$1" 264 265 # Return if user has either pressed ESC or chosen Cancel/No 266 _input=$( f_dialog_input "$msg_group_id_leave_empty_for_default" \ 267 "$_input" "$hline_num_tab_enter" 268 ) || return 269 270 group_gid="$_input" 271 save_flag=1 272 273 f_dprintf "group_gid: [$cur_group_gid]->[$group_gid]" 274 275 return $SUCCESS 276} 277 278# f_dialog_input_group_members [$group_members] 279# 280# Allow the user to modify a list of members for a given group. If the user does 281# not cancel or press ESC, the $group_members variable will hold the newly- 282# configured value upon return. 283# 284f_dialog_input_group_members() 285{ 286 local menu_choice msg size retval _input="$1" 287 local hline="$hline_num_arrows_tab_enter" 288 local user 289 local menu_list 290 local all_users_valid 291 local _group_members 292 local checklist_users 293 294 menu_list=" 295 'X' '$msg_continue' 296 '1' '$msg_select_group_members_from_list' 297 '2' '$msg_enter_group_members_manually' 298 " # END-QUOTE 299 300 local dialog_menu 301 while :; do 302 msg="$msg_group_members:" 303 menu_size=$( eval f_dialog_menu_size \ 304 \"\$DIALOG_TITLE\" \ 305 \"\$DIALOG_BACKTITLE\" \ 306 \"\$msg\" \ 307 \"\$hline\" \ 308 $menu_list ) 309 dialog_menu=$( eval $DIALOG \ 310 --title \"\$DIALOG_TITLE\" \ 311 --backtitle \"\$DIALOG_BACKTITLE\" \ 312 --hline \"\$hline\" \ 313 --ok-label \"\$msg_ok\" \ 314 --cancel-label \"\$msg_cancel\" \ 315 --menu \"\$msg\" $menu_size \ 316 $menu_list \ 317 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 318 ) 319 retval=$? 320 setvar DIALOG_MENU_$$ "$dialog_menu" 321 menu_choice=$( f_dialog_menutag ) 322 f_dprintf "retval=$retval menu_choice=[$menu_choice]" 323 324 # Return if user has either pressed ESC or chosen Cancel/No 325 [ $retval -eq $SUCCESS ] || return $retval 326 327 case "$menu_choice" in 328 X) # Exit 329 break ;; 330 1) # Select Group Members from a list 331 user_list=$( pw usershow -a | awk -F: ' 332 !/^[[:space:]]*(#|$)/ { printf "%s\n", $1 }' ) 333 checklist_users= 334 for user in $user_list; do 335 checklist_users="$checklist_users $user \"\"" 336 if echo "$_input" | grep -q "\<$user\>"; then 337 checklist_users="$checklist_users on" 338 else 339 checklist_users="$checklist_users off" 340 fi 341 done 342 343 size=$( eval f_dialog_radiolist_size \ 344 \"\$DIALOG_TITLE\" \ 345 \"\$DIALOG_BACKTITLE\" \ 346 \"\" \ 347 \"\$hline\" \ 348 $checklist_users ) 349 local dialog_inputbox 350 dialog_inputbox=$( eval $DIALOG \ 351 --title \"\$DIALOG_TITLE\" \ 352 --backtitle \"\$DIALOG_BACKTITLE\" \ 353 --separate-output \ 354 --hline \"\$hline\" \ 355 --ok-label \"\$msg_ok\" \ 356 --cancel-label \"\$msg_cancel\" \ 357 --checklist \"\$msg\" $size \ 358 $checklist_users \ 359 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 360 ) 361 retval=$? 362 setvar DIALOG_INPUTBOX_$$ "$dialog_inputbox" 363 _group_members=$( f_dialog_inputstr | tr '\n' ' ' | 364 sed -e 's/[[:space:]]\{1,\}/,/g;s/^,//;s/,$//' ) 365 366 # Return to previous menu if user has either 367 # pressed ESC or chosen Cancel/No 368 [ $retval -eq $SUCCESS ] || continue 369 370 _input="$_group_members" 371 ;; 372 2) # Enter Group Members manually 373 msg="$msg_group_members ($msg_separated_by_commas)" 374 375 # Return to previous menu if user has either 376 # pressed ESC or chosen Cancel/No 377 _group_members=$( f_dialog_input "$msg" "$_input" \ 378 "$hline_num_tab_enter" 379 ) || continue 380 381 _input="$_group_members" 382 ;; 383 esac 384 done 385 386 group_members="$_input" 387 save_flag=1 388 f_dprintf "group_members: [$cur_group_members]->[$group_members]" 389 390 return $SUCCESS 391} 392 393fi # ! $_USERMGMT_GROUP_INPUT_SUBR 394