This PR adds an `api_only` global permission that restricts a Webmin account to one supported API endpoint, such as virtual-server/remote.cgi.
External integrations need credentials that can call an API without also granting access to the Webmin interface or generic RPC. Existing module permissions do not provide this endpoint-level restriction. The new setting allows administrators to create dedicated integration accounts while Webmin continues performing authorized operations through its privileged backend.
The restriction is enforced in two places:
- MiniServ checks the authenticated account's policy before dispatching CGI, static-file, DAV, or WebSocket requests. Requests outside the configured endpoint receive HTTP 403.
- `init_config` requires the permitted CGI to explicitly opt in before initialization. This also protects Webmin-initializing CGIs hosted by another web server.
Generic RPC is denied for API-only accounts, even when an existing RPC permission would otherwise allow it. The endpoint's own module and operation permissions still apply. Selecting an endpoint does not grant permission to execute every API command.
Webmin Users gains an API-only setting for users and groups. Existing restrictions survive ordinary edits, resets, copies, cloning, renaming, group propagation, and cluster synchronization. Clearing a restriction requires an explicit permission edit. Group updates preserve restrictions already assigned to individual members.
MiniServ reads the policy on each request from the account's existing storage backend: local files, MySQL, PostgreSQL, or LDAP. Policy-read errors deny access instead of treating the account as unrestricted.
Validation passed with the four separately submitted supporting fixes (#2897, #2898, #2899, #2900) ,applied: 169 focused tests, syntax checks, and live Debian tests using file-backed and PostgreSQL accounts. Live checks covered account creation, lifecycle operations, both CGI modes, sessions, RPC, static files, DAV, and WebSockets.
The supporting fixes remain separate PRs. This API-only branch currently has seven lifecycle test failures that depend on the file-cache and group ACL cleanup fixes landing.
This PR fixes package installation pages stopping after "Re-fetching available packages .." on RPM systems, before the System Status refresh, reboot check, and return link appeared.
The regression was introduced by https://github.com/webmin/webmin/commit/658f930, which wrapped RPM queries in `clean_environment` while the Package Updates installer had already cleaned the environment.
The inner clean overwrote the only saved environment, leaving `WEBMIN_CONFIG` unset and causing the System Status library to fail after the page headers had been sent.
Nested `clean_environment` calls now save separate snapshots, allowing each `reset_environment` call to restore the matching environment exactly while preserving Virtualmin's API script runner behavior.
This PR fixes SSL certificate verification for regular `/rpc.cgi` connections.
It reuses the existing certificate requirements already passed to Fast RPC, so both transports honor `checkssl`.
<!-- ANT-2026-1G97HEC6: Reported by Adam via email on October 11, 2026 at 12:08. -->
This PR fixes unauthenticated Fast RPC transfer sockets by requiring the transfer connection to present the active RPC session ID before file data moves.
Patched peers use authentication, while mixed-version transfers retain existing behavior for compatibility.
ANT-2026-1G97HEC6: Reported by Adam email on October 11 2026 at 12:08.
This PR fixes unsafe RPC deserialization by dropping `Data::Dumper` from fast RPC, rejecting `$VAR1` input, and keeping remote objects as plain data.
Original report by Adam emailed October 11, 2026 at 05:34.
This patch fixes valid symlink paths being mistaken for loops by [c51f0ed4](https://github.com/webmin/webmin/commit/c51f0ed4).
It simplifies only the checked path prefix, preserving the unresolved remainder.
Original loop cases still stop quickly, while long valid chains remain supported.
I reproduced incorrect PHP selection in Virtualmin and WP Workbench, and GoAccess choosing its root log-creation branch instead of the domain-user helper.
This patch fixes `get_module_info()` accepting module names with a trailing newline after the regex anchors were changed.
It preserves the strict validation introduced in my `2f4f017ac` to prevent loading files outside installed modules.
The check directly rejects undefined or empty names and any character outside ASCII letters, digits, underscores, and hyphens, including newlines anywhere in the name.
Regression tests pass and verify that invalid names are rejected before module lookup while valid names remain accepted.
This PR fixes WebSocket routes being lost when miniserv configuration changes multiple times within one second.
Read `miniserv.conf` directly so locked updates use the current configuration.
The previous cache could reuse stale data because it compared modification times in whole seconds.
Add a regression test covering route additions and removals with an unchanged modification time.
This PR fixes delays when IPv6 DNS lookups stall otherwise working IPv4 connections.
The earlier changes ([04c74877](04c74877c3) and [8a6f7784](8a6f778410)) added fallback across available IPv4 and IPv6 addresses, which this PR preserves.
Resolving both families upfront appears to have been an implementation choice, yet now IPv6 is resolved only when no IPv4 connection succeeds.
Unit tests and real socket compatibility tests passed on Alma 10 and Debian 13.
This PR stops treating `rpc=0` as a safe-user restriction, restoring File Manager ops and admin features for fully privileged accounts created with RPC disabled.
Preserve explicit `_safe` restrictions and product roles.
Regression tests and Perl syntax checks pass.
Fixes https://github.com/webmin/webmin/issues/2837
This PR adds the ability for the logging pages to hand the Miniserv access and error logs, and the Webmin actions log, to logrotate instead of having Miniserv periodically delete them. The generated section uses copy-truncate rotation, since Miniserv only reopens its error log when the file disappears.
The option only appears when the Log File Rotation module is available and configured correctly.
ⓘ Do not return a short name from /etc/hostname when the full name is requested; resolve it with hostname -f first, honoring the no_hostname_f option, and otherwise fall back to the existing file-based logic.
Also check for /run/systemd/system instead of reading /proc/1/comm as it's much cheaper.
Fixes#2054
ⓘ Follow up on #2794 by making `redirect_port` work even when `redirect_host` is not set. Keep existing host precedence and correctly handle proxy headers, IPv6 addresses, default ports, and invalid port values.
ⓘ Fix linked-server by keeping the child URL recognizable to the parent, then generating the final WebSocket URL on the same host and port the browser is using. This keeps the connection working with the current Webmin session.
ⓘ Extend HTTP and FTP download callbacks with destination validation while preserving legacy tracking callbacks and enforcing SSRF policy across redirects, proxies, caches, and direct/passive sockets.
https://github.com/webmin/webmin/pull/2789#discussion_r3567985773
Block non-public HTTP, HTTPS and FTP destinations by default in File Manager, Mailboxes and Upload and Download, with per-user IP/CIDR exceptions, redirect and proxy protection, cache isolation, and current-ACL enforcement for scheduled jobs.
ⓘ Centralize global file ACL checks for server-local reads and applies them to batch, LDAP batch, MySQL, and PostgreSQL local import and restore flows. Files are read under the configured `fileunix` identity and staged with the correct command-user ownership, preventing constrained Webmin users from bypassing `root`, `otherdirs`, or `fileunix`.
9ceffce70f (r191495975)
ⓘ Use the existing scheduled websocket cleanup path for linked-server ws-link routes and expire unopened temporary routes after five minutes.
This limits how long credential-bearing proxy routes can remain in `miniserv.conf` while leaving active and normal websocket cleanup behavior unchanged.