Just lost a few hours playing with daemon(8) and trying to set a path in an rc.d script
Date: Sat, 14 Sep 2024 08:23:51 UTC
Hey there all,
I’m answering my own question here, writing this in the hopes that someone finds it in the future, in the archives. (xkcd.com/979 <http://xkcd.com/979> is relevant)
Dyjob have a service (etherpad lite) that we start from rc.d, using daemon, but it runs as an unprivileged user and needs a special PATH (because npm wants to install and update its own modules. I hate this, but this is the reality).
Setting export NODE_PATH=$HOME/.node/lib/node_modules:$NODE_PATH as part of the rc.d script was no problem. It stuck, but for some reason, the PATH was not being set.
I tried setting PATH n the user’s home directories and login files, no dice.
I tried setting PATH as part of etherpadlite_env in the rc script, no dice.
I even tried explicitly setting the path as part of the etherpadlite_start() subroutine in the rc script. A printenv showed it existing, but when the actual daemon command ran, it was erased.
===
I almost missed this bit in daemon.c, thinking it’s just an error check. No, this is where daemon does it.
if (setusercontext(NULL, pw, pw->pw_uid, LOGIN_SETALL) != 0) {
errx(1, "failed to set user environment");
}
Turns out, it’s our old and almost never used friend, the login capabilities database well at work. I had to define a custom .login_conf for this user and modify the path there, thusly:
me:\
:path=~/.node/bin /sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin:
===
The manpage for daemon(8) is silent on this, saying only:
-u, --user user
Login name of the user to execute the program under. Environment
variables HOME, USER, and SHELL are set accordingly. Requires
adequate superuser privileges.
Adding a single line that *mentions* login.conf would have saved me a ton of time here, but because it mentions only HOME, USER, and SHELL, the assumption was that everything else would be preserved.
-Dan