mdo(1): Add support and shortcuts for fully specifying users and groups
While preserving compatibility ('root' implied if no user is specified,
option '-i' not setting groups), introduce options to control finely
which user and group IDs are set in the launched process.
To minimize the risks of user error, mdo(1) by default enforces that all
user and group IDs are specified, either with explicit values from the
command-line or, if a known user name is passed with '-u', from the
corresponding content of the password and group databases. The other
main type of use cases is to start from the current process'
credentials, only amending part of them. It is now also possible to
blend both approaches, where some parts must be specified and the others
can just be amended or left as is.
Options:
- As before:
-u: Specifies a user name or ID to change all user IDs to. If a known
name is passed, also automatically sets all groups as per the password and group databases.
-i: Starts from the current groups, instead of having to specify them
by using '-u' with a known user name or explicitly.
- New:
-k: Starts from the current users (incompatible with '-u'). Implies '-i'.
-g: Sets/overrides the primary group IDs with the passed group name or ID.
-G: Sets/overrides the supplementary groups set with the passed list of
comma-separated names or IDs.
-s: Amend the supplementary groups set according to the list of
comma-separated directives from the following: - @: Empties the set. Must be the first directive. Incompatible with '-G'. - +<group>: Add a group to the set. - -<group>: Remove a group from the set. Takes precedence over +<group>.
--euid: Overrides the effective user ID.
--ruid: Overrides the real user ID.
--svuid: Overrides the saved user ID.
--egid: Overrides the effective group ID.
--rgid: Overrides the real group ID.
--svgid: Overrides the saved group ID.
Option '-k' was introduced as a requirement to be explicit when one
wants to keep the current user(s) instead of specifying new ones. This
is both for the purpose of avoiding foot-shooting and preserving the
possibility to omit '-u' to switch to 'root'. In order to avoid
confusion, if any user or group overrides are specified, mdo(1) however
enforces that either '-u' or '-k' has been specified (so, in practice,
'-u root' is implied only in the absence of any other options except
'-i').
Some base supplementary groups set is needed when '-s' is used without
directive '@'. It can be an explicit one specified with '-G',
effectively meaning that '-G' is processed before '-s'. Else, it is
determined from the password/group database (see initgroups(3)) if '-u'
with a user name was passed, or is simply the current set if '-i' (or
'-k') was specified. Other cases require specifying the full set (using
'-G' or '-s' with '@'), and will fail otherwise.
As the release process for 15.0 is progressing, this is committed in
advance of the still-in-progress tests and manual page updates.
Note for MFC to stable/14: As initgroups() has its old behavior,
consistently with it, remove the effective GID from being passed also as
a supplementary group.
Reviewed by: bapt
MFC after: 3 days
Relnotes: yes
Event: EuroBSDCon 2025
Sponsored by: The FreeBSD Foundation
Sponsored by: Google LLC (GSoC 2025)
Co-authored-by: Kushagra Srivastava <kushagra1403@gmail.com>
Differential Revision: https://reviews.freebsd.org/D52613
(cherry picked from commit 3ca1e69028acdee30739c0e0856692395a36fd21)