LAB Portal — pakiet na LABPORTAL (IIS + SQL Express, HTTP :80)

PO PODMIANIE site\ ZNOWU PYTA O HASŁO:
  Nie kopiuj recznie calego folderu site\ — to nadpisuje web.config i recykluje NTLM.
  Na LABPORTAL jako Admin:  napraw-logowanie.ps1
  Na PC/hoscie: Edge tacka → Exit, potem TYLKO  http://labportal
  (FQDN labportal.apnlab.pl bez strefy Intranet = petla hasla.)
  Kolejna podmiana kodu:  kopiu-site.ps1  (nie rusza web.config).

STAN DZIAŁAJĄCY 2026-09-18:
  Site: Anonymous OFF, Windows ON, Basic OFF, providers = NTLM.
  useKernelMode=true (Enable Kernel-Mode authentication) — to jest SSO.
  web.config i skrypty (wdroz / ntlm-iis / napraw-logowanie) MUSZĄ zostawiać kernelMode ON.
  Stare paczki ustawialy useKernelMode=false i po recyklu IIS odhaczaly checkbox.
  useAppPoolCredentials=false, Extended Protection = None.
  ANCM (aspNetCore + handlers) TYLKO w korzeniu system.webServer — NIE w
  location path="." inheritInChildApplications="false" (to kradło /api → StaticFile 404).
  Anonymous TYLKO: /api, /host, /healthz. Nie wkładaj <handlers> do location path="api".
  Aplikacja: IISDefaults, AutomaticAuthentication=true. BEZ FallbackPolicy i BEZ Challenge
  (app 401 wyciera NTLM Type 2 → pętla hasła). Brak cookie /login.
  Z hosta HV: dodaj-intranet.ps1, Exit Edge, wejdź na http://labportal (krótka nazwa).
  FQDN labportal.apnlab.pl bez strefy Intranet = pętla 401. Nie cofać tego przy wdrożeniu.

Na LABPORTAL jako Admin, z NOWEGO folderu labportal-IIS:
  1) wdroz.ps1              (musi wypisac: wdroz FINAL 2026-09-18 kernel)
Jak nie ma tej linii — odpaliles STARY skrypt z Downloads.

0) BŁĄD 500.19 / 0x8007000d
   IIS nie zna tagu <aspNetCore> w web.config.
   To NIE jest zły plik — brakuje ASP.NET Core 8 Hosting Bundle
   (albo zainstalowano go PRZED rolą IIS).

   Na serwerze, jako Administrator:
   - Pobierz: https://aka.ms/dotnetcore-8-0-windowshosting
     (plik: dotnet-hosting-8.0.x-win.exe)
   - Zainstaluj. Jeśli IIS był już wcześniej: odpal instalator jeszcze raz → Repair.
   - Potem OBOWIĄZKOWO:
       net stop was /y
       net start w3svc
   - Sprawdzenie:
       %windir%\system32\inetsrv\appcmd list module
     ma być linia: AspNetCoreModuleV2

2) IIS — Windows Auth + grupy AD (http://labportal.apnlab.pl)
   Physical path = C:\inetpub\wwwroot\labportal   (strona IIS o nazwie labportal)
   Wdrozenie: wdroz.ps1 — nie wrzucaj plikow do C:\LabPortal\site, bo IIS tego nie serwuje.
   Binding: http :80  host header labportal.apnlab.pl
   App Pool: No Managed Code, ApplicationPoolIdentity (konto maszyny w APNLAB)

   Odpal jako Admin TYLKO: wdroz.ps1
   Musi wypisac: wdroz FINAL 2026-09-18 kernel  oraz  Anonymous=OFF  oraz ping 200
   oraz GET /api/host/jobs/next i POST /api/host/inventory bez 404.
   oraz GET / bez poświadczeń = 401 z WWW-Authenticate NTLM.
     (wyłącza Rapid-Fail + idle timeout; logi stdout NIE mogą leżeć w folderze site —
      to recykluje aplikację aż pula padnie. Diagnostyka: C:\ProgramData\LabPortal\lifetime.txt)

   Przy podmianie plików site\: najpierw Stop puli, kopia, Start (albo uruchom-iis.ps1).
   Nie odpalaj wlacz-windows-auth.ps1 przy każdej kopii — CommitChanges recykluje IIS.
     Anonymous Authentication = Disabled  (cała witryna)
     Windows Authentication   = Enabled, providers NTLM, kernelMode ON (SSO)
     Basic Authentication     = Disabled
     Wyjątki Anonymous: tylko /api, /api/host, /healthz
     Nie ma formularza /login — tożsamość to HttpContext.User (np. APNLAB\marnad).

   SPN (konto maszyny, gdy pula = ApplicationPoolIdentity):
     setspn -Q HTTP/labportal
     setspn -Q HTTP/labportal.apnlab.pl
     setspn -S HTTP/labportal APNLAB\LABPORTAL$
     setspn -S HTTP/labportal.apnlab.pl APNLAB\LABPORTAL$
     setspn -L APNLAB\LABPORTAL$
   To robi też wlacz-windows-auth.ps1 (wymaga Domain Admin). Każdy SPN tylko na jednym obiekcie AD.

   Z innego hosta: NA TYM komputerze (SBOX), nie na LABPORTAL, odpal dodaj-intranet.ps1,
   zamknij WSZYSTKIE procesy Edge (tacka → Exit), wejdź na http://labportal
   (krótka nazwa). W oknie hasła: APNLAB\marnad i hasło domenowe.
   http://labportal.apnlab.pl bez strefy Intranet = pętla 401 (Internet zone).
   - Konto domenowe w LAB-Portal-Admins → admin; w LAB-Portal-Users → user
   - Inne konto domenowe → 403 /Denied (nie pętla /login)

   wylacz-logowanie.ps1 NIE odpalać przy zwykłym wdrożeniu ani restarcie IIS.

3) SQL
   Nowa baza: schema.sql. Baza już jest: schema-portal-users.sql
   Login Windows App Poola = db_owner na LabPortal.

To NIE jest pakiet na hosty Hyper-V. Agent HV: folder host\
  Skopiuj host\ na SRV-HV-SBOX* i odpal Register-HostAgent.ps1 (Windows Service LabPortalHostAgent).
  HostAgent.ps1 → http://labportal.apnlab.pl/api/host (Anonymous, nagłówek X-Lab-Host).
  Test na LABPORTAL: curl.exe -s -H "X-Lab-Host: SRV-HV-SBOX1" http://labportal.apnlab.pl/api/host/ping
  Na HV: skopiuj HostAgent.ps1 do C:\LabPortal i Restart-Service LabPortalHostAgent.
