Compare commits

..

33 Commits

Author SHA1 Message Date
Jamie Cameron
0bbeb5f4f7 Merge pull request #2416 from abcbarryn/modules/legacy
Added local copy of perl ini module
2025-02-18 22:09:07 -08:00
Barry Nelson
7d24ec6846 Add local copy of perl ini module 2025-02-19 00:23:37 -05:00
Barry Nelson
7383e6ad8d Merge pull request #10 from webmin/modules/legacy
Update branch
2025-02-19 00:21:46 -05:00
Jamie Cameron
f42adffc15 Merge pull request #2404 from abcbarryn/modules/legacy
Perl scripts to enable XDMCP
2025-02-11 20:09:03 -08:00
Barry Nelson
13de6fea4e Perl script to enable XDMCP
This update will enable XDMCP which is required for the VNC client to function. This has been tested on CentOS stream 9 and SuSE Linux. It will create .bak files of the original configuration.
2025-02-11 18:15:09 -05:00
Barry Nelson
861462d499 Merge pull request #7 from webmin/modules/legacy
Merge pull request #2399 from abcbarryn/modules/legacy
2025-02-09 23:19:54 -05:00
Jamie Cameron
0ed2109fed Merge pull request #2399 from abcbarryn/modules/legacy
Completely disable http/https on port 6080.
2025-02-09 17:21:43 -08:00
Barry Nelson
452958387c Update create VNC service script.
Support systems without xinetd that use systemd instead, also detect if GDM is used and XDMCP is disabled and enabled it. The use still has to open the port for the web socket (default 6080) in the firewall themselves though. Tested on CentOS 9 and an older SuSE Linux.
2025-02-09 01:36:19 -05:00
Barry Nelson
0a51170d3c Patch to completely disable http/https protocol on port 6080.
Only wss (web socket proxy) protocol is enabled on port 6080 and that is required.
2025-02-07 13:55:55 -05:00
Barry Nelson
767aa3a353 Delete vnc/empty directory 2025-02-07 13:52:23 -05:00
Barry Nelson
7fadece759 Merge pull request #6 from webmin/modules/legacy
Merge pull request #2395 from abcbarryn/modules/legacy
2025-02-07 00:29:10 -05:00
Jamie Cameron
32502d0ec9 Merge pull request #2395 from abcbarryn/modules/legacy
This contains no changed files
2025-02-06 21:10:46 -08:00
Barry Nelson
40d42664dd Turn off web directory indexes on web sock proxy and spoof 404 error on vnc.html 2025-02-06 12:42:39 -05:00
Barry Nelson
02d2f59663 Delete vnc/empty/index.html 2025-02-06 12:40:12 -05:00
Barry Nelson
f63e31dd7e Dummy VNC page for web sock proxy 2025-02-06 01:31:45 -05:00
Barry Nelson
ec679ad594 Restricted VNC web page to Webmin and added credits. 2025-02-06 01:29:43 -05:00
Barry Nelson
b5ec296302 Merge pull request #4 from webmin/modules/legacy
Merge pull request #2391 from abcbarryn/modules/legacy
2025-02-06 01:21:09 -05:00
Jamie Cameron
0c7024863a Merge pull request #2391 from abcbarryn/modules/legacy
New VNC module
2025-02-04 19:16:35 -08:00
Barry Nelson
700b0b49fe Finished updating VNC to the new java script version 2025-02-04 18:16:48 -05:00
Barry Nelson
0d87f98edf Add files via upload 2025-02-04 18:15:08 -05:00
Barry Nelson
aa60c17d14 Add files via upload 2025-02-04 18:13:00 -05:00
Barry Nelson
6ef110bcff Add files via upload 2025-02-04 18:12:14 -05:00
Barry Nelson
d8e2ba9d06 Add files via upload 2025-02-04 18:11:15 -05:00
Barry Nelson
c0df2266f3 Add files via upload 2025-02-04 18:09:54 -05:00
Barry Nelson
44a727f3f9 Add files via upload 2025-02-04 18:08:22 -05:00
Barry Nelson
4f16a893b2 Add files via upload 2025-02-04 18:07:28 -05:00
Barry Nelson
8ec49e117a Add files via upload 2025-02-04 18:06:31 -05:00
Barry Nelson
284533ccbf Recreate vnc folder for version 2.0 using java script 2025-02-04 18:05:12 -05:00
Barry Nelson
61013cd1e0 Delete vnc directory 2025-02-04 18:04:07 -05:00
Barry Nelson
67bde6a6fc Delete vnc/lang directory 2025-02-04 18:03:22 -05:00
Barry Nelson
b46b118f76 Delete vnc/images directory 2025-02-04 18:03:00 -05:00
Barry Nelson
5c046d9250 Patches to allow for 4096 bit keys. 2025-02-04 17:57:04 -05:00
Ilia Ross
577b9a9691 Preserve unsupported legacy modules 2025-02-02 14:52:02 +02:00
50665 changed files with 200733 additions and 1659209 deletions

View File

@@ -1,14 +0,0 @@
# 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

9
.gitattributes vendored
View File

@@ -1,9 +0,0 @@
# webmin .gitattribues file
# help git / github to know the encoding of webmin (lang) files
# force module.info to iso-8859-1 even it contains other encodings
*/module.info working-tree-encoding=iso8859-1 git-encoding=iso8859-1
# set all .UTF-8 to UTF-8
*.UTF-8 working-tree-encoding=UTF-8 git-encoding=UTF-8

View File

@@ -1,15 +0,0 @@
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

View File

@@ -1,19 +0,0 @@
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

View File

@@ -1,29 +0,0 @@
name: Package and upload artifacts
on:
push:
branches:
- master
release:
types:
- prereleased
- released
jobs:
build:
uses: webmin/webmin-ci-cd/.github/workflows/master-workflow.yml@main
with:
build-type: package
project-name: ${{ github.event.repository.name }}
is-release: ${{ github.event_name == 'release' }}
is-prerelease: ${{ github.event.release.prerelease || false }}
secrets:
DEV_IP_ADDR: ${{ secrets.DEV_IP_ADDR }}
DEV_IP_KNOWN_HOSTS: ${{ secrets.DEV_IP_KNOWN_HOSTS }}
DEV_UPLOAD_SSH_USER: ${{ secrets.DEV_UPLOAD_SSH_USER }}
DEV_UPLOAD_SSH_DIR: ${{ secrets.DEV_UPLOAD_SSH_DIR }}
PRERELEASE_UPLOAD_SSH_DIR: ${{ secrets.PRERELEASE_UPLOAD_SSH_DIR }}
DEV_SSH_PRV_KEY: ${{ secrets.DEV_SSH_PRV_KEY }}
ALL_GPG_PH2: ${{ secrets.ALL_GPG_PH2 }}
CODE_REVIEW_API_KEY: ${{ secrets.CODE_REVIEW_API_KEY }}
CODE_REVIEW_SMTP_PASSWORD: ${{ secrets.CODE_REVIEW_SMTP_PASSWORD }}

25
.gitignore vendored
View File

@@ -1,25 +0,0 @@
# thumbnails
Thumbs.db
.xvpics
# python byte-compiled
*.py[cod]
# temp files
*~
*.bak
test
*.tmp
*.site
core
# build files
.builds
.build
# makedist.pl
tarballs/
minimal/
.DS_Store
.vscode/settings.json
debug.cgi

View File

@@ -1,6 +0,0 @@
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]

File diff suppressed because it is too large Load Diff

30
LICENCE
View File

@@ -1,30 +0,0 @@
BSD 3-Clause License
Copyright (c) Jamie Cameron
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,30 +0,0 @@
Japanese translation is released under following license.
---------------------------------------------------------
Copyright (c) Kazuya Sakakihara
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the developer nor the names of contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
---------------------------------------------------------

View File

@@ -1,225 +0,0 @@
#!/usr/local/bin/perl -w
use strict;
# Detect the operating system and version.
package OsChooser;
# Package scoped for mapping short names to long "proper" names
my %NAMES_TO_REAL;
# main
sub main {
if ($#ARGV < 1) { die "Usage: $0 os_list.txt outfile [0|1|2|3] [issue]\n"; }
my ($oslist, $out, $auto, $issue) = @ARGV;
return write_file($out, oschooser($oslist, $auto, $issue));
}
main() unless caller(); # make it testable and usable as a library
$| = 1;
sub oschooser {
my ($oslist, $auto, $issue) = @_;
my $ver_ref;
my ($list_ref, $names_ref) = parse_patterns($oslist);
if ($auto && ($ver_ref = auto_detect($oslist, $issue, $list_ref, $names_ref))) {
return ($ver_ref->[2], $ver_ref->[3], $ver_ref->[0], $ver_ref->[1]);
}
elsif (!$auto || ($auto == 3 && have_tty()) || $auto == 2) {
$ver_ref = ask_user($names_ref, $list_ref);
return ($ver_ref->[2], $ver_ref->[3], $ver_ref->[0], $ver_ref->[1]);
}
else {
print "Failed to detect operating system\n";
exit 1;
}
}
# Return a reference to a pre-parsed list array, and a ref to a names array
sub parse_patterns {
my ($oslist) = @_;
my @list;
my @names;
my %donename;
# Parse the patterns file
open(OS, "<$oslist") || die "failed to open $oslist : $!";
while(<OS>) {
chop;
if (/^([^\t]+)\t+([^\t]+)\t+([^\t]+)\t+([^\t]+)\t*(.*)$/) {
push(@list, [ $1, $2, $3, $4, $5 ]);
push(@names, $1) if (!$donename{$1}++);
$NAMES_TO_REAL{$1} ||= $3;
}
}
close(OS);
return (\@list, \@names);
}
# auto_detect($oslist, $issue)
# Returns detected OS details in a hash ref
sub auto_detect {
my ($oslist, $issue, $list_ref) = @_;
my $ver_ref;
my @list = @$list_ref;
# Try to guess the OS name and version
my $etc_issue;
my $uname = `uname -a`;
if ($issue) {
$etc_issue = `cat $issue`;
$uname = $etc_issue; # Strangely, I think this will work fine.
}
elsif (-r "/etc/.issue") {
$etc_issue = `cat /etc/.issue`;
}
elsif (-r "/etc/issue") {
$etc_issue = `cat /etc/issue`;
}
foreach my $o_ref (@list) {
if ($issue && $o_ref->[4]) {
$o_ref->[4] =~ s#cat [/a-zA-Z\-\s]*\s2#cat $issue 2#g;
} # Testable, but this regex substitution is dumb.XXX
local $^W = 0; # Disable warnings for evals, which may have undefined vars
if ($o_ref->[4] && eval "$o_ref->[4]") {
# Got a match! Resolve the versions
print "$o_ref->[4]\n";
$ver_ref = $o_ref;
if ($ver_ref->[1] =~ /\$/) {
$ver_ref->[1] = eval "($o_ref->[4]); $ver_ref->[1]";
}
if ($ver_ref->[3] =~ /\$/) {
$ver_ref->[3] = eval "($o_ref->[4]); $ver_ref->[3]";
}
last;
}
if ($@) {
print STDERR "Error parsing $o_ref->[4]\n";
}
}
return $ver_ref;
}
sub ask_user {
my ($names_ref, $list_ref) = @_;
my @names = @$names_ref;
my @list = @$list_ref;
my $vnum;
my $osnum;
# ask for the operating system name ourselves
my $dashes = "-" x 75;
print <<EOF;
For Webmin to work properly, it needs to know which operating system
type and version you are running. Please select your system type by
entering the number next to it from the list below
$dashes
EOF
{
my $i;
for($i=0; $i<@names; $i++) {
printf " %2d) %-20.20s ", $i+1, $names[$i];
print "\n" if ($i%3 == 2);
}
print "\n" if ($i%3);
}
print $dashes,"\n";
print "Operating system: ";
chop($osnum = <STDIN>);
if ($osnum !~ /^\d+$/) {
print "ERROR: You must enter the number next to your operating\n";
print "system, not its name or version number.\n\n";
exit 9;
}
if ($osnum < 1 || $osnum > @names) {
print "ERROR: $osnum is not a valid operating system number.\n\n";
exit 10;
}
print "\n";
# Ask for the operating system version
my $name = $names[$osnum-1];
print <<EOF;
Please enter the version of $name you are running
EOF
print "Version: ";
chop($vnum = <STDIN>);
if ($vnum !~ /^\S+$/) {
print "ERROR: An operating system number cannot contain\n\n";
print "spaces. It must be like 2.1 or ES4.0.\n";
exit 10;
}
print "\n";
return [ $name, $vnum,
$NAMES_TO_REAL{$name}, $vnum ];
}
# write_file($out, $os_type, $os_version, $real_os_type, $real_os_version)
# Write the name, version and real name and version to a file
sub write_file {
my ($out, $os_type, $os_version, $real_os_type, $real_os_version) = @_;
open(OUT, ">$out") or die "Failed to open $out for writing.";
print OUT "os_type='",$os_type,"'\n";
print OUT "os_version='",$os_version,"'\n";
print OUT "real_os_type='",$real_os_type,"'\n";
print OUT "real_os_version='",$real_os_version,"'\n";
return close(OUT);
}
sub have_tty
{
# Do we have a tty?
my $rv = system("tty >/dev/null 2>&1");
if ($?) {
return 0;
}
else {
return 1;
}
}
1;
__END__
=head1 OsChooser.pm
Attempt to detect operating system and version, or ask the user to select
from a list. Works from the command line, for usage from shell scripts,
or as a library for use within Perl scripts.
=head2 COMMAND LINE USE
OsChooser.pm os_list.txt outfile [auto] [issue]
Where "auto" can be the following values:
=over 4
=item 0
always ask user
=item 1
automatic, give up if fails
=item 2
automatic, ask user if fails
=item 3
automatic, ask user if fails and if a TTY
=back
=head2 SYNOPSIS
use OsChooser;
my ($os_type, $version, $real_os_type, $real_os_version) =
OsChooser->oschooser("os_list.txt", "outfile", $auto, [$issue]);
=cut

View File

@@ -1,53 +0,0 @@
## 内容
* [更新日志](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="稳定版">](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)
* [文档](#文档)
* [致谢](#致谢)
* [许可](#许可)
## 关于
**Webmin** 是一个基于网页的类Unix服务器系统管理工具全球安装超过 _1,000,000_ 次(没错,事宝藏!)。有了它,运维快人一步!比如用户,磁盘配额,服务或者配置文件,比如更改,控制开源应用,再比如 BIND DNS Server管理 Apache HTTP Server PHP MySQL 还有[许多许多好东西](https://doxfer.webmin.com/Webmin/Introduction)。
[![Quick UI overview 2021](https://user-images.githubusercontent.com/4426533/114315375-61a1c480-9b07-11eb-9aaf-4aa949a39ab7.png)](https://www.youtube.com/watch?v=daYG6O4AsEw)
可通过安装可定制的模块来扩展可用性。 除此之外,还有另外两个扩展其功能的项目:
* [Virtualmin](https://www.virtualmin.com) 是一个强大的,灵活的,最受欢迎的,最全面的 Linux 和 BSD 系统网络托管控制面板,在全球拥有超过 _150,000次_ 安装。它有开源社区支持的版本以及功能更丰富的Premium版本
* [Usermin](https://github.com/webmin/usermin) 顾名思义,呈现和控制以用户为中心的功能子集,而不是管理员级别的任务。
Webmin 包括 _116_ 个[标准模块](https://doxfer.webmin.com/Webmin/Webmin_Modules),并且至少有同样多的第三方模块。
### 系统要求
Perl 5.10 或更高。
## 安装
Webmin 可以两种方法安装:
1. 下载一个预编译包可用于不同的发行版CentOS, Fedora, SuSE, Mandriva, Debian, Ubuntu, Solaris 和 [其他发行版](https://webmin.com/support.html))。[下载页面直达车](https://webmin.com/download.html);
<kbd>注:非常建议[在你的系统添加源](https://doxfer.webmin.com/Webmin/Installation),这样可以自动更新</kbd>
2. 下载并解压[源码](https://prdownloads.sourceforge.net/webadmin/webmin-1.996.tar.gz)然后运行[_setup.sh_](https://webmin.com/tgz.html) 脚本,无需任何选项,也就是说会直接安装到当前目录。或者使用命令行参数,例如目标目录。
<kbd>注:如果你正在安装 Webmin [到Windows](https://webmin.com/windows.html) 系统上,你必须运行 `perl setup.pl` 命令。Windows 版能否正常运行取决于许多程序,和可能不属于标准发行版的模块。你需要 _process.exe_ 命令, _sc.exe_ 命令,以及 _Win32::Daemon_ Perl 模块。</kbd>
## 文档
完整的 Webmin 还有它所有模块的详细配置都在[维基页面](https://doxfer.webmin.com/Webmin/Main_Page).
## 致谢
### 首席开发者
* [Jamie Cameron](https://webmin.com/about.html) [![](https://github.com/webmin-devel/webmin/blob/master/media/linkedin-15x15.png?raw=true)](https://www.linkedin.com/in/jamiecameron2)
### 贡献者
* [Joe Cooper](https://github.com/swelljoe)
* [Ilia Rostovtsev](https://github.com/iliaross)
* [Kay Marquardt](https://github.com/gnadelwartz)
* [Nawawi Jamili](https://github.com/nawawi) + [其他无偿奉献的开发者](https://github.com/webmin/webmin/graphs/contributors)
## 许可
Webmin 基于 [BSD 许可](https://github.com/webmin/webmin/blob/master/LICENCE)发布。

View File

@@ -1,61 +0,0 @@
&nbsp;
<p align="center"><img src="https://user-images.githubusercontent.com/4426533/218263860-f7baf9d6-cb19-4ddc-86dc-ac1b7a3c3a8a.png" alt="Webmin" width="310px"></p>
&nbsp;
<p align="center"> <a href="https://webmin.com/docs/" target="_blank">Documentation</a> &nbsp;&nbsp;|&nbsp;&nbsp; <a href="https://webmin.com/faq/" target="_blank">FAQ</a> &nbsp;&nbsp;|&nbsp;&nbsp; <a href="https://webmin.com/security/" target="_blank">Security</a> &nbsp;&nbsp;|&nbsp;&nbsp; <a href="https://webmin.com/screenshots/" target="_blank">Screenshots</a>&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp; <a href="https://forum.virtualmin.com/c/webmin/12" target="_blank">Forum</a> <br><br> <a href="https://webmin.com/"><img src="https://img.shields.io/badge/downloads-25M+-brightgreen.svg" alt="Downloads"></a> <a href="https://github.com/webmin/webmin/releases/"><img src="https://img.shields.io/github/release/webmin/webmin" alt="Latest release"></a> <a href="https://github.com/webmin/webmin/stargazers"><img src="https://img.shields.io/github/stars/webmin/webmin" alt="Stars"></a> <a href="https://github.com/webmin/webmin/network/members"><img src="https://img.shields.io/github/forks/webmin/webmin" alt="Members"></a> <a href="https://github.com/webmin/webmin/contributors/"><img src="https://img.shields.io/github/contributors/webmin/webmin" alt="Contributors"></a> <a href="https://github.com/webmin/webmin/issues/"><img src="https://img.shields.io/github/issues-raw/webmin/webmin" alt="Issues"></a> <a href="https://github.com/webmin/webmin/blob/master/LICENCE"><img src="https://img.shields.io/github/license/webmin/webmin" alt="License"></a> </p>
&nbsp;
---
&nbsp;
* [Changelog](https://github.com/webmin/webmin/blob/master/CHANGELOG.md)
* [About](#about)
* [Installation](#installation)
* [Development](#development)
* [License](#license)
## About
**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">
<a href="https://webmin.com/screenshots/?theme=light#gh-light-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://github.com/user-attachments/assets/a01d0a78-4130-4665-9284-814955ae1c97">
</a>
<a href="https://webmin.com/screenshots/?theme=dark#gh-dark-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://github.com/user-attachments/assets/da4b90a0-c002-4e10-8b34-5acb251bbec9">
</a>
</p>
Usability can be expanded by installing modules, which can be custom made. Aside from this, there are two other major projects that extend its functionality:
* [Virtualmin](https://www.virtualmin.com) is a powerful, flexible, most popular, and most comprehensive web-hosting control panel for Linux, and BSD systems, with over _150,000_ installations worldwide. It is available in an open-source community-supported version, and a more feature-filled version with premium support;
* [Usermin](https://github.com/webmin/usermin) presents and controls a subset of user-centred features, rather than administrator-level tasks.
Webmin includes _116_ [standard modules](https://doxfer.webmin.com/Webmin/Webmin_Modules), and there are at least as many third-party modules.
### Requirements
Perl 5.10 or higher.
## Installation
For detailed installation instructions check our guide on [webmin.com/download](https://webmin.com/download) page.
## Development
### Lead developer
* [Jamie Cameron](https://webmin.com/about.html) [![](https://github.com/webmin-devel/webmin/blob/master/media/linkedin-15x15.png?raw=true)](https://www.linkedin.com/in/jamiecameron2)
### Developers
* [Ilia Rostovtsev](https://github.com/iliaross)
* [Joe Cooper](https://github.com/swelljoe)
### Contributors
* [Kay Marquardt](https://github.com/gnadelwartz)
* [Nawawi Jamili](https://github.com/nawawi)
* [unknown10777](https://github.com/unknown10777) + [90 more...](https://github.com/webmin/webmin/graphs/contributors)
## License
Webmin is released under the [BSD License](https://github.com/webmin/webmin/blob/master/LICENCE).

View File

@@ -1,242 +0,0 @@
> [!WARNING]
> **Found a bug?** If youve found a new security-related issue, email
> [security@webmin.com](mailto:security@webmin.com).
### Webmin 2.510 and below [October 9, 2025]
#### Host header injection vulnerability in the password reset feature [CVE-2025-61541]
- If the password reset feature is enabled, an attacker can use a specially
crafted host header to cause the password reset email to contain a link to a
malicious site.
> Thanks to Nyein Chan Aung and Mg Demon for reporting this.
### Webmin 2.202 and below [February 26, 2025]
#### SSL certificates from clients may be trusted unexpectedly
- 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.
- Upgrade to Webmin 2.301 or later, and if there is any chance of direct
requests by clients disable this at **Webmin ⇾ Webmin Configuration ⇾ IP
Access Control** page using **Trust level for proxy headers** option.
> Thanks to Keigo YAMAZAKI from LAC Co., Ltd. for reporting this.
### 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 Micros 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/

127
Webmin-API-1.0/API.pm Normal file
View File

@@ -0,0 +1,127 @@
package Webmin::API;
require 5.005_62;
require Exporter;
our @ISA = qw(Exporter);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
our @EXPORT = (
'$config_directory',
'$var_directory',
'$remote_error_handler',
'%month_to_number_map',
'%number_to_month_map',
'$config_file',
'%gconfig',
'$null_file',
'$path_separator',
'$root_directory',
'$module_name',
'@root_directories',
'$base_remote_user',
'$remote_user',
'$module_config_directory',
'$module_config_file',
'%config',
'$current_theme',
'$theme_root_directory',
'%tconfig',
'$tb',
'$cb',
'$scriptname',
'$webmin_logfile',
'$current_lang',
'$current_lang_info',
'@lang_order_list',
'%text',
'%module_info',
'$module_root_directory',
'$default_lang',
);
our $VERSION = '1.0';
# Find old symbols by Webmin import
my %oldsyms = %Webmin::API::;
# Preloaded methods go here.
$main::no_acl_check++;
$ENV{'WEBMIN_CONFIG'} ||= "/etc/webmin";
$ENV{'WEBMIN_VAR'} ||= "/var/webmin";
open(MINISERV, $ENV{'WEBMIN_CONFIG'}."/miniserv.conf") ||
die "Could not open Webmin config file ".
$ENV{'WEBMIN_CONFIG'}."/miniserv.conf : $!";
my $webmin_root;
while(<MINISERV>) {
s/\r|\n//g;
if (/^root=(.*)/) {
$webmin_root = $1;
}
}
close(MINISERV);
$webmin_root || die "Could not find Webmin root directory";
chdir($webmin_root);
if ($0 =~ /\/([^\/]+)$/) {
$0 = $webmin_root."/".$1;
}
else {
$0 = $webmin_root."/api.pl"; # Fake name
}
require './web-lib.pl';
&init_config();
# Export core symbols
foreach my $lib ("$webmin_root/web-lib.pl",
"$webmin_root/web-lib-funcs.pl") {
open(WEBLIB, $lib);
while(<WEBLIB>) {
if (/^sub\s+([a-z0-9\_]+)/i) {
push(@EXPORT, $1);
}
}
close(WEBLIB);
}
our @EXPORT_OK = ( @EXPORT );
1;
__END__
=head1 NAME
Webmin::API - Perl module to make calling of Webmin functions from regular
command-line Perl scripts easier.
=head1 SYNOPSIS
use Webmin::API;
@pids = &find_byname("httpd");
foreign_require("cron", "cron-lib.pl");
@jobs = &cron::list_cron_jobs();
=head1 DESCRIPTION
This module just provides a convenient way to call Webmin API functions
from a script that is not run as a Webmin CGI, without having to include a
bunch of boilerplate initialization code at the top. It's main job is to export
all API functions into the namespace of the caller, and to setup the Webmin
environment.
=head2 EXPORT
All core Webmin API functions, like find_byname, foreign_config and so on.
=head1 AUTHOR
Jamie Cameron, jcameron@webmin.com
=head1 SEE ALSO
perl(1).
=cut

6
Webmin-API-1.0/Changes Normal file
View File

@@ -0,0 +1,6 @@
Revision history for Perl extension Webmin::API.
1.0 Mon Dec 10 11:09:17 2007
- original version; created by h2xs 1.20 with options
-AXc -n Webmin::API

5
Webmin-API-1.0/MANIFEST Normal file
View File

@@ -0,0 +1,5 @@
API.pm
Changes
MANIFEST
Makefile.PL
test.pl

768
Webmin-API-1.0/Makefile Normal file
View File

@@ -0,0 +1,768 @@
# This Makefile is for the Webmin::API extension to perl.
#
# It was generated automatically by MakeMaker version
# 6.30_01 (Revision: Revision: 4535 ) from the contents of
# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
#
# ANY CHANGES MADE HERE WILL BE LOST!
#
# MakeMaker ARGV: ()
#
# MakeMaker Parameters:
# NAME => q[Webmin::API]
# PREREQ_PM => { }
# VERSION_FROM => q[API.pm]
# --- MakeMaker post_initialize section:
# --- MakeMaker const_config section:
# These definitions are from config.sh (via /usr/lib/perl/5.8/Config.pm)
# They may have been overridden via Makefile.PL or on the command line
AR = ar
CC = cc
CCCDLFLAGS = -fPIC
CCDLFLAGS = -Wl,-E
DLEXT = so
DLSRC = dl_dlopen.xs
LD = cc
LDDLFLAGS = -shared -L/usr/local/lib
LDFLAGS = -L/usr/local/lib
LIBC = /lib/libc-2.7.so
LIB_EXT = .a
OBJ_EXT = .o
OSNAME = linux
OSVERS = 2.6.24-19-server
RANLIB = :
SITELIBEXP = /usr/local/share/perl/5.8.8
SITEARCHEXP = /usr/local/lib/perl/5.8.8
SO = so
EXE_EXT =
FULL_AR = /usr/bin/ar
VENDORARCHEXP = /usr/lib/perl5
VENDORLIBEXP = /usr/share/perl5
# --- MakeMaker constants section:
AR_STATIC_ARGS = cr
DIRFILESEP = /
DFSEP = $(DIRFILESEP)
NAME = Webmin::API
NAME_SYM = Webmin_API
VERSION = 1.0
VERSION_MACRO = VERSION
VERSION_SYM = 1_0
DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
XS_VERSION = 1.0
XS_VERSION_MACRO = XS_VERSION
XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
INST_ARCHLIB = blib/arch
INST_SCRIPT = blib/script
INST_BIN = blib/bin
INST_LIB = blib/lib
INST_MAN1DIR = blib/man1
INST_MAN3DIR = blib/man3
MAN1EXT = 1p
MAN3EXT = 3pm
INSTALLDIRS = site
DESTDIR =
PREFIX = /usr
PERLPREFIX = $(PREFIX)
SITEPREFIX = $(PREFIX)/local
VENDORPREFIX = $(PREFIX)
INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.8
DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.8.8
DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5
DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.8
DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.8.8
DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5
DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
INSTALLBIN = $(PERLPREFIX)/bin
DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
INSTALLSITEBIN = $(SITEPREFIX)/bin
DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
INSTALLVENDORBIN = $(VENDORPREFIX)/bin
DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
INSTALLSCRIPT = $(PERLPREFIX)/bin
DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
INSTALLSITESCRIPT = $(SITEPREFIX)/bin
DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
INSTALLVENDORSCRIPT = $(VENDORPREFIX)/bin
DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1
DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1
DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3
DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3
DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
PERL_LIB = /usr/share/perl/5.8
PERL_ARCHLIB = /usr/lib/perl/5.8
LIBPERL_A = libperl.a
FIRST_MAKEFILE = Makefile
MAKEFILE_OLD = Makefile.old
MAKE_APERL_FILE = Makefile.aperl
PERLMAINCC = $(CC)
PERL_INC = /usr/lib/perl/5.8/CORE
PERL = /usr/bin/perl
FULLPERL = /usr/bin/perl
ABSPERL = $(PERL)
PERLRUN = $(PERL)
FULLPERLRUN = $(FULLPERL)
ABSPERLRUN = $(ABSPERL)
PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
PERL_CORE = 0
PERM_RW = 644
PERM_RWX = 755
MAKEMAKER = /usr/share/perl/5.8/ExtUtils/MakeMaker.pm
MM_VERSION = 6.30_01
MM_REVISION = Revision: 4535
# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
# DLBASE = Basename part of dynamic library. May be just equal BASEEXT.
FULLEXT = Webmin/API
BASEEXT = API
PARENT_NAME = Webmin
DLBASE = $(BASEEXT)
VERSION_FROM = API.pm
OBJECT =
LDFROM = $(OBJECT)
LINKTYPE = dynamic
BOOTDEP =
# Handy lists of source code files:
XS_FILES =
C_FILES =
O_FILES =
H_FILES =
MAN1PODS =
MAN3PODS = API.pm
# Where is the Config information that we are using/depend on
CONFIGDEP = $(PERL_ARCHLIB)$(DFSEP)Config.pm $(PERL_INC)$(DFSEP)config.h
# Where to build things
INST_LIBDIR = $(INST_LIB)/Webmin
INST_ARCHLIBDIR = $(INST_ARCHLIB)/Webmin
INST_AUTODIR = $(INST_LIB)/auto/$(FULLEXT)
INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)
INST_STATIC =
INST_DYNAMIC =
INST_BOOT =
# Extra linker info
EXPORT_LIST =
PERL_ARCHIVE =
PERL_ARCHIVE_AFTER =
TO_INST_PM = API.pm
PM_TO_BLIB = API.pm \
$(INST_LIB)/Webmin/API.pm
# --- MakeMaker platform_constants section:
MM_Unix_VERSION = 1.50_01
PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc
# --- MakeMaker tool_autosplit section:
# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
AUTOSPLITFILE = $(ABSPERLRUN) -e 'use AutoSplit; autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)'
# --- MakeMaker tool_xsubpp section:
# --- MakeMaker tools_other section:
SHELL = /bin/sh
CHMOD = chmod
CP = cp
MV = mv
NOOP = $(SHELL) -c true
NOECHO = @
RM_F = rm -f
RM_RF = rm -rf
TEST_F = test -f
TOUCH = touch
UMASK_NULL = umask 0
DEV_NULL = > /dev/null 2>&1
MKPATH = $(ABSPERLRUN) "-MExtUtils::Command" -e mkpath
EQUALIZE_TIMESTAMP = $(ABSPERLRUN) "-MExtUtils::Command" -e eqtime
ECHO = echo
ECHO_N = echo -n
UNINST = 0
VERBINST = 0
MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install({@ARGV}, '\''$(VERBINST)'\'', 0, '\''$(UNINST)'\'');'
DOC_INSTALL = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e perllocal_install
UNINSTALL = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e uninstall
WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist
MACROSTART =
MACROEND =
USEMAKEFILE = -f
FIXIN = $(PERLRUN) "-MExtUtils::MY" -e "MY->fixin(shift)"
# --- MakeMaker makemakerdflt section:
makemakerdflt: all
$(NOECHO) $(NOOP)
# --- MakeMaker dist section:
TAR = tar
TARFLAGS = cvf
ZIP = zip
ZIPFLAGS = -r
COMPRESS = gzip --best
SUFFIX = .gz
SHAR = shar
PREOP = $(NOECHO) $(NOOP)
POSTOP = $(NOECHO) $(NOOP)
TO_UNIX = $(NOECHO) $(NOOP)
CI = ci -u
RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
DIST_CP = best
DIST_DEFAULT = tardist
DISTNAME = Webmin-API
DISTVNAME = Webmin-API-1.0
# --- MakeMaker macro section:
# --- MakeMaker depend section:
# --- MakeMaker cflags section:
# --- MakeMaker const_loadlibs section:
# --- MakeMaker const_cccmd section:
# --- MakeMaker post_constants section:
# --- MakeMaker pasthru section:
PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
LINKTYPE="$(LINKTYPE)"\
PREFIX="$(PREFIX)"
# --- MakeMaker special_targets section:
.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir
# --- MakeMaker c_o section:
# --- MakeMaker xs_c section:
# --- MakeMaker xs_o section:
# --- MakeMaker top_targets section:
all :: pure_all manifypods
$(NOECHO) $(NOOP)
pure_all :: config pm_to_blib subdirs linkext
$(NOECHO) $(NOOP)
subdirs :: $(MYEXTLIB)
$(NOECHO) $(NOOP)
config :: $(FIRST_MAKEFILE) blibdirs
$(NOECHO) $(NOOP)
help :
perldoc ExtUtils::MakeMaker
# --- MakeMaker blibdirs section:
blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
$(NOECHO) $(NOOP)
# Backwards compat with 6.18 through 6.25
blibdirs.ts : blibdirs
$(NOECHO) $(NOOP)
$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_LIBDIR)
$(NOECHO) $(CHMOD) 755 $(INST_LIBDIR)
$(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists
$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_ARCHLIB)
$(NOECHO) $(CHMOD) 755 $(INST_ARCHLIB)
$(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists
$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_AUTODIR)
$(NOECHO) $(CHMOD) 755 $(INST_AUTODIR)
$(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists
$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
$(NOECHO) $(CHMOD) 755 $(INST_ARCHAUTODIR)
$(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists
$(INST_BIN)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_BIN)
$(NOECHO) $(CHMOD) 755 $(INST_BIN)
$(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists
$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_SCRIPT)
$(NOECHO) $(CHMOD) 755 $(INST_SCRIPT)
$(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists
$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_MAN1DIR)
$(NOECHO) $(CHMOD) 755 $(INST_MAN1DIR)
$(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists
$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
$(NOECHO) $(MKPATH) $(INST_MAN3DIR)
$(NOECHO) $(CHMOD) 755 $(INST_MAN3DIR)
$(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists
# --- MakeMaker linkext section:
linkext :: $(LINKTYPE)
$(NOECHO) $(NOOP)
# --- MakeMaker dlsyms section:
# --- MakeMaker dynamic section:
dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
$(NOECHO) $(NOOP)
# --- MakeMaker dynamic_bs section:
BOOTSTRAP =
# --- MakeMaker dynamic_lib section:
# --- MakeMaker static section:
## $(INST_PM) has been moved to the all: target.
## It remains here for awhile to allow for old usage: "make static"
static :: $(FIRST_MAKEFILE) $(INST_STATIC)
$(NOECHO) $(NOOP)
# --- MakeMaker static_lib section:
# --- MakeMaker manifypods section:
POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
POD2MAN = $(POD2MAN_EXE)
manifypods : pure_all \
API.pm \
API.pm
$(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) \
API.pm $(INST_MAN3DIR)/Webmin::API.$(MAN3EXT)
# --- MakeMaker processPL section:
# --- MakeMaker installbin section:
# --- MakeMaker subdirs section:
# none
# --- MakeMaker clean_subdirs section:
clean_subdirs :
$(NOECHO) $(NOOP)
# --- MakeMaker clean section:
# Delete temporary files but do not touch installed files. We don't delete
# the Makefile here so a later make realclean still has a makefile to use.
clean :: clean_subdirs
- $(RM_F) \
*$(LIB_EXT) core \
core.[0-9] $(INST_ARCHAUTODIR)/extralibs.all \
core.[0-9][0-9] $(BASEEXT).bso \
pm_to_blib.ts core.[0-9][0-9][0-9][0-9] \
$(BASEEXT).x $(BOOTSTRAP) \
perl$(EXE_EXT) tmon.out \
*$(OBJ_EXT) pm_to_blib \
$(INST_ARCHAUTODIR)/extralibs.ld blibdirs.ts \
core.[0-9][0-9][0-9][0-9][0-9] *perl.core \
core.*perl.*.? $(MAKE_APERL_FILE) \
perl $(BASEEXT).def \
core.[0-9][0-9][0-9] mon.out \
lib$(BASEEXT).def perlmain.c \
perl.exe so_locations \
$(BASEEXT).exp
- $(RM_RF) \
blib
- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)
# --- MakeMaker realclean_subdirs section:
realclean_subdirs :
$(NOECHO) $(NOOP)
# --- MakeMaker realclean section:
# Delete temporary files (via clean) and also delete dist files
realclean purge :: clean realclean_subdirs
- $(RM_F) \
$(MAKEFILE_OLD) $(FIRST_MAKEFILE)
- $(RM_RF) \
$(DISTVNAME)
# --- MakeMaker metafile section:
metafile : create_distdir
$(NOECHO) $(ECHO) Generating META.yml
$(NOECHO) $(ECHO) '# http://module-build.sourceforge.net/META-spec.html' > META_new.yml
$(NOECHO) $(ECHO) '#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#' >> META_new.yml
$(NOECHO) $(ECHO) 'name: Webmin-API' >> META_new.yml
$(NOECHO) $(ECHO) 'version: 1.0' >> META_new.yml
$(NOECHO) $(ECHO) 'version_from: API.pm' >> META_new.yml
$(NOECHO) $(ECHO) 'installdirs: site' >> META_new.yml
$(NOECHO) $(ECHO) 'requires:' >> META_new.yml
$(NOECHO) $(ECHO) '' >> META_new.yml
$(NOECHO) $(ECHO) 'distribution_type: module' >> META_new.yml
$(NOECHO) $(ECHO) 'generated_by: ExtUtils::MakeMaker version 6.30_01' >> META_new.yml
-$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml
# --- MakeMaker signature section:
signature :
cpansign -s
# --- MakeMaker dist_basics section:
distclean :: realclean distcheck
$(NOECHO) $(NOOP)
distcheck :
$(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck
skipcheck :
$(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck
manifest :
$(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest
veryclean : realclean
$(RM_F) *~ *.orig */*~ */*.orig
# --- MakeMaker dist_core section:
dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
$(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
-e ' if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\'' < -M '\''$(FIRST_MAKEFILE)'\'';'
tardist : $(DISTVNAME).tar$(SUFFIX)
$(NOECHO) $(NOOP)
uutardist : $(DISTVNAME).tar$(SUFFIX)
uuencode $(DISTVNAME).tar$(SUFFIX) $(DISTVNAME).tar$(SUFFIX) > $(DISTVNAME).tar$(SUFFIX)_uu
$(DISTVNAME).tar$(SUFFIX) : distdir
$(PREOP)
$(TO_UNIX)
$(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
$(RM_RF) $(DISTVNAME)
$(COMPRESS) $(DISTVNAME).tar
$(POSTOP)
zipdist : $(DISTVNAME).zip
$(NOECHO) $(NOOP)
$(DISTVNAME).zip : distdir
$(PREOP)
$(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
$(RM_RF) $(DISTVNAME)
$(POSTOP)
shdist : distdir
$(PREOP)
$(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
$(RM_RF) $(DISTVNAME)
$(POSTOP)
# --- MakeMaker distdir section:
create_distdir :
$(RM_RF) $(DISTVNAME)
$(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
-e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"
distdir : create_distdir distmeta
$(NOECHO) $(NOOP)
# --- MakeMaker dist_test section:
disttest : distdir
cd $(DISTVNAME) && $(ABSPERLRUN) Makefile.PL
cd $(DISTVNAME) && $(MAKE) $(PASTHRU)
cd $(DISTVNAME) && $(MAKE) test $(PASTHRU)
# --- MakeMaker dist_ci section:
ci :
$(PERLRUN) "-MExtUtils::Manifest=maniread" \
-e "@all = keys %{ maniread() };" \
-e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
-e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"
# --- MakeMaker distmeta section:
distmeta : create_distdir metafile
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}}) } ' \
-e ' or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"'
# --- MakeMaker distsignature section:
distsignature : create_distdir
$(NOECHO) cd $(DISTVNAME) && $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} => q{Public-key signature (added by MakeMaker)}}) } ' \
-e ' or print "Could not add SIGNATURE to MANIFEST: $${'\''@'\''}\n"'
$(NOECHO) cd $(DISTVNAME) && $(TOUCH) SIGNATURE
cd $(DISTVNAME) && cpansign -s
# --- MakeMaker install section:
install :: all pure_install doc_install
$(NOECHO) $(NOOP)
install_perl :: all pure_perl_install doc_perl_install
$(NOECHO) $(NOOP)
install_site :: all pure_site_install doc_site_install
$(NOECHO) $(NOOP)
install_vendor :: all pure_vendor_install doc_vendor_install
$(NOECHO) $(NOOP)
pure_install :: pure_$(INSTALLDIRS)_install
$(NOECHO) $(NOOP)
doc_install :: doc_$(INSTALLDIRS)_install
$(NOECHO) $(NOOP)
pure__install : pure_site_install
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
doc__install : doc_site_install
$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site
pure_perl_install ::
$(NOECHO) umask 022; $(MOD_INSTALL) \
$(INST_LIB) $(DESTINSTALLPRIVLIB) \
$(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
$(INST_BIN) $(DESTINSTALLBIN) \
$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
$(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
$(SITEARCHEXP)/auto/$(FULLEXT)
pure_site_install ::
$(NOECHO) umask 02; $(MOD_INSTALL) \
read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
$(INST_LIB) $(DESTINSTALLSITELIB) \
$(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
$(INST_BIN) $(DESTINSTALLSITEBIN) \
$(INST_SCRIPT) $(DESTINSTALLSITESCRIPT) \
$(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
$(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
$(PERL_ARCHLIB)/auto/$(FULLEXT)
pure_vendor_install ::
$(NOECHO) umask 022; $(MOD_INSTALL) \
$(INST_LIB) $(DESTINSTALLVENDORLIB) \
$(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
$(INST_BIN) $(DESTINSTALLVENDORBIN) \
$(INST_SCRIPT) $(DESTINSTALLVENDORSCRIPT) \
$(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
$(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)
doc_perl_install ::
doc_site_install ::
$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod
-$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH)
-$(NOECHO) umask 02; $(DOC_INSTALL) \
"Module" "$(NAME)" \
"installed into" "$(INSTALLSITELIB)" \
LINKTYPE "$(LINKTYPE)" \
VERSION "$(VERSION)" \
EXE_FILES "$(EXE_FILES)" \
>> $(DESTINSTALLSITEARCH)/perllocal.pod
doc_vendor_install ::
uninstall :: uninstall_from_$(INSTALLDIRS)dirs
$(NOECHO) $(NOOP)
uninstall_from_perldirs ::
uninstall_from_sitedirs ::
$(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist
uninstall_from_vendordirs ::
# --- MakeMaker force section:
# Phony target to force checking subdirectories.
FORCE:
$(NOECHO) $(NOOP)
# --- MakeMaker perldepend section:
# --- MakeMaker makefile section:
# We take a very conservative approach here, but it's worth it.
# We move Makefile to Makefile.old here to avoid gnu make looping.
$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
$(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
$(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
-$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
-$(NOECHO) $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
- $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
$(PERLRUN) Makefile.PL
$(NOECHO) $(ECHO) "==> Your Makefile has been rebuilt. <=="
$(NOECHO) $(ECHO) "==> Please rerun the $(MAKE) command. <=="
false
# --- MakeMaker staticmake section:
# --- MakeMaker makeaperl section ---
MAP_TARGET = perl
FULLPERL = /usr/bin/perl
$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
$(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@
$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib
$(NOECHO) $(ECHO) Writing \"$(MAKE_APERL_FILE)\" for this $(MAP_TARGET)
$(NOECHO) $(PERLRUNINST) \
Makefile.PL DIR= \
MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=
# --- MakeMaker test section:
TEST_VERBOSE=0
TEST_TYPE=test_$(LINKTYPE)
TEST_FILE = test.pl
TEST_FILES =
TESTDB_SW = -d
testdb :: testdb_$(LINKTYPE)
test :: $(TEST_TYPE)
test_dynamic :: pure_all
PERL_DL_NONLAZY=1 $(FULLPERLRUN) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
testdb_dynamic :: pure_all
PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) "-I$(INST_LIB)" "-I$(INST_ARCHLIB)" $(TEST_FILE)
test_ : test_dynamic
test_static :: test_dynamic
testdb_static :: testdb_dynamic
# --- MakeMaker ppd section:
# Creates a PPD (Perl Package Description) for a binary distribution.
ppd:
$(NOECHO) $(ECHO) '<SOFTPKG NAME="$(DISTNAME)" VERSION="1,0,0,0">' > $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <TITLE>$(DISTNAME)</TITLE>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <ABSTRACT></ABSTRACT>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <AUTHOR></AUTHOR>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <IMPLEMENTATION>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <OS NAME="$(OSNAME)" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <ARCHITECTURE NAME="i486-linux-gnu-thread-multi" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' <CODEBASE HREF="" />' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) ' </IMPLEMENTATION>' >> $(DISTNAME).ppd
$(NOECHO) $(ECHO) '</SOFTPKG>' >> $(DISTNAME).ppd
# --- MakeMaker pm_to_blib section:
pm_to_blib : $(TO_INST_PM)
$(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e 'pm_to_blib({@ARGV}, '\''$(INST_LIB)/auto'\'', '\''$(PM_FILTER)'\'')' \
API.pm $(INST_LIB)/Webmin/API.pm
$(NOECHO) $(TOUCH) pm_to_blib
# --- MakeMaker selfdocument section:
# --- MakeMaker postamble section:
# End.

View File

@@ -0,0 +1,8 @@
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'Webmin::API',
'VERSION_FROM' => 'API.pm', # finds $VERSION
'PREREQ_PM' => {}, # e.g., Module::Name => 1.1
);

3
Webmin-API-1.0/make-module.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
cd /usr/local/webadmin
tar --exclude blib --exclude .svn --exclude make-module.sh --exclude Makefile -cvzf ~/webmin.com/Webmin-API-1.0.tar.gz Webmin-API-1.0/

20
Webmin-API-1.0/test.pl Executable file
View File

@@ -0,0 +1,20 @@
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'
######################### We start with some black magic to print on failure.
# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)
BEGIN { $| = 1; print "1..1\n"; }
END {print "not ok 1\n" unless $loaded;}
use Webmin::API;
$loaded = 1;
print "ok 1\n";
######################### End of black magic.
# Insert your test code below (better if it prints "ok 13"
# (correspondingly "not ok 13") depending on the success of chunk 13
# of the test code):

File diff suppressed because one or more lines are too long

View File

@@ -1,68 +0,0 @@
---- Changes since 1.130 ----
Improved the code for finding the openssl program for generating certificates.
Added the ability to restrict allowed Unix users who can login as Webmin users.
---- Changes since 1.150 ----
Added a Module Config option for an alternate user and group list display, which takes up less space on systems with a large number of Webmin users.
---- Changes since 1.160 ----
When editing a Webmin user or group, modules are now displayed under category headings.
---- Changes since 1.170 ----
Added a button to the user editing page for switching the current Webmin login to that user, without needing to know his password.
---- Changes since 1.180 ----
Added module hiding button to the group page, as in the user page.
---- Changes since 1.190 ----
Users and groups can now be backed up using the Backup Configuration Files module.
---- Changes since 1.200 ----
Users and groups with the same name can now be created. Internally, Webmin now uses .gacl files instead of .acl to store group ACL settings.
---- Changes since 1.210 ----
Enhanced the Unix User Authentication page to allow different access to be granted to different users and group members.
---- Changes since 1.220 ----
Users can now be temporarily locked without their passwords being lost.
---- Changes since 1.230 ----
CIDR-format network addresses can now be used in the IP access control field.
The inactivity logout time can now be set on a per-Webmin user basis, rather than the global setting in the Webmin Configuration module applying to all users.
---- Changes since 1.250 ----
Added checkboxes and buttons on the module's main page for deleting several users and groups at once.
Webmin users created and managed by other modules can be marked as non-editable, to prevent them from being edited when any changes would be over-written.
The IP addresses of connected users are displayed on the sessions page.
---- Changes since 1.260 ----
Added the ability to control which hours of the day and days of the week a Webmin user can login.
---- Changes since 1.290 ----
Added an option on the Unix User Authentication page to allow Unix users who can sudo to root to login to Webmin with root privileges.
Added an option to the Unix User Authentication that lets users who pass PAM validation but have no Unix or Webmin account login as a selected Webmin user.
---- Changes since 1.330 ----
When a group is deleted, sub-groups are also removed, and the group is removed from any parents.
---- Changes since 1.360 ----
Added the Password Restrictions page, for configuring password quality and change time settings.
Re-designed the Edit User page to use the new Webmin UI library, and move lesser-used fields into collapsible sections.
Webmin users can have a real name, which can be any text you like.
---- Changes since 1.370 ----
When editing a user who inherits some modules and ACL settings from a group, they can no longer be de-selected or edited.
---- Changes since 1.380 ----
Fixed a bug that prevented cloning from copying detailed access control settings, and ensured that other user attributes like the group, theme, language and access times are cloned too.
Added back the ability to edit the global ACL for groups.
---- Changes since 1.390 ----
Updated the user interface to use the Webmin UI library.
---- Changes since 1.400 ----
Fixed the display of modules granted to groups.
Added a per-user option to opt out of forced password changes after a certain number of days.
A human-readable description of the password restrictions regular expression can be entered, for use in error messages.
Webmin users can now be given temporary passwords, which they are forced to change at the next login. Thanks to GE Medical Systems for supporting this feature.
---- Changes since 1.410 ----
Added an API function to allow easier anonymous module access setup.
---- Changes since 1.440 ----
Removed the Hide Unused button and associated functionality, as un-available modules are already automatically hidden in the Un-used Modules category.
Moved the 'global ACL' fields to the Edit User and Edit Group pages, so that restrictions applying to all modules can be more easily found and edited.
Added a per-user option to not grant that user new module permissions when Webmin is upgraded.
If any theme overlays are installed, users' overlays can be selected on the Edit User page.
Converted commands in the module's API file to POD format, and added more details about each function.
---- Changes since 1.520 ----
Added the User and Group Database page, for configuring Webmin to store all new users, groups and access control lists in a MySQL, PostgreSQL or LDAP database. This allows Webmin permissions to be shared between multiple systems.
---- Changes since 1.650 ----
Added support for two-factor authentication using Authy or Google Authenticator.
---- Changes since 1.660 ----
Converted all pages to use the common Webmin UI library for a more consistent interface.
Made all code Perl strict and warnings compliant.
---- Changes since 1.670 ----
Added a button for adding multiple Webmin users to a group.
---- Changes since 1.930 ----
Added support for creating "safe-mode" Webmin users who have access only to modules and permissions that don't grant root access.

File diff suppressed because it is too large Load Diff

View File

@@ -1,87 +0,0 @@
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
do 'acl-lib.pl';
our (%text, %in);
# acl_security_form(&options)
# Output HTML for editing security options for the acl module
sub acl_security_form
{
my ($o) = @_;
print &ui_table_row($text{'acl_users'},
&ui_radio("users_def", $o->{'users'} eq '*' ? 1 :
$o->{'users'} eq '~' ? 2 : 0,
[ [ 1, $text{'acl_uall'} ],
[ 2, $text{'acl_uthis'}."<br>" ],
[ 0, $text{'acl_usel'} ] ])."<br>\n".
&ui_select("users", [ split(/\s+/, $o->{'users'}) ],
[ (map { $_->{'name'} } &list_users()),
(map { [ '_'.$_->{'name'},
&text('acl_gr', $_->{'name'}) ] }
&list_groups()) ],
6, 1));
print &ui_table_row($text{'acl_mods'},
&ui_radio("mode", $o->{'mode'},
[ [ 0, $text{'acl_all'} ],
[ 1, $text{'acl_own'}."<br>" ],
[ 2, $text{'acl_sel'}."<br>" ] ]).
&ui_select("mods", [ split(/\s+/, $o->{'mods'}) ],
[ map { [ $_->{'dir'}, $_->{'desc'} ] }
&list_module_infos() ],
6, 1));
foreach my $f (&list_acl_yesno_fields()) {
print &ui_table_row($text{'acl_'.$f},
&ui_yesno_radio($f, $o->{$f}));
}
print &ui_table_hr();
print &ui_table_row($text{'acl_groups'},
&ui_yesno_radio("groups", $o->{'groups'}));
print &ui_table_row($text{'acl_gassign'},
&ui_radio("gassign_def", $o->{'gassign'} eq '*' ? 1 : 0,
[ [ 1, $text{'acl_gall'} ],
[ 0, $text{'acl_gsel'} ] ])."<br>\n".
&ui_select("gassign", [ split(/\s+/, $o->{'gassign'}) ],
[ map { $_->{'name'} } &list_groups() ],
6, 1));
}
# acl_security_save(&options)
# Parse the form for security options for the acl module
sub acl_security_save
{
my ($o) = @_;
if ($in{'users_def'} == 1) {
$o->{'users'} = '*';
}
elsif ($in{'users_def'} == 2) {
$o->{'users'} = '~';
}
else {
$o->{'users'} = join(" ", split(/\0/, $in{'users'}));
}
$o->{'mode'} = $in{'mode'};
$o->{'mods'} = $in{'mode'} == 2 ? join(" ", split(/\0/, $in{'mods'}))
: undef;
foreach my $f (&list_acl_yesno_fields()) {
$o->{$f} = $in{$f};
}
$o->{'groups'} = $in{'groups'};
$o->{'gassign'} = $in{'gassign_def'} ? '*' :
join(" ", split(/\0/, $in{'gassign'}));
}
sub list_acl_yesno_fields
{
return ('create', 'delete', 'rename', 'acl', 'cert', 'others', 'chcert',
'lang', 'locale', 'cats', 'theme', 'ips', 'perms', 'sync', 'unix', 'sessions',
'switch', 'times', 'pass', 'sql');
}

View File

@@ -1,108 +0,0 @@
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require 'acl-lib.pl'; ## no critic
our ($config_directory, %gconfig);
# backup_config_files()
# Returns files and directories that can be backed up
sub backup_config_files
{
my @rv;
# Add primary user and group files
my %miniserv;
&get_miniserv_config(\%miniserv);
push(@rv, $miniserv{'userfile'});
push(@rv, &acl_filename());
# Add all .acl files for users and groups
foreach my $u (&list_users(), &list_groups()) {
if (!$u->{'proto'}) {
push(@rv, "$config_directory/$u->{'name'}.acl",
glob("$config_directory/*/$u->{'name'}.acl"));
}
}
# Add /etc/webmin/config
&copy_source_dest("$config_directory/config",
"$config_directory/config.aclbackup");
push(@rv, "$config_directory/config.aclbackup");
# Add /etc/webmin/miniserv.conf
&copy_source_dest("$config_directory/miniserv.conf",
"$config_directory/miniserv.conf.aclbackup");
push(@rv, "$config_directory/miniserv.conf.aclbackup");
return @rv;
}
# pre_backup(&files)
# Called before the files are actually read
sub pre_backup
{
return;
}
# post_backup(&files)
# Called after the files are actually read
sub post_backup
{
unlink("$config_directory/config.aclbackup");
unlink("$config_directory/miniserv.conf.aclbackup");
return;
}
# pre_restore(&files)
# Called before the files are restored from a backup
sub pre_restore
{
# Remove user and group .acl files
foreach my $u (&list_users(), &list_groups()) {
if (!$u->{'proto'}) {
unlink("$config_directory/$u->{'name'}.acl",
glob("$config_directory/*/$u->{'name'}.acl"));
}
}
return;
}
# post_restore(&files)
# Called after the files are restored from a backup
sub post_restore
{
# Splice global config entries for users into real config
my %aclbackup;
&read_file("$config_directory/config.aclbackup", \%aclbackup);
unlink("$config_directory/config.aclbackup");
foreach my $k (keys %gconfig) {
delete($gconfig{$k}) if ($k =~ /^(lang_|notabs_|theme_|ownmods_)/);
}
foreach my $k (keys %aclbackup) {
$gconfig{$k} = $aclbackup{$k} if ($k =~ /^(lang_|notabs_|theme_|ownmods_)/);
}
&write_file("$config_directory/config", \%gconfig);
# Splice miniserv.conf entries for users and password restrictions into
# real config
%aclbackup = ( );
&read_file("$config_directory/miniserv.conf.aclbackup", \%aclbackup);
unlink("$config_directory/miniserv.conf.aclbackup");
my %miniserv;
&get_miniserv_config(\%miniserv);
foreach my $k (keys %miniserv) {
delete($miniserv{$k}) if ($k =~ /^(preroot_|pass_)/);
}
foreach my $k (keys %aclbackup) {
$miniserv{$k} = $aclbackup{$k} if ($k =~ /^(preroot_|pass_)/);
}
&put_miniserv_config(\%miniserv);
&restart_miniserv();
return;
}
1;

View File

@@ -1,56 +0,0 @@
#!/usr/local/bin/perl
# cert_form.cgi
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
&ui_print_header(undef, $text{'cert_title'}, "", undef, undef, undef, undef,
undef, undef, "language=VBSCRIPT onload='postLoad()'");
eval { require Net::SSLeay; Net::SSLeay->import; 1 };
print "<p>$text{'cert_msg'}<p>\n";
if ($ENV{'SSL_USER'}) {
print &text('cert_already', "<tt>$ENV{'SSL_USER'}</tt>"),
"<p>\n";
}
if ($ENV{'HTTP_USER_AGENT'} =~ /Mozilla/i) {
# Output a form that works for netscape and mozilla
print &ui_form_start("cert_issue.cgi", "post");
print &ui_table_start($text{'cert_header'}, undef, 2);
print &ui_table_row($text{'cert_cn'},
&ui_textbox("commonName", undef, 30));
print &ui_table_row($text{'cert_email'},
&ui_textbox("emailAddress", undef, 30));
print &ui_table_row($text{'cert_ou'},
&ui_textbox("organizationalUnitName", undef, 30));
print &ui_table_row($text{'cert_o'},
&ui_textbox("organizationName", undef, 30));
print &ui_table_row($text{'cert_sp'},
&ui_textbox("stateOrProvinceName", undef, 30));
print &ui_table_row($text{'cert_c'},
&ui_textbox("countryName", undef, 30));
print &ui_table_row($text{'cert_key'},
"<keygen name=key>");
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'cert_issue'} ] ]);
}
else {
# Unsupported browser!
print "<p><b>",&text('cert_ebrowser',
"<tt>$ENV{'HTTP_USER_AGENT'}</tt>"),"</b><p>\n";
}
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,58 +0,0 @@
#!/usr/local/bin/perl
# cert_issue.cgi
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $module_config_directory, $base_remote_user);
&ReadParse();
&error_setup($text{'cert_err'});
$in{'key'} || &error($text{'cert_ekey'});
my %miniserv;
&get_miniserv_config(\%miniserv);
# Create the new key
my $temp1 = &transname();
my $temp2 = &tempname();
my $fh = "IN";
&open_tempfile($fh, ">$temp1");
foreach my $k ("emailAddress", "organizationalUnitName", "organizationName",
"stateOrProvinceName", "countryName", "commonName") {
&print_tempfile($fh, "$k = $in{$k}\n");
}
$in{'key'} =~ s/\s//g;
&print_tempfile($fh, "SPKAC = $in{'key'}\n");
&close_tempfile($fh);
my $cmd = &get_ssleay();
my $ssleay = &backquote_logged("$cmd ca -spkac $temp1 -out $temp2 -config $module_config_directory/openssl.cnf -days 1095 2>&1");
&unlink_file($temp1);
if ($?) {
&error("<pre>$ssleay</pre>");
}
else {
# Display status and redirect to actual cert file
&ui_print_unbuffered_header(undef, $text{'cert_title'}, "");
print &text('cert_done', $in{'commonName'}),"<p>\n";
print &text('cert_pickup', "cert_output.cgi?file=$temp2"),"<p>\n";
&ui_print_footer("", $text{'index_return'});
# Update the Webmin user
my ($me) = grep { $_->{'name'} eq $base_remote_user } &list_users();
$me || &error($text{'edit_egone'});
$me->{'cert'} = "/C=$in{'countryName'}".
"/ST=$in{'stateOrProvinceName'}".
"/O=$in{'organizationName'}".
"/OU=$in{'organizationalUnitName'}".
"/CN=$in{'commonName'}".
"/Email=$in{'emailAddress'}";
&modify_user($me->{'name'}, $me);
sleep(1);
&restart_miniserv();
&webmin_log("cert", undef, $base_remote_user, \%in);
}

View File

@@ -1,19 +0,0 @@
#!/usr/local/bin/perl
# cert_issue.cgi
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
&ReadParse();
my $tempdir = &tempname();
$tempdir =~ s/\/[^\/]+$//;
&is_under_directory($tempdir, $in{'file'}) ||
&error($text{'cert_etempdir'});
print "Content-type: application/x-x509-user-cert\n\n";
print &read_file_contents($in{'file'});
&unlink_file($in{'file'});

View File

@@ -1,31 +0,0 @@
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
do 'acl-lib.pl';
our (%access);
sub cgi_args
{
my ($cgi) = @_;
if ($cgi eq 'edit_user.cgi') {
my ($u) = grep { &can_edit_user($_->{'name'}) } &list_users();
return $u ? 'user='.&urlize($u->{'name'}) :
$access{'create'} ? '' : 'none';
}
elsif ($cgi eq 'edit_group.cgi') {
my ($u) = grep { &can_edit_group($_->{'name'}) } &list_groups();
return $u ? 'group='.&urlize($u->{'name'}) :
$access{'groups'} ? '' : 'none';
}
elsif ($cgi eq 'edit_acl.cgi') {
my ($u) = grep { &can_edit_user($_->{'name'}) } &list_users();
if ($u && @{$u->{'modules'}}) {
return 'user='.&urlize($u->{'name'}).
'&mod='.$u->{'modules'}->[0];
}
return 'none';
}
return;
}

View File

@@ -1,4 +0,0 @@
ssleay=/usr/local/ssl/bin/openssl
select=0
order=0
display=1

View File

@@ -1,3 +0,0 @@
ssleay=/usr/bin/openssl
order=0
display=1

View File

@@ -1,3 +0,0 @@
ssleay=/usr/bin/openssl
order=0
display=1

View File

@@ -1,3 +0,0 @@
ssleay=/usr/bin/openssl
order=0
display=1

View File

@@ -1,3 +0,0 @@
ssleay=/usr/bin/openssl
order=0
display=1

View File

@@ -1,3 +0,0 @@
ssleay=/usr/bin/openssl
order=0
display=1

View File

@@ -1,3 +0,0 @@
ssleay=/usr/sfw/bin/openssl
order=0
display=1

View File

@@ -1,4 +0,0 @@
ssleay=/usr/bin/openssl
select=0
order=0
display=1

View File

@@ -1,5 +0,0 @@
line1=Configurable options,11
display=User and group display mode,1,1-Names only,0-Names and modules
order=Sort users and groups by,1,0-Order in file,1-Name
line2=System configuration,11
ssleay=Path to <tt>openssl</tt> or <tt>ssleay</tt> program,3,Automatic

View File

@@ -1,5 +0,0 @@
line1=تكوين الخيارات,11
display=وضع عرض المستخدم والمجموعة,1,1-الأسماء فقط,0-الأسماء والوحدات النمطية
order=فرز المستخدمين والمجموعات حسب,1,0-الطلب في الملف,1-الإ سم
line2=تكوين النظام,11
ssleay=المسار إلى openssl أو برنامج ssleay,3,تلقائي

View File

@@ -1,5 +0,0 @@
line1=Конфигурационни опции,11
display=Режим на показване на потребител и група,1,1-Само имена,0-Имена и модули
order=Подреди юзери и групи по,1,0-подредба във файл,1-име
line2=Системна конфигурация,11
ssleay=Път към openssl или ssleay програма,0

View File

@@ -1,5 +0,0 @@
line1=Opcions configurables,11
display=Forma de mostrar els usuaris i els grups,1,1-Només els noms,0-Noms i mòduls
order=Ordena els usuaris i grups per,1,0-L'ordre del fitxer,1-El nom
line2=Configuració del sistema,11
ssleay=Camí del programa <tt>openssl</tt> o <tt>ssleay</tt>,3,Automàtic

View File

@@ -1,5 +0,0 @@
line1=Možnosti konfigurace,11
display=Mód pro zobrazení uživatele a skupiny,1,1-Pouze jména,0-Jména a moduly
order=Třídit uživatele a skupiny podle,1,0-pořadí v souboru,1-jména
line2=Konfigurace systému,11
ssleay=Cesta k programu openssl nebo ssleay,0

View File

@@ -1,5 +0,0 @@
line1=Konfigurerbare indstillinger,11
display=Bruger og gruppe visnings mode,1,1-Kun navne,0-Navne og moduler
order=Sorter brugere og grupper ved,1.0-Sortering i fil,1-Navn
line2=Systemkonfiguration,11
ssleay=Sti til openssl eller ssleay progarm,3,Automatisk

View File

@@ -1,5 +0,0 @@
line1=Konfigurierbare Optionen,11
display=Benutzer- und Gruppenanzeige,1,1-Nur Namen,0-Namen und Module
order=Sortiere Benutzer und Gruppen nach,1,0-Reihenfolge in Datei,1-Name
line2=Systemkonfiguration,11
ssleay=Pfad zu <tt>openssl</tt> oder <tt>ssleay</tt>,3,Automatisch

View File

@@ -1,5 +0,0 @@
line1=Opciones Configurables,11
display=Modo de mostrar usuario y grupo,1,1-Sólo nombres,0-Nombres y módulos
order=Clasificar usuarios y grupos por,1,0-Orden en archivo,1-Nombre
line2=Configuración de Sistema,11
ssleay=Trayectoria al programa openssl o ssleay,0

View File

@@ -1,5 +0,0 @@
line1=Konfiguragarri diren aukerak, 11
display=Erabiltzaile eta taldea erakusteko modua, 1,1-Izenak soilik, 0-Izenak eta moduluak
order=Ordenatu erabiltzaile eta taldeak,1,0-Fitxategian ordenatu,1-Izena
line2=Sistemaren konfigurazioa,11
ssleay=Openssl edo ssleay programaren helbidea,3,Automatikoa

View File

@@ -1,5 +0,0 @@
line1=گزينه‌هاي پيکربندي,11
display=حالت نمايش کاربران و گروه‌ها,1,1-فقط نامها,0-نامها و پيمانه‌ها
order=مرتب سازي کاربران و گروه‌ها براساس,1,0-ترتيب در پرونده,1-نام
line2=پيکربندي سيستم,11
ssleay=مسير براي openssl يا برنامه ssleay,3,خودکار

View File

@@ -1,5 +0,0 @@
line1=Options configurables,11
display=Mode d'affichage des utilisateurs et des groupes,1,1-Noms seulement,0-Noms et modules
order=Trier les utilisateurs et les groupes par,1,0-Ordre dans le fichier,1-Nom
line2=Configuration du système,11
ssleay=Chemin d'accès au programme openssl ou ssleay,3,Automatique

View File

@@ -1,5 +0,0 @@
line1=Konfigurálható beállítások,11
display=Felhasználó és csoport megjelenítési mód,1,1-Csak a neveket,0-Neveket és modulokat
order=Felhasználók és csoportok rendezése,1,0-A fájl rendezése szerint,1-Név szerint
line2=Rendszer konfiguráció,11
ssleay=Az <code>openssl</code> vagy <code>ssleay</code> program teljes elérési útja,0

View File

@@ -1,5 +0,0 @@
line1=Opzioni configurabili,11
display=Modalità di visualizzazione di utenti e gruppi,1,1-Solo i nomi,0-Nomi e moduli
order=Ordina gli utenti e i gruppi per,1,0-Ordine nel file,1-Nome
line2=Configurazione di sistema,11
ssleay=Percorso al programma openssl o ssleay,3,Automatico

View File

@@ -1,5 +0,0 @@
line1=設定可能なオプション,11
display=ユーザとグループの表示モード,1,1-名前のみ,0-名前とモジュール
order=ユーザとグループのソート順,1,0-ファイル順,1-名前順
line2=システム設定,11
ssleay=opensslプログラムまたはssleayプログラムのパス,3,自動

View File

@@ -1,5 +0,0 @@
line1=가능한 옵션,11
display=유저와 그룹 출력 모드,1,1-이름만,0-이름과 모듈
order=유저와 그룹 정렬,1,0-파일 순,1-이름
line2=시스템 설정,11
ssleay=openssl 또는 ssleay 파일 경로,3,Automatic

View File

@@ -1,5 +0,0 @@
line1=Pilihan konfigurasi,11
display=Mod paparan pengguna dan grup,1,1-Nama sahaja,0-Nama dan modul
order=Tapis pengguna dan grup dengan,1,0-Urutan dalam fail,1-Nama
line2=Konfigurasi sistem,11
ssleay=Lokasi program openssl atau ssleay,3,Automatik

View File

@@ -1,5 +0,0 @@
line1=Instelbare opties,11
display=Gebruiker en groep weergave instelling,1,1-Alleen Namen,0-Namen en modules
order=Sorteer gebruikers en groepen op,1,0-Volgorde in bestand,1-Naam
line2=Systeem configuratie,11
ssleay=Pad naar openssl of ssleay programma,3,Automatisch

View File

@@ -1,5 +0,0 @@
line1=Konfigurerbare innstillinger,11
display=Visningsmodus for bruker og gruppe,1,1-Bare navn,0-Navn og moduler
order=Sorter brukere og grupper etter,1,0-Rekkefølge i filen,1-Navn
line2=System konfigurasjon,11
ssleay=Stien til openssl eller ssleay program,0

View File

@@ -1,5 +0,0 @@
line1=Opcje konfiguracyjne,11
display=Tryb wyświetlania użytkowników i grup,1,1-Tylko nazwy,0-Nazwy i moduły
order=Porządkuj użytkowników i grupy wg,1,0-Kolejności w zbiorze,1-Nazwy
line2=Konfiguracja systemu,11
ssleay=Ścieżka do programu openssl lub ssleay,0

View File

@@ -1,5 +0,0 @@
line1=Opções configuráveis,11
display=Modo de exibição de usuário e grupo, 1, 1-Somente nomes, 0-Nomes e módulos
order=Ordenar usuários e grupos por,1,0-Ordem no arquivo,1-Nome
line2=Configuração do sistema,11
ssleay=Caminho para o programa openssl ou ssleay,0

View File

@@ -1,5 +0,0 @@
line1=Настраиваемые параметры,11
display=Режим отображения пользователей и групп,1,1-Только имена,0-Имена и модули
order=Упорядочивать пользователей и группы по,1,0-Очередности в файле,1-Имени
line2=Системные параметры,11
ssleay=Путь к программе openssl или ssleay,0

View File

@@ -1,5 +0,0 @@
line1=Nastaviteľné možnosti,11
display=Spôsob zobrazenia užívateľov a skupín,1,1-Iba mená,0-Mená a moduly
order=Zoraď užívateľov a skupiny podľa,1,0-Poradia v súbore,1-Mena
line2=Nastavenie Systému,11
ssleay=Cesta k programu openssl alebo ssleay,3,Automatická

View File

@@ -1 +0,0 @@
ssleay=Sökväg till openssl- eller ssleay-program,0

View File

@@ -1,5 +0,0 @@
line1=Yapılandırılabilir seçenekler,11
display=Kullanıcı ve grup görüntüleme biçimi,1,1-Sadece isim,0-İsim ve modüller
order=Kullanıcı ve grupları bu şekilde sırala,1,0-Dosyadaki sırası ile,1-İsim ile
line2=Sistem yapılandırması,11
ssleay=Openssl ya da ssleay programı yolu,3,Otomatik

View File

@@ -1,4 +0,0 @@
line1=Параметри&#44; що настроюються,11
order=Упорядковувати користувачів і групи по,1,0-черговості у файлі,1-імені
line2=Системні параметри,11
ssleay=Шлях до програми openssl чи ssleay,0

View File

@@ -1 +0,0 @@
ssleay=Openssl 或者 Ssleay 程序的路径,0

View File

@@ -1,4 +0,0 @@
line1=組態選項,11
order=排序使用者和全組 依,1,0-檔案內位置,1-名稱
line2=系統組態,11
ssleay=openssl或ssleay程式路徑,0

View File

@@ -1,150 +0,0 @@
#!/usr/local/bin/perl
# convert.cgi
# Convert unix to webmin users
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $config_directory);
&ReadParse();
&error_setup($text{'convert_err'});
$access{'sync'} && $access{'create'} || &error($text{'convert_ecannot'});
&foreign_require("useradmin", "user-lib.pl");
# Validate inputs
my (%users, %nusers, $gid);
if ($access{'gassign'} ne '*') {
my @gcan = split(/\s+/, $access{'gassign'});
&indexof($in{'wgroup'}, @gcan) >= 0 ||
&error($text{'convert_ewgroup2'});
}
if ($in{'conv'} == 1) {
$in{'users'} =~ /\S/ || &error($text{'convert_eusers'});
map { $users{$_}++ } split(/\s+/, $in{'users'});
}
elsif ($in{'conv'} == 2) {
map { $nusers{$_}++ } split(/\s+/, $in{'nusers'});
}
elsif ($in{'conv'} == 3) {
$gid = getgrnam($in{'group'});
defined($gid) || &error($text{'convert_egroup'});
}
elsif ($in{'conv'} == 4) {
$in{'min'} =~ /^\d+$/ || &error($text{'convert_emin'});
$in{'max'} =~ /^\d+$/ || &error($text{'convert_emax'});
}
# Get the group to add to
my $group;
my %exists;
foreach my $g (&list_groups()) {
$group = $g if ($g->{'name'} eq $in{'wgroup'});
$exists{$g->{'name'}}++;
}
$group || &error($text{'convert_ewgroup'});
my (@ginfo, @members);
if ($in{'conv'} == 3) {
# Find secondary members of group
@ginfo = getgrnam($in{'group'});
@members = split(/\s+/, $ginfo[3]);
}
# Build the list of users
my @users;
if ($in{'sync'}) {
# Can just get from getpw* system calls, as password isn't needed
@users = ( );
setpwent();
while(my @uinfo = getpwent()) {
push(@users, { 'user' => $uinfo[0],
'pass' => $uinfo[1],
'uid' => $uinfo[2],
'gid' => $uinfo[3],
'real' => $uinfo[6],
'home' => $uinfo[7],
'shell' => $uinfo[8] });
}
}
else {
# Read /etc/passwd
@users = &useradmin::list_users();
}
# Convert matching users
&ui_print_header(undef, $text{'convert_title'}, "");
print $text{'convert_msg'},"<p>\n";
print &ui_columns_start([ $text{'convert_user'}, $text{'convert_action'} ]);
map { $exists{$_->{'name'}}++ } &list_users();
my ($skipped, $exists, $invalid, $converted) = (0, 0, 0, 0);
foreach my $u (@users) {
my $ok;
if ($in{'conv'} == 0) {
$ok = 1;
}
elsif ($in{'conv'} == 1) {
$ok = $users{$u->{'user'}};
}
elsif ($in{'conv'} == 2) {
$ok = !$nusers{$u->{'user'}};
}
elsif ($in{'conv'} == 3) {
$ok = $u->{'gid'} == $gid ||
&indexof($u->{'user'}, @members) >= 0;
}
elsif ($in{'conv'} == 4) {
$ok = $u->{'uid'} >= $in{'min'} &&
$u->{'uid'} <= $in{'max'};
}
my $msg;
if (!$ok) {
#print &text('convert_skip', $u->{'user'}),"\n";
$msg = undef;
$skipped++;
}
elsif ($exists{$u->{'user'}}) {
$msg = "<i>".&text('convert_exists', $u->{'user'})."</i>";
$exists++;
}
elsif ($u->{'user'} !~ /^[A-z0-9\-\_\.]+$/) {
$msg = "<i>".&text('convert_invalid', $u->{'user'})."</i>";
$invalid++;
}
else {
# Actually add the user
$msg = "<b>".&text('convert_added', $u->{'user'})."</b>";
my $user = { 'name' => $u->{'user'},
'pass' => $in{'sync'} ? 'x' : $u->{'pass'},
'modules' => $group->{'modules'} };
&create_user($user);
foreach my $m (@{$group->{'modules'}}, "") {
my %groupacl;
if (&read_file(
"$config_directory/$m/$in{'wgroup'}.gacl",
\%groupacl)) {
&write_file(
"$config_directory/$m/$u->{'user'}.acl",
\%groupacl);
}
}
push(@{$group->{'members'}}, $u->{'user'});
$exists{$u->{'user'}}++;
$converted++;
}
print &ui_columns_row([ $u->{'user'}, $msg ]) if ($msg);
}
endpwent();
print &ui_columns_end();
# Finish off
&modify_group($group->{'name'}, $group);
&restart_miniserv();
# Print summary
print &text('convert_done', $converted, $invalid, $exists, $skipped),"<p>\n";
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,54 +0,0 @@
#!/usr/local/bin/perl
# convert_form.cgi
# Display a form for converting unix users to webmin users
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
$access{'sync'} && $access{'create'} || &error($text{'convert_ecannot'});
&ui_print_header(undef, $text{'convert_title'}, "");
my @glist = &list_groups();
if ($access{'gassign'} ne '*') {
my @gcan = split(/\s+/, $access{'gassign'});
@glist = grep { &indexof($_->{'name'}, @gcan) >= 0 } @glist;
}
if (!@glist) {
print "$text{'convert_nogroups'}<p>\n";
&ui_print_footer("", $text{'index_return'});
exit;
}
print "$text{'convert_desc'}<p>\n";
print &ui_form_start("convert.cgi", "post");
print &ui_table_start(undef, undef, 2);
# Users to convert
print &ui_table_row($text{'convert_users'},
&ui_radio_table("conv", 0,
[ [ 0, $text{'convert_0'} ],
[ 1, $text{'convert_1'}, &ui_textbox("users", undef, 60)." ".
&user_chooser_button("users", 1) ],
[ 2, $text{'convert_2'}, &ui_textbox("nusers", undef, 60)." ".
&user_chooser_button("nusers", 1) ],
[ 3, $text{'convert_3'}, &unix_group_input("group") ],
[ 4, $text{'convert_4'}, &ui_textbox("min", undef, 6)." - ".
&ui_textbox("max", undef, 6) ]
]));
# Put into group
print &ui_table_row($text{'convert_group'},
&ui_select("wgroup", undef, [ map { $_->{'name'} } @glist ]));
# Keep passwords in sync
print &ui_table_row($text{'convert_sync2'},
&ui_yesno_radio("sync", 1));
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'convert_ok'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,27 +0,0 @@
users=*
mode=0
create=1
delete=1
rename=1
others=1
cert=1
acl=1
chcert=1
lang=1
locale=1
groups=1
gassign=*
perms=0
sync=1
unix=1
theme=1
sessions=1
cats=1
ips=1
switch=1
logouttime=1
times=1
minsize=1
nochange=1
pass=1
sql=1

View File

@@ -1,54 +0,0 @@
#!/usr/local/bin/perl
# delete_group.cgi
# Delete a group (and maybe it's members)
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $base_remote_user);
&ReadParse();
&error_setup($text{'gdelete_err'});
$access{'groups'} || &error($text{'gdelete_ecannot'});
my @glist = &list_groups();
my ($group) = grep { $_->{'name'} eq $in{'group'} } @glist;
my @mems = @{$group->{'members'}};
foreach my $m (@mems) {
&error($text{'gdelete_esub'}) if ($m =~ /^\@/);
}
if (&indexof($base_remote_user, @mems) >= 0) {
&error($text{'gdelete_euser'});
}
elsif (@mems && !$in{'confirm'}) {
# Ask if the user really wants to delete the group and members
&ui_print_header(undef, $text{'gdelete_title'}, "");
print &ui_confirmation_form(
"delete_group.cgi",
&text('gdelete_desc', "<tt>$in{'group'}</tt>",
"<tt>".join(" ", @mems)."</tt>"),
[ [ "group", $in{'group'} ] ],
[ [ "confirm", $text{'gdelete_ok'} ] ],
);
&ui_print_footer("", $text{'index_return'});
}
else {
# Delete the group (and members if any)
&delete_group($in{'group'});
foreach my $u (@mems) {
if ($u =~ /^\@(.*)/) {
&delete_group("$1");
}
else {
&delete_user($u);
}
}
&delete_from_groups("\@".$in{'group'});
&reload_miniserv();
&webmin_log("delete", "group", $in{'group'});
&redirect("");
}

View File

@@ -1,63 +0,0 @@
#!/usr/local/bin/perl
# Delete a bunch of Webmin groups
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $base_remote_user);
&ReadParse();
&error_setup($text{'gdeletes_err'});
$access{'groups'} || &error($text{'gdelete_ecannot'});
# Validate inputs
my @d = split(/\0/, $in{'d'});
@d || &error($text{'udeletes_enone'});
my @glist = &list_groups();
my $ucount = 0;
foreach my $g (@d) {
my ($group) = grep { $_->{'name'} eq $g } @glist;
foreach my $m (@{$group->{'members'}}) {
&error($text{'gdelete_esub'}) if ($m =~ /^\@/);
&error($text{'gdelete_euser'}) if ($m eq $base_remote_user);
$ucount++;
}
}
if ($in{'confirm'}) {
# Do it
foreach my $g (@d) {
my ($group) = grep { $_->{'name'} eq $g } @glist;
&delete_group($g);
foreach my $u (@{$group->{'members'}}) {
if ($u =~ /^\@(.*)/) {
&delete_group("$1");
}
else {
&delete_user($u);
}
}
&delete_from_groups("\@".$g);
}
&reload_miniserv();
&webmin_log("delete", "groups", scalar(@d));
&redirect("");
}
else {
# Ask the user if he is sure
&ui_print_header(undef, $text{'gdeletes_title'}, "");
print &ui_confirmation_form(
"delete_groups.cgi",
&text('gdeletes_rusure', scalar(@d), $ucount),
[ map { [ "d", $_ ] } @d ],
[ [ "confirm", $text{'gdeletes_ok'} ] ],
undef,
&text('gdeletes_users', join(" ", map { "<tt>$_</tt>" } @d)),
);
&ui_print_footer("", $text{'index_return'});
}

View File

@@ -1,20 +0,0 @@
#!/usr/local/bin/perl
# delete_session.cgi
# Delete a single session
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, %sessiondb);
&ReadParse();
$access{'sessions'} || &error($text{'sessions_ecannot'});
my %miniserv;
&get_miniserv_config(\%miniserv);
&delete_session_id(\%miniserv, $in{'id'});
&restart_miniserv();
&redirect($in{'redirect_ref'} ?
&get_referer_relative() : "list_sessions.cgi");

View File

@@ -1,24 +0,0 @@
#!/usr/local/bin/perl
# delete_user.cgi
# Delete a webmin user
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $base_remote_user);
&ReadParse();
&error_setup($text{'delete_err'});
$access{'delete'} || &error($text{'delete_ecannot'});
&can_edit_user($in{'user'}) || &error($text{'delete_euser'});
&used_for_anonymous($in{'user'}) && &error($text{'delete_eanonuser'});
if ($base_remote_user eq $in{'user'}) {
&error($text{'delete_eself'});
}
&delete_user($in{'user'});
&delete_from_groups($in{'user'});
&reload_miniserv();
&webmin_log("delete", "user", $in{'user'});
&redirect("");

View File

@@ -1,112 +0,0 @@
#!/usr/local/bin/perl
# Delete a bunch of Webmin users, or add them to a group
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $base_remote_user);
&ReadParse();
&error_setup($in{'joingroup'} ? $text{'udeletes_jerr'} : $text{'udeletes_err'});
# Validate inputs
my @d = split(/\0/, $in{'d'});
@d || &error($text{'udeletes_enone'});
foreach my $user (@d) {
&can_edit_user($user) || &error($text{'delete_euser'});
if ($base_remote_user eq $user && !$in{'joingroup'}) {
&error($text{'delete_eself'});
}
&used_for_anonymous($user) && &error($text{'delete_eanonuser'});
my $uinfo = &get_user($user);
$uinfo->{'readonly'} && &error($text{'udeletes_ereadonly'});
}
if ($in{'joingroup'}) {
# Add users to a group
my $newgroup = &get_group($in{'group'});
if ($access{'gassign'} ne '*') {
my @gcan = split(/\s+/, $access{'gassign'});
&indexof($in{'group'}, @gcan) >= 0 ||
&error($text{'save_egroup'});
}
foreach my $user (@d) {
my $uinfo = &get_user($user);
next if (!$uinfo);
next if ($newgroup &&
&indexof($user, @{$newgroup->{'members'}}) >= 0);
# Remove from old group, if any
my $oldgroup = &get_users_group($user);
if ($oldgroup) {
$oldgroup->{'members'} =
[ grep { $_ ne $user }
@{$oldgroup->{'members'}} ];
&modify_group($oldgroup->{'name'}, $oldgroup);
}
# Add to new group
push(@{$newgroup->{'members'}}, $user);
&modify_group($newgroup->{'name'}, $newgroup);
my @mods = @{$uinfo->{'modules'}};
if ($oldgroup) {
# Remove modules from the old group
@mods = grep { &indexof($_, @{$oldgroup->{'modules'}})
< 0 } @mods;
}
if ($newgroup) {
# Add modules from group to list
my @ownmods;
foreach my $m (@mods) {
push(@ownmods, $m) if (&indexof($m,
@{$newgroup->{'modules'}}) < 0);
}
@mods = &unique(@mods, @{$newgroup->{'modules'}});
$uinfo->{'ownmods'} = \@ownmods;
# Copy ACL files for group
&copy_group_user_acl_files($in{'group'}, $user,
[ @{$newgroup->{'modules'}}, "" ]);
}
$uinfo->{'modules'} = \@mods;
# Save the user
&modify_user($user, $uinfo);
}
&webmin_log("joingroup", "users", scalar(@d),
{ 'group' => $in{'group'} });
&redirect("");
}
elsif ($in{'confirm'}) {
# Do it
$access{'delete'} || &error($text{'delete_ecannot'});
foreach my $user (@d) {
&delete_user($user);
&delete_from_groups($user);
}
&reload_miniserv();
&webmin_log("delete", "users", scalar(@d));
&redirect("");
}
else {
# Ask the user if he is sure
$access{'delete'} || &error($text{'delete_ecannot'});
&ui_print_header(undef, $text{'udeletes_title'}, "");
print &ui_confirmation_form(
"delete_users.cgi",
&text('udeletes_rusure', scalar(@d)),
[ map { [ "d", $_ ] } @d ],
[ [ "confirm", $text{'udeletes_ok'} ] ],
&text('udeletes_users', join(" ", map { "<tt>$_</tt>" } @d)),
);
print "</center>\n";
&ui_print_footer("", $text{'index_return'});
}

View File

@@ -1,80 +0,0 @@
#!/usr/local/bin/perl
# edit_acl.cgi
# Display a form for editing the access control options for some module
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $base_remote_user, %gconfig);
&ReadParse();
$access{'acl'} || &error($text{'acl_emod'});
my $who;
if ($in{'group'}) {
$access{'groups'} || &error($text{'acl_egroup'});
$who = $in{'group'};
}
else {
my $me = &get_user($base_remote_user);
my @mcan = $access{'mode'} == 1 ? @{$me->{'modules'}} :
$access{'mode'} == 2 ? split(/\s+/, $access{'mods'}) :
( &list_modules() , "" );
&indexof($in{'mod'}, @mcan) >= 0 || &error($text{'acl_emod'});
&can_edit_user($in{'user'}) || &error($text{'acl_euser'});
$who = $in{'user'};
}
my %minfo = $in{'mod'} ? &get_module_info($in{'mod'})
: ( 'desc' => $text{'index_global'} );
my $below = &text($in{'group'} ? 'acl_title3' : 'acl_title2',
"<tt>".&html_escape($who)."</tt>",
"<tt>$minfo{'desc'}</tt>");
&ui_print_header($below, $text{'acl_title'}, "",
-r &help_file($in{'mod'}, "acl_info") ?
[ "acl_info", $in{'mod'} ] : undef);
my %maccess = $in{'group'} ? &get_group_module_acl($who, $in{'mod'})
: &get_module_acl($who, $in{'mod'}, 1);
# display the form
print &ui_form_start("save_acl.cgi", "post");
print &ui_hidden("_acl_mod", $in{'mod'}),"\n";
if ($in{'group'}) {
print &ui_hidden("_acl_group", $who),"\n";
}
else {
print &ui_hidden("_acl_user", $who),"\n";
}
print &ui_table_start(&text('acl_options', $minfo{'desc'}), "width=100%", 4);
# Load custom ACL library
my $mdir = &module_root_directory($in{'mod'});
if (-r "$mdir/acl_security.pl") {
&foreign_require($in{'mod'}, "acl_security.pl");
}
my $shown_config = 0;
if ($in{'mod'} && -r "$mdir/config.info" &&
(!&foreign_defined($in{'mod'}, "acl_security_noconfig") ||
!&foreign_call($in{'mod'}, "acl_security_noconfig"))) {
# Show module config editing option
print &ui_table_row($text{'acl_config'},
&ui_radio("noconfig", $maccess{'noconfig'} ? 1 : 0,
[ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]), 3);
$shown_config = 1;
}
# Show custom ACL form
if (-r "$mdir/acl_security.pl") {
print &ui_table_hr() if ($shown_config);
&foreign_call($in{'mod'}, "load_theme_library");
&foreign_call($in{'mod'}, "acl_security_form", \%maccess);
}
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ],
[ "reset", $text{'acl_reset'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,152 +0,0 @@
#!/usr/local/bin/perl
# edit_group.cgi
# Edit or create a webmin group
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access, $config_directory);
&ReadParse();
$access{'groups'} || &error($text{'gedit_ecannot'});
my $g;
my %group;
if ($in{'group'}) {
# Editing an existing group
&ui_print_header(undef, $text{'gedit_title'}, "");
$g = &get_group($in{'group'});
$g || &error($text{'gedit_egone'});
%group = %$g;
}
else {
# Creating a new group
&ui_print_header(undef, $text{'gedit_title2'}, "");
%group = ( );
if ($in{'clone'}) {
# Copy modules from clone
$g = &get_group($in{'clone'});
if ($g) {
$group{'modules'} = $g->{'modules'};
}
}
}
print &ui_form_start("save_group.cgi", "post");
print &ui_hidden("old", $in{'group'});
if ($in{'clone'}) {
print &ui_hidden("clone", $in{'clone'});
}
print &ui_hidden_table_start($text{'gedit_rights'}, "width=100%", 2, "rights",
1, [ "width=30%" ]);
# Show the group name
print &ui_table_row($text{'gedit_group'},
&ui_textbox("name", $group{'name'}, 30, 0, undef, "autocomplete=off"));
# Show group description
print &ui_table_row($text{'gedit_desc'},
&ui_textbox("desc", $group{'desc'}, 60));
# Find and show the parent group
my @glist = grep { $_->{'name'} ne $group{'name'} } &list_groups();
my @mcan = $access{'gassign'} eq '*' ?
( ( map { $_->{'name'} } @glist ), '_none' ) :
split(/\s+/, $access{'gassign'});
my %gcan = map { $_, 1 } @mcan;
if (@glist && %gcan) {
my @opts = ( );
if ($gcan{'_none'}) {
push(@opts, [ undef, "&lt;$text{'edit_none'}&gt;" ]);
}
my $memg = undef;
foreach my $g (@glist) {
if (&indexof('@'.$group{'name'}, @{$g->{'members'}}) >= 0) {
$memg = $g->{'name'};
}
next if (!$gcan{$g->{'name'}} && $memg ne $g->{'name'});
push(@opts, [ $g->{'name'} ]);
}
print &ui_table_row($text{'edit_group'},
&ui_select("group", $memg, \@opts));
}
if ($in{'group'}) {
# Show all current members
my @grid = map { $_ =~ /^\@(.*)$/ ? ui_link("edit_group.cgi?group=$1", "<i>$1</i>") : ui_link("edit_user.cgi?user=$_", $_) }
@{$group{'members'}};
if (@grid) {
print &ui_table_row($text{'gedit_members'},
&ui_links_row(\@grid));
}
}
# Storage type
if ($in{'group'}) {
print &ui_table_row($text{'edit_proto'},
$text{'edit_proto_'.$group{'proto'}});
}
print &ui_hidden_table_end("basic");
# Start of modules section
print &ui_hidden_table_start($text{'edit_mods'}, "width=100%", 2, "mods");
# Show available modules, under categories
my @mlist = &list_module_infos();
my %has = map { $_, 1 } @{$group{'modules'}};
my @links = ( &select_all_link("mod", 0, $text{'edit_selall'}),
&select_invert_link("mod", 0, $text{'edit_invert'}) );
my @cats = &unique(map { $_->{'category'} || "" } @mlist);
my %catnames;
&read_file("$config_directory/webmin.catnames", \%catnames);
my $grids = "";
foreach my $c (sort { $b cmp $a } @cats) {
my @cmlist = grep { $_->{'category'} eq $c } @mlist;
$grids .= "<b>".($catnames{$c} || $text{'category_'.$c})."</b><br>\n";
my @grid = ( );
my $sw = 0;
foreach my $m (@cmlist) {
my $md = $m->{'dir'};
my $label;
if ($access{'acl'} && $in{'group'}) {
# Show link for editing ACL
$label = ui_link("edit_acl.cgi?" .
"mod=" . urlize($m->{'dir'}) .
"&group=". urlize($in{'group'}),
$m->{'desc'}) . "\n";
}
else {
$label = $m->{'desc'};
}
push(@grid, &ui_checkbox("mod", $md, $label,$has{$md}));
}
$grids .= &ui_grid_table(\@grid, 2, 100, [ "width=50%", "width=50%" ]);
}
print &ui_table_row(undef, &ui_links_row(\@links).
$grids.
&ui_links_row(\@links), 2);
print &ui_hidden_table_end("mods");
# Add global ACL section
if ($access{'acl'} && $in{'group'}) {
print &ui_hidden_table_start($text{'edit_global'}, "width=100%", 2,
"global", 0, [ "width=30%" ]);
my %uaccess = &get_group_module_acl($in{'group'}, "");
print &ui_hidden("acl_security_form", 1);
&foreign_require("", "acl_security.pl");
&foreign_call("", "acl_security_form", \%uaccess);
print &ui_hidden_table_end("global");
}
# Generate form end buttons
my @buts = ( );
push(@buts, [ undef, $in{'group'} ? $text{'save'} : $text{'create'} ]);
if ($in{'group'}) {
push(@buts, [ "but_clone", $text{'edit_clone'} ]);
push(@buts, [ "but_delete", $text{'delete'} ]);
}
print &ui_form_end(\@buts);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,59 +0,0 @@
#!/usr/local/bin/perl
# Show password quality and change restrictions
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
$access{'pass'} || &error($text{'pass_ecannot'});
&ui_print_header(undef, $text{'pass_title'}, "");
my %miniserv;
&get_miniserv_config(\%miniserv);
print &ui_form_start("save_pass.cgi");
print &ui_table_start($text{'pass_header'}, undef, 2);
# Minimum password size
print &ui_table_row($text{'pass_minsize'},
&ui_opt_textbox("minsize", $miniserv{'pass_minsize'}, 5,
$text{'pass_nominsize'})." ".$text{'edit_chars'});
# Regexps password must match
print &ui_table_row($text{'pass_regexps'},
&ui_textarea("regexps",
join("\n", split(/\t+/, $miniserv{'pass_regexps'})), 5, 60));
# Human-readable description of regexp
print &ui_table_row($text{'pass_regdesc'},
&ui_textbox("regdesc", $miniserv{'pass_regdesc'}, 60));
# Days before forced change
print &ui_table_row($text{'pass_maxdays'},
&ui_opt_textbox("maxdays", $miniserv{'pass_maxdays'}, 5,
$text{'pass_nomaxdays'})." ".$text{'pass_days'});
# Days before lockout
print &ui_table_row($text{'pass_lockdays'},
&ui_opt_textbox("lockdays", $miniserv{'pass_lockdays'}, 5,
$text{'pass_nolockdays'})." ".$text{'pass_days'});
# Disallow use of username
print &ui_table_row($text{'pass_nouser'},
&ui_yesno_radio("nouser", $miniserv{'pass_nouser'}));
# Disallow dictionary words
print &ui_table_row($text{'pass_nodict'},
&ui_yesno_radio("nodict", $miniserv{'pass_nodict'}));
# Number of old passwords to reject
print &ui_table_row($text{'pass_oldblock'},
&ui_opt_textbox("oldblock", $miniserv{'pass_oldblock'}, 5,
$text{'pass_nooldblock'})." ".$text{'pass_pass'});
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,114 +0,0 @@
#!/usr/local/bin/perl
# Show form for an external user / group database
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
$access{'sql'} || &error($text{'sql_ecannot'});
&ui_print_header(undef, $text{'sql_title'}, "");
my %miniserv;
&get_miniserv_config(\%miniserv);
print &ui_form_start("save_sql.cgi");
print &ui_table_start($text{'sql_header'}, undef, 2);
my ($proto, $user, $pass, $host, $prefix, $args) =
&split_userdb_string($miniserv{'userdb'});
$proto ||= '';
# Build inputs for MySQL backend
my @mysqlgrid = ( );
push(@mysqlgrid,
$text{'sql_host'},
&ui_textbox("mysql_host", $proto eq "mysql" ? $host : "", 30));
push(@mysqlgrid,
$text{'sql_user'},
&ui_textbox("mysql_user", $proto eq "mysql" ? $user : "", 30));
push(@mysqlgrid,
$text{'sql_pass'},
&ui_textbox("mysql_pass", $proto eq "mysql" ? $pass : "", 30));
push(@mysqlgrid,
$text{'sql_db'},
&ui_textbox("mysql_db", $proto eq "mysql" ? $prefix : "", 30));
my $mysqlgrid = &ui_grid_table(\@mysqlgrid, 2, 100);
# Build inputs for PostgreSQL backend
my @postgresqlgrid = ( );
push(@postgresqlgrid,
$text{'sql_host'},
&ui_textbox("postgresql_host", $proto eq "postgresql" ? $host : "", 30));
push(@postgresqlgrid,
$text{'sql_user'},
&ui_textbox("postgresql_user", $proto eq "postgresql" ? $user : "", 30));
push(@postgresqlgrid,
$text{'sql_pass'},
&ui_textbox("postgresql_pass", $proto eq "postgresql" ? $pass : "", 30));
push(@postgresqlgrid,
$text{'sql_db'},
&ui_textbox("postgresql_db", $proto eq "postgresql" ? $prefix : "", 30));
my $postgresqlgrid = &ui_grid_table(\@postgresqlgrid, 2, 100);
# Build inputs for LDAP backend
my @ldapgrid = ( );
push(@ldapgrid,
$text{'sql_host'},
&ui_textbox("ldap_host", $proto eq "ldap" ? $host : "", 30));
push(@ldapgrid,
$text{'sql_ssl'},
&ui_radio("ldap_ssl", $args->{'scheme'} eq 'ldaps' ? 1 :
$args->{'tls'} ? 2 : 0,
[ [ 0, $text{'sql_ssl0'} ],
[ 1, $text{'sql_ssl1'} ],
[ 2, $text{'sql_ssl2'} ] ]));
push(@ldapgrid,
$text{'sql_user'},
&ui_textbox("ldap_user", $proto eq "ldap" ? $user : "", 30));
push(@ldapgrid,
$text{'sql_pass'},
&ui_textbox("ldap_pass", $proto eq "ldap" ? $pass : "", 30));
push(@ldapgrid,
$text{'sql_prefix'},
&ui_textbox("ldap_prefix", $proto eq "ldap" ? $prefix : "", 30));
push(@ldapgrid,
$text{'sql_userclass'},
&ui_textbox("ldap_userclass", $proto eq "ldap" && $args->{'userclass'} ?
$args->{'userclass'} : "webminUser", 30));
push(@ldapgrid,
$text{'sql_groupclass'},
&ui_textbox("ldap_groupclass", $proto eq "ldap" && $args->{'groupclass'} ?
$args->{'groupclass'} : "webminGroup",30));
push(@ldapgrid,
&ui_button($text{'sql_schema'}, undef, 0,
"onClick='window.location=\"schema.cgi\"'"), "");
my $ldapgrid = &ui_grid_table(\@ldapgrid, 2, 100);
print &ui_table_row(undef,
&ui_radio_table("proto", $proto,
[ [ '', $text{'sql_none'} ],
[ 'mysql', $text{'sql_mysql'}, $mysqlgrid ],
[ 'postgresql', $text{'sql_postgresql'}, $postgresqlgrid ],
[ 'ldap', $text{'sql_ldap'}, $ldapgrid ] ]), 2);
print &ui_table_row(undef,
&ui_radio("addto", int($miniserv{'userdb_addto'} || 0),
[ [ 0, $text{'sql_addto0'} ],
[ 1, $text{'sql_addto1'} ] ]), 2);
print &ui_table_row(undef,
&ui_radio("nocache", int($miniserv{'userdb_nocache'} || 0),
[ [ 0, $text{'sql_nocache0'} ],
[ 1, $text{'sql_nocache1'} ] ]), 2);
print &ui_table_row(undef,
&ui_opt_textbox("timeout", $miniserv{'userdb_cache_timeout'},
5, $text{'sql_timeout_def'}, $text{'sql_timeout_for'}).
" ".$text{'sql_timeout_secs'});
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,44 +0,0 @@
#!/usr/local/bin/perl
# edit_sync.cgi
# Display unix/webmin user synchronization
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
$access{'sync'} && $access{'create'} && $access{'delete'} ||
&error($text{'sync_ecannot'});
&ui_print_header(undef, $text{'sync_title'}, "");
my @glist = &list_groups();
if (!@glist) {
print "<p>$text{'sync_nogroups'}<p>\n";
&ui_print_footer("", $text{'index_return'});
exit;
}
print &ui_form_start("save_sync.cgi");
print &ui_table_start(undef, undef, 2);
# Sync on creation / deletion
print &ui_table_row($text{'sync_when'},
&ui_checkbox("create", 1, $text{'sync_create'}, $config{'sync_create'}).
"<br>\n".
&ui_checkbox("delete", 1, $text{'sync_delete'}, $config{'sync_delete'}).
"<br>\n".
&ui_checkbox("modify", 1, $text{'sync_modify'}, $config{'sync_modify'}).
"<br>\n".
&ui_checkbox("unix", 1, $text{'sync_unix'}, $config{'sync_unix'}));
# Assign new users to group
print &ui_table_row($text{'sync_group'},
&ui_select("group", $config{'sync_group'},
[ map { $_->{'name'} } @glist ]));
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,96 +0,0 @@
#!/usr/local/bin/perl
# edit_unix.cgi
# Map Unix users that do not have Webmin accounts to a Webmin user whose
# access rights and authentication method will be used for their logins.
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %access);
$access{'unix'} && $access{'create'} && $access{'delete'} ||
&error($text{'unix_ecannot'});
&ui_print_header(undef, $text{'unix_title'}, "");
print "$text{'unix_desc'}<p>\n";
my %miniserv;
&get_miniserv_config(\%miniserv);
print &ui_form_start("save_unix.cgi", "post");
print &ui_table_start($text{'unix_header'}, undef, 2);
# Configure Unix login mappings
my @unixauth = &get_unixauth(\%miniserv);
my $utable = "";
$utable .= &ui_radio("unix_def", @unixauth ? 0 : 1,
[ [ 1, $text{'unix_def'} ], [ 0, $text{'unix_sel'} ] ])."<br>\n";
$utable .= &ui_columns_start([ $text{'unix_mode'}, $text{'unix_who'},
$text{'unix_to'} ]);
my $i = 0;
my @webmins = map {
my $auth = $_->{'pass'} eq 'x' ? $text{'edit_unix'} :
$_->{'pass'} eq 'e' ? $text{'edit_extauth'} :
$_->{'pass'} eq '*LK*' || $_->{'pass'} =~ /^!/ ?
$text{'edit_lock'} : $text{'unix_webminpass'};
[ $_->{'name'}, "$_->{'name'} ($auth)" ]
} sort { $a->{'name'} cmp $b->{'name'} } &list_users();
foreach my $ua (@unixauth, [ ], [ ]) {
$utable .= &ui_columns_row([
&ui_select("mode_$i", !defined($ua->[0]) ? 0 :
$ua->[0] eq "" ? 0 :
$ua->[0] eq "*" ? 1 :
$ua->[0] =~ /^\@/ ? 2 : 3,
[ [ 0, " " ],
[ 1, $text{'unix_mall'} ],
[ 2, $text{'unix_group'} ],
[ 3, $text{'unix_user'} ] ]),
&ui_textbox("who_$i", $ua->[0] eq "*" || $ua->[0] eq "" ? "" :
$ua->[0] =~ /^\@(.*)$/ ? $1 : $ua->[0], 20),
&ui_select("to_$i", $ua->[1], \@webmins),
]);
$i++;
}
$utable .= &ui_columns_end();
$utable .= "<p>".&ui_note($text{'unix_mapdesc'}, 0)."</p>\n";
print &ui_table_row($text{'unix_utable'}, $utable);
# Allow users who can sudo to root?
print &ui_table_row("",
&ui_checkbox("sudo", 1, $text{'unix_sudo'},
$miniserv{'sudo'}));
# Allow PAM-only users?
print &ui_table_row("",
&ui_checkbox("pamany", 1, &text('unix_pamany',
&ui_select("pamany_user",
$miniserv{'pamany'},
\@webmins)),
$miniserv{'pamany'}));
print &ui_table_hr();
# Who can do Unix auth?
my $users = $miniserv{"allowusers"} ?
join("\n", split(/\s+/, $miniserv{"allowusers"})) :
$miniserv{"denyusers"} ?
join("\n", split(/\s+/, $miniserv{"denyusers"})) : "";
print &ui_table_row($text{'unix_restrict2'},
&ui_radio("access", $miniserv{"allowusers"} ? 1 :
$miniserv{"denyusers"} ? 2 : 0,
[ [ 0, $text{'unix_all'} ],
[ 1, $text{'unix_allow'} ],
[ 2, $text{'unix_deny'} ] ])."<br>\n".
&ui_textarea("users", $users, 6, 60));
# Block login by shell?
print &ui_table_row("",
&ui_checkbox("shells_deny", 1, $text{'unix_shells'},
$miniserv{'shells_deny'} ? 1 : 0)." ".
&ui_filebox("shells", $miniserv{'shells_deny'} || "/etc/shells", 25));
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,499 +0,0 @@
#!/usr/local/bin/perl
# edit_user.cgi
# Edit a new or existing webmin user
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %config, %gconfig, %access, $config_directory, $base_remote_user, $remote_user);
&foreign_require("webmin", "webmin-lib.pl");
&ReadParse();
my ($u, %user, $safe);
if ($in{'user'}) {
# Editing an existing user
&can_edit_user($in{'user'}) || &error($text{'edit_euser'});
&ui_print_header(undef, $text{'edit_title'}, "");
$u = &get_user($in{'user'});
$u || &error($text{'edit_egone'});
%user = %$u;
my %gacl = &get_module_acl($in{'user'}, '');
$safe = $gacl{'_safe'};
}
else {
# Creating a new user
$access{'create'} || &error($text{'edit_ecreate'});
if ($in{'clone'}) {
# Initial settings come from clone
$u = &get_user($in{'clone'});
%user = %$u;
delete($user{'name'});
my %gacl = &get_module_acl($in{'clone'}, '');
$safe = $gacl{'_safe'};
}
else {
# User starts out empty
%user = ( );
$safe = $in{'safe'};
}
&ui_print_header(undef, $safe ? $text{'edit_title3'}
: $text{'edit_title2'}, "");
}
my $me = &get_user($base_remote_user);
my %uaccess = &get_module_acl($in{'user'} || "", "", 1);
if (!$in{'user'} && $uaccess{'rpc'} == 2) {
# Don't offer the confusing 'root' or 'admin' RPC option by default
$uaccess{'rpc'} = 0;
}
if (!$in{'user'} && $safe) {
# Safe users should not inherit new permissions by default
$uaccess{'negative'} = 1;
}
# Give up if readonly
if ($user{'readonly'} && !$in{'readwrite'}) {
my %minfo = &get_module_info($user{'readonly'});
print &text('edit_readonly', $minfo{'desc'},
"edit_user.cgi?user=$in{'user'}&readwrite=1"),"<p>\n";
&ui_print_footer("", $text{'index_return'});
exit;
}
print &ui_form_start("save_user.cgi", "post");
if ($in{'user'}) {
print &ui_hidden("old", $user{'name'});
print &ui_hidden("oldpass", $user{'pass'});
}
if ($in{'clone'}) {
print &ui_hidden("clone", $in{'clone'});
}
print &ui_hidden("safe", $safe);
print &ui_hidden_table_start($text{'edit_rights'}, "width=100%", 2, "rights",
1, [ "width=30%" ]);
# Username
print &ui_table_row($text{'edit_user'},
$access{'rename'} || !$in{'user'} ?
&ui_textbox("name", $user{'name'}, 30,
0, undef, "autocomplete=off") : $user{'name'});
# Source user for clone
if ($in{'clone'}) {
print &ui_table_row($text{'edit_cloneof'}, "<tt>$in{'clone'}</tt>");
}
# Find and show parent group
my @glist = &list_groups();
my @mcan = $access{'gassign'} eq '*' ?
( ( map { $_->{'name'} } @glist ), '_none' ) :
split(/\s+/, $access{'gassign'});
my %gcan = map { $_, 1 } @mcan;
my $memg;
if (@glist && %gcan) {
my @opts = ( );
if ($gcan{'_none'}) {
push(@opts, [ undef, "&lt;$text{'edit_none'}&gt;" ]);
}
foreach my $g (@glist) {
if (&indexof($user{'name'}, @{$g->{'members'}}) >= 0 ||
$in{'clone'} &&
&indexof($in{'clone'}, @{$g->{'members'}}) >= 0) {
$memg = $g;
}
next if (!$gcan{$g->{'name'}} && $memg ne $g);
push(@opts, [ $g->{'name'} ]);
}
print &ui_table_row($text{'edit_group'},
&ui_select("group", $memg->{'name'}, \@opts));
}
# Show password type menu and current password
my $passmode = !$in{'user'} ? 0 :
$user{'pass'} eq 'x' ? 3 :
$user{'sync'} ? 2 :
$user{'pass'} eq 'e' ? 5 :
$user{'pass'} eq '*LK*' ? 4 : 1;
my %miniserv;
&get_miniserv_config(\%miniserv);
my @opts = ( [ 0, "$text{'edit_set'} .." ] );
if ($in{'user'}) {
push(@opts, [ 1, $text{'edit_dont'} ]);
}
push(@opts, [ 3, $text{'edit_unix'} ]);
if ($user{'sync'}) {
push(@opts, [ 2, $text{'edit_same'} ]);
}
if ($miniserv{'extauth'}) {
push(@opts, [ 5, $text{'edit_extauth'} ]);
}
push(@opts, [ 4, $text{'edit_lock'} ]);
my ($lockbox, $tempbox) = ("", "");
if ($passmode == 1) {
$lockbox = &ui_checkbox("lock", 1, $text{'edit_templock'},
$user{'pass'} =~ /^\!/ ? 1 : 0);
}
if ($passmode != 3 && $passmode != 4) {
$tempbox = &ui_checkbox("temp", 1, $text{'edit_temppass'},
$user{'temppass'});
}
my $expmsg = "";
if ($user{'lastchange'} && $miniserv{'pass_maxdays'}) {
my $daysold = int((time() - $user{'lastchange'})/(24*60*60));
if ($miniserv{'pass_lockdays'} &&
$daysold > $miniserv{'pass_lockdays'}) {
$expmsg = "<br>"."<font color=#ff0000>".
&text('edit_passlocked', $daysold)."</font>";
}
elsif ($daysold > $miniserv{'pass_maxdays'}) {
$expmsg = "<br>"."<font color=#ffaa00>".
&text('edit_passmax', $daysold)."</font>";
}
elsif ($daysold) {
$expmsg = "<br>".&text('edit_passold', $daysold);
}
else {
$expmsg = "<br>".$text{'edit_passtoday'};
}
}
my $js = "onChange='form.pass.disabled = value != 0;'";
print &ui_table_row($text{'edit_pass'},
&ui_select("pass_def", $passmode, \@opts, 1, 0, 0, 0, $js)." ".
&ui_password("pass", undef, 25, $passmode != 0, undef,
"autocomplete=off").
($lockbox || $tempbox ? "<br>" : "").$lockbox.$tempbox.$expmsg);
# Real name
print &ui_table_row($text{'edit_real'},
&ui_textbox("real", $user{'real'}, 60));
# Contact email for recovery
print &ui_table_row($text{'edit_email'},
&ui_textbox("email", $user{'email'}, 60));
# Storage type
if ($in{'user'}) {
print &ui_table_row($text{'edit_proto'},
$text{'edit_proto_'.($user{'proto'} || '')});
}
# Safe or not?
my $smsg;
if ($in{'user'} && $safe) {
$smsg = &ui_radio("unsafe", 0, [ [ 0, $text{'edit_safe1'} ],
[ 1, $text{'edit_safe0'} ] ]);
}
else {
$smsg = $safe ? $text{'edit_safe1'} : $text{'edit_safe0'};
}
print &ui_table_row($text{'edit_safe'}, $smsg);
print &ui_hidden_table_end("rights");
# Start of UI options section
my $showui = $access{'chcert'} || $access{'lang'} ||
$access{'cats'} || $access{'theme'};
if ($showui) {
print &ui_hidden_table_start($text{'edit_ui'}, "width=100%", 2, "ui",
0, [ "width=30%" ]);
}
if ($access{'chcert'}) {
# SSL certificate name
print &ui_table_row($text{'edit_cert'},
&ui_opt_textbox("cert", $user{'cert'}, 50, $text{'edit_none'}));
}
if ($access{'lang'}) {
# Current language
my $ulang = safe_language($user{'lang'});
print &ui_table_row($text{'edit_lang'},
&ui_radio("lang_def", $ulang ? 0 : 1,
[ [ 1, $text{'default'} ],
[ 0, &ui_select("lang", $ulang,
[ map { [ $_->{'lang'}, $_->{'desc'}."" ] }
&list_languages() ]) ]
]));
}
if ($access{'locale'}) {
# Current locale
eval { require DateTime; DateTime->import;
require DateTime::Locale; DateTime::Locale->import;
require DateTime::TimeZone; DateTime::TimeZone->import;
1 };
if (!$@ && $] > 5.011) {
my $locales = &list_locales();
my %localesrev = reverse %{$locales};
my $locale_auto = &parse_accepted_language();
print &ui_table_row($text{'edit_locale'},
&ui_radio("locale_def", $user{'locale'} ? 0 : 1,
[ [ 1, $text{'default'} ],
[ 0, &ui_select("locale", $user{'locale'} || $gconfig{'locale'} || &get_default_system_locale(),
[ map { [ $localesrev{$_}, $_ ] } sort values %{$locales} ]) ] ]),
undef, [ "valign=middle","valign=middle" ]);
}
}
if ($access{'cats'}) {
# Show categorized modules?
print &ui_table_row($text{'edit_notabs'},
&ui_radio("notabs", $user{'notabs'} || 0,
[ [ 1, $text{'yes'} ],
[ 2, $text{'no'} ],
[ 0, $text{'default'} ] ]));
}
my @all = &webmin::list_visible_themes($user{'theme'});
my @themes = grep { !$_->{'overlay'} } @all;
my @overlays = grep { $_->{'overlay'} } @all;
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
my @topts = ( );
push(@topts, !$user{'theme'} ? [ '', $text{'edit_themedef'} ] : ());
foreach my $t (@themes) {
push(@topts, [ $t->{'dir'}, $t->{'desc'} ]);
}
print &ui_table_row($text{'edit_theme'},
&ui_radio("theme_def", defined($user{'theme'}) ? 0 : 1,
[ [ 1, $text{'edit_themeglobal'} ],
[ 0, &ui_select("theme", $user{'theme'}, \@topts).
$tconf_link ] ]));
}
if ($access{'theme'} && @overlays) {
# Overlay theme, if any
print &ui_table_row($text{'edit_overlay'},
&ui_radio("overlay_def", defined($user{'overlay'}) ? 0 : 1,
[ [ 1, $text{'edit_overlayglobal'} ],
[ 0, &ui_select("overlay", $user{'overlay'},
[ map { [ $_->{'dir'}, $_->{'desc'} ] } @overlays ]
) ] ]));
}
if ($showui) {
print &ui_hidden_table_end("ui");
}
# Start of security options section
my $showsecurity = $access{'logouttime'} || $access{'ips'} ||
$access{'minsize'} ||
$access{'times'};
if ($showsecurity) {
print &ui_hidden_table_start($text{'edit_security'}, "width=100%", 2,
"security", 0, [ "width=30%" ]);
}
if ($access{'logouttime'}) {
# Show logout time
print &ui_table_row($text{'edit_logout'},
&ui_opt_textbox("logouttime", $user{'logouttime'}, 5,
$text{'default'})." ".$text{'edit_mins'});
}
if ($access{'minsize'}) {
# Show minimum password length, for just this user
print &ui_table_row($text{'edit_minsize'},
&ui_opt_textbox("minsize", $user{'minsize'}, 5,
$text{'default'})." ".$text{'edit_chars'});
}
if ($access{'nochange'} && $miniserv{'pass_maxdays'}) {
# Opt out of forced password change, for this user
print &ui_table_row($text{'edit_nochange'},
&ui_radio("nochange", $user{'nochange'},
[ [ 0, $text{'yes'} ], [ 1, $text{'no'} ] ]));
}
if ($access{'ips'}) {
# Allowed IP addresses
print &ui_table_row(&hlink("<b>$text{'edit_ips'}</b>", "ips"),
&ui_radio("ipmode", $user{'allow'} ? 1 :
$user{'deny'} ? 2 : 0,
[ [ 0, $text{'edit_all'}."<br>" ],
[ 1, $text{'edit_allow'}."<br>" ],
[ 2, $text{'edit_deny'}."<br>" ] ]).
&ui_textarea("ips",
join("\n", split(/\s+/, $user{'allow'} ||
$user{'deny'} || "")),
4, 30));
}
if ($access{'times'}) {
# Show allowed days of the week
my %days = map { $_, 1 } split(/,/, $user{'days'} || '');
my $daysels = "";
for(my $i=0; $i<7; $i++) {
$daysels .= &ui_checkbox("days", $i, $text{'day_'.$i},
$days{$i});
}
print &ui_table_row($text{'edit_days'},
&ui_radio("days_def", !defined($user{'days'}) || $user{'days'} eq '' ? 1 : 0,
[ [ 1, $text{'edit_alldays'} ],
[ 0, $text{'edit_seldays'} ] ])."<br>".
$daysels);
# Show allow hour/minute range
my ($hf, $mf) = split(/\./, $user{'hoursfrom'} || '');
my ($ht, $mt) = split(/\./, $user{'hoursto'} || '');
print &ui_table_row($text{'edit_hours'},
&ui_radio("hours_def", !defined($hf) || $hf eq '' ? 1 : 0,
[ [ 1, $text{'edit_allhours'} ],
[ 0, &text('edit_selhours',
&ui_textbox("hours_hfrom", $hf, 2),
&ui_textbox("hours_mfrom", $mf, 2),
&ui_textbox("hours_hto", $ht, 2),
&ui_textbox("hours_mto", $mt, 2)) ] ]));
}
# Two-factor details
if ($user{'twofactor_provider'}) {
my ($prov) = grep { $_->[0] eq $user{'twofactor_provider'} }
&webmin::list_twofactor_providers();
print &ui_table_row($text{'edit_twofactor'},
&text('edit_twofactorprov', "<i>$prov->[1]</i>",
"<tt>$user{'twofactor_id'}</tt>")."<br>\n".
&ui_checkbox('cancel', 1, $text{'edit_twofactorcancel'}, 0));
}
elsif ($miniserv{'twofactor_provider'}) {
print &ui_table_row($text{'edit_twofactor'},
$text{'edit_twofactornone'}." ".
&ui_submit($text{'edit_twofactoradd'}, "twofactor"));
}
# Can accept RPC calls?
if ($access{'acl'} && !$safe) {
print &ui_table_row(&hlink($text{'acl_rpc'}, 'rpc'),
&ui_radio("rpc", int($uaccess{'rpc'}),
[ [ 1, $text{'acl_rpc1'} ],
$uaccess{'rpc'} == 2 ? ( [ 2, $text{'acl_rpc2'} ] ) : ( ),
[ 3, $text{'acl_rpc3'} ],
[ 0, $text{'acl_rpc0'} ] ]));
}
print &ui_hidden_table_end("security");
# Work out which modules can be selected
@mcan = $access{'mode'} == 1 ? @{$me->{'modules'}} :
$access{'mode'} == 2 ? split(/\s+/, $access{'mods'}) :
&list_modules();
my (%mcan, %has);
map { $mcan{$_}++ } @mcan;
map { $has{$_}++ } @{$user{'modules'}};
# Start of modules section
my @groups = &list_groups();
print &ui_hidden_table_start(@groups ? $text{'edit_modsg'} : $text{'edit_mods'},
"width=100%", 2, "mods");
# Build list of modules, based on safe mode
my @allmods = &list_module_infos();
if ($safe) {
@allmods = grep { $has{$_->{'dir'}} ||
&get_safe_acl($_->{'dir'}) } @allmods;
}
# Show available modules, under categories
my @mlist = grep { $access{'others'} || $has{$_->{'dir'}} ||
$mcan{$_->{'dir'}} } @allmods;
my @links = ( &select_all_link("mod", 0, $text{'edit_selall'}),
&select_invert_link("mod", 0, $text{'edit_invert'}) );
my @cats = &unique(map { $_->{'category'} || '' } @mlist);
my %catnames;
&read_file("$config_directory/webmin.catnames", \%catnames);
my $grids = "";
foreach my $c (sort { $b cmp $a } @cats) {
my @cmlist = grep { ($_->{'category'} || '') eq $c } @mlist;
$grids .= "<b>".($catnames{$c} ||
$text{'category_'.$c} || '')."</b><br>\n";
my @grid = ( );
my $sw = 0;
foreach my $m (@cmlist) {
next if ($m->{'noacl'});
my $md = $m->{'dir'};
my $fromgroup = $memg &&
&indexof($md, @{$memg->{'modules'}}) >= 0;
if ($mcan{$md} && $fromgroup) {
# Module comes from group
push(@grid, (sprintf "<img src=images/%s.gif> %s\n",
$has{$md} ? 'tick' : 'empty', $m->{'desc'}).
($has{$md} ? &ui_hidden("mod", $md) : ""));
}
elsif ($mcan{$md}) {
my $label;
if ($access{'acl'} && $in{'user'} && !$safe &&
&can_module_acl($m)) {
# Show link for editing ACL
$label = ui_link("edit_acl.cgi?" .
"mod=" . urlize($m->{'dir'}) .
"&user=". urlize($in{'user'}),
$m->{'desc'}) . "\n";
}
else {
# No privileges to edit ACL
$label = $m->{'desc'};
}
push(@grid, &ui_checkbox("mod", $md, $label,$has{$md}));
}
else {
push(@grid, (sprintf "<img src=images/%s.gif> %s\n",
$has{$md} ? 'tick' : 'empty', $m->{'desc'}));
}
}
$grids .= &ui_grid_table(\@grid, 2, 100, [ "width=50%", "width=50%" ]);
}
print &ui_table_row(undef, &ui_links_row(\@links).
$grids.
&ui_links_row(\@links), 2);
print &ui_hidden_table_end("mods");
# Add global ACL section, but only if not set from the group
my $groupglobal = $memg && -r "$config_directory/$memg->{'name'}.acl";
if ($access{'acl'} && !$groupglobal && !$safe) {
print &ui_hidden_table_start($text{'edit_global'}, "width=100%", 2,
"global", 0, [ "width=30%" ]);
print &ui_hidden("acl_security_form", 1);
&foreign_require("", "acl_security.pl");
&foreign_call("", "acl_security_form", \%uaccess);
print &ui_hidden_table_end("global");
}
# Generate form end buttons
my @buts = ( );
push(@buts, [ undef, $in{'user'} ? $text{'save'} : $text{'create'} ]);
if ($in{'user'}) {
if ($access{'create'}) {
push(@buts, [ "but_clone", $text{'edit_clone'} ]);
}
if (&foreign_available("webminlog")) {
push(@buts, [ "but_log", $text{'edit_log'} ]);
}
if ($access{'switch'} && $main::session_id && $in{'user'} ne $remote_user) {
push(@buts, [ "but_switch", $text{'edit_switch'} ]);
}
if ($gconfig{'forgot_pass'}) {
push(@buts, [ "but_forgot", $text{'edit_forgot'} ]);
}
if ($access{'delete'}) {
push(@buts, [ "but_delete", $text{'delete'} ]);
}
}
print &ui_form_end(\@buts);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,19 +0,0 @@
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
do 'acl-lib.pl';
our ($config_directory);
sub feedback_files
{
return ( "$config_directory/miniserv.conf",
"$config_directory/miniserv.users",
"$config_directory/webmin.acl",
"$config_directory/webmin.groups",
"$config_directory/config" );
}
1;

View File

@@ -1,37 +0,0 @@
#!/usr/local/bin/perl
# Show form for force sending a password reset link
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text);
&foreign_require("webmin");
&error_setup($text{'forgot_err'});
&ReadParse();
&can_edit_user($in{'user'}) || &error($text{'edit_euser'});
my $u = &get_user($in{'user'});
$u || &error($text{'edit_egone'});
&ui_print_header(undef, $text{'forgot_title'}, "");
print $text{'forgot_desc'},"<p>\n";
print &ui_form_start("forgot_send.cgi", "post");
print &ui_hidden("user_acc", $u->{'name'});
print &ui_table_start($text{'forgot_header'}, undef, 2);
print &ui_table_row($text{'forgot_user'},
$u->{'name'} eq "root"
? &ui_textbox("user", $u->{'name'}, 12)
: "<tt>".$u->{'name'}."</tt>");
print &ui_table_row($text{'forgot_email'},
&ui_opt_textbox("email", $u->{'email'}, 60,
$text{'forgot_email_def'}."<br>\n",
$text{'forgot_email_sel'}));
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'forgot_send'} ] ]);
&ui_print_footer("", $text{'index_return'});

View File

@@ -1,87 +0,0 @@
#!/usr/local/bin/perl
# Actually send the password reset email
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl'; ## no critic
our (%in, %text, %gconfig);
&foreign_require("webmin");
&error_setup($text{'forgot_err'});
&ReadParse();
&can_edit_user($in{'user_acc'}) || &error($text{'edit_euser'});
my $wuser = &get_user($in{'user_acc'});
$wuser || &error($text{'edit_egone'});
# Validate inputs
$in{'email_def'} || $in{'email'} =~ /^\S+\@\S+$/ ||
&error($text{'forgot_eemail'});
my $unixuser;
if ($in{'user'} ne $in{'user_acc'}) {
&foreign_require("useradmin");
my ($uinfo) = grep { $_->{'user'} eq $in{'user'} }
&useradmin::list_users();
$uinfo || &error($text{'forgot_eunix'});
my $sudo = &useradmin::can_user_sudo_root($in{'user'});
&error($text{'forgot_enosudo'}) if ($sudo < 0);
&error($text{'forgot_ecansudo'}) if (!$sudo);
$unixuser = $in{'user'};
}
# Generate a random ID and tracking file for this password reset
my $now = time();
my %link = ( 'id' => &generate_random_id(),
'remote' => $ENV{'REMOTE_ADDR'},
'time' => $now,
'user' => $wuser->{'name'},
'uuser' => $unixuser, );
$link{'id'} || &error($text{'forgot_erandom'});
&make_dir($main::forgot_password_link_dir, 0700);
my $linkfile = $main::forgot_password_link_dir."/".$link{'id'};
&lock_file($linkfile);
&write_file($linkfile, \%link);
&unlock_file($linkfile);
my $baseurl = &get_webmin_email_url();
my $url = $baseurl.'/forgot.cgi?id='.&urlize($link{'id'});
&load_theme_library();
$url = &theme_forgot_url($baseurl, $link{'id'}, $unixuser || $link{'user'})
if (defined(&theme_forgot_url));
&ui_print_header(undef, $text{'forgot_title'}, "");
my $username = $unixuser || $wuser->{'name'};
if ($in{'email_def'}) {
# Just show the link
my $timeout = $gconfig{'passreset_timeout'} || 15;
print "<p>",&text('forgot_link', $username, $timeout),"</p>\n";
print "<p><tt>".$url."</tt></p>\n";
&webmin_log("forgot", "link", undef,
{ 'user' => $username,
'unix' => $unixuser ? 1 : 0 });
}
else {
# Construct and send the email
&foreign_require("mailboxes");
my $msg = &text('forgot_adminmsg', $wuser->{'name'}, $url, $baseurl);
$msg =~ s/\\n/\n/g;
$msg = join("\n", &mailboxes::wrap_lines($msg, 75))."\n";
my $subject = &text('forgot_subject', $username);
print &text('forgot_sending',
&html_escape($in{'email'}), $username),"<br>\n";
&mailboxes::send_text_mail(&mailboxes::get_from_address(),
$in{'email'},
undef,
$subject,
$msg);
print $text{'forgot_sent'},"<p>\n";
&webmin_log("forgot", "admin", undef,
{ 'user' => $username,
'unix' => $unixuser ? 1 : 0,
'email' => $in{'email'} });
}
&ui_print_footer("", $text{'index_return'});

View File

@@ -1 +0,0 @@
<header> التحكم في الوصول IP </header> يعمل التحكم في وصول IP للمستخدم بنفس الطريقة التي يعمل بها التحكم العام في الوصول إلى IP في وحدة تكوين Webmin. فقط إذا اجتاز المستخدم عناصر التحكم العامة ، فسيتم فحصها هنا أيضًا. <p style=";text-align:right;direction:rtl"><footer>

View File

@@ -1 +0,0 @@
<header> IP контрол на достъпа </header> Потребителският контрол на достъп до IP работи по същия начин като глобалния контрол на достъпа до IP в модула за конфигуриране на Webmin. Само ако потребителят премине глобалните контроли, тези тук също ще бъдат проверени. <p><footer>

View File

@@ -1,8 +0,0 @@
<header>Control d'Accés IP</header>
El control d'accés IP d'usuari funciona de la mateixa manera que el control
d'accés IP global del mòdul de Configuració de Webmin. Només si un usuari passa
els controls globals es comprovaran també aquí aquests. <p>
<footer>

View File

@@ -1 +0,0 @@
<header> Řízení přístupu IP </header> Řízení přístupu uživatelů IP funguje stejným způsobem jako globální řízení přístupu IP v modulu Webmin Configuration. Pouze v případě, že uživatel předá globální ovládací prvky, budou také ty zkontrolovány. <p><footer>

View File

@@ -1,5 +0,0 @@
<header>IP adgangskontrol</header>
Bruger IP adgangskontrol virker på samme måde som den globale IP adgangskontrol i Webmin konfigurationsmodulet. Kun hvis en bruger passerer den globale adgangskontrol vil denne også blive tjekket.
<footer>

View File

@@ -1 +0,0 @@
<header>IP-Zugriffskontrolle</header>Die IP-Zugriffskontrolle für Benutzer funktioniert auf die gleiche Weise wie die globale IP-Zugriffskontrolle im Webmin-Konfigurationsmodul. Nur wenn ein Benutzer die globalen Regeln passiert, werden die hier definierten Einschränkungen ebenfalls überprüft.<p><footer>

View File

@@ -1 +0,0 @@
<header>IP-Zugriffskontrolle</header>Die IP-Zugriffskontrolle für Benutzer:innen funktioniert auf die gleiche Weise wie die globale IP-Zugriffskontrolle im Webmin-Konfigurationsmodul. Nur wenn ein:e Benutzer:in die globalen Regeln passiert, werden die hier definierten Einschränkungen ebenfalls überprüft.<p><footer>

View File

@@ -1 +0,0 @@
<header> Έλεγχος πρόσβασης IP </header> Ο έλεγχος πρόσβασης IP χρήστη λειτουργεί με τον ίδιο τρόπο όπως ο καθολικός έλεγχος πρόσβασης IP στη λειτουργική μονάδα Webmin Configuration. Μόνο εάν ένας χρήστης περάσει τα καθολικά στοιχεία ελέγχου, θα ελεγχθούν και αυτοί εδώ. <p><footer>

View File

@@ -1 +0,0 @@
<header> Control de acceso IP </header> El control de acceso IP del usuario funciona de la misma manera que el control de acceso IP global en el módulo de configuración de Webmin. Solo si un usuario pasa los controles globales, también se verificarán aquí. <p><footer>

View File

@@ -1 +0,0 @@
<header> IP sarbide kontrola </header> Erabiltzaileen IP sarbide kontrola Webmin Konfigurazio moduluan IP sarbide kontrol orokorraren modu berean funtzionatzen du. Erabiltzaile batek kontrol globalak gainditzen baditu hemen ere egiaztatuko dira. <p><footer>

View File

@@ -1,17 +0,0 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<p dir="rtl"><b><header> مهار دسترسي IP </header>
</b>
<body>
</p>
<p dir="rtl">
<body>
<header>مهار دسترسي IP در بخش مهار دسترسي کاربران مانند مهار دسترسي IP عمومي در
بخش پيکربندي وب مين عمل مي نمايد. زماني که کاربر يک کنترل را ارسال مي کند، در اين
قسمت مورد بررسي قرار مي گيرد.</header></p>
</html>

View File

@@ -1 +0,0 @@
<header> IP-pääsyn hallinta </header> Käyttäjän IP-pääsyn hallinta toimii samalla tavalla kuin globaali IP-pääsyn hallinta Webmin-määritysmoduulissa. Vain jos käyttäjä läpäisee globaalit ohjausobjektit, myös nämä tarkistetaan. <p><footer>

View File

@@ -1,5 +0,0 @@
<header>Contrôle d'accès IP</header>
Le contrôle d'accès utilisateur par adresse IP fonctionne de la même manière que le contrôle d'accès IP global dans le module Configuration de Webmin. Seul un utilisateur ayant passé le contrôle global sera vérifié de nouveau avec ces règles.
<footer>

View File

@@ -1 +0,0 @@
<header> IP kontrola pristupa </header> Korisnička kontrola pristupa IP funkcionira na isti način kao i globalna kontrola pristupa u modulu Konfiguracija Webmin. Samo ako korisnik prođe globalne kontrole, provjerit će se i ovdje. <p><footer>

View File

@@ -1,6 +0,0 @@
<header>IP access control</header>
User IP access control works in the same way as the global IP access control in the Webmin Configuration module. Only if a user passes the global controls will those here be checked as well. <p>
<footer>

View File

@@ -1 +0,0 @@
<header> IP hozzáférés vezérlés </header> A felhasználói IP-hozzáférés-vezérlés ugyanúgy működik, mint a globális IP-hozzáférés-vezérlés a Webmin Configuration modulban. Csak akkor, ha a felhasználó átadja a globális vezérlőelemeket, akkor itt ellenőrizni is kell. <p><footer>

View File

@@ -1,5 +0,0 @@
<header>Controllo degli accessi IP</header>
Il controllo degli accessi IP per gli utenti funziona allo stesso modo del controllo degli accessi IP globale configurabile nel modulo 'Configurazione di Webmin'. Solo se un utente soddisfa i requisiti IP impostati con il controllo globale sarà sottoposto ad un nuovo controllo impostato in questa pagina.
<footer>

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