mirror of
https://github.com/webmin/webmin.git
synced 2026-02-05 23:22:15 +00:00
Compare commits
40 Commits
dev/preser
...
2.200
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2751224d4d | ||
|
|
6fce9fa491 | ||
|
|
41fdb5dac2 | ||
|
|
4ffca4597c | ||
|
|
ecfc06d9c6 | ||
|
|
db55dde7ce | ||
|
|
c6edd4b97d | ||
|
|
8cd2dbae96 | ||
|
|
8676a3fb21 | ||
|
|
27339eb1bf | ||
|
|
e014926854 | ||
|
|
a721f60f9c | ||
|
|
46c76e13f9 | ||
|
|
f72058306b | ||
|
|
a15446d3b1 | ||
|
|
fc9ce7f3dd | ||
|
|
72cd50a054 | ||
|
|
e307fb4dcd | ||
|
|
d631929194 | ||
|
|
db9628e7eb | ||
|
|
2c04c04ce7 | ||
|
|
a5301245d3 | ||
|
|
165af690c7 | ||
|
|
29da8ea3d0 | ||
|
|
73b7e62f13 | ||
|
|
76141ce22f | ||
|
|
4b575b8168 | ||
|
|
2b28521297 | ||
|
|
be767951ca | ||
|
|
9960d6011f | ||
|
|
461bd30e2a | ||
|
|
2f88a4eefb | ||
|
|
c9f368d264 | ||
|
|
0e24e8ac61 | ||
|
|
1d0d25efac | ||
|
|
1c5d2d2bd7 | ||
|
|
927a2c32d8 | ||
|
|
4a3c6c4854 | ||
|
|
37beab77ba | ||
|
|
5f579e8ded |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,5 +1,29 @@
|
||||
## Changelog
|
||||
|
||||
#### 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 allow disabling the newly introduced enforcement of _sudo_-capable logins in the Terminal module
|
||||
* 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)
|
||||
* 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
|
||||
|
||||
|
||||
@@ -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-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, hosts and groups to file,3,Main configuration file
|
||||
line2=System configuration,11
|
||||
|
||||
@@ -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-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, hosts i grups al fitxer,3,Fitxer de configuració principal
|
||||
line2=Configuració del sistema,11
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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-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
|
||||
|
||||
@@ -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-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, Hosts und Gruppen in einer Datei hinzu,3,Haupt-Konfigurationsdatei
|
||||
line2=Systemkonfiguration,11
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>ドメイン-名</tt> オプション,0-名前またはメンバー数
|
||||
desc_name=名称の替わりにオブジェクトの説明を表示しますか?,1,1-はい,0-いいえ
|
||||
display_max=サブネットとホストの表示する最大数,3,無制限
|
||||
line2=システム設定,11
|
||||
dhcpd_conf=DHCPサーバ 設定ファイル,0
|
||||
|
||||
@@ -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-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, host en groepen aan file,3,Hoofd configuratie file
|
||||
line2=Systeem configuratie,11
|
||||
|
||||
@@ -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-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, verter og grupper i filen,3,Hoved konfigurasjonsfil
|
||||
line2=System konfigurasjon,11
|
||||
|
||||
@@ -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-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, hosty i grupy do pliku,3,Główny plik konfiguracyjny
|
||||
line2=Opcje systemowe,11
|
||||
|
||||
@@ -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-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, hosts e grupos para arquivo,3,Arquivo principal de configuração
|
||||
line2=Configuração do sistema,11
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'}}) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'} ) : ( ),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>");
|
||||
|
||||
@@ -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_sched=Background installed $1 updated packages
|
||||
log_sched=Enabled scheduled updates
|
||||
log_unsched=Disabled scheduled updates
|
||||
log_refresh=Refreshed available packages
|
||||
|
||||
@@ -18,6 +18,9 @@ elsif ($type eq 'repo') {
|
||||
elsif ($action eq 'update') {
|
||||
return &text('log_update', $object);
|
||||
}
|
||||
elsif ($action eq 'sched') {
|
||||
return &text('log_sched', $object);
|
||||
}
|
||||
elsif ($action eq 'sched') {
|
||||
return $text{$object ? 'log_sched' : 'log_unsched'};
|
||||
}
|
||||
|
||||
@@ -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'}, "");
|
||||
|
||||
|
||||
@@ -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("sched", "packages", $icount);
|
||||
}
|
||||
|
||||
@@ -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'});
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ..
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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') &&
|
||||
|
||||
44
ui-lib.pl
44
ui-lib.pl
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 + "";
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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".
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user