mrrl-logincaps

MRRL version of logincaps
git clone https://ccx.te2000.cz/git/mrrl-logincaps
Log | Files | Refs

logincaps (3012B)


      1 #!/bin/zsh
      2 setopt no_unset warn_create_global
      3 PS4="cap $PS4"
      4 
      5 trap 'printf >&2 "\nlogincaps: ALRM!\n"' ALRM
      6 trap 'printf >&2 "\nlogincaps: HUP!\n"' HUP
      7 
      8 pretendrun() { : "$@" }
      9 typeset -f -t pretendrun
     10 
     11 
     12 stop_x() {
     13 	(($+X)) || return 1
     14 	[[ $X == $1 ]] || return 2
     15 	shift
     16 	s6-svc -wD -T 8000 -t /run/service/container.X$X &&
     17 	chown root:root /run/Xauthority.$X
     18 }
     19 
     20 run_x() {
     21 	(($+X)) || return 1
     22 	[[ $X == $1 ]] || return 2
     23 	shift
     24 	truncate -s 0 /run/Xauthority.$X &&
     25 	# TODO: replace the 2 lines below with s6-svperm after updating s6
     26 	chgrp -R -- $USER /run/service/container.X$X/{event,supervise} &&
     27 	chmod 750 /run/service/container.X$X/supervise &&
     28 	s6-svc -wU -T 8000 -o /run/service/container.X$X &&
     29 	chmod 640 /run/Xauthority.$X &&
     30 	chown xorg:$USER /run/Xauthority.$X &&
     31 	cat /run/containers/X$X.xorg/run/X/Xauthority > /run/Xauthority.$X &&
     32 	chmod o+x /run/containers/X$X.xorg/tmp /run/containers/X$X.xorg/tmp/.X11-unix &&
     33 	chown $USER:$USER /run/containers/X$X.xorg/tmp/.X11-unix/X$X
     34 	# with /proc/sys/fs/protected_hardlinks = 1 only owner can hardlink a socket
     35 }
     36 typeset -f -t run_x
     37 
     38 check_wheel() {
     39 	local wheel_gid
     40 	wheel_gid=${${(s.:.)"$(getent group wheel)"}[3]} || return $?
     41 	[[ $wheel_gid == [1-9]* ]] || return 1
     42 	WHEEL_GID=$wheel_gid s6-envuidgid ccx zsh -c '(( ${${(s/,/)GIDLIST}[(I)$WHEEL_GID]} ))'
     43 	return $?
     44 }
     45 typeset -f -t check_wheel
     46 
     47 cap_cmd() {
     48 	if "$@"; then
     49 		printf 'OK\n'
     50 	else
     51 		printf 'EX%d\n' $?
     52 	fi
     53 }
     54 typeset -f -t cap_cmd
     55 
     56 terminal_spawn_common() {
     57 	local term_cmd term_env
     58 	term_cmd="${3#* }"
     59 	term_env=${term_cmd%% *}
     60 	if ! [[ $term_env =~ ^[-.0-9a-zA-Z]*$ ]]; then
     61 		printf 'ERR: invalid TERM'
     62 		return 1
     63 	fi
     64 	term_cmd="${term_cmd#* }"
     65 	cap_cmd execlineb -c "$1 ${(qqq)term_env} $2 cd / s6-setuidgid ${(qqq)USER} $term_cmd"
     66 }
     67 
     68 terminal_spawn_password() {
     69 	if check_wheel; then
     70 		terminal_spawn_common "check-root-password.py spawn-pty.py" '{ login -f root }' "$1"
     71 	else
     72 		printf 'ERR: Not in the group "wheel" (ex:%d)\n' $?
     73 	fi
     74 }
     75 
     76 terminal_spawn() {
     77 	terminal_spawn_common spawn-pty.py "{ $1 }" "$2"
     78 }
     79 
     80 main() {
     81 	local line term_cmd term_env REPLY
     82 	while read line; do
     83 		case $line in
     84 			((|no)xtrace)
     85 				setopt $line
     86 				printf 'OK\n'
     87 				;;
     88 
     89 			(o)
     90 				cap_cmd poweroff
     91 				;;
     92 
     93 			(b)
     94 				cap_cmd reboot
     95 				;;
     96 
     97 			(terminal *)
     98 				terminal_spawn_password "$line"
     99 				;;
    100 
    101 			(terminal-wpa_cli *)
    102 				terminal_spawn "wpa_cli" "$line"
    103 				;;
    104 
    105 			(chvt tty)
    106 				cap_cmd chvt ${LOGIN_TTY#/dev/tty}
    107 				;;
    108 
    109 			(chvt [Xx])
    110 				cap_cmd chvt $X
    111 				;;
    112 
    113 			(X [5678]*)
    114 				cap_cmd run_x "${(Q@)${(z)${line#X }}}"
    115 				;;
    116 
    117 			(stopX [5678]*)
    118 				cap_cmd stop_x "${(Q@)${(z)${line#stopX }}}"
    119 				;;
    120 
    121 			(login.capability.*)
    122 				local cap_exe=${${=line}[1]}
    123 				if (($+commands[$cap_exe])); then
    124 					cap_cmd execlineb -c "$line"
    125 				else
    126 					printf 'ECMD\n'
    127 				fi
    128 				;;
    129 			(*) printf 'ECMD\n';;
    130 		esac
    131 	done
    132 	stop_x >&2 </dev/null
    133 }
    134 
    135 if [[ $LOGIN_TTY == /dev/tty[1-4] ]]; then
    136 	typeset -g X
    137 	X=$[ ${LOGIN_TTY#/dev/tty} + 4 ]
    138 	export X
    139 fi
    140 
    141 main
    142 #  vim: ft=zsh noet ts=4 sts=4 sw=4