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