An mdo(1) introduction
This post takes a quick look at a recent addition to FreeBSD: mdo(1). The mdo(1) utility allows one user to execute a command as another user. In that sense it is similar to the doas(1) program from OpenBSD and at the same time mdo(1) has noticeable differences when compared with doas(1).
kldload
The mdo(1) utility depends on the mdo policy – and the policy must be loaded into the kernel before we can use mdo(1) from the command line. The mac(4) man page provides some larger context about the Mandatory Access Control (mac) framework:
##
# Enable mac_do(4) policy
root@freebsd# kldload mac_do
The policy can be loaded into kernel at boot time by updating
/etc/rc.conf
through the sysrc(8) utility.
This change will make the policy persistent across reboots:
##
# Enable mac_do(4) policy at boot
root@freebsd# sysrc kld_list+=mac_do
sysctl
A rule defines which user or group members can execute a command as
another user. Rules are stored as a comma-separated list and can be
retrieved or modified via sysctl(8) under the
security.mac.do.rules
node.
If we were to draw a comparison with doas(1) then
security.mac.do.rules
would be roughly
equivalent to the doas.conf
configuration file but it is
neither a direct equivalent nor as feature-rich as
doas.conf
.
A rule has a left-hand side and a right-hand side, separated by the
:
character. The left-hand side describes the user id or
group id that is allowed to run commands as another user, and the
right-hand side describes the target user id. Let's look at some
examples:
##
# Permit alice to run commands as bob
root@freebsd# sysctl security.mac.do.rules=uid=$(id -u alice):$(id -u bob)
##
# Permit members of the beatles to run commands as bob
root@freebsd# gid=$(getent group beatles | awk -F: '{print $3}')
root@freebsd# sysctl security.mac.do.rules=gid=${gid}:$(id -u bob)
##
# Permit alice to run commands as anyone
root@freebsd# sysctl security.mac.do.rules=uid=$(id -u alice):any
mdo
With rules and everything else in place, the user alice can run commands as bob through the mdo(1) utility:
##
# Launch firefox as 'bob'
alice@freebsd$ mdo -u bob /usr/local/bin/firefox