mirror of
https://github.com/webmin/webmin.git
synced 2026-08-21 14:30:41 +01:00
Compare commits
341 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d09b0724c | ||
|
|
7e8366bcb8 | ||
|
|
1335d05f7c | ||
|
|
010f15c2a5 | ||
|
|
e10acfa3bb | ||
|
|
440ddabef1 | ||
|
|
5232c07332 | ||
|
|
53d0d053cf | ||
|
|
1d369dcddf | ||
|
|
523d68c67a | ||
|
|
04efe99340 | ||
|
|
91958ee2c0 | ||
|
|
eb779294fd | ||
|
|
b9766d97a6 | ||
|
|
d8449b9417 | ||
|
|
ad890156fa | ||
|
|
6c74264916 | ||
|
|
ad3ddc489f | ||
|
|
87db158afc | ||
|
|
752d43adb8 | ||
|
|
140e4121b1 | ||
|
|
9de7560728 | ||
|
|
685c07ffbb | ||
|
|
cc02cbabb4 | ||
|
|
05d42e4796 | ||
|
|
5b9dc02948 | ||
|
|
e83202988e | ||
|
|
91f51f7390 | ||
|
|
d87808ca73 | ||
|
|
16c16f4fd4 | ||
|
|
53c3bef94c | ||
|
|
fc6b66fcc0 | ||
|
|
100253bec3 | ||
|
|
3e38e3268e | ||
|
|
d2ba0d910b | ||
|
|
cbc9595649 | ||
|
|
6ed05b5e25 | ||
|
|
c487b579ed | ||
|
|
522925403d | ||
|
|
844b5f8174 | ||
|
|
308cb0c71d | ||
|
|
93befb0a1a | ||
|
|
fc241dd8cd | ||
|
|
d26f4fb7f3 | ||
|
|
28ba5883ef | ||
|
|
52d0382619 | ||
|
|
1f8030a523 | ||
|
|
d93fd6a4b6 | ||
|
|
a5be2f9d39 | ||
|
|
8c2541fdc8 | ||
|
|
ef49236f6a | ||
|
|
79adc13008 | ||
|
|
3c20bd5a4f | ||
|
|
7f63875c42 | ||
|
|
78c9e8f2c5 | ||
|
|
b2fec1756d | ||
|
|
3e394323c7 | ||
|
|
267f05ed73 | ||
|
|
846bbb8252 | ||
|
|
578a41769e | ||
|
|
1d03afbdd5 | ||
|
|
41b8be4ac7 | ||
|
|
251fef722d | ||
|
|
c1ba586dba | ||
|
|
3c8e1d0089 | ||
|
|
b6025b2fc2 | ||
|
|
42142f7a5f | ||
|
|
256046ed1f | ||
|
|
d1c6e8d3a3 | ||
|
|
d81eb13f22 | ||
|
|
ab37804ef9 | ||
|
|
9eff352005 | ||
|
|
4bdb518493 | ||
|
|
b658bdd3ed | ||
|
|
6458658bfb | ||
|
|
c306818f50 | ||
|
|
fa26f8699c | ||
|
|
b71c046596 | ||
|
|
0216b7162f | ||
|
|
d6d6b8806d | ||
|
|
9587d3d091 | ||
|
|
3b819eafb5 | ||
|
|
49138dc5b5 | ||
|
|
21e3367a9c | ||
|
|
3f367adf8d | ||
|
|
2d01675139 | ||
|
|
e60d005ab0 | ||
|
|
7d129ee5e1 | ||
|
|
14abf9f938 | ||
|
|
f508c58929 | ||
|
|
3cff366b1f | ||
|
|
e4b7e97848 | ||
|
|
bf5ae8b5e5 | ||
|
|
257fc2d87c | ||
|
|
45292ea815 | ||
|
|
1d4556b905 | ||
|
|
4cceba5f8f | ||
|
|
d41377983e | ||
|
|
f65fe5b44c | ||
|
|
ccbe7369dd | ||
|
|
d0f6a7672f | ||
|
|
042891c941 | ||
|
|
af175ce12c | ||
|
|
065ce627a0 | ||
|
|
869173d7c6 | ||
|
|
1a86501e88 | ||
|
|
60a9bc010c | ||
|
|
86b9014b21 | ||
|
|
dd4e3e22ef | ||
|
|
361d3b5175 | ||
|
|
aa87f85d4a | ||
|
|
8159fad28f | ||
|
|
4fa30e782e | ||
|
|
b251b7182c | ||
|
|
aeaa9333b8 | ||
|
|
585293fbd3 | ||
|
|
ae2c6a4301 | ||
|
|
4e734a9bd0 | ||
|
|
222d92e392 | ||
|
|
de8e5e36d8 | ||
|
|
e36729f20b | ||
|
|
96dd0ef65d | ||
|
|
d367189711 | ||
|
|
0db0cf77f9 | ||
|
|
d3c9f331c8 | ||
|
|
7dd3902da8 | ||
|
|
413087ae84 | ||
|
|
911aa64a36 | ||
|
|
c6647ce76c | ||
|
|
0b478a1940 | ||
|
|
2b8091537c | ||
|
|
0863d6ba7a | ||
|
|
d46c8f20d5 | ||
|
|
0d3e3d9473 | ||
|
|
084f7b7314 | ||
|
|
29952dce1e | ||
|
|
d202eca8f8 | ||
|
|
236c5cf489 | ||
|
|
99371ad462 | ||
|
|
a9aae79fcd | ||
|
|
04ae776e6a | ||
|
|
7cab23a3ea | ||
|
|
04c33e77a4 | ||
|
|
9dccd2cdce | ||
|
|
1645cadc91 | ||
|
|
2c8ff4ba15 | ||
|
|
da0ff56ee0 | ||
|
|
bf43c793d3 | ||
|
|
46d571c6b5 | ||
|
|
ce1ab74c6f | ||
|
|
4472f210b9 | ||
|
|
7aeb5e4dd7 | ||
|
|
77d817357d | ||
|
|
350908ed56 | ||
|
|
94ac2ff7d7 | ||
|
|
a24e5371b7 | ||
|
|
0810083588 | ||
|
|
2ec6cadbbd | ||
|
|
4c3f7f5bd9 | ||
|
|
1b5e48841a | ||
|
|
241abfe719 | ||
|
|
f78413549b | ||
|
|
b53cce9084 | ||
|
|
a92b52f502 | ||
|
|
c0c0cc323c | ||
|
|
da49c5b9b8 | ||
|
|
5b5c3cc4b1 | ||
|
|
f0b7f10b64 | ||
|
|
bdad9fd173 | ||
|
|
7e01b3eb44 | ||
|
|
95fee0cc33 | ||
|
|
18a6fc3b53 | ||
|
|
c38793c955 | ||
|
|
45376dee35 | ||
|
|
44ff20e5c6 | ||
|
|
159cc14dfc | ||
|
|
aa84044375 | ||
|
|
02b5c9c121 | ||
|
|
b5518df7bd | ||
|
|
2c608b2c71 | ||
|
|
d1523b9648 | ||
|
|
9987b2d493 | ||
|
|
83eb3eeffc | ||
|
|
a6e6b1d21c | ||
|
|
e65c88e7ef | ||
|
|
2bcf00b50d | ||
|
|
eb4fafc504 | ||
|
|
5101871760 | ||
|
|
0c8f74597b | ||
|
|
d3a09db938 | ||
|
|
f4fea0026f | ||
|
|
dbb19c30c4 | ||
|
|
5c66e544b1 | ||
|
|
5671bd4ce6 | ||
|
|
12eff54277 | ||
|
|
6c1de362e3 | ||
|
|
1d2e1983bf | ||
|
|
91f7d5b5c5 | ||
|
|
9d7f4f9d05 | ||
|
|
bedca1546b | ||
|
|
0e4349565a | ||
|
|
a0fb85c152 | ||
|
|
599caa1cd8 | ||
|
|
1d5b426043 | ||
|
|
d61852cc72 | ||
|
|
fd567e6860 | ||
|
|
0cdcb932b1 | ||
|
|
2fe57dd456 | ||
|
|
c8bcccd9b9 | ||
|
|
272a8715f7 | ||
|
|
a664b9d0c0 | ||
|
|
80d1e688c8 | ||
|
|
3c9d53109b | ||
|
|
6825dc11d6 | ||
|
|
1ed1ff84a2 | ||
|
|
4220d18072 | ||
|
|
7f2b4b00aa | ||
|
|
6fb304e384 | ||
|
|
82e9e1c7dd | ||
|
|
2dcb17c408 | ||
|
|
684bb4cc67 | ||
|
|
1d67452a00 | ||
|
|
a6db30bb49 | ||
|
|
df9eb7239b | ||
|
|
8eb0868574 | ||
|
|
95b43e91e1 | ||
|
|
f8bdac8e90 | ||
|
|
1293a2cf4f | ||
|
|
f0a5b92b18 | ||
|
|
dc4668a6b4 | ||
|
|
60951853a9 | ||
|
|
d4208ada15 | ||
|
|
122752f384 | ||
|
|
83a0156217 | ||
|
|
1bb477d2ee | ||
|
|
c9e577e220 | ||
|
|
3977873c0e | ||
|
|
d0604b5d4d | ||
|
|
41e32f4e37 | ||
|
|
a7afa3a4f6 | ||
|
|
db17606643 | ||
|
|
7c7ee616f0 | ||
|
|
fd9b736175 | ||
|
|
25afc8aa02 | ||
|
|
68aab1c057 | ||
|
|
19190a6f5b | ||
|
|
cf432879a1 | ||
|
|
cef294dc5a | ||
|
|
843fc26d97 | ||
|
|
25f15ce10e | ||
|
|
cc9c51c42f | ||
|
|
6a61d50078 | ||
|
|
948f5bfd77 | ||
|
|
73fadd13c8 | ||
|
|
d567b09d24 | ||
|
|
12069d87af | ||
|
|
6c211e721c | ||
|
|
bb39d752a9 | ||
|
|
ae35b100c2 | ||
|
|
84c50bba95 | ||
|
|
544703c1b8 | ||
|
|
44c7b36160 | ||
|
|
6639768aa4 | ||
|
|
39a4b9454d | ||
|
|
9d6b7bc939 | ||
|
|
4f3e993ae6 | ||
|
|
632232fff0 | ||
|
|
4d680b1ea9 | ||
|
|
f03140314e | ||
|
|
6c77b24da6 | ||
|
|
a293fff996 | ||
|
|
da18a16c84 | ||
|
|
0424a98a9b | ||
|
|
ba336c297b | ||
|
|
7183af2fdd | ||
|
|
02dd602d07 | ||
|
|
59fae69c6b | ||
|
|
3bd85ab407 | ||
|
|
87d8969efb | ||
|
|
97774b829d | ||
|
|
33e03595cf | ||
|
|
4b79787fb2 | ||
|
|
bd7e91c712 | ||
|
|
67950afe3a | ||
|
|
a6156ff76b | ||
|
|
6de6529bba | ||
|
|
cf98ce3f55 | ||
|
|
c0fb00a6e4 | ||
|
|
49b8f1a2fa | ||
|
|
3a1df9d797 | ||
|
|
11fafb738d | ||
|
|
0c2987a326 | ||
|
|
f37a73f0fb | ||
|
|
07321eec44 | ||
|
|
ac8cbf57f9 | ||
|
|
995f4fa6c1 | ||
|
|
3f3a84c830 | ||
|
|
dde3f1642e | ||
|
|
2c01d21a1d | ||
|
|
6337f2fefa | ||
|
|
de9e95facf | ||
|
|
5cf228d4a0 | ||
|
|
0e45e0bcbd | ||
|
|
bdb98c49c9 | ||
|
|
9369441fc5 | ||
|
|
77e488b4b6 | ||
|
|
26faad0d39 | ||
|
|
886cf142db | ||
|
|
d4439b445c | ||
|
|
5a336902f8 | ||
|
|
19b0f187ba | ||
|
|
4a283d2180 | ||
|
|
670f33c872 | ||
|
|
b5b65f06b7 | ||
|
|
b02d797bc6 | ||
|
|
b9fbf4b2c3 | ||
|
|
ef1fb66954 | ||
|
|
316529c8ca | ||
|
|
d1e72c08a0 | ||
|
|
7ed4763f00 | ||
|
|
fe90fb2479 | ||
|
|
e44a25191f | ||
|
|
3dbeb4e4db | ||
|
|
7c5d4087fc | ||
|
|
83e4fed616 | ||
|
|
5b8dba4a5f | ||
|
|
2404e1ddfc | ||
|
|
3a75f0f3f8 | ||
|
|
a1091556db | ||
|
|
48269733b1 | ||
|
|
9145c23126 | ||
|
|
4368e00250 | ||
|
|
31d4b6dfd6 | ||
|
|
163dd04175 | ||
|
|
3f96fb8adb | ||
|
|
8242714b99 | ||
|
|
179ddf751b | ||
|
|
e92fc730ee | ||
|
|
d546116ab7 | ||
|
|
0d70782330 | ||
|
|
d89f1ee1de |
15
.github/workflows/close-inactive.yml
vendored
Normal file
15
.github/workflows/close-inactive.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: Close inactive
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 12 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
close-inactive:
|
||||
uses: webmin/webmin-ci-cd/.github/workflows/close-inactive.yml@main
|
||||
12
.github/workflows/code-review.yml
vendored
Normal file
12
.github/workflows/code-review.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Code Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
code-review:
|
||||
uses: webmin/webmin-ci-cd/.github/workflows/code-review.yml@main
|
||||
secrets:
|
||||
CODE_REVIEW_API_KEY: ${{ secrets.CODE_REVIEW_API_KEY }}
|
||||
19
.github/workflows/tests.yml
vendored
Normal file
19
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
prove:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install Perl::Critic
|
||||
run: sudo apt-get update && sudo apt-get install -y libperl-critic-perl
|
||||
- name: prove -lr
|
||||
run: prove -lr
|
||||
4
.github/workflows/webmin.dev+webmin.yml
vendored
4
.github/workflows/webmin.dev+webmin.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: "webmin.dev: webmin/webmin"
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -25,3 +25,5 @@ jobs:
|
||||
PRERELEASE_UPLOAD_SSH_DIR: ${{ secrets.PRERELEASE_UPLOAD_SSH_DIR }}
|
||||
DEV_SSH_PRV_KEY: ${{ secrets.DEV_SSH_PRV_KEY }}
|
||||
ALL_GPG_PH2: ${{ secrets.ALL_GPG_PH2 }}
|
||||
CODE_REVIEW_API_KEY: ${{ secrets.CODE_REVIEW_API_KEY }}
|
||||
CODE_REVIEW_SMTP_PASSWORD: ${{ secrets.CODE_REVIEW_SMTP_PASSWORD }}
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -22,3 +22,4 @@ tarballs/
|
||||
minimal/
|
||||
.DS_Store
|
||||
.vscode/settings.json
|
||||
debug.cgi
|
||||
|
||||
6
.perlcriticrc
Normal file
6
.perlcriticrc
Normal file
@@ -0,0 +1,6 @@
|
||||
severity = 5
|
||||
|
||||
# Octal file permission literals (0700, 0640, etc.) are the standard Perl
|
||||
# idiom for chmod/mkdir/permission helpers throughout this codebase. The
|
||||
# policy flags chmod 0700 itself, so it is too coarse for our use.
|
||||
[-ValuesAndExpressions::ProhibitLeadingZeros]
|
||||
39
CHANGELOG.md
39
CHANGELOG.md
@@ -1,5 +1,42 @@
|
||||
## Changelog
|
||||
|
||||
#### 2.641 (May 10, 2026)
|
||||
* Fixed a bug when editing monitors in the System and Server Status module
|
||||
* Fix Fail2Ban default jail options
|
||||
* Added support for trusted proxy IP addresses
|
||||
|
||||
#### 2.640 (May 4, 2026)
|
||||
* Add new nftables module with profiles, saved tables, and chains/sets management
|
||||
* Add new Nginx module with look and feel matching the Apache module
|
||||
* Add option to hide sensitive values (like passwords or tokens) from Webmin's request logs
|
||||
* Add custom ACME server support for Webmin SSL renewal
|
||||
* Add support for the latest MariaDB on Ubuntu 26.04
|
||||
* Add multi-statement SQL query support when executing inline in MySQL/MariaDB module
|
||||
* Add support for ext4 hidden inode quota mode
|
||||
* Add used space and usage percentage reporting for ZFS in the dashboard
|
||||
* Add mass enable and disable buttons for status monitors in the System and Server Status module
|
||||
* Update tiny ACME client to the latest version
|
||||
* Update DHCP default config for openSUSE 16 [#2678](https://github.com/webmin/webmin/issues/2678)
|
||||
* Fix to prevent bypassing two-factor authentication in RPC requests
|
||||
* Fix session cookies to use safer defaults
|
||||
* Fix handling of connections coming through a reverse proxy
|
||||
* Fix unsafe mailbox attachment handling in Mailbox module
|
||||
* Fix unsafe decoding of Outlook `winmail.dat` attachments
|
||||
* Fix Certbot standalone port conflicts
|
||||
* Fix to correctly preserve full quoted action parameters in the Fail2Ban jail editor [#2647](https://github.com/webmin/webmin/issues/2647)
|
||||
* Fix Fail2Ban default jail options to preserve required timing defaults when saving
|
||||
* Fix ZFS to fall back to `df` when disk space cannot be computed from `zpool`
|
||||
* Fix to allow toggling process priority and I/O controls on or off
|
||||
* Fix issue where disabled email notifications were still being processed
|
||||
* Update Authentic theme to the latest version with various improvements and fixes:
|
||||
- Upgrade stats history graphs from laggy SVG to a blazing-fast canvas renderer
|
||||
- Add option to control corner roundness for the menu, content area and right-side slider
|
||||
- Change the content area to use rounded corners and a margin by default
|
||||
- Fix message of the day display in login page correctly [webmin#2555](https://github.com/webmin/webmin/issues/2685)
|
||||
- Fix tooltip visibility in dark palette
|
||||
- Fix session login button spinner
|
||||
- Fix various button styling issues (active state, tiny buttons, airy buttons, stack position)
|
||||
|
||||
#### 2.630 (March 24, 2026)
|
||||
* Add improvements to user input validation across all modules
|
||||
* Update Authentic theme to the latest version with various improvements and fixes:
|
||||
@@ -542,7 +579,7 @@ This release adds automatic translations for all languages in UTF-8, updates the
|
||||
This release updates the built-in Let's Encrypt client, adds support for creating "safe-mode" Webmin users, support for CAA records in the BIND module, and the ability to search Postfix maps. It also updates the Authentic theme to the latest version, which includes numerous improvements to the File Manager and overall UI.
|
||||
|
||||
#### Version 1.930 (August 18, 2019)
|
||||
These updates fix a [security vulnerability](http://webmin.com/security.html) and should be installed IMMEDIATELY by all users. Although it is not exploitable in a Webmin install with the default configuration, upgrading is strongly recommended.
|
||||
These updates fix a [security vulnerability](https://webmin.com/security/) and should be installed IMMEDIATELY by all users. Although it is not exploitable in a Webmin install with the default configuration, upgrading is strongly recommended.
|
||||
|
||||
#### Version 1.920 (July 4, 2019)
|
||||
This update includes the latest theme version, translation updates, the ability to disable hosts file entries, easier monitoring of bootup actions, and a bunch of bugfixes.
|
||||
|
||||
10
README-zh.md
10
README-zh.md
@@ -1,7 +1,7 @@
|
||||
## 内容
|
||||
* [更新日志](https://github.com/webmin/webmin/blob/master/CHANGELOG.md)
|
||||
* [关于](#关于)
|
||||
* [安装](#安装)[<img src="https://github.com/webmin-devel/webmin/blob/master/media/download-23x14-stable.png?raw=true" title="稳定版">](http://webmin.com/download.html)[<img src="https://github.com/webmin-devel/webmin/blob/master/media/download-23x14-devel.png?raw=true" title="Development Versions">](http://webmin.com/devel.html)
|
||||
* [安装](#安装)[<img src="https://github.com/webmin-devel/webmin/blob/master/media/download-23x14-stable.png?raw=true" title="稳定版">](https://webmin.com/download.html)[<img src="https://github.com/webmin-devel/webmin/blob/master/media/download-23x14-devel.png?raw=true" title="Development Versions">](https://webmin.com/devel.html)
|
||||
* [文档](#文档)
|
||||
* [致谢](#致谢)
|
||||
* [许可](#许可)
|
||||
@@ -26,11 +26,11 @@ Perl 5.10 或更高。
|
||||
## 安装
|
||||
Webmin 可以两种方法安装:
|
||||
|
||||
1. 下载一个预编译包,可用于不同的发行版(CentOS, Fedora, SuSE, Mandriva, Debian, Ubuntu, Solaris 和 [其他发行版](http://www.webmin.com/support.html))。[下载页面直达车](http://webmin.com/download.html);
|
||||
1. 下载一个预编译包,可用于不同的发行版(CentOS, Fedora, SuSE, Mandriva, Debian, Ubuntu, Solaris 和 [其他发行版](https://webmin.com/support.html))。[下载页面直达车](https://webmin.com/download.html);
|
||||
<kbd>注:非常建议[在你的系统添加源](https://doxfer.webmin.com/Webmin/Installation),这样可以自动更新</kbd>
|
||||
|
||||
2. 下载并解压[源码](https://prdownloads.sourceforge.net/webadmin/webmin-1.996.tar.gz)然后运行[_setup.sh_](http://www.webmin.com/tgz.html) 脚本,无需任何选项,也就是说会直接安装到当前目录。或者使用命令行参数,例如目标目录。
|
||||
<kbd>注:如果你正在安装 Webmin [到Windows](http://www.webmin.com/windows.html) 系统上,你必须运行 `perl setup.pl` 命令。Windows 版能否正常运行取决于许多程序,和可能不属于标准发行版的模块。你需要 _process.exe_ 命令, _sc.exe_ 命令,以及 _Win32::Daemon_ Perl 模块。</kbd>
|
||||
2. 下载并解压[源码](https://prdownloads.sourceforge.net/webadmin/webmin-1.996.tar.gz)然后运行[_setup.sh_](https://webmin.com/tgz.html) 脚本,无需任何选项,也就是说会直接安装到当前目录。或者使用命令行参数,例如目标目录。
|
||||
<kbd>注:如果你正在安装 Webmin [到Windows](https://webmin.com/windows.html) 系统上,你必须运行 `perl setup.pl` 命令。Windows 版能否正常运行取决于许多程序,和可能不属于标准发行版的模块。你需要 _process.exe_ 命令, _sc.exe_ 命令,以及 _Win32::Daemon_ Perl 模块。</kbd>
|
||||
|
||||
## 文档
|
||||
完整的 Webmin 还有它所有模块的详细配置都在[维基页面](https://doxfer.webmin.com/Webmin/Main_Page).
|
||||
@@ -39,7 +39,7 @@ Webmin 可以两种方法安装:
|
||||
|
||||
### 首席开发者
|
||||
|
||||
* [Jamie Cameron](http://www.webmin.com/about.html) [](https://www.linkedin.com/in/jamiecameron2)
|
||||
* [Jamie Cameron](https://webmin.com/about.html) [](https://www.linkedin.com/in/jamiecameron2)
|
||||
|
||||
### 贡献者
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ For detailed installation instructions check our guide on [webmin.com/download](
|
||||
|
||||
### Lead developer
|
||||
|
||||
* [Jamie Cameron](https://www.webmin.com/about.html) [](https://www.linkedin.com/in/jamiecameron2)
|
||||
* [Jamie Cameron](https://webmin.com/about.html) [](https://www.linkedin.com/in/jamiecameron2)
|
||||
|
||||
### Developers
|
||||
* [Ilia Rostovtsev](https://github.com/iliaross)
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -11,7 +11,7 @@ Library for editing webmin users, passwords and access rights.
|
||||
|
||||
=cut
|
||||
|
||||
BEGIN { push(@INC, ".."); };
|
||||
BEGIN { push(@INC, ".."); }; ## no critic
|
||||
use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
@@ -92,7 +92,6 @@ while(my $l = <$fh>) {
|
||||
$user{'locale'} = $gconfig{"locale_$user[0]"};
|
||||
$user{'dateformat'} = $gconfig{"dateformat_$user[0]"};
|
||||
$user{'notabs'} = $gconfig{"notabs_$user[0]"};
|
||||
$user{'rbacdeny'} = $gconfig{"rbacdeny_$user[0]"};
|
||||
if ($gconfig{"theme_$user[0]"}) {
|
||||
($user{'theme'}, $user{'overlay'}) =
|
||||
split(/\s+/, $gconfig{"theme_$user[0]"});
|
||||
@@ -353,7 +352,8 @@ each of which is a hash reference in the same format as their module.info files.
|
||||
sub list_module_infos
|
||||
{
|
||||
my @mods = grep { &check_os_support($_) } &get_all_module_infos();
|
||||
return sort { $a->{'desc'} cmp $b->{'desc'} } @mods;
|
||||
my @sorted = sort { $a->{'desc'} cmp $b->{'desc'} } @mods;
|
||||
return @sorted;
|
||||
}
|
||||
|
||||
=head2 create_user(&details, [clone])
|
||||
@@ -501,8 +501,6 @@ else {
|
||||
$gconfig{"lang_".$user->{'name'}} = $user->{'lang'} if ($user->{'lang'});
|
||||
delete($gconfig{"notabs_".$user->{'name'}});
|
||||
$gconfig{"notabs_".$user->{'name'}} = $user->{'notabs'} if ($user->{'notabs'});
|
||||
delete($gconfig{"rbacdeny_".$user->{'name'}});
|
||||
$gconfig{"rbacdeny_".$user->{'name'}} = $user->{'rbacdeny'} if ($user->{'rbacdeny'});
|
||||
delete($gconfig{"ownmods_".$user->{'name'}});
|
||||
$gconfig{"ownmods_".$user->{'name'}} = join(" ", @{$user->{'ownmods'}})
|
||||
if ($user->{'ownmods'} && @{$user->{'ownmods'}});
|
||||
@@ -722,9 +720,6 @@ else {
|
||||
delete($gconfig{"notabs_".$username});
|
||||
$gconfig{"notabs_".$user->{'name'}} = $user->{'notabs'}
|
||||
if ($user->{'notabs'});
|
||||
delete($gconfig{"rbacdeny_".$username});
|
||||
$gconfig{"rbacdeny_".$user->{'name'}} = $user->{'rbacdeny'}
|
||||
if ($user->{'rbacdeny'});
|
||||
delete($gconfig{"ownmods_".$username});
|
||||
$gconfig{"ownmods_".$user->{'name'}} = join(" ", @{$user->{'ownmods'}})
|
||||
if ($user->{'ownmods'} && @{$user->{'ownmods'}});
|
||||
@@ -1337,12 +1332,12 @@ my ($miniserv) = @_;
|
||||
my $sfile = $miniserv->{'sessiondb'} ? $miniserv->{'sessiondb'} :
|
||||
$miniserv->{'pidfile'} =~ /^(.*)\/[^\/]+$/ ? "$1/sessiondb"
|
||||
: return;
|
||||
eval "use SDBM_File";
|
||||
eval { require SDBM_File; SDBM_File->import; 1 };
|
||||
dbmopen(%sessiondb, $sfile, 0700);
|
||||
eval { $sessiondb{'1111111111'} = 'foo bar' };
|
||||
if ($@) {
|
||||
dbmclose(%sessiondb);
|
||||
eval "use NDBM_File";
|
||||
eval { require NDBM_File; NDBM_File->import; 1 };
|
||||
dbmopen(%sessiondb, $sfile, 0700);
|
||||
}
|
||||
else {
|
||||
@@ -1428,10 +1423,10 @@ Creates a new session ID that's already logged in as the given user
|
||||
sub create_session_user
|
||||
{
|
||||
my ($miniserv, $username, $lifetime) = @_;
|
||||
return undef if (&is_readonly_mode());
|
||||
return if (&is_readonly_mode());
|
||||
&open_session_db($miniserv);
|
||||
my $sid = &generate_random_session_id();
|
||||
return undef if (!$sid);
|
||||
return if (!$sid);
|
||||
my $t = time();
|
||||
$sessiondb{$sid} = "$username $t 127.0.0.1".($lifetime ? " ".$lifetime : "");
|
||||
dbmclose(%sessiondb);
|
||||
@@ -1699,7 +1694,7 @@ elsif (&has_command("ssleay")) {
|
||||
return &has_command("ssleay");
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1815,6 +1810,7 @@ foreach my $g (&list_groups()) {
|
||||
return $g;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 check_password_restrictions(username, password)
|
||||
@@ -1859,7 +1855,7 @@ if ($miniserv{'pass_oldblock'} && $user) {
|
||||
last if ($c++ > $miniserv{'pass_oldblock'});
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 hash_session_id(sid)
|
||||
@@ -1896,11 +1892,11 @@ my $use_md5 = &md5_perl_module();
|
||||
$use_md5 || &error("No Perl MD5 hashing module found!");
|
||||
|
||||
# Add the password
|
||||
my $ctx = eval "new $use_md5";
|
||||
my $ctx = $use_md5->new;
|
||||
$ctx->add($passwd);
|
||||
|
||||
# Add some more stuff from the hash of the password and salt
|
||||
my $ctx1 = eval "new $use_md5";
|
||||
my $ctx1 = $use_md5->new;
|
||||
$ctx1->add($passwd);
|
||||
$ctx1->add($passwd);
|
||||
my $final = $ctx1->digest();
|
||||
@@ -1949,12 +1945,12 @@ Returns a Perl module for MD5 hashing, or undef if none.
|
||||
sub md5_perl_module
|
||||
{
|
||||
my $use_md5;
|
||||
eval "use MD5";
|
||||
eval { require MD5; MD5->import; 1 };
|
||||
if (!$@) {
|
||||
$use_md5 = "MD5";
|
||||
}
|
||||
else {
|
||||
eval "use Digest::MD5";
|
||||
eval { require Digest::MD5; Digest::MD5->import; 1 };
|
||||
if (!$@) {
|
||||
$use_md5 = "Digest::MD5";
|
||||
}
|
||||
@@ -2111,16 +2107,16 @@ my ($str, $notablecheck) = @_;
|
||||
my ($proto, $user, $pass, $host, $prefix, $args) = &split_userdb_string($str);
|
||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
# Load DBI driver
|
||||
eval 'use DBI;';
|
||||
eval { require DBI; DBI->import; 1 };
|
||||
return &text('sql_emod', 'DBI') if ($@);
|
||||
if ($proto eq "mysql") {
|
||||
eval 'use DBD::mysql;';
|
||||
eval { require DBD::mysql; DBD::mysql->import; 1 };
|
||||
return &text('sql_emod', 'DBD::mysql') if ($@);
|
||||
my $drh = DBI->install_driver("mysql");
|
||||
return $text{'sql_emysqldriver'} if (!$drh);
|
||||
}
|
||||
else {
|
||||
eval 'use DBD::Pg;';
|
||||
eval { require DBD::Pg; DBD::Pg->import; 1 };
|
||||
return &text('sql_emod', 'DBD::Pg') if ($@);
|
||||
my $drh = DBI->install_driver("Pg");
|
||||
return $text{'sql_epostgresqldriver'} if (!$drh);
|
||||
@@ -2152,11 +2148,11 @@ if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||
}
|
||||
}
|
||||
&disconnect_userdb($str, $dbh);
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
elsif ($proto eq "ldap") {
|
||||
# Load LDAP module
|
||||
eval 'use Net::LDAP;';
|
||||
eval { require Net::LDAP; Net::LDAP->import; 1 };
|
||||
return &text('sql_emod', 'Net::LDAP') if ($@);
|
||||
|
||||
# Try to connect
|
||||
@@ -2190,7 +2186,7 @@ elsif ($proto eq "ldap") {
|
||||
$found || return &text('sql_eldapdn', $prefix);
|
||||
}
|
||||
&disconnect_userdb($str, $dbh);
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
return "Unknown user database type $proto";
|
||||
@@ -2284,8 +2280,8 @@ if (!$miniserv) {
|
||||
$miniserv = { };
|
||||
&get_miniserv_config($miniserv);
|
||||
}
|
||||
foreach $a (split(/\s+/, $miniserv->{'anonymous'})) {
|
||||
if ($a =~ /^([^=]+)=(\S+)$/ && $2 eq $user) {
|
||||
foreach my $tok (split(/\s+/, $miniserv->{'anonymous'})) {
|
||||
if ($tok =~ /^([^=]+)=(\S+)$/ && $2 eq $user) {
|
||||
push(@rv, $1);
|
||||
}
|
||||
}
|
||||
@@ -2299,7 +2295,7 @@ sub get_safe_acl
|
||||
my ($m) = @_;
|
||||
my $mdir = &module_root_directory($m);
|
||||
my %rv;
|
||||
&read_file_cached("$mdir/safeacl", \%rv) || return undef;
|
||||
&read_file_cached("$mdir/safeacl", \%rv) || return;
|
||||
return \%rv;
|
||||
}
|
||||
|
||||
@@ -2313,17 +2309,19 @@ sub generate_random_session_id
|
||||
my $sid;
|
||||
|
||||
# Try /dev/urandom, but with a timeout
|
||||
$SIG{ALRM} = sub { close(RANDOM) };
|
||||
my $randomfh;
|
||||
$SIG{ALRM} = sub { close($randomfh) if ($randomfh) };
|
||||
alarm(5);
|
||||
if (open(RANDOM, "/dev/urandom")) {
|
||||
if (open($randomfh, "<", "/dev/urandom")) {
|
||||
my $tmpsid;
|
||||
if (read(RANDOM, $tmpsid, 16) == 16) {
|
||||
if (read($randomfh, $tmpsid, 16) == 16) {
|
||||
$sid = lc(unpack('h*',$tmpsid));
|
||||
if ($sid !~ /^[0-9a-fA-F]{32}$/) {
|
||||
$sid = 'bad';
|
||||
}
|
||||
}
|
||||
close(RANDOM);
|
||||
close($randomfh);
|
||||
undef($randomfh);
|
||||
}
|
||||
alarm(0);
|
||||
|
||||
@@ -2341,7 +2339,7 @@ return $sid eq 'bad' ? undef : $sid;
|
||||
# Generate an ID string that can be used for a password reset link
|
||||
sub generate_random_id
|
||||
{
|
||||
if (open(my $RANDOM, "</dev/urandom")) {
|
||||
if (open(my $RANDOM, "<", "/dev/urandom")) {
|
||||
my $sid;
|
||||
my $tmpsid;
|
||||
if (read($RANDOM, $tmpsid, 16) == 16) {
|
||||
@@ -2350,7 +2348,9 @@ if (open(my $RANDOM, "</dev/urandom")) {
|
||||
close($RANDOM);
|
||||
return $sid;
|
||||
}
|
||||
return undef;
|
||||
# Explicit undef: callers consume this in hash-literal value position,
|
||||
# where bare 'return' would yield () and shift the surrounding pairing.
|
||||
return undef; ## no critic (ProhibitExplicitReturnUndef)
|
||||
}
|
||||
|
||||
# obsfucate_email(email)
|
||||
|
||||
@@ -3,7 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require 'acl-lib.pl';
|
||||
require 'acl-lib.pl'; ## no critic
|
||||
our ($config_directory, %gconfig);
|
||||
|
||||
# backup_config_files()
|
||||
@@ -43,7 +43,7 @@ return @rv;
|
||||
# Called before the files are actually read
|
||||
sub pre_backup
|
||||
{
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
# post_backup(&files)
|
||||
@@ -52,7 +52,7 @@ sub post_backup
|
||||
{
|
||||
unlink("$config_directory/config.aclbackup");
|
||||
unlink("$config_directory/miniserv.conf.aclbackup");
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
# pre_restore(&files)
|
||||
@@ -66,7 +66,7 @@ foreach my $u (&list_users(), &list_groups()) {
|
||||
glob("$config_directory/*/$u->{'name'}.acl"));
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
# post_restore(&files)
|
||||
@@ -101,7 +101,7 @@ foreach my $k (keys %aclbackup) {
|
||||
&put_miniserv_config(\%miniserv);
|
||||
|
||||
&restart_miniserv();
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -5,11 +5,11 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
&ui_print_header(undef, $text{'cert_title'}, "", undef, undef, undef, undef,
|
||||
undef, undef, "language=VBSCRIPT onload='postLoad()'");
|
||||
eval "use Net::SSLeay";
|
||||
eval { require Net::SSLeay; Net::SSLeay->import; 1 };
|
||||
|
||||
print "<p>$text{'cert_msg'}<p>\n";
|
||||
if ($ENV{'SSL_USER'}) {
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $module_config_directory, $base_remote_user);
|
||||
&ReadParse();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
|
||||
&ReadParse();
|
||||
|
||||
@@ -27,5 +27,5 @@ elsif ($cgi eq 'edit_acl.cgi') {
|
||||
}
|
||||
return 'none';
|
||||
}
|
||||
return undef;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $config_directory);
|
||||
&ReadParse();
|
||||
&error_setup($text{'convert_err'});
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'sync'} && $access{'create'} || &error($text{'convert_ecannot'});
|
||||
&ui_print_header(undef, $text{'convert_title'}, "");
|
||||
|
||||
@@ -19,7 +19,6 @@ sessions=1
|
||||
cats=1
|
||||
ips=1
|
||||
switch=1
|
||||
rbacenable=1
|
||||
logouttime=1
|
||||
times=1
|
||||
minsize=1
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user);
|
||||
&ReadParse();
|
||||
&error_setup($text{'gdelete_err'});
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user);
|
||||
&ReadParse();
|
||||
&error_setup($text{'gdeletes_err'});
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, %sessiondb);
|
||||
&ReadParse();
|
||||
$access{'sessions'} || &error($text{'sessions_ecannot'});
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user);
|
||||
&ReadParse();
|
||||
&error_setup($text{'delete_err'});
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user);
|
||||
&ReadParse();
|
||||
&error_setup($in{'joingroup'} ? $text{'udeletes_jerr'} : $text{'udeletes_err'});
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user, %gconfig);
|
||||
&ReadParse();
|
||||
$access{'acl'} || &error($text{'acl_emod'});
|
||||
@@ -48,15 +48,6 @@ else {
|
||||
}
|
||||
print &ui_table_start(&text('acl_options', $minfo{'desc'}), "width=100%", 4);
|
||||
|
||||
if ($in{'mod'} && $in{'user'} && &supports_rbac($in{'mod'}) &&
|
||||
!$gconfig{'rbacdeny_'.$who}) {
|
||||
# Show RBAC option
|
||||
print &ui_table_row($text{'acl_rbac'},
|
||||
&ui_radio("rbac", $maccess{'rbac'} ? 1 : 0,
|
||||
[ [ 1, $text{'acl_rbacyes'} ],
|
||||
[ 0, $text{'no'} ] ]), 3);
|
||||
}
|
||||
|
||||
# Load custom ACL library
|
||||
my $mdir = &module_root_directory($in{'mod'});
|
||||
if (-r "$mdir/acl_security.pl") {
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $config_directory);
|
||||
&ReadParse();
|
||||
$access{'groups'} || &error($text{'gedit_ecannot'});
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'pass_ecannot'});
|
||||
&ui_print_header(undef, $text{'pass_title'}, "");
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Show RBAC status
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
our (%in, %text, %gconfig, %access, $module_name, $module_root_directory);
|
||||
$access{'rbacenable'} || &error($text{'rbac_ecannot'});
|
||||
&ui_print_header(undef, $text{'rbac_title'}, "");
|
||||
|
||||
print "$text{'rbac_desc'}<p>\n";
|
||||
if ($gconfig{'os_type'} ne 'solaris') {
|
||||
print &text('rbac_esolaris', $gconfig{'real_os_type'}),"<p>\n";
|
||||
}
|
||||
elsif (!&supports_rbac()) {
|
||||
if (&foreign_available("cpan")) {
|
||||
print &text('rbac_eperl', "<tt>Authen::SolarisRBAC</tt>",
|
||||
"../cpan/download.cgi?source=0&local=$module_root_directory/Authen-SolarisRBAC-0.1.tar.gz&mode=2&return=/$module_name/&returndesc=".&urlize($text{'index_return'})),"<p>\n";
|
||||
}
|
||||
else {
|
||||
print &text('rbac_ecpan', "<tt>Authen::SolarisRBAC</tt>"),
|
||||
"<p>\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
print "$text{'rbac_ok'}<p>\n";
|
||||
}
|
||||
|
||||
&ui_print_footer("", $text{'index_return'});
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'sql'} || &error($text{'sql_ecannot'});
|
||||
&ui_print_header(undef, $text{'sql_title'}, "");
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'sync'} && $access{'create'} && $access{'delete'} ||
|
||||
&error($text{'sync_ecannot'});
|
||||
|
||||
@@ -7,7 +7,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'unix'} && $access{'create'} && $access{'delete'} ||
|
||||
&error($text{'unix_ecannot'});
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %gconfig, %access, $config_directory, $base_remote_user, $remote_user);
|
||||
&foreign_require("webmin", "webmin-lib.pl");
|
||||
|
||||
@@ -42,6 +42,11 @@ else {
|
||||
: $text{'edit_title2'}, "");
|
||||
}
|
||||
my $me = &get_user($base_remote_user);
|
||||
my %uaccess = &get_module_acl($in{'user'} || "", "", 1);
|
||||
if (!$in{'user'} && $uaccess{'rpc'} == 2) {
|
||||
# Don't offer the confusing 'root' or 'admin' RPC option by default
|
||||
$uaccess{'rpc'} = 0;
|
||||
}
|
||||
|
||||
# Give up if readonly
|
||||
if ($user{'readonly'} && !$in{'readwrite'}) {
|
||||
@@ -210,7 +215,10 @@ if ($access{'lang'}) {
|
||||
|
||||
if ($access{'locale'}) {
|
||||
# Current locale
|
||||
eval "use DateTime; use DateTime::Locale; use DateTime::TimeZone;";
|
||||
eval { require DateTime; DateTime->import;
|
||||
require DateTime::Locale; DateTime::Locale->import;
|
||||
require DateTime::TimeZone; DateTime::TimeZone->import;
|
||||
1 };
|
||||
if (!$@ && $] > 5.011) {
|
||||
my $locales = &list_locales();
|
||||
my %localesrev = reverse %{$locales};
|
||||
@@ -280,7 +288,7 @@ if ($showui) {
|
||||
# Start of security options section
|
||||
my $showsecurity = $access{'logouttime'} || $access{'ips'} ||
|
||||
$access{'minsize'} ||
|
||||
&supports_rbac() && $access{'mode'} == 0 || $access{'times'};
|
||||
$access{'times'};
|
||||
if ($showsecurity) {
|
||||
print &ui_hidden_table_start($text{'edit_security'}, "width=100%", 2,
|
||||
"security", 0, [ "width=30%" ]);
|
||||
@@ -321,14 +329,6 @@ if ($access{'ips'}) {
|
||||
4, 30));
|
||||
}
|
||||
|
||||
if (&supports_rbac() && $access{'mode'} == 0) {
|
||||
# Deny access to modules not managed by RBAC?
|
||||
print &ui_table_row($text{'edit_rbacdeny'},
|
||||
&ui_radio("rbacdeny", $user{'rbacdeny'} ? 1 : 0,
|
||||
[ [ 0, $text{'edit_rbacdeny0'} ],
|
||||
[ 1, $text{'edit_rbacdeny1'} ] ]));
|
||||
}
|
||||
|
||||
if ($access{'times'}) {
|
||||
# Show allowed days of the week
|
||||
my %days = map { $_, 1 } split(/,/, $user{'days'} || '');
|
||||
@@ -371,6 +371,16 @@ elsif ($miniserv{'twofactor_provider'}) {
|
||||
&ui_submit($text{'edit_twofactoradd'}, "twofactor"));
|
||||
}
|
||||
|
||||
# Can accept RPC calls?
|
||||
if ($access{'acl'} && !$safe) {
|
||||
print &ui_table_row(&hlink($text{'acl_rpc'}, 'rpc'),
|
||||
&ui_radio("rpc", int($uaccess{'rpc'}),
|
||||
[ [ 1, $text{'acl_rpc1'} ],
|
||||
$uaccess{'rpc'} == 2 ? ( [ 2, $text{'acl_rpc2'} ] ) : ( ),
|
||||
[ 3, $text{'acl_rpc3'} ],
|
||||
[ 0, $text{'acl_rpc0'} ] ]));
|
||||
}
|
||||
|
||||
print &ui_hidden_table_end("security");
|
||||
|
||||
# Work out which modules can be selected
|
||||
@@ -450,11 +460,9 @@ print &ui_hidden_table_end("mods");
|
||||
|
||||
# Add global ACL section, but only if not set from the group
|
||||
my $groupglobal = $memg && -r "$config_directory/$memg->{'name'}.acl";
|
||||
if ($access{'acl'} && !$groupglobal && $in{'user'} && !$safe) {
|
||||
if ($access{'acl'} && !$groupglobal && !$safe) {
|
||||
print &ui_hidden_table_start($text{'edit_global'}, "width=100%", 2,
|
||||
"global", 0, [ "width=30%" ]);
|
||||
my %uaccess;
|
||||
%uaccess = &get_module_acl($in{'user'}, "", 1);
|
||||
print &ui_hidden("acl_security_form", 1);
|
||||
&foreign_require("", "acl_security.pl");
|
||||
&foreign_call("", "acl_security_form", \%uaccess);
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text);
|
||||
&foreign_require("webmin");
|
||||
&error_setup($text{'forgot_err'});
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %gconfig);
|
||||
&foreign_require("webmin");
|
||||
&error_setup($text{'forgot_err'});
|
||||
|
||||
14
acl/help/rpc.html
Normal file
14
acl/help/rpc.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<header>Can accept RPC calls?</header>
|
||||
|
||||
This option determines if the user can make use of Webmin's poweful RPC calls
|
||||
feature, which is designed to allow this system to be controlled by a script
|
||||
or other Webmin server via HTTP. Because the RPC feature does <b>not</b>
|
||||
respect any module grants or fine-grained access controls, this option should
|
||||
only be enabled for fully trusted <tt>root</tt>-equivalent users. <p>
|
||||
|
||||
In addition, if the <b>RPC calls only</b> option is selected, the user will not
|
||||
be able to use the Webmin UI. This is useful for creating a separate login with
|
||||
a longer password for RPC purposes only, as two-factor authentication cannot be
|
||||
used when making RPC calls. <p>
|
||||
|
||||
<footer>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 579 B |
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %gconfig, %access, $base_remote_user);
|
||||
&ReadParse();
|
||||
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
|
||||
@@ -206,11 +206,6 @@ if (uc($ENV{'HTTPS'}) eq "ON" && $miniserv{'ca'}) {
|
||||
push(@icons, "images/twofactor.gif");
|
||||
push(@links, "twofactor_form.cgi");
|
||||
push(@titles, $text{'index_twofactor'});
|
||||
if ($access{'rbacenable'} && $gconfig{'os_type'} eq 'solaris') {
|
||||
push(@icons, "images/rbac.gif");
|
||||
push(@links, "edit_rbac.cgi");
|
||||
push(@titles, $text{'index_rbac'});
|
||||
}
|
||||
if ($access{'pass'}) {
|
||||
push(@icons, "images/pass.gif");
|
||||
push(@links, "edit_pass.cgi");
|
||||
|
||||
13
acl/lang/en
13
acl/lang/en
@@ -23,7 +23,6 @@ index_modgroups=Modules from group $1
|
||||
index_sync=Configure Unix User Synchronization
|
||||
index_unix=Configure Unix User Authentication
|
||||
index_sessions=View Login Sessions
|
||||
index_rbac=Setup RBAC
|
||||
index_delete=Delete Selected
|
||||
index_joingroup=Add To Group:
|
||||
index_eulist=Failed to list users : $1
|
||||
@@ -95,9 +94,6 @@ edit_switch=Switch to User
|
||||
edit_forgot=Send Password Reset Link
|
||||
edit_return=Webmin user
|
||||
edit_return2=Webmin group
|
||||
edit_rbacdeny=RBAC access mode
|
||||
edit_rbacdeny0=RBAC only controls selected module ACLs
|
||||
edit_rbacdeny1=RBAC controls all modules and ACLs
|
||||
edit_global=Permissions for all modules
|
||||
edit_templock=Temporarily locked
|
||||
edit_temppass=Force change at next login
|
||||
@@ -185,8 +181,6 @@ acl_title3=For group $1 in $2
|
||||
acl_options=$1 access control options
|
||||
acl_config=Can edit module configuration?
|
||||
acl_reset=Reset To Full Access
|
||||
acl_rbac=Get access control settings from RBAC?
|
||||
acl_rbacyes=Yes (overrides settings below)
|
||||
|
||||
acl_uall=All users
|
||||
acl_uthis=This user
|
||||
@@ -382,13 +376,6 @@ hide_clone=(Clone $1)
|
||||
switch_euser=You are not allowed to switch to this user
|
||||
switch_eold=Existing session not found!
|
||||
|
||||
rbac_title=Setup RBAC
|
||||
rbac_desc=Webmin's RBAC integration provides a way for user module and ACL permissions to be determined from an RBAC (Role Based Access Control) database, rather than Webmin's own configuration files. Once RBAC support is enabled, any user for whom the <b>RBAC controls all modules and ACLs</b> option is selected will have his capabilities determined by RBAC rather than Webmin's own access control settings.
|
||||
rbac_esolaris=RBAC is only supported on Solaris at the moment, and so cannot be used on this $1 system.
|
||||
rbac_eperl=The Perl module $1 needed for RBAC integration is not installed. <a href='$2'>Click here</a> to have it installed now.
|
||||
rbac_ecpan=You do not have access to Webmin's Perl Modules page in order to install the necessary $1 module for RBAC integration.
|
||||
rbac_ok=RBAC integration is available on this system, and can be enabled on a per-user basis on the Edit Webmin User page.
|
||||
|
||||
udeletes_err=Failed to delete users
|
||||
udeletes_jerr=Failed to add users to group
|
||||
udeletes_enone=None selected
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, %sessiondb);
|
||||
$access{'sessions'} || &error($text{'sessions_ecannot'});
|
||||
&ui_print_header(undef, $text{'sessions_title'}, "");
|
||||
|
||||
@@ -16,8 +16,9 @@ my ($user, $script, $action, $type, $object, $p) = @_;
|
||||
my $g = $type eq 'group' ? "_g" : "";
|
||||
if ($action eq 'modify') {
|
||||
if ($p->{'old'} ne $p->{'name'}) {
|
||||
return &text('log_rename'.$g, "<tt>$p->{'old'}</tt>",
|
||||
"<tt>$p->{'name'}</tt>");
|
||||
return &text('log_rename'.$g,
|
||||
"<tt>".&html_escape($p->{'old'})."</tt>",
|
||||
"<tt>".&html_escape($p->{'name'})."</tt>");
|
||||
}
|
||||
else {
|
||||
return &text('log_modify'.$g,
|
||||
@@ -26,7 +27,8 @@ if ($action eq 'modify') {
|
||||
}
|
||||
elsif ($action eq 'create') {
|
||||
if ($p->{'clone'}) {
|
||||
return &text('log_clone'.$g, "<tt>$p->{'clone'}</tt>",
|
||||
return &text('log_clone'.$g,
|
||||
"<tt>".&html_escape($p->{'clone'})."</tt>",
|
||||
"<tt>".&html_escape($object)."</tt>");
|
||||
}
|
||||
else {
|
||||
@@ -36,21 +38,23 @@ elsif ($action eq 'create') {
|
||||
}
|
||||
elsif ($action eq 'delete') {
|
||||
if ($type eq "users" || $type eq "groups") {
|
||||
return &text('log_delete_'.$type, $object);
|
||||
return &text('log_delete_'.$type, &html_escape($object));
|
||||
}
|
||||
else {
|
||||
return &text('log_delete'.$g, "<tt>$object</tt>");
|
||||
return &text('log_delete'.$g,
|
||||
"<tt>".&html_escape($object)."</tt>");
|
||||
}
|
||||
}
|
||||
elsif ($action eq 'joingroup') {
|
||||
return &text('log_joingroup', $object, $p->{'group'});
|
||||
return &text('log_joingroup', &html_escape($object),
|
||||
&html_escape($p->{'group'}));
|
||||
}
|
||||
elsif ($action eq 'acl') {
|
||||
return &text('log_acl', "<tt>$object</tt>",
|
||||
return &text('log_acl', "<tt>".&html_escape($object)."</tt>",
|
||||
"<i>".&html_escape($p->{'moddesc'})."</i>");
|
||||
}
|
||||
elsif ($action eq 'reset') {
|
||||
return &text('log_reset', "<tt>$object</tt>",
|
||||
return &text('log_reset', "<tt>".&html_escape($object)."</tt>",
|
||||
"<i>".&html_escape($p->{'moddesc'})."</i>");
|
||||
}
|
||||
elsif ($action eq 'cert') {
|
||||
@@ -60,7 +64,9 @@ elsif ($action eq 'switch') {
|
||||
return &text('log_switch', "<tt>".&html_escape($object)."</tt>");
|
||||
}
|
||||
elsif ($action eq 'twofactor') {
|
||||
return &text('log_twofactor', $object, $p->{'provider'}, $p->{'id'});
|
||||
return &text('log_twofactor', &html_escape($object),
|
||||
&html_escape($p->{'provider'}),
|
||||
&html_escape($p->{'id'}));
|
||||
}
|
||||
elsif ($action eq 'forgot') {
|
||||
return &text('log_forgot_'.$type, &html_escape($p->{'user'}),
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
&ReadParse();
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
&ReadParse();
|
||||
|
||||
@@ -3,7 +3,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require 'acl-lib.pl';
|
||||
require 'acl-lib.pl'; ## no critic
|
||||
our ($config_directory);
|
||||
|
||||
# Rename the .acl files for any groups to .gacl files
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user, %gconfig,
|
||||
$config_directory);
|
||||
&ReadParse();
|
||||
@@ -54,13 +54,8 @@ else {
|
||||
if (defined($in{'noconfig'})) {
|
||||
$maccess{'noconfig'} = $in{'noconfig'};
|
||||
}
|
||||
if ($in{'rbac'}) {
|
||||
# RBAC overrides everything
|
||||
$maccess{'rbac'} = 1;
|
||||
}
|
||||
elsif (-r "../$in{'_acl_mod'}/acl_security.pl") {
|
||||
if (-r "../$in{'_acl_mod'}/acl_security.pl") {
|
||||
# Use user inputs
|
||||
$maccess{'rbac'} = 0 if (defined($in{'rbac'}));
|
||||
&foreign_require($in{'_acl_mod'}, "acl_security.pl");
|
||||
&foreign_call($in{'_acl_mod'}, "acl_security_save",
|
||||
\%maccess, \%in);
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $config_directory);
|
||||
&ReadParse();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'pass_ecannot'});
|
||||
&error_setup($text{'pass_err'});
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
&ReadParse();
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $module_config_directory);
|
||||
&ReadParse();
|
||||
$access{'sync'} && $access{'create'} && $access{'delete'} ||
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user);
|
||||
&foreign_require("webmin");
|
||||
&error_setup($text{'twofactor_err'});
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
&ReadParse();
|
||||
&error_setup($text{'unix_err'});
|
||||
@@ -70,7 +70,7 @@ else {
|
||||
}
|
||||
if ($in{'sudo'}) {
|
||||
&has_command("sudo") || &error(&text('unix_esudo', "<tt>sudo</tt>"));
|
||||
eval "use IO::Pty";
|
||||
eval { require IO::Pty; IO::Pty->import; 1 };
|
||||
$@ && &error(&text('unix_esudomod', "<tt>IO::Pty</tt>"));
|
||||
}
|
||||
$miniserv{'sudo'} = $in{'sudo'};
|
||||
|
||||
@@ -6,7 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $config_directory, $base_remote_user);
|
||||
&foreign_require("webmin", "webmin-lib.pl");
|
||||
&ReadParse();
|
||||
@@ -105,11 +105,6 @@ foreach my $u (@ulist) {
|
||||
# Find the current group
|
||||
my $oldgroup = $in{'old'} ? &get_users_group($in{'old'}) : undef;
|
||||
|
||||
if (&supports_rbac()) {
|
||||
# Save RBAC mode
|
||||
$user{'rbacdeny'} = $in{'rbacdeny'};
|
||||
}
|
||||
|
||||
my $newgroup;
|
||||
if (defined($in{'group'})) {
|
||||
# Check if group is allowed
|
||||
@@ -374,11 +369,13 @@ else {
|
||||
}
|
||||
|
||||
my $aclfile = "$config_directory/$in{'name'}.acl";
|
||||
if ($in{'old'} && $in{'acl_security_form'} && !$newgroup && !$in{'safe'}) {
|
||||
# Update user's global ACL
|
||||
if ($in{'acl_security_form'} && !$newgroup && !$in{'safe'}) {
|
||||
# Update user's global ACL, and merge in RPC setting which has
|
||||
# been moved out of this form
|
||||
&foreign_require("", "acl_security.pl");
|
||||
my %uaccess;
|
||||
&foreign_call("", "acl_security_save", \%uaccess, \%in);
|
||||
$uaccess{'rpc'} = $in{'rpc'};
|
||||
&lock_file($aclfile);
|
||||
&save_module_acl(\%uaccess, $in{'name'}, "", 1);
|
||||
&set_ownership_permissions(undef, undef, 0640, $aclfile);
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, %sessiondb);
|
||||
&ReadParse();
|
||||
&can_edit_user($in{'user'}) && $access{'switch'} ||
|
||||
|
||||
65
acl/t/perlcritic.t
Normal file
65
acl/t/perlcritic.t
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
|
||||
BEGIN {
|
||||
eval { require Perl::Critic; 1 }
|
||||
or plan skip_all => 'Perl::Critic not installed';
|
||||
}
|
||||
|
||||
use File::Find;
|
||||
|
||||
sub script_dir
|
||||
{
|
||||
my $path = $0;
|
||||
if ($path =~ m{^/}) {
|
||||
$path =~ s{/[^/]+$}{};
|
||||
return $path;
|
||||
}
|
||||
my $cwd = `pwd`;
|
||||
chomp($cwd);
|
||||
if ($path =~ m{/}) {
|
||||
$path =~ s{/[^/]+$}{};
|
||||
return $cwd.'/'.$path;
|
||||
}
|
||||
return $cwd;
|
||||
}
|
||||
|
||||
my $bindir = script_dir();
|
||||
my $module_dir = "$bindir/..";
|
||||
chdir($module_dir) or die "chdir: $!";
|
||||
|
||||
my @files;
|
||||
find(
|
||||
sub {
|
||||
return if -d;
|
||||
# Skip symlinks: shared libs (e.g. md5-lib.pl -> ../useradmin/md5-lib.pl)
|
||||
# belong to the module that owns the underlying file.
|
||||
return if -l;
|
||||
return unless /\.(pl|cgi)\z/;
|
||||
# *.info.pl is the Polish-locale translation of *.info, not Perl code.
|
||||
return if /\.info\.pl\z/;
|
||||
push(@files, $File::Find::name);
|
||||
},
|
||||
'.'
|
||||
);
|
||||
|
||||
@files = sort @files;
|
||||
if (!@files) {
|
||||
plan skip_all => 'no perl files to check';
|
||||
}
|
||||
|
||||
my $critic = Perl::Critic->new(
|
||||
-profile => "$bindir/../../.perlcriticrc",
|
||||
);
|
||||
|
||||
foreach my $file (@files) {
|
||||
my @violations = $critic->critique($file);
|
||||
is(scalar @violations, 0, "$file perlcritic");
|
||||
if (@violations) {
|
||||
diag join("", @violations);
|
||||
}
|
||||
}
|
||||
|
||||
done_testing();
|
||||
1381
acl/t/run-tests.t
Normal file
1381
acl/t/run-tests.t
Normal file
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %access, $base_remote_user);
|
||||
&foreign_require("webmin");
|
||||
&error_setup($text{'twofactor_terr'});
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#!/usr/local/bin/perl
|
||||
# Validate the OTP for some user
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
no warnings 'once';
|
||||
our $module_name;
|
||||
$main::no_acl_check = 1;
|
||||
$main::no_referers_check = 1;
|
||||
$ENV{'WEBMIN_CONFIG'} = "/etc/webmin";
|
||||
@@ -8,17 +12,19 @@ $ENV{'WEBMIN_VAR'} = "/var/webmin";
|
||||
if ($0 =~ /^(.*\/)[^\/]+$/) {
|
||||
chdir($1);
|
||||
}
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
$module_name eq 'acl' || die "Command must be run with full path";
|
||||
|
||||
# Check command-line args
|
||||
@ARGV == 5 || die "Usage: $0 user provider id token api-key";
|
||||
($user, $provider, $id, $token, $apikey) = @ARGV;
|
||||
my ($user, $provider, $id, $token, $apikey) = @ARGV;
|
||||
|
||||
# Call the provider validation function
|
||||
&foreign_require("webmin");
|
||||
$func = "webmin::validate_twofactor_".$provider;
|
||||
$err = &$func($id, $token, $apikey);
|
||||
my $method = "validate_twofactor_".$provider;
|
||||
my $code = webmin->can($method)
|
||||
or die "Unknown twofactor provider: $provider\n";
|
||||
my $err = $code->($id, $token, $apikey);
|
||||
if ($err) {
|
||||
$err =~ s/\r|\n/ /g;
|
||||
print $err,"\n";
|
||||
|
||||
@@ -5,7 +5,7 @@ use strict;
|
||||
use warnings;
|
||||
no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user);
|
||||
&foreign_require("webmin");
|
||||
&error_setup($text{'twofactor_err'});
|
||||
|
||||
@@ -16,7 +16,7 @@ print &ui_table_row($text{'acl_root'},
|
||||
# Other dirs to allow
|
||||
print &ui_table_row($text{'acl_otherdirs'},
|
||||
&ui_textarea("otherdirs", join("\n", split(/\t+/, $o->{'otherdirs'})),
|
||||
5, 40), 3);
|
||||
3, 40), 3);
|
||||
|
||||
# Can see dot files?
|
||||
print &ui_table_row($text{'acl_nodot'},
|
||||
@@ -77,18 +77,6 @@ print &ui_table_row($text{'acl_gedit'},
|
||||
|
||||
print &ui_table_hr();
|
||||
|
||||
# Can submit feedback?
|
||||
print &ui_table_row($text{'acl_feedback'},
|
||||
&ui_radio("feedback", int($o->{'feedback'}),
|
||||
[ map { [ $_, $text{'acl_feedback'.$_} ] } (2,3,1,0) ]));
|
||||
|
||||
# Can accept RPC calls?
|
||||
print &ui_table_row($text{'acl_rpc'},
|
||||
&ui_radio("rpc", int($o->{'rpc'}),
|
||||
[ [ 1, $text{'acl_rpc1'} ],
|
||||
$o->{'rpc'} == 2 ? ( [ 2, $text{'acl_rpc2'} ] ) : ( ),
|
||||
[ 0, $text{'acl_rpc0'} ] ]));
|
||||
|
||||
# Get new permissions?
|
||||
print &ui_table_row($text{'acl_negative'},
|
||||
&ui_radio("negative", int($o->{'negative'}),
|
||||
@@ -110,27 +98,26 @@ print &ui_table_row($text{'acl_webminsearch'},
|
||||
# Parse the form for global security options
|
||||
sub acl_security_save
|
||||
{
|
||||
$_[0]->{'root'} = $in{'root_def'} ? undef : $in{'root'};
|
||||
$_[0]->{'otherdirs'} = join("\t", split(/\r?\n/, $in{'otherdirs'}));
|
||||
$_[0]->{'nodot'} = $in{'nodot'};
|
||||
my ($o) = @_;
|
||||
$o->{'root'} = $in{'root_def'} ? undef : $in{'root'};
|
||||
$o->{'otherdirs'} = join("\t", split(/\r?\n/, $in{'otherdirs'}));
|
||||
$o->{'nodot'} = $in{'nodot'};
|
||||
|
||||
$_[0]->{'uedit_mode'} = $in{'uedit_mode'};
|
||||
$_[0]->{'uedit'} = $in{'uedit_mode'} == 2 ? $in{'uedit_can'} :
|
||||
$o->{'uedit_mode'} = $in{'uedit_mode'};
|
||||
$o->{'uedit'} = $in{'uedit_mode'} == 2 ? $in{'uedit_can'} :
|
||||
$in{'uedit_mode'} == 3 ? $in{'uedit_cannot'} :
|
||||
$in{'uedit_mode'} == 4 ? $in{'uedit_uid'} :
|
||||
$in{'uedit_mode'} == 5 ? getgrnam($in{'uedit_group'}) : "";
|
||||
$_[0]->{'uedit2'} = $in{'uedit_mode'} == 4 ? $in{'uedit_uid2'} : undef;
|
||||
$o->{'uedit2'} = $in{'uedit_mode'} == 4 ? $in{'uedit_uid2'} : undef;
|
||||
|
||||
$_[0]->{'gedit_mode'} = $in{'gedit_mode'};
|
||||
$_[0]->{'gedit'} = $in{'gedit_mode'} == 2 ? $in{'gedit_can'} :
|
||||
$o->{'gedit_mode'} = $in{'gedit_mode'};
|
||||
$o->{'gedit'} = $in{'gedit_mode'} == 2 ? $in{'gedit_can'} :
|
||||
$in{'gedit_mode'} == 3 ? $in{'gedit_cannot'} :
|
||||
$in{'gedit_mode'} == 4 ? $in{'gedit_gid'} : "";
|
||||
$_[0]->{'gedit2'} = $in{'gedit_mode'} == 4 ? $in{'gedit_gid2'} : undef;
|
||||
$_[0]->{'feedback'} = $in{'feedback'};
|
||||
$_[0]->{'rpc'} = $in{'rpc'};
|
||||
$_[0]->{'negative'} = $in{'negative'};
|
||||
$_[0]->{'readonly'} = $in{'readonly'};
|
||||
$_[0]->{'fileunix'} = $in{'fileunix_def'} ? undef : $in{'fileunix'};
|
||||
$_[0]->{'webminsearch'} = $in{'webminsearch'};
|
||||
$o->{'gedit2'} = $in{'gedit_mode'} == 4 ? $in{'gedit_gid2'} : undef;
|
||||
$o->{'negative'} = $in{'negative'};
|
||||
$o->{'readonly'} = $in{'readonly'};
|
||||
$o->{'fileunix'} = $in{'fileunix_def'} ? undef : $in{'fileunix'};
|
||||
$o->{'webminsearch'} = $in{'webminsearch'};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,115 +5,84 @@ require 'apache-lib.pl';
|
||||
# Output HTML for editing security options for the apache module
|
||||
sub acl_security_form
|
||||
{
|
||||
print "<tr> <td valign=top rowspan=4><b>$text{'acl_virts'}</b></td>\n";
|
||||
print "<td rowspan=4 valign=top>\n";
|
||||
printf "<input type=radio name=virts_def value=1 %s> %s\n",
|
||||
$_[0]->{'virts'} eq '*' ? 'checked' : '', $text{'acl_vall'};
|
||||
printf "<input type=radio name=virts_def value=0 %s> %s<br>\n",
|
||||
$_[0]->{'virts'} eq '*' ? '' : 'checked', $text{'acl_vsel'};
|
||||
print "<select name=virts multiple size=5>\n";
|
||||
local $conf = &get_config();
|
||||
local @virts = ( { 'value' => '__default__' },
|
||||
&find_directive_struct("VirtualHost", $conf) );
|
||||
local %vcan = map { $_, 1 } split(/\s+/, $_[0]->{'virts'});
|
||||
local $v;
|
||||
foreach $v (@virts) {
|
||||
local @vn = &virt_acl_name($v);
|
||||
local ($can) = grep { $vcan{$_} } @vn;
|
||||
local $vn = $can || $vn[0];
|
||||
printf "<option value=\"%s\" %s>%s</option>\n",
|
||||
$vn, $can ? "selected" : "",
|
||||
$vn eq "__default__" ? $text{'acl_defserv'} : $vn;
|
||||
my ($o) = @_;
|
||||
|
||||
my $conf = &get_config();
|
||||
my @virts = ( { 'value' => '__default__' },
|
||||
&find_directive_struct("VirtualHost", $conf) );
|
||||
my @vsel = $o->{'virts'} eq '*' ? () : split(/\s+/, $o->{'virts'});
|
||||
my %vcan = map { $_, 1 } @vsel;
|
||||
my @vopts;
|
||||
foreach my $v (@virts) {
|
||||
my @vn = &virt_acl_name($v);
|
||||
my ($can) = grep { $vcan{$_} } @vn;
|
||||
my $show = $can || $vn[0];
|
||||
push(@vopts, [ $show,
|
||||
$show eq "__default__" ? $text{'acl_defserv'}
|
||||
: $show ]);
|
||||
delete($vcan{$can}) if ($can);
|
||||
}
|
||||
foreach $vn (keys %vcan) {
|
||||
next if ($vn eq "*");
|
||||
printf "<option value=\"%s\" %s>%s</option>\n",
|
||||
$vn, "selected",
|
||||
$vn eq "__default__" ? $text{'acl_defserv'} : $vn;
|
||||
print &ui_table_row($text{'acl_virts'},
|
||||
&ui_radio("virts_def", $o->{'virts'} eq '*' ? 1 : 0,
|
||||
[ [ 1, $text{'acl_vall'} ],
|
||||
[ 0, $text{'acl_vsel'} ] ])."<br>\n".
|
||||
&ui_select("virts", \@vsel, \@vopts, 5, 1, 1),
|
||||
3);
|
||||
|
||||
print &ui_table_row($text{'acl_global'},
|
||||
&ui_select("global",
|
||||
defined($o->{'global'}) && $o->{'global'} ne '' ?
|
||||
$o->{'global'} : 0,
|
||||
[ [ 1, $text{'yes'} ],
|
||||
[ 2, $text{'acl_htaccess'} ],
|
||||
[ 0, $text{'no'} ] ]));
|
||||
print &ui_table_row($text{'acl_create'},
|
||||
&ui_yesno_radio("create", $o->{'create'}));
|
||||
|
||||
print &ui_table_row($text{'acl_vuser'},
|
||||
&ui_yesno_radio("vuser", $o->{'vuser'}));
|
||||
print &ui_table_row($text{'acl_vaddr'},
|
||||
&ui_yesno_radio("vaddr", $o->{'vaddr'}));
|
||||
|
||||
print &ui_table_row($text{'acl_pipe'},
|
||||
&ui_yesno_radio("pipe", $o->{'pipe'}));
|
||||
print &ui_table_row($text{'acl_stop'},
|
||||
&ui_yesno_radio("stop", $o->{'stop'}));
|
||||
|
||||
print &ui_table_row($text{'acl_apply'},
|
||||
&ui_yesno_radio("apply", $o->{'apply'}));
|
||||
print &ui_table_row($text{'acl_names'},
|
||||
&ui_yesno_radio("names", $o->{'names'}));
|
||||
|
||||
print &ui_table_row($text{'acl_dir'},
|
||||
&ui_textbox("dir", $o->{'dir'}, 30)." ".
|
||||
&file_chooser_button("dir", 1),
|
||||
3);
|
||||
|
||||
print &ui_table_row($text{'acl_aliasdir'},
|
||||
&ui_textbox("aliasdir", $o->{'aliasdir'}, 30)." ".
|
||||
&file_chooser_button("aliasdir", 1),
|
||||
3);
|
||||
|
||||
my @typesel = $o->{'types'} eq '*' ? () : split(/\s+/, $o->{'types'});
|
||||
my @typeopts;
|
||||
for (my $i = 0; $text{"type_$i"}; $i++) {
|
||||
push(@typeopts, [ $i, $text{"type_$i"} ]);
|
||||
}
|
||||
print "</select></td>\n";
|
||||
print &ui_table_row($text{'acl_types'},
|
||||
&ui_radio("types_def", $o->{'types'} eq '*' ? 1 : 0,
|
||||
[ [ 1, $text{'acl_all'} ],
|
||||
[ 0, $text{'acl_sel'} ] ])."<br>\n".
|
||||
&ui_select("types", \@typesel, \@typeopts, 5, 1),
|
||||
3);
|
||||
|
||||
print "<td><b>$text{'acl_global'}</b></td> <td><select name=global>\n";
|
||||
printf "<option value=1 %s>$text{'yes'}</option>\n",
|
||||
$_[0]->{'global'} == 1 ? "selected" : "";
|
||||
printf "<option value=2 %s>$text{'acl_htaccess'}</option>\n",
|
||||
$_[0]->{'global'} == 2 ? "selected" : "";
|
||||
printf "<option value=0 %s>$text{'no'}</option></select></td> </tr>\n",
|
||||
$_[0]->{'global'} == 0 ? "selected" : "";
|
||||
|
||||
print "<tr> <td><b>$text{'acl_create'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=create value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'create'} ? "checked" : "";
|
||||
printf "<input type=radio name=create value=0 %s> $text{'no'}</td> </tr>\n",
|
||||
$_[0]->{'create'} ? "" : "checked";
|
||||
|
||||
print "<tr> <td><b>$text{'acl_vuser'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=vuser value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'vuser'} ? "checked" : "";
|
||||
printf "<input type=radio name=vuser value=0 %s> $text{'no'}</td> </tr>\n",
|
||||
$_[0]->{'vuser'} ? "" : "checked";
|
||||
|
||||
print "<tr> <td><b>$text{'acl_vaddr'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=vaddr value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'vaddr'} ? "checked" : "";
|
||||
printf "<input type=radio name=vaddr value=0 %s> $text{'no'}</td> </tr>\n",
|
||||
$_[0]->{'vaddr'} ? "" : "checked";
|
||||
|
||||
print "<tr> <td><b>$text{'acl_pipe'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=pipe value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'pipe'} ? "checked" : "";
|
||||
printf "<input type=radio name=pipe value=0 %s> $text{'no'}</td>\n",
|
||||
$_[0]->{'pipe'} ? "" : "checked";
|
||||
|
||||
print "<td><b>$text{'acl_stop'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=stop value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'stop'} ? "checked" : "";
|
||||
printf "<input type=radio name=stop value=0 %s> $text{'no'}</td> </tr>\n",
|
||||
$_[0]->{'stop'} ? "" : "checked";
|
||||
|
||||
print "<tr> <td><b>$text{'acl_apply'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=apply value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'apply'} ? "checked" : "";
|
||||
printf "<input type=radio name=apply value=0 %s> $text{'no'}</td>\n",
|
||||
$_[0]->{'apply'} ? "" : "checked";
|
||||
|
||||
print "<td><b>$text{'acl_names'}</b></td> <td>\n";
|
||||
printf "<input type=radio name=names value=1 %s> $text{'yes'}\n",
|
||||
$_[0]->{'names'} ? "checked" : "";
|
||||
printf "<input type=radio name=names value=0 %s> $text{'no'}</td> </tr>\n",
|
||||
$_[0]->{'names'} ? "" : "checked";
|
||||
|
||||
print "<tr> <td><b>$text{'acl_dir'}</b></td>\n";
|
||||
printf "<td colspan=3><input name=dir size=30 value='%s'> %s</td> </tr>\n",
|
||||
$_[0]->{'dir'}, &file_chooser_button("dir", 1);
|
||||
|
||||
print "<tr> <td><b>$text{'acl_aliasdir'}</b></td>\n";
|
||||
printf "<td colspan=3><input name=aliasdir size=30 value='%s'> %s</td> </tr>\n",
|
||||
$_[0]->{'aliasdir'}, &file_chooser_button("aliasdir", 1);
|
||||
|
||||
print "<tr> <td valign=top><b>$text{'acl_types'}</b></td>\n";
|
||||
print "<td colspan=3>\n";
|
||||
printf "<input type=radio name=types_def value=1 %s> $text{'acl_all'} \n",
|
||||
$_[0]->{'types'} eq '*' ? "checked" : "";
|
||||
printf "<input type=radio name=types_def value=0 %s> $text{'acl_sel'}<br>\n",
|
||||
$_[0]->{'types'} eq '*' ? "" : "checked";
|
||||
map { $types{$_}++ } split(/\s+/, $_[0]->{'types'});
|
||||
print "<select name=types size=5 multiple>\n";
|
||||
for($i=0; $text{"type_$i"}; $i++) {
|
||||
printf "<option value=\"%d\" %s>%s</option>\n",
|
||||
$i, $types{$i} ? "selected" : "", $text{"type_$i"};
|
||||
}
|
||||
print "</select></td> </tr>\n";
|
||||
|
||||
print "<tr> <td valign=top><b>$text{'acl_dirs'}</b></td>\n";
|
||||
print "<td colspan=3>\n";
|
||||
print &ui_radio("dirsmode", $_[0]->{'dirsmode'},
|
||||
[ [ 0, $text{'acl_dirs0'} ],
|
||||
[ 1, $text{'acl_dirs1'} ],
|
||||
[ 2, $text{'acl_dirs2'} ] ]),"<br>\n";
|
||||
print &ui_textarea("dirs", join("\n", split(/\s+/, $_[0]->{'dirs'})), 5, 50);
|
||||
print "</td> </tr>\n";
|
||||
print &ui_table_row($text{'acl_dirs'},
|
||||
&ui_radio("dirsmode", $o->{'dirsmode'},
|
||||
[ [ 0, $text{'acl_dirs0'} ],
|
||||
[ 1, $text{'acl_dirs1'} ],
|
||||
[ 2, $text{'acl_dirs2'} ] ])."<br>\n".
|
||||
&ui_textarea("dirs", join("\n", split(/\s+/, $o->{'dirs'})), 5, 50),
|
||||
3);
|
||||
}
|
||||
|
||||
# acl_security_save(&options)
|
||||
@@ -141,4 +110,3 @@ $_[0]->{'names'} = $in{'names'};
|
||||
$_[0]->{'dirsmode'} = $in{'dirsmode'};
|
||||
$_[0]->{'dirs'} = join(" ", split(/\s+/, $in{'dirs'}));
|
||||
}
|
||||
|
||||
|
||||
@@ -436,6 +436,13 @@ foreach $v (@virt) {
|
||||
return \@get_config_cache;
|
||||
}
|
||||
|
||||
# flush_config_cache()
|
||||
# Delete all in-memory config caches
|
||||
sub flush_config_cache
|
||||
{
|
||||
undef(@get_config_cache);
|
||||
}
|
||||
|
||||
# get_config_file(filename, [&seen-files])
|
||||
# Returns a list of config hash refs from some file
|
||||
sub get_config_file
|
||||
@@ -788,6 +795,428 @@ unlink($file);
|
||||
&delete_webfile_link($file);
|
||||
}
|
||||
|
||||
# can_manage_vhost_files()
|
||||
# Returns 1 if this system uses Debian-style available/enabled site dirs
|
||||
sub can_manage_vhost_files
|
||||
{
|
||||
return 0 if ($gconfig{'os_type'} ne 'debian-linux');
|
||||
my $avail = &vhost_available_dir();
|
||||
my $enabled = &vhost_enabled_dir();
|
||||
return $avail && -d $avail && $enabled && -d $enabled &&
|
||||
&simplify_path(&resolve_links($avail)) ne
|
||||
&simplify_path(&resolve_links($enabled));
|
||||
}
|
||||
|
||||
# vhost_available_dir()
|
||||
# Returns the configured directory of available Apache virtual host files
|
||||
sub vhost_available_dir
|
||||
{
|
||||
return $config{'virt_file'} ? &server_root($config{'virt_file'}) : undef;
|
||||
}
|
||||
|
||||
# vhost_enabled_dir()
|
||||
# Returns the configured directory of enabled Apache virtual host symlinks
|
||||
sub vhost_enabled_dir
|
||||
{
|
||||
return $config{'link_dir'} ? &server_root($config{'link_dir'}) : undef;
|
||||
}
|
||||
|
||||
# get_vhost_available_files()
|
||||
# Returns real config files from the directory used for new virtual hosts
|
||||
sub get_vhost_available_files
|
||||
{
|
||||
my @rv;
|
||||
return @rv if (!&can_manage_vhost_files());
|
||||
my $avail = &vhost_available_dir();
|
||||
opendir(AVAIL, $avail) || return @rv;
|
||||
foreach my $f (sort { lc($a) cmp lc($b) } readdir(AVAIL)) {
|
||||
next if ($f eq "." || $f eq "..");
|
||||
my $file = $avail."/".$f;
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
next if (!$rfile || !-f $rfile || !-r $rfile);
|
||||
push(@rv, $rfile);
|
||||
}
|
||||
closedir(AVAIL);
|
||||
return &unique(@rv);
|
||||
}
|
||||
|
||||
# find_virtuals_in_file(file)
|
||||
# Returns VirtualHost blocks parsed from one config file
|
||||
sub find_virtuals_in_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
return ( ) if (!-r $rfile);
|
||||
my @conf = &get_config_file($rfile);
|
||||
return grep { $_->{'file'} eq $rfile }
|
||||
&find_directive_struct("VirtualHost", \@conf);
|
||||
}
|
||||
|
||||
# is_default_vhost(&virt)
|
||||
# Returns 1 if a VirtualHost looks like a default/catch-all host
|
||||
sub is_default_vhost
|
||||
{
|
||||
my ($virt) = @_;
|
||||
return 1 if (!$virt);
|
||||
return 1 if ($virt->{'value'} =~ /_default_/i);
|
||||
return 1 if (!&find_directive("ServerName", $virt->{'members'}));
|
||||
return 0;
|
||||
}
|
||||
|
||||
# can_manage_vhost_file(file)
|
||||
# Returns 1 if all virtual hosts in a file are manageable by this user
|
||||
sub can_manage_vhost_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
return 0 if (!$rfile || !-f $rfile || !-r $rfile);
|
||||
my @virts = &find_virtuals_in_file($rfile);
|
||||
return 0 if (!@virts);
|
||||
foreach my $virt (@virts) {
|
||||
return 0 if (&is_default_vhost($virt));
|
||||
return 0 if (!&can_edit_virt($virt));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
# can_manage_vhost_state_file(file)
|
||||
# Returns 1 if a virtual host file can have its enabled state managed here
|
||||
sub can_manage_vhost_state_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
return 0 if (!$rfile || !-f $rfile);
|
||||
my %available = map { $_, 1 } &get_vhost_available_files();
|
||||
return 0 if (!$available{$rfile});
|
||||
return &can_manage_vhost_file($rfile);
|
||||
}
|
||||
|
||||
# get_virtual_list_rows(&config)
|
||||
# Returns row hashes for the virtual-host list, preserving sites-available order
|
||||
sub get_virtual_list_rows
|
||||
{
|
||||
my ($conf) = @_;
|
||||
my @active = grep { &can_edit_virt($_) }
|
||||
&find_directive_struct("VirtualHost", $conf);
|
||||
if (&can_manage_vhost_files()) {
|
||||
my @rows;
|
||||
my %active_by_file;
|
||||
foreach my $v (@active) {
|
||||
my $file = &simplify_path(&resolve_links($v->{'file'}));
|
||||
$file ||= $v->{'file'};
|
||||
push(@{$active_by_file{$file}}, $v);
|
||||
}
|
||||
my %done_virt;
|
||||
foreach my $file (&get_vhost_available_files()) {
|
||||
my @filevirts = @{$active_by_file{$file} || [ ]};
|
||||
my $active = @filevirts ? 1 : 0;
|
||||
if (!@filevirts) {
|
||||
@filevirts = grep { &can_edit_virt($_) &&
|
||||
!&is_default_vhost($_) }
|
||||
&find_virtuals_in_file($file);
|
||||
}
|
||||
foreach my $v (@filevirts) {
|
||||
push(@rows, { 'virt' => $v,
|
||||
'active' => $active,
|
||||
'file' => $file });
|
||||
$done_virt{$v}++;
|
||||
}
|
||||
}
|
||||
foreach my $v (@active) {
|
||||
next if ($done_virt{$v});
|
||||
push(@rows, { 'virt' => $v,
|
||||
'active' => 1,
|
||||
'file' => $v->{'file'} });
|
||||
}
|
||||
return @rows;
|
||||
}
|
||||
return map { { 'virt' => $_, 'active' => 1, 'file' => $_->{'file'} } }
|
||||
@active;
|
||||
}
|
||||
|
||||
# vhost_file_link(file)
|
||||
# Returns the enabled symlink path for a virtual host file
|
||||
sub vhost_file_link
|
||||
{
|
||||
my ($file) = @_;
|
||||
return undef if (!&can_manage_vhost_files());
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
my $avail = &vhost_available_dir();
|
||||
my $short;
|
||||
if (opendir(AVAIL, $avail)) {
|
||||
foreach my $f (sort { lc($a) cmp lc($b) } readdir(AVAIL)) {
|
||||
next if ($f eq "." || $f eq "..");
|
||||
my $afile = $avail."/".$f;
|
||||
my $rafile = &simplify_path(&resolve_links($afile));
|
||||
if ($rafile && $rafile eq $rfile) {
|
||||
$short = $f;
|
||||
last;
|
||||
}
|
||||
}
|
||||
closedir(AVAIL);
|
||||
}
|
||||
$short ||= $rfile;
|
||||
$short =~ s/^.*\///;
|
||||
return &vhost_enabled_dir()."/".$short;
|
||||
}
|
||||
|
||||
# vhost_file_links(file)
|
||||
# Returns enabled symlinks for a virtual host file
|
||||
sub vhost_file_links
|
||||
{
|
||||
my ($file) = @_;
|
||||
my @rv;
|
||||
return @rv if (!&can_manage_vhost_files());
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
my $enabled = &vhost_enabled_dir();
|
||||
opendir(LINKDIR, $enabled) || return @rv;
|
||||
foreach my $f (readdir(LINKDIR)) {
|
||||
next if ($f eq "." || $f eq "..");
|
||||
my $link = $enabled."/".$f;
|
||||
next if (!-l $link);
|
||||
my $rlink = &simplify_path(&resolve_links($link));
|
||||
if ($rlink && $rlink eq $rfile) {
|
||||
push(@rv, $link);
|
||||
}
|
||||
}
|
||||
closedir(LINKDIR);
|
||||
return @rv;
|
||||
}
|
||||
|
||||
# vhost_file_enabled(file)
|
||||
# Returns 1 if a virtual host file has an enabled symlink
|
||||
sub vhost_file_enabled
|
||||
{
|
||||
my ($file) = @_;
|
||||
return scalar(&vhost_file_links($file)) ? 1 : 0;
|
||||
}
|
||||
|
||||
# enable_vhost_file(file)
|
||||
# Enables a virtual host file and rolls back if apache configtest fails
|
||||
sub enable_vhost_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
return $text{'enable_efile'} if (!&can_manage_vhost_state_file($rfile));
|
||||
my $verr = &virtualmin_vhost_file_state_error($rfile, "enable");
|
||||
return $verr if ($verr);
|
||||
my $link = &vhost_file_link($rfile);
|
||||
$link || return $text{'enable_elinkdir'};
|
||||
return undef if (&vhost_file_enabled($rfile));
|
||||
if (-e $link || -l $link) {
|
||||
return &text('enable_elinkexists', "<tt>".&html_escape($link)."</tt>");
|
||||
}
|
||||
&symlink_logged($rfile, $link) ||
|
||||
return &text('enable_elink', "<tt>".&html_escape($link)."</tt>",
|
||||
"<tt>".&html_escape($!)."</tt>");
|
||||
my $err = &test_config();
|
||||
if ($err) {
|
||||
&unlink_logged($link);
|
||||
return &text('enable_etest', "<tt>".&html_escape($err)."</tt>");
|
||||
}
|
||||
&flush_config_cache();
|
||||
&update_last_config_change();
|
||||
return undef;
|
||||
}
|
||||
|
||||
# disable_vhost_file(file)
|
||||
# Disables a virtual host file and rolls back if apache configtest fails
|
||||
sub disable_vhost_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
return $text{'enable_efile'} if (!&can_manage_vhost_state_file($rfile));
|
||||
my $verr = &virtualmin_vhost_file_state_error($rfile, "disable");
|
||||
return $verr if ($verr);
|
||||
my @links = &vhost_file_links($file);
|
||||
return undef if (!@links);
|
||||
my @restore = map { [ $_, readlink($_) ] } @links;
|
||||
my @removed;
|
||||
foreach my $link (@links) {
|
||||
if (!&unlink_logged($link)) {
|
||||
foreach my $r (@removed) {
|
||||
&symlink_logged($r->[1], $r->[0])
|
||||
if (defined($r->[1]) && !-e $r->[0] && !-l $r->[0]);
|
||||
}
|
||||
return &text('enable_eunlink',
|
||||
"<tt>".&html_escape($link)."</tt>",
|
||||
"<tt>".&html_escape($!)."</tt>");
|
||||
}
|
||||
my ($restore) = grep { $_->[0] eq $link } @restore;
|
||||
push(@removed, $restore) if ($restore);
|
||||
}
|
||||
my $err = &test_config();
|
||||
if ($err) {
|
||||
foreach my $r (@restore) {
|
||||
&symlink_logged($r->[1], $r->[0])
|
||||
if (defined($r->[1]) && !-e $r->[0] && !-l $r->[0]);
|
||||
}
|
||||
return &text('enable_etest', "<tt>".&html_escape($err)."</tt>");
|
||||
}
|
||||
&flush_config_cache();
|
||||
&update_last_config_change();
|
||||
return undef;
|
||||
}
|
||||
|
||||
# virtualmin_available()
|
||||
# Returns 1 if Virtualmin is installed and supported on this system
|
||||
sub virtualmin_available
|
||||
{
|
||||
return $main::apache_virtualmin_available
|
||||
if (defined($main::apache_virtualmin_available));
|
||||
$main::apache_virtualmin_available = &foreign_check("virtual-server");
|
||||
return $main::apache_virtualmin_available;
|
||||
}
|
||||
|
||||
# virtualmin_domain_by_name(name)
|
||||
# Returns a Virtualmin domain object by domain name, if one exists
|
||||
sub virtualmin_domain_by_name
|
||||
{
|
||||
my ($name) = @_;
|
||||
return undef if (!&virtualmin_available());
|
||||
return $main::apache_virtualmin_domain_by_name_cache{$name}
|
||||
if (exists($main::apache_virtualmin_domain_by_name_cache{$name}));
|
||||
&foreign_require("virtual-server");
|
||||
my $d = &virtual_server::get_domain_by("dom", $name);
|
||||
$main::apache_virtualmin_domain_by_name_cache{$name} = $d;
|
||||
return $d;
|
||||
}
|
||||
|
||||
# virtual_names(&virt)
|
||||
# Returns all hostnames from ServerName and ServerAlias directives
|
||||
sub virtual_names
|
||||
{
|
||||
my ($virt) = @_;
|
||||
my @rv;
|
||||
my $sn = &find_directive("ServerName", $virt->{'members'});
|
||||
push(@rv, $sn) if ($sn);
|
||||
foreach my $sa (&find_directive_struct("ServerAlias", $virt->{'members'})) {
|
||||
push(@rv, @{$sa->{'words'} || [ ]});
|
||||
if (!@{$sa->{'words'} || [ ]} && $sa->{'value'}) {
|
||||
push(@rv, $sa->{'value'});
|
||||
}
|
||||
}
|
||||
return grep { $_ && $_ ne "*" } &unique(@rv);
|
||||
}
|
||||
|
||||
# virtualmin_domain_for_vhost_file(file)
|
||||
# Returns the Virtualmin domain object for a virtual host file, if any
|
||||
sub virtualmin_domain_for_vhost_file
|
||||
{
|
||||
my ($file) = @_;
|
||||
return undef if (!&virtualmin_available());
|
||||
my $rfile = &simplify_path(&resolve_links($file));
|
||||
$rfile ||= $file;
|
||||
return $main::apache_virtualmin_domain_for_file_cache{$rfile}
|
||||
if (exists($main::apache_virtualmin_domain_for_file_cache{$rfile}));
|
||||
foreach my $virt (&find_virtuals_in_file($file)) {
|
||||
next if (!&can_edit_virt($virt));
|
||||
foreach my $name (&virtual_names($virt)) {
|
||||
my $d = &virtualmin_domain_by_name($name);
|
||||
if (!$d && $name =~ /^www\.(\S+)/i) {
|
||||
$d = &virtualmin_domain_by_name($1);
|
||||
}
|
||||
if ($d) {
|
||||
$main::apache_virtualmin_domain_for_file_cache{$rfile} = $d;
|
||||
return $d;
|
||||
}
|
||||
}
|
||||
}
|
||||
$main::apache_virtualmin_domain_for_file_cache{$rfile} = undef;
|
||||
return undef;
|
||||
}
|
||||
|
||||
# vhost_file_state(file)
|
||||
# Returns the effective enabled state for a virtual host file
|
||||
sub vhost_file_state
|
||||
{
|
||||
my ($file) = @_;
|
||||
my $d = &virtualmin_domain_for_vhost_file($file);
|
||||
if ($d) {
|
||||
return { 'enabled' => $d->{'disabled'} ? 0 : 1,
|
||||
'source' => 'virtualmin',
|
||||
'domain' => $d };
|
||||
}
|
||||
return { 'enabled' => &vhost_file_enabled($file) ? 1 : 0,
|
||||
'source' => 'apache' };
|
||||
}
|
||||
|
||||
# vhost_file_toggle_action(file)
|
||||
# Returns the action needed to toggle a virtual host file's effective state
|
||||
sub vhost_file_toggle_action
|
||||
{
|
||||
my ($file) = @_;
|
||||
return &vhost_file_state($file)->{'enabled'} ? "disable" : "enable";
|
||||
}
|
||||
|
||||
# virtualmin_domain_state_link(&domain, enabled?)
|
||||
# Returns a link to the Virtualmin state change form for some domain
|
||||
sub virtualmin_domain_state_link
|
||||
{
|
||||
my ($d, $enabled) = @_;
|
||||
my $page = $enabled ? "disable_domain.cgi" : "enable_domain.cgi";
|
||||
my $label = $enabled ? $text{'enable_virtualmin_disable_label'} :
|
||||
$text{'enable_virtualmin_enable_label'};
|
||||
my $url = "../virtual-server/".$page."?dom=".&urlize($d->{'id'});
|
||||
return &ui_link("e_escape($url), "\"".$label."\"");
|
||||
}
|
||||
|
||||
# virtualmin_vhost_file_state_error(file, action)
|
||||
# Returns an error if a Virtualmin-owned site is being enabled or disabled here
|
||||
sub virtualmin_vhost_file_state_error
|
||||
{
|
||||
my ($file, $action) = @_;
|
||||
return undef if ($action ne "enable" && $action ne "disable");
|
||||
my $state_info = &vhost_file_state($file);
|
||||
return undef if ($state_info->{'source'} ne "virtualmin");
|
||||
my $d = $state_info->{'domain'};
|
||||
return undef if (!$d);
|
||||
my $state = lc($state_info->{'enabled'} ? $text{'index_enabled'} :
|
||||
$text{'index_disabled'});
|
||||
my $dom = "<tt>".&html_escape($d->{'dom'})."</tt>";
|
||||
my $link = &virtualmin_domain_state_link($d, $state_info->{'enabled'});
|
||||
return $state_info->{'enabled'} ?
|
||||
&text('enable_evirtualmin_disable', $dom, $state, $link) :
|
||||
&text('enable_evirtualmin_enable', $dom, $state, $link);
|
||||
}
|
||||
|
||||
# delete_virtuals_from_file(file, &virtualhosts...)
|
||||
# Deletes VirtualHost blocks from one file and removes the file if empty
|
||||
sub delete_virtuals_from_file
|
||||
{
|
||||
my ($file, @virts) = @_;
|
||||
return 0 if (!@virts);
|
||||
my $lref = &read_file_lines($file);
|
||||
foreach my $virt (sort { $b->{'line'} <=> $a->{'line'} } @virts) {
|
||||
my $len = $virt->{'eline'} - $virt->{'line'} + 1;
|
||||
splice(@$lref, $virt->{'line'}, $len);
|
||||
}
|
||||
my $empty = 1;
|
||||
foreach my $line (@$lref) {
|
||||
if ($line =~ /\S/) {
|
||||
$empty = 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
&flush_file_lines($file);
|
||||
if ($empty) {
|
||||
foreach my $link (&vhost_file_links($file)) {
|
||||
&unlink_logged($link);
|
||||
}
|
||||
&unlink_logged($file);
|
||||
}
|
||||
&flush_config_cache();
|
||||
&update_last_config_change();
|
||||
return scalar(@virts);
|
||||
}
|
||||
|
||||
# renumber(&config, line, file, offset)
|
||||
# Recursively changes the line number of all directives from some file
|
||||
# beyond the given line.
|
||||
@@ -1544,9 +1973,10 @@ return undef;
|
||||
# if necessary.
|
||||
sub before_changing
|
||||
{
|
||||
my @extra = grep { $_ } @_;
|
||||
if ($config{'test_always'} || $access{'test_always'}) {
|
||||
local $conf = &get_config();
|
||||
local @files = &unique(map { $_->{'file'} } @$conf);
|
||||
local @files = &unique((map { $_->{'file'} } @$conf), @extra);
|
||||
local $/ = undef;
|
||||
local $f;
|
||||
foreach $f (@files) {
|
||||
@@ -1969,10 +2399,11 @@ return @rv;
|
||||
sub create_webfile_link
|
||||
{
|
||||
local ($file) = @_;
|
||||
if ($config{'link_dir'}) {
|
||||
my $linkdir = &vhost_enabled_dir();
|
||||
if ($linkdir) {
|
||||
local $short = $file;
|
||||
$short =~ s/^.*\///;
|
||||
local $linksrc = "$config{'link_dir'}/$short";
|
||||
local $linksrc = "$linkdir/$short";
|
||||
&lock_file($linksrc);
|
||||
symlink($file, $linksrc);
|
||||
&unlock_file($linksrc);
|
||||
@@ -1985,16 +2416,16 @@ if ($config{'link_dir'}) {
|
||||
sub delete_webfile_link
|
||||
{
|
||||
local ($file) = @_;
|
||||
if ($config{'link_dir'}) {
|
||||
local $short = $file;
|
||||
$short =~ s/^.*\///;
|
||||
opendir(LINKDIR, $config{'link_dir'});
|
||||
$file = &simplify_path(&resolve_links($file));
|
||||
my $linkdir = &vhost_enabled_dir();
|
||||
if ($linkdir && opendir(LINKDIR, $linkdir)) {
|
||||
foreach my $f (readdir(LINKDIR)) {
|
||||
if ($f ne "." && $f ne ".." &&
|
||||
(&simplify_path(
|
||||
&resolve_links($config{'link_dir'}."/".$f)) eq $file ||
|
||||
$short eq $f)) {
|
||||
&unlink_logged($config{'link_dir'}."/".$f);
|
||||
if ($f ne "." && $f ne "..") {
|
||||
my $link = $linkdir."/".$f;
|
||||
next if (!-l $link);
|
||||
if (&simplify_path(&resolve_links($link)) eq $file) {
|
||||
&unlink_logged($link);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(LINKDIR);
|
||||
|
||||
233
apache/core.pl
233
apache/core.pl
@@ -73,11 +73,12 @@ $rv = [ [ 'AccessFileName', 0, 5, 'virtual', undef, 5 ],
|
||||
[ 'Options', 0, 5, 'virtual directory htaccess', undef, 3 ],
|
||||
[ 'PidFile', 0, 9, 'global', -2.0 ],
|
||||
[ 'Protocols', 0, 1, 'virtual', 2.4 ],
|
||||
[ 'require', 0, 4, 'directory htaccess', undef, 6 ],
|
||||
[ 'require', 0, 4, 'directory htaccess', '-2.4', 6 ],
|
||||
[ 'Require allow deny order Satisfy', 1, 4, 'directory htaccess', 2.4, 6 ],
|
||||
[ 'RLimitCPU', 0, 0, 'virtual', 1.2 ],
|
||||
[ 'RLimitMEM', 0, 0, 'virtual', 1.2 ],
|
||||
[ 'RLimitNPROC', 0, 0, 'virtual', 1.2 ],
|
||||
[ 'Satisfy', 0, 4, 'directory htaccess', 1.2, 4 ],
|
||||
[ 'Satisfy', 0, 4, 'directory htaccess', '1.2-2.4', 4 ],
|
||||
[ 'ScoreBoardFile', 0, 9, 'global', '1.2-2.0' ],
|
||||
[ 'SendBufferSize', 0, 1, 'global', -2.0 ],
|
||||
[ 'ServerAdmin', 0, 1, 'virtual' ],
|
||||
@@ -958,6 +959,234 @@ if ($in{'AuthType'}) { return ( [ $in{'AuthType'} ] ); }
|
||||
else { return ( [ ] ); }
|
||||
}
|
||||
|
||||
# parse_access_require_rule(value)
|
||||
# Maps a Require line to a UI mode and value.
|
||||
sub parse_access_require_rule
|
||||
{
|
||||
my ($value) = @_;
|
||||
my $lv = lc($value);
|
||||
return ('granted', '') if ($lv eq 'all granted');
|
||||
return ('denied', '') if ($lv eq 'all denied');
|
||||
return ('local', '') if ($lv eq 'local');
|
||||
return ('valid-user', '') if ($lv eq 'valid-user');
|
||||
return ('file-owner', '') if ($lv eq 'file-owner');
|
||||
return ('file-group', '') if ($lv eq 'file-group');
|
||||
if ($value =~ /^(ip|host|env|user|group|method|expr)\s+(.+)$/i) {
|
||||
return (lc($1), $2);
|
||||
}
|
||||
return ('other', $value);
|
||||
}
|
||||
|
||||
# legacy_access_rule_to_require(&directive)
|
||||
# Converts a single Allow rule from legacy syntax to a Require mode/value pair.
|
||||
sub legacy_access_rule_to_require
|
||||
{
|
||||
my ($dir) = @_;
|
||||
my $what = join(" ", @{$dir->{'words'}});
|
||||
$what =~ s/^from\s+//i;
|
||||
return ('granted', '') if (lc($what) eq 'all');
|
||||
return ('env', $1) if ($what =~ /^env=(\S+)$/i);
|
||||
return ($what =~ /^[0-9a-f\.\:\/]+$/i ? 'ip' : 'host', $what);
|
||||
}
|
||||
|
||||
# legacy_access_to_require_rules(&allow, &deny, &order)
|
||||
# For the common Apache 2.4 cases, convert old Allow/Deny/Order rules to Require.
|
||||
sub legacy_access_to_require_rules
|
||||
{
|
||||
my ($allow, $deny, $order) = @_;
|
||||
my $orderv = @$order ? lc($order->[0]->{'value'}) : '';
|
||||
|
||||
# allow from all
|
||||
if (@$allow == 1 && !@$deny && $allow->[0]->{'value'} =~ /^from\s+all$/i) {
|
||||
return [ [ 'granted', '' ] ];
|
||||
}
|
||||
|
||||
# deny from all
|
||||
if (@$deny == 1 && !@$allow && $deny->[0]->{'value'} =~ /^from\s+all$/i) {
|
||||
return [ [ 'denied', '' ] ];
|
||||
}
|
||||
|
||||
# deny from all, then allow some specific requests
|
||||
if ($orderv eq 'deny,allow' &&
|
||||
@$deny == 1 &&
|
||||
$deny->[0]->{'value'} =~ /^from\s+all$/i &&
|
||||
@$allow) {
|
||||
my @rv;
|
||||
foreach my $dir (@$allow) {
|
||||
push(@rv, [ &legacy_access_rule_to_require($dir) ]);
|
||||
}
|
||||
return \@rv;
|
||||
}
|
||||
|
||||
return [ ];
|
||||
}
|
||||
|
||||
# access_require_conf_root()
|
||||
# Returns the outer-most config list that contains the current section.
|
||||
sub access_require_conf_root
|
||||
{
|
||||
return $vconf if (defined($vconf));
|
||||
return $hconf if (defined($hconf));
|
||||
return $conf;
|
||||
}
|
||||
|
||||
# access_require_container_info(&requires, &satisfy)
|
||||
# Determines the current top-level Require container mode and rules.
|
||||
sub access_require_container_info
|
||||
{
|
||||
my ($requires, $satisfy) = @_;
|
||||
my @all = grep { $_->{'type'} } &find_directive_struct("RequireAll", $conf);
|
||||
my @any = grep { $_->{'type'} } &find_directive_struct("RequireAny", $conf);
|
||||
my @rules = @$requires;
|
||||
my $mode = @$satisfy ? lc($satisfy->[0]->{'value'}) : 'default';
|
||||
my $advanced = 0;
|
||||
|
||||
if (@all || @any) {
|
||||
$advanced = 1 if (@all + @any > 1 || @$requires || @$satisfy);
|
||||
my $container = @all ? $all[0] : $any[0];
|
||||
$mode = @all ? 'all' : 'any';
|
||||
@rules = ( );
|
||||
foreach my $m (@{$container->{'members'}}) {
|
||||
next if ($m->{'name'} eq 'dummy');
|
||||
if ($m->{'type'} || lc($m->{'name'}) ne 'require') {
|
||||
$advanced = 1;
|
||||
next;
|
||||
}
|
||||
push(@rules, $m);
|
||||
}
|
||||
}
|
||||
|
||||
return ($mode, \@rules, $advanced);
|
||||
}
|
||||
|
||||
sub edit_Require_allow_deny_order_Satisfy
|
||||
{
|
||||
my ($reqs, $allow, $deny, $order, $satisfy, $e) = @_;
|
||||
my (@mode, @value);
|
||||
my ($logic, $active_reqs, $advanced) =
|
||||
&access_require_container_info($reqs, $satisfy);
|
||||
foreach my $req (@$active_reqs) {
|
||||
my ($m, $v) = &parse_access_require_rule($req->{'value'});
|
||||
push(@mode, $m);
|
||||
push(@value, $v);
|
||||
}
|
||||
|
||||
my $has_legacy = @$allow || @$deny || @$order || @$satisfy;
|
||||
if (!@mode && $has_legacy) {
|
||||
foreach my $r (@{&legacy_access_to_require_rules($allow, $deny, $order)}) {
|
||||
push(@mode, $r->[0]);
|
||||
push(@value, $r->[1]);
|
||||
}
|
||||
}
|
||||
|
||||
push(@mode, "");
|
||||
push(@value, "");
|
||||
|
||||
my $rv = "";
|
||||
if ($has_legacy) {
|
||||
$rv .= &ui_alert($text{'core_require_legacy'}, 'warning',
|
||||
["fa-info-circle", "", 1],
|
||||
{ style => "margin-bottom: 5px;" });
|
||||
}
|
||||
if ($advanced) {
|
||||
$rv .= "<i>$text{'core_require_advanced'}</i><br>\n";
|
||||
}
|
||||
$rv .= "$text{'core_require_logic'} ".
|
||||
&select_input($logic, "Require_logic", "default",
|
||||
"$text{'core_require_logic_default'},default",
|
||||
"$text{'core_require_logic_any'},any",
|
||||
"$text{'core_require_logic_all'},all")."<br>\n";
|
||||
$rv .= &ui_tag("div", "", { style => "height: 5px;" });
|
||||
$rv .= "<table border>\n".
|
||||
"<tr $tb> <td><b>$text{'core_require_type'}</b></td> ".
|
||||
"<td><b>$text{'core_require_value'}</b></td> </tr>\n";
|
||||
for(my $i=0; $i<@mode; $i++) {
|
||||
$rv .= "<tr $cb>\n";
|
||||
$rv .= "<td>".&select_input($mode[$i], "Require_mode_$i", "",
|
||||
"$text{'default'},",
|
||||
"$text{'core_require_granted'},granted",
|
||||
"$text{'core_require_denied'},denied",
|
||||
"$text{'core_require_local'},local",
|
||||
"$text{'core_require_ip'},ip",
|
||||
"$text{'core_require_host'},host",
|
||||
"$text{'core_require_env'},env",
|
||||
"$text{'core_require_user'},user",
|
||||
"$text{'core_require_group'},group",
|
||||
"$text{'core_require_validuser'},valid-user",
|
||||
"$text{'core_require_fileowner'},file-owner",
|
||||
"$text{'core_require_filegroup'},file-group",
|
||||
"$text{'core_require_method'},method",
|
||||
"$text{'core_require_expr'},expr",
|
||||
"$text{'core_require_other'},other")."</td>\n";
|
||||
$rv .= sprintf "<td><input name=Require_value_%d size=40 value=\"%s\"></td>\n",
|
||||
$i, &html_escape($value[$i]);
|
||||
$rv .= "</tr>\n";
|
||||
}
|
||||
$rv .= "</table>\n";
|
||||
return (2, $text{'mod_access_restr'}, $rv);
|
||||
}
|
||||
|
||||
sub save_Require_allow_deny_order_Satisfy
|
||||
{
|
||||
my (@req);
|
||||
for(my $i=0; defined($in{"Require_mode_$i"}); $i++) {
|
||||
my $mode = $in{"Require_mode_$i"};
|
||||
my $value = $in{"Require_value_$i"};
|
||||
$value =~ /\r|\n|\0/ && &error($text{'enewline'});
|
||||
$value =~ s/^\s+//;
|
||||
$value =~ s/\s+$//;
|
||||
next if (!$mode && $value eq '');
|
||||
$mode || &error($text{'core_require_etype'});
|
||||
if ($mode eq 'granted') {
|
||||
push(@req, "all granted");
|
||||
}
|
||||
elsif ($mode eq 'denied') {
|
||||
push(@req, "all denied");
|
||||
}
|
||||
elsif ($mode eq 'local' ||
|
||||
$mode eq 'valid-user' ||
|
||||
$mode eq 'file-owner' ||
|
||||
$mode eq 'file-group') {
|
||||
push(@req, $mode);
|
||||
}
|
||||
elsif ($mode eq 'other') {
|
||||
$value =~ /\S/ || &error($text{'core_require_evalue'});
|
||||
push(@req, $value);
|
||||
}
|
||||
else {
|
||||
$value =~ /\S/ || &error($text{'core_require_evalue'});
|
||||
push(@req, "$mode $value");
|
||||
}
|
||||
}
|
||||
|
||||
my $logic = $in{'Require_logic'} || 'default';
|
||||
my $root = &access_require_conf_root();
|
||||
my @all = grep { $_->{'type'} } &find_directive_struct("RequireAll", $conf);
|
||||
my @any = grep { $_->{'type'} } &find_directive_struct("RequireAny", $conf);
|
||||
my @containers = (@all, @any);
|
||||
|
||||
if (@req && $logic ne 'default') {
|
||||
my $new = {
|
||||
'name' => $logic eq 'all' ? 'RequireAll' : 'RequireAny',
|
||||
'value' => '',
|
||||
'type' => 1,
|
||||
'members' => [ map { {
|
||||
'name' => 'Require',
|
||||
'value' => $_,
|
||||
'type' => 0,
|
||||
} } @req ],
|
||||
};
|
||||
my $old = shift(@containers);
|
||||
&save_directive_struct($old, $new, $conf, $root);
|
||||
}
|
||||
|
||||
foreach my $c (@containers) {
|
||||
&save_directive_struct($c, undef, $conf, $root);
|
||||
}
|
||||
|
||||
return ( $logic eq 'default' ? \@req : [ ], [ ], [ ], [ ], [ ] );
|
||||
}
|
||||
|
||||
sub edit_require
|
||||
{
|
||||
local($rv, $mode, $list);
|
||||
|
||||
@@ -3,31 +3,107 @@
|
||||
|
||||
require './apache-lib.pl';
|
||||
&ReadParse();
|
||||
&error_setup($text{'delete_err'});
|
||||
@d = split(/\0/, $in{'d'});
|
||||
$file_action = $in{'toggle'} ? "toggle" : undef;
|
||||
&error_setup($file_action ? $text{'enable_err'} : $text{'delete_err'});
|
||||
$access{'vaddr'} || &error($text{'delete_ecannot'});
|
||||
$conf = &get_config();
|
||||
@d = split(/\0/, $in{'d'});
|
||||
$can_vhost_files = &can_manage_vhost_files();
|
||||
@d || &error($text{'delete_enone'});
|
||||
|
||||
if ($file_action) {
|
||||
&can_manage_vhost_files() || &error($text{'enable_elinkdir'});
|
||||
foreach $d (@d) {
|
||||
if ($d =~ /^file\t([^\t]+)/) {
|
||||
$file = $1;
|
||||
}
|
||||
elsif ($d !~ /^file\t/) {
|
||||
($vmembers, $vconf) = &get_virtual_config($d);
|
||||
next if (!$vconf || !&can_edit_virt($vconf));
|
||||
$file = $vconf->{'file'};
|
||||
}
|
||||
else {
|
||||
next;
|
||||
}
|
||||
$rfile = $file ? &simplify_path(&resolve_links($file)) : undef;
|
||||
$files{$rfile}++ if ($rfile && -f $rfile &&
|
||||
&can_manage_vhost_state_file($rfile));
|
||||
}
|
||||
@files = keys %files;
|
||||
@files || &error($text{'enable_enone'});
|
||||
foreach $file (@files) {
|
||||
$action = &vhost_file_toggle_action($file);
|
||||
$err = &virtualmin_vhost_file_state_error($file, $action);
|
||||
$err && &error($err);
|
||||
$file_actions{$file} = $action;
|
||||
}
|
||||
foreach $file (@files) {
|
||||
$err = $file_actions{$file} eq "enable" ?
|
||||
&enable_vhost_file($file) :
|
||||
&disable_vhost_file($file);
|
||||
$err && &error($err);
|
||||
}
|
||||
&webmin_log($file_action, "vhostfile", scalar(@files));
|
||||
&redirect("");
|
||||
exit;
|
||||
}
|
||||
if (!$in{'delete'}) {
|
||||
&error($text{'delete_eaction'});
|
||||
}
|
||||
|
||||
# Get them all
|
||||
foreach $d (@d) {
|
||||
if ($d =~ /^file\t([^\t]+)\t(\d+)$/) {
|
||||
push(@{$file_lines{$1}}, $2);
|
||||
next;
|
||||
}
|
||||
elsif ($d =~ /^file\t/) {
|
||||
next;
|
||||
}
|
||||
($vmembers, $vconf) = &get_virtual_config($d);
|
||||
$vconf || &error($text{'delete_egone'});
|
||||
&can_edit_virt($vconf) || &error(&text('delete_ecannot2',
|
||||
&virtual_name($vconf)));
|
||||
$can_vhost_files && &is_default_vhost($vconf) &&
|
||||
&error($text{'delete_edefault'});
|
||||
push(@virts, $vconf);
|
||||
}
|
||||
if (%file_lines) {
|
||||
foreach $file (keys %file_lines) {
|
||||
$rfile = &simplify_path(&resolve_links($file));
|
||||
next if (!$rfile || !-f $rfile ||
|
||||
!&can_manage_vhost_state_file($rfile));
|
||||
@fvirts = &find_virtuals_in_file($rfile);
|
||||
foreach $line (@{$file_lines{$file}}) {
|
||||
($vconf) = grep { $_->{'line'} == $line } @fvirts;
|
||||
$vconf || &error($text{'delete_egone'});
|
||||
&can_edit_virt($vconf) ||
|
||||
&error(&text('delete_ecannot2',
|
||||
&virtual_name($vconf)));
|
||||
&is_default_vhost($vconf) &&
|
||||
&error($text{'delete_edefault'});
|
||||
push(@{$file_virts{$rfile}}, $vconf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@virts || %file_virts || &error($text{'delete_enone'});
|
||||
|
||||
# Delete their structures
|
||||
&before_changing();
|
||||
&before_changing(keys %file_virts);
|
||||
foreach $vconf (@virts) {
|
||||
&lock_file($vconf->{'file'});
|
||||
&save_directive_struct($vconf, undef, $conf, $conf);
|
||||
&delete_file_if_empty($vconf->{'file'});
|
||||
}
|
||||
foreach $file (keys %file_virts) {
|
||||
&lock_file($file);
|
||||
$deleted += &delete_virtuals_from_file($file, @{$file_virts{$file}});
|
||||
&unlock_file($file);
|
||||
}
|
||||
&flush_file_lines();
|
||||
&unlock_all_files();
|
||||
&update_last_config_change();
|
||||
&after_changing();
|
||||
&webmin_log("virts", "delete", scalar(@virts));
|
||||
$deleted += scalar(@virts);
|
||||
&webmin_log("virts", "delete", $deleted);
|
||||
&redirect("");
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ print $text{'defines_desc'},"<p>\n";
|
||||
@defs = &get_httpd_defines(1);
|
||||
if (@defs) {
|
||||
print &text('defines_config',
|
||||
"<tt><b>".join(" ", @defs)."</b></tt>"),"<p>\n";
|
||||
"<tt><b>".&html_escape(join(" ", @defs))."</b></tt>"),
|
||||
"<p>\n";
|
||||
}
|
||||
|
||||
print &ui_form_start("save_defines.cgi", "post");
|
||||
|
||||
@@ -28,7 +28,7 @@ if ($in{'type'} == 6) {
|
||||
print &ui_hr();
|
||||
print &ui_subheading($text{'global_mime'});
|
||||
print "$text{'global_mimedesc'}<p>\n";
|
||||
@links = ( &ui_link("edit_gmime_type.cgi?file=$mfile",
|
||||
@links = ( &ui_link("edit_gmime_type.cgi?file=".&urlize($mfile),
|
||||
$text{'global_add'}) );
|
||||
print &ui_links_row(\@links);
|
||||
print &ui_columns_start([ $text{'global_type'},
|
||||
@@ -41,7 +41,8 @@ if ($in{'type'} == 6) {
|
||||
if (/^\s*(\S+)\s*(.*)$/) {
|
||||
print &ui_columns_row([
|
||||
&ui_link("edit_gmime_type.cgi?line=$line".
|
||||
"&file=$mfile", $1), $2 ]);
|
||||
"&file=".&urlize($mfile), &html_escape($1)),
|
||||
&html_escape($2) ]);
|
||||
}
|
||||
$line++;
|
||||
}
|
||||
|
||||
103
apache/index.cgi
103
apache/index.cgi
@@ -102,6 +102,10 @@ if (&can_edit_virt()) {
|
||||
push(@vproxy, undef);
|
||||
$sn ||= &get_system_hostname();
|
||||
push(@vurl, $defport ? "http://$sn:$defport/" : "http://$sn/");
|
||||
push(@vfile, undef);
|
||||
push(@vstatus, "");
|
||||
push(@vsel, undef);
|
||||
push(@vfilemanage, 0);
|
||||
$showing_default++;
|
||||
}
|
||||
|
||||
@@ -128,16 +132,23 @@ elsif ($httpd_modules{'core'} >= 1.2) {
|
||||
$ba = &find_directive("ServerName", $conf);
|
||||
$nv{&to_ipaddress($ba ? $ba : &get_system_hostname())}++;
|
||||
}
|
||||
@virt = grep { &can_edit_virt($_) } @virt;
|
||||
$can_vhost_files = &can_manage_vhost_files();
|
||||
@vrows = &get_virtual_list_rows($conf);
|
||||
if ($config{'show_order'} == 1) {
|
||||
# sort by server name
|
||||
@virt = sort { &server_name_sort($a) cmp &server_name_sort($b) } @virt;
|
||||
@vrows = sort { &server_name_sort($a->{'virt'}) cmp
|
||||
&server_name_sort($b->{'virt'}) } @vrows;
|
||||
}
|
||||
elsif ($config{'show_order'} == 2) {
|
||||
# sort by IP address
|
||||
@virt = sort { &server_ip_sort($a) cmp &server_ip_sort($b) } @virt;
|
||||
@vrows = sort { &server_ip_sort($a->{'virt'}) cmp
|
||||
&server_ip_sort($b->{'virt'}) } @vrows;
|
||||
}
|
||||
foreach $v (@virt) {
|
||||
@virt = map { $_->{'virt'} } grep { $_->{'active'} } @vrows;
|
||||
%available_vhost_file = map { $_, 1 } &get_vhost_available_files()
|
||||
if ($can_vhost_files);
|
||||
foreach $r (@vrows) {
|
||||
$v = $r->{'virt'};
|
||||
$vm = $v->{'members'};
|
||||
if ($v->{'words'}->[0] =~ /^\[(\S+)\]:(\d+)$/) {
|
||||
# IPv6 address and port
|
||||
@@ -163,7 +174,7 @@ foreach $v (@virt) {
|
||||
$idx = &indexof($v, @$conf);
|
||||
push(@vidx, $idx);
|
||||
push(@vname, $text{'index_virt'});
|
||||
push(@vlink, "virt_index.cgi?virt=$idx");
|
||||
push(@vlink, $r->{'active'} ? "virt_index.cgi?virt=$idx" : undef);
|
||||
$sname = &find_directive("ServerName", $vm);
|
||||
local $daddr = $addr eq "_default_" ||
|
||||
($addr eq "*" && $httpd_modules{'core'} < 1.2);
|
||||
@@ -225,10 +236,34 @@ foreach $v (@virt) {
|
||||
}
|
||||
$sp = undef if ($sp == 80 && $prot eq "http" ||
|
||||
$sp == 443 && $prot eq "https");
|
||||
push(@vurl, $sp ? "$prot://$sn:$sp/" : "$prot://$sn/");
|
||||
push(@vurl, $r->{'active'} ?
|
||||
($sp ? "$prot://$sn:$sp/" : "$prot://$sn/") : undef);
|
||||
local $rfile = $r->{'file'} ? &simplify_path(&resolve_links($r->{'file'}))
|
||||
: undef;
|
||||
push(@vfile, $rfile);
|
||||
local $status = "";
|
||||
if ($can_vhost_files && $rfile && $available_vhost_file{$rfile}) {
|
||||
local $enabled = &vhost_file_state($rfile)->{'enabled'};
|
||||
$status = $enabled ? $text{'index_enabled'} :
|
||||
$text{'index_disabled'};
|
||||
}
|
||||
push(@vstatus, $status);
|
||||
local $file_manage = $can_vhost_files && $rfile &&
|
||||
$available_vhost_file{$rfile} &&
|
||||
&can_manage_vhost_state_file($rfile);
|
||||
push(@vfilemanage, $file_manage ? 1 : 0);
|
||||
local $sel;
|
||||
if ($r->{'active'} && (!$can_vhost_files || !&is_default_vhost($v))) {
|
||||
$sel = $idx;
|
||||
}
|
||||
elsif (!$r->{'active'} && $can_vhost_files && $rfile &&
|
||||
$available_vhost_file{$rfile} && $file_manage) {
|
||||
$sel = "file\t".$rfile."\t".$v->{'line'};
|
||||
}
|
||||
push(@vsel, $sel);
|
||||
}
|
||||
|
||||
if (@vlink == 1 && !$access{'global'} && $access{'virts'} ne "*" &&
|
||||
if (@vlink == 1 && $vlink[0] && !$access{'global'} && $access{'virts'} ne "*" &&
|
||||
!$access{'create'} && $access{'noconfig'}) {
|
||||
# Can only manage one vhost, so go direct to it
|
||||
&redirect($vlink[0]);
|
||||
@@ -297,7 +332,9 @@ if ($access{'global'}) {
|
||||
# work out select links
|
||||
print &ui_tabs_start_tab("mode", "list");
|
||||
#print $text{'index_desclist'},"<p>\n";
|
||||
$showdel = $access{'vaddr'} && ($vidx[0] || $vidx[1]);
|
||||
$showdel = $access{'vaddr'} &&
|
||||
grep { defined($_) && $_ ne "" } @vsel;
|
||||
$showtoggle = $can_vhost_files && grep { $_ } @vfilemanage;
|
||||
@links = ( );
|
||||
if ($showdel) {
|
||||
push(@links, &select_all_link("d"),
|
||||
@@ -326,8 +363,10 @@ if ($config{'max_servers'} && @vname > $config{'max_servers'}) {
|
||||
}
|
||||
elsif ($config{'show_list'} && scalar(@vname)) {
|
||||
# as list for people with lots of servers
|
||||
$list_form = "vhosts_form";
|
||||
if ($showdel) {
|
||||
print &ui_form_start("delete_vservs.cgi", "post");
|
||||
print &ui_form_start("delete_vservs.cgi", "post", undef,
|
||||
"id='$list_form'");
|
||||
}
|
||||
print &ui_links_row(\@links);
|
||||
print &ui_columns_start([
|
||||
@@ -337,19 +376,23 @@ elsif ($config{'show_list'} && scalar(@vname)) {
|
||||
$text{'index_port'},
|
||||
$text{'index_name'},
|
||||
$text{'index_root'},
|
||||
$can_vhost_files ? ( $text{'index_status'} ) : ( ),
|
||||
$text{'index_url'} ], 100);
|
||||
for($i=0; $i<@vname; $i++) {
|
||||
local @cols;
|
||||
push(@cols, &ui_link($vlink[$i], $vname[$i]) );
|
||||
push(@cols, $vlink[$i] ? &ui_link($vlink[$i], $vname[$i]) :
|
||||
$vname[$i] );
|
||||
push(@cols, &html_escape($vaddr[$i]));
|
||||
push(@cols, &html_escape($vport[$i]));
|
||||
push(@cols, $vserv[$i] || $text{'index_auto'});
|
||||
push(@cols, &html_escape($vproxy[$i]) ||
|
||||
&html_escape($vroot[$i]));
|
||||
push(@cols, &ui_link($vurl[$i], $text{'index_view'}) );
|
||||
if ($showdel && $vidx[$i]) {
|
||||
push(@cols, $vstatus[$i]) if ($can_vhost_files);
|
||||
push(@cols, $vurl[$i] ? &ui_link($vurl[$i], $text{'index_view'}) :
|
||||
"" );
|
||||
if ($showdel && defined($vsel[$i]) && $vsel[$i] ne "") {
|
||||
print &ui_checked_columns_row(\@cols, undef,
|
||||
"d", $vidx[$i]);
|
||||
"d", $vsel[$i]);
|
||||
}
|
||||
elsif ($showdel) {
|
||||
print &ui_columns_row([ "", @cols ]);
|
||||
@@ -361,13 +404,23 @@ elsif ($config{'show_list'} && scalar(@vname)) {
|
||||
print &ui_columns_end();
|
||||
print &ui_links_row(\@links);
|
||||
if ($showdel) {
|
||||
print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]);
|
||||
if ($showtoggle) {
|
||||
print &ui_form_end_side_by_side($list_form,
|
||||
[ [ "delete", $text{'index_delete'} ] ],
|
||||
[ [ "toggle", $text{'index_toggle'}, undef,
|
||||
undef, "form=\"$list_form\"" ] ]);
|
||||
}
|
||||
else {
|
||||
print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# as icons for niceness
|
||||
$list_form = "vhosts_form";
|
||||
if ($showdel) {
|
||||
print &ui_form_start("delete_vservs.cgi", "post");
|
||||
print &ui_form_start("delete_vservs.cgi", "post", undef,
|
||||
"id='$list_form'");
|
||||
}
|
||||
print &ui_links_row(\@links);
|
||||
print "<table width=100% cellpadding=5>\n";
|
||||
@@ -376,8 +429,9 @@ else {
|
||||
print '<div class="row icons-row inline-row">';
|
||||
&generate_icon("images/virt.gif", $vname[$i], $vlink[$i],
|
||||
undef, undef, undef,
|
||||
$vidx[$i] && $access{'vaddr'} ?
|
||||
&ui_checkbox("d", $vidx[$i]) : "");
|
||||
defined($vsel[$i]) && $vsel[$i] ne "" &&
|
||||
$access{'vaddr'} ?
|
||||
&ui_checkbox("d", $vsel[$i]) : "");
|
||||
print "</div>\n";
|
||||
print "</td> <td valign=top>\n";
|
||||
print "$vdesc[$i]<br>\n";
|
||||
@@ -397,12 +451,24 @@ else {
|
||||
print "<b>$text{'index_root'}</b> ",
|
||||
&html_escape($vroot[$i]),"</td> </tr>\n";
|
||||
}
|
||||
if ($can_vhost_files && $vstatus[$i]) {
|
||||
print "<tr><td colspan=2><b>$text{'index_status'}</b> ",
|
||||
$vstatus[$i],"</td></tr>\n";
|
||||
}
|
||||
print "</table></td> </tr>\n";
|
||||
}
|
||||
print "</table>\n";
|
||||
print &ui_links_row(\@links);
|
||||
if ($showdel) {
|
||||
print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]);
|
||||
if ($showtoggle) {
|
||||
print &ui_form_end_side_by_side($list_form,
|
||||
[ [ "delete", $text{'index_delete'} ] ],
|
||||
[ [ "toggle", $text{'index_toggle'}, undef,
|
||||
undef, "form=\"$list_form\"" ] ]);
|
||||
}
|
||||
else {
|
||||
print &ui_form_end([ [ "delete", $text{'index_delete'} ] ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
print &ui_tabs_end_tab();
|
||||
@@ -492,4 +558,3 @@ return $addr eq '_default_' || $addr eq '*' ? undef :
|
||||
$addr =~ /^\[(\S+)\]$/ && &check_ip6address($1) ? $1 :
|
||||
&to_ipaddress($addr);
|
||||
}
|
||||
|
||||
|
||||
@@ -330,7 +330,7 @@ acl_types=أنواع التوجيه المتاحة
|
||||
acl_all=الكل
|
||||
acl_sel=المحدد ..
|
||||
acl_names=يمكن تعديل أسماء الخادم؟
|
||||
acl_dirs=Apache directives available<br><font size=-1>(Subject to types limit above)</font>
|
||||
acl_dirs=توجيهات Apache المتاحة، وفقًا لأنواع التوجيهات المحددة أعلاه
|
||||
acl_dirs0=الكل
|
||||
acl_dirs1=المدرجة فقط ..
|
||||
acl_dirs2=كل ما عدا المدرجة ..
|
||||
|
||||
@@ -329,7 +329,7 @@ acl_types=Налични видове директиви
|
||||
acl_all=Всички
|
||||
acl_sel=Избрани..
|
||||
acl_names=Може да редактира имена на сървъри?
|
||||
acl_dirs=Достъпни директиви на Apache<br><font size=-1>(съгласно лимита на типове по-горе)</font>
|
||||
acl_dirs=Налични директиви на Apache, ограничени от избраните по-горе типове директиви
|
||||
acl_dirs0=Всички
|
||||
acl_dirs1=Само изброените ..
|
||||
acl_dirs2=Всички освен изброените ..
|
||||
|
||||
@@ -329,7 +329,7 @@ acl_types=Tipus de directives disponibles
|
||||
acl_all=Tots
|
||||
acl_sel=Seleccionats...
|
||||
acl_names=Pot editar els noms dels servidors
|
||||
acl_dirs=Directives Apache disponibles<br><font size=-1>(Subjectes al límit de tipus superior)</font>
|
||||
acl_dirs=Directives Apache disponibles, limitades pels tipus de directiva seleccionats a sobre
|
||||
acl_dirs0=Totes
|
||||
acl_dirs1=Només les llistades
|
||||
acl_dirs2=Totes excepte les llistades
|
||||
|
||||
@@ -320,7 +320,7 @@ acl_types=Typy direktiv k dispozici
|
||||
acl_all=Všechny
|
||||
acl_sel=Vybrané..
|
||||
acl_names=Mohu upravovat názvy serverů?
|
||||
acl_dirs=Direktivy Apache jsou přístupné<br><font size=-1>(Subject to types limit above)</font>
|
||||
acl_dirs=Dostupné direktivy Apache, omezené typy direktiv vybranými výše
|
||||
acl_dirs0=Vše
|
||||
acl_dirs1=Jen vybrané ..
|
||||
acl_dirs2=Vše kromě vybraných ..
|
||||
|
||||
@@ -78,7 +78,7 @@ acl_types=Tilgængelige direktiv typer
|
||||
acl_all=Alle
|
||||
acl_sel=Valgte ..
|
||||
acl_names=Kan redigere servernavne?
|
||||
acl_dirs=Apache direktiver tilgængelige<br><font size=-1>(Subjekt tor type begrænsinger ovenfor)</font>
|
||||
acl_dirs=Tilgængelige Apache-direktiver, begrænset af de direktivtyper, der er valgt ovenfor
|
||||
acl_dirs0=Alle
|
||||
acl_dirs1=Kun listede ..
|
||||
acl_dirs2=Alle undtagen listede ..
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Verfügbare Direktiventypen
|
||||
acl_all=Alle
|
||||
acl_sel=Ausgewählt..
|
||||
acl_names=Kann Servernamen bearbeiten?
|
||||
acl_dirs=Verfügbare Apache-Direktiven<br><font size=-1>(Abhängig von obigen Typenbeschränkungen)</font>
|
||||
acl_dirs=Verfügbare Apache-Direktiven, eingeschränkt durch die oben ausgewählten Direktivtypen
|
||||
acl_dirs0=Alle
|
||||
acl_dirs1=Nur aufgeführte ..
|
||||
acl_dirs2=Alle außer aufgeführte ..
|
||||
|
||||
@@ -329,7 +329,7 @@ acl_types=Directive types available
|
||||
acl_all=All
|
||||
acl_sel=Selected..
|
||||
acl_names=Can edit server names?
|
||||
acl_dirs=Apache directives available<br><font size=-1>(Subject to types limit above)</font>
|
||||
acl_dirs=Διαθέσιμες οδηγίες Apache, περιορισμένες από τους τύπους οδηγιών που έχουν επιλεγεί παραπάνω
|
||||
acl_dirs0=All
|
||||
acl_dirs1=Only listed ..
|
||||
acl_dirs2=All except listed ..
|
||||
|
||||
@@ -34,6 +34,9 @@ index_listen=Listen on address (if needed)
|
||||
index_port=Port
|
||||
index_name=Server Name
|
||||
index_root=Document Root
|
||||
index_status=State
|
||||
index_enabled=Enabled
|
||||
index_disabled=Disabled
|
||||
index_url=URL
|
||||
index_view=Open..
|
||||
index_adddir=Allow access to this directory
|
||||
@@ -57,6 +60,7 @@ index_fmode1=Virtual servers file $1
|
||||
index_fmode1d=New file under virtual servers directory $1
|
||||
index_fmode2=Selected file..
|
||||
index_delete=Delete Selected Servers
|
||||
index_toggle=Toggle State
|
||||
|
||||
cvirt_ecannot=You are not allowed to create a virtual server
|
||||
cvirt_err=Failed to create virtual server
|
||||
@@ -332,7 +336,7 @@ acl_types=Directive types available
|
||||
acl_all=All
|
||||
acl_sel=Selected..
|
||||
acl_names=Can edit server names?
|
||||
acl_dirs=Apache directives available<br><font size=-1>(Subject to types limit above)</font>
|
||||
acl_dirs=Available Apache directives, limited by the directive types selected above
|
||||
acl_dirs0=All
|
||||
acl_dirs1=Only listed ..
|
||||
acl_dirs2=All except listed ..
|
||||
@@ -873,6 +877,30 @@ mod_access_epip='$1' is not a valid partial IP address
|
||||
mod_access_emask='$1' is not a valid network/netmask pair
|
||||
mod_access_ecidr='$1' is not a valid network/CIDR pair
|
||||
mod_access_evar='$1' is not a valid variable name
|
||||
core_require_legacy=Legacy Allow/Deny/Order directives were found. Apache 2.4 uses Require rules. Saving this form will replace the legacy directives with the Require rules below.
|
||||
core_require_advanced=Advanced authorization containers were found. This form edits a flat set of Require rules with an optional top-level RequireAny or RequireAll block. Saving will replace nested or mixed authorization containers.
|
||||
core_require_logic=Authorization logic
|
||||
core_require_logic_default=Default flat Require rules
|
||||
core_require_logic_any=Any rule may match
|
||||
core_require_logic_all=All rules must match
|
||||
core_require_type=Rule type
|
||||
core_require_value=Value or arguments
|
||||
core_require_granted=Allow all requests
|
||||
core_require_denied=Deny all requests
|
||||
core_require_local=Only local requests
|
||||
core_require_ip=Request from IP or network
|
||||
core_require_host=Request from host
|
||||
core_require_env=If variable is set
|
||||
core_require_user=Only these users
|
||||
core_require_group=Only these groups
|
||||
core_require_validuser=All valid users
|
||||
core_require_fileowner=File owner matches
|
||||
core_require_filegroup=Group owner matches
|
||||
core_require_method=HTTP method
|
||||
core_require_expr=Expression
|
||||
core_require_other=Raw Require rule
|
||||
core_require_etype=You must select a Require rule type
|
||||
core_require_evalue=You must enter a value for the selected Require rule
|
||||
|
||||
mod_auth_ufile=User text file
|
||||
mod_auth_uedit=Edit users
|
||||
@@ -1008,6 +1036,7 @@ log_stop=Stopped webserver
|
||||
log_apply=Applied changes
|
||||
log_manual=Manually edited configuration file $1
|
||||
log_virts_delete=Deleted $1 virtual servers
|
||||
log_toggle_vhostfile=Toggled state of $1 virtual host files
|
||||
|
||||
search_title=Find Servers
|
||||
search_notfound=No matching virtual servers found
|
||||
@@ -1124,6 +1153,22 @@ delete_err=Failed to delete virtual servers
|
||||
delete_enone=None selected
|
||||
delete_ecannot=You are not allowed to delete servers
|
||||
delete_ecannot2=You are not allowed to edit the server $1
|
||||
delete_eaction=No action was selected
|
||||
delete_egone=The selected virtual server no longer exists
|
||||
delete_edefault=The default virtual server cannot be deleted
|
||||
|
||||
enable_err=Failed to change virtual host file state
|
||||
enable_enone=No manageable virtual host files were selected
|
||||
enable_efile=Virtual host file does not exist or cannot be managed
|
||||
enable_elinkdir=No enabled virtual host links directory is configured
|
||||
enable_elink=Failed to create symbolic link $1 : $2
|
||||
enable_eunlink=Failed to remove symbolic link $1 : $2
|
||||
enable_elinkexists=The symbolic link $1 already exists
|
||||
enable_etest=Apache configuration test failed after changing the virtual host file state : $1
|
||||
enable_evirtualmin_disable=This Apache virtual host is managed by Virtualmin virtual server $1, which is currently $2. Site disabling should be done in Virtualmin using $3.
|
||||
enable_evirtualmin_enable=This Apache virtual host is managed by Virtualmin virtual server $1, which is currently $2. Site enabling should be done in Virtualmin using $3.
|
||||
enable_virtualmin_disable_label=Disable and Delete ⇾ Disable Virtual Server
|
||||
enable_virtualmin_enable_label=Disable and Delete ⇾ Enable Virtual Server
|
||||
|
||||
syslog_desc=Apache error log
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ htaccess_err=Error al crear el archivo de opciones
|
||||
defines_list=Parámetros definidos
|
||||
|
||||
acl_aliasdir=Limite los alias al directorio
|
||||
acl_dirs=Directivas de Apache disponibles <br><font size=-1> (Sujeto al límite de tipos anterior) </font>
|
||||
acl_dirs=Directivas de Apache disponibles, limitadas por los tipos de directiva seleccionados arriba
|
||||
acl_dirs0=Todos
|
||||
acl_dirs1=Solo listado ..
|
||||
acl_dirs2=Todos excepto los enumerados.
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Zuzentarau motak eskuragarri
|
||||
acl_all=guztiak
|
||||
acl_sel=Hautatutako ..
|
||||
acl_names=Editatu al ditzakezu zerbitzariaren izenak?
|
||||
acl_dirs=Apache zuzentzaileak eskuragarri daude <font size=-1>(Aurreko muga moten menpe)</font>
|
||||
acl_dirs=Eskuragarri dauden Apache zuzentarauak, goian hautatutako zuzentarau motez mugatuta
|
||||
acl_dirs0=guztiak
|
||||
acl_dirs1=Zerrenda bakarra ..
|
||||
acl_dirs2=Zerrendatu guztiak ..
|
||||
|
||||
@@ -35,7 +35,7 @@ defines_list=پارامترهای تعریف شده
|
||||
|
||||
acl_aliasdir=نام مستعار را به فهرست راهنما محدود كنيد
|
||||
acl_names=آیا می توانید نام سرور را ویرایش کنید؟
|
||||
acl_dirs=Apache directives available<br><font size=-1>(Subject to types limit above)</font>
|
||||
acl_dirs=دستورهای Apache موجود، محدود به انواع دستور انتخابشده در بالا
|
||||
acl_dirs0=همه
|
||||
acl_dirs1=فقط ذکر شده ..
|
||||
acl_dirs2=همه به جز ذکر شده ..
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Direktiivityyppejä saatavana
|
||||
acl_all=Kaikki
|
||||
acl_sel=Valitut ..
|
||||
acl_names=Voiko palvelimen nimiä muokata?
|
||||
acl_dirs=Apache-direktiivit saatavilla <br><font size=-1> (Ellei tyyppirajoitusta ole yllä) </font>
|
||||
acl_dirs=Saatavilla olevat Apache-direktiivit, joita yllä valitut direktiivityypit rajoittavat
|
||||
acl_dirs0=Kaikki
|
||||
acl_dirs1=Vain listattu ..
|
||||
acl_dirs2=Kaikki paitsi luetellut ..
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Types de directives disponibles
|
||||
acl_all=Tous
|
||||
acl_sel=Sélectionnés...
|
||||
acl_names=Peut modifier les noms de serveurs?
|
||||
acl_dirs=Directives Apache disponibles<br><font size=-1>(assujetties aux limites ci-dessus)</font>
|
||||
acl_dirs=Directives Apache disponibles, limitées par les types de directives sélectionnés ci-dessus
|
||||
acl_dirs0=Toutes
|
||||
acl_dirs1=Seulement les suivantes ...
|
||||
acl_dirs2=Toutes sauf les suivantes ...
|
||||
|
||||
@@ -322,7 +322,7 @@ acl_types=Tipovi propisa dostupni
|
||||
acl_all=Sve
|
||||
acl_sel=Odabrano..
|
||||
acl_names=Ne možete urediti nazive poslužitelja?
|
||||
acl_dirs=Apache propisi dostupni<br><font size=-1>(Mterija tipova limita je iznad)</font>
|
||||
acl_dirs=Dostupne Apache direktive, ograničene vrstama direktiva odabranima iznad
|
||||
acl_dirs0=Sve
|
||||
acl_dirs1=Samo izlistano ..
|
||||
acl_dirs2=Sve prihvaćene liste ..
|
||||
|
||||
@@ -32,7 +32,7 @@ htaccess_err=Nem sikerült létrehozni az opciós fájlt
|
||||
defines_list=Meghatározott paraméterek
|
||||
|
||||
acl_aliasdir=Korlátozza az álneveket a könyvtárba
|
||||
acl_dirs=Apache-irányelvek elérhetőek <br><font size=-1> (A fenti típuskorlátozástól függően) </font>
|
||||
acl_dirs=Elérhető Apache-irányelvek, a fent kiválasztott irányelvtípusok által korlátozva
|
||||
acl_dirs0=Összes
|
||||
acl_dirs1=Csak felsorolt ..
|
||||
acl_dirs2=Minden, kivéve a felsorolt ..
|
||||
|
||||
@@ -45,7 +45,7 @@ restart_ecannot=Non è consentito applicare modifiche
|
||||
acl_apply=È possibile applicare le modifiche?
|
||||
acl_aliasdir=Limita gli alias alla directory
|
||||
acl_names=Puoi modificare i nomi dei server?
|
||||
acl_dirs=Direttive Apache disponibili <br><font size=-1> (Soggetto al limite di tipi sopra) </font>
|
||||
acl_dirs=Direttive Apache disponibili, limitate dai tipi di direttiva selezionati sopra
|
||||
acl_dirs0=Tutti
|
||||
acl_dirs1=Solo elencato ..
|
||||
acl_dirs2=Tutti tranne quelli elencati. ..
|
||||
|
||||
@@ -322,7 +322,7 @@ acl_types=利用可能なディレクティブのタイプ
|
||||
acl_all=すべて
|
||||
acl_sel=選択済み..
|
||||
acl_names=サーバー名を編集できますか?
|
||||
acl_dirs=利用可能なApacheディレクティブ<br> <font size = -1>(上記のタイプ制限に従う)</font>
|
||||
acl_dirs=利用可能な Apache ディレクティブ。上で選択したディレクティブタイプに制限されます
|
||||
acl_dirs0=All
|
||||
acl_dirs1=のみ記載..
|
||||
acl_dirs2=All except listed ..
|
||||
|
||||
@@ -77,7 +77,7 @@ restart_ecannot=변경 사항을 적용 할 수 없습니다
|
||||
acl_apply=변경 사항을 적용 할 수 있습니까?
|
||||
acl_aliasdir=디렉토리로 별명 제한
|
||||
acl_names=서버 이름을 편집 할 수 있습니까?
|
||||
acl_dirs=Apache 지시문 사용 가능 <br><font size=-1> (위의 유형 제한에 따름) </font>
|
||||
acl_dirs=사용 가능한 Apache 지시문, 위에서 선택한 지시문 유형으로 제한됨
|
||||
acl_dirs0=모두
|
||||
acl_dirs1=목록 만 ..
|
||||
acl_dirs2=목록을 제외한 모든 ..
|
||||
|
||||
@@ -297,7 +297,7 @@ acl_types=Jenis arahan boleh didapati
|
||||
acl_all=Semua
|
||||
acl_sel=Dipilih ..
|
||||
acl_names=Boleh sunting nama pelayan?
|
||||
acl_dirs=Arahan Apache yang tersedia <br> <font size=-1> (Tertakluk kepada jenis had seperti diatas) </font>
|
||||
acl_dirs=Arahan Apache yang tersedia, dihadkan oleh jenis arahan yang dipilih di atas
|
||||
acl_dirs0=Semua
|
||||
acl_dirs1=Hanya disenaraikan ..
|
||||
acl_dirs2=Semua kecuali yang disenaraikan ..
|
||||
|
||||
@@ -328,7 +328,7 @@ acl_types=Beschikbare soorten richtlijnen
|
||||
acl_all=Alles
|
||||
acl_sel=Geselecteerd..
|
||||
acl_names=Mag server namen bewerken?
|
||||
acl_dirs=Beschikbare Apache richtlijnen<br><font size=-1>(Behalve de soorten hierboven)</font>
|
||||
acl_dirs=Beschikbare Apache-richtlijnen, beperkt door de hierboven geselecteerde richtlijntypen
|
||||
acl_dirs0=Alles
|
||||
acl_dirs1=Alleen die in de lijst
|
||||
acl_dirs2=Alles behalve die in de lijst ..
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Tilgjengelige direktivtyper
|
||||
acl_all=Alle
|
||||
acl_sel=Valgte..
|
||||
acl_names=Kan redigere tjenernavn?
|
||||
acl_dirs=Tilgjengelig Apache direktiver<br><font size=-1>(Med typebegrensninger som angitt ovenfor)</font>
|
||||
acl_dirs=Tilgjengelige Apache-direktiver, begrenset av direktivtypene som er valgt ovenfor
|
||||
acl_dirs0=Alle
|
||||
acl_dirs1=Kun de i listen ..
|
||||
acl_dirs2=Alle unntatt de i listen ..
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Dostępne typy dyrektyw
|
||||
acl_all=Wszystkie
|
||||
acl_sel=Wybrane..
|
||||
acl_names=Może edytować nazwy serwerów?
|
||||
acl_dirs=Dostępne dyrektywy Apache<br><font size=-1>(Zależne od ograniczeń typów powyżej)</font>
|
||||
acl_dirs=Dostępne dyrektywy Apache, ograniczone przez wybrane powyżej typy dyrektyw
|
||||
acl_dirs0=Wszystkie
|
||||
acl_dirs1=Tylko wymienione ..
|
||||
acl_dirs2=Wszystkie oprócz wymienionych ..
|
||||
|
||||
@@ -120,7 +120,7 @@ acl_defserv=Servidor Padrão
|
||||
acl_apply=Pode aplicar alterações?
|
||||
acl_aliasdir=Limitar aliases ao diretório
|
||||
acl_names=Pode editar nomes de servidores?
|
||||
acl_dirs=Diretivas Apache disponíveis <br><font size=-1> (Sujeito ao limite de tipos acima) </font>
|
||||
acl_dirs=Diretivas Apache disponíveis, limitadas pelos tipos de diretiva selecionados acima
|
||||
acl_dirs0=Todos
|
||||
acl_dirs1=Apenas listado ..
|
||||
acl_dirs2=Todos, exceto listados ..
|
||||
|
||||
@@ -323,7 +323,7 @@ acl_types=Tipos de diretivas disponíveis
|
||||
acl_all=Todos
|
||||
acl_sel=Selecionados..
|
||||
acl_names=Editar nome de servidores?
|
||||
acl_dirs=Diretivas do Apache disponíveis<br><font size=-1>(Assunto para os tipos abaixo permitidos)</font>
|
||||
acl_dirs=Diretivas do Apache disponíveis, limitadas pelos tipos de diretiva selecionados acima
|
||||
acl_dirs0=Todos
|
||||
acl_dirs1=Somente listados ..
|
||||
acl_dirs2=Todos exceto os listados ..
|
||||
|
||||
@@ -318,7 +318,7 @@ acl_types=Доступные типы директив
|
||||
acl_all=Все
|
||||
acl_sel=Выбранные..
|
||||
acl_names=Отредактировать имена серверов?
|
||||
acl_dirs=Имеющиеся директивы Apache <br><font size=-1>(С учетом типов ограничить выше) </font>
|
||||
acl_dirs=Доступные директивы Apache, ограниченные выбранными выше типами директив
|
||||
acl_dirs0=Все
|
||||
acl_dirs1=Только перечисленные...
|
||||
acl_dirs2=Все, кроме перечисленных...
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=Dostupné typy smernice
|
||||
acl_all=všetko
|
||||
acl_sel=Vybraný ..
|
||||
acl_names=Môžete upravovať názvy serverov?
|
||||
acl_dirs=Dostupné direktívy Apache <br><font size=-1> (podľa obmedzenia typov vyššie) </font>
|
||||
acl_dirs=Dostupné direktívy Apache, obmedzené typmi direktív vybranými vyššie
|
||||
acl_dirs0=všetko
|
||||
acl_dirs1=Iba uvedené ..
|
||||
acl_dirs2=Všetky okrem uvedených ..
|
||||
|
||||
@@ -323,7 +323,7 @@ acl_types=Tillgängliga direktiv typer
|
||||
acl_all=Alla
|
||||
acl_sel=Angivna ...
|
||||
acl_names=Kan ändra server namn?
|
||||
acl_dirs=Apache direktiv tillgängliga<br><font size=-1> (Ämnen av typ begränsning under) </font>
|
||||
acl_dirs=Tillgängliga Apache-direktiv, begränsade av de direktivtyper som valts ovan
|
||||
acl_dirs0=Alla
|
||||
acl_dirs1=Endast listade ..
|
||||
acl_dirs2=Alla utom listade ..
|
||||
|
||||
@@ -134,7 +134,7 @@ acl_defserv=Varsayılan Sunucu
|
||||
acl_apply=Değişiklikler uygulayabilir mi?
|
||||
acl_aliasdir=Diğer adları dizine sınırla
|
||||
acl_names=Sunucu adlarını düzenleyebilir mi?
|
||||
acl_dirs=Apache yönergeleri mevcut <br><font size=-1> (Yukarıdaki tür sınırlamasına tabidir) </font>
|
||||
acl_dirs=Kullanılabilir Apache yönergeleri, yukarıda seçilen yönerge türleriyle sınırlıdır
|
||||
acl_dirs0=Herşey
|
||||
acl_dirs1=Sadece listelenmiş ..
|
||||
acl_dirs2=Listelenenler hariç tümü ..
|
||||
|
||||
@@ -54,7 +54,7 @@ restart_ecannot=Вам заборонено застосовувати змін
|
||||
acl_apply=Чи можна застосувати зміни?
|
||||
acl_aliasdir=Обмежте псевдоніми до каталогу
|
||||
acl_names=Чи можна редагувати імена серверів?
|
||||
acl_dirs=Доступні директиви Apache <br><font size=-1> (За умови обмеження типів вище) </font>
|
||||
acl_dirs=Доступні директиви Apache, обмежені вибраними вище типами директив
|
||||
acl_dirs0=Усі
|
||||
acl_dirs1=Тільки перераховані ..
|
||||
acl_dirs2=Усі, крім перерахованих ..
|
||||
|
||||
@@ -331,7 +331,7 @@ acl_types=可用的指令类型
|
||||
acl_all=全部
|
||||
acl_sel=选择的…
|
||||
acl_names=是否编辑服务器名称吗
|
||||
acl_dirs=Apache指令可用<br><font size=-1>(受上述类型限制)</font>
|
||||
acl_dirs=可用的 Apache 指令,受上方所选指令类型限制
|
||||
acl_dirs0=全部
|
||||
acl_dirs1=仅列出 ..
|
||||
acl_dirs2=除列出外的所有内容 ..
|
||||
|
||||
@@ -39,7 +39,7 @@ start_eafter=Apache似乎沒有運行
|
||||
|
||||
acl_aliasdir=將別名限制為目錄
|
||||
acl_names=可以編輯服務器名稱嗎?
|
||||
acl_dirs=可用的Apache指令<br><font size=-1>(受上述類型限制)</font>
|
||||
acl_dirs=可用的 Apache 指令,受上方所選指令類型限制
|
||||
acl_dirs0=所有
|
||||
acl_dirs1=只列出 ..
|
||||
acl_dirs2=除了列出的所有 ..
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
sub mod_access_directives
|
||||
{
|
||||
local($rv);
|
||||
$rv = [ [ 'allow deny order', 1, 4, 'directory htaccess' ] ];
|
||||
$rv = [ [ 'allow deny order', 1, 4, 'directory htaccess', '-2.0' ] ];
|
||||
return &make_directives($rv, $_[0], "mod_access");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
sub mod_auth_digest_directives
|
||||
{
|
||||
local($rv);
|
||||
$rv = [ [ 'AuthDigestAuthoritative', 0, 4, 'directory htaccess' ],
|
||||
$rv = [ [ 'AuthDigestAuthoritative', 0, 4, 'directory htaccess', '-2.4' ],
|
||||
[ 'AuthDigestProvider', 0, 4, 'directory htaccess' ],
|
||||
[ 'AuthDigestAlgorithm', 0, 4, 'directory htaccess' ],
|
||||
];
|
||||
@@ -38,9 +38,11 @@ return ( $p ? [ join(" ", split(/\0/, $p)) ] : [ ] );
|
||||
|
||||
sub edit_AuthDigestAlgorithm
|
||||
{
|
||||
# MD5-sess is not correctly implemented yet!
|
||||
# https://httpd.apache.org/docs/2.4/mod/mod_auth_digest.html#authdigestalgorithm
|
||||
return (1, $text{'mod_auth_digest_al'},
|
||||
&choice_input($_[0]->{'value'}, "AuthDigestAlgorithm", "",
|
||||
"MD5", "MD5-sess", "$text{'default'},") );
|
||||
"MD5,MD5", "MD5-sess,MD5-sess", "$text{'default'},") );
|
||||
}
|
||||
sub save_AuthDigestAlgorithm
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user