Deleted Added
sdiff udiff text old ( 262904 ) new ( 263980 )
full compact
1if [ ! "$_USERMGMT_GROUP_SUBR" ]; then _USERMGMT_GROUP_SUBR=1
2#
3# Copyright (c) 2012 Ron McDowell
4# Copyright (c) 2012-2014 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: head/usr.sbin/bsdconfig/usermgmt/share/group.subr 262904 2014-03-07 20:44:19Z dteske $
29#
30############################################################ INCLUDES
31
32BSDCFG_SHARE="/usr/share/bsdconfig"
33. $BSDCFG_SHARE/common.subr || exit 1
34f_dprintf "%s: loading includes..." usermgmt/group.subr
35f_include $BSDCFG_SHARE/dialog.subr
36f_include $BSDCFG_SHARE/usermgmt/group_input.subr
37
38BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="070.usermgmt"
39f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
40
41############################################################ CONFIGURATION
42
43# set some reasonable defaults if /etc/adduser.conf does not exist.
44[ -f /etc/adduser.conf ] && f_include /etc/adduser.conf
45: ${passwdtype:="yes"}
46
47############################################################ FUNCTIONS
48
49# f_group_add [$group]
50#
51# Add a group. If both $group (as a first argument) and $VAR_GROUP are unset
52# or NULL and we are running interactively, prompt the user to enter the name
53# of a new group and (if $VAR_NO_CONFIRM is unset or NULL) prompt the user to
54# answer some questions about the new group. Variables that can be used to
55# script user input:
56#
57# VAR_GROUP [Optional if running interactively]
58# The group to add. Ignored if given non-NULL first-argument.
59# VAR_GROUP_GID [Optional]
60# Numerical group ID to use. If NULL or unset, the group ID is
61# automatically chosen.
62# VAR_GROUP_MEMBERS [Optional]
63# Comma separated list of users that are a member of this group.
64# VAR_GROUP_PASSWORD [Optional]
65# newgrp(1) password to set for the group. Default if NULL or
66# unset is to disable newgrp(1) password authentication.
67#
68# Returns success if the group was successfully added.
69#
70f_group_add()
71{
72 local funcname=f_group_add
73 local title # Calculated below
74 local alert=f_show_msg no_confirm=
75
76 f_getvar $VAR_NO_CONFIRM no_confirm
77 [ "$no_confirm" ] && alert=f_show_info
78
79 local input
80 f_getvar 3:-\$$VAR_GROUP input "$1"
81
82 #
83 # NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
84 # instead of name. Work-around is to also pass `-g GID' at the same
85 # time (any GID will do; but `-1' is appropriate for this context).
86 #
87 if [ "$input" ] && f_quietly pw groupshow -n "$input" -g -1; then
88 f_show_err "$msg_group_already_used" "$input"
89 return $FAILURE
90 fi
91
92 local group_name="$input"
93 while f_interactive && [ ! "$group_name" ]; do
94 f_dialog_input_group_name group_name "$group_name" ||
95 return $SUCCESS
96 [ "$group_name" ] ||
97 f_show_err "$msg_please_enter_a_group_name"
98 done
99
100 local group_password group_gid group_members
101 f_getvar $VAR_GROUP_PASSWORD group_password
102 f_getvar $VAR_GROUP_GID group_gid
103 f_getvar $VAR_GROUP_MEMBERS group_members
104
105 local group_password_disable=
106 f_interactive || [ "$group_password" ] || group_password_disable=1
107
108 if f_interactive && [ ! "$no_confirm" ]; then
109 f_dialog_noyes \
110 "$msg_use_default_values_for_all_account_details"
111 retval=$?
112 if [ $retval -eq $DIALOG_ESC ]; then
113 return $SUCCESS
114 elif [ $retval -ne $DIALOG_OK ]; then
115 #
116 # Ask series of questions to pre-fill the editor screen
117 #
118 # Defaults used in each dialog should allow the user to
119 # simply hit ENTER to proceed and cancelling a single
120 # dialog cause them to return to the previous menu.
121 #
122
123 if [ "$passwdtype" = "yes" ]; then
124 f_dialog_input_group_password group_password \
125 group_password_disable ||
126 return $FAILURE
127 fi
128 f_dialog_input_group_gid group_gid "$group_gid" ||
129 return $FAILURE
130 f_dialog_input_group_members group_members \
131 "$group_members" || return $FAILURE
132 fi
133 fi
134
135 #
136 # Loop until the user decides to Exit, Cancel, or presses ESC
137 #
138 title="$msg_add $msg_group: $group_name"
139 if f_interactive; then
140 local mtag retval defaultitem=
141 while :; do
142 f_dialog_title "$title"
143 f_dialog_menu_group_add "$defaultitem"
144 retval=$?
145 f_dialog_title_restore
146 f_dialog_menutag_fetch mtag
147 f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
148 defaultitem="$mtag"
149
150 # Return if user either pressed ESC or chose Cancel/No
151 [ $retval -eq $DIALOG_OK ] || return $FAILURE
152
153 case "$mtag" in
154 X) # Add/Exit
155 local cmd="pw groupadd -n '$group_name'"
156 [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
157 [ "$group_members" ] &&
158 cmd="$cmd -M '$group_members'"
159
160 # Execute the command (break on success)
161 if [ "$group_password_disable" ]; then
162 f_eval_catch $funcname pw '%s -h -' "$cmd"
163 elif [ "$group_password" ]; then
164 echo "$group_password" |
165 f_eval_catch $funcname \
166 pw '%s -h 0' "$cmd"
167 else
168 f_eval_catch $funcname pw '%s' "$cmd"
169 fi && break
170 ;;
171 1) # Group Name (prompt for new group name)
172 f_dialog_input_group_name input "$group_name" ||
173 continue
174 if f_quietly pw groupshow -n "$input" -g -1; then
175 f_show_err "$msg_group_already_used" "$input"
176 continue
177 fi
178 group_name="$input"
179 title="$msg_add $msg_group: $group_name"
180 ;;
181 2) # Password
182 f_dialog_input_group_password group_password \
183 group_password_disable
184 ;;
185 3) # Group ID
186 f_dialog_input_group_gid group_gid "$group_gid"
187 ;;
188 4) # Group Members
189 f_dialog_input_group_members group_members \
190 "$group_members"
191 ;;
192 esac
193 done
194 else
195 # Form the command
196 local cmd="pw groupadd -n '$group_name'"
197 [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
198 [ "$group_members" ] && cmd="$cmd -M '$group_members'"
199
200 # Execute the command
201 local retval err
202 if [ "$group_password_disable" ]; then
203 f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
204 elif [ "$group_password" ]; then
205 echo "$group_password" | f_eval_catch -k err \
206 $funcname pw '%s -h 0' "$cmd"
207 else
208 f_eval_catch -k err $funcname pw '%s' "$cmd"
209 fi
210 retval=$?
211 if [ $retval -ne $SUCCESS ]; then
212 f_show_err "%s" "$err"
213 return $retval
214 fi
215 fi
216
217 f_dialog_title "$title"
218 $alert "$msg_group_added"
219 f_dialog_title_restore
220 [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2
221
222 return $SUCCESS
223}
224
225# f_group_delete [$group]
226#
227# Delete a group. If both $group (as a first argument) and $VAR_GROUP are unset
228# or NULL and we are running interactively, prompt the user to select a group
229# from a list of available groups. Variables that can be used to script user
230# input:
231#
232# VAR_GROUP [Optional if running interactively]
233# The group to delete. Ignored if given non-NULL first-argument.
234#
235# Returns success if the group was successfully deleted.
236#
237f_group_delete()
238{
239 local funcname=f_group_delete
240 local title # Calculated below
241 local alert=f_show_msg no_confirm=
242
243 f_getvar $VAR_NO_CONFIRM no_confirm
244 [ "$no_confirm" ] && alert=f_show_info
245
246 local input
247 f_getvar 3:-\$$VAR_GROUP input "$1"
248
249 local group_name group_password group_gid group_members
250 if [ "$input" ] && ! f_input_group "$input"; then
251 f_show_err "$msg_group_not_found" "$input"
252 return $FAILURE
253 fi
254
255 #
256 # Loop until the user decides to Exit, Cancel, or presses ESC
257 #
258 title="$msg_delete $msg_group: $group_name"
259 if f_interactive; then
260 local mtag retval defaultitem=
261 while :; do
262 f_dialog_title "$title"
263 f_dialog_menu_group_delete "$group_name" "$defaultitem"
264 retval=$?
265 f_dialog_title_restore
266 f_dialog_menutag_fetch mtag
267 f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
268 defaultitem="$mtag"
269
270 # Return if user either pressed ESC or chose Cancel/No
271 [ $retval -eq $DIALOG_OK ] || return $FAILURE
272
273 case "$mtag" in
274 X) # Delete/Exit
275 f_eval_catch $funcname pw 'pw groupdel "%s"' \
276 "$group_name" && break
277 ;;
278 1) # Group Name (select different group from list)
279 f_dialog_menu_group_list "$group_name" || continue
280 f_dialog_menutag_fetch mtag
281
282 [ "$mtag" = "X $msg_exit" ] && continue
283
284 if ! f_input_group "$mtag"; then
285 f_show_err "$msg_group_not_found" "$mtag"
286 # Attempt to fall back to previous selection
287 f_input_group "$input" || return $FAILURE
288 else
289 input="$mtag"
290 fi
291 ;;
292 esac
293 done
294 else
295 local retval err
296 f_eval_catch -k err $funcname pw \
297 'pw groupdel "%s"' "$group_name"
298 retval=$?
299 if [ $retval -ne $SUCCESS ]; then
300 f_show_err "%s" "$err"
301 return $retval
302 fi
303 fi
304
305 f_dialog_title "$title"
306 $alert "$msg_group_deleted"
307 f_dialog_title_restore
308 [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2
309
310 return $SUCCESS
311}
312
313# f_group_edit [$group]
314#
315# Modify a group. If both $group (as a first argument) and $VAR_GROUP are unset
316# or NULL and we are running interactively, prompt the user to select a group
317# from a list of available groups. Variables that can be used to script user
318# input:
319#
320# VAR_GROUP [Optional if running interactively]
321# The group to modify. Ignored if given non-NULL first-argument.
322# VAR_GROUP_GID [Optional]
323# Numerical group ID to set. If NULL or unset, the group ID is
324# unchanged.
325# VAR_GROUP_MEMBERS [Optional]
326# Comma separated list of users that are a member of this group.
327# If NULL or unset, group membership is unmodified.
328# VAR_GROUP_PASSWORD [Optional]
329# newgrp(1) password to set for the group. If unset, the password
330# is unmodified. If NULL, the newgrp(1) password is disabled.
331#
332# Returns success if the group was successfully modified.
333#
334f_group_edit()
335{
336 local funcname=f_group_edit
337 local title # Calculated below
338 local alert=f_show_msg no_confirm=
339
340 f_getvar $VAR_NO_CONFIRM no_confirm
341 [ "$no_confirm" ] && alert=f_show_info
342
343 local input
344 f_getvar 3:-\$$VAR_GROUP input "$1"
345
346 #
347 # NB: pw(8) has a ``feature'' wherein `-n name' can be taken as GID
348 # instead of name. Work-around is to also pass `-g GID' at the same
349 # time (any GID will do; but `-1' is appropriate for this context).
350 #
351 if [ "$input" ] && ! f_quietly pw groupshow -n "$input" -g -1; then
352 f_show_err "$msg_group_not_found" "$input"
353 return $FAILURE
354 fi
355
356 if f_interactive && [ ! "$input" ]; then
357 f_dialog_menu_group_list || return $SUCCESS
358 f_dialog_menutag_fetch input
359 [ "$input" = "X $msg_exit" ] && return $SUCCESS
360 elif [ ! "$input" ]; then
361 f_show_err "$msg_no_group_specified"
362 return $FAILURE
363 fi
364
365 local group_name group_password group_gid group_members
366 if ! f_input_group "$input"; then
367 f_show_err "$msg_group_not_found" "$input"
368 return $FAILURE
369 fi
370
371 f_isset $VAR_GROUP_GID && f_getvar $VAR_GROUP_GID group_gid
372 local null_members=
373 if f_isset $VAR_GROUP_MEMBERS; then
374 f_getvar $VAR_GROUP_MEMBERS group_members
375 [ "$group_members" ] || null_members=1
376 fi
377 local group_password_disable=
378 if f_isset $VAR_GROUP_PASSWORD; then
379 f_getvar $VAR_GROUP_PASSWORD group_password
380 [ "$group_password" ] || group_password_disable=1
381 fi
382
383 #
384 # Loop until the user decides to Exit, Cancel, or presses ESC
385 #
386 title="$msg_edit_view $msg_group: $group_name"
387 if f_interactive; then
388 local mtag retval defaultitem=
389 while :; do
390 f_dialog_title "$title"
391 f_dialog_menu_group_edit "$defaultitem"
392 retval=$?
393 f_dialog_title_restore
394 f_dialog_menutag_fetch mtag
395 f_dprintf "retval=%u mtag=[%s]" $retval "$mtag"
396 defaultitem="$mtag"
397
398 # Return if user either pressed ESC or chose Cancel/No
399 [ $retval -eq $DIALOG_OK ] || return $FAILURE
400
401 case "$mtag" in
402 X) # Save/Exit
403 local cmd="pw groupmod -n '$group_name'"
404 [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
405 [ "$group_members" -o "$null_members" ] &&
406 cmd="$cmd -M '$group_members'"
407
408 # Execute the command (break on success)
409 if [ "$group_password_disable" ]; then
410 f_eval_catch $funcname pw '%s -h -' "$cmd"
411 elif [ "$group_password" ]; then
412 echo "$group_password" |
413 f_eval_catch $funcname \
414 pw '%s -h 0' "$cmd"
415 else
416 f_eval_catch $funcname pw '%s' "$cmd"
417 fi && break
418 ;;
419 1) # Group Name (select different group from list)
420 f_dialog_menu_group_list "$group_name" || continue
421 f_dialog_menutag_fetch mtag
422
423 [ "$mtag" = "X $msg_exit" ] && continue
424
425 if ! f_input_group "$mtag"; then
426 f_show_err "$msg_group_not_found" "$mtag"
427 # Attempt to fall back to prevoius selection
428 f_input_group "$input" || return $FAILURE
429 else
430 input="$mtag"
431 fi
432 title="$msg_edit_view $msg_group: $group_name"
433 ;;
434 2) # Password
435 f_dialog_input_group_password group_password \
436 group_password_disable
437 ;;
438 3) # Group ID
439 f_dialog_input_group_gid group_gid "$group_gid"
440 ;;
441 4) # Group Members
442 f_dialog_input_group_members group_members \
443 "$group_members" && [ ! "$group_members" ] &&
444 null_members=1
445 ;;
446 esac
447 done
448 else
449 # Form the command
450 local cmd="pw groupmod -n '$group_name'"
451 [ "$group_gid" ] && cmd="$cmd -g '$group_gid'"
452 [ "$group_members" -o "$null_members" ] &&
453 cmd="$cmd -M '$group_members'"
454
455 # Execute the command
456 local retval err
457 if [ "$group_password_disable" ]; then
458 f_eval_catch -k err $funcname pw '%s -h -' "$cmd"
459 elif [ "$group_password" -o "$null_password" ]; then
460 echo "$group_password" | f_eval_catch -k err \
461 $funcname pw '%s -h 0' "$cmd"
462 else
463 f_eval_catch -k err $funcname pw '%s' "$cmd"
464 fi
465 retval=$?
466 if [ $retval -ne $SUCCESS ]; then
467 f_show_err "%s" "$err"
468 return $retval
469 fi
470 fi
471
472 f_dialog_title "$title"
473 $alert "$msg_group_updated"
474 f_dialog_title_restore
475 [ "$no_confirm" -a "$USE_DIALOG" ] && sleep 2
476
477 return $SUCCESS
478}
479
480############################################################ MAIN
481
482f_dprintf "%s: Successfully loaded." usermgmt/group.subr
483
484fi # ! $_USERMGMT_GROUP_SUBR