]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.sbin/bsdconfig/usermgmt/share/group_input.subr
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.sbin / bsdconfig / usermgmt / share / group_input.subr
1 if [ ! "$_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
32 BSDCFG_SHARE="/usr/share/bsdconfig"
33 . $BSDCFG_SHARE/common.subr || exit 1
34 f_dprintf "%s: loading includes..." usermgmt/group_input.subr
35 f_include $BSDCFG_SHARE/dialog.subr
36 f_include $BSDCFG_SHARE/strings.subr
37
38 BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
39 f_include_lang $BSDCFG_LIBE/include/messages.subr
40 f_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 #
49 f_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 #
66 f_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 #
118 f_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 $DIALOG_OK
132
133                 # Check for reversion
134                 if [ "$_input" = "$cur_group_name" ]; then
135                         group_name="$cur_group_name"
136                         return $DIALOG_OK
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 $DIALOG_OK
165 }
166
167 # f_dialog_input_group_password
168 #
169 # Prompt the user to enter a password (twice).
170 #
171 f_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 $DIALOG_OK ] || 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 $DIALOG_OK ] || 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 $DIALOG_ESC ]; then
243                                 return $retval
244                         elif [ $retval -eq $DIALOG_OK ]; 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 $DIALOG_OK
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 #
270 f_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 $DIALOG_OK
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 #
292 f_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 $DIALOG_OK ] || 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 $DIALOG_OK
403 }
404
405 ############################################################ MAIN
406
407 f_dprintf "%s: Successfully loaded." usermgmt/group_input.subr
408
409 fi # ! $_USERMGMT_GROUP_INPUT_SUBR