mirror of
https://github.com/webmin/webmin.git
synced 2026-06-05 12:50:23 +01:00
This PR expands the "Bootup and Shutdown" module’s systemd support with creation and management for services, timers, sockets, paths and targets. It also adds user-scoped systemd units, linger controls, status and log actions, tabbed unit listings by type, and contextual help for the new options. For user-scoped units, the implementation includes several safety guards because unit files live under user-controlled home directories: - User accounts are validated with system account data before any user-unit operation is attempted. - User unit names are restricted to known systemd unit suffixes and safe filename characters. - User unit files are limited to direct children of `~/.config/systemd/user`. - Symlinked `.config`, `.config/systemd`, and `.config/systemd/user` paths are rejected. - User unit reads, writes, directory creation, and deletes are performed after dropping privileges to the target Unix user. - File operations re-check paths close to the actual read/write/delete operation to reduce symlink race exposure. - User unit create failures roll back half-created files when daemon reload fails. - User-provided unit names, owners, paths, command output, and logs are HTML-escaped before display. - systemctl, journalctl, and loginctl command arguments are shell-quoted before execution. - User services omit `User=` and `Group=` directives because they already run under the selected user’s systemd manager. Together, all these changes will allow Webmin admin to manage both system and user systemd units while keeping user-controlled home-directory paths from becoming root-level file read/write/delete exploits. Implemented in response to these two issue requests https://github.com/webmin/webmin/issues/2733 and https://github.com/webmin/webmin/issues/2734
38 lines
1.2 KiB
Perl
Executable File
38 lines
1.2 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
# Toggle linger for a systemd user manager
|
|
|
|
require './init-lib.pl';
|
|
&error_setup($text{'systemd_linger_err'});
|
|
$access{'bootup'} || &error($text{'edit_ecannot'});
|
|
&ReadParse();
|
|
|
|
# Validate the requested user and linger state before calling loginctl.
|
|
my $user = &clean_systemd_unit_value($in{'user'});
|
|
my $enabled = $in{'enabled'};
|
|
&get_systemd_user_details($user) || &error($text{'systemd_euser'});
|
|
if (!defined($enabled) || $enabled !~ /^[01]$/) {
|
|
&error($text{'systemd_elinger'});
|
|
}
|
|
|
|
my ($ok, $out) = &set_systemd_user_linger($user, $enabled);
|
|
$ok || &error_systemd_linger_command($user, $out);
|
|
if ($enabled) {
|
|
($ok, $out) = &start_systemd_user_manager($user);
|
|
$ok || &error_systemd_linger_command($user, $out);
|
|
}
|
|
|
|
&webmin_log("linger", "systemd-user", $user,
|
|
{ 'user' => $user, 'enabled' => $enabled });
|
|
&redirect(&systemd_index_url(undef, 1, $user));
|
|
|
|
# error_systemd_linger_command(user, output)
|
|
# Shows escaped loginctl or systemctl output from a failed operation.
|
|
sub error_systemd_linger_command
|
|
{
|
|
my ($user, $out) = @_;
|
|
$out ||= $text{'systemd_euser'};
|
|
&error(&text('systemd_eusercmd',
|
|
&ui_tag('tt', &html_escape($user)),
|
|
&ui_tag('pre', &html_escape($out))));
|
|
}
|