Compare commits

...

60 Commits

Author SHA1 Message Date
Jamie Cameron
fd819d83e8 New version bump 2024-07-23 21:58:01 -07:00
Jamie Cameron
8c5fcef916 Fix string for update logging 2024-07-23 21:57:32 -07:00
Jamie Cameron
c15bbca109 Separate comment column https://github.com/webmin/webmin/issues/2221 2024-07-23 21:52:24 -07:00
Jamie Cameron
c47c4b7ffd Merge branch 'master' of github.com:webmin/webmin 2024-07-23 20:12:17 -07:00
Jamie Cameron
8efa25eabf Add missing function 2024-07-23 20:12:06 -07:00
Ilia Ross
190bd58b1b Fix to clarify option name 2024-07-24 03:50:01 +03:00
Ilia Ross
d645dc9345 Update changelog for Webmin 2.201 2024-07-24 03:25:43 +03:00
Ilia Ross
963bb60c02 Fix to go directly to viewing logs on module load 2024-07-24 03:18:31 +03:00
Jamie Cameron
fa4e39ec9a Merge branch 'master' of github.com:webmin/webmin 2024-07-23 17:00:41 -07:00
Jamie Cameron
c1b45ff210 Add option to include compressed rotated logs in searches, and enable it by default, to maintain parity with the old sylog module 2024-07-23 17:00:34 -07:00
Ilia Ross
5cb103bde3 Revert "Fix to call exit after redirect"
This reverts commit e3a1fd849b.
2024-07-24 02:02:14 +03:00
Ilia Ross
7282348b7d Fix to use consistent download page 2024-07-24 00:20:58 +03:00
Ilia Ross
e3a1fd849b Fix to call exit after redirect 2024-07-24 00:20:47 +03:00
Jamie Cameron
1fb01aa46e Fix permissions 2024-07-23 13:50:19 -07:00
Jamie Cameron
779ebb4a63 Fix redirection to first log 2024-07-23 13:50:02 -07:00
Jamie Cameron
c391830670 Fix more cases where switch_to_unix_user isn't being passed the username 2024-07-22 16:48:28 -07:00
Jamie Cameron
c8c6c3e40f Merge branch 'master' of github.com:webmin/webmin 2024-07-22 16:11:41 -07:00
Jamie Cameron
c1f45d6d61 When running a command as a different user, the username needs to be passed to switch_to_unix_user so that all the secondary groups can be populated https://github.com/webmin/webmin/issues/2223 2024-07-22 16:11:37 -07:00
Ilia Ross
8804ba6529 Update CHANGELOG.md 2024-07-22 16:00:56 +03:00
Ilia Ross
11ae39081c Fix to try more simple patch command at first 2024-07-22 14:18:51 +03:00
Jamie Cameron
2751224d4d Really update version 2024-07-21 10:21:20 -07:00
Jamie Cameron
6fce9fa491 New version bump 2024-07-21 10:20:43 -07:00
Jamie Cameron
41fdb5dac2 Fix renumbering when adding a domain 2024-07-20 21:53:49 -07:00
Jamie Cameron
4ffca4597c Clean up group_to_dn function 2024-07-20 21:30:46 -07:00
Jamie Cameron
ecfc06d9c6 Preserve firstname and surname 2024-07-20 21:28:45 -07:00
Jamie Cameron
db55dde7ce Merge branch 'master' of github.com:webmin/webmin 2024-07-20 21:23:16 -07:00
Jamie Cameron
c6edd4b97d Code cleanups 2024-07-20 21:19:01 -07:00
Ilia Ross
8cd2dbae96 Fix to redirect to tabs only inside same module
https://forum.virtualmin.com/t/small-upgrade-error-maybe-wrong-url-on-button/127999?u=ilia
2024-07-21 02:37:32 +03:00
Jamie Cameron
8676a3fb21 Merge branch 'master' of github.com:webmin/webmin 2024-07-20 16:18:25 -07:00
Jamie Cameron
27339eb1bf Use my instead of local 2024-07-20 16:18:16 -07:00
Ilia Ross
e014926854 Update CHANGELOG.md for 2.200 2024-07-21 02:00:01 +03:00
Ilia Ross
a721f60f9c Fix to allow service-worker.js in unauth [build] 2024-07-20 15:57:40 +03:00
Jamie Cameron
46c76e13f9 Merge branch 'master' of github.com:webmin/webmin 2024-07-19 16:52:29 -07:00
Jamie Cameron
f72058306b COnfig option to show hostname and comment https://github.com/webmin/webmin.com/issues/18 2024-07-19 16:52:23 -07:00
Ilia Ross
a15446d3b1 Fix to simplify the code and use no globals [build] 2024-07-19 13:40:14 +03:00
Ilia Ross
fc9ce7f3dd Fix comment 2024-07-19 13:30:01 +03:00
Ilia Ross
72cd50a054 Fix to consider "F" as new theme name "Framed" not "Gray" 2024-07-19 13:13:53 +03:00
Ilia Ross
e307fb4dcd Fix to drop unnecessary option 2024-07-19 12:36:52 +03:00
Jamie Cameron
d631929194 Merge branch 'master' of github.com:webmin/webmin 2024-07-16 16:08:06 -07:00
Jamie Cameron
db9628e7eb Update MIME types for javascript and gzipped files 2024-07-16 16:08:01 -07:00
Jamie Cameron
2c04c04ce7 Merge pull request #2217 from webmin/dev/package-updates-always-show-sec
Fix to always show security updates button
2024-07-16 11:51:16 -07:00
Ilia Ross
a5301245d3 Fix to always show security updates button 2024-07-16 17:38:14 +03:00
Jamie Cameron
165af690c7 Log automatic package updates 2024-07-13 17:07:07 -07:00
Jamie Cameron
29da8ea3d0 Clarify what kind of update it is https://forum.virtualmin.com/t/security-updates-being-auto-installed-regardles-of-software-scheduled-upgrades-set-to-just-notify/127852 2024-07-12 17:22:19 -07:00
Jamie Cameron
73b7e62f13 Merge branch 'master' of github.com:webmin/webmin 2024-07-09 08:30:51 -07:00
Ilia Ross
76141ce22f Fix to use larger QR code [build] 2024-07-09 15:53:18 +03:00
Jamie Cameron
4b575b8168 Clarify comment 2024-07-08 22:55:44 -07:00
Ilia Ross
2b28521297 Fix to display correct return button 2024-07-08 21:03:40 +03:00
Ilia Ross
be767951ca Fix to have no block elements in header 2024-07-08 19:33:52 +03:00
Jamie Cameron
9960d6011f Update comment to match reality 2024-07-07 11:12:47 -07:00
Jamie Cameron
461bd30e2a Save last size and subset mode 2024-07-06 15:26:57 -07:00
Jamie Cameron
2f88a4eefb Follow default reuse option 2024-07-06 15:23:17 -07:00
Jamie Cameron
c9f368d264 Properly check all ServerAlias directives and ports 2024-07-06 15:12:08 -07:00
Jamie Cameron
0e24e8ac61 Merge branch 'master' of github.com:webmin/webmin 2024-07-05 10:32:21 -07:00
Jamie Cameron
1d0d25efac Don't add tab param twice https://sourceforge.net/p/webadmin/bugs/5648/ 2024-07-05 10:01:55 -07:00
Jamie Cameron
1c5d2d2bd7 Merge pull request #2211 from webmin/dev/preserve-file-acls
Add ability to preserve original file ACLs
2024-07-03 15:43:43 -07:00
Jamie Cameron
927a2c32d8 Show queue state in list 2024-07-02 21:36:05 -07:00
Jamie Cameron
4a3c6c4854 Merge branch 'master' of github.com:webmin/webmin 2024-07-02 21:21:27 -07:00
Jamie Cameron
37beab77ba Show mail queue directory 2024-07-02 21:21:21 -07:00
Ilia Ross
5f579e8ded Fix to invalidate OS EOL data on upgrade 2024-07-02 22:24:09 +03:00
47 changed files with 392 additions and 223 deletions

View File

@@ -1,5 +1,33 @@
## Changelog
#### 2.201 (July 24, 2024)
* Fix real-time monitoring not updating graphs in the Dashboard [#2222](https://github.com/webmin/webmin/issues/2222)
* Fix Terminal module to work correctly with _sudo_-capable users [#2223](https://github.com/webmin/webmin/issues/2223)
#### 2.200 (July 21, 2024)
* Add support for blocking a given IP temporarily or permanently in the FirewallD module
* Add support for parsing iCalendar event files in the Mailbox module
* Add support for tailing logs in real time in System Logs module
* Add ability to preserve original file ACLs when writing files [webmin/authentic-theme#1511](https://github.com/webmin/authentic-theme/discussions/1511#discussioncomment-9913902)
* Add a `patch` sub-command to the `webmin` command for easy application of patches
* Add a config option to display hostname and comment in the DHCP Server module [#2221](https://github.com/webmin/webmin/issues/2221)
* Add support for ED25519 and ED448 algorithms in BIND DNS module for DNSSEC
* Add support for larger ranger of authentication methods in Dovecot module
* Add improved support for displaying last logins in the Users and Groups module
* Fix to prevent duplicate `also-notify` and `allow-transfer` IPs in the BIND DNS module
* Fix issues with Terminal module to correct text display problems in editor mode
* Fix to store Terminal module logs in the `/var/webmin` directory
* Fix to display the Spam folder nicely in the Mailbox module
* Fix how modules are loaded in ProFTPd module
* Fix support for the Chrony service on Debian systems in the System Time module
* Fix to use static routes to set the default gateway in Network Configuration module
* Fix to correctly invalidate EOL cache on re-checks [#2139](https://github.com/webmin/webmin/issues/2139)
* Fix to change default monitor name based on database used MariaDB vs MySQL [#2139](https://github.com/virtualmin/virtualmin-gpl/issues/798)
* Fix to disable manual upgrades for systems installed from the repository
* Fix to preserve Webmin service state during package upgrades [#2133](https://github.com/webmin/webmin/issues/2133)
* Change to enforce _sudo_-capable logins as themselves in the Terminal module [docs/modules/terminal](https://webmin.com/docs/modules/terminal/#about)
* Rename "System Logs" module to "System Logs RS" and "System Logs Viewer" to "System Logs" for clarity
#### 2.111 (April 16, 2024)
* Fix EOL detection for unreleased Linux distributions

View File

@@ -37,14 +37,16 @@ init_config();
# Check if curl is installed
if (!has_command('curl')) {
print "curl is not installed\n";
print "\"curl\" command is not installed\n";
exit 1;
}
# Check if git is installed
if (!has_command('git')) {
print "git is not installed\n";
exit 1;
if (!has_command('patch')) {
if (!has_command('git')) {
print "Neither \"patch\" nor \"git\" commands are installed\n";
exit 1;
}
}
# Get patch URL or file
@@ -96,14 +98,23 @@ else {
$cmd = "cat @{[quotemeta($patch)]}";
}
# Apply patch using Git
my $output = `$cmd 2>&1 | git apply --reject --verbose --whitespace=fix 2>&1`;
if ($output !~ /applied patch.*?cleanly/i) {
print "Patch failed: $output\n";
exit 1;
}
# Apply patch using Patch or Git command
my $output;
if (has_command('patch')) {
$output = `$cmd 2>&1 | patch -p1 --verbose 2>&1`;
if ($output !~ /succeeded/i) {
print "Patch failed: $output\n";
exit 1;
}
} else {
$output = `$cmd 2>&1 | git apply --reject --verbose --whitespace=fix 2>&1`;
if ($output !~ /applied patch.*?cleanly/i) {
print "Patch failed: $output\n";
exit 1;
}
}
print "Patch applied successfully to:\n";
print " $1\n" while $output =~ /^Applied patch\s+(\S+)/mg;
print " $1\n" while $output =~ /^(?|Applied patch\s+(\S+)|patching file\s+(\S+))/mg;
system("$config_dir/restart");
=pod

View File

@@ -8,7 +8,7 @@ lease_refresh=Seconds between refreshing lease list,3,Never
show_ip=Show IP addresses for hosts?,1,1-Yes,0-No
show_mac=Show MAC addresses for hosts?,1,1-Yes,0-No
group_name=Show group names as,1,1-<tt>domain&#45;name</tt> option,0-Name or member count,2-Description
desc_name=Show other object descriptions instead of names?,1,1-Yes,0-No
desc_name=Show descriptions instead of names?,1,1-Description only,0-Name only,2-Both name and description
display_max=Maximum number of subnets and hosts to display,3,Unlimited
add_file=Add new subnets&#44; hosts and groups to file,3,Main configuration file
line2=System configuration,11

View File

@@ -7,7 +7,6 @@ lease_refresh=Segons entre refrescs de la llista de préstecs,3,Mai
show_ip=Mostra les adreces IP dels hosts,1,1-Sí,0-No
show_mac=Mostra les adreces MAC dels hosts,1,1-Sí,0-No
group_name=Mostra els noms de grup com,1,1-Opció <tt>domini&#45;nom</tt>,0-Nom o recompte de membres,2-Descripció
desc_name=Mostra les descripcions dels altres objectes en lloc dels noms,1,1-Sí,0-No
display_max=Nombre màxim de subxarxes i hosts a mostrar,3,Il·limitat
add_file=Afegeix subxarxes noves&#44; hosts i grups al fitxer,3,Fitxer de configuració principal
line2=Configuració del sistema,11

View File

@@ -6,7 +6,6 @@ lease_tz=Zobrazit dobu pronájmu v,1,0-GMT,1-Lokálním čase
show_ip=Zobrazit IP adresy pro hosty?,1,1-ano,0-ne
show_mac=Zobrazit MAC adresy hostů?,1,1-Ano,0-Ne
group_name=Zobrazení jmen skupin jako,1,1-<tt>doménová jména</tt>,0-Jména nebo počtu členů,2-Popisu
desc_name=Ukázat popisy objektů místo jejich názvů?,1,1-Ano,0-Ne
display_max=Počet maximálně zobrazených podsítí a hostů,3,Bezomezení
line2=Konfigurace systému,11
dhcpd_conf=Konfigurační soubor DHCP serveru,0

View File

@@ -6,7 +6,6 @@ lease_tz=Vis lease tider i,1,0-GMT,1-Lokal tid
show_ip=Vis IP adresser for hosts?,1,1-Ja,0-Nej
show_mac=Vis MAC adresser for hosts?,1,1-Ja,0-Nej
group_name=Vis gruppenavne som,1,1-<tt>domæne&#45;navne</tt> indstilling,0-Navn eller medlemsantal,2-Beskrivelse
desc_name=Vis andre objektbeskrivelse istedet for navne?,1,1-Ja,0-Nej
display_max=Maksimalt antal hosts og subnet der skal vises,3,Ubegrænset
line2=Systemkonfiguration
dhcpd_conf=DHCP server config fil,0

View File

@@ -7,7 +7,6 @@ lease_refresh=Sekunden zwischen dem Aktualisieren der Leasing-Liste,3,Niemals
show_ip=Zeige IP-Adressen für Hosts?,1,1-Ja,0-Nein
show_mac=Zeige MAC-Adressen für Hosts?,1,1-Ja,0-Nein
group_name=Zeige Gruppennamen als,1,1-<tt>domain&#45;name</tt> Option,0-Name oder Mitglied,2-Beschreibung
desc_name=Zeige andere Objektbeschreibungen statt Namen?,1,1-Ja,0-Nein
display_max=Maximale Anzahl an Subnetzen und Hosts zum Anzeigen,3,Unbegrenzt
add_file=Füge neue Subnetze&#44; Hosts und Gruppen in einer Datei hinzu,3,Haupt-Konfigurationsdatei
line2=Systemkonfiguration,11

View File

@@ -6,7 +6,6 @@ lease_tz=نمايش زمان انتساب داده شده‌ها براساس,1,
show_ip=آيا نشانيهاي IP براي ميزبانها نشان داده شود؟,1,1-بله,0-خير
show_mac=آيا نشانيهاي MACبراي ميزبانها نشان داده شود؟,1,1-بله,0-خير
group_name=نشان‌دادن نامهاي گروه به‌صورت,1,1- گزينه<tt> دامنه/نام </tt>,0-نام يا تعداد اعضا,2-شرح
desc_name=آيا ساير شرحها به جاي نام نشان داده شود؟,1,1-بله,0-خير
display_max=حداکثر تعداد زيرشبکه‌ها و ميزبانها جهت نمايش,3,نامحدود
line2=پيکربندي سيستم,11
dhcpd_conf=پرونده پيکربندي کارساز DHCP,0

View File

@@ -6,7 +6,6 @@ lease_tz=Afficher les temps de bail en,1,0-GMT,1-Temps local
show_ip=Montrer les adresses IP des postes ?,1,1-Oui,0-Non
show_mac=Montrer les adresses MAC des postes ?,1,1-Oui,0-Non
group_name=Montrer les noms de groupe comme,1,1-Nom de domaine,0-Nom ou numero de membre
desc_name=Montrer les descriptions au lieu des noms ?,1,1-Oui,0-Non
display_max=Nombre maximum de sous-reseaux et de postes a afficher,3,Illimite
line2=Configuration du systeme,11
dhcpd_conf=Fichier de configuration du serveur DHCP,0

View File

@@ -6,7 +6,6 @@ lease_tz=リース時間の表示形式,1,0-GMT,1-ローカル時間
show_ip=ホストのIPアドレスを表示しますか?,1,1-はい,0-いいえ
show_mac=ホストのMACアドレスを表示しますか?,1,1-はい,0-いいえ
group_name=グループ名の表示方法,1,1-<tt>ドメイン&#45;名</tt> オプション,0-名前またはメンバー数
desc_name=名称の替わりにオブジェクトの説明を表示しますか?,1,1-はい,0-いいえ
display_max=サブネットとホストの表示する最大数,3,無制限
line2=システム設定,11
dhcpd_conf=DHCPサーバ 設定ファイル,0

View File

@@ -7,7 +7,6 @@ lease_refresh=Seconden tussen verversen van lease lijst,3,Nooit
show_ip=Laat IP adressen zien voor hosts?,1,1-Ja,0-Nee
show_mac=Laat MAC adressen zien voor hosts?,1,1-Ja,0-Nee
group_name=Laat groep namen zien als,1,1-<tt>domein&#45;naam</tt> optie,0-Naam of Lid van,2-Omschrijving
desc_name=Laat andere object omschrijvingen zien in plaats van namen?,1,1-Ja,0-Nee
display_max=Maximum aantal subnets en hosts om te laten zien,3,Ongelimiteerd
add_file=Toevoegen nieuwe subnetten&#44; host en groepen aan file,3,Hoofd configuratie file
line2=Systeem configuratie,11

View File

@@ -7,7 +7,6 @@ lease_refresh=Sekunder mellom oppfrisking av liste med leieavtaler,3,Aldri
show_ip=Vis IP adresser for verter?,1,1-Ja,0-Nei
show_mac=Vis MAC adresser for verter?,1,1-Ja,0-Nei
group_name=Vis gruppenavn som,1,1-<tt>domene&#45;navn</tt> alternativ,0-Navn eller antall medlemmer,2-Beskrivelse
desc_name=Vis andre objektbeskrivelser i stedet for navn,1,1-Ja,0-Nei
display_max=Maks antall subnett og verter som skal vises,3,Ubegrenset
add_file=Legg til nye subnett&#44; verter og grupper i filen,3,Hoved konfigurasjonsfil
line2=System konfigurasjon,11

View File

@@ -7,7 +7,6 @@ lease_refresh=Sekund pomiędzy odświeżaniem listy dzierżawy,3,Nigdy
show_ip=Wyświetlać adres IP hostów?,1,1-Tak,0-Nie
show_mac=Wyświetlać adres MAC hostów?,1,1-Tak,0-Nie
group_name=Wyświetl nazwy grupy jako,1,1-<tt>domain&#45;name</tt>,0-Ilość lub nazwa użytkowników,2-Opis
desc_name=Wyświetlać inne opisy obiektów zamiast nazw,1,1-Tak,0-Nie
display_max=Maksymalna liczba wyświetlanych podsieci i hostów,3,Nieograniczona
add_file=Dodaj nowe podsieci&#44; hosty i grupy do pliku,3,Główny plik konfiguracyjny
line2=Opcje systemowe,11

View File

@@ -6,7 +6,6 @@ lease_tz=Display leases times in,1,0-GMT,1-Local time
show_ip=Mostrar endereço IP para computadores?,1,1-Sim,0-Não
show_mac=Mostrar endereço MAC para computadores?,1,1-Sim,0-Não
group_name=Mostrar nomes de grupo como,1,1-<tt>nome de&#45;domínio</tt>,0-Nome ou membro
desc_name=Mostrar descrição de objetos ao invés de nomes?,1,1-Sim,0-Não
display_max=Número máximo de subredes e computadores a serem
add_file=Acrescentar novas subredes&#44; hosts e grupos para arquivo,3,Arquivo principal de configuração
line2=Configuração do sistema,11

View File

@@ -6,7 +6,6 @@ lease_tz=Zobraziť časy pridelených adries v,1,0-GMT,1-Lokálnom čase
show_ip=Zobraziť IP adresy pre počítače?,1,1-Áno,0-Nie
show_mac=Zobraziť MAC adresy pre počítače?,1,1-Áno,0-Nie
group_name=Zobraziť skupinové mená ako ,1,1-<tt>doménové mená</tt> ,0-Meno alebo počet členov,2-Popis
desc_name=Ukázať popisy objektov namiesto ich názvov?,1,1-Áno,0-Nie
display_max=Maximálny počet subnetov a hostiteľov pre zobrazenie,3,Bez limitu
line2=Systémové nastavenia,11
dhcpd_conf=Konfiguračný súbor DHCP servera,0

View File

@@ -211,14 +211,18 @@ foreach $u (@subn) {
push(@sicons, $i = "images/shared.gif");
push(@checkboxids, $u->{'index'});
}
if ($config{'desc_name'} && $u->{'comment'}) {
push(@utitles, $t = &html_escape($u->{'comment'}));
if ($config{'desc_name'} == 0) {
$t = $u->{'values'}->[0];
}
elsif ($config{'desc_name'} == 1) {
$t = $u->{'comment'} || $u->{'values'}->[0];
}
else {
push(@utitles, $t = &html_escape($u->{'values'}->[0]));
$t = $u->{'values'}->[0].($u->{'comment'} ? " ($u->{'comment'})" : "");
}
push(@utitles, &html_escape($t));
push(@uslinks, $l); # so that ordering is preserved
push(@ustitles, $t);
push(@ustitles, &html_escape($t));
push(@usicons, $i);
}
@checkboxes = map { &ui_checkbox("d", $_) } @checkboxids;
@@ -336,12 +340,16 @@ foreach $h (@host) {
(defined($subnet{$h}) ? "&uidx=$subnet{$h}" : "").
(defined($shared{$h}) ? "&sidx=$shared{$h}" : "") :
undef);
if ($config{'desc_name'} && $h->{'comment'}) {
push(@htitles, &html_escape($h->{'comment'}));
if ($config{'desc_name'} == 0) {
$t = $h->{'values'}->[0];
}
elsif ($config{'desc_name'} == 1) {
$t = $h->{'comment'} || $h->{'values'}->[0];
}
else {
push(@htitles, &html_escape($h->{'values'}->[0]));
$t = $h->{'values'}->[0].($h->{'comment'} ? " ($h->{'comment'})" : "");
}
push(@htitles, &html_escape($t));
if ($config{'show_ip'}) {
$fv = &fixedaddr($h);
$htitles[$#htitles] .= "<br>".$fv if ($fv);
@@ -589,7 +597,13 @@ sub host_table
{
local ($i, $h, $parent);
local @tds = ( "width=5" );
print &ui_columns_start([ "", $text{'index_hostgroup'},
my $hascmt;
for ($i = $_[1]; $i < $_[2]; $i++) {
$hascmt++ if ($_[4]->[$i] =~ /\(.*\)/);
}
print &ui_columns_start([ "",
$text{'index_hostgroup'},
$hascmt ? ( $text{'index_comment'} ) : ( ),
$text{'index_parent'}, $text{'index_hardware'},
$text{'index_nameip'} ], 100, 0, \@tds);
for ($i = $_[1]; $i < $_[2]; $i++) {
@@ -605,6 +619,10 @@ for ($i = $_[1]; $i < $_[2]; $i++) {
$firstcol .= $text{'index_group'}." ";
$sp = "\&nbsp;\&nbsp;";
}
my $cmt;
if ($_[4]->[$i] =~ s/\s+\((.*)\)//) {
$cmt = $1;
}
if ($_[3]->[$i]) {
$firstcol .= &ui_link($_[3]->[$i], $_[4]->[$i]);
}
@@ -612,6 +630,7 @@ for ($i = $_[1]; $i < $_[2]; $i++) {
$firstcol .= $_[4]->[$i];
}
push(@cols, $firstcol);
push(@cols, $cmt) if ($hascmt);
if ($par{$h}->{'name'} eq "group") {
$par_type = $text{'index_togroup'};
@@ -640,7 +659,14 @@ sub net_table
{
local ($i, $n);
local @tds = ( "width=5" );
print &ui_columns_start([ "", $text{'index_net'}, $text{'index_netmask'},
my $hascmt;
for ($i = $_[1]; $i < $_[2]; $i++) {
$hascmt++ if ($_[4]->[$i] =~ /\(.*\)/);
}
print &ui_columns_start([ "",
$text{'index_net'},
$hascmt ? ( $text{'index_comment'} ) : ( ),
$text{'index_netmask'},
$text{'index_desc'}, $text{'index_parent'} ], 100,
0, \@tds);
for ($i = $_[1]; $i < $_[2]; $i++) {
@@ -653,6 +679,10 @@ for ($i = $_[1]; $i < $_[2]; $i++) {
else {
$sp = "\&nbsp;\&nbsp;";
}
my $cmt;
if ($_[4]->[$i] =~ s/\s+\((.*)\)//) {
$cmt = $1;
}
if ($_[3]->[$i]) {
$first .= &ui_link($_[3]->[$i],$_[4]->[$i]);
}
@@ -660,6 +690,7 @@ for ($i = $_[1]; $i < $_[2]; $i++) {
$first .= $_[4]->[$i];
}
push(@cols, $first);
push(@cols, $cmt) if ($hascmt);
push(@cols, $_[3]->[$i] ? &netmask($n) : "");
push(@cols, $n->{'comment'});
push(@cols, $par{$n} ?

View File

@@ -14,6 +14,7 @@ index_memb=$1 members
index_hst=Hosts and Host Groups
index_nohst=No hosts or groups have been defined.
index_hostgroup=Host/Group
index_comment=Description
index_parent=Parent
index_hardware=Hardware Address
index_group=Group:

View File

@@ -95,7 +95,7 @@ foreach (@lines) {
}
}
elsif (/^(\s*)(#?)([a-z0-9\_]+)\s+=\s*(.*)/) {
# A directive inside a section
# A directive which may or may not be inside a section
local $dir = { 'name' => $3,
'value' => $4,
'enabled' => !$2,
@@ -376,9 +376,9 @@ else {
}
}
splice(@$lref, $section->{'line'}, 0, @newlines);
$section->{'eline'} = $section->{'line'} + scalar(@newlines) - 1;
&renumber($conf, $section->{'eline'}, $section->{'file'},
scalar(@newlines)-$oldlen);
$section->{'eline'} = $section->{'line'} + scalar(@newlines) - 1;
$section->{'file'} = $file;
my $i = 1;
foreach my $m (@{$section->{'members'}}) {

View File

@@ -55,7 +55,7 @@ if (@jails) {
$col =~ s/\s/_/g;
if ($col !~ /journal_matches/ &&
$col !~ /file_list/) {
push(@head, "<div $tdc>".$text{"status_head_$col"}."</div>");
push(@head, "<span $tdc>".$text{"status_head_$col"}."</span>");
if ($col =~ /banned_ip_list/) {
$jips = $val;
my @ips = split(/\s+/, $val);

0
firewalld/block_ip.cgi Normal file → Executable file
View File

View File

@@ -230,31 +230,32 @@ return @list_users_cache;
# it to the LDAP database
sub create_user
{
local $ldap = &ldap_connect();
local $base = &get_user_base();
$_[0]->{'dn'} = "uid=$_[0]->{'user'},$base";
local @classes = ( &def_user_obj_class(), "shadowAccount",
my ($user) = @_;
my $ldap = &ldap_connect();
my $base = &get_user_base();
$user->{'dn'} = "uid=$user->{'user'},$base";
my @classes = ( &def_user_obj_class(), "shadowAccount",
split(/\s+/, $config{'other_class'}),
@{$_[0]->{'ldap_class'}} );
local $schema = $ldap->schema();
@{$user->{'ldap_class'}} );
my $schema = $ldap->schema();
if ($schema->objectclass("person") && $config{'person'}) {
push(@classes, "person");
}
@classes = &uniquelc(@classes);
@classes = grep { /\S/ } @classes; # Remove empty
local @attrs = &user_to_dn($_[0]);
push(@attrs, &split_props($config{'props'}, $_[0]));
push(@attrs, @{$_[0]->{'ldap_attrs'}});
my @attrs = &user_to_dn($user);
push(@attrs, &split_props($config{'props'}, $user));
push(@attrs, @{$user->{'ldap_attrs'}});
push(@attrs, "objectClass" => \@classes);
if (&indexoflc("person", @classes) >= 0 && !&in_props(\@attrs, "sn")) {
# Person needs 'sn'
push(@attrs, "sn", &in_props(\@attrs, "cn"));
}
local $rv = $ldap->add($_[0]->{'dn'}, attr => \@attrs);
my $rv = $ldap->add($user->{'dn'}, attr => \@attrs);
if ($rv->code) {
&error(&text('usave_eadd', $rv->error));
}
push(@list_users_cache, $_[0]) if (scalar(@list_users_cache));
push(@list_users_cache, $user) if (scalar(@list_users_cache));
$ldap->unbind();
&useradmin::refresh_nscd() if (!$batch_mode);
}
@@ -264,8 +265,9 @@ $ldap->unbind();
# it from the LDAP database
sub delete_user
{
local $ldap = &ldap_connect();
local $rv = $ldap->delete($_[0]->{'dn'});
my ($user) = @_;
my $ldap = &ldap_connect();
my $rv = $ldap->delete($user->{'dn'});
if ($rv->code) {
my $err = $rv->error;
if ($err !~ /No such object/i) {
@@ -273,7 +275,7 @@ if ($rv->code) {
}
}
$ldap->unbind();
@list_users_cache = grep { $_ ne $_[0] } @list_users_cache
@list_users_cache = grep { $_ ne $user } @list_users_cache
if (scalar(@list_users_cache));
&useradmin::refresh_nscd() if (!$batch_mode);
}
@@ -281,52 +283,53 @@ $ldap->unbind();
# modify_user(&olduser, &newuser)
sub modify_user
{
local $ldap = &ldap_connect();
local $base = &get_user_base();
local @attrs = &user_to_dn($_[1]);
push(@attrs, &split_props($config{'mod_props'}, $_[1]));
push(@attrs, @{$_[1]->{'ldap_attrs'}});
if ($_[1]->{'ldap_class'} &&
(!ref($_[1]->{'ldap_class'}) || @{$_[1]->{'ldap_class'}})) {
push(@attrs, "objectClass" => $_[1]->{'ldap_class'});
my ($olduser, $user) = @_;
my $ldap = &ldap_connect();
my $base = &get_user_base();
my @attrs = &user_to_dn($user);
push(@attrs, &split_props($config{'mod_props'}, $user));
push(@attrs, @{$user->{'ldap_attrs'}});
if ($user->{'ldap_class'} &&
(!ref($user->{'ldap_class'}) || @{$user->{'ldap_class'}})) {
push(@attrs, "objectClass" => $user->{'ldap_class'});
}
if (&indexoflc("person", @{$_[1]->{'ldap_class'}}) >= 0 &&
if (&indexoflc("person", @{$user->{'ldap_class'}}) >= 0 &&
!&in_props(\@attrs, "sn")) {
# Person needs 'sn'
push(@attrs, "sn", &in_props(\@attrs, "cn"));
}
local %replace;
my %replace;
for(my $i=0; $i<@attrs; $i+=2) {
$replace{$attrs[$i]} ||= [ ];
local $v = $attrs[$i+1];
my $v = $attrs[$i+1];
push(@{$replace{$attrs[$i]}}, ref($v) ? @$v : $v);
}
if ($_[0]->{'pass'} eq $_[1]->{'pass'}) {
if ($olduser->{'pass'} eq $user->{'pass'}) {
# Don't change password attribute if not change
delete($replace{'userPassword'});
}
# Do rename to new DN first
if ($_[0]->{'user'} ne $_[1]->{'user'}) {
local $newdn = $_[0]->{'dn'};
if ($newdn !~ s/^uid=$_[0]->{'user'},/uid=$_[1]->{'user'},/) {
$newdn = "uid=$_[1]->{'user'},$base";
if ($olduser->{'user'} ne $user->{'user'}) {
my $newdn = $olduser->{'dn'};
if ($newdn !~ s/^uid=$olduser->{'user'},/uid=$user->{'user'},/) {
$newdn = "uid=$user->{'user'},$base";
}
if (!&same_dn($newdn, $_[0]->{'dn'})) {
$rv = $ldap->moddn($_[0]->{'dn'},
newrdn => "uid=$_[1]->{'user'}");
if (!&same_dn($newdn, $olduser->{'dn'})) {
$rv = $ldap->moddn($olduser->{'dn'},
newrdn => "uid=$user->{'user'}");
if ($rv->code) {
&error(&text('usave_emoddn', $rv->error));
}
$_[1]->{'dn'} = $newdn;
$user->{'dn'} = $newdn;
}
}
local $rv = $ldap->modify($_[1]->{'dn'}, replace => \%replace);
my $rv = $ldap->modify($user->{'dn'}, replace => \%replace);
if ($rv->code) {
&error(&text('usave_emod', $rv->error));
}
if ($_[0] ne $_[1] && &indexof($_[0], @list_users_cache) != -1) {
if ($olduser ne $user && &indexof($olduser, @list_users_cache) != -1) {
# Update old object in cache
%{$_[0]} = %{$_[1]};
%{$olduser} = %{$user};
}
$ldap->unbind();
&useradmin::refresh_nscd() if (!$batch_mode);
@@ -431,37 +434,42 @@ $ldap->unbind();
# in the same format uses by the useradmin module
sub dn_to_hash
{
if ($_[0]->get_value("uid")) {
local %user = ( 'dn' => $_[0]->dn(),
'user' => $_[0]->get_value("uid"),
'uid' => $_[0]->get_value("uidNumber"),
'gid' => $_[0]->get_value("gidNumber"),
'real' => $_[0]->get_value("cn"),
'home' => $_[0]->get_value("homeDirectory"),
'shell' => $_[0]->get_value("loginShell"),
'pass' => $_[0]->get_value("userPassword"),
'change' => $_[0]->get_value("shadowLastChange") || "",
'expire' => $_[0]->get_value("shadowExpire") || "",
'min' => $_[0]->get_value("shadowMin") || "",
'max' => $_[0]->get_value("shadowMax") || "",
'warn' => $_[0]->get_value("shadowWarning") || "",
'inactive' => $_[0]->get_value("shadowInactive") || "",
);
my ($obj) = @_;
if ($obj->get_value("uid")) {
my %user = ( 'dn' => $obj->dn(),
'user' => $obj->get_value("uid"),
'uid' => $obj->get_value("uidNumber"),
'gid' => $obj->get_value("gidNumber"),
'real' => $obj->get_value("cn"),
'home' => $obj->get_value("homeDirectory"),
'shell' => $obj->get_value("loginShell"),
'pass' => $obj->get_value("userPassword"),
'change' => $obj->get_value("shadowLastChange") || "",
'expire' => $obj->get_value("shadowExpire") || "",
'min' => $obj->get_value("shadowMin") || "",
'max' => $obj->get_value("shadowMax") || "",
'warn' => $obj->get_value("shadowWarning") || "",
'inactive' => $obj->get_value("shadowInactive") || "",
);
if ($config{'given'}) {
$user{'firstname'} = $obj->get_value("givenName");
$user{'surname'} = $obj->get_value("sn");
}
$user{'pass'} =~ s/^(\!?)\{[a-z0-9]+\}/$1/i;
$user{'all_ldap_attrs'} = { map { lc($_), scalar($_[0]->get_value($_)) }
$_[0]->attributes() };
$user{'ldap_class'} = [ $_[0]->get_value('objectClass') ];
$user{'all_ldap_attrs'} = { map { lc($_), scalar($obj->get_value($_)) }
$obj->attributes() };
$user{'ldap_class'} = [ $obj->get_value('objectClass') ];
return %user;
}
else {
local @members = $_[0]->get_value('memberUid');
local %group = ( 'dn' => $_[0]->dn(),
'group' => $_[0]->get_value("cn"),
'gid' => $_[0]->get_value("gidNumber"),
'pass' => $_[0]->get_value("userPassword") || "",
'members' => join(",", @members) || "",
'desc' => $_[0]->get_value("description"),
);
my @members = $obj->get_value('memberUid');
my %group = ( 'dn' => $obj->dn(),
'group' => $obj->get_value("cn"),
'gid' => $obj->get_value("gidNumber"),
'pass' => $obj->get_value("userPassword") || "",
'members' => join(",", @members) || "",
'desc' => $obj->get_value("description"),
);
return %group;
}
}
@@ -470,48 +478,56 @@ else {
# Given a useradmin-style user hash, returns a list of properties
sub user_to_dn
{
local $pfx = $_[0]->{'pass'} =~ /^\{[a-z0-9]+\}/i ? undef :
$_[0]->{'pass'} =~ /^\$1\$/ ? "{md5}" :
$_[0]->{'pass'} =~ /^[a-zA-Z0-9\.\/]{13}$/ ? "{crypt}" :
$config{'md5'} == 1 || $config{'md5'} == 3 ? "{md5}" :
$config{'md5'} == 4 ? "{ssha}" :
$config{'md5'} == 0 ? "{crypt}" : "";
local $pass = $_[0]->{'pass'};
local $disabled;
my ($user) = @_;
my $pfx = $user->{'pass'} =~ /^\{[a-z0-9]+\}/i ? undef :
$user->{'pass'} =~ /^\$1\$/ ? "{md5}" :
$user->{'pass'} =~ /^[a-zA-Z0-9\.\/]{13}$/ ? "{crypt}" :
$config{'md5'} == 1 || $config{'md5'} == 3 ? "{md5}" :
$config{'md5'} == 4 ? "{ssha}" :
$config{'md5'} == 0 ? "{crypt}" : "";
my $pass = $user->{'pass'};
my $disabled;
if ($pass =~ s/^\!//) {
$disabled = "!";
}
$cn = $_[0]->{'real'} eq '' ? $_[0]->{'user'} : $_[0]->{'real'};
my $cn = $user->{'real'} eq '' ? $user->{'user'} : $user->{'real'};
return ( "cn" => $cn,
"uid" => $_[0]->{'user'},
"uidNumber" => $_[0]->{'uid'},
"loginShell" => $_[0]->{'shell'},
"homeDirectory" => $_[0]->{'home'},
"gidNumber" => $_[0]->{'gid'},
"uid" => $user->{'user'},
"uidNumber" => $user->{'uid'},
"loginShell" => $user->{'shell'},
"homeDirectory" => $user->{'home'},
"gidNumber" => $user->{'gid'},
"userPassword" => $disabled.$pfx.$pass,
$_[0]->{'change'} eq '' ? ( ) :
( "shadowLastChange" => $_[0]->{'change'} ),
$_[0]->{'expire'} eq '' ? ( ) :
( "shadowExpire" => $_[0]->{'expire'} ),
$_[0]->{'min'} eq '' ? ( ) :
( "shadowMin" => $_[0]->{'min'} ),
$_[0]->{'max'} eq '' ? ( ) :
( "shadowMax" => $_[0]->{'max'} ),
$_[0]->{'warn'} eq '' ? ( ) :
( "shadowWarning" => $_[0]->{'warn'} ),
$_[0]->{'inactive'} eq '' ? ( ) :
( "shadowInactive" => $_[0]->{'inactive'} )
$user->{'change'} eq '' ? ( ) :
( "shadowLastChange" => $user->{'change'} ),
$user->{'expire'} eq '' ? ( ) :
( "shadowExpire" => $user->{'expire'} ),
$user->{'min'} eq '' ? ( ) :
( "shadowMin" => $user->{'min'} ),
$user->{'max'} eq '' ? ( ) :
( "shadowMax" => $user->{'max'} ),
$user->{'warn'} eq '' ? ( ) :
( "shadowWarning" => $user->{'warn'} ),
$user->{'inactive'} eq '' ? ( ) :
( "shadowInactive" => $user->{'inactive'} ),
$user->{'firstname'} eq '' ? ( ) :
( "givenName" => $user->{'firstname'} ),
$user->{'surname'} eq '' ? ( ) :
( "sn" => $user->{'surname'} ),
);
}
# group_to_dn(&group)
# Given a useradmin-style group hash, returns a list of properties
sub group_to_dn
{
local @members = split(/,/, $_[0]->{'members'});
return ( "cn" => $_[0]->{'group'},
"gidNumber" => $_[0]->{'gid'},
"userPassword" => $_[0]->{'pass'},
my ($group) = @_;
my @members = split(/,/, $group->{'members'});
return ( "cn" => $group->{'group'},
"gidNumber" => $group->{'gid'},
"userPassword" => $group->{'pass'},
@members ? ( "memberUid" => \@members ) : ( ),
defined($_[0]->{'desc'}) ? ( "description" => $_[0]->{'desc'} ) : ( ),
defined($group->{'desc'}) ? ( "description" => $group->{'desc'} ) : ( ),
);
}

View File

@@ -3,3 +3,4 @@ lines=100
others=1
reverse=1
log_any=0
compressed=1

View File

@@ -1,7 +1,8 @@
skip_index=Open log view on module load,1,1-Yes,0-No
skip_index=Open log view on module load?,1,1-Yes,0-No
lines=Default number of lines to display,0,6
compressed=Include compressed logs in searches?,1,1-Yes,0-No
refresh=Seconds between log view refreshes,3,Never
others=Show logs from other modules,1,1-Yes,0-No
others=Show logs from other modules?,1,1-Yes,0-No
extras=Extra log files to show,9,50,4,\t
reverse=Log display order,1,1-Newest lines at top,0-Newest lines at bottom
log_any=Can view any file as a log,1,1-Yes,0-No
log_any=Can view any file as a log?,1,1-Yes,0-No

View File

@@ -143,11 +143,9 @@ if (!@acols) {
}
# If we jump directly to logs just redirect
if ($config{'skip_index'} == 1) {
if ($lnks[0]) {
&redirect($lnks[0]);
exit;
}
if ($config{'skip_index'} == 1 && $lnks[0]) {
&redirect($lnks[0]);
return;
}
# Print the header

View File

@@ -251,5 +251,29 @@ sub config_post_save
&clear_systemctl_cache();
}
# catter_command(file)
# Given a file that may be compressed, returns the command to output it in
# plain text, or undef if impossible
sub catter_command
{
local ($l) = @_;
local $q = quotemeta($l);
if ($l =~ /\.gz$/i) {
return &has_command("gunzip") ? "gunzip -c $q" : undef;
}
elsif ($l =~ /\.Z$/i) {
return &has_command("uncompress") ? "uncompress -c $q" : undef;
}
elsif ($l =~ /\.bz2$/i) {
return &has_command("bunzip2") ? "bunzip2 -c $q" : undef;
}
elsif ($l =~ /\.xz$/i) {
return &has_command("xz") ? "xz -d -c $q" : undef;
}
else {
return "cat $q";
}
}
1;

0
logviewer/view_log_progress.cgi Normal file → Executable file
View File

View File

@@ -269,9 +269,9 @@ application/x-director dcr dir dxr
application/x-dvi dvi # DVI
application/x-futuresplash spl
application/x-gtar gtar
application/x-gzip gz tgz # Gzipped data
application/gzip gz tgz # Gzipped data
application/x-hdf hdf
application/x-javascript js # Javascript source
application/javascript js # Javascript source
application/x-koan skp skd skt skm
application/x-latex latex # LaTeX source
application/x-netcdf nc cdf

View File

@@ -4894,7 +4894,7 @@ my %vital = ("port", 80,
"listen_delay", 5,
"pam", "webmin",
"sidname", "sid",
"unauth", "^/unauthenticated/ ^/robots.txt\$ ^[A-Za-z0-9\\-/_]+\\.jar\$ ^[A-Za-z0-9\\-/_]+\\.class\$ ^[A-Za-z0-9\\-/_]+\\.gif\$ ^[A-Za-z0-9\\-/_]+\\.png\$ ^[A-Za-z0-9\\-/_]+\\.conf\$ ^[A-Za-z0-9\\-/_]+\\.ico\$ ^/robots.txt\$",
"unauth", "^/unauthenticated/ ^/robots.txt\$ ^[A-Za-z0-9\\-/_]+\\.jar\$ ^[A-Za-z0-9\\-/_]+\\.class\$ ^[A-Za-z0-9\\-/_]+\\.gif\$ ^[A-Za-z0-9\\-/_]+\\.png\$ ^[A-Za-z0-9\\-/_]+\\.conf\$ ^[A-Za-z0-9\\-/_]+\\.ico\$ ^/robots.txt\$ ^/service-worker.js\$",
"max_post", 10000,
"expires", 7*24*60*60,
"pam_test_user", "root",

View File

@@ -20,12 +20,10 @@ print &ui_tabs_start([ [ 'pkgs', $text{'index_tabpkgs'} ],
# See if any security updates exist
$in{'mode'} ||= 'updates';
@avail = &list_for_mode($in{'mode'}, 0);
($sec) = grep { $_->{'security'} } @avail;
# Show mode selector (all, updates only, updates and new)
@grid = ( );
foreach $m ('current', 'updates', 'new',
$sec || $in{'mode'} eq 'security' ? ( 'security' ) : ( )) {
foreach $m ('current', 'updates', 'security', 'new') {
$mmsg = $text{'index_mode_'.$m};
if ($in{'mode'} eq $m) {
push(@mlinks, "<b>$mmsg</b>");

View File

@@ -103,6 +103,7 @@ sched_yes=Scheduled checking for updates is now active.
sched_no=Scheduled checking for updates has been disabled.
log_update=Installed $1 updated packages
log_schedup=Background installed $1 updated packages
log_sched=Enabled scheduled updates
log_unsched=Disabled scheduled updates
log_refresh=Refreshed available packages

View File

@@ -18,6 +18,9 @@ elsif ($type eq 'repo') {
elsif ($action eq 'update') {
return &text('log_update', $object);
}
elsif ($action eq 'schedup') {
return &text('log_schedup', $object);
}
elsif ($action eq 'sched') {
return $text{$object ? 'log_sched' : 'log_unsched'};
}

View File

@@ -15,10 +15,10 @@ else {
$redir = "index.cgi?mode=".&urlize($in{'mode'}).
"&search=".&urlize($in{'search'});
$redirdesc = $text{'index_return'};
$redir = $redir =~ /tab=/ ? $redir :
$redir =~ /\?/ ? "$redir&tab=pkgs" : "$redir?tab=pkgs";
}
$redir = ($redir =~ /\?/) ? "$redir&tab=pkgs" : "$redir?tab=pkgs";
if ($in{'refresh'} || $in{'refresh_top'}) {
&ui_print_unbuffered_header(undef, $text{'refresh_title'}, "");

View File

@@ -17,19 +17,22 @@ if ($ARGV[0] eq "--debug" || $ARGV[0] eq "-debug") {
$tellcount = 0;
%already = ( );
&start_update_progress([ map { $_->{'name'} } @todo ]);
$icount = 0;
foreach $t (@todo) {
next if ($already{$t->{'update'}});
my $umsg = $t->{'security'} ? "security update" : "update";
if ($config{'sched_action'} == 2 ||
$config{'sched_action'} == 1 && $t->{'security'}) {
# Can install
$body .= "An update to $t->{'name'} from $t->{'oldversion'} to $t->{'version'} is needed.\n";
$body .= "An $umsg to $t->{'name'} from $t->{'oldversion'} to $t->{'version'} is needed.\n";
$icount++;
($out, $done) = &capture_function_output(
\&package_install, $t->{'update'});
if (@$done) {
$body .= "This update has been successfully installed.\n\n";
$body .= "This $umsg has been successfully installed.\n\n";
}
else {
$body .= "However, this update could not be installed! Try the update manually\nusing the Package Updates module.\n\n";
$body .= "However, this $usmg could not be installed! Try the update manually\nusing the Package Updates module.\n\n";
}
foreach $p (@$done) {
$already{$p}++;
@@ -39,7 +42,7 @@ foreach $t (@todo) {
$config{'sched_action'} == 0 ||
$config{'sched_action'} == -1 && $t->{'security'}) {
# Just tell the user about it
$body .= "An update to $t->{'name'} from $t->{'oldversion'} to $t->{'version'} is available.\n\n";
$body .= "An $umsg to $t->{'name'} from $t->{'oldversion'} to $t->{'version'} is available.\n\n";
$tellcount++;
}
}
@@ -69,3 +72,7 @@ if ($config{'sched_email'} && $body) {
}
}
# Log the update, if anything was installed
if ($icount) {
&webmin_log("schedup", "packages", $icount);
}

View File

@@ -16,5 +16,11 @@ print &ui_hidden("oneini", $in{'oneini'}),"\n";
print &ui_textarea("data", &read_file_contents_as_user($in{'file'}), 20, 80);
print &ui_form_end([ [ "save", $text{'save'} ] ]);
&ui_print_footer("", $text{'index_return'});
if ($in{'oneini'}) {
&ui_print_footer("list_ini.cgi?file=".&urlize($in{'file'}),
$text{'list_return'});
}
else {
&ui_print_footer("", $text{'index_return'});
}

View File

@@ -513,6 +513,14 @@ mail_rfc=From line
mail_move=Move to:
mail_eexists=Message no longer exists!
mail_qfile=Mail queue file
mail_qlast=Last retried at
mail_qdir=Mail queue status
mail_qdir_active=Active
mail_qdir_incoming=Incoming
mail_qdir_deferred=Deferred
mail_qdir_corrupt=Corrupt
mail_qdir_hold=On hold
mail_qdir_maildrop=Mail drop
view_title=Read Email
view_desc=Message $1 in $2
@@ -623,6 +631,7 @@ mailq_active=Active
mailq_deferred=Deferred
mailq_hold=Hold Selected
mailq_unhold=Un-Hold Selected
mailq_dir=Queue state
flushq_title=Flush Queue
flushq_desc=Forcing the attempted delivery of mail with the command $1 ..

View File

@@ -1449,6 +1449,15 @@ foreach my $l (split(/\r?\n/, $out)) {
$q->{'time'} = $t;
}
}
foreach my $dir (&list_mailq_directories()) {
my $f = substr($q->{'id'}, 0, 1);
my $path = "$config{'mailq_dir'}/$dir/$f/$q->{'id'}";
if (-r $path) {
$q->{'dir'} = $dir;
$q->{'file'} = $file;
last;
}
}
push(@qfiles, $q);
}
elsif ($l =~ /\((.*)\)/ && @qfiles) {
@@ -1461,18 +1470,18 @@ foreach my $l (split(/\r?\n/, $out)) {
return @qfiles;
}
sub list_mailq_directories
{
return ("active", "incoming", "deferred", "corrupt", "hold", "maildrop");
}
# parse_queue_file(id)
# Parses a postfix mail queue file into a standard mail structure
sub parse_queue_file
{
local @qfiles = ( &recurse_files("$config{'mailq_dir'}/active"),
&recurse_files("$config{'mailq_dir'}/incoming"),
&recurse_files("$config{'mailq_dir'}/deferred"),
&recurse_files("$config{'mailq_dir'}/corrupt"),
&recurse_files("$config{'mailq_dir'}/hold"),
&recurse_files("$config{'mailq_dir'}/maildrop"),
);
local $f = $_[0];
local ($f) = @_;
local @qfiles = map { &recurse_files("$config{'mailq_dir'}/$_") }
&list_mailq_directories();
local ($file) = grep { $_ =~ /\/$f$/ } @qfiles;
return undef if (!$file);
local $mode = 0;
@@ -1505,6 +1514,11 @@ foreach $h (@headers) {
$mail->{'header'}->{lc($h->[0])} = $h->[1];
}
$mail->{'file'} = $file;
my @st = stat($file);
$mail->{'last_retry'} = $st[9];
if ($file =~ /^\Q$config{'mailq_dir'}\E\/([^\/]+)\//) {
$mail->{'dir'} = $1;
}
return $mail;
}
@@ -1857,11 +1871,12 @@ foreach my $q (@$qfiles) {
'value' => $q->{'id'} });
push(@cols, &ui_link("view_mailq.cgi?id=$q->{'id'}",$q->{'id'}));
local $size = &nice_size($q->{'size'});
push(@cols, "<font size=1>$q->{'date'}</font>");
push(@cols, "<font size=1>".&html_escape($q->{'from'})."</font>");
push(@cols, "<font size=1>".&html_escape($q->{'to'})."</font>");
push(@cols, "<font size=1>$size</font>");
push(@cols, "<font size=1>".&html_escape($q->{'status'})."</font>");
push(@cols, $q->{'date'});
push(@cols, &html_escape($q->{'from'}));
push(@cols, &html_escape($q->{'to'}));
push(@cols, $size);
push(@cols, $text{'mailq_'.$q->{'dir'}} || $q->{'dir'});
push(@cols, &html_escape($q->{'status'}));
push(@table, \@cols);
}
@@ -1878,7 +1893,8 @@ print &ui_form_columns_table("delete_queues.cgi",
undef,
undef,
[ "", $text{'mailq_id'}, $text{'mailq_date'}, $text{'mailq_from'},
$text{'mailq_to'}, $text{'mailq_size'}, $text{'mailq_status'} ],
$text{'mailq_to'}, $text{'mailq_size'}, $text{'mailq_dir'},
$text{'mailq_status'} ],
100,
\@table);
}

View File

@@ -53,8 +53,10 @@ if ($in{'headers'}) {
print &ui_table_row($h->[0],
&html_escape(&decode_mimewords($h->[1])), 1, [ "nowrap" ]);
}
print &ui_table_row($text{'mail_qfile'},
"<tt>".&html_escape($mail->{'file'})."</tt>");
if ($mail->{'file'}) {
print &ui_table_row($text{'mail_qfile'},
"<tt>".&html_escape($mail->{'file'})."</tt>");
}
}
else {
# Just show the most useful headers
@@ -70,6 +72,14 @@ else {
print &ui_table_row($text{'mail_subject'},
&html_escape($mail->{'header'}->{'subject'}));
}
if ($mail->{'last_retry'}) {
print &ui_table_row($text{'mail_qlast'},
&make_date($mail->{'last_retry'}));
}
if ($mail->{'dir'}) {
print &ui_table_row($text{'mail_qdir'},
$text{'mailq_'.$mail->{'dir'}} || $mail->{'dir'});
}
print &ui_table_end();
# Find body attachment

View File

@@ -156,14 +156,14 @@ else {
close(OUTr); close(INw);
if ($_[1]) {
local @u = getpwuid($_[1]);
if (defined($_[2])) {
# switch to given UID and GID
&switch_to_unix_user(
[ undef, undef, $_[1], $_[2] ]);
[ $u[0], undef, $_[1], $_[2] ]);
}
else {
# switch to UID and all GIDs
local @u = getpwuid($_[1]);
&switch_to_unix_user(\@u);
}
}
@@ -286,8 +286,9 @@ if (!$@) {
close(STDIN); close(STDOUT); close(STDERR);
untie(*STDIN); untie(*STDOUT); untie(*STDERR);
if ($_[1]) {
&switch_to_unix_user([ undef, undef, $_[1], $_[2] ]);
if ($uid) {
my $username = getpwuid($uid);
&switch_to_unix_user([ $username, undef, $uid, $gid ]);
}
close($ptyfh); # Used by other side only
@@ -345,8 +346,9 @@ else {
close(STDIN); close(STDOUT); close(STDERR);
untie(*STDIN); untie(*STDOUT); untie(*STDERR);
#setpgrp(0, $$);
if ($_[1]) {
&switch_to_unix_user([ undef, undef, $_[1], $_[2] ]);
if ($uid) {
my $username = getpwuid($uid);
&switch_to_unix_user([ $username, undef, $uid, $gid ]);
}
open(STDIN, "<$tty");

View File

@@ -5,7 +5,7 @@
webmin_host="download.webmin.com"
webmin_download="https://$webmin_host"
webmin_download_nightly="https://builds.webmin.dev"
webmin_download_nightly="https://download.webmin.dev"
webmin_key="developers-key.asc"
webmin_key_download="$webmin_download/$webmin_key"
webmin_key_suffix="webmin-developers"

View File

@@ -12,10 +12,7 @@ my $err = sub {
print("<tt>Cannot change theme : $_[0]</tt>\n");
exit(1);
};
# Check if in debug mode
&$err("Debug mode is not enabled!")
if (!$gconfig{'debug_enabled'} &&
!$gconfig{'debug_theme_switcher'});
# Check if allowed to change theme,
# otherwise throw an error
if (!&foreign_available('theme') &&

View File

@@ -2349,11 +2349,45 @@ Hotkeys are:
sub ui_switch_theme_javascript
{
return &theme_ui_switch_theme_javascript(@_) if (defined(&theme_ui_switch_theme_javascript));
return "" if (!$gconfig{'debug_enabled'} && !$gconfig{'debug_theme_switcher'});
my $switch_script = "<script>const __webmin_webprefix__ = '@{[&get_webprefix()]}';</script>\n";
my $webmin_version = &get_webmin_version();
$webmin_version =~ s/\.//g;
$switch_script .= "<script type=\"text/javascript\" src=\"@{[&get_webprefix()]}/unauthenticated/switch_theme.js?$webmin_version\"></script>\n";
my $webprefix = &get_webprefix();
my $switch_script .= <<EOF;
<script type="text/javascript">
(function () {
let firstCombinationPressed = false;
document.addEventListener("keydown", function (event) {
// Check for Ctrl+Alt+T or Control+Option+T
if (event.ctrlKey && event.altKey && event.keyCode === 84) {
firstCombinationPressed = true;
// Set a timeout to reset the state after a short period (e.g., 1 seconds)
setTimeout(() => {
firstCombinationPressed = false;
}, 1000);
}
if (firstCombinationPressed && event.shiftKey &&
(event.keyCode === 65 ||
event.keyCode === 70 || event.keyCode === 71 ||
event.keyCode === 76)) {
const theme =
// Shift + A : Authentic theme
event.keyCode === 65 ? 1 :
// Shift + F / Shift + G : Framed theme / Gray theme
(event.keyCode === 70 || event.keyCode === 71) ? 2 :
// Shift + L : Legacy theme
event.keyCode === 76 ? 3 : null;
firstCombinationPressed = false;
try {
top.document.documentElement.style.filter = 'grayscale(100%) blur(0.5px) brightness(0.75) opacity(0.5)';
top.document.documentElement.style.cursor = 'wait';
top.document.documentElement.style.pointerEvents = 'none';
} catch (error) {}
top.location.href = "$webprefix/switch_theme.cgi?theme=" + theme + "";
}
});
})();
document.currentScript.remove();
</script>
EOF
return $switch_script;
}

View File

@@ -1,31 +0,0 @@
(function () {
let firstCombinationPressed = false;
document.addEventListener("keydown", function (event) {
// Check for Ctrl+Alt+T or Control+Option+T
if (event.ctrlKey && event.altKey && event.keyCode === 84) {
firstCombinationPressed = true;
// Set a timeout to reset the state after a short period (e.g., 1 seconds)
setTimeout(() => {
firstCombinationPressed = false;
}, 1000);
}
if (firstCombinationPressed && event.shiftKey &&
(event.keyCode === 65 || event.keyCode === 71 || event.keyCode === 76)) {
const theme =
// Shift + A : Authentic theme
event.keyCode === 65 ? 1 :
// Shift + G : Gray theme
event.keyCode === 71 ? 2 :
// Shift + L : Legacy theme.
event.keyCode === 76 ? 3 : null;
firstCombinationPressed = false;
try {
top.document.documentElement.style.filter = 'grayscale(100%) blur(0.5px) brightness(0.75) opacity(0.5)';
top.document.documentElement.style.cursor = 'wait';
top.document.documentElement.style.pointerEvents = 'none';
} catch (error) {}
top.location.href = __webmin_webprefix__ + "/switch_theme.cgi?theme=" + theme + "";
}
});
})();

View File

@@ -1 +1 @@
2.111
2.201

View File

@@ -58,7 +58,8 @@ return &software::missing_install_link(
# request_letsencrypt_cert(domain|&domains, webroot, [email], [keysize],
# [request-mode], [use-staging], [account-email],
# [reuse-key], [server-url, server-key, server-hmac],
# [key-type], [reuse-key],
# [server-url, server-key, server-hmac],
# [allow-subset])
# Attempt to request a cert using a generated key with the Let's Encrypt client
# command, and write it to the given path. Returns a status flag, and either

View File

@@ -54,8 +54,11 @@ else {
"VirtualHost", $conf)) {
my $sn = &apache::find_directive(
"ServerName", $virt->{'members'});
my @sa = &apache::find_directive(
"ServerAlias", $virt->{'members'});
my $match = 0;
if ($in{'webroot_mode'} == 0 && $sn eq $doms[0]) {
if ($in{'webroot_mode'} == 0 &&
&indexof($doms[0], $sn, @sa) >= 0) {
# Based on domain name
$match = 1;
}
@@ -63,7 +66,16 @@ else {
# Specifically selected domain
$match = 1;
}
if ($match) {
my @ports;
foreach my $w (@{$virt->{'words'}}) {
if ($w =~ /:(\d+)$/) {
push(@ports, $1);
}
else {
push(@ports, 80);
}
}
if ($match && &indexof(80, @ports) >= 0) {
# Get document root
$webroot = &apache::find_directive(
"DocumentRoot", $virt->{'members'}, 1);
@@ -90,7 +102,7 @@ else {
"<tt>".&html_escape($webroot)."</tt>"),"<p>\n";
my ($ok, $cert, $key, $chain) = &request_letsencrypt_cert(
\@doms, $webroot, undef, $size, $mode, $in{'staging'},
undef, 0, undef, undef, undef, $in{'subset'});
undef, undef, undef, undef, undef, undef, $in{'subset'});
if (!$ok) {
print &text('letsencrypt_failed', $cert),"<p>\n";
}
@@ -129,7 +141,8 @@ else {
&put_miniserv_config(\%miniserv);
&unlock_file($ENV{'MINISERV_CONFIG'});
&save_renewal_only(\@doms, $webroot, $mode);
&save_renewal_only(\@doms, $webroot, $mode,
$size, $in{'subset'});
&webmin_log("letsencrypt");
&restart_miniserv(1);

View File

@@ -234,7 +234,7 @@ my $str = "otpauth://totp/".$name."?secret=".$user->{'twofactor_id'};
my $url;
if (&can_generate_qr()) {
$url = "$gconfig{'webprefix'}/webmin/qr.cgi?".
"size=4&str=".&urlize($str);
"size=6&str=".&urlize($str);
}
else {
$url = "https://chart.googleapis.com/chart".

View File

@@ -2638,6 +2638,10 @@ $gconfig{'real_os_type'} = $osinfo{'real_os_type'};
$gconfig{'real_os_version'} = $osinfo{'real_os_version'};
$gconfig{'os_type'} = $osinfo{'os_type'};
$gconfig{'os_version'} = $osinfo{'os_version'};
foreach my $key ('os_eol_db', 'os_eol_expired',
'os_eol_expiring') {
delete($gconfig{$key});
}
&write_file("$config_directory/config", \%gconfig);
&unlock_file("$config_directory/config");
@@ -2869,7 +2873,7 @@ if (!$@) {
my $out;
Image::PNG::QRCode::qrpng(
text => $str,
scale => $size || 3,
scale => $size || 6,
out => \$out,
);
return ($out, "image/png");