Compare commits

...

5 Commits

Author SHA1 Message Date
Luca Boccassi
9abe624265
Install and use sysusers.d/tmpfiles.d config files
sysusers.d/tmpfiles.d config files allow a package to use
declarative configuration instead of manually written maintainer
scripts. This also allows image-based systems to be created
with /usr/ only, and also allows for factory resetting a system
and recreating /etc/ on boot.

https://www.freedesktop.org/software/systemd/man/latest/sysusers.d.html
https://www.freedesktop.org/software/systemd/man/latest/tmpfiles.d.html

Tests:

- /var/lib/plinth and /var/lib/plinth/sessions/ are created on package install.
  Ownership is plinth:plinth. 0755 is permissions.

- /var/lib/plinth/firstboot-wizard-secret file is created on package install.
  Ownership is plinth:plinth. 0400 is permissions. During first wizard,
  providing the secret works.

- /var/lib/plinth/backups-data is owned by root:root.

- When upgrading from old package to new the permissions don't change.

- When reinstalling the new package, the permissions do not change.

- User is created same as before.
  plinth987:987:FreedomBox service:/var/lib/plinth:/usr/sbin/nologin
- Group is created same as before.
  plinth987:
- id plinth
  uid=987(plinth) gid=987(plinth) groups=987(plinth)

- Upgrading from old package to new does not change user and group records.

- Reinstalling new version does not change user and group records.

[sunil: Don't recursively change ownership for /var/lib/plinth/]
[sunil: Change ownership specifically for /var/lib/plinth/firstboot-wizard-secret]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
Tested-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:45 -07:00
Luca Boccassi
a4b3d53141
Stop deleting system user on remove/purge
This is widely considered bad practice, as the kernel recycles
UIDs/GIDs. So any potential leftover file/directory can then
become owned by the next user/group that gets added, with
unpredictable consequences.
2026-05-13 15:37:41 -07:00
Sunil Mohan Adapa
529bbf77df
bepasty: Don't remove old system user and group
As removing a system user and group is considered a bad practice.  Old unused
system accounts are mostly harmless.

Tests:

- Bepasty functional tests pass.

- Installing bepasty and uploading a file works.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:38 -07:00
Sunil Mohan Adapa
e48ff1afbc
infinoted: Use systemd-sysusers for creating a system user account
- Drop dependency on 'adduser' package.

Tests:

- Functional tests for infinoted work.

- Installing infinoted app works. The system user and group are created with
proper UID/GID, shell, gecos, and home directory.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:35 -07:00
Sunil Mohan Adapa
f4be9039d2
syncthing: Use systemd-sysusers for creating a system user account
- Drop dependency on 'adduser' package.

Tests:

- Functional tests for syncthing work.

- Installing syncthing app works. The system user and group are created with
proper UID/GID, shell, gecos, and home directory.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
2026-05-13 15:37:32 -07:00
10 changed files with 22 additions and 51 deletions

2
debian/control vendored
View File

@ -11,6 +11,7 @@ Uploaders:
James Valleroy <jvalleroy@mailbox.org>,
Build-Depends:
debhelper-compat (= 13),
dh-sequence-installsysusers,
dblatex,
dh-python,
docbook-xsl,
@ -74,7 +75,6 @@ Depends:
${python3:Depends},
${misc:Depends},
${freedombox:Depends},
adduser,
augeas-tools,
bind9-dnsutils,
curl,

View File

@ -13,21 +13,9 @@ sed -i 's+-:ALL EXCEPT root fbx (admin) (sudo):ALL+-:ALL EXCEPT root fbx plinth
case "$1" in
configure)
if ! getent group plinth >/dev/null; then
addgroup --system --quiet plinth
fi
if ! getent passwd plinth >/dev/null; then
adduser --system --quiet --ingroup plinth --no-create-home --home /var/lib/plinth plinth
fi
chown plinth: /var/lib/plinth
chown plinth: /var/lib/plinth/sessions
if [ ! -e '/var/lib/freedombox/is-freedombox-disk-image' ]; then
umask 377
base64 < /dev/urandom | head -c 16 | sed -e 's+$+\n+' > /var/lib/plinth/firstboot-wizard-secret
chown plinth:plinth /var/lib/plinth/firstboot-wizard-secret
db_subst plinth/firstboot_wizard_secret secret $(cat /var/lib/plinth/firstboot-wizard-secret)
db_input high plinth/firstboot_wizard_secret || true
db_go

View File

@ -4,7 +4,6 @@ set -e
case "$1" in
purge)
deluser --system --quiet plinth || true
rm -rf /var/lib/plinth
# Remove legacy directory too

1
debian/freedombox.sysusers vendored Normal file
View File

@ -0,0 +1 @@
u! plinth - "FreedomBox service" /var/lib/plinth

3
debian/freedombox.tmpfiles vendored Normal file
View File

@ -0,0 +1,3 @@
d /var/lib/plinth 0755 plinth plinth
d /var/lib/plinth/sessions 0755 plinth plinth
Z /var/lib/plinth/firstboot-wizard-secret 0400 plinth plinth

View File

@ -91,8 +91,6 @@ def setup(domain_name: str):
# Migrate from old bepasty:bepasty ownership to root:root
shutil.chown(CONF_FILE, user='root', group='root')
action_utils.run(['deluser', 'bepasty'], check=False)
action_utils.run(['delgroup', 'bepasty'], check=False)
@privileged
@ -151,6 +149,6 @@ def _generate_password():
@privileged
def uninstall():
"""Remove bepasty user, group and data."""
"""Remove data and configuration file."""
shutil.rmtree(DATA_DIR, ignore_errors=True)
CONF_FILE.unlink(missing_ok=True)

View File

@ -0,0 +1,6 @@
# Create system user and group to run infinoted as system daemon (as opposed to
# running in particular user's account). The user is created at boot or when
# 'systemd-sysusers freedombox-infinoted.conf' is run. To override this file as
# system administrator, create a file /etc/sysusers.d/freedombox-infinoted.conf
# or link it to /dev/null.
u! infinoted - "Infinoted collaborative editing server" /var/lib/infinoted

View File

@ -1,10 +1,8 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Configure infinoted."""
import grp
import os
import pathlib
import pwd
import shutil
import subprocess
import time
@ -126,21 +124,8 @@ def setup():
action_utils.service_daemon_reload()
# Create infinoted group if needed.
try:
grp.getgrnam('infinoted')
except KeyError:
action_utils.run(['addgroup', '--system', 'infinoted'], check=True)
# Create infinoted user if needed.
try:
pwd.getpwnam('infinoted')
except KeyError:
action_utils.run([
'adduser', '--system', '--ingroup', 'infinoted', '--home',
DATA_DIR, '--gecos', 'Infinoted collaborative editing server',
'infinoted'
], check=True)
# Create an 'infinoted' system user and group, if needed.
action_utils.run(['systemd-sysusers', 'freedombox-infinoted.conf'])
for directory in (DATA_DIR, KEY_DIR, SYNC_DIR):
if not os.path.exists(directory):

View File

@ -0,0 +1,6 @@
# Create system user and group to run syncthing as system daemon (as opposed to
# running in particular user's account). The user is created at boot or when
# 'systemd-sysusers freedombox-syncthing.conf' is run. To override this file as
# system administrator, create a file /etc/sysusers.d/freedombox-syncthing.conf
# or link it to /dev/null.
u! syncthing - "Syncthing file synchronization server" /var/lib/syncthing

View File

@ -1,9 +1,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Configure Syncthing."""
import grp
import os
import pwd
import shutil
import time
@ -32,21 +30,8 @@ def augeas_load(conf_file):
@privileged
def setup():
"""Perform post-install actions for Syncthing."""
# Create syncthing group if needed.
try:
grp.getgrnam('syncthing')
except KeyError:
action_utils.run(['addgroup', '--system', 'syncthing'], check=True)
# Create syncthing user if needed.
try:
pwd.getpwnam('syncthing')
except KeyError:
action_utils.run([
'adduser', '--system', '--ingroup', 'syncthing', '--home',
DATA_DIR, '--gecos', 'Syncthing file synchronization server',
'syncthing'
], check=True)
# Create a 'syncthing' system user and group, if needed.
action_utils.run(['systemd-sysusers', 'freedombox-syncthing.conf'])
if not os.path.exists(DATA_DIR):
os.makedirs(DATA_DIR, mode=0o750)