mirror of
https://github.com/webmin/webmin.git
synced 2026-08-21 22:40:41 +01:00
Compare commits
1148 Commits
2.401
...
dev/req-tr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
463fcea730 | ||
|
|
a94ff2c49a | ||
|
|
ec78452e7b | ||
|
|
a7325b9087 | ||
|
|
cc4bb35dee | ||
|
|
aa2282778e | ||
|
|
1c9d57f5dd | ||
|
|
4ffa02d636 | ||
|
|
57ad5fa535 | ||
|
|
a3f5ea3381 | ||
|
|
2579cf54d9 | ||
|
|
fa06c02be5 | ||
|
|
d02f0b6cb5 | ||
|
|
81d44f8491 | ||
|
|
6135c01d57 | ||
|
|
5aa69015f6 | ||
|
|
061a4ae0d3 | ||
|
|
031a8b8261 | ||
|
|
18296d3a55 | ||
|
|
18bf94af6a | ||
|
|
d2f9e339f2 | ||
|
|
1a2046b1e3 | ||
|
|
db8e34e528 | ||
|
|
6a1200bc03 | ||
|
|
c94ddc5ec8 | ||
|
|
0290ec16a5 | ||
|
|
41b476c87a | ||
|
|
7a68b1b994 | ||
|
|
0dbb5d2f89 | ||
|
|
27dcd2db4a | ||
|
|
147e53e5db | ||
|
|
a970bce5a5 | ||
|
|
d1d1bad4ae | ||
|
|
7878ef466f | ||
|
|
14c8d9b61e | ||
|
|
fa09b191b9 | ||
|
|
c72d232e2f | ||
|
|
6091f08e37 | ||
|
|
d42a6dc725 | ||
|
|
fac6b478b5 | ||
|
|
a0b67db65b | ||
|
|
26311baab9 | ||
|
|
7ba1a39271 | ||
|
|
45ca170c20 | ||
|
|
4064f0675c | ||
|
|
886352c6e8 | ||
|
|
f2fe6c930f | ||
|
|
762e400156 | ||
|
|
f5bf2be07b | ||
|
|
57d650cf9f | ||
|
|
859169bbae | ||
|
|
3f48d37e7a | ||
|
|
d3be11911e | ||
|
|
65f5beeb11 | ||
|
|
8ba6a02122 | ||
|
|
74fd072551 | ||
|
|
b75a95dd42 | ||
|
|
8c631bceeb | ||
|
|
0cf6654fd9 | ||
|
|
c08468ec48 | ||
|
|
cb4a322042 | ||
|
|
f2782073ce | ||
|
|
090aed60df | ||
|
|
b53ca5b618 | ||
|
|
7ebe3f7dfa | ||
|
|
fc546e1e65 | ||
|
|
29c14acf98 | ||
|
|
ea02aeb04a | ||
|
|
d306a63744 | ||
|
|
a9c6fe724a | ||
|
|
7fd89fb350 | ||
|
|
ccd2b13942 | ||
|
|
74bd78ae35 | ||
|
|
74fd0ca12d | ||
|
|
8157ff60d2 | ||
|
|
104b353476 | ||
|
|
bd051635fb | ||
|
|
8574c70d6b | ||
|
|
845f4a40e4 | ||
|
|
b97756b9fb | ||
|
|
8cca3a117f | ||
|
|
e580dcdd40 | ||
|
|
f4b121c059 | ||
|
|
25fea8f568 | ||
|
|
69548c4bb8 | ||
|
|
29f35302ae | ||
|
|
baad7081d3 | ||
|
|
7105021e80 | ||
|
|
30fb29a300 | ||
|
|
a1c88df428 | ||
|
|
cbebe22a14 | ||
|
|
5f72e2e97e | ||
|
|
9fb08dd8f0 | ||
|
|
13a1021661 | ||
|
|
4add8b2e0f | ||
|
|
7884e5f413 | ||
|
|
2187f96d21 | ||
|
|
899c8e270e | ||
|
|
3d26bc80b7 | ||
|
|
841c3e0442 | ||
|
|
5577c1d50f | ||
|
|
e62ee2bb4d | ||
|
|
2007354f27 | ||
|
|
bf397eac7b | ||
|
|
3325cc717e | ||
|
|
305b228c0e | ||
|
|
7ca3819d2b | ||
|
|
162a103c45 | ||
|
|
605e575908 | ||
|
|
1445cd7641 | ||
|
|
5b0b6fbf1f | ||
|
|
de57c42f4a | ||
|
|
ce998ac478 | ||
|
|
f65554cec1 | ||
|
|
8953add81e | ||
|
|
630de14410 | ||
|
|
804591f892 | ||
|
|
a56748a3fc | ||
|
|
854b8e8c2b | ||
|
|
b0fbe87592 | ||
|
|
bf722a658d | ||
|
|
02bdfc20db | ||
|
|
7d6af20741 | ||
|
|
ebbbf7cecb | ||
|
|
da12554998 | ||
|
|
84943943fc | ||
|
|
8dd06e3c34 | ||
|
|
8f8199a4bf | ||
|
|
53c3ee1c5d | ||
|
|
d94000afbd | ||
|
|
ed5bc3e4b6 | ||
|
|
2024a48acf | ||
|
|
db38923b20 | ||
|
|
0d4c65ec04 | ||
|
|
3215c0d0a3 | ||
|
|
c11d67d989 | ||
|
|
6457a1d7d1 | ||
|
|
91c9f6b4ce | ||
|
|
ad06644617 | ||
|
|
d788bbe9c2 | ||
|
|
9577737aeb | ||
|
|
ee50fa41cd | ||
|
|
80497c60b9 | ||
|
|
6026a20424 | ||
|
|
501bddabc8 | ||
|
|
e434d0b138 | ||
|
|
42a5838d9e | ||
|
|
e10b9eeb40 | ||
|
|
1e5f3dbb83 | ||
|
|
e8a3d9d21b | ||
|
|
4e6204f774 | ||
|
|
95197bb0af | ||
|
|
80da8d1915 | ||
|
|
f7b8ef379f | ||
|
|
758aa4a9f7 | ||
|
|
b2dc27c063 | ||
|
|
8dfee31542 | ||
|
|
a113309310 | ||
|
|
6574373761 | ||
|
|
b33b9fb0a0 | ||
|
|
8ef12b66d7 | ||
|
|
8df083b054 | ||
|
|
435d2db4c6 | ||
|
|
57b1ae3b18 | ||
|
|
1eb4eb85a7 | ||
|
|
fd79acd840 | ||
|
|
034d0a09ce | ||
|
|
184887d365 | ||
|
|
111dcb5f21 | ||
|
|
7cf7d14f53 | ||
|
|
c68d03b211 | ||
|
|
35a7459950 | ||
|
|
5a9d2a2ca5 | ||
|
|
3bc901fcb1 | ||
|
|
8d09b0724c | ||
|
|
7e8366bcb8 | ||
|
|
1335d05f7c | ||
|
|
010f15c2a5 | ||
|
|
e10acfa3bb | ||
|
|
440ddabef1 | ||
|
|
5232c07332 | ||
|
|
53d0d053cf | ||
|
|
1d369dcddf | ||
|
|
270e26172b | ||
|
|
523d68c67a | ||
|
|
04efe99340 | ||
|
|
5b58330071 | ||
|
|
292d0d5a1f | ||
|
|
c9ce2ed6d8 | ||
|
|
9b404f8feb | ||
|
|
197df80055 | ||
|
|
6f4f85d33c | ||
|
|
73821b72b0 | ||
|
|
2d21c31ce2 | ||
|
|
afffe48e01 | ||
|
|
3ea7135cb2 | ||
|
|
e6eb1c4983 | ||
|
|
3780c1a9b5 | ||
|
|
675c830e84 | ||
|
|
74393cd312 | ||
|
|
09bdd71c8c | ||
|
|
1e77343482 | ||
|
|
4b33d8bc3f | ||
|
|
4bb0cda0b5 | ||
|
|
87536b42a1 | ||
|
|
1a7a28f192 | ||
|
|
91958ee2c0 | ||
|
|
eb779294fd | ||
|
|
b9766d97a6 | ||
|
|
d8449b9417 | ||
|
|
ad890156fa | ||
|
|
6c74264916 | ||
|
|
ad3ddc489f | ||
|
|
87db158afc | ||
|
|
752d43adb8 | ||
|
|
76833b9e68 | ||
|
|
140e4121b1 | ||
|
|
9de7560728 | ||
|
|
ed75034c98 | ||
|
|
70cb2a700f | ||
|
|
a24c79bb9f | ||
|
|
685c07ffbb | ||
|
|
2c4467a82e | ||
|
|
65c2a0da50 | ||
|
|
da2090bad7 | ||
|
|
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 | ||
|
|
d2b4fa89c5 | ||
|
|
3a3b202a96 | ||
|
|
30f08f73fb | ||
|
|
e499b5b3a5 | ||
|
|
443cf449eb | ||
|
|
58d6308589 | ||
|
|
02ed8e8fbd | ||
|
|
3a0dea1d2c | ||
|
|
916d22b55b | ||
|
|
1f1a7e4562 | ||
|
|
ac68a0be0c | ||
|
|
263cc142a6 | ||
|
|
19fdea395b | ||
|
|
40f82d0df3 | ||
|
|
39ab2c5f02 | ||
|
|
f39a59bdce | ||
|
|
a4846f5f32 | ||
|
|
5558910722 | ||
|
|
bebd99d656 | ||
|
|
bad0d2f821 | ||
|
|
4797852f6f | ||
|
|
d467810076 | ||
|
|
6d1ec1a3e1 | ||
|
|
82ea895c81 | ||
|
|
36e699eb29 | ||
|
|
04e8df863a | ||
|
|
96c2312349 | ||
|
|
1d594e82f0 | ||
|
|
cbd96a4176 | ||
|
|
ed17ade510 | ||
|
|
dc63aa22a5 | ||
|
|
1b9b9ae21f | ||
|
|
f1d580de1b | ||
|
|
f0b9152ae5 | ||
|
|
5862cde30f | ||
|
|
2de16faafc | ||
|
|
098544473f | ||
|
|
2c82255179 | ||
|
|
fe5cf97cef | ||
|
|
01d650ca06 | ||
|
|
e19dca6882 | ||
|
|
3934ae3e73 | ||
|
|
1a0aa44dba | ||
|
|
2c211e557e | ||
|
|
b3ec013fc9 | ||
|
|
b8481cc1e5 | ||
|
|
c0900ffaf8 | ||
|
|
302f635651 | ||
|
|
d5feb72572 | ||
|
|
cd7f867c09 | ||
|
|
16245144eb | ||
|
|
083b4c7826 | ||
|
|
019cc10b79 | ||
|
|
5d860a6728 | ||
|
|
2e4ec03670 | ||
|
|
b4984e495d | ||
|
|
d7434c61a2 | ||
|
|
f204480957 | ||
|
|
04f1426f33 | ||
|
|
f10385417c | ||
|
|
a502eff346 | ||
|
|
a3416dc830 | ||
|
|
3354a0cc2f | ||
|
|
2a7806be31 | ||
|
|
d4850c3aa3 | ||
|
|
7cbe00ade2 | ||
|
|
540181ae22 | ||
|
|
38cae2fae2 | ||
|
|
9a14c437b8 | ||
|
|
bd3fd5d49b | ||
|
|
fb9f7ead7c | ||
|
|
92ac52893e | ||
|
|
2397653d55 | ||
|
|
209a2cbbc3 | ||
|
|
29c2c6f59d | ||
|
|
c89dc4996f | ||
|
|
bfc1f10b38 | ||
|
|
56a1c323c8 | ||
|
|
f7384bbf05 | ||
|
|
9cd60f4741 | ||
|
|
f778af84a0 | ||
|
|
2eb2be2318 | ||
|
|
38352f5c01 | ||
|
|
07a11f7de6 | ||
|
|
8b76f2ffc8 | ||
|
|
6d014e31cb | ||
|
|
3b05ce756d | ||
|
|
7f322a5df6 | ||
|
|
c47047953b | ||
|
|
f30560d61b | ||
|
|
e13123bed1 | ||
|
|
821548354d | ||
|
|
3a1ea4682d | ||
|
|
3713ee01b8 | ||
|
|
de87e037d4 | ||
|
|
e805f95b48 | ||
|
|
b782a124b5 | ||
|
|
c85d04cc74 | ||
|
|
a6bd5c6ebc | ||
|
|
9fd37b7404 | ||
|
|
ac9456b368 | ||
|
|
399d7a8651 | ||
|
|
c87712ef4e | ||
|
|
c47b63bfcf | ||
|
|
3a86d961ce | ||
|
|
402b21abac | ||
|
|
0816c0a71e | ||
|
|
a38114e623 | ||
|
|
a655f875cf | ||
|
|
79b5b307ed | ||
|
|
5a3b0cfd2d | ||
|
|
fa32009fbb | ||
|
|
a9f4fdc8ca | ||
|
|
b593501cff | ||
|
|
107a2e42f4 | ||
|
|
3572049284 | ||
|
|
d9be1b956f | ||
|
|
b2f54c36ca | ||
|
|
cbc96170c4 | ||
|
|
9d01f3cd9e | ||
|
|
ca7c57b181 | ||
|
|
a1091556db | ||
|
|
48269733b1 | ||
|
|
9145c23126 | ||
|
|
4368e00250 | ||
|
|
31d4b6dfd6 | ||
|
|
859580a224 | ||
|
|
163dd04175 | ||
|
|
3f96fb8adb | ||
|
|
30b2e8b6d4 | ||
|
|
8242714b99 | ||
|
|
179ddf751b | ||
|
|
63fd68b2f9 | ||
|
|
8402db53d5 | ||
|
|
e92fc730ee | ||
|
|
d546116ab7 | ||
|
|
736c320a60 | ||
|
|
0ecbb04e00 | ||
|
|
2dfa6cfc1b | ||
|
|
4f438906d2 | ||
|
|
c8fcde9579 | ||
|
|
e6184a0036 | ||
|
|
54bb3ee293 | ||
|
|
bfb496ca29 | ||
|
|
58c9efd7ea | ||
|
|
534c529705 | ||
|
|
2d0063129c | ||
|
|
ad37eabdfe | ||
|
|
6d3da61b95 | ||
|
|
4d05e8a2d0 | ||
|
|
e8e804ddca | ||
|
|
202a1b0b78 | ||
|
|
3c1c327530 | ||
|
|
2d7900d550 | ||
|
|
032f4447db | ||
|
|
e9586fb2d8 | ||
|
|
0d70782330 | ||
|
|
9d95b5c977 | ||
|
|
d9c651d06d | ||
|
|
c70bae48aa | ||
|
|
d89f1ee1de | ||
|
|
83abdc8858 | ||
|
|
2833450b48 | ||
|
|
a0c023637f | ||
|
|
6721e13a6b | ||
|
|
2b2814fdf4 | ||
|
|
4dacdc31f6 | ||
|
|
2627ba289e | ||
|
|
b4a67a0d90 | ||
|
|
63af275296 | ||
|
|
5f1bbc4ac2 | ||
|
|
124147205f | ||
|
|
e9b3ed9624 | ||
|
|
ccde77c0e2 | ||
|
|
ffd8171e18 | ||
|
|
65ab502176 | ||
|
|
013aa5a5c6 | ||
|
|
12dca80535 | ||
|
|
89ee635de3 | ||
|
|
af3ddd652f | ||
|
|
e6d214b776 | ||
|
|
45521e9c30 | ||
|
|
123beb03d8 | ||
|
|
72b122dbce | ||
|
|
e9be9b1d53 | ||
|
|
7beeea2106 | ||
|
|
27c5ad998e | ||
|
|
474ca81d4a | ||
|
|
a63c92f77c | ||
|
|
db96a9fd09 | ||
|
|
198cc1c4d8 | ||
|
|
4f681a2db0 | ||
|
|
ab46ec806f | ||
|
|
b1fe988f57 | ||
|
|
94c0826499 | ||
|
|
191d8a255c | ||
|
|
d4ab826097 | ||
|
|
a84c2af1d8 | ||
|
|
476915850a | ||
|
|
2510b985b1 | ||
|
|
db4f5b5e9c | ||
|
|
f3dda46138 | ||
|
|
7a278ad894 | ||
|
|
179d36859a | ||
|
|
eec14b6c1f | ||
|
|
bc44562637 | ||
|
|
a55a9e142b | ||
|
|
7911eaeae1 | ||
|
|
a2cb8daaee | ||
|
|
c4dc034da7 | ||
|
|
8a8d1bc12f | ||
|
|
025ab50ecb | ||
|
|
1f71aebe49 | ||
|
|
03379b0052 | ||
|
|
86a27eff18 | ||
|
|
b338875039 | ||
|
|
e88d16a888 | ||
|
|
f0486443ae | ||
|
|
f55515fdb0 | ||
|
|
ebefe283fd | ||
|
|
d7c49a51c7 | ||
|
|
018ad0062b | ||
|
|
50075dd71d | ||
|
|
f4e573278d | ||
|
|
9bce05f48a | ||
|
|
238756902b | ||
|
|
b597bfb0bd | ||
|
|
00adb84d69 | ||
|
|
0cf0af85cd | ||
|
|
ae89844754 | ||
|
|
9ba627e461 | ||
|
|
bae6e39889 | ||
|
|
5377098de3 | ||
|
|
48291845b4 | ||
|
|
36194ade8e | ||
|
|
d8e9ad116a | ||
|
|
4c5911887c | ||
|
|
392d3aceff | ||
|
|
15a3c91f9d | ||
|
|
58c6d41295 | ||
|
|
7b9bca5b67 | ||
|
|
ba47e2a0d0 | ||
|
|
3b06c4dccb | ||
|
|
1e6611ade5 | ||
|
|
dfa5ac8b21 | ||
|
|
d7cf050d71 | ||
|
|
7945a9f0e6 | ||
|
|
6cd04c131c | ||
|
|
9f4a4fadf7 | ||
|
|
70c7ddf3bb | ||
|
|
17764483dc | ||
|
|
cdc1c82e83 | ||
|
|
d29e5aea99 | ||
|
|
c3a2396986 | ||
|
|
da37f364dd | ||
|
|
0342f06fc8 | ||
|
|
ef05252413 | ||
|
|
74f879dc2b | ||
|
|
94cbabea9e | ||
|
|
2634afb859 | ||
|
|
4bf296447e | ||
|
|
cf458db765 | ||
|
|
af7cb99298 | ||
|
|
3d300b5fb6 | ||
|
|
8ff9b75953 | ||
|
|
06f75db35f | ||
|
|
4f851d71b1 | ||
|
|
2133d5d4bf | ||
|
|
42e5d45232 | ||
|
|
3e0a08b7ef | ||
|
|
f2f40f1227 | ||
|
|
0955695a15 | ||
|
|
fb3dd9f43d | ||
|
|
9f82fdc808 | ||
|
|
573f3d894a | ||
|
|
ff9348c056 | ||
|
|
2051bfe6dc | ||
|
|
42e228103b | ||
|
|
29d100e8eb | ||
|
|
4e4234c87e | ||
|
|
6d9aa69cb2 | ||
|
|
dbc83bae55 | ||
|
|
d37b790492 | ||
|
|
34616c5fbd | ||
|
|
c57651cd46 | ||
|
|
79f91c1468 | ||
|
|
f49f86dc96 | ||
|
|
ef1e9bbf93 | ||
|
|
84348e3fc4 | ||
|
|
1a52bf4d72 | ||
|
|
d8a74cd275 | ||
|
|
225def99ec | ||
|
|
1c9e8b5a25 | ||
|
|
e0e5ef65f8 | ||
|
|
5d67cdb7c1 | ||
|
|
c7538bc5be | ||
|
|
7959bedfe4 | ||
|
|
4c6511f2c1 | ||
|
|
42c8b02b3b | ||
|
|
fd25d65afe | ||
|
|
ae684ff02c | ||
|
|
37f1b52391 | ||
|
|
067b3e59b0 | ||
|
|
8e0c6ffb14 | ||
|
|
34a2cdd75d | ||
|
|
25b3f95d9c | ||
|
|
5d8196fe95 | ||
|
|
7f93d6ddd8 | ||
|
|
5ed06227a8 | ||
|
|
0576b027c0 | ||
|
|
31e2f533f6 | ||
|
|
51eef83562 | ||
|
|
efcfd3d20e | ||
|
|
4857976e26 | ||
|
|
3633469b4e | ||
|
|
f9373eacc2 | ||
|
|
5ed99dd7eb | ||
|
|
e7cf393f85 | ||
|
|
f5c158ef6a | ||
|
|
5b71274aa1 | ||
|
|
410cdbd01b | ||
|
|
34263aae1f | ||
|
|
3f8f9539a2 | ||
|
|
cb5f4e9d39 | ||
|
|
2acfc37745 | ||
|
|
ffe844d03d | ||
|
|
12edb92b6a | ||
|
|
8517ee6653 | ||
|
|
447727ae68 | ||
|
|
28ea58af07 | ||
|
|
48c5fc2138 | ||
|
|
b9e3363a68 | ||
|
|
f0f4f72d73 | ||
|
|
9a493e581e | ||
|
|
360236d68b | ||
|
|
7e5007e050 | ||
|
|
dfbf446092 | ||
|
|
178c6198f2 | ||
|
|
198e395833 | ||
|
|
4443982256 | ||
|
|
8866833130 | ||
|
|
b1d407a52d | ||
|
|
a7478ac4c9 | ||
|
|
8957333dca | ||
|
|
1caf80bbc1 | ||
|
|
18c12c7f8b | ||
|
|
78a3ab924d | ||
|
|
652f2db774 | ||
|
|
8b58d7cce3 | ||
|
|
52f87286a4 | ||
|
|
28c7939636 | ||
|
|
face8319f2 | ||
|
|
7a651027bf | ||
|
|
bbf317803a | ||
|
|
d694649872 | ||
|
|
1091434ff4 | ||
|
|
991795c296 | ||
|
|
8932f3bd6a | ||
|
|
b3ec083c7b | ||
|
|
da18dea780 | ||
|
|
35f8061049 | ||
|
|
e6e79a7eb5 | ||
|
|
a4d1280ef7 | ||
|
|
cc2cc62717 | ||
|
|
c59591e3de | ||
|
|
fc4e2751dc | ||
|
|
4dc64f5028 | ||
|
|
01d2323496 | ||
|
|
4c8b0fe008 | ||
|
|
e44ec464eb | ||
|
|
98c54fe3fb | ||
|
|
86968bfc31 | ||
|
|
956ad7ed0f | ||
|
|
a0d99e0a31 | ||
|
|
f27b1415be | ||
|
|
1f4b467ea8 | ||
|
|
95423c7425 | ||
|
|
89d23c5aa8 | ||
|
|
be3fcb89b0 | ||
|
|
25fa7c589d | ||
|
|
c86c45b10a | ||
|
|
f10540bd54 | ||
|
|
388f51843f | ||
|
|
7a723719da | ||
|
|
a027ad5dd6 | ||
|
|
d99a24b045 | ||
|
|
f08ad4eb19 | ||
|
|
df97b4a419 | ||
|
|
1ef0914610 | ||
|
|
97678653c6 | ||
|
|
3717dfb505 | ||
|
|
e5d6c5627d | ||
|
|
e194e2d500 | ||
|
|
d5a22a592f | ||
|
|
890a4ffd3f | ||
|
|
4e229d8adb | ||
|
|
d1ee0a5ed6 | ||
|
|
cd489ccefc | ||
|
|
55b5739287 | ||
|
|
adf36a177d | ||
|
|
9393162b0e | ||
|
|
287fb3cb81 | ||
|
|
61b2603e06 | ||
|
|
eb02824bfc | ||
|
|
6191a222ae | ||
|
|
2ac82016aa | ||
|
|
8f987d21a9 | ||
|
|
e88a77d32a | ||
|
|
5231b31ddd | ||
|
|
5c5d5fe699 | ||
|
|
34fba22799 | ||
|
|
a708e5f6e9 | ||
|
|
f7058f10b4 | ||
|
|
a4df380e2e | ||
|
|
70d1c843fc | ||
|
|
1b38d806fc | ||
|
|
f8d7e8810a | ||
|
|
43d5355114 | ||
|
|
87d39127ef | ||
|
|
825d54adc4 | ||
|
|
cbaff19725 | ||
|
|
ece2ff6a1e | ||
|
|
6b71562abf | ||
|
|
a73210adc9 | ||
|
|
c6d9d0338f | ||
|
|
5066534a40 | ||
|
|
84a417bd6e | ||
|
|
90c31af379 | ||
|
|
1453508592 | ||
|
|
35455f04e6 | ||
|
|
220d3124ef | ||
|
|
8b88034335 | ||
|
|
e5bff8f31b | ||
|
|
ba4e72dfc2 | ||
|
|
45eaad6eff | ||
|
|
cd113a468a | ||
|
|
4c6ffd19a4 | ||
|
|
92e71e9ba3 | ||
|
|
e56ea150fe | ||
|
|
e191220178 | ||
|
|
097ef22bbc | ||
|
|
66be8e9c20 | ||
|
|
cf6b79b740 | ||
|
|
81aa781bc9 | ||
|
|
69b707e945 | ||
|
|
1424e248ff | ||
|
|
249dabde7e | ||
|
|
443883d364 | ||
|
|
156cb80104 | ||
|
|
0885a17f55 | ||
|
|
0ffaed090a | ||
|
|
55013abadc | ||
|
|
83a85aed93 | ||
|
|
81b0bee9ee | ||
|
|
b53504dd01 | ||
|
|
c2c99e3305 | ||
|
|
671c62289d | ||
|
|
d296b83192 | ||
|
|
1d898d83fb | ||
|
|
90fa7fede0 | ||
|
|
415e7116f9 | ||
|
|
033d94483f | ||
|
|
69035e0a34 | ||
|
|
bab8d7a0f0 | ||
|
|
9e6ae753e0 | ||
|
|
42b6cac7b4 | ||
|
|
6ca908cf80 | ||
|
|
3be8a327ad | ||
|
|
16110e3e3e | ||
|
|
8f508724e4 | ||
|
|
e2646af3ab | ||
|
|
ef55f007a4 | ||
|
|
613b9e5ffa | ||
|
|
06744537d6 | ||
|
|
3925dd829b | ||
|
|
e5bff72e57 | ||
|
|
dd445a67f1 | ||
|
|
29a4b6b598 | ||
|
|
56729f7e3d | ||
|
|
92b90a8170 | ||
|
|
783ad6f3a2 | ||
|
|
0fd02d4381 | ||
|
|
4c2fde6847 | ||
|
|
9065de316a | ||
|
|
679a1c386e | ||
|
|
462483b667 | ||
|
|
58467ece0b | ||
|
|
e864fa785f | ||
|
|
5aba173111 | ||
|
|
9305ddbdd5 | ||
|
|
08d990ab13 | ||
|
|
ecbeaf7bc7 | ||
|
|
f8cb0db802 | ||
|
|
77b134fec1 | ||
|
|
060a2f2853 | ||
|
|
88c71b5dd4 | ||
|
|
f99f5fbae6 | ||
|
|
2037af9d25 | ||
|
|
d8988bd9f0 | ||
|
|
5ee080d24a | ||
|
|
54bb5eac1e | ||
|
|
10790ccc7f | ||
|
|
820453cc8c | ||
|
|
3d2ea49a47 | ||
|
|
69681c01d4 | ||
|
|
fe8545703d | ||
|
|
f130112177 | ||
|
|
c32b04a7e6 | ||
|
|
afa9e9bd38 | ||
|
|
73d6333f19 | ||
|
|
549c786b84 | ||
|
|
e15ab46a98 | ||
|
|
63abfbfe87 | ||
|
|
da5b814d2b | ||
|
|
187b7c72a8 | ||
|
|
a08d104f82 | ||
|
|
71f441375b | ||
|
|
53fb520392 | ||
|
|
f5305eb065 | ||
|
|
cd51f76062 | ||
|
|
147a10dd8a | ||
|
|
f17f92c5c0 | ||
|
|
69b9756b4a | ||
|
|
6935174133 | ||
|
|
76efb4ee10 | ||
|
|
ed42dd5822 | ||
|
|
51c86d41d4 | ||
|
|
d8166e9a8e | ||
|
|
0a0ad2f119 | ||
|
|
137af3637b | ||
|
|
d2863b7c4c | ||
|
|
0f721a17ae | ||
|
|
72014ab2d7 | ||
|
|
2d86d8c77a | ||
|
|
0bcbcd94b8 | ||
|
|
f353ae31d8 | ||
|
|
24cd121642 | ||
|
|
11de78ce51 | ||
|
|
6b75672534 | ||
|
|
c0f886b670 | ||
|
|
784b2b42e7 | ||
|
|
9dc877910f | ||
|
|
a65f9f5d6c | ||
|
|
4d417ea4bf | ||
|
|
2e245a1035 | ||
|
|
049542b7ed | ||
|
|
780cc982b7 | ||
|
|
848422d256 | ||
|
|
f1e96e3097 | ||
|
|
90f4265389 | ||
|
|
37f9ce4bb4 | ||
|
|
ceb3e583a3 | ||
|
|
436d6f70bb | ||
|
|
72621c2929 | ||
|
|
af07c6c9d9 | ||
|
|
740f5b9d49 | ||
|
|
cb1368f07c | ||
|
|
755325f9a5 | ||
|
|
dd914c7ecf | ||
|
|
489583708e | ||
|
|
58580b7f4b | ||
|
|
d9a120c760 | ||
|
|
fb832eff82 | ||
|
|
75b0a6f7bb | ||
|
|
40707d8602 | ||
|
|
ac45266ee4 | ||
|
|
522aeb5264 | ||
|
|
1d24db1686 | ||
|
|
527043b54d | ||
|
|
56b62346b4 | ||
|
|
ee39f99d23 | ||
|
|
a223243db4 | ||
|
|
b59bdc4f1a | ||
|
|
d087f9f024 | ||
|
|
1607a59239 | ||
|
|
70589cf88a | ||
|
|
c429fbb202 | ||
|
|
f24375e13a | ||
|
|
d428f4d4c1 | ||
|
|
f0e07518c9 | ||
|
|
29709c3c51 | ||
|
|
fb71fbd5ae | ||
|
|
a1f06c5548 | ||
|
|
10e8a420c0 | ||
|
|
8149eef10a | ||
|
|
c4b98ef376 | ||
|
|
621d5c22bc | ||
|
|
98000bb007 | ||
|
|
d90a33bb0c | ||
|
|
d795fc7d60 | ||
|
|
b397ece0ab | ||
|
|
0a11f182b0 | ||
|
|
7c05368e8f | ||
|
|
49ceeebbf8 | ||
|
|
01867c86e0 | ||
|
|
008890dfa1 | ||
|
|
5d846e80b2 | ||
|
|
ce6bbe44ff | ||
|
|
3bc15788af | ||
|
|
faa5dddb0a | ||
|
|
55d03d426a | ||
|
|
da9aa22fa7 | ||
|
|
06ce137903 | ||
|
|
5462c3bbf8 | ||
|
|
bae4af7490 | ||
|
|
bfd2bfbc11 | ||
|
|
8de7fde8bb | ||
|
|
e5e8cde28e | ||
|
|
09d0b26aea | ||
|
|
87ba4dd181 | ||
|
|
282b28da5e | ||
|
|
d519c4099f | ||
|
|
0be73ac433 | ||
|
|
b0c029887f | ||
|
|
ce16f80848 | ||
|
|
cc407bc1c3 | ||
|
|
8e5633d9af | ||
|
|
76bf648f94 |
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# EditorConfig for Perl project
|
||||||
|
# - Indentation: tabs
|
||||||
|
# - Tab width: 8
|
||||||
|
# - Indentation style: Ratliff
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
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
|
||||||
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
|
||||||
13
.github/workflows/webmin.dev+webmin.yml
vendored
13
.github/workflows/webmin.dev+webmin.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: "webmin.dev: webmin/webmin"
|
name: Package and upload artifacts
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@@ -6,21 +6,24 @@ on:
|
|||||||
- master
|
- master
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
- published
|
- prereleased
|
||||||
|
- released
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
uses: webmin/webmin-ci-cd/.github/workflows/master-workflow.yml@main
|
uses: webmin/webmin-ci-cd/.github/workflows/master-workflow.yml@main
|
||||||
with:
|
with:
|
||||||
build-type: package
|
build-type: package
|
||||||
project-name: webmin
|
project-name: ${{ github.event.repository.name }}
|
||||||
is-release: ${{ github.event_name == 'release' }}
|
is-release: ${{ github.event_name == 'release' }}
|
||||||
|
is-prerelease: ${{ github.event.release.prerelease || false }}
|
||||||
secrets:
|
secrets:
|
||||||
DEV_GPG_PH: ${{ secrets.DEV_GPG_PH }}
|
|
||||||
DEV_IP_ADDR: ${{ secrets.DEV_IP_ADDR }}
|
DEV_IP_ADDR: ${{ secrets.DEV_IP_ADDR }}
|
||||||
DEV_IP_KNOWN_HOSTS: ${{ secrets.DEV_IP_KNOWN_HOSTS }}
|
DEV_IP_KNOWN_HOSTS: ${{ secrets.DEV_IP_KNOWN_HOSTS }}
|
||||||
DEV_UPLOAD_SSH_USER: ${{ secrets.DEV_UPLOAD_SSH_USER }}
|
DEV_UPLOAD_SSH_USER: ${{ secrets.DEV_UPLOAD_SSH_USER }}
|
||||||
DEV_UPLOAD_SSH_DIR: ${{ secrets.DEV_UPLOAD_SSH_DIR }}
|
DEV_UPLOAD_SSH_DIR: ${{ secrets.DEV_UPLOAD_SSH_DIR }}
|
||||||
PRERELEASE_UPLOAD_SSH_DIR: ${{ secrets.PRERELEASE_UPLOAD_SSH_DIR }}
|
PRERELEASE_UPLOAD_SSH_DIR: ${{ secrets.PRERELEASE_UPLOAD_SSH_DIR }}
|
||||||
DEV_SSH_PRV_KEY: ${{ secrets.DEV_SSH_PRV_KEY }}
|
DEV_SSH_PRV_KEY: ${{ secrets.DEV_SSH_PRV_KEY }}
|
||||||
DEV_SIGN_BUILD_REPOS_CMD: ${{ secrets.DEV_SIGN_BUILD_REPOS_CMD }}
|
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/
|
minimal/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.vscode/settings.json
|
.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]
|
||||||
268
CHANGELOG.md
268
CHANGELOG.md
@@ -1,5 +1,250 @@
|
|||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
|
#### 2.652 (July, 2026)
|
||||||
|
* Fix to recognize hex numeric HTML entities to work in various elements
|
||||||
|
|
||||||
|
#### 2.651 (June 28, 2026)
|
||||||
|
* Fix Certbot-backed certificate requests and renewals to correctly parse PEM paths after issuance
|
||||||
|
* Fix live activation of Linux bond interfaces [#2777](https://github.com/webmin/webmin/pull/2777)
|
||||||
|
* Update the Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
- Fix search-result all-items delete in File Manager
|
||||||
|
- Fix search-result delete ordering in File Manager
|
||||||
|
- Fix to speed up search-result deletion cleanup in File Manager
|
||||||
|
|
||||||
|
#### 2.650 (June 25, 2026)
|
||||||
|
* Add new Systemd Services and Units module
|
||||||
|
* Add new GRUB 2 Boot Loader module
|
||||||
|
* Add new Kea DHCP Server module
|
||||||
|
* Add WebSocket proxy support to the Webmin Servers Index module
|
||||||
|
* Add basic Alpine Linux support
|
||||||
|
* Add IP-based Let's Encrypt certificate support with Certbot 5.3
|
||||||
|
* Add editable SSH public keys for newly added Unix users in Users and Groups module
|
||||||
|
* Add improvements to custom Webmin temporary directory handling
|
||||||
|
* Add quick service and port forwarding controls to the nftables module
|
||||||
|
* Add optional pre- and post-scripts for scheduled package updates
|
||||||
|
* Add option to control when scheduled package update email is sent
|
||||||
|
* Add per-user RPC/API-only access option to the Webmin Users module
|
||||||
|
* Add Apache 2.4 MPM process limit directives [#1821](https://github.com/webmin/webmin/issues/1821)
|
||||||
|
* Add dhcpcd network backend for Debian and Raspberry Pi OS [#1607](https://github.com/webmin/webmin/issues/1607)
|
||||||
|
* Add hardware RAID passthrough devices config in the SMART Status module [#1704](https://github.com/webmin/webmin/issues/1704)
|
||||||
|
* Update Xterm.js to fix Control-C handling on iPadOS/Safari terminals
|
||||||
|
* Update Webmin systemd service unit to run without forking
|
||||||
|
* Fix IPv6 CIDR access control matching [#1570](https://github.com/webmin/webmin/issues/1570)
|
||||||
|
* Fix Bootup and Shutdown module to show only services and not all units on systemd systems
|
||||||
|
* Fix Let's Encrypt renewal scheduling to count from the last successful request
|
||||||
|
* Fix NetworkManager detection on Debian and IPv6 DNS nameserver saving
|
||||||
|
* Fix Dovecot configuration file handling when saving extra configs
|
||||||
|
* Fix mailbox listing to skip unusable Maildir entries and remove stale deleted or moved entries
|
||||||
|
* Fix Postfix module labels to identify virtual alias maps instead of virtual mailbox domains #1541
|
||||||
|
* Fix Apache module to hide disabled default virtual hosts from the active server list
|
||||||
|
* Fix Netplan DNS saving to preserve YAML structure
|
||||||
|
* Fix BIND DNS handling of underscores, trailing dots, and mass record length checks
|
||||||
|
* Fix MariaDB user creation when using auth plugin syntax
|
||||||
|
* Fix PHP-FPM monitor on EL systems when using `/etc/php.ini` as the config file
|
||||||
|
* Fix RPC-only accounts to block browser/module access before module ACL checks
|
||||||
|
* Fix reflected XSS in Webmin status messages
|
||||||
|
* Fix path validation in File Manager, package delete helpers, and Apache virtual host files
|
||||||
|
* Fix authentication state handling for SSL certificate logins and proxied keep-alive requests
|
||||||
|
* Update session handling to improve security, which will require users to re-authenticate after upgrading
|
||||||
|
* Update the Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
- Add zooming to stats history graphs by holding shift and scrolling in the dashboard
|
||||||
|
- Add support for saving live stats history for up to 24 hours without performance impact
|
||||||
|
- Add better support for the new Nginx, nftables, and upcoming systemd, Kea-DHCP, and GRUB 2 Webmin modules
|
||||||
|
- Add ability to always show available dashboard panels in theme configuration
|
||||||
|
- Add support for live stats and terminal WebSocket connections through Webmin Servers Index proxy links
|
||||||
|
- Fix proxying when Webmin is accessed with a webprefix using Webmin Servers Index module
|
||||||
|
- Fix theme UI helpers to escape generated markup more safely
|
||||||
|
- Fix iOS terminal viewport sizing
|
||||||
|
- Fix editor save handling, clean-state indication and dirty reload guard
|
||||||
|
- Fix popover positioning, z-index and border color for help bubbles
|
||||||
|
- Fix the active product switch border in the navigation menu for the dark palette
|
||||||
|
- Fix to validate password reset return URLs
|
||||||
|
|
||||||
|
#### 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:
|
||||||
|
- Add a new airy button style to the light palette to match the dark one
|
||||||
|
- Fix to optimize stats server to reduce WebSocket memory usage
|
||||||
|
- Fix the real-time follow indicator when viewing the journal
|
||||||
|
- Fix regex-based match highlighting when viewing the journal
|
||||||
|
- Fix mail compose panel sizing in HTML mode on low-DPR screens
|
||||||
|
- Fix display of the 2FA QR code in the dark palette
|
||||||
|
|
||||||
|
#### 2.621 (January 25, 2026)
|
||||||
|
* Fix to prevent NAT from dropping idle RPC sessions during long transfers
|
||||||
|
* Fix to improve the message when socket authentication is used in the MySQL/MariaDB module
|
||||||
|
* Fix to make upload tracking work correctly in all situations and on all systems
|
||||||
|
* Fix to correctly display the PHP version in the PHP Configuration module when managing packages
|
||||||
|
* Update Xterm.js to the latest version with lots of improvements and fixes
|
||||||
|
* Update Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
* Fix the support for the cloned Terminal module
|
||||||
|
* Fix error handling for file uploads when the user is out of quota or the system is out of disk space in the File Manager module
|
||||||
|
* Fix to stop loading full file into memory for upload check to prevent memory leak on large uploads in the File Manager module
|
||||||
|
* Fix to permanently save the state of the navigation menu and right-side slider when toggled
|
||||||
|
|
||||||
|
|
||||||
|
#### 2.620 (January 9, 2026)
|
||||||
|
* Add ability to use correct driver depending on the database in MySQL/MariaDB module
|
||||||
|
* Add improvements to BIND DNS module for better key management
|
||||||
|
* Add support for Ubuntu 26.04 development preview
|
||||||
|
* Add a config option to increase the RPC timeout
|
||||||
|
* Add support for EC SSL certificate and key in the ProFTPd module
|
||||||
|
* Add support for using `gpart` in FreeBSD disk management module
|
||||||
|
* Add support for Ed25519 public key in User and Groups module
|
||||||
|
* Fix RPC session timeout during large file transfers
|
||||||
|
* Fix selection and configuration of TLS certificate and key in the ProFTPd module
|
||||||
|
* Update Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
* Add support for multiple scrollable tabs in the File Manager
|
||||||
|
* Fix displaying of the right-side toolbar in File Manager when using Safari
|
||||||
|
* Fix to print menu separator when no virtual servers are added yet in Virtualmin
|
||||||
|
* Fix bugs in white palette
|
||||||
|
* Fix exported file name in data tables
|
||||||
|
|
||||||
|
#### 2.610 (November 23, 2025)
|
||||||
|
* Fix to drop dependency on `IO::Pty` Perl module
|
||||||
|
* Fix `virtual-server` module server-side search to work correctly
|
||||||
|
* Update the Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
- Add a range slider to adjust content page margins more precisely
|
||||||
|
- Add an option to enable rounded corners for content page
|
||||||
|
- Add more customization options for pie charts
|
||||||
|
- Fix to increase clickable area for checkboxes in File Manager
|
||||||
|
- Fix to correct rotation of pin and unpin button for right side slider
|
||||||
|
- Fix color of selected items in the multiselect dropdown
|
||||||
|
- Fix to improve the visibility of disabled checkboxes
|
||||||
|
- Fix to send saved params in the post body when saving theme configuration
|
||||||
|
[More details...](https://github.com/webmin/authentic-theme/releases/tag/26.20)
|
||||||
|
|
||||||
|
#### 2.600 (November 9, 2025)
|
||||||
|
* Add an options to enable the slow query log in the MySQL/MariaDB module [#2560](https://github.com/webmin/webmin/issues/2560)
|
||||||
|
* Add ability to install multiple PHP extensions at once in the PHP Configuration module
|
||||||
|
* Add ability to show package URL in the Software Packages module [#1141](https://github.com/virtualmin/virtualmin-gpl/issues/1141)
|
||||||
|
* Add support to show Debian package install time in the Software Packages module
|
||||||
|
* Add support to show detailed Webmin server stats using new `webmin stats` CLI command [forum.virtualmin.com/t/135556](https://forum.virtualmin.com/t/is-this-memory-used-a-bit-high/135556/6?u=ilia)
|
||||||
|
* Add a major Authentic theme UI update with lots of visual and structural improvements for a smoother and more modern experience
|
||||||
|
[More details...](https://forum.virtualmin.com/t/authentic-theme-version-26-00-release-overview/135755?u=ilia)
|
||||||
|
* Fix EOL library fatal error for OS in development [#2121](https://github.com/webmin/webmin/issues/2121)
|
||||||
|
* Fix correctly saving jails with parameters containing quotes in the Fail2Ban module [#2572](https://github.com/webmin/webmin/issues/2572)
|
||||||
|
* Fix file is always renamed as the effective user in the Upload and Download module [#1054](https://github.com/webmin/webmin/issues/1054)
|
||||||
|
|
||||||
|
#### 2.520 (October 4, 2025)
|
||||||
|
* Fix to make sure the mail URL uses a well-known host name [security]
|
||||||
|
* Fix support for other Raspberry Pi sensors [#2545](https://github.com/webmin/webmin/issues/2545)
|
||||||
|
* Fix the printing of the bottom button row in the form column table
|
||||||
|
* Fix to recommend Perl `Sys::Syslog` module [#2557](https://github.com/webmin/webmin/issues/2557)
|
||||||
|
* Fix to avoid using short hostname in HTTPS redirects when an FQDN is available
|
||||||
|
* Fix to use _/proc_ sampler instead of `vmstat` for the same output with much lower overhead
|
||||||
|
* Fix to query specific fields in FreeBSD memory stats collection, cutting CPU use by 80%
|
||||||
|
* Fix to kill Webmin subprocesses during RC stop on FreeBSD and other systems
|
||||||
|
* Fix to correctly fetch command version in `PPTP VPN Client` module [#2567](https://github.com/webmin/webmin/issues/2567)
|
||||||
|
* Add a complete overhaul of `var_dump` subroutine, which is now fully portable
|
||||||
|
* Update the Authentic theme to the latest version with various fixes:
|
||||||
|
- Fix the text color when reading email in the Read User Mail module [webmin#2555](https://github.com/webmin/webmin/issues/2555)
|
||||||
|
- Fix to ensure the selected color palette is correctly stored when changed manually [webmin#2552](https://github.com/webmin/webmin/issues/2552)
|
||||||
|
- Fix a bug when the Webmin version label was missing when copying to clipboard system information from the dashboard
|
||||||
|
- Fix DNS query spike from network stats collection on FreeBSD [webmin#2556](https://github.com/webmin/webmin/issues/2556)
|
||||||
|
- Fix to display the appropriate icon for proxy mode on new Bunny DNS
|
||||||
|
- Fix spinner color in toast messages for dark palette
|
||||||
|
- Fix other bugs and add various small improvements
|
||||||
|
|
||||||
|
#### 2.510 (September 16, 2025)
|
||||||
|
* Fix to ensure DNSSEC re-signing period is less than 30 days in the BIND DNS module
|
||||||
|
* Fix to treat 201 as a valid response code in the internal download function
|
||||||
|
* Update the Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
- Add optimizations to dashboard graphs with dynamic trimming to prevent page lagging
|
||||||
|
- Add improvements to how the system cache for the dashboard is updated
|
||||||
|
- Add support to correctly reload the page in proxy mode
|
||||||
|
- Add an option to choose if default page should always load when switching navigation
|
||||||
|
- Fix to ensure the color palette is preserved for the user [webmin#2537](https://github.com/webmin/webmin/issues/2537)
|
||||||
|
- Fix algorithm for calculating rows per page in data table pagination
|
||||||
|
- Fix the alert info box text color for dark mode
|
||||||
|
- Fix critical lags and appearance of Custom Commands module
|
||||||
|
|
||||||
|
#### 2.501 (September 10, 2025)
|
||||||
|
* Add support for Raspberry Pi sensors #2539 #2517
|
||||||
|
* Add Squid 7 support
|
||||||
|
* Update the Authentic theme to the latest version with the following fixes:
|
||||||
|
- Fix broken editor in "Bootup and Shutdown" module
|
||||||
|
|
||||||
|
#### 2.500 (September 4, 2025)
|
||||||
|
* Add support for the Webmin webserver to work in both HTTP and HTTPS modes at the same time
|
||||||
|
* Add distinct warning to the login page if the connection is not secure
|
||||||
|
* Add support for timeouts in temporary rules in "FirewallD" module
|
||||||
|
* Add support for the new Dovecot version 2.4
|
||||||
|
* Add support for MariaDB version 12 #2522
|
||||||
|
* Add support for IMAP through a local command for Usermin
|
||||||
|
* Add latest SSLeay support for redirects to SSL work
|
||||||
|
* Add improvements to "Bootup and Shutdown" module for _systemd_ systems
|
||||||
|
* Add field for secondary server key in "BIND DNS Server" module
|
||||||
|
* Add reversible encryption helpers API
|
||||||
|
* Add API to display relative dates
|
||||||
|
* Add API to mask sensitive text, like displayed passwords, unless hovered over
|
||||||
|
* Add status monitor for PHP FPM #2499
|
||||||
|
* Add support for DNF5 format in the "Software Packages" module
|
||||||
|
* Add support for redirecting to the enforced domain when the `musthost_redirect` directive is set
|
||||||
|
* Add option to customize the SMTP login for scheduled background monitoring in the "System and Server Status" module
|
||||||
|
* Change to show relative dates in "Webmin Users: Current Login Sessions" and "Webmin Actions Log: Search Results" pages
|
||||||
|
* Change "Last Logins" on the dashboard to show usernames, relative dates, and all users from the past 3 days
|
||||||
|
* Change to always enable HSTS by default
|
||||||
|
* Fix MySQL/MariaDB to remove obsolete `set-variable` options that break modern config files #2497
|
||||||
|
* Fix download link in table rows in "MySQL/MariaDB Database Server" module
|
||||||
|
* Fix module not to fail on old MySQL 5.5
|
||||||
|
* Update the Authentic theme to the latest version with various improvements and fixes:
|
||||||
|
- Add support to automatically set the color palette based on OS or browser preferences
|
||||||
|
- Add improvements to tooltips in dark palette
|
||||||
|
- Change the default shortcut key for toggling the light/dark palette
|
||||||
|
- Change the default shortcut key for toggling right slider
|
||||||
|
- Change wording to use "shortcut" instead of "hotkey"
|
||||||
|
- Change the default maximum column width
|
||||||
|
- Fix navigation menu load in proxy mode #2502
|
||||||
|
- Fix navigation menu to always stay in sync with the product switch
|
||||||
|
- Fix sporadic issue where the navigation menu disappeared and the content page was shifted
|
||||||
|
- Fix info alert text color and button color in the dark palette
|
||||||
|
- Fix styling of checkboxes and radios for backup and restore pages in Virtualmin
|
||||||
|
- Fix styling for extra backup destinations in Virtualmin
|
||||||
|
- Fix advanced schedule display in the cron chooser in Virtualmin
|
||||||
|
[More details...](https://github.com/webmin/authentic-theme/releases/tag/25.00)
|
||||||
|
|
||||||
|
#### 2.402 (June 16, 2025)
|
||||||
|
* Update the Authentic theme to the latest version with various fixes and improvements
|
||||||
|
* Fix support for EL10-based systems
|
||||||
|
|
||||||
#### 2.401 (June 2, 2025)
|
#### 2.401 (June 2, 2025)
|
||||||
* Add forgotten password recovery support for Virtualmin mailbox users
|
* Add forgotten password recovery support for Virtualmin mailbox users
|
||||||
* Add forgotten password recovery support in Usermin
|
* Add forgotten password recovery support in Usermin
|
||||||
@@ -119,7 +364,7 @@
|
|||||||
* Update the Authentic theme to the latest version with various fixes and improvements
|
* Update the Authentic theme to the latest version with various fixes and improvements
|
||||||
|
|
||||||
#### 2.201 (July 24, 2024)
|
#### 2.201 (July 24, 2024)
|
||||||
* Fix real-time monitoring not updating graphs in the Dashboard [#2222](https://github.com/webmin/webmin/issues/2222)
|
* Fix real-time monitoring not updating graphs in the dashboard [#2222](https://github.com/webmin/webmin/issues/2222)
|
||||||
* Fix Terminal module to work correctly with _sudo_-capable users [#2223](https://github.com/webmin/webmin/issues/2223)
|
* Fix Terminal module to work correctly with _sudo_-capable users [#2223](https://github.com/webmin/webmin/issues/2223)
|
||||||
|
|
||||||
#### 2.200 (July 21, 2024)
|
#### 2.200 (July 21, 2024)
|
||||||
@@ -162,7 +407,7 @@
|
|||||||
* Fix to using the `qrencode` command to generate QR codes locally instead of the remote Google Chart API
|
* Fix to using the `qrencode` command to generate QR codes locally instead of the remote Google Chart API
|
||||||
* Fix a number of various other issues
|
* Fix a number of various other issues
|
||||||
|
|
||||||
#### 2.105 (November 09, 2023)
|
#### 2.105 (November 9, 2023)
|
||||||
* Fix param to read only headers [sourceforge.net/usermin-bugs#501](https://sourceforge.net/p/webadmin/usermin-bugs/501/)
|
* Fix param to read only headers [sourceforge.net/usermin-bugs#501](https://sourceforge.net/p/webadmin/usermin-bugs/501/)
|
||||||
* Fix not to set `reuse` flag on initial Let's Encrypt request
|
* Fix not to set `reuse` flag on initial Let's Encrypt request
|
||||||
* Fix to correctly escape mail file names upon deletion
|
* Fix to correctly escape mail file names upon deletion
|
||||||
@@ -177,7 +422,7 @@
|
|||||||
* Fix the absent init script for legacy systems after the initial installation
|
* Fix the absent init script for legacy systems after the initial installation
|
||||||
* Update the Authentic theme to the latest version with various fixes and improvements
|
* Update the Authentic theme to the latest version with various fixes and improvements
|
||||||
|
|
||||||
#### 2.103 (October 08, 2023)
|
#### 2.103 (October 8, 2023)
|
||||||
* Add support for hostname detection using `hostnamectl` command
|
* Add support for hostname detection using `hostnamectl` command
|
||||||
* Add support for other ACME services
|
* Add support for other ACME services
|
||||||
* Add ability to hide dotfiles in File Manager [#1578](https://github.com/webmin/authentic-theme/issues/1578)
|
* Add ability to hide dotfiles in File Manager [#1578](https://github.com/webmin/authentic-theme/issues/1578)
|
||||||
@@ -226,13 +471,13 @@
|
|||||||
* Fix clearing packages caches before checking for updates in status collection #1863
|
* Fix clearing packages caches before checking for updates in status collection #1863
|
||||||
* Update the Authentic theme to the latest version
|
* Update the Authentic theme to the latest version
|
||||||
|
|
||||||
#### 2.020 (March 08, 2023)
|
#### 2.020 (March 8, 2023)
|
||||||
* Add full locale support
|
* Add full locale support
|
||||||
* Add slave zone file format option in BIND DNS module
|
* Add slave zone file format option in BIND DNS module
|
||||||
* Add support for editing ACLs in File Manager
|
* Add support for editing ACLs in File Manager
|
||||||
* Add support to configure SSL connection for MySQL/MariaDB module
|
* Add support to configure SSL connection for MySQL/MariaDB module
|
||||||
* Add support for compressed backups in PostgreSQL module
|
* Add support for compressed backups in PostgreSQL module
|
||||||
* Add support for displaying inodes too in Disk Usage in the Dashboard
|
* Add support for displaying inodes too in Disk Usage in the dashboard
|
||||||
* Add better support for CloudLinux
|
* Add better support for CloudLinux
|
||||||
* Fix to always default to RSA key type in Let's Encrypt requests
|
* Fix to always default to RSA key type in Let's Encrypt requests
|
||||||
* Fix setup repository script for Oracle
|
* Fix setup repository script for Oracle
|
||||||
@@ -240,7 +485,7 @@
|
|||||||
* Fix support for SpamAssassin 4
|
* Fix support for SpamAssassin 4
|
||||||
* Fix to use system default hashing format for `htpasswd` file
|
* Fix to use system default hashing format for `htpasswd` file
|
||||||
* Fix FastRPC issues
|
* Fix FastRPC issues
|
||||||
* Update the Authentic theme to the latest version, with sped-up Dashboard performance
|
* Update the Authentic theme to the latest version, with sped-up dashboard performance
|
||||||
|
|
||||||
#### 2.013 (January 19, 2023)
|
#### 2.013 (January 19, 2023)
|
||||||
* Fix Authentic theme issue with error handling
|
* Fix Authentic theme issue with error handling
|
||||||
@@ -394,12 +639,12 @@ 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.
|
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)
|
#### 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 04, 2019)
|
#### 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.
|
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.
|
||||||
|
|
||||||
#### Version 1.910 (May 09, 2019)
|
#### Version 1.910 (May 9, 2019)
|
||||||
This release includes theme and translation updates, a page for editing package repositories, cron and status module improvements, and a bunch of other bugfixes and small improvements.
|
This release includes theme and translation updates, a page for editing package repositories, cron and status module improvements, and a bunch of other bugfixes and small improvements.
|
||||||
|
|
||||||
#### Version 1.900 (November 19, 2018)
|
#### Version 1.900 (November 19, 2018)
|
||||||
@@ -411,7 +656,7 @@ This version includes Ubuntu 18 network config support, translation updates, mul
|
|||||||
#### Version 1.880 (March 16, 2018)
|
#### Version 1.880 (March 16, 2018)
|
||||||
This version includes German, Catalan and Bulgarian translation updates, a new version of the Authentic theme, support for directly editing the MySQL and PostgreSQL config files, Let's Encrypt bugfixes, more control over system status email notifications, and more.
|
This version includes German, Catalan and Bulgarian translation updates, a new version of the Authentic theme, support for directly editing the MySQL and PostgreSQL config files, Let's Encrypt bugfixes, more control over system status email notifications, and more.
|
||||||
|
|
||||||
#### Version 1.870 (December 08, 2018)
|
#### Version 1.870 (December 8, 2018)
|
||||||
This release includes many translation updates, fixes for Let's Encrypt support, UI cleanups, and most importantly a new major version of the Authentic theme.
|
This release includes many translation updates, fixes for Let's Encrypt support, UI cleanups, and most importantly a new major version of the Authentic theme.
|
||||||
|
|
||||||
#### Version 1.860 (October 10, 2017)
|
#### Version 1.860 (October 10, 2017)
|
||||||
@@ -420,7 +665,7 @@ This release includes Let's Encrypt DNS fixes, Majordomo module improvements, XS
|
|||||||
#### Version 1.850 (June 28, 2017)
|
#### Version 1.850 (June 28, 2017)
|
||||||
This release includes Let's Encrypt fixes, Majordomo module improvements, FirewallD forwarding support, translation updates, an update to the Authentic theme, and a bunch of other bugfixes.
|
This release includes Let's Encrypt fixes, Majordomo module improvements, FirewallD forwarding support, translation updates, an update to the Authentic theme, and a bunch of other bugfixes.
|
||||||
|
|
||||||
#### Version 1.840 (May 08, 2017)
|
#### Version 1.840 (May 8, 2017)
|
||||||
This major release includes a large theme update, XSS security fixes, per-domain SSL cert support, thin-provisioned LVM support, Let's Encrypt improvements, translation updates, and the usual gang of bugfixes. Also available is Usermin 1.710, which contains many of the same updates.
|
This major release includes a large theme update, XSS security fixes, per-domain SSL cert support, thin-provisioned LVM support, Let's Encrypt improvements, translation updates, and the usual gang of bugfixes. Also available is Usermin 1.710, which contains many of the same updates.
|
||||||
|
|
||||||
#### Version 1.830 (December 29, 2016)
|
#### Version 1.830 (December 29, 2016)
|
||||||
@@ -727,4 +972,3 @@ This updated includes the latest Authentic theme, a new IPv6 Firewall module for
|
|||||||
#### Version 1.140
|
#### Version 1.140
|
||||||
* Fixed a security hole that allowed any user to view the configuration of any module, even those that they should not have access to.
|
* Fixed a security hole that allowed any user to view the configuration of any module, even those that they should not have access to.
|
||||||
* Fixed a security hole that could allow an attacker to lock valid users by sending a bogus username or password.
|
* Fixed a security hole that could allow an attacker to lock valid users by sending a bogus username or password.
|
||||||
|
|
||||||
|
|||||||
12
README-zh.md
12
README-zh.md
@@ -1,7 +1,7 @@
|
|||||||
## 内容
|
## 内容
|
||||||
* [更新日志](https://github.com/webmin/webmin/blob/master/CHANGELOG.md)
|
* [更新日志](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 可以两种方法安装:
|
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>
|
<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) 脚本,无需任何选项,也就是说会直接安装到当前目录。或者使用命令行参数,例如目标目录。
|
2. 下载并解压[源码](https://prdownloads.sourceforge.net/webadmin/webmin-1.996.tar.gz)然后运行[_setup.sh_](https://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>
|
<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).
|
完整的 Webmin 还有它所有模块的详细配置都在[维基页面](https://doxfer.webmin.com/Webmin/Main_Page).
|
||||||
@@ -39,12 +39,12 @@ 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)
|
||||||
|
|
||||||
### 贡献者
|
### 贡献者
|
||||||
|
|
||||||
* [Joe Cooper](https://github.com/swelljoe)
|
* [Joe Cooper](https://github.com/swelljoe)
|
||||||
* [Ilia Rostovtsev](https://github.com/iliajie)
|
* [Ilia Rostovtsev](https://github.com/iliaross)
|
||||||
* [Kay Marquardt](https://github.com/gnadelwartz)
|
* [Kay Marquardt](https://github.com/gnadelwartz)
|
||||||
* [Nawawi Jamili](https://github.com/nawawi) + [其他无偿奉献的开发者](https://github.com/webmin/webmin/graphs/contributors)
|
* [Nawawi Jamili](https://github.com/nawawi) + [其他无偿奉献的开发者](https://github.com/webmin/webmin/graphs/contributors)
|
||||||
|
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -19,11 +19,11 @@
|
|||||||
**Webmin** is a web-based system administration tool for Unix-like servers, and services with about _1,000,000_ yearly installations worldwide. Using it, it is possible to configure operating system internals, such as users, disk quotas, services or configuration files, as well as modify, and control open-source apps, such as BIND DNS Server, Apache HTTP Server, PHP, MySQL, and many more.
|
**Webmin** is a web-based system administration tool for Unix-like servers, and services with about _1,000,000_ yearly installations worldwide. Using it, it is possible to configure operating system internals, such as users, disk quotas, services or configuration files, as well as modify, and control open-source apps, such as BIND DNS Server, Apache HTTP Server, PHP, MySQL, and many more.
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://webmin.com/screenshots/#gh-light-mode-only" target="_blank">
|
<a href="https://webmin.com/screenshots/?theme=light#gh-light-mode-only" target="_blank">
|
||||||
<img width="1440" alt="Dashboard screenshot" src="https://user-images.githubusercontent.com/4426533/218264253-c08fb45a-8d75-44bf-93b3-37a2ecae3d20.png">
|
<img width="1440" alt="Dashboard screenshot" src="https://github.com/user-attachments/assets/a01d0a78-4130-4665-9284-814955ae1c97">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://webmin.com/screenshots/#gh-dark-mode-only" target="_blank">
|
<a href="https://webmin.com/screenshots/?theme=dark#gh-dark-mode-only" target="_blank">
|
||||||
<img width="1440" alt="Dashboard screenshot" src="https://user-images.githubusercontent.com/4426533/218265232-31140aa6-ada1-4019-bd75-04240aeabc83.png">
|
<img width="1440" alt="Dashboard screenshot" src="https://github.com/user-attachments/assets/da4b90a0-c002-4e10-8b34-5acb251bbec9">
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@@ -45,16 +45,16 @@ For detailed installation instructions check our guide on [webmin.com/download](
|
|||||||
|
|
||||||
### Lead developer
|
### 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
|
### Developers
|
||||||
* [Ilia Rostovtsev](https://github.com/iliajie)
|
* [Ilia Rostovtsev](https://github.com/iliaross)
|
||||||
* [Joe Cooper](https://github.com/swelljoe)
|
* [Joe Cooper](https://github.com/swelljoe)
|
||||||
|
|
||||||
### Contributors
|
### Contributors
|
||||||
* [Kay Marquardt](https://github.com/gnadelwartz)
|
* [Kay Marquardt](https://github.com/gnadelwartz)
|
||||||
* [Nawawi Jamili](https://github.com/nawawi)
|
* [Nawawi Jamili](https://github.com/nawawi)
|
||||||
* [unknown10777](https://github.com/unknown10777) + [90 more..](https://github.com/webmin/webmin/graphs/contributors)
|
* [unknown10777](https://github.com/unknown10777) + [90 more...](https://github.com/webmin/webmin/graphs/contributors)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
249
SECURITY.md
249
SECURITY.md
@@ -1,23 +1,242 @@
|
|||||||
## Reporting Security Issues
|
|
||||||
|
|
||||||
Please send all reports of security issues found in Webmin to security@webmin.com
|
> [!WARNING]
|
||||||
via email, ideally PGP encrypted with the key from https://www.webmin.com/jcameron-key.asc .
|
> **Found a bug?** If you’ve found a new security-related issue, email
|
||||||
|
> [security@webmin.com](mailto:security@webmin.com).
|
||||||
|
|
||||||
Potential security issues, in descending order of impact, include :
|
### Webmin 2.510 and below [October 9, 2025]
|
||||||
|
#### Host header injection vulnerability in the password reset feature [CVE-2025-61541]
|
||||||
|
|
||||||
* Remotely exploitable attacks that allow `root` access to Webmin without
|
- If the password reset feature is enabled, an attacker can use a specially
|
||||||
any credentials.
|
crafted host header to cause the password reset email to contain a link to a
|
||||||
|
malicious site.
|
||||||
|
|
||||||
* Privilege escalation vulnerabilities that allow non-`root` users of Webmin
|
> Thanks to Nyein Chan Aung and Mg Demon for reporting this.
|
||||||
to run commands or access files as `root`.
|
|
||||||
|
|
||||||
* XSS attacks that target users already logged into Webmin when they visit
|
### Webmin 2.202 and below [February 26, 2025]
|
||||||
another website.
|
#### SSL certificates from clients may be trusted unexpectedly
|
||||||
|
|
||||||
Things that are not actually security issues include :
|
- If Webmin is configured to trust remote IP addresses provided by a proxy *and*
|
||||||
|
you have users authenticating using client SSL certificates, a browser
|
||||||
|
connecting directly (not via the proxy) can provide a forged header to fake
|
||||||
|
the client certificate.
|
||||||
|
|
||||||
* XSS attacks that are blocked by Webmin's referrer checks, which are enabled
|
- Upgrade to Webmin 2.301 or later, and if there is any chance of direct
|
||||||
by default.
|
requests by clients disable this at **Webmin ⇾ Webmin Configuration ⇾ IP
|
||||||
|
Access Control** page using **Trust level for proxy headers** option.
|
||||||
|
|
||||||
* Attacks that require modifications to Webmin's code or configuration, which
|
> Thanks to Keigo YAMAZAKI from LAC Co., Ltd. for reporting this.
|
||||||
can only be done by someone who already has `root` permissions.
|
|
||||||
|
### Webmin 2.105 and below [April 15, 2024]
|
||||||
|
#### Privilege escalation by non-root users [CVE-2024-12828]
|
||||||
|
|
||||||
|
- A less-privileged Webmin user can execute commands as root via a vulnerability in the shell autocomplete feature.
|
||||||
|
|
||||||
|
- All Virtualmin admins and Webmin admins who have created additional accounts should upgrade to version 2.111 as soon as possible!
|
||||||
|
|
||||||
|
> Thanks to Trend Micro’s Zero Day Initiative for finding and reporting this issue.
|
||||||
|
|
||||||
|
### Webmin 1.995 and Usermin 1.850 and below [June 30, 2022]
|
||||||
|
#### XSS vulnerability in the HTTP Tunnel module
|
||||||
|
|
||||||
|
- If a less-privileged Webmin user is given permission to edit the configuration of the HTTP Tunnel module, he/she could use this to introduce a vulnerability that captures cookies belonging to other Webmin users that use the module.
|
||||||
|
|
||||||
|
> Thanks to [BLACK MENACE][2] and [PYBRO][3] for reporting this issue.
|
||||||
|
|
||||||
|
- An HTML email crafted by an attacker could capture browser cookies when opened.
|
||||||
|
|
||||||
|
> Thanks to [ly1g3][4] for reporting this bug.
|
||||||
|
|
||||||
|
### Webmin 1.991 and below [April 18, 2022]
|
||||||
|
#### Privilege escalation exploit [CVE-2022-30708]
|
||||||
|
- Less privileged Webmin users (excluding those created by Virtualmin and Cloudmin) can modify arbitrary files with root privileges, and so run commands as root. All systems with additional untrusted Webmin users should upgrade immediately.
|
||||||
|
|
||||||
|
> Thanks to [esp0xdeadbeef][5] and [V1s3r1on][6] for finding and reporting this issue!
|
||||||
|
|
||||||
|
### Webmin 1.984 and below [December 26, 2021]
|
||||||
|
#### File Manager privilege exploit [CVE-2022-0824 and CVE-2022-0829]
|
||||||
|
|
||||||
|
- Less privileged Webmin users who do not have any File Manager module restrictions configured can access files with root privileges, if using the default Authentic theme. All systems with additional untrusted Webmin users should upgrade immediately. Note that Virtualmin systems are not effected by this bug, due to the way domain owner Webmin users are configured.
|
||||||
|
|
||||||
|
> Thanks to Faisal Fs ([faisalfs10x][7]) from [NetbyteSEC][8] for finding and reporting this issue!
|
||||||
|
|
||||||
|
### Virtualmin Procmail wrapper version 1.0
|
||||||
|
#### Privilege escalation exploit
|
||||||
|
- Version 1.0 of the `procmail-wrapper` package installed with Virtualmin has a vulnerability that can be used by anyone with SSH access to gain `root` privileges. To prevent this, all Virtualmin users should upgrade to version 1.1 or later immediately.
|
||||||
|
|
||||||
|
### Webmin 1.973 and below [March 7, 2021]
|
||||||
|
#### XSS vulnerabilities if Webmin is installed using the `setup.pl` script [CVE-2021-31760, CVE-2021-31761 and CVE-2021-31762]
|
||||||
|
|
||||||
|
- If Webmin is installed using the non-recommended `setup.pl` script, checking for unknown referers is not enabled by default. This opens the system up to XSS and CSRF attacks using malicious links. Fortunately the standard `rpm`, `deb`, `pkg` and `tar` packages do not use this script and so are not vulnerable. If you did install using the `setup.pl` script, the vulnerability can be fixed by adding the line `referers_none=1` to `/etc/webmin/config` file.
|
||||||
|
|
||||||
|
> Thanks to Meshal ( Mesh3l\_911 ) [@Mesh3l\_911][9] and Mohammed ( Z0ldyck ) [@electronicbots][10] for finding and reporting this issue!
|
||||||
|
|
||||||
|
### Webmin 1.941 and below [January 16, 2020]
|
||||||
|
#### XSS vulnerability in the Command Shell module [CVE-2020-8820 and CVE-2020-8821]
|
||||||
|
|
||||||
|
- A user with privileges to create custom commands could exploit other users via unescaped HTML.
|
||||||
|
|
||||||
|
> Thanks to Mauro Caseres for reporting this and the following issue.
|
||||||
|
|
||||||
|
### Webmin 1.941 and below [January 16, 2020]
|
||||||
|
#### XSS vulnerability in the Read Mail module [CVE-2020-12670]
|
||||||
|
- Saving a malicious HTML attachment could trigger and XSS vulnerability.
|
||||||
|
|
||||||
|
### Webmin 1.882 to 1.921 [July 6, 2019]
|
||||||
|
#### Remote Command Execution [CVE-2019-15231]
|
||||||
|
- Webmin releases between these versions contain a vulnerability that allows remote command execution! Version 1.890 is vulnerable in a default install and should be upgraded immediately - other versions are only vulnerable if changing of expired passwords is enabled, which is not the case by default.
|
||||||
|
|
||||||
|
Either way, upgrading to version 1.930 is strongly recommended. Alternately, if running versions 1.900 to 1.920, edit `/etc/webmin/miniserv.conf`, remove the `passwd_mode=` line, then run `/etc/webmin/restart` command.
|
||||||
|
{{< details-start post-indent-details "More details.." >}}
|
||||||
|
Webmin version 1.890 was released with a backdoor that could allow anyone with knowledge of it to execute commands as root. Versions 1.900 to 1.920 also contained a backdoor using similar code, but it was not exploitable in a default Webmin install. Only if the admin had enabled the feature at **Webmin ⇾ Webmin Configuration ⇾ Authentication** to allow changing of expired passwords could it be used by an attacker.
|
||||||
|
|
||||||
|
Neither of these were accidental bugs - rather, the Webmin source code had been maliciously modified to add a non-obvious vulnerability. It appears that this happened as follows :
|
||||||
|
|
||||||
|
- At some time in April 2018, the Webmin development build server was exploited and a vulnerability added to the `password_change.cgi` script. Because the timestamp on the file was set back, it did not show up in any Git diffs. This was included in the Webmin 1.890 release.
|
||||||
|
- The vulnerable file was reverted to the checked-in version from GitHub, but sometime in July 2018 the file was modified again by the attacker. However, this time the exploit was added to code that is only executed if changing of expired passwords is enabled. This was included in the Webmin 1.900 release.
|
||||||
|
- On September 10th 2018, the vulnerable build server was decommissioned and replaced with a newly installed server running CentOS 7. However, the build directory containing the modified file was copied across from backups made on the original server.
|
||||||
|
- On August 17th 2019, we were informed that a 0-day exploit that made use of the vulnerability had been released. In response, the exploit code was removed and Webmin version 1.930 created and released to all users.
|
||||||
|
|
||||||
|
In order to prevent similar attacks in future, we're doing the following :
|
||||||
|
|
||||||
|
- Updating the build process to use only checked-in code from GitHub, rather than a local directory that is kept in sync.
|
||||||
|
- Rotated all passwords and keys accessible from the old build system.
|
||||||
|
- Auditing all GitHub commits over the past year to look for commits that may have introduced similar vulnerabilities.
|
||||||
|
{{< details-end >}}
|
||||||
|
|
||||||
|
### Webmin 1.900 [November 19, 2018]
|
||||||
|
#### Remote Command Execution (Metasploit)
|
||||||
|
|
||||||
|
- This is _not_ a workable exploit as it requires that the attacker already know the root password. Hence there is no fix for it in Webmin.
|
||||||
|
|
||||||
|
### Webmin 1.900 and below [November 19, 2018]
|
||||||
|
#### Malicious HTTP headers in downloaded URLs
|
||||||
|
|
||||||
|
- If the Upload and Download or File Manager module is used to fetch an un-trusted URL. If a Webmin user downloads a file from a malicious URL, HTTP headers returned can be used exploit an XSS vulnerability.
|
||||||
|
|
||||||
|
> Thanks to independent security researcher, John Page aka hyp3rlinx, who reported this vulnerability to Beyond Security's SecuriTeam Secure Disclosure program.
|
||||||
|
|
||||||
|
### Webmin 1.800 and below [May 26, 2016]
|
||||||
|
#### Authentic theme configuration page vulnerability
|
||||||
|
- Only an issue if your system has un-trusted users with Webmin access and is using the new Authentic theme. A non-root Webmin user could use the theme configuration page to execute commands as root.
|
||||||
|
|
||||||
|
#### Authentic theme remote access vulnerability
|
||||||
|
- Only if the Authentic theme is enabled globally. An attacker could execute commands remotely as root, as long as there was no firewall blocking access to Webmin's port 10000.
|
||||||
|
|
||||||
|
### Webmin 1.750 and below [May 12, 2015]
|
||||||
|
#### XSS (cross-site scripting) vulnerability in `xmlrpc.cgi` script [CVE-2015-1990]
|
||||||
|
- A malicious website could create links or JavaScript referencing the `xmlrpc.cgi` script, triggered when a user logged into Webmin visits the attacking site.
|
||||||
|
|
||||||
|
> Thanks to Peter Allor from IBM for finding and reporting this issue.
|
||||||
|
|
||||||
|
### Webmin 1.720 and below [November 24, 2014]
|
||||||
|
#### Read Mail module vulnerable to malicious links
|
||||||
|
- If un-trusted users have both SSH access and the ability to use Read User Mail module (as is the case for Virtualmin domain owners), a malicious link could be created to allow reading any file on the system, even those owned by _root_.
|
||||||
|
|
||||||
|
> Thanks to Patrick William from RACK911 labs for finding this bug.
|
||||||
|
|
||||||
|
### Webmin 1.700 and below [August 11, 2014]
|
||||||
|
#### Shellshock vulnerability
|
||||||
|
- If your _bash_ shell is vulnerable to _shellshock_, it can be exploited by attackers who have a Webmin login to run arbitrary commands as _root_. Updating to version 1.710 (or updating _bash_) will fix this issue.
|
||||||
|
|
||||||
|
### Webmin 1.590 and below [June 30, 2012]
|
||||||
|
#### XSS (cross-site scripting) security hole
|
||||||
|
- A malicious website could create links or JavaScript referencing the File Manager module that allowed execution of arbitrary commands via Webmin when the website is viewed by the victim. See [CERT vulnerability note VU#788478][12] for more details. Thanks to Jared Allar from the American Information Security Group for reporting this problem.
|
||||||
|
|
||||||
|
#### Referer checks don't include port
|
||||||
|
- If an attacker has control over `http://example.com/` then he/she could create a page with malicious JavaScript that could take over a Webmin session at `https://example.com:10000/` when `http://example.com/` is viewed by the victim.
|
||||||
|
|
||||||
|
> Thanks to Marcin Teodorczyk for finding this issue.
|
||||||
|
|
||||||
|
### Webmin 1.540 and below [April 20, 2011]
|
||||||
|
#### XSS (cross-site scripting) security hole
|
||||||
|
- This vulnerability can be triggered if an attacker changes his Unix username via a tool like `chfn`, and a page listing usernames is then viewed by the root user in Webmin.
|
||||||
|
|
||||||
|
> Thanks to Javier Bassi for reporting this bug.
|
||||||
|
|
||||||
|
### Virtualmin 3.70 and below [June 23, 2009]
|
||||||
|
#### Unsafe file writes in Virtualmin
|
||||||
|
- This bug allows a virtual server owner to read or write to arbitrary files on the system by creating malicious symbolic links and then having Virtualmin perform operations on those links. Upgrading to version 3.70 is strongly recommended if your system has un-trusted domain owners.
|
||||||
|
|
||||||
|
### Webmin 1.390 and below, Usermin 1.320 and below [February 8, 2008]
|
||||||
|
#### XSS (cross-site scripting) security hole
|
||||||
|
- This attack could open users who visit un-trusted websites while having Webmin open in the same browser up to having their session cookie captured, which could then allow an attacker to login to Webmin without a password. The quick fix is to go to the **Webmin Configuration** module, click on the **Trusted Referers** icon, set **Referrer checking enabled?** to **Yes**, and un-check the box **Trust links from unknown referrers**. Webmin 1.400 and Usermin 1.330 will make these settings the defaults.
|
||||||
|
|
||||||
|
### Webmin 1.380 and below [November 3, 2007]
|
||||||
|
#### Windows-only command execution bug
|
||||||
|
- Any user logged into Webmin can execute any command using special URL parameters. This could be used by less-privileged Webmin users to raise their level of access.
|
||||||
|
|
||||||
|
> Thanks for Keigo Yamazaki of Little eArth Corporation for finding this bug.
|
||||||
|
|
||||||
|
### Webmin 1.374 and below, Usermin 1.277 and below
|
||||||
|
#### XSS bug in `pam_login.cgi` script
|
||||||
|
- A malicious link to Webmin `pam_login.cgi` script can be used to execute JavaScript within the Webmin server context, and perhaps steal session cookies.
|
||||||
|
|
||||||
|
### Webmin 1.330 and below, Usermin 1.260 and below
|
||||||
|
#### XSS bug in `chooser.cgi` script
|
||||||
|
- When using Webmin or Usermin to browse files on a system that were created by an attacker, a specially crafted filename could be used to inject arbitrary JavaScript into the browser.
|
||||||
|
|
||||||
|
### Webmin 1.296 and below, Usermin 1.226 and below
|
||||||
|
#### Remote source code access
|
||||||
|
- An attacker can view the source code of Webmin CGI and Perl programs using a specially crafted URL. Because the source code for Webmin is freely available, this issue should only be of concern to sites that have custom modules for which they want the source to remain hidden.
|
||||||
|
#### XSS bug
|
||||||
|
- The XSS bug makes use of a similar technique to craft a URL that can allow arbitrary JavaScript to be executed in the user's browser if a malicious link is clicked on.
|
||||||
|
|
||||||
|
> Thanks for Keigo Yamazaki of Little eArth Corporation for finding this bug.
|
||||||
|
|
||||||
|
### Webmin 1.290 and below, Usermin 1.220 and below
|
||||||
|
#### Arbitrary remote file access
|
||||||
|
- An attacker without a login to Webmin can read the contents of any file on the server using a specially crafted URL. All users should upgrade to version 1.290 as soon as possible, or setup IP access control in Webmin.
|
||||||
|
|
||||||
|
> Thanks to Kenny Chen for bringing this to my attention.
|
||||||
|
|
||||||
|
### Webmin 1.280 and below
|
||||||
|
#### Windows arbitrary file access
|
||||||
|
- If running Webmin on Windows, an attacker can remotely view the contents of any file on your system using a specially crafted URL. This does not affect other operating systems, but if you use Webmin on Windows you should upgrade to version 1.280 or later.
|
||||||
|
|
||||||
|
> Thanks to Keigo Yamazaki of Little eArth Corporation for discovering this bug.
|
||||||
|
|
||||||
|
### Webmin 1.250 and below, Usermin 1.180 and below
|
||||||
|
#### Perl syslog input attack
|
||||||
|
- When logging of failing login attempts via `syslog` is enabled, an attacker can crash and possibly take over the Webmin webserver, due to un-checked input being passed to Perl's `syslog` function. Upgrading to the latest release of Webmin is recommended.
|
||||||
|
|
||||||
|
> Thanks to Jack at Dyad Security for reporting this problem to me.
|
||||||
|
|
||||||
|
### Webmin 1.220 and below, Usermin 1.150 and below
|
||||||
|
#### Full PAM conversations' mode remote attack
|
||||||
|
- Affects systems when the option **Support full PAM conversations?** is enabled on the **Webmin ⇾ Webmin Configuration ⇾ Authentication** page. When this option is enabled in Webmin or Usermin, an attacker can gain remote access to Webmin without needing to supply a valid login or password. Fortunately this option is not enabled by default and is rarely used unless you have a PAM setup that requires more than just a username and password, but upgrading is advised anyway. <br />
|
||||||
|
|
||||||
|
> Thanks to Keigo Yamazaki of Little eArth Corporation and [JPCERT/CC][13] for discovering and notifying me of this bug.
|
||||||
|
|
||||||
|
### Webmin 1.175 and below, Usermin 1.104 and below
|
||||||
|
#### Brute force password guessing attack
|
||||||
|
- Prior Webmin and Usermin versions do not have password timeouts turned on by default, so an attacker can try every possible password for the _root_ or admin user until he/she finds the correct one.
|
||||||
|
The solution is to enable password timeouts, so that repeated attempts to login as the same user will become progressively slower. This can be done by following these steps :
|
||||||
|
|
||||||
|
* Go to the **Webmin Configuration** module.
|
||||||
|
* Click on the **Authentication** icon.
|
||||||
|
* Select the **Enable password timeouts** button.
|
||||||
|
* Click the **Save** button at the bottom of the page.
|
||||||
|
|
||||||
|
This problem is also present in Usermin, and can be prevented by following the same steps in the **Usermin Configuration** module.
|
||||||
|
|
||||||
|
### Webmin 1.150 and below, Usermin 1.080 and below
|
||||||
|
#### XSS vulnerability
|
||||||
|
- When viewing HTML email, several potentially dangerous types of URLs can be passed through. This can be used to perform malicious actions like executing commands as the logged-in Usermin user.
|
||||||
|
|
||||||
|
#### Module configurations are visible
|
||||||
|
- Even if a Webmin user does not have access to a module, he/she can still view it's Module Config page by entering a URL that calls `config.cgi` with the module name as a parameter.
|
||||||
|
|
||||||
|
#### Account lockout attack
|
||||||
|
- By sending a specially constructed password, an attacker can lock out other users if password timeouts are enabled.
|
||||||
|
|
||||||
|
[2]: https://github.com/bl4ckmenace
|
||||||
|
[3]: https://github.com/Pybro09
|
||||||
|
[4]: https://github.com/ly1g3
|
||||||
|
[5]: https://github.com/esp0xdeadbeef
|
||||||
|
[6]: https://github.com/V1s3r1on
|
||||||
|
[7]: https://github.com/faisalfs10x/
|
||||||
|
[8]: https://www.netbytesec.com/
|
||||||
|
[9]: https://twitter.com/Mesh3l_911
|
||||||
|
[10]: https://twitter.com/electronicbots
|
||||||
|
[12]: http://www.kb.cert.org/vuls/id/788478
|
||||||
|
[13]: http://www.jpcert.or.jp/
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Binary file not shown.
209
acl/acl-lib.pl
209
acl/acl-lib.pl
@@ -11,7 +11,7 @@ Library for editing webmin users, passwords and access rights.
|
|||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
BEGIN { push(@INC, ".."); };
|
BEGIN { push(@INC, ".."); }; ## no critic
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
@@ -92,7 +92,6 @@ while(my $l = <$fh>) {
|
|||||||
$user{'locale'} = $gconfig{"locale_$user[0]"};
|
$user{'locale'} = $gconfig{"locale_$user[0]"};
|
||||||
$user{'dateformat'} = $gconfig{"dateformat_$user[0]"};
|
$user{'dateformat'} = $gconfig{"dateformat_$user[0]"};
|
||||||
$user{'notabs'} = $gconfig{"notabs_$user[0]"};
|
$user{'notabs'} = $gconfig{"notabs_$user[0]"};
|
||||||
$user{'rbacdeny'} = $gconfig{"rbacdeny_$user[0]"};
|
|
||||||
if ($gconfig{"theme_$user[0]"}) {
|
if ($gconfig{"theme_$user[0]"}) {
|
||||||
($user{'theme'}, $user{'overlay'}) =
|
($user{'theme'}, $user{'overlay'}) =
|
||||||
split(/\s+/, $gconfig{"theme_$user[0]"});
|
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
|
sub list_module_infos
|
||||||
{
|
{
|
||||||
my @mods = grep { &check_os_support($_) } &get_all_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])
|
=head2 create_user(&details, [clone])
|
||||||
@@ -501,8 +501,6 @@ else {
|
|||||||
$gconfig{"lang_".$user->{'name'}} = $user->{'lang'} if ($user->{'lang'});
|
$gconfig{"lang_".$user->{'name'}} = $user->{'lang'} if ($user->{'lang'});
|
||||||
delete($gconfig{"notabs_".$user->{'name'}});
|
delete($gconfig{"notabs_".$user->{'name'}});
|
||||||
$gconfig{"notabs_".$user->{'name'}} = $user->{'notabs'} if ($user->{'notabs'});
|
$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'}});
|
delete($gconfig{"ownmods_".$user->{'name'}});
|
||||||
$gconfig{"ownmods_".$user->{'name'}} = join(" ", @{$user->{'ownmods'}})
|
$gconfig{"ownmods_".$user->{'name'}} = join(" ", @{$user->{'ownmods'}})
|
||||||
if ($user->{'ownmods'} && @{$user->{'ownmods'}});
|
if ($user->{'ownmods'} && @{$user->{'ownmods'}});
|
||||||
@@ -722,9 +720,6 @@ else {
|
|||||||
delete($gconfig{"notabs_".$username});
|
delete($gconfig{"notabs_".$username});
|
||||||
$gconfig{"notabs_".$user->{'name'}} = $user->{'notabs'}
|
$gconfig{"notabs_".$user->{'name'}} = $user->{'notabs'}
|
||||||
if ($user->{'notabs'});
|
if ($user->{'notabs'});
|
||||||
delete($gconfig{"rbacdeny_".$username});
|
|
||||||
$gconfig{"rbacdeny_".$user->{'name'}} = $user->{'rbacdeny'}
|
|
||||||
if ($user->{'rbacdeny'});
|
|
||||||
delete($gconfig{"ownmods_".$username});
|
delete($gconfig{"ownmods_".$username});
|
||||||
$gconfig{"ownmods_".$user->{'name'}} = join(" ", @{$user->{'ownmods'}})
|
$gconfig{"ownmods_".$user->{'name'}} = join(" ", @{$user->{'ownmods'}})
|
||||||
if ($user->{'ownmods'} && @{$user->{'ownmods'}});
|
if ($user->{'ownmods'} && @{$user->{'ownmods'}});
|
||||||
@@ -1337,12 +1332,12 @@ my ($miniserv) = @_;
|
|||||||
my $sfile = $miniserv->{'sessiondb'} ? $miniserv->{'sessiondb'} :
|
my $sfile = $miniserv->{'sessiondb'} ? $miniserv->{'sessiondb'} :
|
||||||
$miniserv->{'pidfile'} =~ /^(.*)\/[^\/]+$/ ? "$1/sessiondb"
|
$miniserv->{'pidfile'} =~ /^(.*)\/[^\/]+$/ ? "$1/sessiondb"
|
||||||
: return;
|
: return;
|
||||||
eval "use SDBM_File";
|
eval { require SDBM_File; SDBM_File->import; 1 };
|
||||||
dbmopen(%sessiondb, $sfile, 0700);
|
dbmopen(%sessiondb, $sfile, 0700);
|
||||||
eval { $sessiondb{'1111111111'} = 'foo bar' };
|
eval { $sessiondb{'1111111111'} = 'foo bar' };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
dbmclose(%sessiondb);
|
dbmclose(%sessiondb);
|
||||||
eval "use NDBM_File";
|
eval { require NDBM_File; NDBM_File->import; 1 };
|
||||||
dbmopen(%sessiondb, $sfile, 0700);
|
dbmopen(%sessiondb, $sfile, 0700);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1428,16 +1423,158 @@ Creates a new session ID that's already logged in as the given user
|
|||||||
sub create_session_user
|
sub create_session_user
|
||||||
{
|
{
|
||||||
my ($miniserv, $username, $lifetime) = @_;
|
my ($miniserv, $username, $lifetime) = @_;
|
||||||
return undef if (&is_readonly_mode());
|
return if (&is_readonly_mode());
|
||||||
&open_session_db($miniserv);
|
&open_session_db($miniserv);
|
||||||
my $sid = &generate_random_session_id();
|
my $sid = &generate_random_session_id();
|
||||||
return undef if (!$sid);
|
return if (!$sid);
|
||||||
my $t = time();
|
my $t = time();
|
||||||
$sessiondb{$sid} = "$username $t 127.0.0.1".($lifetime ? " ".$lifetime : "");
|
$sessiondb{$sid} = "$username $t 127.0.0.1".($lifetime ? " ".$lifetime : "");
|
||||||
dbmclose(%sessiondb);
|
dbmclose(%sessiondb);
|
||||||
return $sid;
|
return $sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
=head2 set_module_access(&modules, enabled, [&users-groups])
|
||||||
|
|
||||||
|
Grants or revokes Webmin module access for users and groups. The modules
|
||||||
|
parameter must be an array ref of module names. The enabled flag should be
|
||||||
|
1 to grant access, or 0 to revoke access. If the users-groups parameter is
|
||||||
|
not given, all users and groups are updated. Otherwise, it must be an array
|
||||||
|
ref of usernames and group names. Group names may be prefixed with @ to
|
||||||
|
target only a group.
|
||||||
|
|
||||||
|
Returns the number of directly updated user and group records.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
sub set_module_access
|
||||||
|
{
|
||||||
|
my ($mods, $enabled, $usersgroups) = @_;
|
||||||
|
$mods ||= [];
|
||||||
|
return 0 if (!@$mods);
|
||||||
|
my $set_module_access_list = sub {
|
||||||
|
my ($obj, $key, $addmods) = @_;
|
||||||
|
$addmods ||= $mods;
|
||||||
|
my @old = @{$obj->{$key} || []};
|
||||||
|
my @new;
|
||||||
|
if ($enabled) {
|
||||||
|
@new = &unique(@old, @$addmods);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
my %remove = map { $_, 1 } @$mods;
|
||||||
|
@new = grep { !$remove{$_} } @old;
|
||||||
|
}
|
||||||
|
return 0 if (join("\0", @old) eq join("\0", @new));
|
||||||
|
$obj->{$key} = \@new;
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
my $own_module_updates = sub {
|
||||||
|
my ($obj, $inherited) = @_;
|
||||||
|
return $mods if (!$enabled);
|
||||||
|
return [] if (!@{$obj->{'ownmods'} || []} && !@$inherited);
|
||||||
|
return [ grep { &indexof($_, @$inherited) < 0 } @$mods ];
|
||||||
|
};
|
||||||
|
my @users = &list_users();
|
||||||
|
my @groups = &list_groups();
|
||||||
|
my $all = !defined($usersgroups);
|
||||||
|
my (%target_user, %target_group);
|
||||||
|
if (!$all) {
|
||||||
|
foreach my $ug (@$usersgroups) {
|
||||||
|
if ($ug =~ /^\@(.*)$/) {
|
||||||
|
$target_group{$1} = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$target_user{$ug} = 1;
|
||||||
|
$target_group{$ug} = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my $changed = 0;
|
||||||
|
my (%user_group, %group_parent);
|
||||||
|
foreach my $g (@groups) {
|
||||||
|
foreach my $m (@{$g->{'members'} || []}) {
|
||||||
|
if ($m =~ /^\@(.*)$/) {
|
||||||
|
$group_parent{$1} = $g;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$user_group{$m} = $g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my (@ordered_groups, %ordered_group, %ordering_group);
|
||||||
|
my $add_ordered_group;
|
||||||
|
$add_ordered_group = sub {
|
||||||
|
my ($g) = @_;
|
||||||
|
return if (!$g || $ordered_group{$g->{'name'}});
|
||||||
|
return if ($ordering_group{$g->{'name'}}++);
|
||||||
|
$add_ordered_group->($group_parent{$g->{'name'}});
|
||||||
|
delete($ordering_group{$g->{'name'}});
|
||||||
|
push(@ordered_groups, $g);
|
||||||
|
$ordered_group{$g->{'name'}}++;
|
||||||
|
};
|
||||||
|
foreach my $g (@groups) {
|
||||||
|
$add_ordered_group->($g);
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update groups first, so member users and sub-groups inherit the new set
|
||||||
|
foreach my $g (@ordered_groups) {
|
||||||
|
next if (!$all && !$target_group{$g->{'name'}});
|
||||||
|
my $gchanged = 0;
|
||||||
|
my $parent = $group_parent{$g->{'name'}};
|
||||||
|
my $ownmods = $own_module_updates->(
|
||||||
|
$g, [ @{$parent ? $parent->{'modules'} || [] : []} ]);
|
||||||
|
$gchanged += $set_module_access_list->($g, "modules");
|
||||||
|
$gchanged += $set_module_access_list->($g, "ownmods", $ownmods);
|
||||||
|
if ($gchanged) {
|
||||||
|
&modify_group($g->{'name'}, $g);
|
||||||
|
&update_members(\@users, \@groups, $g->{'modules'},
|
||||||
|
$g->{'members'});
|
||||||
|
$changed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update directly targeted users
|
||||||
|
foreach my $u (@users) {
|
||||||
|
next if (!$all && !$target_user{$u->{'name'}});
|
||||||
|
my $uchanged = 0;
|
||||||
|
my $group = $user_group{$u->{'name'}};
|
||||||
|
my $ownmods = $own_module_updates->(
|
||||||
|
$u, [ @{$group ? $group->{'modules'} || [] : []} ]);
|
||||||
|
$uchanged += $set_module_access_list->($u, "modules");
|
||||||
|
$uchanged += $set_module_access_list->($u, "ownmods", $ownmods);
|
||||||
|
if ($uchanged) {
|
||||||
|
&modify_user($u->{'name'}, $u);
|
||||||
|
$changed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($changed) {
|
||||||
|
undef(%main::acl_hash_cache);
|
||||||
|
undef(%main::acl_array_cache);
|
||||||
|
}
|
||||||
|
return $changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
=head2 enable_module_access(&modules, [&users-groups])
|
||||||
|
|
||||||
|
Grants users and groups access to one or more modules. This is a wrapper
|
||||||
|
around set_module_access.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
sub enable_module_access
|
||||||
|
{
|
||||||
|
return &set_module_access($_[0], 1, $_[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
=head2 disable_module_access(&modules, [&users-groups])
|
||||||
|
|
||||||
|
Revokes users and groups access to one or more modules. This is a wrapper
|
||||||
|
around set_module_access.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
sub disable_module_access
|
||||||
|
{
|
||||||
|
return &set_module_access($_[0], 0, $_[1]);
|
||||||
|
}
|
||||||
|
|
||||||
=head2 update_members(&allusers, &allgroups, &modules, &members)
|
=head2 update_members(&allusers, &allgroups, &modules, &members)
|
||||||
|
|
||||||
Update the modules for members users and groups of some group. The parameters
|
Update the modules for members users and groups of some group. The parameters
|
||||||
@@ -1699,7 +1836,7 @@ elsif (&has_command("ssleay")) {
|
|||||||
return &has_command("ssleay");
|
return &has_command("ssleay");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1815,6 +1952,7 @@ foreach my $g (&list_groups()) {
|
|||||||
return $g;
|
return $g;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 check_password_restrictions(username, password)
|
=head2 check_password_restrictions(username, password)
|
||||||
@@ -1859,7 +1997,7 @@ if ($miniserv{'pass_oldblock'} && $user) {
|
|||||||
last if ($c++ > $miniserv{'pass_oldblock'});
|
last if ($c++ > $miniserv{'pass_oldblock'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
=head2 hash_session_id(sid)
|
=head2 hash_session_id(sid)
|
||||||
@@ -1896,11 +2034,11 @@ my $use_md5 = &md5_perl_module();
|
|||||||
$use_md5 || &error("No Perl MD5 hashing module found!");
|
$use_md5 || &error("No Perl MD5 hashing module found!");
|
||||||
|
|
||||||
# Add the password
|
# Add the password
|
||||||
my $ctx = eval "new $use_md5";
|
my $ctx = $use_md5->new;
|
||||||
$ctx->add($passwd);
|
$ctx->add($passwd);
|
||||||
|
|
||||||
# Add some more stuff from the hash of the password and salt
|
# 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);
|
||||||
$ctx1->add($passwd);
|
$ctx1->add($passwd);
|
||||||
my $final = $ctx1->digest();
|
my $final = $ctx1->digest();
|
||||||
@@ -1949,12 +2087,12 @@ Returns a Perl module for MD5 hashing, or undef if none.
|
|||||||
sub md5_perl_module
|
sub md5_perl_module
|
||||||
{
|
{
|
||||||
my $use_md5;
|
my $use_md5;
|
||||||
eval "use MD5";
|
eval { require MD5; MD5->import; 1 };
|
||||||
if (!$@) {
|
if (!$@) {
|
||||||
$use_md5 = "MD5";
|
$use_md5 = "MD5";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
eval "use Digest::MD5";
|
eval { require Digest::MD5; Digest::MD5->import; 1 };
|
||||||
if (!$@) {
|
if (!$@) {
|
||||||
$use_md5 = "Digest::MD5";
|
$use_md5 = "Digest::MD5";
|
||||||
}
|
}
|
||||||
@@ -2111,16 +2249,16 @@ my ($str, $notablecheck) = @_;
|
|||||||
my ($proto, $user, $pass, $host, $prefix, $args) = &split_userdb_string($str);
|
my ($proto, $user, $pass, $host, $prefix, $args) = &split_userdb_string($str);
|
||||||
if ($proto eq "mysql" || $proto eq "postgresql") {
|
if ($proto eq "mysql" || $proto eq "postgresql") {
|
||||||
# Load DBI driver
|
# Load DBI driver
|
||||||
eval 'use DBI;';
|
eval { require DBI; DBI->import; 1 };
|
||||||
return &text('sql_emod', 'DBI') if ($@);
|
return &text('sql_emod', 'DBI') if ($@);
|
||||||
if ($proto eq "mysql") {
|
if ($proto eq "mysql") {
|
||||||
eval 'use DBD::mysql;';
|
eval { require DBD::mysql; DBD::mysql->import; 1 };
|
||||||
return &text('sql_emod', 'DBD::mysql') if ($@);
|
return &text('sql_emod', 'DBD::mysql') if ($@);
|
||||||
my $drh = DBI->install_driver("mysql");
|
my $drh = DBI->install_driver("mysql");
|
||||||
return $text{'sql_emysqldriver'} if (!$drh);
|
return $text{'sql_emysqldriver'} if (!$drh);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
eval 'use DBD::Pg;';
|
eval { require DBD::Pg; DBD::Pg->import; 1 };
|
||||||
return &text('sql_emod', 'DBD::Pg') if ($@);
|
return &text('sql_emod', 'DBD::Pg') if ($@);
|
||||||
my $drh = DBI->install_driver("Pg");
|
my $drh = DBI->install_driver("Pg");
|
||||||
return $text{'sql_epostgresqldriver'} if (!$drh);
|
return $text{'sql_epostgresqldriver'} if (!$drh);
|
||||||
@@ -2152,11 +2290,11 @@ if ($proto eq "mysql" || $proto eq "postgresql") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&disconnect_userdb($str, $dbh);
|
&disconnect_userdb($str, $dbh);
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
elsif ($proto eq "ldap") {
|
elsif ($proto eq "ldap") {
|
||||||
# Load LDAP module
|
# Load LDAP module
|
||||||
eval 'use Net::LDAP;';
|
eval { require Net::LDAP; Net::LDAP->import; 1 };
|
||||||
return &text('sql_emod', 'Net::LDAP') if ($@);
|
return &text('sql_emod', 'Net::LDAP') if ($@);
|
||||||
|
|
||||||
# Try to connect
|
# Try to connect
|
||||||
@@ -2190,7 +2328,7 @@ elsif ($proto eq "ldap") {
|
|||||||
$found || return &text('sql_eldapdn', $prefix);
|
$found || return &text('sql_eldapdn', $prefix);
|
||||||
}
|
}
|
||||||
&disconnect_userdb($str, $dbh);
|
&disconnect_userdb($str, $dbh);
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return "Unknown user database type $proto";
|
return "Unknown user database type $proto";
|
||||||
@@ -2284,8 +2422,8 @@ if (!$miniserv) {
|
|||||||
$miniserv = { };
|
$miniserv = { };
|
||||||
&get_miniserv_config($miniserv);
|
&get_miniserv_config($miniserv);
|
||||||
}
|
}
|
||||||
foreach $a (split(/\s+/, $miniserv->{'anonymous'})) {
|
foreach my $tok (split(/\s+/, $miniserv->{'anonymous'})) {
|
||||||
if ($a =~ /^([^=]+)=(\S+)$/ && $2 eq $user) {
|
if ($tok =~ /^([^=]+)=(\S+)$/ && $2 eq $user) {
|
||||||
push(@rv, $1);
|
push(@rv, $1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2299,7 +2437,7 @@ sub get_safe_acl
|
|||||||
my ($m) = @_;
|
my ($m) = @_;
|
||||||
my $mdir = &module_root_directory($m);
|
my $mdir = &module_root_directory($m);
|
||||||
my %rv;
|
my %rv;
|
||||||
&read_file_cached("$mdir/safeacl", \%rv) || return undef;
|
&read_file_cached("$mdir/safeacl", \%rv) || return;
|
||||||
return \%rv;
|
return \%rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2313,17 +2451,19 @@ sub generate_random_session_id
|
|||||||
my $sid;
|
my $sid;
|
||||||
|
|
||||||
# Try /dev/urandom, but with a timeout
|
# Try /dev/urandom, but with a timeout
|
||||||
$SIG{ALRM} = sub { close(RANDOM) };
|
my $randomfh;
|
||||||
|
$SIG{ALRM} = sub { close($randomfh) if ($randomfh) };
|
||||||
alarm(5);
|
alarm(5);
|
||||||
if (open(RANDOM, "/dev/urandom")) {
|
if (open($randomfh, "<", "/dev/urandom")) {
|
||||||
my $tmpsid;
|
my $tmpsid;
|
||||||
if (read(RANDOM, $tmpsid, 16) == 16) {
|
if (read($randomfh, $tmpsid, 16) == 16) {
|
||||||
$sid = lc(unpack('h*',$tmpsid));
|
$sid = lc(unpack('h*',$tmpsid));
|
||||||
if ($sid !~ /^[0-9a-fA-F]{32}$/) {
|
if ($sid !~ /^[0-9a-fA-F]{32}$/) {
|
||||||
$sid = 'bad';
|
$sid = 'bad';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(RANDOM);
|
close($randomfh);
|
||||||
|
undef($randomfh);
|
||||||
}
|
}
|
||||||
alarm(0);
|
alarm(0);
|
||||||
|
|
||||||
@@ -2341,7 +2481,7 @@ return $sid eq 'bad' ? undef : $sid;
|
|||||||
# Generate an ID string that can be used for a password reset link
|
# Generate an ID string that can be used for a password reset link
|
||||||
sub generate_random_id
|
sub generate_random_id
|
||||||
{
|
{
|
||||||
if (open(my $RANDOM, "</dev/urandom")) {
|
if (open(my $RANDOM, "<", "/dev/urandom")) {
|
||||||
my $sid;
|
my $sid;
|
||||||
my $tmpsid;
|
my $tmpsid;
|
||||||
if (read($RANDOM, $tmpsid, 16) == 16) {
|
if (read($RANDOM, $tmpsid, 16) == 16) {
|
||||||
@@ -2350,7 +2490,9 @@ if (open(my $RANDOM, "</dev/urandom")) {
|
|||||||
close($RANDOM);
|
close($RANDOM);
|
||||||
return $sid;
|
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)
|
# obsfucate_email(email)
|
||||||
@@ -2368,4 +2510,3 @@ return $mailbox."\@".join(".", @doms);
|
|||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require 'acl-lib.pl';
|
require 'acl-lib.pl'; ## no critic
|
||||||
our ($config_directory, %gconfig);
|
our ($config_directory, %gconfig);
|
||||||
|
|
||||||
# backup_config_files()
|
# backup_config_files()
|
||||||
@@ -43,7 +43,7 @@ return @rv;
|
|||||||
# Called before the files are actually read
|
# Called before the files are actually read
|
||||||
sub pre_backup
|
sub pre_backup
|
||||||
{
|
{
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# post_backup(&files)
|
# post_backup(&files)
|
||||||
@@ -52,7 +52,7 @@ sub post_backup
|
|||||||
{
|
{
|
||||||
unlink("$config_directory/config.aclbackup");
|
unlink("$config_directory/config.aclbackup");
|
||||||
unlink("$config_directory/miniserv.conf.aclbackup");
|
unlink("$config_directory/miniserv.conf.aclbackup");
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# pre_restore(&files)
|
# pre_restore(&files)
|
||||||
@@ -66,7 +66,7 @@ foreach my $u (&list_users(), &list_groups()) {
|
|||||||
glob("$config_directory/*/$u->{'name'}.acl"));
|
glob("$config_directory/*/$u->{'name'}.acl"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
# post_restore(&files)
|
# post_restore(&files)
|
||||||
@@ -101,7 +101,7 @@ foreach my $k (keys %aclbackup) {
|
|||||||
&put_miniserv_config(\%miniserv);
|
&put_miniserv_config(\%miniserv);
|
||||||
|
|
||||||
&restart_miniserv();
|
&restart_miniserv();
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
&ui_print_header(undef, $text{'cert_title'}, "", undef, undef, undef, undef,
|
&ui_print_header(undef, $text{'cert_title'}, "", undef, undef, undef, undef,
|
||||||
undef, undef, "language=VBSCRIPT onload='postLoad()'");
|
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";
|
print "<p>$text{'cert_msg'}<p>\n";
|
||||||
if ($ENV{'SSL_USER'}) {
|
if ($ENV{'SSL_USER'}) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $module_config_directory, $base_remote_user);
|
our (%in, %text, %config, %access, $module_config_directory, $base_remote_user);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
|
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ elsif ($cgi eq 'edit_acl.cgi') {
|
|||||||
}
|
}
|
||||||
return 'none';
|
return 'none';
|
||||||
}
|
}
|
||||||
return undef;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $config_directory);
|
our (%in, %text, %config, %access, $config_directory);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&error_setup($text{'convert_err'});
|
&error_setup($text{'convert_err'});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'sync'} && $access{'create'} || &error($text{'convert_ecannot'});
|
$access{'sync'} && $access{'create'} || &error($text{'convert_ecannot'});
|
||||||
&ui_print_header(undef, $text{'convert_title'}, "");
|
&ui_print_header(undef, $text{'convert_title'}, "");
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ sessions=1
|
|||||||
cats=1
|
cats=1
|
||||||
ips=1
|
ips=1
|
||||||
switch=1
|
switch=1
|
||||||
rbacenable=1
|
|
||||||
logouttime=1
|
logouttime=1
|
||||||
times=1
|
times=1
|
||||||
minsize=1
|
minsize=1
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %access, $base_remote_user);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&error_setup($text{'gdelete_err'});
|
&error_setup($text{'gdelete_err'});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %access, $base_remote_user);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&error_setup($text{'gdeletes_err'});
|
&error_setup($text{'gdeletes_err'});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, %sessiondb);
|
our (%in, %text, %config, %access, %sessiondb);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
$access{'sessions'} || &error($text{'sessions_ecannot'});
|
$access{'sessions'} || &error($text{'sessions_ecannot'});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %access, $base_remote_user);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&error_setup($text{'delete_err'});
|
&error_setup($text{'delete_err'});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %access, $base_remote_user);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&error_setup($in{'joingroup'} ? $text{'udeletes_jerr'} : $text{'udeletes_err'});
|
&error_setup($in{'joingroup'} ? $text{'udeletes_jerr'} : $text{'udeletes_err'});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user, %gconfig);
|
our (%in, %text, %config, %access, $base_remote_user, %gconfig);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
$access{'acl'} || &error($text{'acl_emod'});
|
$access{'acl'} || &error($text{'acl_emod'});
|
||||||
@@ -48,15 +48,6 @@ else {
|
|||||||
}
|
}
|
||||||
print &ui_table_start(&text('acl_options', $minfo{'desc'}), "width=100%", 4);
|
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
|
# Load custom ACL library
|
||||||
my $mdir = &module_root_directory($in{'mod'});
|
my $mdir = &module_root_directory($in{'mod'});
|
||||||
if (-r "$mdir/acl_security.pl") {
|
if (-r "$mdir/acl_security.pl") {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $config_directory);
|
our (%in, %text, %config, %access, $config_directory);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
$access{'groups'} || &error($text{'gedit_ecannot'});
|
$access{'groups'} || &error($text{'gedit_ecannot'});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'pass'} || &error($text{'pass_ecannot'});
|
$access{'pass'} || &error($text{'pass_ecannot'});
|
||||||
&ui_print_header(undef, $text{'pass_title'}, "");
|
&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;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'sql'} || &error($text{'sql_ecannot'});
|
$access{'sql'} || &error($text{'sql_ecannot'});
|
||||||
&ui_print_header(undef, $text{'sql_title'}, "");
|
&ui_print_header(undef, $text{'sql_title'}, "");
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'sync'} && $access{'create'} && $access{'delete'} ||
|
$access{'sync'} && $access{'create'} && $access{'delete'} ||
|
||||||
&error($text{'sync_ecannot'});
|
&error($text{'sync_ecannot'});
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'unix'} && $access{'create'} && $access{'delete'} ||
|
$access{'unix'} && $access{'create'} && $access{'delete'} ||
|
||||||
&error($text{'unix_ecannot'});
|
&error($text{'unix_ecannot'});
|
||||||
@@ -82,7 +82,7 @@ print &ui_table_row($text{'unix_restrict2'},
|
|||||||
print &ui_table_row("",
|
print &ui_table_row("",
|
||||||
&ui_checkbox("shells_deny", 1, $text{'unix_shells'},
|
&ui_checkbox("shells_deny", 1, $text{'unix_shells'},
|
||||||
$miniserv{'shells_deny'} ? 1 : 0)." ".
|
$miniserv{'shells_deny'} ? 1 : 0)." ".
|
||||||
&ui_filebox("shells", $miniserv{'shells_deny'} || "/etc/shells", 40));
|
&ui_filebox("shells", $miniserv{'shells_deny'} || "/etc/shells", 25));
|
||||||
|
|
||||||
print &ui_table_end();
|
print &ui_table_end();
|
||||||
print &ui_form_end([ [ undef, $text{'save'} ] ]);
|
print &ui_form_end([ [ undef, $text{'save'} ] ]);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
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);
|
our (%in, %text, %config, %gconfig, %access, $config_directory, $base_remote_user, $remote_user);
|
||||||
&foreign_require("webmin", "webmin-lib.pl");
|
&foreign_require("webmin", "webmin-lib.pl");
|
||||||
|
|
||||||
@@ -42,6 +42,11 @@ else {
|
|||||||
: $text{'edit_title2'}, "");
|
: $text{'edit_title2'}, "");
|
||||||
}
|
}
|
||||||
my $me = &get_user($base_remote_user);
|
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
|
# Give up if readonly
|
||||||
if ($user{'readonly'} && !$in{'readwrite'}) {
|
if ($user{'readonly'} && !$in{'readwrite'}) {
|
||||||
@@ -210,7 +215,10 @@ if ($access{'lang'}) {
|
|||||||
|
|
||||||
if ($access{'locale'}) {
|
if ($access{'locale'}) {
|
||||||
# Current 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) {
|
if (!$@ && $] > 5.011) {
|
||||||
my $locales = &list_locales();
|
my $locales = &list_locales();
|
||||||
my %localesrev = reverse %{$locales};
|
my %localesrev = reverse %{$locales};
|
||||||
@@ -238,6 +246,18 @@ my @themes = grep { !$_->{'overlay'} } @all;
|
|||||||
my @overlays = grep { $_->{'overlay'} } @all;
|
my @overlays = grep { $_->{'overlay'} } @all;
|
||||||
|
|
||||||
if ($access{'theme'}) {
|
if ($access{'theme'}) {
|
||||||
|
my $tconf_link;
|
||||||
|
my %tinfo = &webmin::get_theme_info($user{'theme'});
|
||||||
|
if ($user{'theme'} && $user{'theme'} eq $tinfo{'dir'} &&
|
||||||
|
$user{'name'} eq $remote_user &&
|
||||||
|
$tinfo{'config_link'}) {
|
||||||
|
$tconf_link = &ui_tag('span', &ui_link(
|
||||||
|
"@{[&get_webprefix()]}/$tinfo{'config_link'}",
|
||||||
|
&ui_tag('span', '⚙',
|
||||||
|
{ class => 'theme-config-char',
|
||||||
|
title => $text{'themes_configure'} }),
|
||||||
|
'text-link'), { style => 'position: relative;' });
|
||||||
|
}
|
||||||
# Current theme
|
# Current theme
|
||||||
my @topts = ( );
|
my @topts = ( );
|
||||||
push(@topts, !$user{'theme'} ? [ '', $text{'edit_themedef'} ] : ());
|
push(@topts, !$user{'theme'} ? [ '', $text{'edit_themedef'} ] : ());
|
||||||
@@ -247,7 +267,8 @@ if ($access{'theme'}) {
|
|||||||
print &ui_table_row($text{'edit_theme'},
|
print &ui_table_row($text{'edit_theme'},
|
||||||
&ui_radio("theme_def", defined($user{'theme'}) ? 0 : 1,
|
&ui_radio("theme_def", defined($user{'theme'}) ? 0 : 1,
|
||||||
[ [ 1, $text{'edit_themeglobal'} ],
|
[ [ 1, $text{'edit_themeglobal'} ],
|
||||||
[ 0, &ui_select("theme", $user{'theme'}, \@topts) ] ]));
|
[ 0, &ui_select("theme", $user{'theme'}, \@topts).
|
||||||
|
$tconf_link ] ]));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($access{'theme'} && @overlays) {
|
if ($access{'theme'} && @overlays) {
|
||||||
@@ -267,7 +288,7 @@ if ($showui) {
|
|||||||
# Start of security options section
|
# Start of security options section
|
||||||
my $showsecurity = $access{'logouttime'} || $access{'ips'} ||
|
my $showsecurity = $access{'logouttime'} || $access{'ips'} ||
|
||||||
$access{'minsize'} ||
|
$access{'minsize'} ||
|
||||||
&supports_rbac() && $access{'mode'} == 0 || $access{'times'};
|
$access{'times'};
|
||||||
if ($showsecurity) {
|
if ($showsecurity) {
|
||||||
print &ui_hidden_table_start($text{'edit_security'}, "width=100%", 2,
|
print &ui_hidden_table_start($text{'edit_security'}, "width=100%", 2,
|
||||||
"security", 0, [ "width=30%" ]);
|
"security", 0, [ "width=30%" ]);
|
||||||
@@ -308,14 +329,6 @@ if ($access{'ips'}) {
|
|||||||
4, 30));
|
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'}) {
|
if ($access{'times'}) {
|
||||||
# Show allowed days of the week
|
# Show allowed days of the week
|
||||||
my %days = map { $_, 1 } split(/,/, $user{'days'} || '');
|
my %days = map { $_, 1 } split(/,/, $user{'days'} || '');
|
||||||
@@ -358,6 +371,16 @@ elsif ($miniserv{'twofactor_provider'}) {
|
|||||||
&ui_submit($text{'edit_twofactoradd'}, "twofactor"));
|
&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");
|
print &ui_hidden_table_end("security");
|
||||||
|
|
||||||
# Work out which modules can be selected
|
# Work out which modules can be selected
|
||||||
@@ -437,11 +460,9 @@ print &ui_hidden_table_end("mods");
|
|||||||
|
|
||||||
# Add global ACL section, but only if not set from the group
|
# Add global ACL section, but only if not set from the group
|
||||||
my $groupglobal = $memg && -r "$config_directory/$memg->{'name'}.acl";
|
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,
|
print &ui_hidden_table_start($text{'edit_global'}, "width=100%", 2,
|
||||||
"global", 0, [ "width=30%" ]);
|
"global", 0, [ "width=30%" ]);
|
||||||
my %uaccess;
|
|
||||||
%uaccess = &get_module_acl($in{'user'}, "", 1);
|
|
||||||
print &ui_hidden("acl_security_form", 1);
|
print &ui_hidden("acl_security_form", 1);
|
||||||
&foreign_require("", "acl_security.pl");
|
&foreign_require("", "acl_security.pl");
|
||||||
&foreign_call("", "acl_security_form", \%uaccess);
|
&foreign_call("", "acl_security_form", \%uaccess);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text);
|
our (%in, %text);
|
||||||
&foreign_require("webmin");
|
&foreign_require("webmin");
|
||||||
&error_setup($text{'forgot_err'});
|
&error_setup($text{'forgot_err'});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %gconfig);
|
our (%in, %text, %gconfig);
|
||||||
&foreign_require("webmin");
|
&foreign_require("webmin");
|
||||||
&error_setup($text{'forgot_err'});
|
&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,8 +6,8 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %gconfig, %access, $base_remote_user);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
|
&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(@icons, "images/twofactor.gif");
|
||||||
push(@links, "twofactor_form.cgi");
|
push(@links, "twofactor_form.cgi");
|
||||||
push(@titles, $text{'index_twofactor'});
|
push(@titles, $text{'index_twofactor'});
|
||||||
if ($access{'rbacenable'}) {
|
|
||||||
push(@icons, "images/rbac.gif");
|
|
||||||
push(@links, "edit_rbac.cgi");
|
|
||||||
push(@titles, $text{'index_rbac'});
|
|
||||||
}
|
|
||||||
if ($access{'pass'}) {
|
if ($access{'pass'}) {
|
||||||
push(@icons, "images/pass.gif");
|
push(@icons, "images/pass.gif");
|
||||||
push(@links, "edit_pass.cgi");
|
push(@links, "edit_pass.cgi");
|
||||||
@@ -291,7 +286,13 @@ return &ui_checkbox("d", $user->{'name'}, "", 0).
|
|||||||
($ro ? "<b>" : "").
|
($ro ? "<b>" : "").
|
||||||
&ui_link("$cgi?$param=".&urlize($user->{'name'}),
|
&ui_link("$cgi?$param=".&urlize($user->{'name'}),
|
||||||
$user->{'name'}).
|
$user->{'name'}).
|
||||||
($user->{'twofactor_id'} ? "*" : "").
|
($user->{'twofactor_id'}
|
||||||
|
? &ui_tag('sup', '⚷',
|
||||||
|
{ title => $text{'index_twofactor_enabled'},
|
||||||
|
class => 'twofactor-enabled-icon',
|
||||||
|
style => 'font-size: 11px; margin-left: 5px; cursor: default;'.
|
||||||
|
'display: inline-block; transform: rotate(90deg);' } )
|
||||||
|
: "").
|
||||||
($ro ? "</b>" : "").
|
($ro ? "</b>" : "").
|
||||||
($lck ? "</i>" : "");
|
($lck ? "</i>" : "");
|
||||||
}
|
}
|
||||||
|
|||||||
36
acl/lang/en
36
acl/lang/en
@@ -6,6 +6,7 @@ index_screate=Create a new safe user.
|
|||||||
index_convert=Convert Unix To Webmin Users
|
index_convert=Convert Unix To Webmin Users
|
||||||
index_cert=Request an SSL Certificate
|
index_cert=Request an SSL Certificate
|
||||||
index_twofactor=Two-Factor Authentication
|
index_twofactor=Two-Factor Authentication
|
||||||
|
index_twofactor_enabled=Two-factor authentication is enabled for this user
|
||||||
index_certmsg=Click this button to request an SSL certificate that will allow you to securely login to Webmin without having to enter a username and password.
|
index_certmsg=Click this button to request an SSL certificate that will allow you to securely login to Webmin without having to enter a username and password.
|
||||||
index_return=user list
|
index_return=user list
|
||||||
index_none=None
|
index_none=None
|
||||||
@@ -22,7 +23,6 @@ index_modgroups=Modules from group $1
|
|||||||
index_sync=Configure Unix User Synchronization
|
index_sync=Configure Unix User Synchronization
|
||||||
index_unix=Configure Unix User Authentication
|
index_unix=Configure Unix User Authentication
|
||||||
index_sessions=View Login Sessions
|
index_sessions=View Login Sessions
|
||||||
index_rbac=Setup RBAC
|
|
||||||
index_delete=Delete Selected
|
index_delete=Delete Selected
|
||||||
index_joingroup=Add To Group:
|
index_joingroup=Add To Group:
|
||||||
index_eulist=Failed to list users : $1
|
index_eulist=Failed to list users : $1
|
||||||
@@ -94,9 +94,6 @@ edit_switch=Switch to User
|
|||||||
edit_forgot=Send Password Reset Link
|
edit_forgot=Send Password Reset Link
|
||||||
edit_return=Webmin user
|
edit_return=Webmin user
|
||||||
edit_return2=Webmin group
|
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_global=Permissions for all modules
|
||||||
edit_templock=Temporarily locked
|
edit_templock=Temporarily locked
|
||||||
edit_temppass=Force change at next login
|
edit_temppass=Force change at next login
|
||||||
@@ -184,8 +181,6 @@ acl_title3=For group $1 in $2
|
|||||||
acl_options=$1 access control options
|
acl_options=$1 access control options
|
||||||
acl_config=Can edit module configuration?
|
acl_config=Can edit module configuration?
|
||||||
acl_reset=Reset To Full Access
|
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_uall=All users
|
||||||
acl_uthis=This user
|
acl_uthis=This user
|
||||||
@@ -355,18 +350,19 @@ unix_utable=Allowed Unix users
|
|||||||
sessions_title=Current Login Sessions
|
sessions_title=Current Login Sessions
|
||||||
sessions_id=Session ID
|
sessions_id=Session ID
|
||||||
sessions_user=Webmin user
|
sessions_user=Webmin user
|
||||||
|
sessions_login_ago=Last active ago
|
||||||
sessions_login=Last active at
|
sessions_login=Last active at
|
||||||
sessions_host=IP address
|
sessions_host=IP address
|
||||||
sessions_lview=View logs..
|
sessions_lview=View logs
|
||||||
sessions_actions=Actions..
|
sessions_actions=Actions
|
||||||
sessions_all=All sessions..
|
sessions_all=All sessions
|
||||||
sessions_logouts=Also show logged-out sessions..
|
sessions_logouts=Also show logged-out sessions
|
||||||
sessions_state=State
|
sessions_state=State
|
||||||
sessions_action=Actions
|
sessions_action=Actions
|
||||||
sessions_this=This login
|
sessions_this=This login
|
||||||
sessions_in=Logged in
|
sessions_in=Logged in
|
||||||
sessions_out=Logged out
|
sessions_out=Logged out
|
||||||
sessions_kill=Disconnect..
|
sessions_kill=Disconnect
|
||||||
|
|
||||||
logins_title=Recent Webmin logins
|
logins_title=Recent Webmin logins
|
||||||
|
|
||||||
@@ -380,13 +376,6 @@ hide_clone=(Clone $1)
|
|||||||
switch_euser=You are not allowed to switch to this user
|
switch_euser=You are not allowed to switch to this user
|
||||||
switch_eold=Existing session not found!
|
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_err=Failed to delete users
|
||||||
udeletes_jerr=Failed to add users to group
|
udeletes_jerr=Failed to add users to group
|
||||||
udeletes_enone=None selected
|
udeletes_enone=None selected
|
||||||
@@ -512,9 +501,18 @@ twofactor_enable=Enroll For Two-Factor Authentication
|
|||||||
twofactor_header=Two-factor authentication enrollment details
|
twofactor_header=Two-factor authentication enrollment details
|
||||||
twofactor_enrolling=Enrolling for two-factor authentication with provider $1 ..
|
twofactor_enrolling=Enrolling for two-factor authentication with provider $1 ..
|
||||||
twofactor_failed=.. enrollment failed : $1
|
twofactor_failed=.. enrollment failed : $1
|
||||||
twofactor_done=.. complete. Your ID with this provider is <tt>$1</tt>.
|
twofactor_done=.. completed, with ID <tt>$1</tt>
|
||||||
twofactor_setup=Two-factor authentication has not been enabled on this system yet, but can be turned on using the <a href='$1'>Webmin Configuration</a> module.
|
twofactor_setup=Two-factor authentication has not been enabled on this system yet, but can be turned on using the <a href='$1'>Webmin Configuration</a> module.
|
||||||
twofactor_ebutton=No button clicked!
|
twofactor_ebutton=No button clicked!
|
||||||
|
twofactor_testdesc=Before logging out, you can test your new two-factor authentication setup here by entering a token. If for some reason it doesn't work, turn off two-factor authentication and try setting it up again.
|
||||||
|
twofactor_testfield=Two-factor token
|
||||||
|
twofactor_test=Validate Token
|
||||||
|
twofactor_terr=Failed to test two-factor setup
|
||||||
|
twofactor_etestuser=Login does not have two-factor enabled!
|
||||||
|
twofactor_testing=Testing two-factor validation with $1 ..
|
||||||
|
twofactor_testfailed=.. test failed! Maybe the wrong token was entered, or your authentication app has not been configured correctly?
|
||||||
|
twofactor_testok=.. test passed! You can now safely login using two-factor authentication.
|
||||||
|
twofactor_testdis=Disable Two-Factor Now
|
||||||
|
|
||||||
forgot_title=Send Password Reset Link
|
forgot_title=Send Password Reset Link
|
||||||
forgot_err=Failed to send password reset link
|
forgot_err=Failed to send password reset link
|
||||||
|
|||||||
100
acl/lang/no
100
acl/lang/no
@@ -1,9 +1,9 @@
|
|||||||
index_title=Webmin Brukere
|
index_title=Webmin Brukere
|
||||||
index_user=Brukere
|
index_user=Brukere
|
||||||
index_modules=Moduler
|
index_modules=Moduler
|
||||||
index_create=Opprett ny Webmin bruker
|
index_create=Opprett ny Webmin-bruker
|
||||||
index_screate=Opprett ny sikker bruker
|
index_screate=Opprett ny sikker bruker
|
||||||
index_convert=Konverter Unix til Webmin brukere
|
index_convert=Konverter Unix til Webmin-brukere
|
||||||
index_cert=Krever SSL sertifikat
|
index_cert=Krever SSL sertifikat
|
||||||
index_twofactor=To-faktor autentisering
|
index_twofactor=To-faktor autentisering
|
||||||
index_certmsg=Klikk på denne knappen for å spørre etter et SSL sertifikat som vil gi deg sikker login i Webmin uten å måtte skrive brukernavn og passord.
|
index_certmsg=Klikk på denne knappen for å spørre etter et SSL sertifikat som vil gi deg sikker login i Webmin uten å måtte skrive brukernavn og passord.
|
||||||
@@ -14,7 +14,7 @@ index_global=Global ACL
|
|||||||
index_users=Webmin Brukere
|
index_users=Webmin Brukere
|
||||||
index_groups=Webmin Grupper
|
index_groups=Webmin Grupper
|
||||||
index_group=Gruppe
|
index_group=Gruppe
|
||||||
index_nousers=Ingen editerbar Webmin bruker er definert.
|
index_nousers=Ingen editerbar Webmin-bruker er definert.
|
||||||
index_nogroups=Ingen editerbar Webmin gruppe er definert.
|
index_nogroups=Ingen editerbar Webmin gruppe er definert.
|
||||||
index_gcreate=Lag en ny Webmin gruppe
|
index_gcreate=Lag en ny Webmin gruppe
|
||||||
index_members=Medlemmer
|
index_members=Medlemmer
|
||||||
@@ -30,11 +30,11 @@ index_eglist=Kunne ikke liste grupper : $1
|
|||||||
|
|
||||||
edit_title=Rediger Webmin Bruker
|
edit_title=Rediger Webmin Bruker
|
||||||
edit_title2=Lag Webmin Bruker
|
edit_title2=Lag Webmin Bruker
|
||||||
edit_title3=Opprett sikker Webmin bruker
|
edit_title3=Opprett sikker Webmin-bruker
|
||||||
edit_readonly=Denne Webmin brukeren bør ikke redigeres siden den vedlikeholdes av modulen $1. <a href='$2'>Klikk her</a> for å ignorere denne advarselen og redigere brukeren allikevel - men vær oppmerksom på at manuelle endringer kan bli overskrevet!
|
edit_readonly=Denne Webmin-brukeren bør ikke redigeres siden den vedlikeholdes av modulen $1. <a href='$2'>Klikk her</a> for å ignorere denne advarselen og redigere brukeren allikevel - men vær oppmerksom på at manuelle endringer kan bli overskrevet!
|
||||||
edit_rights=Tilgangsrettigheter for Webmin bruker
|
edit_rights=Tilgangsrettigheter for Webmin-bruker
|
||||||
edit_user=Brukernavn
|
edit_user=Brukernavn
|
||||||
edit_cloneof=Klober Webmin bruker
|
edit_cloneof=Klober Webmin-bruker
|
||||||
edit_real=Virkelig navn
|
edit_real=Virkelig navn
|
||||||
edit_group=Medlem av gruppe
|
edit_group=Medlem av gruppe
|
||||||
edit_pass=Passord
|
edit_pass=Passord
|
||||||
@@ -89,7 +89,7 @@ edit_selall=Velg alle
|
|||||||
edit_invert=Inverter valg
|
edit_invert=Inverter valg
|
||||||
edit_hide=Skjul ubrukte
|
edit_hide=Skjul ubrukte
|
||||||
edit_switch=Bytt til bruker
|
edit_switch=Bytt til bruker
|
||||||
edit_return=Webmin bruker
|
edit_return=Webmin-bruker
|
||||||
edit_return2=Webmin gruppe
|
edit_return2=Webmin gruppe
|
||||||
edit_rbacdeny=RBAC tilgangsmodus
|
edit_rbacdeny=RBAC tilgangsmodus
|
||||||
edit_rbacdeny0=RBAC kontrollerer valgte modul ACLer
|
edit_rbacdeny0=RBAC kontrollerer valgte modul ACLer
|
||||||
@@ -126,21 +126,21 @@ save_eoverlay=Et tema-overlegg kan ikke velges med mindre et tema er
|
|||||||
save_edeny=Du kan ikke nekte deg selv tilgang til Webmin Bruker modulen
|
save_edeny=Du kan ikke nekte deg selv tilgang til Webmin Bruker modulen
|
||||||
save_eos=Det samme som Unix passord opsjonen er ikke støttet på ditt operativsystem.
|
save_eos=Det samme som Unix passord opsjonen er ikke støttet på ditt operativsystem.
|
||||||
save_emd5=Det samme som Unix passord opsjonen kan ikke brukes på systemer med MD5 kryptering
|
save_emd5=Det samme som Unix passord opsjonen kan ikke brukes på systemer med MD5 kryptering
|
||||||
save_eunix=Unix bruker '$1' eksisterer ikke
|
save_eunix=Unix-brukeren '$1' eksisterer ikke
|
||||||
save_emod=Du kan ikke bevilge tilgang til modul '$1'
|
save_emod=Du kan ikke bevilge tilgang til modul '$1'
|
||||||
save_ecreate=Du har ikke tilgang til å opprette brukere
|
save_ecreate=Du har ikke tilgang til å opprette brukere
|
||||||
save_euser=Du har ikke tilgang til å editere denne brukeren
|
save_euser=Du har ikke tilgang til å redigere denne brukeren
|
||||||
save_ecolon=Passord kan ikke inneholde : karakteren
|
save_ecolon=Passord kan ikke inneholde : karakteren
|
||||||
save_epass=Passord er ikke gyldig : $1
|
save_epass=Passord er ikke gyldig : $1
|
||||||
save_eself=Din vanlige IP adresse ($1) vil bli nektet
|
save_eself=Din vanlige IP-adresse ($1) vil bli nektet
|
||||||
save_epam=PAM autentisering er ikke tilgjengelig fordi <tt>Authen::PAM</tt> Perl modulen ikke er installert eller ikke virker ordentlig.
|
save_epam=PAM autentisering er ikke tilgjengelig fordi <tt>Authen::PAM</tt> Perl modulen ikke er installert eller ikke virker ordentlig.
|
||||||
save_epam2=Du kan bruke Webmin's Perl Modules modul til <a href='$1'>laste ned å installere Authen::PAM</a> nå.
|
save_epam2=Du kan bruke Webmin's Perl Modules modul til <a href='$1'>laste ned å installere Authen::PAM</a> nå.
|
||||||
save_egroup=Du har ikke rettigheter til å tildele til den gruppen
|
save_egroup=Du har ikke rettigheter til å tildele til den gruppen
|
||||||
save_enone=Ingen adresse er tastet inn
|
save_enone=Ingen adresse er tastet inn
|
||||||
save_enet='$1' er ikke en gyldig nettverks adresse
|
save_enet='$1' er ikke en gyldig nettverksadresse
|
||||||
save_emask='$1' er ikke en gyldig nettmaske
|
save_emask='$1' er ikke en gyldig nettmaske
|
||||||
save_eip='$1' er ikke en komplett IP eller nettverks adresse
|
save_eip='$1' er ikke en komplett IP eller nettverksadresse
|
||||||
save_ehost=Kunne ikke finne IP adresse for '$1'
|
save_ehost=Kunne ikke finne IP-adresse for '$1'
|
||||||
save_elogouttime=Manglende eller ikke-numerisk tid for utlogging ved inaktivitet
|
save_elogouttime=Manglende eller ikke-numerisk tid for utlogging ved inaktivitet
|
||||||
save_eminsize=Manglende eller ikke-numerisk minimum passordlengde
|
save_eminsize=Manglende eller ikke-numerisk minimum passordlengde
|
||||||
save_edays=Ingen tillatte dager valgt
|
save_edays=Ingen tillatte dager valgt
|
||||||
@@ -223,11 +223,11 @@ acl_times=Kan endre tillatte innloggings-tider?
|
|||||||
acl_pass=Kan endre passord-begrensinger?
|
acl_pass=Kan endre passord-begrensinger?
|
||||||
acl_sql=Kan konfigurere databasen for brukere og grupper?
|
acl_sql=Kan konfigurere databasen for brukere og grupper?
|
||||||
|
|
||||||
log_modify=Modifisert Webmin bruker $1
|
log_modify=Modifisert Webmin-bruker $1
|
||||||
log_rename=Skiftet navn på Webmin bruker $1 til $2
|
log_rename=Skiftet navn på Webmin-bruker $1 til $2
|
||||||
log_create=Opprettet Webmin bruker $1
|
log_create=Opprettet Webmin-bruker $1
|
||||||
log_clone=Klonet Webmin bruker $1 til $2
|
log_clone=Klonet Webmin-bruker $1 til $2
|
||||||
log_delete=Slettet Webmin bruker $1
|
log_delete=Slettet Webmin-bruker $1
|
||||||
log_acl=Oppdatert tilgang for $1 i $2
|
log_acl=Oppdatert tilgang for $1 i $2
|
||||||
log_reset=Tilbakestilte tilgang for $1 i $2
|
log_reset=Tilbakestilte tilgang for $1 i $2
|
||||||
log_cert=Utlevert sertifikat for bruker $1
|
log_cert=Utlevert sertifikat for bruker $1
|
||||||
@@ -235,10 +235,10 @@ log_modify_g=Modifisert Webmin gruppe $1
|
|||||||
log_rename_g=Forandret navn på Webmin gruppe $1 til $2
|
log_rename_g=Forandret navn på Webmin gruppe $1 til $2
|
||||||
log_create_g=Opprettet Webmin gruppe $1
|
log_create_g=Opprettet Webmin gruppe $1
|
||||||
log_delete_g=Slettet Webmin gruppe $1
|
log_delete_g=Slettet Webmin gruppe $1
|
||||||
log_switch=Byttet til Webmin bruker $1
|
log_switch=Byttet til Webmin-bruker $1
|
||||||
log_delete_users=Slettet $1 Webmin brukere
|
log_delete_users=Slettet $1 Webmin-brukere
|
||||||
log_delete_groups=Slettet $1 Webmin grupper
|
log_delete_groups=Slettet $1 Webmin grupper
|
||||||
log_joingroup=La til $1 Webmin brukere i gruppe $2
|
log_joingroup=La til $1 Webmin-brukere i gruppe $2
|
||||||
log_pass=Endret passord-begrensinger
|
log_pass=Endret passord-begrensinger
|
||||||
log_unix=Endret unix bruker-autentisering
|
log_unix=Endret unix bruker-autentisering
|
||||||
log_sync=Endret unix bruker-synkronisering
|
log_sync=Endret unix bruker-synkronisering
|
||||||
@@ -273,7 +273,7 @@ gsave_edesc=Ugyldig beskrivelse - tegnet : er ikke tillatt
|
|||||||
convert_title=Konverter Brukere
|
convert_title=Konverter Brukere
|
||||||
convert_ecannot=Du har ikke tilgang til å konvertere Unix brukere
|
convert_ecannot=Du har ikke tilgang til å konvertere Unix brukere
|
||||||
convert_nogroups=Ingen Webmin gruppe er definert på ditt system. Du må i det minste lage en gruppe før du konverterer brukere, dette for å kunne sette rettigheter for konverterte brukere.
|
convert_nogroups=Ingen Webmin gruppe er definert på ditt system. Du må i det minste lage en gruppe før du konverterer brukere, dette for å kunne sette rettigheter for konverterte brukere.
|
||||||
convert_desc=Denne Dette feltet lar deg konvertere eksisterende Unix brukere til Webmin brukere. Rettighetene til hver nye Webmin bruker vil bestemmes av rettighetene til gruppen som valgt over.
|
convert_desc=Denne Dette feltet lar deg konvertere eksisterende Unix-brukere til Webmin-brukere. Rettighetene til hver nye Webmin-bruker vil bestemmes av rettighetene til gruppen som valgt over.
|
||||||
convert_0=Alle brukere
|
convert_0=Alle brukere
|
||||||
convert_1=Bare brukere
|
convert_1=Bare brukere
|
||||||
convert_2=Alle unntagen brukere
|
convert_2=Alle unntagen brukere
|
||||||
@@ -284,43 +284,43 @@ convert_sync2=Synk. passord med Unix-bruker i fremtiden?
|
|||||||
convert_ok=Konverter nå
|
convert_ok=Konverter nå
|
||||||
convert_err=Kunne ikke konvertere brukere
|
convert_err=Kunne ikke konvertere brukere
|
||||||
convert_eusers=Ingen brukere inntastet
|
convert_eusers=Ingen brukere inntastet
|
||||||
convert_egroup=Unix gruppe eksisterer ikke
|
convert_egroup=Unix-gruppen eksisterer ikke
|
||||||
convert_emin=Ugyldig minimum bruker ID (UID)
|
convert_emin=Ugyldig minimum bruker-ID (UID)
|
||||||
convert_emax=Ugyldig maksimum bruker ID (UID)
|
convert_emax=Ugyldig maksimum bruker-ID (UID)
|
||||||
convert_ewgroup=Ingen sånn Webmin gruppe
|
convert_ewgroup=Ingen sånn Webmin gruppe
|
||||||
convert_ewgroup2=Du har ikke rettigheter til å tilordne nye brukere til denne gruppen
|
convert_ewgroup2=Du har ikke rettigheter til å tilordne nye brukere til denne gruppen
|
||||||
convert_skip=Hoppet over $1
|
convert_skip=Hoppet over $1
|
||||||
convert_exists=$1 Eksisterer allerede
|
convert_exists=$1 Eksisterer allerede
|
||||||
convert_invalid=$1 er ikke et gyldig Webmin brukernavn
|
convert_invalid=$1 er ikke et gyldig Webmin-brukernavn
|
||||||
convert_added=$1 er lagt til
|
convert_added=$1 er lagt til
|
||||||
convert_msg=Konverterer Unix brukere...
|
convert_msg=Konverterer Unix-brukere...
|
||||||
convert_user=Unix-bruker
|
convert_user=Unix-bruker
|
||||||
convert_action=Handling utført
|
convert_action=Handling utført
|
||||||
convert_done=$1 brukere konvertert, $2 ugyldig, $3 finnes allerede, $4 ekskludert.
|
convert_done=$1 brukere konvertert, $2 ugyldig, $3 finnes allerede, $4 ekskludert.
|
||||||
convert_users=Brukere som skal konverteres
|
convert_users=Brukere som skal konverteres
|
||||||
|
|
||||||
sync_title=Unix Bruker Synkronisering
|
sync_title=Unix-brukersynkronisering
|
||||||
sync_desc=Dette feltet lar deg konfigurere automatisk synkronisering av Unix brukere laget via Webmin og brukere i denne modulen.
|
sync_desc=Dette feltet lar deg konfigurere automatisk synkronisering av Unix-brukere laget via Webmin og brukere i denne modulen.
|
||||||
sync_nogroups=Ingen Webmin gruppe er definert på ditt system. Du må i det minste lage en gruppe før du konverterer brukere, dette for å kunne sette rettigheter for konverterte brukere.
|
sync_nogroups=Ingen Webmin gruppe er definert på ditt system. Du må i det minste lage en gruppe før du konverterer brukere, dette for å kunne sette rettigheter for konverterte brukere.
|
||||||
sync_when=Synkroniser når
|
sync_when=Synkroniser når
|
||||||
sync_create=Opprett Webmin bruker når en Unix bruker blir laget.
|
sync_create=Opprett Webmin-bruker når en Unix bruker blir laget.
|
||||||
sync_update=Oppdater passende Webmin bruker når Unix brukere blir oppdatert.
|
sync_update=Oppdater passende Webmin-bruker når Unix-brukere blir oppdatert.
|
||||||
sync_delete=Slett passende Webmin bruker når Unix brukere blir slettet.
|
sync_delete=Slett passende Webmin-bruker når Unix-brukere blir slettet.
|
||||||
sync_group=Tilordne ny bruker til Webmin gruppe
|
sync_group=Tilordne ny bruker til Webmin gruppe
|
||||||
sync_unix=Sett passord for nye brukere til Unix autentisering
|
sync_unix=Sett passord for nye brukere til Unix autentisering
|
||||||
sync_ecannot=Du har ikke rettigheter til å konfigurere bruker synkronisering.
|
sync_ecannot=Du har ikke rettigheter til å konfigurere bruker synkronisering.
|
||||||
|
|
||||||
unix_title=Unix Bruker Autentisering
|
unix_title=Unix-brukerautentisering
|
||||||
unix_err=Kunne ikke lagre Unix autentisering
|
unix_err=Kunne ikke lagre Unix autentisering
|
||||||
unix_desc=Denne siden lar deg konfigurere Webmin til verifisere login forsøk med systemets bruker liste og PAM. Dette kan være nyttig hvis du har mange eksisterende Unix brukere som du ønsker å gi tilgang til Webmin.
|
unix_desc=Denne siden lar deg konfigurere Webmin til verifisere login forsøk med systemets bruker liste og PAM. Dette kan være nyttig hvis du har mange eksisterende Unix-brukere som du ønsker å gi tilgang til Webmin.
|
||||||
unix_def=Tillat bare login av Webmin brukere
|
unix_def=Tillat bare login av Webmin-brukere
|
||||||
unix_sel=Tillat Unix brukere i listen nedenfor å logge inn ..
|
unix_sel=Tillat Unix-brukere i listen nedenfor å logge inn ..
|
||||||
unix_mode=Tillat
|
unix_mode=Tillat
|
||||||
unix_mall=Alle brukere
|
unix_mall=Alle brukere
|
||||||
unix_group=Medlemmer i gruppen..
|
unix_group=Medlemmer i gruppen..
|
||||||
unix_user=Tillat alle Unix brukere login med rettigheter som Users
|
unix_user=Tillat alle Unix-brukere login med rettigheter som Users
|
||||||
unix_who=Bruker eller gruppe
|
unix_who=Bruker eller gruppe
|
||||||
unix_to=Som Webmin bruker
|
unix_to=Som Webmin-bruker
|
||||||
unix_ecannot=Du har ikke rettigheter til å konfigurere Unix bruker autentisering
|
unix_ecannot=Du har ikke rettigheter til å konfigurere Unix bruker autentisering
|
||||||
unix_epam=Unix autentisering er ikke tilgjengelig fordi <tt>Authen::PAM</tt> Perl modul ikke er installert eller ikke virker som den skal.
|
unix_epam=Unix autentisering er ikke tilgjengelig fordi <tt>Authen::PAM</tt> Perl modul ikke er installert eller ikke virker som den skal.
|
||||||
unix_all=Tillat alle Unix brukere
|
unix_all=Tillat alle Unix brukere
|
||||||
@@ -329,12 +329,12 @@ unix_deny=Nekt listede Unix brukere
|
|||||||
unix_none=Ingen brukere angitt
|
unix_none=Ingen brukere angitt
|
||||||
unix_euser='$1' er ikke et gyldig brukernavn
|
unix_euser='$1' er ikke et gyldig brukernavn
|
||||||
unix_egroup='$1' er ikke et gyldig gruppenavn
|
unix_egroup='$1' er ikke et gyldig gruppenavn
|
||||||
unix_shells=Nekt Unix brukere hvis skall ikke finnes i filen
|
unix_shells=Nekt Unix-brukere hvis skall ikke finnes i filen
|
||||||
unix_eshells=Manglende eller ikke-eksisterende shells fil
|
unix_eshells=Manglende eller ikke-eksisterende shells fil
|
||||||
unix_restrict2=Ekstra restriksjoner
|
unix_restrict2=Ekstra restriksjoner
|
||||||
unix_ewhogroup=Manglende tillatt gruppe i rad $1
|
unix_ewhogroup=Manglende tillatt gruppe i rad $1
|
||||||
unix_ewhouser=Manglende tilllatt bruker i rad $1
|
unix_ewhouser=Manglende tilllatt bruker i rad $1
|
||||||
unix_enone=Ingen tillatte Unix brukere og grupper ble angitt
|
unix_enone=Ingen tillatte Unix-brukere og grupper ble angitt
|
||||||
unix_same=<Samme bruker eller gruppe>
|
unix_same=<Samme bruker eller gruppe>
|
||||||
unix_sudo=TIllatt brukere som kan kjøre alle kommandoer via <tt>sudo</tt> å logge inn som <tt>root</tt>
|
unix_sudo=TIllatt brukere som kan kjøre alle kommandoer via <tt>sudo</tt> å logge inn som <tt>root</tt>
|
||||||
unix_pamany=Behandle brukere som bare sender PAM validering som $1
|
unix_pamany=Behandle brukere som bare sender PAM validering som $1
|
||||||
@@ -345,9 +345,9 @@ unix_utable=Tillatte Unix brukere
|
|||||||
|
|
||||||
sessions_title=Aktuell Login Session
|
sessions_title=Aktuell Login Session
|
||||||
sessions_id=Sessions ID
|
sessions_id=Sessions ID
|
||||||
sessions_user=Webmin bruker
|
sessions_user=Webmin-bruker
|
||||||
sessions_login=Innlogget
|
sessions_login=Innlogget
|
||||||
sessions_host=IP adresse
|
sessions_host=IP-adresse
|
||||||
sessions_lview=Se logger..
|
sessions_lview=Se logger..
|
||||||
sessions_actions=Handlinger..
|
sessions_actions=Handlinger..
|
||||||
sessions_logouts=Vis også utloggede sesjoner..
|
sessions_logouts=Vis også utloggede sesjoner..
|
||||||
@@ -357,7 +357,7 @@ sessions_in=Innlogget
|
|||||||
sessions_out=Logget ut
|
sessions_out=Logget ut
|
||||||
sessions_kill=Koble fra..
|
sessions_kill=Koble fra..
|
||||||
|
|
||||||
logins_title=Siste Webmin innlogginger
|
logins_title=Siste Webmin-innlogginger
|
||||||
|
|
||||||
hide_title=Skjul ubrukte moduler
|
hide_title=Skjul ubrukte moduler
|
||||||
hide_desc=Følgende moduler vil bli fjernet fra modul tilgangslisten for $1 siden deres tilhørende tjenere ikke er installert på systemet ditt ..
|
hide_desc=Følgende moduler vil bli fjernet fra modul tilgangslisten for $1 siden deres tilhørende tjenere ikke er installert på systemet ditt ..
|
||||||
@@ -374,7 +374,7 @@ rbac_desc=Webmin's RBAC integration provides a way for user module and ACL permi
|
|||||||
rbac_esolaris=RBAC støttes bare på Solaris systemer for øyeblikket, og kan derfor ikke brukes på dette $1 systemet.
|
rbac_esolaris=RBAC støttes bare på Solaris systemer for øyeblikket, og kan derfor ikke brukes på dette $1 systemet.
|
||||||
rbac_eperl=Perl-modulen $1, som behøves for RBAC integrasjon, er ikke installert. <a href='$2'>Klikk her</a> for å installere den nå.
|
rbac_eperl=Perl-modulen $1, som behøves for RBAC integrasjon, er ikke installert. <a href='$2'>Klikk her</a> for å installere den nå.
|
||||||
rbac_ecpan=Du har ikke tilgang til Webmins Perl Moduler side for å kunne installere den nødvendige $1 modulen for RBAC integrasjon.
|
rbac_ecpan=Du har ikke tilgang til Webmins Perl Moduler side for å kunne installere den nødvendige $1 modulen for RBAC integrasjon.
|
||||||
rbac_ok=RBAC integrasjon er tilgjengelig for dette systemet, og kan aktiveres per bruker på siden Rediger Webmin bruker.
|
rbac_ok=RBAC integrasjon er tilgjengelig for dette systemet, og kan aktiveres per bruker på siden Rediger Webmin-bruker.
|
||||||
|
|
||||||
udeletes_err=Kunne ikke slette brukere
|
udeletes_err=Kunne ikke slette brukere
|
||||||
udeletes_jerr=Kunne ikke legg til brukere i gruppe
|
udeletes_jerr=Kunne ikke legg til brukere i gruppe
|
||||||
@@ -391,7 +391,7 @@ gdeletes_rusure=Er du sikker på at du ønsker å slette de $1 valgte gruppene o
|
|||||||
gdeletes_users=Valgte grupper: $1
|
gdeletes_users=Valgte grupper: $1
|
||||||
gdeletes_ok=Slett grupper
|
gdeletes_ok=Slett grupper
|
||||||
|
|
||||||
pass_title=Passord begrensinger
|
pass_title=Passordbegrensinger
|
||||||
pass_ecannot=Du har ikke lov til å redigere passord-begrensinger
|
pass_ecannot=Du har ikke lov til å redigere passord-begrensinger
|
||||||
pass_header=Innstillinger for Webmin passord begrensinger
|
pass_header=Innstillinger for Webmin passord begrensinger
|
||||||
pass_minsize=Minimum passordlengde
|
pass_minsize=Minimum passordlengde
|
||||||
@@ -424,7 +424,7 @@ cpass_old=Gamle passord kan ikke brukes på nytt
|
|||||||
|
|
||||||
sql_title=Bruker- og gruppe-database
|
sql_title=Bruker- og gruppe-database
|
||||||
sql_ecannot=Du har ikke lov til å konfigurere bruker- og gruppedatabasen
|
sql_ecannot=Du har ikke lov til å konfigurere bruker- og gruppedatabasen
|
||||||
sql_header=Instillinger for database backend for brukere og grupper
|
sql_header=Innstillinger for database backend for brukere og grupper
|
||||||
sql_host=Vertsnavn
|
sql_host=Vertsnavn
|
||||||
sql_user=Brukernavn
|
sql_user=Brukernavn
|
||||||
sql_pass=Passord
|
sql_pass=Passord
|
||||||
@@ -456,7 +456,7 @@ sql_edb=Ugyldig databasenavn (mellomrom ikke tillatt)
|
|||||||
sql_eprefix=Manglende eller ugyldig base DN (mellomrom ikke tillatt)
|
sql_eprefix=Manglende eller ugyldig base DN (mellomrom ikke tillatt)
|
||||||
sql_eprefix2=Ugyldig-utseende base DN - skal være på formen <tt>dc=mittdomene,dc=no</tt>
|
sql_eprefix2=Ugyldig-utseende base DN - skal være på formen <tt>dc=mittdomene,dc=no</tt>
|
||||||
sql_title2=Opprett manglende tabeller
|
sql_title2=Opprett manglende tabeller
|
||||||
sql_tableerr=Instillinger for bruker- og gruppedatabase er gyldig, men noen tabeller som Webmin trenger, mangler : $1
|
sql_tableerr=Innstillinger for bruker- og gruppedatabase er gyldig, men noen tabeller som Webmin trenger, mangler : $1
|
||||||
sql_tableerr2=Klikk på knappen <b>Opprett tabeller</b> nedenfor, for å få opprettet dem automatisk, eller du kan kjøre SQL uttrykket nedenfor manuelt.
|
sql_tableerr2=Klikk på knappen <b>Opprett tabeller</b> nedenfor, for å få opprettet dem automatisk, eller du kan kjøre SQL uttrykket nedenfor manuelt.
|
||||||
sql_make=Opprett tabeller
|
sql_make=Opprett tabeller
|
||||||
sql_title3=Opprett manglende DN
|
sql_title3=Opprett manglende DN
|
||||||
@@ -489,7 +489,7 @@ twofactor_title=To-faktor autentisering
|
|||||||
twofactor_disable=Deaktiver to-faktor autentisering
|
twofactor_disable=Deaktiver to-faktor autentisering
|
||||||
twofactor_already=Din Webmin-bruker har allerede to-faktor autentisering aktivert med leverandør %1 og konto ID %2.
|
twofactor_already=Din Webmin-bruker har allerede to-faktor autentisering aktivert med leverandør %1 og konto ID %2.
|
||||||
twofactor_already2=Webmin-brukeren %3 har allerede to-faktor autentisering aktivert med leverandør %1 og konto ID %2.
|
twofactor_already2=Webmin-brukeren %3 har allerede to-faktor autentisering aktivert med leverandør %1 og konto ID %2.
|
||||||
twofactor_desc=Denne siden lar deg aktivere to-faktor autentisering for din Webmin bruker vha. <a href='$2' target=_blank>$1</a>. Når denne er aktivert kreves det et ekstra autentiserings-token når du logger inn på Webmin.
|
twofactor_desc=Denne siden lar deg aktivere to-faktor autentisering for din Webmin-bruker vha. <a href='$2' target=_blank>$1</a>. Når denne er aktivert kreves det et ekstra autentiserings-token når du logger inn på Webmin.
|
||||||
twofactor_desc2=Denne siden lar deg aktivere to-faktor autentisering for Webmin-brukeren $1 vha. <a href='$2' target=_blank>$1</a>. Når denne er aktivert vil det kreves et ekstra autentiserings-token for å logge inn på Webmin.
|
twofactor_desc2=Denne siden lar deg aktivere to-faktor autentisering for Webmin-brukeren $1 vha. <a href='$2' target=_blank>$1</a>. Når denne er aktivert vil det kreves et ekstra autentiserings-token for å logge inn på Webmin.
|
||||||
twofactor_enable=Meld inn til to-faktor autentisering
|
twofactor_enable=Meld inn til to-faktor autentisering
|
||||||
twofactor_header=Detaljer for innmelding til to-faktor autentisering
|
twofactor_header=Detaljer for innmelding til to-faktor autentisering
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, %sessiondb);
|
our (%in, %text, %config, %access, %sessiondb);
|
||||||
$access{'sessions'} || &error($text{'sessions_ecannot'});
|
$access{'sessions'} || &error($text{'sessions_ecannot'});
|
||||||
&ui_print_header(undef, $text{'sessions_title'}, "");
|
&ui_print_header(undef, $text{'sessions_title'}, "");
|
||||||
@@ -28,7 +28,7 @@ print &ui_columns_start([ $text{'sessions_id'},
|
|||||||
$text{'sessions_state'},
|
$text{'sessions_state'},
|
||||||
$text{'sessions_user'},
|
$text{'sessions_user'},
|
||||||
$text{'sessions_host'},
|
$text{'sessions_host'},
|
||||||
$text{'sessions_login'},
|
$text{'sessions_login_ago'},
|
||||||
$text{'sessions_actions'},
|
$text{'sessions_actions'},
|
||||||
], 100);
|
], 100);
|
||||||
foreach my $k (sort { my @a = split(/\s+/, $sessiondb{$a});
|
foreach my $k (sort { my @a = split(/\s+/, $sessiondb{$a});
|
||||||
@@ -68,7 +68,8 @@ foreach my $k (sort { my @a = split(/\s+/, $sessiondb{$a});
|
|||||||
push(@cols, $user);
|
push(@cols, $user);
|
||||||
}
|
}
|
||||||
push(@cols, $lip);
|
push(@cols, $lip);
|
||||||
push(@cols, &make_date($ltime));
|
push(@cols, &make_date_relative($ltime).
|
||||||
|
" ".&ui_help(&make_date($ltime)));
|
||||||
my @links;
|
my @links;
|
||||||
if ($haslog) {
|
if ($haslog) {
|
||||||
push(@links, ui_link("../webminlog/search.cgi?uall=1&mall=1&tall=1&wall=1&fall=1&sid=$k", $text{'sessions_lview'}));
|
push(@links, ui_link("../webminlog/search.cgi?uall=1&mall=1&tall=1&wall=1&fall=1&sid=$k", $text{'sessions_lview'}));
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ my ($user, $script, $action, $type, $object, $p) = @_;
|
|||||||
my $g = $type eq 'group' ? "_g" : "";
|
my $g = $type eq 'group' ? "_g" : "";
|
||||||
if ($action eq 'modify') {
|
if ($action eq 'modify') {
|
||||||
if ($p->{'old'} ne $p->{'name'}) {
|
if ($p->{'old'} ne $p->{'name'}) {
|
||||||
return &text('log_rename'.$g, "<tt>$p->{'old'}</tt>",
|
return &text('log_rename'.$g,
|
||||||
"<tt>$p->{'name'}</tt>");
|
"<tt>".&html_escape($p->{'old'})."</tt>",
|
||||||
|
"<tt>".&html_escape($p->{'name'})."</tt>");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return &text('log_modify'.$g,
|
return &text('log_modify'.$g,
|
||||||
@@ -26,7 +27,8 @@ if ($action eq 'modify') {
|
|||||||
}
|
}
|
||||||
elsif ($action eq 'create') {
|
elsif ($action eq 'create') {
|
||||||
if ($p->{'clone'}) {
|
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>");
|
"<tt>".&html_escape($object)."</tt>");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -36,21 +38,23 @@ elsif ($action eq 'create') {
|
|||||||
}
|
}
|
||||||
elsif ($action eq 'delete') {
|
elsif ($action eq 'delete') {
|
||||||
if ($type eq "users" || $type eq "groups") {
|
if ($type eq "users" || $type eq "groups") {
|
||||||
return &text('log_delete_'.$type, $object);
|
return &text('log_delete_'.$type, &html_escape($object));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return &text('log_delete'.$g, "<tt>$object</tt>");
|
return &text('log_delete'.$g,
|
||||||
|
"<tt>".&html_escape($object)."</tt>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elsif ($action eq 'joingroup') {
|
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') {
|
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>");
|
"<i>".&html_escape($p->{'moddesc'})."</i>");
|
||||||
}
|
}
|
||||||
elsif ($action eq 'reset') {
|
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>");
|
"<i>".&html_escape($p->{'moddesc'})."</i>");
|
||||||
}
|
}
|
||||||
elsif ($action eq 'cert') {
|
elsif ($action eq 'cert') {
|
||||||
@@ -60,7 +64,9 @@ elsif ($action eq 'switch') {
|
|||||||
return &text('log_switch', "<tt>".&html_escape($object)."</tt>");
|
return &text('log_switch', "<tt>".&html_escape($object)."</tt>");
|
||||||
}
|
}
|
||||||
elsif ($action eq 'twofactor') {
|
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') {
|
elsif ($action eq 'forgot') {
|
||||||
return &text('log_forgot_'.$type, &html_escape($p->{'user'}),
|
return &text('log_forgot_'.$type, &html_escape($p->{'user'}),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require 'acl-lib.pl';
|
require 'acl-lib.pl'; ## no critic
|
||||||
our ($config_directory);
|
our ($config_directory);
|
||||||
|
|
||||||
# Rename the .acl files for any groups to .gacl files
|
# Rename the .acl files for any groups to .gacl files
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user, %gconfig,
|
our (%in, %text, %config, %access, $base_remote_user, %gconfig,
|
||||||
$config_directory);
|
$config_directory);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
@@ -54,13 +54,8 @@ else {
|
|||||||
if (defined($in{'noconfig'})) {
|
if (defined($in{'noconfig'})) {
|
||||||
$maccess{'noconfig'} = $in{'noconfig'};
|
$maccess{'noconfig'} = $in{'noconfig'};
|
||||||
}
|
}
|
||||||
if ($in{'rbac'}) {
|
if (-r "../$in{'_acl_mod'}/acl_security.pl") {
|
||||||
# RBAC overrides everything
|
|
||||||
$maccess{'rbac'} = 1;
|
|
||||||
}
|
|
||||||
elsif (-r "../$in{'_acl_mod'}/acl_security.pl") {
|
|
||||||
# Use user inputs
|
# Use user inputs
|
||||||
$maccess{'rbac'} = 0 if (defined($in{'rbac'}));
|
|
||||||
&foreign_require($in{'_acl_mod'}, "acl_security.pl");
|
&foreign_require($in{'_acl_mod'}, "acl_security.pl");
|
||||||
&foreign_call($in{'_acl_mod'}, "acl_security_save",
|
&foreign_call($in{'_acl_mod'}, "acl_security_save",
|
||||||
\%maccess, \%in);
|
\%maccess, \%in);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $config_directory);
|
our (%in, %text, %config, %access, $config_directory);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'pass'} || &error($text{'pass_ecannot'});
|
$access{'pass'} || &error($text{'pass_ecannot'});
|
||||||
&error_setup($text{'pass_err'});
|
&error_setup($text{'pass_err'});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $module_config_directory);
|
our (%in, %text, %config, %access, $module_config_directory);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
$access{'sync'} && $access{'create'} && $access{'delete'} ||
|
$access{'sync'} && $access{'create'} && $access{'delete'} ||
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %access, $base_remote_user);
|
||||||
&foreign_require("webmin");
|
&foreign_require("webmin");
|
||||||
&error_setup($text{'twofactor_err'});
|
&error_setup($text{'twofactor_err'});
|
||||||
@@ -55,7 +55,7 @@ if ($in{'enable'}) {
|
|||||||
my $mfunc = "webmin::message_twofactor_".
|
my $mfunc = "webmin::message_twofactor_".
|
||||||
$miniserv{'twofactor_provider'};
|
$miniserv{'twofactor_provider'};
|
||||||
if (defined(&{\&{$mfunc}})) {
|
if (defined(&{\&{$mfunc}})) {
|
||||||
print &{\&{$mfunc}}($user);
|
print "<p></p>".&{\&{$mfunc}}($user);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Save user
|
# Save user
|
||||||
@@ -65,6 +65,19 @@ if ($in{'enable'}) {
|
|||||||
&webmin_log("twofactor", "user", $user->{'name'},
|
&webmin_log("twofactor", "user", $user->{'name'},
|
||||||
{ 'provider' => $user->{'twofactor_provider'},
|
{ 'provider' => $user->{'twofactor_provider'},
|
||||||
'id' => $user->{'twofactor_id'} });
|
'id' => $user->{'twofactor_id'} });
|
||||||
|
|
||||||
|
# Show a test form only when enrolling for yourself
|
||||||
|
if ($user->{'name'} eq $base_remote_user) {
|
||||||
|
print &ui_form_start("test_twofactor.cgi");
|
||||||
|
print &ui_tag('p', $text{'twofactor_testdesc'});
|
||||||
|
print &ui_tag('p', "$text{'twofactor_testfield'}".
|
||||||
|
" ".
|
||||||
|
&ui_textbox("test", undef, 12));
|
||||||
|
print &ui_hidden("user", $in{'user'}) if ($in{'user'});
|
||||||
|
print &ui_tag('p');
|
||||||
|
print &ui_form_end([ [ undef,
|
||||||
|
$text{'twofactor_test'} ] ]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&ui_print_footer("", $text{'index_return'});
|
&ui_print_footer("", $text{'index_return'});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&error_setup($text{'unix_err'});
|
&error_setup($text{'unix_err'});
|
||||||
@@ -70,7 +70,7 @@ else {
|
|||||||
}
|
}
|
||||||
if ($in{'sudo'}) {
|
if ($in{'sudo'}) {
|
||||||
&has_command("sudo") || &error(&text('unix_esudo', "<tt>sudo</tt>"));
|
&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>"));
|
$@ && &error(&text('unix_esudomod', "<tt>IO::Pty</tt>"));
|
||||||
}
|
}
|
||||||
$miniserv{'sudo'} = $in{'sudo'};
|
$miniserv{'sudo'} = $in{'sudo'};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $config_directory, $base_remote_user);
|
our (%in, %text, %config, %access, $config_directory, $base_remote_user);
|
||||||
&foreign_require("webmin", "webmin-lib.pl");
|
&foreign_require("webmin", "webmin-lib.pl");
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
@@ -105,11 +105,6 @@ foreach my $u (@ulist) {
|
|||||||
# Find the current group
|
# Find the current group
|
||||||
my $oldgroup = $in{'old'} ? &get_users_group($in{'old'}) : undef;
|
my $oldgroup = $in{'old'} ? &get_users_group($in{'old'}) : undef;
|
||||||
|
|
||||||
if (&supports_rbac()) {
|
|
||||||
# Save RBAC mode
|
|
||||||
$user{'rbacdeny'} = $in{'rbacdeny'};
|
|
||||||
}
|
|
||||||
|
|
||||||
my $newgroup;
|
my $newgroup;
|
||||||
if (defined($in{'group'})) {
|
if (defined($in{'group'})) {
|
||||||
# Check if group is allowed
|
# Check if group is allowed
|
||||||
@@ -374,11 +369,13 @@ else {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $aclfile = "$config_directory/$in{'name'}.acl";
|
my $aclfile = "$config_directory/$in{'name'}.acl";
|
||||||
if ($in{'old'} && $in{'acl_security_form'} && !$newgroup && !$in{'safe'}) {
|
if ($in{'acl_security_form'} && !$newgroup && !$in{'safe'}) {
|
||||||
# Update user's global ACL
|
# Update user's global ACL, and merge in RPC setting which has
|
||||||
|
# been moved out of this form
|
||||||
&foreign_require("", "acl_security.pl");
|
&foreign_require("", "acl_security.pl");
|
||||||
my %uaccess;
|
my %uaccess;
|
||||||
&foreign_call("", "acl_security_save", \%uaccess, \%in);
|
&foreign_call("", "acl_security_save", \%uaccess, \%in);
|
||||||
|
$uaccess{'rpc'} = $in{'rpc'};
|
||||||
&lock_file($aclfile);
|
&lock_file($aclfile);
|
||||||
&save_module_acl(\%uaccess, $in{'name'}, "", 1);
|
&save_module_acl(\%uaccess, $in{'name'}, "", 1);
|
||||||
&set_ownership_permissions(undef, undef, 0640, $aclfile);
|
&set_ownership_permissions(undef, undef, 0640, $aclfile);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access);
|
our (%in, %text, %config, %access);
|
||||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, %sessiondb);
|
our (%in, %text, %config, %access, %sessiondb);
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
&can_edit_user($in{'user'}) && $access{'switch'} ||
|
&can_edit_user($in{'user'}) && $access{'switch'} ||
|
||||||
|
|||||||
@@ -20,7 +20,12 @@ foreach my $k (keys %sessiondb) {
|
|||||||
next if ($k =~ /^1111111/);
|
next if ($k =~ /^1111111/);
|
||||||
next if (!$sessiondb{$k});
|
next if (!$sessiondb{$k});
|
||||||
my ($user, $ltime, $lip) = split(/\s+/, $sessiondb{$k});
|
my ($user, $ltime, $lip) = split(/\s+/, $sessiondb{$k});
|
||||||
next if ($user ne $remote_user && $user ne "!".$remote_user);
|
next if (&webmin_user_is_admin()
|
||||||
|
? ($user eq "!" ||
|
||||||
|
($user ne $remote_user &&
|
||||||
|
# Show all logins for past 3 days for admin
|
||||||
|
$ltime && $ltime < time() - 3*24*60*60))
|
||||||
|
: ($user ne $remote_user && $user ne "!".$remote_user));
|
||||||
push(@logins, [ $user, $ltime, $lip, $k ]);
|
push(@logins, [ $user, $ltime, $lip, $k ]);
|
||||||
}
|
}
|
||||||
if (@logins) {
|
if (@logins) {
|
||||||
@@ -29,7 +34,8 @@ if (@logins) {
|
|||||||
@logins = @logins[0..4];
|
@logins = @logins[0..4];
|
||||||
}
|
}
|
||||||
my $html = &ui_columns_start([ $text{'sessions_host'},
|
my $html = &ui_columns_start([ $text{'sessions_host'},
|
||||||
$text{'sessions_login'},
|
$text{'sessions_user'},
|
||||||
|
$text{'sessions_login_ago'},
|
||||||
$text{'sessions_state'},
|
$text{'sessions_state'},
|
||||||
$text{'sessions_action'} ]);
|
$text{'sessions_action'} ]);
|
||||||
my $open = 0;
|
my $open = 0;
|
||||||
@@ -62,9 +68,13 @@ if (@logins) {
|
|||||||
&ui_link("@{[&get_webprefix()]}/acl/delete_session.cgi?id=$l->[3]&redirect_ref=1",
|
&ui_link("@{[&get_webprefix()]}/acl/delete_session.cgi?id=$l->[3]&redirect_ref=1",
|
||||||
$text{'sessions_kill'}))
|
$text{'sessions_kill'}))
|
||||||
}
|
}
|
||||||
|
my $user = $l->[0];
|
||||||
|
$user =~ s/^\!//;
|
||||||
$html .= &ui_columns_row([
|
$html .= &ui_columns_row([
|
||||||
$l->[2],
|
$l->[2],
|
||||||
&make_date($l->[1]),
|
$user,
|
||||||
|
&make_date_relative($l->[1]).
|
||||||
|
" ".&ui_help(&make_date($l->[1])),
|
||||||
$state,
|
$state,
|
||||||
&ui_links_row(\@links) ]);
|
&ui_links_row(\@links) ]);
|
||||||
}
|
}
|
||||||
|
|||||||
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();
|
||||||
1527
acl/t/run-tests.t
Normal file
1527
acl/t/run-tests.t
Normal file
File diff suppressed because it is too large
Load Diff
47
acl/test_twofactor.cgi
Executable file
47
acl/test_twofactor.cgi
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/local/bin/perl
|
||||||
|
# Validate a user-supplied two-factor token
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
no warnings 'redefine';
|
||||||
|
no warnings 'uninitialized';
|
||||||
|
require './acl-lib.pl'; ## no critic
|
||||||
|
our (%in, %text, %access, $base_remote_user);
|
||||||
|
&foreign_require("webmin");
|
||||||
|
&error_setup($text{'twofactor_terr'});
|
||||||
|
&ReadParse();
|
||||||
|
|
||||||
|
# Get the user
|
||||||
|
my @users = &list_users();
|
||||||
|
my $user;
|
||||||
|
if ($in{'user'}) {
|
||||||
|
&can_edit_user($in{'user'}) || &error($text{'edit_euser'});
|
||||||
|
($user) = grep { $_->{'name'} eq $in{'user'} } @users;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
($user) = grep { $_->{'name'} eq $base_remote_user } @users;
|
||||||
|
}
|
||||||
|
$user || &error($text{'twofactor_euser'});
|
||||||
|
$user->{'twofactor_provider'} || &error($text{'twofactor_etestuser'});
|
||||||
|
my @provs = &webmin::list_twofactor_providers();
|
||||||
|
my ($prov) = grep { $_->[0] eq $user->{'twofactor_provider'} } @provs;
|
||||||
|
|
||||||
|
# Call the validation function
|
||||||
|
&ui_print_header(undef, $text{'twofactor_title'}, "");
|
||||||
|
|
||||||
|
print &text('twofactor_testing', $prov->[1]),"<br>\n";
|
||||||
|
my $func = "webmin::validate_twofactor_".$user->{'twofactor_provider'};
|
||||||
|
my $err = &{\&{$func}}($user->{'twofactor_id'}, $in{'test'},
|
||||||
|
$user->{'twofactor_apikey'});
|
||||||
|
if ($err) {
|
||||||
|
print &text('twofactor_testfailed', $err),"<p>\n";
|
||||||
|
|
||||||
|
print &ui_form_start("save_twofactor.cgi");
|
||||||
|
print &ui_hidden("user", $in{'user'}) if ($in{'user'});
|
||||||
|
print &ui_form_end([ [ "disable", $text{'twofactor_testdis'} ] ]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
print $text{'twofactor_testok'},"<p>\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
&ui_print_footer("", $text{'index_return'});
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
#!/usr/local/bin/perl
|
#!/usr/local/bin/perl
|
||||||
# Validate the OTP for some user
|
# Validate the OTP for some user
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
no warnings 'once';
|
||||||
|
our $module_name;
|
||||||
$main::no_acl_check = 1;
|
$main::no_acl_check = 1;
|
||||||
$main::no_referers_check = 1;
|
$main::no_referers_check = 1;
|
||||||
$ENV{'WEBMIN_CONFIG'} = "/etc/webmin";
|
$ENV{'WEBMIN_CONFIG'} = "/etc/webmin";
|
||||||
@@ -8,17 +12,19 @@ $ENV{'WEBMIN_VAR'} = "/var/webmin";
|
|||||||
if ($0 =~ /^(.*\/)[^\/]+$/) {
|
if ($0 =~ /^(.*\/)[^\/]+$/) {
|
||||||
chdir($1);
|
chdir($1);
|
||||||
}
|
}
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
$module_name eq 'acl' || die "Command must be run with full path";
|
$module_name eq 'acl' || die "Command must be run with full path";
|
||||||
|
|
||||||
# Check command-line args
|
# Check command-line args
|
||||||
@ARGV == 5 || die "Usage: $0 user provider id token api-key";
|
@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
|
# Call the provider validation function
|
||||||
&foreign_require("webmin");
|
&foreign_require("webmin");
|
||||||
$func = "webmin::validate_twofactor_".$provider;
|
my $method = "validate_twofactor_".$provider;
|
||||||
$err = &$func($id, $token, $apikey);
|
my $code = webmin->can($method)
|
||||||
|
or die "Unknown twofactor provider: $provider\n";
|
||||||
|
my $err = $code->($id, $token, $apikey);
|
||||||
if ($err) {
|
if ($err) {
|
||||||
$err =~ s/\r|\n/ /g;
|
$err =~ s/\r|\n/ /g;
|
||||||
print $err,"\n";
|
print $err,"\n";
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use strict;
|
|||||||
use warnings;
|
use warnings;
|
||||||
no warnings 'redefine';
|
no warnings 'redefine';
|
||||||
no warnings 'uninitialized';
|
no warnings 'uninitialized';
|
||||||
require './acl-lib.pl';
|
require './acl-lib.pl'; ## no critic
|
||||||
our (%in, %text, %config, %access, $base_remote_user);
|
our (%in, %text, %config, %access, $base_remote_user);
|
||||||
&foreign_require("webmin");
|
&foreign_require("webmin");
|
||||||
&error_setup($text{'twofactor_err'});
|
&error_setup($text{'twofactor_err'});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ print &ui_table_row($text{'acl_root'},
|
|||||||
# Other dirs to allow
|
# Other dirs to allow
|
||||||
print &ui_table_row($text{'acl_otherdirs'},
|
print &ui_table_row($text{'acl_otherdirs'},
|
||||||
&ui_textarea("otherdirs", join("\n", split(/\t+/, $o->{'otherdirs'})),
|
&ui_textarea("otherdirs", join("\n", split(/\t+/, $o->{'otherdirs'})),
|
||||||
5, 40), 3);
|
3, 40), 3);
|
||||||
|
|
||||||
# Can see dot files?
|
# Can see dot files?
|
||||||
print &ui_table_row($text{'acl_nodot'},
|
print &ui_table_row($text{'acl_nodot'},
|
||||||
@@ -77,18 +77,6 @@ print &ui_table_row($text{'acl_gedit'},
|
|||||||
|
|
||||||
print &ui_table_hr();
|
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?
|
# Get new permissions?
|
||||||
print &ui_table_row($text{'acl_negative'},
|
print &ui_table_row($text{'acl_negative'},
|
||||||
&ui_radio("negative", int($o->{'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
|
# Parse the form for global security options
|
||||||
sub acl_security_save
|
sub acl_security_save
|
||||||
{
|
{
|
||||||
$_[0]->{'root'} = $in{'root_def'} ? undef : $in{'root'};
|
my ($o) = @_;
|
||||||
$_[0]->{'otherdirs'} = join("\t", split(/\r?\n/, $in{'otherdirs'}));
|
$o->{'root'} = $in{'root_def'} ? undef : $in{'root'};
|
||||||
$_[0]->{'nodot'} = $in{'nodot'};
|
$o->{'otherdirs'} = join("\t", split(/\r?\n/, $in{'otherdirs'}));
|
||||||
|
$o->{'nodot'} = $in{'nodot'};
|
||||||
|
|
||||||
$_[0]->{'uedit_mode'} = $in{'uedit_mode'};
|
$o->{'uedit_mode'} = $in{'uedit_mode'};
|
||||||
$_[0]->{'uedit'} = $in{'uedit_mode'} == 2 ? $in{'uedit_can'} :
|
$o->{'uedit'} = $in{'uedit_mode'} == 2 ? $in{'uedit_can'} :
|
||||||
$in{'uedit_mode'} == 3 ? $in{'uedit_cannot'} :
|
$in{'uedit_mode'} == 3 ? $in{'uedit_cannot'} :
|
||||||
$in{'uedit_mode'} == 4 ? $in{'uedit_uid'} :
|
$in{'uedit_mode'} == 4 ? $in{'uedit_uid'} :
|
||||||
$in{'uedit_mode'} == 5 ? getgrnam($in{'uedit_group'}) : "";
|
$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'};
|
$o->{'gedit_mode'} = $in{'gedit_mode'};
|
||||||
$_[0]->{'gedit'} = $in{'gedit_mode'} == 2 ? $in{'gedit_can'} :
|
$o->{'gedit'} = $in{'gedit_mode'} == 2 ? $in{'gedit_can'} :
|
||||||
$in{'gedit_mode'} == 3 ? $in{'gedit_cannot'} :
|
$in{'gedit_mode'} == 3 ? $in{'gedit_cannot'} :
|
||||||
$in{'gedit_mode'} == 4 ? $in{'gedit_gid'} : "";
|
$in{'gedit_mode'} == 4 ? $in{'gedit_gid'} : "";
|
||||||
$_[0]->{'gedit2'} = $in{'gedit_mode'} == 4 ? $in{'gedit_gid2'} : undef;
|
$o->{'gedit2'} = $in{'gedit_mode'} == 4 ? $in{'gedit_gid2'} : undef;
|
||||||
$_[0]->{'feedback'} = $in{'feedback'};
|
$o->{'negative'} = $in{'negative'};
|
||||||
$_[0]->{'rpc'} = $in{'rpc'};
|
$o->{'readonly'} = $in{'readonly'};
|
||||||
$_[0]->{'negative'} = $in{'negative'};
|
$o->{'fileunix'} = $in{'fileunix_def'} ? undef : $in{'fileunix'};
|
||||||
$_[0]->{'readonly'} = $in{'readonly'};
|
$o->{'webminsearch'} = $in{'webminsearch'};
|
||||||
$_[0]->{'fileunix'} = $in{'fileunix_def'} ? undef : $in{'fileunix'};
|
|
||||||
$_[0]->{'webminsearch'} = $in{'webminsearch'};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,115 +5,84 @@ require 'apache-lib.pl';
|
|||||||
# Output HTML for editing security options for the apache module
|
# Output HTML for editing security options for the apache module
|
||||||
sub acl_security_form
|
sub acl_security_form
|
||||||
{
|
{
|
||||||
print "<tr> <td valign=top rowspan=4><b>$text{'acl_virts'}</b></td>\n";
|
my ($o) = @_;
|
||||||
print "<td rowspan=4 valign=top>\n";
|
|
||||||
printf "<input type=radio name=virts_def value=1 %s> %s\n",
|
my $conf = &get_config();
|
||||||
$_[0]->{'virts'} eq '*' ? 'checked' : '', $text{'acl_vall'};
|
my @virts = ( { 'value' => '__default__' },
|
||||||
printf "<input type=radio name=virts_def value=0 %s> %s<br>\n",
|
&find_directive_struct("VirtualHost", $conf) );
|
||||||
$_[0]->{'virts'} eq '*' ? '' : 'checked', $text{'acl_vsel'};
|
my @vsel = $o->{'virts'} eq '*' ? () : split(/\s+/, $o->{'virts'});
|
||||||
print "<select name=virts multiple size=5>\n";
|
my %vcan = map { $_, 1 } @vsel;
|
||||||
local $conf = &get_config();
|
my @vopts;
|
||||||
local @virts = ( { 'value' => '__default__' },
|
foreach my $v (@virts) {
|
||||||
&find_directive_struct("VirtualHost", $conf) );
|
my @vn = &virt_acl_name($v);
|
||||||
local %vcan = map { $_, 1 } split(/\s+/, $_[0]->{'virts'});
|
my ($can) = grep { $vcan{$_} } @vn;
|
||||||
local $v;
|
my $show = $can || $vn[0];
|
||||||
foreach $v (@virts) {
|
push(@vopts, [ $show,
|
||||||
local @vn = &virt_acl_name($v);
|
$show eq "__default__" ? $text{'acl_defserv'}
|
||||||
local ($can) = grep { $vcan{$_} } @vn;
|
: $show ]);
|
||||||
local $vn = $can || $vn[0];
|
|
||||||
printf "<option value=\"%s\" %s>%s</option>\n",
|
|
||||||
$vn, $can ? "selected" : "",
|
|
||||||
$vn eq "__default__" ? $text{'acl_defserv'} : $vn;
|
|
||||||
delete($vcan{$can}) if ($can);
|
delete($vcan{$can}) if ($can);
|
||||||
}
|
}
|
||||||
foreach $vn (keys %vcan) {
|
print &ui_table_row($text{'acl_virts'},
|
||||||
next if ($vn eq "*");
|
&ui_radio("virts_def", $o->{'virts'} eq '*' ? 1 : 0,
|
||||||
printf "<option value=\"%s\" %s>%s</option>\n",
|
[ [ 1, $text{'acl_vall'} ],
|
||||||
$vn, "selected",
|
[ 0, $text{'acl_vsel'} ] ])."<br>\n".
|
||||||
$vn eq "__default__" ? $text{'acl_defserv'} : $vn;
|
&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";
|
print &ui_table_row($text{'acl_dirs'},
|
||||||
printf "<option value=1 %s>$text{'yes'}</option>\n",
|
&ui_radio("dirsmode", $o->{'dirsmode'},
|
||||||
$_[0]->{'global'} == 1 ? "selected" : "";
|
[ [ 0, $text{'acl_dirs0'} ],
|
||||||
printf "<option value=2 %s>$text{'acl_htaccess'}</option>\n",
|
[ 1, $text{'acl_dirs1'} ],
|
||||||
$_[0]->{'global'} == 2 ? "selected" : "";
|
[ 2, $text{'acl_dirs2'} ] ])."<br>\n".
|
||||||
printf "<option value=0 %s>$text{'no'}</option></select></td> </tr>\n",
|
&ui_textarea("dirs", join("\n", split(/\s+/, $o->{'dirs'})), 5, 50),
|
||||||
$_[0]->{'global'} == 0 ? "selected" : "";
|
3);
|
||||||
|
|
||||||
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";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# acl_security_save(&options)
|
# acl_security_save(&options)
|
||||||
@@ -141,4 +110,3 @@ $_[0]->{'names'} = $in{'names'};
|
|||||||
$_[0]->{'dirsmode'} = $in{'dirsmode'};
|
$_[0]->{'dirsmode'} = $in{'dirsmode'};
|
||||||
$_[0]->{'dirs'} = join(" ", split(/\s+/, $in{'dirs'}));
|
$_[0]->{'dirs'} = join(" ", split(/\s+/, $in{'dirs'}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ $conf = &get_config();
|
|||||||
&indexof($in{'file'}, @files) >= 0 || &error($text{'manual_efile'});
|
&indexof($in{'file'}, @files) >= 0 || &error($text{'manual_efile'});
|
||||||
|
|
||||||
$temp = &transname();
|
$temp = &transname();
|
||||||
&execute_command("cp ".quotemeta($in{'file'})." $temp");
|
&execute_command("cp ".quotemeta($in{'file'})." ".quotemeta($temp));
|
||||||
$in{'data'} =~ s/\r//g;
|
$in{'data'} =~ s/\r//g;
|
||||||
&lock_file($in{'file'});
|
&lock_file($in{'file'});
|
||||||
&open_tempfile(FILE, ">$in{'file'}");
|
&open_tempfile(FILE, ">$in{'file'}");
|
||||||
@@ -22,7 +22,7 @@ $in{'data'} =~ s/\r//g;
|
|||||||
if ($config{'test_manual'}) {
|
if ($config{'test_manual'}) {
|
||||||
$err = &test_config();
|
$err = &test_config();
|
||||||
if ($err) {
|
if ($err) {
|
||||||
&execute_command("mv $temp '$in{'file'}'");
|
&execute_command("mv ".quotemeta($temp)." ".quotemeta($in{'file'}));
|
||||||
&error(&text('manual_etest', "<pre>$err</pre>"));
|
&error(&text('manual_etest', "<pre>$err</pre>"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,4 +30,3 @@ unlink($temp);
|
|||||||
&format_config_file($in{'file'});
|
&format_config_file($in{'file'});
|
||||||
&webmin_log("manual", undef, undef, { 'file' => $in{'file'} });
|
&webmin_log("manual", undef, undef, { 'file' => $in{'file'} });
|
||||||
&redirect("index.cgi?mode=global");
|
&redirect("index.cgi?mode=global");
|
||||||
|
|
||||||
|
|||||||
@@ -26,82 +26,94 @@ $last_restart_time_flag = $module_var_directory."/restart-flag";
|
|||||||
# if the Apache binary changes, when Webmin is upgraded, or once every five
|
# if the Apache binary changes, when Webmin is upgraded, or once every five
|
||||||
# minutes if automatic rebuilding is enabled.
|
# minutes if automatic rebuilding is enabled.
|
||||||
if ($module_name ne 'htaccess') {
|
if ($module_name ne 'htaccess') {
|
||||||
local %oldsite;
|
&create_site_file();
|
||||||
local $httpd = &find_httpd();
|
|
||||||
local @st = stat($httpd);
|
|
||||||
&read_file($site_file, \%oldsite);
|
|
||||||
local @sst = stat($site_file);
|
|
||||||
if ($oldsite{'path'} ne $httpd ||
|
|
||||||
$oldsite{'size'} != $st[7] ||
|
|
||||||
$oldsite{'webmin'} != &get_webmin_version() ||
|
|
||||||
$config{'auto_mods'} && $sst[9] < time()-5*60) {
|
|
||||||
# Need to build list of supported modules
|
|
||||||
local ($ver, $mods, $fullver) = &httpd_info($httpd);
|
|
||||||
if ($ver) {
|
|
||||||
my @allmods = &available_modules();
|
|
||||||
local @mods = map { "$_/$ver" }
|
|
||||||
&configurable_modules(\@allmods);
|
|
||||||
foreach my $m (@mods) {
|
|
||||||
if ($m =~ /(\S+)\/(\S+)/) {
|
|
||||||
$httpd_modules{$1} = $2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Call again now that known modules have been set, as
|
|
||||||
# sometimes there are dependencies due to LoadModule
|
|
||||||
# statements in an IfModule block
|
|
||||||
undef(@get_config_cache);
|
|
||||||
@allmods = &available_modules();
|
|
||||||
@mods = map { "$_/$ver" }
|
|
||||||
&configurable_modules(\@allmods);
|
|
||||||
local %site = ( 'size' => $st[7],
|
|
||||||
'path' => $httpd,
|
|
||||||
'modules' => join(' ', @mods),
|
|
||||||
'allmodules' => join(' ', @allmods),
|
|
||||||
'version' => $ver,
|
|
||||||
'fullversion' => $fullver,
|
|
||||||
'webmin' => &get_webmin_version() );
|
|
||||||
&lock_file($site_file);
|
|
||||||
&write_file($site_file, \%site);
|
|
||||||
chmod(0644, $site_file);
|
|
||||||
&unlock_file($site_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read the site-specific setup file, then require in all the module-specific
|
|
||||||
# .pl files
|
|
||||||
if (&read_file($site_file, \%site)) {
|
|
||||||
local($m, $f, $d);
|
|
||||||
$httpd_size = $site{'size'};
|
|
||||||
foreach $m (split(/\s+/, $site{'modules'})) {
|
|
||||||
if ($m =~ /(\S+)\/(\S+)/) {
|
|
||||||
$httpd_modules{$1} = $2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach $m (split(/\s+/, $site{'allmodules'})) {
|
|
||||||
$all_httpd_modules{$m} = $site{'version'};
|
|
||||||
}
|
|
||||||
foreach $m (keys %httpd_modules) {
|
|
||||||
if (!-r "$module_root_directory/$m.pl") {
|
|
||||||
delete($httpd_modules{$m});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach $f (split(/\s+/, $site{'htaccess'})) {
|
|
||||||
if (-r $f) { push(@htaccess_files, $f); }
|
|
||||||
}
|
|
||||||
foreach $m (keys %httpd_modules) {
|
|
||||||
do "$m.pl";
|
|
||||||
}
|
|
||||||
foreach $d (split(/\s+/, $site{'defines'})) {
|
|
||||||
$httpd_defines{$d}++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
&read_site_file();
|
||||||
|
|
||||||
$apache_docbase = $config{'apache_docbase'} ? $config{'apache_docbase'} :
|
$apache_docbase = $config{'apache_docbase'} ? $config{'apache_docbase'} :
|
||||||
$httpd_modules{'core'} >= 2.0 ?
|
$httpd_modules{'core'} >= 2.0 ?
|
||||||
"http://httpd.apache.org/docs-2.0/mod/" :
|
"http://httpd.apache.org/docs-2.0/mod/" :
|
||||||
"http://httpd.apache.org/docs/mod/";
|
"http://httpd.apache.org/docs/mod/";
|
||||||
|
|
||||||
|
# create_site_file()
|
||||||
|
# If the Apache binary or Webmin version has changed, create the site
|
||||||
|
# file containing all known Apache modules
|
||||||
|
sub create_site_file
|
||||||
|
{
|
||||||
|
my %oldsite;
|
||||||
|
my $httpd = &find_httpd();
|
||||||
|
my @st = stat($httpd);
|
||||||
|
&read_file($site_file, \%oldsite);
|
||||||
|
my @sst = stat($site_file);
|
||||||
|
if ($oldsite{'path'} ne $httpd ||
|
||||||
|
$oldsite{'size'} != $st[7] ||
|
||||||
|
$oldsite{'webmin'} != &get_webmin_version() ||
|
||||||
|
$config{'auto_mods'} && $sst[9] < time()-5*60) {
|
||||||
|
# Need to build list of supported modules
|
||||||
|
my ($ver, $mods, $fullver) = &httpd_info($httpd);
|
||||||
|
if ($ver) {
|
||||||
|
my @allmods = &available_modules();
|
||||||
|
my @mods = map { "$_/$ver" }
|
||||||
|
&configurable_modules(\@allmods);
|
||||||
|
foreach my $m (@mods) {
|
||||||
|
if ($m =~ /(\S+)\/(\S+)/) {
|
||||||
|
$httpd_modules{$1} = $2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Call again now that known modules have been set, as
|
||||||
|
# sometimes there are dependencies due to LoadModule
|
||||||
|
# statements in an IfModule block
|
||||||
|
undef(@get_config_cache);
|
||||||
|
@allmods = &available_modules();
|
||||||
|
@mods = map { "$_/$ver" }
|
||||||
|
&configurable_modules(\@allmods);
|
||||||
|
my %site = ( 'size' => $st[7],
|
||||||
|
'path' => $httpd,
|
||||||
|
'modules' => join(' ', @mods),
|
||||||
|
'allmodules' => join(' ', @allmods),
|
||||||
|
'version' => $ver,
|
||||||
|
'fullversion' => $fullver,
|
||||||
|
'webmin' => &get_webmin_version() );
|
||||||
|
&lock_file($site_file);
|
||||||
|
&write_file($site_file, \%site);
|
||||||
|
chmod(0644, $site_file);
|
||||||
|
&unlock_file($site_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# read_site_file()
|
||||||
|
# Read the site-specific setup file, then require in all the module-specific
|
||||||
|
# .pl files
|
||||||
|
sub read_site_file
|
||||||
|
{
|
||||||
|
if (&read_file($site_file, \%site)) {
|
||||||
|
foreach my $m (split(/\s+/, $site{'modules'})) {
|
||||||
|
if ($m =~ /(\S+)\/(\S+)/) {
|
||||||
|
$httpd_modules{$1} = $2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach my $m (split(/\s+/, $site{'allmodules'})) {
|
||||||
|
$all_httpd_modules{$m} = $site{'version'};
|
||||||
|
}
|
||||||
|
foreach my $m (keys %httpd_modules) {
|
||||||
|
if (!-r "$module_root_directory/$m.pl") {
|
||||||
|
delete($httpd_modules{$m});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach my $f (split(/\s+/, $site{'htaccess'})) {
|
||||||
|
if (-r $f) { push(@htaccess_files, $f); }
|
||||||
|
}
|
||||||
|
foreach my $m (keys %httpd_modules) {
|
||||||
|
do "$m.pl";
|
||||||
|
}
|
||||||
|
foreach my $d (split(/\s+/, $site{'defines'})) {
|
||||||
|
$httpd_defines{$d}++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
# parse_config_file(handle, lines, file, [recursive])
|
# parse_config_file(handle, lines, file, [recursive])
|
||||||
# Parses lines of text from some config file into a data structure. The
|
# Parses lines of text from some config file into a data structure. The
|
||||||
# return value is an array of references, one for each directive in the file.
|
# return value is an array of references, one for each directive in the file.
|
||||||
@@ -424,6 +436,13 @@ foreach $v (@virt) {
|
|||||||
return \@get_config_cache;
|
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])
|
# get_config_file(filename, [&seen-files])
|
||||||
# Returns a list of config hash refs from some file
|
# Returns a list of config hash refs from some file
|
||||||
sub get_config_file
|
sub get_config_file
|
||||||
@@ -776,6 +795,428 @@ unlink($file);
|
|||||||
&delete_webfile_link($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)
|
# renumber(&config, line, file, offset)
|
||||||
# Recursively changes the line number of all directives from some file
|
# Recursively changes the line number of all directives from some file
|
||||||
# beyond the given line.
|
# beyond the given line.
|
||||||
@@ -800,9 +1241,16 @@ foreach my $d (@$conf) {
|
|||||||
# Convert a relative path to being under the server root
|
# Convert a relative path to being under the server root
|
||||||
sub server_root
|
sub server_root
|
||||||
{
|
{
|
||||||
if (!$_[0]) { return undef; }
|
my ($path) = @_;
|
||||||
elsif ($_[0] =~ /^\//) { return $_[0]; }
|
if (!$path) {
|
||||||
else { return "$config{'httpd_dir'}/$_[0]"; }
|
return undef;
|
||||||
|
}
|
||||||
|
elsif ($path =~ /^\//) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "$config{'httpd_dir'}/$path";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub dump_config
|
sub dump_config
|
||||||
@@ -1223,6 +1671,9 @@ sub restart_button
|
|||||||
local $args = "redir=".&urlize(&this_url());
|
local $args = "redir=".&urlize(&this_url());
|
||||||
local @rv;
|
local @rv;
|
||||||
if (&is_apache_running()) {
|
if (&is_apache_running()) {
|
||||||
|
if ($access{'stop'}) {
|
||||||
|
push(@rv, &ui_link("stop.cgi?$args", $text{'apache_stop'}) );
|
||||||
|
}
|
||||||
if ($access{'apply'}) {
|
if ($access{'apply'}) {
|
||||||
my $n = &needs_config_restart();
|
my $n = &needs_config_restart();
|
||||||
if ($n) {
|
if ($n) {
|
||||||
@@ -1233,9 +1684,6 @@ if (&is_apache_running()) {
|
|||||||
push(@rv, &ui_link("restart.cgi?$args", $text{'apache_apply'}) );
|
push(@rv, &ui_link("restart.cgi?$args", $text{'apache_apply'}) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($access{'stop'}) {
|
|
||||||
push(@rv, &ui_link("stop.cgi?$args", $text{'apache_stop'}) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elsif ($access{'stop'}) {
|
elsif ($access{'stop'}) {
|
||||||
push(@rv, &ui_link("start.cgi?$args", $text{'apache_start'}) );
|
push(@rv, &ui_link("start.cgi?$args", $text{'apache_start'}) );
|
||||||
@@ -1420,7 +1868,7 @@ sub allowed_auth_file
|
|||||||
local $_;
|
local $_;
|
||||||
return 1 if ($access{'dir'} eq '/');
|
return 1 if ($access{'dir'} eq '/');
|
||||||
return 0 if ($_[0] =~ /\.\./);
|
return 0 if ($_[0] =~ /\.\./);
|
||||||
local $f = &server_root($_[0], &get_config());
|
local $f = &server_root($_[0]);
|
||||||
return 0 if (-l $f && !&allowed_auth_file(readlink($f)));
|
return 0 if (-l $f && !&allowed_auth_file(readlink($f)));
|
||||||
local $l = length($access{'dir'});
|
local $l = length($access{'dir'});
|
||||||
return length($f) >= $l && substr($f, 0, $l) eq $access{'dir'};
|
return length($f) >= $l && substr($f, 0, $l) eq $access{'dir'};
|
||||||
@@ -1430,7 +1878,7 @@ return length($f) >= $l && substr($f, 0, $l) eq $access{'dir'};
|
|||||||
# Returns 1 if the directory in some path exists
|
# Returns 1 if the directory in some path exists
|
||||||
sub directory_exists
|
sub directory_exists
|
||||||
{
|
{
|
||||||
local $path = &server_root($_[0], &get_config());
|
local $path = &server_root($_[0]);
|
||||||
if ($path =~ /^(\S*\/)([^\/]+)$/) {
|
if ($path =~ /^(\S*\/)([^\/]+)$/) {
|
||||||
return -d $1;
|
return -d $1;
|
||||||
}
|
}
|
||||||
@@ -1525,9 +1973,10 @@ return undef;
|
|||||||
# if necessary.
|
# if necessary.
|
||||||
sub before_changing
|
sub before_changing
|
||||||
{
|
{
|
||||||
|
my @extra = grep { $_ } @_;
|
||||||
if ($config{'test_always'} || $access{'test_always'}) {
|
if ($config{'test_always'} || $access{'test_always'}) {
|
||||||
local $conf = &get_config();
|
local $conf = &get_config();
|
||||||
local @files = &unique(map { $_->{'file'} } @$conf);
|
local @files = &unique((map { $_->{'file'} } @$conf), @extra);
|
||||||
local $/ = undef;
|
local $/ = undef;
|
||||||
local $f;
|
local $f;
|
||||||
foreach $f (@files) {
|
foreach $f (@files) {
|
||||||
@@ -1606,7 +2055,7 @@ local $conf = &get_config();
|
|||||||
local $pidfilestr = &find_directive_struct("PidFile", $conf);
|
local $pidfilestr = &find_directive_struct("PidFile", $conf);
|
||||||
local $pidfile = $pidfilestr ? $pidfilestr->{'words'}->[0]
|
local $pidfile = $pidfilestr ? $pidfilestr->{'words'}->[0]
|
||||||
: "logs/httpd.pid";
|
: "logs/httpd.pid";
|
||||||
return &server_root($pidfile, $conf);
|
return &server_root($pidfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
# restart_apache()
|
# restart_apache()
|
||||||
@@ -1791,8 +2240,8 @@ if (!&is_apache_running()) {
|
|||||||
return $text{'start_eunknown'};
|
return $text{'start_eunknown'};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$errorlog = &server_root($errorlog, $conf);
|
$errorlog = &server_root($errorlog);
|
||||||
$out = `tail -5 $errorlog`;
|
$out = &backquote_command("tail -5 ".quotemeta($errorlog));
|
||||||
return "$text{'start_eafter'} : <pre>$out</pre>";
|
return "$text{'start_eafter'} : <pre>$out</pre>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1808,7 +2257,7 @@ local $conf = &get_config();
|
|||||||
local $errorlogstr = &find_directive_struct("ErrorLog", $conf);
|
local $errorlogstr = &find_directive_struct("ErrorLog", $conf);
|
||||||
local $errorlog = $errorlogstr ? $errorlogstr->{'words'}->[0]
|
local $errorlog = $errorlogstr ? $errorlogstr->{'words'}->[0]
|
||||||
: "logs/error_log";
|
: "logs/error_log";
|
||||||
$errorlog = &server_root($errorlog, $conf);
|
$errorlog = &server_root($errorlog);
|
||||||
return $errorlog;
|
return $errorlog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1950,10 +2399,11 @@ return @rv;
|
|||||||
sub create_webfile_link
|
sub create_webfile_link
|
||||||
{
|
{
|
||||||
local ($file) = @_;
|
local ($file) = @_;
|
||||||
if ($config{'link_dir'}) {
|
my $linkdir = &vhost_enabled_dir();
|
||||||
|
if ($linkdir) {
|
||||||
local $short = $file;
|
local $short = $file;
|
||||||
$short =~ s/^.*\///;
|
$short =~ s/^.*\///;
|
||||||
local $linksrc = "$config{'link_dir'}/$short";
|
local $linksrc = "$linkdir/$short";
|
||||||
&lock_file($linksrc);
|
&lock_file($linksrc);
|
||||||
symlink($file, $linksrc);
|
symlink($file, $linksrc);
|
||||||
&unlock_file($linksrc);
|
&unlock_file($linksrc);
|
||||||
@@ -1966,16 +2416,16 @@ if ($config{'link_dir'}) {
|
|||||||
sub delete_webfile_link
|
sub delete_webfile_link
|
||||||
{
|
{
|
||||||
local ($file) = @_;
|
local ($file) = @_;
|
||||||
if ($config{'link_dir'}) {
|
$file = &simplify_path(&resolve_links($file));
|
||||||
local $short = $file;
|
my $linkdir = &vhost_enabled_dir();
|
||||||
$short =~ s/^.*\///;
|
if ($linkdir && opendir(LINKDIR, $linkdir)) {
|
||||||
opendir(LINKDIR, $config{'link_dir'});
|
|
||||||
foreach my $f (readdir(LINKDIR)) {
|
foreach my $f (readdir(LINKDIR)) {
|
||||||
if ($f ne "." && $f ne ".." &&
|
if ($f ne "." && $f ne "..") {
|
||||||
(&simplify_path(
|
my $link = $linkdir."/".$f;
|
||||||
&resolve_links($config{'link_dir'}."/".$f)) eq $file ||
|
next if (!-l $link);
|
||||||
$short eq $f)) {
|
if (&simplify_path(&resolve_links($link)) eq $file) {
|
||||||
&unlink_logged($config{'link_dir'}."/".$f);
|
&unlink_logged($link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(LINKDIR);
|
closedir(LINKDIR);
|
||||||
@@ -2274,5 +2724,14 @@ sub format_config_allowed
|
|||||||
return $config{'format_config'};
|
return $config{'format_config'};
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
# clear_apache_modules_cache()
|
||||||
|
# If new Apache modules were enabled, force re-gen of the site file
|
||||||
|
# that contains the modules cache
|
||||||
|
sub clear_apache_modules_cache
|
||||||
|
{
|
||||||
|
&unlink_file($site_file);
|
||||||
|
&create_site_file();
|
||||||
|
&read_site_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|||||||
@@ -14,23 +14,23 @@ push(@rv, map { $_->{'file'} } @$conf);
|
|||||||
# Add mime types file
|
# Add mime types file
|
||||||
local $mfile = &find_directive("TypesConfig", $conf);
|
local $mfile = &find_directive("TypesConfig", $conf);
|
||||||
if (!$mfile) { $mfile = $config{'mime_types'}; }
|
if (!$mfile) { $mfile = $config{'mime_types'}; }
|
||||||
if (!$mfile) { $mfile = &server_root("etc/mime.types", $conf); }
|
if (!$mfile) { $mfile = &server_root("etc/mime.types"); }
|
||||||
if (!-r $mfile) { $mfile = &server_root("conf/mime.types", $conf); }
|
if (!-r $mfile) { $mfile = &server_root("conf/mime.types"); }
|
||||||
if ($mfile) {
|
if ($mfile) {
|
||||||
push(@rv, &server_root($mfile, $conf));
|
push(@rv, &server_root($mfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add mime magic file
|
# Add mime magic file
|
||||||
local $magic = &find_directive("MimeMagicFile", $conf);
|
local $magic = &find_directive("MimeMagicFile", $conf);
|
||||||
if ($magic) {
|
if ($magic) {
|
||||||
push(@rv, &server_root($magic, $conf));
|
push(@rv, &server_root($magic));
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add all auth files
|
# Add all auth files
|
||||||
local $auth;
|
local $auth;
|
||||||
foreach $auth (&find_all_directives($conf, "AuthUserFile"),
|
foreach $auth (&find_all_directives($conf, "AuthUserFile"),
|
||||||
&find_all_directives($conf, "AuthGroupFile")) {
|
&find_all_directives($conf, "AuthGroupFile")) {
|
||||||
push(@rv, &server_root($auth, $conf));
|
push(@rv, &server_root($auth));
|
||||||
}
|
}
|
||||||
|
|
||||||
return &unique(@rv);
|
return &unique(@rv);
|
||||||
|
|||||||
336
apache/core.pl
336
apache/core.pl
@@ -73,11 +73,12 @@ $rv = [ [ 'AccessFileName', 0, 5, 'virtual', undef, 5 ],
|
|||||||
[ 'Options', 0, 5, 'virtual directory htaccess', undef, 3 ],
|
[ 'Options', 0, 5, 'virtual directory htaccess', undef, 3 ],
|
||||||
[ 'PidFile', 0, 9, 'global', -2.0 ],
|
[ 'PidFile', 0, 9, 'global', -2.0 ],
|
||||||
[ 'Protocols', 0, 1, 'virtual', 2.4 ],
|
[ '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 ],
|
[ 'RLimitCPU', 0, 0, 'virtual', 1.2 ],
|
||||||
[ 'RLimitMEM', 0, 0, 'virtual', 1.2 ],
|
[ 'RLimitMEM', 0, 0, 'virtual', 1.2 ],
|
||||||
[ 'RLimitNPROC', 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' ],
|
[ 'ScoreBoardFile', 0, 9, 'global', '1.2-2.0' ],
|
||||||
[ 'SendBufferSize', 0, 1, 'global', -2.0 ],
|
[ 'SendBufferSize', 0, 1, 'global', -2.0 ],
|
||||||
[ 'ServerAdmin', 0, 1, 'virtual' ],
|
[ 'ServerAdmin', 0, 1, 'virtual' ],
|
||||||
@@ -108,7 +109,7 @@ return ();
|
|||||||
sub edit_MaxClients
|
sub edit_MaxClients
|
||||||
{
|
{
|
||||||
return (1,
|
return (1,
|
||||||
$text{'core_maxconc'},
|
&hlink($text{'core_maxconc'}, "MaxClients"),
|
||||||
&opt_input($_[0]->{'value'}, "MaxClients", $text{'core_default'}, 4));
|
&opt_input($_[0]->{'value'}, "MaxClients", $text{'core_default'}, 4));
|
||||||
}
|
}
|
||||||
sub save_MaxClients
|
sub save_MaxClients
|
||||||
@@ -117,6 +118,19 @@ return &parse_opt("MaxClients", '^\d+$',
|
|||||||
$text{'core_emaxconc'});
|
$text{'core_emaxconc'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub edit_MaxRequestWorkers
|
||||||
|
{
|
||||||
|
return (1,
|
||||||
|
&hlink($text{'core_maxconc'}, "MaxRequestWorkers"),
|
||||||
|
&opt_input($_[0]->{'value'}, "MaxRequestWorkers",
|
||||||
|
$text{'core_default'}, 4));
|
||||||
|
}
|
||||||
|
sub save_MaxRequestWorkers
|
||||||
|
{
|
||||||
|
return &parse_opt("MaxRequestWorkers", '^\d+$',
|
||||||
|
$text{'core_emaxconc'});
|
||||||
|
}
|
||||||
|
|
||||||
sub edit_MaxKeepAliveRequests
|
sub edit_MaxKeepAliveRequests
|
||||||
{
|
{
|
||||||
return (1,
|
return (1,
|
||||||
@@ -132,7 +146,7 @@ return &parse_opt("MaxKeepAliveRequests", '^\d+$',
|
|||||||
sub edit_MaxRequestsPerChild
|
sub edit_MaxRequestsPerChild
|
||||||
{
|
{
|
||||||
return (1,
|
return (1,
|
||||||
$text{'core_maxreq'},
|
&hlink($text{'core_maxreq'}, "MaxRequestsPerChild"),
|
||||||
&opt_input($_[0]->{'value'}, "MaxRequestsPerChild", $text{'core_default'}, 5));
|
&opt_input($_[0]->{'value'}, "MaxRequestsPerChild", $text{'core_default'}, 5));
|
||||||
}
|
}
|
||||||
sub save_MaxRequestsPerChild
|
sub save_MaxRequestsPerChild
|
||||||
@@ -144,7 +158,7 @@ return &parse_opt("MaxRequestsPerChild", '^\d+$',
|
|||||||
sub edit_MinSpareServers
|
sub edit_MinSpareServers
|
||||||
{
|
{
|
||||||
return (1,
|
return (1,
|
||||||
$text{'core_minspare'},
|
&hlink($text{'core_minspare'}, "MinSpareServers"),
|
||||||
&opt_input($_[0]->{'value'},"MinSpareServers",$text{'core_default'}, 4));
|
&opt_input($_[0]->{'value'},"MinSpareServers",$text{'core_default'}, 4));
|
||||||
}
|
}
|
||||||
sub save_MinSpareServers
|
sub save_MinSpareServers
|
||||||
@@ -156,7 +170,7 @@ return &parse_opt("MinSpareServers", '^\d+$',
|
|||||||
sub edit_MaxSpareServers
|
sub edit_MaxSpareServers
|
||||||
{
|
{
|
||||||
return (1,
|
return (1,
|
||||||
$text{'core_maxspare'},
|
&hlink($text{'core_maxspare'}, "MaxSpareServers"),
|
||||||
&opt_input($_[0]->{'value'},"MaxSpareServers",$text{'core_default'}, 4));
|
&opt_input($_[0]->{'value'},"MaxSpareServers",$text{'core_default'}, 4));
|
||||||
}
|
}
|
||||||
sub save_MaxSpareServers
|
sub save_MaxSpareServers
|
||||||
@@ -168,7 +182,7 @@ return &parse_opt("MaxSpareServers", '^\d+$',
|
|||||||
sub edit_StartServers
|
sub edit_StartServers
|
||||||
{
|
{
|
||||||
return (1,
|
return (1,
|
||||||
$text{'core_initial'},
|
&hlink($text{'core_initial'}, "StartServers"),
|
||||||
&opt_input($_[0]->{'value'}, "StartServers", $text{'core_default'}, 4));
|
&opt_input($_[0]->{'value'}, "StartServers", $text{'core_default'}, 4));
|
||||||
}
|
}
|
||||||
sub save_StartServers
|
sub save_StartServers
|
||||||
@@ -177,9 +191,70 @@ return &parse_opt("StartServers", '^\d+$',
|
|||||||
$text{'core_einitial'});
|
$text{'core_einitial'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub edit_ServerLimit
|
||||||
|
{
|
||||||
|
return (1,
|
||||||
|
&hlink($text{'core_serverlimit'}, "ServerLimit"),
|
||||||
|
&opt_input($_[0]->{'value'}, "ServerLimit", $text{'core_default'}, 4));
|
||||||
|
}
|
||||||
|
sub save_ServerLimit
|
||||||
|
{
|
||||||
|
return &parse_opt("ServerLimit", '^\d+$',
|
||||||
|
$text{'core_eserverlimit'});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub edit_MinSpareThreads
|
||||||
|
{
|
||||||
|
return (1,
|
||||||
|
&hlink($text{'worker_minspare'}, "MinSpareThreads"),
|
||||||
|
&opt_input($_[0]->{'value'},"MinSpareThreads",$text{'core_default'}, 4));
|
||||||
|
}
|
||||||
|
sub save_MinSpareThreads
|
||||||
|
{
|
||||||
|
return &parse_opt("MinSpareThreads", '^\d+$',
|
||||||
|
$text{'worker_eminspare'});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub edit_MaxSpareThreads
|
||||||
|
{
|
||||||
|
return (1,
|
||||||
|
&hlink($text{'worker_maxspare'}, "MaxSpareThreads"),
|
||||||
|
&opt_input($_[0]->{'value'},"MaxSpareThreads",$text{'core_default'}, 4));
|
||||||
|
}
|
||||||
|
sub save_MaxSpareThreads
|
||||||
|
{
|
||||||
|
return &parse_opt("MaxSpareThreads", '^\d+$',
|
||||||
|
$text{'worker_emaxspare'});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub edit_ThreadLimit
|
||||||
|
{
|
||||||
|
return (1,
|
||||||
|
&hlink($text{'worker_threadlimit'}, "ThreadLimit"),
|
||||||
|
&opt_input($_[0]->{'value'},"ThreadLimit",$text{'core_default'}, 4));
|
||||||
|
}
|
||||||
|
sub save_ThreadLimit
|
||||||
|
{
|
||||||
|
return &parse_opt("ThreadLimit", '^\d+$',
|
||||||
|
$text{'worker_ethreadlimit'});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub edit_ThreadsPerChild
|
||||||
|
{
|
||||||
|
return (1,
|
||||||
|
&hlink($text{'worker_threads'}, "ThreadsPerChild"),
|
||||||
|
&opt_input($_[0]->{'value'},"ThreadsPerChild",$text{'core_default'}, 4));
|
||||||
|
}
|
||||||
|
sub save_ThreadsPerChild
|
||||||
|
{
|
||||||
|
return &parse_opt("ThreadsPerChild", '^\d+$',
|
||||||
|
$text{'worker_ethreads'});
|
||||||
|
}
|
||||||
|
|
||||||
sub edit_RLimitCPU
|
sub edit_RLimitCPU
|
||||||
{
|
{
|
||||||
return &rlimit_input("RLimitCPU", $text{'core_cpulimit'}, $_[0]);
|
return &rlimit_input("RLimitCPU",
|
||||||
|
&hlink($text{'core_cpulimit'}, "RLimitCPU"), $_[0]);
|
||||||
}
|
}
|
||||||
sub save_RLimitCPU
|
sub save_RLimitCPU
|
||||||
{
|
{
|
||||||
@@ -188,7 +263,8 @@ return &parse_rlimit("RLimitCPU", $text{'core_cpulimit2'});
|
|||||||
|
|
||||||
sub edit_RLimitMEM
|
sub edit_RLimitMEM
|
||||||
{
|
{
|
||||||
return &rlimit_input("RLimitMEM", $text{'core_memlimit'}, $_[0]);
|
return &rlimit_input("RLimitMEM",
|
||||||
|
&hlink($text{'core_memlimit'}, "RLimitMEM"), $_[0]);
|
||||||
}
|
}
|
||||||
sub save_RLimitMEM
|
sub save_RLimitMEM
|
||||||
{
|
{
|
||||||
@@ -197,7 +273,8 @@ return &parse_rlimit("RLimitMEM", $text{'core_memlimit2'});
|
|||||||
|
|
||||||
sub edit_RLimitNPROC
|
sub edit_RLimitNPROC
|
||||||
{
|
{
|
||||||
return &rlimit_input("RLimitNPROC", $text{'core_proclimit'}, $_[0]);
|
return &rlimit_input("RLimitNPROC",
|
||||||
|
&hlink($text{'core_proclimit'}, "RLimitNPROC"), $_[0]);
|
||||||
}
|
}
|
||||||
sub save_RLimitNPROC
|
sub save_RLimitNPROC
|
||||||
{
|
{
|
||||||
@@ -958,6 +1035,234 @@ if ($in{'AuthType'}) { return ( [ $in{'AuthType'} ] ); }
|
|||||||
else { return ( [ ] ); }
|
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
|
sub edit_require
|
||||||
{
|
{
|
||||||
local($rv, $mode, $list);
|
local($rv, $mode, $list);
|
||||||
@@ -1051,7 +1356,7 @@ return &parse_opt("LockFile", '^\S+', $text{'core_elock'});
|
|||||||
|
|
||||||
sub edit_LimitRequestBody
|
sub edit_LimitRequestBody
|
||||||
{
|
{
|
||||||
return (1, $text{'core_maxbody'},
|
return (1, &hlink($text{'core_maxbody'}, "LimitRequestBody"),
|
||||||
&opt_input($_[0]->{'value'}, "LimitRequestBody", $text{'core_default'}, 8)
|
&opt_input($_[0]->{'value'}, "LimitRequestBody", $text{'core_default'}, 8)
|
||||||
.&ui_space(2).$text{'bytes'});
|
.&ui_space(2).$text{'bytes'});
|
||||||
}
|
}
|
||||||
@@ -1062,7 +1367,7 @@ return &parse_opt("LimitRequestBody", '^\d+$', $text{'core_ebody'});
|
|||||||
|
|
||||||
sub edit_LimitXMLRequestBody
|
sub edit_LimitXMLRequestBody
|
||||||
{
|
{
|
||||||
return (1, $text{'core_maxxml'},
|
return (1, &hlink($text{'core_maxxml'}, "LimitXMLRequestBody"),
|
||||||
&opt_input($_[0]->{'value'}, "LimitXMLRequestBody",
|
&opt_input($_[0]->{'value'}, "LimitXMLRequestBody",
|
||||||
$text{'core_default'}, 8).&ui_space(2).$text{'bytes'});
|
$text{'core_default'}, 8).&ui_space(2).$text{'bytes'});
|
||||||
}
|
}
|
||||||
@@ -1075,7 +1380,7 @@ return &parse_opt("LimitXMLRequestBody", '^\d+$', $text{'core_exml'});
|
|||||||
|
|
||||||
sub edit_LimitRequestFields
|
sub edit_LimitRequestFields
|
||||||
{
|
{
|
||||||
return (1, $text{'core_maxhead'},
|
return (1, &hlink($text{'core_maxhead'}, "LimitRequestFields"),
|
||||||
&opt_input($_[0]->{'value'}, "LimitRequestFields", $text{'core_default'}, 6));
|
&opt_input($_[0]->{'value'}, "LimitRequestFields", $text{'core_default'}, 6));
|
||||||
}
|
}
|
||||||
sub save_LimitRequestFields
|
sub save_LimitRequestFields
|
||||||
@@ -1085,7 +1390,7 @@ return &parse_opt("LimitRequestFields", '^\d+$', $text{'core_ehead'});
|
|||||||
|
|
||||||
sub edit_LimitRequestFieldsize
|
sub edit_LimitRequestFieldsize
|
||||||
{
|
{
|
||||||
return (1, $text{'core_maxshead'},
|
return (1, &hlink($text{'core_maxshead'}, "LimitRequestFieldsize"),
|
||||||
&opt_input($_[0]->{'value'}, "LimitRequestFieldsize", $text{'core_default'}, 6));
|
&opt_input($_[0]->{'value'}, "LimitRequestFieldsize", $text{'core_default'}, 6));
|
||||||
}
|
}
|
||||||
sub save_LimitRequestFieldsize
|
sub save_LimitRequestFieldsize
|
||||||
@@ -1095,7 +1400,7 @@ return &parse_opt("LimitRequestFieldsize", '^\d+$', $text{'core_eshead'});
|
|||||||
|
|
||||||
sub edit_LimitRequestLine
|
sub edit_LimitRequestLine
|
||||||
{
|
{
|
||||||
return (1, $text{'core_maxline'},
|
return (1, &hlink($text{'core_maxline'}, "LimitRequestLine"),
|
||||||
&opt_input($_[0]->{'value'}, "LimitRequestLine", $text{'core_default'}, 6));
|
&opt_input($_[0]->{'value'}, "LimitRequestLine", $text{'core_default'}, 6));
|
||||||
}
|
}
|
||||||
sub save_LimitRequestLine
|
sub save_LimitRequestLine
|
||||||
@@ -1402,4 +1707,3 @@ else { return ( [ ], [ ] ); }
|
|||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
|||||||
@@ -119,8 +119,10 @@ elsif ($in{'fmode'} == 1) {
|
|||||||
else {
|
else {
|
||||||
# Use a user-specified file
|
# Use a user-specified file
|
||||||
$f = $in{'file'};
|
$f = $in{'file'};
|
||||||
|
&allowed_auth_file($f) ||
|
||||||
|
&error(&text('cvirt_efile', &html_escape($f), $!));
|
||||||
}
|
}
|
||||||
-r $f || open(FILE, ">>$f") || &error(&text('cvirt_efile', &html_escape($f), $!));
|
-r $f || open(FILE, ">>", $f) || &error(&text('cvirt_efile', &html_escape($f), $!));
|
||||||
close(FILE);
|
close(FILE);
|
||||||
|
|
||||||
&lock_apache_files();
|
&lock_apache_files();
|
||||||
|
|||||||
@@ -3,31 +3,107 @@
|
|||||||
|
|
||||||
require './apache-lib.pl';
|
require './apache-lib.pl';
|
||||||
&ReadParse();
|
&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'});
|
$access{'vaddr'} || &error($text{'delete_ecannot'});
|
||||||
$conf = &get_config();
|
$conf = &get_config();
|
||||||
@d = split(/\0/, $in{'d'});
|
$can_vhost_files = &can_manage_vhost_files();
|
||||||
@d || &error($text{'delete_enone'});
|
@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
|
# Get them all
|
||||||
foreach $d (@d) {
|
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);
|
($vmembers, $vconf) = &get_virtual_config($d);
|
||||||
|
$vconf || &error($text{'delete_egone'});
|
||||||
&can_edit_virt($vconf) || &error(&text('delete_ecannot2',
|
&can_edit_virt($vconf) || &error(&text('delete_ecannot2',
|
||||||
&virtual_name($vconf)));
|
&virtual_name($vconf)));
|
||||||
|
$can_vhost_files && &is_default_vhost($vconf) &&
|
||||||
|
&error($text{'delete_edefault'});
|
||||||
push(@virts, $vconf);
|
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
|
# Delete their structures
|
||||||
&before_changing();
|
&before_changing(keys %file_virts);
|
||||||
foreach $vconf (@virts) {
|
foreach $vconf (@virts) {
|
||||||
&lock_file($vconf->{'file'});
|
&lock_file($vconf->{'file'});
|
||||||
&save_directive_struct($vconf, undef, $conf, $conf);
|
&save_directive_struct($vconf, undef, $conf, $conf);
|
||||||
&delete_file_if_empty($vconf->{'file'});
|
&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();
|
&flush_file_lines();
|
||||||
&unlock_all_files();
|
&unlock_all_files();
|
||||||
&update_last_config_change();
|
&update_last_config_change();
|
||||||
&after_changing();
|
&after_changing();
|
||||||
&webmin_log("virts", "delete", scalar(@virts));
|
$deleted += scalar(@virts);
|
||||||
|
&webmin_log("virts", "delete", $deleted);
|
||||||
&redirect("");
|
&redirect("");
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ print $text{'defines_desc'},"<p>\n";
|
|||||||
@defs = &get_httpd_defines(1);
|
@defs = &get_httpd_defines(1);
|
||||||
if (@defs) {
|
if (@defs) {
|
||||||
print &text('defines_config',
|
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");
|
print &ui_form_start("save_defines.cgi", "post");
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ print &ui_form_end([ [ "", $text{'save'} ] ]);
|
|||||||
if ($in{'type'} == 6) {
|
if ($in{'type'} == 6) {
|
||||||
$mfile = &find_directive("TypesConfig", $conf);
|
$mfile = &find_directive("TypesConfig", $conf);
|
||||||
if (!$mfile) { $mfile = $config{'mime_types'}; }
|
if (!$mfile) { $mfile = $config{'mime_types'}; }
|
||||||
if (!$mfile) { $mfile = &server_root("etc/mime.types", $conf); }
|
if (!$mfile) { $mfile = &server_root("etc/mime.types"); }
|
||||||
if (!-r $mfile) { $mfile = &server_root("conf/mime.types", $conf); }
|
if (!-r $mfile) { $mfile = &server_root("conf/mime.types"); }
|
||||||
$mfile = &server_root($mfile, $conf);
|
$mfile = &server_root($mfile);
|
||||||
print &ui_hr();
|
print &ui_hr();
|
||||||
print &ui_subheading($text{'global_mime'});
|
print &ui_subheading($text{'global_mime'});
|
||||||
print "$text{'global_mimedesc'}<p>\n";
|
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'}) );
|
$text{'global_add'}) );
|
||||||
print &ui_links_row(\@links);
|
print &ui_links_row(\@links);
|
||||||
print &ui_columns_start([ $text{'global_type'},
|
print &ui_columns_start([ $text{'global_type'},
|
||||||
@@ -41,7 +41,8 @@ if ($in{'type'} == 6) {
|
|||||||
if (/^\s*(\S+)\s*(.*)$/) {
|
if (/^\s*(\S+)\s*(.*)$/) {
|
||||||
print &ui_columns_row([
|
print &ui_columns_row([
|
||||||
&ui_link("edit_gmime_type.cgi?line=$line".
|
&ui_link("edit_gmime_type.cgi?line=$line".
|
||||||
"&file=$mfile", $1), $2 ]);
|
"&file=".&urlize($mfile), &html_escape($1)),
|
||||||
|
&html_escape($2) ]);
|
||||||
}
|
}
|
||||||
$line++;
|
$line++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,19 @@
|
|||||||
require './apache-lib.pl';
|
require './apache-lib.pl';
|
||||||
&ReadParse();
|
&ReadParse();
|
||||||
$access{'global'}==1 || &error($text{'mime_ecannot'});
|
$access{'global'}==1 || &error($text{'mime_ecannot'});
|
||||||
|
|
||||||
|
# Validate that the file parameter matches the actual MIME types file
|
||||||
|
$conf = &get_config();
|
||||||
|
$mfile = &find_directive("TypesConfig", $conf);
|
||||||
|
if (!$mfile) { $mfile = $config{'mime_types'}; }
|
||||||
|
if (!$mfile) { $mfile = &server_root("etc/mime.types", $conf); }
|
||||||
|
if (!-r $mfile) { $mfile = &server_root("conf/mime.types", $conf); }
|
||||||
|
$mfile = &server_root($mfile);
|
||||||
|
$in{'file'} eq $mfile || &error($text{'mime_ecannot'});
|
||||||
|
|
||||||
if (defined($in{'line'})) {
|
if (defined($in{'line'})) {
|
||||||
&ui_print_header(undef, $text{'mime_edit'}, "");
|
&ui_print_header(undef, $text{'mime_edit'}, "");
|
||||||
open(MIME, "<$in{'file'}");
|
open(MIME, "<", $in{'file'});
|
||||||
for($i=0; $i<=$in{'line'}; $i++) {
|
for($i=0; $i<=$in{'line'}; $i++) {
|
||||||
$line = <MIME>;
|
$line = <MIME>;
|
||||||
}
|
}
|
||||||
|
|||||||
7
apache/help/AssignUserId.html
Normal file
7
apache/help/AssignUserId.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Tie virtual to child process</header>
|
||||||
|
The <tt>AssignUserId</tt> directive assigns a virtual host to a child process
|
||||||
|
running with the selected user ID and group ID for the legacy perchild MPM.
|
||||||
|
<p>
|
||||||
|
This directive is only available for Apache versions and MPMs that support
|
||||||
|
perchild.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/ChildPerUserId.html
Normal file
7
apache/help/ChildPerUserId.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Child process UID assignments</header>
|
||||||
|
The <tt>ChildPerUserId</tt> directive defines how many child processes should
|
||||||
|
run for a selected user ID and group ID in the legacy perchild MPM.
|
||||||
|
<p>
|
||||||
|
This directive is only available for Apache versions and MPMs that support
|
||||||
|
perchild.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/LimitRequestBody.html
Normal file
7
apache/help/LimitRequestBody.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Maximum request body size</header>
|
||||||
|
The <tt>LimitRequestBody</tt> directive sets the maximum allowed size of an HTTP
|
||||||
|
request body in bytes.
|
||||||
|
<p>
|
||||||
|
This can be used to limit upload or form submission size for the server,
|
||||||
|
virtual host, directory, or location where the directive is applied.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/LimitRequestFields.html
Normal file
7
apache/help/LimitRequestFields.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Maximum headers in request</header>
|
||||||
|
The <tt>LimitRequestFields</tt> directive sets the maximum number of HTTP
|
||||||
|
request header fields that Apache will accept.
|
||||||
|
<p>
|
||||||
|
Lowering this limit can reduce exposure to unusually large requests, but values
|
||||||
|
that are too low can reject legitimate clients.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/LimitRequestFieldsize.html
Normal file
7
apache/help/LimitRequestFieldsize.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Maximum request header size</header>
|
||||||
|
The <tt>LimitRequestFieldSize</tt> directive sets the maximum size of each HTTP
|
||||||
|
request header field in bytes.
|
||||||
|
<p>
|
||||||
|
Lowering this limit can reject oversized request headers, but values that are
|
||||||
|
too low can break clients that send larger cookies or authorization headers.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/LimitRequestLine.html
Normal file
7
apache/help/LimitRequestLine.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Maximum request line size</header>
|
||||||
|
The <tt>LimitRequestLine</tt> directive sets the maximum size of the HTTP
|
||||||
|
request line in bytes.
|
||||||
|
<p>
|
||||||
|
This line contains the method, requested URI, and HTTP protocol version. Values
|
||||||
|
that are too low can reject legitimate long URLs.
|
||||||
|
<p><footer>
|
||||||
6
apache/help/LimitXMLRequestBody.html
Normal file
6
apache/help/LimitXMLRequestBody.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<header>Maximum XML request body size</header>
|
||||||
|
The <tt>LimitXMLRequestBody</tt> directive sets the maximum allowed size of an
|
||||||
|
XML request body in bytes.
|
||||||
|
<p>
|
||||||
|
It is mainly used by modules that parse XML request bodies, such as WebDAV.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/MaxClients.html
Normal file
8
apache/help/MaxClients.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Maximum simultaneous requests</header>
|
||||||
|
The <tt>MaxClients</tt> directive is the old Apache name for the maximum number
|
||||||
|
of requests that can be served at the same time. On Apache 2.4 and newer, the
|
||||||
|
equivalent directive is <tt>MaxRequestWorkers</tt>.
|
||||||
|
<p>
|
||||||
|
For prefork MPM, this limits child server processes. For threaded MPMs, it
|
||||||
|
limits the total number of worker threads across all child processes.
|
||||||
|
<p><footer>
|
||||||
9
apache/help/MaxRequestWorkers.html
Normal file
9
apache/help/MaxRequestWorkers.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<header>Maximum simultaneous requests</header>
|
||||||
|
The <tt>MaxRequestWorkers</tt> directive sets the maximum number of requests
|
||||||
|
that Apache can serve at the same time. Requests above this limit wait until an
|
||||||
|
existing worker is free.
|
||||||
|
<p>
|
||||||
|
For prefork MPM, this limits child server processes. For threaded MPMs, it
|
||||||
|
limits the total number of worker threads across all child processes. Raising
|
||||||
|
this value may also require increasing <tt>ServerLimit</tt>.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/MaxRequestsPerChild.html
Normal file
8
apache/help/MaxRequestsPerChild.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Maximum requests per child process</header>
|
||||||
|
The <tt>MaxRequestsPerChild</tt> directive sets how many requests an Apache
|
||||||
|
child process will handle before it exits and is replaced. A value of
|
||||||
|
<tt>0</tt> means the process is not recycled because of this limit.
|
||||||
|
<p>
|
||||||
|
Recycling can help contain memory growth in long-running processes, but setting
|
||||||
|
this too low can create unnecessary process churn.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/MaxSpareServers.html
Normal file
8
apache/help/MaxSpareServers.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Maximum idle server processes</header>
|
||||||
|
The <tt>MaxSpareServers</tt> directive sets the maximum number of idle child
|
||||||
|
server processes Apache tries to keep when using prefork-style process
|
||||||
|
handling.
|
||||||
|
<p>
|
||||||
|
If more idle child processes are available, Apache stops some of them to avoid
|
||||||
|
keeping unnecessary processes running.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/MaxSpareThreads.html
Normal file
7
apache/help/MaxSpareThreads.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Maximum idle worker threads</header>
|
||||||
|
The <tt>MaxSpareThreads</tt> directive sets the maximum number of idle worker
|
||||||
|
threads Apache tries to keep when using a threaded MPM such as worker or event.
|
||||||
|
<p>
|
||||||
|
If more idle threads are available, Apache can reduce the number of running
|
||||||
|
workers instead of keeping excess capacity open.
|
||||||
|
<p><footer>
|
||||||
6
apache/help/MaxThreadsPerChild.html
Normal file
6
apache/help/MaxThreadsPerChild.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<header>Maximum threads per child process</header>
|
||||||
|
The <tt>MaxThreadsPerChild</tt> directive sets the maximum number of worker
|
||||||
|
threads allowed in each child process for the legacy perchild MPM.
|
||||||
|
<p>
|
||||||
|
This directive only appears for Apache versions and MPMs that support perchild.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/MinSpareServers.html
Normal file
8
apache/help/MinSpareServers.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Minimum idle server processes</header>
|
||||||
|
The <tt>MinSpareServers</tt> directive sets the minimum number of idle child
|
||||||
|
server processes Apache tries to keep ready when using prefork-style process
|
||||||
|
handling.
|
||||||
|
<p>
|
||||||
|
If fewer idle child processes are available, Apache starts more so new
|
||||||
|
connections can be accepted without waiting for a process to be created.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/MinSpareThreads.html
Normal file
8
apache/help/MinSpareThreads.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Minimum idle worker threads</header>
|
||||||
|
The <tt>MinSpareThreads</tt> directive sets the minimum number of idle worker
|
||||||
|
threads Apache tries to keep ready when using a threaded MPM such as worker or
|
||||||
|
event.
|
||||||
|
<p>
|
||||||
|
If fewer idle threads are available, Apache starts or adjusts child processes
|
||||||
|
so new connections can be accepted without waiting for threads to become free.
|
||||||
|
<p><footer>
|
||||||
6
apache/help/NumServers.html
Normal file
6
apache/help/NumServers.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<header>Number of child processes</header>
|
||||||
|
The <tt>NumServers</tt> directive sets the number of child server processes for
|
||||||
|
the legacy perchild MPM.
|
||||||
|
<p>
|
||||||
|
This directive only appears for Apache versions and MPMs that support perchild.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/RLimitCPU.html
Normal file
8
apache/help/RLimitCPU.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>CPU resource limit</header>
|
||||||
|
The <tt>RLimitCPU</tt> directive sets a CPU time resource limit for processes
|
||||||
|
started by Apache in this context, such as CGI programs where supported by the
|
||||||
|
operating system.
|
||||||
|
<p>
|
||||||
|
The soft limit is applied first. If a hard limit is also set, it is the maximum
|
||||||
|
value that the process can raise the soft limit to.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/RLimitMEM.html
Normal file
8
apache/help/RLimitMEM.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Memory resource limit</header>
|
||||||
|
The <tt>RLimitMEM</tt> directive sets a memory resource limit for processes
|
||||||
|
started by Apache in this context, such as CGI programs where supported by the
|
||||||
|
operating system.
|
||||||
|
<p>
|
||||||
|
The soft limit is applied first. If a hard limit is also set, it is the maximum
|
||||||
|
value that the process can raise the soft limit to.
|
||||||
|
<p><footer>
|
||||||
8
apache/help/RLimitNPROC.html
Normal file
8
apache/help/RLimitNPROC.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<header>Process limit</header>
|
||||||
|
The <tt>RLimitNPROC</tt> directive sets a process count resource limit for
|
||||||
|
processes started by Apache in this context, such as CGI programs where
|
||||||
|
supported by the operating system.
|
||||||
|
<p>
|
||||||
|
The soft limit is applied first. If a hard limit is also set, it is the maximum
|
||||||
|
value that the process can raise the soft limit to.
|
||||||
|
<p><footer>
|
||||||
9
apache/help/ServerLimit.html
Normal file
9
apache/help/ServerLimit.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<header>Server process limit</header>
|
||||||
|
The <tt>ServerLimit</tt> directive sets the hard upper limit on the number of
|
||||||
|
Apache child server processes. It caps values such as
|
||||||
|
<tt>MaxRequestWorkers</tt> for prefork MPM, and works with
|
||||||
|
<tt>ThreadsPerChild</tt> for threaded MPMs.
|
||||||
|
<p>
|
||||||
|
Increasing this value may require a full Apache stop and start before it takes
|
||||||
|
effect.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/StartServers.html
Normal file
7
apache/help/StartServers.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Server processes at startup</header>
|
||||||
|
The <tt>StartServers</tt> directive sets how many child server processes Apache
|
||||||
|
starts when the server first launches.
|
||||||
|
<p>
|
||||||
|
Apache adjusts the number of child processes after startup based on traffic and
|
||||||
|
the spare process or spare thread limits.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/StartThreads.html
Normal file
7
apache/help/StartThreads.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Initial threads per child process</header>
|
||||||
|
The <tt>StartThreads</tt> directive sets how many worker threads are created at
|
||||||
|
startup for legacy threaded MPMs that support this directive.
|
||||||
|
<p>
|
||||||
|
Apache may adjust the number of running workers after startup based on traffic
|
||||||
|
and the configured spare thread limits.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/ThreadLimit.html
Normal file
7
apache/help/ThreadLimit.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Thread limit per child process</header>
|
||||||
|
The <tt>ThreadLimit</tt> directive sets the hard upper limit for the number of
|
||||||
|
worker threads that can be configured in each child process.
|
||||||
|
<p>
|
||||||
|
It must be high enough for <tt>ThreadsPerChild</tt>. Increasing this value may
|
||||||
|
require a full Apache stop and start before it takes effect.
|
||||||
|
<p><footer>
|
||||||
7
apache/help/ThreadsPerChild.html
Normal file
7
apache/help/ThreadsPerChild.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<header>Worker threads per child process</header>
|
||||||
|
The <tt>ThreadsPerChild</tt> directive sets how many worker threads Apache
|
||||||
|
creates in each child process when using a threaded MPM.
|
||||||
|
<p>
|
||||||
|
The total request capacity for threaded MPMs is controlled by this value
|
||||||
|
together with <tt>ServerLimit</tt> and <tt>MaxRequestWorkers</tt>.
|
||||||
|
<p><footer>
|
||||||
103
apache/index.cgi
103
apache/index.cgi
@@ -102,6 +102,10 @@ if (&can_edit_virt()) {
|
|||||||
push(@vproxy, undef);
|
push(@vproxy, undef);
|
||||||
$sn ||= &get_system_hostname();
|
$sn ||= &get_system_hostname();
|
||||||
push(@vurl, $defport ? "http://$sn:$defport/" : "http://$sn/");
|
push(@vurl, $defport ? "http://$sn:$defport/" : "http://$sn/");
|
||||||
|
push(@vfile, undef);
|
||||||
|
push(@vstatus, "");
|
||||||
|
push(@vsel, undef);
|
||||||
|
push(@vfilemanage, 0);
|
||||||
$showing_default++;
|
$showing_default++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,16 +132,23 @@ elsif ($httpd_modules{'core'} >= 1.2) {
|
|||||||
$ba = &find_directive("ServerName", $conf);
|
$ba = &find_directive("ServerName", $conf);
|
||||||
$nv{&to_ipaddress($ba ? $ba : &get_system_hostname())}++;
|
$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) {
|
if ($config{'show_order'} == 1) {
|
||||||
# sort by server name
|
# 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) {
|
elsif ($config{'show_order'} == 2) {
|
||||||
# sort by IP address
|
# 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'};
|
$vm = $v->{'members'};
|
||||||
if ($v->{'words'}->[0] =~ /^\[(\S+)\]:(\d+)$/) {
|
if ($v->{'words'}->[0] =~ /^\[(\S+)\]:(\d+)$/) {
|
||||||
# IPv6 address and port
|
# IPv6 address and port
|
||||||
@@ -163,7 +174,7 @@ foreach $v (@virt) {
|
|||||||
$idx = &indexof($v, @$conf);
|
$idx = &indexof($v, @$conf);
|
||||||
push(@vidx, $idx);
|
push(@vidx, $idx);
|
||||||
push(@vname, $text{'index_virt'});
|
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);
|
$sname = &find_directive("ServerName", $vm);
|
||||||
local $daddr = $addr eq "_default_" ||
|
local $daddr = $addr eq "_default_" ||
|
||||||
($addr eq "*" && $httpd_modules{'core'} < 1.2);
|
($addr eq "*" && $httpd_modules{'core'} < 1.2);
|
||||||
@@ -225,10 +236,34 @@ foreach $v (@virt) {
|
|||||||
}
|
}
|
||||||
$sp = undef if ($sp == 80 && $prot eq "http" ||
|
$sp = undef if ($sp == 80 && $prot eq "http" ||
|
||||||
$sp == 443 && $prot eq "https");
|
$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'}) {
|
!$access{'create'} && $access{'noconfig'}) {
|
||||||
# Can only manage one vhost, so go direct to it
|
# Can only manage one vhost, so go direct to it
|
||||||
&redirect($vlink[0]);
|
&redirect($vlink[0]);
|
||||||
@@ -297,7 +332,9 @@ if ($access{'global'}) {
|
|||||||
# work out select links
|
# work out select links
|
||||||
print &ui_tabs_start_tab("mode", "list");
|
print &ui_tabs_start_tab("mode", "list");
|
||||||
#print $text{'index_desclist'},"<p>\n";
|
#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 = ( );
|
@links = ( );
|
||||||
if ($showdel) {
|
if ($showdel) {
|
||||||
push(@links, &select_all_link("d"),
|
push(@links, &select_all_link("d"),
|
||||||
@@ -326,8 +363,10 @@ if ($config{'max_servers'} && @vname > $config{'max_servers'}) {
|
|||||||
}
|
}
|
||||||
elsif ($config{'show_list'} && scalar(@vname)) {
|
elsif ($config{'show_list'} && scalar(@vname)) {
|
||||||
# as list for people with lots of servers
|
# as list for people with lots of servers
|
||||||
|
$list_form = "vhosts_form";
|
||||||
if ($showdel) {
|
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_links_row(\@links);
|
||||||
print &ui_columns_start([
|
print &ui_columns_start([
|
||||||
@@ -337,19 +376,23 @@ elsif ($config{'show_list'} && scalar(@vname)) {
|
|||||||
$text{'index_port'},
|
$text{'index_port'},
|
||||||
$text{'index_name'},
|
$text{'index_name'},
|
||||||
$text{'index_root'},
|
$text{'index_root'},
|
||||||
|
$can_vhost_files ? ( $text{'index_status'} ) : ( ),
|
||||||
$text{'index_url'} ], 100);
|
$text{'index_url'} ], 100);
|
||||||
for($i=0; $i<@vname; $i++) {
|
for($i=0; $i<@vname; $i++) {
|
||||||
local @cols;
|
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($vaddr[$i]));
|
||||||
push(@cols, &html_escape($vport[$i]));
|
push(@cols, &html_escape($vport[$i]));
|
||||||
push(@cols, $vserv[$i] || $text{'index_auto'});
|
push(@cols, $vserv[$i] || $text{'index_auto'});
|
||||||
push(@cols, &html_escape($vproxy[$i]) ||
|
push(@cols, &html_escape($vproxy[$i]) ||
|
||||||
&html_escape($vroot[$i]));
|
&html_escape($vroot[$i]));
|
||||||
push(@cols, &ui_link($vurl[$i], $text{'index_view'}) );
|
push(@cols, $vstatus[$i]) if ($can_vhost_files);
|
||||||
if ($showdel && $vidx[$i]) {
|
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,
|
print &ui_checked_columns_row(\@cols, undef,
|
||||||
"d", $vidx[$i]);
|
"d", $vsel[$i]);
|
||||||
}
|
}
|
||||||
elsif ($showdel) {
|
elsif ($showdel) {
|
||||||
print &ui_columns_row([ "", @cols ]);
|
print &ui_columns_row([ "", @cols ]);
|
||||||
@@ -361,13 +404,23 @@ elsif ($config{'show_list'} && scalar(@vname)) {
|
|||||||
print &ui_columns_end();
|
print &ui_columns_end();
|
||||||
print &ui_links_row(\@links);
|
print &ui_links_row(\@links);
|
||||||
if ($showdel) {
|
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 {
|
else {
|
||||||
# as icons for niceness
|
# as icons for niceness
|
||||||
|
$list_form = "vhosts_form";
|
||||||
if ($showdel) {
|
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_links_row(\@links);
|
||||||
print "<table width=100% cellpadding=5>\n";
|
print "<table width=100% cellpadding=5>\n";
|
||||||
@@ -376,8 +429,9 @@ else {
|
|||||||
print '<div class="row icons-row inline-row">';
|
print '<div class="row icons-row inline-row">';
|
||||||
&generate_icon("images/virt.gif", $vname[$i], $vlink[$i],
|
&generate_icon("images/virt.gif", $vname[$i], $vlink[$i],
|
||||||
undef, undef, undef,
|
undef, undef, undef,
|
||||||
$vidx[$i] && $access{'vaddr'} ?
|
defined($vsel[$i]) && $vsel[$i] ne "" &&
|
||||||
&ui_checkbox("d", $vidx[$i]) : "");
|
$access{'vaddr'} ?
|
||||||
|
&ui_checkbox("d", $vsel[$i]) : "");
|
||||||
print "</div>\n";
|
print "</div>\n";
|
||||||
print "</td> <td valign=top>\n";
|
print "</td> <td valign=top>\n";
|
||||||
print "$vdesc[$i]<br>\n";
|
print "$vdesc[$i]<br>\n";
|
||||||
@@ -397,12 +451,24 @@ else {
|
|||||||
print "<b>$text{'index_root'}</b> ",
|
print "<b>$text{'index_root'}</b> ",
|
||||||
&html_escape($vroot[$i]),"</td> </tr>\n";
|
&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></td> </tr>\n";
|
||||||
}
|
}
|
||||||
print "</table>\n";
|
print "</table>\n";
|
||||||
print &ui_links_row(\@links);
|
print &ui_links_row(\@links);
|
||||||
if ($showdel) {
|
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();
|
print &ui_tabs_end_tab();
|
||||||
@@ -492,4 +558,3 @@ return $addr eq '_default_' || $addr eq '*' ? undef :
|
|||||||
$addr =~ /^\[(\S+)\]$/ && &check_ip6address($1) ? $1 :
|
$addr =~ /^\[(\S+)\]$/ && &check_ip6address($1) ? $1 :
|
||||||
&to_ipaddress($addr);
|
&to_ipaddress($addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ acl_types=أنواع التوجيه المتاحة
|
|||||||
acl_all=الكل
|
acl_all=الكل
|
||||||
acl_sel=المحدد ..
|
acl_sel=المحدد ..
|
||||||
acl_names=يمكن تعديل أسماء الخادم؟
|
acl_names=يمكن تعديل أسماء الخادم؟
|
||||||
acl_dirs=Apache directives available<br><font size=-1>(Subject to types limit above)</font>
|
acl_dirs=توجيهات Apache المتاحة، وفقًا لأنواع التوجيهات المحددة أعلاه
|
||||||
acl_dirs0=الكل
|
acl_dirs0=الكل
|
||||||
acl_dirs1=المدرجة فقط ..
|
acl_dirs1=المدرجة فقط ..
|
||||||
acl_dirs2=كل ما عدا المدرجة ..
|
acl_dirs2=كل ما عدا المدرجة ..
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ acl_types=Налични видове директиви
|
|||||||
acl_all=Всички
|
acl_all=Всички
|
||||||
acl_sel=Избрани..
|
acl_sel=Избрани..
|
||||||
acl_names=Може да редактира имена на сървъри?
|
acl_names=Може да редактира имена на сървъри?
|
||||||
acl_dirs=Достъпни директиви на Apache<br><font size=-1>(съгласно лимита на типове по-горе)</font>
|
acl_dirs=Налични директиви на Apache, ограничени от избраните по-горе типове директиви
|
||||||
acl_dirs0=Всички
|
acl_dirs0=Всички
|
||||||
acl_dirs1=Само изброените ..
|
acl_dirs1=Само изброените ..
|
||||||
acl_dirs2=Всички освен изброените ..
|
acl_dirs2=Всички освен изброените ..
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user