While preserving compatibility ('root' implied if not 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 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: Change the supplementary groups set to exactly the passed one, as a list
of comma-separated names or IDs.
-s: Modify 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 to still allow to omit '-u' to switch to
'root'. In order to avoid user confusion, if one but not all of the
user overrides are specified, then mdo(1) enforces that either '-u' or
'-k' is specified (not defaulting to '-u root' in this case).
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.
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.
Sponsored by: The FreeBSD Foundation
Sponsored by: Google LLC (GSoC 2025)
Co-authored-by: Kushagra Srivastava <kushagra1403@gmail.com>