[Bug 298817] net-mgmt/semaphore: run as a dedicated user instead of root

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 24 Sep 2026 12:51:52 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=298817

            Bug ID: 298817
           Summary: net-mgmt/semaphore: run as a dedicated user instead of
                    root
           Product: Ports & Packages
           Version: Latest
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: Individual Port(s)
          Assignee: egypcio@FreeBSD.org
          Reporter: joneum@FreeBSD.org
          Assignee: egypcio@FreeBSD.org
             Flags: maintainer-feedback?(egypcio@FreeBSD.org)

Created attachment 275070
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=275070&action=edit
patch

Semaphore currently runs as root.  Since it executes Ansible playbooks and
holds SSH keys for the hosts it manages, a dedicated service account is the
safer default.

The patch reserves uid/gid 524 for semaphore in UIDs and GIDs, adds
USERS/GROUPS, creates /var/db/semaphore through the plist so the data
directory belongs to the service account, and starts the daemon with
daemon(8) -u.

Existing installations keep their data directory owned by root.  In that
state the service still starts and answers /api/ping, but every write ends
in "panic: attempt to write a readonly database", so the pkg-message asks
for a one-time chown.  That message is limited to upgrades from before
2.19.7_3.

Tested on 15.1/amd64: poudriere build and check-plist pass, a fresh install
creates /var/db/semaphore owned by semaphore, the service runs as that user
and creates its database, the web UI answers, and stop is clean.  The
upgrade path was tested by running 2.19.7_2 as root first, upgrading, and
verifying that the documented chown restores write access.

Two notes for whoever reviews this:

The user cannot be made configurable through a semaphore_user variable.
rc.subr reserves ${name}_user and would then run daemon(8) itself via su(1),
which makes writing the pidfile in /var/run fail.  The user is therefore
hardcoded in the rc script.

This conflicts textually with bug 298453, which adds output logging to the
same command_args line.  Whichever goes in first, the other needs a trivial
rebase.  Note that the two cannot simply be combined: daemon(8) opens the
output file after dropping privileges, so writing to /var/log fails once the
service no longer runs as root.  Logging plus a dedicated user would need
its own /var/log/semaphore directory in the plist, like www/gitea does.

The original patch came from Niclas Wagner; I fixed the staging violation in
post-install, which broke the package build, and added the migration note.

egypcio, my offer from bug 297378 still stands: I am happy to take over
maintainership of this port if you would rather pass it on.

Reported by:    Niclas Wagner (via private mail)

-- 
You are receiving this mail because:
You are the assignee for the bug.