# chj.users – správa účtů, sudo a SSH

Plugin spravuje linuxové účty přes existující SSH relaci Core. Neexistuje obecné API pro root příkazy:
Core spouští pouze pevný skript `src/main/users/remoteUsers.sh` s validovanými argumenty.

## Oprávnění a sudo
- `PrivilegedExecutor` (`src/main/sessions/privilegedExec.js`) je sdílená služba Core: rozliší root, sudo bez hesla,
  sudo s heslem a účet bez sudo. Neprivilegované čtení běží bez sudo.
- Heslo pro sudo se zapíše do stdin až po výzvě sudo (`-p` marker), nikdy do argumentů, logů ani úložiště.
  Data a tajné údaje (heslo účtu, obsah authorized_keys) se posílají jako stdin rámce až po markeru READY.
- Chybové kódy: `SUDO_PASSWORD_REQUIRED`, `SUDO_PASSWORD_INCORRECT`, `SUDO_NOT_PERMITTED`, `SUDO_TTY_REQUIRED`,
  `SUDO_UNAVAILABLE`. Ověřený stav „bez sudo" se v relaci pamatuje a heslo se znovu nevyžaduje.
- `requiretty` CH-J neobchází (PTY režim není implementován).

## SSH politika
- Jediný spravovaný soubor `/etc/ssh/sshd_config.d/01-chj-users.conf`; podporováno jen tam, kde `sshd_config`
  načítá `sshd_config.d` před prvním `Match`. Hlavní konfigurace se nemění. Ručně upravený soubor CH-J nepřepíše.
- Direktivy: `DenyUsers user`, `user@0.0.0.0/0`, `user@::/0`, `Match User` s `PasswordAuthentication`,
  `KbdInteractiveAuthentication`, `PubkeyAuthentication`.
- Postup: záloha (`/var/lib/chj-server-manager/users`), zápis, `sshd -t`, `sshd -T -C` pro cílový účet (IPv4/IPv6)
  a účet relace, ověření účinku, reload (ne restart), u vlastního účtu testovací nové přihlášení, potvrzení.
  EOF/odpojení nebo nepotvrzení do 120 s vrátí předchozí stav (watchdog na serveru).

## Účet root
- Root zůstává chráněný: nelze ho smazat ani měnit UID/GID, skupiny, shell či domovský adresář.
- SSH klíče roota (`/root/.ssh/authorized_keys`) a SSH politiku lze spravovat z root relace nebo přes sudo.
- `PermitRootLogin` se zapisuje do `Match User root` ve spravovaném souboru: `inherit` (výchozí, nic nezapisuje),
  `no`, `prohibit-password` (doporučeno), `forced-commands-only`, `yes`. Ověření přes `sshd -T` akceptuje alias
  `without-password`. U ostatních účtů se volba odmítne.
- Povolení přihlášení roota heslem vyžaduje v UI zvláštní potvrzení (opsání jména) a v API `confirmRootPassword: true`,
  jinak `USERS_ROOT_PASSWORD_CONFIRMATION_REQUIRED`.

## Alpine a další systémy bez util-linux
- `run_as` použije `runuser`, util-linux `setpriv` (jen s `--reuid`), jinak `su` s jedním ocitovaným příkazem
  (BusyBox `su` předává argumenty jinak). Stav hesel čte z `/etc/shadow`, když `getent` nemá databázi shadow.
- OpenRC se rozpozná před pidfile; po reloadu se čeká až 10 s na živý proces z pidfile (OpenSSH může po HUP běžet pod
  novým PID).
- Zamčený root (`!` v shadow) se na systémech bez PAM nepřihlásí ani klíčem – to je nastavení systému, ne CH-J.
- Proxmox VE: `/root/.ssh/authorized_keys` je symlink do `/etc/pve`; CH-J ho z bezpečnostních důvodů nemění.

## Testy
- `npm test` – jednotkové testy (`test/usersPlugin.test.js`).
- `CHJ_USERS_INTEGRATION=1 CHJ_USERS_IMAGE=chj-users-it-debian node --test test/usersIntegration.test.js` – destruktivní
  testy v jednorázovém kontejneru (image z `test/fixtures/usersIntegration`, Debian i Rocky). Nikdy proti reálnému serveru.
- `npx electron scripts/smokeUsersUi.js [adresář-snímků]` – UI smoke proti stejnému kontejneru
  (ve VS Code spouštět bez proměnné `ELECTRON_RUN_AS_NODE`).

## Windows (Windows 11, Windows Server)
- Platforma se určuje ze systémových údajů: `uname -s`, jinak Windows registr / `Win32_OperatingSystem` přes
  PowerShell (`src/main/sessions/platformDetect.js`). Výzva shellu ani název hostitele se nepoužívají.
- Funguje s výchozím SSH shellem `cmd.exe`, Windows PowerShell 5.1 i PowerShell 7: Core posílá jen krátký
  `powershell.exe -EncodedCommand` bootstrap, skript `src/main/users/windows/remoteUsers.ps1` a argumenty (JSON)
  jdou přes stdin. Hesla se nikdy neobjeví v příkazové řádce.
- Účty se spravují modulem `Microsoft.PowerShell.LocalAccounts` a identifikují podle SID; skupina Administrators
  podle `S-1-5-32-544` (lokalizované názvy se nepoužívají). Windows nepoužívá sudo: administrativní operace vyžadují
  SSH relaci se zvýšeným tokenem, CH-J neobchází UAC. Standardní účet dostane režim čtení.
- Chráněné: vestavěné účty (RID < 1000), účet aktivní relace, poslední povolený člen Administrators.
  Doménové a cloudové identity jsou jen pro čtení.
- SSH: Windows nemá `sshd_config.d`; CH-J vkládá do `%ProgramData%\ssh\sshd_config` dvě označené sekce
  (globální `DenyUsers` před první existující `Match`, vlastní `Match User` na konec). IPv4/IPv6 se omezuje vzory
  `user@*.*.*.*` a `user@*:*`, protože Windows OpenSSH převádí `/` v `DenyUsers` na `\` (CIDR nelze použít).
  `KbdInteractiveAuthentication` se nezapisuje.
- `sshd -T -C` pro cizí účet funguje jen pod SYSTEM (jinak se zasekne), proto vyhodnocení běží v jednorázové
  naplánované úloze SYSTEM z adresáře `%ProgramData%\CH-J\chj-users` (ACL jen SYSTEM a Administrators).
- Aplikace změny: kandidát → `sshd -t -f` + `sshd -T -f -C` → naplánovaná úloha SYSTEM zazálohuje soubor i ACL,
  zapíše změnu, restartuje `sshd` a čeká 120 s na potvrzení z **nového** SSH přihlášení; jinak sama obnoví zálohu
  a restartuje `sshd` (funguje i po pádu CH-J). Bez údajů pro testovací přihlášení se změna neprovede.
- Klíče: běžný účet `profil\.ssh\authorized_keys`, administrátoři sdílený `administrators_authorized_keys`
  (upozornění, že klíč platí pro všechny správce). Úprava zachovává ostatní řádky i ACL (`ReplaceFile`).
- Testy: `test/usersWindows.test.js` (jednotkové), `test/usersWindowsIntegration.test.js` (jen izolovaný testovací
  stroj, proměnné `CHJ_USERS_WINDOWS_*`, `CHJ_USERS_WINDOWS_SLOW=1` pro rollback scénáře) a
  `scripts/smokeUsersUiWindows.js` (UI).
