Users and permissions: accounts, login, enforced file permissions, setuid, su, passwd, doas

The kernel now checks owner/group/other on open, create, unlink, rename, exec
and path search; honours set-user-id and set-group-id; restricts kill, mount,
reboot and mknod; keeps supplementary groups; and implements chown. devtmpfs
nodes carry owners and modes that chmod/chown keep. Terminals run login, the
image has root and schos, X starts as the ordinary user.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EVRhxi9zpdW2uDUN4FVcao
This commit is contained in:
Nexoniarz 2026-10-26 13:16:07 +01:00
commit 020aa6113c
34 changed files with 1342 additions and 120 deletions

View file

@ -1,11 +1,11 @@
# The interactive shell on /dev/tty1, the first virtual terminal.
Label = os.schos.console-shell
# zsh, not /bin/sh. mksh stays as /bin/sh and is what schinit falls back to
# when no manifest loads -- so if zsh ever fails to start, the recovery shell
# is a different program rather than the same broken one. See ports/zsh.
Program = /bin/zsh
Args = -zsh
# A login prompt, not a shell: /etc/schos-getty hands the terminal to login,
# which asks who is there and starts their shell. tty6 keeps a root shell
# with no login, for when this part of the system is what is broken.
Program = /bin/sh
Args = sh /etc/schos-getty
RunAtLoad = yes
KeepAlive = yes
@ -15,8 +15,6 @@ KeepAlive = yes
# most: a line editor with no TERM cannot ask terminfo how to move a cursor.
Environment = TERM=linux
Environment = PATH=/bin:/usr/bin
Environment = HOME=/root
Environment = SHELL=/bin/zsh
# This job reads the console, so it has to own it: schinit puts every job in
# its own session, and a session with no controlling terminal is not delivered

View file

@ -6,15 +6,13 @@
# what /dev/tty1 and /dev/tty2 being different terminals means.
Label = os.schos.tty2-shell
Program = /bin/zsh
Args = -zsh
Program = /bin/sh
Args = sh /etc/schos-getty
RunAtLoad = yes
KeepAlive = yes
Environment = TERM=linux
Environment = PATH=/bin:/usr/bin
Environment = HOME=/root
Environment = SHELL=/bin/zsh
ControllingTerminal = yes

View file

@ -10,15 +10,13 @@
# for six lines each is the wrong trade.
Label = os.schos.tty3-shell
Program = /bin/zsh
Args = -zsh
Program = /bin/sh
Args = sh /etc/schos-getty
RunAtLoad = yes
KeepAlive = yes
Environment = TERM=linux
Environment = PATH=/bin:/usr/bin
Environment = HOME=/root
Environment = SHELL=/bin/zsh
ControllingTerminal = yes

View file

@ -10,15 +10,13 @@
# for six lines each is the wrong trade.
Label = os.schos.tty4-shell
Program = /bin/zsh
Args = -zsh
Program = /bin/sh
Args = sh /etc/schos-getty
RunAtLoad = yes
KeepAlive = yes
Environment = TERM=linux
Environment = PATH=/bin:/usr/bin
Environment = HOME=/root
Environment = SHELL=/bin/zsh
ControllingTerminal = yes

View file

@ -10,15 +10,13 @@
# for six lines each is the wrong trade.
Label = os.schos.tty5-shell
Program = /bin/zsh
Args = -zsh
Program = /bin/sh
Args = sh /etc/schos-getty
RunAtLoad = yes
KeepAlive = yes
Environment = TERM=linux
Environment = PATH=/bin:/usr/bin
Environment = HOME=/root
Environment = SHELL=/bin/zsh
ControllingTerminal = yes

View file

@ -1,3 +1,6 @@
# A root shell on /dev/tty6, with no login: the way in when login itself is
# what has broken. Every other terminal asks who is there.
#
# An interactive shell on /dev/tty6.
#
# NVT is 6 (include/dev/vt.h) and the kernel creates all six terminals, but only

10
etc/schos-getty Normal file
View file

@ -0,0 +1,10 @@
#!/bin/sh
# What a virtual terminal runs: take the terminal back from whoever had it, and
# ask for a login. login hands the terminal to the user it lets in, and this
# runs again when their shell exits.
t=$(tty 2>/dev/null)
if [ -n "$t" ]; then
chown root:tty "$t" 2>/dev/null
chmod 0660 "$t" 2>/dev/null
fi
exec /bin/login

14
etc/udev-schos.rules Normal file
View file

@ -0,0 +1,14 @@
# SchOS's own device permissions, applied after Alpine's (the name sorts last
# once installed as 90-schos.rules).
#
# The kernel makes these nodes with the permissions it means them to have
# (kernel/fs/devfs.c). udev, with no rule that names a node, would chmod it to
# 0600 -- which made /dev/null unusable to everyone but root -- so every kernel
# device is named here with the same answer the kernel gave.
SUBSYSTEM=="mem", MODE="0666"
SUBSYSTEM=="tty", KERNEL=="console", GROUP="root", MODE="0600"
SUBSYSTEM=="tty", KERNEL=="tty0|tty[0-9]|tty1[0-2]", GROUP="tty", MODE="0660"
SUBSYSTEM=="input", GROUP="input", MODE="0660"
SUBSYSTEM=="graphics", GROUP="video", MODE="0660"
SUBSYSTEM=="block", GROUP="disk", MODE="0660"