Compare commits

...

180 Commits

Author SHA1 Message Date
Ilia Ross
ff4e0ae386 Fix to split lines up
https://github.com/webmin/webmin/pull/2462#pullrequestreview-2797791341
2025-04-28 03:33:52 +03:00
Ilia Ross
19bfe18e0f Add ability to make authentication in two steps 2025-04-28 00:55:59 +03:00
Ilia Ross
b48f6d3406 Fix to drop obsolete code 2025-04-28 00:51:04 +03:00
Jamie Cameron
172c504abb Add check for in-use TLS keys 2025-04-27 11:23:54 -07:00
Jamie Cameron
b92d8d11d6 Make sure atd is running if needed
https://github.com/webmin/webmin/issues/2461
2025-04-27 09:52:43 -07:00
Jamie Cameron
d073280e80 Factor out check for atd init script 2025-04-27 09:44:53 -07:00
Jamie Cameron
ebf1138788 CGI to save TLS keys 2025-04-26 21:50:44 -07:00
Jamie Cameron
3706f7862b Certs can start with BEGIN PUBLIC KEY 2025-04-26 20:25:31 -07:00
Jamie Cameron
9bd96b6448 Rate limit before checking if the user exists 2025-04-26 14:44:37 -07:00
Jamie Cameron
7ff37cd12f Add a delay based on the number of tries 2025-04-26 14:42:18 -07:00
Ilia Ross
55fd013b35 Fix to remove pointless new line that looks bad 2025-04-26 21:40:00 +03:00
Ilia Ross
014f949fdb Fix language when logging 2025-04-26 21:38:04 +03:00
Ilia Ross
cb3bde5374 Fix to set email correctly when resetting password 2025-04-26 21:37:42 +03:00
Jamie Cameron
4fbc57350f Add logging for password resets 2025-04-26 10:04:43 -07:00
Jamie Cameron
924e7e8ff5 Remove useless variable 2025-04-26 08:49:49 -07:00
Jamie Cameron
cb7de4edec Remove duplicate variable 2025-04-26 08:32:28 -07:00
Jamie Cameron
f17be6a383 Always show option to download in the background immediately 2025-04-25 20:11:45 -07:00
Jamie Cameron
bcfb698ac6 Detect case where cache is somehow empty
https://github.com/webmin/webmin/issues/2460
2025-04-25 19:50:25 -07:00
Jamie Cameron
8bd079f52f Merge branch 'master' of github.com:webmin/webmin 2025-04-25 16:51:05 -07:00
Jamie Cameron
cef76798f8 clean/reset environment will preserve variables 2025-04-25 16:50:58 -07:00
Ilia Ross
4f046c1d6d Fix to quote escape labels 2025-04-25 23:58:06 +03:00
Ilia Ross
cc83641c11 Add ability for themes to handle each "forgot_*" page 2025-04-25 20:01:30 +03:00
Ilia Ross
971c526ade Fix to lower the static delay for now 2025-04-25 11:39:27 +03:00
Jamie Cameron
717f0b1100 Work on form to edit a TLS key 2025-04-24 21:39:47 -07:00
Jamie Cameron
6ff0e50e94 Merge branch 'master' of github.com:webmin/webmin 2025-04-24 21:12:13 -07:00
Jamie Cameron
0de1844755 Work on DNS over TLS 2025-04-24 21:07:03 -07:00
Ilia Ross
e55f3bdb74 Add ability for the theme to construct own forgot link 2025-04-25 00:49:39 +03:00
Ilia Ross
25d2edeeaf Add a cooldown period for password reset request rates 2025-04-24 21:06:43 +03:00
Ilia Ross
201d817e9d Fix to preserve ACL even for modules with noacl flag
What matters now is that the module gets removed from ACLs, and the new module config page (that didn't exist before) stops working. So the simplest and best solution is to keep the module visible normally, but skip editable ACLs—since the plugin is meant to be controlled by Virtualmin permissions, and access to its config should always be allowed.

https://github.com/webmin/webmin/pull/2426/files#r1972474077
2025-04-24 11:25:03 +03:00
Ilia Ross
b2626ca9c1 Fix to default to useradmin module even for anon user 2025-04-24 10:24:17 +03:00
Ilia Ross
0553cae4e3 Fix to avoid printing switch theme code unless authed 2025-04-24 10:23:14 +03:00
Jamie Cameron
740368fc0d Use correct password hashing function 2025-04-23 20:58:48 -07:00
Jamie Cameron
7c932d3cb0 No need to create extra variables 2025-04-23 20:56:21 -07:00
Jamie Cameron
b46043de84 Check for the d variable properly 2025-04-23 20:51:59 -07:00
Ilia Ross
69e3844cec Fix critical issues when resetting the password
1. If changing password in `/etc/shadow` clone user correctly
 2. Restart miniserv after changing password in `/etc/shadow`
 3. Use correct hashing format when changing Webmin and Unix password
2025-04-23 15:18:09 +03:00
Ilia Ross
215b1332fc Fix to check if domain hash isn't empty 2025-04-23 14:15:56 +03:00
Jamie Cameron
bb8b926d52 Properly declare $d 2025-04-22 22:01:21 -07:00
Ilia Ross
967d519943 Fix to replace the table with much simpler and better layout 2025-04-22 22:25:38 +03:00
Ilia Ross
c84ef98016 Fix default mode to be login and password 2025-04-22 15:27:34 +03:00
Ilia Ross
fd153b28f3 Add improvements to the UI 2025-04-22 15:26:41 +03:00
Ilia Ross
7a3210849d Fix default system type config option to show label correctly 2025-04-22 13:45:52 +03:00
Ilia Ross
fb8339a3ca Fix to always default to fast mode
https://github.com/webmin/webmin/issues/2458#issuecomment-2818513756
2025-04-22 13:40:54 +03:00
Jamie Cameron
e0b6ae7691 Obsfucate email for display 2025-04-21 22:04:03 -07:00
Jamie Cameron
3f5ae24beb Ask for password twice 2025-04-21 19:56:20 -07:00
Jamie Cameron
8cd74c1c35 Don't show Virtualmin output when resetting a password 2025-04-21 16:55:35 -07:00
Jamie Cameron
e983ded21e Include forgotten password pages in package 2025-04-21 16:51:51 -07:00
Ilia Ross
0037d9a9ca Fix to use fast PRC mode by default 2025-04-21 16:28:38 +03:00
Jamie Cameron
a49b5fc0cb Sure as hell nobody is running BIND 8 anymore 2025-04-20 21:20:12 -07:00
Jamie Cameron
e87fc560c9 Move random flag check into a function 2025-04-20 21:15:49 -07:00
Jamie Cameron
ac21e39a88 Use standard functions for version checks 2025-04-20 20:50:51 -07:00
Jamie Cameron
d070176535 Cleanup and reformat code 2025-04-20 20:35:22 -07:00
Jamie Cameron
4c60aa1865 Include username is email subject 2025-04-20 11:15:17 -07:00
Jamie Cameron
590a3218be Cleanup old forgotten password reset key 2025-04-20 11:14:05 -07:00
Jamie Cameron
cf50dd2431 Start of work on password reset rate limiting 2025-04-20 10:54:39 -07:00
Jamie Cameron
a04646e785 Cannot reset password if you're logged in 2025-04-20 10:30:14 -07:00
Jamie Cameron
5d2debca26 Code cleanups 2025-04-20 10:24:07 -07:00
Jamie Cameron
79e5d72393 Cleanup forgotten password link files older than 1 day 2025-04-20 10:21:25 -07:00
Jamie Cameron
410d240e8b What if WEBMIN_VAR isn't set 2025-04-20 10:18:36 -07:00
Jamie Cameron
c074e150f6 Merge branch 'master' of github.com:webmin/webmin 2025-04-20 10:00:55 -07:00
Jamie Cameron
2916f5b723 Define the forgot password dir in init_config 2025-04-20 10:00:47 -07:00
Jamie Cameron
167e8f2b1f support unix user password changes 2025-04-18 22:01:56 -07:00
Ilia Ross
f71c413b6d Fix to allow proxy links to open as they are if the referrer is trusted 2025-04-19 00:31:42 +03:00
Jamie Cameron
a664809bf4 Implement forgotted password reset for Virtualmin users 2025-04-17 22:11:39 -07:00
Jamie Cameron
d8513dbd9e Fix case where error is not called in a module 2025-04-17 22:08:53 -07:00
Jamie Cameron
268b72917d CGI to un-install PHP versions 2025-04-17 21:52:25 -07:00
Jamie Cameron
4082701c48 Version detection fixes 2025-04-17 21:48:05 -07:00
Jamie Cameron
4018977aeb Code and variable scope cleanups
https://github.com/webmin/webmin/issues/2458
2025-04-17 14:15:50 -07:00
Jamie Cameron
ff0da2ca90 Code cleanups
https://github.com/webmin/webmin/issues/2458
2025-04-17 14:05:40 -07:00
Jamie Cameron
badb5b60f7 Merge branch 'master' of github.com:webmin/webmin 2025-04-17 07:39:22 -07:00
Jamie Cameron
a9652f4c88 Minor version bump 2025-04-17 07:39:12 -07:00
Ilia Ross
2febc12586 Merge pull request #2456 from MacSteini/master
Update de
2025-04-16 15:27:03 +03:00
MacSteini
625fff0c6f Update de 2025-04-16 11:32:22 +01:00
Jamie Cameron
ea973b571b Fix password change for regular webmin users 2025-04-15 21:23:10 -07:00
Jamie Cameron
ba6da02850 Don't show module index link if not in a module 2025-04-15 21:19:59 -07:00
Jamie Cameron
f15b147bd0 No need to check for the same condition twice 2025-04-15 21:16:49 -07:00
Jamie Cameron
4b927ed588 Avoid duplicating the error message 2025-04-15 21:14:06 -07:00
Jamie Cameron
8894ca18cf Merge branch 'master' of github.com:webmin/webmin 2025-04-15 19:05:19 -07:00
Jamie Cameron
d9dbcd9746 More work on forgotten password support 2025-04-14 22:44:55 -07:00
Ilia Ross
00ad7fec7a Fix broken Hungarian translations #2455 2025-04-15 01:04:50 +03:00
Jamie Cameron
f76451975c Fix allow-update check
https://forum.virtualmin.com/t/virtualmin-dns-fails-to-detect-rndc-freeze-is-needed/132653
2025-04-12 21:42:41 -07:00
Jamie Cameron
315664a1e1 Merge branch 'master' of github.com:webmin/webmin 2025-04-12 11:00:36 -07:00
Jamie Cameron
18a4c86e2f Work on forgotten password page 2025-04-12 11:00:30 -07:00
Ilia Ross
f65625047b Fix to convert entities to ASCII before printing to logs 2025-04-12 18:26:26 +03:00
Ilia Ross
8d0f19f64d Fix to simplify error print 2025-04-12 18:25:18 +03:00
Jamie Cameron
a768e731cf Allow anonymous access to the forgotten password CGIs 2025-04-11 22:25:17 -07:00
Jamie Cameron
535accda63 Merge branch 'master' of github.com:webmin/webmin 2025-04-11 22:12:18 -07:00
Jamie Cameron
a6c3cccbac Code cleanups 2025-04-11 22:11:59 -07:00
Ilia Ross
d2d16608dc Fix to filter out potentially dangerous characters
https://github.com/webmin/webmin/issues/1838#issuecomment-2795296531
2025-04-11 14:12:33 +03:00
Ilia Ross
196e3ed6c4 Fix to drop trailing dot to align 2025-04-11 12:43:35 +03:00
Jamie Cameron
acdc65c5d7 Code cleanups 2025-04-10 21:39:48 -07:00
Jamie Cameron
dffdd66fb4 UI to enable forgotten password recovery 2025-04-10 21:37:54 -07:00
Jamie Cameron
f6fc4490db Clean up code and check for existing flag before checking variables 2025-04-10 21:32:52 -07:00
Jamie Cameron
73a882b7a0 Merge branch 'master' of github.com:webmin/webmin 2025-04-10 21:29:30 -07:00
Jamie Cameron
5de2d599a2 Delete webmin module from debian package properly 2025-04-10 21:28:08 -07:00
Ilia Ross
cf2806edac Fix to check if local version of mysqldump supports --set-gtid-purged flag
https://forum.virtualmin.com/t/schedule-backup-database-remote-mysql-error/132874/25?u=ilia
2025-04-10 19:36:01 +03:00
Jamie Cameron
0bf83ea2a8 Merge pull request #2447 from webmin/dev/fix-ssl-scheduled-renewals-for-webmin
Fix to respect option to copy new key and certificate to Webmin
2025-04-09 21:32:41 -07:00
Ilia Ross
544db4b1a9 Merge pull request #2451 from MacSteini/master
Update de
2025-04-09 11:43:28 +03:00
MacSteini
f7e4b57c42 Update de 2025-04-09 09:41:47 +01:00
MacSteini
9e9fc9bc87 Update de 2025-04-09 08:40:45 +01:00
MacSteini
23dff016cd Update de 2025-04-09 08:36:45 +01:00
Jamie Cameron
c191caf04b Add a Webmin user field for email address 2025-04-08 20:58:28 -07:00
Jamie Cameron
05f4b8ff96 log package deletion 2025-04-08 20:19:24 -07:00
Jamie Cameron
f30275b49e Merge branch 'master' of github.com:webmin/webmin 2025-04-08 20:13:05 -07:00
Jamie Cameron
3e1b07f823 Add UI for deleting packages and modules 2025-04-08 20:12:38 -07:00
Jamie Cameron
49990e5949 Merge pull request #2450 from MacSteini/master
Update de
2025-04-08 18:36:35 -07:00
MacSteini
434d46643b Update de 2025-04-09 01:16:04 +01:00
MacSteini
33ed262ff0 Merge branch 'webmin:master' into master 2025-04-09 01:11:14 +01:00
Ilia Ross
0bc1dae232 Fix no use logic 2025-04-08 12:12:07 +03:00
Ilia Ross
2760336b40 Fix to use a different type of double-negation logic
https://github.com/webmin/webmin/pull/2447#discussion_r2030265612
2025-04-07 16:42:48 +03:00
Jamie Cameron
18bd46fe93 Work on support for removing packages 2025-04-06 18:58:58 -07:00
Jamie Cameron
fde1b02880 Factor out function to get domains list 2025-04-06 17:21:16 -07:00
Jamie Cameron
f94dabb88c Add form to install a new PHP package 2025-04-06 12:38:12 -07:00
Jamie Cameron
9e9d674206 Show version used by Virtualmin as well 2025-04-06 11:42:03 -07:00
Jamie Cameron
bd5c0bfa54 No need to show domains column if virtualmin isn't installed 2025-04-06 11:33:49 -07:00
Jamie Cameron
b1fdf42530 Don't set a flag that's already set
https://forum.virtualmin.com/t/schedule-backup-database-remote-mysql-error/132874/10
2025-04-03 21:55:59 -07:00
Ilia Ross
f2cba6af00 Fix to respect option to copy new key and certificate to Webmin
https://forum.virtualmin.com/t/letsencrypt-automatic-certificate-advice/132891/3?u=ilia
2025-04-03 16:51:45 +03:00
Jamie Cameron
e5beb7f022 Merge branch 'master' of github.com:webmin/webmin 2025-04-01 22:25:13 -07:00
Jamie Cameron
99f6638194 Coe style cleaups 2025-04-01 22:25:09 -07:00
Jamie Cameron
aa55e33b7e Work on page to show PHP versions 2025-04-01 22:24:33 -07:00
Ilia Ross
b3f28ee4f7 Fix to use new API for remote QR code generation
https://forum.virtualmin.com/t/two-factor-authenticator-is-missing-google-option/132766/14?u=ilia
2025-04-01 14:49:22 +03:00
MacSteini
2ce1157190 Update de 2025-04-01 10:27:58 +01:00
Ilia Ross
d40dbe391e Update translations 2025-03-31 15:42:27 +03:00
Ilia Ross
0fc1bea55e Update TOTP help page 2025-03-31 15:41:48 +03:00
Ilia Ross
225d113d38 Fix not to switch to remote user in case of admin login 2025-03-30 15:43:46 +03:00
Jamie Cameron
663640d801 Merge pull request #2445 from webmin/dev/fix-listing-mysql-auth-plugins
Fix to dynamically list auth plugins in MySQL/MariaDB
2025-03-29 22:07:05 -05:00
Ilia Ross
8bc5ba7a32 Fix to correctly display hashed passwords in UI 2025-03-29 22:19:44 +02:00
Ilia Ross
a10de5a9dc Fix updating unix_socket plugin in default mode 2025-03-29 21:05:37 +02:00
Ilia Ross
a67e327627 Fix to dynamically list auth plugins in MySQL/MariaDB 2025-03-29 16:25:42 +02:00
Ilia Ross
99889c1f30 Fix to use prepared statement instead when getting account lock status 2025-03-29 16:00:30 +02:00
Ilia Ross
42b8f2c25c Add support for account locking in MariaDB 2025-03-29 15:53:37 +02:00
Ilia Ross
6905548fa4 Fix to correctly set the password with auth plugin
https://forum.virtualmin.com/t/maria-db-failed-to-save-user/132794/4
2025-03-29 15:19:34 +02:00
Jamie Cameron
4ae5ec1694 Fix links to edit pages with non-original zone types
https://github.com/webmin/webmin/issues/2443
2025-03-27 07:22:54 -07:00
Jamie Cameron
f3a841d2b9 Merge branch 'master' of github.com:webmin/webmin 2025-03-23 10:42:53 -07:00
Jamie Cameron
2aee714a81 Handle case where two interfaces are modified
https://github.com/webmin/webmin/issues/1546
2025-03-23 10:42:45 -07:00
Ilia Ross
16fec003dc Fix to use shell command with direct file writing for EOL data file 2025-03-23 15:44:36 +02:00
Ilia Ross
fdbf960a2c Fix to use dmesg -T for Linux systems #2442 2025-03-23 03:07:50 +02:00
Ilia Ross
e8b2b21bce Fix to stop rebuilding on release edit
[no-build]
2025-03-22 18:56:44 +02:00
Ilia Ross
1f07fdb274 Fix to prefer JSON::XS over JSON::PP if available for better performance 2025-03-21 16:55:32 +02:00
Ilia Ross
7b85a75a2b Fix not to add ? unless there is a query
[no-build]
2025-03-21 12:54:08 +02:00
Ilia Ross
2185f2068d Update pod
[no-build]
2025-03-21 12:53:05 +02:00
Jamie Cameron
e60be7133b Add support for template variables to help pages 2025-03-20 20:02:47 -07:00
Jamie Cameron
4021b6d8bb Merge branch 'master' of github.com:webmin/webmin 2025-03-20 15:08:23 -07:00
Jamie Cameron
5a777e9395 Dynamic updates may also be enabled globally
https://forum.virtualmin.com/t/virtualmin-dns-fails-to-detect-rndc-freeze-is-needed/132653
2025-03-20 14:55:54 -07:00
Ilia Ross
51e2ebec70 Merge pull request #2441 from MacSteini/master
Update de
2025-03-20 14:12:43 +02:00
MacSteini
afe100d9f0 Update de 2025-03-20 11:26:56 +00:00
Jamie Cameron
eca9472980 Merge pull request #2437 from webmin/dev/fix-dovecot-listen
Add support to configure listen for any type of address
2025-03-19 18:53:53 -07:00
Ilia Ross
62c02d1273 Add TOML as editable by default #2438 2025-03-20 03:23:33 +02:00
Ilia Ross
d74e7e66c5 Fix to simplify regex check 2025-03-19 13:31:37 +02:00
Jamie Cameron
7250c44648 We can use the -cgi binary as a fallback 2025-03-18 21:58:22 -07:00
Jamie Cameron
31c7e63407 Show the PHP binary and version 2025-03-18 21:56:30 -07:00
Ilia Ross
264ecae147 Fix regex to match more accurately 2025-03-19 02:15:55 +02:00
Ilia Ross
6dd8915808 Fix to simplify check 2025-03-19 02:13:25 +02:00
Ilia Ross
48602503cd Add support to configure listen for any type of address
https://github.com/webmin/webmin/issues/2436
2025-03-18 14:04:38 +02:00
Jamie Cameron
13acaeece7 Stop creating a changelog that is no longer used 2025-03-17 15:49:07 -07:00
Jamie Cameron
bb787e4e1c Merge branch 'master' of github.com:webmin/webmin 2025-03-17 15:15:41 -07:00
Jamie Cameron
d4fab15024 No need to switch users if we already switched 2025-03-17 15:15:36 -07:00
Joe Cooper
1cb53ff00a Merge pull request #2435 from swelljoe/fix-makemoduledeb
We don't have to build debs on Debian
2025-03-16 18:43:50 -05:00
Joe Cooper
8043aabf18 We don't have to build debs on Debian 2025-03-16 18:43:04 -05:00
Ilia Ross
3a94ea3788 Update translations 2025-03-15 21:52:41 +02:00
Jamie Cameron
2183088706 Merge branch 'master' of github.com:webmin/webmin 2025-03-15 09:59:08 -07:00
Jamie Cameron
3736f26a84 Handle case where --to-destination is followed by a bare IPv6 address
https://github.com/webmin/webmin/issues/2434
2025-03-15 09:58:46 -07:00
Ilia Ross
f2307ae1fa Fix to stop using MD5 module that was deprecated 2025-03-14 14:42:49 +02:00
Jamie Cameron
45ef8d11c1 Merge branch 'master' of github.com:webmin/webmin 2025-03-13 17:13:44 -07:00
Jamie Cameron
b17df99700 Check the UID that is used for file operations 2025-03-13 17:13:37 -07:00
Ilia Ross
a3f2e64315 Update date 2025-03-14 00:29:51 +02:00
Ilia Ross
853bde5e1a Update CHANGELOG.md 2025-03-14 00:24:23 +02:00
Ilia Ross
083f9b09a2 Ensure li tags are always closed 2025-03-14 00:10:12 +02:00
Jamie Cameron
81e8fc6c37 Merge branch 'master' of github.com:webmin/webmin 2025-03-12 21:39:35 -07:00
Jamie Cameron
b9d2910d60 Run the man command as nobody, to prevent misuse of the section param 2025-03-12 21:38:04 -07:00
Ilia Ross
574f66c251 Merge pull request #2433 from MacSteini/master
Update de
2025-03-12 18:24:45 +02:00
MacSteini
56a231e78d Update de 2025-03-12 11:44:43 +00:00
Ilia Ross
85e7f6c292 Fix to filter out scope identifier
* We could support it but it would be much more work
2025-03-10 13:32:39 +02:00
Ilia Ross
9fa35cc2c9 Fix to save IPv6 nameservers 2025-03-10 13:31:32 +02:00
Jamie Cameron
23cb74fa35 Add function to show warnings in records 2025-03-09 16:34:14 -07:00
Jamie Cameron
e1d87fac1c Some sendmail hash files end with .cdb
https://forum.virtualmin.com/t/issues-editing-sendmail-8-18-1-on-webmin-2-302/132460/7
2025-03-07 17:21:25 -08:00
Jamie Cameron
9ba9bfd524 Merge branch 'master' of github.com:webmin/webmin 2025-03-06 19:03:47 -08:00
Jamie Cameron
6c5c5fa225 No need for modprobe since IPv6 is always in the kernel these days
https://github.com/webmin/webmin/issues/2432
2025-03-06 18:51:14 -08:00
Ilia Ross
495a196b2f Fix type when adding addr 2025-03-06 14:22:49 +02:00
Jamie Cameron
50eb61b89e Use the ip command instead of ifconfig 2025-03-05 20:56:42 -08:00
Jamie Cameron
3cb358fe9e Preserve ordering in module.info files 2025-03-05 11:23:09 -08:00
160 changed files with 2003 additions and 743 deletions

View File

@@ -7,7 +7,6 @@ on:
release:
types:
- published
- edited
jobs:
build:

View File

@@ -1,5 +1,13 @@
## Changelog
#### 2.303 (March 14, 2025)
* Fix permissions error when attempting to open a temp file for writing
* Fix Network Configuration module to use `ip` command instead of `ifconfig` on Debian systems
* Fix to correctly save IPv6 nameservers in Network Configuration module
* Fix to run `man` as `nobody` to prevent section param misuse in System Documentation module
* Add support for Sendmail hash files ending with `.cdb`
* Update German translations
#### 2.302 (March 3, 2025)
* Add ability to preserve allow/deny IPs in Webmin Configuration module #2427
* Add enhancements to module config saving to ensure reliability under all conditions

File diff suppressed because one or more lines are too long

View File

@@ -104,6 +104,7 @@ while(my $l = <$fh>) {
[ split(/\s+/, $gconfig{"ownmods_$user[0]"} || "") ];
$user{'logouttime'} = $logout{$user[0]};
$user{'real'} = $gconfig{"realname_$user[0]"};
$user{'email'} = $user[14];
push(@rv, \%user);
}
}
@@ -482,7 +483,8 @@ else {
($user->{'temppass'} || ""),":",
($user->{'twofactor_provider'} || ""),":",
($user->{'twofactor_id'} || ""),":",
($user->{'twofactor_apikey'} || ""),
($user->{'twofactor_apikey'} || ""),":",
($user->{'email'} || ""),
"\n");
&close_tempfile($fh);
&unlock_file($miniserv{'userfile'});
@@ -672,7 +674,8 @@ else {
$user->{'temppass'},":",
$user->{'twofactor_provider'},":",
$user->{'twofactor_id'},":",
$user->{'twofactor_apikey'},
$user->{'twofactor_apikey'},":",
$user->{'email'},
"\n");
}
else {
@@ -1714,7 +1717,7 @@ elsif ($mode == 2) {
}
else {
# Try detecting system default first
if (&foreign_available('useradmin')) {
if (&foreign_installed('useradmin')) {
&foreign_require('useradmin');
return &useradmin::encrypt_password($pass, $salt, 1);
}

View File

@@ -159,6 +159,10 @@ print &ui_table_row($text{'edit_pass'},
print &ui_table_row($text{'edit_real'},
&ui_textbox("real", $user{'real'}, 60));
# Contact email for recovery
print &ui_table_row($text{'edit_email'},
&ui_textbox("email", $user{'email'}, 60));
# Storage type
if ($in{'user'}) {
print &ui_table_row($text{'edit_proto'},
@@ -392,7 +396,6 @@ foreach my $c (sort { $b cmp $a } @cats) {
my @grid = ( );
my $sw = 0;
foreach my $m (@cmlist) {
next if ($m->{'noacl'});
my $md = $m->{'dir'};
my $fromgroup = $memg &&
&indexof($md, @{$memg->{'modules'}}) >= 0;
@@ -405,7 +408,7 @@ foreach my $c (sort { $b cmp $a } @cats) {
elsif ($mcan{$md}) {
my $label;
if ($access{'acl'} && $in{'user'} && !$safe &&
&can_module_acl($m)) {
&can_module_acl($m) && !$m->{'noacl'}) {
# Show link for editing ACL
$label = ui_link("edit_acl.cgi?" .
"mod=" . urlize($m->{'dir'}) .

View File

@@ -280,16 +280,18 @@ print &ui_links_row(\@rowlinks);
}
# user_link(user, cgi, param)
# Return HTML for a link to edit one user
sub user_link
{
my $lck = $_[0]->{'pass'} =~ /^\!/ ? 1 : 0;
my $ro = $_[0]->{'readonly'};
return &ui_checkbox("d", $_[0]->{'name'}, "", 0).
my ($user, $cgi, $param) = @_;
my $lck = $user->{'pass'} =~ /^\!/ ? 1 : 0;
my $ro = $user->{'readonly'};
return &ui_checkbox("d", $user->{'name'}, "", 0).
($lck ? "<i>" : "").
($ro ? "<b>" : "").
ui_link("$_[1]?$_[2]=".&urlize($_[0]->{'name'}),
$_[0]->{'name'}).
($_[0]->{'twofactor_id'} ? "*" : "").
&ui_link("$cgi?$param=".&urlize($user->{'name'}),
$user->{'name'}).
($user->{'twofactor_id'} ? "*" : "").
($ro ? "</b>" : "").
($lck ? "</i>" : "");
}

View File

@@ -36,6 +36,7 @@ edit_rights=Zugriffsrechte für Webmin-Benutzer
edit_user=Benutzername
edit_cloneof=Webmin-Benutzer klonen
edit_real=Echter Name
edit_email=E-Mail-Adresse
edit_group=Mitglied der Gruppe
edit_pass=Passwort
edit_same=Gleich wie Unix
@@ -148,6 +149,7 @@ save_edays=Keine Tage ausgewählt
save_ehours=Fehlende oder ungültige Zeiten
save_ehours2=Startzeit muss vor Endzeit liegen
save_etemp=Die Option, das Passwort beim nächsten Login zu ändern, kann nur verwendet werden, wenn <a href='$1'>Benutzer aufgefordert werden, neue Passwörter einzugeben</a> aktiviert ist
save_eemail=Die E-Mail-Adresse darf das Zeichen ":" nicht enthalten
delete_err=Fehler beim Löschen des Benutzers
delete_eself=Sie können sich nicht selbst löschen

View File

@@ -36,6 +36,7 @@ edit_rights=Webmin user access rights
edit_user=Username
edit_cloneof=Cloning Webmin user
edit_real=Real name
edit_email=Contact email
edit_group=Member of group
edit_pass=Password
edit_same=Same as Unix
@@ -148,6 +149,7 @@ save_edays=No days to allow selected
save_ehours=Missing or invalid times to allow
save_ehours2=Start time to allow must be before end
save_etemp=The option to force a password change at next login cannot be used unless <a href='$1'>prompting users to enter new passwords</a> is enabled
save_eemail=Email address cannot contain the : character
delete_err=Failed to delete user
delete_eself=You cannot delete yourself
@@ -247,6 +249,8 @@ log_sync=Changed unix user synchronization
log_sql=Changed user and group database
log_twofactor=Enrolled user $1 with two-factor provider $2
log_onefactor=Dis-enrolled user $1 for two-factor authentication
log_forgot_send=Sent password reset email for user $1 to $2
log_forgot_reset=Reset password for user $1 with email $2
gedit_ecannot=You are not allowed to edit groups
gedit_title=Edit Webmin Group

View File

@@ -62,6 +62,10 @@ elsif ($action eq 'switch') {
elsif ($action eq 'twofactor') {
return &text('log_twofactor', $object, $p->{'provider'}, $p->{'id'});
}
elsif ($action eq 'forgot') {
return &text('log_forgot_'.$type, &html_escape($p->{'user'}),
&html_escape($p->{'email'}));
}
else {
return $text{'log_'.$action};
}

View File

@@ -225,6 +225,8 @@ $user{'nochange'} = !$access{'nochange'} || !defined($in{'nochange'}) ?
$user{'lastchange'} = $old->{'lastchange'};
$user{'olds'} = $old->{'olds'};
$user{'real'} = $in{'real'} =~ /\S/ ? $in{'real'} : undef;
$in{'email'} =~ /:/ && &error($text{'save_eemail'});
$user{'email'} = $in{'email'};
my $raddr = $ENV{'REMOTE_ADDR'};
my @ips;
if ($access{'ips'}) {

View File

@@ -153,5 +153,18 @@ else {
}
}
# get_init_status()
# If the init module is installed and there is an atd bootup action, return
# its name, current running status and boot status
sub get_init_status
{
return () if (!&foreign_available("init"));
my $init = defined(&get_init_name) ? &get_init_name() : undef;
return () if (!$init);
my $r = &init::status_action($init);
my $atboot = &init::action_status($init);
return ($init, $r, $atboot);
}
1;

View File

@@ -138,34 +138,31 @@ if ($access{'allow'} && $config{'allow_file'}) {
}
# If there is an init script that runs an atd server, show status
if (&foreign_available("init")) {
&foreign_require("init");
my $init = defined(&get_init_name) ? &get_init_name() : undef;
if ($access{'stop'} && $init) {
print &ui_hr();
print &ui_buttons_start();
my ($init, $r, $atboot) = &get_init_status();
if ($access{'stop'} && $init) {
print &ui_hr();
print &ui_buttons_start();
# Running now?
my $r = &init::status_action($init);
if ($r == 1) {
print &ui_buttons_row("stop.cgi", $text{'index_stop'},
$text{'index_stopdesc'});
}
elsif ($r == 0) {
print &ui_buttons_row("start.cgi", $text{'index_start'},
$text{'index_startdesc'});
}
# Start at boot?
my $atboot = &init::action_status($init);
print &ui_buttons_row("bootup.cgi", $text{'index_boot'},
$text{'index_bootdesc'}, undef,
&ui_radio("boot", $atboot == 2 ? 1 : 0,
[ [ 1, $text{'yes'} ],
[ 0, $text{'no'} ] ]));
print &ui_buttons_end();
# Running now?
my $r = &init::status_action($init);
if ($r == 1) {
print &ui_buttons_row("stop.cgi", $text{'index_stop'},
$text{'index_stopdesc'});
}
elsif ($r == 0) {
print &ui_buttons_row("start.cgi", $text{'index_start'},
$text{'index_startdesc'});
}
# Start at boot?
my $atboot = &init::action_status($init);
print &ui_buttons_row("bootup.cgi", $text{'index_boot'},
$text{'index_bootdesc'}, undef,
&ui_radio("boot", $atboot == 2 ? 1 : 0,
[ [ 1, $text{'yes'} ],
[ 0, $text{'no'} ] ]));
print &ui_buttons_end();
}
&ui_print_footer("/", $text{'index'});

View File

@@ -63,16 +63,21 @@ if ($bind_version && $bind_version =~ /^(\d+\.\d+)\./) {
our $dnssec_dlv_zone = "dlv.isc.org.";
our @dnssec_dlv_key = ( 257, 3, 5, '"BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URkY62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboMQKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VStTDN0YUuWrBNh"' );
my $rand_flag;
# get_rand_flag()
# Return a flag to read from a randomness source
sub get_rand_flag
{
if ($gconfig{'os_type'} =~ /-linux$/ &&
$config{'force_random'} eq '0' &&
-r "/dev/urandom" &&
$bind_version =~ /^9\./ &&
&compare_version_numbers($bind_version, '<', '9.14.2')) {
&compare_version_numbers($bind_version, 9) >= 0 &&
&compare_version_numbers($bind_version, '9.14.2') < 0) {
# Version: 9.14.2 deprecated the use of -r option
# in favor of using /dev/random [bugs:#5370]
$rand_flag = "-r /dev/urandom";
return "-r /dev/urandom";
}
return "";
}
# have_dnssec_tools_support()
# Returns 1 if dnssec-tools support is available and we meet minimum version
@@ -2481,22 +2486,22 @@ sub list_zone_names
{
# Check if any files have changed, or if the master config has changed, or
# the PID file.
my (%files, %znc);
my ($changed, $filecount, %donefile);
my (%files, %znc, $changed);
my @st = stat($zone_names_cache);
if (@st) {
&read_file_cached_with_stat($zone_names_cache, \%znc);
my $filecount = 0;
foreach my $k (keys %znc) {
if ($k =~ /^file_(.*)$/) {
$filecount++;
$donefile{$1}++;
my @fst = stat($1);
if (!@fst || $fst[9] > $st[9] ||
$znc{'size_'.$1} != $fst[7]) {
$changed = 1;
}
$filecount++;
}
}
$changed = 1 if (!$filecount);
}
else {
$changed = 1;
@@ -2508,6 +2513,11 @@ if ($changed || !$znc{'version'} ||
# Yes .. need to rebuild
%znc = ( );
my $conf = &get_config();
my $gau;
my $opts = &find("options", $conf);
if ($opts && &find("allow-update", $opts->{'members'})) {
$gau = 1;
}
my @views = &find("view", $conf);
my $n = 0;
foreach my $v (@views) {
@@ -2519,7 +2529,7 @@ if ($changed || !$znc{'version'} ||
my $file = &find_value("file", $z->{'members'});
my $up = &find("update-policy", $z->{'members'});
my $au = &find("allow-update", $z->{'members'});
my $dynamic = $up || $au ? 1 : 0;
my $dynamic = $up || $au || $gau ? 1 : 0;
$znc{"zone_".($n++)} = join("\t", $z->{'value'},
$z->{'index'}, $type, $v->{'value'}, $dynamic, $file);
$files{$z->{'file'}}++;
@@ -2535,7 +2545,7 @@ if ($changed || !$znc{'version'} ||
$file ||= ""; # slaves and other types with no file
my $up = &find("update-policy", $z->{'members'});
my $au = &find("allow-update", $z->{'members'});
my $dynamic = $up || $au ? 1 : 0;
my $dynamic = $up || $au || $gau ? 1 : 0;
$znc{"zone_".($n++)} = join("\t", $z->{'value'},
$z->{'index'}, $type, "*", $dynamic, $file);
$files{$z->{'file'}}++;
@@ -3151,6 +3161,14 @@ sub supports_check_zone
return $config{'checkzone'} && &has_command($config{'checkzone'});
}
# supports_tls()
# Returns 1 if DNS over TLS is supported
sub supports_tls
{
return 1; # XXX fix me
return &compare_version_numbers($bind_version, 9.17) >= 0 ? 1 : 0;
}
# check_zone_records(&zone-name|&zone)
# Returns a list of errors from checking some zone file, if any
sub check_zone_records
@@ -3174,6 +3192,36 @@ my $out = &backquote_command(
return $? ? split(/\r?\n/, $out) : ( );
}
# check_zone_warnings(&zone-name|&zone)
# Returns a list of warnings from checking some zone file, if any
sub check_zone_warnings
{
my ($zone) = @_;
my ($zonename, $zonefile);
if ($zone->{'values'}) {
# Zone object
$zonename = $zone->{'values'}->[0];
my $f = &find("file", $zone->{'members'});
$zonefile = $f->{'values'}->[0];
}
else {
# Zone name object
$zonename = $zone->{'name'};
$zonefile = $zone->{'file'};
}
my $absfile = &make_chroot(&absolute_path($zonefile));
my $out = &backquote_command(
$config{'checkzone'}." ".quotemeta($zonename)." ".
quotemeta($absfile)." 2>&1 </dev/null");
my @rv;
foreach my $l (split(/\r?\n/, $out)) {
if ($l =~ /^\Q$absfile\E:\d+:\s*(.*)/) {
push(@rv, $1);
}
}
return @rv;
}
# supports_check_conf()
# Returns 1 if BIND configuration checking is supported, 0 if not
sub supports_check_conf
@@ -3337,10 +3385,8 @@ return &has_command($config{'signzone'}) &&
# dnssec-validation directive is not supported, 0 otherwise
sub supports_dnssec_client
{
my ($bind_major, $bind_minor) = split(/\./, $bind_version);
return $bind_major > 9 ? 2 :
$bind_major == 9 ? ($bind_minor >= 4 ? 2 : 1) : 0;
return &compare_version_numbers($bind_version, 9.4) >= 0 ? 2 :
&compare_version_numbers($bind_version, 9) >= 0 ? 1 : 0;
}
# dnssec_size_range(algorithm)
@@ -3406,7 +3452,7 @@ closedir(ZONEDIR);
# Fork a background job to do lots of IO, to generate entropy
my $pid;
if (!$rand_flag) {
if (!&get_rand_flag()) {
$pid = fork();
if (!$pid) {
exec("find / -type f >/dev/null 2>&1");
@@ -3455,7 +3501,7 @@ else {
"cd ".quotemeta($fn)." && ".
"$config{'keygen'} -a ".quotemeta($alg).
" -b ".quotemeta($zonesize).
" -n ZONE $rand_flag $dom 2>&1");
" -n ZONE ".&get_rand_flag()." $dom 2>&1");
if ($?) {
kill('KILL', $pid) if ($pid);
return $out;
@@ -3467,7 +3513,7 @@ else {
"cd ".quotemeta($fn)." && ".
"$config{'keygen'} -a ".quotemeta($alg).
" -b ".quotemeta($size).
" -n ZONE -f KSK $rand_flag $dom 2>&1");
" -n ZONE -f KSK ".&get_rand_flag()." $dom 2>&1");
kill('KILL', $pid) if ($pid);
if ($?) {
return $out;
@@ -3537,7 +3583,7 @@ $zonekey || return "Could not find DNSSEC zone key";
# Fork a background job to do lots of IO, to generate entropy
my $pid;
if (!$rand_flag) {
if (!&get_rand_flag()) {
$pid = fork();
if (!$pid) {
exec("find / -type f >/dev/null 2>&1");
@@ -3554,7 +3600,7 @@ my $alg = $zonekey->{'algorithm'};
my $out = &backquote_logged(
"cd ".quotemeta($dir)." && ".
"$config{'keygen'} -a ".quotemeta($alg)." -b ".quotemeta($zonesize).
" -n ZONE $rand_flag $dom 2>&1");
" -n ZONE ".&get_rand_flag()." $dom 2>&1");
kill('KILL', $pid) if ($pid);
if ($?) {
return "Failed to generate new zone key : $out";
@@ -4492,4 +4538,23 @@ if ($zone) {
return $r;
}
# find_tls_users(&conf, name)
# Find all listen-on or other directives that use a given TLS key name
sub find_tls_users
{
my ($conf, $name) = @_;
my @rv;
my $opts = &find("optons", $conf);
if ($opts) {
my @listen = &find("listen-on", $opts->{'members'});
foreach my $l (@listen) {
my $idx = &indexof("tls", @{$l->{'values'}});
if ($idx >= 0 && $l->{'values'}->[$idx+1] eq $name) {
push(@rv, $l);
}
}
}
return @rv;
}
1;

View File

@@ -20,12 +20,22 @@ my $desc = &ip6int_to_net(&arpa_to_ip($zone->{'name'}));
my $file = &make_chroot(&absolute_path($zone->{'file'}));
my @errs = &check_zone_records($zone);
my @warns = &check_zone_warnings($zone);
if (@errs) {
# Show list of errors
print "<b>",&text('check_errs', "<tt>$file</tt>"),"</b><p>\n";
print "<ul>\n";
foreach my $e (@errs) {
print "<li>".&html_escape($e)."\n";
print "<li>".&html_escape($e)."</li>\n";
}
print "</ul>\n";
}
elsif (@warns) {
# Just show warnings
print "<b>",&text('check_warns', "<tt>$file</tt>"),"</b><p>\n";
print "<ul>\n";
foreach my $e (@warns) {
print "<li>".&html_escape($e)."</li>\n";
}
print "</ul>\n";
}

View File

@@ -21,7 +21,7 @@ if (@errs) {
print "<b>",&text('ncheck_errs', "<tt>$file</tt>"),"</b><p>\n";
print "<ul>\n";
foreach my $e (@errs) {
print "<li>".&html_escape($e)."\n";
print "<li>".&html_escape($e)."</li>\n";
}
print "</ul>\n";
}

63
bind8/edit_tls.cgi Normal file
View File

@@ -0,0 +1,63 @@
#!/usr/local/bin/perl
# Show a form to edit or create a TLS key and cert
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
our (%access, %text, %in);
require './bind8-lib.pl';
$access{'defaults'} || &error($text{'tls_ecannot'});
&supports_tls() || &error($text{'tls_esupport'});
&ReadParse();
# Get the TLS config being edited
my $tls;
if (!$in{'new'}) {
my $conf = &get_config();
my @tls = &find("tls", $conf);
($tls) = grep { $_->{'values'}->[0] eq $in{'name'} } @tls;
$tls || &error($text{'tls_egone'});
}
else {
$tls = { 'values' => [],
'members' => [] };
}
my $mems = $tls->{'members'};
&ui_print_header(undef, $in{'new'} ? $text{'tls_title1'}
: $text{'tls_title2'}, "");
print &ui_form_start("save_tls.cgi", "post");
print &ui_hidden("new", $in{'new'});
print &ui_hidden("oldname", $in{'name'});
print &ui_table_start($text{'tls_header'}, undef, 2);
# Name of this key
print &ui_table_row($text{'tls_name'},
&ui_textbox("name", $tls->{'values'}->[0], 30));
# Key file
print &ui_table_row($text{'tls_key'},
&ui_filebox("key", &find_value("key-file", $mems), 60));
# Cert file
print &ui_table_row($text{'tls_cert'},
&ui_filebox("cert", &find_value("cert-file", $mems), 60));
# CA cert file
my $ca = &find_value("ca-file", $mems);
print &ui_table_row($text{'tls_ca'},
&ui_radio("ca_def", $ca ? 0 : 1,
[ [ 1, $text{'tls_ca_def'} ],
[ 0, &ui_filebox("ca", $ca, 60) ] ]));
print &ui_table_end();
print &ui_form_end(
$in{'new'} ? [ [ undef, $text{'create'} ] ]
: [ [ undef, $text{'save'} ],
[ 'delete', $text{'delete'} ] ]
);
&ui_print_footer("list_tls.cgi", $text{'tls_return'});

View File

@@ -26,6 +26,10 @@ foreach my $z (@zones) {
$v eq "." || !&can_edit_zone($z) ||
&arpa_to_ip($v) !~ /\Q$in{'search'}\E/i);
my $t = $z->{'type'};
next if (!$t);
$t = "delegation" if ($t eq "delegation-only");
$t = "master" if ($t eq "primary");
$t = "slave" if ($t eq "secondary");
if ($z->{'view'}) {
push(@zlinks, "edit_$t.cgi?zone=$z->{'name'}".
"&view=$z->{'viewindex'}");

BIN
bind8/images/tls.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 B

View File

@@ -118,16 +118,19 @@ if ($access{'defaults'}) {
if ($access{'defaults'}) {
# display global options
print &ui_subheading($text{'index_opts'});
my @olinks = ("conf_servers.cgi", "conf_logging.cgi", "conf_acls.cgi",
"conf_files.cgi", "conf_forwarding.cgi", "conf_net.cgi",
"conf_misc.cgi", "conf_controls.cgi", "conf_keys.cgi",
"conf_zonedef.cgi", "list_slaves.cgi",
$bind_version >= 9 ? ( "conf_rndc.cgi" ) : ( ),
&supports_dnssec_client() ? ( "conf_trusted.cgi" ) : ( ),
((&supports_dnssec()) && (&have_dnssec_tools_support())) ? ( "conf_dnssectools.cgi" ) : ( ),
&supports_dnssec() ? ( "conf_dnssec.cgi" ) : ( ),
&supports_check_conf() ? ( "conf_ncheck.cgi" ) : ( ),
"conf_manual.cgi" );
my @olinks = (
"conf_servers.cgi", "conf_logging.cgi", "conf_acls.cgi",
"conf_files.cgi", "conf_forwarding.cgi", "conf_net.cgi",
"conf_misc.cgi", "conf_controls.cgi", "conf_keys.cgi",
"conf_zonedef.cgi", "list_slaves.cgi", "conf_rndc.cgi",
&supports_dnssec_client() ? ( "conf_trusted.cgi" ) : ( ),
&supports_dnssec() && &have_dnssec_tools_support() ?
( "conf_dnssectools.cgi" ) : ( ),
&supports_dnssec() ? ( "conf_dnssec.cgi" ) : ( ),
&supports_tls() ? ( "list_tls.cgi" ) : ( ),
&supports_check_conf() ? ( "conf_ncheck.cgi" ) : ( ),
"conf_manual.cgi",
);
my @otitles = map { /(conf|list)_(\S+).cgi/; $text{$2."_title"} } @olinks;
my @oicons = map { /^(conf|list)_(\S+).cgi/; "images/$2.gif"; } @olinks;
&icons_table(\@olinks, \@otitles, \@oicons, 6);
@@ -453,7 +456,7 @@ else {
print &ui_links_row(\@crlinks);
}
if ($access{'views'} && $bind_version >= 9) {
if ($access{'views'}) {
# Display list of views
print &ui_hr();
print &ui_subheading($text{'index_views'});

View File

@@ -1173,6 +1173,7 @@ rmass_clash=إنشاء حتى لو كان السجل موجود بالفعل؟
check_title=تحقق السجلات
check_ecannot=غير مسموح لك بالتحقق من السجلات
check_errs=The following errors were found in the records file $1 ..
check_warns=تم العثور على التحذيرات التالية في ملف السجلات $1 ..
check_allok=No errors were found in the records file $1.
ncheck_title=تحقق BIND التكوين

View File

@@ -59,6 +59,8 @@ log_delete_recs2=Изтрити $1 записи в зона $2
massdelete_vwarn=Някои зони са свързани с домейна Virtualmin $1 и затова не трябва да се изтриват тук!
massdelete_vwarn2=Някои зони са свързани с домейна Virtualmin $1 и $2 други и затова не трябва да се изтриват тук!
check_warns=Следните предупреждения бяха намерени във файла със записи $1 ..
zonekey_algorithm=DNSSEC алгоритъм : $1
zonekey_ds_keytag=Ключов етикет
zonekey_ds_alg=Алгоритъм

View File

@@ -63,6 +63,8 @@ log_delete_recs2=S'han suprimit $1 registres a la zona $2
massdelete_vwarn=Algunes zones estan associades al domini Virtualmin $1, per tant, no hauríem de suprimir-les aquí.
massdelete_vwarn2=Algunes zones estan associades al domini Virtualmin $1 i $2, per tant, no hauríem de suprimir-les.
check_warns=S'han trobat els advertiments següents al fitxer de registres $1 ..
zonekey_algorithm=Algorisme DNSSEC : $1
zonekey_ds_keytag=Etiqueta clau
zonekey_ds_alg=Algorisme

View File

@@ -289,6 +289,7 @@ rmass_eclash2=.. záznam se stejným názvem a stejnou hodnotou $1 již existuje
check_title=Zkontrolujte záznamy
check_ecannot=Není dovoleno kontrolovat záznamy
check_errs=V souboru záznamů $1 byly nalezeny následující chyby.
check_warns=V souboru záznamů $1 byla nalezena následující varování ..
check_allok=V souboru záznamů $1 nebyly nalezeny žádné chyby.
ncheck_title=Zkontrolujte BIND Config

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Opret, selvom der allerede findes en post?
check_title=Tjek poster
check_ecannot=Du har ikke tilladelse til at kontrollere poster
check_errs=Følgende fejl blev fundet i posteringsfilen $1 ..
check_warns=Følgende advarsler blev fundet i postfilen $1 ..
check_allok=Der blev ikke fundet nogen fejl i postfilen $1.
ncheck_title=Kontroller BIND Config

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Erstellen, auch wenn Eintrag bereits existiert?
check_title=Einträge prüfen
check_ecannot=Sie sind nicht berechtigt, Einträge zu überprüfen.
check_errs=Die folgenden Fehler wurden in der Eintragsdatei $1 gefunden ..
check_warns=Die folgenden Warnungen wurden in der Eintragsdatei $1 gefunden ..
check_allok=Keine Fehler in der Eintragsdatei $1 gefunden.
ncheck_title=BIND-Konfiguration prüfen

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Δημιουργήστε ακόμα και αν υπάρχει ήδ
check_title=Ελέγξτε τις εγγραφές
check_ecannot=Δεν επιτρέπεται να ελέγχετε τα αρχεία
check_errs=Τα παρακάτω σφάλματα βρέθηκαν στο αρχείο εγγραφών $1 ..
check_warns=Οι ακόλουθες προειδοποιήσεις βρέθηκαν στο αρχείο εγγραφών $1 ..
check_allok=Δεν βρέθηκαν σφάλματα στο αρχείο εγγραφών $1.
ncheck_title=Ελέγξτε το BIND Config

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Create even if record already exists?
check_title=Check Records
check_ecannot=You are not allowed to check records
check_errs=The following errors were found in the records file $1 ..
check_warns=The following warnings were found in the records file $1 ..
check_allok=No errors were found in the records file $1.
ncheck_title=Check BIND Config
@@ -1348,4 +1349,30 @@ xfer_done=.. from $1 : Completed OK
xfer_count=Test transfer successfully fetched $1 records from at least one nameserver. Actual transfers by BIND should also succeed.
xfer_none=Test transfer appeared to succeed, but didn't actually fetch any records!
tls_title=SSL Keys And Certificates
tls_ecannot=You are not allowed to edit SSL keys and certificates
tls_esupport=SSL keys and certificates are not supported on this system
tls_name=Key name
tls_key=Key file
tls_cert=Certificate file
tls_ca=CA certificate file
tls_ca_def=None required
tls_ecannot=You are not allowed to edit SSL keys and certificates
tls_esupport=DNS over SSL is not supported on this system
tls_none=No SSL keys have been added yet.
tls_add=Add a new SSL key.
tls_desc=The SSL keys and certificates listed on this page can be used to enable DNS over SSL/TLS.
tls_title1=Add SSL Key
tls_title2=Edit SSL Key
tls_egone=SSL key no longer exists!
tls_header=Key and certificate details
tls_cerr=Failed to create SSL key
tls_derr=Failed to delete SSL key
tls_err=Failed to save SSL key
tls_ename=SSL key name can only contain letters, numbers, underscore and dash
tls_ekey=Missing or non-existent SSL key file
tls_ecert=Missing or non-existent SSL certificate file
tls_eca=Missing or non-existent SSL CA certificate file
tls_eusers=SSL certificate is still in use by BIND
__norefs=1

View File

@@ -489,6 +489,7 @@ rmass_clash=¿Crear incluso si el registro ya existe?
check_title=Verificar registros
check_ecannot=No tiene permiso para verificar registros
check_errs=Se encontraron los siguientes errores en el archivo de registros $1 ..
check_warns=Las siguientes advertencias se encontraron en el archivo de registros $1 ..
check_allok=No se encontraron errores en el archivo de registros $1.
ncheck_title=Verifique la configuración de BIND

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Sortu erregistroa dagoeneko badago?
check_title=Egiaztatu Erregistroak
check_ecannot=Ezin duzu erregistroak egiaztatu
check_errs=Ondorengo akatsak aurkitu dira $1 erregistroko fitxategian.
check_warns=Honako abisu hauek $1 erregistro fitxategian aurkitu dira ..
check_allok=Ez da akatsik aurkitu $1 erregistroko fitxategian.
ncheck_title=Begiratu BIND Config

View File

@@ -429,6 +429,7 @@ rmass_clash=حتی اگر سابقه قبلاً وجود داشته باشد ا
check_title=سوابق را بررسی کنید
check_ecannot=شما مجاز به بررسی سوابق نیستید
check_errs=The following errors were found in the records file $1 ..
check_warns=اخطارهای زیر در فایل سوابق $1 یافت شد ..
check_allok=No errors were found in the records file $1.
ncheck_title=پیکربندی BIND را بررسی کنید

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Luo vaikka tietue on jo olemassa?
check_title=Tarkista tietueet
check_ecannot=Et voi tarkistaa tietueita
check_errs=Seuraavat virheet löytyivät tietuetiedostosta $1 ..
check_warns=Tietuetiedostosta $1.. löytyi seuraavat varoitukset ..
check_allok=Tietuetiedostossa $1 ei löytynyt virheitä.
ncheck_title=Tarkista BIND-kokoonpano

View File

@@ -44,6 +44,8 @@ value_NAPTR3_P=Action spécifique au protocole
log_delete_recs2=$1 enregistrements supprimés dans la zone $2
check_warns=Les avertissements suivants ont été trouvés dans le fichier d'enregistrements $1 ..
zonekey_algorithm=Algorithme DNSSEC  : $1
zonekey_ds_keytag=Porte-clés
zonekey_ds_alg=Algorithme

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Kreirajte čak i ako zapis već postoji?
check_title=Provjerite zapise
check_ecannot=Nije vam dopušteno provjeravati zapise
check_errs=Sljedeće pogreške pronađene su u datoteci zapisa $1.
check_warns=Sljedeća upozorenja pronađena su u datoteci zapisa $1 ..
check_allok=U datoteci zapisa $1 nisu pronađene pogreške.
ncheck_title=Označite BIND Config

View File

@@ -167,6 +167,8 @@ massdelete_vwarn2=Egyes zónák a (z) $1 és a (z) $2 Virtualmin domainhez vanna
rmass_esign=.. kész, de az aláírás sikertelen : $1
check_warns=A következő figyelmeztetések találhatók a(z) $1.. rekordfájlban ..
dnssec_secs=másodperc
dnssectools_title=DNSSEC-Tools automatizálás

View File

@@ -562,6 +562,7 @@ rmass_clash=Crea anche se il record esiste già?
check_title=Controlla i record
check_ecannot=Non è consentito controllare i record
check_errs=I seguenti errori sono stati trovati nel file dei record $1 ..
check_warns=Sono stati trovati i seguenti avvisi nel file di record $1 ..
check_allok=Nessun errore trovato nel file dei record $1.
ncheck_title=Controlla la configurazione BIND

View File

@@ -221,6 +221,7 @@ rmass_name2=(ドメイン名に<tt>@</tt>を入力します)
rmass_esign=..完了しましたが、署名に失敗しました:$1
rmass_eclash2=..同じ名前と同じ値を持つレコード$1はすでに存在します。
check_warns=レコード ファイル $1 に次の警告が見つかりました。
ncheck_title=BIND Configを確認してください
ncheck_ecannot=BIND構成を確認することはできません
ncheck_errs=BIND構成ファイル$1または参照ゾーンファイルで次のエラーが見つかりました。

View File

@@ -747,6 +747,7 @@ rmass_clash=레코드가 이미 존재하더라도 작성 하시겠습니까?
check_title=기록 확인
check_ecannot=기록을 확인할 수 없습니다
check_errs=레코드 파일 $1에서 다음 오류가 발견되었습니다.
check_warns=다음 경고가 $1 레코드 파일에서 발견되었습니다 ..
check_allok=레코드 파일 $1에서 오류가 발견되지 않았습니다.
ncheck_title=BIND 구성 확인

View File

@@ -1171,6 +1171,7 @@ rmass_clash=Buat walaupun rekod sudah wujud?
check_title=Semak Rekod
check_ecannot=Anda tidak dibenarkan menyemak rekod
check_errs=Kesalahan berikut telah dijumpai dalam fail rekod $1 ..
check_warns=Amaran berikut ditemui dalam fail rekod $1 ..
check_allok=Tiada ralat ditemui dalam fail rekod $1.
ncheck_title=Semak BIND Config

View File

@@ -157,6 +157,8 @@ massdelete_vwarn2=Sommige zones zijn geassocieerd met het Virtualmin-domein $1 e
rmass_esign=.. klaar, maar ondertekenen mislukt : $1
check_warns=De volgende waarschuwingen zijn gevonden in het recordbestand $1 ..
dnssec_secs=seconden
zonekey_publicfile=Bestand met openbare sleutel : $1

View File

@@ -44,6 +44,8 @@ value_NAPTR3_P=Protokollspesifikk handling
log_delete_recs2=Slettet $1 poster i sone $2
check_warns=Følgende advarsler ble funnet i postfilen $1 ..
zonekey_algorithm=DNSSEC-algoritme : $1
zonekey_ds_keytag=Nøkkelbrikke
zonekey_ds_alg=Algoritme

View File

@@ -107,6 +107,8 @@ log_delete_recs2=Usunięto $1 rekordów w strefie $2
massdelete_vwarn=Niektóre strefy są powiązane z domeną Virtualmin $1, dlatego nie należy ich tutaj usuwać!
massdelete_vwarn2=Niektóre strefy są powiązane z domeną Virtualmin $1 i $2 innymi, dlatego nie należy ich tutaj usuwać!
check_warns=Znaleziono następujące ostrzeżenia w pliku rekordów $1 ..
dnssec_secs=sekundy
dt_zone_zskrolldesc=Wymuś najazd klucza podpisującego strefę

View File

@@ -839,6 +839,7 @@ rmass_clash=Criar mesmo se o registro já existir?
check_title=Verificar registros
check_ecannot=Você não tem permissão para verificar registros
check_errs=Os seguintes erros foram encontrados no arquivo de registros $1 ..
check_warns=Os seguintes avisos foram encontrados no arquivo de registros $1 ..
check_allok=Nenhum erro foi encontrado no arquivo de registros $1.
ncheck_title=Verifique a configuração do BIND

View File

@@ -197,6 +197,8 @@ rmass_name2=(Digite <tt>@</tt> para o nome do domínio)
rmass_esign=.. feito, mas a assinatura falhou : $1
rmass_eclash2=.. um registro com o mesmo nome e o mesmo valor $1 já existe.
check_warns=Os seguintes avisos foram encontrados no arquivo de registros $1 ..
dnssec_secs=segundos
dnssectools_title=Automação de Ferramentas DNSSEC

View File

@@ -589,6 +589,7 @@ rmass_clash=Создать, даже если запись уже существ
check_title=Проверьте записи
check_ecannot=Вам не разрешено проверять записи
check_errs=Следующие ошибки были обнаружены в файле записей $1 ..
check_warns=В файле записей $1 были обнаружены следующие предупреждения ..
check_allok=В файле записей $1 ошибок не обнаружено.
ncheck_title=Проверьте BIND Config

View File

@@ -1173,6 +1173,7 @@ rmass_clash=Vytvoriť, aj keď už záznam existuje?
check_title=Skontrolujte záznamy
check_ecannot=Nemáte oprávnenie kontrolovať záznamy
check_errs=V súbore záznamov $1 sa našli nasledujúce chyby.
check_warns=V súbore záznamov $1 sa našli nasledujúce upozornenia ..
check_allok=V súbore záznamov $1 sa nenašli žiadne chyby.
ncheck_title=Skontrolujte BIND Config

View File

@@ -314,6 +314,7 @@ rmass_clash=Skapa även om posten redan finns?
check_title=Kontrollera poster
check_ecannot=Du får inte kontrollera poster
check_errs=Följande fel hittades i registerfilen $1 ..
check_warns=Följande varningar hittades i postfilen $1 ..
check_allok=Inga fel hittades i registerfilen $1.
ncheck_title=Kontrollera BIND Config

View File

@@ -335,6 +335,7 @@ rmass_clash=Kayıt zaten mevcut olsa bile oluşturulsun mu?
check_title=Kayıtları Kontrol Et
check_ecannot=Kayıtları kontrol etme izniniz yok
check_errs=$1 kayıt dosyasında aşağıdaki hatalar bulundu.
check_warns=$1 kayıt dosyasında aşağıdaki uyarılar bulundu ..
check_allok=$1 kayıt dosyasında hata bulunamadı.
ncheck_title=BIND Config'i kontrol edin

View File

@@ -589,6 +589,7 @@ rmass_clash=Створити, навіть якщо запис уже існує
check_title=Перевірте записи
check_ecannot=Вам заборонено перевіряти записи
check_errs=У файлі записів $1 виявлено такі помилки.
check_warns=Наступні попередження знайдено у файлі записів $1 ..
check_allok=У файлі записів $1 не виявлено помилок.
ncheck_title=Перевірте налаштування BIND

View File

@@ -564,6 +564,7 @@ rmass_clash=即使记录已经存在也创建吗?
check_title=检查记录
check_ecannot=您无权检查记录
check_errs=在记录文件$1中发现以下错误。
check_warns=在记录文件 $1 中发现下列警告。
check_allok=在记录文件$1中未找到错误。
ncheck_title=检查BIND配置

View File

@@ -845,6 +845,7 @@ rmass_clash=即使記錄已經存在也創建嗎?
check_title=檢查記錄
check_ecannot=您無權檢查記錄
check_errs=在記錄文件$1中發現以下錯誤。
check_warns=在記錄文件 $1 中發現下列警告。
check_allok=在記錄文件$1中未找到錯誤。
ncheck_title=檢查BIND配置

44
bind8/list_tls.cgi Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/local/bin/perl
# Show all registered TLS keys
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
our (%access, %text);
require './bind8-lib.pl';
$access{'defaults'} || &error($text{'tls_ecannot'});
&supports_tls() || &error($text{'tls_esupport'});
my $conf = &get_config();
&ui_print_header(undef, $text{'tls_title'}, "");
print $text{'tls_desc'},"<p>\n";
# Show a table of TLS keys
my @tls = &find("tls", $conf);
my @links = ( &ui_link("edit_tls.cgi?new=1", $text{'tls_add'}) );
if (@tls) {
print &ui_links_row(\@links);
print &ui_columns_start([ $text{'tls_name'},
$text{'tls_key'},
$text{'tls_cert'} ], 100);
foreach my $tls (@tls) {
my $mems = $tls->{'members'};
print &ui_columns_row([
&ui_link("edit_tls.cgi?name=".
&urlize($tls->{'values'}->[0]),
$tls->{'values'}->[0]),
&html_escape(&find_value("key-file", $mems)),
&html_escape(&find_value("cert-file", $mems)),
]);
}
print &ui_columns_end();
}
else {
print "<b>$text{'tls_none'}</b> <p>\n";
}
print &ui_links_row(\@links);
&ui_print_footer("", $text{'index_return'});

90
bind8/save_tls.cgi Normal file
View File

@@ -0,0 +1,90 @@
#!/usr/local/bin/perl
# Create, update or delete a TLS key and cert
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
our (%access, %text, %in, %config);
require './bind8-lib.pl';
$access{'defaults'} || &error($text{'tls_ecannot'});
&supports_tls() || &error($text{'tls_esupport'});
&ReadParse();
&error_setup($in{'new'} ? $text{'tls_cerr'} :
$in{'delete'} ? $text{'tls_derr'} : $text{'tls_err'});
# Get the TLS config being edited
my $parent = &get_config_parent();
my $conf = &get_config();
my @tls = &find("tls", $conf);
my $tls;
if (!$in{'new'}) {
($tls) = grep { $_->{'values'}->[0] eq $in{'oldname'} } @tls;
$tls || &error($text{'tls_egone'});
}
&lock_file(&make_chroot($config{'named_conf'}));
if ($in{'delete'}) {
# Just remove this one TLS key, if unused
my @users = &find_tls_users($conf, $tls->{'values'}->[0]);
@users && &error($text{'tls_eusers'});
&save_directive($parent, [ $tls ], [ ]);
}
else {
# Validate inputs
$in{'name'} =~ /^[a-z0-9\-\_]+$/i || &error($text{'tls_ename'});
-r $in{'key'} || &error($text{'tls_ekey'});
-r $in{'cert'} || &error($text{'tls_ecert'});
if (!$in{'ca_def'}) {
-r $in{'ca'} || &error($text{'tls_eca'});
}
&foreign_require("webmin");
&webmin::validate_key_cert($in{'key'}, $in{'cert'});
if (!$in{'ca_def'}) {
&webmin::validate_key_cert($in{'key'}, $in{'ca'});
}
if ($in{'new'}) {
# Create the TLS object
$tls = { 'name' => 'tls',
'values' => [ $in{'name'} ],
'type' => 1,
'members' => [
{ 'name' => 'key-file',
'values' => [ $in{'key'} ]
},
{ 'name' => 'cert-file',
'values' => [ $in{'cert'} ]
},
]
};
if (!$in{'ca_def'}) {
push(@{$tls->{'members'}},
{ 'name' => 'ca-file',
'values' => [ $in{'ca'} ]
});
}
&save_directive($parent, [ ], [ $tls ]);
}
else {
# Update the existing object
$tls->{'values'}->[0] = $in{'name'};
&save_directive($parent, [ $tls ], [ $tls ]);
&save_directive($tls, "key-file",
[ { 'name' => 'key-file',
'values' => [ $in{'key'} ] } ]);
&save_directive($tls, "cert-file",
[ { 'name' => 'cert-file',
'values' => [ $in{'cert'} ] } ]);
&save_directive($tls, "ca-file", $in{'ca_def'} ? [ ] :
[ { 'name' => 'ca-file',
'values' => [ $in{'ca'} ] } ]);
}
}
&flush_file_lines();
&unlock_file(&make_chroot($config{'named_conf'}));
&webmin_log($in{'new'} ? 'create' : $in{'delete'} ? 'delete' : 'modify',
'tls', $tls->{'values'}->[0]);
&redirect("list_tls.cgi");

View File

@@ -78,17 +78,17 @@ return \%rv;
# or error message
sub run_cluster_job
{
local @rv;
local $func = $_[1];
my ($job, $func) = @_;
my @rv;
# Work out which servers to run on
local @servers = &servers::list_servers_sorted();
local @groups = &servers::list_all_groups(\@servers);
local @run;
foreach $s (split(/\s+/, $_[0]->{'cluster_server'})) {
foreach my $s (split(/\s+/, $job->{'cluster_server'})) {
if ($s =~ /^group_(.*)$/) {
# All members of a group
($group) = grep { $_->{'name'} eq $1 } @groups;
my ($group) = grep { $_->{'name'} eq $1 } @groups;
foreach $m (@{$group->{'members'}}) {
push(@run, grep { $_->{'host'} eq $m && $_->{'user'} }
@servers);
@@ -96,7 +96,7 @@ foreach $s (split(/\s+/, $_[0]->{'cluster_server'})) {
}
elsif ($s eq '*') {
# This server
push(@run, ( { 'desc' => $text{'edit_this'} } ));
push(@run, ( { 'id' => 0, 'desc' => $text{'edit_this'} } ));
}
elsif ($s eq 'ALL') {
# All servers with users
@@ -107,7 +107,10 @@ foreach $s (split(/\s+/, $_[0]->{'cluster_server'})) {
push(@run, grep { $_->{'host'} eq $s } @servers);
}
}
@run = &unique(@run);
# Run once per host
my %done;
@run = grep { !$done{$_->{'id'}}++ } @run;
# Setup error handler for down hosts
sub inst_error
@@ -119,7 +122,7 @@ $inst_error_msg = join("", @_);
# Create a local temp file containing input
local $ltemp = &transname();
open(TEMP, ">$ltemp");
local $inp = $_[0]->{'cluster_input'};
local $inp = $job->{'cluster_input'};
$inp =~ s/\\%/\0/g;
@lines = split(/%/, $inp);
foreach $l (@lines) {
@@ -129,8 +132,8 @@ foreach $l (@lines) {
close(TEMP);
# Run one each one in parallel and display the output
$p = 0;
foreach $s (@run) {
my $p = 0;
foreach my $s (@run) {
local ($rh = "READ$p", $wh = "WRITE$p");
pipe($rh, $wh);
select($wh); $| = 1; select(STDOUT);
@@ -150,16 +153,16 @@ foreach $s (@run) {
local $rtemp = &remote_write($s->{'host'}, $ltemp);
# Run the command and capture output
local $q = quotemeta($_[0]->{'cluster_command'});
local $q = quotemeta($job->{'cluster_command'});
local $rv;
if ($_[0]->{'cluster_user'} eq 'root') {
if ($job->{'cluster_user'} eq 'root') {
$rv = &remote_eval($s->{'host'}, "webmin",
"\$x=&backquote_command('($_[0]->{'cluster_command'}) <$rtemp 2>&1')");
"\$x=&backquote_command('($job->{'cluster_command'}) <$rtemp 2>&1')");
}
else {
$q = quotemeta($q);
$rv = &remote_eval($s->{'host'}, "webmin",
"\$x=&backquote_command(&command_as_user('$_[0]->{'cluster_user'}', 0, '$_[0]->{'cluster_command'}').' <$rtemp 2>&1')");
"\$x=&backquote_command(&command_as_user('$job->{'cluster_user'}', 0, '$job->{'cluster_command'}').' <$rtemp 2>&1')");
}
&remote_eval($s->{'host'}, "webmin", "unlink('$rtemp')");
@@ -177,12 +180,11 @@ foreach $s (@run) {
local $rh = "READ$p";
local $line = <$rh>;
close($rh);
local $rv = &unserialise_variable($line);
if (!$line) {
&$func(0, $s, "Unknown reason");
}
else {
my $rv = &unserialise_variable($line);
&$func($rv->[0], $s, $rv->[1]);
}
$p++;

View File

@@ -23,20 +23,22 @@ $job->{'run'} = [ map { $_->{'host'} } @run ]; # for logging
&ui_print_footer("edit.cgi?id=$in{'id'}", $cron::text{'edit_return'},
"", $text{'index_return'});
# callback(error, &server, message)
# callback(ok, &server, message)
# Called back to print results for each host the job is run on
sub callback
{
local $d = ($_[1]->{'host'} || &get_system_hostname()).
($_[1]->{'desc'} ? " ($_[1]->{'desc'})" : "");
if (!$_[0]) {
my ($ok, $s, $msg) = @_;
my $d = ($s->{'host'} || &get_system_hostname()).
($s->{'desc'} ? " ($s->{'desc'})" : "");
if (!$ok) {
# Failed - show error
print "<b>",&text('exec_failed', $d, $_[2]),"</b><p>\n";
print "<b>",&text('exec_failed', $d, &html_escape($msg)),"</b><p>\n";
}
else {
# Show output if any
print "<b>",&text('exec_success', $d),"</b>\n";
if ($_[2]) {
print "<ul><pre>$_[2]</pre></ul><p>\n";
if ($ok) {
print "<ul><pre>",&html_escape($msg),"</pre></ul><p>\n";
}
else {
print "<br><ul><i>$cron::text{'exec_none'}</i></ul><p>\n";

5
cron/cleanup.pl Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/perl
# Manually run the temp files cleanup function
require './cron-lib.pl';
&cleanup_temp_files();

View File

@@ -1573,41 +1573,58 @@ if ($gconfig{'tempdir'} && !$gconfig{'tempdirdelete'}) {
print STDERR "Temp file clearing is not done for the custom directory $gconfig{'tempdir'}\n";
}
else {
local $tempdir = &transname();
my $tempdir = &transname();
$tempdir =~ s/\/([^\/]+)$//;
if (!$tempdir || $tempdir eq "/") {
$tempdir = "/tmp/.webmin";
}
local $cutoff = time() - $gconfig{'tempdelete_days'}*24*60*60;
opendir(DIR, $tempdir);
my $cutoff = time() - $gconfig{'tempdelete_days'}*24*60*60;
if (opendir(DIR, $tempdir)) {
foreach my $f (readdir(DIR)) {
next if ($f eq "." || $f eq "..");
my @st = lstat("$tempdir/$f");
if ($st[9] < $cutoff) {
&unlink_file("$tempdir/$f");
}
}
closedir(DIR);
}
}
# Delete stale lock files
my $lockdir = $var_directory."/locks";
if (opendir(DIR, $lockdir)) {
foreach my $f (readdir(DIR)) {
next if ($f eq "." || $f eq "..");
local @st = lstat("$tempdir/$f");
if ($st[9] < $cutoff) {
&unlink_file("$tempdir/$f");
next if ($f !~ /^\d+$/);
if (!kill(0, $f)) {
# Process is gone, but never cleaned up!
&unlink_file("$lockdir/$f");
}
}
closedir(DIR);
}
# Delete stale lock files
my $lockdir = $var_directory."/locks";
opendir(DIR, $lockdir);
foreach my $f (readdir(DIR)) {
next if ($f eq "." || $f eq "..");
next if ($f !~ /^\d+$/);
if (!kill(0, $f)) {
# Process is gone, but never cleaned up!
&unlink_file("$lockdir/$f");
}
}
closedir(DIR);
# Cleanup old websockets
foreach (&get_miniserv_websockets_modules()) {
&cleanup_miniserv_websockets(undef, $_);
}
# Delete forgot-password files older than 1 day
if (opendir(DIR, $main::forgot_password_link_dir)) {
my $cutoff = time() - 24*60*60;
foreach my $f (readdir(DIR)) {
next if ($f eq "." || $f eq "..");
next if ($f eq "ratelimit");
my $path = $main::forgot_password_link_dir."/".$f;
my @st = stat($path);
if ($st[9] < $cutoff) {
&unlink_file($path);
}
}
closedir(DIR);
}
}
=head2 list_cron_files()

View File

@@ -1,4 +1,4 @@
index_title=Időzitett futtatások (Cron munkák)
index_title=Időzített futtatások (Cron)
index_user=Felhasználó
index_active=Érvényes?
index_command=Parancs

View File

@@ -1,2 +1,2 @@
longdesc_hu=IdĂľzitett futtatĂĄsok lĂŠtrehozĂĄsa, mĂłdosĂ­tĂĄsa ĂŠs tĂśrlĂŠse
desc_hu=IdĂľzitett futtatĂĄsok (Cron)
longdesc_hu=Időzített futtatások létrehozása, módosítása és törlése
desc_hu=Időzített futtatások (Cron)

View File

@@ -11,6 +11,8 @@ eval {
'func' => 'cleanup_temp_files',
'interval' => 3600 };
&webmincron::create_webmin_cron($cron, $temp_delete_cmd);
&create_wrapper($module_config_directory."/cleanup.pl",
$module_name, "cleanup.pl");
};
if ($@) {
print STDERR "Failed to setup /tmp cleanup cron job : $@\n";

View File

@@ -32,21 +32,27 @@ print &ui_table_row($text{'net_ssl_disable'},
[ @opts,
[ "", &getdef($sslopt, \@opts) ] ]));
@listens = &find("imap_listen", $conf, 2) ?
my @listens = &find("imap_listen", $conf, 2) ?
("imap_listen", "pop3_listen", "imaps_listen", "pop3s_listen") :
("listen", "ssl_listen");
("listen");
my $mode;
foreach $l (@listens) {
$listen = &find_value($l, $conf);
$mode = !$listen ? 0 :
$listen eq "[::]" ? 1 :
$listen eq "*" ? 2 : 3,
my $v = &find_value($l, $conf);
$mode = !$v ? 0 :
# All interfaces, put in any order, e.g. "[::], *" or "*, ::"
$v =~ /^\*,\s*(::|\[::\])$/ || $v =~ /^(::|\[::\]),\s*\*$/ ? 1 :
# IPv6 only, e.g. "[::]" or "::"
$v eq '::' || $v eq '[::]' ? 4 :
# IPv4 only, e.g. "*"
$v eq "*" ? 2 : 3,
print &ui_table_row($text{'net_'.$l},
&ui_radio($l."_mode", $mode,
[ [ 0, $text{'net_listen0'} ],
[ 1, $text{'net_listen1'} ],
[ 2, $text{'net_listen2'} ],
[ 4, $text{'net_listen4'} ],
[ 3, $text{'net_listen3'} ] ])."\n".
&ui_textbox($l, $mode == 3 ? $listen : "", 20), 3);
&ui_textbox($l, $mode == 3 ? $v : "", 40), 3);
}
print &ui_table_end();

View File

@@ -1,25 +1,25 @@
index_ecmd=Das Dovecot-Serverprogramm $1 wurde auf Ihrem System nicht gefunden. Möglicherweise ist es nicht installiert oder die <a href='$2'>Modulkonfiguration</a> ist falsch.
index_econf=Die Dovecot-Konfigurationsdatei $1 wurde auf Ihrem System nicht gefunden. Möglicherweise ist sie nicht installiert oder die <a href='$2'>Modulkonfiguration</a> ist falsch.
index_ecmd=Das Dovecot-Serverprogramm $1 wurde auf Ihrem System nicht gefunden. Möglicherweise ist es nicht installiert oder die <a href='$2'>Modulkonfiguration</a> ist fehlerhaft.
index_econf=Die Dovecot-Konfigurationsdatei $1 wurde auf Ihrem System nicht gefunden. Möglicherweise ist sie nicht installiert oder die <a href='$2'>Modulkonfiguration</a> ist fehlerhaft.
index_dovecot=Dovecot
index_stop=Dovecot-Server stoppen
index_stopdesc=Den laufenden Dovecot IMAP/POP3-Serverprozess herunterfahren. Dies verhindert, dass Benutzer ihre E-Mails herunterladen.
index_stopdesc=Beendet den laufenden Dovecot IMAP/POP3-Serverprozess. Dadurch wird verhindert, dass Benutzer:innen ihre E-Mails herunterladen können.
index_start=Dovecot-Server starten
index_startdesc=Den Dovecot IMAP/POP3-Serverprozess starten, damit Benutzer ihre E-Mails herunterladen können.
index_apply=Konfiguration anwenden
index_applydesc=Aktivieren Sie die aktuelle Dovecot-Konfiguration, indem Sie den Serverprozess stoppen und neu starten.
index_startdesc=Startet den Dovecot IMAP/POP3-Serverprozess, damit Benutzer:innen ihre E-Mails herunterladen können.
index_apply=Konfiguration übernehmen
index_applydesc=Aktiviert die aktuelle Dovecot-Konfiguration durch Stoppen und erneutes Starten des Serverprozesses.
index_boot=Beim Systemstart starten?
index_bootdesc=Ändern Sie diese Einstellung, um den Start des Dovecot-Servers beim Systemstart zu aktivieren oder zu deaktivieren.
index_return=Modulindex
index_version=Version $1
stop_err=Dovecot konnte nicht gestoppt werden
stop_erunning=Nicht mehr in Betrieb
stop_erunning=Nicht mehr aktiv
start_err=Dovecot konnte nicht gestartet werden
apply_err=Konfiguration konnte nicht angewendet werden
apply_err=Konfiguration konnte nicht übernommen werden
net_title=Netzwerk- und Protokolleinstellungen
net_header=Dovecot Netzwerk- und Mailprotokoll-Optionen
net_protocols=Zu bedienende Mail-Protokolle
net_title=Netzwerk und Protokolle
net_header=Netzwerk- und Mailprotokolloptionen für Dovecot
net_protocols=Bereitzustellende Mail-Protokolle
net_pop3=POP3
net_imap=IMAP
net_pop3s=POP3 (SSL)
@@ -29,136 +29,132 @@ net_ssl_disable=SSL-Verbindungen akzeptieren?
net_ssl_required=Nur SSL-Verbindungen akzeptieren
net_imap_listen=Schnittstellen für IMAP-Verbindungen
net_pop3_listen=Schnittstellen für POP3-Verbindungen
net_imaps_listen=Schnittstellen für IMAP SSL-Verbindungen
net_pop3s_listen=Schnittstellen für POP3 SSL-Verbindungen
net_listen=Schnittstellen für Nicht-SSL-Verbindungen
net_ssl_listen=Schnittstellen für SSL-Verbindungen
net_imaps_listen=Schnittstellen für IMAP-SSL-Verbindungen
net_pop3s_listen=Schnittstellen für POP3-SSL-Verbindungen
net_listen=Lauschen auf
net_listen0=Standard
net_listen1=Alle IPv4- und IPv6-Adressen
net_listen2=Alle IPv4-Adressen
net_listen4=Alle IPv6-Adressen
net_listen3=IP-Adresse
net_err=Netzwerkoptionen konnten nicht gespeichert werden
net_eimap_listen=Ungültige IP-Adresse für IMAP-Verbindungen
net_epop3_listen=Ungültige IP-Adresse für POP3-Verbindungen
net_eimaps_listen=Ungültige IP-Adresse für IMAP SSL-Verbindungen
net_epop3s_listen=Ungültige IP-Adresse für POP3 SSL-Verbindungen
net_elisten=Ungültige IP-Adresse für Nicht-SSL-Verbindungen
net_essl_listen=Ungültige IP-Adresse für SSL-Verbindungen
net_ealisten=Ungültige IP-Adresse für das Lauschen: <tt>$1</tt>
net_ealisten_invalid_mix=Eine einzelne IP-Adresse <tt>$1</tt> kann nicht zusammen mit dem Platzhalter <tt>$2</tt> verwendet werden. Geben Sie entweder einzelne IP-Adressen an oder verwenden Sie den Platzhalter, aber nicht beides.
imap_title=IMAP-Optionen
pop3_title=POP3-Optionen
ssl_title=SSL-Konfiguration
ssl_header=IMAP- und POP3-SSL-Modus-Optionen
ssl_key=SSL-Privatschlüsseldatei
ssl_cert=SSL-Zertifikatsdatei
ssl_ca=SSL-Client-CA-Zertifikatsdatei
ssl_header=SSL-Modus-Optionen für IMAP und POP3
ssl_key=Datei mit dem privaten SSL-Schlüssel
ssl_cert=SSL-Zertifikatdatei
ssl_ca=Zertifikatsdatei der SSL-Client-CA
ssl_pass=Passwort für Schlüsseldatei
ssl_prompt=Kein Passwort benötigt
ssl_regen=Intervall für SSL-Parameterregenerierung
ssl_prompt=Keines erforderlich
ssl_regen=Intervall für SSL-Parameterneuerstellung
ssl_hours=Stunden
ssl_none=Kein
ssl_plain=Nur Klartext-Authentifizierung im Nicht-SSL-Modus ablehnen?
ssl_plain=Klartextauthentifizierung im Nicht-SSL-Modus verbieten?
ssl_err=SSL-Konfiguration konnte nicht gespeichert werden
ssl_ekey=Fehlende oder nicht vorhandene Privatschlüsseldatei
ssl_ecert=Fehlende oder nicht vorhandene Zertifikatsdatei
ssl_eca=Fehlende oder nicht vorhandene Client-CA-Zertifikatsdatei
ssl_eregen=Fehlendes oder nicht-numerisches Parameter-Regenerierungsintervall
ssl_ekey=Fehlende oder nicht vorhandene Datei mit privatem Schlüssel
ssl_ecert=Fehlende oder nicht vorhandene Zertifikatdatei
ssl_eca=Fehlende oder nicht vorhandene Zertifikatsdatei der Client-CA
ssl_eregen=Fehlendes oder nicht-numerisches Intervall für Parameterneuerstellung
ssl_epass=Kein Passwort für die SSL-Schlüsseldatei eingegeben
misc_title=Sonstige Optionen
misc_title=Weitere Optionen
login_title=Benutzer- und Login-Optionen
login_header=Optionen für Benutzer-Authentifizierung und Login
login_fuid=Minimal gültige UID
login_luid=Maximal gültige UID
login_fgid=Minimal gültige Gruppen-ID
login_lgid=Maximal gültige Gruppen-ID
login_extra=Zusätzlich gewährte Sekundärgruppen
login_header=Benutzerauthentifizierung und Login-Einstellungen
login_fuid=Minimal zulässige UID
login_luid=Maximal zulässige UID
login_fgid=Minimal zulässige Gruppen-ID
login_lgid=Maximal zulässige Gruppen-ID
login_extra=Zusätzliche gewährte sekundäre Gruppen
login_none=Keine
login_chroot=Chroot-Verzeichnis für den Mail-Prozess
login_chroot=Chroot-Verzeichnis für Mail-Prozess
login_err=Benutzer- und Login-Optionen konnten nicht gespeichert werden
login_efuid=Fehlende oder ungültige numerische minimale UID
login_eluid=Fehlende oder ungültige numerische maximale UID
login_efgid=Fehlende oder ungültige numerische minimale Gruppen-ID
login_elgid=Fehlende oder ungültige numerische maximale Gruppen-ID
login_echroot=Fehlendes oder ungültiges Chroot-Verzeichnis
login_realms=SASL-Authentifizierungsdomänen
login_realm=Standard-Authentifizierungsdomäne
login_realms=SASL-Authentifizierungsbereiche
login_realm=Standard-Authentifizierungsbereich
login_mechs=Authentifizierungsmethoden
login_anonymous=Anonym
login_plain=Klartext
login_digest-md5=Digest-MD5
login_cram-md5=Cram-MD5
login_apop=APOP
login_otp=Einmaliges Passwort
login_otp=Einmalpasswort
login_skey=Sicherheitsschlüssel
login_oauthbearer=OAuth2-Token-Authentifizierung
login_xoauth2=Google OAuth2-Token-Authentifizierung
login_oauthbearer=OAuth2 Bearer-Authentifizierung
login_xoauth2=Google OAuth2 Bearer-Authentifizierung
login_external=Externe SASL-Authentifizierung
login_userdb=Datenquelle für Benutzer, Home-Verzeichnisse und IDs
login_userdb=Datenquelle für Benutzer:innen, Home-Verzeichnisse und IDs
login_passwd=Standard Unix-Benutzerdatenbank
login_passwdfile=Benutzerdefinierte Passwortdatei $1
login_static=Immer UID $1, GID $2 und Home-Verzeichnis $3 verwenden
login_vpopmail=VPOPMail-Bibliothek
login_ldap=LDAP, Konfigurationsdatei $1 verwenden
login_pgsql=PostgreSQL, Konfigurationsdatei $1 verwenden
login_sql=SQL-Datenbank, Konfigurationsdatei $1 verwenden
login_ldap=LDAP, Konfigurationsdatei $1
login_pgsql=PostgreSQL, Konfigurationsdatei $1
login_sql=SQL-Datenbank, Konfigurationsdatei $1
login_passdb=Passwort-Authentifizierungsquelle
login_passwd2=Unix <tt>passwd</tt>-Datei
login_shadow=Unix <tt>shadow</tt>-Datei
login_dpam=Standard PAM-Dienst (<tt>dovecot</tt>)
login_dpam=Standard-PAM-Dienst (<tt>dovecot</tt>)
login_pam=PAM-Dienst $1
login_session=PAM-Sitzungen öffnen und schließen
login_pam2=PAM-Dienst $1<br>&nbsp;&nbsp;$2<br>&nbsp;&nbsp;Verwenden Sie den Cache-Schlüssel $3
login_other=Andere Dovecot-Einstellung $1
login_pam2=PAM-Dienst $1<br>&nbsp;&nbsp;$2<br>&nbsp;&nbsp;Cache-Schlüssel $3 verwenden
login_other=Weitere Dovecot-Einstellung $1
login_epasswdfile=Fehlende oder nicht vorhandene benutzerdefinierte Passwortdatei
login_euid=Fehlende oder nicht numerische UID
login_egid=Fehlende oder nicht numerische GID
login_euid=Fehlende oder nicht-numerische UID
login_egid=Fehlende oder nicht-numerische GID
login_ehome=Fehlendes Home-Verzeichnis
login_eldap=Fehlende oder nicht vorhandene LDAP-Konfigurationsdatei
login_epgsql=Fehlende oder nicht vorhandene PostgreSQL-Konfigurationsdatei
login_esql=Fehlende oder nicht vorhandene SQL-Konfigurationsdatei
login_eppam=Fehlender oder ungültiger PAM-Dienst
login_bsdauth=BSD-Authentifizierung<br>&nbsp;&nbsp;Verwenden Sie den Cache-Schlüssel $1
login_bsdauth=BSD-Authentifizierung<br>&nbsp;&nbsp;Cache-Schlüssel $1 verwenden
login_checkpassword=Externes Programm $1
login_eckey=Fehlender oder ungültiger Cache-Schlüssel
login_echeckpassword=Fehlendes oder ungültiges externes Passwortprüfungsprogramm
login_procs=Maximale Login-Prozesse
login_count=Anfängliche Login-Prozesse
login_procs=Maximale Anzahl von Login-Prozessen
login_count=Initiale Login-Prozesse
login_eprocs=Fehlende oder ungültige maximale Anzahl von Login-Prozessen
login_ecount=Fehlende oder ungültige anfängliche Anzahl von Login-Prozessen
login_ecount=Fehlende oder ungültige initiale Anzahl von Login-Prozessen
mail_title=Mail-Dateien
mail_header=Mail-Speicherort und Leseoptionen
mail_env=Mail-Dateispeicherort
mail_header=Speicherort und Leseoptionen für E-Mails
mail_env=Speicherort der Mail-Dateien
mail_env0=Automatisch erkennen
mail_env1=Posteingang und Ordner in <tt>~/Maildir</tt>
mail_env2=Posteingang unter <tt>/var/mail</tt>, Ordner in <tt>~/mail</tt>
mail_env3=Posteingang in <tt>~/Maildir</tt>, Ordner in <tt>~/mail</tt>
mail_env4=Andere Dovecot-Position $1
mail_env4=Anderer Dovecot-Speicherort $1
mail_index=Speicherort der Index-Dateien
mail_index0=Standard (im Maildir-Verzeichnis)
mail_index1=Nur im Speicher
mail_index1=Nur im Arbeitsspeicher
mail_index2=Anderes Verzeichnis $1
mail_control=Speicherort der Steuerdateien
mail_check=Intervall zwischen Mail-Überprüfungen
mail_never=Niemals überprüfen
mail_check=Intervall für Mail-Prüfung
mail_never=Nie prüfen
mail_secs=Sekunden
mail_idle=Intervall zwischen Überprüfungen, wenn inaktiv
mail_idle=Intervall für Mail-Prüfung im Leerlauf
mail_full=Zugriff auf das gesamte Dateisystem erlauben?
mail_crlf=E-Mails mit CRLF-Zeilenenden speichern?
mail_change=Änderungen durch andere Programme verarbeiten?
mail_umask=Umask für neue Dateien
mail_err=Mail-Datei-Optionen konnten nicht gespeichert werden
mail_eenv=Fehlender oder ungültiger Mail-Speicherort
mail_echeck=Fehlende oder nicht-numerische Anzahl von Sekunden zwischen Überprüfungen
mail_eidle=Fehlende oder nicht-numerische Anzahl von Sekunden zwischen Überprüfungen im Leerlauf
mail_crlf=E-Mails mit CRLF-Zeilenumbrüchen speichern?
mail_change=Mail-Änderungen durch andere Programme berücksichtigen?
mail_umask=Umask-Berechtigungen für neue Dateien
mail_err=Mail-Dateioptionen konnten nicht gespeichert werden
mail_eenv=Fehlender oder ungültiger Speicherort für Mail-Dateien
mail_echeck=Fehlende oder nicht-numerische Anzahl von Sekunden zwischen Prüfungen
mail_eidle=Fehlende oder nicht-numerische Anzahl von Sekunden zwischen Prüfungen im Leerlauf
mail_eumask=Fehlende oder ungültige vierstellige oktale Umask
mail_uidl=UIDL-Format
mail_uidl_other=Andere..
mail_uidl_none=Nicht gesetzt (WARNUNG - Dovecot könnte nicht starten)
mail_uidl_other=Anderes..
mail_uidl_none=Nicht gesetzt (WARNUNG Dovecot startet eventuell nicht)
mail_uidl_dovecot=Altes Dovecot, neues Cyrus
mail_uidl_uw=UW ipop3d
mail_uidl_courier0=Courier Version 0
@@ -166,37 +162,37 @@ mail_uidl_courier1=Courier Version 1, altes Cyrus
mail_uidl_courier2=Courier Version 2
mail_uidl_tpop3d=tpop3d
mail_euidl=Fehlendes oder ungültiges UIDL-Format
mail_last=Verwendung des POP3 LAST-Befehls zulassen?
mail_lock=Methode zur Sperrung von Index-Dateien
mail_last=Verwendung des POP3-Befehls LAST erlauben?
mail_lock=Sperrmethode für Index-Dateien
mail_fcntl=fcntl-Funktion
mail_flock=flock-Funktion
mail_dotlock=.lock-Dateien
mail_lockf=lockf-Funktion
mail_mbox_read_locks=Sperrmethode für das Lesen von Mailboxen
mail_mbox_write_locks=Sperrmethode für das Schreiben von Mailboxen
mail_mbox_read_locks=Lesesperrmethode für Mailboxen
mail_mbox_write_locks=Schreibsperrmethode für Mailboxen
mail_none=Keine
mail_sel=Unten ausgewählt, in der Reihenfolge ..
mail_embox_read_locks=Keine Sperrmethode für das Lesen ausgewählt
mail_embox_write_locks=Keine Sperrmethode für das Schreiben ausgewählt
mail_eindexmode=Der Speicherort der Indexdateien kann nicht festgelegt werden, wenn der Mail-Speicherort automatisch erkannt wird
mail_econtrolmode=Der Speicherort der Steuerdateien kann nicht festgelegt werden, wenn der Mail-Speicherort automatisch erkannt wird
mail_sel=Unten ausgewählt, in Reihenfolge ..
mail_embox_read_locks=Keine Lesesperrmethode ausgewählt
mail_embox_write_locks=Keine Schreibsperrmethode ausgewählt
mail_eindexmode=Der Speicherort der Index-Dateien kann nicht gesetzt werden, wenn der Speicherort der Mail-Dateien automatisch erkannt wird
mail_econtrolmode=Der Speicherort der Steuerdateien kann nicht gesetzt werden, wenn der Speicherort der Mail-Dateien automatisch erkannt wird
mail_eindex=Fehlender oder ungültiger absoluter Pfad für Index-Dateien
mail_econtrol=Fehlender oder ungültiger absoluter Pfad für Steuerdateien
log_net=Netzwerk- und Protokolleinstellungen geändert
log_net=Netzwerk und Protokolle geändert
log_login=Benutzer- und Login-Optionen geändert
log_mail=Mail-Dateien geändert
log_ssl=SSL-Konfiguration geändert
log_apply=Konfiguration angewendet
log_apply=Konfiguration übernommen
log_start=Dovecot-Server gestartet
log_stop=Dovecot-Server gestoppt
log_bootup=Dovecot beim Systemstart aktiviert
log_bootdown=Dovecot beim Systemstart deaktiviert
log_manual=Konfigurationsdatei $1 manuell bearbeitet
log_manual=Konfigurationsdatei manuell bearbeitet: $1
manual_title=Konfigurationsdateien bearbeiten
manual_editsel=Dovecot-Konfigurationsdatei bearbeiten
manual_err=Konfigurationsdatei konnte nicht gespeichert werden
manual_edata=Nichts eingegeben!
manual_efile=Ausgewählte Konfigurationsdatei ist nicht gültig
manual_edata=Keine Eingabe erfolgt!
manual_efile=Ausgewählte Konfigurationsdatei ist ungültig
manual_ok=Bearbeiten

View File

@@ -31,19 +31,15 @@ net_imap_listen=Interfaces for IMAP connections
net_pop3_listen=Interfaces for POP3 connections
net_imaps_listen=Interfaces for IMAP SSL connections
net_pop3s_listen=Interfaces for POP3 SSL connections
net_listen=Interfaces for non-SSL connections
net_ssl_listen=Interfaces for SSL connections
net_listen=Listen on
net_listen0=Default
net_listen1=All IPv4 and IPv6
net_listen2=All IPv4
net_listen4=All IPv6
net_listen3=IP address
net_err=Failed to save networking options
net_eimap_listen=Invalid IP address for IMAP connections
net_epop3_listen=Invalid IP address for POP3 connections
net_eimaps_listen=Invalid IP address for IMAP SSL connections
net_epop3s_listen=Invalid IP address for POP3 SSL connections
net_elisten=Invalid IP address for non-SSL connections
net_essl_listen=Invalid IP address for SSL connections
net_ealisten=Invalid IP address to listen on : <tt>$1</tt>
net_ealisten_invalid_mix=Cannot use an individual IP address <tt>$1</tt> together with the <tt>$2</tt> wildcard. Specify either specific IP addresses or use the wildcard, not both
imap_title=IMAP Options

View File

@@ -12,20 +12,50 @@ $sslopt = &find("ssl_disable", $conf, 2) ? "ssl_disable" : "ssl";
&save_directive($conf, $sslopt, $in{$sslopt} eq '' ? undef : $in{$sslopt});
@listens = &find("imap_listen", $conf, 2) ?
("imap_listen", "pop3_listen", "imaps_listen", "pop3s_listen") :
("listen", "ssl_listen");
("listen");
foreach $l (@listens) {
if ($in{$l."_mode"} == 0) {
$listen = undef;
}
elsif ($in{$l."_mode"} == 1) {
$listen = "[::]";
$listen = "*, ::";
}
elsif ($in{$l."_mode"} == 2) {
$listen = "*";
}
elsif ($in{$l."_mode"} == 4) {
$listen = "::";
}
elsif ($in{$l."_mode"} == 3) {
&check_ipaddress($in{$l}) || &error($text{'net_e'.$l});
$listen = $in{$l};
# Check each IP address
my @ips_list = split(/[\s,]+/, $in{$l});
my @ips_valid;
my $has_ip4_wildcard = grep { $_ eq "*" } @ips_list;
my $has_ip6_wildcard = grep { /^(\[::\]|::)$/ } @ips_list;
foreach my $ip (@ips_list) {
# Check for wildcards
if ($ip =~ /^(\*|::|\[::\])$/) {
push(@ips_valid, $ip);
next;
}
# Validate IP address
my $is_ipv4 = &check_ipaddress($ip);
my $is_ipv6 = &check_ip6address($ip);
if (!$is_ipv4 && !$is_ipv6) {
&error(&text("net_ealisten", $ip));
}
# Add IP address to list
push(@ips_valid, $ip);
# Validate against wildcards
&error(&text("net_ealisten_invalid_mix", $ip, "*"))
if ($has_ip4_wildcard && &check_ipaddress($ip));
&error(&text("net_ealisten_invalid_mix", $ip, "::"))
if ($has_ip6_wildcard && &check_ip6address($ip));
}
$listen = join(", ", @ips_valid) if (@ips_valid);
}
&save_directive($conf, $l, $listen);
}

View File

@@ -1,3 +1,3 @@
allowed_paths=$HOME
work_as_root=1
allowed_for_edit=application-x-php application-x-ruby application-xml application-xslt+xml application-javascript application-x-shellscript application-x-perl application-x-yaml application-json application-x-x509-ca-cert application-pkix-cert application-x-sql application-x-asp application-x-aspx application-xhtml+xml
allowed_for_edit=application-x-php application-x-ruby application-xml application-xslt+xml application-javascript application-x-shellscript application-x-perl application-x-yaml application-x-toml application-json application-x-x509-ca-cert application-pkix-cert application-x-sql application-x-asp application-x-aspx application-xhtml+xml

View File

@@ -141,6 +141,12 @@ if (($table->{'name'} eq 'nat' && $rule->{'chain'} ne 'POSTROUTING') &&
$dpfrom = $2;
$dpto = $4;
}
elsif (&check_ipvx_ipaddress($rule->{'to-destination'}->[1])) {
$dipfrom = $rule->{'to-destination'}->[1];
$dipto = "";
$dpfrom = "";
$dpto = "";
}
}
print &ui_table_row($text{'edit_dnat'},
&ui_radio("dnatdef", $dipfrom eq "" ? 1 : 0,

View File

@@ -39,7 +39,7 @@ else {
"icmp6-addr-unreachable", "icmp6-port-unreachable",
"echo-reply", "tcp-reset" );
$ipvx_todestpattern='^\[([0-9A-Fa-f:]+)](\-([0-9A-Fa-f:]+))?(:(\d+)(\-(\d+))?)?$';
$ipvx_todestpattern='^\[([0-9A-Fa-f:]+)\](\-([0-9A-Fa-f:]+))?(:(\d+)(\-(\d+))?)?$';
# set IP Version
&set_ipvx_version('ipv6');

145
forgot.cgi Executable file
View File

@@ -0,0 +1,145 @@
#!/usr/local/bin/perl
# Linked to from the forgotten password email
BEGIN { push(@INC, "."); };
use WebminCore;
$no_acl_check++;
$trust_unknown_referers = 1;
&init_config();
&ReadParse();
&load_theme_library();
&error_setup($text{'forgot_err'});
$gconfig{'forgot_pass'} || &error($text{'forgot_ecannot'});
&theme_forgot_handler($0) if (defined(&theme_forgot_handler));
my $forgot_timeout = 10;
$remote_user && &error($text{'forgot_elogin'});
# Check that the random ID is valid
$in{'id'} =~ /^[a-f0-9]+$/i || &error($text{'forgot_eid'});
my %link;
&read_file("$main::forgot_password_link_dir/$in{'id'}", \%link) ||
&error($text{'forgot_eid2'});
time() - $link{'time'} > 60*$forgot_timeout &&
&error(&text('forgot_etime', $forgot_timeout));
# Get the Webmin user
&foreign_require("acl");
my ($wuser) = grep { $_->{'name'} eq $link{'user'} } &acl::list_users();
$wuser || &error(&text('forgot_euser2',
"<tt>".&html_escape($link{'user'})."</tt>"));
&ui_print_header(undef, $text{'forgot_title'}, "", undef, undef, 1, 1);
if (defined($in{'newpass'})) {
# Validate the password
$in{'newpass'} =~ /\S/ || &error($text{'forgot_enewpass'});
$in{'newpass'} eq $in{'newpass2'} ||
&error($text{'forgot_enewpass2'});
my $perr = &acl::check_password_restrictions(
$wuser->{'name'}, $in{'newpass'});
$perr && &error(&text('forgot_equality', $perr));
# Actually update the password
my $d;
if (&foreign_check("virtual-server")) {
# Is this a Virtualmin domain owner?
&foreign_require("virtual-server");
$d = &virtual_server::get_domain_by("user", $link{'user'},
"parent", "");
$d && $d->{'disabled'} && &error($text{'forgot_edisabled'});
}
if ($d) {
# Update in Virtualmin
print &text('forgot_vdoing',
&virtual_server::show_domain_name($d)),"<br>\n";
&virtual_server::push_all_print();
&virtual_server::set_all_null_print();
foreach my $d (&virtual_server::get_domain_by("user", $link{'user'})) {
&virtual_server::lock_domain($d);
my $oldd = { %$d };
$d->{'pass'} = $in{'newpass'};
$d->{'pass_set'} = 1;
&virtual_server::generate_domain_password_hashes($d, 0);
# Update all features
foreach my $f (&virtual_server::domain_features($d)) {
if ($virtual_server::config{$f} && $d->{$f}) {
my $mfunc = "virtual_server::modify_".$f;
&$mfunc($d, $oldd);
}
}
# Update all plugins
foreach my $f (&virtual_server::list_feature_plugins()) {
if ($d->{$f}) {
&virtual_server::plugin_call(
$f, "feature_modify", $d, $oldd);
}
}
&virtual_server::save_domain($d);
&virtual_server::unlock_domain($d);
}
&virtual_server::run_post_actions();
&virtual_server::pop_all_print();
print $text{'forgot_done'},"<p>\n";
}
elsif ($wuser->{'pass'} eq 'x') {
# Update in Users and Groups
print &text('forgot_udoing',
"<tt>".&html_escape($link{'user'})."</tt>"),"<br>\n";
&foreign_require("useradmin");
my ($user) = grep { $_->{'user'} eq $link{'user'} }
&useradmin::list_users();
$user || &error($text{'forgot_eunix'});
$user->{'pass'} eq $useradmin::config{'lock_string'} &&
&error($text{'forgot_eunixlock'});
my $olduser = { %$user };
$user->{'name'} = $link{'user'};
$user->{'passmode'} = 3;
$user->{'plainpass'} = $in{'newpass'};
$user->{'pass'} = &useradmin::encrypt_password($in{'newpass'},
undef, 1);
&useradmin::modify_user($olduser, $user);
&useradmin::other_modules("useradmin_modify_user", $user,
$olduser);
&reload_miniserv();
print $text{'forgot_done'},"<p>\n";
}
else {
# Update in Webmin
print &text('forgot_wdoing',
"<tt>".&html_escape($link{'user'})."</tt>"),"<br>\n";
$wuser->{'pass'} = &acl::encrypt_password($in{'newpass'});
&acl::modify_user($wuser->{'name'}, $wuser);
&reload_miniserv();
print $text{'forgot_done'},"<p>\n";
}
print &text('forgot_retry', '/'),"<p>\n";
&webmin_log("forgot", "reset", undef,
{ 'user' => $wuser->{'name'},
'email' => $wuser->{'email'} }, "acl");
&unlink_file("$main::forgot_password_link_dir/$in{'id'}");
}
else {
# Show password selection form
print "<center>\n";
print &ui_form_start("forgot.cgi", "post");
print &ui_hidden("id", $in{'id'});
print &ui_table_start(undef, undef, 2);
print &ui_table_row(
&text('forgot_newpass',
"<tt>".&html_escape($link{'user'})."</tt>"),
&ui_password("newpass", undef, 30));
print &ui_table_row(
$text{'forgot_newpass2'},
&ui_password("newpass2", undef, 30));
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'forgot_passok'} ] ]);
print "</center>\n";
}
&ui_print_footer();

27
forgot_form.cgi Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/local/bin/perl
# Display the forgotten password form
BEGIN { push(@INC, "."); };
use WebminCore;
$no_acl_check++;
&init_config();
&ReadParse();
&load_theme_library();
&error_setup($text{'forgot_err'});
$gconfig{'forgot_pass'} || &error($text{'forgot_ecannot'});
&theme_forgot_handler($0) if (defined(&theme_forgot_handler));
$remote_user && &error($text{'forgot_elogin'});
&ui_print_header(undef, $text{'forgot_title'}, "", undef, undef, 1, 1);
print "<center>\n";
print $text{'forgot_desc'},"<p>\n";
print &ui_form_start("forgot_send.cgi", "post");
print "<b>$text{'forgot_user'}</b>\n",
&ui_textbox("forgot", $in{'failed'}, 40),"<br>\n";
print &ui_form_end([ [ undef, $text{'forgot_ok'} ] ]);
print "</center>\n";
&ui_print_footer();

140
forgot_send.cgi Executable file
View File

@@ -0,0 +1,140 @@
#!/usr/local/bin/perl
# Send a forgotten password reset email
BEGIN { push(@INC, "."); };
use WebminCore;
$no_acl_check++;
&init_config();
&ReadParse();
&load_theme_library();
&error_setup($text{'forgot_err'});
$gconfig{'forgot_pass'} || &error($text{'forgot_ecannot'});
&theme_forgot_handler($0) if (defined(&theme_forgot_handler));
$remote_user && &error($text{'forgot_elogin'});
# Lookup the Webmin user
&foreign_require("acl");
my ($wuser) = grep { lc($_->{'name'}) eq lc($in{'forgot'}) } &acl::list_users();
my $email = $wuser ? $wuser->{'email'} : undef;
# Check if the IP or Webmin user is over it's rate limit
&make_dir($main::forgot_password_link_dir, 0700);
my $ratelimit_file = $main::forgot_password_link_dir."/ratelimit";
&lock_file($ratelimit_file);
my %ratelimit;
&read_file($ratelimit_file, \%ratelimit);
my $now = time();
my $rlerr;
my $maxtries = 0;
foreach my $key ($ENV{'REMOTE_ADDR'},
$wuser ? ( $wuser->{'name'} ) : ( ),
$email ? ( $email ) : ( )) {
if (!$ratelimit{$key."_last"} ||
$ratelimit{$key."_last"} < $now-5*60) {
# More than 5 mins since the last try, so reset counter
$ratelimit{$key} = 1;
}
else {
$ratelimit{$key}++;
}
$maxtries = $ratelimit{$key} if ($ratelimit{$key} > $maxtries);
$ratelimit{$key."_last"} = $now;
if ($ratelimit{$key} > 10) {
# More than 10 attempts in the last 5 minutes!
$rlerr = &text('forgot_erate',
"<tt>".&html_escape($key)."</tt>");
last;
}
}
# Clean up old ratelimit entries
my $cutoff = $now - 24*60*60;
my @cleanup;
foreach my $k (keys %ratelimit) {
if ($k =~ /^(.*)_last$/ && $ratelimit{$k} < $cutoff) {
push(@cleanup, $k);
push(@cleanup, $1);
}
}
foreach my $k (@cleanup) {
delete($ratelimit{$k});
}
&write_file($ratelimit_file, \%ratelimit);
&unlock_file($ratelimit_file);
sleep($maxtries);
&error($rlerr) if ($rlerr);
# Make sure the Webmin user exists and is eligible for a reset
$wuser && $wuser->{'email'} || &error($text{'forgot_euser'});
($wuser->{'sync'} || $wuser->{'pass'} eq 'e') && &error($text{'forgot_esync'});
$wuser->{'pass'} eq '*LK*' && &error($text{'forgot_elock'});
# Generate a random ID for this password reset
my %link = ( 'id' => &generate_random_id(),
'remote' => $ENV{'REMOTE_ADDR'},
'time' => $now,
'user' => $wuser->{'name'} );
$link{'id'} || &error($text{'forgot_erandom'});
&write_file("$main::forgot_password_link_dir/$link{'id'}", \%link);
my $baseurl = &get_webmin_email_url();
my $url = $baseurl.'/forgot.cgi?id='.&urlize($link{'id'});
$url = &theme_forgot_url($baseurl, $link{'id'}, $link{'user'})
if (defined(&theme_forgot_url));
&ui_print_header(undef, $text{'forgot_title'}, "", undef, undef, 1, 1);
# Send email with a link to generate the reset form
&foreign_require("mailboxes");
my $msg = &text('forgot_msg', $wuser->{'name'}, $url, $ENV{'REMOTE_HOST'},
$baseurl);
$msg =~ s/\\n/\n/g;
$msg = join("\n", &mailboxes::wrap_lines($msg, 75))."\n";
my $subject = &text('forgot_subject', $wuser->{'name'});
&mailboxes::send_text_mail(&mailboxes::get_from_address(),
$email,
undef,
$subject,
$msg);
# Tell the user
print "<center>\n";
print &text('forgot_sent',
"<tt>".&html_escape(&obsfucate_email($email))."</tt>",
"<tt>".&html_escape($wuser->{'name'})."</tt>"),"\n";
print "</center>\n";
&webmin_log("forgot", "send", undef,
{ 'user' => $wuser->{'name'},
'email' => $email }, "acl");
&ui_print_footer();
# generate_random_id()
# Generate an ID string that can be used for a password reset link
sub generate_random_id
{
if (open(my $RANDOM, "</dev/urandom")) {
my $sid;
my $tmpsid;
if (read($RANDOM, $tmpsid, 16) == 16) {
$sid = lc(unpack('h*',$tmpsid));
}
close($RANDOM);
return $sid;
}
return undef;
}
# obsfucate_email(email)
# Convert an email like foo@bar.com to f**@b**.com
sub obsfucate_email
{
my ($email) = @_;
my ($mailbox, $dom) = split(/\@/, $email);
$mailbox = substr($mailbox, 0, 1) . ("*" x (length($mailbox)-1));
my @doms;
foreach my $d (split(/\./, $dom)) {
push(@doms, substr($d, 0, 1) . ("*" x (length($d)-1)));
}
return $mailbox."\@".join(".", @doms);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -10,24 +10,41 @@ use WebminCore;
$ENV{'PATH_INFO'} !~ /[\\\&\;\`\'\"\|\*\?\~\<\>\^\(\)\[\]\{\}\$\n\r]/ ||
&error($text{'help_epath'});
$ENV{'PATH_INFO'} =~ /^\/(\S+)\/(\S+)$/ || &error($text{'help_epath'});
$module = $1; $file = $2;
my $module = $1;
my $file = $2;
&ReadParse();
# if it ends with .gif assume it is a direct URL
if ($file =~ /\.(gif|jpg|jpeg|png)$/i) {
&redirect("$module/$file");
exit;
}
return;
}
# read the help file
$help = &read_help_file($module, $file);
my $help = &read_help_file($module, $file);
$help || &helperror(&text('help_efile3',
&html_escape($file), &html_escape($module)));
my %hash;
# Modify help file based on module
if (&foreign_exists($module) &&
&foreign_require($module) &&
&foreign_defined($module, 'help_pre_load')) {
$help = &foreign_call($module, "help_pre_load", $help);
&foreign_require($module)) {
if (&foreign_defined($module, 'help_pre_load')) {
$help = &foreign_call($module, "help_pre_load", $help);
}
if (&foreign_defined($module, 'help_template')) {
%hash = &foreign_call($module, "help_template");
}
}
# if any template variables were given as URL params, substitute them into the file
foreach my $k (keys %in) {
if ($k =~ /^tmpl_(\S+)$/i) {
$hash{$1} = $in{$k};
}
}
if (%hash) {
$help = &substitute_template($help, \%hash);
}
# find and replace the <header> section

28
lang/de
View File

@@ -144,6 +144,32 @@ session_twofailed=Zwei-Faktor-Authentifizierung fehlgeschlagen: $1
session_logout=Abmeldung erfolgreich. Verwenden Sie das untenstehende Formular, um sich erneut anzumelden.
session_timed_out=Sitzung nach $1 Minuten Inaktivität abgelaufen.
session_save=Login dauerhaft speichern?
session_forgot=Passwort vergessen?
forgot_title=Zurücksetzen eines vergessenen Passworts
forgot_user=Webmin-Benutzer:innenname:
forgot_desc=Wenn Ihr Webmin-Login mit einer Wiederherstellungs-E-Mail-Adresse verknüpft ist, können Sie auf dieser Seite einen Link anfordern, um das Passwort zurückzusetzen.
forgot_ok=Link zum Zurücksetzen des Passworts senden
forgot_ecannot=Die Wiederherstellung vergessener Passwörter ist nicht aktiviert!
forgot_euser=Der Benutzer:innenname existiert entweder nicht oder es ist keine Wiederherstellungs-E-Mail-Adresse konfiguriert.
forgot_msg=Sie erhalten diese E-Mail aufgrund einer Anfrage zur Passwortwiederherstellung im Webmin-System auf $4 von $3 für den Login $1.\n\nWenn Sie das Passwort zurücksetzen möchten, folgen Sie diesem Link:\n$2
forgot_subject=Webmin Passwort-Zurücksetzung
forgot_sent=Ein Link zum Zurücksetzen des Webmin-Passworts für den Login $2 wurde an die Wiederherstellungs-E-Mail-Adresse $1 gesendet.
forgot_erandom=Zufällige ID konnte nicht generiert werden!
forgot_eid=Fehlende oder ungültig aussehende Zurücksetz-ID!
forgot_eid2=Die Zurücksetz-ID ist ungültig!
forgot_etime=Die E-Mail zur Passwort-Zurücksetzung ist älter als $1 Minuten.
forgot_newpass=Geben Sie ein neues Passwort für Webmin-Benutzer:in $1 ein:
forgot_passok=Passwort ändern
forgot_euser2=Webmin-Benutzer:in $1 existiert nicht!
forgot_esync=Das Passwort kann für diese:n Benutzer:in nicht geändert werden
forgot_elock=Das Passwort für diese:n Benutzer:in ist gesperrt
forgot_err=Passwortänderung fehlgeschlagen
forgot_enewpass=Kein neues Passwort eingegeben!
forgot_equality=Die Passwortanforderungen wurden nicht erfüllt: $1
forgot_wdoing=Ändere Passwort für Webmin-Benutzer:in $1 ..
forgot_done=.. Passwortänderung abgeschlossen.
forgot_retry=Sie können sich nun mit Ihrem neuen Passwort <a href='$1'>bei Webmin anmelden</a>.
pam_header=Bei Webmin anmelden
pam_mesg=Sie müssen die untenstehende Frage beantworten, um sich beim Webmin-Server auf $1 anzumelden.
@@ -267,7 +293,7 @@ progress_size2=Herunterladen von $1 ($2) ..
progress_nosize=Herunterladen von $1 ..
progress_datan=Empfangen von $1 ($2 %)
progress_data2n=Empfangen von $1
progress_done=.. Download abgeschlossen.
progress_done=.. Download abgeschlossen
progress_incache=Gefunden $1 im Cache ..
readparse_cdheader=Fehlender Content-Disposition Header

37
lang/en
View File

@@ -144,6 +144,41 @@ session_twofailed=Two-factor authentication failed : $1
session_logout=Logout successful. Use the form below to login again.
session_timed_out=Session timed out after $1 minutes of inactivity.
session_save=Remember login permanently?
session_forgot=Forgot Password?
forgot_title=Reset Forgotten Password
forgot_user=Webmin username:
forgot_desc=If your Webmin login has a recovery email address associated with it, you can use this page to send a link that can be used to reset the password.
forgot_ok=Send Password Reset Link
forgot_ecannot=Forgotten password recovery is not enabled!
forgot_euser=The username either does not exist or does not have a recovery email configured.
forgot_msg=You are receiving this email due to a request for password recovery from the Webmin system at $4 from $3, for the login $1.\n\nIf you would like to proceed with resetting the password, follow this link :\n$2
forgot_subject=Webmin password reset for $1
forgot_sent=A link to reset your Webmin password for login $2 has been sent to the recovery email address $1.
forgot_erandom=Failed to generate random ID!
forgot_eid=Missing or invalid-looking reset ID!
forgot_eid2=Reset ID is not valid!
forgot_etime=Password reset email is more than $1 minutes old.
forgot_newpass=New password for Webmin user $1
forgot_newpass2=New password again
forgot_passok=Change Password
forgot_euser2=Webmin user $1 does not exist!
forgot_esync=The password cannot be changed for this user
forgot_elock=The password for this user is locked
forgot_err=Failed to reset password
forgot_enewpass=No new password entered!
forgot_enewpass2=New passwords do not match!
forgot_equality=Password requirements were not met : $1
forgot_wdoing=Changing password for Webmin user $1 ..
forgot_done=.. password change complete.
forgot_retry=You can now <a href='$1'>login to Webmin</a> using your new password.
forgot_edisabled=The password for a disabled Virtualmin domain cannot be reset
forgot_vdoing=Changing password for Virtualmin domain $1 ..
forgot_udoing=Changing password for Unix user $1 ..
forgot_eunix=Unix user does not exist!
forgot_eunixlock=User user's password is locked!
forgot_elogin=Forgotted password pages cannot be used when you are already logged in to Webmin!
forgot_erate=Too many password reset attempts for $1! Please try again later.
pam_header=Login to Webmin
pam_mesg=You must respond to the question below to login to Webmin server on $1.
@@ -267,7 +302,7 @@ progress_size2=Downloading $1 ($2) ..
progress_nosize=Downloading $1 ..
progress_datan=Received $1 ($2 %)
progress_data2n=Received $1
progress_done=.. download complete.
progress_done=.. download complete
progress_incache=Found $1 in cache ..
readparse_cdheader=Missing Content-Disposition header

View File

@@ -9,7 +9,7 @@ use WebminCore;
&init_config();
&ReadParse();
&switch_to_remote_user();
&webmin_user_is_admin() or &switch_to_remote_user();
do "./xhr-lib.pl";
xhr();

View File

@@ -60,7 +60,8 @@ $vers || usage();
"webmin-search-lib.pl", "WebminCore.pm",
"record-login.pl", "record-logout.pl", "record-failed.pl",
"robots.txt", "unauthenticated", "bin", "html-editor-lib.pl",
"switch_theme.cgi", "os_eol.json",
"switch_theme.cgi", "os_eol.json", "forgot_form.cgi",
"forgot_send.cgi", "forgot.cgi",
);
if ($min) {
# Only those required by others
@@ -247,7 +248,6 @@ if (-d "/home/jcameron/webmin.com" && (!$release || $release == 1)) {
# this is a new full version, so round down to the previous full version
$lastvers = sprintf("%.2f0", $vers-0.006);
}
system("./showchangelog.pl --html $lastvers >/home/jcameron/webmin.com/changes-$vers.html");
}
if ($min && !$release) {
@@ -259,12 +259,13 @@ if ($min && !$release) {
# Fill an associative array with name=value pairs from a file
sub read_file
{
open(ARFILE, $_[0]) || return 0;
my ($file, $data_hash, $order) = @_;
open(ARFILE, $file) || return 0;
while(<ARFILE>) {
chop;
if (!/^#/ && /^([^=]+)=(.*)$/) {
$_[1]->{$1} = $2;
push(@{$_[2]}, $1);
$data_hash->{$1} = $2;
push(@$order, $1) if ($order);
}
}
close(ARFILE);
@@ -275,11 +276,20 @@ return 1;
# Write out the contents of an associative array as name=value lines
sub write_file
{
local($arr);
$arr = $_[1];
open(ARFILE, "> $_[0]");
foreach $k (keys %$arr) {
print ARFILE "$k=$$arr{$k}\n";
my ($file, $data_hash) = @_;
my (%old, @order);
&read_file($file, \%old, \@order);
open(ARFILE, ">$file");
my %done;
foreach my $k (@order) {
if (exists($data_hash->{$k}) && !$done{$k}++) {
print ARFILE $k,"=",$data_hash->{$k},"\n";
}
}
foreach $k (keys %$data_hash) {
if (!exists($old{$k}) && !$done{$k}++) {
print ARFILE $k,"=",$data_hash->{$k},"\n";
}
}
close(ARFILE);
}

View File

@@ -24,9 +24,6 @@ my $copyright_file = "$debian_dir/copyright";
my $changelog_file = "$debian_dir/changelog";
my $files_file = "$debian_dir/files";
-r "/etc/debian_version" ||
die RED, "makemoduledeb.pl must be run on Debian", RESET;
# Parse command-line args
my ($force_theme, $url, $upstream, $provides, $debdepends, $debrecommends,
$no_prefix, $force_usermin, $release, $allow_overwrite, $final_mod,

View File

@@ -33,7 +33,10 @@ SECT: foreach $sec (@sects) {
$cmd = $ocmd;
$cmd =~ s/PAGE/$qpage/;
$cmd =~ s/SECTION/$qsec/;
$out = &backquote_command("$cmd 2>&1", 1);
if ($< == 0) {
$cmd = &command_as_user("nobody", 0, $cmd);
}
$out = &backquote_command($cmd." 2>&1", 1);
if ($out !~ /^.*no manual entry/i && $out !~ /^.*no entry/i &&
$out !~ /^.*nothing appropriate/i) {
# Found it

View File

@@ -1842,13 +1842,16 @@ if ($config{'session'} && !$deny_authentication &&
&http_error(500, "Invalid password",
"Password contains invalid characters");
}
local $twofactor_probe = 0;
local ($vu, $expired, $nonexist, $wvu) =
&validate_user_caseless($in{'user'}, $in{'pass'}, $host,
$acptip, $port);
if ($vu && $wvu) {
my $uinfo = &get_user_details($wvu, $vu);
if ($uinfo && $uinfo->{'twofactor_provider'}) {
my $can2fa = $uinfo && $uinfo->{'twofactor_provider'};
$twofactor_probe = 1 if ($in{'twofprobe'} && $can2fa);
if ($can2fa && !$twofactor_probe) {
# Check two-factor token ID
$err = &validate_twofactor(
$wvu, $in{'twofactor'}, $vu);
@@ -1857,7 +1860,8 @@ if ($config{'session'} && !$deny_authentication &&
$vu, 'twofactor',
$loghost, $localip);
$twofactor_msg = $err;
$twofactor_nolog = 'nolog' if (!$in{'twofactor'});
$twofactor_nolog = 'nolog'
if (!$in{'twofactor'});
$vu = undef;
}
}
@@ -1865,7 +1869,8 @@ if ($config{'session'} && !$deny_authentication &&
local $hrv = &handle_login(
$vu || $in{'user'}, $vu ? 1 : 0,
$expired, $nonexist, $in{'pass'},
$in{'notestingcookie'}, $twofactor_nolog);
$in{'notestingcookie'}, $twofactor_nolog,
$twofactor_probe);
return $hrv if (defined($hrv));
}
}
@@ -2052,13 +2057,16 @@ if (!$validated) {
if (!$validated) {
# Check if this path allows unauthenticated access
local ($u, $unauth);
foreach $u (@unauth) {
$unauth++ if ($simple =~ /$u/);
my $unauth;
foreach my $u (@unauth) {
$unauth = 4 if ($simple =~ /$u/);
}
foreach my $u (@unauthcgi) {
$unauth = 3 if ($simple =~ /$u/);
}
if (!$bogus && $unauth) {
# Unauthenticated directory or file request - approve it
$validated = 4;
$validated = $unauth;
$baseauthuser = $authuser = undef;
}
}
@@ -2098,12 +2106,8 @@ if (!$validated) {
$method = "GET";
$querystring .= "&failed=".&urlize($failed_user)
if ($failed_user);
if ($twofactor_msg) {
$querystring .= "&failed_save=".&urlize($failed_save);
$querystring .= "&failed_pass=".&urlize($failed_pass);
$querystring .= "&failed_twofactor_attempt=".&urlize($failed_twofactor_attempt);
$querystring .= "&twofactor_msg=".&urlize($twofactor_msg);
}
$querystring .= "&twofactor_msg=".&urlize($twofactor_msg)
if ($twofactor_msg);
$querystring .= "&timed_out=$timed_out"
if ($timed_out);
$queryargs = "";
@@ -4240,11 +4244,12 @@ if (!$sid && !$force_urandom) {
return $sid;
}
# handle_login(username, ok, expired, not-exists, password, [no-test-cookie], [no-log])
# handle_login(username, ok, expired, not-exists, password,
# [no-test-cookie], [no-log], [twofactor-probe])
# Called from handle_session to either mark a user as logged in, or not
sub handle_login
{
local ($vu, $ok, $expired, $nonexist, $pass, $notest, $nolog) = @_;
local ($vu, $ok, $expired, $nonexist, $pass, $notest, $nolog, $twof_probe) = @_;
$authuser = $vu if ($ok);
# check if the test cookie is set
@@ -4268,6 +4273,19 @@ if ($config{'passdelay'} && $vu) {
if ($ok && (!$expired ||
$config{'passwd_mode'} == 1)) {
# Log in creds were OK but two-factor auth is still pending
if ($twof_probe) {
# Two-factor auth is required
$validated = $already_session_id = undef;
$authuser = $baseauthuser = undef;
$querystring = $method = $page = $request_uri = undef;
$logged_code = undef;
$queryargs = "";
# Write response
&http_error(401, "Two-factor authentication is required");
return undef;
}
# Logged in OK! Tell the main process about
# the new SID
local $sid = &generate_random_id();
@@ -4349,10 +4367,7 @@ else {
$expired ? 'expiredpass' : 'wrongpass',
$loghost, $localip);
$failed_user = $vu;
$failed_pass = $pass;
$failed_save = $in{'save'};
$failed_twofactor_attempt = $in{'failed_twofactor_attempt'} || 0;
$failed_twofactor_attempt++;
$request_uri = $in{'page'};
$already_session_id = undef;
$method = "GET";
@@ -4915,6 +4930,7 @@ my %vital = ("port", 80,
"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\$ ^/service-worker.js\$",
"unauthcgi", "^/forgot_form.cgi\$ ^/forgot_send.cgi\$ ^/forgot.cgi\$",
"max_post", 10000,
"expires", 7*24*60*60,
"pam_test_user", "root",
@@ -5400,6 +5416,7 @@ foreach my $a (split(/\s+/, $config{'ipaccess'})) {
# build unauthenticated URLs list
@unauth = split(/\s+/, $config{'unauth'});
@unauthcgi = split(/\s+/, $config{'unauthcgi'});
# build redirect mapping
undef(%redirect);

View File

@@ -63,10 +63,15 @@ my $plugin = $fieldmap{'plugin'};
my $unixsocket = $plugin && $u->[$plugin] eq 'unix_socket';
my $nopass = ((!defined($epassfield1) || !$u->[$epassfield1]) &&
(!defined($epassfield2) || !$u->[$epassfield2]));
my $hashpass = $u->[$epassfield1] || $u->[$epassfield2];
my $lock_supported = exists($fieldmap{'account_locked'}) &&
defined($u->[$fieldmap{'account_locked'}]);
my $hashpass = $u->[$epassfield2] || $u->[$epassfield1];
my $lock_supported = &get_account_lock_support();
# Old way for checking account locking
my $locked = $u->[$fieldmap{'account_locked'}] eq 'Y';
# New account locking check
if (!exists($fieldmap{'account_locked'}) ||
!defined($u->[$fieldmap{'account_locked'}])) {
$locked = &get_account_lock_status($u->[1], $u->[0]);
}
print &ui_table_row($text{'user_pass'},
&ui_radio("mysqlpass_mode", $in{'new'} ? 0 :
$lock_supported && $locked ? 4 :
@@ -79,17 +84,19 @@ print &ui_table_row($text{'user_pass'},
# Current hashed password
if (!$in{'new'} && $hashpass) {
$hashpass =~ s/[^[:print:]\n]//g; # keep printable and newline
$hashpass =~ s/\n/\\n/g; # display newline as literal '\n'
print &ui_table_row($text{'user_hashpass'},
"<tt>".&html_escape($hashpass)."</tt>");
}
# Plugin for setting password
my @plugins = &list_authentication_plugins();
if (@plugins) {
my $plugins = &list_authentication_plugins();
if ($plugins) {
print &ui_table_row($text{'user_plugin'},
&ui_select("plugin", $plugin && $u->[$plugin],
[ [ '', $text{'default'} ],
@plugins ]));
@{$plugins} ]));
}
# Allowed host / network

View File

@@ -650,13 +650,14 @@ return $rv;
sub quote_table
{
return &quotestr($_[0]);
my ($rv) = @_;
return &quotestr($rv);
}
# quotestr(string)
sub quotestr
{
local $rv = $_[0];
my ($rv) = @_;
if (&supports_quoting()) {
return "`$rv`";
}
@@ -677,18 +678,19 @@ return $db;
# unquote_mysql_database(name)
# Returns a MySQL database name with \% and \_ characters unescaped
sub unquote_mysql_database {
my ($db) = @_;
$db =~ s/\\%/%/g;
$db =~ s/\\_/_/g;
return $db;
sub unquote_mysql_database
{
my ($db) = @_;
$db =~ s/\\%/%/g;
$db =~ s/\\_/_/g;
return $db;
}
# escapestr(string)
# Returns a string with quotes escaped, for use in SQL
sub escapestr
{
local $rv = $_[0];
my ($rv) = @_;
$rv =~ s/'/''/g;
return $rv;
}
@@ -697,8 +699,8 @@ return $rv;
# Escapes backslashes, but only inside quoted strings
sub escape_backslashes_in_quotes
{
local ($str) = @_;
local $rv;
my ($str) = @_;
my $rv;
while($str =~ /^([^"]*)"([^"]*)"(.*)$/) {
local ($before, $quoted, $after) = ($1, $2, $3);
$quoted =~ s/\\/\\\\/g;
@@ -724,6 +726,14 @@ sub supports_mysqldump_events
return &compare_version_numbers($mysql_version, "5.1.8") >= 0;
}
# supports_mysqldump_setgtid()
# Returns 1 if mysqldump supports --set-gtid-purged flag
sub supports_mysqldump_setgtid
{
my $out = &backquote_command("$config{'mysqldump'} --help 2>&1 </dev/null");
return $out =~ /--set-gtid-purged/ ? 1 : 0;
}
# supports_routines()
# Returns 1 if mysqldump supports routines
sub supports_routines
@@ -1681,15 +1691,21 @@ my $routinessql = &supports_routines() ? "--routines" : "";
my $tablessql = join(" ", map { quotemeta($_) } @$tables);
my $eventssql = &supports_mysqldump_events() ? "--events" : "";
my $gtidsql = "";
eval {
local $main::error_must_die = 1;
my $d = &execute_sql($master_db, "show variables like 'gtid_mode'");
if (@{$d->{'data'}} && uc($d->{'data'}->[0]->[1]) eq 'ON' &&
&compare_version_numbers($mysql_version, "5.6") >= 0) {
# Add flag to support GTIDs
$gtidsql = "--set-gtid-purged=OFF";
}
};
if (&supports_mysqldump_setgtid() &&
$config{'mysqldump'} !~ /--set-gtid-purged/) {
eval {
local $main::error_must_die = 1;
my $d = &execute_sql($master_db,
"show variables like 'gtid_mode'");
my ($ver, $variant) = &get_remote_mysql_variant();
if (@{$d->{'data'}} && uc($d->{'data'}->[0]->[1]) eq 'ON' &&
$variant eq 'mysql' &&
&compare_version_numbers($ver, "5.6") >= 0) {
# Add flag to support GTIDs
$gtidsql = "--set-gtid-purged=OFF";
}
};
}
if ($user && $user ne "root") {
# Actual writing of output is done as another user
$writer = &command_as_user($user, 0, $writer);
@@ -1730,23 +1746,72 @@ my $conf = &get_mysql_config();
return &unique(map { $_->{'file'} } @$conf);
}
# get_change_pass_sql(unescaped_plaintext_password, user, host)
# get_account_lock_status(user, host)
# Returns the account lock status of a user
sub get_account_lock_status
{
my ($user, $host) = @_;
my $rv = &execute_sql_safe($master_db, 'show create user ?@?', $user, $host);
return undef if (!ref($rv) || !@{$rv->{'data'}});
return $rv->{'data'}->[0][0] =~ /account\s+lock/i ? 1 : 0;
}
# get_account_lock_support()
# Returns 1 if the MySQL/MariaDB server supports account locking
sub get_account_lock_support
{
my ($ver, $variant) = &get_remote_mysql_variant();
return
$variant eq "mariadb" && &compare_version_numbers($ver, "10.4.2") >= 0 ||
$variant eq "mysql" && &compare_version_numbers($ver, "8.0") >= 0;
}
# get_plugin_sql(version, variant, plainpass, plugin)
# Get the right query for setting user password with plugin
sub get_plugin_sql
{
my ($ver, $variant, $plainpass, $plugin) = @_;
my $pass = &escapestr($plainpass);
# Has account locking support?
my $suplock = &get_account_lock_support();
my $lockcurr;
if ($suplock) {
$lockcurr = !defined($plainpass);
if ($lockcurr) {
$pass = sprintf("%x", rand 16) for 1..30;
}
}
my $is_plugin_socket = $plugin eq "unix_socket";
my $by = "";
$by = " by '$pass'" if (!$is_plugin_socket);
my $sp = "identified with $plugin$by";
if ($variant eq "mariadb") {
$by = " using $password_func('$pass')" if (!$is_plugin_socket);
$sp = "identified via $plugin$by";
}
if ($suplock) {
$sp = $lockcurr ? "account lock" : "$sp account unlock";
}
return $sp;
}
# get_change_pass_sql(unescaped_plaintext_password, user, host, plugin)
# Get the right query for changing user password
sub get_change_pass_sql
{
my ($unescaped_plainpass, $user, $host) = @_;
my $plugin = &get_mysql_plugin();
$plugin = $plugin ? "with $plugin" : "";
my $escaped_pass = &escapestr($unescaped_plainpass);
my ($unescaped_plainpass, $user, $host, $plugin) = @_;
$plugin ||= &get_mysql_plugin();
my $sql;
my ($ver, $variant) = &get_remote_mysql_variant();
my $mysql_mariadb_with_auth_string =
my $supauth =
$variant eq "mariadb" && &compare_version_numbers($ver, "10.2") >= 0 ||
$variant eq "mysql" && &compare_version_numbers($ver, "5.7.6") >= 0;
if ($mysql_mariadb_with_auth_string && $unescaped_plainpass) {
$sql = "alter user '$user'\@'$host' identified $plugin by '$escaped_pass'";
if ($plugin && $supauth) {
my $sp = &get_plugin_sql($ver, $variant, $unescaped_plainpass, $plugin);
$sql = "alter user '$user'\@'$host' $sp";
}
else {
my $escaped_pass = &escapestr($unescaped_plainpass);
$sql = "set password for '".$user."'\@'".$host."' = ".
"$password_func('$escaped_pass')";
}
@@ -1937,34 +2002,12 @@ else {
sub change_user_password
{
my ($plainpass, $user, $host, $plugin) = @_;
my ($ver, $variant) = &get_remote_mysql_variant();
$plugin ||= &get_mysql_plugin();
$plugin = $plugin ? "with $plugin" : "";
my $lock_supported = $variant eq "mysql" && &compare_version_numbers($ver, "8.0.19");
my $mysql_mariadb_with_auth_string =
$variant eq "mariadb" && &compare_version_numbers($ver, "10.4") >= 0 ||
$variant eq "mysql" && &compare_version_numbers($ver, "5.7.6") >= 0;
$plugin ||= "";
my $sql;
my $pass = &escapestr($plainpass);
$host ||= '%';
my $lock = !defined($plainpass);
if ($lock) {
$pass = sprintf("%x", rand 16) for 1..30;
}
if ($mysql_mariadb_with_auth_string) {
my $sp = "identified $plugin by '".$pass."'";
if ($lock_supported) {
$sp = $lock ? "account lock" : "$sp account unlock";
}
$sql = "alter user '$user'\@'$host' $sp";
&execute_sql_logged($master_db, $sql);
}
else {
$sql = &get_change_pass_sql($plainpass, $user, $host);
&execute_sql_logged($master_db, $sql);
}
$sql = &get_change_pass_sql($plainpass, $user, $host, $plugin);
&execute_sql_logged($master_db, $sql);
# Update module password when needed
&update_config_credentials({
@@ -2058,7 +2101,7 @@ if (!$pid || !kill(0, $pid)) {
}
# Update password by running command directly
my $cmd = $config{'mysql'} || 'mysql';
$cmd = $config{'mysql'} || 'mysql';
my $sql = &get_change_pass_sql($pass, $user, 'localhost');
my $out = &backquote_command("$cmd -D $master_db -e ".
quotemeta("flush privileges; $sql")." 2>&1 </dev/null");
@@ -2154,13 +2197,16 @@ return $rv->{'data'}->[0]->[0] =~ /unix_socket/i ? 'socket' : 'password';
}
# list_authentication_plugins()
# Returns a list of supported authentication plugins for setting passwords
# Returns a list ref of supported authentication plugins for setting passwords
sub list_authentication_plugins
{
my ($ver, $variant) = &get_remote_mysql_variant();
if ($variant eq "mariadb" && &compare_version_numbers($ver, "10.4") >= 0 ||
$variant eq "mysql" && &compare_version_numbers($ver, "5.7.6") >= 0) {
return ('mysql_native_password', 'caching_sha2_password', 'unix_socket');
my $rv = &execute_sql($master_db, "show plugins");
my @plugins = map { $_->[0] } grep { $_->[1] eq 'ACTIVE' &&
$_->[2] eq 'AUTHENTICATION' } @{ $rv->{data} };
return @plugins ? \@plugins : ['mysql_native_password'];
}
return ();
}

View File

@@ -77,6 +77,11 @@ else {
&change_user_password(undef, $olduser, $oldhost,
$in{'plugin'});
}
elsif ($in{'mysqlpass_mode'} == 1 &&
$in{'plugin'} eq "unix_socket") {
&change_user_password('', $olduser, $oldhost,
$in{'plugin'});
}
elsif ($in{'mysqlpass_mode'} != 1) {
($in{'mysqlpass_mode'} eq '0' && !$in{'mysqlpass'}) && &error($text{'root_epass1'});
my $pass = $in{'mysqlpass'} || '';

View File

@@ -254,7 +254,12 @@ if(($cfg->{'vlan'} == 1) && ($gconfig{'os_version'} < 5)) {
}
}
if(($cfg->{'vlan'} == 1) && ($cfg->{'mtu'})) {
push(@options, ['pre-up', '/sbin/ifconfig '.$cfg->{'physical'}.' mtu '.$cfg->{'mtu'}]);
if (&has_command("ip")) {
push(@options, ['pre-up', 'ip link set mtu '.$cfg->{'mtu'}.' dev '.$cfg->{'physical'}]);
}
else {
push(@options, ['pre-up', '/sbin/ifconfig '.$cfg->{'physical'}.' mtu '.$cfg->{'mtu'}]);
}
}
# Find the existing interface section
@@ -328,9 +333,6 @@ else {
my @options6;
my @address6 = @{$cfg->{'address6'}};
my @netmask6 = @{$cfg->{'netmask6'}};
if (@address6 || $cfg->{'auto6'}) {
push(@options6, ['pre-up', '/sbin/modprobe -q ipv6 ; /bin/true']);
}
if (@address6) {
push(@options6, [ "address", shift(@address6) ]);
push(@options6, [ "netmask", shift(@netmask6) ]);
@@ -338,7 +340,12 @@ if (@address6) {
while(@address6) {
my $a = shift(@address6);
my $n = shift(@netmask6);
push(@options6, [ "up","ifconfig $cfg->{'fullname'} inet6 add $a/$n" ]);
if (&has_command("ip")) {
push(@options6, [ "up", "ip addr add $a/$n dev $cfg->{'fullname'}" ]);
}
else {
push(@options6, [ "up", "ifconfig $cfg->{'fullname'} inet6 add $a/$n" ]);
}
}
if ($cfg->{'gateway6'}) {
push(@options6, [ "gateway", $cfg->{'gateway6'} ]);

View File

@@ -271,8 +271,18 @@ else {
my $lref = &read_file_lines($old->{'file'});
splice(@$lref, $old->{'line'},
$old->{'eline'} - $old->{'line'} + 1, @lines);
my $diff = scalar(@lines) - ($old->{'eline'} - $old->{'line'} + 1);
$iface->{'line'} = $old->{'line'};
$iface->{'eline'} = $iface->{'line'} + scalar(@lines) - 1;
&flush_file_lines($old->{'file'});
&unlock_file($old->{'file'});
if ($diff) {
# May need to renumber other interface lines
foreach my $b (@$boot) {
$b->{'line'} += $diff if ($b->{'line'} > $iface->{'eline'});
$b->{'eline'} += $diff if ($b->{'eline'} > $iface->{'eline'});
}
}
}
else {
# Adding a new one (possibly to it's own file)
@@ -295,6 +305,8 @@ else {
splice(@$lref, $nline+1, 0, " ".$sect.":");
}
splice(@$lref, $eline+1, 0, @lines);
$iface->{'line'} = $eline + 1;
$iface->{'eline'} = $iface->{'line'} + scalar(@lines) - 1;
&flush_file_lines($iface->{'file'});
&unlock_file($iface->{'file'});
}
@@ -558,7 +570,7 @@ $sysctl{'net.ipv4.ip_forward'} = $in{'forward'};
&unlock_file($sysctl_config);
# Save static routes
my @boot = &boot_interfaces();
my @boot = &boot_interfaces();
foreach my $b (grep { $_->{'virtual'} eq '' } @boot) {
my @r;
if ($b->{'routes'}) {
@@ -627,7 +639,8 @@ return ( );
sub set_default_gateway
{
my ($gw, $dev) = @_;
foreach my $iface (&boot_interfaces()) {
my @boot = &boot_interfaces();
foreach my $iface (@boot) {
# What is this interface's current default and how is it set?
my $oldgw = $iface->{'gateway'};
my $oldr;
@@ -670,7 +683,7 @@ foreach my $iface (&boot_interfaces()) {
}
if ($save) {
&save_interface($iface);
&save_interface($iface, \@boot);
}
}
}
@@ -694,16 +707,17 @@ return ( );
sub set_default_ipv6_gateway
{
my ($gw, $dev) = @_;
foreach my $iface (&boot_interfaces()) {
my @boot = &boot_interfaces();
foreach my $iface (@boot) {
if ($iface->{'fullname'} eq $dev && $iface->{'gateway6'} ne $gw) {
# Need to add to this interface
$iface->{'gateway6'} = $gw;
&save_interface($iface);
&save_interface($iface, \@boot);
}
elsif ($iface->{'fullname'} ne $dev && $iface->{'gateway6'}) {
# Need to remove from this interface
delete($iface->{'gateway6'});
&save_interface($iface);
&save_interface($iface, \@boot);
}
}
}

View File

@@ -230,8 +230,10 @@ my $method6 = $iface->{'auto6'} ? "auto" :
# Update nameservers
my @ns = $iface->{'nameserver'} ? @{$iface->{'nameserver'}} : ();
&save_nm_config($cfg, "ipv4", "dns",
@ns ? join(" ", @ns) : undef);
my @ns4 = grep { &check_ipaddress($_) } @ns;
my @ns6 = grep { &check_ip6address($ns6) } @ns;
&save_nm_config($cfg, "ipv4", "dns", @ns4 ? join(" ", @ns4) : undef) if (@ns4);
&save_nm_config($cfg, "ipv6", "dns", @ns6 ? join(" ", @ns6) : undef) if (@ns6);
my @sr = $iface->{'search'} ? @{$iface->{'search'}} : ();
&save_nm_config($cfg, "ipv4", "dns-search",
@sr ? join(" ", @sr) : undef);

View File

@@ -21,9 +21,12 @@ for($i=0; defined($ns = $in{"nameserver_$i"}); $i++) {
$ns = $in{"nameserver_$i"};
$ns =~ s/^\s+//; $ns =~ s/\s+$//;
if ($ns) {
&check_ipaddress_any($ns) ||
my $nns = $ns;
# Just remove scope identifier (%interface) for simplicity
$nns =~ s/\%.*$//;
&check_ipaddress_any($nns) ||
&error(&text('dns_ens', &html_escape($ns)));
push(@{$dns->{'nameserver'}}, $ns);
push(@{$dns->{'nameserver'}}, $nns);
}
}
if ($in{'name0'}) {

62
phpini/delete_pkgs.cgi Executable file
View File

@@ -0,0 +1,62 @@
#!/usr/local/bin/perl
# Remove some PHP versions
require './phpini-lib.pl';
&error_setup($text{'dpkgs_err'});
$access{'global'} || &error($text{'pkgs_ecannot'});
&foreign_available("software") || &error($text{'pkgs_ecannot2'});
&ReadParse();
my @d = split(/\0/, $in{'d'});
@d || &error($text{'dpkgs_enone'});
my $vmap = &get_virtualmin_php_map();
# Find all packages and check that they can be safely removed
my @pkgs = &list_php_base_packages();
my @delpkgs;
foreach my $name (@d) {
($pkg) = grep { $_->{'name'} eq $name } @pkgs;
$pkg || &error($text{'dpkgs_eexists'});
if ($vmap) {
$ulist = $vmap->{$pkg->{'shortver'}};
if ($ulist && @$ulist) {
&error(&text('dpkg_eusers', $pkg->{'phpver'},
scalar(@$ulist)));
}
}
push(@delpkgs, $pkg);
}
&ui_print_unbuffered_header(undef, $text{'dpkgs_title'}, "");
if (!$in{'confirm'}) {
# Find the packages first
print &ui_form_start("delete_pkgs.cgi");
foreach my $d (@d) {
print &ui_hidden("d", $d);
}
my @alldel;
foreach my $pkg (@delpkgs) {
push(@alldel, &list_all_php_version_packages($pkg));
}
print &text('dpkgs_rusure',
join(" ", map { "<tt>$_</tt>" } @alldel)),"<p>\n";
print &ui_form_end([ [ 'confirm', $text{'pkgs_delete'} ] ]);
}
else {
# Actually do the deletion
foreach my $pkg (@delpkgs) {
print &text('dpkgs_doing', "<tt>$pkg->{'name'}</tt>",
$pkg->{'phpver'}),"<br>\n";
$err = &delete_php_base_package($pkg);
if ($err) {
print &text('dpkgs_failed', $err),"<p>\n";
}
else {
print $text{'dpkgs_done'},"<p>\n";
}
}
&webmin_log("delete", "pkgs", scalar(@delpkgs));
}
&ui_print_footer("list_pkgs.cgi", $text{'pkgs_return'});

View File

@@ -61,6 +61,16 @@ else {
print &ui_form_end();
}
# Show button to install PHP versions
if ($access{'global'} && &foreign_available("software")) {
print &ui_hr();
print &ui_buttons_start();
print &ui_buttons_row("list_pkgs.cgi",
$text{'index_pkgs'},
$text{'index_pkgsdesc'});
print &ui_buttons_end();
}
&ui_print_footer("/", $text{'index'});
}

View File

@@ -3,151 +3,154 @@ index_eaccess=Sie haben keinen Zugriff auf PHP-Konfigurationsdateien.
index_efiles=Keine der PHP-Konfigurationsdateien, auf die Sie Zugriff haben, existiert.
index_efiles2=Es wurden keine PHP-Konfigurationsdateien gefunden. Passen Sie die <a href='$1'>Modulkonfiguration</a> an, um den korrekten Pfad zur globalen PHP-Konfigurationsdatei festzulegen.
index_file=Konfigurationsdatei
index_desc=Zweck
index_desc=Verwendungszweck
index_actions=Aktionen
index_edit=Verwalten
index_manual=Manuell bearbeiten
index_anyfile=Andere PHP-Konfigurationsdatei bearbeiten
index_return=Konfigurationsdateien
index_pkgs=PHP-Pakete verwalten
index_pkgsdesc=Installieren und entfernen Sie PHP-Versionen aus dem Softwarepaket-Repository Ihres Systems, sodass sie hier konfiguriert und in Virtualmin verwendet werden können.
file_global=Globale PHP-Konfiguration
file_eread=Fehler beim Lesen von $1: $2
file_eread=Lesen von $1 fehlgeschlagen: $2
manual_title=Konfiguration manuell bearbeiten
manual_desc=Diese Seite kann verwendet werden, um eine PHP-Konfigurationsdatei manuell zu bearbeiten. Dies sollte mit Vorsicht erfolgen, da keine Syntax- oder Gültigkeitsprüfung für Ihre Änderungen durchgeführt wird.
manual_err=Fehler beim Bearbeiten der Konfigurationsdatei
manual_edata=Kein neuer Inhalt eingegeben
manual_desc=Auf dieser Seite kann eine PHP-Konfigurationsdatei manuell bearbeitet werden. Dies sollte mit Vorsicht erfolgen, da keine Syntax- oder Gültigkeitsprüfung der Änderungen durchgeführt wird.
manual_err=Konfigurationsdatei konnte nicht bearbeitet werden
manual_edata=Keine neuen Inhalte eingegeben
list_title=PHP-Konfiguration verwalten
list_ecannot=Sie sind nicht berechtigt, diese PHP-Konfigurationsdatei zu verwalten.
list_efile=Die zu bearbeitende Datei muss ein absoluter Pfad sein.
list_ecannot=Sie dürfen diese PHP-Konfigurationsdatei nicht verwalten
list_efile=Pfad zur zu bearbeitenden Datei muss absolut sein
list_return=PHP-Konfiguration
list_format_ini=INI-Format
list_format_fpm=FPM-Format
list_bin=PHP-Version $2 unter $1
vars_title=PHP-Variablen
vars_header=Erstellung und Zitierung von PHP-Variablen
vars_magic=Alle Eingabevariablen zitieren?
vars_runtime=Daten zur Laufzeit zitieren?
vars_header=Erstellung und Maskierung von PHP-Variablen
vars_magic=Alle Eingabevariablen maskieren?
vars_runtime=Daten zur Laufzeit maskieren?
vars_register=Alle Eingaben in globale Variablen umwandeln?
vars_args=Kommandozeilenparameter in globale Variablen umwandeln?
vars_long=Alte Array-Formate wie <tt>HTTP_GET_VARS</tt> erstellen?
vars_err=Fehler beim Speichern der PHP-Variableneinstellungen
vars_long=Veraltete Array-Formate wie <tt>HTTP_GET_VARS</tt> erstellen?
vars_err=PHP-Variableinstellungen konnten nicht gespeichert werden
dirs_title=Verzeichniseinstellungen
dirs_header=Verzeichnis- und Erweiterungseinstellungen für PHP-Skripte
dirs_header=Verzeichnisoptionen für PHP-Skripte und -Erweiterungen
dirs_include=Suchverzeichnisse für Includes
dirs_below=Unten aufgeführt..
dirs_upload=Datei-Uploads zulassen?
dirs_below=Unten aufgelistet..
dirs_upload=Datei-Uploads erlauben?
dirs_utmp=Temporäres Verzeichnis für hochgeladene Dateien
dirs_err=Fehler beim Speichern der Verzeichniseinstellungen
dirs_err=Verzeichniseinstellungen konnten nicht gespeichert werden
dirs_eincs=Keine Include-Suchverzeichnisse eingegeben
dirs_eutmp=Fehlendes oder ungültiges temporäres Verzeichnis für Dateien
db_title=Datenbankeinstellungen
db_header1=MySQL-Datenbankverbindungs-Einstellungen
db_persist=Persistente Datenbankverbindungen zulassen?
db_maxpersist=Maximale Anzahl persistenter Verbindungen?
db_maxlinks=Maximale Anzahl gesamter Verbindungen?
db_timeout=Timeout für MySQL-Verbindungen?
db_host=Standard-Host des MySQL-Servers
db_port=Standard-Port des MySQL-Servers
db_header1=MySQL-Datenbankverbindungseinstellungen
db_persist=Persistente Datenbankverbindungen erlauben?
db_maxpersist=Maximale persistente Verbindungen?
db_maxlinks=Maximale Gesamtverbindungen?
db_timeout=MySQL-Verbindungs-Timeout?
db_host=Standard-MySQL-Serverhost
db_port=Standard-MySQL-Serverport
db_unlimited=Unbegrenzt
db_s=Sekunden
db_header2=PostgreSQL-Datenbankverbindungs-Einstellungen
db_header2=PostgreSQL-Datenbankverbindungseinstellungen
db_reset=Persistente Verbindungen automatisch wiederherstellen?
db_err=Fehler beim Speichern der Datenbankeinstellungen
db_err=Datenbankeinstellungen konnten nicht gespeichert werden
db_emaxpersist=Fehlende oder ungültige maximale Anzahl persistenter Verbindungen
db_emaxlinks=Fehlende oder ungültige maximale Anzahl gesamter Verbindungen
db_etimeout=Fehlendes oder ungültiges Verbindungstimeout
db_ehost=Fehlender oder ungültiger Standard-Host des MySQL-Servers
db_eport=Fehlender oder ungültiger Standard-Port des MySQL-Servers
db_emaxlinks=Fehlende oder ungültige maximale Gesamtverbindungen
db_etimeout=Fehlendes oder ungültiges Verbindungs-Timeout
db_ehost=Fehlender oder ungültiger Standard-MySQL-Serverhost
db_eport=Fehlender oder ungültiger Standard-MySQL-Serverport
session_title=Session-Optionen
session_header=Optionen für PHP-Sitzungsverfolgung
session_handler=Mechanismus zur Speicherung von Sitzungen
session_handler=Mechanismus zur Sitzungsspeicherung
session_files=Dateien
session_mm=Im Speicher
session_users=Benutzerdefiniert
session_redis=Redis
session_memcache=MemcacheD
session_path=Verzeichnis für Sitzungsdateien
session_cookies=Verwendung von Cookies zur Sitzungsverfolgung zulassen?
session_only_cookies=Immer Cookies zur Sitzungsverfolgung verwenden?
session_cookies=Verwendung von Cookies zur Sitzungserkennung erlauben?
session_only_cookies=Immer Cookies zur Sitzungserkennung verwenden?
session_life=Cookie-Lebensdauer
session_forever=Unbegrenzt
session_maxlife=Maximale Sitzungslebensdauer
session_maxlife=Maximale Sitzungsdauer
session_epath=Fehlendes oder ungültiges Verzeichnis für Sitzungsdateien
session_elife=Fehlende oder ungültige Cookie-Lebensdauer
session_emaxlife=Fehlende oder ungültige maximale Sitzungslebensdauer
session_emaxlife=Fehlende oder ungültige maximale Sitzungsdauer
limits_title=Ressourcenlimits
limits_title=Ressourcenbeschränkungen
limits_header=Optionen für Speicher- und Übertragungsgrenzen
limits_mem=Maximale Speicherzuweisung
limits_mem=Maximaler Speicherverbrauch
limits_post=Maximale HTTP-POST-Größe
limits_upload=Maximale Datei-Upload-Größe
limits_upload=Maximale Dateiupload-Größe
limits_exec=Maximale Ausführungszeit
limits_input=Maximale Eingabeparsing-Zeit
limits_vars=Maximale Anzahl an Eingabevariablen
limits_err=Fehler beim Speichern der Ressourcenlimits
limits_emem=Fehlende oder ungültige maximale Speicherzuweisung
limits_input=Maximale Zeit für Eingabeverarbeitung
limits_vars=Maximale Anzahl von Eingabevariablen
limits_err=Ressourcengrenzen konnten nicht gespeichert werden
limits_emem=Fehlender oder ungültiger maximaler Speicherverbrauch
limits_epost=Fehlende oder ungültige maximale HTTP-POST-Größe
limits_eupload=Fehlende oder ungültige maximale Datei-Upload-Größe
limits_eupload=Fehlende oder ungültige maximale Upload-Größe
limits_eexec=Fehlende oder ungültige maximale Ausführungszeit
limits_einput=Fehlende oder ungültige maximale Eingabeparsing-Zeit
limits_evars=Fehlende oder ungültige maximale Anzahl an Eingabevariablen
limits_einput=Fehlende oder ungültige maximale Zeit für Eingabeverarbeitung
limits_evars=Fehlende oder ungültige maximale Anzahl von Eingabevariablen
errors_title=Fehlerprotokollierung
errors_header=Anzeige- und Protokollierungsoptionen für Fehlermeldungen
errors_display=Fehlermeldungen anzeigen?
errors_log=Fehlermeldungen in das Protokoll schreiben?
errors_log=Fehlermeldungen protokollieren?
errors_bits=Anzuzeigende Fehlertypen
errors_reporting=Ausdruck für Fehlertypen
errors_E_ALL=Alle Fehler und Warnungen
errors_E_ERROR=Schwerwiegende Laufzeitfehler
errors_E_WARNING=Laufzeitwarnungen
errors_E_PARSE=Syntaxfehler zur Kompilierzeit
errors_E_NOTICE=Hinweise zur Laufzeit
errors_E_CORE_ERROR=Schwerwiegende Fehler während des Startvorgangs
errors_E_CORE_WARNING=Warnungen während des Startvorgangs
errors_E_COMPILE_ERROR=Schwerwiegende Fehler zur Kompilierzeit
errors_E_COMPILE_WARNING=Warnungen zur Kompilierzeit
errors_E_USER_ERROR=Vom Benutzer generierte Fehlermeldung
errors_E_USER_WARNING=Vom Benutzer generierte Warnmeldung
errors_E_USER_NOTICE=Vom Benutzer generierte Hinweisnachricht
errors_E_PARSE=Fehler beim Parsen zur Kompilierzeit
errors_E_NOTICE=Laufzeit-Hinweise
errors_E_CORE_ERROR=Schwerwiegende Fehler beim Start
errors_E_CORE_WARNING=Warnungen beim Start
errors_E_COMPILE_ERROR=Schwerwiegende Kompilierfehler
errors_E_COMPILE_WARNING=Kompilierzeit-Warnungen
errors_E_USER_ERROR=Benutzerdefinierte Fehlermeldung
errors_E_USER_WARNING=Benutzerdefinierte Warnung
errors_E_USER_NOTICE=Benutzerdefinierter Hinweis
errors_ignore=Wiederholte Fehler ignorieren?
errors_source=Quelle beim Prüfen auf Wiederholungen ignorieren?
errors_maxlen=Maximale Größe protokollierter Fehler
errors_file=Protokolldatei für Fehler
errors_source=Quelltext bei Wiederholung ignorieren?
errors_maxlen=Maximale Größe für protokollierte Fehler
errors_file=Fehlerprotokolldatei
errors_none=Keine
errors_syslog=Syslog
errors_other=Andere Datei $1
errors_unlimited=Unbegrenzt
errors_err=Fehler beim Speichern der Fehlerprotokollierung
errors_err=Fehlerprotokollierung konnte nicht gespeichert werden
errors_ereporting=Kein Ausdruck für Fehlertypen eingegeben
errors_emaxlen=Fehlende oder ungültige maximale Größe protokollierter Fehler
errors_efile=Fehlende Protokolldatei für Fehler
errors_emaxlen=Fehlende oder ungültige maximale Protokollgröße
errors_efile=Fehlende Fehlerprotokolldatei
misc_title=Weitere Einstellungen
misc_header=Verschiedene zusätzliche PHP-Einstellungen
misc_short=PHP-Skripte mit &lt;? zulassen?
misc_asp=Tags &lt;% %&gt; zulassen?
misc_header=Sonstige PHP-Einstellungen
misc_short=PHP-Skripte mit &lt;? erlauben?
misc_asp=&lt;% %&gt;-Tags erlauben?
misc_zlib=Ausgabe mit zlib komprimieren?
misc_flush=Ausgabe nach jedem Schreibvorgang leeren?
misc_fopen=Öffnen von URLs als Dateien zulassen?
misc_smtp=SMTP-Server für den E-Mail-Versand
misc_port=SMTP-Port auf dem Server
misc_fopen=Öffnen von URLs als Dateien erlauben?
misc_smtp=SMTP-Server zum Versenden von E-Mails
misc_port=SMTP-Port des Servers
misc_none=Keine
misc_sendmail=Pfad zum Befehl für den E-Mail-Versand
misc_err=Fehler beim Speichern weiterer Einstellungen
misc_sendmail=Pfad zum Befehl zum Versenden von E-Mails
misc_err=Weitere Einstellungen konnten nicht gespeichert werden
misc_esmtp=Fehlender oder nicht auflösbarer SMTP-Server
misc_esmtp_port=Fehlender oder nicht-numerischer SMTP-Port
misc_esendmail=Ungültiger Befehl für den E-Mail-Versand
misc_esendmail2=Fehlender Befehl für den E-Mail-Versand
misc_include=Öffnen von Remote-Includes zulassen?
misc_esendmail=Ungültiger Befehl zum Versenden von E-Mails
misc_esendmail2=Fehlender Befehl zum Versenden von E-Mails
misc_include=Öffnen von entfernten Includes erlauben?
misc_path=CGI Fix Path Info?
misc_timezone=PHP-Zeitzone
misc_charset=Standard-Zeichensatz
misc_charset=Standardzeichensatz
disable_title=Deaktivierte Funktionen
disable_header=Deaktivierte PHP-Funktionen und -Features
@@ -160,36 +163,36 @@ disable_proc_open=proc_open (Befehl ausführen und Ein-/Ausgabe erfassen)
disable_popen=popen (Pipe zu ausgeführtem Befehl öffnen)
disable_curl_exec=curl_exec (URL-Download-Sitzung ausführen)
disable_curl_multi_exec=curl_multi_exec (Mehrere URL-Download-Sitzungen ausführen)
disable_parse_ini_file=parse_ini_file (PHP-INI-Datei einlesen)
disable_show_source=show_source (Datei mit PHP-Syntaxhervorhebung ausgeben)
disable_parse_ini_file=parse_ini_file (PHP-INI-Datei lesen)
disable_show_source=show_source (Datei mit PHP-Syntaxhervorhebung anzeigen)
disable_mail=mail (E-Mail senden)
disable_leftover=Weitere Funktionen:
disable_err=Fehler beim Speichern deaktivierter Funktionen
disable_err=Deaktivierte Funktionen konnten nicht gespeichert werden
disable_classes=Deaktivierte integrierte Klassen
mods_title=PHP-Erweiterungen
mods_edir=PHP-Erweiterungsverzeichnis konnte nicht gefunden werden!
mods_ecannot=Sie sind nicht berechtigt, aktivierte PHP-Erweiterungen zu bearbeiten.
mods_desc=Auf dieser Seite können PHP-Version-$1-Erweiterungen systemweit für alle Benutzer:innen aktiviert oder deaktiviert werden.
mods_edir=Verzeichnis für PHP-Erweiterungen konnte nicht gefunden werden!
mods_ecannot=Sie dürfen aktivierte PHP-Erweiterungen nicht bearbeiten
mods_desc=Auf dieser Seite können global PHP-Erweiterungen für Version $1 für alle Benutzer:innen auf diesem System aktiviert oder deaktiviert werden.
mods_enabled=Aktiviert?
mods_name=Erweiterungsname
mods_file=Konfigurationsdatei
mods_pkg=Paket
mods_idesc=PHP-Erweiterungen, die auf diesem System noch nicht installiert sind, können aus den konfigurierten Softwarepaket-Repositories installiert werden.
mods_idesc=PHP-Erweiterungen, die auf diesem System noch nicht installiert sind, können aus den konfigurierten Software-Repositories installiert werden.
mods_newpkg=PHP-Erweiterung hinzufügen
mods_install=Jetzt installieren
mods_err=Fehler beim Speichern der PHP-Erweiterungen
mods_egetver=PHP-Version für Konfigurationsdatei $1 konnte nicht ermittelt werden.
mods_egetbin=PHP-Binärdatei für Konfigurationsdatei $1 konnte nicht ermittelt werden.
mods_err=PHP-Erweiterungen konnten nicht gespeichert werden
mods_egetver=PHP-Version für Konfigurationsdatei $1 konnte nicht ermittelt werden
mods_egetbin=PHP-Binary für Konfigurationsdatei $1 konnte nicht ermittelt werden
mods_return=PHP-Erweiterungen
imod_title=PHP-Modul installieren
imod_err=Fehler bei der Installation des PHP-Moduls
imod_emod=Kein PHP-Modul angegeben
imod_err=PHP-Modul konnte nicht installiert werden
imod_emod=Kein PHP-Modul eingegeben
imod_alldoing=PHP-Modul $1 für PHP-Version $2 wird installiert ..
imod_alreadygot=PHP-Modul $1 ist bereits installiert.
imod_alldone=.. das PHP-Modul wurde erfolgreich aus Paket $1 installiert und steht nun zur Nutzung bereit.
imod_allfailed=.. es konnten keine Softwarepakete für das angegebene PHP-Modul installiert werden, trotz $1 Versuchen.
imod_alreadygot=PHP-Modul $1 ist bereits installiert
imod_alldone=.. das PHP-Modul wurde erfolgreich aus Paket $1 installiert und steht nun zur Verfügung.
imod_allfailed=.. kein Softwarepaket für das angegebene PHP-Modul konnte installiert werden, trotz Versuch über $1
imod_missing=.. Installation abgeschlossen, aber das PHP-Modul wurde nicht erkannt.
log_manual=Datei $1 manuell bearbeitet
@@ -198,17 +201,44 @@ log_dirs=Verzeichniseinstellungen in $1 geändert
log_db=Datenbankeinstellungen in $1 geändert
log_session=Session-Optionen in $1 geändert
log_safe=Safe-Mode-Optionen in $1 geändert
log_limits=Ressourcenlimits in $1 geändert
log_limits=Ressourcengrenzen in $1 geändert
log_errors=Fehlerprotokollierung in $1 geändert
log_misc=Weitere Einstellungen in $1 geändert
log_mods=Aktivierte Module in $1 aktualisiert
log_imod=PHP-Modul $2 in $1 installiert
log_delete_dpkgs=Deinstallation von $1 PHP-Paketen abgeschlossen
acl_global=Darf globale PHP-Konfiguration bearbeiten?
acl_anyfile=Darf beliebige Dateien als PHP-Konfiguration bearbeiten?
acl_manual=Darf Konfigurationsdateien manuell bearbeiten?
acl_inis=Zusätzliche Konfigurationsdateien<br>(Im Format <i>Dateiname</i>=<i>Beschreibung</i>)
acl_user=Darf Dateien als Benutzer:in lesen und schreiben
acl_global=Globale PHP-Konfiguration bearbeiten dürfen?
acl_anyfile=Beliebige Datei als PHP-Konfiguration bearbeiten dürfen?
acl_manual=Konfigurationsdateien manuell bearbeiten dürfen?
acl_inis=Zusätzliche Konfigurationsdateien<br>(im Format <i>Dateiname</i>=<i>Beschreibung</i>)
acl_user=Dateien im Kontext von Benutzer:innen lesen und schreiben
opt_default=Standardwert: <tt>$1</tt>
opt_default_unknown=Unbekannt
pkgs_title=PHP-Pakete
pkgs_name=Paketname
pkgs_ver=Paketversion
pkgs_phpver=PHP-Version
pkgs_shortver=Kurze Version
pkgs_users=Verwendet von
pkgs_delete=Ausgewählte Pakete löschen
pkgs_none=Auf Ihrem System wurden keine PHP-Pakete gefunden!
pkgs_ecannot=Sie haben keine Berechtigung, PHP-Pakete zu verwalten!
pkgs_ecannot2=Softwarepakete können auf diesem System nicht verwaltet werden
pkgs_nousers=Keine Domains
pkgs_ucount=$1 Domains
pkgs_newver=Zu installierendes PHP-Paket:
pkgs_install=Jetzt installieren
pkgs_return=PHP-Pakete
dpkgs_err=Fehler beim Löschen der PHP-Pakete
dpkgs_title=PHP-Pakete werden gelöscht
dpkgs_doing=Deinstalliere Paket $1 und Module für PHP-Version $2 ..
dpkgs_failed=.. fehlgeschlagen : $1
dpkgs_done=.. erfolgreich deinstalliert
dpkgs_enone=Keine Pakete ausgewählt
dpkgs_eexists=Das Paket existiert nicht!
dpkg_eusers=Das Paket für PHP-Version $1 kann nicht deinstalliert werden, da es noch von $2 Domain(s) verwendet wird
dpkgs_rusure=Möchten Sie die ausgewählten PHP-Pakete wirklich entfernen: $1

View File

@@ -9,6 +9,8 @@ index_edit=Manage
index_manual=Edit Manually
index_anyfile=Edit other PHP configuration file
index_return=configuration files
index_pkgs=Manage PHP Packages
index_pkgsdesc=Install and remove PHP versions from your system's software package repository, so that they can be configured here any used in Virtualmin.
file_global=Global PHP configuration
file_eread=Failed to read $1 : $2
@@ -24,6 +26,7 @@ list_efile=File to edit must be an absolute path
list_return=PHP configuration
list_format_ini=INI format
list_format_fpm=FPM format
list_bin=PHP version $2 at $1
vars_title=PHP Variables
vars_header=PHP variable creation and quoting options
@@ -203,6 +206,7 @@ log_errors=Changed error logging in $1
log_misc=Changed other settings in $1
log_mods=Updated enabled modules in $1
log_imod=Installed PHP module $2 in $1
log_delete_dpkgs=Uninstalled $1 PHP packages
acl_global=Can edit global PHP configuration?
acl_anyfile=Can edit any file as a PHP configuration?
@@ -213,4 +217,31 @@ acl_user=Read and write files as user
opt_default=Default Value: <tt>$1</tt>
opt_default_unknown=Unknown
pkgs_title=PHP Packages
pkgs_name=Package name
pkgs_ver=Package version
pkgs_phpver=PHP version
pkgs_bin=Executable
pkgs_shortver=Short version
pkgs_users=Used by
pkgs_delete=Delete Selected Packages
pkgs_none=No PHP packages were found on your system!
pkgs_ecannot=You are not allowed to manage PHP packages!
pkgs_ecannot2=Software packages cannot be managed on this system
pkgs_nousers=No domains
pkgs_ucount=$1 domains
pkgs_newver=PHP package to install:
pkgs_install=Install Now
pkgs_return=PHP packages
dpkgs_err=Failed to delete PHP packages
dpkgs_title=Deleting PHP Packages
dpkgs_doing=Uninstalling package $1 and modules for PHP version $2 ..
dpkgs_failed=.. failed : $1
dpkgs_done=.. uninstalled successfully
dpkgs_enone=No packages selected
dpkgs_eexists=Package does not exist!
dpkg_eusers=Package for PHP version $1 cannot be uninstalled, as it is still being used by $2 domains
dpkgs_rusure=Are you sure you want to remove the selected PHP packages : $1
__norefs=1

View File

@@ -13,7 +13,13 @@ if (@files == 1 && !$access{'anyfile'} && $access{'noconfig'}) {
}
$inidir = &get_php_ini_dir($in{'file'});
&ui_print_header("<tt>".&html_escape($in{'file'})."</tt>",
my $bin = &get_php_ini_binary($in{'file'});
my $ver = &get_php_binary_version($in{'file'});
my $vmsg = "";
if ($bin && $ver) {
$vmsg = "<br>".&text('list_bin', "<tt>$bin</tt>", $ver);
}
&ui_print_header("<tt>".&html_escape($in{'file'})."</tt>".$vmsg,
$text{'list_title'}, "", undef, 0, $onefile);
@pages = ( "vars", "dirs", "db", "session", "limits",

67
phpini/list_pkgs.cgi Executable file
View File

@@ -0,0 +1,67 @@
#!/usr/local/bin/perl
# Show all installed PHP versions
require './phpini-lib.pl';
$access{'global'} || &error($text{'pkgs_ecannot'});
&foreign_available("software") || &error($text{'pkgs_ecannot2'});
&ui_print_header(undef, $text{'pkgs_title'}, "");
my @pkgs = &list_php_base_packages();
my %got;
if (@pkgs) {
my $vmap = &get_virtualmin_php_map();
my @tds = ( "width=5" );
print &ui_form_start("delete_pkgs.cgi", "post");
print &ui_columns_start([ "", $text{'pkgs_name'},
$text{'pkgs_ver'},
$text{'pkgs_phpver'},
$text{'pkgs_bin'},
$vmap ? (
$text{'pkgs_shortver'},
$text{'pkgs_users'} ) : ( ),
], \@tds);
foreach my $pkg (@pkgs) {
my $users;
if ($vmap) {
my $ulist = $vmap->{$pkg->{'shortver'}};
$users = !$ulist || !@$ulist ? $text{'pkgs_nousers'} :
@$ulist > 5 ? &text('pkgs_ucount',
scalar(@$ulist)) :
join(", ", map { "<tt>$_->{'dom'}</tt>" }
@$ulist);
}
print &ui_checked_columns_row([
$pkg->{'name'},
$pkg->{'ver'},
$pkg->{'phpver'},
$pkg->{'binary'},
$vmap ? ( $pkg->{'shortver'}, $users ) : ( ),
], \@tds, "d", $pkg->{'name'});
$got{$pkg->{'name'}}++;
}
print &ui_columns_end();
print &ui_form_end([ [ undef, $text{'pkgs_delete'} ] ]);
}
else {
print "<b>$text{'pkgs_none'}</b> <p>\n";
}
if (&foreign_installed("package-updates")) {
# Show form to install a new version
@newpkgs = grep { !$got{$_->{'name'}} } &list_available_php_packages();
print &ui_hr();
print &ui_form_start(
&get_webprefix()."/package-updates/update.cgi", "post");
print "<b>$text{'pkgs_newver'}</b>\n";
print &ui_select("u", undef,
[ map { [ $_->{'name'},
$_->{'name'}." (".$_->{'ver'}.")" ] } @newpkgs ]);
print &ui_hidden(
"redir", &get_webprefix()."/$module_name/list_pkgs.cgi");
print &ui_hidden("redirdesc", $text{'pkgs_title'});
print &ui_hidden("mode", "new");
print &ui_form_end([ [ undef, $text{'pkgs_install'} ] ]);
}
&ui_print_footer("", $text{'index_return'});

View File

@@ -12,6 +12,11 @@ if ($action eq "imod") {
return &text('log_'.$action, "<tt>".&html_escape($object)."</tt>",
"<tt>".&html_escape($p->{'mod'})."</tt>");
}
return &text('log_'.$action, "<tt>".&html_escape($object)."</tt>");
elsif ($type eq "pkgs") {
return &text('log_'.$action.'_pkgs', $object);
}
else {
return &text('log_'.$action, "<tt>".&html_escape($object)."</tt>");
}
}

View File

@@ -342,7 +342,8 @@ if (&foreign_check("virtual-server")) {
# RHEL and derivatives Debian/Ubuntu
if ($file =~ /php(\d+)/ || $file =~ /php\/([\d\.]+)/) {
$ver = $1;
my $binary = &has_command("php$ver");
my $binary = &has_command("php$ver") ||
&has_command("php$ver-cgi");
return $binary if ($binary);
}
@@ -352,7 +353,9 @@ if ($file =~ /^php.*?([\d\.]+)$/) {
my $nodot = $ver;
$nodot =~ s/\.//g;
my $binary = &has_command("php$ver") ||
&has_command("php$nodot");
&has_command("php$nodot") ||
&has_command("php$ver-cgi") ||
&has_command("php$nodot-cgi");
return $binary if ($binary);
}
@@ -863,5 +866,157 @@ else {
return @poss;
}
# list_php_base_packages()
# Returns a list of hash refs, one per PHP version installed, with the
# following keys :
# name - Package name
# system - Package system
# ver - Package version
# phpver - PHP version
sub list_php_base_packages
{
&foreign_require("software");
my $n = &software::list_packages();
my @rv;
my %done;
for(my $i=0; $i<$n; $i++) {
my $name = $software::packages{$i,'name'};
next if ($name !~ /^(php\d*)(-php|-runtime)?$/);
$name = $1;
my $phpver = $software::packages{$i,'version'};
$phpver =~ s/\-.*$//;
my $bin;
foreach my $b ($name, $name."-cgi", "php-".$phpver) {
if ($bin = &has_command($b)) {
last;
}
}
if ($bin) {
my $out = &backquote_command("$bin -v 2>&1");
if ($out =~ /(^|\n)PHP\s+([\d\.]+)/) {
$phpver = $2;
}
}
my $shortver = $phpver;
$shortver =~ s/^(\d+\.\d+).*$/$1/;
if ($shortver =~ /^5\./) {
$shortver = "5";
}
push(@rv, { 'name' => $software::packages{$i,'name'},
'system' => $software::packages{$i,'system'},
'ver' => $software::packages{$i,'version'},
'shortver' => $shortver,
'phpver' => $phpver,
'binary' => $bin, });
}
@rv = sort { $a->{'name'} cmp $b->{'name'} } @rv;
@rv = grep { !$done{$_->{'shortver'}}++ } @rv;
return sort { &compare_version_numbers($a->{'ver'}, $b->{'ver'}) } @rv;
}
# list_all_php_module_packages(base-package)
# Returns all install packages for PHP extensions of a given base package
sub list_all_php_module_packages
{
my ($base) = @_;
$base =~ s/(-php|-runtime)$//;
my @rv;
&foreign_require("software");
my $n = &software::list_packages();
for(my $i=0; $i<$n; $i++) {
my $name = $software::packages{$i,'name'};
next if ($name !~ /^\Q$base\E-/);
push(@rv, { 'name' => $software::packages{$i,'name'},
'system' => $software::packages{$i,'system'},
'ver' => $software::packages{$i,'version'},
});
}
return @rv;
}
# list_available_php_packages()
# Returns a list of hash refs, one per PHP version available, with the
# following keys :
# name - Package name
# ver - Package version
# phpver - PHP version
sub list_available_php_packages
{
&foreign_require("package-updates");
my @rv;
foreach my $pkg (&package_updates::list_available()) {
my $name = $pkg->{'name'};
next if ($name !~ /^php(\d*)$/);
my $phpver = $pkg->{'version'};
$phpver =~ s/\-.*$//;
my $shortver = $phpver;
$shortver =~ s/^(\d+\.\d+).*$/$1/;
if ($shortver =~ /^5\./) {
$shortver = "5";
}
push(@rv, { 'name' => $pkg->{'name'},
'ver' => $pkg->{'version'},
'shortver' => $shortver,
'phpver' => $phpver,
});
}
return sort { &compare_version_numbers($a->{'ver'}, $b->{'ver'}) } @rv;
}
# get_virtualmin_php_map()
# Return a hash mapping PHP versions like 5 or 7.2 to a list of domains, or
# undef if Virtualmin isn't installed
sub get_virtualmin_php_map
{
my %vmap;
&foreign_check("virtual-server") || return undef;
&foreign_require("virtual-server");
foreach my $d (&virtual_server::list_domains()) {
my $v = $d->{'php_mode'} eq 'fpm' ? $d->{'php_fpm_version'}
: $d->{'php_version'};
if ($v) {
$vmap{$v} ||= [ ];
push(@{$vmap{$v}}, $d);
}
}
return \%vmap;
}
# list_all_php_version_packages(&base-pkg)
# Returns all package names for installed packages related to one PHP package,
# such as those for extensions
sub list_all_php_version_packages
{
my ($pkg) = @_;
&foreign_require("software");
my @rv = map { $_->{'name'} }
&list_all_php_module_packages($pkg->{'name'});
my $base = $pkg->{'name'};
$base =~ s/-php$//;
my @poss = ( @modpkgs, $base."-php", $base."-runtime", $base );
foreach my $p (@poss) {
my @info = &software::package_info($p, $pkg->{'ver'});
next if (!@info);
push(@rv, $p);
}
return @rv;
}
# delete_php_base_package(&package)
# Delete a PHP package, and return undef on success or an error on failure
sub delete_php_base_package
{
my ($pkg) = @_;
foreach my $p (&list_all_php_version_packages($pkg)) {
my @info = &software::package_info($p);
next if (!@info);
my $err = &software::delete_package($p, { 'nodeps' => 1 });
if ($err) {
return &html_strip($err);
}
}
return undef;
}
1;

View File

@@ -7,7 +7,7 @@ require 'proc-lib.pl';
sub syslog_getlogs
{
if ($gconfig{'os_type'} =~ /-linux$/) {
return ( { 'cmd' => "dmesg",
return ( { 'cmd' => "dmesg -T",
'desc' => $text{'syslog_dmesg'},
'active' => 1, } );
}

View File

@@ -226,11 +226,11 @@ sub find_textfile
local($conf, $dbm) = @_;
if ($conf) { return $conf; }
elsif (!$dbm) { return undef; }
elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash)$/i && -r $1) {
elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash|cdb)$/i && -r $1) {
# Database is like /etc/virtusertable.db, text is /etc/virtusertable
return $1;
}
elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash)$/i && -r "$1.txt") {
elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash|cdb)$/i && -r "$1.txt") {
# Database is like /etc/virtusertable.db, text is /etc/virtusertable.txt
return "$1.txt";
}
@@ -238,7 +238,7 @@ elsif (-r "$dbm.txt") {
# Database is like /etc/virtusertable, text is /etc/virtusertable.txt
return "$dbm.txt";
}
elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash)$/i) {
elsif ($dbm =~ /^(.*)\.(db|dbm|pag|dir|hash|cdb)$/i) {
# Database is like /etc/virtusertable.db, text is /etc/virtusertable,
# but doesn't exist yet.
return $1;

View File

@@ -3,7 +3,7 @@ scan_time=5
display_mode=0
sort_mode=0
show_status=1
deflink=0
deffast=2
deflink=1
deffast=1
show_ip=0
max_servers=100

View File

@@ -4,7 +4,7 @@ display_mode=0
sort_mode=0
show_status=1
deflink=0
deffast=2
deffast=1
show_ip=0
max_servers=100
capath=/usr/share/ca-certificates /etc/ssl/certs

View File

@@ -4,7 +4,7 @@ display_mode=0
sort_mode=0
show_status=1
deflink=0
deffast=2
deffast=1
show_ip=0
max_servers=100
capath=/etc/pki/tls/certs/ca-bundle.crt

View File

@@ -1,4 +1,4 @@
deffast=2
deffast=1
max_servers=100
resolve=1
deflink=0

View File

@@ -7,7 +7,7 @@ sort_mode=Sort servers by,4,4-IP Address,1-Hostname,2-Description,3-OS,5-Group,0
show_status=Show status for servers,1,1-Yes,0-No
show_ip=Always show address and port on main page?,1,1-Yes,0-No
deflink=Default login mode,4,0-Normal link to server,1-Login via Webmin,2-Login when icon is clicked,3-Login with same username and password
deffast=Default RPC mode,1,1-Fast,2-Automatic,0-Slow
deffast=Default RPC mode,1,2-Automatic,1-Fast,0-Slow
auto_type=Default system type,14,show_deftype
skipips=IPs or hostnames of systems to not detect,9,50,5,\t
skipifaces=Network interfaces to not detect,0

Some files were not shown because too many files have changed in this diff Show More