Compare commits

...

14 Commits
2.600 ... 2.610

Author SHA1 Message Date
Jamie Cameron
70c7ddf3bb New version bump 2025-11-23 17:53:04 -08:00
Ilia Ross
17764483dc Fix changelog missing link to the theme
[no-build]
2025-11-23 19:34:28 +02:00
Ilia Ross
cdc1c82e83 Update changelog for 2.610 2025-11-23 19:32:23 +02:00
Ilia Ross
d29e5aea99 Fix terminal normal font size
[no-build]
2025-11-23 15:30:53 +02:00
Ilia Ross
c3a2396986 Fix to exclude .github from builds 2025-11-20 20:30:41 +02:00
Ilia Ross
da37f364dd Fix to allow some hidden modules to be searchable
Like Virtualmin Virtual Servers, which has a separate switch in the menu, so we don't want it to show up as a regular link in the menu as well
2025-11-19 12:04:33 +02:00
Jamie Cameron
0342f06fc8 Remove dependency on IO::Pty for calling sudo
https://github.com/webmin/webmin/issues/2587
2025-11-18 21:04:48 -08:00
Jamie Cameron
ef05252413 Merge pull request #2589 from webmin/dev/pure-perl-openpty
Add support for using pure-Perl Linux fallback to open PTY
2025-11-18 15:00:30 -08:00
Ilia Ross
74f879dc2b Fix to move sub to Linux lib
https://github.com/webmin/webmin/pull/2589#discussion_r2539675817
2025-11-18 23:16:10 +02:00
Ilia Ross
94cbabea9e Add support for using pure-Perl Linux fallback to open PTY 2025-11-18 20:15:26 +02:00
Ilia Ross
2634afb859 Fix to displays 2FA better 2025-11-14 15:37:00 +02:00
Ilia Ross
4bf296447e Fix to drop js.map file
https://github.com/webmin/webmin/issues/2582#issuecomment-3529211242
2025-11-13 20:50:31 +02:00
Ilia Ross
cf458db765 Fix to open correct palette on the remote 2025-11-12 23:07:21 +02:00
Ilia Ross
af7cb99298 Update screenshots 2025-11-12 23:04:51 +02:00
15 changed files with 154 additions and 57 deletions

View File

@@ -1,5 +1,19 @@
## Changelog
#### 2.610 (November 23, 2025)
* Fix to drop dependency on `IO::Pty` Perl module
* Fix `virtual-server` module server-side search to work correctly
* Update the Authentic theme to the latest version with various improvements and fixes:
- Add a range slider to adjust content page margins more precisely
- Add an option to enable rounded corners for content page
- Add more customization options for pie charts
- Fix to increase clickable area for checkboxes in File Manager
- Fix to correct rotation of pin and unpin button for right side slider
- Fix color of selected items in the multiselect dropdown
- Fix to improve the visibility of disabled checkboxes
- Fix to send saved params in the post body when saving theme configuration
[More details...](https://github.com/webmin/authentic-theme/releases/tag/26.20)
#### 2.600 (November 9, 2025)
* Add an options to enable the slow query log in the MySQL/MariaDB module [#2560](https://github.com/webmin/webmin/issues/2560)
* Add ability to install multiple PHP extensions at once in the PHP Configuration module

View File

@@ -19,11 +19,11 @@
**Webmin** is a web-based system administration tool for Unix-like servers, and services with about _1,000,000_ yearly installations worldwide. Using it, it is possible to configure operating system internals, such as users, disk quotas, services or configuration files, as well as modify, and control open-source apps, such as BIND DNS Server, Apache HTTP Server, PHP, MySQL, and many more.
<p align="center">
<a href="https://webmin.com/screenshots/#gh-light-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://user-images.githubusercontent.com/4426533/218264253-c08fb45a-8d75-44bf-93b3-37a2ecae3d20.png">
<a href="https://webmin.com/screenshots/?theme=light#gh-light-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://github.com/user-attachments/assets/a01d0a78-4130-4665-9284-814955ae1c97">
</a>
<a href="https://webmin.com/screenshots/#gh-dark-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://user-images.githubusercontent.com/4426533/218265232-31140aa6-ada1-4019-bd75-04240aeabc83.png">
<a href="https://webmin.com/screenshots/?theme=dark#gh-dark-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://github.com/user-attachments/assets/da4b90a0-c002-4e10-8b34-5acb251bbec9">
</a>
</p>

View File

@@ -291,7 +291,13 @@ return &ui_checkbox("d", $user->{'name'}, "", 0).
($ro ? "<b>" : "").
&ui_link("$cgi?$param=".&urlize($user->{'name'}),
$user->{'name'}).
($user->{'twofactor_id'} ? "*" : "").
($user->{'twofactor_id'}
? &ui_tag('sup', '⚷',
{ title => $text{'index_twofactor_enabled'},
class => 'twofactor-enabled-icon',
style => 'font-size: 11px; margin-left: 5px; cursor: default;'.
'display: inline-block; transform: rotate(90deg);' } )
: "").
($ro ? "</b>" : "").
($lck ? "</i>" : "");
}

View File

@@ -6,6 +6,7 @@ index_screate=Create a new safe user.
index_convert=Convert Unix To Webmin Users
index_cert=Request an SSL Certificate
index_twofactor=Two-Factor Authentication
index_twofactor_enabled=Two-factor authentication is enabled for this user
index_certmsg=Click this button to request an SSL certificate that will allow you to securely login to Webmin without having to enter a username and password.
index_return=user list
index_none=None

View File

@@ -241,6 +241,7 @@ if ($< == 0) {
system("cd $usr_dir && chown -R root:bin .");
}
system("find $usr_dir -name .git | xargs rm -rf");
system("find $usr_dir -name .github | xargs rm -rf");
system("find $usr_dir -name RELEASE | xargs rm -rf");
system("find $usr_dir -name RELEASE.sh | xargs rm -rf");
if (-r "$usr_dir/$mod/EXCLUDE") {

View File

@@ -263,6 +263,7 @@ my $ucprog = ucfirst($prog);
system("/bin/mkdir -p /tmp/makemodulerpm");
system("cd $par && /bin/cp -rpL $source_mod /tmp/makemodulerpm/$mod");
system("/usr/bin/find /tmp/makemodulerpm -name .git | xargs rm -rf");
system("/usr/bin/find /tmp/makemodulerpm -name .github | xargs rm -rf");
system("/usr/bin/find /tmp/makemodulerpm -name RELEASE | xargs rm -rf");
system("/usr/bin/find /tmp/makemodulerpm -name RELEASE.sh | xargs rm -rf");
system("/usr/bin/find /tmp/makemodulerpm -name t | xargs rm -rf");

View File

@@ -227,15 +227,7 @@ if ($rand1 eq $rand2) {
# Check if we can call sudo
if ($config{'sudo'} && &has_command("sudo")) {
eval "use IO::Pty";
if (!$@) {
$use_sudo = 1;
}
else {
push(@startup_msg,
"Perl module IO::Pty needed for calling sudo is not ".
"installed : $@");
}
$use_sudo = 1;
}
# init days and months for http_date
@@ -6042,7 +6034,7 @@ sub check_sudo_permissions
{
local ($user, $pass) = @_;
# First try the pipes
# First try the cache stored by the main process
if ($PASSINw) {
print DEBUG "check_sudo_permissions: querying cache for $user\n";
print $PASSINw "readsudo $user\n";
@@ -6054,27 +6046,18 @@ if ($PASSINw) {
}
}
local $ptyfh = new IO::Pty;
print DEBUG "check_sudo_permissions: ptyfh=$ptyfh\n";
if (!$ptyfh) {
&log_error("Failed to create new PTY with IO::Pty");
return 0;
}
local @uinfo = getpwnam($user);
# Setup pipes for communication with the sudo sub-process
pipe(SUDOINr, SUDOINw);
pipe(SUDOOUTr, SUDOOUTw);
print DEBUG "check_sudo_permissions\n";
my @uinfo = getpwnam($user);
if (!@uinfo) {
&log_error("Unix user $user does not exist for sudo");
return 0;
}
# Execute sudo in a sub-process, via a pty
local $ttyfh = $ptyfh->slave();
print DEBUG "check_sudo_permissions: ttyfh=$ttyfh\n";
local $tty = $ptyfh->ttyname();
print DEBUG "check_sudo_permissions: tty=$tty\n";
chown($uinfo[2], $uinfo[3], $tty);
pipe(SUDOr, SUDOw);
print DEBUG "check_sudo_permissions: about to fork..\n";
local $pid = fork();
my $pid = fork();
print DEBUG "check_sudo_permissions: fork=$pid pid=$$\n";
if ($pid < 0) {
&log_error("fork for sudo failed : $!");
@@ -6089,40 +6072,37 @@ if (!$pid) {
$ENV{'USER'} = $ENV{'LOGNAME'} = $user;
$ENV{'HOME'} = $uinfo[7];
$ptyfh->make_slave_controlling_terminal();
close(STDIN); close(STDOUT); close(STDERR);
untie(*STDIN); untie(*STDOUT); untie(*STDERR);
close($PASSINw); close($PASSOUTr);
close(SUDOw);
close(SUDOINw); close(SUDOOUTr);
close(SOCK);
close(MAIN);
open(STDIN, "<&SUDOr");
open(STDOUT, ">$tty");
open(STDIN, "<&SUDOINr");
open(STDOUT, ">&SUDOOUTw");
open(STDERR, ">&STDOUT");
close($ptyfh);
exec("sudo -l -S");
print "Exec failed : $!\n";
exit 1;
}
print DEBUG "check_sudo_permissions: pid=$pid\n";
close(SUDOr);
$ptyfh->close_slave();
close(SUDOINr);
close(SUDOOUTw);
# Send password, and get back response
local $oldfh = select(SUDOw);
my $oldfh = select(SUDOINw);
$| = 1;
select($oldfh);
print DEBUG "check_sudo_permissions: about to send pass\n";
local $SIG{'PIPE'} = 'ignore'; # Sometimes sudo doesn't ask for a password
print SUDOw $pass,"\n";
print SUDOINw $pass,"\n";
print DEBUG "check_sudo_permissions: sent pass=$pass\n";
close(SUDOw);
local $out;
while(<$ptyfh>) {
close(SUDOINw);
my $out;
while(<SUDOOUTr>) {
print DEBUG "check_sudo_permissions: got $_";
$out .= $_;
}
close($ptyfh);
close(SUDOOUTr);
kill('KILL', $pid);
waitpid($pid, 0);
local ($ok) = ($out =~ /\(ALL\)\s+ALL|\(ALL\)\s+NOPASSWD:\s+ALL|\(ALL\s*:\s*ALL\)\s+ALL|\(ALL\s*:\s*ALL\)\s+NOPASSWD:\s+ALL/ ? 1 : 0);

View File

@@ -158,6 +158,51 @@ $out =~ s/^\s+//g; $out =~ s/\s+$//g;
return split(/\s+/, $out);
}
# linux_openpty()
# Linux-only, pure-Perl openpty(3)-style helper.
# Returns master fh, slave fh, slave path, and ioctl value on success
sub linux_openpty
{
require Fcntl; Fcntl->import(qw(O_RDWR));
require POSIX; POSIX->import(qw(setsid));
# Linux ioctl values
my $TIOCGPTN = 0x80045430; # get pty number
my $TIOCSPTLCK = 0x40045431; # unlock slave
my $TIOCSCTTY = 0x540E; # set controlling tty
my ($ptmx, $ttyfh);
# Open PTY master
sysopen($ptmx, "/dev/ptmx", O_RDWR) || return;
# Unlock the slave
my $lock = pack("i", 0);
ioctl($ptmx, $TIOCSPTLCK, $lock) || do {
close($ptmx);
return;
};
# Get slave number
my $buf = pack("i", 0);
ioctl($ptmx, $TIOCGPTN, $buf) || do {
close($ptmx);
return;
};
my $n = unpack("i", $buf);
# Open PTY slave
my $tty = "/dev/pts/$n";
open($ttyfh, "+<", $tty) || do {
close($ptmx);
return;
};
# Return master fh, slave fh, slave path, ioctl value
return ($ptmx, $ttyfh, $tty, $TIOCSCTTY);
}
# get_new_pty()
# Returns the filehandles and names for a pty and tty
sub get_new_pty

View File

@@ -261,17 +261,19 @@ if (&is_readonly_mode()) {
&webmin_debug_log('CMD', "cmd=$cmd uid=$uid gid=$gid")
if ($gconfig{'debug_what_cmd'});
my ($ptyfh, $ttyfh, $pty, $tty, $TIOCSCTTY);
eval "use IO::Pty";
if (!$@) {
# Use the IO::Pty perl module if installed
local $ptyfh = new IO::Pty;
$ptyfh = new IO::Pty;
if (!$ptyfh) {
&error("Failed to create new PTY with IO::Pty");
}
local $pid = fork();
if (!$pid) {
local $ttyfh = $ptyfh->slave();
local $tty = $ptyfh->ttyname();
$ttyfh = $ptyfh->slave();
$tty = $ptyfh->ttyname();
if (defined(&close_controlling_pty)) {
&close_controlling_pty();
}
@@ -311,9 +313,57 @@ if (!$@) {
$ptyfh->close_slave();
return ($ptyfh, $pid);
}
elsif (defined &linux_openpty &&
do { ($ptyfh, $ttyfh, $tty, $TIOCSCTTY) = linux_openpty(); $ptyfh }) {
# Use pure-Perl Linux fallback
my $pid = fork();
if (!$pid) {
if (defined(&close_controlling_pty)) {
&close_controlling_pty();
}
setsid(); # create new session group
my $ctty_arg = 0; # must be writable scalar
ioctl($ttyfh, $TIOCSCTTY, $ctty_arg) # controlling tty
or &error("TIOCSCTTY failed: $!");
# Child must not hold the master end
close($ptyfh);
# Turn off echoing, if we can
eval "use IO::Stty";
if (!$@) {
IO::Stty::stty($ttyfh, 'raw', '-echo');
}
close(STDIN); close(STDOUT); close(STDERR);
untie(*STDIN); untie(*STDOUT); untie(*STDERR);
if ($uid) {
my $username = getpwuid($uid);
&switch_to_unix_user([ $username, undef, $uid, $gid ]);
}
open(STDIN, "<&".fileno($ttyfh));
open(STDOUT, ">&".fileno($ttyfh));
open(STDERR, ">&".fileno($ttyfh));
close($ttyfh);
if ($binary) {
my @args = &split_quoted_string($cmd);
my $args0 = $args[0];
$args[0] = $binary;
exec { $args0 } @args;
}
else {
exec($cmd);
}
print STDERR "Exec failed : $!\n";
exit 1;
}
close($ttyfh);
return ($ptyfh, $pid);
}
else {
# Need to create a PTY using built-in Webmin code
local ($ptyfh, $ttyfh, $pty, $tty) = &get_new_pty();
($ptyfh, $ttyfh, $pty, $tty) = &get_new_pty();
$tty || &error("Failed to create new PTY - try installing the IO::Tty Perl module");
local $pid = fork();
if (!$pid) {

View File

@@ -1 +1 @@
2.600
2.610

View File

@@ -40,8 +40,8 @@ else {
# All reasonable modules
@mods = &get_available_module_infos();
}
@mods = grep { !$_->{'clone'} && !$_->{'hidden'} }
grep { !$_->{'noui'} && !$_->{$pn.'_noui'} } @mods;
@mods = grep { !($_->{clone} || $_->{noui} || ($pn && $_->{"${pn}_noui"})) &&
(($_->{hidden} // 0) != 1) } @mods;
@mods = sort { $b->{'longdesc'} cmp $a->{'longdesc'} } @mods;
foreach my $m (@mods) {
if ($m->{'desc'} =~ /\Q$re\E/i) {

View File

@@ -1,5 +1,5 @@
xterm=xterm-256color
fontsize=15
fontsize=14
base_port=555
rcfile=0
locale=0

View File

@@ -1,6 +1,6 @@
xterm=Set <tt>TERM</tt> environmental variable to,4,xterm+256color-xterm&#45;256color,xterm+16color-xterm&#45;16color,xterm-xterm,vt102-vt102,vt100-vt100,vt52-vt52,rxvt-rxvt,nsterm-nsterm,dtterm-dtterm,ansi-ansi
size=Terminal width and height in characters,3,Automatic,5,,,Static (80x24)
fontsize=Adjust font size,4,0-Auto,12-Small,15-Normal,18-Large,21-Huge
fontsize=Adjust font size,4,0-Auto,12-Small,14-Normal,16-Large,18-Huge
locale=Set shell character encoding,10,0-Shell default,1-<tt>en_US.UTF&#45;8</tt>,Custom
rcfile=Execute initialization commands from file,10,0-Shell default,1-Module default,Custom
screen_reader=Enable screen reader mode,1,true-Yes,false-No

View File

@@ -6,7 +6,7 @@ require './xterm-lib.pl';
$ENV{'HTTP_WEBMIN_PATH'} && &error($text{'index_eproxy'});
# Check for needed modules
my @modnames = ("Digest::SHA", "Digest::MD5", "IO::Pty",
my @modnames = ("Digest::SHA", "Digest::MD5",
"IO::Select", "Time::HiRes",
"Net::WebSocket::Server");
foreach my $modname (@modnames) {
@@ -55,7 +55,7 @@ my $def_cols_n = 80;
my $def_rows_n = 24;
my $xmlhr = $ENV{'HTTP_X_REQUESTED_WITH'} eq "XMLHttpRequest";
my %term_opts;
my $font_size = $config{'fontsize'} || 15;
my $font_size = $config{'fontsize'} || 14;
# Parse module config
my ($conf_cols_n, $conf_rows_n) = ($conf_size_str =~ /([\d]+)X([\d]+)/i);

File diff suppressed because one or more lines are too long