leaf

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 run a command as another user, and it is conceptually similar to doas(1) from OpenBSD. 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
root@freebsd# sysctl security.mac.do.enabled=1

sysctl

A rule defines what user or member(s) of a group can run a command as another user. Multiple rules are separated by a comma. And rules are stored as kernel state that can be get or set via sysctl(8) and security.mac.do.rules.

If we were to draw a comparison with doas(1) then security.mac.do.rules would be equivalent to the doas.conf configuration file:

##
# 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@localhost# 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 weechat as the 'weechat' user
main@localhost$ mdo -u weechat /usr/local/bin/weechat